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 / LYNews.c < prev    next >
C/C++ Source or Header  |  1998-05-02  |  12KB  |  432 lines

  1. #include <HTUtils.h>
  2. #include <tcp.h>
  3. #include <HTParse.h>
  4. #include <HTAccess.h>
  5. #include <HTCJK.h>
  6. #include <HTAlert.h>
  7. #include <LYCurses.h>
  8. #include <LYSignal.h>
  9. #include <LYStructs.h>
  10. #include <LYUtils.h>
  11. #include <LYClean.h>
  12. #include <LYStrings.h>
  13. #include <LYGetFile.h>
  14. #include <LYHistory.h>
  15. #include <LYSystem.h>
  16. #include <GridText.h>
  17. #include <LYCharSets.h>
  18. #include <LYNews.h>
  19.  
  20. #include <LYGlobalDefs.h>
  21.  
  22. #include <LYLeaks.h>
  23.  
  24. #define FREE(x) if (x) {free(x); x = NULL;}
  25.  
  26. /*
  27. **  Global variable for async i/o.
  28. */
  29. BOOLEAN term_message = FALSE;
  30. PRIVATE void terminate_message  PARAMS((int sig));
  31.  
  32. /*
  33. **  This function is called from HTLoadNews() to have the user
  34. **  create a file with news headers and a body for posting of
  35. **  a new message (based on a newspost://nntp_host/newsgroups
  36. **  or snewspost://secure_nntp_host/newsgroups URL), or to post
  37. **  a followup (based on a newsreply://nntp_host/newsgroups or
  38. **  snewsreply://secure_nntp_host/newsgroups URL). The group
  39. **  or comma-separated list of newsgroups is passed without
  40. **  a lead slash, and followup is TRUE for newsreply or
  41. **  snewsreply URLs.  - FM
  42. */
  43. PUBLIC char *LYNewsPost ARGS2(
  44.     char *,        newsgroups,
  45.     BOOLEAN,    followup)
  46. {
  47.     char user_input[1024];
  48.     char CJKinput[1024];
  49.     char *cp = NULL;
  50.     int c = 0;  /* user input */
  51.     FILE *fd = NULL;
  52.     char my_tempfile[256];
  53.     FILE *fc = NULL;
  54.     char CJKfile[256];
  55.     char *postfile = NULL;
  56.     char *NewsGroups = NULL;
  57.     char *org = NULL;
  58.     FILE *fp = NULL;
  59.  
  60.     /*
  61.      *  Make sure a non-zero length newspost, newsreply,
  62.      *  snewspost or snewsreply path was sent to us. - FM
  63.      */
  64.     if (!(newsgroups && *newsgroups))
  65.     return(postfile);
  66.  
  67.     /*
  68.      *  Open a temporary file for the headers
  69.      *  and message body. - FM
  70.      */
  71.     tempname(my_tempfile, NEW_FILE);
  72.     if ((fd = LYNewTxtFile(my_tempfile)) == NULL) {
  73.     HTAlert(CANNOT_OPEN_TEMP);
  74.     return(postfile);
  75.     }
  76.  
  77.     /*
  78.      *  If we're using a Japanese display character set,
  79.      *  open a temporary file for a conversion to JIS. - FM
  80.      */
  81.     CJKfile[0] = '\0';
  82.     if (!strncmp(LYchar_set_names[current_char_set], "Japanese (EUC)", 14) ||
  83.     !strncmp(LYchar_set_names[current_char_set], "Japanese (SJIS)", 15)) {
  84.     tempname(CJKfile, NEW_FILE);
  85.     if ((fc = LYNewTxtFile(CJKfile)) == NULL) {
  86.         HTAlert(CANNOT_OPEN_TEMP);
  87.         fclose(fd);
  88. #ifdef VMS
  89.         while (remove(my_tempfile) == 0)
  90.         ; /* loop through all versions */
  91. #else
  92.         remove(my_tempfile);
  93. #endif /* VMS */
  94.         return(postfile);
  95.     }
  96.     }
  97.  
  98.     /*
  99.      *  The newsgroups could be a comma-seperated list.
  100.      *  It need not have spaces, but deal with any that
  101.      *  may also have been hex escaped. - FM
  102.      */
  103.     StrAllocCopy(NewsGroups, newsgroups);
  104.     HTUnEscape(NewsGroups);
  105.  
  106.     /*
  107.      *  Allow ^C to cancel the posting,
  108.      *  i.e., don't let SIGINTs exit Lynx.
  109.      */
  110.     signal(SIGINT, terminate_message);
  111.     term_message = FALSE;
  112.  
  113.     /*
  114.      *  Show the list of newsgroups. - FM
  115.      */
  116.     clear();
  117.     move(2,0);
  118.     scrollok(stdscr, TRUE);    /* Enable scrolling. */
  119.     addstr("You will be posting to:");
  120.     addstr("\n\t");
  121.     addstr(NewsGroups);
  122.     addch('\n');
  123.  
  124.     /*
  125.      *  Get the mail address for the From header,
  126.      *  offering personal_mail_address as default.
  127.      */
  128.     addstr("\n\n Please provide your mail address for the From: header\n");
  129.     strcpy(user_input, "From: ");
  130.     if (personal_mail_address)
  131.     strcat(user_input, personal_mail_address);
  132.     if (LYgetstr(user_input, VISIBLE,
  133.          sizeof(user_input), NORECALL) < 0 ||
  134.     term_message) {
  135.         _statusline(NEWS_POST_CANCELLED);
  136.     sleep(InfoSecs);
  137.     fclose(fd);         /* Close the temp file. */
  138.     scrollok(stdscr, FALSE); /* Stop scrolling.     */
  139.     goto cleanup;
  140.     }
  141.     fprintf(fd, "%s\n", user_input);
  142.  
  143.     /*
  144.      *  Get the Subject header, offering the current
  145.      *  document's title as the default if this is a
  146.      *  followup rather than a new post. - FM
  147.      */
  148.     addstr("\n\n Please provide or edit the Subject: header\n");
  149.     strcpy(user_input, "Subject: ");
  150.     if ((followup == TRUE && nhist > 0) &&
  151.         (cp = HText_getTitle()) != NULL) {
  152.     /*
  153.      *  Add the default subject.
  154.      */
  155.     cp = LYSkipBlanks(cp);
  156.     if (strncasecomp(cp, "Re:", 3)) {
  157.             strcat(user_input, "Re: ");
  158.     }
  159.         strcat(user_input, cp);
  160.     }
  161.     cp = NULL;
  162.     if (LYgetstr(user_input, VISIBLE,
  163.          sizeof(user_input), NORECALL) < 0 ||
  164.     term_message) {
  165.         _statusline(NEWS_POST_CANCELLED);
  166.         sleep(InfoSecs);
  167.         fclose(fd);         /* Close the temp file. */
  168.     scrollok(stdscr, FALSE); /* Stop scrolling.     */
  169.         goto cleanup;
  170.     }
  171.     fprintf(fd,"%s\n",user_input);
  172.  
  173.     /*
  174.      *  Add Organization: header.
  175.      */
  176.     StrAllocCopy(cp, "Organization: ");
  177.     if (((org = getenv("ORGANIZATION")) != NULL) && *org != '\0') {
  178.     StrAllocCat(cp, org);
  179.     } else if (((org = getenv("NEWS_ORGANIZATION")) != NULL) &&
  180.                *org != '\0') {
  181.     StrAllocCat(cp, org);
  182. #ifndef VMS
  183.     } else if ((fp = fopen("/etc/organization", "r")) != NULL) {
  184.     if (fgets(user_input, sizeof(user_input), fp) != NULL) {
  185.         if ((org = strchr(user_input, '\n')) != NULL) {
  186.             *org = '\0';
  187.         }
  188.         if (user_input[0] != '\0') {
  189.             StrAllocCat(cp, user_input);
  190.         }
  191.     }
  192.     fclose(fp);
  193. #endif /* !VMS */
  194.     }
  195.     LYstrncpy(user_input, cp, (sizeof(user_input) - 16));
  196.     FREE(cp); 
  197.     addstr("\n\n Please provide or edit the Organization: header\n");
  198.     if (LYgetstr(user_input, VISIBLE,
  199.          sizeof(user_input), NORECALL) < 0 ||
  200.     term_message) {
  201.         _statusline(NEWS_POST_CANCELLED);
  202.         sleep(InfoSecs);
  203.         fclose(fd);         /* Close the temp file. */
  204.     scrollok(stdscr, FALSE); /* Stop scrolling.     */
  205.         goto cleanup;
  206.     }
  207.     fprintf(fd, "%s\n", user_input);
  208.  
  209.     /*
  210.      *  Add Newsgroups Summary and Keywords headers.
  211.      */
  212.     fprintf(fd, "Newsgroups: %s\nSummary: \nKeywords: \n\n", NewsGroups);
  213.  
  214.     /*
  215.      *  Have the user create the message body.
  216.      */
  217.     if (!no_editor && editor && *editor != '\0') {
  218.         /*
  219.      *  Use an external editor.
  220.      */
  221.     char *editor_arg = "";
  222.  
  223.     if (followup && nhist > 0) {
  224.         /*
  225.          *  Ask if the user wants to include the original message.
  226.          */
  227.         _statusline(INC_ORIG_MSG_PROMPT);
  228.         c = 0;
  229.         while (TOUPPER(c) != 'Y' && TOUPPER(c) != 'N' &&
  230.                !term_message && c != 7 && c != 3)
  231.             c = LYgetch();
  232.         if (TOUPPER(c) == 'Y')
  233.             /*
  234.          *  The 1 will add the reply ">" in front of every line.
  235.          *  We're assuming that if the display character set is
  236.          *  Japanese and the document did not have a CJK charset,
  237.          *  any non-EUC or non-SJIS 8-bit characters in it where
  238.          *  converted to 7-bit equivalents. - FM
  239.          */
  240.             print_wwwfile_to_fd(fd, 1);
  241.     }
  242.     fclose(fd);         /* Close the temp file. */
  243.     scrollok(stdscr, FALSE); /* Stop scrolling.     */
  244.     if (term_message || c == 7 || c == 3)
  245.         goto cleanup;
  246.  
  247.     /*
  248.      *  Spawn the user's editor on the news file.
  249.      */
  250.     if (strstr(editor, "pico")) {
  251.         editor_arg = " -t"; /* No prompt for filename to use */
  252.     }
  253.     sprintf(user_input,"%s%s %s", editor, editor_arg, my_tempfile);
  254.     _statusline(SPAWNING_EDITOR_FOR_NEWS);
  255.     stop_curses();
  256.     if (system(user_input)) {
  257.         start_curses();
  258.         _statusline(ERROR_SPAWNING_EDITOR);
  259.         sleep(AlertSecs);
  260.     } else {
  261.         start_curses();
  262.     }
  263.     } else {
  264.         /*
  265.      *  Use the built in line editior.
  266.      */
  267.     addstr("\n\n Please enter your message below.");
  268.     addstr("\n When you are done, press enter and put a single period (.)");
  269.     addstr("\n on a line and press enter again.");
  270.     addstr("\n\n");
  271.     refresh();
  272.         *user_input = '\0';
  273.     if (LYgetstr(user_input, VISIBLE,
  274.                  sizeof(user_input), NORECALL) < 0 ||
  275.         term_message) {
  276.         _statusline(NEWS_POST_CANCELLED);
  277.         sleep(InfoSecs);
  278.         fclose(fd);            /* Close the temp file.    */
  279.         scrollok(stdscr, FALSE);    /* Stop scrolling.    */
  280.         goto cleanup;
  281.     }
  282.     while (!STREQ(user_input,".") && !term_message) { 
  283.         addch('\n');
  284.         fprintf(fd,"%s\n",user_input);
  285.         *user_input = '\0';
  286.         if (LYgetstr(user_input, VISIBLE,
  287.                     sizeof(user_input), NORECALL) < 0) {
  288.             _statusline(NEWS_POST_CANCELLED);
  289.             sleep(InfoSecs);
  290.             fclose(fd);         /* Close the temp file. */
  291.         scrollok(stdscr, FALSE); /* Stop scrolling.     */
  292.             goto cleanup;
  293.         }
  294.      }
  295.     fprintf(fd, "\n");
  296.     fclose(fd);         /* Close the temp file. */
  297.     scrollok(stdscr, FALSE); /* Stop scrolling.     */
  298.     }
  299.  
  300.     /*
  301.      *  Confirm whether to post, and if so,
  302.      *  whether to append the sig file. - FM
  303.      */
  304.     LYStatusLine = (LYlines - 1);
  305.     _statusline(POST_MSG_PROMPT);
  306.     c = 0;
  307.     LYStatusLine = -1;
  308.     while (TOUPPER(c) != 'Y' && TOUPPER(c) != 'N' &&
  309.        !term_message && c != 7   && c != 3)
  310.     c = LYgetch();
  311.     if (TOUPPER(c) != 'Y') {
  312.         clear();  /* clear the screen */
  313.     goto cleanup;
  314.     }
  315.     if ((LynxSigFile != NULL) &&
  316.         (fp = fopen(LynxSigFile, "r")) != NULL) {
  317.     LYStatusLine = (LYlines - 1);
  318.     _user_message(APPEND_SIG_FILE, LynxSigFile);
  319.     c = 0;
  320.         LYStatusLine = -1;
  321.     while (TOUPPER(c) != 'Y' && TOUPPER(c) != 'N' &&
  322.            !term_message && c != 7   && c != 3)
  323.         c = LYgetch();
  324.     if (TOUPPER(c) == 'Y') {
  325.         if ((fd = fopen(my_tempfile, "a")) != NULL) {
  326.             fputs("-- \n", fd);
  327.             while (fgets(user_input, sizeof(user_input), fp) != NULL) {
  328.             fputs(user_input, fd);
  329.         }
  330.         fclose(fd);
  331.         }
  332.     }
  333.     fclose(fp);
  334.     }
  335.     clear();  /* clear the screen */
  336.  
  337.     /*
  338.      *  If we are using a Japanese display character
  339.      *  set, convert the contents of the temp file to
  340.      *  JIS (nothing should change if it does not, in
  341.      *  fact, contain EUC or SJIS di-bytes).  Otherwise,
  342.      *  use the temp file as is. - FM
  343.      */
  344.     if (CJKfile[0] != '\0') {
  345.     if ((fd = fopen(my_tempfile, "r")) != NULL) {
  346.         while (fgets(user_input, sizeof(user_input), fd) != NULL) {
  347.             TO_JIS((unsigned char *)user_input,
  348.                (unsigned char *)CJKinput);
  349.         fputs(CJKinput, fc);
  350.         }
  351.         fclose(fc);
  352.         StrAllocCopy(postfile, CJKfile);
  353.         fclose(fd);
  354. #ifdef VMS
  355.         while (remove(my_tempfile) == 0)
  356.         ; /* loop through all versions */
  357. #else
  358.         remove(my_tempfile);
  359. #endif /* VMS */
  360.         fd = fc;
  361.         strcpy(my_tempfile, CJKfile);
  362.         CJKfile[0] = '\0';
  363.     } else {
  364.         StrAllocCopy(postfile, my_tempfile);
  365.     }
  366.     } else {
  367.     StrAllocCopy(postfile, my_tempfile);
  368.     }
  369.     if (!followup) {
  370.         /*
  371.      *  If it's not a followup, the current document
  372.      *  most likely is the group listing, so force a
  373.      *  to have the article show up in the list after
  374.      *  the posting.  Note, that if it's a followup
  375.      *  via a link in a news article, the user must
  376.      *  do a reload manually on returning to the
  377.      *  group listing. - FM
  378.      */
  379.         LYforce_no_cache = TRUE;
  380.     }
  381.     LYStatusLine = (LYlines - 1);
  382.     statusline(POSTING_TO_NEWS);
  383.     LYStatusLine = -1;
  384.     sleep(MessageSecs);
  385.  
  386.     /*
  387.      *  Come here to cleanup and exit.
  388.      */
  389. cleanup:
  390. #ifndef VMS
  391.     signal(SIGINT, cleanup_sig);
  392. #endif /* !VMS */
  393.     term_message = FALSE;
  394.     if (!postfile) {
  395. #ifdef VMS
  396.         while (remove(my_tempfile) == 0)
  397.         ; /* loop through all versions */
  398. #else
  399.     remove(my_tempfile);
  400. #endif /* VMS */
  401.     }
  402.     if (CJKfile[0] != '\0') {
  403. #ifdef VMS
  404.     fclose(fc);
  405.         while (remove(CJKfile) == 0)
  406.         ; /* loop through all versions */
  407. #else
  408.     remove(CJKfile);
  409. #endif /* VMS */
  410.     }
  411.     FREE(NewsGroups);
  412.  
  413.     return(postfile);
  414. }
  415.  
  416. PRIVATE void terminate_message ARGS1(
  417.     int,    sig GCC_UNUSED)
  418. {
  419.     term_message = TRUE;
  420.     /*
  421.      *  Reassert the AST.
  422.      */
  423.     signal(SIGINT, terminate_message);
  424. #ifdef VMS
  425.     /*
  426.      *  Refresh the screen to get rid of the "interrupt" message.
  427.      */
  428.     lynx_force_repaint();
  429.     refresh();
  430. #endif /* VMS */
  431. }
  432.