Browse Source

Plan 9 from Bell Labs 2004-03-10

David du Colombier 20 years ago
parent
commit
9c736214c2

+ 23 - 24
dist/replica/plan9.db

@@ -543,7 +543,7 @@
 386/lib/libmemdraw.a - 664 sys sys 1073851273 291288
 386/lib/libmemlayer.a - 664 sys sys 1073851273 47636
 386/lib/libmp.a - 664 sys sys 1077940925 77700
-386/lib/libndb.a - 664 sys sys 1078626124 61198
+386/lib/libndb.a - 664 sys sys 1078839930 60772
 386/lib/libplumb.a - 664 sys sys 1073851274 18876
 386/lib/libregexp.a - 664 sys sys 1073851274 37502
 386/lib/libscribble.a - 664 sys sys 1073851274 107542
@@ -3413,7 +3413,7 @@ sys/include/memdraw.h - 664 sys sys 1039752978 5616
 sys/include/memlayer.h - 664 sys sys 1051031022 1851
 sys/include/mouse.h - 664 sys sys 1035232010 1003
 sys/include/mp.h - 664 sys sys 1014929065 4610
-sys/include/ndb.h - 664 sys sys 1078618596 4334
+sys/include/ndb.h - 664 sys sys 1078839927 4315
 sys/include/nfs3.h - 664 sys sys 1045589438 15082
 sys/include/plumb.h - 664 sys sys 1014929065 989
 sys/include/pool.h - 664 sys sys 1032058257 1156
@@ -4835,7 +4835,7 @@ sys/man/2/mouse - 664 sys sys 971455512 4966
 sys/man/2/mp - 664 sys sys 1071238964 10690
 sys/man/2/muldiv - 664 sys sys 984709633 639
 sys/man/2/nan - 664 sys sys 975084242 937
-sys/man/2/ndb - 664 sys sys 1078625843 9479
+sys/man/2/ndb - 664 sys sys 1078840106 9427
 sys/man/2/notify - 664 sys sys 1032058674 6376
 sys/man/2/object - 664 sys sys 944959695 3864
 sys/man/2/open - 664 sys sys 1015091524 3404
@@ -5207,7 +5207,6 @@ sys/src/9/boot/bootmkfile - 664 sys sys 1032053196 390
 sys/src/9/boot/doauthenticate.c - 664 sys sys 1015012529 2300
 sys/src/9/boot/embed.c - 664 sys sys 1039763720 1191
 sys/src/9/boot/getpasswd.c - 664 sys sys 957373373 654
-sys/src/9/boot/libboot.a8 - 664 sys sys 1074883206 62012
 sys/src/9/boot/local.c - 664 sys sys 1068835808 5355
 sys/src/9/boot/mkboot - 775 sys sys 1045504382 1935
 sys/src/9/boot/nopsession.c - 664 sys sys 957373374 843
@@ -6762,7 +6761,7 @@ sys/src/cmd/9nfs/pcnfsd.c - 664 sys sys 1017337815 3964
 sys/src/cmd/9nfs/portmapper.c - 664 sys sys 1040952456 3179
 sys/src/cmd/9nfs/rpc.c - 664 sys sys 1017337815 5293
 sys/src/cmd/9nfs/rpc.h - 664 sys sys 1017337815 1996
-sys/src/cmd/9nfs/server.c - 664 sys sys 1050715043 11065
+sys/src/cmd/9nfs/server.c - 664 sys sys 1078839960 10996
 sys/src/cmd/9nfs/string.c - 664 sys sys 1017337815 1659
 sys/src/cmd/9nfs/strparse.c - 664 sys sys 1015090373 506
 sys/src/cmd/9nfs/system.c - 664 sys sys 1017337815 437
@@ -6794,7 +6793,7 @@ sys/src/cmd/acme/disk.c - 664 sys sys 1014926093 2151
 sys/src/cmd/acme/ecmd.c - 664 sys sys 1077376256 24294
 sys/src/cmd/acme/edit.c - 664 sys sys 1015701171 12055
 sys/src/cmd/acme/edit.h - 664 sys sys 969500816 2466
-sys/src/cmd/acme/elog.c - 664 sys sys 1067723163 7241
+sys/src/cmd/acme/elog.c - 664 sys sys 1078839859 7236
 sys/src/cmd/acme/exec.c - 664 sys sys 1077376257 28024
 sys/src/cmd/acme/file.c - 664 sys sys 1044626079 5717
 sys/src/cmd/acme/fns.h - 664 sys sys 1077376255 2857
@@ -6848,14 +6847,14 @@ sys/src/cmd/astro/venust.c - 664 sys sys 944960761 739
 sys/src/cmd/auth - 20000000775 sys sys 1015008432 0
 sys/src/cmd/auth/asn12rsa.c - 664 sys sys 1048614959 1192
 sys/src/cmd/auth/authcmdlib.h - 664 sys sys 1032497636 1438
-sys/src/cmd/auth/authsrv.c - 664 sys sys 1051128389 18428
+sys/src/cmd/auth/authsrv.c - 664 sys sys 1078839960 18395
 sys/src/cmd/auth/challenge.c - 664 sys sys 1015008432 980
 sys/src/cmd/auth/changeuser.c - 664 sys sys 1015008431 2933
 sys/src/cmd/auth/convbio.c - 664 sys sys 1015008432 2212
 sys/src/cmd/auth/convkeys.c - 664 sys sys 1015008430 2347
 sys/src/cmd/auth/convkeys2.c - 664 sys sys 1015008432 2401
 sys/src/cmd/auth/cron.c - 664 sys sys 1063858528 11410
-sys/src/cmd/auth/debug.c - 664 sys sys 1044839697 7324
+sys/src/cmd/auth/debug.c - 664 sys sys 1078839961 7339
 sys/src/cmd/auth/disable - 775 sys sys 1015008431 146
 sys/src/cmd/auth/enable - 775 sys sys 1015008430 134
 sys/src/cmd/auth/factotum - 20000000775 sys sys 1017165894 0
@@ -6930,7 +6929,7 @@ sys/src/cmd/auth/secstore/secstore.h - 664 sys sys 1041890053 841
 sys/src/cmd/auth/secstore/secstored.c - 664 sys sys 1074559798 7998
 sys/src/cmd/auth/secstore/secuser.c - 664 sys sys 1064667494 4971
 sys/src/cmd/auth/secstore/util.c - 664 sys sys 1021579985 1498
-sys/src/cmd/auth/secureidcheck.c - 664 sys sys 1074559811 8985
+sys/src/cmd/auth/secureidcheck.c - 664 sys sys 1078840013 9007
 sys/src/cmd/auth/status - 775 sys sys 1015008430 738
 sys/src/cmd/auth/uniq.c - 664 sys sys 1015008430 1429
 sys/src/cmd/auth/userpasswd.c - 664 sys sys 1015008432 591
@@ -7078,7 +7077,7 @@ sys/src/cmd/aux/reboot.c - 664 sys sys 1014925091 1411
 sys/src/cmd/aux/searchfs.c - 664 sys sys 1014925091 18176
 sys/src/cmd/aux/stub.c - 664 sys sys 1032468954 2637
 sys/src/cmd/aux/timesync.c - 664 sys sys 1071334828 24811
-sys/src/cmd/aux/trampoline.c - 664 sys sys 1034780422 3571
+sys/src/cmd/aux/trampoline.c - 664 sys sys 1078840013 3521
 sys/src/cmd/aux/typepasswd.c - 664 sys sys 1014925091 1761
 sys/src/cmd/aux/unlock - 664 sys sys 944960793 0
 sys/src/cmd/aux/vga - 20000000775 sys sys 1018723175 0
@@ -7094,7 +7093,7 @@ sys/src/cmd/aux/vga/clgd546x.c - 664 sys sys 1014925007 7996
 sys/src/cmd/aux/vga/ct65540.c - 664 sys sys 1014925007 5355
 sys/src/cmd/aux/vga/cyber938x.c - 664 sys sys 1045505008 6440
 sys/src/cmd/aux/vga/data.c - 664 sys sys 1019498850 2200
-sys/src/cmd/aux/vga/db.c - 664 sys sys 1048636615 9349
+sys/src/cmd/aux/vga/db.c - 664 sys sys 1078840016 9331
 sys/src/cmd/aux/vga/error.c - 664 sys sys 1014925008 745
 sys/src/cmd/aux/vga/et4000.c - 664 sys sys 1014925008 6720
 sys/src/cmd/aux/vga/et4000hwgc.c - 664 sys sys 1014925008 552
@@ -9426,7 +9425,6 @@ sys/src/cmd/ip/ftpfs/ftpfs.c - 664 sys sys 1048285493 13555
 sys/src/cmd/ip/ftpfs/ftpfs.h - 664 sys sys 1048312051 2328
 sys/src/cmd/ip/ftpfs/mkfile - 664 sys sys 1048312050 173
 sys/src/cmd/ip/ftpfs/proto.c - 664 sys sys 1048285496 29321
-sys/src/cmd/ip/gizzard.c - 664 sys sys 1063897565 8950
 sys/src/cmd/ip/glob.c - 664 sys sys 1015013111 2968
 sys/src/cmd/ip/glob.h - 664 sys sys 1015090252 270
 sys/src/cmd/ip/gping.c - 664 sys sys 1015013112 20476
@@ -9434,6 +9432,7 @@ sys/src/cmd/ip/hogports.c - 664 sys sys 988225294 987
 sys/src/cmd/ip/httpd - 20000000775 sys sys 1016902735 0
 sys/src/cmd/ip/httpd/anonymous.c - 664 sys sys 984773807 195
 sys/src/cmd/ip/httpd/authorize.c - 664 sys sys 1016902735 2387
+sys/src/cmd/ip/httpd/classify.c - 664 sys sys 1078840017 9665
 sys/src/cmd/ip/httpd/content.c - 664 sys sys 1015090170 3140
 sys/src/cmd/ip/httpd/emem.c - 664 sys sys 984773807 278
 sys/src/cmd/ip/httpd/hints.c - 664 sys sys 1024927592 6314
