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