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