home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / uucp / duucp-1.17 / AU-117b4-src.lha / src / sendmail / domain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-02  |  5.4 KB  |  233 lines

  1. /*
  2.  *  DOMAIN.C
  3.  *
  4.  *  (C) Copyright 1989-1990 by Matthew Dillon,    All Rights Reserved.
  5.  *
  6.  *  Given the first machine in a path scan the domain list and
  7.  *  return the type, class, and address of the resource entry.
  8.  *
  9.  *  AUTOMATIC HACKS:    scans L.sys file and automatically deals
  10.  *            with machine[.UUCP] domain, returning
  11.  *            Type=MD Class=UU Addr=machine.UUCP
  12.  */
  13.  
  14. #include "defs.h"
  15.  
  16. Prototype int DomainLookup (char *, int, char *, char *, char *, int);
  17. Prototype int CompareDomain (char **, int, char **, int);
  18.  
  19. /*
  20.  *  DomainLookup() looks up a domain route for an address.  Determination
  21.  *  of whether something will bounce or not is done here as well.  For
  22.  *  INCOMING MAIL ONLY, if no route is found and bouncing is enabled AND
  23.  *  there is no alias (which essentially makes the mail outgoing again,
  24.  *  this is the 'nobounce' flag), then we return level 0 meaning an
  25.  *  error.
  26.  */
  27.  
  28. int
  29. DomainLookup (char *name, int len, char *tb, char *cb, char *ab, int nobounce)
  30. {
  31.     char
  32.         *dary [16],
  33.         *tmp = malloc (len + 1),
  34.         *tbase = tmp;
  35.     int
  36.         b,
  37.         i,
  38.         di,
  39.         level;
  40.     FILE
  41.         *fi;
  42.     static char
  43.         buf [256];
  44.  
  45.     if (!tmp) {
  46.         ulog (-1, "DomainLookup, no mem!");
  47.         return 0;
  48.     }
  49.  
  50.     for (b = i = di = 0; i < len && name[i] != '!'; ++i) {
  51.         if (name [i] == '.') {
  52.             if (di == sizeof (dary) / sizeof (dary [0]) - 1) {
  53.                 ulog (-1, "DomainLookup, too many domains! %s", name);
  54.                 break;
  55.             }
  56.             strncpy (tmp, name + b, i - b);
  57.             tmp [i - b] = 0;
  58.             dary [di] = tmp;
  59.             tmp += i - b + 1;
  60.             b = i + 1;
  61.             ++di;
  62.         }
  63.     }
  64.  
  65.     strncpy (tmp, name + b, i - b);
  66.     tmp [i - b] = 0;
  67.     dary [di++] = tmp;
  68.  
  69.     /*
  70.      *  Check local mail.  If local mail return a dummy UUCP domain
  71.      *  for ourself.  This will cause the mail to be queued for
  72.      *  immediate execution.  Sendmail may not run UUXQT as this can
  73.      *  cause mail loops.  Since the user has not been run through
  74.      *  aliases we cannot simply post it locally, but must go through
  75.      *  another mail run.
  76.      *
  77.      *  MBS UPDATE: 1/2/94 -- Expand aliases before calling here.
  78.      *              Thank you. (sendmail.c does.)
  79.      */
  80.  
  81.     level = 0;
  82.  
  83.     if (stricmp (dary [0], NodeName) == 0) {
  84.         strcpy (tb, "MD");
  85.         strcpy (cb, "UU");
  86.         strcpy (ab, NodeName);
  87.         strcat (ab, ".uucp");
  88.         level = 1;
  89.     }
  90.  
  91.     if (level == 0 && (fi = fopen (MakeConfigPath (UULIB, "Domain"), "r"))) {
  92.         while (fgets (buf, sizeof (buf), fi)) {
  93.             int
  94.                 l2,
  95.                 di2 = 0;
  96.             char
  97.                 *dary2 [16];
  98.  
  99.             if (buf [0] == ' ' || buf [0] == '\t' || buf [0] == '\n' || buf [0] == '#')
  100.                 continue;
  101.             for (b = i = 0; buf [i] && buf [i] != ' ' && buf [i] != '\t'; ++i) {
  102.                 if (buf [i] == '.') {
  103.                     if (di2 == sizeof (dary2) / sizeof (dary2 [0]) - 1) {
  104.                         ulog (-1, "%s, entry has too many subdomains: %s", MakeConfigPath (UULIB, "Domain"), buf);
  105.                         break;
  106.                     }
  107.                     dary2 [di2++] = buf + b;
  108.                     buf [i] = 0;
  109.                     b = i + 1;
  110.                 }
  111.             }
  112.             buf [i] = 0;
  113.             dary2 [di2++] = buf + b;
  114.  
  115.             buf[i] = 0;        /*    get domain name/wildcard        */
  116.  
  117.             l2 = CompareDomain (dary, di, dary2, di2);
  118.  
  119.             if (l2 > level) {   /*    better domain then what we have     */
  120.                 sscanf (buf + i + 1, "%s %s %s", tb, cb, ab);
  121.                 level = l2;
  122.             }
  123.         }
  124.         fclose (fi);
  125.     }
  126.  
  127.     /*
  128.      *  Couldn't find the appropriate domain entry, check L.sys
  129.      *  OR domain entry is a forwarder, check L.sys
  130.      */
  131.  
  132.     if (strcmp (tb, "MF") == 0 || level == 0) {
  133.         if (fi = fopen (MakeConfigPath (UULIB, "L.sys"), "r")) {
  134.             while (fgets (buf, sizeof (buf), fi)) {
  135.                 if (buf [0] == ' ' || buf [0] == 9 || buf [0] == '#' || buf[0] == '\n')
  136.                     continue;
  137.                 for (i = 0; buf [i] && buf [i] != ' ' && buf [i] != 9; ++i);
  138.                 buf[i] = 0;
  139.                 if (stricmp (dary [0], buf) == 0) {
  140.                     strcpy (tb, "MD");
  141.                     strcpy (cb, "UU");
  142.                     strcpy (ab, buf);
  143.                     strcat (ab, ".uucp");
  144.                     level = 1;
  145.                     break;
  146.                 }
  147.             }
  148.             fclose (fi);
  149.         }
  150.     }
  151.  
  152.     /*
  153.      *  Couldn't find nothing, use DefaultNode for outgoing mail.  If
  154.      *  Bounce's are enabled then bounce if incoming mail, else route it
  155.      *  to the default node (if we feed other Amiga's we may not want to
  156.      *  enable the bounce because they can then mail to a domain
  157.      *  address straight and it will be routed through everyone's
  158.      *  DefaultNode automatically)
  159.      */
  160.  
  161.     if (level == 0) {
  162.         if (ROpt && BounceOpt && !nobounce) {
  163.             /*
  164.              *  If incoming mail and the bounce option is enabled then
  165.              *  return 0, signifying a failure
  166.              */
  167.  
  168.             strcpy (tb, "MD");
  169.             strcpy (cb, "UU");
  170.             strcpy (ab, dary [0]);
  171.             level = 0;
  172.         }
  173.         else {
  174.             /*
  175.              *  outgoing mail, go to default node
  176.              */
  177.  
  178.             if (DefaultNode == NULL) {
  179.                 ulog (-1, "Error, DefaultNode must exist if no Domain file");
  180.                 fprintf (stderr, "ERROR, no entry in Domain, L.sys, and\n");
  181.                 fprintf (stderr, "no DefaultNode config entry for %s\n", name);
  182.                 fprintf (stderr, "cannot send mail\n");
  183.                 free (tbase);
  184.                 return 0;
  185.             }
  186.             strcpy (tb, "MF");
  187.             strcpy (cb, "UU");
  188.             strcpy (ab, DefaultNode);
  189.             level = 1;
  190.         }
  191.     }
  192.  
  193.     free (tbase);
  194.     return level > 0;
  195. }
  196.  
  197. /*
  198.  *  Compares a broken up address with a domain entry (buf).
  199.  */
  200.  
  201. int
  202. CompareDomain (char **da1, int di1, char **da2, int di2)
  203. {
  204.     int
  205.         i,
  206.         j,
  207.         level = 0;
  208.  
  209.     for (i = di1 - 1, j = di2 - 1; i >= 0 && j >= 0; --i, --j) {
  210.         if (da2 [j] [0] == '*') {
  211.             ++level;
  212.             if (i && j == 0)    /*    so loop does not terminate  */
  213.                 ++j;
  214.             continue;
  215.         }
  216.         if (stricmp (da1 [i], da2 [j]) == 0)
  217.             level += 2;
  218.         else {
  219.             if (j + 1 < di2 && da2 [j + 1] [0] == '*') {
  220.                 ++level;
  221.                 ++j;
  222.             }
  223.             else
  224.                 return 0;
  225.         }
  226.     }
  227.  
  228.     if (j >= 0)        /*    didn't exhaust domain entry */
  229.         return 0;
  230.  
  231.     return level;
  232. }
  233.