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 / sendmail.c < prev    next >
Text File  |  1994-09-25  |  17KB  |  620 lines

  1. /*  sendmail.c   This routine lets a user compose and sendmail.
  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. /* Send mail to all addressees.  Mail that cannot be sent is saved in the
  26.    user's home directory in the file 'dead.letter'.  Rewritten --REB  */
  27.  
  28. #include "uucp.h"
  29. #include "mail.h"
  30. #include <time.h>
  31. #include <ctype.h>
  32. #include <signal.h>
  33.  
  34. #define WORDSIZE  40
  35.  
  36. EXTERN QQ char sepsym, quotechar, *dotilde;
  37. EXTERN QQ flag usedotilde, rmailin;
  38.  
  39. static QQ flag fromdaemon;                      /* mail from user 'daemon' */
  40.  
  41.  
  42. int sendmail()
  43. {
  44.      char *words[WORDSIZE];
  45.      register int i;
  46.      int n, result;
  47.      char *deadletter = "dead.letter";
  48.  
  49.      *tempfile = '\0';
  50.  
  51.      /* Is user local user 'daemon'? */
  52.      fromdaemon =  strucmp (user, "daemon") == 0  ? TRUE : FALSE;
  53.      asetuid (0);
  54.      maketemp (tempfile, '1', FALSE);        /* compose mail in temp file */
  55.      asetuid (myuid);
  56.  
  57.      /* If ABORT is returned something went wrong.  An error message should
  58.         have already be display, just exit quietly.  Otherwise, send the
  59.         mail. */
  60.  
  61.      if (compmail() == OK)
  62.        {
  63.           /* separate the destination addresses */
  64.           n = getargs (words, address, WORDSIZE);
  65.  
  66.           /* send to each address */
  67.           puts ("\n");
  68.  
  69.           if (n > 0)
  70.             {
  71.                /* Load rmail if it isn't already loaded.  We may be back with
  72.                   more. */
  73. #ifndef _OSK
  74.                if (!rmailin)
  75.                  {
  76.                     asetuid (0);
  77.  
  78.                     if (nmlink (rmail, 0, 0) == -1)
  79.                          if (nmload (rmail, 0, 0) == -1)
  80.                               fatal ("sendmail: can't load rmail");
  81.                  }
  82. #else
  83.                if (n > 1  &&  !rmailin)
  84.                  {
  85.                     asetuid (0);
  86.  
  87.                     if (modlink (rmail, 0) == -1)
  88.                       {
  89.                          char tmp[64];
  90.  
  91.                          if (modloadp (rmail, 0, tmp) == -1)
  92.                               fatal ("sendmail: can't load rmail");
  93.                       }
  94.                  }
  95. #endif
  96.                asetuid (myuid);
  97.                rmailin = TRUE;
  98.  
  99.                for (i = 0; i < n; i++)
  100.                  {
  101.                     printf ("%s %s %s\n",
  102.                             forward ? i == 0 ? "Forwarding" :  "          "
  103.                                     : i == 0 ? "Sending"    :  "       ",
  104.                             i == 0  ? "mail to:"  : "        ",
  105.                             words[i]);
  106.  
  107.                     sprintf (cmd, "rmail %s %s",
  108.                                   tempfile, words[i]);
  109.  
  110.                     if (debug > 0)
  111.                          puts  (cmd);
  112.  
  113.                     /* superuser runs RMAIL but don't quit on errors */
  114.                     asetuid (0);
  115.                     result = docmd_na (cmd);
  116.                     asetuid (myuid);
  117.  
  118.                     if (result != 0)
  119.                       {
  120.                          printf ("undelivered mail put in '%s'\n\n",
  121.                                  deadletter);
  122.  
  123.                          sprintf (fname, "%s/%s", homedir, deadletter);
  124.                          fileapnd (tempfile, fname, TRUE);
  125.                       }
  126.                  }
  127.             }
  128.           else
  129.             {
  130.                Bell();
  131.                printf ("mailx: who do I send the mail to?  Mail put in '%s'\n\n",
  132.                        deadletter);
  133.  
  134.                sprintf (fname, "%s/%s", homedir, deadletter);
  135.                fileapnd (tempfile, fname, TRUE);
  136.             }
  137.        }
  138.  
  139.      /* throw away mail temp file */
  140.      asetuid (0);
  141.      unlink (tempfile);
  142.      asetuid (myuid);
  143.      *tempfile = '\0';
  144. }
  145.  
  146.  
  147.  
  148. /* compose mail
  149.  
  150.    Changed to allow forwarded mail, mail from local mailer daemon such as
  151.    bounced mail.  The global variable tempfile contains the name of the
  152.    temporary mail file.  TRUE (OK) is returned if mail is to be sent.  ABORT
  153.    is returned if there was some type of of error. */
  154.  
  155. int compmail()
  156. {
  157.      char *words[40], *p, **wordptr, **wordlast;
  158.      int count;
  159.      struct sgtbuf date;
  160.      long seq;
  161.      register char *lp;
  162.      char *got_escape = "<ESC> hit...exiting";
  163.  
  164.      lp = line;
  165.  
  166.      /* open temporary mail file */
  167.      asetuid (0);                                      /* BAS */
  168.  
  169.      if ((ltrfile = fopen (tempfile, "w")) == NULL)
  170.           fatal ("compmail: can't open temp file");
  171.  
  172.      /* set ownership of file and reset uid -- BAS */
  173.      chown (tempfile, myuid);
  174.      asetuid (myuid);
  175.      fixperms (ltrfile);
  176.  
  177.      /* Get Message-ID number.  Moved here to speed things up --REB */
  178.      seq = getseq (MAILSEQ);
  179.  
  180.      if (!redirect)
  181.        {
  182. #ifndef _OSK
  183.           if (!usedotilde)
  184.             {
  185.                if (nmlink (dotilde, 0, 0) == -1)
  186.                     if (nmload (dotilde, 0, 0) == -1)
  187.                          fatal ("compmail: can't load dotilde");
  188.                usedotilde = TRUE;
  189.             }
  190. #endif
  191.           cls();
  192.        }
  193.  
  194.      /* From rickadams Tue Feb 12 10:57:02 1991 -0800
  195.         Added 'daemon' --REB */
  196.  
  197.      sprintf (lp,  "From %s %s",
  198.                    !fromdaemon ? user : "MAILER-DAEMON",  date822());
  199.  
  200.      if (!redirect)
  201.           puts (lp);
  202.  
  203.      fprintf (ltrfile, "%s\n", lp);
  204.  
  205.      /* From: Rick Adams <rickadams@ccentral.UUCP>
  206.         From: rickadams@ccentral.UUCP
  207.         Added daemon -- REB */
  208.  
  209.      if (!fromdaemon)
  210.           sprintf (lp, "%s%s%s%s%c%s%s",
  211.                        Hfrom,
  212.                        *name != '\0' ? name : "",
  213.                        *name != '\0' ? " <" : "",
  214.                        sepsym != '!' ? user : sitename,
  215.                        sepsym,
  216.                        sepsym != '!' ? sitename : user,
  217.                        *name != '\0' ? ">" : "");
  218.      else
  219.           sprintf (lp, "%sMail Delivery Subsystem <MAILER-DAEMON@%s>",
  220.                        Hfrom, sitename);
  221.  
  222.      if (!redirect)
  223.           puts (lp);
  224.  
  225.      fprintf (ltrfile, "%s\n", lp);
  226.  
  227.      /* Message-Id: line */
  228.      getime (&date);
  229.      sprintf (lp, "Message-Id: <%02d%02d%02d%02d%02d.AA%05ld@%s>",
  230.                   date.t_year, date.t_month, date.t_day, date.t_hour,
  231.                   date.t_minute, seq, sitename);
  232.  
  233.      fprintf (ltrfile, "%s\n", lp);
  234.  
  235.      if (!redirect)
  236.           puts (lp);
  237.  
  238.  
  239.      /* Subject: line */
  240.      if (forward)
  241.        {
  242.           if (extract_orig_header (ltrfile) == ABORT)
  243.             {
  244.                fclose (ltrfile);
  245.                return (ABORT);
  246.             }
  247.        }
  248.      else
  249.        {
  250.           if (*subject == '\0')
  251.             {
  252.                fputs (Hsubject, stdout);
  253.  
  254.                if (!redirect)
  255.                  {
  256.                     if (mfgets (subject, sizeof (subject), stdin) == NULL)
  257.                       {
  258.                          errno = 0;
  259.                          fatal (got_escape);
  260.                       }
  261.                  }
  262.                else
  263.                  {
  264.                     fflush (stdout);
  265.                     count = readln (2, subject, sizeof (subject) - 1);
  266.  
  267.                     if (count < 1)
  268.                          count = 1;
  269.  
  270.                     subject[count - 1] = '\0';
  271.                  }
  272.             }
  273.           else
  274.             {
  275.                if (!redirect)
  276.                     printf ("%s%s\n", Hsubject, subject);
  277.             }
  278.  
  279.           fprintf (ltrfile, "%s%s\n",
  280.                            Hsubject,
  281.                            *subject != '\0' ? subject : "<No subject given>");
  282.        }
  283.  
  284.      /* Reply-To: bob@kc2wz.bubble.org
  285.         If mail comes from daemon Reply-To is set to 'postmaster'. */
  286.  
  287.      if (!fromdaemon)
  288.           sprintf (lp, "%s%s%s%s%c%s%s",
  289.                        Hreplyto,
  290.                        *name != '\0' ? name : "",
  291.                        *name != '\0' ? " <" : "",
  292.                        sepsym != '!' ? user : sitename,
  293.                        sepsym,
  294.                        sepsym != '!' ? sitename : user,
  295.                        *name != '\0' ? ">" : "");
  296.      else
  297.           sprintf (lp, "%spostmaster%c%s", Hreplyto, sepsym, sitename);
  298.  
  299.      if (!redirect)
  300.           puts (lp);
  301.  
  302.      fprintf (ltrfile, "%s\n", lp);
  303.  
  304.      /* To: addressee line(s).  If message is from redirected file, don't
  305.         bother with showing the addresses. */
  306.  
  307.      if (!redirect)
  308.           fputs (Hto, stdout);
  309.  
  310.      fputs (Hto, ltrfile);
  311.      strcpy (temp, address);
  312.      count = 4;
  313.      wordptr = words;
  314.      wordlast = words + getargs (words, temp, WORDSIZE);
  315.  
  316.      while (wordptr < wordlast)
  317.        {
  318.           int wordlen = strlen (*wordptr);
  319.  
  320.           if (count + wordlen >= 78  &&  wordlen < 76)
  321.             {
  322.                strcpy (lp, "\n    ");
  323.                fputs (lp, ltrfile);
  324.  
  325.                if (!redirect)
  326.                     fputs (lp, stdout);
  327.  
  328.                count = 4;
  329.             }
  330.           fprintf (ltrfile, "%s", *wordptr);
  331.  
  332.           if (!redirect)
  333.                fputs (*wordptr, stdout);
  334.  
  335.           count += wordlen;
  336.  
  337.           if (++wordptr < wordlast)
  338.             {
  339.                strcpy (lp, ", ");
  340.                fputs (lp, ltrfile);
  341.  
  342.                if (!redirect)
  343.                     fputs (lp, stdout);
  344.  
  345.                count += 2;
  346.             }
  347.        }
  348.  
  349.      if (!redirect)
  350.           putchar ('\n');
  351.  
  352.      putc ('\n', ltrfile);
  353.  
  354.      /* Sender: line *
  355.  
  356.      /* Date: Tue, 12 Feb 91 10:57:45 -0800 */
  357.      sprintf (lp, "%s%s", Hdate, date822());
  358.  
  359.      if (!redirect)
  360.           puts (lp);
  361.  
  362.      fprintf (ltrfile, "%s\n", lp);
  363.  
  364.      /* Cc: line     Added forward and daemon --REB */
  365.      if (cc_prompt && !fromdaemon && !forward)
  366.        {
  367.           fputs (Hcc, stdout);
  368.  
  369.           if (!redirect)
  370.             {
  371.                if (mfgets (lp, sizeof (line), stdin) == NULL)
  372.                  {
  373.                     errno = 0;
  374.                     fatal (got_escape);
  375.                  }
  376.             }
  377.           else
  378.             {
  379.                fflush (stdout);
  380.                count = readln (2, lp, 132);
  381.  
  382.                if (count < 1)
  383.                     count = 1;
  384.  
  385.                line[count - 1] = '\0';
  386.             }
  387.           p = skipspace (line);
  388.  
  389.           if (*p)
  390.             {
  391.                int n;
  392.  
  393.                /* Add new addresses to addressee list.  First save where the
  394.                   new ones will go. */
  395.  
  396.                n = getargs (words, p, WORDSIZE);
  397.                p = strend (address);
  398.                parse_addr (n, words);
  399.  
  400.                /* write Cc: line using parsed addresses */
  401.                fputs (Hcc, ltrfile);
  402.                strcpy (temp, p);
  403.                count = 4;
  404.                wordptr = words;
  405.                wordlast = words + getargs (words, temp, WORDSIZE);
  406.  
  407.                while (wordptr < wordlast)
  408.                  {
  409.                     int wordlen = strlen (*wordptr);
  410.  
  411.                     if (count + wordlen >= 78  &&  wordlen < 76)
  412.                       {
  413.                          fputs ("\n    ", ltrfile);
  414.                          count = 4;
  415.                       }
  416.                     fputs (*wordptr, ltrfile);
  417.                     count += wordlen;
  418.  
  419.                     if (++wordptr < wordlast)
  420.                       {
  421.                          fputs (", ", ltrfile);
  422.                          count += 2;
  423.                       }
  424.                  }
  425.                putc ('\n', ltrfile);
  426.             }
  427.        }
  428.  
  429.      /* In-Reply-To: Fromname's/address's message of date line */
  430.      if (reply && *frommsgid != '\0')
  431.        {
  432.           sprintf (lp, "In-Reply-To: %s's message of %s", fromname, fromdate);
  433.  
  434.           if (!redirect)
  435.                puts (lp);
  436.  
  437.           fprintf (ltrfile, "%s\n", lp);
  438.           sprintf (lp, "             id <%s>", frommsgid);
  439.  
  440.           if (!redirect)
  441.                puts (lp);
  442.  
  443.           fprintf (ltrfile, "%s\n", lp);
  444.        }
  445.  
  446.      /* X-Mailer: line */
  447. #ifdef OS9
  448.      sprintf (lp, "X-Mailer: Mailx (OS-9/6809 UUCP v%s %s)",
  449. #else
  450. # ifndef _OS9K
  451.      sprintf (lp, "X-Mailer: Mailx (OS-9/68K UUCP v%s %s)",
  452. # else
  453.      sprintf (lp, "X-Mailer: Mailx (OS-9000 UUCP v%s %s)",
  454. # endif
  455. #endif
  456.                    version, VERDATE);
  457.  
  458.      fprintf (ltrfile, "%s\n", lp);
  459.  
  460.      if (!redirect)
  461.           puts (lp);
  462.  
  463.      /* blank line after header */
  464.      putc ('\n', ltrfile);
  465.  
  466.      if (!redirect)
  467.           putchar ('\n');
  468.  
  469.      /* forwarding? */
  470.      if (forward)
  471.        {
  472.           int tilde;
  473.           char *dash = "----------";
  474.  
  475.           sprintf (temp, "%s Forwarded message begins here %s\n", dash, dash);
  476.  
  477.           if (!redirect)
  478.                fputs (temp, stdout);
  479.  
  480.           fputs (temp, ltrfile);
  481.           fclose (ltrfile);
  482.           sprintf (temp, "dotilde \"~r %s\" %d %d %c %s %s %s",
  483.                          message, t2flag, myuid, quotechar, tempfile, homedir,
  484.                          message);
  485.  
  486.           tilde = docmd_na (temp);
  487.  
  488.           if (tilde == SIGINT  ||  tilde == SIGQUIT)
  489.                interrupt (0);
  490.           else if (tilde == ABORT)
  491.                return (ABORT);
  492.  
  493.           if ((ltrfile = fopen (tempfile, "a")) == NULL)
  494.             {
  495.                printf ("\n%s: can't forward letter", pname);
  496.                return (ABORT);
  497.             }
  498.  
  499.           fprintf (ltrfile, "%s End forwarded message %s\n", dash, dash);
  500.        }
  501.  
  502.      /* Compose body of text.  Clear line buffer first. */
  503.      memset (line, '\0', sizeof (line));
  504.      while (mfgets (line, sizeof (line), stdin) != NULL)
  505.        {
  506.           int tilde;
  507.  
  508.           if (*line == '.'  &&  *(line+1) == '\0')
  509.                break;
  510.  
  511.           /* tilde command? */
  512.           if (*line == '~')
  513.             {
  514.                fclose (ltrfile);
  515.                sprintf (temp, "dotilde \"%s\" %d %d %c %s %s %s",
  516.                               line, t2flag, myuid, quotechar, tempfile,
  517.                               homedir, message);
  518.  
  519.                tilde = docmd_na (temp);
  520.  
  521.                if (tilde == SIGINT  ||  tilde == SIGQUIT)
  522.                     interrupt (0);
  523.                else if (tilde == ABORT)
  524.                     return (ABORT);
  525.  
  526.                asetuid (0);
  527.  
  528.                if ((ltrfile = fopen (tempfile, "a")) == NULL)
  529.                  {
  530.                     fputs ("compmail: can't reopen letter file", stderr);
  531.                     asetuid (myuid);
  532.                     return (ABORT);
  533.                  }
  534.                asetuid (myuid);
  535.             }
  536.           else
  537.                fprintf (ltrfile, "%s\n", lp);
  538.        }
  539.  
  540.      /* append signature? */
  541.      if (usesig  &&  !fromdaemon)
  542.        {
  543.           register FILE *sigfile;
  544.  
  545. #ifdef _OSK
  546.           sprintf (fname, "%s/%s", homedir,
  547.                           usesig == USESIG ? ".signature" : ".alt_signature");
  548. #else
  549.           sprintf (fname, "%s/%s/%s", homedir, uudir,
  550.                           usesig == USESIG ? "signature" : "alt_signature");
  551. #endif
  552.           /* Added fix so that it goes up one line ONLY if '.' was used.
  553.              Using ESC interrupted the last line of the text on the screen
  554.              --BGP */
  555.  
  556.           if (!redirect  &&  *line == '.')
  557.             {
  558.                CurUp();
  559.                fputs (" \b", stdout);
  560.             }
  561.           fflush (stdout);
  562.  
  563.           if ((sigfile = fopen (fname, "r")) != NULL)
  564.             {
  565.                fputs ("-- \n", ltrfile);
  566.  
  567.                if (!redirect)
  568.                     puts ("--");
  569.  
  570.                while (mfgets (lp, sizeof (line), sigfile) != NULL)
  571.                  {
  572.                     fprintf (ltrfile, "%s\n", lp);
  573.  
  574.                     if (!redirect)
  575.                          puts (lp);
  576.                  }
  577.                fclose (sigfile);
  578.             }
  579.        }
  580.      fclose (ltrfile);
  581.      return (OK);
  582. }
  583.  
  584.  
  585.  
  586. /* Get original header info for forwarded mail. */
  587.  
  588. int extract_orig_header (ltr)
  589. FILE *ltr;
  590. {
  591.      register char *lp;
  592.      FILE *origmsg;
  593.  
  594.      if ((origmsg = fopen (message, "r")) == NULL)
  595.           return (ABORT);
  596.  
  597.      /* Get original To: field.  Tack 'X-' to the beginning of it.  Ignore
  598.         the other fields. */
  599.  
  600.      lp = line;
  601.      while (mfgets (lp, sizeof (line), origmsg) != NULL   &&  *lp != '\0')
  602.        {
  603.           if (*lp == '>'  &&  strnucmp (lp, ">From ", 6) == 0)
  604.                continue;
  605.           if (strnucmp (Hsubject, lp, 9) == 0
  606.                || strnucmp (Hsubj, lp ,6) == 0)
  607.             {
  608.                sprintf (temp, "%s (forwarded)\n", lp);
  609.                fputs (temp, stdout);
  610.                fputs (temp, ltr);
  611.             }
  612.           else if (strnucmp (lp, Hsender, 8) == 0)
  613.                fprintf (ltr, "%s%s\n", Hx, lp);
  614.           else if (strnucmp (lp, Hto, 3) == 0)
  615.                fprintf (ltr, "%s%s\n", Hx, lp);
  616.        }
  617.      fclose (origmsg);
  618.      return (OK);
  619. }
  620.