1 /* $LynxId: LYrcFile.c,v 1.90 2012/11/14 01:06:06 tom Exp $ */
2 #include <HTUtils.h>
3 #include <HTFTP.h>
4 #include <LYUtils.h>
5 #include <LYrcFile.h>
6 #include <LYStrings.h>
7 #include <LYGlobalDefs.h>
8 #include <LYCharSets.h>
9 #include <LYBookmark.h>
10 #include <LYCookie.h>
11 #include <LYKeymap.h>
12 #include <HTMLDTD.h>
13
14 #include <LYLeaks.h>
15
16 #define MSG_ENABLE_LYNXRC N_("Normally disabled. See ENABLE_LYNXRC in lynx.cfg\n")
17 #define putBool(value) ((value) ? "on" : "off")
18 /* *INDENT-OFF* */
19 static Config_Enum tbl_DTD_recovery[] = {
20 { "true", TRUE },
21 { "false", FALSE },
22 { "on", TRUE },
23 { "off", FALSE },
24 { "sortasgml", TRUE },
25 { "tagsoup", FALSE },
26 { NULL, -1 },
27 };
28
29 static Config_Enum tbl_bad_html[] = {
30 { "ignore", BAD_HTML_IGNORE },
31 { "trace", BAD_HTML_TRACE },
32 { "message", BAD_HTML_MESSAGE },
33 { "warn", BAD_HTML_WARN },
34 { NULL, -1 }
35 };
36
37 #ifdef DIRED_SUPPORT
38 static Config_Enum tbl_dir_list_style[] = {
39 { "FILES_FIRST", FILES_FIRST },
40 { "DIRECTORIES_FIRST", DIRS_FIRST },
41 { "MIXED_STYLE", MIXED_STYLE },
42 { NULL, MIXED_STYLE },
43 };
44 #ifdef LONG_LIST
45 static Config_Enum tbl_dir_list_order[] = {
46 { "ORDER_BY_NAME", ORDER_BY_NAME },
47 { "ORDER_BY_TYPE", ORDER_BY_TYPE },
48 { "ORDER_BY_SIZE", ORDER_BY_SIZE },
49 { "ORDER_BY_DATE", ORDER_BY_DATE },
50 { "ORDER_BY_MODE", ORDER_BY_MODE },
51 #ifndef NO_GROUPS
52 { "ORDER_BY_USER", ORDER_BY_USER },
53 { "ORDER_BY_GROUP", ORDER_BY_GROUP },
54 #endif
55 { NULL, ORDER_BY_NAME },
56 };
57 #endif /* LONG_LIST */
58 #endif /* DIRED_SUPPORT */
59
60 static Config_Enum tbl_file_sort[] = {
61 { "BY_FILENAME", FILE_BY_NAME },
62 { "BY_TYPE", FILE_BY_TYPE },
63 { "BY_SIZE", FILE_BY_SIZE },
64 { "BY_DATE", FILE_BY_DATE },
65 { NULL, -1 },
66 };
67
68 Config_Enum tbl_keypad_mode[] = {
69 { "FIELDS_ARE_NUMBERED", FIELDS_ARE_NUMBERED },
70 { "LINKS_AND_FIELDS_ARE_NUMBERED", LINKS_AND_FIELDS_ARE_NUMBERED },
71 { "LINKS_ARE_NUMBERED", LINKS_ARE_NUMBERED },
72 { "LINKS_ARE_NOT_NUMBERED", NUMBERS_AS_ARROWS },
73 /* obsolete variations: */
74 { "LINKS_AND_FORM_FIELDS_ARE_NUMBERED", LINKS_AND_FIELDS_ARE_NUMBERED },
75 { "NUMBERS_AS_ARROWS", NUMBERS_AS_ARROWS },
76 { NULL, DEFAULT_KEYPAD_MODE }
77 };
78
79 Config_Enum tbl_multi_bookmarks[] = {
80 { "OFF", MBM_OFF },
81 { "STANDARD", MBM_STANDARD },
82 { "ON", MBM_STANDARD },
83 { "ADVANCED", MBM_ADVANCED },
84 { NULL, -1 }
85 };
86
87 /* the names in this table are used as lowercase in HTTP.c */
88 Config_Enum tbl_preferred_encoding[] = {
89 { "none", encodingNONE },
90 #if defined(USE_ZLIB) || defined(GZIP_PATH)
91 { "gzip", encodingGZIP },
92 { "deflate", encodingDEFLATE },
93 #endif
94 #if defined(USE_ZLIB) || defined(COMPRESS_PATH)
95 { "compress", encodingCOMPRESS },
96 #endif
97 #if defined(USE_BZLIB) || defined(BZIP2_PATH)
98 { "bzip2", encodingBZIP2 },
99 #endif
100 { "all", encodingALL },
101 { NULL, -1 }
102 };
103
104 Config_Enum tbl_preferred_media[] = {
105 { "INTERNAL", mediaOpt1 },
106 { "CONFIGFILE", mediaOpt2 },
107 { "USER", mediaOpt3 },
108 { "SYSTEM", mediaOpt4 },
109 { "ALL", mediaALL },
110 { NULL, -1 }
111 };
112
113 static Config_Enum tbl_show_colors[] = {
114 { "default", SHOW_COLOR_UNKNOWN },
115 { "default", SHOW_COLOR_OFF },
116 { "default", SHOW_COLOR_ON },
117 { "on", SHOW_COLOR_UNKNOWN },
118 { "off", SHOW_COLOR_UNKNOWN },
119 { "never", SHOW_COLOR_NEVER },
120 { "always", SHOW_COLOR_ALWAYS },
121 { NULL, SHOW_COLOR_UNKNOWN }
122 };
123
124 Config_Enum tbl_transfer_rate[] = {
125 { "NONE", rateOFF },
126 { "KB", rateKB },
127 { "TRUE", rateKB },
128 { "BYTES", rateBYTES },
129 { "FALSE", rateBYTES },
130 #ifdef USE_READPROGRESS
131 { "KB,ETA", rateEtaKB },
132 { "BYTES,ETA", rateEtaBYTES },
133 { "KB2,ETA", rateEtaKB2 },
134 { "BYTES2,ETA", rateEtaBYTES2 },
135 #endif
136 #ifdef USE_PROGRESSBAR
137 { "METER", rateBAR },
138 { "FALSE", rateBAR },
139 #endif
140 { NULL, -1 },
141 };
142
143 Config_Enum tbl_user_mode[] = {
144 { "ADVANCED", ADVANCED_MODE },
145 { "INTERMEDIATE", INTERMEDIATE_MODE },
146 { "NOVICE", NOVICE_MODE },
147 { NULL, NOVICE_MODE }
148 };
149
150 static Config_Enum tbl_visited_links[] = {
151 { "FIRST_REVERSED", VISITED_LINKS_AS_FIRST_V | VISITED_LINKS_REVERSE },
152 { "FIRST", VISITED_LINKS_AS_FIRST_V },
153 { "TREE", VISITED_LINKS_AS_TREE },
154 { "LAST_REVERSED", VISITED_LINKS_AS_LATEST | VISITED_LINKS_REVERSE },
155 { "LAST", VISITED_LINKS_AS_LATEST },
156 { NULL, DEFAULT_VISITED_LINKS }
157 };
158
159 Config_Enum tbl_force_prompt[] = {
160 { "prompt", FORCE_PROMPT_DFT },
161 { "yes", FORCE_PROMPT_YES },
162 { "no", FORCE_PROMPT_NO },
163 { NULL, -1 }
164 };
165 /* *INDENT-ON* */
166
getBool(char * src)167 static BOOL getBool(char *src)
168 {
169 return (BOOL) (!strncasecomp(src, "on", 2) || !strncasecomp(src, "true", 4));
170 }
171
LYputEnum(Config_Enum * table,int value)172 const char *LYputEnum(Config_Enum * table, int value)
173 {
174 while (table->name != 0) {
175 if (table->value == value) {
176 return table->name;
177 }
178 table++;
179 }
180 return "?";
181 }
182
LYgetEnum(Config_Enum * table,const char * name,int * result)183 BOOL LYgetEnum(Config_Enum * table, const char *name,
184 int *result)
185 {
186 Config_Enum *found = 0;
187 unsigned len = (unsigned) strlen(name);
188 int match = 0;
189
190 if (len != 0) {
191 while (table->name != 0) {
192 if (!strncasecomp(table->name, name, (int) len)) {
193 found = table;
194 if (!strcasecomp(table->name, name)) {
195 match = 1;
196 break;
197 }
198 ++match;
199 }
200 table++;
201 }
202 if (match == 1) { /* if unambiguous */
203 *result = found->value;
204 return TRUE;
205 }
206 }
207 return FALSE; /* no match */
208 }
209
210 /* these are for data that are normally not read/written from .lynxrc */
211 #define PARSE_SET(n,v,h) {n, 1, CONF_BOOL, UNION_SET(v), 0, 0, 0, h}
212 #define PARSE_ARY(n,v,t,h) {n, 1, CONF_ARRAY, UNION_INT(v), t, 0, 0, h}
213 #define PARSE_ENU(n,v,t,h) {n, 1, CONF_ENUM, UNION_INT(v), 0, t, 0, h}
214 #define PARSE_LIS(n,v,h) {n, 1, CONF_LIS, UNION_STR(v), 0, 0, 0, h}
215 #define PARSE_STR(n,v,h) {n, 1, CONF_STR, UNION_STR(v), 0, 0, 0, h}
216 #define PARSE_FUN(n,v,w,h) {n, 1, CONF_FUN, UNION_FUN(v), 0, 0, w, h}
217 #define PARSE_MBM(n,h) {n, 1, CONF_MBM, UNION_DEF(0), 0, 0, 0, h}
218
219 /* these are for data that are optionally read/written from .lynxrc */
220 #define MAYBE_SET(n,v,h) {n, 0, CONF_BOOL, UNION_SET(v), 0, 0, 0, h}
221 #define MAYBE_ARY(n,v,t,h) {n, 0, CONF_ARRAY, UNION_INT(v), t, 0, 0, h}
222 #define MAYBE_ENU(n,v,t,h) {n, 0, CONF_ENUM, UNION_INT(v), 0, t, 0, h}
223 #define MAYBE_LIS(n,v,h) {n, 0, CONF_LIS, UNION_STR(v), 0, 0, 0, h}
224 #define MAYBE_STR(n,v,h) {n, 0, CONF_STR, UNION_STR(v), 0, 0, 0, h}
225 #define MAYBE_FUN(n,v,w,h) {n, 0, CONF_FUN, UNION_FUN(v), 0, 0, w, h}
226 #define MAYBE_MBM(n,h) {n, 0, CONF_MBM, UNION_DEF(0), 0, 0, 0, h}
227
228 #define PARSE_NIL {NULL, 1, CONF_NIL, UNION_DEF(0), 0, 0, 0, 0}
229
230 typedef enum {
231 CONF_NIL = 0
232 ,CONF_ARRAY
233 ,CONF_BOOL
234 ,CONF_FUN
235 ,CONF_INT
236 ,CONF_ENUM
237 ,CONF_LIS
238 ,CONF_MBM
239 ,CONF_STR
240 } Conf_Types;
241
242 typedef struct config_type {
243 const char *name;
244 int enabled; /* see lynx.cfg ENABLE_LYNXRC "off" lines */
245 Conf_Types type;
246 ParseData;
247 const char **strings;
248 Config_Enum *table;
249 void (*write_it) (FILE *fp, struct config_type *);
250 const char *note;
251 } Config_Type;
252
get_assume_charset(char * value)253 static int get_assume_charset(char *value)
254 {
255 int i;
256
257 for (i = 0; i < LYNumCharsets; ++i) {
258 if (!strcasecomp(value, LYCharSet_UC[i].MIMEname)) {
259 UCLYhndl_for_unspec = i;
260 break;
261 }
262 }
263 return 0;
264 }
265
put_assume_charset(FILE * fp,struct config_type * tbl)266 static void put_assume_charset(FILE *fp, struct config_type *tbl)
267 {
268 int i;
269
270 for (i = 0; i < LYNumCharsets; ++i)
271 fprintf(fp, "# %s\n", LYCharSet_UC[i].MIMEname);
272 fprintf(fp, "%s=%s\n\n", tbl->name, LYCharSet_UC[UCLYhndl_for_unspec].MIMEname);
273 }
274
get_display_charset(char * value)275 static int get_display_charset(char *value)
276 {
277 int i = 0;
278
279 i = UCGetLYhndl_byAnyName(value); /* by MIME or full name */
280 if (i >= 0)
281 current_char_set = i;
282 return 0;
283 }
284
put_display_charset(FILE * fp,struct config_type * tbl)285 static void put_display_charset(FILE *fp, struct config_type *tbl)
286 {
287 int i;
288
289 for (i = 0; LYchar_set_names[i]; i++)
290 fprintf(fp, "# %s\n", LYchar_set_names[i]);
291 fprintf(fp, "%s=%s\n\n", tbl->name, LYchar_set_names[current_char_set]);
292 }
293
get_editor(char * value)294 static int get_editor(char *value)
295 {
296 if (!system_editor)
297 StrAllocCopy(editor, value);
298 return 0;
299 }
300
put_editor(FILE * fp,struct config_type * tbl)301 static void put_editor(FILE *fp, struct config_type *tbl)
302 {
303 fprintf(fp, "%s=%s\n\n", tbl->name, NonNull(editor));
304 }
305
get_tagsoup(char * value)306 int get_tagsoup(char *value)
307 {
308 int found = Old_DTD;
309
310 if (LYgetEnum(tbl_DTD_recovery, value, &found)
311 && Old_DTD != found) {
312 Old_DTD = found;
313 HTSwitchDTD(!Old_DTD);
314 }
315 return 0;
316 }
317
put_tagsoup(FILE * fp,struct config_type * tbl)318 static void put_tagsoup(FILE *fp, struct config_type *tbl)
319 {
320 fprintf(fp, "%s=%s\n\n", tbl->name, LYputEnum(tbl_DTD_recovery, Old_DTD));
321 }
322
323 /* This table is searched ignoring case */
324 /* *INDENT-OFF* */
325 static Config_Type Config_Table [] =
326 {
327 PARSE_SET(RC_ACCEPT_ALL_COOKIES, LYAcceptAllCookies, N_("\
328 accept_all_cookies allows the user to tell Lynx to automatically\n\
329 accept all cookies if desired. The default is \"FALSE\" which will\n\
330 prompt for each cookie. Set accept_all_cookies to \"TRUE\" to accept\n\
331 all cookies.\n\
332 ")),
333 MAYBE_FUN(RC_ASSUME_CHARSET, get_assume_charset, put_assume_charset, MSG_ENABLE_LYNXRC),
334 #ifndef DISABLE_FTP
335 PARSE_STR(RC_ANONFTP_PASSWORD, anonftp_password, N_("\
336 anonftp_password allows the user to tell Lynx to use the personal\n\
337 email address as the password for anonymous ftp. If no value is given,\n\
338 Lynx will use the personal email address. Set anonftp_password\n\
339 to a different value if you choose.\n\
340 ")),
341 #endif
342 MAYBE_ENU(RC_BAD_HTML, cfg_bad_html, tbl_bad_html,
343 MSG_ENABLE_LYNXRC),
344 PARSE_STR(RC_BOOKMARK_FILE, bookmark_page, N_("\
345 bookmark_file specifies the name and location of the default bookmark\n\
346 file into which the user can paste links for easy access at a later\n\
347 date.\n\
348 ")),
349 PARSE_SET(RC_CASE_SENSITIVE_SEARCHING, LYcase_sensitive, N_("\
350 If case_sensitive_searching is \"on\" then when the user invokes a search\n\
351 using the 's' or '/' keys, the search performed will be case sensitive\n\
352 instead of case INsensitive. The default is usually \"off\".\n\
353 ")),
354 PARSE_FUN(RC_CHARACTER_SET, get_display_charset, put_display_charset, N_("\
355 The character_set definition controls the representation of 8 bit\n\
356 characters for your terminal. If 8 bit characters do not show up\n\
357 correctly on your screen you may try changing to a different 8 bit\n\
358 set or using the 7 bit character approximations.\n\
359 Current valid characters sets are:\n\
360 ")),
361 PARSE_LIS(RC_COOKIE_ACCEPT_DOMAINS, LYCookieAcceptDomains, N_("\
362 cookie_accept_domains and cookie_reject_domains are comma-delimited\n\
363 lists of domains from which Lynx should automatically accept or reject\n\
364 all cookies. If a domain is specified in both options, rejection will\n\
365 take precedence. The accept_all_cookies parameter will override any\n\
366 settings made here.\n\
367 ")),
368 #ifdef USE_PERSISTENT_COOKIES
369 PARSE_STR(RC_COOKIE_FILE, LYCookieFile, N_("\
370 cookie_file specifies the file from which to read persistent cookies.\n\
371 The default is ~/" FNAME_LYNX_COOKIES ".\n\
372 ")),
373 #endif
374 PARSE_STR(RC_COOKIE_LOOSE_INVALID_DOMAINS, LYCookieLooseCheckDomains, N_("\
375 cookie_loose_invalid_domains, cookie_strict_invalid_domains, and\n\
376 cookie_query_invalid_domains are comma-delimited lists of which domains\n\
377 should be subjected to varying degrees of validity checking. If a\n\
378 domain is set to strict checking, strict conformance to RFC2109 will\n\
379 be applied. A domain with loose checking will be allowed to set cookies\n\
380 with an invalid path or domain attribute. All domains will default to\n\
381 querying the user for an invalid path or domain.\n\
382 ")),
383 PARSE_STR(RC_COOKIE_QUERY_INVALID_DOMAINS, LYCookieQueryCheckDomains, NULL),
384 PARSE_LIS(RC_COOKIE_REJECT_DOMAINS, LYCookieRejectDomains, NULL),
385 PARSE_STR(RC_COOKIE_STRICT_INVALID_DOMAIN, LYCookieStrictCheckDomains, NULL),
386 #ifdef DIRED_SUPPORT
387 #ifdef LONG_LIST
388 PARSE_ENU(RC_DIR_LIST_ORDER, dir_list_order, tbl_dir_list_order, N_("\
389 dir_list_order specifies the directory list order under DIRED_SUPPORT\n\
390 (if implemented). The default is \"ORDER_BY_NAME\"\n\
391 ")),
392 #endif
393 PARSE_ENU(RC_DIR_LIST_STYLE, dir_list_style, tbl_dir_list_style, N_("\
394 dir_list_styles specifies the directory list style under DIRED_SUPPORT\n\
395 (if implemented). The default is \"MIXED_STYLE\", which sorts both\n\
396 files and directories together. \"FILES_FIRST\" lists files first and\n\
397 \"DIRECTORIES_FIRST\" lists directories first.\n\
398 ")),
399 #endif
400 MAYBE_STR(RC_DISPLAY, x_display, MSG_ENABLE_LYNXRC),
401 PARSE_SET(RC_EMACS_KEYS, emacs_keys, N_("\
402 If emacs_keys is to \"on\" then the normal EMACS movement keys:\n\
403 ^N = down ^P = up\n\
404 ^B = left ^F = right\n\
405 will be enabled.\n\
406 ")),
407 PARSE_FUN(RC_FILE_EDITOR, get_editor, put_editor, N_("\
408 file_editor specifies the editor to be invoked when editing local files\n\
409 or sending mail. If no editor is specified, then file editing is disabled\n\
410 unless it is activated from the command line, and the built-in line editor\n\
411 will be used for sending mail.\n\
412 ")),
413 #ifndef DISABLE_FTP
414 PARSE_ENU(RC_FILE_SORTING_METHOD, HTfileSortMethod, tbl_file_sort, N_("\
415 The file_sorting_method specifies which value to sort on when viewing\n\
416 file lists such as FTP directories. The options are:\n\
417 BY_FILENAME -- sorts on the name of the file\n\
418 BY_TYPE -- sorts on the type of the file\n\
419 BY_SIZE -- sorts on the size of the file\n\
420 BY_DATE -- sorts on the date of the file\n\
421 ")),
422 #endif
423 MAYBE_ENU(RC_FORCE_COOKIE_PROMPT, cookie_noprompt, tbl_force_prompt,
424 MSG_ENABLE_LYNXRC),
425 #ifdef USE_SSL
426 MAYBE_ENU(RC_FORCE_SSL_PROMPT, ssl_noprompt, tbl_force_prompt,
427 MSG_ENABLE_LYNXRC),
428 #endif
429 #ifndef DISABLE_FTP
430 MAYBE_SET(RC_FTP_PASSIVE, ftp_passive, MSG_ENABLE_LYNXRC),
431 #endif
432 MAYBE_SET(RC_HTML5_CHARSETS, html5_charsets, MSG_ENABLE_LYNXRC),
433 #ifdef EXP_KEYBOARD_LAYOUT
434 PARSE_ARY(RC_KBLAYOUT, current_layout, LYKbLayoutNames, NULL),
435 #endif
436 PARSE_ENU(RC_KEYPAD_MODE, keypad_mode, tbl_keypad_mode, NULL),
437 PARSE_ARY(RC_LINEEDIT_MODE, current_lineedit, LYLineeditNames, N_("\
438 lineedit_mode specifies the key binding used for inputting strings in\n\
439 prompts and forms. If lineedit_mode is set to \"Default Binding\" then\n\
440 the following control characters are used for moving and deleting:\n\
441 \n\
442 Prev Next Enter = Accept input\n\
443 Move char: <- -> ^G = Cancel input\n\
444 Move word: ^P ^N ^U = Erase line\n\
445 Delete char: ^H ^R ^A = Beginning of line\n\
446 Delete word: ^B ^F ^E = End of line\n\
447 \n\
448 Current lineedit modes are:\n\
449 ")),
450 #ifdef USE_LOCALE_CHARSET
451 MAYBE_SET(RC_LOCALE_CHARSET, LYLocaleCharset, MSG_ENABLE_LYNXRC),
452 #endif
453 MAYBE_SET(RC_MAKE_PSEUDO_ALTS_FOR_INLINES, pseudo_inline_alts, MSG_ENABLE_LYNXRC),
454 MAYBE_SET(RC_MAKE_LINKS_FOR_ALL_IMAGES, clickable_images, MSG_ENABLE_LYNXRC),
455 PARSE_MBM(RC_MULTI_BOOKMARK, N_("\
456 The following allow you to define sub-bookmark files and descriptions.\n\
457 The format is multi_bookmark<capital_letter>=<filename>,<description>\n\
458 Up to 26 bookmark files (for the English capital letters) are allowed.\n\
459 We start with \"multi_bookmarkB\" since 'A' is the default (see above).\n\
460 ")),
461 PARSE_STR(RC_PERSONAL_MAIL_ADDRESS, personal_mail_address, N_("\
462 personal_mail_address specifies your personal mail address. The\n\
463 address will be sent during HTTP file transfers for authorization and\n\
464 logging purposes, and for mailed comments.\n\
465 If you do not want this information given out, set the NO_FROM_HEADER\n\
466 to TRUE in lynx.cfg, or use the -nofrom command line switch. You also\n\
467 could leave this field blank, but then you won't have it included in\n\
468 your mailed comments.\n\
469 ")),
470 PARSE_STR(RC_PERSONAL_MAIL_NAME, personal_mail_name, N_("\
471 personal_mail_name specifies your personal name, for mail. The\n\
472 name is sent for mailed comments. Lynx will prompt for this,\n\
473 showing the configured value as a default when sending mail.\n\
474 This is not necessarily the same as a name provided as part of the\n\
475 personal_mail_address.\n\
476 Lynx does not save your changes to that default value as a side-effect\n\
477 of sending email. To update the default value, you must use the options\n\
478 menu, or modify this file directly.\n\
479 ")),
480 PARSE_STR(RC_PREFERRED_CHARSET, pref_charset, N_("\
481 preferred_charset specifies the character set in MIME notation (e.g.,\n\
482 ISO-8859-2, ISO-8859-5) which Lynx will indicate you prefer in requests\n\
483 to http servers using an Accept-Charset header. The value should NOT\n\
484 include ISO-8859-1 or US-ASCII, since those values are always assumed\n\
485 by default. May be a comma-separated list.\n\
486 If a file in that character set is available, the server will send it.\n\
487 If no Accept-Charset header is present, the default is that any\n\
488 character set is acceptable. If an Accept-Charset header is present,\n\
489 and if the server cannot send a response which is acceptable\n\
490 according to the Accept-Charset header, then the server SHOULD send\n\
491 an error response, though the sending of an unacceptable response\n\
492 is also allowed.\n\
493 ")),
494 MAYBE_ENU(RC_PREFERRED_ENCODING, LYAcceptEncoding, tbl_preferred_encoding,
495 MSG_ENABLE_LYNXRC),
496 PARSE_STR(RC_PREFERRED_LANGUAGE, language, N_("\
497 preferred_language specifies the language in MIME notation (e.g., en,\n\
498 fr, may be a comma-separated list in decreasing preference)\n\
499 which Lynx will indicate you prefer in requests to http servers.\n\
500 If a file in that language is available, the server will send it.\n\
501 Otherwise, the server will send the file in its default language.\n\
502 ")),
503 MAYBE_ENU(RC_PREFERRED_MEDIA_TYPES, LYAcceptMedia, tbl_preferred_media,
504 MSG_ENABLE_LYNXRC),
505 MAYBE_SET(RC_RAW_MODE, LYRawMode, MSG_ENABLE_LYNXRC),
506 #if defined(ENABLE_OPTS_CHANGE_EXEC) && (defined(EXEC_LINKS) || defined(EXEC_SCRIPTS))
507 PARSE_SET(RC_RUN_ALL_EXECUTION_LINKS, local_exec, N_("\
508 If run_all_execution_links is set \"on\" then all local execution links\n\
509 will be executed when they are selected.\n\
510 \n\
511 WARNING - This is potentially VERY dangerous. Since you may view\n\
512 information that is written by unknown and untrusted sources\n\
513 there exists the possibility that Trojan horse links could be\n\
514 written. Trojan horse links could be written to erase files\n\
515 or compromise security. This should only be set to \"on\" if\n\
516 you are viewing trusted source information.\n\
517 ")),
518 PARSE_SET(RC_RUN_EXECUTION_LINKS_LOCAL, local_exec_on_local_files, N_("\
519 If run_execution_links_on_local_files is set \"on\" then all local\n\
520 execution links that are found in LOCAL files will be executed when they\n\
521 are selected. This is different from run_all_execution_links in that\n\
522 only files that reside on the local system will have execution link\n\
523 permissions.\n\
524 \n\
525 WARNING - This is potentially dangerous. Since you may view\n\
526 information that is written by unknown and untrusted sources\n\
527 there exists the possibility that Trojan horse links could be\n\
528 written. Trojan horse links could be written to erase files\n\
529 or compromise security. This should only be set to \"on\" if\n\
530 you are viewing trusted source information.\n\
531 ")),
532 #endif
533 #ifdef USE_SCROLLBAR
534 MAYBE_SET(RC_SCROLLBAR, LYShowScrollbar, MSG_ENABLE_LYNXRC),
535 #endif
536 PARSE_SET(RC_SELECT_POPUPS, LYSelectPopups, N_("\
537 select_popups specifies whether the OPTIONs in a SELECT block which\n\
538 lacks a MULTIPLE attribute are presented as a vertical list of radio\n\
539 buttons or via a popup menu. Note that if the MULTIPLE attribute is\n\
540 present in the SELECT start tag, Lynx always will create a vertical list\n\
541 of checkboxes for the OPTIONs. A value of \"on\" will set popup menus\n\
542 as the default while a value of \"off\" will set use of radio boxes.\n\
543 The default can be overridden via the -popup command line toggle.\n\
544 ")),
545 MAYBE_SET(RC_SEND_USERAGENT, LYSendUserAgent, MSG_ENABLE_LYNXRC),
546 MAYBE_SET(RC_SET_COOKIES, LYSetCookies, MSG_ENABLE_LYNXRC),
547 PARSE_ENU(RC_SHOW_COLOR, LYrcShowColor, tbl_show_colors, N_("\
548 show_color specifies how to set the color mode at startup. A value of\n\
549 \"never\" will force color mode off (treat the terminal as monochrome)\n\
550 at startup even if the terminal appears to be color capable. A value of\n\
551 \"always\" will force color mode on even if the terminal appears to be\n\
552 monochrome, if this is supported by the library used to build lynx.\n\
553 A value of \"default\" will yield the behavior of assuming\n\
554 a monochrome terminal unless color capability is inferred at startup\n\
555 based on the terminal type, or the -color command line switch is used, or\n\
556 the COLORTERM environment variable is set. The default behavior always is\n\
557 used in anonymous accounts or if the \"option_save\" restriction is set.\n\
558 The effect of the saved value can be overridden via\n\
559 the -color and -nocolor command line switches.\n\
560 The mode set at startup can be changed via the \"show color\" option in\n\
561 the 'o'ptions menu. If the option settings are saved, the \"on\" and\n\
562 \"off\" \"show color\" settings will be treated as \"default\".\n\
563 ")),
564 PARSE_SET(RC_SHOW_CURSOR, LYShowCursor, N_("\
565 show_cursor specifies whether to 'hide' the cursor to the right (and\n\
566 bottom, if possible) of the screen, or to place it to the left of the\n\
567 current link in documents, or current option in select popup windows.\n\
568 Positioning the cursor to the left of the current link or option is\n\
569 helpful for speech or braille interfaces, and when the terminal is\n\
570 one which does not distinguish the current link based on highlighting\n\
571 or color. A value of \"on\" will set positioning to the left as the\n\
572 default while a value of \"off\" will set 'hiding' of the cursor.\n\
573 The default can be overridden via the -show_cursor command line toggle.\n\
574 ")),
575 PARSE_SET(RC_SHOW_DOTFILES, show_dotfiles, N_("\
576 show_dotfiles specifies that the directory listing should include\n\
577 \"hidden\" (dot) files/directories. If set \"on\", this will be\n\
578 honored only if enabled via userdefs.h and/or lynx.cfg, and not\n\
579 restricted via a command line switch. If display of hidden files\n\
580 is disabled, creation of such files via Lynx also is disabled.\n\
581 ")),
582 #ifdef USE_READPROGRESS
583 MAYBE_ENU(RC_SHOW_KB_RATE, LYTransferRate, tbl_transfer_rate,
584 MSG_ENABLE_LYNXRC),
585 #endif
586 PARSE_ENU(RC_SUB_BOOKMARKS, LYMultiBookmarks, tbl_multi_bookmarks, N_("\
587 If sub_bookmarks is not turned \"off\", and multiple bookmarks have\n\
588 been defined (see below), then all bookmark operations will first\n\
589 prompt the user to select an active sub-bookmark file. If the default\n\
590 Lynx bookmark_file is defined (see above), it will be used as the\n\
591 default selection. When this option is set to \"advanced\", and the\n\
592 user mode is advanced, the 'v'iew bookmark command will invoke a\n\
593 statusline prompt instead of the menu seen in novice and intermediate\n\
594 user modes. When this option is set to \"standard\", the menu will be\n\
595 presented regardless of user mode.\n\
596 ")),
597 MAYBE_FUN(RC_TAGSOUP, get_tagsoup, put_tagsoup,
598 MSG_ENABLE_LYNXRC),
599 MAYBE_SET(RC_UNDERLINE_LINKS, LYUnderlineLinks, MSG_ENABLE_LYNXRC),
600 PARSE_ENU(RC_USER_MODE, user_mode, tbl_user_mode, N_("\
601 user_mode specifies the users level of knowledge with Lynx. The\n\
602 default is \"NOVICE\" which displays two extra lines of help at the\n\
603 bottom of the screen to aid the user in learning the basic Lynx\n\
604 commands. Set user_mode to \"INTERMEDIATE\" to turn off the extra info.\n\
605 Use \"ADVANCED\" to see the URL of the currently selected link at the\n\
606 bottom of the screen.\n\
607 ")),
608 MAYBE_STR(RC_USERAGENT, LYUserAgent, MSG_ENABLE_LYNXRC),
609 PARSE_SET(RC_VERBOSE_IMAGES, verbose_img, N_("\
610 If verbose_images is \"on\", lynx will print the name of the image\n\
611 source file in place of [INLINE], [LINK] or [IMAGE]\n\
612 See also VERBOSE_IMAGES in lynx.cfg\n\
613 ")),
614 PARSE_SET(RC_VI_KEYS, vi_keys, N_("\
615 If vi_keys is set to \"on\", then the normal VI movement keys:\n\
616 j = down k = up\n\
617 h = left l = right\n\
618 will be enabled. These keys are only lower case.\n\
619 Capital 'H', 'J' and 'K will still activate help, jump shortcuts,\n\
620 and the keymap display, respectively.\n\
621 ")),
622 PARSE_ENU(RC_VISITED_LINKS, Visited_Links_As, tbl_visited_links, N_("\
623 The visited_links setting controls how Lynx organizes the information\n\
624 in the Visited Links Page.\n\
625 ")),
626 #ifdef USE_SESSIONS
627 MAYBE_SET(RC_AUTO_SESSION, LYAutoSession, MSG_ENABLE_LYNXRC),
628 MAYBE_STR(RC_SESSION_FILE, LYSessionFile, MSG_ENABLE_LYNXRC),
629 #endif
630 MAYBE_SET(RC_NO_PAUSE, no_pause, MSG_ENABLE_LYNXRC),
631
632 PARSE_NIL
633 };
634 /* *INDENT-ON* */
635
lookup_config(const char * name)636 static Config_Type *lookup_config(const char *name)
637 {
638 Config_Type *tbl = Config_Table;
639 char ch = (char) TOUPPER(*name);
640
641 while (tbl->name != 0) {
642 if (tbl->enabled) {
643 char ch1 = tbl->name[0];
644
645 if ((ch == TOUPPER(ch1))
646 && (0 == strcasecomp(name, tbl->name)))
647 break;
648 }
649
650 tbl++;
651 }
652 return tbl;
653 }
654
LYsetRcValue(const char * name,const char * param)655 BOOL LYsetRcValue(const char *name, const char *param)
656 {
657 char MBM_line[256];
658 char *notes;
659 int n;
660 Config_Type *tbl;
661 ParseUnionPtr q;
662 BOOL changed = TRUE;
663 char *value = NULL;
664
665 StrAllocCopy(value, param);
666 value = LYSkipBlanks(value);
667 CTRACE2(TRACE_CFG, (tfp, "LYrcFile %s:%s\n", name, value));
668
669 tbl = lookup_config(name);
670 if (tbl->name == 0) {
671 const char *special = RC_MULTI_BOOKMARK;
672
673 if (!strncasecomp(name, special, (int) strlen(special))) {
674 tbl = lookup_config(special);
675 }
676 /*
677 * lynx ignores unknown keywords.
678 * This includes known keywords where there is no ENABLE_LYNXRC.
679 */
680 if (tbl->name == 0) {
681 CTRACE((tfp, "LYrcFile: ignored %s=%s\n", name, value));
682 return FALSE;
683 }
684 }
685
686 q = ParseUnionOf(tbl);
687 switch (tbl->type) {
688 case CONF_BOOL:
689 if (q->set_value != 0)
690 *(q->set_value) = getBool(value);
691 break;
692
693 case CONF_FUN:
694 if (q->fun_value != 0)
695 (*(q->fun_value)) (value);
696 break;
697
698 case CONF_ARRAY:
699 for (n = 0; tbl->strings[n] != 0; ++n) {
700 if (!strcasecomp(value, tbl->strings[n])) {
701 *(q->int_value) = n;
702 break;
703 }
704 }
705 break;
706
707 case CONF_ENUM:
708 if (tbl->table != 0)
709 LYgetEnum(tbl->table, value, q->int_value);
710 break;
711
712 case CONF_INT:
713 if (q->int_value != 0) {
714 int ival;
715
716 if (1 == sscanf(value, "%d", &ival))
717 *(q->int_value) = ival;
718 }
719 break;
720
721 case CONF_LIS:
722 if (q->str_value != 0) {
723 if (*(q->str_value) != NULL)
724 StrAllocCat(*(q->str_value), ",");
725 StrAllocCat(*(q->str_value), value);
726 }
727 break;
728
729 case CONF_MBM:
730 for (n = 1; n <= MBM_V_MAXFILES; n++) {
731 sprintf(MBM_line, "multi_bookmark%c", LYindex2MBM(n));
732
733 if (!strcasecomp(name, MBM_line)) {
734 if ((notes = strchr(value, ',')) != 0) {
735 *notes++ = '\0';
736 LYTrimTrailing(value);
737 notes = LYSkipBlanks(notes);
738 } else {
739 notes = value + strlen(value);
740 }
741 StrAllocCopy(MBM_A_subbookmark[n], value);
742 StrAllocCopy(MBM_A_subdescript[n], notes);
743 break;
744 }
745 }
746 break;
747
748 case CONF_STR:
749 if (q->str_value != 0)
750 StrAllocCopy(*(q->str_value), value);
751 break;
752
753 default:
754 changed = FALSE;
755 break;
756 }
757 FREE(value);
758
759 return changed;
760 }
761
762 /* Read and process user options. If the passed-in fp is NULL, open the
763 * regular user defaults file for reading, otherwise use fp which has to be a
764 * file open for reading. - kw
765 */
read_rc(FILE * fp)766 void read_rc(FILE *fp)
767 {
768 char *buffer = NULL;
769 char rcfile[LY_MAXPATH];
770
771 if (!fp) {
772 /*
773 * Make an RC file name, open it for reading.
774 */
775 LYAddPathToHome(rcfile, sizeof(rcfile), FNAME_LYNXRC);
776 if ((fp = fopen(rcfile, TXT_R)) == NULL) {
777 return;
778 }
779 CTRACE((tfp, "read_rc opened %s\n", rcfile));
780 } else {
781 CTRACE((tfp, "read_rc used passed-in stream\n"));
782 }
783
784 /*
785 * Process the entries.
786 */
787 while (LYSafeGets(&buffer, fp) != NULL) {
788 char *name, *value;
789
790 /* Most lines in the config file are comment lines. Weed them out
791 * now. Also, leading whitespace is ok, so trim it.
792 */
793 LYTrimTrailing(buffer);
794 name = LYSkipBlanks(buffer);
795 if (ispunct(UCH(*name)) || *name == '\0')
796 continue;
797
798 /*
799 * Parse the "name=value" strings.
800 */
801 if ((value = strchr(name, '=')) == 0) {
802 CTRACE((tfp, "LYrcFile: missing '=' %s\n", name));
803 continue;
804 }
805 *value++ = '\0';
806 LYTrimTrailing(name);
807 LYsetRcValue(name, value);
808 }
809
810 LYCloseInput(fp);
811 LYConfigCookies(); /* update cookie settings, if any */
812
813 #if defined(USE_SLANG) || defined(COLOR_CURSES)
814 /*
815 * We may override the commandline "-color" option with the .lynxrc file
816 */
817 switch (LYrcShowColor) {
818 case SHOW_COLOR_ALWAYS:
819 if (LYShowColor != SHOW_COLOR_NEVER)
820 LYShowColor = SHOW_COLOR_ALWAYS;
821 break;
822 case SHOW_COLOR_NEVER:
823 if (LYShowColor == SHOW_COLOR_ON)
824 LYShowColor = SHOW_COLOR_OFF;
825 break;
826 default:
827 /* don't override */
828 break;
829 }
830 #endif
831 set_default_bookmark_page(bookmark_page);
832 }
833
834 /*
835 * Write a set of comments. Doing it this way avoids preprocessor problems
836 * with the leading '#', makes it simpler to use gettext.
837 */
write_list(FILE * fp,const char * list)838 static void write_list(FILE *fp, const char *list)
839 {
840 int first = TRUE;
841
842 while (*list != 0) {
843 int ch = *list++;
844
845 if (first) {
846 fputs("# ", fp);
847 first = FALSE;
848 }
849 if (ch == '\n') {
850 first = TRUE;
851 }
852 fputc(ch, fp);
853 }
854 }
855
856 /*
857 * This is too long for some compilers.
858 */
explain_keypad_mode(FILE * fp)859 static void explain_keypad_mode(FILE *fp)
860 {
861 write_list(fp, gettext("\
862 If keypad_mode is set to \"NUMBERS_AS_ARROWS\", then the numbers on\n\
863 your keypad when the numlock is on will act as arrow keys:\n\
864 8 = Up Arrow\n\
865 4 = Left Arrow 6 = Right Arrow\n\
866 2 = Down Arrow\n\
867 and the corresponding keyboard numbers will act as arrow keys,\n\
868 regardless of whether numlock is on.\n\
869 "));
870 write_list(fp, gettext("\
871 If keypad_mode is set to \"LINKS_ARE_NUMBERED\", then numbers will\n\
872 appear next to each link and numbers are used to select links.\n\
873 "));
874 write_list(fp, gettext("\
875 If keypad_mode is set to \"LINKS_AND_FORM_FIELDS_ARE_NUMBERED\", then\n\
876 numbers will appear next to each link and visible form input field.\n\
877 Numbers are used to select links, or to move the \"current link\" to a\n\
878 form input field or button. In addition, options in popup menus are\n\
879 indexed so that the user may type an option number to select an option in\n\
880 a popup menu, even if the option isn't visible on the screen. Reference\n\
881 lists and output from the list command also enumerate form inputs.\n\
882 "));
883 write_list(fp, gettext("\
884 NOTE: Some fixed format documents may look disfigured when\n\
885 \"LINKS_ARE_NUMBERED\" or \"LINKS_AND_FORM_FIELDS_ARE_NUMBERED\" are\n\
886 enabled.\n\
887 "));
888 }
889
890 /* Save user options. If the passed-in fp is NULL, open the regular user
891 * defaults file for writing, otherwise use fp which has to be a temp file open
892 * for writing. - kw
893 */
save_rc(FILE * fp)894 int save_rc(FILE *fp)
895 {
896 Config_Type *tbl = Config_Table;
897 char rcfile[LY_MAXPATH];
898 BOOLEAN is_tempfile = (BOOL) (fp != NULL);
899 int n;
900
901 if (!fp) {
902 /*
903 * Make a name.
904 */
905 LYAddPathToHome(rcfile, sizeof(rcfile), FNAME_LYNXRC);
906
907 /*
908 * Open the file for write.
909 */
910 if ((fp = LYNewTxtFile(rcfile)) == NULL) {
911 return FALSE;
912 }
913 }
914
915 write_list(fp, gettext("\
916 Lynx User Defaults File\n\
917 \n\
918 "));
919
920 /*
921 * We have either the HTML options form, or the older menu, or both.
922 */
923 #ifndef NO_OPTION_FORMS
924 write_list(fp, gettext("\
925 This file contains options saved from the Lynx Options Screen (normally\n\
926 with the 'o' key). To save options with that screen, you must select the\n\
927 checkbox:\n\
928 "));
929 fprintf(fp, "#\t%s\n", SAVE_OPTIONS);
930 fprintf(fp, "#\n");
931 write_list(fp, gettext("\
932 You must then save the settings using the link on the line above the\n\
933 checkbox:\n\
934 "));
935 fprintf(fp, "#\t%s\n", ACCEPT_CHANGES);
936 fprintf(fp, "#\n");
937 #ifndef NO_OPTION_MENU
938 write_list(fp, gettext("\
939 You may also use the command-line option \"-forms_options\", which displays\n\
940 the simpler Options Menu instead. Save options with that using the '>' key.\n\
941 \n\
942 "));
943 #endif
944 #else /* we only have old options-menu */
945 write_list(fp, gettext("\
946 This file contains options saved from the Lynx Options Screen (normally\n\
947 with the '>' key).\n\
948 \n\
949 "));
950 #endif
951
952 write_list(fp, gettext("\
953 There is normally no need to edit this file manually, since the defaults\n\
954 here can be controlled from the Options Screen, and the next time options\n\
955 are saved from the Options Screen this file will be completely rewritten.\n\
956 You have been warned...\n\
957 \n\
958 If you are looking for the general configuration file - it is normally\n\
959 called \"lynx.cfg\". It has different content and a different format.\n\
960 It is not this file.\n\
961 "));
962 fprintf(fp, "\n");
963
964 while (tbl->name != 0) {
965 ParseUnionPtr q = ParseUnionOf(tbl);
966
967 if (!tbl->enabled) {
968 tbl++;
969 continue;
970 }
971 if (tbl->note != NULL) {
972 write_list(fp, gettext(tbl->note));
973 } else if (tbl->table == tbl_keypad_mode) {
974 explain_keypad_mode(fp);
975 }
976
977 switch (tbl->type) {
978 case CONF_BOOL:
979 fprintf(fp, "%s=%s\n\n", tbl->name, putBool(*(q->set_value)));
980 break;
981
982 case CONF_FUN:
983 if (tbl->write_it != 0)
984 tbl->write_it(fp, tbl);
985 break;
986
987 case CONF_ARRAY:
988 for (n = 0; tbl->strings[n] != 0; ++n)
989 fprintf(fp, "# %s\n", tbl->strings[n]);
990 fprintf(fp, "%s=%s\n\n", tbl->name,
991 tbl->strings[*(q->int_value)]);
992 break;
993
994 case CONF_ENUM:
995 fprintf(fp, "%s=%s\n\n", tbl->name,
996 LYputEnum(tbl->table, *(q->int_value)));
997 break;
998
999 case CONF_INT:
1000 fprintf(fp, "%s=%d\n\n", tbl->name, *(q->int_value));
1001 break;
1002
1003 case CONF_MBM:
1004 for (n = 1; n <= MBM_V_MAXFILES; n++) {
1005 fprintf(fp, "multi_bookmark%c=", LYindex2MBM(n));
1006
1007 fprintf(fp, "%s", NonNull(MBM_A_subbookmark[n]));
1008 if (MBM_A_subdescript[n] != 0
1009 && *MBM_A_subdescript[n] != 0)
1010 fprintf(fp, ",%s", MBM_A_subdescript[n]);
1011 fprintf(fp, "\n");
1012 }
1013 fprintf(fp, "\n");
1014 break;
1015
1016 case CONF_LIS:
1017 /* FALLTHRU */
1018 case CONF_STR:
1019 fprintf(fp, "%s=%s\n\n", tbl->name,
1020 (q->str_value != 0 && *(q->str_value) != 0)
1021 ? *(q->str_value)
1022 : "");
1023 break;
1024
1025 case CONF_NIL:
1026 break;
1027 }
1028 tbl++;
1029 }
1030
1031 /*
1032 * Close the RC file.
1033 */
1034 if (is_tempfile) {
1035 LYCloseTempFP(fp);
1036 } else {
1037 LYCloseOutput(fp);
1038 HTSYS_purge(rcfile);
1039 }
1040
1041 return TRUE;
1042 }
1043
1044 /*
1045 * Returns true if the given name would be saved in .lynxrc
1046 */
will_save_rc(const char * name)1047 BOOL will_save_rc(const char *name)
1048 {
1049 Config_Type *tbl = lookup_config(name);
1050
1051 return (BOOL) (tbl->name != 0);
1052 }
1053
enable_lynxrc(char * value)1054 int enable_lynxrc(char *value)
1055 {
1056 Config_Type *tbl;
1057 char *colon = strchr(value, ':');
1058
1059 if (colon != 0) {
1060 *colon++ = 0;
1061 LYTrimLeading(value);
1062 LYTrimTrailing(value);
1063
1064 for (tbl = Config_Table; tbl->name != 0; tbl++) {
1065 if (!strcasecomp(value, tbl->name)) {
1066 tbl->enabled = getBool(colon);
1067 break;
1068 }
1069 }
1070 }
1071 return 0;
1072 }
1073