create_local_bg_thread(
    cupsd_printer_t *printer)		/* I - Printer */
{
  cups_file_t	*from,			/* Source file */
		*to;			/* Destination file */
  char		fromppd[1024],		/* Source PPD */
		toppd[1024],		/* Destination PPD */
		scheme[32],		/* URI scheme */
		userpass[256],		/* User:pass */
		host[256],		/* Hostname */
		resource[1024],		/* Resource path */
		line[1024];		/* Line from PPD */
  int		port;			/* Port number */
  http_encryption_t encryption;		/* Type of encryption to use */
  http_t	*http;			/* Connection to printer */
  ipp_t		*request,		/* Request to printer */
		*response;		/* Response from printer */
  ipp_attribute_t *attr;		/* Attribute in response */


 /*
  * Try connecting to the printer...
  */

  cupsdLogMessage(CUPSD_LOG_DEBUG, "%s: Generating PPD file from \"%s\"...", printer->name, printer->device_uri);

  if (httpSeparateURI(HTTP_URI_CODING_ALL, printer->device_uri, scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK)
  {
    cupsdLogMessage(CUPSD_LOG_ERROR, "%s: Bad device URI \"%s\".", printer->name, printer->device_uri);
    return (NULL);
  }

  if (!strcmp(scheme, "ipps") || port == 443)
    encryption = HTTP_ENCRYPTION_ALWAYS;
  else
    encryption = HTTP_ENCRYPTION_IF_REQUESTED;

  if ((http = httpConnect2(host, port, NULL, AF_UNSPEC, encryption, 1, 30000, NULL)) == NULL)
  {
    cupsdLogMessage(CUPSD_LOG_ERROR, "%s: Unable to connect to %s:%d: %s", printer->name, host, port, cupsLastErrorString());
    return (NULL);
  }

 /*
  * Query the printer for its capabilities...
  */

  cupsdLogMessage(CUPSD_LOG_DEBUG, "%s: Connected to %s:%d, sending Get-Printer-Attributes request...", printer->name, host, port);

  request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, printer->device_uri);
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", NULL, "all");

  response = cupsDoRequest(http, request, resource);

  cupsdLogMessage(CUPSD_LOG_DEBUG, "%s: Get-Printer-Attributes returned %s", printer->name, ippErrorString(cupsLastError()));

  // TODO: Grab printer icon file...
  httpClose(http);

 /*
  * Write the PPD for the queue...
  */

  if (_ppdCreateFromIPP(fromppd, sizeof(fromppd), response))
  {
    if ((!printer->info || !*(printer->info)) && (attr = ippFindAttribute(response, "printer-info", IPP_TAG_TEXT)) != NULL)
      cupsdSetString(&printer->info, ippGetString(attr, 0, NULL));

    if ((!printer->location || !*(printer->location)) && (attr = ippFindAttribute(response, "printer-location", IPP_TAG_TEXT)) != NULL)
      cupsdSetString(&printer->location, ippGetString(attr, 0, NULL));

    if ((!printer->geo_location || !*(printer->geo_location)) && (attr = ippFindAttribute(response, "printer-geo-location", IPP_TAG_URI)) != NULL)
      cupsdSetString(&printer->geo_location, ippGetString(attr, 0, NULL));

    if ((from = cupsFileOpen(fromppd, "r")) == NULL)
    {
      cupsdLogMessage(CUPSD_LOG_ERROR, "%s: Unable to read generated PPD: %s", printer->name, strerror(errno));
      return (NULL);
    }

    snprintf(toppd, sizeof(toppd), "%s/ppd/%s.ppd", ServerRoot, printer->name);
    if ((to = cupsdCreateConfFile(toppd, ConfigFilePerm)) == NULL)
    {
      cupsdLogMessage(CUPSD_LOG_ERROR, "%s: Unable to create PPD for printer: %s", printer->name, strerror(errno));
      cupsFileClose(from);
      return (NULL);
    }

    while (cupsFileGets(from, line, sizeof(line)))
      cupsFilePrintf(to, "%s\n", line);

    cupsFileClose(from);
    if (!cupsdCloseCreatedConfFile(to, toppd))
    {
      printer->config_time = time(NULL);
      printer->state       = IPP_PSTATE_IDLE;
      printer->accepting   = 1;

      cupsdSetPrinterAttrs(printer);

      cupsdAddEvent(CUPSD_EVENT_PRINTER_CONFIG, printer, NULL, "Printer \"%s\" is now available.", printer->name);
      cupsdLogMessage(CUPSD_LOG_INFO, "Printer \"%s\" is now available.", printer->name);
    }
  }
  else
    cupsdLogMessage(CUPSD_LOG_ERROR, "%s: PPD creation failed: %s", printer->name, cupsLastErrorString());

  return (NULL);
}