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