@@ -9474,7 +9473,7 @@ sys/src/cmd/ip/imap4d/store.c - 664 sys sys 1066317059 1910
 sys/src/cmd/ip/imap4d/utils.c - 664 sys sys 1015013077 2481
 sys/src/cmd/ip/ipconfig.c - 664 sys sys 1071498576 34555
 sys/src/cmd/ip/measure.c - 664 sys sys 944961011 3733
-sys/src/cmd/ip/mkfile - 664 sys sys 1063897563 1250
+sys/src/cmd/ip/mkfile - 664 sys sys 1078879907 1240
 sys/src/cmd/ip/ping.c - 664 sys sys 1061496964 5552
 sys/src/cmd/ip/ppp - 20000000775 sys sys 988249980 0
 sys/src/cmd/ip/ppp/block.c - 664 sys sys 1015090266 5353
@@ -9735,10 +9734,10 @@ sys/src/cmd/mv.c - 664 sys sys 1014926695 4276
 sys/src/cmd/ndb - 20000000775 sys sys 988249988 0
 sys/src/cmd/ndb/convDNS2M.c - 664 sys sys 1060612175 6862
 sys/src/cmd/ndb/convM2DNS.c - 664 sys sys 1060612175 7248
-sys/src/cmd/ndb/cs.c - 664 sys sys 1078631715 33161
+sys/src/cmd/ndb/cs.c - 664 sys sys 1078840015 33033
 sys/src/cmd/ndb/csgetval.c - 664 sys sys 957402051 1051
 sys/src/cmd/ndb/csquery.c - 664 sys sys 1014926159 1062
-sys/src/cmd/ndb/dblookup.c - 664 sys sys 1060612175 17896
+sys/src/cmd/ndb/dblookup.c - 664 sys sys 1078840015 18019
 sys/src/cmd/ndb/dn.c - 664 sys sys 1063855019 26727
 sys/src/cmd/ndb/dnarea.c - 664 sys sys 1055701929 2126
 sys/src/cmd/ndb/dnnotify.c - 664 sys sys 1055701929 3062
@@ -9755,9 +9754,9 @@ sys/src/cmd/ndb/mkdb.c - 664 sys sys 957402054 2886
 sys/src/cmd/ndb/mkfile - 664 sys sys 1055701930 1877
 sys/src/cmd/ndb/mkhash.c - 664 sys sys 1014926160 2899
 sys/src/cmd/ndb/mkhosts.c - 664 sys sys 957402054 4294
-sys/src/cmd/ndb/query.c - 664 sys sys 957402054 1133
+sys/src/cmd/ndb/query.c - 664 sys sys 1078840016 1120
 sys/src/cmd/ndb/time.c - 664 sys sys 957402055 321
-sys/src/cmd/netstat.c - 664 sys sys 1063854991 3794
+sys/src/cmd/netstat.c - 664 sys sys 1078839959 3846
 sys/src/cmd/news.c - 664 sys sys 1014926614 3778
 sys/src/cmd/nfs.c - 664 sys sys 1050068720 31096
 sys/src/cmd/nm.c - 664 sys sys 1073313392 4912
@@ -10398,7 +10397,7 @@ sys/src/cmd/ssh/scp.c - 664 sys sys 1075130172 13886
 sys/src/cmd/ssh/smsg.c - 664 sys sys 1062091015 6135
 sys/src/cmd/ssh/ssh.c - 664 sys sys 1066515693 9667
 sys/src/cmd/ssh/ssh.h - 664 sys sys 1048179595 6054
-sys/src/cmd/ssh/sshnet.c - 664 sys sys 1062091019 17661
+sys/src/cmd/ssh/sshnet.c - 664 sys sys 1078840016 17641
 sys/src/cmd/ssh/sshserve.c - 664 sys sys 1062091020 5786
 sys/src/cmd/ssh/util.c - 664 sys sys 1063858753 4478
 sys/src/cmd/stats.c - 664 sys sys 1074086705 28191
@@ -10810,7 +10809,7 @@ sys/src/cmd/upas/common/aux.c - 664 sys sys 1019498851 2300
 sys/src/cmd/upas/common/become.c - 664 sys sys 1015009623 430
 sys/src/cmd/upas/common/common.h - 664 sys sys 1075069143 2021
 sys/src/cmd/upas/common/config.c - 664 sys sys 944961316 254
-sys/src/cmd/upas/common/libsys.c - 664 sys sys 1071334866 14459
+sys/src/cmd/upas/common/libsys.c - 664 sys sys 1078840017 14437
 sys/src/cmd/upas/common/mail.c - 664 sys sys 944961315 1346
 sys/src/cmd/upas/common/makefile - 664 sys sys 944961315 366
 sys/src/cmd/upas/common/mkfile - 664 sys sys 1075069142 273
@@ -11333,7 +11332,7 @@ sys/src/libauth/noworld.c - 664 sys sys 1014929318 779
 sys/src/libauthsrv - 20000000775 sys sys 1015091654 0
 sys/src/libauthsrv/_asgetticket.c - 664 sys sys 1015091652 280
 sys/src/libauthsrv/_asrdresp.c - 664 sys sys 1015091652 874
-sys/src/libauthsrv/authdial.c - 664 sys sys 1017166331 711
+sys/src/libauthsrv/authdial.c - 664 sys sys 1078840018 687
 sys/src/libauthsrv/convA2M.c - 664 sys sys 1015091652 501
 sys/src/libauthsrv/convM2A.c - 664 sys sys 1015091652 470
 sys/src/libauthsrv/convM2PR.c - 664 sys sys 1015091653 610
@@ -12110,7 +12109,7 @@ sys/src/libmp/power/mpvecsub.s - 664 sys sys 950104732 1118
 sys/src/libmp/power/placeholder.c - 664 sys sys 944961747 0
 sys/src/libmp/test.c - 664 sys sys 964798440 12260
 sys/src/libndb - 20000000775 sys sys 1015013466 0
-sys/src/libndb/csgetval.c - 664 sys sys 1078626122 1600
+sys/src/libndb/csgetval.c - 664 sys sys 1078839927 1752
 sys/src/libndb/csipinfo.c - 664 sys sys 1069206439 1175
 sys/src/libndb/dnsquery.c - 664 sys sys 1078618597 2840
 sys/src/libndb/ipattr.c - 664 sys sys 953844690 586
@@ -12121,12 +12120,12 @@ sys/src/libndb/ndbcat.c - 664 sys sys 950311789 224
 sys/src/libndb/ndbconcatenate.c - 664 sys sys 1078618598 259
 sys/src/libndb/ndbdiscard.c - 664 sys sys 1078618598 436
 sys/src/libndb/ndbfree.c - 664 sys sys 1078618598 952
-sys/src/libndb/ndbgetipaddr.c - 664 sys sys 1078618598 813
-sys/src/libndb/ndbgetval.c - 664 sys sys 1078626122 1160
+sys/src/libndb/ndbgetipaddr.c - 664 sys sys 1078839928 792
+sys/src/libndb/ndbgetval.c - 664 sys sys 1078839928 1309
 sys/src/libndb/ndbhash.c - 664 sys sys 1069206440 4973
 sys/src/libndb/ndbhf.h - 664 sys sys 1015013485 746
 sys/src/libndb/ndbipinfo.c - 664 sys sys 1078618599 4640
-sys/src/libndb/ndblookval.c - 664 sys sys 1078626123 981
+sys/src/libndb/ndblookval.c - 664 sys sys 1078839929 791
 sys/src/libndb/ndbopen.c - 664 sys sys 1069206441 2716
 sys/src/libndb/ndbparse.c - 664 sys sys 1069206440 1167
 sys/src/libndb/ndbreorder.c - 664 sys sys 1078618600 966

+ 26 - 0
dist/replica/plan9.log

@@ -14055,3 +14055,29 @@
 1078626641 3 c sys/src/libndb/ndbgetval.c - 664 sys sys 1078626122 1160
 1078626641 4 c sys/src/libndb/ndblookval.c - 664 sys sys 1078626123 981
 1078632040 0 c sys/src/cmd/ndb/cs.c - 664 sys sys 1078631715 33161
+1078840879 0 c 386/lib/libndb.a - 664 sys sys 1078839930 60772
+1078840879 1 c sys/include/ndb.h - 664 sys sys 1078839927 4315
+1078840879 2 c sys/man/2/ndb - 664 sys sys 1078840106 9427
+1078840879 3 c sys/src/cmd/9nfs/server.c - 664 sys sys 1078839960 10996
+1078840879 4 c sys/src/cmd/acme/elog.c - 664 sys sys 1078839859 7236
+1078840879 5 c sys/src/cmd/auth/authsrv.c - 664 sys sys 1078839960 18395
+1078840879 6 c sys/src/cmd/auth/debug.c - 664 sys sys 1078839961 7339
+1078840879 7 c sys/src/cmd/auth/secureidcheck.c - 664 sys sys 1078840013 9007
+1078840879 8 c sys/src/cmd/aux/trampoline.c - 664 sys sys 1078840013 3521
+1078840879 9 c sys/src/cmd/aux/vga/db.c - 664 sys sys 1078840016 9331
+1078840879 10 c sys/src/cmd/ip/gizzard.c - 664 sys sys 1078840014 8603
+1078840879 11 a sys/src/cmd/ip/httpd/classify.c - 664 sys sys 1078840017 9665
+1078840879 12 c sys/src/cmd/ndb/cs.c - 664 sys sys 1078840015 33033
+1078840879 13 c sys/src/cmd/ndb/dblookup.c - 664 sys sys 1078840015 18019
+1078840879 14 c sys/src/cmd/ndb/query.c - 664 sys sys 1078840016 1120
+1078840879 15 c sys/src/cmd/netstat.c - 664 sys sys 1078839959 3846
+1078840879 16 c sys/src/cmd/ssh/sshnet.c - 664 sys sys 1078840016 17641
+1078840879 17 c sys/src/cmd/upas/common/libsys.c - 664 sys sys 1078840017 14437
+1078840879 18 c sys/src/libauthsrv/authdial.c - 664 sys sys 1078840018 687
+1078840879 19 c sys/src/libndb/csgetval.c - 664 sys sys 1078839927 1752
+1078840879 20 c sys/src/libndb/ndbgetipaddr.c - 664 sys sys 1078839928 792
+1078840879 21 c sys/src/libndb/ndbgetval.c - 664 sys sys 1078839928 1309
+1078840879 22 c sys/src/libndb/ndblookval.c - 664 sys sys 1078839929 791
+1078880487 0 c sys/src/cmd/ip/mkfile - 664 sys sys 1078879907 1240
+1078880487 1 d sys/src/cmd/ip/gizzard.c - 664 sys sys 1078840014 0
+1078893089 0 d sys/src/9/boot/libboot.a8 - 664 sys sys 1074883206 0

