summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES-1.5.txt5
-rw-r--r--CHANGES.txt15
-rw-r--r--backend/dnssd.c4
-rw-r--r--backend/ipp.c78
-rw-r--r--backend/lpd.c22
-rw-r--r--backend/snmp-supplies.c2
-rw-r--r--backend/testbackend.c8
-rw-r--r--cgi-bin/ipp-var.c4
-rw-r--r--config-scripts/cups-common.m436
-rw-r--r--config-scripts/cups-dnssd.m420
-rw-r--r--config.h.in16
-rw-r--r--cups/auth.c20
-rw-r--r--cups/dest-options.c2
-rw-r--r--cups/emit.c24
-rw-r--r--cups/encode.c5
-rw-r--r--cups/http-support.c55
-rw-r--r--cups/http.c89
-rw-r--r--cups/ipp-support.c6
-rw-r--r--cups/ipp.c6
-rw-r--r--cups/ppd-cache.c21
-rw-r--r--cups/ppd-private.h3
-rw-r--r--cups/testipp.c4
-rw-r--r--cups/usersys.c105
-rw-r--r--doc/help/api-cups.html284
-rw-r--r--doc/help/api-httpipp.html159
-rw-r--r--doc/help/options.html116
-rw-r--r--doc/help/policies.html29
-rw-r--r--doc/help/ppd-compiler.html8
-rw-r--r--doc/help/ref-client-conf.html15
-rw-r--r--doc/help/ref-cupsd-conf.html.in15
-rw-r--r--doc/help/spec-ipp.html14
-rw-r--r--doc/help/spec-ppd.html23
-rw-r--r--filter/ppd-compiler.header8
-rw-r--r--filter/pstops.c56
-rw-r--r--filter/spec-ppd.shtml22
-rw-r--r--man/client.conf.man.in10
-rw-r--r--man/cupsd.conf.man.in9
-rw-r--r--man/ppdc.man9
-rw-r--r--scheduler/Makefile4
-rw-r--r--scheduler/auth.c12
-rw-r--r--scheduler/avahi.c441
-rw-r--r--scheduler/avahi.h69
-rw-r--r--scheduler/client.h6
-rw-r--r--scheduler/conf.c4
-rw-r--r--scheduler/cups-driverd.cxx10
-rw-r--r--scheduler/cupsd.h28
-rw-r--r--scheduler/ipp.c194
-rw-r--r--scheduler/job.c13
-rw-r--r--scheduler/job.h2
-rw-r--r--scheduler/main.c33
-rw-r--r--scheduler/printers.c4
-rw-r--r--scheduler/testsub.c4
-rw-r--r--scheduler/timeout.c249
-rw-r--r--test/get-completed-jobs.test4
-rw-r--r--test/get-jobs.test4
-rw-r--r--test/ipptool.c30
56 files changed, 1813 insertions, 625 deletions
diff --git a/CHANGES-1.5.txt b/CHANGES-1.5.txt
index f97e843e3..3250d60aa 100644
--- a/CHANGES-1.5.txt
+++ b/CHANGES-1.5.txt
@@ -3,11 +3,12 @@ CHANGES-1.5.txt
CHANGES IN CUPS V1.5.3
+ - The cups-driverd program could temporarily "forget" a PPD file if it
+ was updated in place.
+ - The dnssd backend now prefers IPPS over IPP.
- The USB backend now uses and requires LIBUSB 1.0 or later (STR #3477)
- The LIBUSB-based USB backend now supports the back-channel (STR #2890)
- Changed how timeouts are implemented in the LPD backend (STR #4013)
- - The IPP backend no longer specifies the document-format for auto-
- detect unless required (STR #3986)
- Added more supported color names for SNMP supplies (STR #3981)
- The default InputSlot setting was never used (STR #3957)
- POSIX ACLs are now set properly on certificate files (STR #3970)
diff --git a/CHANGES.txt b/CHANGES.txt
index 454e98dc9..0528f3c3d 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,8 +1,21 @@
-CHANGES.txt - 1.6b1 - 2012-01-30
+CHANGES.txt - 1.6b1 - 2012-02-15
--------------------------------
CHANGES IN CUPS V1.6b1
+ - Documentation updates (STR #3927, STR #3980, STR #4010)
+ - CUPS now supports a User directive in client.conf and the CUPS_USER
+ environment variable for overriding the default username (STR #3114)
+ - Now set the PJL USERNAME variable as needed (STR #3100)
+ - Added support for usernames and passwords longer than 32 characters
+ (STR #2856)
+ - Added a new MaxHoldTime directive to automatically cancel jobs that
+ have been held indefinitely after a specific number of seconds
+ (STR #2291)
+ - The LPD backend now uses the originating host name when it is not the
+ local system (STR #2053)
+ - CUPS now prefers the suffix "dpcm" when reporting resolution in dots-
+ per-centimeter (STR #4006)
- The configure script and build system no longer support building of
separate 32-bit and 64-bit libraries.
- The "brightness", "columns", "fitplot", "gamma", "hue",
diff --git a/backend/dnssd.c b/backend/dnssd.c
index fd86e0814..12571b15c 100644
--- a/backend/dnssd.c
+++ b/backend/dnssd.c
@@ -3,7 +3,7 @@
*
* DNS-SD discovery backend for CUPS.
*
- * Copyright 2008-2011 by Apple Inc.
+ * Copyright 2008-2012 by Apple Inc.
*
* These coded instructions, statements, and computer programs are the
* property of Apple Inc. and are protected by Federal copyright
@@ -43,8 +43,8 @@
typedef enum
{
CUPS_DEVICE_PRINTER = 0, /* lpd://... */
- CUPS_DEVICE_IPP, /* ipp://... */
CUPS_DEVICE_IPPS, /* ipps://... */
+ CUPS_DEVICE_IPP, /* ipp://... */
CUPS_DEVICE_FAX_IPP, /* ipp://... */
CUPS_DEVICE_PDL_DATASTREAM, /* socket://... */
CUPS_DEVICE_RIOUSBPRINT /* riousbprint://... */
diff --git a/backend/ipp.c b/backend/ipp.c
index 68c05e954..20391f8a2 100644
--- a/backend/ipp.c
+++ b/backend/ipp.c
@@ -90,7 +90,9 @@ static const char * const jattrs[] = /* Job attributes we want */
};
static int job_canceled = 0;
/* Job cancelled? */
-static char *password = NULL;
+static char username[256] = "",
+ /* Username for device URI */
+ *password = NULL;
/* Password for device URI */
static int password_tries = 0;
/* Password tries */
@@ -98,7 +100,6 @@ static const char * const pattrs[] = /* Printer attributes we want */
{
"copies-supported",
"cups-version",
- "document-format-default",
"document-format-supported",
"marker-colors",
"marker-high-levels",
@@ -190,7 +191,6 @@ main(int argc, /* I - Number of command-line args */
const char *device_uri; /* Device URI */
char scheme[255], /* Scheme in URI */
hostname[1024], /* Hostname */
- username[255], /* Username info */
resource[1024], /* Resource info (printer name) */
addrname[256], /* Address name */
*optptr, /* Pointer to URI options */
@@ -230,7 +230,6 @@ main(int argc, /* I - Number of command-line args */
ipp_attribute_t *job_state; /* job-state */
ipp_attribute_t *copies_sup; /* copies-supported */
ipp_attribute_t *cups_version; /* cups-version */
- ipp_attribute_t *format_dflt; /* document-format-default */
ipp_attribute_t *format_sup; /* document-format-supported */
ipp_attribute_t *media_col_sup; /* media-col-supported */
ipp_attribute_t *operations_sup; /* operations-supported */
@@ -612,7 +611,10 @@ main(int argc, /* I - Number of command-line args */
const char *ptr = getenv("AUTH_USERNAME");
if (ptr)
+ {
+ strlcpy(username, ptr, sizeof(username));
cupsSetUser(ptr);
+ }
password = getenv("AUTH_PASSWORD");
}
@@ -841,7 +843,9 @@ main(int argc, /* I - Number of command-line args */
fprintf(stderr, "DEBUG: Get-Printer-Attributes: %s (%s)\n",
ippErrorString(ipp_status), cupsLastErrorString());
- if (ipp_status > IPP_OK_CONFLICT)
+ if (ipp_status <= IPP_OK_CONFLICT)
+ password_tries = 0;
+ else
{
fprintf(stderr, "DEBUG: Get-Printer-Attributes returned %s.\n",
ippErrorString(ipp_status));
@@ -898,7 +902,8 @@ main(int argc, /* I - Number of command-line args */
return (CUPS_BACKEND_STOP);
}
- else if (ipp_status == IPP_NOT_AUTHORIZED || ipp_status == IPP_FORBIDDEN)
+ else if (ipp_status == IPP_FORBIDDEN ||
+ ipp_status == IPP_AUTHENTICATION_CANCELED)
{
const char *www_auth = httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE);
/* WWW-Authenticate field value */
@@ -911,7 +916,7 @@ main(int argc, /* I - Number of command-line args */
fprintf(stderr, "ATTR: auth-info-required=%s\n", auth_info_required);
return (CUPS_BACKEND_AUTH_REQUIRED);
}
- else
+ else if (ipp_status != IPP_NOT_AUTHORIZED)
{
_cupsLangPrintFilter(stderr, "ERROR",
_("Unable to get printer status."));
@@ -997,16 +1002,6 @@ main(int argc, /* I - Number of command-line args */
cups_version = ippFindAttribute(supported, "cups-version", IPP_TAG_TEXT);
- if ((format_dflt = ippFindAttribute(supported, "document-format-default",
- IPP_TAG_MIMETYPE)) != NULL)
- {
- fprintf(stderr, "DEBUG: document-format-default (%d values)\n",
- format_dflt->num_values);
- for (i = 0; i < format_dflt->num_values; i ++)
- fprintf(stderr, "DEBUG: [%d] = \"%s\"\n", i,
- format_dflt->values[i].string.text);
- }
-
if ((format_sup = ippFindAttribute(supported, "document-format-supported",
IPP_TAG_MIMETYPE)) != NULL)
{
@@ -1184,21 +1179,17 @@ main(int argc, /* I - Number of command-line args */
if (format_sup != NULL)
{
for (i = 0; i < format_sup->num_values; i ++)
- if (!_cups_strcasecmp(final_content_type,
- format_sup->values[i].string.text))
+ if (!_cups_strcasecmp(final_content_type, format_sup->values[i].string.text))
{
document_format = final_content_type;
break;
}
- if (!document_format &&
- (!format_dflt ||
- _cups_strcasecmp(format_dflt->values[0].string.text,
- "application/octet-stream")))
+ if (!document_format)
{
for (i = 0; i < format_sup->num_values; i ++)
if (!_cups_strcasecmp("application/octet-stream",
- format_sup->values[i].string.text))
+ format_sup->values[i].string.text))
{
document_format = "application/octet-stream";
break;
@@ -1303,7 +1294,7 @@ main(int argc, /* I - Number of command-line args */
_cupsLangPrintFilter(stderr, "INFO", _("The printer is busy."));
sleep(10);
}
- else if (ipp_status == IPP_NOT_AUTHORIZED || ipp_status == IPP_FORBIDDEN ||
+ else if (ipp_status == IPP_FORBIDDEN ||
ipp_status == IPP_AUTHENTICATION_CANCELED)
{
const char *www_auth = httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE);
@@ -1463,6 +1454,8 @@ main(int argc, /* I - Number of command-line args */
}
else if (ipp_status == IPP_ERROR_JOB_CANCELED)
goto cleanup;
+ else if (ipp_status == IPP_NOT_AUTHORIZED)
+ continue;
else
{
/*
@@ -1472,11 +1465,12 @@ main(int argc, /* I - Number of command-line args */
_cupsLangPrintFilter(stderr, "ERROR",
_("Print file was not accepted."));
- if (ipp_status == IPP_NOT_AUTHORIZED || ipp_status == IPP_FORBIDDEN)
+ if (ipp_status == IPP_FORBIDDEN ||
+ ipp_status == IPP_AUTHENTICATION_CANCELED)
{
const char *www_auth = httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE);
/* WWW-Authenticate field value */
-
+
if (!strncmp(www_auth, "Negotiate", 9))
auth_info_required = "negotiate";
else if (www_auth[0])
@@ -1515,6 +1509,7 @@ main(int argc, /* I - Number of command-line args */
}
else
{
+ password_tries = 0;
monitor.job_id = job_id = job_id_attr->values[0].integer;
_cupsLangPrintFilter(stderr, "INFO",
_("Print file accepted - job ID %d."), job_id);
@@ -1616,8 +1611,13 @@ main(int argc, /* I - Number of command-line args */
_("Unable to add document to print job."));
break;
}
- else if (num_files == 0 || fd < 0)
- break;
+ else
+ {
+ password_tries = 0;
+
+ if (num_files == 0 || fd < 0)
+ break;
+ }
}
}
@@ -1705,7 +1705,9 @@ main(int argc, /* I - Number of command-line args */
fprintf(stderr, "DEBUG: Get-Job-Attributes: %s (%s)\n",
ippErrorString(ipp_status), cupsLastErrorString());
- if (ipp_status > IPP_OK_CONFLICT)
+ if (ipp_status <= IPP_OK_CONFLICT)
+ password_tries = 0;
+ else
{
if (ipp_status != IPP_SERVICE_UNAVAILABLE &&
ipp_status != IPP_NOT_POSSIBLE &&
@@ -1966,6 +1968,9 @@ check_printer_state(
fprintf(stderr, "DEBUG: Get-Printer-Attributes: %s (%s)\n",
ippErrorString(cupsLastError()), cupsLastErrorString());
+ if (cupsLastError() <= IPP_OK_CONFLICT)
+ password_tries = 0;
+
/*
* Return the printer-state value...
*/
@@ -2073,6 +2078,8 @@ monitor_printer(
http = _httpCreate(monitor->hostname, monitor->port, NULL, monitor->encryption,
AF_UNSPEC);
httpSetTimeout(http, 30.0, timeout_cb, NULL);
+ if (username[0])
+ cupsSetUser(username);
cupsSetPasswordCB(password_cb);
/*
@@ -2130,6 +2137,9 @@ monitor_printer(
fprintf(stderr, "DEBUG: %s: %s (%s)\n", ippOpString(job_op),
ippErrorString(cupsLastError()), cupsLastErrorString());
+ if (cupsLastError() <= IPP_OK_CONFLICT)
+ password_tries = 0;
+
if (job_op == IPP_GET_JOB_ATTRIBUTES)
{
if ((attr = ippFindAttribute(response, "job-state",
@@ -2452,6 +2462,9 @@ new_request(
"multiple-document-handling", NULL, collate_str);
break;
}
+
+ if (i >= doc_handling_sup->num_values)
+ copies = 1;
}
/*
@@ -2500,7 +2513,7 @@ new_request(
cupsEncodeOptions(request, num_options, options);
}
- if (copies > 1)
+ if (copies > 1 && copies <= pc->max_copies)
ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "copies", copies);
}
@@ -2515,6 +2528,9 @@ new_request(
static const char * /* O - Password */
password_cb(const char *prompt) /* I - Prompt (not used) */
{
+ fprintf(stderr, "DEBUG: password_cb(prompt=\"%s\"), password=%p, "
+ "password_tries=%d\n", prompt, password, password_tries);
+
(void)prompt;
/*
diff --git a/backend/lpd.c b/backend/lpd.c
index 0dabfd766..3e3cbfc90 100644
--- a/backend/lpd.c
+++ b/backend/lpd.c
@@ -92,7 +92,7 @@ static int lpd_queue(const char *hostname, http_addrlist_t *addrlist,
int mode, const char *user, const char *title,
int copies, int banner, int format, int order,
int reserve, int manual_copies, int timeout,
- int contimeout);
+ int contimeout, const char *orighost);
static int lpd_write(int lpd_fd, char *buffer, int length);
#ifndef HAVE_RRESVPORT_AF
static int rresvport_af(int *port, int family);
@@ -144,6 +144,8 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
struct sigaction action; /* Actions for POSIX signals */
#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+ int num_jobopts; /* Number of job options */
+ cups_option_t *jobopts = NULL; /* Job options */
/*
@@ -191,6 +193,8 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
return (CUPS_BACKEND_FAILED);
}
+ num_jobopts = cupsParseOptions(argv[5], 0, &jobopts);
+
/*
* Extract the hostname and printer name from the URI...
*/
@@ -525,7 +529,9 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
status = lpd_queue(hostname, addrlist, resource + 1, fd, snmp_fd, mode,
username, title, copies, banner, format, order, reserve,
- manual_copies, timeout, contimeout);
+ manual_copies, timeout, contimeout,
+ cupsGetOption("job-originating-host-name", num_jobopts,
+ jobopts));
if (!status)
fprintf(stderr, "PAGE: 1 %d\n", atoi(argv[4]));
@@ -533,7 +539,9 @@ main(int argc, /* I - Number of command-line arguments (6 or 7) */
else
status = lpd_queue(hostname, addrlist, resource + 1, fd, snmp_fd, mode,
username, title, 1, banner, format, order, reserve, 1,
- timeout, contimeout);
+ timeout, contimeout,
+ cupsGetOption("job-originating-host-name", num_jobopts,
+ jobopts));
/*
* Remove the temporary file if necessary...
@@ -638,7 +646,8 @@ lpd_queue(const char *hostname, /* I - Host to connect to */
int reserve, /* I - Reserve ports? */
int manual_copies,/* I - Do copies by hand... */
int timeout, /* I - Timeout... */
- int contimeout) /* I - Connection timeout */
+ int contimeout, /* I - Connection timeout */
+ const char *orighost) /* I - job-originating-host-name */
{
char localhost[255]; /* Local host name */
int error; /* Error number */
@@ -927,7 +936,10 @@ lpd_queue(const char *hostname, /* I - Host to connect to */
return (CUPS_BACKEND_FAILED);
}
- httpGetHostname(NULL, localhost, sizeof(localhost));
+ if (orighost)
+ strlcpy(localhost, orighost, sizeof(localhost));
+ else
+ httpGetHostname(NULL, localhost, sizeof(localhost));
snprintf(control, sizeof(control),
"H%.31s\n" /* RFC 1179, Section 7.2 - host name <= 31 chars */
diff --git a/backend/snmp-supplies.c b/backend/snmp-supplies.c
index 601bc979d..0eaba065d 100644
--- a/backend/snmp-supplies.c
+++ b/backend/snmp-supplies.c
@@ -149,7 +149,7 @@ static const int prtMarkerSuppliesType[] =
static const backend_state_t const printer_states[] =
{
- { CUPS_TC_lowPaper, "media-low-report" },
+ /* { CUPS_TC_lowPaper, "media-low-report" }, */
{ CUPS_TC_noPaper | CUPS_TC_inputTrayEmpty, "media-empty-warning" },
/* { CUPS_TC_lowToner, "toner-low-report" }, */ /* now use prtMarkerSupplies */
/* { CUPS_TC_noToner, "toner-empty-warning" }, */ /* now use prtMarkerSupplies */
diff --git a/backend/testbackend.c b/backend/testbackend.c
index 6182471d1..a3a7d97e6 100644
--- a/backend/testbackend.c
+++ b/backend/testbackend.c
@@ -98,12 +98,18 @@ main(int argc, /* I - Number of command-line args */
(ptr = strrchr(libpath, '/')) != NULL && !strcmp(ptr, "/backend"))
{
strlcpy(ptr, "/cups", sizeof(libpath) - (ptr - libpath));
- if (access(libpath, 0))
+ if (!access(libpath, 0))
+ {
#ifdef __APPLE__
+ fprintf(stderr, "Setting DYLD_LIBRARY_PATH to \"%s\".\n", libpath);
setenv("DYLD_LIBRARY_PATH", libpath, 1);
#else
+ fprintf(stderr, "Setting LD_LIBRARY_PATH to \"%s\".\n", libpath);
setenv("LD_LIBRARY_PATH", libpath, 1);
#endif /* __APPLE__ */
+ }
+ else
+ perror(libpath);
}
/*
diff --git a/cgi-bin/ipp-var.c b/cgi-bin/ipp-var.c
index 31d34d7fd..6c432a9d6 100644
--- a/cgi-bin/ipp-var.c
+++ b/cgi-bin/ipp-var.c
@@ -3,7 +3,7 @@
*
* CGI <-> IPP variable routines for CUPS.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -1219,7 +1219,7 @@ cgiSetIPPObjectVars(
"%dx%d%s", attr->values[i].resolution.xres,
attr->values[i].resolution.yres,
attr->values[i].resolution.units == IPP_RES_PER_INCH ?
- "dpi" : "dpc");
+ "dpi" : "dpcm");
break;
case IPP_TAG_URI :
diff --git a/config-scripts/cups-common.m4 b/config-scripts/cups-common.m4
index 04e700eb5..9b8ac80aa 100644
--- a/config-scripts/cups-common.m4
+++ b/config-scripts/cups-common.m4
@@ -225,24 +225,20 @@ AC_ARG_ENABLE(libusb, [ --enable-libusb use libusb for USB printing])
LIBUSB=""
AC_SUBST(LIBUSB)
-if test x$enable_libusb = xyes; then
- check_libusb=yes
-elif test x$enable_libusb != xno -a $uname != Darwin; then
- check_libusb=yes
-else
- check_libusb=no
-fi
-
-if test $check_libusb = yes -a "x$PKGCONFIG" != x; then
- AC_MSG_CHECKING(for libusb-1.0)
- if $PKGCONFIG --exists libusb-1.0; then
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_LIBUSB)
- CFLAGS="$CFLAGS `$PKGCONFIG --cflags libusb-1.0`"
- LIBUSB="`$PKGCONFIG --libs libusb-1.0`"
- else
- AC_MSG_RESULT(no)
+if test "x$PKGCONFIG" != x; then
+ if test x$enable_libusb = xyes -o $uname != Darwin; then
+ AC_MSG_CHECKING(for libusb-1.0)
+ if $PKGCONFIG --exists libusb-1.0; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_LIBUSB)
+ CFLAGS="$CFLAGS `$PKGCONFIG --cflags libusb-1.0`"
+ LIBUSB="`$PKGCONFIG --libs libusb-1.0`"
+ else
+ AC_MSG_RESULT(no)
+ fi
fi
+elif x$enable_libusb = xyes; then
+ AC_MSG_ERROR(Need pkg-config to enable libusb support.)
fi
dnl See if we have libwrap for TCP wrappers support...
@@ -353,12 +349,6 @@ case $uname in
dnl Check for dynamic store function...
AC_CHECK_FUNCS(SCDynamicStoreCopyComputerName)
- dnl Check for new ColorSync APIs...
- SAVELIBS="$LIBS"
- LIBS="$LIBS -framework ApplicationServices"
- AC_CHECK_FUNCS(ColorSyncRegisterDevice)
- LIBS="$SAVELIBS"
-
dnl Check for the new membership functions in MacOSX 10.4...
AC_CHECK_HEADER(membership.h,AC_DEFINE(HAVE_MEMBERSHIP_H))
AC_CHECK_HEADER(membershipPriv.h,AC_DEFINE(HAVE_MEMBERSHIPPRIV_H))
diff --git a/config-scripts/cups-dnssd.m4 b/config-scripts/cups-dnssd.m4
index 1999be3ff..3ed91f79b 100644
--- a/config-scripts/cups-dnssd.m4
+++ b/config-scripts/cups-dnssd.m4
@@ -3,7 +3,7 @@ dnl "$Id: cups-dnssd.m4 7890 2008-08-29 22:19:39Z mike $"
dnl
dnl DNS Service Discovery (aka Bonjour) stuff for CUPS.
dnl
-dnl Copyright 2007-2011 by Apple Inc.
+dnl Copyright 2007-2012 by Apple Inc.
dnl
dnl These coded instructions, statements, and computer programs are the
dnl property of Apple Inc. and are protected by Federal copyright
@@ -12,7 +12,8 @@ dnl which should have been included with this file. If this file is
dnl file is missing or damaged, see the license at "http://www.cups.org/".
dnl
-AC_ARG_ENABLE(dnssd, [ --disable-dnssd disable DNS Service Discovery support])
+AC_ARG_ENABLE(avahi, [ --disable-avahi disable DNS Service Discovery support using Avahi])
+AC_ARG_ENABLE(dnssd, [ --disable-dnssd disable DNS Service Discovery support using mDNSResponder])
AC_ARG_WITH(dnssd-libs, [ --with-dnssd-libs set directory for DNS Service Discovery library],
LDFLAGS="-L$withval $LDFLAGS"
DSOFLAGS="-L$withval $DSOFLAGS",)
@@ -23,7 +24,20 @@ AC_ARG_WITH(dnssd-includes, [ --with-dnssd-includes set directory for DNS Ser
DNSSDLIBS=""
DNSSD_BACKEND=""
-if test x$enable_dnssd != xno; then
+if test "x$PKGCONFIG" != x -a x$enable_avahi != xno; then
+ AC_MSG_CHECKING(for Avahi)
+ if $PKGCONFIG --exists avahi-client; then
+ AC_MSG_RESULT(yes)
+ CFLAGS="$CFLAGS `$PKGCONFIG --cflags avahi-client`"
+ DNSSDLIBS="`$PKGCONFIG --libs avahi-client`"
+ DNSSD_BACKEND="dnssd"
+ AC_DEFINE(HAVE_AVAHI)
+ else
+ AC_MSG_RESULT(no)
+ fi
+fi
+
+if test "x$DNSSD_BACKEND" = x -a x$enable_dnssd != xno; then
AC_CHECK_HEADER(dns_sd.h, [
case "$uname" in
Darwin*)
diff --git a/config.h.in b/config.h.in
index e5f383e15..9c1faf9ab 100644
--- a/config.h.in
+++ b/config.h.in
@@ -379,13 +379,20 @@
/*
- * Do we have DNS Service Discovery (aka Bonjour)?
+ * Do we have mDNSResponder for DNS Service Discovery (aka Bonjour)?
*/
#undef HAVE_DNSSD
/*
+ * Do we have Avahi for DNS Service Discovery (aka Bonjour)?
+ */
+
+#undef HAVE_AVAHI
+
+
+/*
* Do we have <sys/ioctl.h>?
*/
@@ -724,13 +731,6 @@
/*
- * Do we have the ColorSyncRegisterDevice function?
- */
-
-#undef HAVE_COLORSYNCREGISTERDEVICE
-
-
-/*
* Do we have XPC?
*/
diff --git a/cups/auth.c b/cups/auth.c
index bea62b797..7e091bee0 100644
--- a/cups/auth.c
+++ b/cups/auth.c
@@ -124,7 +124,8 @@ cupsDoAuthentication(
const char *method, /* I - Request method ("GET", "POST", "PUT") */
const char *resource) /* I - Resource path */
{
- const char *password; /* Password string */
+ const char *password, /* Password string */
+ *www_auth; /* WWW-Authenticate header */
char prompt[1024], /* Prompt for user */
realm[HTTP_MAX_VALUE], /* realm="xyz" string */
nonce[HTTP_MAX_VALUE]; /* nonce="xyz" string */
@@ -179,9 +180,11 @@ cupsDoAuthentication(
* Nope, see if we should retry the current username:password...
*/
+ www_auth = http->fields[HTTP_FIELD_WWW_AUTHENTICATE];
+
if ((http->digest_tries > 1 || !http->userpass[0]) &&
- (!strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Basic", 5) ||
- !strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Digest", 6)))
+ (!_cups_strncasecmp(www_auth, "Basic", 5) ||
+ !_cups_strncasecmp(www_auth, "Digest", 6)))
{
/*
* Nope - get a new password from the user...
@@ -197,8 +200,7 @@ cupsDoAuthentication(
cupsUser(),
http->hostname[0] == '/' ? "localhost" : http->hostname);
- http->digest_tries = _cups_strncasecmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE],
- "Digest", 5) != 0;
+ http->digest_tries = _cups_strncasecmp(www_auth, "Digest", 6) != 0;
http->userpass[0] = '\0';
if ((password = cupsGetPassword2(prompt, http, method, resource)) == NULL)
@@ -227,7 +229,7 @@ cupsDoAuthentication(
*/
#ifdef HAVE_GSSAPI
- if (!strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Negotiate", 9))
+ if (!_cups_strncasecmp(www_auth, "Negotiate", 9))
{
/*
* Kerberos authentication...
@@ -241,7 +243,7 @@ cupsDoAuthentication(
}
else
#endif /* HAVE_GSSAPI */
- if (!strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Basic", 5))
+ if (!_cups_strncasecmp(www_auth, "Basic", 5))
{
/*
* Basic authentication...
@@ -254,7 +256,7 @@ cupsDoAuthentication(
(int)strlen(http->userpass));
httpSetAuthString(http, "Basic", encode);
}
- else if (!strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Digest", 6))
+ else if (!_cups_strncasecmp(www_auth, "Digest", 6))
{
/*
* Digest authentication...
@@ -277,7 +279,7 @@ cupsDoAuthentication(
else
{
DEBUG_printf(("1cupsDoAuthentication: Unknown auth type: \"%s\"",
- http->fields[HTTP_FIELD_WWW_AUTHENTICATE]));
+ www_auth));
http->status = HTTP_AUTHORIZATION_CANCELED;
return (-1);
}
diff --git a/cups/dest-options.c b/cups/dest-options.c
index eff70dcb0..af5a26256 100644
--- a/cups/dest-options.c
+++ b/cups/dest-options.c
@@ -187,7 +187,7 @@ cupsCheckDestSupported(
if (!strcmp(temp, "dpi"))
units_value = IPP_RES_PER_INCH;
- else if (!strcmp(temp, "dpc"))
+ else if (!strcmp(temp, "dpc") || !strcmp(temp, "dpcm"))
units_value = IPP_RES_PER_CM;
else
return (0);
diff --git a/cups/emit.c b/cups/emit.c
index 23e0c2800..e322bfe1a 100644
--- a/cups/emit.c
+++ b/cups/emit.c
@@ -3,7 +3,7 @@
*
* PPD code emission routines for CUPS.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -519,15 +519,27 @@ ppdEmitJCL(ppd_file_t *ppd, /* I - PPD file record */
*/
if (display && strcmp(display->value, "job"))
- {
fprintf(fp, "@PJL JOB NAME = \"%s\"\n", temp);
-
- if (display && !strcmp(display->value, "rdymsg"))
- fprintf(fp, "@PJL RDYMSG DISPLAY = \"%s\"\n", displaymsg);
- }
+ else if (display && !strcmp(display->value, "rdymsg"))
+ fprintf(fp, "@PJL RDYMSG DISPLAY = \"%s\"\n", displaymsg);
else
fprintf(fp, "@PJL JOB NAME = \"%s\" DISPLAY = \"%s\"\n", temp,
displaymsg);
+
+ /*
+ * Replace double quotes with single quotes and UTF-8 characters with
+ * question marks so that the user does not cause a PJL syntax error.
+ */
+
+ strlcpy(temp, user, sizeof(temp));
+
+ for (ptr = temp; *ptr; ptr ++)
+ if (*ptr == '\"')
+ *ptr = '\'';
+ else if (!charset && (*ptr & 128))
+ *ptr = '?';
+
+ fprintf(fp, "@PJL SET USERNAME = \"%s\"\n", temp);
}
else
fputs(ppd->jcl_begin, fp);
diff --git a/cups/encode.c b/cups/encode.c
index 91a37ecd8..2226e1950 100644
--- a/cups/encode.c
+++ b/cups/encode.c
@@ -3,7 +3,7 @@
*
* Option encoding routines for CUPS.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -539,7 +539,8 @@ cupsEncodeOptions2(
else
attr->values[j].resolution.yres = attr->values[j].resolution.xres;
- if (!_cups_strcasecmp(s, "dpc"))
+ if (!_cups_strcasecmp(s, "dpc") ||
+ !_cups_strcasecmp(s, "dpcm"))
attr->values[j].resolution.units = IPP_RES_PER_CM;
else
attr->values[j].resolution.units = IPP_RES_PER_INCH;
diff --git a/cups/http-support.c b/cups/http-support.c
index 0d1f2b211..b886515bd 100644
--- a/cups/http-support.c
+++ b/cups/http-support.c
@@ -757,10 +757,13 @@ httpGetDateString2(time_t t, /* I - UNIX time */
tdate = gmtime(&t);
- snprintf(s, slen, "%s, %02d %s %d %02d:%02d:%02d GMT",
- http_days[tdate->tm_wday], tdate->tm_mday,
- http_months[tdate->tm_mon], tdate->tm_year + 1900,
- tdate->tm_hour, tdate->tm_min, tdate->tm_sec);
+ if (tdate)
+ snprintf(s, slen, "%s, %02d %s %d %02d:%02d:%02d GMT",
+ http_days[tdate->tm_wday], tdate->tm_mday,
+ http_months[tdate->tm_mon], tdate->tm_year + 1900,
+ tdate->tm_hour, tdate->tm_min, tdate->tm_sec);
+ else
+ s[0] = '\0';
return (s);
}
@@ -1504,15 +1507,19 @@ _httpResolveURI(
if (DNSServiceCreateConnection(&ref) == kDNSServiceErr_NoError)
{
localref = ref;
- if (DNSServiceResolve(&localref, kDNSServiceFlagsShareConnection, 0,
- hostname, regtype, "local.", http_resolve_cb,
+ if (DNSServiceResolve(&localref,
+ kDNSServiceFlagsShareConnection |
+ kDNSServiceFlagsTimeout, 0, hostname, regtype,
+ "local.", http_resolve_cb,
&uribuf) == kDNSServiceErr_NoError)
{
int fds; /* Number of ready descriptors */
time_t timeout, /* Poll timeout */
- start_time = time(NULL);/* Start time */
+ start_time = time(NULL),/* Start time */
+ end_time = start_time + 90;
+ /* End time */
- for (;;)
+ while (time(NULL) < end_time)
{
if (options & _HTTP_RESOLVE_STDERR)
_cupsLangPrintFilter(stderr, "INFO", _("Looking for printer."));
@@ -1524,27 +1531,27 @@ _httpResolveURI(
}
/*
- * For the first minute (or forever if we have a callback), wakeup
- * every 2 seconds to emit a "looking for printer" message...
+ * Wakeup every 2 seconds to emit a "looking for printer" message...
*/
- timeout = (time(NULL) < (start_time + 60) || cb) ? 2000 : -1;
+ if ((timeout = end_time - time(NULL)) > 2)
+ timeout = 2;
#ifdef HAVE_POLL
polldata.fd = DNSServiceRefSockFD(ref);
polldata.events = POLLIN;
- fds = poll(&polldata, 1, timeout);
+ fds = poll(&polldata, 1, 1000 * timeout);
#else /* select() */
FD_ZERO(&input_set);
FD_SET(DNSServiceRefSockFD(ref), &input_set);
- stimeout.tv_sec = ((int)timeout) / 1000;
- stimeout.tv_usec = ((int)(timeout) * 1000) % 1000000;
+ stimeout.tv_sec = timeout;
+ stimeout.tv_usec = 0;
fds = select(DNSServiceRefSockFD(ref)+1, &input_set, NULL, NULL,
- timeout < 0.0 ? NULL : &stimeout);
+ &stimeout);
#endif /* HAVE_POLL */
if (fds < 0)
@@ -1562,7 +1569,7 @@ _httpResolveURI(
* comes in, do an additional domain resolution...
*/
- if (domainsent == 0 && (domain && _cups_strcasecmp(domain, "local.")))
+ if (domainsent == 0 && domain && _cups_strcasecmp(domain, "local."))
{
if (options & _HTTP_RESOLVE_STDERR)
fprintf(stderr,
@@ -1571,10 +1578,12 @@ _httpResolveURI(
domain ? domain : "");
domainref = ref;
- if (DNSServiceResolve(&domainref, kDNSServiceFlagsShareConnection,
+ if (DNSServiceResolve(&domainref,
+ kDNSServiceFlagsShareConnection |
+ kDNSServiceFlagsTimeout,
0, hostname, regtype, domain,
- http_resolve_cb, &uribuf)
- == kDNSServiceErr_NoError)
+ http_resolve_cb,
+ &uribuf) == kDNSServiceErr_NoError)
domainsent = 1;
}
@@ -1612,11 +1621,15 @@ _httpResolveURI(
if (options & _HTTP_RESOLVE_STDERR)
{
if (uri)
+ {
fprintf(stderr, "DEBUG: Resolved as \"%s\"...\n", uri);
+ fputs("STATE: -connecting-to-device,offline-report\n", stderr);
+ }
else
+ {
fputs("DEBUG: Unable to resolve URI\n", stderr);
-
- fputs("STATE: -connecting-to-device,offline-report\n", stderr);
+ fputs("STATE: -connecting-to-device\n", stderr);
+ }
}
#else
diff --git a/cups/http.c b/cups/http.c
index 16351ef0d..1f2d826dd 100644
--- a/cups/http.c
+++ b/cups/http.c
@@ -1668,6 +1668,8 @@ _httpPeek(http_t *http, /* I - Connection to server */
* Buffer small reads for better performance...
*/
+ ssize_t buflen; /* Length of read for buffer */
+
if (!http->blocking)
{
while (!httpWait(http, http->wait_value))
@@ -1680,48 +1682,69 @@ _httpPeek(http_t *http, /* I - Connection to server */
}
if (http->data_remaining > sizeof(http->buffer))
- bytes = sizeof(http->buffer);
+ buflen = sizeof(http->buffer);
else
- bytes = http->data_remaining;
+ buflen = http->data_remaining;
+
+ DEBUG_printf(("2_httpPeek: Reading %d bytes into buffer.", (int)buflen));
+ do
+ {
#ifdef HAVE_SSL
- if (http->tls)
- bytes = http_read_ssl(http, http->buffer, bytes);
- else
+ if (http->tls)
+ bytes = http_read_ssl(http, http->buffer, buflen);
+ else
#endif /* HAVE_SSL */
- {
- DEBUG_printf(("2_httpPeek: reading %d bytes from socket into buffer...",
- (int)bytes));
-
- bytes = recv(http->fd, http->buffer, bytes, 0);
-
- DEBUG_printf(("2_httpPeek: read %d bytes from socket into buffer...",
- (int)bytes));
- }
+ bytes = recv(http->fd, http->buffer, buflen, 0);
- if (bytes > 0)
- http->used = bytes;
- else if (bytes < 0)
- {
-#ifdef WIN32
- if (WSAGetLastError() != WSAEINTR && WSAGetLastError() != WSAEWOULDBLOCK)
+ if (bytes < 0)
{
- http->error = WSAGetLastError();
- return (-1);
- }
+#ifdef WIN32
+ if (WSAGetLastError() != WSAEINTR)
+ {
+ http->error = WSAGetLastError();
+ return (-1);
+ }
+ else if (WSAGetLastError() == WSAEWOULDBLOCK)
+ {
+ if (!http->timeout_cb ||
+ !(*http->timeout_cb)(http, http->timeout_data))
+ {
+ http->error = WSAEWOULDBLOCK;
+ return (-1);
+ }
+ }
#else
- if (errno != EINTR && errno != EAGAIN)
- {
- http->error = errno;
- return (-1);
- }
+ if (errno == EWOULDBLOCK || errno == EAGAIN)
+ {
+ if (http->timeout_cb && !(*http->timeout_cb)(http, http->timeout_data))
+ {
+ http->error = errno;
+ return (-1);
+ }
+ else if (!http->timeout_cb && errno != EAGAIN)
+ {
+ http->error = errno;
+ return (-1);
+ }
+ }
+ else if (errno != EINTR)
+ {
+ http->error = errno;
+ return (-1);
+ }
#endif /* WIN32 */
+ }
}
- else
- {
- http->error = EPIPE;
- return (0);
- }
+ while (bytes < 0);
+
+ DEBUG_printf(("2_httpPeek: Read " CUPS_LLFMT " bytes into buffer.",
+ CUPS_LLCAST bytes));
+#ifdef DEBUG
+ http_debug_hex("_httpPeek", http->buffer, (int)bytes);
+#endif /* DEBUG */
+
+ http->used = bytes;
}
if (http->used > 0)
diff --git a/cups/ipp-support.c b/cups/ipp-support.c
index ec4c2c998..362321a55 100644
--- a/cups/ipp-support.c
+++ b/cups/ipp-support.c
@@ -3,7 +3,7 @@
*
* Internet Printing Protocol support functions for CUPS.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -487,12 +487,12 @@ ippAttributeString(
bufptr += snprintf(bufptr, bufend - bufptr + 1, "%dx%d%s",
val->resolution.xres, val->resolution.yres,
val->resolution.units == IPP_RES_PER_INCH ?
- "dpi" : "dpc");
+ "dpi" : "dpcm");
else
bufptr += snprintf(temp, sizeof(temp), "%dx%d%s",
val->resolution.xres, val->resolution.yres,
val->resolution.units == IPP_RES_PER_INCH ?
- "dpi" : "dpc");
+ "dpi" : "dpcm");
break;
case IPP_TAG_DATE :
diff --git a/cups/ipp.c b/cups/ipp.c
index 96361abdc..6b88d71de 100644
--- a/cups/ipp.c
+++ b/cups/ipp.c
@@ -3673,7 +3673,11 @@ ippSetString(ipp_t *ipp, /* IO - IPP message */
* Range check input...
*/
- if (!ipp || !attr || !*attr || (*attr)->value_tag != IPP_TAG_INTEGER ||
+ if (!ipp || !attr || !*attr ||
+ ((*attr)->value_tag != IPP_TAG_TEXTLANG &&
+ (*attr)->value_tag != IPP_TAG_NAMELANG &&
+ ((*attr)->value_tag < IPP_TAG_TEXT ||
+ (*attr)->value_tag > IPP_TAG_MIMETYPE)) ||
element < 0 || element > (*attr)->num_values || !strvalue)
return (0);
diff --git a/cups/ppd-cache.c b/cups/ppd-cache.c
index c9ee6af2d..cf34a00bd 100644
--- a/cups/ppd-cache.c
+++ b/cups/ppd-cache.c
@@ -171,6 +171,8 @@ _ppdCacheCreateWithFile(
goto create_error;
}
+ pc->max_copies = 9999;
+
/*
* Read the file...
*/
@@ -553,6 +555,8 @@ _ppdCacheCreateWithFile(
cupsArrayAdd(pc->finishings, finishings);
}
+ else if (!_cups_strcasecmp(line, "MaxCopies"))
+ pc->max_copies = atoi(value);
else
{
DEBUG_printf(("_ppdCacheCreateWithFile: Unknown %s on line %d.", line,
@@ -1349,6 +1353,17 @@ _ppdCacheCreateWithPPD(ppd_file_t *ppd) /* I - PPD file */
}
/*
+ * Max copies...
+ */
+
+ if ((ppd_attr = ppdFindAttr(ppd, "cupsMaxCopies", NULL)) != NULL)
+ pc->max_copies = atoi(ppd_attr->value);
+ else if (ppd->manual_copies)
+ pc->max_copies = 1;
+ else
+ pc->max_copies = 9999;
+
+ /*
* Return the cache data...
*/
@@ -2334,6 +2349,12 @@ _ppdCacheWriteFile(
}
/*
+ * Max copies...
+ */
+
+ cupsFilePrintf(fp, "MaxCopies %d\n", pc->max_copies);
+
+ /*
* IPP attributes, if any...
*/
diff --git a/cups/ppd-private.h b/cups/ppd-private.h
index bc6a0f8b9..426c74ff8 100644
--- a/cups/ppd-private.h
+++ b/cups/ppd-private.h
@@ -49,7 +49,7 @@ extern "C" {
* Constants...
*/
-# define _PPD_CACHE_VERSION 2 /* Version number in cache file */
+# define _PPD_CACHE_VERSION 3 /* Version number in cache file */
/*
@@ -141,6 +141,7 @@ struct _ppd_cache_s /**** PPD cache and PWG conversion data ****/
*prefilters; /* cupsPreFilter values */
int single_file; /* cupsSingleFile value */
cups_array_t *finishings; /* cupsIPPFinishings values */
+ int max_copies; /* cupsMaxCopies value */
};
diff --git a/cups/testipp.c b/cups/testipp.c
index 70c83bf4b..5655b6be2 100644
--- a/cups/testipp.c
+++ b/cups/testipp.c
@@ -3,7 +3,7 @@
*
* IPP test program for CUPS.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 1997-2005 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -901,7 +901,7 @@ print_attributes(ipp_t *ipp, /* I - IPP request */
case IPP_TAG_RESOLUTION :
for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
printf(" %dx%d%s", val->resolution.xres, val->resolution.yres,
- val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpc");
+ val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
putchar('\n');
break;
diff --git a/cups/usersys.c b/cups/usersys.c
index dfd5cb21c..0fcd86e57 100644
--- a/cups/usersys.c
+++ b/cups/usersys.c
@@ -66,6 +66,7 @@ static void cups_read_client_conf(cups_file_t *fp,
_cups_globals_t *cg,
const char *cups_encryption,
const char *cups_server,
+ const char *cups_user,
#ifdef HAVE_GSSAPI
const char *cups_gssservicename,
#endif /* HAVE_GSSAPI */
@@ -435,55 +436,11 @@ cupsSetUser(const char *user) /* I - User name */
const char * /* O - User name */
cupsUser(void)
{
- const char *user; /* USER environment variable */
_cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
if (!cg->user[0])
- {
-#ifdef WIN32
- /*
- * Get the current user name from the OS...
- */
-
- DWORD size; /* Size of string */
-
- size = sizeof(cg->user);
- if (!GetUserName(cg->user, &size))
-#else
- /*
- * Get the user name corresponding to the current UID...
- */
-
- struct passwd *pwd; /* User/password entry */
-
- setpwent();
- if ((pwd = getpwuid(getuid())) != NULL)
- {
- /*
- * Found a match!
- */
-
- strlcpy(cg->user, pwd->pw_name, sizeof(cg->user));
- }
- else
-#endif /* WIN32 */
- if ((user = getenv("USER")) != NULL)
- {
- /*
- * Use the username from the "USER" environment variable...
- */
- strlcpy(cg->user, user, sizeof(cg->user));
- }
- else
- {
- /*
- * Use the default "unknown" user name...
- */
-
- strcpy(cg->user, "unknown");
- }
- }
+ _cupsSetDefaults();
return (cg->user);
}
@@ -791,6 +748,7 @@ _cupsSetDefaults(void)
const char *home, /* Home directory of user */
*cups_encryption, /* CUPS_ENCRYPTION env var */
*cups_server, /* CUPS_SERVER env var */
+ *cups_user, /* CUPS_USER/USER env var */
#ifdef HAVE_GSSAPI
*cups_gssservicename, /* CUPS_GSSSERVICENAME env var */
#endif /* HAVE_GSSAPI */
@@ -816,13 +774,16 @@ _cupsSetDefaults(void)
cups_expiredroot = getenv("CUPS_EXPIREDROOT");
cups_expiredcerts = getenv("CUPS_EXPIREDCERTS");
+ if ((cups_user = getenv("CUPS_USER")) == NULL)
+ cups_user = getenv("USER");
+
/*
* Then, if needed, read the ~/.cups/client.conf or /etc/cups/client.conf
* files to get the default values...
*/
if (cg->encryption == (http_encryption_t)-1 || !cg->server[0] ||
- !cg->ipp_port)
+ !cg->user[0] || !cg->ipp_port)
{
if ((home = getenv("HOME")) != NULL)
{
@@ -852,7 +813,7 @@ _cupsSetDefaults(void)
* functions handle NULL cups_file_t pointers...
*/
- cups_read_client_conf(fp, cg, cups_encryption, cups_server,
+ cups_read_client_conf(fp, cg, cups_encryption, cups_server, cups_user,
#ifdef HAVE_GSSAPI
cups_gssservicename,
#endif /* HAVE_GSSAPI */
@@ -873,6 +834,7 @@ cups_read_client_conf(
_cups_globals_t *cg, /* I - Global data */
const char *cups_encryption, /* I - CUPS_ENCRYPTION env var */
const char *cups_server, /* I - CUPS_SERVER env var */
+ const char *cups_user, /* I - CUPS_USER env var */
#ifdef HAVE_GSSAPI
const char *cups_gssservicename,
/* I - CUPS_GSSSERVICENAME env var */
@@ -888,6 +850,7 @@ cups_read_client_conf(
#ifndef __APPLE__
server_name[1024], /* ServerName value */
#endif /* !__APPLE__ */
+ user[256], /* User value */
any_root[1024], /* AllowAnyRoot value */
expired_root[1024], /* AllowExpiredRoot value */
expired_certs[1024]; /* AllowExpiredCerts value */
@@ -921,6 +884,11 @@ cups_read_client_conf(
cups_server = server_name;
}
#endif /* !__APPLE__ */
+ else if (!cups_user && !_cups_strcasecmp(line, "User") && value)
+ {
+ strlcpy(user, value, sizeof(user));
+ cups_user = user;
+ }
else if (!cups_anyroot && !_cups_strcasecmp(line, "AllowAnyRoot") && value)
{
strlcpy(any_root, value, sizeof(any_root));
@@ -1029,6 +997,49 @@ cups_read_client_conf(
cg->ipp_port = CUPS_DEFAULT_IPP_PORT;
}
+ if (!cg->user[0])
+ {
+ if (cups_user)
+ strlcpy(cg->user, cups_user, sizeof(cg->user));
+ else
+ {
+#ifdef WIN32
+ /*
+ * Get the current user name from the OS...
+ */
+
+ DWORD size; /* Size of string */
+
+ size = sizeof(cg->user);
+ if (!GetUserName(cg->user, &size))
+#else
+ /*
+ * Get the user name corresponding to the current UID...
+ */
+
+ struct passwd *pwd; /* User/password entry */
+
+ setpwent();
+ if ((pwd = getpwuid(getuid())) != NULL)
+ {
+ /*
+ * Found a match!
+ */
+
+ strlcpy(cg->user, pwd->pw_name, sizeof(cg->user));
+ }
+ else
+#endif /* WIN32 */
+ {
+ /*
+ * Use the default "unknown" user name...
+ */
+
+ strcpy(cg->user, "unknown");
+ }
+ }
+ }
+
#ifdef HAVE_GSSAPI
if (!cups_gssservicename)
cups_gssservicename = CUPS_DEFAULT_GSSSERVICENAME;
diff --git a/doc/help/api-cups.html b/doc/help/api-cups.html
index 5ebd932dc..bda8ad661 100644
--- a/doc/help/api-cups.html
+++ b/doc/help/api-cups.html
@@ -400,8 +400,13 @@ div.contents ul.subcontents li {
<li><a href="#cupsAdminSetServerSettings" title="Set settings on the server.">cupsAdminSetServerSettings</a></li>
<li><a href="#cupsCancelJob" title="Cancel a print job on the default server.">cupsCancelJob</a></li>
<li><a href="#cupsCancelJob2" title="Cancel or purge a print job.">cupsCancelJob2</a></li>
+ <li><a href="#cupsConnectDest" title="Connect to the server for a destination.">cupsConnectDest</a></li>
+ <li><a href="#cupsConnectDestBlock" title="Connect to the server for a destination.">cupsConnectDestBlock</a></li>
+ <li><a href="#cupsCopyDest" title="Callback block">cupsCopyDest</a></li>
<li><a href="#cupsCreateJob" title="Create an empty job for streaming.">cupsCreateJob</a></li>
<li><a href="#cupsEncryption" title="Get the current encryption settings.">cupsEncryption</a></li>
+ <li><a href="#cupsEnumDests" title="Enumerate available destinations with a callback function.">cupsEnumDests</a></li>
+ <li><a href="#cupsEnumDestsBlock" title="Enumerate available destinations with a block.">cupsEnumDestsBlock</a></li>
<li><a href="#cupsFinishDocument" title="Finish sending a document.">cupsFinishDocument</a></li>
<li><a href="#cupsFreeDests" title="Free the memory used by the list of destinations.">cupsFreeDests</a></li>
<li><a href="#cupsFreeJobs" title="Free memory used by job data.">cupsFreeJobs</a></li>
@@ -463,27 +468,40 @@ connections.">cupsSetCredentials</a></li>
<li><a href="#cupsUser" title="Return the current user's name.">cupsUser</a></li>
</ul></li>
<li><a href="#TYPES">Data Types</a><ul class="code">
- <li><a href="#cups_client_cert_cb_t" title="Client credentials callback ">cups_client_cert_cb_t</a></li>
+ <li><a href="#cups_client_cert_cb_t" title="Client credentials callback
+">cups_client_cert_cb_t</a></li>
+ <li><a href="#cups_dest_block_t" title="Destination enumeration block
+">cups_dest_block_t</a></li>
+ <li><a href="#cups_dest_cb_t" title="Destination enumeration callback
+">cups_dest_cb_t</a></li>
<li><a href="#cups_dest_t" title="Destination">cups_dest_t</a></li>
- <li><a href="#cups_device_cb_t" title="Device callback ">cups_device_cb_t</a></li>
+ <li><a href="#cups_device_cb_t" title="Device callback
+">cups_device_cb_t</a></li>
+ <li><a href="#cups_dinfo_t" title="Destination capability and status
+information ">cups_dinfo_t</a></li>
<li><a href="#cups_job_t" title="Job">cups_job_t</a></li>
<li><a href="#cups_option_t" title="Printer Options">cups_option_t</a></li>
- <li><a href="#cups_password_cb2_t" title="New password callback ">cups_password_cb2_t</a></li>
+ <li><a href="#cups_password_cb2_t" title="New password callback
+">cups_password_cb2_t</a></li>
<li><a href="#cups_password_cb_t" title="Password callback">cups_password_cb_t</a></li>
<li><a href="#cups_ptype_t" title="Printer type/capability bits">cups_ptype_t</a></li>
- <li><a href="#cups_server_cert_cb_t" title="Server credentials callback ">cups_server_cert_cb_t</a></li>
+ <li><a href="#cups_server_cert_cb_t" title="Server credentials callback
+">cups_server_cert_cb_t</a></li>
+ <li><a href="#cups_size_t" title="Media Size ">cups_size_t</a></li>
</ul></li>
<li><a href="#STRUCTURES">Structures</a><ul class="code">
<li><a href="#cups_dest_s" title="Destination">cups_dest_s</a></li>
<li><a href="#cups_job_s" title="Job">cups_job_s</a></li>
<li><a href="#cups_option_s" title="Printer Options">cups_option_s</a></li>
+ <li><a href="#cups_size_s" title="Media Size ">cups_size_s</a></li>
</ul></li>
<li><a href="#VARIABLES">Variables</a><ul class="code">
<li><a href="#CF_RETURNS_RETAINED" title="Get the Apple language identifier associated with a
locale ID.">CF_RETURNS_RETAINED</a></li>
</ul></li>
<li><a href="#ENUMERATIONS">Constants</a><ul class="code">
- <li><a href="#cups_ptype_e" title="Printer type/capability bit constants">cups_ptype_e</a></li>
+ <li><a href="#cups_ptype_e" title="Printer type/capability bit
+constants">cups_ptype_e</a></li>
</ul></li>
</ul>
<!--
@@ -1152,6 +1170,108 @@ Use the <a href="#cupsLastError"><code>cupsLastError</code></a> and <a href="#cu
the cause of any failure.
</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.6&nbsp;</span><a name="cupsConnectDest">cupsConnectDest</a></h3>
+<p class="description">Connect to the server for a destination.</p>
+<p class="code">
+http_t *cupsConnectDest (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dest_t">cups_dest_t</a> *dest,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned flags,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int msec,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int *cancel,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *resource,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;size_t resourcesize,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dest_cb_t">cups_dest_cb_t</a> cb,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;void *user_data<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>dest</dt>
+<dd class="description">Destination</dd>
+<dt>flags</dt>
+<dd class="description">Connection flags</dd>
+<dt>msec</dt>
+<dd class="description">Timeout in milliseconds</dd>
+<dt>cancel</dt>
+<dd class="description">Pointer to &quot;cancel&quot; variable</dd>
+<dt>resource</dt>
+<dd class="description">Resource buffer</dd>
+<dt>resourcesize</dt>
+<dd class="description">Size of resource buffer</dd>
+<dt>cb</dt>
+<dd class="description">Callback function</dd>
+<dt>user_data</dt>
+<dd class="description">User data pointer</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Connection to server or <code>NULL</code></p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">Connect to the destination, returning a new http_t connection object and
+optionally the resource path to use for the destination. These calls will
+block until a connection is made, the timeout expires, the integer pointed
+to by &quot;cancel&quot; is non-zero, or the callback function (or block) returns 0,
+The caller is responsible for calling httpClose() on the returned object.
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.6&nbsp;</span><a name="cupsConnectDestBlock">cupsConnectDestBlock</a></h3>
+<p class="description">Connect to the server for a destination.</p>
+<p class="code">
+http_t *cupsConnectDestBlock (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dest_t">cups_dest_t</a> *dest,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned flags,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int msec,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int *cancel,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char *resource,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;size_t resourcesize,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dest_block_t">cups_dest_block_t</a> block<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>dest</dt>
+<dd class="description">Destination</dd>
+<dt>flags</dt>
+<dd class="description">Connection flags</dd>
+<dt>msec</dt>
+<dd class="description">Timeout in milliseconds</dd>
+<dt>cancel</dt>
+<dd class="description">Pointer to &quot;cancel&quot; variable</dd>
+<dt>resource</dt>
+<dd class="description">Resource buffer</dd>
+<dt>resourcesize</dt>
+<dd class="description">Size of resource buffer</dd>
+<dt>block</dt>
+<dd class="description">Callback block</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Connection to server or <code>NULL</code></p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">Connect to the destination, returning a new http_t connection object and
+optionally the resource path to use for the destination. These calls will
+block until a connection is made, the timeout expires, the integer pointed
+to by &quot;cancel&quot; is non-zero, or the callback function (or block) returns 0,
+The caller is responsible for calling httpClose() on the returned object.
+
+</p>
+<h3 class="function"><a name="cupsCopyDest">cupsCopyDest</a></h3>
+<p class="description">Callback block</p>
+<p class="code">
+int cupsCopyDest (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dest_t">cups_dest_t</a> *dest,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int num_dests,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dest_t">cups_dest_t</a> **dests<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>dest</dt>
+<dt>num_dests</dt>
+<dt>dests</dt>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Copy a destination.</p>
+<p class="discussion">Make a copy of the destination to an array of destinations (or just a single
+copy) - for use with the cupsEnumDests* functions. The caller is responsible
+for calling cupsFreeDests() on the returned object(s).
+
+</p>
<h3 class="function"><span class="info">&nbsp;CUPS 1.4/Mac OS X 10.6&nbsp;</span><a name="cupsCreateJob">cupsCreateJob</a></h3>
<p class="description">Create an empty job for streaming.</p>
<p class="code">
@@ -1201,6 +1321,86 @@ Note: The current encryption setting is tracked separately for each thread
in a program. Multi-threaded programs that override the setting via the
<a href="#cupsSetEncryption"><code>cupsSetEncryption</code></a> function need to do so in each thread for the same
setting to be used.</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.6&nbsp;</span><a name="cupsEnumDests">cupsEnumDests</a></h3>
+<p class="description">Enumerate available destinations with a callback function.</p>
+<p class="code">
+int cupsEnumDests (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned flags,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int msec,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int *cancel,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_ptype_t">cups_ptype_t</a> type,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_ptype_t">cups_ptype_t</a> mask,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dest_cb_t">cups_dest_cb_t</a> cb,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;void *user_data<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>flags</dt>
+<dd class="description">Enumeration flags</dd>
+<dt>msec</dt>
+<dd class="description">Timeout in milliseconds,
+-1 for indefinite</dd>
+<dt>cancel</dt>
+<dd class="description">Pointer to &quot;cancel&quot; variable</dd>
+<dt>type</dt>
+<dd class="description">Printer type bits</dd>
+<dt>mask</dt>
+<dd class="description">Mask for printer type bits</dd>
+<dt>cb</dt>
+<dd class="description">Callback function</dd>
+<dt>user_data</dt>
+<dd class="description">User data</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 on success, 0 on failure</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">Destinations are enumerated from one or more sources. The callback function
+receives the <code>user_data</code> pointer, destination name, instance, number of
+options, and options which can be used as input to the <a href="#cupsAddDest"><code>cupsAddDest</code></a>
+function. The function must return 1 to continue enumeration or 0 to stop.<br>
+<br>
+Enumeration happens on the current thread and does not return until all
+destinations have been enumerated or the callback function returns 0.
+
+</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.6&nbsp;</span><a name="cupsEnumDestsBlock">cupsEnumDestsBlock</a></h3>
+<p class="description">Enumerate available destinations with a block.</p>
+<p class="code">
+int cupsEnumDestsBlock (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;unsigned flags,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int timeout,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int *cancel,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_ptype_t">cups_ptype_t</a> type,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_ptype_t">cups_ptype_t</a> mask,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#cups_dest_block_t">cups_dest_block_t</a> block<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>flags</dt>
+<dd class="description">Enumeration flags</dd>
+<dt>timeout</dt>
+<dd class="description">Timeout in milliseconds, 0 for indefinite</dd>
+<dt>cancel</dt>
+<dd class="description">Pointer to &quot;cancel&quot; variable</dd>
+<dt>type</dt>
+<dd class="description">Printer type bits</dd>
+<dt>mask</dt>
+<dd class="description">Mask for printer type bits</dd>
+<dt>block</dt>
+<dd class="description">Block</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 on success, 0 on failure</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">Destinations are enumerated from one or more sources. The block receives the
+destination name, instance, number of options, and options which can be used
+as input to the <a href="#cupsAddDest"><code>cupsAddDest</code></a> function. The block must return 1 to
+continue enumeration or 0 to stop.<br>
+<br>
+Enumeration happens on the current thread and does not return until all
+destinations have been enumerated or the block returns 0.
+
+</p>
<h3 class="function"><span class="info">&nbsp;CUPS 1.4/Mac OS X 10.6&nbsp;</span><a name="cupsFinishDocument">cupsFinishDocument</a></h3>
<p class="description">Finish sending a document.</p>
<p class="code">
@@ -2332,20 +2532,40 @@ program. Multi-threaded programs that override the user name with the
name to be used.</p>
<h2 class="title"><a name="TYPES">Data Types</a></h2>
<h3 class="typedef"><span class="info">&nbsp;CUPS 1.5/Mac OS X 10.7&nbsp;</span><a name="cups_client_cert_cb_t">cups_client_cert_cb_t</a></h3>
-<p class="description">Client credentials callback </p>
+<p class="description">Client credentials callback
+</p>
<p class="code">
typedef int (*cups_client_cert_cb_t)(http_t *http, void *tls, cups_array_t *distinguished_names, void *user_data);
</p>
+<h3 class="typedef"><span class="info">&nbsp;CUPS 1.6&nbsp;</span><a name="cups_dest_block_t">cups_dest_block_t</a></h3>
+<p class="description">Destination enumeration block
+</p>
+<p class="code">
+typedef int (*cups_dest_block_t(unsigned flags, <a href="#cups_dest_t">cups_dest_t</a> *dest);
+</p>
+<h3 class="typedef"><span class="info">&nbsp;CUPS 1.6&nbsp;</span><a name="cups_dest_cb_t">cups_dest_cb_t</a></h3>
+<p class="description">Destination enumeration callback
+</p>
+<p class="code">
+typedef int (*cups_dest_cb_t)(void *user_data, unsigned flags, <a href="#cups_dest_t">cups_dest_t</a> *dest);
+</p>
<h3 class="typedef"><a name="cups_dest_t">cups_dest_t</a></h3>
<p class="description">Destination</p>
<p class="code">
typedef struct <a href="#cups_dest_s">cups_dest_s</a> cups_dest_t;
</p>
<h3 class="typedef"><span class="info">&nbsp;CUPS 1.4/Mac OS X 10.6&nbsp;</span><a name="cups_device_cb_t">cups_device_cb_t</a></h3>
-<p class="description">Device callback </p>
+<p class="description">Device callback
+</p>
<p class="code">
typedef void (*cups_device_cb_t)(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, void *user_data);
</p>
+<h3 class="typedef"><span class="info">&nbsp;CUPS 1.6&nbsp;</span><a name="cups_dinfo_t">cups_dinfo_t</a></h3>
+<p class="description">Destination capability and status
+information </p>
+<p class="code">
+typedef struct _cups_dinfo_s cups_dinfo_t;
+</p>
<h3 class="typedef"><a name="cups_job_t">cups_job_t</a></h3>
<p class="description">Job</p>
<p class="code">
@@ -2357,7 +2577,8 @@ typedef struct <a href="#cups_job_s">cups_job_s</a> cups_job_t;
typedef struct <a href="#cups_option_s">cups_option_s</a> cups_option_t;
</p>
<h3 class="typedef"><span class="info">&nbsp;CUPS 1.4/Mac OS X 10.6&nbsp;</span><a name="cups_password_cb2_t">cups_password_cb2_t</a></h3>
-<p class="description">New password callback </p>
+<p class="description">New password callback
+</p>
<p class="code">
typedef const char *(*cups_password_cb2_t)(const char *prompt, http_t *http, const char *method, const char *resource, void *user_data);
</p>
@@ -2372,10 +2593,16 @@ typedef const char *(*cups_password_cb_t)(const char *prompt);
typedef unsigned cups_ptype_t;
</p>
<h3 class="typedef"><span class="info">&nbsp;CUPS 1.5/Mac OS X 10.7&nbsp;</span><a name="cups_server_cert_cb_t">cups_server_cert_cb_t</a></h3>
-<p class="description">Server credentials callback </p>
+<p class="description">Server credentials callback
+</p>
<p class="code">
typedef int (*cups_server_cert_cb_t)(http_t *http, void *tls, cups_array_t *certs, void *user_data);
</p>
+<h3 class="typedef"><span class="info">&nbsp;CUPS 1.6&nbsp;</span><a name="cups_size_t">cups_size_t</a></h3>
+<p class="description">Media Size </p>
+<p class="code">
+typedef struct <a href="#cups_size_s">cups_size_s</a> cups_size_t;
+</p>
<h2 class="title"><a name="STRUCTURES">Structures</a></h2>
<h3 class="struct"><a name="cups_dest_s">cups_dest_s</a></h3>
<p class="description">Destination</p>
@@ -2449,6 +2676,20 @@ typedef int (*cups_server_cert_cb_t)(http_t *http, void *tls, cups_array_t *cert
<dt>value </dt>
<dd class="description">Value of option</dd>
</dl>
+<h3 class="struct"><span class="info">&nbsp;CUPS 1.6&nbsp;</span><a name="cups_size_s">cups_size_s</a></h3>
+<p class="description">Media Size </p>
+<p class="code">struct cups_size_s {<br>
+&nbsp;&nbsp;&nbsp;&nbsp;char media[128];<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int width, length, bottom, left, right, top;<br>
+};</p>
+<h4 class="members">Members</h4>
+<dl>
+<dt>media[128] </dt>
+<dd class="description">Media name to use</dd>
+<dt>top </dt>
+<dd class="description">Top margin in hundredths of
+millimeters</dd>
+</dl>
<h2 class="title"><a name="VARIABLES">Variables</a></h2>
<h3 class="variable"><a name="CF_RETURNS_RETAINED">CF_RETURNS_RETAINED</a></h3>
<p class="description">Get the Apple language identifier associated with a
@@ -2456,11 +2697,13 @@ locale ID.</p>
<p class="code">const char *locale) CF_RETURNS_RETAINED;</p>
<h2 class="title"><a name="ENUMERATIONS">Constants</a></h2>
<h3 class="enumeration"><a name="cups_ptype_e">cups_ptype_e</a></h3>
-<p class="description">Printer type/capability bit constants</p>
+<p class="description">Printer type/capability bit
+constants</p>
<h4 class="constants">Constants</h4>
<dl>
<dt>CUPS_PRINTER_AUTHENTICATED <span class="info">&nbsp;CUPS 1.2/Mac OS X 10.5&nbsp;</span></dt>
-<dd class="description">Printer requires authentication </dd>
+<dd class="description">Printer requires authentication
+</dd>
<dt>CUPS_PRINTER_BIND </dt>
<dd class="description">Can bind output</dd>
<dt>CUPS_PRINTER_BW </dt>
@@ -2472,7 +2715,8 @@ locale ID.</p>
<dt>CUPS_PRINTER_COLOR </dt>
<dd class="description">Can do color printing</dd>
<dt>CUPS_PRINTER_COMMANDS <span class="info">&nbsp;CUPS 1.2/Mac OS X 10.5&nbsp;</span></dt>
-<dd class="description">Printer supports maintenance commands </dd>
+<dd class="description">Printer supports maintenance commands
+</dd>
<dt>CUPS_PRINTER_COPIES </dt>
<dd class="description">Can do copies</dd>
<dt>CUPS_PRINTER_COVER </dt>
@@ -2480,15 +2724,12 @@ locale ID.</p>
<dt>CUPS_PRINTER_DEFAULT </dt>
<dd class="description">Default printer on network</dd>
<dt>CUPS_PRINTER_DELETE <span class="info">&nbsp;CUPS 1.2/Mac OS X 10.5&nbsp;</span></dt>
-<dd class="description">Delete printer </dd>
-<dt>CUPS_PRINTER_DISCOVERED <span class="info">&nbsp;CUPS 1.3/Mac OS X 10.5&nbsp;</span></dt>
-<dd class="description">Printer was automatically discovered and added </dd>
+<dd class="description">Delete printer
+</dd>
<dt>CUPS_PRINTER_DUPLEX </dt>
<dd class="description">Can do duplexing</dd>
<dt>CUPS_PRINTER_FAX </dt>
<dd class="description">Fax queue</dd>
-<dt>CUPS_PRINTER_IMPLICIT </dt>
-<dd class="description">Implicit class</dd>
<dt>CUPS_PRINTER_LARGE </dt>
<dd class="description">Can do D/E/A1/A0</dd>
<dt>CUPS_PRINTER_LOCAL </dt>
@@ -2496,9 +2737,11 @@ locale ID.</p>
<dt>CUPS_PRINTER_MEDIUM </dt>
<dd class="description">Can do Tabloid/B/C/A3/A2</dd>
<dt>CUPS_PRINTER_MFP <span class="info">&nbsp;CUPS 1.4/Mac OS X 10.6&nbsp;</span></dt>
-<dd class="description">Printer with scanning capabilities </dd>
+<dd class="description">Printer with scanning capabilities
+</dd>
<dt>CUPS_PRINTER_NOT_SHARED <span class="info">&nbsp;CUPS 1.2/Mac OS X 10.5&nbsp;</span></dt>
-<dd class="description">Printer is not shared </dd>
+<dd class="description">Printer is not shared
+</dd>
<dt>CUPS_PRINTER_PUNCH </dt>
<dd class="description">Can punch output</dd>
<dt>CUPS_PRINTER_REJECTING </dt>
@@ -2506,7 +2749,8 @@ locale ID.</p>
<dt>CUPS_PRINTER_REMOTE </dt>
<dd class="description">Remote printer or class</dd>
<dt>CUPS_PRINTER_SCANNER <span class="info">&nbsp;CUPS 1.4/Mac OS X 10.6&nbsp;</span></dt>
-<dd class="description">Scanner-only device </dd>
+<dd class="description">Scanner-only device
+</dd>
<dt>CUPS_PRINTER_SMALL </dt>
<dd class="description">Can do Letter/Legal/A4</dd>
<dt>CUPS_PRINTER_SORT </dt>
diff --git a/doc/help/api-httpipp.html b/doc/help/api-httpipp.html
index b0f94ecba..b04021e9c 100644
--- a/doc/help/api-httpipp.html
+++ b/doc/help/api-httpipp.html
@@ -468,6 +468,8 @@ request-uri.">httpMD5Final</a></li>
<li><a href="#httpRead" title="Read data from a HTTP connection.">httpRead</a></li>
<li><a href="#httpRead2" title="Read data from a HTTP connection.">httpRead2</a></li>
<li><a href="#httpReconnect" title="Reconnect to a HTTP server.">httpReconnect</a></li>
+ <li><a href="#httpReconnect2" title="Reconnect to a HTTP server with timeout and optional
+cancel.">httpReconnect2</a></li>
<li><a href="#httpSeparate" title="Separate a Universal Resource Identifier into its
components.">httpSeparate</a></li>
<li><a href="#httpSeparate2" title="Separate a Universal Resource Identifier into its
@@ -516,18 +518,21 @@ in seconds.">ippDateToTime</a></li>
<li><a href="#ippEnumValue" title="Return the value associated with a given enum string.">ippEnumValue</a></li>
<li><a href="#ippErrorString" title="Return a name for the given status code.">ippErrorString</a></li>
<li><a href="#ippErrorValue" title="Return a status code for the given name.">ippErrorValue</a></li>
- <li><a href="#ippFindAttribute" title="Find a named attribute in a request...">ippFindAttribute</a></li>
- <li><a href="#ippFindNextAttribute" title="Find the next named attribute in a request...">ippFindNextAttribute</a></li>
+ <li><a href="#ippFindAttribute" title="Find a named attribute in a request.">ippFindAttribute</a></li>
+ <li><a href="#ippFindNextAttribute" title="Find the next named attribute in a request.">ippFindNextAttribute</a></li>
<li><a href="#ippFirstAttribute" title="Return the first attribute in the message.">ippFirstAttribute</a></li>
<li><a href="#ippGetBoolean" title="Get a boolean value for an attribute.">ippGetBoolean</a></li>
<li><a href="#ippGetCollection" title="Get a collection value for an attribute.">ippGetCollection</a></li>
<li><a href="#ippGetCount" title="Get the number of values in an attribute.">ippGetCount</a></li>
+ <li><a href="#ippGetDate" title="Get a date value for an attribute.">ippGetDate</a></li>
<li><a href="#ippGetGroupTag" title="Get the group associated with an attribute.">ippGetGroupTag</a></li>
<li><a href="#ippGetInteger" title="Get the integer/enum value for an attribute.">ippGetInteger</a></li>
<li><a href="#ippGetName" title="Get the attribute name.">ippGetName</a></li>
<li><a href="#ippGetOperation" title="Get the operation ID in an IPP message.">ippGetOperation</a></li>
+ <li><a href="#ippGetRange" title="Get a rangeOfInteger value from an attribute.">ippGetRange</a></li>
<li><a href="#ippGetRequestId" title="Get the request ID from an IPP message.">ippGetRequestId</a></li>
<li><a href="#ippGetResolution" title="Get a resolution value for an attribute.">ippGetResolution</a></li>
+ <li><a href="#ippGetState" title="Get the IPP message state.">ippGetState</a></li>
<li><a href="#ippGetStatusCode" title="Get the status code from an IPP response or event message.">ippGetStatusCode</a></li>
<li><a href="#ippGetString" title="Return the value...">ippGetString</a></li>
<li><a href="#ippGetValueTag" title="Get the value tag for an attribute.">ippGetValueTag</a></li>
@@ -544,6 +549,7 @@ in seconds.">ippDateToTime</a></li>
<li><a href="#ippReadIO" title="Read data for an IPP message.">ippReadIO</a></li>
<li><a href="#ippSetBoolean" title="Set a boolean value in an attribute.">ippSetBoolean</a></li>
<li><a href="#ippSetCollection" title="Set a collection value in an attribute.">ippSetCollection</a></li>
+ <li><a href="#ippSetDate" title="Set a date value in an attribute.">ippSetDate</a></li>
<li><a href="#ippSetGroupTag" title="Set the group tag of an attribute.">ippSetGroupTag</a></li>
<li><a href="#ippSetInteger" title="Set an integer or enum value in an attribute.">ippSetInteger</a></li>
<li><a href="#ippSetName" title="Set the name of an attribute.">ippSetName</a></li>
@@ -552,6 +558,7 @@ in seconds.">ippDateToTime</a></li>
<li><a href="#ippSetRange" title="Set a rangeOfInteger value in an attribute.">ippSetRange</a></li>
<li><a href="#ippSetRequestId" title="Set the request ID in an IPP message.">ippSetRequestId</a></li>
<li><a href="#ippSetResolution" title="Set a resolution value in an attribute.">ippSetResolution</a></li>
+ <li><a href="#ippSetState" title="Set the current state of the IPP message.">ippSetState</a></li>
<li><a href="#ippSetStatusCode" title="Set the status code in an IPP response or event message.">ippSetStatusCode</a></li>
<li><a href="#ippSetString" title="Set a string value in an attribute.">ippSetString</a></li>
<li><a href="#ippSetValueTag" title="Set the value tag of an attribute.">ippSetValueTag</a></li>
@@ -2350,6 +2357,26 @@ int httpReconnect (<br>
</dl>
<h4 class="returnvalue">Return Value</h4>
<p class="description">0 on success, non-zero on failure</p>
+<h3 class="function"><a name="httpReconnect2">httpReconnect2</a></h3>
+<p class="description">Reconnect to a HTTP server with timeout and optional
+cancel.</p>
+<p class="code">
+int httpReconnect2 (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#http_t">http_t</a> *http,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int msec,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int *cancel<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>http</dt>
+<dd class="description">Connection to server</dd>
+<dt>msec</dt>
+<dd class="description">Timeout in milliseconds</dd>
+<dt>cancel</dt>
+<dd class="description">Pointer to &quot;cancel&quot; variable</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">0 on success, non-zero on failure</p>
<h3 class="function"><span class="info">&nbsp;DEPRECATED&nbsp;</span><a name="httpSeparate">httpSeparate</a></h3>
<p class="description">Separate a Universal Resource Identifier into its
components.</p>
@@ -3415,7 +3442,7 @@ void ippDeleteAttribute (<br>
<p class="code">
int ippDeleteValues (<br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_attribute_t">ipp_attribute_t</a> *attr,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_attribute_t">ipp_attribute_t</a> **attr,<br>
&nbsp;&nbsp;&nbsp;&nbsp;int element,<br>
&nbsp;&nbsp;&nbsp;&nbsp;int count<br>
);</p>
@@ -3433,8 +3460,10 @@ int ippDeleteValues (<br>
<h4 class="returnvalue">Return Value</h4>
<p class="description">1 on success, 0 on failure</p>
<h4 class="discussion">Discussion</h4>
-<p class="discussion">The <code>element</code> parameter specifies the first value to delete, starting at 0. It
-must be less than the number of values returned by <a href="#ippGetCount"><code>ippGetCount</code></a>.<br>
+<p class="discussion">The <code>element</code> parameter specifies the first value to delete, starting at
+0. It must be less than the number of values returned by <a href="#ippGetCount"><code>ippGetCount</code></a>.<br>
+<br>
+The <code>attr</code> parameter may be modified as a result of setting the value.<br>
<br>
Deleting all values in an attribute deletes the attribute.
@@ -3498,7 +3527,7 @@ ipp_status_t ippErrorValue (<br>
<h4 class="returnvalue">Return Value</h4>
<p class="description">IPP status code</p>
<h3 class="function"><a name="ippFindAttribute">ippFindAttribute</a></h3>
-<p class="description">Find a named attribute in a request...</p>
+<p class="description">Find a named attribute in a request.</p>
<p class="code">
<a href="#ipp_attribute_t">ipp_attribute_t</a> *ippFindAttribute (<br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
@@ -3517,7 +3546,7 @@ ipp_status_t ippErrorValue (<br>
<h4 class="returnvalue">Return Value</h4>
<p class="description">Matching attribute</p>
<h3 class="function"><a name="ippFindNextAttribute">ippFindNextAttribute</a></h3>
-<p class="description">Find the next named attribute in a request...</p>
+<p class="description">Find the next named attribute in a request.</p>
<p class="code">
<a href="#ipp_attribute_t">ipp_attribute_t</a> *ippFindNextAttribute (<br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
@@ -3603,6 +3632,27 @@ int ippGetCount (<br>
</dl>
<h4 class="returnvalue">Return Value</h4>
<p class="description">Number of values or -1 on error</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.6&nbsp;</span><a name="ippGetDate">ippGetDate</a></h3>
+<p class="description">Get a date value for an attribute.</p>
+<p class="code">
+const <a href="#ipp_uchar_t">ipp_uchar_t</a> *ippGetDate (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_attribute_t">ipp_attribute_t</a> *attr,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int element<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>attr</dt>
+<dd class="description">IPP attribute</dd>
+<dt>element</dt>
+<dd class="description">Value number (0-based)</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Date value or <code>NULL</code></p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The <code>element</code> parameter specifies which value to get from 0 to
+<a href="#ippGetCount(attr)"><code>ippGetCount(attr)</code></a> - 1.
+
+</p>
<h3 class="function"><span class="info">&nbsp;CUPS 1.6&nbsp;</span><a name="ippGetGroupTag">ippGetGroupTag</a></h3>
<p class="description">Get the group associated with an attribute.</p>
<p class="code">
@@ -3663,6 +3713,30 @@ ipp_op_t ippGetOperation (<br>
</dl>
<h4 class="returnvalue">Return Value</h4>
<p class="description">Operation ID or -1 on error</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.6&nbsp;</span><a name="ippGetRange">ippGetRange</a></h3>
+<p class="description">Get a rangeOfInteger value from an attribute.</p>
+<p class="code">
+int ippGetRange (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_attribute_t">ipp_attribute_t</a> *attr,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int element,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int *uppervalue<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>attr</dt>
+<dd class="description">IPP attribute</dd>
+<dt>element</dt>
+<dd class="description">Value number (0-based)</dd>
+<dt>uppervalue</dt>
+<dd class="description">Upper value of range</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">Lower value of range or -1</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The <code>element</code> parameter specifies which value to get from 0 to
+<a href="#ippGetCount(attr)"><code>ippGetCount(attr)</code></a> - 1.
+
+</p>
<h3 class="function"><span class="info">&nbsp;CUPS 1.6&nbsp;</span><a name="ippGetRequestId">ippGetRequestId</a></h3>
<p class="description">Get the request ID from an IPP message.</p>
<p class="code">
@@ -3703,6 +3777,19 @@ int ippGetResolution (<br>
<a href="#ippGetCount(attr)"><code>ippGetCount(attr)</code></a> - 1.
</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.6&nbsp;</span><a name="ippGetState">ippGetState</a></h3>
+<p class="description">Get the IPP message state.</p>
+<p class="code">
+<a href="#ipp_state_t">ipp_state_t</a> ippGetState (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">IPP message state value</p>
<h3 class="function"><span class="info">&nbsp;CUPS 1.6&nbsp;</span><a name="ippGetStatusCode">ippGetStatusCode</a></h3>
<p class="description">Get the status code from an IPP response or event message.</p>
<p class="code">
@@ -3972,6 +4059,38 @@ The <code>element</code> parameter specifies which value to set from 0 to
<a href="#ippGetCount(attr)"><code>ippGetCount(attr)</code></a>.
</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.6&nbsp;</span><a name="ippSetDate">ippSetDate</a></h3>
+<p class="description">Set a date value in an attribute.</p>
+<p class="code">
+int ippSetDate (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_attribute_t">ipp_attribute_t</a> **attr,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;int element,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;const <a href="#ipp_uchar_t">ipp_uchar_t</a> *datevalue<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+<dt>attr</dt>
+<dd class="description">IPP attribute</dd>
+<dt>element</dt>
+<dd class="description">Value number (0-based)</dd>
+<dt>datevalue</dt>
+<dd class="description">Date value</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 on success, 0 on failure</p>
+<h4 class="discussion">Discussion</h4>
+<p class="discussion">The <code>ipp</code> parameter refers to the IPP message containing the attribute that was
+previously created using the <a href="#ippNew"><code>ippNew</code></a> or <a href="#ippNewRequest"><code>ippNewRequest</code></a> functions.<br>
+<br>
+The <code>attr</code> parameter may be modified as a result of setting the value.<br>
+<br>
+The <code>element</code> parameter specifies which value to set from 0 to
+<a href="#ippGetCount(attr)"><code>ippGetCount(attr)</code></a>.
+
+</p>
<h3 class="function"><span class="info">&nbsp;CUPS 1.6&nbsp;</span><a name="ippSetGroupTag">ippSetGroupTag</a></h3>
<p class="description">Set the group tag of an attribute.</p>
<p class="code">
@@ -4190,6 +4309,22 @@ The <code>element</code> parameter specifies which value to set from 0 to
<a href="#ippGetCount(attr)"><code>ippGetCount(attr)</code></a>.
</p>
+<h3 class="function"><span class="info">&nbsp;CUPS 1.6&nbsp;</span><a name="ippSetState">ippSetState</a></h3>
+<p class="description">Set the current state of the IPP message.</p>
+<p class="code">
+int ippSetState (<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_t">ipp_t</a> *ipp,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;<a href="#ipp_state_t">ipp_state_t</a> state<br>
+);</p>
+<h4 class="parameters">Parameters</h4>
+<dl>
+<dt>ipp</dt>
+<dd class="description">IPP message</dd>
+<dt>state</dt>
+<dd class="description">IPP state value</dd>
+</dl>
+<h4 class="returnvalue">Return Value</h4>
+<p class="description">1 on success, 0 on failure</p>
<h3 class="function"><span class="info">&nbsp;CUPS 1.6&nbsp;</span><a name="ippSetStatusCode">ippSetStatusCode</a></h3>
<p class="description">Set the status code in an IPP response or event message.</p>
<p class="code">
@@ -5093,6 +5228,8 @@ are server-oriented...</p>
<dd class="description">Hold a job for printing</dd>
<dt>IPP_IDENTIFY_PRINTER </dt>
<dd class="description">Identify-Printer (proposed IPP JPS3)</dd>
+<dt>IPP_OP_CUPS_INVALID </dt>
+<dd class="description">Invalid operation name for <a href="#ippOpValue"><code>ippOpValue</code></a></dd>
<dt>IPP_PAUSE_PRINTER </dt>
<dd class="description">Stop a printer</dd>
<dt>IPP_PRINT_JOB </dt>
@@ -5261,10 +5398,16 @@ are server-oriented...</p>
<dd class="description">client-error-request-value-too-long</dd>
<dt>IPP_SERVICE_UNAVAILABLE </dt>
<dd class="description">server-error-service-unavailable</dd>
+<dt>IPP_STATUS_CUPS_INVALID </dt>
+<dd class="description">Invalid status name for <a href="#ippErrorValue"><code>ippErrorValue</code></a></dd>
<dt>IPP_TEMPORARY_ERROR </dt>
<dd class="description">server-error-temporary-error</dd>
<dt>IPP_TIMEOUT </dt>
<dd class="description">client-error-timeout</dd>
+<dt>IPP_TOO_MANY_DOCUMENTS </dt>
+<dd class="description">server-error-too-many-documents</dd>
+<dt>IPP_TOO_MANY_JOBS </dt>
+<dd class="description">server-error-too-many-jobs</dd>
<dt>IPP_TOO_MANY_SUBSCRIPTIONS </dt>
<dd class="description">client-error-too-many-subscriptions</dd>
<dt>IPP_UPGRADE_REQUIRED </dt>
@@ -5286,6 +5429,8 @@ are server-oriented...</p>
<dd class="description">Boolean value</dd>
<dt>IPP_TAG_CHARSET </dt>
<dd class="description">Character set value</dd>
+<dt>IPP_TAG_CUPS_INVALID </dt>
+<dd class="description">Invalid tag name for <a href="#ippTagValue"><code>ippTagValue</code></a></dd>
<dt>IPP_TAG_DATE </dt>
<dd class="description">Date/time value</dd>
<dt>IPP_TAG_DEFAULT </dt>
diff --git a/doc/help/options.html b/doc/help/options.html
index 0cfa74135..546f2ec1a 100644
--- a/doc/help/options.html
+++ b/doc/help/options.html
@@ -95,8 +95,8 @@ printing.</P>
printer options using the <CODE>-o</CODE> option:</P>
<PRE CLASS="command">
-lp -o landscape -o scaling=75 -o media=A4 filename.jpg
-lpr -o landscape -o scaling=75 -o media=A4 filename.jpg
+lp -o landscape -o fit-to-page -o media=A4 filename.jpg
+lpr -o landscape -o fit-to-page -o media=A4 filename.jpg
</PRE>
<P>The available printer options vary depending on the printer.
@@ -662,117 +662,5 @@ lpr -o nowrap filename
</PRE>
-<H2 CLASS="title"><SPAN CLASS="info">Not Supported on Mac OS X</SPAN><A NAME="IMAGEOPTIONS">Image Options</A></H2>
-
-<P>CUPS supports several options that are only used when printing
-image files. These options have absolutely no effect on PostScript, PDF,
-HP-GL/2, or text files.</P>
-
-<H3><A NAME="position">Positioning Images</A></H3>
-
-<P>The <CODE>-o position=name</CODE> option specifies the position of the
-image on the page:
-
-<UL>
-
- <LI><CODE>center</CODE> - Center the image on the page (default)
-
- <LI><CODE>top</CODE> - Print the image centered at the top of the page
-
- <LI><CODE>left</CODE> - Print the image centered on the left of page
-
- <LI><CODE>right</CODE> - Print the image centered on the right of the page
-
- <LI><CODE>top-left</CODE> - Print the image at the top left corner of
- the page
-
- <LI><CODE>top-right</CODE> - Print the image at the top right corner of
- the page
-
- <LI><CODE>bottom</CODE> - Print the image centered at the bottom of
- the page
-
- <LI><CODE>bottom-left</CODE> - Print the image at the bottom left
- corner of the page
-
- <LI><CODE>bottom-right</CODE> - Print the image at the bottom right
- corner of the page
-
-</UL>
-
-<H3><A NAME="scaling">Scaling Images</A></H3>
-
-<P>The <CODE>-o scaling=percent</CODE>, <CODE>-o
-ppi=value</CODE>, and <CODE>-o natural-scaling=percent</CODE>
-options change the size of a printed image:
-
-<PRE CLASS="command">
-lp -o scaling=<EM>percent</EM> filename
-lp -o ppi=<EM>value</EM> filename
-lpr -o natural-scaling=<EM>percent</EM> filename
-</PRE>
-
-<P>The <CODE>scaling=percent</CODE> value is a number from 1 to 800
-specifying the size in relation to the page (<EM>not</EM> the image.) A
-scaling of 100 percent will fill the page as completely as the image
-aspect ratio allows. A scaling of 200 percent will print on up to 4
-pages.
-
-<P>The <CODE>ppi=value</CODE> value is a number from 1 to 1200 specifying the
-resolution of the image in pixels per inch. An image that is 3000x2400
-pixels will print 10x8 inches at 300 pixels per inch, for example. If
-the specified resolution makes the image larger than the page, multiple
-pages will be printed to satisfy the request.
-
-<P>The <CODE>natural-scaling=percent</CODE> value is a number
-from 1 to 800 specifying the size in relation to the natural
-image size. A scaling of 100 percent will print the image at its
-natural size, while a scaling of 50 percent will print the image
-at half its natural size. If the specified scaling makes the
-image larger than the page, multiple pages will be printed to
-satisfy the request.
-
-
-<H2 CLASS="title"><A NAME="HPGL2OPTIONS">HP-GL/2 Options</A></H2>
-
-<P>CUPS supports several options that are only used when printing
-HP-GL/2 files. These options have absolutely no effect on PostScript, PDF,
-image, or text files.</P>
-
-<H3><A NAME="blackplot">Printing in Black</A></H3>
-
-<P>The <CODE>-o blackplot</CODE> option specifies that all pens should
-plot in black:</P>
-
-<PRE CLASS="command">
-lp -o blackplot filename
-lpr -o blackplot filename
-</PRE>
-
-<P>The default is to use the colors defined in the plot file or the
-standard pen colors defined in the HP-GL/2 reference manual from
-Hewlett Packard.
-
-<H3><A NAME="penwidth">Setting the Default Pen Width</A></H3>
-
-<P>The <CODE>-o penwidth=value</CODE> option specifies the default pen
-width for HP-GL/2 files:</P>
-
-<PRE CLASS="command">
-lp -o penwidth=<EM>value</EM> filename
-lpr -o penwidth=<EM>value</EM> filename
-</PRE>
-
-<P>The pen width <CODE>value</CODE> specifies the pen width in micrometers.
-The default value of 1000 produces lines that are 1 millimeter in width.
-Specifying a pen width of 0 produces lines that are exactly 1 pixel wide.</P>
-
-<BLOCKQUOTE><B>Note:</B>
-
-<P>This option is ignored when the pen widths are set in the plot
-file.
-
-</BLOCKQUOTE>
-
</BODY>
</HTML>
diff --git a/doc/help/policies.html b/doc/help/policies.html
index 14a5b4b87..18f4c80e9 100644
--- a/doc/help/policies.html
+++ b/doc/help/policies.html
@@ -36,7 +36,7 @@ HREF="ref-cupsd-conf.html#LimitIPP"><TT>Limit</TT></A> subsections which list th
4 Require user @OWNER @SYSTEM
5 Order deny,allow
6 &lt;/Limit>
- 7
+ 7
8 # All administration operations require an administrator
to authenticate...
9 &lt;Limit CUPS-Add-Printer CUPS-Delete-Printer CUPS-Add-Class
@@ -45,7 +45,7 @@ HREF="ref-cupsd-conf.html#LimitIPP"><TT>Limit</TT></A> subsections which list th
11 Require user @SYSTEM
12 Order deny,allow
13 &lt;/Limit>
-14
+14
15 # All printer operations require a printer operator
to authenticate...
16 &lt;Limit Pause-Printer Resume-Printer
@@ -59,14 +59,14 @@ HREF="ref-cupsd-conf.html#LimitIPP"><TT>Limit</TT></A> subsections which list th
18 Require user <em>varies by OS</em>
19 Order deny,allow
20 &lt;/Limit>
-21
+21
22 # Only the owner or an administrator can cancel or
authenticate a job...
23 &lt;Limit Cancel-Job CUPS-Authenticate-Job>
24 Require user @OWNER @SYSTEM
25 Order deny,allow
26 &lt;/Limit>
-27
+27
28 &lt;Limit All>
29 Order deny,allow
30 &lt;/Limit>
@@ -106,7 +106,7 @@ HREF="ref-cupsd-conf.html#LimitIPP"><TT>Limit</TT></A> subsections which list th
11 Require user @SYSTEM
12 Order deny,allow
13 &lt;/Limit>
-14
+14
15 # All printer operations require a printer operator
to authenticate...
16 &lt;Limit Pause-Printer Resume-Printer
@@ -380,12 +380,12 @@ HREF="ref-cupsd-conf.html#LimitIPP"><TT>Limit</TT></A> subsections which list th
<TD>Prints a job after others.</TD>
</TR>
<TR>
- <TD NOWRAP><TT>CUPS-Get-Default</TT></TD>
+ <TD NOWRAP><TT>CUPS-Get-Default</TT> *</TD>
<TD>Yes</TD>
<TD>Gets the server/network default printer or class.</TD>
</TR>
<TR>
- <TD NOWRAP><TT>CUPS-Get-Printers</TT></TD>
+ <TD NOWRAP><TT>CUPS-Get-Printers</TT> *</TD>
<TD>Yes</TD>
<TD>Gets a list of printers and/or classes.</TD>
</TR>
@@ -395,12 +395,12 @@ HREF="ref-cupsd-conf.html#LimitIPP"><TT>Limit</TT></A> subsections which list th
<TD>Adds or modifies a printer.</TD>
</TR>
<TR>
- <TD NOWRAP><TT>CUPS-Delete-Printer</TT></TD>
+ <TD NOWRAP><TT>CUPS-Delete-Printer</TT> *</TD>
<TD>Yes</TD>
<TD>Removes a printer.</TD>
</TR>
<TR>
- <TD NOWRAP><TT>CUPS-Get-Classes</TT></TD>
+ <TD NOWRAP><TT>CUPS-Get-Classes</TT> *</TD>
<TD>Yes</TD>
<TD>Gets a list of classes.</TD>
</TR>
@@ -410,7 +410,7 @@ HREF="ref-cupsd-conf.html#LimitIPP"><TT>Limit</TT></A> subsections which list th
<TD>Adds or modifies a class.</TD>
</TR>
<TR>
- <TD NOWRAP><TT>CUPS-Delete-Class</TT></TD>
+ <TD NOWRAP><TT>CUPS-Delete-Class</TT> *</TD>
<TD>Yes</TD>
<TD>Removes a class.</TD>
</TR>
@@ -427,17 +427,17 @@ HREF="ref-cupsd-conf.html#LimitIPP"><TT>Limit</TT></A> subsections which list th
attribute to false.</TD>
</TR>
<TR>
- <TD NOWRAP><TT>CUPS-Set-Default</TT></TD>
+ <TD NOWRAP><TT>CUPS-Set-Default</TT> *</TD>
<TD>Yes</TD>
<TD>Sets the server/network default printer or class.</TD>
</TR>
<TR>
- <TD NOWRAP><TT>CUPS-Get-Devices</TT></TD>
+ <TD NOWRAP><TT>CUPS-Get-Devices</TT> *</TD>
<TD>Yes</TD>
<TD>Gets a list of printer devices.</TD>
</TR>
<TR>
- <TD NOWRAP><TT>CUPS-Get-PPDs</TT></TD>
+ <TD NOWRAP><TT>CUPS-Get-PPDs</TT> *</TD>
<TD>Yes</TD>
<TD>Gets a list of printer drivers or manufacturers.</TD>
</TR>
@@ -459,6 +459,7 @@ HREF="ref-cupsd-conf.html#LimitIPP"><TT>Limit</TT></A> subsections which list th
</TBODY>
</TABLE></DIV>
+<P>* = These operations only apply to the default policy.</P>
<H2 CLASS="title"><A NAME="CREATING">Creating Your Own Policies</A></H2>
@@ -556,7 +557,7 @@ Allow from @LOCAL</PRE></TD>
5 Order allow,deny
6 Allow from 10.0.2.0/24
7 &lt;/Limit>
- 8
+ 8
9 # All administration operations require a lab technician
or an administrator to authenticate...
10 &lt;Limit Pause-Printer Resume-Printer
diff --git a/doc/help/ppd-compiler.html b/doc/help/ppd-compiler.html
index 67fdfbc0e..b946ff652 100644
--- a/doc/help/ppd-compiler.html
+++ b/doc/help/ppd-compiler.html
@@ -345,7 +345,7 @@ div.contents ul.subcontents li {
PPD compiler documentation for CUPS.
- Copyright 2007-2010 by Apple Inc.
+ Copyright 2007-2012 by Apple Inc.
Copyright 1997-2007 by Easy Software Products.
These coded instructions, statements, and computer programs are the
@@ -361,6 +361,12 @@ div.contents ul.subcontents li {
(PPD) file compiler. The PPD compiler generates PPD files from simple text files
that describe the features and capabilities of one or more printers.</P>
+<BLOCKQUOTE><B>Note:</B>
+
+<P>The PPD compiler and related tools are deprecated and will be removed in a future release of CUPS.</P>
+
+</BLOCKQUOTE>
+
<div class='summary'><table summary='General Information'>
<tbody>
<tr>
diff --git a/doc/help/ref-client-conf.html b/doc/help/ref-client-conf.html
index 5b4e7e772..a69b568d3 100644
--- a/doc/help/ref-client-conf.html
+++ b/doc/help/ref-client-conf.html
@@ -71,5 +71,20 @@ ServerName foo.bar.com:8631
present, only the last one is used. This directive is not supported on Mac OS X 10.7 or later.</P>
</BLOCKQUOTE>
+
+<H2 CLASS="title"><SPAN CLASS="info">CUPS 1.6</SPAN><A NAME="User">User</A></H2>
+
+<H3>Examples</H3>
+
+<PRE CLASS="command">
+User joe
+User bob
+</PRE>
+
+<H3>Description</H3>
+
+<P>The <CODE>User</CODE> directive sets the user name to use. The default is the username associated with the current login.</P>
+
+
</BODY>
</HTML>
diff --git a/doc/help/ref-cupsd-conf.html.in b/doc/help/ref-cupsd-conf.html.in
index d14d0d7c0..38f00d2a3 100644
--- a/doc/help/ref-cupsd-conf.html.in
+++ b/doc/help/ref-cupsd-conf.html.in
@@ -1675,6 +1675,21 @@ copies to 100.</P>
</BLOCKQUOTE>
+<H2 CLASS="title"><SPAN CLASS="info">CUPS 1.6</SPAN><A NAME="MaxHoldTime">MaxHoldTime</A></H2>
+
+<H3>Examples</H3>
+
+<PRE CLASS="command">
+MaxHoldTime 10800
+MaxHoldTime 0
+</PRE>
+
+<H3>Description</H3>
+
+<P>The <CODE>MaxHoldTime</CODE> directive controls the maximum number of seconds allowed for a job to remain in the "indefinite" hold state. The job is canceled automatically if it remains held indefinitely longer than the specified number of seconds.</P>
+
+<p>The default setting is 0 which disables this functionality.</P>
+
<H2 CLASS="title"><A NAME="MaxJobs">MaxJobs</A></H2>
diff --git a/doc/help/spec-ipp.html b/doc/help/spec-ipp.html
index 01d4086df..2b6c7a3d0 100644
--- a/doc/help/spec-ipp.html
+++ b/doc/help/spec-ipp.html
@@ -2277,23 +2277,23 @@ defined:
</ul>
-<h4><a name="page-bottom">page-bottom (integer(0:MAX))</a></h4>
+<h4><a name="page-bottom">page-bottom (integer(0:MAX))</a><span class="info">Deprecated</span></h4>
<p>The page-bottom attribute specifies the bottom margin in points (72 points
equals 1 inch). The default value is the device physical margin.
-<h4><a name="page-label">page-label (text(MAX))</a><span class='info'>CUPS 1.1.7</span></h4>
+<h4><a name="page-label">page-label (text(MAX))</a><span class='info'>Deprecated</span></h4>
<p>The page-label attribute provides a text value to place in
the header and footer on each page. If a classification level is
set on the server, then this classification is printed before
the page label.
-<h4><a name="page-left">page-left (integer(0:MAX))</a></h4>
+<h4><a name="page-left">page-left (integer(0:MAX))</a><span class="info">Deprecated</span></h4>
<p>The page-left attribute specifies the left margin in points (72 points
equals 1 inch). The default value is the device physical margin.
-<h4><a name="page-right">page-right (integer(0:MAX))</a></h4>
+<h4><a name="page-right">page-right (integer(0:MAX))</a><span class="info">Deprecated</span></h4>
<p>The page-right attribute specifies the right margin in points (72 points
equals 1 inch). The default value is the device physical margin.
@@ -2304,18 +2304,18 @@ equals 1 inch). The default value is the device physical margin.
supported keywords are "all", "even", and "odd". The default value is
"all".
-<h4><a name="page-top">page-top (integer(0:MAX))</a></h4>
+<h4><a name="page-top">page-top (integer(0:MAX))</a><span class="info">Deprecated</span></h4>
<p>The page-top attribute specifies the top margin in points (72 points
equals 1 inch). The default value is the device physical margin.
-<h4><a name="prettyprint">prettyprint (boolean)</a></h4>
+<h4><a name="prettyprint">prettyprint (boolean)</a><span class="info">Deprecated</span></h4>
<p>The prettyprint attribute specifies whether text files should be printed
with a shaded header and keyword highlighting (prettyprint=true) or without
additional formatting (prettyprint=false). The default value is false.
-<h4><a name="wrap">wrap (boolean)</a></h4>
+<h4><a name="wrap">wrap (boolean)</a><span class="info">Deprecated</span></h4>
<p>The wrap attribute specifies whether long lines should be wrapped
(wrap=true) or not (wrap=false) when printing text files. The default
diff --git a/doc/help/spec-ppd.html b/doc/help/spec-ppd.html
index 21a980118..4521543bc 100644
--- a/doc/help/spec-ppd.html
+++ b/doc/help/spec-ppd.html
@@ -413,6 +413,7 @@ div.contents ul.subcontents li {
<li><a href="#cupsManualCopies">cupsManualCopies</a></li>
<li><a href="#cupsMarkerName">cupsMarkerName</a></li>
<li><a href="#cupsMarkerNotice">cupsMarkerNotice</a></li>
+ <li><a href="#cupsMaxCopies">cupsMaxCopies</a></li>
<li><a href="#cupsModelNumber">cupsModelNumber</a></li>
<li><a href="#cupsPJLCharset">cupsPJLCharset</a></li>
<li><a href="#cupsPJLDisplay">cupsPJLDisplay</a></li>
@@ -1746,6 +1747,19 @@ are approximate".</p>
*cupsMarkerNotice: "Supply levels are approximate."
</pre>
+<h3><span class='info'>CUPS 1.6</span><a name='cupsMaxCopies'>cupsMaxCopies</a></h3>
+
+<p class='summary'>*cupsMaxCopies: integer</p>
+
+<p>This integer keyword notifies the filters that the destination printer supports up to N copies in hardware. The default value is <code>9999</code>.</p>
+
+<p>Example:</p>
+
+<pre class='command'>
+<em>*% Tell the RIP filters we can do up to 99 copies</em>
+*cupsMaxCopies: 99
+</pre>
+
<h3><a name='cupsModelNumber'>cupsModelNumber</a></h3>
<p class='summary'>*cupsModelNumber: number</p>
@@ -2203,6 +2217,15 @@ the device.</p>
<h2 class='title'><a name='HISTORY'>Change History</a></h2>
+<h3>Changes in CUPS 1.6</h3>
+
+<ul>
+
+ <li>Added <a href="#cupsMaxCopies"><tt>cupsMaxCopies</tt></a> keyword.</li>
+
+</ul>
+
+
<h3>Changes in CUPS 1.5</h3>
<ul>
diff --git a/filter/ppd-compiler.header b/filter/ppd-compiler.header
index 4af7865f8..2caf3aecd 100644
--- a/filter/ppd-compiler.header
+++ b/filter/ppd-compiler.header
@@ -3,7 +3,7 @@
PPD compiler documentation for CUPS.
- Copyright 2007-2010 by Apple Inc.
+ Copyright 2007-2012 by Apple Inc.
Copyright 1997-2007 by Easy Software Products.
These coded instructions, statements, and computer programs are the
@@ -19,6 +19,12 @@
(PPD) file compiler. The PPD compiler generates PPD files from simple text files
that describe the features and capabilities of one or more printers.</P>
+<BLOCKQUOTE><B>Note:</B>
+
+<P>The PPD compiler and related tools are deprecated and will be removed in a future release of CUPS.</P>
+
+</BLOCKQUOTE>
+
<div class='summary'><table summary='General Information'>
<tbody>
<tr>
diff --git a/filter/pstops.c b/filter/pstops.c
index 16628627a..1688d9287 100644
--- a/filter/pstops.c
+++ b/filter/pstops.c
@@ -128,7 +128,7 @@ typedef struct /**** Document information ****/
*ap_page_size; /* AP_FIRSTPAGE_PageSize value */
int collate, /* Collate copies? */
emit_jcl, /* Emit JCL commands? */
- fitplot; /* Fit pages to media */
+ fit_to_page; /* Fit pages to media */
const char *input_slot, /* InputSlot value */
*manual_feed, /* ManualFeed value */
*media_color, /* MediaColor value */
@@ -978,7 +978,7 @@ copy_dsc(cups_file_t *fp, /* I - File to read from */
puts("%%Trailer");
printf("%%%%Pages: %d\n", cupsArrayCount(doc->pages));
- if (doc->number_up > 1 || doc->fitplot)
+ if (doc->number_up > 1 || doc->fit_to_page)
printf("%%%%BoundingBox: %.0f %.0f %.0f %.0f\n",
PageLeft, PageBottom, PageRight, PageTop);
else
@@ -1382,7 +1382,7 @@ copy_page(cups_file_t *fp, /* I - File to read from */
memcpy(bounding_box, doc->bounding_box,
sizeof(bounding_box));
}
- else if (doc->number_up == 1 && !doc->fitplot && Orientation)
+ else if (doc->number_up == 1 && !doc->fit_to_page && Orientation)
{
int temp_bbox[4]; /* Temporary bounding box */
@@ -1480,7 +1480,7 @@ copy_page(cups_file_t *fp, /* I - File to read from */
* %%IncludeFeature: *MainKeyword OptionKeyword
*/
- if (doc->number_up == 1 &&!doc->fitplot)
+ if (doc->number_up == 1 &&!doc->fit_to_page)
pageinfo->num_options = include_feature(ppd, line,
pageinfo->num_options,
&(pageinfo->options));
@@ -1557,14 +1557,14 @@ copy_page(cups_file_t *fp, /* I - File to read from */
{
feature = 1;
- if (doc->number_up > 1 || doc->fitplot)
+ if (doc->number_up > 1 || doc->fit_to_page)
continue;
}
else if (!strncmp(line, "%%EndFeature", 12))
{
feature = 0;
- if (doc->number_up > 1 || doc->fitplot)
+ if (doc->number_up > 1 || doc->fit_to_page)
continue;
}
else if (!strncmp(line, "%%IncludeFeature:", 17))
@@ -1580,7 +1580,7 @@ copy_page(cups_file_t *fp, /* I - File to read from */
if (line[0] != '%' && !feature)
break;
- if (!feature || (doc->number_up == 1 && !doc->fitplot))
+ if (!feature || (doc->number_up == 1 && !doc->fit_to_page))
doc_write(doc, line, linelen);
}
@@ -1803,7 +1803,7 @@ copy_setup(cups_file_t *fp, /* I - File to read from */
* %%IncludeFeature: *MainKeyword OptionKeyword
*/
- if (doc->number_up == 1 && !doc->fitplot)
+ if (doc->number_up == 1 && !doc->fit_to_page)
num_options = include_feature(ppd, line, num_options, &options);
}
else if (strncmp(line, "%%BeginSetup", 12))
@@ -1868,7 +1868,7 @@ copy_trailer(cups_file_t *fp, /* I - File to read from */
fprintf(stderr, "DEBUG: Wrote %d pages...\n", number);
printf("%%%%Pages: %d\n", number);
- if (doc->number_up > 1 || doc->fitplot)
+ if (doc->number_up > 1 || doc->fit_to_page)
printf("%%%%BoundingBox: %.0f %.0f %.0f %.0f\n",
PageLeft, PageBottom, PageRight, PageTop);
else
@@ -2330,6 +2330,7 @@ set_pstops_options(
ppd_option_t *option; /* PPD option */
ppd_choice_t *choice; /* PPD choice */
const char *content_type; /* Original content type */
+ int max_copies; /* Maximum number of copies supported */
/*
@@ -2421,7 +2422,7 @@ set_pstops_options(
doc->emit_jcl = 1;
/*
- * fitplot/fit-to-page/ipp-attribute-fidelity
+ * fit-to-page/ipp-attribute-fidelity
*
* (Only for original PostScript content)
*/
@@ -2431,16 +2432,13 @@ set_pstops_options(
if (!_cups_strcasecmp(content_type, "application/postscript"))
{
- if ((val = cupsGetOption("fitplot", num_options, options)) != NULL &&
+ if ((val = cupsGetOption("fit-to-page", num_options, options)) != NULL &&
!_cups_strcasecmp(val, "true"))
- doc->fitplot = 1;
- else if ((val = cupsGetOption("fit-to-page", num_options, options)) != NULL &&
- !_cups_strcasecmp(val, "true"))
- doc->fitplot = 1;
+ doc->fit_to_page = 1;
else if ((val = cupsGetOption("ipp-attribute-fidelity", num_options,
options)) != NULL &&
!_cups_strcasecmp(val, "true"))
- doc->fitplot = 1;
+ doc->fit_to_page = 1;
}
/*
@@ -2592,7 +2590,16 @@ set_pstops_options(
* Now figure out if we have to force collated copies, etc.
*/
- if (ppd && ppd->manual_copies && Duplex && doc->copies > 1)
+ if ((attr = ppdFindAttr(ppd, "cupsMaxCopies", NULL)) != NULL)
+ max_copies = atoi(attr->value);
+ else if (ppd && ppd->manual_copies)
+ max_copies = 1;
+ else
+ max_copies = 9999;
+
+ if (doc->copies > max_copies)
+ doc->collate = 1;
+ else if (ppd && ppd->manual_copies && Duplex && doc->copies > 1)
{
/*
* Force collated copies when printing a duplexed document to
@@ -2616,7 +2623,8 @@ set_pstops_options(
doc->slow_collate = 1;
- if ((choice = ppdFindMarkedChoice(ppd, "Collate")) != NULL &&
+ if (doc->copies <= max_copies &&
+ (choice = ppdFindMarkedChoice(ppd, "Collate")) != NULL &&
!_cups_strcasecmp(choice->choice, "True"))
{
/*
@@ -2773,7 +2781,7 @@ start_nup(pstops_doc_t *doc, /* I - Document information */
pagew = PageRight - PageLeft;
pagel = PageTop - PageBottom;
- if (doc->fitplot)
+ if (doc->fit_to_page)
{
bboxx = bounding_box[0];
bboxy = bounding_box[1];
@@ -2820,18 +2828,18 @@ start_nup(pstops_doc_t *doc, /* I - Document information */
doc_printf(doc, "%.1f 0.0 translate -1 1 scale\n", PageWidth);
/*
- * Offset and scale as necessary for fitplot/fit-to-page/number-up...
+ * Offset and scale as necessary for fit_to_page/fit-to-page/number-up...
*/
if (Duplex && doc->number_up > 1 && ((number / doc->number_up) & 1))
doc_printf(doc, "%.1f %.1f translate\n", PageWidth - PageRight, PageBottom);
- else if (doc->number_up > 1 || doc->fitplot)
+ else if (doc->number_up > 1 || doc->fit_to_page)
doc_printf(doc, "%.1f %.1f translate\n", PageLeft, PageBottom);
switch (doc->number_up)
{
default :
- if (doc->fitplot)
+ if (doc->fit_to_page)
{
w = pagew;
l = w * bboxl / bboxw;
@@ -3157,7 +3165,7 @@ start_nup(pstops_doc_t *doc, /* I - Document information */
doc_puts(doc, "grestore\n");
}
- if (doc->fitplot)
+ if (doc->fit_to_page)
{
/*
* Offset the page by its bounding box...
@@ -3167,7 +3175,7 @@ start_nup(pstops_doc_t *doc, /* I - Document information */
-bounding_box[1]);
}
- if (doc->fitplot || doc->number_up > 1)
+ if (doc->fit_to_page || doc->number_up > 1)
{
/*
* Clip the page to the page's bounding box...
diff --git a/filter/spec-ppd.shtml b/filter/spec-ppd.shtml
index 670e89913..6daa361fe 100644
--- a/filter/spec-ppd.shtml
+++ b/filter/spec-ppd.shtml
@@ -1307,6 +1307,19 @@ are approximate".</p>
*cupsMarkerNotice: "Supply levels are approximate."
</pre>
+<h3><span class='info'>CUPS 1.6</span><a name='cupsMaxCopies'>cupsMaxCopies</a></h3>
+
+<p class='summary'>*cupsMaxCopies: integer</p>
+
+<p>This integer keyword notifies the filters that the destination printer supports up to N copies in hardware. The default value is <code>9999</code>.</p>
+
+<p>Example:</p>
+
+<pre class='command'>
+<em>*% Tell the RIP filters we can do up to 99 copies</em>
+*cupsMaxCopies: 99
+</pre>
+
<h3><a name='cupsModelNumber'>cupsModelNumber</a></h3>
<p class='summary'>*cupsModelNumber: number</p>
@@ -1764,6 +1777,15 @@ the device.</p>
<h2 class='title'><a name='HISTORY'>Change History</a></h2>
+<h3>Changes in CUPS 1.6</h3>
+
+<ul>
+
+ <li>Added <a href="#cupsMaxCopies"><tt>cupsMaxCopies</tt></a> keyword.</li>
+
+</ul>
+
+
<h3>Changes in CUPS 1.5</h3>
<ul>
diff --git a/man/client.conf.man.in b/man/client.conf.man.in
index ca659ff54..e7df54e2a 100644
--- a/man/client.conf.man.in
+++ b/man/client.conf.man.in
@@ -3,7 +3,7 @@
.\"
.\" client.conf man page for CUPS.
.\"
-.\" Copyright 2007-2011 by Apple Inc.
+.\" Copyright 2007-2012 by Apple Inc.
.\" Copyright 2006 by Easy Software Products.
.\"
.\" These coded instructions, statements, and computer programs are the
@@ -12,7 +12,7 @@
.\" which should have been included with this file. If this file is
.\" file is missing or damaged, see the license at "http://www.cups.org/".
.\"
-.TH client.conf 5 "CUPS" "2 September 2011" "Apple Inc."
+.TH client.conf 5 "CUPS" "15 February 2012" "Apple Inc."
.SH NAME
client.conf \- client configuration file for cups
.SH DESCRIPTION
@@ -46,10 +46,14 @@ ServerName /domain/socket
.br
Specifies the address and optionally the port to use when connecting to the
server. \fBNote: Not supported on Mac OS X 10.7 or later.\fR
+.TP 5
+User name
+.br
+Specifies the default user name to use for requests.
.SH SEE ALSO
http://localhost:631/help
.SH COPYRIGHT
-Copyright 2007-2011 by Apple Inc.
+Copyright 2007-2012 by Apple Inc.
.\"
.\" End of "$Id: client.conf.man.in 6649 2007-07-11 21:46:42Z mike $".
.\"
diff --git a/man/cupsd.conf.man.in b/man/cupsd.conf.man.in
index d1d27cca4..b5d790f8b 100644
--- a/man/cupsd.conf.man.in
+++ b/man/cupsd.conf.man.in
@@ -12,7 +12,7 @@
.\" which should have been included with this file. If this file is
.\" file is missing or damaged, see the license at "http://www.cups.org/".
.\"
-.TH cupsd.conf 5 "CUPS" "6 January 2012" "Apple Inc."
+.TH cupsd.conf 5 "CUPS" "15 February 2012" "Apple Inc."
.SH NAME
cupsd.conf \- server configuration file for cups
.SH DESCRIPTION
@@ -386,6 +386,11 @@ MaxCopies number
.br
Specifies the maximum number of copies that a user can print of each job.
.TP 5
+MaxHoldTime seconds
+.br
+Specifies the maximum time a job may remain in the "indefinite" hold state
+before it is canceled. Set to 0 to disable cancellation of held jobs.
+.TP 5
MaxJobs number
.br
Specifies the maximum number of simultaneous jobs to support.
@@ -634,7 +639,7 @@ Specifies whether the web interface is enabled.
.br
http://localhost:631/help
.SH COPYRIGHT
-Copyright 2007-2011 by Apple Inc.
+Copyright 2007-2012 by Apple Inc.
.\"
.\" End of "$Id: cupsd.conf.man.in 7935 2008-09-11 01:54:11Z mike $".
.\"
diff --git a/man/ppdc.man b/man/ppdc.man
index bfed12f1f..8f30bfb56 100644
--- a/man/ppdc.man
+++ b/man/ppdc.man
@@ -3,7 +3,7 @@
.\"
.\" ppdc man page for CUPS.
.\"
-.\" Copyright 2007-2011 by Apple Inc.
+.\" Copyright 2007-2012 by Apple Inc.
.\" Copyright 1997-2007 by Easy Software Products.
.\"
.\" These coded instructions, statements, and computer programs are the
@@ -12,7 +12,7 @@
.\" which should have been included with this file. If this file is
.\" file is missing or damaged, see the license at "http://www.cups.org/".
.\"
-.TH ppdc 1 "CUPS" "10 October 2008" "Apple Inc."
+.TH ppdc 1 "CUPS" "15 February 2012" "Apple Inc."
.SH NAME
ppdc \- cups ppd compiler
.SH SYNOPSIS
@@ -31,7 +31,8 @@ ppdc \- cups ppd compiler
.I source-file
.SH DESCRIPTION
\fIppdc\fR compiles PPDC source files into one or more PPD
-files.
+files. \fBThis program is deprecated and will be removed in a future release of
+CUPS.\fR
.PP
The \fI-D\fR option sets the named variable for use in the
source file. It is equivalent to using the #define directive
@@ -74,7 +75,7 @@ ppdhtml(1), ppdi(1), ppdmerge(1), ppdpo(1), ppdcfile(5)
.br
http://localhost:631/help
.SH COPYRIGHT
-Copyright 2007-2011 by Apple Inc.
+Copyright 2007-2012 by Apple Inc.
.\"
.\" End of "$Id: ppdc.man 7600 2008-05-20 21:06:23Z mike $".
.\"
diff --git a/scheduler/Makefile b/scheduler/Makefile
index e92e6048f..72c7f6488 100644
--- a/scheduler/Makefile
+++ b/scheduler/Makefile
@@ -17,6 +17,7 @@ include ../Makedefs
CUPSDOBJS = \
auth.o \
+ avahi.o \
banners.o \
cert.o \
classes.o \
@@ -39,7 +40,8 @@ CUPSDOBJS = \
server.o \
statbuf.o \
subscriptions.o \
- sysman.o
+ sysman.o \
+ timeout.o
LIBOBJS = \
filter.o \
mime.o \
diff --git a/scheduler/auth.c b/scheduler/auth.c
index 044a3c3c6..732fc324e 100644
--- a/scheduler/auth.c
+++ b/scheduler/auth.c
@@ -3,7 +3,7 @@
*
* Authorization routines for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* This file contains Kerberos support code, copyright 2006 by
@@ -130,8 +130,8 @@ static void to64(char *s, unsigned long v, int n);
#if HAVE_LIBPAM
typedef struct cupsd_authdata_s /**** Authentication data ****/
{
- char username[33], /* Username string */
- password[33]; /* Password string */
+ char username[HTTP_MAX_VALUE], /* Username string */
+ password[HTTP_MAX_VALUE]; /* Password string */
} cupsd_authdata_t;
#endif /* HAVE_LIBPAM */
@@ -322,8 +322,10 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */
int type; /* Authentication type */
const char *authorization; /* Pointer into Authorization string */
char *ptr, /* Pointer into string */
- username[256], /* Username string */
- password[33]; /* Password string */
+ username[HTTP_MAX_VALUE],
+ /* Username string */
+ password[HTTP_MAX_VALUE];
+ /* Password string */
cupsd_cert_t *localuser; /* Certificate username */
char nonce[HTTP_MAX_VALUE], /* Nonce value from client */
md5[33], /* MD5 password */
diff --git a/scheduler/avahi.c b/scheduler/avahi.c
new file mode 100644
index 000000000..5761317bf
--- /dev/null
+++ b/scheduler/avahi.c
@@ -0,0 +1,441 @@
+/*
+ * "$Id$"
+ *
+ * Avahi poll implementation for the CUPS scheduler.
+ *
+ * Copyright (C) 2010, 2011 Red Hat, Inc.
+ * Authors:
+ * Tim Waugh <twaugh@redhat.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Contents:
+ *
+ * watch_read_cb - Read callback for file descriptor
+ * watch_write_cb - Write callback for file descriptor
+ * watched_fd_add_select() - Call cupsdAddSelect() as needed
+ * watch_new() - Create a new file descriptor watch
+ * watch_free() - Free a file descriptor watch
+ * watch_update() - Update watched events for a file descriptor
+ * watch_get_events() - Get events that happened for a file descriptor
+ * timeout_cb() - Run a timed Avahi callback
+ * timeout_new() - Set a wakeup time
+ * timeout_update() - Update the expiration time for a timeout
+ * timeout_free() - Free a timeout
+ * compare_watched_fds() - Compare watched file descriptors for array sorting
+ * avahi_cups_poll_new() - Create a new Avahi main loop object for CUPS
+ * avahi_cups_poll_free() - Free an Avahi main loop object for CUPS
+ * avahi_cups_poll_get() - Get the abstract poll API structure
+ */
+
+#include <config.h>
+
+#ifdef HAVE_AVAHI /* Applies to entire file... */
+
+/*
+ * Include necessary headers...
+ */
+
+#include "cupsd.h"
+
+#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
+# include <malloc.h>
+#endif /* HAVE_MALLOC_H && HAVE_MALLINFO */
+
+#ifdef HAVE_AVAHI
+# include <avahi-common/timeval.h>
+#endif /* HAVE_AVAHI */
+
+
+typedef struct
+{
+ AvahiCupsPoll *cups_poll;
+
+ int fd;
+ AvahiWatchEvent occurred;
+ cups_array_t *watches;
+} cupsd_watched_fd_t;
+
+struct AvahiWatch
+{
+ cupsd_watched_fd_t *watched_fd;
+
+ AvahiWatchEvent events;
+ AvahiWatchCallback callback;
+ void *userdata;
+};
+
+struct AvahiTimeout
+{
+ AvahiCupsPoll *cups_poll;
+ AvahiTimeoutCallback callback;
+ void *userdata;
+ cupsd_timeout_t *cupsd_timeout;
+};
+
+/*
+ * Local functions...
+ */
+
+static AvahiWatch * watch_new(const AvahiPoll *api,
+ int fd,
+ AvahiWatchEvent events,
+ AvahiWatchCallback callback,
+ void *userdata);
+static void watch_free(AvahiWatch *watch);
+static void watch_update(AvahiWatch *watch,
+ AvahiWatchEvent events);
+static AvahiWatchEvent watch_get_events(AvahiWatch *watch);
+
+
+/*
+ * 'watch_read_cb' - Read callback for file descriptor
+ */
+
+static void
+watch_read_cb (void *userdata)
+{
+ AvahiWatch *watch;
+ cupsd_watched_fd_t *watched_fd = userdata;
+ watched_fd->occurred |= AVAHI_WATCH_IN;
+ for (watch = (AvahiWatch *)cupsArrayFirst(watched_fd->watches);
+ watch;
+ watch = (AvahiWatch *)cupsArrayNext(watched_fd->watches))
+ {
+ if (watch->events & watched_fd->occurred)
+ {
+ (watch->callback) (watch, watched_fd->fd,
+ AVAHI_WATCH_IN, watch->userdata);
+ watched_fd->occurred &= ~AVAHI_WATCH_IN;
+ break;
+ }
+ }
+}
+
+
+/*
+ * 'watch_write_cb' - Write callback for file descriptor
+ */
+
+static void
+watch_write_cb (void *userdata)
+{
+ AvahiWatch *watch;
+ cupsd_watched_fd_t *watched_fd = userdata;
+ watched_fd->occurred |= AVAHI_WATCH_OUT;
+ for (watch = (AvahiWatch *)cupsArrayFirst(watched_fd->watches);
+ watch;
+ watch = (AvahiWatch *)cupsArrayNext(watched_fd->watches))
+ {
+ if (watch->events & watched_fd->occurred)
+ {
+ (watch->callback) (watch, watched_fd->fd,
+ AVAHI_WATCH_OUT, watch->userdata);
+ watched_fd->occurred &= ~AVAHI_WATCH_OUT;
+ break;
+ }
+ }
+}
+
+
+/*
+ * 'watched_fd_add_select' - Call cupsdAddSelect() as needed
+ */
+
+static int /* O - Watches? */
+watched_fd_add_select (cupsd_watched_fd_t *watched_fd)
+{
+ AvahiWatch *watch;
+ cupsd_selfunc_t read_cb = NULL, write_cb = NULL;
+ int any_watches = 0;
+
+ for (watch = (AvahiWatch *)cupsArrayFirst(watched_fd->watches);
+ watch;
+ watch = (AvahiWatch *)cupsArrayNext(watched_fd->watches))
+ {
+ any_watches = 1;
+ if (watch->events & (AVAHI_WATCH_IN |
+ AVAHI_WATCH_ERR |
+ AVAHI_WATCH_HUP))
+ {
+ read_cb = (cupsd_selfunc_t)watch_read_cb;
+ if (write_cb != NULL)
+ break;
+ }
+
+ if (watch->events & AVAHI_WATCH_OUT)
+ {
+ write_cb = (cupsd_selfunc_t)watch_write_cb;
+ if (read_cb != NULL)
+ break;
+ }
+ }
+
+ if (read_cb || write_cb)
+ cupsdAddSelect (watched_fd->fd, read_cb, write_cb, watched_fd);
+ else
+ cupsdRemoveSelect (watched_fd->fd);
+
+ return (any_watches);
+}
+
+/*
+ * 'watch_new' - Create a new file descriptor watch
+ */
+
+static AvahiWatch *
+watch_new (const AvahiPoll *api,
+ int fd,
+ AvahiWatchEvent events,
+ AvahiWatchCallback callback,
+ void *userdata)
+{
+ cupsd_watched_fd_t key, *watched_fd;
+ AvahiCupsPoll *cups_poll = api->userdata;
+ AvahiWatch *watch = malloc(sizeof(AvahiWatch));
+ if (watch == NULL)
+ return (NULL);
+
+ watch->events = events;
+ watch->callback = callback;
+ watch->userdata = userdata;
+
+ key.fd = fd;
+ watched_fd = cupsArrayFind (cups_poll->watched_fds, &key);
+ if (watched_fd == NULL)
+ {
+ watched_fd = malloc(sizeof(cupsd_watched_fd_t));
+ if (watched_fd == NULL)
+ {
+ free (watch);
+ return (NULL);
+ }
+
+ watched_fd->fd = fd;
+ watched_fd->occurred = 0;
+ watched_fd->cups_poll = cups_poll;
+ watched_fd->watches = cupsArrayNew (NULL, NULL);
+ cupsArrayAdd (cups_poll->watched_fds, watched_fd);
+ }
+
+ watch->watched_fd = watched_fd;
+ cupsArrayAdd(watched_fd->watches, watch);
+ watched_fd_add_select (watched_fd);
+ return (watch);
+}
+
+
+/*
+ * 'watch_free' - Free a file descriptor watch
+ */
+
+static void
+watch_free (AvahiWatch *watch)
+{
+ cupsd_watched_fd_t *watched_fd = watch->watched_fd;
+ AvahiCupsPoll *cups_poll = watched_fd->cups_poll;
+
+ cupsArrayRemove (watched_fd->watches, watch);
+ free (watch);
+
+ if (!watched_fd_add_select (watched_fd))
+ {
+ /* No more watches */
+ cupsArrayRemove (cups_poll->watched_fds, watched_fd);
+ free (watched_fd);
+ }
+}
+
+
+/*
+ * 'watch_update' - Update watched events for a file descriptor
+ */
+
+static void
+watch_update (AvahiWatch *watch,
+ AvahiWatchEvent events)
+{
+ watch->events = events;
+ watched_fd_add_select (watch->watched_fd);
+}
+
+
+/*
+ * 'watch_get_events' - Get events that happened for a file descriptor
+ */
+
+static AvahiWatchEvent
+watch_get_events (AvahiWatch *watch)
+{
+ return (watch->watched_fd->occurred);
+}
+
+
+/*
+ * 'timeout_cb()' - Run a timed Avahi callback
+ */
+
+static void
+timeout_cb (cupsd_timeout_t *cupsd_timeout, void *userdata)
+{
+ AvahiTimeout *timeout = userdata;
+ (timeout->callback) (timeout, timeout->userdata);
+}
+
+
+/*
+ * 'timeout_new' - Set a wakeup time
+ */
+
+static AvahiTimeout *
+timeout_new (const AvahiPoll *api,
+ const struct timeval *tv,
+ AvahiTimeoutCallback callback,
+ void *userdata)
+{
+ AvahiTimeout *timeout;
+ AvahiCupsPoll *cups_poll = api->userdata;
+
+ timeout = malloc(sizeof(AvahiTimeout));
+ if (timeout == NULL)
+ return (NULL);
+
+ timeout->cups_poll = cups_poll;
+ timeout->callback = callback;
+ timeout->userdata = userdata;
+ timeout->cupsd_timeout = cupsdAddTimeout (tv,
+ (cupsd_timeoutfunc_t)timeout_cb,
+ timeout);
+ cupsArrayAdd (cups_poll->timeouts, timeout);
+ return (timeout);
+}
+
+
+/*
+ * 'timeout_update' - Update the expiration time for a timeout
+ */
+
+static void
+timeout_update (AvahiTimeout *timeout,
+ const struct timeval *tv)
+{
+ cupsdUpdateTimeout (timeout->cupsd_timeout, tv);
+}
+
+
+/*
+ * ' timeout_free' - Free a timeout
+ */
+
+static void
+timeout_free (AvahiTimeout *timeout)
+{
+ cupsArrayRemove (timeout->cups_poll->timeouts, timeout);
+ cupsdRemoveTimeout (timeout->cupsd_timeout);
+ free (timeout);
+}
+
+
+/*
+ * 'compare_watched_fds' - Compare watched file descriptors for array sorting
+ */
+static int
+compare_watched_fds(cupsd_watched_fd_t *p0,
+ cupsd_watched_fd_t *p1)
+{
+ /*
+ * Compare by fd (no two elements have the same fd)
+ */
+
+ if (p0->fd == p1->fd)
+ return 0;
+
+ return (p0->fd < p1->fd ? -1 : 1);
+}
+
+
+/*
+ * 'avahi_cups_poll_new' - Create a new Avahi main loop object for CUPS
+ */
+
+AvahiCupsPoll *
+avahi_cups_poll_new (void)
+{
+ AvahiCupsPoll *cups_poll = malloc(sizeof(AvahiCupsPoll));
+ if (cups_poll == NULL)
+ return (NULL);
+
+ cups_poll->watched_fds = cupsArrayNew ((cups_array_func_t)compare_watched_fds,
+ NULL);
+ cups_poll->timeouts = cupsArrayNew (NULL, NULL);
+
+ cups_poll->api.userdata = cups_poll;
+ cups_poll->api.watch_new = watch_new;
+ cups_poll->api.watch_free = watch_free;
+ cups_poll->api.watch_update = watch_update;
+ cups_poll->api.watch_get_events = watch_get_events;
+
+ cups_poll->api.timeout_new = timeout_new;
+ cups_poll->api.timeout_update = timeout_update;
+ cups_poll->api.timeout_free = timeout_free;
+
+ return (cups_poll);
+}
+
+
+/*
+ * 'avahi_cups_poll_free' - Free an Avahi main loop object for CUPS
+ */
+void
+avahi_cups_poll_free (AvahiCupsPoll *cups_poll)
+{
+ cupsd_watched_fd_t *watched_fd;
+
+ for (watched_fd = (cupsd_watched_fd_t*)cupsArrayFirst(cups_poll->watched_fds);
+ watched_fd;
+ watched_fd = (cupsd_watched_fd_t*)cupsArrayNext(cups_poll->watched_fds))
+ cupsArrayClear (watched_fd->watches);
+
+ cupsArrayClear (cups_poll->watched_fds);
+ cupsArrayClear (cups_poll->timeouts);
+}
+
+
+/*
+ * 'avahi_cups_poll_get' - Get the abstract poll API structure
+ */
+
+const AvahiPoll *
+avahi_cups_poll_get (AvahiCupsPoll *cups_poll)
+{
+ return (&cups_poll->api);
+}
+
+
+#endif /* HAVE_AVAHI ... from top of file */
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/avahi.h b/scheduler/avahi.h
new file mode 100644
index 000000000..d92049dc2
--- /dev/null
+++ b/scheduler/avahi.h
@@ -0,0 +1,69 @@
+/*
+ * "$Id$"
+ *
+ * Avahi poll implementation for the CUPS scheduler.
+ *
+ * Copyright (C) 2010, 2011 Red Hat, Inc.
+ * Authors:
+ * Tim Waugh <twaugh@redhat.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#ifdef HAVE_AVAHI
+# include <avahi-client/client.h>
+# include <avahi-client/publish.h>
+#endif /* HAVE_AVAHI */
+
+#ifdef HAVE_AUTHORIZATION_H
+# include <Security/Authorization.h>
+#endif /* HAVE_AUTHORIZATION_H */
+
+
+#ifdef HAVE_AVAHI
+typedef struct
+{
+ AvahiPoll api;
+ cups_array_t *watched_fds;
+ cups_array_t *timeouts;
+} AvahiCupsPoll;
+#endif /* HAVE_AVAHI */
+
+/*
+ * Prototypes...
+ */
+
+#ifdef HAVE_AVAHI
+extern AvahiCupsPoll * avahi_cups_poll_new(void);
+extern void avahi_cups_poll_free(AvahiCupsPoll *cups_poll);
+extern const AvahiPoll *avahi_cups_poll_get(AvahiCupsPoll *cups_poll);
+#endif /* HAVE_AVAHI */
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/scheduler/client.h b/scheduler/client.h
index ded57bd75..ff1bfc0c9 100644
--- a/scheduler/client.h
+++ b/scheduler/client.h
@@ -32,8 +32,10 @@ struct cupsd_client_s
http_state_t operation; /* Request operation */
off_t bytes; /* Bytes transferred for this request */
int type; /* AuthType for username */
- char username[256], /* Username from Authorization: line */
- password[33], /* Password from Authorization: line */
+ char username[HTTP_MAX_VALUE],
+ /* Username from Authorization: line */
+ password[HTTP_MAX_VALUE],
+ /* Password from Authorization: line */
uri[HTTP_MAX_URI],
/* Localized URL/URI for GET/PUT */
*filename, /* Filename of output file */
diff --git a/scheduler/conf.c b/scheduler/conf.c
index 7279f4ff5..de9d80c0e 100644
--- a/scheduler/conf.c
+++ b/scheduler/conf.c
@@ -3,7 +3,7 @@
*
* Configuration routines for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -132,6 +132,7 @@ static const cupsd_var_t variables[] =
{ "MaxClientsPerHost", &MaxClientsPerHost, CUPSD_VARTYPE_INTEGER },
{ "MaxCopies", &MaxCopies, CUPSD_VARTYPE_INTEGER },
{ "MaxEvents", &MaxEvents, CUPSD_VARTYPE_INTEGER },
+ { "MaxHoldTime", &MaxHoldTime, CUPSD_VARTYPE_INTEGER },
{ "MaxJobs", &MaxJobs, CUPSD_VARTYPE_INTEGER },
{ "MaxJobsPerPrinter", &MaxJobsPerPrinter, CUPSD_VARTYPE_INTEGER },
{ "MaxJobsPerUser", &MaxJobsPerUser, CUPSD_VARTYPE_INTEGER },
@@ -743,6 +744,7 @@ cupsdReadConfiguration(void)
JobHistory = DEFAULT_HISTORY;
JobFiles = DEFAULT_FILES;
JobAutoPurge = 0;
+ MaxHoldTime = 0;
MaxJobs = 500;
MaxActiveJobs = 0;
MaxJobsPerUser = 0;
diff --git a/scheduler/cups-driverd.cxx b/scheduler/cups-driverd.cxx
index dd44af3c6..95f6b3a31 100644
--- a/scheduler/cups-driverd.cxx
+++ b/scheduler/cups-driverd.cxx
@@ -7,7 +7,7 @@
* created from driver information files, and dynamically generated PPD files
* using driver helper programs.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -2299,17 +2299,19 @@ load_ppds(const char *d, /* I - Actual directory */
ppd->record.model_number = model_number;
ppd->record.type = type;
+ strlcpy(ppd->record.filename, name, sizeof(ppd->record.filename));
strlcpy(ppd->record.name, name, sizeof(ppd->record.name));
- strlcpy(ppd->record.make, manufacturer, sizeof(ppd->record.make));
- strlcpy(ppd->record.make_and_model, make_model,
- sizeof(ppd->record.make_and_model));
strlcpy(ppd->record.languages[0], lang_version,
sizeof(ppd->record.languages[0]));
strlcpy(ppd->record.products[0], (char *)cupsArrayFirst(products),
sizeof(ppd->record.products[0]));
strlcpy(ppd->record.psversions[0], (char *)cupsArrayFirst(psversions),
sizeof(ppd->record.psversions[0]));
+ strlcpy(ppd->record.make, manufacturer, sizeof(ppd->record.make));
+ strlcpy(ppd->record.make_and_model, make_model,
+ sizeof(ppd->record.make_and_model));
strlcpy(ppd->record.device_id, device_id, sizeof(ppd->record.device_id));
+ strlcpy(ppd->record.scheme, "file", sizeof(ppd->record.scheme));
}
/*
diff --git a/scheduler/cupsd.h b/scheduler/cupsd.h
index 630285f3e..8d7117bb2 100644
--- a/scheduler/cupsd.h
+++ b/scheduler/cupsd.h
@@ -140,6 +140,15 @@ extern const char *cups_hstrerror(int);
typedef void (*cupsd_selfunc_t)(void *data);
+#ifdef HAVE_AVAHI
+/*
+ * Timeout callback function type...
+ */
+
+typedef struct _cupsd_timeout_s cupsd_timeout_t;
+typedef void (*cupsd_timeoutfunc_t)(cupsd_timeout_t *timeout, void *data);
+#endif /* HAVE_AVAHI */
+
/*
* Globals...
@@ -173,6 +182,12 @@ VAR int Launchd VALUE(0);
/* Running from launchd */
#endif /* HAVE_LAUNCH_H */
+#ifdef HAVE_AVAHI
+VAR cups_array_t *Timeouts VALUE(NULL);
+ /* Timed callbacks for main loop */
+#endif /* HAVE_AVAHI */
+
+
/*
* Prototypes...
@@ -236,6 +251,19 @@ extern void cupsdStopSelect(void);
extern void cupsdStartServer(void);
extern void cupsdStopServer(void);
+#ifdef HAVE_AVAHI
+extern cupsd_timeout_t *cupsdAddTimeout(const struct timeval *tv,
+ cupsd_timeoutfunc_t cb,
+ void *data);
+extern cupsd_timeout_t *cupsdNextTimeout(long *delay);
+extern void cupsdRemoveTimeout(cupsd_timeout_t *timeout);
+extern void cupsdRunTimeout(cupsd_timeout_t *timeout);
+extern void cupsdUpdateTimeout(cupsd_timeout_t *timeout,
+ const struct timeval *tv);
+#endif /* HAVE_AVAHI */
+
+extern int cupsdRemoveFile(const char *filename);
+
/*
* End of "$Id: cupsd.h 7928 2008-09-10 22:14:22Z mike $".
diff --git a/scheduler/ipp.c b/scheduler/ipp.c
index e5a464737..ce0ccc9f0 100644
--- a/scheduler/ipp.c
+++ b/scheduler/ipp.c
@@ -112,9 +112,7 @@
#ifdef __APPLE__
# include <ApplicationServices/ApplicationServices.h>
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
extern CFUUIDRef ColorSyncCreateUUIDFromUInt32(unsigned id);
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
# include <CoreFoundation/CoreFoundation.h>
# ifdef HAVE_MEMBERSHIP_H
# include <membership.h>
@@ -147,11 +145,7 @@ static void add_printer_state_reasons(cupsd_client_t *con,
static void add_queued_job_count(cupsd_client_t *con, cupsd_printer_t *p);
#ifdef __APPLE__
static void apple_init_profile(ppd_file_t *ppd, cups_array_t *languages,
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
CFMutableDictionaryRef profile,
-# else
- CMDeviceProfileInfo *profile,
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
unsigned id, const char *name,
const char *text, const char *iccfile);
static void apple_register_profiles(cupsd_printer_t *p);
@@ -2897,19 +2891,13 @@ static void
apple_init_profile(
ppd_file_t *ppd, /* I - PPD file */
cups_array_t *languages, /* I - Languages in the PPD file */
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
CFMutableDictionaryRef profile, /* I - Profile dictionary */
-# else
- CMDeviceProfileInfo *profile, /* I - Profile record */
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
unsigned id, /* I - Profile ID */
const char *name, /* I - Profile name */
const char *text, /* I - Profile UI text */
const char *iccfile) /* I - ICC filename */
{
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
CFURLRef url; /* URL for profile filename */
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
CFMutableDictionaryRef dict; /* Dictionary for name */
char *language; /* Current language */
ppd_attr_t *attr; /* Profile attribute */
@@ -2988,7 +2976,6 @@ apple_init_profile(
* Fill in the profile data...
*/
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
if (iccfile)
{
url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
@@ -3004,17 +2991,6 @@ apple_init_profile(
CFDictionarySetValue(profile, kColorSyncDeviceModeDescriptions, dict);
CFRelease(dict);
-
-# else
- profile->dataVersion = cmDeviceProfileInfoVersion1;
- profile->profileID = id;
- profile->profileLoc.locType = iccfile ? cmPathBasedProfile : cmNoProfileBase;
- profile->profileName = dict;
-
- if (iccfile)
- strlcpy(profile->profileLoc.u.pathLoc.path, iccfile,
- sizeof(profile->profileLoc.u.pathLoc.path));
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
}
@@ -3054,34 +3030,18 @@ apple_register_profiles(
CFMutableDictionaryRef device_name; /* Printer device name dictionary */
CFStringRef printer_name; /* Printer name string */
cups_array_t *languages; /* Languages array */
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
CFMutableDictionaryRef profiles, /* Dictionary of profiles */
profile; /* Current profile info dictionary */
CFStringRef dict_key; /* Key in factory profile dictionary */
-# else
- CMDeviceScope scope = /* Scope of the registration */
- {
- kCFPreferencesAnyUser,
- kCFPreferencesCurrentHost
- };
- CMDeviceProfileArrayPtr profiles; /* Profiles */
- CMDeviceProfileInfo *profile; /* Current profile */
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
/*
* Make sure ColorSync is available...
*/
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
if (ColorSyncRegisterDevice == NULL)
return;
-# else
- if (CMRegisterColorDevice == NULL)
- return;
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
-
/*
* Try opening the PPD file for this printer...
*/
@@ -3116,13 +3076,13 @@ apple_register_profiles(
cupsdLogMessage(CUPSD_LOG_ERROR,
"%s: ICC Profile \"%s\" does not exist.", p->name,
iccfile);
+ cupsdSetPrinterReasons(p, "+cups-missing-filter-warning");
continue;
}
num_profiles ++;
}
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
/*
* Create a dictionary for the factory profiles...
*/
@@ -3137,7 +3097,6 @@ apple_register_profiles(
ppdClose(ppd);
return;
}
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
/*
* If we have profiles, add them...
@@ -3207,25 +3166,6 @@ apple_register_profiles(
q3_choice = NULL;
}
-# ifndef HAVE_COLORSYNCREGISTERDEVICE
- /*
- * Build the array of profiles...
- *
- * Note: This calloc actually requests slightly more memory than needed.
- */
-
- if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to allocate memory for factory profiles.");
- ppdClose(ppd);
- return;
- }
-
- profiles->profileCount = num_profiles;
- profile = profiles->profiles;
-# endif /* !HAVE_COLORSYNCREGISTERDEVICE */
-
/*
* Loop through the profiles listed in the PPD...
*/
@@ -3267,7 +3207,6 @@ apple_register_profiles(
else
profile_id = atoi(attr->spec);
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
@@ -3293,13 +3232,6 @@ apple_register_profiles(
CFRelease(profile);
-# else
- apple_init_profile(ppd, languages, profile, profile_id, attr->spec,
- attr->text[0] ? attr->text : attr->spec, iccfile);
-
- profile ++;
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
-
/*
* See if this is the default profile...
*/
@@ -3368,23 +3300,6 @@ apple_register_profiles(
num_profiles = cm_option->num_choices;
-# ifndef HAVE_COLORSYNCREGISTERDEVICE
- /*
- * Create an array for the factory profiles...
- */
-
- if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to allocate memory for factory profiles.");
- ppdClose(ppd);
- return;
- }
-
- profiles->profileCount = num_profiles;
- profile = profiles->profiles;
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
-
for (i = cm_option->num_choices, cm_choice = cm_option->choices;
i > 0;
i --, cm_choice ++)
@@ -3404,7 +3319,6 @@ apple_register_profiles(
snprintf(selector, sizeof(selector), "%s..", profile_name);
profile_id = _ppdHashName(selector);
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
@@ -3430,12 +3344,6 @@ apple_register_profiles(
CFRelease(profile);
-# else
- apple_init_profile(ppd, NULL, profile, profile_id, cm_choice->choice,
- cm_choice->text, NULL);
- profile ++;
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
-
if (cm_choice->marked)
default_profile_id = profile_id;
}
@@ -3450,7 +3358,6 @@ apple_register_profiles(
num_profiles = (attr && ppd->colorspace == PPD_CS_GRAY) ? 1 : 2;
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
/*
* Add the grayscale profile first. We always have a grayscale profile.
*/
@@ -3538,61 +3445,6 @@ apple_register_profiles(
}
CFRelease(profile);
-
-# else
- /*
- * Create an array for the factory profiles...
- */
-
- if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL)
- {
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Unable to allocate memory for factory profiles.");
- ppdClose(ppd);
- return;
- }
-
- profiles->profileCount = num_profiles;
-
- /*
- * Add the grayscale profile first. We always have a grayscale profile.
- */
-
- profile_id = _ppdHashName("Gray..");
- apple_init_profile(ppd, NULL, profiles->profiles, profile_id, "Gray",
- "Gray", NULL);
-
- /*
- * Then add the RGB/CMYK/DeviceN color profile...
- */
-
- switch (ppd->colorspace)
- {
- default :
- case PPD_CS_RGB :
- case PPD_CS_CMY :
- profile_id = _ppdHashName("RGB..");
- apple_init_profile(ppd, NULL, profiles->profiles + 1, profile_id,
- "RGB", "RGB", NULL);
- break;
- case PPD_CS_RGBK :
- case PPD_CS_CMYK :
- profile_id = _ppdHashName("CMYK..");
- apple_init_profile(ppd, NULL, profiles->profiles + 1, profile_id,
- "CMYK", "CMYK", NULL);
- break;
-
- case PPD_CS_GRAY :
- if (attr)
- break;
-
- case PPD_CS_N :
- profile_id = _ppdHashName("DeviceN..");
- apple_init_profile(ppd, NULL, profiles->profiles + 1, profile_id,
- "DeviceN", "DeviceN", NULL);
- break;
- }
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
}
if (num_profiles > 0)
@@ -3604,7 +3456,6 @@ apple_register_profiles(
if (!default_profile_id)
default_profile_id = profile_id; /* Last profile */
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%u"),
default_profile_id);
if (dict_key)
@@ -3613,7 +3464,6 @@ apple_register_profiles(
dict_key);
CFRelease(dict_key);
}
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
/*
* Get the device ID hash and pathelogical name dictionary.
@@ -3631,13 +3481,10 @@ apple_register_profiles(
if (device_name && printer_name)
{
- CFDictionarySetValue(device_name, CFSTR("en_US"), printer_name);
-
/*
* Register the device with ColorSync...
*/
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
CFTypeRef deviceDictKeys[] =
{ /* Device keys */
kColorSyncDeviceDescriptions,
@@ -3655,6 +3502,8 @@ apple_register_profiles(
CFDictionaryRef deviceDict; /* Device dictionary */
CFUUIDRef deviceUUID; /* Device UUID */
+ CFDictionarySetValue(device_name, CFSTR("en_US"), printer_name);
+
deviceDict = CFDictionaryCreate(kCFAllocatorDefault,
(const void **)deviceDictKeys,
(const void **)deviceDictVals,
@@ -3674,19 +3523,6 @@ apple_register_profiles(
if (deviceDict)
CFRelease(deviceDict);
-
-# else
- error = CMRegisterColorDevice(cmPrinterDeviceClass, device_id,
- device_name, &scope);
-
- /*
- * Register the profiles...
- */
-
- if (error == noErr)
- error = CMSetDeviceFactoryProfiles(cmPrinterDeviceClass, device_id,
- default_profile_id, profiles);
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
}
else
error = 1000;
@@ -3711,21 +3547,8 @@ apple_register_profiles(
* Free any memory we used...
*/
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
CFRelease(profiles);
-# else
- if (num_profiles > 0)
- {
- for (profile = profiles->profiles;
- num_profiles > 0;
- profile ++, num_profiles --)
- CFRelease(profile->profileName);
-
- free(profiles);
- }
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
-
ppdClose(ppd);
}
@@ -3743,7 +3566,6 @@ apple_unregister_profiles(
* Make sure ColorSync is available...
*/
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
if (ColorSyncUnregisterDevice != NULL)
{
/*
@@ -3761,11 +3583,6 @@ apple_unregister_profiles(
CFRelease(deviceUUID);
}
}
-
-# else
- if (CMUnregisterColorDevice != NULL)
- CMUnregisterColorDevice(cmPrinterDeviceClass, _ppdHashName(p->name));
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
}
#endif /* __APPLE__ */
@@ -5159,7 +4976,7 @@ copy_banner(cupsd_client_t *con, /* I - Client connection */
cupsFilePrintf(out, "%dx%d%s", attr->values[i].resolution.xres,
attr->values[i].resolution.yres,
attr->values[i].resolution.units == IPP_RES_PER_INCH ?
- "dpi" : "dpc");
+ "dpi" : "dpcm");
break;
case IPP_TAG_URI :
@@ -9713,6 +9530,7 @@ release_job(cupsd_client_t *con, /* I - Client connection */
cupsdAddEvent(CUPSD_EVENT_JOB_CONFIG_CHANGED, cupsdFindDest(job->dest), job,
"Job job-hold-until value changed by user.");
+ ippSetString(job->attrs, &job->reasons, 0, "none");
}
/*
@@ -11453,7 +11271,7 @@ set_printer_defaults(
sprintf(value, "%dx%d%s", attr->values[0].resolution.xres,
attr->values[0].resolution.yres,
attr->values[0].resolution.units == IPP_RES_PER_INCH ?
- "dpi" : "dpc");
+ "dpi" : "dpcm");
printer->num_options = cupsAddOption(name, value,
printer->num_options,
&(printer->options));
diff --git a/scheduler/job.c b/scheduler/job.c
index 49a408219..a9c07aa07 100644
--- a/scheduler/job.c
+++ b/scheduler/job.c
@@ -2239,12 +2239,16 @@ cupsdSetJobHoldUntil(cupsd_job_t *job, /* I - Job */
job->dirty = 1;
cupsdMarkDirty(CUPSD_DIRTY_JOBS);
}
+
+ ippSetString(job->attrs, &job->reasons, 0, "job-hold-until-specified");
}
/*
* Update the hold time...
*/
+ job->cancel_time = 0;
+
if (!strcmp(when, "indefinite") || !strcmp(when, "auth-info-required"))
{
/*
@@ -2252,6 +2256,9 @@ cupsdSetJobHoldUntil(cupsd_job_t *job, /* I - Job */
*/
job->hold_until = 0;
+
+ if (MaxHoldTime > 0)
+ job->cancel_time = time(NULL) + MaxHoldTime;
}
else if (!strcmp(when, "day-time"))
{
@@ -3657,7 +3664,7 @@ get_options(cupsd_job_t *job, /* I - Job */
"%dx%d%s", attr->values[i].resolution.xres,
attr->values[i].resolution.yres,
attr->values[i].resolution.units == IPP_RES_PER_INCH ?
- "dpi" : "dpc");
+ "dpi" : "dpcm");
break;
case IPP_TAG_STRING :
@@ -4262,6 +4269,10 @@ start_job(cupsd_job_t *job, /* I - Job ID */
if (!cupsdLoadJob(job))
return;
+ if (!job->printer_message)
+ job->printer_message = ippFindAttribute(job->attrs,
+ "job-printer-state-message",
+ IPP_TAG_TEXT);
if (job->printer_message)
cupsdSetString(&(job->printer_message->values[0].string.text), "");
diff --git a/scheduler/job.h b/scheduler/job.h
index 50f17cc9d..b34f91e16 100644
--- a/scheduler/job.h
+++ b/scheduler/job.h
@@ -99,6 +99,8 @@ VAR int MaxJobs VALUE(0),
/* Max number of jobs */
MaxActiveJobs VALUE(0),
/* Max number of active jobs */
+ MaxHoldTime VALUE(0),
+ /* Max time for indefinite hold */
MaxJobsPerUser VALUE(0),
/* Max jobs per user */
MaxJobsPerPrinter VALUE(0),
diff --git a/scheduler/main.c b/scheduler/main.c
index aa5a3b34c..e0de67e4b 100644
--- a/scheduler/main.c
+++ b/scheduler/main.c
@@ -3,7 +3,7 @@
*
* Main loop for the CUPS scheduler.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -145,6 +145,10 @@ main(int argc, /* I - Number of command-line args */
int launchd_idle_exit;
/* Idle exit on select timeout? */
#endif /* HAVE_LAUNCHD */
+#ifdef HAVE_AVAHI
+ cupsd_timeout_t *tmo; /* Next scheduled timed callback */
+ long tmo_delay; /* Time before it must be called */
+#endif /* HAVE_AVAHI */
#ifdef HAVE_GETEUID
@@ -858,6 +862,16 @@ main(int argc, /* I - Number of command-line args */
}
#endif /* __APPLE__ */
+#ifdef HAVE_AVAHI
+ /*
+ * If a timed callback is due, run it.
+ */
+
+ tmo = cupsdNextTimeout(&tmo_delay);
+ if (tmo && tmo_delay == 0)
+ cupsdRunTimeout(tmo);
+#endif /* HAVE_AVAHI */
+
#ifndef __APPLE__
/*
* Update the network interfaces once a minute...
@@ -1753,6 +1767,10 @@ select_timeout(int fds) /* I - Number of descriptors returned */
cupsd_job_t *job; /* Job information */
cupsd_subscription_t *sub; /* Subscription information */
const char *why; /* Debugging aid */
+#ifdef HAVE_AVAHI
+ cupsd_timeout_t *tmo; /* Timed callback */
+ long tmo_delay; /* Seconds before calling it */
+#endif /* HAVE_AVAHI */
/*
@@ -1795,6 +1813,19 @@ select_timeout(int fds) /* I - Number of descriptors returned */
}
#endif /* __APPLE__ */
+#ifdef HAVE_AVAHI
+ /*
+ * See if there are any scheduled timed callbacks to run.
+ */
+
+ if ((tmo = cupsdNextTimeout(&tmo_delay)) != NULL &&
+ (now + tmo_delay) < timeout)
+ {
+ timeout = tmo_delay;
+ why = "run a timed callback";
+ }
+#endif /* HAVE_AVAHI */
+
/*
* Check whether we are accepting new connections...
*/
diff --git a/scheduler/printers.c b/scheduler/printers.c
index 37c16511d..293b64d31 100644
--- a/scheduler/printers.c
+++ b/scheduler/printers.c
@@ -1947,7 +1947,7 @@ cupsdSetPrinterAttr(
ptr ++;
else if (*ptr == '\'' || *ptr == '\"')
quote = *ptr;
- else if (*ptr == '.')
+ else if (*ptr == ',')
count ++;
}
@@ -2052,7 +2052,7 @@ cupsdSetPrinterAttr(
else
_cups_strcpy(ptr, ptr + 1);
}
- else if (*ptr == '.')
+ else if (*ptr == ',')
{
*ptr++ = '\0';
break;
diff --git a/scheduler/testsub.c b/scheduler/testsub.c
index 36e161507..88294a357 100644
--- a/scheduler/testsub.c
+++ b/scheduler/testsub.c
@@ -3,7 +3,7 @@
*
* Scheduler notification tester for CUPS.
*
- * Copyright 2007-2011 by Apple Inc.
+ * Copyright 2007-2012 by Apple Inc.
* Copyright 2006-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -453,7 +453,7 @@ print_attributes(ipp_t *ipp, /* I - IPP request */
case IPP_TAG_RESOLUTION :
for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
printf(" %dx%d%s", val->resolution.xres, val->resolution.yres,
- val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpc");
+ val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
putchar('\n');
break;
diff --git a/scheduler/timeout.c b/scheduler/timeout.c
new file mode 100644
index 000000000..2c3b376c2
--- /dev/null
+++ b/scheduler/timeout.c
@@ -0,0 +1,249 @@
+/*
+ * "$Id$"
+ *
+ * Timeout functions for the CUPS Scheduler.
+ *
+ * Copyright 2012 by Apple Inc.
+ *
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file. If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
+ *
+ * Copyright (C) 2010, 2011 Red Hat, Inc.
+ * Authors:
+ * Tim Waugh <twaugh@redhat.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Contents:
+ *
+ * cupsdAddTimeout() - Add a timed callback.
+ * cupsdNextTimeout() - Find the next enabled timed callback.
+ * cupsdRemoveTimeout() - Discard a timed callback.
+ * cupsdRunTimeout() - Run a timed callback.
+ * cupsdUpdateTimeout() - Adjust the time of a timed callback or disable it.
+ * compare_addrs() - Compare pointers for array sorting.
+ * compare_timeouts() - Compare timed callbacks for array sorting.
+ */
+
+#include "cupsd.h"
+#ifdef HAVE_AVAHI /* Applies to entire file... */
+
+/*
+ * Include necessary headers...
+ */
+
+# include <avahi-common/timeval.h>
+
+
+/*
+ * Local types...
+ */
+
+struct _cupsd_timeout_s /* Timeout data */
+{
+ struct timeval when; /* When to fire timeout */
+ int enabled; /* Is the timeout enabled? */
+ cupsd_timeoutfunc_t callback; /* Timeout callback */
+ void *data; /* User data for callback */
+};
+
+
+/*
+ * Local functions...
+ */
+
+static int compare_addrs(void *p0, void *p1);
+static int compare_timeouts(cupsd_timeout_t *p0, cupsd_timeout_t *p1);
+
+
+/*
+ * 'cupsdAddTimeout()' - Add a timed callback.
+ */
+
+cupsd_timeout_t * /* O - Timeout handle */
+cupsdAddTimeout(
+ const struct timeval *tv, /* I - Absolute time */
+ cupsd_timeoutfunc_t cb, /* I - Callback function */
+ void *data) /* I - User data */
+{
+ cupsd_timeout_t *timeout; /* I - New timeout */
+
+
+ if ((timeout = calloc(1, sizeof(cupsd_timeout_t))) != NULL)
+ {
+ timeout->enabled = (tv != NULL);
+ if (tv)
+ timeout->when = *tv;
+
+ timeout->callback = cb;
+ timeout->data = data;
+
+ if (!Timeouts)
+ Timeouts = cupsArrayNew((cups_array_func_t)compare_timeouts, NULL);
+
+ cupsArrayAdd(Timeouts, timeout);
+ }
+
+ return (timeout);
+}
+
+
+/*
+ * 'cupsdNextTimeout()' - Find the next enabled timed callback.
+ */
+
+cupsd_timeout_t * /* O - Next enabled timeout or NULL */
+cupsdNextTimeout(long *delay) /* O - Seconds before scheduled */
+{
+ cupsd_timeout_t *first = cupsArrayFirst(Timeouts);
+ /* First timeout */
+ struct timeval curtime; /* Current time */
+
+
+ if (first && !first->enabled)
+ first = NULL;
+
+ if (first && delay)
+ {
+ gettimeofday(&curtime, NULL);
+ if (avahi_timeval_compare(&curtime, &first->when) > 0)
+ *delay = 0;
+ else
+ {
+ *delay = 1 + first->when.tv_sec - curtime.tv_sec;
+ if (first->when.tv_usec < curtime.tv_usec)
+ (*delay) --;
+ }
+ }
+
+ return (first);
+}
+
+
+/*
+ * 'cupsdRemoveTimeout()' - Discard a timed callback.
+ */
+
+void
+cupsdRemoveTimeout(
+ cupsd_timeout_t *timeout) /* I - Timeout */
+{
+ cupsArrayRemove(Timeouts, timeout);
+ free(timeout);
+}
+
+
+/*
+ * 'cupsdRunTimeout()' - Run a timed callback.
+ */
+
+void
+cupsdRunTimeout(
+ cupsd_timeout_t *timeout) /* I - Timeout */
+{
+ if (timeout)
+ {
+ timeout->enabled = 0;
+ if (timeout->callback)
+ (*timeout->callback)(timeout, timeout->data);
+ }
+}
+
+
+/*
+ * 'cupsdUpdateTimeout()' - Adjust the time of a timed callback or disable it.
+ */
+
+void
+cupsdUpdateTimeout(
+ cupsd_timeout_t *timeout, /* I - Timeout */
+ const struct timeval *tv) /* I - Absolute time or NULL */
+{
+ cupsArrayRemove(Timeouts, timeout);
+ timeout->enabled = (tv != NULL);
+
+ if (tv)
+ timeout->when = *tv;
+
+ cupsArrayAdd(Timeouts, timeout);
+}
+
+
+/*
+ * 'compare_addrs()' - Compare pointers for array sorting.
+ */
+
+static int /* O - Result of comparison */
+compare_addrs(void *p0, /* I - First pointer */
+ void *p1) /* I - Second pointer */
+{
+ if (p0 == p1)
+ return (0);
+ else if (p0 < p1)
+ return (-1);
+ else
+ return (1);
+}
+
+
+/*
+ * 'compare_timeouts()' - Compare timed callbacks for array sorting.
+ */
+
+static int /* O - Result of comparison */
+compare_timeouts(cupsd_timeout_t *p0, /* I - First timeout */
+ cupsd_timeout_t *p1) /* I - Second timeout */
+{
+ int addrsdiff = compare_addrs (p0, p1);
+ /* Address difference */
+ int tvdiff; /* Time difference */
+
+
+ if (addrsdiff == 0)
+ return (0);
+
+ if (!p0->enabled || !p1->enabled)
+ {
+ if (!p0->enabled && !p1->enabled)
+ return (addrsdiff);
+
+ return (p0->enabled ? -1 : 1);
+ }
+
+ tvdiff = avahi_timeval_compare(&p0->when, &p1->when);
+ if (tvdiff != 0)
+ return (tvdiff);
+
+ return (addrsdiff);
+}
+#endif /* HAVE_AVAHI */
+
+
+/*
+ * End of "$Id$".
+ */
diff --git a/test/get-completed-jobs.test b/test/get-completed-jobs.test
index 9d8ebb40c..eca227935 100644
--- a/test/get-completed-jobs.test
+++ b/test/get-completed-jobs.test
@@ -3,7 +3,7 @@
#
# Get list of completed jobs.
#
-# Copyright 2007-2010 by Apple Inc.
+# Copyright 2007-2012 by Apple Inc.
# Copyright 2001-2006 by Easy Software Products. All rights reserved.
#
# These coded instructions, statements, and computer programs are the
@@ -32,7 +32,7 @@
ATTR uri printer-uri $uri
ATTR keyword which-jobs completed
ATTR keyword requested-attributes
- job-id,job-state,job-name,job-originating-user-name,job-media-sheets-completed
+ job-id,job-state,job-state-reasons,job-name,job-originating-user-name,job-media-sheets-completed
# What statuses are OK?
STATUS successful-ok
diff --git a/test/get-jobs.test b/test/get-jobs.test
index 4da5f6a7a..13b9959c2 100644
--- a/test/get-jobs.test
+++ b/test/get-jobs.test
@@ -3,7 +3,7 @@
#
# Get list of not-completed jobs.
#
-# Copyright 2007-2010 by Apple Inc.
+# Copyright 2007-2012 by Apple Inc.
# Copyright 2001-2006 by Easy Software Products. All rights reserved.
#
# These coded instructions, statements, and computer programs are the
@@ -31,7 +31,7 @@
ATTR language attributes-natural-language en
ATTR uri printer-uri $uri
ATTR keyword requested-attributes
- job-id,job-state,job-name,job-originating-user-name,job-media-sheets,job-media-sheets-completed,job-impressions,job-impressions-completed
+ job-id,job-state,job-state-reasons,job-name,job-originating-user-name,job-media-sheets,job-media-sheets-completed,job-impressions,job-impressions-completed
# What statuses are OK?
STATUS successful-ok
diff --git a/test/ipptool.c b/test/ipptool.c
index 66358e65f..d1cdea442 100644
--- a/test/ipptool.c
+++ b/test/ipptool.c
@@ -1608,7 +1608,9 @@ do_tests(_cups_vars_t *vars, /* I - Variables */
}
if (ptr <= token || xres <= 0 || yres <= 0 || !ptr ||
- (_cups_strcasecmp(ptr, "dpi") && _cups_strcasecmp(ptr, "dpc") &&
+ (_cups_strcasecmp(ptr, "dpi") &&
+ _cups_strcasecmp(ptr, "dpc") &&
+ _cups_strcasecmp(ptr, "dpcm") &&
_cups_strcasecmp(ptr, "other")))
{
print_fatal_error("Bad resolution value \"%s\" on line %d.",
@@ -1620,7 +1622,8 @@ do_tests(_cups_vars_t *vars, /* I - Variables */
if (!_cups_strcasecmp(ptr, "dpi"))
attrptr = ippAddResolution(request, group, attr, IPP_RES_PER_INCH,
xres, yres);
- else if (!_cups_strcasecmp(ptr, "dpc"))
+ else if (!_cups_strcasecmp(ptr, "dpc") ||
+ !_cups_strcasecmp(ptr, "dpcm"))
attrptr = ippAddResolution(request, group, attr, IPP_RES_PER_CM,
xres, yres);
else
@@ -2501,7 +2504,7 @@ do_tests(_cups_vars_t *vars, /* I - Variables */
{
int out_of_order = 0; /* Are attribute groups out-of-order? */
cupsArrayClear(a);
-
+
switch (attrptr->group_tag)
{
@@ -2639,7 +2642,7 @@ do_tests(_cups_vars_t *vars, /* I - Variables */
add_stringf(errors, "EXPECTED: %s OF-TYPE %s (got %s)",
expect->name, expect->of_type,
ippTagString(found->value_tag));
-
+
if (expect->in_group && found->group_tag != expect->in_group)
add_stringf(errors, "EXPECTED: %s IN-GROUP %s (got %s).",
expect->name, ippTagString(expect->in_group),
@@ -3273,7 +3276,9 @@ get_collection(_cups_vars_t *vars, /* I - Variables */
char units[6]; /* Units */
if (sscanf(token, "%dx%d%5s", &xres, &yres, units) != 3 ||
- (_cups_strcasecmp(units, "dpi") && _cups_strcasecmp(units, "dpc") &&
+ (_cups_strcasecmp(units, "dpi") &&
+ _cups_strcasecmp(units, "dpc") &&
+ _cups_strcasecmp(units, "dpcm") &&
_cups_strcasecmp(units, "other")))
{
print_fatal_error("Bad resolution value \"%s\" on line %d.",
@@ -3284,7 +3289,8 @@ get_collection(_cups_vars_t *vars, /* I - Variables */
if (!_cups_strcasecmp(units, "dpi"))
ippAddResolution(col, IPP_TAG_ZERO, attr, xres, yres,
IPP_RES_PER_INCH);
- else if (!_cups_strcasecmp(units, "dpc"))
+ else if (!_cups_strcasecmp(units, "dpc") ||
+ !_cups_strcasecmp(units, "dpcm"))
ippAddResolution(col, IPP_TAG_ZERO, attr, xres, yres,
IPP_RES_PER_CM);
else
@@ -3679,12 +3685,12 @@ print_attr(ipp_attribute_t *attr, /* I - Attribute to print */
attr->values[i].resolution.xres,
attr->values[i].resolution.yres,
attr->values[i].resolution.units == IPP_RES_PER_INCH ?
- "dpi" : "dpc");
+ "dpi" : "dpcm");
else
printf("%dx%d%s ", attr->values[i].resolution.xres,
attr->values[i].resolution.yres,
attr->values[i].resolution.units == IPP_RES_PER_INCH ?
- "dpi" : "dpc");
+ "dpi" : "dpcm");
break;
case IPP_TAG_DATE :
@@ -3831,7 +3837,7 @@ print_col(ipp_t *col) /* I - Collection attribute to print */
printf("%dx%d%s ", attr->values[i].resolution.xres,
attr->values[i].resolution.yres,
attr->values[i].resolution.units == IPP_RES_PER_INCH ?
- "dpi" : "dpc");
+ "dpi" : "dpcm");
break;
case IPP_TAG_STRING :
@@ -4554,7 +4560,7 @@ validate_attr(cups_array_t *errors, /* I - Errors array */
attr->values[i].resolution.units ==
IPP_RES_PER_INCH ? "dpi" :
attr->values[i].resolution.units ==
- IPP_RES_PER_CM ? "dpc" : "unknown");
+ IPP_RES_PER_CM ? "dpcm" : "unknown");
}
if (attr->values[i].resolution.yres <= 0)
@@ -4570,7 +4576,7 @@ validate_attr(cups_array_t *errors, /* I - Errors array */
attr->values[i].resolution.units ==
IPP_RES_PER_INCH ? "dpi" :
attr->values[i].resolution.units ==
- IPP_RES_PER_CM ? "dpc" : "unknown");
+ IPP_RES_PER_CM ? "dpcm" : "unknown");
}
if (attr->values[i].resolution.units != IPP_RES_PER_INCH &&
@@ -4586,7 +4592,7 @@ validate_attr(cups_array_t *errors, /* I - Errors array */
attr->values[i].resolution.units ==
IPP_RES_PER_INCH ? "dpi" :
attr->values[i].resolution.units ==
- IPP_RES_PER_CM ? "dpc" : "unknown");
+ IPP_RES_PER_CM ? "dpcm" : "unknown");
}
}
break;