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