/* 
 * This file is part of the UCB release of Plan 9. It is subject to the license
 * terms in the LICENSE file found in the top-level directory of this
 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
 * part of the UCB release of Plan 9, including this file, may be copied,
 * modified, propagated, or distributed except according to the terms contained
 * in the LICENSE file.
 */
#include <stdlib.h>

#include <stdio.h>
#include <parlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <pthread.h>
#include <fcntl.h>
#include <ctype.h>
#include <error.h>
#include <iplib.h>
#include <ndb.h>
#include <fcallfmt.h>
#include <fcall.h>

#define ARRAY_SIZE(x) (sizeof((x))/sizeof((x)[0]))

enum
{
	Nreply=			20,
	Maxreply=		256,
	Maxrequest=		128,
	Maxpath=		128,
	Maxfdata=		8192,
	Maxhost=		64,		/* maximum host name size */
	Maxservice=		64,		/* maximum service name size */

	Qdir=			0,
	Qcs=			1,
};

typedef struct Mfile	Mfile;
typedef struct Mlist	Mlist;
typedef struct Network	Network;
typedef struct Flushreq	Flushreq;
typedef struct Job	Job;

int vers;		/* incremented each clone/attach */
/* need to resolve the #inluce for all this stuff. */
#define DMDIR              0x80000000      /* mode bit for directories */
#define QTDIR 0x80
#define QTFILE 0
#define ERRMAX 128

struct Mfile
{
	int		busy;

	char		*user;
	struct qid     qid;
	int		fid;

	/*
	 *  current request
	 */
	char		*net;
	char		*host;
	char		*serv;
	char		*rem;

	/*
	 *  result of the last lookup
	 */
	Network		*nextnet;
	int		nreply;
	char		*reply[Nreply];
	int		replylen[Nreply];
};

struct Mlist
{
	Mlist	*next;
	Mfile	mf;
};


/*
 *  active requests
 */
struct Job
{
	Job	*next;
	int	flushed;
	struct fcall	request;
	struct fcall	reply;
	pthread_t thread;
};

//spinlock_t	joblock;
int joblock;
Job	*joblist;

Mlist	*mlist;
int	mfd[2];
int	debug;
int	paranoia;
int	ipv6lookups = 1;
char	*dbfile = "lib/ndb/local";
struct ndb	*db, *netdb;

void	rversion(Job*);
void	rflush(Job*);
void	rattach(Job*, Mfile*);
char*	rwalk(Job*, Mfile*);
void	ropen(Job*, Mfile*);
void	rcreate(Job*, Mfile*);
void	rread(Job*, Mfile*);
void	rwrite(Job*, Mfile*);
void	rclunk(Job*, Mfile*);
void	rremove(Job*, Mfile*);
void	rstat(Job*, Mfile*);
void	rwstat(Job*, Mfile*);
void	rauth(Job*);
void	sendmsg(Job*, char*);
void	mountinit(char*, char*);
void	io(void);
void	ndbinit(void);
void	netinit(int);
void	netadd(char*);
char	*genquery(Mfile*, char*);
char*	ipinfoquery(Mfile*, char**, int);
int	needproto(Network*, struct ndbtuple*);
int	lookup(Mfile*);
struct ndbtuple*	reorder(struct ndbtuple*, struct ndbtuple*);
void	ipid(void);
void	readipinterfaces(void);
void*	emalloc(int);
char*	estrdup(char*);
Job*	newjob(void);
void	freejob(Job*);
void	setext(char*, int, char*);
void	cleanmf(Mfile*);

extern void	paralloc(void);

spinlock_t	dblock;		/* mutex on database operations */
spinlock_t	netlock;	/* mutex for netinit() */

char	*logfile = "cs";
char	*paranoiafile = "cs.paranoia";

char	mntpt[Maxpath];
char	netndb[Maxpath];

/*
 *  Network specific translators
 */
struct ndbtuple*	iplookup(Network*, char*, char*, int);
char*		iptrans(struct ndbtuple*, Network*, char*, char*, int);
struct ndbtuple*	telcolookup(Network*, char*, char*, int);
char*		telcotrans(struct ndbtuple*, Network*, char*, char*, int);
struct ndbtuple*	dnsiplookup(char*, struct ndbs*);

struct Network
{
	char		*net;
	struct ndbtuple	*(*lookup)(Network*, char*, char*, int);
	char		*(*trans)(struct ndbtuple*, Network*, char*, char*, int);
	int		considered;		/* flag: ignored for "net!"? */
	int		fasttimeouthack;	/* flag. was for IL */
	Network		*next;
};

enum
{
	Ntcp = 0,
};

/*
 *  net doesn't apply to (r)udp, icmp(v6), or telco (for speed).
 */
Network network[] = {
[Ntcp]	{ "tcp",	iplookup,	iptrans,	0 },
	{ "udp",	iplookup,	iptrans,	1 },
	{ "icmp",	iplookup,	iptrans,	1 },
	{ "icmpv6",	iplookup,	iptrans,	1 },
	{ "rudp",	iplookup,	iptrans,	1 },
	{ "ssh",	iplookup,	iptrans,	1 },
	{ "telco",	telcolookup,	telcotrans,	1 },
	{ 0 },
};

spinlock_t ipifclock;
struct ipifc *ipifcs;

char	eaddr[16];		/* ascii ethernet address */
char	ipaddr[64];		/* ascii internet address */
uint8_t	ipa[IPaddrlen];		/* binary internet address */
char	*mysysname;

Network *netlist;		/* networks ordered by preference */
Network *last;

static void
nstrcpy(char *to, char *from, int len)
{
	strncpy(to, from, len);
	to[len-1] = 0;
}

char *argv0;
void
usage(void)
{
	fprintf(stderr, "CS:usage: %s [-dn] [-f ndb-file] [-x netmtpt]\n", argv0);
	fprintf(stderr, "CS:usage");
	exit(1);
}

/*
 * based on libthread's threadsetname, but drags in less library code.
 * actually just sets the arguments displayed.
 */
