#include <u.h>
#include <libc.h>
#include <bio.h>
#include <ndb.h>
#include <ip.h>
#include "dns.h"

static Ndb *db;

static RR*	dblookup1(char*, int, int, int);
static RR*	addrrr(Ndbtuple*, Ndbtuple*);
static RR*	nsrr(Ndbtuple*, Ndbtuple*);
static RR*	cnamerr(Ndbtuple*, Ndbtuple*);
static RR*	mxrr(Ndbtuple*, Ndbtuple*);
static RR*	soarr(Ndbtuple*, Ndbtuple*);
static RR*	ptrrr(Ndbtuple*, Ndbtuple*);
static Ndbtuple* look(Ndbtuple*, Ndbtuple*, char*);
static RR*	doaxfr(Ndb*, char*);
static RR*	nullrr(Ndbtuple *entry, Ndbtuple *pair);
static RR*	txtrr(Ndbtuple *entry, Ndbtuple *pair);
static Lock	dblock;
static void	createptrs(void);

static int	implemented[Tall] =
{
	[Ta]		1,
	[Tns]		1,
	[Tsoa]		1,
	[Tmx]		1,
	[Tptr]		1,
	[Tcname]	1,
	[Tnull]		1,
	[Ttxt]		1,
};

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

int
opendatabase(void)
{
	char buf[256];
	Ndb *xdb;

	if(db == nil){
		snprint(buf, sizeof(buf), "%s/ndb", mntpt);
		xdb = ndbopen(dbfile);
		if(xdb != nil)
			xdb->nohash = 1;
		db = ndbcat(ndbopen(buf), xdb);
	}
	if(db == nil)
		return -1;
	else
		return 0;
}

/*
 *  lookup an RR in the network database, look for matches
 *  against both the domain name and the wildcarded domain name.
 *
 *  the lock makes sure only one process can be accessing the data
 *  base at a time.  This is important since there's a lot of
 *  shared state there.
 *
 *  e.g. for x.research.bell-labs.com, first look for a match against
 *       the x.research.bell-labs.com.  If nothing matches, try *.research.bell-labs.com.
 */
RR*
dblookup(char *name, int class, int type, int auth, int ttl)
{
	RR *rp, *tp;
	char buf[256];
	char *wild, *cp;
	DN *dp, *ndp;
	int err;
	static int parallel;
	static int parfd[2];
	static char token[1];

	/* so far only internet lookups are implemented */
	if(class != Cin)
		return 0;

	err = Rname;

	if(type == Tall){
		rp = 0;
		for (type = Ta; type < Tall; type++)
			if(implemented[type])
				rrcat(&rp, dblookup(name, class, type, auth, ttl));
		return rp;
	}

	lock(&dblock);
	dp = dnlookup(name, class, 1);
	if(opendatabase() < 0)
		goto out;
	if(dp->rr)
		err = 0;

	/* first try the given name */
	rp = 0;
	if(cachedb)
		rp = rrlookup(dp, type, NOneg);
	else
		rp = dblookup1(name, type, auth, ttl);
	if(rp)
		goto out;

	/* try lower case version */
	for(cp = name; *cp; cp++)
		*cp = tolower(*cp);
	if(cachedb)
		rp = rrlookup(dp, type, NOneg);
	else
		rp = dblookup1(name, type, auth, ttl);
	if(rp)
		goto out;

	/* walk the domain name trying the wildcard '*' at each position */
	for(wild = strchr(name, '.'); wild; wild = strchr(wild+1, '.')){
		snprint(buf, sizeof(buf), "*%s", wild);
		ndp = dnlookup(buf, class, 1);
		if(ndp->rr)
			err = 0;
		if(cachedb)
			rp = rrlookup(ndp, type, NOneg);
		else
			rp = dblookup1(buf, type, auth, ttl);
		if(rp)
			break;
	}
out:
	/* add owner to uncached records */
	if(rp){
		for(tp = rp; tp; tp = tp->next)
			tp->owner = dp;
	} else {
		/* don't call it non-existent if it's not ours */
		if(err == Rname && !inmyarea(name))
			err = Rserver;
		dp->nonexistent = err;
	}

	unlock(&dblock);
	return rp;
}

/*
 *  lookup an RR in the network database
 */
