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