home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / internet / tcpipsrc / DNS / c / domain < prev    next >
Text File  |  1995-02-04  |  13KB  |  431 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5.  
  6. /* #define MEM_NORMAL      1 */
  7.  
  8. #include "global.h"
  9. #include "netdb.h"
  10. #include "mbuf.h"
  11. #include "timer.h"
  12. #include "netuser.h"
  13. #include "cmdparse.h"
  14. #include "domain.h"
  15. #include "misc.h"
  16. #include "socket.h"
  17. #include "var.h"
  18.  
  19. extern int twprintf(char *fmt, ...);
  20.  
  21. extern varlist global_vars;
  22.  
  23. extern char domainfile[];
  24.  
  25. static char *Domain_Suffix;    /* Default suffix for names without periods */
  26.  
  27. static struct Domain_Struct
  28. {
  29.         char *Name;
  30.         int32 Address;
  31.         long  ttl;
  32.         int Type;
  33. #define IN_A 1
  34. #define IN_MX 2
  35.         struct Domain_Struct *Next;
  36. }
  37. *Domain_Start = (struct Domain_Struct *)NULL;
  38.  
  39. static int doadd(int, char **);
  40. static int dolist(int, char **);
  41. static int doread(int, char **);
  42. static int doquery(int, char **);
  43. static int dosuffix(int, char **);
  44.  
  45. static struct cmds Dcmds[] = {
  46.         "add",          doadd,          3, "domain add name address [ttl]", NULLCHAR,
  47.         "list",         dolist,         0, NULLCHAR, NULLCHAR,
  48.         "read",         doread,         2, "domain read <file>", NULLCHAR,
  49.         "query",        doquery,        2, "domain query <name|address>", NULLCHAR,
  50.         "suffix",       dosuffix,       0, NULLCHAR, NULLCHAR,
  51.         NULLCHAR,       NULLFP,         0, "domain subcommands: add list read query suffix", NULLCHAR
  52. };
  53.  
  54. int dodomain(int argc, char **argv)
  55. {
  56.         return subcmd(Dcmds, argc, argv);
  57. }
  58.  
  59. static int dosuffix(int argc, char **argv)
  60. {
  61.         if (argc < 2)
  62.         {
  63.                 if (Domain_Suffix != NULLCHAR)
  64.                         cwprintf(NULL, "%s\r\n", Domain_Suffix);
  65.                 return 0;
  66.         }
  67.  
  68.         if (Domain_Suffix != NULLCHAR) mem_free(Domain_Suffix,__FILE__,__LINE__);
  69.  
  70.         Domain_Suffix = mem_strdup(argv[1],__FILE__,__LINE__);
  71.         return 0;
  72. }
  73.  
  74. int Read_Domain_File(void)
  75. {
  76.         char Buffer[200];
  77.         char *Name, *ttl, *Class, *Type, *Address;
  78.         struct Domain_Struct *Domain_Ptr;
  79.         struct Domain_Struct *Last_Domain;
  80.         FILE *fp;
  81.  
  82.         if ((fp = fopen(domainfile, "rt")) == NULL)
  83.                 return(0);
  84.  
  85.         while (fgets(Buffer, 200, fp) != NULL)
  86.         {
  87.  
  88.                 { /* Little patch to ensure variables are
  89.                      translated in domain files */
  90.                   char xbuf[200];
  91.                   var_translate(global_vars, Buffer, 0, xbuf, 200);
  92.                   strcpy(Buffer, xbuf);
  93.                 }
  94.  
  95.                 if (Buffer[0] == '#') continue;
  96.  
  97.                 Name = strtok(Buffer, " \t");
  98.                 ttl = strtok(NULLCHAR, " \t");
  99.                 Class = strtok(NULLCHAR, " \t");
  100.                 Type = strtok(NULLCHAR, " \t");
  101.                 Address = strtok(NULLCHAR, " \t");
  102.  
  103.                 if (!isdigit(ttl[0]))
  104.                 {
  105.                         /* Optional ttl field is missing; slide the other fields over */
  106.                         Address = Type;
  107.                         Type    = Class;
  108.                         Class   = ttl;
  109.                         ttl     = NULLCHAR;
  110.                 }
  111.  
  112.                 if (Address == NULLCHAR) continue;
  113.                 /* Ammended to allow MX records in Domain file */
  114.                 if (strcmp(Class, "IN") != 0 || (strcmp(Type, "A") != 0 && strcmp(Type, "MX") != 0)) continue;
  115.  
  116.                 if ((Domain_Ptr = (struct Domain_Struct *)malloc(sizeof(struct Domain_Struct))) == (struct Domain_Struct *)NULL)
  117.                 {
  118.                         /* What the fucks this then ? */
  119.                         cwprintf(NULL, "Out of memory !!!\r\n");
  120.                         return(0);
  121.                 }
  122.  
  123.                 Domain_Ptr->Name    = strdup(Name);
  124.                 Domain_Ptr->Address = aton(Address);
  125.                 Domain_Ptr->ttl     = (ttl != NULLCHAR) ? atol(ttl) : 0L;
  126.                 Domain_Ptr->Type    = (strcmp(Type, "A") == 0) ? IN_A : IN_MX;
  127.                 Domain_Ptr->Next    = (struct Domain_Struct *)NULL;
  128.  
  129.                 if (Domain_Start == (struct Domain_Struct *)NULL)
  130.                         Domain_Start = Domain_Ptr;
  131.                 else
  132.                         Last_Domain->Next = Domain_Ptr;
  133.  
  134.                 Last_Domain = Domain_Ptr;
  135.         }
  136.  
  137.         fclose(fp);
  138.  
  139.         return(1);
  140. }
  141.  
  142. /* The following is a kludge to allow MX lookups to be done via the
  143.    local domain file - this allows the local host to have a local MX
  144.    route for loopback routing of mail
  145.    P.S. This is just a rough copy of resolve below, but calls _mxresolve
  146.    (was mxresolve) if the lookup cant be satified by the domain file
  147.  */
  148.  
  149. extern int _mxresolve( char *Name );
  150.  
  151. int mxresolve( char *Name )
  152. {
  153.         register struct Domain_Struct *Domain_Ptr;
  154.         char *Full_Name;
  155.  
  156.         if (Name == NULLCHAR) return(0);
  157.  
  158.         if (*Name == '[')
  159.           return(int)(aton(Name + 1));
  160.         else if (isdigit(*Name))  /* Need to check if this is valid...
  161.                                   can host names start with a digit?? - adam */
  162.           return((int)aton(Name));
  163.  
  164.         if (strchr(Name,'.') == NULLCHAR && Domain_Suffix != NULLCHAR)
  165.         {
  166.                 Full_Name = malloc(strlen(Name) + strlen(Domain_Suffix) + 3);
  167.                 sprintf(Full_Name, "%s.%s", Name, Domain_Suffix);
  168.         }
  169.         else
  170.         {
  171.                 Full_Name = malloc(strlen(Name) + 2);
  172.                 strcpy(Full_Name, Name);
  173.         }
  174.  
  175.         if (Full_Name[strlen(Full_Name) - 1] != '.')
  176.                 strcat(Full_Name, ".");
  177.  
  178.         Domain_Ptr = Domain_Start;
  179.  
  180.         while (Domain_Ptr != (struct Domain_Struct *)NULL)
  181.         {
  182.                 if (stricmp(Domain_Ptr->Name, Full_Name) == 0 && Domain_Ptr->Type==IN_MX)
  183.                 {
  184.                         free(Full_Name);
  185.                         return(int)(Domain_Ptr->Address);
  186.                 }
  187.  
  188.                 Domain_Ptr = Domain_Ptr->Next;
  189.         }
  190.         free(Full_Name);
  191.  
  192.         return _mxresolve(Name);
  193. }
  194.  
  195. char *resolve_p(int32 a)
  196. {
  197.   struct hostent *host;
  198.  
  199.   if (host = gethostbyaddr(a, 4, AF_INET), host!=NULL)
  200.     return host->h_name;
  201.  
  202.   return NULL;
  203. }
  204.  
  205. /* Main entry point for domain name -> address resolution. Returns 0 if
  206.  * name is definitely not valid.
  207.  */
  208. int32 resolve(char *Name)
  209. {
  210.         register struct Domain_Struct *Domain_Ptr;
  211.         char *Full_Name;
  212.         struct hostent *hosts;
  213.  
  214.         if (Name == NULLCHAR) return(0);
  215.  
  216.         if (*Name == '[')
  217.           return(aton(Name + 1));
  218.         else if (isdigit(*Name))  /* Need to check if this is valid...
  219.                                   can host names start with a digit?? - adam */
  220.           return(aton(Name));
  221.  
  222.  
  223.  
  224.         if (strchr(Name,'.') == NULLCHAR && Domain_Suffix != NULLCHAR)
  225.         {
  226.                 Full_Name = malloc(strlen(Name) + strlen(Domain_Suffix) + 3);
  227.                 sprintf(Full_Name, "%s.%s", Name, Domain_Suffix);
  228.         }
  229.         else
  230.         {
  231.                 Full_Name = malloc(strlen(Name) + 2);
  232.                 strcpy(Full_Name, Name);
  233.         }
  234.  
  235.         if (Full_Name[strlen(Full_Name) - 1] != '.')
  236.                 strcat(Full_Name, ".");
  237.  
  238.         Domain_Ptr = Domain_Start;
  239.  
  240.         while (Domain_Ptr != (struct Domain_Struct *)NULL)
  241.         {
  242.                 if (stricmp(Domain_Ptr->Name, Full_Name) == 0 && Domain_Ptr->Type==IN_A)
  243.                 {
  244.                         free(Full_Name);
  245.                         return(Domain_Ptr->Address);
  246.                 }
  247.  
  248.                 Domain_Ptr = Domain_Ptr->Next;
  249.         }
  250.  
  251.     if( !(hosts = gethostbyname( Name, 0 )) || !hosts->h_addr_list[0] || hosts->h_length!=4)
  252.     {
  253.             free(Full_Name);
  254.             return(0);
  255.     }
  256.     return( *(int *)hosts->h_addr_list[0] );
  257. }
  258.  
  259. static int dolist(int argc, char **argv)
  260. {
  261.         register struct Domain_Struct *Domain_Ptr;
  262.  
  263.         argc = argc;
  264.         argv = argv;
  265.  
  266.         Domain_Ptr = Domain_Start;
  267.  
  268.         cwprintf(NULL, "Name                            TTL     Address\r\n");
  269.  
  270.         while (Domain_Ptr != (struct Domain_Struct *)NULL)
  271.         {
  272.                 cwprintf(NULL, "%-30s  %6ld  %-20s\r\n", Domain_Ptr->Name, Domain_Ptr->ttl, ntoa(Domain_Ptr->Address));
  273.  
  274.                 Domain_Ptr = Domain_Ptr->Next;
  275.         }
  276.  
  277.         return(0);
  278. }
  279.  
  280. static int doquery