static RR*
dblookup1(char *name, int type, int auth, int ttl)
{
	Ndbtuple *t, *nt;
	RR *rp, *list, **l;
	Ndbs s;
	char dname[Domlen];
	char *attr;
	DN *dp;
	RR *(*f)(Ndbtuple*, Ndbtuple*);
	int found, x;

	dp = 0;
	switch(type){
	case Tptr:
		attr = "ptr";
		f = ptrrr;
		break;
	case Ta:
		attr = "ip";
		f = addrrr;
		break;
	case Tnull:
		attr = "nullrr";
		f = nullrr;
		break;
	case Tns:
		attr = "ns";
		f = nsrr;
		break;
	case Tsoa:
		attr = "soa";
		f = soarr;
		break;
	case Tmx:
		attr = "mx";
		f = mxrr;
		break;
	case Tcname:
		attr = "cname";
		f = cnamerr;
		break;
	case Taxfr:
	case Tixfr:
		return doaxfr(db, name);
	default:
		return nil;
	}

	/*
	 *  find a matching entry in the database
	 */
	free(ndbgetvalue(db, &s, "dom", name, attr, &t));

	/*
	 *  hack for local names
	 */
	if(t == 0 && strchr(name, '.') == 0)
		free(ndbgetvalue(db, &s, "sys", name, attr, &t));
	if(t == 0)
		return nil;

	/* search whole entry for default domain name */
	strncpy(dname, name, sizeof dname);
	for(nt = t; nt; nt = nt->entry)
		if(strcmp(nt->attr, "dom") == 0){
			nstrcpy(dname, nt->val, sizeof dname);
			break;
		}

	/* ttl is maximum of soa minttl and entry's ttl ala rfc883 */
	nt = look(t, s.t, "ttl");
	if(nt){
		x = atoi(nt->val);
		if(x > ttl)
			ttl = x;
	}

	/* default ttl is one day */
	if(ttl < 0)
		ttl = DEFTTL;

	/*
	 *  The database has 2 levels of precedence; line and entry.
	 *  Pairs on the same line bind tighter than pairs in the
	 *  same entry, so we search the line first.
	 */
	found = 0;
	list = 0;
	l = &list;
	for(nt = s.t;; ){
		if(found == 0 && strcmp(nt->attr, "dom") == 0){
			nstrcpy(dname, nt->val, sizeof dname);
			found = 1;
		}
		if(cistrcmp(attr, nt->attr) == 0){
			rp = (*f)(t, nt);
			rp->auth = auth;
			rp->db = 1;
			if(ttl)
				rp->ttl = ttl;
			if(dp == 0)
				dp = dnlookup(dname, Cin, 1);
			rp->owner = dp;
			*l = rp;
			l = &rp->next;
			nt->ptr = 1;
		}
		nt = nt->line;
		if(nt == s.t)
			break;
	}

	/* search whole entry */
	for(nt = t; nt; nt = nt->entry)
		if(nt->ptr == 0 && cistrcmp(attr, nt->attr) == 0){
			rp = (*f)(t, nt);
			rp->db = 1;
			if(ttl)
				rp->ttl = ttl;
			rp->auth = auth;
			if(dp == 0)
				dp = dnlookup(dname, Cin, 1);
			rp->owner = dp;
			*l = rp;
			l = &rp->next;
		}
	ndbfree(t);

	return list;
}

/*
 *  make various types of resource records from a database entry
 */
static RR*
addrrr(Ndbtuple *entry, Ndbtuple *pair)
{
	RR *rp;
	uchar addr[IPaddrlen];

	USED(entry);
	parseip(addr, pair->val);
	if(isv4(addr))
		rp = rralloc(Ta);
	else
		rp = rralloc(Taaaa);
	rp->ip = dnlookup(pair->val, Cin, 1);
	return rp;
}
static RR*
nullrr(Ndbtuple *entry, Ndbtuple *pair)
{
	RR *rp;

	USED(entry);
	rp = rralloc(Tnull);
	rp->null->data = (uchar*)estrdup(pair->val);
	rp->null->dlen = strlen((char*)rp->null->data);
	return rp;
}
/*
 *  txt rr strings are at most 255 bytes long.  one
 *  can represent longer strings by multiple concatenated
 *  <= 255 byte ones.
 */
