⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nsdb.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*      @(#)nsdb.c 1.1 92/07/30 SMI      *//*	Copyright (c) 1984 AT&T	*//*	  All Rights Reserved  	*//*	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T	*//*	The copyright notice above does not evidence any   	*//*	actual or intended publication of such source code.	*/#ident	"@(#)nserve:nsdb.c	1.10"#include <stdio.h>#include <string.h>#include <ctype.h>#include "nslog.h"#include "nsdb.h"#include "stdns.h"#include <rfs/nserve.h>#include "nsrec.h"#include <tiuser.h>#include <rfs/nsaddr.h>/* * *	This file contains the core of the Name Server *	database.  From the outside, the database is a *	group of resource records that may be accessed *	through a set of access functions defined here. * *	The header file nsdb.h should be included by any *	program that uses these access functions.  It *	defines the functions and structures that are *	used by the database. * *	 */#define ISIZE 4		/* distance to indent when dumping database	*//* static variables */static struct domain  Dstruct;		/* root of database	*/static struct domain  *Domain = &Dstruct;static struct {	char	*name;	int	type;} *Tptr, Table[] = {	"P",	SOA,	"SOA",	SOA,	"S",	NS,	"NS",	NS,	"DOM",	DOM,	"RN",	RN,	"A",	A,	"NSTYPE",  NSTYPE,	"ANYTYPE", ANYTYPE,	"ANY",	ANYTYPE,	"*",	ANYTYPE,	NULL,0};static int	Indent;	/* for dumping domains	*//* static functions */static struct res_rec	**findrec();static int		addrec();static struct domain	*finddom();static struct domain	*newdom();static struct res_rec	**findns();static int		freedom();struct res_rec	**duplist();struct question	**dupqd();struct res_rec	*duprec();int	writedb();int	readfile();char	*prec();char	*getctype();char	*dompart();char	*namepart();/* * Find resource records that match name and type. * Return pointer to list or NULL. */struct res_rec **findrr(name, type)char	*name;int	type;{	struct res_rec	**list;	char	*r;	struct domain	*d;	struct domain	*d1 = NULL;	LOG4(L_DB,"(%5d) findrr: name=%s, type=%s\n",		Logstamp,name,getctype(type));	d = Domain;	r = dompart(name);	if ((d1=finddom(r,d)) == NULL) {		LOG3(L_DB,"(%5d) findrr: can't find domain '%s'\n",Logstamp,r);		return(NULL);	}	if ((list = findrec(namepart(name),type,d1)) ==  NULL)		LOG4(L_DB,"(%5d) findrr: search failed, name = '%s', type =%d\n",			Logstamp,name,type);	return(duplist(list));}/* * Add a record in the database using name as key. * Return R_NOERR if the operation is successful, * otherwise return an appropriate rcode value (see stdns.h) * Addrr copies the record before adding it to the database. */intaddrr(name,res)char	*name;struct res_rec	*res;{	int	ret;	if ((ret = addraw(name,duprec(res))) == R_NOERR)		return(R_NOERR);	return(ret);}/* * addraw adds a record to the database without first copying it */static intaddraw(name,res)char	*name;struct res_rec	*res;{	struct domain	*d;	struct domain	*d1;	char	*r;	LOG4(L_DB,"(%5d) addrr: name=%s, res=%s\n",		Logstamp,name,prec(res));	d = Domain;	r = dompart(name);	if (*r == WILDCARD) {		LOG2(L_DB,"(%5d) addrr: can't add wildcard\n",Logstamp);		return(R_FORMAT);	}	if ((d1=finddom(r,d)) == NULL) {		LOG3(L_DB,"(%5d) addrr: can't find domain '%s'\n",			Logstamp,r);		return(R_NONAME);	}	return(addrec(namepart(name),res,d1));}/* * put record res in domain dom under name name. */static intaddrec(name,res,dom)char	*name;struct res_rec	*res;struct domain	*dom;{	int	type;	int	i;	type = res->rr_type;	LOG4(L_DB,"(%5d) addrec: name=%s, res=%s\n",		Logstamp,name,prec(res));	if (findrec(namepart(name),type,dom) != NULL) {		LOG4(L_DB,"(%5d) addrec: DUPLICATE NAME='%s', TYPE='%s'\n",			Logstamp, name, getctype(type));		return(R_DUP);	}	for(i=0;1;i++) {		if (i+1 >= dom->d_size) {			dom->d_size += NREC;			if (dom->d_rec) {			    free(dom->d_rec);			    if ((dom->d_rec=(struct res_rec **)realloc(dom->d_rec,				 sizeof(struct res_rec *) * dom->d_size)) == NULL) {					PLOG4(					  "(%5d) addrec: can't realloc(%s,%d)\n",					  Logstamp,"dom->rec",					  sizeof(struct res_rec *)*dom->d_size);					return(R_NSFAIL);			    }			}			else {			    if ((dom->d_rec=(struct res_rec **)				 calloc(dom->d_size,sizeof(struct res_rec *)))				    == NULL) {					PLOG4(					  "(%5d) addrec: can't calloc(%d,%d)\n",					  Logstamp,dom->d_size,					  sizeof(struct res_rec *));					return(R_NSFAIL);			    }			}		}		if (dom->d_rec[i] == NULL)			break;	/* found */	}	dom->d_rec[i] = res;	dom->d_rec[i+1] = NULL;	LOG2(L_DB,"(%5d) addrec: returns R_NOERR\n",Logstamp);	return(R_NOERR);}/* * findrec takes a domain ptr, a name, and a type and * returns all records in domain that match name and type. * Name is an unqualified (i.e., no dots) domain or resource name. * * if name is "*", all names are matched. * if type is ANYTYPE, all types are matched. * if type is NSTYPE, all name server types are matched. * * findrec returns a NULL terminated list of pointers * to struct res_rec if any records are found.  If none * are found, it returns NULL. * * findrec puts the list that points to its result in static storage, * therefore, subsequent calls will destroy previous results. */static struct res_rec	**findrec(name,type,d)char	*name;int	type;struct domain	*d;{	static	int rrsize = 0;	static	struct res_rec	**rrlist = NULL;	int	trrec = 0;	int	i;	int	nstype;	struct res_rec *rp;	LOG5(L_DB,"(%5d) findrec: name=%s, type=%s, domain=%d\n",		Logstamp,name,getctype(type),d);	nstype = (type == NSTYPE)?NSTYPE:0;	if (d->d_rec == NULL)		return(NULL);	if (rrsize < d->d_size)		/* expand rrlist */		if (!(rrlist = (rrlist == NULL) ?			(struct res_rec **)malloc((rrsize = d->d_size) * sizeof(struct res_rec *)) :			(struct res_rec **)realloc(rrlist, (rrsize = d->d_size) * sizeof(struct res_rec *))))			return NULL;	for (i=0, rp=d->d_rec[0]; i < d->d_size && rp != NULL; rp=d->d_rec[++i])		if ((type == ANYTYPE || type == rp->rr_type || nstype & rp->rr_type) &&		    (*name == WILDCARD || strcmp(name,rp->rr_name) == NULL))			rrlist[trrec++] = rp;	LOG3(L_DB,"(%5d) findrec: returns %d records\n",		Logstamp,trrec);	if (trrec > 0) {		rrlist[trrec] = NULL;		return(rrlist);	}	return(NULL);}/* * * finddom searches the database from the given * root and returns a pointer to the domain structure * that represents the argument "name." * * finddom returns NULL if there is an error. * errors include: * 	given name is not a domain. * 	can't find name. * */static struct domain *finddom(name,domain)char	*name;struct domain *domain;{	char	*r;	char	sname[BUFSIZ];	struct domain	*d;	struct res_rec	**rec;	char	*rtoken();	LOG4(L_DB,"(%5d) finddom: name=%s, domain=%d\n",		Logstamp, (name)?name:"NULL",domain);	if (name == NULL)		return(NULL);	/* null name means this is the correct domain already */	if (*name == '\0')		return(domain);	strcpy(sname,name);	for (r=rtoken(sname), d=domain; r != NULL; r=rtoken(NULL))		if ((rec=findrec(r,DOM,d)) != NULL)			d = rec[0]->rr_dom;		else			return(NULL);	return(d);}/* * find list of name servers that should know about this * name.  Uses findns, starting from the root of the database. */struct res_rec **findind(name)char	*name;{	return(duplist(findns(name,Domain)));}/* * * findns searches the database for a reference to a * remote name servers anywhere in the given name. * It returns a list of pointers to the MOST qualified * name servers found. (i.e., if SOA or NS records are found * for b.c.e and b.c, the reference to b.c.e will be returned). * * findns returns NULL if there is an error or if * no name server records are found. * */static struct res_rec **findns(name,domain)char	*name;struct domain *domain;{	static	int reclen = 0;		int	i, tot;	char	*r;	char	sname[BUFSIZ];	struct domain	*d;		struct res_rec	**trec=NULL;	struct res_rec	**recptr=NULL;	static struct res_rec	**rec=NULL;	char	*rtoken();	LOG4(L_DB,"(%5d) findns: name=%s, domain=%d\n",		Logstamp,(name)?name:"NULL",domain);	if (name == NULL || domain == NULL)		return(NULL);	strcpy(sname,name);	for (r=rtoken(sname), d=domain; r != NULL; r=rtoken(NULL)) {		if ((trec=findrec(r,NSTYPE,d)) != NULL) {			for (i=0; trec[i] != NULL; i++);			if (i >= reclen) {				reclen = i + 1;				rec = (rec == NULL) ?				(struct res_rec **)malloc((i + 1) * sizeof(struct res_rec *)) :				(struct res_rec **)realloc(rec, (i + 1) * sizeof(struct res_rec *));			}			tot = i;			for (;i >= 0; --i)				rec[i] = trec[i];			recptr = rec;		}		if ((trec=findrec(r,DOM,d)) != NULL)			d = trec[0]->rr_dom;		else			break;	}	LOG3(L_DB,"(%5d) findns: returns %d records\n",		Logstamp,(recptr)?tot:0);	return(recptr);}/* * dump entire database to stdout. */intdumpdb(){	struct domain	*d;	Indent = 0;	d = Domain;	dumpdom(d,"");	return;}/* * dump the contents of a domain and all of its * subdomains to stdout. */intdumpdom(d,name)struct domain	*d;char	*name;	/* name so far	*/{	struct res_rec	**list;	struct res_rec	*rec;	char	dname[MAXDNAME];	if (d == NULL || d->d_rec == NULL)		return;	for (list=d->d_rec; *list != NULL; list++) {		rec = *list;#ifdef RIGHT_TO_LEFT		sprintf(dname,"%s.%s",rec->rr_name,name);#else		sprintf(dname,"%s.%s",name,rec->rr_name);#endif		if (*name == '\0')			dname[strlen(dname)-1] = '\0';		printf("%*s%s\t%s",Indent,"",dname,getctype(rec->rr_type));		switch (rec->rr_type) {		case RN:			printf("\t%s\n",rec->rr_owner);			break;		case DOM:			printf(", auth=%d, size=%d\n",rec->rr_dauth,rec->rr_dsize);			Indent += ISIZE;			dumpdom(rec->rr_dom,dname);			Indent -= ISIZE;			break;		default:			printf("\t%s\n",rec->rr_data);			break;		}	}	return;}/* *  remrr removes the resource record that matches *  the name and type passed in.  WILDCARDS are illegal. * *  It returns R_NOERR if the operation is successful, *  otherwise, it returns an rcode (see stdns.h). */intremrr(name,res)char	*name;struct res_rec	*res;{	char	*r;	struct domain	*d;	struct domain	*d1;	int	i,j;	struct res_rec	*rptr;	LOG4(L_DB,"(%5d) remrr: name=%s, res=%s\n",		Logstamp,name,prec(res));	d1 = Domain;	r = dompart(name);	if ((d=finddom(r,d1)) == NULL) {		LOG3(L_DB,"(%5d) remrr: can't find domain '%s'\n",			Logstamp,r);		return(R_NONAME);	}	r = namepart(name);	for (i=0, rptr=d->d_rec[0]; i < d->d_size && rptr != NULL;	     rptr = d->d_rec[++i])		if ((strcmp(r,rptr->rr_name) == NULL) &&		    (res->rr_type == rptr->rr_type)) {			for (j=i; j+1 < d->d_size && d->d_rec[j] != NULL; j++)				d->d_rec[j] = d->d_rec[j+1];			d->d_rec[j] = NULL;			freerec(rptr);			return(R_NOERR);		}	return(R_NONAME);}/* * Inverse query.  Search for resource(s) given domain, rdata, and type. * The argument name is matched as a character string with the data portion * of records of all types except RN, where name is matched with rr_owner. * Since DOM records are internal, an inverse query for DOM records will * return NULL. */struct res_rec **iquery(domain, type, name)	/* find rrs where rdata matches name		*/char	*domain;int	type;char	*name;{	static int reclen = 0;	struct res_rec	**list;	int	i,j;	char	*str;	static struct res_rec	**rlist;	char	*dompart();	char	*namepart();	char	qname[2];	struct domain	*d;	struct domain	*d1 = NULL;	LOG5(L_DB,"(%5d) iquery: domain=%s, type=%s, name=%s\n",		Logstamp,domain,getctype(type),name);	d = Domain;	if ((d1=finddom(domain,d)) == NULL) {		if ((list=findns(domain,d)) == NULL)			LOG3(L_DB,"(%5d) iquery: can't find domain '%s'\n",				Logstamp,domain);		return(duplist(list));	}	/* get all records with the right type regardless of name.	*/	qname[0] = WILDCARD;	qname[1] = '\0';	if ((list = findrec(qname,type,d1)) ==  NULL) {		LOG4(L_DB,"(%5d) iquery: search failed, name = '%s', type =%d\n",			Logstamp,qname,type);		return(NULL);	}	for (i=0, j=0; list[i] != NULL; i++) {		LOG3(L_DB,"(%5d) iquery: checks record %s\n",			Logstamp,prec(list[i]));		switch (type) {		case DOM:			return(NULL);		case RN:			str = list[i]->rr_owner;			break;		default:			str = list[i]->rr_data;			break;		}		if ((str == NULL) || (strcmp(str,name) != NULL))			continue;		LOG2(L_DB,"(%5d) iquery: record matches\n",Logstamp);		if (j >= reclen)			rlist = (rlist == NULL) ?				(struct res_rec **)malloc((1+ ++reclen) * sizeof(struct res_rec *)) :				(struct res_rec **)realloc(rlist, (1+ ++reclen) * sizeof(struct res_rec *));		rlist[j++] = list[i];	}	LOG3(L_DB,"(%5d) iquery: returns %d records\n",Logstamp,j);	if (j > 0) {		rlist[j] = 0;		return(duplist(rlist));	}	return(NULL);}char *prec(rec)struct res_rec *rec;{	static	char	buf[BUFSIZ];	char	*ptr;	sprintf(buf,"%s %s",rec->rr_name,getctype(rec->rr_type));	ptr = &(buf[strlen(buf)]);	switch (rec->rr_type) {	default:		sprintf(ptr," %s",rec->rr_data);		break;	case DOM:		sprintf(ptr," auth=%d size=%d",rec->rr_dauth,rec->rr_dsize);		break;	case RN:		sprintf(ptr," %s",rec->rr_owner);		break;	}	return(buf);}/* * convert string representation of a record type into * its internal numeric value. */intgettype(nm)char	*nm;{	char	type[10];	int	i;	for (i=0; i < 10 && *nm != NULL; i++, nm++)		type[i] = toupper(*nm);	type[i] = '\0';	for (Tptr = Table; Tptr->name != NULL; Tptr++)		if (strcmp(Tptr->name,type) == NULL) {			LOG4(L_DB,"(%5d) gettype: nm='%s', returns %d\n",				Logstamp,type,Tptr->type);			return(Tptr->type);		}	LOG4(L_DB,"(%5d) gettype: nm='%s', NOT FOUND returns %d\n",		Logstamp,type,NULL);	return(NULL);}/* * convert numeric record type into character string * NOTE: all NSTYPES are forced to fold into either SOA or NS. */char *getctype(num)int num;{	if (((num & MASKNS) == NSTYPE) && num != SOA)		num = NS;	for (Tptr = Table; Tptr->name != NULL; Tptr++)		if (Tptr->type == num)			return((Tptr->name)?Tptr->name:"NULL");	return(" NULL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -