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 / LYPrint.c < prev    next >
C/C++ Source or Header  |  1998-05-02  |  37KB  |  1,403 lines

  1. #include <HTUtils.h>
  2. #include <tcp.h>
  3. #include <HTAccess.h>
  4. #include <HTList.h>
  5. #include <HTAlert.h>
  6. #include <HTFile.h>
  7. #include <LYCurses.h>
  8. #include <GridText.h>
  9. #include <LYUtils.h>
  10. #include <LYPrint.h>
  11. #include <LYGlobalDefs.h>
  12. #include <LYSignal.h>
  13. #include <LYStrings.h>
  14. #include <LYClean.h>
  15. #include <LYGetFile.h>
  16. #include <LYHistory.h>
  17. #include <LYSystem.h>
  18. #include <LYList.h>
  19. #include <LYCharSets.h>  /* To get current charset for mail header. */
  20. #ifdef VMS
  21. #include <HTVMSUtils.h>
  22. #endif /* VMS */
  23. #ifdef DOSPATH
  24. #include <HTDOS.h>
  25. #endif
  26.  
  27. #include <LYLeaks.h>
  28.  
  29. #define FREE(x) if (x) {free(x); x = NULL;}
  30.  
  31. /*
  32.  *  printfile prints out the current file minus the links and targets
  33.  *  to a veriaty of places
  34.  */
  35.  
  36. /* it parses an incoming link that looks like
  37.  *
  38.  *  LYNXPRINT://LOCAL_FILE/lines=##
  39.  *  LYNXPRINT://MAIL_FILE/lines=##
  40.  *  LYNXPRINT://TO_SCREEN/lines=##
  41.  *  LYNXPRINT://LPANSI/lines=##
  42.  *  LYNXPRINT://PRINTER/lines=##/number=#
  43.  */
  44.  
  45. #define TO_FILE   1
  46. #define TO_SCREEN 2
  47. /*
  48.  * "lpansi.c"
  49.  * Original author: Gary Day (gday@comp.uark.edu), 11/30/93
  50.  * Current version: 2.1 by Noel Hunter (noel@wfu.edu), 10/20/94
  51.  *
  52.  * Basic structure based on print -- format files for printing from
  53.  * _Practical_C_Programming by Steve Oualline, O'Reilly & Associates
  54.  *
  55.  * adapted from the README for lpansi.c v2.1, dated 10/20/1994:
  56.  *            Print to ANSI printer on local terminal
  57.  *     The VT100 standard defines printer on and off escape sequences,
  58.  *     esc[5i is printer on, and esc[4i is printer off.
  59.  *
  60.  * incorporate the idea of "lpansi" directly into LYPrint.c - HN
  61.  */
  62. #define LPANSI    3
  63. #define MAIL      4
  64. #define PRINTER   5
  65.  
  66. #ifdef VMS
  67. PRIVATE int remove_quotes PARAMS((char *string));
  68. #endif /* VMS */
  69.  
  70. PUBLIC int printfile ARGS1(
  71.     document *,    newdoc)
  72. {
  73.     static char tempfile[256];
  74.     static BOOLEAN first = TRUE;
  75.     char buffer[LINESIZE];
  76.     char filename[LINESIZE];
  77.     char user_response[256];
  78.     int lines_in_file = 0;
  79.     int printer_number = 0;
  80.     int pages = 0;
  81.     int type = 0, c, len;
  82.     BOOLEAN Lpansi = FALSE;
  83.     FILE *outfile_fp;
  84.     char *cp = NULL;
  85.     lynx_printer_item_type *cur_printer;
  86.     char *sug_filename = NULL;
  87.     char *link_info = NULL;
  88.     DocAddress WWWDoc;
  89.     int pagelen = 0;
  90.     int ch, recall;
  91.     int FnameTotal;
  92.     int FnameNum;
  93.     BOOLEAN FirstRecall = TRUE;
  94.     char *content_base = NULL, *content_location = NULL;
  95.     HTFormat format;
  96.     HTAtom *encoding;
  97.     BOOL use_mime, use_cte, use_type;
  98.     CONST char *disp_charset;
  99.     static BOOLEAN first_mail_preparsed = TRUE;
  100.     char *envbuffer = NULL;
  101. #ifdef VMS
  102.     BOOLEAN isPMDF = FALSE;
  103.     char hdrfile[256];
  104.     FILE *hfd;
  105.  
  106.     if (!strncasecomp(system_mail, "PMDF SEND", 9)) {
  107.     isPMDF = TRUE;
  108.     }
  109. #endif /* VMS */
  110.  
  111.     /*
  112.      *    Extract useful info from URL.
  113.      */
  114.     StrAllocCopy(link_info, newdoc->address+12);
  115.  
  116.     /*
  117.      *    Reload the file we want to print into memory.
  118.      */
  119.     LYpop(newdoc);
  120.     WWWDoc.address = newdoc->address;
  121.     WWWDoc.post_data = newdoc->post_data;
  122.     WWWDoc.post_content_type = newdoc->post_content_type;
  123.     WWWDoc.bookmark = newdoc->bookmark;
  124.     WWWDoc.isHEAD = newdoc->isHEAD;
  125.     WWWDoc.safe = newdoc->safe;
  126.     if (!HTLoadAbsolute(&WWWDoc))
  127.     return(NOT_FOUND);
  128.  
  129.     /*
  130.      *    If we have an explicit content-base, we may use it even
  131.      *    if not in source mode. - kw
  132.      */
  133.     if (HText_getContentBase()) {
  134.     StrAllocCopy(content_base, HText_getContentBase());
  135.     LYRemoveBlanks(content_base);
  136.     if (!(content_base && *content_base)) {
  137.         FREE(content_base);
  138.     }
  139.     }
  140.     /*
  141.      *    If document is source, load the content_base
  142.      *    and content_location strings. - FM
  143.      */
  144.     if (HTisDocumentSource()) {
  145.     if (HText_getContentLocation()) {
  146.         StrAllocCopy(content_location, HText_getContentLocation());
  147.         LYRemoveBlanks(content_location);
  148.         if (!(content_location && *content_location)) {
  149.         FREE(content_location);
  150.         }
  151.     }
  152.     if (!content_base) {
  153.         if ((content_location) && is_url(content_location)) {
  154.         StrAllocCopy(content_base, content_location);
  155.         } else {
  156.         StrAllocCopy(content_base, newdoc->address);
  157.         }
  158.     }
  159.     if (!content_location) {
  160.         StrAllocCopy(content_location, newdoc->address);
  161.     }
  162.     }
  163.  
  164.     /*
  165.      *    Load the suggested filename string. - FM
  166.      */
  167.     if (HText_getSugFname() != 0)
  168.     StrAllocCopy(sug_filename, HText_getSugFname()); /* must be freed */
  169.     else
  170.     StrAllocCopy(sug_filename, newdoc->address); /* must be freed */
  171.     /*
  172.      *    Strip any gzip or compress suffix, if present. - FM
  173.      */
  174.     cp = NULL;
  175.     if (strlen(sug_filename) > 3) {
  176.     cp = (char *)&sug_filename[(strlen(sug_filename) - 3)];
  177.     if ((*cp == '.' || *cp == '-' || *cp == '_') &&
  178.         !strcasecomp((cp + 1), "gz")) {
  179.         *cp = '\0';
  180.     } else {
  181.         cp = NULL;
  182.     }
  183.     }
  184.     if ((cp == NULL) && strlen(sug_filename) > 2) {
  185.     cp = (char *)&sug_filename[(strlen(sug_filename) - 2)];
  186.     if ((*cp == '.' || *cp == '-' || *cp == '_') &&
  187.         !strcasecomp((cp + 1), "Z")) {
  188.         *cp = '\0';
  189.     }
  190.     }
  191.     cp = NULL;
  192.  
  193.     /*
  194.      *    Get the number of lines in the file.
  195.      */
  196.     if ((cp = (char *)strstr(link_info, "lines=")) != NULL) {
  197.     /*
  198.      *  Terminate prev string here.
  199.      */
  200.     *cp = '\0';
  201.     /*
  202.      *  Number of characters in "lines=".
  203.      */
  204.     cp += 6;
  205.  
  206.     lines_in_file = atoi(cp);
  207.     pages = lines_in_file/66;
  208.     }
  209.  
  210.     /*
  211.      *    Determine the type.
  212.      */
  213.     if (strstr(link_info, "LOCAL_FILE")) {
  214.     type = TO_FILE;
  215.     } else if (strstr(link_info, "TO_SCREEN")) {
  216.     type = TO_SCREEN;
  217.     } else if (strstr(link_info, "LPANSI")) {
  218.     Lpansi = TRUE;
  219.     type = TO_SCREEN;
  220.     } else if (strstr(link_info, "MAIL_FILE")) {
  221.     type = MAIL;
  222.     } else if (strstr(link_info, "PRINTER")) {
  223.     type = PRINTER;
  224.  
  225.     if ((cp = (char *)strstr(link_info, "number=")) != NULL) {
  226.         /* number of characters in "number=" */
  227.         cp += 7;
  228.         printer_number = atoi(cp);
  229.     }
  230.     if ((cp = (char *)strstr(link_info, "pagelen=")) != NULL) {
  231.         /* number of characters in "pagelen=" */
  232.         cp += 8;
  233.         pagelen = atoi(cp);
  234.     } else {
  235.         /* default to 66 lines */
  236.         pagelen = 66;
  237.     }
  238.     }
  239.  
  240.     /*
  241.      *    Set up the sug_filenames recall buffer.
  242.      */
  243.     FnameTotal = (sug_filenames ? HTList_count(sug_filenames) : 0);
  244.     recall = ((FnameTotal >= 1) ? RECALL : NORECALL);
  245.     FnameNum = FnameTotal;
  246.  
  247.     /*
  248.      *    Act on the request. - FM
  249.      */
  250.     switch (type) {
  251.     case TO_FILE:
  252. #if defined(__DJGPP__) || defined(_WINDOWS)
  253.         _fmode = O_TEXT;
  254. #endif /* __DJGPP__  or _WINDOWS */
  255.         _statusline(FILENAME_PROMPT);
  256.     retry:    strcpy(filename, sug_filename);  /* add suggestion info */
  257.         /* make the sug_filename conform to system specs */
  258.         change_sug_filename(filename);
  259.         if (!(HTisDocumentSource()) &&
  260.             (cp = strrchr(filename, '.')) != NULL) {
  261.             format = HTFileFormat(filename, &encoding, NULL);
  262.             if (!strcasecomp(format->name, "text/html") ||
  263.             !IsUnityEnc(encoding)) {
  264.             *cp = '\0';
  265.             strcat(filename, ".txt");
  266.             }
  267.         }
  268.         if (lynx_save_space && *lynx_save_space) {
  269.             strcpy(buffer, lynx_save_space);
  270.             strcat(buffer, filename);
  271.             strcpy(filename, buffer);
  272.         }
  273.     check_recall:
  274.         if ((ch = LYgetstr(filename, VISIBLE,
  275.                    sizeof(filename), recall)) < 0 ||
  276.             *filename == '\0' || ch == UPARROW || ch == DNARROW) {
  277.             if (recall && ch == UPARROW) {
  278.             if (FirstRecall) {
  279.                 FirstRecall = FALSE;
  280.                 /*
  281.                  *    Use the last Fname in the list. - FM
  282.                  */
  283.                 FnameNum = 0;
  284.             } else {
  285.                 /*
  286.                  *    Go back to the previous Fname
  287.                  *    in the list. - FM
  288.                  */
  289.                 FnameNum++;
  290.             }
  291.             if (FnameNum >= FnameTotal) {
  292.                 /*
  293.                  *    Reset the FirstRecall flag,
  294.                  *    and use sug_file or a blank. - FM
  295.                  */
  296.                 FirstRecall = TRUE;
  297.                 FnameNum = FnameTotal;
  298.                 _statusline(FILENAME_PROMPT);
  299.                 goto retry;
  300.             } else if ((cp = (char *)HTList_objectAt(
  301.                             sug_filenames,
  302.                             FnameNum)) != NULL) {
  303.                 strcpy(filename, cp);
  304.                 if (FnameTotal == 1) {
  305.                 _statusline(EDIT_THE_PREV_FILENAME);
  306.                 } else {
  307.                 _statusline(EDIT_A_PREV_FILENAME);
  308.                 }
  309.                 goto check_recall;
  310.             }
  311.             } else if (recall && ch == DNARROW) {
  312.             if (FirstRecall) {
  313.                 FirstRecall = FALSE;
  314.                 /*
  315.                  * Use the first Fname in the list. - FM
  316.                  */
  317.                 FnameNum = FnameTotal - 1;
  318.             } else {
  319.                 /*
  320.                  * Advance to the next Fname in the list. - FM
  321.                  */
  322.                 FnameNum--;
  323.             }
  324.             if (FnameNum < 0) {
  325.                 /*
  326.                  *    Set the FirstRecall flag,
  327.                  *    and use sug_file or a blank. - FM
  328.                  */
  329.                 FirstRecall = TRUE;
  330.                 FnameNum = FnameTotal;
  331.                 _statusline(FILENAME_PROMPT);
  332.                 goto retry;
  333.             } else if ((cp = (char *)HTList_objectAt(
  334.                             sug_filenames,
  335.                             FnameNum)) != NULL) {
  336.                 strcpy(filename, cp);
  337.                 if (FnameTotal == 1) {
  338.                 _statusline(EDIT_THE_PREV_FILENAME);
  339.                 } else {
  340.                 _statusline(EDIT_A_PREV_FILENAME);
  341.                 }
  342.                 goto check_recall;
  343.             }
  344.             }
  345.  
  346.             /*
  347.              *    Save cancelled.
  348.              */
  349.             _statusline(SAVE_REQUEST_CANCELLED);
  350.             sleep(InfoSecs);
  351.             break;
  352.         }
  353.  
  354.         if (no_dotfiles || !show_dotfiles) {
  355.             if (*filename == '.' ||
  356. #ifdef VMS
  357.             ((cp = strrchr(filename, ':')) && *(cp+1) == '.') ||
  358.             ((cp = strrchr(filename, ']')) && *(cp+1) == '.') ||
  359. #endif /* VMS */
  360.             ((cp = strrchr(filename, '/')) && *(cp+1) == '.')) {
  361.             HTAlert(FILENAME_CANNOT_BE_DOT);
  362.             _statusline(NEW_FILENAME_PROMPT);
  363.             FirstRecall = TRUE;
  364.             FnameNum = FnameTotal;
  365.             goto retry;
  366.             }
  367.         }
  368.         /*
  369.          *  Cancel if the user entered "/dev/null" on Unix,
  370.          *  or an "nl:" path (case-insensitive) on VMS. - FM
  371.          */
  372. #ifdef VMS
  373.         if (!strncasecomp(filename, "nl:", 3) ||
  374.             !strncasecomp(filename, "/nl/", 4))
  375. #else
  376.         if (!strcmp(filename, "/dev/null"))
  377. #endif /* VMS */
  378.         {
  379.             _statusline(SAVE_REQUEST_CANCELLED);
  380.             sleep(InfoSecs);
  381.             break;
  382.         }
  383.         if ((cp = strchr(filename, '~'))) {
  384.             *(cp++) = '\0';
  385.             strcpy(buffer, filename);
  386.             if ((len=strlen(buffer)) > 0 && buffer[len-1] == '/')
  387.             buffer[len-1] = '\0';
  388. #ifdef DOSPATH
  389.             strcat(buffer, HTDOS_wwwName((char *)Home_Dir()));
  390. #else
  391. #ifdef VMS
  392.             strcat(buffer, HTVMS_wwwName((char *)Home_Dir()));
  393. #else
  394.             strcat(buffer, Home_Dir());
  395. #endif /* VMS */
  396. #endif /* DOSPATH */
  397.             strcat(buffer, cp);
  398.             strcpy(filename, buffer);
  399.         }
  400. #ifdef VMS
  401.         if (strchr(filename, '/') != NULL) {
  402.             strcpy(buffer, HTVMS_name("", filename));
  403.             strcpy(filename, buffer);
  404.         }
  405.         if (filename[0] != '/' && strchr(filename, ':') == NULL) {
  406.             strcpy(buffer, "sys$disk:");
  407.             if (strchr(filename, ']') == NULL)
  408.             strcat(buffer, "[]");
  409.             strcat(buffer, filename);
  410.         } else {
  411.             strcpy(buffer, filename);
  412.         }
  413. #else
  414. #ifndef __EMX__
  415.         if (*filename != '/')
  416.             cp = getenv("PWD");
  417.         else
  418. #endif
  419.             cp = NULL;
  420.         if (cp)
  421. #ifdef DOSPATH
  422.             sprintf(buffer, "%s/%s", cp, HTDOS_name(filename));
  423. #else
  424.             sprintf(buffer, "%s/%s", cp, filename);
  425. #endif
  426.         else
  427. #ifdef DOSPATH
  428.             strcpy(buffer, HTDOS_name(filename));
  429. #else
  430.             strcpy(buffer, filename);
  431. #endif
  432. #endif /* VMS */
  433.  
  434.         /*
  435.          *  See if it already exists.
  436.          */
  437.         if ((outfile_fp = fopen(buffer, "r")) != NULL) {
  438.             fclose(outfile_fp);
  439. #ifdef VMS
  440.             _statusline(FILE_EXISTS_HPROMPT);
  441. #else
  442.             _statusline(FILE_EXISTS_OPROMPT);
  443. #endif /* VMS */
  444.             c = 0;
  445.             while (TOUPPER(c)!='Y' && TOUPPER(c)!='N' &&
  446.                c != 7 && c != 3)
  447.             c = LYgetch();
  448. #ifdef VMS
  449.             if (HadVMSInterrupt) {
  450.             HadVMSInterrupt = FALSE;
  451.             _statusline(SAVE_REQUEST_CANCELLED);
  452.             sleep(InfoSecs);
  453.             break;
  454.             }
  455. #endif /* VMS */
  456.             if (c == 7 || c == 3) { /* Control-G or Control-C */
  457.             _statusline(SAVE_REQUEST_CANCELLED);
  458.             sleep(InfoSecs);
  459.             break;
  460.             }
  461.             if (TOUPPER(c) == 'N') {
  462.             _statusline(NEW_FILENAME_PROMPT);
  463.             FirstRecall = TRUE;
  464.             FnameNum = FnameTotal;
  465.             goto retry;
  466.             }
  467.         }
  468.  
  469.         if ((outfile_fp = LYNewTxtFile(buffer)) == NULL) {
  470.             HTAlert(CANNOT_WRITE_TO_FILE);
  471.             _statusline(NEW_FILENAME_PROMPT);
  472.             FirstRecall = TRUE;
  473.             FnameNum = FnameTotal;
  474.             goto retry;
  475.         }
  476.  
  477.         if (LYPrependBaseToSource && HTisDocumentSource()) {
  478.             /*
  479.              *    Added the document's base as a BASE tag
  480.              *    to the top of the file.  May create
  481.              *    technically invalid HTML, but will help
  482.              *    get any partial or relative URLs resolved
  483.              *    properly if no BASE tag is present to
  484.              *    replace it. - FM
  485.              */
  486.             fprintf(outfile_fp,
  487.                 "<!-- X-URL: %s -->\n<BASE HREF=\"%s\">\n",
  488.                 newdoc->address, content_base);
  489.         }
  490.  
  491.         if (LYPrependCharsetToSource && HTisDocumentSource()) {
  492.             /*
  493.              *    Added the document's charset as a META CHARSET tag
  494.              *    to the top of the file.  May create
  495.              *    technically invalid HTML, but will help to resolve
  496.              *    properly the document converted via chartrans:
  497.              *    printed document correspond to a display charset
  498.              *    and we *should* override both assume_local_charset
  499.              *    and original document's META CHARSET (if any).
  500.              *
  501.              *    Currently, if several META CHARSETs are found Lynx uses
  502.              *    the first only, and it is opposite to BASE where the
  503.              *    original BASE in the <HEAD> overrides ones from the
  504.              *    top.
  505.              *
  506.              *    As in print-to-email we write charset only if the
  507.              *    document has 8-bit characters, and we have no CJK or an
  508.              *    unofficial "x-" charset.
  509.              */
  510.              use_cte = HTLoadedDocumentEightbit();
  511.              disp_charset = LYCharSet_UC[current_char_set].MIMEname;
  512.              if (!use_cte || LYHaveCJKCharacterSet ||
  513.               strncasecomp(disp_charset, "x-", 2) == 0) {
  514.              } else {
  515.             fprintf(outfile_fp,
  516.                 "<META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html; charset=%s\">\n\n",
  517.                 disp_charset);
  518.             }
  519.         }
  520.  
  521.         print_wwwfile_to_fd(outfile_fp,0);
  522.         if (keypad_mode)
  523.             printlist(outfile_fp,FALSE);
  524.  
  525.         fclose(outfile_fp);
  526. #ifdef VMS
  527.         if (0 == strncasecomp(buffer, "sys$disk:", 9)) {
  528.             if (0 == strncmp((buffer+9), "[]", 2)) {
  529.             HTAddSugFilename(buffer+11);
  530.             } else {
  531.             HTAddSugFilename(buffer+9);
  532.             }
  533.         } else {
  534.             HTAddSugFilename(buffer);
  535.         }
  536. #else
  537.         HTAddSugFilename(buffer);
  538. #endif /* VMS */
  539. #if defined(__DJGPP__) || defined(_WINDOWS)
  540.         _fmode = O_BINARY;
  541. #endif /* __DJGPP__ or _WINDOWS */
  542.         break;
  543.  
  544.     case MAIL:
  545.         if (LYPreparsedSource && first_mail_preparsed &&
  546.         HTisDocumentSource()) {
  547.         _statusline(CONFIRM_MAIL_SOURCE_PREPARSED);
  548.         c = 0;
  549.         while (TOUPPER(c)!='Y' && TOUPPER(c)!='N' &&
  550.                c != 7 && c != 3)
  551.             c = LYgetch();
  552. #ifdef VMS
  553.         if (HadVMSInterrupt) {
  554.             HadVMSInterrupt = FALSE;
  555.             _statusline(MAIL_REQUEST_CANCELLED);
  556.             sleep(InfoSecs);
  557.             break;
  558.         }
  559. #endif /* VMS */
  560.         if (c == RTARROW || c == 'y' || c== 'Y'
  561.             || c == '\n' || c == '\r') {
  562.             addstr("   Ok...");
  563.             first_mail_preparsed = FALSE;
  564.         } else    {
  565.             _statusline(MAIL_REQUEST_CANCELLED);
  566.             sleep(InfoSecs);
  567.             break;
  568.         }
  569.         }
  570.  
  571.         _statusline(MAIL_ADDRESS_PROMPT);
  572.         strcpy(user_response, (personal_mail_address ?
  573.                        personal_mail_address : ""));
  574.         if (LYgetstr(user_response, VISIBLE,
  575.                  sizeof(user_response), NORECALL) < 0 ||
  576.             *user_response == '\0') {
  577.             _statusline(MAIL_REQUEST_CANCELLED);
  578.             sleep(InfoSecs);
  579.             break;
  580.         }
  581.  
  582.         /*
  583.          *  Determine which mail headers should be sent.
  584.          *  Use Content-Type and MIME-Version headers only
  585.          *  if needed.    We need them if we are mailing HTML
  586.          *  source, or if we have 8-bit characters and will
  587.          *  be sending Content-Transfer-Encoding to indicate
  588.          *  this.  We will append a charset parameter to the
  589.          *  Content-Type if we do not have an "x-" charset,
  590.          *  and we will include the Content-Transfer-Encoding
  591.          *  only if we are appending the charset parameter,
  592.          *  because indicating an 8-bit transfer without also
  593.          *  indicating the charset can cause problems with
  594.          *  many mailers. - FM & KW
  595.          */
  596.         disp_charset = LYCharSet_UC[current_char_set].MIMEname;
  597.         use_cte = HTLoadedDocumentEightbit();
  598.         if (!(use_cte && strncasecomp(disp_charset, "x-", 2))) {
  599.             disp_charset = NULL;
  600.             use_cte = FALSE;
  601.         }
  602.         use_type =  (disp_charset || HTisDocumentSource());
  603.  
  604.         change_sug_filename(sug_filename);
  605. #ifdef VMS
  606.         if (strchr(user_response,'@') && !strchr(user_response,':') &&
  607.            !strchr(user_response,'%') && !strchr(user_response,'"')) {
  608.             sprintf(filename, mail_adrs, user_response);
  609.             strcpy(user_response, filename);
  610.         }
  611.  
  612.         if (first) {
  613.             tempname(tempfile, NEW_FILE);
  614.             if (isPMDF) {
  615.             tempname(hdrfile, NEW_FILE);
  616.             if ((len = strlen(hdrfile)) > 4) {
  617.                 len -= 5;
  618.                 if (!strcasecomp((hdrfile + len), ".html")) {
  619.                 hdrfile[len] = '\0';
  620.                 strcat(hdrfile, ".txt");
  621.                 }
  622.             }
  623.             }
  624.             first = FALSE;
  625.         } else {
  626.             remove(tempfile);    /* remove duplicates */
  627.         }
  628.         if (HTisDocumentSource()) {
  629.             if ((len = strlen(tempfile)) > 3) {
  630.             len -= 4;
  631.             if (!strcasecomp((tempfile + len), ".txt")) {
  632.                 tempfile[len] = '\0';
  633.                 strcat(tempfile, ".html");
  634.             }
  635.             }
  636.         } else if ((len = strlen(tempfile)) > 4) {
  637.             len -= 5;
  638.             if (!strcasecomp((tempfile + len), ".html")) {
  639.             tempfile[len] = '\0';
  640.             strcat(tempfile, ".txt");
  641.             }
  642.         }
  643.         if ((outfile_fp = LYNewTxtFile(tempfile)) == NULL) {
  644.             HTAlert(UNABLE_TO_OPEN_TEMPFILE);
  645.             break;
  646.         }
  647.  
  648.         if (isPMDF) {
  649.             if ((hfd = LYNewTxtFile(hdrfile)) == NULL) {
  650.             HTAlert(UNABLE_TO_OPEN_TEMPFILE);
  651.             break;
  652.             }
  653.             if (use_type) {
  654.             fprintf(hfd, "Mime-Version: 1.0\n");
  655.             if (use_cte) {
  656.                 fprintf(hfd,
  657.                     "Content-Transfer-Encoding: 8bit\n");
  658.             }
  659.             }
  660.             if (HTisDocumentSource()) {
  661.             /*
  662.              *  Add Content-Type, Content-Location, and
  663.              *  Content-Base headers for HTML source. - FM
  664.              */
  665.             fprintf(hfd, "Content-Type: text/html");
  666.             if (disp_charset != NULL) {
  667.                 fprintf(hfd,
  668.                     "; charset=%s\n",
  669.                     disp_charset);
  670.             } else {
  671.                 fprintf(hfd, "\n");
  672.             }
  673.             fprintf(hfd,
  674.                 "Content-Base: %s\n",
  675.                 content_base);
  676.             fprintf(hfd,
  677.                 "Content-Location: %s\n",
  678.                 content_location);
  679.             } else {
  680.             /*
  681.              *  Add Content-Type: text/plain if we have 8-bit
  682.              *  characters and a valid charset for non-source
  683.              *  documents. - FM
  684.              */
  685.             if (disp_charset != NULL) {
  686.                 fprintf(hfd,
  687.                     "Content-Type: text/plain; charset=%s\n",
  688.                     disp_charset);
  689.             }
  690.             }
  691.             /*
  692.              *    X-URL header. - FM
  693.              */
  694.             fprintf(hfd, "X-URL: %s\n", newdoc->address);
  695.         }
  696.  
  697.         /*
  698.          *  Write the contents to a temp file.
  699.          */
  700.         if (LYPrependBaseToSource && HTisDocumentSource()) {
  701.             /*
  702.              *    Added the document's base as a BASE tag to
  703.              *    the top of the message body.  May create
  704.              *    technically invalid HTML, but will help
  705.              *    get any partial or relative URLs resolved
  706.              *    properly if no BASE tag is present to
  707.              *    replace it. - FM
  708.              */
  709.             fprintf(outfile_fp,
  710.                 "<!-- X-URL: %s -->\n<BASE HREF=\"%s\">\n\n",
  711.                 newdoc->address, content_base);
  712.         } else if (!isPMDF) {
  713.             fprintf(outfile_fp, "X-URL: %s\n\n", newdoc->address);
  714.         }
  715.         print_wwwfile_to_fd(outfile_fp, 0);
  716.         if (keypad_mode)
  717.             printlist(outfile_fp, FALSE);
  718.         fclose(outfile_fp);
  719.  
  720.         if (isPMDF) {
  721.             /*
  722.              *    For PMDF, put the subject in the
  723.              *    header file and close it. - FM
  724.              */
  725.             fprintf(hfd, "Subject: %.70s\n\n", sug_filename);
  726.             fclose(hfd);
  727.             /*
  728.              *    Now set up the command. - FM
  729.              */
  730.             sprintf(buffer,
  731.                 "%s %s %s,%s %s",
  732.                 system_mail,
  733.                 system_mail_flags,
  734.                 hdrfile,
  735.                 tempfile,
  736.                 user_response);
  737.         } else {
  738.             /*
  739.              *    For "generic" VMS MAIL, include
  740.              *    the subject in the command. - FM
  741.              */
  742.             remove_quotes(sug_filename);
  743.             sprintf(buffer,
  744.                 "%s %s/subject=\"%.70s\" %s %s",
  745.                 system_mail,
  746.                 system_mail_flags,
  747.                 sug_filename,
  748.                 tempfile,
  749.                 user_response);
  750.         }
  751.  
  752.         stop_curses();
  753.         printf(MAILING_FILE);
  754.         fflush(stdout);
  755.         system(buffer);
  756.         fflush(stdout);
  757.         sleep(AlertSecs);
  758.         start_curses();
  759.         if (isPMDF) {
  760.             /*
  761.              *    Delete the header file. - FM
  762.              */
  763.             remove(hdrfile);
  764.         }
  765. #else /* Unix: */
  766.         sprintf(buffer, "%s %s", system_mail, system_mail_flags);
  767.  
  768. #ifdef DOSPATH
  769.         sprintf(tempfile, "%s%s", lynx_temp_space, "temp_mail.txt");
  770.         if ((outfile_fp = LYNewTxtFile(tempfile)) == NULL) {
  771.             _statusline(MAIL_REQUEST_FAILED);
  772.             sleep(AlertSecs);
  773.             return;
  774.         }
  775. #else
  776.         if ((outfile_fp = popen(buffer, "w")) == NULL) {
  777.             _statusline(MAIL_REQUEST_FAILED);
  778.             sleep(AlertSecs);
  779.             break;
  780.         }
  781. #endif
  782.  
  783.         /*
  784.          *  Determine which mail headers should be sent.
  785.          *  Use Content-Type and MIME-Version headers only
  786.          *  if needed.    We need them if we are mailing HTML
  787.          *  source, or if we have 8-bit characters and will
  788.          *  be sending Content-Transfer-Encoding to indicate
  789.          *  this.
  790.          *
  791.          *  Send Content-Transfer-Encoding only if the document
  792.          *  has 8-bit characters.  Send a charset parameter only
  793.          *  if the document has 8-bit characters and we we seem
  794.          *  to have a valid charset.  - kw
  795.          */
  796.         use_cte = HTLoadedDocumentEightbit();
  797.         disp_charset = LYCharSet_UC[current_char_set].MIMEname;
  798.         /*
  799.          *  Don't send a charset if we have a CJK character set
  800.          *  selected, since it may not be appropriate for mail...
  801.          *  Also don't use an inofficial "x-" charset. - kw
  802.          */
  803.         if (!use_cte || LYHaveCJKCharacterSet ||
  804.             strncasecomp(disp_charset, "x-", 2) == 0) {
  805.             disp_charset = NULL;
  806.         }
  807. #ifdef NOTDEFINED
  808.         /*  Enable this if indicating an 8-bit transfer without
  809.          *  also indicating the charset causes problems. - kw */
  810.         if (use_cte && !disp_charse)
  811.             use_cte = FALSE;
  812. #endif /* NOTDEFINED */
  813.         use_type =  (disp_charset || HTisDocumentSource());
  814.         use_mime = (use_cte || use_type);
  815.  
  816.         if (use_mime) {
  817.             fprintf(outfile_fp, "Mime-Version: 1.0\n");
  818.             if (use_cte) {
  819.             fprintf(outfile_fp,
  820.                 "Content-Transfer-Encoding: 8bit\n");
  821.             }
  822.         }
  823.  
  824.         if (HTisDocumentSource()) {
  825.             /*
  826.              *    Add Content-Type, Content-Location, and
  827.              *    Content-Base headers for HTML source. - FM
  828.              */
  829.             fprintf(outfile_fp, "Content-Type: text/html");
  830.             if (disp_charset != NULL) {
  831.             fprintf(outfile_fp, "; charset=%s\n",
  832.                         disp_charset);
  833.             } else {
  834.             fprintf(outfile_fp, "\n");
  835.             }
  836.         } else {
  837.             /*
  838.              *    Add Content-Type: text/plain if we have 8-bit
  839.              *    characters and a valid charset for non-source
  840.              *    documents. - KW
  841.              */
  842.             if (disp_charset != NULL) {
  843.             fprintf(outfile_fp,
  844.                 "Content-Type: text/plain; charset=%s\n",
  845.                 disp_charset);
  846.             }
  847.         }
  848.         /*
  849.          *  If we are using MIME headers, add content-base and
  850.          *  content-location if we have them.  This will always
  851.          *  be the case if the document is source. - kw
  852.          */
  853.         if (use_mime) {
  854.             if (content_base)
  855.             fprintf(outfile_fp, "Content-Base: %s\n",
  856.                 content_base);
  857.             if (content_location)
  858.             fprintf(outfile_fp, "Content-Location: %s\n",
  859.                 content_location);
  860.         }
  861.  
  862.         /*
  863.          *  Add the To, Subject, and X-URL headers. - FM
  864.          */
  865.         fprintf(outfile_fp, "To: %s\nSubject: %s\n",
  866.                      user_response, sug_filename);
  867.         fprintf(outfile_fp, "X-URL: %s\n\n", newdoc->address);
  868.         if (LYPrependBaseToSource && HTisDocumentSource()) {
  869.             /*
  870.              *    Added the document's base as a BASE tag to
  871.              *    the top of the message body.  May create
  872.              *    technically invalid HTML, but will help
  873.              *    get any partial or relative URLs resolved
  874.              *    properly if no BASE tag is present to
  875.              *    replace it. - FM
  876.              */
  877.             fprintf(outfile_fp,
  878.                 "<!-- X-URL: %s -->\n<BASE HREF=\"%s\">\n\n",
  879.                 newdoc->address, content_base);
  880.         }
  881.         print_wwwfile_to_fd(outfile_fp, 0);
  882.         if (keypad_mode)
  883.             printlist(outfile_fp, FALSE);
  884.  
  885. #ifdef DOSPATH
  886.         sprintf(buffer, "%s -t \"%s\" -F %s", system_mail, user_response, tempfile);
  887.         fclose(outfile_fp);    /* Close the tmpfile. */
  888.         stop_curses();
  889.         printf("Sending \n\n$ %s\n\nPlease wait...", buffer);
  890.         system(buffer);
  891.         sleep(MessageSecs);
  892.         start_curses();
  893.         remove(tempfile);    /* Delete the tmpfile. */
  894. #else
  895.         pclose(outfile_fp);
  896. #endif
  897. #endif /* VMS */
  898.         break;
  899.  
  900.     case TO_SCREEN:
  901.         pages = lines_in_file/(LYlines+1);
  902.         /* count fractional pages ! */
  903.         if ((lines_in_file % (LYlines+1)) > 0)
  904.             pages++;
  905.         if (pages > 4) {
  906.             sprintf(filename, CONFIRM_LONG_SCREEN_PRINT, pages);
  907.             _statusline(filename);
  908.             c = LYgetch();
  909. #ifdef VMS
  910.             if (HadVMSInterrupt) {
  911.             HadVMSInterrupt = FALSE;
  912.             _statusline(PRINT_REQUEST_CANCELLED);
  913.             sleep(InfoSecs);
  914.             break;
  915.             }
  916. #endif /* VMS */
  917.             if (c == RTARROW || c == 'y' || c== 'Y'
  918.              || c == '\n' || c == '\r') {
  919.             addstr("   Ok...");
  920.             } else {
  921.             _statusline(PRINT_REQUEST_CANCELLED);
  922.             sleep(InfoSecs);
  923.             break;
  924.             }
  925.         }
  926.  
  927.         if (Lpansi) {
  928.               _statusline(CHECK_PRINTER);
  929.         } else    {
  930.               _statusline(PRESS_RETURN_TO_BEGIN);
  931.         }
  932.         *filename = '\0';
  933.         if (LYgetstr(filename, VISIBLE,
  934.                  sizeof(filename), NORECALL) < 0) {
  935.               _statusline(PRINT_REQUEST_CANCELLED);
  936.               sleep(InfoSecs);
  937.               break;
  938.         }
  939.  
  940.         outfile_fp = stdout;
  941.  
  942.         stop_curses();
  943. #ifndef VMS
  944.         signal(SIGINT, SIG_IGN);
  945. #endif /* !VMS */
  946.  
  947.         if (LYPrependBaseToSource && HTisDocumentSource()) {
  948.             /*
  949.              *    Added the document's base as a BASE tag
  950.              *    to the top of the file.  May create
  951.              *    technically invalid HTML, but will help
  952.              *    get any partial or relative URLs resolved
  953.              *    properly if no BASE tag is present to
  954.              *    replace it. - FM
  955.              */
  956.             fprintf(outfile_fp,
  957.                 "<!-- X-URL: %s -->\n<BASE HREF=\"%s\">\n\n",
  958.                 newdoc->address, content_base);
  959.         }
  960.         if (Lpansi)
  961.             printf("\033[5i");
  962.         print_wwwfile_to_fd(outfile_fp, 0);
  963.         if (keypad_mode)
  964.             printlist(outfile_fp, FALSE);
  965.  
  966. #ifdef VMS
  967.         if (HadVMSInterrupt) {
  968.              HadVMSInterrupt = FALSE;
  969.              start_curses();
  970.              break;
  971.         }
  972. #endif /* VMS */
  973.         if (Lpansi) {
  974.              printf("\n\014");    /* Form feed */
  975.              printf("\033[4i");
  976.              Lpansi = FALSE;
  977.         } else {
  978.              fprintf(stdout,"\n\n%s", PRESS_RETURN_TO_FINISH);
  979.              LYgetch();  /* grab some user input to pause */
  980. #ifdef VMS
  981.              HadVMSInterrupt = FALSE;
  982. #endif /* VMS */
  983.         }
  984.         fflush(stdout);  /* refresh to screen */
  985.         start_curses();
  986.         break;
  987.  
  988.     case PRINTER:
  989.         pages = lines_in_file/pagelen;
  990.         /* count fractional pages ! */
  991.         if ((lines_in_file % pagelen) > 0)
  992.             pages++;
  993.         if (pages > 4) {
  994.             sprintf(filename, CONFIRM_LONG_PAGE_PRINT, pages);
  995.             _statusline(filename);
  996.             c=LYgetch();
  997. #ifdef VMS
  998.             if (HadVMSInterrupt) {
  999.             HadVMSInterrupt = FALSE;
  1000.             _statusline(PRINT_REQUEST_CANCELLED);
  1001.             sleep(InfoSecs);
  1002.             break;
  1003.             }
  1004. #endif /* VMS */
  1005.             if (c == RTARROW || c == 'y' || c== 'Y'
  1006.              || c == '\n' || c == '\r') {
  1007.             addstr("   Ok...");
  1008.             } else  {
  1009.             _statusline(PRINT_REQUEST_CANCELLED);
  1010.             sleep(InfoSecs);
  1011.             break;
  1012.             }
  1013.         }
  1014.  
  1015.         if (first) {
  1016.             tempname(tempfile, NEW_FILE);
  1017.             first = FALSE;
  1018.         } else {
  1019.             remove(tempfile);    /* Remove previous tempfile. */
  1020.         }
  1021.         if (((cp = strrchr(tempfile, '.')) != NULL) &&
  1022. #ifdef VMS
  1023.             NULL == strchr(cp, ']') &&
  1024. #endif /* VMS */
  1025.             NULL == strchr(cp, '/')) {
  1026.             if (HTisDocumentSource() &&
  1027.             strcasecomp(cp, HTML_SUFFIX)) {
  1028.             *cp = '\0';
  1029.             strcat(tempfile, HTML_SUFFIX);
  1030.             } else if (!HTisDocumentSource() &&
  1031.                    strcasecomp(cp, ".txt")) {
  1032.             *cp = '\0';
  1033.             strcat(tempfile, ".txt");
  1034.             }
  1035.         }
  1036.         if ((outfile_fp = LYNewTxtFile(tempfile)) == NULL) {
  1037.             HTAlert(FILE_ALLOC_FAILED);
  1038.             break;
  1039.         }
  1040.  
  1041.         if (LYPrependBaseToSource && HTisDocumentSource()) {
  1042.             /*
  1043.              *    Added the document's base as a BASE tag
  1044.              *    to the top of the file.  May create
  1045.              *    technically invalid HTML, but will help
  1046.              *    get any partial or relative URLs resolved
  1047.              *    properly if no BASE tag is present to
  1048.              *    replace it. - FM
  1049.              */
  1050.             fprintf(outfile_fp,
  1051.                 "<!-- X-URL: %s -->\n<BASE HREF=\"%s\">\n\n",
  1052.                 newdoc->address, content_base);
  1053.         }
  1054.         print_wwwfile_to_fd(outfile_fp, 0);
  1055.         if (keypad_mode)
  1056.             printlist(outfile_fp, FALSE);
  1057.  
  1058.         fclose(outfile_fp);
  1059.  
  1060.         /* find the right printer number */
  1061.         {
  1062.             int count=0;
  1063.             for (cur_printer = printers;
  1064.              count < printer_number;
  1065.              count++, cur_printer = cur_printer->next)
  1066.             ; /* null body */
  1067.         }
  1068.  
  1069.         /*
  1070.          *  Commands have the form "command %s [%s] [etc]"
  1071.          *  where %s is the filename and the second optional
  1072.          *  %s is the suggested filename.
  1073.          */
  1074.         if (cur_printer->command != NULL) {
  1075.             /*
  1076.              *    Check for two '%s' and ask for the second filename
  1077.              *    argument if there is.
  1078.              */
  1079.             char *first_s = strstr(cur_printer->command, "%s");
  1080.             if (first_s && strstr(first_s+1, "%s")) {
  1081.             _statusline(FILENAME_PROMPT);
  1082.         again:    strcpy(filename, sug_filename);
  1083.             change_sug_filename(filename);
  1084.             if (!(HTisDocumentSource()) &&
  1085.                 (cp = strrchr(filename, '.')) != NULL) {
  1086.                 format = HTFileFormat(filename, &encoding, NULL);
  1087.                 if (!strcasecomp(format->name, "text/html") ||
  1088.                 !IsUnityEnc(encoding)) {
  1089.                 *cp = '\0';
  1090.                 strcat(filename, ".txt");
  1091.                 }
  1092.             }
  1093.         check_again:
  1094.             if ((ch = LYgetstr(filename, VISIBLE,
  1095.                        sizeof(filename), recall)) < 0 ||
  1096.                 *filename == '\0' ||
  1097.                 ch == UPARROW || ch == DNARROW) {
  1098.                 if (recall && ch == UPARROW) {
  1099.                 if (FirstRecall) {
  1100.                     FirstRecall = FALSE;
  1101.                     /*
  1102.                      *    Use the last Fname in the list. - FM
  1103.                      */
  1104.                     FnameNum = 0;
  1105.                 } else {
  1106.                     /*
  1107.                      *    Go back to the previous Fname
  1108.                      *    in the list. - FM
  1109.                      */
  1110.                     FnameNum++;
  1111.                 }
  1112.                 if (FnameNum >= FnameTotal) {
  1113.                     /*
  1114.                      *    Reset the FirstRecall flag,
  1115.                      *    and use sug_file or a blank. - FM
  1116.                      */
  1117.                     FirstRecall = TRUE;
  1118.                     FnameNum = FnameTotal;
  1119.                     _statusline(FILENAME_PROMPT);
  1120.                     goto again;
  1121.                 } else if ((cp = (char *)HTList_objectAt(
  1122.                             sug_filenames,
  1123.                             FnameNum)) != NULL) {
  1124.                     strcpy(filename, cp);
  1125.                     if (FnameTotal == 1) {
  1126.                     _statusline(EDIT_THE_PREV_FILENAME);
  1127.                     } else {
  1128.                     _statusline(EDIT_A_PREV_FILENAME);
  1129.                     }
  1130.                     goto check_again;
  1131.                 }
  1132.                 } else if (recall && ch == DNARROW) {
  1133.                 if (FirstRecall) {
  1134.                     FirstRecall = FALSE;
  1135.                     /*
  1136.                      *    Use the first Fname in the list. - FM
  1137.                      */
  1138.                     FnameNum = FnameTotal - 1;
  1139.                 } else {
  1140.                     /*
  1141.                      *    Advance to the next Fname
  1142.                      *    in the list. - FM
  1143.                      */
  1144.                     FnameNum--;
  1145.                 }
  1146.                 if (FnameNum < 0) {
  1147.                     /*
  1148.                      *    Set the FirstRecall flag,
  1149.                      *    and use sug_file or a blank. - FM
  1150.                      */
  1151.                     FirstRecall = TRUE;
  1152.                     FnameNum = FnameTotal;
  1153.                     _statusline(FILENAME_PROMPT);
  1154.                     goto again;
  1155.                 } else if ((cp = (char *)HTList_objectAt(
  1156.                             sug_filenames,
  1157.                             FnameNum)) != NULL) {
  1158.                     strcpy(filename, cp);
  1159.                     if (FnameTotal == 1) {
  1160.                     _statusline(EDIT_THE_PREV_FILENAME);
  1161.                     } else {
  1162.                     _statusline(EDIT_A_PREV_FILENAME);
  1163.                     }
  1164.                     goto check_again;
  1165.                 }
  1166.                 }
  1167.  
  1168.                 /*
  1169.                  *    Printer cancelled.
  1170.                  */
  1171.                 _statusline(PRINT_REQUEST_CANCELLED);
  1172.                 sleep(InfoSecs);
  1173.                 break;
  1174.             }
  1175.  
  1176.             if (no_dotfiles || !show_dotfiles) {
  1177.                 if (*filename == '.' ||
  1178. #ifdef VMS
  1179.                    ((cp = strrchr(filename, ':')) &&
  1180.                         *(cp+1) == '.') ||
  1181.                    ((cp = strrchr(filename, ']')) &&
  1182.                         *(cp+1) == '.') ||
  1183. #endif /* VMS */
  1184.                    ((cp = strrchr(filename, '/')) &&
  1185.                         *(cp+1) == '.')) {
  1186.                 HTAlert(FILENAME_CANNOT_BE_DOT);
  1187.                 _statusline(NEW_FILENAME_PROMPT);
  1188.                 FirstRecall = TRUE;
  1189.                 FnameNum = FnameTotal;
  1190.                 goto again;
  1191.                 }
  1192.             }
  1193.             /*
  1194.              *  Cancel if the user entered "/dev/null" on Unix,
  1195.              *  or an "nl:" path (case-insensitive) on VMS. - FM
  1196.              */
  1197. #ifdef VMS
  1198.             if (!strncasecomp(filename, "nl:", 3) ||
  1199.                 !strncasecomp(filename, "/nl/", 4))
  1200. #else
  1201.             if (!strcmp(filename, "/dev/null"))
  1202. #endif /* VMS */
  1203.             {
  1204.                 _statusline(PRINT_REQUEST_CANCELLED);
  1205.                 sleep(InfoSecs);
  1206.                 break;
  1207.             }
  1208.             HTAddSugFilename(filename);
  1209.             }
  1210.  
  1211. #if defined (VMS) || defined (__EMX__)
  1212.             sprintf(buffer, cur_printer->command, tempfile, filename,
  1213.                     "", "", "", "", "", "", "", "", "", "");
  1214. #else /* Unix: */
  1215.             /*
  1216.              *    Prevent spoofing of the shell.
  1217.              */
  1218.             cp = quote_pathname(filename);
  1219.             sprintf(buffer, cur_printer->command, tempfile, cp,
  1220.                     "", "", "", "", "", "", "", "", "", "");
  1221.             FREE(cp);
  1222. #endif /* !VMS */
  1223.  
  1224.         } else {
  1225.             HTAlert(PRINTER_MISCONF_ERROR);
  1226.             break;
  1227.         }
  1228.  
  1229.         /*
  1230.          *  Move the cursor to the top of the screen so that
  1231.          *  output from system'd commands don't scroll up
  1232.          *  the screen.
  1233.          */
  1234.         move(1,1);
  1235.  
  1236.         stop_curses();
  1237.         CTRACE(tfp, "command: %s\n", buffer);
  1238.         printf(PRINTING_FILE);
  1239. #ifdef VMS
  1240.         /*
  1241.          *  Set document's title as a VMS logical. -  FM
  1242.          */
  1243.         StrAllocCopy(envbuffer, HText_getTitle());
  1244.         if (!(envbuffer && *envbuffer))
  1245.             StrAllocCopy(envbuffer, "No Title");
  1246.         Define_VMSLogical("LYNX_PRINT_TITLE", envbuffer);
  1247. #else
  1248.         /*
  1249.          *  Set document's title as an environment variable. - JKT
  1250.          */
  1251.         StrAllocCopy(envbuffer, "LYNX_PRINT_TITLE=");
  1252.         StrAllocCat(envbuffer, HText_getTitle());
  1253.         putenv(envbuffer);
  1254. #endif /* VMS */
  1255.         fflush(stdout);
  1256.         system(buffer);
  1257. #ifdef VMS
  1258.         /*
  1259.          *  Remove LYNX_PRINT_TITLE logical. - FM
  1260.          */
  1261.         Define_VMSLogical("LYNX_PRINT_TITLE", "");
  1262. #else
  1263.         /*
  1264.          *  Remove LYNX_PRINT_TITLE value from environment. - KW
  1265.          */
  1266.         envbuffer[17] = '\0'; /* truncate after '=' */
  1267.         putenv(envbuffer);
  1268. #endif /* VMS */
  1269.         FREE(envbuffer);
  1270.         fflush(stdout);
  1271. #ifndef VMS
  1272.         signal(SIGINT, cleanup_sig);
  1273. #endif /* !VMS */
  1274.         sleep(MessageSecs);
  1275.         start_curses();
  1276.         /* don't remove(tempfile); */
  1277.     } /* end switch */
  1278.  
  1279.     FREE(link_info);
  1280.     FREE(sug_filename);
  1281.     FREE(content_base);
  1282.     FREE(content_location);
  1283.     return(NORMAL);
  1284. }
  1285.  
  1286. #ifdef VMS
  1287. PRIVATE int remove_quotes ARGS1(
  1288.     char *,     string)
  1289. {
  1290.    int i;
  1291.  
  1292.    for(i = 0; string[i] != '\0'; i++)
  1293.     if(string[i] == '"')
  1294.        string[i] = ' ';
  1295.     else if(string[i] == '&')
  1296.        string[i] = ' ';
  1297.     else if(string[i] == '|')
  1298.        string[i] = ' ';
  1299.  
  1300.    return(0);
  1301. }
  1302. #endif /* VMS */
  1303.  
  1304. /*
  1305.  * print_options writes out the current printer choices to a file
  1306.  * so that the user can select printers in the same way that
  1307.  * they select all other links
  1308.  * printer links look like
  1309.  *  LYNXPRINT://LOCAL_FILE/lines=#         print to a local file
  1310.  *  LYNXPRINT://TO_SCREEN/lines=#         print to the screen
  1311.  *  LYNXPRINT://LPANSI/lines=#             print to the local terminal
  1312.  *  LYNXPRINT://MAIL_FILE/lines=#         mail the file
  1313.  *  LYNXPRINT://PRINTER/lines=#/number=#   print to printer number #
  1314.  */
  1315. PUBLIC int print_options ARGS2(
  1316.     char **,    newfile,
  1317.     int,        lines_in_file)
  1318. {
  1319.     static char tempfile[256];
  1320.     static BOOLEAN first = TRUE;
  1321.     static char print_filename[256];
  1322.     char buffer[LINESIZE];
  1323.     int count;
  1324.     int pages;
  1325.     FILE *fp0;
  1326.     lynx_printer_item_type *cur_printer;
  1327.  
  1328.     pages = lines_in_file/66 + 1;
  1329.  
  1330.     if (first) {
  1331.     tempname(tempfile, NEW_FILE);
  1332. #if defined (VMS) || defined (DOSPATH) || defined (__EMX__)
  1333.     sprintf(print_filename, "file://localhost/%s", tempfile);
  1334. #else
  1335.     sprintf(print_filename, "file://localhost%s", tempfile);
  1336. #endif /* VMS */
  1337.     first = FALSE;
  1338. #ifdef VMS
  1339.     } else {
  1340.     remove(tempfile);   /* Remove duplicates on VMS. */
  1341. #endif /* !VMS */
  1342.     }
  1343.  
  1344.     if ((fp0 = LYNewTxtFile(tempfile)) == NULL) {
  1345.     HTAlert(UNABLE_TO_OPEN_PRINTOP_FILE);
  1346.     return(-1);
  1347.     }
  1348.  
  1349.     StrAllocCopy(*newfile, print_filename);
  1350.     LYforce_no_cache = TRUE;
  1351.  
  1352.     fprintf(fp0, "<head>\n<title>%s</title>\n</head>\n<body>\n",
  1353.          PRINT_OPTIONS_TITLE);
  1354.  
  1355.     fprintf(fp0,"<h1>Printing Options (%s Version %s)</h1><pre>\n",
  1356.                        LYNX_NAME, LYNX_VERSION);
  1357.  
  1358.     pages = (lines_in_file+65)/66;
  1359.     sprintf(buffer,
  1360.        "   There are %d lines, or approximately %d page%s, to print.\n",
  1361.         lines_in_file, pages, (pages > 1 ? "s" : ""));
  1362.     fputs(buffer,fp0);
  1363.  
  1364.     if (no_print || no_disk_save || child_lynx || no_mail)
  1365.     fprintf(fp0, "   Some print functions have been disabled!!!\n");
  1366.  
  1367.     fprintf(fp0, "   You have the following print choices.\n");
  1368.     fprintf(fp0, "   Please select one:\n\n");
  1369.  
  1370.     if (child_lynx == FALSE && no_disk_save == FALSE && no_print == FALSE)
  1371.     fprintf(fp0,
  1372.    "   <a href=\"LYNXPRINT://LOCAL_FILE/lines=%d\">Save to a local file</a>\n",
  1373.         lines_in_file);
  1374.     else
  1375.     fprintf(fp0,"   Save to disk disabled.\n");
  1376.     if (child_lynx == FALSE && no_mail == FALSE)
  1377.      fprintf(fp0,
  1378.    "   <a href=\"LYNXPRINT://MAIL_FILE/lines=%d\">Mail the file</a>\n",
  1379.         lines_in_file);
  1380.     fprintf(fp0,
  1381.    "   <a href=\"LYNXPRINT://TO_SCREEN/lines=%d\">Print to the screen</a>\n",
  1382.         lines_in_file);
  1383.     fprintf(fp0,
  1384.    "   <a href=\"LYNXPRINT://LPANSI/lines=%d\">Print out on a printer attached to your vt100 terminal</a>\n",
  1385.         lines_in_file);
  1386.  
  1387.     for (count = 0, cur_printer = printers; cur_printer != NULL;
  1388.     cur_printer = cur_printer->next, count++)
  1389.     if (no_print == FALSE || cur_printer->always_enabled) {
  1390.     fprintf(fp0,
  1391.    "   <a href=\"LYNXPRINT://PRINTER/number=%d/pagelen=%d/lines=%d\">",
  1392.         count, cur_printer->pagelen, lines_in_file);
  1393.     fprintf(fp0, (cur_printer->name ?
  1394.               cur_printer->name : "No Name Given"));
  1395.     fprintf(fp0, "</a>\n");
  1396.     }
  1397.     fprintf(fp0, "</pre>\n</body>\n");
  1398.     fclose(fp0);
  1399.  
  1400.     LYforce_no_cache = TRUE;
  1401.     return(0);
  1402. }
  1403.