home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / UUCPbb_2_1_src.lzh / UUCPBB21 / postnews.c < prev    next >
Text File  |  1994-09-25  |  18KB  |  696 lines

  1. /*  postnews.c   This is main program for sending Usenet news.
  2.     Copyright (C) 1990, 1993  Rick Adams and Bob Billson
  3.  
  4.     This file is part of the OS-9 UUCP package, UUCPbb.
  5.  
  6.     This program is free software; you can redistribute it and/or modify
  7.     it under the terms of the GNU General Public License as published by
  8.     the Free Software Foundation; either version 2 of the License, or
  9.     (at your option) any later version.
  10.  
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.     GNU General Public License for more details.
  15.  
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program; if not, write to the Free Software
  18.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20.     The author of UUCPbb, Bob Billson, can be contacted at:
  21.     bob@kc2wz.bubble.org  or  uunet!kc2wz!bob  or  by snail mail:
  22.     21 Bates Way, Westfield, NJ 07090
  23. */
  24.  
  25. /* Options:
  26.  
  27.    -f <file>
  28.    -n <newsgroup>
  29.    -S <system>
  30.    -s <subject>
  31.    -i <reference-ID>
  32.    -a <reference-article>
  33.    -t (force /t2 "dumb" windowing codes)
  34.    -x <debug_level>
  35. */
  36.  
  37. #define MAIN
  38.  
  39. #include "uucp.h"
  40. #include <time.h>
  41. #ifndef _OSK
  42. #include <utime.h>
  43. #endif
  44. #include <signal.h>
  45. #ifndef _OSK
  46. #include <os9.h>
  47. #endif
  48.  
  49. extern QQ unsigned myuid;
  50. extern QQ char sepsym, quotechar;
  51. extern QQ char *nodename, *sitename, *name, *newshost, *organization;
  52. extern char user[], temp[];
  53.  
  54. #ifndef TERMCAP
  55. QQ flag t2flag = FALSE;
  56. #endif
  57. QQ FILE *log;
  58. #ifndef _OSK
  59. QQ flag usedotilde;
  60. static char *dotilde = "dotilde";
  61. #endif
  62. QQ char *got_escape = "<ESC> hit...exiting";
  63. QQ int debuglvl = 0;
  64. static char value[100];
  65. char sysname[20], artfile[100], newsgroup[1024], subject[128];
  66. char reference[256],article[100], distrib[50], localgroup[256];
  67. char tempfile[100];                /* moved from postgroup() so interrupt() */
  68.                                    /* can clean up -- REB */
  69.  
  70. main (argc, argv)
  71. int argc;
  72. char *argv[];
  73. {
  74.      int option, interrupt();
  75.      register char *p;
  76. #ifndef _OSK
  77.      struct registers regs;
  78. #endif
  79.      *sysname = *artfile = *newsgroup = *subject = *localgroup = '\0';
  80.      *reference = *article = *tempfile = '\0';
  81.      homedir = NULL;
  82.      opterr = TRUE;
  83.      log = stderr;               /* use stderr rather than uulog file --REB */
  84.  
  85. #ifndef _OSK
  86.      pflinit();                  /* tell linker longs will be printed --REB */
  87. #endif
  88.  
  89.      /* handle keyboard interrupts */
  90.      intercept (interrupt);
  91.  
  92. #ifdef TERMCAP
  93.      init_term_cap();
  94. #endif
  95.  
  96.      while ((option = getopt (argc, argv, "f:n:s:S:i:a:tx:")) != EOF)
  97.           switch (option)
  98.             {
  99.                case 'f':
  100.                     strcpy (artfile, optarg);
  101.                     break;
  102.  
  103.                case 'n':
  104.                     strcat (strcat (newsgroup, optarg), " ");
  105.                     break;
  106.  
  107.                case 's':
  108.                     strcpy (subject, optarg);
  109.                     break;
  110.  
  111.                case 'S':
  112.                     strcpy (sysname, optarg);
  113.                     break;
  114.  
  115.                case 'i':
  116.                     strcpy (reference, optarg);
  117.                     break;
  118.  
  119.                case 'a':
  120.                     strcpy (article, optarg);
  121.                     break;
  122.  
  123.                case 't':
  124. #ifndef TERMCAP
  125.                     t2flag = TRUE;
  126.                     break;
  127. #endif
  128.                case 'x':
  129.                     debuglvl = atoi (optarg);
  130.                     break;
  131.  
  132.                case '?':
  133.                     usage();
  134.                     break;
  135.  
  136.                default:
  137.                     strcat (strcat (newsgroup, optarg), " ");
  138.                     break;
  139.             }
  140.  
  141.      /* elminated last blank in newsgroup list -- REB */
  142.      newsgroup[strlen (newsgroup) - 1] = '\0';
  143.  
  144.      if (getparam() == FALSE)
  145.           interrupt (0);
  146.  
  147.      userparam();
  148.  
  149.      if ((newsdir = getdirs ("newsdir")) == NULL)
  150.           badparam ("newsdir");
  151.  
  152.      if ((spooldir = getdirs ("spooldir")) == NULL)
  153.           badparam ("spooldir");
  154.  
  155. #ifndef _OSK
  156.     if (nmlink (dotilde, 0, 0) == -1)
  157.          if (nmload (dotilde, 0, 0) == -1)
  158.               fatal ("can't load dotilde");
  159.  
  160.     usedotilde = TRUE;
  161. #endif
  162.  
  163. #ifndef TERMCAP
  164.      if (!t2flag)
  165.           t2flag = t2test();
  166. #endif
  167.      /* figure out path to article being replied to, if any */
  168.      if (*article != '\0')
  169.        {
  170.           sprintf (temp, "%s/%s/%s", newsdir, newsgroup, article);
  171.  
  172.           while ((p = strchr (temp, '.')) != NULL)
  173.                *p = '/';
  174.  
  175.           strcpy (article, temp);
  176.        }
  177.  
  178.      /* use default newsfeed host is -S wasn't on command line -- REB */
  179.      if (*sysname == '\0')
  180.           if (*newshost != '\0')
  181.                strcpy (sysname, newshost);
  182.           else
  183.                getsys (sysname);
  184.  
  185.      /* get user name */
  186.      if (*user == '\0')
  187.           fatal ("user not in password file");
  188.  
  189.      /* post article to newsgroup */
  190.      postgroup (sysname);
  191.      interrupt (0);
  192. }
  193.  
  194.  
  195.  
  196. /* postgroup  --queue article for remote news delivery */
  197.  
  198. int postgroup (system)
  199. char *system;
  200. {
  201.      static char line[128], filename[50];
  202.      static char cname[15], xname[14], dname[14], jname[14];
  203.      char seq[5];
  204.      FILE *file, *qfile, *sigfile;
  205.      char *p;
  206.      long nseq;
  207.      int result;
  208.      flag localonly;
  209.  
  210.      /* open prepared article, if any */
  211.      if (*artfile != '\0')
  212.           if ((file = fopen (artfile, "r")) == NULL)
  213.                fatal ("can't open article file");
  214.  
  215.      /* Become super user so we can go to proper spool file */
  216.      asetuid (0);
  217.      sprintf (temp, "%s/%s", spooldir, system);
  218.  
  219.      if (chdir (temp) == -1)
  220.        {
  221.           char tmp[100];
  222.  
  223.           sprintf (tmp, "can't change to spool directory: %s\n", temp);
  224.           fatal (tmp);
  225.        }
  226.      asetuid (myuid);
  227.  
  228.      /* Get unique message ID number.  Moved here to speed things up a bit.
  229.         When we return our user ID will be restored.  --REB */
  230.  
  231.      nseq = getseq (NEWSEQ);
  232.  
  233.      /* figure out all the spool file names */
  234.      strcpy (seq, genseq() );
  235.  
  236.      /* D.sysnameXXXX filename (article data file) */
  237.      sprintf (dname, "D.%.7s%s", nodename, seq);
  238.  
  239.      /* D.sysnameXXXX file (job file) */
  240.      sprintf (jname, "D.%.7s%s", system, seq);
  241.  
  242.      /* C.sysnameCXXXX (control file) */
  243.      sprintf (cname, "C.%.7sC%s", system, seq);
  244.  
  245.      /* X.sysnameXXXX (execute file) */
  246.      sprintf (xname, "X.%.7s%s", system, seq);
  247.  
  248.      /* open article data file */
  249.      maketemp (tempfile, '1', FALSE);
  250.  
  251.      /* change id so we can open a file -- BAS */
  252.      cls();
  253.      asetuid (0);
  254.  
  255.      if ((qfile = fopen (tempfile, "w")) == NULL)
  256.           fatal ("can't open article data file");
  257.  
  258.      fixperms (qfile);
  259.      asetuid (myuid);
  260.  
  261.      /* Path: ccentral!rickadams */
  262.      fprintf (qfile, "Path: %s!%s\n", nodename, user);
  263.  
  264.      /* From: rickadams@ccentral.UUCP (The OTHER Rick Adams) */
  265.      sprintf (line, "From: %s%c%s%s%s%s\n",
  266.                     sepsym != '!' ? user : sitename,
  267.                     sepsym,
  268.                     sepsym != '!' ? sitename : user,
  269.                     *name != '\0' ? " (" : "",
  270.                     *name != '\0' ? name : "",
  271.                     *name != '\0' ? ")"  : "");
  272.  
  273.      fputs (line, stdout);
  274.      fputs (line, qfile);
  275.  
  276.      /* Newsgroups: ca.test */
  277.      if (*newsgroup == '\0')
  278.        {
  279.           sprintf (filename, "%s/active", UUCPSYS);
  280.           getvalue (qfile, "Newsgroups", filename);
  281.           strcpy (newsgroup, value);
  282.        }
  283.      else
  284.        {
  285.           sprintf (line, "Newsgroups: %s\n", newsgroup);
  286.           fputs (line, stdout);
  287.           fputs (line, qfile);
  288.        }
  289.  
  290.      /* Subject: test */
  291.      if (*subject == '\0')
  292.           getfield (qfile, "Subject", TRUE);
  293.      else
  294.        {
  295.           sprintf (line, "Subject: %s\n", subject);
  296.           fputs (line, stdout);
  297.           fputs (line, qfile);
  298.        }
  299.  
  300.      /* Keywords: test */
  301.      getfield (qfile, "Keywords", FALSE);
  302.  
  303.      /* Message-ID: <1@ccentral.UUCP>   Changed -- REB */
  304.      sprintf (line, "Message-ID: <%ld@%s>\n", nseq, sitename);
  305.      fputs (line, stdout);
  306.      fputs (line, qfile);
  307.  
  308.      /* Date: Tue, 12 Feb 91 10:57:45 -0800    Changed -- REB */
  309.      strcat (strcpy (line, "Date: "), date822());
  310.      puts (line);
  311.      fprintf (qfile, "%s\n", line);
  312.  
  313.      /* Reply-To: user@sitename   Some news articles seem to have this */
  314.      /* I don't know if it is done completely right. -- BAS            */
  315.  
  316.      sprintf (line, "Reply-To: %s%c%s\n",
  317.                     sepsym != '!' ? user : sitename,
  318.                     sepsym,
  319.                     sepsym != '!' ? sitename : user);
  320.  
  321.      fputs (line, stdout);
  322.      fputs (line, qfile);
  323.  
  324.      /* References: <1234@sitename.UUCP>   Changed -- REB */
  325.      if (*reference != '\0')
  326.        {
  327.           sprintf (line, "References: %s\n", reference);
  328.           fputs (line, stdout);
  329.           fputs (line, qfile);
  330.        }
  331.  
  332.      /* Distribution: ca */
  333.      if (!localcheck())
  334.        {
  335.           sprintf (filename, "%s/distributions", UUCPSYS);
  336.           getvalue (qfile, "Distribution", filename);
  337.           strcpy (distrib, value);
  338.        }
  339.      else
  340.        {
  341.           /* local article */
  342.           sprintf (line, "Distribution: local\n");
  343.           fputs (line, stdout);
  344.           fputs (line, qfile);
  345.           strcpy (distrib, "local");
  346.        }
  347.  
  348.      /* local distribution only? */
  349.      localonly = (strcmp (distrib, "local") == 0)  ? TRUE : FALSE;
  350.  
  351.      /* Summary: This is a test message. */
  352.      getfield (qfile, "Summary", FALSE);
  353.  
  354.      /* Organization: Color Central Software */
  355.      if (*organization != '\0')
  356.        {
  357.           sprintf (line, "Organization: %s\n", organization);
  358.           fputs (line, stdout);
  359.           fputs (line, qfile);
  360.        }
  361.  
  362.      /* body of message */
  363.      putchar ('\n');
  364.      putc ('\n', qfile);
  365.  
  366.      if (*artfile != '\0')
  367.        {
  368.           while (fgets (line, sizeof (line), file) != NULL)
  369.             {
  370.                if ((p = strchr (line, '\n')) != NULL)
  371.                     *p = '\0';
  372.  
  373.                fprintf (qfile, "%s\n", line);
  374.                printf ("%s\n", line);
  375.             }
  376.           fclose (file);
  377.        }
  378.      else
  379.           for (;;)
  380.             {
  381.                /* end of input? */
  382.                if (fgets (line, sizeof (line), stdin) == NULL)
  383.                     break;
  384.  
  385.                if (*line == '.'  &&  *(line + 1) == '\n')
  386.                  {
  387.                     CurUp();
  388.                     fputs (" \b", stdout);
  389.                     fflush (stdout);
  390.                     break;
  391.                  }
  392.                else
  393.                  {
  394.                     if (*line == '~')
  395.                       {
  396.                          int tilde;
  397.  
  398.                          fclose (qfile);
  399.                          line[strlen (line) - 1] = '\0';
  400.  
  401.                          sprintf (temp,
  402.                                   "dotilde \"%s\" %d %d %c %s %s %s",
  403. #ifndef TERMCAP
  404.                                   line, t2flag, myuid, quotechar, tempfile,
  405. #else
  406.                                   line, 0, myuid, quotechar, tempfile,
  407. #endif
  408.                                   homedir, article);
  409.  
  410.                          asetuid (0);
  411.                          tilde = docmd_na (temp);
  412.  
  413.                          if (tilde == SIGINT  ||  tilde == SIGQUIT
  414.                              || tilde == ABORT)
  415.                            {
  416.                               interrupt (0);
  417.                            }
  418.  
  419.                          if ((qfile = fopen (tempfile, "a")) == NULL)
  420.                               fatal ("can't reopen article file");
  421.  
  422.                          fixperms (qfile);
  423.                          asetuid (myuid);
  424.                       }
  425.                     else
  426.                          fprintf (qfile, "%s", line);
  427.                  }
  428.             }
  429.  
  430.      /* append signature file */
  431. #ifdef _OSK
  432.      sprintf (line, "%s/.signature", homedir);
  433. #else
  434.      sprintf (line, "%s/%s/signature", homedir, uudir);
  435. #endif
  436.  
  437.      if ((sigfile = fopen (line, "r")) != NULL)
  438.        {
  439.           fprintf (qfile, "-- \n");
  440.           puts ("--");
  441.  
  442.           while (fgets (line, sizeof (line), sigfile) != NULL)
  443.             {
  444.                if ((p = strchr (line, '\n')) != NULL)
  445.                     *p = '\0';
  446.  
  447.                fprintf (qfile, "%s\n", line);
  448.                printf ("%s\n", line);
  449.             }
  450.           fclose (sigfile);
  451.        }
  452.  
  453.      /* close article file */
  454.      fclose (qfile);
  455.  
  456.      /* transfer article file to queued data file and replace CRs with LFs */
  457.      asetuid (0);
  458.      filemovl (tempfile, dname);
  459.      *tempfile = '\0';
  460.      fputs ("\n\nposting your article...locally...", stdout);
  461.      fflush (stdout);
  462.  
  463.      /* post article locally */
  464.      sprintf (line, "rnews -x%d -n%s %s", debuglvl, newsgroup, dname);
  465.  
  466.      if ((result = docmd_na (line)) != 0)
  467.        {
  468.           unlink (dname);
  469.           interrupt (result);
  470.        }
  471.  
  472.      /* local article only? */
  473.      if (localonly)
  474.        {
  475.           asetuid (0);                  /* so we can delete the file -- BAS */
  476.           unlink (dname);
  477.           asetuid (myuid);
  478.           cls();
  479.           return (0);
  480.        }
  481.  
  482.      fputs ("and to the net...", stdout);
  483.      fflush (stdout);
  484.  
  485.      /* write job file */
  486.      asetuid (0);
  487.  
  488.      if ((qfile = fopen (jname, "w")) == NULL)
  489.           fatal ("can't create job file");
  490.  
  491.      fixperms (qfile);
  492.      chown (jname, myuid);
  493.  
  494.      fprintf (qfile, "U %s %s\x0a", user, nodename);
  495.      fprintf (qfile, "F %s\x0a", dname);
  496.      fprintf (qfile, "I %s\x0a", dname);
  497.      fputs ("C rnews \x0a", qfile);
  498.      fclose( qfile);
  499.  
  500.      /* write control file */
  501.      if ((qfile = fopen (cname, "w")) == NULL)
  502.           fatal ("can't create control file");
  503.  
  504.      fixperms (qfile);
  505.      chown (cname, myuid);
  506.  
  507.      fprintf (qfile, "S %s %s %s - %s 0666 %s\n",
  508.                      dname, dname, user, dname, user);
  509.  
  510.      fprintf (qfile, "S %s %s %s - %s 0666 %s\n",
  511.                      jname, xname, user, jname, user);
  512.  
  513.      fclose (qfile);
  514.      asetuid (myuid);
  515.      cls();
  516.      return (0);
  517. }
  518.  
  519.  
  520.  
  521. int getvalue (file, prompt, filename)
  522. FILE *file;
  523. char *prompt, *filename;
  524. {
  525.      char line[100];
  526.      flag status;
  527.      FILE *file2;
  528.      char *p;
  529.  
  530.      do
  531.        {
  532.           /* get value */
  533.           do
  534.             {
  535.                printf ("%s: ", prompt);
  536.  
  537.                if (mfgets (value, sizeof (value), stdin) == NULL)
  538.                  {
  539.                     errno = 0;
  540.                     fatal (got_escape);
  541.                  }
  542.  
  543.                if (*value == '\0')
  544.                     printf ("\nThe \"%s\" field is required.\n\n", prompt);
  545.             }
  546.           while (*value == '\0');
  547.  
  548.           status = findent (value, filename, line, sizeof(line));
  549.  
  550.           if (!status)
  551.             {
  552.                /* dump out valid values */
  553.                printf ("\nInvalid -- valid values for \"%s\" are:\n", prompt);
  554.  
  555.                if ((file2 = fopen (filename, "r")) != NULL)
  556.                  {
  557.                     while (mfgets (line, sizeof (line), file2) != NULL)
  558.                       {
  559.                          if ((p = strchr (line, ' ')) != NULL)
  560.                               *p = '\0';
  561.  
  562.                          printf ("   %s\n", line);
  563.                       }
  564.                     fclose (file);
  565.                  }
  566.                putchar ('\n');
  567.             }
  568.        }
  569.      while (!status);
  570.  
  571.     fprintf (file, "%s: %s\n", prompt, value);
  572. }
  573.  
  574.  
  575.  
  576. int getfield (file, prompt, needthis)
  577. FILE *file;
  578. char *prompt;
  579. flag needthis;                                          /* field required? */
  580. {
  581.      register char *p;
  582.  
  583.      p = value;
  584.      do
  585.        {
  586.           printf ("%s: ", prompt);
  587.  
  588.           if (mfgets (p, sizeof (value), stdin) == NULL)
  589.             {
  590.                errno = 0;
  591.                fatal (got_escape);
  592.             }
  593.  
  594.           if (needthis  &&  *p == '\0')
  595.                printf ("\nThe \"%s\" field is required.\n\n", prompt);
  596.  
  597.        }
  598.      while (needthis  &&  *p == '\0');
  599.  
  600.      fprintf (file, "%s: %s\n", prompt, p);
  601.      return (strlen (p));
  602. }
  603.  
  604.  
  605.  
  606. /* check to see if this is a local newsgroup */
  607.  
  608. int localcheck()
  609. {
  610.      /* newsgroup begins with "nodename."? */
  611.      strcat (strcpy (temp, nodename), ".");
  612.  
  613.      if (strncmp (newsgroup, temp, strlen (temp)) == 0)
  614.           return (TRUE);
  615.  
  616.      /* newsgroup begins with "local." or "general."? */
  617.      if (strncmp (newsgroup, "local.", 6) == 0)
  618.           return (TRUE);
  619.      else if (strncmp (newsgroup, "general.", 8) == 0)
  620.           return (TRUE);
  621.      else
  622.           return (FALSE);
  623. }
  624.  
  625.  
  626.  
  627. int fatal (msg)
  628. char *msg;
  629. {
  630.      fprintf (stderr, "\npostnews: %s", msg);
  631.  
  632.      if (errno != 0)
  633.           fprintf (stderr, "...error %d", errno);
  634.  
  635.      putc ('\n', stderr);
  636.      interrupt (0);
  637. }
  638.  
  639.  
  640.  
  641. int badparam (msg)
  642. char *msg;
  643. {
  644.      fprintf (stderr, "postnews: %s not in Parameters\n", msg);
  645.      interrupt (0);
  646. }
  647.  
  648.  
  649.  
  650. /* deal with interruptions */
  651.  
  652. int interrupt (sig)
  653. int sig;
  654. {
  655.      if (*tempfile != '\0')
  656.           unlink (tempfile);
  657. #ifndef _OSK
  658.      if (usedotilde)
  659.           munload (dotilde, 0);
  660. #endif
  661.      exit (sig);
  662. }
  663.  
  664.  
  665.  
  666. int usage()
  667. {
  668.      char *stredetab();
  669.      register char **ptr;
  670.      static char *help[] = {
  671.                      "postnews\t post news to Usenet",
  672.                      " ",
  673.                      "Usage: postnews [options]",
  674.                      "\t  Options:",
  675.                      "\t\t-f <file>",
  676.                      "\t\t-n <newsgroup>",
  677.                      "\t\t-S <system>",
  678.                      "\t\t-s <subject>",
  679.                      "\t\t-i <reference-ID>",
  680.                      "\t\t-a <reference-article>",
  681. #ifndef TERMCAP
  682.                      "\t\t-t (force /t2 \"dumb\" windowing codes)",
  683. #endif
  684.                      NULL
  685.                   };
  686.  
  687.      putc ('\n', stderr);
  688.      for (ptr = help;  *ptr != NULL;  ++ptr)
  689.           fprintf (stderr, "%s\n", strdetab (strcpy (temp, *ptr), 6));
  690.  
  691.      fprintf (stderr, "\nv%s (%s) This is free software released under the GNU General Public\n",
  692.                       version, VERDATE);
  693.      fputs ("License.  Please send suggestions/bug reports to:  bob@kc2wz.bubble.org\n", stderr);
  694.      exit (0);
  695. }
  696.