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