Esempio n. 1
0
static void
write_expect(_cups_reg_t *reg,		/* I - Registration information */
             ipp_tag_t   group)		/* I - Attribute group tag */
{
  const char	*syntax;		/* Pointer into syntax string */
  int		single = 1,		/* Single valued? */
		skip = 0;		/* Skip characters? */


  printf("\tEXPECT ?%s OF-TYPE ", reg->name);

  syntax = reg->syntax;

  while (*syntax)
  {
    if (!strncmp(syntax, "1setOf", 6))
    {
      single = 0;
      syntax += 6;

      while (isspace(*syntax & 255))
        syntax ++;

      if (*syntax == '(')
        syntax ++;
    }
    else if (!strncmp(syntax, "type1", 5) || !strncmp(syntax, "type2", 5) ||
             !strncmp(syntax, "type3", 5))
      syntax += 5;
    else if (*syntax == '(')
    {
      skip = 1;
      syntax ++;
    }
    else if (*syntax == ')')
    {
      skip = 0;
      syntax ++;
    }
    else if (!skip && (*syntax == '|' || isalpha(*syntax & 255)))
      putchar(*syntax++);
    else
      syntax ++;
  }

  if (single)
    printf(" IN-GROUP %s COUNT 1\n", ippTagString(group));
  else
    printf(" IN-GROUP %s\n", ippTagString(group));
}
Esempio n. 2
0
int				/* O - Exit status */
main(int  argc,			/* I - Number of command-line arguments */
     char *argv[])		/* I - Command-line arguments */
{
  _ippdata_t	data;		/* IPP buffer */
  ipp_uchar_t	buffer[8192];	/* Write buffer data */
  ipp_t		*cols[2],	/* Collections */
		*size;		/* media-size collection */
  ipp_t		*request;	/* Request */
  ipp_attribute_t *media_col,	/* media-col attribute */
		*media_size,	/* media-size attribute */
		*attr;		/* Other attribute */
  ipp_state_t	state;		/* State */
  size_t	length;		/* Length of data */
  cups_file_t	*fp;		/* File pointer */
  size_t	i;		/* Looping var */
  int		status;		/* Status of tests (0 = success, 1 = fail) */
#ifdef DEBUG
  const char	*name;		/* Option name */
#endif /* DEBUG */


  status = 0;

  if (argc == 1)
  {
   /*
    * Test request generation code...
    */

    printf("Create Sample Request: ");

    request = ippNew();
    request->request.op.version[0]   = 0x01;
    request->request.op.version[1]   = 0x01;
    request->request.op.operation_id = IPP_OP_PRINT_JOB;
    request->request.op.request_id   = 1;

    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
        	 "attributes-charset", NULL, "utf-8");
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
        	 "attributes-natural-language", NULL, "en");
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
        	 "printer-uri", NULL, "ipp://localhost/printers/foo");

    cols[0] = ippNew();
    size    = ippNew();
    ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "x-dimension", 21590);
    ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "y-dimension", 27940);
    ippAddCollection(cols[0], IPP_TAG_JOB, "media-size", size);
    ippDelete(size);
    ippAddString(cols[0], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-color", NULL,
                 "blue");
    ippAddString(cols[0], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-type", NULL,
                 "plain");

    cols[1] = ippNew();
    size    = ippNew();
    ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "x-dimension", 21000);
    ippAddInteger(size, IPP_TAG_ZERO, IPP_TAG_INTEGER, "y-dimension", 29700);
    ippAddCollection(cols[1], IPP_TAG_JOB, "media-size", size);
    ippDelete(size);
    ippAddString(cols[1], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-color", NULL,
                 "plaid");
    ippAddString(cols[1], IPP_TAG_JOB, IPP_TAG_KEYWORD, "media-type", NULL,
		 "glossy");

    ippAddCollections(request, IPP_TAG_JOB, "media-col", 2,
                      (const ipp_t **)cols);
    ippDelete(cols[0]);
    ippDelete(cols[1]);

    length = ippLength(request);
    if (length != sizeof(collection))
    {
      printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n",
             (int)length, (int)sizeof(collection));
      status = 1;
    }
    else
      puts("PASS");

   /*
    * Write test #1...
    */

    printf("Write Sample to Memory: ");

    data.wused   = 0;
    data.wsize   = sizeof(buffer);
    data.wbuffer = buffer;

    while ((state = ippWriteIO(&data, (ipp_iocb_t)write_cb, 1, NULL,
                               request)) != IPP_STATE_DATA)
      if (state == IPP_STATE_ERROR)
	break;

    if (state != IPP_STATE_DATA)
    {
      printf("FAIL - %d bytes written.\n", (int)data.wused);
      status = 1;
    }
    else if (data.wused != sizeof(collection))
    {
      printf("FAIL - wrote %d bytes, expected %d bytes!\n", (int)data.wused,
             (int)sizeof(collection));
      hex_dump("Bytes Written", data.wbuffer, data.wused);
      hex_dump("Baseline", collection, sizeof(collection));
      status = 1;
    }
    else if (memcmp(data.wbuffer, collection, data.wused))
    {
      for (i = 0; i < data.wused; i ++)
        if (data.wbuffer[i] != collection[i])
	  break;

      printf("FAIL - output does not match baseline at 0x%04x!\n", (unsigned)i);
      hex_dump("Bytes Written", data.wbuffer, data.wused);
      hex_dump("Baseline", collection, sizeof(collection));
      status = 1;
    }
    else
      puts("PASS");

    ippDelete(request);

   /*
    * Read the data back in and confirm...
    */

    printf("Read Sample from Memory: ");

    request     = ippNew();
    data.rpos = 0;

    while ((state = ippReadIO(&data, (ipp_iocb_t)read_cb, 1, NULL,
                              request)) != IPP_STATE_DATA)
      if (state == IPP_STATE_ERROR)
	break;

    length = ippLength(request);

    if (state != IPP_STATE_DATA)
    {
      printf("FAIL - %d bytes read.\n", (int)data.rpos);
      status = 1;
    }
    else if (data.rpos != data.wused)
    {
      printf("FAIL - read %d bytes, expected %d bytes!\n", (int)data.rpos,
             (int)data.wused);
      print_attributes(request, 8);
      status = 1;
    }
    else if (length != sizeof(collection))
    {
      printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n",
             (int)length, (int)sizeof(collection));
      print_attributes(request, 8);
      status = 1;
    }
    else
      puts("PASS");

    fputs("ippFindAttribute(media-col): ", stdout);
    if ((media_col = ippFindAttribute(request, "media-col",
                                      IPP_TAG_BEGIN_COLLECTION)) == NULL)
    {
      if ((media_col = ippFindAttribute(request, "media-col",
                                        IPP_TAG_ZERO)) == NULL)
        puts("FAIL (not found)");
      else
        printf("FAIL (wrong type - %s)\n", ippTagString(media_col->value_tag));

      status = 1;
    }
    else if (media_col->num_values != 2)
    {
      printf("FAIL (wrong count - %d)\n", media_col->num_values);
      status = 1;
    }
    else
      puts("PASS");

    if (media_col)
    {
      fputs("ippFindAttribute(media-size 1): ", stdout);
      if ((media_size = ippFindAttribute(media_col->values[0].collection,
					 "media-size",
					 IPP_TAG_BEGIN_COLLECTION)) == NULL)
      {
	if ((media_size = ippFindAttribute(media_col->values[0].collection,
					   "media-col",
					   IPP_TAG_ZERO)) == NULL)
	  puts("FAIL (not found)");
	else
	  printf("FAIL (wrong type - %s)\n",
	         ippTagString(media_size->value_tag));

	status = 1;
      }
      else
      {
	if ((attr = ippFindAttribute(media_size->values[0].collection,
				     "x-dimension", IPP_TAG_INTEGER)) == NULL)
	{
	  if ((attr = ippFindAttribute(media_size->values[0].collection,
				       "x-dimension", IPP_TAG_ZERO)) == NULL)
	    puts("FAIL (missing x-dimension)");
	  else
	    printf("FAIL (wrong type for x-dimension - %s)\n",
		   ippTagString(attr->value_tag));

	  status = 1;
	}
	else if (attr->values[0].integer != 21590)
	{
	  printf("FAIL (wrong value for x-dimension - %d)\n",
		 attr->values[0].integer);
	  status = 1;
	}
	else if ((attr = ippFindAttribute(media_size->values[0].collection,
					  "y-dimension",
					  IPP_TAG_INTEGER)) == NULL)
	{
	  if ((attr = ippFindAttribute(media_size->values[0].collection,
				       "y-dimension", IPP_TAG_ZERO)) == NULL)
	    puts("FAIL (missing y-dimension)");
	  else
	    printf("FAIL (wrong type for y-dimension - %s)\n",
		   ippTagString(attr->value_tag));

	  status = 1;
	}
	else if (attr->values[0].integer != 27940)
	{
	  printf("FAIL (wrong value for y-dimension - %d)\n",
		 attr->values[0].integer);
	  status = 1;
	}
	else
	  puts("PASS");
      }

      fputs("ippFindAttribute(media-size 2): ", stdout);
      if ((media_size = ippFindAttribute(media_col->values[1].collection,
					 "media-size",
					 IPP_TAG_BEGIN_COLLECTION)) == NULL)
      {
	if ((media_size = ippFindAttribute(media_col->values[1].collection,
					   "media-col",
					   IPP_TAG_ZERO)) == NULL)
	  puts("FAIL (not found)");
	else
	  printf("FAIL (wrong type - %s)\n",
	         ippTagString(media_size->value_tag));

	status = 1;
      }
      else
      {
	if ((attr = ippFindAttribute(media_size->values[0].collection,
				     "x-dimension",
				     IPP_TAG_INTEGER)) == NULL)
	{
	  if ((attr = ippFindAttribute(media_size->values[0].collection,
				       "x-dimension", IPP_TAG_ZERO)) == NULL)
	    puts("FAIL (missing x-dimension)");
	  else
	    printf("FAIL (wrong type for x-dimension - %s)\n",
		   ippTagString(attr->value_tag));

	  status = 1;
	}
	else if (attr->values[0].integer != 21000)
	{
	  printf("FAIL (wrong value for x-dimension - %d)\n",
		 attr->values[0].integer);
	  status = 1;
	}
	else if ((attr = ippFindAttribute(media_size->values[0].collection,
					  "y-dimension",
					  IPP_TAG_INTEGER)) == NULL)
	{
	  if ((attr = ippFindAttribute(media_size->values[0].collection,
				       "y-dimension", IPP_TAG_ZERO)) == NULL)
	    puts("FAIL (missing y-dimension)");
	  else
	    printf("FAIL (wrong type for y-dimension - %s)\n",
		   ippTagString(attr->value_tag));

	  status = 1;
	}
	else if (attr->values[0].integer != 29700)
	{
	  printf("FAIL (wrong value for y-dimension - %d)\n",
		 attr->values[0].integer);
	  status = 1;
	}
	else
	  puts("PASS");
      }
    }

   /*
    * Test hierarchical find...
    */

    fputs("ippFindAttribute(media-col/media-size/x-dimension): ", stdout);
    if ((attr = ippFindAttribute(request, "media-col/media-size/x-dimension", IPP_TAG_INTEGER)) != NULL)
    {
      if (ippGetInteger(attr, 0) != 21590)
      {
        printf("FAIL (wrong value for x-dimension - %d)\n", ippGetInteger(attr, 0));
        status = 1;
      }
      else
        puts("PASS");
    }
    else
    {
      puts("FAIL (not found)");
      status = 1;
    }

    fputs("ippFindNextAttribute(media-col/media-size/x-dimension): ", stdout);
    if ((attr = ippFindNextAttribute(request, "media-col/media-size/x-dimension", IPP_TAG_INTEGER)) != NULL)
    {
      if (ippGetInteger(attr, 0) != 21000)
      {
        printf("FAIL (wrong value for x-dimension - %d)\n", ippGetInteger(attr, 0));
        status = 1;
      }
      else
        puts("PASS");
    }
    else
    {
      puts("FAIL (not found)");
      status = 1;
    }

    fputs("ippFindNextAttribute(media-col/media-size/x-dimension) again: ", stdout);
    if ((attr = ippFindNextAttribute(request, "media-col/media-size/x-dimension", IPP_TAG_INTEGER)) != NULL)
    {
      printf("FAIL (got %d, expected nothing)\n", ippGetInteger(attr, 0));
      status = 1;
    }
    else
      puts("PASS");

    ippDelete(request);

   /*
    * Read the mixed data and confirm we converted everything to rangeOfInteger
    * values...
    */

    printf("Read Mixed integer/rangeOfInteger from Memory: ");

    request = ippNew();
    data.rpos    = 0;
    data.wused   = sizeof(mixed);
    data.wsize   = sizeof(mixed);
    data.wbuffer = mixed;

    while ((state = ippReadIO(&data, (ipp_iocb_t)read_cb, 1, NULL,
                              request)) != IPP_STATE_DATA)
      if (state == IPP_STATE_ERROR)
	break;

    length = ippLength(request);

    if (state != IPP_STATE_DATA)
    {
      printf("FAIL - %d bytes read.\n", (int)data.rpos);
      status = 1;
    }
    else if (data.rpos != sizeof(mixed))
    {
      printf("FAIL - read %d bytes, expected %d bytes!\n", (int)data.rpos,
             (int)sizeof(mixed));
      print_attributes(request, 8);
      status = 1;
    }
    else if (length != (sizeof(mixed) + 4))
    {
      printf("FAIL - wrong ippLength(), %d instead of %d bytes!\n",
             (int)length, (int)sizeof(mixed) + 4);
      print_attributes(request, 8);
      status = 1;
    }
    else
      puts("PASS");

    fputs("ippFindAttribute(notify-lease-duration-supported): ", stdout);
    if ((attr = ippFindAttribute(request, "notify-lease-duration-supported",
                                 IPP_TAG_ZERO)) == NULL)
    {
      puts("FAIL (not found)");
      status = 1;
    }
    else if (attr->value_tag != IPP_TAG_RANGE)
    {
      printf("FAIL (wrong type - %s)\n", ippTagString(attr->value_tag));
      status = 1;
    }
    else if (attr->num_values != 2)
    {
      printf("FAIL (wrong count - %d)\n", attr->num_values);
      status = 1;
    }
    else if (attr->values[0].range.lower != 1 ||
             attr->values[0].range.upper != 1 ||
             attr->values[1].range.lower != 16 ||
             attr->values[1].range.upper != 32)
    {
      printf("FAIL (wrong values - %d,%d and %d,%d)\n",
             attr->values[0].range.lower,
             attr->values[0].range.upper,
             attr->values[1].range.lower,
             attr->values[1].range.upper);
      status = 1;
    }
    else
      puts("PASS");

    ippDelete(request);

