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

📄 radix.c

📁 很好的一个嵌入式linux平台下的bootloader
💻 C
📖 第 1 页 / 共 2 页
字号:
	cplim = netmask + mlen;	for (cp = netmask + skip; cp < cplim; cp++)		if (*(u_char *)cp != 0xff)			break;	b = (cp - netmask) << 3;	if (cp != cplim) {		if (*cp != 0) {			gotOddMasks = 1;			for (j = 0x80; j; b++, j >>= 1)  				if ((j & *cp) == 0)					break;		}	}	x->rn_b = -1 - b;	return (x);}struct radix_node *rn_addroute(v, netmask, head, treenodes)struct radix_node *head;	caddr_t netmask, v;	struct radix_node treenodes[2];{	register int j;	register caddr_t cp;	register struct radix_node *t, *x, *tt;	short b = 0, b_leaf;	int vlen = *(u_char *)v, mlen, keyduplicated;	caddr_t cplim; unsigned char *maskp;	struct radix_mask *m, **mp;	struct radix_node *saved_tt;	/*	 * In dealing with non-contiguous masks, there may be	 * many different routes which have the same mask.	 * We will find it useful to have a unique pointer to	 * the mask to speed avoiding duplicate references at	 * nodes and possibly save time in calculating indices.	 */	if (netmask)  {		x = rn_search(netmask, rn_maskhead);		mlen = *(u_char *)netmask;		if (Bcmp(netmask, x->rn_key, mlen) != 0) {			x = rn_addmask(netmask, 0, head->rn_off);			if (x == 0)				return (0);		}		netmask = x->rn_key;		b = -1 - x->rn_b;	}	/*	 * Deal with duplicated keys: attach node to previous instance	 */	saved_tt = tt = rn_insert(v, head, &keyduplicated, treenodes);	if (keyduplicated) {		do {			if (tt->rn_mask == netmask)				return (0);			t = tt;		} while (tt = tt->rn_dupedkey);		/*		 * If the mask is not duplicated, we wouldn't		 * find it among possible duplicate key entries		 * anyway, so the above test doesn't hurt.		 *		 * XXX: we really ought to sort the masks		 * for a duplicated key the same way as in a masklist.		 * It is an unfortunate pain having to relocate		 * the head of the list.		 */		t->rn_dupedkey = tt = treenodes;#ifdef RN_DEBUG		t=tt+1; tt->rn_info = rn_nodenum++; t->rn_info = rn_nodenum++;		tt->rn_twin = t; tt->rn_ybro = rn_clist; rn_clist = tt;#endif		t = saved_tt;		tt->rn_key = (caddr_t) v;		tt->rn_b = -1;		tt->rn_flags = t->rn_flags & ~RNF_ROOT;	}	/*	 * Put mask in tree.	 */	if (netmask) {		tt->rn_mask = netmask;		tt->rn_b = x->rn_b;	}	t = saved_tt->rn_p;	b_leaf = -1 - t->rn_b;	if (t->rn_r == saved_tt) x = t->rn_l; else x = t->rn_r;	/* Promote general routes from below */	if (x->rn_b < 0) { 		if (x->rn_mask && (x->rn_b >= b_leaf) && x->rn_mklist == 0) {			MKGet(m);			if (m) {				Bzero(m, sizeof *m);				m->rm_b = x->rn_b;				m->rm_mask = x->rn_mask;				x->rn_mklist = t->rn_mklist = m;			}		}	} else if (x->rn_mklist) {		/*		 * Skip over masks whose index is > that of new node		 */		for (mp = &x->rn_mklist; m = *mp; mp = &m->rm_mklist)			if (m->rm_b >= b_leaf)				break;		t->rn_mklist = m; *mp = 0;	}	/* Add new route to highest possible ancestor's list */	if ((netmask == 0) || (b > t->rn_b ))		return tt; /* can't lift at all */	b_leaf = tt->rn_b;	do {		x = t;		t = t->rn_p;	} while (b <= t->rn_b && x != head);	/*	 * Search through routes associated with node to	 * insert new route according to index.	 * For nodes of equal index, place more specific	 * masks first.	 */	cplim = netmask + mlen;	for (mp = &x->rn_mklist; m = *mp; mp = &m->rm_mklist) {		if (m->rm_b < b_leaf)			continue;		if (m->rm_b > b_leaf)			break;		if (m->rm_mask == netmask) {			m->rm_refs++;			tt->rn_mklist = m;			return tt;		}		maskp = (u_char *)m->rm_mask;		for (cp = netmask; cp < cplim; cp++)			if (*(u_char *)cp > *maskp++)				goto on2;	}on2:	MKGet(m);	if (m == 0) {		printf("Mask for route not entered\n");		return (tt);	}	Bzero(m, sizeof *m);	m->rm_b = b_leaf;	m->rm_mask = netmask;	m->rm_mklist = *mp;	*mp = m;	tt->rn_mklist = m;	return tt;}struct radix_node *rn_delete(v, netmask, head)	caddr_t v, netmask;	struct radix_node *head;{	register struct radix_node *t, *p, *x = head;	register struct radix_node *tt = rn_search(v, x);	int b, head_off = x->rn_off, vlen =  * (u_char *) v;	struct radix_mask *m, *saved_m, **mp;	struct radix_node *dupedkey, *saved_tt = tt;	if (tt == 0 ||	    Bcmp(v + head_off, tt->rn_key + head_off, vlen - head_off))		return (0);	/*	 * Delete our route from mask lists.	 */	if (dupedkey = tt->rn_dupedkey) {		if (netmask) 			netmask = rn_search(netmask, rn_maskhead)->rn_key;		while (tt->rn_mask != netmask)			if ((tt = tt->rn_dupedkey) == 0)				return (0);	}	if (tt->rn_mask == 0 || (saved_m = m = tt->rn_mklist) == 0)		goto on1;	if (m->rm_mask != tt->rn_mask) {		printf("rn_delete: inconsistent annotation\n");		goto on1;	}	if (--m->rm_refs >= 0)		goto on1;	b = -1 - tt->rn_b;	t = saved_tt->rn_p;	if (b > t->rn_b)		goto on1; /* Wasn't lifted at all */	do {		x = t;		t = t->rn_p;	} while (b <= t->rn_b && x != head);	for (mp = &x->rn_mklist; m = *mp; mp = &m->rm_mklist)		if (m == saved_m) {			*mp = m->rm_mklist;			MKFree(m);			break;		}	if (m == 0)		printf("rn_delete: couldn't find our annotation\n");on1:	/*	 * Eliminate us from tree	 */	if (tt->rn_flags & RNF_ROOT)		return (0);#ifdef RN_DEBUG	/* Get us out of the creation list */	for (t = rn_clist; t && t->rn_ybro != tt; t = t->rn_ybro) {}	if (t) t->rn_ybro = tt->rn_ybro;#endif RN_DEBUG	t = tt->rn_p;	if (dupedkey) {		if (tt == saved_tt) {			x = dupedkey; x->rn_p = t;			if (t->rn_l == tt) t->rn_l = x; else t->rn_r = x;#ifndef RN_DEBUG			x++; t = tt + 1; *x = *t; p = t->rn_p;#else			x++; b = x->rn_info; t = tt + 1; *x = *t; p = t->rn_p;			x->rn_info = b;#endif			if (p->rn_l == t) p->rn_l = x; else p->rn_r = x;			x->rn_l->rn_p = x; x->rn_r->rn_p = x;		} else {			for (p = saved_tt; p && p->rn_dupedkey != tt;)				p = p->rn_dupedkey;			if (p) p->rn_dupedkey = tt->rn_dupedkey;			else printf("rn_delete: couldn't find us\n");		}		goto out;	}	if (t->rn_l == tt) x = t->rn_r; else x = t->rn_l;	p = t->rn_p;	if (p->rn_r == t) p->rn_r = x; else p->rn_l = x;	x->rn_p = p;	/*	 * Demote routes attached to us.	 */	if (t->rn_mklist) {		if (x->rn_b >= 0) {			for (mp = &x->rn_mklist; m = *mp;)				mp = &m->rm_mklist;			*mp = t->rn_mklist;		} else {			for (m = t->rn_mklist; m;) {				struct radix_mask *mm = m->rm_mklist;				if (m == x->rn_mklist && (--(m->rm_refs) < 0)) {					x->rn_mklist = 0;					MKFree(m);				} else 					printf("%s %x at %x\n",					    "rn_delete: Orphaned Mask", m, x);				m = mm;			}		}	}	/*	 * We may be holding an active internal node in the tree.	 */	x = tt + 1;	if (t != x) {#ifndef RN_DEBUG		*t = *x;#else		b = t->rn_info; *t = *x; t->rn_info = b;#endif		t->rn_l->rn_p = t; t->rn_r->rn_p = t;		p = x->rn_p;		if (p->rn_l == x) p->rn_l = t; else p->rn_r = t;	}out:	tt->rn_flags &= ~RNF_ACTIVE;	tt[1].rn_flags &= ~RNF_ACTIVE;	return (tt);}char rn_zeros[MAXKEYLEN], rn_ones[MAXKEYLEN];rn_inithead(head, off, af)struct radix_node_head **head;int off;{	register struct radix_node_head *rnh;	register struct radix_node *t, *tt, *ttt;	if (*head)		return (1);	R_Malloc(rnh, struct radix_node_head *, sizeof (*rnh));	if (rnh == 0)		return (0);	Bzero(rnh, sizeof (*rnh));	*head = rnh;	t = rn_newpair(rn_zeros, off, rnh->rnh_nodes);	ttt = rnh->rnh_nodes + 2;	t->rn_r = ttt;	t->rn_p = t;	tt = t->rn_l;	tt->rn_flags = t->rn_flags = RNF_ROOT | RNF_ACTIVE;	tt->rn_b = -1 - off;	*ttt = *tt;	ttt->rn_key = rn_ones;	rnh->rnh_af = af;	rnh->rnh_treetop = t;	if (radix_node_head == 0) {		caddr_t cp = rn_ones, cplim = rn_ones + MAXKEYLEN;		while (cp < cplim)			*cp++ = -1;		if (rn_inithead(&radix_node_head, 0, 0) == 0) {			Free(rnh);			*head = 0;			return (0);		}		mask_rnhead = radix_node_head;	}	rnh->rnh_next = radix_node_head->rnh_next;	if (radix_node_head != rnh)		radix_node_head->rnh_next = rnh;	return (1);}

⌨️ 快捷键说明

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