This commit is contained in:
rsc 2005-02-11 19:41:16 +00:00
parent ad017cfbf5
commit d957951b75
27 changed files with 2521 additions and 0 deletions

13
src/cmd/ndb/mkfile Normal file
View file

@ -0,0 +1,13 @@
<$PLAN9/src/mkhdr
TARG=\
ndbmkdb\
ndbquery\
ndbmkhash\
ndbmkhosts\
ndbipquery\
LIB=$PLAN9/lib/libndb.a
<$PLAN9/src/mkmany

54
src/cmd/ndb/ndbipquery.c Normal file
View file

@ -0,0 +1,54 @@
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <ndb.h>
#include <ip.h>
/*
* search the database for matches
*/
void
usage(void)
{
fprint(2, "usage: ipquery attr value rattribute\n");
exits("usage");
}
void
search(Ndb *db, char *attr, char *val, char **rattr, int nrattr)
{
Ndbtuple *t;
t = ndbipinfo(db, attr, val, rattr, nrattr);
for(; t; t = t->entry)
print("%s=%s ", t->attr, t->val);
print("\n");
ndbfree(t);
}
void
main(int argc, char **argv)
{
Ndb *db;
char *dbfile = 0;
ARGBEGIN{
case 'f':
dbfile = ARGF();
break;
}ARGEND;
if(argc < 3)
usage();
db = ndbopen(dbfile);
if(db == 0){
fprint(2, "no db files\n");
exits("no db");
}
search(db, argv[0], argv[1], argv+2, argc-2);
ndbclose(db);
exits(0);
}

203
src/cmd/ndb/ndbmkdb.c Normal file
View file

@ -0,0 +1,203 @@
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <ctype.h>
Biobuf in;
Biobuf out;
enum
{
Empty,
Sys,
Dk,
Ip,
Domain,
};
int
iscomment(char *name)
{
return *name == '#';
}
/*
* is this a fully specified datakit name?
*/
int
isdk(char *name)
{
int slash;
slash = 0;
for(; *name; name++){
if(isalnum(*name))
continue;
if(*name == '/'){
slash = 1;
continue;
}
return 0;
}
return slash;
}
/*
* Is this an internet domain name?
*/
int
isdomain(char *name)
{
int dot = 0;
int alpha = 0;
for(; *name; name++){
if(isalpha(*name) || *name == '-'){
alpha = 1;
continue;
}
if(*name == '.'){
dot = 1;
continue;
}
if(isdigit(*name))
continue;
return 0;
}
return dot && alpha;
}
/*
* is this an ip address?
*/
int
isip(char *name)
{
int dot = 0;
for(; *name; name++){
if(*name == '.'){
dot = 1;
continue;
}
if(isdigit(*name))
continue;
return 0;
}
return dot;
}
char tup[64][64];
int ttype[64];
int ntup;
void
tprint(void)
{
int i, tab;
char *p;
tab = 0;
for(i = 0; i < ntup; i++){
if(ttype[i] == Sys){
Bprint(&out, "sys = %s\n", tup[i]);
tab = 1;
ttype[i] = Empty;
break;
}
}
for(i = 0; i < ntup; i++){
if(ttype[i] == Empty)
continue;
if(tab)
Bprint(&out, "\t");
tab = 1;
switch(ttype[i]){
case Domain:
Bprint(&out, "dom=%s\n", tup[i]);
break;
case Ip:
Bprint(&out, "ip=%s\n", tup[i]);
break;
case Dk:
p = strrchr(tup[i], '/');
if(p){
p++;
if((*p == 'C' || *p == 'R')
&& strncmp(tup[i], "nj/astro/", p-tup[i]) == 0)
Bprint(&out, "flavor=console ");
}
Bprint(&out, "dk=%s\n", tup[i]);
break;
case Sys:
Bprint(&out, "sys=%s\n", tup[i]);
break;
}
}
}
#define NFIELDS 64
/*
* make a database file from a merged uucp/inet database
*/
void
main(void)
{
int n, i, j;
char *l;
char *fields[NFIELDS];
int ftype[NFIELDS];
int same, match;
Binit(&in, 0, OREAD);
Binit(&out, 1, OWRITE);
ntup = 0;
while(l = Brdline(&in, '\n')){
l[Blinelen(&in)-1] = 0;
n = getfields(l, fields, NFIELDS, 1, " \t");
same = 0;
for(i = 0; i < n; i++){
if(iscomment(fields[i])){
n = i;
break;
}
if(isdomain(fields[i])){
ftype[i] = Domain;
for(j = 0; j < ntup; j++)
if(ttype[j] == Domain && strcmp(fields[i], tup[j]) == 0){
same = 1;
ftype[i] = Empty;
break;
}
} else if(isip(fields[i]))
ftype[i] = Ip;
else if(isdk(fields[i]))
ftype[i] = Dk;
else
ftype[i] = Sys;
}
if(!same && ntup){
tprint();
ntup = 0;
}
for(i = 0; i < n; i++){
match = 0;
for(j = 0; j < ntup; j++){
if(ftype[i] == ttype[j] && strcmp(fields[i], tup[j]) == 0){
match = 1;
break;
}
}
if(!match){
ttype[ntup] = ftype[i];
strcpy(tup[ntup], fields[i]);
ntup++;
}
}
}
if(ntup)
tprint();
exits(0);
}