void
procsetname(char *fmt, ...)
{
/* someday ... */
#if 0
	int fd;
	char *cmdname;
	char buf[128];
	va_list arg;

	va_start(arg, fmt);
	cmdname = vsmprint(fmt, arg);
	va_end(arg);
	if (cmdname == NULL)
		return;
	snprintf(buf, sizeof buf, "#p/%d/args", getpid());
	if((fd = open(buf, OWRITE)) >= 0){
		write(fd, cmdname, strlen(cmdname)+1);
		close(fd);
	}
	free(cmdname);
#endif
}

void
main(int argc, char *argv[])
{
	int justsetname;
	char ext[Maxpath], servefile[Maxpath];
	argv0 = argv[0];
	justsetname = 0;
	setnetmtpt(mntpt, sizeof(mntpt), NULL);
	register_printf_specifier('F', printf_fcall, printf_fcall_info);
	ext[0] = 0;
	argc--, argv++;
	while (argc && **argv == '-'){
		switch(argv[0][1]){
	case '4':
		ipv6lookups = 0;
		break;
	case 'd':
		debug = 1;
		break;
	case 'f':
		if (argc < 2)
			usage();
		dbfile = argv[1];
		argc--,argv++;
		break;
	case 'n':
		justsetname = 1;
		break;
	case 'x':
		if (argc < 2)
			usage();
		setnetmtpt(mntpt, sizeof(mntpt), argv[1]);
		argc--,argv++;
		setext(ext, sizeof(ext), mntpt);
		break;
		}
		argc--,argv++;
	}

	//rfork(RFREND|RFNOTEG);

	snprintf(servefile, sizeof(servefile), "#s/cs%s", ext);
	snprintf(netndb, sizeof(netndb), "%s/ndb", mntpt);
	syscall(SYS_nunmount, (unsigned long)servefile, (unsigned long)mntpt);
	remove(servefile);

	ndbinit();
	netinit(0);

	if(!justsetname){
		mountinit(servefile, mntpt);
		io();
	}
	exit(0);
}

/*
 *  if a mount point is specified, set the cs extention to be the mount point
 *  with '_'s replacing '/'s
 */
void
setext(char *ext, int n, char *p)
{
	int i, c;

	n--;
	for(i = 0; i < n; i++){
		c = p[i];
		if(c == 0)
			break;
		if(c == '/')
			c = '_';
		ext[i] = c;
	}
	ext[i] = 0;
}

void
mountinit(char *service, char *mntpt)
{
	int f;
	int p[2];
	char buf[32];
	int ret;

	ret = syscall(SYS_pipe, (unsigned long)p);
	if (ret < 0){
		error(1, 0, "pipe: %r");
		exit(1);
	}

	/*
	 *  make a /srv/cs
	 * ORCLOSE means remove on last close. Handy. Not here yet. 
	 */
	f = open(service, O_WRONLY|O_CREAT/*|ORCLOSE*/, 0666);
	if(f < 0)
		error(1, 0, "%s: %r",service);
	snprintf(buf, sizeof(buf), "%d", p[1]);
	if(write(f, buf, strlen(buf)) != strlen(buf))
		error(1, 0, "Write %s: %r", service);
	/* using #s: we create a pipe and drop it into #s. 
	 * we no longer mount. That's up to you.
	 * #s will route requests to us.
	 */
	close(p[1]);

	mfd[0] = mfd[1] = p[0];
}

void
ndbinit(void)
{
	db = ndbopen(dbfile);
	if(db == NULL)
		error(1, 0, "%s: %r","can't open network database");

	netdb = ndbopen(netndb);
	if(netdb != NULL){
		netdb->nohash = 1;
		db = ndbcat(netdb, db);
	}
}

Mfile*
newfid(int fid)
{
	Mlist *f, *ff;
	Mfile *mf;

	ff = 0;
	for(f = mlist; f; f = f->next)
		if(f->mf.busy && f->mf.fid == fid)
			return &f->mf;
		else if(!ff && !f->mf.busy)
			ff = f;
	if(ff == 0){
		ff = emalloc(sizeof *f);
		ff->next = mlist;
		mlist = ff;
	}
	mf = &ff->mf;
	memset(mf, 0, sizeof *mf);
	mf->fid = fid;
	return mf;
}

Job*
newjob(void)
{
	Job *job;

	job = calloc(1, sizeof(Job));
	if (! job){
		error(1, 0, "%s: %r","job calloc");
	}
//	//lock(&joblock);
	job->next = joblist;
	joblist = job;
	job->request.tag = -1;
//	//unlock(&joblock);
	return job;
}

void
freejob(Job *job)
{
	Job **l;
	//lock(&joblock);
	for(l = &joblist; *l; l = &(*l)->next){
		if((*l) == job){
			*l = job->next;
			free(job);
			break;
		}
	}
	//unlock(&joblock);
}

void
flushjob(int tag)
{
	Job *job;

	//lock(&joblock);
	for(job = joblist; job; job = job->next){
		if(job->request.tag == tag && job->request.type != Tflush){
			job->flushed = 1;
			break;
		}
	}
	//unlock(&joblock);
}

void *job_thread(void* arg)
{
	Mfile *mf;
	Job *job = arg;
	//lock(&dblock);
	mf = newfid(job->request.fid);

	if(debug)
		fprintf(stderr, "CS:%F", &job->request);
	switch(job->request.type){
	default:
		fprintf(stderr, "CS:unknown request type %d", job->request.type);
		break;
	case Tversion:
		rversion(job);
		break;
	case Tauth:
		rauth(job);
		break;
	case Tflush:
		rflush(job);
		break;
	case Tattach:
		rattach(job, mf);
		break;
	case Twalk:
		rwalk(job, mf);
		break;
	case Topen:
		ropen(job, mf);
		break;
	case Tcreate:
		rcreate(job, mf);
		break;
	case Tread:
		rread(job, mf);
		break;
	case Twrite:
		rwrite(job, mf);
		break;
	case Tclunk:
		rclunk(job, mf);
		break;
	case Tremove:
		rremove(job, mf);
		break;
	case Tstat:
		rstat(job, mf);
		break;
	case Twstat:
		rwstat(job, mf);
		break;
	}
	//unlock(&dblock);

	freejob(job);

	if (debug)
		fprintf(stderr, "CS:Job done\n");
	return 0;
}


