parse_variable(
    const char        *filename,	/* I - Name of configuration file */
    int               linenum,		/* I - Line in configuration file */
    const char        *line,		/* I - Line from configuration file */
    const char        *value,		/* I - Value from configuration file */
    size_t            num_vars,		/* I - Number of variables */
    const cupsd_var_t *vars)		/* I - Variables */
{
  size_t		i;		/* Looping var */
  const cupsd_var_t	*var;		/* Variables */
  char			temp[1024];	/* Temporary string */


  for (i = num_vars, var = vars; i > 0; i --, var ++)
    if (!_cups_strcasecmp(line, var->name))
      break;

  if (i == 0)
  {
   /*
    * Unknown directive!  Output an error message and continue...
    */

    if (!value)
      cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value for %s on line %d of %s.",
		      line, linenum, filename);
    else
      cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown directive %s on line %d of %s.",
		      line, linenum, filename);

    return (0);
  }

  switch (var->type)
  {
    case CUPSD_VARTYPE_INTEGER :
	if (!value)
	{
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "Missing integer value for %s on line %d of %s.",
			  line, linenum, filename);
          return (0);
	}
	else if (!isdigit(*value & 255))
	{
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "Bad integer value for %s on line %d of %s.",
			  line, linenum, filename);
          return (0);
	}
	else
	{
	  int	n;		/* Number */
	  char	*units;		/* Units */

	  n = strtol(value, &units, 0);

	  if (units && *units)
	  {
	    if (tolower(units[0] & 255) == 'g')
	      n *= 1024 * 1024 * 1024;
	    else if (tolower(units[0] & 255) == 'm')
	      n *= 1024 * 1024;
	    else if (tolower(units[0] & 255) == 'k')
	      n *= 1024;
	    else if (tolower(units[0] & 255) == 't')
	      n *= 262144;
	    else
	    {
	      cupsdLogMessage(CUPSD_LOG_ERROR,
			      "Unknown integer value for %s on line %d of %s.",
			      line, linenum, filename);
	      return (0);
	    }
	  }

	  if (n < 0)
	  {
	    cupsdLogMessage(CUPSD_LOG_ERROR,
			    "Bad negative integer value for %s on line %d of "
			    "%s.", line, linenum, filename);
	    return (0);
	  }
	  else
	  {
	    *((int *)var->ptr) = n;
	  }
	}
	break;

    case CUPSD_VARTYPE_PERM :
	if (!value)
	{
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "Missing permissions value for %s on line %d of %s.",
			  line, linenum, filename);
          return (0);
	}
	else if (!isdigit(*value & 255))
	{
	 /* TODO: Add chmod UGO syntax support */
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "Bad permissions value for %s on line %d of %s.",
			  line, linenum, filename);
          return (0);
	}
	else
	{
	  int n = strtol(value, NULL, 8);
					/* Permissions value */

	  if (n < 0)
	  {
	    cupsdLogMessage(CUPSD_LOG_ERROR,
			    "Bad negative permissions value for %s on line %d of "
			    "%s.", line, linenum, filename);
	    return (0);
	  }
	  else
	  {
	    *((mode_t *)var->ptr) = (mode_t)n;
	  }
	}
	break;

    case CUPSD_VARTYPE_TIME :
	if (!value)
	{
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "Missing time interval value for %s on line %d of "
			  "%s.", line, linenum, filename);
	  return (0);
	}
	else if (!_cups_strncasecmp(line, "PreserveJob", 11) &&
		 (!_cups_strcasecmp(value, "true") ||
		  !_cups_strcasecmp(value, "on") ||
		  !_cups_strcasecmp(value, "enabled") ||
		  !_cups_strcasecmp(value, "yes")))
	{
	  *((int *)var->ptr) = INT_MAX;
	}
	else if (!_cups_strcasecmp(value, "false") ||
		 !_cups_strcasecmp(value, "off") ||
		 !_cups_strcasecmp(value, "disabled") ||
		 !_cups_strcasecmp(value, "no"))
	{
	  *((int *)var->ptr) = 0;
	}
	else if (!isdigit(*value & 255))
	{
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "Unknown time interval value for %s on line %d of "
			  "%s.", line, linenum, filename);
          return (0);
	}
	else
	{
	  double	n;		/* Number */
	  char		*units;		/* Units */

	  n = strtod(value, &units);

	  if (units && *units)
	  {
	    if (tolower(units[0] & 255) == 'w')
	      n *= 7 * 24 * 60 * 60;
	    else if (tolower(units[0] & 255) == 'd')
	      n *= 24 * 60 * 60;
	    else if (tolower(units[0] & 255) == 'h')
	      n *= 60 * 60;
	    else if (tolower(units[0] & 255) == 'm')
	      n *= 60;
	    else
	    {
	      cupsdLogMessage(CUPSD_LOG_ERROR,
			      "Unknown time interval value for %s on line "
			      "%d of %s.", line, linenum, filename);
	      return (0);
	    }
	  }

	  if (n < 0.0 || n > INT_MAX)
	  {
	    cupsdLogMessage(CUPSD_LOG_ERROR,
			    "Bad time value for %s on line %d of %s.",
			    line, linenum, filename);
	    return (0);
	  }
	  else
	  {
	    *((int *)var->ptr) = (int)n;
	  }
	}
	break;

    case CUPSD_VARTYPE_BOOLEAN :
	if (!value)
	{
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "Missing boolean value for %s on line %d of %s.",
			  line, linenum, filename);
	  return (0);
	}
	else if (!_cups_strcasecmp(value, "true") ||
		 !_cups_strcasecmp(value, "on") ||
		 !_cups_strcasecmp(value, "enabled") ||
		 !_cups_strcasecmp(value, "yes") ||
		 atoi(value) != 0)
	{
	  *((int *)var->ptr) = TRUE;
	}
	else if (!_cups_strcasecmp(value, "false") ||
		 !_cups_strcasecmp(value, "off") ||
		 !_cups_strcasecmp(value, "disabled") ||
		 !_cups_strcasecmp(value, "no") ||
		 !_cups_strcasecmp(value, "0"))
	{
	  *((int *)var->ptr) = FALSE;
	}
	else
	{
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "Unknown boolean value %s on line %d of %s.",
			  value, linenum, filename);
	  return (0);
	}
	break;

    case CUPSD_VARTYPE_PATHNAME :
	if (!value)
	{
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "Missing pathname value for %s on line %d of %s.",
			  line, linenum, filename);
	  return (0);
	}

	if (value[0] == '/')
	  strlcpy(temp, value, sizeof(temp));
	else
	  snprintf(temp, sizeof(temp), "%s/%s", ServerRoot, value);

	if (access(temp, 0) && _cups_strcasecmp(value, "internal") && _cups_strcasecmp(line, "ServerKeychain"))
	{
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "File or directory for \"%s %s\" on line %d of %s "
			  "does not exist.", line, value, linenum, filename);
	  return (0);
	}

	cupsdSetString((char **)var->ptr, temp);
	break;

    case CUPSD_VARTYPE_STRING :
	cupsdSetString((char **)var->ptr, value);
	break;
  }

  return (1);
}
parse_variable(
    const char        *filename,	 
    int               linenum,		 
    const char        *line,		 
    const char        *value,		 
    size_t            num_vars,		 
    const cupsd_var_t *vars)		 
{
  size_t		i;		 
  const cupsd_var_t	*var;		 
  char			temp[1024];	 


  for (i = num_vars, var = vars; i > 0; i --, var ++)
    if (!_cups_strcasecmp(line, var->name))
      break;

  if (i == 0)
  {
    

    if (!value)
      cupsdLogMessage(CUPSD_LOG_ERROR, "Missing value for %s on line %d of %s.",
		      line, linenum, filename);
    else
      cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown directive %s on line %d of %s.",
		      line, linenum, filename);

    return (0);
  }

  switch (var->type)
  {
    case CUPSD_VARTYPE_INTEGER :
	if (!value)
	{
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "Missing integer value for %s on line %d of %s.",
			  line, linenum, filename);
          return (0);
	}
	else if (!isdigit(*value & 255))
	{
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "Bad integer value for %s on line %d of %s.",
			  line, linenum, filename);
          return (0);
	}
	else
	{
	  int	n;		 
	  char	*units;		 

	  n = strtol(value, &units, 0);

	  if (units && *units)
	  {
	    if (tolower(units[0] & 255) == 'g')
	      n *= 1024 * 1024 * 1024;
	    else if (tolower(units[0] & 255) == 'm')
	      n *= 1024 * 1024;
	    else if (tolower(units[0] & 255) == 'k')
	      n *= 1024;
	    else if (tolower(units[0] & 255) == 't')
	      n *= 262144;
	    else
	    {
	      cupsdLogMessage(CUPSD_LOG_ERROR,
			      "Unknown integer value for %s on line %d of %s.",
			      line, linenum, filename);
	      return (0);
	    }
	  }

	  if (n < 0)
	  {
	    cupsdLogMessage(CUPSD_LOG_ERROR,
			    "Bad negative integer value for %s on line %d of "
			    "%s.", line, linenum, filename);
	    return (0);
	  }
	  else
	  {
	    *((int *)var->ptr) = n;
	  }
	}
	break;

    case CUPSD_VARTYPE_PERM :
	if (!value)
	{
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "Missing permissions value for %s on line %d of %s.",
			  line, linenum, filename);
          return (0);
	}
	else if (!isdigit(*value & 255))
	{
	  
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "Bad permissions value for %s on line %d of %s.",
			  line, linenum, filename);
          return (0);
	}
	else
	{
	  int n = strtol(value, NULL, 8);
					 

	  if (n < 0)
	  {
	    cupsdLogMessage(CUPSD_LOG_ERROR,
			    "Bad negative permissions value for %s on line %d of "
			    "%s.", line, linenum, filename);
	    return (0);
	  }
	  else
	  {
	    *((mode_t *)var->ptr) = (mode_t)n;
	  }
	}
	break;

    case CUPSD_VARTYPE_TIME :
	if (!value)
	{
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "Missing time interval value for %s on line %d of "
			  "%s.", line, linenum, filename);
	  return (0);
	}
	else if (!_cups_strncasecmp(line, "PreserveJob", 11) &&
		 (!_cups_strcasecmp(value, "true") ||
		  !_cups_strcasecmp(value, "on") ||
		  !_cups_strcasecmp(value, "enabled") ||
		  !_cups_strcasecmp(value, "yes")))
	{
	  *((int *)var->ptr) = INT_MAX;
	}
	else if (!_cups_strcasecmp(value, "false") ||
		 !_cups_strcasecmp(value, "off") ||
		 !_cups_strcasecmp(value, "disabled") ||
		 !_cups_strcasecmp(value, "no"))
	{
	  *((int *)var->ptr) = 0;
	}
	else if (!isdigit(*value & 255))
	{
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "Unknown time interval value for %s on line %d of "
			  "%s.", line, linenum, filename);
          return (0);
	}
	else
	{
	  double	n;		 
	  char		*units;		 

	  n = strtod(value, &units);

	  if (units && *units)
	  {
	    if (tolower(units[0] & 255) == 'w')
	      n *= 7 * 24 * 60 * 60;
	    else if (tolower(units[0] & 255) == 'd')
	      n *= 24 * 60 * 60;
	    else if (tolower(units[0] & 255) == 'h')
	      n *= 60 * 60;
	    else if (tolower(units[0] & 255) == 'm')
	      n *= 60;
	    else
	    {
	      cupsdLogMessage(CUPSD_LOG_ERROR,
			      "Unknown time interval value for %s on line "
			      "%d of %s.", line, linenum, filename);
	      return (0);
	    }
	  }

	  if (n < 0.0 || n > INT_MAX)
	  {
	    cupsdLogMessage(CUPSD_LOG_ERROR,
			    "Bad time value for %s on line %d of %s.",
			    line, linenum, filename);
	    return (0);
	  }
	  else
	  {
	    *((int *)var->ptr) = (int)n;
	  }
	}
	break;

    case CUPSD_VARTYPE_BOOLEAN :
	if (!value)
	{
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "Missing boolean value for %s on line %d of %s.",
			  line, linenum, filename);
	  return (0);
	}
	else if (!_cups_strcasecmp(value, "true") ||
		 !_cups_strcasecmp(value, "on") ||
		 !_cups_strcasecmp(value, "enabled") ||
		 !_cups_strcasecmp(value, "yes") ||
		 atoi(value) != 0)
	{
	  *((int *)var->ptr) = TRUE;
	}
	else if (!_cups_strcasecmp(value, "false") ||
		 !_cups_strcasecmp(value, "off") ||
		 !_cups_strcasecmp(value, "disabled") ||
		 !_cups_strcasecmp(value, "no") ||
		 !_cups_strcasecmp(value, "0"))
	{
	  *((int *)var->ptr) = FALSE;
	}
	else
	{
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "Unknown boolean value %s on line %d of %s.",
			  value, linenum, filename);
	  return (0);
	}
	break;

    case CUPSD_VARTYPE_PATHNAME :
	if (!value)
	{
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "Missing pathname value for %s on line %d of %s.",
			  line, linenum, filename);
	  return (0);
	}

	if (value[0] == '/')
	  strlcpy(temp, value, sizeof(temp));
	else
	  snprintf(temp, sizeof(temp), "%s/%s", ServerRoot, value);

	if (access(temp, 0) && _cups_strcasecmp(value, "internal") && _cups_strcasecmp(line, "ServerKeychain"))
	{
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "File or directory for \"%s %s\" on line %d of %s "
			  "does not exist.", line, value, linenum, filename);
	  return (0);
	}

	cupsdSetString((char **)var->ptr, temp);
	break;

    case CUPSD_VARTYPE_STRING :
	cupsdSetString((char **)var->ptr, value);
	break;
  }

  return (1);
}