1 /*
2 * $LynxId: LYReadCFG.c,v 1.199 2021/06/09 21:49:32 tom Exp $
3 */
4 #ifndef NO_RULES
5 #include <HTRules.h>
6 #else
7 #include <HTUtils.h>
8 #endif
9 #include <HTTP.h> /* 'reloading' flag */
10 #include <HTFile.h>
11 #include <HTInit.h>
12 #include <UCMap.h>
13
14 #include <LYUtils.h>
15 #include <GridText.h>
16 #include <LYStrings.h>
17 #include <LYStructs.h>
18 #include <LYGlobalDefs.h>
19 #include <LYCharSets.h>
20 #include <LYCharUtils.h>
21 #include <LYKeymap.h>
22 #include <LYJump.h>
23 #include <LYGetFile.h>
24 #include <LYCgi.h>
25 #include <LYCurses.h>
26 #include <LYBookmark.h>
27 #include <LYCookie.h>
28 #include <LYReadCFG.h>
29 #include <HTAlert.h>
30 #include <LYHistory.h>
31 #include <LYPrettySrc.h>
32 #include <LYrcFile.h>
33
34 #ifdef DIRED_SUPPORT
35 #include <LYLocal.h>
36 #endif /* DIRED_SUPPORT */
37
38 #include <LYexit.h>
39 #include <LYLeaks.h>
40
41 #ifndef DISABLE_NEWS
42 #include <HTNews.h>
43 #endif
44
45 BOOLEAN have_read_cfg = FALSE;
46 BOOLEAN LYUseNoviceLineTwo = TRUE;
47
48 /*
49 * Translate a TRUE/FALSE field in a string buffer.
50 */
is_true(const char * string)51 static BOOL is_true(const char *string)
52 {
53 if (!strcasecomp(string, "TRUE") || !strcasecomp(string, "ON"))
54 return (TRUE);
55 else
56 return (FALSE);
57 }
58
59 /*
60 * Find an unescaped colon in a string buffer.
61 */
find_colon(const char * buffer)62 static const char *find_colon(const char *buffer)
63 {
64 char ch;
65 const char *buf = buffer;
66
67 if (buf == NULL)
68 return NULL;
69
70 while ((ch = *buf) != 0) {
71 if (ch == ':')
72 return buf;
73 if (ch == '\\') {
74 buf++;
75 if (*buf == 0)
76 break;
77 }
78 buf++;
79 }
80 return NULL;
81 }
82
free_item_list_item(lynx_list_item_type ** list,lynx_list_item_type * ptr)83 static void free_item_list_item(lynx_list_item_type **list,
84 lynx_list_item_type *ptr)
85 {
86 lynx_list_item_type *prev;
87 lynx_list_item_type *cur;
88
89 for (cur = *list, prev = 0; cur != 0; prev = cur, cur = cur->next) {
90 if (cur == ptr) {
91
92 if (prev != 0)
93 prev->next = cur->next;
94 else
95 *list = cur->next;
96
97 FREE(cur->name);
98 FREE(cur->menu_name);
99 FREE(cur->command);
100 FREE(cur);
101 break;
102 }
103 }
104 }
105
free_item_list(lynx_list_item_type ** ptr)106 static void free_item_list(lynx_list_item_type **ptr)
107 {
108 while (*ptr != 0) {
109 free_item_list_item(ptr, *ptr);
110 }
111 }
112
113 /*
114 * Function for freeing the DOWNLOADER and UPLOADER menus list. - FM
115 */
free_all_item_lists(void)116 static void free_all_item_lists(void)
117 {
118 free_item_list(&printers);
119 free_item_list(&downloaders);
120 #ifdef DIRED_SUPPORT
121 free_item_list(&uploaders);
122 #endif /* DIRED_SUPPORT */
123
124 #ifdef USE_EXTERNALS
125 free_item_list(&externals);
126 #endif /* USE_EXTERNALS */
127
128 return;
129 }
130
parse_list_bool(BOOL * target,const char * source)131 static const char *parse_list_bool(BOOL *target, const char *source)
132 {
133 const char *result;
134
135 source = LYSkipCBlanks(source);
136 result = find_colon(source);
137
138 if (*source != '\0') {
139 char temp[20];
140 size_t len = ((result != 0)
141 ? (size_t) (result - source)
142 : strlen(source));
143
144 if (len > sizeof(temp))
145 len = (sizeof(temp) - 1);
146 LYStrNCpy(temp, source, len);
147 *target = is_true(temp);
148 CTRACE2(TRACE_CFG, (tfp, "parse_list_bool(%s) '%d'\n", source, *target));
149 }
150 return result;
151 }
152
parse_list_int(int * target,const char * source)153 static const char *parse_list_int(int *target, const char *source)
154 {
155 const char *result;
156
157 source = LYSkipCBlanks(source);
158 result = find_colon(source);
159
160 if (*source != '\0') {
161 *target = atoi(source);
162 CTRACE2(TRACE_CFG, (tfp, "parse_list_int(%s) '%d'\n", source, *target));
163 }
164 return result;
165 }
166
parse_list_string(char ** target,const char * source)167 static const char *parse_list_string(char **target, const char *source)
168 {
169 const char *result;
170
171 source = LYSkipCBlanks(source);
172 result = find_colon(source);
173
174 if (*source != '\0') {
175 const char *next = ((result == 0)
176 ? (source + strlen(source))
177 : result);
178
179 *target = typecallocn(char, (size_t) (next - source + 1));
180
181 if (*target == NULL)
182 outofmem(__FILE__, "read_cfg");
183 LYStrNCpy(*target, source, (next - source));
184 remove_backslashes(*target);
185
186 CTRACE2(TRACE_CFG, (tfp, "parse_list_string(%s) '%s'\n", source, *target));
187 }
188 return result;
189 }
190
191 /*
192 * Process string buffer fields for DOWNLOADER or UPLOADER
193 * or PRINTERS or EXTERNALS menus
194 */
add_item_to_list(char * buffer,lynx_list_item_type ** list_ptr,int special,int menu_name)195 static void add_item_to_list(char *buffer,
196 lynx_list_item_type **list_ptr,
197 int special,
198 int menu_name)
199 {
200 const char *colon, *last_colon;
201 lynx_list_item_type *cur_item, *prev_item;
202
203 /*
204 * Check if the XWINDOWS or NON_XWINDOWS keyword is present in the last
205 * field, and act properly when found depending if external environment
206 * $DISPLAY variable is set.
207 */
208 if ((colon = find_colon(buffer)) == 0) {
209 return;
210 }
211 for (last_colon = colon;
212 (colon = find_colon(last_colon + 1)) != 0;
213 last_colon = colon) {
214 ;
215 }
216
217 /*
218 * If colon equals XWINDOWS then only continue
219 * if there is a $DISPLAY variable
220 */
221 if (!strcasecomp(last_colon + 1, "XWINDOWS")) {
222 if (LYgetXDisplay() == NULL)
223 return;
224 }
225 /*
226 * If colon equals NON_XWINDOWS then only continue
227 * if there is no $DISPLAY variable
228 */
229 else if (!strcasecomp(last_colon + 1, "NON_XWINDOWS")) {
230 if (LYgetXDisplay() != NULL)
231 return;
232 }
233
234 /*
235 * Make a linked list
236 */
237 if (*list_ptr == NULL) {
238 /*
239 * First item.
240 */
241 cur_item = typecalloc(lynx_list_item_type);
242
243 if (cur_item == NULL)
244 outofmem(__FILE__, "read_cfg");
245
246 *list_ptr = cur_item;
247 #ifdef LY_FIND_LEAKS
248 atexit(free_all_item_lists);
249 #endif
250 } else {
251 /*
252 * Find the last item.
253 */
254 for (prev_item = *list_ptr;
255 prev_item->next != NULL;
256 prev_item = prev_item->next) ; /* null body */
257 cur_item = typecalloc(lynx_list_item_type);
258
259 if (cur_item == NULL)
260 outofmem(__FILE__, "read_cfg");
261 else
262 prev_item->next = cur_item;
263 }
264 /* fill-in nonzero default values */
265 cur_item->pagelen = 66;
266
267 /*
268 * Find first unescaped colon and process fields
269 */
270 if (find_colon(buffer) != NULL) {
271 colon = parse_list_string(&(cur_item->name), buffer);
272
273 if (colon && menu_name) {
274 colon = parse_list_string(&(cur_item->menu_name), colon + 1);
275 }
276 if (colon) {
277 colon = parse_list_string(&(cur_item->command), colon + 1);
278 }
279 if (colon) {
280 colon = parse_list_bool(&(cur_item->always_enabled), colon + 1);
281 }
282 if (colon) {
283 if (special) {
284 (void) parse_list_int(&(cur_item->pagelen), colon + 1);
285 } else {
286 (void) parse_list_bool(&(cur_item->override_action), colon + 1);
287 }
288 }
289 }
290
291 /* ignore empty data */
292 if (cur_item->name == NULL
293 || cur_item->command == NULL) {
294 CTRACE2(TRACE_CFG, (tfp, "ignoring incomplete list_item '%s'\n", buffer));
295 free_item_list_item(list_ptr, cur_item);
296 } else if (cur_item->menu_name == NULL) {
297 StrAllocCopy(cur_item->menu_name, cur_item->command);
298 }
299 }
300
find_item_by_number(lynx_list_item_type * list_ptr,char * number)301 lynx_list_item_type *find_item_by_number(lynx_list_item_type *list_ptr,
302 char *number)
303 {
304 int value = atoi(number);
305
306 while (value-- >= 0 && list_ptr != 0) {
307 list_ptr = list_ptr->next;
308 }
309 return list_ptr;
310 }
311
match_item_by_name(lynx_list_item_type * ptr,const char * name,int only_overriders)312 int match_item_by_name(lynx_list_item_type *ptr,
313 const char *name,
314 int only_overriders)
315 {
316 return
317 (ptr->command != 0
318 && !strncasecomp(ptr->name, name, (int) strlen(ptr->name))
319 && (only_overriders ? ptr->override_action : 1));
320 }
321
322 #if defined(USE_COLOR_STYLE) || defined(USE_COLOR_TABLE)
323
324 #ifndef COLOR_WHITE
325 #define COLOR_WHITE 7
326 #endif
327
328 #ifndef COLOR_BLACK
329 #define COLOR_BLACK 0
330 #endif
331
332 #ifdef USE_DEFAULT_COLORS
333 int default_fg = DEFAULT_COLOR;
334 int default_bg = DEFAULT_COLOR;
335
336 #else
337 int default_fg = COLOR_WHITE;
338 int default_bg = COLOR_BLACK;
339 #endif
340
341 static const char *Color_Strings[16] =
342 {
343 "black",
344 "red",
345 "green",
346 "brown",
347 "blue",
348 "magenta",
349 "cyan",
350 "lightgray",
351 "gray",
352 "brightred",
353 "brightgreen",
354 "yellow",
355 "brightblue",
356 "brightmagenta",
357 "brightcyan",
358 "white"
359 };
360
361 #if defined(PDCURSES) && !defined(XCURSES)
362 /*
363 * PDCurses (and possibly some other implementations) use a non-ANSI set of
364 * codes for colors.
365 */
ColorCode(int color)366 static int ColorCode(int color)
367 {
368 /* *INDENT-OFF* */
369 static int map[] =
370 {
371 0, 4, 2, 6, 1, 5, 3, 7,
372 8, 12, 10, 14, 9, 13, 11, 15
373 };
374 /* *INDENT-ON* */
375
376 return map[color];
377 }
378 #else
379 #define ColorCode(color) (color)
380 #endif
381
382 BOOL default_color_reset = FALSE;
383
384 /*
385 * Validator for COLOR fields.
386 */
check_color(const char * color,int the_default)387 int check_color(const char *color,
388 int the_default)
389 {
390 int i;
391
392 CTRACE2(TRACE_STYLE, (tfp, "check_color(%s,%d)\n", color, the_default));
393 if (!strcasecomp(color, "default")) {
394 #ifdef USE_DEFAULT_COLORS
395 if (LYuse_default_colors && !default_color_reset)
396 the_default = DEFAULT_COLOR;
397 #endif /* USE_DEFAULT_COLORS */
398 CTRACE2(TRACE_STYLE, (tfp, "=> default %d\n", the_default));
399 return the_default;
400 }
401 if (!strcasecomp(color, "nocolor"))
402 return NO_COLOR;
403
404 for (i = 0; i < 16; i++) {
405 if (!strcasecomp(color, Color_Strings[i])) {
406 int c = ColorCode(i);
407
408 CTRACE2(TRACE_STYLE, (tfp, "=> %d\n", c));
409 return c;
410 }
411 }
412 CTRACE2(TRACE_STYLE, (tfp, "=> ERR_COLOR\n"));
413 return ERR_COLOR;
414 }
415
lookup_color(int code)416 const char *lookup_color(int code)
417 {
418 unsigned n;
419
420 for (n = 0; n < 16; n++) {
421 if ((int) ColorCode(n) == code)
422 return Color_Strings[n];
423 }
424 return "default";
425 }
426 #endif /* USE_COLOR_STYLE || USE_COLOR_TABLE */
427
428 #if defined(USE_COLOR_TABLE) || defined(EXP_ASSUMED_COLOR)
429
430 /*
431 * Exit routine for failed COLOR parsing.
432 */
exit_with_color_syntax(char * error_line)433 static void exit_with_color_syntax(char *error_line)
434 {
435 unsigned int i;
436
437 fprintf(stderr, gettext("\
438 Syntax Error parsing COLOR in configuration file:\n\
439 The line must be of the form:\n\
440 COLOR:INTEGER:FOREGROUND:BACKGROUND\n\
441 \n\
442 Here FOREGROUND and BACKGROUND must be one of:\n\
443 The special strings 'nocolor' or 'default', or\n")
444 );
445 for (i = 0; i < 16; i += 4) {
446 fprintf(stderr, "%16s %16s %16s %16s\n",
447 Color_Strings[i], Color_Strings[i + 1],
448 Color_Strings[i + 2], Color_Strings[i + 3]);
449 }
450 fprintf(stderr, "%s\nCOLOR:%s\n", gettext("Offending line:"), error_line);
451 exit_immediately(EXIT_FAILURE);
452 }
453 #endif /* defined(USE_COLOR_TABLE) || defined(EXP_ASSUMED_COLOR) */
454
455 #if defined(USE_COLOR_TABLE)
456 /*
457 * Process string buffer fields for COLOR setting.
458 */
parse_color(char * buffer)459 static void parse_color(char *buffer)
460 {
461 int color;
462 const char *fg, *bg;
463 char *temp_fg = 0;
464
465 /*
466 * We are expecting a line of the form:
467 * INTEGER:FOREGROUND:BACKGROUND
468 */
469 color = atoi(buffer);
470 if (NULL == (fg = find_colon(buffer)))
471 exit_with_color_syntax(buffer);
472
473 if (NULL == (bg = find_colon(++fg)))
474 exit_with_color_syntax(buffer);
475
476 StrAllocCopy(temp_fg, fg);
477 temp_fg[bg++ - fg] = '\0';
478
479 #if defined(USE_SLANG)
480 if ((check_color(temp_fg, default_fg) == ERR_COLOR) ||
481 (check_color(bg, default_bg) == ERR_COLOR))
482 exit_with_color_syntax(buffer);
483
484 SLtt_set_color(color, NULL, temp_fg, bg);
485 #else
486 if (lynx_chg_color(color,
487 check_color(temp_fg, default_fg),
488 check_color(bg, default_bg)) < 0)
489 exit_with_color_syntax(buffer);
490 #endif
491 FREE(temp_fg);
492 }
493 #endif /* USE_COLOR_TABLE */
494 /* *INDENT-OFF* */
495 #ifdef USE_SOURCE_CACHE
496 static Config_Enum tbl_source_cache[] = {
497 { "FILE", SOURCE_CACHE_FILE },
498 { "MEMORY", SOURCE_CACHE_MEMORY },
499 { "NONE", SOURCE_CACHE_NONE },
500 { NULL, -1 },
501 };
502
503 static Config_Enum tbl_abort_source_cache[] = {
504 { "KEEP", SOURCE_CACHE_FOR_ABORTED_KEEP },
505 { "DROP", SOURCE_CACHE_FOR_ABORTED_DROP },
506 { NULL, -1 },
507 };
508 #endif
509 /* *INDENT-ON* */
510
511 #define PARSE_ADD(n,v) {n, CONF_ADD_ITEM, UNION_ADD(v), 0}
512 #define PARSE_SET(n,v) {n, CONF_BOOL, UNION_SET(v), 0}
513 #define PARSE_ENU(n,v,t) {n, CONF_ENUM, UNION_INT(v), t}
514 #define PARSE_INT(n,v) {n, CONF_INT, UNION_INT(v), 0}
515 #define PARSE_TIM(n,v) {n, CONF_TIME, UNION_INT(v), 0}
516 #define PARSE_STR(n,v) {n, CONF_STR, UNION_STR(v), 0}
517 #define PARSE_PRG(n,v) {n, CONF_PRG, UNION_DEF(v), 0}
518 #define PARSE_Env(n,v) {n, CONF_ENV, UNION_ENV(v), 0}
519 #define PARSE_ENV(n,v) {n, CONF_ENV2, UNION_ENV(v), 0}
520 #define PARSE_FUN(n,v) {n, CONF_FUN, UNION_FUN(v), 0}
521 #define PARSE_REQ(n,v) {n, CONF_INCLUDE, UNION_FUN(v), 0}
522 #define PARSE_LST(n,v) {n, CONF_ADD_STRING, UNION_LST(v), 0}
523 #define PARSE_DEF(n,v) {n, CONF_ADD_TRUSTED, UNION_DEF(v), 0}
524 #define PARSE_NIL {NULL, CONF_NIL, UNION_DEF(0), 0}
525
526 typedef enum {
527 CONF_NIL = 0
528 ,CONF_BOOL /* BOOLEAN type */
529 ,CONF_FUN
530 ,CONF_TIME
531 ,CONF_ENUM
532 ,CONF_INT
533 ,CONF_STR
534 ,CONF_PRG
535 ,CONF_ENV /* from environment variable */
536 ,CONF_ENV2 /* from environment VARIABLE */
537 ,CONF_INCLUDE /* include file-- handle special */
538 ,CONF_ADD_ITEM
539 ,CONF_ADD_STRING
540 ,CONF_ADD_TRUSTED
541 } Conf_Types;
542
543 typedef struct {
544 const char *name;
545 Conf_Types type;
546 ParseData;
547 Config_Enum *table;
548 } Config_Type;
549
assume_charset_fun(char * value)550 static int assume_charset_fun(char *value)
551 {
552 assumed_charset = TRUE;
553 UCLYhndl_for_unspec = safeUCGetLYhndl_byMIME(value);
554 StrAllocCopy(UCAssume_MIMEcharset,
555 LYCharSet_UC[UCLYhndl_for_unspec].MIMEname);
556 CTRACE((tfp, "assume_charset_fun %s ->%d ->%s\n",
557 NonNull(value),
558 UCLYhndl_for_unspec,
559 UCAssume_MIMEcharset));
560 return 0;
561 }
562
assume_local_charset_fun(char * value)563 static int assume_local_charset_fun(char *value)
564 {
565 UCLYhndl_HTFile_for_unspec = safeUCGetLYhndl_byMIME(value);
566 return 0;
567 }
568
assume_unrec_charset_fun(char * value)569 static int assume_unrec_charset_fun(char *value)
570 {
571 UCLYhndl_for_unrec = safeUCGetLYhndl_byMIME(value);
572 return 0;
573 }
574
character_set_fun(char * value)575 static int character_set_fun(char *value)
576 {
577 int i = UCGetLYhndl_byAnyName(value); /* by MIME or full name */
578
579 if (i < 0) {
580 #ifdef CAN_AUTODETECT_DISPLAY_CHARSET
581 if (auto_display_charset >= 0
582 && (!strncasecomp(value, "AutoDetect ", 11)
583 || !strncasecomp(value, "AutoDetect-2 ", 13)))
584 current_char_set = auto_display_charset;
585 #endif
586 /* do nothing here: so fallback to userdefs.h */
587 } else {
588 current_char_set = i;
589 }
590
591 return 0;
592 }
593
outgoing_mail_charset_fun(char * value)594 static int outgoing_mail_charset_fun(char *value)
595 {
596 outgoing_mail_charset = UCGetLYhndl_byMIME(value);
597 /* -1 if NULL or not recognized value: no translation (compatibility) */
598
599 return 0;
600 }
601
602 #ifdef EXP_ASSUMED_COLOR
603 /*
604 * Process string buffer fields for ASSUMED_COLOR setting.
605 */
assumed_color_fun(char * buffer)606 static int assumed_color_fun(char *buffer)
607 {
608 const char *fg = buffer, *bg;
609 char *temp_fg = 0;
610
611 if (LYuse_default_colors) {
612
613 /*
614 * We are expecting a line of the form:
615 * FOREGROUND:BACKGROUND
616 */
617 if (NULL == (bg = find_colon(fg)))
618 exit_with_color_syntax(buffer);
619
620 StrAllocCopy(temp_fg, fg);
621 temp_fg[bg++ - fg] = '\0';
622
623 default_fg = check_color(temp_fg, default_fg);
624 default_bg = check_color(bg, default_bg);
625
626 if (default_fg == ERR_COLOR
627 || default_bg == ERR_COLOR)
628 exit_with_color_syntax(buffer);
629 FREE(temp_fg);
630 } else {
631 CTRACE((tfp, "...ignored since DEFAULT_COLORS:off\n"));
632 }
633 return 0;
634 }
635 #endif /* EXP_ASSUMED_COLOR */
636
637 #ifdef USE_COLOR_TABLE
color_fun(char * value)638 static int color_fun(char *value)
639 {
640 parse_color(value);
641 return 0;
642 }
643 #endif
644
645 #ifdef USE_COLOR_STYLE
lynx_lss_file_fun(char * value)646 static int lynx_lss_file_fun(char *value)
647 {
648 CTRACE((tfp, "lynx_lss_file_fun '%s'\n", NonNull(value)));
649 if (isEmpty(value)) {
650 clear_lss_list();
651 } else {
652 add_to_lss_list(value, NULL);
653 }
654 return 0;
655 }
656 #endif
657
658 #ifdef USE_DEFAULT_COLORS
update_default_colors(void)659 void update_default_colors(void)
660 {
661 int old_fg = default_fg;
662 int old_bg = default_bg;
663
664 default_color_reset = !LYuse_default_colors;
665 if (LYuse_default_colors) {
666 default_color_reset = FALSE;
667 default_fg = DEFAULT_COLOR;
668 default_bg = DEFAULT_COLOR;
669 } else {
670 default_color_reset = TRUE;
671 default_fg = COLOR_WHITE;
672 default_bg = COLOR_BLACK;
673 }
674 if (old_fg != default_fg || old_bg != default_bg) {
675 lynx_setup_colors();
676 #ifdef USE_COLOR_STYLE
677 update_color_style();
678 #endif
679 }
680 }
681
default_colors_fun(char * value)682 static int default_colors_fun(char *value)
683 {
684 LYuse_default_colors = is_true(value);
685 update_default_colors();
686 return 0;
687 }
688 #endif
689
default_bookmark_file_fun(char * value)690 static int default_bookmark_file_fun(char *value)
691 {
692 set_default_bookmark_page(value);
693 return 0;
694 }
695
default_cache_size_fun(char * value)696 static int default_cache_size_fun(char *value)
697 {
698 HTCacheSize = atoi(value);
699 if (HTCacheSize < 2)
700 HTCacheSize = 2;
701 return 0;
702 }
703
default_editor_fun(char * value)704 static int default_editor_fun(char *value)
705 {
706 if (!system_editor)
707 StrAllocCopy(editor, value);
708 return 0;
709 }
710
numbers_as_arrows_fun(char * value)711 static int numbers_as_arrows_fun(char *value)
712 {
713 if (is_true(value))
714 keypad_mode = NUMBERS_AS_ARROWS;
715 else
716 keypad_mode = LINKS_ARE_NUMBERED;
717
718 return 0;
719 }
720
721 #ifdef DIRED_SUPPORT
dired_menu_fun(char * value)722 static int dired_menu_fun(char *value)
723 {
724 add_menu_item(value);
725 return 0;
726 }
727 #endif
728
jumpfile_fun(char * value)729 static int jumpfile_fun(char *value)
730 {
731 char *buffer = NULL;
732
733 HTSprintf0(&buffer, "JUMPFILE:%s", value);
734 if (!LYJumpInit(buffer))
735 CTRACE((tfp, "Failed to register %s\n", buffer));
736 FREE(buffer);
737
738 return 0;
739 }
740
741 #ifdef EXP_KEYBOARD_LAYOUT
keyboard_layout_fun(char * key)742 static int keyboard_layout_fun(char *key)
743 {
744 if (!LYSetKbLayout(key))
745 CTRACE((tfp, "Failed to set keyboard layout %s\n", key));
746 return 0;
747 }
748 #endif /* EXP_KEYBOARD_LAYOUT */
749
keymap_fun(char * key)750 static int keymap_fun(char *key)
751 {
752 char *func, *efunc;
753
754 if ((func = StrChr(key, ':')) != NULL) {
755 *func++ = '\0';
756 efunc = StrChr(func, ':');
757 /* Allow comments on the ends of key remapping lines. - DT */
758 /* Allow third field for line-editor action. - kw */
759 if (efunc == func) { /* have 3rd field, but 2nd field empty */
760 func = NULL;
761 } else if (efunc && strncasecomp(efunc + 1, "DIRED", 5) == 0) {
762 if (!remap(key, strtok(func, " \t\n:#"), TRUE)) {
763 fprintf(stderr,
764 gettext("key remapping of %s to %s for %s failed\n"),
765 key, func, efunc + 1);
766 } else if (!strcmp("TOGGLE_HELP", func)) {
767 LYUseNoviceLineTwo = FALSE;
768 }
769 return 0;
770 } else if (!remap(key, strtok(func, " \t\n:#"), FALSE)) {
771 fprintf(stderr, gettext("key remapping of %s to %s failed\n"),
772 key, func);
773 } else {
774 if (!strcmp("TOGGLE_HELP", func))
775 LYUseNoviceLineTwo = FALSE;
776 }
777 if (efunc) {
778 efunc++;
779 if (efunc == strtok((func ? NULL : efunc), " \t\n:#") && *efunc) {
780 BOOLEAN success = FALSE;
781 int lkc = lkcstring_to_lkc(key);
782 int lec = -1;
783 int select_edi = 0;
784 char *sselect_edi = strtok(NULL, " \t\n:#");
785 char **endp = &sselect_edi;
786
787 if (sselect_edi) {
788 if (*sselect_edi)
789 select_edi = (int) strtol(sselect_edi, endp, 10);
790 if (**endp != '\0') {
791 fprintf(stderr,
792 gettext("invalid line-editor selection %s for key %s, selecting all\n"),
793 sselect_edi, key);
794 select_edi = 0;
795 }
796 }
797 /*
798 * PASS! tries to enter the key into the LYLineEditors
799 * bindings in a different way from PASS, namely as binding
800 * that maps to the specific lynx actioncode (rather than to
801 * LYE_FORM_PASS). That only works for lynx keycodes with
802 * modifier bit set, and we have no documented/official way to
803 * specify this in the KEYMAP directive, although it can be
804 * made to work e.g. by specifying a hex value that has the
805 * modifier bit set. But knowledge about the bit pattern of
806 * modifiers should remain in internal matter subject to
807 * change... At any rate, if PASS! fails try it the same way
808 * as for PASS. - kw
809 */
810 if (!success && strcasecomp(efunc, "PASS!") == 0) {
811 if (func) {
812 lec = LYE_FORM_LAC | lacname_to_lac(func);
813 success = (BOOL) LYRemapEditBinding(lkc, lec, select_edi);
814 }
815 if (!success)
816 fprintf(stderr,
817 gettext("setting of line-editor binding for key %s (0x%x) to 0x%x for %s failed\n"),
818 key,
819 (unsigned) lkc,
820 (unsigned) lec,
821 efunc);
822 else
823 return 0;
824 }
825 if (!success) {
826 lec = lecname_to_lec(efunc);
827 success = (BOOL) LYRemapEditBinding(lkc, lec, select_edi);
828 }
829 if (!success) {
830 if (lec != -1) {
831 fprintf(stderr,
832 gettext("setting of line-editor binding for key %s (0x%x) to 0x%x for %s failed\n"),
833 key,
834 (unsigned) lkc,
835 (unsigned) lec,
836 efunc);
837 } else {
838 fprintf(stderr,
839 gettext("setting of line-editor binding for key %s (0x%x) for %s failed\n"),
840 key,
841 (unsigned) lkc,
842 efunc);
843 }
844 }
845 }
846 }
847 }
848 return 0;
849 }
850
localhost_alias_fun(char * value)851 static int localhost_alias_fun(char *value)
852 {
853 LYAddLocalhostAlias(value);
854 return 0;
855 }
856
857 #ifdef LYNXCGI_LINKS
lynxcgi_environment_fun(char * value)858 static int lynxcgi_environment_fun(char *value)
859 {
860 add_lynxcgi_environment(value);
861 return 0;
862 }
863 #endif
864
lynx_sig_file_fun(char * value)865 static int lynx_sig_file_fun(char *value)
866 {
867 char temp[LY_MAXPATH];
868
869 LYStrNCpy(temp, value, sizeof(temp) - 1);
870 if (LYPathOffHomeOK(temp, sizeof(temp))) {
871 StrAllocCopy(LynxSigFile, temp);
872 LYAddPathToHome(temp, sizeof(temp), LynxSigFile);
873 StrAllocCopy(LynxSigFile, temp);
874 CTRACE((tfp, "LYNX_SIG_FILE set to '%s'\n", LynxSigFile));
875 } else {
876 CTRACE((tfp, "LYNX_SIG_FILE '%s' is bad. Ignoring.\n", LYNX_SIG_FILE));
877 }
878 return 0;
879 }
880
881 #ifndef DISABLE_NEWS
news_chunk_size_fun(char * value)882 static int news_chunk_size_fun(char *value)
883 {
884 HTNewsChunkSize = atoi(value);
885 /*
886 * If the new HTNewsChunkSize exceeds the maximum,
887 * increase HTNewsMaxChunk to this size. - FM
888 */
889 if (HTNewsChunkSize > HTNewsMaxChunk)
890 HTNewsMaxChunk = HTNewsChunkSize;
891 return 0;
892 }
893
news_max_chunk_fun(char * value)894 static int news_max_chunk_fun(char *value)
895 {
896 HTNewsMaxChunk = atoi(value);
897 /*
898 * If HTNewsChunkSize exceeds the new maximum,
899 * reduce HTNewsChunkSize to this maximum. - FM
900 */
901 if (HTNewsChunkSize > HTNewsMaxChunk)
902 HTNewsChunkSize = HTNewsMaxChunk;
903 return 0;
904 }
905
news_posting_fun(char * value)906 static int news_posting_fun(char *value)
907 {
908 LYNewsPosting = is_true(value);
909 no_newspost = (BOOL) (LYNewsPosting == FALSE);
910 return 0;
911 }
912 #endif /* DISABLE_NEWS */
913
914 #ifndef NO_RULES
cern_rulesfile_fun(char * value)915 static int cern_rulesfile_fun(char *value)
916 {
917 char *rulesfile1 = NULL;
918 char *rulesfile2 = NULL;
919
920 if (HTLoadRules(value) >= 0) {
921 return 0;
922 }
923 StrAllocCopy(rulesfile1, value);
924 LYTrimLeading(value);
925 LYTrimTrailing(value);
926
927 StrAllocCopy(rulesfile2, value);
928 LYTildeExpand(&rulesfile2, FALSE);
929
930 if (strcmp(rulesfile1, rulesfile2) &&
931 HTLoadRules(rulesfile2) >= 0) {
932 FREE(rulesfile1);
933 FREE(rulesfile2);
934 return 0;
935 }
936 fprintf(stderr,
937 gettext("Lynx: cannot start, CERN rules file %s is not available\n"),
938 non_empty(rulesfile2) ? rulesfile2 : gettext("(no name)"));
939 exit_immediately(EXIT_FAILURE);
940 return 0; /* though redundant, for compiler-warnings */
941 }
942 #endif /* NO_RULES */
943
referer_with_query_fun(char * value)944 static int referer_with_query_fun(char *value)
945 {
946 if (!strncasecomp(value, "SEND", 4))
947 LYRefererWithQuery = 'S';
948 else if (!strncasecomp(value, "PARTIAL", 7))
949 LYRefererWithQuery = 'P';
950 else
951 LYRefererWithQuery = 'D';
952 return 0;
953 }
954
status_buffer_size_fun(char * value)955 static int status_buffer_size_fun(char *value)
956 {
957 status_buf_size = atoi(value);
958 if (status_buf_size < 2)
959 status_buf_size = 2;
960 return 0;
961 }
962
startfile_fun(char * value)963 static int startfile_fun(char *value)
964 {
965 StrAllocCopy(startfile, value);
966
967 #ifdef USE_PROGRAM_DIR
968 if (is_url(startfile) == 0) {
969 char *tmp = NULL;
970
971 HTSprintf0(&tmp, "%s\\%s", program_dir, startfile);
972 FREE(startfile);
973 LYLocalFileToURL(&startfile, tmp);
974 FREE(tmp);
975 }
976 #endif
977 return 0;
978 }
979
suffix_fun(char * value)980 static int suffix_fun(char *value)
981 {
982 char *mime_type, *p, *parsed;
983 const char *encoding = NULL;
984 char *sq = NULL;
985 char *description = NULL;
986 double q = 1.0;
987
988 if ((strlen(value) < 3)
989 || (NULL == (mime_type = StrChr(value, ':')))) {
990 CTRACE((tfp, "Invalid SUFFIX:%s ignored.\n", value));
991 return 0;
992 }
993
994 *mime_type++ = '\0';
995 if (*mime_type) {
996 if ((parsed = StrChr(mime_type, ':')) != NULL) {
997 *parsed++ = '\0';
998 if ((sq = StrChr(parsed, ':')) != NULL) {
999 *sq++ = '\0';
1000 if ((description = StrChr(sq, ':')) != NULL) {
1001 *description++ = '\0';
1002 if ((p = StrChr(sq, ':')) != NULL)
1003 *p = '\0';
1004 LYTrimTail(description);
1005 }
1006 LYRemoveBlanks(sq);
1007 if (!*sq)
1008 sq = NULL;
1009 }
1010 LYRemoveBlanks(parsed);
1011 LYLowerCase(parsed);
1012 if (!*parsed)
1013 parsed = NULL;
1014 }
1015 encoding = parsed;
1016 }
1017
1018 LYRemoveBlanks(mime_type);
1019 /*
1020 * mime-type is not converted to lowercase on input, to make it possible to
1021 * reproduce the equivalent of some of the HTInit.c defaults that use mixed
1022 * case, although that is not recommended. - kw
1023 */
1024 if (!*mime_type) { /* that's ok now, with an encoding! */
1025 CTRACE((tfp, "SUFFIX:%s without MIME type for %s\n", value,
1026 encoding ? encoding : "what?"));
1027 mime_type = NULL; /* that's ok now, with an encoding! */
1028 if (!encoding)
1029 return 0;
1030 }
1031
1032 if (!encoding) {
1033 if (strstr(mime_type, "tex") != NULL ||
1034 strstr(mime_type, "postscript") != NULL ||
1035 strstr(mime_type, "sh") != NULL ||
1036 strstr(mime_type, "troff") != NULL ||
1037 strstr(mime_type, "rtf") != NULL)
1038 encoding = "8bit";
1039 else
1040 encoding = "binary";
1041 }
1042 if (!sq) {
1043 q = 1.0;
1044 } else {
1045 double df = strtod(sq, &p);
1046
1047 if (p == sq && df <= 0.0) {
1048 CTRACE((tfp, "Invalid q=%s for SUFFIX:%s, using -1.0\n",
1049 sq, value));
1050 q = -1.0;
1051 } else {
1052 q = df;
1053 }
1054 }
1055 HTSetSuffix5(value, mime_type, encoding, description, q);
1056
1057 return 0;
1058 }
1059
suffix_order_fun(char * value)1060 static int suffix_order_fun(char *value)
1061 {
1062 char *p = value;
1063 char *optn;
1064 BOOLEAN want_file_init_now = FALSE;
1065
1066 LYUseBuiltinSuffixes = TRUE;
1067 while ((optn = HTNextTok(&p, ", ", "", NULL)) != NULL) {
1068 if (!strcasecomp(optn, "NO_BUILTIN")) {
1069 LYUseBuiltinSuffixes = FALSE;
1070 } else if (!strcasecomp(optn, "PRECEDENCE_HERE")) {
1071 want_file_init_now = TRUE;
1072 } else if (!strcasecomp(optn, "PRECEDENCE_OTHER")) {
1073 want_file_init_now = FALSE;
1074 } else {
1075 CTRACE((tfp, "Invalid SUFFIX_ORDER:%s\n", optn));
1076 break;
1077 }
1078 }
1079
1080 if (want_file_init_now && !FileInitAlreadyDone) {
1081 HTFileInit();
1082 FileInitAlreadyDone = TRUE;
1083 }
1084 return 0;
1085 }
1086
system_editor_fun(char * value)1087 static int system_editor_fun(char *value)
1088 {
1089 StrAllocCopy(editor, value);
1090 system_editor = TRUE;
1091 return 0;
1092 }
1093
1094 #define SetViewer(mime_type, viewer) \
1095 HTSetPresentation(mime_type, viewer, 0, 1.0, 3.0, 0.0, 0L, mediaCFG)
1096
viewer_fun(char * value)1097 static int viewer_fun(char *value)
1098 {
1099 char *mime_type;
1100 char *viewer;
1101 char *environment;
1102
1103 mime_type = value;
1104
1105 if ((strlen(value) < 3)
1106 || (NULL == (viewer = StrChr(mime_type, ':'))))
1107 return 0;
1108
1109 *viewer++ = '\0';
1110
1111 LYRemoveBlanks(mime_type);
1112 LYLowerCase(mime_type);
1113
1114 environment = strrchr(viewer, ':');
1115 if ((environment != NULL) &&
1116 (strlen(viewer) > 1) && *(environment - 1) != '\\') {
1117 *environment++ = '\0';
1118 remove_backslashes(viewer);
1119 /*
1120 * If environment equals xwindows then only assign the presentation if
1121 * there is a $DISPLAY variable.
1122 */
1123 if (!strcasecomp(environment, "XWINDOWS")) {
1124 if (LYgetXDisplay() != NULL)
1125 SetViewer(mime_type, viewer);
1126 } else if (!strcasecomp(environment, "NON_XWINDOWS")) {
1127 if (LYgetXDisplay() == NULL)
1128 SetViewer(mime_type, viewer);
1129 } else {
1130 SetViewer(mime_type, viewer);
1131 }
1132 } else {
1133 remove_backslashes(viewer);
1134 SetViewer(mime_type, viewer);
1135 }
1136
1137 return 0;
1138 }
1139
nonrest_sigwinch_fun(char * value)1140 static int nonrest_sigwinch_fun(char *value)
1141 {
1142 if (!strncasecomp(value, "XWINDOWS", 8)) {
1143 LYNonRestartingSIGWINCH = (BOOL) (LYgetXDisplay() != NULL);
1144 } else {
1145 LYNonRestartingSIGWINCH = is_true(value);
1146 }
1147 return 0;
1148 }
1149
1150 #ifdef USE_CHARSET_CHOICE
matched_charset_choice(int display_charset,int i)1151 static void matched_charset_choice(int display_charset,
1152 int i)
1153 {
1154 int j;
1155
1156 if (display_charset && !custom_display_charset) {
1157 for (custom_display_charset = TRUE, j = 0; j < LYNumCharsets; ++j)
1158 charset_subsets[j].hide_display = TRUE;
1159 } else if (!display_charset && !custom_assumed_doc_charset) {
1160 for (custom_assumed_doc_charset = TRUE, j = 0; j < LYNumCharsets; ++j)
1161 charset_subsets[j].hide_assumed = TRUE;
1162 }
1163 if (display_charset)
1164 charset_subsets[i].hide_display = FALSE;
1165 else
1166 charset_subsets[i].hide_assumed = FALSE;
1167 }
1168
parse_charset_choice(char * p,int display_charset)1169 static int parse_charset_choice(char *p,
1170 int display_charset) /*if FALSE, then assumed doc charset */
1171 {
1172 int len, i;
1173 int matches = 0;
1174
1175 /*only one charset choice is allowed per line! */
1176 LYTrimHead(p);
1177 LYTrimTail(p);
1178 CTRACE((tfp, "parsing charset choice for %s:\"%s\"",
1179 (display_charset ? "display charset" : "assumed doc charset"), p));
1180 len = (int) strlen(p);
1181 if (!len) {
1182 CTRACE((tfp, " - EMPTY STRING\n"));
1183 return 1;
1184 }
1185 if (*p == '*' && len == 1) {
1186 if (display_charset)
1187 for (custom_display_charset = TRUE, i = 0; i < LYNumCharsets; ++i)
1188 charset_subsets[i].hide_display = FALSE;
1189 else
1190 for (custom_assumed_doc_charset = TRUE, i = 0; i < LYNumCharsets; ++i)
1191 charset_subsets[i].hide_assumed = FALSE;
1192 CTRACE((tfp, " - all unhidden\n"));
1193 return 0;
1194 }
1195 if (p[len - 1] == '*') {
1196 --len;
1197 for (i = 0; i < LYNumCharsets; ++i) {
1198 if ((!strncasecomp(p, LYchar_set_names[i], len)) ||
1199 (!strncasecomp(p, LYCharSet_UC[i].MIMEname, len))) {
1200 ++matches;
1201 matched_charset_choice(display_charset, i);
1202 }
1203 }
1204 CTRACE((tfp, " - %d matches\n", matches));
1205 return 0;
1206 } else {
1207 for (i = 0; i < LYNumCharsets; ++i) {
1208 if ((!strcasecomp(p, LYchar_set_names[i])) ||
1209 (!strcasecomp(p, LYCharSet_UC[i].MIMEname))) {
1210 matched_charset_choice(display_charset, i);
1211 ++matches;
1212 CTRACE((tfp, " - OK, %d matches\n", matches));
1213 return 0;
1214 }
1215 }
1216 CTRACE((tfp, " - NOT recognised\n"));
1217 return 1;
1218 }
1219 }
1220
parse_display_charset_choice(char * p)1221 static int parse_display_charset_choice(char *p)
1222 {
1223 return parse_charset_choice(p, 1);
1224 }
1225
parse_assumed_doc_charset_choice(char * p)1226 static int parse_assumed_doc_charset_choice(char *p)
1227 {
1228 return parse_charset_choice(p, 0);
1229 }
1230
1231 #endif /* USE_CHARSET_CHOICE */
1232
1233 #ifdef USE_EXTERNALS
1234 /*
1235 * EXTERNAL and EXTERNAL_MENU share the same list. EXTERNAL_MENU allows
1236 * setting a different name than the command string.
1237 */
external_fun(char * str)1238 static int external_fun(char *str)
1239 {
1240 add_item_to_list(str, &externals, FALSE, TRUE);
1241 return 0;
1242 }
1243 #endif
1244
1245 #ifdef USE_PRETTYSRC
html_src_bad_syntax(char * value,char * option_name)1246 static void html_src_bad_syntax(char *value,
1247 char *option_name)
1248 {
1249 char *buf = 0;
1250
1251 HTSprintf0(&buf, "HTMLSRC_%s", option_name);
1252 LYUpperCase(buf);
1253 fprintf(stderr, "Bad syntax in TAGSPEC %s:%s\n", buf, value);
1254 exit_immediately(EXIT_FAILURE);
1255 }
1256
parse_html_src_spec(HTlexeme lexeme_code,char * value,char * option_name)1257 static int parse_html_src_spec(HTlexeme lexeme_code, char *value,
1258 char *option_name)
1259 {
1260 /* Now checking the value for being correct. Since HTML_dtd is not
1261 * initialized completely (member tags points to non-initiailized data), we
1262 * use tags_old. If the syntax is incorrect, then lynx will exit with error
1263 * message.
1264 */
1265 char *ts2;
1266
1267 if (isEmpty(value))
1268 return 0; /* silently ignoring */
1269
1270 #define BS() html_src_bad_syntax(value,option_name)
1271
1272 ts2 = StrChr(value, ':');
1273 if (!ts2)
1274 BS();
1275
1276 *ts2 = '\0';
1277
1278 CTRACE2(TRACE_CFG, (tfp,
1279 "LYReadCFG - parsing tagspec '%s:%s' for option '%s'\n",
1280 value, ts2, option_name));
1281 html_src_clean_item(lexeme_code);
1282 if (!html_src_parse_tagspec(value, lexeme_code, TRUE, TRUE)
1283 || !html_src_parse_tagspec(ts2, lexeme_code, TRUE, TRUE)) {
1284 *ts2 = ':';
1285 BS();
1286 }
1287
1288 *ts2 = ':';
1289 StrAllocCopy(HTL_tagspecs[lexeme_code], value);
1290 #undef BS
1291 return 0;
1292 }
1293
psrcspec_fun(char * s)1294 static int psrcspec_fun(char *s)
1295 {
1296 char *e;
1297 /* *INDENT-OFF* */
1298 static Config_Enum lexemnames[] =
1299 {
1300 { "comm", HTL_comm },
1301 { "tag", HTL_tag },
1302 { "attrib", HTL_attrib },
1303 { "attrval", HTL_attrval },
1304 { "abracket", HTL_abracket },
1305 { "entity", HTL_entity },
1306 { "href", HTL_href },
1307 { "entire", HTL_entire },
1308 { "badseq", HTL_badseq },
1309 { "badtag", HTL_badtag },
1310 { "badattr", HTL_badattr },
1311 { "sgmlspecial", HTL_sgmlspecial },
1312 { NULL, -1 }
1313 };
1314 /* *INDENT-ON* */
1315
1316 int found;
1317
1318 e = StrChr(s, ':');
1319 if (!e) {
1320 CTRACE((tfp,
1321 "bad format of PRETTYSRC_SPEC setting value, ignored %s\n",
1322 s));
1323 return 0;
1324 }
1325 *e = '\0';
1326 if (!LYgetEnum(lexemnames, s, &found)) {
1327 CTRACE((tfp,
1328 "bad format of PRETTYSRC_SPEC setting value, ignored %s:%s\n",
1329 s, e + 1));
1330 return 0;
1331 }
1332 parse_html_src_spec((HTlexeme) found, e + 1, s);
1333 return 0;
1334 }
1335
read_htmlsrc_attrname_xform(char * str)1336 static int read_htmlsrc_attrname_xform(char *str)
1337 {
1338 int val;
1339
1340 if (1 == sscanf(str, "%d", &val)) {
1341 if (val < 0 || val > 2) {
1342 CTRACE((tfp,
1343 "bad value for htmlsrc_attrname_xform (ignored - must be one of 0,1,2): %d\n",
1344 val));
1345 } else
1346 attrname_transform = val;
1347 } else {
1348 CTRACE((tfp, "bad value for htmlsrc_attrname_xform (ignored): %s\n",
1349 str));
1350 }
1351 return 0;
1352 }
1353
read_htmlsrc_tagname_xform(char * str)1354 static int read_htmlsrc_tagname_xform(char *str)
1355 {
1356 int val;
1357
1358 if (1 == sscanf(str, "%d", &val)) {
1359 if (val < 0 || val > 2) {
1360 CTRACE((tfp,
1361 "bad value for htmlsrc_tagname_xform (ignored - must be one of 0,1,2): %d\n",
1362 val));
1363 } else
1364 tagname_transform = val;
1365 } else {
1366 CTRACE((tfp, "bad value for htmlsrc_tagname_xform (ignored): %s\n",
1367 str));
1368 }
1369 return 0;
1370 }
1371 #endif
1372
1373 #ifdef USE_SESSIONS
session_limit_fun(char * value)1374 static int session_limit_fun(char *value)
1375 {
1376 session_limit = (short) atoi(value);
1377 if (session_limit < 1)
1378 session_limit = 1;
1379 else if (session_limit > MAX_SESSIONS)
1380 session_limit = MAX_SESSIONS;
1381 return 0;
1382 }
1383 #endif /* USE_SESSIONS */
1384
1385 #if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401
screen_size_fun(char * value)1386 static int screen_size_fun(char *value)
1387 {
1388 char *cp;
1389
1390 if ((cp = StrChr(value, ',')) != 0) {
1391 *cp++ = '\0'; /* Terminate ID */
1392 scrsize_x = atoi(value);
1393 scrsize_y = atoi(cp);
1394 if ((scrsize_x <= 1) || (scrsize_y <= 1)) {
1395 scrsize_x = scrsize_y = 0;
1396 }
1397 if ((scrsize_x > 0) && (scrsize_x < 80)) {
1398 scrsize_x = 80;
1399 }
1400 if ((scrsize_y > 0) && (scrsize_y < 4)) {
1401 scrsize_y = 4;
1402 }
1403 CTRACE((tfp, "scrsize: x=%d, y=%d\n", scrsize_x, scrsize_y));
1404 }
1405 return 0;
1406 }
1407 #endif
1408
1409 #if defined(HAVE_LIBINTL_H) || defined(HAVE_LIBGETTEXT_H)
message_language_fun(char * value)1410 static int message_language_fun(char *value)
1411 {
1412 char *tmp = NULL;
1413
1414 HTSprintf0(&tmp, "LANG=%s", value);
1415 putenv(tmp);
1416
1417 LYSetTextDomain();
1418
1419 return 0;
1420 }
1421 #endif
1422
1423 /* This table is searched ignoring case */
1424 /* *INDENT-OFF* */
1425 static Config_Type Config_Table [] =
1426 {
1427 PARSE_SET(RC_ACCEPT_ALL_COOKIES, LYAcceptAllCookies),
1428 PARSE_TIM(RC_ALERTSECS, AlertSecs),
1429 #if USE_BLAT_MAILER
1430 PARSE_SET(RC_ALT_BLAT_MAIL, mail_is_altblat),
1431 #endif
1432 PARSE_SET(RC_ALWAYS_RESUBMIT_POSTS, LYresubmit_posts),
1433 #ifdef EXEC_LINKS
1434 PARSE_DEF(RC_ALWAYS_TRUSTED_EXEC, ALWAYS_EXEC_PATH),
1435 #endif
1436 PARSE_FUN(RC_ASSUME_CHARSET, assume_charset_fun),
1437 PARSE_FUN(RC_ASSUME_LOCAL_CHARSET, assume_local_charset_fun),
1438 PARSE_FUN(RC_ASSUME_UNREC_CHARSET, assume_unrec_charset_fun),
1439 #ifdef EXP_ASSUMED_COLOR
1440 PARSE_FUN(RC_ASSUMED_COLOR, assumed_color_fun),
1441 #endif
1442 #ifdef USE_CHARSET_CHOICE
1443 PARSE_FUN(RC_ASSUMED_DOC_CHARSET_CHOICE, parse_assumed_doc_charset_choice),
1444 #endif
1445 #ifdef DIRED_SUPPORT
1446 PARSE_INT(RC_AUTO_UNCACHE_DIRLISTS, LYAutoUncacheDirLists),
1447 #endif
1448 #ifndef DISABLE_BIBP
1449 PARSE_STR(RC_BIBP_BIBHOST, BibP_bibhost),
1450 PARSE_STR(RC_BIBP_GLOBALSERVER, BibP_globalserver),
1451 #endif
1452 #if USE_BLAT_MAILER
1453 PARSE_SET(RC_BLAT_MAIL, mail_is_blat),
1454 #endif
1455 PARSE_SET(RC_BLOCK_MULTI_BOOKMARKS, LYMBMBlocked),
1456 PARSE_SET(RC_BOLD_H1, bold_H1),
1457 PARSE_SET(RC_BOLD_HEADERS, bold_headers),
1458 PARSE_SET(RC_BOLD_NAME_ANCHORS, bold_name_anchors),
1459 #ifndef DISABLE_FTP
1460 PARSE_LST(RC_BROKEN_FTP_EPSV, broken_ftp_epsv),
1461 PARSE_LST(RC_BROKEN_FTP_RETR, broken_ftp_retr),
1462 #endif
1463 PARSE_PRG(RC_BZIP2_PATH, ppBZIP2),
1464 PARSE_SET(RC_CASE_SENSITIVE_ALWAYS_ON, LYcase_sensitive),
1465 PARSE_FUN(RC_CHARACTER_SET, character_set_fun),
1466 #ifdef CAN_SWITCH_DISPLAY_CHARSET
1467 PARSE_STR(RC_CHARSET_SWITCH_RULES, charset_switch_rules),
1468 PARSE_STR(RC_CHARSETS_DIRECTORY, charsets_directory),
1469 #endif
1470 PARSE_SET(RC_CHECKMAIL, check_mail),
1471 PARSE_PRG(RC_CHMOD_PATH, ppCHMOD),
1472 PARSE_SET(RC_COLLAPSE_BR_TAGS, LYCollapseBRs),
1473 #ifdef USE_COLOR_TABLE
1474 PARSE_FUN(RC_COLOR, color_fun),
1475 #endif
1476 #ifdef USE_COLOR_STYLE
1477 PARSE_FUN(RC_COLOR_STYLE, lynx_lss_file_fun),
1478 #endif
1479 PARSE_PRG(RC_COMPRESS_PATH, ppCOMPRESS),
1480 PARSE_PRG(RC_COPY_PATH, ppCOPY),
1481 PARSE_INT(RC_CONNECT_TIMEOUT, connect_timeout),
1482 PARSE_SET(RC_CONV_JISX0201KANA, conv_jisx0201kana),
1483 PARSE_STR(RC_COOKIE_ACCEPT_DOMAINS, LYCookieSAcceptDomains),
1484 #ifdef USE_PERSISTENT_COOKIES
1485 PARSE_STR(RC_COOKIE_FILE, LYCookieFile),
1486 #endif /* USE_PERSISTENT_COOKIES */
1487 PARSE_STR(RC_COOKIE_LOOSE_INVALID_DOMAINS, LYCookieSLooseCheckDomains),
1488 PARSE_STR(RC_COOKIE_QUERY_INVALID_DOMAINS, LYCookieSQueryCheckDomains),
1489 PARSE_STR(RC_COOKIE_REJECT_DOMAINS, LYCookieSRejectDomains),
1490 #ifdef USE_PERSISTENT_COOKIES
1491 PARSE_STR(RC_COOKIE_SAVE_FILE, LYCookieSaveFile),
1492 #endif /* USE_PERSISTENT_COOKIES */
1493 PARSE_STR(RC_COOKIE_STRICT_INVALID_DOMAIN, LYCookieSStrictCheckDomains),
1494 PARSE_ENU(RC_COOKIE_VERSION, cookie_version, tbl_cookie_version),
1495 PARSE_Env(RC_CSO_PROXY, 0),
1496 #ifdef VMS
1497 PARSE_PRG(RC_CSWING_PATH, ppCSWING),
1498 #endif
1499 PARSE_TIM(RC_DELAYSECS, DelaySecs),
1500 PARSE_FUN(RC_DEFAULT_BOOKMARK_FILE, default_bookmark_file_fun),
1501 PARSE_FUN(RC_DEFAULT_CACHE_SIZE, default_cache_size_fun),
1502 #ifdef USE_DEFAULT_COLORS
1503 PARSE_FUN(RC_DEFAULT_COLORS, default_colors_fun),
1504 #endif
1505 PARSE_FUN(RC_DEFAULT_EDITOR, default_editor_fun),
1506 PARSE_STR(RC_DEFAULT_INDEX_FILE, indexfile),
1507 PARSE_ENU(RC_DEFAULT_KEYPAD_MODE, keypad_mode, tbl_keypad_mode),
1508 PARSE_FUN(RC_DEFAULT_KEYPAD_MODE_NUMARO, numbers_as_arrows_fun),
1509 PARSE_ENU(RC_DEFAULT_USER_MODE, user_mode, tbl_user_mode),
1510 #if defined(VMS) && defined(VAXC) && !defined(__DECC)
1511 PARSE_INT(RC_DEFAULT_VIRTUAL_MEMORY_SIZE, HTVirtualMemorySize),
1512 #endif
1513 #ifdef DIRED_SUPPORT
1514 PARSE_FUN(RC_DIRED_MENU, dired_menu_fun),
1515 #endif
1516 #ifdef USE_CHARSET_CHOICE
1517 PARSE_FUN(RC_DISPLAY_CHARSET_CHOICE, parse_display_charset_choice),
1518 #endif
1519 PARSE_SET(RC_DONT_WRAP_PRE, dont_wrap_pre),
1520 PARSE_ADD(RC_DOWNLOADER, downloaders),
1521 PARSE_SET(RC_EMACS_KEYS_ALWAYS_ON, emacs_keys),
1522 PARSE_FUN(RC_ENABLE_LYNXRC, enable_lynxrc),
1523 PARSE_SET(RC_ENABLE_SCROLLBACK, enable_scrollback),
1524 #ifdef USE_EXTERNALS
1525 PARSE_ADD(RC_EXTERNAL, externals),
1526 PARSE_FUN(RC_EXTERNAL_MENU, external_fun),
1527 #endif
1528 PARSE_Env(RC_FINGER_PROXY, 0),
1529 #if defined(_WINDOWS) /* 1998/10/05 (Mon) 17:34:15 */
1530 PARSE_SET(RC_FOCUS_WINDOW, focus_window),
1531 #endif
1532 PARSE_SET(RC_FORCE_8BIT_TOUPPER, UCForce8bitTOUPPER),
1533 PARSE_ENU(RC_FORCE_COOKIE_PROMPT, cookie_noprompt, tbl_force_prompt),
1534 PARSE_SET(RC_FORCE_EMPTY_HREFLESS_A, force_empty_hrefless_a),
1535 PARSE_SET(RC_FORCE_HTML, LYforce_HTML_mode),
1536 PARSE_SET(RC_FORCE_SSL_COOKIES_SECURE, LYForceSSLCookiesSecure),
1537 #ifdef USE_SSL
1538 PARSE_ENU(RC_FORCE_SSL_PROMPT, ssl_noprompt, tbl_force_prompt),
1539 #endif
1540 #if !defined(NO_OPTION_FORMS) && !defined(NO_OPTION_MENU)
1541 PARSE_SET(RC_FORMS_OPTIONS, LYUseFormsOptions),
1542 #endif
1543 PARSE_STR(RC_FTP_FORMAT, ftp_format),
1544 #ifndef DISABLE_FTP
1545 PARSE_SET(RC_FTP_PASSIVE, ftp_passive),
1546 #endif
1547 PARSE_Env(RC_FTP_PROXY, 0),
1548 PARSE_STR(RC_GLOBAL_EXTENSION_MAP, global_extension_map),
1549 PARSE_STR(RC_GLOBAL_MAILCAP, global_type_map),
1550 PARSE_Env(RC_GOPHER_PROXY, 0),
1551 PARSE_SET(RC_GOTOBUFFER, goto_buffer),
1552 PARSE_PRG(RC_GZIP_PATH, ppGZIP),
1553 PARSE_SET(RC_GUESS_SCHEME, LYGuessScheme),
1554 PARSE_STR(RC_HELPFILE, helpfile),
1555 PARSE_FUN(RC_HIDDENLINKS, hiddenlinks_fun),
1556 #ifdef MARK_HIDDEN_LINKS
1557 PARSE_STR(RC_HIDDEN_LINK_MARKER, hidden_link_marker),
1558 #endif
1559 PARSE_SET(RC_HISTORICAL_COMMENTS, historical_comments),
1560 PARSE_SET(RC_HTML5_CHARSETS, html5_charsets),
1561 #ifdef USE_PRETTYSRC
1562 PARSE_FUN(RC_HTMLSRC_ATTRNAME_XFORM, read_htmlsrc_attrname_xform),
1563 PARSE_FUN(RC_HTMLSRC_TAGNAME_XFORM, read_htmlsrc_tagname_xform),
1564 #endif
1565 PARSE_FUN(RC_HTTP_PROTOCOL, get_http_protocol),
1566 PARSE_Env(RC_HTTP_PROXY, 0),
1567 PARSE_Env(RC_HTTPS_PROXY, 0),
1568 PARSE_REQ(RC_INCLUDE, 0),
1569 PARSE_PRG(RC_INFLATE_PATH, ppINFLATE),
1570 PARSE_TIM(RC_INFOSECS, InfoSecs),
1571 PARSE_PRG(RC_INSTALL_PATH, ppINSTALL),
1572 PARSE_STR(RC_JUMP_PROMPT, jumpprompt),
1573 PARSE_SET(RC_JUMPBUFFER, jump_buffer),
1574 PARSE_FUN(RC_JUMPFILE, jumpfile_fun),
1575 #ifdef USE_JUSTIFY_ELTS
1576 PARSE_SET(RC_JUSTIFY, ok_justify),
1577 PARSE_INT(RC_JUSTIFY_MAX_VOID_PERCENT, justify_max_void_percent),
1578 #endif
1579 #ifdef EXP_KEYBOARD_LAYOUT
1580 PARSE_FUN(RC_KEYBOARD_LAYOUT, keyboard_layout_fun),
1581 #endif
1582 PARSE_FUN(RC_KEYMAP, keymap_fun),
1583 PARSE_SET(RC_LEFTARROW_IN_TEXTFLD_PROMPT, textfield_prompt_at_left_edge),
1584 PARSE_SET(RC_LISTONLY, dump_links_only),
1585 PARSE_SET(RC_LIST_DECODED, dump_links_decoded),
1586 #ifndef VMS
1587 PARSE_STR(RC_LIST_FORMAT, list_format),
1588 #endif
1589 PARSE_SET(RC_LIST_INLINE, dump_links_inline),
1590 #ifndef DISABLE_NEWS
1591 PARSE_SET(RC_LIST_NEWS_DATES, LYListNewsDates),
1592 PARSE_SET(RC_LIST_NEWS_NUMBERS, LYListNewsNumbers),
1593 #endif
1594 #ifdef USE_LOCALE_CHARSET
1595 PARSE_SET(RC_LOCALE_CHARSET, LYLocaleCharset),
1596 #endif
1597 PARSE_STR(RC_LOCAL_DOMAIN, LYLocalDomain),
1598 PARSE_SET(RC_LOCALHOST, local_host_only),
1599 PARSE_FUN(RC_LOCALHOST_ALIAS, localhost_alias_fun),
1600 #if defined(EXEC_LINKS) || defined(EXEC_SCRIPTS)
1601 PARSE_SET(RC_LOCAL_EXECUTION_LINKS_ALWAYS, local_exec),
1602 PARSE_SET(RC_LOCAL_EXECUTION_LINKS_LOCAL, local_exec_on_local_files),
1603 #endif
1604 PARSE_STR(RC_LYNX_HOST_NAME, LYHostName),
1605 PARSE_FUN(RC_LYNX_SIG_FILE, lynx_sig_file_fun),
1606 #ifdef LYNXCGI_LINKS
1607 #ifndef VMS
1608 PARSE_STR(RC_LYNXCGI_DOCUMENT_ROOT, LYCgiDocumentRoot),
1609 #endif
1610 PARSE_FUN(RC_LYNXCGI_ENVIRONMENT, lynxcgi_environment_fun),
1611 #endif
1612 #if USE_VMS_MAILER
1613 PARSE_STR(RC_MAIL_ADRS, mail_adrs),
1614 #endif
1615 PARSE_SET(RC_MAIL_SYSTEM_ERROR_LOGGING, error_logging),
1616 PARSE_SET(RC_MAKE_LINKS_FOR_ALL_IMAGES, clickable_images),
1617 PARSE_SET(RC_MAKE_PSEUDO_ALTS_FOR_INLINES, pseudo_inline_alts),
1618 PARSE_INT(RC_MAX_COOKIES_BUFFER, max_cookies_buffer),
1619 PARSE_INT(RC_MAX_COOKIES_DOMAIN, max_cookies_domain),
1620 PARSE_INT(RC_MAX_COOKIES_GLOBAL, max_cookies_global),
1621 PARSE_INT(RC_MAX_URI_SIZE, max_uri_size),
1622 PARSE_TIM(RC_MESSAGESECS, MessageSecs),
1623 #if defined(HAVE_LIBINTL_H) || defined(HAVE_LIBGETTEXT_H)
1624 PARSE_FUN(RC_MESSAGE_LANGUAGE, message_language_fun),
1625 #endif
1626 PARSE_SET(RC_MINIMAL_COMMENTS, minimal_comments),
1627 PARSE_PRG(RC_MKDIR_PATH, ppMKDIR),
1628 PARSE_ENU(RC_MULTI_BOOKMARK_SUPPORT, LYMultiBookmarks, tbl_multi_bookmarks),
1629 PARSE_PRG(RC_MV_PATH, ppMV),
1630 PARSE_SET(RC_NCR_IN_BOOKMARKS, UCSaveBookmarksInUnicode),
1631 #ifdef EXP_NESTED_TABLES
1632 PARSE_SET(RC_NESTED_TABLES, nested_tables),
1633 #endif
1634 #ifndef DISABLE_NEWS
1635 PARSE_FUN(RC_NEWS_CHUNK_SIZE, news_chunk_size_fun),
1636 PARSE_FUN(RC_NEWS_MAX_CHUNK, news_max_chunk_fun),
1637 PARSE_FUN(RC_NEWS_POSTING, news_posting_fun),
1638 PARSE_Env(RC_NEWS_PROXY, 0),
1639 PARSE_Env(RC_NEWSPOST_PROXY, 0),
1640 PARSE_Env(RC_NEWSREPLY_PROXY, 0),
1641 PARSE_Env(RC_NNTP_PROXY, 0),
1642 PARSE_ENV(RC_NNTPSERVER, 0), /* actually NNTPSERVER */
1643 #endif
1644 PARSE_SET(RC_NUMBER_FIELDS_ON_LEFT,number_fields_on_left),
1645 PARSE_SET(RC_NUMBER_LINKS_ON_LEFT, number_links_on_left),
1646 PARSE_SET(RC_NO_DOT_FILES, no_dotfiles),
1647 PARSE_SET(RC_NO_FILE_REFERER, no_filereferer),
1648 #ifndef VMS
1649 PARSE_SET(RC_NO_FORCED_CORE_DUMP, LYNoCore),
1650 #endif
1651 PARSE_SET(RC_NO_FROM_HEADER, LYNoFromHeader),
1652 PARSE_SET(RC_NO_ISMAP_IF_USEMAP, LYNoISMAPifUSEMAP),
1653 PARSE_SET(RC_NO_MARGINS, no_margins),
1654 PARSE_SET(RC_NO_PAUSE, no_pause),
1655 PARSE_Env(RC_NO_PROXY, 0),
1656 PARSE_SET(RC_NO_REFERER_HEADER, LYNoRefererHeader),
1657 PARSE_SET(RC_NO_TABLE_CENTER, no_table_center),
1658 PARSE_SET(RC_NO_TITLE, no_title),
1659 PARSE_SET(RC_UPDATE_TERM_TITLE, update_term_title),
1660 PARSE_FUN(RC_NONRESTARTING_SIGWINCH, nonrest_sigwinch_fun),
1661 PARSE_FUN(RC_OUTGOING_MAIL_CHARSET, outgoing_mail_charset_fun),
1662 #ifdef DISP_PARTIAL
1663 PARSE_SET(RC_PARTIAL, display_partial_flag),
1664 PARSE_INT(RC_PARTIAL_THRES, partial_threshold),
1665 #endif
1666 #ifdef USE_PERSISTENT_COOKIES
1667 PARSE_SET(RC_PERSISTENT_COOKIES, persistent_cookies),
1668 #endif /* USE_PERSISTENT_COOKIES */
1669 PARSE_STR(RC_PERSONAL_EXTENSION_MAP, personal_extension_map),
1670 PARSE_STR(RC_PERSONAL_MAILCAP, personal_type_map),
1671 PARSE_LST(RC_POSITIONABLE_EDITOR, positionable_editor),
1672 PARSE_STR(RC_PREFERRED_CHARSET, pref_charset),
1673 PARSE_ENU(RC_PREFERRED_CONTENT_TYPE, LYContentType, tbl_preferred_content),
1674 PARSE_ENU(RC_PREFERRED_ENCODING, LYAcceptEncoding, tbl_preferred_encoding),
1675 PARSE_STR(RC_PREFERRED_LANGUAGE, language),
1676 PARSE_ENU(RC_PREFERRED_MEDIA_TYPES, LYAcceptMedia, tbl_preferred_media),
1677 PARSE_SET(RC_PREPEND_BASE_TO_SOURCE, LYPrependBaseToSource),
1678 PARSE_SET(RC_PREPEND_CHARSET_TO_SOURCE, LYPrependCharsetToSource),
1679 #ifdef USE_PRETTYSRC
1680 PARSE_SET(RC_PRETTYSRC, LYpsrc),
1681 PARSE_FUN(RC_PRETTYSRC_SPEC, psrcspec_fun),
1682 PARSE_SET(RC_PRETTYSRC_VIEW_NO_ANCHOR_NUM, psrcview_no_anchor_numbering),
1683 #endif
1684 PARSE_ADD(RC_PRINTER, printers),
1685 PARSE_SET(RC_QUIT_DEFAULT_YES, LYQuitDefaultYes),
1686 PARSE_INT(RC_READ_TIMEOUT, reading_timeout),
1687 PARSE_INT(RC_REDIRECTION_LIMIT, redirection_limit),
1688 PARSE_FUN(RC_REFERER_WITH_QUERY, referer_with_query_fun),
1689 #ifdef USE_CMD_LOGGING
1690 PARSE_TIM(RC_REPLAYSECS, ReplaySecs),
1691 #endif
1692 PARSE_SET(RC_REUSE_TEMPFILES, LYReuseTempfiles),
1693 PARSE_PRG(RC_RLOGIN_PATH, ppRLOGIN),
1694 PARSE_PRG(RC_RMDIR_PATH, ppRMDIR),
1695 PARSE_PRG(RC_RM_PATH, ppRM),
1696 #ifndef NO_RULES
1697 PARSE_FUN(RC_RULE, HTSetConfiguration),
1698 PARSE_FUN(RC_RULESFILE, cern_rulesfile_fun),
1699 #endif /* NO_RULES */
1700 PARSE_STR(RC_SAVE_SPACE, lynx_save_space),
1701 PARSE_SET(RC_SCAN_FOR_BURIED_NEWS_REFS, scan_for_buried_news_references),
1702 #if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401
1703 PARSE_FUN(RC_SCREEN_SIZE, screen_size_fun),
1704 #endif
1705 #ifdef USE_SCROLLBAR
1706 PARSE_SET(RC_SCROLLBAR, LYShowScrollbar),
1707 PARSE_SET(RC_SCROLLBAR_ARROW, LYsb_arrow),
1708 #endif
1709 PARSE_SET(RC_SEEK_FRAG_AREA_IN_CUR, LYSeekFragAREAinCur),
1710 PARSE_SET(RC_SEEK_FRAG_MAP_IN_CUR, LYSeekFragMAPinCur),
1711 #ifdef USE_SESSIONS
1712 PARSE_SET(RC_AUTO_SESSION, LYAutoSession),
1713 PARSE_STR(RC_SESSION_FILE, LYSessionFile),
1714 PARSE_FUN(RC_SESSION_LIMIT, session_limit_fun),
1715 #endif
1716 PARSE_SET(RC_SET_COOKIES, LYSetCookies),
1717 PARSE_SET(RC_SHORT_URL, long_url_ok),
1718 PARSE_SET(RC_SHOW_CURSOR, LYShowCursor),
1719 PARSE_STR(RC_SHOW_KB_NAME, LYTransferName),
1720 PARSE_ENU(RC_SHOW_KB_RATE, LYTransferRate, tbl_transfer_rate),
1721 PARSE_Env(RC_SNEWS_PROXY, 0),
1722 PARSE_Env(RC_SNEWSPOST_PROXY, 0),
1723 PARSE_Env(RC_SNEWSREPLY_PROXY, 0),
1724 PARSE_SET(RC_SOFT_DQUOTES, soft_dquotes),
1725 #ifdef USE_SOURCE_CACHE
1726 PARSE_ENU(RC_SOURCE_CACHE, LYCacheSource, tbl_source_cache),
1727 PARSE_ENU(RC_SOURCE_CACHE_FOR_ABORTED, LYCacheSourceForAborted, tbl_abort_source_cache),
1728 #endif
1729 PARSE_STR(RC_SSL_CERT_FILE, SSL_cert_file),
1730 PARSE_STR(RC_SSL_CLIENT_CERT_FILE, SSL_client_cert_file),
1731 PARSE_STR(RC_SSL_CLIENT_KEY_FILE, SSL_client_key_file),
1732 PARSE_FUN(RC_STARTFILE, startfile_fun),
1733 PARSE_FUN(RC_STATUS_BUFFER_SIZE, status_buffer_size_fun),
1734 PARSE_SET(RC_STRIP_DOTDOT_URLS, LYStripDotDotURLs),
1735 PARSE_SET(RC_SUBSTITUTE_UNDERSCORES, use_underscore),
1736 PARSE_FUN(RC_SUFFIX, suffix_fun),
1737 PARSE_FUN(RC_SUFFIX_ORDER, suffix_order_fun),
1738 #ifdef SYSLOG_REQUESTED_URLS
1739 PARSE_SET(RC_SYSLOG_REQUESTED_URLS, syslog_requested_urls),
1740 PARSE_STR(RC_SYSLOG_TEXT, syslog_txt),
1741 #endif
1742 PARSE_FUN(RC_SYSTEM_EDITOR, system_editor_fun),
1743 PARSE_STR(RC_SYSTEM_MAIL, system_mail),
1744 PARSE_STR(RC_SYSTEM_MAIL_FLAGS, system_mail_flags),
1745 PARSE_FUN(RC_TAGSOUP, get_tagsoup),
1746 PARSE_PRG(RC_TAR_PATH, ppTAR),
1747 PARSE_PRG(RC_TELNET_PATH, ppTELNET),
1748 #ifdef TEXTFIELDS_MAY_NEED_ACTIVATION
1749 PARSE_SET(RC_TEXTFIELDS_NEED_ACTIVATION, textfields_activation_option),
1750 #endif
1751 PARSE_PRG(RC_TN3270_PATH, ppTN3270),
1752 #if defined(_WINDOWS)
1753 PARSE_INT(RC_TIMEOUT, lynx_timeout),
1754 #endif
1755 PARSE_PRG(RC_TOUCH_PATH, ppTOUCH),
1756 PARSE_SET(RC_TRACK_INTERNAL_LINKS, track_internal_links),
1757 PARSE_SET(RC_TRIM_BLANK_LINES, LYtrimBlankLines),
1758 PARSE_SET(RC_TRIM_INPUT_FIELDS, LYtrimInputFields),
1759 #ifdef EXEC_LINKS
1760 PARSE_DEF(RC_TRUSTED_EXEC, EXEC_PATH),
1761 #endif
1762 #ifdef LYNXCGI_LINKS
1763 PARSE_DEF(RC_TRUSTED_LYNXCGI, CGI_PATH),
1764 #endif
1765 PARSE_PRG(RC_UNCOMPRESS_PATH, ppUNCOMPRESS),
1766 PARSE_SET(RC_UNDERLINE_LINKS, LYUnderlineLinks),
1767 PARSE_SET(RC_UNIQUE_URLS, unique_urls),
1768 PARSE_PRG(RC_UNZIP_PATH, ppUNZIP),
1769 #ifdef DIRED_SUPPORT
1770 PARSE_ADD(RC_UPLOADER, uploaders),
1771 #endif
1772 PARSE_STR(RC_URL_DOMAIN_PREFIXES, URLDomainPrefixes),
1773 PARSE_STR(RC_URL_DOMAIN_SUFFIXES, URLDomainSuffixes),
1774 #ifdef VMS
1775 PARSE_SET(RC_USE_FIXED_RECORDS, UseFixedRecords),
1776 #endif
1777 #if defined(USE_MOUSE)
1778 PARSE_SET(RC_USE_MOUSE, LYUseMouse),
1779 #endif
1780 PARSE_SET(RC_USE_SELECT_POPUPS, LYSelectPopups),
1781 PARSE_PRG(RC_UUDECODE_PATH, ppUUDECODE),
1782 PARSE_SET(RC_VERBOSE_IMAGES, verbose_img),
1783 PARSE_SET(RC_VI_KEYS_ALWAYS_ON, vi_keys),
1784 PARSE_FUN(RC_VIEWER, viewer_fun),
1785 PARSE_Env(RC_WAIS_PROXY, 0),
1786 PARSE_SET(RC_WAIT_VIEWER_TERMINATION, wait_viewer_termination),
1787 PARSE_SET(RC_WITH_BACKSPACES, with_backspaces),
1788 PARSE_STR(RC_XLOADIMAGE_COMMAND, XLoadImageCommand),
1789 PARSE_SET(RC_XHTML_PARSING, LYxhtml_parsing),
1790 PARSE_PRG(RC_ZCAT_PATH, ppZCAT),
1791 PARSE_PRG(RC_ZIP_PATH, ppZIP),
1792
1793 PARSE_NIL
1794 };
1795 /* *INDENT-ON* */
1796
1797 static char *lynxcfginfo_url = NULL; /* static */
1798
1799 #if defined(HAVE_CONFIG_H) && !defined(NO_CONFIG_INFO)
1800 static char *configinfo_url = NULL; /* static */
1801 #endif
1802
1803 /*
1804 * Free memory allocated in 'read_cfg()'
1805 */
free_lynx_cfg(void)1806 void free_lynx_cfg(void)
1807 {
1808 Config_Type *tbl;
1809
1810 for (tbl = Config_Table; tbl->name != 0; tbl++) {
1811 ParseUnionPtr q = ParseUnionOf(tbl);
1812
1813 switch (tbl->type) {
1814 case CONF_ENV:
1815 if (q->str_value != 0) {
1816 char *name = *(q->str_value);
1817 char *eqls = StrChr(name, '=');
1818
1819 if (eqls != 0) {
1820 *eqls = 0;
1821 #ifdef VMS
1822 Define_VMSLogical(name, NULL);
1823 #else
1824 # ifdef HAVE_PUTENV
1825 if (putenv(name))
1826 break;
1827 # else
1828 unsetenv(name);
1829 # endif
1830 #endif
1831 }
1832 FREE(*(q->str_value));
1833 FREE(q->str_value);
1834 /* is it enough for reload_read_cfg() to clean up
1835 * the result of putenv()? No for certain platforms.
1836 */
1837 }
1838 break;
1839 default:
1840 break;
1841 }
1842 }
1843 free_all_item_lists();
1844 #ifdef DIRED_SUPPORT
1845 reset_dired_menu(); /* frees and resets dired menu items - kw */
1846 #endif
1847 FREE(lynxcfginfo_url);
1848 #if defined(HAVE_CONFIG_H) && !defined(NO_CONFIG_INFO)
1849 FREE(configinfo_url);
1850 #endif
1851 }
1852
lookup_config(const char * name)1853 static Config_Type *lookup_config(const char *name)
1854 {
1855 Config_Type *tbl = Config_Table;
1856 char ch = (char) TOUPPER(*name);
1857
1858 while (tbl->name != 0) {
1859 char ch1 = tbl->name[0];
1860
1861 if ((ch == TOUPPER(ch1))
1862 && (0 == strcasecomp(name, tbl->name)))
1863 break;
1864
1865 tbl++;
1866 }
1867 return tbl;
1868 }
1869
1870 /*
1871 * If the given value is an absolute path (by syntax), or we can read it, use
1872 * the value as given. Otherwise, assume it must be in the same place we read
1873 * the parent configuration file from.
1874 *
1875 * Note: only read files from the current directory if there's no parent
1876 * filename, otherwise it leads to user surprise.
1877 */
actual_filename(const char * cfg_filename,const char * parent_filename,const char * dft_filename)1878 static char *actual_filename(const char *cfg_filename,
1879 const char *parent_filename,
1880 const char *dft_filename)
1881 {
1882 char *my_filename = NULL;
1883
1884 if (!LYisAbsPath(cfg_filename)
1885 && !(parent_filename == 0 && LYCanReadFile(cfg_filename))) {
1886 if (LYIsTilde(cfg_filename[0]) && LYIsPathSep(cfg_filename[1])) {
1887 HTSprintf0(&my_filename, "%s%s", Home_Dir(), cfg_filename + 1);
1888 } else {
1889 if (parent_filename != 0) {
1890 StrAllocCopy(my_filename, parent_filename);
1891 *LYPathLeaf(my_filename) = '\0';
1892 StrAllocCat(my_filename, cfg_filename);
1893 }
1894 if (my_filename == 0 || !LYCanReadFile(my_filename)) {
1895 StrAllocCopy(my_filename, dft_filename);
1896 *LYPathLeaf(my_filename) = '\0';
1897 StrAllocCat(my_filename, cfg_filename);
1898 if (!LYCanReadFile(my_filename)) {
1899 StrAllocCopy(my_filename,
1900 LYFindConfigFile(cfg_filename,
1901 dft_filename));
1902 }
1903 }
1904 }
1905 } else {
1906 StrAllocCopy(my_filename, cfg_filename);
1907 }
1908 return my_filename;
1909 }
1910
LYOpenCFG(const char * cfg_filename,const char * parent_filename,const char * dft_filename)1911 FILE *LYOpenCFG(const char *cfg_filename,
1912 const char *parent_filename,
1913 const char *dft_filename)
1914 {
1915 char *my_file = actual_filename(cfg_filename, parent_filename, dft_filename);
1916 FILE *result;
1917
1918 CTRACE((tfp, "opening config file %s\n", my_file));
1919 result = fopen(my_file, TXT_R);
1920 FREE(my_file);
1921
1922 return result;
1923 }
1924
1925 #define NOPTS_ ( TABLESIZE(Config_Table) - 1 )
1926 typedef BOOL (optidx_set_t)[NOPTS_];
1927
1928 /* if element is FALSE, then it's allowed in the current file */
1929
1930 #define optidx_set_AND(r,a,b) \
1931 {\
1932 unsigned i1;\
1933 for (i1 = 0; i1 < NOPTS_; ++i1) \
1934 (r)[i1]= (BOOLEAN) ((a)[i1] || (b)[i1]); \
1935 }
1936
1937 /*
1938 * For simple (boolean, string, integer, time) values, set the corresponding
1939 * configuration variable.
1940 */
LYSetConfigValue(const char * name,const char * param)1941 BOOL LYSetConfigValue(const char *name,
1942 const char *param)
1943 {
1944 BOOL changed = TRUE;
1945 char *value = NULL;
1946 Config_Type *tbl = lookup_config(name);
1947 ParseUnionPtr q = ParseUnionOf(tbl);
1948 char *temp_name = 0;
1949 char *temp_value = 0;
1950
1951 if (param == NULL)
1952 param = "";
1953 StrAllocCopy(value, param);
1954 switch (tbl->type) {
1955 case CONF_BOOL:
1956 if (q->set_value != 0)
1957 *(q->set_value) = is_true(value);
1958 break;
1959
1960 case CONF_FUN:
1961 if (q->fun_value != 0)
1962 (*(q->fun_value)) (value);
1963 break;
1964
1965 case CONF_TIME:
1966 if (q->int_value != 0) {
1967 float ival;
1968
1969 if (1 == LYscanFloat(value, &ival)) {
1970 *(q->int_value) = (int) SECS2Secs(ival);
1971 }
1972 }
1973 break;
1974
1975 case CONF_ENUM:
1976 if (tbl->table != 0)
1977 LYgetEnum(tbl->table, value, q->int_value);
1978 break;
1979
1980 case CONF_INT:
1981 if (q->int_value != 0) {
1982 int ival;
1983
1984 if (1 == sscanf(value, "%d", &ival))
1985 *(q->int_value) = ival;
1986 }
1987 break;
1988
1989 case CONF_STR:
1990 if (q->str_value != 0)
1991 StrAllocCopy(*(q->str_value), value);
1992 break;
1993
1994 case CONF_ENV:
1995 case CONF_ENV2:
1996
1997 if (StrAllocCopy(temp_name, name)) {
1998 if (tbl->type == CONF_ENV)
1999 LYLowerCase(temp_name);
2000 else
2001 LYUpperCase(temp_name);
2002
2003 if (LYGetEnv(temp_name) == 0) {
2004 #ifdef VMS
2005 Define_VMSLogical(temp_name, value);
2006 #else
2007 if (q->str_value == 0) {
2008 q->str_value = typecalloc(char *);
2009
2010 if (q->str_value == 0)
2011 outofmem(__FILE__, "LYSetConfigValue");
2012 }
2013
2014 HTSprintf0(q->str_value, "%s=%s", temp_name, value);
2015 putenv(*(q->str_value));
2016 #endif
2017 }
2018 FREE(temp_name);
2019 }
2020 break;
2021 case CONF_ADD_ITEM:
2022 if (q->add_value != 0)
2023 add_item_to_list(value,
2024 q->add_value,
2025 (q->add_value == &printers),
2026 FALSE);
2027 break;
2028
2029 case CONF_ADD_STRING:
2030 if (*(q->lst_value) == NULL) {
2031 *(q->lst_value) = HTList_new();
2032 }
2033 temp_value = NULL;
2034 StrAllocCopy(temp_value, value);
2035 HTList_appendObject(*(q->lst_value), temp_value);
2036 temp_value = NULL;
2037 break;
2038
2039 #if defined(EXEC_LINKS) || defined(LYNXCGI_LINKS)
2040 case CONF_ADD_TRUSTED:
2041 add_trusted(value, (int) q->def_value);
2042 break;
2043 #endif
2044
2045 case CONF_PRG:
2046 if (isEmpty(value)) {
2047 HTSetProgramPath((ProgramPaths) (q->def_value), NULL);
2048 } else if (StrAllocCopy(temp_value, value)) {
2049 HTSetProgramPath((ProgramPaths) (q->def_value), temp_value);
2050 }
2051 break;
2052
2053 default:
2054 changed = FALSE;
2055 break;
2056 }
2057 FREE(value);
2058
2059 return changed;
2060 }
2061
2062 /*
2063 * Process the configuration file (lynx.cfg).
2064 *
2065 * 'allowed' is a pointer to HTList of allowed options. Since the included
2066 * file can also include other files with a list of acceptable options, these
2067 * lists are ANDed.
2068 */
do_read_cfg(const char * cfg_filename,const char * parent_filename,int nesting_level,FILE * fp0,optidx_set_t * allowed)2069 static void do_read_cfg(const char *cfg_filename,
2070 const char *parent_filename,
2071 int nesting_level,
2072 FILE *fp0,
2073 optidx_set_t *allowed)
2074 {
2075 FILE *fp;
2076 char *buffer = 0;
2077
2078 CTRACE((tfp, "Loading cfg file '%s'.\n", cfg_filename));
2079
2080 /*
2081 * Don't get hung up by an include file loop. Arbitrary max depth
2082 * of 10. - BL
2083 */
2084 if (nesting_level > 10) {
2085 fprintf(stderr,
2086 gettext("More than %d nested lynx.cfg includes -- perhaps there is a loop?!?\n"),
2087 nesting_level - 1);
2088 fprintf(stderr, gettext("Last attempted include was '%s',\n"), cfg_filename);
2089 fprintf(stderr, gettext("included from '%s'.\n"), parent_filename);
2090 exit_immediately(EXIT_FAILURE);
2091 }
2092 /*
2093 * Locate and open the file.
2094 */
2095 if (!cfg_filename || strlen(cfg_filename) == 0) {
2096 CTRACE((tfp, "No filename following -cfg switch!\n"));
2097 return;
2098 }
2099 if ((fp = LYOpenCFG(cfg_filename, parent_filename, LYNX_CFG_FILE)) == 0) {
2100 CTRACE((tfp, "lynx.cfg file not found as '%s'\n", cfg_filename));
2101 return;
2102 }
2103 have_read_cfg = TRUE;
2104
2105 /*
2106 * Process each line in the file.
2107 */
2108 if (show_cfg) {
2109 time_t t;
2110
2111 time(&t);
2112 printf("### %s %s, at %s", LYNX_NAME, LYNX_VERSION, ctime(&t));
2113 }
2114 while (LYSafeGets(&buffer, fp) != 0) {
2115 char *name, *value;
2116 char *cp;
2117 Config_Type *tbl;
2118
2119 /* Most lines in the config file are comment lines. Weed them out
2120 * now. Also, leading whitespace is ok, so trim it.
2121 */
2122 name = LYSkipBlanks(buffer);
2123
2124 if (ispunct(UCH(*name)))
2125 continue;
2126
2127 LYTrimTrailing(name);
2128
2129 if (*name == 0)
2130 continue;
2131
2132 /* Significant lines are of the form KEYWORD:WHATEVER */
2133 if ((value = StrChr(name, ':')) == 0) {
2134 /* fprintf (stderr, "Bad line-- no :\n"); */
2135 CTRACE((tfp, "LYReadCFG: missing ':' %s\n", name));
2136 continue;
2137 }
2138
2139 /* skip past colon, but replace ':' with 0 to make name meaningful */
2140 *value++ = 0;
2141
2142 /*
2143 * Trim off any trailing comments.
2144 *
2145 * (Apparently, the original code considers a trailing comment valid
2146 * only if preceded by a space character but is not followed by a
2147 * colon. -- JED)
2148 */
2149 if ((cp = strrchr(value, ':')) == 0)
2150 cp = value;
2151 if ((cp = StrChr(cp, '#')) != 0) {
2152 cp--;
2153 if (isspace(UCH(*cp)))
2154 *cp = 0;
2155 }
2156
2157 CTRACE2(TRACE_CFG, (tfp, "LYReadCFG %s:%s\n", name, value));
2158 tbl = lookup_config(name);
2159 if (tbl->name == 0) {
2160 /* lynx ignores unknown keywords */
2161 CTRACE((tfp, "LYReadCFG: ignored %s:%s\n", name, value));
2162 continue;
2163 }
2164 if (show_cfg)
2165 printf("%s:%s\n", name, value);
2166
2167 if (allowed && (*allowed)[tbl - Config_Table]) {
2168 if (fp0 == NULL)
2169 fprintf(stderr, "%s is not allowed in the %s\n",
2170 name, cfg_filename);
2171 /*FIXME: we can do something wiser if we are generating
2172 the html representation of lynx.cfg - say include this line
2173 in bold, or something... */
2174
2175 continue;
2176 }
2177
2178 (void) ParseUnionOf(tbl);
2179 switch ((fp0 != 0 && tbl->type != CONF_INCLUDE)
2180 ? CONF_NIL
2181 : tbl->type) {
2182 case CONF_BOOL:
2183 case CONF_FUN:
2184 case CONF_TIME:
2185 case CONF_ENUM:
2186 case CONF_INT:
2187 case CONF_STR:
2188 case CONF_ENV:
2189 case CONF_ENV2:
2190 case CONF_PRG:
2191 case CONF_ADD_ITEM:
2192 case CONF_ADD_STRING:
2193 case CONF_ADD_TRUSTED:
2194 LYSetConfigValue(name, value);
2195 break;
2196
2197 case CONF_INCLUDE:{
2198 /* include another file */
2199 optidx_set_t cur_set, anded_set;
2200 optidx_set_t *resultant_set = NULL;
2201 char *p1, *p2, savechar;
2202 BOOL any_optname_found = FALSE;
2203
2204 char *url = NULL;
2205 char *cp1 = NULL;
2206 const char *sep = NULL;
2207
2208 if ((p1 = strstr(value, sep = " for ")) != 0
2209 #if defined(UNIX) && !defined(USE_DOS_DRIVES)
2210 || (p1 = strstr(value, sep = ":")) != 0
2211 #endif
2212 ) {
2213 *p1 = '\0';
2214 p1 += strlen(sep);
2215 }
2216 #ifndef NO_CONFIG_INFO
2217 if (fp0 != 0 && !no_lynxcfg_xinfo) {
2218 char *my_file = actual_filename(value, cfg_filename, LYNX_CFG_FILE);
2219
2220 LYLocalFileToURL(&url, my_file);
2221 FREE(my_file);
2222 StrAllocCopy(cp1, value);
2223 if (StrChr(value, '&') || StrChr(value, '<')) {
2224 LYEntify(&cp1, TRUE);
2225 }
2226
2227 fprintf(fp0, "%s:<a href=\"%s\">%s</a>\n\n", name, url, cp1);
2228 fprintf(fp0, " #<begin %s>\n", cp1);
2229 }
2230 #endif
2231
2232 if (p1) {
2233 while (*(p1 = LYSkipBlanks(p1)) != 0) {
2234 Config_Type *tbl2;
2235
2236 p2 = LYSkipNonBlanks(p1);
2237 savechar = *p2;
2238 *p2 = 0;
2239
2240 tbl2 = lookup_config(p1);
2241 if (tbl2->name == 0) {
2242 if (fp0 == NULL)
2243 fprintf(stderr,
2244 "unknown option name %s in %s\n",
2245 p1, cfg_filename);
2246 } else {
2247 unsigned i;
2248
2249 if (!any_optname_found) {
2250 any_optname_found = TRUE;
2251 for (i = 0; i < NOPTS_; ++i)
2252 cur_set[i] = TRUE;
2253 }
2254 cur_set[tbl2 - Config_Table] = FALSE;
2255 }
2256 if (savechar && p2[1])
2257 p1 = p2 + 1;
2258 else
2259 break;
2260 }
2261 }
2262 if (!allowed) {
2263 if (!any_optname_found)
2264 resultant_set = NULL;
2265 else
2266 resultant_set = &cur_set;
2267 } else {
2268 if (!any_optname_found)
2269 resultant_set = allowed;
2270 else {
2271 optidx_set_AND(anded_set, *allowed, cur_set);
2272 resultant_set = &anded_set;
2273 }
2274 }
2275
2276 #ifndef NO_CONFIG_INFO
2277 /*
2278 * Now list the opts that are allowed in included file. If all
2279 * opts are allowed, then emit nothing, else emit an effective set
2280 * of allowed options in <ul>. Option names will be uppercased.
2281 * FIXME: uppercasing option names can be considered redundant.
2282 */
2283 if (fp0 != 0 && !no_lynxcfg_xinfo && resultant_set) {
2284 char *buf = NULL;
2285 unsigned i;
2286
2287 fprintf(fp0, " Options allowed in this file:\n");
2288 for (i = 0; i < NOPTS_; ++i) {
2289 if ((*resultant_set)[i])
2290 continue;
2291 StrAllocCopy(buf, Config_Table[i].name);
2292 LYUpperCase(buf);
2293 fprintf(fp0, " * %s\n", buf);
2294 }
2295 FREE(buf);
2296 }
2297 #endif
2298 do_read_cfg(value, cfg_filename, nesting_level + 1, fp0, resultant_set);
2299
2300 #ifndef NO_CONFIG_INFO
2301 if (fp0 != 0 && !no_lynxcfg_xinfo) {
2302 fprintf(fp0, " #<end of %s>\n\n", cp1);
2303 FREE(url);
2304 FREE(cp1);
2305 }
2306 #endif
2307 }
2308 break;
2309
2310 default:
2311 if (fp0 != 0) {
2312 if (StrChr(value, '&') || StrChr(value, '<')) {
2313 char *cp1 = NULL;
2314
2315 StrAllocCopy(cp1, value);
2316 LYEntify(&cp1, TRUE);
2317 fprintf(fp0, "%s:%s\n", name, cp1);
2318 FREE(cp1);
2319 } else {
2320 fprintf(fp0, "%s:%s\n", name, value);
2321 }
2322 }
2323 break;
2324 }
2325 }
2326
2327 LYCloseInput(fp);
2328
2329 /*
2330 * If any DOWNLOADER: commands have always_enabled set (:TRUE), make
2331 * override_no_download TRUE, so that other restriction settings will not
2332 * block presentation of a download menu with those always_enabled options
2333 * still available. - FM
2334 */
2335 if (downloaders != 0) {
2336 lynx_list_item_type *cur_download;
2337
2338 cur_download = downloaders;
2339 while (cur_download != 0) {
2340 if (cur_download->always_enabled) {
2341 override_no_download = TRUE;
2342 break;
2343 }
2344 cur_download = cur_download->next;
2345 }
2346 }
2347
2348 /*
2349 * If any COOKIE_{ACCEPT,REJECT}_DOMAINS have been defined,
2350 * process them. These are comma delimited lists of
2351 * domains. - BJP
2352 *
2353 * And for query/strict/loose invalid cookie checking. - BJP
2354 */
2355 LYConfigCookies();
2356
2357 /*
2358 * Do not allow infinite redirection loops.
2359 */
2360 if (redirection_limit < 5)
2361 redirection_limit = 5;
2362 if (redirection_limit > 25)
2363 redirection_limit = 25;
2364 }
2365
2366 /* this is a public interface to do_read_cfg */
read_cfg(const char * cfg_filename,const char * parent_filename,int nesting_level,FILE * fp0)2367 void read_cfg(const char *cfg_filename,
2368 const char *parent_filename,
2369 int nesting_level,
2370 FILE *fp0)
2371 {
2372 HTInitProgramPaths(TRUE);
2373 do_read_cfg(cfg_filename, parent_filename, nesting_level, fp0, NULL);
2374 }
2375
2376 #ifndef NO_CONFIG_INFO
extra_cfg_link(FILE * fp,const char * href,const char * name)2377 static void extra_cfg_link(FILE *fp, const char *href,
2378 const char *name)
2379 {
2380 fprintf(fp, "<a href=\"%s\">%s</a>",
2381 href, name);
2382 }
2383 #endif /* NO_CONFIG_INFO */
2384
2385 /*
2386 * Show rendered lynx.cfg data without comments, LYNXCFG:/ internal page.
2387 * Called from getfile() cycle: we create and load the page just in place and
2388 * return to mainloop().
2389 */
lynx_cfg_infopage(DocInfo * newdoc)2390 int lynx_cfg_infopage(DocInfo *newdoc)
2391 {
2392 static char tempfile[LY_MAXPATH] = "\0";
2393 DocAddress WWWDoc; /* need on exit */
2394 char *temp = 0;
2395 char *cp1 = NULL;
2396 FILE *fp0;
2397
2398 #ifndef NO_CONFIG_INFO
2399 /*-------------------------------------------------
2400 * kludge a link from LYNXCFG:/, the URL was:
2401 * " <a href=\"LYNXCFG://reload\">RELOAD THE CHANGES</a>\n"
2402 *--------------------------------------------------*/
2403
2404 if (!no_lynxcfg_xinfo && (strstr(newdoc->address, "LYNXCFG://reload"))) {
2405 /*
2406 * Some stuff to reload read_cfg(), but also load options menu items
2407 * and command-line options to make things consistent. Implemented in
2408 * LYMain.c
2409 */
2410 reload_read_cfg();
2411
2412 /*
2413 * now pop-up and return to updated LYNXCFG:/ page, remind
2414 * postoptions() but much simpler:
2415 */
2416 /*
2417 * But check whether the top history document is really the expected
2418 * LYNXCFG: page. - kw
2419 */
2420 if (HTMainText && nhist > 0 &&
2421 !strcmp(HTLoadedDocumentTitle(), LYNXCFG_TITLE) &&
2422 !strcmp(HTLoadedDocumentURL(), HDOC(nhist - 1).address) &&
2423 LYIsUIPage(HDOC(nhist - 1).address, UIP_LYNXCFG) &&
2424 (!lynxcfginfo_url ||
2425 strcmp(HTLoadedDocumentURL(), lynxcfginfo_url))) {
2426 /* the page was pushed, so pop-up. */
2427 LYpop(newdoc);
2428 WWWDoc.address = newdoc->address;
2429 WWWDoc.post_data = newdoc->post_data;
2430 WWWDoc.post_content_type = newdoc->post_content_type;
2431 WWWDoc.bookmark = newdoc->bookmark;
2432 WWWDoc.isHEAD = newdoc->isHEAD;
2433 WWWDoc.safe = newdoc->safe;
2434 LYforce_no_cache = FALSE; /* ! */
2435 LYoverride_no_cache = TRUE; /* ! */
2436
2437 /*
2438 * Working out of getfile() cycle we reset *no_cache manually here
2439 * so HTLoadAbsolute() will return "Document already in memory":
2440 * it was forced reloading obsolete file again without this
2441 * (overhead).
2442 *
2443 * Probably *no_cache was set in a wrong position because of the
2444 * internal page...
2445 */
2446 if (!HTLoadAbsolute(&WWWDoc))
2447 return (NOT_FOUND);
2448
2449 HTuncache_current_document(); /* will never use again */
2450 LYUnRegisterUIPage(UIP_LYNXCFG);
2451 }
2452
2453 /* now set up the flag and fall down to create a new LYNXCFG:/ page */
2454 FREE(lynxcfginfo_url); /* see below */
2455 }
2456 #endif /* !NO_CONFIG_INFO */
2457
2458 /*
2459 * We regenerate the file if reloading has been requested (with LYK_NOCACHE
2460 * key). If we did not regenerate, there would be no way to recover in a
2461 * session from a situation where the file is corrupted (for example
2462 * truncated because the file system was full when it was first created -
2463 * lynx doesn't check for write errors below), short of manual complete
2464 * removal or perhaps forcing regeneration with LYNXCFG://reload.
2465 * Similarly, there would be no simple way to get a different page if
2466 * user_mode has changed to Advanced after the file was first generated in
2467 * a non-Advanced mode (the difference being in whether the page includes
2468 * the link to LYNXCFG://reload or not).
2469 *
2470 * We also try to regenerate the file if lynxcfginfo_url is set, indicating
2471 * that tempfile is valid, but the file has disappeared anyway. This can
2472 * happen to a long-lived lynx process if for example some system script
2473 * periodically cleans up old files in the temp file space. - kw
2474 */
2475
2476 if (LYforce_no_cache && reloading) {
2477 FREE(lynxcfginfo_url); /* flag to code below to regenerate - kw */
2478 } else if (lynxcfginfo_url != NULL) {
2479 if (!LYCanReadFile(tempfile)) { /* check existence */
2480 FREE(lynxcfginfo_url); /* flag to code below to try again - kw */
2481 }
2482 }
2483 if (lynxcfginfo_url == 0) {
2484
2485 if ((fp0 = InternalPageFP(tempfile, TRUE)) == 0)
2486 return (NOT_FOUND);
2487
2488 LYLocalFileToURL(&lynxcfginfo_url, tempfile);
2489
2490 LYforce_no_cache = TRUE; /* don't cache this doc */
2491
2492 BeginInternalPage(fp0, LYNXCFG_TITLE, NULL);
2493 fprintf(fp0, "<pre>\n");
2494
2495 #ifndef NO_CONFIG_INFO
2496 if (!no_lynxcfg_xinfo) {
2497 #if defined(HAVE_CONFIG_H) || defined(VMS)
2498 if (strcmp(lynx_cfg_file, LYNX_CFG_FILE)) {
2499 fprintf(fp0, "<em>%s\n%s",
2500 gettext("The following is read from your lynx.cfg file."),
2501 gettext("Please read the distribution"));
2502 LYLocalFileToURL(&temp, LYNX_CFG_FILE);
2503 fprintf(fp0, " <a href=\"%s\">lynx.cfg</a> ",
2504 temp);
2505 FREE(temp);
2506 fprintf(fp0, "%s</em>\n\n",
2507 gettext("for more comments."));
2508 } else
2509 #endif /* HAVE_CONFIG_H */
2510 {
2511 /* no absolute path... for lynx.cfg on DOS/Win32 */
2512 fprintf(fp0, "<em>%s\n%s",
2513 gettext("The following is read from your lynx.cfg file."),
2514 gettext("Please read the distribution"));
2515 fprintf(fp0, " </em>lynx.cfg<em> ");
2516 fprintf(fp0, "%s</em>\n",
2517 gettext("for more comments."));
2518 }
2519
2520 #ifndef NO_CONFIG_INFO
2521 #if defined(HAVE_CONFIG_H) && defined(USE_COLOR_STYLE)
2522 if (!no_compileopts_info && !no_lynxcfg_xinfo) {
2523 fprintf(fp0, "%s</pre><ul><li>", SEE_ALSO);
2524 extra_cfg_link(fp0, STR_LYNXCFLAGS, COMPILE_OPT_SEGMENT);
2525
2526 fprintf(fp0, "<li>");
2527 LYLocalFileToURL(&temp, lynx_lss_file);
2528 extra_cfg_link(fp0, temp, COLOR_STYLE_SEGMENT);
2529 fprintf(fp0, "</ul><pre>\n");
2530 } else
2531 #endif
2532 {
2533 fprintf(fp0, "%s ", SEE_ALSO);
2534 #if defined(HAVE_CONFIG_H)
2535 if (!no_compileopts_info) {
2536 extra_cfg_link(fp0, STR_LYNXCFLAGS, COMPILE_OPT_SEGMENT);
2537 }
2538 #endif
2539 #if defined(USE_COLOR_STYLE)
2540 if (!no_lynxcfg_xinfo) {
2541 LYLocalFileToURL(&temp, lynx_lss_file);
2542 extra_cfg_link(fp0, temp, COLOR_STYLE_SEGMENT);
2543 }
2544 #endif
2545 fprintf(fp0, "\n\n");
2546 }
2547 #endif /* NO_CONFIG_INFO */
2548
2549 /** a new experimental link ... **/
2550 if (user_mode == ADVANCED_MODE)
2551 fprintf(fp0, " <a href=\"%s//reload\">%s</a>\n",
2552 STR_LYNXCFG,
2553 gettext("RELOAD THE CHANGES"));
2554
2555 LYLocalFileToURL(&temp, lynx_cfg_file);
2556 StrAllocCopy(cp1, lynx_cfg_file);
2557 if (StrChr(lynx_cfg_file, '&') || StrChr(lynx_cfg_file, '<')) {
2558 LYEntify(&cp1, TRUE);
2559 }
2560 fprintf(fp0, "\n #<em>%s <a href=\"%s\">%s</a></em>\n",
2561 gettext("Your primary configuration"),
2562 temp,
2563 cp1);
2564 FREE(temp);
2565 FREE(cp1);
2566
2567 } else
2568 #endif /* !NO_CONFIG_INFO */
2569
2570 fprintf(fp0, "<em>%s</em>\n\n",
2571 gettext("The following is read from your lynx.cfg file."));
2572
2573 /*
2574 * Process the configuration file.
2575 */
2576 read_cfg(lynx_cfg_file, "main program", 1, fp0);
2577
2578 fprintf(fp0, "</pre>\n");
2579 EndInternalPage(fp0);
2580 LYCloseTempFP(fp0);
2581 LYRegisterUIPage(lynxcfginfo_url, UIP_LYNXCFG);
2582 }
2583
2584 /* return to getfile() cycle */
2585 StrAllocCopy(newdoc->address, lynxcfginfo_url);
2586 WWWDoc.address = newdoc->address;
2587 WWWDoc.post_data = newdoc->post_data;
2588 WWWDoc.post_content_type = newdoc->post_content_type;
2589 WWWDoc.bookmark = newdoc->bookmark;
2590 WWWDoc.isHEAD = newdoc->isHEAD;
2591 WWWDoc.safe = newdoc->safe;
2592
2593 if (!HTLoadAbsolute(&WWWDoc))
2594 return (NOT_FOUND);
2595 #ifdef DIRED_SUPPORT
2596 lynx_edit_mode = FALSE;
2597 #endif /* DIRED_SUPPORT */
2598 return (NORMAL);
2599 }
2600
2601 #if defined(HAVE_CONFIG_H) && !defined(NO_CONFIG_INFO)
2602 /*
2603 * Compile-time definitions info, LYNXCOMPILEOPTS:/ internal page, from
2604 * getfile() cycle.
2605 */
lynx_compile_opts(DocInfo * newdoc)2606 int lynx_compile_opts(DocInfo *newdoc)
2607 {
2608 static char tempfile[LY_MAXPATH] = "\0";
2609
2610 #define PutDefs(table, N) fprintf(fp0, "%-35s %s\n", table[N].name, table[N].value)
2611 #include <cfg_defs.h>
2612 unsigned n;
2613 DocAddress WWWDoc; /* need on exit */
2614 FILE *fp0;
2615
2616 /* In general, create the page only once - compile-time data will not
2617 * change... But we will regenerate the file anyway, in a few situations:
2618 *
2619 * (a) configinfo_url has been FREEd - this can happen if free_lynx_cfg()
2620 * was called as part of a LYNXCFG://reload action.
2621 *
2622 * (b) reloading has been requested (with LYK_NOCACHE key). If we did not
2623 * regenerate, there would be no way to recover in a session from a
2624 * situation where the file is corrupted (for example truncated because the
2625 * file system was full when it was first created - lynx doesn't check for
2626 * write errors below), short of manual complete removal or forcing
2627 * regeneration with LYNXCFG://reload.
2628 *
2629 * (c) configinfo_url is set, indicating that tempfile is valid, but the
2630 * file has disappeared anyway. This can happen to a long-lived lynx
2631 * process if for example some system script periodically cleans up old
2632 * files in the temp file space. - kw
2633 */
2634
2635 if (LYforce_no_cache && reloading) {
2636 FREE(configinfo_url); /* flag to code below to regenerate - kw */
2637 } else if (configinfo_url != NULL) {
2638 if (!LYCanReadFile(tempfile)) { /* check existence */
2639 FREE(configinfo_url); /* flag to code below to try again - kw */
2640 }
2641 }
2642 if (configinfo_url == NULL) {
2643 if ((fp0 = InternalPageFP(tempfile, TRUE)) == 0)
2644 return (NOT_FOUND);
2645
2646 LYLocalFileToURL(&configinfo_url, tempfile);
2647
2648 BeginInternalPage(fp0, CONFIG_DEF_TITLE, NULL);
2649 fprintf(fp0, "<pre>\n");
2650
2651 fprintf(fp0, "\n%s<br>\n<em>config.cache</em>\n", AUTOCONF_CONFIG_CACHE);
2652 for (n = 0; n < TABLESIZE(config_cache); n++) {
2653 PutDefs(config_cache, n);
2654 }
2655 fprintf(fp0, "\n%s<br>\n<em>lynx_cfg.h</em>\n", AUTOCONF_LYNXCFG_H);
2656 for (n = 0; n < TABLESIZE(config_defines); n++) {
2657 PutDefs(config_defines, n);
2658 }
2659 fprintf(fp0, "</pre>\n");
2660 EndInternalPage(fp0);
2661 LYCloseTempFP(fp0);
2662 LYRegisterUIPage(configinfo_url, UIP_CONFIG_DEF);
2663 }
2664
2665 /* exit to getfile() cycle */
2666 StrAllocCopy(newdoc->address, configinfo_url);
2667 WWWDoc.address = newdoc->address;
2668 WWWDoc.post_data = newdoc->post_data;
2669 WWWDoc.post_content_type = newdoc->post_content_type;
2670 WWWDoc.bookmark = newdoc->bookmark;
2671 WWWDoc.isHEAD = newdoc->isHEAD;
2672 WWWDoc.safe = newdoc->safe;
2673
2674 if (!HTLoadAbsolute(&WWWDoc))
2675 return (NOT_FOUND);
2676 #ifdef DIRED_SUPPORT
2677 lynx_edit_mode = FALSE;
2678 #endif /* DIRED_SUPPORT */
2679 return (NORMAL);
2680 }
2681 #endif /* !NO_CONFIG_INFO */
2682