Exemplo n.º 1
0
int					/* O - 1 on success, 0 on failure */
cupsSetServerCredentials(
    const char *path,			/* I - Path to keychain/directory */
    const char *common_name,		/* I - Default common name for server */
    int        auto_create)		/* I - 1 = automatically create self-signed certificates */
{
  char	temp[1024];			/* Default path buffer */


  DEBUG_printf(("cupsSetServerCredentials(path=\"%s\", common_name=\"%s\", auto_create=%d)", path, common_name, auto_create));

 /*
  * Use defaults as needed...
  */

  if (!path)
    path = http_gnutls_default_path(temp, sizeof(temp));

 /*
  * Range check input...
  */

  if (!path || !common_name)
  {
    _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0);
    return (0);
  }

  _cupsMutexLock(&tls_mutex);

 /*
  * Free old values...
  */

  if (tls_keypath)
    _cupsStrFree(tls_keypath);

  if (tls_common_name)
    _cupsStrFree(tls_common_name);

 /*
  * Save the new values...
  */

  tls_keypath     = _cupsStrAlloc(path);
  tls_auto_create = auto_create;
  tls_common_name = _cupsStrAlloc(common_name);

  _cupsMutexUnlock(&tls_mutex);

  return (1);
}
Exemplo n.º 2
0
void
cupsdSetStringf(char       **s,		/* O - New string */
                const char *f,		/* I - Printf-style format string */
	        ...)			/* I - Additional args as needed */
{
  char		v[4096];		/* Formatting string value */
  va_list	ap;			/* Argument pointer */
  char		*olds;			/* Old string */


  if (!s)
    return;

  olds = *s;

  if (f)
  {
    va_start(ap, f);
    vsnprintf(v, sizeof(v), f, ap);
    va_end(ap);

    *s = _cupsStrAlloc(v);
  }
  else
    *s = NULL;

  if (olds)
    _cupsStrFree(olds);
}
Exemplo n.º 3
0
void
cgiSetVariable(const char *name,	/* I - Name of variable */
               const char *value)	/* I - Value of variable */
{
  int		i;			/* Looping var */
  _cgi_var_t	*var;			/* Returned variable */


  if (name == NULL || value == NULL)
    return;

  fprintf(stderr, "cgiSetVariable: %s=\"%s\"\n", name, value);

  if ((var = cgi_find_variable(name)) == NULL)
  {
    cgi_add_variable(name, 0, value);
    cgi_sort_variables();
  }
  else
  {
    for (i = 0; i < var->nvalues; i ++)
      if (var->values[i])
        _cupsStrFree((char *)var->values[i]);

    var->values[0] = _cupsStrAlloc(value);
    var->nvalues   = 1;
  }
}
Exemplo n.º 4
0
void
_cupsSetError(ipp_status_t status,	/* I - IPP status code */
              const char   *message,	/* I - status-message value */
	      int          localize)	/* I - Localize the message? */
{
  _cups_globals_t	*cg;		/* Global data */


  if (!message && errno)
  {
    message  = strerror(errno);
    localize = 0;
  }

  cg             = _cupsGlobals();
  cg->last_error = status;

  if (cg->last_status_message)
  {
    _cupsStrFree(cg->last_status_message);

    cg->last_status_message = NULL;
  }

  if (message)
  {
    if (localize)
    {
     /*
      * Get the message catalog...
      */

      if (!cg->lang_default)
	cg->lang_default = cupsLangDefault();

      cg->last_status_message = _cupsStrAlloc(_cupsLangString(cg->lang_default,
                                                              message));
    }
    else
      cg->last_status_message = _cupsStrAlloc(message);
  }

  DEBUG_printf(("4_cupsSetError: last_error=%s, last_status_message=\"%s\"",
                ippErrorString(cg->last_error), cg->last_status_message));
}
Exemplo n.º 5
0
static void
cgi_add_variable(const char *name,	/* I - Variable name */
		 int        element,	/* I - Array element number */
                 const char *value)	/* I - Variable value */
{
  _cgi_var_t	*var;			/* New variable */


  if (name == NULL || value == NULL || element < 0 || element > 100000)
    return;

  DEBUG_printf(("cgi_add_variable: Adding variable \'%s\' with value "
                "\'%s\'...\n", name, value));

  if (form_count >= form_alloc)
  {
    _cgi_var_t	*temp_vars;		/* Temporary form pointer */


    if (form_alloc == 0)
      temp_vars = malloc(sizeof(_cgi_var_t) * 16);
    else
      temp_vars = realloc(form_vars, (size_t)(form_alloc + 16) * sizeof(_cgi_var_t));

    if (!temp_vars)
      return;

    form_vars  = temp_vars;
    form_alloc += 16;
  }

  var = form_vars + form_count;

  if ((var->values = calloc((size_t)element + 1, sizeof(char *))) == NULL)
    return;

  var->name            = _cupsStrAlloc(name);
  var->nvalues         = element + 1;
  var->avalues         = element + 1;
  var->values[element] = _cupsStrAlloc(value);

  form_count ++;
}
Exemplo n.º 6
0
void
cupsdSetString(char       **s,		/* O - New string */
               const char *v)		/* I - String value */
{
  if (!s || *s == v)
    return;

  if (*s)
    _cupsStrFree(*s);

  if (v)
    *s = _cupsStrAlloc(v);
  else
    *s = NULL;
}
Exemplo n.º 7
0
void
cgiSetArray(const char *name,		/* I - Name of variable */
            int        element,		/* I - Element number (0 to N) */
            const char *value)		/* I - Value of variable */
{
  int		i;			/* Looping var */
  _cgi_var_t	*var;			/* Returned variable */


  if (name == NULL || value == NULL || element < 0 || element > 100000)
    return;

  fprintf(stderr, "DEBUG: cgiSetArray: %s[%d]=\"%s\"\n", name, element, value);

  if ((var = cgi_find_variable(name)) == NULL)
  {
    cgi_add_variable(name, element, value);
    cgi_sort_variables();
  }
  else
  {
    if (element >= var->avalues)
    {
      const char **temp;		/* Temporary pointer */

      temp = (const char **)realloc((void *)(var->values),
                                    sizeof(char *) * (size_t)(element + 16));
      if (!temp)
        return;

      var->avalues = element + 16;
      var->values  = temp;
    }

    if (element >= var->nvalues)
    {
      for (i = var->nvalues; i < element; i ++)
	var->values[i] = NULL;

      var->nvalues = element + 1;
    }
    else if (var->values[element])
      _cupsStrFree((char *)var->values[element]);

    var->values[element] = _cupsStrAlloc(value);
  }
}
Exemplo n.º 8
0
static void
ppd_mark_option(ppd_file_t *ppd,	/* I - PPD file */
                const char *option,	/* I - Option name */
                const char *choice)	/* I - Choice name */
{
  int		i, j;			/* Looping vars */
  ppd_option_t	*o;			/* Option pointer */
  ppd_choice_t	*c,			/* Choice pointer */
		*oldc,			/* Old choice pointer */
		key;			/* Search key for choice */
  struct lconv	*loc;			/* Locale data */


  DEBUG_printf(("7ppd_mark_option(ppd=%p, option=\"%s\", choice=\"%s\")",
        	ppd, option, choice));

 /*
  * AP_D_InputSlot is the "default input slot" on MacOS X, and setting
  * it clears the regular InputSlot choices...
  */

  if (!_cups_strcasecmp(option, "AP_D_InputSlot"))
  {
    cupsArraySave(ppd->options);

    if ((o = ppdFindOption(ppd, "InputSlot")) != NULL)
    {
      key.option = o;
      if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL)
      {
        oldc->marked = 0;
        cupsArrayRemove(ppd->marked, oldc);
      }
    }

    cupsArrayRestore(ppd->options);
  }

 /*
  * Check for custom options...
  */

  cupsArraySave(ppd->options);

  o = ppdFindOption(ppd, option);

  cupsArrayRestore(ppd->options);

  if (!o)
    return;

  loc = localeconv();

  if (!_cups_strncasecmp(choice, "Custom.", 7))
  {
   /*
    * Handle a custom option...
    */

    if ((c = ppdFindChoice(o, "Custom")) == NULL)
      return;

    if (!_cups_strcasecmp(option, "PageSize"))
    {
     /*
      * Handle custom page sizes...
      */

      ppdPageSize(ppd, choice);
    }
    else
    {
     /*
      * Handle other custom options...
      */

      ppd_coption_t	*coption;	/* Custom option */
      ppd_cparam_t	*cparam;	/* Custom parameter */
      char		*units;		/* Custom points units */


      if ((coption = ppdFindCustomOption(ppd, option)) != NULL)
      {
        if ((cparam = (ppd_cparam_t *)cupsArrayFirst(coption->params)) == NULL)
	  return;

        switch (cparam->type)
	{
	  case PPD_CUSTOM_CURVE :
	  case PPD_CUSTOM_INVCURVE :
	  case PPD_CUSTOM_REAL :
	      cparam->current.custom_real = (float)_cupsStrScand(choice + 7,
	                                                         NULL, loc);
	      break;

	  case PPD_CUSTOM_POINTS :
	      cparam->current.custom_points = (float)_cupsStrScand(choice + 7,
	                                                           &units,
	                                                           loc);

              if (units)
	      {
        	if (!_cups_strcasecmp(units, "cm"))
	          cparam->current.custom_points *= 72.0f / 2.54f;
        	else if (!_cups_strcasecmp(units, "mm"))
	          cparam->current.custom_points *= 72.0f / 25.4f;
        	else if (!_cups_strcasecmp(units, "m"))
	          cparam->current.custom_points *= 72.0f / 0.0254f;
        	else if (!_cups_strcasecmp(units, "in"))
	          cparam->current.custom_points *= 72.0f;
        	else if (!_cups_strcasecmp(units, "ft"))
	          cparam->current.custom_points *= 12.0f * 72.0f;
              }
	      break;

	  case PPD_CUSTOM_INT :
	      cparam->current.custom_int = atoi(choice + 7);
	      break;

	  case PPD_CUSTOM_PASSCODE :
	  case PPD_CUSTOM_PASSWORD :
	  case PPD_CUSTOM_STRING :
	      if (cparam->current.custom_string)
	        _cupsStrFree(cparam->current.custom_string);

	      cparam->current.custom_string = _cupsStrAlloc(choice + 7);
	      break;
	}
      }
    }

   /*
    * Make sure that we keep the option marked below...
    */

    choice = "Custom";
  }
  else if (choice[0] == '{')
  {
   /*
    * Handle multi-value custom options...
    */

    ppd_coption_t	*coption;	/* Custom option */
    ppd_cparam_t	*cparam;	/* Custom parameter */
    char		*units;		/* Custom points units */
    int			num_vals;	/* Number of values */
    cups_option_t	*vals,		/* Values */
			*val;		/* Value */


    if ((c = ppdFindChoice(o, "Custom")) == NULL)
      return;

    if ((coption = ppdFindCustomOption(ppd, option)) != NULL)
    {
      num_vals = cupsParseOptions(choice, 0, &vals);

      for (i = 0, val = vals; i < num_vals; i ++, val ++)
      {
        if ((cparam = ppdFindCustomParam(coption, val->name)) == NULL)
	  continue;

	switch (cparam->type)
	{
	  case PPD_CUSTOM_CURVE :
	  case PPD_CUSTOM_INVCURVE :
	  case PPD_CUSTOM_REAL :
	      cparam->current.custom_real = (float)_cupsStrScand(val->value,
	                                                         NULL, loc);
	      break;

	  case PPD_CUSTOM_POINTS :
	      cparam->current.custom_points = (float)_cupsStrScand(val->value,
	                                                           &units,
	                                                           loc);

	      if (units)
	      {
        	if (!_cups_strcasecmp(units, "cm"))
		  cparam->current.custom_points *= 72.0f / 2.54f;
        	else if (!_cups_strcasecmp(units, "mm"))
		  cparam->current.custom_points *= 72.0f / 25.4f;
        	else if (!_cups_strcasecmp(units, "m"))
		  cparam->current.custom_points *= 72.0f / 0.0254f;
        	else if (!_cups_strcasecmp(units, "in"))
		  cparam->current.custom_points *= 72.0f;
        	else if (!_cups_strcasecmp(units, "ft"))
		  cparam->current.custom_points *= 12.0f * 72.0f;
	      }
	      break;

	  case PPD_CUSTOM_INT :
	      cparam->current.custom_int = atoi(val->value);
	      break;

	  case PPD_CUSTOM_PASSCODE :
	  case PPD_CUSTOM_PASSWORD :
	  case PPD_CUSTOM_STRING :
	      if (cparam->current.custom_string)
		_cupsStrFree(cparam->current.custom_string);

	      cparam->current.custom_string = _cupsStrRetain(val->value);
	      break;
	}
      }

      cupsFreeOptions(num_vals, vals);
    }
  }
  else
  {
    for (i = o->num_choices, c = o->choices; i > 0; i --, c ++)
      if (!_cups_strcasecmp(c->choice, choice))
        break;

    if (!i)
      return;
  }

 /*
  * Option found; mark it and then handle unmarking any other options.
  */

  if (o->ui != PPD_UI_PICKMANY)
  {
   /*
    * Unmark all other choices...
    */

    if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, c)) != NULL)
    {
      oldc->marked = 0;
      cupsArrayRemove(ppd->marked, oldc);
    }

    if (!_cups_strcasecmp(option, "PageSize") || !_cups_strcasecmp(option, "PageRegion"))
    {
     /*
      * Mark current page size...
      */

      for (j = 0; j < ppd->num_sizes; j ++)
	ppd->sizes[j].marked = !_cups_strcasecmp(ppd->sizes[j].name,
		                           choice);

     /*
      * Unmark the current PageSize or PageRegion setting, as
      * appropriate...
      */

      cupsArraySave(ppd->options);

      if (!_cups_strcasecmp(option, "PageSize"))
      {
	if ((o = ppdFindOption(ppd, "PageRegion")) != NULL)
        {
          key.option = o;
          if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL)
          {
            oldc->marked = 0;
            cupsArrayRemove(ppd->marked, oldc);
          }
        }
      }
      else
      {
	if ((o = ppdFindOption(ppd, "PageSize")) != NULL)
        {
          key.option = o;
          if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL)
          {
            oldc->marked = 0;
            cupsArrayRemove(ppd->marked, oldc);
          }
        }
      }

      cupsArrayRestore(ppd->options);
    }
    else if (!_cups_strcasecmp(option, "InputSlot"))
    {
     /*
      * Unmark ManualFeed option...
      */

      cupsArraySave(ppd->options);

      if ((o = ppdFindOption(ppd, "ManualFeed")) != NULL)
      {
        key.option = o;
        if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL)
        {
          oldc->marked = 0;
          cupsArrayRemove(ppd->marked, oldc);
        }
      }

      cupsArrayRestore(ppd->options);
    }
    else if (!_cups_strcasecmp(option, "ManualFeed") &&
	     !_cups_strcasecmp(choice, "True"))
    {
     /*
      * Unmark InputSlot option...
      */

      cupsArraySave(ppd->options);

      if ((o = ppdFindOption(ppd, "InputSlot")) != NULL)
      {
        key.option = o;
        if ((oldc = (ppd_choice_t *)cupsArrayFind(ppd->marked, &key)) != NULL)
        {
          oldc->marked = 0;
          cupsArrayRemove(ppd->marked, oldc);
        }
      }

      cupsArrayRestore(ppd->options);
    }
  }

  c->marked = 1;

  cupsArrayAdd(ppd->marked, c);
}
Exemplo n.º 9
0
int					/* O  - Number of options */
cupsAddOption(const char    *name,	/* I  - Name of option */
              const char    *value,	/* I  - Value of option */
	      int           num_options,/* I  - Number of options */
              cups_option_t **options)	/* IO - Pointer to options */
{
  cups_option_t	*temp;			/* Pointer to new option */
  int		insert,			/* Insertion point */
		diff;			/* Result of search */


  DEBUG_printf(("2cupsAddOption(name=\"%s\", value=\"%s\", num_options=%d, options=%p)", name, value, num_options, (void *)options));

  if (!name || !name[0] || !value || !options || num_options < 0)
  {
    DEBUG_printf(("3cupsAddOption: Returning %d", num_options));
    return (num_options);
  }

  if (!_cups_strcasecmp(name, "cupsPrintQuality"))
    num_options = cupsRemoveOption("print-quality", num_options, options);
  else if (!_cups_strcasecmp(name, "print-quality"))
    num_options = cupsRemoveOption("cupsPrintQuality", num_options, options);

 /*
  * Look for an existing option with the same name...
  */

  if (num_options == 0)
  {
    insert = 0;
    diff   = 1;
  }
  else
  {
    insert = cups_find_option(name, num_options, *options, num_options - 1,
                              &diff);

    if (diff > 0)
      insert ++;
  }

  if (diff)
  {
   /*
    * No matching option name...
    */

    DEBUG_printf(("4cupsAddOption: New option inserted at index %d...",
                  insert));

    if (num_options == 0)
      temp = (cups_option_t *)malloc(sizeof(cups_option_t));
    else
      temp = (cups_option_t *)realloc(*options, sizeof(cups_option_t) * (size_t)(num_options + 1));

    if (!temp)
    {
      DEBUG_puts("3cupsAddOption: Unable to expand option array, returning 0");
      return (0);
    }

    *options = temp;

    if (insert < num_options)
    {
      DEBUG_printf(("4cupsAddOption: Shifting %d options...",
                    (int)(num_options - insert)));
      memmove(temp + insert + 1, temp + insert, (size_t)(num_options - insert) * sizeof(cups_option_t));
    }

    temp        += insert;
    temp->name  = _cupsStrAlloc(name);
    num_options ++;
  }
  else
  {
   /*
    * Match found; free the old value...
    */

    DEBUG_printf(("4cupsAddOption: Option already exists at index %d...",
                  insert));

    temp = *options + insert;
    _cupsStrFree(temp->value);
  }

  temp->value = _cupsStrAlloc(value);

  DEBUG_printf(("3cupsAddOption: Returning %d", num_options));

  return (num_options);
}
Exemplo n.º 10
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.º 11
0
static int				/* O - 0 on success, 1 on fail */
delete_printer_from_class(
    http_t *http,			/* I - Server connection */
    char   *printer,			/* I - Printer to remove */
    char   *pclass)	  		/* I - Class to remove from */
{
  int		i, j, k;		/* Looping vars */
  ipp_t		*request,		/* IPP Request */
		*response;		/* IPP Response */
  ipp_attribute_t *attr,		/* Current attribute */
		*members;		/* Members in class */
  char		uri[HTTP_MAX_URI];	/* URI for printer/class */


  DEBUG_printf(("delete_printer_from_class(%p, \"%s\", \"%s\")\n", http,
                printer, pclass));

 /*
  * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
  * attributes:
  *
  *    attributes-charset
  *    attributes-natural-language
  *    printer-uri
  *    requesting-user-name
  */

  request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);

  httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
                   "localhost", 0, "/classes/%s", pclass);
  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());

 /*
  * Do the request and get back a response...
  */

  if ((response = cupsDoRequest(http, request, "/classes/")) == NULL ||
      response->request.status.status_code == IPP_NOT_FOUND)
  {
    _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString());

    ippDelete(response);

    return (1);
  }

 /*
  * See if the printer is already in the class...
  */

  if ((members = ippFindAttribute(response, "member-names", IPP_TAG_NAME)) == NULL)
  {
    _cupsLangPuts(stderr, _("lpadmin: No member names were seen."));

    ippDelete(response);

    return (1);
  }

  for (i = 0; i < members->num_values; i ++)
    if (!_cups_strcasecmp(printer, members->values[i].string.text))
      break;

  if (i >= members->num_values)
  {
    _cupsLangPrintf(stderr,
                    _("lpadmin: Printer %s is not a member of class %s."),
	            printer, pclass);

    ippDelete(response);

    return (1);
  }

  if (members->num_values == 1)
  {
   /*
    * Build a CUPS_DELETE_CLASS request, which requires the following
    * attributes:
    *
    *    attributes-charset
    *    attributes-natural-language
    *    printer-uri
    *    requesting-user-name
    */

    request = ippNewRequest(CUPS_DELETE_CLASS);

    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());
  }
  else
  {
   /*
    * Build a CUPS_ADD_MODIFY_CLASS request, which requires the following
    * attributes:
    *
    *    attributes-charset
    *    attributes-natural-language
    *    printer-uri
    *    requesting-user-name
    *    member-uris
    */

    request = ippNewRequest(CUPS_ADD_MODIFY_CLASS);

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

   /*
    * Delete the printer from the class...
    */

    members = ippFindAttribute(response, "member-uris", IPP_TAG_URI);
    attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_URI,
                         "member-uris", members->num_values - 1, NULL, NULL);

    for (j = 0, k = 0; j < members->num_values; j ++)
      if (j != i)
        attr->values[k ++].string.text =
	    _cupsStrAlloc(members->values[j].string.text);
  }

 /*
  * Then send the request...
  */

  ippDelete(response);

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

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

    return (1);
  }
  else
    return (0);
}
Exemplo n.º 12
0
static int				/* O - 0 on success, 1 on fail */
add_printer_to_class(http_t *http,	/* I - Server connection */
                     char   *printer,	/* I - Printer to add */
		     char   *pclass)	/* I - Class to add to */
{
  int		i;			/* Looping var */
  ipp_t		*request,		/* IPP Request */
		*response;		/* IPP Response */
  ipp_attribute_t *attr,		/* Current attribute */
		*members;		/* Members in class */
  char		uri[HTTP_MAX_URI];	/* URI for printer/class */


  DEBUG_printf(("add_printer_to_class(%p, \"%s\", \"%s\")\n", http,
                printer, pclass));

 /*
  * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
  * attributes:
  *
  *    attributes-charset
  *    attributes-natural-language
  *    printer-uri
  *    requesting-user-name
  */

  request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);

  httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
                   "localhost", 0, "/classes/%s", pclass);
  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());

 /*
  * Do the request and get back a response...
  */

  response = cupsDoRequest(http, request, "/");

 /*
  * Build a CUPS_ADD_MODIFY_CLASS request, which requires the following
  * attributes:
  *
  *    attributes-charset
  *    attributes-natural-language
  *    printer-uri
  *    requesting-user-name
  *    member-uris
  */

  request = ippNewRequest(CUPS_ADD_MODIFY_CLASS);

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

 /*
  * See if the printer is already in the class...
  */

  if (response != NULL &&
      (members = ippFindAttribute(response, "member-names",
                                  IPP_TAG_NAME)) != NULL)
    for (i = 0; i < members->num_values; i ++)
      if (_cups_strcasecmp(printer, members->values[i].string.text) == 0)
      {
        _cupsLangPrintf(stderr,
	                _("lpadmin: Printer %s is already a member of class "
			  "%s."), printer, pclass);
        ippDelete(request);
	ippDelete(response);
	return (0);
      }

 /*
  * OK, the printer isn't part of the class, so add it...
  */

  httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
                   "localhost", 0, "/printers/%s", printer);

  if (response != NULL &&
      (members = ippFindAttribute(response, "member-uris",
                                  IPP_TAG_URI)) != NULL)
  {
   /*
    * Add the printer to the existing list...
    */

    attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_URI,
                         "member-uris", members->num_values + 1, NULL, NULL);
    for (i = 0; i < members->num_values; i ++)
      attr->values[i].string.text =
          _cupsStrAlloc(members->values[i].string.text);

    attr->values[i].string.text = _cupsStrAlloc(uri);
  }
  else
    ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "member-uris", NULL,
                 uri);

 /*
  * Then send the request...
  */

  ippDelete(response);

  ippDelete(cupsDoRequest(http, request, "/admin/"));
  if (cupsLastError() > IPP_OK_CONFLICT)
  {
    _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString());

    return (1);
  }
  else
    return (0);
}
Exemplo n.º 13
0
int					/* O - Number of jobs */
cupsGetJobs2(http_t     *http,		/* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */
             cups_job_t **jobs,		/* O - Job data */
             const char *name,		/* I - @code NULL@ = all destinations, otherwise show jobs for named destination */
             int        myjobs,		/* I - 0 = all users, 1 = mine */
	     int        whichjobs)	/* I - @code CUPS_WHICHJOBS_ALL@, @code CUPS_WHICHJOBS_ACTIVE@, or @code CUPS_WHICHJOBS_COMPLETED@ */
{
  int		n;			/* Number of jobs */
  ipp_t		*request,		/* IPP Request */
		*response;		/* IPP Response */
  ipp_attribute_t *attr;		/* Current attribute */
  cups_job_t	*temp;			/* Temporary pointer */
  int		id,			/* job-id */
		priority,		/* job-priority */
		size;			/* job-k-octets */
  ipp_jstate_t	state;			/* job-state */
  time_t	completed_time,		/* time-at-completed */
		creation_time,		/* time-at-creation */
		processing_time;	/* time-at-processing */
  const char	*dest,			/* job-printer-uri */
		*format,		/* document-format */
		*title,			/* job-name */
		*user;			/* job-originating-user-name */
  char		uri[HTTP_MAX_URI];	/* URI for jobs */
  _cups_globals_t *cg = _cupsGlobals();	/* Pointer to library globals */
  static const char * const attrs[] =	/* Requested attributes */
		{
		  "document-format",
		  "job-id",
		  "job-k-octets",
		  "job-name",
		  "job-originating-user-name",
		  "job-printer-uri",
		  "job-priority",
		  "job-state",
		  "time-at-completed",
		  "time-at-creation",
		  "time-at-processing"
		};


 /*
  * Range check input...
  */

  if (!jobs)
  {
    _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0);

    return (-1);
  }

 /*
  * Get the right URI...
  */

  if (name)
  {
    if (httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
                         "localhost", 0, "/printers/%s", name) != HTTP_URI_OK)
    {
      _cupsSetError(IPP_INTERNAL_ERROR, _("Unable to create printer-uri"), 1);

      return (-1);
    }
  }
  else
    strcpy(uri, "ipp://localhost/");

  if (!http)
    if ((http = _cupsConnect()) == NULL)
      return (-1);

 /*
  * Build an IPP_GET_JOBS request, which requires the following
  * attributes:
  *
  *    attributes-charset
  *    attributes-natural-language
  *    printer-uri
  *    requesting-user-name
  *    which-jobs
  *    my-jobs
  *    requested-attributes
  */

  request = ippNewRequest(IPP_GET_JOBS);

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

  if (myjobs)
    ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1);

  if (whichjobs == CUPS_WHICHJOBS_COMPLETED)
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
                 "which-jobs", NULL, "completed");
  else if (whichjobs == CUPS_WHICHJOBS_ALL)
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
                 "which-jobs", NULL, "all");

  ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
                "requested-attributes", sizeof(attrs) / sizeof(attrs[0]),
		NULL, attrs);

 /*
  * Do the request and get back a response...
  */

  n     = 0;
  *jobs = NULL;

  if ((response = cupsDoRequest(http, request, "/")) != NULL)
  {
    for (attr = response->attrs; attr; attr = attr->next)
    {
     /*
      * Skip leading attributes until we hit a job...
      */

      while (attr && attr->group_tag != IPP_TAG_JOB)
        attr = attr->next;

      if (!attr)
        break;

     /*
      * Pull the needed attributes from this job...
      */

      id              = 0;
      size            = 0;
      priority        = 50;
      state           = IPP_JOB_PENDING;
      user            = "******";
      dest            = NULL;
      format          = "application/octet-stream";
      title           = "untitled";
      creation_time   = 0;
      completed_time  = 0;
      processing_time = 0;

      while (attr && attr->group_tag == IPP_TAG_JOB)
      {
        if (!strcmp(attr->name, "job-id") &&
	    attr->value_tag == IPP_TAG_INTEGER)
	  id = attr->values[0].integer;
        else if (!strcmp(attr->name, "job-state") &&
	         attr->value_tag == IPP_TAG_ENUM)
	  state = (ipp_jstate_t)attr->values[0].integer;
        else if (!strcmp(attr->name, "job-priority") &&
	         attr->value_tag == IPP_TAG_INTEGER)
	  priority = attr->values[0].integer;
        else if (!strcmp(attr->name, "job-k-octets") &&
	         attr->value_tag == IPP_TAG_INTEGER)
	  size = attr->values[0].integer;
        else if (!strcmp(attr->name, "time-at-completed") &&
	         attr->value_tag == IPP_TAG_INTEGER)
	  completed_time = attr->values[0].integer;
        else if (!strcmp(attr->name, "time-at-creation") &&
	         attr->value_tag == IPP_TAG_INTEGER)
	  creation_time = attr->values[0].integer;
        else if (!strcmp(attr->name, "time-at-processing") &&
	         attr->value_tag == IPP_TAG_INTEGER)
	  processing_time = attr->values[0].integer;
        else if (!strcmp(attr->name, "job-printer-uri") &&
	         attr->value_tag == IPP_TAG_URI)
	{
	  if ((dest = strrchr(attr->values[0].string.text, '/')) != NULL)
	    dest ++;
        }
        else if (!strcmp(attr->name, "job-originating-user-name") &&
	         attr->value_tag == IPP_TAG_NAME)
	  user = attr->values[0].string.text;
        else if (!strcmp(attr->name, "document-format") &&
	         attr->value_tag == IPP_TAG_MIMETYPE)
	  format = attr->values[0].string.text;
        else if (!strcmp(attr->name, "job-name") &&
	         (attr->value_tag == IPP_TAG_TEXT ||
		  attr->value_tag == IPP_TAG_NAME))
	  title = attr->values[0].string.text;

        attr = attr->next;
      }

     /*
      * See if we have everything needed...
      */

      if (!dest || !id)
      {
        if (!attr)
	  break;
	else
          continue;
      }

     /*
      * Allocate memory for the job...
      */

      if (n == 0)
        temp = malloc(sizeof(cups_job_t));
      else
	temp = realloc(*jobs, sizeof(cups_job_t) * (n + 1));

      if (!temp)
      {
       /*
        * Ran out of memory!
        */

        _cupsSetError(IPP_INTERNAL_ERROR, NULL, 0);

	cupsFreeJobs(n, *jobs);
	*jobs = NULL;

        ippDelete(response);

	return (-1);
      }

      *jobs = temp;
      temp  += n;
      n ++;

     /*
      * Copy the data over...
      */

      temp->dest            = _cupsStrAlloc(dest);
      temp->user            = _cupsStrAlloc(user);
      temp->format          = _cupsStrAlloc(format);
      temp->title           = _cupsStrAlloc(title);
      temp->id              = id;
      temp->priority        = priority;
      temp->state           = state;
      temp->size            = size;
      temp->completed_time  = completed_time;
      temp->creation_time   = creation_time;
      temp->processing_time = processing_time;

      if (!attr)
        break;
    }

    ippDelete(response);
  }

  if (n == 0 && cg->last_error >= IPP_BAD_REQUEST)
    return (-1);
  else
    return (n);
}
Exemplo n.º 14
0
void
cupsdLoadAllClasses(void)
{
  int			i;		/* Looping var */
  cups_file_t		*fp;		/* classes.conf file */
  int			linenum;	/* Current line number */
  char			line[4096],	/* Line from file */
			*value,		/* Pointer to value */
			*valueptr;	/* Pointer into value */
  cupsd_printer_t	*p,		/* Current printer class */
			*temp;		/* Temporary pointer to printer */


 /*
  * Open the classes.conf file...
  */

  snprintf(line, sizeof(line), "%s/classes.conf", ServerRoot);
  if ((fp = cupsFileOpen(line, "r")) == NULL)
  {
    if (errno != ENOENT)
      cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open %s - %s", line,
		      strerror(errno));
    return;
  }

 /*
  * Read class configurations until we hit EOF...
  */

  linenum = 0;
  p       = NULL;

  while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
  {
   /*
    * Decode the directive...
    */

    if (!strcasecmp(line, "<Class") ||
        !strcasecmp(line, "<DefaultClass"))
    {
     /*
      * <Class name> or <DefaultClass name>
      */

      if (p == NULL && value)
      {
        cupsdLogMessage(CUPSD_LOG_DEBUG, "Loading class %s...", value);

       /*
        * Since prior classes may have implicitly defined this class,
	* see if it already exists...
	*/

        if ((p = cupsdFindDest(value)) != NULL)
	{
	  p->type = CUPS_PRINTER_CLASS;
	  cupsdSetStringf(&p->uri, "ipp://%s:%d/classes/%s", ServerName,
	                  LocalPort, value);
	  cupsdSetString(&p->error_policy, "retry-job");
	}
	else
          p = cupsdAddClass(value);

	p->accepting = 1;
	p->state     = IPP_PRINTER_IDLE;

        if (!strcasecmp(line, "<DefaultClass"))
	  DefaultPrinter = p;
      }
      else
        cupsdLogMessage(CUPSD_LOG_ERROR,
	                "Syntax error on line %d of classes.conf.", linenum);
    }
    else if (!strcasecmp(line, "</Class>"))
    {
      if (p != NULL)
      {
        cupsdSetPrinterAttrs(p);
        p = NULL;
      }
      else
        cupsdLogMessage(CUPSD_LOG_ERROR,
	                "Syntax error on line %d of classes.conf.", linenum);
    }
    else if (!p)
    {
      cupsdLogMessage(CUPSD_LOG_ERROR,
                      "Syntax error on line %d of classes.conf.", linenum);
    }
    else if (!strcasecmp(line, "AuthInfoRequired"))
    {
      if (!cupsdSetAuthInfoRequired(p, value, NULL))
	cupsdLogMessage(CUPSD_LOG_ERROR,
			"Bad AuthInfoRequired on line %d of classes.conf.",
			linenum);
    }
    else if (!strcasecmp(line, "Info"))
    {
      if (value)
        cupsdSetString(&p->info, value);
    }
    else if (!strcasecmp(line, "Location"))
    {
      if (value)
        cupsdSetString(&p->location, value);
    }
    else if (!strcasecmp(line, "Option") && value)
    {
     /*
      * Option name value
      */

      for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++);

      if (!*valueptr)
        cupsdLogMessage(CUPSD_LOG_ERROR,
	                "Syntax error on line %d of classes.conf.", linenum);
      else
      {
        for (; *valueptr && isspace(*valueptr & 255); *valueptr++ = '\0');

        p->num_options = cupsAddOption(value, valueptr, p->num_options,
	                               &(p->options));
      }
    }
    else if (!strcasecmp(line, "Printer"))
    {
      if (!value)
      {
	cupsdLogMessage(CUPSD_LOG_ERROR,
	                "Syntax error on line %d of classes.conf.", linenum);
        continue;
      }
      else if ((temp = cupsdFindPrinter(value)) == NULL)
      {
	cupsdLogMessage(CUPSD_LOG_WARN,
	                "Unknown printer %s on line %d of classes.conf.",
	                value, linenum);

       /*
	* Add the missing remote printer...
	*/

	if ((temp = cupsdAddPrinter(value)) != NULL)
	{
	  cupsdSetString(&temp->make_model, "Remote Printer on unknown");

          temp->state       = IPP_PRINTER_STOPPED;
	  temp->type        |= CUPS_PRINTER_REMOTE;
	  temp->browse_time = 2147483647;

	  cupsdSetString(&temp->location, "Location Unknown");
	  cupsdSetString(&temp->info, "No Information Available");
	  temp->hostname[0] = '\0';

	  cupsdSetPrinterAttrs(temp);
	}
      }

      if (temp)
        cupsdAddPrinterToClass(p, temp);
    }
    else if (!strcasecmp(line, "State"))
    {
     /*
      * Set the initial queue state...
      */

      if (!strcasecmp(value, "idle"))
        p->state = IPP_PRINTER_IDLE;
      else if (!strcasecmp(value, "stopped"))
      {
        p->state = IPP_PRINTER_STOPPED;

        for (i = 0 ; i < p->num_reasons; i ++)
	  if (!strcmp("paused", p->reasons[i]))
	    break;

        if (i >= p->num_reasons &&
	    p->num_reasons < (int)(sizeof(p->reasons) / sizeof(p->reasons[0])))
	{
	  p->reasons[p->num_reasons] = _cupsStrAlloc("paused");
	  p->num_reasons ++;
	}
      }
      else
	cupsdLogMessage(CUPSD_LOG_ERROR,
	                "Syntax error on line %d of classes.conf.",
	                linenum);
    }
    else if (!strcasecmp(line, "StateMessage"))
    {
     /*
      * Set the initial queue state message...
      */

      if (value)
	strlcpy(p->state_message, value, sizeof(p->state_message));
    }
    else if (!strcasecmp(line, "StateTime"))
    {
     /*
      * Set the state time...
      */

      if (value)
        p->state_time = atoi(value);
    }
    else if (!strcasecmp(line, "Accepting"))
    {
     /*
      * Set the initial accepting state...
      */

      if (value &&
          (!strcasecmp(value, "yes") ||
           !strcasecmp(value, "on") ||
           !strcasecmp(value, "true")))
        p->accepting = 1;
      else if (value &&
               (!strcasecmp(value, "no") ||
        	!strcasecmp(value, "off") ||
        	!strcasecmp(value, "false")))
        p->accepting = 0;
      else
	cupsdLogMessage(CUPSD_LOG_ERROR,
	                "Syntax error on line %d of classes.conf.",
	                linenum);
    }
    else if (!strcasecmp(line, "Shared"))
    {
     /*
      * Set the initial shared state...
      */

      if (value &&
          (!strcasecmp(value, "yes") ||
           !strcasecmp(value, "on") ||
           !strcasecmp(value, "true")))
        p->shared = 1;
      else if (value &&
               (!strcasecmp(value, "no") ||
        	!strcasecmp(value, "off") ||
        	!strcasecmp(value, "false")))
        p->shared = 0;
      else
	cupsdLogMessage(CUPSD_LOG_ERROR,
	                "Syntax error on line %d of classes.conf.",
	                linenum);
    }
    else if (!strcasecmp(line, "JobSheets"))
    {
     /*
      * Set the initial job sheets...
      */

      if (value)
      {
	for (valueptr = value;
	     *valueptr && !isspace(*valueptr & 255);
	     valueptr ++);

	if (*valueptr)
          *valueptr++ = '\0';

	cupsdSetString(&p->job_sheets[0], value);

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

	if (*valueptr)
	{
          for (value = valueptr;
	       *valueptr && !isspace(*valueptr & 255);
	       valueptr ++);

	  if (*valueptr)
            *valueptr = '\0';

	  cupsdSetString(&p->job_sheets[1], value);
	}
      }
      else
	cupsdLogMessage(CUPSD_LOG_ERROR,
	                "Syntax error on line %d of classes.conf.", linenum);
    }
    else if (!strcasecmp(line, "AllowUser"))
    {
      if (value)
      {
        p->deny_users = 0;
        cupsdAddPrinterUser(p, value);
      }
      else
	cupsdLogMessage(CUPSD_LOG_ERROR,
	                "Syntax error on line %d of classes.conf.", linenum);
    }
    else if (!strcasecmp(line, "DenyUser"))
    {
      if (value)
      {
        p->deny_users = 1;
        cupsdAddPrinterUser(p, value);
      }
      else
	cupsdLogMessage(CUPSD_LOG_ERROR,
	                "Syntax error on line %d of classes.conf.", linenum);
    }
    else if (!strcasecmp(line, "QuotaPeriod"))
    {
      if (value)
        p->quota_period = atoi(value);
      else
	cupsdLogMessage(CUPSD_LOG_ERROR,
	                "Syntax error on line %d of classes.conf.", linenum);
    }
    else if (!strcasecmp(line, "PageLimit"))
    {
      if (value)
        p->page_limit = atoi(value);
      else
	cupsdLogMessage(CUPSD_LOG_ERROR,
	                "Syntax error on line %d of classes.conf.", linenum);
    }
    else if (!strcasecmp(line, "KLimit"))
    {
      if (value)
        p->k_limit = atoi(value);
      else
	cupsdLogMessage(CUPSD_LOG_ERROR,
	                "Syntax error on line %d of classes.conf.", linenum);
    }
    else if (!strcasecmp(line, "OpPolicy"))
    {
      if (value)
      {
        cupsd_policy_t *pol;		/* Policy */


        if ((pol = cupsdFindPolicy(value)) != NULL)
	{
          cupsdSetString(&p->op_policy, value);
	  p->op_policy_ptr = pol;
	}
	else
	  cupsdLogMessage(CUPSD_LOG_ERROR,
	                  "Bad policy \"%s\" on line %d of classes.conf",
			  value, linenum);
      }
      else
	cupsdLogMessage(CUPSD_LOG_ERROR,
	                "Syntax error on line %d of classes.conf.", linenum);
    }
    else if (!strcasecmp(line, "ErrorPolicy"))
    {
      if (value)
      {
        if (strcmp(value, "retry-current-job") && strcmp(value, "retry-job"))
	  cupsdLogMessage(CUPSD_LOG_WARN,
	                  "ErrorPolicy %s ignored on line %d of classes.conf",
			  value, linenum);
      }
      else
	cupsdLogMessage(CUPSD_LOG_ERROR,
	                "Syntax error on line %d of classes.conf.", linenum);
    }
    else
    {
     /*
      * Something else we don't understand...
      */

      cupsdLogMessage(CUPSD_LOG_ERROR,
                      "Unknown configuration directive %s on line %d of classes.conf.",
	              line, linenum);
    }
  }

  cupsFileClose(fp);
}