155
src/cmd/ndb/ndbmkhash.c Normal file
View file

@ -0,0 +1,155 @@
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <ndb.h>
/*
* make the hash table completely in memory and then write as a file
*/
uchar *ht;
ulong hlen;
Ndb *db;
ulong nextchain;
char*
syserr(void)
{
static char buf[ERRMAX];
errstr(buf, sizeof buf);
return buf;
}
void
enter(char *val, ulong dboff)
{
ulong h;
uchar *last;
ulong ptr;
h = ndbhash(val, hlen);
h *= NDBPLEN;
last = &ht[h];
ptr = NDBGETP(last);
if(ptr == NDBNAP){
NDBPUTP(dboff, last);
return;
}
if(ptr & NDBCHAIN){
/* walk the chain to the last entry */
for(;;){
ptr &= ~NDBCHAIN;
last = &ht[ptr+NDBPLEN];
ptr = NDBGETP(last);
if(ptr == NDBNAP){
NDBPUTP(dboff, last);
return;
}
if(!(ptr & NDBCHAIN)){
NDBPUTP(nextchain|NDBCHAIN, last);
break;
}
}
} else
NDBPUTP(nextchain|NDBCHAIN, last);
/* add a chained entry */
NDBPUTP(ptr, &ht[nextchain]);
NDBPUTP(dboff, &ht[nextchain + NDBPLEN]);
nextchain += 2*NDBPLEN;
}
uchar nbuf[16*1024];
void
main(int argc, char **argv)
{
Ndbtuple *t, *nt;
int n;
Dir *d;
uchar buf[8];
char file[128];
int fd;
ulong off;
uchar *p;
if(argc != 3){
fprint(2, "mkhash: usage file attribute\n");
exits("usage");
}
db = ndbopen(argv[1]);
if(db == 0){
fprint(2, "mkhash: can't open %s\n", argv[1]);
exits(syserr());
}
/* try a bigger than normal buffer */
Binits(&db->b, Bfildes(&db->b), OREAD, nbuf, sizeof(nbuf));
/* count entries to calculate hash size */
n = 0;
while(nt = ndbparse(db)){
for(t = nt; t; t = t->entry){
if(strcmp(t->attr, argv[2]) == 0)
n++;
}
ndbfree(nt);
}
/* allocate an array large enough for worst case */
hlen = 2*n+1;
n = hlen*NDBPLEN + hlen*2*NDBPLEN;
ht = mallocz(n, 1);
if(ht == 0){
fprint(2, "mkhash: not enough memory\n");
exits(syserr());
}
for(p = ht; p < &ht[n]; p += NDBPLEN)
NDBPUTP(NDBNAP, p);
nextchain = hlen*NDBPLEN;
/* create the in core hash table */
Bseek(&db->b, 0, 0);
off = 0;
while(nt = ndbparse(db)){
for(t = nt; t; t = t->entry){
if(strcmp(t->attr, argv[2]) == 0)
enter(t->val, off);
}
ndbfree(nt);
off = Boffset(&db->b);
}
/* create the hash file */
snprint(file, sizeof(file), "%s.%s", argv[1], argv[2]);
fd = create(file, ORDWR, 0664);
if(fd < 0){
fprint(2, "mkhash: can't create %s\n", file);
exits(syserr());
}
NDBPUTUL(db->mtime, buf);
NDBPUTUL(hlen, buf+NDBULLEN);
if(write(fd, buf, NDBHLEN) != NDBHLEN){
fprint(2, "mkhash: writing %s\n", file);
exits(syserr());
}
if(write(fd, ht, nextchain) != nextchain){
fprint(2, "mkhash: writing %s\n", file);
exits(syserr());
}
close(fd);
/* make sure file didn't change while we were making the hash */
d = dirstat(argv[1]);
if(d == nil || d->qid.path != db->qid.path
|| d->qid.vers != db->qid.vers){
fprint(2, "mkhash: %s changed underfoot\n", argv[1]);
remove(file);
exits("changed");
}
exits(0);
}

