/* 
 * 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, strlen(servefile),
	        (unsigned long)mntpt, strlen(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;
}
