1 /*
2  * $LynxId: LYMain.c,v 1.243 2013/05/30 08:58:21 tom Exp $
3  */
4 #include <HTUtils.h>
5 #include <HTTP.h>
6 #include <HTParse.h>
7 #include <HTAccess.h>
8 #include <HTList.h>
9 #include <HTFile.h>
10 #include <UCMap.h>
11 #include <UCDefs.h>
12 #include <HTInit.h>
13 #include <HTAlert.h>
14 #include <LYCurses.h>
15 #include <LYStyle.h>
16 #include <HTML.h>
17 #include <LYUtils.h>
18 #include <LYGlobalDefs.h>
19 #include <LYMail.h>
20 #include <LYOptions.h>
21 #include <LYSignal.h>
22 #include <LYGetFile.h>
23 #include <LYStrings.h>
24 #include <LYClean.h>
25 #include <LYCharSets.h>
26 #include <LYCharUtils.h>
27 #include <LYReadCFG.h>
28 #include <LYrcFile.h>
29 #include <LYKeymap.h>
30 #include <HTForms.h>
31 #include <LYList.h>
32 #include <LYJump.h>
33 
34 #ifdef USE_SESSIONS
35 #include <LYSession.h>
36 #endif
37 
38 #include <LYMainLoop.h>
39 #include <LYBookmark.h>
40 #include <LYCookie.h>
41 #include <LYPrettySrc.h>
42 #include <LYShowInfo.h>
43 #include <LYHistory.h>
44 
45 #ifdef VMS
46 #include <HTFTP.h>
47 #endif /* !DECNET */
48 
49 #ifdef __DJGPP__
50 #include <dos.h>
51 #include <dpmi.h>
52 #include <io.h>
53 #include <sys/stat.h>
54 #include <sys/exceptn.h>
55 #endif /* __DJGPP__ */
56 
57 #ifdef __EMX__
58 #include <io.h>
59 #endif
60 
61 #if defined(LOCALE) && (!defined(HAVE_LIBINTL_H) || !defined(LC_ALL))
62 #undef gettext			/* Solaris locale.h prototypes gettext() */
63 #include <locale.h>
64 #ifndef HAVE_GETTEXT
65 #define gettext(s) s
66 #endif
67 #endif /* LOCALE */
68 
69 #include <LYexit.h>
70 #include <LYLeaks.h>
71 
72 /* ahhhhhhhhhh!! Global variables :-< */
73 #ifdef SOCKS
74 BOOLEAN socks_flag = TRUE;
75 #endif /* SOCKS */
76 
77 #ifdef IGNORE_CTRL_C
78 BOOLEAN sigint = FALSE;
79 #endif /* IGNORE_CTRL_C */
80 
81 #ifdef __DJGPP__
82 static char init_ctrl_break[1];
83 #endif /* __DJGPP__ */
84 
85 #if USE_VMS_MAILER
86 char *mail_adrs = NULL;		/* the mask for a VMS mail transport */
87 #endif
88 
89 #ifdef VMS
90 	       /* create FIXED 512 binaries */
91 BOOLEAN UseFixedRecords = USE_FIXED_RECORDS;
92 #endif /* VMS */
93 
94 #ifndef VMS
95 static char *lynx_version_putenv_command = NULL;
96 char *list_format = NULL;	/* LONG_LIST formatting mask */
97 #endif /* !VMS */
98 
99 char *ftp_format = NULL;	/* LONG_LIST formatting mask */
100 
101 #ifdef SYSLOG_REQUESTED_URLS
102 char *syslog_txt = NULL;	/* syslog arb text for session */
103 BOOLEAN syslog_requested_urls = FALSE;
104 #endif
105 
106 int cfg_bad_html = BAD_HTML_WARN;
107 
108 #ifdef DIRED_SUPPORT
109 BOOLEAN lynx_edit_mode = FALSE;
110 BOOLEAN no_dired_support = FALSE;
111 HTList *tagged = NULL;
112 int LYAutoUncacheDirLists = 2;	/* default dired uncaching behavior */
113 int dir_list_order = ORDER_BY_NAME;
114 int dir_list_style = MIXED_STYLE;
115 
116 #ifdef OK_OVERRIDE
117 BOOLEAN prev_lynx_edit_mode = FALSE;
118 #endif /* OK_OVERRIDE */
119 
120 #ifdef OK_PERMIT
121 #ifdef NO_CHANGE_EXECUTE_PERMS
122 BOOLEAN no_change_exec_perms = TRUE;
123 
124 #else
125 BOOLEAN no_change_exec_perms = FALSE;
126 #endif /* NO_CHANGE_EXECUTE_PERMS */
127 #endif /* OK_PERMIT */
128 
129 #endif /* DIRED_SUPPORT */
130 
131 	   /* Number of docs cached in memory */
132 int HTCacheSize = DEFAULT_CACHE_SIZE;
133 
134 #if defined(VMS) && defined(VAXC) && !defined(__DECC)
135 	   /* Don't dump doc cache unless this size is exceeded */
136 int HTVirtualMemorySize = DEFAULT_VIRTUAL_MEMORY_SIZE;
137 #endif /* VMS && VAXC && !_DECC */
138 
139 #if defined(EXEC_LINKS) || defined(EXEC_SCRIPTS)
140 #ifndef NEVER_ALLOW_REMOTE_EXEC
141 BOOLEAN local_exec = LOCAL_EXECUTION_LINKS_ALWAYS_ON;
142 
143 #else
144 BOOLEAN local_exec = FALSE;
145 #endif /* NEVER_ALLOW_REMOTE_EXEC */
146 BOOLEAN local_exec_on_local_files =
147 LOCAL_EXECUTION_LINKS_ON_BUT_NOT_REMOTE;
148 #endif /* EXEC_LINKS || EXEC_SCRIPTS */
149 
150 #if defined(LYNXCGI_LINKS) && !defined(VMS)	/* WebSter Mods -jkt */
151 char *LYCgiDocumentRoot = NULL;	/* DOCUMENT_ROOT in the lynxcgi env */
152 #endif /* LYNXCGI_LINKS */
153 
154 #ifdef TRACK_INTERNAL_LINKS
155 BOOLEAN track_internal_links = TRUE;
156 
157 #else
158 BOOLEAN track_internal_links = FALSE;
159 #endif
160 
161 #ifdef REVERSE_CLEAR_SCREEN_PROBLEM
162 BOOLEAN enable_scrollback = TRUE;
163 
164 #else
165 BOOLEAN enable_scrollback = FALSE;
166 #endif /* REVERSE_CLEAR_SCREEN_PROBLEM */
167 
168 char empty_string[] =
169 {'\0'};
170 
171 int display_lines;		/* number of lines in display */
172 int www_search_result = -1;
173 
174 			       /* linked list of printers */
175 lynx_list_item_type *printers = NULL;
176 
177 			    /* linked list of download options */
178 lynx_list_item_type *downloaders = NULL;
179 
180 			    /* linked list of upload options */
181 #ifdef USE_EXTERNALS
182 lynx_list_item_type *externals = NULL;
183 
184 			    /* linked list of external options */
185 #endif
186 
187 lynx_list_item_type *uploaders = NULL;
188 int LYShowColor = SHOW_COLOR_UNKNOWN;	/* to show or not */
189 int LYrcShowColor = SHOW_COLOR_UNKNOWN;		/* ... last used */
190 
191 #if !defined(NO_OPTION_FORMS) && !defined(NO_OPTION_MENU)
192 BOOLEAN LYUseFormsOptions = TRUE;	/* use forms-based options menu */
193 #endif
194 
195 BOOLEAN LYJumpFileURL = FALSE;	/* always FALSE the first time */
196 BOOLEAN LYPermitURL = FALSE;
197 BOOLEAN LYRestricted = FALSE;	/* whether we have -anonymous option */
198 BOOLEAN LYShowCursor = SHOW_CURSOR;	/* to show or not to show */
199 BOOLEAN LYUnderlineLinks = UNDERLINE_LINKS;	/* Show the links underlined vs bold */
200 BOOLEAN LYUseDefShoCur = TRUE;	/* Command line -show_cursor toggle */
201 BOOLEAN LYUserSpecifiedURL = TRUE;	/* always TRUE  the first time */
202 BOOLEAN LYValidate = FALSE;
203 BOOLEAN LYforce_no_cache = FALSE;
204 BOOLEAN LYinternal_flag = FALSE;	/* override no-cache b/c internal link */
205 BOOLEAN LYoverride_no_cache = FALSE;	/*override no-cache b/c history etc */
206 BOOLEAN LYresubmit_posts = ALWAYS_RESUBMIT_POSTS;
207 BOOLEAN LYtrimInputFields = FALSE;
208 BOOLEAN LYxhtml_parsing = FALSE;
209 BOOLEAN bold_H1 = FALSE;
210 BOOLEAN bold_headers = FALSE;
211 BOOLEAN bold_name_anchors = FALSE;
212 BOOLEAN LYcase_sensitive = CASE_SENSITIVE_ALWAYS_ON;
213 BOOLEAN check_mail = CHECKMAIL;
214 BOOLEAN child_lynx = FALSE;
215 BOOLEAN dump_links_only = FALSE;
216 BOOLEAN dump_output_immediately = FALSE;
217 BOOLEAN dump_to_stderr = FALSE;
218 BOOLEAN emacs_keys = EMACS_KEYS_ALWAYS_ON;
219 BOOLEAN error_logging = MAIL_SYSTEM_ERROR_LOGGING;
220 BOOLEAN goto_buffer = GOTOBUFFER;	/* TRUE if offering default goto URL */
221 BOOLEAN historical_comments = FALSE;
222 BOOLEAN html5_charsets = FALSE;
223 BOOLEAN is_www_index = FALSE;
224 BOOLEAN jump_buffer = JUMPBUFFER;	/* TRUE if offering default shortcut */
225 BOOLEAN lynx_mode = NORMAL_LYNX_MODE;
226 BOOLEAN minimal_comments = FALSE;
227 BOOLEAN number_fields_on_left = TRUE;
228 BOOLEAN number_links_on_left = TRUE;
229 BOOLEAN recent_sizechange = FALSE;	/* the window size changed recently? */
230 BOOLEAN soft_dquotes = FALSE;
231 BOOLEAN unique_urls = FALSE;
232 BOOLEAN use_underscore = SUBSTITUTE_UNDERSCORES;
233 BOOLEAN verbose_img = VERBOSE_IMAGES;	/* show filenames or not */
234 BOOLEAN vi_keys = VI_KEYS_ALWAYS_ON;
235 int keypad_mode = DEFAULT_KEYPAD_MODE;
236 int user_mode = NOVICE_MODE;
237 
238 BOOLEAN telnet_ok = TRUE;
239 
240 #ifndef DISABLE_NEWS
241 BOOLEAN news_ok = TRUE;
242 #endif
243 BOOLEAN rlogin_ok = TRUE;
244 BOOLEAN long_url_ok = FALSE;
245 BOOLEAN ftp_ok = TRUE;
246 BOOLEAN system_editor = FALSE;
247 
248 BOOLEAN had_restrictions_default = FALSE;
249 BOOLEAN had_restrictions_all = FALSE;
250 
251 BOOLEAN exec_frozen = FALSE;
252 BOOLEAN no_bookmark = FALSE;
253 BOOLEAN no_bookmark_exec = FALSE;
254 BOOLEAN no_chdir = FALSE;
255 BOOLEAN no_disk_save = FALSE;
256 BOOLEAN no_dotfiles = NO_DOT_FILES;
257 BOOLEAN no_download = FALSE;
258 BOOLEAN no_editor = FALSE;
259 BOOLEAN no_exec = FALSE;
260 BOOLEAN no_file_url = FALSE;
261 BOOLEAN no_goto = FALSE;
262 BOOLEAN no_goto_configinfo = FALSE;
263 BOOLEAN no_goto_cso = FALSE;
264 BOOLEAN no_goto_file = FALSE;
265 BOOLEAN no_goto_finger = FALSE;
266 BOOLEAN no_goto_ftp = FALSE;
267 BOOLEAN no_goto_gopher = FALSE;
268 BOOLEAN no_goto_http = FALSE;
269 BOOLEAN no_goto_https = FALSE;
270 BOOLEAN no_goto_lynxcgi = FALSE;
271 BOOLEAN no_goto_lynxexec = FALSE;
272 BOOLEAN no_goto_lynxprog = FALSE;
273 BOOLEAN no_goto_mailto = FALSE;
274 BOOLEAN no_goto_rlogin = FALSE;
275 BOOLEAN no_goto_telnet = FALSE;
276 BOOLEAN no_goto_tn3270 = FALSE;
277 BOOLEAN no_goto_wais = FALSE;
278 BOOLEAN no_inside_ftp = FALSE;
279 BOOLEAN no_inside_rlogin = FALSE;
280 BOOLEAN no_inside_telnet = FALSE;
281 BOOLEAN no_jump = FALSE;
282 BOOLEAN no_lynxcfg_info = FALSE;
283 BOOLEAN no_lynxcgi = FALSE;
284 BOOLEAN no_mail = FALSE;
285 BOOLEAN no_multibook = FALSE;
286 BOOLEAN no_option_save = FALSE;
287 BOOLEAN no_outside_ftp = FALSE;
288 BOOLEAN no_outside_rlogin = FALSE;
289 BOOLEAN no_outside_telnet = FALSE;
290 BOOLEAN no_print = FALSE;
291 BOOLEAN no_shell = FALSE;
292 BOOLEAN no_suspend = FALSE;
293 BOOLEAN no_telnet_port = FALSE;
294 BOOLEAN no_useragent = FALSE;
295 
296 #ifndef DISABLE_FTP
297 BOOLEAN ftp_passive = FTP_PASSIVE;	/* TRUE if doing ftp in passive mode */
298 BOOLEAN ftp_local_passive;
299 HTList *broken_ftp_epsv = NULL;
300 HTList *broken_ftp_retr = NULL;
301 char *ftp_lasthost = NULL;
302 #endif
303 
304 #ifndef DISABLE_NEWS
305 BOOLEAN no_goto_news = FALSE;
306 BOOLEAN no_goto_nntp = FALSE;
307 BOOLEAN no_goto_snews = FALSE;
308 BOOLEAN no_inside_news = FALSE;
309 BOOLEAN no_newspost = FALSE;
310 BOOLEAN no_outside_news = FALSE;
311 #endif
312 
313 #ifdef USE_EXTERNALS
314 BOOLEAN no_externals = FALSE;
315 #endif
316 
317 #ifndef NO_CONFIG_INFO
318 BOOLEAN no_lynxcfg_xinfo = FALSE;
319 
320 #ifdef HAVE_CONFIG_H
321 BOOLEAN no_compileopts_info = FALSE;
322 #endif
323 #endif
324 
325 BOOLEAN no_statusline = FALSE;
326 BOOLEAN no_filereferer = TRUE;
327 char LYRefererWithQuery = 'D';	/* 'D' for drop */
328 BOOLEAN local_host_only = FALSE;
329 BOOLEAN override_no_download = FALSE;
330 BOOLEAN show_dotfiles = FALSE;	/* From rcfile if no_dotfiles is false */
331 BOOLEAN LYforce_HTML_mode = FALSE;
332 BOOLEAN LYfind_leaks = TRUE;
333 
334 #ifdef __DJGPP__
335 BOOLEAN watt_debug = FALSE;	/* WATT-32 debugging */
336 BOOLEAN dj_is_bash = FALSE;	/* Check for bash shell under DJGPP */
337 #endif /* __DJGPP__ */
338 
339 #ifdef WIN_EX
340 BOOLEAN focus_window = FALSE;	/* 1998/10/05 (Mon) 17:18:42 */
341 char windows_drive[4];		/* 1998/01/13 (Tue) 21:13:24 */
342 #endif
343 
344 #ifdef _WINDOWS
345 #define	TIMEOUT	180		/* 1998/03/30 (Mon) 14:50:44 */
346 int lynx_timeout = TIMEOUT;
347 CRITICAL_SECTION critSec_DNS;	/* 1998/09/03 (Thu) 22:01:56 */
348 CRITICAL_SECTION critSec_READ;	/* 1998/09/03 (Thu) 22:01:56 */
349 #endif /* _WINDOWS */
350 
351 #if defined(WIN_EX)
352 BOOLEAN system_is_NT = FALSE;
353 #endif
354 
355 BOOLEAN show_cfg = FALSE;
356 
357 BOOLEAN no_table_center = FALSE;	/* 1998/10/09 (Fri) 15:12:49 */
358 
359 #if USE_BLAT_MAILER
360 BOOLEAN mail_is_blat = TRUE;
361 BOOLEAN mail_is_altblat = USE_ALT_BLAT_MAILER;
362 
363 #if USE_ALT_BLAT_MAILER
364 #define THIS_BLAT_MAIL ALTBLAT_MAIL
365 #define THAT_BLAT_MAIL BLAT_MAIL
366 #else
367 #define THIS_BLAT_MAIL BLAT_MAIL
368 #define THAT_BLAT_MAIL ALTBLAT_MAIL
369 #endif
370 #endif
371 
372 #ifdef USE_BLINK
373 #  ifdef __EMX__
374 BOOLEAN term_blink_is_boldbg = TRUE;
375 
376 #  else
377 BOOLEAN term_blink_is_boldbg = FALSE;
378 
379 #  endif
380 #endif
381 
382 BOOLEAN HEAD_request = FALSE;
383 BOOLEAN LYAcceptAllCookies = ACCEPT_ALL_COOKIES;	/* take all cookies? */
384 BOOLEAN LYCancelledFetch = FALSE;	/* TRUE if cancelled binary fetch */
385 BOOLEAN LYCollapseBRs = COLLAPSE_BR_TAGS;	/* Collapse serial BRs? */
386 BOOLEAN LYDefaultRawMode;
387 BOOLEAN LYListNewsDates = LIST_NEWS_DATES;
388 BOOLEAN LYListNewsNumbers = LIST_NEWS_NUMBERS;
389 BOOLEAN LYMBMBlocked = BLOCK_MULTI_BOOKMARKS;
390 BOOLEAN LYNewsPosting = NEWS_POSTING;	/* News posting supported? */
391 BOOLEAN LYNoFromHeader = TRUE;	/* Never send From header?         */
392 BOOLEAN LYNoRefererForThis = FALSE;	/* No Referer header for this URL? */
393 BOOLEAN LYNoRefererHeader = FALSE;	/* Never send Referer header?     */
394 BOOLEAN LYRawMode;
395 BOOLEAN LYSelectPopups = USE_SELECT_POPUPS;
396 BOOLEAN LYSendUserAgent = SEND_USERAGENT;	/* send Lynx User-Agent header? */
397 BOOLEAN LYSetCookies = SET_COOKIES;	/* Process Set-Cookie headers? */
398 BOOLEAN LYUseDefSelPop = TRUE;	/* Command line -popup toggle */
399 BOOLEAN LYUseDefaultRawMode = TRUE;
400 BOOLEAN LYUseMouse = FALSE;
401 BOOLEAN LYisConfiguredForX = FALSE;
402 BOOLEAN UCForce8bitTOUPPER = FALSE;	/* override locale for case-conversion? */
403 BOOLEAN UCSaveBookmarksInUnicode = FALSE;
404 BOOLEAN bookmark_start = FALSE;
405 BOOLEAN check_realm = FALSE;	/* Restrict to the starting realm? */
406 BOOLEAN clickable_images = MAKE_LINKS_FOR_ALL_IMAGES;
407 BOOLEAN crawl = FALSE;		/* Do crawl? */
408 BOOLEAN keep_mime_headers = FALSE;	/* Include mime headers with source dump */
409 BOOLEAN more_text = FALSE;	/* is there more text to display? */
410 BOOLEAN more_links = FALSE;	/* Links beyond a displayed page with no links? */
411 BOOLEAN no_list = FALSE;
412 BOOLEAN no_margins = FALSE;
413 BOOLEAN no_pause = FALSE;
414 BOOLEAN no_title = FALSE;
415 BOOLEAN no_url_redirection = FALSE;	/* Don't follow URL redirections */
416 BOOLEAN pseudo_inline_alts = MAKE_PSEUDO_ALTS_FOR_INLINES;
417 BOOLEAN scan_for_buried_news_references = TRUE;
418 BOOLEAN startfile_ok = FALSE;
419 static BOOLEAN startfile_stdin = FALSE;
420 BOOLEAN traversal = FALSE;	/* Do traversals? */
421 
422 char *BookmarkPage = NULL;	/* the name of the current bookmark page */
423 char *LYCookieAcceptDomains = NULL;	/* domains to accept all cookies */
424 char *LYCookieLooseCheckDomains = NULL;		/* check loosely   */
425 char *LYCookieQueryCheckDomains = NULL;		/* check w/a query */
426 char *LYCookieRejectDomains = NULL;	/* domains to reject all cookies */
427 char *LYCookieSAcceptDomains = NULL;	/* domains to accept all cookies */
428 char *LYCookieSLooseCheckDomains = NULL;	/* check loosely   */
429 char *LYCookieSQueryCheckDomains = NULL;	/* check w/a query */
430 char *LYCookieSRejectDomains = NULL;	/* domains to reject all cookies */
431 char *LYCookieSStrictCheckDomains = NULL;	/* check strictly  */
432 char *LYCookieStrictCheckDomains = NULL;	/* check strictly  */
433 char *LYHostName = NULL;	/* treat as a local host name */
434 char *LYLocalDomain = NULL;	/* treat as a local domain tail */
435 char *LYUserAgent = NULL;	/* Lynx User-Agent header          */
436 char *LYUserAgentDefault = NULL;	/* Lynx default User-Agent header  */
437 char *LynxHome = NULL;		/* the default Home HREF. */
438 char *LynxSigFile = NULL;	/* Signature file, in or off home */
439 char *UCAssume_MIMEcharset = NULL;
440 char *URLDomainPrefixes = NULL;
441 char *URLDomainSuffixes = NULL;
442 char *anonftp_password = NULL;	/* anonymous ftp password (default: email) */
443 char *authentication_info[2] =
444 {NULL, NULL};			/* Id:Password for protected documents */
445 char *bookmark_page = NULL;	/* the name of the default bookmark page */
446 char *editor = NULL;		/* the name of the current editor */
447 char *form_get_data = NULL;	/* User data for get form */
448 char *form_post_data = NULL;	/* User data for post form */
449 char *global_extension_map = NULL;	/* global mime.types */
450 char *global_type_map = NULL;	/* global mailcap */
451 char *helpfile = NULL;		/* the main help file */
452 char *helpfilepath = NULL;	/* the path to the help file set */
453 char *homepage = NULL;		/* home page or main screen */
454 char *http_error_file = NULL;	/* Place HTTP status code in this file */
455 char *indexfile = NULL;		/* an index file if there is one */
456 char *jumpfile = NULL;		/* the name of the default jumps file */
457 char *jumpprompt = NULL;	/* the default jumps prompt */
458 char *language = NULL;		/* preferred language */
459 char *lynx_cfg_file = NULL;	/* location of active lynx.cfg */
460 char *lynx_cmd_logfile;		/* file to write keystroke commands, if any */
461 char *lynx_cmd_script;		/* file to read keystroke commands, if any */
462 char *lynx_save_space = NULL;	/* The prefix for save to disk paths */
463 char *lynx_temp_space = NULL;	/* The prefix for temporary file paths */
464 char *lynxjumpfile = NULL;	/* the current jump file URL */
465 char *lynxlinksfile = NULL;	/* the current visited links file URL */
466 char *lynxlistfile = NULL;	/* the current list file URL */
467 char *original_dir = NULL;	/* the original directory */
468 char *personal_extension_map = NULL;	/* .mime.types */
469 char *personal_mail_address = NULL;	/* the user's mail address */
470 char *personal_mail_name = NULL;	/* the user's personal name mail */
471 char *personal_type_map = NULL;	/* .mailcap */
472 char *pref_charset = NULL;	/* preferred character set */
473 char *proxyauth_info[2] =
474 {NULL, NULL};			/* Id:Password for protected proxy servers */
475 
476 #ifdef USE_SESSIONS
477 BOOLEAN LYAutoSession = FALSE;	/* enable/disable auto saving/restoring of */
478 
479 				/* session */
480 char *LYSessionFile = NULL;	/* the session file from lynx.cfg */
481 char *session_file = NULL;	/* the current session file */
482 char *sessionin_file = NULL;	/* only resume session from this file */
483 char *sessionout_file = NULL;	/* only save session to this file */
484 short session_limit = 250;	/* maximal number of entries saved per */
485 
486 				/* session file, rest will be ignored */
487 #endif /* USE_SESSIONS */
488 char *startfile = NULL;		/* the first file */
489 char *startrealm = NULL;	/* the startfile realm */
490 char *system_mail = NULL;	/* The path for sending mail */
491 char *system_mail_flags = NULL;	/* Flags for sending mail */
492 char *x_display = NULL;		/* display environment variable */
493 
494 HistInfo *history;
495 int nhist = 0;			/* number of used history entries */
496 int size_history;		/* number of allocated history entries */
497 
498 LinkInfo links[MAXLINKS];
499 
500 BOOLEAN nomore = FALSE;		/* display -more- string in statusline messages */
501 int AlertSecs;			/* time-delay for HTAlert() messages   */
502 int DelaySecs;			/* time-delay for HTProgress messages */
503 int InfoSecs;			/* time-delay for Information messages */
504 int LYMultiBookmarks = MULTI_BOOKMARK_SUPPORT;
505 int LYStatusLine = -1;		/* Line for statusline() if > -1 */
506 int LYcols = DFT_COLS;
507 int LYlines = DFT_ROWS;
508 int MessageSecs;		/* time-delay for important Messages   */
509 int ReplaySecs;			/* time-delay for command-scripts */
510 int crawl_count = 0;		/* Starting number for lnk#.dat files in crawls */
511 int dump_output_width = 0;
512 int dump_server_status = 0;
513 int lynx_temp_subspace = 0;	/* > 0 if we made temp-directory */
514 int max_cookies_domain = 50;
515 int max_cookies_global = 500;
516 int max_cookies_buffer = 4096;
517 int max_uri_size = 8192;
518 int nlinks = 0;			/* number of links in memory */
519 int outgoing_mail_charset = -1;	/* translate mail to this charset */
520 
521 #ifndef DISABLE_BIBP
522 BOOLEAN BibP_bibhost_available = FALSE;		/* until check succeeds  */
523 BOOLEAN BibP_bibhost_checked = FALSE;	/*  until LYCheckBibHost   */
524 BOOLEAN no_goto_bibp = FALSE;
525 char *BibP_bibhost = NULL;	/* local server for bibp: links  */
526 char *BibP_globalserver = NULL;	/* global server for bibp: links */
527 #endif
528 
529 #ifdef USE_PERSISTENT_COOKIES
530 BOOLEAN persistent_cookies = FALSE;	/* disabled by default! */
531 char *LYCookieFile = NULL;	/* cookie read file */
532 char *LYCookieSaveFile = NULL;	/* cookie save file */
533 #endif /* USE_PERSISTENT_COOKIES */
534 
535 #ifdef EXP_NESTED_TABLES
536 BOOLEAN nested_tables =
537 #if defined(USE_COLOR_STYLE)
538 TRUE
539 #else
540 FALSE				/* see 2001-08-15  */
541 #endif
542  ;
543 #endif
544 
545 BOOLEAN LYShowTransferRate = TRUE;
546 int LYTransferRate = rateKB;
547 int LYAcceptEncoding = encodingALL;
548 int LYAcceptMedia = mediaOpt1;
549 char *LYTransferName = NULL;
550 
551 char *XLoadImageCommand = NULL;	/* Default image viewer for X */
552 BOOLEAN LYNoISMAPifUSEMAP = FALSE;	/* Omit ISMAP link if MAP present? */
553 int LYHiddenLinks = HIDDENLINKS_SEPARATE;	/* Show hidden links? */
554 
555 char *SSL_cert_file = NULL;	/* Default CA CERT file */
556 
557 int Old_DTD = NO;
558 static BOOLEAN DTD_recovery = NO;
559 
560 #ifndef NO_LYNX_TRACE
561 FILE *LYTraceLogFP = NULL;	/* Pointer for TRACE log  */
562 #endif
563 char *LYTraceLogPath = NULL;	/* Path for TRACE log      */
564 BOOLEAN LYUseTraceLog = USE_TRACE_LOG;	/* Use a TRACE log?        */
565 
566 BOOLEAN LYSeekFragMAPinCur = TRUE;
567 BOOLEAN LYSeekFragAREAinCur = TRUE;
568 BOOLEAN LYStripDotDotURLs = TRUE;	/* Try to fix ../ in some URLs? */
569 BOOLEAN LYForceSSLCookiesSecure = FALSE;
570 BOOLEAN LYNoCc = FALSE;
571 BOOLEAN LYPreparsedSource = FALSE;	/* Show source as preparsed? */
572 BOOLEAN LYPrependBaseToSource = TRUE;
573 BOOLEAN LYPrependCharsetToSource = TRUE;
574 BOOLEAN LYQuitDefaultYes = QUIT_DEFAULT_YES;
575 BOOLEAN dont_wrap_pre = FALSE;
576 
577 int cookie_noprompt;
578 
579 #ifdef USE_SSL
580 int ssl_noprompt = FORCE_PROMPT_DFT;
581 #endif
582 BOOLEAN conv_jisx0201kana = TRUE;
583 BOOLEAN wait_viewer_termination = FALSE;
584 
585 int connect_timeout = 18000; /*=180000*0.1 - used in HTDoConnect.*/
586 int reading_timeout = 18000; /*=180000*0.1 - used in HTDoConnect.*/
587 
588 #ifdef USE_JUSTIFY_ELTS
589 BOOLEAN ok_justify = FALSE;
590 int justify_max_void_percent = 35;
591 #endif
592 
593 #ifdef USE_LOCALE_CHARSET
594 BOOLEAN LYLocaleCharset = FALSE;
595 #endif
596 
597 #ifndef NO_DUMP_WITH_BACKSPACES
598 BOOLEAN with_backspaces = FALSE;
599 #endif
600 
601 #if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401
602 int scrsize_x = 0;
603 int scrsize_y = 0;
604 #endif
605 
606 BOOLEAN force_empty_hrefless_a = FALSE;
607 
608 #ifdef TEXTFIELDS_MAY_NEED_ACTIVATION
609 BOOL textfields_need_activation = FALSE;
610 BOOLEAN textfields_activation_option = FALSE;
611 #endif
612 
613 BOOLEAN textfield_prompt_at_left_edge = FALSE;
614 
615 #ifdef MARK_HIDDEN_LINKS
616 char *hidden_link_marker = NULL;
617 #endif
618 
619 #ifdef DISP_PARTIAL
620 BOOLEAN display_partial_flag = TRUE;	/* Display document during download */
621 BOOLEAN debug_display_partial = FALSE;	/* Show with MessageSecs delay */
622 int partial_threshold = -1;	/* # of lines to be d/l'ed until we repaint */
623 #endif
624 
625 BOOLEAN LYNonRestartingSIGWINCH = FALSE;
626 BOOLEAN LYReuseTempfiles = FALSE;
627 BOOLEAN LYUseBuiltinSuffixes = TRUE;
628 
629 #ifdef MISC_EXP
630 int LYNoZapKey = 0;		/* 0: off (do z checking), 1: full, 2: initially */
631 #endif
632 
633 #ifndef DISABLE_NEWS
634 #include <HTNews.h>
635 #endif
636 
637 BOOLEAN FileInitAlreadyDone = FALSE;
638 
639 #ifdef USE_PROGRAM_DIR
640 char *program_dir = NULL;
641 #endif
642 
643 static BOOLEAN stack_dump = FALSE;
644 static char *terminal = NULL;
645 static const char *pgm;
646 static BOOLEAN no_numbers = FALSE;
647 static BOOLEAN number_links = FALSE;
648 static BOOLEAN number_fields = FALSE;
649 static BOOLEAN LYPrependBase = FALSE;
650 static HTList *LYStdinArgs = NULL;
651 HTList *positionable_editor = NULL;
652 
653 #ifndef EXTENDED_OPTION_LOGIC
654 /* if set then '--' will be recognized as the end of options */
655 #define EXTENDED_OPTION_LOGIC 1
656 #endif
657 
658 #ifndef EXTENDED_STARTFILE_RECALL
659 /* if set then additional non-option args (before the last one) will be
660    made available for 'g'oto recall - kw */
661 #define EXTENDED_STARTFILE_RECALL 1
662 #endif
663 
664 #if EXTENDED_STARTFILE_RECALL
665 static char *nonoption = 0;
666 #endif
667 
668 #ifndef OPTNAME_ALLOW_DASHES
669 /* if set, then will allow dashes and underscores to be used interchangeable
670    in commandline option's names - VH */
671 #define OPTNAME_ALLOW_DASHES 1
672 #endif
673 
674 static BOOL parse_arg(char **arg, unsigned mask, int *countp);
675 static void print_help_and_exit(int exit_status) GCC_NORETURN;
676 static void print_help_strings(const char *name,
677 			       const char *help,
678 			       const char *value,
679 			       int option);
680 
681 #ifndef VMS
682 BOOLEAN LYNoCore = NO_FORCED_CORE_DUMP;
683 BOOLEAN restore_sigpipe_for_children = FALSE;
684 #if !defined(LYNX_DONT_CATCH_SIGBUS) || \
685     !defined(LYNX_DONT_CATCH_SIGSEGV) || \
686     !defined(LYNX_DONT_CATCH_SIGILL)
687 static void FatalProblem(int sig);
688 #endif
689 #endif /* !VMS */
690 
691 #if defined(USE_COLOR_STYLE)
692 int LYuse_color_style = TRUE;
693 char *lynx_lss_file = NULL;	/* from config-file, etc. */
694 static char *lynx_lss_file2 = NULL;	/* from command-line options */
695 #endif
696 
697 #ifdef USE_DEFAULT_COLORS
698 BOOLEAN LYuse_default_colors = TRUE;
699 #endif
700 
701 #ifdef __DJGPP__
LY_set_ctrl_break(int setting)702 static void LY_set_ctrl_break(int setting)
703 {
704     (void) signal(SIGINT, (setting ? SIG_DFL : SIG_IGN));
705     setcbrk(setting);
706 }
707 
LY_get_ctrl_break(void)708 static int LY_get_ctrl_break(void)
709 {
710     __dpmi_regs regs;
711 
712     regs.h.ah = 0x33;
713     regs.h.al = 0x00;
714     __dpmi_int(0x21, &regs);
715     return ((int) regs.h.dl);
716 }
717 
reset_break(void)718 static void reset_break(void)
719 {
720     LY_set_ctrl_break(init_ctrl_break[0]);
721 }
722 #endif /* __DJGPP__ */
723 
724 #if defined(WIN_EX)
is_windows_nt(void)725 static int is_windows_nt(void)
726 {
727     DWORD version;
728 
729     version = GetVersion();
730     if ((version & 0x80000000) == 0)
731 	return 1;
732     else
733 	return 0;
734 }
735 #endif
736 
737 #ifdef LY_FIND_LEAKS
free_lynx_globals(void)738 static void free_lynx_globals(void)
739 {
740     int i;
741 
742     FREE(ftp_format);
743 #ifndef VMS
744     FREE(list_format);
745 #ifdef LYNXCGI_LINKS		/* WebSter Mods -jkt */
746     FREE(LYCgiDocumentRoot);
747 #endif /* LYNXCGI_LINKS */
748     free_lynx_cfg();
749 #endif /* !VMS */
750 
751 #ifdef SYSLOG_REQUESTED_URLS
752     FREE(syslog_txt);
753 #endif
754 
755 #ifdef VMS
756     Define_VMSLogical("LYNX_VERSION", "");
757 #endif /* VMS */
758 #ifndef VMS
759     FREE(lynx_version_putenv_command);
760 #endif
761 
762 #if USE_VMS_MAILER
763     FREE(mail_adrs);
764 #endif
765 
766     FREE(LynxHome);
767     FREE(history);
768     FREE(homepage);
769     FREE(original_dir);
770     FREE(startfile);
771     FREE(helpfile);
772     FREE(helpfilepath);
773     FREE(jumpprompt);
774 #ifdef JUMPFILE
775     FREE(jumpfile);
776 #endif /* JUMPFILE */
777     FREE(indexfile);
778     FREE(x_display);
779     FREE(global_type_map);
780     FREE(personal_type_map);
781     FREE(global_extension_map);
782     FREE(personal_extension_map);
783     FREE(language);
784     FREE(pref_charset);
785     FREE(LynxSigFile);
786     FREE(system_mail);
787     FREE(system_mail_flags);
788 #ifndef DISABLE_BIBP
789     FREE(BibP_bibhost);
790     FREE(BibP_globalserver);
791 #endif
792 #ifdef USE_PERSISTENT_COOKIES
793     FREE(LYCookieFile);
794     FREE(LYCookieSaveFile);
795 #endif
796     FREE(LYCookieAcceptDomains);
797     FREE(LYCookieRejectDomains);
798     FREE(LYCookieLooseCheckDomains);
799     FREE(LYCookieStrictCheckDomains);
800     FREE(LYCookieQueryCheckDomains);
801     FREE(LYUserAgent);
802     FREE(LYUserAgentDefault);
803     FREE(LYHostName);
804     FREE(LYLocalDomain);
805     FREE(lynx_save_space);
806     FREE(bookmark_page);
807     FREE(BookmarkPage);
808     for (i = 0; i <= MBM_V_MAXFILES; i++) {
809 	FREE(MBM_A_subbookmark[i]);
810 	FREE(MBM_A_subdescript[i]);
811     }
812     FREE(editor);
813     FREE(authentication_info[0]);
814     FREE(authentication_info[1]);
815     FREE(proxyauth_info[0]);
816     FREE(proxyauth_info[1]);
817     FREE(lynxjumpfile);
818 #ifndef DISABLE_FTP
819     FREE(ftp_lasthost);
820     LYFreeStringList(broken_ftp_epsv);
821     LYFreeStringList(broken_ftp_retr);
822 #endif
823     FREE(startrealm);
824     FREE(personal_mail_address);
825     FREE(personal_mail_name);
826     FREE(anonftp_password);
827     FREE(URLDomainPrefixes);
828     FREE(URLDomainSuffixes);
829     FREE(XLoadImageCommand);
830     FREE(lynx_temp_space);
831     FREE(LYTransferName);
832     FREE(LYTraceLogPath);
833     FREE(lynx_cfg_file);
834     FREE(SSL_cert_file);
835 #if defined(USE_COLOR_STYLE)
836     FREE(lynx_lss_file2);
837     FREE(lynx_lss_file);
838 #endif
839     FREE(UCAssume_MIMEcharset);
840     LYUIPages_free();
841     LYFreeHilites(0, nlinks);
842     nlinks = 0;
843     LYFreeStringList(LYcommandList());
844     HTInitProgramPaths(FALSE);
845 #if EXTENDED_STARTFILE_RECALL
846     FREE(nonoption);
847 #endif
848     LYFreeStringList(positionable_editor);
849 
850     return;
851 }
852 #endif /* LY_FIND_LEAKS */
853 
854 /*
855  * This function frees the LYStdinArgs list.  - FM
856  */
LYStdinArgs_free(void)857 static void LYStdinArgs_free(void)
858 {
859     LYFreeStringList(LYStdinArgs);
860     LYStdinArgs = NULL;
861 }
862 
reset_signals(void)863 void reset_signals(void)
864 {
865 #ifndef NOSIGHUP
866     (void) signal(SIGHUP, SIG_DFL);
867 #endif /* NOSIGHUP */
868     (void) signal(SIGTERM, SIG_DFL);
869 #ifndef VMS
870     (void) signal(SIGINT, SIG_DFL);
871 #endif /* !VMS */
872 #ifdef SIGTSTP
873     if (no_suspend)
874 	(void) signal(SIGTSTP, SIG_DFL);
875 #endif /* SIGTSTP */
876 }
877 
exit_immediately(int code)878 void exit_immediately(int code)
879 {
880     reset_signals();
881     exit(code);
882 }
883 
884 #ifdef  EBCDIC
FixCharacters(void)885 static void FixCharacters(void)
886 {
887     int c;
888     int work1[256], work2[256];
889 
890     for (c = 0; c < 256; c++) {
891 	work1[c] = keymap[c + 1];
892 	work2[c] = key_override[c + 1];
893     }
894     for (c = 0; c < 256; c++) {
895 	keymap[IBM1047[c] + 1] = work1[c];
896 	key_override[IBM1047[c] + 1] = work2[c];
897     }
898 }
899 #endif /* EBCDIC */
900 
GetStdin(char ** buf,int marker)901 static BOOL GetStdin(char **buf,
902 		     int marker)
903 {
904     if (LYSafeGets(buf, stdin) != 0
905 	&& (!marker || StrNCmp(*buf, "---", 3) != 0)) {
906 	LYTrimTrailing(*buf);
907 	CTRACE((tfp, "...data: %s\n", *buf));
908 	return TRUE;
909     }
910     CTRACE((tfp, "...mark: %s\n", *buf ? *buf : ""));
911     return FALSE;
912 }
913 
914 #ifdef WIN32
cleanup_win32(DWORD fdwCtrlType)915 static BOOL cleanup_win32(DWORD fdwCtrlType)
916 {
917     switch (fdwCtrlType) {
918     case CTRL_CLOSE_EVENT:
919 	cleanup_sig(-1);
920 	return TRUE;
921     default:
922 	return FALSE;
923     }
924 }
925 #endif
926 
927 /*
928  * Append the SSL version to lynx version or user-agent string.
929  */
930 #ifdef USE_SSL
append_ssl_version(char ** target,const char * separator)931 static void append_ssl_version(char **target,
932 			       const char *separator)
933 {
934     char SSLLibraryVersion[256];
935     char *SSLcp;
936 
937     HTSprintf(target, " SSL-MM%s1.4.1", separator);
938 
939 #undef LYNX_SSL_VERSION
940 
941 #if defined(SSLEAY_VERSION)
942 #define LYNX_SSL_VERSION SSLeay_version(SSLEAY_VERSION)
943 #elif defined(OPENSSL_VERSION_TEXT)
944 #define LYNX_SSL_VERSION OPENSSL_VERSION_TEXT
945 #elif defined(GNUTLS_VERSION)
946 #define LYNX_SSL_VERSION "GNUTLS " GNUTLS_VERSION " "
947 #endif
948 
949 #ifdef LYNX_SSL_VERSION
950     if (*separator == ' ')
951 	StrAllocCat(*target, ",");
952     LYStrNCpy(SSLLibraryVersion, LYNX_SSL_VERSION, sizeof(SSLLibraryVersion) - 1);
953     if ((SSLcp = strchr(SSLLibraryVersion, ' ')) != NULL) {
954 	*SSLcp++ = *separator;
955 	if ((SSLcp = strchr(SSLcp, ' ')) != NULL) {
956 	    *SSLcp = '\0';
957 	    StrAllocCat(*target, " ");
958 	    StrAllocCat(*target, SSLLibraryVersion);
959 	}
960     }
961 #endif /* LYNX_SSL_VERSION */
962 }
963 #endif /* USE_SSL */
964 
965 /* Set the text message domain.  */
LYSetTextDomain(void)966 void LYSetTextDomain(void)
967 {
968 #if defined(HAVE_LIBINTL_H) || defined(HAVE_LIBGETTEXT_H)
969     const char *cp;
970 
971     if ((cp = LYGetEnv("LYNX_LOCALEDIR")) == 0) {
972 #ifdef USE_PROGRAM_DIR
973 	char *localedir = NULL;
974 
975 	HTSprintf0(&localedir, "%s\\locale", program_dir);
976 	cp = localedir;
977 #else
978 	cp = LOCALEDIR;
979 #endif
980     }
981     bindtextdomain(NLS_TEXTDOMAIN, cp);
982     textdomain(NLS_TEXTDOMAIN);
983 #endif
984 }
985 
SetLocale(void)986 static void SetLocale(void)
987 {
988 #ifdef LOCALE
989     /*
990      * LOCALE support for international characters.
991      */
992     setlocale(LC_ALL, "");
993 #endif /* LOCALE */
994     LYSetTextDomain();
995 }
996 
997 /*
998  * Wow!  Someone wants to start up Lynx.
999  */
main(int argc,char ** argv)1000 int main(int argc,
1001 	 char **argv)
1002 {
1003     int i;			/* indexing variable */
1004     int status = 0;		/* exit status */
1005     char *temp = NULL;
1006     const char *ccp;
1007     char *cp;
1008     FILE *fp;
1009     struct stat dir_info;
1010     char filename[LY_MAXPATH];
1011     BOOL LYGetStdinArgs = FALSE;
1012 
1013 #ifdef _WINDOWS
1014     WSADATA WSAData;
1015 #endif /* _WINDOWS */
1016 
1017     /*
1018      * Just in case someone has the idea to install lynx set-uid, let's try
1019      * to discourage it.
1020      */
1021 #if defined(GETUID) && defined(SETUID)
1022     setuid(getuid());
1023 #endif
1024 
1025 #ifdef LY_FIND_LEAKS
1026     /*
1027      * Register the final function to be executed when being exited.  Will
1028      * display memory leaks if the -find-leaks option is used.  This should
1029      * be the first call to atexit() for leak-checking, which ensures that
1030      * all of the other functions will be invoked before LYLeaks().
1031      */
1032     atexit(LYLeaks);
1033     /*
1034      * Register the function which will free our allocated globals.
1035      */
1036     atexit(free_lynx_globals);
1037 #endif /* LY_FIND_LEAKS */
1038 
1039 #ifdef    NOT_ASCII
1040     FixCharacters();
1041 #endif /* NOT_ASCII */
1042 
1043 #ifndef DISABLE_FTP
1044     /* malloc a sizeof(char) so 1st strcmp() won't dump in HTLoadFile() */
1045     ftp_lasthost = typecalloc(char);
1046 #endif
1047 
1048 #ifdef USE_CHARSET_CHOICE
1049     memset((char *) charset_subsets, 0, sizeof(charset_subset_t) * MAXCHARSETS);
1050 #endif
1051 
1052 #ifdef _WINDOWS
1053     {
1054 	int err;
1055 	WORD wVerReq;
1056 
1057 	wVerReq = MAKEWORD(1, 1);
1058 
1059 	err = WSAStartup(wVerReq, &WSAData);
1060 	if (err != 0) {
1061 	    puts(gettext("No Winsock found, sorry."));
1062 	    sleep(5);
1063 	    return 1;
1064 	}
1065     }
1066 
1067     /* 1998/09/03 (Thu) 22:02:32 */
1068     InitializeCriticalSection(&critSec_DNS);
1069     InitializeCriticalSection(&critSec_READ);
1070 
1071 #endif /* _WINDOWS */
1072 
1073 #if defined(WIN_EX)
1074     /* 1997/10/19 (Sun) 21:40:54 */
1075     system_is_NT = (BOOL) is_windows_nt();
1076 
1077     /* 1998/01/13 (Tue) 21:13:47 */
1078     GetWindowsDirectory(filename, sizeof filename);
1079     windows_drive[0] = filename[0];
1080     windows_drive[1] = filename[1];
1081     windows_drive[2] = '\0';
1082 #endif
1083 
1084 #ifdef __DJGPP__
1085     if (LY_get_ctrl_break() == 0) {
1086 	LY_set_ctrl_break(TRUE);
1087 	init_ctrl_break[0] = 0;
1088     } else {
1089 	init_ctrl_break[0] = 1;
1090     }
1091     __djgpp_set_sigquit_key(0x082D);	/* Bind ALT-X to SIGQUIT */
1092     signal(SIGQUIT, cleanup_sig);
1093     atexit(reset_break);
1094 
1095     if (((ccp = LYGetEnv("SHELL")) != NULL)
1096 	&& (strstr(LYPathLeaf(ccp), "sh") != NULL))
1097 	dj_is_bash = TRUE;
1098 #endif /* __DJGPP__ */
1099 
1100     /*
1101      * To prevent corrupting binary data on DOS, MS-WINDOWS or OS/2
1102      * we open files and stdout in BINARY mode by default.
1103      * Where necessary we should open and (close!) TEXT mode.
1104      * (use LYNewTxtFile/LYAppendToTxtFile to open text files for writing)
1105      */
1106     SetDefaultMode(O_BINARY);
1107     SetOutputMode(O_BINARY);
1108 
1109 #ifdef DOSPATH
1110     if (LYGetEnv("TERM") == NULL)
1111 	putenv("TERM=vt100");
1112 #endif
1113 
1114     LYShowColor = (SHOW_COLOR ? SHOW_COLOR_ON : SHOW_COLOR_OFF);
1115     /*
1116      * Set up the argument list.
1117      */
1118     pgm = argv[0];
1119     cp = NULL;
1120 #ifdef USE_PROGRAM_DIR
1121     StrAllocCopy(program_dir, pgm);
1122     if ((cp = strrchr(program_dir, '\\')) != NULL) {
1123 	*cp = '\0';
1124     } else {
1125 	FREE(program_dir);
1126 	StrAllocCopy(program_dir, ".");
1127     }
1128 #endif
1129     if ((cp = LYLastPathSep(pgm)) != NULL) {
1130 	pgm = cp + 1;
1131     }
1132 
1133     /*
1134      * Set up trace, the anonymous account defaults, validate restrictions,
1135      * and/or the nosocks flag, if requested, and an alternate configuration
1136      * file, if specified, NOW.  Also, if we only want the help menu, output
1137      * that and exit.  - FM
1138      */
1139 #ifndef NO_LYNX_TRACE
1140     if (LYGetEnv("LYNX_TRACE") != 0) {
1141 	WWW_TraceFlag = TRUE;
1142     }
1143 #endif
1144 
1145     /*
1146      * Set up the TRACE log path, and logging if appropriate.  - FM
1147      */
1148     if ((ccp = LYGetEnv("LYNX_TRACE_FILE")) == 0)
1149 	ccp = FNAME_LYNX_TRACE;
1150     LYTraceLogPath = typeMallocn(char, LY_MAXPATH);
1151 
1152     LYAddPathToHome(LYTraceLogPath, (size_t) LY_MAXPATH, ccp);
1153 
1154     /*
1155      * Act on -version, -trace and -trace-mask NOW.
1156      */
1157     for (i = 1; i < argc; i++) {
1158 	parse_arg(&argv[i], 1, &i);
1159     }
1160     LYOpenTraceLog();
1161 
1162     SetLocale();
1163 
1164     /*
1165      * Initialize our startup and global variables.
1166      */
1167 #ifdef ULTRIX
1168     /*
1169      * Need this for Ultrix.
1170      */
1171     terminal = LYGetEnv("TERM");
1172     if ((terminal == NULL) || !strncasecomp(terminal, "xterm", 5))
1173 	terminal = "vt100";
1174 #endif /* ULTRIX */
1175     /*
1176      * Zero the links and history struct arrays.
1177      */
1178     memset((void *) links, 0, sizeof(LinkInfo) * MAXLINKS);
1179     LYAllocHistory(8);
1180     /*
1181      * Zero the MultiBookmark arrays.
1182      */
1183     memset((void *) MBM_A_subbookmark, 0, sizeof(char) * (MBM_V_MAXFILES + 1));
1184     memset((void *) MBM_A_subdescript, 0, sizeof(char) * (MBM_V_MAXFILES + 1));
1185 
1186 #ifndef VMS
1187     StrAllocCopy(list_format, LIST_FORMAT);
1188     StrAllocCopy(ftp_format, FTP_FORMAT);
1189 #endif /* !VMS */
1190 
1191     AlertSecs = SECS2Secs(ALERTSECS);
1192     DelaySecs = SECS2Secs(DEBUGSECS);
1193     InfoSecs = SECS2Secs(INFOSECS);
1194     MessageSecs = SECS2Secs(MESSAGESECS);
1195     ReplaySecs = SECS2Secs(REPLAYSECS);
1196 
1197     StrAllocCopy(LYTransferName, "KiB");
1198     StrAllocCopy(helpfile, HELPFILE);
1199     StrAllocCopy(startfile, STARTFILE);
1200     LYEscapeStartfile(&startfile);
1201     StrAllocCopy(indexfile, DEFAULT_INDEX_FILE);
1202     StrAllocCopy(global_type_map, GLOBAL_MAILCAP);
1203     StrAllocCopy(personal_type_map, PERSONAL_MAILCAP);
1204     StrAllocCopy(global_extension_map, GLOBAL_EXTENSION_MAP);
1205     StrAllocCopy(personal_extension_map, PERSONAL_EXTENSION_MAP);
1206     StrAllocCopy(language, PREFERRED_LANGUAGE);
1207     StrAllocCopy(pref_charset, PREFERRED_CHARSET);
1208     StrAllocCopy(system_mail, SYSTEM_MAIL);
1209     StrAllocCopy(system_mail_flags, SYSTEM_MAIL_FLAGS);
1210 
1211     StrAllocCopy(LYUserAgent, LYNX_NAME);
1212     StrAllocCat(LYUserAgent, "/");
1213     StrAllocCat(LYUserAgent, LYNX_VERSION);
1214 #ifdef __MirBSD__
1215     StrAllocCat(LYUserAgent, " (compatible; MirBSD; UNIX)");
1216 #endif
1217     if (HTLibraryVersion) {
1218 	StrAllocCat(LYUserAgent, " libwww-FM/");
1219 	StrAllocCat(LYUserAgent, HTLibraryVersion);
1220     }
1221 #ifdef USE_SSL
1222     append_ssl_version(&LYUserAgent, "/");
1223 #endif /* USE_SSL */
1224     StrAllocCopy(LYUserAgentDefault, LYUserAgent);
1225 
1226 #ifdef VMS
1227     Define_VMSLogical("LYNX_VERSION", LYNX_VERSION);
1228 #else
1229     StrAllocCopy(lynx_version_putenv_command, "LYNX_VERSION=");
1230     StrAllocCat(lynx_version_putenv_command, LYNX_VERSION);
1231     (void) putenv(lynx_version_putenv_command);
1232     /* Note: you must not free the data passed to 'putenv()' until you give it
1233      * a new value for that variable.
1234      */
1235 #endif /* VMS */
1236 
1237     if ((ccp = LYGetEnv("LYNX_TEMP_SPACE")) != NULL)
1238 	StrAllocCopy(lynx_temp_space, ccp);
1239 #if defined (UNIX) || defined (__DJGPP__)
1240     else if ((ccp = LYGetEnv("TMPDIR")) != NULL)
1241 	StrAllocCopy(lynx_temp_space, ccp);
1242 #endif
1243 #if defined (DOSPATH) || defined (__EMX__)
1244     else if ((ccp = LYGetEnv("TEMP")) != NULL)
1245 	StrAllocCopy(lynx_temp_space, ccp);
1246     else if ((ccp = LYGetEnv("TMP")) != NULL)
1247 	StrAllocCopy(lynx_temp_space, ccp);
1248 #endif
1249     else {
1250 #if defined(USE_PROGRAM_DIR)
1251 	StrAllocCopy(lynx_temp_space, program_dir);
1252 #elif defined(TEMP_SPACE)
1253 	StrAllocCopy(lynx_temp_space, TEMP_SPACE);
1254 #else
1255 	puts(gettext("You MUST define a valid TMP or TEMP area!"));
1256 	exit_immediately(EXIT_FAILURE);
1257 #endif
1258     }
1259 
1260 #ifdef WIN_EX			/* for Windows 2000 ... 1999/08/23 (Mon) 08:24:35 */
1261     if (access(lynx_temp_space, 0) != 0)
1262 #endif
1263 	LYTildeExpand(&lynx_temp_space, TRUE);
1264 
1265     if ((cp = strstr(lynx_temp_space, "$USER")) != NULL) {
1266 	char *cp1;
1267 
1268 	if ((cp1 = LYGetEnv("USER")) != NULL) {
1269 	    *cp = '\0';
1270 	    StrAllocCopy(temp, lynx_temp_space);
1271 	    *cp = '$';
1272 	    StrAllocCat(temp, cp1);
1273 	    cp += 5;
1274 	    StrAllocCat(temp, cp);
1275 	    StrAllocCopy(lynx_temp_space, temp);
1276 	    FREE(temp);
1277 	}
1278     }
1279 #ifdef VMS
1280     LYLowerCase(lynx_temp_space);
1281     if (strchr(lynx_temp_space, '/') != NULL) {
1282 	if (strlen(lynx_temp_space) == 1) {
1283 	    StrAllocCopy(lynx_temp_space, "sys$scratch:");
1284 	} else {
1285 	    LYAddPathSep(&lynx_temp_space);
1286 	    StrAllocCopy(temp, HTVMS_name("", lynx_temp_space));
1287 	    StrAllocCopy(lynx_temp_space, temp);
1288 	    FREE(temp);
1289 	}
1290     }
1291     if (strchr(lynx_temp_space, ':') == NULL &&
1292 	strchr(lynx_temp_space, ']') == NULL) {
1293 	StrAllocCat(lynx_temp_space, ":");
1294     }
1295 #else
1296     LYAddPathSep(&lynx_temp_space);
1297     StrAllocCopy(lynx_temp_space, HTSYS_name(lynx_temp_space));
1298 #endif /* VMS */
1299 
1300     if ((HTStat(lynx_temp_space, &dir_info) < 0
1301 #if defined(MULTI_USER_UNIX)
1302 	 && mkdir(lynx_temp_space, 0700) < 0
1303 #endif
1304 	)
1305 	|| !S_ISDIR(dir_info.st_mode)) {
1306 	fprintf(stderr, "%s: %s\n",
1307 		lynx_temp_space,
1308 		gettext("No such directory"));
1309 	exit_immediately(EXIT_FAILURE);
1310     }
1311 #if USE_VMS_MAILER
1312 #ifndef MAIL_ADRS
1313 #define MAIL_ADRS "\"IN%%\"\"%s\"\"\""
1314 #endif
1315     StrAllocCopy(mail_adrs, MAIL_ADRS);
1316 #endif
1317 
1318 #ifdef LYNX_HOST_NAME
1319     StrAllocCopy(LYHostName, LYNX_HOST_NAME);
1320 #else
1321     StrAllocCopy(LYHostName, HTHostName());
1322 #endif /* LYNX_HOST_NAME */
1323 
1324     StrAllocCopy(LYLocalDomain, LOCAL_DOMAIN);
1325     StrAllocCopy(URLDomainPrefixes, URL_DOMAIN_PREFIXES);
1326     StrAllocCopy(URLDomainSuffixes, URL_DOMAIN_SUFFIXES);
1327     StrAllocCopy(XLoadImageCommand, XLOADIMAGE_COMMAND);
1328     StrAllocCopy(SSL_cert_file, SSL_CERT_FILE);
1329 
1330 #ifndef DISABLE_BIBP
1331     StrAllocCopy(BibP_globalserver, BIBP_GLOBAL_SERVER);
1332     StrAllocCopy(BibP_bibhost, "http://bibhost/");	/* protocol specified. */
1333 #endif
1334 
1335     /*
1336      * Disable news posting if the compilation-based LYNewsPosting value is
1337      * FALSE.  This may be changed further down via lynx.cfg or the
1338      * -restriction command line switch.  - FM
1339      */
1340 #ifndef DISABLE_NEWS
1341     no_newspost = (BOOL) (LYNewsPosting == FALSE);
1342 #endif
1343 
1344     for (i = 1; i < argc; i++) {
1345 	parse_arg(&argv[i], 2, &i);
1346     }
1347 
1348     /*
1349      * If we have a lone "-" switch for getting arguments from stdin, get them
1350      * NOW, and act on the relevant ones, saving the others into an HTList for
1351      * handling after the other initializations.  The primary purpose of this
1352      * feature is to allow for the potentially very long command line that can
1353      * be associated with post or get data.  The original implementation
1354      * required that the lone "-" be the only command line argument, but that
1355      * precluded its use when the lynx command is aliased with other arguments.
1356      * When interactive, the stdin input is terminated by by Control-D on Unix
1357      * or Control-Z on VMS, and each argument is terminated by a RETURN.  When
1358      * the argument is -get_data or -post_data, the data are terminated by a
1359      * "---" string, alone on the line (also terminated by RETURN).  - FM
1360      */
1361     for (i = 1; i < argc; i++) {
1362 	if (strcmp(argv[i], "-") == 0) {
1363 	    LYGetStdinArgs = TRUE;
1364 	    break;
1365 	}
1366     }
1367     if (LYGetStdinArgs == TRUE) {
1368 	char *buf = NULL;
1369 
1370 	CTRACE((tfp, "processing stdin arguments\n"));
1371 	while (GetStdin(&buf, TRUE)) {
1372 	    char *noargv[2];
1373 
1374 	    noargv[0] = buf;
1375 	    noargv[1] = NULL;
1376 	    LYTrimTrailing(buf);
1377 
1378 	    if (parse_arg(&noargv[0], 2, (int *) 0) == FALSE
1379 		&& buf[0] != '\0') {
1380 		char *argument = NULL;
1381 
1382 		if (LYStdinArgs == NULL) {
1383 		    LYStdinArgs = HTList_new();
1384 #ifdef LY_FIND_LEAKS
1385 		    atexit(LYStdinArgs_free);
1386 #endif
1387 		}
1388 		StrAllocCopy(argument, buf);
1389 		HTList_appendObject(LYStdinArgs, argument);
1390 		CTRACE((tfp, "...StdinArg:%s\n", argument));
1391 	    } else {
1392 		CTRACE((tfp, "...complete:%s\n", buf));
1393 	    }
1394 	}
1395 	CTRACE((tfp, "...done with stdin arguments\n"));
1396 	FREE(buf);
1397     }
1398 #ifdef SOCKS
1399     if (socks_flag)
1400 	SOCKSinit(argv[0]);
1401 #endif /* SOCKS */
1402 
1403     /*
1404      * If we had -validate set all of the restrictions and disallow a TRACE log
1405      * NOW.  - FM
1406      */
1407     if (LYValidate == TRUE) {
1408 	parse_restrictions("all");
1409 	LYUseTraceLog = FALSE;
1410     }
1411 
1412     /*
1413      * If we didn't get and act on a -validate or -anonymous switch, but can
1414      * verify that this is the anonymous account, set the default restrictions
1415      * for that account and disallow a TRACE log NOW.  - FM
1416      */
1417     if (!LYValidate && !LYRestricted &&
1418 	strlen(ANONYMOUS_USER) > 0 &&
1419 #if defined (VMS) || defined (NOUSERS)
1420 	!strcasecomp((LYGetEnv("USER") == NULL ? " " : LYGetEnv("USER")),
1421 		     ANONYMOUS_USER)
1422 #else
1423 #ifdef HAVE_CUSERID
1424 	STREQ((char *) cuserid((char *) NULL), ANONYMOUS_USER)
1425 #else
1426 	STREQ(((char *) getlogin() == NULL ? " " : getlogin()), ANONYMOUS_USER)
1427 #endif /* HAVE_CUSERID */
1428 #endif /* VMS */
1429 	) {
1430 	parse_restrictions("default");
1431 	LYRestricted = TRUE;
1432 	LYUseTraceLog = FALSE;
1433     }
1434 #ifdef USE_CMD_LOGGING
1435     /*
1436      * Open command-script, if specified
1437      */
1438     if (lynx_cmd_script != 0) {
1439 	LYTildeExpand(&lynx_cmd_script, TRUE);
1440 	LYOpenCmdScript();
1441     }
1442     /*
1443      * Open command-logging, if specified
1444      */
1445     if (lynx_cmd_logfile != 0) {
1446 	LYTildeExpand(&lynx_cmd_logfile, TRUE);
1447 	LYOpenCmdLogfile(argc, argv);
1448     }
1449 #endif
1450 
1451     /*
1452      * Set up the default jump file stuff.  - FM
1453      */
1454     StrAllocCopy(jumpprompt, JUMP_PROMPT);
1455 #ifdef JUMPFILE
1456     StrAllocCopy(jumpfile, JUMPFILE);
1457     {
1458 	temp = NULL;
1459 	HTSprintf0(&temp, "JUMPFILE:%s", jumpfile);
1460 	if (!LYJumpInit(temp)) {
1461 	    CTRACE((tfp, "Failed to register %s\n", temp));
1462 	}
1463 	FREE(temp);
1464     }
1465 #endif /* JUMPFILE */
1466 
1467     /*
1468      * If no alternate configuration file was specified on the command line,
1469      * see if it's in the environment.
1470      */
1471     if (!lynx_cfg_file) {
1472 	if (((cp = LYGetEnv("LYNX_CFG")) != NULL) ||
1473 	    (cp = LYGetEnv("lynx_cfg")) != NULL)
1474 	    StrAllocCopy(lynx_cfg_file, cp);
1475     }
1476 #ifdef USE_PROGRAM_DIR
1477     if (!lynx_cfg_file) {
1478 	HTSprintf0(&lynx_cfg_file, "%s\\lynx.cfg", program_dir);
1479 	if (!LYCanReadFile(lynx_cfg_file)) {
1480 	    FREE(lynx_cfg_file);
1481 	    lynx_cfg_file = NULL;
1482 	}
1483     }
1484 #endif
1485 
1486     /*
1487      * If we still don't have a configuration file, use the userdefs.h
1488      * definition.
1489      */
1490     if (!lynx_cfg_file)
1491 	StrAllocCopy(lynx_cfg_file, LYNX_CFG_FILE);
1492 
1493 #ifndef _WINDOWS		/* avoid the whole ~ thing for now */
1494     LYTildeExpand(&lynx_cfg_file, FALSE);
1495 #endif
1496 
1497     /*
1498      * If the configuration file is not available, inform the user and exit.
1499      */
1500     if (!LYCanReadFile(lynx_cfg_file)) {
1501 	fprintf(stderr,
1502 		gettext("\nConfiguration file \"%s\" is not available.\n\n"),
1503 		lynx_cfg_file);
1504 	exit_immediately(EXIT_FAILURE);
1505     }
1506 
1507     /*
1508      * Make sure we have the character sets declared.  This will initialize the
1509      * CHARTRANS handling.  - KW
1510      */
1511     if (!LYCharSetsDeclared()) {
1512 	fprintf(stderr, gettext("\nLynx character sets not declared.\n\n"));
1513 	exit_immediately(EXIT_FAILURE);
1514     }
1515     /*
1516      * (**) in Lynx, UCLYhndl_HTFile_for_unspec and UCLYhndl_for_unrec may be
1517      * valid or not, but current_char_set and UCLYhndl_for_unspec SHOULD ALWAYS
1518      * be a valid charset.  Initialized here and may be changed later from
1519      * lynx.cfg/command_line/options_menu.  - LP (**)
1520      */
1521     /*
1522      * Set up the compilation default character set.  - FM
1523      */
1524 #ifdef CAN_AUTODETECT_DISPLAY_CHARSET
1525     if (auto_display_charset >= 0)
1526 	current_char_set = auto_display_charset;
1527     else
1528 #endif
1529 	current_char_set = safeUCGetLYhndl_byMIME(CHARACTER_SET);
1530     /*
1531      * Set up HTTP default for unlabeled charset (iso-8859-1).
1532      */
1533     UCLYhndl_for_unspec = LATIN1;
1534     StrAllocCopy(UCAssume_MIMEcharset,
1535 		 LYCharSet_UC[UCLYhndl_for_unspec].MIMEname);
1536 
1537     /*
1538      * Make sure we have the edit map declared.  - FM
1539      */
1540     if (!LYEditmapDeclared()) {
1541 	fprintf(stderr, gettext("\nLynx edit map not declared.\n\n"));
1542 	exit_immediately(EXIT_FAILURE);
1543     }
1544 #ifdef USE_COLOR_TABLE
1545     /*
1546      * Set up default foreground and background colors.
1547      */
1548     lynx_setup_colors();
1549 #endif /* USE_COLOR_TABLE */
1550 
1551     /*
1552      * Set the original directory, used for default download
1553      */
1554     if (!strcmp(Current_Dir(filename), ".")) {
1555 	if ((cp = LYGetEnv("PWD")) != 0)
1556 	    StrAllocCopy(original_dir, cp);
1557     } else {
1558 	StrAllocCopy(original_dir, filename);
1559     }
1560 
1561     /*
1562      * Set the compilation default signature file.  - FM
1563      */
1564     LYStrNCpy(filename, LYNX_SIG_FILE, sizeof(filename) - 1);
1565     if (LYPathOffHomeOK(filename, sizeof(filename))) {
1566 	StrAllocCopy(LynxSigFile, filename);
1567 	LYAddPathToHome(filename, sizeof(filename), LynxSigFile);
1568 	StrAllocCopy(LynxSigFile, filename);
1569 	CTRACE((tfp, "LYNX_SIG_FILE set to '%s'\n", LynxSigFile));
1570     } else {
1571 	CTRACE((tfp, "LYNX_SIG_FILE '%s' is bad. Ignoring.\n", LYNX_SIG_FILE));
1572     }
1573 
1574 #ifdef USE_PRETTYSRC
1575     /*this is required for checking the tagspecs when parsing cfg file by
1576        LYReadCFG.c:parse_html_src_spec -HV */
1577     HTSwitchDTD(TRUE);
1578 #endif
1579     /*
1580      * Process the configuration file.
1581      */
1582     read_cfg(lynx_cfg_file, "main program", 1, (FILE *) 0);
1583 
1584 #if defined(USE_COLOR_STYLE)
1585     if (!dump_output_immediately) {
1586 	/*
1587 	 * A command-line "-lss" always overrides the config-file, even if it is
1588 	 * an empty string such as -lss="".
1589 	 */
1590 	if (lynx_lss_file2 != 0) {
1591 	    FREE(lynx_lss_file);
1592 	    lynx_lss_file = lynx_lss_file2;
1593 	    lynx_lss_file2 = 0;
1594 	}
1595 
1596 	/*
1597 	 * If no alternate lynx-style file was specified on the command line, see
1598 	 * if it's in the environment.
1599 	 */
1600 	if (!lynx_lss_file) {
1601 	    if (((cp = LYGetEnv("LYNX_LSS")) != NULL) ||
1602 		(cp = LYGetEnv("lynx_lss")) != NULL)
1603 		StrAllocCopy(lynx_lss_file, cp);
1604 	}
1605 
1606 	/*
1607 	 * If we still don't have a lynx-style file, use the userdefs.h definition.
1608 	 */
1609 	if (!lynx_lss_file)
1610 	    StrAllocCopy(lynx_lss_file, LYNX_LSS_FILE);
1611 
1612 	LYTildeExpand(&lynx_lss_file, TRUE);
1613 #ifdef USE_PROGRAM_DIR
1614 	if (!isEmpty(lynx_lss_file) && !LYCanReadFile(lynx_lss_file)) {
1615 	    HTSprintf0(&lynx_lss_file, "%s\\lynx.lss", program_dir);
1616 	}
1617 #endif
1618 
1619 	/*
1620 	 * If the lynx-style file is not available, inform the user and exit.
1621 	 */
1622 	if (non_empty(lynx_lss_file) && !LYCanReadFile(lynx_lss_file)) {
1623 	    fprintf(stderr, gettext("\nLynx file \"%s\" is not available.\n\n"),
1624 		    lynx_lss_file);
1625 	    exit_immediately(EXIT_FAILURE);
1626 	} else {
1627 	    style_readFromFile(lynx_lss_file);
1628 	}
1629     }
1630 #endif /* USE_COLOR_STYLE */
1631 
1632     /*
1633      * Process the RC file.
1634      */
1635     read_rc(NULL);
1636 
1637 #ifdef USE_LOCALE_CHARSET
1638     LYFindLocaleCharset();
1639 #endif
1640 
1641     /*
1642      * Get WWW_HOME environment variable if it exists.
1643      */
1644     if ((cp = LYGetEnv("WWW_HOME")) != NULL) {
1645 	StrAllocCopy(startfile, cp);
1646 	LYEscapeStartfile(&startfile);
1647     }
1648 
1649     /*
1650      * Set the LynxHome URL.  If it's a file URL and the
1651      * host is defaulted, force in "//localhost", and if
1652      * it's not an absolute URL, make it one. - FM
1653      */
1654     StrAllocCopy(LynxHome, startfile);
1655     LYEnsureAbsoluteURL(&LynxHome, "LynxHome", FALSE);
1656 
1657     /*
1658      * Process any command line arguments not already handled.  - FM
1659      * May set startfile as a side-effect.
1660      */
1661     for (i = 1; i < argc; i++) {
1662 	parse_arg(&argv[i], 4, &i);
1663     }
1664 
1665     /*
1666      * Process any stdin-derived arguments for a lone "-" which we've loaded
1667      * into LYStdinArgs.  - FM
1668      */
1669     if (LYStdinArgs != NULL) {
1670 	char *my_args[2];
1671 	HTList *cur = LYStdinArgs;
1672 
1673 	my_args[1] = NULL;
1674 	while (NULL != (my_args[0] = (char *) HTList_nextObject(cur))) {
1675 	    parse_arg(my_args, 4, (int *) 0);
1676 	}
1677 	LYStdinArgs_free();
1678     }
1679 #ifdef HAVE_TTYNAME
1680     /*
1681      * If the input is not a tty, we are either running in cron, or are
1682      * getting input via a pipe:
1683      *
1684      * a) in cron, none of stdin/stdout/stderr are ttys.
1685      * b) from a pipe, we should have either "-" or "-stdin" options.
1686      */
1687     if (!LYGetStdinArgs
1688 	&& !startfile_stdin
1689 	&& !isatty(fileno(stdin))
1690 	&& (isatty(fileno(stdout) || isatty(fileno(stderr))))) {
1691 	int ignored = 0;
1692 
1693 	while (fgetc(stdin) != EOF) {
1694 	    ++ignored;
1695 	}
1696 	if (ignored) {
1697 	    fprintf(stderr,
1698 		    gettext("Ignored %d characters from standard input.\n"), ignored);
1699 	    fprintf(stderr,
1700 		    gettext("Use \"-stdin\" or \"-\" to tell how to handle piped input.\n"));
1701 	}
1702     }
1703 #endif /* HAVE_TTYNAME */
1704 
1705 #ifdef CAN_SWITCH_DISPLAY_CHARSET
1706     if (current_char_set == auto_display_charset)	/* Better: explicit option */
1707 	switch_display_charsets = 1;
1708 #endif
1709 
1710 #if defined (TTY_DEVICE) || defined(HAVE_TTYNAME)
1711     /*
1712      * If we are told to read the startfile from standard input, do it now,
1713      * after we have read all of the option data from standard input.
1714      * Later we'll use LYReopenInput().
1715      */
1716     if (startfile_stdin) {
1717 	char result[LY_MAXPATH];
1718 	char *buf = NULL;
1719 
1720 	CTRACE((tfp, "processing stdin startfile\n"));
1721 	if ((fp = LYOpenTemp(result, HTML_SUFFIX, "w")) != 0) {
1722 	    StrAllocCopy(startfile, result);
1723 	    while (GetStdin(&buf, FALSE)) {
1724 		fputs(buf, fp);
1725 		fputc('\n', fp);
1726 	    }
1727 	    FREE(buf);
1728 	    LYCloseTempFP(fp);
1729 	}
1730 	CTRACE((tfp, "...done stdin startfile\n"));
1731     }
1732 #endif
1733 
1734     /*
1735      * Initialize other things based on the configuration read.
1736      */
1737 
1738 #ifdef USE_PRETTYSRC
1739     if ((!Old_DTD) != TRUE)	/* skip if they are already initialized -HV */
1740 #endif
1741 	HTSwitchDTD(!Old_DTD);
1742 
1743     /*
1744      * Set up the proper character set with the desired
1745      * startup raw 8-bit or CJK mode handling.  - FM
1746      */
1747     HTMLUseCharacterSet(current_char_set);
1748 
1749 #ifdef USE_PERSISTENT_COOKIES
1750     /*
1751      * Sod it, this looks like a reasonable place to load the
1752      * cookies file, probably.  - RP
1753      *
1754      * And to set LYCookieSaveFile. - BJP
1755      */
1756     if (persistent_cookies) {
1757 	if (LYCookieFile == NULL) {
1758 	    LYCookieFile = typeMallocn(char, LY_MAXPATH);
1759 
1760 	    LYAddPathToHome(LYCookieFile, (size_t) LY_MAXPATH, FNAME_LYNX_COOKIES);
1761 	} else {
1762 	    LYTildeExpand(&LYCookieFile, FALSE);
1763 	}
1764 	LYLoadCookies(LYCookieFile);
1765     }
1766 
1767     /* tilde-expand LYCookieSaveFile */
1768     if (LYCookieSaveFile != NULL) {
1769 	LYTildeExpand(&LYCookieSaveFile, FALSE);
1770     }
1771 #ifdef USE_PROGRAM_DIR
1772     if (is_url(helpfile) == 0) {
1773 	char *tmp = NULL;
1774 
1775 	HTSprintf0(&tmp, "%s\\%s", program_dir, helpfile);
1776 	FREE(helpfile);
1777 	LYLocalFileToURL(&helpfile, tmp);
1778 	FREE(tmp);
1779     }
1780 #endif
1781 
1782     /*
1783      * In dump_output_immediately mode, LYCookieSaveFile defaults to
1784      * /dev/null, otherwise it defaults to LYCookieFile.
1785      */
1786 
1787     if (LYCookieSaveFile == NULL) {
1788 	if (dump_output_immediately) {
1789 	    StrAllocCopy(LYCookieSaveFile, "/dev/null");
1790 	} else {
1791 	    StrAllocCopy(LYCookieSaveFile, LYCookieFile);
1792 	}
1793     }
1794 #endif
1795 
1796     /*
1797      * Check for a help file URL in the environment. Overiding
1798      * compiled-in default and configuration file setting, if found.
1799      */
1800     if ((cp = LYGetEnv("LYNX_HELPFILE")) != NULL)
1801 	StrAllocCopy(helpfile, cp);
1802 
1803     /*
1804      * Set up our help and about file base paths. - FM
1805      */
1806     StrAllocCopy(helpfilepath, helpfile);
1807     if ((cp = LYPathLeaf(helpfilepath)) != helpfilepath)
1808 	*cp = '\0';
1809     LYAddHtmlSep(&helpfilepath);
1810 
1811     /*
1812      * Check for a save space path in the environment.  If one was set in the
1813      * configuration file, that one will be overridden.  - FM
1814      */
1815     if ((cp = LYGetEnv("LYNX_SAVE_SPACE")) != NULL)
1816 	StrAllocCopy(lynx_save_space, cp);
1817 
1818     /*
1819      * We have a save space path, make sure it's valid.  - FM
1820      */
1821     if (lynx_save_space && *lynx_save_space == '\0') {
1822 	FREE(lynx_save_space);
1823     }
1824     if (lynx_save_space) {
1825 	LYTildeExpand(&lynx_save_space, TRUE);
1826 #ifdef VMS
1827 	LYLowerCase(lynx_save_space);
1828 	if (strchr(lynx_save_space, '/') != NULL) {
1829 	    if (strlen(lynx_save_space) == 1) {
1830 		StrAllocCopy(lynx_save_space, "sys$login:");
1831 	    } else {
1832 		LYAddPathSep(&lynx_save_space);
1833 		StrAllocCopy(temp, HTVMS_name("", lynx_save_space));
1834 		StrAllocCopy(lynx_save_space, temp);
1835 		FREE(temp);
1836 	    }
1837 	}
1838 	if (strchr(lynx_save_space, ':') == NULL &&
1839 	    strchr(lynx_save_space, ']') == NULL) {
1840 	    StrAllocCat(lynx_save_space, ":");
1841 	}
1842 #else
1843 	LYAddPathSep(&lynx_save_space);
1844 #endif /* VMS */
1845     }
1846 
1847     /*
1848      * Set up the file extension and mime type maps from src/HTInit.c and the
1849      * global and personal mime.types and mailcap files.  These will override
1850      * any SUFFIX or VIEWER maps in userdefs.h or the configuration file, if
1851      * they overlap.
1852      */
1853     HTFormatInit();
1854     if (!FileInitAlreadyDone)
1855 	HTFileInit();
1856 
1857     if (!LYCheckUserAgent()) {
1858 	HTAlwaysAlert(gettext("Warning:"), UA_NO_LYNX_WARNING);
1859     }
1860     if (show_cfg) {
1861 	cleanup();
1862 	exit_immediately(EXIT_SUCCESS);
1863     }
1864 #ifdef USE_SLANG
1865     if (LYShowColor >= SHOW_COLOR_ON &&
1866 	!(Lynx_Color_Flags & SL_LYNX_USE_COLOR)) {
1867 	Lynx_Color_Flags |= SL_LYNX_USE_COLOR;
1868     } else if ((Lynx_Color_Flags & SL_LYNX_USE_COLOR) ||
1869 	       LYGetEnv("COLORTERM") != NULL) {
1870 	if (LYShowColor != SHOW_COLOR_NEVER &&
1871 	    LYShowColor != SHOW_COLOR_ALWAYS) {
1872 	    LYShowColor = SHOW_COLOR_ON;
1873 	}
1874     }
1875 #endif /* USE_SLANG */
1876 
1877     if (LYPreparsedSource) {
1878 	HTPreparsedFormatInit();
1879     }
1880 #if defined(EXEC_LINKS) || defined(EXEC_SCRIPTS)
1881 #ifdef NEVER_ALLOW_REMOTE_EXEC
1882     if (local_exec) {
1883 	local_exec = FALSE;
1884 	local_exec_on_local_files = TRUE;
1885     }
1886 #endif /* NEVER_ALLOW_REMOTE_EXEC */
1887 #endif /* EXEC_LINKS || EXEC_SCRIPTS */
1888 
1889     if (emacs_keys)
1890 	set_emacs_keys();
1891 
1892     if (vi_keys)
1893 	set_vi_keys();
1894 
1895     if (no_numbers) {
1896 	number_links = FALSE;
1897 	number_fields = FALSE;
1898 	keypad_mode = NUMBERS_AS_ARROWS;
1899 	set_numbers_as_arrows();
1900     }
1901 
1902     if (crawl) {
1903 	/* No numbered links by default, as documented
1904 	   in CRAWL.announce. - kw */
1905 	if (!number_links) {
1906 	    keypad_mode = NUMBERS_AS_ARROWS;
1907 	}
1908     }
1909 
1910     if (!links_are_numbered()) {
1911 	if (number_fields)
1912 	    keypad_mode = LINKS_AND_FIELDS_ARE_NUMBERED;
1913 	if (number_links)
1914 	    keypad_mode = LINKS_ARE_NUMBERED;
1915 	set_numbers_as_arrows();
1916     }
1917 
1918     /*
1919      * Check the -popup command line toggle.  - FM
1920      */
1921     if (LYUseDefSelPop == FALSE) {
1922 	LYSelectPopups = (BOOLEAN) !LYSelectPopups;
1923     }
1924 
1925     /*
1926      * Check the -show_cursor command line toggle.  - FM
1927      */
1928     if (LYUseDefShoCur == FALSE) {
1929 	LYShowCursor = (BOOLEAN) !LYShowCursor;
1930     }
1931 
1932     /*
1933      * Check the -base command line switch with -source.  - FM
1934      */
1935     if (LYPrependBase && HTOutputFormat == HTAtom_for("www/download")) {
1936 	LYPrependBaseToSource = TRUE;
1937     }
1938 
1939     /*
1940      * Disable multiple bookmark support if not interactive, so it doesn't
1941      * crash on curses functions, or if the support was blocked via userdefs.h
1942      * and/or lynx.cfg, or via command line restrictions.  - FM
1943      */
1944     if (no_multibook)
1945 	LYMBMBlocked = TRUE;
1946     if (dump_output_immediately || LYMBMBlocked || no_multibook) {
1947 	LYMultiBookmarks = MBM_OFF;
1948 	LYMBMBlocked = TRUE;
1949 	no_multibook = TRUE;
1950     }
1951 #ifdef USE_SOURCE_CACHE
1952     /*
1953      * Disable source caching if not interactive.
1954      */
1955     if (dump_output_immediately)
1956 	LYCacheSource = SOURCE_CACHE_NONE;
1957 #endif
1958 #ifdef DISP_PARTIAL
1959     /*
1960      * Disable partial mode if not interactive.
1961      */
1962     if (dump_output_immediately)
1963 	display_partial_flag = FALSE;
1964 #endif
1965 
1966 #ifdef VMS
1967     set_vms_keys();
1968 #endif /* VMS */
1969 
1970 #if defined (__DJGPP__)
1971     if (watt_debug)
1972 	dbug_init();
1973     sock_init();
1974 
1975     __system_flags =
1976 	__system_emulate_chdir |	/* handle `cd' internally */
1977 	__system_handle_null_commands |		/* ignore cmds with no effect */
1978 	__system_allow_long_cmds |	/* handle commands > 126 chars   */
1979 	__system_use_shell |	/* use $SHELL if set */
1980 	__system_allow_multiple_cmds |	/* allow `cmd1; cmd2; ...' */
1981 	__system_redirect;	/* redirect internally */
1982 
1983     /* This speeds up stat() tremendously */
1984     _djstat_flags |= _STAT_INODE | _STAT_EXEC_MAGIC | _STAT_DIRSIZE;
1985 #endif /* __DJGPP__ */
1986 
1987     /* trap interrupts */
1988 #ifdef WIN32
1989     SetConsoleCtrlHandler((PHANDLER_ROUTINE) cleanup_win32, TRUE);
1990 #endif
1991 
1992 #ifndef NOSIGHUP
1993     if (!dump_output_immediately)
1994 	(void) signal(SIGHUP, cleanup_sig);
1995 #endif /* NOSIGHUP */
1996 
1997     (void) signal(SIGTERM, cleanup_sig);
1998 #ifdef SIGWINCH
1999     LYExtSignal(SIGWINCH, size_change);
2000 #endif /* SIGWINCH */
2001 #ifndef VMS
2002     if (!TRACE && !dump_output_immediately && !stack_dump) {
2003 	(void) signal(SIGINT, cleanup_sig);
2004 #ifndef __linux__
2005 #ifdef SIGBUS
2006 #ifndef LYNX_DONT_CATCH_SIGBUS
2007 	(void) signal(SIGBUS, FatalProblem);
2008 #endif
2009 #endif /* SIGBUS */
2010 #endif /* !__linux__ */
2011 #ifndef LYNX_DONT_CATCH_SIGSEGV
2012 	(void) signal(SIGSEGV, FatalProblem);
2013 #endif
2014 #ifndef LYNX_DONT_CATCH_SIGILL
2015 	(void) signal(SIGILL, FatalProblem);
2016 #endif
2017 	/*
2018 	 * Since we're doing lots of TCP, just ignore SIGPIPE altogether.
2019 	 *
2020 	 * HTTCP.c should deal with a broken pipe for servers.  Rick Mallet's
2021 	 * check after c = GetChar() in LYStrings.c should deal with a
2022 	 * disconnected terminal.  So the runaway CPU time problem on Unix
2023 	 * should not occur any more.
2024 	 */
2025 #ifdef SIGPIPE
2026 	if (signal(SIGPIPE, SIG_IGN) != SIG_IGN)
2027 	    restore_sigpipe_for_children = TRUE;
2028 #endif /* SIGPIPE */
2029     }
2030 #endif /* !VMS */
2031 
2032 #ifdef SIGTSTP
2033     /*
2034      * Block Control-Z suspending if requested.  - FM
2035      */
2036     if (no_suspend)
2037 	(void) signal(SIGTSTP, SIG_IGN);
2038 #endif /* SIGTSTP */
2039 
2040     /*
2041      * Check for a valid HEAD request.  - FM
2042      */
2043     if (HEAD_request && LYCanDoHEAD(startfile) != TRUE) {
2044 	fprintf(stderr,
2045 		"The '-head' switch is for http HEAD requests and cannot be used for\n'%s'.\n",
2046 		startfile);
2047 	exit_immediately(EXIT_FAILURE);
2048     }
2049 
2050     /*
2051      * Check for a valid MIME headers request.  - FM
2052      */
2053     if (keep_mime_headers && LYCanDoHEAD(startfile) != TRUE) {
2054 	fprintf(stderr,
2055 		"The '-mime_header' switch is for http URLs and cannot be used for\n'%s'.\n",
2056 		startfile);
2057 	exit_immediately(EXIT_FAILURE);
2058     }
2059 
2060     /*
2061      * Check for a valid traversal request.  - FM
2062      */
2063     if (traversal && StrNCmp(startfile, "http", 4)) {
2064 	fprintf(stderr,
2065 		"The '-traversal' switch is for http URLs and cannot be used for\n'%s'.\n",
2066 		startfile);
2067 	exit_immediately(EXIT_FAILURE);
2068     }
2069 
2070     /*
2071      * Finish setting up for an INTERACTIVE session.  Done here so that URL
2072      * guessing in LYEnsureAbsoluteURL() can be interruptible (terminal is in
2073      * raw mode, select() works).  -BL
2074      */
2075 #ifdef USE_PRETTYSRC
2076     if (!dump_output_immediately) {
2077 	HTMLSRC_init_caches(FALSE);	/* do it before terminal is initialized */
2078 #ifdef LY_FIND_LEAKS
2079 	atexit(html_src_clean_data);
2080 #endif
2081     }
2082 #endif
2083 
2084     if (!dump_output_immediately) {
2085 	setup(terminal);
2086     }
2087     /*
2088      * If startfile is a file URL and the host is defaulted, force in
2089      * "//localhost", and if it's not an absolute URL, make it one.  - FM
2090      */
2091     LYEnsureAbsoluteURL(&startfile, "STARTFILE", FALSE);
2092 
2093     /*
2094      * If homepage was specified and is a file URL with the host defaulted,
2095      * force in "//localhost", and if it's not an absolute URL, make it one.  -
2096      * FM
2097      */
2098     if (homepage) {
2099 	LYEnsureAbsoluteURL(&homepage, "HOMEPAGE", FALSE);
2100     }
2101 
2102     /*
2103      * If we don't have a homepage specified, set it to startfile.  Otherwise,
2104      * reset LynxHome.  - FM
2105      */
2106     if (isEmpty(homepage)) {
2107 	StrAllocCopy(homepage, startfile);
2108     } else {
2109 	StrAllocCopy(LynxHome, homepage);
2110     }
2111 
2112     /*
2113      * Set up the inside/outside domain restriction flags.  - FM
2114      */
2115     if (inlocaldomain()) {
2116 #if !defined(HAVE_UTMP) || defined(VMS)		/* not selective */
2117 	telnet_ok = (BOOL) (!no_inside_telnet && !no_outside_telnet && telnet_ok);
2118 #ifndef DISABLE_NEWS
2119 	news_ok = (BOOL) (!no_inside_news && !no_outside_news && news_ok);
2120 #endif
2121 	ftp_ok = (BOOL) (!no_inside_ftp && !no_outside_ftp && ftp_ok);
2122 	rlogin_ok = (BOOL) (!no_inside_rlogin && !no_outside_rlogin && rlogin_ok);
2123 #else
2124 	CTRACE((tfp, "LYMain: User in Local domain\n"));
2125 	telnet_ok = (BOOL) (!no_inside_telnet && telnet_ok);
2126 #ifndef DISABLE_NEWS
2127 	news_ok = (BOOL) (!no_inside_news && news_ok);
2128 #endif
2129 	ftp_ok = (BOOL) (!no_inside_ftp && ftp_ok);
2130 	rlogin_ok = (BOOL) (!no_inside_rlogin && rlogin_ok);
2131 #endif /* !HAVE_UTMP || VMS */
2132     } else {
2133 	CTRACE((tfp, "LYMain: User in REMOTE domain\n"));
2134 	telnet_ok = (BOOL) (!no_outside_telnet && telnet_ok);
2135 #ifndef DISABLE_NEWS
2136 	news_ok = (BOOL) (!no_outside_news && news_ok);
2137 #endif
2138 	ftp_ok = (BOOL) (!no_outside_ftp && ftp_ok);
2139 	rlogin_ok = (BOOL) (!no_outside_rlogin && rlogin_ok);
2140     }
2141 #ifdef DISABLE_FTP
2142     ftp_ok = FALSE;
2143 #else
2144     /* predefine some known broken ftp servers */
2145     LYSetConfigValue(RC_BROKEN_FTP_RETR, "ProFTPD 1.2.5");
2146     LYSetConfigValue(RC_BROKEN_FTP_RETR, "spftp/");
2147     LYSetConfigValue(RC_BROKEN_FTP_EPSV, "(Version wu-2.6.2-12)");
2148 #endif
2149 
2150     /*
2151      * Make sure our bookmark default strings are all allocated and
2152      * synchronized.  - FM
2153      */
2154     if (isEmpty(bookmark_page)) {
2155 	set_default_bookmark_page("./.etc/bookmark.htm");
2156     }
2157     if (isEmpty(BookmarkPage)) {
2158 	set_default_bookmark_page(bookmark_page);
2159     }
2160 #if defined(SYSLOG_REQUESTED_URLS)
2161     LYOpenlog(syslog_txt);
2162 #endif
2163 
2164     if (non_empty(x_display)) {
2165 	LYisConfiguredForX = TRUE;
2166     }
2167 
2168     /*
2169      * Here's where we do all the work.
2170      */
2171     if (dump_output_immediately) {
2172 	/*
2173 	 * Finish setting up and start a NON-INTERACTIVE session.  - FM
2174 	 */
2175 	if (crawl && !number_links && !number_fields) {
2176 	    keypad_mode = NUMBERS_AS_ARROWS;
2177 	} else if (no_numbers) {
2178 	    keypad_mode = NUMBERS_AS_ARROWS;
2179 	} else if (!no_list) {
2180 	    if (!links_are_numbered()) {
2181 		if (number_fields)
2182 		    keypad_mode = LINKS_AND_FIELDS_ARE_NUMBERED;
2183 		else
2184 		    keypad_mode = LINKS_ARE_NUMBERED;
2185 	    }
2186 	}
2187 	if (dump_output_width > 0) {
2188 	    LYcols = dump_output_width;
2189 	}
2190 	/*
2191 	 * Normal argument processing puts non-options (URLs) into the Goto
2192 	 * history.  Use this to dump all of the pages listed on the command
2193 	 * line, or (if none are listed) via the startfile mechanism.
2194 	 * history.
2195 	 */
2196 #ifdef EXTENDED_STARTFILE_RECALL
2197 	HTAddGotoURL(startfile);
2198 	for (i = HTList_count(Goto_URLs) - 1; i >= 0; --i) {
2199 	    StrAllocCopy(startfile, (char *) HTList_objectAt(Goto_URLs, i));
2200 	    CTRACE((tfp, "dumping %d:%d %s\n",
2201 		    i + 1, HTList_count(Goto_URLs), startfile));
2202 	    status = mainloop();
2203 	    if (!no_list &&
2204 		!crawl)		/* For -crawl it has already been done! */
2205 		printlist(stdout, FALSE);
2206 	    if (i != 0)
2207 		printf("\n");
2208 	}
2209 #else
2210 	status = mainloop();
2211 	if (!no_list &&
2212 	    !crawl &&		/* For -crawl it has already been done! */
2213 	    links_are_numbered())
2214 	    printlist(stdout, FALSE);
2215 #endif
2216 #ifdef USE_PERSISTENT_COOKIES
2217 	/*
2218 	 * We want to save cookies picked up when in immediate dump mode.
2219 	 * Instead of calling cleanup() here, let's only call this one.  - BJP
2220 	 */
2221 	if (persistent_cookies)
2222 	    LYStoreCookies(LYCookieSaveFile);
2223 #endif /* USE_PERSISTENT_COOKIES */
2224 	exit_immediately(status);
2225     } else {
2226 	/*
2227 	 * Start an INTERACTIVE session.  - FM
2228 	 */
2229 #ifdef USE_COLOR_STYLE
2230 	cache_tag_styles();
2231 #endif
2232 
2233 #ifndef NO_DUMP_WITH_BACKSPACES
2234 	if (with_backspaces) {
2235 	    /* we should warn about this somehow (nop for now) -VH */
2236 	    with_backspaces = FALSE;
2237 	}
2238 #endif
2239 
2240 #ifndef ALL_CHARSETS_IN_O_MENU_SCREEN
2241 	init_charset_subsets();
2242 #endif
2243 
2244 	ena_csi((BOOLEAN) (LYlowest_eightbit[current_char_set] > 155));
2245 #ifdef USE_SESSIONS
2246 	RestoreSession();
2247 #endif /* USE_SESSIONS */
2248 	status = mainloop();
2249 	LYCloseCloset(RECALL_URL);
2250 	LYCloseCloset(RECALL_MAIL);
2251 #if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401
2252 	if (!isendwin()) {
2253 	    if ((saved_scrsize_x != 0) && (saved_scrsize_y != 0)) {
2254 		resize_term(saved_scrsize_y, saved_scrsize_x);
2255 	    }
2256 	}
2257 #endif
2258 	cleanup();
2259 	exit_immediately(status);
2260     }
2261 
2262     return (status);		/* though redundant, for compiler-warnings */
2263 }
2264 
2265 /*
2266  * Called by HTAccessInit to register any protocols supported by lynx.
2267  * Protocols added by lynx:
2268  *    LYNXKEYMAP, lynxcgi, LYNXIMGMAP, LYNXCOOKIE, LYNXCACHE, LYNXMESSAGES
2269  */
2270 #ifdef GLOBALREF_IS_MACRO
2271 extern GLOBALREF (HTProtocol, LYLynxKeymap);
2272 extern GLOBALREF (HTProtocol, LYLynxCGI);
2273 extern GLOBALREF (HTProtocol, LYLynxIMGmap);
2274 extern GLOBALREF (HTProtocol, LYLynxCookies);
2275 
2276 #ifdef USE_CACHEJAR
2277 extern GLOBALREF (HTProtocol, LYLynxCache);
2278 #endif
2279 extern GLOBALREF (HTProtocol, LYLynxStatusMessages);
2280 
2281 #else
2282 GLOBALREF HTProtocol LYLynxKeymap;
2283 GLOBALREF HTProtocol LYLynxCGI;
2284 GLOBALREF HTProtocol LYLynxIMGmap;
2285 GLOBALREF HTProtocol LYLynxCookies;
2286 
2287 #ifdef USE_CACHEJAR
2288 GLOBALREF HTProtocol LYLynxCache;
2289 #endif
2290 GLOBALREF HTProtocol LYLynxStatusMessages;
2291 #endif /* GLOBALREF_IS_MACRO */
2292 
LYRegisterLynxProtocols(void)2293 void LYRegisterLynxProtocols(void)
2294 {
2295     HTRegisterProtocol(&LYLynxKeymap);
2296     HTRegisterProtocol(&LYLynxCGI);
2297     HTRegisterProtocol(&LYLynxIMGmap);
2298     HTRegisterProtocol(&LYLynxCookies);
2299 #ifdef USE_CACHEJAR
2300     HTRegisterProtocol(&LYLynxCache);
2301 #endif
2302     HTRegisterProtocol(&LYLynxStatusMessages);
2303 }
2304 
2305 #ifndef NO_CONFIG_INFO
2306 /*
2307  * Some stuff to reload lynx.cfg without restarting new lynx session, also load
2308  * options menu items and command-line options to make things consistent.
2309  *
2310  * Called by user of interactive session by LYNXCFG://reload/ link.
2311  *
2312  * Warning:  experimental, more main() reorganization required.
2313  *	*Known* exceptions: persistent cookies, cookie files.
2314  *
2315  *	Some aspects of COLOR (with slang?).
2316  *	Viewer stuff, mailcap files
2317  *	SUFFIX, mime.types files
2318  *	RULESFILE/RULE
2319  *
2320  *	All work "somewhat", but not exactly as the first time.
2321  */
reload_read_cfg(void)2322 void reload_read_cfg(void)
2323 {
2324     char *tempfile;
2325     FILE *rcfp;
2326 
2327     /*
2328      * no_option_save is always set for -anonymous and -validate.  It is better
2329      * to check for one or several specific restriction flags than for
2330      * 'LYRestricted', which doesn't get set for individual restrictions or for
2331      * -validate!  However, no_option_save may not be the appropriate one to
2332      * check - in that case, a new no_something should be added that gets
2333      * automatically set for -anonymous and -validate (and whether it applies
2334      * for -anonymous can be made installer- configurable in the usual way at
2335      * the bottom of userdefs.h).  - kw
2336      *
2337      */
2338     if (no_option_save) {
2339 	/* current logic requires(?) that saving user preferences is
2340 	   possible.  Additional applicable restrictions are already
2341 	   checked by caller. - kw */
2342 	return;
2343     }
2344 
2345     /*
2346      * Current user preferences are saved in a temporary file, to be read in
2347      * again after lynx.cfg has been read.  This avoids accidental changing of
2348      * the preferences file.  The regular preferences file doesn't even need to
2349      * exist, and won't be created as a side effect of this function.  Honoring
2350      * the no_option_save restriction may thus be unnecessarily restrictive,
2351      * but the check is currently still left in place.  - kw
2352      */
2353     tempfile = typecallocn(char, LY_MAXPATH);
2354     if (!tempfile) {
2355 	HTAlwaysAlert(NULL, NOT_ENOUGH_MEMORY);
2356 	return;
2357     }
2358     rcfp = LYOpenTemp(tempfile, ".rc", "w");
2359     if (rcfp == NULL) {
2360 	FREE(tempfile);
2361 	HTAlwaysAlert(NULL, CANNOT_OPEN_TEMP);
2362 	return;
2363     }
2364     if (!save_rc(rcfp)) {
2365 	HTAlwaysAlert(NULL, OPTIONS_NOT_SAVED);
2366 	(void) LYRemoveTemp(tempfile);
2367 	FREE(tempfile);
2368 	return;			/* can not write the very own file :( */
2369     } {
2370 	/* set few safe flags: */
2371 #ifdef USE_PERSISTENT_COOKIES
2372 	BOOLEAN persistent_cookies_flag = persistent_cookies;
2373 	char *LYCookieFile_flag = NULL;
2374 	char *LYCookieSaveFile_flag = NULL;
2375 
2376 	if (persistent_cookies) {
2377 	    StrAllocCopy(LYCookieFile_flag, LYCookieFile);
2378 	    StrAllocCopy(LYCookieSaveFile_flag, LYCookieSaveFile);
2379 	}
2380 #endif
2381 
2382 #ifdef USE_CHARSET_CHOICE
2383 	custom_assumed_doc_charset = FALSE;
2384 	custom_display_charset = FALSE;
2385 	memset((char *) charset_subsets, 0, sizeof(charset_subset_t) * MAXCHARSETS);
2386 #endif
2387 
2388 #ifdef USE_PRETTYSRC
2389 	html_src_on_lynxcfg_reload();
2390 #endif
2391 	/* free downloaders, printers, environments, dired menu */
2392 	free_lynx_cfg();
2393 #ifdef USE_SOURCE_CACHE
2394 	source_cache_file_error = FALSE;	/* reset flag */
2395 #endif
2396 
2397 	/*
2398 	 * Process the configuration file.
2399 	 */
2400 	read_cfg(lynx_cfg_file, "main program", 1, (FILE *) 0);
2401 
2402 	/*
2403 	 * Process the temporary RC file.
2404 	 */
2405 	rcfp = fopen(tempfile, "r");
2406 	read_rc(rcfp);
2407 	(void) LYRemoveTemp(tempfile);
2408 	FREE(tempfile);		/* done with it - kw */
2409 
2410 #ifdef USE_CHARSET_CHOICE
2411 	init_charset_subsets();
2412 #endif
2413 
2414 	/*
2415 	 * Initialize other things based on the configuration read.
2416 	 */
2417 	LYSetDisplayLines();
2418 	/* Not implemented yet here,
2419 	 * a major problem: file paths
2420 	 * like lynx_save_space, LYCookieFile etc.
2421 	 */
2422 #ifdef USE_PERSISTENT_COOKIES
2423 	/* restore old settings */
2424 	if (persistent_cookies != persistent_cookies_flag) {
2425 	    persistent_cookies = persistent_cookies_flag;
2426 	    HTAlert(gettext("persistent cookies state will be changed in next session only."));
2427 	}
2428 	if (persistent_cookies) {
2429 	    if (strcmp(LYCookieFile, LYCookieFile_flag)) {
2430 		StrAllocCopy(LYCookieFile, LYCookieFile_flag);
2431 		CTRACE((tfp,
2432 			"cookie file can be changed in next session only, restored.\n"));
2433 	    }
2434 	    if (strcmp(LYCookieSaveFile, LYCookieSaveFile_flag)) {
2435 		StrAllocCopy(LYCookieSaveFile, LYCookieSaveFile_flag);
2436 		CTRACE((tfp,
2437 			"cookie save file can be changed in next session only, restored.\n"));
2438 	    }
2439 	    FREE(LYCookieFile_flag);
2440 	    FREE(LYCookieSaveFile_flag);
2441 	}
2442 #endif
2443 
2444     }
2445 }
2446 #endif /* !NO_CONFIG_INFO */
2447 
force_dump_mode(void)2448 static void force_dump_mode(void)
2449 {
2450     dump_output_immediately = TRUE;
2451     no_pause = TRUE;
2452     LYcols = DFT_COLS;
2453 }
2454 
2455 /* There are different ways of setting arguments on the command line, and
2456  * there are different types of arguments.  These include:
2457  *
2458  *   -set_some_variable		 ==> some_variable  = TRUE
2459  *   -toggle_some_variable	 ==> some_variable = !some_variable
2460  *   -some_variable=value	 ==> some_variable = value
2461  *
2462  * Others are complicated and require a function call.
2463  */
2464 
2465 #define PARSE_SET(n,t,v,h) {n,    t, UNION_SET(v), h}
2466 #define PARSE_INT(n,t,v,h) {n,    t, UNION_INT(v), h}
2467 #define PARSE_STR(n,t,v,h) {n,    t, UNION_STR(v), h}
2468 #define PARSE_FUN(n,t,v,h) {n,    t, UNION_FUN(v), h}
2469 #define PARSE_NIL          {NULL, 0, UNION_DEF(0), NULL}
2470 
2471 typedef struct parse_args_type {
2472     const char *name;
2473     int type;
2474 
2475 #define TOGGLE_ARG		0x0010
2476 #define SET_ARG			0x0020
2477 #define UNSET_ARG		0x0030
2478 #define FUNCTION_ARG		0x0040
2479 #define LYSTRING_ARG		0x0050
2480 #define INT_ARG			0x0060
2481 #define STRING_ARG		0x0070
2482 #define TIME_ARG		0x0080
2483 #define ARG_TYPE_MASK		0x0FF0
2484 #define NEED_NEXT_ARG		0x1000
2485 
2486 #define NEED_INT_ARG		(NEED_NEXT_ARG | INT_ARG)
2487 #define NEED_TIME_ARG		(NEED_NEXT_ARG | TIME_ARG)
2488 #define NEED_LYSTRING_ARG	(NEED_NEXT_ARG | LYSTRING_ARG)
2489 #define NEED_STRING_ARG		(NEED_NEXT_ARG | STRING_ARG)
2490 #define NEED_FUNCTION_ARG	(NEED_NEXT_ARG | FUNCTION_ARG)
2491 
2492     /* If the NEED_NEXT_ARG flags is set, and the option was not specified
2493      * with an '=' character, then use the next argument in the argv list.
2494      */
2495 
2496       ParseData;
2497     const char *help_string;
2498 } Config_Type;
2499 
2500 /* -auth, -pauth */
parse_authentication(char * next_arg,char ** result)2501 static int parse_authentication(char *next_arg,
2502 				char **result)
2503 {
2504     /*
2505      * Authentication information for protected documents.
2506      */
2507     char *auth_info = 0;
2508 
2509     if (next_arg != 0) {
2510 	StrAllocCopy(auth_info, next_arg);
2511 	memset(next_arg, ' ', strlen(next_arg));	/* Let's not show too much */
2512     }
2513 
2514     if (auth_info != 0) {
2515 	char *cp;
2516 
2517 	if ((cp = strchr(auth_info, ':')) != 0) {	/* Pw */
2518 	    *cp++ = '\0';	/* Terminate ID */
2519 	    HTUnEscape(cp);
2520 	    StrAllocCopy(result[1], cp);
2521 	}
2522 	if (*auth_info) {	/* Id */
2523 	    HTUnEscape(auth_info);
2524 	    StrAllocCopy(result[0], auth_info);
2525 	}
2526 	FREE(auth_info);
2527     }
2528     return 0;
2529 }
2530 
2531 /* -anonymous */
anonymous_fun(char * next_arg GCC_UNUSED)2532 static int anonymous_fun(char *next_arg GCC_UNUSED)
2533 {
2534     if (!LYValidate && !LYRestricted)
2535 	parse_restrictions("default");
2536     LYRestricted = TRUE;
2537     return 0;
2538 }
2539 
2540 /* -assume_charset */
assume_charset_fun(char * next_arg)2541 static int assume_charset_fun(char *next_arg)
2542 {
2543     UCLYhndl_for_unspec = safeUCGetLYhndl_byMIME(next_arg);
2544     StrAllocCopy(UCAssume_MIMEcharset,
2545 		 LYCharSet_UC[UCLYhndl_for_unspec].MIMEname);
2546 /*	   this may be a memory for bogus typo -
2547     StrAllocCopy(UCAssume_MIMEcharset, next_arg);
2548     LYLowerCase(UCAssume_MIMEcharset);   */
2549 
2550     return 0;
2551 }
2552 
2553 /* -assume_local_charset */
assume_local_charset_fun(char * next_arg)2554 static int assume_local_charset_fun(char *next_arg)
2555 {
2556     UCLYhndl_HTFile_for_unspec = safeUCGetLYhndl_byMIME(next_arg);
2557     return 0;
2558 }
2559 
2560 /* -assume_unrec_charset */
assume_unrec_charset_fun(char * next_arg)2561 static int assume_unrec_charset_fun(char *next_arg)
2562 {
2563     UCLYhndl_for_unrec = safeUCGetLYhndl_byMIME(next_arg);
2564     return 0;
2565 }
2566 
2567 /* -auth */
auth_fun(char * next_arg)2568 static int auth_fun(char *next_arg)
2569 {
2570     parse_authentication(next_arg, authentication_info);
2571     return 0;
2572 }
2573 
2574 /* -base */
base_fun(char * next_arg GCC_UNUSED)2575 static int base_fun(char *next_arg GCC_UNUSED)
2576 {
2577     /*
2578      * Treat -source equivalently to an interactive download with
2579      * LYPrefixBaseToSource configured to TRUE, so that a BASE tag is prepended
2580      * for text/html content types.  We normally treat the module-wide global
2581      * LYPrefixBaseToSource flag as FALSE with -source, but force it TRUE,
2582      * later, if LYPrependBase is set TRUE here.  - FM
2583      */
2584     LYPrependBase = TRUE;
2585     if (HTOutputFormat == HTAtom_for("www/dump"))
2586 	HTOutputFormat = HTAtom_for("www/download");
2587 
2588     return 0;
2589 }
2590 
2591 /* -cache */
cache_fun(char * next_arg)2592 static int cache_fun(char *next_arg)
2593 {
2594     if (next_arg != 0)
2595 	HTCacheSize = atoi(next_arg);
2596     /*
2597      * Limit size.
2598      */
2599     if (HTCacheSize < 2)
2600 	HTCacheSize = 2;
2601 
2602     return 0;
2603 }
2604 
2605 /* -child */
child_fun(char * next_arg GCC_UNUSED)2606 static int child_fun(char *next_arg GCC_UNUSED)
2607 {
2608     child_lynx = TRUE;
2609     no_disk_save = TRUE;
2610     no_mail = TRUE;
2611     return 0;
2612 }
2613 
2614 /* -child_relaxed */
child_relaxed_fun(char * next_arg GCC_UNUSED)2615 static int child_relaxed_fun(char *next_arg GCC_UNUSED)
2616 {
2617     child_lynx = TRUE;
2618     return 0;
2619 }
2620 
2621 #ifdef USE_SLANG
2622 /* -color */
color_fun(char * next_arg GCC_UNUSED)2623 static int color_fun(char *next_arg GCC_UNUSED)
2624 {
2625     Lynx_Color_Flags |= SL_LYNX_USE_COLOR;
2626 
2627     if (LYShowColor != SHOW_COLOR_ALWAYS)
2628 	LYShowColor = SHOW_COLOR_ON;
2629 
2630     return 0;
2631 }
2632 #endif
2633 
2634 #ifdef MISC_EXP
2635 /* -convert_to */
convert_to_fun(char * next_arg)2636 static int convert_to_fun(char *next_arg)
2637 {
2638     if (next_arg != 0) {
2639 	char *outformat = NULL;
2640 	char *cp1, *cp2, *cp4;
2641 	int chndl;
2642 
2643 	StrAllocCopy(outformat, next_arg);
2644 	/* not lowercased, to allow for experimentation - kw */
2645 	/*LYLowerCase(outformat); */
2646 	if ((cp1 = strchr(outformat, ';')) != NULL) {
2647 	    if ((cp2 = LYstrstr(cp1, "charset")) != NULL) {
2648 		cp2 += 7;
2649 		while (*cp2 == ' ' || *cp2 == '=' || *cp2 == '"')
2650 		    cp2++;
2651 		for (cp4 = cp2; (*cp4 != '\0' && *cp4 != '"' &&
2652 				 *cp4 != ';' &&
2653 				 !WHITE(*cp4)); cp4++) ;	/* do nothing */
2654 		*cp4 = '\0';
2655 		/* This is intentionally not the "safe" version,
2656 		   to allow for experimentation. */
2657 		chndl = UCGetLYhndl_byMIME(cp2);
2658 		if (chndl < 0)
2659 		    chndl = UCLYhndl_for_unrec;
2660 		if (chndl < 0) {
2661 		    fprintf(stderr,
2662 			    gettext("Lynx: ignoring unrecognized charset=%s\n"), cp2);
2663 		} else {
2664 		    current_char_set = chndl;
2665 		}
2666 		*cp1 = '\0';	/* truncate outformat */
2667 	    }
2668 	}
2669 	HTOutputFormat = HTAtom_for(outformat);
2670 	FREE(outformat);
2671     } else {
2672 	HTOutputFormat = NULL;
2673     }
2674     return 0;
2675 }
2676 #endif
2677 
2678 /* -crawl */
crawl_fun(char * next_arg GCC_UNUSED)2679 static int crawl_fun(char *next_arg GCC_UNUSED)
2680 {
2681     crawl = TRUE;
2682     LYcols = DFT_COLS;
2683     return 0;
2684 }
2685 
2686 /* -display */
display_fun(char * next_arg)2687 static int display_fun(char *next_arg)
2688 {
2689     if (next_arg != 0) {
2690 	LYsetXDisplay(next_arg);
2691     }
2692 
2693     return 0;
2694 }
2695 
2696 /* -display_charset */
display_charset_fun(char * next_arg)2697 static int display_charset_fun(char *next_arg)
2698 {
2699     int i = UCGetLYhndl_byMIME(next_arg);
2700 
2701 #ifdef CAN_AUTODETECT_DISPLAY_CHARSET
2702     if (i < 0 && !strcasecomp(next_arg, "auto"))
2703 	i = auto_display_charset;
2704 #endif
2705     if (i < 0) {		/* do nothing here: so fallback to lynx.cfg */
2706 	fprintf(stderr,
2707 		gettext("Lynx: ignoring unrecognized charset=%s\n"), next_arg);
2708     } else
2709 	current_char_set = i;
2710     return 0;
2711 }
2712 
2713 /* -dump */
dump_output_fun(char * next_arg GCC_UNUSED)2714 static int dump_output_fun(char *next_arg GCC_UNUSED)
2715 {
2716     force_dump_mode();
2717     return 0;
2718 }
2719 
2720 /* -editor */
editor_fun(char * next_arg)2721 static int editor_fun(char *next_arg)
2722 {
2723     if (next_arg != 0)
2724 	StrAllocCopy(editor, next_arg);
2725     system_editor = TRUE;
2726     return 0;
2727 }
2728 
2729 /* -error_file */
error_file_fun(char * next_arg)2730 static int error_file_fun(char *next_arg)
2731 {
2732     /*
2733      * Output return (success/failure) code of an HTTP transaction.
2734      */
2735     if (next_arg != 0)
2736 	http_error_file = next_arg;
2737     return 0;
2738 }
2739 
2740 #if defined(EXEC_LINKS) || defined(EXEC_SCRIPTS)
2741 /* -exec */
exec_fun(char * next_arg GCC_UNUSED)2742 static int exec_fun(char *next_arg GCC_UNUSED)
2743 {
2744 #ifndef NEVER_ALLOW_REMOTE_EXEC
2745     local_exec = TRUE;
2746 #else
2747     local_exec_on_local_files = TRUE;
2748 #endif /* NEVER_ALLOW_REMOTE_EXEC */
2749     return 0;
2750 }
2751 #endif
2752 
2753 /* -get_data */
get_data_fun(char * next_arg GCC_UNUSED)2754 static int get_data_fun(char *next_arg GCC_UNUSED)
2755 {
2756     /*
2757      * User data for GET form.
2758      */
2759     char **get_data;
2760     char *buf = NULL;
2761 
2762     /*
2763      * On Unix, conflicts with curses when interactive so let's force a dump.
2764      * -CL
2765      *
2766      * On VMS, mods have been made in LYCurses.c to deal with potential
2767      * conflicts, so don't force the dump here.  - FM
2768      */
2769 #ifndef VMS
2770     force_dump_mode();
2771 #endif /* VMS */
2772 
2773     StrAllocCopy(form_get_data, "?");	/* Prime the pump */
2774     get_data = &form_get_data;
2775 
2776     /*
2777      * Build GET data for later.  Stop reading when we see a line with "---" as
2778      * its first three characters.
2779      */
2780     while (GetStdin(&buf, TRUE)) {
2781 	StrAllocCat(*get_data, buf);
2782     }
2783 
2784     CTRACE((tfp, "get_data:%s\n", *get_data));
2785     CTRACE((tfp, "get_data:%s\n", form_get_data));
2786     return 0;
2787 }
2788 
2789 /* -help */
help_fun(char * next_arg GCC_UNUSED)2790 static int help_fun(char *next_arg GCC_UNUSED)
2791 {
2792     print_help_and_exit(0);
2793     return 0;
2794 }
2795 
2796 /* -hiddenlinks */
hiddenlinks_fun(char * next_arg)2797 static int hiddenlinks_fun(char *next_arg)
2798 {
2799     /* *INDENT-OFF* */
2800     static Config_Enum table[] = {
2801 	{ "merge",	HIDDENLINKS_MERGE },
2802 	{ "listonly",	HIDDENLINKS_SEPARATE },
2803 	{ "ignore",	HIDDENLINKS_IGNORE },
2804 	{ NULL,		-1 },
2805     };
2806     /* *INDENT-ON* */
2807 
2808     if (next_arg != 0) {
2809 	if (!LYgetEnum(table, next_arg, &LYHiddenLinks))
2810 	    print_help_and_exit(-1);
2811     } else {
2812 	LYHiddenLinks = HIDDENLINKS_MERGE;
2813     }
2814 
2815     return 0;
2816 }
2817 
2818 /* -homepage */
homepage_fun(char * next_arg)2819 static int homepage_fun(char *next_arg)
2820 {
2821     if (next_arg != 0) {
2822 	StrAllocCopy(homepage, next_arg);
2823 	LYEscapeStartfile(&homepage);
2824     }
2825     return 0;
2826 }
2827 
2828 /* -mime_header */
mime_header_fun(char * next_arg GCC_UNUSED)2829 static int mime_header_fun(char *next_arg GCC_UNUSED)
2830 {
2831     /*
2832      * Include mime headers and force source dump.
2833      */
2834     keep_mime_headers = TRUE;
2835     force_dump_mode();
2836     HTOutputFormat = (LYPrependBase ?
2837 		      HTAtom_for("www/download") : HTAtom_for("www/dump"));
2838     LYcols = MAX_COLS;
2839     return 0;
2840 }
2841 
2842 #ifndef DISABLE_NEWS
2843 /* -newschunksize */
newschunksize_fun(char * next_arg)2844 static int newschunksize_fun(char *next_arg)
2845 {
2846     if (next_arg != 0) {
2847 	HTNewsChunkSize = atoi(next_arg);
2848 	/*
2849 	 * If the new HTNewsChunkSize exceeds the maximum,
2850 	 * increase HTNewsMaxChunk to this size. - FM
2851 	 */
2852 	if (HTNewsChunkSize > HTNewsMaxChunk)
2853 	    HTNewsMaxChunk = HTNewsChunkSize;
2854     }
2855     return 0;
2856 }
2857 
2858 /* -newsmaxchunk */
newsmaxchunk_fun(char * next_arg)2859 static int newsmaxchunk_fun(char *next_arg)
2860 {
2861     if (next_arg) {
2862 	HTNewsMaxChunk = atoi(next_arg);
2863 	/*
2864 	 * If HTNewsChunkSize exceeds the new maximum,
2865 	 * reduce HTNewsChunkSize to this maximum. - FM
2866 	 */
2867 	if (HTNewsChunkSize > HTNewsMaxChunk)
2868 	    HTNewsChunkSize = HTNewsMaxChunk;
2869     }
2870     return 0;
2871 }
2872 #endif /* not DISABLE_NEWS */
2873 
2874 /* -nobold */
nobold_fun(char * next_arg GCC_UNUSED)2875 static int nobold_fun(char *next_arg GCC_UNUSED)
2876 {
2877     LYnoVideo(1);
2878     return 0;
2879 }
2880 
2881 /* -nobrowse */
nobrowse_fun(char * next_arg GCC_UNUSED)2882 static int nobrowse_fun(char *next_arg GCC_UNUSED)
2883 {
2884     HTDirAccess = HT_DIR_FORBID;
2885     return 0;
2886 }
2887 
2888 /* -nocolor */
nocolor_fun(char * next_arg GCC_UNUSED)2889 static int nocolor_fun(char *next_arg GCC_UNUSED)
2890 {
2891     LYShowColor = SHOW_COLOR_NEVER;
2892 #ifdef USE_SLANG
2893     Lynx_Color_Flags &= ~SL_LYNX_USE_COLOR;
2894     Lynx_Color_Flags |= SL_LYNX_OVERRIDE_COLOR;
2895 #endif
2896     return 0;
2897 }
2898 
2899 /* -nopause */
nopause_fun(char * next_arg GCC_UNUSED)2900 static int nopause_fun(char *next_arg GCC_UNUSED)
2901 {
2902     no_pause = TRUE;
2903     return 0;
2904 }
2905 
2906 /* -nomore */
nomore_fun(char * next_arg GCC_UNUSED)2907 static int nomore_fun(char *next_arg GCC_UNUSED)
2908 {
2909     nomore = TRUE;
2910     return 0;
2911 }
2912 
2913 /* -noreverse */
noreverse_fun(char * next_arg GCC_UNUSED)2914 static int noreverse_fun(char *next_arg GCC_UNUSED)
2915 {
2916     LYnoVideo(2);
2917     return 0;
2918 }
2919 
2920 /* -nounderline */
nounderline_fun(char * next_arg GCC_UNUSED)2921 static int nounderline_fun(char *next_arg GCC_UNUSED)
2922 {
2923     LYnoVideo(4);
2924     return 0;
2925 }
2926 
2927 #ifdef MISC_EXP
2928 /* -nozap */
nozap_fun(char * next_arg)2929 static int nozap_fun(char *next_arg)
2930 {
2931     LYNoZapKey = 1;		/* everything but "initially" treated as "full" - kw */
2932     if (next_arg != 0) {
2933 	if (strcasecomp(next_arg, "initially") == 0)
2934 	    LYNoZapKey = 2;
2935 
2936     }
2937     return 0;
2938 }
2939 #endif /* MISC_EXP */
2940 
2941 /* -pauth */
pauth_fun(char * next_arg)2942 static int pauth_fun(char *next_arg)
2943 {
2944     parse_authentication(next_arg, proxyauth_info);
2945     return 0;
2946 }
2947 
2948 /* -post_data */
post_data_fun(char * next_arg GCC_UNUSED)2949 static int post_data_fun(char *next_arg GCC_UNUSED)
2950 {
2951     /*
2952      * User data for POST form.
2953      */
2954     char **post_data;
2955     char *buf = NULL;
2956 
2957     /*
2958      * On Unix, conflicts with curses when interactive so let's force a dump.
2959      * - CL
2960      *
2961      * On VMS, mods have been made in LYCurses.c to deal with potential
2962      * conflicts, so don't force a dump here.  - FM
2963      */
2964 #ifndef VMS
2965     force_dump_mode();
2966 #endif /* VMS */
2967 
2968     post_data = &form_post_data;
2969 
2970     /*
2971      * Build post data for later.  Stop reading when we see a line with "---"
2972      * as its first three characters.
2973      */
2974     while (GetStdin(&buf, TRUE)) {
2975 	StrAllocCat(*post_data, buf);
2976     }
2977     return 0;
2978 }
2979 
show_restriction(const char * name)2980 static const char *show_restriction(const char *name)
2981 {
2982     const char *value = 0;
2983 
2984     switch (find_restriction(name, -1)) {
2985     case TRUE:
2986 	value = "on";
2987 	break;
2988     case FALSE:
2989 	value = "off";
2990 	break;
2991     default:
2992 	value = "?";
2993 	break;
2994     }
2995     return value;
2996 }
2997 
2998 /* -restrictions */
restrictions_fun(char * next_arg)2999 static int restrictions_fun(char *next_arg)
3000 {
3001     /* *INDENT-OFF* */
3002     static const struct {
3003 	const char *name;
3004 	const char *help;
3005     } table[] = {
3006 	{ "all", "restricts all options." },
3007 	{ "bookmark", "disallow changing the location of the bookmark file" },
3008 	{ "bookmark_exec", "disallow execution links via the bookmark file" },
3009 #if defined(DIRED_SUPPORT) && defined(OK_PERMIT)
3010 	{ "change_exec_perms", "\
3011 disallow changing the eXecute permission on files\n\
3012 (but still allow it for directories) when local file\n\
3013 management is enabled." },
3014 #endif /* DIRED_SUPPORT && OK_PERMIT */
3015 #ifdef SUPPORT_CHDIR
3016 	{ "chdir", "\
3017 disallow changing the working directory of lynx, e.g.,\n\
3018 to affect the behavior of download command" },
3019 #endif
3020 #if defined(HAVE_CONFIG_H) && !defined(NO_CONFIG_INFO)
3021 	{ "compileopts_info", "\
3022 disable info on options used to compile the binary" },
3023 #endif
3024 	{ "default", "\
3025 same as commandline option -anonymous.  Sets the\n\
3026 default service restrictions for anonymous users.  Set to\n\
3027 all restricted, except for: inside_telnet, outside_telnet,\n\
3028 inside_ftp, outside_ftp, inside_rlogin, outside_rlogin,\n\
3029 inside_news, outside_news, telnet_port, jump, mail, print,\n\
3030 exec, and goto.  The settings for these, as well as\n\
3031 additional goto restrictions for specific URL schemes\n\
3032 that are also applied, are derived from definitions\n\
3033 within userdefs.h." },
3034 #ifdef DIRED_SUPPORT
3035 	{ "dired_support", "disallow local file management" },
3036 #endif /* DIRED_SUPPORT */
3037 	{ "disk_save", "disallow saving to disk in the download and print menus" },
3038 	{ "dotfiles", "disallow access to, or creation of, hidden (dot) files" },
3039 	{ "download", "disallow some downloaders in the download menu" },
3040 	{ "editor", "disallow editing" },
3041 	{ "exec", "disable execution scripts" },
3042 	{ "exec_frozen", "disallow the user from changing the execution link option" },
3043 #ifdef USE_EXTERNALS
3044 	{ "externals", "disable passing URLs to some external programs" },
3045 #endif
3046 	{ "file_url", "\
3047 disallow using G)oto, served links or bookmarks for\n\
3048 file: URLs" },
3049 	{ "goto", "disable the 'g' (goto) command" },
3050 #if !defined(HAVE_UTMP) || defined(VMS) /* not selective */
3051 	{ "inside_ftp", "\
3052 disallow ftps coming from inside your\n\
3053 domain (utmp required for selectivity)" },
3054 	{ "inside_news", "\
3055 disallow USENET news reading and posting coming\n\
3056 from inside your domain (utmp required for selectivity)" },
3057 	{ "inside_rlogin", "\
3058 disallow rlogins coming from inside your\n\
3059 domain (utmp required for selectivity)" },
3060 	{ "inside_telnet", "\
3061 disallow telnets coming from inside your\n\
3062 domain (utmp required for selectivity)" },
3063 #else
3064 	{ "inside_ftp", "\
3065 disallow ftps coming from inside your domain" },
3066 	{ "inside_news", "\
3067 disallow USENET news reading and posting coming\n\
3068 from inside your domain" },
3069 	{ "inside_rlogin", "\
3070 disallow rlogins coming from inside your domain" },
3071 	{ "inside_telnet", "\
3072 disallow telnets coming from inside your domain" },
3073 #endif /* HAVE_UTMP || VMS */
3074 	{ "jump", "disable the 'j' (jump) command" },
3075 	{ "lynxcfg_info", "\
3076 disable viewing of lynx.cfg configuration file info" },
3077 #ifndef NO_CONFIG_INFO
3078 	{ "lynxcfg_xinfo", "\
3079 disable extended lynx.cfg viewing and reloading" },
3080 #endif
3081 	{ "lynxcgi", "\
3082 disallow execution of Lynx CGI URLs" },
3083 	{ "mail", "disallow mail" },
3084 	{ "multibook", "disallow multiple bookmark files" },
3085 	{ "news_post", "disallow USENET News posting." },
3086 	{ "option_save", "disallow saving options in .etc/lynxrc" },
3087 #if !defined(HAVE_UTMP) || defined(VMS) /* not selective */
3088 	{ "outside_ftp", "\
3089 disallow ftps coming from outside your\n\
3090 domain (utmp required for selectivity)" },
3091 	{ "outside_news", "\
3092 disallow USENET news reading and posting coming\n\
3093 from outside your domain (utmp required for selectivity)" },
3094 	{ "outside_rlogin", "\
3095 disallow rlogins coming from outside your\n\
3096 domain (utmp required for selectivity)" },
3097 	{ "outside_telnet", "\
3098 disallow telnets coming from outside your\n\
3099 domain (utmp required for selectivity)" },
3100 #else
3101 	{ "outside_ftp", "\
3102 disallow ftp coming from outside your domain" },
3103 	{ "outside_news", "\
3104 disallow USENET news reading and posting coming\n\
3105 from outside your domain" },
3106 	{ "outside_rlogin", "\
3107 disallow rlogins coming from outside your domain" },
3108 	{ "outside_telnet", "\
3109 disallow telnets coming from outside your domain" },
3110 #endif /* !HAVE_UTMP || VMS */
3111 	{ "print", "disallow most print options" },
3112 	{ "shell", "\
3113 disallow shell escapes, and lynxexec, lynxprog or lynxcgi\n\
3114 G)oto" },
3115 	{ "suspend", "disallow Control-Z suspends with escape to shell" },
3116 	{ "telnet_port", "disallow specifying a port in telnet G)oto" },
3117 	{ "useragent", "disallow modifications of the User-Agent header" },
3118     };
3119     /* *INDENT-ON* */
3120 
3121     static const char *Usage[] =
3122     {
3123 	""
3124 	,"USAGE: lynx -restrictions=[option][,option][,option]"
3125 	,"List of Options:"
3126 	,"  ?                 when used alone, list restrictions in effect."
3127 
3128     };
3129     unsigned j, k, column = 0;
3130     const char *name;
3131     const char *value;
3132     BOOLEAN found, first;
3133 
3134     if (isEmpty(next_arg)) {
3135 	SetOutputMode(O_TEXT);
3136 	for (j = 0; j < TABLESIZE(Usage); j++) {
3137 	    printf("%s\n", Usage[j]);
3138 	}
3139 	for (j = 0; j < TABLESIZE(table); j++) {
3140 	    if (!strcmp(table[j].name, "all")
3141 		|| !strcmp(table[j].name, "default")) {
3142 		value = NULL;
3143 	    } else {
3144 		value = show_restriction(table[j].name);
3145 	    }
3146 	    print_help_strings(table[j].name, table[j].help, value, FALSE);
3147 	}
3148 	first = TRUE;
3149 	for (j = 0; j < TABLESIZE(table); j++) {
3150 	    found = FALSE;
3151 	    if ((name = index_to_restriction(j)) == 0) {
3152 		break;
3153 	    }
3154 	    for (k = 0; k < TABLESIZE(table); k++) {
3155 		if (!strcmp(name, table[k].name)) {
3156 		    found = TRUE;
3157 		}
3158 	    }
3159 	    if (!found) {
3160 		if (first) {
3161 		    printf("Other restrictions (see the user's guide):\n");
3162 		}
3163 		value = show_restriction(table[j].name);
3164 		printf("%s%s (%s)", column ? ", " : "  ", name, value);
3165 		column += (unsigned) (5 + strlen(name) + strlen(value));
3166 		if (column > 50) {
3167 		    column = 0;
3168 		    printf("\n");
3169 		}
3170 		first = FALSE;
3171 	    }
3172 	}
3173 	if (column)
3174 	    printf("\n");
3175 	SetOutputMode(O_BINARY);
3176 	exit_immediately(EXIT_SUCCESS);
3177     } else if (*next_arg == '?') {
3178 	SetOutputMode(O_TEXT);
3179 	print_restrictions_to_fd(stdout);
3180 	SetOutputMode(O_BINARY);
3181 	exit_immediately(EXIT_SUCCESS);
3182     } else {
3183 	parse_restrictions(next_arg);
3184     }
3185     return 0;
3186 }
3187 
3188 /* -selective */
selective_fun(char * next_arg GCC_UNUSED)3189 static int selective_fun(char *next_arg GCC_UNUSED)
3190 {
3191     HTDirAccess = HT_DIR_SELECTIVE;
3192     return 0;
3193 }
3194 
3195 /* -source */
source_fun(char * next_arg GCC_UNUSED)3196 static int source_fun(char *next_arg GCC_UNUSED)
3197 {
3198     force_dump_mode();
3199     HTOutputFormat = (LYPrependBase ?
3200 		      HTAtom_for("www/download") : HTAtom_for("www/dump"));
3201     LYcols = MAX_COLS;
3202     return 0;
3203 }
3204 
3205 /* -traversal */
traversal_fun(char * next_arg GCC_UNUSED)3206 static int traversal_fun(char *next_arg GCC_UNUSED)
3207 {
3208     traversal = TRUE;
3209 #ifdef USE_SLANG
3210     LYcols = DFT_COLS;
3211 #else
3212     LYcols = MAX_COLS;
3213 #endif /* USE_SLANG */
3214 
3215     return 0;
3216 }
3217 
3218 /* -version */
version_fun(char * next_arg GCC_UNUSED)3219 static int version_fun(char *next_arg GCC_UNUSED)
3220 {
3221     char *result = NULL;
3222 
3223     SetLocale();
3224     SetOutputMode(O_TEXT);
3225 
3226     HTSprintf0(&result, gettext("%s Version %s (%s)"),
3227 	       LYNX_NAME, LYNX_VERSION,
3228 	       LYVersionDate());
3229 
3230     StrAllocCat(result, "\n");
3231 #ifdef USE_SSL
3232     HTSprintf(&result, "libwww-FM %s,", HTLibraryVersion);
3233     append_ssl_version(&result, " ");
3234 #else
3235     HTSprintf(&result, "libwww-FM %s", HTLibraryVersion);
3236 #endif /* USE_SSL */
3237 
3238 #if defined(NCURSES) && defined(HAVE_CURSES_VERSION)
3239     HTSprintf(&result, ", %s", curses_version());
3240 #if defined(WIDEC_CURSES)
3241     HTSprintf(&result, "(wide)");
3242 #endif
3243 #elif defined(PDCURSES) && defined(PDC_BUILD)
3244     HTSprintf(&result, ", pdcurses %.3f", PDC_BUILD * 0.001);
3245 #elif defined(USE_SLANG) && defined(SLANG_VERSION_STRING)
3246     HTSprintf(&result, ", s-lang %s", SLANG_VERSION_STRING);
3247 #endif
3248 
3249     printf("%s\n", result);
3250     free(result);
3251 
3252     printf("No compilation information available.\n");
3253 
3254     puts("");
3255     puts(gettext("Copyrights held by the Lynx Developers Group,"));
3256     puts(gettext("the University of Kansas, CERN, and other contributors."));
3257     puts(gettext("Distributed under the GNU General Public License (Version 2)."));
3258     puts(gettext("See http://lynx.isc.org/ and the online help for more information."));
3259     puts("");
3260 #ifdef USE_SSL
3261 #if defined(OPENSSL_VERSION_TEXT) && !defined(LIBGNUTLS_VERSION)
3262     puts("See http://www.openssl.org/ for information about OpenSSL.");
3263 #endif /* OPENSSL_VERSION_TEXT */
3264     puts("");
3265 #endif /* USE_SSL */
3266 
3267     SetOutputMode(O_BINARY);
3268 
3269     exit_immediately(EXIT_SUCCESS);
3270     /* NOT REACHED */
3271     return 0;
3272 }
3273 
3274 /* -width */
width_fun(char * next_arg)3275 static int width_fun(char *next_arg)
3276 {
3277     if (next_arg != 0) {
3278 	int w = atoi(next_arg);
3279 
3280 	if (w > 0)
3281 	    dump_output_width = ((w < MAX_COLS) ? w : MAX_COLS);
3282     }
3283 
3284     return 0;
3285 }
3286 
3287 #if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401
3288 /* -scrsize */
scrsize_fun(char * next_arg)3289 static int scrsize_fun(char *next_arg)
3290 {
3291     if (next_arg != 0) {
3292 	char *cp;
3293 
3294 	if ((cp = strchr(next_arg, ',')) != 0) {
3295 	    *cp++ = '\0';	/* Terminate ID */
3296 	    scrsize_x = atoi(next_arg);
3297 	    scrsize_y = atoi(cp);
3298 	    if ((scrsize_x <= 1) || (scrsize_y <= 1)) {
3299 		scrsize_x = scrsize_y = 0;
3300 	    }
3301 	    if ((scrsize_x > 0) && (scrsize_x < 80)) {
3302 		scrsize_x = 80;
3303 	    }
3304 	    if ((scrsize_y > 0) && (scrsize_y < 4)) {
3305 		scrsize_y = 4;
3306 	    }
3307 	    CTRACE((tfp, "scrsize: x=%d, y=%d\n", scrsize_x, scrsize_y));
3308 	}
3309     }
3310     return 0;
3311 }
3312 #endif
3313 
3314 /* NOTE: This table is sorted by name to make the help message useful */
3315 /* *INDENT-OFF* */
3316 static Config_Type Arg_Table [] =
3317 {
3318    PARSE_SET(
3319       "accept_all_cookies", 4|SET_ARG,		LYAcceptAllCookies,
3320       "\naccept cookies without prompting if Set-Cookie handling\nis on"
3321    ),
3322 #if USE_BLAT_MAILER
3323    PARSE_SET(
3324       "altblat",	4|TOGGLE_ARG,		mail_is_altblat,
3325       "select mail tool (`"THIS_BLAT_MAIL"' ==> `"THAT_BLAT_MAIL"')"
3326    ),
3327 #endif
3328    PARSE_FUN(
3329       "anonymous",	2|FUNCTION_ARG,		anonymous_fun,
3330       "apply restrictions for anonymous account,\nsee also -restrictions"
3331    ),
3332    PARSE_FUN(
3333       "assume_charset", 4|NEED_FUNCTION_ARG,	assume_charset_fun,
3334       "=MIMEname\ncharset for documents that don't specify it"
3335    ),
3336    PARSE_FUN(
3337       "assume_local_charset", 4|NEED_FUNCTION_ARG, assume_local_charset_fun,
3338       "=MIMEname\ncharset assumed for local files"
3339    ),
3340    PARSE_FUN(
3341       "assume_unrec_charset", 4|NEED_FUNCTION_ARG, assume_unrec_charset_fun,
3342       "=MIMEname\nuse this instead of unrecognized charsets"
3343    ),
3344    PARSE_FUN(
3345       "auth",		4|NEED_FUNCTION_ARG,	auth_fun,
3346       "=id:pw\nauthentication information for protected documents"
3347    ),
3348    PARSE_FUN(
3349       "base",		4|FUNCTION_ARG,		base_fun,
3350       "prepend a request URL comment and BASE tag to text/html\n\
3351 outputs for -source dumps"
3352    ),
3353 #ifndef DISABLE_BIBP
3354    PARSE_STR(
3355       "bibhost",	4|NEED_LYSTRING_ARG,	BibP_bibhost,
3356       "=URL\nlocal bibp server (default http://bibhost/)"
3357    ),
3358 #endif
3359 #ifdef USE_BLINK
3360    PARSE_SET(
3361       "blink",		4|SET_ARG,		term_blink_is_boldbg,
3362       "enable bright background via the BLINK terminal attribute"
3363    ),
3364 #endif
3365    PARSE_SET(
3366       "book",		4|SET_ARG,		bookmark_start,
3367       "use the bookmark page as the startfile"
3368    ),
3369    PARSE_SET(
3370       "buried_news",	4|TOGGLE_ARG,		scan_for_buried_news_references,
3371       "toggles scanning of news articles for buried references"
3372    ),
3373    PARSE_FUN(
3374       "cache",		4|NEED_FUNCTION_ARG,	cache_fun,
3375       "=NUMBER\nNUMBER of documents cached in memory"
3376    ),
3377    PARSE_SET(
3378       "case",		4|SET_ARG,		LYcase_sensitive,
3379       "enable case sensitive user searching"
3380    ),
3381    PARSE_SET(
3382       "center",		4|TOGGLE_ARG,		no_table_center,
3383       "toggle center alignment in HTML TABLE"
3384    ),
3385    PARSE_STR(
3386       "cfg",		2|NEED_LYSTRING_ARG,	lynx_cfg_file,
3387       "=FILENAME\nspecifies a lynx.cfg file other than the default"
3388    ),
3389    PARSE_FUN(
3390       "child",		4|FUNCTION_ARG,		child_fun,
3391       "exit on left-arrow in startfile, and disable save to disk"
3392    ),
3393    PARSE_FUN(
3394       "child_relaxed",	4|FUNCTION_ARG,		child_relaxed_fun,
3395       "exit on left-arrow in startfile (allows save to disk)"
3396    ),
3397 #ifdef USE_CMD_LOGGING
3398    PARSE_STR(
3399       "cmd_log",	2|NEED_LYSTRING_ARG,	lynx_cmd_logfile,
3400       "=FILENAME\nlog keystroke commands to the given file"
3401    ),
3402    PARSE_STR(
3403       "cmd_script",	2|NEED_LYSTRING_ARG,	lynx_cmd_script,
3404       "=FILENAME\nread keystroke commands from the given file\n(see -cmd_log)"
3405    ),
3406 #endif
3407 #ifdef USE_SLANG
3408    PARSE_FUN(
3409       "color",		4|FUNCTION_ARG,		color_fun,
3410       "force color mode on with standard bg colors"
3411    ),
3412 #endif
3413    PARSE_INT(
3414       "connect_timeout", 4|NEED_INT_ARG,	connect_timeout,
3415       "=N\nset the N-second connection timeout"
3416    ),
3417 #ifdef MISC_EXP
3418    PARSE_FUN(
3419       "convert_to",	4|FUNCTION_ARG,		convert_to_fun,
3420       "=FORMAT\nconvert input, FORMAT is in MIME type notation\n(experimental)"
3421    ),
3422 #endif
3423 #ifdef USE_PERSISTENT_COOKIES
3424    PARSE_STR(
3425       "cookie_file",	4|LYSTRING_ARG,		LYCookieFile,
3426       "=FILENAME\nspecifies a file to use to read cookies"
3427    ),
3428    PARSE_STR(
3429       "cookie_save_file", 4|LYSTRING_ARG,	LYCookieSaveFile,
3430       "=FILENAME\nspecifies a file to use to store cookies"
3431    ),
3432 #endif /* USE_PERSISTENT_COOKIES */
3433    PARSE_SET(
3434       "cookies",	4|TOGGLE_ARG,		LYSetCookies,
3435       "toggles handling of Set-Cookie headers"
3436    ),
3437 #ifndef VMS
3438    PARSE_SET(
3439       "core",		4|TOGGLE_ARG,		LYNoCore,
3440       "toggles forced core dumps on fatal errors"
3441    ),
3442 #endif
3443    PARSE_FUN(
3444       "crawl",		4|FUNCTION_ARG,		crawl_fun,
3445       "with -traversal, output each page to a file\n\
3446 with -dump, format output as with -traversal, but to stdout"
3447    ),
3448 #ifdef USE_CURSES_PADS
3449    PARSE_SET(
3450       "curses_pads",	4|TOGGLE_ARG,		LYuseCursesPads,
3451       "uses curses pad feature to support left/right shifting"
3452    ),
3453 #endif
3454 #ifdef DISP_PARTIAL
3455    PARSE_SET(
3456       "debug_partial",	4|TOGGLE_ARG,		debug_display_partial,
3457       "incremental display stages with MessageSecs delay"
3458    ),
3459 #endif
3460 #ifdef USE_DEFAULT_COLORS
3461    PARSE_SET(
3462       "default_colors",	4|TOGGLE_ARG,		LYuse_default_colors,
3463       "use terminal default foreground/background colors"
3464    ),
3465 #endif
3466    PARSE_INT(
3467       "delay",		4|NEED_TIME_ARG,	DelaySecs,
3468       "=NNN\nset NNN-second delay at statusline message"
3469    ),
3470    PARSE_FUN(
3471       "display",	4|NEED_FUNCTION_ARG,	display_fun,
3472       "=DISPLAY\nset the display variable for X exec'ed programs"
3473    ),
3474    PARSE_FUN(
3475       "display_charset", 4|NEED_FUNCTION_ARG,	display_charset_fun,
3476       "=MIMEname\ncharset for the terminal output"
3477    ),
3478    PARSE_SET(
3479       "dont_wrap_pre",	4|SET_ARG,		dont_wrap_pre,
3480       "inhibit wrapping of text in <pre> when -dump'ing and\n\
3481 -crawl'ing, mark wrapped lines in interactive session"
3482    ),
3483    PARSE_FUN(
3484       "dump",		1|FUNCTION_ARG,		dump_output_fun,
3485       "dump the first file to stdout and exit"
3486    ),
3487    PARSE_FUN(
3488       "editor",		4|NEED_FUNCTION_ARG,	editor_fun,
3489       "=EDITOR\nenable edit mode with specified editor"
3490    ),
3491    PARSE_SET(
3492       "emacskeys",	4|SET_ARG,		emacs_keys,
3493       "enable emacs-like key movement"
3494    ),
3495    PARSE_SET(
3496       "enable_scrollback", 4|TOGGLE_ARG,	enable_scrollback,
3497       "\ntoggles compatibility with comm programs' scrollback\n\
3498 keys (may be incompatible with some curses packages)"
3499    ),
3500    PARSE_FUN(
3501       "error_file",	4|NEED_FUNCTION_ARG,	error_file_fun,
3502       "=FILE\nwrite the HTTP status code here"
3503    ),
3504 #if defined(EXEC_LINKS) || defined(EXEC_SCRIPTS)
3505 #ifndef NEVER_ALLOW_REMOTE_EXEC
3506    PARSE_FUN(
3507       "exec",		4|FUNCTION_ARG,		exec_fun,
3508       "enable local program execution"
3509    ),
3510 #endif
3511 #endif /* EXEC_LINKS || EXEC_SCRIPTS */
3512 #ifdef VMS
3513    PARSE_SET(
3514       "fileversions",	4|SET_ARG,		HTVMSFileVersions,
3515       "include all versions of files in local VMS directory\nlistings"
3516    ),
3517 #endif
3518 #ifdef LY_FIND_LEAKS
3519    PARSE_SET(
3520       "find_leaks",	4|TOGGLE_ARG,		LYfind_leaks,
3521       "toggles memory-leak checking"
3522    ),
3523 #endif
3524    PARSE_SET(
3525       "force_empty_hrefless_a",	4|SET_ARG,	force_empty_hrefless_a,
3526       "\nforce HREF-less 'A' elements to be empty (close them as\n\
3527 soon as they are seen)"
3528    ),
3529    PARSE_SET(
3530       "force_html",	4|SET_ARG,		LYforce_HTML_mode,
3531       "forces the first document to be interpreted as HTML"
3532    ),
3533    PARSE_SET(
3534       "force_secure",	4|TOGGLE_ARG,		LYForceSSLCookiesSecure,
3535       "toggles forcing of the secure flag for SSL cookies"
3536    ),
3537 #if !defined(NO_OPTION_FORMS) && !defined(NO_OPTION_MENU)
3538    PARSE_SET(
3539       "forms_options",	4|TOGGLE_ARG,		LYUseFormsOptions,
3540       "toggles forms-based vs old-style options menu"
3541    ),
3542 #endif
3543    PARSE_SET(
3544       "from",		4|TOGGLE_ARG,		LYNoFromHeader,
3545       "toggle transmission of From headers"
3546    ),
3547 #ifndef DISABLE_FTP
3548    PARSE_SET(
3549       "ftp",		4|UNSET_ARG,		ftp_ok,
3550       "disable ftp access"
3551    ),
3552 #endif
3553    PARSE_FUN(
3554       "get_data",	2|FUNCTION_ARG,		get_data_fun,
3555       "user data for get forms, read from stdin,\nterminated by '---' on a line"
3556    ),
3557    PARSE_SET(
3558       "head",		4|SET_ARG,		HEAD_request,
3559       "send a HEAD request"
3560    ),
3561    PARSE_FUN(
3562       "help",		4|FUNCTION_ARG,		help_fun,
3563       "print this usage message"
3564    ),
3565    PARSE_FUN(
3566       "hiddenlinks",	4|NEED_FUNCTION_ARG,	hiddenlinks_fun,
3567       "=[option]\nhidden links: options are merge, listonly, or ignore"
3568    ),
3569    PARSE_SET(
3570       "historical",	4|TOGGLE_ARG,		historical_comments,
3571       "toggles use of '>' or '-->' as terminator for comments"
3572    ),
3573    PARSE_FUN(
3574       "homepage",	4|NEED_FUNCTION_ARG,	homepage_fun,
3575       "=URL\nset homepage separate from start page"
3576    ),
3577    PARSE_SET(
3578       "html5_charsets",	4|TOGGLE_ARG,		html5_charsets,
3579       "toggles use of HTML5 charset replacements"
3580    ),
3581    PARSE_SET(
3582       "image_links",	4|TOGGLE_ARG,		clickable_images,
3583       "toggles inclusion of links for all images"
3584    ),
3585    PARSE_STR(
3586       "index",		4|NEED_LYSTRING_ARG,	indexfile,
3587       "=URL\nset the default index file to URL"
3588    ),
3589    PARSE_SET(
3590       "ismap",		4|TOGGLE_ARG,		LYNoISMAPifUSEMAP,
3591       "toggles inclusion of ISMAP links when client-side\nMAPs are present"
3592    ),
3593 #ifdef USE_JUSTIFY_ELTS
3594    PARSE_SET(
3595       "justify",	4|SET_ARG,		ok_justify,
3596       "do justification of text"
3597    ),
3598 #endif
3599    PARSE_INT(
3600       "link",		4|NEED_INT_ARG,		crawl_count,
3601       "=NUMBER\nstarting count for lnk#.dat files produced by -crawl"
3602    ),
3603    PARSE_SET(
3604       "listonly",	4|TOGGLE_ARG,		dump_links_only,
3605       "with -dump, forces it to show only the list of links"
3606    ),
3607    PARSE_SET(
3608       "localhost",	4|SET_ARG,		local_host_only,
3609       "disable URLs that point to remote hosts"
3610    ),
3611 #if defined(EXEC_LINKS) || defined(EXEC_SCRIPTS)
3612    PARSE_SET(
3613       "locexec",	4|SET_ARG,		local_exec_on_local_files,
3614       "enable local program execution from local files only"
3615    ),
3616 #endif /* EXEC_LINKS || EXEC_SCRIPTS */
3617 #if defined(USE_COLOR_STYLE)
3618    PARSE_STR(
3619       "lss",		2|NEED_LYSTRING_ARG,	lynx_lss_file2,
3620       "=FILENAME\nspecifies a lynx.lss file other than the default"
3621    ),
3622 #endif
3623    PARSE_FUN(
3624       "mime_header",	4|FUNCTION_ARG,		mime_header_fun,
3625       "include mime headers and force source dump"
3626    ),
3627    PARSE_SET(
3628       "minimal",	4|TOGGLE_ARG,		minimal_comments,
3629       "toggles minimal versus valid comment parsing"
3630    ),
3631 #ifdef EXP_NESTED_TABLES
3632    PARSE_SET(
3633       "nested_tables",	4|TOGGLE_ARG,		nested_tables,
3634       "toggles nested-tables logic"
3635    ),
3636 #endif
3637 #ifndef DISABLE_NEWS
3638    PARSE_FUN(
3639       "newschunksize",	4|NEED_FUNCTION_ARG,	newschunksize_fun,
3640       "=NUMBER\nnumber of articles in chunked news listings"
3641    ),
3642    PARSE_FUN(
3643       "newsmaxchunk",	4|NEED_FUNCTION_ARG,	newsmaxchunk_fun,
3644       "=NUMBER\nmaximum news articles in listings before chunking"
3645    ),
3646 #endif
3647 #if USE_BLAT_MAILER
3648    PARSE_SET(
3649       "noblat",		4|TOGGLE_ARG,		mail_is_blat,
3650       "select mail tool (`"THIS_BLAT_MAIL"' ==> `"SYSTEM_MAIL"')"
3651    ),
3652 #endif
3653    PARSE_FUN(
3654       "nobold",		4|FUNCTION_ARG,		nobold_fun,
3655       "disable bold video-attribute"
3656    ),
3657    PARSE_FUN(
3658       "nobrowse",	4|FUNCTION_ARG,		nobrowse_fun,
3659       "disable directory browsing"
3660    ),
3661    PARSE_SET(
3662       "nocc",		4|SET_ARG,		LYNoCc,
3663       "disable Cc: prompts for self copies of mailings"
3664    ),
3665    PARSE_FUN(
3666       "nocolor",	4|FUNCTION_ARG,		nocolor_fun,
3667       "turn off color support"
3668    ),
3669 #if defined(EXEC_LINKS) || defined(EXEC_SCRIPTS)
3670    PARSE_SET(
3671       "noexec",		4|UNSET_ARG,		local_exec,
3672       "disable local program execution (DEFAULT)"
3673    ),
3674 #endif /* EXEC_LINKS || EXEC_SCRIPTS */
3675    PARSE_SET(
3676       "nofilereferer",	4|SET_ARG,		no_filereferer,
3677       "disable transmission of Referer headers for file URLs"
3678    ),
3679    PARSE_SET(
3680       "nolist",		4|SET_ARG,		no_list,
3681       "disable the link list feature in dumps"
3682    ),
3683    PARSE_SET(
3684       "nolog",		4|UNSET_ARG,		error_logging,
3685       "disable mailing of error messages to document owners"
3686    ),
3687    PARSE_SET(
3688       "nomargins",	4|SET_ARG,		no_margins,
3689       "disable the right/left margins in the default\nstyle-sheet"
3690    ),
3691    PARSE_FUN(
3692       "nomore",		4|FUNCTION_ARG,		nomore_fun,
3693       "disable -more- string in statusline messages"
3694    ),
3695 #if defined(HAVE_SIGACTION) && defined(SIGWINCH)
3696    PARSE_SET(
3697       "nonrestarting_sigwinch", 4|SET_ARG,	LYNonRestartingSIGWINCH,
3698       "\nmake window size change handler non-restarting"
3699    ),
3700 #endif /* HAVE_SIGACTION */
3701    PARSE_SET(
3702       "nonumbers",	4|SET_ARG,		no_numbers,
3703       "disable the link/form numbering feature in dumps"
3704    ),
3705    PARSE_FUN(
3706       "nopause",	4|FUNCTION_ARG,		nopause_fun,
3707       "disable forced pauses for statusline messages"
3708    ),
3709    PARSE_SET(
3710       "noprint",	4|SET_ARG,		no_print,
3711       "disable some print functions, like -restrictions=print"
3712    ),
3713    PARSE_SET(
3714       "noredir",	4|SET_ARG,		no_url_redirection,
3715       "don't follow Location: redirection"
3716    ),
3717    PARSE_SET(
3718       "noreferer",	4|SET_ARG,		LYNoRefererHeader,
3719       "disable transmission of Referer headers"
3720    ),
3721    PARSE_FUN(
3722       "noreverse",	4|FUNCTION_ARG,		noreverse_fun,
3723       "disable reverse video-attribute"
3724    ),
3725 #ifdef SOCKS
3726    PARSE_SET(
3727       "nosocks",	2|UNSET_ARG,		socks_flag,
3728       "don't use SOCKS proxy for this session"
3729    ),
3730 #endif
3731    PARSE_SET(
3732       "nostatus",	4|SET_ARG,		no_statusline,
3733       "disable the miscellaneous information messages"
3734    ),
3735    PARSE_SET(
3736       "notitle",	4|SET_ARG,		no_title,
3737       "disable the title at the top of each page"
3738    ),
3739    PARSE_FUN(
3740       "nounderline",	4|FUNCTION_ARG,		nounderline_fun,
3741       "disable underline video-attribute"
3742    ),
3743 #ifdef MISC_EXP
3744    PARSE_FUN(
3745       "nozap",		4|FUNCTION_ARG,		nozap_fun,
3746       "=DURATION (\"initially\" or \"full\") disable checks for 'z' key"
3747    ),
3748 #endif
3749    PARSE_SET(
3750       "number_fields",	4|SET_ARG,		number_fields,
3751       "force numbering of links as well as form input fields"
3752    ),
3753    PARSE_SET(
3754       "number_links",	4|SET_ARG,		number_links,
3755       "force numbering of links"
3756    ),
3757 #ifdef DISP_PARTIAL
3758    PARSE_SET(
3759       "partial",	4|TOGGLE_ARG,		display_partial_flag,
3760       "toggles display partial pages while downloading"
3761    ),
3762    PARSE_INT(
3763       "partial_thres",	4|NEED_INT_ARG,		partial_threshold,
3764       "[=NUMBER]\nnumber of lines to render before repainting display\n\
3765 with partial-display logic"
3766    ),
3767 #endif
3768 #ifndef DISABLE_FTP
3769    PARSE_SET(
3770       "passive-ftp",	4|TOGGLE_ARG,		ftp_passive,
3771       "toggles passive ftp connection"
3772    ),
3773 #endif
3774    PARSE_FUN(
3775       "pauth",		4|NEED_FUNCTION_ARG,	pauth_fun,
3776       "=id:pw\nauthentication information for protected proxy server"
3777    ),
3778    PARSE_SET(
3779       "popup",		4|UNSET_ARG,		LYUseDefSelPop,
3780       "toggles handling of single-choice SELECT options via\n\
3781 popup windows or as lists of radio buttons"
3782    ),
3783    PARSE_FUN(
3784       "post_data",	2|FUNCTION_ARG,		post_data_fun,
3785       "user data for post forms, read from stdin,\n\
3786 terminated by '---' on a line"
3787    ),
3788    PARSE_SET(
3789       "preparsed",	4|SET_ARG,		LYPreparsedSource,
3790       "show parsed text/html with -source and in source view\n\
3791 to visualize how lynx behaves with invalid HTML"
3792    ),
3793 #ifdef USE_PRETTYSRC
3794    PARSE_SET(
3795       "prettysrc",	4|SET_ARG,		LYpsrc,
3796       "do syntax highlighting and hyperlink handling in source\nview"
3797    ),
3798 #endif
3799    PARSE_SET(
3800       "print",		4|UNSET_ARG,		no_print,
3801       "enable print functions (DEFAULT), opposite of -noprint"
3802    ),
3803    PARSE_SET(
3804       "pseudo_inlines", 4|TOGGLE_ARG,		pseudo_inline_alts,
3805       "toggles pseudo-ALTs for inlines with no ALT string"
3806    ),
3807    PARSE_SET(
3808       "raw",		4|UNSET_ARG,		LYUseDefaultRawMode,
3809       "toggles default setting of 8-bit character translations\n\
3810 or CJK mode for the startup character set"
3811    ),
3812    PARSE_SET(
3813       "realm",		4|SET_ARG,		check_realm,
3814       "restricts access to URLs in the starting realm"
3815    ),
3816    PARSE_INT(
3817       "read_timeout",	4|NEED_INT_ARG,		reading_timeout,
3818       "=N\nset the N-second read-timeout"
3819    ),
3820    PARSE_SET(
3821       "reload",		4|SET_ARG,		reloading,
3822       "flushes the cache on a proxy server\n(only the first document affected)"
3823    ),
3824    PARSE_FUN(
3825       "restrictions",	4|FUNCTION_ARG,		restrictions_fun,
3826       "=[options]\nuse -restrictions to see list"
3827    ),
3828    PARSE_SET(
3829       "resubmit_posts", 4|TOGGLE_ARG,		LYresubmit_posts,
3830       "toggles forced resubmissions (no-cache) of forms with\n\
3831 method POST when the documents they returned are sought\n\
3832 with the PREV_DOC command or from the History List"
3833    ),
3834    PARSE_SET(
3835       "rlogin",		4|UNSET_ARG,		rlogin_ok,
3836       "disable rlogins"
3837    ),
3838 #if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401
3839    PARSE_FUN(
3840       "scrsize",	4|NEED_FUNCTION_ARG,	scrsize_fun,
3841       "=width,height\nsize of window"
3842    ),
3843 #endif
3844 #ifdef USE_SCROLLBAR
3845    PARSE_SET(
3846       "scrollbar",	4|TOGGLE_ARG,		LYShowScrollbar,
3847       "toggles showing scrollbar"
3848    ),
3849    PARSE_SET(
3850       "scrollbar_arrow", 4|TOGGLE_ARG,		LYsb_arrow,
3851       "toggles showing arrows at ends of the scrollbar"
3852    ),
3853 #endif
3854    PARSE_FUN(
3855       "selective",	4|FUNCTION_ARG,		selective_fun,
3856       "require .www_browsable files to browse directories"
3857    ),
3858 #ifdef USE_SESSIONS
3859    PARSE_STR(
3860       "session",	2|NEED_LYSTRING_ARG,	session_file,
3861       "=FILENAME\nresumes from specified file on startup and\n\
3862 saves session to that file on exit"
3863    ),
3864    PARSE_STR(
3865       "sessionin",	2|NEED_LYSTRING_ARG,	sessionin_file,
3866       "=FILENAME\nresumes session from specified file"
3867    ),
3868    PARSE_STR(
3869       "sessionout",	2|NEED_LYSTRING_ARG,	sessionout_file,
3870       "=FILENAME\nsaves session to specified file"
3871    ),
3872 #endif /* USE_SESSIONS */
3873    PARSE_SET(
3874       "short_url",	4|SET_ARG,		long_url_ok,
3875       "enables examination of beginning and end of long URL in\nstatus line"
3876    ),
3877    PARSE_SET(
3878       "show_cfg",	1|SET_ARG,		show_cfg,
3879       "Show `LYNX.CFG' setting"
3880    ),
3881    PARSE_SET(
3882       "show_cursor",	4|TOGGLE_ARG,		LYUseDefShoCur,
3883       "toggles hiding of the cursor in the lower right corner"
3884    ),
3885 #ifdef USE_READPROGRESS
3886    PARSE_SET(
3887       "show_rate",	4|TOGGLE_ARG,		LYShowTransferRate,
3888       "toggles display of transfer rate"
3889    ),
3890 #endif
3891    PARSE_SET(
3892       "soft_dquotes",	4|TOGGLE_ARG,		soft_dquotes,
3893       "toggles emulation of the old Netscape and Mosaic\n\
3894 bug which treated '>' as a co-terminator for\ndouble-quotes and tags"
3895    ),
3896    PARSE_FUN(
3897       "source",		4|FUNCTION_ARG,		source_fun,
3898       "dump the source of the first file to stdout and exit"
3899    ),
3900    PARSE_SET(
3901       "stack_dump",	4|SET_ARG,		stack_dump,
3902       "disable SIGINT cleanup handler"
3903    ),
3904    PARSE_SET(
3905       "startfile_ok",	4|SET_ARG,		startfile_ok,
3906       "allow non-http startfile and homepage with -validate"
3907    ),
3908    PARSE_SET(
3909       "stderr",		4|SET_ARG,		dump_to_stderr,
3910       "write warning messages to standard error when -dump\nor -source is used"
3911    ),
3912    PARSE_SET(
3913       "stdin",		4|SET_ARG,		startfile_stdin,
3914       "read startfile from standard input"
3915    ),
3916 #ifdef SYSLOG_REQUESTED_URLS
3917    PARSE_STR(
3918       "syslog",		4|NEED_LYSTRING_ARG,	syslog_txt,
3919       "=text\ninformation for syslog call"
3920    ),
3921    PARSE_SET(
3922       "syslog-urls",	4|SET_ARG,		syslog_requested_urls,
3923       "log requested URLs with syslog"
3924    ),
3925 #endif
3926    PARSE_SET(
3927       "tagsoup",	4|SET_ARG,		DTD_recovery,
3928       "use TagSoup rather than SortaSGML parser"
3929    ),
3930    PARSE_SET(
3931       "telnet",		4|UNSET_ARG,		telnet_ok,
3932       "disable telnets"
3933    ),
3934    PARSE_STR(
3935       "term",		4|NEED_STRING_ARG,	terminal,
3936       "=TERM\nset terminal type to TERM"
3937    ),
3938 #ifdef _WINDOWS
3939    PARSE_INT(
3940       "timeout",	4|INT_ARG,		lynx_timeout,
3941       "=NUMBER\nset TCP/IP timeout"
3942    ),
3943 #endif
3944    PARSE_SET(
3945       "tlog",		2|TOGGLE_ARG,		LYUseTraceLog,
3946       "toggles use of a Lynx Trace Log for the current\nsession"
3947    ),
3948 #ifdef TEXTFIELDS_MAY_NEED_ACTIVATION
3949    PARSE_SET(
3950       "tna",		4|SET_ARG,		textfields_activation_option,
3951       "turn on \"Textfields Need Activation\" mode"
3952    ),
3953 #endif
3954 #ifndef NO_LYNX_TRACE
3955    PARSE_SET(
3956       "trace",		1|SET_ARG,		WWW_TraceFlag,
3957       "turns on Lynx trace mode"
3958    ),
3959    PARSE_INT(
3960       "trace_mask",	1|INT_ARG,		WWW_TraceMask,
3961       "customize Lynx trace mode"
3962    ),
3963 #endif
3964    PARSE_FUN(
3965       "traversal",	4|FUNCTION_ARG,		traversal_fun,
3966       "traverse all http links derived from startfile"
3967    ),
3968    PARSE_SET(
3969       "trim_input_fields", 2|SET_ARG,		LYtrimInputFields,
3970       "\ntrim input text/textarea fields in forms"
3971    ),
3972    PARSE_SET(
3973       "underline_links",4|TOGGLE_ARG,		LYUnderlineLinks,
3974       "toggles use of underline/bold attribute for links"
3975    ),
3976    PARSE_SET(
3977       "underscore",	4|TOGGLE_ARG,		use_underscore,
3978       "toggles use of _underline_ format in dumps"
3979    ),
3980    PARSE_SET(
3981       "unique_urls",	4|TOGGLE_ARG,		unique_urls,
3982       "toggles use of unique-urls setting for -dump and -listonly options"
3983    ),
3984 #if defined(USE_MOUSE)
3985    PARSE_SET(
3986       "use_mouse",	4|SET_ARG,		LYUseMouse,
3987       "turn on mouse support"
3988    ),
3989 #endif
3990    PARSE_STR(
3991       "useragent",	4|NEED_LYSTRING_ARG,	LYUserAgent,
3992       "=Name\nset alternate Lynx User-Agent header"
3993    ),
3994    PARSE_SET(
3995       "validate",	2|SET_ARG,		LYValidate,
3996       "accept only http URLs (meant for validation)\n\
3997 implies more restrictions than -anonymous, but\n\
3998 goto is allowed for http and https"
3999    ),
4000    PARSE_SET(
4001       "verbose",	4|TOGGLE_ARG,		verbose_img,
4002       "toggles [LINK], [IMAGE] and [INLINE] comments\n\
4003 with filenames of these images"
4004    ),
4005    PARSE_FUN(
4006       "version",	1|FUNCTION_ARG,		version_fun,
4007       "print Lynx version information"
4008    ),
4009    PARSE_SET(
4010       "vikeys",		4|SET_ARG,		vi_keys,
4011       "enable vi-like key movement"
4012    ),
4013 #ifdef __DJGPP__
4014    PARSE_SET(
4015       "wdebug",		4|TOGGLE_ARG,		watt_debug,
4016       "enables Waterloo tcp/ip packet debug. Prints to watt\ndebugfile"
4017   ),
4018 #endif /* __DJGPP__ */
4019    PARSE_FUN(
4020       "width",		4|NEED_FUNCTION_ARG,	width_fun,
4021       "=NUMBER\nscreen width for formatting of dumps (default is 80)"
4022    ),
4023 #ifndef NO_DUMP_WITH_BACKSPACES
4024    PARSE_SET(
4025       "with_backspaces", 4|SET_ARG,		with_backspaces,
4026       "emit backspaces in output if -dumping or -crawling\n(like 'man' does)"
4027    ),
4028 #endif
4029    PARSE_SET(
4030       "xhtml-parsing",	4|SET_ARG,		LYxhtml_parsing,
4031       "enable XHTML 1.0 parsing"
4032    ),
4033    PARSE_NIL
4034 };
4035 /* *INDENT-ON* */
4036 
print_help_strings(const char * name,const char * help,const char * value,int option)4037 static void print_help_strings(const char *name,
4038 			       const char *help,
4039 			       const char *value,
4040 			       int option)
4041 {
4042     int pad;
4043     int c;
4044     int first;
4045     int field_width = 20;
4046 
4047     pad = field_width - (2 + option + (int) strlen(name));
4048 
4049     fprintf(stdout, "  %s%s", option ? "-" : "", name);
4050 
4051     if (*help != '=') {
4052 	pad--;
4053 	while (pad > 0) {
4054 	    fputc(' ', stdout);
4055 	    pad--;
4056 	}
4057 	fputc(' ', stdout);	/* at least one space */
4058 	first = 0;
4059     } else {
4060 	first = pad;
4061     }
4062 
4063     if (strchr(help, '\n') == 0) {
4064 	fprintf(stdout, "%s", help);
4065     } else {
4066 	while ((c = *help) != 0) {
4067 	    if (c == '\n') {
4068 		if ((pad = --first) < 0) {
4069 		    pad = field_width;
4070 		} else {
4071 		    c = ' ';
4072 		}
4073 		fputc(c, stdout);
4074 		while (pad--)
4075 		    fputc(' ', stdout);
4076 	    } else {
4077 		fputc(c, stdout);
4078 	    }
4079 	    help++;
4080 	    first--;
4081 	}
4082     }
4083     if (value)
4084 	printf(" (%s)", value);
4085     fputc('\n', stdout);
4086 }
4087 
print_help_and_exit(int exit_status)4088 static void print_help_and_exit(int exit_status)
4089 {
4090     Config_Type *p;
4091 
4092     if (pgm == NULL)
4093 	pgm = "lynx";
4094 
4095     SetOutputMode(O_TEXT);
4096 
4097     fprintf(stdout, gettext("USAGE: %s [options] [file]\n"), pgm);
4098     fprintf(stdout, gettext("Options are:\n"));
4099 #ifdef VMS
4100     print_help_strings("",
4101 		       "receive the arguments from stdin (enclose\n\
4102 in double-quotes (\"-\") on VMS)", NULL, TRUE);
4103 #else
4104     print_help_strings("", "receive options and arguments from stdin", NULL, TRUE);
4105 #endif /* VMS */
4106 
4107     for (p = Arg_Table; p->name != 0; p++) {
4108 	char temp[LINESIZE], *value = temp;
4109 	ParseUnionPtr q = ParseUnionOf(p);
4110 
4111 	switch (p->type & ARG_TYPE_MASK) {
4112 	case TOGGLE_ARG:
4113 	case SET_ARG:
4114 	    strcpy(temp, *(q->set_value) ? "on" : "off");
4115 	    break;
4116 	case UNSET_ARG:
4117 	    strcpy(temp, *(q->set_value) ? "off" : "on");
4118 	    break;
4119 	case INT_ARG:
4120 	    sprintf(temp, "%d", *(q->int_value));
4121 	    break;
4122 	case TIME_ARG:
4123 	    sprintf(temp, SECS_FMT, (double) Secs2SECS(*(q->int_value)));
4124 	    break;
4125 	case STRING_ARG:
4126 	    if ((value = *(q->str_value)) != 0
4127 		&& !*value)
4128 		value = 0;
4129 	    break;
4130 	default:
4131 	    value = 0;
4132 	    break;
4133 	}
4134 	print_help_strings(p->name, p->help_string, value, TRUE);
4135     }
4136 
4137     SetOutputMode(O_BINARY);
4138 
4139     exit_immediately(exit_status);
4140 }
4141 
4142 /*
4143  * This function performs a string comparison on two strings a and b.  a is
4144  * assumed to be an ordinary null terminated string, but b may be terminated
4145  * by an '=', '+' or '-' character.  If terminated by '=', *c will be pointed
4146  * to the character following the '='.  If terminated by '+' or '-', *c will
4147  * be pointed to that character.  (+/- added for toggle processing - BL.)
4148  * If a and b match, it returns 1.  Otherwise 0 is returned.
4149  */
arg_eqs_parse(const char * a,char * b,char ** c)4150 static int arg_eqs_parse(const char *a,
4151 			 char *b,
4152 			 char **c)
4153 {
4154     int result = -1;
4155 
4156     *c = NULL;
4157     while (result < 0) {
4158 	if ((*a != *b)
4159 	    || (*a == 0)
4160 	    || (*b == 0)) {
4161 	    if (*a == 0) {
4162 		switch (*b) {
4163 		case '\t':	/* embedded blank when reading stdin */
4164 		case ' ':
4165 		    *c = LYSkipBlanks(b);
4166 		    result = 1;
4167 		    break;
4168 		case '=':
4169 		case ':':
4170 		    *c = b + 1;
4171 		    result = 1;
4172 		    break;
4173 		case '-':
4174 #if OPTNAME_ALLOW_DASHES
4175 		    if (isalpha(UCH(b[1]))) {
4176 			result = 0;
4177 			break;
4178 		    }
4179 #endif
4180 		    /* FALLTHRU */
4181 		case '+':
4182 		    *c = b;
4183 		    result = 1;
4184 		    break;
4185 		case 0:
4186 		    result = 1;
4187 		    break;
4188 		default:
4189 		    result = 0;
4190 		    break;
4191 		}
4192 	    } else {
4193 #if OPTNAME_ALLOW_DASHES
4194 		if (!(*a == '_' && *b == '-'))
4195 #endif
4196 		    result = 0;
4197 	    }
4198 	}
4199 	a++;
4200 	b++;
4201     }
4202     return result;
4203 }
4204 
4205 #define is_true(s)  (*s == '1' || *s == '+' || !strcasecomp(s, "on")  || !strcasecomp(s, "true"))
4206 #define is_false(s) (*s == '0' || *s == '-' || !strcasecomp(s, "off") || !strcasecomp(s, "false"))
4207 
4208 /*
4209  * Parse an option.
4210  *	argv[] points to the beginning of the unprocessed options.
4211  *	mask is used to select certain options which must be processed
4212  *		before others.
4213  *	countp (if nonnull) points to an index into argv[], which is updated
4214  *		to reflect option values which are also parsed.
4215  */
parse_arg(char ** argv,unsigned mask,int * countp)4216 static BOOL parse_arg(char **argv,
4217 		      unsigned mask,
4218 		      int *countp)
4219 {
4220     Config_Type *p;
4221     char *arg_name;
4222 
4223 #if EXTENDED_STARTFILE_RECALL
4224     static BOOLEAN no_options_further = FALSE;	/* set to TRUE after '--' argument */
4225     static int nof_index = 0;	/* set the index of -- argument */
4226 #endif
4227 
4228     arg_name = argv[0];
4229     CTRACE((tfp, "parse_arg(arg_name=%s, mask=%u, count=%d)\n",
4230 	    arg_name, mask, countp ? *countp : -1));
4231 
4232 #if EXTENDED_STARTFILE_RECALL
4233     if (mask == (unsigned) ((countp != 0) ? 0 : 1)) {
4234 	no_options_further = FALSE;
4235 	/* want to reset nonoption when beginning scan for --stdin */
4236 	if (nonoption != 0) {
4237 	    FREE(nonoption);
4238 	}
4239     }
4240 #endif
4241 
4242     /*
4243      * Check for a command line startfile.  - FM
4244      */
4245     if (*arg_name != '-'
4246 #if EXTENDED_OPTION_LOGIC
4247 	|| ((no_options_further == TRUE)
4248 	    && (countp != 0)
4249 	    && (nof_index < (*countp)))
4250 #endif
4251 	) {
4252 #if EXTENDED_STARTFILE_RECALL
4253 	/*
4254 	 * On the last pass (mask==4), check for cases where we may want to
4255 	 * provide G)oto history for multiple startfiles.
4256 	 */
4257 	if (mask == 4) {
4258 	    if (nonoption != 0) {
4259 		LYEnsureAbsoluteURL(&nonoption, "NONOPTION", FALSE);
4260 		HTAddGotoURL(nonoption);
4261 		FREE(nonoption);
4262 	    }
4263 	    StrAllocCopy(nonoption, arg_name);
4264 	}
4265 #endif
4266 	StrAllocCopy(startfile, arg_name);
4267 	LYEscapeStartfile(&startfile);
4268 #ifdef _WINDOWS			/* 1998/01/14 (Wed) 20:11:17 */
4269 	HTUnEscape(startfile);
4270 	{
4271 	    char *q = startfile;
4272 
4273 	    while (*q++) {
4274 		if (*q == '|')
4275 		    *q = ':';
4276 	    }
4277 	}
4278 #endif
4279 	CTRACE((tfp, "parse_arg startfile:%s\n", startfile));
4280 	return (BOOL) (countp != 0);
4281     }
4282 #if EXTENDED_OPTION_LOGIC
4283     if (strcmp(arg_name, "--") == 0) {
4284 	no_options_further = TRUE;
4285 	nof_index = countp ? *countp : -1;
4286 	return TRUE;
4287     }
4288 #endif
4289 
4290     /* lose the first '-' character */
4291     arg_name++;
4292 
4293     /*
4294      * Skip any lone "-" arguments, because we've loaded the stdin input into
4295      * an HTList structure for special handling.  - FM
4296      */
4297     if (*arg_name == 0)
4298 	return TRUE;
4299 
4300     /* allow GNU-style options with -- prefix */
4301     if (*arg_name == '-')
4302 	++arg_name;
4303 
4304     CTRACE((tfp, "parse_arg lookup(%s)\n", arg_name));
4305 
4306     p = Arg_Table;
4307     while (p->name != 0) {
4308 	ParseUnionPtr q = ParseUnionOf(p);
4309 	ParseFunc fun;
4310 	char *next_arg = NULL;
4311 	char *temp_ptr = NULL;
4312 
4313 	if ((p->name[0] != *arg_name)
4314 	    || (0 == arg_eqs_parse(p->name, arg_name, &next_arg))) {
4315 	    p++;
4316 	    continue;
4317 	}
4318 
4319 	if (p->type & NEED_NEXT_ARG) {
4320 	    if (next_arg == 0) {
4321 		next_arg = argv[1];
4322 		if ((countp != 0) && (next_arg != 0))
4323 		    (*countp)++;
4324 	    }
4325 	    CTRACE((tfp, "...arg:%s\n", NONNULL(next_arg)));
4326 	}
4327 
4328 	/* ignore option if it's not our turn */
4329 	if (((unsigned) (p->type) & mask) == 0) {
4330 	    CTRACE((tfp, "...skip (mask %u/%d)\n", mask, p->type & 7));
4331 	    return FALSE;
4332 	}
4333 
4334 	switch (p->type & ARG_TYPE_MASK) {
4335 	case TOGGLE_ARG:	/* FALLTHRU */
4336 	case SET_ARG:		/* FALLTHRU */
4337 	case UNSET_ARG:
4338 	    if (q->set_value != 0) {
4339 		if (next_arg == 0) {
4340 		    switch (p->type & ARG_TYPE_MASK) {
4341 		    case TOGGLE_ARG:
4342 			*(q->set_value) = (BOOL) !(*(q->set_value));
4343 			break;
4344 		    case SET_ARG:
4345 			*(q->set_value) = TRUE;
4346 			break;
4347 		    case UNSET_ARG:
4348 			*(q->set_value) = FALSE;
4349 			break;
4350 		    }
4351 		} else if (is_true(next_arg)) {
4352 		    *(q->set_value) = TRUE;
4353 		} else if (is_false(next_arg)) {
4354 		    *(q->set_value) = FALSE;
4355 		}
4356 		/* deliberately ignore anything else - BL */
4357 	    }
4358 	    break;
4359 
4360 	case FUNCTION_ARG:
4361 	    fun = q->fun_value;
4362 	    if (0 != fun) {
4363 		if (-1 == (*fun) (next_arg)) {
4364 		}
4365 	    }
4366 	    break;
4367 
4368 	case LYSTRING_ARG:
4369 	    if ((q->str_value != 0) && (next_arg != 0))
4370 		StrAllocCopy(*(q->str_value), next_arg);
4371 	    break;
4372 
4373 	case INT_ARG:
4374 	    if ((q->int_value != 0) && (next_arg != 0))
4375 		*(q->int_value) = (int) strtol(next_arg, &temp_ptr, 0);
4376 	    break;
4377 
4378 	case TIME_ARG:
4379 	    if ((q->int_value != 0) && (next_arg != 0)) {
4380 		float ival;
4381 
4382 		if (1 == LYscanFloat(next_arg, &ival)) {
4383 		    *(q->int_value) = (int) SECS2Secs(ival);
4384 		}
4385 	    }
4386 	    break;
4387 
4388 	case STRING_ARG:
4389 	    if ((q->str_value != 0) && (next_arg != 0))
4390 		*(q->str_value) = next_arg;
4391 	    break;
4392 	}
4393 
4394 	Old_DTD = DTD_recovery;	/* BOOL != int */
4395 	return TRUE;
4396     }
4397 
4398     if (pgm == 0)
4399 	pgm = "LYNX";
4400 
4401     fprintf(stderr, gettext("%s: Invalid Option: %s\n"), pgm, argv[0]);
4402     print_help_and_exit(-1);
4403     return FALSE;
4404 }
4405 
4406 #ifndef VMS
4407 #if !defined(LYNX_DONT_CATCH_SIGBUS) || \
4408     !defined(LYNX_DONT_CATCH_SIGSEGV) || \
4409     !defined(LYNX_DONT_CATCH_SIGILL)
FatalProblem(int sig)4410 static void FatalProblem(int sig)
4411 {
4412     /*
4413      * Ignore further interrupts.  - mhc:  11/2/91
4414      */
4415 #ifndef NOSIGHUP
4416     (void) signal(SIGHUP, SIG_IGN);
4417 #endif /* NOSIGHUP */
4418     (void) signal(SIGTERM, SIG_IGN);
4419     (void) signal(SIGINT, SIG_IGN);
4420 #ifndef __linux__
4421 #ifdef SIGBUS
4422     (void) signal(SIGBUS, SIG_IGN);
4423 #endif /* ! SIGBUS */
4424 #endif /* !__linux__ */
4425     (void) signal(SIGSEGV, SIG_IGN);
4426     (void) signal(SIGILL, SIG_IGN);
4427 
4428     /*
4429      * Flush all messages.  - FM
4430      */
4431     fflush(stderr);
4432     fflush(stdout);
4433 
4434     /*
4435      * Deal with curses, if on, and clean up.  - FM
4436      */
4437     if (LYOutOfMemory && LYCursesON) {
4438 	LYSleepAlert();
4439     }
4440     cleanup_sig(0);
4441 #ifndef __linux__
4442 #ifdef SIGBUS
4443     signal(SIGBUS, SIG_DFL);
4444 #endif /* SIGBUS */
4445 #endif /* !__linux__ */
4446     signal(SIGSEGV, SIG_DFL);
4447     signal(SIGILL, SIG_DFL);
4448 
4449     /*
4450      * Issue appropriate messages and abort or exit.  - FM
4451      */
4452     if (LYOutOfMemory == FALSE) {
4453 	fprintf(stderr, "\r\n\
4454 A Fatal error has occurred in %s Ver. %s\r\n", LYNX_NAME, LYNX_VERSION);
4455 
4456 	fprintf(stderr, "\r\n\
4457 Please notify your system administrator to confirm a bug, and\r\n\
4458 if confirmed, to notify the lynx-dev list.  Bug reports should\r\n\
4459 have concise descriptions of the command and/or URL which causes\r\n\
4460 the problem, the operating system name with version number, the\r\n\
4461 TCPIP implementation, and any other relevant information.\r\n");
4462 
4463 	if (!(sig == 0 && LYNoCore)) {
4464 	    fprintf(stderr, "\r\n\
4465 Do NOT mail the core file if one was generated.\r\n");
4466 	}
4467 	if (sig != 0) {
4468 	    fprintf(stderr, "\r\n\
4469 Lynx now exiting with signal:  %d\r\n\r\n", sig);
4470 #ifdef WIN_EX			/* 1998/08/09 (Sun) 09:58:25 */
4471 	    {
4472 		char *msg;
4473 
4474 		switch (sig) {
4475 		case SIGABRT:
4476 		    msg = "SIGABRT";
4477 		    break;
4478 		case SIGFPE:
4479 		    msg = "SIGFPE";
4480 		    break;
4481 		case SIGILL:
4482 		    msg = "SIGILL";
4483 		    break;
4484 		case SIGSEGV:
4485 		    msg = "SIGSEGV";
4486 		    break;
4487 		default:
4488 		    msg = "Not-def";
4489 		    break;
4490 		}
4491 		fprintf(stderr, "signal code = %s\n", msg);
4492 	    }
4493 #endif
4494 	}
4495 
4496 	/*
4497 	 * Exit and possibly dump core.
4498 	 */
4499 	if (LYNoCore) {
4500 	    exit_immediately(EXIT_FAILURE);
4501 	}
4502 	abort();
4503 
4504     } else {
4505 	LYOutOfMemory = FALSE;
4506 	printf("\r\n%s\r\n\r\n", MEMORY_EXHAUSTED_ABORT);
4507 	fflush(stdout);
4508 
4509 	/*
4510 	 * Exit without dumping core.
4511 	 */
4512 	exit_immediately(EXIT_FAILURE);
4513     }
4514 }
4515 #endif
4516 #endif /* !VMS */
4517