+ 3 - 3
sys/include/ndb.h

@@ -122,7 +122,7 @@ struct Ndbs
 #define NDB_IPlen 16
 
 Ndbtuple*	csgetval(char*, char*, char*, char*, char*);
-Ndbtuple*	csgetvalue(char*, char*, char*, char*, char*, int);
+char*		csgetvalue(char*, char*, char*, char*, Ndbtuple**);
 Ndbtuple*	csipinfo(char*, char*, char*, char**, int);
 Ndbtuple*	dnsquery(char*, char*, char*);
 char*		ipattr(char*);
@@ -134,11 +134,11 @@ Ndbtuple*	ndbdiscard(Ndbtuple*, Ndbtuple*);
 void		ndbfree(Ndbtuple*);
 Ndbtuple*	ndbgetipaddr(Ndb*, char*);
 Ndbtuple*	ndbgetval(Ndb*, Ndbs*, char*, char*, char*, char*);
-Ndbtuple*	ndbgetvalue(Ndb*, Ndbs*, char*, char*, char*, char*, int);
+char*		ndbgetvalue(Ndb*, Ndbs*, char*, char*, char*, Ndbtuple**);
+Ndbtuple*	ndbfindattr(Ndbtuple*, Ndbtuple*, char*);
 ulong		ndbhash(char*, int);
 Ndbtuple*	ndbipinfo(Ndb*, char*, char*, char**, int);
 Ndbtuple*	ndblookval(Ndbtuple*, Ndbtuple*, char*, char*);
-Ndbtuple*	ndblookvalue(Ndbtuple*, Ndbtuple*, char*, char*, int);
 Ndbtuple*	ndbnew(char*, char*);
 Ndb*		ndbopen(char*);
 Ndbtuple*	ndbparse(Ndb*);

+ 17 - 22
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, ndblookvalue, dnsquery, ndbdiscard, ndbconcatenate, ndbreorder, ndbsubstitute, ndbgetval, csgetval, ndblookval \- network database
+ndbopen, ndbcat, ndbchanged, ndbclose, ndbreopen, ndbsearch, ndbsnext, ndbgetvalue, ndbfree, ipattr, ndbgetipaddr, ndbipinfo, csipinfo, ndbhash, ndbparse, csgetvalue, ndbfindattr, dnsquery, ndbdiscard, ndbconcatenate, ndbreorder, ndbsubstitute, ndbgetval, csgetval, ndblookval \- network database
 .SH SYNOPSIS
 .B #include <u.h>
 .br
@@ -33,14 +33,14 @@ Ndbtuple*	ndbsearch(Ndb *db, Ndbs *s, char *attr, char *val)
 Ndbtuple*	ndbsnext(Ndbs *s, char *attr, char *val)
 .PP
 .B
-Ndbtuple*	ndbgetvalue(Ndb *db, Ndbs *s, char *attr, char *val,
+char*	ndbgetvalue(Ndb *db, Ndbs *s, char *attr, char *val,
 .br
 .B
-		char *rattr, char *buf, int buflen)
+		char *rattr, Ndbtuple **tp)
 .PP
 .B
-Ndbtuple*	csgetvalue(char *netroot, char *attr, char *val, char *rattr,
-		char *buf, int buflen)
+char*	csgetvalue(char *netroot, char *attr, char *val, char *rattr,
+		Ndbtuple **tp)
 .PP
 .B
 char*	ipattr(char *name)
@@ -68,8 +68,7 @@ Ndbtuple*	ndbparse(Ndb *db)
 Ndbtuple*	dnsquery(char *netroot, char *domainname, char *type)
 .PP
 .B
-Ndbtuple*	ndblookvalue(Ndbtuple *entry, Ndbtuple *line, char *attr,
-		char *to, int tolen)
+Ndbtuple*	ndbfindattr(Ndbtuple *entry, Ndbtuple *line, char *attr)
 .PP
 .B
 void	ndbfree(Ndbtuple *db)
@@ -195,12 +194,14 @@ attribute/value pair,
 .IR attr = val ,
 but also a pair with the attribute
 .IR rattr .
-If successful, it copies up to
-.I buflen
-bytes of the value associated with
-.I rattr
-into
-.IR buf .
+If successful, it returns a malloced copy of the null terminated value associated with
+.IR  rattr .
+If
+.I tp
+is non nil,
+.I *tp
+will point to the entry.  Otherwise the entry will be freeed.
+.PP
 .I Csgetvalue
 is like
 .I ndbgetvalue
@@ -374,16 +375,12 @@ name servers.  Returns domain name
 and name server
 .RI ( ns )
 .PP
-.I Ndblookvalue
+.I Ndbfindattr
 searches 
 .I entry
 for the tuple
 with attribute
-.IR attr ,
-copies up to
-.I tolen
-bytes of the value into
-.IR to ,
+.I attr
 and returns a pointer to the tuple.
 If
 .I line
@@ -453,8 +450,6 @@ is freed.
 .IR ndb (6)
 .IR ndb (8)
 .SH DIAGNOSTICS
-These routines set
-.IR errstr .
 .IR Ndbgetvalue ,
 .IR csgetvalue ,
 and
@@ -462,7 +457,7 @@ and
 set
 .I errstr
 to
-.B "return value truncated"
+.B "buffer too short"
 if the buffer provided isn't long enough for the
 returned value.
 .SH BUGS

+ 7 - 9
sys/src/cmd/9nfs/server.c

@@ -473,10 +473,10 @@ addcacheentry(void *name, int len, ulong ip)
 int
 getdnsdom(ulong ip, char *name, int len)
 {
-	char buf[Ndbvlen];
-	char dom[Ndbvlen];
+	char buf[128];
+	char dom[256];
 	Namecache *nc;
-	Ndbtuple *t;
+	char *p;
 
 	if(nc=iplookup(ip)) {
 		strncpy(name, nc->dom, len);
@@ -485,14 +485,12 @@ getdnsdom(ulong ip, char *name, int len)
 	}
 	clog("getdnsdom: %I\n", ip);
 	snprint(buf, sizeof buf, "%I", ip);
-	t = csgetval("/net", "ip", buf, "dom", dom);
-clog("csgetval %p\n", t);
-	if(t == nil)
+	p = csgetvalue("/net", "ip", buf, "dom", nil);
+	if(p == nil)
 		return -1;
-	ndbfree(t);
-clog("csgetval %s\n", dom);
-	strncpy(name, dom, len-1);
+	strncpy(name, p, len-1);
 	name[len] = 0;
+	free(p);
 	addcacheentry(name, strlen(name), ip);
 	return 0;
 }

+ 1 - 1
sys/src/cmd/acme/elog.c

@@ -170,7 +170,7 @@ eloginsert(File *f, int q0, Rune *r, int nr)
 		elogflush(f);
 	}
 	/* try to merge with previous */
