+ 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);
+}
+
+
+/*
+ * 'read_cupsd_conf()' - Read the cupsd.conf configuration file.
+ */
+
+static int /* O - 1 on success, 0 on failure */
+read_cupsd_conf(cups_file_t *fp) /* I - File to read from */
+{
+ int linenum; /* Current line number */
+ char line[HTTP_MAX_BUFFER],
+ /* Line from file */
+ temp[HTTP_MAX_BUFFER],
+ /* Temporary buffer for value */
+ *value, /* Pointer to value */
+ *valueptr; /* Pointer into value */
+ int valuelen; /* Length of value */
+ http_addrlist_t *addrlist, /* Address list */
+ *addr; /* Current address */
+ cups_file_t *incfile; /* Include file */
+ char incname[1024]; /* Include filename */
+
+
+ /*
+ * Loop through each line in the file...
+ */
+
+ linenum = 0;
+
+ while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
+ {
+ /*
+ * Decode the directive...
+ */
+
+ if (!_cups_strcasecmp(line, "Include") && value)
+ {
+ /*
+ * Include filename
+ */
+
+ if (value[0] == '/')
+ strlcpy(incname, value, sizeof(incname));
+ else
+ snprintf(incname, sizeof(incname), "%s/%s", ServerRoot, value);
+
+ if ((incfile = cupsFileOpen(incname, "rb")) == NULL)
+ cupsdLogMessage(CUPSD_LOG_ERROR,
+ "Unable to include config file \"%s\" - %s",
+ incname, strerror(errno));
+ else
+ {
+ read_cupsd_conf(incfile);
+ cupsFileClose(incfile);
+ }
+ }
+ else if (!_cups_strcasecmp(line, "<Location") && value)
+ {
+ /*
+ * <Location path>