static RR*
txtrr(Ndbtuple *entry, Ndbtuple *pair)
{
	RR *rp;
	Txt *t, **l;
	int i, len, sofar;

	USED(entry);
	rp = rralloc(Ttxt);
	l = &rp->txt;
	rp->txt = nil;
	len = strlen(pair->val);
	sofar = 0;
	while(len > sofar){
		t = emalloc(sizeof(*t));
		t->next = nil;

		i = len-sofar;
		if(i > 255)
			i = 255;

		t->p = emalloc(i+1);
		memmove(t->p, pair->val+sofar, i);
		t->p[i] = 0;
		sofar += i;

		*l = t;
		l = &t->next;
	}
	return rp;
}
static RR*
cnamerr(Ndbtuple *entry, Ndbtuple *pair)
{
	RR *rp;

	USED(entry);
	rp = rralloc(Tcname);
	rp->host = dnlookup(pair->val, Cin, 1);
	return rp;
}
static RR*
mxrr(Ndbtuple *entry, Ndbtuple *pair)
{
	RR * rp;

	rp = rralloc(Tmx);
	rp->host = dnlookup(pair->val, Cin, 1);
	pair = look(entry, pair, "pref");
	if(pair)
		rp->pref = atoi(pair->val);
	else
		rp->pref = 1;
	return rp;
}
static RR*
nsrr(Ndbtuple *entry, Ndbtuple *pair)
{
	RR *rp;
	Ndbtuple *t;

	rp = rralloc(Tns);
	rp->host = dnlookup(pair->val, Cin, 1);
	t = look(entry, pair, "soa");
	if(t && t->val[0] == 0)
		rp->local = 1;
	return rp;
}
static RR*
ptrrr(Ndbtuple *entry, Ndbtuple *pair)
{
	RR *rp;

	USED(entry);
	rp = rralloc(Tns);
	rp->ptr = dnlookup(pair->val, Cin, 1);
	return rp;
}
static RR*
soarr(Ndbtuple *entry, Ndbtuple *pair)
{
	RR *rp;
	Ndbtuple *ns, *mb, *t;
	char mailbox[Domlen];
	Ndb *ndb;
	char *p;

	rp = rralloc(Tsoa);
	rp->soa->serial = 1;
	for(ndb = db; ndb; ndb = ndb->next)
		if(ndb->mtime > rp->soa->serial)
			rp->soa->serial = ndb->mtime;
	rp->soa->refresh = Day;
	rp->soa->retry = Hour;
	rp->soa->expire = Day;
	rp->soa->minttl = Day;
	t = look(entry, pair, "ttl");
	if(t)
		rp->soa->minttl = atoi(t->val);
	t = look(entry, pair, "refresh");
	if(t)
		rp->soa->refresh = atoi(t->val);
	t = look(entry, pair, "serial");
	if(t)
		rp->soa->serial = strtoul(t->val, 0, 10);

	ns = look(entry, pair, "ns");
	if(ns == 0)
		ns = look(entry, pair, "dom");
	rp->host = dnlookup(ns->val, Cin, 1);

	/* accept all of:
	 *  mbox=person
	 *  mbox=person@machine.dom
	 *  mbox=person.machine.dom
	 */
	mb = look(entry, pair, "mbox");
	if(mb == nil)
		mb = look(entry, pair, "mb");
	if(mb){
		if(strchr(mb->val, '.')) {
			p = strchr(mb->val, '@');
			if(p != nil)
				*p = '.';
			rp->rmb = dnlookup(mb->val, Cin, 1);
		} else {
			snprint(mailbox, sizeof(mailbox), "%s.%s",
				mb->val, ns->val);
			rp->rmb = dnlookup(mailbox, Cin, 1);
		}
	} else {
		snprint(mailbox, sizeof(mailbox), "postmaster.%s",
			ns->val);
		rp->rmb = dnlookup(mailbox, Cin, 1);
	}

	/*  hang dns slaves off of the soa.  this is 
	 *  for managing the area.
	 */
	for(t = entry; t != nil; t = t->entry)
		if(strcmp(t->attr, "dnsslave") == 0)
			addserver(&rp->soa->slaves, t->val);
			
	return rp;
}

/*
 *  Look for a pair with the given attribute.  look first on the same line,
 *  then in the whole entry.
 */
