[cups.development] notifier - Get-Job-Attributes client-error-bad-request
Rodger Devine
rdevine at umich.edu
Wed Apr 21 11:49:13 PDT 2010
In article <5088-cups.development at news.easysw.com>,
Michael Sweet <msweet at apple.com> wrote:
> On Apr 13, 2010, at 2:05 PM, Rodger Devine wrote:
> > ...
> > using ippNew() with ipp->request.op.operation_id = IP_GET_JOB_ATTRIBUTES
> > and ipp->request.op.request_id = 1
>
> Use ippNewRequest(IPP_GET_JOB_ATTRIBUTES)...
>
> > ########################################################################
> > Apr 13 16:34:58 server cupsd[9912]: Get-Job-Attributes
> > client-error-bad-request: Attribute groups are out of order (1 < 7)!
>
> That sounds like you aren't adding attributes in the right order or group -
> can you provide the code that creates the request?
>
> ________________________________________________________________________
> Michael Sweet, Senior Printing System Engineer, PWG Chair
Thanks for help thus far. Regarding my previous notifier inquiries, I've
been able to use the ippNewRequest(IPP_GET_JOB_ATTRIBUTES) function you
previously suggested to retrieve the additional attributes we need (i.e.
username, jobsize, and jobtime).
However, I've run into a 12-byte memory leak in our notifier, which I've
isolated to the following code (borrowed from lpq.c):
....
if (response->request.status.status_code > IPP_OK_CONFLICT)
{
fprintf(stderr, "jnotify: %s\n", cupsLastErrorString());
ippDelete(response);
return(0);
}
....
In a nutshell, we'd like to incorporate functionality *somewhat* similar
to the lpq -a +1 command (report job status on all printers) to store
job and printer status info into a database.
We've used the testnotify.c scaffolding as follows:
{
event = ippNew();
while ((state = ippReadFile(0, event)) != IPP_DATA)
{
if (state <= IPP_IDLE)
break;
}
if (state == IPP_ERROR) {
fputs("There was an IPP read error. Exiting.", stderr);
exit(IPP_ERROR);
}
if (state <= IPP_IDLE) {
ippDelete(event);
return (0);
}
store_event(event);
ippDelete(event);
}
Our store_event function reads the IPP request (i.e. event) and uses the
ippFindAttribute function to retrieve values for job-name, printer-name,
job-id, job-impressions-completed, etc.
Once we retrieve these values, we connect to the scheduler and make
another IPP request by job-id:
store_event(ipp_t *ipp){
....
/* Get first round of attributes */
....
/* Build IPP_GET_JOB_ATTRIBUTES request to retrieve additional job
attributes */
ipp = ippNewRequest(IPP_GET_JOB_ATTRIBUTES);
snprintf(resource, sizeof(resource), "ipp://localhost/jobs/%d",
notify_job_id);
ippAddString(ipp, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL,
resource);
/* Connect to HTTP server (scheduler) */
http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
if (http == NULL)
{
perror("Unable to connect to server");
return(1);
}
/* Make IPP request to CUPS Scheduler */
if ((response = cupsDoRequest(http, ipp, "/")) != NULL)
{
if (response->request.status.status_code > IPP_OK_CONFLICT)
{
fprintf(stderr, "jnotify: %s\n", cupsLastErrorString());
ippDelete(response);
return(0);
}
/* Retrieve user that printed the job */
.....
It is my understanding the ipp_t types (i.e. event, response) must be
explicitly deleted using ippDelete(). In this instance, I'm encountering
the 12-byte leak inside the first check:
response->request.status.status_code > IPP_OK_CONFLICT.
A few questions:
Is it legal to call ippNewRequest(IPP_GET_JOB_ATTRIBUTES) and store the
ipp_t pointer into the same variable as the original IPP request (event
= ippNew())?
Any clues as to why we might be running issues with the
ippDelete(response)?
Incidentally, I've also noticed that user-name is not returned when I
add the ippDelete(response) at the end of the cupdDoRequest loop as I
presume we should.
Rodger
More information about the cups-devel
mailing list