void
io(void)
{
	long n;

	uint8_t mdata[IOHDRSZ + Maxfdata];
	Job *job;

	/*
	 * each request is handled via a thread. Somewhat less efficient than the old
	 * cs but way cleaner. 
	 */

	for(;;){
		n = read9pmsg(mfd[0], mdata, sizeof mdata);
		if(n<=0)
			error(1, 0, "%s: %r","mount read");
		job = newjob();
		if(convM2S(mdata, n, &job->request) != n){
			fprintf(stderr, "convM2S went south: format error %ux %ux %ux %ux %ux",
				mdata[0], mdata[1], mdata[2], mdata[3], mdata[4]);
			error(1, 0, "format error %ux %ux %ux %ux %ux",
				mdata[0], mdata[1], mdata[2], mdata[3], mdata[4]);
			freejob(job);
			continue;
		}
		/* stash the thread in the job so we can join them all
		 * later if we want to.
		 */
#if 0
		if (pthread_create(&job->thread, NULL, &job_thread, job)) {
			error(1, 0, "%s: %r","Failed to create job");
			continue;
		}
#endif
	job_thread(job);


	}
}

void
rversion(Job *job)
{
	if(job->request.msize > IOHDRSZ + Maxfdata)
		job->reply.msize = IOHDRSZ + Maxfdata;
	else
		job->reply.msize = job->request.msize;
	if(strncmp(job->request.version, "9P2000", 6) != 0)
		sendmsg(job, "unknown 9P version");
	else{
		job->reply.version = "9P2000";
		sendmsg(job, 0);
	}
}

void
rauth(Job *job)
{
	sendmsg(job, "cs: authentication not required");
}

/*
 *  don't flush till all the threads  are done
 */
void
rflush(Job *job)
{
	flushjob(job->request.oldtag);
	sendmsg(job, 0);
}

void
rattach(Job *job, Mfile *mf)
{
	if(mf->busy == 0){
		mf->busy = 1;
		mf->user = estrdup(job->request.uname);
	}
	mf->qid.vers = vers++;
	mf->qid.type = QTDIR;
	mf->qid.path = 0LL;
	job->reply.qid = mf->qid;
	sendmsg(job, 0);
}


char*
rwalk(Job *job, Mfile *mf)
{
	char *err;
	char **elems;
	int nelems;
	int i;
	Mfile *nmf;
	struct qid qid;

	err = 0;
	nmf = NULL;
	elems = job->request.wname;
	nelems = job->request.nwname;
	job->reply.nwqid = 0;

	if(job->request.newfid != job->request.fid){
		/* clone fid */
		nmf = newfid(job->request.newfid);
		if(nmf->busy){
			nmf = NULL;
			err = "clone to used channel";
			goto send;
		}
		*nmf = *mf;
		nmf->user = estrdup(mf->user);
		nmf->fid = job->request.newfid;
		nmf->qid.vers = vers++;
		mf = nmf;
	}
	/* else nmf will be nil */

	qid = mf->qid;
	if(nelems > 0){
		/* walk fid */
		for(i=0; i<nelems && i<MAXWELEM; i++){
			if((qid.type & QTDIR) == 0){
				err = "not a directory";
				break;
			}
			if(strcmp(elems[i], "..") == 0 || strcmp(elems[i], ".") == 0){
				qid.type = QTDIR;
				qid.path = Qdir;
    Found:
				job->reply.wqid[i] = qid;
				job->reply.nwqid++;
				continue;
			}
			if(strcmp(elems[i], "cs") == 0){
				qid.type = QTFILE;
				qid.path = Qcs;
				goto Found;
			}
			err = "file does not exist";
			break;
		}
	}

    send:
	if(nmf != NULL && (err!=NULL || job->reply.nwqid<nelems)){
		cleanmf(nmf);
		free(nmf->user);
		nmf->user = 0;
		nmf->busy = 0;
		nmf->fid = 0;
	}
	if(err == NULL)
		mf->qid = qid;
	sendmsg(job, err);
	return err;
}

void
ropen(Job *job, Mfile *mf)
{
	int mode;
	char *err;

	err = 0;
	mode = job->request.mode;
	if(mf->qid.type & QTDIR){
		if(mode)
			err = "permission denied";
	}
	job->reply.qid = mf->qid;
	job->reply.iounit = 0;
	sendmsg(job, err);
}

void
rcreate(Job *job, Mfile *mf)
{
	sendmsg(job, "creation permission denied");
}

void
rread(Job *job, Mfile *mf)
{
	int i, n, cnt;
	long off, toff, clock;
	struct dir dir;
	uint8_t buf[Maxfdata];
	char *err;

	n = 0;
	err = 0;
	off = job->request.offset;
	cnt = job->request.count;
	if(mf->qid.type & QTDIR){
		//	clock = time(0);
		if(off == 0){
			memset(&dir, 0, sizeof dir);
			dir.name = "cs";
			dir.qid.type = QTFILE;
			dir.qid.vers = vers;
			dir.qid.path = Qcs;
			dir.mode = 0666;
			dir.length = 0;
			dir.uid = mf->user;
			dir.gid = mf->user;
			dir.muid = mf->user;
			dir.atime = clock;	/* wrong */
			dir.mtime = clock;	/* wrong */
			n = convD2M(&dir, buf, sizeof buf);
		}
		job->reply.data = (char*)buf;
	} else {
		for(;;){
			/* look for an answer at the right offset */
			toff = 0;
			for(i = 0; mf->reply[i] && i < mf->nreply; i++){
				n = mf->replylen[i];
				if(off < toff + n)
					break;
				toff += n;
			}
			if(i < mf->nreply)
				break;		/* got something to return */

			/* try looking up more answers */
			if(lookup(mf) == 0){
				/* no more */
				n = 0;
				goto send;
			}
		}

		/* give back a single reply (or part of one) */
		job->reply.data = mf->reply[i] + (off - toff);
		if(cnt > toff - off + n)
			n = toff - off + n;
		else
			n = cnt;
	}
send:
	job->reply.count = n;
	sendmsg(job, err);
}
void
cleanmf(Mfile *mf)
{
	int i;

	if(mf->net != NULL){
		free(mf->net);
		mf->net = NULL;
	}
	if(mf->host != NULL){
		free(mf->host);
		mf->host = NULL;
	}
	if(mf->serv != NULL){
		free(mf->serv);
		mf->serv = NULL;
	}
	if(mf->rem != NULL){
		free(mf->rem);
		mf->rem = NULL;
	}
	for(i = 0; i < mf->nreply; i++){
		free(mf->reply[i]);
		mf->reply[i] = NULL;
		mf->replylen[i] = 0;
	}
	mf->nreply = 0;
	mf->nextnet = netlist;
}

