Exemplo n.º 1
0
void
cupsEncodeOptions(ipp_t         *ipp,		/* I - Request to add to */
        	  int           num_options,	/* I - Number of options */
		  cups_option_t *options)	/* I - Options */
{
  DEBUG_printf(("cupsEncodeOptions(%p, %d, %p)", ipp, num_options, options));

 /*
  * Add the options in the proper groups & order...
  */

  cupsEncodeOptions2(ipp, num_options, options, IPP_TAG_OPERATION);
  cupsEncodeOptions2(ipp, num_options, options, IPP_TAG_JOB);
  cupsEncodeOptions2(ipp, num_options, options, IPP_TAG_SUBSCRIPTION);
}
Exemplo n.º 2
0
http_status_t				/* O - Status of document creation */
cupsStartDestDocument(
    http_t        *http,		/* I - Connection to destination */
    cups_dest_t   *dest,		/* I - Destination */
    cups_dinfo_t  *info, 		/* I - Destination information */
    int           job_id,		/* I - Job ID */
    const char    *docname,		/* I - Document name */
    const char    *format,		/* I - Document format */
    int           num_options,		/* I - Number of document options */
    cups_option_t *options,		/* I - Document options */
    int           last_document)	/* I - 1 if this is the last document */
{
  ipp_t		*request;		/* Send-Document request */
  http_status_t	status;			/* HTTP status */


  DEBUG_printf(("cupsStartDestDocument(http=%p, dest=%p(%s/%s), info=%p, "
                "job_id=%d, docname=\"%s\", format=\"%s\", num_options=%d, "
                "options=%p, last_document=%d)",
                http, dest, dest ? dest->name : NULL,
                dest ? dest->instance : NULL, info, job_id, docname, format,
                num_options, options, last_document));

 /*
  * Range check input...
  */

  if (!http || !dest || !info || job_id <= 0)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    DEBUG_puts("1cupsStartDestDocument: Bad arguments.");
    return (HTTP_STATUS_ERROR);
  }

 /*
  * Create a Send-Document request...
  */

  if ((request = ippNewRequest(IPP_OP_SEND_DOCUMENT)) == NULL)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOMEM), 0);
    DEBUG_puts("1cupsStartDestDocument: Unable to create Send-Document "
               "request.");
    return (HTTP_STATUS_ERROR);
  }

  ippSetVersion(request, info->version / 10, info->version % 10);

  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
               NULL, info->uri);
  ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job_id);
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
               NULL, cupsUser());
  if (docname)
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "document-name",
                 NULL, docname);
  if (format)
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE,
                 "document-format", NULL, format);
  ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", last_document);

  cupsEncodeOptions2(request, num_options, options, IPP_TAG_OPERATION);
  cupsEncodeOptions2(request, num_options, options, IPP_TAG_DOCUMENT);

 /*
  * Send and delete the request, then return the status...
  */

  status = cupsSendRequest(http, request, info->resource, CUPS_LENGTH_VARIABLE);

  ippDelete(request);

  return (status);
}
Exemplo n.º 3
0
ipp_status_t				/* O - IPP status code */
cupsCreateDestJob(
    http_t        *http,		/* I - Connection to destination */
    cups_dest_t   *dest,		/* I - Destination */
    cups_dinfo_t  *info, 		/* I - Destination information */
    int           *job_id,		/* O - Job ID or 0 on error */
    const char    *title,		/* I - Job name */
    int           num_options,		/* I - Number of job options */
    cups_option_t *options)		/* I - Job options */
{
  ipp_t			*request,	/* Create-Job request */
			*response;	/* Create-Job response */
  ipp_attribute_t	*attr;		/* job-id attribute */


  DEBUG_printf(("cupsCreateDestJob(http=%p, dest=%p(%s/%s), info=%p, "
                "job_id=%p, title=\"%s\", num_options=%d, options=%p)",
                http, dest, dest ? dest->name : NULL,
                dest ? dest->instance : NULL, info, job_id, title, num_options,
                options));

 /*
  * Range check input...
  */

  if (job_id)
    *job_id = 0;

  if (!http || !dest || !info || !job_id)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    DEBUG_puts("1cupsCreateDestJob: Bad arguments.");
    return (IPP_STATUS_ERROR_INTERNAL);
  }

 /*
  * Build a Create-Job request...
  */

  if ((request = ippNewRequest(IPP_OP_CREATE_JOB)) == NULL)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOMEM), 0);
    DEBUG_puts("1cupsCreateDestJob: Unable to create Create-Job request.");
    return (IPP_STATUS_ERROR_INTERNAL);
  }

  ippSetVersion(request, info->version / 10, info->version % 10);

  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
               NULL, info->uri);
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
               NULL, cupsUser());
  if (title)
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL,
                 title);

  cupsEncodeOptions2(request, num_options, options, IPP_TAG_OPERATION);
  cupsEncodeOptions2(request, num_options, options, IPP_TAG_JOB);
  cupsEncodeOptions2(request, num_options, options, IPP_TAG_SUBSCRIPTION);

 /*
  * Send the request and get the job-id...
  */

  response = cupsDoRequest(http, request, info->resource);

  if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) != NULL)
  {
    *job_id = attr->values[0].integer;
    DEBUG_printf(("1cupsCreateDestJob: job-id=%d", *job_id));
  }

  ippDelete(response);

 /*
  * Return the status code from the Create-Job request...
  */

  DEBUG_printf(("1cupsCreateDestJob: %s (%s)", ippErrorString(cupsLastError()),
                cupsLastErrorString()));

  return (cupsLastError());
}
Exemplo n.º 4
0
void
cupsEncodeOptions2(
    ipp_t         *ipp,			/* I - Request to add to */
    int           num_options,		/* I - Number of options */
    cups_option_t *options,		/* I - Options */
    ipp_tag_t     group_tag)		/* I - Group to encode */
{
  int		i, j;			/* Looping vars */
  int		count;			/* Number of values */
  char		*s,			/* Pointer into option value */
		*val,			/* Pointer to option value */
		*copy,			/* Copy of option value */
		*sep,			/* Option separator */
		quote;			/* Quote character */
  ipp_attribute_t *attr;		/* IPP attribute */
  ipp_tag_t	value_tag;		/* IPP value tag */
  cups_option_t	*option;		/* Current option */
  ipp_t		*collection;		/* Collection value */
  int		num_cols;		/* Number of collection values */
  cups_option_t	*cols;			/* Collection values */


  DEBUG_printf(("cupsEncodeOptions2(ipp=%p, num_options=%d, options=%p, "
                "group_tag=%x)", ipp, num_options, options, group_tag));

 /*
  * Range check input...
  */

  if (!ipp || num_options < 1 || !options)
    return;

 /*
  * Do special handling for the document-format/raw options...
  */

  if (group_tag == IPP_TAG_OPERATION)
  {
   /*
    * Handle the document format stuff first...
    */

    if ((val = (char *)cupsGetOption("document-format", num_options, options)) != NULL)
      ippAddString(ipp, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format",
        	   NULL, val);
    else if (cupsGetOption("raw", num_options, options))
      ippAddString(ipp, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format",
        	   NULL, "application/vnd.cups-raw");
    else
      ippAddString(ipp, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format",
        	   NULL, "application/octet-stream");
  }

 /*
  * Then loop through the options...
  */

  for (i = num_options, option = options; i > 0; i --, option ++)
  {
    _ipp_option_t	*match;		/* Matching attribute */


   /*
    * Skip document format options that are handled above...
    */

    if (!_cups_strcasecmp(option->name, "raw") ||
        !_cups_strcasecmp(option->name, "document-format") ||
	!option->name[0])
      continue;

   /*
    * Figure out the proper value and group tags for this option...
    */

    if ((match = _ippFindOption(option->name)) != NULL)
    {
      if (match->group_tag != group_tag)
        continue;

      value_tag = match->value_tag;
    }
    else
    {
      int	namelen;		/* Length of name */


      namelen = (int)strlen(option->name);

      if (namelen < 9 || strcmp(option->name + namelen - 8, "-default"))
      {
	if (group_tag != IPP_TAG_JOB)
          continue;
      }
      else if (group_tag != IPP_TAG_PRINTER)
        continue;

      if (!_cups_strcasecmp(option->value, "true") ||
          !_cups_strcasecmp(option->value, "false"))
	value_tag = IPP_TAG_BOOLEAN;
      else
	value_tag = IPP_TAG_NAME;
    }

   /*
    * Count the number of values...
    */

    if (match && match->multivalue)
    {
      for (count = 1, sep = option->value, quote = 0; *sep; sep ++)
      {
	if (*sep == quote)
	  quote = 0;
	else if (!quote && (*sep == '\'' || *sep == '\"'))
	{
	 /*
	  * Skip quoted option value...
	  */

	  quote = *sep++;
	}
	else if (*sep == ',' && !quote)
	  count ++;
	else if (*sep == '\\' && sep[1])
	  sep ++;
      }
    }
    else
      count = 1;

    DEBUG_printf(("2cupsEncodeOptions2: option=\"%s\", count=%d",
                  option->name, count));

   /*
    * Allocate memory for the attribute values...
    */

    if ((attr = _ippAddAttr(ipp, count)) == NULL)
    {
     /*
      * Ran out of memory!
      */

      DEBUG_puts("1cupsEncodeOptions2: Ran out of memory for attributes!");
      return;
    }

   /*
    * Now figure out what type of value we have...
    */

    attr->group_tag = group_tag;
    attr->value_tag = value_tag;

   /*
    * Copy the name over...
    */

    attr->name = _cupsStrAlloc(option->name);

    if (count > 1)
    {
     /*
      * Make a copy of the value we can fiddle with...
      */

      if ((copy = strdup(option->value)) == NULL)
      {
       /*
	* Ran out of memory!
	*/

	DEBUG_puts("1cupsEncodeOptions2: Ran out of memory for value copy!");
	ippDeleteAttribute(ipp, attr);
	return;
      }

      val = copy;
    }
    else
    {
     /*
      * Since we have a single value, use the value directly...
      */

      val  = option->value;
      copy = NULL;
    }

   /*
    * Scan the value string for values...
    */

    for (j = 0, sep = val; j < count; val = sep, j ++)
    {
     /*
      * Find the end of this value and mark it if needed...
      */

      if (count > 1)
      {
	for (quote = 0; *sep; sep ++)
	{
	  if (*sep == quote)
	  {
	   /*
	    * Finish quoted value...
	    */

	    quote = 0;
	  }
	  else if (!quote && (*sep == '\'' || *sep == '\"'))
	  {
	   /*
	    * Handle quoted option value...
	    */

	    quote = *sep;
	  }
	  else if (*sep == ',' && count > 1)
	    break;
	  else if (*sep == '\\' && sep[1])
	  {
	   /*
	    * Skip quoted character...
	    */

	    sep ++;
	  }
	}

	if (*sep == ',')
	  *sep++ = '\0';
      }

     /*
      * Copy the option value(s) over as needed by the type...
      */

      switch (attr->value_tag)
      {
	case IPP_TAG_INTEGER :
	case IPP_TAG_ENUM :
	   /*
	    * Integer/enumeration value...
	    */

            attr->values[j].integer = strtol(val, &s, 10);

            DEBUG_printf(("2cupsEncodeOptions2: Added integer option value "
	                  "%d...", attr->values[j].integer));
            break;

	case IPP_TAG_BOOLEAN :
	    if (!_cups_strcasecmp(val, "true") ||
	        !_cups_strcasecmp(val, "on") ||
	        !_cups_strcasecmp(val, "yes"))
	    {
	     /*
	      * Boolean value - true...
	      */

	      attr->values[j].boolean = 1;

              DEBUG_puts("2cupsEncodeOptions2: Added boolean true value...");
	    }
	    else
	    {
	     /*
	      * Boolean value - false...
	      */

	      attr->values[j].boolean = 0;

              DEBUG_puts("2cupsEncodeOptions2: Added boolean false value...");
	    }
            break;

	case IPP_TAG_RANGE :
	   /*
	    * Range...
	    */

            if (*val == '-')
	    {
	      attr->values[j].range.lower = 1;
	      s = val;
	    }
	    else
	      attr->values[j].range.lower = strtol(val, &s, 10);

	    if (*s == '-')
	    {
	      if (s[1])
		attr->values[j].range.upper = strtol(s + 1, NULL, 10);
	      else
		attr->values[j].range.upper = 2147483647;
            }
	    else
	      attr->values[j].range.upper = attr->values[j].range.lower;

	    DEBUG_printf(("2cupsEncodeOptions2: Added range option value "
	                  "%d-%d...", attr->values[j].range.lower,
			  attr->values[j].range.upper));
            break;

	case IPP_TAG_RESOLUTION :
	   /*
	    * Resolution...
	    */

	    attr->values[j].resolution.xres = strtol(val, &s, 10);

	    if (*s == 'x')
	      attr->values[j].resolution.yres = strtol(s + 1, &s, 10);
	    else
	      attr->values[j].resolution.yres = attr->values[j].resolution.xres;

	    if (!_cups_strcasecmp(s, "dpc"))
              attr->values[j].resolution.units = IPP_RES_PER_CM;
            else
              attr->values[j].resolution.units = IPP_RES_PER_INCH;

	    DEBUG_printf(("2cupsEncodeOptions2: Added resolution option value "
	                  "%s...", val));
            break;

	case IPP_TAG_STRING :
           /*
	    * octet-string
	    */

            attr->values[j].unknown.length = (int)strlen(val);
	    attr->values[j].unknown.data   = strdup(val);

            DEBUG_printf(("2cupsEncodeOptions2: Added octet-string value "
	                  "\"%s\"...", (char *)attr->values[j].unknown.data));
            break;

        case IPP_TAG_BEGIN_COLLECTION :
	   /*
	    * Collection value
	    */

	    num_cols   = cupsParseOptions(val, 0, &cols);
	    if ((collection = ippNew()) == NULL)
	    {
	      cupsFreeOptions(num_cols, cols);

	      if (copy)
	        free(copy);

	      ippDeleteAttribute(ipp, attr);
	      return;
            }

	    attr->values[j].collection = collection;
	    cupsEncodeOptions2(collection, num_cols, cols, IPP_TAG_JOB);
            cupsFreeOptions(num_cols, cols);
	    break;

	default :
	    if ((attr->values[j].string.text = _cupsStrAlloc(val)) == NULL)
	    {
	     /*
	      * Ran out of memory!
	      */

	      DEBUG_puts("1cupsEncodeOptions2: Ran out of memory for string!");

	      if (copy)
	        free(copy);

	      ippDeleteAttribute(ipp, attr);
	      return;
	    }

	    DEBUG_printf(("2cupsEncodeOptions2: Added string value \"%s\"...",
	                  val));
            break;
      }
    }

    if (copy)
      free(copy);
  }
}
Exemplo n.º 5
0
ipp_status_t				/* O - Request status - @code IPP_OK@ on success. */
cupsGetDevices(
    http_t           *http,		/* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
    int              timeout,		/* I - Timeout in seconds or @code CUPS_TIMEOUT_DEFAULT@ */
    const char       *include_schemes,	/* I - Comma-separated URI schemes to include or @code CUPS_INCLUDE_ALL@ */
    const char       *exclude_schemes,	/* I - Comma-separated URI schemes to exclude or @code CUPS_EXCLUDE_NONE@ */
    cups_device_cb_t callback,		/* I - Callback function */
    void             *user_data)	/* I - User data pointer */
{
  ipp_t		*request,		/* CUPS-Get-Devices request */
		*response;		/* CUPS-Get-Devices response */
  ipp_attribute_t *attr;		/* Current attribute */
  const char	*device_class,		/* device-class value */
		*device_id,		/* device-id value */
		*device_info,		/* device-info value */
		*device_location,	/* device-location value */
		*device_make_and_model,	/* device-make-and-model value */
		*device_uri;		/* device-uri value */
  int		blocking;		/* Current blocking-IO mode */
  cups_option_t	option;			/* in/exclude-schemes option */
  http_status_t	status;			/* HTTP status of request */
  ipp_state_t	state;			/* IPP response state */


 /*
  * Range check input...
  */

  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));

  if (!callback)
    return (IPP_STATUS_ERROR_INTERNAL);

  if (!http)
    http = _cupsConnect();

  if (!http)
    return (IPP_STATUS_ERROR_SERVICE_UNAVAILABLE);

 /*
  * Create a CUPS-Get-Devices request...
  */

  request = ippNewRequest(IPP_OP_CUPS_GET_DEVICES);

  if (timeout > 0)
    ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "timeout",
                  timeout);

  if (include_schemes)
  {
    option.name  = "include-schemes";
    option.value = (char *)include_schemes;

    cupsEncodeOptions2(request, 1, &option, IPP_TAG_OPERATION);
  }

  if (exclude_schemes)
  {
    option.name  = "exclude-schemes";
    option.value = (char *)exclude_schemes;

    cupsEncodeOptions2(request, 1, &option, IPP_TAG_OPERATION);
  }

 /*
  * Send the request and do any necessary authentication...
  */

  do
  {
    DEBUG_puts("2cupsGetDevices: Sending request...");
    status = cupsSendRequest(http, request, "/", ippLength(request));

    DEBUG_puts("2cupsGetDevices: Waiting for response status...");
    while (status == HTTP_STATUS_CONTINUE)
      status = httpUpdate(http);

    if (status != HTTP_STATUS_OK)
    {
      httpFlush(http);

      if (status == HTTP_STATUS_UNAUTHORIZED)
      {
       /*
	* See if we can do authentication...
	*/

	DEBUG_puts("2cupsGetDevices: Need authorization...");

	if (!cupsDoAuthentication(http, "POST", "/"))
	  httpReconnect2(http, 30000, NULL);
	else
	{
	  status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED;
	  break;
	}
      }

#ifdef HAVE_SSL
      else if (status == HTTP_STATUS_UPGRADE_REQUIRED)
      {
       /*
	* Force a reconnect with encryption...
	*/

	DEBUG_puts("2cupsGetDevices: Need encryption...");

	if (!httpReconnect2(http, 30000, NULL))
	  httpEncryption(http, HTTP_ENCRYPTION_REQUIRED);
      }
#endif /* HAVE_SSL */
    }
  }
  while (status == HTTP_STATUS_UNAUTHORIZED ||
         status == HTTP_STATUS_UPGRADE_REQUIRED);

  DEBUG_printf(("2cupsGetDevices: status=%d", status));

  ippDelete(request);

  if (status != HTTP_STATUS_OK)
  {
    _cupsSetHTTPError(status);
    return (cupsLastError());
  }

 /*
  * Read the response in non-blocking mode...
  */

  blocking = httpGetBlocking(http);
  httpBlocking(http, 0);

  response              = ippNew();
  device_class          = NULL;
  device_id             = NULL;
  device_info           = NULL;
  device_location       = "";
  device_make_and_model = NULL;
  device_uri            = NULL;
  attr                  = NULL;

  DEBUG_puts("2cupsGetDevices: Reading response...");

  do
  {
    if ((state = ippRead(http, response)) == IPP_STATE_ERROR)
      break;

    DEBUG_printf(("2cupsGetDevices: state=%d, response->last=%p", state, (void *)response->last));

    if (!response->attrs)
      continue;

    while (attr != response->last)
    {
      if (!attr)
	attr = response->attrs;
      else
        attr = attr->next;

      DEBUG_printf(("2cupsGetDevices: attr->name=\"%s\", attr->value_tag=%d",
                    attr->name, attr->value_tag));

      if (!attr->name)
      {
        if (device_class && device_id && device_info && device_make_and_model &&
	    device_uri)
          (*callback)(device_class, device_id, device_info,
	              device_make_and_model, device_uri, device_location,
		      user_data);

	device_class          = NULL;
	device_id             = NULL;
	device_info           = NULL;
	device_location       = "";
	device_make_and_model = NULL;
	device_uri            = NULL;
      }
      else if (!strcmp(attr->name, "device-class") &&
               attr->value_tag == IPP_TAG_KEYWORD)
        device_class = attr->values[0].string.text;
      else if (!strcmp(attr->name, "device-id") &&
               attr->value_tag == IPP_TAG_TEXT)
        device_id = attr->values[0].string.text;
      else if (!strcmp(attr->name, "device-info") &&
               attr->value_tag == IPP_TAG_TEXT)
        device_info = attr->values[0].string.text;
      else if (!strcmp(attr->name, "device-location") &&
               attr->value_tag == IPP_TAG_TEXT)
        device_location = attr->values[0].string.text;
      else if (!strcmp(attr->name, "device-make-and-model") &&
               attr->value_tag == IPP_TAG_TEXT)
        device_make_and_model = attr->values[0].string.text;
      else if (!strcmp(attr->name, "device-uri") &&
               attr->value_tag == IPP_TAG_URI)
        device_uri = attr->values[0].string.text;
    }
  }
  while (state != IPP_STATE_DATA);

  DEBUG_printf(("2cupsGetDevices: state=%d, response->last=%p", state, (void *)response->last));

  if (device_class && device_id && device_info && device_make_and_model &&
      device_uri)
    (*callback)(device_class, device_id, device_info,
		device_make_and_model, device_uri, device_location, user_data);

 /*
  * Set the IPP status and return...
  */

  httpBlocking(http, blocking);
  httpFlush(http);

  if (status == HTTP_STATUS_ERROR)
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(http->error), 0);
  else
  {
    attr = ippFindAttribute(response, "status-message", IPP_TAG_TEXT);

    DEBUG_printf(("cupsGetDevices: status-code=%s, status-message=\"%s\"",
		  ippErrorString(response->request.status.status_code),
		  attr ? attr->values[0].string.text : ""));

    _cupsSetError(response->request.status.status_code,
		  attr ? attr->values[0].string.text :
		      ippErrorString(response->request.status.status_code), 0);
  }

  ippDelete(response);

  return (cupsLastError());
}
Exemplo n.º 6
0
static int				/* O - 0 on success, 1 on fail */
set_printer_options(
    http_t        *http,		/* I - Server connection */
    char          *printer,		/* I - Printer */
    int           num_options,		/* I - Number of options */
    cups_option_t *options,		/* I - Options */
    char          *file)		/* I - PPD file/interface script */
{
  ipp_t		*request;		/* IPP Request */
  const char	*ppdfile;		/* PPD filename */
  int		ppdchanged;		/* PPD changed? */
  ppd_file_t	*ppd;			/* PPD file */
  ppd_choice_t	*choice;		/* Marked choice */
  char		uri[HTTP_MAX_URI],	/* URI for printer/class */
		line[1024],		/* Line from PPD file */
		keyword[1024],		/* Keyword from Default line */
		*keyptr,		/* Pointer into keyword... */
		tempfile[1024];		/* Temporary filename */
  cups_file_t	*in,			/* PPD file */
		*out;			/* Temporary file */
  const char	*protocol,		/* Old protocol option */
		*customval,		/* Custom option value */
		*boolval;		/* Boolean value */
  int		wrote_ipp_supplies = 0,	/* Wrote cupsIPPSupplies keyword? */
		wrote_snmp_supplies = 0;/* Wrote cupsSNMPSupplies keyword? */


  DEBUG_printf(("set_printer_options(http=%p, printer=\"%s\", num_options=%d, "
                "options=%p, file=\"%s\")\n", http, printer, num_options,
		options, file));

 /*
  * Build a CUPS_ADD_MODIFY_PRINTER or CUPS_ADD_MODIFY_CLASS request, which
  * requires the following attributes:
  *
  *    attributes-charset
  *    attributes-natural-language
  *    printer-uri
  *    requesting-user-name
  *    other options
  */

  if (get_printer_type(http, printer, uri, sizeof(uri)) & CUPS_PRINTER_CLASS)
    request = ippNewRequest(CUPS_ADD_MODIFY_CLASS);
  else
    request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER);

  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
               "printer-uri", NULL, uri);
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
               "requesting-user-name", NULL, cupsUser());

 /*
  * Add the options...
  */

  cupsEncodeOptions2(request, num_options, options, IPP_TAG_PRINTER);

  if ((protocol = cupsGetOption("protocol", num_options, options)) != NULL)
  {
    if (!_cups_strcasecmp(protocol, "bcp"))
      ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "port-monitor",
                   NULL, "bcp");
    else if (!_cups_strcasecmp(protocol, "tbcp"))
      ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "port-monitor",
                   NULL, "tbcp");
  }

  if (file)
    ppdfile = file;
  else if (request->request.op.operation_id == CUPS_ADD_MODIFY_PRINTER)
    ppdfile = cupsGetPPD(printer);
  else
    ppdfile = NULL;

  if (ppdfile != NULL)
  {
   /*
    * Set default options in the PPD file...
    */

    ppd = ppdOpenFile(ppdfile);
    ppdMarkDefaults(ppd);
    cupsMarkOptions(ppd, num_options, options);

    if ((out = cupsTempFile2(tempfile, sizeof(tempfile))) == NULL)
    {
      _cupsLangPrintError(NULL, _("lpadmin: Unable to create temporary file"));
      ippDelete(request);
      if (ppdfile != file)
        unlink(ppdfile);
      return (1);
    }

    if ((in = cupsFileOpen(ppdfile, "r")) == NULL)
    {
      _cupsLangPrintf(stderr,
                      _("lpadmin: Unable to open PPD file \"%s\" - %s"),
        	      ppdfile, strerror(errno));
      ippDelete(request);
      if (ppdfile != file)
	unlink(ppdfile);
      cupsFileClose(out);
      unlink(tempfile);
      return (1);
    }

    ppdchanged = 0;

    while (cupsFileGets(in, line, sizeof(line)))
    {
      if (!strncmp(line, "*cupsIPPSupplies:", 17) &&
	  (boolval = cupsGetOption("cupsIPPSupplies", num_options,
	                           options)) != NULL)
      {
        wrote_ipp_supplies = 1;
        cupsFilePrintf(out, "*cupsIPPSupplies: %s\n",
	               (!_cups_strcasecmp(boolval, "true") ||
		        !_cups_strcasecmp(boolval, "yes") ||
		        !_cups_strcasecmp(boolval, "on")) ? "True" : "False");
      }
      else if (!strncmp(line, "*cupsSNMPSupplies:", 18) &&
	       (boolval = cupsGetOption("cupsSNMPSupplies", num_options,
	                                options)) != NULL)
      {
        wrote_snmp_supplies = 1;
        cupsFilePrintf(out, "*cupsSNMPSupplies: %s\n",
	               (!_cups_strcasecmp(boolval, "true") ||
		        !_cups_strcasecmp(boolval, "yes") ||
		        !_cups_strcasecmp(boolval, "on")) ? "True" : "False");
      }
      else if (strncmp(line, "*Default", 8))
        cupsFilePrintf(out, "%s\n", line);
      else
      {
       /*
        * Get default option name...
	*/

        strlcpy(keyword, line + 8, sizeof(keyword));

	for (keyptr = keyword; *keyptr; keyptr ++)
	  if (*keyptr == ':' || isspace(*keyptr & 255))
	    break;

        *keyptr++ = '\0';
        while (isspace(*keyptr & 255))
	  keyptr ++;

        if (!strcmp(keyword, "PageRegion") ||
	    !strcmp(keyword, "PageSize") ||
	    !strcmp(keyword, "PaperDimension") ||
	    !strcmp(keyword, "ImageableArea"))
	{
	  if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) == NULL)
	    choice = ppdFindMarkedChoice(ppd, "PageRegion");
        }
	else
	  choice = ppdFindMarkedChoice(ppd, keyword);

        if (choice && strcmp(choice->choice, keyptr))
	{
	  if (strcmp(choice->choice, "Custom"))
	  {
	    cupsFilePrintf(out, "*Default%s: %s\n", keyword, choice->choice);
	    ppdchanged = 1;
	  }
	  else if ((customval = cupsGetOption(keyword, num_options,
	                                      options)) != NULL)
	  {
	    cupsFilePrintf(out, "*Default%s: %s\n", keyword, customval);
	    ppdchanged = 1;
	  }
	  else
	    cupsFilePrintf(out, "%s\n", line);
	}
	else
	  cupsFilePrintf(out, "%s\n", line);
      }
    }

    if (!wrote_ipp_supplies &&
	(boolval = cupsGetOption("cupsIPPSupplies", num_options,
				 options)) != NULL)
    {
      cupsFilePrintf(out, "*cupsIPPSupplies: %s\n",
		     (!_cups_strcasecmp(boolval, "true") ||
		      !_cups_strcasecmp(boolval, "yes") ||
		      !_cups_strcasecmp(boolval, "on")) ? "True" : "False");
    }

    if (!wrote_snmp_supplies &&
        (boolval = cupsGetOption("cupsSNMPSupplies", num_options,
			         options)) != NULL)
    {
      cupsFilePrintf(out, "*cupsSNMPSupplies: %s\n",
		     (!_cups_strcasecmp(boolval, "true") ||
		      !_cups_strcasecmp(boolval, "yes") ||
		      !_cups_strcasecmp(boolval, "on")) ? "True" : "False");
    }

    cupsFileClose(in);
    cupsFileClose(out);
    ppdClose(ppd);

   /*
    * Do the request...
    */

    ippDelete(cupsDoFileRequest(http, request, "/admin/",
                                ppdchanged ? tempfile : file));

   /*
    * Clean up temp files... (TODO: catch signals in case we CTRL-C during
    * lpadmin)
    */

    if (ppdfile != file)
      unlink(ppdfile);
    unlink(tempfile);
  }
  else
  {
   /*
    * No PPD file - just set the options...
    */

    ippDelete(cupsDoRequest(http, request, "/admin/"));
  }

 /*
  * Check the response...
  */

  if (cupsLastError() > IPP_OK_CONFLICT)
  {
    _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString());

    return (1);
  }
  else
    return (0);
}
Exemplo n.º 7
0
int					/* O - Job ID or 0 on error */
cupsCreateJob(
    http_t        *http,		/* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
    const char    *name,		/* I - Destination name */
    const char    *title,		/* I - Title of job */
    int           num_options,		/* I - Number of options */
    cups_option_t *options)		/* I - Options */
{
  char		printer_uri[1024],	/* Printer URI */
		resource[1024];		/* Printer resource */
  ipp_t		*request,		/* Create-Job request */
		*response;		/* Create-Job response */
  ipp_attribute_t *attr;		/* job-id attribute */
  int		job_id = 0;		/* job-id value */


  DEBUG_printf(("cupsCreateJob(http=%p, name=\"%s\", title=\"%s\", "
                "num_options=%d, options=%p)",
                http, name, title, num_options, options));

 /*
  * Range check input...
  */

  if (!name)
  {
    _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0);
    return (0);
  }

 /*
  * Build a Create-Job request...
  */

  if ((request = ippNewRequest(IPP_CREATE_JOB)) == NULL)
  {
    _cupsSetError(IPP_INTERNAL_ERROR, strerror(ENOMEM), 0);
    return (0);
  }

  httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), "ipp",
                   NULL, "localhost", ippPort(), "/printers/%s", name);
  snprintf(resource, sizeof(resource), "/printers/%s", name);

  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
               NULL, printer_uri);
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
               NULL, cupsUser());
  if (title)
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL,
                 title);
  cupsEncodeOptions2(request, num_options, options, IPP_TAG_JOB);
  cupsEncodeOptions2(request, num_options, options, IPP_TAG_SUBSCRIPTION);

 /*
  * Send the request and get the job-id...
  */

  response = cupsDoRequest(http, request, resource);

  if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) != NULL)
    job_id = attr->values[0].integer;

  ippDelete(response);

 /*
  * Return it...
  */

  return (job_id);
}