home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / lynx2.8.1dev.10.tar.gz / lynx2.8.1dev.10.tar / lynx2-8 / src / LYReadCFG.c < prev    next >
C/C++ Source or Header  |  1998-05-10  |  30KB  |  1,139 lines

  1. #include <HTUtils.h>
  2. #include <tcp.h>
  3. #include <HTFile.h>
  4. #include <UCMap.h>
  5.  
  6. #include <LYUtils.h>
  7. #include <LYStrings.h>
  8. #include <LYStructs.h>
  9. #include <LYGlobalDefs.h>
  10. #include <LYCharSets.h>
  11. #include <LYKeymap.h>
  12. #include <LYJump.h>
  13. #include <LYGetFile.h>
  14. #include <LYCgi.h>
  15. #include <LYCurses.h>
  16. #include <LYSignal.h>
  17. #include <LYBookmark.h>
  18. #include <LYReadCFG.h>
  19.  
  20. #ifdef DIRED_SUPPORT
  21. #include <LYLocal.h>
  22. #endif /* DIRED_SUPPORT */
  23.  
  24. #include <LYexit.h>
  25. #include <LYLeaks.h>
  26.  
  27. #define FREE(x) if (x) {free(x); x = NULL;}
  28.  
  29. extern int HTNewsMaxChunk;  /* Max news articles before chunking (HTNews.c) */
  30. extern int HTNewsChunkSize; /* Number of news articles per chunk (HTNews.c) */
  31.  
  32. PUBLIC BOOLEAN have_read_cfg=FALSE;
  33. PUBLIC BOOLEAN LYUseNoviceLineTwo=TRUE;
  34.  
  35. #ifdef VMS
  36. #define DISPLAY "DECW$DISPLAY"
  37. #else
  38. #define DISPLAY "DISPLAY"
  39. #endif /* VMS */
  40.  
  41. /*
  42.  *  Translate a TRUE/FALSE field in a string buffer.
  43.  */
  44. PRIVATE int is_true ARGS1(
  45.     char *, string)
  46. {
  47.     if (!strncasecomp(string,"TRUE",4))
  48.     return(TRUE);
  49.     else
  50.     return(FALSE);
  51. }
  52.  
  53. /*
  54.  *  Find an unescaped colon in a string buffer.
  55.  */
  56. PRIVATE char *find_colon ARGS1(
  57.     char *, buffer)
  58. {
  59.     char ch, *buf = buffer;
  60.  
  61.     if (buf == NULL)
  62.     return NULL;
  63.  
  64.     while ((ch = *buf) != 0) {
  65.     if (ch == ':')
  66.         return buf;
  67.     if (ch == '\\') {
  68.         buf++;
  69.         if (*buf == 0)
  70.         break;
  71.     }
  72.     buf++;
  73.     }
  74.     return NULL;
  75. }
  76.  
  77. /*
  78.  *  Function for freeing the DOWNLOADER and UPLOADER menus list. - FM
  79.  */
  80. PRIVATE void free_item_list NOARGS
  81. {
  82.     lynx_html_item_type *cur;
  83.     lynx_html_item_type *next;
  84.  
  85.     cur = downloaders;
  86.     while (cur) {
  87.     next = cur->next;
  88.     FREE(cur->name);
  89.     FREE(cur->command);
  90.     FREE(cur);
  91.     cur = next;
  92.     }
  93.     downloaders = NULL;
  94.  
  95. #ifdef DIRED_SUPPORT
  96.     cur = uploaders;
  97.     while (cur) {
  98.     next = cur->next;
  99.     FREE(cur->name);
  100.     FREE(cur->command);
  101.     FREE(cur);
  102.     cur = next;
  103.     }
  104.     uploaders = NULL;
  105. #endif /* DIRED_SUPPORT */
  106.  
  107. #ifdef USE_EXTERNALS
  108.     cur = externals;
  109.     while (cur) {
  110.     next = cur->next;
  111.     FREE(cur->name);
  112.     FREE(cur->command);
  113.     FREE(cur);
  114.     cur = next;
  115.     }
  116.     externals = NULL;
  117. #endif /* USE_EXTERNALS */
  118.  
  119.     return;
  120. }
  121.  
  122. /*
  123.  *  Process string buffer fields for DOWNLOADER or UPLOADER menus.
  124.  */
  125. PRIVATE void add_item_to_list ARGS2(
  126.     char *,         buffer,
  127.     lynx_html_item_type **, list_ptr)
  128. {
  129.     char *colon, *next_colon;
  130.     lynx_html_item_type *cur_item, *prev_item;
  131.  
  132.     /*
  133.      *    Make a linked list
  134.      */
  135.     if (*list_ptr == NULL) {
  136.     /*
  137.      *  First item.
  138.      */
  139.     cur_item = (lynx_html_item_type *)calloc(sizeof(lynx_html_item_type),1);
  140.     if (cur_item == NULL)
  141.         perror("Out of memory in read_cfg");
  142.     *list_ptr = cur_item;
  143.     atexit(free_item_list);
  144.     } else {
  145.     /*
  146.      *  Find the last item.
  147.      */
  148.     for (prev_item = *list_ptr;
  149.          prev_item->next != NULL;
  150.          prev_item = prev_item->next)
  151.         ;  /* null body */
  152.     cur_item = (lynx_html_item_type *)calloc(sizeof(lynx_html_item_type),1);
  153.     if (cur_item == NULL)
  154.         perror("Out of memory in read_cfg");
  155.     else
  156.         prev_item->next = cur_item;
  157.     }
  158.     cur_item->next = NULL;
  159.     cur_item->name = NULL;
  160.     cur_item->command = NULL;
  161.     cur_item->always_enabled = FALSE;
  162.  
  163.     /*
  164.      *    Find first unescaped colon and process fields
  165.      */
  166.     if ((colon = find_colon(buffer)) != NULL) {
  167.     /*
  168.      *  Process name field
  169.      */
  170.     cur_item->name = (char *)calloc((colon-buffer+1),sizeof(char));
  171.     if (cur_item->name == NULL)
  172.         perror("Out of memory in read_cfg");
  173.     LYstrncpy(cur_item->name, buffer, (int)(colon-buffer));
  174.     remove_backslashes(cur_item->name);
  175.  
  176.     /*
  177.      *  Process TRUE/FALSE field
  178.      */
  179.     if ((next_colon = find_colon(colon+1)) != NULL) {
  180.         cur_item->command = (char *)calloc(next_colon-colon, sizeof(char));
  181.         if (cur_item->command == NULL)
  182.         perror("Out of memory in read_cfg");
  183.         LYstrncpy(cur_item->command, colon+1, (int)(next_colon-(colon+1)));
  184.         remove_backslashes(cur_item->command);
  185.         cur_item->always_enabled = is_true(next_colon+1);
  186.     }
  187.     }
  188. }
  189.  
  190.  
  191. /*
  192.  *  Function for freeing the PRINTER menus list. - FM
  193.  */
  194. PRIVATE void free_printer_item_list NOARGS
  195. {
  196.     lynx_printer_item_type *cur = printers;
  197.     lynx_printer_item_type *next;
  198.  
  199.     while (cur) {
  200.     next = cur->next;
  201.     FREE(cur->name);
  202.     FREE(cur->command);
  203.     FREE(cur);
  204.     cur = next;
  205.     }
  206.     printers = NULL;
  207.  
  208.     return;
  209. }
  210.  
  211. /*
  212.  *  Process string buffer fields for PRINTER menus.
  213.  */
  214. PRIVATE void add_printer_to_list ARGS2(
  215.     char *,             buffer,
  216.     lynx_printer_item_type **,    list_ptr)
  217. {
  218.     char *colon, *next_colon;
  219.     lynx_printer_item_type *cur_item, *prev_item;
  220.  
  221.     /*
  222.      *    Make a linked list.
  223.      */
  224.     if (*list_ptr == NULL) {
  225.     /*
  226.      *  First item.
  227.      */
  228.     cur_item = (lynx_printer_item_type *)calloc(sizeof(lynx_printer_item_type),1);
  229.     if (cur_item == NULL)
  230.         perror("Out of memory in read_cfg");
  231.     *list_ptr = cur_item;
  232.     atexit(free_printer_item_list);
  233.     } else {
  234.     /*
  235.      *  Find the last item.
  236.      */
  237.     for (prev_item = *list_ptr;
  238.          prev_item->next != NULL;
  239.          prev_item = prev_item->next)
  240.         ;  /* null body */
  241.  
  242.     cur_item = (lynx_printer_item_type *)calloc(sizeof(lynx_printer_item_type),1);
  243.     if (cur_item == NULL)
  244.         perror("Out of memory in read_cfg");
  245.     else
  246.         prev_item->next = cur_item;
  247.     }
  248.     cur_item->next = NULL;
  249.     cur_item->name = NULL;
  250.     cur_item->command = NULL;
  251.     cur_item->always_enabled = FALSE;
  252.  
  253.     /*
  254.      *    Find first unescaped colon and process fields.
  255.      */
  256.     if ((colon = find_colon(buffer)) != NULL) {
  257.     /*
  258.      *  Process name field.
  259.      */
  260.     cur_item->name = (char *)calloc((colon-buffer+1), sizeof(char));
  261.     if (cur_item->name == NULL)
  262.         perror("Out of memory in read_cfg");
  263.     LYstrncpy(cur_item->name, buffer, (int)(colon-buffer));
  264.     remove_backslashes(cur_item->name);
  265.  
  266.     /*
  267.      *  Process TRUE/FALSE field.
  268.      */
  269.     if ((next_colon = find_colon(colon+1)) != NULL) {
  270.         cur_item->command = (char *)calloc(next_colon-colon, sizeof(char));
  271.         if (cur_item->command == NULL)
  272.         perror("Out of memory in read_cfg");
  273.         LYstrncpy(cur_item->command, colon+1, (int)(next_colon-(colon+1)));
  274.         remove_backslashes(cur_item->command);
  275.         cur_item->always_enabled = is_true(next_colon+1);
  276.     }
  277.  
  278.     /*
  279.      *  Process pagelen field.
  280.      */
  281.     if ((next_colon = find_colon(next_colon+1)) != NULL) {
  282.         cur_item->pagelen = atoi(next_colon+1);
  283.     } else {
  284.         /* default to 66 lines */
  285.         cur_item->pagelen = 66;
  286.     }
  287.     }
  288. }
  289.  
  290. #if defined(USE_COLOR_STYLE) || defined(USE_COLOR_TABLE)
  291.  
  292. #ifdef USE_SLANG
  293. #define COLOR_WHITE 7
  294. #define COLOR_BLACK 0
  295. #endif
  296.  
  297. int default_fg = COLOR_WHITE;
  298. int default_bg = COLOR_BLACK;
  299.  
  300. static char *Color_Strings[16] =
  301. {
  302.     "black",
  303.     "red",
  304.     "green",
  305.     "brown",
  306.     "blue",
  307.     "magenta",
  308.     "cyan",
  309.     "lightgray",
  310.     "gray",
  311.     "brightred",
  312.     "brightgreen",
  313.     "yellow",
  314.     "brightblue",
  315.     "brightmagenta",
  316.     "brightcyan",
  317.     "white"
  318. };
  319.  
  320. #ifdef DOSPATH
  321. /*
  322.  * PDCurses (and possibly some other implementations) use a non-ANSI set of
  323.  * codes for colors.
  324.  */
  325. PRIVATE int ColorCode ARGS1(
  326.     int,    color)
  327. {
  328.     static int map[] = {
  329.         0,  4,    2,  6, 1,  5,  3,  7,
  330.         8, 12, 10, 14, 9, 13, 11, 15 };
  331.     return map[color];
  332. }
  333. #else
  334. #define ColorCode(color) (color)
  335. #endif
  336.  
  337. /*
  338.  *  Validator for COLOR fields.
  339.  */
  340. PUBLIC int check_color ARGS2(
  341.     char *, color,
  342.     int,    the_default)
  343. {
  344.     int i;
  345.  
  346.     if (!strcasecomp(color, "default"))
  347.     return the_default;
  348.     if (!strcasecomp(color, "nocolor"))
  349.     return NO_COLOR;
  350.  
  351.     for (i = 0; i < 16; i++) {
  352.     if (!strcasecomp(color, Color_Strings[i]))
  353.         return ColorCode(i);
  354.     }
  355.     return ERR_COLOR;
  356. }
  357. #endif /* USE_COLOR_STYLE || USE_COLOR_TABLE */
  358.  
  359. #if defined(USE_COLOR_TABLE)
  360.  
  361. /*
  362.  *  Exit routine for failed COLOR parsing.
  363.  */
  364. PRIVATE void exit_with_color_syntax ARGS1(
  365.     char *,     error_line)
  366. {
  367.     unsigned int i;
  368.     fprintf (stderr, "\
  369. Syntax Error parsing COLOR in configuration file:\n\
  370. The line must be of the form:\n\
  371. COLOR:INTEGER:FOREGROUND:BACKGROUND\n\
  372. \n\
  373. Here FOREGROUND and BACKGROUND must be one of:\n\
  374. The special strings 'nocolor' or 'default', or\n"
  375.         );
  376.     for (i = 0; i < 16; i += 4) {
  377.     fprintf(stderr, "%16s %16s %16s %16s\n",
  378.         Color_Strings[i], Color_Strings[i + 1],
  379.         Color_Strings[i + 2], Color_Strings[i + 3]);
  380.     }
  381.     fprintf (stderr, "Offending line:\n%s\n",error_line);
  382.  
  383. #ifndef NOSIGHUP
  384.     (void) signal(SIGHUP, SIG_DFL);
  385. #endif /* NOSIGHUP */
  386.     (void) signal(SIGTERM, SIG_DFL);
  387. #ifndef VMS
  388.     (void) signal(SIGINT, SIG_DFL);
  389. #endif /* !VMS */
  390. #ifdef SIGTSTP
  391.     if (no_suspend)
  392.     (void) signal(SIGTSTP,SIG_DFL);
  393. #endif /* SIGTSTP */
  394.     exit(-1);
  395. }
  396.  
  397. /*
  398.  *  Process string buffer fields for COLOR setting.
  399.  */
  400. PRIVATE void parse_color ARGS1(
  401.     char *, buffer)
  402. {
  403.     int color;
  404.     char *fg, *bg;
  405.     char temp[501];
  406.  
  407.     if (strlen(buffer) < sizeof(temp))
  408.     strcpy(temp, buffer);
  409.     else
  410.     strcpy(temp, "Color config line too long");
  411.  
  412.     /*
  413.      *    We are expecting a line of the form:
  414.      *      INTEGER:FOREGROUND:BACKGROUND
  415.      */
  416.     color = atoi(buffer);
  417.     if (NULL == (fg = find_colon(buffer)))
  418.     exit_with_color_syntax(temp);
  419.     *fg++ = '\0';
  420.  
  421.     if (NULL == (bg = find_colon(fg)))
  422.     exit_with_color_syntax(temp);
  423.     *bg++ = '\0';
  424.  
  425. #if defined(USE_SLANG)
  426.     if ((check_color(fg, default_fg) < 0) ||
  427.     (check_color(bg, default_bg) < 0))
  428.     exit_with_color_syntax(temp);
  429.  
  430.     SLtt_set_color(color, NULL, fg, bg);
  431. #else
  432.     if (lynx_chg_color(color,
  433.     check_color(fg, default_fg),
  434.     check_color(bg, default_bg)) < 0)
  435.     exit_with_color_syntax(temp);
  436. #endif
  437. }
  438. #endif /* USE_COLOR_TABLE */
  439.  
  440. #define MAX_LINE_BUFFER_LEN    501
  441.  
  442. typedef int (*ParseFunc) PARAMS((char *));
  443.  
  444. typedef union {
  445.     lynx_html_item_type ** add_value;
  446.     BOOLEAN * set_value;
  447.     int *      int_value;
  448.     char **   str_value;
  449.     ParseFunc fun_value;
  450.     long      def_value;
  451. } ConfigUnion;
  452.  
  453. #undef  PARSE_DEBUG
  454. #ifdef    PARSE_DEBUG
  455. #define ParseData \
  456.     lynx_html_item_type** add_value; \
  457.     BOOLEAN *set_value; \
  458.     int *int_value; \
  459.     char **str_value; \
  460.     ParseFunc fun_value; \
  461.     long def_value
  462. #define PARSE_ADD(n,t,v) {n,t,     &v,  0,  0,  0,  0,  0}
  463. #define PARSE_SET(n,t,v) {n,t,      0, &v,  0,  0,  0,  0}
  464. #define PARSE_INT(n,t,v) {n,t,      0,  0, &v,  0,  0,  0}
  465. #define PARSE_STR(n,t,v) {n,t,      0,  0,  0, &v,  0,  0}
  466. #define PARSE_FUN(n,t,v) {n,t,      0,  0,  0,  0,  v,  0}
  467. #define PARSE_DEF(n,t,v) {n,t,      0,  0,  0,  0,  0,  v}
  468. #else
  469. #define ParseData long value
  470. #define PARSE_ADD(n,t,v) {n,t,     (long)&(v)}
  471. #define PARSE_SET(n,t,v) {n,t,     (long)&(v)}
  472. #define PARSE_INT(n,t,v) {n,t,     (long)&(v)}
  473. #define PARSE_STR(n,t,v) {n,t,     (long)&(v)}
  474. #define PARSE_FUN(n,t,v) {n,t,     (long) (v)}
  475. #define PARSE_DEF(n,t,v) {n,t,     (long) (v)}
  476. #endif
  477.  
  478. typedef struct
  479. {
  480.    char *name;
  481.    int type;
  482. #define CONF_BOOL        1      /* BOOLEAN type */
  483. #define CONF_FUN        2
  484. #define CONF_INT        3
  485. #define CONF_STR        4
  486. #define CONF_ENV        5      /* from environment variable */
  487. #define CONF_INCLUDE        6      /* include file-- handle special */
  488. #define CONF_ADD_ITEM        7
  489. #define CONF_ADD_TRUSTED    8
  490.  
  491.    ParseData;
  492. }
  493. Config_Type;
  494.  
  495. static int assume_charset_fun ARGS1(
  496.     char *,     value)
  497. {
  498.     StrAllocCopy(UCAssume_MIMEcharset, value);
  499.     LYLowerCase(UCAssume_MIMEcharset);
  500.     UCLYhndl_for_unspec = UCGetLYhndl_byMIME(UCAssume_MIMEcharset);
  501.     return 0;
  502. }
  503.  
  504. static int assume_local_charset_fun ARGS1(
  505.     char *,     value)
  506. {
  507.     StrAllocCopy(UCAssume_localMIMEcharset, value);
  508.     LYLowerCase(UCAssume_localMIMEcharset);
  509.     UCLYhndl_HTFile_for_unspec = UCGetLYhndl_byMIME(UCAssume_localMIMEcharset);
  510.     return 0;
  511. }
  512.  
  513. static int assume_unrec_charset_fun ARGS1(
  514.     char *,     value)
  515. {
  516.     StrAllocCopy(UCAssume_unrecMIMEcharset, value);
  517.     LYLowerCase(UCAssume_unrecMIMEcharset);
  518.     UCLYhndl_for_unrec = UCGetLYhndl_byMIME(UCAssume_unrecMIMEcharset);
  519.     return 0;
  520. }
  521.  
  522. static int character_set_fun ARGS1(
  523.     char *,     value)
  524. {
  525.     size_t i;
  526.     size_t len;
  527.  
  528.     len = strlen (value);
  529.     for (i = 0; LYchar_set_names[i]; i++) {
  530.     if (!strncmp(value, LYchar_set_names[i], len)) {
  531.         current_char_set = i;
  532.         HTMLSetRawModeDefault(i);
  533.         break;
  534.     }
  535.     }
  536.  
  537.     return 0;
  538. }
  539.  
  540. #ifdef USE_COLOR_TABLE
  541. static int color_fun ARGS1(
  542.     char *,     value)
  543. {
  544.     parse_color (value);
  545.     return 0;
  546. }
  547. #endif
  548.  
  549. static int default_bookmark_file_fun ARGS1(
  550.     char *,     value)
  551. {
  552.     StrAllocCopy(bookmark_page, value);
  553.     StrAllocCopy(BookmarkPage, bookmark_page);
  554.     StrAllocCopy(MBM_A_subbookmark[0], bookmark_page);
  555.     StrAllocCopy(MBM_A_subdescript[0], MULTIBOOKMARKS_DEFAULT);
  556.     return 0;
  557. }
  558.  
  559. static int default_cache_size_fun ARGS1(
  560.     char *,     value)
  561. {
  562.     HTCacheSize = atoi(value);
  563.     if (HTCacheSize < 2) HTCacheSize = 2;
  564.     return 0;
  565. }
  566.  
  567. static int default_editor_fun ARGS1(
  568.     char *,     value)
  569. {
  570.     if (!system_editor) StrAllocCopy(editor, value);
  571.     return 0;
  572. }
  573.  
  574. static int numbers_as_arrows_fun ARGS1(
  575.     char *,     value)
  576. {
  577.     if (is_true(value))
  578.     keypad_mode = NUMBERS_AS_ARROWS;
  579.     else
  580.     keypad_mode = LINKS_ARE_NUMBERED;
  581.  
  582.     return 0;
  583. }
  584.  
  585. static int default_user_mode_fun ARGS1(
  586.     char *,     value)
  587. {
  588.     if (!strncasecomp(value, "NOVICE", 6))
  589.     user_mode = NOVICE_MODE;
  590.     else if (!strncasecomp(value, "INTER", 5))
  591.     user_mode = INTERMEDIATE_MODE;
  592.     else if (!strncasecomp(value, "ADVANCE", 7))
  593.     user_mode = ADVANCED_MODE;
  594.  
  595.    return 0;
  596. }
  597.  
  598. #ifdef DIRED_SUPPORT
  599. static int dired_menu_fun ARGS1(
  600.     char *,     value)
  601. {
  602.     add_menu_item(value);
  603.     return 0;
  604. }
  605. #endif
  606.  
  607. static int jumpfile_fun ARGS1(
  608.     char *,     value)
  609. {
  610.     char buffer [MAX_LINE_BUFFER_LEN];
  611.  
  612.     sprintf (buffer, "JUMPFILE:%s", value);
  613.     if (!LYJumpInit(buffer))
  614.     CTRACE(tfp, "Failed to register %s\n", buffer);
  615.  
  616.     return 0;
  617. }
  618.  
  619. static int keymap_fun ARGS1(
  620.     char *,     key)
  621. {
  622.     char *func;
  623.  
  624.     if ((func = strchr(key, ':')) != NULL)    {
  625.     *func++ = '\0';
  626.     /* Allow comments on the ends of key remapping lines. - DT */
  627.     if (!remap(key, strtok(func, " \t\n#")))
  628.         fprintf(stderr,
  629.             "key remapping of %s to %s failed\n",key,func);
  630.     else if (!strcmp("TOGGLE_HELP", strtok(func, " \t\n#")))
  631.         LYUseNoviceLineTwo = FALSE;
  632.     }
  633.     return 0;
  634. }
  635.  
  636. static int localhost_alias_fun ARGS1(
  637.     char *,     value)
  638. {
  639.     LYAddLocalhostAlias(value);
  640.     return 0;
  641. }
  642.  
  643. #ifdef LYNXCGI_LINKS
  644. static int lynxcgi_environment_fun ARGS1(
  645.     char *,     value)
  646. {
  647.     add_lynxcgi_environment(value);
  648.     return 0;
  649. }
  650. #endif
  651.  
  652. static int lynx_sig_file_fun ARGS1(
  653.     char *,     value)
  654. {
  655.     if (LYPathOffHomeOK(value, 256)) {
  656.     StrAllocCopy(LynxSigFile, value);
  657.     LYAddPathToHome(value, 256, LynxSigFile);
  658.     StrAllocCopy(LynxSigFile, value);
  659.     CTRACE(tfp, "LYNX_SIG_FILE set to '%s'\n", LynxSigFile);
  660.     } else {
  661.     CTRACE(tfp, "LYNX_SIG_FILE '%s' is bad. Ignoring.\n", LYNX_SIG_FILE);
  662.     }
  663.     return 0;
  664. }
  665.  
  666. static int news_chunk_size_fun ARGS1(
  667.     char *,     value)
  668. {
  669.     HTNewsChunkSize = atoi(value);
  670.     /*
  671.      * If the new HTNewsChunkSize exceeds the maximum,
  672.      * increase HTNewsMaxChunk to this size. - FM
  673.      */
  674.     if (HTNewsChunkSize > HTNewsMaxChunk)
  675.     HTNewsMaxChunk = HTNewsChunkSize;
  676.     return 0;
  677. }
  678.  
  679. static int news_max_chunk_fun ARGS1(
  680.     char *,     value)
  681. {
  682.     HTNewsMaxChunk = atoi(value);
  683.     /*
  684.      * If HTNewsChunkSize exceeds the new maximum,
  685.      * reduce HTNewsChunkSize to this maximum. - FM
  686.      */
  687.     if (HTNewsChunkSize > HTNewsMaxChunk)
  688.     HTNewsChunkSize = HTNewsMaxChunk;
  689.     return 0;
  690. }
  691.  
  692. static int news_posting_fun ARGS1(
  693.     char *,     value)
  694. {
  695.     LYNewsPosting = is_true(value);
  696.     no_newspost = (LYNewsPosting == FALSE);
  697.     return 0;
  698. }
  699.  
  700. static int printer_fun ARGS1(
  701.     char *,     value)
  702. {
  703.     add_printer_to_list(value, &printers);
  704.     return 0;
  705. }
  706.  
  707. static int suffix_fun ARGS1(
  708.     char *,     value)
  709. {
  710.     char *mime_type;
  711.  
  712.     if ((strlen (value) < 3)
  713.     || (NULL == (mime_type = strchr (value, ':'))))
  714.     return 0;
  715.  
  716.     *mime_type++ = '\0';
  717.  
  718.     LYRemoveBlanks(mime_type);
  719.     LYLowerCase(mime_type);
  720.  
  721.     if (strstr(mime_type, "tex") != NULL ||
  722.     strstr(mime_type, "postscript") != NULL ||
  723.     strstr(mime_type, "sh") != NULL ||
  724.     strstr(mime_type, "troff") != NULL ||
  725.     strstr(mime_type, "rtf") != NULL)
  726.     HTSetSuffix(value, mime_type, "8bit", 1.0);
  727.     else
  728.     HTSetSuffix(value, mime_type, "binary", 1.0);
  729.  
  730.     return 0;
  731. }
  732.  
  733. static int system_editor_fun ARGS1(
  734.     char *,     value)
  735. {
  736.     StrAllocCopy(editor, value);
  737.     system_editor = TRUE;
  738.     return 0;
  739. }
  740.  
  741. static int viewer_fun ARGS1(
  742.     char *,     value)
  743. {
  744.     char *mime_type;
  745.     char *viewer;
  746.     char *environment;
  747.     char *cp;
  748.  
  749.     mime_type = value;
  750.  
  751.     if ((strlen (value) < 3)
  752.     || (NULL == (viewer = strchr (mime_type, ':'))))
  753.     return 0;
  754.  
  755.     *viewer++ = '\0';
  756.  
  757.     LYRemoveBlanks(mime_type);
  758.     LYLowerCase(mime_type);
  759.  
  760.     environment = strrchr(viewer, ':');
  761.     if ((environment != NULL) &&
  762.     (strlen(viewer) > 1) && *(environment-1) != '\\') {
  763.     *environment++ = '\0';
  764.     remove_backslashes(viewer);
  765.     /*
  766.      * If environment equals xwindows then only assign the presentation if
  767.      * there is a $DISPLAY variable.
  768.      */
  769.     if (!strcasecomp(environment,"XWINDOWS")) {
  770.         if ((cp = getenv(DISPLAY)) != NULL && *cp != '\0')
  771.         HTSetPresentation(mime_type, viewer, 1.0, 3.0, 0.0, 0);
  772.     } else if (!strcasecomp(environment,"NON_XWINDOWS")) {
  773.         if ((cp = getenv(DISPLAY)) == NULL || *cp == '\0')
  774.         HTSetPresentation(mime_type, viewer, 1.0, 3.0, 0.0, 0);
  775.     } else {
  776.         HTSetPresentation(mime_type, viewer, 1.0, 3.0, 0.0, 0);
  777.     }
  778.     } else {
  779.     remove_backslashes(viewer);
  780.     HTSetPresentation(mime_type, viewer, 1.0, 3.0, 0.0, 0);
  781.     }
  782.  
  783.     return 0;
  784. }
  785.  
  786. static Config_Type Config_Table [] =
  787. {
  788.      PARSE_INT("alertsecs", CONF_INT, AlertSecs),
  789.      PARSE_SET("always_resubmit_posts", CONF_BOOL, LYresubmit_posts),
  790. #ifdef EXEC_LINKS
  791.      PARSE_DEF("always_trusted_exec", CONF_ADD_TRUSTED, ALWAYS_EXEC_PATH),
  792. #endif
  793.      PARSE_FUN("assume_charset", CONF_FUN, assume_charset_fun),
  794.      PARSE_FUN("assume_local_charset", CONF_FUN, assume_local_charset_fun),
  795.      PARSE_FUN("assume_unrec_charset", CONF_FUN, assume_unrec_charset_fun),
  796.      PARSE_SET("block_multi_bookmarks", CONF_BOOL, LYMBMBlocked),
  797.      PARSE_SET("bold_h1", CONF_BOOL, bold_H1),
  798.      PARSE_SET("bold_headers", CONF_BOOL, bold_headers),
  799.      PARSE_SET("bold_name_anchors", CONF_BOOL, bold_name_anchors),
  800.      PARSE_SET("case_sensitive_always_on", CONF_BOOL, case_sensitive),
  801.      PARSE_FUN("character_set", CONF_FUN, character_set_fun),
  802.      PARSE_SET("checkmail", CONF_BOOL, check_mail),
  803.      PARSE_SET("collapse_br_tags", CONF_BOOL, LYCollapseBRs),
  804. #ifdef USE_COLOR_TABLE
  805.      PARSE_FUN("color", CONF_FUN, color_fun),
  806. #endif
  807.      PARSE_STR("cso_proxy", CONF_ENV, cso_proxy_putenv_cmd ),
  808. #ifdef VMS
  809.      PARSE_STR("CSWING_PATH", CONF_STR, LYCSwingPath),
  810. #endif
  811.      PARSE_FUN("default_bookmark_file", CONF_FUN, default_bookmark_file_fun),
  812.      PARSE_FUN("default_cache_size", CONF_FUN, default_cache_size_fun),
  813.      PARSE_FUN("default_editor", CONF_FUN, default_editor_fun),
  814.      PARSE_STR("default_index_file", CONF_STR, indexfile),
  815.      PARSE_FUN("default_keypad_mode_is_numbers_as_arrows", CONF_FUN, numbers_as_arrows_fun),
  816.      PARSE_FUN("default_user_mode", CONF_FUN, default_user_mode_fun),
  817. #if defined(VMS) && defined(VAXC) && !defined(__DECC)
  818.      PARSE_INT("default_virtual_memory_size", CONF_INT, HTVirtualMemorySize),
  819. #endif
  820. #ifdef DIRED_SUPPORT
  821.      PARSE_FUN("dired_menu", CONF_FUN, dired_menu_fun),
  822. #endif
  823.      PARSE_ADD("downloader", CONF_ADD_ITEM, downloaders),
  824.      PARSE_SET("emacs_keys_always_on", CONF_BOOL, emacs_keys),
  825.      PARSE_SET("enable_scrollback", CONF_BOOL, enable_scrollback),
  826. #ifdef USE_EXTERNALS
  827.      PARSE_ADD("external", CONF_ADD_ITEM, externals),
  828. #endif
  829.      PARSE_STR("finger_proxy", CONF_ENV, finger_proxy_putenv_cmd ),
  830.      PARSE_SET("force_ssl_cookies_secure", CONF_BOOL, LYForceSSLCookiesSecure),
  831.      PARSE_STR("ftp_proxy", CONF_ENV, ftp_proxy_putenv_cmd ),
  832.      PARSE_STR("global_extension_map", CONF_STR, global_extension_map),
  833.      PARSE_STR("global_mailcap", CONF_STR, global_type_map),
  834.      PARSE_STR("gopher_proxy", CONF_ENV, gopher_proxy_putenv_cmd ),
  835.      PARSE_SET("gotobuffer", CONF_BOOL, goto_buffer),
  836.      PARSE_STR("helpfile", CONF_STR, helpfile),
  837.      PARSE_SET("historical_comments", CONF_BOOL, historical_comments),
  838.      PARSE_STR("http_proxy", CONF_ENV, http_proxy_putenv_cmd ),
  839.      PARSE_STR("https_proxy", CONF_ENV, https_proxy_putenv_cmd ),
  840.      PARSE_FUN("include", CONF_INCLUDE, 0),
  841.      PARSE_INT("infosecs", CONF_INT, InfoSecs),
  842.      PARSE_STR("jump_prompt", CONF_STR, jumpprompt),
  843.      PARSE_SET("jumpbuffer", CONF_BOOL, jump_buffer),
  844.      PARSE_FUN("jumpfile", CONF_FUN, jumpfile_fun),
  845.      PARSE_FUN("keymap", CONF_FUN, keymap_fun),
  846.      PARSE_SET("list_news_numbers", CONF_BOOL, LYListNewsNumbers),
  847.      PARSE_SET("list_news_dates", CONF_BOOL, LYListNewsDates),
  848. #ifndef VMS
  849.      PARSE_STR("list_format", CONF_STR, list_format),
  850. #endif
  851.      PARSE_FUN("localhost_alias", CONF_FUN, localhost_alias_fun),
  852.      PARSE_STR("local_domain", CONF_STR, LYLocalDomain),
  853. #if defined(EXEC_LINKS) || defined(EXEC_SCRIPTS)
  854.      PARSE_SET("local_execution_links_always_on", CONF_BOOL, local_exec),
  855.      PARSE_SET("local_execution_links_on_but_not_remote", CONF_BOOL, local_exec_on_local_files),
  856. #endif
  857. #ifdef LYNXCGI_LINKS
  858.      PARSE_FUN("lynxcgi_environment", CONF_FUN, lynxcgi_environment_fun),
  859. #ifndef VMS
  860.      PARSE_STR("lynxcgi_document_root", CONF_STR, LYCgiDocumentRoot),
  861. #endif
  862. #endif
  863.      PARSE_STR("lynx_host_name", CONF_STR, LYHostName),
  864.      PARSE_FUN("lynx_sig_file", CONF_FUN, lynx_sig_file_fun),
  865.      PARSE_SET("mail_system_error_logging", CONF_BOOL, error_logging),
  866. #ifdef VMS
  867.      PARSE_STR("mail_adrs", CONF_STR, mail_adrs),
  868. #endif
  869.      PARSE_SET("make_links_for_all_images", CONF_BOOL, clickable_images),
  870.      PARSE_SET("make_pseudo_alts_for_inlines", CONF_BOOL, pseudo_inline_alts),
  871.      PARSE_INT("messagesecs", CONF_INT, MessageSecs),
  872.      PARSE_SET("minimal_comments", CONF_BOOL, minimal_comments),
  873.      PARSE_INT("multi_bookmark_support", CONF_BOOL, LYMultiBookmarks),
  874.      PARSE_FUN("news_chunk_size", CONF_FUN, news_chunk_size_fun),
  875.      PARSE_FUN("news_max_chunk", CONF_FUN, news_max_chunk_fun),
  876.      PARSE_FUN("news_posting", CONF_FUN, news_posting_fun),
  877.      PARSE_STR("news_proxy", CONF_ENV, news_proxy_putenv_cmd),
  878.      PARSE_STR("newspost_proxy", CONF_ENV, newspost_proxy_putenv_cmd),
  879.      PARSE_STR("newsreply_proxy", CONF_ENV, newsreply_proxy_putenv_cmd),
  880.      PARSE_STR("nntp_proxy", CONF_ENV, nntp_proxy_putenv_cmd),
  881.      PARSE_STR("nntpserver", CONF_ENV, NNTPSERVER_putenv_cmd),
  882.      PARSE_SET("no_dot_files", CONF_BOOL, no_dotfiles),
  883.      PARSE_SET("no_file_referer", CONF_BOOL, no_filereferer),
  884. #ifndef VMS
  885.      PARSE_SET("no_forced_core_dump", CONF_BOOL, LYNoCore),
  886. #endif
  887.      PARSE_SET("no_from_header", CONF_BOOL, LYNoFromHeader),
  888.      PARSE_SET("no_ismap_if_usemap", CONF_BOOL, LYNoISMAPifUSEMAP),
  889.      PARSE_STR("no_proxy", CONF_ENV, no_proxy_putenv_cmd ),
  890.      PARSE_SET("no_referer_header", CONF_BOOL, LYNoRefererHeader),
  891. #ifdef DISP_PARTIAL
  892.      PARSE_SET("partial", CONF_BOOL, display_partial),
  893. #endif
  894.      PARSE_STR("personal_mailcap", CONF_STR, personal_type_map),
  895.      PARSE_STR("personal_extension_map", CONF_STR, personal_extension_map),
  896.      PARSE_STR("preferred_charset", CONF_STR, pref_charset),
  897.      PARSE_STR("preferred_language", CONF_STR, language),
  898.      PARSE_SET("prepend_base_to_source", CONF_BOOL, LYPrependBaseToSource),
  899.      PARSE_SET("prepend_charset_to_source", CONF_BOOL, LYPrependCharsetToSource),
  900.      PARSE_FUN("printer", CONF_FUN, printer_fun),
  901. #ifdef RAWDOSKEYHACK
  902.      PARSE_SET("raw_dos_key_hack", CONF_BOOL, raw_dos_key_hack),
  903. #endif
  904.      PARSE_SET("quit_default_yes", CONF_BOOL, LYQuitDefaultYes),
  905.      PARSE_STR("save_space", CONF_STR, lynx_save_space),
  906.      PARSE_SET("scan_for_buried_news_refs", CONF_BOOL, scan_for_buried_news_references),
  907.      PARSE_SET("seek_frag_area_in_cur", CONF_BOOL, LYSeekFragAREAinCur),
  908.      PARSE_SET("seek_frag_map_in_cur", CONF_BOOL, LYSeekFragMAPinCur),
  909.      PARSE_SET("set_cookies", CONF_BOOL, LYSetCookies),
  910.      PARSE_SET("show_cursor", CONF_BOOL, LYShowCursor),
  911.      PARSE_STR("snews_proxy", CONF_ENV, snews_proxy_putenv_cmd ),
  912.      PARSE_STR("snewspost_proxy", CONF_ENV, snewspost_proxy_putenv_cmd ),
  913.      PARSE_STR("snewsreply_proxy", CONF_ENV, snewsreply_proxy_putenv_cmd ),
  914.      PARSE_SET("soft_dquotes", CONF_BOOL, soft_dquotes),
  915.      PARSE_STR("startfile", CONF_STR, startfile),
  916.      PARSE_SET("strip_dotdot_urls", CONF_BOOL, LYStripDotDotURLs),
  917.      PARSE_SET("substitute_underscores", CONF_BOOL, use_underscore),
  918.      PARSE_FUN("suffix", CONF_FUN, suffix_fun),
  919.      PARSE_FUN("system_editor", CONF_FUN, system_editor_fun),
  920.      PARSE_STR("system_mail", CONF_STR, system_mail),
  921.      PARSE_STR("system_mail_flags", CONF_STR, system_mail_flags),
  922. #ifdef EXEC_LINKS
  923.      PARSE_DEF("trusted_exec", CONF_ADD_TRUSTED, EXEC_PATH),
  924. #endif
  925. #ifdef LYNXCGI_LINKS
  926.      PARSE_DEF("trusted_lynxcgi", CONF_ADD_TRUSTED, CGI_PATH),
  927. #endif
  928.      PARSE_STR("url_domain_prefixes", CONF_STR, URLDomainPrefixes),
  929.      PARSE_STR("url_domain_suffixes", CONF_STR, URLDomainSuffixes),
  930. #ifdef DIRED_SUPPORT
  931.      PARSE_ADD("uploader", CONF_ADD_ITEM, uploaders),
  932. #endif
  933. #ifdef VMS
  934.      PARSE_SET("use_fixed_records", CONF_BOOL, UseFixedRecords),
  935. #endif
  936. #if defined(NCURSES_MOUSE_VERSION) || defined(USE_SLANG_MOUSE)
  937.      PARSE_SET("use_mouse", CONF_BOOL, LYUseMouse),
  938. #endif
  939.      PARSE_SET("use_select_popups", CONF_BOOL, LYSelectPopups),
  940.      PARSE_SET("verbose_images", CONF_BOOL, verbose_img),
  941.      PARSE_SET("vi_keys_always_on", CONF_BOOL, vi_keys),
  942.      PARSE_FUN("viewer", CONF_FUN, viewer_fun),
  943.      PARSE_STR("wais_proxy", CONF_ENV, wais_proxy_putenv_cmd ),
  944.      PARSE_STR("xloadimage_command", CONF_STR, XLoadImageCommand),
  945.  
  946.      {0}
  947. };
  948.  
  949. /*
  950.  * Process the configuration file (lynx.cfg).
  951.  */
  952. PUBLIC void read_cfg ARGS3(
  953.     char *, cfg_filename,
  954.     char *, parent_filename,
  955.     int,    nesting_level)
  956. {
  957.     FILE *fp;
  958.     char buffer[MAX_LINE_BUFFER_LEN];
  959.  
  960.     CTRACE(tfp, "Loading cfg file '%s'.\n", cfg_filename);
  961.  
  962.     /*
  963.      *    Don't get hung up by an include file loop.  Arbitrary max depth
  964.      *    of 10.    - BL
  965.      */
  966.     if (nesting_level > 10) {
  967.     fprintf(stderr,
  968.         "More than %d nested lynx.cfg includes -- perhaps there is a loop?!?\n",
  969.         nesting_level - 1);
  970.     fprintf(stderr,"Last attempted include was '%s',\n", cfg_filename);
  971.     fprintf(stderr,"included from '%s'.\n", parent_filename);
  972.     exit(-1);
  973.     }
  974.     /*
  975.      *    Locate and open the file.
  976.      */
  977.     if (!cfg_filename || strlen(cfg_filename) == 0) {
  978.     CTRACE(tfp,"No filename following -cfg switch!\n");
  979.     return;
  980.     }
  981.     if ((fp = fopen(cfg_filename,"r")) == 0) {
  982.     CTRACE(tfp,"lynx.cfg file not found as %s\n",cfg_filename);
  983.     return;
  984.     }
  985.     have_read_cfg = TRUE;
  986.  
  987.     /*
  988.      *    Process each line in the file.
  989.      */
  990.     while (fgets(buffer, sizeof(buffer), fp) != 0) {
  991.     char *name, *value;
  992.     char *cp;
  993.     Config_Type *tbl;
  994.     char ch;
  995. #ifdef PARSE_DEBUG
  996.     Config_Type *q;
  997. #else
  998.     ConfigUnion *q;
  999. #endif
  1000.  
  1001.     /* Most lines in the config file are comment lines.  Weed them out
  1002.      * now.  Also, leading whitespace is ok, so trim it.
  1003.      */
  1004.     name = LYSkipBlanks(buffer);
  1005.  
  1006.     if (*name == '#')
  1007.         continue;
  1008.  
  1009.     LYTrimTrailing(name);
  1010.  
  1011.     if (*name == 0) continue;
  1012.  
  1013.     /* Significant lines are of the form KEYWORD:WHATEVER */
  1014.     if ((value = strchr (name, ':')) == 0) {
  1015.          /* fprintf (stderr, "Bad line-- no :\n"); */
  1016.          continue;
  1017.     }
  1018.  
  1019.     /* skip past colon, but replace ':' with 0 to make name meaningful */
  1020.     *value++ = 0;
  1021.  
  1022.     /*
  1023.      *  Trim off any trailing comments.
  1024.      *
  1025.      *  (Apparently, the original code considers a trailing comment
  1026.      *   valid only if preceded by a space character but is not followed
  1027.      *   by a colon.  -- JED)
  1028.      */
  1029.     if ((cp = strrchr (value, ':')) == 0)
  1030.         cp = value;
  1031.     if ((cp = strchr (cp, '#')) != 0) {
  1032.         cp--;
  1033.         if (isspace ((unsigned char) *cp))
  1034.         *cp = 0;
  1035.     }
  1036.  
  1037.     tbl = Config_Table;
  1038.     ch = TOUPPER(*name);
  1039.     while (tbl->name != 0) {
  1040.         char ch1 = tbl->name[0];
  1041.  
  1042.         if ((ch == TOUPPER(ch1))
  1043.         && (0 == strcasecomp (name, tbl->name)))
  1044.         break;
  1045.  
  1046.         tbl++;
  1047.     }
  1048.  
  1049.     if (tbl->name == 0) {
  1050.         /* Apparently, lynx ignores unknown keywords */
  1051.         /* fprintf (stderr, "%s not found in config file */
  1052.         continue;
  1053.     }
  1054.  
  1055. #ifdef PARSE_DEBUG
  1056.     q = tbl;
  1057. #else
  1058.     q = (ConfigUnion *)(&(tbl->value));
  1059. #endif
  1060.     switch (tbl->type) {
  1061.     case CONF_BOOL:
  1062.         if (q->set_value != 0)
  1063.         *(q->set_value) = is_true (value);
  1064.         break;
  1065.  
  1066.     case CONF_FUN:
  1067.         if (q->fun_value != 0)
  1068.         (*(q->fun_value)) (value);
  1069.         break;
  1070.  
  1071.     case CONF_INT:
  1072.         if (q->int_value != 0) {
  1073.         int ival;
  1074.         /* Apparently, if an integer value is not present, then the
  1075.          * value is not changed.  So, use the sscanf function to make
  1076.          * this determination.
  1077.          */
  1078.         if (1 == sscanf (value, "%d", &ival))
  1079.             *(q->int_value) = ival;
  1080.         }
  1081.         break;
  1082.  
  1083.     case CONF_STR:
  1084.         if (q->str_value != 0)
  1085.         StrAllocCopy(*(q->str_value), value);
  1086.         break;
  1087.  
  1088.     case CONF_ENV:
  1089.         if (getenv (tbl->name) == 0) {
  1090. #ifdef VMS
  1091.         Define_VMSLogical(tbl->name, value);
  1092. #else
  1093.         char tmpbuf[MAX_LINE_BUFFER_LEN];
  1094.         sprintf (tmpbuf, "%s=%s", tbl->name, value);
  1095.         StrAllocCopy(*(q->str_value), tmpbuf);
  1096.         putenv (*(q->str_value));
  1097. #endif
  1098.         }
  1099.         break;
  1100.  
  1101.     case CONF_INCLUDE:
  1102.         /* include another file */
  1103.         read_cfg (value, cfg_filename, nesting_level + 1);
  1104.         break;
  1105.  
  1106.     case CONF_ADD_ITEM:
  1107.         if (q->add_value != 0)
  1108.         add_item_to_list (value, q->add_value);
  1109.         break;
  1110. #if defined(EXEC_LINKS) || defined(LYNXCGI_LINKS)
  1111.     case CONF_ADD_TRUSTED:
  1112.         add_trusted (value, q->def_value);
  1113.         break;
  1114. #endif
  1115.     }
  1116.     }
  1117.  
  1118.     fclose (fp);
  1119.  
  1120.     /*
  1121.      *    If any DOWNLOADER: commands have always_enabled set (:TRUE),
  1122.      *    make override_no_download TRUE, so that other restriction
  1123.      *    settings will not block presentation of a download menu
  1124.      *    with those always_enabled options still available. - FM
  1125.      */
  1126.     if (downloaders != 0) {
  1127.     lynx_html_item_type *cur_download;
  1128.  
  1129.     cur_download = downloaders;
  1130.     while (cur_download != 0) {
  1131.         if (cur_download->always_enabled) {
  1132.         override_no_download = TRUE;
  1133.         break;
  1134.         }
  1135.         cur_download = cur_download->next;
  1136.     }
  1137.     }
  1138. }
  1139.