void
rwrite(Job *job, Mfile *mf)
{
	int cnt, n;
	char *err;
	char *field[4];
	char curerr[64];

	err = 0;
	cnt = job->request.count;
	if(mf->qid.type & QTDIR){
		err = "can't write directory";
		goto send;
	}
	if(cnt >= Maxrequest){
		err = "request too long";
		goto send;
	}
	job->request.data[cnt] = 0;
	/*
	 *  toggle debugging
	 */
	if(strncmp(job->request.data, "debug", 5)==0){
		debug ^= 1;
		fprintf(stderr, "CS:debug %d", debug);
		goto send;
	}

	/*
	 *  toggle ipv6 lookups
	 */
	if(strncmp(job->request.data, "ipv6", 4)==0){
		ipv6lookups ^= 1;
		fprintf(stderr, "CS:ipv6lookups %d", ipv6lookups);
		goto send;
	}

	/*
	 *  toggle debugging
	 */
	if(strncmp(job->request.data, "paranoia", 8)==0){
		paranoia ^= 1;
		fprintf(stderr,  "CS:paranoia %d", paranoia);
		goto send;
	}

	/*
	 *  add networks to the default list
	 */
	if(strncmp(job->request.data, "add ", 4)==0){
		if(job->request.data[cnt-1] == '\n')
			job->request.data[cnt-1] = 0;
		netadd(job->request.data+4);
		readipinterfaces();
		goto send;
	}

	/*
	 *  refresh all state
	 */
	if(strncmp(job->request.data, "refresh", 7)==0){
		netinit(0/*1*/);
		goto send;
	}

	/* start transaction with a clean slate */
	cleanmf(mf);

	/*
	 *  look for a general query
	 */
	if(*job->request.data == '!'){
		err = genquery(mf, job->request.data+1);
		goto send;
	}

	if(debug)
		fprintf(stderr,  "CS:write %s", job->request.data);
	if(paranoia)
		fprintf(stderr,  "CS:write %s by %s", job->request.data, mf->user);

	/*
	 *  break up name
	 */
	n = getfields(job->request.data, field, 4, 1, "!");
	switch(n){
	case 1:
		mf->net = strdup("net");
		mf->host = strdup(field[0]);
		break;
	case 4:
		mf->rem = strdup(field[3]);
		/* fall through */
	case 3:
		mf->serv = strdup(field[2]);
		/* fall through */
	case 2:
		mf->host = strdup(field[1]);
		mf->net = strdup(field[0]);
		break;
	}
	/*
	 *  do the first net worth of lookup
	 */
	if(lookup(mf) == 0){
		snprintf(curerr, sizeof curerr, "%r");
		err = curerr;
	}
send:
	job->reply.count = cnt;
	sendmsg(job, err);
}

void
rclunk(Job *job, Mfile *mf)
{
	cleanmf(mf);
	free(mf->user);
	mf->user = 0;
	mf->busy = 0;
	mf->fid = 0;
	sendmsg(job, 0);
}

void
rremove(Job *job, Mfile *mf)
{
	sendmsg(job, "remove permission denied");
}

void
rstat(Job *job, Mfile *mf)
{
	struct dir dir;
	uint8_t buf[IOHDRSZ+Maxfdata];

	memset(&dir, 0, sizeof dir);
	if(mf->qid.type & QTDIR){
		dir.name = ".";
		dir.mode = DMDIR|0555;
	} else {
		dir.name = "cs";
		dir.mode = 0666;
	}
	dir.qid = mf->qid;
	dir.length = 0;
	dir.uid = mf->user;
	dir.gid = mf->user;
	dir.muid = mf->user;
	//dir.atime = dir.mtime = time(0);
	job->reply.nstat = convD2M(&dir, buf, sizeof buf);
	job->reply.stat = buf;
	sendmsg(job, 0);
}

void
rwstat(Job *job, Mfile *mf)
{
	sendmsg(job, "wstat permission denied");
}

void
sendmsg(Job *job, char *err)
{
	int n;
	uint8_t mdata[IOHDRSZ + Maxfdata];
	char ename[ERRMAX];

	if(err){
		job->reply.type = Rerror;
		snprintf(ename, sizeof(ename), "cs: %s", err);
		job->reply.ename = ename;
	}else{
		job->reply.type = job->request.type+1;
	}
	job->reply.tag = job->request.tag;
	n = convS2M(&job->reply, mdata, sizeof mdata);
	if(n == 1){
		fprintf(stderr,  "CS:sendmsg convS2M of %F returns 0", &job->reply);
		abort();
	}
	//lock(&joblock);
	if(job->flushed == 0)
		if(write(mfd[1], mdata, n)!=n)
			error(1, 0, "%s: %r","mount write");
	//unlock(&joblock);
	if(debug)
		fprintf(stderr,  "CS:%F %d", &job->reply, n);
}

