shithub: riscv

Download patch

ref: a4e444f430b874661f2793d8f9d1daeab60a89b1
parent: 08385e66816940b999a5c433a1feef303cea67e4
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Sep 16 08:39:47 EDT 2018

libndb: make ndbipinfo() walk ipnet for all matching entries, concatenate and dedup result

--- a/sys/include/ndb.h
+++ b/sys/include/ndb.h
@@ -148,4 +148,5 @@
 void		ndbsetval(Ndbtuple*, char*, int);
 Ndbtuple*	ndbsnext(Ndbs*, char*, char*);
 Ndbtuple*	ndbsubstitute(Ndbtuple*, Ndbtuple*, Ndbtuple*);
+Ndbtuple*	ndbdedup(Ndbtuple*);
 void		ndbsetmalloctag(Ndbtuple*, uintptr);
--- a/sys/man/2/ndb
+++ b/sys/man/2/ndb
@@ -1,6 +1,6 @@
 .TH NDB 2
 .SH NAME
-ndbopen, ndbcat, ndbchanged, ndbclose, ndbreopen, ndbsearch, ndbsnext, ndbgetvalue, ndbfree, ipattr, ndbgetipaddr, ndbipinfo, csipinfo, ndbhash, ndbparse, csgetvalue, ndbfindattr, dnsquery, ndbdiscard, ndbconcatenate, ndbreorder, ndbsubstitute \- network database
+ndbopen, ndbcat, ndbchanged, ndbclose, ndbreopen, ndbsearch, ndbsnext, ndbgetvalue, ndbfree, ipattr, ndbgetipaddr, ndbipinfo, csipinfo, ndbhash, ndbparse, csgetvalue, ndbfindattr, dnsquery, ndbdiscard, ndbconcatenate, ndbreorder, ndbsubstitute, ndbdedup \- network database
 .SH SYNOPSIS
 .B #include <u.h>
 .br
@@ -87,6 +87,9 @@
 Ndbtuple*	ndbsubstitute(Ndbtuple *t, Ndbtuple *from, Ndbtuple *to)
 .PP
 .B
+Ndbtuple*	ndbdedup(Ndbtuple *t)
+.PP
+.B
 void	ndbsetmalloctag(Ndbtuple *t, uintptr tag)
 .SH DESCRIPTION
 These routines are used by network administrative programs to search
@@ -236,13 +239,13 @@
 .I Ndbgetipaddr
 looks in
 .I db
-for an entry matching
+for entries matching
 .I sys
 as the value of a
 .B sys=
 or
 .B dom=
-attribute/value pair and returns all IP addresses in the entry.
+attribute/value pair and returns all IP addresses.
 If
 .I sys
 is already an IP address, a tuple containing just
@@ -464,7 +467,7 @@
 first in its line.
 .PP
 .I Ndbsubstitute
-replaces a single att/val pair
+replaces a single attr/val pair
 .I from
 in
 .I t
@@ -475,6 +478,10 @@
 end up on the same line.
 .I from
 is freed.
+.PP
+.I Ndbdedup
+removes duplicate attr/val pairs from tuple list
+.IR t .
 .PP
 .I Ndbsetmalloctag
 sets the malloc tag
--- a/sys/src/cmd/ndb/cs.c
+++ b/sys/src/cmd/ndb/cs.c
@@ -1392,7 +1392,7 @@
 	}
 	qunlock(&ipifclock);
 
-	return t;
+	return ndbdedup(t);
 }
 
 /*
@@ -1919,29 +1919,6 @@
 	return t;
 }
 
-/*
- *  remove duplicates
- */
-static Ndbtuple*
-ndbdedup(Ndbtuple *t)
-{
-	Ndbtuple *tt, *nt, **l;
-
-	for(nt = t; nt != nil; nt = nt->entry){
-		for(l = &nt->entry; (tt = *l) != nil;){
-			if(strcmp(nt->attr, tt->attr) != 0
-			|| strcmp(nt->val, tt->val) != 0){
-				l = &tt->entry;
-				continue;
-			}
-			*l = tt->entry;
-			tt->entry = nil;
-			ndbfree(tt);
-		}
-	}
-	return t;
-}
-
 char*
 ipinfoquery(Mfile *mf, char **list, int n)
 {
@@ -1992,7 +1969,6 @@
 		return "no match";
 
 	if(nresolve != 0){
-		t = ndbdedup(t);
 		for(l = &t; *l != nil;){
 			nt = *l;
 
@@ -2020,8 +1996,9 @@
 			nt->entry = nil;
 			ndbfree(nt);
 		}
+
+		t = ndbdedup(t);
 	}
-	t = ndbdedup(t);
 
 	/* make it all one line */
 	t = ndbline(t);
--- a/sys/src/cmd/ndb/dblookup.c
+++ b/sys/src/cmd/ndb/dblookup.c
@@ -794,7 +794,7 @@
 	qunlock(&ipifclock);
 	qunlock(&dblock);
 
-	return t;
+	return ndbdedup(t);
 }
 
 /*
--- a/sys/src/libndb/mkfile
+++ b/sys/src/libndb/mkfile
@@ -21,6 +21,7 @@
 	ndbparse.$O\
 	ndbreorder.$O\
 	ndbsubstitute.$O\
+	ndbdedup.$O\
 
 HFILES=\
 	/sys/include/ndb.h\
--- a/sys/src/libndb/ndbgetipaddr.c
+++ b/sys/src/libndb/ndbgetipaddr.c
@@ -16,6 +16,7 @@
 	attr = ipattr(val);
 	if(strcmp(attr, "ip") == 0){
 		it = ndbnew("ip", val);
+		it->line = it;
 		ndbsetmalloctag(it, getcallerpc(&db));
 		return it;
 	}
@@ -25,24 +26,29 @@
 	if(p == nil)
 		return nil;
 	free(p);
-
-	/* remove the non-ip entries */
 	first = last = nil;
