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