Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2.3] papd: update cups_get_printer_status() #696

Merged
266 changes: 116 additions & 150 deletions etc/papd/print_cups.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@

static const char* cups_status_msg[] = {
"status: busy; info: \"%s\" is rejecting jobs; ",
"status: idle; info: \"%s\" is stopped, accepting jobs ;",
"status: idle; info: \"%s\" is stopped, accepting jobs ; ",
"status: idle; info: \"%s\" is ready ; ",
"status: busy; info: \"%s\" is processing a job ; ",
};

/* Local functions */
Expand Down Expand Up @@ -121,56 +122,8 @@ cups_printername_ok(char *name) /* I - Name of printer */
"Unable to connect to destination \"%s\": %s", dest->name, cupsLastErrorString());
return (0);
}


/*
* Build an IPP_GET_PRINTER_ATTRS request, which requires the following
* attributes:
*
* attributes-charset
* attributes-natural-language
* requested-attributes
* printer-uri
*/
request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);

ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
"requested-attributes", NULL, "printer-uri");

const char *uri = cupsGetOption("printer-uri-supported", dest->num_options, dest->options);

ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
"printer-uri", NULL, uri);

/*
* Do the request and get back a response...
*/

if ((response = cupsDoRequest(http, request, "/")) == NULL)
{
LOG(log_error, logtype_papd, "Unable to get printer status for %s - %s", name,
ippErrorString(cupsLastError()));
cupsFreeDests(1, dest);
httpClose(http);
return (0);
}
cupsFreeDests(1, dest);
httpClose(http);

if (cupsLastError() >= IPP_STATUS_OK_CONFLICTING)
{
LOG(log_error, logtype_papd, "Unable to get printer status for %s - %s", name,
ippErrorString(cupsLastError()));
ippDelete(response);
return (0);
}
else
{
ippDelete(response);
return (1);
}

return (0);
return (1);
}

const char *
Expand Down Expand Up @@ -365,131 +318,151 @@ cups_get_printer_ppd ( char * name)
int
cups_get_printer_status (struct printer *pr)
{

http_t *http; /* HTTP connection to server */
cups_dest_t *dest = NULL; /* Destination */
ipp_t *request, /* IPP Request */
*response; /* IPP Response */
ipp_attribute_t *attr; /* Current attribute */
http_t* http; /* HTTP connection to server */
cups_dest_t* dest = NULL; /* Destination */
int status = -1;
char printer_reason[150];
memset(printer_reason, 0, sizeof(printer_reason));
int printer_avail = 0;
int printer_state = 3;
unsigned flags;

static const char *pattrs[] = /* Requested printer attributes */
{
"printer-state",
"printer-state-message",
"printer-is-accepting-jobs"
};

/*
* Make sure we don't ask for passwords...
*/
/*
* Make sure we don't ask for passwords...
*/

cupsSetPasswordCB2(cups_passwd_cb, NULL);
cupsSetPasswordCB2(cups_passwd_cb, NULL);

/*
* Try to connect to the requested printer...
*/

dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, pr->p_printer, NULL);

if (!dest)
{
LOG(log_error, logtype_papd,
"Unable to get destination \"%s\": %s", pr->p_printer, cupsLastErrorString());
"Unable to get destination \"%s\": %s", pr->p_printer, cupsLastErrorString());
snprintf(pr->p_status, 255, "status: busy; info: \"%s\" appears to be offline.", pr->p_printer);
return (0);
}
if ((http = cupsConnectDest(dest, CUPS_DEST_FLAGS_NONE, 30000, NULL, NULL, 0, NULL, NULL)) == NULL)

/*
* Collect the needed attributes...
*/
const char* printer_uri_supported = cupsGetOption("printer-uri-supported", dest->num_options, dest->options);
const char* printer_is_temporary = cupsGetOption("printer-is-temporary", dest->num_options, dest->options);

memset(pr->p_status, 0, sizeof(pr->p_status));
if (!printer_uri_supported || !strcmp(printer_is_temporary, "true")) /* DNS-SD discovered IPP printer: Get status directly from printer */
flags = CUPS_DEST_FLAGS_DEVICE;
else
flags = CUPS_DEST_FLAGS_NONE;

if ((http = cupsConnectDest(dest, flags, 30000, NULL, NULL, 0, NULL, NULL)) == NULL)
{
LOG(log_error, logtype_papd,
"Unable to connect to destination \"%s\": %s", dest->name, cupsLastErrorString());
"Unable to connect to destination \"%s\": %s", dest->name, cupsLastErrorString());
snprintf(pr->p_status, 255, "status: busy; info: \"%s\" appears to be offline.", pr->p_printer);
cupsFreeDests(1, dest);
return (0);
}
ipp_t * request, /* IPP Request */
* response; /* IPP Response */
const char* pattrs[] = /* Requested printer attributes */
{
"printer-state",
"printer-is-accepting-jobs",
"printer-state-reasons"
};

ipp_attribute_t* attr;

/*
* Generate the printer URI...
*/

const char *uri = cupsGetOption("printer-uri-supported", dest->num_options, dest->options);



