home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Spezial / SPEZIAL2_97.zip / SPEZIAL2_97.iso / ANWEND / ONLINE / ELM23-2 / ELM23-2.ZIP / src / domains.c < prev    next >
C/C++ Source or Header  |  1992-03-16  |  9KB  |  314 lines

  1.  
  2. static char rcsid[] = "@(#)$Id: domains.c,v 4.1.1.1 90/07/12 23:19:14 syd Exp $";
  3.  
  4. /*******************************************************************************
  5.  *  The Elm Mail System  -  $Revision: 4.1.1.1 $   $State: Exp $
  6.  *
  7.  *             Copyright (c) 1986, 1987 Dave Taylor
  8.  *             Copyright (c) 1988, 1989, 1990 USENET Community Trust
  9.  *******************************************************************************
  10.  * Bug reports, patches, comments, suggestions should be sent to:
  11.  *
  12.  *    Syd Weinstein, Elm Coordinator
  13.  *    elm@DSI.COM            dsinc!elm
  14.  *
  15.  *******************************************************************************
  16.  * $Log:    domains.c,v $
  17.  * Revision 4.1.1.1  90/07/12  23:19:14  syd
  18.  * Make domain name checking case independent
  19.  * From: Syd, reported by Steven Baur
  20.  *
  21.  * Revision 4.1  90/04/28  22:42:44  syd
  22.  * checkin of Elm 2.3 as of Release PL0
  23.  *
  24.  *
  25.  ******************************************************************************/
  26.  
  27. /** This file contains all the code dealing with the expansion of
  28.     domain based addresses in Elm.  It uses the file "domains" as
  29.     defined in the sysdefs.h file.
  30.  
  31.     From a file format and idea in "uumail" - designed by Stan Barber.
  32. **/
  33.  
  34. #if defined(OPTIMIZE_RETURN) || !defined(DONT_TOUCH_ADDRESSES)
  35.  
  36. #include <ctype.h>
  37.  
  38. #include "headers.h"
  39.  
  40. #ifdef BSD
  41. # undef toupper
  42. # undef tolower
  43. #endif
  44.  
  45. /** define the various characters that we can encounter after a "%" sign
  46.     in the template file...
  47. **/
  48.  
  49. #define USERNAME    'U'    /* %U = the name of the remote user */
  50. #define RMTMNAME    'N'    /* %N = the remote machine name     */
  51. #define FULLNAME    'D'    /* %D = %N + domain info given      */
  52. #define NPATH        'R'    /* %R = path to %N from pathalias   */
  53. #define PPATH        'P'    /* %P = path to 'P' from pathalias  */
  54. #define OBSOLETE    'S'    /* %S = (used to be suffix string)  */
  55.  
  56. /** and finally some characters that are allowed in user/machine names **/
  57.  
  58. #define okay_others(c)    (c == '-' || c == '^' || c == '$' || c == '_')
  59.  
  60. /** and some allowed ONLY in the username field **/
  61.  
  62. #define special_chars(c)    (c == '%' || c == ':')
  63.  
  64. char *find_path_to(), *expand_domain(), *match_and_expand_domain();
  65. char *strcpy(), *strcat(), *strtok();
  66. void rewind();
  67.  
  68. open_domain_file()
  69. {
  70.         char domainsfile[SLEN];
  71.  
  72.         sprintf(domainsfile, "%s/%s", elmhome, domains);
  73.  
  74.     if ((domainfd = fopen(domainsfile, "r")) == NULL) {
  75.       dprint(2, (debugfile,"Warning: can't open file %s as domains file\n",
  76.         domainsfile));
  77.     }
  78.     else {
  79.       dprint(3, (debugfile,
  80.             "Opened '%s' as the domain database\n\n", domains));
  81.     }
  82.  
  83.     /* if it fails it'll instantiate domainfd to NULL which is
  84.        exactly what we want to have happen!! */
  85. }
  86.  
  87. char *expand_domain(buffer)
  88. char *buffer;
  89. {
  90.     /** Expand the address 'buffer' based on the domain information,
  91.         if any.  Returns NULL if it can't expand it for any reason.
  92.     **/
  93.  
  94.     char name[NLEN], address[NLEN], domain[NLEN];
  95.     char *match_and_expand_domain();
  96.  
  97.     if (domainfd == NULL) return(NULL);    /* no file present! */
  98.  
  99.     if (explode(buffer, name, address, domain))
  100.       return( match_and_expand_domain(domain, name, address) );
  101.     else {    /* invalid format - not "user@host.domain" */
  102.       dprint(2,  (debugfile,
  103.          "Invalid format for domain expansion: %s (expand_domain)\n",
  104.            buffer));
  105.       return(NULL);
  106.     }
  107. }
  108.  
  109. int
  110. explode(buffer, name, address, domain)
  111. char *buffer, *name, *address, *domain;
  112. {
  113.     /** Break buffer, if in format name@machine.domain, into the
  114.         component parts, otherwise return ZERO and don't worry
  115.         about the values of the parameters!
  116.     **/
  117.  
  118.     register int i, j = 0;
  119.  
  120.     /** First get the name... **/
  121.  
  122.     for (i=0; buffer[i] != '@'; i++) {
  123.       if (! isalnum(buffer[i]) && ! okay_others(buffer[i]) && !
  124.         special_chars(buffer[i]))
  125.         return(0);            /* invalid character in string! */
  126.       name[i] = buffer[i];
  127.     }
  128.  
  129.     name[i++] = '\0';
  130.  
  131.     /** now let's get the machinename **/
  132.  
  133.     while (buffer[i] != '.') {
  134.       if (! isalnum(buffer[i]) && ! okay_others(buffer[i]))
  135.          return(0);            /* invalid character in string! */
  136.       address[j++] = buffer[i++];
  137.     }
  138.     address[j] = '\0';
  139.  
  140.     j = 0;
  141.  
  142.     /** finally let's get the domain information (there better be some!) **/
  143.  
  144.     while (buffer[i] != '\0') {
  145.       if (! isalnum(buffer[i]) && ! okay_others(buffer[i]) &&
  146.             buffer[i] != '.')
  147.         return(0);              /* an you fail again, bozo! */
  148.       domain[j++] = toupper(buffer[i]);
  149.       i++;
  150.     }
  151.  
  152.     domain[j] = '\0';
  153.  
  154.     return(j);        /* if j == 0 there's no domain info! */
  155. }
  156.  
  157. char *match_and_expand_domain(domain, name, machine)
  158. char *domain, *name, *machine;
  159. {
  160.     /** Given the domain, try to find it in the domain file and
  161.            if found expand the entry and return the result as a
  162.         character string...
  163.     **/
  164.  
  165.     static char address[SLEN];
  166.     char   buffer[SLEN], domainbuff[NLEN];
  167.     char   field1[NLEN], field2[NLEN], field3[NLEN];
  168.     char   *path, *template, *expanded, *mydomain;
  169.     int    matched = 0, in_percent = 0;
  170.     register int j = 0;
  171.  
  172.     address[j] = '\0';
  173.  
  174.     domainbuff[0] = '\0';
  175.     mydomain = (char *) domainbuff;            /* set up buffer etc */
  176.  
  177.     do {
  178.       rewind(domainfd);                   /* back to ground zero! */
  179.  
  180.       if (strlen(mydomain) > 0) {           /* already in a domain! */
  181.         mydomain++;                       /* skip leading '.' */
  182.         while (*mydomain != '.' && *mydomain != ',')
  183.           mydomain++;                   /* next character   */
  184.         if (*mydomain == ',')
  185.           return (NULL);                /* didn't find domain!  */
  186.       }
  187.       else
  188.         sprintf(mydomain, "%s,", domain);        /* match ENTIRELY! */
  189.  
  190.     /* whip through file looking for the entry, please... */
  191.  
  192.     while (fgets(buffer, SLEN, domainfd) != NULL) {
  193.       if (buffer[0] == '#')                  /* skip comments */
  194.         continue;
  195.       if (strincmp(buffer, mydomain, strlen(mydomain)) == 0) { /* match? */
  196.          matched++;    /* Gotcha!  Remember this momentous event! */
  197.          break;
  198.       }
  199.     }
  200.  
  201.     if (! matched)
  202.        continue;        /* Nothing.  Not a sausage!  Step through! */
  203.  
  204.     /** We've matched the domain! **/
  205.  
  206.     no_ret(buffer);
  207.  
  208.     (void) strtok(buffer, ",");    /* skip the domain info */
  209.  
  210.     strcpy(field1, strtok(NULL, ","));    /* fun         */
  211.     strcpy(field2, strtok(NULL, ","));    /*    stuff     */
  212.     strcpy(field3, strtok(NULL, ","));    /*       eh?    */
  213.  
  214.     path = (char *) NULL;
  215.  
  216.     /* now we merely need to figure out what permutation this is!
  217.  
  218.            Fields are null if they have only a blank in them or are null.
  219.            If fields 2 and 3 are null, use field 1 as the template.
  220.             --else--
  221.            If field 3 is null and 2 is not, use field 2 as the template.
  222.             --else--
  223.            Field 3 is the template. */
  224.  
  225.  
  226.     if (strcmp(field3," ") == 0 || field3[0] == '\0'){
  227.       if (strcmp(field2," ") == 0 || field2[0] == '\0')
  228.         template = (char *) field1;
  229.       else {
  230.         path     = (char *) field1;
  231.         template = (char *) field2;
  232.       }
  233.     }
  234.     else {
  235.       path     = (char *) field1;
  236.       template = (char *) field3;
  237.     }
  238.     dprint(1, (debugfile,
  239.       "-> %s\n-> %s\n-> %s\n", field1, field2, field3));
  240.     dprint(1, (debugfile,
  241.       "Path-> %s\nTemplate-> %s\n", path, template));
  242.  
  243.     if (strlen(path) > 0 && path[0] == '>')
  244.        path++;    /* skip the '>' character, okay? */
  245.  
  246.     j = 0;             /* address is zero, right now, right?? */
  247.     address[j] = '\0';          /* make sure string is too! */
  248.  
  249.     for (; *template; template++) {
  250.       if (*template == '%') {
  251.         if (! in_percent)               /* just hit a NEW percent! */
  252.           in_percent = 1;
  253.         else {          /* just another percent sign on the wall... */
  254.           address[j++] = '%';
  255.           address[j] = '\0';             /* ALWAYS NULL terminate */
  256.           in_percent = 0;
  257.         }
  258.       }
  259.       else if (in_percent) {           /* Hey! a real command string */
  260.         in_percent = 0;
  261.         switch (*template) {
  262.           case USERNAME: strcat(address, name);        break;
  263.           case RMTMNAME: strcat(address, machine);        break;
  264.           case FULLNAME: strcat(address, machine);
  265.                  strcat(address, domain);        break;
  266.           case NPATH   :
  267.  
  268.          if ((expanded = find_path_to(machine, FALSE)) == NULL) {
  269.             dprint(3, (debugfile,
  270.                 "\nCouldn't expand system path '%s' (%s)\n\n",
  271.                 machine, "domains"));
  272.                 error1("Couldn't find a path to %s!", machine);
  273.                 sleep(2);
  274.                 return(NULL);    /* failed!! */
  275.              }
  276.              strcat(address, expanded);    /* isn't this fun??? */
  277.  
  278.              break;
  279.  
  280.           case PPATH   :
  281.  
  282.          if ((expanded = find_path_to(path, FALSE)) == NULL) {
  283.             dprint(3, (debugfile,
  284.             "\nCouldn't expand system path '%s' (%s)\n\n",
  285.             path, "domains"));
  286.                 error1("Couldn't find a path to %s!", path);
  287.                 sleep(2);
  288.                 return(NULL);    /* failed!! */
  289.              }
  290.              strcat(address, expanded);    /* isn't this fun??? */
  291.  
  292.              break;
  293.  
  294.           case OBSOLETE:    /* fall through.. */
  295.           default      : dprint(1, (debugfile,
  296.          "\nError: Bad sequence in template file for domain '%s': %%%c\n\n",
  297.             domain, *template));
  298.         }
  299.         j = strlen(address);
  300.       }
  301.       else {
  302.         address[j++] = *template;
  303.         address[j] = '\0';            /* null terminate */
  304.       }
  305.     }
  306.  
  307.     address[j] = '\0';
  308.  
  309.     } while (strlen(address) < 1);
  310.  
  311.     return( (char *) address);
  312. }
  313. #endif
  314.