static Ndbtuple*
look(Ndbtuple *entry, Ndbtuple *line, char *attr)
{
	Ndbtuple *nt;

	/* first look on same line (closer binding) */
	for(nt = line;;){
		if(cistrcmp(attr, nt->attr) == 0)
			return nt;
		nt = nt->line;
		if(nt == line)
			break;
	}
	/* search whole tuple */
	for(nt = entry; nt; nt = nt->entry)
		if(cistrcmp(attr, nt->attr) == 0)
			return nt;
	return 0;
}

static RR**
linkrr(RR *rp, DN *dp, RR **l)
{
	rp->owner = dp;
	rp->auth = 1;
	rp->db = 1;
	*l = rp;
	return &rp->next;
}

/* these are answered specially by the tcp version */
static RR*
doaxfr(Ndb *db, char *name)
{
	USED(db);
	USED(name);
	return 0;
}


/*
 *  read the all the soa's from the database to determine area's.
 *  this is only used when we're not caching the database.
 */
static void
dbfile2area(Ndb *db)
{
	Ndbtuple *t;

	if(debug)
		syslog(0, logfile, "rereading %s", db->file);
	Bseek(&db->b, 0, 0);
	while(t = ndbparse(db)){
		ndbfree(t);
	}
}

/*
 *  read the database into the cache
 */
static void
dbpair2cache(DN *dp, Ndbtuple *entry, Ndbtuple *pair)
{
	RR *rp;
	Ndbtuple *t;
	static ulong ord;

	rp = 0;
	if(cistrcmp(pair->attr, "ip") == 0){
		dp->ordinal = ord++;
		rp = addrrr(entry, pair);
	} else 	if(cistrcmp(pair->attr, "ns") == 0){
		rp = nsrr(entry, pair);
	} else if(cistrcmp(pair->attr, "soa") == 0){
		rp = soarr(entry, pair);
		addarea(dp, rp, pair);
	} else if(cistrcmp(pair->attr, "mx") == 0){
		rp = mxrr(entry, pair);
	} else if(cistrcmp(pair->attr, "cname") == 0){
		rp = cnamerr(entry, pair);
	} else if(cistrcmp(pair->attr, "nullrr") == 0){
		rp = nullrr(entry, pair);
	} else if(cistrcmp(pair->attr, "txtrr") == 0){
		rp = txtrr(entry, pair);
	}

	if(rp == 0)
		return;

	rp->owner = dp;
	rp->db = 1;
	t = look(entry, pair, "ttl");
	if(t)
		rp->ttl = atoi(t->val);
	rrattach(rp, 0);
}
static void
dbtuple2cache(Ndbtuple *t)
{
	Ndbtuple *et, *nt;
	DN *dp;

	for(et = t; et; et = et->entry){
		if(strcmp(et->attr, "dom") == 0){
			dp = dnlookup(et->val, Cin, 1);

			/* first same line */
			for(nt = et->line; nt != et; nt = nt->line){
				dbpair2cache(dp, t, nt);
				nt->ptr = 1;
			}

			/* then rest of entry */
			for(nt = t; nt; nt = nt->entry){
				if(nt->ptr == 0)
					dbpair2cache(dp, t, nt);
				nt->ptr = 0;
			}
		}
	}
}
static void
dbfile2cache(Ndb *db)
{
	Ndbtuple *t;

	if(debug)
		syslog(0, logfile, "rereading %s", db->file);
	Bseek(&db->b, 0, 0);
	while(t = ndbparse(db)){
		dbtuple2cache(t);
		ndbfree(t);
	}
}
void
db2cache(int doit)
{
	Ndb *ndb;
	Dir *d;
	ulong youngest, temp;
	static ulong lastcheck;
	static ulong lastyoungest;

	/* no faster than once every 2 minutes */
	if(now < lastcheck + 2*Min && !doit)
		return;

	refresh_areas(owned);

	lock(&dblock);

	if(opendatabase() < 0){
		unlock(&dblock);
		return;
	}

	/*
	 *  file may be changing as we are reading it, so loop till
	 *  mod times are consistent.
	 *
	 *  we don't use the times in the ndb records because they may
	 *  change outside of refreshing our cached knowledge.
	 */
	for(;;){
		lastcheck = now;
		youngest = 0;
		for(ndb = db; ndb; ndb = ndb->next){
			/* the dirfstat avoids walking the mount table each time */
			if((d = dirfstat(Bfildes(&ndb->b))) != nil ||
			   (d = dirstat(ndb->file)) != nil){
				temp = d->mtime;		/* ulong vs int crap */
				if(temp > youngest)
					youngest = temp;
				free(d);
			}
		}
		if(!doit && youngest == lastyoungest){
			unlock(&dblock);
			return;
		}
	
		/* forget our area definition */
		freearea(&owned);
		freearea(&delegated);
	
		/* reopen all the files (to get oldest for time stamp) */
		for(ndb = db; ndb; ndb = ndb->next)
			ndbreopen(ndb);

		if(cachedb){
			/* mark all db records as timed out */
			dnagedb();
	
			/* read in new entries */
			for(ndb = db; ndb; ndb = ndb->next)
				dbfile2cache(ndb);
	
			/* mark as authentic anything in our domain */
			dnauthdb();
	
			/* remove old entries */
			dnageall(1);
		} else {
			/* read all the soa's to get database defaults */
			for(ndb = db; ndb; ndb = ndb->next)
				dbfile2area(ndb);
		}

		doit = 0;
		lastyoungest = youngest;
		createptrs();
	}

	unlock(&dblock);
}