-	if(f->elog.type==Insert && q0==f->elog.q0 && (q0+nr)-f->elog.q0<Maxstring){
+	if(f->elog.type==Insert && q0==f->elog.q0 && f->elog.nr+nr<Maxstring){
 		runemove(f->elog.r+f->elog.nr, r, nr);
 		f->elog.nr += nr;
 		return;

+ 7 - 10
sys/src/cmd/auth/authsrv.c

@@ -339,16 +339,18 @@ static char*
 domainname(void)
 {
 	static char sysname[Maxpath];
-	static char domain[Ndbvlen];
-	Ndbtuple *t;
+	static char *domain;
 	int n;
 
-	if(*domain)
+	if(domain)
 		return domain;
-
 	if(*sysname)
 		return sysname;
 
+	domain = csgetvalue(0, "sys", sysname, "dom", nil);
+	if(domain)
+		return domain;
+
 	n = readfile("/dev/sysname", sysname, sizeof(sysname)-1);
 	if(n < 0){
 		strcpy(sysname, "kremvax");
@@ -356,12 +358,7 @@ domainname(void)
 	}
 	sysname[n] = 0;
 
-	t = csgetval(0, "sys", sysname, "dom", domain);
-	if(t == 0)
-		return sysname;
-
-	ndbfree(t);
-	return domain;
+	return sysname;
 }
 
 static int

+ 9 - 8
sys/src/cmd/auth/debug.c

@@ -143,8 +143,7 @@ void
 authdialfutz(char *dom, char *user)
 {
 	int fd;
-	Ndbtuple *nt;
-	char server[Ndbvlen];
+	char *server;
 	char *addr;
 
 	fd = authdial(nil, dom);
@@ -155,20 +154,22 @@ authdialfutz(char *dom, char *user)
 		return;
 	}
 	print("\tcannot dial auth server: %r\n");
-	nt = csgetval(nil, "authdom", dom, "auth", server);
-	if(nt){
+	server = csgetvalue(nil, "authdom", dom, "auth", nil);
+	if(server){
 		print("\tcsquery authdom=%q auth=%s\n", dom, server);
+		free(server);
 		return;
 	}
 	print("\tcsquery authdom=%q auth=* failed\n", dom);
-	nt = csgetval(nil, "dom", dom, "auth", server);
-	if(nt){
+	server = csgetvalue(nil, "dom", dom, "auth", nil);
+	if(server){
 		print("\tcsquery dom=%q auth=%q\n", dom, server);
+		free(server);
 		return;
 	}
-	print("\tcsquery dom=%q auth=%q\n", dom, server);
+	print("\tcsquery dom=%q auth=*\n", dom);
 
-	fd = dial(addr=netmkaddr(server, nil, "ticket"), 0, 0, 0);
+	fd = dial(addr=netmkaddr("$auth", nil, "ticket"), 0, 0, 0);
 	if(fd >= 0){
 		print("\tdial %s succeeded\n", addr);
 		close(fd);

+ 5 - 5
sys/src/cmd/auth/secureidcheck.c

@@ -333,8 +333,8 @@ secureidcheck(char *user, char *response)
 	Packet *req = nil, *resp = nil;
 	ulong u[4];
 	uchar x[16];
-	char radiussecret[Ndbvlen];
-	char ruser[Ndbvlen];
+	char *radiussecret;
+	char ruser[ 64];
 	char dest[3*IPaddrlen+20];
 	Secret shared, pass;
 	char *rv = "authentication failed";
@@ -351,8 +351,8 @@ secureidcheck(char *user, char *response)
 		goto out;
 
 	/* get radius secret */
-	t = ndbgetval(db, &s, "radius", "lra-radius", "secret", radiussecret);
-	if(t == nil){
+	radiussecret = ndbgetvalue(db, &s, "radius", "lra-radius", "secret", &t);
+	if(radiussecret == nil){
 		syslog(0, AUTHLOG, "secureidcheck: nil radius secret: %r");
 		goto out;
 	}
@@ -437,7 +437,7 @@ secureidcheck(char *user, char *response)
 		break; // we have a proper reply, no need to ask again
 	}
 	ndbfree(t);
-
+	free(radiussecret);
 out:
 	freePacket(req);
 	freePacket(resp);

+ 3 - 8
sys/src/cmd/aux/trampoline.c

@@ -212,15 +212,10 @@ iptomac(char *ip, char *net)
 int
 macok(char *mac)
 {
-	Ndbtuple *tp;
-	char buf[Ndbvlen];
+	char *p;
 
 	if(mac == nil)
 		return 0;
-	tp = csgetval("/net", "ether", mac, "trampok", buf);
-	if(tp == nil)
-		return 0;
-	ndbfree(tp);
-	return 1;
+	free(p = csgetvalue("/net", "ether", mac, "trampok", nil));
+	return !(p == nil);
 }
-

+ 4 - 4
sys/src/cmd/aux/vga/db.c

@@ -227,7 +227,7 @@ dbmonitor(Ndb* db, Mode* mode, char* type, char* size)
 {
 	Ndbs s;
 	Ndbtuple *t, *tuple;
-	char *p, attr[Namelen+1], val[Namelen+1], buf[2*Namelen+1], vbuf[Ndbvlen];
+	char *p, attr[Namelen+1], val[Namelen+1], buf[2*Namelen+1];
 	int clock, x;
 
 	/*
@@ -253,9 +253,9 @@ dbmonitor(Ndb* db, Mode* mode, char* type, char* size)
 	strcpy(attr, type);
 	strcpy(val, buf);
 
-	if(t=ndbgetval(db, &s, attr, "", "videobw", vbuf)){
-		ndbfree(t);
-		mode->videobw = atol(vbuf)*1000000UL;
+	if(p = ndbgetvalue(db, &s, attr, "", "videobw", nil)){
+		mode->videobw = atol(p)*1000000UL;
+		free(p);
 	}
 
 	if(mode->x == 0 && ((mode->x = strtol(val, &p, 0)) == 0 || *p++ != 'x'))

+ 0 - 467
sys/src/cmd/ip/gizzard.c

@@ -1,467 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <ctype.h>
-#include <bio.h>
-#include <ndb.h>
-#include <ip.h>
-
-Biobuf in;
-
-void
-usage(void)
-{
-	fprint(2, "usage: %s [-x netroot]\n", argv0);
-	exits("usage");
-}
-
-char *vec[] =
-{
-	"ip",
-	"ipmask",
-	"dns",
-	"dom",
-	"auth",
-	"authdom",
-	"fs",
-	"sys",
-	"ipgw",
-	"ntp",
-};
-
-char *outvec[] =
-{
-	"ipgw",
-	"dns",
-	"auth",
-	"fs",
-	"ntp",
-	0
-};
-
-enum
-{
-	Tnone,
-	Tip,
-	Tdom,
-	Tmask,
-	Tstring,
-};
-
-typedef struct Attribute Attribute;
-typedef void (Helper)(Attribute*);
-
-struct Attribute
-{
-	char *attr;
-	char *desc;
-	int type;
-	int multiple;
-	Helper *helper;
-};
-
-Helper authdomhelper, authhelper, fshelper;
-
-Attribute expl[] =
-{
-	{ "ip", "ip address on this interface", Tip, 0, nil },
-	{ "ipmask", "ip mask on this interface", Tmask, 0, nil },
-	{ "dns", "domain name server", Tdom, 1, nil },
-	{ "dom", "domain name", Tdom, 0, nil },
-	{ "auth", "authentication server", Tdom, 0, authhelper },
-	{ "authdom", "authentication domain", Tstring, 0, authdomhelper },
-	{ "fs", "file server", Tdom, 0, fshelper },
-	{ "sys", "your system name", Tstring, 0, nil },
-	{ "ipgw", "ip gateway on this network", 0, nil },
-	{ "ntp", "network time server", Tdom, 0, nil },
-	{ 0 },
-};
-
-char *authserver;
-
-Ndbtuple*
-find(char *attr, Ndbtuple *t1, Ndbtuple *t2, Ndbtuple *t3)
-{
-	for(; t1; t1 = t1->entry)
-		if(strcmp(attr, t1->attr) == 0)
-			return t1;
-	for(; t2; t2 = t2->entry)
-		if(strcmp(attr, t2->attr) == 0)
-			return t2;
-	for(; t3; t3 = t3->entry)
-		if(strcmp(attr, t3->attr) == 0)
-			return t3;
-	return nil;
-}
-
-Ndbtuple*
-findnext(Ndbtuple *t, char *attr, Ndbtuple *t1, Ndbtuple *t2, Ndbtuple *t3)
-{
-	if(t == nil)
-		return find(attr, t1, t2, t3);
-	for(; t1; t1 = t1->entry)
-		if(t1 == t)
-			return find(attr, t->entry, t2, t3);
-	for(; t2; t2 = t2->entry)
-		if(t2 == t)
-			return find(attr, t->entry, t3, nil);
-	for(; t3; t3 = t3->entry)
-		if(t3 == t)
-			return find(attr, t->entry, nil, nil);
-	return nil;
-}
-
-Ndbtuple*
-newtuple(char *attr, char *val)
-{
-	Ndbtuple *nt;
-
-	nt = malloc(sizeof *nt);
-	nt->entry = nt->line = nil;
-	strncpy(nt->attr, attr, Ndbalen-1);
-	nt->attr[Ndbalen-1] = 0;
-	strncpy(nt->val, val, Ndbvlen-1);
-	nt->attr[Ndbvlen-1] = 0;
-	return nt;
-}
-
-Ndbtuple*
-duptuple(Ndbtuple *t)
-{
-	Ndbtuple *nt;
-
-	nt = malloc(sizeof *nt);
-	nt->entry = nt->line = nil;
-	strcpy(nt->val, t->val);
-	strcpy(nt->attr, t->attr);
-	return nt;
-}
-
-Ndbtuple*
-concat(Ndbtuple *t1, Ndbtuple *t2)
-{
-	Ndbtuple *t;
-
-	if(t1 == nil)
-		return t2;
-	if(t2 == nil)
-		return t1;
-
-	t = t1;
-	for(; t1->entry != nil; t1 = t1->entry)
-		;
-	t1->entry = t1->line = t2;
-	return t;
-}
-
-void
-removetuple(Ndbtuple **l, Ndbtuple *nt)
-{
-	Ndbtuple *t;
-
-	while(*l != nil){
-		t = *l;
-		if(strcmp(t->attr, nt->attr) == 0
-		&& strcmp(t->val, nt->val) == 0){
-			*l = t->entry;
-			free(t);
-		} else
-			l = &t->entry;
-	}
-}
-
-void
-help(Attribute *e)
-{
-	if(e->helper){
-		print("--------------------------------\n");
-		(*e->helper)(e);
-		print("--------------------------------\n");
-	}
-}
-
-Ndbtuple*
-need(int must, char *attr)
-{
-	char *p;
-	uchar ip[IPaddrlen];
-	int i;
-	Attribute *e;
-	Ndbtuple *first, **l, *t;
-
-	e = nil;
-	for(i = 0; expl[i].attr != nil; i++){
-		if(strcmp(expl[i].attr, attr) == 0){
-			e = &expl[i];
-			break;
-		}
-	}
-	if(e == nil)
-		return nil;
-
-	first = nil;
-	l = &first;
-	for(;;){
-		if(first != nil)
-			must = 0;
-		print("Enter%s %s (type ? for help%s)? ", first!=nil ? " another" : "",
-			e->desc, must!=0 ? "" : ", return to skip");
-
-		p = Brdline(&in, '\n');
-		p[Blinelen(&in)-1] = 0;
-		while(*p == ' ' || *p == '\t')
-			p++;
-
-		if(*p == '?'){
-			help(e);
-			continue;
-		}
-
-		if(*p == 0){
-			if(must)
-				continue;
-			else
-				break;
-		}
-		t = nil;
-		switch(e->type){
-		case Tip:
-			parseip(ip, p);
-			if(ipcmp(ip, IPnoaddr) == 0){
-				print("!not an IP address\n");
-				break;
-			}
-			t = newtuple(attr, p);
-			break;
-		case Tdom:
-			if(strchr(p, '.') == nil && strchr(p, ':') == nil){
-				print("!not an IP address or domain name\n");
-				break;
-			}
-			t = newtuple(attr, p);
-			break;
-		case Tmask:
-			parseipmask(ip, p);
-			if(ipcmp(ip, IPnoaddr) == 0){
-				print("!not an IP mask\n");
-				break;
-			}
-			t = newtuple(attr, p);
-			break;
-		case Tstring:
-			if(strchr(p, ' ')){
-				print("!the string cannot contain spaces\n");
-				break;
-			}
-			t = newtuple(attr, p);
-			break;
-		}
-		if(t != nil){
-			*l = t;
-			l = &t->entry;
-		}
-	}
-
-	return first;	
-}
-
-void
-printnet(Ndbtuple *ndb, Ndbtuple *local, Ndbtuple *added)
-{
-	uchar ip[IPaddrlen];
-	uchar mask[IPaddrlen];
-	uchar net[IPaddrlen];
-	Ndbtuple *t;
-	char **l;
-
-	/* some little calculations */
-	t = find("ip", ndb, local, added);
-	if(t == nil)
-		return;
-	parseip(ip, t->val);
-	t = find("ipmask", ndb, local, added);
-	if(t != nil)
-		parseipmask(mask, t->val);
-	else
-		ipmove(mask, defmask(ip));
-	maskip(ip, mask, net);
-
-	/* print out a sample network database */
-	print("ipnet=mynet ip=%I ipmask=%M\n", net, mask);
-	for(l = outvec; *l; l++){
-		t = nil;
-		while((t = findnext(t, *l, added, ndb, local)) != nil)
-			print("	%s=%s\n", t->attr, t->val);
-	}
-}
-
-void
-printauthdom(Ndbtuple *ndb, Ndbtuple *local, Ndbtuple *added)
-{
-	Ndbtuple *t, *nt;
-
-	t = find("authdom", ndb, local, added);
-	if(t == nil)
-		return;
-	nt = nil;
-	print("authdom=%s\n", t->val);
-	while((nt = findnext(nt, "auth", ndb, local, added)) != nil)
-		print("\tauth=%s\n", nt->val);
-}
-
-void
-printhost(Ndbtuple *added)
-{
-	uchar ip[IPaddrlen];
-	Ndbtuple *t;
-	char **l;
-
-	t = find("ip", added, nil, nil);
-	if(t == nil)
-		return;
-	parseip(ip, t->val);
-	print("ip=%I\n", ip);
-	for(l = outvec; *l; l++){
-		t = nil;
-		while((t = findnext(t, *l, added, nil, nil)) != nil)
-			print("	%s=%s\n", t->attr, t->val);
-	}
-}
-
-void
-main(int argc, char **argv)
-{
-	Ndbs s;
-	char *net;
-	char ndbfile[128];
-	char authdomval[Ndbvlen];
-	Ndb *db, *netdb;
-	Ndbtuple *ndb, *local, *added, *nt, *t, *xt;
-
-	fmtinstall('I', eipfmt);
-	fmtinstall('M', eipfmt);
-
-	db = ndbopen("/lib/ndb/local");
-	Binit(&in, 0, OREAD);
-
-	net = "/net";
-	ARGBEGIN {
-	case 'x':
-		net = ARGF();
-		if(net == nil)
-			usage();
-		break;
-	} ARGEND;
-
-	/* see what ipconfig knows */
-	snprint(ndbfile, sizeof ndbfile, "%s/ndb", net);
-	netdb = ndbopen(ndbfile);
-	ndb = ndbparse(netdb);
-	added = nil;
-
-	/* ask user for ip address */
-	t = find("ip", ndb, added, nil);
-	if(t == nil){
-		t = need(1, "ip");
-		added = concat(added, t);
-	}
-	if(t == nil)
-		sysfatal("cannot continue without your ip address");
-
-	/* see what the database knows */
-	local = ndbipinfo(db, "ip", t->val, vec, nelem(vec));
-
-	/* get hostname */
-	t = find("sys", ndb, local, added);
-	if(t == nil){
-		t = need(1, "sys");
-		added = concat(added, t);
-	}
-
-	/* get auth server */
-	t = find("auth", ndb, local, added);
-	if(t == nil){
-		t = need(0, "auth");
-		added = concat(added, t);
-	}
-	if(t != nil){
-		authserver = t->val;
-		xt = ndbgetval(db, &s, "auth", t->val, "authdom", authdomval);
-		for(nt = find("authdom", xt, nil, nil); nt != nil;
-		    nt = find("authdom", nt->entry, nil, nil))
-			local = concat(local, duptuple(nt));
-		ndbfree(xt);
-		if(xt == nil){
-			t = need(1, "authdom");
-			added = concat(added, t);
-		}
-	}
-
-	/* look for things we need */
-	if(find("ipmask", added, ndb, local) == nil){
-		t = need(0, "ipmask");
-		added = concat(added, t);
-	}
-	if(find("dns", added, ndb, local) == nil){
-		t = need(0, "dns");
-		added = concat(added, t);
-	}
-	if(find("ntp", added, ndb, local) == nil){
-		t = need(0, "ntp");
-		added = concat(added, t);
-	}
-	if(find("fs", added, ndb, local) == nil){
-		t = need(0, "fs");
-		added = concat(added, t);
-	}
-
-	/* remove redundancy */
-	for(t = local; t != nil; t = t->entry)
-		removetuple(&ndb, t);
-
-	print("======================================\n");
-	print("recomended additions to /lib/ndb/local\n");
-	print("======================================\n");
-
-	if(added != nil)
-		printnet(ndb, local, added);
-	printauthdom(ndb, local, added);
-	printhost(added);
-
-	exits(0);
-}
-
-void
-authentication(void)
-{
-	print("\tPlan 9 systems that accept connections from other Plan 9\n");
-	print("\tsystems need to authenticate to each other.  A set of secrets\n");
-	print("\tand authentication servers to validate those secrets is\n");
-	print("\tidentified by a string called an 'authentication domain'.\n");
-	print("\tIf you expect anyone to 'cpu' to or 'import' from your machine,\n");
-	print("\tyour machine must know its authentication domain and the\n");
-	print("\tauthentication server(s) that validate keys for it.\n");
-}
-
-void
-authdomhelper(Attribute *)
-{
-	authentication();
-	print("\n\tEnter the authentication domain that is served by the\n");
-	print("\tauthentication server '%s'.\n", authserver);
-}
-
-void
-authhelper(Attribute *)
-{
-	authentication();
-	print("\n\tEnter the name or address of the default authentication server\n");
-	print("\tto be used by this system.\n");
-}
-
-void
-fshelper(Attribute *)
-{
-	print("\tThis is only important if you are going to run diskless from\n");
-	print("\ta remote server, i.e., if you wish to answer 'il' or 'tcp' to the\n");
-	print("\t'root is from:' boot prompt.\n");
-}

+ 427 - 0
sys/src/cmd/ip/httpd/classify.c

@@ -0,0 +1,427 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <ndb.h>
+#include "whois.h"
+
+typedef struct Country Country;
+
+struct Country
+{
+	char *code;
+	char *name;
+};
+
+Country badc[] =
+{
+	{"af", "afghanistan"},
+	{"cu", "cuba"},
+	{"ir", "iran"},
+	{"iq", "iraq"},
+	{"ly", "libya"},
+	{"kp", "north korea"},
+	{"sd", "sudan"},
+	{"sy", "syria"},
+	{ 0, 0 }
+};
+
+Country goodc[] =
+{
+	// the original, us and canada
+	{"us", "united states of america"},
+	{"ca", "canada"},
+	{"gov", "gov"},
+	{"mil", "mil"},
+
+	// the european union
+	{ "eu",	"european union" },
+	{ "be",	"belgium" },
+	{ "de",	"germany" },
+	{ "fr",	"france" },
+	{ "it",	"italy" },
+	{ "lu",	"luxembourg" },
+	{ "nl",	"netherlands" },
+	{ "dk",	"denmark" },
+	{ "ie",	"ireland" },
+	{ "gb",	"great britain" },
+	{ "uk",	"united kingdom" },
+	{ "gr",	"greece" },
+	{ "es",	"spain" },
+	{ "pt",	"portugal" },
+	{ "au",	"australia" },
+	{ "fi",	"finland" },
+	{ "se",	"sweden" },
+
+	// the rest
+	{"au", "australia"},
+	{"no", "norway"},
+	{"cz", "czech republic"},
+	{"hu", "hungary"},
+	{"pl", "poland"},
+	{"jp", "japan"},
+	{"ch", "switzerland"},
+	{"nz", "new zealand"},
+	{ 0, 0 }
+};
+
+char *gov[] =
+{
+	"gov",
+	"gouv",
+	"mil",
+	"government",
+	0,
+};
+
+Country allc[] =
+{
+	{ "ad",	"andorra" },
+	{ "ae",	"united arab emirates" },
+	{ "af",	"afghanistan" },
+	{ "ag",	"antigua and barbuda" },
+	{ "ai",	"anguilla" },
+	{ "al",	"albania" },
+	{ "am",	"armenia" },
+	{ "an",	"netherlands antilles" },
+	{ "ao",	"angola" },
+	{ "aq",	"antarctica" },
+	{ "ar",	"argentina" },
+	{ "as",	"american samoa" },
+	{ "at",	"austria" },
+	{ "au",	"australia" },
+	{ "aw",	"aruba" },
+	{ "az",	"azerbaijan" },
+	{ "ba",	"bosnia and herzegovina" },
+	{ "bb",	"barbados" },
+	{ "bd",	"bangladesh" },
+	{ "be",	"belgium" },
+	{ "bf",	"burkina faso" },
+	{ "bg",	"bulgaria" },
+	{ "bh",	"bahrain" },
+	{ "bi",	"burundi" },
+	{ "bj",	"benin" },
+	{ "bm",	"bermuda" },
+	{ "bn",	"brunei darussalam" },
+	{ "bo",	"bolivia" },
+	{ "br",	"brazil" },
+	{ "bs",	"bahamas" },
+	{ "bt",	"bhutan" },
+	{ "bu",	"burma" },
+	{ "bv",	"bouvet island" },
+	{ "bw",	"botswana" },
+	{ "by",	"belarus" },
+	{ "bz",	"belize" },
+	{ "ca",	"canada" },
+	{ "cc",	"cocos (keeling) islands" },
+	{ "cf",	"central african republic" },
+	{ "cg",	"congo" },
+	{ "ch",	"switzerland" },
+	{ "ci",	"cote d'ivoire (ivory coast)" },
+	{ "ck",	"cook islands" },
+	{ "cl",	"chile" },
+	{ "cm",	"cameroon" },
+	{ "cn",	"china" },
+	{ "co",	"colombia" },
+	{ "cr",	"costa rica" },
+	{ "cs",	"czechoslovakia (former)" },
+	{ "ct",	"canton and enderbury island" },
+	{ "cu",	"cuba" },
+	{ "cv",	"cape verde" },
+	{ "cx",	"christmas island" },
+	{ "cy",	"cyprus" },
+	{ "cz",	"czech republic" },
+	{ "dd",	"german democratic republic" },
+	{ "de",	"germany" },
+	{ "dj",	"djibouti" },
+	{ "dk",	"denmark" },
+	{ "dm",	"dominica" },
+	{ "do",	"dominican republic" },
+	{ "dz",	"algeria" },
+	{ "ec",	"ecuador" },
+	{ "ee",	"estonia" },
+	{ "eg",	"egypt" },
+	{ "eh",	"western sahara" },
+	{ "er",	"eritrea" },
+	{ "es",	"spain" },
+	{ "et",	"ethiopia" },
+	{ "eu",	"european union" },
+	{ "fi",	"finland" },
+	{ "fj",	"fiji" },
+	{ "fk",	"falkland islands (malvinas)" },
+	{ "fm",	"micronesia" },
+	{ "fo",	"faroe islands" },
+	{ "fr",	"france" },
+	{ "fx",	"france, metropolitan" },
+	{ "ga",	"gabon" },
+	{ "gb",	"great britain (uk)" },
+	{ "gd",	"grenada" },
+	{ "ge",	"georgia" },
+	{ "gf",	"french guiana" },
+	{ "gh",	"ghana" },
+	{ "gi",	"gibraltar" },
+	{ "gl",	"greenland" },
+	{ "gm",	"gambia" },
+	{ "gn",	"guinea" },
+	{ "gp",	"guadeloupe" },
+	{ "gq",	"equatorial guinea" },
+	{ "gr",	"greece" },
+	{ "gs",	"s. georgia and s. sandwich isls." },
+	{ "gt",	"guatemala" },
+	{ "gu",	"guam" },
+	{ "gw",	"guinea-bissau" },
+	{ "gy",	"guyana" },
+	{ "hk",	"hong kong" },
+	{ "hm",	"heard and mcdonald islands" },
+	{ "hn",	"honduras" },
+	{ "hr",	"croatia (hrvatska)" },
+	{ "ht",	"haiti" },
+	{ "hu",	"hungary" },
+	{ "id",	"indonesia" },
+	{ "ie",	"ireland" },
+	{ "il",	"israel" },
+	{ "in",	"india" },
+	{ "io",	"british indian ocean territory" },
+	{ "iq",	"iraq" },
+	{ "ir",	"iran" },
+	{ "is",	"iceland" },
+	{ "it",	"italy" },
+	{ "jm",	"jamaica" },
+	{ "jo",	"jordan" },
+	{ "jp",	"japan" },
+	{ "jt",	"johnston island" },
+	{ "ke",	"kenya" },
+	{ "kg",	"kyrgyzstan" },
+	{ "kh",	"cambodia (democratic kampuchea)" },
+	{ "ki",	"kiribati" },
+	{ "km",	"comoros" },
+	{ "kn",	"saint kitts and nevis" },
+	{ "kp",	"korea (north)" },
+	{ "kr",	"korea (south)" },
+	{ "kw",	"kuwait" },
+	{ "ky",	"cayman islands" },
+	{ "kz",	"kazakhstan" },
+	{ "la",	"laos" },
+	{ "lb",	"lebanon" },
+	{ "lc",	"saint lucia" },
+	{ "li",	"liechtenstein" },
+	{ "lk",	"sri lanka" },
+	{ "lr",	"liberia" },
+	{ "ls",	"lesotho" },
+	{ "lt",	"lithuania" },
+	{ "lu",	"luxembourg" },
+	{ "lv",	"latvia" },
+	{ "ly",	"libya" },
+	{ "ma",	"morocco" },
+	{ "mc",	"monaco" },
+	{ "md",	"moldova" },
+	{ "mg",	"madagascar" },
+	{ "mh",	"marshall islands" },
+	{ "mi",	"midway islands" },
+	{ "mk",	"macedonia" },
+	{ "ml",	"mali" },
+	{ "mm",	"myanmar" },
+	{ "mn",	"mongolia" },
+	{ "mo",	"macau" },
+	{ "mp",	"northern mariana islands" },
+	{ "mq",	"martinique" },
+	{ "mr",	"mauritania" },
+	{ "ms",	"montserrat" },
+	{ "mt",	"malta" },
+	{ "mu",	"mauritius" },
+	{ "mv",	"maldives" },
+	{ "mw",	"malawi" },
+	{ "mx",	"mexico" },
+	{ "my",	"malaysia" },
+	{ "mz",	"mozambique" },
+	{ "na",	"namibia" },
+	{ "nc",	"new caledonia" },
+	{ "ne",	"niger" },
+	{ "nf",	"norfolk island" },
+	{ "ng",	"nigeria" },
+	{ "ni",	"nicaragua" },
+	{ "nl",	"netherlands" },
+	{ "no",	"norway" },
+	{ "np",	"nepal" },
+	{ "nq",	"dronning maud land" },
+	{ "nr",	"nauru" },
+	{ "nt",	"neutral zone" },
+	{ "nu",	"niue" },
+	{ "nz",	"new zealand (aotearoa)" },
+	{ "om",	"oman" },
+	{ "pa",	"panama" },
+	{ "pc",	"pacific islands" },
+	{ "pe",	"peru" },
+	{ "pf",	"french polynesia" },
+	{ "pg",	"papua new guinea" },
+	{ "ph",	"philippines" },
+	{ "pk",	"pakistan" },
+	{ "pl",	"poland" },
+	{ "pm",	"st. pierre and miquelon" },
+	{ "pn",	"pitcairn" },
+	{ "pr",	"puerto rico" },
+	{ "pu",	"united states misc. pacific islands" },
+	{ "pt",	"portugal" },
+	{ "pw",	"palau" },
+	{ "py",	"paraguay" },
+	{ "qa",	"qatar" },
+	{ "re",	"reunion" },
+	{ "ro",	"romania" },
+	{ "ru",	"russian federation" },
+	{ "rw",	"rwanda" },
+	{ "sa",	"saudi arabia" },
+	{ "sb",	"solomon islands" },
+	{ "sc",	"seychelles" },
+	{ "sd",	"sudan" },
+	{ "se",	"sweden" },
+	{ "sg",	"singapore" },
+	{ "sh",	"st. helena" },
+	{ "si",	"slovenia" },
+	{ "sj",	"svalbard and jan mayen islands" },
+	{ "sk",	"slovak republic" },
+	{ "sl",	"sierra leone" },
+	{ "sm",	"san marino" },
+	{ "sn",	"senegal" },
+	{ "so",	"somalia" },
+	{ "sr",	"suriname" },
+	{ "st",	"sao tome and principe" },
+	{ "su",	"ussr (former)" },
+	{ "sv",	"el salvador" },
+	{ "sy",	"syria" },
+	{ "sz",	"swaziland" },
+	{ "tc",	"turks and caicos islands" },
+	{ "td",	"chad" },
+	{ "tf",	"french southern territories" },
+	{ "tg",	"togo" },
+	{ "th",	"thailand" },
+	{ "tj",	"tajikistan" },
+	{ "tk",	"tokelau" },
+	{ "tm",	"turkmenistan" },
+	{ "tn",	"tunisia" },
+	{ "to",	"tonga" },
+	{ "tp",	"east timor" },
+	{ "tr",	"turkey" },
+	{ "tt",	"trinidad and tobago" },
+	{ "tv",	"tuvalu" },
+	{ "tw",	"taiwan" },
+	{ "tz",	"tanzania" },
+	{ "ua",	"ukraine" },
+	{ "ug",	"uganda" },
+	{ "uk",	"united kingdom" },
+	{ "um",	"us minor outlying islands" },
+	{ "us",	"united states" },
+	{ "uy",	"uruguay" },
+	{ "uz",	"uzbekistan" },
+	{ "va",	"vatican city state (holy see)" },
+	{ "vc",	"saint vincent and the grenadines" },
+	{ "ve",	"venezuela" },
+	{ "vg",	"virgin islands (british)" },
+	{ "vi",	"virgin islands (u.s.)" },
+	{ "vn",	"viet nam" },
+	{ "vu",	"vanuatu" },
+	{ "wf",	"wallis and futuna islands" },
+	{ "wk",	"wake island" },
+	{ "ws",	"samoa" },
+	{ "yd",	"democratic yemen" },
+	{ "ye",	"yemen" },
+	{ "yt",	"mayotte" },
+	{ "yu",	"yugoslavia" },
+	{ "za",	"south africa" },
+	{ "zm",	"zambia" },
+	{ "zr",	"zaire" },
+	{ "zw",	"zimbabwe" },
+
+	{"gov", "gov"},
+	{"mil", "mil"},
+
+	{ 0, 0 }
+};
+
+int classdebug;
+
+static int
+incountries(char *s, Country *cp)
+{
+	for(; cp->code != 0; cp++)
+		if(cistrcmp(s, cp->code) == 0
+		|| cistrcmp(s, cp->name) == 0)
+			return 1;
+	return 0;
+}
+
+static int
+indomains(char *s, char **dp)
+{
+	for(; *dp != nil; dp++)
+		if(cistrcmp(s, *dp) == 0)
+			return 1;
+
+	return 0;
+}
+
+int
+classify(char *ip, Ndbtuple *t)
+{
+	int isgov, iscountry, isbadc, isgoodc;
+	char dom[256];
+	char *df[128];
+	Ndbtuple *nt, *x;
+	int n;
+
+	isgov = iscountry = isbadc = 0;
+	isgoodc = 1;
+	
+	for(nt = t; nt != nil; nt = nt->entry){
+		if(strcmp(nt->attr, "country") == 0){
+			iscountry = 1;
+			if(incountries(nt->val, badc)){
+				if(classdebug)fprint(2, "isbadc\n");
+				isbadc = 1;
+				isgoodc = 0;
+			} else if(!incountries(nt->val, goodc)){
+				if(classdebug)fprint(2, "!isgoodc\n");
+				isgoodc = 0;
+			}
+		}
+
+		/* domain names can always hurt, even without forward verification */
+		if(strcmp(nt->attr, "dom") == 0){
+			strncpy(dom, nt->val, sizeof dom);
+			dom[sizeof(dom)-1] = 0;
+			n = getfields(dom, df, nelem(df), 0, ".");
+
+			/* a bad country in a domain name is always believed */
+			if(incountries(df[n-1], badc)){
+				if(classdebug)fprint(2, "isbadc dom\n");
+				isbadc = 1;
+				isgoodc = 0;
+			}
+
+			/* a goverment in a domain name is always believed */
+			if(n > 1 && indomains(df[n-2], gov))
+				isgov = 1;
+		}
+	}
+	if(iscountry == 0){
+		/* did the forward lookup work? */
+		for(nt = t; nt != nil; nt = nt->entry){
+			if(strcmp(nt->attr, "ip") == 0 && strcmp(nt->val, ip) == 0)
+				break;
+		}
+
+		/* see if the domain name ends in a country code */
+		if(nt != nil && (x = ndbfindattr(t, nt, "dom")) != nil){
+			strncpy(dom, x->val, sizeof dom);
+			dom[sizeof(dom)-1] = 0;
+			n = getfields(dom, df, nelem(df), 0, ".");
+			if(incountries(df[n-1], allc))
+				iscountry = 1;
+		}
+	}
+	if(iscountry == 0)
+		return Cunknown;
+	if(isbadc)
+		return Cbadc;
+	if(!isgoodc && isgov)
+		return Cbadgov;
+	return Cok;
+}

+ 0 - 1
sys/src/cmd/ip/mkfile

@@ -2,7 +2,6 @@
 
 TARG = 	dhcpclient\
 	ftpd\
-	gizzard\
 	gping\
 	hogports\
 	ipconfig\

+ 13 - 15
sys/src/cmd/ndb/cs.c

@@ -1006,14 +1006,13 @@ ipid(void)
 		if(mysysname == 0){
 			t = nil;
 			if(isvalidip(ipa))
-				t = ndbgetvalue(db, &s, "ip", ipaddr, "sys", nil, 0);
+				free(ndbgetvalue(db, &s, "ip", ipaddr, "sys", &t));
 			if(t == nil){
 				for(f = 0; f < 3; f++){
 					snprint(buf, sizeof buf, "%s/ether%d", mntpt, f);
 					if(myetheraddr(addr, buf) >= 0){
 						snprint(eaddr, sizeof(eaddr), "%E", addr);
-						t = ndbgetvalue(db, &s, "ether", eaddr, "sys",
-							nil, 0);
+						free(ndbgetvalue(db, &s, "ether", eaddr, "sys", &t));
 						if(t != nil)
 							break;
 					}
@@ -1271,19 +1270,18 @@ ipserv(Network *np, char *name, char *buf, int blen)
 		else 
 			return 0;
 	}
+	t = nil;
+	p = nil;
 	if(alpha){
-		t = ndbgetvalue(db, &s, np->net, name, "port", port, sizeof(port));
-		if(t == 0)
-			return 0;
+		p = ndbgetvalue(db, &s, np->net, name, "port", &t);
 	} else {
 		/* look up only for tcp ports < 1024 to get the restricted
 		 * attribute
 		 */
-		t = nil;
 		if(atoi(name) < 1024 && strcmp(np->net, "tcp") == 0)
-			t = ndbgetvalue(db, &s, "port", name, "port", port, sizeof(port));
-		if(t == nil)
-			nstrcpy(port, name, sizeof(port));
+			p = ndbgetvalue(db, &s, "port", name, "port", &t);
+		if(p == nil)
+			p = strdup(name);
 	}
 
 	if(t){
@@ -1292,7 +1290,9 @@ ipserv(Network *np, char *name, char *buf, int blen)
 				restr = 1;
 		ndbfree(t);
 	}
-	snprint(buf, blen, "%s%s", port, restr ? "!r" : ""); 
+	snprint(buf, blen, "%s%s", p, restr ? "!r" : "");
+	free(p);
+
 	return buf;
 }
 
@@ -1333,7 +1333,6 @@ iplookup(Network *np, char *host, char *serv, int nolookup)
 	Ndbtuple *t, *nt;
 	Ndbs s;
 	char ts[Maxservice];
-	char th[Maxhost];
 	char dollar[Maxhost];
 	uchar ip[IPaddrlen];
 	uchar net[IPaddrlen];
@@ -1396,7 +1395,7 @@ iplookup(Network *np, char *host, char *serv, int nolookup)
 	if(strcmp(attr, "dom") == 0)
 		t = dnsiplookup(host, &s);
 	if(t == 0)
-		t = ndbgetvalue(db, &s, attr, host, "ip", th, sizeof(th));
+		free(ndbgetvalue(db, &s, attr, host, "ip", &t));
 	if(t == 0)
 		t = dnsiplookup(host, &s);
 	if(t == 0)
@@ -1473,12 +1472,11 @@ telcolookup(Network *np, char *host, char *serv, int nolookup)
 {
 	Ndbtuple *t;
 	Ndbs s;
-	char th[Maxhost];
 
 	USED(np, nolookup, serv);
 
 	werrstr("can't translate address");
-	t = ndbgetvalue(db, &s, "sys", host, "telco", th, sizeof(th));
+	free(ndbgetvalue(db, &s, "sys", host, "telco", &t));
 	if(t == 0)
 		return ndbnew("telco", host);
 

+ 13 - 6
sys/src/cmd/ndb/dblookup.c

@@ -33,6 +33,13 @@ static int	implemented[Tall] =
 	[Ttxt]		1,
 };
 
+static void
+nstrcpy(char *to, char *from, int len)
+{
+	strncpy(to, from, len);
+	to[len-1] = 0;
+}
+
 int
 opendatabase(void)
 {
@@ -153,7 +160,7 @@ dblookup1(char *name, int type, int auth, int ttl)
 	Ndbtuple *t, *nt;
 	RR *rp, *list, **l;
 	Ndbs s;
-	char val[Ndbvlen], dname[Ndbvlen];
+	char dname[Domlen];
 	char *attr;
 	DN *dp;
 	RR *(*f)(Ndbtuple*, Ndbtuple*);
@@ -199,21 +206,21 @@ dblookup1(char *name, int type, int auth, int ttl)
 	/*
 	 *  find a matching entry in the database
 	 */
-	t = ndbgetval(db, &s, "dom", name, attr, val);
+	free(ndbgetvalue(db, &s, "dom", name, attr, &t));
 
 	/*
 	 *  hack for local names
 	 */
 	if(t == 0 && strchr(name, '.') == 0)
-		t = ndbgetval(db, &s, "sys", name, attr, val);
+		free(ndbgetvalue(db, &s, "sys", name, attr, &t));
 	if(t == 0)
 		return nil;
 
 	/* search whole entry for default domain name */
-	strncpy(dname, name, Ndbvlen);
+	strncpy(dname, name, sizeof dname);
 	for(nt = t; nt; nt = nt->entry)
 		if(strcmp(nt->attr, "dom") == 0){
-			strcpy(dname, nt->val);
+			nstrcpy(dname, nt->val, sizeof dname);
 			break;
 		}
 
@@ -239,7 +246,7 @@ dblookup1(char *name, int type, int auth, int ttl)
 	l = &list;
 	for(nt = s.t;; ){
 		if(found == 0 && strcmp(nt->attr, "dom") == 0){
-			strcpy(dname, nt->val);
+			nstrcpy(dname, nt->val, sizeof dname);
 			found = 1;
 		}
 		if(cistrcmp(attr, nt->attr) == 0){

+ 5 - 5
sys/src/cmd/ndb/query.c

@@ -19,13 +19,13 @@ search(Ndb *db, char *attr, char *val, char *rattr)
 	Ndbs s;
 	Ndbtuple *t;
 	Ndbtuple *nt;
-	char buf[Ndbvlen];
+	char *p;
 
 	if(rattr){
-		t = ndbgetval(db, &s, attr, val, rattr, buf);
-		if(t){
-			print("%s\n", buf);
-			ndbfree(t);
+		p = ndbgetvalue(db, &s, attr, val, rattr, nil);
+		if(p){
+			print("%s\n", p);
+			free(p);
 		}
 		return;
 	}

+ 14 - 17
sys/src/cmd/netstat.c

@@ -95,17 +95,16 @@ nstat(char *net, void (*f)(char*, Dir*))
 char*
 getport(char *net, char *p)
 {
-	static char buf[Ndbvlen];
-	Ndbtuple *t;
-
-	if(notrans)
-		return p;
-	t = csgetval(netroot, "port", p, net, buf);
-	if(t)
-		ndbfree(t);
-	if(buf[0] == 0)
-		return p;
-	return buf;
+	static char port[10];
+
+	strncpy(port, p, sizeof(port)-1);
+	port[sizeof(port)-1] = 0;
+	if(notrans || (p = csgetvalue(netroot, "port", p, net, nil)) == nil)
+		return port;
+	strncpy(port, p, sizeof(port)-1);
+	port[sizeof(port)-1] = 0;
+	free(p);
+	return port;
 }
 
 void
@@ -113,8 +112,7 @@ pip(char *net, Dir *db)
 {
 	int n, fd;
 	char buf[128], *p;
-	Ndbtuple *tp;
-	char dname[Ndbvlen];
+	char *dname;
 
 	if(strcmp(db->name, "clone") == 0)
 		return;
@@ -181,15 +179,14 @@ pip(char *net, Dir *db)
 		Bprint(&out, "%-10s %s\n", getport(net, p), buf);
 		return;
 	}
-	tp = csgetval(netroot, "ip", buf, "dom", dname);
-	if(tp)
-		ndbfree(tp);
-	if(dname[0] == 0) {
+	dname = csgetvalue(netroot, "ip", buf, "dom", nil);
+	if(dname == nil) {
 		Bprint(&out, "%-10s %s\n", getport(net, p), buf);
 		return;
 	}
 	Bprint(&out, "%-10s %s\n", getport(net, p), dname);
 	Bflush(&out);
+	free(dname);
 }
 
 void

+ 7 - 7
sys/src/cmd/ssh/sshnet.c

@@ -467,11 +467,9 @@ struct Cs
 static int
 ndbfindport(char *p)
 {
-	char *s, port[Ndbvlen];
+	char *s, *port;
 	int n;
 	static Ndb *db;
-	Ndbtuple *t;
-	Ndbs ndbs;
 
 	if(*p == '\0')
 		return -1;
@@ -486,11 +484,13 @@ ndbfindport(char *p)
 			return -1;
 	}
 
-	t = ndbgetval(db, &ndbs, "tcp", p, "port", port);
-	if(t == nil)
+	port = ndbgetvalue(db, nil, "tcp", p, "port", nil);
+	if(port == nil)
 		return -1;
-	ndbfree(t);
-	return atoi(port);
+	n = atoi(port);
+	free(port);
+
+	return n;
 }	
 
 static void

+ 2 - 2
sys/src/cmd/upas/common/libsys.c

@@ -457,14 +457,14 @@ sysnames_read(void)
 {
 	static char **namev;
 	Ndbtuple *t, *nt;
-	char domain[Ndbvlen];
 	int n;
 	char *cp;
 
 	if(namev)
 		return namev;
 
-	t = csgetval(0, "sys", alt_sysname_read(), "dom", domain);
+	free(csgetvalue(0, "sys", alt_sysname_read(), "dom", &t));
+
 	n = 0;
 	for(nt = t; nt; nt = nt->entry)
 		if(strcmp(nt->attr, "dom") == 0)

+ 9 - 9
sys/src/libauthsrv/authdial.c

@@ -7,23 +7,23 @@
 int
 authdial(char *netroot, char *dom)
 {
-	char server[Ndbvlen];
-	Ndbtuple *nt;
-
+	char *p;
+	int rv;
 	
 	if(dom != nil){
 		/* look up an auth server in an authentication domain */
-		nt = csgetval(netroot, "authdom", dom, "auth", server);
+		p = csgetvalue(netroot, "authdom", dom, "auth", nil);
 
 		/* if that didn't work, just try the IP domain */
-		if(nt == nil)
-			nt = csgetval(netroot, "dom", dom, "auth", server);
-		if(nt == nil){
+		if(p == nil)
+			p = csgetvalue(netroot, "dom", dom, "auth", nil);
+		if(p == nil){
 			werrstr("no auth server found for %s", dom);
 			return -1;
 		}
-		ndbfree(nt);
-		return dial(netmkaddr(server, netroot, "ticket"), 0, 0, 0);
+		rv = dial(netmkaddr(p, netroot, "ticket"), 0, 0, 0);
+		free(p);
+		return rv;
 	} else {
 		/* look for one relative to my machine */
 		return dial(netmkaddr("$auth", netroot, "ticket"), 0, 0, 0);

+ 39 - 15
sys/src/libndb/csgetval.c

@@ -10,15 +10,19 @@
  *
  *  return 0 if not found.
  */
-Ndbtuple*
-csgetvalue(char *netroot, char *attr, char *val, char *rattr, char *buf, int len)
+char*
+csgetvalue(char *netroot, char *attr, char *val, char *rattr, Ndbtuple **pp)
 {
 	Ndbtuple *t, *first, *last;
 	int n, linefound;
 	char line[1024];
 	int fd;
+	int oops = 0;
+	char *rv;
 
-	buf[0] = 0;
+	if(pp)
+		*pp = nil;
+	rv = nil;
 
 	if(netroot)
 		snprint(line, sizeof(line), "%s/cs", netroot);
@@ -35,7 +39,6 @@ csgetvalue(char *netroot, char *attr, char *val, char *rattr, char *buf, int len
 	}
 	seek(fd, 0, 0);
 
-	werrstr("");
 	first = last = 0;
 	linefound = 0;
 	for(;;){
@@ -58,26 +61,47 @@ csgetvalue(char *netroot, char *attr, char *val, char *rattr, char *buf, int len
 			last = last->entry;
 
 		for(; t; t = t->entry){
-			if(buf[0] == 0 || linefound == 0)
+			if(linefound == 0){
 				if(strcmp(rattr, t->attr) == 0){
-					strncpy(buf, t->val, len);
-					buf[len-1] = 0;
-					if(strlen(t->val) >= len)
-						werrstr("return value truncated");
-				}
-			if(linefound == 0)
-				if(strcmp(attr, t->attr) == 0)
 					linefound = 1;
+					rv = strdup(t->val);
+				}
+			}
 		}
 	}
 	close(fd);
 
-	setmalloctag(first, getcallerpc(&netroot));
-	return first;
+	if(oops){
+		werrstr("buffer too short");
+		ndbfree(first);
+		return nil;
+	}
+
+	if(pp){
+		setmalloctag(first, getcallerpc(&netroot));
+		*pp = first;
+	} else
+		ndbfree(first);
+
+	return rv;
 }
 
 Ndbtuple*
 csgetval(char *netroot, char *attr, char *val, char *rattr, char *buf)
 {
-	return csgetvalue(netroot, attr, val, rattr, buf, Ndbvlen);
+	Ndbtuple *t;
+	char *p;
+
+	p = csgetvalue(netroot, attr, val, rattr, &t);
+	if(p == nil){
+		if(buf != nil)
+			*buf = 0;
+	} else {
+		if(buf != nil){
+			strncpy(buf, p, Ndbvlen-1);
+			buf[Ndbvlen-1] = 0;
+		}
+		free(p);
+	}
+	return t;
 }

+ 4 - 4
sys/src/libndb/ndbgetipaddr.c

@@ -8,10 +8,9 @@
 Ndbtuple*
 ndbgetipaddr(Ndb *db, char *val)
 {
-	char *attr;
+	char *attr, *p;
 	Ndbtuple *it, *first, *last, *next;
 	Ndbs s;
-	char buf[Ndbvlen];
 
 	/* already an IP address? */
 	attr = ipattr(val);
@@ -21,9 +20,10 @@ ndbgetipaddr(Ndb *db, char *val)
 	}
 
 	/* look it up */
-	it = ndbgetvalue(db, &s, attr, val, "ip", buf, sizeof(buf));
-	if(it == nil)
+	p = ndbgetvalue(db, &s, attr, val, "ip", &it);
+	if(p == nil)
 		return nil;
+	free(p);
 
 	/* remove the non-ip entries */
 	first = last = nil;

+ 38 - 16
sys/src/libndb/ndbgetval.c

@@ -9,45 +9,67 @@
  *
  *  return 0 if not found.
  */
-Ndbtuple*
-ndbgetvalue(Ndb *db, Ndbs *s, char *attr, char *val, char *rattr, char *buf, int len)
+char*
+ndbgetvalue(Ndb *db, Ndbs *s, char *attr, char *val, char *rattr, Ndbtuple **pp)
 {
 	Ndbtuple *t, *nt;
+	char *rv;
+	Ndbs temps;
 
-	werrstr("");
+	if(s == nil)
+		s = &temps;
+	if(pp)
+		*pp = nil;
 	t = ndbsearch(db, s, attr, val);
 	while(t){
 		/* first look on same line (closer binding) */
 		nt = s->t;
 		for(;;){
 			if(strcmp(rattr, nt->attr) == 0){
-				strncpy(buf, nt->val, len);
-				buf[len-1] = 0;
-				if(strlen(nt->val) >= len)
-					werrstr("return value truncated");
-				return t;
+				rv = strdup(nt->val);
+				if(pp != nil)
+					*pp = t;
+				else
+					ndbfree(t);
+				return rv;
 			}
 			nt = nt->line;
 			if(nt == s->t)
 				break;
 		}
 		/* search whole tuple */
-		for(nt = t; nt; nt = nt->entry)
+		for(nt = t; nt; nt = nt->entry){
 			if(strcmp(rattr, nt->attr) == 0){
-				strncpy(buf, nt->val, len);
-				buf[len-1] = 0;
-				if(strlen(nt->val) >= len)
-					werrstr("return value truncated");
-				return t;
+				rv = strdup(nt->val);
+				if(pp != nil)
+					*pp = t;
+				else
+					ndbfree(t);
+				return rv;
 			}
+		}
 		ndbfree(t);
 		t = ndbsnext(s, attr, val);
 	}
-	return 0;
+	return nil;
 }
 
 Ndbtuple*
 ndbgetval(Ndb *db, Ndbs *s, char *attr, char *val, char *rattr, char *buf)
 {
-	return ndbgetvalue(db, s, attr, val, rattr, buf, Ndbvlen);
+	Ndbtuple *t;
+	char *p;
+
+	p = ndbgetvalue(db, s, attr, val, rattr, &t);
+	if(p == nil){
+		if(buf != nil)
+			*buf = 0;
+	} else {
+		if(buf != nil){
+			strncpy(buf, p, Ndbvlen-1);
+			buf[Ndbvlen-1] = 0;
+		}
+		free(p);
+	}
+	return t;
 }

+ 14 - 17
sys/src/libndb/ndblookval.c

@@ -9,20 +9,14 @@
  *  then in the whole entry.
  */
 Ndbtuple*
-ndblookvalue(Ndbtuple *entry, Ndbtuple *line, char *attr, char *to, int len)
+ndbfindattr(Ndbtuple *entry, Ndbtuple *line, char *attr)
 {
 	Ndbtuple *nt;
 
 	/* first look on same line (closer binding) */
-	werrstr("");
-	for(nt = line;;){
-		if(strcmp(attr, nt->attr) == 0){
-			strncpy(to, nt->val, len);
-			to[len-1] = 0;
-			if(strlen(nt->val) >= len)
-				werrstr("return value truncated");
+	for(nt = line; nt;){
+		if(strcmp(attr, nt->attr) == 0)
 			return nt;
-		}
 		nt = nt->line;
 		if(nt == line)
 			break;
@@ -30,18 +24,21 @@ ndblookvalue(Ndbtuple *entry, Ndbtuple *line, char *attr, char *to, int len)
 
 	/* search whole tuple */
 	for(nt = entry; nt; nt = nt->entry)
-		if(strcmp(attr, nt->attr) == 0){
-			strncpy(to, nt->val, len);
-			to[len-1] = 0;
-			if(strlen(nt->val) >= len)
-				werrstr("return value truncated");
+		if(strcmp(attr, nt->attr) == 0)
 			return nt;
-		}
-	return 0;
+
+	return nil;
 }
 
 Ndbtuple*
 ndblookval(Ndbtuple *entry, Ndbtuple *line, char *attr, char *to)
 {
-	return ndblookvalue(entry, line, attr, to, Ndbvlen);
+	Ndbtuple *t;
+
+	t = ndbfindattr(entry, line, attr);
+	if(t != nil){
+		strncpy(to, t->val, Ndbvlen-1);
+		to[Ndbvlen-1] = 0;
+	}
+	return t;
 }