summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2008-01-04 02:32:38 +0000
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2008-01-04 02:32:38 +0000
commit3d052e433049a9cd5a7a1b7934b8a39badc8102b (patch)
tree602a5e18f110368a3d42ed822eae735d4f931c32
parenta4924f6c45f9a65e7c380e63c8539e86c0795d60 (diff)
downloadcups-3d052e433049a9cd5a7a1b7934b8a39badc8102b.tar.gz
Import CUPS 1.4svn-r7170.
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@567 a1ca3aef-8c08-0410-bb20-df032aa958be
-rw-r--r--CHANGES-1.3.txt5
-rw-r--r--CHANGES.txt3
-rw-r--r--README.txt10
-rw-r--r--backend/ipp.c7
-rw-r--r--berkeley/lpr.c136
-rw-r--r--cups/cups.h49
-rw-r--r--cups/dest.c62
-rw-r--r--cups/globals.h1
-rw-r--r--cups/libcups.exp8
-rw-r--r--cups/request.c678
-rw-r--r--cups/util.c780
-rw-r--r--data/testprint.ps8
-rw-r--r--doc/index.html.in4
-rw-r--r--man/cupsd.conf.man.in12
-rw-r--r--man/lpadmin.man27
-rw-r--r--man/lpq.man8
-rw-r--r--pdftops/pdftops.cxx3
-rw-r--r--systemv/lp.c140
-rw-r--r--templates/trailer.tmpl4
19 files changed, 1033 insertions, 912 deletions
diff --git a/CHANGES-1.3.txt b/CHANGES-1.3.txt
index 5822d1565..c9e71da74 100644
--- a/CHANGES-1.3.txt
+++ b/CHANGES-1.3.txt
@@ -3,6 +3,11 @@ CHANGES-1.3.txt
CHANGES IN CUPS V1.3.6
+ - Documentation updates (STR #2646, STR #2647, STR #2649)
+ - The PDF filter incorrectly filtered pages when page-ranges
+ and number-up were both specified (STR #2643)
+ - The IPP backend did not handle printing of pictwps files
+ to a non-Mac CUPS server properly.
- The scheduler did not detect network interface changes
on operating systems other than Mac OS X (STR #2631)
- The scheduler now logs the UNIX error message when it
diff --git a/CHANGES.txt b/CHANGES.txt
index 9d917f106..3678d8164 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,8 +1,9 @@
-CHANGES.txt - 2007-12-19
+CHANGES.txt - 2008-01-03
------------------------
CHANGES IN CUPS V1.4b1
+ - Added a new streaming request API (STR #2261)
- Added a new cupsGetNamedDest() function to the CUPS
library for faster printing with lp and lpr (STR #2638)
- The scheduler now sets the PAM RHOST value on systems
diff --git a/README.txt b/README.txt
index 48fee5a99..10d723239 100644
--- a/README.txt
+++ b/README.txt
@@ -1,5 +1,5 @@
-README - CUPS v1.3.0 - 2007-08-13
----------------------------------
+README - CUPS v1.4svn - 2008-01-02
+----------------------------------
Looking for compile instructions? Read the file "INSTALL.txt"
instead...
@@ -153,9 +153,9 @@ PRINTING FILES
LEGAL STUFF
- CUPS is Copyright 2007 by Apple Inc. CUPS, the CUPS logo, and
- the Common UNIX Printing System are the trademark property of
- Apple Inc.
+ CUPS is Copyright 2007-2008 by Apple Inc. CUPS, the CUPS logo,
+ and the Common UNIX Printing System are the trademark property
+ of Apple Inc.
The MD5 Digest code is Copyright 1999 Aladdin Enterprises.
diff --git a/backend/ipp.c b/backend/ipp.c
index 95e598252..3348cd5cf 100644
--- a/backend/ipp.c
+++ b/backend/ipp.c
@@ -3,7 +3,7 @@
*
* IPP backend for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products, all rights reserved.
*
* These coded instructions, statements, and computer programs are the
@@ -865,12 +865,13 @@ main(int argc, /* I - Number of command-line args */
num_options = cupsParseOptions(argv[5], 0, &options);
#ifdef __APPLE__
- if (!strcasecmp(content_type, "application/pictwps") && num_files == 1)
+ if (!strcasecmp(final_content_type, "application/pictwps") &&
+ num_files == 1)
{
if (format_sup != NULL)
{
for (i = 0; i < format_sup->num_values; i ++)
- if (!strcasecmp(content_type, format_sup->values[i].string.text))
+ if (!strcasecmp(final_content_type, format_sup->values[i].string.text))
break;
}
diff --git a/berkeley/lpr.c b/berkeley/lpr.c
index de01906bc..a1388be7e 100644
--- a/berkeley/lpr.c
+++ b/berkeley/lpr.c
@@ -1,5 +1,5 @@
/*
- * "$Id: lpr.c 7017 2007-10-10 22:09:57Z mike $"
+ * "$Id: lpr.c 7170 2008-01-04 02:21:30Z mike $"
*
* "lpr" command for the Common UNIX Printing System (CUPS).
*
@@ -14,8 +14,7 @@
*
* Contents:
*
- * main() - Parse options and send files for printing.
- * sighandler() - Signal catcher for when we print from stdin...
+ * main() - Parse options and send files for printing.
*/
/*
@@ -30,25 +29,6 @@
#include <cups/cups.h>
#include <cups/i18n.h>
-#ifndef WIN32
-# include <unistd.h>
-# include <signal.h>
-
-
-/*
- * Local functions.
- */
-
-void sighandler(int);
-#endif /* !WIN32 */
-
-
-/*
- * Globals...
- */
-
-char tempfile[1024]; /* Temporary file for printing from stdin */
-
/*
* 'main()' - Parse options and send files for printing.
@@ -73,13 +53,6 @@ main(int argc, /* I - Number of command-line arguments */
cups_option_t *options; /* Options */
int deletefile; /* Delete file after print? */
char buffer[8192]; /* Copy buffer */
- ssize_t bytes; /* Bytes copied */
- off_t filesize; /* Size of temp file */
- int temp; /* Temporary file descriptor */
-#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
- struct sigaction action; /* Signal action */
- struct sigaction oldaction; /* Old signal action */
-#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
_cupsSetLocale(argv);
@@ -409,72 +382,38 @@ main(int argc, /* I - Number of command-line arguments */
unlink(files[i]);
}
}
- else
+ else if ((job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, printer,
+ title ? title : "(stdin)",
+ num_options, options)) > 0)
{
- num_files = 1;
-
-#ifndef WIN32
-# if defined(HAVE_SIGSET)
- sigset(SIGHUP, sighandler);
- if (sigset(SIGINT, sighandler) == SIG_IGN)
- sigset(SIGINT, SIG_IGN);
- sigset(SIGTERM, sighandler);
-# elif defined(HAVE_SIGACTION)
- memset(&action, 0, sizeof(action));
- action.sa_handler = sighandler;
-
- sigaction(SIGHUP, &action, NULL);
- sigaction(SIGINT, NULL, &oldaction);
- if (oldaction.sa_handler != SIG_IGN)
- sigaction(SIGINT, &action, NULL);
- sigaction(SIGTERM, &action, NULL);
-# else
- signal(SIGHUP, sighandler);
- if (signal(SIGINT, sighandler) == SIG_IGN)
- signal(SIGINT, SIG_IGN);
- signal(SIGTERM, sighandler);
-# endif
-#endif /* !WIN32 */
-
- if ((temp = cupsTempFd(tempfile, sizeof(tempfile))) < 0)
- {
- _cupsLangPrintf(stderr,
- _("%s: Error - unable to create temporary file "
- "\"%s\" - %s\n"),
- argv[0], tempfile, strerror(errno));
- return (1);
- }
+ http_status_t status; /* Write status */
+ const char *format; /* Document format */
+ ssize_t bytes; /* Bytes read */
- while ((bytes = read(0, buffer, sizeof(buffer))) > 0)
- if (write(temp, buffer, bytes) < 0)
- {
- _cupsLangPrintf(stderr,
- _("%s: Error - unable to write to temporary file "
- "\"%s\" - %s\n"),
- argv[0], tempfile, strerror(errno));
- close(temp);
- unlink(tempfile);
- return (1);
- }
- filesize = lseek(temp, 0, SEEK_CUR);
- close(temp);
+ if (cupsGetOption("raw", num_options, options))
+ format = CUPS_FORMAT_RAW;
+ else if ((format = cupsGetOption("document-format", num_options,
+ options)) == NULL)
+ format = CUPS_FORMAT_AUTO;
+
+ status = cupsStartDocument(CUPS_HTTP_DEFAULT, printer, job_id, NULL,
+ format, 1);
- if (filesize <= 0)
+ while (status == HTTP_CONTINUE &&
+ (bytes = read(0, buffer, sizeof(buffer))) > 0)
+ status = cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer, bytes);
+
+ if (status != HTTP_CONTINUE)
{
_cupsLangPrintf(stderr,
- _("%s: Error - stdin is empty, so no job has been sent.\n"),
- argv[0]);
- unlink(tempfile);
+ _("%s: Error - unable to queue from stdin - %s\n"),
+ argv[0], httpStatus(status));
return (1);
}
- if (title)
- job_id = cupsPrintFile(printer, tempfile, title, num_options, options);
- else
- job_id = cupsPrintFile(printer, tempfile, "(stdin)", num_options, options);
-
- unlink(tempfile);
+ if (cupsFinishDocument(CUPS_HTTP_DEFAULT, printer) != IPP_OK)
+ job_id = 0;
}
if (job_id < 1)
@@ -487,29 +426,6 @@ main(int argc, /* I - Number of command-line arguments */
}
-#ifndef WIN32
-/*
- * 'sighandler()' - Signal catcher for when we print from stdin...
- */
-
-void
-sighandler(int s) /* I - Signal number */
-{
- /*
- * Remove the temporary file we're using to print from stdin...
- */
-
- unlink(tempfile);
-
- /*
- * Exit...
- */
-
- exit(s);
-}
-#endif /* !WIN32 */
-
-
/*
- * End of "$Id: lpr.c 7017 2007-10-10 22:09:57Z mike $".
+ * End of "$Id: lpr.c 7170 2008-01-04 02:21:30Z mike $".
*/
diff --git a/cups/cups.h b/cups/cups.h
index e938dfa94..187071682 100644
--- a/cups/cups.h
+++ b/cups/cups.h
@@ -59,11 +59,19 @@ extern "C" {
* Constants...
*/
-# define CUPS_VERSION 1.0400
+# define CUPS_VERSION 1.0399
# define CUPS_VERSION_MAJOR 1
# define CUPS_VERSION_MINOR 4
-# define CUPS_VERSION_PATCH 0
-# define CUPS_DATE_ANY -1
+# define CUPS_VERSION_PATCH -1
+
+# define CUPS_DATE_ANY (time_t)-1
+# define CUPS_FORMAT_AUTO "application/octet-stream"
+# define CUPS_FORMAT_PDF "application/pdf"
+# define CUPS_FORMAT_POSTSCRIPT "application/postscript"
+# define CUPS_FORMAT_RAW "application/vnd.cups-raw"
+# define CUPS_FORMAT_TEXT "text/plain"
+# define CUPS_HTTP_DEFAULT (http_t *)0
+# define CUPS_LENGTH_VARIABLE (ssize_t)0
/*
@@ -140,7 +148,7 @@ typedef struct cups_job_s /**** Job ****/
* Functions...
*/
-extern int cupsCancelJob(const char *printer, int job);
+extern int cupsCancelJob(const char *name, int job_id);
extern ipp_t *cupsDoFileRequest(http_t *http, ipp_t *request,
const char *resource,
const char *filename);
@@ -152,13 +160,13 @@ extern int cupsGetClasses(char ***classes) _CUPS_DEPRECATED;
extern const char *cupsGetDefault(void);
extern int cupsGetJobs(cups_job_t **jobs, const char *dest,
int myjobs, int completed);
-extern const char *cupsGetPPD(const char *printer);
+extern const char *cupsGetPPD(const char *name);
extern int cupsGetPrinters(char ***printers) _CUPS_DEPRECATED;
extern ipp_status_t cupsLastError(void);
-extern int cupsPrintFile(const char *printer, const char *filename,
+extern int cupsPrintFile(const char *name, const char *filename,
const char *title, int num_options,
cups_option_t *options);
-extern int cupsPrintFiles(const char *printer, int num_files,
+extern int cupsPrintFiles(const char *name, int num_files,
const char **files, const char *title,
int num_options, cups_option_t *options);
extern char *cupsTempFile(char *filename, int len) _CUPS_DEPRECATED;
@@ -206,14 +214,14 @@ extern http_status_t cupsPutFd(http_t *http, const char *resource, int fd) _CUPS
extern const char *cupsGetDefault2(http_t *http) _CUPS_API_1_1_21;
extern int cupsGetDests2(http_t *http, cups_dest_t **dests) _CUPS_API_1_1_21;
extern int cupsGetJobs2(http_t *http, cups_job_t **jobs,
- const char *dest, int myjobs,
+ const char *name, int myjobs,
int completed) _CUPS_API_1_1_21;
-extern const char *cupsGetPPD2(http_t *http, const char *printer) _CUPS_API_1_1_21;
-extern int cupsPrintFile2(http_t *http, const char *printer,
+extern const char *cupsGetPPD2(http_t *http, const char *name) _CUPS_API_1_1_21;
+extern int cupsPrintFile2(http_t *http, const char *name,
const char *filename,
const char *title, int num_options,
cups_option_t *options) _CUPS_API_1_1_21;
-extern int cupsPrintFiles2(http_t *http, const char *printer,
+extern int cupsPrintFiles2(http_t *http, const char *name,
int num_files, const char **files,
const char *title, int num_options,
cups_option_t *options) _CUPS_API_1_1_21;
@@ -249,11 +257,30 @@ extern void cupsSetDefaultDest(const char *name,
cups_dest_t *dests) _CUPS_API_1_3;
/**** New in CUPS 1.4 ****/
+extern ipp_status_t cupsCancelJob2(http_t *http, int job_id, int purge);
+extern int cupsCreateJob(http_t *http, const char *name,
+ const char *title, int num_options,
+ cups_option_t *options) _CUPS_API_1_4;
+extern ipp_status_t cupsFinishDocument(http_t *http,
+ const char *name) _CUPS_API_1_4;
extern cups_dest_t *cupsGetNamedDest(http_t *http, const char *name,
const char *instance) _CUPS_API_1_4;
extern http_status_t cupsGetPPD3(http_t *http, const char *name,
time_t *modtime, char *buffer,
size_t bufsize) _CUPS_API_1_4;
+extern ipp_t *cupsGetResponse(http_t *http,
+ const char *resource) _CUPS_API_1_4;
+extern ssize_t cupsReadResponseData(http_t *http, char *buffer,
+ size_t length) _CUPS_API_1_4;
+extern http_status_t cupsSendRequest(http_t *http, ipp_t *request,
+ const char *resource,
+ size_t length) _CUPS_API_1_4;
+extern http_status_t cupsStartDocument(http_t *http, const char *name,
+ int job_id, const char *docname,
+ const char *format,
+ int last_document) _CUPS_API_1_4;
+extern http_status_t cupsWriteRequestData(http_t *http, const char *buffer,
+ size_t length) _CUPS_API_1_4;
# ifdef __cplusplus
}
diff --git a/cups/dest.c b/cups/dest.c
index 9f4fd212b..2b8978433 100644
--- a/cups/dest.c
+++ b/cups/dest.c
@@ -265,20 +265,7 @@ cupsGetDest(const char *name, /* I - Destination name or NULL for the default
int /* O - Number of destinations */
cupsGetDests(cups_dest_t **dests) /* O - Destinations */
{
- int num_dests; /* Number of destinations */
- _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
-
-
- /*
- * Connect to the CUPS server and get the destination list and options...
- */
-
- if (!cg->http)
- cg->http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
-
- num_dests = cupsGetDests2(cg->http, dests);
-
- return (num_dests);
+ return (cupsGetDests2(CUPS_HTTP_DEFAULT, dests));
}
@@ -297,7 +284,7 @@ cupsGetDests(cups_dest_t **dests) /* O - Destinations */
*/
int /* O - Number of destinations */
-cupsGetDests2(http_t *http, /* I - HTTP connection */
+cupsGetDests2(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
cups_dest_t **dests) /* O - Destinations */
{
int i; /* Looping var */
@@ -310,14 +297,14 @@ cupsGetDests2(http_t *http, /* I - HTTP connection */
*instance; /* Pointer to instance name */
int num_reals; /* Number of real queues */
cups_dest_t *reals; /* Real queues */
- _cups_globals_t *cg = _cupsGlobals(); /* Global data */
+ _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
/*
* Range check the input...
*/
- if (!http || !dests)
+ if (!dests)
return (0);
/*
@@ -461,7 +448,8 @@ cupsGetDests2(http_t *http, /* I - HTTP connection */
* If NULL is returned, the destination does not exist or there is no default
* destination.
*
- * If "http" is NULL, the connection to the default print server will be used.
+ * If "http" is CUPS_HTTP_DEFAULT, the connection to the default print server
+ * will be used.
*
* If "name" is NULL, the default printer for the current user will be returned.
*
@@ -472,7 +460,7 @@ cupsGetDests2(http_t *http, /* I - HTTP connection */
*/
cups_dest_t * /* O - Destination or NULL */
-cupsGetNamedDest(http_t *http, /* I - HTTP connection or NULL */
+cupsGetNamedDest(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
const char *name, /* I - Destination name or NULL */
const char *instance) /* I - Instance name or NULL */
{
@@ -486,20 +474,6 @@ cupsGetNamedDest(http_t *http, /* I - HTTP connection or NULL */
/*
- * Connect to the server as needed...
- */
-
- if (!http)
- {
- if (!cg->http &&
- (cg->http = httpConnectEncrypt(cupsServer(), ippPort(),
- cupsEncryption())) == NULL)
- return (NULL);
-
- http = cg->http;
- }
-
- /*
* If "name" is NULL, find the default destination...
*/
@@ -634,7 +608,7 @@ cupsRemoveDest(const char *name, /* I - Destination name */
/*
- * 'cupsDestSetDefaultDest()' - Set the default destination.
+ * 'cupsSetDefaultDest()' - Set the default destination.
*
* @since CUPS 1.3@
*/
@@ -681,17 +655,7 @@ void
cupsSetDests(int num_dests, /* I - Number of destinations */
cups_dest_t *dests) /* I - Destinations */
{
- _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
-
-
- /*
- * Connect to the CUPS server and save the destination list and options...
- */
-
- if (!cg->http)
- cg->http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
-
- cupsSetDests2(cg->http, num_dests, dests);
+ cupsSetDests2(CUPS_HTTP_DEFAULT, num_dests, dests);
}
@@ -705,7 +669,7 @@ cupsSetDests(int num_dests, /* I - Number of destinations */
*/
int /* O - 0 on success, -1 on error */
-cupsSetDests2(http_t *http, /* I - HTTP connection */
+cupsSetDests2(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
int num_dests, /* I - Number of destinations */
cups_dest_t *dests) /* I - Destinations */
{
@@ -723,14 +687,14 @@ cupsSetDests2(http_t *http, /* I - HTTP connection */
cups_dest_t *temps, /* Temporary destinations */
*temp; /* Current temporary dest */
const char *val; /* Value of temporary option */
- _cups_globals_t *cg = _cupsGlobals(); /* Global data */
+ _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
/*
* Range check the input...
*/
- if (!http || !num_dests || !dests)
+ if (!num_dests || !dests)
return (-1);
/*
@@ -1155,7 +1119,7 @@ cups_get_dests(const char *filename, /* I - File to read from */
*/
static int /* O - Number of destinations */
-cups_get_sdests(http_t *http, /* I - HTTP connection */
+cups_get_sdests(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
ipp_op_t op, /* I - IPP operation */
const char *name, /* I - Name of destination */
int num_dests, /* I - Number of destinations */
diff --git a/cups/globals.h b/cups/globals.h
index ac3dd83df..b310461dd 100644
--- a/cups/globals.h
+++ b/cups/globals.h
@@ -124,6 +124,7 @@ typedef struct _cups_globals_s /**** CUPS global state data ****/
* Prototypes...
*/
+extern http_t *_cupsConnect(void);
extern const char *_cupsGetPassword(const char *prompt);
extern _cups_globals_t *_cupsGlobals(void);
extern void _cupsSetError(ipp_status_t status, const char *message);
diff --git a/cups/libcups.exp b/cups/libcups.exp
index b68dedf8f..f14668ef1 100644
--- a/cups/libcups.exp
+++ b/cups/libcups.exp
@@ -62,7 +62,9 @@ _cupsBackChannelRead
_cupsBackChannelWrite
_cupsBackendDeviceURI
_cupsCancelJob
+_cupsCancelJob2
_cupsCharsetToUTF8
+_cupsCreateJob
_cupsDirClose
_cupsDirOpen
_cupsDirRead
@@ -100,6 +102,7 @@ _cupsFileStdout
_cupsFileTell
_cupsFileUnlock
_cupsFileWrite
+_cupsFinishDocument
_cupsFreeDests
_cupsFreeJobs
_cupsFreeOptions
@@ -120,6 +123,7 @@ _cupsGetPPD
_cupsGetPPD2
_cupsGetPPD3
_cupsGetPrinters
+_cupsGetResponse
_cupsGetServerPPD
_cupsLangDefault
_cupsLangEncoding
@@ -138,8 +142,10 @@ _cupsPrintFiles
_cupsPrintFiles2
_cupsPutFd
_cupsPutFile
+_cupsReadResponseData
_cupsRemoveDest
_cupsRemoveOption
+_cupsSendRequest
_cupsServer
_cupsSetDefaultDest
_cupsSetDests
@@ -151,6 +157,7 @@ _cupsSetUser
_cupsSideChannelDoRequest
_cupsSideChannelRead
_cupsSideChannelWrite
+_cupsStartDocument
_cupsTempFd
_cupsTempFile
_cupsTempFile2
@@ -158,6 +165,7 @@ _cupsUser
_cupsUTF32ToUTF8
_cupsUTF8ToCharset
_cupsUTF8ToUTF32
+_cupsWriteRequestData
_httpAddrAny
_httpAddrConnect
_httpAddrEqual
diff --git a/cups/request.c b/cups/request.c
index 14741e95c..6544c3448 100644
--- a/cups/request.c
+++ b/cups/request.c
@@ -3,7 +3,7 @@
*
* IPP utilities for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -16,11 +16,15 @@
*
* Contents:
*
- * cupsDoFileRequest() - Do an IPP request with a file.
- * cupsDoIORequest() - Do an IPP request with file descriptors.
- * cupsDoRequest() - Do an IPP request.
- * _cupsSetError() - Set the last IPP status code and status-message.
- * _cupsSetHTTPError() - Set the last error using the HTTP status.
+ * cupsDoFileRequest() - Do an IPP request with a file.
+ * cupsDoIORequest() - Do an IPP request with file descriptors.
+ * cupsDoRequest() - Do an IPP request.
+ * cupsGetResponse() - Get a response to an IPP request.
+ * cupsReadResponseData() - Read additional data after the IPP response.
+ * cupsSendRequest() - Send an IPP request.
+ * cupsWriteRequestData() - Write additional data after an IPP request.
+ * _cupsSetError() - Set the last IPP status code and status-message.
+ * _cupsSetHTTPError() - Set the last error using the HTTP status.
*/
/*
@@ -52,7 +56,7 @@
*/
ipp_t * /* O - Response data */
-cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */
+cupsDoFileRequest(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
ipp_t *request, /* I - IPP request */
const char *resource, /* I - HTTP resource for POST */
const char *filename) /* I - File to send or NULL for none */
@@ -106,38 +110,45 @@ cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */
*/
ipp_t * /* O - Response data */
-cupsDoIORequest(http_t *http, /* I - HTTP connection to server */
+cupsDoIORequest(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
ipp_t *request, /* I - IPP request */
const char *resource, /* I - HTTP resource for POST */
int infile, /* I - File to read from or -1 for none */
int outfile) /* I - File to write to or -1 for none */
{
- ipp_t *response; /* IPP response data */
- size_t length; /* Content-Length value */
+ ipp_t *response = NULL; /* IPP response data */
+ size_t length = 0; /* Content-Length value */
http_status_t status; /* Status of HTTP request */
- int got_status; /* Did we get the status? */
- ipp_state_t state; /* State of IPP processing */
struct stat fileinfo; /* File information */
int bytes; /* Number of bytes read/written */
char buffer[32768]; /* Output buffer */
- http_status_t expect; /* Expect: header to use */
- DEBUG_printf(("cupsDoFileRequest(%p, %p, \'%s\', \'%s\')\n",
- http, request, resource ? resource : "(null)",
- filename ? filename : "(null)"));
+ DEBUG_printf(("cupsDoIORequest(http=%p, request=%p, resource=\"%s\""
+ "infile=%d, outfile=%d)\n", http, request,
+ resource ? resource : "(null)", infile, outfile));
+
+ /*
+ * Range check input...
+ */
- if (http == NULL || request == NULL || resource == NULL)
+ if (!request || !resource)
{
- if (request != NULL)
- ippDelete(request);
+ ippDelete(request);
- _cupsSetError(IPP_INTERNAL_ERROR, NULL);
+ _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL));
return (NULL);
}
/*
+ * Get the default connection as needed...
+ */
+
+ if (!http)
+ http = _cupsConnect();
+
+ /*
* See if we have a file to send...
*/
@@ -149,7 +160,7 @@ cupsDoIORequest(http_t *http, /* I - HTTP connection to server */
* Can't get file information!
*/
- _cupsSetError(errno == ENOENT ? IPP_NOT_FOUND : IPP_NOT_AUTHORIZED,
+ _cupsSetError(errno == EBADF ? IPP_NOT_FOUND : IPP_NOT_AUTHORIZED,
strerror(errno));
ippDelete(request);
@@ -173,8 +184,347 @@ cupsDoIORequest(http_t *http, /* I - HTTP connection to server */
return (NULL);
}
+
+#ifndef WIN32
+ if (!S_ISREG(fileinfo.st_mode))
+ length = 0; /* Chunk when piping */
+ else
+#endif /* !WIN32 */
+ length = ippLength(request) + fileinfo.st_size;
+ }
+ else
+ length = ippLength(request);
+
+ /*
+ * Loop until we can send the request without authorization problems.
+ */
+
+ while (response == NULL)
+ {
+ DEBUG_puts("cupsDoFileRequest: setup...");
+
+ /*
+ * Send the request...
+ */
+
+ status = cupsSendRequest(http, request, resource, length);
+
+ DEBUG_printf(("cupsDoFileRequest: status=%d\n", status));
+
+ if (status == HTTP_CONTINUE && request->state == IPP_DATA && infile >= 0)
+ {
+ DEBUG_puts("cupsDoFileRequest: file write...");
+
+ /*
+ * Send the file with the request...
+ */
+
+#ifndef WIN32
+ if (S_ISREG(fileinfo.st_mode))
+#endif /* WIN32 */
+ lseek(infile, 0, SEEK_SET);
+
+ while ((bytes = (int)read(infile, buffer, sizeof(buffer))) > 0)
+ {
+ if (httpCheck(http))
+ {
+ if ((status = httpUpdate(http)) != HTTP_CONTINUE)
+ break;
+ }
+
+ if (httpWrite2(http, buffer, bytes) < bytes)
+ break;
+ }
+ }
+
+ /*
+ * Get the server's response...
+ */
+
+ if (status == HTTP_CONTINUE || status == HTTP_OK)
+ {
+ response = cupsGetResponse(http, resource);
+ status = http->status;
+ }
+
+ if (response)
+ {
+ if (outfile >= 0)
+ {
+ /*
+ * Write trailing data to file...
+ */
+
+ while ((bytes = (int)httpRead2(http, buffer, sizeof(buffer))) > 0)
+ if (write(outfile, buffer, bytes) < bytes)
+ break;
+ }
+ else
+ {
+ /*
+ * Flush any remaining data...
+ */
+
+ httpFlush(http);
+ }
+ }
+ }
+
+ /*
+ * Delete the original request and return the response...
+ */
+
+ ippDelete(request);
+
+ return (response);
+}
+
+
+/*
+ * 'cupsDoRequest()' - Do an IPP request.
+ *
+ * This function sends the IPP request to the specified server, retrying
+ * and authenticating as necessary. The request is freed with ippDelete()
+ * after receiving a valid IPP response.
+ */
+
+ipp_t * /* O - Response data */
+cupsDoRequest(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+ ipp_t *request, /* I - IPP request */
+ const char *resource) /* I - HTTP resource for POST */
+{
+ return (cupsDoFileRequest(http, request, resource, NULL));
+}
+
+
+/*
+ * 'cupsGetResponse()' - Get a response to an IPP request.
+ *
+ * Use this function to get the response for an IPP request sent using
+ * cupsSendDocument() or cupsSendRequest(). For requests that return
+ * additional data, use httpRead() after getting a successful response.
+ *
+ * @since CUPS 1.4@
+ */
+
+ipp_t * /* O - Response or NULL on HTTP error */
+cupsGetResponse(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+ const char *resource) /* I - HTTP resource for POST */
+{
+ http_status_t status; /* HTTP status */
+ ipp_state_t state; /* IPP read state */
+ ipp_t *response = NULL; /* IPP response */
+
+
+ DEBUG_printf(("cupsGetReponse(http=%p)\n", http));
+
+ /*
+ * Connect to the default server as needed...
+ */
+
+ if (!http)
+ http = _cupsConnect();
+
+ if (!http || (http->state != HTTP_POST_RECV && http->state != HTTP_POST_SEND))
+ return (NULL);
+
+ /*
+ * Check for an unfinished chunked request...
+ */
+
+ if (http->data_encoding == HTTP_ENCODE_CHUNKED)
+ {
+ /*
+ * Send a 0-length chunk to finish off the request...
+ */
+
+ DEBUG_puts("cupsGetResponse: Finishing chunked POST...");
+
+ if (httpWrite2(http, "", 0) < 0)
+ return (NULL);
+ }
+
+ /*
+ * Wait for a response from the server...
+ */
+
+ DEBUG_puts("cupsGetResponse: update...");
+
+ while ((status = httpUpdate(http)) == HTTP_CONTINUE)
+ /* Do nothing but update */;
+
+ DEBUG_printf(("cupsGetResponse: status = %d\n", status));
+
+ if (status == HTTP_OK)
+ {
+ /*
+ * Get the IPP response...
+ */
+
+ response = ippNew();
+
+ while ((state = ippRead(http, response)) != IPP_DATA)
+ if (state == IPP_ERROR)
+ break;
+
+ if (state == IPP_ERROR)
+ {
+ /*
+ * Delete the response...
+ */
+
+ DEBUG_puts("IPP read error!");
+
+ ippDelete(response);
+ response = NULL;
+
+ _cupsSetError(IPP_SERVICE_UNAVAILABLE, strerror(errno));
+ }
+ }
+ else if (status != HTTP_ERROR)
+ {
+ /*
+ * Flush any error message...
+ */
+
+ httpFlush(http);
+
+ /*
+ * Then handle encryption and authentication...
+ */
+
+ if (status == HTTP_UNAUTHORIZED)
+ {
+ /*
+ * See if we can do authentication...
+ */
+
+ DEBUG_puts("cupsGetResponse: Need authorization...");
+
+ if (!cupsDoAuthentication(http, "POST", resource))
+ httpReconnect(http);
+ }
+
+#ifdef HAVE_SSL
+ else if (status == HTTP_UPGRADE_REQUIRED)
+ {
+ /*
+ * Force a reconnect with encryption...
+ */
+
+ DEBUG_puts("cupsGetResponse: Need encryption...");
+
+ if (!httpReconnect(http))
+ httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
+ }
+#endif /* HAVE_SSL */
+ }
+
+ if (response)
+ {
+ ipp_attribute_t *attr; /* status-message attribute */
+
+
+ attr = ippFindAttribute(response, "status-message", IPP_TAG_TEXT);
+
+ _cupsSetError(response->request.status.status_code,
+ attr ? attr->values[0].string.text :
+ ippErrorString(response->request.status.status_code));
+ }
+ else if (status != HTTP_OK)
+ _cupsSetHTTPError(status);
+
+ return (response);
+}
+
+
+/*
+ * 'cupsReadResponseData()' - Read additional data after the IPP response.
+ *
+ * This function is used after cupsGetResponse() to read the PPD or document
+ * files for CUPS_GET_PPD and CUPS_GET_DOCUMENT requests, respectively.
+ *
+ * @since CUPS 1.4@
+ */
+
+ssize_t /* O - Bytes read, 0 on EOF, -1 on error */
+cupsReadResponseData(
+ http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+ char *buffer, /* I - Buffer to use */
+ size_t length) /* I - Number of bytes to read */
+{
+ /*
+ * Get the default connection as needed...
+ */
+
+ if (!http)
+ {
+ _cups_globals_t *cg = _cupsGlobals();
+ /* Pointer to library globals */
+
+ if ((http = cg->http) == NULL)
+ {
+ _cupsSetError(IPP_INTERNAL_ERROR, "No active connection");
+ return (-1);
+ }
}
+ /*
+ * Then read from the HTTP connection...
+ */
+
+ return (httpRead2(http, buffer, length));
+}
+
+
+/*
+ * 'cupsSendRequest()' - Send an IPP request.
+ *
+ * Use httpWrite() to write any additional data (document, PPD file, etc.)
+ * for the request, cupsGetResponse() to get the IPP response, and httpRead()
+ * to read any additional data following the response. Only one request can be
+ * sent/queued at a time.
+ *
+ * Unlike cupsDoFileRequest(), cupsDoIORequest(), and cupsDoRequest(), the
+ * request is not freed.
+ *
+ * @since CUPS 1.4@
+ */
+
+http_status_t /* O - Initial HTTP status */
+cupsSendRequest(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+ ipp_t *request, /* I - IPP request */
+ const char *resource, /* I - Resource path */
+ size_t length) /* I - Length of data to follow or CUPS_LENGTH_VARIABLE */
+{
+ http_status_t status; /* Status of HTTP request */
+ int got_status; /* Did we get the status? */
+ ipp_state_t state; /* State of IPP processing */
+ http_status_t expect; /* Expect: header to use */
+
+
+ DEBUG_printf(("cupsSendRequest(http=%p, request=%p, resource=\"%s\", "
+ "length=" CUPS_LLFMT ")\n", http, request,
+ resource ? resource : "(null)", CUPS_LLCAST length));
+
+ /*
+ * Range check input...
+ */
+
+ if (!request || !resource)
+ {
+ _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL));
+
+ return (HTTP_ERROR);
+ }
+
+ /*
+ * Get the default connection as needed...
+ */
+
+ if (!http)
+ http = _cupsConnect();
+
#ifdef HAVE_SSL
/*
* See if we have an auth-info attribute and are communicating over
@@ -185,57 +535,42 @@ cupsDoIORequest(http_t *http, /* I - HTTP connection to server */
if (ippFindAttribute(request, "auth-info", IPP_TAG_TEXT) &&
!httpAddrLocalhost(http->hostaddr) && !http->tls &&
httpEncryption(http, HTTP_ENCRYPT_REQUIRED))
- return (NULL);
+ return (HTTP_ERROR);
#endif /* HAVE_SSL */
/*
* Loop until we can send the request without authorization problems.
*/
- response = NULL;
- status = HTTP_ERROR;
- expect = HTTP_CONTINUE;
+ status = HTTP_ERROR;
+ expect = HTTP_CONTINUE;
- while (response == NULL)
+ for (;;)
{
- DEBUG_puts("cupsDoFileRequest: setup...");
+ DEBUG_puts("cupsSendRequest: setup...");
/*
* Setup the HTTP variables needed...
*/
- length = ippLength(request);
- if (infile >= 0)
- {
-#ifndef WIN32
- if (!S_ISREG(fileinfo.st_mode))
- length = 0; /* Chunk when piping */
- else
-#endif /* !WIN32 */
- length += fileinfo.st_size;
- }
-
httpClearFields(http);
httpSetLength(http, length);
httpSetField(http, HTTP_FIELD_CONTENT_TYPE, "application/ipp");
httpSetField(http, HTTP_FIELD_AUTHORIZATION, http->authstring);
httpSetExpect(http, expect);
- DEBUG_printf(("cupsDoFileRequest: authstring=\"%s\"\n", http->authstring));
+ DEBUG_printf(("cupsSendRequest: authstring=\"%s\"\n", http->authstring));
/*
* Try the request...
*/
- DEBUG_puts("cupsDoFileRequest: post...");
+ DEBUG_puts("cupsSendRequest: post...");
if (httpPost(http, resource))
{
if (httpReconnect(http))
- {
- status = HTTP_ERROR;
- break;
- }
+ return (HTTP_ERROR);
else
continue;
}
@@ -244,7 +579,7 @@ cupsDoIORequest(http_t *http, /* I - HTTP connection to server */
* Send the IPP data...
*/
- DEBUG_puts("cupsDoFileRequest: ipp write...");
+ DEBUG_puts("cupsSendRequest: ipp write...");
request->state = IPP_IDLE;
status = HTTP_CONTINUE;
@@ -261,222 +596,115 @@ cupsDoIORequest(http_t *http, /* I - HTTP connection to server */
break;
}
- if (!got_status)
- {
- /*
- * Wait up to 1 second to get the 100-continue response...
- */
+ /*
+ * Wait up to 1 second to get the 100-continue response as needed...
+ */
+ if (!got_status && expect == HTTP_CONTINUE)
+ {
if (httpWait(http, 1000))
status = httpUpdate(http);
}
else if (httpCheck(http))
status = httpUpdate(http);
- if (status == HTTP_CONTINUE && state == IPP_DATA && infile >= 0)
- {
- DEBUG_puts("cupsDoFileRequest: file write...");
-
- /*
- * Send the file...
- */
-
-#ifndef WIN32
- if (S_ISREG(fileinfo.st_mode))
-#endif /* WIN32 */
- lseek(infile, 0, SEEK_SET);
-
- while ((bytes = (int)read(infile, buffer, sizeof(buffer))) > 0)
- {
- if (httpCheck(http))
- {
- if ((status = httpUpdate(http)) != HTTP_CONTINUE)
- break;
- }
-
- if (httpWrite2(http, buffer, bytes) < bytes)
- break;
- }
- }
-
/*
- * Get the server's return status...
+ * Process the current HTTP status...
*/
- DEBUG_puts("cupsDoFileRequest: update...");
-
- while (status == HTTP_CONTINUE)
- status = httpUpdate(http);
-
- DEBUG_printf(("cupsDoFileRequest: status = %d\n", status));
-
- if (status == HTTP_UNAUTHORIZED)
+ switch (status)
{
- DEBUG_puts("cupsDoFileRequest: unauthorized...");
-
- /*
- * Flush any error message...
- */
-
- httpFlush(http);
-
- /*
- * See if we can do authentication...
- */
-
- if (cupsDoAuthentication(http, "POST", resource))
- break;
+ case HTTP_ERROR :
+ case HTTP_CONTINUE :
+ case HTTP_OK :
+ return (status);
- if (httpReconnect(http))
- {
- status = HTTP_ERROR;
- break;
- }
+ case HTTP_UNAUTHORIZED :
+ if (!cupsDoAuthentication(http, "POST", resource))
+ if (httpReconnect(http))
+ return (HTTP_ERROR);
- continue;
- }
- else if (status == HTTP_ERROR)
- {
- DEBUG_printf(("cupsDoFileRequest: http->error=%d (%s)\n", http->error,
- strerror(http->error)));
+ return (status);
-#ifdef WIN32
- if (http->error != WSAENETDOWN && http->error != WSAENETUNREACH &&
- http->error != WSAETIMEDOUT)
-#else
- if (http->error != ENETDOWN && http->error != ENETUNREACH &&
- http->error != ETIMEDOUT)
-#endif /* WIN32 */
- continue;
- else
- break;
- }
#ifdef HAVE_SSL
- else if (status == HTTP_UPGRADE_REQUIRED)
- {
- /* Flush any error message... */
- httpFlush(http);
+ case HTTP_UPGRADE_REQUIRED :
+ /*
+ * Flush any error message, reconnect, and then upgrade with
+ * encryption...
+ */
- /* Reconnect... */
- if (httpReconnect(http))
- {
- status = HTTP_ERROR;
- break;
- }
+ if (httpReconnect(http))
+ return (HTTP_ERROR);
- /* Upgrade with encryption... */
- httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
+ httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
- /* Try again, this time with encryption enabled... */
- continue;
- }
+ return (status);
#endif /* HAVE_SSL */
- else if (status == HTTP_EXPECTATION_FAILED)
- {
- /*
- * Don't try using the Expect: header the next time around...
- */
- expect = (http_status_t)0;
- }
- else if (status != HTTP_OK)
- {
- DEBUG_printf(("cupsDoFileRequest: error %d...\n", status));
+ case HTTP_EXPECTATION_FAILED :
+ /*
+ * Don't try using the Expect: header the next time around...
+ */
- /*
- * Flush any error message...
- */
+ expect = (http_status_t)0;
- httpFlush(http);
- break;
- }
- else
- {
- /*
- * Read the response...
- */
-
- DEBUG_puts("cupsDoFileRequest: response...");
-
- response = ippNew();
-
- while ((state = ippRead(http, response)) != IPP_DATA)
- if (state == IPP_ERROR)
- break;
-
- if (state == IPP_ERROR)
- {
- /*
- * Delete the response...
- */
-
- DEBUG_puts("IPP read error!");
- ippDelete(response);
- response = NULL;
-
- _cupsSetError(IPP_SERVICE_UNAVAILABLE, strerror(errno));
-
- break;
- }
- else if (outfile >= 0)
- {
- /*
- * Write trailing data to file...
- */
-
- while ((bytes = (int)httpRead2(http, buffer, sizeof(buffer))) > 0)
- if (write(outfile, buffer, bytes) < bytes)
- break;
- }
- else
- {
- /*
- * Flush any remaining data...
- */
+ default :
+ /*
+ * Some other error...
+ */
- httpFlush(http);
- }
+ return (status);
}
}
+}
+
+
+/*
+ * 'cupsWriteRequestData()' - Write additional data after an IPP request.
+ *
+ * This function is used after cupsSendRequest() or cupsStartDocument()
+ * to provide a PPD or document file as needed.
+ *
+ * @since CUPS 1.4@
+ */
+http_status_t /* O - HTTP_CONTINUE if OK or HTTP status on error */
+cupsWriteRequestData(
+ http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+ const char *buffer, /* I - Bytes to write */
+ size_t length) /* I - Number of bytes to write */
+{
/*
- * Delete the original request and return the response...
+ * Get the default connection as needed...
*/
-
- ippDelete(request);
- if (response)
+ if (!http)
{
- ipp_attribute_t *attr; /* status-message attribute */
-
+ _cups_globals_t *cg = _cupsGlobals();
+ /* Pointer to library globals */
- attr = ippFindAttribute(response, "status-message", IPP_TAG_TEXT);
-
- _cupsSetError(response->request.status.status_code,
- attr ? attr->values[0].string.text :
- ippErrorString(response->request.status.status_code));
+ if ((http = cg->http) == NULL)
+ {
+ _cupsSetError(IPP_INTERNAL_ERROR, "No active connection");
+ return (HTTP_ERROR);
+ }
}
- else if (status != HTTP_OK)
- _cupsSetHTTPError(status);
- return (response);
-}
+ /*
+ * Then write to the HTTP connection...
+ */
+ if (httpWrite2(http, buffer, length) < 0)
+ return (HTTP_ERROR);
-/*
- * 'cupsDoRequest()' - Do an IPP request.
- *
- * This function sends the IPP request to the specified server, retrying
- * and authenticating as necessary. The request is freed with ippDelete()
- * after receiving a valid IPP response.
- */
+ /*
+ * Finally, check if we have any pending data from the server...
+ */
-ipp_t * /* O - Response data */
-cupsDoRequest(http_t *http, /* I - HTTP connection to server */
- ipp_t *request, /* I - IPP request */
- const char *resource) /* I - HTTP resource for POST */
-{
- return (cupsDoFileRequest(http, request, resource, NULL));
+ if (httpCheck(http))
+ return (httpUpdate(http));
+ else
+ return (HTTP_CONTINUE);
}
diff --git a/cups/util.c b/cups/util.c
index 142c70a7a..33ba35053 100644
--- a/cups/util.c
+++ b/cups/util.c
@@ -3,7 +3,7 @@
*
* Printing utilities for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2006 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
@@ -17,18 +17,21 @@
* Contents:
*
* cupsCancelJob() - Cancel a print job on the default server.
+ * cupsCancelJob2() - Cancel or purge a print job.
+ * cupsCreateJob() - Create an empty job.
+ * cupsFinishDocument() - Finish sending a document.
* cupsFreeJobs() - Free memory used by job data.
* cupsGetClasses() - Get a list of printer classes from the default
* server.
- * cupsGetDefault() - Get the default printer or class from the default
+ * cupsGetDefault() - Get the default printer or class for the default
+ * server.
+ * cupsGetDefault2() - Get the default printer or class for the specified
* server.
- * cupsGetDefault2() - Get the default printer or class from the
- * specified server.
* cupsGetJobs() - Get the jobs from the default server.
* cupsGetJobs2() - Get the jobs from the specified server.
* cupsGetPPD() - Get the PPD file for a printer on the default
* server.
- * cupsGetPPD2() - Get the PPD file for a printer on the specified
+ * cupsGetPPD2() - Get the PPD file for a printer from the specified
* server.
* cupsGetPPD3() - Get the PPD file for a printer on the specified
* server if it has changed.
@@ -44,7 +47,9 @@
* the default server.
* cupsPrintFiles2() - Print one or more files to a printer or class on
* the specified server.
- * cups_connect() - Connect to the specified host...
+ * cupsStartDocument() - Add a document to a job created with
+ * cupsCreateJob().
+ * _cupsConnect() - Get the default server connection...
* cups_get_printer_uri() - Get the printer-uri-supported attribute for the
* first printer in a class.
*/
@@ -70,7 +75,6 @@
* Local functions...
*/
-static char *cups_connect(const char *name, char *printer, char *hostname);
static int cups_get_printer_uri(http_t *http, const char *name,
char *host, int hostsize, int *port,
char *resource, int resourcesize,
@@ -86,38 +90,51 @@ static int cups_get_printer_uri(http_t *http, const char *name,
int /* O - 1 on success, 0 on failure */
cupsCancelJob(const char *name, /* I - Name of printer or class */
- int job) /* I - Job ID */
+ int job_id) /* I - Job ID */
{
- char printer[HTTP_MAX_URI], /* Printer name */
- hostname[HTTP_MAX_URI], /* Hostname */
- uri[HTTP_MAX_URI]; /* Printer URI */
- ipp_t *request, /* IPP request */
- *response; /* IPP response */
- _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
+ return (cupsCancelJob2(CUPS_HTTP_DEFAULT, job_id, 0)
+ < IPP_REDIRECTION_OTHER_SITE);
+}
+
+
+/*
+ * 'cupsCancelJob2()' - Cancel or purge a print job.
+ *
+ * Canceled jobs remain in the job history while purged jobs are removed
+ * from the job history.
+ *
+ * Use the cupsLastError() and cupsLastErrorString() functions to get
+ * the cause of any failure.
+ *
+ * @since CUPS 1.4@
+ */
+
+ipp_status_t /* O - IPP status */
+cupsCancelJob2(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+ int job_id, /* I - Job ID */
+ int purge) /* I - 1 to purge, 0 to cancel */
+{
+ char uri[HTTP_MAX_URI]; /* Job URI */
+ ipp_t *request; /* IPP request */
/*
- * See if we can connect to the server...
+ * Range check input...
*/
- if (!cups_connect(name, printer, hostname))
+ if (job_id <= 0)
{
- DEBUG_puts("Unable to connect to server!");
-
+ _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL));
return (0);
}
/*
- * Create a printer URI...
+ * Connect to the default server as needed...
*/
- if (httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
- "localhost", 0, "/printers/%s", printer) != HTTP_URI_OK)
- {
- _cupsSetError(IPP_INTERNAL_ERROR, NULL);
-
- return (0);
- }
+ if (!http)
+ if ((http = _cupsConnect()) == NULL)
+ return (IPP_SERVICE_UNAVAILABLE);
/*
* Build an IPP_CANCEL_JOB request, which requires the following
@@ -125,29 +142,130 @@ cupsCancelJob(const char *name, /* I - Name of printer or class */
*
* attributes-charset
* attributes-natural-language
- * printer-uri
- * job-id
- * [requesting-user-name]
+ * job-uri
+ * requesting-user-name
+ * [purge-job]
*/
request = ippNewRequest(IPP_CANCEL_JOB);
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
- NULL, uri);
-
- ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job);
+ snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", job_id);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
NULL, cupsUser());
+ if (purge)
+ ippAddBoolean(request, IPP_TAG_OPERATION, "purge-job", 1);
/*
* Do the request...
*/
- if ((response = cupsDoRequest(cg->http, request, "/jobs/")) != NULL)
- ippDelete(response);
+ ippDelete(cupsDoRequest(http, request, "/jobs/"));
+
+ return (cupsLastError());
+}
+
+
+/*
+ * 'cupsCreateJob()' - Create an empty job.
+ *
+ * Submit files for printing to the job using the cupsStartDocument(),
+ * cupsWriteRequestData(), and cupsFinishDocument() functions.
+ *
+ * @since CUPS 1.4@
+ */
+
+int /* O - Job ID or 0 on error */
+cupsCreateJob(
+ http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+ const char *name, /* I - Printer or class name */
+ const char *title, /* I - Title of job */
+ int num_options, /* I - Number of options */
+ cups_option_t *options) /* I - Options */
+{
+ char printer_uri[1024], /* Printer URI */
+ resource[1024]; /* Printer resource */
+ ipp_t *request, /* Create-Job request */
+ *response; /* Create-Job response */
+ ipp_attribute_t *attr; /* job-id attribute */
+ int job_id = 0; /* job-id value */
+
+
+ DEBUG_printf(("cupsCreateJob(http=%p, name=\"%s\", title=\"%s\", "
+ "num_options=%d, options=%p)\n",
+ http, name, title, num_options, options));
+
+ /*
+ * Range check input...
+ */
+
+ if (!name)
+ {
+ _cupsSetError(IPP_INTERNAL_ERROR, NULL);
+ return (0);
+ }
+
+ /*
+ * Build a Create-Job request...
+ */
+
+ if ((request = ippNewRequest(IPP_CREATE_JOB)) == NULL)
+ {
+ _cupsSetError(IPP_INTERNAL_ERROR, NULL);
+ return (0);
+ }
+
+ httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), "ipp",
+ NULL, "localhost", ippPort(), "/printers/%s", name);
+ snprintf(resource, sizeof(resource), "/printers/%s", name);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, printer_uri);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, cupsUser());
+ if (title)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL,
+ title);
+ cupsEncodeOptions(request, num_options, options);
+
+ /*
+ * Send the request and get the job-id...
+ */
+
+ response = cupsDoRequest(http, request, resource);
+
+ if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) != NULL)
+ job_id = attr->values[0].integer;
- return (cg->last_error < IPP_REDIRECTION_OTHER_SITE);
+ ippDelete(response);
+
+ /*
+ * Return it...
+ */
+
+ return (job_id);
+}
+
+
+/*
+ * 'cupsFinishDocument()' - Finish sending a document.
+ *
+ * @since CUPS 1.4@
+ */
+
+ipp_status_t /* O - Status of document submission */
+cupsFinishDocument(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+ const char *name) /* I - Printer or class name */
+{
+ char resource[1024]; /* Printer resource */
+
+
+ snprintf(resource, sizeof(resource), "/printers/%s", name);
+
+ ippDelete(cupsGetResponse(http, resource));
+
+ return (cupsLastError());
}
@@ -159,18 +277,19 @@ void
cupsFreeJobs(int num_jobs, /* I - Number of jobs */
cups_job_t *jobs) /* I - Jobs */
{
- int i; /* Looping var */
+ int i; /* Looping var */
+ cups_job_t *job; /* Current job */
- if (num_jobs <= 0 || jobs == NULL)
+ if (num_jobs <= 0 || !jobs)
return;
- for (i = 0; i < num_jobs; i ++)
+ for (i = num_jobs, job = jobs; i > 0; i --, job ++)
{
- free(jobs[i].dest);
- free(jobs[i].user);
- free(jobs[i].format);
- free(jobs[i].title);
+ _cupsStrFree(job->dest);
+ _cupsStrFree(job->user);
+ _cupsStrFree(job->format);
+ _cupsStrFree(job->title);
}
free(jobs);
@@ -193,26 +312,20 @@ cupsGetClasses(char ***classes) /* O - Classes */
*response; /* IPP Response */
ipp_attribute_t *attr; /* Current attribute */
char **temp; /* Temporary pointer */
- _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
+ http_t *http; /* Connection to server */
- if (classes == NULL)
+ if (!classes)
{
_cupsSetError(IPP_INTERNAL_ERROR, NULL);
return (0);
}
- /*
- * Try to connect to the server...
- */
-
- if (!cups_connect("default", NULL, NULL))
- {
- DEBUG_puts("Unable to connect to server!");
+ *classes = NULL;
+ if ((http = _cupsConnect()) == NULL)
return (0);
- }
/*
* Build a CUPS_GET_CLASSES request, which requires the following
@@ -232,10 +345,9 @@ cupsGetClasses(char ***classes) /* O - Classes */
* Do the request and get back a response...
*/
- n = 0;
- *classes = NULL;
+ n = 0;
- if ((response = cupsDoRequest(cg->http, request, "/")) != NULL)
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
{
for (attr = response->attrs; attr != NULL; attr = attr->next)
if (attr->name != NULL &&
@@ -290,38 +402,11 @@ cupsGetClasses(char ***classes) /* O - Classes */
const char * /* O - Default printer or NULL */
cupsGetDefault(void)
{
- const char *var; /* Environment variable */
- _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
-
-
- /*
- * First see if the LPDEST or PRINTER environment variables are
- * set... However, if PRINTER is set to "lp", ignore it to work
- * around a "feature" in most Linux distributions - the default
- * user login scripts set PRINTER to "lp"...
- */
-
- if ((var = getenv("LPDEST")) != NULL)
- return (var);
- else if ((var = getenv("PRINTER")) != NULL && strcmp(var, "lp") != 0)
- return (var);
-
- /*
- * Try to connect to the server...
- */
-
- if (!cups_connect("default", NULL, NULL))
- {
- DEBUG_puts("Unable to connect to server!");
-
- return (NULL);
- }
-
/*
* Return the default printer...
*/
- return (cupsGetDefault2(cg->http));
+ return (cupsGetDefault2(CUPS_HTTP_DEFAULT));
}
@@ -361,11 +446,12 @@ cupsGetDefault2(http_t *http) /* I - HTTP connection */
return (var);
/*
- * Range check input...
+ * Connect to the server as needed...
*/
if (!http)
- return (NULL);
+ if ((http = _cupsConnect()) == NULL)
+ return (NULL);
/*
* Build a CUPS_GET_DEFAULT request, which requires the following
@@ -383,9 +469,11 @@ cupsGetDefault2(http_t *http) /* I - HTTP connection */
if ((response = cupsDoRequest(http, request, "/")) != NULL)
{
- if ((attr = ippFindAttribute(response, "printer-name", IPP_TAG_NAME)) != NULL)
+ if ((attr = ippFindAttribute(response, "printer-name",
+ IPP_TAG_NAME)) != NULL)
{
- strlcpy(cg->def_printer, attr->values[0].string.text, sizeof(cg->def_printer));
+ strlcpy(cg->def_printer, attr->values[0].string.text,
+ sizeof(cg->def_printer));
ippDelete(response);
return (cg->def_printer);
}
@@ -409,24 +497,11 @@ cupsGetJobs(cups_job_t **jobs, /* O - Job data */
int completed) /* I - -1 = show all, 0 = active, *
* 1 = completed jobs */
{
- _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
-
- /*
- * Try to connect to the server...
- */
-
- if (!cups_connect("default", NULL, NULL))
- {
- DEBUG_puts("Unable to connect to server!");
-
- return (-1);
- }
-
/*
* Return the jobs...
*/
- return (cupsGetJobs2(cg->http, jobs, mydest, myjobs, completed));
+ return (cupsGetJobs2(CUPS_HTTP_DEFAULT, jobs, mydest, myjobs, completed));
}
@@ -438,7 +513,7 @@ cupsGetJobs(cups_job_t **jobs, /* O - Job data */
*/
int /* O - Number of jobs */
-cupsGetJobs2(http_t *http, /* I - HTTP connection */
+cupsGetJobs2(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
cups_job_t **jobs, /* O - Job data */
const char *mydest, /* I - NULL = all destinations, *
* otherwise show jobs for mydest */
@@ -484,7 +559,7 @@ cupsGetJobs2(http_t *http, /* I - HTTP connection */
* Range check input...
*/
- if (!http || !jobs)
+ if (!jobs)
{
_cupsSetError(IPP_INTERNAL_ERROR, NULL);
@@ -508,6 +583,9 @@ cupsGetJobs2(http_t *http, /* I - HTTP connection */
else
strcpy(uri, "ipp://localhost/jobs");
+ if (!http)
+ if ((http = _cupsConnect()) == NULL)
+ return (-1);
/*
* Build an IPP_GET_JOBS request, which requires the following
@@ -553,16 +631,16 @@ cupsGetJobs2(http_t *http, /* I - HTTP connection */
if ((response = cupsDoRequest(http, request, "/")) != NULL)
{
- for (attr = response->attrs; attr != NULL; attr = attr->next)
+ for (attr = response->attrs; attr; attr = attr->next)
{
/*
* Skip leading attributes until we hit a job...
*/
- while (attr != NULL && attr->group_tag != IPP_TAG_JOB)
+ while (attr && attr->group_tag != IPP_TAG_JOB)
attr = attr->next;
- if (attr == NULL)
+ if (!attr)
break;
/*
@@ -581,42 +659,42 @@ cupsGetJobs2(http_t *http, /* I - HTTP connection */
completed_time = 0;
processing_time = 0;
- while (attr != NULL && attr->group_tag == IPP_TAG_JOB)
+ while (attr && attr->group_tag == IPP_TAG_JOB)
{
- if (strcmp(attr->name, "job-id") == 0 &&
+ if (!strcmp(attr->name, "job-id") &&
attr->value_tag == IPP_TAG_INTEGER)
id = attr->values[0].integer;
- else if (strcmp(attr->name, "job-state") == 0 &&
+ else if (!strcmp(attr->name, "job-state") &&
attr->value_tag == IPP_TAG_ENUM)
state = (ipp_jstate_t)attr->values[0].integer;
- else if (strcmp(attr->name, "job-priority") == 0 &&
+ else if (!strcmp(attr->name, "job-priority") &&
attr->value_tag == IPP_TAG_INTEGER)
priority = attr->values[0].integer;
- else if (strcmp(attr->name, "job-k-octets") == 0 &&
+ else if (!strcmp(attr->name, "job-k-octets") &&
attr->value_tag == IPP_TAG_INTEGER)
size = attr->values[0].integer;
- else if (strcmp(attr->name, "time-at-completed") == 0 &&
+ else if (!strcmp(attr->name, "time-at-completed") &&
attr->value_tag == IPP_TAG_INTEGER)
completed_time = attr->values[0].integer;
- else if (strcmp(attr->name, "time-at-creation") == 0 &&
+ else if (!strcmp(attr->name, "time-at-creation") &&
attr->value_tag == IPP_TAG_INTEGER)
creation_time = attr->values[0].integer;
- else if (strcmp(attr->name, "time-at-processing") == 0 &&
+ else if (!strcmp(attr->name, "time-at-processing") &&
attr->value_tag == IPP_TAG_INTEGER)
processing_time = attr->values[0].integer;
- else if (strcmp(attr->name, "job-printer-uri") == 0 &&
+ else if (!strcmp(attr->name, "job-printer-uri") &&
attr->value_tag == IPP_TAG_URI)
{
if ((dest = strrchr(attr->values[0].string.text, '/')) != NULL)
dest ++;
}
- else if (strcmp(attr->name, "job-originating-user-name") == 0 &&
+ else if (!strcmp(attr->name, "job-originating-user-name") &&
attr->value_tag == IPP_TAG_NAME)
user = attr->values[0].string.text;
- else if (strcmp(attr->name, "document-format") == 0 &&
+ else if (!strcmp(attr->name, "document-format") &&
attr->value_tag == IPP_TAG_MIMETYPE)
format = attr->values[0].string.text;
- else if (strcmp(attr->name, "job-name") == 0 &&
+ else if (!strcmp(attr->name, "job-name") &&
(attr->value_tag == IPP_TAG_TEXT ||
attr->value_tag == IPP_TAG_NAME))
title = attr->values[0].string.text;
@@ -628,9 +706,9 @@ cupsGetJobs2(http_t *http, /* I - HTTP connection */
* See if we have everything needed...
*/
- if (dest == NULL || id == 0)
+ if (!dest || !id)
{
- if (attr == NULL)
+ if (!attr)
break;
else
continue;
@@ -645,17 +723,20 @@ cupsGetJobs2(http_t *http, /* I - HTTP connection */
else
temp = realloc(*jobs, sizeof(cups_job_t) * (n + 1));
- if (temp == NULL)
+ if (!temp)
{
/*
* Ran out of memory!
*/
+ _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno));
+
cupsFreeJobs(n, *jobs);
*jobs = NULL;
ippDelete(response);
- return (0);
+
+ return (-1);
}
*jobs = temp;
@@ -666,10 +747,10 @@ cupsGetJobs2(http_t *http, /* I - HTTP connection */
* Copy the data over...
*/
- temp->dest = strdup(dest);
- temp->user = strdup(user);
- temp->format = strdup(format);
- temp->title = strdup(title);
+ temp->dest = _cupsStrAlloc(dest);
+ temp->user = _cupsStrAlloc(user);
+ temp->format = _cupsStrAlloc(format);
+ temp->title = _cupsStrAlloc(title);
temp->id = id;
temp->priority = priority;
temp->state = state;
@@ -678,7 +759,7 @@ cupsGetJobs2(http_t *http, /* I - HTTP connection */
temp->creation_time = creation_time;
temp->processing_time = processing_time;
- if (attr == NULL)
+ if (!attr)
break;
}
@@ -707,23 +788,12 @@ cupsGetPPD(const char *name) /* I - Printer name */
/*
- * See if we can connect to the server...
- */
-
- if (!cups_connect(name, NULL, NULL))
- {
- DEBUG_puts("Unable to connect to server!");
-
- return (NULL);
- }
-
- /*
* Return the PPD file...
*/
cg->ppd_filename[0] = '\0';
- if (cupsGetPPD3(cg->http, name, &modtime, cg->ppd_filename,
+ if (cupsGetPPD3(CUPS_HTTP_DEFAULT, name, &modtime, cg->ppd_filename,
sizeof(cg->ppd_filename)) == HTTP_OK)
return (cg->ppd_filename);
else
@@ -741,7 +811,7 @@ cupsGetPPD(const char *name) /* I - Printer name */
*/
const char * /* O - Filename for PPD file */
-cupsGetPPD2(http_t *http, /* I - HTTP connection */
+cupsGetPPD2(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
const char *name) /* I - Printer name */
{
_cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
@@ -775,7 +845,7 @@ cupsGetPPD2(http_t *http, /* I - HTTP connection */
*/
http_status_t /* O - HTTP status */
-cupsGetPPD3(http_t *http, /* I - HTTP connection */
+cupsGetPPD3(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
const char *name, /* I - Printer name */
time_t *modtime, /* IO - Modification time */
char *buffer, /* I - Filename buffer */
@@ -802,12 +872,6 @@ cupsGetPPD3(http_t *http, /* I - HTTP connection */
"bufsize=%d)\n", http, name ? name : "(null)", modtime,
modtime ? *modtime : 0, buffer, (int)bufsize));
- if (!http)
- {
- _cupsSetError(IPP_INTERNAL_ERROR, "No HTTP connection!");
- return (HTTP_NOT_ACCEPTABLE);
- }
-
if (!name)
{
_cupsSetError(IPP_INTERNAL_ERROR, "No printer name!");
@@ -830,6 +894,9 @@ cupsGetPPD3(http_t *http, /* I - HTTP connection */
* Try finding a printer URI for this printer...
*/
+ if (!http)
+ http = _cupsConnect();
+
if (!cups_get_printer_uri(http, name, hostname, sizeof(hostname), &port,
resource, sizeof(resource), 0))
return (HTTP_NOT_FOUND);
@@ -972,26 +1039,28 @@ cupsGetPrinters(char ***printers) /* O - Printers */
*response; /* IPP Response */
ipp_attribute_t *attr; /* Current attribute */
char **temp; /* Temporary pointer */
- _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
+ http_t *http; /* Connection to server */
+
+ /*
+ * Range check input...
+ */
- if (printers == NULL)
+ if (!printers)
{
_cupsSetError(IPP_INTERNAL_ERROR, NULL);
return (0);
}
+ *printers = NULL;
+
/*
* Try to connect to the server...
*/
- if (!cups_connect("default", NULL, NULL))
- {
- DEBUG_puts("Unable to connect to server!");
-
+ if ((http = _cupsConnect()) == NULL)
return (0);
- }
/*
* Build a CUPS_GET_PRINTERS request, which requires the following
@@ -1017,10 +1086,9 @@ cupsGetPrinters(char ***printers) /* O - Printers */
* Do the request and get back a response...
*/
- n = 0;
- *printers = NULL;
+ n = 0;
- if ((response = cupsDoRequest(cg->http, request, "/")) != NULL)
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
{
for (attr = response->attrs; attr != NULL; attr = attr->next)
if (attr->name != NULL &&
@@ -1077,7 +1145,7 @@ cupsGetPrinters(char ***printers) /* O - Printers */
*/
char * /* O - Name of PPD file or NULL on error */
-cupsGetServerPPD(http_t *http, /* I - HTTP connection */
+cupsGetServerPPD(http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
const char *name) /* I - Name of PPD file ("ppd-name") */
{
int fd; /* PPD file descriptor */
@@ -1090,16 +1158,17 @@ cupsGetServerPPD(http_t *http, /* I - HTTP connection */
* Range check input...
*/
- if (!http || !name)
+ if (!name)
{
- if (!http)
- _cupsSetError(IPP_INTERNAL_ERROR, "No HTTP connection!");
- else
- _cupsSetError(IPP_INTERNAL_ERROR, "No PPD name!");
+ _cupsSetError(IPP_INTERNAL_ERROR, "No PPD name!");
return (NULL);
}
+ if (!http)
+ if ((http = _cupsConnect()) == NULL)
+ return (NULL);
+
/*
* Get a temp file...
*/
@@ -1176,7 +1245,8 @@ cupsPrintFile(const char *name, /* I - Printer or class name */
"title=\"%s\", num_options=%d, options=%p)\n",
name, filename, title, num_options, options));
- return (cupsPrintFiles(name, 1, &filename, title, num_options, options));
+ return (cupsPrintFiles2(CUPS_HTTP_DEFAULT, name, 1, &filename, title,
+ num_options, options));
}
@@ -1187,19 +1257,20 @@ cupsPrintFile(const char *name, /* I - Printer or class name */
*/
int /* O - Job ID */
-cupsPrintFile2(http_t *http, /* I - HTTP connection */
- const char *name, /* I - Printer or class name */
- const char *filename, /* I - File to print */
- const char *title, /* I - Title of job */
- int num_options,
- /* I - Number of options */
- cups_option_t *options) /* I - Options */
+cupsPrintFile2(
+ http_t *http, /* I - HTTP connection */
+ const char *name, /* I - Printer or class name */
+ const char *filename, /* I - File to print */
+ const char *title, /* I - Title of job */
+ int num_options, /* I - Number of options */
+ cups_option_t *options) /* I - Options */
{
DEBUG_printf(("cupsPrintFile2(http=%p, name=\"%s\", filename=\"%s\", "
"title=\"%s\", num_options=%d, options=%p)\n",
http, name, filename, title, num_options, options));
- return (cupsPrintFiles2(http, name, 1, &filename, title, num_options, options));
+ return (cupsPrintFiles2(http, name, 1, &filename, title, num_options,
+ options));
}
@@ -1209,44 +1280,28 @@ cupsPrintFile2(http_t *http, /* I - HTTP connection */
*/
int /* O - Job ID */
-cupsPrintFiles(const char *name, /* I - Printer or class name */
- int num_files, /* I - Number of files */
- const char **files, /* I - File(s) to print */
- const char *title, /* I - Title of job */
- int num_options,
- /* I - Number of options */
- cups_option_t *options) /* I - Options */
+cupsPrintFiles(
+ const char *name, /* I - Printer or class name */
+ int num_files, /* I - Number of files */
+ const char **files, /* I - File(s) to print */
+ const char *title, /* I - Title of job */
+ int num_options, /* I - Number of options */
+ cups_option_t *options) /* I - Options */
{
- _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
-
DEBUG_printf(("cupsPrintFiles(name=\"%s\", num_files=%d, "
"files=%p, title=\"%s\", num_options=%d, options=%p)\n",
name, num_files, files, title, num_options, options));
/*
- * Setup a connection and request data...
- */
-
- if (!cups_connect(name, NULL, NULL))
- {
- DEBUG_printf(("cupsPrintFiles: Unable to open connection - %s.\n",
- strerror(errno)));
- DEBUG_puts("Unable to connect to server!");
-
- return (0);
- }
-
- /*
* Print the file(s)...
*/
- return (cupsPrintFiles2(cg->http, name, num_files, files, title,
+ return (cupsPrintFiles2(CUPS_HTTP_DEFAULT, name, num_files, files, title,
num_options, options));
}
-
/*
* 'cupsPrintFiles2()' - Print one or more files to a printer or class on the
* specified server.
@@ -1255,26 +1310,26 @@ cupsPrintFiles(const char *name, /* I - Printer or class name */
*/
int /* O - Job ID */
-cupsPrintFiles2(http_t *http, /* I - HTTP connection */
- const char *name, /* I - Printer or class name */
- int num_files,/* I - Number of files */
- const char **files, /* I - File(s) to print */
- const char *title, /* I - Title of job */
- int num_options,
- /* I - Number of options */
- cups_option_t *options) /* I - Options */
+cupsPrintFiles2(
+ http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+ const char *name, /* I - Printer or class name */
+ int num_files, /* I - Number of files */
+ const char **files, /* I - File(s) to print */
+ const char *title, /* I - Title of job */
+ int num_options, /* I - Number of options */
+ cups_option_t *options) /* I - Options */
{
int i; /* Looping var */
- const char *val; /* Pointer to option value */
- ipp_t *request; /* IPP request */
- ipp_t *response; /* IPP response */
- ipp_attribute_t *attr; /* IPP job-id attribute */
- char uri[HTTP_MAX_URI]; /* Printer URI */
- int jobid; /* New job ID */
- const char *base; /* Basename of current filename */
+ int job_id; /* New job ID */
+ const char *docname; /* Basename of current filename */
+ const char *format; /* Document format */
+ cups_file_t *fp; /* Current file */
+ char buffer[8192]; /* Copy buffer */
+ ssize_t bytes; /* Bytes in buffer */
+ http_status_t status; /* Status of write */
- DEBUG_printf(("cupsPrintFiles(http=%p, name=\"%s\", num_files=%d, "
+ DEBUG_printf(("cupsPrintFiles2(http=%p, name=\"%s\", num_files=%d, "
"files=%p, title=\"%s\", num_options=%d, options=%p)\n",
http, name, num_files, files, title, num_options, options));
@@ -1282,7 +1337,7 @@ cupsPrintFiles2(http_t *http, /* I - HTTP connection */
* Range check input...
*/
- if (!http || !name || num_files < 1 || files == NULL)
+ if (!name || num_files < 1 || !files)
{
_cupsSetError(IPP_INTERNAL_ERROR, NULL);
@@ -1290,215 +1345,204 @@ cupsPrintFiles2(http_t *http, /* I - HTTP connection */
}
/*
- * Setup the printer URI...
+ * Create the print job...
*/
- if (httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
- "localhost", 0, "/printers/%s", name) != HTTP_URI_OK)
- {
- _cupsSetError(IPP_INTERNAL_ERROR, NULL);
-
+ if ((job_id = cupsCreateJob(http, name, title, num_options, options)) == 0)
return (0);
- }
/*
- * Build a standard CUPS URI for the printer and fill the standard IPP
- * attributes...
+ * Send each of the files...
*/
- if ((request = ippNewRequest(num_files == 1 ? IPP_PRINT_JOB :
- IPP_CREATE_JOB)) == NULL)
- {
- _cupsSetError(IPP_INTERNAL_ERROR, NULL);
-
- return (0);
- }
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
- NULL, uri);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, cupsUser());
+ if (cupsGetOption("raw", num_options, options))
+ format = CUPS_FORMAT_RAW;
+ else if ((format = cupsGetOption("document-format", num_options,
+ options)) == NULL)
+ format = CUPS_FORMAT_AUTO;
- if (title)
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL,
- title);
-
- /*
- * Then add all options...
- */
-
- cupsEncodeOptions(request, num_options, options);
-
- /*
- * Do the request...
- */
-
- snprintf(uri, sizeof(uri), "/printers/%s", name);
+ for (i = 0; i < num_files; i ++)
+ {
+ /*
+ * Start the next file...
+ */
- if (num_files == 1)
- response = cupsDoFileRequest(http, request, uri, *files);
- else
- response = cupsDoRequest(http, request, uri);
+ if ((docname = strrchr(files[i], '/')) != NULL)
+ docname ++;
+ else
+ docname = files[i];
- if (response == NULL)
- jobid = 0;
- else if (response->request.status.status_code > IPP_OK_CONFLICT)
- {
- DEBUG_printf(("IPP response code was 0x%x!\n",
- response->request.status.status_code));
- jobid = 0;
- }
- else if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) == NULL)
- {
- DEBUG_puts("No job ID!");
+ if ((fp = cupsFileOpen(files[i], "rb")) == NULL)
+ {
+ /*
+ * Unable to open print file, cancel the job and return...
+ */
- _cupsSetError(IPP_INTERNAL_ERROR, NULL);
+ cupsCancelJob2(http, job_id, 0);
+ return (0);
+ }
- jobid = 0;
- }
- else
- jobid = attr->values[0].integer;
+ status = cupsStartDocument(http, name, job_id, docname, format,
+ i == (num_files - 1));
- if (response != NULL)
- ippDelete(response);
+ while (status == HTTP_CONTINUE &&
+ (bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0)
+ status = cupsWriteRequestData(http, buffer, bytes);
- /*
- * Handle multiple file jobs if the create-job operation worked...
- */
+ cupsFileClose(fp);
- if (jobid > 0 && num_files > 1)
- for (i = 0; i < num_files; i ++)
+ if (status != HTTP_CONTINUE || cupsFinishDocument(http, name) != IPP_OK)
{
/*
- * Build a standard CUPS URI for the job and fill the standard IPP
- * attributes...
+ * Unable to queue, cancel the job and return...
*/
- if ((request = ippNewRequest(IPP_SEND_DOCUMENT)) == NULL)
- return (0);
-
- snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", jobid);
+ cupsCancelJob2(http, job_id, 0);
+ return (0);
+ }
+ }
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri",
- NULL, uri);
+ return (job_id);
+}
- /*
- * Handle raw print files...
- */
- if (cupsGetOption("raw", num_options, options))
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE,
- "document-format", NULL, "application/vnd.cups-raw");
- else if ((val = cupsGetOption("document-format", num_options,
- options)) != NULL)
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE,
- "document-format", NULL, val);
- else
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE,
- "document-format", NULL, "application/octet-stream");
+/*
+ * 'cupsStartDocument()' - Add a document to a job created with cupsCreateJob().
+ *
+ * Use cupsWriteRequestData() to write data for the document and
+ * cupsFinishDocument() to finish the document and get the submission status.
+ *
+ * The MIME type constants CUPS_FORMAT_AUTO, CUPS_FORMAT_PDF,
+ * CUPS_FORMAT_POSTSCRIPT, CUPS_FORMAT_RAW, and CUPS_FORMAT_TEXT are provided
+ * for the "format" argument, although any supported MIME type string can be
+ * supplied.
+ *
+ * @since CUPS 1.4@
+ */
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requesting-user-name", NULL, cupsUser());
+http_status_t /* O - HTTP status of request */
+cupsStartDocument(
+ http_t *http, /* I - HTTP connection or CUPS_HTTP_DEFAULT */
+ const char *name, /* I - Printer or class name */
+ int job_id, /* I - Job ID from cupsCreateJob() */
+ const char *docname, /* I - Name of document */
+ const char *format, /* I - MIME type or CUPS_FORMAT_foo */
+ int last_document) /* I - 1 for last document in job, 0 otherwise */
+{
+ char resource[1024], /* Resource for destinatio */
+ printer_uri[1024]; /* Printer URI */
+ ipp_t *request; /* Send-Document request */
+ http_status_t status; /* HTTP status */
- /*
- * Add the original document filename...
- */
- if ((base = strrchr(files[i], '/')) != NULL)
- base ++;
- else
- base = files[i];
+ /*
+ * Create a Send-Document request...
+ */
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "document-name",
- NULL, base);
+ if ((request = ippNewRequest(IPP_SEND_DOCUMENT)) == NULL)
+ {
+ _cupsSetError(IPP_INTERNAL_ERROR, NULL);
+ return (0);
+ }
- /*
- * Is this the last document?
- */
+ httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), "ipp",
+ NULL, "localhost", ippPort(), "/printers/%s", name);
+ snprintf(resource, sizeof(resource), "/printers/%s", name);
- if (i == (num_files - 1))
- ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, printer_uri);
+ ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job_id);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, cupsUser());
+ if (docname)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "document-name",
+ NULL, docname);
+ if (format)
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE,
+ "document-format", NULL, format);
+ ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", last_document);
- /*
- * Send the file...
- */
+ /*
+ * Send and delete the request, then return the status...
+ */
- snprintf(uri, sizeof(uri), "/printers/%s", name);
+ status = cupsSendRequest(http, request, resource, CUPS_LENGTH_VARIABLE);
- if ((response = cupsDoFileRequest(http, request, uri,
- files[i])) != NULL)
- ippDelete(response);
- }
+ ippDelete(request);
- return (jobid);
+ return (status);
}
/*
- * 'cups_connect()' - Connect to the specified host...
+ * '_cupsConnect()' - Get the default server connection...
*/
-static char * /* I - Printer name or NULL */
-cups_connect(const char *name, /* I - Destination (printer[@host]) */
- char *printer, /* O - Printer name [HTTP_MAX_URI] */
- char *hostname) /* O - Hostname [HTTP_MAX_URI] */
+http_t * /* O - HTTP connection */
+_cupsConnect(void)
{
- char hostbuf[HTTP_MAX_URI], /* Name of host */
- http_hostname[HTTP_MAX_HOST]; /* Hostname associated with connection */
- _cups_globals_t *cg = _cupsGlobals();/* Pointer to library globals */
-
-
- DEBUG_printf(("cups_connect(\"%s\", %p, %p)\n", name, printer, hostname));
-
- if (name == NULL)
- {
- _cupsSetError(IPP_BAD_REQUEST, NULL);
+ _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */
- return (NULL);
- }
/*
- * All jobs are now queued to cupsServer() to avoid hostname
- * resolution problems and to ensure that the user sees all
- * locally queued jobs locally.
+ * See if we are connected to the same server...
*/
- strlcpy(hostbuf, cupsServer(), sizeof(hostbuf));
+ if (cg->http)
+ {
+ int port; /* Port for connection */
- httpGetHostname(cg->http, http_hostname, sizeof(http_hostname));
- if (hostname != NULL)
- strlcpy(hostname, hostbuf, HTTP_MAX_URI);
- else
- hostname = hostbuf;
+ /*
+ * Get the port associated with the current connection...
+ */
- if (printer != NULL)
- strlcpy(printer, name, HTTP_MAX_URI);
- else
- printer = (char *)name;
+#ifdef AF_INET6
+ if (cg->http->hostaddr->addr.sa_family == AF_INET6)
+ port = ntohs(cg->http->hostaddr->ipv6.sin6_port);
+ else
+#endif /* AF_INET6 */
+ if (cg->http->hostaddr->addr.sa_family == AF_INET)
+ port = ntohs(cg->http->hostaddr->ipv4.sin_port);
+ else
+ port = cg->ipp_port;
- if (cg->http != NULL)
- {
- if (!strcasecmp(http_hostname, hostname))
- return (printer);
+ /*
+ * Compare the connection hostname, port, and encryption settings to
+ * the cached defaults; these were initialized the first time we
+ * connected...
+ */
+
+ if (strcmp(cg->http->hostname, cg->server) || cg->ipp_port != port ||
+ (cg->http->encryption != cg->encryption &&
+ cg->http->encryption == HTTP_ENCRYPT_NEVER))
+ {
+ /*
+ * Need to close the current connection because something has changed...
+ */
- httpClose(cg->http);
+ httpClose(cg->http);
+ cg->http = NULL;
+ }
}
- DEBUG_printf(("connecting to %s on port %d...\n", hostname, ippPort()));
+ /*
+ * (Re)connect as needed...
+ */
- if ((cg->http = httpConnectEncrypt(hostname, ippPort(),
- cupsEncryption())) == NULL)
+ if (!cg->http)
{
- DEBUG_puts("Unable to connect to server!");
+ if ((cg->http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption())) == NULL)
+ _cupsSetError(IPP_SERVICE_UNAVAILABLE,
+ errno ? strerror(errno) : "Unable to connect to host.");
+ }
- _cupsSetError(IPP_SERVICE_UNAVAILABLE, strerror(errno));
+ /*
+ * Return the cached connection...
+ */
- return (NULL);
- }
- else
- return (printer);
+ return (cg->http);
}
diff --git a/data/testprint.ps b/data/testprint.ps
index ead73978a..72f5da9ee 100644
--- a/data/testprint.ps
+++ b/data/testprint.ps
@@ -14,7 +14,7 @@
%
% PostScript test page for the Common UNIX Printing System ("CUPS").
%
-% Copyright 2007 Apple Inc.
+% Copyright 2007-2008 Apple Inc.
% Copyright 1993-2007 Easy Software Products
%
% These coded instructions, statements, and computer programs are the
@@ -567,16 +567,16 @@ gsave
pageWidth 17 mul % Center of page
pageHeight 10 mul % Bottom of page
moveto % Position text
- (Printed Using CUPS v1.3.x) show
+ (Printed Using CUPS v1.4.x) show
pageWidth 17 mul % Left side of page
pageHeight 8 mul % Move down...
2 copy moveto % Position text
smallFont setfont % Font
- (Copyright 2007 Apple Inc., All Rights Reserved. CUPS and the CUPS logo are the trademark) show
+ (Copyright 2007-2008 Apple Inc., All Rights Reserved. CUPS and the CUPS logo are the) show
pageHeight 2 add sub % Move down...
2 copy moveto % Position text
- (property of Apple Inc., 1 Infinite Loop, Cupertino, CA 95014, USA.) show
+ (trademark property of Apple Inc., 1 Infinite Loop, Cupertino, CA 95014, USA.) show
pageHeight 2 mul 4 add sub % Move down...
moveto % Position text
(Need help? Contact your operating system vendor or visit "http://www.cups.org/".) show
diff --git a/doc/index.html.in b/doc/index.html.in
index fa40ee272..560f7668b 100644
--- a/doc/index.html.in
+++ b/doc/index.html.in
@@ -77,8 +77,8 @@ assistance:</P>
<TR><TD>&nbsp;</TD></TR>
<TR><TD CLASS="trailer">The Common UNIX Printing System, CUPS, and
the CUPS logo are the trademark property of
-<A HREF="http://www.apple.com">Apple Inc.</A> CUPS is copyright 2007 by Apple
-Inc., all rights reserved.</TD></TR>
+<A HREF="http://www.apple.com">Apple Inc.</A> CUPS is copyright 2007-2008 by
+Apple Inc., all rights reserved.</TD></TR>
</TABLE>
</BODY>
</HTML>
diff --git a/man/cupsd.conf.man.in b/man/cupsd.conf.man.in
index ef2db81ad..68ce70c47 100644
--- a/man/cupsd.conf.man.in
+++ b/man/cupsd.conf.man.in
@@ -3,7 +3,7 @@
.\"
.\" cupsd.conf man page for the Common UNIX Printing System (CUPS).
.\"
-.\" Copyright 2007 by Apple Inc.
+.\" Copyright 2007-2008 by Apple Inc.
.\" Copyright 1997-2006 by Easy Software Products.
.\"
.\" These coded instructions, statements, and computer programs are the
@@ -12,7 +12,7 @@
.\" which should have been included with this file. If this file is
.\" file is missing or damaged, see the license at "http://www.cups.org/".
.\"
-.TH cupsd.conf 5 "Common UNIX Printing System" "6 June 2006" "Apple Inc."
+.TH cupsd.conf 5 "Common UNIX Printing System" "2 January 2008" "Apple Inc."
.SH NAME
cupsd.conf \- server configuration file for cups
.SH DESCRIPTION
@@ -230,6 +230,12 @@ DefaultPolicy policy-name
.br
Specifies the default access policy to use.
.TP 5
+DefaultShared Yes
+.TP 5
+DefaultShared No
+.br
+Specifies whether local printers are shared by default.
+.TP 5
Deny all
.TP 5
Deny none
@@ -606,7 +612,7 @@ Specifies the user name or ID that is used when running external programs.
.br
http://localhost:631/help
.SH COPYRIGHT
-Copyright 2007 by Apple Inc.
+Copyright 2007-2008 by Apple Inc.
.\"
.\" End of "$Id: cupsd.conf.man.in 7002 2007-10-01 23:07:37Z mike $".
.\"
diff --git a/man/lpadmin.man b/man/lpadmin.man
index 7b7f5b4a9..ab6fc264e 100644
--- a/man/lpadmin.man
+++ b/man/lpadmin.man
@@ -3,7 +3,7 @@
.\"
.\" lpadmin man page for the Common UNIX Printing System (CUPS).
.\"
-.\" Copyright 2007 by Apple Inc.
+.\" Copyright 2007-2008 by Apple Inc.
.\" Copyright 1997-2006 by Easy Software Products.
.\"
.\" These coded instructions, statements, and computer programs are the
@@ -12,7 +12,7 @@
.\" which should have been included with this file. If this file is
.\" file is missing or damaged, see the license at "http://www.cups.org/".
.\"
-.TH lpadmin 8 "Common UNIX Printing System" "13 July 2006" "Apple Inc."
+.TH lpadmin 8 "Common UNIX Printing System" "2 January 2008" "Apple Inc."
.SH NAME
lpadmin \- configure cups printers and classes
.SH SYNOPSIS
@@ -81,12 +81,6 @@ and is intended for providing support for legacy printer drivers.
Sets a standard System V interface script or PPD file from the
\fImodel\fR directory.
.TP 5
--o name=value
-.br
-Sets a PPD or server option for the printer. PPD options can be
-listed using the \fI-l\fR option with the \fIlpoptions(1)\fR
-command.
-.TP 5
-o job-k-limit=value
.br
Sets the kilobyte limit for per-user quotas. The value is an
@@ -109,10 +103,23 @@ integer number of seconds; 86,400 seconds are in one day.
.br
Sets the default banner page(s) to use for print jobs.
.TP 5
+-o name=value
+.br
+Sets a PPD option for the printer. PPD options can be
+listed using the \fI-l\fR option with the \fIlpoptions(1)\fR
+command.
+.TP 5
+-o name-default=value
+.br
+Sets a default server-side option for the printer. Any print-time
+option can be defaulted, e.g. "-o cpi-default=17" to set the default
+"cpi" option value to 17.
+.TP 5
-o port-monitor=name
.br
Sets the binary communications program to use when printing,
-"none", "bcp", or "tbcp". The default program is "none".
+"none", "bcp", or "tbcp". The default program is "none". The
+specified port monitor must be listed in the printer's PPD file.
.TP 5
-o printer-error-policy=name
.br
@@ -194,7 +201,7 @@ System V or Solaris printing system configuration options.
.br
http://localhost:631/help
.SH COPYRIGHT
-Copyright 2007 by Apple Inc.
+Copyright 2007-2008 by Apple Inc.
.\"
.\" End of "$Id: lpadmin.man 6649 2007-07-11 21:46:42Z mike $".
.\"
diff --git a/man/lpq.man b/man/lpq.man
index fac327e10..3be52e9f4 100644
--- a/man/lpq.man
+++ b/man/lpq.man
@@ -3,7 +3,7 @@
.\"
.\" lpq man page for the Common UNIX Printing System (CUPS).
.\"
-.\" Copyright 2007 by Apple Inc.
+.\" Copyright 2007-2008 by Apple Inc.
.\" Copyright 1997-2006 by Easy Software Products.
.\"
.\" These coded instructions, statements, and computer programs are the
@@ -12,7 +12,7 @@
.\" which should have been included with this file. If this file is
.\" file is missing or damaged, see the license at "http://www.cups.org/".
.\"
-.TH lpq 1 "Common UNIX Printing System" "12 February 2006" "Apple Inc."
+.TH lpq 1 "Common UNIX Printing System" "2 January 2008" "Apple Inc."
.SH NAME
lpq \- show printer queue status
.SH SYNOPSIS
@@ -33,7 +33,7 @@ no printer or class is specified on the command-line.
.LP
The \fI+interval\fR option allows you to continuously report the
jobs in the queue until the queue is empty; the list of jobs is
-show one every \fIinterval\fR seconds.
+show once every \fIinterval\fR seconds.
.SH OPTIONS
\fIlpq\fR supports the following options:
.TP 5
@@ -66,7 +66,7 @@ Requests a more verbose (long) reporting format.
.br
http://localhost:631/help
.SH COPYRIGHT
-Copyright 2007 by Apple Inc.
+Copyright 2007-2008 by Apple Inc.
.\"
.\" End of "$Id: lpq.man 6649 2007-07-11 21:46:42Z mike $".
.\"
diff --git a/pdftops/pdftops.cxx b/pdftops/pdftops.cxx
index 4e8d7279f..a583ae46c 100644
--- a/pdftops/pdftops.cxx
+++ b/pdftops/pdftops.cxx
@@ -308,8 +308,7 @@ main(int argc, // I - Number of command-line args
// write PostScript file
psOut = new PSOutputDev(psFileName->getCString(), doc->getXRef(),
doc->getCatalog(), 1, doc->getNumPages(),
- psModePS, 0, 0, 0, 0, gFalse,
- cupsGetOption("page-ranges", num_options, options));
+ psModePS, 0, 0, 0, 0, gFalse, NULL);
if (psOut->isOk())
doc->displayPages(psOut, 1, doc->getNumPages(), 72.0, 72.0, 0,
gTrue, gFalse, gFalse);
diff --git a/systemv/lp.c b/systemv/lp.c
index 9c886ae3c..c14ec2d62 100644
--- a/systemv/lp.c
+++ b/systemv/lp.c
@@ -1,5 +1,5 @@
/*
- * "$Id: lp.c 6649 2007-07-11 21:46:42Z mike $"
+ * "$Id: lp.c 7170 2008-01-04 02:21:30Z mike $"
*
* "lp" command for the Common UNIX Printing System (CUPS).
*
@@ -17,7 +17,6 @@
* main() - Parse options and send files for printing.
* restart_job() - Restart a job.
* set_job_attrs() - Set job attributes.
- * sighandler() - Signal catcher for when we print from stdin...
*/
/*
@@ -32,30 +31,16 @@
#include <cups/i18n.h>
-#ifndef WIN32
-# include <unistd.h>
-# include <signal.h>
-
-
/*
* Local functions.
*/
-void sighandler(int);
-#endif /* !WIN32 */
int restart_job(const char *command, int job_id);
int set_job_attrs(const char *command, int job_id, int num_options,
cups_option_t *options);
/*
- * Globals...
- */
-
-char tempfile[1024]; /* Temporary file for printing from stdin */
-
-
-/*
* 'main()' - Parse options and send files for printing.
*/
@@ -79,13 +64,6 @@ main(int argc, /* I - Number of command-line arguments */
int end_options; /* No more options? */
int silent; /* Silent or verbose output? */
char buffer[8192]; /* Copy buffer */
- ssize_t bytes; /* Bytes copied */
- off_t filesize; /* Size of temp file */
- int temp; /* Temporary file descriptor */
-#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
- struct sigaction action; /* Signal action */
- struct sigaction oldaction; /* Old signal action */
-#endif /* HAVE_SIGACTION && !HAVE_SIGSET*/
#ifdef __sun
@@ -635,73 +613,38 @@ main(int argc, /* I - Number of command-line arguments */
if (num_files > 0)
job_id = cupsPrintFiles(printer, num_files, files, title, num_options, options);
- else
+ else if ((job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, printer,
+ title ? title : "(stdin)",
+ num_options, options)) > 0)
{
- num_files = 1;
-
-#ifndef WIN32
-# if defined(HAVE_SIGSET)
- sigset(SIGHUP, sighandler);
- if (sigset(SIGINT, sighandler) == SIG_IGN)
- sigset(SIGINT, SIG_IGN);
- sigset(SIGTERM, sighandler);
-# elif defined(HAVE_SIGACTION)
- memset(&action, 0, sizeof(action));
- action.sa_handler = sighandler;
-
- sigaction(SIGHUP, &action, NULL);
- sigaction(SIGINT, NULL, &oldaction);
- if (oldaction.sa_handler != SIG_IGN)
- sigaction(SIGINT, &action, NULL);
- sigaction(SIGTERM, &action, NULL);
-# else
- signal(SIGHUP, sighandler);
- if (signal(SIGINT, sighandler) == SIG_IGN)
- signal(SIGINT, SIG_IGN);
- signal(SIGTERM, sighandler);
-# endif
-#endif /* !WIN32 */
-
- temp = cupsTempFd(tempfile, sizeof(tempfile));
-
- if (temp < 0)
- {
- _cupsLangPrintf(stderr,
- _("%s: Error - unable to create temporary file \"%s\" - %s\n"),
- argv[0], tempfile, strerror(errno));
- return (1);
- }
+ http_status_t status; /* Write status */
+ const char *format; /* Document format */
+ ssize_t bytes; /* Bytes read */
- while ((bytes = read(0, buffer, sizeof(buffer))) > 0)
- if (write(temp, buffer, bytes) < 0)
- {
- _cupsLangPrintf(stderr,
- _("%s: Error - unable to write to temporary file "
- "\"%s\" - %s\n"),
- argv[0], tempfile, strerror(errno));
- close(temp);
- unlink(tempfile);
- return (1);
- }
- filesize = lseek(temp, 0, SEEK_CUR);
- close(temp);
+ if (cupsGetOption("raw", num_options, options))
+ format = CUPS_FORMAT_RAW;
+ else if ((format = cupsGetOption("document-format", num_options,
+ options)) == NULL)
+ format = CUPS_FORMAT_AUTO;
+
+ status = cupsStartDocument(CUPS_HTTP_DEFAULT, printer, job_id, NULL,
+ format, 1);
- if (filesize <= 0)
+ while (status == HTTP_CONTINUE &&
+ (bytes = read(0, buffer, sizeof(buffer))) > 0)
+ status = cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer, bytes);
+
+ if (status != HTTP_CONTINUE)
{
_cupsLangPrintf(stderr,
- _("%s: Error - stdin is empty, so no job has been sent.\n"),
- argv[0]);
- unlink(tempfile);
+ _("%s: Error - unable to queue from stdin - %s\n"),
+ argv[0], httpStatus(status));
return (1);
}
- if (title)
- job_id = cupsPrintFile(printer, tempfile, title, num_options, options);
- else
- job_id = cupsPrintFile(printer, tempfile, "(stdin)", num_options, options);
-
- unlink(tempfile);
+ if (cupsFinishDocument(CUPS_HTTP_DEFAULT, printer) != IPP_OK)
+ job_id = 0;
}
if (job_id < 1)
@@ -725,13 +668,10 @@ int /* O - Exit status */
restart_job(const char *command, /* I - Command name */
int job_id) /* I - Job ID */
{
- http_t *http; /* HTTP connection to server */
ipp_t *request; /* IPP request */
char uri[HTTP_MAX_URI]; /* URI for job */
- http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
-
request = ippNewRequest(IPP_RESTART_JOB);
sprintf(uri, "ipp://localhost/jobs/%d", job_id);
@@ -742,7 +682,7 @@ restart_job(const char *command, /* I - Command name */
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
"requesting-user-name", NULL, cupsUser());
- ippDelete(cupsDoRequest(http, request, "/jobs"));
+ ippDelete(cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/jobs"));
if (cupsLastError() > IPP_OK_CONFLICT)
{
@@ -764,7 +704,6 @@ set_job_attrs(const char *command, /* I - Command name */
int num_options,/* I - Number of options */
cups_option_t *options) /* I - Options */
{
- http_t *http; /* HTTP connection to server */
ipp_t *request; /* IPP request */
char uri[HTTP_MAX_URI]; /* URI for job */
@@ -772,8 +711,6 @@ set_job_attrs(const char *command, /* I - Command name */
if (num_options == 0)
return (0);
- http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
-
request = ippNewRequest(IPP_SET_JOB_ATTRIBUTES);
sprintf(uri, "ipp://localhost/jobs/%d", job_id);
@@ -786,7 +723,7 @@ set_job_attrs(const char *command, /* I - Command name */
cupsEncodeOptions(request, num_options, options);
- ippDelete(cupsDoRequest(http, request, "/jobs"));
+ ippDelete(cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/jobs"));
if (cupsLastError() > IPP_OK_CONFLICT)
{
@@ -798,29 +735,6 @@ set_job_attrs(const char *command, /* I - Command name */
}
-#ifndef WIN32
-/*
- * 'sighandler()' - Signal catcher for when we print from stdin...
- */
-
-void
-sighandler(int s) /* I - Signal number */
-{
- /*
- * Remove the temporary file we're using to print from stdin...
- */
-
- unlink(tempfile);
-
- /*
- * Exit...
- */
-
- exit(s);
-}
-#endif /* !WIN32 */
-
-
/*
- * End of "$Id: lp.c 6649 2007-07-11 21:46:42Z mike $".
+ * End of "$Id: lp.c 7170 2008-01-04 02:21:30Z mike $".
*/
diff --git a/templates/trailer.tmpl b/templates/trailer.tmpl
index fd79db9b6..088e3238f 100644
--- a/templates/trailer.tmpl
+++ b/templates/trailer.tmpl
@@ -2,8 +2,8 @@
<TR><TD>&nbsp;</TD></TR>
<TR><TD CLASS="trailer">The Common UNIX Printing System, CUPS, and
the CUPS logo are the trademark property of
-<A HREF="http://www.apple.com">Apple Inc.</A> CUPS is copyright 2007 by Apple
-Inc., all rights reserved.</TD></TR>
+<A HREF="http://www.apple.com">Apple Inc.</A> CUPS is copyright 2007-2008 by
+Apple Inc., all rights reserved.</TD></TR>
</TABLE>
</BODY>
</HTML>