/*
* Build an IPP_OP_GET_PRINTER_ATTRIBUTES request, which requires the
* following attributes:
*
* attributes-charset
* attributes-natural-language
* requested-attributes
* printer-uri
*/

request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
/*
* Build an IPP_OP_GET_PRINTER_ATTRIBUTES request, which requires the
* following attributes:
*
* requested-attributes
* printer-uri
*/

ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
"requested-attributes",
(sizeof(pattrs) / sizeof(pattrs[0])),
NULL, pattrs);
request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
const char* uri = cupsGetOption("device-uri", dest->num_options, dest->options);

ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
"printer-uri", NULL, uri);
if (flags == CUPS_DEST_FLAGS_DEVICE)
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
"printer-uri", NULL, uri);
else
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
"printer-uri", NULL, printer_uri_supported);

/*
* Do the request and get back a response...
*/
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
"requested-attributes",
(sizeof(pattrs) / sizeof(pattrs[0])), NULL, pattrs);

if ((response = cupsDoRequest(http, request, "/")) == NULL)
{
LOG(log_error, logtype_papd, "Unable to get printer status for %s - %s", pr->p_printer,
ippErrorString(cupsLastError()));
cupsFreeDests(1, dest);
httpClose(http);
return (0);
}
/*
* Do the request and get back a response...
*/

if (cupsLastError() >= IPP_STATUS_OK_CONFLICTING)
{
LOG(log_error, logtype_papd, "Unable to get printer status for %s - %s", pr->p_printer,
ippErrorString(cupsLastError()));
ippDelete(response);
if ((response = cupsDoRequest(http, request, "/")) == NULL)
{
/* Printer didn't respond to status request. Don't block print jobs as the scheduler will handle them */
LOG(log_error, logtype_papd, "Unable to get printer attribs for %s - %s", pr->p_printer,
ippErrorString(cupsLastError()));
snprintf(pr->p_status, 255, "status: busy; info: \"%s\" not responding to queries.", pr->p_printer);
httpClose(http);
cupsFreeDests(1, dest);
httpClose(http);
return (0);
}

/*
* Get the current printer status and convert it to the status values.
*/
return (1);
}
if ((attr = ippFindAttribute(response, "printer-state",
IPP_TAG_ENUM)) != NULL)
{
printer_state = ippGetInteger(attr, 0);
}
if ((attr = ippFindAttribute(response, "printer-is-accepting-jobs",
IPP_TAG_BOOLEAN)) != NULL)
{
printer_avail = ippGetBoolean(attr, 0);
}
if ((attr = ippFindAttribute(response, "printer-state-reasons",
IPP_TAG_KEYWORD)) != NULL)
{
int i, count = ippGetCount(attr);
for (i = 0; i < count; i++)
{
strncat(printer_reason, ippGetString(attr, i, NULL), 150 - strlen(printer_reason));
if ( i != (count-1))
strncat(printer_reason, ", ", 150 - strlen(printer_reason));
}
}
ippDelete(response);
httpClose(http);

memset ( pr->p_status, 0 ,sizeof(pr->p_status));
/*
* Get the current printer status and convert it to the status values.
*/

if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL)
{
if (ippGetInteger(attr, 0) == IPP_PSTATE_STOPPED)
status = 1;
else if (ippGetInteger(attr,0) == IPP_STATUS_ERROR_NOT_ACCEPTING_JOBS)
status = 0;
else
status = 2;
}
if (printer_state == 5) /* printer is stopped */
status = 1;
else if (printer_state == 4) /* printer is processing a job */
status = 3;
else /* ready */
status = 2;

if ((attr = ippFindAttribute(response, "printer-is-accepting-jobs", IPP_TAG_BOOLEAN)) != NULL)
{
if ( ippGetBoolean(attr, 0) == 0 )
status = 0;
}

snprintf ( pr->p_status, 255, cups_status_msg[status], pr->p_printer );
if (!printer_avail && printer_state != 4)
status = 0; /* printer is rejecting jobs */

if ((attr = ippFindAttribute(response, "printer-state-message", IPP_TAG_TEXT)) != NULL)
strncat ( pr->p_status, ippGetString(attr, 0, NULL), 255-strlen(pr->p_status));
snprintf(pr->p_status, 255, cups_status_msg[status], pr->p_printer);

ippDelete(response);
/* printer state */
if (!strcmp(printer_reason, "none\n"))
strncat(pr->p_status, printer_reason, 255 - strlen(pr->p_status));

/*
* Return the print status ...
*/

/*
* Return the print status ...
*/
cupsFreeDests(1, dest);
httpClose(http);

return (status);
}

Expand Down Expand Up @@ -531,13 +504,6 @@ int cups_print_job ( char * name, char *filename, char *job, char *username, cha
cupsFreeDests(1,dest);
return (0);
}
if ((http = cupsConnectDest(dest, CUPS_DEST_FLAGS_NONE, 30000, NULL, NULL, 0, NULL, NULL)) == NULL)
{
LOG(log_error, logtype_papd,
"Unable to connect to destination \"%s\": %s", dest->name, cupsLastErrorString());
cupsFreeDests(1,dest);
return (0);
}

info = cupsCopyDestInfo(CUPS_HTTP_DEFAULT, dest);

Expand Down