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)
-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",
*
* 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
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://... */
};
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 */
{
"copies-supported",
"cups-version",
- "document-format-default",
"document-format-supported",
"marker-colors",
"marker-high-levels",
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 */
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 */
const char *ptr = getenv("AUTH_USERNAME");
if (ptr)
+ {
+ strlcpy(username, ptr, sizeof(username));
cupsSetUser(ptr);
+ }
password = getenv("AUTH_PASSWORD");
}
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));
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 */
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."));
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)
{
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;
_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);
}
else if (ipp_status == IPP_ERROR_JOB_CANCELED)
goto cleanup;
+ else if (ipp_status == IPP_NOT_AUTHORIZED)
+ continue;
else
{
/*
_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])
}
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);
_("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;
+ }
}
}
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 &&
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...
*/
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);
/*
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",
"multiple-document-handling", NULL, collate_str);
break;
}
+
+ if (i >= doc_handling_sup->num_values)
+ copies = 1;
}
/*
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);
}
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;
/*
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);
#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 */
/*
return (CUPS_BACKEND_FAILED);
}
+ num_jobopts = cupsParseOptions(argv[5], 0, &jobopts);
+
/*
* Extract the hostname and printer name from the URI...
*/
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]));
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...
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 */
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 */
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 */
(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);
}
/*
*
* 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
"%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 :
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...
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))
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
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",)
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*)
/*
- * 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>?
*/
#undef CUPS_BUNDLEDIR
-/*
- * Do we have the ColorSyncRegisterDevice function?
- */
-
-#undef HAVE_COLORSYNCREGISTERDEVICE
-
-
/*
* Do we have XPC?
*/
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 */
* 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...
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)
*/
#ifdef HAVE_GSSAPI
- if (!strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Negotiate", 9))
+ if (!_cups_strncasecmp(www_auth, "Negotiate", 9))
{
/*
* Kerberos authentication...
}
else
#endif /* HAVE_GSSAPI */
- if (!strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Basic", 5))
+ if (!_cups_strncasecmp(www_auth, "Basic", 5))
{
/*
* Basic authentication...
(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...
else
{
DEBUG_printf(("1cupsDoAuthentication: Unknown auth type: \"%s\"",
- http->fields[HTTP_FIELD_WWW_AUTHENTICATE]));
+ www_auth));
http->status = HTTP_AUTHORIZATION_CANCELED;
return (-1);
}
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);
*
* 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
*/
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);
*
* 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
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;
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);
}
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."));
}
/*
- * 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)
* 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,
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;
}
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
* Buffer small reads for better performance...
*/
+ ssize_t buflen; /* Length of read for buffer */
+
if (!http->blocking)
{
while (!httpWait(http, http->wait_value))
}
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)
*
* 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
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 :
* 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);
goto create_error;
}
+ pc->max_copies = 9999;
+
/*
* Read the file...
*/
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,
NULL)) != NULL);
}
+ /*
+ * 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...
*/
cupsFilePutChar(fp, '\n');
}
+ /*
+ * Max copies...
+ */
+
+ cupsFilePrintf(fp, "MaxCopies %d\n", pc->max_copies);
+
/*
* IPP attributes, if any...
*/
* Constants...
*/
-# define _PPD_CACHE_VERSION 2 /* Version number in cache file */
+# define _PPD_CACHE_VERSION 3 /* Version number in cache file */
/*
*prefilters; /* cupsPreFilter values */
int single_file; /* cupsSingleFile value */
cups_array_t *finishings; /* cupsIPPFinishings values */
+ int max_copies; /* cupsMaxCopies value */
};
*
* 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
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;
_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 */
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);
}
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 */
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)
{
* 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 */
_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 */
#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 */
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));
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;
<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>
<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>
<!--
Use the <a href="#cupsLastError"><code>cupsLastError</code></a> and <a href="#cupsLastErrorString"><code>cupsLastErrorString</code></a> functions to get
the cause of any failure.
+</p>
+<h3 class="function"><span class="info"> CUPS 1.6 </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>
+ <a href="#cups_dest_t">cups_dest_t</a> *dest,<br>
+ unsigned flags,<br>
+ int msec,<br>
+ int *cancel,<br>
+ char *resource,<br>
+ size_t resourcesize,<br>
+ <a href="#cups_dest_cb_t">cups_dest_cb_t</a> cb,<br>
+ 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 "cancel" 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 "cancel" 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"> CUPS 1.6 </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>
+ <a href="#cups_dest_t">cups_dest_t</a> *dest,<br>
+ unsigned flags,<br>
+ int msec,<br>
+ int *cancel,<br>
+ char *resource,<br>
+ size_t resourcesize,<br>
+ <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 "cancel" 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 "cancel" 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>
+ <a href="#cups_dest_t">cups_dest_t</a> *dest,<br>
+ int num_dests,<br>
+ <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"> CUPS 1.4/Mac OS X 10.6 </span><a name="cupsCreateJob">cupsCreateJob</a></h3>
<p class="description">Create an empty job for streaming.</p>
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"> CUPS 1.6 </span><a name="cupsEnumDests">cupsEnumDests</a></h3>
+<p class="description">Enumerate available destinations with a callback function.</p>
+<p class="code">
+int cupsEnumDests (<br>
+ unsigned flags,<br>
+ int msec,<br>
+ int *cancel,<br>
+ <a href="#cups_ptype_t">cups_ptype_t</a> type,<br>
+ <a href="#cups_ptype_t">cups_ptype_t</a> mask,<br>
+ <a href="#cups_dest_cb_t">cups_dest_cb_t</a> cb,<br>
+ 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 "cancel" 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"> CUPS 1.6 </span><a name="cupsEnumDestsBlock">cupsEnumDestsBlock</a></h3>
+<p class="description">Enumerate available destinations with a block.</p>
+<p class="code">
+int cupsEnumDestsBlock (<br>
+ unsigned flags,<br>
+ int timeout,<br>
+ int *cancel,<br>
+ <a href="#cups_ptype_t">cups_ptype_t</a> type,<br>
+ <a href="#cups_ptype_t">cups_ptype_t</a> mask,<br>
+ <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 "cancel" 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"> CUPS 1.4/Mac OS X 10.6 </span><a name="cupsFinishDocument">cupsFinishDocument</a></h3>
<p class="description">Finish sending a document.</p>
<p class="code">
name to be used.</p>
<h2 class="title"><a name="TYPES">Data Types</a></h2>
<h3 class="typedef"><span class="info"> CUPS 1.5/Mac OS X 10.7 </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"> CUPS 1.6 </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"> CUPS 1.6 </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"> CUPS 1.4/Mac OS X 10.6 </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"> CUPS 1.6 </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">
typedef struct <a href="#cups_option_s">cups_option_s</a> cups_option_t;
</p>
<h3 class="typedef"><span class="info"> CUPS 1.4/Mac OS X 10.6 </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>
typedef unsigned cups_ptype_t;
</p>
<h3 class="typedef"><span class="info"> CUPS 1.5/Mac OS X 10.7 </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"> CUPS 1.6 </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>
<dt>value </dt>
<dd class="description">Value of option</dd>
</dl>
+<h3 class="struct"><span class="info"> CUPS 1.6 </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>
+ char media[128];<br>
+ 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
<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"> CUPS 1.2/Mac OS X 10.5 </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>
<dt>CUPS_PRINTER_COLOR </dt>
<dd class="description">Can do color printing</dd>
<dt>CUPS_PRINTER_COMMANDS <span class="info"> CUPS 1.2/Mac OS X 10.5 </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>
<dt>CUPS_PRINTER_DEFAULT </dt>
<dd class="description">Default printer on network</dd>
<dt>CUPS_PRINTER_DELETE <span class="info"> CUPS 1.2/Mac OS X 10.5 </span></dt>
-<dd class="description">Delete printer </dd>
-<dt>CUPS_PRINTER_DISCOVERED <span class="info"> CUPS 1.3/Mac OS X 10.5 </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>
<dt>CUPS_PRINTER_MEDIUM </dt>
<dd class="description">Can do Tabloid/B/C/A3/A2</dd>
<dt>CUPS_PRINTER_MFP <span class="info"> CUPS 1.4/Mac OS X 10.6 </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"> CUPS 1.2/Mac OS X 10.5 </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>
<dt>CUPS_PRINTER_REMOTE </dt>
<dd class="description">Remote printer or class</dd>
<dt>CUPS_PRINTER_SCANNER <span class="info"> CUPS 1.4/Mac OS X 10.6 </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>
<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
<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>
<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>
<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>
</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>
+ <a href="#http_t">http_t</a> *http,<br>
+ int msec,<br>
+ 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 "cancel" 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"> DEPRECATED </span><a name="httpSeparate">httpSeparate</a></h3>
<p class="description">Separate a Universal Resource Identifier into its
components.</p>
<p class="code">
int ippDeleteValues (<br>
<a href="#ipp_t">ipp_t</a> *ipp,<br>
- <a href="#ipp_attribute_t">ipp_attribute_t</a> *attr,<br>
+ <a href="#ipp_attribute_t">ipp_attribute_t</a> **attr,<br>
int element,<br>
int count<br>
);</p>
<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.
<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>
<a href="#ipp_t">ipp_t</a> *ipp,<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>
<a href="#ipp_t">ipp_t</a> *ipp,<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"> CUPS 1.6 </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>
+ <a href="#ipp_attribute_t">ipp_attribute_t</a> *attr,<br>
+ 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"> CUPS 1.6 </span><a name="ippGetGroupTag">ippGetGroupTag</a></h3>
<p class="description">Get the group associated with an attribute.</p>
<p class="code">
</dl>
<h4 class="returnvalue">Return Value</h4>
<p class="description">Operation ID or -1 on error</p>
+<h3 class="function"><span class="info"> CUPS 1.6 </span><a name="ippGetRange">ippGetRange</a></h3>
+<p class="description">Get a rangeOfInteger value from an attribute.</p>
+<p class="code">
+int ippGetRange (<br>
+ <a href="#ipp_attribute_t">ipp_attribute_t</a> *attr,<br>
+ int element,<br>
+ 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"> CUPS 1.6 </span><a name="ippGetRequestId">ippGetRequestId</a></h3>
<p class="description">Get the request ID from an IPP message.</p>
<p class="code">
<a href="#ippGetCount(attr)"><code>ippGetCount(attr)</code></a> - 1.
</p>
+<h3 class="function"><span class="info"> CUPS 1.6 </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>
+ <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"> CUPS 1.6 </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">
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"> CUPS 1.6 </span><a name="ippSetDate">ippSetDate</a></h3>
+<p class="description">Set a date value in an attribute.</p>
+<p class="code">
+int ippSetDate (<br>
+ <a href="#ipp_t">ipp_t</a> *ipp,<br>
+ <a href="#ipp_attribute_t">ipp_attribute_t</a> **attr,<br>
+ int element,<br>
+ 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"> CUPS 1.6 </span><a name="ippSetGroupTag">ippSetGroupTag</a></h3>
<p class="description">Set the group tag of an attribute.</p>
<a href="#ippGetCount(attr)"><code>ippGetCount(attr)</code></a>.
</p>
+<h3 class="function"><span class="info"> CUPS 1.6 </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>
+ <a href="#ipp_t">ipp_t</a> *ipp,<br>
+ <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"> CUPS 1.6 </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">
<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>
<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>
<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>
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.
</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>
4 Require user @OWNER @SYSTEM
5 Order deny,allow
6 </Limit>
- 7
+ 7
8 # All administration operations require an administrator
to authenticate...
9 <Limit CUPS-Add-Printer CUPS-Delete-Printer CUPS-Add-Class
11 Require user @SYSTEM
12 Order deny,allow
13 </Limit>
-14
+14
15 # All printer operations require a printer operator
to authenticate...
16 <Limit Pause-Printer Resume-Printer
18 Require user <em>varies by OS</em>
19 Order deny,allow
20 </Limit>
-21
+21
22 # Only the owner or an administrator can cancel or
authenticate a job...
23 <Limit Cancel-Job CUPS-Authenticate-Job>
24 Require user @OWNER @SYSTEM
25 Order deny,allow
26 </Limit>
-27
+27
28 <Limit All>
29 Order deny,allow
30 </Limit>
11 Require user @SYSTEM
12 Order deny,allow
13 </Limit>
-14
+14
15 # All printer operations require a printer operator
to authenticate...
16 <Limit Pause-Printer Resume-Printer
<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>
<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>
<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>
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>
</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>
5 Order allow,deny
6 Allow from 10.0.2.0/24
7 </Limit>
- 8
+ 8
9 # All administration operations require a lab technician
or an administrator to authenticate...
10 <Limit Pause-Printer Resume-Printer
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
(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>
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>
</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>
</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.
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
<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>
*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>
<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>
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
(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>
*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 */
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
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 */
* %%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));
{
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))
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);
}
* %%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))
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
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 */
/*
doc->emit_jcl = 1;
/*
- * fitplot/fit-to-page/ipp-attribute-fidelity
+ * fit-to-page/ipp-attribute-fidelity
*
* (Only for original PostScript content)
*/
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;
}
/*
* 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
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"))
{
/*
pagew = PageRight - PageLeft;
pagel = PageTop - PageBottom;
- if (doc->fitplot)
+ if (doc->fit_to_page)
{
bboxx = bounding_box[0];
bboxy = bounding_box[1];
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;
doc_puts(doc, "grestore\n");
}
- if (doc->fitplot)
+ if (doc->fit_to_page)
{
/*
* Offset the page by its bounding box...
-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...
*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>
<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>
.\"
.\" 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
.\" 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
.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 $".
.\"
.\" 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
.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.
.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 $".
.\"
.\"
.\" 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
.\" 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
.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
.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 $".
.\"
CUPSDOBJS = \
auth.o \
+ avahi.o \
banners.o \
cert.o \
classes.o \
server.o \
statbuf.o \
subscriptions.o \
- sysman.o
+ sysman.o \
+ timeout.o
LIBOBJS = \
filter.o \
mime.o \
*
* 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
#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 */
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 */
--- /dev/null
+/*
+ * "$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$".
+ */
--- /dev/null
+/*
+ * "$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$".
+ */
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 */
*
* 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
{ "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 },
JobHistory = DEFAULT_HISTORY;
JobFiles = DEFAULT_FILES;
JobAutoPurge = 0;
+ MaxHoldTime = 0;
MaxJobs = 500;
MaxActiveJobs = 0;
MaxJobsPerUser = 0;
* 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
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));
}
/*
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...
/* 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...
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 $".
#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>
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);
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 */
* Fill in the profile data...
*/
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
if (iccfile)
{
url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
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 */
}
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...
*/
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...
*/
ppdClose(ppd);
return;
}
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
/*
* If we have profiles, add them...
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...
*/
else
profile_id = atoi(attr->spec);
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
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...
*/
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 ++)
snprintf(selector, sizeof(selector), "%s..", profile_name);
profile_id = _ppdHashName(selector);
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
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;
}
num_profiles = (attr && ppd->colorspace == PPD_CS_GRAY) ? 1 : 2;
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
/*
* Add the grayscale profile first. We always have a grayscale profile.
*/
}
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)
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)
dict_key);
CFRelease(dict_key);
}
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
/*
* Get the device ID hash and pathelogical name dictionary.
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,
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,
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;
* 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);
}
* Make sure ColorSync is available...
*/
-# ifdef HAVE_COLORSYNCREGISTERDEVICE
if (ColorSyncUnregisterDevice != NULL)
{
/*
CFRelease(deviceUUID);
}
}
-
-# else
- if (CMUnregisterColorDevice != NULL)
- CMUnregisterColorDevice(cmPrinterDeviceClass, _ppdHashName(p->name));
-# endif /* HAVE_COLORSYNCREGISTERDEVICE */
}
#endif /* __APPLE__ */
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 :
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");
}
/*
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));
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"))
{
/*
*/
job->hold_until = 0;
+
+ if (MaxHoldTime > 0)
+ job->cancel_time = time(NULL) + MaxHoldTime;
}
else if (!strcmp(when, "day-time"))
{
"%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 :
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), "");
/* 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),
*
* 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
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
}
#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...
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 */
/*
}
#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...
*/
ptr ++;
else if (*ptr == '\'' || *ptr == '\"')
quote = *ptr;
- else if (*ptr == '.')
+ else if (*ptr == ',')
count ++;
}
else
_cups_strcpy(ptr, ptr + 1);
}
- else if (*ptr == '.')
+ else if (*ptr == ',')
{
*ptr++ = '\0';
break;
*
* 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
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;
--- /dev/null
+/*
+ * "$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$".
+ */
#
# 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
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
#
# 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
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
}
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.",
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
{
int out_of_order = 0; /* Are attribute groups out-of-order? */
cupsArrayClear(a);
-
+
switch (attrptr->group_tag)
{
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),
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.",
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
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 :
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 :
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)
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 &&
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;