Skip to content

Commit

Permalink
Merge pull request #235 from zdohnal/check_get_printattrs
Browse files Browse the repository at this point in the history
driverless, libcupsfilters: Check for driverless support and set device-info accordingly
  • Loading branch information
tillkamppeter authored May 19, 2020
2 parents 1712ee2 + 0004caa commit a917099
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 4 deletions.
41 changes: 41 additions & 0 deletions cupsfilters/ipp.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,20 @@ resolve_uri(const char *raw_uri)
}

#ifdef HAVE_CUPS_1_6
/* Check how the driverless support is provided */
int
check_driverless_support(const char* uri)
{
int support_status = DRVLESS_CHECKERR;
ipp_t *response = NULL;

response = get_printer_attributes3(NULL, uri, NULL, 0, NULL, 0, 1, &support_status);
if (response != NULL)
ippDelete(response);

return support_status;
}

/* Get attributes of a printer specified only by URI */
ipp_t *
get_printer_attributes(const char* raw_uri,
Expand All @@ -96,6 +110,23 @@ get_printer_attributes2(http_t *http_printer,
const char* const req_attrs[],
int req_attrs_size,
int debug)
{
return get_printer_attributes3(http_printer, raw_uri, pattrs, pattrs_size,
req_attrs, req_attrs_size, debug, NULL);
}

/* Get attributes of a printer specified by URI and under a given HTTP
connection, for example via a domain socket, and give info about used
fallbacks */
ipp_t *
get_printer_attributes3(http_t *http_printer,
const char* raw_uri,
const char* const pattrs[],
int pattrs_size,
const char* const req_attrs[],
int req_attrs_size,
int debug,
int* driverless_info)
{
const char *uri;
int have_http, uri_status, host_port, i = 0, total_attrs = 0, fallback,
Expand Down Expand Up @@ -139,6 +170,10 @@ get_printer_attributes2(http_t *http_printer,
"uri-security-supported"
};

/* Expect a device capable of standard IPP Everywhere*/
if (driverless_info != NULL)
*driverless_info = FULL_DRVLESS;

/* Request printer properties via IPP, for example to
- generate a PPD file for the printer
(mainly driverless-capable printers)
Expand Down Expand Up @@ -282,12 +317,18 @@ get_printer_attributes2(http_t *http_printer,
if (fallback == 1 + cap) {
log_printf(get_printer_attributes_log,
"No further fallback available, giving up\n");
if (driverless_info != NULL)
*driverless_info = DRVLESS_CHECKERR;
} else if (cap && fallback == 1) {
log_printf(get_printer_attributes_log,
"The server doesn't support the standard IPP request, trying request without media-col\n");
if (driverless_info != NULL)
*driverless_info = DRVLESS_INCOMPLETEIPP;
} else if (fallback == 0) {
log_printf(get_printer_attributes_log,
"The server doesn't support IPP2.0 request, trying IPP1.1 request\n");
if (driverless_info != NULL)
*driverless_info = DRVLESS_IPP11;
}
}

Expand Down
25 changes: 25 additions & 0 deletions cupsfilters/ipp.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,23 @@ char get_printer_attributes_log[LOGSIZE];

const char *resolve_uri(const char *raw_uri);
#ifdef HAVE_CUPS_1_6
/* Enum of possible driverless options */
enum driverless_support_modes {
DRVLESS_CHECKERR, /* Unable to get get-printer-attributes response*/
FULL_DRVLESS, /* Standard IPP Everywhere support, works with 'everywhere' model */
DRVLESS_IPP11, /* Driverless support via IPP 1.1 request */
DRVLESS_INCOMPLETEIPP /* Driverless support without media-col-database attribute */
};

/* Array of text strings explaining available driverless support */
const char * driverless_support_strs[] = {
"driverless - cannot check driverless status",
"fully driverless",
"driverless via IPP 1.1",
"driverless with incomplete IPP request"
};

int check_driverless_support(const char* uri);
ipp_t *get_printer_attributes(const char* raw_uri,
const char* const pattrs[],
int pattrs_size,
Expand All @@ -55,6 +72,14 @@ ipp_t *get_printer_attributes2(http_t *http_printer,
const char* const req_attrs[],
int req_attrs_size,
int debug);
ipp_t *get_printer_attributes3(http_t *http_printer,
const char* raw_uri,
const char* const pattrs[],
int pattrs_size,
const char* const req_attrs[],
int req_attrs_size,
int debug,
int* driverless_support);
#endif /* HAVE_CUPS_1_6 */

# ifdef __cplusplus
Expand Down
30 changes: 26 additions & 4 deletions utils/driverless.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ static void cancel_job(int sig);
int
list_printers (int mode)
{
int ippfind_pid, /* Process ID for ippfind */
int driverless_support = 0, /* Process ID for ippfind */
ippfind_pid, /* Process ID of ippfind */
post_proc_pid = 0, /* Process ID of post-processing */
post_proc_pipe[2], /* Pipe to post-processing */
wait_children, /* Number of child processes left */
Expand Down Expand Up @@ -75,6 +76,7 @@ list_printers (int mode)
make[512], /* Manufacturer */
model[256], /* Model */
pdl[256], /* PDL */
driverless_info[256], /* Driverless info string */
device_id[2048]; /* 1284 device ID */

/*
Expand Down Expand Up @@ -362,14 +364,34 @@ list_printers (int mode)
else
strncpy(make_and_model, model, sizeof(make_and_model) - 1);

/* Check which driverless support is available for the found device:
* 0) DRVLESS_CHECKERR - the device failed to respond
* to any get-printer-attributes request versions available.
* 1) FULL_DRVLESS - the device responded correctly to IPP 2.0 get-printer-attributes request.
* The device is compatible with CUPS 'everywhere' model.
* 2) DRVLESS_IPP11 - the device responded correctly to IPP 1.1 get-printer-attributes request.
* 3) DRVLESS_INCOMPLETEIPP - the device responded correctly to IPP get-printer-attributes request
* without media-col-database attribute
*
* If we know which driverless support is available, we can divide which devices can be supported
* by CUPS temporary queues and which devices need cups-browsed to run.
*/
driverless_support = check_driverless_support(service_uri);

if (driverless_support == DRVLESS_CHECKERR)
fprintf(stderr, "Failed to get info about driverless support.");

snprintf(driverless_info, 255, "%s", driverless_support_strs[driverless_support]);
driverless_info[255] = '\0';

if (mode == 1)
/* Call with "list" argument (PPD generator in list mode */
printf("\"driverless:%s\" en \"%s\" \"%s, driverless, cups-filters " VERSION
"\" \"%s\"\n", service_uri, make, make_and_model, device_id);
printf("\"driverless:%s\" en \"%s\" \"%s, %s, cups-filters " VERSION
"\" \"%s\"\n", service_uri, make, make_and_model, driverless_info, device_id);
else
/* Call without arguments and env variable "SOFTWARE" starting
with "CUPS" (Backend in discovery mode) */
printf("network %s \"%s\" \"%s (driverless)\" \"%s\" \"\"\n", service_uri, make_and_model, make_and_model, device_id);
printf("network %s \"%s\" \"%s (%s)\" \"%s\" \"\"\n", service_uri, make_and_model, make_and_model, driverless_info, device_id);

read_error:
continue;
Expand Down

0 comments on commit a917099

Please sign in to comment.