static int
isvalidip(uint8_t *ip)
{
	return ipcmp(ip, IPnoaddr) != 0 && ipcmp(ip, v4prefix) != 0;
}

static uint8_t loopbacknet[IPaddrlen] = {
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0xff, 0xff,
	127, 0, 0, 0
};
static uint8_t loopbackmask[IPaddrlen] = {
	0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff,
	0xff, 0, 0, 0
};

void
readipinterfaces(void)
{
	if(myipaddr(ipa, mntpt) != 0)
		ipmove(ipa, IPnoaddr);
	snprintf(ipaddr, sizeof(ipaddr), "%I", ipa);
	if (debug)
		fprintf(stderr, "CS:dns", "ipaddr is %s\n", ipaddr);
}

/*
 *  get the system name
 */
void
ipid(void)
{
	uint8_t addr[6];
	struct ndbtuple *t, *tt;
	char *p, *attr;
	struct ndbs s;
	int f;
	char buf[Maxpath];

	/* use environment, ether addr, or ipaddr to get system name */
	if(mysysname == 0){
		/*
		 *  environment has priority.
		 *
		 *  on the sgi power the default system name
		 *  is the ip address.  ignore that.
		 *
		 */
		p = getenv("sysname");
		if(p && *p){
			attr = ipattr(p);
			if(strcmp(attr, "ip") != 0)
				mysysname = strdup(p);
		}

		/*
		 *  the /net/ndb contains what the network
		 *  figured out from DHCP.  use that name if
		 *  there is one.
		 */
		if(mysysname == 0 && netdb != NULL){
			ndbreopen(netdb);
			for(tt = t = ndbparse(netdb); t != NULL; t = t->entry){
				if(strcmp(t->attr, "sys") == 0){
					mysysname = strdup(t->val);
					break;
				}
			}
			ndbfree(tt);
		}

		/* next network database, ip address, and ether address to find a name */
		if(mysysname == 0){
			t = NULL;
			if(isvalidip(ipa))
				free(ndbgetvalue(db, &s, "ip", ipaddr, "sys", &t));
			if(t == NULL){
				for(f = 0; f < 3; f++){
					snprintf(buf, sizeof buf, "%s/ether%d", mntpt, f);
					if(myetheraddr(addr, buf) >= 0){
						snprintf(eaddr, sizeof(eaddr), "%E", addr);
						free(ndbgetvalue(db, &s, "ether", eaddr, "sys", &t));
						if(t != NULL)
							break;
					}
				}
			}
			for(tt = t; tt != NULL; tt = tt->entry){
				if(strcmp(tt->attr, "sys") == 0){
					mysysname = strdup(tt->val);
					break;
				}
			}
			ndbfree(t);
		}

		/* nothing else worked, use the ip address */
		if(mysysname == 0 && isvalidip(ipa))
			mysysname = strdup(ipaddr);


		/* set /dev/sysname if we now know it */
		if(mysysname){
			f = open("/dev/sysname", O_RDWR);
			if(f >= 0){
				write(f, mysysname, strlen(mysysname));
				close(f);
			}
		}
	}
}

/*
 *  Set up a list of default networks by looking for
 *  /net/^*^/clone.
 *  For now, never background.
 */
void
netinit(int background)
{
	char clone[Maxpath];
	Network *np;
	static int working;

	/* add the mounted networks to the default list */
	for(np = network; np->net; np++){
		int fuckup;
		if(np->considered)
			continue;
		snprintf(clone, sizeof(clone), "%s/%s/clone", mntpt, np->net);
		fuckup = open(clone, O_RDONLY);
		if (fuckup < 0)
			continue;
		close(fuckup);
		//if(access(clone, R_OK))
			//continue;
		if(netlist)
			last->next = np;
		else
			netlist = np;
		last = np;
		np->next = 0;
		np->considered = 1;
	}

	/* find out what our ip address is */
	readipinterfaces();

	/* set the system name if we need to, these days ip is all we have */
	ipid();

	if(debug)
		fprintf(stderr, logfile, "CS:mysysname %s eaddr %s ipaddr %s ipa %I\n",
			mysysname?mysysname:"???", eaddr, ipaddr, ipa);

}

/*
 *  add networks to the standard list
 */
void
netadd(char *p)
{
	Network *np;
	char *field[12];
	int i, n;

	n = getfields(p, field, 12, 1, " ");
	for(i = 0; i < n; i++){
		for(np = network; np->net; np++){
			if(strcmp(field[i], np->net) != 0)
				continue;
			if(np->considered)
				break;
			if(netlist)
				last->next = np;
			else
				netlist = np;
			last = np;
			np->next = 0;
			np->considered = 1;
		}
	}
}

int
lookforproto(struct ndbtuple *t, char *proto)
{
	for(; t != NULL; t = t->entry)
		if(strcmp(t->attr, "proto") == 0 && strcmp(t->val, proto) == 0)
			return 1;
	return 0;
}

/*
 *  lookup a request.  the network "net" means we should pick the
 *  best network to get there.
 */
