Blame src/LYReadCFG.c

Packit f574b8
/*
Packit f574b8
 * $LynxId: LYReadCFG.c,v 1.193 2018/05/11 00:03:10 tom Exp $
Packit f574b8
 */
Packit f574b8
#ifndef NO_RULES
Packit f574b8
#include <HTRules.h>
Packit f574b8
#else
Packit f574b8
#include <HTUtils.h>
Packit f574b8
#endif
Packit f574b8
#include <HTTP.h>		/* 'reloading' flag */
Packit f574b8
#include <HTFile.h>
Packit f574b8
#include <HTInit.h>
Packit f574b8
#include <UCMap.h>
Packit f574b8
Packit f574b8
#include <LYUtils.h>
Packit f574b8
#include <GridText.h>
Packit f574b8
#include <LYStrings.h>
Packit f574b8
#include <LYStructs.h>
Packit f574b8
#include <LYGlobalDefs.h>
Packit f574b8
#include <LYCharSets.h>
Packit f574b8
#include <LYCharUtils.h>
Packit f574b8
#include <LYKeymap.h>
Packit f574b8
#include <LYJump.h>
Packit f574b8
#include <LYGetFile.h>
Packit f574b8
#include <LYCgi.h>
Packit f574b8
#include <LYCurses.h>
Packit f574b8
#include <LYBookmark.h>
Packit f574b8
#include <LYCookie.h>
Packit f574b8
#include <LYReadCFG.h>
Packit f574b8
#include <HTAlert.h>
Packit f574b8
#include <LYHistory.h>
Packit f574b8
#include <LYPrettySrc.h>
Packit f574b8
#include <LYrcFile.h>
Packit f574b8
Packit f574b8
#ifdef DIRED_SUPPORT
Packit f574b8
#include <LYLocal.h>
Packit f574b8
#endif /* DIRED_SUPPORT */
Packit f574b8
Packit f574b8
#include <LYexit.h>
Packit f574b8
#include <LYLeaks.h>
Packit f574b8
Packit f574b8
#ifndef DISABLE_NEWS
Packit f574b8
#include <HTNews.h>
Packit f574b8
#endif
Packit f574b8
Packit f574b8
BOOLEAN have_read_cfg = FALSE;
Packit f574b8
BOOLEAN LYUseNoviceLineTwo = TRUE;
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Translate a TRUE/FALSE field in a string buffer.
Packit f574b8
 */
Packit f574b8
static BOOL is_true(const char *string)
Packit f574b8
{
Packit f574b8
    if (!strcasecomp(string, "TRUE") || !strcasecomp(string, "ON"))
Packit f574b8
	return (TRUE);
Packit f574b8
    else
Packit f574b8
	return (FALSE);
Packit f574b8
}
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Find an unescaped colon in a string buffer.
Packit f574b8
 */
Packit f574b8
static const char *find_colon(const char *buffer)
Packit f574b8
{
Packit f574b8
    char ch;
Packit f574b8
    const char *buf = buffer;
Packit f574b8
Packit f574b8
    if (buf == NULL)
Packit f574b8
	return NULL;
Packit f574b8
Packit f574b8
    while ((ch = *buf) != 0) {
Packit f574b8
	if (ch == ':')
Packit f574b8
	    return buf;
Packit f574b8
	if (ch == '\\') {
Packit f574b8
	    buf++;
Packit f574b8
	    if (*buf == 0)
Packit f574b8
		break;
Packit f574b8
	}
Packit f574b8
	buf++;
Packit f574b8
    }
Packit f574b8
    return NULL;
Packit f574b8
}
Packit f574b8
Packit f574b8
static void free_item_list_item(lynx_list_item_type **list,
Packit f574b8
				lynx_list_item_type *ptr)