-	for(; it; it = next){
-		next = it->entry;
-		if(strcmp(it->attr, "ip") == 0){
-			if(first == nil)
-				first = it;
-			else
-				last->entry = it;
-			it->entry = nil;
-			it->line = first;
-			last = it;
-		} else {
-			it->entry = nil;
-			ndbfree(it);
+	do {
+		/* remove the non-ip entries */
+		for(; it != nil; it = next){
+			next = it->entry;
+			if(strcmp(it->attr, "ip") == 0){
+				if(first == nil)
+					first = it;
+				else {
+					last->entry = it;
+					last->line = it;
+				}
+				it->entry = nil;
+				it->line = first;
+				last = it;
+			} else {
+				it->entry = nil;
+				ndbfree(it);
+			}
 		}
-	}
+	} while((it = ndbsnext(&s, attr, val)) != nil);
+
+	first = ndbdedup(first);
 
 	ndbsetmalloctag(first, getcallerpc(&db));
 	return first;
--- a/sys/src/libndb/ndbipinfo.c
+++ b/sys/src/libndb/ndbipinfo.c
@@ -149,67 +149,29 @@
 	return t;
 }
 
-/*
- *  fill in all the requested attributes for a system.
- *  if the system's entry doesn't have all required,
- *  walk through successively more inclusive networks
- *  for inherited attributes.
- */
-Ndbtuple*
-ndbipinfo(Ndb *db, char *attr, char *val, char **alist, int n)
+static Ndbtuple*
+netinfo(Ndb *db, Ndbtuple *t, char **alist, int n)
 {
-	Ndbtuple *t, *nt, *f;
-	Ndbs s;
-	char *ipstr;
-	uchar net[IPaddrlen], ip[IPaddrlen];
+	uchar ip[IPaddrlen], net[IPaddrlen];
 	int prefix, smallestprefix, force;
-	vlong r;
+	Ndbtuple *f, *nt;
 
-	/* just in case */
-	fmtinstall('I', eipfmt);
-	fmtinstall('M', eipfmt);
+	nt = ndbfindattr(t, t, "ip");
+	if(nt == nil || parseip(ip, nt->val) == -1){
+		ndbfree(t);
+		return nil;
+	}
 
 	/* get needed attributes */
 	f = mkfilter(n, alist);
 
-	/*
-	 *  first look for a matching entry with an ip address
-	 */
-	t = nil;
-	ipstr = ndbgetvalue(db, &s, attr, val, "ip", &nt);
-	if(ipstr == nil){
-		/* none found, make one up */
-		if(strcmp(attr, "ip") != 0) {
-			ndbfree(f);
-			return nil;	
-		}
-		t = ndbnew("ip", val);
-		t->line = t;
-		t->entry = nil;
-		r = parseip(net, val);
-		if(r == -1)
-			ndbfree(t);
-	} else {
-		/* found one */
-		while(nt != nil){
-			nt = ndbreorder(nt, s.t);
-			t = ndbconcatenate(t, nt);
-			nt = ndbsnext(&s, attr, val);
-		}
-		r = parseip(net, ipstr);
-		free(ipstr);
-	}
-	if(r < 0){
-		ndbfree(f);
-		return nil;
-	}
-	ipmove(ip, net);
 	t = filter(db, t, f);
 
 	/*
 	 *  now go through subnets to fill in any missing attributes
 	 */
-	if(isv4(net)){
+	ipmove(net, ip);
+	if(isv4(ip)){
 		prefix = 127;
 		smallestprefix = 100;
 		force = 0;
@@ -241,14 +203,58 @@
 	 *  if there's an unfulfilled ipmask, make one up
 	 */
 	nt = ndbfindattr(f, f, "ipmask");
-	if(nt && !(nt->ptr & Fignore)){
+	if(nt != nil && !(nt->ptr & Fignore)){
 		char x[64];
 
 		snprint(x, sizeof(x), "%M", defmask(ip));
-		t = ndbconcatenate(t, ndbnew("ipmask", x));
+		nt = ndbnew("ipmask", x);
+		nt->line = nt;
+		nt->entry = nil;
+		t = ndbconcatenate(t, nt);
 	}
 
 	ndbfree(f);
 	ndbsetmalloctag(t, getcallerpc(&db));
 	return t;
+}
+
+/*
+ *  fill in all the requested attributes for a system.
+ *  if the system's entry doesn't have all required,
+ *  walk through successively more inclusive networks
+ *  for inherited attributes.
+ */
+Ndbtuple*
+ndbipinfo(Ndb *db, char *attr, char *val, char **alist, int n)
+{
+	Ndbtuple *t, *nt;
+	char *ipstr;
+	Ndbs s;
+
+	/* just in case */
+	fmtinstall('I', eipfmt);
+	fmtinstall('M', eipfmt);	
+
+	/*
+	 *  first look for a matching entry with an ip address
+	 */
+	ipstr = ndbgetvalue(db, &s, attr, val, "ip", &nt);
+	if(ipstr == nil){
+		/* none found, make one up */
+		if(strcmp(attr, "ip") != 0)
+			return nil;	
+		nt = ndbnew("ip", val);
+		nt->line = nt;
+		nt->entry = nil;
+		t = netinfo(db, nt, alist, n);
+	} else {
+		/* found one */
+		free(ipstr);
+		t = nil;
+		do {
+			nt = ndbreorder(nt, s.t);
+			t = ndbconcatenate(t, netinfo(db, nt, alist, n));
+		} while((nt = ndbsnext(&s, attr, val)) != nil);
+	}
+	return ndbdedup(t);
 }