233
src/cmd/ndb/ndbmkhosts.c Normal file
View file

@ -0,0 +1,233 @@
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <ndb.h>
#include <ip.h>
typedef struct x
{
Ndbtuple *t;
Ndbtuple *it;
Ndbtuple *nt;
} X;
X x[4096];
int nx;
char *domname = "research.att.com";
int domnamlen;
char*
upper(char *x)
{
char *p;
int c;
for(p = x; c = *p; p++)
*p = toupper(c);
return x;
}
void
printArecord(int fd, X *p)
{
Ndbtuple *nt;
char *c;
char *dom = 0;
char *curdom = 0;
int i, cdlen = 0;
int mxweight = 0;
if(p->nt) {
return;
}
for(nt=p->t; nt; nt = nt->entry) {
/* we are only going to handle things in the specified domain */
c = strchr(nt->val, '.');
if (c==0 || strcmp(++c, domname)!=0)
continue;
i = c - nt->val - 1;
if(strcmp(nt->attr, "dom") == 0) {
curdom = nt->val;
cdlen = i;
if (dom == 0) {
dom = curdom;
fprint(fd, "%-.*s%.*s IN A %s\n", i, nt->val, 15-i, " ", p->it->val);
} else
fprint(fd, "%-.*s%.*s IN CNAME %s.\n", i, nt->val, 15-i, " ", dom);
} else if(strcmp(nt->attr, "mx") == 0) {
if (curdom != 0)
fprint(fd, "%-.*s%.*s MX %d %s.\n", cdlen, curdom, 15-cdlen, " ", mxweight++, nt->val);
}
}
}
void
printentry(int fd, X *p)
{
Ndbtuple *nt;
if(p->nt)
return;
fprint(fd, "%s ", p->it->val);
for(nt = p->t; nt; nt = nt->entry)
if(strcmp(nt->attr, "dom") == 0)
fprint(fd, " %s", nt->val);
for(nt = p->t; nt; nt = nt->entry)
if(strcmp(nt->attr, "sys") == 0)
fprint(fd, " %s", nt->val);
fprint(fd, "\n");
}
void
printsys(int fd, X *p)
{
Ndbtuple *nt;
for(nt = p->t; nt; nt = nt->entry)
if(strcmp(nt->attr, "dom") == 0)
fprint(fd, "%s\n", nt->val);
}
void
printtxt(int fd, X *p)
{
int i;
Ndbtuple *nt;
if(p->nt){
for(;;){
i = strlen(p->it->val);
if(strcmp(p->it->val+i-2, ".0") == 0)
p->it->val[i-2] = 0;
else
break;
}
fprint(fd, "\nNET : %s : %s\n", p->it->val, upper(p->nt->val));
return;
}
fprint(fd, "HOST : %s :", p->it->val);
i = 0;
for(nt = p->t; nt; nt = nt->entry)
if(strcmp(nt->attr, "dom") == 0){
if(i++ == 0)
fprint(fd, " %s", upper(nt->val));
else
fprint(fd, ", %s", upper(nt->val));
}
fprint(fd, "\n");
}
void
parse(char *file)
{
int i;
Ndb *db;
Ndbtuple *t, *nt, *tt, *ipnett;
char *p;
db = ndbopen(file);
if(db == 0)
exits("no database");
while(t = ndbparse(db)){
for(nt = t; nt; nt = nt->entry){
if(strcmp(nt->attr, "ip") == 0)
break;
if(strcmp(nt->attr, "flavor") == 0
&& strcmp(nt->val, "console") == 0)
return;
}
if(nt == 0){
ndbfree(t);
continue;
}
/* dump anything not on our nets */
ipnett = 0;
for(tt = t; tt; tt = tt->entry){
if(strcmp(tt->attr, "ipnet") == 0){
ipnett = tt;
break;
}
if(strcmp(tt->attr, "dom") == 0){
i = strlen(tt->val);
p = tt->val+i-domnamlen;
if(p >= tt->val && strcmp(p, domname) == 0)
break;
}
}
if(tt == 0){
ndbfree(t);
continue;
}
for(; nt; nt = nt->entry){
if(strcmp(nt->attr, "ip") != 0)
continue;
x[nx].it = nt;
x[nx].nt = ipnett;
x[nx++].t = t;
}
}
}
void
main(int argc, char *argv[])
{
int i, fd;
char fn[128];
if (argc>1)
domname = argv[1];
domnamlen = strlen(domname);
if(argc > 2){
for(i = 2; i < argc; i++)
parse(argv[i]);
} else {
parse(unsharp("#9/ndb/local"));
parse(unsharp("#9/ndb/friends"));
}
// sprint(fn, "/lib/ndb/hosts.%-.21s", domname);
// fd = create(fn, OWRITE, 0664);
// if(fd < 0){
// fprint(2, "can't create %s: %r\n", fn);
// exits("boom");
// }
// for(i = 0; i < nx; i++)
// printentry(fd, &x[i]);
// close(fd);
//
sprint(fn, "/lib/ndb/db.%-.24s", domname);
fd = create(fn, OWRITE, 0664);
if(fd < 0){
fprint(2, "can't create %s: %r\n", fn);
exits("boom");
}
fprint(fd, "; This file is generated automatically, do not edit!\n");
for(i = 0; i < nx; i++)
printArecord(fd, &x[i]);
close(fd);
sprint(fn, "/lib/ndb/equiv.%-.21s", domname);
fd = create(fn, OWRITE, 0664);
if(fd < 0){
fprint(2, "can't create %s: %r\n", fn);
exits("boom");
}
for(i = 0; i < nx; i++)
printsys(fd, &x[i]);
close(fd);
sprint(fn, "/lib/ndb/txt.%-.23s", domname);
fd = create(fn, OWRITE, 0664);
if(fd < 0){
fprint(2, "can't create %s: %r\n", fn);
exits("boom");
}
for(i = 0; i < nx; i++)
printtxt(fd, &x[i]);
close(fd);
exits(0);
}

