1 /* $LynxId: LYOptions.c,v 1.183 2021/07/05 21:17:42 tom Exp $ */
2 #include <HTUtils.h>
3 #include <HTFTP.h>
4 #include <HTTP.h> /* 'reloading' flag */
5 #include <HTML.h>
6 #include <LYCurses.h>
7 #include <LYUtils.h>
8 #include <LYStrings.h>
9 #include <LYGlobalDefs.h>
10 #include <LYHistory.h>
11 #include <LYOptions.h>
12 #include <LYSignal.h>
13 #include <LYClean.h>
14 #include <LYCharSets.h>
15 #include <UCMap.h>
16 #include <UCAux.h>
17 #include <LYKeymap.h>
18 #include <LYrcFile.h>
19 #include <HTAlert.h>
20 #include <LYBookmark.h>
21 #include <GridText.h>
22 #include <LYGetFile.h>
23 #include <LYReadCFG.h>
24 #include <LYPrettySrc.h>
25 #include <HTFile.h>
26 #include <LYCharUtils.h>
27
28 #ifdef USE_COLOR_STYLE
29 #include <LYStyle.h>
30 #endif
31
32 #include <LYLeaks.h>
33
34 BOOLEAN term_options;
35
36 #define TOP_LINK "/"
37 #define MBM_LINK "//MBM_MENU"
38
39 #define MARGIN_STR (no_margins ? "" : " ")
40 #define MARGIN_LEN (no_margins ? 0 : 2)
41
42 static void terminate_options(int sig);
43
44 #define COL_OPTION_VALUES 36 /* display column where option values start */
45
46 #if defined(USE_SLANG) || defined(COLOR_CURSES)
47 static BOOLEAN can_do_colors = FALSE;
48 #endif
49
50 static int LYChosenShowColor = SHOW_COLOR_UNKNOWN; /* whether to show and save */
51
LYCheckUserAgent(void)52 BOOLEAN LYCheckUserAgent(void)
53 {
54 if (non_empty(LYUserAgent)) {
55 if (strstr(LYUserAgent, "Lynx") == 0
56 && strstr(LYUserAgent, "lynx") == 0
57 && strstr(LYUserAgent, "L_y_n_x") == 0
58 && strstr(LYUserAgent, "l_y_n_x") == 0) {
59 return FALSE;
60 }
61 }
62 return TRUE;
63 }
64
validate_x_display(void)65 static void validate_x_display(void)
66 {
67 char *cp;
68
69 if ((cp = LYgetXDisplay()) != NULL) {
70 StrAllocCopy(x_display, cp);
71 } else {
72 FREE(x_display);
73 }
74 }
75
summarize_x_display(char * display_option)76 static void summarize_x_display(char *display_option)
77 {
78 if ((x_display == NULL && *display_option == '\0') ||
79 (x_display != NULL && !strcmp(x_display, display_option))) {
80 if (x_display == NULL && LYisConfiguredForX == TRUE) {
81 _statusline(VALUE_ACCEPTED_WARNING_X);
82 } else if (x_display != NULL && LYisConfiguredForX == FALSE) {
83 _statusline(VALUE_ACCEPTED_WARNING_NONX);
84 } else {
85 _statusline(VALUE_ACCEPTED);
86 }
87 } else {
88 if (*display_option) {
89 _statusline(FAILED_TO_SET_DISPLAY);
90 } else {
91 _statusline(FAILED_CLEAR_SET_DISPLAY);
92 }
93 }
94 }
95
SetupChosenShowColor(void)96 static void SetupChosenShowColor(void)
97 {
98 #if defined(USE_SLANG) || defined(COLOR_CURSES)
99 can_do_colors = TRUE;
100 #if defined(COLOR_CURSES)
101 if (LYCursesON) /* could crash if called before initialization */
102 can_do_colors = (has_colors()
103 ? TRUE
104 : FALSE);
105 #endif
106 if (!no_option_save) {
107 if (LYChosenShowColor == SHOW_COLOR_UNKNOWN) {
108 switch (LYrcShowColor) {
109 case SHOW_COLOR_NEVER:
110 LYChosenShowColor =
111 (LYShowColor >= SHOW_COLOR_ON) ?
112 SHOW_COLOR_ON : SHOW_COLOR_NEVER;
113 break;
114 case SHOW_COLOR_ALWAYS:
115 if (!can_do_colors)
116 LYChosenShowColor = SHOW_COLOR_ALWAYS;
117 else
118 LYChosenShowColor =
119 (LYShowColor >= SHOW_COLOR_ON) ?
120 SHOW_COLOR_ALWAYS : SHOW_COLOR_OFF;
121 break;
122 default:
123 LYChosenShowColor =
124 (LYShowColor >= SHOW_COLOR_ON) ?
125 SHOW_COLOR_ON : SHOW_COLOR_OFF;
126 }
127 }
128 }
129 #endif /* USE_SLANG || COLOR_CURSES */
130 }
131
132 #ifndef NO_OPTION_MENU
133 static int boolean_choice(int status,
134 int line,
135 int column,
136 STRING2PTR choices);
137
138 #define LYChooseBoolean(status, line, column, choices) \
139 (BOOLEAN) boolean_choice(status, line, column, (const char *const*)choices)
140
141 #define LYChooseEnum(status, line, column, choices) \
142 boolean_choice(status, line, column, (const char *const*)choices)
143
144 #define MAXCHOICES 10
145
146 /*
147 * Values for the options menu. - FM
148 *
149 * L_foo values are the Y coordinates for the menu item.
150 * B_foo values are the X coordinates for the item's prompt string.
151 * C_foo values are the X coordinates for the item's value string.
152 */
153 #define L_EDITOR 2
154 #define L_DISPLAY 3
155
156 #define L_HOME 4
157 #define C_MULTI 24
158 #define B_BOOK 34
159 #define C_DEFAULT 50
160
161 #define L_FTPSTYPE 5
162 #define L_MAIL_ADDRESS 6
163 #define L_SSEARCH 7
164 #define L_LANGUAGE 8
165 #define L_PREF_CHARSET 9
166 #define L_ASSUME_CHARSET (L_PREF_CHARSET + 1)
167 #define L_CHARSET 10
168 #define L_RAWMODE 11
169
170 #define L_COLOR L_RAWMODE
171 #define B_COLOR 44
172 #define C_COLOR 62
173
174 #define L_BOOL_A 12
175 #define B_VIKEYS 5
176 #define C_VIKEYS 15
177 #define B_EMACSKEYS 22
178 #define C_EMACSKEYS 36
179 #define B_SHOW_DOTFILES 44
180 #define C_SHOW_DOTFILES 62
181
182 #define L_BOOL_B 13
183 #define B_SELECT_POPUPS 5
184 #define C_SELECT_POPUPS 36
185 #define B_SHOW_CURSOR 44
186 #define C_SHOW_CURSOR 62
187
188 #define L_KEYPAD 14
189 #define L_LINEED 15
190 #define L_LAYOUT 16
191
192 #ifdef DIRED_SUPPORT
193 #define L_DIRED 17
194 #define L_USER_MODE 18
195 #define L_USER_AGENT 19
196 #define L_EXEC 20
197 #else
198 #define L_USER_MODE 17
199 #define L_USER_AGENT 18
200 #define L_EXEC 19
201 #endif /* DIRED_SUPPORT */
202
203 #define L_VERBOSE_IMAGES L_USER_MODE
204 #define B_VERBOSE_IMAGES 50
205 #define C_VERBOSE_IMAGES (B_VERBOSE_IMAGES + 21)
206
207 /* a kludge to add assume_charset only in ADVANCED mode... */
208 #define L_Bool_A (use_assume_charset ? L_BOOL_A + 1 : L_BOOL_A)
209 #define L_Bool_B (use_assume_charset ? L_BOOL_B + 1 : L_BOOL_B)
210 #define L_Exec (use_assume_charset ? L_EXEC + 1 : L_EXEC)
211 #define L_Rawmode (use_assume_charset ? L_RAWMODE + 1 : L_RAWMODE)
212 #define L_Charset (use_assume_charset ? L_CHARSET + 1 : L_CHARSET)
213 #define L_Color (use_assume_charset ? L_COLOR + 1 : L_COLOR)
214 #define L_Keypad (use_assume_charset ? L_KEYPAD + 1 : L_KEYPAD)
215 #define L_Lineed (use_assume_charset ? L_LINEED + 1 : L_LINEED)
216 #define L_Layout (use_assume_charset ? L_LAYOUT + 1 : L_LAYOUT)
217 #define L_Dired (use_assume_charset ? L_DIRED + 1 : L_DIRED)
218 #define L_User_Mode (use_assume_charset ? L_USER_MODE + 1 : L_USER_MODE)
219 #define L_User_Agent (use_assume_charset ? L_USER_AGENT + 1 : L_USER_AGENT)
220
221 #define LPAREN '('
222 #define RPAREN ')'
223
add_it(char * text,int len)224 static int add_it(char *text, int len)
225 {
226 if (len) {
227 text[len] = '\0';
228 LYaddstr(text);
229 }
230 return 0;
231 }
232
233 /*
234 * addlbl() is used instead of plain LYaddstr() in old-style options menu
235 * to show hot keys in bold.
236 */
addlbl(const char * text)237 static void addlbl(const char *text)
238 {
239 char actual[80];
240 int s, d;
241 BOOL b = FALSE;
242
243 for (s = d = 0; text[s]; s++) {
244 actual[d++] = text[s];
245 if (text[s] == LPAREN) {
246 d = add_it(actual, d - 1);
247 lynx_start_bold();
248 b = TRUE;
249 actual[d++] = text[s];
250 } else if (text[s] == RPAREN) {
251 d = add_it(actual, d);
252 lynx_stop_bold();
253 b = FALSE;
254 }
255 }
256 add_it(actual, d);
257 if (b)
258 lynx_stop_bold();
259 }
260
261 #if !defined(VMS) || defined(USE_SLANG)
262 #define HANDLE_LYOPTIONS \
263 if (term_options) { \
264 term_options = FALSE; \
265 } else { \
266 AddValueAccepted = TRUE; \
267 } \
268 goto draw_options
269 #else
270 #define HANDLE_LYOPTIONS \
271 term_options = FALSE; \
272 if (use_assume_charset != old_use_assume_charset) \
273 goto draw_options
274 #endif /* !VMS || USE_SLANG */
275
LYoptions(void)276 void LYoptions(void)
277 {
278 #define ShowBool(value) LYaddstr((value) ? "ON " : "OFF")
279 static const char *bool_choices[] =
280 {
281 "OFF",
282 "ON",
283 NULL
284 };
285 static const char *const caseless_choices[] =
286 {
287 "CASE INSENSITIVE",
288 "CASE SENSITIVE",
289 NULL
290 };
291
292 #ifdef DIRED_SUPPORT
293 static const char *dirList_choices[] =
294 {
295 "Directories first",
296 "Files first",
297 "Mixed style",
298 NULL
299 };
300 #endif
301
302 #if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS))
303 static const char *exec_choices[] =
304 {
305 "ALWAYS OFF",
306 "FOR LOCAL FILES ONLY",
307 #ifndef NEVER_ALLOW_REMOTE_EXEC
308 "ALWAYS ON",
309 #endif /* !NEVER_ALLOW_REMOTE_EXEC */
310 NULL
311 };
312 #endif
313 static const char *fileSort_choices[] =
314 {
315 "By Filename",
316 "By Type",
317 "By Size",
318 "By Date",
319 NULL
320 };
321 static const char *keypad_choices[] =
322 {
323 "Numbers act as arrows",
324 "Links are numbered",
325 "Links and form fields are numbered",
326 NULL
327 };
328 static const char *mbm_choices[] =
329 {
330 "OFF ",
331 "STANDARD",
332 "ADVANCED",
333 NULL
334 };
335 static const char *userMode_choices[] =
336 {
337 "Novice",
338 "Intermediate",
339 "Advanced",
340 NULL
341 };
342
343 #if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS))
344 int itmp;
345 #endif /* ENABLE_OPTS_CHANGE_EXEC */
346 int response, ch;
347
348 /*
349 * If the user changes the display we need memory to put it in.
350 */
351 bstring *my_data = NULL;
352 char *choices[MAXCHOICES];
353 int CurrentCharSet = current_char_set;
354 int CurrentAssumeCharSet = UCLYhndl_for_unspec;
355 int CurrentShowColor = LYShowColor;
356 BOOLEAN CurrentRawMode = LYRawMode;
357 BOOLEAN AddValueAccepted = FALSE;
358 BOOL use_assume_charset;
359
360 #if defined(VMS) || defined(USE_SLANG)
361 BOOL old_use_assume_charset;
362 #endif
363
364 #ifdef DIRED_SUPPORT
365 #ifdef ENABLE_OPTS_CHANGE_EXEC
366 if (LYlines < 24) {
367 HTAlert(OPTION_SCREEN_NEEDS_24);
368 return;
369 }
370 #else
371 if (LYlines < 23) {
372 HTAlert(OPTION_SCREEN_NEEDS_23);
373 return;
374 }
375 #endif /* ENABLE_OPTS_CHANGE_EXEC */
376 #else
377 #ifdef ENABLE_OPTS_CHANGE_EXEC
378 if (LYlines < 23) {
379 HTAlert(OPTION_SCREEN_NEEDS_23);
380 return;
381 }
382 #else
383 if (LYlines < 22) {
384 HTAlert(OPTION_SCREEN_NEEDS_22);
385 return;
386 }
387 #endif /* ENABLE_OPTS_CHANGE_EXEC */
388 #endif /* DIRED_SUPPORT */
389
390 term_options = FALSE;
391 LYStatusLine = (LYlines - 1); /* screen is otherwise too crowded */
392 signal(SIGINT, terminate_options);
393 if (no_option_save) {
394 if (LYShowColor == SHOW_COLOR_NEVER) {
395 LYShowColor = SHOW_COLOR_OFF;
396 } else if (LYShowColor == SHOW_COLOR_ALWAYS) {
397 LYShowColor = SHOW_COLOR_ON;
398 }
399 #if defined(USE_SLANG) || defined(COLOR_CURSES)
400 } else {
401 SetupChosenShowColor();
402 #endif /* USE_SLANG || COLOR_CURSES */
403 }
404
405 use_assume_charset = (BOOLEAN) (user_mode == ADVANCED_MODE);
406
407 draw_options:
408
409 #if defined(VMS) || defined(USE_SLANG)
410 old_use_assume_charset = use_assume_charset;
411 #endif
412 /*
413 * NOTE that printw() should be avoided for strings that might have
414 * non-ASCII or multibyte/CJK characters. - FM
415 */
416 #if defined(FANCY_CURSES) || defined (USE_SLANG)
417 if (enable_scrollback) {
418 LYclear();
419 } else {
420 LYerase();
421 }
422 #else
423 LYclear();
424 #endif /* FANCY_CURSES || USE_SLANG */
425 LYmove(0, 5);
426
427 lynx_start_h1_color();
428 LYaddstr(" Options Menu (");
429 LYaddstr(LYNX_NAME);
430 LYaddstr(" Version ");
431 LYaddstr(LYNX_VERSION);
432 LYaddch(')');
433 lynx_stop_h1_color();
434 LYmove(L_EDITOR, 5);
435 addlbl("(E)ditor : ");
436 LYaddstr(non_empty(editor) ? editor : "NONE");
437
438 LYmove(L_DISPLAY, 5);
439 addlbl("(D)ISPLAY variable : ");
440 LYaddstr(non_empty(x_display) ? x_display : "NONE");
441
442 LYmove(L_HOME, 5);
443 addlbl("mu(L)ti-bookmarks: ");
444 LYaddstr(mbm_choices[LYMultiBookmarks]);
445 LYmove(L_HOME, B_BOOK);
446 if (LYMultiBookmarks != MBM_OFF) {
447 addlbl("review/edit (B)ookmarks files");
448 } else {
449 addlbl("(B)ookmark file: ");
450 LYaddstr(non_empty(bookmark_page) ? bookmark_page : "NONE");
451 }
452
453 LYmove(L_FTPSTYPE, 5);
454 addlbl("(F)TP sort criteria : ");
455 LYaddstr((HTfileSortMethod == FILE_BY_NAME ? "By Filename" :
456 (HTfileSortMethod == FILE_BY_SIZE ? "By Size " :
457 (HTfileSortMethod == FILE_BY_TYPE ? "By Type " :
458 "By Date "))));
459
460 LYmove(L_MAIL_ADDRESS, 5);
461 addlbl("(P)ersonal mail address : ");
462 LYaddstr(non_empty(personal_mail_address) ?
463 personal_mail_address : "NONE");
464
465 LYmove(L_SSEARCH, 5);
466 addlbl("(S)earching type : ");
467 LYaddstr(LYcase_sensitive ? "CASE SENSITIVE " : "CASE INSENSITIVE");
468
469 LYmove(L_Charset, 5);
470 addlbl("display (C)haracter set : ");
471 LYaddstr(LYchar_set_names[current_char_set]);
472
473 LYmove(L_LANGUAGE, 5);
474 addlbl("preferred document lan(G)uage: ");
475 LYaddstr(non_empty(language) ? language : "NONE");
476
477 LYmove(L_PREF_CHARSET, 5);
478 addlbl("preferred document c(H)arset : ");
479 LYaddstr(non_empty(pref_charset) ? pref_charset : "NONE");
480
481 if (use_assume_charset) {
482 LYmove(L_ASSUME_CHARSET, 5);
483 addlbl("(^A)ssume charset if unknown : ");
484 if (UCAssume_MIMEcharset)
485 LYaddstr(UCAssume_MIMEcharset);
486 else
487 LYaddstr((UCLYhndl_for_unspec >= 0) ?
488 LYCharSet_UC[UCLYhndl_for_unspec].MIMEname
489 : "NONE");
490 }
491
492 LYmove(L_Rawmode, 5);
493 addlbl("Raw 8-bit or CJK m(O)de : ");
494 ShowBool(LYRawMode);
495
496 #if defined(USE_SLANG) || defined(COLOR_CURSES)
497 LYmove(L_Color, B_COLOR);
498 addlbl("show color (&) : ");
499 if (no_option_save) {
500 ShowBool(LYShowColor == SHOW_COLOR_OFF);
501 } else {
502 switch (LYChosenShowColor) {
503 case SHOW_COLOR_NEVER:
504 LYaddstr("NEVER ");
505 break;
506 case SHOW_COLOR_OFF:
507 LYaddstr("OFF");
508 break;
509 case SHOW_COLOR_ON:
510 LYaddstr("ON ");
511 break;
512 case SHOW_COLOR_ALWAYS:
513 #if defined(COLOR_CURSES)
514 if (!has_colors())
515 LYaddstr("Always try");
516 else
517 #endif
518 LYaddstr("ALWAYS ");
519 }
520 }
521 #endif /* USE_SLANG || COLOR_CURSES */
522
523 LYmove(L_Bool_A, B_VIKEYS);
524 addlbl("(V)I keys: ");
525 ShowBool(vi_keys);
526
527 LYmove(L_Bool_A, B_EMACSKEYS);
528 addlbl("e(M)acs keys: ");
529 ShowBool(emacs_keys);
530
531 LYmove(L_Bool_A, B_SHOW_DOTFILES);
532 addlbl("sho(W) dot files: ");
533 ShowBool(!no_dotfiles && show_dotfiles);
534
535 LYmove(L_Bool_B, B_SELECT_POPUPS);
536 addlbl("popups for selec(T) fields : ");
537 ShowBool(LYSelectPopups);
538
539 LYmove(L_Bool_B, B_SHOW_CURSOR);
540 addlbl("show cursor (@) : ");
541 ShowBool(LYShowCursor);
542
543 LYmove(L_Keypad, 5);
544 addlbl("(K)eypad mode : ");
545 LYaddstr((fields_are_numbered() && links_are_numbered())
546 ? "Links and form fields are numbered"
547 : (links_are_numbered()
548 ? "Links are numbered "
549 : (fields_are_numbered()
550 ? "Form fields are numbered "
551 : "Numbers act as arrows ")));
552
553 LYmove(L_Lineed, 5);
554 addlbl("li(N)e edit style : ");
555 LYaddstr(LYEditorNames[current_lineedit]);
556
557 #ifdef EXP_KEYBOARD_LAYOUT
558 LYmove(L_Layout, 5);
559 addlbl("Ke(Y)board layout : ");
560 LYaddstr(LYKbLayoutNames[current_layout]);
561 #endif
562
563 #ifdef DIRED_SUPPORT
564 LYmove(L_Dired, 5);
565 addlbl("l(I)st directory style : ");
566 LYaddstr((dir_list_style == FILES_FIRST) ? "Files first " :
567 ((dir_list_style == MIXED_STYLE) ? "Mixed style " :
568 "Directories first"));
569 #endif /* DIRED_SUPPORT */
570
571 LYmove(L_User_Mode, 5);
572 addlbl("(U)ser mode : ");
573 LYaddstr((user_mode == NOVICE_MODE) ? "Novice " :
574 ((user_mode == INTERMEDIATE_MODE) ? "Intermediate" :
575 "Advanced "));
576
577 addlbl(" verbose images (!) : ");
578 ShowBool(verbose_img);
579
580 LYmove(L_User_Agent, 5);
581 addlbl("user (A)gent : ");
582 LYaddstr(non_empty(LYUserAgent) ? LYUserAgent : "NONE");
583
584 #if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS))
585 LYmove(L_Exec, 5);
586 addlbl("local e(X)ecution links : ");
587 #ifndef NEVER_ALLOW_REMOTE_EXEC
588 LYaddstr(local_exec ? "ALWAYS ON " :
589 (local_exec_on_local_files ? "FOR LOCAL FILES ONLY" :
590 "ALWAYS OFF "));
591 #else
592 LYaddstr(local_exec_on_local_files ? "FOR LOCAL FILES ONLY" :
593 "ALWAYS OFF ");
594 #endif /* !NEVER_ALLOW_REMOTE_EXEC */
595 #endif /* ENABLE_OPTS_CHANGE_EXEC */
596
597 LYmove(LYlines - 3, 2);
598 LYaddstr(SELECT_SEGMENT);
599 lynx_start_bold();
600 LYaddstr(CAP_LETT_SEGMENT);
601 lynx_stop_bold();
602 LYaddstr(OF_OPT_LINE_SEGMENT);
603 if (!no_option_save) {
604 LYaddstr(" '");
605 lynx_start_bold();
606 LYaddstr(">");
607 lynx_stop_bold();
608 LYaddstr("'");
609 LYaddstr(TO_SAVE_SEGMENT);
610 }
611 LYaddstr(OR_SEGMENT);
612 LYaddstr("'");
613 lynx_start_bold();
614 LYaddstr("r");
615 lynx_stop_bold();
616 LYaddstr("'");
617 LYaddstr(TO_RETURN_SEGMENT);
618
619 response = 0;
620 while (response != 'R' &&
621 !LYisNonAlnumKeyname(response, LYK_PREV_DOC) &&
622 response != '>' && !term_options &&
623 !LYCharIsINTERRUPT_NO_letter(response)) {
624 if (AddValueAccepted == TRUE) {
625 _statusline(VALUE_ACCEPTED);
626 AddValueAccepted = FALSE;
627 }
628 LYmove((LYlines - 2), 0);
629 lynx_start_prompt_color();
630 LYaddstr(COMMAND_PROMPT);
631 lynx_stop_prompt_color();
632
633 LYrefresh();
634 response = LYgetch_single();
635 if (term_options || LYCharIsINTERRUPT_NO_letter(response))
636 response = 'R';
637 if (LYisNonAlnumKeyname(response, LYK_REFRESH)) {
638 lynx_force_repaint();
639 goto draw_options;
640 }
641 switch (response) {
642 case 'E': /* Change the editor. */
643 if (no_editor) {
644 _statusline(EDIT_DISABLED);
645 } else if (system_editor) {
646 _statusline(EDITOR_LOCKED);
647 } else {
648 if (non_empty(editor)) {
649 BStrCopy0(my_data, editor);
650 } else { /* clear the NONE */
651 LYmove(L_EDITOR, COL_OPTION_VALUES);
652 LYaddstr(" ");
653 BStrCopy0(my_data, "");
654 }
655 _statusline(ACCEPT_DATA);
656 LYmove(L_EDITOR, COL_OPTION_VALUES);
657 lynx_start_bold();
658 ch = LYgetBString(&my_data, FALSE, 0, NORECALL);
659 lynx_stop_bold();
660 LYmove(L_EDITOR, COL_OPTION_VALUES);
661 if (term_options || ch == -1) {
662 LYaddstr(non_empty(editor) ?
663 editor : "NONE");
664 } else if (isBEmpty(my_data)) {
665 FREE(editor);
666 LYaddstr("NONE");
667 } else {
668 StrAllocCopy(editor, my_data->str);
669 LYaddstr(editor);
670 }
671 LYclrtoeol();
672 if (ch == -1) {
673 HTInfoMsg(CANCELLED);
674 HTInfoMsg("");
675 } else {
676 _statusline(VALUE_ACCEPTED);
677 }
678 }
679 response = ' ';
680 break;
681
682 case 'D': /* Change the display. */
683 if (non_empty(x_display)) {
684 BStrCopy0(my_data, x_display);
685 } else { /* clear the NONE */
686 LYmove(L_DISPLAY, COL_OPTION_VALUES);
687 LYaddstr(" ");
688 BStrCopy0(my_data, "");
689 }
690 _statusline(ACCEPT_DATA);
691 LYmove(L_DISPLAY, COL_OPTION_VALUES);
692 lynx_start_bold();
693 ch = LYgetBString(&my_data, FALSE, 0, NORECALL);
694 lynx_stop_bold();
695 LYmove(L_DISPLAY, COL_OPTION_VALUES);
696
697 #ifdef VMS
698 #define CompareEnvVars(a,b) strcasecomp(a, b)
699 #else
700 #define CompareEnvVars(a,b) strcmp(a, b)
701 #endif /* VMS */
702
703 if ((term_options || ch == -1) ||
704 (x_display != NULL &&
705 !CompareEnvVars(x_display, my_data->str))) {
706 /*
707 * Cancelled, or a non-NULL display string wasn't changed. -
708 * FM
709 */
710 LYaddstr(non_empty(x_display) ? x_display : "NONE");
711 LYclrtoeol();
712 if (ch == -1) {
713 HTInfoMsg(CANCELLED);
714 HTInfoMsg("");
715 } else {
716 _statusline(VALUE_ACCEPTED);
717 }
718 response = ' ';
719 break;
720 } else if (isBEmpty(my_data)) {
721 if ((x_display == NULL) ||
722 (x_display != NULL && *x_display == '\0')) {
723 /*
724 * NULL or zero-length display string wasn't changed. - FM
725 */
726 LYaddstr("NONE");
727 LYclrtoeol();
728 _statusline(VALUE_ACCEPTED);
729 response = ' ';
730 break;
731 }
732 }
733 /*
734 * Set the new DISPLAY variable. - FM
735 */
736 LYsetXDisplay(my_data->str);
737 validate_x_display();
738 LYaddstr(x_display ? x_display : "NONE");
739 LYclrtoeol();
740 summarize_x_display(my_data->str);
741 response = ' ';
742 break;
743
744 case 'L': /* Change multibookmarks option. */
745 if (LYMBMBlocked) {
746 _statusline(MULTIBOOKMARKS_DISALLOWED);
747 response = ' ';
748 break;
749 }
750 if (!LYSelectPopups) {
751 LYMultiBookmarks = LYChooseEnum(LYMultiBookmarks,
752 L_HOME, C_MULTI,
753 mbm_choices);
754 } else {
755 LYMultiBookmarks = LYChoosePopup(LYMultiBookmarks,
756 L_HOME, (C_MULTI - 1),
757 mbm_choices,
758 3, FALSE, FALSE);
759 }
760 #if defined(VMS) || defined(USE_SLANG)
761 if (LYSelectPopups) {
762 LYmove(L_HOME, C_MULTI);
763 LYclrtoeol();
764 LYaddstr(mbm_choices[LYMultiBookmarks]);
765 }
766 #endif /* VMS || USE_SLANG */
767 #if !defined(VMS) && !defined(USE_SLANG)
768 if (!LYSelectPopups)
769 #endif /* !VMS && !USE_SLANG */
770 {
771 LYmove(L_HOME, B_BOOK);
772 LYclrtoeol();
773 if (LYMultiBookmarks != MBM_OFF) {
774 LYaddstr(gettext("review/edit B)ookmarks files"));
775 } else {
776 LYaddstr(gettext("B)ookmark file: "));
777 LYaddstr(non_empty(bookmark_page) ?
778 bookmark_page : "NONE");
779 }
780 }
781 response = ' ';
782 if (LYSelectPopups) {
783 HANDLE_LYOPTIONS;
784 }
785 break;
786
787 case 'B': /* Change the bookmark page location. */
788 /*
789 * Anonymous users should not be allowed to change the bookmark
790 * page.
791 */
792 if (!no_bookmark) {
793 if (LYMultiBookmarks != MBM_OFF) {
794 edit_bookmarks();
795 signal(SIGINT, terminate_options);
796 goto draw_options;
797 }
798 if (non_empty(bookmark_page)) {
799 BStrCopy0(my_data, bookmark_page);
800 } else { /* clear the NONE */
801 LYmove(L_HOME, C_DEFAULT);
802 LYclrtoeol();
803 BStrCopy0(my_data, "");
804 }
805 _statusline(ACCEPT_DATA);
806 LYmove(L_HOME, C_DEFAULT);
807 lynx_start_bold();
808 ch = LYgetBString(&my_data, FALSE, 0, NORECALL);
809 lynx_stop_bold();
810 LYmove(L_HOME, C_DEFAULT);
811 BStrAlloc(my_data, my_data->len + LY_MAXPATH); /* lengthen */
812 if (term_options ||
813 ch == -1 || isBEmpty(my_data)) {
814 LYaddstr(non_empty(bookmark_page) ?
815 bookmark_page : "NONE");
816 } else if (!LYPathOffHomeOK(my_data->str, (size_t) my_data->len)) {
817 LYaddstr(non_empty(bookmark_page) ?
818 bookmark_page : "NONE");
819 LYclrtoeol();
820 _statusline(USE_PATH_OFF_HOME);
821 response = ' ';
822 break;
823 } else {
824 StrAllocCopy(bookmark_page, my_data->str);
825 StrAllocCopy(MBM_A_subbookmark[0], bookmark_page);
826 LYaddstr(bookmark_page);
827 }
828 LYclrtoeol();
829 if (ch == -1) {
830 HTInfoMsg(CANCELLED);
831 HTInfoMsg("");
832 } else {
833 _statusline(VALUE_ACCEPTED);
834 }
835 } else { /* anonymous */
836 _statusline(BOOKMARK_CHANGE_DISALLOWED);
837 }
838 response = ' ';
839 break;
840
841 case 'F': /* Change ftp directory sorting. */
842 if (!LYSelectPopups) {
843 HTfileSortMethod = LYChooseEnum(HTfileSortMethod,
844 L_FTPSTYPE, -1,
845 fileSort_choices);
846 } else {
847 HTfileSortMethod = LYChoosePopup(HTfileSortMethod,
848 L_FTPSTYPE, -1,
849 fileSort_choices,
850 4, FALSE, FALSE);
851 #if defined(VMS) || defined(USE_SLANG)
852 LYmove(L_FTPSTYPE, COL_OPTION_VALUES);
853 LYclrtoeol();
854 LYaddstr(fileSort_choices[HTfileSortMethod]);
855 #endif /* VMS || USE_SLANG */
856 }
857 response = ' ';
858 if (LYSelectPopups) {
859 HANDLE_LYOPTIONS;
860 }
861 break;
862
863 case 'P': /* Change personal mail address for From headers. */
864 if (non_empty(personal_mail_address)) {
865 BStrCopy0(my_data, personal_mail_address);
866 } else { /* clear the NONE */
867 LYmove(L_MAIL_ADDRESS, COL_OPTION_VALUES);
868 LYaddstr(" ");
869 BStrCopy0(my_data, "");
870 }
871 _statusline(ACCEPT_DATA);
872 LYmove(L_MAIL_ADDRESS, COL_OPTION_VALUES);
873 lynx_start_bold();
874 ch = LYgetBString(&my_data, FALSE, 0, NORECALL);
875 lynx_stop_bold();
876 LYmove(L_MAIL_ADDRESS, COL_OPTION_VALUES);
877 if (term_options || ch == -1) {
878 LYaddstr((personal_mail_address &&
879 *personal_mail_address) ?
880 personal_mail_address : "NONE");
881 } else if (isBEmpty(my_data)) {
882 FREE(personal_mail_address);
883 LYaddstr("NONE");
884 } else {
885 StrAllocCopy(personal_mail_address, my_data->str);
886 LYaddstr(personal_mail_address);
887 }
888 LYclrtoeol();
889 if (ch == -1) {
890 HTInfoMsg(CANCELLED);
891 HTInfoMsg("");
892 } else {
893 _statusline(VALUE_ACCEPTED);
894 }
895 response = ' ';
896 break;
897
898 case 'S': /* Change case sensitivity for searches. */
899 LYcase_sensitive = LYChooseBoolean(LYcase_sensitive,
900 L_SSEARCH, -1,
901 caseless_choices);
902 response = ' ';
903 break;
904
905 case '\001': /* Change assume_charset setting. */
906 if (use_assume_charset) {
907 int i, curval;
908 const char **assume_list;
909 assume_list = typecallocn(const char *, (unsigned)
910 (LYNumCharsets + 1));
911
912 if (!assume_list) {
913 outofmem(__FILE__, "options");
914 }
915 for (i = 0; i < LYNumCharsets; i++) {
916 assume_list[i] = LYCharSet_UC[i].MIMEname;
917 }
918 curval = UCLYhndl_for_unspec;
919 if (curval == current_char_set && UCAssume_MIMEcharset) {
920 curval = UCGetLYhndl_byMIME(UCAssume_MIMEcharset);
921 }
922 if (curval < 0)
923 curval = LYRawMode ? current_char_set : 0;
924 if (!LYSelectPopups) {
925 #ifndef ALL_CHARSETS_IN_O_MENU_SCREEN
926 UCLYhndl_for_unspec =
927 assumed_doc_charset_map[(LYChooseEnum(charset_subsets[curval].assumed_idx,
928 L_ASSUME_CHARSET, -1,
929 assumed_charset_choices)
930 ? 1
931 : 0)];
932 #else
933 UCLYhndl_for_unspec =
934 LYChooseEnum(curval,
935 L_ASSUME_CHARSET, -1,
936 assume_list);
937 #endif
938 } else {
939 #ifndef ALL_CHARSETS_IN_O_MENU_SCREEN
940 UCLYhndl_for_unspec =
941 assumed_doc_charset_map[(LYChoosePopup(charset_subsets[curval].assumed_idx,
942 L_ASSUME_CHARSET, -1,
943 assumed_charset_choices,
944 0,
945 FALSE,
946 FALSE)
947 ? 1
948 : 0)];
949 #else
950 UCLYhndl_for_unspec =
951 LYChoosePopup(curval,
952 L_ASSUME_CHARSET, -1,
953 assume_list,
954 0, FALSE, FALSE);
955 #endif
956 #if defined(VMS) || defined(USE_SLANG)
957 LYmove(L_ASSUME_CHARSET, COL_OPTION_VALUES);
958 LYclrtoeol();
959 if (UCLYhndl_for_unspec >= 0)
960 LYaddstr(LYCharSet_UC[UCLYhndl_for_unspec].MIMEname);
961 #endif /* VMS || USE_SLANG */
962 }
963
964 /*
965 * Set the raw 8-bit or CJK mode defaults and character set if
966 * changed. - FM
967 */
968 if (CurrentAssumeCharSet != UCLYhndl_for_unspec ||
969 UCLYhndl_for_unspec != curval) {
970 if (UCLYhndl_for_unspec != CurrentAssumeCharSet) {
971 StrAllocCopy(UCAssume_MIMEcharset,
972 LYCharSet_UC[UCLYhndl_for_unspec].MIMEname);
973 }
974 if (HTCJK != JAPANESE)
975 LYRawMode = (BOOLEAN) (UCLYhndl_for_unspec == current_char_set);
976 HTMLSetUseDefaultRawMode(current_char_set, LYRawMode);
977 HTMLSetCharacterHandling(current_char_set);
978 CurrentAssumeCharSet = UCLYhndl_for_unspec;
979 CurrentRawMode = LYRawMode;
980 #if !defined(VMS) && !defined(USE_SLANG)
981 if (!LYSelectPopups)
982 #endif /* !VMS && !USE_SLANG */
983 {
984 LYmove(L_RAWMODE + 1, COL_OPTION_VALUES);
985 LYclrtoeol();
986 ShowBool(LYRawMode);
987 }
988 }
989 FREE(assume_list);
990 response = ' ';
991 if (LYSelectPopups) {
992 HANDLE_LYOPTIONS;
993 }
994 } else {
995 _statusline(NEED_ADVANCED_USER_MODE);
996 AddValueAccepted = FALSE;
997 }
998 break;
999
1000 case 'C': /* Change display charset setting. */
1001 if (!LYSelectPopups) {
1002 #ifndef ALL_CHARSETS_IN_O_MENU_SCREEN
1003 displayed_display_charset_idx = LYChooseEnum(displayed_display_charset_idx,
1004 L_Charset, -1,
1005 display_charset_choices);
1006 current_char_set = display_charset_map[displayed_display_charset_idx];
1007 #else
1008 current_char_set = LYChooseEnum(current_char_set,
1009 L_Charset, -1,
1010 LYchar_set_names);
1011 #endif
1012 } else {
1013 #ifndef ALL_CHARSETS_IN_O_MENU_SCREEN
1014 displayed_display_charset_idx = LYChoosePopup(displayed_display_charset_idx,
1015 L_Charset, -1,
1016 display_charset_choices,
1017 0, FALSE, FALSE);
1018 current_char_set = display_charset_map[displayed_display_charset_idx];
1019 #else
1020 current_char_set = LYChoosePopup(current_char_set,
1021 L_Charset, -1,
1022 LYchar_set_names,
1023 0, FALSE, FALSE);
1024 #endif
1025
1026 #if defined(VMS) || defined(USE_SLANG)
1027 LYmove(L_Charset, COL_OPTION_VALUES);
1028 LYclrtoeol();
1029 LYaddstr(LYchar_set_names[current_char_set]);
1030 #endif /* VMS || USE_SLANG */
1031 }
1032 /*
1033 * Set the raw 8-bit or CJK mode defaults and character set if
1034 * changed. - FM
1035 */
1036 if (CurrentCharSet != current_char_set) {
1037 LYUseDefaultRawMode = TRUE;
1038 HTMLUseCharacterSet(current_char_set);
1039 CurrentCharSet = current_char_set;
1040 CurrentRawMode = LYRawMode;
1041 #if !defined(VMS) && !defined(USE_SLANG)
1042 if (!LYSelectPopups)
1043 #endif /* !VMS && !USE_SLANG */
1044 {
1045 LYmove(L_Rawmode, COL_OPTION_VALUES);
1046 LYclrtoeol();
1047 ShowBool(LYRawMode);
1048 }
1049 #ifdef CAN_SWITCH_DISPLAY_CHARSET
1050 /* Deduce whether the user wants autoswitch: */
1051 switch_display_charsets =
1052 (current_char_set == auto_display_charset
1053 || current_char_set == auto_other_display_charset);
1054 #endif
1055 }
1056 response = ' ';
1057 if (LYSelectPopups) {
1058 HANDLE_LYOPTIONS;
1059 }
1060 break;
1061
1062 case 'O': /* Change raw mode setting. */
1063 LYRawMode = LYChooseBoolean(LYRawMode, L_Rawmode, -1, bool_choices);
1064 /*
1065 * Set the LYUseDefaultRawMode value and character handling if
1066 * LYRawMode was changed. - FM
1067 */
1068 if (CurrentRawMode != LYRawMode) {
1069 HTMLSetUseDefaultRawMode(current_char_set, LYRawMode);
1070 HTMLSetCharacterHandling(current_char_set);
1071 CurrentRawMode = LYRawMode;
1072 }
1073 response = ' ';
1074 break;
1075
1076 case 'G': /* Change language preference. */
1077 if (non_empty(language)) {
1078 BStrCopy0(my_data, language);
1079 } else { /* clear the NONE */
1080 LYmove(L_LANGUAGE, COL_OPTION_VALUES);
1081 LYaddstr(" ");
1082 BStrCopy0(my_data, "");
1083 }
1084 _statusline(ACCEPT_DATA);
1085 LYmove(L_LANGUAGE, COL_OPTION_VALUES);
1086 lynx_start_bold();
1087 ch = LYgetBString(&my_data, FALSE, 0, NORECALL);
1088 lynx_stop_bold();
1089 LYmove(L_LANGUAGE, COL_OPTION_VALUES);
1090 if (term_options || ch == -1) {
1091 LYaddstr(non_empty(language) ?
1092 language : "NONE");
1093 } else if (isBEmpty(my_data)) {
1094 FREE(language);
1095 LYaddstr("NONE");
1096 } else {
1097 StrAllocCopy(language, my_data->str);
1098 LYaddstr(language);
1099 }
1100 LYclrtoeol();
1101 if (ch == -1) {
1102 HTInfoMsg(CANCELLED);
1103 HTInfoMsg("");
1104 } else {
1105 _statusline(VALUE_ACCEPTED);
1106 }
1107 response = ' ';
1108 break;
1109
1110 case 'H': /* Change charset preference. */
1111 if (non_empty(pref_charset)) {
1112 BStrCopy0(my_data, pref_charset);
1113 } else { /* clear the NONE */
1114 LYmove(L_PREF_CHARSET, COL_OPTION_VALUES);
1115 LYaddstr(" ");
1116 BStrCopy0(my_data, "");
1117 }
1118 _statusline(ACCEPT_DATA);
1119 LYmove(L_PREF_CHARSET, COL_OPTION_VALUES);
1120 lynx_start_bold();
1121 ch = LYgetBString(&my_data, FALSE, 0, NORECALL);
1122 lynx_stop_bold();
1123 LYmove(L_PREF_CHARSET, COL_OPTION_VALUES);
1124 if (term_options || ch == -1) {
1125 LYaddstr(non_empty(pref_charset) ?
1126 pref_charset : "NONE");
1127 } else if (isBEmpty(my_data)) {
1128 FREE(pref_charset);
1129 LYaddstr("NONE");
1130 } else {
1131 StrAllocCopy(pref_charset, my_data->str);
1132 LYaddstr(pref_charset);
1133 }
1134 LYclrtoeol();
1135 if (ch == -1) {
1136 HTInfoMsg(CANCELLED);
1137 HTInfoMsg("");
1138 } else {
1139 _statusline(VALUE_ACCEPTED);
1140 }
1141 response = ' ';
1142 break;
1143
1144 case 'V': /* Change VI keys setting. */
1145 vi_keys = LYChooseBoolean(vi_keys,
1146 L_Bool_A, C_VIKEYS,
1147 bool_choices);
1148 if (vi_keys) {
1149 set_vi_keys();
1150 } else {
1151 reset_vi_keys();
1152 }
1153 response = ' ';
1154 break;
1155
1156 case 'M': /* Change emacs keys setting. */
1157 emacs_keys = LYChooseBoolean(emacs_keys,
1158 L_Bool_A, C_EMACSKEYS,
1159 bool_choices);
1160 if (emacs_keys) {
1161 set_emacs_keys();
1162 } else {
1163 reset_emacs_keys();
1164 }
1165 response = ' ';
1166 break;
1167
1168 case 'W': /* Change show dotfiles setting. */
1169 if (no_dotfiles) {
1170 _statusline(DOTFILE_ACCESS_DISABLED);
1171 } else {
1172 show_dotfiles = LYChooseBoolean(show_dotfiles,
1173 L_Bool_A,
1174 C_SHOW_DOTFILES,
1175 bool_choices);
1176 }
1177 response = ' ';
1178 break;
1179
1180 case 'T': /* Change select popups setting. */
1181 LYSelectPopups = LYChooseBoolean(LYSelectPopups,
1182 L_Bool_B,
1183 C_SELECT_POPUPS,
1184 bool_choices);
1185 response = ' ';
1186 break;
1187
1188 #if defined(USE_SLANG) || defined(COLOR_CURSES)
1189 case '&': /* Change show color setting. */
1190 if (no_option_save) {
1191 #if defined(COLOR_CURSES)
1192 if (!has_colors()) {
1193 char *terminal = LYGetEnv("TERM");
1194
1195 if (terminal)
1196 HTUserMsg2(COLOR_TOGGLE_DISABLED_FOR_TERM,
1197 terminal);
1198 else
1199 HTUserMsg(COLOR_TOGGLE_DISABLED);
1200 break;
1201 }
1202 #endif
1203 LYShowColor = LYChooseEnum((LYShowColor - 1),
1204 L_Color,
1205 C_COLOR,
1206 bool_choices);
1207 if (LYShowColor == 0) {
1208 LYShowColor = SHOW_COLOR_OFF;
1209 } else {
1210 LYShowColor = SHOW_COLOR_ON;
1211 }
1212 } else { /* !no_option_save */
1213 BOOLEAN again = FALSE;
1214 int chosen;
1215
1216 /*
1217 * Copy strings into choice array.
1218 */
1219 choices[0] = NULL;
1220 StrAllocCopy(choices[0], "NEVER ");
1221 choices[1] = NULL;
1222 StrAllocCopy(choices[1], "OFF ");
1223 choices[2] = NULL;
1224 StrAllocCopy(choices[2], "ON ");
1225 choices[3] = NULL;
1226 #if defined(COLOR_CURSES)
1227 if (!has_colors())
1228 StrAllocCopy(choices[3], "Always try");
1229 else
1230 #endif
1231 StrAllocCopy(choices[3], "ALWAYS ");
1232 choices[4] = NULL;
1233 do {
1234 if (!LYSelectPopups) {
1235 chosen = LYChooseEnum(LYChosenShowColor,
1236 L_Color,
1237 C_COLOR,
1238 choices);
1239 } else {
1240 chosen = LYChoosePopup(LYChosenShowColor,
1241 L_Color,
1242 C_COLOR,
1243 choices, 4, FALSE, FALSE);
1244 }
1245 #if defined(COLOR_CURSES)
1246 again = (BOOLEAN) (chosen == SHOW_COLOR_ON && !has_colors());
1247 if (again) {
1248 char *terminal = LYGetEnv("TERM");
1249
1250 if (terminal)
1251 HTUserMsg2(COLOR_TOGGLE_DISABLED_FOR_TERM,
1252 terminal);
1253 else
1254 HTUserMsg(COLOR_TOGGLE_DISABLED);
1255 }
1256 #endif
1257 } while (again);
1258 LYChosenShowColor = chosen;
1259 #if defined(VMS)
1260 if (LYSelectPopups) {
1261 LYmove(L_Color, C_COLOR);
1262 LYclrtoeol();
1263 LYaddstr(choices[LYChosenShowColor]);
1264 }
1265 #endif /* VMS */
1266 #if defined(COLOR_CURSES)
1267 if (has_colors())
1268 #endif
1269 LYShowColor = chosen;
1270 FREE(choices[0]);
1271 FREE(choices[1]);
1272 FREE(choices[2]);
1273 FREE(choices[3]);
1274 }
1275 if (CurrentShowColor != LYShowColor) {
1276 lynx_force_repaint();
1277 }
1278 CurrentShowColor = LYShowColor;
1279 #ifdef USE_SLANG
1280 SLtt_Use_Ansi_Colors = (LYShowColor > SHOW_COLOR_OFF ? TRUE : FALSE);
1281 #endif
1282 response = ' ';
1283 if (LYSelectPopups && !no_option_save) {
1284 HANDLE_LYOPTIONS;
1285 }
1286 break;
1287 #endif /* USE_SLANG or COLOR_CURSES */
1288
1289 case '@': /* Change show cursor setting. */
1290 LYShowCursor = LYChooseBoolean(LYShowCursor,
1291 L_Bool_B,
1292 C_SHOW_CURSOR,
1293 bool_choices);
1294 response = ' ';
1295 break;
1296
1297 case 'K': /* Change keypad mode. */
1298 if (!LYSelectPopups) {
1299 keypad_mode = LYChooseEnum(keypad_mode,
1300 L_Keypad, -1,
1301 keypad_choices);
1302 } else {
1303 keypad_mode = LYChoosePopup(keypad_mode,
1304 L_Keypad, -1,
1305 keypad_choices,
1306 3, FALSE, FALSE);
1307 #if defined(VMS) || defined(USE_SLANG)
1308 LYmove(L_Keypad, COL_OPTION_VALUES);
1309 LYclrtoeol();
1310 LYaddstr(keypad_choices[keypad_mode]);
1311 #endif /* VMS || USE_SLANG */
1312 }
1313 if (keypad_mode == NUMBERS_AS_ARROWS) {
1314 set_numbers_as_arrows();
1315 } else {
1316 reset_numbers_as_arrows();
1317 }
1318 response = ' ';
1319 if (LYSelectPopups) {
1320 HANDLE_LYOPTIONS;
1321 }
1322 break;
1323
1324 case 'N': /* Change line editor key bindings. */
1325 if (!LYSelectPopups) {
1326 current_lineedit = LYChooseEnum(current_lineedit,
1327 L_Lineed, -1,
1328 LYEditorNames);
1329 } else {
1330 current_lineedit = LYChoosePopup(current_lineedit,
1331 L_Lineed, -1,
1332 LYEditorNames,
1333 0, FALSE, FALSE);
1334 #if defined(VMS) || defined(USE_SLANG)
1335 LYmove(L_Lineed, COL_OPTION_VALUES);
1336 LYclrtoeol();
1337 LYaddstr(LYEditorNames[current_lineedit]);
1338 #endif /* VMS || USE_SLANG */
1339 }
1340 response = ' ';
1341 if (LYSelectPopups) {
1342 HANDLE_LYOPTIONS;
1343 }
1344 break;
1345
1346 #ifdef EXP_KEYBOARD_LAYOUT
1347 case 'Y': /* Change keyboard layout */
1348 if (!LYSelectPopups) {
1349 current_layout = LYChooseEnum(current_layout,
1350 L_Layout, -1,
1351 LYKbLayoutNames);
1352 } else {
1353 current_layout = LYChoosePopup(current_layout,
1354 L_Layout, -1,
1355 LYKbLayoutNames,
1356 0, FALSE, FALSE);
1357 #if defined(VMS) || defined(USE_SLANG)
1358 LYmove(L_Layout, COL_OPTION_VALUES);
1359 LYclrtoeol();
1360 LYaddstr(LYKbLayoutNames[current_layout]);
1361 #endif /* VMS || USE_SLANG */
1362 }
1363 response = ' ';
1364 if (LYSelectPopups) {
1365 HANDLE_LYOPTIONS;
1366 }
1367 break;
1368 #endif /* EXP_KEYBOARD_LAYOUT */
1369
1370 #ifdef DIRED_SUPPORT
1371 case 'I': /* Change local directory sorting. */
1372 if (!LYSelectPopups) {
1373 dir_list_style = LYChooseEnum(dir_list_style,
1374 L_Dired, -1,
1375 dirList_choices);
1376 } else {
1377 dir_list_style = LYChoosePopup(dir_list_style,
1378 L_Dired, -1,
1379 dirList_choices,
1380 3, FALSE, FALSE);
1381 #if defined(VMS) || defined(USE_SLANG)
1382 LYmove(L_Dired, COL_OPTION_VALUES);
1383 LYclrtoeol();
1384 LYaddstr(dirList_choices[dir_list_style]);
1385 #endif /* VMS || USE_SLANG */
1386 }
1387 response = ' ';
1388 if (LYSelectPopups) {
1389 HANDLE_LYOPTIONS;
1390 }
1391 break;
1392 #endif /* DIRED_SUPPORT */
1393
1394 case 'U': /* Change user mode. */
1395 if (!LYSelectPopups) {
1396 user_mode = LYChooseEnum(user_mode,
1397 L_User_Mode, -1,
1398 userMode_choices);
1399 use_assume_charset = (BOOLEAN) (user_mode >= 2);
1400 } else {
1401 user_mode = LYChoosePopup(user_mode,
1402 L_User_Mode, -1,
1403 userMode_choices,
1404 3, FALSE, FALSE);
1405 use_assume_charset = (BOOLEAN) (user_mode >= 2);
1406 #if defined(VMS) || defined(USE_SLANG)
1407 if (use_assume_charset == old_use_assume_charset) {
1408 LYmove(L_User_Mode, COL_OPTION_VALUES);
1409 LYclrtoeol();
1410 LYaddstr(userMode_choices[user_mode]);
1411 }
1412 #endif /* VMS || USE_SLANG */
1413 }
1414 LYSetDisplayLines();
1415 response = ' ';
1416 if (LYSelectPopups) {
1417 HANDLE_LYOPTIONS;
1418 }
1419 break;
1420
1421 case '!':
1422 if (!LYSelectPopups) {
1423 verbose_img = LYChooseBoolean(verbose_img,
1424 L_VERBOSE_IMAGES,
1425 C_VERBOSE_IMAGES,
1426 bool_choices);
1427 } else {
1428 verbose_img = (BOOLEAN) LYChoosePopup(verbose_img,
1429 L_VERBOSE_IMAGES,
1430 C_VERBOSE_IMAGES,
1431 bool_choices,
1432 2, FALSE, FALSE);
1433 }
1434 response = ' ';
1435 if (LYSelectPopups) {
1436 HANDLE_LYOPTIONS;
1437 }
1438 break;
1439
1440 case 'A': /* Change user agent string. */
1441 if (!no_useragent) {
1442 if (non_empty(LYUserAgent)) {
1443 BStrCopy0(my_data, LYUserAgent);
1444 } else { /* clear the NONE */
1445 LYmove(L_HOME, COL_OPTION_VALUES);
1446 LYaddstr(" ");
1447 BStrCopy0(my_data, "");
1448 }
1449 _statusline(ACCEPT_DATA_OR_DEFAULT);
1450 LYmove(L_User_Agent, COL_OPTION_VALUES);
1451 lynx_start_bold();
1452 ch = LYgetBString(&my_data, FALSE, 0, NORECALL);
1453 lynx_stop_bold();
1454 LYmove(L_User_Agent, COL_OPTION_VALUES);
1455 if (term_options || ch == -1) {
1456 LYaddstr((LYUserAgent &&
1457 *LYUserAgent) ?
1458 LYUserAgent : "NONE");
1459 } else if (isBEmpty(my_data)) {
1460 StrAllocCopy(LYUserAgent, LYUserAgentDefault);
1461 LYaddstr((LYUserAgent &&
1462 *LYUserAgent) ?
1463 LYUserAgent : "NONE");
1464 } else {
1465 StrAllocCopy(LYUserAgent, my_data->str);
1466 LYaddstr(LYUserAgent);
1467 }
1468 LYclrtoeol();
1469 if (ch == -1) {
1470 HTInfoMsg(CANCELLED);
1471 HTInfoMsg("");
1472 } else if (!LYCheckUserAgent()) {
1473 _statusline(UA_PLEASE_USE_LYNX);
1474 } else {
1475 _statusline(VALUE_ACCEPTED);
1476 }
1477 } else { /* disallowed */
1478 _statusline(UA_CHANGE_DISABLED);
1479 }
1480 response = ' ';
1481 break;
1482
1483 #if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS))
1484 case 'X': /* Change local exec restriction. */
1485 if (exec_frozen && !LYSelectPopups) {
1486 _statusline(CHANGE_OF_SETTING_DISALLOWED);
1487 response = ' ';
1488 break;
1489 }
1490 #ifndef NEVER_ALLOW_REMOTE_EXEC
1491 if (local_exec) {
1492 itmp = 2;
1493 } else
1494 #endif /* !NEVER_ALLOW_REMOTE_EXEC */
1495 {
1496 if (local_exec_on_local_files) {
1497 itmp = 1;
1498 } else {
1499 itmp = 0;
1500 }
1501 }
1502 if (!LYSelectPopups) {
1503 itmp = LYChooseEnum(itmp,
1504 L_Exec, -1,
1505 exec_choices);
1506 } else {
1507 itmp = LYChoosePopup(itmp,
1508 L_Exec, -1,
1509 exec_choices,
1510 0, (exec_frozen ? TRUE : FALSE),
1511 FALSE);
1512 #if defined(VMS) || defined(USE_SLANG)
1513 LYmove(L_Exec, COL_OPTION_VALUES);
1514 LYclrtoeol();
1515 LYaddstr(exec_choices[itmp]);
1516 #endif /* VMS || USE_SLANG */
1517 }
1518 if (!exec_frozen) {
1519 switch (itmp) {
1520 case 0:
1521 local_exec = FALSE;
1522 local_exec_on_local_files = FALSE;
1523 break;
1524 case 1:
1525 local_exec = FALSE;
1526 local_exec_on_local_files = TRUE;
1527 break;
1528 #ifndef NEVER_ALLOW_REMOTE_EXEC
1529 case 2:
1530 local_exec = TRUE;
1531 local_exec_on_local_files = FALSE;
1532 break;
1533 #endif /* !NEVER_ALLOW_REMOTE_EXEC */
1534 } /* end switch */
1535 }
1536 response = ' ';
1537 if (LYSelectPopups) {
1538 HANDLE_LYOPTIONS;
1539 }
1540 break;
1541 #endif /* ENABLE_OPTS_CHANGE_EXEC */
1542
1543 case '>': /* Save current options to RC file. */
1544 if (!no_option_save) {
1545 HTInfoMsg(SAVING_OPTIONS);
1546 LYrcShowColor = LYChosenShowColor;
1547 if (save_rc(NULL)) {
1548 HTInfoMsg(OPTIONS_SAVED);
1549 } else {
1550 HTAlert(OPTIONS_NOT_SAVED);
1551 }
1552 } else {
1553 HTInfoMsg(R_TO_RETURN_TO_LYNX);
1554 /*
1555 * Change response so that we don't exit the options menu.
1556 */
1557 response = ' ';
1558 }
1559 break;
1560
1561 case 'R': /* Return to document (quit options menu). */
1562 break;
1563
1564 default:
1565 if (!no_option_save) {
1566 HTInfoMsg(SAVE_OR_R_TO_RETURN_TO_LYNX);
1567 } else {
1568 HTInfoMsg(R_TO_RETURN_TO_LYNX);
1569 }
1570 } /* end switch */
1571 } /* end while */
1572
1573 term_options = FALSE;
1574 LYStatusLine = -1; /* let user_mode have some of the screen */
1575 signal(SIGINT, cleanup_sig);
1576 BStrFree(my_data);
1577 return;
1578 }
1579
widest_choice(STRING2PTR choices)1580 static int widest_choice(STRING2PTR choices)
1581 {
1582 int n, width = 0;
1583
1584 for (n = 0; choices[n] != NULL; ++n) {
1585 int len = (int) strlen(choices[n]);
1586
1587 if (width < len)
1588 width = len;
1589 }
1590 return width;
1591 }
1592
show_choice(const char * choice,int width)1593 static void show_choice(const char *choice,
1594 int width)
1595 {
1596 int len = 0;
1597
1598 if (choice != 0) {
1599 len = (int) strlen(choice);
1600
1601 LYaddstr(choice);
1602 }
1603 while (len++ < width)
1604 LYaddch(' ');
1605 }
1606
1607 /*
1608 * Take a status code, prompt the user for a new status, and return it.
1609 */
boolean_choice(int cur_choice,int line,int column,STRING2PTR choices)1610 static int boolean_choice(int cur_choice,
1611 int line,
1612 int column,
1613 STRING2PTR choices)
1614 {
1615 int response = 0;
1616 int cmd = 0;
1617 int number = 0;
1618 int col = (column >= 0 ? column : COL_OPTION_VALUES);
1619 int orig_choice = cur_choice;
1620 int width = widest_choice(choices);
1621
1622 /*
1623 * Get the number of choices and then make number zero-based.
1624 */
1625 for (number = 0; choices[number] != NULL; number++) ; /* empty loop body */
1626 number--;
1627
1628 /*
1629 * Update the statusline.
1630 */
1631 _statusline(ANY_KEY_CHANGE_RET_ACCEPT);
1632
1633 /*
1634 * Highlight the current choice.
1635 */
1636 LYmove(line, col);
1637 lynx_start_reverse();
1638 show_choice(choices[cur_choice], width);
1639 if (LYShowCursor)
1640 LYmove(line, (col - 1));
1641 LYrefresh();
1642
1643 /*
1644 * Get the keyboard entry, and leave the cursor at the choice, to indicate
1645 * that it can be changed, until the user accepts the current choice.
1646 */
1647 term_options = FALSE;
1648 while (1) {
1649 LYmove(line, col);
1650 if (term_options == FALSE) {
1651 response = LYgetch_single();
1652 }
1653 if (term_options || LYCharIsINTERRUPT_NO_letter(response)) {
1654 /*
1655 * Control-C or Control-G.
1656 */
1657 response = '\n';
1658 term_options = TRUE;
1659 cur_choice = orig_choice;
1660 }
1661 #ifdef VMS
1662 if (HadVMSInterrupt) {
1663 HadVMSInterrupt = FALSE;
1664 response = '\n';
1665 term_options = TRUE;
1666 cur_choice = orig_choice;
1667 }
1668 #endif /* VMS */
1669 if ((response != '\n' && response != '\r') &&
1670 (cmd = LKC_TO_LAC(keymap, response)) != LYK_ACTIVATE) {
1671 switch (cmd) {
1672 case LYK_HOME:
1673 cur_choice = 0;
1674 break;
1675
1676 case LYK_END:
1677 cur_choice = number;
1678 break;
1679
1680 case LYK_REFRESH:
1681 lynx_force_repaint();
1682 LYrefresh();
1683 break;
1684
1685 case LYK_QUIT:
1686 case LYK_ABORT:
1687 case LYK_PREV_DOC:
1688 cur_choice = orig_choice;
1689 term_options = TRUE;
1690 break;
1691
1692 case LYK_PREV_PAGE:
1693 case LYK_UP_HALF:
1694 case LYK_UP_TWO:
1695 case LYK_PREV_LINK:
1696 case LYK_LPOS_PREV_LINK:
1697 case LYK_FASTBACKW_LINK:
1698 case LYK_UP_LINK:
1699 case LYK_LEFT_LINK:
1700 if (cur_choice == 0)
1701 cur_choice = number; /* go back to end */
1702 else
1703 cur_choice--;
1704 break;
1705
1706 case LYK_1:
1707 case LYK_2:
1708 case LYK_3:
1709 case LYK_4:
1710 case LYK_5:
1711 case LYK_6:
1712 case LYK_7:
1713 case LYK_8:
1714 case LYK_9:
1715 if ((cmd - LYK_1 + 1) <= number) {
1716 cur_choice = cmd - LYK_1 + 1;
1717 break;
1718 } /* else fall through! */
1719 default:
1720 if (cur_choice == number)
1721 cur_choice = 0; /* go over the top and around */
1722 else
1723 cur_choice++;
1724 } /* end of switch */
1725 show_choice(choices[cur_choice], width);
1726 if (LYShowCursor)
1727 LYmove(line, (col - 1));
1728 LYrefresh();
1729 } else {
1730 /*
1731 * Unhighlight choice.
1732 */
1733 LYmove(line, col);
1734 lynx_stop_reverse();
1735 show_choice(choices[cur_choice], width);
1736
1737 if (term_options) {
1738 term_options = FALSE;
1739 HTInfoMsg(CANCELLED);
1740 HTInfoMsg("");
1741 } else {
1742 _statusline(VALUE_ACCEPTED);
1743 }
1744 return cur_choice;
1745 }
1746 }
1747 }
1748 #endif /* !NO_OPTION_MENU */
1749
terminate_options(int sig GCC_UNUSED)1750 static void terminate_options(int sig GCC_UNUSED)
1751 {
1752 term_options = TRUE;
1753 /*
1754 * Reassert the AST.
1755 */
1756 signal(SIGINT, terminate_options);
1757 #ifdef VMS
1758 /*
1759 * Refresh the screen to get rid of the "interrupt" message.
1760 */
1761 if (!dump_output_immediately) {
1762 lynx_force_repaint();
1763 LYrefresh();
1764 }
1765 #endif /* VMS */
1766 }
1767
1768 /*
1769 * Multi-Bookmark On-Line editing support. - FMG & FM
1770 */
edit_bookmarks(void)1771 void edit_bookmarks(void)
1772 {
1773 int response = 0, def_response = 0;
1774 int MBM_current = 1;
1775
1776 #define MULTI_OFFSET 8
1777 int a; /* misc counter */
1778 bstring *my_data = NULL;
1779
1780 /*
1781 * We need (MBM_V_MAXFILES + MULTI_OFFSET) lines to display the whole list
1782 * at once. Otherwise break it up into two segments. We know it won't be
1783 * less than that because 'o'ptions needs 23-24 at LEAST.
1784 */
1785 term_options = FALSE;
1786 signal(SIGINT, terminate_options);
1787
1788 draw_bookmark_list:
1789 /*
1790 * Display menu of bookmarks. NOTE that we avoid printw()'s to increase
1791 * the chances that any non-ASCII or multibyte/CJK characters will be
1792 * handled properly. - FM
1793 */
1794 #if defined(FANCY_CURSES) || defined (USE_SLANG)
1795 if (enable_scrollback) {
1796 LYclear();
1797 } else {
1798 LYerase();
1799 }
1800 #else
1801 LYclear();
1802 #endif /* FANCY_CURSES || USE_SLANG */
1803 LYmove(0, 5);
1804 lynx_start_h1_color();
1805 if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) {
1806 char *ehead_buffer = 0;
1807
1808 HTSprintf0(&ehead_buffer, MULTIBOOKMARKS_EHEAD_MASK, MBM_current);
1809 LYaddstr(ehead_buffer);
1810 FREE(ehead_buffer);
1811 } else {
1812 LYaddstr(MULTIBOOKMARKS_EHEAD);
1813 }
1814 lynx_stop_h1_color();
1815
1816 if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) {
1817 for (a = ((MBM_V_MAXFILES / 2 + 1) * (MBM_current - 1));
1818 a <= (MBM_current * MBM_V_MAXFILES / 2); a++) {
1819 LYmove((3 + a) - ((MBM_V_MAXFILES / 2 + 1) * (MBM_current - 1)), 5);
1820 LYaddch(UCH(LYindex2MBM(a)));
1821 LYaddstr(" : ");
1822 if (MBM_A_subdescript[a])
1823 LYaddstr(MBM_A_subdescript[a]);
1824 LYmove((3 + a) - ((MBM_V_MAXFILES / 2 + 1) * (MBM_current - 1)), 35);
1825 LYaddstr("| ");
1826 if (MBM_A_subbookmark[a]) {
1827 LYaddstr(MBM_A_subbookmark[a]);
1828 }
1829 }
1830 } else {
1831 for (a = 0; a <= MBM_V_MAXFILES; a++) {
1832 LYmove(3 + a, 5);
1833 LYaddch(UCH(LYindex2MBM(a)));
1834 LYaddstr(" : ");
1835 if (MBM_A_subdescript[a])
1836 LYaddstr(MBM_A_subdescript[a]);
1837 LYmove(3 + a, 35);
1838 LYaddstr("| ");
1839 if (MBM_A_subbookmark[a]) {
1840 LYaddstr(MBM_A_subbookmark[a]);
1841 }
1842 }
1843 }
1844
1845 /*
1846 * Only needed when we have 2 screens.
1847 */
1848 if (LYlines < MBM_V_MAXFILES + MULTI_OFFSET) {
1849 LYmove((LYlines - 4), 0);
1850 LYaddstr("'");
1851 lynx_start_bold();
1852 LYaddstr("[");
1853 lynx_stop_bold();
1854 LYaddstr("' ");
1855 LYaddstr(PREVIOUS);
1856 LYaddstr(", '");
1857 lynx_start_bold();
1858 LYaddstr("]");
1859 lynx_stop_bold();
1860 LYaddstr("' ");
1861 LYaddstr(NEXT_SCREEN);
1862 }
1863
1864 LYmove((LYlines - 3), 0);
1865 if (!no_option_save) {
1866 LYaddstr("'");
1867 lynx_start_bold();
1868 LYaddstr(">");
1869 lynx_stop_bold();
1870 LYaddstr("'");
1871 LYaddstr(TO_SAVE_SEGMENT);
1872 }
1873 LYaddstr(OR_SEGMENT);
1874 LYaddstr("'");
1875 lynx_start_bold();
1876 LYaddstr("^G");
1877 lynx_stop_bold();
1878 LYaddstr("'");
1879 LYaddstr(TO_RETURN_SEGMENT);
1880
1881 while (!term_options &&
1882 !LYisNonAlnumKeyname(response, LYK_PREV_DOC) &&
1883 !LYCharIsINTERRUPT_NO_letter(response) && response != '>') {
1884
1885 LYmove((LYlines - 2), 0);
1886 lynx_start_prompt_color();
1887 LYaddstr(MULTIBOOKMARKS_LETTER);
1888 lynx_stop_prompt_color();
1889
1890 LYrefresh();
1891 response = (def_response ? def_response : LYgetch_single());
1892 def_response = 0;
1893
1894 /*
1895 * Check for a cancel.
1896 */
1897 if (term_options || LYCharIsINTERRUPT_NO_letter(response) ||
1898 LYisNonAlnumKeyname(response, LYK_PREV_DOC))
1899 continue;
1900
1901 /*
1902 * Check for a save.
1903 */
1904 if (response == '>') {
1905 if (!no_option_save) {
1906 HTInfoMsg(SAVING_OPTIONS);
1907 if (save_rc(NULL))
1908 HTInfoMsg(OPTIONS_SAVED);
1909 else
1910 HTAlert(OPTIONS_NOT_SAVED);
1911 } else {
1912 HTInfoMsg(R_TO_RETURN_TO_LYNX);
1913 /*
1914 * Change response so that we don't exit the options menu.
1915 */
1916 response = ' ';
1917 }
1918 continue;
1919 }
1920
1921 /*
1922 * Check for a refresh.
1923 */
1924 if (LYisNonAlnumKeyname(response, LYK_REFRESH)) {
1925 lynx_force_repaint();
1926 continue;
1927 }
1928
1929 /*
1930 * Move between the screens - if we can't show it all at once.
1931 */
1932 if ((response == ']' ||
1933 LYisNonAlnumKeyname(response, LYK_NEXT_PAGE)) &&
1934 LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) {
1935 MBM_current++;
1936 if (MBM_current >= 3)
1937 MBM_current = 1;
1938 goto draw_bookmark_list;
1939 }
1940 if ((response == '[' ||
1941 LYisNonAlnumKeyname(response, LYK_PREV_PAGE)) &&
1942 LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) {
1943 MBM_current--;
1944 if (MBM_current <= 0)
1945 MBM_current = 2;
1946 goto draw_bookmark_list;
1947 }
1948
1949 /*
1950 * Instead of using 26 case statements, we set up a scan through the
1951 * letters and edit the lines that way.
1952 */
1953 for (a = 0; a <= MBM_V_MAXFILES; a++) {
1954 if (LYMBM2index(response) == a) {
1955 if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET)) {
1956 if (MBM_current == 1 && a > (MBM_V_MAXFILES / 2)) {
1957 MBM_current = 2;
1958 def_response = response;
1959 goto draw_bookmark_list;
1960 }
1961 if (MBM_current == 2 && a < (MBM_V_MAXFILES / 2)) {
1962 MBM_current = 1;
1963 def_response = response;
1964 goto draw_bookmark_list;
1965 }
1966 }
1967 _statusline(ACCEPT_DATA);
1968
1969 if (a > 0) {
1970 lynx_start_bold();
1971 if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET))
1972 LYmove((3 + a)
1973 - ((MBM_V_MAXFILES / 2 + 1) * (MBM_current - 1)),
1974 9);
1975 else
1976 LYmove((3 + a), 9);
1977 BStrCopy0(my_data,
1978 (!MBM_A_subdescript[a] ?
1979 "" : MBM_A_subdescript[a]));
1980 (void) LYgetBString(&my_data, FALSE, 0, NORECALL);
1981 lynx_stop_bold();
1982
1983 if (isBEmpty(my_data)) {
1984 FREE(MBM_A_subdescript[a]);
1985 } else {
1986 StrAllocCopy(MBM_A_subdescript[a], my_data->str);
1987 }
1988 if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET))
1989 LYmove((3 + a)
1990 - ((MBM_V_MAXFILES / 2 + 1)
1991 * (MBM_current - 1)),
1992 5);
1993 else
1994 LYmove((3 + a), 5);
1995 LYaddch(UCH(LYindex2MBM(a)));
1996 LYaddstr(" : ");
1997 if (MBM_A_subdescript[a])
1998 LYaddstr(MBM_A_subdescript[a]);
1999 LYclrtoeol();
2000 LYrefresh();
2001 }
2002
2003 if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET))
2004 LYmove((3 + a)
2005 - ((MBM_V_MAXFILES / 2 + 1)
2006 * (MBM_current - 1)),
2007 35);
2008 else
2009 LYmove((3 + a), 35);
2010 LYaddstr("| ");
2011
2012 lynx_start_bold();
2013 BStrCopy0(my_data, NonNull(MBM_A_subbookmark[a]));
2014 (void) LYgetBString(&my_data, FALSE, 0, NORECALL);
2015 lynx_stop_bold();
2016
2017 if (isBEmpty(my_data)) {
2018 if (a == 0)
2019 StrAllocCopy(MBM_A_subbookmark[a], bookmark_page);
2020 else
2021 FREE(MBM_A_subbookmark[a]);
2022 } else {
2023 BStrAlloc(my_data, my_data->len + LY_MAXPATH);
2024 if (!LYPathOffHomeOK(my_data->str, (size_t) my_data->len)) {
2025 LYMBM_statusline(USE_PATH_OFF_HOME);
2026 LYSleepAlert();
2027 } else {
2028 StrAllocCopy(MBM_A_subbookmark[a], my_data->str);
2029 if (a == 0) {
2030 StrAllocCopy(bookmark_page, MBM_A_subbookmark[a]);
2031 }
2032 }
2033 }
2034 if (LYlines < (MBM_V_MAXFILES + MULTI_OFFSET))
2035 LYmove((3 + a)
2036 - ((MBM_V_MAXFILES / 2 + 1)
2037 * (MBM_current - 1)),
2038 35);
2039 else
2040 LYmove((3 + a), 35);
2041 LYaddstr("| ");
2042 if (MBM_A_subbookmark[a])
2043 LYaddstr(MBM_A_subbookmark[a]);
2044 LYclrtoeol();
2045 LYParkCursor();
2046 break;
2047 }
2048 } /* end for */
2049 } /* end while */
2050
2051 BStrFree(my_data);
2052 term_options = FALSE;
2053 signal(SIGINT, cleanup_sig);
2054 }
2055
2056 #if defined(USE_CURSES_PADS) || !defined(NO_OPTION_MENU) || (defined(USE_MOUSE) && (defined(NCURSES) || defined(PDCURSES)))
2057
2058 /*
2059 * This function offers the choices for values of an option via a popup window
2060 * which functions like that for selection of options in a form. - FM
2061 *
2062 * Also used for mouse popups with ncurses; this is indicated by for_mouse.
2063 */
popup_choice(int cur_choice,int line,int column,STRING2PTR choices,int i_length,int disabled,int for_mouse)2064 int popup_choice(int cur_choice,
2065 int line,
2066 int column,
2067 STRING2PTR choices,
2068 int i_length,
2069 int disabled,
2070 int for_mouse)
2071 {
2072 if (column < 0)
2073 column = (COL_OPTION_VALUES - 1);
2074
2075 term_options = FALSE;
2076 cur_choice = LYhandlePopupList(cur_choice,
2077 line,
2078 column,
2079 (STRING2PTR) choices,
2080 -1,
2081 i_length,
2082 disabled,
2083 for_mouse);
2084 switch (cur_choice) {
2085 case LYK_QUIT:
2086 case LYK_ABORT:
2087 case LYK_PREV_DOC:
2088 term_options = TRUE;
2089 if (!for_mouse) {
2090 HTUserMsg(CANCELLED);
2091 }
2092 break;
2093 }
2094
2095 if (disabled || term_options) {
2096 _statusline("");
2097 } else if (!for_mouse) {
2098 _statusline(VALUE_ACCEPTED);
2099 }
2100 return (cur_choice);
2101 }
2102
2103 #endif /* !NO_OPTION_MENU */
2104 #ifndef NO_OPTION_FORMS
2105
2106 /*
2107 * I'm paranoid about mistyping strings. Also, this way they get combined
2108 * so we don't have to worry about the intelligence of the compiler.
2109 * We don't need to burn memory like it's cheap. We're better than that.
2110 */
2111 #define SELECTED(flag) (flag) ? selected_string : ""
2112 #define DISABLED(flag) (flag) ? disabled_string : ""
2113
2114 typedef struct {
2115 int value;
2116 const char *LongName;
2117 const char *HtmlName;
2118 } OptValues;
2119
2120 #define END_OPTIONS {0, 0, 0}
2121
2122 #define HasOptValues(table) (((table) != NULL) && ((table)->LongName != NULL))
2123
2124 typedef struct {
2125 char *tag;
2126 char *value;
2127 } PostPair;
2128
2129 static const char selected_string[] = "selected";
2130 static const char disabled_string[] = "disabled";
2131 static const char on_string[] = N_("ON");
2132 static const char off_string[] = N_("OFF");
2133 static const char never_string[] = N_("NEVER");
2134 static const char always_string[] = N_("ALWAYS");
2135 static OptValues bool_values[] =
2136 {
2137 {FALSE, N_("OFF"), "OFF"},
2138 {TRUE, N_("ON"), "ON"},
2139 END_OPTIONS
2140 };
2141
2142 static const char *secure_string = "secure";
2143 static char *secure_value = NULL;
2144 static const char *save_options_string = "save_options";
2145
2146 /*
2147 * Personal Preferences
2148 */
2149 static const char *cookies_string = RC_SET_COOKIES;
2150 static const char *cookies_ignore_all_string = N_("ignore");
2151 static const char *cookies_up_to_user_string = N_("ask user");
2152 static const char *cookies_accept_all_string = N_("accept all");
2153 static const char *x_display_string = RC_DISPLAY;
2154 static const char *editor_string = RC_FILE_EDITOR;
2155 static const char *emacs_keys_string = RC_EMACS_KEYS;
2156
2157 #if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS))
2158 #define EXEC_ALWAYS 2
2159 #define EXEC_LOCAL 1
2160 #define EXEC_NEVER 0
2161 static const char *exec_links_string = RC_RUN_ALL_EXECUTION_LINKS;
2162 static OptValues exec_links_values[] =
2163 {
2164 {EXEC_NEVER, N_("ALWAYS OFF"), "ALWAYS OFF"},
2165 {EXEC_LOCAL, N_("FOR LOCAL FILES ONLY"), "FOR LOCAL FILES ONLY"},
2166 #ifndef NEVER_ALLOW_REMOTE_EXEC
2167 {EXEC_ALWAYS, N_("ALWAYS ON"), "ALWAYS ON"},
2168 #endif
2169 END_OPTIONS
2170 };
2171 #endif /* ENABLE_OPTS_CHANGE_EXEC */
2172
2173 #ifdef EXP_KEYBOARD_LAYOUT
2174 static const char *kblayout_string = RC_KBLAYOUT;
2175 #endif
2176 static const char *keypad_mode_string = RC_KEYPAD_MODE;
2177 static OptValues keypad_mode_values[] =
2178 {
2179 {NUMBERS_AS_ARROWS, N_("Numbers act as arrows"),
2180 "number_arrows"},
2181 {LINKS_ARE_NUMBERED, N_("Links are numbered"),
2182 "links_numbered"},
2183 {LINKS_AND_FIELDS_ARE_NUMBERED,
2184 N_("Links and form fields are numbered"),
2185 "links_and_forms"},
2186 {FIELDS_ARE_NUMBERED,
2187 N_("Form fields are numbered"),
2188 "forms_numbered"},
2189 END_OPTIONS
2190 };
2191 static const char *lineedit_mode_string = RC_LINEEDIT_MODE;
2192 static const char *mail_address_string = RC_PERSONAL_MAIL_ADDRESS;
2193 static const char *personal_name_string = RC_PERSONAL_MAIL_NAME;
2194 static const char *search_type_string = RC_CASE_SENSITIVE_SEARCHING;
2195
2196 #ifndef DISABLE_FTP
2197 static const char *anonftp_password_string = RC_ANONFTP_PASSWORD;
2198 #endif
2199
2200 static OptValues search_type_values[] =
2201 {
2202 {FALSE, N_("Case insensitive"), "case_insensitive"},
2203 {TRUE, N_("Case sensitive"), "case_sensitive"},
2204 END_OPTIONS
2205 };
2206
2207 #if defined(USE_SLANG) || defined(COLOR_CURSES)
2208 static const char *show_color_string = RC_SHOW_COLOR;
2209 static OptValues show_color_values[] =
2210 {
2211 {SHOW_COLOR_NEVER, never_string, never_string},
2212 {SHOW_COLOR_OFF, off_string, off_string},
2213 {SHOW_COLOR_ON, on_string, on_string},
2214 {SHOW_COLOR_ALWAYS, always_string, always_string},
2215 END_OPTIONS
2216 };
2217 #endif
2218
2219 #ifdef USE_COLOR_STYLE
2220 static const char *color_style_string = RC_COLOR_STYLE;
2221 static OptValues *color_style_values;
2222 static HTList *color_style_list;
2223 #endif
2224
2225 #ifdef USE_DEFAULT_COLORS
2226 static const char *default_colors_string = RC_DEFAULT_COLORS;
2227 #endif
2228
2229 static const char *show_cursor_string = RC_SHOW_CURSOR;
2230
2231 static const char *underline_links_string = RC_UNDERLINE_LINKS;
2232
2233 #ifdef USE_SCROLLBAR
2234 static const char *show_scrollbar_string = RC_SCROLLBAR;
2235 #endif
2236
2237 static const char prompt_dft_string[] = N_("prompt normally");
2238 static const char prompt_yes_string[] = N_("force yes-response");
2239 static const char prompt_no_string[] = N_("force no-response");
2240 static OptValues prompt_values[] =
2241 {
2242 {FORCE_PROMPT_DFT, prompt_dft_string, prompt_dft_string},
2243 {FORCE_PROMPT_YES, prompt_yes_string, prompt_yes_string},
2244 {FORCE_PROMPT_NO, prompt_no_string, prompt_no_string},
2245 END_OPTIONS
2246 };
2247 static const char *cookie_prompt_string = RC_FORCE_COOKIE_PROMPT;
2248
2249 static const char RFC_2109_string[] = N_("RFC 2109");
2250 static const char RFC_2965_string[] = N_("RFC 2965");
2251 static const char RFC_6265_string[] = N_("RFC 6265");
2252 static OptValues cookies_values[] =
2253 {
2254 {COOKIES_RFC_2109, RFC_2109_string, RFC_2109_string},
2255 {COOKIES_RFC_2965, RFC_2965_string, RFC_2965_string},
2256 {COOKIES_RFC_6265, RFC_6265_string, RFC_6265_string},
2257 END_OPTIONS
2258 };
2259 static const char *cookie_version_string = RC_COOKIE_VERSION;
2260
2261 #ifdef USE_SSL
2262 static const char *ssl_prompt_string = RC_FORCE_SSL_PROMPT;
2263 #endif
2264
2265 static const char *user_mode_string = RC_USER_MODE;
2266 static OptValues user_mode_values[] =
2267 {
2268 {NOVICE_MODE, N_("Novice"), "Novice"},
2269 {INTERMEDIATE_MODE, N_("Intermediate"), "Intermediate"},
2270 {ADVANCED_MODE, N_("Advanced"), "Advanced"},
2271 END_OPTIONS
2272 };
2273
2274 static const char *vi_keys_string = RC_VI_KEYS;
2275
2276 static const char *visited_links_string = RC_VISITED_LINKS;
2277 static OptValues visited_links_values[] =
2278 {
2279 {VISITED_LINKS_AS_FIRST_V, N_("By First Visit"), "first_visited"},
2280 {VISITED_LINKS_AS_FIRST_V | VISITED_LINKS_REVERSE,
2281 N_("By First Visit Reversed"), "first_visited_reversed"},
2282 {VISITED_LINKS_AS_TREE, N_("As Visit Tree"), "visit_tree"},
2283 {VISITED_LINKS_AS_LATEST, N_("By Last Visit"), "last_visited"},
2284 {VISITED_LINKS_AS_LATEST | VISITED_LINKS_REVERSE,
2285 N_("By Last Visit Reversed"), "last_visited_reversed"},
2286 END_OPTIONS
2287 };
2288
2289 /*
2290 * Document Layout
2291 */
2292 static const char *DTD_recovery_string = RC_TAGSOUP;
2293 static OptValues DTD_type_values[] =
2294 {
2295 /* Old_DTD variable */
2296 {TRUE, N_("relaxed (TagSoup mode)"), "tagsoup"},
2297 {FALSE, N_("strict (SortaSGML mode)"), "sortasgml"},
2298 END_OPTIONS
2299 };
2300
2301 static const char *bad_html_string = RC_BAD_HTML;
2302 static OptValues bad_html_values[] =
2303 {
2304 {BAD_HTML_IGNORE, N_("Ignore"), "ignore"},
2305 {BAD_HTML_TRACE, N_("Add to trace-file"), "trace"},
2306 {BAD_HTML_MESSAGE, N_("Add to LYNXMESSAGES"), "message"},
2307 {BAD_HTML_WARN, N_("Warn, point to trace-file"), "warn"},
2308 END_OPTIONS
2309 };
2310
2311 static const char *select_popups_string = RC_SELECT_POPUPS;
2312 static const char *images_string = "images";
2313 static const char *images_ignore_all_string = N_("ignore");
2314 static const char *images_use_label_string = N_("as labels");
2315 static const char *images_use_links_string = N_("as links");
2316
2317 static const char *verbose_images_string = RC_VERBOSE_IMAGES;
2318 static OptValues verbose_images_type_values[] =
2319 {
2320 /* verbose_img variable */
2321 {FALSE, N_("OFF"), "OFF"},
2322 {TRUE, N_("show filename"), "ON"},
2323 END_OPTIONS
2324 };
2325
2326 static const char *collapse_br_tags_string = RC_COLLAPSE_BR_TAGS;
2327 static OptValues collapse_br_tags_values[] =
2328 {
2329 /* LYCollapseBRs variable */
2330 {FALSE, N_("OFF"), "OFF"},
2331 {TRUE, N_("collapse"), "ON"},
2332 END_OPTIONS
2333 };
2334
2335 static const char *trim_blank_lines_string = RC_TRIM_BLANK_LINES;
2336 static OptValues trim_blank_lines_values[] =
2337 {
2338 /* LYtrimBlankLines variable */
2339 {FALSE, N_("OFF"), "OFF"},
2340 {TRUE, N_("trim-lines"), "ON"},
2341 END_OPTIONS
2342 };
2343
2344 /*
2345 * Bookmark Options
2346 */
2347 static const char *mbm_string = RC_MULTI_BOOKMARK;
2348 static OptValues mbm_values[] =
2349 {
2350 {MBM_OFF, N_("OFF"), "OFF"},
2351 {MBM_STANDARD, N_("STANDARD"), "STANDARD"},
2352 {MBM_ADVANCED, N_("ADVANCED"), "ADVANCED"},
2353 END_OPTIONS
2354 };
2355
2356 static const char *single_bookmark_string = RC_BOOKMARK_FILE;
2357
2358 #ifdef USE_SESSIONS
2359 static const char *auto_session_string = RC_AUTO_SESSION;
2360 static const char *single_session_string = RC_SESSION_FILE;
2361 #endif
2362
2363 /*
2364 * Character Set Options
2365 */
2366 static const char *assume_char_set_string = RC_ASSUME_CHARSET;
2367 static const char *display_char_set_string = RC_CHARACTER_SET;
2368 static const char *raw_mode_string = RC_RAW_MODE;
2369
2370 #ifdef USE_IDN2
2371 static const char *idna_mode_string = RC_IDNA_MODE;
2372 static OptValues idna_values[] =
2373 {
2374 {LYidna2003, N_("IDNA 2003"), "idna2003"},
2375 {LYidna2008, N_("IDNA 2008"), "idna2008"},
2376 {LYidnaTR46, N_("IDNA TR46"), "idnaTR46"},
2377 {LYidnaCompat, N_("IDNA Compatible"), "idnaCompat"},
2378 END_OPTIONS
2379 };
2380 #endif
2381
2382 #ifdef USE_LOCALE_CHARSET
2383 static const char *locale_charset_string = RC_LOCALE_CHARSET;
2384 #endif
2385
2386 static const char *html5_charsets_string = RC_HTML5_CHARSETS;
2387
2388 /*
2389 * File Management Options
2390 */
2391 static const char *show_dotfiles_string = RC_SHOW_DOTFILES;
2392 static const char *no_pause_string = RC_NO_PAUSE;
2393
2394 #ifdef DIRED_SUPPORT
2395 static const char *dired_list_string = RC_DIR_LIST_STYLE;
2396 static OptValues dired_list_values[] =
2397 {
2398 {DIRS_FIRST, N_("Directories first"), "dired_dir"},
2399 {FILES_FIRST, N_("Files first"), "dired_files"},
2400 {MIXED_STYLE, N_("Mixed style"), "dired_mixed"},
2401 END_OPTIONS
2402 };
2403
2404 #ifdef LONG_LIST
2405 static const char *dired_sort_string = RC_DIR_LIST_ORDER;
2406 static OptValues dired_sort_values[] =
2407 {
2408 {ORDER_BY_NAME, N_("By Name"), "dired_by_name"},
2409 {ORDER_BY_TYPE, N_("By Type"), "dired_by_type"},
2410 {ORDER_BY_SIZE, N_("By Size"), "dired_by_size"},
2411 {ORDER_BY_DATE, N_("By Date"), "dired_by_date"},
2412 {ORDER_BY_MODE, N_("By Mode"), "dired_by_mode"},
2413 #ifndef NO_GROUPS
2414 {ORDER_BY_USER, N_("By User"), "dired_by_user"},
2415 {ORDER_BY_GROUP, N_("By Group"), "dired_by_group"},
2416 #endif
2417 END_OPTIONS
2418 };
2419 #endif /* LONG_LIST */
2420 #endif /* DIRED_SUPPORT */
2421
2422 #ifndef DISABLE_FTP
2423 static const char *passive_ftp_string = RC_FTP_PASSIVE;
2424
2425 static const char *ftp_sort_string = RC_FILE_SORTING_METHOD;
2426 static OptValues ftp_sort_values[] =
2427 {
2428 {FILE_BY_NAME, N_("By Name"), "ftp_by_name"},
2429 {FILE_BY_TYPE, N_("By Type"), "ftp_by_type"},
2430 {FILE_BY_SIZE, N_("By Size"), "ftp_by_size"},
2431 {FILE_BY_DATE, N_("By Date"), "ftp_by_date"},
2432 END_OPTIONS
2433 };
2434 #endif
2435
2436 #ifdef USE_READPROGRESS
2437 static const char *show_rate_string = RC_SHOW_KB_RATE;
2438 static OptValues rate_values[] =
2439 {
2440 {rateOFF, N_("Do not show rate"), "rate_off"},
2441 {rateBYTES, N_("Show %s/sec rate"), "rate_bytes"},
2442 {rateKB, N_("Show %s/sec rate"), "rate_kb"},
2443 #ifdef USE_READPROGRESS
2444 {rateEtaBYTES, N_("Show %s/sec, ETA"), "rate_eta_bytes"},
2445 {rateEtaKB, N_("Show %s/sec, ETA"), "rate_eta_kb"},
2446 {rateEtaBYTES2, N_("Show %s/sec (2-digits), ETA"), "rate_eta_bytes2"},
2447 {rateEtaKB2, N_("Show %s/sec (2-digits), ETA"), "rate_eta_kb2"},
2448 #endif
2449 #ifdef USE_PROGRESSBAR
2450 {rateBAR, N_("Show progressbar"), "rate_bar"},
2451 #endif
2452 END_OPTIONS
2453 };
2454 #endif /* USE_READPROGRESS */
2455
2456 static const char *preferred_content_string = RC_PREFERRED_CONTENT_TYPE;
2457 static OptValues content_values[] =
2458 {
2459 {contentBINARY, STR_BINARY, STR_BINARY},
2460 {contentTEXT, STR_PLAINTEXT, STR_PLAINTEXT},
2461 {contentHTML, STR_HTML, STR_HTML},
2462 END_OPTIONS
2463 };
2464
2465 /*
2466 * Presentation (MIME) types used in "Accept".
2467 */
2468 static const char *preferred_media_string = RC_PREFERRED_MEDIA_TYPES;
2469 static OptValues media_values[] =
2470 {
2471 {mediaOpt1, N_("Accept lynx's internal types"), "media_opt1"},
2472 {mediaOpt2, N_("Also accept lynx.cfg's types"), "media_opt2"},
2473 {mediaOpt3, N_("Also accept user's types"), "media_opt3"},
2474 {mediaOpt4, N_("Also accept system's types"), "media_opt4"},
2475 {mediaALL, N_("Accept all types"), "media_all"},
2476 END_OPTIONS
2477 };
2478
2479 static const char *preferred_encoding_string = RC_PREFERRED_ENCODING;
2480 static OptValues encoding_values[] =
2481 {
2482 {encodingNONE, N_("None"), "encoding_none"},
2483 #if defined(USE_ZLIB) || defined(GZIP_PATH)
2484 {encodingGZIP, N_("gzip"), "encoding_gzip"},
2485 {encodingDEFLATE, N_("deflate"), "encoding_deflate"},
2486 #endif
2487 #if defined(USE_ZLIB) || defined(COMPRESS_PATH)
2488 {encodingCOMPRESS, N_("compress"), "encoding_compress"},
2489 #endif
2490 #if defined(USE_BZLIB) || defined(BZIP2_PATH)
2491 {encodingBZIP2, N_("bzip2"), "encoding_bzip2"},
2492 #endif
2493 {encodingALL, N_("All"), "encoding_all"},
2494 END_OPTIONS
2495 };
2496
2497 /*
2498 * Headers transferred to remote server
2499 */
2500 static const char *http_protocol_string = RC_HTTP_PROTOCOL;
2501 static OptValues http_protocol_values[] =
2502 {
2503 {HTTP_1_0, N_("HTTP 1.0"), "HTTP_1_0"},
2504 {HTTP_1_1, N_("HTTP 1.1"), "HTTP_1_1"},
2505 END_OPTIONS
2506 };
2507
2508 static const char *preferred_doc_char_string = RC_PREFERRED_CHARSET;
2509 static const char *preferred_doc_lang_string = RC_PREFERRED_LANGUAGE;
2510 static const char *send_user_agent_string = RC_SEND_USERAGENT;
2511 static const char *user_agent_string = RC_USERAGENT;
2512
2513 static const char *ssl_client_certificate_file = RC_SSL_CLIENT_CERT_FILE;
2514 static const char *ssl_client_key_file = RC_SSL_CLIENT_KEY_FILE;
2515
2516 #define PutHeader(fp, Name) \
2517 fprintf(fp, "\n%s<em>%s</em>\n", MARGIN_STR, LYEntifyTitle(&buffer, Name));
2518
2519 #define PutCheckBox(fp, Name, Value, disable) \
2520 fprintf(fp,\
2521 "<input type=\"checkbox\" name=\"%s\" %s %s>\n",\
2522 Name, Value ? "checked" : "", disable_all?disabled_string:disable)
2523
2524 #define PutTextInput(fp, Name, Value, Size, disable) \
2525 fprintf(fp,\
2526 "<input size=%d type=\"text\" name=\"%s\" value=\"%s\" %s>\n",\
2527 (int) Size, Name, Value, disable_all?disabled_string:disable)
2528
2529 #define PutOption(fp, flag, html, name) \
2530 fprintf(fp,"<option value=\"%s\" %s>%s\n", html, SELECTED(flag), gettext(name))
2531
2532 #define BeginSelect(fp, text) \
2533 fprintf(fp,"<select name=\"%s\" %s>\n", text, disable_all?disabled_string:"")
2534
2535 #define MaybeSelect(fp, flag, text) \
2536 fprintf(fp,"<select name=\"%s\" %s>\n", text, disable_all?disabled_string:DISABLED(flag))
2537
2538 #define EndSelect(fp)\
2539 fprintf(fp,"</select>\n")
2540
PutOptValues(FILE * fp,int value,OptValues * table)2541 static void PutOptValues(FILE *fp, int value,
2542 OptValues * table)
2543 {
2544 while (table->LongName != 0) {
2545 if (table->HtmlName) {
2546 PutOption(fp,
2547 value == table->value,
2548 table->HtmlName,
2549 table->LongName);
2550 }
2551 table++;
2552 }
2553 }
2554
GetOptValues(OptValues * table,char * value,int * result)2555 static BOOLEAN GetOptValues(OptValues * table, char *value,
2556 int *result)
2557 {
2558 while (table->LongName != 0) {
2559 if (table->HtmlName && !strcmp(value, table->HtmlName)) {
2560 *result = table->value;
2561 return TRUE;
2562 }
2563 table++;
2564 }
2565 return FALSE;
2566 }
2567
2568 #ifdef USE_COLOR_STYLE
2569 #ifdef LY_FIND_LEAKS
free_colorstyle_leaks(void)2570 void free_colorstyle_leaks(void)
2571 {
2572 FREE(color_style_values);
2573 }
2574 #endif
2575
build_lss_enum(HTList * list)2576 void build_lss_enum(HTList *list)
2577 {
2578 int count = HTList_count(list);
2579
2580 #ifdef LY_FIND_LEAKS
2581 atexit(free_colorstyle_leaks);
2582 #endif
2583
2584 FREE(color_style_values);
2585 if (count != 0) {
2586 LSS_NAMES *obj;
2587 int position = 0;
2588
2589 color_style_values = typecallocn(OptValues, count + 2);
2590
2591 if (color_style_values == NULL)
2592 outofmem(__FILE__, "build_lss_enum");
2593
2594 color_style_values[position++] = bool_values[0];
2595 while ((obj = HTList_objectAt(list, position - 1)) != 0) {
2596 color_style_values[position].value = position;
2597 color_style_values[position].LongName = obj->given;
2598 color_style_values[position].HtmlName = obj->given;
2599 position++;
2600 }
2601 }
2602 color_style_list = list;
2603 }
2604
2605 /*
2606 * Find the current lss-file in the list, to get the default value for the
2607 * form.
2608 */
get_color_style_value(void)2609 static int get_color_style_value(void)
2610 {
2611 int result = 0;
2612
2613 if (LYuse_color_style && non_empty(lynx_lss_file)) {
2614 LSS_NAMES *obj;
2615 int position = 1;
2616
2617 while ((obj = HTList_objectAt(color_style_list, position - 1)) != 0) {
2618 if (obj->actual != 0 && !strcmp(obj->actual, lynx_lss_file)) {
2619 result = position;
2620 break;
2621 } else if (!strcmp(obj->given, lynx_lss_file)) {
2622 result = position;
2623 break;
2624 }
2625 ++position;
2626 }
2627 }
2628 return result;
2629 }
2630
2631 /*
2632 * Return the pathname found in the given list-item.
2633 */
get_color_style_config(int code)2634 static char *get_color_style_config(int code)
2635 {
2636 char *result = 0;
2637
2638 if (LYuse_color_style) {
2639 LSS_NAMES *obj;
2640
2641 if ((obj = HTList_objectAt(color_style_list, code - 1)) != 0) {
2642 result = obj->actual;
2643 }
2644 }
2645 return result;
2646 }
2647 #endif
2648
2649 /*
2650 * Break cgi line into array of pairs of pointers. Don't bother trying to
2651 * be efficient. We're not called all that often.
2652 * We come in with a string looking like:
2653 * tag1=value1&tag2=value2&...&tagN=valueN
2654 * We leave with an array of post_pairs. The last element in the array
2655 * will have a tag pointing to NULL.
2656 * Not pretty, but works. Hey, if strings can be null terminate arrays...
2657 */
break_data(bstring * data)2658 static PostPair *break_data(bstring *data)
2659 {
2660 char *p;
2661 PostPair *q = NULL;
2662 int count = 0;
2663
2664 if (isBEmpty(data))
2665 return NULL;
2666
2667 p = BStrData(data);
2668 CTRACE((tfp, "break_data %s\n", p));
2669
2670 q = typecalloc(PostPair);
2671 if (q == NULL)
2672 outofmem(__FILE__, "break_data(calloc)");
2673
2674 do {
2675 /*
2676 * First, break up on '&', sliding 'p' on down the line.
2677 */
2678 q[count].value = LYstrsep(&p, "&");
2679 /*
2680 * Then break up on '=', sliding value down, and setting tag.
2681 */
2682 q[count].tag = LYstrsep(&(q[count].value), "=");
2683
2684 /*
2685 * Clean them up a bit, in case user entered a funky string.
2686 */
2687 HTUnEscape(q[count].tag);
2688
2689 /* In the value field we have '+' instead of ' '. So do a simple
2690 * find&replace on the value field before UnEscaping() - SKY
2691 */
2692 {
2693 size_t i, len;
2694
2695 len = strlen(q[count].value);
2696 for (i = 0; i < len; i++) {
2697 if (q[count].value[i] == '+') {
2698 #ifdef UNIX
2699 /*
2700 * Allow for special case of options which begin with a "+" on
2701 * Unix - TD
2702 */
2703 if (i > 0
2704 && q[count].value[i + 1] == '+'
2705 && isalnum(UCH(q[count].value[i + 2]))) {
2706 q[count].value[i++] = ' ';
2707 i++;
2708 continue;
2709 }
2710 #endif
2711 q[count].value[i] = ' ';
2712 }
2713 }
2714 }
2715 HTUnEscape(q[count].value);
2716 CTRACE((tfp, "...item[%d] tag=%s, value=%s\n",
2717 count, q[count].tag, q[count].value));
2718
2719 count++;
2720 /*
2721 * Like I said, screw efficiency. Sides, realloc is fast on
2722 * Linux ;->
2723 */
2724 q = typeRealloc(PostPair, q, (unsigned) (count + 1));
2725 if (q == NULL)
2726 outofmem(__FILE__, "break_data(realloc)");
2727
2728 q[count].tag = NULL;
2729 } while (p != NULL && p[0] != '\0');
2730 return q;
2731 }
2732
isLynxOptionsPage(const char * address,const char * portion)2733 static BOOL isLynxOptionsPage(const char *address, const char *portion)
2734 {
2735 BOOL result = FALSE;
2736
2737 if (!strncasecomp(address, STR_LYNXOPTIONS, LEN_LYNXOPTIONS)) {
2738 unsigned len = (unsigned) strlen(portion);
2739
2740 address += LEN_LYNXOPTIONS;
2741 if (!strncasecomp(address, portion, (int) len)
2742 && (address[len] == '\0' || LYIsHtmlSep(address[len]))) {
2743 result = TRUE;
2744 }
2745 }
2746 return result;
2747 }
2748
2749 static int gen_options(char **newfile);
2750
2751 /*
2752 * Handle options from the pseudo-post. I think we really only need
2753 * post_data here, but bring along everything just in case. It's only a
2754 * pointer. MRC
2755 *
2756 * Options are processed in order according to gen_options(), we should not
2757 * depend on it and add boolean flags where the order is essential (save,
2758 * character sets...)
2759 *
2760 * Security: some options are disabled in gen_options() under certain
2761 * conditions. We *should* duplicate the same conditions here in postoptions()
2762 * to prevent user with a limited access from editing HTML options code
2763 * manually (e.g., doing 'e'dit in 'o'ptions) and submit it to access the
2764 * restricted items. Prevent spoofing attempts from index overrun. - LP
2765 *
2766 * Exit status: NULLFILE (reload) or NORMAL (use HText cache).
2767 *
2768 * On exit, got the document which was current before the Options menu:
2769 *
2770 * (from cache) nothing changed or no visual effect supposed:
2771 * editor name, e-mail, etc.
2772 *
2773 * (reload locally) to see the effect of certain changes:
2774 * display_char_set, assume_charset, etc.
2775 * (use 'need_reload' flag where necessary).
2776 *
2777 * (reload from remote server and uncache on a proxy)
2778 * few options changes should be transferred to remote server:
2779 * preferred language, fake browser name, etc.
2780 * (use 'need_end_reload' flag).
2781 */
2782
postoptions(DocInfo * newdoc)2783 int postoptions(DocInfo *newdoc)
2784 {
2785 PostPair *data = 0;
2786 DocAddress WWWDoc; /* need on exit */
2787 int i;
2788 int code = 0;
2789 BOOLEAN save_all = FALSE;
2790 int display_char_set_old = current_char_set;
2791 int old_media_value = LYAcceptMedia;
2792 BOOLEAN raw_mode_old = LYRawMode;
2793 BOOLEAN assume_char_set_changed = FALSE;
2794 BOOLEAN need_reload = FALSE;
2795 BOOLEAN need_end_reload = FALSE;
2796
2797 #if defined(USE_SLANG) || defined(COLOR_CURSES)
2798 int CurrentShowColor = LYShowColor;
2799 #endif
2800 #ifdef USE_DEFAULT_COLORS
2801 BOOLEAN current_default_colors = LYuse_default_colors;
2802 #endif
2803
2804 /*-------------------------------------------------
2805 * kludge a link from mbm_menu, the URL was:
2806 * "<a href=\"" LYNXOPTIONS_PAGE(MBM_MENU) "\">Goto multi-bookmark menu</a>\n"
2807 *--------------------------------------------------*/
2808
2809 if (isLynxOptionsPage(newdoc->address, MBM_LINK)) {
2810 FREE(newdoc->post_data);
2811 if (no_bookmark) {
2812 HTAlert(BOOKMARK_CHANGE_DISALLOWED); /* anonymous */
2813 return (NULLFILE);
2814 } else if (dump_output_immediately) {
2815 return (NOT_FOUND);
2816 } else {
2817 edit_bookmarks();
2818 return (NULLFILE);
2819 }
2820 } else if (!isLynxOptionsPage(newdoc->address, "/")) {
2821 HTAlert(RANDOM_URL_DISALLOWED);
2822 return NULLFILE;
2823 }
2824
2825 data = break_data(newdoc->post_data);
2826
2827 if (!data) {
2828 int status;
2829
2830 /*-------------------------------------------------
2831 * kludge gen_options() call:
2832 *--------------------------------------------------*/
2833 status = gen_options(&newdoc->address);
2834 if (status != NORMAL) {
2835 HTAlwaysAlert("Unexpected way of accessing", newdoc->address);
2836 FREE(newdoc->address);
2837 return (status);
2838 }
2839
2840 /* exit to getfile() cycle */
2841 WWWDoc.address = newdoc->address;
2842 WWWDoc.post_data = newdoc->post_data;
2843 WWWDoc.post_content_type = newdoc->post_content_type;
2844 WWWDoc.bookmark = newdoc->bookmark;
2845 WWWDoc.isHEAD = newdoc->isHEAD;
2846 WWWDoc.safe = newdoc->safe;
2847
2848 if (!HTLoadAbsolute(&WWWDoc))
2849 return (NOT_FOUND);
2850 LYRegisterUIPage(newdoc->address, UIP_OPTIONS_MENU);
2851 #ifdef DIRED_SUPPORT
2852 lynx_edit_mode = FALSE;
2853 #endif /* DIRED_SUPPORT */
2854 return (NORMAL);
2855 }
2856
2857 if (!LYIsUIPage3(HTLoadedDocumentURL(), UIP_OPTIONS_MENU, 0) &&
2858 !LYIsUIPage3(HTLoadedDocumentURL(), UIP_VLINKS, 0)) {
2859 char *buf = NULL;
2860
2861 /* We may have been spoofed? */
2862 HTSprintf0(&buf,
2863 gettext("Use %s to invoke the Options menu!"),
2864 key_for_func_ext(LYK_OPTIONS, FOR_PANEL));
2865 HTAlert(buf);
2866 FREE(buf);
2867 FREE(data);
2868 return (NOT_FOUND);
2869 }
2870
2871 /*
2872 * Checkbox will be missing from data if unchecked.
2873 */
2874 LYSendUserAgent = FALSE;
2875
2876 for (i = 0; data[i].tag != NULL; i++) {
2877 /*
2878 * This isn't really for security, but rather for avoiding that the
2879 * user may revisit an older instance from the history stack and submit
2880 * stuff which accidentally undoes changes that had been done from a
2881 * newer instance. - kw
2882 */
2883 if (!strcmp(data[i].tag, secure_string)) {
2884 if (!secure_value || strcmp(data[i].value, secure_value)) {
2885 char *buf = NULL;
2886
2887 /*
2888 * We probably came from an older instance of the Options
2889 * page that had been on the history stack. - kw
2890 */
2891 HTSprintf0(&buf,
2892 gettext("Use %s to invoke the Options menu!"),
2893 key_for_func_ext(LYK_OPTIONS, FOR_PANEL));
2894 HTAlert(buf);
2895 FREE(data);
2896 return (NULLFILE);
2897 }
2898 FREE(secure_value);
2899 }
2900
2901 /* Save options */
2902 if (!strcmp(data[i].tag, save_options_string) && (!no_option_save)) {
2903 save_all = TRUE;
2904 }
2905
2906 /* Cookies: SELECT */
2907 if (!strcmp(data[i].tag, cookies_string)) {
2908 if (!strcmp(data[i].value, cookies_ignore_all_string)) {
2909 LYSetCookies = FALSE;
2910 } else if (!strcmp(data[i].value, cookies_up_to_user_string)) {
2911 LYSetCookies = TRUE;
2912 LYAcceptAllCookies = FALSE;
2913 } else if (!strcmp(data[i].value, cookies_accept_all_string)) {
2914 LYSetCookies = TRUE;
2915 LYAcceptAllCookies = TRUE;
2916 }
2917 }
2918
2919 /* X Display: INPUT */
2920 if (!strcmp(data[i].tag, x_display_string)) {
2921 LYsetXDisplay(data[i].value);
2922 validate_x_display();
2923 summarize_x_display(data[i].value);
2924 }
2925
2926 /* Editor: INPUT */
2927 if (!strcmp(data[i].tag, editor_string)) {
2928 FREE(editor);
2929 StrAllocCopy(editor, data[i].value);
2930 }
2931
2932 /* Emacs keys: ON/OFF */
2933 if (!strcmp(data[i].tag, emacs_keys_string)
2934 && GetOptValues(bool_values, data[i].value, &code)) {
2935 if ((emacs_keys = (BOOLEAN) code) != FALSE) {
2936 set_emacs_keys();
2937 } else {
2938 reset_emacs_keys();
2939 }
2940 }
2941
2942 /* Execution links: SELECT */
2943 #if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS))
2944 if (!strcmp(data[i].tag, exec_links_string)
2945 && GetOptValues(exec_links_values, data[i].value, &code)) {
2946 #ifndef NEVER_ALLOW_REMOTE_EXEC
2947 local_exec = (BOOLEAN) (code == EXEC_ALWAYS);
2948 #endif /* !NEVER_ALLOW_REMOTE_EXEC */
2949 local_exec_on_local_files = (BOOLEAN) (code == EXEC_LOCAL);
2950 }
2951 #endif /* ENABLE_OPTS_CHANGE_EXEC */
2952
2953 /* Keypad Mode: SELECT */
2954 if (!strcmp(data[i].tag, keypad_mode_string)) {
2955 int newval = 0;
2956
2957 if (GetOptValues(keypad_mode_values, data[i].value, &newval)
2958 && keypad_mode != newval) {
2959 keypad_mode = newval;
2960 need_reload = TRUE;
2961 if (keypad_mode == NUMBERS_AS_ARROWS) {
2962 set_numbers_as_arrows();
2963 } else {
2964 reset_numbers_as_arrows();
2965 }
2966 }
2967 }
2968
2969 /* Line edit style: SELECT */
2970 if (!strcmp(data[i].tag, lineedit_mode_string)) {
2971 int newval = atoi(data[i].value);
2972 int j;
2973
2974 /* prevent spoofing attempt */
2975 for (j = 0; LYEditorNames[j]; j++) {
2976 if (j == newval)
2977 current_lineedit = newval;
2978 }
2979 }
2980 #ifdef EXP_KEYBOARD_LAYOUT
2981 /* Keyboard layout: SELECT */
2982 if (!strcmp(data[i].tag, kblayout_string)) {
2983 int newval = atoi(data[i].value);
2984 int j;
2985
2986 /* prevent spoofing attempt */
2987 for (j = 0; LYKbLayoutNames[j]; j++) {
2988 if (j == newval)
2989 current_layout = newval;
2990 }
2991 }
2992 #endif /* EXP_KEYBOARD_LAYOUT */
2993
2994 /* Mail Address: INPUT */
2995 if (!strcmp(data[i].tag, mail_address_string)) {
2996 FREE(personal_mail_address);
2997 StrAllocCopy(personal_mail_address, data[i].value);
2998 }
2999 #ifndef NO_ANONYMOUS_EMAIL
3000 /* Personal Name: INPUT */
3001 if (!strcmp(data[i].tag, personal_name_string)) {
3002 FREE(personal_mail_name);
3003 StrAllocCopy(personal_mail_name, data[i].value);
3004 }
3005 #endif
3006
3007 /* Anonymous FTP Password: INPUT */
3008 #ifndef DISABLE_FTP
3009 if (!strcmp(data[i].tag, anonftp_password_string)) {
3010 FREE(anonftp_password);
3011 StrAllocCopy(anonftp_password, data[i].value);
3012 }
3013 #endif
3014
3015 /* Search Type: SELECT */
3016 if (!strcmp(data[i].tag, search_type_string)
3017 && GetOptValues(search_type_values, data[i].value, &code)) {
3018 LYcase_sensitive = (BOOLEAN) code;
3019 }
3020
3021 /* HTML error tolerance: SELECT */
3022 if (!strcmp(data[i].tag, DTD_recovery_string)
3023 && GetOptValues(DTD_type_values, data[i].value, &code)) {
3024 if (Old_DTD != code) {
3025 Old_DTD = code;
3026 HTSwitchDTD(!Old_DTD);
3027 need_reload = TRUE;
3028 }
3029 }
3030
3031 /* Bad HTML warnings: SELECT */
3032 if (!strcmp(data[i].tag, bad_html_string)
3033 && GetOptValues(bad_html_values, data[i].value, &code)) {
3034 cfg_bad_html = code;
3035 }
3036
3037 /* Select Popups: ON/OFF */
3038 if (!strcmp(data[i].tag, select_popups_string)
3039 && GetOptValues(bool_values, data[i].value, &code)) {
3040 LYSelectPopups = (BOOLEAN) code;
3041 }
3042 #if defined(USE_SLANG) || defined(COLOR_CURSES)
3043 /* Show Color: SELECT */
3044 if (!strcmp(data[i].tag, show_color_string)
3045 && GetOptValues(show_color_values, data[i].value,
3046 &LYChosenShowColor)) {
3047 if (can_do_colors)
3048 LYShowColor = LYChosenShowColor;
3049 if (CurrentShowColor != LYShowColor) {
3050 lynx_force_repaint();
3051 }
3052 #ifdef USE_SLANG
3053 SLtt_Use_Ansi_Colors = (LYShowColor > SHOW_COLOR_OFF ? TRUE : FALSE);
3054 #endif
3055 }
3056 #endif /* USE_SLANG || COLOR_CURSES */
3057
3058 #ifdef USE_COLOR_STYLE
3059 /* Color Style: ON/OFF */
3060 if (!strcmp(data[i].tag, color_style_string)
3061 && GetOptValues(color_style_values, data[i].value, &code)) {
3062 if (code) {
3063 LYuse_color_style = TRUE;
3064 StrAllocCopy(lynx_lss_file, get_color_style_config(code));
3065 reinit_color_styles();
3066 } else {
3067 LYuse_color_style = FALSE;
3068 }
3069 update_color_style();
3070 lynx_force_repaint();
3071 }
3072 #endif
3073
3074 #ifdef USE_DEFAULT_COLORS
3075 /* Default Colors: ON/OFF */
3076 if (!strcmp(data[i].tag, default_colors_string)
3077 && GetOptValues(bool_values, data[i].value, &code)) {
3078 LYuse_default_colors = (BOOLEAN) code;
3079 if (current_default_colors != LYuse_default_colors) {
3080 CTRACE((tfp, "default_colors changed, updating colors...\n"));
3081 if (has_colors()) {
3082 if (LYuse_default_colors) {
3083 use_default_colors();
3084 } else {
3085 restart_curses();
3086 }
3087 update_default_colors();
3088 lynx_force_repaint();
3089 }
3090 }
3091 }
3092 #endif
3093
3094 /* Show Cursor: ON/OFF */
3095 if (!strcmp(data[i].tag, show_cursor_string)
3096 && GetOptValues(bool_values, data[i].value, &code)) {
3097 LYShowCursor = (BOOLEAN) code;
3098 }
3099
3100 /* Underline links: ON/OFF */
3101 if (!strcmp(data[i].tag, underline_links_string)
3102 && GetOptValues(bool_values, data[i].value, &code)) {
3103 LYUnderlineLinks = (BOOLEAN) code;
3104 }
3105 #ifdef USE_SCROLLBAR
3106 /* Show Scrollbar: ON/OFF */
3107 if (!strcmp(data[i].tag, show_scrollbar_string)
3108 && GetOptValues(bool_values, data[i].value, &code)) {
3109 LYShowScrollbar = (BOOLEAN) code;
3110 need_reload = TRUE;
3111 }
3112 #endif
3113
3114 /* Cookie Version: SELECT */
3115 if (!strcmp(data[i].tag, cookie_version_string))
3116 GetOptValues(cookies_values, data[i].value, &cookie_version);
3117
3118 /* Cookie Prompting: SELECT */
3119 if (!strcmp(data[i].tag, cookie_prompt_string))
3120 GetOptValues(prompt_values, data[i].value, &cookie_noprompt);
3121
3122 #ifdef USE_SSL
3123 /* SSL Prompting: SELECT */
3124 if (!strcmp(data[i].tag, ssl_prompt_string))
3125 GetOptValues(prompt_values, data[i].value, &ssl_noprompt);
3126 #endif
3127
3128 /* User Mode: SELECT */
3129 if (!strcmp(data[i].tag, user_mode_string)
3130 && GetOptValues(user_mode_values, data[i].value, &user_mode)) {
3131 LYSetDisplayLines();
3132 }
3133
3134 /* Type of visited pages page: SELECT */
3135 if (!strcmp(data[i].tag, visited_links_string))
3136 GetOptValues(visited_links_values, data[i].value, &Visited_Links_As);
3137
3138 /* Show Images: SELECT */
3139 if (!strcmp(data[i].tag, images_string)) {
3140 if (!strcmp(data[i].value, images_ignore_all_string)
3141 && !(pseudo_inline_alts == FALSE && clickable_images == FALSE)) {
3142 pseudo_inline_alts = FALSE;
3143 clickable_images = FALSE;
3144 need_reload = TRUE;
3145 } else if (!strcmp(data[i].value, images_use_label_string)
3146 && !(pseudo_inline_alts == TRUE && clickable_images == FALSE)) {
3147 pseudo_inline_alts = TRUE;
3148 clickable_images = FALSE;
3149 need_reload = TRUE;
3150 } else if (!strcmp(data[i].value, images_use_links_string)
3151 && !(clickable_images == TRUE)) {
3152 clickable_images = TRUE;
3153 need_reload = TRUE;
3154 }
3155 }
3156
3157 /* Verbose Images: ON/OFF */
3158 if (!strcmp(data[i].tag, verbose_images_string)
3159 && GetOptValues(verbose_images_type_values, data[i].value, &code)) {
3160 if (verbose_img != code) {
3161 verbose_img = (BOOLEAN) code;
3162 need_reload = TRUE;
3163 }
3164 }
3165
3166 /* Collapse BR Tags: ON/OFF */
3167 if (!strcmp(data[i].tag, collapse_br_tags_string)
3168 && GetOptValues(collapse_br_tags_values, data[i].value, &code)) {
3169 if (LYCollapseBRs != code) {
3170 LYCollapseBRs = (BOOLEAN) code;
3171 need_reload = TRUE;
3172 }
3173 }
3174
3175 /* Trim Blank Lines: ON/OFF */
3176 if (!strcmp(data[i].tag, trim_blank_lines_string)
3177 && GetOptValues(trim_blank_lines_values, data[i].value, &code)) {
3178 if (LYtrimBlankLines != code) {
3179 LYtrimBlankLines = (BOOLEAN) code;
3180 need_reload = TRUE;
3181 }
3182 }
3183
3184 /* VI Keys: ON/OFF */
3185 if (!strcmp(data[i].tag, vi_keys_string)
3186 && GetOptValues(bool_values, data[i].value, &code)) {
3187 if ((vi_keys = (BOOLEAN) code) != FALSE) {
3188 set_vi_keys();
3189 } else {
3190 reset_vi_keys();
3191 }
3192 }
3193
3194 /* Bookmarks File Menu: SELECT */
3195 if (!strcmp(data[i].tag, mbm_string) && (!LYMBMBlocked)) {
3196 GetOptValues(mbm_values, data[i].value, &LYMultiBookmarks);
3197 }
3198
3199 /* Default Bookmarks filename: INPUT */
3200 if (!strcmp(data[i].tag, single_bookmark_string) && (!no_bookmark)) {
3201 if (strcmp(data[i].value, "")) {
3202 FREE(bookmark_page);
3203 StrAllocCopy(bookmark_page, data[i].value);
3204 }
3205 }
3206 #ifdef USE_SESSIONS
3207 /* Auto Session: ON/OFF */
3208 if (!strcmp(data[i].tag, auto_session_string)
3209 && GetOptValues(bool_values, data[i].value, &code)) {
3210 LYAutoSession = (BOOLEAN) code;
3211 }
3212
3213 /* Default Session filename: INPUT */
3214 if (!strcmp(data[i].tag, single_session_string)) {
3215 if (strcmp(data[i].value, "")) {
3216 FREE(LYSessionFile);
3217 StrAllocCopy(LYSessionFile, data[i].value);
3218 }
3219 }
3220 #endif
3221
3222 /* Assume Character Set: SELECT */
3223 if (!strcmp(data[i].tag, assume_char_set_string)) {
3224 int newval = UCGetLYhndl_byMIME(data[i].value);
3225
3226 if (newval >= 0
3227 && ((raw_mode_old &&
3228 newval != safeUCGetLYhndl_byMIME(UCAssume_MIMEcharset))
3229 || (!raw_mode_old &&
3230 newval != UCLYhndl_for_unspec)
3231 )) {
3232
3233 UCLYhndl_for_unspec = newval;
3234 StrAllocCopy(UCAssume_MIMEcharset, data[i].value);
3235 assume_char_set_changed = TRUE;
3236 }
3237 }
3238 #ifdef USE_LOCALE_CHARSET
3239 /* Use locale-based character set: ON/OFF */
3240 if (!strcmp(data[i].tag, locale_charset_string)
3241 && GetOptValues(bool_values, data[i].value, &code)) {
3242 LYLocaleCharset = (BOOLEAN) code;
3243 }
3244 #endif
3245 /* Use HTML5 charset replacements: ON/OFF */
3246 if (!strcmp(data[i].tag, html5_charsets_string)
3247 && GetOptValues(bool_values, data[i].value, &code)) {
3248 html5_charsets = (BOOLEAN) code;
3249 assume_char_set_changed = TRUE;
3250 }
3251
3252 /* Display Character Set: SELECT */
3253 if (!strcmp(data[i].tag, display_char_set_string)) {
3254 int newval = atoi(data[i].value);
3255 int j;
3256
3257 /* prevent spoofing attempt */
3258 for (j = 0; LYchar_set_names[j]; j++) {
3259 if (j == newval)
3260 current_char_set = newval;
3261 }
3262 }
3263 #ifdef USE_IDN2
3264 /* Internationalized Domain Names: SELECT */
3265 if (!strcmp(data[i].tag, idna_mode_string)
3266 && GetOptValues(idna_values, data[i].value, &code)) {
3267 LYidnaMode = code;
3268 }
3269 #endif
3270
3271 /* Raw Mode: ON/OFF */
3272 if (!strcmp(data[i].tag, raw_mode_string)
3273 && GetOptValues(bool_values, data[i].value, &code)) {
3274 LYRawMode = (BOOLEAN) code;
3275 }
3276 #ifndef DISABLE_FTP
3277 /*
3278 * passive ftp: ON/OFF
3279 */
3280 if (!strcmp(data[i].tag, passive_ftp_string)) {
3281 ftp_passive = (BOOLEAN) code;
3282 }
3283
3284 /*
3285 * ftp sort: SELECT
3286 */
3287 if (!strcmp(data[i].tag, ftp_sort_string)) {
3288 GetOptValues(ftp_sort_values, data[i].value, &HTfileSortMethod);
3289 }
3290 #endif /* DISABLE_FTP */
3291
3292 #ifdef DIRED_SUPPORT
3293 /* Local Directory Style: SELECT */
3294 if (!strcmp(data[i].tag, dired_list_string)) {
3295 GetOptValues(dired_list_values, data[i].value, &dir_list_style);
3296 }
3297 #ifdef LONG_LIST
3298 /* Local Directory Order: SELECT */
3299 if (!strcmp(data[i].tag, dired_sort_string)) {
3300 GetOptValues(dired_sort_values, data[i].value, &dir_list_order);
3301 }
3302 #endif /* LONG_LIST */
3303 #endif /* DIRED_SUPPORT */
3304
3305 /* Show dot files: ON/OFF */
3306 if (!strcmp(data[i].tag, show_dotfiles_string) && (!no_dotfiles)
3307 && GetOptValues(bool_values, data[i].value, &code)) {
3308 show_dotfiles = (BOOLEAN) code;
3309 }
3310
3311 /* Pause when showing messages: ON/OFF */
3312 if (!strcmp(data[i].tag, no_pause_string)
3313 && GetOptValues(bool_values, data[i].value, &code)) {
3314 no_pause = (BOOLEAN) !code;
3315 }
3316 #ifdef USE_READPROGRESS
3317 /* Show Transfer Rate: enumerated value */
3318 if (!strcmp(data[i].tag, show_rate_string)
3319 && GetOptValues(rate_values, data[i].value, &code)) {
3320 LYTransferRate = code;
3321 }
3322 #endif /* USE_READPROGRESS */
3323
3324 /* Preferred Content Type: SELECT */
3325 if (!strcmp(data[i].tag, preferred_content_string)) {
3326 GetOptValues(content_values, data[i].value, &LYContentType);
3327 }
3328
3329 /* Preferred Media Type: SELECT */
3330 if (!strcmp(data[i].tag, preferred_media_string)) {
3331 GetOptValues(media_values, data[i].value, &LYAcceptMedia);
3332 }
3333
3334 /* Preferred Encoding: SELECT */
3335 if (!strcmp(data[i].tag, preferred_encoding_string)) {
3336 GetOptValues(encoding_values, data[i].value, &LYAcceptEncoding);
3337 }
3338
3339 /* Preferred Document Character Set: INPUT */
3340 if (!strcmp(data[i].tag, preferred_doc_char_string)) {
3341 if (strcmp(pref_charset, data[i].value)) {
3342 FREE(pref_charset);
3343 StrAllocCopy(pref_charset, data[i].value);
3344 need_end_reload = TRUE;
3345 }
3346 }
3347
3348 /* Preferred Document Language: INPUT */
3349 if (!strcmp(data[i].tag, preferred_doc_lang_string)) {
3350 if (strcmp(language, data[i].value)) {
3351 FREE(language);
3352 StrAllocCopy(language, data[i].value);
3353 need_end_reload = TRUE;
3354 }
3355 }
3356
3357 /*
3358 * HTTP protocol: SELECT
3359 */
3360 if (!strcmp(data[i].tag, http_protocol_string)) {
3361 GetOptValues(http_protocol_values, data[i].value, &HTprotocolLevel);
3362 }
3363
3364 /* Send User Agent: INPUT */
3365 if (!strcmp(data[i].tag, send_user_agent_string)) {
3366 LYSendUserAgent = (BOOLEAN) !strcasecomp(data[i].value, "ON");
3367 }
3368
3369 if (!strcmp(data[i].tag, ssl_client_certificate_file)) {
3370 FREE(SSL_client_cert_file);
3371 StrAllocCopy(SSL_client_cert_file, data[i].value);
3372 }
3373
3374 if (!strcmp(data[i].tag, ssl_client_key_file)) {
3375 FREE(SSL_client_key_file);
3376 StrAllocCopy(SSL_client_key_file, data[i].value);
3377 }
3378
3379 /* User Agent: INPUT */
3380 if (!strcmp(data[i].tag, user_agent_string) && (!no_useragent)) {
3381 if (strcmp(LYUserAgent, data[i].value)) {
3382 need_end_reload = TRUE;
3383 FREE(LYUserAgent);
3384 /* ignore Copyright warning ? */
3385 StrAllocCopy(LYUserAgent,
3386 *(data[i].value)
3387 ? data[i].value
3388 : LYUserAgentDefault);
3389 if (!LYCheckUserAgent()) {
3390 HTAlert(UA_PLEASE_USE_LYNX);
3391 }
3392 }
3393 }
3394 } /* end of loop */
3395
3396 /*
3397 * Process the flags:
3398 */
3399 #ifdef USE_LOCALE_CHARSET
3400 LYFindLocaleCharset();
3401 #endif
3402
3403 if (old_media_value != LYAcceptMedia)
3404 HTFilterPresentations();
3405
3406 if (display_char_set_old != current_char_set ||
3407 raw_mode_old != LYRawMode ||
3408 assume_char_set_changed) {
3409 /*
3410 * charset settings: the order is essential here.
3411 */
3412 if (display_char_set_old != current_char_set) {
3413 /*
3414 * Set the LYUseDefaultRawMode value and character handling if
3415 * LYRawMode was changed. - FM
3416 */
3417 LYUseDefaultRawMode = TRUE;
3418 HTMLUseCharacterSet(current_char_set);
3419 #ifdef CAN_SWITCH_DISPLAY_CHARSET
3420 /* Deduce whether the user wants autoswitch: */
3421 switch_display_charsets =
3422 (current_char_set == auto_display_charset
3423 || current_char_set == auto_other_display_charset);
3424 #endif
3425 }
3426 if (assume_char_set_changed && HTCJK != JAPANESE) {
3427 LYRawMode = (BOOLEAN) (UCLYhndl_for_unspec == current_char_set);
3428 }
3429 if (raw_mode_old != LYRawMode || assume_char_set_changed) {
3430 /*
3431 * Set the raw 8-bit or CJK mode defaults and character set if
3432 * changed. - FM
3433 */
3434 HTMLSetUseDefaultRawMode(current_char_set, LYRawMode);
3435 HTMLSetCharacterHandling(current_char_set);
3436 }
3437 need_reload = TRUE;
3438 }
3439 /* end of charset settings */
3440
3441 BStrFree(newdoc->post_data);
3442 FREE(data);
3443 if (save_all) {
3444 HTInfoMsg(SAVING_OPTIONS);
3445 LYrcShowColor = LYChosenShowColor;
3446 if (save_rc(NULL)) {
3447 HTInfoMsg(OPTIONS_SAVED);
3448 } else {
3449 HTAlert(OPTIONS_NOT_SAVED);
3450 }
3451 }
3452
3453 /*
3454 * Exit: working around the previous document. Being out of
3455 * mainloop()/getfile() cycle, do things manually.
3456 */
3457 CTRACE((tfp, "\nLYOptions.c/postoptions(): exiting...\n"));
3458 CTRACE((tfp, " need_reload = %s\n",
3459 need_reload ? "TRUE" : "FALSE"));
3460 CTRACE((tfp, " need_end_reload = %s\n",
3461 need_end_reload ? "TRUE" : "FALSE"));
3462
3463 /* Options menu was pushed before postoptions(), so pop-up. */
3464 LYpop(newdoc);
3465 WWWDoc.address = newdoc->address;
3466 WWWDoc.post_data = newdoc->post_data;
3467 WWWDoc.post_content_type = newdoc->post_content_type;
3468 WWWDoc.bookmark = newdoc->bookmark;
3469 WWWDoc.isHEAD = newdoc->isHEAD;
3470 WWWDoc.safe = newdoc->safe;
3471 LYforce_no_cache = FALSE; /* ! */
3472 LYoverride_no_cache = TRUE; /* ! */
3473 /*
3474 * Working out of getfile() cycle we reset *no_cache manually here so
3475 * HTLoadAbsolute() will return "Document already in memory": it was
3476 * forced reloading Options Menu again without this (overhead).
3477 *
3478 * Probably *no_cache was set in a wrong position because of
3479 * the internal page...
3480 */
3481 if (!HTLoadAbsolute(&WWWDoc))
3482 return (NOT_FOUND);
3483
3484 HTuncache_current_document(); /* will never use again */
3485
3486 /*
3487 * Return to previous doc, not to options menu! Reload the document we had
3488 * before the options menu but uncache only when necessary (Hurrah, user!):
3489 */
3490 LYpop(newdoc);
3491 WWWDoc.address = newdoc->address;
3492 WWWDoc.post_data = newdoc->post_data;
3493 WWWDoc.post_content_type = newdoc->post_content_type;
3494 WWWDoc.bookmark = newdoc->bookmark;
3495 WWWDoc.isHEAD = newdoc->isHEAD;
3496 WWWDoc.safe = newdoc->safe;
3497 LYforce_no_cache = FALSE; /* see below */
3498 LYoverride_no_cache = TRUE; /* see below */
3499 /*
3500 * Re-setting of *no_cache is probably not required here but this is a
3501 * guarantee against _double_ reloading over the net in case prev document
3502 * has its own "no cache" attribute and options menu set "need_reload"
3503 * also. Force this HTLoadAbsolute() to return "Document already in
3504 * memory".
3505 */
3506 if (!HTLoadAbsolute(&WWWDoc))
3507 return (NOT_FOUND);
3508
3509 /*
3510 * Now most interesting part: reload document when necessary.
3511 * **********************************************************
3512 */
3513
3514 reloading = FALSE; /* set manually */
3515 /* force end-to-end reload from remote server if change LYUserAgent or
3516 * language or pref_charset (marked by need_end_reload flag above), from
3517 * old-style LYK_OPTIONS (mainloop):
3518 */
3519 if ((need_end_reload == TRUE &&
3520 (StrNCmp(newdoc->address, "http", 4) == 0 ||
3521 isLYNXCGI(newdoc->address)))) {
3522 /*
3523 * An option has changed which may influence content negotiation, and
3524 * the resource is from a http or https or lynxcgi URL (the only
3525 * protocols which currently do anything with this information). Set
3526 * reloading = TRUE so that proxy caches will be flushed, which is
3527 * necessary until the time when all proxies understand HTTP 1.1 Vary:
3528 * and all Servers properly use it... Treat like case LYK_RELOAD (see
3529 * comments there). - KW
3530 */
3531 reloading = TRUE; /* global flag */
3532 need_reload = TRUE; /* this was probably already TRUE, don't worry */
3533 }
3534
3535 if (need_reload == FALSE) {
3536 /* no uncache, already loaded */
3537 CTRACE((tfp, "LYOptions.c/postoptions(): now really exit.\n\n"));
3538 return (NORMAL);
3539 } else {
3540 /* update HText cache */
3541
3542 /*
3543 * see LYK_RELOAD & LYK_OPTIONS in mainloop for details...
3544 */
3545 if (HTisDocumentSource()) {
3546 srcmode_for_next_retrieval(1);
3547 }
3548 #ifdef USE_SOURCE_CACHE
3549 if (reloading == FALSE) {
3550 /* one more attempt to be smart enough: */
3551 if (HTcan_reparse_document()) {
3552 if (!HTreparse_document())
3553 srcmode_for_next_retrieval(0);
3554 CTRACE((tfp, "LYOptions.c/postoptions(): now really exit.\n\n"));
3555 return (NORMAL);
3556 }
3557 }
3558 #endif
3559 if (newdoc->post_data != NULL && !newdoc->safe &&
3560 confirm_post_resub(newdoc->address, newdoc->title, 2, 1) == FALSE) {
3561 HTInfoMsg(WILL_NOT_RELOAD_DOC);
3562 if (HTisDocumentSource()) {
3563 srcmode_for_next_retrieval(0);
3564 }
3565 return (NORMAL);
3566 }
3567
3568 HEAD_request = HTLoadedDocumentIsHEAD();
3569 /* uncache and load again */
3570 HTuncache_current_document();
3571 LYpush(newdoc, FALSE);
3572 CTRACE((tfp, "LYOptions.c/postoptions(): now really exit.\n\n"));
3573 return (NULLFILE);
3574 }
3575
3576 /******** Done! **************************************************/
3577 }
3578
NewSecureValue(void)3579 static char *NewSecureValue(void)
3580 {
3581 static char oops[] = "?";
3582
3583 FREE(secure_value);
3584 if ((secure_value = typeMallocn(char, 80)) != 0) {
3585 #if defined(RAND_MAX)
3586 long key = (long) lynx_rand();
3587
3588 #else
3589 long key = (long) secure_value + (long) time(0);
3590 #endif
3591 sprintf(secure_value, "%ld", key);
3592 return secure_value;
3593 }
3594 return oops;
3595 }
3596
3597 #define LABEL_LEN 33
3598
3599 /*
3600 * Note: the 'value' we are passing here is a local copy of the "same" string
3601 * as is used in LYrcFile.c to index the saveable options.
3602 */
PutLabel(FILE * fp,const char * name,const char * value)3603 static void PutLabel(FILE *fp, const char *name,
3604 const char *value)
3605 {
3606 int have = (int) strlen(name);
3607 int want = LABEL_LEN;
3608 int need = LYstrExtent(name, have, want);
3609 char *buffer = NULL;
3610
3611 fprintf(fp, "%s%s", MARGIN_STR, LYEntifyTitle(&buffer, NonNull(name)));
3612
3613 if (will_save_rc(value) && !no_option_save) {
3614 while (need++ < want)
3615 fprintf(fp, " ");
3616 } else {
3617 want -= 3;
3618 if (need < want) {
3619 fprintf(fp, " ");
3620 ++need;
3621 }
3622 fprintf(fp, "(!)");
3623 while (need++ < want) {
3624 fprintf(fp, " ");
3625 }
3626 }
3627 fprintf(fp, ": ");
3628 FREE(buffer);
3629 }
3630
3631 /*
3632 * For given a list of the .lynxrc names for boolean flags that make up a
3633 * composite setting, check if any are not writable for the .lynxrc file. If
3634 * so, return that name, so the subsequence will_save_rc() check in PutLabel()
3635 * will flag the composite as not-saved.
3636 */
check_if_write_lynxrc(STRING2PTR table)3637 static const char *check_if_write_lynxrc(STRING2PTR table)
3638 {
3639 int n;
3640 const char *result = NULL;
3641
3642 for (n = 0; table[n] != 0; ++n) {
3643 result = table[n];
3644 if (!will_save_rc(result))
3645 break;
3646 }
3647 return result;
3648 }
3649
3650 /*
3651 * The options menu treats "Cookies" as a single enumeration, but it is read
3652 * from lynx.cfg (and perhaps .lynxrc) as a set of booleans. Check if any are
3653 * not writable to .lynxrc, so we can show the user.
3654 */
will_save_cookies(void)3655 static const char *will_save_cookies(void)
3656 {
3657 static const char *table[] =
3658 {
3659 RC_SET_COOKIES, /* LYSetCookies */
3660 RC_ACCEPT_ALL_COOKIES, /* LYAcceptAllCookies */
3661 NULL
3662 };
3663
3664 return check_if_write_lynxrc(table);
3665 }
3666
3667 /*
3668 * The options menu treats "Show images" as a single enumeration, but it is
3669 * read from lynx.cfg (and perhaps .lynxrc) as a set of booleans. Check if any
3670 * are not writable to .lynxrc, so we can show the user.
3671 */
will_save_images(void)3672 static const char *will_save_images(void)
3673 {
3674 static const char *table[] =
3675 {
3676 RC_MAKE_PSEUDO_ALTS_FOR_INLINES, /* pseudo_inline_alts */
3677 RC_MAKE_LINKS_FOR_ALL_IMAGES, /* clickable_images */
3678 NULL
3679 };
3680
3681 return check_if_write_lynxrc(table);
3682 }
3683
3684 /*
3685 * The visited-links menu is used from the visited-links page as well as the
3686 * options page.
3687 */
LYMenuVisitedLinks(FILE * fp0,int disable_all)3688 void LYMenuVisitedLinks(FILE *fp0, int disable_all)
3689 {
3690 BeginSelect(fp0, visited_links_string);
3691 PutOptValues(fp0, Visited_Links_As, visited_links_values);
3692 EndSelect(fp0);
3693 }
3694
3695 /*
3696 * Okay, someone wants to change options. So, let's gen up a form for them
3697 * and pass it around. Gor, this is ugly. Be a lot easier in Bourne with
3698 * "here" documents. :->
3699 * Basic Strategy: For each option, throw up the appropriate type of
3700 * control, giving defaults as appropriate. If nothing else, we're
3701 * probably going to test every control there is. MRC
3702 *
3703 * This function is synchronized with postoptions(). Read the comments in
3704 * postoptions() header if you change something in gen_options().
3705 */
gen_options(char ** newfile)3706 static int gen_options(char **newfile)
3707 {
3708 static char tempfile[LY_MAXPATH] = "\0";
3709
3710 int i;
3711 char *buffer = NULL;
3712 BOOLEAN disable_all = FALSE;
3713 FILE *fp0;
3714 size_t cset_len = 0;
3715 size_t text_len = (size_t) ((LYcolLimit > 45)
3716 ? LYcolLimit - (LABEL_LEN + 2 + MARGIN_LEN)
3717 : 7); /* cf: PutLabel */
3718
3719 if ((fp0 = InternalPageFP(tempfile, TRUE)) == 0)
3720 return (NOT_FOUND);
3721
3722 LYLocalFileToURL(newfile, tempfile);
3723
3724 /* This should not be needed if we regenerate the temp file every time with
3725 * a new name, which just happened above in the case
3726 * LYReuseTempfiles==FALSE. Even for LYReuseTempfiles=TRUE, code at the
3727 * end of postoptions() may remove an older cached version from memory if
3728 * that version of the page was left by submitting changes. - kw
3729 * 1999-11-27
3730 * If access to the actual file via getfile() later fails (maybe because of
3731 * some restrictions), mainloop may leave this flag on after popping the
3732 * previous doc which is then unnecessarily reloaded. But I changed
3733 * mainloop to reset the flag. - kw 1999-05-24
3734 */
3735 LYforce_no_cache = TRUE;
3736
3737 /*
3738 * Without LYUseFormsOptions set we should maybe not even get here.
3739 * However, it's possible we do; disable the form in that case. - kw
3740 */
3741 #ifndef NO_OPTION_MENU
3742 if (!LYUseFormsOptions)
3743 disable_all = TRUE;
3744 #endif
3745
3746 BeginInternalPage(fp0, OPTIONS_TITLE, NULL); /* help link below */
3747
3748 /*
3749 * I do C, not HTML. Feel free to pretty this up.
3750 */
3751 fprintf(fp0, "<form action=\"%s\" method=\"post\">\n", STR_LYNXOPTIONS);
3752 /*
3753 * use following with some sort of one shot secret key akin to NCSA
3754 * (or was it CUTE?) telnet one shot password to allow ftp to self.
3755 * to prevent spoofing.
3756 */
3757 fprintf(fp0, "<input name=\"%s\" type=\"hidden\" value=\"%s\">\n",
3758 secure_string, NewSecureValue());
3759
3760 /*
3761 * visible text begins here
3762 */
3763
3764 /* Submit/Reset/Help */
3765 fprintf(fp0, "<p align=center>\n");
3766 if (!disable_all) {
3767 fprintf(fp0,
3768 "<input type=\"submit\" value=\"%s\"> - \n",
3769 LYEntifyValue(&buffer, ACCEPT_CHANGES));
3770 fprintf(fp0,
3771 "<input type=\"reset\" value=\"%s\"> - \n",
3772 LYEntifyValue(&buffer, RESET_CHANGES));
3773 fprintf(fp0,
3774 "%s - \n",
3775 LYEntifyTitle(&buffer, CANCEL_CHANGES));
3776 }
3777 fprintf(fp0, "<a href=\"%s%s\">%s</a>\n",
3778 helpfilepath, LYEntifyTitle(&buffer, OPTIONS_HELP), TO_HELP);
3779
3780 /* Save options */
3781 if (!no_option_save) {
3782 if (!disable_all) {
3783 fprintf(fp0, "<p align=center>%s: ", LYEntifyTitle(&buffer, SAVE_OPTIONS));
3784 fprintf(fp0, "<input type=\"checkbox\" name=\"%s\">\n",
3785 save_options_string);
3786 }
3787 fprintf(fp0, "<br>%s\n",
3788 LYEntifyTitle(&buffer,
3789 gettext("(options marked with (!) will not be saved)")));
3790 }
3791
3792 /*
3793 * preformatted text follows
3794 */
3795 fprintf(fp0, "<pre>\n");
3796
3797 PutHeader(fp0, gettext("General Preferences"));
3798 /*****************************************************************/
3799
3800 /* User Mode: SELECT */
3801 PutLabel(fp0, gettext("User mode"), user_mode_string);
3802 BeginSelect(fp0, user_mode_string);
3803 PutOptValues(fp0, user_mode, user_mode_values);
3804 EndSelect(fp0);
3805
3806 /* Editor: INPUT */
3807 PutLabel(fp0, gettext("Editor"), editor_string);
3808 PutTextInput(fp0, editor_string, NonNull(editor), text_len,
3809 DISABLED(no_editor || system_editor));
3810
3811 /* Search Type: SELECT */
3812 PutLabel(fp0, gettext("Type of Search"), search_type_string);
3813 BeginSelect(fp0, search_type_string);
3814 PutOptValues(fp0, LYcase_sensitive, search_type_values);
3815 EndSelect(fp0);
3816
3817 PutHeader(fp0, gettext("Security and Privacy"));
3818 /*****************************************************************/
3819
3820 /* Cookies: SELECT */
3821 PutLabel(fp0, gettext("Cookies"), will_save_cookies());
3822 BeginSelect(fp0, cookies_string);
3823 PutOption(fp0, !LYSetCookies,
3824 cookies_ignore_all_string,
3825 cookies_ignore_all_string);
3826 PutOption(fp0, LYSetCookies && !LYAcceptAllCookies,
3827 cookies_up_to_user_string,
3828 cookies_up_to_user_string);
3829 PutOption(fp0, LYSetCookies && LYAcceptAllCookies,
3830 cookies_accept_all_string,
3831 cookies_accept_all_string);
3832 EndSelect(fp0);
3833
3834 /* Cookie Version: SELECT */
3835 PutLabel(fp0, gettext("Cookie RFC-version"), cookie_version_string);
3836 BeginSelect(fp0, cookie_version_string);
3837 PutOptValues(fp0, cookie_version, cookies_values);
3838 EndSelect(fp0);
3839
3840 /* Cookie Prompting: SELECT */
3841 PutLabel(fp0, gettext("Invalid-Cookie Prompting"), cookie_prompt_string);
3842 BeginSelect(fp0, cookie_prompt_string);
3843 PutOptValues(fp0, cookie_noprompt, prompt_values);
3844 EndSelect(fp0);
3845
3846 #ifdef USE_SSL
3847 /* SSL Prompting: SELECT */
3848 PutLabel(fp0, gettext("SSL Prompting"), ssl_prompt_string);
3849 BeginSelect(fp0, ssl_prompt_string);
3850 PutOptValues(fp0, ssl_noprompt, prompt_values);
3851 EndSelect(fp0);
3852
3853 PutLabel(fp0, gettext("SSL client certificate file"), ssl_client_certificate_file);
3854 PutTextInput(fp0, ssl_client_certificate_file,
3855 NonNull(SSL_client_cert_file), text_len, "");
3856
3857 PutLabel(fp0, gettext("SSL client key file"), ssl_client_key_file);
3858 PutTextInput(fp0, ssl_client_key_file,
3859 NonNull(SSL_client_key_file), text_len, "");
3860
3861 #endif
3862
3863 PutHeader(fp0, gettext("Keyboard Input"));
3864 /*****************************************************************/
3865
3866 /* Keypad Mode: SELECT */
3867 PutLabel(fp0, gettext("Keypad mode"), keypad_mode_string);
3868 BeginSelect(fp0, keypad_mode_string);
3869 PutOptValues(fp0, keypad_mode, keypad_mode_values);
3870 EndSelect(fp0);
3871
3872 /* Emacs keys: ON/OFF */
3873 PutLabel(fp0, gettext("Emacs keys"), emacs_keys_string);
3874 BeginSelect(fp0, emacs_keys_string);
3875 PutOptValues(fp0, emacs_keys, bool_values);
3876 EndSelect(fp0);
3877
3878 /* VI Keys: ON/OFF */
3879 PutLabel(fp0, gettext("VI keys"), vi_keys_string);
3880 BeginSelect(fp0, vi_keys_string);
3881 PutOptValues(fp0, vi_keys, bool_values);
3882 EndSelect(fp0);
3883
3884 /* Line edit style: SELECT */
3885 if (LYEditorNames[1]) { /* well, at least 2 line edit styles available */
3886 PutLabel(fp0, gettext("Line edit style"), lineedit_mode_string);
3887 BeginSelect(fp0, lineedit_mode_string);
3888 for (i = 0; LYEditorNames[i]; i++) {
3889 char temp[DigitsOf(i) + 3];
3890
3891 sprintf(temp, "%d", i);
3892 PutOption(fp0, i == current_lineedit, temp, LYEditorNames[i]);
3893 }
3894 EndSelect(fp0);
3895 }
3896 #ifdef EXP_KEYBOARD_LAYOUT
3897 /* Keyboard layout: SELECT */
3898 PutLabel(fp0, gettext("Keyboard layout"), kblayout_string);
3899 BeginSelect(fp0, kblayout_string);
3900 for (i = 0; LYKbLayoutNames[i]; i++) {
3901 char temp[DigitsOf(i) + 3];
3902
3903 sprintf(temp, "%d", i);
3904 PutOption(fp0, i == current_layout, temp, LYKbLayoutNames[i]);
3905 }
3906 EndSelect(fp0);
3907 #endif /* EXP_KEYBOARD_LAYOUT */
3908
3909 /*
3910 * Display and Character Set
3911 */
3912 PutHeader(fp0, gettext("Display and Character Set"));
3913 /*****************************************************************/
3914
3915 #ifdef USE_LOCALE_CHARSET
3916 /* Use locale-based character set: ON/OFF */
3917 PutLabel(fp0, gettext("Use locale-based character set"), locale_charset_string);
3918 BeginSelect(fp0, locale_charset_string);
3919 PutOptValues(fp0, LYLocaleCharset, bool_values);
3920 EndSelect(fp0);
3921 #else
3922 #define LYLocaleCharset FALSE
3923 #endif
3924 PutLabel(fp0, gettext("Use HTML5 charset replacements"), html5_charsets_string);
3925 BeginSelect(fp0, html5_charsets_string);
3926 PutOptValues(fp0, html5_charsets, bool_values);
3927 EndSelect(fp0);
3928
3929 /* Display Character Set: SELECT */
3930 PutLabel(fp0, gettext("Display character set"), display_char_set_string);
3931 MaybeSelect(fp0, LYLocaleCharset, display_char_set_string);
3932 for (i = 0; LYchar_set_names[i]; i++) {
3933 char temp[DigitsOf(i) + 3];
3934 size_t len = strlen(LYchar_set_names[i]);
3935
3936 if (len > cset_len)
3937 cset_len = len;
3938 sprintf(temp, "%d", i);
3939 #ifdef USE_CHARSET_CHOICE
3940 if (!charset_subsets[i].hide_display)
3941 #endif
3942 PutOption(fp0, i == current_char_set, temp, LYchar_set_names[i]);
3943 }
3944 EndSelect(fp0);
3945
3946 /* Assume Character Set: SELECT */
3947 {
3948 int curval;
3949
3950 curval = UCLYhndl_for_unspec;
3951
3952 /*
3953 * FIXME: If bogus value in lynx.cfg, then in old way, that is the
3954 * string that was displayed. Now, user will never see that. Good
3955 * or bad? I don't know. MRC
3956 */
3957 if (curval == current_char_set) {
3958 /* ok, LYRawMode, so use UCAssume_MIMEcharset */
3959 curval = safeUCGetLYhndl_byMIME(UCAssume_MIMEcharset);
3960 }
3961 PutLabel(fp0, gettext("Assumed document character set"), assume_char_set_string);
3962 BeginSelect(fp0, assume_char_set_string);
3963 for (i = 0; i < LYNumCharsets; i++) {
3964 #ifdef USE_CHARSET_CHOICE
3965 if (!charset_subsets[i].hide_assumed)
3966 #endif
3967 PutOption(fp0, i == curval,
3968 LYCharSet_UC[i].MIMEname,
3969 LYCharSet_UC[i].MIMEname);
3970 }
3971 EndSelect(fp0);
3972 }
3973
3974 #ifdef USE_IDN2
3975 /* Internationalized Domain Names: SELECT */
3976 {
3977 PutLabel(fp0, gettext("Internationalized domain names"), idna_mode_string);
3978 BeginSelect(fp0, idna_mode_string);
3979 for (i = 0; idna_values[i].value != 0; i++) {
3980 PutOption(fp0, idna_values[i].value == LYidnaMode,
3981 idna_values[i].HtmlName,
3982 idna_values[i].LongName);
3983 }
3984 EndSelect(fp0);
3985 }
3986 #endif
3987
3988 /* Raw Mode: ON/OFF */
3989 if (LYHaveCJKCharacterSet) {
3990 /*
3991 * Since CJK people hardly mixed with other world
3992 * we split the header to make it more readable:
3993 * "CJK mode" for CJK display charsets, and "Raw 8-bit" for others.
3994 */
3995 PutLabel(fp0, gettext("CJK mode"), raw_mode_string);
3996 } else {
3997 PutLabel(fp0, gettext("Raw 8-bit"), raw_mode_string);
3998 }
3999
4000 BeginSelect(fp0, raw_mode_string);
4001 PutOptValues(fp0, LYRawMode, bool_values);
4002 EndSelect(fp0);
4003
4004 /* X Display: INPUT */
4005 PutLabel(fp0, gettext("X Display"), x_display_string);
4006 PutTextInput(fp0, x_display_string, NonNull(x_display), text_len, "");
4007
4008 /*
4009 * Document Appearance
4010 */
4011 PutHeader(fp0, gettext("Document Appearance"));
4012 /*****************************************************************/
4013
4014 /* Show Color: SELECT */
4015 #if defined(USE_SLANG) || defined(COLOR_CURSES)
4016 SetupChosenShowColor();
4017 PutLabel(fp0, gettext("Show color"), show_color_string);
4018 if (no_option_save) {
4019 MaybeSelect(fp0, !can_do_colors, show_color_string);
4020 if (LYShowColor == SHOW_COLOR_NEVER) {
4021 LYShowColor = SHOW_COLOR_OFF;
4022 } else if (LYShowColor == SHOW_COLOR_ALWAYS) {
4023 LYShowColor = SHOW_COLOR_ON;
4024 }
4025 PutOptValues(fp0, LYShowColor - SHOW_COLOR_OFF, bool_values);
4026 } else {
4027 BeginSelect(fp0, show_color_string);
4028 if (can_do_colors) {
4029 show_color_values[2].HtmlName = on_string;
4030 show_color_values[3].LongName = always_string;
4031 } else {
4032 show_color_values[2].HtmlName = NULL; /* suppress "ON" - kw */
4033 show_color_values[3].LongName = "Always try";
4034 }
4035 PutOptValues(fp0, LYChosenShowColor, show_color_values);
4036 }
4037 EndSelect(fp0);
4038 #endif /* USE_SLANG || COLOR_CURSES */
4039
4040 #ifdef USE_COLOR_STYLE
4041 /* Color style: ON/OFF */
4042 if (HasOptValues(color_style_values)) {
4043 PutLabel(fp0, gettext("Color style"), color_style_string);
4044 BeginSelect(fp0, color_style_string);
4045 PutOptValues(fp0, get_color_style_value(), color_style_values);
4046 EndSelect(fp0);
4047 }
4048 #endif
4049
4050 #ifdef USE_DEFAULT_COLORS
4051 /* Default colors: ON/OFF */
4052 if (has_colors()) {
4053 PutLabel(fp0, gettext("Default colors"), default_colors_string);
4054 BeginSelect(fp0, default_colors_string);
4055 PutOptValues(fp0, LYuse_default_colors, bool_values);
4056 EndSelect(fp0);
4057 }
4058 #endif
4059
4060 /* Show cursor: ON/OFF */
4061 PutLabel(fp0, gettext("Show cursor"), show_cursor_string);
4062 BeginSelect(fp0, show_cursor_string);
4063 PutOptValues(fp0, LYShowCursor, bool_values);
4064 EndSelect(fp0);
4065
4066 /* Underline links: ON/OFF */
4067 PutLabel(fp0, gettext("Underline links"), underline_links_string);
4068 BeginSelect(fp0, underline_links_string);
4069 PutOptValues(fp0, LYUnderlineLinks, bool_values);
4070 EndSelect(fp0);
4071
4072 #ifdef USE_SCROLLBAR
4073 /* Show scrollbar: ON/OFF */
4074 PutLabel(fp0, gettext("Show scrollbar"), show_scrollbar_string);
4075 BeginSelect(fp0, show_scrollbar_string);
4076 PutOptValues(fp0, LYShowScrollbar, bool_values);
4077 EndSelect(fp0);
4078 #endif
4079
4080 /* Select Popups: ON/OFF */
4081 PutLabel(fp0, gettext("Popups for select fields"), select_popups_string);
4082 BeginSelect(fp0, select_popups_string);
4083 PutOptValues(fp0, LYSelectPopups, bool_values);
4084 EndSelect(fp0);
4085
4086 /* HTML error recovery: SELECT */
4087 PutLabel(fp0, gettext("HTML error recovery"), DTD_recovery_string);
4088 BeginSelect(fp0, DTD_recovery_string);
4089 PutOptValues(fp0, Old_DTD, DTD_type_values);
4090 EndSelect(fp0);
4091
4092 /* Bad HTML messages: SELECT */
4093 PutLabel(fp0, gettext("Bad HTML messages"), bad_html_string);
4094 BeginSelect(fp0, bad_html_string);
4095 PutOptValues(fp0, cfg_bad_html, bad_html_values);
4096 EndSelect(fp0);
4097
4098 /* Show Images: SELECT */
4099 PutLabel(fp0, gettext("Show images"), will_save_images());
4100 BeginSelect(fp0, images_string);
4101 PutOption(fp0, !pseudo_inline_alts && !clickable_images,
4102 images_ignore_all_string,
4103 images_ignore_all_string);
4104 PutOption(fp0, pseudo_inline_alts && !clickable_images,
4105 images_use_label_string,
4106 images_use_label_string);
4107 PutOption(fp0, clickable_images,
4108 images_use_links_string,
4109 images_use_links_string);
4110 EndSelect(fp0);
4111
4112 /* Verbose Images: ON/OFF */
4113 PutLabel(fp0, gettext("Verbose images"), verbose_images_string);
4114 BeginSelect(fp0, verbose_images_string);
4115 PutOptValues(fp0, verbose_img, verbose_images_type_values);
4116 EndSelect(fp0);
4117
4118 /* Collapse BR Tags: ON/OFF */
4119 PutLabel(fp0, gettext("Collapse BR tags"), collapse_br_tags_string);
4120 BeginSelect(fp0, collapse_br_tags_string);
4121 PutOptValues(fp0, LYCollapseBRs, collapse_br_tags_values);
4122 EndSelect(fp0);
4123
4124 /* Trim blank lines: ON/OFF */
4125 PutLabel(fp0, gettext("Trim blank lines"), trim_blank_lines_string);
4126 BeginSelect(fp0, trim_blank_lines_string);
4127 PutOptValues(fp0, LYtrimBlankLines, trim_blank_lines_values);
4128 EndSelect(fp0);
4129
4130 /*
4131 * Headers Transferred to Remote Servers
4132 */
4133 PutHeader(fp0, gettext("Headers Transferred to Remote Servers"));
4134 /*****************************************************************/
4135
4136 /* Mail Address: INPUT */
4137 PutLabel(fp0, gettext("Personal mail address"), mail_address_string);
4138 PutTextInput(fp0, mail_address_string,
4139 NonNull(personal_mail_address), text_len, "");
4140
4141 #ifndef NO_ANONYMOUS_EMAIL
4142 PutLabel(fp0, gettext("Personal name for mail"), personal_name_string);
4143 PutTextInput(fp0, personal_name_string,
4144 NonNull(personal_mail_name), text_len, "");
4145 #endif
4146
4147 /* Anonymous FTP Address: INPUT */
4148 #ifndef DISABLE_FTP
4149 PutLabel(fp0, gettext("Password for anonymous ftp"), anonftp_password_string);
4150 PutTextInput(fp0, anonftp_password_string,
4151 NonNull(anonftp_password), text_len, "");
4152 #endif
4153
4154 /* Preferred content type: SELECT */
4155 PutLabel(fp0, gettext("Preferred content type"), preferred_content_string);
4156 BeginSelect(fp0, preferred_content_string);
4157 PutOptValues(fp0, LYContentType, content_values);
4158 EndSelect(fp0);
4159
4160 /* Preferred media type: SELECT */
4161 PutLabel(fp0, gettext("Preferred media type"), preferred_media_string);
4162 BeginSelect(fp0, preferred_media_string);
4163 PutOptValues(fp0, LYAcceptMedia, media_values);
4164 EndSelect(fp0);
4165
4166 /* Preferred encoding: SELECT */
4167 PutLabel(fp0, gettext("Preferred encoding"), preferred_encoding_string);
4168 BeginSelect(fp0, preferred_encoding_string);
4169 PutOptValues(fp0, LYAcceptEncoding, encoding_values);
4170 EndSelect(fp0);
4171
4172 /* Preferred Document Character Set: INPUT */
4173 PutLabel(fp0, gettext("Preferred document character set"), preferred_doc_char_string);
4174 PutTextInput(fp0, preferred_doc_char_string,
4175 NonNull(pref_charset), cset_len + 2, "");
4176
4177 /* Preferred Document Language: INPUT */
4178 PutLabel(fp0, gettext("Preferred document language"), preferred_doc_lang_string);
4179 PutTextInput(fp0, preferred_doc_lang_string,
4180 NonNull(language), cset_len + 2, "");
4181
4182 /* HTTP protocol SELECT */
4183 PutLabel(fp0, gettext("HTTP protocol"), http_protocol_string);
4184 BeginSelect(fp0, http_protocol_string);
4185 PutOptValues(fp0, HTprotocolLevel, http_protocol_values);
4186 EndSelect(fp0);
4187
4188 /* User Agent: INPUT */
4189 if (!no_useragent) {
4190 PutLabel(fp0, gettext("Send User-Agent header"), send_user_agent_string);
4191 PutCheckBox(fp0, send_user_agent_string, LYSendUserAgent, "");
4192 PutLabel(fp0, gettext("User-Agent header"), user_agent_string);
4193 PutTextInput(fp0, user_agent_string,
4194 NonNull(LYUserAgent), text_len, "");
4195 }
4196
4197 /*
4198 * Listing and Accessing Files
4199 */
4200 PutHeader(fp0, gettext("Listing and Accessing Files"));
4201 /*****************************************************************/
4202
4203 #ifndef DISABLE_FTP
4204 /* FTP sort: SELECT */
4205 PutLabel(fp0, gettext("Use Passive FTP"), passive_ftp_string);
4206 BeginSelect(fp0, passive_ftp_string);
4207 PutOptValues(fp0, ftp_passive, bool_values);
4208 EndSelect(fp0);
4209
4210 /* FTP sort: SELECT */
4211 PutLabel(fp0, gettext("FTP sort criteria"), ftp_sort_string);
4212 BeginSelect(fp0, ftp_sort_string);
4213 PutOptValues(fp0, HTfileSortMethod, ftp_sort_values);
4214 EndSelect(fp0);
4215 #endif /* DISABLE_FTP */
4216
4217 #ifdef DIRED_SUPPORT
4218 /* Local Directory Sort: SELECT */
4219 PutLabel(fp0, gettext("Local directory sort criteria"), dired_list_string);
4220 BeginSelect(fp0, dired_list_string);
4221 PutOptValues(fp0, dir_list_style, dired_list_values);
4222 EndSelect(fp0);
4223 #ifdef LONG_LIST
4224 /* Local Directory Order: SELECT */
4225 PutLabel(fp0, gettext("Local directory sort order"), dired_sort_string);
4226 BeginSelect(fp0, dired_sort_string);
4227 PutOptValues(fp0, dir_list_order, dired_sort_values);
4228 EndSelect(fp0);
4229 #endif /* LONG_LIST */
4230 #endif /* DIRED_SUPPORT */
4231
4232 /* Show dot files: ON/OFF */
4233 if (!no_dotfiles) {
4234 PutLabel(fp0, gettext("Show dot files"), show_dotfiles_string);
4235 BeginSelect(fp0, show_dotfiles_string);
4236 PutOptValues(fp0, show_dotfiles, bool_values);
4237 EndSelect(fp0);
4238 }
4239
4240 /* Execution links: SELECT */
4241 #if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS))
4242 PutLabel(fp0, gettext("Execution links"), exec_links_string);
4243 BeginSelect(fp0, exec_links_string);
4244 #ifndef NEVER_ALLOW_REMOTE_EXEC
4245 PutOptValues(fp0, local_exec
4246 ? EXEC_ALWAYS
4247 : (local_exec_on_local_files
4248 ? EXEC_LOCAL
4249 : EXEC_NEVER),
4250 exec_links_values);
4251 #else
4252 PutOptValues(fp0, local_exec_on_local_files
4253 ? EXEC_LOCAL
4254 : EXEC_NEVER,
4255 exec_links_values);
4256 #endif /* !NEVER_ALLOW_REMOTE_EXEC */
4257 EndSelect(fp0);
4258 #endif /* ENABLE_OPTS_CHANGE_EXEC */
4259
4260 PutLabel(fp0, gettext("Pause when showing message"), no_pause_string);
4261 BeginSelect(fp0, no_pause_string);
4262 PutOptValues(fp0, !no_pause, bool_values);
4263 EndSelect(fp0);
4264
4265 #ifdef USE_READPROGRESS
4266 /* Show transfer rate: SELECT */
4267 PutLabel(fp0, gettext("Show transfer rate"), show_rate_string);
4268 BeginSelect(fp0, show_rate_string);
4269 for (i = 0; rate_values[i].LongName != 0; ++i) {
4270 char *message = NULL;
4271
4272 HTSprintf0(&message,
4273 rate_values[i].LongName,
4274 HTProgressUnits(rate_values[i].value));
4275 PutOption(fp0,
4276 LYTransferRate == rate_values[i].value,
4277 rate_values[i].HtmlName,
4278 message);
4279 FREE(message);
4280 }
4281 EndSelect(fp0);
4282 #endif /* USE_READPROGRESS */
4283
4284 /*
4285 * Special Files and Screens
4286 */
4287 PutHeader(fp0, gettext("Special Files and Screens"));
4288 /*****************************************************************/
4289
4290 /* Multi-Bookmark Mode: SELECT */
4291 if (!LYMBMBlocked) {
4292 PutLabel(fp0, gettext("Multi-bookmarks"), mbm_string);
4293 BeginSelect(fp0, mbm_string);
4294 PutOptValues(fp0, LYMultiBookmarks, mbm_values);
4295 EndSelect(fp0);
4296 }
4297
4298 /* Bookmarks File Menu: LINK/INPUT */
4299 if (LYMultiBookmarks) {
4300 PutLabel(fp0, gettext("Review/edit Bookmarks files"), mbm_string);
4301 fprintf(fp0, "<a href=\"%s\">%s</a>\n",
4302 LYNXOPTIONS_PAGE(MBM_LINK),
4303 LYEntifyTitle(&buffer, gettext("Goto multi-bookmark menu")));
4304 } else {
4305 PutLabel(fp0, gettext("Bookmarks file"), single_bookmark_string);
4306 PutTextInput(fp0, single_bookmark_string,
4307 NonNull(bookmark_page), text_len, "");
4308 }
4309
4310 #ifdef USE_SESSIONS
4311 /* Auto Session: ON/OFF */
4312 PutLabel(fp0, gettext("Auto Session"), auto_session_string);
4313 BeginSelect(fp0, auto_session_string);
4314 PutOptValues(fp0, LYAutoSession, bool_values);
4315 EndSelect(fp0);
4316
4317 /* Session File Menu: INPUT */
4318 PutLabel(fp0, gettext("Session file"), single_session_string);
4319 PutTextInput(fp0, single_session_string,
4320 NonNull(LYSessionFile), text_len, "");
4321 #endif
4322
4323 /* Visited Pages: SELECT */
4324 PutLabel(fp0, gettext("Visited Pages"), visited_links_string);
4325 LYMenuVisitedLinks(fp0, disable_all);
4326
4327 if (!no_lynxcfg_info) {
4328 fprintf(fp0, "\n %s<a href=\"%s\">lynx.cfg</a>.\n",
4329 LYEntifyTitle(&buffer, gettext("View the file ")),
4330 STR_LYNXCFG);
4331 }
4332
4333 fprintf(fp0, "\n</pre>\n");
4334
4335 /* Submit/Reset */
4336 if (!disable_all) {
4337 fprintf(fp0, "<p align=center>\n");
4338 fprintf(fp0,
4339 "<input type=\"submit\" value=\"%s\"> - \n",
4340 LYEntifyValue(&buffer, ACCEPT_CHANGES));
4341 fprintf(fp0,
4342 "<input type=\"reset\" value=\"%s\"> - \n",
4343 LYEntifyValue(&buffer, RESET_CHANGES));
4344 fprintf(fp0, "%s\n", LYEntifyTitle(&buffer, CANCEL_CHANGES));
4345 }
4346
4347 /*
4348 * close HTML
4349 */
4350 fprintf(fp0, "</form>\n");
4351 EndInternalPage(fp0);
4352
4353 FREE(buffer);
4354
4355 LYCloseTempFP(fp0);
4356 return (NORMAL);
4357 }
4358
4359 #endif /* !NO_OPTION_FORMS */
4360