home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / sendmail-5.65c+IDA-1.4.4.1 / uiuc / uucp-queue.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-29  |  8.6 KB  |  372 lines

  1. #include     <stdio.h>
  2. #include    <sysexits.h>
  3. #include    "path.h"
  4.  
  5. #ifndef    lint
  6. static char RCSid[] = "$Header: uucp-queue.c,v 4.4 86/11/07 08:34:15 essick Exp $";
  7. #endif    /* !lint */
  8.  
  9. #ifndef    MAILLOG
  10. #define        MAILLOG        "/usr/lib/mail/MailLog"
  11. #endif    /* !MAILLOG */
  12.  
  13. /*
  14.  *    uucp-queue
  15.  *
  16.  *    This program takes a letter formatted for UUCP transmission
  17.  *    as standard input and a pair of arguements which correspond
  18.  *    to the host and user.  The end result is an invocation of
  19.  *    UUX on some nearby machine with a properly expended path.
  20.  *
  21.  *    Note that this method can result in loops. Let's hope that
  22.  *    things like sendmail will notice that the letter has been
  23.  *    through here before and do something about it....
  24.  *
  25.  *    Ray Essick    May 1, 1984
  26.  *
  27.  */
  28.  
  29. int     Debug = 0;
  30. int     Pathalias = 0;                    /* paths have embedded %s */
  31. int     PrefixBase = 0;                    /* expand user */
  32. char   *Command = (char *) NULL;            /* command to do */
  33. #define    DFLTCOMMAND    "/usr/bin/uux"            /* normally this */
  34.  
  35. extern char *strsave ();                /* in misc.c */
  36. extern int  strlower ();
  37. extern char *getpath ();                /* in getpath.c */
  38. extern char *index ();
  39.  
  40. main (argc, argv)
  41. int     argc;
  42. char  **argv;
  43. {
  44.     int     i,
  45.             j,
  46.             k;
  47.     char   *p,
  48.            *q,
  49.            *r;
  50.     char   *neighbor,
  51.            *rest;
  52.     char   *remainder;
  53.     char    remotbuf[1024];                /* hold some bigass paths */
  54.     char    cmdline[1024];
  55.     FILE * myson;
  56.     FILE * popen ();
  57.     char    nextdoor[255];                /* my neighbor */
  58.     char   *host;
  59.     char   *domain;                    /* portion of full host */
  60.     char   *path;
  61.     int     fullroute;                    /* complete route ? */
  62.     char   *InvokedAs;
  63.     char    options[1024];                /* uux options */
  64.  
  65.     FILE * logfd;                    /* log traffic */
  66.     char   *Logfromuser = "UnSpecified";
  67.     int     messagebytes;
  68.     char    Logtouser[BUFSIZ];
  69.  
  70.     struct findpath_f   hostpath;
  71.     struct findpath_f  *hostp;
  72.     struct findpath_f  *userp;
  73.     struct findpath_f  *findpath();
  74.  
  75.  
  76.     InvokedAs = argv[0];                /* save command name */
  77.     argc--;
  78.     argv++;
  79.     while (argc > 0 && argv[0][0] == '-')        /* parse options */
  80.     {                            /* wish i had getopt() */
  81.     if (strcmp (argv[0], "-") == 0)            /* end of options */
  82.     {
  83.         argc--;
  84.         argv++;
  85.         break;
  86.     }
  87.     if (strcmp (argv[0], "-c") == 0)        /* -c == common */
  88.     {
  89.         PrefixBase++;
  90.         argc--;
  91.         argv++;
  92.         continue;
  93.     }
  94.     if (strcmp (argv[0], "-d") == 0)        /* -d == Debugging */
  95.     {
  96.         Debug++;
  97.         argc--;
  98.         argv++;
  99.         continue;
  100.     }
  101.     if (strcmp (argv[0], "-p") == 0)        /* -p == pathalias format */
  102.     {
  103.         Pathalias++;
  104.         argc--;
  105.         argv++;
  106.         continue;
  107.     }
  108.     if (strncmp (argv[0], "-f", 2) == 0)        /* -fsender */
  109.     {
  110.         if (argv[0][2] != '\0')            /* not bare option */
  111.         {
  112.         Logfromuser = strsave (&argv[0][2]);
  113.         }
  114.         argc--;
  115.         argv++;
  116.         continue;
  117.     }
  118.     if (strncmp (argv[0], "-C", 2) == 0)        /* -Ccommand */
  119.     {
  120.         p = &argv[0][2];                /* "command" */
  121.         if (*p == 0)
  122.         {
  123.         goto usage;                /* empty command */
  124.         }
  125.         if (Command != (char *) NULL)
  126.         {
  127.         fprintf (stderr, "Only one -C option allowed\n");
  128.         goto usage;
  129.         }
  130.         Command = p;                /* save the comand */
  131.         argc--;
  132.         argv++;
  133.     }
  134.     fprintf (stderr, "Unknown option: %s\n", argv[0]);
  135.     goto usage;
  136.     }
  137.     /* 
  138.      * if "Command" is still null, load the default
  139.      */
  140.     if (Command == (char *) NULL)
  141.     {
  142.     Command = DFLTCOMMAND;
  143.     }
  144.  
  145.     /* 
  146.      * collect any options that we should pass to uux
  147.      */
  148.     options[0] = '\0';                    /* empty option list */
  149.     while (argc > 0 && **argv == '-')            /* while its a - */
  150.     {
  151.     strcat (options, " ");
  152.     strcat (options, argv[0]);
  153.     argv++;
  154.     argc--;
  155.     }
  156.     if (Debug)
  157.     fprintf (stderr, "option line is: %s\n", options);
  158.     /* 
  159.      * time for the nitty gritty
  160.      */
  161.     if (argc < 2)
  162.     {
  163.     fprintf (stderr,
  164.         "Improper argument count\n");
  165. usage: 
  166.     fprintf (stderr,
  167.         "Usage: %s [-p] [-c] [-Ccommand] [-d] [-] [commandoptions] host user\n",
  168.         InvokedAs);
  169.     exit (EX_USAGE);
  170.     }
  171.  
  172.     host = *argv;
  173.     argc--;
  174.     argv++;                        /* count it out */
  175.     if (Debug)
  176.     fprintf (stderr, "Looking for Host: %s\n", host);
  177.  
  178.     domain = strsave (host);                /* make a copy */
  179.     strlower (domain);                    /* and go lower case */
  180.     hostp = findpath (domain);                /* get a route */
  181.     if (hostp != (struct findpath_f *) NULL)        /* is a path */
  182.     {
  183.     hostpath = *hostp;
  184.     }
  185.     else
  186.     {
  187.     hostpath.fp_path = (char *) NULL;
  188.     hostpath.fp_matched = (char *) NULL;
  189.     hostpath.fp_fullroute = 1;
  190.     }
  191.  
  192.     if (hostpath.fp_path != (char *) NULL)        /* got a path? */
  193.     {
  194.     if (Pathalias &&
  195.         strlen (hostpath.fp_path) >= 2 &&
  196.         strncmp (hostpath.fp_path, "%s", 2) == 0)
  197.     {
  198.         /* 
  199.          *    we got a path like "%s" or "%s@site"
  200.          *    but we really want a path of the form
  201.          *    "host!...%s...." so we can strip a 
  202.          *    leading host...
  203.          */
  204.         fprintf (stderr, "%s: %s: no leftmost host!.\n",
  205.             InvokedAs, hostpath.fp_path);
  206.         exit (EX_UNAVAILABLE);
  207.     }
  208.     neighbor = nextdoor;
  209.     q = hostpath.fp_path;
  210.     while (*q && *q != '!')                /* get first hop */
  211.         *neighbor++ = *q++;
  212.     *neighbor = '\0';                /* terminate */
  213.  
  214.     remainder = strsave (++q);            /* rest of path */
  215.     *--q = '!';                    /* and restore */
  216.     if (!Pathalias)                    /* append a %s */
  217.     {
  218.         char    buf[1024];
  219.         sprintf (buf, "%s%%s", remainder);
  220.         free (remainder);
  221.         remainder = strsave (buf);
  222.     }
  223.     }
  224.     else
  225.     {
  226.     /* 
  227.      * no path to the site or any of the enclosing domains.
  228.      * set things up as if we had a straight shot to the site.
  229.      */
  230.     strcpy (nextdoor, host);
  231.     remainder = "%s";                /* printf fmt */
  232.     }
  233.  
  234. #ifdef    ALIASESINPATH
  235.     /* 
  236.      * if our first hop is through ALIASEINPATH, we shouldn't
  237.      * be doing this; we should have defered this letter somewhere
  238.      * upstream.
  239.      * so, to keep from going to non-existent sites, we will
  240.      * defer this letter.
  241.      */
  242.     if (strcmp (nextdoor, ALIASESINPATH) == 0)
  243.     {
  244.     if (Debug)
  245.     {
  246.         fprintf (stderr, "first hop through %s, defer the letter\n",
  247.             ALIASESINPATH);
  248.     }
  249.     exit (EX_TEMPFAIL);
  250.     }
  251. #endif    /* ALIASESINPATH */
  252.  
  253.     sprintf (cmdline, "%s %s %s!rmail",
  254.         Command, options, nextdoor);
  255.  
  256.     /* 
  257.      * now for each user...
  258.      */
  259.  
  260.     Logtouser[0] = '\0';                /* empty the string */
  261.     while (argc > 0)
  262.     {
  263.     char    addon[1024];
  264.     char    userbuf[512];
  265.     char    buildbuf[1024];
  266.     char   *touser;
  267.     char   *up;                    /* hold user */
  268.     char   *hp;                    /* hold host */
  269.  
  270.     if (Debug)
  271.         fprintf (stderr, "User: %s\n", *argv);
  272.     if (!PrefixBase)
  273.     {
  274.         /* 
  275.          * see if we have a "full route". if so, we want to hand
  276.          * off just the plain "user" field.  if not, we need to
  277.          * build a "host!user" string and hand that to the
  278.          * segment that builds the rmail arguements.
  279.          */
  280.         if (hostpath.fp_fullroute)
  281.         {
  282.         /* 
  283.          * know the whole thing
  284.          */
  285.         touser = *argv;
  286.         }
  287.         else
  288.         {
  289.         /* 
  290.          * incomplete route; prepend the host name
  291.          */
  292.         sprintf (buildbuf, "%s!%s", host, *argv);
  293.         touser = buildbuf;
  294.         }
  295.     }
  296.     else
  297.     {
  298.         /* 
  299.          * PrefixBase work
  300.          *
  301.          * find a path to the user.
  302.          * compare it for common prefixes with that to host
  303.          * remove first hop
  304.          * rebuild new user information.
  305.          * pass it on down to the command line formatting.
  306.          *
  307.          * have to make some sort of distinction between how an
  308.          * address like site!user will come across vs how
  309.          * an address like hop!site!user will come across.
  310.          * we don't want to do the user path expansion for the
  311.          * second case.  i'm not sure how i want to do this.
  312.          */
  313.     }
  314.  
  315.     sprintf (userbuf, remainder, touser);        /* make arg */
  316.     sprintf (addon, " \"(%s)\"", userbuf);
  317.     if (Debug)
  318.     {
  319.         fprintf (stderr, "\ttouser = %s\n", touser);
  320.         fprintf (stderr, "\tadded to cmdline: %s\n", addon);
  321.     }
  322.     strcat (cmdline, addon);            /* append to cmd */
  323. #ifdef    MAILLOG
  324.     strcat (Logtouser, " ");            /* separator */
  325.     strcat (Logtouser, *argv);            /* and user */
  326. #endif    /* MAILLOG */
  327.     argc--;
  328.     argv++;
  329.     }
  330.     if (Debug)
  331.     {
  332.     printf ("Doing: %s\n", cmdline);
  333.     exit (EX_UNAVAILABLE);
  334.     }
  335.     myson = popen (cmdline, "w");            /* send text here */
  336.     if (myson == NULL)
  337.     {
  338.     printf ("Couldn't make pipe to \"%s\"\n", cmdline);
  339.     exit (EX_UNAVAILABLE);
  340.     }
  341.  
  342.     messagebytes = 0;
  343.     while ((i = getc (stdin)) != EOF)
  344.     {
  345.     putc (i, myson);                /* copy it all */
  346.     messagebytes++;
  347.     }
  348.  
  349.  
  350. #ifdef    MAILLOG
  351.     /* 
  352.      * LOG the following:
  353.      *
  354.      * Neighbor, Fromstring, Size, FullPath, [users]
  355.      */
  356.     if ((logfd = fopen (MAILLOG, "a")) != (FILE *) NULL)/* if there */
  357.     {
  358.     fprintf (logfd, "%s\t%s\t%d\t%s\t%s\n",
  359.         nextdoor, Logfromuser, messagebytes,
  360.         hostpath.fp_path, Logtouser);
  361.     /* 
  362.      * could include [%s ] and Logtouser
  363.      */
  364.     fclose (logfd);
  365.     }
  366. #endif    /* MAILLOG */
  367.  
  368.  
  369.     exit (pclose (myson) >> 8);
  370.  
  371. }
  372.