81
src/cmd/ndb/ndbquery.c Normal file
View file

@ -0,0 +1,81 @@
#include <u.h>
#include <libc.h>
#include <bio.h>
#include <ndb.h>
/*
* search the database for matches
*/
void
usage(void)
{
fprint(2, "usage: query attr value [returned attribute]\n");
exits("usage");
}
void
search(Ndb *db, char *attr, char *val, char *rattr)
{
Ndbs s;
Ndbtuple *t;
Ndbtuple *nt;
char *p;
if(rattr){
p = ndbgetvalue(db, &s, attr, val, rattr, nil);
if(p){
print("%s\n", p);
free(p);
}
return;
}
t = ndbsearch(db, &s, attr, val);
while(t){
for(nt = t; nt; nt = nt->entry)
print("%s=%s ", nt->attr, nt->val);
print("\n");
ndbfree(t);
t = ndbsnext(&s, attr, val);
}
}
void
main(int argc, char **argv)
{
char *rattr = 0;
Ndb *db;
char *dbfile = 0;
int reps = 1;
ARGBEGIN{
case 'f':
dbfile = ARGF();
break;
}ARGEND;
switch(argc){
case 4:
reps = atoi(argv[3]);
/* fall through */
case 3:
rattr = argv[2];
break;
case 2:
rattr = 0;
break;
default:
usage();
}
db = ndbopen(dbfile);
if(db == 0){
fprint(2, "no db files\n");
exits("no db");
}
while(reps--)
search(db, argv[0], argv[1], rattr);
ndbclose(db);
exits(0);
}