home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
- #include <stdlib.h>
-
- /* #define MEM_NORMAL 1 */
-
- #include "global.h"
- #include "netdb.h"
- #include "mbuf.h"
- #include "timer.h"
- #include "netuser.h"
- #include "cmdparse.h"
- #include "domain.h"
- #include "misc.h"
- #include "socket.h"
- #include "var.h"
-
- extern int twprintf(char *fmt, ...);
-
- extern varlist global_vars;
-
- extern char domainfile[];
-
- static char *Domain_Suffix; /* Default suffix for names without periods */
-
- static struct Domain_Struct
- {
- char *Name;
- int32 Address;
- long ttl;
- int Type;
- #define IN_A 1
- #define IN_MX 2
- struct Domain_Struct *Next;
- }
- *Domain_Start = (struct Domain_Struct *)NULL;
-
- static int doadd(int, char **);
- static int dolist(int, char **);
- static int doread(int, char **);
- static int doquery(int, char **);
- static int dosuffix(int, char **);
-
- static struct cmds Dcmds[] = {
- "add", doadd, 3, "domain add name address [ttl]", NULLCHAR,
- "list", dolist, 0, NULLCHAR, NULLCHAR,
- "read", doread, 2, "domain read <file>", NULLCHAR,
- "query", doquery, 2, "domain query <name|address>", NULLCHAR,
- "suffix", dosuffix, 0, NULLCHAR, NULLCHAR,
- NULLCHAR, NULLFP, 0, "domain subcommands: add list read query suffix", NULLCHAR
- };
-
- int dodomain(int argc, char **argv)
- {
- return subcmd(Dcmds, argc, argv);
- }
-
- static int dosuffix(int argc, char **argv)
- {
- if (argc < 2)
- {
- if (Domain_Suffix != NULLCHAR)
- cwprintf(NULL, "%s\r\n", Domain_Suffix);
- return 0;
- }
-
- if (Domain_Suffix != NULLCHAR) mem_free(Domain_Suffix,__FILE__,__LINE__);
-
- Domain_Suffix = mem_strdup(argv[1],__FILE__,__LINE__);
- return 0;
- }
-
- int Read_Domain_File(void)
- {
- char Buffer[200];
- char *Name, *ttl, *Class, *Type, *Address;
- struct Domain_Struct *Domain_Ptr;
- struct Domain_Struct *Last_Domain;
- FILE *fp;
-
- if ((fp = fopen(domainfile, "rt")) == NULL)
- return(0);
-
- while (fgets(Buffer, 200, fp) != NULL)
- {
-
- { /* Little patch to ensure variables are
- translated in domain files */
- char xbuf[200];
- var_translate(global_vars, Buffer, 0, xbuf, 200);
- strcpy(Buffer, xbuf);
- }
-
- if (Buffer[0] == '#') continue;
-
- Name = strtok(Buffer, " \t");
- ttl = strtok(NULLCHAR, " \t");
- Class = strtok(NULLCHAR, " \t");
- Type = strtok(NULLCHAR, " \t");
- Address = strtok(NULLCHAR, " \t");
-
- if (!isdigit(ttl[0]))
- {
- /* Optional ttl field is missing; slide the other fields over */
- Address = Type;
- Type = Class;
- Class = ttl;
- ttl = NULLCHAR;
- }
-
- if (Address == NULLCHAR) continue;
- /* Ammended to allow MX records in Domain file */
- if (strcmp(Class, "IN") != 0 || (strcmp(Type, "A") != 0 && strcmp(Type, "MX") != 0)) continue;
-
- if ((Domain_Ptr = (struct Domain_Struct *)malloc(sizeof(struct Domain_Struct))) == (struct Domain_Struct *)NULL)
- {
- /* What the fucks this then ? */
- cwprintf(NULL, "Out of memory !!!\r\n");
- return(0);
- }
-
- Domain_Ptr->Name = strdup(Name);
- Domain_Ptr->Address = aton(Address);
- Domain_Ptr->ttl = (ttl != NULLCHAR) ? atol(ttl) : 0L;
- Domain_Ptr->Type = (strcmp(Type, "A") == 0) ? IN_A : IN_MX;
- Domain_Ptr->Next = (struct Domain_Struct *)NULL;
-
- if (Domain_Start == (struct Domain_Struct *)NULL)
- Domain_Start = Domain_Ptr;
- else
- Last_Domain->Next = Domain_Ptr;
-
- Last_Domain = Domain_Ptr;
- }
-
- fclose(fp);
-
- return(1);
- }
-
- /* The following is a kludge to allow MX lookups to be done via the
- local domain file - this allows the local host to have a local MX
- route for loopback routing of mail
- P.S. This is just a rough copy of resolve below, but calls _mxresolve
- (was mxresolve) if the lookup cant be satified by the domain file
- */
-
- extern int _mxresolve( char *Name );
-
- int mxresolve( char *Name )
- {
- register struct Domain_Struct *Domain_Ptr;
- char *Full_Name;
-
- if (Name == NULLCHAR) return(0);
-
- if (*Name == '[')
- return(int)(aton(Name + 1));
- else if (isdigit(*Name)) /* Need to check if this is valid...
- can host names start with a digit?? - adam */
- return((int)aton(Name));
-
- if (strchr(Name,'.') == NULLCHAR && Domain_Suffix != NULLCHAR)
- {
- Full_Name = malloc(strlen(Name) + strlen(Domain_Suffix) + 3);
- sprintf(Full_Name, "%s.%s", Name, Domain_Suffix);
- }
- else
- {
- Full_Name = malloc(strlen(Name) + 2);
- strcpy(Full_Name, Name);
- }
-
- if (Full_Name[strlen(Full_Name) - 1] != '.')
- strcat(Full_Name, ".");
-
- Domain_Ptr = Domain_Start;
-
- while (Domain_Ptr != (struct Domain_Struct *)NULL)
- {
- if (stricmp(Domain_Ptr->Name, Full_Name) == 0 && Domain_Ptr->Type==IN_MX)
- {
- free(Full_Name);
- return(int)(Domain_Ptr->Address);
- }
-
- Domain_Ptr = Domain_Ptr->Next;
- }
- free(Full_Name);
-
- return _mxresolve(Name);
- }
-
- char *resolve_p(int32 a)
- {
- struct hostent *host;
-
- if (host = gethostbyaddr(a, 4, AF_INET), host!=NULL)
- return host->h_name;
-
- return NULL;
- }
-
- /* Main entry point for domain name -> address resolution. Returns 0 if
- * name is definitely not valid.
- */
- int32 resolve(char *Name)
- {
- register struct Domain_Struct *Domain_Ptr;
- char *Full_Name;
- struct hostent *hosts;
-
- if (Name == NULLCHAR) return(0);
-
- if (*Name == '[')
- return(aton(Name + 1));
- else if (isdigit(*Name)) /* Need to check if this is valid...
- can host names start with a digit?? - adam */
- return(aton(Name));
-
-
-
- if (strchr(Name,'.') == NULLCHAR && Domain_Suffix != NULLCHAR)
- {
- Full_Name = malloc(strlen(Name) + strlen(Domain_Suffix) + 3);
- sprintf(Full_Name, "%s.%s", Name, Domain_Suffix);
- }
- else
- {
- Full_Name = malloc(strlen(Name) + 2);
- strcpy(Full_Name, Name);
- }
-
- if (Full_Name[strlen(Full_Name) - 1] != '.')
- strcat(Full_Name, ".");
-
- Domain_Ptr = Domain_Start;
-
- while (Domain_Ptr != (struct Domain_Struct *)NULL)
- {
- if (stricmp(Domain_Ptr->Name, Full_Name) == 0 && Domain_Ptr->Type==IN_A)
- {
- free(Full_Name);
- return(Domain_Ptr->Address);
- }
-
- Domain_Ptr = Domain_Ptr->Next;
- }
-
- if( !(hosts = gethostbyname( Name, 0 )) || !hosts->h_addr_list[0] || hosts->h_length!=4)
- {
- free(Full_Name);
- return(0);
- }
- return( *(int *)hosts->h_addr_list[0] );
- }
-
- static int dolist(int argc, char **argv)
- {
- register struct Domain_Struct *Domain_Ptr;
-
- argc = argc;
- argv = argv;
-
- Domain_Ptr = Domain_Start;
-
- cwprintf(NULL, "Name TTL Address\r\n");
-
- while (Domain_Ptr != (struct Domain_Struct *)NULL)
- {
- cwprintf(NULL, "%-30s %6ld %-20s\r\n", Domain_Ptr->Name, Domain_Ptr->ttl, ntoa(Domain_Ptr->Address));
-
- Domain_Ptr = Domain_Ptr->Next;
- }
-
- return(0);
- }
-
- static int doquery(int argc, char **argv)
- {
- register struct Domain_Struct *Domain_Ptr;
- char *Full_Name;
- int32 Address;
-
- argc = argc;
-
- if (argv[1][0] != '[')
- {
- if (strchr(argv[1], '.') == NULLCHAR && Domain_Suffix != NULLCHAR)
- {
- Full_Name = malloc(strlen(argv[1]) + strlen(Domain_Suffix) + 3);
- sprintf(Full_Name, "%s.%s", argv[1], Domain_Suffix);
- }
- else
- {
- Full_Name = malloc(strlen(argv[1]) + 2);
- strcpy(Full_Name, argv[1]);
- }
-
- if (Full_Name[strlen(Full_Name) - 1] != '.')
- strcat(Full_Name, ".");
-
- Domain_Ptr = Domain_Start;
-
- while (Domain_Ptr != (struct Domain_Struct *)NULL)
- {
- if (strcmp(Domain_Ptr->Name, Full_Name) == 0 && Domain_Ptr->Type==IN_A)
- {
- cwprintf(NULL, "[%s]\r\n", ntoa(Domain_Ptr->Address));
- free(Full_Name);
- return(0);
- }
-
- Domain_Ptr = Domain_Ptr->Next;
- }
-
- cwprintf(NULL, "%s not found in domain database\r\n", argv[1]);
- free(Full_Name);
- return(0);
- }
- else
- {
- Address = aton(argv[1] + 1);
-
- Domain_Ptr = Domain_Start;
-
- while (Domain_Ptr != (struct Domain_Struct *)NULL)
- {
- if (Domain_Ptr->Address == Address)
- {
- cwprintf(NULL, "%s\r\n", Domain_Ptr->Name);
- return(0);
- }
-
- Domain_Ptr = Domain_Ptr->Next;
- }
-
- cwprintf(NULL, "%s not found in domain database\r\n", argv[1]);
- return(0);
- }
- }
-
- static int doadd(int argc, char **argv)
- {
- register struct Domain_Struct *Domain_Ptr;
- register struct Domain_Struct *Last_Domain;
-
-
- if ((Domain_Ptr = (struct Domain_Struct *)malloc(sizeof(struct Domain_Struct))) == (struct Domain_Struct *)NULL)
- {
- cwprintf(NULL, "Out of memory in DOMAIN\r\n");
- return(0);
- }
-
- Domain_Ptr->Name = strdup(argv[1]);
- Domain_Ptr->Address = aton(argv[2] + 1);
- Domain_Ptr->ttl = (argc > 3) ? atol(argv[3]) : 0L;
- Domain_Ptr->Next = (struct Domain_Struct *)NULL;
-
- if (Domain_Start == (struct Domain_Struct *)NULL)
- {
- Domain_Start = Domain_Ptr;
- }
- else
- {
- Last_Domain = Domain_Start;
-
- while (Last_Domain->Next != (struct Domain_Struct *)NULL)
- Last_Domain = Last_Domain->Next;
-
- Last_Domain->Next = Domain_Ptr;
- }
-
- return(0);
- }
-
- static int doread(int argc, char **argv)
- {
- char Buffer[200];
- char *Name, *ttl, *Class, *Type, *Address;
- char *nargv[4];
- FILE *fp;
-
- argc = argc;
-
- if ((fp = fopen(argv[1], "rt")) == NULL)
- return(0);
-
- while (fgets(Buffer, 200, fp) != NULL)
- {
- { /* Little patch to ensure variables are
- translated in domain files */
- char xbuf[200];
- var_translate(global_vars, Buffer, 0, xbuf, 200);
- strcpy(Buffer, xbuf);
- }
-
- if (Buffer[0] == '#') continue;
-
- Name = strtok(Buffer, " \t");
- ttl = strtok(NULLCHAR, " \t");
- Class = strtok(NULLCHAR, " \t");
- Type = strtok(NULLCHAR, " \t");
- Address = strtok(NULLCHAR, " \t");
-
- if (!isdigit(ttl[0]))
- {
- /* Optional ttl field is missing; slide the other fields over */
- Address = Type;
- Type = Class;
- Class = ttl;
- ttl = NULLCHAR;
- }
-
- if (Address == NULLCHAR) continue;
- if (strcmp(Class, "IN") != 0 || strcmp(Type, "A") != 0) continue;
-
- nargv[1] = Name;
- nargv[2] = Address;
- nargv[3] = (ttl != NULLCHAR) ? ttl : "0";
-
- doadd(4, nargv);
- }
-
- fclose(fp);
-
- return(1);
- }
-
-