#ifdef DEBUG
   /*
    * Test that private option array is sorted...
    */

    fputs("_ippCheckOptions: ", stdout);
    if ((name = _ippCheckOptions()) == NULL)
      puts("PASS");
    else
    {
      printf("FAIL (\"%s\" out of order)\n", name);
      status = 1;
    }
#endif /* DEBUG */

   /*
    * Test _ippFindOption() private API...
    */

    fputs("_ippFindOption(\"printer-type\"): ", stdout);
    if (_ippFindOption("printer-type"))
      puts("PASS");
    else
    {
      puts("FAIL");
      status = 1;
    }

   /*
    * Summarize...
    */

    putchar('\n');

    if (status)
      puts("Core IPP tests failed.");
    else
      puts("Core IPP tests passed.");
  }
  else
  {
   /*
    * Read IPP files...
    */

    for (i = 1; i < (size_t)argc; i ++)
    {
      if ((fp = cupsFileOpen(argv[i], "r")) == NULL)
      {
	printf("Unable to open \"%s\" - %s\n", argv[i], strerror(errno));
	status = 1;
	continue;
      }

      request = ippNew();
      while ((state = ippReadIO(fp, (ipp_iocb_t)cupsFileRead, 1, NULL,
                                request)) == IPP_STATE_ATTRIBUTE);

      if (state != IPP_STATE_DATA)
      {
	printf("Error reading IPP message from \"%s\"!\n", argv[i]);
	status = 1;
      }
      else
      {
	printf("\n%s:\n", argv[i]);
	print_attributes(request, 4);
      }

      ippDelete(request);
      cupsFileClose(fp);
    }
  }

  return (status);
}
Esempio n. 3
0
size_t					/* O - Number of bytes less nul */
_ippAttrString(ipp_attribute_t *attr,	/* I - Attribute */
               char            *buffer,	/* I - String buffer or NULL */
               size_t          bufsize)	/* I - Size of string buffer */
{
    int		i;			/* Looping var */
    char		*bufptr,		/* Pointer into buffer */
                *bufend,		/* End of buffer */
                temp[256];		/* Temporary string */
    const char	*ptr;			/* Pointer into string */
    ipp_value_t	*val;			/* Current value */


    if (!attr || !attr->name)
    {
        if (buffer)
            *buffer = '\0';

        return (0);
    }

    bufptr = buffer;
    if (buffer)
        bufend = buffer + bufsize - 1;
    else
        bufend = NULL;

    for (i = attr->num_values, val = attr->values; i > 0; i --, val ++)
    {
        if (val > attr->values)
        {
            if (buffer && bufptr < bufend)
                *bufptr++ = ',';
            else
                bufptr ++;
        }

        switch (attr->value_tag & ~IPP_TAG_COPY)
        {
        case IPP_TAG_ENUM :
            if (!strcmp(attr->name, "printer-state") &&
                    val->integer >= IPP_PRINTER_IDLE &&
                    val->integer <= IPP_PRINTER_STOPPED)
            {
                ptr = printer_states[val->integer - IPP_PRINTER_IDLE];

                if (buffer && bufptr < bufend)
                    strlcpy(bufptr, ptr, bufend - bufptr + 1);

                bufptr += strlen(ptr);
                break;
            }
            else if (!strcmp(attr->name, "job-state") &&
                     val->integer >= IPP_JOB_PENDING &&
                     val->integer <= IPP_JOB_COMPLETED)
            {
                ptr = job_states[val->integer - IPP_JOB_PENDING];

                if (buffer && bufptr < bufend)
                    strlcpy(bufptr, ptr, bufend - bufptr + 1);

                bufptr += strlen(ptr);
                break;
            }
            else if (!strcmp(attr->name, "operations-supported"))
            {
                ptr = ippOpString(val->integer);

                if (buffer && bufptr < bufend)
                    strlcpy(bufptr, ptr, bufend - bufptr + 1);

                bufptr += strlen(ptr);
                break;
            }

        case IPP_TAG_INTEGER :
            if (buffer && bufptr < bufend)
                bufptr += snprintf(bufptr, bufend - bufptr + 1, "%d", val->integer);
            else
                bufptr += snprintf(temp, sizeof(temp), "%d", val->integer);
            break;

        case IPP_TAG_BOOLEAN :
            if (buffer && bufptr < bufend)
                strlcpy(bufptr, val->boolean ? "true" : "false",
                        bufend - bufptr + 1);

            bufptr += val->boolean ? 4 : 5;
            break;

        case IPP_TAG_RANGE :
            if (buffer && bufptr < bufend)
                bufptr += snprintf(bufptr, bufend - bufptr + 1, "%d-%d",
                                   val->range.lower, val->range.upper);
            else
                bufptr += snprintf(temp, sizeof(temp), "%d-%d", val->range.lower,
                                   val->range.upper);
            break;

        case IPP_TAG_RESOLUTION :
            if (buffer && bufptr < bufend)
                bufptr += snprintf(bufptr, bufend - bufptr + 1, "%dx%d%s",
                                   val->resolution.xres, val->resolution.yres,
                                   val->resolution.units == IPP_RES_PER_INCH ?
                                   "dpi" : "dpc");
            else
                bufptr += snprintf(temp, sizeof(temp), "%dx%d%s",
                                   val->resolution.xres, val->resolution.yres,
                                   val->resolution.units == IPP_RES_PER_INCH ?
                                   "dpi" : "dpc");
            break;

        case IPP_TAG_DATE :
        {
            unsigned year;		/* Year */

            year = (val->date[0] << 8) + val->date[1];

            if (val->date[9] == 0 && val->date[10] == 0)
                snprintf(temp, sizeof(temp), "%04u-%02u-%02uT%02u:%02u:%02uZ",
                         year, val->date[2], val->date[3], val->date[4],
                         val->date[5], val->date[6]);
            else
                snprintf(temp, sizeof(temp),
                         "%04u-%02u-%02uT%02u:%02u:%02u%c%02u%02u",
                         year, val->date[2], val->date[3], val->date[4],
                         val->date[5], val->date[6], val->date[8], val->date[9],
                         val->date[10]);

            if (buffer && bufptr < bufend)
                strlcpy(bufptr, temp, bufend - bufptr + 1);

            bufptr += strlen(temp);
        }
        break;

        case IPP_TAG_TEXT :
        case IPP_TAG_NAME :
        case IPP_TAG_KEYWORD :
        case IPP_TAG_CHARSET :
        case IPP_TAG_URI :
        case IPP_TAG_URISCHEME :
        case IPP_TAG_MIMETYPE :
        case IPP_TAG_LANGUAGE :
        case IPP_TAG_TEXTLANG :
        case IPP_TAG_NAMELANG :
            if (!val->string.text)
                break;

            for (ptr = val->string.text; *ptr; ptr ++)
            {
                if (*ptr == '\\' || *ptr == '\"')
                {
                    if (buffer && bufptr < bufend)
                        *bufptr = '\\';
                    bufptr ++;
                }

                if (buffer && bufptr < bufend)
                    *bufptr = *ptr;
                bufptr ++;
            }
            break;

        case IPP_TAG_BEGIN_COLLECTION :
            if (buffer && bufptr < bufend)
                bufptr += ipp_col_string(val->collection, bufptr,
                                         bufend - bufptr + 1);
            else
                bufptr += ipp_col_string(val->collection, NULL, 0);
            break;

        case IPP_TAG_STRING :
            for (ptr = val->string.text; *ptr; ptr ++)
            {
                if (*ptr == '\\' || _cups_isspace(*ptr))
                {
                    if (buffer && bufptr < bufend)
                        *bufptr = '\\';
                    bufptr ++;

                    if (buffer && bufptr < bufend)
                        *bufptr = *ptr;
                    bufptr ++;
                }
                else if (!isprint(*ptr & 255))
                {
                    if (buffer && bufptr < bufend)
                        bufptr += snprintf(bufptr, bufend - bufptr + 1, "\\%03o",
                                           *ptr & 255);
                    else
                        bufptr += snprintf(temp, sizeof(temp), "\\%03o",
                                           *ptr & 255);
                }
                else
                {
                    if (buffer && bufptr < bufend)
                        *bufptr = *ptr;
                    bufptr ++;
                }
            }
            break;

        default :
            ptr = ippTagString(attr->value_tag);
            if (buffer && bufptr < bufend)
                strlcpy(bufptr, ptr, bufend - bufptr + 1);
            bufptr += strlen(ptr);
            break;
        }
    }

    if (buffer && bufptr < bufend)
        *bufptr = '\0';
    else if (bufend)
        *bufend = '\0';

    return (bufptr - buffer);
}
Esempio n. 4
0
static void
show_supported(http_t       *http,	/* I - Connection to destination */
	       cups_dest_t  *dest,	/* I - Destination */
	       cups_dinfo_t *dinfo,	/* I - Destination information */
	       const char   *option,	/* I - Option, if any */
	       const char   *value)	/* I - Value, if any */
{
  ipp_attribute_t	*attr;		/* Attribute */
  int			i,		/* Looping var */
			count;		/* Number of values */


  if (!option)
  {
    attr = cupsFindDestSupported(http, dest, dinfo, "job-creation-attributes");
    if (attr)
    {
      count = ippGetCount(attr);
      for (i = 0; i < count; i ++)
        show_supported(http, dest, dinfo, ippGetString(attr, i, NULL), NULL);
    }
    else
    {
      static const char * const options[] =
      {					/* List of standard options */
        CUPS_COPIES,
	CUPS_FINISHINGS,
	CUPS_MEDIA,
	CUPS_NUMBER_UP,
	CUPS_ORIENTATION,
	CUPS_PRINT_COLOR_MODE,
	CUPS_PRINT_QUALITY,
	CUPS_SIDES
      };

      puts("No job-creation-attributes-supported attribute, probing instead.");

      for (i = 0; i < (int)(sizeof(options) / sizeof(options[0])); i ++)
        if (cupsCheckDestSupported(http, dest, dinfo, options[i], NULL))
	  show_supported(http, dest, dinfo, options[i], NULL);
    }
  }
  else if (!value)
  {
    printf("%s (%s)\n", option, cupsCheckDestSupported(http, dest, dinfo, option, NULL) ? "supported" : "not-supported");

    if ((attr = cupsFindDestSupported(http, dest, dinfo, option)) != NULL)
    {
      count = ippGetCount(attr);

      switch (ippGetValueTag(attr))
      {
        case IPP_TAG_INTEGER :
	    for (i = 0; i < count; i ++)
              printf("  %d\n", ippGetInteger(attr, i));
	    break;

        case IPP_TAG_ENUM :
	    for (i = 0; i < count; i ++)
              printf("  %s\n", ippEnumString(option, ippGetInteger(attr, i)));
	    break;

        case IPP_TAG_RANGE :
	    for (i = 0; i < count; i ++)
	    {
	      int upper, lower = ippGetRange(attr, i, &upper);

              printf("  %d-%d\n", lower, upper);
	    }
	    break;

        case IPP_TAG_RESOLUTION :
	    for (i = 0; i < count; i ++)
	    {
	      int xres, yres;
	      ipp_res_t units;
	      xres = ippGetResolution(attr, i, &yres, &units);

              if (xres == yres)
                printf("  %d%s\n", xres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
	      else
                printf("  %dx%d%s\n", xres, yres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
	    }
	    break;

	case IPP_TAG_TEXTLANG :
	case IPP_TAG_NAMELANG :
	case IPP_TAG_TEXT :
	case IPP_TAG_NAME :
	case IPP_TAG_KEYWORD :
	case IPP_TAG_URI :
	case IPP_TAG_URISCHEME :
	case IPP_TAG_CHARSET :
	case IPP_TAG_LANGUAGE :
	case IPP_TAG_MIMETYPE :
	    for (i = 0; i < count; i ++)
              printf("  %s\n", ippGetString(attr, i, NULL));
	    break;

        case IPP_TAG_STRING :
	    for (i = 0; i < count; i ++)
	    {
	      int j, len;
	      unsigned char *data = ippGetOctetString(attr, i, &len);

              fputs("  ", stdout);
	      for (j = 0; j < len; j ++)
	      {
	        if (data[j] < ' ' || data[j] >= 0x7f)
		  printf("<%02X>", data[j]);
		else
		  putchar(data[j]);
              }
              putchar('\n');
	    }
	    break;

        case IPP_TAG_BOOLEAN :
	    break;

        default :
	    printf("  %s\n", ippTagString(ippGetValueTag(attr)));
	    break;
      }
    }

  }
  else if (cupsCheckDestSupported(http, dest, dinfo, option, value))
    puts("YES");
  else
    puts("NO");
}
Esempio n. 5
0
option_values_t
destination_implObj::parse_attribute_values(info_t::lock &lock,
					    ipp_attribute_t *attrs,
					    const char *option_s,
					    bool unicode_flag)
{
	if (!attrs)
		return {};

	auto count=ippGetCount(attrs);

	auto tag_value=ippGetValueTag(attrs);

	switch (tag_value) {
	case IPP_TAG_NOVALUE:
		return {};
	case IPP_TAG_RANGE:
		{
			std::vector<std::tuple<int, int>> v;

			v.reserve(count);

			for (decltype (count) i=0; i<count; i++)
			{
				int upper;

				int lower=ippGetRange(attrs, i, &upper);

				v.emplace_back(lower, upper);
			}
			return v;
		}
	case IPP_TAG_RESOLUTION:
		{
			std::vector<resolution> v;

			v.reserve(count);

			for (decltype (count) i=0; i<count; i++)
			{
				resolution res;
				ipp_res_t units;

				res.xres=ippGetResolution(attrs, i,
							  &res.yres, &units);

				switch (units) {
				case IPP_RES_PER_INCH:
					res.units=res.per_inch;
					break;
				case IPP_RES_PER_CM:
					res.units=res.per_cm;
					break;
				default:
					res.units=res.unknown;
				}
				v.push_back(res);
			}
			return v;
		}

	case IPP_TAG_INTEGER:
		{
			std::unordered_set<int> v;

			for (decltype (count) i=0; i<count; i++)
			{
				v.insert(ippGetInteger(attrs, i));
			}
			return v;
		}
	case IPP_TAG_BOOLEAN:
		{
			std::unordered_set<bool> v;

			for (decltype (count) i=0; i<count; i++)
			{
				v.insert(ippGetBoolean(attrs, i));
			}
			return v;
		}
	case IPP_TAG_ENUM:
		if (unicode_flag)
		{
			auto l=locale::base::global();

			std::unordered_map<int, std::u32string> v;

			for (decltype (count) i=0; i<count; i++)
			{
				auto value=ippGetInteger(attrs, i);

				auto s=enum_string(option_s, value);

				auto us=unicode::iconvert::tou
					::convert(s, l->charset()).first;

				v.emplace(value, us);
			}
			return v;
		}
		else
		{
			std::unordered_map<int, std::string> v;

			for (decltype (count) i=0; i<count; i++)
			{
				auto value=ippGetInteger(attrs, i);


				v.emplace(value, enum_string(option_s, value));
			}
			return v;
		}
	case IPP_TAG_BEGIN_COLLECTION:
		{
			std::vector<const_collection> v;

			v.reserve(count);

			for (decltype (count) i=0; i<count; i++)
			{
				auto ippc=ippGetCollection(attrs, i);

				auto c=collection::create();

				for (auto attr=ippFirstAttribute(ippc);
				     attr;
				     attr=ippNextAttribute(ippc))
				{
					std::string n=ippGetName(attr);
					c->emplace(n, parse_attribute_values
						   (lock, attr, n.c_str(),
						    unicode_flag));
				}
				v.push_back(c);
			}
			return v;
		}
	default:
		break;
	}

	std::unordered_map<std::string, std::string> v;

	bool is_media=strcmp(option_s, CUPS_MEDIA) == 0;

	auto localizer=strcmp(option_s, CUPS_SIDES) == 0
		? sides
		: strcmp(option_s, CUPS_PRINT_COLOR_MODE) == 0
		? print_color_mode
		: no_localizer;

	for (decltype (count) i=0; i<count; i++)
	{
		const char *lang=0;

		auto val=ippGetString(attrs, i, &lang);

		if (!val)
		{

			std::ostringstream o;

			o << "{unknown tag "
			  << ippTagString(ippGetValueTag(attrs)) << "}";
			v.emplace(o.str(), "");
			continue;
		}

		std::string lang_s;

		if (is_media)
		{
			cups_size_t size;

			lang_s=val;

			if (cupsGetDestMediaByName(lock->http,
						   lock->dest,
						   lock->info,
						   val,
						   CUPS_MEDIA_FLAGS_DEFAULT,
						   &size))
			{
				auto l=cupsLocalizeDestMedia
					(lock->http,
					 lock->dest,
					 lock->info,
					 CUPS_MEDIA_FLAGS_DEFAULT,
					 &size);

				if (l)
					lang_s=l;
			}
		}
		else
		{
			auto c=cupsLocalizeDestValue(lock->http,
						     lock->dest,
						     lock->info,
						     option_s,
						     val);

			if (c && strcmp(c, val))
			{
				lang_s=c;
			}
			else
			{
				lang_s=localizer(val);
			}
		}
		v.emplace(val, lang_s);
	}

	if (!unicode_flag)
		return v;

	auto l=locale::base::global();

	std::unordered_map<std::string, std::u32string> uv;

	for (const auto &s:v)
	{
		auto n=s.first;


		uv.emplace(s.first,
			   unicode::iconvert::tou::convert(s.second,
							   l->charset())
			   .first);
	}
	return uv;
}
Esempio n. 6
0
ipp_t *					/* O - Attributes */
serverLoadAttributes(
    const char *filename,		/* I - File to load */
    char       **authtype,		/* O - Authentication type, if any */
    char       **command,		/* O - Command to run, if any */
    char       **device_uri,		/* O - Device URI, if any */
    char       **make,			/* O - Manufacturer */
    char       **model,			/* O - Model */
    char       **proxy_user)		/* O - Proxy user, if any */
{
  ipp_t		*attrs;			/* Attributes to return */
  cups_file_t	*fp;			/* File */
  int		linenum = 0;		/* Current line number */
  char		attr[128],		/* Attribute name */
		token[1024],		/* Token from file */
		*tokenptr;		/* Pointer into token */
  ipp_tag_t	value;			/* Current value type */
  ipp_attribute_t *attrptr;		/* Attribute pointer */


  if ((fp = cupsFileOpen(filename, "r")) == NULL)
  {
    serverLog(SERVER_LOGLEVEL_ERROR, "Unable to open \"%s\": %s", filename, strerror(errno));
    return (NULL);
  }

  attrs = ippNew();

  while (get_token(fp, token, sizeof(token), &linenum) != NULL)
  {
    if (!_cups_strcasecmp(token, "ATTR"))
    {
     /*
      * Attribute...
      */

      if (!get_token(fp, token, sizeof(token), &linenum))
      {
	serverLog(SERVER_LOGLEVEL_ERROR, "Missing ATTR value tag on line %d of \"%s\".", linenum, filename);
        goto load_error;
      }

      if ((value = ippTagValue(token)) == IPP_TAG_ZERO)
      {
	serverLog(SERVER_LOGLEVEL_ERROR, "Bad ATTR value tag \"%s\" on line %d of \"%s\".", token, linenum, filename);
        goto load_error;
      }

      if (!get_token(fp, attr, sizeof(attr), &linenum))
      {
	serverLog(SERVER_LOGLEVEL_ERROR, "Missing ATTR name on line %d of \"%s\".", linenum, filename);
        goto load_error;
      }

      if (!get_token(fp, token, sizeof(token), &linenum))
      {
	serverLog(SERVER_LOGLEVEL_ERROR, "Missing ATTR value on line %d of \"%s\".", linenum, filename);
        goto load_error;
      }

      attrptr = NULL;

      switch (value)
      {
	case IPP_TAG_BOOLEAN :
	    if (!_cups_strcasecmp(token, "true"))
	      attrptr = ippAddBoolean(attrs, IPP_TAG_PRINTER, attr, 1);
	    else
	      attrptr = ippAddBoolean(attrs, IPP_TAG_PRINTER, attr, (char)atoi(token));
	    break;

	case IPP_TAG_INTEGER :
	case IPP_TAG_ENUM :
	    if (!strchr(token, ','))
	      attrptr = ippAddInteger(attrs, IPP_TAG_PRINTER, value, attr, (int)strtol(token, &tokenptr, 0));
	    else
	    {
	      int	values[100],	/* Values */
			num_values = 1;	/* Number of values */

	      values[0] = (int)strtol(token, &tokenptr, 10);
	      while (tokenptr && *tokenptr &&
		     num_values < (int)(sizeof(values) / sizeof(values[0])))
	      {
		if (*tokenptr == ',')
		  tokenptr ++;
		else if (!isdigit(*tokenptr & 255) && *tokenptr != '-')
		  break;

		values[num_values] = (int)strtol(tokenptr, &tokenptr, 0);
		num_values ++;
	      }

	      attrptr = ippAddIntegers(attrs, IPP_TAG_PRINTER, value, attr, num_values, values);
	    }

	    if (!tokenptr || *tokenptr)
	    {
	      serverLog(SERVER_LOGLEVEL_ERROR, "Bad %s value \"%s\" on line %d of \"%s\".", ippTagString(value), token, linenum, filename);
              goto load_error;
	    }
	    break;

	case IPP_TAG_RESOLUTION :
	    {
	      int	xres,		/* X resolution */
			yres;		/* Y resolution */
	      ipp_res_t	units;		/* Units */
	      char	*start,		/* Start of value */
			*ptr,		/* Pointer into value */
			*next = NULL;	/* Next value */

	      for (start = token; start; start = next)
	      {
		xres = yres = (int)strtol(start, (char **)&ptr, 10);
		if (ptr > start && xres > 0)
		{
		  if (*ptr == 'x')
		    yres = (int)strtol(ptr + 1, (char **)&ptr, 10);
		}

		if (ptr && (next = strchr(ptr, ',')) != NULL)
		  *next++ = '\0';

		if (ptr <= start || xres <= 0 || yres <= 0 || !ptr ||
		    (_cups_strcasecmp(ptr, "dpi") &&
		     _cups_strcasecmp(ptr, "dpc") &&
		     _cups_strcasecmp(ptr, "dpcm") &&
		     _cups_strcasecmp(ptr, "other")))
		{
		  serverLog(SERVER_LOGLEVEL_ERROR, "Bad resolution value \"%s\" on line %d of \"%s\".", token, linenum, filename);
                  goto load_error;
		}

		if (!_cups_strcasecmp(ptr, "dpc") || !_cups_strcasecmp(ptr, "dpcm"))
		  units = IPP_RES_PER_CM;
		else
		  units = IPP_RES_PER_INCH;

                if (attrptr)
		  ippSetResolution(attrs, &attrptr, ippGetCount(attrptr), units, xres, yres);
		else
		  attrptr = ippAddResolution(attrs, IPP_TAG_PRINTER, attr, units, xres, yres);
	      }
	    }
	    break;

	case IPP_TAG_RANGE :
	    {
	      int	lowers[4],	/* Lower value */
			uppers[4],	/* Upper values */
			num_vals;	/* Number of values */


	      num_vals = sscanf(token, "%d-%d,%d-%d,%d-%d,%d-%d",
				lowers + 0, uppers + 0,
				lowers + 1, uppers + 1,
				lowers + 2, uppers + 2,
				lowers + 3, uppers + 3);

	      if ((num_vals & 1) || num_vals == 0)
	      {
		serverLog(SERVER_LOGLEVEL_ERROR, "Bad rangeOfInteger value \"%s\" on line %d of \"%s\".", token, linenum, filename);
                goto load_error;
	      }

	      attrptr = ippAddRanges(attrs, IPP_TAG_PRINTER, attr, num_vals / 2, lowers,
				     uppers);
	    }
	    break;

	case IPP_TAG_BEGIN_COLLECTION :
	    if (!strcmp(token, "{"))
	    {
	      ipp_t	*col = get_collection(fp, filename, &linenum);
				    /* Collection value */

	      if (col)
	      {
		attrptr = ippAddCollection(attrs, IPP_TAG_PRINTER, attr, col);
		ippDelete(col);
	      }
	      else
		exit(1);
	    }
	    else
	    {
	      serverLog(SERVER_LOGLEVEL_ERROR, "Bad ATTR collection value on line %d of \"%s\".", linenum, filename);
              goto load_error;
	    }

	    do
	    {
	      ipp_t	*col;			/* Collection value */
	      long	pos = cupsFileTell(fp);	/* Save position of file */

	      if (!get_token(fp, token, sizeof(token), &linenum))
		break;

	      if (strcmp(token, ","))
	      {
		cupsFileSeek(fp, pos);
		break;
	      }

	      if (!get_token(fp, token, sizeof(token), &linenum) || strcmp(token, "{"))
	      {
		serverLog(SERVER_LOGLEVEL_ERROR, "Unexpected \"%s\" on line %d of \"%s\".", token, linenum, filename);
                goto load_error;
	      }

	      if ((col = get_collection(fp, filename, &linenum)) == NULL)
		break;

	      ippSetCollection(attrs, &attrptr, ippGetCount(attrptr), col);
	    }
	    while (!strcmp(token, "{"));
	    break;

	case IPP_TAG_STRING :
	    attrptr = ippAddOctetString(attrs, IPP_TAG_PRINTER, attr, token, (int)strlen(token));
	    break;

	default :
	    serverLog(SERVER_LOGLEVEL_ERROR, "Unsupported ATTR value tag %s on line %d of \"%s\".", ippTagString(value), linenum, filename);
            goto load_error;

	case IPP_TAG_TEXTLANG :
	case IPP_TAG_NAMELANG :
	case IPP_TAG_TEXT :
	case IPP_TAG_NAME :
	case IPP_TAG_KEYWORD :
	case IPP_TAG_URI :
	case IPP_TAG_URISCHEME :
	case IPP_TAG_CHARSET :
	case IPP_TAG_LANGUAGE :
	case IPP_TAG_MIMETYPE :
	    if (!strchr(token, ','))
	      attrptr = ippAddString(attrs, IPP_TAG_PRINTER, value, attr, NULL, token);
	    else
	    {
	     /*
	      * Multiple string values...
	      */

	      int	num_values;	/* Number of values */
	      char	*values[100],	/* Values */
			*ptr;		/* Pointer to next value */


	      values[0]  = token;
	      num_values = 1;

	      for (ptr = strchr(token, ','); ptr; ptr = strchr(ptr, ','))
	      {
		if (ptr > token && ptr[-1] == '\\')
		  _cups_strcpy(ptr - 1, ptr);
		else
		{
		  *ptr++ = '\0';
		  values[num_values] = ptr;
		  num_values ++;
		  if (num_values >= (int)(sizeof(values) / sizeof(values[0])))
		    break;
		}
	      }

	      attrptr = ippAddStrings(attrs, IPP_TAG_PRINTER, value, attr, num_values, NULL, (const char **)values);
	    }
	    break;
      }

      if (!attrptr)
      {
        serverLog(SERVER_LOGLEVEL_ERROR, "Unable to add attribute on line %d of \"%s\": %s", linenum, filename, cupsLastErrorString());
        goto load_error;
      }
    }
    else if (!_cups_strcasecmp(token, "AUTHTYPE") && authtype)
    {
      if (!get_token(fp, token, sizeof(token), &linenum))
      {
	serverLog(SERVER_LOGLEVEL_ERROR, "Missing AUTHTYPE value on line %d of \"%s\".", linenum, filename);
        goto load_error;
      }

      *authtype = strdup(token);
    }
    else if (!_cups_strcasecmp(token, "COMMAND") && command)
    {
      if (!get_token(fp, token, sizeof(token), &linenum))
      {
	serverLog(SERVER_LOGLEVEL_ERROR, "Missing COMMAND value on line %d of \"%s\".", linenum, filename);
        goto load_error;
      }

      *command = strdup(token);
    }
    else if (!_cups_strcasecmp(token, "DEVICEURI") && device_uri)
    {
      if (!get_token(fp, token, sizeof(token), &linenum))
      {
	serverLog(SERVER_LOGLEVEL_ERROR, "Missing DEVICE-URI value on line %d of \"%s\".", linenum, filename);
        goto load_error;
      }

      *device_uri = strdup(token);
    }
    else if (!_cups_strcasecmp(token, "MAKE") && make)
    {
      if (!get_token(fp, token, sizeof(token), &linenum))
      {
	serverLog(SERVER_LOGLEVEL_ERROR, "Missing MAKE value on line %d of \"%s\".", linenum, filename);
        goto load_error;
      }

      *make = strdup(token);
    }
    else if (!_cups_strcasecmp(token, "MODEL") && model)
    {
      if (!get_token(fp, token, sizeof(token), &linenum))
      {
	serverLog(SERVER_LOGLEVEL_ERROR, "Missing MODEL value on line %d of \"%s\".", linenum, filename);
        goto load_error;
      }

      *model = strdup(token);
    }
    else if (!_cups_strcasecmp(token, "PROXYUSER") && proxy_user)
    {
      if (!get_token(fp, token, sizeof(token), &linenum))
      {
	serverLog(SERVER_LOGLEVEL_ERROR, "Missing PROXY-USER value on line %d of \"%s\".", linenum, filename);
        goto load_error;
      }

      *proxy_user = strdup(token);
    }
    else
    {
      serverLog(SERVER_LOGLEVEL_ERROR, "Unknown directive \"%s\" on line %d of \"%s\".", token, linenum, filename);
      goto load_error;
    }
  }

  cupsFileClose(fp);

  return (attrs);

 /*
  * If we get here something bad happened...
  */

  load_error:

  cupsFileClose(fp);

  ippDelete(attrs);

  return (NULL);
}