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

📄 main.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
	if(last == nil){		if(f->pr == root)			return f;		f = fillin(f, root);		if(f == nil)			return nil;		return addnode(f, root);	}	/* breadth first search though the protocol graph */	nf = f;	for(i = 1; i < 20; i++){		nf = _fillin(f, last, i);		if(nf != nil)			break;	}	return nf;}/* *  massage tree so that all paths from the root to a leaf *  contain a filter node for each header. * *  also, set f->pr where possible */Filter*complete(Filter *f, Proto *last){	Proto *pr;	if(f == nil)		return f;	/* do a depth first traversal of the filter tree */	switch(f->op){	case '!':		f->l = complete(f->l, last);		break;	case LAND:	case LOR:		f->l = complete(f->l, last);		f->r = complete(f->r, last);		break;	case '=':		break;	case WORD:		pr = findproto(f->s);		f->pr = pr;		if(pr == nil){			if(f->l != nil){				fprint(2, "%s unknown proto, ignoring params\n",					f->s);				f->l = nil;			}		} else {			f->l = complete(f->l, pr);			f = fillin(f, last);			if(f == nil)				sysfatal("internal error: can't get to %s", pr->name);		}		break;	}	return f;}/* *  merge common nodes under | and & moving the merged node *  above the | or &. * *  do some constant foldong, e.g. `true & x' becomes x and *  'true | x' becomes true. */static int changed;static Filter*_optimize(Filter *f){	Filter *l;	if(f == nil)		return f;	switch(f->op){	case '!':		/* is child also a not */		if(f->l->op == '!'){			changed = 1;			return f->l->l;		}		break;	case LOR:		/* are two children the same protocol? */		if(f->l->op != f->r->op || f->r->op != WORD		|| f->l->pr != f->r->pr || f->l->pr == nil)			break;	/* no optimization */		changed = 1;		/* constant folding */		/* if either child is childless, just return that */		if(f->l->l == nil)			return f->l;		else if(f->r->l == nil)			return f->r;		/* move the common node up, thow away one node */		l = f->l;		f->l = l->l;		f->r = f->r->l;		l->l = f;		return l;	case LAND:		/* are two children the same protocol? */		if(f->l->op != f->r->op || f->r->op != WORD		|| f->l->pr != f->r->pr || f->l->pr == nil)			break;	/* no optimization */		changed = 1;		/* constant folding */		/* if either child is childless, ignore it */		if(f->l->l == nil)			return f->r;		else if(f->r->l == nil)			return f->l;		/* move the common node up, thow away one node */		l = f->l;		f->l = _optimize(l->l);		f->r = _optimize(f->r->l);		l->l = f;		return l;	}	f->l = _optimize(f->l);	f->r = _optimize(f->r);	return f;}Filter*optimize(Filter *f){	do{		changed = 0;		f = _optimize(f);	}while(changed);	return f;}/* *  find any top level nodes that aren't the root */intfindbogus(Filter *f){	int rv;	if(f->op != WORD){		rv = findbogus(f->l);		if(f->r)			rv |= findbogus(f->r);		return rv;	} else if(f->pr != root){		fprint(2, "bad top-level protocol: %s\n", f->s);		return 1;	}	return 0;}/* *  compile the filter */static void_compile(Filter *f, Proto *last){	if(f == nil)		return;	switch(f->op){	case '!':		_compile(f->l, last);		break;	case LOR:	case LAND:		_compile(f->l, last);		_compile(f->r, last);		break;	case WORD:		if(last != nil){			if(last->compile == nil)				sysfatal("unknown %s subprotocol: %s", f->pr->name, f->s);			(*last->compile)(f);		}		if(f->l)			_compile(f->l, f->pr);		break;	case '=':		if(last == nil)			sysfatal("internal error: compilewalk: badly formed tree");				if(last->compile == nil)			sysfatal("unknown %s field: %s", f->pr->name, f->s);		(*last->compile)(f);		break;	default:		sysfatal("internal error: compilewalk op: %d", f->op);	}}Filter*compile(Filter *f){	if(f == nil)		return f;	/* fill in the missing header filters */	f = complete(f, nil);	/* constant folding */	f = optimize(f);	if(!toflag)		printfilter(f, "after optimize");	/* protocol specific compilations */	_compile(f, nil);	/* at this point, the root had better be the root proto */	if(findbogus(f)){		fprint(2, "bogus filter\n");		exits("bad filter");	}	return f;}/* *  parse a byte array */intparseba(uchar *to, char *from){	char nip[4];	char *p;	int i;	p = from;	for(i = 0; i < 16; i++){		if(*p == 0)			return -1;		nip[0] = *p++;		if(*p == 0)			return -1;		nip[1] = *p++;		nip[2] = 0;		to[i] = strtoul(nip, 0, 16);	}	return i;}/* *  compile WORD = WORD, becomes a single node with a subop */voidcompile_cmp(char *proto, Filter *f, Field *fld){	uchar x[IPaddrlen];	if(f->op != '=')		sysfatal("internal error: compile_cmp %s: not a cmp", proto);	for(; fld->name != nil; fld++){		if(strcmp(f->l->s, fld->name) == 0){			f->op = WORD;			f->subop = fld->subop;			switch(fld->ftype){			case Fnum:				f->ulv = atoi(f->r->s);				break;			case Fether:				parseether(f->a, f->r->s);				break;			case Fv4ip:				f->ulv = parseip(x, f->r->s);				break;			case Fv6ip:				parseip(f->a, f->r->s);				break;			case Fba:				parseba(f->a, f->r->s);				break;			default:				sysfatal("internal error: compile_cmp %s: %d",					proto, fld->ftype);			}			f->l = f->r = nil;			return;		}	}	sysfatal("unknown %s field in: %s = %s", proto, f->l->s, f->r->s);}void_pf(Filter *f){	char *s;	if(f == nil)		return;	s = nil;	switch(f->op){	case '!':		fprint(2, "!");		_pf(f->l);		break;	case WORD:		fprint(2, "%s", f->s);		if(f->l != nil){			fprint(2, "(");			_pf(f->l);			fprint(2, ")");		}		break;	case LAND:		s = "&&";		goto print;	case LOR:		s = "||";		goto print;	case '=':	print:		_pf(f->l);		if(s)			fprint(2, " %s ", s);		else			fprint(2, " %c ", f->op);		_pf(f->r);		break;	default:		fprint(2, "???");		break;	}}voidprintfilter(Filter *f, char *tag){	fprint(2, "%s: ", tag);	_pf(f);	fprint(2, "\n");}voidcat(void){	char buf[1024];	int n;		while((n = read(0, buf, sizeof buf)) > 0)		write(1, buf, n);}static int fd1 = -1;voidstartmc(void){	int p[2];		if(fd1 == -1)		fd1 = dup(1, -1);		if(pipe(p) < 0)		return;	switch(fork()){	case -1:		return;	default:		close(p[0]);		dup(p[1], 1);		if(p[1] != 1)			close(p[1]);		return;	case 0:		close(p[1]);		dup(p[0], 0);		if(p[0] != 0)			close(p[0]);		execl("/bin/mc", "mc", nil);		cat();		_exits(0);	}}voidstopmc(void){	close(1);	dup(fd1, 1);	waitpid();}voidprinthelp(char *name){	int len;	Proto *pr, **l;	Mux *m;	Field *f;	char fmt[40];		if(name == nil){		print("protocols:\n");		startmc();		for(l=protos; (pr=*l) != nil; l++)			print("  %s\n", pr->name);		stopmc();		return;	}		pr = findproto(name);	if(pr == nil){		print("unknown protocol %s\n", name);		return;	}		if(pr->field){		print("%s's filter attributes:\n", pr->name);		len = 0;		for(f=pr->field; f->name; f++)			if(len < strlen(f->name))				len = strlen(f->name);		startmc();		for(f=pr->field; f->name; f++)			print("  %-*s - %s\n", len, f->name, f->help);		stopmc();	}	if(pr->mux){		print("%s's subprotos:\n", pr->name);		startmc();		snprint(fmt, sizeof fmt, "  %s %%s\n", pr->valfmt);		for(m=pr->mux; m->name != nil; m++)			print(fmt, m->val, m->name);		stopmc();	}}/* *  demultiplex to next prototol header */voiddemux(Mux *mx, ulong val1, ulong val2, Msg *m, Proto *def){	m->pr = def;	for(mx = mx; mx->name != nil; mx++){		if(val1 == mx->val || val2 == mx->val){			m->pr = mx->pr;			break;		}	}}/* *  default framer just assumes the input packet is *  a single read */intdefaultframer(int fd, uchar *pkt, int pktlen){	return read(fd, pkt, pktlen);}

⌨️ 快捷键说明

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