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

📄 cs.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
 *  the service '*' needs no translation. */char*ipserv(Network *np, char *name, char *buf, int blen){	char *p;	int alpha = 0;	int restr = 0;	char port[10];	Ndbtuple *t, *nt;	Ndbs s;	/* '*' means any service */	if(strcmp(name, "*")==0){		strcpy(buf, name);		return buf;	}	/*  see if it's numeric or symbolic */	port[0] = 0;	for(p = name; *p; p++){		if(isdigit(*p))			{}		else if(isalpha(*p) || *p == '-' || *p == '$')			alpha = 1;		else 			return 0;	}	t = nil;	p = nil;	if(alpha){		p = ndbgetvalue(db, &s, np->net, name, "port", &t);		if(p == nil)			return 0;	} else {		/* look up only for tcp ports < 1024 to get the restricted		 * attribute		 */		if(atoi(name) < 1024 && strcmp(np->net, "tcp") == 0)			p = ndbgetvalue(db, &s, "port", name, "port", &t);		if(p == nil)			p = strdup(name);	}	if(t){		for(nt = t; nt; nt = nt->entry)			if(strcmp(nt->attr, "restricted") == 0)				restr = 1;		ndbfree(t);	}	snprint(buf, blen, "%s%s", p, restr ? "!r" : "");	free(p);	return buf;}/* *  lookup an ip attribute */intipattrlookup(Ndb *db, char *ipa, char *attr, char *val, int vlen){		Ndbtuple *t, *nt;	char *alist[2];	alist[0] = attr;	t = ndbipinfo(db, "ip", ipa, alist, 1);	if(t == nil)		return 0;	for(nt = t; nt != nil; nt = nt->entry){		if(strcmp(nt->attr, attr) == 0){			nstrcpy(val, nt->val, vlen);			ndbfree(t);			return 1;		}	}	/* we shouldn't get here */	ndbfree(t);	return 0;}/* *  lookup (and translate) an ip destination */Ndbtuple*iplookup(Network *np, char *host, char *serv, int nolookup){	char *attr, *dnsname;	Ndbtuple *t, *nt;	Ndbs s;	char ts[Maxservice];	char dollar[Maxhost];	uchar ip[IPaddrlen];	uchar net[IPaddrlen];	uchar tnet[IPaddrlen];	Ipifc *ifc;	Iplifc *lifc;	USED(nolookup);	/*	 *  start with the service since it's the most likely to fail	 *  and costs the least	 */	werrstr("can't translate address");	if(serv==0 || ipserv(np, serv, ts, sizeof ts) == 0){		werrstr("can't translate service");		return 0;	}	/* for dial strings with no host */	if(strcmp(host, "*") == 0)		return ndbnew("ip", "*");	/*	 *  hack till we go v6 :: = 0.0.0.0	 */	if(strcmp("::", host) == 0)		return ndbnew("ip", "*");	/*	 *  '$' means the rest of the name is an attribute that we	 *  need to search for	 */	if(*host == '$'){		if(ipattrlookup(db, ipaddr, host+1, dollar, sizeof dollar))			host = dollar;	}	/*	 *  turn '[ip address]' into just 'ip address'	 */	if(*host == '[' && host[strlen(host)-1] == ']'){		host++;		host[strlen(host)-1] = 0;	}	/*	 *  just accept addresses	 */	attr = ipattr(host);	if(strcmp(attr, "ip") == 0)		return ndbnew("ip", host);	/*	 *  give the domain name server the first opportunity to	 *  resolve domain names.  if that fails try the database.	 */	t = 0;	werrstr("can't translate address");	if(strcmp(attr, "dom") == 0)		t = dnsiplookup(host, &s);	if(t == 0)		free(ndbgetvalue(db, &s, attr, host, "ip", &t));	if(t == 0){		dnsname = ndbgetvalue(db, &s, attr, host, "dom", nil);		if(dnsname){			t = dnsiplookup(dnsname, &s);			free(dnsname);		}	}	if(t == 0)		t = dnsiplookup(host, &s);	if(t == 0)		return 0;	/*	 *  reorder the tuple to have the matched line first and	 *  save that in the request structure.	 */	t = reorder(t, s.t);	/*	 * reorder according to our interfaces	 */	lock(&ipifclock);	for(ifc = ipifcs; ifc != nil; ifc = ifc->next){		for(lifc = ifc->lifc; lifc != nil; lifc = lifc->next){ 			maskip(lifc->ip, lifc->mask, net);			for(nt = t; nt; nt = nt->entry){				if(strcmp(nt->attr, "ip") != 0)					continue;				parseip(ip, nt->val);				maskip(ip, lifc->mask, tnet);				if(memcmp(net, tnet, IPaddrlen) == 0){					t = reorder(t, nt);					unlock(&ipifclock);					return t;				}			}		}	}	unlock(&ipifclock);	return t;}/* *  translate an ip address */char*iptrans(Ndbtuple *t, Network *np, char *serv, char *rem, int hack){	char ts[Maxservice];	char reply[Maxreply];	char x[Maxservice];	if(strcmp(t->attr, "ip") != 0)		return 0;	if(serv == 0 || ipserv(np, serv, ts, sizeof ts) == 0){		werrstr("can't translate service");		return 0;	}	if(rem != nil)		snprint(x, sizeof(x), "!%s", rem);	else		*x = 0;	if(*t->val == '*')		snprint(reply, sizeof(reply), "%s/%s/clone %s%s",			mntpt, np->net, ts, x);	else		snprint(reply, sizeof(reply), "%s/%s/clone %s!%s%s%s",			mntpt, np->net, t->val, ts, x, hack?"!fasttimeout":"");	return strdup(reply);}/* *  lookup a telephone number */Ndbtuple*telcolookup(Network *np, char *host, char *serv, int nolookup){	Ndbtuple *t;	Ndbs s;	USED(np, nolookup, serv);	werrstr("can't translate address");	free(ndbgetvalue(db, &s, "sys", host, "telco", &t));	if(t == 0)		return ndbnew("telco", host);	return reorder(t, s.t);}/* *  translate a telephone address */char*telcotrans(Ndbtuple *t, Network *np, char *serv, char *rem, int){	char reply[Maxreply];	char x[Maxservice];	if(strcmp(t->attr, "telco") != 0)		return 0;	if(rem != nil)		snprint(x, sizeof(x), "!%s", rem);	else		*x = 0;	if(serv)		snprint(reply, sizeof(reply), "%s/%s/clone %s!%s%s", mntpt, np->net,			t->val, serv, x);	else		snprint(reply, sizeof(reply), "%s/%s/clone %s%s", mntpt, np->net,			t->val, x);	return strdup(reply);}/* *  reorder the tuple to put x's line first in the entry */Ndbtuple*reorder(Ndbtuple *t, Ndbtuple *x){	Ndbtuple *nt;	Ndbtuple *line;	/* find start of this entry's line */	for(line = x; line->entry == line->line; line = line->line)		;	line = line->line;	if(line == t)		return t;	/* already the first line */	/* remove this line and everything after it from the entry */	for(nt = t; nt->entry != line; nt = nt->entry)		;	nt->entry = 0;	/* make that the start of the entry */	for(nt = line; nt->entry; nt = nt->entry)		;	nt->entry = t;	return line;}/* *  create a slave process to handle a request to avoid one request blocking *  another.  parent returns to job loop. */voidslave(void){	if(*isslave)		return;		/* we're already a slave process */	switch(rfork(RFPROC|RFNOTEG|RFMEM|RFNOWAIT)){	case -1:		break;	case 0:		if(debug)			syslog(0, logfile, "slave %d", getpid());		*isslave = 1;		break;	default:		longjmp(masterjmp, 1);	}}/* *  call the dns process and have it try to translate a name */Ndbtuple*dnsiplookup(char *host, Ndbs *s){	char buf[Maxreply];	Ndbtuple *t;	unlock(&dblock);	/* save the name before starting a slave */	snprint(buf, sizeof(buf), "%s", host);	slave();	if(strcmp(ipattr(buf), "ip") == 0)		t = dnsquery(mntpt, buf, "ptr");	else		t = dnsquery(mntpt, buf, "ip");	s->t = t;	if(t == nil){		rerrstr(buf, sizeof buf);		if(strstr(buf, "exist"))			werrstr("can't translate address: %s", buf);		else if(strstr(buf, "dns failure"))			werrstr("temporary problem: %s", buf);	}	lock(&dblock);	return t;}intqmatch(Ndbtuple *t, char **attr, char **val, int n){	int i, found;	Ndbtuple *nt;	for(i = 1; i < n; i++){		found = 0;		for(nt = t; nt; nt = nt->entry)			if(strcmp(attr[i], nt->attr) == 0)				if(strcmp(val[i], "*") == 0				|| strcmp(val[i], nt->val) == 0){					found = 1;					break;				}		if(found == 0)			break;	}	return i == n;}voidqreply(Mfile *mf, Ndbtuple *t){	Ndbtuple *nt;	String *s;	s = s_new();	for(nt = t; mf->nreply < Nreply && nt; nt = nt->entry){		s_append(s, nt->attr);		s_append(s, "=");		s_append(s, nt->val);		if(nt->line != nt->entry){			mf->replylen[mf->nreply] = s_len(s);			mf->reply[mf->nreply++] = strdup(s_to_c(s));			s_restart(s);		} else			s_append(s, " ");	}	s_free(s);}enum{	Maxattr=	32,};/* *  generic query lookup.  The query is of one of the following *  forms: * *  attr1=val1 attr2=val2 attr3=val3 ... * *  returns the matching tuple * *  ipinfo attr=val attr1 attr2 attr3 ... * *  is like ipinfo and returns the attr{1-n} *  associated with the ip address. */char*genquery(Mfile *mf, char *query){	int i, n;	char *p;	char *attr[Maxattr];	char *val[Maxattr];	Ndbtuple *t;	Ndbs s;	n = getfields(query, attr, 32, 1, " ");	if(n == 0)		return "bad query";	if(strcmp(attr[0], "ipinfo") == 0)		return ipinfoquery(mf, attr, n);	/* parse pairs */	for(i = 0; i < n; i++){		p = strchr(attr[i], '=');		if(p == 0)			return "bad query";		*p++ = 0;		val[i] = p;	}	/* give dns a chance */	if((strcmp(attr[0], "dom") == 0 || strcmp(attr[0], "ip") == 0) && val[0]){		t = dnsiplookup(val[0], &s);		if(t){			if(qmatch(t, attr, val, n)){				qreply(mf, t);				ndbfree(t);				return 0;			}			ndbfree(t);		}	}	/* first pair is always the key.  It can't be a '*' */	t = ndbsearch(db, &s, attr[0], val[0]);	/* search is the and of all the pairs */	while(t){		if(qmatch(t, attr, val, n)){			qreply(mf, t);			ndbfree(t);			return 0;		}		ndbfree(t);		t = ndbsnext(&s, attr[0], val[0]);	}	return "no match";}/* *  resolve an ip address */static Ndbtuple*ipresolve(char *attr, char *host){	Ndbtuple *t, *nt, **l;	t = iplookup(&network[Ntcp], host, "*", 0);	for(l = &t; *l != nil; ){		nt = *l;		if(strcmp(nt->attr, "ip") != 0){			*l = nt->entry;			nt->entry = nil;			ndbfree(nt);			continue;		}		strcpy(nt->attr, attr);		l = &nt->entry;	}	return t;}char*ipinfoquery(Mfile *mf, char **list, int n){	int i, nresolve;	int resolve[Maxattr];	Ndbtuple *t, *nt, **l;	char *attr, *val;	/* skip 'ipinfo' */	list++; n--;	if(n < 1)		return "bad query";	/* get search attribute=value, or assume ip=myipaddr */	attr = *list;	if((val = strchr(attr, '=')) != nil){		*val++ = 0;		list++;		n--;	}else{		attr = "ip";		val = ipaddr;	}	if(n < 1)		return "bad query";	/*	 *  don't let ndbipinfo resolve the addresses, we're	 *  better at it.	 */	nresolve = 0;	for(i = 0; i < n; i++)		if(*list[i] == '@'){			list[i]++;			resolve[i] = 1;			nresolve++;		} else			resolve[i] = 0;	t = ndbipinfo(db, attr, val, list, n);	if(t == nil)		return "no match";	if(nresolve != 0){		for(l = &t; *l != nil;){			nt = *l;			/* already an address? */			if(strcmp(ipattr(nt->val), "ip") == 0){				l = &(*l)->entry;				continue;			}			/* user wants it resolved? */			for(i = 0; i < n; i++)				if(strcmp(list[i], nt->attr) == 0)					break;			if(i >= n || resolve[i] == 0){				l = &(*l)->entry;				continue;			}			/* resolve address and replace entry */			*l = ipresolve(nt->attr, nt->val);			while(*l != nil)				l = &(*l)->entry;			*l = nt->entry;			nt->entry = nil;			ndbfree(nt);		}	}	/* make it all one line */	for(nt = t; nt != nil; nt = nt->entry){		if(nt->entry == nil)			nt->line = t;		else			nt->line = nt->entry;	}	qreply(mf, t);	return nil;}void*emalloc(int size){	void *x;	x = malloc(size);	if(x == nil)		abort();	memset(x, 0, size);	return x;}char*estrdup(char *s){	int size;	char *p;	size = strlen(s)+1;	p = malloc(size);	if(p == nil)		abort();	memmove(p, s, size);	return p;}

⌨️ 快捷键说明

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