Packit f574b8
{
Packit f574b8
    lynx_list_item_type *prev;
Packit f574b8
    lynx_list_item_type *cur;
Packit f574b8
Packit f574b8
    for (cur = *list, prev = 0; cur != 0; prev = cur, cur = cur->next) {
Packit f574b8
	if (cur == ptr) {
Packit f574b8
Packit f574b8
	    if (prev != 0)
Packit f574b8
		prev->next = cur->next;
Packit f574b8
	    else
Packit f574b8
		*list = cur->next;
Packit f574b8
Packit f574b8
	    FREE(cur->name);
Packit f574b8
	    FREE(cur->menu_name);
Packit f574b8
	    FREE(cur->command);
Packit f574b8
	    FREE(cur);
Packit f574b8
	    break;
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
}
Packit f574b8
Packit f574b8
static void free_item_list(lynx_list_item_type **ptr)
Packit f574b8
{
Packit f574b8
    while (*ptr != 0) {
Packit f574b8
	free_item_list_item(ptr, *ptr);
Packit f574b8
    }
Packit f574b8
}
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Function for freeing the DOWNLOADER and UPLOADER menus list.  - FM
Packit f574b8
 */
Packit f574b8
static void free_all_item_lists(void)
Packit f574b8
{
Packit f574b8
    free_item_list(&printers);
Packit f574b8
    free_item_list(&downloaders);
Packit f574b8
#ifdef DIRED_SUPPORT
Packit f574b8
    free_item_list(&uploaders);
Packit f574b8
#endif /* DIRED_SUPPORT */
Packit f574b8
Packit f574b8
#ifdef USE_EXTERNALS
Packit f574b8
    free_item_list(&externals);
Packit f574b8
#endif /* USE_EXTERNALS */
Packit f574b8
Packit f574b8
    return;
Packit f574b8
}
Packit f574b8
Packit f574b8
static const char *parse_list_bool(BOOL *target, const char *source)
Packit f574b8
{
Packit f574b8
    const char *result;
Packit f574b8
Packit f574b8
    source = LYSkipCBlanks(source);
Packit f574b8
    result = find_colon(source);
Packit f574b8
Packit f574b8
    if (*source != '\0') {
Packit f574b8
	char temp[20];
Packit f574b8
	size_t len = ((result != 0)
Packit f574b8
		      ? (size_t) (result - source)
Packit f574b8
		      : strlen(source));
Packit f574b8
Packit f574b8
	if (len > sizeof(temp))
Packit f574b8
	    len = (sizeof(temp) - 1);
Packit f574b8
	LYStrNCpy(temp, source, len);
Packit f574b8
	*target = is_true(temp);
Packit f574b8
	CTRACE2(TRACE_CFG, (tfp, "parse_list_bool(%s) '%d'\n", source, *target));
Packit f574b8
    }
Packit f574b8
    return result;
Packit f574b8
}
Packit f574b8
Packit f574b8
static const char *parse_list_int(int *target, const char *source)
Packit f574b8
{
Packit f574b8
    const char *result;
Packit f574b8
Packit f574b8
    source = LYSkipCBlanks(source);
Packit f574b8
    result = find_colon(source);
Packit f574b8
Packit f574b8
    if (*source != '\0') {
Packit f574b8
	*target = atoi(source);
Packit f574b8
	CTRACE2(TRACE_CFG, (tfp, "parse_list_int(%s) '%d'\n", source, *target));
Packit f574b8
    }
Packit f574b8
    return result;
Packit f574b8
}
Packit f574b8
Packit f574b8
static const char *parse_list_string(char **target, const char *source)
Packit f574b8
{
Packit f574b8
    const char *result;
Packit f574b8
Packit f574b8
    source = LYSkipCBlanks(source);
Packit f574b8
    result = find_colon(source);
Packit f574b8
Packit f574b8
    if (*source != '\0') {
Packit f574b8
	const char *next = ((result == 0)
Packit f574b8
			    ? (source + strlen(source))
Packit f574b8
			    : result);
Packit f574b8
Packit f574b8
	*target = typecallocn(char, (size_t) (next - source + 1));
Packit f574b8
Packit f574b8
	if (*target == NULL)
Packit f574b8
	    outofmem(__FILE__, "read_cfg");
Packit f574b8
	LYStrNCpy(*target, source, (next - source));
Packit f574b8
	remove_backslashes(*target);
Packit f574b8
Packit f574b8
	CTRACE2(TRACE_CFG, (tfp, "parse_list_string(%s) '%s'\n", source, *target));
Packit f574b8
    }
Packit f574b8
    return result;
Packit f574b8
}
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Process string buffer fields for DOWNLOADER or UPLOADER
Packit f574b8
 *                               or PRINTERS   or EXTERNALS menus
Packit f574b8
 */
Packit f574b8
static void add_item_to_list(char *buffer,
Packit f574b8
			     lynx_list_item_type **list_ptr,
Packit f574b8
			     int special,
Packit f574b8
			     int menu_name)
Packit f574b8
{
Packit f574b8
    const char *colon, *last_colon;
Packit f574b8
    lynx_list_item_type *cur_item, *prev_item;
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Check if the XWINDOWS or NON_XWINDOWS keyword is present in the last
Packit f574b8
     * field, and act properly when found depending if external environment
Packit f574b8
     * $DISPLAY variable is set.
Packit f574b8
     */
Packit f574b8
    if ((colon = find_colon(buffer)) == 0) {
Packit f574b8
	return;
Packit f574b8
    }
Packit f574b8
    for (last_colon = colon;
Packit f574b8
	 (colon = find_colon(last_colon + 1)) != 0;
Packit f574b8
	 last_colon = colon) {
Packit f574b8
	;
Packit f574b8
    }
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * If colon equals XWINDOWS then only continue
Packit f574b8
     * if there is a $DISPLAY variable
Packit f574b8
     */
Packit f574b8
    if (!strcasecomp(last_colon + 1, "XWINDOWS")) {
Packit f574b8
	if (LYgetXDisplay() == NULL)
Packit f574b8
	    return;
Packit f574b8
    }
Packit f574b8
    /*
Packit f574b8
     * If colon equals NON_XWINDOWS then only continue
Packit f574b8
     * if there is no $DISPLAY variable
Packit f574b8
     */
Packit f574b8
    else if (!strcasecomp(last_colon + 1, "NON_XWINDOWS")) {
Packit f574b8
	if (LYgetXDisplay() != NULL)
Packit f574b8
	    return;
Packit f574b8
    }
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Make a linked list
Packit f574b8
     */
Packit f574b8
    if (*list_ptr == NULL) {
Packit f574b8
	/*
Packit f574b8
	 * First item.
Packit f574b8
	 */
Packit f574b8
	cur_item = typecalloc(lynx_list_item_type);
Packit f574b8
Packit f574b8
	if (cur_item == NULL)
Packit f574b8
	    outofmem(__FILE__, "read_cfg");
Packit f574b8
Packit f574b8
	*list_ptr = cur_item;
Packit f574b8
#ifdef LY_FIND_LEAKS
Packit f574b8
	atexit(free_all_item_lists);
Packit f574b8
#endif
Packit f574b8
    } else {
Packit f574b8
	/*
Packit f574b8
	 * Find the last item.
Packit f574b8
	 */
Packit f574b8
	for (prev_item = *list_ptr;
Packit f574b8
	     prev_item->next != NULL;
Packit f574b8
	     prev_item = prev_item->next) ;	/* null body */
Packit f574b8
	cur_item = typecalloc(lynx_list_item_type);
Packit f574b8
Packit f574b8
	if (cur_item == NULL)
Packit f574b8
	    outofmem(__FILE__, "read_cfg");
Packit f574b8
	else
Packit f574b8
	    prev_item->next = cur_item;
Packit f574b8
    }
Packit f574b8
    /* fill-in nonzero default values */
Packit f574b8
    cur_item->pagelen = 66;
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Find first unescaped colon and process fields
Packit f574b8
     */
Packit f574b8
    if (find_colon(buffer) != NULL) {
Packit f574b8
	colon = parse_list_string(&(cur_item->name), buffer);
Packit f574b8
Packit f574b8
	if (colon && menu_name) {
Packit f574b8
	    colon = parse_list_string(&(cur_item->menu_name), colon + 1);
Packit f574b8
	}
Packit f574b8
	if (colon) {
Packit f574b8
	    colon = parse_list_string(&(cur_item->command), colon + 1);
Packit f574b8
	}
Packit f574b8
	if (colon) {
Packit f574b8
	    colon = parse_list_bool(&(cur_item->always_enabled), colon + 1);
Packit f574b8
	}
Packit f574b8
	if (colon) {
Packit f574b8
	    if (special) {
Packit f574b8
		(void) parse_list_int(&(cur_item->pagelen), colon + 1);
Packit f574b8
	    } else {
Packit f574b8
		(void) parse_list_bool(&(cur_item->override_action), colon + 1);
Packit f574b8
	    }
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
Packit f574b8
    /* ignore empty data */
Packit f574b8
    if (cur_item->name == NULL
Packit f574b8
	|| cur_item->command == NULL) {
Packit f574b8
	CTRACE2(TRACE_CFG, (tfp, "ignoring incomplete list_item '%s'\n", buffer));
Packit f574b8
	free_item_list_item(list_ptr, cur_item);
Packit f574b8
    } else if (cur_item->menu_name == NULL) {
Packit f574b8
	StrAllocCopy(cur_item->menu_name, cur_item->command);
Packit f574b8
    }
Packit f574b8
}
Packit f574b8
Packit f574b8
lynx_list_item_type *find_item_by_number(lynx_list_item_type *list_ptr,
Packit f574b8
					 char *number)
Packit f574b8
{
Packit f574b8
    int value = atoi(number);
Packit f574b8
Packit f574b8
    while (value-- >= 0 && list_ptr != 0) {
Packit f574b8
	list_ptr = list_ptr->next;
Packit f574b8
    }
Packit f574b8
    return list_ptr;
Packit f574b8
}
Packit f574b8
Packit f574b8
int match_item_by_name(lynx_list_item_type *ptr,
Packit f574b8
		       const char *name,
Packit f574b8
		       int only_overriders)
Packit f574b8
{
Packit f574b8
    return
Packit f574b8
	(ptr->command != 0
Packit f574b8
	 && !strncasecomp(ptr->name, name, (int) strlen(ptr->name))
Packit f574b8
	 && (only_overriders ? ptr->override_action : 1));
Packit f574b8
}
Packit f574b8
Packit f574b8
#if defined(USE_COLOR_STYLE) || defined(USE_COLOR_TABLE)
Packit f574b8
Packit f574b8
#ifndef COLOR_WHITE
Packit f574b8
#define COLOR_WHITE 7
Packit f574b8
#endif
Packit f574b8
Packit f574b8
#ifndef COLOR_BLACK
Packit f574b8
#define COLOR_BLACK 0
Packit f574b8
#endif
Packit f574b8
Packit f574b8
#ifdef USE_DEFAULT_COLORS
Packit f574b8
int default_fg = DEFAULT_COLOR;
Packit f574b8
int default_bg = DEFAULT_COLOR;
Packit f574b8
Packit f574b8
#else
Packit f574b8
int default_fg = COLOR_WHITE;
Packit f574b8
int default_bg = COLOR_BLACK;
Packit f574b8
#endif
Packit f574b8
Packit f574b8
static const char *Color_Strings[16] =
Packit f574b8
{
Packit f574b8
    "black",
Packit f574b8
    "red",
Packit f574b8
    "green",
Packit f574b8
    "brown",
Packit f574b8
    "blue",
Packit f574b8
    "magenta",
Packit f574b8
    "cyan",
Packit f574b8
    "lightgray",
Packit f574b8
    "gray",
Packit f574b8
    "brightred",
Packit f574b8
    "brightgreen",
Packit f574b8
    "yellow",
Packit f574b8
    "brightblue",
Packit f574b8
    "brightmagenta",
Packit f574b8
    "brightcyan",
Packit f574b8
    "white"
Packit f574b8
};
Packit f574b8
Packit f574b8
#if defined(PDCURSES) && !defined(XCURSES)
Packit f574b8
/*
Packit f574b8
 * PDCurses (and possibly some other implementations) use a non-ANSI set of
Packit f574b8
 * codes for colors.
Packit f574b8
 */
Packit f574b8
static int ColorCode(int color)
Packit f574b8
{
Packit f574b8
    /* *INDENT-OFF* */
Packit f574b8
    static int map[] =
Packit f574b8
    {
Packit f574b8
	0,  4,  2,  6,  1,  5,  3,  7,
Packit f574b8
	8, 12, 10, 14,  9, 13, 11, 15
Packit f574b8
    };
Packit f574b8
    /* *INDENT-ON* */
Packit f574b8
Packit f574b8
    return map[color];
Packit f574b8
}
Packit f574b8
#else
Packit f574b8
#define ColorCode(color) (color)
Packit f574b8
#endif
Packit f574b8
Packit f574b8
BOOL default_color_reset = FALSE;
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Validator for COLOR fields.
Packit f574b8
 */
Packit f574b8
int check_color(const char *color,
Packit f574b8
		int the_default)
Packit f574b8
{
Packit f574b8
    int i;
Packit f574b8
Packit f574b8
    CTRACE2(TRACE_STYLE, (tfp, "check_color(%s,%d)\n", color, the_default));
Packit f574b8
    if (!strcasecomp(color, "default")) {
Packit f574b8
#ifdef USE_DEFAULT_COLORS
Packit f574b8
	if (LYuse_default_colors && !default_color_reset)
Packit f574b8
	    the_default = DEFAULT_COLOR;
Packit f574b8
#endif /* USE_DEFAULT_COLORS */
Packit f574b8
	CTRACE2(TRACE_STYLE, (tfp, "=> default %d\n", the_default));
Packit f574b8
	return the_default;
Packit f574b8
    }
Packit f574b8
    if (!strcasecomp(color, "nocolor"))
Packit f574b8
	return NO_COLOR;
Packit f574b8
Packit f574b8
    for (i = 0; i < 16; i++) {
Packit f574b8
	if (!strcasecomp(color, Color_Strings[i])) {
Packit f574b8
	    int c = ColorCode(i);
Packit f574b8
Packit f574b8
	    CTRACE2(TRACE_STYLE, (tfp, "=> %d\n", c));
Packit f574b8
	    return c;
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
    CTRACE2(TRACE_STYLE, (tfp, "=> ERR_COLOR\n"));
Packit f574b8
    return ERR_COLOR;
Packit f574b8
}
Packit f574b8
Packit f574b8
const char *lookup_color(int code)
Packit f574b8
{
Packit f574b8
    unsigned n;
Packit f574b8
Packit f574b8
    for (n = 0; n < 16; n++) {
Packit f574b8
	if ((int) ColorCode(n) == code)
Packit f574b8
	    return Color_Strings[n];
Packit f574b8
    }
Packit f574b8
    return "default";
Packit f574b8
}
Packit f574b8
#endif /* USE_COLOR_STYLE || USE_COLOR_TABLE */
Packit f574b8
Packit f574b8
#if defined(USE_COLOR_TABLE) || defined(EXP_ASSUMED_COLOR)
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Exit routine for failed COLOR parsing.
Packit f574b8
 */
Packit f574b8
static void exit_with_color_syntax(char *error_line)
Packit f574b8
{
Packit f574b8
    unsigned int i;
Packit f574b8
Packit f574b8
    fprintf(stderr, gettext("\
Packit f574b8
Syntax Error parsing COLOR in configuration file:\n\
Packit f574b8
The line must be of the form:\n\
Packit f574b8
COLOR:INTEGER:FOREGROUND:BACKGROUND\n\
Packit f574b8
\n\
Packit f574b8
Here FOREGROUND and BACKGROUND must be one of:\n\
Packit f574b8
The special strings 'nocolor' or 'default', or\n")
Packit f574b8
	);
Packit f574b8
    for (i = 0; i < 16; i += 4) {
Packit f574b8
	fprintf(stderr, "%16s %16s %16s %16s\n",
Packit f574b8
		Color_Strings[i], Color_Strings[i + 1],
Packit f574b8
		Color_Strings[i + 2], Color_Strings[i + 3]);
Packit f574b8
    }
Packit f574b8
    fprintf(stderr, "%s\nCOLOR:%s\n", gettext("Offending line:"), error_line);
Packit f574b8
    exit_immediately(EXIT_FAILURE);
Packit f574b8
}
Packit f574b8
#endif /* defined(USE_COLOR_TABLE) || defined(EXP_ASSUMED_COLOR) */
Packit f574b8
Packit f574b8
#if defined(USE_COLOR_TABLE)
Packit f574b8
/*
Packit f574b8
 * Process string buffer fields for COLOR setting.
Packit f574b8
 */
Packit f574b8
static void parse_color(char *buffer)
Packit f574b8
{
Packit f574b8
    int color;
Packit f574b8
    const char *fg, *bg;
Packit f574b8
    char *temp_fg = 0;
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * We are expecting a line of the form:
Packit f574b8
     *    INTEGER:FOREGROUND:BACKGROUND
Packit f574b8
     */
Packit f574b8
    color = atoi(buffer);
Packit f574b8
    if (NULL == (fg = find_colon(buffer)))
Packit f574b8
	exit_with_color_syntax(buffer);
Packit f574b8
Packit f574b8
    if (NULL == (bg = find_colon(++fg)))
Packit f574b8
	exit_with_color_syntax(buffer);
Packit f574b8
Packit f574b8
    StrAllocCopy(temp_fg, fg);
Packit f574b8
    temp_fg[bg++ - fg] = '\0';
Packit f574b8
Packit f574b8
#if defined(USE_SLANG)
Packit f574b8
    if ((check_color(temp_fg, default_fg) == ERR_COLOR) ||
Packit f574b8
	(check_color(bg, default_bg) == ERR_COLOR))
Packit f574b8
	exit_with_color_syntax(buffer);
Packit f574b8
Packit f574b8
    SLtt_set_color(color, NULL, temp_fg, bg);
Packit f574b8
#else
Packit f574b8
    if (lynx_chg_color(color,
Packit f574b8
		       check_color(temp_fg, default_fg),
Packit f574b8
		       check_color(bg, default_bg)) < 0)
Packit f574b8
	exit_with_color_syntax(buffer);
Packit f574b8
#endif
Packit f574b8
    FREE(temp_fg);
Packit f574b8
}
Packit f574b8
#endif /* USE_COLOR_TABLE */
Packit f574b8
/* *INDENT-OFF* */
Packit f574b8
#ifdef USE_SOURCE_CACHE
Packit f574b8
static Config_Enum tbl_source_cache[] = {
Packit f574b8
    { "FILE",	SOURCE_CACHE_FILE },
Packit f574b8
    { "MEMORY",	SOURCE_CACHE_MEMORY },
Packit f574b8
    { "NONE",	SOURCE_CACHE_NONE },
Packit f574b8
    { NULL,		-1 },
Packit f574b8
};
Packit f574b8
Packit f574b8
static Config_Enum tbl_abort_source_cache[] = {
Packit f574b8
    { "KEEP",	SOURCE_CACHE_FOR_ABORTED_KEEP },
Packit f574b8
    { "DROP",	SOURCE_CACHE_FOR_ABORTED_DROP },
Packit f574b8
    { NULL,		-1 },
Packit f574b8
};
Packit f574b8
#endif
Packit f574b8
/* *INDENT-ON* */
Packit f574b8
Packit f574b8
#define PARSE_ADD(n,v)   {n, CONF_ADD_ITEM,    UNION_ADD(v), 0}
Packit f574b8
#define PARSE_SET(n,v)   {n, CONF_BOOL,        UNION_SET(v), 0}
Packit f574b8
#define PARSE_ENU(n,v,t) {n, CONF_ENUM,        UNION_INT(v), t}
Packit f574b8
#define PARSE_INT(n,v)   {n, CONF_INT,         UNION_INT(v), 0}
Packit f574b8
#define PARSE_TIM(n,v)   {n, CONF_TIME,        UNION_INT(v), 0}
Packit f574b8
#define PARSE_STR(n,v)   {n, CONF_STR,         UNION_STR(v), 0}
Packit f574b8
#define PARSE_PRG(n,v)   {n, CONF_PRG,         UNION_DEF(v), 0}
Packit f574b8
#define PARSE_Env(n,v)   {n, CONF_ENV,         UNION_ENV(v), 0}
Packit f574b8
#define PARSE_ENV(n,v)   {n, CONF_ENV2,        UNION_ENV(v), 0}
Packit f574b8
#define PARSE_FUN(n,v)   {n, CONF_FUN,         UNION_FUN(v), 0}
Packit f574b8
#define PARSE_REQ(n,v)   {n, CONF_INCLUDE,     UNION_FUN(v), 0}
Packit f574b8
#define PARSE_LST(n,v)   {n, CONF_ADD_STRING,  UNION_LST(v), 0}
Packit f574b8
#define PARSE_DEF(n,v)   {n, CONF_ADD_TRUSTED, UNION_DEF(v), 0}
Packit f574b8
#define PARSE_NIL        {NULL, CONF_NIL,      UNION_DEF(0), 0}
Packit f574b8
Packit f574b8
typedef enum {
Packit f574b8
    CONF_NIL = 0
Packit f574b8
    ,CONF_BOOL			/* BOOLEAN type */
Packit f574b8
    ,CONF_FUN
Packit f574b8
    ,CONF_TIME
Packit f574b8
    ,CONF_ENUM
Packit f574b8
    ,CONF_INT
Packit f574b8
    ,CONF_STR
Packit f574b8
    ,CONF_PRG
Packit f574b8
    ,CONF_ENV			/* from environment variable */
Packit f574b8
    ,CONF_ENV2			/* from environment VARIABLE */
Packit f574b8
    ,CONF_INCLUDE		/* include file-- handle special */
Packit f574b8
    ,CONF_ADD_ITEM
Packit f574b8
    ,CONF_ADD_STRING
Packit f574b8
    ,CONF_ADD_TRUSTED
Packit f574b8
} Conf_Types;
Packit f574b8
Packit f574b8
typedef struct {
Packit f574b8
    const char *name;
Packit f574b8
    Conf_Types type;
Packit f574b8
      ParseData;
Packit f574b8
    Config_Enum *table;
Packit f574b8
} Config_Type;
Packit f574b8
Packit f574b8
static int assume_charset_fun(char *value)
Packit f574b8
{
Packit f574b8
    assumed_charset = TRUE;
Packit f574b8
    UCLYhndl_for_unspec = safeUCGetLYhndl_byMIME(value);
Packit f574b8
    StrAllocCopy(UCAssume_MIMEcharset,
Packit f574b8
		 LYCharSet_UC[UCLYhndl_for_unspec].MIMEname);
Packit f574b8
    CTRACE((tfp, "assume_charset_fun %s ->%d ->%s\n",
Packit f574b8
	    NonNull(value),
Packit f574b8
	    UCLYhndl_for_unspec,
Packit f574b8
	    UCAssume_MIMEcharset));
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
static int assume_local_charset_fun(char *value)
Packit f574b8
{
Packit f574b8
    UCLYhndl_HTFile_for_unspec = safeUCGetLYhndl_byMIME(value);
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
static int assume_unrec_charset_fun(char *value)
Packit f574b8
{
Packit f574b8
    UCLYhndl_for_unrec = safeUCGetLYhndl_byMIME(value);
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
static int character_set_fun(char *value)
Packit f574b8
{
Packit f574b8
    int i = UCGetLYhndl_byAnyName(value);	/* by MIME or full name */
Packit f574b8
Packit f574b8
    if (i < 0) {
Packit f574b8
#ifdef CAN_AUTODETECT_DISPLAY_CHARSET
Packit f574b8
	if (auto_display_charset >= 0
Packit f574b8
	    && (!strncasecomp(value, "AutoDetect ", 11)
Packit f574b8
		|| !strncasecomp(value, "AutoDetect-2 ", 13)))
Packit f574b8
	    current_char_set = auto_display_charset;
Packit f574b8
#endif
Packit f574b8
	/* do nothing here: so fallback to userdefs.h */
Packit f574b8
    } else {
Packit f574b8
	current_char_set = i;
Packit f574b8
    }
Packit f574b8
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
static int outgoing_mail_charset_fun(char *value)
Packit f574b8
{
Packit f574b8
    outgoing_mail_charset = UCGetLYhndl_byMIME(value);
Packit f574b8
    /* -1 if NULL or not recognized value: no translation (compatibility) */
Packit f574b8
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
#ifdef EXP_ASSUMED_COLOR
Packit f574b8
/*
Packit f574b8
 * Process string buffer fields for ASSUMED_COLOR setting.
Packit f574b8
 */
Packit f574b8
static int assumed_color_fun(char *buffer)
Packit f574b8
{
Packit f574b8
    const char *fg = buffer, *bg;
Packit f574b8
    char *temp_fg = 0;
Packit f574b8
Packit f574b8
    if (LYuse_default_colors) {
Packit f574b8
Packit f574b8
	/*
Packit f574b8
	 * We are expecting a line of the form:
Packit f574b8
	 *    FOREGROUND:BACKGROUND
Packit f574b8
	 */
Packit f574b8
	if (NULL == (bg = find_colon(fg)))
Packit f574b8
	    exit_with_color_syntax(buffer);
Packit f574b8
Packit f574b8
	StrAllocCopy(temp_fg, fg);
Packit f574b8
	temp_fg[bg++ - fg] = '\0';
Packit f574b8
Packit f574b8
	default_fg = check_color(temp_fg, default_fg);
Packit f574b8
	default_bg = check_color(bg, default_bg);
Packit f574b8
Packit f574b8
	if (default_fg == ERR_COLOR
Packit f574b8
	    || default_bg == ERR_COLOR)
Packit f574b8
	    exit_with_color_syntax(buffer);
Packit f574b8
	FREE(temp_fg);
Packit f574b8
    } else {
Packit f574b8
	CTRACE((tfp, "...ignored since DEFAULT_COLORS:off\n"));
Packit f574b8
    }
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
#endif /* EXP_ASSUMED_COLOR */
Packit f574b8
Packit f574b8
#ifdef USE_COLOR_TABLE
Packit f574b8
static int color_fun(char *value)
Packit f574b8
{
Packit f574b8
    parse_color(value);
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
#endif
Packit f574b8
Packit f574b8
#ifdef USE_COLOR_STYLE
Packit f574b8
static int lynx_lss_file_fun(char *value)
Packit f574b8
{
Packit f574b8
    CTRACE((tfp, "lynx_lss_file_fun '%s'\n", NonNull(value)));
Packit f574b8
    if (isEmpty(value)) {
Packit f574b8
	clear_lss_list();
Packit f574b8
    } else {
Packit f574b8
	add_to_lss_list(value, NULL);
Packit f574b8
    }
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
#endif
Packit f574b8
Packit f574b8
#ifdef USE_DEFAULT_COLORS
Packit f574b8
void update_default_colors(void)
Packit f574b8
{
Packit f574b8
    int old_fg = default_fg;
Packit f574b8
    int old_bg = default_bg;
Packit f574b8
Packit f574b8
    default_color_reset = !LYuse_default_colors;
Packit f574b8
    if (LYuse_default_colors) {
Packit f574b8
	default_color_reset = FALSE;
Packit f574b8
	default_fg = DEFAULT_COLOR;
Packit f574b8
	default_bg = DEFAULT_COLOR;
Packit f574b8
    } else {
Packit f574b8
	default_color_reset = TRUE;
Packit f574b8
	default_fg = COLOR_WHITE;
Packit f574b8
	default_bg = COLOR_BLACK;
Packit f574b8
    }
Packit f574b8
    if (old_fg != default_fg || old_bg != default_bg) {
Packit f574b8
	lynx_setup_colors();
Packit f574b8
#ifdef USE_COLOR_STYLE
Packit f574b8
	update_color_style();
Packit f574b8
#endif
Packit f574b8
    }
Packit f574b8
}
Packit f574b8
Packit f574b8
static int default_colors_fun(char *value)
Packit f574b8
{
Packit f574b8
    LYuse_default_colors = is_true(value);
Packit f574b8
    update_default_colors();
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
#endif
Packit f574b8
Packit f574b8
static int default_bookmark_file_fun(char *value)
Packit f574b8
{
Packit f574b8
    set_default_bookmark_page(value);
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
static int default_cache_size_fun(char *value)
Packit f574b8
{
Packit f574b8
    HTCacheSize = atoi(value);
Packit f574b8
    if (HTCacheSize < 2)
Packit f574b8
	HTCacheSize = 2;
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
static int default_editor_fun(char *value)
Packit f574b8
{
Packit f574b8
    if (!system_editor)
Packit f574b8
	StrAllocCopy(editor, value);
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
static int numbers_as_arrows_fun(char *value)
Packit f574b8
{
Packit f574b8
    if (is_true(value))
Packit f574b8
	keypad_mode = NUMBERS_AS_ARROWS;
Packit f574b8
    else
Packit f574b8
	keypad_mode = LINKS_ARE_NUMBERED;
Packit f574b8
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
#ifdef DIRED_SUPPORT
Packit f574b8
static int dired_menu_fun(char *value)
Packit f574b8
{
Packit f574b8
    add_menu_item(value);
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
#endif
Packit f574b8
Packit f574b8
static int jumpfile_fun(char *value)
Packit f574b8
{
Packit f574b8
    char *buffer = NULL;
Packit f574b8
Packit f574b8
    HTSprintf0(&buffer, "JUMPFILE:%s", value);
Packit f574b8
    if (!LYJumpInit(buffer))
Packit f574b8
	CTRACE((tfp, "Failed to register %s\n", buffer));
Packit f574b8
    FREE(buffer);
Packit f574b8
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
#ifdef EXP_KEYBOARD_LAYOUT
Packit f574b8
static int keyboard_layout_fun(char *key)
Packit f574b8
{
Packit f574b8
    if (!LYSetKbLayout(key))
Packit f574b8
	CTRACE((tfp, "Failed to set keyboard layout %s\n", key));
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
#endif /* EXP_KEYBOARD_LAYOUT */
Packit f574b8
Packit f574b8
static int keymap_fun(char *key)
Packit f574b8
{
Packit f574b8
    char *func, *efunc;
Packit f574b8
Packit f574b8
    if ((func = StrChr(key, ':')) != NULL) {
Packit f574b8
	*func++ = '\0';
Packit f574b8
	efunc = StrChr(func, ':');
Packit f574b8
	/* Allow comments on the ends of key remapping lines. - DT */
Packit f574b8
	/* Allow third field for line-editor action. - kw */
Packit f574b8
	if (efunc == func) {	/* have 3rd field, but 2nd field empty */
Packit f574b8
	    func = NULL;
Packit f574b8
	} else if (efunc && strncasecomp(efunc + 1, "DIRED", 5) == 0) {
Packit f574b8
	    if (!remap(key, strtok(func, " \t\n:#"), TRUE)) {
Packit f574b8
		fprintf(stderr,
Packit f574b8
			gettext("key remapping of %s to %s for %s failed\n"),
Packit f574b8
			key, func, efunc + 1);
Packit f574b8
	    } else if (!strcmp("TOGGLE_HELP", func)) {
Packit f574b8
		LYUseNoviceLineTwo = FALSE;
Packit f574b8
	    }
Packit f574b8
	    return 0;
Packit f574b8
	} else if (!remap(key, strtok(func, " \t\n:#"), FALSE)) {
Packit f574b8
	    fprintf(stderr, gettext("key remapping of %s to %s failed\n"),
Packit f574b8
		    key, func);
Packit f574b8
	} else {
Packit f574b8
	    if (!strcmp("TOGGLE_HELP", func))
Packit f574b8
		LYUseNoviceLineTwo = FALSE;
Packit f574b8
	}
Packit f574b8
	if (efunc) {
Packit f574b8
	    efunc++;
Packit f574b8
	    if (efunc == strtok((func ? NULL : efunc), " \t\n:#") && *efunc) {
Packit f574b8
		BOOLEAN success = FALSE;
Packit f574b8
		int lkc = lkcstring_to_lkc(key);
Packit f574b8
		int lec = -1;
Packit f574b8
		int select_edi = 0;
Packit f574b8
		char *sselect_edi = strtok(NULL, " \t\n:#");
Packit f574b8
		char **endp = &sselect_edi;
Packit f574b8
Packit f574b8
		if (sselect_edi) {
Packit f574b8
		    if (*sselect_edi)
Packit f574b8
			select_edi = (int) strtol(sselect_edi, endp, 10);
Packit f574b8
		    if (**endp != '\0') {
Packit f574b8
			fprintf(stderr,
Packit f574b8
				gettext("invalid line-editor selection %s for key %s, selecting all\n"),
Packit f574b8
				sselect_edi, key);
Packit f574b8
			select_edi = 0;
Packit f574b8
		    }
Packit f574b8
		}
Packit f574b8
		/*
Packit f574b8
		 * PASS!  tries to enter the key into the LYLineEditors
Packit f574b8
		 * bindings in a different way from PASS, namely as binding
Packit f574b8
		 * that maps to the specific lynx actioncode (rather than to
Packit f574b8
		 * LYE_FORM_PASS).  That only works for lynx keycodes with
Packit f574b8
		 * modifier bit set, and we have no documented/official way to
Packit f574b8
		 * specify this in the KEYMAP directive, although it can be
Packit f574b8
		 * made to work e.g. by specifying a hex value that has the
Packit f574b8
		 * modifier bit set.  But knowledge about the bit pattern of
Packit f574b8
		 * modifiers should remain in internal matter subject to
Packit f574b8
		 * change...  At any rate, if PASS!  fails try it the same way
Packit f574b8
		 * as for PASS.  - kw
Packit f574b8
		 */
Packit f574b8
		if (!success && strcasecomp(efunc, "PASS!") == 0) {
Packit f574b8
		    if (func) {
Packit f574b8
			lec = LYE_FORM_LAC | lacname_to_lac(func);
Packit f574b8
			success = (BOOL) LYRemapEditBinding(lkc, lec, select_edi);
Packit f574b8
		    }
Packit f574b8
		    if (!success)
Packit f574b8
			fprintf(stderr,
Packit f574b8
				gettext("setting of line-editor binding for key %s (0x%x) to 0x%x for %s failed\n"),
Packit f574b8
				key, lkc, lec, efunc);
Packit f574b8
		    else
Packit f574b8
			return 0;
Packit f574b8
		}
Packit f574b8
		if (!success) {
Packit f574b8
		    lec = lecname_to_lec(efunc);
Packit f574b8
		    success = (BOOL) LYRemapEditBinding(lkc, lec, select_edi);
Packit f574b8
		}
Packit f574b8
		if (!success) {
Packit f574b8
		    if (lec != -1) {
Packit f574b8
			fprintf(stderr,
Packit f574b8
				gettext("setting of line-editor binding for key %s (0x%x) to 0x%x for %s failed\n"),
Packit f574b8
				key, lkc, lec, efunc);
Packit f574b8
		    } else {
Packit f574b8
			fprintf(stderr,
Packit f574b8
				gettext("setting of line-editor binding for key %s (0x%x) for %s failed\n"),
Packit f574b8
				key, lkc, efunc);
Packit f574b8
		    }
Packit f574b8
		}
Packit f574b8
	    }
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
static int localhost_alias_fun(char *value)
Packit f574b8
{
Packit f574b8
    LYAddLocalhostAlias(value);
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
#ifdef LYNXCGI_LINKS
Packit f574b8
static int lynxcgi_environment_fun(char *value)
Packit f574b8
{
Packit f574b8
    add_lynxcgi_environment(value);
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
#endif
Packit f574b8
Packit f574b8
static int lynx_sig_file_fun(char *value)
Packit f574b8
{
Packit f574b8
    char temp[LY_MAXPATH];
Packit f574b8
Packit f574b8
    LYStrNCpy(temp, value, sizeof(temp) - 1);
Packit f574b8
    if (LYPathOffHomeOK(temp, sizeof(temp))) {
Packit f574b8
	StrAllocCopy(LynxSigFile, temp);
Packit f574b8
	LYAddPathToHome(temp, sizeof(temp), LynxSigFile);
Packit f574b8
	StrAllocCopy(LynxSigFile, temp);
Packit f574b8
	CTRACE((tfp, "LYNX_SIG_FILE set to '%s'\n", LynxSigFile));
Packit f574b8
    } else {
Packit f574b8
	CTRACE((tfp, "LYNX_SIG_FILE '%s' is bad. Ignoring.\n", LYNX_SIG_FILE));
Packit f574b8
    }
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
#ifndef DISABLE_NEWS
Packit f574b8
static int news_chunk_size_fun(char *value)
Packit f574b8
{
Packit f574b8
    HTNewsChunkSize = atoi(value);
Packit f574b8
    /*
Packit f574b8
     * If the new HTNewsChunkSize exceeds the maximum,
Packit f574b8
     * increase HTNewsMaxChunk to this size. - FM
Packit f574b8
     */
Packit f574b8
    if (HTNewsChunkSize > HTNewsMaxChunk)
Packit f574b8
	HTNewsMaxChunk = HTNewsChunkSize;
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
static int news_max_chunk_fun(char *value)
Packit f574b8
{
Packit f574b8
    HTNewsMaxChunk = atoi(value);
Packit f574b8
    /*
Packit f574b8
     * If HTNewsChunkSize exceeds the new maximum,
Packit f574b8
     * reduce HTNewsChunkSize to this maximum. - FM
Packit f574b8
     */
Packit f574b8
    if (HTNewsChunkSize > HTNewsMaxChunk)
Packit f574b8
	HTNewsChunkSize = HTNewsMaxChunk;
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
static int news_posting_fun(char *value)
Packit f574b8
{
Packit f574b8
    LYNewsPosting = is_true(value);
Packit f574b8
    no_newspost = (BOOL) (LYNewsPosting == FALSE);
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
#endif /* DISABLE_NEWS */
Packit f574b8
Packit f574b8
#ifndef NO_RULES
Packit f574b8
static int cern_rulesfile_fun(char *value)
Packit f574b8
{
Packit f574b8
    char *rulesfile1 = NULL;
Packit f574b8
    char *rulesfile2 = NULL;
Packit f574b8
Packit f574b8
    if (HTLoadRules(value) >= 0) {
Packit f574b8
	return 0;
Packit f574b8
    }
Packit f574b8
    StrAllocCopy(rulesfile1, value);
Packit f574b8
    LYTrimLeading(value);
Packit f574b8
    LYTrimTrailing(value);
Packit f574b8
Packit f574b8
    StrAllocCopy(rulesfile2, value);
Packit f574b8
    LYTildeExpand(&rulesfile2, FALSE);
Packit f574b8
Packit f574b8
    if (strcmp(rulesfile1, rulesfile2) &&
Packit f574b8
	HTLoadRules(rulesfile2) >= 0) {
Packit f574b8
	FREE(rulesfile1);
Packit f574b8
	FREE(rulesfile2);
Packit f574b8
	return 0;
Packit f574b8
    }
Packit f574b8
    fprintf(stderr,
Packit f574b8
	    gettext("Lynx: cannot start, CERN rules file %s is not available\n"),
Packit f574b8
	    non_empty(rulesfile2) ? rulesfile2 : gettext("(no name)"));
Packit f574b8
    exit_immediately(EXIT_FAILURE);
Packit f574b8
    return 0;			/* though redundant, for compiler-warnings */
Packit f574b8
}
Packit f574b8
#endif /* NO_RULES */
Packit f574b8
Packit f574b8
static int referer_with_query_fun(char *value)
Packit f574b8
{
Packit f574b8
    if (!strncasecomp(value, "SEND", 4))
Packit f574b8
	LYRefererWithQuery = 'S';
Packit f574b8
    else if (!strncasecomp(value, "PARTIAL", 7))
Packit f574b8
	LYRefererWithQuery = 'P';
Packit f574b8
    else
Packit f574b8
	LYRefererWithQuery = 'D';
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
static int status_buffer_size_fun(char *value)
Packit f574b8
{
Packit f574b8
    status_buf_size = atoi(value);
Packit f574b8
    if (status_buf_size < 2)
Packit f574b8
	status_buf_size = 2;
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
static int startfile_fun(char *value)
Packit f574b8
{
Packit f574b8
    StrAllocCopy(startfile, value);
Packit f574b8
Packit f574b8
#ifdef USE_PROGRAM_DIR
Packit f574b8
    if (is_url(startfile) == 0) {
Packit f574b8
	char *tmp = NULL;
Packit f574b8
Packit f574b8
	HTSprintf0(&tmp, "%s\\%s", program_dir, startfile);
Packit f574b8
	FREE(startfile);
Packit f574b8
	LYLocalFileToURL(&startfile, tmp);
Packit f574b8
	FREE(tmp);
Packit f574b8
    }
Packit f574b8
#endif
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
static int suffix_fun(char *value)
Packit f574b8
{
Packit f574b8
    char *mime_type, *p, *parsed;
Packit f574b8
    const char *encoding = NULL;
Packit f574b8
    char *sq = NULL;
Packit f574b8
    char *description = NULL;
Packit f574b8
    double q = 1.0;
Packit f574b8
Packit f574b8
    if ((strlen(value) < 3)
Packit f574b8
	|| (NULL == (mime_type = StrChr(value, ':')))) {
Packit f574b8
	CTRACE((tfp, "Invalid SUFFIX:%s ignored.\n", value));
Packit f574b8
	return 0;
Packit f574b8
    }
Packit f574b8
Packit f574b8
    *mime_type++ = '\0';
Packit f574b8
    if (*mime_type) {
Packit f574b8
	if ((parsed = StrChr(mime_type, ':')) != NULL) {
Packit f574b8
	    *parsed++ = '\0';
Packit f574b8
	    if ((sq = StrChr(parsed, ':')) != NULL) {
Packit f574b8
		*sq++ = '\0';
Packit f574b8
		if ((description = StrChr(sq, ':')) != NULL) {
Packit f574b8
		    *description++ = '\0';
Packit f574b8
		    if ((p = StrChr(sq, ':')) != NULL)
Packit f574b8
			*p = '\0';
Packit f574b8
		    LYTrimTail(description);
Packit f574b8
		}
Packit f574b8
		LYRemoveBlanks(sq);
Packit f574b8
		if (!*sq)
Packit f574b8
		    sq = NULL;
Packit f574b8
	    }
Packit f574b8
	    LYRemoveBlanks(parsed);
Packit f574b8
	    LYLowerCase(parsed);
Packit f574b8
	    if (!*parsed)
Packit f574b8
		parsed = NULL;
Packit f574b8
	}
Packit f574b8
	encoding = parsed;
Packit f574b8
    }
Packit f574b8
Packit f574b8
    LYRemoveBlanks(mime_type);
Packit f574b8
    /*
Packit f574b8
     * mime-type is not converted to lowercase on input, to make it possible to
Packit f574b8
     * reproduce the equivalent of some of the HTInit.c defaults that use mixed
Packit f574b8
     * case, although that is not recomended.  - kw
Packit f574b8
     */
Packit f574b8
    if (!*mime_type) {		/* that's ok now, with an encoding!  */
Packit f574b8
	CTRACE((tfp, "SUFFIX:%s without MIME type for %s\n", value,
Packit f574b8
		encoding ? encoding : "what?"));
Packit f574b8
	mime_type = NULL;	/* that's ok now, with an encoding!  */
Packit f574b8
	if (!encoding)
Packit f574b8
	    return 0;
Packit f574b8
    }
Packit f574b8
Packit f574b8
    if (!encoding) {
Packit f574b8
	if (strstr(mime_type, "tex") != NULL ||
Packit f574b8
	    strstr(mime_type, "postscript") != NULL ||
Packit f574b8
	    strstr(mime_type, "sh") != NULL ||
Packit f574b8
	    strstr(mime_type, "troff") != NULL ||
Packit f574b8
	    strstr(mime_type, "rtf") != NULL)
Packit f574b8
	    encoding = "8bit";
Packit f574b8
	else
Packit f574b8
	    encoding = "binary";
Packit f574b8
    }
Packit f574b8
    if (!sq) {
Packit f574b8
	q = 1.0;
Packit f574b8
    } else {
Packit f574b8
	double df = strtod(sq, &p);
Packit f574b8
Packit f574b8
	if (p == sq && df <= 0.0) {
Packit f574b8
	    CTRACE((tfp, "Invalid q=%s for SUFFIX:%s, using -1.0\n",
Packit f574b8
		    sq, value));
Packit f574b8
	    q = -1.0;
Packit f574b8
	} else {
Packit f574b8
	    q = df;
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
    HTSetSuffix5(value, mime_type, encoding, description, q);
Packit f574b8
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
static int suffix_order_fun(char *value)
Packit f574b8
{
Packit f574b8
    char *p = value;
Packit f574b8
    char *optn;
Packit f574b8
    BOOLEAN want_file_init_now = FALSE;
Packit f574b8
Packit f574b8
    LYUseBuiltinSuffixes = TRUE;
Packit f574b8
    while ((optn = HTNextTok(&p, ", ", "", NULL)) != NULL) {
Packit f574b8
	if (!strcasecomp(optn, "NO_BUILTIN")) {
Packit f574b8
	    LYUseBuiltinSuffixes = FALSE;
Packit f574b8
	} else if (!strcasecomp(optn, "PRECEDENCE_HERE")) {
Packit f574b8
	    want_file_init_now = TRUE;
Packit f574b8
	} else if (!strcasecomp(optn, "PRECEDENCE_OTHER")) {
Packit f574b8
	    want_file_init_now = FALSE;
Packit f574b8
	} else {
Packit f574b8
	    CTRACE((tfp, "Invalid SUFFIX_ORDER:%s\n", optn));
Packit f574b8
	    break;
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
Packit f574b8
    if (want_file_init_now && !FileInitAlreadyDone) {
Packit f574b8
	HTFileInit();
Packit f574b8
	FileInitAlreadyDone = TRUE;
Packit f574b8
    }
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
static int system_editor_fun(char *value)
Packit f574b8
{
Packit f574b8
    StrAllocCopy(editor, value);
Packit f574b8
    system_editor = TRUE;
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
#define SetViewer(mime_type, viewer) \
Packit f574b8
    HTSetPresentation(mime_type, viewer, 0, 1.0, 3.0, 0.0, 0L, mediaCFG)
Packit f574b8
Packit f574b8
static int viewer_fun(char *value)
Packit f574b8
{
Packit f574b8
    char *mime_type;
Packit f574b8
    char *viewer;
Packit f574b8
    char *environment;
Packit f574b8
Packit f574b8
    mime_type = value;
Packit f574b8
Packit f574b8
    if ((strlen(value) < 3)
Packit f574b8
	|| (NULL == (viewer = StrChr(mime_type, ':'))))
Packit f574b8
	return 0;
Packit f574b8
Packit f574b8
    *viewer++ = '\0';
Packit f574b8
Packit f574b8
    LYRemoveBlanks(mime_type);
Packit f574b8
    LYLowerCase(mime_type);
Packit f574b8
Packit f574b8
    environment = strrchr(viewer, ':');
Packit f574b8
    if ((environment != NULL) &&
Packit f574b8
	(strlen(viewer) > 1) && *(environment - 1) != '\\') {
Packit f574b8
	*environment++ = '\0';
Packit f574b8
	remove_backslashes(viewer);
Packit f574b8
	/*
Packit f574b8
	 * If environment equals xwindows then only assign the presentation if
Packit f574b8
	 * there is a $DISPLAY variable.
Packit f574b8
	 */
Packit f574b8
	if (!strcasecomp(environment, "XWINDOWS")) {
Packit f574b8
	    if (LYgetXDisplay() != NULL)
Packit f574b8
		SetViewer(mime_type, viewer);
Packit f574b8
	} else if (!strcasecomp(environment, "NON_XWINDOWS")) {
Packit f574b8
	    if (LYgetXDisplay() == NULL)
Packit f574b8
		SetViewer(mime_type, viewer);
Packit f574b8
	} else {
Packit f574b8
	    SetViewer(mime_type, viewer);
Packit f574b8
	}
Packit f574b8
    } else {
Packit f574b8
	remove_backslashes(viewer);
Packit f574b8
	SetViewer(mime_type, viewer);
Packit f574b8
    }
Packit f574b8
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
static int nonrest_sigwinch_fun(char *value)
Packit f574b8
{
Packit f574b8
    if (!strncasecomp(value, "XWINDOWS", 8)) {
Packit f574b8
	LYNonRestartingSIGWINCH = (BOOL) (LYgetXDisplay() != NULL);
Packit f574b8
    } else {
Packit f574b8
	LYNonRestartingSIGWINCH = is_true(value);
Packit f574b8
    }
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
#ifdef USE_CHARSET_CHOICE
Packit f574b8
static void matched_charset_choice(int display_charset,
Packit f574b8
				   int i)
Packit f574b8
{
Packit f574b8
    int j;
Packit f574b8
Packit f574b8
    if (display_charset && !custom_display_charset) {
Packit f574b8
	for (custom_display_charset = TRUE, j = 0; j < LYNumCharsets; ++j)
Packit f574b8
	    charset_subsets[j].hide_display = TRUE;
Packit f574b8
    } else if (!display_charset && !custom_assumed_doc_charset) {
Packit f574b8
	for (custom_assumed_doc_charset = TRUE, j = 0; j < LYNumCharsets; ++j)
Packit f574b8
	    charset_subsets[j].hide_assumed = TRUE;
Packit f574b8
    }
Packit f574b8
    if (display_charset)
Packit f574b8
	charset_subsets[i].hide_display = FALSE;
Packit f574b8
    else
Packit f574b8
	charset_subsets[i].hide_assumed = FALSE;
Packit f574b8
}
Packit f574b8
Packit f574b8
static int parse_charset_choice(char *p,
Packit f574b8
				int display_charset)	/*if FALSE, then assumed doc charset */
Packit f574b8
{
Packit f574b8
    int len, i;
Packit f574b8
    int matches = 0;
Packit f574b8
Packit f574b8
    /*only one charset choice is allowed per line! */
Packit f574b8
    LYTrimHead(p);
Packit f574b8
    LYTrimTail(p);
Packit f574b8
    CTRACE((tfp, "parsing charset choice for %s:\"%s\"",
Packit f574b8
	    (display_charset ? "display charset" : "assumed doc charset"), p));
Packit f574b8
    len = (int) strlen(p);
Packit f574b8
    if (!len) {
Packit f574b8
	CTRACE((tfp, " - EMPTY STRING\n"));
Packit f574b8
	return 1;
Packit f574b8
    }
Packit f574b8
    if (*p == '*' && len == 1) {
Packit f574b8
	if (display_charset)
Packit f574b8
	    for (custom_display_charset = TRUE, i = 0; i < LYNumCharsets; ++i)
Packit f574b8
		charset_subsets[i].hide_display = FALSE;
Packit f574b8
	else
Packit f574b8
	    for (custom_assumed_doc_charset = TRUE, i = 0; i < LYNumCharsets; ++i)
Packit f574b8
		charset_subsets[i].hide_assumed = FALSE;
Packit f574b8
	CTRACE((tfp, " - all unhidden\n"));
Packit f574b8
	return 0;
Packit f574b8
    }
Packit f574b8
    if (p[len - 1] == '*') {
Packit f574b8
	--len;
Packit f574b8
	for (i = 0; i < LYNumCharsets; ++i) {
Packit f574b8
	    if ((!strncasecomp(p, LYchar_set_names[i], len)) ||
Packit f574b8
		(!strncasecomp(p, LYCharSet_UC[i].MIMEname, len))) {
Packit f574b8
		++matches;
Packit f574b8
		matched_charset_choice(display_charset, i);
Packit f574b8
	    }
Packit f574b8
	}
Packit f574b8
	CTRACE((tfp, " - %d matches\n", matches));
Packit f574b8
	return 0;
Packit f574b8
    } else {
Packit f574b8
	for (i = 0; i < LYNumCharsets; ++i) {
Packit f574b8
	    if ((!strcasecomp(p, LYchar_set_names[i])) ||
Packit f574b8
		(!strcasecomp(p, LYCharSet_UC[i].MIMEname))) {
Packit f574b8
		matched_charset_choice(display_charset, i);
Packit f574b8
		++matches;
Packit f574b8
		CTRACE((tfp, " - OK, %d matches\n", matches));
Packit f574b8
		return 0;
Packit f574b8
	    }
Packit f574b8
	}
Packit f574b8
	CTRACE((tfp, " - NOT recognised\n"));
Packit f574b8
	return 1;
Packit f574b8
    }
Packit f574b8
}
Packit f574b8
Packit f574b8
static int parse_display_charset_choice(char *p)
Packit f574b8
{
Packit f574b8
    return parse_charset_choice(p, 1);
Packit f574b8
}
Packit f574b8
Packit f574b8
static int parse_assumed_doc_charset_choice(char *p)
Packit f574b8
{
Packit f574b8
    return parse_charset_choice(p, 0);
Packit f574b8
}
Packit f574b8
Packit f574b8
#endif /* USE_CHARSET_CHOICE */
Packit f574b8
Packit f574b8
#ifdef USE_EXTERNALS
Packit f574b8
/*
Packit f574b8
 * EXTERNAL and EXTERNAL_MENU share the same list.  EXTERNAL_MENU allows
Packit f574b8
 * setting a different name than the command string.
Packit f574b8
 */
Packit f574b8
static int external_fun(char *str)
Packit f574b8
{
Packit f574b8
    add_item_to_list(str, &externals, FALSE, TRUE);
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
#endif
Packit f574b8
Packit f574b8
#ifdef USE_PRETTYSRC
Packit f574b8
static void html_src_bad_syntax(char *value,
Packit f574b8
				char *option_name)
Packit f574b8
{
Packit f574b8
    char *buf = 0;
Packit f574b8
Packit f574b8
    HTSprintf0(&buf, "HTMLSRC_%s", option_name);
Packit f574b8
    LYUpperCase(buf);
Packit f574b8
    fprintf(stderr, "Bad syntax in TAGSPEC %s:%s\n", buf, value);
Packit f574b8
    exit_immediately(EXIT_FAILURE);
Packit f574b8
}
Packit f574b8
Packit f574b8
static int parse_html_src_spec(HTlexeme lexeme_code, char *value,
Packit f574b8
			       char *option_name)
Packit f574b8
{
Packit f574b8
    /* Now checking the value for being correct.  Since HTML_dtd is not
Packit f574b8
     * initialized completely (member tags points to non-initiailized data), we
Packit f574b8
     * use tags_old.  If the syntax is incorrect, then lynx will exit with error
Packit f574b8
     * message.
Packit f574b8
     */
Packit f574b8
    char *ts2;
Packit f574b8
Packit f574b8
    if (isEmpty(value))
Packit f574b8
	return 0;		/* silently ignoring */
Packit f574b8
Packit f574b8
#define BS() html_src_bad_syntax(value,option_name)
Packit f574b8
Packit f574b8
    ts2 = StrChr(value, ':');
Packit f574b8
    if (!ts2)
Packit f574b8
	BS();
Packit f574b8
Packit f574b8
    *ts2 = '\0';
Packit f574b8
Packit f574b8
    CTRACE2(TRACE_CFG, (tfp,
Packit f574b8
			"LYReadCFG - parsing tagspec '%s:%s' for option '%s'\n",
Packit f574b8
			value, ts2, option_name));
Packit f574b8
    html_src_clean_item(lexeme_code);
Packit f574b8
    if (!html_src_parse_tagspec(value, lexeme_code, TRUE, TRUE)
Packit f574b8
	|| !html_src_parse_tagspec(ts2, lexeme_code, TRUE, TRUE)) {
Packit f574b8
	*ts2 = ':';
Packit f574b8
	BS();
Packit f574b8
    }
Packit f574b8
Packit f574b8
    *ts2 = ':';
Packit f574b8
    StrAllocCopy(HTL_tagspecs[lexeme_code], value);
Packit f574b8
#undef BS
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
static int psrcspec_fun(char *s)
Packit f574b8
{
Packit f574b8
    char *e;
Packit f574b8
    /* *INDENT-OFF* */
Packit f574b8
    static Config_Enum lexemnames[] =
Packit f574b8
    {
Packit f574b8
	{ "comm",	HTL_comm	},
Packit f574b8
	{ "tag",	HTL_tag		},
Packit f574b8
	{ "attrib",	HTL_attrib	},
Packit f574b8
	{ "attrval",	HTL_attrval	},
Packit f574b8
	{ "abracket",	HTL_abracket	},
Packit f574b8
	{ "entity",	HTL_entity	},
Packit f574b8
	{ "href",	HTL_href	},
Packit f574b8
	{ "entire",	HTL_entire	},
Packit f574b8
	{ "badseq",	HTL_badseq	},
Packit f574b8
	{ "badtag",	HTL_badtag	},
Packit f574b8
	{ "badattr",	HTL_badattr	},
Packit f574b8
	{ "sgmlspecial", HTL_sgmlspecial },
Packit f574b8
	{ NULL,		-1		}
Packit f574b8
    };
Packit f574b8
    /* *INDENT-ON* */
Packit f574b8
Packit f574b8
    int found;
Packit f574b8
Packit f574b8
    e = StrChr(s, ':');
Packit f574b8
    if (!e) {
Packit f574b8
	CTRACE((tfp,
Packit f574b8
		"bad format of PRETTYSRC_SPEC setting value, ignored %s\n",
Packit f574b8
		s));
Packit f574b8
	return 0;
Packit f574b8
    }
Packit f574b8
    *e = '\0';
Packit f574b8
    if (!LYgetEnum(lexemnames, s, &found)) {
Packit f574b8
	CTRACE((tfp,
Packit f574b8
		"bad format of PRETTYSRC_SPEC setting value, ignored %s:%s\n",
Packit f574b8
		s, e + 1));
Packit f574b8
	return 0;
Packit f574b8
    }
Packit f574b8
    parse_html_src_spec((HTlexeme) found, e + 1, s);
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
static int read_htmlsrc_attrname_xform(char *str)
Packit f574b8
{
Packit f574b8
    int val;
Packit f574b8
Packit f574b8
    if (1 == sscanf(str, "%d", &val)) {
Packit f574b8
	if (val < 0 || val > 2) {
Packit f574b8
	    CTRACE((tfp,
Packit f574b8
		    "bad value for htmlsrc_attrname_xform (ignored - must be one of 0,1,2): %d\n",
Packit f574b8
		    val));
Packit f574b8
	} else
Packit f574b8
	    attrname_transform = val;
Packit f574b8
    } else {
Packit f574b8
	CTRACE((tfp, "bad value for htmlsrc_attrname_xform (ignored): %s\n",
Packit f574b8
		str));
Packit f574b8
    }
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
Packit f574b8
static int read_htmlsrc_tagname_xform(char *str)
Packit f574b8
{
Packit f574b8
    int val;
Packit f574b8
Packit f574b8
    if (1 == sscanf(str, "%d", &val)) {
Packit f574b8
	if (val < 0 || val > 2) {
Packit f574b8
	    CTRACE((tfp,
Packit f574b8
		    "bad value for htmlsrc_tagname_xform (ignored - must be one of 0,1,2): %d\n",
Packit f574b8
		    val));
Packit f574b8
	} else
Packit f574b8
	    tagname_transform = val;
Packit f574b8
    } else {
Packit f574b8
	CTRACE((tfp, "bad value for htmlsrc_tagname_xform (ignored): %s\n",
Packit f574b8
		str));
Packit f574b8
    }
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
#endif
Packit f574b8
Packit f574b8
#ifdef USE_SESSIONS
Packit f574b8
static int session_limit_fun(char *value)
Packit f574b8
{
Packit f574b8
    session_limit = (short) atoi(value);
Packit f574b8
    if (session_limit < 1)
Packit f574b8
	session_limit = 1;
Packit f574b8
    else if (session_limit > MAX_SESSIONS)
Packit f574b8
	session_limit = MAX_SESSIONS;
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
#endif /* USE_SESSIONS */
Packit f574b8
Packit f574b8
#if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401
Packit f574b8
static int screen_size_fun(char *value)
Packit f574b8
{
Packit f574b8
    char *cp;
Packit f574b8
Packit f574b8
    if ((cp = StrChr(value, ',')) != 0) {
Packit f574b8
	*cp++ = '\0';		/* Terminate ID */
Packit f574b8
	scrsize_x = atoi(value);
Packit f574b8
	scrsize_y = atoi(cp);
Packit f574b8
	if ((scrsize_x <= 1) || (scrsize_y <= 1)) {
Packit f574b8
	    scrsize_x = scrsize_y = 0;
Packit f574b8
	}
Packit f574b8
	if ((scrsize_x > 0) && (scrsize_x < 80)) {
Packit f574b8
	    scrsize_x = 80;
Packit f574b8
	}
Packit f574b8
	if ((scrsize_y > 0) && (scrsize_y < 4)) {
Packit f574b8
	    scrsize_y = 4;
Packit f574b8
	}
Packit f574b8
	CTRACE((tfp, "scrsize: x=%d, y=%d\n", scrsize_x, scrsize_y));
Packit f574b8
    }
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
#endif
Packit f574b8
Packit f574b8
#if defined(HAVE_LIBINTL_H) || defined(HAVE_LIBGETTEXT_H)
Packit f574b8
static int message_language_fun(char *value)
Packit f574b8
{
Packit f574b8
    char *tmp = NULL;
Packit f574b8
Packit f574b8
    HTSprintf0(&tmp, "LANG=%s", value);
Packit f574b8
    putenv(tmp);
Packit f574b8
Packit f574b8
    LYSetTextDomain();
Packit f574b8
Packit f574b8
    return 0;
Packit f574b8
}
Packit f574b8
#endif
Packit f574b8
Packit f574b8
/* This table is searched ignoring case */
Packit f574b8
/* *INDENT-OFF* */
Packit f574b8
static Config_Type Config_Table [] =
Packit f574b8
{
Packit f574b8
     PARSE_SET(RC_ACCEPT_ALL_COOKIES,   LYAcceptAllCookies),
Packit f574b8
     PARSE_TIM(RC_ALERTSECS,            AlertSecs),
Packit f574b8
#if USE_BLAT_MAILER
Packit f574b8
     PARSE_SET(RC_ALT_BLAT_MAIL,        mail_is_altblat),
Packit f574b8
#endif
Packit f574b8
     PARSE_SET(RC_ALWAYS_RESUBMIT_POSTS, LYresubmit_posts),
Packit f574b8
#ifdef EXEC_LINKS
Packit f574b8
     PARSE_DEF(RC_ALWAYS_TRUSTED_EXEC,  ALWAYS_EXEC_PATH),
Packit f574b8
#endif
Packit f574b8
     PARSE_FUN(RC_ASSUME_CHARSET,       assume_charset_fun),
Packit f574b8
     PARSE_FUN(RC_ASSUME_LOCAL_CHARSET, assume_local_charset_fun),
Packit f574b8
     PARSE_FUN(RC_ASSUME_UNREC_CHARSET, assume_unrec_charset_fun),
Packit f574b8
#ifdef EXP_ASSUMED_COLOR
Packit f574b8
     PARSE_FUN(RC_ASSUMED_COLOR,        assumed_color_fun),
Packit f574b8
#endif
Packit f574b8
#ifdef USE_CHARSET_CHOICE
Packit f574b8
     PARSE_FUN(RC_ASSUMED_DOC_CHARSET_CHOICE, parse_assumed_doc_charset_choice),
Packit f574b8
#endif
Packit f574b8
#ifdef DIRED_SUPPORT
Packit f574b8
     PARSE_INT(RC_AUTO_UNCACHE_DIRLISTS, LYAutoUncacheDirLists),
Packit f574b8
#endif
Packit f574b8
#ifndef DISABLE_BIBP
Packit f574b8
     PARSE_STR(RC_BIBP_BIBHOST,         BibP_bibhost),
Packit f574b8
     PARSE_STR(RC_BIBP_GLOBALSERVER,    BibP_globalserver),
Packit f574b8
#endif
Packit f574b8
#if USE_BLAT_MAILER
Packit f574b8
     PARSE_SET(RC_BLAT_MAIL,            mail_is_blat),
Packit f574b8
#endif
Packit f574b8
     PARSE_SET(RC_BLOCK_MULTI_BOOKMARKS, LYMBMBlocked),
Packit f574b8
     PARSE_SET(RC_BOLD_H1,              bold_H1),
Packit f574b8
     PARSE_SET(RC_BOLD_HEADERS,         bold_headers),
Packit f574b8
     PARSE_SET(RC_BOLD_NAME_ANCHORS,    bold_name_anchors),
Packit f574b8
#ifndef DISABLE_FTP
Packit f574b8
     PARSE_LST(RC_BROKEN_FTP_EPSV,      broken_ftp_epsv),
Packit f574b8
     PARSE_LST(RC_BROKEN_FTP_RETR,      broken_ftp_retr),
Packit f574b8
#endif
Packit f574b8
     PARSE_PRG(RC_BZIP2_PATH,           ppBZIP2),
Packit f574b8
     PARSE_SET(RC_CASE_SENSITIVE_ALWAYS_ON, LYcase_sensitive),
Packit f574b8
     PARSE_FUN(RC_CHARACTER_SET,        character_set_fun),
Packit f574b8
#ifdef CAN_SWITCH_DISPLAY_CHARSET
Packit f574b8
     PARSE_STR(RC_CHARSET_SWITCH_RULES, charset_switch_rules),
Packit f574b8
     PARSE_STR(RC_CHARSETS_DIRECTORY,   charsets_directory),
Packit f574b8
#endif
Packit f574b8
     PARSE_SET(RC_CHECKMAIL,            check_mail),
Packit f574b8
     PARSE_PRG(RC_CHMOD_PATH,           ppCHMOD),
Packit f574b8
     PARSE_SET(RC_COLLAPSE_BR_TAGS,     LYCollapseBRs),
Packit f574b8
#ifdef USE_COLOR_TABLE
Packit f574b8
     PARSE_FUN(RC_COLOR,                color_fun),
Packit f574b8
#endif
Packit f574b8
#ifdef USE_COLOR_STYLE
Packit f574b8
     PARSE_FUN(RC_COLOR_STYLE,          lynx_lss_file_fun),
Packit f574b8
#endif
Packit f574b8
     PARSE_PRG(RC_COMPRESS_PATH,        ppCOMPRESS),
Packit f574b8
     PARSE_PRG(RC_COPY_PATH,            ppCOPY),
Packit f574b8
     PARSE_INT(RC_CONNECT_TIMEOUT,      connect_timeout),
Packit f574b8
     PARSE_SET(RC_CONV_JISX0201KANA,    conv_jisx0201kana),
Packit f574b8
     PARSE_STR(RC_COOKIE_ACCEPT_DOMAINS, LYCookieSAcceptDomains),
Packit f574b8
#ifdef USE_PERSISTENT_COOKIES
Packit f574b8
     PARSE_STR(RC_COOKIE_FILE,          LYCookieFile),
Packit f574b8
#endif /* USE_PERSISTENT_COOKIES */
Packit f574b8
     PARSE_STR(RC_COOKIE_LOOSE_INVALID_DOMAINS, LYCookieSLooseCheckDomains),
Packit f574b8
     PARSE_STR(RC_COOKIE_QUERY_INVALID_DOMAINS, LYCookieSQueryCheckDomains),
Packit f574b8
     PARSE_STR(RC_COOKIE_REJECT_DOMAINS, LYCookieSRejectDomains),
Packit f574b8
#ifdef USE_PERSISTENT_COOKIES
Packit f574b8
     PARSE_STR(RC_COOKIE_SAVE_FILE,     LYCookieSaveFile),
Packit f574b8
#endif /* USE_PERSISTENT_COOKIES */
Packit f574b8
     PARSE_STR(RC_COOKIE_STRICT_INVALID_DOMAIN, LYCookieSStrictCheckDomains),
Packit f574b8
     PARSE_Env(RC_CSO_PROXY,            0),
Packit f574b8
#ifdef VMS
Packit f574b8
     PARSE_PRG(RC_CSWING_PATH,          ppCSWING),
Packit f574b8
#endif
Packit f574b8
     PARSE_TIM(RC_DELAYSECS,            DelaySecs),
Packit f574b8
     PARSE_FUN(RC_DEFAULT_BOOKMARK_FILE, default_bookmark_file_fun),
Packit f574b8
     PARSE_FUN(RC_DEFAULT_CACHE_SIZE,   default_cache_size_fun),
Packit f574b8
#ifdef USE_DEFAULT_COLORS
Packit f574b8
     PARSE_FUN(RC_DEFAULT_COLORS,       default_colors_fun),
Packit f574b8
#endif
Packit f574b8
     PARSE_FUN(RC_DEFAULT_EDITOR,       default_editor_fun),
Packit f574b8
     PARSE_STR(RC_DEFAULT_INDEX_FILE,   indexfile),
Packit f574b8
     PARSE_ENU(RC_DEFAULT_KEYPAD_MODE,  keypad_mode, tbl_keypad_mode),
Packit f574b8
     PARSE_FUN(RC_DEFAULT_KEYPAD_MODE_NUMARO, numbers_as_arrows_fun),
Packit f574b8
     PARSE_ENU(RC_DEFAULT_USER_MODE,    user_mode, tbl_user_mode),
Packit f574b8
#if defined(VMS) && defined(VAXC) && !defined(__DECC)
Packit f574b8
     PARSE_INT(RC_DEFAULT_VIRTUAL_MEMORY_SIZE, HTVirtualMemorySize),
Packit f574b8
#endif
Packit f574b8
#ifdef DIRED_SUPPORT
Packit f574b8
     PARSE_FUN(RC_DIRED_MENU,           dired_menu_fun),
Packit f574b8
#endif
Packit f574b8
#ifdef USE_CHARSET_CHOICE
Packit f574b8
     PARSE_FUN(RC_DISPLAY_CHARSET_CHOICE, parse_display_charset_choice),
Packit f574b8
#endif
Packit f574b8
     PARSE_SET(RC_DONT_WRAP_PRE,        dont_wrap_pre),
Packit f574b8
     PARSE_ADD(RC_DOWNLOADER,           downloaders),
Packit f574b8
     PARSE_SET(RC_EMACS_KEYS_ALWAYS_ON, emacs_keys),
Packit f574b8
     PARSE_FUN(RC_ENABLE_LYNXRC,        enable_lynxrc),
Packit f574b8
     PARSE_SET(RC_ENABLE_SCROLLBACK,    enable_scrollback),
Packit f574b8
#ifdef USE_EXTERNALS
Packit f574b8
     PARSE_ADD(RC_EXTERNAL,             externals),
Packit f574b8
     PARSE_FUN(RC_EXTERNAL_MENU,        external_fun),
Packit f574b8
#endif
Packit f574b8
     PARSE_Env(RC_FINGER_PROXY,         0),
Packit f574b8
#if defined(_WINDOWS)	/* 1998/10/05 (Mon) 17:34:15 */
Packit f574b8
     PARSE_SET(RC_FOCUS_WINDOW,         focus_window),
Packit f574b8
#endif
Packit f574b8
     PARSE_SET(RC_FORCE_8BIT_TOUPPER,   UCForce8bitTOUPPER),
Packit f574b8
     PARSE_ENU(RC_FORCE_COOKIE_PROMPT,  cookie_noprompt, tbl_force_prompt),
Packit f574b8
     PARSE_SET(RC_FORCE_EMPTY_HREFLESS_A, force_empty_hrefless_a),
Packit f574b8
     PARSE_SET(RC_FORCE_HTML,           LYforce_HTML_mode),
Packit f574b8
     PARSE_SET(RC_FORCE_SSL_COOKIES_SECURE, LYForceSSLCookiesSecure),
Packit f574b8
#ifdef USE_SSL
Packit f574b8
     PARSE_ENU(RC_FORCE_SSL_PROMPT,     ssl_noprompt, tbl_force_prompt),
Packit f574b8
#endif
Packit f574b8
#if !defined(NO_OPTION_FORMS) && !defined(NO_OPTION_MENU)
Packit f574b8
     PARSE_SET(RC_FORMS_OPTIONS,        LYUseFormsOptions),
Packit f574b8
#endif
Packit f574b8
     PARSE_STR(RC_FTP_FORMAT,           ftp_format),
Packit f574b8
#ifndef DISABLE_FTP
Packit f574b8
     PARSE_SET(RC_FTP_PASSIVE,          ftp_passive),
Packit f574b8
#endif
Packit f574b8
     PARSE_Env(RC_FTP_PROXY,            0),
Packit f574b8
     PARSE_STR(RC_GLOBAL_EXTENSION_MAP, global_extension_map),
Packit f574b8
     PARSE_STR(RC_GLOBAL_MAILCAP,       global_type_map),
Packit f574b8
     PARSE_Env(RC_GOPHER_PROXY,         0),
Packit f574b8
     PARSE_SET(RC_GOTOBUFFER,           goto_buffer),
Packit f574b8
     PARSE_PRG(RC_GZIP_PATH,            ppGZIP),
Packit f574b8
     PARSE_SET(RC_GUESS_SCHEME,         LYGuessScheme),
Packit f574b8
     PARSE_STR(RC_HELPFILE,             helpfile),
Packit f574b8
     PARSE_FUN(RC_HIDDENLINKS,          hiddenlinks_fun),
Packit f574b8
#ifdef MARK_HIDDEN_LINKS
Packit f574b8
     PARSE_STR(RC_HIDDEN_LINK_MARKER,   hidden_link_marker),
Packit f574b8
#endif
Packit f574b8
     PARSE_SET(RC_HISTORICAL_COMMENTS,  historical_comments),
Packit f574b8
     PARSE_SET(RC_HTML5_CHARSETS,       html5_charsets),
Packit f574b8
#ifdef USE_PRETTYSRC
Packit f574b8
     PARSE_FUN(RC_HTMLSRC_ATTRNAME_XFORM, read_htmlsrc_attrname_xform),
Packit f574b8
     PARSE_FUN(RC_HTMLSRC_TAGNAME_XFORM, read_htmlsrc_tagname_xform),
Packit f574b8
#endif
Packit f574b8
     PARSE_FUN(RC_HTTP_PROTOCOL,        get_http_protocol),
Packit f574b8
     PARSE_Env(RC_HTTP_PROXY,           0),
Packit f574b8
     PARSE_Env(RC_HTTPS_PROXY,          0),
Packit f574b8
     PARSE_REQ(RC_INCLUDE,              0),
Packit f574b8
     PARSE_PRG(RC_INFLATE_PATH,         ppINFLATE),
Packit f574b8
     PARSE_TIM(RC_INFOSECS,             InfoSecs),
Packit f574b8
     PARSE_PRG(RC_INSTALL_PATH,         ppINSTALL),
Packit f574b8
     PARSE_STR(RC_JUMP_PROMPT,          jumpprompt),
Packit f574b8
     PARSE_SET(RC_JUMPBUFFER,           jump_buffer),
Packit f574b8
     PARSE_FUN(RC_JUMPFILE,             jumpfile_fun),
Packit f574b8
#ifdef USE_JUSTIFY_ELTS
Packit f574b8
     PARSE_SET(RC_JUSTIFY,              ok_justify),
Packit f574b8
     PARSE_INT(RC_JUSTIFY_MAX_VOID_PERCENT, justify_max_void_percent),
Packit f574b8
#endif
Packit f574b8
#ifdef EXP_KEYBOARD_LAYOUT
Packit f574b8
     PARSE_FUN(RC_KEYBOARD_LAYOUT,      keyboard_layout_fun),
Packit f574b8
#endif
Packit f574b8
     PARSE_FUN(RC_KEYMAP,               keymap_fun),
Packit f574b8
     PARSE_SET(RC_LEFTARROW_IN_TEXTFLD_PROMPT, textfield_prompt_at_left_edge),
Packit f574b8
     PARSE_SET(RC_LISTONLY,             dump_links_only),
Packit f574b8
#ifndef VMS
Packit f574b8
     PARSE_STR(RC_LIST_FORMAT,          list_format),
Packit f574b8
#endif
Packit f574b8
     PARSE_SET(RC_LIST_INLINE,          dump_links_inline),
Packit f574b8
#ifndef DISABLE_NEWS
Packit f574b8
     PARSE_SET(RC_LIST_NEWS_DATES,      LYListNewsDates),
Packit f574b8
     PARSE_SET(RC_LIST_NEWS_NUMBERS,    LYListNewsNumbers),
Packit f574b8
#endif
Packit f574b8
#ifdef USE_LOCALE_CHARSET
Packit f574b8
     PARSE_SET(RC_LOCALE_CHARSET,       LYLocaleCharset),
Packit f574b8
#endif
Packit f574b8
     PARSE_STR(RC_LOCAL_DOMAIN,         LYLocalDomain),
Packit f574b8
     PARSE_SET(RC_LOCALHOST,            local_host_only),
Packit f574b8
     PARSE_FUN(RC_LOCALHOST_ALIAS,      localhost_alias_fun),
Packit f574b8
#if defined(EXEC_LINKS) || defined(EXEC_SCRIPTS)
Packit f574b8
     PARSE_SET(RC_LOCAL_EXECUTION_LINKS_ALWAYS, local_exec),
Packit f574b8
     PARSE_SET(RC_LOCAL_EXECUTION_LINKS_LOCAL, local_exec_on_local_files),
Packit f574b8
#endif
Packit f574b8
     PARSE_STR(RC_LYNX_HOST_NAME,       LYHostName),
Packit f574b8
     PARSE_FUN(RC_LYNX_SIG_FILE,        lynx_sig_file_fun),
Packit f574b8
#ifdef LYNXCGI_LINKS
Packit f574b8
#ifndef VMS
Packit f574b8
     PARSE_STR(RC_LYNXCGI_DOCUMENT_ROOT, LYCgiDocumentRoot),
Packit f574b8
#endif
Packit f574b8
     PARSE_FUN(RC_LYNXCGI_ENVIRONMENT,  lynxcgi_environment_fun),
Packit f574b8
#endif
Packit f574b8
#if USE_VMS_MAILER
Packit f574b8
     PARSE_STR(RC_MAIL_ADRS,            mail_adrs),
Packit f574b8
#endif
Packit f574b8
     PARSE_SET(RC_MAIL_SYSTEM_ERROR_LOGGING, error_logging),
Packit f574b8
     PARSE_SET(RC_MAKE_LINKS_FOR_ALL_IMAGES, clickable_images),
Packit f574b8
     PARSE_SET(RC_MAKE_PSEUDO_ALTS_FOR_INLINES, pseudo_inline_alts),
Packit f574b8
     PARSE_INT(RC_MAX_COOKIES_BUFFER,   max_cookies_buffer),
Packit f574b8
     PARSE_INT(RC_MAX_COOKIES_DOMAIN,   max_cookies_domain),
Packit f574b8
     PARSE_INT(RC_MAX_COOKIES_GLOBAL,   max_cookies_global),
Packit f574b8
     PARSE_INT(RC_MAX_URI_SIZE,         max_uri_size),
Packit f574b8
     PARSE_TIM(RC_MESSAGESECS,          MessageSecs),
Packit f574b8
#if defined(HAVE_LIBINTL_H) || defined(HAVE_LIBGETTEXT_H)
Packit f574b8
     PARSE_FUN(RC_MESSAGE_LANGUAGE,     message_language_fun),
Packit f574b8
#endif
Packit f574b8
     PARSE_SET(RC_MINIMAL_COMMENTS,     minimal_comments),
Packit f574b8
     PARSE_PRG(RC_MKDIR_PATH,           ppMKDIR),
Packit f574b8
     PARSE_ENU(RC_MULTI_BOOKMARK_SUPPORT, LYMultiBookmarks, tbl_multi_bookmarks),
Packit f574b8
     PARSE_PRG(RC_MV_PATH,              ppMV),
Packit f574b8
     PARSE_SET(RC_NCR_IN_BOOKMARKS,     UCSaveBookmarksInUnicode),
Packit f574b8
#ifdef EXP_NESTED_TABLES
Packit f574b8
     PARSE_SET(RC_NESTED_TABLES,        nested_tables),
Packit f574b8
#endif
Packit f574b8
#ifndef DISABLE_NEWS
Packit f574b8
     PARSE_FUN(RC_NEWS_CHUNK_SIZE,      news_chunk_size_fun),
Packit f574b8
     PARSE_FUN(RC_NEWS_MAX_CHUNK,       news_max_chunk_fun),
Packit f574b8
     PARSE_FUN(RC_NEWS_POSTING,         news_posting_fun),
Packit f574b8
     PARSE_Env(RC_NEWS_PROXY,           0),
Packit f574b8
     PARSE_Env(RC_NEWSPOST_PROXY,       0),
Packit f574b8
     PARSE_Env(RC_NEWSREPLY_PROXY,      0),
Packit f574b8
     PARSE_Env(RC_NNTP_PROXY,           0),
Packit f574b8
     PARSE_ENV(RC_NNTPSERVER,           0), /* actually NNTPSERVER */
Packit f574b8
#endif
Packit f574b8
     PARSE_SET(RC_NUMBER_FIELDS_ON_LEFT,number_fields_on_left),
Packit f574b8
     PARSE_SET(RC_NUMBER_LINKS_ON_LEFT, number_links_on_left),
Packit f574b8
     PARSE_SET(RC_NO_DOT_FILES,         no_dotfiles),
Packit f574b8
     PARSE_SET(RC_NO_FILE_REFERER,      no_filereferer),
Packit f574b8
#ifndef VMS
Packit f574b8
     PARSE_SET(RC_NO_FORCED_CORE_DUMP,  LYNoCore),
Packit f574b8
#endif
Packit f574b8
     PARSE_SET(RC_NO_FROM_HEADER,       LYNoFromHeader),
Packit f574b8
     PARSE_SET(RC_NO_ISMAP_IF_USEMAP,   LYNoISMAPifUSEMAP),
Packit f574b8
     PARSE_SET(RC_NO_MARGINS,           no_margins),
Packit f574b8
     PARSE_SET(RC_NO_PAUSE,             no_pause),
Packit f574b8
     PARSE_Env(RC_NO_PROXY,             0),
Packit f574b8
     PARSE_SET(RC_NO_REFERER_HEADER,    LYNoRefererHeader),
Packit f574b8
     PARSE_SET(RC_NO_TABLE_CENTER,      no_table_center),
Packit f574b8
     PARSE_SET(RC_NO_TITLE,             no_title),
Packit f574b8
     PARSE_FUN(RC_NONRESTARTING_SIGWINCH, nonrest_sigwinch_fun),
Packit f574b8
     PARSE_FUN(RC_OUTGOING_MAIL_CHARSET, outgoing_mail_charset_fun),
Packit f574b8
#ifdef DISP_PARTIAL
Packit f574b8
     PARSE_SET(RC_PARTIAL,              display_partial_flag),
Packit f574b8
     PARSE_INT(RC_PARTIAL_THRES,        partial_threshold),
Packit f574b8
#endif
Packit f574b8
#ifdef USE_PERSISTENT_COOKIES
Packit f574b8
     PARSE_SET(RC_PERSISTENT_COOKIES,   persistent_cookies),
Packit f574b8
#endif /* USE_PERSISTENT_COOKIES */
Packit f574b8
     PARSE_STR(RC_PERSONAL_EXTENSION_MAP, personal_extension_map),
Packit f574b8
     PARSE_STR(RC_PERSONAL_MAILCAP,     personal_type_map),
Packit f574b8
     PARSE_LST(RC_POSITIONABLE_EDITOR,  positionable_editor),
Packit f574b8
     PARSE_STR(RC_PREFERRED_CHARSET,    pref_charset),
Packit f574b8
     PARSE_ENU(RC_PREFERRED_CONTENT_TYPE, LYContentType, tbl_preferred_content),
Packit f574b8
     PARSE_ENU(RC_PREFERRED_ENCODING,   LYAcceptEncoding, tbl_preferred_encoding),
Packit f574b8
     PARSE_STR(RC_PREFERRED_LANGUAGE,   language),
Packit f574b8
     PARSE_ENU(RC_PREFERRED_MEDIA_TYPES, LYAcceptMedia, tbl_preferred_media),
Packit f574b8
     PARSE_SET(RC_PREPEND_BASE_TO_SOURCE, LYPrependBaseToSource),
Packit f574b8
     PARSE_SET(RC_PREPEND_CHARSET_TO_SOURCE, LYPrependCharsetToSource),
Packit f574b8
#ifdef USE_PRETTYSRC
Packit f574b8
     PARSE_SET(RC_PRETTYSRC,            LYpsrc),
Packit f574b8
     PARSE_FUN(RC_PRETTYSRC_SPEC,       psrcspec_fun),
Packit f574b8
     PARSE_SET(RC_PRETTYSRC_VIEW_NO_ANCHOR_NUM, psrcview_no_anchor_numbering),
Packit f574b8
#endif
Packit f574b8
     PARSE_ADD(RC_PRINTER,              printers),
Packit f574b8
     PARSE_SET(RC_QUIT_DEFAULT_YES,     LYQuitDefaultYes),
Packit f574b8
     PARSE_INT(RC_READ_TIMEOUT,         reading_timeout),
Packit f574b8
     PARSE_FUN(RC_REFERER_WITH_QUERY,   referer_with_query_fun),
Packit f574b8
#ifdef USE_CMD_LOGGING
Packit f574b8
     PARSE_TIM(RC_REPLAYSECS,           ReplaySecs),
Packit f574b8
#endif
Packit f574b8
     PARSE_SET(RC_REUSE_TEMPFILES,      LYReuseTempfiles),
Packit f574b8
     PARSE_PRG(RC_RLOGIN_PATH,          ppRLOGIN),
Packit f574b8
     PARSE_PRG(RC_RMDIR_PATH,           ppRMDIR),
Packit f574b8
     PARSE_PRG(RC_RM_PATH,              ppRM),
Packit f574b8
#ifndef NO_RULES
Packit f574b8
     PARSE_FUN(RC_RULE,                 HTSetConfiguration),
Packit f574b8
     PARSE_FUN(RC_RULESFILE,            cern_rulesfile_fun),
Packit f574b8
#endif /* NO_RULES */
Packit f574b8
     PARSE_STR(RC_SAVE_SPACE,           lynx_save_space),
Packit f574b8
     PARSE_SET(RC_SCAN_FOR_BURIED_NEWS_REFS, scan_for_buried_news_references),
Packit f574b8
#if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401
Packit f574b8
     PARSE_FUN(RC_SCREEN_SIZE,          screen_size_fun),
Packit f574b8
#endif
Packit f574b8
#ifdef USE_SCROLLBAR
Packit f574b8
     PARSE_SET(RC_SCROLLBAR,            LYShowScrollbar),
Packit f574b8
     PARSE_SET(RC_SCROLLBAR_ARROW,      LYsb_arrow),
Packit f574b8
#endif
Packit f574b8
     PARSE_SET(RC_SEEK_FRAG_AREA_IN_CUR, LYSeekFragAREAinCur),
Packit f574b8
     PARSE_SET(RC_SEEK_FRAG_MAP_IN_CUR, LYSeekFragMAPinCur),
Packit f574b8
#ifdef USE_SESSIONS
Packit f574b8
     PARSE_SET(RC_AUTO_SESSION,         LYAutoSession),
Packit f574b8
     PARSE_STR(RC_SESSION_FILE,         LYSessionFile),
Packit f574b8
     PARSE_FUN(RC_SESSION_LIMIT,        session_limit_fun),
Packit f574b8
#endif
Packit f574b8
     PARSE_SET(RC_SET_COOKIES,          LYSetCookies),
Packit f574b8
     PARSE_SET(RC_SHORT_URL,            long_url_ok),
Packit f574b8
     PARSE_SET(RC_SHOW_CURSOR,          LYShowCursor),
Packit f574b8
     PARSE_STR(RC_SHOW_KB_NAME,         LYTransferName),
Packit f574b8
     PARSE_ENU(RC_SHOW_KB_RATE,         LYTransferRate, tbl_transfer_rate),
Packit f574b8
     PARSE_Env(RC_SNEWS_PROXY,          0),
Packit f574b8
     PARSE_Env(RC_SNEWSPOST_PROXY,      0),
Packit f574b8
     PARSE_Env(RC_SNEWSREPLY_PROXY,     0),
Packit f574b8
     PARSE_SET(RC_SOFT_DQUOTES,         soft_dquotes),
Packit f574b8
#ifdef USE_SOURCE_CACHE
Packit f574b8
     PARSE_ENU(RC_SOURCE_CACHE,         LYCacheSource, tbl_source_cache),
Packit f574b8
     PARSE_ENU(RC_SOURCE_CACHE_FOR_ABORTED, LYCacheSourceForAborted, tbl_abort_source_cache),
Packit f574b8
#endif
Packit f574b8
     PARSE_STR(RC_SSL_CERT_FILE,        SSL_cert_file),
Packit f574b8
     PARSE_STR(RC_SSL_CLIENT_CERT_FILE, SSL_client_cert_file),
Packit f574b8
     PARSE_STR(RC_SSL_CLIENT_KEY_FILE,  SSL_client_key_file),
Packit f574b8
     PARSE_FUN(RC_STARTFILE,            startfile_fun),
Packit f574b8
     PARSE_FUN(RC_STATUS_BUFFER_SIZE,   status_buffer_size_fun),
Packit f574b8
     PARSE_SET(RC_STRIP_DOTDOT_URLS,    LYStripDotDotURLs),
Packit f574b8
     PARSE_SET(RC_SUBSTITUTE_UNDERSCORES, use_underscore),
Packit f574b8
     PARSE_FUN(RC_SUFFIX,               suffix_fun),
Packit f574b8
     PARSE_FUN(RC_SUFFIX_ORDER,         suffix_order_fun),
Packit f574b8
#ifdef SYSLOG_REQUESTED_URLS
Packit f574b8
     PARSE_SET(RC_SYSLOG_REQUESTED_URLS, syslog_requested_urls),
Packit f574b8
     PARSE_STR(RC_SYSLOG_TEXT,          syslog_txt),
Packit f574b8
#endif
Packit f574b8
     PARSE_FUN(RC_SYSTEM_EDITOR,        system_editor_fun),
Packit f574b8
     PARSE_STR(RC_SYSTEM_MAIL,          system_mail),
Packit f574b8
     PARSE_STR(RC_SYSTEM_MAIL_FLAGS,    system_mail_flags),
Packit f574b8
     PARSE_FUN(RC_TAGSOUP,              get_tagsoup),
Packit f574b8
     PARSE_PRG(RC_TAR_PATH,             ppTAR),
Packit f574b8
     PARSE_PRG(RC_TELNET_PATH,          ppTELNET),
Packit f574b8
#ifdef TEXTFIELDS_MAY_NEED_ACTIVATION
Packit f574b8
     PARSE_SET(RC_TEXTFIELDS_NEED_ACTIVATION, textfields_activation_option),
Packit f574b8
#endif
Packit f574b8
     PARSE_PRG(RC_TN3270_PATH,          ppTN3270),
Packit f574b8
#if defined(_WINDOWS)
Packit f574b8
     PARSE_INT(RC_TIMEOUT,              lynx_timeout),
Packit f574b8
#endif
Packit f574b8
     PARSE_PRG(RC_TOUCH_PATH,           ppTOUCH),
Packit f574b8
     PARSE_SET(RC_TRACK_INTERNAL_LINKS, track_internal_links),
Packit f574b8
     PARSE_SET(RC_TRIM_BLANK_LINES,     LYtrimBlankLines),
Packit f574b8
     PARSE_SET(RC_TRIM_INPUT_FIELDS,    LYtrimInputFields),
Packit f574b8
#ifdef EXEC_LINKS
Packit f574b8
     PARSE_DEF(RC_TRUSTED_EXEC,         EXEC_PATH),
Packit f574b8
#endif
Packit f574b8
#ifdef LYNXCGI_LINKS
Packit f574b8
     PARSE_DEF(RC_TRUSTED_LYNXCGI,      CGI_PATH),
Packit f574b8
#endif
Packit f574b8
     PARSE_PRG(RC_UNCOMPRESS_PATH,      ppUNCOMPRESS),
Packit f574b8
     PARSE_SET(RC_UNDERLINE_LINKS,      LYUnderlineLinks),
Packit f574b8
     PARSE_SET(RC_UNIQUE_URLS,          unique_urls),
Packit f574b8
     PARSE_PRG(RC_UNZIP_PATH,           ppUNZIP),
Packit f574b8
#ifdef DIRED_SUPPORT
Packit f574b8
     PARSE_ADD(RC_UPLOADER,             uploaders),
Packit f574b8
#endif
Packit f574b8
     PARSE_STR(RC_URL_DOMAIN_PREFIXES,  URLDomainPrefixes),
Packit f574b8
     PARSE_STR(RC_URL_DOMAIN_SUFFIXES,  URLDomainSuffixes),
Packit f574b8
#ifdef VMS
Packit f574b8
     PARSE_SET(RC_USE_FIXED_RECORDS,    UseFixedRecords),
Packit f574b8
#endif
Packit f574b8
#if defined(USE_MOUSE)
Packit f574b8
     PARSE_SET(RC_USE_MOUSE,            LYUseMouse),
Packit f574b8
#endif
Packit f574b8
     PARSE_SET(RC_USE_SELECT_POPUPS,    LYSelectPopups),
Packit f574b8
     PARSE_PRG(RC_UUDECODE_PATH,        ppUUDECODE),
Packit f574b8
     PARSE_SET(RC_VERBOSE_IMAGES,       verbose_img),
Packit f574b8
     PARSE_SET(RC_VI_KEYS_ALWAYS_ON,    vi_keys),
Packit f574b8
     PARSE_FUN(RC_VIEWER,               viewer_fun),
Packit f574b8
     PARSE_Env(RC_WAIS_PROXY,           0),
Packit f574b8
     PARSE_SET(RC_WAIT_VIEWER_TERMINATION, wait_viewer_termination),
Packit f574b8
     PARSE_SET(RC_WITH_BACKSPACES,      with_backspaces),
Packit f574b8
     PARSE_STR(RC_XLOADIMAGE_COMMAND,   XLoadImageCommand),
Packit f574b8
     PARSE_SET(RC_XHTML_PARSING,        LYxhtml_parsing),
Packit f574b8
     PARSE_PRG(RC_ZCAT_PATH,            ppZCAT),
Packit f574b8
     PARSE_PRG(RC_ZIP_PATH,             ppZIP),
Packit f574b8
Packit f574b8
     PARSE_NIL
Packit f574b8
};
Packit f574b8
/* *INDENT-ON* */
Packit f574b8
Packit f574b8
static char *lynxcfginfo_url = NULL;	/* static */
Packit f574b8
Packit f574b8
#if defined(HAVE_CONFIG_H) && !defined(NO_CONFIG_INFO)
Packit f574b8
static char *configinfo_url = NULL;	/* static */
Packit f574b8
#endif
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Free memory allocated in 'read_cfg()'
Packit f574b8
 */
Packit f574b8
void free_lynx_cfg(void)
Packit f574b8
{
Packit f574b8
    Config_Type *tbl;
Packit f574b8
Packit f574b8
    for (tbl = Config_Table; tbl->name != 0; tbl++) {
Packit f574b8
	ParseUnionPtr q = ParseUnionOf(tbl);
Packit f574b8
Packit f574b8
	switch (tbl->type) {
Packit f574b8
	case CONF_ENV:
Packit f574b8
	    if (q->str_value != 0) {
Packit f574b8
		char *name = *(q->str_value);
Packit f574b8
		char *eqls = StrChr(name, '=');
Packit f574b8
Packit f574b8
		if (eqls != 0) {
Packit f574b8
		    *eqls = 0;
Packit f574b8
#ifdef VMS
Packit f574b8
		    Define_VMSLogical(name, NULL);
Packit f574b8
#else
Packit f574b8
# ifdef HAVE_PUTENV
Packit f574b8
		    if (putenv(name))
Packit f574b8
			break;
Packit f574b8
# else
Packit f574b8
		    unsetenv(name);
Packit f574b8
# endif
Packit f574b8
#endif
Packit f574b8
		}
Packit f574b8
		FREE(*(q->str_value));
Packit f574b8
		FREE(q->str_value);
Packit f574b8
		/* is it enough for reload_read_cfg() to clean up
Packit f574b8
		 * the result of putenv()?  No for certain platforms.
Packit f574b8
		 */
Packit f574b8
	    }
Packit f574b8
	    break;
Packit f574b8
	default:
Packit f574b8
	    break;
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
    free_all_item_lists();
Packit f574b8
#ifdef DIRED_SUPPORT
Packit f574b8
    reset_dired_menu();		/* frees and resets dired menu items - kw */
Packit f574b8
#endif
Packit f574b8
    FREE(lynxcfginfo_url);
Packit f574b8
#if defined(HAVE_CONFIG_H) && !defined(NO_CONFIG_INFO)
Packit f574b8
    FREE(configinfo_url);
Packit f574b8
#endif
Packit f574b8
}
Packit f574b8
Packit f574b8
static Config_Type *lookup_config(const char *name)
Packit f574b8
{
Packit f574b8
    Config_Type *tbl = Config_Table;
Packit f574b8
    char ch = (char) TOUPPER(*name);
Packit f574b8
Packit f574b8
    while (tbl->name != 0) {
Packit f574b8
	char ch1 = tbl->name[0];
Packit f574b8
Packit f574b8
	if ((ch == TOUPPER(ch1))
Packit f574b8
	    && (0 == strcasecomp(name, tbl->name)))
Packit f574b8
	    break;
Packit f574b8
Packit f574b8
	tbl++;
Packit f574b8
    }
Packit f574b8
    return tbl;
Packit f574b8
}
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * If the given value is an absolute path (by syntax), or we can read it, use
Packit f574b8
 * the value as given.  Otherwise, assume it must be in the same place we read
Packit f574b8
 * the parent configuration file from.
Packit f574b8
 *
Packit f574b8
 * Note:  only read files from the current directory if there's no parent
Packit f574b8
 * filename, otherwise it leads to user surprise.
Packit f574b8
 */
Packit f574b8
static char *actual_filename(const char *cfg_filename,
Packit f574b8
			     const char *parent_filename,
Packit f574b8
			     const char *dft_filename)
Packit f574b8
{
Packit f574b8
    char *my_filename = NULL;
Packit f574b8
Packit f574b8
    if (!LYisAbsPath(cfg_filename)
Packit f574b8
	&& !(parent_filename == 0 && LYCanReadFile(cfg_filename))) {
Packit f574b8
	if (LYIsTilde(cfg_filename[0]) && LYIsPathSep(cfg_filename[1])) {
Packit f574b8
	    HTSprintf0(&my_filename, "%s%s", Home_Dir(), cfg_filename + 1);
Packit f574b8
	} else {
Packit f574b8
	    if (parent_filename != 0) {
Packit f574b8
		StrAllocCopy(my_filename, parent_filename);
Packit f574b8
		*LYPathLeaf(my_filename) = '\0';
Packit f574b8
		StrAllocCat(my_filename, cfg_filename);
Packit f574b8
	    }
Packit f574b8
	    if (my_filename == 0 || !LYCanReadFile(my_filename)) {
Packit f574b8
		StrAllocCopy(my_filename, dft_filename);
Packit f574b8
		*LYPathLeaf(my_filename) = '\0';
Packit f574b8
		StrAllocCat(my_filename, cfg_filename);
Packit f574b8
		if (!LYCanReadFile(my_filename)) {
Packit f574b8
		    StrAllocCopy(my_filename,
Packit f574b8
				 LYFindConfigFile(cfg_filename,
Packit f574b8
						  dft_filename));
Packit f574b8
		}
Packit f574b8
	    }
Packit f574b8
	}
Packit f574b8
    } else {
Packit f574b8
	StrAllocCopy(my_filename, cfg_filename);
Packit f574b8
    }
Packit f574b8
    return my_filename;
Packit f574b8
}
Packit f574b8
Packit f574b8
FILE *LYOpenCFG(const char *cfg_filename,
Packit f574b8
		const char *parent_filename,
Packit f574b8
		const char *dft_filename)
Packit f574b8
{
Packit f574b8
    char *my_file = actual_filename(cfg_filename, parent_filename, dft_filename);
Packit f574b8
    FILE *result;
Packit f574b8
Packit f574b8
    CTRACE((tfp, "opening config file %s\n", my_file));
Packit f574b8
    result = fopen(my_file, TXT_R);
Packit f574b8
    FREE(my_file);
Packit f574b8
Packit f574b8
    return result;
Packit f574b8
}
Packit f574b8
Packit f574b8
#define NOPTS_ ( TABLESIZE(Config_Table) - 1 )
Packit f574b8
typedef BOOL (optidx_set_t)[NOPTS_];
Packit f574b8
Packit f574b8
 /* if element is FALSE, then it's allowed in the current file */
Packit f574b8
Packit f574b8
#define optidx_set_AND(r,a,b) \
Packit f574b8
    {\
Packit f574b8
	unsigned i1;\
Packit f574b8
	for (i1 = 0; i1 < NOPTS_; ++i1) \
Packit f574b8
	    (r)[i1]= (BOOLEAN) ((a)[i1] || (b)[i1]); \
Packit f574b8
    }
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * For simple (boolean, string, integer, time) values, set the corresponding
Packit f574b8
 * configuration variable.
Packit f574b8
 */
Packit f574b8
BOOL LYSetConfigValue(const char *name,
Packit f574b8
		      const char *param)
Packit f574b8
{
Packit f574b8
    BOOL changed = TRUE;
Packit f574b8
    char *value = NULL;
Packit f574b8
    Config_Type *tbl = lookup_config(name);
Packit f574b8
    ParseUnionPtr q = ParseUnionOf(tbl);
Packit f574b8
    char *temp_name = 0;
Packit f574b8
    char *temp_value = 0;
Packit f574b8
Packit f574b8
    if (param == NULL)
Packit f574b8
	param = "";
Packit f574b8
    StrAllocCopy(value, param);
Packit f574b8
    switch (tbl->type) {
Packit f574b8
    case CONF_BOOL:
Packit f574b8
	if (q->set_value != 0)
Packit f574b8
	    *(q->set_value) = is_true(value);
Packit f574b8
	break;
Packit f574b8
Packit f574b8
    case CONF_FUN:
Packit f574b8
	if (q->fun_value != 0)
Packit f574b8
	    (*(q->fun_value)) (value);
Packit f574b8
	break;
Packit f574b8
Packit f574b8
    case CONF_TIME:
Packit f574b8
	if (q->int_value != 0) {
Packit f574b8
	    float ival;
Packit f574b8
Packit f574b8
	    if (1 == LYscanFloat(value, &ival)) {
Packit f574b8
		*(q->int_value) = (int) SECS2Secs(ival);
Packit f574b8
	    }
Packit f574b8
	}
Packit f574b8
	break;
Packit f574b8
Packit f574b8
    case CONF_ENUM:
Packit f574b8
	if (tbl->table != 0)
Packit f574b8
	    LYgetEnum(tbl->table, value, q->int_value);
Packit f574b8
	break;
Packit f574b8
Packit f574b8
    case CONF_INT:
Packit f574b8
	if (q->int_value != 0) {
Packit f574b8
	    int ival;
Packit f574b8
Packit f574b8
	    if (1 == sscanf(value, "%d", &ival))
Packit f574b8
		*(q->int_value) = ival;
Packit f574b8
	}
Packit f574b8
	break;
Packit f574b8
Packit f574b8
    case CONF_STR:
Packit f574b8
	if (q->str_value != 0)
Packit f574b8
	    StrAllocCopy(*(q->str_value), value);
Packit f574b8
	break;
Packit f574b8
Packit f574b8
    case CONF_ENV:
Packit f574b8
    case CONF_ENV2:
Packit f574b8
Packit f574b8
	if (StrAllocCopy(temp_name, name)) {
Packit f574b8
	    if (tbl->type == CONF_ENV)
Packit f574b8
		LYLowerCase(temp_name);
Packit f574b8
	    else
Packit f574b8
		LYUpperCase(temp_name);
Packit f574b8
Packit f574b8
	    if (LYGetEnv(temp_name) == 0) {
Packit f574b8
#ifdef VMS
Packit f574b8
		Define_VMSLogical(temp_name, value);
Packit f574b8
#else
Packit f574b8
		if (q->str_value == 0) {
Packit f574b8
		    q->str_value = typecalloc(char *);
Packit f574b8
Packit f574b8
		    if (q->str_value == 0)
Packit f574b8
			outofmem(__FILE__, "LYSetConfigValue");
Packit f574b8
		}
Packit f574b8
Packit f574b8
		HTSprintf0(q->str_value, "%s=%s", temp_name, value);
Packit f574b8
		putenv(*(q->str_value));
Packit f574b8
#endif
Packit f574b8
	    }
Packit f574b8
	    FREE(temp_name);
Packit f574b8
	}
Packit f574b8
	break;
Packit f574b8
    case CONF_ADD_ITEM:
Packit f574b8
	if (q->add_value != 0)
Packit f574b8
	    add_item_to_list(value,
Packit f574b8
			     q->add_value,
Packit f574b8
			     (q->add_value == &printers),
Packit f574b8
			     FALSE);
Packit f574b8
	break;
Packit f574b8
Packit f574b8
    case CONF_ADD_STRING:
Packit f574b8
	if (*(q->lst_value) == NULL) {
Packit f574b8
	    *(q->lst_value) = HTList_new();
Packit f574b8
	}
Packit f574b8
	temp_value = NULL;
Packit f574b8
	StrAllocCopy(temp_value, value);
Packit f574b8
	HTList_appendObject(*(q->lst_value), temp_value);
Packit f574b8
	temp_value = NULL;
Packit f574b8
	break;
Packit f574b8
Packit f574b8
#if defined(EXEC_LINKS) || defined(LYNXCGI_LINKS)
Packit f574b8
    case CONF_ADD_TRUSTED:
Packit f574b8
	add_trusted(value, (int) q->def_value);
Packit f574b8
	break;
Packit f574b8
#endif
Packit f574b8
Packit f574b8
    case CONF_PRG:
Packit f574b8
	if (isEmpty(value)) {
Packit f574b8
	    HTSetProgramPath((ProgramPaths) (q->def_value), NULL);
Packit f574b8
	} else if (StrAllocCopy(temp_value, value)) {
Packit f574b8
	    HTSetProgramPath((ProgramPaths) (q->def_value), temp_value);
Packit f574b8
	}
Packit f574b8
	break;
Packit f574b8
Packit f574b8
    default:
Packit f574b8
	changed = FALSE;
Packit f574b8
	break;
Packit f574b8
    }
Packit f574b8
    FREE(value);
Packit f574b8
Packit f574b8
    return changed;
Packit f574b8
}
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Process the configuration file (lynx.cfg).
Packit f574b8
 *
Packit f574b8
 * 'allowed' is a pointer to HTList of allowed options.  Since the included
Packit f574b8
 * file can also include other files with a list of acceptable options, these
Packit f574b8
 * lists are ANDed.
Packit f574b8
 */
Packit f574b8
static void do_read_cfg(const char *cfg_filename,
Packit f574b8
			const char *parent_filename,
Packit f574b8
			int nesting_level,
Packit f574b8
			FILE *fp0,
Packit f574b8
			optidx_set_t *allowed)
Packit f574b8
{
Packit f574b8
    FILE *fp;
Packit f574b8
    char *buffer = 0;
Packit f574b8
Packit f574b8
    CTRACE((tfp, "Loading cfg file '%s'.\n", cfg_filename));
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Don't get hung up by an include file loop.  Arbitrary max depth
Packit f574b8
     * of 10.  - BL
Packit f574b8
     */
Packit f574b8
    if (nesting_level > 10) {
Packit f574b8
	fprintf(stderr,
Packit f574b8
		gettext("More than %d nested lynx.cfg includes -- perhaps there is a loop?!?\n"),
Packit f574b8
		nesting_level - 1);
Packit f574b8
	fprintf(stderr, gettext("Last attempted include was '%s',\n"), cfg_filename);
Packit f574b8
	fprintf(stderr, gettext("included from '%s'.\n"), parent_filename);
Packit f574b8
	exit_immediately(EXIT_FAILURE);
Packit f574b8
    }
Packit f574b8
    /*
Packit f574b8
     * Locate and open the file.
Packit f574b8
     */
Packit f574b8
    if (!cfg_filename || strlen(cfg_filename) == 0) {
Packit f574b8
	CTRACE((tfp, "No filename following -cfg switch!\n"));
Packit f574b8
	return;
Packit f574b8
    }
Packit f574b8
    if ((fp = LYOpenCFG(cfg_filename, parent_filename, LYNX_CFG_FILE)) == 0) {
Packit f574b8
	CTRACE((tfp, "lynx.cfg file not found as '%s'\n", cfg_filename));
Packit f574b8
	return;
Packit f574b8
    }
Packit f574b8
    have_read_cfg = TRUE;
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Process each line in the file.
Packit f574b8
     */
Packit f574b8
    if (show_cfg) {
Packit f574b8
	time_t t;
Packit f574b8
Packit f574b8
	time(&t);
Packit f574b8
	printf("### %s %s, at %s", LYNX_NAME, LYNX_VERSION, ctime(&t);;
Packit f574b8
    }
Packit f574b8
    while (LYSafeGets(&buffer, fp) != 0) {
Packit f574b8
	char *name, *value;
Packit f574b8
	char *cp;
Packit f574b8
	Config_Type *tbl;
Packit f574b8
Packit f574b8
	/* Most lines in the config file are comment lines.  Weed them out
Packit f574b8
	 * now.  Also, leading whitespace is ok, so trim it.
Packit f574b8
	 */
Packit f574b8
	name = LYSkipBlanks(buffer);
Packit f574b8
Packit f574b8
	if (ispunct(UCH(*name)))
Packit f574b8
	    continue;
Packit f574b8
Packit f574b8
	LYTrimTrailing(name);
Packit f574b8
Packit f574b8
	if (*name == 0)
Packit f574b8
	    continue;
Packit f574b8
Packit f574b8
	/* Significant lines are of the form KEYWORD:WHATEVER */
Packit f574b8
	if ((value = StrChr(name, ':')) == 0) {
Packit f574b8
	    /* fprintf (stderr, "Bad line-- no :\n"); */
Packit f574b8
	    CTRACE((tfp, "LYReadCFG: missing ':' %s\n", name));
Packit f574b8
	    continue;
Packit f574b8
	}
Packit f574b8
Packit f574b8
	/* skip past colon, but replace ':' with 0 to make name meaningful */
Packit f574b8
	*value++ = 0;
Packit f574b8
Packit f574b8
	/*
Packit f574b8
	 * Trim off any trailing comments.
Packit f574b8
	 *
Packit f574b8
	 * (Apparently, the original code considers a trailing comment valid
Packit f574b8
	 * only if preceded by a space character but is not followed by a
Packit f574b8
	 * colon.  -- JED)
Packit f574b8
	 */
Packit f574b8
	if ((cp = strrchr(value, ':')) == 0)
Packit f574b8
	    cp = value;
Packit f574b8
	if ((cp = StrChr(cp, '#')) != 0) {
Packit f574b8
	    cp--;
Packit f574b8
	    if (isspace(UCH(*cp)))
Packit f574b8
		*cp = 0;
Packit f574b8
	}
Packit f574b8
Packit f574b8
	CTRACE2(TRACE_CFG, (tfp, "LYReadCFG %s:%s\n", name, value));
Packit f574b8
	tbl = lookup_config(name);
Packit f574b8
	if (tbl->name == 0) {
Packit f574b8
	    /* lynx ignores unknown keywords */
Packit f574b8
	    CTRACE((tfp, "LYReadCFG: ignored %s:%s\n", name, value));
Packit f574b8
	    continue;
Packit f574b8
	}
Packit f574b8
	if (show_cfg)
Packit f574b8
	    printf("%s:%s\n", name, value);
Packit f574b8
Packit f574b8
	if (allowed && (*allowed)[tbl - Config_Table]) {
Packit f574b8
	    if (fp0 == NULL)
Packit f574b8
		fprintf(stderr, "%s is not allowed in the %s\n",
Packit f574b8
			name, cfg_filename);
Packit f574b8
	    /*FIXME: we can do something wiser if we are generating
Packit f574b8
	       the html representation of lynx.cfg - say include this line
Packit f574b8
	       in bold, or something... */
Packit f574b8
Packit f574b8
	    continue;
Packit f574b8
	}
Packit f574b8
Packit f574b8
	(void) ParseUnionOf(tbl);
Packit f574b8
	switch ((fp0 != 0 && tbl->type != CONF_INCLUDE)
Packit f574b8
		? CONF_NIL
Packit f574b8
		: tbl->type) {
Packit f574b8
	case CONF_BOOL:
Packit f574b8
	case CONF_FUN:
Packit f574b8
	case CONF_TIME:
Packit f574b8
	case CONF_ENUM:
Packit f574b8
	case CONF_INT:
Packit f574b8
	case CONF_STR:
Packit f574b8
	case CONF_ENV:
Packit f574b8
	case CONF_ENV2:
Packit f574b8
	case CONF_PRG:
Packit f574b8
	case CONF_ADD_ITEM:
Packit f574b8
	case CONF_ADD_STRING:
Packit f574b8
	case CONF_ADD_TRUSTED:
Packit f574b8
	    LYSetConfigValue(name, value);
Packit f574b8
	    break;
Packit f574b8
Packit f574b8
	case CONF_INCLUDE:{
Packit f574b8
		/* include another file */
Packit f574b8
		optidx_set_t cur_set, anded_set;
Packit f574b8
		optidx_set_t *resultant_set = NULL;
Packit f574b8
		char *p1, *p2, savechar;
Packit f574b8
		BOOL any_optname_found = FALSE;
Packit f574b8
Packit f574b8
		char *url = NULL;
Packit f574b8
		char *cp1 = NULL;
Packit f574b8
		const char *sep = NULL;
Packit f574b8
Packit f574b8
		if ((p1 = strstr(value, sep = " for ")) != 0
Packit f574b8
#if defined(UNIX) && !defined(USE_DOS_DRIVES)
Packit f574b8
		    || (p1 = strstr(value, sep = ":")) != 0
Packit f574b8
#endif
Packit f574b8
		    ) {
Packit f574b8
		    *p1 = '\0';
Packit f574b8
		    p1 += strlen(sep);
Packit f574b8
		}
Packit f574b8
#ifndef NO_CONFIG_INFO
Packit f574b8
		if (fp0 != 0 && !no_lynxcfg_xinfo) {
Packit f574b8
		    char *my_file = actual_filename(value, cfg_filename, LYNX_CFG_FILE);
Packit f574b8
Packit f574b8
		    LYLocalFileToURL(&url, my_file);
Packit f574b8
		    FREE(my_file);
Packit f574b8
		    StrAllocCopy(cp1, value);
Packit f574b8
		    if (StrChr(value, '&') || StrChr(value, '<')) {
Packit f574b8
			LYEntify(&cp1, TRUE);
Packit f574b8
		    }
Packit f574b8
Packit f574b8
		    fprintf(fp0, "%s:%s\n\n", name, url, cp1);
Packit f574b8
		    fprintf(fp0, "    #<begin  %s>\n", cp1);
Packit f574b8
		}
Packit f574b8
#endif
Packit f574b8
Packit f574b8
		if (p1) {
Packit f574b8
		    while (*(p1 = LYSkipBlanks(p1)) != 0) {
Packit f574b8
			Config_Type *tbl2;
Packit f574b8
Packit f574b8
			p2 = LYSkipNonBlanks(p1);
Packit f574b8
			savechar = *p2;
Packit f574b8
			*p2 = 0;
Packit f574b8
Packit f574b8
			tbl2 = lookup_config(p1);
Packit f574b8
			if (tbl2->name == 0) {
Packit f574b8
			    if (fp0 == NULL)
Packit f574b8
				fprintf(stderr,
Packit f574b8
					"unknown option name %s in %s\n",
Packit f574b8
					p1, cfg_filename);
Packit f574b8
			} else {
Packit f574b8
			    unsigned i;
Packit f574b8
Packit f574b8
			    if (!any_optname_found) {
Packit f574b8
				any_optname_found = TRUE;
Packit f574b8
				for (i = 0; i < NOPTS_; ++i)
Packit f574b8
				    cur_set[i] = TRUE;
Packit f574b8
			    }
Packit f574b8
			    cur_set[tbl2 - Config_Table] = FALSE;
Packit f574b8
			}
Packit f574b8
			if (savechar && p2[1])
Packit f574b8
			    p1 = p2 + 1;
Packit f574b8
			else
Packit f574b8
			    break;
Packit f574b8
		    }
Packit f574b8
		}
Packit f574b8
		if (!allowed) {
Packit f574b8
		    if (!any_optname_found)
Packit f574b8
			resultant_set = NULL;
Packit f574b8
		    else
Packit f574b8
			resultant_set = &cur_set;
Packit f574b8
		} else {
Packit f574b8
		    if (!any_optname_found)
Packit f574b8
			resultant_set = allowed;
Packit f574b8
		    else {
Packit f574b8
			optidx_set_AND(anded_set, *allowed, cur_set);
Packit f574b8
			resultant_set = &anded_set;
Packit f574b8
		    }
Packit f574b8
		}
Packit f574b8
Packit f574b8
#ifndef NO_CONFIG_INFO
Packit f574b8
		/*
Packit f574b8
		 * Now list the opts that are allowed in included file.  If all
Packit f574b8
		 * opts are allowed, then emit nothing, else emit an effective set
Packit f574b8
		 * of allowed options in 
    . Option names will be uppercased.
Packit f574b8
		 * FIXME:  uppercasing option names can be considered redundant.
Packit f574b8
		 */
Packit f574b8
		if (fp0 != 0 && !no_lynxcfg_xinfo && resultant_set) {
Packit f574b8
		    char *buf = NULL;
Packit f574b8
		    unsigned i;
Packit f574b8
Packit f574b8
		    fprintf(fp0, "     Options allowed in this file:\n");
Packit f574b8
		    for (i = 0; i < NOPTS_; ++i) {
Packit f574b8
			if ((*resultant_set)[i])
Packit f574b8
			    continue;
Packit f574b8
			StrAllocCopy(buf, Config_Table[i].name);
Packit f574b8
			LYUpperCase(buf);
Packit f574b8
			fprintf(fp0, "         * %s\n", buf);
Packit f574b8
		    }
Packit f574b8
		    FREE(buf);
Packit f574b8
		}
Packit f574b8
#endif
Packit f574b8
		do_read_cfg(value, cfg_filename, nesting_level + 1, fp0, resultant_set);
Packit f574b8
Packit f574b8
#ifndef NO_CONFIG_INFO
Packit f574b8
		if (fp0 != 0 && !no_lynxcfg_xinfo) {
Packit f574b8
		    fprintf(fp0, "    #<end of %s>\n\n", cp1);
Packit f574b8
		    FREE(url);
Packit f574b8
		    FREE(cp1);
Packit f574b8
		}
Packit f574b8
#endif
Packit f574b8
	    }
Packit f574b8
	    break;
Packit f574b8
Packit f574b8
	default:
Packit f574b8
	    if (fp0 != 0) {
Packit f574b8
		if (StrChr(value, '&') || StrChr(value, '<')) {
Packit f574b8
		    char *cp1 = NULL;
Packit f574b8
Packit f574b8
		    StrAllocCopy(cp1, value);
Packit f574b8
		    LYEntify(&cp1, TRUE);
Packit f574b8
		    fprintf(fp0, "%s:%s\n", name, cp1);
Packit f574b8
		    FREE(cp1);
Packit f574b8
		} else {
Packit f574b8
		    fprintf(fp0, "%s:%s\n", name, value);
Packit f574b8
		}
Packit f574b8
	    }
Packit f574b8
	    break;
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
Packit f574b8
    LYCloseInput(fp);
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * If any DOWNLOADER:  commands have always_enabled set (:TRUE), make
Packit f574b8
     * override_no_download TRUE, so that other restriction settings will not
Packit f574b8
     * block presentation of a download menu with those always_enabled options
Packit f574b8
     * still available.  - FM
Packit f574b8
     */
Packit f574b8
    if (downloaders != 0) {
Packit f574b8
	lynx_list_item_type *cur_download;
Packit f574b8
Packit f574b8
	cur_download = downloaders;
Packit f574b8
	while (cur_download != 0) {
Packit f574b8
	    if (cur_download->always_enabled) {
Packit f574b8
		override_no_download = TRUE;
Packit f574b8
		break;
Packit f574b8
	    }
Packit f574b8
	    cur_download = cur_download->next;
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * If any COOKIE_{ACCEPT,REJECT}_DOMAINS have been defined,
Packit f574b8
     * process them.  These are comma delimited lists of
Packit f574b8
     * domains. - BJP
Packit f574b8
     *
Packit f574b8
     * And for query/strict/loose invalid cookie checking. - BJP
Packit f574b8
     */
Packit f574b8
    LYConfigCookies();
Packit f574b8
}
Packit f574b8
Packit f574b8
/* this is a public interface to do_read_cfg */
Packit f574b8
void read_cfg(const char *cfg_filename,
Packit f574b8
	      const char *parent_filename,
Packit f574b8
	      int nesting_level,
Packit f574b8
	      FILE *fp0)
Packit f574b8
{
Packit f574b8
    HTInitProgramPaths(TRUE);
Packit f574b8
    do_read_cfg(cfg_filename, parent_filename, nesting_level, fp0, NULL);
Packit f574b8
}
Packit f574b8
Packit f574b8
#ifndef NO_CONFIG_INFO
Packit f574b8
static void extra_cfg_link(FILE *fp, const char *href,
Packit f574b8
			   const char *name)
Packit f574b8
{
Packit f574b8
    fprintf(fp, "%s",
Packit f574b8
	    href, name);
Packit f574b8
}
Packit f574b8
#endif /* NO_CONFIG_INFO */
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Show rendered lynx.cfg data without comments, LYNXCFG:/ internal page. 
Packit f574b8
 * Called from getfile() cycle:  we create and load the page just in place and
Packit f574b8
 * return to mainloop().
Packit f574b8
 */
Packit f574b8
int lynx_cfg_infopage(DocInfo *newdoc)
Packit f574b8
{
Packit f574b8
    static char tempfile[LY_MAXPATH] = "\0";
Packit f574b8
    DocAddress WWWDoc;		/* need on exit */
Packit f574b8
    char *temp = 0;
Packit f574b8
    char *cp1 = NULL;
Packit f574b8
    FILE *fp0;
Packit f574b8
Packit f574b8
#ifndef NO_CONFIG_INFO
Packit f574b8
    /*-------------------------------------------------
Packit f574b8
     * kludge a link from LYNXCFG:/, the URL was:
Packit f574b8
     * "  RELOAD THE CHANGES\n"
Packit f574b8
     *--------------------------------------------------*/
Packit f574b8
Packit f574b8
    if (!no_lynxcfg_xinfo && (strstr(newdoc->address, "LYNXCFG://reload"))) {
Packit f574b8
	/*
Packit f574b8
	 * Some stuff to reload read_cfg(), but also load options menu items
Packit f574b8
	 * and command-line options to make things consistent.  Implemented in
Packit f574b8
	 * LYMain.c
Packit f574b8
	 */
Packit f574b8
	reload_read_cfg();
Packit f574b8
Packit f574b8
	/*
Packit f574b8
	 * now pop-up and return to updated LYNXCFG:/ page, remind
Packit f574b8
	 * postoptions() but much simpler:
Packit f574b8
	 */
Packit f574b8
	/*
Packit f574b8
	 * But check whether the top history document is really the expected
Packit f574b8
	 * LYNXCFG:  page.  - kw
Packit f574b8
	 */
Packit f574b8
	if (HTMainText && nhist > 0 &&
Packit f574b8
	    !strcmp(HTLoadedDocumentTitle(), LYNXCFG_TITLE) &&
Packit f574b8
	    !strcmp(HTLoadedDocumentURL(), HDOC(nhist - 1).address) &&
Packit f574b8
	    LYIsUIPage(HDOC(nhist - 1).address, UIP_LYNXCFG) &&
Packit f574b8
	    (!lynxcfginfo_url ||
Packit f574b8
	     strcmp(HTLoadedDocumentURL(), lynxcfginfo_url))) {
Packit f574b8
	    /*  the page was pushed, so pop-up. */
Packit f574b8
	    LYpop(newdoc);
Packit f574b8
	    WWWDoc.address = newdoc->address;
Packit f574b8
	    WWWDoc.post_data = newdoc->post_data;
Packit f574b8
	    WWWDoc.post_content_type = newdoc->post_content_type;
Packit f574b8
	    WWWDoc.bookmark = newdoc->bookmark;
Packit f574b8
	    WWWDoc.isHEAD = newdoc->isHEAD;
Packit f574b8
	    WWWDoc.safe = newdoc->safe;
Packit f574b8
	    LYforce_no_cache = FALSE;	/* ! */
Packit f574b8
	    LYoverride_no_cache = TRUE;		/* ! */
Packit f574b8
Packit f574b8
	    /*
Packit f574b8
	     * Working out of getfile() cycle we reset *no_cache manually here
Packit f574b8
	     * so HTLoadAbsolute() will return "Document already in memory": 
Packit f574b8
	     * it was forced reloading obsolete file again without this
Packit f574b8
	     * (overhead).
Packit f574b8
	     *
Packit f574b8
	     * Probably *no_cache was set in a wrong position because of the
Packit f574b8
	     * internal page...
Packit f574b8
	     */
Packit f574b8
	    if (!HTLoadAbsolute(&WWWDoc))
Packit f574b8
		return (NOT_FOUND);
Packit f574b8
Packit f574b8
	    HTuncache_current_document();	/* will never use again */
Packit f574b8
	    LYUnRegisterUIPage(UIP_LYNXCFG);
Packit f574b8
	}
Packit f574b8
Packit f574b8
	/*  now set up the flag and fall down to create a new LYNXCFG:/ page */
Packit f574b8
	FREE(lynxcfginfo_url);	/* see below */
Packit f574b8
    }
Packit f574b8
#endif /* !NO_CONFIG_INFO */
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * We regenerate the file if reloading has been requested (with LYK_NOCACHE
Packit f574b8
     * key).  If we did not regenerate, there would be no way to recover in a
Packit f574b8
     * session from a situation where the file is corrupted (for example
Packit f574b8
     * truncated because the file system was full when it was first created -
Packit f574b8
     * lynx doesn't check for write errors below), short of manual complete
Packit f574b8
     * removal or perhaps forcing regeneration with LYNXCFG://reload. 
Packit f574b8
     * Similarly, there would be no simple way to get a different page if
Packit f574b8
     * user_mode has changed to Advanced after the file was first generated in
Packit f574b8
     * a non-Advanced mode (the difference being in whether the page includes
Packit f574b8
     * the link to LYNXCFG://reload or not).
Packit f574b8
     *
Packit f574b8
     * We also try to regenerate the file if lynxcfginfo_url is set, indicating
Packit f574b8
     * that tempfile is valid, but the file has disappeared anyway.  This can
Packit f574b8
     * happen to a long-lived lynx process if for example some system script
Packit f574b8
     * periodically cleans up old files in the temp file space.  - kw
Packit f574b8
     */
Packit f574b8
Packit f574b8
    if (LYforce_no_cache && reloading) {
Packit f574b8
	FREE(lynxcfginfo_url);	/* flag to code below to regenerate - kw */
Packit f574b8
    } else if (lynxcfginfo_url != NULL) {
Packit f574b8
	if (!LYCanReadFile(tempfile)) {		/* check existence */
Packit f574b8
	    FREE(lynxcfginfo_url);	/* flag to code below to try again - kw */
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
    if (lynxcfginfo_url == 0) {
Packit f574b8
Packit f574b8
	if ((fp0 = InternalPageFP(tempfile, TRUE)) == 0)
Packit f574b8
	    return (NOT_FOUND);
Packit f574b8
Packit f574b8
	LYLocalFileToURL(&lynxcfginfo_url, tempfile);
Packit f574b8
Packit f574b8
	LYforce_no_cache = TRUE;	/* don't cache this doc */
Packit f574b8
Packit f574b8
	BeginInternalPage(fp0, LYNXCFG_TITLE, NULL);
Packit f574b8
	fprintf(fp0, "
\n");
Packit f574b8
Packit f574b8
#ifndef NO_CONFIG_INFO
Packit f574b8
	if (!no_lynxcfg_xinfo) {
Packit f574b8
#if defined(HAVE_CONFIG_H) || defined(VMS)
Packit f574b8
	    if (strcmp(lynx_cfg_file, LYNX_CFG_FILE)) {
Packit f574b8
		fprintf(fp0, "%s\n%s",
Packit f574b8
			gettext("The following is read from your lynx.cfg file."),
Packit f574b8
			gettext("Please read the distribution"));
Packit f574b8
		LYLocalFileToURL(&temp, LYNX_CFG_FILE);
Packit f574b8
		fprintf(fp0, " lynx.cfg ",
Packit f574b8
			temp);
Packit f574b8
		FREE(temp);
Packit f574b8
		fprintf(fp0, "%s\n\n",
Packit f574b8
			gettext("for more comments."));
Packit f574b8
	    } else
Packit f574b8
#endif /* HAVE_CONFIG_H */
Packit f574b8
	    {
Packit f574b8
		/* no absolute path... for lynx.cfg on DOS/Win32 */
Packit f574b8
		fprintf(fp0, "%s\n%s",
Packit f574b8
			gettext("The following is read from your lynx.cfg file."),
Packit f574b8
			gettext("Please read the distribution"));
Packit f574b8
		fprintf(fp0, " lynx.cfg ");
Packit f574b8
		fprintf(fp0, "%s\n",
Packit f574b8
			gettext("for more comments."));
Packit f574b8
	    }
Packit f574b8
Packit f574b8
#ifndef NO_CONFIG_INFO
Packit f574b8
#if defined(HAVE_CONFIG_H) && defined(USE_COLOR_STYLE)
Packit f574b8
	    if (!no_compileopts_info && !no_lynxcfg_xinfo) {
Packit f574b8
		fprintf(fp0, "%s
  • ", SEE_ALSO);
Packit f574b8
		extra_cfg_link(fp0, STR_LYNXCFLAGS, COMPILE_OPT_SEGMENT);
Packit f574b8
Packit f574b8
		fprintf(fp0, "
  • ");
  • Packit f574b8
    		LYLocalFileToURL(&temp, lynx_lss_file);
    Packit f574b8
    		extra_cfg_link(fp0, temp, COLOR_STYLE_SEGMENT);
    Packit f574b8
    		fprintf(fp0, "
    \n");
    Packit f574b8
    	    } else
    Packit f574b8
    #endif
    Packit f574b8
    	    {
    Packit f574b8
    		fprintf(fp0, "%s ", SEE_ALSO);
    Packit f574b8
    #if defined(HAVE_CONFIG_H)
    Packit f574b8
    		if (!no_compileopts_info) {
    Packit f574b8
    		    extra_cfg_link(fp0, STR_LYNXCFLAGS, COMPILE_OPT_SEGMENT);
    Packit f574b8
    		}
    Packit f574b8
    #endif
    Packit f574b8
    #if defined(USE_COLOR_STYLE)
    Packit f574b8
    		if (!no_lynxcfg_xinfo) {
    Packit f574b8
    		    LYLocalFileToURL(&temp, lynx_lss_file);
    Packit f574b8
    		    extra_cfg_link(fp0, temp, COLOR_STYLE_SEGMENT);
    Packit f574b8
    		}
    Packit f574b8
    #endif
    Packit f574b8
    		fprintf(fp0, "\n\n");
    Packit f574b8
    	    }
    Packit f574b8
    #endif /* NO_CONFIG_INFO */
    Packit f574b8
    Packit f574b8
    	    /** a new experimental link ... **/
    Packit f574b8
    	    if (user_mode == ADVANCED_MODE)
    Packit f574b8
    		fprintf(fp0, "  %s\n",
    Packit f574b8
    			STR_LYNXCFG,
    Packit f574b8
    			gettext("RELOAD THE CHANGES"));
    Packit f574b8
    Packit f574b8
    	    LYLocalFileToURL(&temp, lynx_cfg_file);
    Packit f574b8
    	    StrAllocCopy(cp1, lynx_cfg_file);
    Packit f574b8
    	    if (StrChr(lynx_cfg_file, '&') || StrChr(lynx_cfg_file, '<')) {
    Packit f574b8
    		LYEntify(&cp1, TRUE);
    Packit f574b8
    	    }
    Packit f574b8
    	    fprintf(fp0, "\n    #%s %s\n",
    Packit f574b8
    		    gettext("Your primary configuration"),
    Packit f574b8
    		    temp,
    Packit f574b8
    		    cp1);
    Packit f574b8
    	    FREE(temp);
    Packit f574b8
    	    FREE(cp1);
    Packit f574b8
    Packit f574b8
    	} else
    Packit f574b8
    #endif /* !NO_CONFIG_INFO */
    Packit f574b8
    Packit f574b8
    	    fprintf(fp0, "%s\n\n",
    Packit f574b8
    		    gettext("The following is read from your lynx.cfg file."));
    Packit f574b8
    Packit f574b8
    	/*
    Packit f574b8
    	 * Process the configuration file.
    Packit f574b8
    	 */
    Packit f574b8
    	read_cfg(lynx_cfg_file, "main program", 1, fp0);
    Packit f574b8
    Packit f574b8
    	fprintf(fp0, "\n");
    Packit f574b8
    	EndInternalPage(fp0);
    Packit f574b8
    	LYCloseTempFP(fp0);
    Packit f574b8
    	LYRegisterUIPage(lynxcfginfo_url, UIP_LYNXCFG);
    Packit f574b8
        }
    Packit f574b8
    Packit f574b8
        /* return to getfile() cycle */
    Packit f574b8
        StrAllocCopy(newdoc->address, lynxcfginfo_url);
    Packit f574b8
        WWWDoc.address = newdoc->address;
    Packit f574b8
        WWWDoc.post_data = newdoc->post_data;
    Packit f574b8
        WWWDoc.post_content_type = newdoc->post_content_type;
    Packit f574b8
        WWWDoc.bookmark = newdoc->bookmark;
    Packit f574b8
        WWWDoc.isHEAD = newdoc->isHEAD;
    Packit f574b8
        WWWDoc.safe = newdoc->safe;
    Packit f574b8
    Packit f574b8
        if (!HTLoadAbsolute(&WWWDoc))
    Packit f574b8
    	return (NOT_FOUND);
    Packit f574b8
    #ifdef DIRED_SUPPORT
    Packit f574b8
        lynx_edit_mode = FALSE;
    Packit f574b8
    #endif /* DIRED_SUPPORT */
    Packit f574b8
        return (NORMAL);
    Packit f574b8
    }
    Packit f574b8
    Packit f574b8
    #if defined(HAVE_CONFIG_H) && !defined(NO_CONFIG_INFO)
    Packit f574b8
    /*
    Packit f574b8
     * Compile-time definitions info, LYNXCOMPILEOPTS:/ internal page, from
    Packit f574b8
     * getfile() cycle.
    Packit f574b8
     */
    Packit f574b8
    int lynx_compile_opts(DocInfo *newdoc)
    Packit f574b8
    {
    Packit f574b8
        static char tempfile[LY_MAXPATH] = "\0";
    Packit f574b8
    Packit f574b8
    #define PutDefs(table, N) fprintf(fp0, "%-35s %s\n", table[N].name, table[N].value)
    Packit f574b8
    #include <cfg_defs.h>
    Packit f574b8
        unsigned n;
    Packit f574b8
        DocAddress WWWDoc;		/* need on exit */
    Packit f574b8
        FILE *fp0;
    Packit f574b8
    Packit f574b8
        /* In general, create the page only once - compile-time data will not
    Packit f574b8
         * change...  But we will regenerate the file anyway, in a few situations:
    Packit f574b8
         *
    Packit f574b8
         * (a) configinfo_url has been FREEd - this can happen if free_lynx_cfg()
    Packit f574b8
         * was called as part of a LYNXCFG://reload action.
    Packit f574b8
         *
    Packit f574b8
         * (b) reloading has been requested (with LYK_NOCACHE key).  If we did not
    Packit f574b8
         * regenerate, there would be no way to recover in a session from a
    Packit f574b8
         * situation where the file is corrupted (for example truncated because the
    Packit f574b8
         * file system was full when it was first created - lynx doesn't check for
    Packit f574b8
         * write errors below), short of manual complete removal or forcing
    Packit f574b8
         * regeneration with LYNXCFG://reload.
    Packit f574b8
         *
    Packit f574b8
         * (c) configinfo_url is set, indicating that tempfile is valid, but the
    Packit f574b8
         * file has disappeared anyway.  This can happen to a long-lived lynx
    Packit f574b8
         * process if for example some system script periodically cleans up old
    Packit f574b8
         * files in the temp file space.  - kw
    Packit f574b8
         */
    Packit f574b8
    Packit f574b8
        if (LYforce_no_cache && reloading) {
    Packit f574b8
    	FREE(configinfo_url);	/* flag to code below to regenerate - kw */
    Packit f574b8
        } else if (configinfo_url != NULL) {
    Packit f574b8
    	if (!LYCanReadFile(tempfile)) {		/* check existence */
    Packit f574b8
    	    FREE(configinfo_url);	/* flag to code below to try again - kw */
    Packit f574b8
    	}
    Packit f574b8
        }
    Packit f574b8
        if (configinfo_url == NULL) {
    Packit f574b8
    	if ((fp0 = InternalPageFP(tempfile, TRUE)) == 0)
    Packit f574b8
    	    return (NOT_FOUND);
    Packit f574b8
    Packit f574b8
    	LYLocalFileToURL(&configinfo_url, tempfile);
    Packit f574b8
    Packit f574b8
    	BeginInternalPage(fp0, CONFIG_DEF_TITLE, NULL);
    Packit f574b8
    	fprintf(fp0, "
    \n");
    Packit f574b8
    Packit f574b8
    	fprintf(fp0, "\n%s
    \nconfig.cache\n", AUTOCONF_CONFIG_CACHE);
    Packit f574b8
    	for (n = 0; n < TABLESIZE(config_cache); n++) {
    Packit f574b8
    	    PutDefs(config_cache, n);
    Packit f574b8
    	}
    Packit f574b8
    	fprintf(fp0, "\n%s
    \nlynx_cfg.h\n", AUTOCONF_LYNXCFG_H);
    Packit f574b8
    	for (n = 0; n < TABLESIZE(config_defines); n++) {
    Packit f574b8
    	    PutDefs(config_defines, n);
    Packit f574b8
    	}
    Packit f574b8
    	fprintf(fp0, "\n");
    Packit f574b8
    	EndInternalPage(fp0);
    Packit f574b8
    	LYCloseTempFP(fp0);
    Packit f574b8
    	LYRegisterUIPage(configinfo_url, UIP_CONFIG_DEF);
    Packit f574b8
        }
    Packit f574b8
    Packit f574b8
        /* exit to getfile() cycle */
    Packit f574b8
        StrAllocCopy(newdoc->address, configinfo_url);
    Packit f574b8
        WWWDoc.address = newdoc->address;
    Packit f574b8
        WWWDoc.post_data = newdoc->post_data;
    Packit f574b8
        WWWDoc.post_content_type = newdoc->post_content_type;
    Packit f574b8
        WWWDoc.bookmark = newdoc->bookmark;
    Packit f574b8
        WWWDoc.isHEAD = newdoc->isHEAD;
    Packit f574b8
        WWWDoc.safe = newdoc->safe;
    Packit f574b8
    Packit f574b8
        if (!HTLoadAbsolute(&WWWDoc))
    Packit f574b8
    	return (NOT_FOUND);
    Packit f574b8
    #ifdef DIRED_SUPPORT
    Packit f574b8
        lynx_edit_mode = FALSE;
    Packit f574b8
    #endif /* DIRED_SUPPORT */
    Packit f574b8
        return (NORMAL);
    Packit f574b8
    }
    Packit f574b8
    #endif /* !NO_CONFIG_INFO */