summaryrefslogtreecommitdiffstats
path: root/src/LYOptions.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/LYOptions.c')
-rw-r--r--src/LYOptions.c4365
1 files changed, 4365 insertions, 0 deletions
diff --git a/src/LYOptions.c b/src/LYOptions.c
new file mode 100644
index 0000000..828aacc
--- /dev/null
+++ b/src/LYOptions.c
@@ -0,0 +1,4365 @@
+/* $LynxId: LYOptions.c,v 1.186 2023/01/05 09:17:16 tom Exp $ */
+#include <HTUtils.h>
+#include <HTFTP.h>
+#include <HTTP.h> /* 'reloading' flag */
+#include <HTML.h>
+#include <LYCurses.h>
+#include <LYUtils.h>
+#include <LYStrings.h>
+#include <LYGlobalDefs.h>
+#include <LYHistory.h>
+#include <LYOptions.h>
+#include <LYSignal.h>
+#include <LYClean.h>
+#include <LYCharSets.h>
+#include <UCMap.h>
+#include <UCAux.h>
+#include <LYKeymap.h>
+#include <LYrcFile.h>
+#include <HTAlert.h>
+#include <LYBookmark.h>
+#include <GridText.h>
+#include <LYGetFile.h>
+#include <LYReadCFG.h>
+#include <LYPrettySrc.h>
+#include <HTFile.h>
+#include <LYCharUtils.h>
+
+#ifdef USE_COLOR_STYLE
+#include <LYStyle.h>
+#endif
+
+#include <LYLeaks.h>
+
+BOOLEAN term_options;
+
+#define TOP_LINK "/"
+#define MBM_LINK "//MBM_MENU"
+
+#define MARGIN_STR (no_margins ? "" : "&nbsp;&nbsp;")
+#define MARGIN_LEN (no_margins ? 0 : 2)
+
+static void terminate_options(int sig);
+
+#define COL_OPTION_VALUES 36 /* display column where option values start */
+
+#if defined(USE_SLANG) || defined(COLOR_CURSES)
+static BOOLEAN can_do_colors = FALSE;
+#endif
+
+static int LYChosenShowColor = SHOW_COLOR_UNKNOWN; /* whether to show and save */
+
+BOOLEAN LYCheckUserAgent(void)
+{
+ if (non_empty(LYUserAgent)) {
+ if (strstr(LYUserAgent, "Lynx") == 0
+ && strstr(LYUserAgent, "lynx") == 0
+ && strstr(LYUserAgent, "L_y_n_x") == 0
+ && strstr(LYUserAgent, "l_y_n_x") == 0) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static void validate_x_display(void)
+{
+ char *cp;
+
+ if ((cp = LYgetXDisplay()) != NULL) {
+ StrAllocCopy(x_display, cp);
+ } else {
+ FREE(x_display);
+ }
+}
+
+static void summarize_x_display(char *display_option)
+{
+ if ((x_display == NULL && *display_option == '\0') ||
+ (x_display != NULL && !strcmp(x_display, display_option))) {
+ if (x_display == NULL && LYisConfiguredForX == TRUE) {
+ _statusline(VALUE_ACCEPTED_WARNING_X);
+ } else if (x_display != NULL && LYisConfiguredForX == FALSE) {
+ _statusline(VALUE_ACCEPTED_WARNING_NONX);
+ } else {
+ _statusline(VALUE_ACCEPTED);
+ }
+ } else {
+ if (*display_option) {
+ _statusline(FAILED_TO_SET_DISPLAY);
+ } else {
+ _statusline(FAILED_CLEAR_SET_DISPLAY);
+ }
+ }
+}
+
+#if defined(USE_SLANG) || defined(COLOR_CURSES)
+static void SetupChosenShowColor(void)
+{
+ can_do_colors = TRUE;
+#if defined(COLOR_CURSES)
+ if (LYCursesON) /* could crash if called before initialization */
+ can_do_colors = (has_colors()
+ ? TRUE
+ : FALSE);
+#endif
+ if (!no_option_save) {
+ if (LYChosenShowColor == SHOW_COLOR_UNKNOWN) {
+ switch (LYrcShowColor) {
+ case SHOW_COLOR_NEVER:
+ LYChosenShowColor =
+ (LYShowColor >= SHOW_COLOR_ON) ?
+ SHOW_COLOR_ON : SHOW_COLOR_NEVER;
+ break;
+ case SHOW_COLOR_ALWAYS:
+ if (!can_do_colors)
+ LYChosenShowColor = SHOW_COLOR_ALWAYS;
+ else
+ LYChosenShowColor =
+ (LYShowColor >= SHOW_COLOR_ON) ?
+ SHOW_COLOR_ALWAYS : SHOW_COLOR_OFF;
+ break;
+ default:
+ LYChosenShowColor =
+ (LYShowColor >= SHOW_COLOR_ON) ?
+ SHOW_COLOR_ON : SHOW_COLOR_OFF;
+ }
+ }
+ }
+}
+#endif /* USE_SLANG || COLOR_CURSES */
+
+#ifndef NO_OPTION_MENU
+static int boolean_choice(int status,
+ int line,
+ int column,
+ STRING2PTR choices);
+
+#define LYChooseBoolean(status, line, column, choices) \
+ (BOOLEAN) boolean_choice(status, line, column, (const char *const*)choices)
+
+#define LYChooseEnum(status, line, column, choices) \
+ boolean_choice(status, line, column, (const char *const*)choices)
+
+#define MAXCHOICES 10
+
+/*
+ * Values for the options menu. - FM
+ *
+ * L_foo values are the Y coordinates for the menu item.
+ * B_foo values are the X coordinates for the item's prompt string.
+ * C_foo values are the X coordinates for the item's value string.
+ */
+#define L_EDITOR 2
+#define L_DISPLAY 3
+
+#define L_HOME 4
+#define C_MULTI 24
+#define B_BOOK 34
+#define C_DEFAULT 50
+
+#define L_FTPSTYPE 5
+#define L_MAIL_ADDRESS 6
+#define L_SSEARCH 7
+#define L_LANGUAGE 8
+#define L_PREF_CHARSET 9
+#define L_ASSUME_CHARSET (L_PREF_CHARSET + 1)
+#define L_CHARSET 10
+#define L_RAWMODE 11
+
+#define L_COLOR L_RAWMODE
+#define B_COLOR 44
+#define C_COLOR 62
+
+#define L_BOOL_A 12
+#define B_VIKEYS 5
+#define C_VIKEYS 15
+#define B_EMACSKEYS 22
+#define C_EMACSKEYS 36
+#define B_SHOW_DOTFILES 44
+#define C_SHOW_DOTFILES 62
+
+#define L_BOOL_B 13
+#define B_SELECT_POPUPS 5
+#define C_SELECT_POPUPS 36
+#define B_SHOW_CURSOR 44
+#define C_SHOW_CURSOR 62
+
+#define L_KEYPAD 14
+#define L_LINEED 15
+#define L_LAYOUT 16
+
+#ifdef DIRED_SUPPORT
+#define L_DIRED 17
+#define L_USER_MODE 18
+#define L_USER_AGENT 19
+#define L_EXEC 20
+#else
+#define L_USER_MODE 17
+#define L_USER_AGENT 18
+#define L_EXEC 19
+#endif /* DIRED_SUPPORT */
+
+#define L_VERBOSE_IMAGES L_USER_MODE
+#define B_VERBOSE_IMAGES 50
+#define C_VERBOSE_IMAGES (B_VERBOSE_IMAGES + 21)
+
+/* a kludge to add assume_charset only in ADVANCED mode... */
+#define L_Bool_A (use_assume_charset ? L_BOOL_A + 1 : L_BOOL_A)
+#define L_Bool_B (use_assume_charset ? L_BOOL_B + 1 : L_BOOL_B)
+#define L_Exec (use_assume_charset ? L_EXEC + 1 : L_EXEC)
+#define L_Rawmode (use_assume_charset ? L_RAWMODE + 1 : L_RAWMODE)
+#define L_Charset (use_assume_charset ? L_CHARSET + 1 : L_CHARSET)
+#define L_Color (use_assume_charset ? L_COLOR + 1 : L_COLOR)
+#define L_Keypad (use_assume_charset ? L_KEYPAD + 1 : L_KEYPAD)
+#define L_Lineed (use_assume_charset ? L_LINEED + 1 : L_LINEED)
+#define L_Layout (use_assume_charset ? L_LAYOUT + 1 : L_LAYOUT)
+#define L_Dired (use_assume_charset ? L_DIRED + 1 : L_DIRED)
+#define L_User_Mode (use_assume_charset ? L_USER_MODE + 1 : L_USER_MODE)
+#define L_User_Agent (use_assume_charset ? L_USER_AGENT + 1 : L_USER_AGENT)
+
+#define LPAREN '('
+#define RPAREN ')'
+
+static int add_it(char *text, int len)
+{
+ if (len) {
+ text[len] = '\0';
+ LYaddstr(text);
+ }
+ return 0;
+}
+
+/*
+ * addlbl() is used instead of plain LYaddstr() in old-style options menu
+ * to show hot keys in bold.
+ */
+static void addlbl(const char *text)
+{
+ char actual[80];
+ int s, d;
+ BOOL b = FALSE;
+
+ for (s = d = 0; text[s]; s++) {
+ actual[d++] = text[s];
+ if (text[s] == LPAREN) {
+ d = add_it(actual, d - 1);
+ lynx_start_bold();
+ b = TRUE;
+ actual[d++] = text[s];
+ } else if (text[s] == RPAREN) {
+ d = add_it(actual, d);
+ lynx_stop_bold();
+ b = FALSE;
+ }
+ }
+ add_it(actual, d);
+ if (b)
+ lynx_stop_bold();
+}
+
+#if !defined(VMS) || defined(USE_SLANG)
+#define HANDLE_LYOPTIONS \
+ if (term_options) { \
+ term_options = FALSE; \
+ } else { \
+ AddValueAccepted = TRUE; \
+ } \
+ goto draw_options
+#else
+#define HANDLE_LYOPTIONS \
+ term_options = FALSE; \
+ if (use_assume_charset != old_use_assume_charset) \
+ goto draw_options
+#endif /* !VMS || USE_SLANG */
+
+void LYoptions(void)
+{
+#define ShowBool(value) LYaddstr((value) ? "ON " : "OFF")
+ static const char *bool_choices[] =
+ {
+ "OFF",
+ "ON",
+ NULL
+ };
+ static const char *const caseless_choices[] =
+ {
+ "CASE INSENSITIVE",
+ "CASE SENSITIVE",
+ NULL
+ };
+
+#ifdef DIRED_SUPPORT
+ static const char *dirList_choices[] =
+ {
+ "Directories first",
+ "Files first",
+ "Mixed style",
+ NULL
+ };
+#endif
+
+#if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS))
+ static const char *exec_choices[] =
+ {
+ "ALWAYS OFF",
+ "FOR LOCAL FILES ONLY",
+#ifndef NEVER_ALLOW_REMOTE_EXEC
+ "ALWAYS ON",
+#endif /* !NEVER_ALLOW_REMOTE_EXEC */
+ NULL
+ };
+#endif
+ static const char *fileSort_choices[] =
+ {
+ "By Filename",
+ "By Type",
+ "By Size",
+ "By Date",
+ NULL
+ };
+ static const char *keypad_choices[] =
+ {
+ "Numbers act as arrows",
+ "Links are numbered",
+ "Links and form fields are numbered",
+ NULL
+ };
+ static const char *mbm_choices[] =
+ {
+ "OFF ",
+ "STANDARD",
+ "ADVANCED",
+ NULL
+ };
+ static const char *userMode_choices[] =
+ {
+ "Novice",
+ "Intermediate",
+ "Advanced",
+ "Minimal",
+ NULL
+ };
+
+#if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS))
+ int itmp;
+#endif /* ENABLE_OPTS_CHANGE_EXEC */
+ int response, ch;
+
+ /*
+ * If the user changes the display we need memory to put it in.
+ */
+ bstring *my_data = NULL;
+ char *choices[MAXCHOICES];
+ int CurrentCharSet = current_char_set;
+ int CurrentAssumeCharSet = UCLYhndl_for_unspec;
+ int CurrentShowColor = LYShowColor;
+ BOOLEAN CurrentRawMode = LYRawMode;
+ BOOLEAN AddValueAccepted = FALSE;
+ BOOL use_assume_charset;
+
+#if defined(VMS) || defined(USE_SLANG)
+ BOOL old_use_assume_charset;
+#endif
+
+#ifdef DIRED_SUPPORT
+#ifdef ENABLE_OPTS_CHANGE_EXEC
+ if (LYlines < 24) {
+ HTAlert(OPTION_SCREEN_NEEDS_24);
+ return;
+ }
+#else
+ if (LYlines < 23) {
+ HTAlert(OPTION_SCREEN_NEEDS_23);
+ return;
+ }
+#endif /* ENABLE_OPTS_CHANGE_EXEC */
+#else
+#ifdef ENABLE_OPTS_CHANGE_EXEC
+ if (LYlines < 23) {
+ HTAlert(OPTION_SCREEN_NEEDS_23);
+ return;
+ }
+#else
+ if (LYlines < 22) {
+ HTAlert(OPTION_SCREEN_NEEDS_22);
+ return;
+ }
+#endif /* ENABLE_OPTS_CHANGE_EXEC */
+#endif /* DIRED_SUPPORT */
+
+ term_options = FALSE;
+ LYStatusLine = (LYlines - 1); /* screen is otherwise too crowded */
+ signal(SIGINT, terminate_options);
+ if (no_option_save) {
+ if (LYShowColor == SHOW_COLOR_NEVER) {
+ LYShowColor = SHOW_COLOR_OFF;
+ } else if (LYShowColor == SHOW_COLOR_ALWAYS) {
+ LYShowColor = SHOW_COLOR_ON;
+ }
+#if defined(USE_SLANG) || defined(COLOR_CURSES)
+ } else {
+ SetupChosenShowColor();
+#endif /* USE_SLANG || COLOR_CURSES */
+ }
+
+ use_assume_charset = (BOOLEAN) (user_mode == ADVANCED_MODE);
+
+ draw_options:
+
+#if defined(VMS) || defined(USE_SLANG)
+ old_use_assume_charset = use_assume_charset;
+#endif
+ /*
+ * NOTE that printw() should be avoided for strings that might have
+ * non-ASCII or multibyte/CJK characters. - FM
+ */
+#if defined(FANCY_CURSES) || defined (USE_SLANG)
+ if (enable_scrollback) {
+ LYclear();
+ } else {
+ LYerase();
+ }
+#else
+ LYclear();
+#endif /* FANCY_CURSES || USE_SLANG */
+ LYmove(0, 5);
+
+ lynx_start_h1_color();
+ LYaddstr(" Options Menu (");
+ LYaddstr(LYNX_NAME);
+ LYaddstr(" Version ");
+ LYaddstr(LYNX_VERSION);
+ LYaddch(')');
+ lynx_stop_h1_color();
+ LYmove(L_EDITOR, 5);
+ addlbl("(E)ditor : ");
+ LYaddstr(non_empty(editor) ? editor : "NONE");
+
+ LYmove(L_DISPLAY, 5);
+ addlbl("(D)ISPLAY variable : ");
+ LYaddstr(non_empty(x_display) ? x_display : "NONE");
+
+ LYmove(L_HOME, 5);
+ addlbl("mu(L)ti-bookmarks: ");
+ LYaddstr(mbm_choices[LYMultiBookmarks]);
+ LYmove(L_HOME, B_BOOK);
+ if (LYMultiBookmarks != MBM_OFF) {
+ addlbl("review/edit (B)ookmarks files");
+ } else {
+ addlbl("(B)ookmark file: ");
+ LYaddstr(non_empty(bookmark_page) ? bookmark_page : "NONE");
+ }
+
+ LYmove(L_FTPSTYPE, 5);
+ addlbl("(F)TP sort criteria : ");
+ LYaddstr((HTfileSortMethod == FILE_BY_NAME ? "By Filename" :
+ (HTfileSortMethod == FILE_BY_SIZE ? "By Size " :
+ (HTfileSortMethod == FILE_BY_TYPE ? "By Type " :
+ "By Date "))));
+
+ LYmove(L_MAIL_ADDRESS, 5);
+ addlbl("(P)ersonal mail address : ");
+ LYaddstr(non_empty(personal_mail_address) ?
+ personal_mail_address : "NONE");
+
+ LYmove(L_SSEARCH, 5);
+ addlbl("(S)earching type : ");
+ LYaddstr(LYcase_sensitive ? "CASE SENSITIVE " : "CASE INSENSITIVE");
+
+ LYmove(L_Charset, 5);
+ addlbl("display (C)haracter set : ");
+ LYaddstr(LYchar_set_names[current_char_set]);
+
+ LYmove(L_LANGUAGE, 5);
+ addlbl("preferred document lan(G)uage: ");
+ LYaddstr(non_empty(language) ? language : "NONE");
+
+ LYmove(L_PREF_CHARSET, 5);
+ addlbl("preferred document c(H)arset : ");
+ LYaddstr(non_empty(pref_charset) ? pref_charset : "NONE");
+
+ if (use_assume_charset) {
+ LYmove(L_ASSUME_CHARSET, 5);
+ addlbl("(^A)ssume charset if unknown : ");
+ if (UCAssume_MIMEcharset)
+ LYaddstr(UCAssume_MIMEcharset);
+ else
+ LYaddstr((UCLYhndl_for_unspec >= 0) ?
+ LYCharSet_UC[UCLYhndl_for_unspec].MIMEname
+ : "NONE");
+ }
+
+ LYmove(L_Rawmode, 5);
+ addlbl("Raw 8-bit or CJK m(O)de : ");
+ ShowBool(LYRawMode);
+
+#if defined(USE_SLANG) || defined(COLOR_CURSES)
+ LYmove(L_Color, B_COLOR);
+ addlbl("show color (&) : ");
+ if (no_option_save) {
+ ShowBool(LYShowColor == SHOW_COLOR_OFF);
+ } else {
+ switch (LYChosenShowColor) {
+ case SHOW_COLOR_NEVER:
+ LYaddstr("NEVER ");
+ break;
+ case SHOW_COLOR_OFF:
+ LYaddstr("OFF");
+ break;
+ case SHOW_COLOR_ON:
+ LYaddstr("ON ");
+ break;
+ case SHOW_COLOR_ALWAYS:
+#if defined(COLOR_CURSES)
+ if (!has_colors())
+ LYaddstr("Always try");
+ else
+#endif
+ LYaddstr("ALWAYS ");
+ }
+ }
+#endif /* USE_SLANG || COLOR_CURSES */
+
+ LYmove(L_Bool_A, B_VIKEYS);
+ addlbl("(V)I keys: ");
+ ShowBool(vi_keys);
+
+ LYmove(L_Bool_A, B_EMACSKEYS);
+ addlbl("e(M)acs keys: ");
+ ShowBool(emacs_keys);
+
+ LYmove(L_Bool_A, B_SHOW_DOTFILES);
+ addlbl("sho(W) dot files: ");
+ ShowBool(!no_dotfiles && show_dotfiles);
+
+ LYmove(L_Bool_B, B_SELECT_POPUPS);
+ addlbl("popups for selec(T) fields : ");
+ ShowBool(LYSelectPopups);
+
+ LYmove(L_Bool_B, B_SHOW_CURSOR);
+ addlbl("show cursor (@) : ");
+ ShowBool(LYShowCursor);
+
+ LYmove(L_Keypad, 5);
+ addlbl("(K)eypad mode : ");
+ LYaddstr((fields_are_numbered() && links_are_numbered())
+ ? "Links and form fields are numbered"
+ : (links_are_numbered()
+ ? "Links are numbered "
+ : (fields_are_numbered()
+ ? "Form fields are numbered "
+ : "Numbers act as arrows ")));
+
+ LYmove(L_Lineed, 5);
+ addlbl("li(N)e edit style : ");
+ LYaddstr(LYEditorNames[current_lineedit]);
+
+#ifdef EXP_KEYBOARD_LAYOUT
+ LYmove(L_Layout, 5);
+ addlbl("Ke(Y)board layout : ");
+ LYaddstr(LYKbLayoutNames[current_layout]);
+#endif
+
+#ifdef DIRED_SUPPORT
+ LYmove(L_Dired, 5);
+ addlbl("l(I)st directory style : ");
+ LYaddstr((dir_list_style == FILES_FIRST) ? "Files first " :
+ ((dir_list_style == MIXED_STYLE) ? "Mixed style " :
+ "Directories first"));
+#endif /* DIRED_SUPPORT */
+
+ LYmove(L_User_Mode, 5);
+ addlbl("(U)ser mode : ");
+ LYaddstr((user_mode == NOVICE_MODE) ? "Novice " :
+ ((user_mode == INTERMEDIATE_MODE) ? "Intermediate" :
+ ((user_mode == ADVANCED_MODE) ? "Advanced " :
+ "Minimal ")));
+
+ addlbl(" verbose images (!) : ");
+ ShowBool(verbose_img);
+
+ LYmove(L_User_Agent, 5);
+ addlbl("user (A)gent : ");
+ LYaddstr(non_empty(LYUserAgent) ? LYUserAgent : "NONE");
+
+#if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS))
+ LYmove(L_Exec, 5);
+ addlbl("local e(X)ecution links : ");
+#ifndef NEVER_ALLOW_REMOTE_EXEC
+ LYaddstr(local_exec ? "ALWAYS ON " :
+ (local_exec_on_local_files ? "FOR LOCAL FILES ONLY" :
+ "ALWAYS OFF "));
+#else
+ LYaddstr(local_exec_on_local_files ? "FOR LOCAL FILES ONLY" :
+ "ALWAYS OFF ");
+#endif /* !NEVER_ALLOW_REMOTE_EXEC */
+#endif /* ENABLE_OPTS_CHANGE_EXEC */
+
+ LYmove(LYlines - 3, 2);
+ LYaddstr(SELECT_SEGMENT);
+ lynx_start_bold();
+ LYaddstr(CAP_LETT_SEGMENT);
+ lynx_stop_bold();
+ LYaddstr(OF_OPT_LINE_SEGMENT);
+ if (!no_option_save) {
+ LYaddstr(" '");
+ lynx_start_bold();
+ LYaddstr(">");
+ lynx_stop_bold();
+ LYaddstr("'");
+ LYaddstr(TO_SAVE_SEGMENT);
+ }
+ LYaddstr(OR_SEGMENT);
+ LYaddstr("'");
+ lynx_start_bold();
+ LYaddstr("r");
+ lynx_stop_bold();
+ LYaddstr("'");
+ LYaddstr(TO_RETURN_SEGMENT);
+
+ response = 0;
+ while (response != 'R' &&
+ !LYisNonAlnumKeyname(response, LYK_PREV_DOC) &&
+ response != '>' && !term_options &&
+ !LYCharIsINTERRUPT_NO_letter(response)) {
+ if (AddValueAccepted == TRUE) {
+ _statusline(VALUE_ACCEPTED);
+ AddValueAccepted = FALSE;
+ }
+ LYmove((LYlines - 2), 0);
+ lynx_start_prompt_color();
+ LYaddstr(COMMAND_PROMPT);
+ lynx_stop_prompt_color();
+
+ LYrefresh();
+ response = LYgetch_single();
+ if (term_options || LYCharIsINTERRUPT_NO_letter(response))
+ response = 'R';
+ if (LYisNonAlnumKeyname(response, LYK_REFRESH)) {
+ lynx_force_repaint();
+ goto draw_options;
+ }
+ switch (response) {
+ case 'E': /* Change the editor. */
+ if (no_editor) {
+ _statusline(EDIT_DISABLED);
+ } else if (system_editor) {
+ _statusline(EDITOR_LOCKED);
+ } else {
+ if (non_empty(editor)) {
+ BStrCopy0(my_data, editor);
+ } else { /* clear the NONE */
+ LYmove(L_EDITOR, COL_OPTION_VALUES);
+ LYaddstr(" ");
+ BStrCopy0(my_data, "");
+ }
+ _statusline(ACCEPT_DATA);
+ LYmove(L_EDITOR, COL_OPTION_VALUES);
+ lynx_start_bold();
+ ch = LYgetBString(&my_data, FALSE, 0, NORECALL);
+ lynx_stop_bold();
+ LYmove(L_EDITOR, COL_OPTION_VALUES);
+ if (term_options || ch == -1) {
+ LYaddstr(non_empty(editor) ?
+ editor : "NONE");
+ } else if (isBEmpty(my_data)) {
+ FREE(editor);
+ LYaddstr("NONE");
+ } else {
+ StrAllocCopy(editor, my_data->str);
+ LYaddstr(editor);
+ }
+ LYclrtoeol();
+ if (ch == -1) {
+ HTInfoMsg(CANCELLED);
+ HTInfoMsg("");
+ } else {
+ _statusline(VALUE_ACCEPTED);
+ }
+ }
+ response = ' ';
+ break;
+
+ case 'D': /* Change the display. */
+ if (non_empty(x_display)) {
+ BStrCopy0(my_data, x_display);
+ } else { /* clear the NONE */
+ LYmove(L_DISPLAY, COL_OPTION_VALUES);
+ LYaddstr(" ");
+ BStrCopy0(my_data, "");
+ }
+ _statusline(ACCEPT_DATA);
+ LYmove(L_DISPLAY, COL_OPTION_VALUES);
+ lynx_start_bold();
+ ch = LYgetBString(&my_data, FALSE, 0, NORECALL);
+ lynx_stop_bold();
+ LYmove(L_DISPLAY, COL_OPTION_VALUES);
+
+#ifdef VMS
+#define CompareEnvVars(a,b) strcasecomp(a, b)
+#else
+#define CompareEnvVars(a,b) strcmp(a, b)
+#endif /* VMS */
+
+ if ((term_options || ch == -1) ||
+ (x_display != NULL &&
+ !CompareEnvVars(x_display, my_data->str))) {
+ /*
+ * Cancelled, or a non-NULL display string wasn't changed. -
+ * FM
+ */
+ LYaddstr(non_empty(x_display) ? x_display : "NONE");
+ LYclrtoeol();
+ if (ch == -1) {
+ HTInfoMsg(CANCELLED);
+ HTInfoMsg("");
+ } else {
+ _statusline(VALUE_ACCEPTED);
+ }
+ response = ' ';
+ break;
+ } else if (isBEmpty(my_data)) {
+ if ((x_display == NULL) ||
+ (x_display != NULL && *x_display == '\0')) {
+ /*
+ * NULL or zero-length display string wasn't changed. - FM
+ */
+ LYaddstr("NONE");
+ LYclrtoeol();
+ _statusline(VALUE_ACCEPTED);
+ response = ' ';
+ break;
+ }
+ }
+ /*
+ * Set the new DISPLAY variable. - FM
+ */
+ LYsetXDisplay(my_data->str);
+ validate_x_display();
+ LYaddstr(x_display ? x_display : "NONE");
+ LYclrtoeol();
+ summarize_x_display(my_data->str);
+ response = ' ';
+ break;
+
+ case 'L': /* Change multibookmarks option. */
+ if (LYMBMBlocked) {
+ _statusline(MULTIBOOKMARKS_DISALLOWED);
+ response = ' ';
+ break;
+ }
+ if (!LYSelectPopups) {
+ LYMultiBookmarks = LYChooseEnum(LYMultiBookmarks,
+ L_HOME, C_MULTI,
+ mbm_choices);
+ } else {
+ LYMultiBookmarks = LYChoosePopup(LYMultiBookmarks,
+ L_HOME, (C_MULTI - 1),
+ mbm_choices,
+ 3, FALSE, FALSE);
+ }
+#if defined(VMS) || defined(USE_SLANG)
+ if (LYSelectPopups) {
+ LYmove(L_HOME, C_MULTI);
+ LYclrtoeol();
+ LYaddstr(mbm_choices[LYMultiBookmarks]);
+ }
+#endif /* VMS || USE_SLANG */
+#if !defined(VMS) && !defined(USE_SLANG)
+ if (!LYSelectPopups)
+#endif /* !VMS && !USE_SLANG */
+ {
+ LYmove(L_HOME, B_BOOK);
+ LYclrtoeol();
+ if (LYMultiBookmarks != MBM_OFF) {
+ LYaddstr(gettext("review/edit B)ookmarks files"));
+ } else {
+ LYaddstr(gettext("B)ookmark file: "));
+ LYaddstr(non_empty(bookmark_page) ?
+ bookmark_page : "NONE");
+ }
+ }
+ response = ' ';
+ if (LYSelectPopups) {
+ HANDLE_LYOPTIONS;
+ }
+ break;
+
+ case 'B': /* Change the bookmark page location. */
+ /*
+ * Anonymous users should not be allowed to change the bookmark
+ * page.
+ */
+ if (!no_bookmark) {
+ if (LYMultiBookmarks != MBM_OFF) {
+ edit_bookmarks();
+ signal(SIGINT, terminate_options);
+ goto draw_options;
+ }
+ if (non_empty(bookmark_page)) {
+ BStrCopy0(my_data, bookmark_page);
+ } else { /* clear the NONE */
+ LYmove(L_HOME, C_DEFAULT);
+ LYclrtoeol();
+ BStrCopy0(my_data, "");
+ }
+ _statusline(ACCEPT_DATA);
+ LYmove(L_HOME, C_DEFAULT);
+ lynx_start_bold();
+ ch = LYgetBString(&my_data, FALSE, 0, NORECALL);
+ lynx_stop_bold();
+ LYmove(L_HOME, C_DEFAULT);
+ BStrAlloc(my_data, my_data->len + LY_MAXPATH); /* lengthen */
+ if (term_options ||
+ ch == -1 || isBEmpty(my_data)) {
+ LYaddstr(non_empty(bookmark_page) ?
+ bookmark_page : "NONE");
+ } else if (!LYPathOffHomeOK(my_data->str, (size_t) my_data->len)) {
+ LYaddstr(non_empty(bookmark_page) ?
+ bookmark_page : "NONE");
+ LYclrtoeol();
+ _statusline(USE_PATH_OFF_HOME);
+ response = ' ';
+ break;
+ } else {
+ StrAllocCopy(bookmark_page, my_data->str);
+ StrAllocCopy(MBM_A_subbookmark[0], bookmark_page);
+ LYaddstr(bookmark_page);
+ }
+ LYclrtoeol();
+ if (ch == -1) {
+ HTInfoMsg(CANCELLED);
+ HTInfoMsg("");
+ } else {
+ _statusline(VALUE_ACCEPTED);
+ }
+ } else { /* anonymous */
+ _statusline(BOOKMARK_CHANGE_DISALLOWED);
+ }
+ response = ' ';
+ break;
+
+ case 'F': /* Change ftp directory sorting. */
+ if (!LYSelectPopups) {
+ HTfileSortMethod = LYChooseEnum(HTfileSortMethod,
+ L_FTPSTYPE, -1,
+ fileSort_choices);
+ } else {
+ HTfileSortMethod = LYChoosePopup(HTfileSortMethod,
+ L_FTPSTYPE, -1,
+ fileSort_choices,
+ 4, FALSE, FALSE);
+#if defined(VMS) || defined(USE_SLANG)
+ LYmove(L_FTPSTYPE, COL_OPTION_VALUES);
+ LYclrtoeol();
+ LYaddstr(fileSort_choices[HTfileSortMethod]);
+#endif /* VMS || USE_SLANG */
+ }
+ response = ' ';
+ if (LYSelectPopups) {
+ HANDLE_LYOPTIONS;
+ }
+ break;
+
+ case 'P': /* Change personal mail address for From headers. */
+ if (non_empty(personal_mail_address)) {
+ BStrCopy0(my_data, personal_mail_address);
+ } else { /* clear the NONE */
+ LYmove(L_MAIL_ADDRESS, COL_OPTION_VALUES);
+ LYaddstr(" ");
+ BStrCopy0(my_data, "");
+ }
+ _statusline(ACCEPT_DATA);
+ LYmove(L_MAIL_ADDRESS, COL_OPTION_VALUES);
+ lynx_start_bold();
+ ch = LYgetBString(&my_data, FALSE, 0, NORECALL);
+ lynx_stop_bold();
+ LYmove(L_MAIL_ADDRESS, COL_OPTION_VALUES);
+ if (term_options || ch == -1) {
+ LYaddstr((personal_mail_address &&
+ *personal_mail_address) ?
+ personal_mail_address : "NONE");
+ } else if (isBEmpty(my_data)) {
+ FREE(personal_mail_address);
+ LYaddstr("NONE");
+ } else {
+ StrAllocCopy(personal_mail_address, my_data->str);
+ LYaddstr(personal_mail_address);
+ }
+ LYclrtoeol();
+ if (ch == -1) {
+ HTInfoMsg(CANCELLED);
+ HTInfoMsg("");
+ } else {
+ _statusline(VALUE_ACCEPTED);
+ }
+ response = ' ';
+ break;
+
+ case 'S': /* Change case sensitivity for searches. */
+ LYcase_sensitive = LYChooseBoolean(LYcase_sensitive,
+ L_SSEARCH, -1,
+ caseless_choices);
+ response = ' ';
+ break;
+
+ case '\001': /* Change assume_charset setting. */
+ if (use_assume_charset) {
+ int i, curval;
+ const char **assume_list;
+ assume_list = typecallocn(const char *, (unsigned)
+ (LYNumCharsets + 1));
+
+ if (!assume_list) {
+ outofmem(__FILE__, "options");
+ }
+ for (i = 0; i < LYNumCharsets; i++) {
+ assume_list[i] = LYCharSet_UC[i].MIMEname;
+ }
+ curval = UCLYhndl_for_unspec;
+ if (curval == current_char_set && UCAssume_MIMEcharset) {
+ curval = UCGetLYhndl_byMIME(UCAssume_MIMEcharset);
+ }
+ if (curval < 0)
+ curval = LYRawMode ? current_char_set : 0;
+ if (!LYSelectPopups) {
+#ifndef ALL_CHARSETS_IN_O_MENU_SCREEN
+ UCLYhndl_for_unspec =
+ assumed_doc_charset_map[(LYChooseEnum(charset_subsets[curval].assumed_idx,
+ L_ASSUME_CHARSET, -1,
+ assumed_charset_choices)
+ ? 1
+ : 0)];
+#else
+ UCLYhndl_for_unspec =
+ LYChooseEnum(curval,
+ L_ASSUME_CHARSET, -1,
+ assume_list);
+#endif
+ } else {
+#ifndef ALL_CHARSETS_IN_O_MENU_SCREEN
+ UCLYhndl_for_unspec =
+ assumed_doc_charset_map[(LYChoosePopup(charset_subsets[curval].assumed_idx,
+ L_ASSUME_CHARSET, -1,
+ assumed_charset_choices,
+ 0,
+ FALSE,
+ FALSE)
+ ? 1
+ : 0)];
+#else
+ UCLYhndl_for_unspec =
+ LYChoosePopup(curval,
+ L_ASSUME_CHARSET, -1,
+ assume_list,
+ 0, FALSE, FALSE);
+#endif
+#if defined(VMS) || defined(USE_SLANG)
+ LYmove(L_ASSUME_CHARSET, COL_OPTION_VALUES);
+ LYclrtoeol();
+ if (UCLYhndl_for_unspec >= 0)
+ LYaddstr(LYCharSet_UC[UCLYhndl_for_unspec].MIMEname);
+#endif /* VMS || USE_SLANG */
+ }
+
+ /*
+ * Set the raw 8-bit or CJK mode defaults and character set if
+ * changed. - FM
+ */
+ if (CurrentAssumeCharSet != UCLYhndl_for_unspec ||
+ UCLYhndl_for_unspec != curval) {
+ if (UCLYhndl_for_unspec != CurrentAssumeCharSet) {
+ StrAllocCopy(UCAssume_MIMEcharset,
+ LYCharSet_UC[UCLYhndl_for_unspec].MIMEname);
+ }
+ if (HTCJK != JAPANESE)
+ LYRawMode = (BOOLEAN) (UCLYhndl_for_unspec == current_char_set);
+ HTMLSetUseDefaultRawMode(current_char_set, LYRawMode);
+ HTMLSetCharacterHandling(current_char_set);
+ CurrentAssumeCharSet = UCLYhndl_for_unspec;
+ CurrentRawMode = LYRawMode;
+#if !defined(VMS) && !defined(USE_SLANG)
+ if (!LYSelectPopups)
+#endif /* !VMS && !USE_SLANG */
+ {
+ LYmove(L_RAWMODE + 1, COL_OPTION_VALUES);
+ LYclrtoeol();
+ ShowBool(LYRawMode);
+ }
+ }
+ FREE(assume_list);
+ response = ' ';
+ if (LYSelectPopups) {
+ HANDLE_LYOPTIONS;
+ }
+ } else {
+ _statusline(NEED_ADVANCED_USER_MODE);
+ AddValueAccepted = FALSE;
+ }
+ break;
+
+ case 'C': /* Change display charset setting. */
+ if (!LYSelectPopups) {
+#ifndef ALL_CHARSETS_IN_O_MENU_SCREEN
+ displayed_display_charset_idx = LYChooseEnum(displayed_display_charset_idx,
+ L_Charset, -1,
+ display_charset_choices);
+ current_char_set = display_charset_map[displayed_display_charset_idx];
+#else
+ current_char_set = LYChooseEnum(current_char_set,
+ L_Charset, -1,
+ LYchar_set_names);
+#endif
+ } else {
+#ifndef ALL_CHARSETS_IN_O_MENU_SCREEN
+ displayed_display_charset_idx = LYChoosePopup(displayed_display_charset_idx,
+ L_Charset, -1,
+ display_charset_choices,
+ 0, FALSE, FALSE);
+ current_char_set = display_charset_map[displayed_display_charset_idx];
+#else
+ current_char_set = LYChoosePopup(current_char_set,
+ L_Charset, -1,
+ LYchar_set_names,
+ 0, FALSE, FALSE);
+#endif
+
+#if defined(VMS) || defined(USE_SLANG)
+ LYmove(L_Charset, COL_OPTION_VALUES);
+ LYclrtoeol();
+ LYaddstr(LYchar_set_names[current_char_set]);
+#endif /* VMS || USE_SLANG */
+ }
+ /*
+ * Set the raw 8-bit or CJK mode defaults and character set if
+ * changed. - FM
+ */
+ if (CurrentCharSet != current_char_set) {
+ LYUseDefaultRawMode = TRUE;
+ HTMLUseCharacterSet(current_char_set);
+ CurrentCharSet = current_char_set;
+ CurrentRawMode = LYRawMode;
+#if !defined(VMS) && !defined(USE_SLANG)
+ if (!LYSelectPopups)
+#endif /* !VMS && !USE_SLANG */
+ {
+ LYmove(L_Rawmode, COL_OPTION_VALUES);
+ LYclrtoeol();
+ ShowBool(LYRawMode);
+ }
+#ifdef CAN_SWITCH_DISPLAY_CHARSET
+ /* Deduce whether the user wants autoswitch: */
+ switch_display_charsets =
+ (current_char_set == auto_display_charset
+ || current_char_set == auto_other_display_charset);
+#endif
+ }
+ response = ' ';
+ if (LYSelectPopups) {
+ HANDLE_LYOPTIONS;
+ }
+ break;
+
+ case 'O': /* Change raw mode setting. */
+ LYRawMode = LYChooseBoolean(LYRawMode, L_Rawmode, -1, bool_choices);
+ /*
+ * Set the LYUseDefaultRawMode value and character handling if
+ * LYRawMode was changed. - FM
+ */
+ if (CurrentRawMode != LYRawMode) {
+ HTMLSetUseDefaultRawMode(current_char_set, LYRawMode);
+ HTMLSetCharacterHandling(current_char_set);
+ CurrentRawMode = LYRawMode;
+ }
+ response = ' ';
+ break;
+
+ case 'G': /* Change language preference. */
+ if (non_empty(language)) {
+ BStrCopy0(my_data, language);
+ } else { /* clear the NONE */
+ LYmove(L_LANGUAGE, COL_OPTION_VALUES);
+ LYaddstr(" ");
+ BStrCopy0(my_data, "");
+ }
+ _statusline(ACCEPT_DATA);
+ LYmove(L_LANGUAGE, COL_OPTION_VALUES);
+ lynx_start_bold();
+ ch = LYgetBString(&my_data, FALSE, 0, NORECALL);
+ lynx_stop_bold();
+ LYmove(L_LANGUAGE, COL_OPTION_VALUES);
+ if (term_options || ch == -1) {
+ LYaddstr(non_empty(language) ?
+ language : "NONE");
+ } else if (isBEmpty(my_data)) {
+ FREE(language);
+ LYaddstr("NONE");
+ } else {
+ StrAllocCopy(language, my_data->str);
+ LYaddstr(language);
+ }
+ LYclrtoeol();
+ if (ch == -1) {
+ HTInfoMsg(CANCELLED);
+ HTInfoMsg("");
+ } else {
+ _statusline(VALUE_ACCEPTED);
+ }
+ response = ' ';
+ break;
+
+ case 'H': /* Change charset preference. */
+ if (non_empty(pref_charset)) {
+ BStrCopy0(my_data, pref_charset);
+ } else { /* clear the NONE */
+ LYmove(L_PREF_CHARSET, COL_OPTION_VALUES);
+ LYaddstr(" ");
+ BStrCopy0(my_data, "");
+ }
+ _statusline(ACCEPT_DATA);
+ LYmove(L_PREF_CHARSET, COL_OPTION_VALUES);
+ lynx_start_bold();
+ ch = LYgetBString(&my_data, FALSE, 0, NORECALL);
+ lynx_stop_bold();
+ LYmove(L_PREF_CHARSET, COL_OPTION_VALUES);
+ if (term_options || ch == -1) {
+ LYaddstr(non_empty(pref_charset) ?
+ pref_charset : "NONE");
+ } else if (isBEmpty(my_data)) {
+ FREE(pref_charset);
+ LYaddstr("NONE");
+ } else {
+ StrAllocCopy(pref_charset, my_data->str);
+ LYaddstr(pref_charset);
+ }
+ LYclrtoeol();
+ if (ch == -1) {
+ HTInfoMsg(CANCELLED);
+ HTInfoMsg("");
+ } else {
+ _statusline(VALUE_ACCEPTED);
+ }
+ response = ' ';
+ break;
+
+ case 'V': /* Change VI keys setting. */
+ vi_keys = LYChooseBoolean(vi_keys,
+ L_Bool_A, C_VIKEYS,
+ bool_choices);
+ if (vi_keys) {
+ set_vi_keys();
+ } else {
+ reset_vi_keys();
+ }
+ response = ' ';
+ break;
+
+ case 'M': /* Change emacs keys setting. */
+ emacs_keys = LYChooseBoolean(emacs_keys,
+ L_Bool_A, C_EMACSKEYS,
+ bool_choices);
+ if (emacs_keys) {
+ set_emacs_keys();
+ } else {
+ reset_emacs_keys();
+ }
+ response = ' ';
+ break;
+
+ case 'W': /* Change show dotfiles setting. */
+ if (no_dotfiles) {
+ _statusline(DOTFILE_ACCESS_DISABLED);
+ } else {
+ show_dotfiles = LYChooseBoolean(show_dotfiles,
+ L_Bool_A,
+ C_SHOW_DOTFILES,
+ bool_choices);
+ }
+ response = ' ';
+ break;
+
+ case 'T': /* Change select popups setting. */
+ LYSelectPopups = LYChooseBoolean(LYSelectPopups,
+ L_Bool_B,
+ C_SELECT_POPUPS,
+ bool_choices);
+ response = ' ';
+ break;
+
+#if defined(USE_SLANG) || defined(COLOR_CURSES)
+ case '&': /* Change show color setting. */
+ if (no_option_save) {
+#if defined(COLOR_CURSES)
+ if (!has_colors()) {
+ char *terminal = LYGetEnv("TERM");
+
+ if (terminal)
+ HTUserMsg2(COLOR_TOGGLE_DISABLED_FOR_TERM,
+ terminal);
+ else
+ HTUserMsg(COLOR_TOGGLE_DISABLED);
+ break;
+ }
+#endif
+ LYShowColor = LYChooseEnum((LYShowColor - 1),
+ L_Color,
+ C_COLOR,
+ bool_choices);
+ if (LYShowColor == 0) {
+ LYShowColor = SHOW_COLOR_OFF;
+ } else {
+ LYShowColor = SHOW_COLOR_ON;
+ }
+ } else { /* !no_option_save */
+ BOOLEAN again = FALSE;
+ int chosen;
+
+ /*
+ * Copy strings into choice array.
+ */
+ choices[0] = NULL;
+ StrAllocCopy(choices[0], "NEVER ");
+ choices[1] = NULL;
+ StrAllocCopy(choices[1], "OFF ");
+ choices[2] = NULL;
+ StrAllocCopy(choices[2], "ON ");
+ choices[3] = NULL;
+#if defined(COLOR_CURSES)
+ if (!has_colors())
+ StrAllocCopy(choices[3], "Always try");
+ else
+#endif
+ StrAllocCopy(choices[3], "ALWAYS ");
+ choices[4] = NULL;
+ do {
+ if (!LYSelectPopups) {
+ chosen = LYChooseEnum(LYChosenShowColor,
+ L_Color,
+ C_COLOR,
+ choices);
+ } else {
+ chosen = LYChoosePopup(LYChosenShowColor,
+ L_Color,
+ C_COLOR,
+ choices, 4, FALSE, FALSE);
+ }
+#if defined(COLOR_CURSES)
+ again = (BOOLEAN) (chosen == SHOW_COLOR_ON && !has_colors());
+ if (again) {
+ char *terminal = LYGetEnv("TERM");
+
+ if (terminal)
+ HTUserMsg2(COLOR_TOGGLE_DISABLED_FOR_TERM,
+ terminal);
+ else
+ HTUserMsg(COLOR_TOGGLE_DISABLED);
+ }
+#endif
+ } while (again);
+ LYChosenShowColor = chosen;
+#if defined(VMS)
+ if (LYSelectPopups) {
+ LYmove(L_Color, C_COLOR);
+ LYclrtoeol();
+ LYaddstr(choices[LYChosenShowColor]);
+ }
+#endif /* VMS */
+#if defined(COLOR_CURSES)
+ if (has_colors())
+#endif
+ LYShowColor = chosen;
+ FREE(choices[0]);
+ FREE(choices[1]);
+ FREE(choices[2]);
+ FREE(choices[3]);
+ }
+ if (CurrentShowColor != LYShowColor) {
+ lynx_force_repaint();
+ }
+ CurrentShowColor = LYShowColor;
+#ifdef USE_SLANG
+ SLtt_Use_Ansi_Colors = (LYShowColor > SHOW_COLOR_OFF ? TRUE : FALSE);
+#endif
+ response = ' ';
+ if (LYSelectPopups && !no_option_save) {
+ HANDLE_LYOPTIONS;
+ }
+ break;
+#endif /* USE_SLANG or COLOR_CURSES */
+
+ case '@': /* Change show cursor setting. */
+ LYShowCursor = LYChooseBoolean(LYShowCursor,
+ L_Bool_B,
+ C_SHOW_CURSOR,
+ bool_choices);
+ response = ' ';
+ break;
+
+ case 'K': /* Change keypad mode. */
+ if (!LYSelectPopups) {
+ keypad_mode = LYChooseEnum(keypad_mode,
+ L_Keypad, -1,
+ keypad_choices);
+ } else {
+ keypad_mode = LYChoosePopup(keypad_mode,
+ L_Keypad, -1,
+ keypad_choices,
+ 3, FALSE, FALSE);
+#if defined(VMS) || defined(USE_SLANG)
+ LYmove(L_Keypad, COL_OPTION_VALUES);
+ LYclrtoeol();
+ LYaddstr(keypad_choices[keypad_mode]);
+#endif /* VMS || USE_SLANG */
+ }
+ if (keypad_mode == NUMBERS_AS_ARROWS) {
+ set_numbers_as_arrows();
+ } else {
+ reset_numbers_as_arrows();
+ }
+ response = ' ';
+ if (LYSelectPopups) {
+ HANDLE_LYOPTIONS;
+ }
+ break;
+
+ case 'N': /* Change line editor key bindings. */
+ if (!LYSelectPopups) {
+ current_lineedit = LYChooseEnum(current_lineedit,
+ L_Lineed, -1,
+ LYEditorNames);
+ } else {
+ current_lineedit = LYChoosePopup(current_lineedit,
+ L_Lineed, -1,
+ LYEditorNames,
+ 0, FALSE, FALSE);
+#if defined(VMS) || defined(USE_SLANG)
+ LYmove(L_Lineed, COL_OPTION_VALUES);
+ LYclrtoeol();
+ LYaddstr(LYEditorNames[current_lineedit]);
+#endif /* VMS || USE_SLANG */
+ }
+ response = ' ';
+ if (LYSelectPopups) {
+ HANDLE_LYOPTIONS;
+ }
+ break;
+
+#ifdef EXP_KEYBOARD_LAYOUT
+ case 'Y': /* Change keyboard layout */
+ if (!LYSelectPopups) {
+ current_layout = LYChooseEnum(current_layout,
+ L_Layout, -1,
+ LYKbLayoutNames);
+ } else {
+ current_layout = LYChoosePopup(current_layout,
+ L_Layout, -1,
+ LYKbLayoutNames,
+ 0, FALSE, FALSE);
+#if defined(VMS) || defined(USE_SLANG)
+ LYmove(L_Layout, COL_OPTION_VALUES);
+ LYclrtoeol();
+ LYaddstr(LYKbLayoutNames[current_layout]);
+#endif /* VMS || USE_SLANG */
+ }
+ response = ' ';
+ if (LYSelectPopups) {
+ HANDLE_LYOPTIONS;
+ }
+ break;
+#endif /* EXP_KEYBOARD_LAYOUT */
+
+#ifdef DIRED_SUPPORT
+ case 'I': /* Change local directory sorting. */
+ if (!LYSelectPopups) {
+ dir_list_style = LYChooseEnum(dir_list_style,
+ L_Dired, -1,
+ dirList_choices);
+ } else {
+ dir_list_style = LYChoosePopup(dir_list_style,
+ L_Dired, -1,
+ dirList_choices,
+ 3, FALSE, FALSE);
+#if defined(VMS) || defined(USE_SLANG)
+ LYmove(L_Dired, COL_OPTION_VALUES);
+ LYclrtoeol();
+ LYaddstr(dirList_choices[dir_list_style]);
+#endif /* VMS || USE_SLANG */
+ }
+ response = ' ';
+ if (LYSelectPopups) {
+ HANDLE_LYOPTIONS;
+ }
+ break;
+#endif /* DIRED_SUPPORT */
+
+ case 'U': /* Change user mode. */
+ if (!LYSelectPopups) {
+ user_mode = LYChooseEnum(user_mode,
+ L_User_Mode, -1,
+ userMode_choices);
+ use_assume_charset = (BOOLEAN) (user_mode == ADVANCED_MODE);
+ } else {
+ user_mode = LYChoosePopup(user_mode,
+ L_User_Mode, -1,
+ userMode_choices,
+ 3, FALSE, FALSE);
+ use_assume_charset = (BOOLEAN) (user_mode == ADVANCED_MODE);
+#if defined(VMS) || defined(USE_SLANG)
+ if (use_assume_charset == old_use_assume_charset) {
+ LYmove(L_User_Mode, COL_OPTION_VALUES);
+ LYclrtoeol();
+ LYaddstr(userMode_choices[user_mode]);
+ }
+#endif /* VMS || USE_SLANG */
+ }
+ LYSetDisplayLines();
+ response = ' ';
+ if (LYSelectPopups) {
+ HANDLE_LYOPTIONS;
+ }
+ break;
+
+ case '!':
+ if (!LYSelectPopups) {
+ verbose_img = LYChooseBoolean(verbose_img,
+ L_VERBOSE_IMAGES,
+ C_VERBOSE_IMAGES,
+ bool_choices);
+ } else {
+ verbose_img = (BOOLEAN) LYChoosePopup(verbose_img,
+ L_VERBOSE_IMAGES,
+ C_VERBOSE_IMAGES,
+ bool_choices,
+ 2, FALSE, FALSE);
+ }
+ response = ' ';
+ if (LYSelectPopups) {
+ HANDLE_LYOPTIONS;
+ }
+ break;
+
+ case 'A': /* Change user agent string. */
+ if (!no_useragent) {
+ if (non_empty(LYUserAgent)) {
+ BStrCopy0(my_data, LYUserAgent);
+ } else { /* clear the NONE */
+ LYmove(L_HOME, COL_OPTION_VALUES);
+ LYaddstr(" ");
+ BStrCopy0(my_data, "");
+ }
+ _statusline(ACCEPT_DATA_OR_DEFAULT);
+ LYmove(L_User_Agent, COL_OPTION_VALUES);
+ lynx_start_bold();
+ ch = LYgetBString(&my_data, FALSE, 0, NORECALL);
+ lynx_stop_bold();
+ LYmove(L_User_Agent, COL_OPTION_VALUES);
+ if (term_options || ch == -1) {
+ LYaddstr((LYUserAgent &&
+ *LYUserAgent) ?
+ LYUserAgent : "NONE");
+ } else if (isBEmpty(my_data)) {
+ StrAllocCopy(LYUserAgent, LYUserAgentDefault);
+ LYaddstr((LYUserAgent &&
+ *LYUserAgent) ?
+ LYUserAgent : "NONE");
+ } else {
+ StrAllocCopy(LYUserAgent, my_data->str);
+ LYaddstr(LYUserAgent);
+ }
+ LYclrtoeol();
+ if (ch == -1) {
+ HTInfoMsg(CANCELLED);
+ HTInfoMsg("");
+ } else if (!LYCheckUserAgent()) {
+ _statusline(UA_PLEASE_USE_LYNX);
+ } else {
+ _statusline(VALUE_ACCEPTED);
+ }
+ } else { /* disallowed */
+ _statusline(UA_CHANGE_DISABLED);
+ }
+ response = ' ';
+ break;
+
+#if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS))
+ case 'X': /* Change local exec restriction. */
+ if (exec_frozen && !LYSelectPopups) {
+ _statusline(CHANGE_OF_SETTING_DISALLOWED);
+ response = ' ';
+ break;
+ }
+#ifndef NEVER_ALLOW_REMOTE_EXEC
+ if (local_exec) {
+ itmp = 2;
+ } else
+#endif /* !NEVER_ALLOW_REMOTE_EXEC */
+ {
+ if (local_exec_on_local_files) {
+ itmp = 1;
+ } else {
+ itmp = 0;
+ }
+ }
+ if (!LYSelectPopups) {
+ itmp = LYChooseEnum(itmp,
+ L_Exec, -1,
+ exec_choices);
+ } else {
+ itmp = LYChoosePopup(itmp,
+ L_Exec, -1,
+ exec_choices,
+ 0, (exec_frozen ? TRUE : FALSE),
+ FALSE);
+#if defined(VMS) || defined(USE_SLANG)
+ LYmove(L_Exec, COL_OPTION_VALUES);
+ LYclrtoeol();
+ LYaddstr(exec_choices[itmp]);
+#endif /* VMS || USE_SLANG */
+ }
+ if (!exec_frozen) {
+ switch (itmp) {
+ case 0:
+ local_exec = FALSE;
+ local_exec_on_local_files = FALSE;
+ break;
+ case 1:
+ local_exec = FALSE;
+ local_exec_on_local_files = TRUE;
+ break;
+#ifndef NEVER_ALLOW_REMOTE_EXEC
+ case 2:
+ local_exec = TRUE;
+ local_exec_on_local_files = FALSE;
+ break;
+#endif /* !NEVER_ALLOW_REMOTE_EXEC */
+ } /* end switch */
+ }
+ response = ' ';
+ if (LYSelectPopups) {
+ HANDLE_LYOPTIONS;
+ }
+ break;
+#endif /* ENABLE_OPTS_CHANGE_EXEC */
+
+ case '>': /* Save current options to RC file. */
+ if (!no_option_save) {
+ HTInfoMsg(SAVING_OPTIONS);
+ LYrcShowColor = LYChosenShowColor;
+ if (save_rc(NULL)) {
+ HTInfoMsg(OPTIONS_SAVED);
+ } else {
+ HTAlert(OPTIONS_NOT_SAVED);
+ }
+ } else {
+ HTInfoMsg(R_TO_RETURN_TO_LYNX);
+ /*
+ * Change response so that we don't exit the options menu.
+ */
+ response = ' ';
+ }
+ break;
+
+ case 'R': /* Return to document (quit options menu). */
+ break;
+
+ default:
+ if (!no_option_save) {
+ HTInfoMsg(SAVE_OR_R_TO_RETURN_TO_LYNX);
+ } else {
+ HTInfoMsg(R_TO_RETURN_TO_LYNX);
+ }
+ } /* end switch */
+ } /* end while */
+
+ term_options = FALSE;
+ LYStatusLine = -1; /* let user_mode have some of the screen */
+ signal(SIGINT, cleanup_sig);
+ BStrFree(my_data);
+ return;
+}
+
+static int widest_choice(STRING2PTR choices)
+{
+ int n, width = 0;
+
+ for (n = 0; choices[n] != NULL; ++n) {
+ int len = (int) strlen(choices[n]);
+
+ if (width < len)
+ width = len;
+ }
+ return width;
+}
+
+static void show_choice(const char *choice,
+ int width)
+{
+ int len = 0;
+
+ if (choice != 0) {
+ len = (int) strlen(choice);
+
+ LYaddstr(choice);
+ }
+ while (len++ < width)
+ LYaddch(' ');
+}
+
+/*
+ * Take a status code, prompt the user for a new status, and return it.
+ */
+static int boolean_choice(int cur_choice,
+ int line,
+ int column,
+ STRING2PTR choices)
+{
+ int response = 0;
+ int cmd = 0;
+ int number = 0;
+ int col = (column >= 0 ? column : COL_OPTION_VALUES);
+ int orig_choice = cur_choice;
+ int width = widest_choice(choices);
+
+ /*
+ * Get the number of choices and then make number zero-based.
+ */
+ for (number = 0; choices[number] != NULL; number++) ; /* empty loop body */
+ number--;
+
+ /*
+ * Update the statusline.
+ */
+ _statusline(ANY_KEY_CHANGE_RET_ACCEPT);
+
+ /*
+ * Highlight the current choice.
+ */
+ LYmove(line, col);
+ lynx_start_reverse();
+ show_choice(choices[cur_choice], width);
+ if (LYShowCursor)
+ LYmove(line, (col - 1));
+ LYrefresh();
+
+ /*
+ * Get the keyboard entry, and leave the cursor at the choice, to indicate
+ * that it can be changed, until the user accepts the current choice.
+ */
+ term_options = FALSE;
+ while (1) {
+ LYmove(line, col);
+ if (term_options == FALSE) {
+ response = LYgetch_single();
+ }
+ if (term_options || LYCharIsINTERRUPT_NO_letter(response)) {
+ /*
+ * Control-C or Control-G.
+ */
+ response = '\n';
+ term_options = TRUE;
+ cur_choice = orig_choice;
+ }
+#ifdef VMS
+ if (HadVMSInterrupt) {
+ HadVMSInterrupt = FALSE;
+ response = '\n';
+ term_options = TRUE;
+ cur_choice = orig_choice;
+ }
+#endif /* VMS */
+ if ((response != '\n' && response != '\r') &&
+ (cmd = LKC_TO_LAC(keymap, response)) != LYK_ACTIVATE) {
+ switch (cmd) {
+ case LYK_HOME:
+ cur_choice = 0;
+ break;
+
+ case LYK_END:
+ cur_choice = number;
+ break;
+
+ case LYK_REFRESH:
+ lynx_force_repaint();
+ LYrefresh();
+ break;
+
+ case LYK_QUIT:
+ case LYK_ABORT:
+ case LYK_PREV_DOC:
+ cur_choice = orig_choice;
+ term_options = TRUE;
+ break;
+
+ case LYK_PREV_PAGE:
+ case LYK_UP_HALF:
+ case LYK_UP_TWO:
+ case LYK_PREV_LINK:
+ case LYK_LPOS_PREV_LINK:
+ case LYK_FASTBACKW_LINK:
+ case LYK_UP_LINK:
+ case LYK_LEFT_LINK:
+ if (cur_choice == 0)
+ cur_choice = number; /* go back to end */
+ else
+ cur_choice--;
+ break;
+
+ case LYK_1:
+ case LYK_2:
+ case LYK_3:
+ case LYK_4:
+ case LYK_5:
+ case LYK_6:
+ case LYK_7:
+ case LYK_8:
+ case LYK_9:
+ if ((cmd - LYK_1 + 1) <= number) {
+ cur_choice = cmd - LYK_1 + 1;
+ break;
+ } /* else fall through! */
+ default:
+ if (cur_choice == number)
+ cur_choice = 0; /* go over the top and around */
+ else
+ cur_choice++;
+ } /* end of switch */
+ show_choice(choices[cur_choice], width);
+ if (LYShowCursor)
+ LYmove(line, (col - 1));
+ LYrefresh();
+ } else {
+ /*
+ * Unhighlight choice.
+ */
+ LYmove(line, col);
+ lynx_stop_reverse();
+ show_choice(choices[cur_choice], width);
+
+ if (term_options) {
+ term_options = FALSE;
+ HTInfoMsg(CANCELLED);
+ HTInfoMsg("");
+ } else {
+ _statusline(VALUE_ACCEPTED);
+ }
+ return cur_choice;
+ }
+ }
+}
+#endif /* !NO_OPTION_MENU */
+
+static void terminate_options(int sig GCC_UNUSED)
+{
+ term_options = TRUE;
+ /*
+ * Reassert the AST.
+ */
+ signal(SIGINT, terminate_options);
+#ifdef VMS
+ /*
+ * Refresh the screen to get rid of the "interrupt" message.
+ */
+ if (!dump_output_immediately) {
+ lynx_force_repaint();
+ LYrefresh();
+ }
+#endif /* VMS */
+}
+
+/*
+ * Multi-Bookmark On-Line editing support. - FMG & FM
+ */
+void edit_bookmarks(void)
+{
+ int response = 0, def_response = 0;
+ int MBM_current = 1;
+
+#define MULTI_OFFSET 8
+ int a; /* misc counter */
+ bstring *my_data = NULL;
+
+ /*
+ * We need (MBM_V_MAXFILES + MULTI_OFFSET) lines to display the whole list
+ * at once. Otherwise break it up into two segments. We know it won't be
+ * less than that because 'o'ptions needs 23-24 at LEAST.
+ */
+ term_options = FALSE;
+ signal(SIGINT, terminate_options);
+
+ draw_bookmark_list:
+ /*
+ * Display menu of bookmarks. NOTE that we avoid printw()'s to increase
+ * the chances that any non-ASCII or multibyte/CJK characters will be
+ * handled properly. - FM
+ */
+#if defined(FANCY_CURSES) || defined (USE_SLANG)
+ if (enable_scrollback) {
+ LYclear();
+ } else {
+ LYerase();
+ }
+#else
+ LYclear();
+#endif /* FANCY_CURSES || USE_SLANG */
+ LYmove(0, 5);
+ lynx_start_h1_color();
+ if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) {
+ char *ehead_buffer = 0;
+
+ HTSprintf0(&ehead_buffer, MULTIBOOKMARKS_EHEAD_MASK, MBM_current);
+ LYaddstr(ehead_buffer);
+ FREE(ehead_buffer);
+ } else {
+ LYaddstr(MULTIBOOKMARKS_EHEAD);
+ }
+ lynx_stop_h1_color();
+
+ if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) {
+ for (a = ((MBM_V_MAXFILES / 2 + 1) * (MBM_current - 1));
+ a <= (MBM_current * MBM_V_MAXFILES / 2); a++) {
+ LYmove((3 + a) - ((MBM_V_MAXFILES / 2 + 1) * (MBM_current - 1)), 5);
+ LYaddch(UCH(LYindex2MBM(a)));
+ LYaddstr(" : ");
+ if (MBM_A_subdescript[a])
+ LYaddstr(MBM_A_subdescript[a]);
+ LYmove((3 + a) - ((MBM_V_MAXFILES / 2 + 1) * (MBM_current - 1)), 35);
+ LYaddstr("| ");
+ if (MBM_A_subbookmark[a]) {
+ LYaddstr(MBM_A_subbookmark[a]);
+ }
+ }
+ } else {
+ for (a = 0; a <= MBM_V_MAXFILES; a++) {
+ LYmove(3 + a, 5);
+ LYaddch(UCH(LYindex2MBM(a)));
+ LYaddstr(" : ");
+ if (MBM_A_subdescript[a])
+ LYaddstr(MBM_A_subdescript[a]);
+ LYmove(3 + a, 35);
+ LYaddstr("| ");
+ if (MBM_A_subbookmark[a]) {
+ LYaddstr(MBM_A_subbookmark[a]);
+ }
+ }
+ }
+
+ /*
+ * Only needed when we have 2 screens.
+ */
+ if (LYlines < MBM_V_MAXFILES + MULTI_OFFSET) {
+ LYmove((LYlines - 4), 0);
+ LYaddstr("'");
+ lynx_start_bold();
+ LYaddstr("[");
+ lynx_stop_bold();
+ LYaddstr("' ");
+ LYaddstr(PREVIOUS);
+ LYaddstr(", '");
+ lynx_start_bold();
+ LYaddstr("]");
+ lynx_stop_bold();
+ LYaddstr("' ");
+ LYaddstr(NEXT_SCREEN);
+ }
+
+ LYmove((LYlines - 3), 0);
+ if (!no_option_save) {
+ LYaddstr("'");
+ lynx_start_bold();
+ LYaddstr(">");
+ lynx_stop_bold();
+ LYaddstr("'");
+ LYaddstr(TO_SAVE_SEGMENT);
+ }
+ LYaddstr(OR_SEGMENT);
+ LYaddstr("'");
+ lynx_start_bold();
+ LYaddstr("^G");
+ lynx_stop_bold();
+ LYaddstr("'");
+ LYaddstr(TO_RETURN_SEGMENT);
+
+ while (!term_options &&
+ !LYisNonAlnumKeyname(response, LYK_PREV_DOC) &&
+ !LYCharIsINTERRUPT_NO_letter(response) && response != '>') {
+
+ LYmove((LYlines - 2), 0);
+ lynx_start_prompt_color();
+ LYaddstr(MULTIBOOKMARKS_LETTER);
+ lynx_stop_prompt_color();
+
+ LYrefresh();
+ response = (def_response ? def_response : LYgetch_single());
+ def_response = 0;
+
+ /*
+ * Check for a cancel.
+ */
+ if (term_options || LYCharIsINTERRUPT_NO_letter(response) ||
+ LYisNonAlnumKeyname(response, LYK_PREV_DOC))
+ continue;
+
+ /*
+ * Check for a save.
+ */
+ if (response == '>') {
+ if (!no_option_save) {
+ HTInfoMsg(SAVING_OPTIONS);
+ if (save_rc(NULL))
+ HTInfoMsg(OPTIONS_SAVED);
+ else
+ HTAlert(OPTIONS_NOT_SAVED);
+ } else {
+ HTInfoMsg(R_TO_RETURN_TO_LYNX);
+ /*
+ * Change response so that we don't exit the options menu.
+ */
+ response = ' ';
+ }
+ continue;
+ }
+
+ /*
+ * Check for a refresh.
+ */
+ if (LYisNonAlnumKeyname(response, LYK_REFRESH)) {
+ lynx_force_repaint();
+ continue;
+ }
+
+ /*
+ * Move between the screens - if we can't show it all at once.
+ */
+ if ((response == ']' ||
+ LYisNonAlnumKeyname(response, LYK_NEXT_PAGE)) &&
+ LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) {
+ MBM_current++;
+ if (MBM_current >= 3)
+ MBM_current = 1;
+ goto draw_bookmark_list;
+ }
+ if ((response == '[' ||
+ LYisNonAlnumKeyname(response, LYK_PREV_PAGE)) &&
+ LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) {
+ MBM_current--;
+ if (MBM_current <= 0)
+ MBM_current = 2;
+ goto draw_bookmark_list;
+ }
+
+ /*
+ * Instead of using 26 case statements, we set up a scan through the
+ * letters and edit the lines that way.
+ */
+ for (a = 0; a <= MBM_V_MAXFILES; a++) {
+ if (LYMBM2index(response) == a) {
+ if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) {
+ if (MBM_current == 1 && a > (MBM_V_MAXFILES / 2)) {
+ MBM_current = 2;
+ def_response = response;
+ goto draw_bookmark_list;
+ }
+ if (MBM_current == 2 && a < (MBM_V_MAXFILES / 2)) {
+ MBM_current = 1;
+ def_response = response;
+ goto draw_bookmark_list;
+ }
+ }
+ _statusline(ACCEPT_DATA);
+
+ if (a > 0) {
+ lynx_start_bold();
+ if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET))
+ LYmove((3 + a)
+ - ((MBM_V_MAXFILES / 2 + 1) * (MBM_current - 1)),
+ 9);
+ else
+ LYmove((3 + a), 9);
+ BStrCopy0(my_data,
+ (!MBM_A_subdescript[a] ?
+ "" : MBM_A_subdescript[a]));
+ (void) LYgetBString(&my_data, FALSE, 0, NORECALL);
+ lynx_stop_bold();
+
+ if (isBEmpty(my_data)) {
+ FREE(MBM_A_subdescript[a]);
+ } else {
+ StrAllocCopy(MBM_A_subdescript[a], my_data->str);
+ }
+ if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET))
+ LYmove((3 + a)
+ - ((MBM_V_MAXFILES / 2 + 1)
+ * (MBM_current - 1)),
+ 5);
+ else
+ LYmove((3 + a), 5);
+ LYaddch(UCH(LYindex2MBM(a)));
+ LYaddstr(" : ");
+ if (MBM_A_subdescript[a])
+ LYaddstr(MBM_A_subdescript[a]);
+ LYclrtoeol();
+ LYrefresh();
+ }
+
+ if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET))
+ LYmove((3 + a)
+ - ((MBM_V_MAXFILES / 2 + 1)
+ * (MBM_current - 1)),
+ 35);
+ else
+ LYmove((3 + a), 35);
+ LYaddstr("| ");
+
+ lynx_start_bold();
+ BStrCopy0(my_data, NonNull(MBM_A_subbookmark[a]));
+ (void) LYgetBString(&my_data, FALSE, 0, NORECALL);
+ lynx_stop_bold();
+
+ if (isBEmpty(my_data)) {
+ if (a == 0)
+ StrAllocCopy(MBM_A_subbookmark[a], bookmark_page);
+ else
+ FREE(MBM_A_subbookmark[a]);
+ } else {
+ BStrAlloc(my_data, my_data->len + LY_MAXPATH);
+ if (!LYPathOffHomeOK(my_data->str, (size_t) my_data->len)) {
+ LYMBM_statusline(USE_PATH_OFF_HOME);
+ LYSleepAlert();
+ } else {
+ StrAllocCopy(MBM_A_subbookmark[a], my_data->str);
+ if (a == 0) {
+ StrAllocCopy(bookmark_page, MBM_A_subbookmark[a]);
+ }
+ }
+ }
+ if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET))
+ LYmove((3 + a)
+ - ((MBM_V_MAXFILES / 2 + 1)
+ * (MBM_current - 1)),
+ 35);
+ else
+ LYmove((3 + a), 35);
+ LYaddstr("| ");
+ if (MBM_A_subbookmark[a])
+ LYaddstr(MBM_A_subbookmark[a]);
+ LYclrtoeol();
+ LYParkCursor();
+ break;
+ }
+ } /* end for */
+ } /* end while */
+
+ BStrFree(my_data);
+ term_options = FALSE;
+ signal(SIGINT, cleanup_sig);
+}
+
+#if defined(USE_CURSES_PADS) || !defined(NO_OPTION_MENU) || (defined(USE_MOUSE) && (defined(NCURSES) || defined(PDCURSES)))
+
+/*
+ * This function offers the choices for values of an option via a popup window
+ * which functions like that for selection of options in a form. - FM
+ *
+ * Also used for mouse popups with ncurses; this is indicated by for_mouse.
+ */
+int popup_choice(int cur_choice,
+ int line,
+ int column,
+ STRING2PTR choices,
+ int i_length,
+ int disabled,
+ int for_mouse)
+{
+ if (column < 0)
+ column = (COL_OPTION_VALUES - 1);
+
+ term_options = FALSE;
+ cur_choice = LYhandlePopupList(cur_choice,
+ line,
+ column,
+ (STRING2PTR) choices,
+ -1,
+ i_length,
+ disabled,
+ for_mouse);
+ switch (cur_choice) {
+ case LYK_QUIT:
+ case LYK_ABORT:
+ case LYK_PREV_DOC:
+ term_options = TRUE;
+ if (!for_mouse) {
+ HTUserMsg(CANCELLED);
+ }
+ break;
+ }
+
+ if (disabled || term_options) {
+ _statusline("");
+ } else if (!for_mouse) {
+ _statusline(VALUE_ACCEPTED);
+ }
+ return (cur_choice);
+}
+
+#endif /* !NO_OPTION_MENU */
+#ifndef NO_OPTION_FORMS
+
+/*
+ * I'm paranoid about mistyping strings. Also, this way they get combined
+ * so we don't have to worry about the intelligence of the compiler.
+ * We don't need to burn memory like it's cheap. We're better than that.
+ */
+#define SELECTED(flag) (flag) ? selected_string : ""
+#define DISABLED(flag) (flag) ? disabled_string : ""
+
+typedef struct {
+ int value;
+ const char *LongName;
+ const char *HtmlName;
+} OptValues;
+
+#define END_OPTIONS {0, 0, 0}
+
+#define HasOptValues(table) (((table) != NULL) && ((table)->LongName != NULL))
+
+typedef struct {
+ char *tag;
+ char *value;
+} PostPair;
+
+static const char selected_string[] = "selected";
+static const char disabled_string[] = "disabled";
+static const char on_string[] = N_("ON");
+static const char off_string[] = N_("OFF");
+static const char never_string[] = N_("NEVER");
+static const char always_string[] = N_("ALWAYS");
+static OptValues bool_values[] =
+{
+ {FALSE, N_("OFF"), "OFF"},
+ {TRUE, N_("ON"), "ON"},
+ END_OPTIONS
+};
+
+static const char *secure_string = "secure";
+static char *secure_value = NULL;
+static const char *save_options_string = "save_options";
+
+/*
+ * Personal Preferences
+ */
+static const char *cookies_string = RC_SET_COOKIES;
+static const char *cookies_ignore_all_string = N_("ignore");
+static const char *cookies_up_to_user_string = N_("ask user");
+static const char *cookies_accept_all_string = N_("accept all");
+static const char *x_display_string = RC_DISPLAY;
+static const char *editor_string = RC_FILE_EDITOR;
+static const char *emacs_keys_string = RC_EMACS_KEYS;
+
+#if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS))
+#define EXEC_ALWAYS 2
+#define EXEC_LOCAL 1
+#define EXEC_NEVER 0
+static const char *exec_links_string = RC_RUN_ALL_EXECUTION_LINKS;
+static OptValues exec_links_values[] =
+{
+ {EXEC_NEVER, N_("ALWAYS OFF"), "ALWAYS OFF"},
+ {EXEC_LOCAL, N_("FOR LOCAL FILES ONLY"), "FOR LOCAL FILES ONLY"},
+#ifndef NEVER_ALLOW_REMOTE_EXEC
+ {EXEC_ALWAYS, N_("ALWAYS ON"), "ALWAYS ON"},
+#endif
+ END_OPTIONS
+};
+#endif /* ENABLE_OPTS_CHANGE_EXEC */
+
+#ifdef EXP_KEYBOARD_LAYOUT
+static const char *kblayout_string = RC_KBLAYOUT;
+#endif
+static const char *keypad_mode_string = RC_KEYPAD_MODE;
+static OptValues keypad_mode_values[] =
+{
+ {NUMBERS_AS_ARROWS, N_("Numbers act as arrows"),
+ "number_arrows"},
+ {LINKS_ARE_NUMBERED, N_("Links are numbered"),
+ "links_numbered"},
+ {LINKS_AND_FIELDS_ARE_NUMBERED,
+ N_("Links and form fields are numbered"),
+ "links_and_forms"},
+ {FIELDS_ARE_NUMBERED,
+ N_("Form fields are numbered"),
+ "forms_numbered"},
+ END_OPTIONS
+};
+static const char *lineedit_mode_string = RC_LINEEDIT_MODE;
+static const char *mail_address_string = RC_PERSONAL_MAIL_ADDRESS;
+static const char *personal_name_string = RC_PERSONAL_MAIL_NAME;
+static const char *search_type_string = RC_CASE_SENSITIVE_SEARCHING;
+
+#ifndef DISABLE_FTP
+static const char *anonftp_password_string = RC_ANONFTP_PASSWORD;
+#endif
+
+static OptValues search_type_values[] =
+{
+ {FALSE, N_("Case insensitive"), "case_insensitive"},
+ {TRUE, N_("Case sensitive"), "case_sensitive"},
+ END_OPTIONS
+};
+
+#if defined(USE_SLANG) || defined(COLOR_CURSES)
+static const char *show_color_string = RC_SHOW_COLOR;
+static OptValues show_color_values[] =
+{
+ {SHOW_COLOR_NEVER, never_string, never_string},
+ {SHOW_COLOR_OFF, off_string, off_string},
+ {SHOW_COLOR_ON, on_string, on_string},
+ {SHOW_COLOR_ALWAYS, always_string, always_string},
+ END_OPTIONS
+};
+#endif
+
+#ifdef USE_COLOR_STYLE
+static const char *color_style_string = RC_COLOR_STYLE;
+static OptValues *color_style_values;
+static HTList *color_style_list;
+#endif
+
+#ifdef USE_DEFAULT_COLORS
+static const char *default_colors_string = RC_DEFAULT_COLORS;
+#endif
+
+static const char *show_cursor_string = RC_SHOW_CURSOR;
+
+static const char *underline_links_string = RC_UNDERLINE_LINKS;
+
+#ifdef USE_SCROLLBAR
+static const char *show_scrollbar_string = RC_SCROLLBAR;
+#endif
+
+static const char prompt_dft_string[] = N_("prompt normally");
+static const char prompt_yes_string[] = N_("force yes-response");
+static const char prompt_no_string[] = N_("force no-response");
+static OptValues prompt_values[] =
+{
+ {FORCE_PROMPT_DFT, prompt_dft_string, prompt_dft_string},
+ {FORCE_PROMPT_YES, prompt_yes_string, prompt_yes_string},
+ {FORCE_PROMPT_NO, prompt_no_string, prompt_no_string},
+ END_OPTIONS
+};
+static const char *cookie_prompt_string = RC_FORCE_COOKIE_PROMPT;
+
+static const char RFC_2109_string[] = N_("RFC 2109");
+static const char RFC_2965_string[] = N_("RFC 2965");
+static const char RFC_6265_string[] = N_("RFC 6265");
+static OptValues cookies_values[] =
+{
+ {COOKIES_RFC_2109, RFC_2109_string, RFC_2109_string},
+ {COOKIES_RFC_2965, RFC_2965_string, RFC_2965_string},
+ {COOKIES_RFC_6265, RFC_6265_string, RFC_6265_string},
+ END_OPTIONS
+};
+static const char *cookie_version_string = RC_COOKIE_VERSION;
+
+#ifdef USE_SSL
+static const char *ssl_prompt_string = RC_FORCE_SSL_PROMPT;
+#endif
+
+static const char *user_mode_string = RC_USER_MODE;
+static OptValues user_mode_values[] =
+{
+ {NOVICE_MODE, N_("Novice"), "Novice"},
+ {INTERMEDIATE_MODE, N_("Intermediate"), "Intermediate"},
+ {ADVANCED_MODE, N_("Advanced"), "Advanced"},
+ {MINIMAL_MODE, N_("Minimal"), "Minimal"},
+ END_OPTIONS
+};
+
+static const char *vi_keys_string = RC_VI_KEYS;
+
+static const char *visited_links_string = RC_VISITED_LINKS;
+static OptValues visited_links_values[] =
+{
+ {VISITED_LINKS_AS_FIRST_V, N_("By First Visit"), "first_visited"},
+ {VISITED_LINKS_AS_FIRST_V | VISITED_LINKS_REVERSE,
+ N_("By First Visit Reversed"), "first_visited_reversed"},
+ {VISITED_LINKS_AS_TREE, N_("As Visit Tree"), "visit_tree"},
+ {VISITED_LINKS_AS_LATEST, N_("By Last Visit"), "last_visited"},
+ {VISITED_LINKS_AS_LATEST | VISITED_LINKS_REVERSE,
+ N_("By Last Visit Reversed"), "last_visited_reversed"},
+ END_OPTIONS
+};
+
+/*
+ * Document Layout
+ */
+static const char *DTD_recovery_string = RC_TAGSOUP;
+static OptValues DTD_type_values[] =
+{
+ /* Old_DTD variable */
+ {TRUE, N_("relaxed (TagSoup mode)"), "tagsoup"},
+ {FALSE, N_("strict (SortaSGML mode)"), "sortasgml"},
+ END_OPTIONS
+};
+
+static const char *bad_html_string = RC_BAD_HTML;
+static OptValues bad_html_values[] =
+{
+ {BAD_HTML_IGNORE, N_("Ignore"), "ignore"},
+ {BAD_HTML_TRACE, N_("Add to trace-file"), "trace"},
+ {BAD_HTML_MESSAGE, N_("Add to LYNXMESSAGES"), "message"},
+ {BAD_HTML_WARN, N_("Warn, point to trace-file"), "warn"},
+ END_OPTIONS
+};
+
+static const char *select_popups_string = RC_SELECT_POPUPS;
+static const char *images_string = "images";
+static const char *images_ignore_all_string = N_("ignore");
+static const char *images_use_label_string = N_("as labels");
+static const char *images_use_links_string = N_("as links");
+
+static const char *verbose_images_string = RC_VERBOSE_IMAGES;
+static OptValues verbose_images_type_values[] =
+{
+ /* verbose_img variable */
+ {FALSE, N_("OFF"), "OFF"},
+ {TRUE, N_("show filename"), "ON"},
+ END_OPTIONS
+};
+
+static const char *collapse_br_tags_string = RC_COLLAPSE_BR_TAGS;
+static OptValues collapse_br_tags_values[] =
+{
+ /* LYCollapseBRs variable */
+ {FALSE, N_("OFF"), "OFF"},
+ {TRUE, N_("collapse"), "ON"},
+ END_OPTIONS
+};
+
+static const char *trim_blank_lines_string = RC_TRIM_BLANK_LINES;
+static OptValues trim_blank_lines_values[] =
+{
+ /* LYtrimBlankLines variable */
+ {FALSE, N_("OFF"), "OFF"},
+ {TRUE, N_("trim-lines"), "ON"},
+ END_OPTIONS
+};
+
+/*
+ * Bookmark Options
+ */
+static const char *mbm_string = RC_MULTI_BOOKMARK;
+static OptValues mbm_values[] =
+{
+ {MBM_OFF, N_("OFF"), "OFF"},
+ {MBM_STANDARD, N_("STANDARD"), "STANDARD"},
+ {MBM_ADVANCED, N_("ADVANCED"), "ADVANCED"},
+ END_OPTIONS
+};
+
+static const char *single_bookmark_string = RC_BOOKMARK_FILE;
+
+#ifdef USE_SESSIONS
+static const char *auto_session_string = RC_AUTO_SESSION;
+static const char *single_session_string = RC_SESSION_FILE;
+#endif
+
+/*
+ * Character Set Options
+ */
+static const char *assume_char_set_string = RC_ASSUME_CHARSET;
+static const char *display_char_set_string = RC_CHARACTER_SET;
+static const char *raw_mode_string = RC_RAW_MODE;
+
+#ifdef USE_IDN2
+static const char *idna_mode_string = RC_IDNA_MODE;
+static OptValues idna_values[] =
+{
+ {LYidna2003, N_("IDNA 2003"), "idna2003"},
+ {LYidna2008, N_("IDNA 2008"), "idna2008"},
+ {LYidnaTR46, N_("IDNA TR46"), "idnaTR46"},
+ {LYidnaCompat, N_("IDNA Compatible"), "idnaCompat"},
+ END_OPTIONS
+};
+#endif
+
+#ifdef USE_LOCALE_CHARSET
+static const char *locale_charset_string = RC_LOCALE_CHARSET;
+#endif
+
+static const char *html5_charsets_string = RC_HTML5_CHARSETS;
+
+/*
+ * File Management Options
+ */
+static const char *show_dotfiles_string = RC_SHOW_DOTFILES;
+static const char *no_pause_string = RC_NO_PAUSE;
+
+#ifdef DIRED_SUPPORT
+static const char *dired_list_string = RC_DIR_LIST_STYLE;
+static OptValues dired_list_values[] =
+{
+ {DIRS_FIRST, N_("Directories first"), "dired_dir"},
+ {FILES_FIRST, N_("Files first"), "dired_files"},
+ {MIXED_STYLE, N_("Mixed style"), "dired_mixed"},
+ END_OPTIONS
+};
+
+#ifdef LONG_LIST
+static const char *dired_sort_string = RC_DIR_LIST_ORDER;
+static OptValues dired_sort_values[] =
+{
+ {ORDER_BY_NAME, N_("By Name"), "dired_by_name"},
+ {ORDER_BY_TYPE, N_("By Type"), "dired_by_type"},
+ {ORDER_BY_SIZE, N_("By Size"), "dired_by_size"},
+ {ORDER_BY_DATE, N_("By Date"), "dired_by_date"},
+ {ORDER_BY_MODE, N_("By Mode"), "dired_by_mode"},
+#ifndef NO_GROUPS
+ {ORDER_BY_USER, N_("By User"), "dired_by_user"},
+ {ORDER_BY_GROUP, N_("By Group"), "dired_by_group"},
+#endif
+ END_OPTIONS
+};
+#endif /* LONG_LIST */
+#endif /* DIRED_SUPPORT */
+
+#ifndef DISABLE_FTP
+static const char *passive_ftp_string = RC_FTP_PASSIVE;
+
+static const char *ftp_sort_string = RC_FILE_SORTING_METHOD;
+static OptValues ftp_sort_values[] =
+{
+ {FILE_BY_NAME, N_("By Name"), "ftp_by_name"},
+ {FILE_BY_TYPE, N_("By Type"), "ftp_by_type"},
+ {FILE_BY_SIZE, N_("By Size"), "ftp_by_size"},
+ {FILE_BY_DATE, N_("By Date"), "ftp_by_date"},
+ END_OPTIONS
+};
+#endif
+
+#ifdef USE_READPROGRESS
+static const char *show_rate_string = RC_SHOW_KB_RATE;
+static OptValues rate_values[] =
+{
+ {rateOFF, N_("Do not show rate"), "rate_off"},
+ {rateBYTES, N_("Show %s/sec rate"), "rate_bytes"},
+ {rateKB, N_("Show %s/sec rate"), "rate_kb"},
+#ifdef USE_READPROGRESS
+ {rateEtaBYTES, N_("Show %s/sec, ETA"), "rate_eta_bytes"},
+ {rateEtaKB, N_("Show %s/sec, ETA"), "rate_eta_kb"},
+ {rateEtaBYTES2, N_("Show %s/sec (2-digits), ETA"), "rate_eta_bytes2"},
+ {rateEtaKB2, N_("Show %s/sec (2-digits), ETA"), "rate_eta_kb2"},
+#endif
+#ifdef USE_PROGRESSBAR
+ {rateBAR, N_("Show progressbar"), "rate_bar"},
+#endif
+ END_OPTIONS
+};
+#endif /* USE_READPROGRESS */
+
+static const char *preferred_content_string = RC_PREFERRED_CONTENT_TYPE;
+static OptValues content_values[] =
+{
+ {contentBINARY, STR_BINARY, STR_BINARY},
+ {contentTEXT, STR_PLAINTEXT, STR_PLAINTEXT},
+ {contentHTML, STR_HTML, STR_HTML},
+ END_OPTIONS
+};
+
+/*
+ * Presentation (MIME) types used in "Accept".
+ */
+static const char *preferred_media_string = RC_PREFERRED_MEDIA_TYPES;
+static OptValues media_values[] =
+{
+ {mediaOpt1, N_("Accept lynx's internal types"), "media_opt1"},
+ {mediaOpt2, N_("Also accept lynx.cfg's types"), "media_opt2"},
+ {mediaOpt3, N_("Also accept user's types"), "media_opt3"},
+ {mediaOpt4, N_("Also accept system's types"), "media_opt4"},
+ {mediaALL, N_("Accept all types"), "media_all"},
+ END_OPTIONS
+};
+
+static const char *preferred_encoding_string = RC_PREFERRED_ENCODING;
+static OptValues encoding_values[] =
+{
+ {encodingNONE, N_("None"), "encoding_none"},
+#if defined(USE_ZLIB) || defined(GZIP_PATH)
+ {encodingGZIP, N_("gzip"), "encoding_gzip"},
+ {encodingDEFLATE, N_("deflate"), "encoding_deflate"},
+#endif
+#if defined(USE_ZLIB) || defined(COMPRESS_PATH)
+ {encodingCOMPRESS, N_("compress"), "encoding_compress"},
+#endif
+#if defined(USE_BZLIB) || defined(BZIP2_PATH)
+ {encodingBZIP2, N_("bzip2"), "encoding_bzip2"},
+#endif
+#if defined(USE_BROTLI) || defined(BROTLI_PATH)
+ {encodingBROTLI, N_("brotli"), "encoding_brotli"},
+#endif
+ {encodingALL, N_("All"), "encoding_all"},
+ END_OPTIONS
+};
+
+/*
+ * Headers transferred to remote server
+ */
+static const char *http_protocol_string = RC_HTTP_PROTOCOL;
+static OptValues http_protocol_values[] =
+{
+ {HTTP_1_0, N_("HTTP 1.0"), "HTTP_1_0"},
+ {HTTP_1_1, N_("HTTP 1.1"), "HTTP_1_1"},
+ END_OPTIONS
+};
+
+static const char *preferred_doc_char_string = RC_PREFERRED_CHARSET;
+static const char *preferred_doc_lang_string = RC_PREFERRED_LANGUAGE;
+static const char *send_user_agent_string = RC_SEND_USERAGENT;
+static const char *user_agent_string = RC_USERAGENT;
+
+static const char *ssl_client_certificate_file = RC_SSL_CLIENT_CERT_FILE;
+static const char *ssl_client_key_file = RC_SSL_CLIENT_KEY_FILE;
+
+#define PutHeader(fp, Name) \
+ fprintf(fp, "\n%s<em>%s</em>\n", MARGIN_STR, LYEntifyTitle(&buffer, Name));
+
+#define PutCheckBox(fp, Name, Value, disable) \
+ fprintf(fp,\
+ "<input type=\"checkbox\" name=\"%s\" %s %s>\n",\
+ Name, Value ? "checked" : "", disable_all?disabled_string:disable)
+
+#define PutTextInput(fp, Name, Value, Size, disable) \
+ fprintf(fp,\
+ "<input size=%d type=\"text\" name=\"%s\" value=\"%s\" %s>\n",\
+ (int) Size, Name, Value, disable_all?disabled_string:disable)
+
+#define PutOption(fp, flag, html, name) \
+ fprintf(fp,"<option value=\"%s\" %s>%s\n", html, SELECTED(flag), gettext(name))
+
+#define BeginSelect(fp, text) \
+ fprintf(fp,"<select name=\"%s\" %s>\n", text, disable_all?disabled_string:"")
+
+#define MaybeSelect(fp, flag, text) \
+ fprintf(fp,"<select name=\"%s\" %s>\n", text, disable_all?disabled_string:DISABLED(flag))
+
+#define EndSelect(fp)\
+ fprintf(fp,"</select>\n")
+
+static void PutOptValues(FILE *fp, int value,
+ OptValues * table)
+{
+ while (table->LongName != 0) {
+ if (table->HtmlName) {
+ PutOption(fp,
+ value == table->value,
+ table->HtmlName,
+ table->LongName);
+ }
+ table++;
+ }
+}
+
+static BOOLEAN GetOptValues(OptValues * table, char *value,
+ int *result)
+{
+ while (table->LongName != 0) {
+ if (table->HtmlName && !strcmp(value, table->HtmlName)) {
+ *result = table->value;
+ return TRUE;
+ }
+ table++;
+ }
+ return FALSE;
+}
+
+#ifdef USE_COLOR_STYLE
+#ifdef LY_FIND_LEAKS
+void free_colorstyle_leaks(void)
+{
+ FREE(color_style_values);
+}
+#endif
+
+void build_lss_enum(HTList *list)
+{
+ int count = HTList_count(list);
+
+#ifdef LY_FIND_LEAKS
+ atexit(free_colorstyle_leaks);
+#endif
+
+ FREE(color_style_values);
+ if (count != 0) {
+ LSS_NAMES *obj;
+ int position = 0;
+
+ color_style_values = typecallocn(OptValues, count + 2);
+
+ if (color_style_values == NULL)
+ outofmem(__FILE__, "build_lss_enum");
+
+ color_style_values[position++] = bool_values[0];
+ while ((obj = HTList_objectAt(list, position - 1)) != 0) {
+ color_style_values[position].value = position;
+ color_style_values[position].LongName = obj->given;
+ color_style_values[position].HtmlName = obj->given;
+ position++;
+ }
+ }
+ color_style_list = list;
+}
+
+/*
+ * Find the current lss-file in the list, to get the default value for the
+ * form.
+ */
+static int get_color_style_value(void)
+{
+ int result = 0;
+
+ if (LYuse_color_style && non_empty(lynx_lss_file)) {
+ LSS_NAMES *obj;
+ int position = 1;
+
+ while ((obj = HTList_objectAt(color_style_list, position - 1)) != 0) {
+ if (obj->actual != 0 && !strcmp(obj->actual, lynx_lss_file)) {
+ result = position;
+ break;
+ } else if (!strcmp(obj->given, lynx_lss_file)) {
+ result = position;
+ break;
+ }
+ ++position;
+ }
+ }
+ return result;
+}
+
+/*
+ * Return the pathname found in the given list-item.
+ */
+static char *get_color_style_config(int code)
+{
+ char *result = 0;
+
+ if (LYuse_color_style) {
+ LSS_NAMES *obj;
+
+ if ((obj = HTList_objectAt(color_style_list, code - 1)) != 0) {
+ result = obj->actual;
+ }
+ }
+ return result;
+}
+#endif
+
+/*
+ * Break cgi line into array of pairs of pointers. Don't bother trying to
+ * be efficient. We're not called all that often.
+ * We come in with a string looking like:
+ * tag1=value1&tag2=value2&...&tagN=valueN
+ * We leave with an array of post_pairs. The last element in the array
+ * will have a tag pointing to NULL.
+ * Not pretty, but works. Hey, if strings can be null terminate arrays...
+ */
+static PostPair *break_data(bstring *data)
+{
+ char *p;
+ PostPair *q = NULL;
+ int count = 0;
+
+ if (isBEmpty(data))
+ return NULL;
+
+ p = BStrData(data);
+ CTRACE((tfp, "break_data %s\n", p));
+
+ q = typecalloc(PostPair);
+ if (q == NULL)
+ outofmem(__FILE__, "break_data(calloc)");
+
+ do {
+ /*
+ * First, break up on '&', sliding 'p' on down the line.
+ */
+ q[count].value = LYstrsep(&p, "&");
+ /*
+ * Then break up on '=', sliding value down, and setting tag.
+ */
+ q[count].tag = LYstrsep(&(q[count].value), "=");
+
+ /*
+ * Clean them up a bit, in case user entered a funky string.
+ */
+ HTUnEscape(q[count].tag);
+
+ /* In the value field we have '+' instead of ' '. So do a simple
+ * find&replace on the value field before UnEscaping() - SKY
+ */
+ {
+ size_t i, len;
+
+ len = strlen(q[count].value);
+ for (i = 0; i < len; i++) {
+ if (q[count].value[i] == '+') {
+#ifdef UNIX
+ /*
+ * Allow for special case of options which begin with a "+" on
+ * Unix - TD
+ */
+ if (i > 0
+ && q[count].value[i + 1] == '+'
+ && isalnum(UCH(q[count].value[i + 2]))) {
+ q[count].value[i++] = ' ';
+ i++;
+ continue;
+ }
+#endif
+ q[count].value[i] = ' ';
+ }
+ }
+ }
+ HTUnEscape(q[count].value);
+ CTRACE((tfp, "...item[%d] tag=%s, value=%s\n",
+ count, q[count].tag, q[count].value));
+
+ count++;
+ /*
+ * Like I said, screw efficiency. Sides, realloc is fast on
+ * Linux ;->
+ */
+ q = typeRealloc(PostPair, q, (unsigned) (count + 1));
+ if (q == NULL)
+ outofmem(__FILE__, "break_data(realloc)");
+
+ q[count].tag = NULL;
+ } while (p != NULL && p[0] != '\0');
+ return q;
+}
+
+static BOOL isLynxOptionsPage(const char *address, const char *portion)
+{
+ BOOL result = FALSE;
+
+ if (!strncasecomp(address, STR_LYNXOPTIONS, LEN_LYNXOPTIONS)) {
+ unsigned len = (unsigned) strlen(portion);
+
+ address += LEN_LYNXOPTIONS;
+ if (!strncasecomp(address, portion, (int) len)
+ && (address[len] == '\0' || LYIsHtmlSep(address[len]))) {
+ result = TRUE;
+ }
+ }
+ return result;
+}
+
+static int gen_options(char **newfile);
+
+/*
+ * Handle options from the pseudo-post. I think we really only need
+ * post_data here, but bring along everything just in case. It's only a
+ * pointer. MRC
+ *
+ * Options are processed in order according to gen_options(), we should not
+ * depend on it and add boolean flags where the order is essential (save,
+ * character sets...)
+ *
+ * Security: some options are disabled in gen_options() under certain
+ * conditions. We *should* duplicate the same conditions here in postoptions()
+ * to prevent user with a limited access from editing HTML options code
+ * manually (e.g., doing 'e'dit in 'o'ptions) and submit it to access the
+ * restricted items. Prevent spoofing attempts from index overrun. - LP
+ *
+ * Exit status: NULLFILE (reload) or NORMAL (use HText cache).
+ *
+ * On exit, got the document which was current before the Options menu:
+ *
+ * (from cache) nothing changed or no visual effect supposed:
+ * editor name, e-mail, etc.
+ *
+ * (reload locally) to see the effect of certain changes:
+ * display_char_set, assume_charset, etc.
+ * (use 'need_reload' flag where necessary).
+ *
+ * (reload from remote server and uncache on a proxy)
+ * few options changes should be transferred to remote server:
+ * preferred language, fake browser name, etc.
+ * (use 'need_end_reload' flag).
+ */
+
+int postoptions(DocInfo *newdoc)
+{
+ PostPair *data = 0;
+ DocAddress WWWDoc; /* need on exit */
+ int i;
+ int code = 0;
+ BOOLEAN save_all = FALSE;
+ int display_char_set_old = current_char_set;
+ int old_media_value = LYAcceptMedia;
+ BOOLEAN raw_mode_old = LYRawMode;
+ BOOLEAN assume_char_set_changed = FALSE;
+ BOOLEAN need_reload = FALSE;
+ BOOLEAN need_end_reload = FALSE;
+
+#if defined(USE_SLANG) || defined(COLOR_CURSES)
+ int CurrentShowColor = LYShowColor;
+#endif
+#ifdef USE_DEFAULT_COLORS
+ BOOLEAN current_default_colors = LYuse_default_colors;
+#endif
+
+ /*-------------------------------------------------
+ * kludge a link from mbm_menu, the URL was:
+ * "<a href=\"" LYNXOPTIONS_PAGE(MBM_MENU) "\">Goto multi-bookmark menu</a>\n"
+ *--------------------------------------------------*/
+
+ if (isLynxOptionsPage(newdoc->address, MBM_LINK)) {
+ FREE(newdoc->post_data);
+ if (no_bookmark) {
+ HTAlert(BOOKMARK_CHANGE_DISALLOWED); /* anonymous */
+ return (NULLFILE);
+ } else if (dump_output_immediately) {
+ return (NOT_FOUND);
+ } else {
+ edit_bookmarks();
+ return (NULLFILE);
+ }
+ } else if (!isLynxOptionsPage(newdoc->address, "/")) {
+ HTAlert(RANDOM_URL_DISALLOWED);
+ return NULLFILE;
+ }
+
+ data = break_data(newdoc->post_data);
+
+ if (!data) {
+ int status;
+
+ /*-------------------------------------------------
+ * kludge gen_options() call:
+ *--------------------------------------------------*/
+ status = gen_options(&newdoc->address);
+ if (status != NORMAL) {
+ HTAlwaysAlert("Unexpected way of accessing", newdoc->address);
+ FREE(newdoc->address);
+ return (status);
+ }
+
+ /* exit to getfile() cycle */
+ WWWDoc.address = newdoc->address;
+ WWWDoc.post_data = newdoc->post_data;
+ WWWDoc.post_content_type = newdoc->post_content_type;
+ WWWDoc.bookmark = newdoc->bookmark;
+ WWWDoc.isHEAD = newdoc->isHEAD;
+ WWWDoc.safe = newdoc->safe;
+
+ if (!HTLoadAbsolute(&WWWDoc))
+ return (NOT_FOUND);
+ LYRegisterUIPage(newdoc->address, UIP_OPTIONS_MENU);
+#ifdef DIRED_SUPPORT
+ lynx_edit_mode = FALSE;
+#endif /* DIRED_SUPPORT */
+ return (NORMAL);
+ }
+
+ if (!LYIsUIPage3(HTLoadedDocumentURL(), UIP_OPTIONS_MENU, 0) &&
+ !LYIsUIPage3(HTLoadedDocumentURL(), UIP_VLINKS, 0)) {
+ char *buf = NULL;
+
+ /* We may have been spoofed? */
+ HTSprintf0(&buf,
+ gettext("Use %s to invoke the Options menu!"),
+ key_for_func_ext(LYK_OPTIONS, FOR_PANEL));
+ HTAlert(buf);
+ FREE(buf);
+ FREE(data);
+ return (NOT_FOUND);
+ }
+
+ /*
+ * Checkbox will be missing from data if unchecked.
+ */
+ LYSendUserAgent = FALSE;
+
+ for (i = 0; data[i].tag != NULL; i++) {
+ /*
+ * This isn't really for security, but rather for avoiding that the
+ * user may revisit an older instance from the history stack and submit
+ * stuff which accidentally undoes changes that had been done from a
+ * newer instance. - kw
+ */
+ if (!strcmp(data[i].tag, secure_string)) {
+ if (!secure_value || strcmp(data[i].value, secure_value)) {
+ char *buf = NULL;
+
+ /*
+ * We probably came from an older instance of the Options
+ * page that had been on the history stack. - kw
+ */
+ HTSprintf0(&buf,
+ gettext("Use %s to invoke the Options menu!"),
+ key_for_func_ext(LYK_OPTIONS, FOR_PANEL));
+ HTAlert(buf);
+ FREE(data);
+ return (NULLFILE);
+ }
+ FREE(secure_value);
+ }
+
+ /* Save options */
+ if (!strcmp(data[i].tag, save_options_string) && (!no_option_save)) {
+ save_all = TRUE;
+ }
+
+ /* Cookies: SELECT */
+ if (!strcmp(data[i].tag, cookies_string)) {
+ if (!strcmp(data[i].value, cookies_ignore_all_string)) {
+ LYSetCookies = FALSE;
+ } else if (!strcmp(data[i].value, cookies_up_to_user_string)) {
+ LYSetCookies = TRUE;
+ LYAcceptAllCookies = FALSE;
+ } else if (!strcmp(data[i].value, cookies_accept_all_string)) {
+ LYSetCookies = TRUE;
+ LYAcceptAllCookies = TRUE;
+ }
+ }
+
+ /* X Display: INPUT */
+ if (!strcmp(data[i].tag, x_display_string)) {
+ LYsetXDisplay(data[i].value);
+ validate_x_display();
+ summarize_x_display(data[i].value);
+ }
+
+ /* Editor: INPUT */
+ if (!strcmp(data[i].tag, editor_string)) {
+ FREE(editor);
+ StrAllocCopy(editor, data[i].value);
+ }
+
+ /* Emacs keys: ON/OFF */
+ if (!strcmp(data[i].tag, emacs_keys_string)
+ && GetOptValues(bool_values, data[i].value, &code)) {
+ if ((emacs_keys = (BOOLEAN) code) != FALSE) {
+ set_emacs_keys();
+ } else {
+ reset_emacs_keys();
+ }
+ }
+
+ /* Execution links: SELECT */
+#if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS))
+ if (!strcmp(data[i].tag, exec_links_string)
+ && GetOptValues(exec_links_values, data[i].value, &code)) {
+#ifndef NEVER_ALLOW_REMOTE_EXEC
+ local_exec = (BOOLEAN) (code == EXEC_ALWAYS);
+#endif /* !NEVER_ALLOW_REMOTE_EXEC */
+ local_exec_on_local_files = (BOOLEAN) (code == EXEC_LOCAL);
+ }
+#endif /* ENABLE_OPTS_CHANGE_EXEC */
+
+ /* Keypad Mode: SELECT */
+ if (!strcmp(data[i].tag, keypad_mode_string)) {
+ int newval = 0;
+
+ if (GetOptValues(keypad_mode_values, data[i].value, &newval)
+ && keypad_mode != newval) {
+ keypad_mode = newval;
+ need_reload = TRUE;
+ if (keypad_mode == NUMBERS_AS_ARROWS) {
+ set_numbers_as_arrows();
+ } else {
+ reset_numbers_as_arrows();
+ }
+ }
+ }
+
+ /* Line edit style: SELECT */
+ if (!strcmp(data[i].tag, lineedit_mode_string)) {
+ int newval = atoi(data[i].value);
+ int j;
+
+ /* prevent spoofing attempt */
+ for (j = 0; LYEditorNames[j]; j++) {
+ if (j == newval)
+ current_lineedit = newval;
+ }
+ }
+#ifdef EXP_KEYBOARD_LAYOUT
+ /* Keyboard layout: SELECT */
+ if (!strcmp(data[i].tag, kblayout_string)) {
+ int newval = atoi(data[i].value);
+ int j;
+
+ /* prevent spoofing attempt */
+ for (j = 0; LYKbLayoutNames[j]; j++) {
+ if (j == newval)
+ current_layout = newval;
+ }
+ }
+#endif /* EXP_KEYBOARD_LAYOUT */
+
+ /* Mail Address: INPUT */
+ if (!strcmp(data[i].tag, mail_address_string)) {
+ FREE(personal_mail_address);
+ StrAllocCopy(personal_mail_address, data[i].value);
+ }
+#ifndef NO_ANONYMOUS_EMAIL
+ /* Personal Name: INPUT */
+ if (!strcmp(data[i].tag, personal_name_string)) {
+ FREE(personal_mail_name);
+ StrAllocCopy(personal_mail_name, data[i].value);
+ }
+#endif
+
+ /* Anonymous FTP Password: INPUT */
+#ifndef DISABLE_FTP
+ if (!strcmp(data[i].tag, anonftp_password_string)) {
+ FREE(anonftp_password);
+ StrAllocCopy(anonftp_password, data[i].value);
+ }
+#endif
+
+ /* Search Type: SELECT */
+ if (!strcmp(data[i].tag, search_type_string)
+ && GetOptValues(search_type_values, data[i].value, &code)) {
+ LYcase_sensitive = (BOOLEAN) code;
+ }
+
+ /* HTML error tolerance: SELECT */
+ if (!strcmp(data[i].tag, DTD_recovery_string)
+ && GetOptValues(DTD_type_values, data[i].value, &code)) {
+ if (Old_DTD != code) {
+ Old_DTD = code;
+ HTSwitchDTD(!Old_DTD);
+ need_reload = TRUE;
+ }
+ }
+
+ /* Bad HTML warnings: SELECT */
+ if (!strcmp(data[i].tag, bad_html_string)
+ && GetOptValues(bad_html_values, data[i].value, &code)) {
+ cfg_bad_html = code;
+ }
+
+ /* Select Popups: ON/OFF */
+ if (!strcmp(data[i].tag, select_popups_string)
+ && GetOptValues(bool_values, data[i].value, &code)) {
+ LYSelectPopups = (BOOLEAN) code;
+ }
+#if defined(USE_SLANG) || defined(COLOR_CURSES)
+ /* Show Color: SELECT */
+ if (!strcmp(data[i].tag, show_color_string)
+ && GetOptValues(show_color_values, data[i].value,
+ &LYChosenShowColor)) {
+ if (can_do_colors)
+ LYShowColor = LYChosenShowColor;
+ if (CurrentShowColor != LYShowColor) {
+ lynx_force_repaint();
+ }
+#ifdef USE_SLANG
+ SLtt_Use_Ansi_Colors = (LYShowColor > SHOW_COLOR_OFF ? TRUE : FALSE);
+#endif
+ }
+#endif /* USE_SLANG || COLOR_CURSES */
+
+#ifdef USE_COLOR_STYLE
+ /* Color Style: ON/OFF */
+ if (!strcmp(data[i].tag, color_style_string)
+ && GetOptValues(color_style_values, data[i].value, &code)) {
+ if (code) {
+ LYuse_color_style = TRUE;
+ StrAllocCopy(lynx_lss_file, get_color_style_config(code));
+ reinit_color_styles();
+ } else {
+ LYuse_color_style = FALSE;
+ }
+ update_color_style();
+ lynx_force_repaint();
+ }
+#endif
+
+#ifdef USE_DEFAULT_COLORS
+ /* Default Colors: ON/OFF */
+ if (!strcmp(data[i].tag, default_colors_string)
+ && GetOptValues(bool_values, data[i].value, &code)) {
+ LYuse_default_colors = (BOOLEAN) code;
+ if (current_default_colors != LYuse_default_colors) {
+ CTRACE((tfp, "default_colors changed, updating colors...\n"));
+ if (has_colors()) {
+ if (LYuse_default_colors) {
+ use_default_colors();
+ } else {
+ restart_curses();
+ }
+ update_default_colors();
+ lynx_force_repaint();
+ }
+ }
+ }
+#endif
+
+ /* Show Cursor: ON/OFF */
+ if (!strcmp(data[i].tag, show_cursor_string)
+ && GetOptValues(bool_values, data[i].value, &code)) {
+ LYShowCursor = (BOOLEAN) code;
+ }
+
+ /* Underline links: ON/OFF */
+ if (!strcmp(data[i].tag, underline_links_string)
+ && GetOptValues(bool_values, data[i].value, &code)) {
+ LYUnderlineLinks = (BOOLEAN) code;
+ }
+#ifdef USE_SCROLLBAR
+ /* Show Scrollbar: ON/OFF */
+ if (!strcmp(data[i].tag, show_scrollbar_string)
+ && GetOptValues(bool_values, data[i].value, &code)) {
+ LYShowScrollbar = (BOOLEAN) code;
+ need_reload = TRUE;
+ }
+#endif
+
+ /* Cookie Version: SELECT */
+ if (!strcmp(data[i].tag, cookie_version_string))
+ GetOptValues(cookies_values, data[i].value, &cookie_version);
+
+ /* Cookie Prompting: SELECT */
+ if (!strcmp(data[i].tag, cookie_prompt_string))
+ GetOptValues(prompt_values, data[i].value, &cookie_noprompt);
+
+#ifdef USE_SSL
+ /* SSL Prompting: SELECT */
+ if (!strcmp(data[i].tag, ssl_prompt_string))
+ GetOptValues(prompt_values, data[i].value, &ssl_noprompt);
+#endif
+
+ /* User Mode: SELECT */
+ if (!strcmp(data[i].tag, user_mode_string)
+ && GetOptValues(user_mode_values, data[i].value, &user_mode)) {
+ LYSetDisplayLines();
+ }
+
+ /* Type of visited pages page: SELECT */
+ if (!strcmp(data[i].tag, visited_links_string))
+ GetOptValues(visited_links_values, data[i].value, &Visited_Links_As);
+
+ /* Show Images: SELECT */
+ if (!strcmp(data[i].tag, images_string)) {
+ if (!strcmp(data[i].value, images_ignore_all_string)
+ && !(pseudo_inline_alts == FALSE && clickable_images == FALSE)) {
+ pseudo_inline_alts = FALSE;
+ clickable_images = FALSE;
+ need_reload = TRUE;
+ } else if (!strcmp(data[i].value, images_use_label_string)
+ && !(pseudo_inline_alts == TRUE && clickable_images == FALSE)) {
+ pseudo_inline_alts = TRUE;
+ clickable_images = FALSE;
+ need_reload = TRUE;
+ } else if (!strcmp(data[i].value, images_use_links_string)
+ && !(clickable_images == TRUE)) {
+ clickable_images = TRUE;
+ need_reload = TRUE;
+ }
+ }
+
+ /* Verbose Images: ON/OFF */
+ if (!strcmp(data[i].tag, verbose_images_string)
+ && GetOptValues(verbose_images_type_values, data[i].value, &code)) {
+ if (verbose_img != code) {
+ verbose_img = (BOOLEAN) code;
+ need_reload = TRUE;
+ }
+ }
+
+ /* Collapse BR Tags: ON/OFF */
+ if (!strcmp(data[i].tag, collapse_br_tags_string)
+ && GetOptValues(collapse_br_tags_values, data[i].value, &code)) {
+ if (LYCollapseBRs != code) {
+ LYCollapseBRs = (BOOLEAN) code;
+ need_reload = TRUE;
+ }
+ }
+
+ /* Trim Blank Lines: ON/OFF */
+ if (!strcmp(data[i].tag, trim_blank_lines_string)
+ && GetOptValues(trim_blank_lines_values, data[i].value, &code)) {
+ if (LYtrimBlankLines != code) {
+ LYtrimBlankLines = (BOOLEAN) code;
+ need_reload = TRUE;
+ }
+ }
+
+ /* VI Keys: ON/OFF */
+ if (!strcmp(data[i].tag, vi_keys_string)
+ && GetOptValues(bool_values, data[i].value, &code)) {
+ if ((vi_keys = (BOOLEAN) code) != FALSE) {
+ set_vi_keys();
+ } else {
+ reset_vi_keys();
+ }
+ }
+
+ /* Bookmarks File Menu: SELECT */
+ if (!strcmp(data[i].tag, mbm_string) && (!LYMBMBlocked)) {
+ GetOptValues(mbm_values, data[i].value, &LYMultiBookmarks);
+ }
+
+ /* Default Bookmarks filename: INPUT */
+ if (!strcmp(data[i].tag, single_bookmark_string) && (!no_bookmark)) {
+ if (strcmp(data[i].value, "")) {
+ FREE(bookmark_page);
+ StrAllocCopy(bookmark_page, data[i].value);
+ }
+ }
+#ifdef USE_SESSIONS
+ /* Auto Session: ON/OFF */
+ if (!strcmp(data[i].tag, auto_session_string)
+ && GetOptValues(bool_values, data[i].value, &code)) {
+ LYAutoSession = (BOOLEAN) code;
+ }
+
+ /* Default Session filename: INPUT */
+ if (!strcmp(data[i].tag, single_session_string)) {
+ if (strcmp(data[i].value, "")) {
+ FREE(LYSessionFile);
+ StrAllocCopy(LYSessionFile, data[i].value);
+ }
+ }
+#endif
+
+ /* Assume Character Set: SELECT */
+ if (!strcmp(data[i].tag, assume_char_set_string)) {
+ int newval = UCGetLYhndl_byMIME(data[i].value);
+
+ if (newval >= 0
+ && ((raw_mode_old &&
+ newval != safeUCGetLYhndl_byMIME(UCAssume_MIMEcharset))
+ || (!raw_mode_old &&
+ newval != UCLYhndl_for_unspec)
+ )) {
+
+ UCLYhndl_for_unspec = newval;
+ StrAllocCopy(UCAssume_MIMEcharset, data[i].value);
+ assume_char_set_changed = TRUE;
+ }
+ }
+#ifdef USE_LOCALE_CHARSET
+ /* Use locale-based character set: ON/OFF */
+ if (!strcmp(data[i].tag, locale_charset_string)
+ && GetOptValues(bool_values, data[i].value, &code)) {
+ LYLocaleCharset = (BOOLEAN) code;
+ }
+#endif
+ /* Use HTML5 charset replacements: ON/OFF */
+ if (!strcmp(data[i].tag, html5_charsets_string)
+ && GetOptValues(bool_values, data[i].value, &code)) {
+ html5_charsets = (BOOLEAN) code;
+ assume_char_set_changed = TRUE;
+ }
+
+ /* Display Character Set: SELECT */
+ if (!strcmp(data[i].tag, display_char_set_string)) {
+ int newval = atoi(data[i].value);
+ int j;
+
+ /* prevent spoofing attempt */
+ for (j = 0; LYchar_set_names[j]; j++) {
+ if (j == newval)
+ current_char_set = newval;
+ }
+ }
+#ifdef USE_IDN2
+ /* Internationalized Domain Names: SELECT */
+ if (!strcmp(data[i].tag, idna_mode_string)
+ && GetOptValues(idna_values, data[i].value, &code)) {
+ LYidnaMode = code;
+ }
+#endif
+
+ /* Raw Mode: ON/OFF */
+ if (!strcmp(data[i].tag, raw_mode_string)
+ && GetOptValues(bool_values, data[i].value, &code)) {
+ LYRawMode = (BOOLEAN) code;
+ }
+#ifndef DISABLE_FTP
+ /*
+ * passive ftp: ON/OFF
+ */
+ if (!strcmp(data[i].tag, passive_ftp_string)) {
+ ftp_passive = (BOOLEAN) code;
+ }
+
+ /*
+ * ftp sort: SELECT
+ */
+ if (!strcmp(data[i].tag, ftp_sort_string)) {
+ GetOptValues(ftp_sort_values, data[i].value, &HTfileSortMethod);
+ }
+#endif /* DISABLE_FTP */
+
+#ifdef DIRED_SUPPORT
+ /* Local Directory Style: SELECT */
+ if (!strcmp(data[i].tag, dired_list_string)) {
+ GetOptValues(dired_list_values, data[i].value, &dir_list_style);
+ }
+#ifdef LONG_LIST
+ /* Local Directory Order: SELECT */
+ if (!strcmp(data[i].tag, dired_sort_string)) {
+ GetOptValues(dired_sort_values, data[i].value, &dir_list_order);
+ }
+#endif /* LONG_LIST */
+#endif /* DIRED_SUPPORT */
+
+ /* Show dot files: ON/OFF */
+ if (!strcmp(data[i].tag, show_dotfiles_string) && (!no_dotfiles)
+ && GetOptValues(bool_values, data[i].value, &code)) {
+ show_dotfiles = (BOOLEAN) code;
+ }
+
+ /* Pause when showing messages: ON/OFF */
+ if (!strcmp(data[i].tag, no_pause_string)
+ && GetOptValues(bool_values, data[i].value, &code)) {
+ no_pause = (BOOLEAN) !code;
+ }
+#ifdef USE_READPROGRESS
+ /* Show Transfer Rate: enumerated value */
+ if (!strcmp(data[i].tag, show_rate_string)
+ && GetOptValues(rate_values, data[i].value, &code)) {
+ LYTransferRate = code;
+ }
+#endif /* USE_READPROGRESS */
+
+ /* Preferred Content Type: SELECT */
+ if (!strcmp(data[i].tag, preferred_content_string)) {
+ GetOptValues(content_values, data[i].value, &LYContentType);
+ }
+
+ /* Preferred Media Type: SELECT */
+ if (!strcmp(data[i].tag, preferred_media_string)) {
+ GetOptValues(media_values, data[i].value, &LYAcceptMedia);
+ }
+
+ /* Preferred Encoding: SELECT */
+ if (!strcmp(data[i].tag, preferred_encoding_string)) {
+ GetOptValues(encoding_values, data[i].value, &LYAcceptEncoding);
+ }
+
+ /* Preferred Document Character Set: INPUT */
+ if (!strcmp(data[i].tag, preferred_doc_char_string)) {
+ if (strcmp(pref_charset, data[i].value)) {
+ FREE(pref_charset);
+ StrAllocCopy(pref_charset, data[i].value);
+ need_end_reload = TRUE;
+ }
+ }
+
+ /* Preferred Document Language: INPUT */
+ if (!strcmp(data[i].tag, preferred_doc_lang_string)) {
+ if (strcmp(language, data[i].value)) {
+ FREE(language);
+ StrAllocCopy(language, data[i].value);
+ need_end_reload = TRUE;
+ }
+ }
+
+ /*
+ * HTTP protocol: SELECT
+ */
+ if (!strcmp(data[i].tag, http_protocol_string)) {
+ GetOptValues(http_protocol_values, data[i].value, &HTprotocolLevel);
+ }
+
+ /* Send User Agent: INPUT */
+ if (!strcmp(data[i].tag, send_user_agent_string)) {
+ LYSendUserAgent = (BOOLEAN) !strcasecomp(data[i].value, "ON");
+ }
+
+ if (!strcmp(data[i].tag, ssl_client_certificate_file)) {
+ FREE(SSL_client_cert_file);
+ StrAllocCopy(SSL_client_cert_file, data[i].value);
+ }
+
+ if (!strcmp(data[i].tag, ssl_client_key_file)) {
+ FREE(SSL_client_key_file);
+ StrAllocCopy(SSL_client_key_file, data[i].value);
+ }
+
+ /* User Agent: INPUT */
+ if (!strcmp(data[i].tag, user_agent_string) && (!no_useragent)) {
+ if (strcmp(LYUserAgent, data[i].value)) {
+ need_end_reload = TRUE;
+ FREE(LYUserAgent);
+ /* ignore Copyright warning ? */
+ StrAllocCopy(LYUserAgent,
+ *(data[i].value)
+ ? data[i].value
+ : LYUserAgentDefault);
+ if (!LYCheckUserAgent()) {
+ HTAlert(UA_PLEASE_USE_LYNX);
+ }
+ }
+ }
+ } /* end of loop */
+
+ /*
+ * Process the flags:
+ */
+#ifdef USE_LOCALE_CHARSET
+ LYFindLocaleCharset();
+#endif
+
+ if (old_media_value != LYAcceptMedia)
+ HTFilterPresentations();
+
+ if (display_char_set_old != current_char_set ||
+ raw_mode_old != LYRawMode ||
+ assume_char_set_changed) {
+ /*
+ * charset settings: the order is essential here.
+ */
+ if (display_char_set_old != current_char_set) {
+ /*
+ * Set the LYUseDefaultRawMode value and character handling if
+ * LYRawMode was changed. - FM
+ */
+ LYUseDefaultRawMode = TRUE;
+ HTMLUseCharacterSet(current_char_set);
+#ifdef CAN_SWITCH_DISPLAY_CHARSET
+ /* Deduce whether the user wants autoswitch: */
+ switch_display_charsets =
+ (current_char_set == auto_display_charset
+ || current_char_set == auto_other_display_charset);
+#endif
+ }
+ if (assume_char_set_changed && HTCJK != JAPANESE) {
+ LYRawMode = (BOOLEAN) (UCLYhndl_for_unspec == current_char_set);
+ }
+ if (raw_mode_old != LYRawMode || assume_char_set_changed) {
+ /*
+ * Set the raw 8-bit or CJK mode defaults and character set if
+ * changed. - FM
+ */
+ HTMLSetUseDefaultRawMode(current_char_set, LYRawMode);
+ HTMLSetCharacterHandling(current_char_set);
+ }
+ need_reload = TRUE;
+ }
+ /* end of charset settings */
+
+ BStrFree(newdoc->post_data);
+ FREE(data);
+ if (save_all) {
+ HTInfoMsg(SAVING_OPTIONS);
+ LYrcShowColor = LYChosenShowColor;
+ if (save_rc(NULL)) {
+ HTInfoMsg(OPTIONS_SAVED);
+ } else {
+ HTAlert(OPTIONS_NOT_SAVED);
+ }
+ }
+
+ /*
+ * Exit: working around the previous document. Being out of
+ * mainloop()/getfile() cycle, do things manually.
+ */
+ CTRACE((tfp, "\nLYOptions.c/postoptions(): exiting...\n"));
+ CTRACE((tfp, " need_reload = %s\n",
+ need_reload ? "TRUE" : "FALSE"));
+ CTRACE((tfp, " need_end_reload = %s\n",
+ need_end_reload ? "TRUE" : "FALSE"));
+
+ /* Options menu was pushed before postoptions(), so pop-up. */
+ LYpop(newdoc);
+ WWWDoc.address = newdoc->address;
+ WWWDoc.post_data = newdoc->post_data;
+ WWWDoc.post_content_type = newdoc->post_content_type;
+ WWWDoc.bookmark = newdoc->bookmark;
+ WWWDoc.isHEAD = newdoc->isHEAD;
+ WWWDoc.safe = newdoc->safe;
+ LYforce_no_cache = FALSE; /* ! */
+ LYoverride_no_cache = TRUE; /* ! */
+ /*
+ * Working out of getfile() cycle we reset *no_cache manually here so
+ * HTLoadAbsolute() will return "Document already in memory": it was
+ * forced reloading Options Menu again without this (overhead).
+ *
+ * Probably *no_cache was set in a wrong position because of
+ * the internal page...
+ */
+ if (!HTLoadAbsolute(&WWWDoc))
+ return (NOT_FOUND);
+
+ HTuncache_current_document(); /* will never use again */
+
+ /*
+ * Return to previous doc, not to options menu! Reload the document we had
+ * before the options menu but uncache only when necessary (Hurrah, user!):
+ */
+ LYpop(newdoc);
+ WWWDoc.address = newdoc->address;
+ WWWDoc.post_data = newdoc->post_data;
+ WWWDoc.post_content_type = newdoc->post_content_type;
+ WWWDoc.bookmark = newdoc->bookmark;
+ WWWDoc.isHEAD = newdoc->isHEAD;
+ WWWDoc.safe = newdoc->safe;
+ LYforce_no_cache = FALSE; /* see below */
+ LYoverride_no_cache = TRUE; /* see below */
+ /*
+ * Re-setting of *no_cache is probably not required here but this is a
+ * guarantee against _double_ reloading over the net in case prev document
+ * has its own "no cache" attribute and options menu set "need_reload"
+ * also. Force this HTLoadAbsolute() to return "Document already in
+ * memory".
+ */
+ if (!HTLoadAbsolute(&WWWDoc))
+ return (NOT_FOUND);
+
+ /*
+ * Now most interesting part: reload document when necessary.
+ * **********************************************************
+ */
+
+ reloading = FALSE; /* set manually */
+ /* force end-to-end reload from remote server if change LYUserAgent or
+ * language or pref_charset (marked by need_end_reload flag above), from
+ * old-style LYK_OPTIONS (mainloop):
+ */
+ if ((need_end_reload == TRUE &&
+ (StrNCmp(newdoc->address, "http", 4) == 0 ||
+ isLYNXCGI(newdoc->address)))) {
+ /*
+ * An option has changed which may influence content negotiation, and
+ * the resource is from a http or https or lynxcgi URL (the only
+ * protocols which currently do anything with this information). Set
+ * reloading = TRUE so that proxy caches will be flushed, which is
+ * necessary until the time when all proxies understand HTTP 1.1 Vary:
+ * and all Servers properly use it... Treat like case LYK_RELOAD (see
+ * comments there). - KW
+ */
+ reloading = TRUE; /* global flag */
+ need_reload = TRUE; /* this was probably already TRUE, don't worry */
+ }
+
+ if (need_reload == FALSE) {
+ /* no uncache, already loaded */
+ CTRACE((tfp, "LYOptions.c/postoptions(): now really exit.\n\n"));
+ return (NORMAL);
+ } else {
+ /* update HText cache */
+
+ /*
+ * see LYK_RELOAD & LYK_OPTIONS in mainloop for details...
+ */
+ if (HTisDocumentSource()) {
+ srcmode_for_next_retrieval(1);
+ }
+#ifdef USE_SOURCE_CACHE
+ if (reloading == FALSE) {
+ /* one more attempt to be smart enough: */
+ if (HTcan_reparse_document()) {
+ if (!HTreparse_document())
+ srcmode_for_next_retrieval(0);
+ CTRACE((tfp, "LYOptions.c/postoptions(): now really exit.\n\n"));
+ return (NORMAL);
+ }
+ }
+#endif
+ if (newdoc->post_data != NULL && !newdoc->safe &&
+ confirm_post_resub(newdoc->address, newdoc->title, 2, 1) == FALSE) {
+ HTInfoMsg(WILL_NOT_RELOAD_DOC);
+ if (HTisDocumentSource()) {
+ srcmode_for_next_retrieval(0);
+ }
+ return (NORMAL);
+ }
+
+ HEAD_request = HTLoadedDocumentIsHEAD();
+ /* uncache and load again */
+ HTuncache_current_document();
+ LYpush(newdoc, FALSE);
+ CTRACE((tfp, "LYOptions.c/postoptions(): now really exit.\n\n"));
+ return (NULLFILE);
+ }
+
+ /******** Done! **************************************************/
+}
+
+static char *NewSecureValue(void)
+{
+ static char oops[] = "?";
+
+ FREE(secure_value);
+ if ((secure_value = typeMallocn(char, 80)) != 0) {
+#if defined(RAND_MAX)
+ long key = (long) lynx_rand();
+
+#else
+ long key = (long) secure_value + (long) time(0);
+#endif
+ sprintf(secure_value, "%ld", key);
+ return secure_value;
+ }
+ return oops;
+}
+
+#define LABEL_LEN 33
+
+/*
+ * Note: the 'value' we are passing here is a local copy of the "same" string
+ * as is used in LYrcFile.c to index the saveable options.
+ */
+static void PutLabel(FILE *fp, const char *name,
+ const char *value)
+{
+ int have = (int) strlen(name);
+ int want = LABEL_LEN;
+ int need = LYstrExtent(name, have, want);
+ char *buffer = NULL;
+
+ fprintf(fp, "%s%s", MARGIN_STR, LYEntifyTitle(&buffer, NonNull(name)));
+
+ if (will_save_rc(value) && !no_option_save) {
+ while (need++ < want)
+ fprintf(fp, "&nbsp;");
+ } else {
+ want -= 3;
+ if (need < want) {
+ fprintf(fp, "&nbsp;");
+ ++need;
+ }
+ fprintf(fp, "(!)");
+ while (need++ < want) {
+ fprintf(fp, "&nbsp;");
+ }
+ }
+ fprintf(fp, ": ");
+ FREE(buffer);
+}
+
+/*
+ * For given a list of the .lynxrc names for boolean flags that make up a
+ * composite setting, check if any are not writable for the .lynxrc file. If
+ * so, return that name, so the subsequence will_save_rc() check in PutLabel()
+ * will flag the composite as not-saved.
+ */
+static const char *check_if_write_lynxrc(STRING2PTR table)
+{
+ int n;
+ const char *result = NULL;
+
+ for (n = 0; table[n] != 0; ++n) {
+ result = table[n];
+ if (!will_save_rc(result))
+ break;
+ }
+ return result;
+}
+
+/*
+ * The options menu treats "Cookies" as a single enumeration, but it is read
+ * from lynx.cfg (and perhaps .lynxrc) as a set of booleans. Check if any are
+ * not writable to .lynxrc, so we can show the user.
+ */
+static const char *will_save_cookies(void)
+{
+ static const char *table[] =
+ {
+ RC_SET_COOKIES, /* LYSetCookies */
+ RC_ACCEPT_ALL_COOKIES, /* LYAcceptAllCookies */
+ NULL
+ };
+
+ return check_if_write_lynxrc(table);
+}
+
+/*
+ * The options menu treats "Show images" as a single enumeration, but it is
+ * read from lynx.cfg (and perhaps .lynxrc) as a set of booleans. Check if any
+ * are not writable to .lynxrc, so we can show the user.
+ */
+static const char *will_save_images(void)
+{
+ static const char *table[] =
+ {
+ RC_MAKE_PSEUDO_ALTS_FOR_INLINES, /* pseudo_inline_alts */
+ RC_MAKE_LINKS_FOR_ALL_IMAGES, /* clickable_images */
+ NULL
+ };
+
+ return check_if_write_lynxrc(table);
+}
+
+/*
+ * The visited-links menu is used from the visited-links page as well as the
+ * options page.
+ */
+void LYMenuVisitedLinks(FILE *fp0, int disable_all)
+{
+ BeginSelect(fp0, visited_links_string);
+ PutOptValues(fp0, Visited_Links_As, visited_links_values);
+ EndSelect(fp0);
+}
+
+/*
+ * Okay, someone wants to change options. So, let's gen up a form for them
+ * and pass it around. Gor, this is ugly. Be a lot easier in Bourne with
+ * "here" documents. :->
+ * Basic Strategy: For each option, throw up the appropriate type of
+ * control, giving defaults as appropriate. If nothing else, we're
+ * probably going to test every control there is. MRC
+ *
+ * This function is synchronized with postoptions(). Read the comments in
+ * postoptions() header if you change something in gen_options().
+ */
+static int gen_options(char **newfile)
+{
+ static char tempfile[LY_MAXPATH] = "\0";
+
+ int i;
+ char *buffer = NULL;
+ BOOLEAN disable_all = FALSE;
+ FILE *fp0;
+ size_t cset_len = 0;
+ size_t text_len = (size_t) ((LYcolLimit > 45)
+ ? LYcolLimit - (LABEL_LEN + 2 + MARGIN_LEN)
+ : 7); /* cf: PutLabel */
+
+ if ((fp0 = InternalPageFP(tempfile, TRUE)) == 0)
+ return (NOT_FOUND);
+
+ LYLocalFileToURL(newfile, tempfile);
+
+ /* This should not be needed if we regenerate the temp file every time with
+ * a new name, which just happened above in the case
+ * LYReuseTempfiles==FALSE. Even for LYReuseTempfiles=TRUE, code at the
+ * end of postoptions() may remove an older cached version from memory if
+ * that version of the page was left by submitting changes. - kw
+ * 1999-11-27
+ * If access to the actual file via getfile() later fails (maybe because of
+ * some restrictions), mainloop may leave this flag on after popping the
+ * previous doc which is then unnecessarily reloaded. But I changed
+ * mainloop to reset the flag. - kw 1999-05-24
+ */
+ LYforce_no_cache = TRUE;
+
+ /*
+ * Without LYUseFormsOptions set we should maybe not even get here.
+ * However, it's possible we do; disable the form in that case. - kw
+ */
+#ifndef NO_OPTION_MENU
+ if (!LYUseFormsOptions)
+ disable_all = TRUE;
+#endif
+
+ BeginInternalPage(fp0, OPTIONS_TITLE, NULL); /* help link below */
+
+ /*
+ * I do C, not HTML. Feel free to pretty this up.
+ */
+ fprintf(fp0, "<form action=\"%s\" method=\"post\">\n", STR_LYNXOPTIONS);
+ /*
+ * use following with some sort of one shot secret key akin to NCSA
+ * (or was it CUTE?) telnet one shot password to allow ftp to self.
+ * to prevent spoofing.
+ */
+ fprintf(fp0, "<input name=\"%s\" type=\"hidden\" value=\"%s\">\n",
+ secure_string, NewSecureValue());
+
+ /*
+ * visible text begins here
+ */
+
+ /* Submit/Reset/Help */
+ fprintf(fp0, "<p align=center>\n");
+ if (!disable_all) {
+ fprintf(fp0,
+ "<input type=\"submit\" value=\"%s\"> - \n",
+ LYEntifyValue(&buffer, ACCEPT_CHANGES));
+ fprintf(fp0,
+ "<input type=\"reset\" value=\"%s\"> - \n",
+ LYEntifyValue(&buffer, RESET_CHANGES));
+ fprintf(fp0,
+ "%s - \n",
+ LYEntifyTitle(&buffer, CANCEL_CHANGES));
+ }
+ fprintf(fp0, "<a href=\"%s%s\">%s</a>\n",
+ helpfilepath, LYEntifyTitle(&buffer, OPTIONS_HELP), TO_HELP);
+
+ /* Save options */
+ if (!no_option_save) {
+ if (!disable_all) {
+ fprintf(fp0, "<p align=center>%s: ", LYEntifyTitle(&buffer, SAVE_OPTIONS));
+ fprintf(fp0, "<input type=\"checkbox\" name=\"%s\">\n",
+ save_options_string);
+ }
+ fprintf(fp0, "<br>%s\n",
+ LYEntifyTitle(&buffer,
+ gettext("(options marked with (!) will not be saved)")));
+ }
+
+ /*
+ * preformatted text follows
+ */
+ fprintf(fp0, "<pre>\n");
+
+ PutHeader(fp0, gettext("General Preferences"));
+ /*****************************************************************/
+
+ /* User Mode: SELECT */
+ PutLabel(fp0, gettext("User mode"), user_mode_string);
+ BeginSelect(fp0, user_mode_string);
+ PutOptValues(fp0, user_mode, user_mode_values);
+ EndSelect(fp0);
+
+ /* Editor: INPUT */
+ PutLabel(fp0, gettext("Editor"), editor_string);
+ PutTextInput(fp0, editor_string, NonNull(editor), text_len,
+ DISABLED(no_editor || system_editor));
+
+ /* Search Type: SELECT */
+ PutLabel(fp0, gettext("Type of Search"), search_type_string);
+ BeginSelect(fp0, search_type_string);
+ PutOptValues(fp0, LYcase_sensitive, search_type_values);
+ EndSelect(fp0);
+
+ PutHeader(fp0, gettext("Security and Privacy"));
+ /*****************************************************************/
+
+ /* Cookies: SELECT */
+ PutLabel(fp0, gettext("Cookies"), will_save_cookies());
+ BeginSelect(fp0, cookies_string);
+ PutOption(fp0, !LYSetCookies,
+ cookies_ignore_all_string,
+ cookies_ignore_all_string);
+ PutOption(fp0, LYSetCookies && !LYAcceptAllCookies,
+ cookies_up_to_user_string,
+ cookies_up_to_user_string);
+ PutOption(fp0, LYSetCookies && LYAcceptAllCookies,
+ cookies_accept_all_string,
+ cookies_accept_all_string);
+ EndSelect(fp0);
+
+ /* Cookie Version: SELECT */
+ PutLabel(fp0, gettext("Cookie RFC-version"), cookie_version_string);
+ BeginSelect(fp0, cookie_version_string);
+ PutOptValues(fp0, cookie_version, cookies_values);
+ EndSelect(fp0);
+
+ /* Cookie Prompting: SELECT */
+ PutLabel(fp0, gettext("Invalid-Cookie Prompting"), cookie_prompt_string);
+ BeginSelect(fp0, cookie_prompt_string);
+ PutOptValues(fp0, cookie_noprompt, prompt_values);
+ EndSelect(fp0);
+
+#ifdef USE_SSL
+ /* SSL Prompting: SELECT */
+ PutLabel(fp0, gettext("SSL Prompting"), ssl_prompt_string);
+ BeginSelect(fp0, ssl_prompt_string);
+ PutOptValues(fp0, ssl_noprompt, prompt_values);
+ EndSelect(fp0);
+
+ PutLabel(fp0, gettext("SSL client certificate file"), ssl_client_certificate_file);
+ PutTextInput(fp0, ssl_client_certificate_file,
+ NonNull(SSL_client_cert_file), text_len, "");
+
+ PutLabel(fp0, gettext("SSL client key file"), ssl_client_key_file);
+ PutTextInput(fp0, ssl_client_key_file,
+ NonNull(SSL_client_key_file), text_len, "");
+
+#endif
+
+ PutHeader(fp0, gettext("Keyboard Input"));
+ /*****************************************************************/
+
+ /* Keypad Mode: SELECT */
+ PutLabel(fp0, gettext("Keypad mode"), keypad_mode_string);
+ BeginSelect(fp0, keypad_mode_string);
+ PutOptValues(fp0, keypad_mode, keypad_mode_values);
+ EndSelect(fp0);
+
+ /* Emacs keys: ON/OFF */
+ PutLabel(fp0, gettext("Emacs keys"), emacs_keys_string);
+ BeginSelect(fp0, emacs_keys_string);
+ PutOptValues(fp0, emacs_keys, bool_values);
+ EndSelect(fp0);
+
+ /* VI Keys: ON/OFF */
+ PutLabel(fp0, gettext("VI keys"), vi_keys_string);
+ BeginSelect(fp0, vi_keys_string);
+ PutOptValues(fp0, vi_keys, bool_values);
+ EndSelect(fp0);
+
+ /* Line edit style: SELECT */
+ if (LYEditorNames[1]) { /* well, at least 2 line edit styles available */
+ PutLabel(fp0, gettext("Line edit style"), lineedit_mode_string);
+ BeginSelect(fp0, lineedit_mode_string);
+ for (i = 0; LYEditorNames[i]; i++) {
+ char temp[DigitsOf(i) + 3];
+
+ sprintf(temp, "%d", i);
+ PutOption(fp0, i == current_lineedit, temp, LYEditorNames[i]);
+ }
+ EndSelect(fp0);
+ }
+#ifdef EXP_KEYBOARD_LAYOUT
+ /* Keyboard layout: SELECT */
+ PutLabel(fp0, gettext("Keyboard layout"), kblayout_string);
+ BeginSelect(fp0, kblayout_string);
+ for (i = 0; LYKbLayoutNames[i]; i++) {
+ char temp[DigitsOf(i) + 3];
+
+ sprintf(temp, "%d", i);
+ PutOption(fp0, i == current_layout, temp, LYKbLayoutNames[i]);
+ }
+ EndSelect(fp0);
+#endif /* EXP_KEYBOARD_LAYOUT */
+
+ /*
+ * Display and Character Set
+ */
+ PutHeader(fp0, gettext("Display and Character Set"));
+ /*****************************************************************/
+
+#ifdef USE_LOCALE_CHARSET
+ /* Use locale-based character set: ON/OFF */
+ PutLabel(fp0, gettext("Use locale-based character set"), locale_charset_string);
+ BeginSelect(fp0, locale_charset_string);
+ PutOptValues(fp0, LYLocaleCharset, bool_values);
+ EndSelect(fp0);
+#else
+#define LYLocaleCharset FALSE
+#endif
+ PutLabel(fp0, gettext("Use HTML5 charset replacements"), html5_charsets_string);
+ BeginSelect(fp0, html5_charsets_string);
+ PutOptValues(fp0, html5_charsets, bool_values);
+ EndSelect(fp0);
+
+ /* Display Character Set: SELECT */
+ PutLabel(fp0, gettext("Display character set"), display_char_set_string);
+ MaybeSelect(fp0, LYLocaleCharset, display_char_set_string);
+ for (i = 0; LYchar_set_names[i]; i++) {
+ char temp[DigitsOf(i) + 3];
+ size_t len = strlen(LYchar_set_names[i]);
+
+ if (len > cset_len)
+ cset_len = len;
+ sprintf(temp, "%d", i);
+#ifdef USE_CHARSET_CHOICE
+ if (!charset_subsets[i].hide_display)
+#endif
+ PutOption(fp0, i == current_char_set, temp, LYchar_set_names[i]);
+ }
+ EndSelect(fp0);
+
+ /* Assume Character Set: SELECT */
+ {
+ int curval;
+
+ curval = UCLYhndl_for_unspec;
+
+ /*
+ * FIXME: If bogus value in lynx.cfg, then in old way, that is the
+ * string that was displayed. Now, user will never see that. Good
+ * or bad? I don't know. MRC
+ */
+ if (curval == current_char_set) {
+ /* ok, LYRawMode, so use UCAssume_MIMEcharset */
+ curval = safeUCGetLYhndl_byMIME(UCAssume_MIMEcharset);
+ }
+ PutLabel(fp0, gettext("Assumed document character set"), assume_char_set_string);
+ BeginSelect(fp0, assume_char_set_string);
+ for (i = 0; i < LYNumCharsets; i++) {
+#ifdef USE_CHARSET_CHOICE
+ if (!charset_subsets[i].hide_assumed)
+#endif
+ PutOption(fp0, i == curval,
+ LYCharSet_UC[i].MIMEname,
+ LYCharSet_UC[i].MIMEname);
+ }
+ EndSelect(fp0);
+ }
+
+#ifdef USE_IDN2
+ /* Internationalized Domain Names: SELECT */
+ {
+ PutLabel(fp0, gettext("Internationalized domain names"), idna_mode_string);
+ BeginSelect(fp0, idna_mode_string);
+ for (i = 0; idna_values[i].value != 0; i++) {
+ PutOption(fp0, idna_values[i].value == LYidnaMode,
+ idna_values[i].HtmlName,
+ idna_values[i].LongName);
+ }
+ EndSelect(fp0);
+ }
+#endif
+
+ /* Raw Mode: ON/OFF */
+ if (LYHaveCJKCharacterSet) {
+ /*
+ * Since CJK people hardly mixed with other world
+ * we split the header to make it more readable:
+ * "CJK mode" for CJK display charsets, and "Raw 8-bit" for others.
+ */
+ PutLabel(fp0, gettext("CJK mode"), raw_mode_string);
+ } else {
+ PutLabel(fp0, gettext("Raw 8-bit"), raw_mode_string);
+ }
+
+ BeginSelect(fp0, raw_mode_string);
+ PutOptValues(fp0, LYRawMode, bool_values);
+ EndSelect(fp0);
+
+ /* X Display: INPUT */
+ PutLabel(fp0, gettext("X Display"), x_display_string);
+ PutTextInput(fp0, x_display_string, NonNull(x_display), text_len, "");
+
+ /*
+ * Document Appearance
+ */
+ PutHeader(fp0, gettext("Document Appearance"));
+ /*****************************************************************/
+
+ /* Show Color: SELECT */
+#if defined(USE_SLANG) || defined(COLOR_CURSES)
+ SetupChosenShowColor();
+ PutLabel(fp0, gettext("Show color"), show_color_string);
+ if (no_option_save) {
+ MaybeSelect(fp0, !can_do_colors, show_color_string);
+ if (LYShowColor == SHOW_COLOR_NEVER) {
+ LYShowColor = SHOW_COLOR_OFF;
+ } else if (LYShowColor == SHOW_COLOR_ALWAYS) {
+ LYShowColor = SHOW_COLOR_ON;
+ }
+ PutOptValues(fp0, LYShowColor - SHOW_COLOR_OFF, bool_values);
+ } else {
+ BeginSelect(fp0, show_color_string);
+ if (can_do_colors) {
+ show_color_values[2].HtmlName = on_string;
+ show_color_values[3].LongName = always_string;
+ } else {
+ show_color_values[2].HtmlName = NULL; /* suppress "ON" - kw */
+ show_color_values[3].LongName = "Always try";
+ }
+ PutOptValues(fp0, LYChosenShowColor, show_color_values);
+ }
+ EndSelect(fp0);
+#endif /* USE_SLANG || COLOR_CURSES */
+
+#ifdef USE_COLOR_STYLE
+ /* Color style: ON/OFF */
+ if (HasOptValues(color_style_values)) {
+ PutLabel(fp0, gettext("Color style"), color_style_string);
+ BeginSelect(fp0, color_style_string);
+ PutOptValues(fp0, get_color_style_value(), color_style_values);
+ EndSelect(fp0);
+ }
+#endif
+
+#ifdef USE_DEFAULT_COLORS
+ /* Default colors: ON/OFF */
+ if (has_colors()) {
+ PutLabel(fp0, gettext("Default colors"), default_colors_string);
+ BeginSelect(fp0, default_colors_string);
+ PutOptValues(fp0, LYuse_default_colors, bool_values);
+ EndSelect(fp0);
+ }
+#endif
+
+ /* Show cursor: ON/OFF */
+ PutLabel(fp0, gettext("Show cursor"), show_cursor_string);
+ BeginSelect(fp0, show_cursor_string);
+ PutOptValues(fp0, LYShowCursor, bool_values);
+ EndSelect(fp0);
+
+ /* Underline links: ON/OFF */
+ PutLabel(fp0, gettext("Underline links"), underline_links_string);
+ BeginSelect(fp0, underline_links_string);
+ PutOptValues(fp0, LYUnderlineLinks, bool_values);
+ EndSelect(fp0);
+
+#ifdef USE_SCROLLBAR
+ /* Show scrollbar: ON/OFF */
+ PutLabel(fp0, gettext("Show scrollbar"), show_scrollbar_string);
+ BeginSelect(fp0, show_scrollbar_string);
+ PutOptValues(fp0, LYShowScrollbar, bool_values);
+ EndSelect(fp0);
+#endif
+
+ /* Select Popups: ON/OFF */
+ PutLabel(fp0, gettext("Popups for select fields"), select_popups_string);
+ BeginSelect(fp0, select_popups_string);
+ PutOptValues(fp0, LYSelectPopups, bool_values);
+ EndSelect(fp0);
+
+ /* HTML error recovery: SELECT */
+ PutLabel(fp0, gettext("HTML error recovery"), DTD_recovery_string);
+ BeginSelect(fp0, DTD_recovery_string);
+ PutOptValues(fp0, Old_DTD, DTD_type_values);
+ EndSelect(fp0);
+
+ /* Bad HTML messages: SELECT */
+ PutLabel(fp0, gettext("Bad HTML messages"), bad_html_string);
+ BeginSelect(fp0, bad_html_string);
+ PutOptValues(fp0, cfg_bad_html, bad_html_values);
+ EndSelect(fp0);
+
+ /* Show Images: SELECT */
+ PutLabel(fp0, gettext("Show images"), will_save_images());
+ BeginSelect(fp0, images_string);
+ PutOption(fp0, !pseudo_inline_alts && !clickable_images,
+ images_ignore_all_string,
+ images_ignore_all_string);
+ PutOption(fp0, pseudo_inline_alts && !clickable_images,
+ images_use_label_string,
+ images_use_label_string);
+ PutOption(fp0, clickable_images,
+ images_use_links_string,
+ images_use_links_string);
+ EndSelect(fp0);
+
+ /* Verbose Images: ON/OFF */
+ PutLabel(fp0, gettext("Verbose images"), verbose_images_string);
+ BeginSelect(fp0, verbose_images_string);
+ PutOptValues(fp0, verbose_img, verbose_images_type_values);
+ EndSelect(fp0);
+
+ /* Collapse BR Tags: ON/OFF */
+ PutLabel(fp0, gettext("Collapse BR tags"), collapse_br_tags_string);
+ BeginSelect(fp0, collapse_br_tags_string);
+ PutOptValues(fp0, LYCollapseBRs, collapse_br_tags_values);
+ EndSelect(fp0);
+
+ /* Trim blank lines: ON/OFF */
+ PutLabel(fp0, gettext("Trim blank lines"), trim_blank_lines_string);
+ BeginSelect(fp0, trim_blank_lines_string);
+ PutOptValues(fp0, LYtrimBlankLines, trim_blank_lines_values);
+ EndSelect(fp0);
+
+ /*
+ * Headers Transferred to Remote Servers
+ */
+ PutHeader(fp0, gettext("Headers Transferred to Remote Servers"));
+ /*****************************************************************/
+
+ /* Mail Address: INPUT */
+ PutLabel(fp0, gettext("Personal mail address"), mail_address_string);
+ PutTextInput(fp0, mail_address_string,
+ NonNull(personal_mail_address), text_len, "");
+
+#ifndef NO_ANONYMOUS_EMAIL
+ PutLabel(fp0, gettext("Personal name for mail"), personal_name_string);
+ PutTextInput(fp0, personal_name_string,
+ NonNull(personal_mail_name), text_len, "");
+#endif
+
+ /* Anonymous FTP Address: INPUT */
+#ifndef DISABLE_FTP
+ PutLabel(fp0, gettext("Password for anonymous ftp"), anonftp_password_string);
+ PutTextInput(fp0, anonftp_password_string,
+ NonNull(anonftp_password), text_len, "");
+#endif
+
+ /* Preferred content type: SELECT */
+ PutLabel(fp0, gettext("Preferred content type"), preferred_content_string);
+ BeginSelect(fp0, preferred_content_string);
+ PutOptValues(fp0, LYContentType, content_values);
+ EndSelect(fp0);
+
+ /* Preferred media type: SELECT */
+ PutLabel(fp0, gettext("Preferred media type"), preferred_media_string);
+ BeginSelect(fp0, preferred_media_string);
+ PutOptValues(fp0, LYAcceptMedia, media_values);
+ EndSelect(fp0);
+
+ /* Preferred encoding: SELECT */
+ PutLabel(fp0, gettext("Preferred encoding"), preferred_encoding_string);
+ BeginSelect(fp0, preferred_encoding_string);
+ PutOptValues(fp0, LYAcceptEncoding, encoding_values);
+ EndSelect(fp0);
+
+ /* Preferred Document Character Set: INPUT */
+ PutLabel(fp0, gettext("Preferred document character set"), preferred_doc_char_string);
+ PutTextInput(fp0, preferred_doc_char_string,
+ NonNull(pref_charset), cset_len + 2, "");
+
+ /* Preferred Document Language: INPUT */
+ PutLabel(fp0, gettext("Preferred document language"), preferred_doc_lang_string);
+ PutTextInput(fp0, preferred_doc_lang_string,
+ NonNull(language), cset_len + 2, "");
+
+ /* HTTP protocol SELECT */
+ PutLabel(fp0, gettext("HTTP protocol"), http_protocol_string);
+ BeginSelect(fp0, http_protocol_string);
+ PutOptValues(fp0, HTprotocolLevel, http_protocol_values);
+ EndSelect(fp0);
+
+ /* User Agent: INPUT */
+ if (!no_useragent) {
+ PutLabel(fp0, gettext("Send User-Agent header"), send_user_agent_string);
+ PutCheckBox(fp0, send_user_agent_string, LYSendUserAgent, "");
+ PutLabel(fp0, gettext("User-Agent header"), user_agent_string);
+ PutTextInput(fp0, user_agent_string,
+ NonNull(LYUserAgent), text_len, "");
+ }
+
+ /*
+ * Listing and Accessing Files
+ */
+ PutHeader(fp0, gettext("Listing and Accessing Files"));
+ /*****************************************************************/
+
+#ifndef DISABLE_FTP
+ /* FTP sort: SELECT */
+ PutLabel(fp0, gettext("Use Passive FTP"), passive_ftp_string);
+ BeginSelect(fp0, passive_ftp_string);
+ PutOptValues(fp0, ftp_passive, bool_values);
+ EndSelect(fp0);
+
+ /* FTP sort: SELECT */
+ PutLabel(fp0, gettext("FTP sort criteria"), ftp_sort_string);
+ BeginSelect(fp0, ftp_sort_string);
+ PutOptValues(fp0, HTfileSortMethod, ftp_sort_values);
+ EndSelect(fp0);
+#endif /* DISABLE_FTP */
+
+#ifdef DIRED_SUPPORT
+ /* Local Directory Sort: SELECT */
+ PutLabel(fp0, gettext("Local directory sort criteria"), dired_list_string);
+ BeginSelect(fp0, dired_list_string);
+ PutOptValues(fp0, dir_list_style, dired_list_values);
+ EndSelect(fp0);
+#ifdef LONG_LIST
+ /* Local Directory Order: SELECT */
+ PutLabel(fp0, gettext("Local directory sort order"), dired_sort_string);
+ BeginSelect(fp0, dired_sort_string);
+ PutOptValues(fp0, dir_list_order, dired_sort_values);
+ EndSelect(fp0);
+#endif /* LONG_LIST */
+#endif /* DIRED_SUPPORT */
+
+ /* Show dot files: ON/OFF */
+ if (!no_dotfiles) {
+ PutLabel(fp0, gettext("Show dot files"), show_dotfiles_string);
+ BeginSelect(fp0, show_dotfiles_string);
+ PutOptValues(fp0, show_dotfiles, bool_values);
+ EndSelect(fp0);
+ }
+
+ /* Execution links: SELECT */
+#if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS))
+ PutLabel(fp0, gettext("Execution links"), exec_links_string);
+ BeginSelect(fp0, exec_links_string);
+#ifndef NEVER_ALLOW_REMOTE_EXEC
+ PutOptValues(fp0, local_exec
+ ? EXEC_ALWAYS
+ : (local_exec_on_local_files
+ ? EXEC_LOCAL
+ : EXEC_NEVER),
+ exec_links_values);
+#else
+ PutOptValues(fp0, local_exec_on_local_files
+ ? EXEC_LOCAL
+ : EXEC_NEVER,
+ exec_links_values);
+#endif /* !NEVER_ALLOW_REMOTE_EXEC */
+ EndSelect(fp0);
+#endif /* ENABLE_OPTS_CHANGE_EXEC */
+
+ PutLabel(fp0, gettext("Pause when showing message"), no_pause_string);
+ BeginSelect(fp0, no_pause_string);
+ PutOptValues(fp0, !no_pause, bool_values);
+ EndSelect(fp0);
+
+#ifdef USE_READPROGRESS
+ /* Show transfer rate: SELECT */
+ PutLabel(fp0, gettext("Show transfer rate"), show_rate_string);
+ BeginSelect(fp0, show_rate_string);
+ for (i = 0; rate_values[i].LongName != 0; ++i) {
+ char *message = NULL;
+
+ HTSprintf0(&message,
+ rate_values[i].LongName,
+ HTProgressUnits(rate_values[i].value));
+ PutOption(fp0,
+ LYTransferRate == rate_values[i].value,
+ rate_values[i].HtmlName,
+ message);
+ FREE(message);
+ }
+ EndSelect(fp0);
+#endif /* USE_READPROGRESS */
+
+ /*
+ * Special Files and Screens
+ */
+ PutHeader(fp0, gettext("Special Files and Screens"));
+ /*****************************************************************/
+
+ /* Multi-Bookmark Mode: SELECT */
+ if (!LYMBMBlocked) {
+ PutLabel(fp0, gettext("Multi-bookmarks"), mbm_string);
+ BeginSelect(fp0, mbm_string);
+ PutOptValues(fp0, LYMultiBookmarks, mbm_values);
+ EndSelect(fp0);
+ }
+
+ /* Bookmarks File Menu: LINK/INPUT */
+ if (LYMultiBookmarks) {
+ PutLabel(fp0, gettext("Review/edit Bookmarks files"), mbm_string);
+ fprintf(fp0, "<a href=\"%s\">%s</a>\n",
+ LYNXOPTIONS_PAGE(MBM_LINK),
+ LYEntifyTitle(&buffer, gettext("Goto multi-bookmark menu")));
+ } else {
+ PutLabel(fp0, gettext("Bookmarks file"), single_bookmark_string);
+ PutTextInput(fp0, single_bookmark_string,
+ NonNull(bookmark_page), text_len, "");
+ }
+
+#ifdef USE_SESSIONS
+ /* Auto Session: ON/OFF */
+ PutLabel(fp0, gettext("Auto Session"), auto_session_string);
+ BeginSelect(fp0, auto_session_string);
+ PutOptValues(fp0, LYAutoSession, bool_values);
+ EndSelect(fp0);
+
+ /* Session File Menu: INPUT */
+ PutLabel(fp0, gettext("Session file"), single_session_string);
+ PutTextInput(fp0, single_session_string,
+ NonNull(LYSessionFile), text_len, "");
+#endif
+
+ /* Visited Pages: SELECT */
+ PutLabel(fp0, gettext("Visited Pages"), visited_links_string);
+ LYMenuVisitedLinks(fp0, disable_all);
+
+ if (!no_lynxcfg_info) {
+ fprintf(fp0, "\n %s<a href=\"%s\">lynx.cfg</a>.\n",
+ LYEntifyTitle(&buffer, gettext("View the file ")),
+ STR_LYNXCFG);
+ }
+
+ fprintf(fp0, "\n</pre>\n");
+
+ /* Submit/Reset */
+ if (!disable_all) {
+ fprintf(fp0, "<p align=center>\n");
+ fprintf(fp0,
+ "<input type=\"submit\" value=\"%s\"> - \n",
+ LYEntifyValue(&buffer, ACCEPT_CHANGES));
+ fprintf(fp0,
+ "<input type=\"reset\" value=\"%s\"> - \n",
+ LYEntifyValue(&buffer, RESET_CHANGES));
+ fprintf(fp0, "%s\n", LYEntifyTitle(&buffer, CANCEL_CHANGES));
+ }
+
+ /*
+ * close HTML
+ */
+ fprintf(fp0, "</form>\n");
+ EndInternalPage(fp0);
+
+ FREE(buffer);
+
+ LYCloseTempFP(fp0);
+ return (NORMAL);
+}
+
+#endif /* !NO_OPTION_FORMS */