int
lookup(Mfile *mf)
{
	Network *np;
	char *cp;
	struct ndbtuple *nt, *t;
	char reply[Maxreply];
	int i, rv;
	int hack;

	/* open up the standard db files */
	if(db == 0)
		ndbinit();
	if(db == 0)
		error(1, 0, "%s: %r","can't open mf->network database\n");

	rv = 0;

	if(mf->net == NULL)
		return 0;	/* must have been a genquery */

	if(strcmp(mf->net, "net") == 0){
		/*
		 *  go through set of default nets
		 */
		for(np = mf->nextnet; np; np = np->next){
			nt = (*np->lookup)(np, mf->host, mf->serv, 1);
			if(nt == NULL)
				continue;
			hack = np->fasttimeouthack && !lookforproto(nt, np->net);
			for(t = nt; mf->nreply < Nreply && t; t = t->entry){
				cp = (*np->trans)(t, np, mf->serv, mf->rem, hack);
				if(cp){
					/* avoid duplicates */
					for(i = 0; i < mf->nreply; i++)
						if(strcmp(mf->reply[i], cp) == 0)
							break;
					if(i == mf->nreply){
						/* save the reply */
						mf->replylen[mf->nreply] = strlen(cp);
						mf->reply[mf->nreply++] = cp;
						rv++;
					}
				}
			}
			ndbfree(nt);
			np = np->next;
			break;
		}
		mf->nextnet = np;
		return rv;
	}

	/*
	 *  if not /net, we only get one lookup
	 */
	if(mf->nreply != 0)
		return 0;
	/*
	 *  look for a specific network
	 */
	for(np = netlist; np && np->net != NULL; np++){
		if(np->fasttimeouthack)
			continue;
		if(strcmp(np->net, mf->net) == 0)
			break;
	}

	if(np && np->net != NULL){
		/*
		 *  known network
		 */
		nt = (*np->lookup)(np, mf->host, mf->serv, 1);
		for(t = nt; mf->nreply < Nreply && t; t = t->entry){
			cp = (*np->trans)(t, np, mf->serv, mf->rem, 0);
			if(cp){
				mf->replylen[mf->nreply] = strlen(cp);
				mf->reply[mf->nreply++] = cp;
				rv++;
			}
		}
		ndbfree(nt);
		return rv;
	} else {
		/*
		 *  not a known network, don't translate host or service
		 */
		if(mf->serv)
			snprintf(reply, sizeof(reply), "%s/%s/clone %s!%s",
				mntpt, mf->net, mf->host, mf->serv);
		else
			snprintf(reply, sizeof(reply), "%s/%s/clone %s",
				mntpt, mf->net, mf->host);
		mf->reply[0] = strdup(reply);
		mf->replylen[0] = strlen(reply);
		mf->nreply = 1;
		return 1;
	}
}

/*
 *  translate an ip service name into a port number.  If it's a numeric port
 *  number, look for restricted access.
 *
 *  the service '*' needs no translation.
 */
char*
ipserv(Network *np, char *name, char *buf, int blen)
{
	char *p;
	int alpha = 0;
	int restr = 0;
	char port[10];
	struct ndbtuple *t, *nt;
	struct ndbs s;

	/* '*' means any service */
	if(strcmp(name, "*")==0){
		strcpy(buf, name);
		return buf;
	}

	/*  see if it's numeric or symbolic */
	port[0] = 0;
	for(p = name; *p; p++){
		if(isdigit(*p))
			{}
		else if(isalpha(*p) || *p == '-' || *p == '$')
			alpha = 1;
		else
			return 0;
	}
	t = NULL;
	p = NULL;
	if(alpha){
		p = ndbgetvalue(db, &s, np->net, name, "port", &t);
		if(p == NULL)
			return 0;
	} else {
		/* look up only for tcp ports < 1024 to get the restricted
		 * attribute
		 */
		if(atoi(name) < 1024 && strcmp(np->net, "tcp") == 0)
			p = ndbgetvalue(db, &s, "port", name, "port", &t);
		if(p == NULL)
			p = strdup(name);
	}

	if(t){
		for(nt = t; nt; nt = nt->entry)
			if(strcmp(nt->attr, "restricted") == 0)
				restr = 1;
		ndbfree(t);
	}
	snprintf(buf, blen, "%s%s", p, restr ? "!r" : "");
	free(p);
	return buf;
}

/*
 *  lookup an ip attribute
 */
int
ipattrlookup(struct ndb *db, char *ipa, char *attr, char *val, int vlen)
{

	struct ndbtuple *t, *nt;
	char *alist[2];

	alist[0] = attr;
	t = ndbipinfo(db, "ip", ipa, alist, 1);
	if(t == NULL)
		return 0;
	for(nt = t; nt != NULL; nt = nt->entry){
		if(strcmp(nt->attr, attr) == 0){
			nstrcpy(val, nt->val, vlen);
			ndbfree(t);
			return 1;
		}
	}

	/* we shouldn't get here */
	ndbfree(t);
	return 0;
}

/*
 *  lookup (and translate) an ip destination
 */
struct ndbtuple*
iplookup(Network *np, char *host, char *serv, int nolookup)
{
	char *attr, *dnsname;
	struct ndbtuple *t, *nt;
	struct ndbs s;
	char ts[Maxservice];
	char dollar[Maxhost];
	uint8_t ip[IPaddrlen];
	uint8_t net[IPaddrlen];
	uint8_t tnet[IPaddrlen];
	struct ipifc *ifc;
	struct iplifc *lifc;

	/*
	 *  start with the service since it's the most likely to fail
	 *  and costs the least
	 */
	werrstr("can't translate address");
	if(serv==0 || ipserv(np, serv, ts, sizeof ts) == 0){
		werrstr("can't translate service");
		return 0;
	}

	/* for dial strings with no host */
	if(strcmp(host, "*") == 0)
		return ndbnew("ip", "*");

	/*
	 *  hack till we go v6 :: = 0.0.0.0
	 */
	if(strcmp("::", host) == 0)
		return ndbnew("ip", "*");

	/*
	 *  '$' means the rest of the name is an attribute that we
	 *  need to search for
	 */
	if(*host == '$'){
		if(ipattrlookup(db, ipaddr, host+1, dollar, sizeof dollar))
			host = dollar;
	}

	/*
	 *  turn '[ip address]' into just 'ip address'
	 */
	if(*host == '[' && host[strlen(host)-1] == ']'){
		host++;
		host[strlen(host)-1] = 0;
	}

	/*
	 *  just accept addresses
	 */
	attr = ipattr(host);
	if(strcmp(attr, "ip") == 0)
		return ndbnew("ip", host);

	/*
	 *  give the domain name server the first opportunity to
	 *  resolve domain names.  if that fails try the database.
	 */
	t = 0;
	werrstr("can't translate address");
	if(strcmp(attr, "dom") == 0)
		t = dnsiplookup(host, &s);
	if(t == 0)
		free(ndbgetvalue(db, &s, attr, host, "ip", &t));
	if(t == 0){
		dnsname = ndbgetvalue(db, &s, attr, host, "dom", NULL);
		if(dnsname){
			t = dnsiplookup(dnsname, &s);
			free(dnsname);
		}
	}
	if(t == 0)
		t = dnsiplookup(host, &s);
	if(t == 0)
		return 0;

	/*
	 *  reorder the tuple to have the matched line first and
	 *  save that in the request structure.
	 */
	t = reorder(t, s.t);

	/*
	 * reorder according to our interfaces
	 */
	//lock(&ipifclock);
	for(ifc = ipifcs; ifc != NULL; ifc = ifc->next){
		for(lifc = ifc->lifc; lifc != NULL; lifc = lifc->next){
			maskip(lifc->ip, lifc->mask, net);
			for(nt = t; nt; nt = nt->entry){
				if(strcmp(nt->attr, "ip") != 0)
					continue;
				parseip(ip, nt->val);
				maskip(ip, lifc->mask, tnet);
				if(memcmp(net, tnet, IPaddrlen) == 0){
					t = reorder(t, nt);
					//unlock(&ipifclock);
					return t;
				}
			}
		}
	}
	//unlock(&ipifclock);

	return t;
}

