125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann/*
225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann * cupsGetDevices implementation for CUPS.
325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann *
425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann * Copyright 2008-2016 by Apple Inc.
525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann *
625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann * These coded instructions, statements, and computer programs are the
725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann * property of Apple Inc. and are protected by Federal copyright
825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann * which should have been included with this file.  If this file is
102447373f182dbfeb47fb86c0f5a6ac5773c65ac2Philip P. Moltmann * missing or damaged, see the license at "http://www.cups.org/".
1125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann *
1225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann * This file is subject to the Apple OS-Developed Software exception.
1325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann */
1425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
1525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann/*
1625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann * Include necessary headers...
1725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann */
1825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
1925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann#include "cups-private.h"
2025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann#include "adminutil.h"
2125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
2225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
2325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann/*
2425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann * 'cupsGetDevices()' - Get available printer devices.
2525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann *
2625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann * This function sends a CUPS-Get-Devices request and streams the discovered
2725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann * devices to the specified callback function. The "timeout" parameter controls
2825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann * how long the request lasts, while the "include_schemes" and "exclude_schemes"
2925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann * parameters provide comma-delimited lists of backends to include or omit from
3025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann * the request respectively.
3125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann *
3225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann * @since CUPS 1.4/macOS 10.6@
3325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann */
3425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
3525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmannipp_status_t				/* O - Request status - @code IPP_OK@ on success. */
3625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. MoltmanncupsGetDevices(
3725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    http_t           *http,		/* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
3825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    int              timeout,		/* I - Timeout in seconds or @code CUPS_TIMEOUT_DEFAULT@ */
3925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    const char       *include_schemes,	/* I - Comma-separated URI schemes to include or @code CUPS_INCLUDE_ALL@ */
4025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    const char       *exclude_schemes,	/* I - Comma-separated URI schemes to exclude or @code CUPS_EXCLUDE_NONE@ */
4125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    cups_device_cb_t callback,		/* I - Callback function */
4225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    void             *user_data)	/* I - User data pointer */
4325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann{
4425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  ipp_t		*request,		/* CUPS-Get-Devices request */
4525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann		*response;		/* CUPS-Get-Devices response */
4625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  ipp_attribute_t *attr;		/* Current attribute */
4725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  const char	*device_class,		/* device-class value */
4825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann		*device_id,		/* device-id value */
4925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann		*device_info,		/* device-info value */
5025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann		*device_location,	/* device-location value */
5125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann		*device_make_and_model,	/* device-make-and-model value */
5225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann		*device_uri;		/* device-uri value */
5325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  int		blocking;		/* Current blocking-IO mode */
5425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  cups_option_t	option;			/* in/exclude-schemes option */
5525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  http_status_t	status;			/* HTTP status of request */
5625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  ipp_state_t	state;			/* IPP response state */
5725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
5825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
5925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann /*
6025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  * Range check input...
6125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  */
6225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
6325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  DEBUG_printf(("cupsGetDevices(http=%p, timeout=%d, include_schemes=\"%s\", exclude_schemes=\"%s\", callback=%p, user_data=%p)", (void *)http, timeout, include_schemes, exclude_schemes, (void *)callback, user_data));
6425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
6525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  if (!callback)
6625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    return (IPP_STATUS_ERROR_INTERNAL);
6725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
6825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  if (!http)
6925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    http = _cupsConnect();
7025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
7125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  if (!http)
7225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    return (IPP_STATUS_ERROR_SERVICE_UNAVAILABLE);
7325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
7425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann /*
7525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  * Create a CUPS-Get-Devices request...
7625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  */
7725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
7825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  request = ippNewRequest(IPP_OP_CUPS_GET_DEVICES);
7925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
8025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  if (timeout > 0)
8125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "timeout",
8225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann                  timeout);
8325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
8425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  if (include_schemes)
8525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  {
8625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    option.name  = "include-schemes";
8725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    option.value = (char *)include_schemes;
8825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
8925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    cupsEncodeOptions2(request, 1, &option, IPP_TAG_OPERATION);
9025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  }
9125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
9225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  if (exclude_schemes)
9325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  {
9425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    option.name  = "exclude-schemes";
9525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    option.value = (char *)exclude_schemes;
9625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
9725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    cupsEncodeOptions2(request, 1, &option, IPP_TAG_OPERATION);
9825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  }
9925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
10025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann /*
10125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  * Send the request and do any necessary authentication...
10225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  */
10325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
10425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  do
10525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  {
10625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    DEBUG_puts("2cupsGetDevices: Sending request...");
10725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    status = cupsSendRequest(http, request, "/", ippLength(request));
10825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
10925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    DEBUG_puts("2cupsGetDevices: Waiting for response status...");
11025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    while (status == HTTP_STATUS_CONTINUE)
11125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann      status = httpUpdate(http);
11225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
11325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    if (status != HTTP_STATUS_OK)
11425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    {
11525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann      httpFlush(http);
11625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
11725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann      if (status == HTTP_STATUS_UNAUTHORIZED)
11825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann      {
11925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann       /*
12025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	* See if we can do authentication...
12125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	*/
12225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
12325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	DEBUG_puts("2cupsGetDevices: Need authorization...");
12425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
12525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	if (!cupsDoAuthentication(http, "POST", "/"))
12625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	  httpReconnect2(http, 30000, NULL);
12725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	else
12825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	{
12925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	  status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED;
13025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	  break;
13125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	}
13225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann      }
13325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
13425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann#ifdef HAVE_SSL
13525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann      else if (status == HTTP_STATUS_UPGRADE_REQUIRED)
13625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann      {
13725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann       /*
13825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	* Force a reconnect with encryption...
13925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	*/
14025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
14125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	DEBUG_puts("2cupsGetDevices: Need encryption...");
14225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
14325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	if (!httpReconnect2(http, 30000, NULL))
14425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	  httpEncryption(http, HTTP_ENCRYPTION_REQUIRED);
14525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann      }
14625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann#endif /* HAVE_SSL */
14725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    }
14825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  }
14925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  while (status == HTTP_STATUS_UNAUTHORIZED ||
15025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann         status == HTTP_STATUS_UPGRADE_REQUIRED);
15125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
15225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  DEBUG_printf(("2cupsGetDevices: status=%d", status));
15325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
15425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  ippDelete(request);
15525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
15625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  if (status != HTTP_STATUS_OK)
15725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  {
15825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    _cupsSetHTTPError(status);
15925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    return (cupsLastError());
16025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  }
16125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
16225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann /*
16325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  * Read the response in non-blocking mode...
16425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  */
16525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
16625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  blocking = httpGetBlocking(http);
16725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  httpBlocking(http, 0);
16825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
16925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  response              = ippNew();
17025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  device_class          = NULL;
17125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  device_id             = NULL;
17225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  device_info           = NULL;
17325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  device_location       = "";
17425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  device_make_and_model = NULL;
17525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  device_uri            = NULL;
17625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  attr                  = NULL;
17725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
17825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  DEBUG_puts("2cupsGetDevices: Reading response...");
17925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
18025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  do
18125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  {
18225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    if ((state = ippRead(http, response)) == IPP_STATE_ERROR)
18325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann      break;
18425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
18525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    DEBUG_printf(("2cupsGetDevices: state=%d, response->last=%p", state, (void *)response->last));
18625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
18725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    if (!response->attrs)
18825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann      continue;
18925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
19025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    while (attr != response->last)
19125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    {
19225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann      if (!attr)
19325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	attr = response->attrs;
19425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann      else
19525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann        attr = attr->next;
19625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
19725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann      DEBUG_printf(("2cupsGetDevices: attr->name=\"%s\", attr->value_tag=%d",
19825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann                    attr->name, attr->value_tag));
19925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
20025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann      if (!attr->name)
20125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann      {
20225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann        if (device_class && device_id && device_info && device_make_and_model &&
20325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	    device_uri)
20425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann          (*callback)(device_class, device_id, device_info,
20525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	              device_make_and_model, device_uri, device_location,
20625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann		      user_data);
20725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
20825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	device_class          = NULL;
20925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	device_id             = NULL;
21025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	device_info           = NULL;
21125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	device_location       = "";
21225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	device_make_and_model = NULL;
21325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann	device_uri            = NULL;
21425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann      }
21525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann      else if (!strcmp(attr->name, "device-class") &&
21625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann               attr->value_tag == IPP_TAG_KEYWORD)
21725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann        device_class = attr->values[0].string.text;
21825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann      else if (!strcmp(attr->name, "device-id") &&
21925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann               attr->value_tag == IPP_TAG_TEXT)
22025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann        device_id = attr->values[0].string.text;
22125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann      else if (!strcmp(attr->name, "device-info") &&
22225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann               attr->value_tag == IPP_TAG_TEXT)
22325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann        device_info = attr->values[0].string.text;
22425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann      else if (!strcmp(attr->name, "device-location") &&
22525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann               attr->value_tag == IPP_TAG_TEXT)
22625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann        device_location = attr->values[0].string.text;
22725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann      else if (!strcmp(attr->name, "device-make-and-model") &&
22825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann               attr->value_tag == IPP_TAG_TEXT)
22925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann        device_make_and_model = attr->values[0].string.text;
23025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann      else if (!strcmp(attr->name, "device-uri") &&
23125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann               attr->value_tag == IPP_TAG_URI)
23225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann        device_uri = attr->values[0].string.text;
23325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    }
23425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  }
23525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  while (state != IPP_STATE_DATA);
23625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
23725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  DEBUG_printf(("2cupsGetDevices: state=%d, response->last=%p", state, (void *)response->last));
23825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
23925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  if (device_class && device_id && device_info && device_make_and_model &&
24025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann      device_uri)
24125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    (*callback)(device_class, device_id, device_info,
24225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann		device_make_and_model, device_uri, device_location, user_data);
24325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
24425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann /*
24525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  * Set the IPP status and return...
24625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  */
24725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
24825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  httpBlocking(http, blocking);
24925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  httpFlush(http);
25025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
25125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  if (status == HTTP_STATUS_ERROR)
25225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(http->error), 0);
25325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  else
25425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  {
25525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    attr = ippFindAttribute(response, "status-message", IPP_TAG_TEXT);
25625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
25725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    DEBUG_printf(("cupsGetDevices: status-code=%s, status-message=\"%s\"",
25825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann		  ippErrorString(response->request.status.status_code),
25925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann		  attr ? attr->values[0].string.text : ""));
26025aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
26125aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann    _cupsSetError(response->request.status.status_code,
26225aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann		  attr ? attr->values[0].string.text :
26325aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann		      ippErrorString(response->request.status.status_code), 0);
26425aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  }
26525aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
26625aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  ippDelete(response);
26725aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann
26825aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann  return (cupsLastError());
26925aee82d491492e1fa3b005e5880e684dc081ffbPhilip P. Moltmann}
270