extern uchar	ipaddr[IPaddrlen];

/*
 *  get all my xxx
 */
Ndbtuple*
lookupinfo(char *attr)
{
	char buf[64];
	char *a[2];
	static Ndbtuple *t;

	snprint(buf, sizeof buf, "%I", ipaddr);
	a[0] = attr;
	
	lock(&dblock);
	if(opendatabase() < 0){
		unlock(&dblock);
		return nil;
	}
	t = ndbipinfo(db, "ip", buf, a, 1);
	unlock(&dblock);
	return t;
}

char *localservers = "local#dns#servers";
char *localserverprefix = "local#dns#server";

/*
 *  return non-zero is this is a bad delegation
 */
int
baddelegation(RR *rp, RR *nsrp, uchar *addr)
{
	Ndbtuple *nt;
	static Ndbtuple *t;

	if(t == nil)
		t = lookupinfo("dom");
	if(t == nil)
		return 0;

	for(; rp; rp = rp->next){
		if(rp->type != Tns)
			continue;

		/* see if delegation is looping */
		if(nsrp)
		if(rp->owner != nsrp->owner)
		if(subsume(rp->owner->name, nsrp->owner->name) &&
		   strcmp(nsrp->owner->name, localservers) != 0){
			syslog(0, logfile, "delegation loop %R -> %R from %I", nsrp, rp, addr);
			return 1;
		}

		/* see if delegating to us what we don't own */
		for(nt = t; nt != nil; nt = nt->entry)
			if(rp->host && cistrcmp(rp->host->name, nt->val) == 0)
				break;
		if(nt != nil && !inmyarea(rp->owner->name)){
			syslog(0, logfile, "bad delegation %R from %I", rp, addr);
			return 1;
		}
	}

	return 0;
}

static void
addlocaldnsserver(DN *dp, int class, char *ipaddr, int i)
{
	DN *nsdp;
	RR *rp;
	char buf[32];

	/* ns record for name server, make up an impossible name */
	rp = rralloc(Tns);
	snprint(buf, sizeof(buf), "%s%d", localserverprefix, i);
	nsdp = dnlookup(buf, class, 1);
	rp->host = nsdp;
	rp->owner = dp;
	rp->local = 1;
	rp->db = 1;
	rp->ttl = 10*Min;
	rrattach(rp, 1);

print("dns %s\n", ipaddr);
	/* A record */
	rp = rralloc(Ta);
	rp->ip = dnlookup(ipaddr, class, 1);
	rp->owner = nsdp;
	rp->local = 1;
	rp->db = 1;
	rp->ttl = 10*Min;
	rrattach(rp, 1);
}

/*
 *  return list of dns server addresses to use when
 *  acting just as a resolver.
 */