/*
 *  translate an ip address
 */
char*
iptrans(struct ndbtuple *t, Network *np, char *serv, char *rem, int hack)
{
	char ts[Maxservice];
	char reply[Maxreply];
	char x[Maxservice];

	if(strcmp(t->attr, "ip") != 0)
		return 0;

	if(serv == 0 || ipserv(np, serv, ts, sizeof ts) == 0){
		werrstr("can't translate service");
		return 0;
	}
	if(rem != NULL)
		snprintf(x, sizeof(x), "!%s", rem);
	else
		*x = 0;

	if(*t->val == '*')
		snprintf(reply, sizeof(reply), "%s/%s/clone %s%s",
			mntpt, np->net, ts, x);
	else
		snprintf(reply, sizeof(reply), "%s/%s/clone %s!%s%s%s",
			mntpt, np->net, t->val, ts, x, hack? "!fasttimeout": "");

	return strdup(reply);
}

/*
 *  lookup a telephone number
 */
struct ndbtuple*
telcolookup(Network *np, char *host, char *serv, int nolookup)
{
	struct ndbtuple *t;
	struct ndbs s;

	werrstr("can't translate address");
	free(ndbgetvalue(db, &s, "sys", host, "telco", &t));
	if(t == 0)
		return ndbnew("telco", host);

	return reorder(t, s.t);
}

/*
 *  translate a telephone address
 */
char*
telcotrans(struct ndbtuple *t, Network *np, char *serv, char *rem, int unused)
{
	char reply[Maxreply];
	char x[Maxservice];

	if(strcmp(t->attr, "telco") != 0)
		return 0;

	if(rem != NULL)
		snprintf(x, sizeof(x), "!%s", rem);
	else
		*x = 0;
	if(serv)
		snprintf(reply, sizeof(reply), "%s/%s/clone %s!%s%s", mntpt, np->net,
			t->val, serv, x);
	else
		snprintf(reply, sizeof(reply), "%s/%s/clone %s%s", mntpt, np->net,
			t->val, x);
	return strdup(reply);
}

/*
 *  reorder the tuple to put x's line first in the entry
 */
struct ndbtuple*
reorder(struct ndbtuple *t, struct ndbtuple *x)
{
	struct ndbtuple *nt;
	struct ndbtuple *line;

	/* find start of this entry's line */
	for(line = x; line->entry == line->line; line = line->line)
		;
	line = line->line;
	if(line == t)
		return t;	/* already the first line */

	/* remove this line and everything after it from the entry */
	for(nt = t; nt->entry != line; nt = nt->entry)
		;
	nt->entry = 0;

	/* make that the start of the entry */
	for(nt = line; nt->entry; nt = nt->entry)
		;
	nt->entry = t;
	return line;
}

static struct ndbtuple*
dnsip6lookup(char *mntpt, char *buf, struct ndbtuple *t)
{
	struct ndbtuple *t6, *tt;

	t6 = dnsquery(mntpt, buf, "ipv6");	/* lookup AAAA dns RRs */
	if (t6 == NULL)
		return t;

	/* convert ipv6 attr to ip */
	for (tt = t6; tt != NULL; tt = tt->entry)
		if (strcmp(tt->attr, "ipv6") == 0)
			strncpy(tt->attr, "ip", sizeof tt->attr - 1);

	if (t == NULL)
		return t6;

	/* append t6 list to t list */
	for (tt = t; tt->entry != NULL; tt = tt->entry)
		;
	tt->entry = t6;
	return t;
}

/*
 *  call the dns process and have it try to translate a name
 */
struct ndbtuple*
dnsiplookup(char *host, struct ndbs *s)
{
	char buf[Maxreply];
	struct ndbtuple *t;

	//unlock(&dblock);

	/* save the name */
	snprintf(buf, sizeof(buf), "%s", host);

	if(strcmp(ipattr(buf), "ip") == 0)
		t = dnsquery(mntpt, buf, "ptr");
	else {
		t = dnsquery(mntpt, buf, "ip");
		/* special case: query ipv6 (AAAA dns RR) too */
		if (ipv6lookups)
			t = dnsip6lookup(mntpt, buf, t);
	}
	s->t = t;

	if(t == NULL){
		snprintf(buf, sizeof buf, "%r");
		if(strstr(buf, "exist"))
			werrstr("can't translate address: %s", buf);
		else if(strstr(buf, "dns failure"))
			werrstr("temporary problem: %s", buf);
	}

	//lock(&dblock);
	return t;
}

int
qmatch(struct ndbtuple *t, char **attr, char **val, int n)
{
	int i, found;
	struct ndbtuple *nt;

	for(i = 1; i < n; i++){
		found = 0;
		for(nt = t; nt; nt = nt->entry)
			if(strcmp(attr[i], nt->attr) == 0)
				if(strcmp(val[i], "*") == 0
				|| strcmp(val[i], nt->val) == 0){
					found = 1;
					break;
				}
		if(found == 0)
			break;
	}
	return i == n;
}

