diff options
author | Michael Sweet <michael.r.sweet@gmail.com> | 2017-05-26 14:04:45 -0400 |
---|---|---|
committer | Michael Sweet <michael.r.sweet@gmail.com> | 2017-05-26 14:04:45 -0400 |
commit | 4a366251171ae1125900f3b099a9fb33efdd091f (patch) | |
tree | c9e97f0503e065e172de229db9322cceea762ea1 /cups/dest.c | |
parent | 9022d60bbde151c462741887ae704117aa57f6d1 (diff) | |
download | cups-4a366251171ae1125900f3b099a9fb33efdd091f.tar.gz |
Add support for lp and lpr to print to network printers that haven't been added
yet (Issue #5006)
Diffstat (limited to 'cups/dest.c')
-rw-r--r-- | cups/dest.c | 126 |
1 files changed, 104 insertions, 22 deletions
diff --git a/cups/dest.c b/cups/dest.c index e30396b73..e7eccf01f 100644 --- a/cups/dest.c +++ b/cups/dest.c @@ -120,13 +120,18 @@ typedef struct _cups_dnssd_resolve_s /* Data for resolving URI */ } _cups_dnssd_resolve_t; #endif /* HAVE_DNSSD */ - typedef struct _cups_getdata_s { int num_dests; /* Number of destinations */ cups_dest_t *dests; /* Destinations */ } _cups_getdata_t; +typedef struct _cups_namedata_s +{ + const char *name; /* Named destination */ + cups_dest_t *dest; /* Destination */ +} _cups_namedata_t; + /* * Local functions... @@ -233,6 +238,7 @@ static int cups_get_dests(const char *filename, const char *match_name, int num_dests, cups_dest_t **dests); static char *cups_make_string(ipp_attribute_t *attr, char *buffer, size_t bufsize); +static int cups_name_cb(_cups_namedata_t *data, unsigned flags, cups_dest_t *dest); static void cups_queue_name(char *name, const char *serviceName, size_t namesize); @@ -1460,36 +1466,58 @@ _cupsGetDestResource( * Grab the printer URI... */ - if ((uri = cupsGetOption("printer-uri-supported", dest->num_options, - dest->options)) == NULL) + if ((uri = cupsGetOption("printer-uri-supported", dest->num_options, dest->options)) == NULL) { - DEBUG_puts("1_cupsGetDestResource: No printer-uri-supported found."); + if ((uri = cupsGetOption("resolved-device-uri", dest->num_options, dest->options)) == NULL) + { + if ((uri = cupsGetOption("device-uri", dest->num_options, dest->options)) != NULL) + { +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI) + if (strstr(uri, "._tcp")) + uri = cups_dnssd_resolve(dest, uri, 5000, NULL, NULL, NULL); +#endif /* HAVE_DNSSD || HAVE_AVAHI */ + } + } - if (resource) - *resource = '\0'; + if (uri) + { + DEBUG_printf(("1_cupsGetDestResource: Resolved printer-uri-supported=\"%s\"", uri)); - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOENT), 0); + uri = _cupsCreateDest(dest->name, cupsGetOption("printer-info", dest->num_options, dest->options), NULL, uri, resource, resourcesize); + } - return (NULL); - } + if (uri) + { + DEBUG_printf(("1_cupsGetDestResource: Local printer-uri-supported=\"%s\"", uri)); - DEBUG_printf(("1_cupsGetDestResource: printer-uri-supported=\"%s\"", uri)); + dest->num_options = cupsAddOption("printer-uri-supported", uri, dest->num_options, &dest->options); + + uri = cupsGetOption("printer-uri-supported", dest->num_options, dest->options); + } + else + { + DEBUG_puts("1_cupsGetDestResource: No printer-uri-supported found."); + + if (resource) + *resource = '\0'; + + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOENT), 0); -#ifdef HAVE_DNSSD - if (strstr(uri, "._tcp")) - { - if ((uri = cups_dnssd_resolve(dest, uri, 5000, NULL, NULL, NULL)) == NULL) return (NULL); + } } -#endif /* HAVE_DNSSD */ - - if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), - userpass, sizeof(userpass), hostname, sizeof(hostname), - &port, resource, (int)resourcesize) < HTTP_URI_STATUS_OK) + else { - _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad printer-uri."), 1); + DEBUG_printf(("1_cupsGetDestResource: printer-uri-supported=\"%s\"", uri)); - return (NULL); + if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), + userpass, sizeof(userpass), hostname, sizeof(hostname), + &port, resource, (int)resourcesize) < HTTP_URI_STATUS_OK) + { + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Bad printer-uri."), 1); + + return (NULL); + } } DEBUG_printf(("1_cupsGetDestResource: resource=\"%s\"", resource)); @@ -1682,6 +1710,8 @@ _cupsGetDests(http_t *http, /* I - Connection to server or }; + DEBUG_printf(("_cupsGetDests(http=%p, op=%x(%s), name=\"%s\", dests=%p, type=%x, mask=%x)", http, op, ippOpString(op), name, dests, type, mask)); + #ifdef __APPLE__ /* * Get the default paper size... @@ -2111,6 +2141,8 @@ cupsGetNamedDest(http_t *http, /* I - Connection to server or @code CUPS_HTT _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ + DEBUG_printf(("cupsGetNamedDest(http=%p, name=\"%s\", instance=\"%s\")", http, name, instance)); + /* * If "name" is NULL, find the default destination... */ @@ -2161,7 +2193,11 @@ cupsGetNamedDest(http_t *http, /* I - Connection to server or @code CUPS_HTT */ op = IPP_OP_CUPS_GET_DEFAULT; + + DEBUG_puts("1cupsGetNamedDest: Asking server for default printer..."); } + else + DEBUG_printf(("1cupsGetNamedDest: Using name=\"%s\"...", name)); } /* @@ -2169,7 +2205,28 @@ cupsGetNamedDest(http_t *http, /* I - Connection to server or @code CUPS_HTT */ if (!_cupsGetDests(http, op, name, &dest, 0, CUPS_PRINTER_3D)) - return (NULL); + { + if (name) + { + _cups_namedata_t data; /* Callback data */ + + DEBUG_puts("1cupsGetNamedDest: No queue found for printer, looking on network..."); + + data.name = name; + data.dest = NULL; + + cupsEnumDests(0, 1000, NULL, 0, CUPS_PRINTER_3D, (cups_dest_cb_t)cups_name_cb, &data); + + if (!data.dest) + return (NULL); + + dest = data.dest; + } + else + return (NULL); + } + + DEBUG_printf(("1cupsGetNamedDest: Got dest=%p", dest)); if (instance) dest->instance = _cupsStrAlloc(instance); @@ -4196,6 +4253,31 @@ cups_make_string( /* + * 'cups_name_cb()' - Find an enumerated destination. + */ + +static int /* O - 1 to continue, 0 to stop */ +cups_name_cb(_cups_namedata_t *data, /* I - Data from cupsGetNamedDest */ + unsigned flags, /* I - Enumeration flags */ + cups_dest_t *dest) /* I - Destination */ +{ + DEBUG_printf(("2cups_name_cb(data=%p(%s), flags=%x, dest=%p(%s)", data, data->name, flags, dest, dest->name)); + + if (!(flags & CUPS_DEST_FLAGS_REMOVED) && !dest->instance && !strcasecmp(data->name, dest->name)) + { + /* + * Copy destination and stop enumeration... + */ + + cupsCopyDest(dest, 0, &data->dest); + return (0); + } + + return (1); +} + + +/* * 'cups_queue_name()' - Create a local queue name based on the service name. */ |