home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / sendmail-5.65 / rmail / rmail.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-31  |  5.8 KB  |  229 lines

  1. /*
  2.  * Copyright (c) 1981, 1988 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that: (1) source distributions retain this entire copyright
  7.  * notice and comment, and (2) distributions including binaries display
  8.  * the following acknowledgement:  ``This product includes software
  9.  * developed by the University of California, Berkeley and its contributors''
  10.  * in the documentation or other materials provided with the distribution
  11.  * and in all advertising materials mentioning features or use of this
  12.  * software. Neither the name of the University nor the names of its
  13.  * contributors may be used to endorse or promote products derived
  14.  * from this software without specific prior written permission.
  15.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  16.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  17.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18.  */
  19.  
  20. #ifndef lint
  21. char copyright[] =
  22. "@(#) Copyright (c) 1981, 1988 The Regents of the University of California.\n\
  23.  All rights reserved.\n";
  24. #endif /* not lint */
  25.  
  26. #ifndef lint
  27. static char sccsid[] = "@(#)rmail.c    4.15 (Berkeley) 5/31/90";
  28. #endif /* not lint */
  29.  
  30. /*
  31.  * RMAIL -- UUCP mail server.
  32.  *
  33.  *    This program reads the >From ... remote from ... lines that
  34.  *    UUCP is so fond of and turns them into something reasonable.
  35.  *    It calls sendmail giving it a -f option built from these lines. 
  36.  */
  37.  
  38. #include <sysexits.h>
  39. #include <sys/types.h>
  40. #include <sys/file.h>
  41. #include <sys/stat.h>
  42. #include <stdio.h>
  43. #include <paths.h>
  44.  
  45. typedef char bool;
  46. #define TRUE    1
  47. #define FALSE    0
  48.  
  49. extern char *index();
  50. extern char *rindex();
  51.  
  52. char *Domain = "UUCP";        /* Default "Domain" */
  53.  
  54. main(argc, argv)
  55.     int argc;
  56.     char **argv;
  57. {
  58.     char lbuf[1024];    /* one line of the message */
  59.     char from[512];        /* accumulated path of sender */
  60.     char ufrom[512];    /* user on remote system */
  61.     char sys[512];        /* a system in path */
  62.     char fsys[512];        /* first system in path */
  63.     char junk[1024];    /* scratchpad */
  64.     char *args[100];    /* arguments to mailer command */
  65.     register char *cp;
  66.     register char *uf = NULL;    /* ptr into ufrom */
  67.     int i;
  68.     long position;
  69.     struct stat sbuf;
  70. #ifdef DEBUG
  71.     bool Debug;
  72.  
  73.     if (argc > 1 && strcmp(argv[1], "-T") == 0) {
  74.         Debug = TRUE;
  75.         argc--;
  76.         argv++;
  77.     }
  78. #endif
  79.  
  80.     if (argc < 2) {
  81.         fprintf(stderr, "Usage: rmail user ...\n");
  82.         exit(EX_USAGE);
  83.     }
  84.     if (argc > 2 && strncmp(argv[1], "-D", 2) == 0) {
  85.         Domain = &argv[1][2];
  86.         argc -= 2;
  87.         argv += 2;
  88.     }
  89.     from[0] = '\0';
  90.     fsys[0] = '\0';
  91.     (void) strcpy(ufrom, _PATH_DEVNULL);
  92.  
  93.     for (position = 0;; position = ftell(stdin)) {
  94.         if (fgets(lbuf, sizeof lbuf, stdin) == NULL)
  95.             exit(EX_DATAERR);
  96.         if (strncmp(lbuf, "From ", 5) != 0 &&
  97.             strncmp(lbuf, ">From ", 6) != 0)
  98.             break;
  99.         (void) sscanf(lbuf, "%s %s", junk, ufrom);
  100.         cp = lbuf;
  101.         uf = ufrom;
  102.         for (;;) {
  103.             cp = index(cp + 1, 'r');
  104.             if (cp == NULL) {
  105.                 register char *p = rindex(uf, '!');
  106.  
  107.                 if (p != NULL) {
  108.                     *p = '\0';
  109.                     (void) strcpy(sys, uf);
  110.                     uf = p + 1;
  111.                     break;
  112.                 }
  113.                 (void) strcpy(sys, "");
  114.                 break;    /* no "remote from" found */
  115.             }
  116. #ifdef DEBUG
  117.             if (Debug)
  118.                 printf("cp='%s'\n", cp);
  119. #endif
  120.             if (strncmp(cp, "remote from ", 12) == 0)
  121.                 break;
  122.         }
  123.         if (cp != NULL)
  124.             (void) sscanf(cp, "remote from %s", sys);
  125.         if (fsys[0] == '\0')
  126.             (void) strcpy(fsys, sys);
  127.         if (sys[0]) {
  128.             (void) strcat(from, sys);
  129.             (void) strcat(from, "!");
  130.         }
  131. #ifdef DEBUG
  132.         if (Debug)
  133.             printf("ufrom='%s', sys='%s', from now '%s'\n", uf, sys, from);
  134. #endif
  135.     }
  136.     if (uf == NULL) {    /* No From line was provided */
  137.         fprintf(stderr, "No From line in rmail\n");
  138.         exit(EX_DATAERR);
  139.     }
  140.     (void) strcat(from, uf);
  141.     (void) fstat(0, &sbuf);
  142.     (void) lseek(0, position, L_SET);
  143.  
  144.     /*
  145.      * Now we rebuild the argument list and chain to sendmail. Note that
  146.      * the above lseek might fail on irregular files, but we check for
  147.      * that case below. 
  148.      */
  149.     i = 0;
  150.     args[i++] = _PATH_SENDMAIL;
  151.     args[i++] = "-oee";        /* no errors, just status */
  152.     args[i++] = "-odq";        /* queue it, don't try to deliver */
  153.     args[i++] = "-oi";        /* ignore '.' on a line by itself */
  154.     if (fsys[0] != '\0') {        /* set sender's host name */
  155.         static char junk2[512];
  156.  
  157.         if (index(fsys, '.') == NULL) {
  158.             (void) strcat(fsys, ".");
  159.             (void) strcat(fsys, Domain);
  160.         }
  161.         (void) sprintf(junk2, "-oMs%s", fsys);
  162.         args[i++] = junk2;
  163.     }
  164.                     /* set protocol used */
  165.     (void) sprintf(junk, "-oMr%s", Domain);
  166.     args[i++] = junk;
  167.     if (from[0] != '\0') {        /* set name of ``from'' person */
  168.         static char junk2[512];
  169.  
  170.         (void) sprintf(junk2, "-f%s", from);
  171.         args[i++] = junk2;
  172.     }
  173.     for (; *++argv != NULL; i++) {
  174.         /*
  175.          * don't copy arguments beginning with - as they will
  176.          * be passed to sendmail and could be interpreted as flags
  177.          * should be fixed in sendmail by using getopt(3), and
  178.          * just passing "--" before regular args.
  179.          */
  180.         if (**argv != '-')
  181.             args[i] = *argv;
  182.     }
  183.     args[i] = NULL;
  184. #ifdef DEBUG
  185.     if (Debug) {
  186.         printf("Command:");
  187.         for (i = 0; args[i]; i++)
  188.             printf(" %s", args[i]);
  189.         printf("\n");
  190.     }
  191. #endif
  192.     if ((sbuf.st_mode & S_IFMT) != S_IFREG) {
  193.         /*
  194.          * If we were not called with standard input on a regular
  195.          * file, then we have to fork another process to send the
  196.          * first line down the pipe. 
  197.          */
  198.         int pipefd[2];
  199. #ifdef DEBUG
  200.         if (Debug)
  201.             printf("Not a regular file!\n");
  202. #endif
  203.         if (pipe(pipefd) < 0)
  204.             exit(EX_OSERR);
  205.         if (fork() == 0) {
  206.             /*
  207.              * Child: send the message down the pipe. 
  208.              */
  209.             FILE *out;
  210.  
  211.             out = fdopen(pipefd[1], "w");
  212.             close(pipefd[0]);
  213.             fputs(lbuf, out);
  214.             while (fgets(lbuf, sizeof lbuf, stdin))
  215.                 fputs(lbuf, out);
  216.             (void) fclose(out);
  217.             exit(EX_OK);
  218.         }
  219.         /*
  220.          * Parent: call sendmail with pipe as standard input 
  221.          */
  222.         close(pipefd[1]);
  223.         dup2(pipefd[0], 0);
  224.     }
  225.     execv(_PATH_SENDMAIL, args);
  226.     fprintf(stderr, "Exec of %s failed!\n", _PATH_SENDMAIL);
  227.     exit(EX_OSERR);
  228. }
  229.