/* this is awful but I don't want to bring in libstring just for this.
 * you want real strings don't use C
 */
void
qreply(Mfile *mf, struct ndbtuple *t)
{
	struct ndbtuple *nt;
	char *s, *cur;
	int len, amt;

	s = malloc(4096);
	cur = s;
	len = 4096;

	for(nt = t; mf->nreply < Nreply && nt; nt = nt->entry){
		amt = snprintf(cur, len, "%s=%s", nt->attr, nt->val);

		if (amt < 0)
			len = 0;
		else {
			len -= amt;
			cur += amt;
		}

		if(nt->line != nt->entry){
			mf->replylen[mf->nreply] = strlen(s);
			mf->reply[mf->nreply++] = strdup(s);
			cur = s;
			len = 4096;
		} else {
			amt = snprintf(cur, len, " ");
			if (amt < 0)
				len = 0;
			else {
				len -= amt;
				cur += amt;
			}
		}

	}
	free(s);
}

enum
{
	Maxattr=	32,
};

/*
 *  generic query lookup.  The query is of one of the following
 *  forms:
 *
 *  attr1=val1 attr2=val2 attr3=val3 ...
 *
 *  returns the matching tuple
 *
 *  ipinfo attr=val attr1 attr2 attr3 ...
 *
 *  is like ipinfo and returns the attr{1-n}
 *  associated with the ip address.
 */
char*
genquery(Mfile *mf, char *query)
{
	int i, n;
	char *p;
	char *attr[Maxattr];
	char *val[Maxattr];
	struct ndbtuple *t;
	struct ndbs s;

	n = getfields(query, attr, ARRAY_SIZE(attr), 1, " ");
	if(n == 0)
		return "bad query";

	if(strcmp(attr[0], "ipinfo") == 0)
		return ipinfoquery(mf, attr, n);

	/* parse pairs */
	for(i = 0; i < n; i++){
		p = strchr(attr[i], '=');
		if(p == 0)
			return "bad query";
		*p++ = 0;
		val[i] = p;
	}

	/* give dns a chance */
	if((strcmp(attr[0], "dom") == 0 || strcmp(attr[0], "ip") == 0) && val[0]){
		t = dnsiplookup(val[0], &s);
		if(t){
			if(qmatch(t, attr, val, n)){
				qreply(mf, t);
				ndbfree(t);
				return 0;
			}
			ndbfree(t);
		}
	}

	/* first pair is always the key.  It can't be a '*' */
	t = ndbsearch(db, &s, attr[0], val[0]);

	/* search is the and of all the pairs */
	while(t){
		if(qmatch(t, attr, val, n)){
			qreply(mf, t);
			ndbfree(t);
			return 0;
		}

		ndbfree(t);
		t = ndbsnext(&s, attr[0], val[0]);
	}

	return "no match";
}

/*
 *  resolve an ip address
 */
static struct ndbtuple*
ipresolve(char *attr, char *host)
{
	struct ndbtuple *t, *nt, **l;

	t = iplookup(&network[Ntcp], host, "*", 0);
	for(l = &t; *l != NULL; ){
		nt = *l;
		if(strcmp(nt->attr, "ip") != 0){
			*l = nt->entry;
			nt->entry = NULL;
			ndbfree(nt);
			continue;
		}
		strcpy(nt->attr, attr);
		l = &nt->entry;
	}
	return t;
}

char*
ipinfoquery(Mfile *mf, char **list, int n)
{
	int i, nresolve;
	int resolve[Maxattr];
	struct ndbtuple *t, *nt, **l;
	char *attr, *val;

	/* skip 'ipinfo' */
	list++; n--;

	if(n < 1)
		return "bad query";

	/* get search attribute=value, or assume ip=myipaddr */
	attr = *list;
	if((val = strchr(attr, '=')) != NULL){
		*val++ = 0;
		list++;
		n--;
	}else{
		attr = "ip";
		val = ipaddr;
	}

	if(n < 1)
		return "bad query";

	/*
	 *  don't let ndbipinfo resolve the addresses, we're
	 *  better at it.
	 */
	nresolve = 0;
	for(i = 0; i < n; i++)
		if(*list[i] == '@'){		/* @attr=val ? */
			list[i]++;
			resolve[i] = 1;		/* we'll resolve it */
			nresolve++;
		} else
			resolve[i] = 0;

	t = ndbipinfo(db, attr, val, list, n);
	if(t == NULL)
		return "no match";

	if(nresolve != 0){
		for(l = &t; *l != NULL;){
			nt = *l;

			/* already an address? */
			if(strcmp(ipattr(nt->val), "ip") == 0){
				l = &(*l)->entry;
				continue;
			}

			/* user wants it resolved? */
			for(i = 0; i < n; i++)
				if(strcmp(list[i], nt->attr) == 0)
					break;
			if(i >= n || resolve[i] == 0){
				l = &(*l)->entry;
				continue;
			}

			/* resolve address and replace entry */
			*l = ipresolve(nt->attr, nt->val);
			while(*l != NULL)
				l = &(*l)->entry;
			*l = nt->entry;

			nt->entry = NULL;
			ndbfree(nt);
		}
	}

	/* make it all one line */
	for(nt = t; nt != NULL; nt = nt->entry){
		if(nt->entry == NULL)
			nt->line = t;
		else
			nt->line = nt->entry;
	}

	qreply(mf, t);

	return NULL;
}

void*
emalloc(int size)
{
	void *x;

	x = calloc(size, 1);
	if(x == NULL)
		abort();
	memset(x, 0, size);
	return x;
}

char*
estrdup(char *s)
{
	int size;
	char *p;

	size = strlen(s)+1;
	p = calloc(size, 1);
	if(p == NULL)
		abort();
	memmove(p, s, size);
	return p;
}
