CHANGES IN CUPS V1.3.8
- Documentation updates (STR #2785)
+ - The CUPS PHP extension was not thread-safe (STR #2828)
+ - The scheduler incorrectly added the document-format-default
+ attribute to the list of "common" printer attributes, which
+ over time would slow down the printing system (STR #2755,
+ STR #2836)
+ - The cups-deviced and cups-driverd helper programs did not set
+ the CFProcessPath environment variable on Mac OS X (STR #2837)
+ - "lpstat -p" could report the wrong job as printing (STR #2845)
+ - The scheduler would crash when some cupsd.conf directives
+ were missing values (STR #2849)
- The web interface "move jobs" operation redirected users to
the wrong URL (STR #2815)
- The Polish web interface translation contained errors
sockets (STR #2750)
- The scheduler incorrectly logged errors for print filters
when a job was canceled (STR #2806, #2808)
- - The scheduler not long allows multiple RSS subscriptions
+ - The scheduler no longer allows multiple RSS subscriptions
with the same URI (STR #2789)
- The scheduler now supports Kerberized printing with
multiple server names (STR #2783)
switch (SSL_shutdown(conn))
{
case 1 :
- cupsdLogMessage(CUPSD_LOG_INFO,
- "cupsdCloseClient: SSL shutdown successful!");
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "SSL shutdown successful!");
break;
case -1 :
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdCloseClient: Fatal error during SSL shutdown!");
+ "Fatal error during SSL shutdown!");
default :
while ((error = ERR_get_error()) != 0)
- cupsdLogMessage(CUPSD_LOG_ERROR, "cupsdCloseClient: %s",
+ cupsdLogMessage(CUPSD_LOG_ERROR, "SSL shutdown failed: %s",
ERR_error_string(error, NULL));
break;
}
switch (error)
{
case GNUTLS_E_SUCCESS:
- cupsdLogMessage(CUPSD_LOG_INFO,
- "cupsdCloseClient: SSL shutdown successful!");
+ cupsdLogMessage(CUPSD_LOG_DEBUG,
+ "SSL shutdown successful!");
break;
default:
cupsdLogMessage(CUPSD_LOG_ERROR,
- "cupsdCloseClient: %s", gnutls_strerror(error));
+ "SSL shutdown failed: %s", gnutls_strerror(error));
break;
}
switch (sscanf(line, "%63s%1023s%63s", operation, con->uri, version))
{
case 1 :
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "Bad request line \"%s\" from %s!", line,
- con->http.hostname);
- cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE);
- cupsdCloseClient(con);
+ if (line[0])
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Bad request line \"%s\" from %s!", line,
+ con->http.hostname);
+ cupsdSendError(con, HTTP_BAD_REQUEST, CUPSD_AUTH_NONE);
+ cupsdCloseClient(con);
+ }
return;
case 2 :
con->http.version = HTTP_0_9;
* Decode the directive...
*/
- if (!strcasecmp(line, "Include"))
+ if (!strcasecmp(line, "Include") && value)
{
/*
* Include filename
cupsFileClose(incfile);
}
}
- else if (!strcasecmp(line, "<Location"))
+ else if (!strcasecmp(line, "<Location") && value)
{
/*
* <Location path>
*/
- if (value)
- {
- linenum = read_location(fp, value, linenum);
- if (linenum == 0)
- return (0);
- }
- else
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d.",
- linenum);
- return (0);
- }
+ linenum = read_location(fp, value, linenum);
+ if (linenum == 0)
+ return (0);
}
- else if (!strcasecmp(line, "<Policy"))
+ else if (!strcasecmp(line, "<Policy") && value)
{
/*
* <Policy name>
*/
- if (value)
- {
- linenum = read_policy(fp, value, linenum);
- if (linenum == 0)
- return (0);
- }
- else
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d.", linenum);
- return (0);
- }
+ linenum = read_policy(fp, value, linenum);
+ if (linenum == 0)
+ return (0);
}
- else if (!strcasecmp(line, "FaxRetryInterval"))
+ else if (!strcasecmp(line, "FaxRetryInterval") && value)
{
- if (value)
- {
- JobRetryInterval = atoi(value);
- cupsdLogMessage(CUPSD_LOG_WARN,
- "FaxRetryInterval is deprecated; use "
- "JobRetryInterval on line %d.", linenum);
- }
- else
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d.", linenum);
- return (0);
- }
+ JobRetryInterval = atoi(value);
+ cupsdLogMessage(CUPSD_LOG_WARN,
+ "FaxRetryInterval is deprecated; use "
+ "JobRetryInterval on line %d.", linenum);
}
- else if (!strcasecmp(line, "FaxRetryLimit"))
+ else if (!strcasecmp(line, "FaxRetryLimit") && value)
{
- if (value)
- {
- JobRetryLimit = atoi(value);
- cupsdLogMessage(CUPSD_LOG_WARN,
- "FaxRetryLimit is deprecated; use "
- "JobRetryLimit on line %d.", linenum);
- }
- else
- {
- cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d.", linenum);
- return (0);
- }
+ JobRetryLimit = atoi(value);
+ cupsdLogMessage(CUPSD_LOG_WARN,
+ "FaxRetryLimit is deprecated; use "
+ "JobRetryLimit on line %d.", linenum);
}
else if (!strcasecmp(line, "Port") || !strcasecmp(line, "Listen")
#ifdef HAVE_SSL
httpAddrFreeList(addrlist);
}
- else if (!strcasecmp(line, "BrowseAddress"))
+ else if (!strcasecmp(line, "BrowseAddress") && value)
{
/*
* Add a browse address to the list...
cupsdLogMessage(CUPSD_LOG_ERROR, "Bad BrowseAddress %s at line %d.",
value, linenum);
}
- else if (!strcasecmp(line, "BrowseOrder"))
+ else if (!strcasecmp(line, "BrowseOrder") && value)
{
/*
* "BrowseOrder Deny,Allow" or "BrowseOrder Allow,Deny"...
if (strcasecmp(line, "BrowseRemoteProtocols"))
BrowseLocalProtocols = protocols;
}
- else if (!strcasecmp(line, "BrowseAllow") ||
- !strcasecmp(line, "BrowseDeny"))
+ else if ((!strcasecmp(line, "BrowseAllow") ||
+ !strcasecmp(line, "BrowseDeny")) && value)
{
/*
* BrowseAllow [From] host/ip...
}
}
}
- else if (!strcasecmp(line, "BrowseRelay"))
+ else if (!strcasecmp(line, "BrowseRelay") && value)
{
/*
* BrowseRelay [from] source [to] destination
value, linenum);
}
}
- else if (!strcasecmp(line, "BrowsePoll"))
+ else if (!strcasecmp(line, "BrowsePoll") && value)
{
/*
* BrowsePoll address[:port]
cupsdLogMessage(CUPSD_LOG_INFO, "Polling %s:%d", pollp->hostname,
pollp->port);
}
- else if (!strcasecmp(line, "DefaultAuthType"))
+ else if (!strcasecmp(line, "DefaultAuthType") && value)
{
/*
* DefaultAuthType {basic,digest,basicdigest,negotiate}
}
#endif /* HAVE_SSL */
#ifdef HAVE_GSSAPI
- else if (!strcasecmp(line, "Krb5Keytab"))
+ else if (!strcasecmp(line, "Krb5Keytab") && value)
{
cupsdSetStringf(&Krb5Keytab, "KRB5_KTNAME=%s", value);
putenv(Krb5Keytab);
# endif /* HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY */
}
#endif /* HAVE_GSSAPI */
- else if (!strcasecmp(line, "User"))
+ else if (!strcasecmp(line, "User") && value)
{
/*
* User ID to run as...
*/
- if (value && isdigit(value[0] & 255))
+ if (isdigit(value[0] & 255))
{
int uid = atoi(value);
else
User = atoi(value);
}
- else if (value)
+ else
{
struct passwd *p; /* Password information */
"Unknown User \"%s\" on line %d, ignoring!",
value, linenum);
}
- else
- cupsdLogMessage(CUPSD_LOG_ERROR,
- "User directive on line %d missing the username!",
- linenum);
}
- else if (!strcasecmp(line, "Group"))
+ else if (!strcasecmp(line, "Group") && value)
{
/*
* Group ID to run as...
value, linenum);
}
}
- else if (!strcasecmp(line, "SystemGroup"))
+ else if (!strcasecmp(line, "SystemGroup") && value)
{
/*
* SystemGroup (admin) group(s)...
"Unknown SystemGroup \"%s\" on line %d, ignoring!",
value, linenum);
}
- else if (!strcasecmp(line, "HostNameLookups"))
+ else if (!strcasecmp(line, "HostNameLookups") && value)
{
/*
* Do hostname lookups?
cupsdLogMessage(CUPSD_LOG_WARN, "Unknown HostNameLookups %s on line %d.",
value, linenum);
}
- else if (!strcasecmp(line, "LogLevel"))
+ else if (!strcasecmp(line, "LogLevel") && value)
{
/*
* Amount of logging to do...
cupsdLogMessage(CUPSD_LOG_WARN, "Unknown LogLevel %s on line %d.",
value, linenum);
}
- else if (!strcasecmp(line, "PrintcapFormat"))
+ else if (!strcasecmp(line, "PrintcapFormat") && value)
{
/*
* Format of printcap file?
cupsdLogMessage(CUPSD_LOG_WARN, "Unknown PrintcapFormat %s on line %d.",
value, linenum);
}
- else if (!strcasecmp(line, "ServerTokens"))
+ else if (!strcasecmp(line, "ServerTokens") && value)
{
/*
* Set the string used for the Server header...
cupsdLogMessage(CUPSD_LOG_WARN, "Unknown ServerTokens %s on line %d.",
value, linenum);
}
- else if (!strcasecmp(line, "PassEnv"))
+ else if (!strcasecmp(line, "PassEnv") && value)
{
/*
* PassEnv variable [... variable]
break;
}
}
- else if (!strcasecmp(line, "SetEnv"))
+ else if (!strcasecmp(line, "SetEnv") && value)
{
/*
* SetEnv variable value
* Unknown directive! Output an error message and continue...
*/
- cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown directive %s on line %d.",
- line, linenum);
+ if (!value)
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value for %s on line %d.",
+ line, linenum);
+ else
+ cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown directive %s on line %d.",
+ line, linenum);
continue;
}
break;
case CUPSD_VARTYPE_PATHNAME :
- if (value[0] == '/')
+ if (!value)
+ {
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Missing pathname value for %s on line %d!",
+ line, linenum);
+ break;
+ }
+
+ if (value[0] == '/')
strlcpy(temp, value, sizeof(temp));
else
snprintf(temp, sizeof(temp), "%s/%s", ServerRoot, value);
{
const char *server_bin; /* CUPS_SERVERBIN environment variable */
char program[1024]; /* Full path to backend */
- int fds[2]; /* Pipe file descriptors */
cupsd_backend_t *backend; /* Current backend */
+ char *argv[2]; /* Command-line arguments */
if (num_backends >= MAX_BACKENDS)
return (-1);
}
- if (pipe(fds))
- {
- fprintf(stderr, "ERROR: Unable to create a pipe for \"%s\" - %s\n",
- name, strerror(errno));
- return (-1);
- }
-
if ((server_bin = getenv("CUPS_SERVERBIN")) == NULL)
server_bin = CUPS_SERVERBIN;
backend = backends + num_backends;
- if ((backend->pid = fork()) < 0)
- {
- /*
- * Error!
- */
+ argv[0] = (char *)name;
+ argv[1] = NULL;
- fprintf(stderr, "ERROR: [cups-deviced] Unable to fork for \"%s\" - %s\n",
- program, strerror(errno));
- close(fds[0]);
- close(fds[1]);
- return (-1);
- }
- else if (!backend->pid)
+ if ((backend->pipe = cupsdPipeCommand(&(backend->pid), program, argv,
+ root ? 0 : normal_user)) == NULL)
{
- /*
- * Child comes here...
- */
-
- if (!getuid() && !root)
- setuid(normal_user); /* Run as restricted user */
-
- close(0); /* </dev/null */
- open("/dev/null", O_RDONLY);
-
- close(1); /* >pipe */
- dup(fds[1]);
-
- close(fds[0]); /* Close copies of pipes */
- close(fds[1]);
-
- execl(program, name, (char *)0); /* Run it! */
fprintf(stderr, "ERROR: [cups-deviced] Unable to execute \"%s\" - %s\n",
program, strerror(errno));
- exit(1);
+ return (-1);
}
/*
- * Parent comes here, allocate a backend and open the input side of the
- * pipe...
+ * Fill in the rest of the backend information...
*/
fprintf(stderr, "DEBUG: [cups-deviced] Started backend %s (PID %d)\n",
program, backend->pid);
- close(fds[1]);
-
- backend_fds[num_backends].fd = fds[0];
+ backend_fds[num_backends].fd = cupsFileNumber(backend->pipe);
backend_fds[num_backends].events = POLLIN;
backend->name = strdup(name);
backend->status = 0;
- backend->pipe = cupsFileOpenFd(fds[0], "r");
backend->count = 0;
active_backends ++;
*/
const char *serverbin; /* CUPS_SERVERBIN env var */
+ char *argv[4]; /* Arguments for program */
if ((serverbin = getenv("CUPS_SERVERBIN")) == NULL)
cupsdSendIPPTrailer();
}
- if (execl(line, scheme, "cat", name, (char *)NULL))
+ argv[0] = scheme;
+ argv[1] = (char *)"cat";
+ argv[2] = (char *)name;
+ argv[3] = NULL;
+
+ if (cupsdExec(line, argv))
{
/*
* Unable to execute driver...
*ptr; /* Pointer into string */
const char *server_bin; /* CUPS_SERVERBIN env variable */
char drivers[1024]; /* Location of driver programs */
- FILE *fp; /* Pipe to driver program */
+ int pid; /* Process ID for driver program */
+ cups_file_t *fp; /* Pipe to driver program */
cups_dir_t *dir; /* Directory pointer */
cups_dentry_t *dent; /* Directory entry */
- char filename[1024], /* Name of driver */
+ char *argv[3], /* Arguments for command */
+ filename[1024], /* Name of driver */
line[2048], /* Line from driver */
name[512], /* ppd-name */
make[128], /* ppd-make */
* Loop through all of the device drivers...
*/
+ argv[1] = (char *)"list";
+ argv[2] = NULL;
+
while ((dent = cupsDirRead(dir)) != NULL)
{
/*
* Run the driver with no arguments and collect the output...
*/
- snprintf(filename, sizeof(filename), "%s/%s list", drivers, dent->filename);
- if ((fp = popen(filename, "r")) != NULL)
+ argv[0] = dent->filename;
+ snprintf(filename, sizeof(filename), "%s/%s", drivers, dent->filename);
+
+ if ((fp = cupsdPipeCommand(&pid, filename, argv, 0)) != NULL)
{
- while (fgets(line, sizeof(line), fp) != NULL)
+ while (cupsFileGets(fp, line, sizeof(line)))
{
/*
* Each line is of the form:
if (type >= (int)(sizeof(ppd_types) / sizeof(ppd_types[0])))
{
- fprintf(stderr, "ERROR: [cups-driverd] Bad ppd-type \"%s\" ignored!\n",
+ fprintf(stderr,
+ "ERROR: [cups-driverd] Bad ppd-type \"%s\" ignored!\n",
type_str);
type = PPD_TYPE_UNKNOWN;
}
if (!ppd)
{
cupsDirClose(dir);
- pclose(fp);
+ cupsFileClose(fp);
return (0);
}
}
}
- pclose(fp);
+ cupsFileClose(fp);
}
else
fprintf(stderr, "WARNING: [cups-driverd] Unable to execute \"%s\": %s\n",
1);
if (!cupsGetOption("document-format", p->num_options, p->options))
- ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE,
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE,
"document-format-default", NULL, "application/octet-stream");
if (!cupsGetOption("job-hold-until", p->num_options, p->options))
*
* Mini-daemon utility functions for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2005 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
* Contents:
*
* cupsdCompareNames() - Compare two names.
+ * cupsdExec() - Run a program with the correct environment.
+ * cupsdPipeCommand() - Read output from a command.
* cupsdSendIPPGroup() - Send a group tag.
* cupsdSendIPPHeader() - Send the IPP response header.
* cupsdSendIPPInteger() - Send an integer attribute.
*/
#include "util.h"
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef __APPLE__
+# include <libgen.h>
+extern char **environ;
+#endif /* __APPLE__ */
/*
}
+/*
+ * 'cupsdExec()' - Run a program with the correct environment.
+ *
+ * On Mac OS X, we need to update the CFProcessPath environment variable that
+ * is passed in the environment so the child can access its bundled resources.
+ */
+
+int /* O - exec() status */
+cupsdExec(const char *command, /* I - Full path to program */
+ char **argv) /* I - Command-line arguments */
+{
+#ifdef __APPLE__
+ int i, j; /* Looping vars */
+ char *envp[500], /* Array of environment variables */
+ cfprocesspath[1024], /* CFProcessPath environment variable */
+ linkpath[1024]; /* Link path for symlinks... */
+ int linkbytes; /* Bytes for link path */
+
+
+ /*
+ * Some Mac OS X programs are bundled and need the CFProcessPath environment
+ * variable defined. If the command is a symlink, resolve the link and point
+ * to the resolved location, otherwise, use the command path itself.
+ */
+
+ if ((linkbytes = readlink(command, linkpath, sizeof(linkpath) - 1)) > 0)
+ {
+ /*
+ * Yes, this is a symlink to the actual program, nul-terminate and
+ * use it...
+ */
+
+ linkpath[linkbytes] = '\0';
+
+ if (linkpath[0] == '/')
+ snprintf(cfprocesspath, sizeof(cfprocesspath), "CFProcessPath=%s",
+ linkpath);
+ else
+ snprintf(cfprocesspath, sizeof(cfprocesspath), "CFProcessPath=%s/%s",
+ dirname((char *)command), linkpath);
+ }
+ else
+ snprintf(cfprocesspath, sizeof(cfprocesspath), "CFProcessPath=%s", command);
+
+ envp[0] = cfprocesspath;
+
+ /*
+ * Copy the rest of the environment except for any CFProcessPath that may
+ * already be there...
+ */
+
+ for (i = 1, j = 0;
+ environ[j] && i < (int)(sizeof(envp) / sizeof(envp[0]) - 1);
+ j ++)
+ if (strncmp(environ[j], "CFProcessPath=", 14))
+ envp[i ++] = environ[j];
+
+ envp[i] = NULL;
+
+ /*
+ * Use execve() to run the program...
+ */
+
+ return (execve(command, argv, envp));
+
+#else
+ /*
+ * On other operating systems, just call execv() to use the same environment
+ * variables as the parent...
+ */
+
+ return (execv(command, argv));
+#endif /* __APPLE__ */
+}
+
+
+/*
+ * 'cupsdPipeCommand()' - Read output from a command.
+ */
+
+cups_file_t * /* O - CUPS file or NULL on error */
+cupsdPipeCommand(int *pid, /* O - Process ID or 0 on error */
+ const char *command, /* I - Command to run */
+ char **argv, /* I - Arguments to pass to command */
+ int user) /* I - User to run as or 0 for current */
+{
+ int fds[2]; /* Pipe file descriptors */
+
+
+ /*
+ * First create the pipe...
+ */
+
+ if (pipe(fds))
+ {
+ *pid = 0;
+ return (NULL);
+ }
+
+ /*
+ * Set the "close on exec" flag on each end of the pipe...
+ */
+
+ if (fcntl(fds[0], F_SETFD, fcntl(fds[0], F_GETFD) | FD_CLOEXEC))
+ {
+ close(fds[0]);
+ close(fds[1]);
+
+ *pid = 0;
+
+ return (NULL);
+ }
+
+ if (fcntl(fds[1], F_SETFD, fcntl(fds[1], F_GETFD) | FD_CLOEXEC))
+ {
+ close(fds[0]);
+ close(fds[1]);
+
+ *pid = 0;
+
+ return (NULL);
+ }
+
+ /*
+ * Then run the command...
+ */
+
+ if ((*pid = fork()) < 0)
+ {
+ /*
+ * Unable to fork!
+ */
+
+ *pid = 0;
+ close(fds[0]);
+ close(fds[1]);
+
+ return (NULL);
+ }
+ else if (!*pid)
+ {
+ /*
+ * Child comes here...
+ */
+
+ if (!getuid() && user)
+ setuid(user); /* Run as restricted user */
+
+ close(0); /* </dev/null */
+ open("/dev/null", O_RDONLY);
+
+ close(1); /* >pipe */
+ dup(fds[1]);
+
+ cupsdExec(command, argv);
+ exit(errno);
+ }
+
+ /*
+ * Parent comes here, open the input side of the pipe...
+ */
+
+ close(fds[1]);
+
+ return (cupsFileOpenFd(fds[0], "r"));
+}
+
+
/*
* 'cupsdSendIPPGroup()' - Send a group tag.
*/
*
* Mini-daemon utility definitions for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007 by Apple Inc.
+ * Copyright 2007-2008 by Apple Inc.
* Copyright 1997-2005 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
* Prototypes...
*/
-extern int cupsdCompareNames(const char *s, const char *t);
-extern void cupsdSendIPPGroup(ipp_tag_t group_tag);
-extern void cupsdSendIPPHeader(ipp_status_t status_code, int request_id);
-extern void cupsdSendIPPInteger(ipp_tag_t value_tag, const char *name,
- int value);
-extern void cupsdSendIPPString(ipp_tag_t value_tag, const char *name,
- const char *value);
-extern void cupsdSendIPPTrailer(void);
+extern int cupsdCompareNames(const char *s, const char *t);
+extern int cupsdExec(const char *command, char **argv);
+extern cups_file_t *cupsdPipeCommand(int *pid, const char *command,
+ char **argv, int user);
+extern void cupsdSendIPPGroup(ipp_tag_t group_tag);
+extern void cupsdSendIPPHeader(ipp_status_t status_code,
+ int request_id);
+extern void cupsdSendIPPInteger(ipp_tag_t value_tag,
+ const char *name, int value);
+extern void cupsdSendIPPString(ipp_tag_t value_tag,
+ const char *name, const char *value);
+extern void cupsdSendIPPTrailer(void);
#endif /* !_CUPSD_UTIL_H_ */
if (ZEND_NUM_ARGS() != 2 ||
- zend_parse_parameters(2, "sl", &dest, &dest_len, &id))
+ zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &dest, &dest_len, &id))
{
WRONG_PARAM_COUNT;
}
if (ZEND_NUM_ARGS() != 3 ||
- zend_parse_parameters(3, "sll", &dest, &dest_len, &myjobs, &completed))
+ zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll", &dest, &dest_len, &myjobs, &completed))
{
WRONG_PARAM_COUNT;
}
if (ZEND_NUM_ARGS() != 4 ||
- zend_parse_parameters(4, "sssa", &dest, &dest_len,
+ zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sssa", &dest, &dest_len,
&filename, &filename_len,
&title, &title_len, &optionsobj))
{
if (ZEND_NUM_ARGS() != 4 ||
- zend_parse_parameters(4, "sasa", &dest, &dest_len, &filesobj,
+ zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sasa", &dest, &dest_len, &filesobj,
&title, &title_len, &optionsobj))
{
WRONG_PARAM_COUNT;
* Get the current active job on this queue...
*/
+ ipp_jstate_t jobstate = IPP_JOB_PENDING;
jobid = 0;
for (jobattr = jobs->attrs; jobattr; jobattr = jobattr->next)
{
if (!jobattr->name)
- continue;
+ {
+ if (jobstate == IPP_JOB_PROCESSING)
+ break;
+ else
+ continue;
+ }
if (!strcmp(jobattr->name, "job-id") &&
jobattr->value_tag == IPP_TAG_INTEGER)
jobid = jobattr->values[0].integer;
else if (!strcmp(jobattr->name, "job-state") &&
- jobattr->value_tag == IPP_TAG_ENUM &&
- jobattr->values[0].integer == IPP_JOB_PROCESSING)
- break;
+ jobattr->value_tag == IPP_TAG_ENUM)
+ jobstate = jobattr->values[0].integer;
}
+ if (jobstate != IPP_JOB_PROCESSING)
+ jobid = 0;
+
ippDelete(jobs);
}
}