RR*
dnsservers(int class)
{
	Ndbtuple *t, *nt;
	RR *nsrp;
	DN *dp;
	char *p;
	int i, n;
	char *buf, *args[5];

	dp = dnlookup(localservers, class, 1);
	nsrp = rrlookup(dp, Tns, NOneg);
	if(nsrp != nil)
		return nsrp;

	p = getenv("DNSSERVER");
	if(p != nil){
		buf = estrdup(p);
		n = tokenize(buf, args, nelem(args));
		for(i = 0; i < n; i++)
			addlocaldnsserver(dp, class, args[i], i);
		free(buf);
	} else {
		t = lookupinfo("@dns");
		if(t == nil)
			return nil;
		i = 0;
		for(nt = t; nt != nil; nt = nt->entry){
			addlocaldnsserver(dp, class, nt->val, i);
			i++;
		}
		ndbfree(t);
	}

	return rrlookup(dp, Tns, NOneg);
}

static void
addlocaldnsdomain(DN *dp, int class, char *domain)
{
	RR *rp;

	/* A record */
	rp = rralloc(Tptr);
	rp->ptr = dnlookup(domain, class, 1);
	rp->owner = dp;
	rp->db = 1;
	rp->ttl = 10*Min;
	rrattach(rp, 1);
}

/*
 *  return list of domains to use when resolving names without '.'s
 */
RR*
domainlist(int class)
{
	Ndbtuple *t, *nt;
	RR *rp;
	DN *dp;

	dp = dnlookup("local#dns#domains", class, 1);
	rp = rrlookup(dp, Tptr, NOneg);
	if(rp != nil)
		return rp;

	t = lookupinfo("dnsdomain");
	if(t == nil)
		return nil;
	for(nt = t; nt != nil; nt = nt->entry)
		addlocaldnsdomain(dp, class, nt->val);
	ndbfree(t);

	return rrlookup(dp, Tptr, NOneg);
}

char *v4ptrdom = ".in-addr.arpa";
char *v6ptrdom = ".ip6.arpa";		/* ip6.int deprecated, rfc 3152 */

char *attribs[] = {
	"ipmask",
	0
};

/*
 *  create ptrs that are in our areas
 */
static void
createptrs(void)
{
	int len, dlen, n;
	Area *s;
	char *f[40];
	char buf[Domlen+1];
	uchar net[IPaddrlen];
	uchar mask[IPaddrlen];
	char ipa[48];
	Ndbtuple *t, *nt;

	dlen = strlen(v4ptrdom);
	for(s = owned; s; s = s->next){
		len = strlen(s->soarr->owner->name);
		if(len <= dlen)
			continue;
		if(cistrcmp(s->soarr->owner->name+len-dlen, v4ptrdom) != 0)
			continue;

		/* get mask and net value */
		strncpy(buf, s->soarr->owner->name, sizeof(buf));
		buf[sizeof(buf)-1] = 0;
		n = getfields(buf, f, nelem(f), 0, ".");
		memset(mask, 0xff, IPaddrlen);
		ipmove(net, v4prefix);
		switch(n){
		case 3: /* /8 */
			net[IPv4off] = atoi(f[0]);
			mask[IPv4off+1] = 0;
			mask[IPv4off+2] = 0;
			mask[IPv4off+3] = 0;
			break;
		case 4: /* /16 */
			net[IPv4off] = atoi(f[1]);
			net[IPv4off+1] = atoi(f[0]);
			mask[IPv4off+2] = 0;
			mask[IPv4off+3] = 0;
			break;
		case 5: /* /24 */
			net[IPv4off] = atoi(f[2]);
			net[IPv4off+1] = atoi(f[1]);
			net[IPv4off+2] = atoi(f[0]);
			mask[IPv4off+3] = 0;
			break;
		case 6:	/* rfc2317 */
			net[IPv4off] = atoi(f[3]);
			net[IPv4off+1] = atoi(f[2]);
			net[IPv4off+2] = atoi(f[1]);
			net[IPv4off+3] = atoi(f[0]);
			sprint(ipa, "%I", net);
			t = ndbipinfo(db, "ip", ipa, attribs, 1);
			if(t == nil) /* could be a reverse with no forward */
				continue;
			nt = look(t, t, "ipmask");
			if(nt == nil){	/* we're confused */
				ndbfree(t);
				continue;
			}
			parseipmask(mask, nt->val);
			n = 5;
			break;
		default:
			continue;
		}

		/* go through all domain entries looking for RR's in this network and create ptrs */
		dnptr(net, mask, s->soarr->owner->name, 6-n, 0);
	}
}
