From 903885454167e86ce4cb967f901cbaf741f21501 Mon Sep 17 00:00:00 2001 From: "Thomas E. Dickey" Date: Mon, 3 May 2010 00:45:10 -0400 Subject: snapshot of project "lynx", label v2-8-8dev_3c --- src/LYMain.c | 4439 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 4439 insertions(+) create mode 100644 src/LYMain.c (limited to 'src/LYMain.c') diff --git a/src/LYMain.c b/src/LYMain.c new file mode 100644 index 00000000..9301d64c --- /dev/null +++ b/src/LYMain.c @@ -0,0 +1,4439 @@ +/* + * $LynxId: LYMain.c,v 1.212 2010/04/30 23:49:43 tom Exp $ + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef USE_SESSIONS +#include +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef VMS +#include +#endif /* !DECNET */ + +#ifdef __DJGPP__ +#include +#include +#include +#include +#include +#endif /* __DJGPP__ */ + +#ifdef __EMX__ +#include +#endif + +#if defined(LOCALE) && (!defined(HAVE_LIBINTL_H) || !defined(LC_ALL)) +#undef gettext /* Solaris locale.h prototypes gettext() */ +#include +#ifndef HAVE_GETTEXT +#define gettext(s) s +#endif +#endif /* LOCALE */ + +#include +#include + +/* ahhhhhhhhhh!! Global variables :-< */ +#ifdef SOCKS +BOOLEAN socks_flag = TRUE; +#endif /* SOCKS */ + +#ifdef IGNORE_CTRL_C +BOOLEAN sigint = FALSE; +#endif /* IGNORE_CTRL_C */ + +#ifdef __DJGPP__ +static char init_ctrl_break[1]; +#endif /* __DJGPP__ */ + +#if USE_VMS_MAILER +char *mail_adrs = NULL; /* the mask for a VMS mail transport */ +#endif + +#ifdef VMS + /* create FIXED 512 binaries */ +BOOLEAN UseFixedRecords = USE_FIXED_RECORDS; +#endif /* VMS */ + +#ifndef VMS +static char *lynx_version_putenv_command = NULL; +char *list_format = NULL; /* LONG_LIST formatting mask */ +#endif /* !VMS */ + +char *ftp_format = NULL; /* LONG_LIST formatting mask */ + +#ifdef SYSLOG_REQUESTED_URLS +char *syslog_txt = NULL; /* syslog arb text for session */ +BOOLEAN syslog_requested_urls = FALSE; +#endif + +int cfg_bad_html = BAD_HTML_WARN; + +#ifdef DIRED_SUPPORT +BOOLEAN lynx_edit_mode = FALSE; +BOOLEAN no_dired_support = FALSE; +HTList *tagged = NULL; +int LYAutoUncacheDirLists = 2; /* default dired uncaching behavior */ +int dir_list_order = ORDER_BY_NAME; +int dir_list_style = MIXED_STYLE; + +#ifdef OK_OVERRIDE +BOOLEAN prev_lynx_edit_mode = FALSE; +#endif /* OK_OVERRIDE */ + +#ifdef OK_PERMIT +#ifdef NO_CHANGE_EXECUTE_PERMS +BOOLEAN no_change_exec_perms = TRUE; + +#else +BOOLEAN no_change_exec_perms = FALSE; +#endif /* NO_CHANGE_EXECUTE_PERMS */ +#endif /* OK_PERMIT */ + +#endif /* DIRED_SUPPORT */ + + /* Number of docs cached in memory */ +int HTCacheSize = DEFAULT_CACHE_SIZE; + +#if defined(VMS) && defined(VAXC) && !defined(__DECC) + /* Don't dump doc cache unless this size is exceeded */ +int HTVirtualMemorySize = DEFAULT_VIRTUAL_MEMORY_SIZE; +#endif /* VMS && VAXC && !_DECC */ + +#if defined(EXEC_LINKS) || defined(EXEC_SCRIPTS) +#ifndef NEVER_ALLOW_REMOTE_EXEC +BOOLEAN local_exec = LOCAL_EXECUTION_LINKS_ALWAYS_ON; + +#else +BOOLEAN local_exec = FALSE; +#endif /* NEVER_ALLOW_REMOTE_EXEC */ +BOOLEAN local_exec_on_local_files = +LOCAL_EXECUTION_LINKS_ON_BUT_NOT_REMOTE; +#endif /* EXEC_LINKS || EXEC_SCRIPTS */ + +#if defined(LYNXCGI_LINKS) && !defined(VMS) /* WebSter Mods -jkt */ +char *LYCgiDocumentRoot = NULL; /* DOCUMENT_ROOT in the lynxcgi env */ +#endif /* LYNXCGI_LINKS */ + +#ifdef REVERSE_CLEAR_SCREEN_PROBLEM +BOOLEAN enable_scrollback = TRUE; + +#else +BOOLEAN enable_scrollback = FALSE; +#endif /* REVERSE_CLEAR_SCREEN_PROBLEM */ + +char empty_string[] = +{'\0'}; + +int display_lines; /* number of lines in display */ +int www_search_result = -1; + + /* linked list of printers */ +lynx_list_item_type *printers = NULL; + + /* linked list of download options */ +lynx_list_item_type *downloaders = NULL; + + /* linked list of upload options */ +#ifdef USE_EXTERNALS +lynx_list_item_type *externals = NULL; + + /* linked list of external options */ +#endif + +lynx_list_item_type *uploaders = NULL; +int LYShowColor = SHOW_COLOR_UNKNOWN; /* to show or not */ +int LYrcShowColor = SHOW_COLOR_UNKNOWN; /* ... last used */ + +#if !defined(NO_OPTION_FORMS) && !defined(NO_OPTION_MENU) +BOOLEAN LYUseFormsOptions = TRUE; /* use forms-based options menu */ +#endif + +BOOLEAN LYJumpFileURL = FALSE; /* always FALSE the first time */ +BOOLEAN LYPermitURL = FALSE; +BOOLEAN LYRestricted = FALSE; /* whether we have -anonymous option */ +BOOLEAN LYShowCursor = SHOW_CURSOR; /* to show or not to show */ +BOOLEAN LYUnderlineLinks = UNDERLINE_LINKS; /* Show the links underlined vs bold */ +BOOLEAN LYUseDefShoCur = TRUE; /* Command line -show_cursor toggle */ +BOOLEAN LYUserSpecifiedURL = TRUE; /* always TRUE the first time */ +BOOLEAN LYValidate = FALSE; +BOOLEAN LYforce_no_cache = FALSE; +BOOLEAN LYinternal_flag = FALSE; /* override no-cache b/c internal link */ +BOOLEAN LYoverride_no_cache = FALSE; /*override no-cache b/c history etc */ +BOOLEAN LYresubmit_posts = ALWAYS_RESUBMIT_POSTS; +BOOLEAN LYtrimInputFields = FALSE; +BOOLEAN LYxhtml_parsing = FALSE; +BOOLEAN bold_H1 = FALSE; +BOOLEAN bold_headers = FALSE; +BOOLEAN bold_name_anchors = FALSE; +BOOLEAN case_sensitive = CASE_SENSITIVE_ALWAYS_ON; +BOOLEAN check_mail = CHECKMAIL; +BOOLEAN child_lynx = FALSE; +BOOLEAN dump_links_only = FALSE; +BOOLEAN dump_output_immediately = FALSE; +BOOLEAN dump_to_stderr = FALSE; +BOOLEAN emacs_keys = EMACS_KEYS_ALWAYS_ON; +BOOLEAN error_logging = MAIL_SYSTEM_ERROR_LOGGING; +BOOLEAN goto_buffer = GOTOBUFFER; /* TRUE if offering default goto URL */ +BOOLEAN historical_comments = FALSE; +BOOLEAN is_www_index = FALSE; +BOOLEAN jump_buffer = JUMPBUFFER; /* TRUE if offering default shortcut */ +BOOLEAN lynx_mode = NORMAL_LYNX_MODE; +BOOLEAN minimal_comments = FALSE; +BOOLEAN number_fields_on_left = TRUE; +BOOLEAN number_links_on_left = TRUE; +BOOLEAN recent_sizechange = FALSE; /* the window size changed recently? */ +BOOLEAN soft_dquotes = FALSE; +BOOLEAN use_underscore = SUBSTITUTE_UNDERSCORES; +BOOLEAN verbose_img = VERBOSE_IMAGES; /* show filenames or not */ +BOOLEAN vi_keys = VI_KEYS_ALWAYS_ON; +int keypad_mode = DEFAULT_KEYPAD_MODE; +int user_mode = NOVICE_MODE; + +BOOLEAN telnet_ok = TRUE; + +#ifndef DISABLE_NEWS +BOOLEAN news_ok = TRUE; +#endif +BOOLEAN rlogin_ok = TRUE; +BOOLEAN long_url_ok = FALSE; +BOOLEAN ftp_ok = TRUE; +BOOLEAN system_editor = FALSE; + +BOOLEAN had_restrictions_default = FALSE; +BOOLEAN had_restrictions_all = FALSE; + +BOOLEAN exec_frozen = FALSE; +BOOLEAN no_bookmark = FALSE; +BOOLEAN no_bookmark_exec = FALSE; +BOOLEAN no_chdir = FALSE; +BOOLEAN no_disk_save = FALSE; +BOOLEAN no_dotfiles = NO_DOT_FILES; +BOOLEAN no_download = FALSE; +BOOLEAN no_editor = FALSE; +BOOLEAN no_exec = FALSE; +BOOLEAN no_file_url = FALSE; +BOOLEAN no_goto = FALSE; +BOOLEAN no_goto_configinfo = FALSE; +BOOLEAN no_goto_cso = FALSE; +BOOLEAN no_goto_file = FALSE; +BOOLEAN no_goto_finger = FALSE; +BOOLEAN no_goto_ftp = FALSE; +BOOLEAN no_goto_gopher = FALSE; +BOOLEAN no_goto_http = FALSE; +BOOLEAN no_goto_https = FALSE; +BOOLEAN no_goto_lynxcgi = FALSE; +BOOLEAN no_goto_lynxexec = FALSE; +BOOLEAN no_goto_lynxprog = FALSE; +BOOLEAN no_goto_mailto = FALSE; +BOOLEAN no_goto_rlogin = FALSE; +BOOLEAN no_goto_telnet = FALSE; +BOOLEAN no_goto_tn3270 = FALSE; +BOOLEAN no_goto_wais = FALSE; +BOOLEAN no_inside_ftp = FALSE; +BOOLEAN no_inside_rlogin = FALSE; +BOOLEAN no_inside_telnet = FALSE; +BOOLEAN no_jump = FALSE; +BOOLEAN no_lynxcfg_info = FALSE; +BOOLEAN no_lynxcgi = FALSE; +BOOLEAN no_mail = FALSE; +BOOLEAN no_multibook = FALSE; +BOOLEAN no_option_save = FALSE; +BOOLEAN no_outside_ftp = FALSE; +BOOLEAN no_outside_rlogin = FALSE; +BOOLEAN no_outside_telnet = FALSE; +BOOLEAN no_print = FALSE; +BOOLEAN no_shell = FALSE; +BOOLEAN no_suspend = FALSE; +BOOLEAN no_telnet_port = FALSE; +BOOLEAN no_useragent = FALSE; + +#ifndef DISABLE_FTP +BOOLEAN ftp_passive = FTP_PASSIVE; /* TRUE if doing ftp in passive mode */ +BOOLEAN ftp_local_passive; +HTList *broken_ftp_epsv = NULL; +HTList *broken_ftp_retr = NULL; +char *ftp_lasthost = NULL; +#endif + +#ifndef DISABLE_NEWS +BOOLEAN no_goto_news = FALSE; +BOOLEAN no_goto_nntp = FALSE; +BOOLEAN no_goto_snews = FALSE; +BOOLEAN no_inside_news = FALSE; +BOOLEAN no_newspost = FALSE; +BOOLEAN no_outside_news = FALSE; +#endif + +#ifdef USE_EXTERNALS +BOOLEAN no_externals = FALSE; +#endif + +#ifndef NO_CONFIG_INFO +BOOLEAN no_lynxcfg_xinfo = FALSE; + +#ifdef HAVE_CONFIG_H +BOOLEAN no_compileopts_info = FALSE; +#endif +#endif + +BOOLEAN no_statusline = FALSE; +BOOLEAN no_filereferer = TRUE; +char LYRefererWithQuery = 'D'; /* 'D' for drop */ +BOOLEAN local_host_only = FALSE; +BOOLEAN override_no_download = FALSE; +BOOLEAN show_dotfiles = FALSE; /* From rcfile if no_dotfiles is false */ +BOOLEAN LYforce_HTML_mode = FALSE; +BOOLEAN LYfind_leaks = TRUE; + +#ifdef __DJGPP__ +BOOLEAN watt_debug = FALSE; /* WATT-32 debugging */ +BOOLEAN dj_is_bash = FALSE; /* Check for bash shell under DJGPP */ +#endif /* __DJGPP__ */ + +#ifdef WIN_EX +BOOLEAN focus_window = FALSE; /* 1998/10/05 (Mon) 17:18:42 */ +char windows_drive[4]; /* 1998/01/13 (Tue) 21:13:24 */ +#endif + +#ifdef _WINDOWS +#define TIMEOUT 180 /* 1998/03/30 (Mon) 14:50:44 */ +int lynx_timeout = TIMEOUT; +CRITICAL_SECTION critSec_DNS; /* 1998/09/03 (Thu) 22:01:56 */ +CRITICAL_SECTION critSec_READ; /* 1998/09/03 (Thu) 22:01:56 */ +#endif /* _WINDOWS */ + +#if defined(WIN_EX) +BOOLEAN system_is_NT = FALSE; +#endif + +BOOLEAN show_cfg = FALSE; + +BOOLEAN no_table_center = FALSE; /* 1998/10/09 (Fri) 15:12:49 */ + +#if USE_BLAT_MAILER +BOOLEAN mail_is_blat = TRUE; +#endif + +#ifdef USE_BLINK +# ifdef __EMX__ +BOOLEAN term_blink_is_boldbg = TRUE; + +# else +BOOLEAN term_blink_is_boldbg = FALSE; + +# endif +#endif + +BOOLEAN HEAD_request = FALSE; +BOOLEAN LYAcceptAllCookies = ACCEPT_ALL_COOKIES; /* take all cookies? */ +BOOLEAN LYCancelledFetch = FALSE; /* TRUE if cancelled binary fetch */ +BOOLEAN LYCollapseBRs = COLLAPSE_BR_TAGS; /* Collapse serial BRs? */ +BOOLEAN LYDefaultRawMode; +BOOLEAN LYListNewsDates = LIST_NEWS_DATES; +BOOLEAN LYListNewsNumbers = LIST_NEWS_NUMBERS; +BOOLEAN LYMBMBlocked = BLOCK_MULTI_BOOKMARKS; +BOOLEAN LYNewsPosting = NEWS_POSTING; /* News posting supported? */ +BOOLEAN LYNoFromHeader = TRUE; /* Never send From header? */ +BOOLEAN LYNoRefererForThis = FALSE; /* No Referer header for this URL? */ +BOOLEAN LYNoRefererHeader = FALSE; /* Never send Referer header? */ +BOOLEAN LYRawMode; +BOOLEAN LYSelectPopups = USE_SELECT_POPUPS; +BOOLEAN LYSendUserAgent = SEND_USERAGENT; /* send Lynx User-Agent header? */ +BOOLEAN LYSetCookies = SET_COOKIES; /* Process Set-Cookie headers? */ +BOOLEAN LYUseDefSelPop = TRUE; /* Command line -popup toggle */ +BOOLEAN LYUseDefaultRawMode = TRUE; +BOOLEAN LYUseMouse = FALSE; +BOOLEAN LYisConfiguredForX = FALSE; +BOOLEAN UCForce8bitTOUPPER = FALSE; /* override locale for case-conversion? */ +BOOLEAN UCSaveBookmarksInUnicode = FALSE; +BOOLEAN bookmark_start = FALSE; +BOOLEAN check_realm = FALSE; /* Restrict to the starting realm? */ +BOOLEAN clickable_images = MAKE_LINKS_FOR_ALL_IMAGES; +BOOLEAN crawl = FALSE; /* Do crawl? */ +BOOLEAN keep_mime_headers = FALSE; /* Include mime headers with source dump */ +BOOLEAN more_text = FALSE; /* is there more text to display? */ +BOOLEAN more_links = FALSE; /* Links beyond a displayed page with no links? */ +BOOLEAN no_list = FALSE; +BOOLEAN no_margins = FALSE; +BOOLEAN no_pause = FALSE; +BOOLEAN no_title = FALSE; +BOOLEAN no_url_redirection = FALSE; /* Don't follow URL redirections */ +BOOLEAN pseudo_inline_alts = MAKE_PSEUDO_ALTS_FOR_INLINES; +BOOLEAN scan_for_buried_news_references = TRUE; +BOOLEAN startfile_ok = FALSE; +static BOOLEAN startfile_stdin = FALSE; +BOOLEAN traversal = FALSE; /* Do traversals? */ + +char *BookmarkPage = NULL; /* the name of the current bookmark page */ +char *LYCookieAcceptDomains = NULL; /* domains to accept all cookies */ +char *LYCookieLooseCheckDomains = NULL; /* check loosely */ +char *LYCookieQueryCheckDomains = NULL; /* check w/a query */ +char *LYCookieRejectDomains = NULL; /* domains to reject all cookies */ +char *LYCookieSAcceptDomains = NULL; /* domains to accept all cookies */ +char *LYCookieSLooseCheckDomains = NULL; /* check loosely */ +char *LYCookieSQueryCheckDomains = NULL; /* check w/a query */ +char *LYCookieSRejectDomains = NULL; /* domains to reject all cookies */ +char *LYCookieSStrictCheckDomains = NULL; /* check strictly */ +char *LYCookieStrictCheckDomains = NULL; /* check strictly */ +char *LYHostName = NULL; /* treat as a local host name */ +char *LYLocalDomain = NULL; /* treat as a local domain tail */ +char *LYUserAgent = NULL; /* Lynx User-Agent header */ +char *LYUserAgentDefault = NULL; /* Lynx default User-Agent header */ +char *LynxHome = NULL; /* the default Home HREF. */ +char *LynxSigFile = NULL; /* Signature file, in or off home */ +char *UCAssume_MIMEcharset = NULL; +char *URLDomainPrefixes = NULL; +char *URLDomainSuffixes = NULL; +char *anonftp_password = NULL; /* anonymous ftp password (default: email) */ +char *authentication_info[2] = +{NULL, NULL}; /* Id:Password for protected documents */ +char *bookmark_page = NULL; /* the name of the default bookmark page */ +char *editor = NULL; /* the name of the current editor */ +char *form_get_data = NULL; /* User data for get form */ +char *form_post_data = NULL; /* User data for post form */ +char *global_extension_map = NULL; /* global mime.types */ +char *global_type_map = NULL; /* global mailcap */ +char *helpfile = NULL; /* the main help file */ +char *helpfilepath = NULL; /* the path to the help file set */ +char *homepage = NULL; /* home page or main screen */ +char *http_error_file = NULL; /* Place HTTP status code in this file */ +char *indexfile = NULL; /* an index file if there is one */ +char *jumpfile = NULL; /* the name of the default jumps file */ +char *jumpprompt = NULL; /* the default jumps prompt */ +char *language = NULL; /* preferred language */ +char *lynx_cfg_file = NULL; /* location of active lynx.cfg */ +char *lynx_cmd_logfile; /* file to write keystroke commands, if any */ +char *lynx_cmd_script; /* file to read keystroke commands, if any */ +char *lynx_save_space = NULL; /* The prefix for save to disk paths */ +char *lynx_temp_space = NULL; /* The prefix for temporary file paths */ +char *lynxjumpfile = NULL; /* the current jump file URL */ +char *lynxlinksfile = NULL; /* the current visited links file URL */ +char *lynxlistfile = NULL; /* the current list file URL */ +char *original_dir = NULL; /* the original directory */ +char *personal_extension_map = NULL; /* .mime.types */ +char *personal_mail_address = NULL; /* the users mail address */ +char *personal_type_map = NULL; /* .mailcap */ +char *pref_charset = NULL; /* preferred character set */ +char *proxyauth_info[2] = +{NULL, NULL}; /* Id:Password for protected proxy servers */ + +#ifdef USE_SESSIONS +BOOLEAN LYAutoSession = FALSE; /* enable/disable auto saving/restoring of */ + + /* session */ +char *LYSessionFile = NULL; /* the session file from lynx.cfg */ +char *session_file = NULL; /* the current session file */ +char *sessionin_file = NULL; /* only resume session from this file */ +char *sessionout_file = NULL; /* only save session to this file */ +short session_limit = 250; /* maximal number of entries saved per */ + + /* session file, rest will be ignored */ +#endif /* USE_SESSIONS */ +char *startfile = NULL; /* the first file */ +char *startrealm = NULL; /* the startfile realm */ +char *system_mail = NULL; /* The path for sending mail */ +char *system_mail_flags = NULL; /* Flags for sending mail */ +char *x_display = NULL; /* display environment variable */ + +HistInfo *history; +int nhist = 0; /* number of used history entries */ +int size_history; /* number of allocated history entries */ + +LinkInfo links[MAXLINKS]; + +BOOLEAN nomore = FALSE; /* display -more- string in statusline messages */ +int AlertSecs; /* time-delay for HTAlert() messages */ +int DebugSecs; /* time-delay for HTProgress messages */ +int InfoSecs; /* time-delay for Information messages */ +int LYMultiBookmarks = MULTI_BOOKMARK_SUPPORT; +int LYStatusLine = -1; /* Line for statusline() if > -1 */ +int LYcols = DFT_COLS; +int LYlines = DFT_ROWS; +int MessageSecs; /* time-delay for important Messages */ +int ReplaySecs; /* time-delay for command-scripts */ +int crawl_count = 0; /* Starting number for lnk#.dat files in crawls */ +int dump_output_width = 0; +int dump_server_status = 0; +int lynx_temp_subspace = 0; /* > 0 if we made temp-directory */ +int max_cookies_domain = 50; +int max_cookies_global = 500; +int max_cookies_buffer = 4096; +int nlinks = 0; /* number of links in memory */ +int outgoing_mail_charset = -1; /* translate mail to this charset */ + +#ifndef DISABLE_BIBP +BOOLEAN BibP_bibhost_available = FALSE; /* until check succeeds */ +BOOLEAN BibP_bibhost_checked = FALSE; /* until LYCheckBibHost */ +BOOLEAN no_goto_bibp = FALSE; +char *BibP_bibhost = NULL; /* local server for bibp: links */ +char *BibP_globalserver = NULL; /* global server for bibp: links */ +#endif + +#ifdef USE_PERSISTENT_COOKIES +BOOLEAN persistent_cookies = FALSE; /* disabled by default! */ +char *LYCookieFile = NULL; /* cookie read file */ +char *LYCookieSaveFile = NULL; /* cookie save file */ +#endif /* USE_PERSISTENT_COOKIES */ + +#ifdef EXP_NESTED_TABLES +BOOLEAN nested_tables = +#if defined(USE_COLOR_STYLE) +TRUE +#else +FALSE /* see 2001-08-15 */ +#endif + ; +#endif + +BOOLEAN LYShowTransferRate = TRUE; +int LYTransferRate = rateKB; +int LYAcceptEncoding = encodingALL; +int LYAcceptMedia = mediaOpt1; +char *LYTransferName = NULL; + +char *XLoadImageCommand = NULL; /* Default image viewer for X */ +BOOLEAN LYNoISMAPifUSEMAP = FALSE; /* Omit ISMAP link if MAP present? */ +int LYHiddenLinks = HIDDENLINKS_SEPARATE; /* Show hidden links? */ + +char *SSL_cert_file = NULL; /* Default CA CERT file */ + +int Old_DTD = NO; +static BOOLEAN DTD_recovery = NO; + +#ifndef NO_LYNX_TRACE +FILE *LYTraceLogFP = NULL; /* Pointer for TRACE log */ +#endif +char *LYTraceLogPath = NULL; /* Path for TRACE log */ +BOOLEAN LYUseTraceLog = USE_TRACE_LOG; /* Use a TRACE log? */ + +BOOLEAN LYSeekFragMAPinCur = TRUE; +BOOLEAN LYSeekFragAREAinCur = TRUE; +BOOLEAN LYStripDotDotURLs = TRUE; /* Try to fix ../ in some URLs? */ +BOOLEAN LYForceSSLCookiesSecure = FALSE; +BOOLEAN LYNoCc = FALSE; +BOOLEAN LYPreparsedSource = FALSE; /* Show source as preparsed? */ +BOOLEAN LYPrependBaseToSource = TRUE; +BOOLEAN LYPrependCharsetToSource = TRUE; +BOOLEAN LYQuitDefaultYes = QUIT_DEFAULT_YES; +BOOLEAN dont_wrap_pre = FALSE; + +int cookie_noprompt; + +#ifdef USE_SSL +int ssl_noprompt = FORCE_PROMPT_DFT; +#endif + +int connect_timeout = 18000; /*=180000*0.1 - used in HTDoConnect.*/ +int reading_timeout = 18000; /*=180000*0.1 - used in HTDoConnect.*/ + +#ifdef USE_JUSTIFY_ELTS +BOOLEAN ok_justify = FALSE; +int justify_max_void_percent = 35; +#endif + +#ifdef USE_LOCALE_CHARSET +BOOLEAN LYLocaleCharset = FALSE; +#endif + +#ifndef NO_DUMP_WITH_BACKSPACES +BOOLEAN with_backspaces = FALSE; +#endif + +#if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401 +int scrsize_x = 0; +int scrsize_y = 0; +#endif + +BOOLEAN force_empty_hrefless_a = FALSE; + +#ifdef TEXTFIELDS_MAY_NEED_ACTIVATION +BOOL textfields_need_activation = FALSE; +BOOLEAN textfields_activation_option = FALSE; +#endif + +BOOLEAN textfield_prompt_at_left_edge = FALSE; + +#ifdef MARK_HIDDEN_LINKS +char *hidden_link_marker = NULL; +#endif + +#ifdef DISP_PARTIAL +BOOLEAN display_partial_flag = TRUE; /* Display document during download */ +BOOLEAN debug_display_partial = FALSE; /* Show with MessageSecs delay */ +int partial_threshold = -1; /* # of lines to be d/l'ed until we repaint */ +#endif + +BOOLEAN LYNonRestartingSIGWINCH = FALSE; +BOOLEAN LYReuseTempfiles = FALSE; +BOOLEAN LYUseBuiltinSuffixes = TRUE; + +#ifdef MISC_EXP +int LYNoZapKey = 0; /* 0: off (do z checking), 1: full, 2: initially */ +#endif + +#ifndef DISABLE_NEWS +#include +#endif + +BOOLEAN FileInitAlreadyDone = FALSE; + +static BOOLEAN stack_dump = FALSE; +static char *terminal = NULL; +static const char *pgm; +static BOOLEAN no_numbers = FALSE; +static BOOLEAN number_links = FALSE; +static BOOLEAN number_fields = FALSE; +static BOOLEAN LYPrependBase = FALSE; +static HTList *LYStdinArgs = NULL; +HTList *positionable_editor = NULL; + +#ifndef EXTENDED_OPTION_LOGIC +/* if set then '--' will be recognized as the end of options */ +#define EXTENDED_OPTION_LOGIC 1 +#endif + +#ifndef EXTENDED_STARTFILE_RECALL +/* if set then additional non-option args (before the last one) will be + made available for 'g'oto recall - kw */ +#define EXTENDED_STARTFILE_RECALL 1 +#endif + +#if EXTENDED_STARTFILE_RECALL +static char *nonoption = 0; +#endif + +#ifndef OPTNAME_ALLOW_DASHES +/* if set, then will allow dashes and underscores to be used interchangeable + in commandline option's names - VH */ +#define OPTNAME_ALLOW_DASHES 1 +#endif + +static BOOL parse_arg(char **arg, unsigned mask, int *countp); +static void print_help_and_exit(int exit_status) GCC_NORETURN; +static void print_help_strings(const char *name, + const char *help, + const char *value, + BOOLEAN option); + +#ifndef VMS +BOOLEAN LYNoCore = NO_FORCED_CORE_DUMP; +BOOLEAN restore_sigpipe_for_children = FALSE; +static void FatalProblem(int sig); +#endif /* !VMS */ + +#if defined(USE_COLOR_STYLE) +char *lynx_lss_file2 = NULL; /* from command-line options */ +char *lynx_lss_file = NULL; /* from config-file, etc. */ +#endif + +#ifdef USE_DEFAULT_COLORS +BOOLEAN LYuse_default_colors = TRUE; +#endif + +#ifdef __DJGPP__ +static void LY_set_ctrl_break(int setting) +{ + (void) signal(SIGINT, (setting ? SIG_DFL : SIG_IGN)); + setcbrk(setting); +} + +static int LY_get_ctrl_break(void) +{ + __dpmi_regs regs; + + regs.h.ah = 0x33; + regs.h.al = 0x00; + __dpmi_int(0x21, ®s); + return ((int) regs.h.dl); +} + +static void reset_break(void) +{ + LY_set_ctrl_break(init_ctrl_break[0]); +} +#endif /* __DJGPP__ */ + +#if defined(WIN_EX) +static int is_windows_nt(void) +{ + DWORD version; + + version = GetVersion(); + if ((version & 0x80000000) == 0) + return 1; + else + return 0; +} +#endif + +#ifdef LY_FIND_LEAKS +static void free_lynx_globals(void) +{ + int i; + + FREE(ftp_format); +#ifndef VMS + FREE(list_format); +#ifdef LYNXCGI_LINKS /* WebSter Mods -jkt */ + FREE(LYCgiDocumentRoot); +#endif /* LYNXCGI_LINKS */ + free_lynx_cfg(); +#endif /* !VMS */ + +#ifdef SYSLOG_REQUESTED_URLS + FREE(syslog_txt); +#endif + +#ifdef VMS + Define_VMSLogical("LYNX_VERSION", ""); +#endif /* VMS */ +#ifndef VMS + FREE(lynx_version_putenv_command); +#endif + +#if USE_VMS_MAILER + FREE(mail_adrs); +#endif + + FREE(LynxHome); + FREE(history); + FREE(homepage); + FREE(original_dir); + FREE(startfile); + FREE(helpfile); + FREE(helpfilepath); + FREE(jumpprompt); +#ifdef JUMPFILE + FREE(jumpfile); +#endif /* JUMPFILE */ + FREE(indexfile); + FREE(x_display); + FREE(global_type_map); + FREE(personal_type_map); + FREE(global_extension_map); + FREE(personal_extension_map); + FREE(language); + FREE(pref_charset); + FREE(LynxSigFile); + FREE(system_mail); + FREE(system_mail_flags); +#ifndef DISABLE_BIBP + FREE(BibP_bibhost); + FREE(BibP_globalserver); +#endif +#ifdef USE_PERSISTENT_COOKIES + FREE(LYCookieFile); + FREE(LYCookieSaveFile); +#endif + FREE(LYCookieAcceptDomains); + FREE(LYCookieRejectDomains); + FREE(LYCookieLooseCheckDomains); + FREE(LYCookieStrictCheckDomains); + FREE(LYCookieQueryCheckDomains); + FREE(LYUserAgent); + FREE(LYUserAgentDefault); + FREE(LYHostName); + FREE(LYLocalDomain); + FREE(lynx_save_space); + FREE(bookmark_page); + FREE(BookmarkPage); + for (i = 0; i <= MBM_V_MAXFILES; i++) { + FREE(MBM_A_subbookmark[i]); + FREE(MBM_A_subdescript[i]); + } + FREE(editor); + FREE(authentication_info[0]); + FREE(authentication_info[1]); + FREE(proxyauth_info[0]); + FREE(proxyauth_info[1]); + FREE(lynxjumpfile); +#ifndef DISABLE_FTP + FREE(ftp_lasthost); + LYFreeStringList(broken_ftp_epsv); + LYFreeStringList(broken_ftp_retr); +#endif + FREE(startrealm); + FREE(personal_mail_address); + FREE(anonftp_password); + FREE(URLDomainPrefixes); + FREE(URLDomainSuffixes); + FREE(XLoadImageCommand); + FREE(lynx_temp_space); + FREE(LYTransferName); + FREE(LYTraceLogPath); + FREE(lynx_cfg_file); +#if defined(USE_COLOR_STYLE) + FREE(lynx_lss_file2); + FREE(lynx_lss_file); +#endif + FREE(UCAssume_MIMEcharset); + LYUIPages_free(); + LYFreeHilites(0, nlinks); + nlinks = 0; + LYFreeStringList(LYcommandList()); + HTInitProgramPaths(); +#if EXTENDED_STARTFILE_RECALL + FREE(nonoption); +#endif + LYFreeStringList(positionable_editor); + + return; +} +#endif /* LY_FIND_LEAKS */ + +/* + * This function frees the LYStdinArgs list. - FM + */ +static void LYStdinArgs_free(void) +{ + LYFreeStringList(LYStdinArgs); + LYStdinArgs = NULL; +} + +void reset_signals(void) +{ +#ifndef NOSIGHUP + (void) signal(SIGHUP, SIG_DFL); +#endif /* NOSIGHUP */ + (void) signal(SIGTERM, SIG_DFL); +#ifndef VMS + (void) signal(SIGINT, SIG_DFL); +#endif /* !VMS */ +#ifdef SIGTSTP + if (no_suspend) + (void) signal(SIGTSTP, SIG_DFL); +#endif /* SIGTSTP */ +} + +void exit_immediately(int code) +{ + reset_signals(); + exit(code); +} + +#ifdef EBCDIC +static void FixCharacters(void) +{ + int c; + int work1[256], work2[256]; + + for (c = 0; c < 256; c++) { + work1[c] = keymap[c + 1]; + work2[c] = key_override[c + 1]; + } + for (c = 0; c < 256; c++) { + keymap[IBM1047[c] + 1] = work1[c]; + key_override[IBM1047[c] + 1] = work2[c]; + } +} +#endif /* EBCDIC */ + +static BOOL GetStdin(char **buf, + BOOL marker) +{ + if (LYSafeGets(buf, stdin) != 0 + && (!marker || strncmp(*buf, "---", 3) != 0)) { + LYTrimTrailing(*buf); + CTRACE((tfp, "...data: %s\n", *buf)); + return TRUE; + } + CTRACE((tfp, "...mark: %s\n", *buf ? *buf : "")); + return FALSE; +} + +#ifdef WIN32 +static BOOL cleanup_win32(DWORD fdwCtrlType) +{ + switch (fdwCtrlType) { + case CTRL_CLOSE_EVENT: + cleanup_sig(-1); + return TRUE; + default: + return FALSE; + } +} +#endif + +/* + * Append the SSL version to lynx version or user-agent string. + */ +#ifdef USE_SSL +static void append_ssl_version(char **target, + const char *separator) +{ + char SSLLibraryVersion[256]; + char *SSLcp; + + HTSprintf(target, " SSL-MM%s1.4.1", separator); + +#undef LYNX_SSL_VERSION + +#if defined(SSLEAY_VERSION) +#define LYNX_SSL_VERSION SSLeay_version(SSLEAY_VERSION) +#else +#if defined(OPENSSL_VERSION_TEXT) +#define LYNX_SSL_VERSION OPENSSL_VERSION_TEXT +#else +#if defined(GNUTLS_VERSION) +#define LYNX_SSL_VERSION GNUTLS_VERSION +#endif /* GNUTLS_VERSION */ +#endif /* OPENSSL_VERSION_TEXT */ +#endif + +#ifdef LYNX_SSL_VERSION + if (*separator == ' ') + StrAllocCat(*target, ","); + LYstrncpy(SSLLibraryVersion, LYNX_SSL_VERSION, sizeof(SSLLibraryVersion) - 1); + if ((SSLcp = strchr(SSLLibraryVersion, ' ')) != NULL) { + *SSLcp++ = *separator; + if ((SSLcp = strchr(SSLcp, ' ')) != NULL) { + *SSLcp = '\0'; + StrAllocCat(*target, " "); + StrAllocCat(*target, SSLLibraryVersion); + } + } +#endif /* LYNX_SSL_VERSION */ +} +#endif /* USE_SSL */ + +static void SetLocale(void) +{ +#ifdef LOCALE + /* + * LOCALE support for international characters. + */ + setlocale(LC_ALL, ""); +#endif /* LOCALE */ + /* Set the text message domain. */ +#if defined(HAVE_LIBINTL_H) || defined(HAVE_LIBGETTEXT_H) + { + char *cp; + + if ((cp = LYGetEnv("LYNX_LOCALEDIR")) == 0) + cp = LOCALEDIR; + bindtextdomain("lynx", cp); + textdomain("lynx"); + } +#endif /* HAVE_LIBINTL_H */ +} + +/* + * Wow! Someone wants to start up Lynx. + */ +int main(int argc, + char **argv) +{ + int i; /* indexing variable */ + int status = 0; /* exit status */ + char *temp = NULL; + char *cp; + FILE *fp; + struct stat dir_info; + char filename[LY_MAXPATH]; + BOOL LYGetStdinArgs = FALSE; + +#ifdef _WINDOWS + WSADATA WSAData; +#endif /* _WINDOWS */ + + /* + * Just in case someone has the idea to install lynx set-uid, let's try + * to discourage it. + */ +#if defined(GETUID) && defined(SETUID) + setuid(getuid()); +#endif + +#ifdef NOT_ASCII + FixCharacters(); +#endif /* NOT_ASCII */ + +#ifndef DISABLE_FTP + /* malloc a sizeof(char) so 1st strcmp() won't dump in HTLoadFile() */ + ftp_lasthost = typecalloc(char); +#endif + +#ifdef USE_CHARSET_CHOICE + memset((char *) charset_subsets, 0, sizeof(charset_subset_t) * MAXCHARSETS); +#endif + +#ifdef _WINDOWS + { + int err; + WORD wVerReq; + + wVerReq = MAKEWORD(1, 1); + + err = WSAStartup(wVerReq, &WSAData); + if (err != 0) { + puts(gettext("No Winsock found, sorry.")); + sleep(5); + return 1; + } + } + + /* 1998/09/03 (Thu) 22:02:32 */ + InitializeCriticalSection(&critSec_DNS); + InitializeCriticalSection(&critSec_READ); + +#endif /* _WINDOWS */ + +#if defined(WIN_EX) + /* 1997/10/19 (Sun) 21:40:54 */ + system_is_NT = (BOOL) is_windows_nt(); + + /* 1998/01/13 (Tue) 21:13:47 */ + GetWindowsDirectory(filename, sizeof filename); + windows_drive[0] = filename[0]; + windows_drive[1] = filename[1]; + windows_drive[2] = '\0'; +#endif + +#ifdef __DJGPP__ + if (LY_get_ctrl_break() == 0) { + LY_set_ctrl_break(TRUE); + init_ctrl_break[0] = 0; + } else { + init_ctrl_break[0] = 1; + } + __djgpp_set_sigquit_key(0x082D); /* Bind ALT-X to SIGQUIT */ + signal(SIGQUIT, cleanup_sig); + atexit(reset_break); + + if (((cp = LYGetEnv("SHELL")) != NULL) + && (strstr(LYPathLeaf(cp), "sh") != NULL)) + dj_is_bash = TRUE; +#endif /* __DJGPP__ */ + + /* + * To prevent corrupting binary data on DOS, MS-WINDOWS or OS/2 + * we open files and stdout in BINARY mode by default. + * Where necessary we should open and (close!) TEXT mode. + * (use LYNewTxtFile/LYAppendToTxtFile to open text files for writing) + */ + SetDefaultMode(O_BINARY); + SetOutputMode(O_BINARY); + +#ifdef DOSPATH + if (LYGetEnv("TERM") == NULL) + putenv("TERM=vt100"); +#endif + + LYShowColor = (SHOW_COLOR ? SHOW_COLOR_ON : SHOW_COLOR_OFF); + /* + * Set up the argument list. + */ + pgm = argv[0]; + cp = NULL; + if ((cp = LYLastPathSep(pgm)) != NULL) { + pgm = cp + 1; + } + + /* + * Set up trace, the anonymous account defaults, validate restrictions, + * and/or the nosocks flag, if requested, and an alternate configuration + * file, if specified, NOW. Also, if we only want the help menu, output + * that and exit. - FM + */ +#ifndef NO_LYNX_TRACE + if (LYGetEnv("LYNX_TRACE") != 0) { + WWW_TraceFlag = TRUE; + } +#endif + + /* + * Set up the TRACE log path, and logging if appropriate. - FM + */ + if ((cp = LYGetEnv("LYNX_TRACE_FILE")) == 0) + cp = FNAME_LYNX_TRACE; + LYTraceLogPath = typeMallocn(char, LY_MAXPATH); + + LYAddPathToHome(LYTraceLogPath, LY_MAXPATH, cp); + + /* + * Act on -version, -trace and -trace-mask NOW. + */ + for (i = 1; i < argc; i++) { + parse_arg(&argv[i], 1, &i); + } + LYOpenTraceLog(); + +#ifdef LY_FIND_LEAKS + /* + * Register the final function to be executed when being exited. Will + * display memory leaks if the -find-leaks option is used. + */ + atexit(LYLeaks); + /* + * Register the function which will free our allocated globals. + */ + atexit(free_lynx_globals); +#endif /* LY_FIND_LEAKS */ + + SetLocale(); + + /* + * Initialize our startup and global variables. + */ +#ifdef ULTRIX + /* + * Need this for Ultrix. + */ + terminal = LYGetEnv("TERM"); + if ((terminal == NULL) || !strncasecomp(terminal, "xterm", 5)) + terminal = "vt100"; +#endif /* ULTRIX */ + /* + * Zero the links and history struct arrays. + */ + memset((void *) links, 0, sizeof(LinkInfo) * MAXLINKS); + LYAllocHistory(8); + /* + * Zero the MultiBookmark arrays. + */ + memset((void *) MBM_A_subbookmark, 0, sizeof(char) * (MBM_V_MAXFILES + 1)); + memset((void *) MBM_A_subdescript, 0, sizeof(char) * (MBM_V_MAXFILES + 1)); + +#ifndef VMS + StrAllocCopy(list_format, LIST_FORMAT); +#endif /* !VMS */ + StrAllocCopy(ftp_format, FTP_FORMAT); + + AlertSecs = SECS2Secs(ALERTSECS); + DebugSecs = SECS2Secs(DEBUGSECS); + InfoSecs = SECS2Secs(INFOSECS); + MessageSecs = SECS2Secs(MESSAGESECS); + ReplaySecs = SECS2Secs(REPLAYSECS); + + StrAllocCopy(LYTransferName, "KiB"); + StrAllocCopy(helpfile, HELPFILE); + StrAllocCopy(startfile, STARTFILE); + LYEscapeStartfile(&startfile); + StrAllocCopy(indexfile, DEFAULT_INDEX_FILE); + StrAllocCopy(global_type_map, GLOBAL_MAILCAP); + StrAllocCopy(personal_type_map, PERSONAL_MAILCAP); + StrAllocCopy(global_extension_map, GLOBAL_EXTENSION_MAP); + StrAllocCopy(personal_extension_map, PERSONAL_EXTENSION_MAP); + StrAllocCopy(language, PREFERRED_LANGUAGE); + StrAllocCopy(pref_charset, PREFERRED_CHARSET); + StrAllocCopy(system_mail, SYSTEM_MAIL); +#ifdef SYSTEM_MAIL_FLAGS + StrAllocCopy(system_mail_flags, SYSTEM_MAIL_FLAGS); +#else + StrAllocCopy(system_mail_flags, ""); +#endif + + StrAllocCopy(LYUserAgent, LYNX_NAME); + StrAllocCat(LYUserAgent, "/"); + StrAllocCat(LYUserAgent, LYNX_VERSION); + if (HTLibraryVersion) { + StrAllocCat(LYUserAgent, " libwww-FM/"); + StrAllocCat(LYUserAgent, HTLibraryVersion); + } +#ifdef USE_SSL + append_ssl_version(&LYUserAgent, "/"); +#endif /* USE_SSL */ + StrAllocCopy(LYUserAgentDefault, LYUserAgent); + +#ifdef VMS + Define_VMSLogical("LYNX_VERSION", LYNX_VERSION); +#else + StrAllocCopy(lynx_version_putenv_command, "LYNX_VERSION="); + StrAllocCat(lynx_version_putenv_command, LYNX_VERSION); + (void) putenv(lynx_version_putenv_command); + /* Note: you must not free the data passed to 'putenv()' until you give it + * a new value for that variable. + */ +#endif /* VMS */ + + if ((cp = LYGetEnv("LYNX_TEMP_SPACE")) != NULL) + StrAllocCopy(lynx_temp_space, cp); +#if defined (UNIX) || defined (__DJGPP__) + else if ((cp = LYGetEnv("TMPDIR")) != NULL) + StrAllocCopy(lynx_temp_space, cp); +#endif +#if defined (DOSPATH) || defined (__EMX__) + else if ((cp = LYGetEnv("TEMP")) != NULL) + StrAllocCopy(lynx_temp_space, cp); + else if ((cp = LYGetEnv("TMP")) != NULL) + StrAllocCopy(lynx_temp_space, cp); +#endif + else +#ifdef TEMP_SPACE + StrAllocCopy(lynx_temp_space, TEMP_SPACE); +#else + { + puts(gettext("You MUST define a valid TMP or TEMP area!")); + exit_immediately(EXIT_FAILURE); + } +#endif + +#ifdef WIN_EX /* for Windows 2000 ... 1999/08/23 (Mon) 08:24:35 */ + if (access(lynx_temp_space, 0) != 0) +#endif + LYTildeExpand(&lynx_temp_space, TRUE); + + if ((cp = strstr(lynx_temp_space, "$USER")) != NULL) { + char *cp1; + + if ((cp1 = LYGetEnv("USER")) != NULL) { + *cp = '\0'; + StrAllocCopy(temp, lynx_temp_space); + *cp = '$'; + StrAllocCat(temp, cp1); + cp += 5; + StrAllocCat(temp, cp); + StrAllocCopy(lynx_temp_space, temp); + FREE(temp); + } + } +#ifdef VMS + LYLowerCase(lynx_temp_space); + if (strchr(lynx_temp_space, '/') != NULL) { + if (strlen(lynx_temp_space) == 1) { + StrAllocCopy(lynx_temp_space, "sys$scratch:"); + } else { + LYAddPathSep(&lynx_temp_space); + StrAllocCopy(temp, HTVMS_name("", lynx_temp_space)); + StrAllocCopy(lynx_temp_space, temp); + FREE(temp); + } + } + if (strchr(lynx_temp_space, ':') == NULL && + strchr(lynx_temp_space, ']') == NULL) { + StrAllocCat(lynx_temp_space, ":"); + } +#else + LYAddPathSep(&lynx_temp_space); + StrAllocCopy(lynx_temp_space, HTSYS_name(lynx_temp_space)); +#endif /* VMS */ + + if ((HTStat(lynx_temp_space, &dir_info) < 0 +#if defined(MULTI_USER_UNIX) + && mkdir(lynx_temp_space, 0700) < 0 +#endif + ) + || !S_ISDIR(dir_info.st_mode)) { + fprintf(stderr, "%s: %s\n", + lynx_temp_space, + gettext("No such directory")); + exit_immediately(EXIT_FAILURE); + } +#if USE_VMS_MAILER +#ifndef MAIL_ADRS +#define MAIL_ADRS "\"IN%%\"\"%s\"\"\"" +#endif + StrAllocCopy(mail_adrs, MAIL_ADRS); +#endif + +#ifdef LYNX_HOST_NAME + StrAllocCopy(LYHostName, LYNX_HOST_NAME); +#else + StrAllocCopy(LYHostName, HTHostName()); +#endif /* LYNX_HOST_NAME */ + + StrAllocCopy(LYLocalDomain, LOCAL_DOMAIN); + StrAllocCopy(URLDomainPrefixes, URL_DOMAIN_PREFIXES); + StrAllocCopy(URLDomainSuffixes, URL_DOMAIN_SUFFIXES); + StrAllocCopy(XLoadImageCommand, XLOADIMAGE_COMMAND); + StrAllocCopy(SSL_cert_file, SSL_CERT_FILE); + +#ifndef DISABLE_BIBP + StrAllocCopy(BibP_globalserver, BIBP_GLOBAL_SERVER); + StrAllocCopy(BibP_bibhost, "http://bibhost/"); /* protocol specified. */ +#endif + + /* + * Disable news posting if the compilation-based LYNewsPosting value is + * FALSE. This may be changed further down via lynx.cfg or the + * -restriction command line switch. - FM + */ +#ifndef DISABLE_NEWS + no_newspost = (BOOL) (LYNewsPosting == FALSE); +#endif + + for (i = 1; i < argc; i++) { + parse_arg(&argv[i], 2, &i); + } + + /* + * If we have a lone "-" switch for getting arguments from stdin, get them + * NOW, and act on the relevant ones, saving the others into an HTList for + * handling after the other initializations. The primary purpose of this + * feature is to allow for the potentially very long command line that can + * be associated with post or get data. The original implementation + * required that the lone "-" be the only command line argument, but that + * precluded its use when the lynx command is aliased with other arguments. + * When interactive, the stdin input is terminated by by Control-D on Unix + * or Control-Z on VMS, and each argument is terminated by a RETURN. When + * the argument is -get_data or -post_data, the data are terminated by a + * "---" string, alone on the line (also terminated by RETURN). - FM + */ + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-") == 0) { + LYGetStdinArgs = TRUE; + break; + } + } + if (LYGetStdinArgs == TRUE) { + char *buf = NULL; + + CTRACE((tfp, "processing stdin arguments\n")); + while (GetStdin(&buf, TRUE)) { + char *noargv[2]; + + noargv[0] = buf; + noargv[1] = NULL; + LYTrimTrailing(buf); + + if (parse_arg(&noargv[0], 2, (int *) 0) == FALSE + && buf[0] != '\0') { + char *argument = NULL; + + if (LYStdinArgs == NULL) { + LYStdinArgs = HTList_new(); +#ifdef LY_FIND_LEAKS + atexit(LYStdinArgs_free); +#endif + } + StrAllocCopy(argument, buf); + HTList_appendObject(LYStdinArgs, argument); + CTRACE((tfp, "...StdinArg:%s\n", argument)); + } else { + CTRACE((tfp, "...complete:%s\n", buf)); + } + } + CTRACE((tfp, "...done with stdin arguments\n")); + FREE(buf); + } +#ifdef SOCKS + if (socks_flag) + SOCKSinit(argv[0]); +#endif /* SOCKS */ + + /* + * If we had -validate set all of the restrictions and disallow a TRACE log + * NOW. - FM + */ + if (LYValidate == TRUE) { + parse_restrictions("all"); + LYUseTraceLog = FALSE; + } + + /* + * If we didn't get and act on a -validate or -anonymous switch, but can + * verify that this is the anonymous account, set the default restrictions + * for that account and disallow a TRACE log NOW. - FM + */ + if (!LYValidate && !LYRestricted && + strlen(ANONYMOUS_USER) > 0 && +#if defined (VMS) || defined (NOUSERS) + !strcasecomp((LYGetEnv("USER") == NULL ? " " : LYGetEnv("USER")), + ANONYMOUS_USER) +#else +#ifdef HAVE_CUSERID + STREQ((char *) cuserid((char *) NULL), ANONYMOUS_USER) +#else + STREQ(((char *) getlogin() == NULL ? " " : getlogin()), ANONYMOUS_USER) +#endif /* HAVE_CUSERID */ +#endif /* VMS */ + ) { + parse_restrictions("default"); + LYRestricted = TRUE; + LYUseTraceLog = FALSE; + } +#ifdef USE_CMD_LOGGING + /* + * Open command-script, if specified + */ + if (lynx_cmd_script != 0) { + LYTildeExpand(&lynx_cmd_script, TRUE); + LYOpenCmdScript(); + } + /* + * Open command-logging, if specified + */ + if (lynx_cmd_logfile != 0) { + LYTildeExpand(&lynx_cmd_logfile, TRUE); + LYOpenCmdLogfile(argc, argv); + } +#endif + + /* + * Set up the default jump file stuff. - FM + */ + StrAllocCopy(jumpprompt, JUMP_PROMPT); +#ifdef JUMPFILE + StrAllocCopy(jumpfile, JUMPFILE); + { + temp = NULL; + HTSprintf0(&temp, "JUMPFILE:%s", jumpfile); + if (!LYJumpInit(temp)) { + CTRACE((tfp, "Failed to register %s\n", temp)); + } + FREE(temp); + } +#endif /* JUMPFILE */ + + /* + * If no alternate configuration file was specified on the command line, + * see if it's in the environment. + */ + if (!lynx_cfg_file) { + if (((cp = LYGetEnv("LYNX_CFG")) != NULL) || + (cp = LYGetEnv("lynx_cfg")) != NULL) + StrAllocCopy(lynx_cfg_file, cp); + } + + /* + * If we still don't have a configuration file, use the userdefs.h + * definition. + */ + if (!lynx_cfg_file) + StrAllocCopy(lynx_cfg_file, LYNX_CFG_FILE); + +#ifndef _WINDOWS /* avoid the whole ~ thing for now */ + LYTildeExpand(&lynx_cfg_file, FALSE); +#endif + + /* + * If the configuration file is not available, inform the user and exit. + */ + if (!LYCanReadFile(lynx_cfg_file)) { + fprintf(stderr, + gettext("\nConfiguration file \"%s\" is not available.\n\n"), + lynx_cfg_file); + exit_immediately(EXIT_FAILURE); + } + + /* + * Make sure we have the character sets declared. This will initialize the + * CHARTRANS handling. - KW + */ + if (!LYCharSetsDeclared()) { + fprintf(stderr, gettext("\nLynx character sets not declared.\n\n")); + exit_immediately(EXIT_FAILURE); + } + /* + * (**) in Lynx, UCLYhndl_HTFile_for_unspec and UCLYhndl_for_unrec may be + * valid or not, but current_char_set and UCLYhndl_for_unspec SHOULD ALWAYS + * be a valid charset. Initialized here and may be changed later from + * lynx.cfg/command_line/options_menu. - LP (**) + */ + /* + * Set up the compilation default character set. - FM + */ +#ifdef CAN_AUTODETECT_DISPLAY_CHARSET + if (auto_display_charset >= 0) + current_char_set = auto_display_charset; + else +#endif + current_char_set = safeUCGetLYhndl_byMIME(CHARACTER_SET); + /* + * Set up HTTP default for unlabeled charset (iso-8859-1). + */ + UCLYhndl_for_unspec = LATIN1; + StrAllocCopy(UCAssume_MIMEcharset, + LYCharSet_UC[UCLYhndl_for_unspec].MIMEname); + + /* + * Make sure we have the edit map declared. - FM + */ + if (!LYEditmapDeclared()) { + fprintf(stderr, gettext("\nLynx edit map not declared.\n\n")); + exit_immediately(EXIT_FAILURE); + } +#ifdef USE_COLOR_TABLE + /* + * Set up default foreground and background colors. + */ + lynx_setup_colors(); +#endif /* USE_COLOR_TABLE */ + + /* + * Set the original directory, used for default download + */ + if (!strcmp(Current_Dir(filename), ".")) { + if ((cp = LYGetEnv("PWD")) != 0) + StrAllocCopy(original_dir, cp); + } else { + StrAllocCopy(original_dir, filename); + } + + /* + * Set the compilation default signature file. - FM + */ + LYstrncpy(filename, LYNX_SIG_FILE, sizeof(filename) - 1); + if (LYPathOffHomeOK(filename, sizeof(filename))) { + StrAllocCopy(LynxSigFile, filename); + LYAddPathToHome(filename, sizeof(filename), LynxSigFile); + StrAllocCopy(LynxSigFile, filename); + CTRACE((tfp, "LYNX_SIG_FILE set to '%s'\n", LynxSigFile)); + } else { + CTRACE((tfp, "LYNX_SIG_FILE '%s' is bad. Ignoring.\n", LYNX_SIG_FILE)); + } + +#ifdef USE_PRETTYSRC + /*this is required for checking the tagspecs when parsing cfg file by + LYReadCFG.c:parse_html_src_spec -HV */ + HTSwitchDTD(TRUE); +#endif + /* + * Process the configuration file. + */ + read_cfg(lynx_cfg_file, "main program", 1, (FILE *) 0); + +#if defined(USE_COLOR_STYLE) + /* + * A command-line "-lss" always overrides the config-file, even if it is + * an empty string such as -lss="". + */ + if (lynx_lss_file2 != 0) { + FREE(lynx_lss_file); + lynx_lss_file = lynx_lss_file2; + lynx_lss_file2 = 0; + } + + /* + * If no alternate lynx-style file was specified on the command line, see + * if it's in the environment. + */ + if (!lynx_lss_file) { + if (((cp = LYGetEnv("LYNX_LSS")) != NULL) || + (cp = LYGetEnv("lynx_lss")) != NULL) + StrAllocCopy(lynx_lss_file, cp); + } + + /* + * If we still don't have a lynx-style file, use the userdefs.h definition. + */ + if (!lynx_lss_file) + StrAllocCopy(lynx_lss_file, LYNX_LSS_FILE); + + LYTildeExpand(&lynx_lss_file, TRUE); + + /* + * If the lynx-style file is not available, inform the user and exit. + */ + if (non_empty(lynx_lss_file) && !LYCanReadFile(lynx_lss_file)) { + fprintf(stderr, gettext("\nLynx file \"%s\" is not available.\n\n"), + lynx_lss_file); + exit_immediately(EXIT_FAILURE); + } else { + style_readFromFile(lynx_lss_file); + } +#endif /* USE_COLOR_STYLE */ + + /* + * Process the RC file. + */ + read_rc(NULL); + +#ifdef USE_LOCALE_CHARSET + LYFindLocaleCharset(); +#endif + + /* + * Get WWW_HOME environment variable if it exists. + */ + if ((cp = LYGetEnv("WWW_HOME")) != NULL) { + StrAllocCopy(startfile, cp); + LYEscapeStartfile(&startfile); + } + + /* + * Set the LynxHome URL. If it's a file URL and the + * host is defaulted, force in "//localhost", and if + * it's not an absolute URL, make it one. - FM + */ + StrAllocCopy(LynxHome, startfile); + LYEnsureAbsoluteURL(&LynxHome, "LynxHome", FALSE); + + /* + * Process any command line arguments not already handled. - FM + * May set startfile as a side-effect. + */ + for (i = 1; i < argc; i++) { + parse_arg(&argv[i], 4, &i); + } + + /* + * Process any stdin-derived arguments for a lone "-" which we've loaded + * into LYStdinArgs. - FM + */ + if (LYStdinArgs != NULL) { + char *my_args[2]; + HTList *cur = LYStdinArgs; + + my_args[1] = NULL; + while (NULL != (my_args[0] = (char *) HTList_nextObject(cur))) { + parse_arg(my_args, 4, (int *) 0); + } + LYStdinArgs_free(); + } +#ifdef HAVE_TTYNAME + /* + * If the input is not a tty, we are either running in cron, or are + * getting input via a pipe: + * + * a) in cron, none of stdin/stdout/stderr are tty's. + * b) from a pipe, we should have either "-" or "-stdin" options. + */ + if (!LYGetStdinArgs + && !startfile_stdin + && !isatty(fileno(stdin)) + && (isatty(fileno(stdout) || isatty(fileno(stderr))))) { + int ignored = 0; + + while (fgetc(stdin) != EOF) { + ++ignored; + } + if (ignored) { + fprintf(stderr, + gettext("Ignored %d characters from standard input.\n"), ignored); + fprintf(stderr, + gettext("Use \"-stdin\" or \"-\" to tell how to handle piped input.\n")); + } + } +#endif /* HAVE_TTYNAME */ + +#ifdef CAN_SWITCH_DISPLAY_CHARSET + if (current_char_set == auto_display_charset) /* Better: explicit option */ + switch_display_charsets = 1; +#endif + +#if defined (TTY_DEVICE) || defined(HAVE_TTYNAME) + /* + * If we are told to read the startfile from standard input, do it now, + * after we have read all of the option data from standard input. + * Later we'll use LYReopenInput(). + */ + if (startfile_stdin) { + char result[LY_MAXPATH]; + char *buf = NULL; + + CTRACE((tfp, "processing stdin startfile\n")); + if ((fp = LYOpenTemp(result, HTML_SUFFIX, "w")) != 0) { + StrAllocCopy(startfile, result); + while (GetStdin(&buf, FALSE)) { + fputs(buf, fp); + fputc('\n', fp); + } + FREE(buf); + LYCloseTempFP(fp); + } + CTRACE((tfp, "...done stdin startfile\n")); + } +#endif + + /* + * Initialize other things based on the configuration read. + */ + +#ifdef USE_PRETTYSRC + if ((!Old_DTD) != TRUE) /* skip if they are already initialized -HV */ +#endif + HTSwitchDTD(!Old_DTD); + + /* + * Set up the proper character set with the desired + * startup raw 8-bit or CJK mode handling. - FM + */ + HTMLUseCharacterSet(current_char_set); + +#ifdef USE_PERSISTENT_COOKIES + /* + * Sod it, this looks like a reasonable place to load the + * cookies file, probably. - RP + * + * And to set LYCookieSaveFile. - BJP + */ + if (persistent_cookies) { + if (LYCookieFile == NULL) { + LYCookieFile = typeMallocn(char, LY_MAXPATH); + + LYAddPathToHome(LYCookieFile, LY_MAXPATH, FNAME_LYNX_COOKIES); + } else { + LYTildeExpand(&LYCookieFile, FALSE); + } + LYLoadCookies(LYCookieFile); + } + + /* tilde-expand LYCookieSaveFile */ + if (LYCookieSaveFile != NULL) { + LYTildeExpand(&LYCookieSaveFile, FALSE); + } + + /* + * In dump_output_immediately mode, LYCookieSaveFile defaults to + * /dev/null, otherwise it defaults to LYCookieFile. + */ + + if (LYCookieSaveFile == NULL) { + if (dump_output_immediately) { + StrAllocCopy(LYCookieSaveFile, "/dev/null"); + } else { + StrAllocCopy(LYCookieSaveFile, LYCookieFile); + } + } +#endif + + /* + * Check for a help file URL in the environment. Overiding + * compiled-in default and configuration file setting, if found. + */ + if ((cp = LYGetEnv("LYNX_HELPFILE")) != NULL) + StrAllocCopy(helpfile, cp); + + /* + * Set up our help and about file base paths. - FM + */ + StrAllocCopy(helpfilepath, helpfile); + if ((cp = LYPathLeaf(helpfilepath)) != helpfilepath) + *cp = '\0'; + LYAddHtmlSep(&helpfilepath); + + /* + * Check for a save space path in the environment. If one was set in the + * configuration file, that one will be overridden. - FM + */ + if ((cp = LYGetEnv("LYNX_SAVE_SPACE")) != NULL) + StrAllocCopy(lynx_save_space, cp); + + /* + * We have a save space path, make sure it's valid. - FM + */ + if (lynx_save_space && *lynx_save_space == '\0') { + FREE(lynx_save_space); + } + if (lynx_save_space) { + LYTildeExpand(&lynx_save_space, TRUE); +#ifdef VMS + LYLowerCase(lynx_save_space); + if (strchr(lynx_save_space, '/') != NULL) { + if (strlen(lynx_save_space) == 1) { + StrAllocCopy(lynx_save_space, "sys$login:"); + } else { + LYAddPathSep(&lynx_save_space); + StrAllocCopy(temp, HTVMS_name("", lynx_save_space)); + StrAllocCopy(lynx_save_space, temp); + FREE(temp); + } + } + if (strchr(lynx_save_space, ':') == NULL && + strchr(lynx_save_space, ']') == NULL) { + StrAllocCat(lynx_save_space, ":"); + } +#else + LYAddPathSep(&lynx_save_space); +#endif /* VMS */ + } + + /* + * Set up the file extension and mime type maps from src/HTInit.c and the + * global and personal mime.types and mailcap files. These will override + * any SUFFIX or VIEWER maps in userdefs.h or the configuration file, if + * they overlap. + */ + HTFormatInit(); + if (!FileInitAlreadyDone) + HTFileInit(); + + if (!LYCheckUserAgent()) { + HTAlwaysAlert(gettext("Warning:"), UA_NO_LYNX_WARNING); + } + if (show_cfg) { + cleanup(); + exit_immediately(EXIT_SUCCESS); + } +#ifdef USE_SLANG + if (LYShowColor >= SHOW_COLOR_ON && + !(Lynx_Color_Flags & SL_LYNX_USE_COLOR)) { + Lynx_Color_Flags |= SL_LYNX_USE_COLOR; + } else if ((Lynx_Color_Flags & SL_LYNX_USE_COLOR) || + LYGetEnv("COLORTERM") != NULL) { + if (LYShowColor != SHOW_COLOR_NEVER && + LYShowColor != SHOW_COLOR_ALWAYS) { + LYShowColor = SHOW_COLOR_ON; + } + } +#endif /* USE_SLANG */ + + if (LYPreparsedSource) { + HTPreparsedFormatInit(); + } +#if defined(EXEC_LINKS) || defined(EXEC_SCRIPTS) +#ifdef NEVER_ALLOW_REMOTE_EXEC + if (local_exec) { + local_exec = FALSE; + local_exec_on_local_files = TRUE; + } +#endif /* NEVER_ALLOW_REMOTE_EXEC */ +#endif /* EXEC_LINKS || EXEC_SCRIPTS */ + + if (emacs_keys) + set_emacs_keys(); + + if (vi_keys) + set_vi_keys(); + + if (no_numbers) { + number_links = FALSE; + number_fields = FALSE; + keypad_mode = NUMBERS_AS_ARROWS; + set_numbers_as_arrows(); + } + + if (crawl) { + /* No numbered links by default, as documented + in CRAWL.announce. - kw */ + if (!number_links) { + keypad_mode = NUMBERS_AS_ARROWS; + } + } + + if (!links_are_numbered()) { + if (number_fields) + keypad_mode = LINKS_AND_FIELDS_ARE_NUMBERED; + if (number_links) + keypad_mode = LINKS_ARE_NUMBERED; + set_numbers_as_arrows(); + } + + /* + * Check the -popup command line toggle. - FM + */ + if (LYUseDefSelPop == FALSE) { + LYSelectPopups = (BOOLEAN) !LYSelectPopups; + } + + /* + * Check the -show_cursor command line toggle. - FM + */ + if (LYUseDefShoCur == FALSE) { + LYShowCursor = (BOOLEAN) !LYShowCursor; + } + + /* + * Check the -base command line switch with -source. - FM + */ + if (LYPrependBase && HTOutputFormat == HTAtom_for("www/download")) { + LYPrependBaseToSource = TRUE; + } + + /* + * Disable multiple bookmark support if not interactive, so it doesn't + * crash on curses functions, or if the support was blocked via userdefs.h + * and/or lynx.cfg, or via command line restrictions. - FM + */ + if (no_multibook) + LYMBMBlocked = TRUE; + if (dump_output_immediately || LYMBMBlocked || no_multibook) { + LYMultiBookmarks = MBM_OFF; + LYMBMBlocked = TRUE; + no_multibook = TRUE; + } +#ifdef USE_SOURCE_CACHE + /* + * Disable source caching if not interactive. + */ + if (dump_output_immediately) + LYCacheSource = SOURCE_CACHE_NONE; +#endif +#ifdef DISP_PARTIAL + /* + * Disable partial mode if not interactive. + */ + if (dump_output_immediately) + display_partial_flag = FALSE; +#endif + +#ifdef VMS + set_vms_keys(); +#endif /* VMS */ + +#if defined (__DJGPP__) + if (watt_debug) + dbug_init(); + sock_init(); + + __system_flags = + __system_emulate_chdir | /* handle `cd' internally */ + __system_handle_null_commands | /* ignore cmds with no effect */ + __system_allow_long_cmds | /* handle commands > 126 chars */ + __system_use_shell | /* use $SHELL if set */ + __system_allow_multiple_cmds | /* allow `cmd1; cmd2; ...' */ + __system_redirect; /* redirect internally */ + + /* This speeds up stat() tremendously */ + _djstat_flags |= _STAT_INODE | _STAT_EXEC_MAGIC | _STAT_DIRSIZE; +#endif /* __DJGPP__ */ + + /* trap interrupts */ +#ifdef WIN32 + SetConsoleCtrlHandler((PHANDLER_ROUTINE) cleanup_win32, TRUE); +#endif + +#ifndef NOSIGHUP + if (!dump_output_immediately) + (void) signal(SIGHUP, cleanup_sig); +#endif /* NOSIGHUP */ + + (void) signal(SIGTERM, cleanup_sig); +#ifdef SIGWINCH + LYExtSignal(SIGWINCH, size_change); +#endif /* SIGWINCH */ +#ifndef VMS + if (!TRACE && !dump_output_immediately && !stack_dump) { + (void) signal(SIGINT, cleanup_sig); +#ifndef __linux__ +#ifdef SIGBUS + (void) signal(SIGBUS, FatalProblem); +#endif /* SIGBUS */ +#endif /* !__linux__ */ + (void) signal(SIGSEGV, FatalProblem); + (void) signal(SIGILL, FatalProblem); + /* + * Since we're doing lots of TCP, just ignore SIGPIPE altogether. + * + * HTTCP.c should deal with a broken pipe for servers. Rick Mallet's + * check after c = GetChar() in LYStrings.c should deal with a + * disconnected terminal. So the runaway CPU time problem on Unix + * should not occur any more. + */ +#ifdef SIGPIPE + if (signal(SIGPIPE, SIG_IGN) != SIG_IGN) + restore_sigpipe_for_children = TRUE; +#endif /* SIGPIPE */ + } +#endif /* !VMS */ + +#ifdef SIGTSTP + /* + * Block Control-Z suspending if requested. - FM + */ + if (no_suspend) + (void) signal(SIGTSTP, SIG_IGN); +#endif /* SIGTSTP */ + + /* + * Check for a valid HEAD request. - FM + */ + if (HEAD_request && LYCanDoHEAD(startfile) != TRUE) { + fprintf(stderr, + "The '-head' switch is for http HEAD requests and cannot be used for\n'%s'.\n", + startfile); + exit_immediately(EXIT_FAILURE); + } + + /* + * Check for a valid MIME headers request. - FM + */ + if (keep_mime_headers && LYCanDoHEAD(startfile) != TRUE) { + fprintf(stderr, + "The '-mime_header' switch is for http URLs and cannot be used for\n'%s'.\n", + startfile); + exit_immediately(EXIT_FAILURE); + } + + /* + * Check for a valid traversal request. - FM + */ + if (traversal && strncmp(startfile, "http", 4)) { + fprintf(stderr, + "The '-traversal' switch is for http URLs and cannot be used for\n'%s'.\n", + startfile); + exit_immediately(EXIT_FAILURE); + } + + /* + * Finish setting up for an INTERACTIVE session. Done here so that URL + * guessing in LYEnsureAbsoluteURL() can be interruptible (terminal is in + * raw mode, select() works). -BL + */ +#ifdef USE_PRETTYSRC + if (!dump_output_immediately) { + HTMLSRC_init_caches(FALSE); /* do it before terminal is initialized */ +#ifdef LY_FIND_LEAKS + atexit(html_src_clean_data); +#endif + } +#endif + + if (!dump_output_immediately) { + setup(terminal); + } + /* + * If startfile is a file URL and the host is defaulted, force in + * "//localhost", and if it's not an absolute URL, make it one. - FM + */ + LYEnsureAbsoluteURL(&startfile, "STARTFILE", FALSE); + + /* + * If homepage was specified and is a file URL with the host defaulted, + * force in "//localhost", and if it's not an absolute URL, make it one. - + * FM + */ + if (homepage) { + LYEnsureAbsoluteURL(&homepage, "HOMEPAGE", FALSE); + } + + /* + * If we don't have a homepage specified, set it to startfile. Otherwise, + * reset LynxHome. - FM + */ + if (isEmpty(homepage)) { + StrAllocCopy(homepage, startfile); + } else { + StrAllocCopy(LynxHome, homepage); + } + + /* + * Set up the inside/outside domain restriction flags. - FM + */ + if (inlocaldomain()) { +#if !defined(HAVE_UTMP) || defined(VMS) /* not selective */ + telnet_ok = (BOOL) (!no_inside_telnet && !no_outside_telnet && telnet_ok); +#ifndef DISABLE_NEWS + news_ok = (BOOL) (!no_inside_news && !no_outside_news && news_ok); +#endif + ftp_ok = (BOOL) (!no_inside_ftp && !no_outside_ftp && ftp_ok); + rlogin_ok = (BOOL) (!no_inside_rlogin && !no_outside_rlogin && rlogin_ok); +#else + CTRACE((tfp, "LYMain: User in Local domain\n")); + telnet_ok = (BOOL) (!no_inside_telnet && telnet_ok); +#ifndef DISABLE_NEWS + news_ok = (BOOL) (!no_inside_news && news_ok); +#endif + ftp_ok = (BOOL) (!no_inside_ftp && ftp_ok); + rlogin_ok = (BOOL) (!no_inside_rlogin && rlogin_ok); +#endif /* !HAVE_UTMP || VMS */ + } else { + CTRACE((tfp, "LYMain: User in REMOTE domain\n")); + telnet_ok = (BOOL) (!no_outside_telnet && telnet_ok); +#ifndef DISABLE_NEWS + news_ok = (BOOL) (!no_outside_news && news_ok); +#endif + ftp_ok = (BOOL) (!no_outside_ftp && ftp_ok); + rlogin_ok = (BOOL) (!no_outside_rlogin && rlogin_ok); + } +#ifdef DISABLE_FTP + ftp_ok = FALSE; +#else + /* predefine some known broken ftp servers */ + LYSetConfigValue(RC_BROKEN_FTP_RETR, "ProFTPD 1.2.5"); + LYSetConfigValue(RC_BROKEN_FTP_RETR, "spftp/"); + LYSetConfigValue(RC_BROKEN_FTP_EPSV, "(Version wu-2.6.2-12)"); +#endif + + /* + * Make sure our bookmark default strings are all allocated and + * synchronized. - FM + */ + if (isEmpty(bookmark_page)) { + temp = NULL; + HTSprintf0(&temp, "lynx_bookmarks%s", HTML_SUFFIX); + set_default_bookmark_page(temp); + FREE(temp); + } + if (isEmpty(BookmarkPage)) { + set_default_bookmark_page(bookmark_page); + } +#if defined(SYSLOG_REQUESTED_URLS) + LYOpenlog(syslog_txt); +#endif + + if (non_empty(x_display)) { + LYisConfiguredForX = TRUE; + } + + /* + * Here's where we do all the work. + */ + if (dump_output_immediately) { + /* + * Finish setting up and start a NON-INTERACTIVE session. - FM + */ + if (crawl && !number_links && !number_fields) { + keypad_mode = NUMBERS_AS_ARROWS; + } else if (no_numbers) { + keypad_mode = NUMBERS_AS_ARROWS; + } else if (!no_list) { + if (!links_are_numbered()) { + if (number_fields) + keypad_mode = LINKS_AND_FIELDS_ARE_NUMBERED; + else + keypad_mode = LINKS_ARE_NUMBERED; + } + } + if (dump_output_width > 0) { + LYcols = dump_output_width; + } + /* + * Normal argument processing puts non-options (URLs) into the Goto + * history. Use this to dump all of the pages listed on the command + * line, or (if none are listed) via the startfile mechanism. + * history. + */ +#ifdef EXTENDED_STARTFILE_RECALL + HTAddGotoURL(startfile); + for (i = HTList_count(Goto_URLs) - 1; i >= 0; --i) { + StrAllocCopy(startfile, (char *) HTList_objectAt(Goto_URLs, i)); + CTRACE((tfp, "dumping %d:%d %s\n", + i + 1, HTList_count(Goto_URLs), startfile)); + status = mainloop(); + if (!no_list && + !crawl) /* For -crawl it has already been done! */ + printlist(stdout, FALSE); + if (i != 0) + printf("\n"); + } +#else + status = mainloop(); + if (!no_list && + !crawl && /* For -crawl it has already been done! */ + links_are_numbered()) + printlist(stdout, FALSE); +#endif +#ifdef USE_PERSISTENT_COOKIES + /* + * We want to save cookies picked up when in immediate dump mode. + * Instead of calling cleanup() here, let's only call this one. - BJP + */ + if (persistent_cookies) + LYStoreCookies(LYCookieSaveFile); +#endif /* USE_PERSISTENT_COOKIES */ + exit_immediately(status); + } else { + /* + * Start an INTERACTIVE session. - FM + */ +#ifdef USE_COLOR_STYLE + cache_tag_styles(); +#endif + +#ifndef NO_DUMP_WITH_BACKSPACES + if (with_backspaces) { + /* we should warn about this somehow (nop for now) -VH */ + with_backspaces = FALSE; + } +#endif + +#ifndef ALL_CHARSETS_IN_O_MENU_SCREEN + init_charset_subsets(); +#endif + + ena_csi((BOOLEAN) (LYlowest_eightbit[current_char_set] > 155)); +#ifdef USE_SESSIONS + RestoreSession(); +#endif /* USE_SESSIONS */ + status = mainloop(); + LYCloseCloset(RECALL_URL); + LYCloseCloset(RECALL_MAIL); +#if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401 + if (!isendwin()) { + if ((saved_scrsize_x != 0) && (saved_scrsize_y != 0)) { + resize_term(saved_scrsize_y, saved_scrsize_x); + } + } +#endif + cleanup(); + exit_immediately(status); + } + + return (status); /* though redundant, for compiler-warnings */ +} + +/* + * Called by HTAccessInit to register any protocols supported by lynx. + * Protocols added by lynx: + * LYNXKEYMAP, lynxcgi, LYNXIMGMAP, LYNXCOOKIE, LYNXCACHE, LYNXMESSAGES + */ +#ifdef GLOBALREF_IS_MACRO +extern GLOBALREF (HTProtocol, LYLynxKeymap); +extern GLOBALREF (HTProtocol, LYLynxCGI); +extern GLOBALREF (HTProtocol, LYLynxIMGmap); +extern GLOBALREF (HTProtocol, LYLynxCookies); + +#ifdef USE_CACHEJAR +extern GLOBALREF (HTProtocol, LYLynxCache); +#endif +extern GLOBALREF (HTProtocol, LYLynxStatusMessages); + +#else +GLOBALREF HTProtocol LYLynxKeymap; +GLOBALREF HTProtocol LYLynxCGI; +GLOBALREF HTProtocol LYLynxIMGmap; +GLOBALREF HTProtocol LYLynxCookies; + +#ifdef USE_CACHEJAR +GLOBALREF HTProtocol LYLynxCache; +#endif +GLOBALREF HTProtocol LYLynxStatusMessages; +#endif /* GLOBALREF_IS_MACRO */ + +void LYRegisterLynxProtocols(void) +{ + HTRegisterProtocol(&LYLynxKeymap); + HTRegisterProtocol(&LYLynxCGI); + HTRegisterProtocol(&LYLynxIMGmap); + HTRegisterProtocol(&LYLynxCookies); +#ifdef USE_CACHEJAR + HTRegisterProtocol(&LYLynxCache); +#endif + HTRegisterProtocol(&LYLynxStatusMessages); +} + +#ifndef NO_CONFIG_INFO +/* + * Some stuff to reload lynx.cfg without restarting new lynx session, also load + * options menu items and command-line options to make things consistent. + * + * Called by user of interactive session by LYNXCFG://reload/ link. + * + * Warning: experimental, more main() reorganization required. + * *Known* exceptions: persistent cookies, cookie files. + * + * Some aspects of COLOR (with slang?). + * Viewer stuff, mailcap files + * SUFFIX, mime.types files + * RULESFILE/RULE + * + * All work "somewhat", but not exactly as the first time. + */ +void reload_read_cfg(void) +{ + char *tempfile; + FILE *rcfp; + + /* + * no_option_save is always set for -anonymous and -validate. It is better + * to check for one or several specific restriction flags than for + * 'LYRestricted', which doesn't get set for individual restrictions or for + * -validate! However, no_option_save may not be the appropriate one to + * check - in that case, a new no_something should be added that gets + * automatically set for -anonymous and -validate (and whether it applies + * for -anonymous can be made installer- configurable in the usual way at + * the bottom of userdefs.h). - kw + * + */ + if (no_option_save) { + /* current logic requires(?) that saving user preferences is + possible. Additional applicable restrictions are already + checked by caller. - kw */ + return; + } + + /* + * Current user preferences are saved in a temporary file, to be read in + * again after lynx.cfg has been read. This avoids accidental changing of + * the preferences file. The regular preferences file doesn't even need to + * exist, and won't be created as a side effect of this function. Honoring + * the no_option_save restriction may thus be unnecessarily restrictive, + * but the check is currently still left in place. - kw + */ + tempfile = typecallocn(char, LY_MAXPATH); + if (!tempfile) { + HTAlwaysAlert(NULL, NOT_ENOUGH_MEMORY); + return; + } + rcfp = LYOpenTemp(tempfile, ".rc", "w"); + if (rcfp == NULL) { + FREE(tempfile); + HTAlwaysAlert(NULL, CANNOT_OPEN_TEMP); + return; + } + if (!save_rc(rcfp)) { + HTAlwaysAlert(NULL, OPTIONS_NOT_SAVED); + LYRemoveTemp(tempfile); + FREE(tempfile); + return; /* can not write the very own file :( */ + } { + /* set few safe flags: */ +#ifdef USE_PERSISTENT_COOKIES + BOOLEAN persistent_cookies_flag = persistent_cookies; + char *LYCookieFile_flag = NULL; + char *LYCookieSaveFile_flag = NULL; + + if (persistent_cookies) { + StrAllocCopy(LYCookieFile_flag, LYCookieFile); + StrAllocCopy(LYCookieSaveFile_flag, LYCookieSaveFile); + } +#endif + +#ifdef USE_CHARSET_CHOICE + custom_assumed_doc_charset = FALSE; + custom_display_charset = FALSE; + memset((char *) charset_subsets, 0, sizeof(charset_subset_t) * MAXCHARSETS); +#endif + +#ifdef USE_PRETTYSRC + html_src_on_lynxcfg_reload(); +#endif + /* free downloaders, printers, environments, dired menu */ + free_lynx_cfg(); +#ifdef USE_SOURCE_CACHE + source_cache_file_error = FALSE; /* reset flag */ +#endif + + /* + * Process the configuration file. + */ + read_cfg(lynx_cfg_file, "main program", 1, (FILE *) 0); + + /* + * Process the temporary RC file. + */ + rcfp = fopen(tempfile, "r"); + read_rc(rcfp); + LYRemoveTemp(tempfile); + FREE(tempfile); /* done with it - kw */ + +#ifdef USE_CHARSET_CHOICE + init_charset_subsets(); +#endif + + /* + * Initialize other things based on the configuration read. + */ + LYSetDisplayLines(); + /* Not implemented yet here, + * a major problem: file paths + * like lynx_save_space, LYCookieFile etc. + */ +#ifdef USE_PERSISTENT_COOKIES + /* restore old settings */ + if (persistent_cookies != persistent_cookies_flag) { + persistent_cookies = persistent_cookies_flag; + HTAlert(gettext("persistent cookies state will be changed in next session only.")); + } + if (persistent_cookies) { + if (strcmp(LYCookieFile, LYCookieFile_flag)) { + StrAllocCopy(LYCookieFile, LYCookieFile_flag); + CTRACE((tfp, + "cookie file can be changed in next session only, restored.\n")); + } + if (strcmp(LYCookieSaveFile, LYCookieSaveFile_flag)) { + StrAllocCopy(LYCookieSaveFile, LYCookieSaveFile_flag); + CTRACE((tfp, + "cookie save file can be changed in next session only, restored.\n")); + } + FREE(LYCookieFile_flag); + FREE(LYCookieSaveFile_flag); + } +#endif + + } +} +#endif /* !NO_CONFIG_INFO */ + +static void force_dump_mode(void) +{ + dump_output_immediately = TRUE; + no_pause = TRUE; + LYcols = DFT_COLS; +} + +/* There are different ways of setting arguments on the command line, and + * there are different types of arguments. These include: + * + * -set_some_variable ==> some_variable = TRUE + * -toggle_some_variable ==> some_variable = !some_variable + * -some_variable=value ==> some_variable = value + * + * Others are complicated and require a function call. + */ + +#define PARSE_SET(n,t,v,h) {n, t, UNION_SET(v), h} +#define PARSE_INT(n,t,v,h) {n, t, UNION_INT(v), h} +#define PARSE_STR(n,t,v,h) {n, t, UNION_STR(v), h} +#define PARSE_FUN(n,t,v,h) {n, t, UNION_FUN(v), h} +#define PARSE_NIL {NULL, 0, UNION_DEF(0), NULL} + +typedef struct parse_args_type { + const char *name; + int type; + +#define TOGGLE_ARG 0x0010 +#define SET_ARG 0x0020 +#define UNSET_ARG 0x0030 +#define FUNCTION_ARG 0x0040 +#define LYSTRING_ARG 0x0050 +#define INT_ARG 0x0060 +#define STRING_ARG 0x0070 +#define TIME_ARG 0x0080 +#define ARG_TYPE_MASK 0x0FF0 +#define NEED_NEXT_ARG 0x1000 + +#define NEED_INT_ARG (NEED_NEXT_ARG | INT_ARG) +#define NEED_TIME_ARG (NEED_NEXT_ARG | TIME_ARG) +#define NEED_LYSTRING_ARG (NEED_NEXT_ARG | LYSTRING_ARG) +#define NEED_STRING_ARG (NEED_NEXT_ARG | STRING_ARG) +#define NEED_FUNCTION_ARG (NEED_NEXT_ARG | FUNCTION_ARG) + + /* If the NEED_NEXT_ARG flags is set, and the option was not specified + * with an '=' character, then use the next argument in the argv list. + */ + + ParseData; + const char *help_string; +} Config_Type; + +/* -auth, -pauth */ +static int parse_authentication(char *next_arg, + char **result) +{ + /* + * Authentication information for protected documents. + */ + char *auth_info = 0; + + if (next_arg != 0) { + StrAllocCopy(auth_info, next_arg); + memset(next_arg, ' ', strlen(next_arg)); /* Let's not show too much */ + } + + if (auth_info != 0) { + char *cp; + + if ((cp = strchr(auth_info, ':')) != 0) { /* Pw */ + *cp++ = '\0'; /* Terminate ID */ + HTUnEscape(cp); + StrAllocCopy(result[1], cp); + } + if (*auth_info) { /* Id */ + HTUnEscape(auth_info); + StrAllocCopy(result[0], auth_info); + } + FREE(auth_info); + } + return 0; +} + +/* -anonymous */ +static int anonymous_fun(char *next_arg GCC_UNUSED) +{ + if (!LYValidate && !LYRestricted) + parse_restrictions("default"); + LYRestricted = TRUE; + return 0; +} + +/* -assume_charset */ +static int assume_charset_fun(char *next_arg) +{ + UCLYhndl_for_unspec = safeUCGetLYhndl_byMIME(next_arg); + StrAllocCopy(UCAssume_MIMEcharset, + LYCharSet_UC[UCLYhndl_for_unspec].MIMEname); +/* this may be a memory for bogus typo - + StrAllocCopy(UCAssume_MIMEcharset, next_arg); + LYLowerCase(UCAssume_MIMEcharset); */ + + return 0; +} + +/* -assume_local_charset */ +static int assume_local_charset_fun(char *next_arg) +{ + UCLYhndl_HTFile_for_unspec = safeUCGetLYhndl_byMIME(next_arg); + return 0; +} + +/* -assume_unrec_charset */ +static int assume_unrec_charset_fun(char *next_arg) +{ + UCLYhndl_for_unrec = safeUCGetLYhndl_byMIME(next_arg); + return 0; +} + +/* -auth */ +static int auth_fun(char *next_arg) +{ + parse_authentication(next_arg, authentication_info); + return 0; +} + +/* -base */ +static int base_fun(char *next_arg GCC_UNUSED) +{ + /* + * Treat -source equivalently to an interactive download with + * LYPrefixBaseToSource configured to TRUE, so that a BASE tag is prepended + * for text/html content types. We normally treat the module-wide global + * LYPrefixBaseToSource flag as FALSE with -source, but force it TRUE, + * later, if LYPrependBase is set TRUE here. - FM + */ + LYPrependBase = TRUE; + if (HTOutputFormat == HTAtom_for("www/dump")) + HTOutputFormat = HTAtom_for("www/download"); + + return 0; +} + +/* -cache */ +static int cache_fun(char *next_arg) +{ + if (next_arg != 0) + HTCacheSize = atoi(next_arg); + /* + * Limit size. + */ + if (HTCacheSize < 2) + HTCacheSize = 2; + + return 0; +} + +/* -child */ +static int child_fun(char *next_arg GCC_UNUSED) +{ + child_lynx = TRUE; + no_disk_save = TRUE; + no_mail = TRUE; + return 0; +} + +/* -child_relaxed */ +static int child_relaxed_fun(char *next_arg GCC_UNUSED) +{ + child_lynx = TRUE; + return 0; +} + +#ifdef USE_SLANG +/* -color */ +static int color_fun(char *next_arg GCC_UNUSED) +{ + Lynx_Color_Flags |= SL_LYNX_USE_COLOR; + + if (LYShowColor != SHOW_COLOR_ALWAYS) + LYShowColor = SHOW_COLOR_ON; + + return 0; +} +#endif + +#ifdef MISC_EXP +/* -convert_to */ +static int convert_to_fun(char *next_arg) +{ + if (next_arg != 0) { + char *outformat = NULL; + char *cp1, *cp2, *cp4; + int chndl; + + StrAllocCopy(outformat, next_arg); + /* not lowercased, to allow for experimentation - kw */ + /*LYLowerCase(outformat); */ + if ((cp1 = strchr(outformat, ';')) != NULL) { + if ((cp2 = LYstrstr(cp1, "charset")) != NULL) { + cp2 += 7; + while (*cp2 == ' ' || *cp2 == '=' || *cp2 == '"') + cp2++; + for (cp4 = cp2; (*cp4 != '\0' && *cp4 != '"' && + *cp4 != ';' && + !WHITE(*cp4)); cp4++) ; /* do nothing */ + *cp4 = '\0'; + /* This is intentionally not the "safe" version, + to allow for experimentation. */ + chndl = UCGetLYhndl_byMIME(cp2); + if (chndl < 0) + chndl = UCLYhndl_for_unrec; + if (chndl < 0) { + fprintf(stderr, + gettext("Lynx: ignoring unrecognized charset=%s\n"), cp2); + } else { + current_char_set = chndl; + } + *cp1 = '\0'; /* truncate outformat */ + } + } + HTOutputFormat = HTAtom_for(outformat); + FREE(outformat); + } else { + HTOutputFormat = NULL; + } + return 0; +} +#endif + +/* -crawl */ +static int crawl_fun(char *next_arg GCC_UNUSED) +{ + crawl = TRUE; + LYcols = DFT_COLS; + return 0; +} + +/* -display */ +static int display_fun(char *next_arg) +{ + if (next_arg != 0) { + LYsetXDisplay(next_arg); + } + + return 0; +} + +/* -display_charset */ +static int display_charset_fun(char *next_arg) +{ + int i = UCGetLYhndl_byMIME(next_arg); + +#ifdef CAN_AUTODETECT_DISPLAY_CHARSET + if (i < 0 && !strcasecomp(next_arg, "auto")) + i = auto_display_charset; +#endif + if (i < 0) { /* do nothing here: so fallback to lynx.cfg */ + fprintf(stderr, + gettext("Lynx: ignoring unrecognized charset=%s\n"), next_arg); + } else + current_char_set = i; + return 0; +} + +/* -dump */ +static int dump_output_fun(char *next_arg GCC_UNUSED) +{ + force_dump_mode(); + return 0; +} + +/* -editor */ +static int editor_fun(char *next_arg) +{ + if (next_arg != 0) + StrAllocCopy(editor, next_arg); + system_editor = TRUE; + return 0; +} + +/* -error_file */ +static int error_file_fun(char *next_arg) +{ + /* + * Output return (success/failure) code of an HTTP transaction. + */ + if (next_arg != 0) + http_error_file = next_arg; + return 0; +} + +#if defined(EXEC_LINKS) || defined(EXEC_SCRIPTS) +/* -exec */ +static int exec_fun(char *next_arg GCC_UNUSED) +{ +#ifndef NEVER_ALLOW_REMOTE_EXEC + local_exec = TRUE; +#else + local_exec_on_local_files = TRUE; +#endif /* NEVER_ALLOW_REMOTE_EXEC */ + return 0; +} +#endif + +/* -get_data */ +static int get_data_fun(char *next_arg GCC_UNUSED) +{ + /* + * User data for GET form. + */ + char **get_data; + char *buf = NULL; + + /* + * On Unix, conflicts with curses when interactive so let's force a dump. + * -CL + * + * On VMS, mods have been made in LYCurses.c to deal with potential + * conflicts, so don't force the dump here. - FM + */ +#ifndef VMS + force_dump_mode(); +#endif /* VMS */ + + StrAllocCopy(form_get_data, "?"); /* Prime the pump */ + get_data = &form_get_data; + + /* + * Build GET data for later. Stop reading when we see a line with "---" as + * its first three characters. + */ + while (GetStdin(&buf, TRUE)) { + StrAllocCat(*get_data, buf); + } + + CTRACE((tfp, "get_data:%s\n", *get_data)); + CTRACE((tfp, "get_data:%s\n", form_get_data)); + return 0; +} + +/* -help */ +static int help_fun(char *next_arg GCC_UNUSED) +{ + print_help_and_exit(0); + return 0; +} + +/* -hiddenlinks */ +static int hiddenlinks_fun(char *next_arg) +{ + /* *INDENT-OFF* */ + static Config_Enum table[] = { + { "merge", HIDDENLINKS_MERGE }, + { "listonly", HIDDENLINKS_SEPARATE }, + { "ignore", HIDDENLINKS_IGNORE }, + { NULL, -1 }, + }; + /* *INDENT-ON* */ + + if (next_arg != 0) { + if (!LYgetEnum(table, next_arg, &LYHiddenLinks)) + print_help_and_exit(-1); + } else { + LYHiddenLinks = HIDDENLINKS_MERGE; + } + + return 0; +} + +/* -homepage */ +static int homepage_fun(char *next_arg) +{ + if (next_arg != 0) { + StrAllocCopy(homepage, next_arg); + LYEscapeStartfile(&homepage); + } + return 0; +} + +/* -mime_header */ +static int mime_header_fun(char *next_arg GCC_UNUSED) +{ + /* + * Include mime headers and force source dump. + */ + keep_mime_headers = TRUE; + force_dump_mode(); + HTOutputFormat = (LYPrependBase ? + HTAtom_for("www/download") : HTAtom_for("www/dump")); + LYcols = MAX_COLS; + return 0; +} + +#ifndef DISABLE_NEWS +/* -newschunksize */ +static int newschunksize_fun(char *next_arg) +{ + if (next_arg != 0) { + HTNewsChunkSize = atoi(next_arg); + /* + * If the new HTNewsChunkSize exceeds the maximum, + * increase HTNewsMaxChunk to this size. - FM + */ + if (HTNewsChunkSize > HTNewsMaxChunk) + HTNewsMaxChunk = HTNewsChunkSize; + } + return 0; +} + +/* -newsmaxchunk */ +static int newsmaxchunk_fun(char *next_arg) +{ + if (next_arg) { + HTNewsMaxChunk = atoi(next_arg); + /* + * If HTNewsChunkSize exceeds the new maximum, + * reduce HTNewsChunkSize to this maximum. - FM + */ + if (HTNewsChunkSize > HTNewsMaxChunk) + HTNewsChunkSize = HTNewsMaxChunk; + } + return 0; +} +#endif /* not DISABLE_NEWS */ + +/* -nobold */ +static int nobold_fun(char *next_arg GCC_UNUSED) +{ + LYnoVideo(1); + return 0; +} + +/* -nobrowse */ +static int nobrowse_fun(char *next_arg GCC_UNUSED) +{ + HTDirAccess = HT_DIR_FORBID; + return 0; +} + +/* -nocolor */ +static int nocolor_fun(char *next_arg GCC_UNUSED) +{ + LYShowColor = SHOW_COLOR_NEVER; +#ifdef USE_SLANG + Lynx_Color_Flags &= ~SL_LYNX_USE_COLOR; + Lynx_Color_Flags |= SL_LYNX_OVERRIDE_COLOR; +#endif + return 0; +} + +/* -nopause */ +static int nopause_fun(char *next_arg GCC_UNUSED) +{ + no_pause = TRUE; + return 0; +} + +/* -nomore */ +static int nomore_fun(char *next_arg GCC_UNUSED) +{ + nomore = TRUE; + return 0; +} + +/* -noreverse */ +static int noreverse_fun(char *next_arg GCC_UNUSED) +{ + LYnoVideo(2); + return 0; +} + +/* -nounderline */ +static int nounderline_fun(char *next_arg GCC_UNUSED) +{ + LYnoVideo(4); + return 0; +} + +#ifdef MISC_EXP +/* -nozap */ +static int nozap_fun(char *next_arg) +{ + LYNoZapKey = 1; /* everything but "initially" treated as "full" - kw */ + if (next_arg != 0) { + if (strcasecomp(next_arg, "initially") == 0) + LYNoZapKey = 2; + + } + return 0; +} +#endif /* MISC_EXP */ + +/* -pauth */ +static int pauth_fun(char *next_arg) +{ + parse_authentication(next_arg, proxyauth_info); + return 0; +} + +/* -post_data */ +static int post_data_fun(char *next_arg GCC_UNUSED) +{ + /* + * User data for POST form. + */ + char **post_data; + char *buf = NULL; + + /* + * On Unix, conflicts with curses when interactive so let's force a dump. + * - CL + * + * On VMS, mods have been made in LYCurses.c to deal with potential + * conflicts, so don't force a dump here. - FM + */ +#ifndef VMS + force_dump_mode(); +#endif /* VMS */ + + post_data = &form_post_data; + + /* + * Build post data for later. Stop reading when we see a line with "---" + * as its first three characters. + */ + while (GetStdin(&buf, TRUE)) { + StrAllocCat(*post_data, buf); + } + return 0; +} + +static const char *show_restriction(const char *name) +{ + const char *value = 0; + + switch (find_restriction(name, -1)) { + case TRUE: + value = "on"; + break; + case FALSE: + value = "off"; + break; + default: + value = "?"; + break; + } + return value; +} + +/* -restrictions */ +static int restrictions_fun(char *next_arg) +{ + /* *INDENT-OFF* */ + static const struct { + const char *name; + const char *help; + } table[] = { + { "all", "restricts all options." }, + { "bookmark", "disallow changing the location of the bookmark file" }, + { "bookmark_exec", "disallow execution links via the bookmark file" }, +#if defined(DIRED_SUPPORT) && defined(OK_PERMIT) + { "change_exec_perms", "\ +disallow changing the eXecute permission on files\n\ +(but still allow it for directories) when local file\n\ +management is enabled." }, +#endif /* DIRED_SUPPORT && OK_PERMIT */ +#ifdef SUPPORT_CHDIR + { "chdir", "\ +disallow changing the working directory of lynx, e.g.,\n\ +to affect the behavior of download command" }, +#endif +#if defined(HAVE_CONFIG_H) && !defined(NO_CONFIG_INFO) + { "compileopts_info", "\ +disable info on options used to compile the binary" }, +#endif + { "default", "\ +same as commandline option -anonymous. Sets the\n\ +default service restrictions for anonymous users. Set to\n\ +all restricted, except for: inside_telnet, outside_telnet,\n\ +inside_ftp, outside_ftp, inside_rlogin, outside_rlogin,\n\ +inside_news, outside_news, telnet_port, jump, mail, print,\n\ +exec, and goto. The settings for these, as well as\n\ +additional goto restrictions for specific URL schemes\n\ +that are also applied, are derived from definitions\n\ +within userdefs.h." }, +#ifdef DIRED_SUPPORT + { "dired_support", "disallow local file management" }, +#endif /* DIRED_SUPPORT */ + { "disk_save", "disallow saving to disk in the download and print menus" }, + { "dotfiles", "disallow access to, or creation of, hidden (dot) files" }, + { "download", "disallow some downloaders in the download menu" }, + { "editor", "disallow editing" }, + { "exec", "disable execution scripts" }, + { "exec_frozen", "disallow the user from changing the execution link option" }, +#ifdef USE_EXTERNALS + { "externals", "disable passing URLs to some external programs" }, +#endif + { "file_url", "\ +disallow using G)oto, served links or bookmarks for\n\ +file: URL's" }, + { "goto", "disable the 'g' (goto) command" }, +#if !defined(HAVE_UTMP) || defined(VMS) /* not selective */ + { "inside_ftp", "\ +disallow ftps coming from inside your\n\ +domain (utmp required for selectivity)" }, + { "inside_news", "\ +disallow USENET news reading and posting coming\n\ +from inside your domain (utmp required for selectivity)" }, + { "inside_rlogin", "\ +disallow rlogins coming from inside your\n\ +domain (utmp required for selectivity)" }, + { "inside_telnet", "\ +disallow telnets coming from inside your\n\ +domain (utmp required for selectivity)" }, +#else + { "inside_ftp", "\ +disallow ftps coming from inside your domain" }, + { "inside_news", "\ +disallow USENET news reading and posting coming\n\ +from inside your domain" }, + { "inside_rlogin", "\ +disallow rlogins coming from inside your domain" }, + { "inside_telnet", "\ +disallow telnets coming from inside your domain" }, +#endif /* HAVE_UTMP || VMS */ + { "jump", "disable the 'j' (jump) command" }, + { "lynxcfg_info", "\ +disable viewing of lynx.cfg configuration file info" }, +#ifndef NO_CONFIG_INFO + { "lynxcfg_xinfo", "\ +disable extended lynx.cfg viewing and reloading" }, +#endif + { "lynxcgi", "\ +disallow execution of Lynx CGI URLs" }, + { "mail", "disallow mail" }, + { "multibook", "disallow multiple bookmark files" }, + { "news_post", "disallow USENET News posting." }, + { "option_save", "disallow saving options in .lynxrc" }, +#if !defined(HAVE_UTMP) || defined(VMS) /* not selective */ + { "outside_ftp", "\ +disallow ftps coming from outside your\n\ +domain (utmp required for selectivity)" }, + { "outside_news", "\ +disallow USENET news reading and posting coming\n\ +from outside your domain (utmp required for selectivity)" }, + { "outside_rlogin", "\ +disallow rlogins coming from outside your\n\ +domain (utmp required for selectivity)" }, + { "outside_telnet", "\ +disallow telnets coming from outside your\n\ +domain (utmp required for selectivity)" }, +#else + { "outside_ftp", "\ +disallow ftp coming from outside your domain" }, + { "outside_news", "\ +disallow USENET news reading and posting coming\n\ +from outside your domain" }, + { "outside_rlogin", "\ +disallow rlogins coming from outside your domain" }, + { "outside_telnet", "\ +disallow telnets coming from outside your domain" }, +#endif /* !HAVE_UTMP || VMS */ + { "print", "disallow most print options" }, + { "shell", "\ +disallow shell escapes, and lynxexec, lynxprog or lynxcgi\n\ +G)oto's" }, + { "suspend", "disallow Control-Z suspends with escape to shell" }, + { "telnet_port", "disallow specifying a port in telnet G)oto's" }, + { "useragent", "disallow modifications of the User-Agent header" }, + }; + /* *INDENT-ON* */ + + static const char *Usage[] = + { + "" + ,"USAGE: lynx -restrictions=[option][,option][,option]" + ,"List of Options:" + ," ? when used alone, list restrictions in effect." + + }; + unsigned j, k, column = 0; + const char *name; + const char *value; + BOOLEAN found, first; + + if (isEmpty(next_arg)) { + SetOutputMode(O_TEXT); + for (j = 0; j < TABLESIZE(Usage); j++) { + printf("%s\n", Usage[j]); + } + for (j = 0; j < TABLESIZE(table); j++) { + if (!strcmp(table[j].name, "all") + || !strcmp(table[j].name, "default")) { + value = NULL; + } else { + value = show_restriction(table[j].name); + } + print_help_strings(table[j].name, table[j].help, value, FALSE); + } + first = TRUE; + for (j = 0;; j++) { + found = FALSE; + if ((name = index_to_restriction(j)) == 0) { + break; + } + for (k = 0; k < TABLESIZE(table); k++) { + if (!strcmp(name, table[k].name)) { + found = TRUE; + } + } + if (!found) { + if (first) { + printf("Other restrictions (see the user's guide):\n"); + } + value = show_restriction(table[j].name); + printf("%s%s (%s)", column ? ", " : " ", name, value); + column += 5 + strlen(name) + strlen(value); + if (column > 50) { + column = 0; + printf("\n"); + } + first = FALSE; + } + } + if (column) + printf("\n"); + SetOutputMode(O_BINARY); + exit_immediately(EXIT_SUCCESS); + } else if (*next_arg == '?') { + SetOutputMode(O_TEXT); + print_restrictions_to_fd(stdout); + SetOutputMode(O_BINARY); + exit_immediately(EXIT_SUCCESS); + } else { + parse_restrictions(next_arg); + } + return 0; +} + +/* -selective */ +static int selective_fun(char *next_arg GCC_UNUSED) +{ + HTDirAccess = HT_DIR_SELECTIVE; + return 0; +} + +/* -source */ +static int source_fun(char *next_arg GCC_UNUSED) +{ + force_dump_mode(); + HTOutputFormat = (LYPrependBase ? + HTAtom_for("www/download") : HTAtom_for("www/dump")); + LYcols = MAX_COLS; + return 0; +} + +/* -traversal */ +static int traversal_fun(char *next_arg GCC_UNUSED) +{ + traversal = TRUE; +#ifdef USE_SLANG + LYcols = DFT_COLS; +#else + LYcols = MAX_COLS; +#endif /* USE_SLANG */ + + return 0; +} + +/* -version */ +static int version_fun(char *next_arg GCC_UNUSED) +{ + char *result = NULL; + + SetLocale(); + SetOutputMode(O_TEXT); + + HTSprintf0(&result, gettext("%s Version %s (%s)"), + LYNX_NAME, LYNX_VERSION, + LYVersionDate()); + + StrAllocCat(result, "\n"); +#ifdef USE_SSL + HTSprintf(&result, "libwww-FM %s,", HTLibraryVersion); + append_ssl_version(&result, " "); +#else + HTSprintf(&result, "libwww-FM %s", HTLibraryVersion); +#endif /* USE_SSL */ + +#if defined(NCURSES) && defined(HAVE_CURSES_VERSION) + HTSprintf(&result, ", %s", curses_version()); +#if defined(WIDEC_CURSES) + HTSprintf(&result, "(wide)"); +#endif +#elif defined(PDCURSES) && defined(PDC_BUILD) + HTSprintf(&result, ", pdcurses %.3f", PDC_BUILD * 0.001); +#elif defined(USE_SLANG) && defined(SLANG_VERSION_STRING) + HTSprintf(&result, ", s-lang %s", SLANG_VERSION_STRING); +#endif + + printf("%s\n", result); + free(result); + +#ifndef __DATE__ +#define __DATE__ "" +#endif +#ifndef __TIME__ +#define __TIME__ "" +#endif + +/* + * SYSTEM_NAME is set by the configure script. Show build date/time for other + * systems, according to predefined compiler symbols. + */ +#ifdef SYSTEM_NAME + printf(gettext("Built on %s %s %s\n"), SYSTEM_NAME, __DATE__, __TIME__); +#else +#ifdef __CYGWIN__ + printf("Compiled by CYGWIN (%s %s).\n", __DATE__, __TIME__); +#else +#ifdef __BORLANDC__ + printf("Compiled by Borland C++ (%s %s).\n", __DATE__, __TIME__); +#else +#ifdef _MSC_VER + printf("Compiled by Microsoft Visual C++ (%s %s).\n", __DATE__, __TIME__); +#else +#ifdef __DJGPP__ + printf("Compiled by DJGPP (%s %s).\n", __DATE__, __TIME__); +#else + printf("Compiled at (%s %s).\n", __DATE__, __TIME__); +#endif /* __DJGPP__ */ +#endif /* _MSC_VER */ +#endif /* __BORLANDC__ */ +#endif /* __CYGWIN__ */ +#endif + + puts(""); + puts(gettext("Copyrights held by the Lynx Developers Group,")); + puts(gettext("the University of Kansas, CERN, and other contributors.")); + puts(gettext("Distributed under the GNU General Public License (Version 2).")); + puts(gettext("See http://lynx.isc.org/ and the online help for more information.")); + puts(""); +#ifdef USE_SSL +#if defined(OPENSSL_VERSION_TEXT) && !defined(LIBGNUTLS_VERSION) + puts("See http://www.openssl.org/ for information about OpenSSL."); +#endif /* OPENSSL_VERSION_TEXT */ + puts(""); +#endif /* USE_SSL */ + + SetOutputMode(O_BINARY); + + exit_immediately(EXIT_SUCCESS); + /* NOT REACHED */ + return 0; +} + +/* -width */ +static int width_fun(char *next_arg) +{ + if (next_arg != 0) { + int w = atoi(next_arg); + + if (w > 0) + dump_output_width = ((w < MAX_COLS) ? w : MAX_COLS); + } + + return 0; +} + +#if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401 +/* -scrsize */ +static int scrsize_fun(char *next_arg) +{ + if (next_arg != 0) { + char *cp; + + if ((cp = strchr(next_arg, ',')) != 0) { + *cp++ = '\0'; /* Terminate ID */ + scrsize_x = atoi(next_arg); + scrsize_y = atoi(cp); + if ((scrsize_x <= 1) || (scrsize_y <= 1)) { + scrsize_x = scrsize_y = 0; + } + if ((scrsize_x > 0) && (scrsize_x < 80)) { + scrsize_x = 80; + } + if ((scrsize_y > 0) && (scrsize_y < 4)) { + scrsize_y = 4; + } + CTRACE((tfp, "scrsize: x=%d, y=%d\n", scrsize_x, scrsize_y)); + } + } + return 0; +} +#endif + +/* NOTE: This table is sorted by name to make the help message useful */ +/* *INDENT-OFF* */ +static Config_Type Arg_Table [] = +{ + PARSE_SET( + "accept_all_cookies", 4|SET_ARG, LYAcceptAllCookies, + "\naccept cookies without prompting if Set-Cookie handling\nis on" + ), + PARSE_FUN( + "anonymous", 2|FUNCTION_ARG, anonymous_fun, + "apply restrictions for anonymous account,\nsee also -restrictions" + ), + PARSE_FUN( + "assume_charset", 4|NEED_FUNCTION_ARG, assume_charset_fun, + "=MIMEname\ncharset for documents that don't specify it" + ), + PARSE_FUN( + "assume_local_charset", 4|NEED_FUNCTION_ARG, assume_local_charset_fun, + "=MIMEname\ncharset assumed for local files" + ), + PARSE_FUN( + "assume_unrec_charset", 4|NEED_FUNCTION_ARG, assume_unrec_charset_fun, + "=MIMEname\nuse this instead of unrecognized charsets" + ), + PARSE_FUN( + "auth", 4|NEED_FUNCTION_ARG, auth_fun, + "=id:pw\nauthentication information for protected documents" + ), + PARSE_FUN( + "base", 4|FUNCTION_ARG, base_fun, + "prepend a request URL comment and BASE tag to text/html\n\ +outputs for -source dumps" + ), +#ifndef DISABLE_BIBP + PARSE_STR( + "bibhost", 4|NEED_LYSTRING_ARG, BibP_bibhost, + "=URL\nlocal bibp server (default http://bibhost/)" + ), +#endif +#ifdef USE_BLINK + PARSE_SET( + "blink", 4|SET_ARG, term_blink_is_boldbg, + "enable bright background via the BLINK terminal attribute" + ), +#endif + PARSE_SET( + "book", 4|SET_ARG, bookmark_start, + "use the bookmark page as the startfile" + ), + PARSE_SET( + "buried_news", 4|TOGGLE_ARG, scan_for_buried_news_references, + "toggles scanning of news articles for buried references" + ), + PARSE_FUN( + "cache", 4|NEED_FUNCTION_ARG, cache_fun, + "=NUMBER\nNUMBER of documents cached in memory" + ), + PARSE_SET( + "case", 4|SET_ARG, case_sensitive, + "enable case sensitive user searching" + ), + PARSE_SET( + "center", 4|TOGGLE_ARG, no_table_center, + "toggle center alignment in HTML TABLE" + ), + PARSE_STR( + "cfg", 2|NEED_LYSTRING_ARG, lynx_cfg_file, + "=FILENAME\nspecifies a lynx.cfg file other than the default" + ), + PARSE_FUN( + "child", 4|FUNCTION_ARG, child_fun, + "exit on left-arrow in startfile, and disable save to disk" + ), + PARSE_FUN( + "child_relaxed", 4|FUNCTION_ARG, child_relaxed_fun, + "exit on left-arrow in startfile (allows save to disk)" + ), +#ifdef USE_CMD_LOGGING + PARSE_STR( + "cmd_log", 2|NEED_LYSTRING_ARG, lynx_cmd_logfile, + "=FILENAME\nlog keystroke commands to the given file" + ), + PARSE_STR( + "cmd_script", 2|NEED_LYSTRING_ARG, lynx_cmd_script, + "=FILENAME\nread keystroke commands from the given file\n(see -cmd_log)" + ), +#endif +#ifdef USE_SLANG + PARSE_FUN( + "color", 4|FUNCTION_ARG, color_fun, + "force color mode on with standard bg colors" + ), +#endif + PARSE_INT( + "connect_timeout", 4|NEED_INT_ARG, connect_timeout, + "=N\nset the N-second connection timeout" + ), +#ifdef MISC_EXP + PARSE_FUN( + "convert_to", 4|FUNCTION_ARG, convert_to_fun, + "=FORMAT\nconvert input, FORMAT is in MIME type notation\n(experimental)" + ), +#endif +#ifdef USE_PERSISTENT_COOKIES + PARSE_STR( + "cookie_file", 4|LYSTRING_ARG, LYCookieFile, + "=FILENAME\nspecifies a file to use to read cookies" + ), + PARSE_STR( + "cookie_save_file", 4|LYSTRING_ARG, LYCookieSaveFile, + "=FILENAME\nspecifies a file to use to store cookies" + ), +#endif /* USE_PERSISTENT_COOKIES */ + PARSE_SET( + "cookies", 4|TOGGLE_ARG, LYSetCookies, + "toggles handling of Set-Cookie headers" + ), +#ifndef VMS + PARSE_SET( + "core", 4|TOGGLE_ARG, LYNoCore, + "toggles forced core dumps on fatal errors" + ), +#endif + PARSE_FUN( + "crawl", 4|FUNCTION_ARG, crawl_fun, + "with -traversal, output each page to a file\n\ +with -dump, format output as with -traversal, but to stdout" + ), +#ifdef USE_CURSES_PADS + PARSE_SET( + "curses_pads", 4|TOGGLE_ARG, LYuseCursesPads, + "uses curses pad feature to support left/right shifting" + ), +#endif +#ifdef DISP_PARTIAL + PARSE_SET( + "debug_partial", 4|TOGGLE_ARG, debug_display_partial, + "incremental display stages with MessageSecs delay" + ), +#endif + PARSE_INT( + "delay", 4|NEED_TIME_ARG, DebugSecs, + "=NNN\nset NNN-second delay at statusline message" + ), + PARSE_FUN( + "display", 4|NEED_FUNCTION_ARG, display_fun, + "=DISPLAY\nset the display variable for X exec'ed programs" + ), + PARSE_FUN( + "display_charset", 4|NEED_FUNCTION_ARG, display_charset_fun, + "=MIMEname\ncharset for the terminal output" + ), + PARSE_SET( + "dont_wrap_pre", 4|SET_ARG, dont_wrap_pre, + "inhibit wrapping of text in
 when -dump'ing and\n\
+-crawl'ing, mark wrapped lines in interactive session"
+   ),
+   PARSE_FUN(
+      "dump",		4|FUNCTION_ARG,		dump_output_fun,
+      "dump the first file to stdout and exit"
+   ),
+   PARSE_FUN(
+      "editor",		4|NEED_FUNCTION_ARG,	editor_fun,
+      "=EDITOR\nenable edit mode with specified editor"
+   ),
+   PARSE_SET(
+      "emacskeys",	4|SET_ARG,		emacs_keys,
+      "enable emacs-like key movement"
+   ),
+   PARSE_SET(
+      "enable_scrollback", 4|TOGGLE_ARG,	enable_scrollback,
+      "\ntoggles compatibility with comm programs' scrollback\n\
+keys (may be incompatible with some curses packages)"
+   ),
+   PARSE_FUN(
+      "error_file",	4|NEED_FUNCTION_ARG,	error_file_fun,
+      "=FILE\nwrite the HTTP status code here"
+   ),
+#if defined(EXEC_LINKS) || defined(EXEC_SCRIPTS)
+#ifndef NEVER_ALLOW_REMOTE_EXEC
+   PARSE_FUN(
+      "exec",		4|FUNCTION_ARG,		exec_fun,
+      "enable local program execution"
+   ),
+#endif
+#endif /* EXEC_LINKS || EXEC_SCRIPTS */
+#ifdef VMS
+   PARSE_SET(
+      "fileversions",	4|SET_ARG,		HTVMSFileVersions,
+      "include all versions of files in local VMS directory\nlistings"
+   ),
+#endif
+#ifdef LY_FIND_LEAKS
+   PARSE_SET(
+      "find_leaks",	4|TOGGLE_ARG,		LYfind_leaks,
+      "toggles memory-leak checking"
+   ),
+#endif
+   PARSE_SET(
+      "force_empty_hrefless_a",	4|SET_ARG,	force_empty_hrefless_a,
+      "\nforce HREF-less 'A' elements to be empty (close them as\n\
+soon as they are seen)"
+   ),
+   PARSE_SET(
+      "force_html",	4|SET_ARG,		LYforce_HTML_mode,
+      "forces the first document to be interpreted as HTML"
+   ),
+   PARSE_SET(
+      "force_secure",	4|TOGGLE_ARG,		LYForceSSLCookiesSecure,
+      "toggles forcing of the secure flag for SSL cookies"
+   ),
+#if !defined(NO_OPTION_FORMS) && !defined(NO_OPTION_MENU)
+   PARSE_SET(
+      "forms_options",	4|TOGGLE_ARG,		LYUseFormsOptions,
+      "toggles forms-based vs old-style options menu"
+   ),
+#endif
+   PARSE_SET(
+      "from",		4|TOGGLE_ARG,		LYNoFromHeader,
+      "toggle transmission of From headers"
+   ),
+#ifndef DISABLE_FTP
+   PARSE_SET(
+      "ftp",		4|UNSET_ARG,		ftp_ok,
+      "disable ftp access"
+   ),
+#endif
+   PARSE_FUN(
+      "get_data",	2|FUNCTION_ARG,		get_data_fun,
+      "user data for get forms, read from stdin,\nterminated by '---' on a line"
+   ),
+   PARSE_SET(
+      "head",		4|SET_ARG,		HEAD_request,
+      "send a HEAD request"
+   ),
+   PARSE_FUN(
+      "help",		4|FUNCTION_ARG,		help_fun,
+      "print this usage message"
+   ),
+   PARSE_FUN(
+      "hiddenlinks",	4|NEED_FUNCTION_ARG,	hiddenlinks_fun,
+      "=[option]\nhidden links: options are merge, listonly, or ignore"
+   ),
+   PARSE_SET(
+      "historical",	4|TOGGLE_ARG,		historical_comments,
+      "toggles use of '>' or '-->' as terminator for comments"
+   ),
+   PARSE_FUN(
+      "homepage",	4|NEED_FUNCTION_ARG,	homepage_fun,
+      "=URL\nset homepage separate from start page"
+   ),
+   PARSE_SET(
+      "image_links",	4|TOGGLE_ARG,		clickable_images,
+      "toggles inclusion of links for all images"
+   ),
+   PARSE_STR(
+      "index",		4|NEED_LYSTRING_ARG,	indexfile,
+      "=URL\nset the default index file to URL"
+   ),
+   PARSE_SET(
+      "ismap",		4|TOGGLE_ARG,		LYNoISMAPifUSEMAP,
+      "toggles inclusion of ISMAP links when client-side\nMAPs are present"
+   ),
+#ifdef USE_JUSTIFY_ELTS
+   PARSE_SET(
+      "justify",	4|SET_ARG,		ok_justify,
+      "do justification of text"
+   ),
+#endif
+   PARSE_INT(
+      "link",		4|NEED_INT_ARG,		crawl_count,
+      "=NUMBER\nstarting count for lnk#.dat files produced by -crawl"
+   ),
+   PARSE_SET(
+      "listonly",	4|TOGGLE_ARG,		dump_links_only,
+      "with -dump, forces it to show only the list of links"
+   ),
+   PARSE_SET(
+      "localhost",	4|SET_ARG,		local_host_only,
+      "disable URLs that point to remote hosts"
+   ),
+#if defined(EXEC_LINKS) || defined(EXEC_SCRIPTS)
+   PARSE_SET(
+      "locexec",	4|SET_ARG,		local_exec_on_local_files,
+      "enable local program execution from local files only"
+   ),
+#endif /* EXEC_LINKS || EXEC_SCRIPTS */
+#if defined(USE_COLOR_STYLE)
+   PARSE_STR(
+      "lss",		2|NEED_LYSTRING_ARG,	lynx_lss_file2,
+      "=FILENAME\nspecifies a lynx.lss file other than the default"
+   ),
+#endif
+   PARSE_FUN(
+      "mime_header",	4|FUNCTION_ARG,		mime_header_fun,
+      "include mime headers and force source dump"
+   ),
+   PARSE_SET(
+      "minimal",	4|TOGGLE_ARG,		minimal_comments,
+      "toggles minimal versus valid comment parsing"
+   ),
+#ifdef EXP_NESTED_TABLES
+   PARSE_SET(
+      "nested_tables",	4|TOGGLE_ARG,		nested_tables,
+      "toggles nested-tables logic"
+   ),
+#endif
+#ifndef DISABLE_NEWS
+   PARSE_FUN(
+      "newschunksize",	4|NEED_FUNCTION_ARG,	newschunksize_fun,
+      "=NUMBER\nnumber of articles in chunked news listings"
+   ),
+   PARSE_FUN(
+      "newsmaxchunk",	4|NEED_FUNCTION_ARG,	newsmaxchunk_fun,
+      "=NUMBER\nmaximum news articles in listings before chunking"
+   ),
+#endif
+#if USE_BLAT_MAILER
+   PARSE_SET(
+      "noblat",		4|TOGGLE_ARG,		mail_is_blat,
+      "select mail tool (`BLAT' ==> `sendmail')"
+   ),
+#endif
+   PARSE_FUN(
+      "nobold",		4|FUNCTION_ARG,		nobold_fun,
+      "disable bold video-attribute"
+   ),
+   PARSE_FUN(
+      "nobrowse",	4|FUNCTION_ARG,		nobrowse_fun,
+      "disable directory browsing"
+   ),
+   PARSE_SET(
+      "nocc",		4|SET_ARG,		LYNoCc,
+      "disable Cc: prompts for self copies of mailings"
+   ),
+   PARSE_FUN(
+      "nocolor",	4|FUNCTION_ARG,		nocolor_fun,
+      "turn off color support"
+   ),
+#if defined(EXEC_LINKS) || defined(EXEC_SCRIPTS)
+   PARSE_SET(
+      "noexec",		4|UNSET_ARG,		local_exec,
+      "disable local program execution (DEFAULT)"
+   ),
+#endif /* EXEC_LINKS || EXEC_SCRIPTS */
+   PARSE_SET(
+      "nofilereferer",	4|SET_ARG,		no_filereferer,
+      "disable transmission of Referer headers for file URLs"
+   ),
+   PARSE_SET(
+      "nolist",		4|SET_ARG,		no_list,
+      "disable the link list feature in dumps"
+   ),
+   PARSE_SET(
+      "nolog",		4|UNSET_ARG,		error_logging,
+      "disable mailing of error messages to document owners"
+   ),
+   PARSE_SET(
+      "nomargins",	4|SET_ARG,		no_margins,
+      "disable the right/left margins in the default\nstyle-sheet"
+   ),
+   PARSE_FUN(
+      "nomore",		4|FUNCTION_ARG,		nomore_fun,
+      "disable -more- string in statusline messages"
+   ),
+#if defined(HAVE_SIGACTION) && defined(SIGWINCH)
+   PARSE_SET(
+      "nonrestarting_sigwinch", 4|SET_ARG,	LYNonRestartingSIGWINCH,
+      "\nmake window size change handler non-restarting"
+   ),
+#endif /* HAVE_SIGACTION */
+   PARSE_SET(
+      "nonumbers",	4|SET_ARG,		no_numbers,
+      "disable the link/form numbering feature in dumps"
+   ),
+   PARSE_FUN(
+      "nopause",	4|FUNCTION_ARG,		nopause_fun,
+      "disable forced pauses for statusline messages"
+   ),
+   PARSE_SET(
+      "noprint",	4|SET_ARG,		no_print,
+      "disable some print functions, like -restrictions=print"
+   ),
+   PARSE_SET(
+      "noredir",	4|SET_ARG,		no_url_redirection,
+      "don't follow Location: redirection"
+   ),
+   PARSE_SET(
+      "noreferer",	4|SET_ARG,		LYNoRefererHeader,
+      "disable transmission of Referer headers"
+   ),
+   PARSE_FUN(
+      "noreverse",	4|FUNCTION_ARG,		noreverse_fun,
+      "disable reverse video-attribute"
+   ),
+#ifdef SOCKS
+   PARSE_SET(
+      "nosocks",	2|UNSET_ARG,		socks_flag,
+      "don't use SOCKS proxy for this session"
+   ),
+#endif
+   PARSE_SET(
+      "nostatus",	4|SET_ARG,		no_statusline,
+      "disable the miscellaneous information messages"
+   ),
+   PARSE_SET(
+      "notitle",	4|SET_ARG,		no_title,
+      "disable the title at the top of each page"
+   ),
+   PARSE_FUN(
+      "nounderline",	4|FUNCTION_ARG,		nounderline_fun,
+      "disable underline video-attribute"
+   ),
+#ifdef MISC_EXP
+   PARSE_FUN(
+      "nozap",		4|FUNCTION_ARG,		nozap_fun,
+      "=DURATION (\"initially\" or \"full\") disable checks for 'z' key"
+   ),
+#endif
+   PARSE_SET(
+      "number_fields",	4|SET_ARG,		number_fields,
+      "force numbering of links as well as form input fields"
+   ),
+   PARSE_SET(
+      "number_links",	4|SET_ARG,		number_links,
+      "force numbering of links"
+   ),
+#ifdef DISP_PARTIAL
+   PARSE_SET(
+      "partial",	4|TOGGLE_ARG,		display_partial_flag,
+      "toggles display partial pages while downloading"
+   ),
+   PARSE_INT(
+      "partial_thres",	4|NEED_INT_ARG,		partial_threshold,
+      "[=NUMBER]\nnumber of lines to render before repainting display\n\
+with partial-display logic"
+   ),
+#endif
+#ifndef DISABLE_FTP
+   PARSE_SET(
+      "passive-ftp",	4|TOGGLE_ARG,		ftp_passive,
+      "toggles passive ftp connection"
+   ),
+#endif
+   PARSE_FUN(
+      "pauth",		4|NEED_FUNCTION_ARG,	pauth_fun,
+      "=id:pw\nauthentication information for protected proxy server"
+   ),
+   PARSE_SET(
+      "popup",		4|UNSET_ARG,		LYUseDefSelPop,
+      "toggles handling of single-choice SELECT options via\n\
+popup windows or as lists of radio buttons"
+   ),
+   PARSE_FUN(
+      "post_data",	2|FUNCTION_ARG,		post_data_fun,
+      "user data for post forms, read from stdin,\n\
+terminated by '---' on a line"
+   ),
+   PARSE_SET(
+      "preparsed",	4|SET_ARG,		LYPreparsedSource,
+      "show parsed text/html with -source and in source view\n\
+to visualize how lynx behaves with invalid HTML"
+   ),
+#ifdef USE_PRETTYSRC
+   PARSE_SET(
+      "prettysrc",	4|SET_ARG,		LYpsrc,
+      "do syntax highlighting and hyperlink handling in source\nview"
+   ),
+#endif
+   PARSE_SET(
+      "print",		4|UNSET_ARG,		no_print,
+      "enable print functions (DEFAULT), opposite of -noprint"
+   ),
+   PARSE_SET(
+      "pseudo_inlines", 4|TOGGLE_ARG,		pseudo_inline_alts,
+      "toggles pseudo-ALTs for inlines with no ALT string"
+   ),
+   PARSE_SET(
+      "raw",		4|UNSET_ARG,		LYUseDefaultRawMode,
+      "toggles default setting of 8-bit character translations\n\
+or CJK mode for the startup character set"
+   ),
+   PARSE_SET(
+      "realm",		4|SET_ARG,		check_realm,
+      "restricts access to URLs in the starting realm"
+   ),
+   PARSE_INT(
+      "read_timeout",	4|NEED_INT_ARG,		reading_timeout,
+      "=N\nset the N-second read-timeout"
+   ),
+   PARSE_SET(
+      "reload",		4|SET_ARG,		reloading,
+      "flushes the cache on a proxy server\n(only the first document affected)"
+   ),
+   PARSE_FUN(
+      "restrictions",	4|FUNCTION_ARG,		restrictions_fun,
+      "=[options]\nuse -restrictions to see list"
+   ),
+   PARSE_SET(
+      "resubmit_posts", 4|TOGGLE_ARG,		LYresubmit_posts,
+      "toggles forced resubmissions (no-cache) of forms with\n\
+method POST when the documents they returned are sought\n\
+with the PREV_DOC command or from the History List"
+   ),
+   PARSE_SET(
+      "rlogin",		4|UNSET_ARG,		rlogin_ok,
+      "disable rlogins"
+   ),
+#if defined(PDCURSES) && defined(PDC_BUILD) && PDC_BUILD >= 2401
+   PARSE_FUN(
+      "scrsize",	4|NEED_FUNCTION_ARG,	scrsize_fun,
+      "=width,height\nsize of window"
+   ),
+#endif
+#ifdef USE_SCROLLBAR
+   PARSE_SET(
+      "scrollbar",	4|TOGGLE_ARG,		LYShowScrollbar,
+      "toggles showing scrollbar"
+   ),
+   PARSE_SET(
+      "scrollbar_arrow", 4|TOGGLE_ARG,		LYsb_arrow,
+      "toggles showing arrows at ends of the scrollbar"
+   ),
+#endif
+   PARSE_FUN(
+      "selective",	4|FUNCTION_ARG,		selective_fun,
+      "require .www_browsable files to browse directories"
+   ),
+#ifdef USE_SESSIONS
+   PARSE_STR(
+      "session",	2|NEED_LYSTRING_ARG,	session_file,
+      "=FILENAME\nresumes from specified file on startup and\n\
+saves session to that file on exit"
+   ),
+   PARSE_STR(
+      "sessionin",	2|NEED_LYSTRING_ARG,	sessionin_file,
+      "=FILENAME\nresumes session from specified file"
+   ),
+   PARSE_STR(
+      "sessionout",	2|NEED_LYSTRING_ARG,	sessionout_file,
+      "=FILENAME\nsaves session to specified file"
+   ),
+#endif /* USE_SESSIONS */
+   PARSE_SET(
+      "short_url",	4|SET_ARG,		long_url_ok,
+      "enables examination of beginning and end of long URL in\nstatus line"
+   ),
+   PARSE_SET(
+      "show_cfg",	1|SET_ARG,		show_cfg,
+      "Show `LYNX.CFG' setting"
+   ),
+   PARSE_SET(
+      "show_cursor",	4|TOGGLE_ARG,		LYUseDefShoCur,
+      "toggles hiding of the cursor in the lower right corner"
+   ),
+#ifdef USE_READPROGRESS
+   PARSE_SET(
+      "show_rate",	4|TOGGLE_ARG,		LYShowTransferRate,
+      "toggles display of transfer rate"
+   ),
+#endif
+   PARSE_SET(
+      "soft_dquotes",	4|TOGGLE_ARG,		soft_dquotes,
+      "toggles emulation of the old Netscape and Mosaic\n\
+bug which treated '>' as a co-terminator for\ndouble-quotes and tags"
+   ),
+   PARSE_FUN(
+      "source",		4|FUNCTION_ARG,		source_fun,
+      "dump the source of the first file to stdout and exit"
+   ),
+   PARSE_SET(
+      "stack_dump",	4|SET_ARG,		stack_dump,
+      "disable SIGINT cleanup handler"
+   ),
+   PARSE_SET(
+      "startfile_ok",	4|SET_ARG,		startfile_ok,
+      "allow non-http startfile and homepage with -validate"
+   ),
+   PARSE_SET(
+      "stderr",		4|SET_ARG,		dump_to_stderr,
+      "write warning messages to standard error when -dump\nor -source is used"
+   ),
+   PARSE_SET(
+      "stdin",		4|SET_ARG,		startfile_stdin,
+      "read startfile from standard input"
+   ),
+#ifdef SYSLOG_REQUESTED_URLS
+   PARSE_STR(
+      "syslog",		4|NEED_LYSTRING_ARG,	syslog_txt,
+      "=text\ninformation for syslog call"
+   ),
+   PARSE_SET(
+      "syslog-urls",	4|SET_ARG,		syslog_requested_urls,
+      "log requested URLs with syslog"
+   ),
+#endif
+   PARSE_SET(
+      "tagsoup",	4|SET_ARG,		DTD_recovery,
+      "use TagSoup rather than SortaSGML parser"
+   ),
+   PARSE_SET(
+      "telnet",		4|UNSET_ARG,		telnet_ok,
+      "disable telnets"
+   ),
+   PARSE_STR(
+      "term",		4|NEED_STRING_ARG,	terminal,
+      "=TERM\nset terminal type to TERM"
+   ),
+#ifdef _WINDOWS
+   PARSE_INT(
+      "timeout",	4|INT_ARG,		lynx_timeout,
+      "=NUMBER\nset TCP/IP timeout"
+   ),
+#endif
+   PARSE_SET(
+      "tlog",		2|TOGGLE_ARG,		LYUseTraceLog,
+      "toggles use of a Lynx Trace Log for the current\nsession"
+   ),
+#ifdef TEXTFIELDS_MAY_NEED_ACTIVATION
+   PARSE_SET(
+      "tna",		4|SET_ARG,		textfields_activation_option,
+      "turn on \"Textfields Need Activation\" mode"
+   ),
+#endif
+#ifndef NO_LYNX_TRACE
+   PARSE_SET(
+      "trace",		1|SET_ARG,		WWW_TraceFlag,
+      "turns on Lynx trace mode"
+   ),
+   PARSE_INT(
+      "trace_mask",	1|INT_ARG,		WWW_TraceMask,
+      "customize Lynx trace mode"
+   ),
+#endif
+   PARSE_FUN(
+      "traversal",	4|FUNCTION_ARG,		traversal_fun,
+      "traverse all http links derived from startfile"
+   ),
+   PARSE_SET(
+      "trim_input_fields", 2|SET_ARG,		LYtrimInputFields,
+      "\ntrim input text/textarea fields in forms"
+   ),
+   PARSE_SET(
+      "underline_links",4|TOGGLE_ARG,		LYUnderlineLinks,
+      "toggles use of underline/bold attribute for links"
+   ),
+   PARSE_SET(
+      "underscore",	4|TOGGLE_ARG,		use_underscore,
+      "toggles use of _underline_ format in dumps"
+   ),
+#if defined(USE_MOUSE)
+   PARSE_SET(
+      "use_mouse",	4|SET_ARG,		LYUseMouse,
+      "turn on mouse support"
+   ),
+#endif
+   PARSE_STR(
+      "useragent",	4|NEED_LYSTRING_ARG,	LYUserAgent,
+      "=Name\nset alternate Lynx User-Agent header"
+   ),
+   PARSE_SET(
+      "validate",	2|SET_ARG,		LYValidate,
+      "accept only http URLs (meant for validation)\n\
+implies more restrictions than -anonymous, but\n\
+goto is allowed for http and https"
+   ),
+   PARSE_SET(
+      "verbose",	4|TOGGLE_ARG,		verbose_img,
+      "toggles [LINK], [IMAGE] and [INLINE] comments\n\
+with filenames of these images"
+   ),
+   PARSE_FUN(
+      "version",	1|FUNCTION_ARG,		version_fun,
+      "print Lynx version information"
+   ),
+   PARSE_SET(
+      "vikeys",		4|SET_ARG,		vi_keys,
+      "enable vi-like key movement"
+   ),
+#ifdef __DJGPP__
+   PARSE_SET(
+      "wdebug",		4|TOGGLE_ARG,		watt_debug,
+      "enables Waterloo tcp/ip packet debug. Prints to watt\ndebugfile"
+  ),
+#endif /* __DJGPP__ */
+   PARSE_FUN(
+      "width",		4|NEED_FUNCTION_ARG,	width_fun,
+      "=NUMBER\nscreen width for formatting of dumps (default is 80)"
+   ),
+#ifndef NO_DUMP_WITH_BACKSPACES
+   PARSE_SET(
+      "with_backspaces", 4|SET_ARG,		with_backspaces,
+      "emit backspaces in output if -dumping or -crawling\n(like 'man' does)"
+   ),
+#endif
+   PARSE_SET(
+      "xhtml-parsing",	4|SET_ARG,		LYxhtml_parsing,
+      "enable XHTML 1.0 parsing"
+   ),
+   PARSE_NIL
+};
+/* *INDENT-ON* */
+
+static void print_help_strings(const char *name,
+			       const char *help,
+			       const char *value,
+			       BOOLEAN option)
+{
+    int pad;
+    int c;
+    int first;
+    int field_width = 20;
+
+    pad = field_width - (2 + option + (int) strlen(name));
+
+    fprintf(stdout, "  %s%s", option ? "-" : "", name);
+
+    if (*help != '=') {
+	pad--;
+	while (pad > 0) {
+	    fputc(' ', stdout);
+	    pad--;
+	}
+	fputc(' ', stdout);	/* at least one space */
+	first = 0;
+    } else {
+	first = pad;
+    }
+
+    if (strchr(help, '\n') == 0) {
+	fprintf(stdout, "%s", help);
+    } else {
+	while ((c = *help) != 0) {
+	    if (c == '\n') {
+		if ((pad = --first) < 0) {
+		    pad = field_width;
+		} else {
+		    c = ' ';
+		}
+		fputc(c, stdout);
+		while (pad--)
+		    fputc(' ', stdout);
+	    } else {
+		fputc(c, stdout);
+	    }
+	    help++;
+	    first--;
+	}
+    }
+    if (value)
+	printf(" (%s)", value);
+    fputc('\n', stdout);
+}
+
+static void print_help_and_exit(int exit_status)
+{
+    Config_Type *p;
+
+    if (pgm == NULL)
+	pgm = "lynx";
+
+    SetOutputMode(O_TEXT);
+
+    fprintf(stdout, gettext("USAGE: %s [options] [file]\n"), pgm);
+    fprintf(stdout, gettext("Options are:\n"));
+#ifdef VMS
+    print_help_strings("",
+		       "receive the arguments from stdin (enclose\n\
+in double-quotes (\"-\") on VMS)", NULL, TRUE);
+#else
+    print_help_strings("", "receive options and arguments from stdin", NULL, TRUE);
+#endif /* VMS */
+
+    for (p = Arg_Table; p->name != 0; p++) {
+	char temp[LINESIZE], *value = temp;
+	ParseUnionPtr q = ParseUnionOf(p);
+
+	switch (p->type & ARG_TYPE_MASK) {
+	case TOGGLE_ARG:
+	case SET_ARG:
+	    strcpy(temp, *(q->set_value) ? "on" : "off");
+	    break;
+	case UNSET_ARG:
+	    strcpy(temp, *(q->set_value) ? "off" : "on");
+	    break;
+	case INT_ARG:
+	    sprintf(temp, "%d", *(q->int_value));
+	    break;
+	case TIME_ARG:
+	    sprintf(temp, SECS_FMT, (double) Secs2SECS(*(q->int_value)));
+	    break;
+	case STRING_ARG:
+	    if ((value = *(q->str_value)) != 0
+		&& !*value)
+		value = 0;
+	    break;
+	default:
+	    value = 0;
+	    break;
+	}
+	print_help_strings(p->name, p->help_string, value, TRUE);
+    }
+
+    SetOutputMode(O_BINARY);
+
+    exit_immediately(exit_status);
+}
+
+/*
+ * This function performs a string comparison on two strings a and b.  a is
+ * assumed to be an ordinary null terminated string, but b may be terminated
+ * by an '=', '+' or '-' character.  If terminated by '=', *c will be pointed
+ * to the character following the '='.  If terminated by '+' or '-', *c will
+ * be pointed to that character.  (+/- added for toggle processing - BL.)
+ * If a and b match, it returns 1.  Otherwise 0 is returned.
+ */
+static int arg_eqs_parse(const char *a,
+			 char *b,
+			 char **c)
+{
+    int result = -1;
+
+    *c = NULL;
+    while (result < 0) {
+	if ((*a != *b)
+	    || (*a == 0)
+	    || (*b == 0)) {
+	    if (*a == 0) {
+		switch (*b) {
+		case '\t':	/* embedded blank when reading stdin */
+		case ' ':
+		    *c = LYSkipBlanks(b);
+		    result = 1;
+		    break;
+		case '=':
+		case ':':
+		    *c = b + 1;
+		    result = 1;
+		    break;
+		case '-':
+#if OPTNAME_ALLOW_DASHES
+		    if (isalpha(UCH(b[1]))) {
+			result = 0;
+			break;
+		    }
+#endif
+		    /* FALLTHRU */
+		case '+':
+		    *c = b;
+		    result = 1;
+		    break;
+		case 0:
+		    result = 1;
+		    break;
+		default:
+		    result = 0;
+		    break;
+		}
+	    } else {
+#if OPTNAME_ALLOW_DASHES
+		if (!(*a == '_' && *b == '-'))
+#endif
+		    result = 0;
+	    }
+	}
+	a++;
+	b++;
+    }
+    return result;
+}
+
+#define is_true(s)  (*s == '1' || *s == '+' || !strcasecomp(s, "on")  || !strcasecomp(s, "true"))
+#define is_false(s) (*s == '0' || *s == '-' || !strcasecomp(s, "off") || !strcasecomp(s, "false"))
+
+/*
+ * Parse an option.
+ *	argv[] points to the beginning of the unprocessed options.
+ *	mask is used to select certain options which must be processed
+ *		before others.
+ *	countp (if nonnull) points to an index into argv[], which is updated
+ *		to reflect option values which are also parsed.
+ */
+static BOOL parse_arg(char **argv,
+		      unsigned mask,
+		      int *countp)
+{
+    Config_Type *p;
+    char *arg_name;
+
+#if EXTENDED_STARTFILE_RECALL
+    static BOOLEAN no_options_further = FALSE;	/* set to TRUE after '--' argument */
+    static int nof_index = 0;	/* set the index of -- argument */
+#endif
+
+    arg_name = argv[0];
+    CTRACE((tfp, "parse_arg(arg_name=%s, mask=%u, count=%d)\n",
+	    arg_name, mask, countp ? *countp : -1));
+
+#if EXTENDED_STARTFILE_RECALL
+    if (mask == (unsigned) ((countp != 0) ? 0 : 1)) {
+	no_options_further = FALSE;
+	/* want to reset nonoption when beginning scan for --stdin */
+	if (nonoption != 0) {
+	    FREE(nonoption);
+	}
+    }
+#endif
+
+    /*
+     * Check for a command line startfile.  - FM
+     */
+    if (*arg_name != '-'
+#if EXTENDED_OPTION_LOGIC
+	|| (no_options_further == TRUE && nof_index < (*countp))
+#endif
+	) {
+#if EXTENDED_STARTFILE_RECALL
+	/*
+	 * On the last pass (mask==4), check for cases where we may want to
+	 * provide G)oto history for multiple startfiles.
+	 */
+	if (mask == 4) {
+	    if (nonoption != 0) {
+		LYEnsureAbsoluteURL(&nonoption, "NONOPTION", FALSE);
+		HTAddGotoURL(nonoption);
+		FREE(nonoption);
+	    }
+	    StrAllocCopy(nonoption, arg_name);
+	}
+#endif
+	StrAllocCopy(startfile, arg_name);
+	LYEscapeStartfile(&startfile);
+#ifdef _WINDOWS			/* 1998/01/14 (Wed) 20:11:17 */
+	HTUnEscape(startfile);
+	{
+	    char *q = startfile;
+
+	    while (*q++) {
+		if (*q == '|')
+		    *q = ':';
+	    }
+	}
+#endif
+	CTRACE((tfp, "parse_arg startfile:%s\n", startfile));
+	return (BOOL) (countp != 0);
+    }
+#if EXTENDED_OPTION_LOGIC
+    if (strcmp(arg_name, "--") == 0) {
+	no_options_further = TRUE;
+	nof_index = countp ? *countp : -1;
+	return TRUE;
+    }
+#endif
+
+    /* lose the first '-' character */
+    arg_name++;
+
+    /*
+     * Skip any lone "-" arguments, because we've loaded the stdin input into
+     * an HTList structure for special handling.  - FM
+     */
+    if (*arg_name == 0)
+	return TRUE;
+
+    /* allow GNU-style options with -- prefix */
+    if (*arg_name == '-')
+	++arg_name;
+
+    CTRACE((tfp, "parse_arg lookup(%s)\n", arg_name));
+
+    p = Arg_Table;
+    while (p->name != 0) {
+	ParseUnionPtr q = ParseUnionOf(p);
+	ParseFunc fun;
+	char *next_arg = NULL;
+	char *temp_ptr = NULL;
+
+	if ((p->name[0] != *arg_name)
+	    || (0 == arg_eqs_parse(p->name, arg_name, &next_arg))) {
+	    p++;
+	    continue;
+	}
+
+	if (p->type & NEED_NEXT_ARG) {
+	    if (next_arg == 0) {
+		next_arg = argv[1];
+		if ((countp != 0) && (next_arg != 0))
+		    (*countp)++;
+	    }
+	    CTRACE((tfp, "...arg:%s\n", NONNULL(next_arg)));
+	}
+
+	/* ignore option if it's not our turn */
+	if ((p->type & mask) == 0) {
+	    CTRACE((tfp, "...skip (mask %u/%d)\n", mask, p->type & 7));
+	    return FALSE;
+	}
+
+	switch (p->type & ARG_TYPE_MASK) {
+	case TOGGLE_ARG:	/* FALLTHRU */
+	case SET_ARG:		/* FALLTHRU */
+	case UNSET_ARG:
+	    if (q->set_value != 0) {
+		if (next_arg == 0) {
+		    switch (p->type & ARG_TYPE_MASK) {
+		    case TOGGLE_ARG:
+			*(q->set_value) = (BOOL) !(*(q->set_value));
+			break;
+		    case SET_ARG:
+			*(q->set_value) = TRUE;
+			break;
+		    case UNSET_ARG:
+			*(q->set_value) = FALSE;
+			break;
+		    }
+		} else if (is_true(next_arg)) {
+		    *(q->set_value) = TRUE;
+		} else if (is_false(next_arg)) {
+		    *(q->set_value) = FALSE;
+		}
+		/* deliberately ignore anything else - BL */
+	    }
+	    break;
+
+	case FUNCTION_ARG:
+	    fun = q->fun_value;
+	    if (0 != fun) {
+		if (-1 == (*fun) (next_arg)) {
+		}
+	    }
+	    break;
+
+	case LYSTRING_ARG:
+	    if ((q->str_value != 0) && (next_arg != 0))
+		StrAllocCopy(*(q->str_value), next_arg);
+	    break;
+
+	case INT_ARG:
+	    if ((q->int_value != 0) && (next_arg != 0))
+		*(q->int_value) = strtol(next_arg, &temp_ptr, 0);
+	    break;
+
+	case TIME_ARG:
+	    if ((q->int_value != 0) && (next_arg != 0)) {
+		float ival;
+
+		if (1 == LYscanFloat(next_arg, &ival)) {
+		    *(q->int_value) = (int) SECS2Secs(ival);
+		}
+	    }
+	    break;
+
+	case STRING_ARG:
+	    if ((q->str_value != 0) && (next_arg != 0))
+		*(q->str_value) = next_arg;
+	    break;
+	}
+
+	Old_DTD = DTD_recovery;	/* BOOL != int */
+	return TRUE;
+    }
+
+    if (pgm == 0)
+	pgm = "LYNX";
+
+    fprintf(stderr, gettext("%s: Invalid Option: %s\n"), pgm, argv[0]);
+    print_help_and_exit(-1);
+    return FALSE;
+}
+
+#ifndef VMS
+static void FatalProblem(int sig)
+{
+    /*
+     * Ignore further interrupts.  - mhc:  11/2/91
+     */
+#ifndef NOSIGHUP
+    (void) signal(SIGHUP, SIG_IGN);
+#endif /* NOSIGHUP */
+    (void) signal(SIGTERM, SIG_IGN);
+    (void) signal(SIGINT, SIG_IGN);
+#ifndef __linux__
+#ifdef SIGBUS
+    (void) signal(SIGBUS, SIG_IGN);
+#endif /* ! SIGBUS */
+#endif /* !__linux__ */
+    (void) signal(SIGSEGV, SIG_IGN);
+    (void) signal(SIGILL, SIG_IGN);
+
+    /*
+     * Flush all messages.  - FM
+     */
+    fflush(stderr);
+    fflush(stdout);
+
+    /*
+     * Deal with curses, if on, and clean up.  - FM
+     */
+    if (LYOutOfMemory && LYCursesON) {
+	LYSleepAlert();
+    }
+    cleanup_sig(0);
+#ifndef __linux__
+#ifdef SIGBUS
+    signal(SIGBUS, SIG_DFL);
+#endif /* SIGBUS */
+#endif /* !__linux__ */
+    signal(SIGSEGV, SIG_DFL);
+    signal(SIGILL, SIG_DFL);
+
+    /*
+     * Issue appropriate messages and abort or exit.  - FM
+     */
+    if (LYOutOfMemory == FALSE) {
+	fprintf(stderr, "\r\n\
+A Fatal error has occurred in %s Ver. %s\r\n", LYNX_NAME, LYNX_VERSION);
+
+	fprintf(stderr, "\r\n\
+Please notify your system administrator to confirm a bug, and\r\n\
+if confirmed, to notify the lynx-dev list.  Bug reports should\r\n\
+have concise descriptions of the command and/or URL which causes\r\n\
+the problem, the operating system name with version number, the\r\n\
+TCPIP implementation, and any other relevant information.\r\n");
+
+	if (!(sig == 0 && LYNoCore)) {
+	    fprintf(stderr, "\r\n\
+Do NOT mail the core file if one was generated.\r\n");
+	}
+	if (sig != 0) {
+	    fprintf(stderr, "\r\n\
+Lynx now exiting with signal:  %d\r\n\r\n", sig);
+#ifdef WIN_EX			/* 1998/08/09 (Sun) 09:58:25 */
+	    {
+		char *msg;
+
+		switch (sig) {
+		case SIGABRT:
+		    msg = "SIGABRT";
+		    break;
+		case SIGFPE:
+		    msg = "SIGFPE";
+		    break;
+		case SIGILL:
+		    msg = "SIGILL";
+		    break;
+		case SIGSEGV:
+		    msg = "SIGSEGV";
+		    break;
+		default:
+		    msg = "Not-def";
+		    break;
+		}
+		fprintf(stderr, "signal code = %s\n", msg);
+	    }
+#endif
+	}
+
+	/*
+	 * Exit and possibly dump core.
+	 */
+	if (LYNoCore) {
+	    exit_immediately(EXIT_FAILURE);
+	}
+	abort();
+
+    } else {
+	LYOutOfMemory = FALSE;
+	printf("\r\n%s\r\n\r\n", MEMORY_EXHAUSTED_ABORT);
+	fflush(stdout);
+
+	/*
+	 * Exit without dumping core.
+	 */
+	exit_immediately(EXIT_FAILURE);
+    }
+}
+#endif /* !VMS */
-- 
cgit 1.4.1-2-gfad0