home *** CD-ROM | disk | FTP | other *** search
/ Unix System Administration Handbook 1997 October / usah_oct97.iso / news / nn.tar / nn-6.5.1 / reroute.c < prev    next >
C/C++ Source or Header  |  1996-08-11  |  7KB  |  376 lines

  1. /*
  2.  *    (c) Copyright 1990, Kim Fabricius Storm.  All rights reserved.
  3.  *
  4.  *    Reply address rewriting.
  5.  */
  6.  
  7. #include "config.h"
  8.  
  9. #define TRACE
  10.  
  11.  
  12. #ifdef HAVE_ROUTING
  13.  
  14. int
  15. reroute(route, address)
  16. char *route, *address;
  17. {
  18.     char *name, *atpos;
  19.     register char *sp;
  20.     register c;
  21.  
  22.     if ((atpos = strchr(address, '@'))) {
  23.     name = atpos;
  24.  
  25.     while (--name >= address)
  26.         if (isspace(*name) || *name == '<') {
  27.         name++;
  28.         break;
  29.         }
  30.     if (name < address) name++;
  31.  
  32.     for (sp = atpos; (c = *sp); sp++)
  33.         if (isspace(c) || c == '>') break;
  34.  
  35.     *sp = NUL;
  36.     strcpy(route, name);
  37.     *sp = c;
  38.     } else
  39.     strcpy(route, address);
  40.     return 1;
  41. }
  42.  
  43. #else
  44.  
  45.  
  46. #ifdef TRACE
  47. FILE *route_trace = NULL;
  48. #endif
  49. static char cmdc;    /* we need this for trace output */
  50.  
  51.  
  52. static char *cstreq(string, match)
  53. char *string, *match;
  54. {
  55.     register char *s1, *s2;
  56.     s1 = string;
  57.  
  58. next_part:
  59.     s2 = match;
  60.  
  61.     while (isspace(*s1) || *s1 == ',') s1++;
  62.  
  63.     while (*s2) {
  64.     if (*s1 == NUL || isspace(*s1)) return NULL;
  65.     if (*s1 == ',') goto next_part;
  66.     if (toupper(*s1) != toupper(*s2)) break;
  67.     s1++, s2++;
  68.     }
  69.  
  70.     if (*s2 == NUL && (*s1 == NUL || isspace(*s1) || *s1 == ',')) {
  71.     if (*s1 == ',') while (*s1 && !isspace(*s1)) s1++;
  72. #ifdef TRACE
  73.     if (route_trace)
  74.         fprintf(route_trace, "/%c %s=%s -> %s", cmdc, string, match, s1);
  75. #endif
  76.     return s1;
  77.     }
  78.  
  79.     while (*s1 && !isspace(*s1)) {
  80.     if (*s1 == ',') goto next_part;
  81.     s1++;
  82.     }
  83.  
  84.     return NULL;
  85. }
  86.  
  87.  
  88. static char *cstrcpy(s1, s2)
  89. register char *s1, *s2;
  90. {
  91.     while (*s2 && isspace(*s2)) s2++;
  92.     while (*s2 && !isspace(*s2) && *s2 != ',') *s1++ = *s2++;
  93.     *s1 = NUL;
  94.     return s1;
  95. }
  96.  
  97. /*
  98.  * lookup site,domain in routes database
  99.  * if not found and bang is non-empty, use bang default if it exist
  100.  */
  101.  
  102. static find_route(route, remote_user, remote_host, remote_domain, bang)
  103. char *route, *remote_user, *remote_host, *remote_domain, *bang;
  104. {
  105.     char line[512];        /* line from route file */
  106.     register char *lp;        /* current line position */
  107.     char *routep;               /* ptr into route */
  108.     char *pattern;        /* pattern from line */
  109.     int  dom_ok;        /* in right domain */
  110.     int  host_ok;        /* right host */
  111.     FILE *rf;            /* route file */
  112.     char local_host[100];    /* callers host name */
  113.     char local_domain[100];    /* this domain */
  114.  
  115.     if (bang && *bang == NUL) bang = NULL;
  116.     if (remote_host == NULL || *remote_host == NUL) return 0;
  117.  
  118.     if (remote_domain && *remote_domain == NUL) remote_domain = NULL;
  119.  
  120.     nn_gethostname(local_host, 100);
  121.     if (routep = strchr(local_host, '.')) *routep = NUL;
  122.     local_domain[0] = NUL;
  123.  
  124.     rf = open_file(relative(lib_directory, "routes"), OPEN_READ);
  125.     if (rf == NULL) {
  126. #ifdef TRACE
  127.     if (route_trace) fprintf(route_trace, "---No routes file\n");
  128. #endif
  129.     return 0;
  130.     }
  131.  
  132.     dom_ok = host_ok = 1;
  133.     routep = route;
  134.     pattern = NULL;
  135.  
  136.     while (fgets(line, 512, rf) != NULL) {
  137.     lp = line;
  138.     while (*lp && isspace(*lp)) lp++;
  139.     if (*lp == NUL || *lp == '#') continue;
  140.  
  141.     if (*lp == '/') {
  142.         lp++;
  143.         cmdc = *lp++;
  144.         while (*lp && isspace(*lp)) lp++;
  145.         if (*lp == '#') *lp = NUL;
  146.  
  147.         if (cmdc == 'L') {        /* local (default) domain name(s) */
  148.         cstrcpy(local_domain, lp);
  149.  
  150.         if (remote_domain == NULL ||
  151.             cstreq(lp, remote_domain) != NULL) {
  152.             dom_ok = 1;
  153.             if (strcmp(local_host, remote_host) == 0) {
  154.             pattern = "%p%n";
  155.             break;
  156.             }
  157.         }
  158.         continue;
  159.         }
  160.  
  161.         if (cmdc == 'D') {        /* destination domain */
  162.         if (*lp == NUL)
  163.             dom_ok = 1;
  164.         else
  165.             dom_ok = (cstreq(lp, remote_domain) != NULL);
  166.         continue;
  167.         }
  168.  
  169.         if (!dom_ok) continue;
  170.  
  171.         if (cmdc == 'H') {        /* local host */
  172.         if (*lp == NUL)
  173.             host_ok = 1;
  174.         else
  175.             host_ok = (cstreq(lp, local_host) != NULL);
  176.         continue;
  177.         }
  178.  
  179.         if (!host_ok) continue;
  180.  
  181.         switch (cmdc) {
  182.  
  183.          case 'N':    /* neighbouring (uucp) sites */
  184.         if (cstreq(lp, remote_host) == NULL) continue;
  185.         pattern = "%s!%n";
  186.         break;
  187.  
  188.          case 'P':
  189.         if (*lp == '+')
  190.             routep = cstrcpy(routep, ++lp);
  191.         else
  192.             routep = cstrcpy(route, lp);
  193.         continue;
  194.  
  195.          case 'G':
  196.         pattern = lp;
  197.         break;
  198.  
  199.          case 'B':
  200.         if (!bang) continue;
  201.         pattern = lp;
  202.         break;
  203.  
  204.          default:
  205.         continue;
  206.         }
  207.  
  208.         break;
  209.     }
  210.  
  211.     if (!dom_ok) continue;
  212.     if (!host_ok) continue;
  213.  
  214.     if ((pattern = cstreq(lp, remote_host))!=NULL) break;
  215.     }
  216.  
  217.     fclose(rf);
  218.  
  219.     if (pattern == NULL) return 0;
  220.  
  221. #ifdef TRACE
  222.     if (route_trace) fprintf(route_trace, "   pattern='%s'\n", pattern);
  223. #endif
  224.  
  225.     for (; *pattern != NL && *pattern != NUL; pattern++) {
  226.     if (*pattern == SP || *pattern == TAB) continue;
  227.     if (*pattern == '%') {
  228.         pattern++;
  229.         switch(*pattern) {
  230.          case 'n':
  231.         routep = cstrcpy(routep, remote_user);
  232.         continue;
  233.          case 's':
  234.         routep = cstrcpy(routep, remote_host);
  235.         continue;
  236.          case 'd':
  237.         routep = cstrcpy(routep,
  238.                  remote_domain ? remote_domain : local_domain);
  239.         continue;
  240.          case 'b':
  241.         routep = cstrcpy(routep, bang);
  242.         continue;
  243.          case 'p':
  244.         routep = route;
  245.         continue;
  246.          case '%':
  247.         break;
  248.          default:
  249.         continue;
  250.         }
  251.     }
  252.     *routep++ = *pattern;
  253.     }
  254.     *routep = NUL;
  255.  
  256.     return 1;
  257. }
  258.  
  259. reroute(route, address)
  260. char *route, *address;
  261. {
  262.     char *name, *site, *domain;
  263.     char *atpos, *dotpos;
  264.     register char *sp;
  265.     register c;
  266.     int found;
  267.  
  268. #ifdef TRACE
  269.     if (route_trace ||
  270.     (route_trace = open_file(relative(nn_directory, "trace"),
  271.                 OPEN_APPEND | DONT_CREATE)))
  272.     fprintf(route_trace, "--orig: '%s'\n", address);
  273. #endif
  274.  
  275.     found = 0;
  276.  
  277.     /* if a sender (or receiver!) is not provided,
  278.      * we first try the site from the 'Reply-To:'
  279.      * and 'From:' lines  who@site.domain */
  280.  
  281.     if (atpos = strchr(address, '@')) {
  282.     *atpos = NUL;
  283.     name = atpos;
  284.  
  285.     while (--name >= address)
  286.         if (isspace(*name) || *name == '<') {
  287.         name++;
  288.         break;
  289.         }
  290.     if (name < address) name++;
  291.  
  292.     dotpos = atpos;
  293.     site   = atpos + 1;
  294.  
  295.      next_dot:
  296.     *dotpos = NUL;
  297.     domain = dotpos + 1;
  298.     for (sp = domain; c = *sp; sp++) {
  299.         if (isspace(c) || c == '>') break;
  300.         if (c == '.') {
  301.         *dotpos = '.';
  302.         dotpos = sp;
  303.         goto next_dot;
  304.         }
  305.     }
  306.     *sp = NUL;
  307.     if (site == domain)
  308.         domain = NULL;
  309.     else
  310.         *atpos = NUL;    /* overwritten when first . is found */
  311.  
  312. #ifdef TRACE
  313.     if (route_trace)
  314.         fprintf(route_trace,
  315.             "   @-type: name='%s' site='%s' domain='%s'\n",
  316.             name, site, domain ? domain : "");
  317. #endif
  318.  
  319.     found = find_route(route, name, site, domain, (char *)NULL);
  320.  
  321.     if (dotpos) { *dotpos = '.'; *sp = c; }
  322.     if (atpos) *atpos = '@';
  323.  
  324.     goto out;
  325.     }
  326.  
  327.     /*
  328.      * not domain address -- look for bang address
  329.      */
  330.  
  331.     if (!(name = strrchr(address, '!'))) {
  332.     /*
  333.      * neither domain nor bang -- suppose it is a local address
  334.      */
  335.     strcpy(route, address);
  336.     found = 1;
  337.     goto out;
  338.     }
  339.  
  340.     *name++ = NUL;
  341.     if (site = strrchr(address, '!'))
  342.     *site++ = NUL;
  343.     else {
  344.     site = address;
  345.     address = NULL;
  346.     }
  347.  
  348. #ifdef TRACE
  349.     if (route_trace)
  350.     fprintf(route_trace,
  351.         "   !-type: name='%s' site='%s' bang='%s'\n",
  352.         name, site, address ? address : "NONE");
  353. #endif
  354.  
  355.     found = find_route(route, name, site, (char *)NULL, address);
  356.  
  357.     *--name = '!';
  358.     if (address) *--site = '!';
  359.  
  360.  out:
  361.  
  362. #ifdef TRACE
  363.     if (route_trace) {
  364.     if (found)
  365.         fprintf(route_trace, "--route='%s'\n\n", route);
  366.     else
  367.         fprintf(route_trace, "--NO ROUTE\n\n");
  368.     fclose(route_trace);
  369.     route_trace = NULL;
  370.     }
  371. #endif
  372.     return found;
  373. }
  374.  
  375. #endif
  376.