}
#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,
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,
"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)
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;
}
}
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,
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
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 */
make[512], /* Manufacturer */
model[256], /* Model */
pdl[256], /* PDL */
+ driverless_info[256], /* Driverless info string */
device_id[2048]; /* 1284 device ID */
/*
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;