home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / fish / telecom / uucp_442 / src / dmail / sendmail.c < prev    next >
C/C++ Source or Header  |  1990-12-27  |  9KB  |  514 lines

  1.  
  2. /*
  3.  *  SENDMAIL.C
  4.  *
  5.  *  $Header: Beta:src/uucp/src/dmail/RCS/sendmail.c,v 1.1 90/02/02 12:04:06 dillon Exp Locker: dillon $
  6.  *
  7.  *  (C) Copyright 1985-1990 by Matthew Dillon,  All Rights Reserved.
  8.  *
  9.  *  Global Routines:    DO_REPLY()
  10.  *            DO_MAIL()
  11.  *
  12.  *  Static Routines:    WORD_SIZE()
  13.  *            FOPEN_SCRATCH()
  14.  *            FREOPEN_SCRATCH()
  15.  *            FCLOSE_SCRATCH()
  16.  *            FTERMINATE_SCRATCH()
  17.  *            DELETE_SCRATCH()
  18.  *            RUN_VI()
  19.  *            SEND_MAIL()
  20.  *
  21.  *
  22.  */
  23.  
  24. #include <stdio.h>
  25. #include <sys/types.h>
  26. #include <sys/stat.h>
  27. #include <sys/file.h>
  28. #ifdef UNIX
  29. #include <sys/ioctl.h>
  30. #endif
  31. #include <sys/time.h>
  32. #include <signal.h>
  33. #include "dmail.h"
  34. #include "config.h"
  35.  
  36. FILE *fi;
  37. char file[64];
  38.  
  39. void fclose_scratch();
  40. void fopen_scratch();
  41. void copy_header();
  42. void send_mail();
  43.  
  44. do_reply(garbage, itext)
  45. char *garbage;
  46. {
  47.     int i, j;
  48.     int anyargs  = 0;
  49.     int len;
  50.     char *ptr;
  51.     static char buf[1024];
  52.     char *istr;
  53.  
  54.     if (!(istr = get_var(LEVEL_SET, "_headchar")))
  55.     istr = ">";
  56.     if (push_base()) {
  57.     push_break();
  58.     pop_base();
  59.     fclose_scratch();
  60.     puts ("ABORTED, no mail sent");
  61.     unlink(file);
  62.     pop_break();
  63.     return (-1);
  64.     }
  65.     fopen_scratch();
  66.     strcpy (buf, "To: ");
  67.     for (i = 1; i < ac; ++i) {
  68.     if (*av[i] >= '0'  &&  *av[i] <= '9') {
  69.         if ((j = indexof(atoi(av[i]))) < 0) {
  70.         puts ("No such message");
  71.         fclose_scratch();
  72.         unlink(file);
  73.         pop_break();
  74.         return (-1);
  75.         }
  76.         Current = j;
  77.     } else {
  78.         if (anyargs)
  79.         strcat (buf, ", ");
  80.         anyargs = 1;
  81.         strcat (buf, av[i]);
  82.     }
  83.     }
  84.     len = strlen(buf);
  85.     switch (itext) {
  86.     case R_FORWARD:
  87.     case R_FWDINCL:
  88.     strcat (buf, "\n");
  89.     fputs (buf, fi);
  90.     fputs ("Subject: \n", fi);
  91.     break;
  92.     case R_INCLUDE:
  93.     case R_REPLY:
  94.     if (anyargs) {
  95.         strcat (buf, ", ");
  96.         len = strlen(buf);
  97.     }
  98.     buf[len] = 0;
  99.     if (Current >= 0) {
  100.         char *rf = get_var(LEVEL_SET, "replyfields");
  101.         if (rf == NULL)
  102.         rf = "";
  103.         while (*rf) {       /* attempt to find the fields listed */
  104.         char *re;
  105.         char *ptr;
  106.         char c;
  107.         for (re = rf; *re && *re != ' ' && *re != 9; ++re);
  108.         c = *re;
  109.         *re = 0;
  110.         ptr = get_field(rf);
  111.         if (*ptr) {
  112.             *re = c;
  113.             sprintf (buf + len, "%s\n", ptr);
  114.             break;
  115.         }
  116.         *re = c;
  117.         while (*re == ' ' || *re == 9)
  118.             ++re;
  119.         rf = re;
  120.         }
  121.         if (*rf == 0) {
  122.         sprintf (buf + len, "%.*s\n",
  123.             word_size(Entry[Current].from), Entry[Current].from);
  124.         }
  125.     }
  126.     fputs (buf, fi);
  127.  
  128.     fputs ("Cc: ", fi);
  129.     ptr = get_field ("Cc:");
  130.     if (*ptr)
  131.         fputs (ptr, fi);
  132.  
  133.     fputs ("\nSubject: Re: ", fi);
  134.     {
  135.         char *ptr = get_field("Subject:");
  136.         for (;;) {                              /*  skip multiple Re:'s */
  137.         while (*ptr == ' ' || *ptr == '\t')
  138.             ++ptr;
  139.         if (strnicmp(ptr, "re:", 3) == 0) {
  140.             ptr += 3;
  141.             continue;
  142.         }
  143.         break;
  144.         }
  145.         fputs(ptr, fi);
  146.     }
  147.     fputs ("\n", fi);
  148.     break;
  149.     case R_MAIL:
  150.     fputs (buf, fi);
  151.     fputs ("\n", fi);
  152.     fputs ("Cc: \n", fi);
  153.     fputs ("Bcc: \n", fi);
  154.     fputs ("Subject: \n", fi);
  155.     break;
  156.     default:
  157.     puts ("INTERNAL STUPID MAIL ERROR: REPLY");
  158.     break;
  159.     }
  160.     fputs ("\n\n", fi);
  161.     if (itext == R_FORWARD || itext == R_FWDINCL || itext == R_INCLUDE) {
  162.     position_current();
  163.     if (itext == R_FORWARD || itext == R_FWDINCL) {
  164.         if (Current >= 0)
  165.         fprintf (fi, "ORIGINALLY From %s\n", Entry[Current].from);
  166.     } else {
  167.         skip_to_data (m_fi);
  168.     }
  169.     while ((fgets (Buf, MAXFIELDSIZE, m_fi) != NULL) && !isfrom(Buf)) {
  170.         if (itext == R_INCLUDE || itext == R_FWDINCL)
  171.         fputs(istr, fi);
  172.         fputs (Buf, fi);
  173.     }
  174.     fputs ("\n", fi);
  175.     }
  176.     copy_header (fi);
  177.     fclose_scratch();
  178.     if (itext != R_MAIL) {
  179.     push_break();
  180.     if (Current >= 0) {
  181.         Entry[Current].status |= ST_SCR;
  182.         write_file("t:Original", O_CREAT | O_TRUNC, ST_SCR, 0);
  183.         Entry[Current].status &= ~ST_SCR;
  184.     }
  185.     pop_break();
  186.     }
  187.     j = -1;
  188. loop:
  189.     ++j;
  190.     if (run_vi() || j) {
  191.     push_break();
  192.     switch (do_ask()) {
  193.     case 1:
  194.         puts ("SENDING.. wait");
  195.         send_mail();
  196.         {
  197.         FILE *li = fopen(file, "r");
  198.         char buf[128], *ptr = NULL;
  199.  
  200.         if (li) {
  201.             while (fgets(buf, 128, li) && buf[0] != '\n') {
  202.             if (strncmp(buf, "Farchive:", 9) == 0) {
  203.                 buf[strlen(buf)-1] = '\0';
  204.                 for (ptr = buf + 9; *ptr == ' '; ++ptr);
  205.                 if (ptr[0] == '$')
  206.                 ptr = get_var(LEVEL_SET, ptr+1);
  207.                 break;
  208.             }
  209.             }
  210.             fclose(li);
  211.         }
  212.         archive_mail(ptr);
  213.         }
  214.         unlink(file);
  215.         break;
  216.     case 2:
  217.         pop_break();
  218.         goto loop;
  219.     default:
  220.         unlink (file);
  221.         break;
  222.     }
  223.     pop_base();
  224.     pop_break();
  225.     } else {
  226.     puts ("File not modified or ABORTED, no mail sent");
  227.     unlink(file);
  228.     pop_base();
  229.     }
  230.     unlink ("T:Original");
  231. }
  232.  
  233. do_ask()
  234. {
  235.     char in[256];
  236.  
  237.     if (!S_ask)
  238.     return (1);
  239.     fputs ("\n(Send, Vi, Quit) ?", stdout);
  240.     fflush(stdout);
  241.     gets (in);
  242.     switch (in[0]) {
  243.     case 's':
  244.     case 'S':
  245.     return (1);
  246.     case 'q':
  247.     case 'Q':
  248.     puts ("ABORT, no mail sent");
  249.     return (3);
  250.     case 'v':
  251.     case 'V':
  252.     default:
  253.     return (2);
  254.     }
  255. }
  256.  
  257.  
  258.  
  259. static void
  260. copy_header(fi)
  261. FILE *fi;
  262. {
  263.     FILE *fs;
  264.     char *ptr;
  265.     char *tmp = NULL;
  266.  
  267.     if (ptr = get_var (LEVEL_SET, "header")) {
  268.     push_break();
  269.     fs = fopen(ptr, "r");
  270.     if (fs == NULL) {   /*  check uulib:    */
  271.         tmp = malloc(strlen(ptr) + strlen(MakeConfigPath(UULIB, "")) + 1);
  272.         sprintf(tmp, "%s%s", MakeConfigPath(UULIB, ""), ptr);
  273.         fs = fopen(tmp, "r");
  274.     }
  275.     if (fs) {
  276.         while (fgets (Buf, MAXFIELDSIZE, fs) != NULL)
  277.         fputs (Buf, fi);
  278.         fclose (fs);
  279.     } else {
  280.         printf ("Cannot open header file %d %s\n", strlen(ptr), ptr);
  281.         perror ("fopen");
  282.     }
  283.     if (tmp)
  284.         free(tmp);
  285.     pop_break();
  286.     }
  287. }
  288.  
  289.  
  290. static void
  291. fopen_scratch()
  292. {
  293.     static int c;
  294.     int fd;
  295.  
  296.     sprintf(file, "t:dmt%d%d", getpid(), c++);
  297.     fd = open(file, O_RDWR|O_CREAT|O_TRUNC, 0700);
  298.     if (fd < 0) {
  299.     perror ("Dmail, cannot open scratch file");
  300.     done (1);
  301.     }
  302. #ifdef AMIGA        /*    fix bug in Lattice C fdopen */
  303.     fi = fopen("nil:", "w");
  304.     fclose(fi);
  305. #endif
  306.     fi = fdopen(fd, "w+");
  307. }
  308.  
  309. static void
  310. fclose_scratch()
  311. {
  312.     if (fi != NULL) {
  313.     fflush (fi);
  314.     fclose (fi);
  315.     fi = NULL;
  316.     }
  317. }
  318.  
  319.  
  320. static
  321. word_size(str)
  322. register char *str;
  323. {
  324.     register int size = 0;
  325.  
  326.     while (*str) {
  327.     if (*str == ' ')
  328.         return (size);
  329.     ++str;
  330.     ++size;
  331.     }
  332.     return (size);
  333. }
  334.  
  335.  
  336. static
  337. run_vi()
  338. {
  339. #ifdef UNIX
  340.     char buf[64];
  341.     int ret;
  342.     volatile int pid = 0;
  343. #endif
  344.     struct stat stat1, stat2;
  345.     char *argv[3];
  346.  
  347.     argv[0] = visual;
  348.     argv[1] = file;
  349.     argv[2] = NULL;
  350.     if (push_base()) {
  351.     push_break();
  352.     pop_base();
  353. #ifdef UNIX
  354.     if (pid) {
  355.         kill (pid, SIGKILL);
  356.         sprintf (buf, "t:Ex%d", pid); unlink (buf);
  357.         sprintf (buf, "t:Rx%d", pid); unlink (buf);
  358.         wait(0);
  359.         system ("clear; reset ; clear");
  360.         pid = 0;
  361.     }
  362. #endif
  363.     pop_break();
  364.     return (0);
  365.     }
  366.     stat1.st_mtime = stat2.st_mtime = stat1.st_ctime = stat2.st_ctime = 0;
  367.     stat (file, &stat1);
  368.     if (S_novibreak)
  369.     push_break();
  370.  
  371. #ifdef UNIX
  372.     pid = vfork();
  373.     if (!pid) {
  374.     execv (visual, argv);
  375.     printf ("Cannot exec visual: %s\n", visual);
  376.     _exit (1);
  377.     }
  378.     while ((ret = wait(0)) > 0) {
  379.     if (ret == pid)
  380.         break;
  381.     }
  382. #endif
  383. #ifdef AMIGA
  384.     {
  385.     short i;
  386.     static char buf[128];
  387.  
  388.     strcpy(buf, argv[0]);
  389.     for (i = 1; argv[i]; ++i) {
  390.         strcat(buf, " ");
  391.         strcat(buf, argv[i]);
  392.     }
  393.     Execute(buf, NULL, NULL);
  394.     }
  395. #endif
  396.     if (S_novibreak)
  397.     pop_break();
  398.     stat (file, &stat2);
  399.     pop_base();
  400.     return (!(stat1.st_mtime==stat2.st_mtime));
  401. }
  402.  
  403.  
  404. #ifdef UNIX
  405.  
  406. static void
  407. send_mail()
  408. {
  409.     int fd, stdin_fd;
  410.     char *argv[6];
  411.  
  412.     push_break();
  413.     argv[0] = S_sendmail;
  414.     argv[1] = "-t";
  415.     argv[2] = "-oem";
  416.     argv[3] = "-i";
  417.     if (S_verbose) {
  418.     argv[4] = "-v";
  419.     argv[5] = NULL;
  420.     } else {
  421.     argv[4] = NULL;
  422.     }
  423.  
  424.     fd = open (file, O_RDONLY, 0);
  425.     if (fd < 0) {
  426.     perror ("Dmail, Cannot open scratch file");
  427.     done (1);
  428.     }
  429.     lseek(fd, 0L, 0);
  430.  
  431.     stdin_fd = dup (0);
  432.     dup2 (fd, 0);       /* STDIN = message file */
  433.     close(fd);          /* don't need message file anymore  */
  434.     if (!fork()) {
  435.     int fd = open("/dev/tty", O_RDWR, 0);
  436.     if (fd >= 0) {
  437.         ioctl(fd, TIOCNOTTY, 0);
  438.         close(fd);
  439.         freopen("/dev/null", "w", stdout);
  440.         freopen("/dev/null", "w", stderr);
  441.     }
  442.     execv (S_sendmail, argv);
  443.     printf ("Unable to exec sendmail: %s\n", S_sendmail);
  444.     _exit (1);
  445.     }
  446.     dup2 (stdin_fd, 0);     /* restore STDIN    */
  447.     close(stdin_fd);
  448.     if (S_verbose) {
  449.     puts ("Waiting for sendmail...");
  450.     wait (0);
  451.     puts ("Sendmail done");
  452.     }
  453.     pop_break();
  454. }
  455.  
  456. #endif
  457. #ifdef AMIGA
  458.  
  459. static void
  460. send_mail()
  461. {
  462.     static char Buf[256];
  463.  
  464.     push_break();
  465.     sprintf(Buf, "%s < %s%s -f %s", S_sendmail, file, (S_verbose ? " -v" : ""), user_name);
  466.  
  467.     printf("Sending\n", Buf);
  468.     if (Execute(Buf, NULL, NULL) == 0)
  469.     printf("Unable to run: %s\n", Buf);
  470.  
  471.     pop_break();
  472. }
  473.  
  474. #endif
  475.  
  476.  
  477.  
  478.  
  479.  
  480. static
  481. archive_mail(ptr)
  482. char *ptr;
  483. {
  484.     FILE *ifi, *ofi;
  485.     long tim = time(NULL);
  486.  
  487.     if (!ptr)
  488.     ptr = get_var(LEVEL_SET, "archive");
  489.     if (ptr == NULL || *ptr == '\0')
  490.     return(-1);
  491.     ifi = fopen(file, "r");
  492.     if (ifi == NULL) {
  493.     puts ("Cannot open scratch file");
  494.     return(-1);
  495.     }
  496.     ofi = fopen(ptr, "a");
  497.     if (ofi == NULL) {
  498.     puts ("Cannot open archive file");
  499.     fclose(ifi);
  500.     return(-1);
  501.     }
  502.     sprintf (Buf, "\nFrom %s (ARCHIVE)\n", user_name);
  503.     fputs (Buf, ofi);
  504.     sprintf (Buf, "Date: %s", ctime(&tim));
  505.     fputs (Buf, ofi);
  506.     while (fgets (Buf, MAXFIELDSIZE, ifi))
  507.     fputs (Buf, ofi);
  508.     fclose(ofi);
  509.     fclose(ifi);
  510.     return (1);
  511. }
  512.  
  513.  
  514.