/* pathalias -- by steve bellovin, as told to peter honeyman */
#ifndef lint
static char	*sccsid = "@(#)domain.c	9.5 92/08/25";
static char	*rcsid = "@(#)smail/pd/pathalias:RELEASE-3_2_0_108:domain.c,v 1.6 1998/11/06 19:58:38 woods Exp";
#endif /* lint */

#define NEED_SOCKETS			/* only for smail-3 */
#include "def.h"

/* imports */
extern dom *newdom();
extern void die();
extern char *strsave();
extern int errno, Vflag;

/* exports */
int ondomlist();
int nslookup();
void adddom();
void movetofront();

/* privates */
static dom *good, *bad;

/*
 * good and bad are passed by reference for move-to-front
 */
int
isadomain(domain)
	char *domain;
{

	if (ondomlist(&good, domain)) {
		Vprintf(stderr, "%s on\n", domain);
		return 1;
	}

	if (ondomlist(&bad, domain)) {
		Vprintf(stderr, "%s off\n", domain);
		return 0;
	}

	if (nslookup(domain)) {
		adddom(&good, domain);
		Vprintf(stderr, "%s add\n", domain);
		return 1;
	} else {
		adddom(&bad, domain);
		Vprintf(stderr, "%s del\n", domain);
		return 0;
	}
}

int
ondomlist(headp, domain)
	dom **headp;
	char *domain;
{	dom *d, *head = *headp;

	for (d = head; d != 0; d = d->next) {
		if (strcmp(d->name, domain) == 0) {
			if (d != head)
				movetofront(headp, d);
			return 1;
		}
	}
	return 0;
}


void			
adddom(headp, domain)
	dom **headp;
	char *domain;
{	dom *d, *head = *headp;

	d = newdom();
	d->next = head;
	d->name = strsave(domain);
	if (d->next)
		d->next->prev = d;
	*headp = d;
}

void
movetofront(headp, d)
	dom **headp, *d;
{	dom *head = *headp;

	if (d->prev)
		d->prev->next = d->next;
	if (d->next)
		d->next->prev = d->prev;
	if (head)
		head->prev = d;
	d->next = head;
	*headp = d;
}

#ifdef RESOLVER
int
nslookup(domain)
	char *domain;
{	register HEADER *hp;
	register int n;
	char q[PACKETSZ], a[PACKETSZ];	/* query, answer */
	char buf[PACKETSZ+1];

	if ((n = strlen(domain)) >= PACKETSZ)
		return 0;
	strcpy(buf, domain);
	if (buf[n-1] != '.') {
		buf[n++] = '.';
		buf[n] = 0;
	}
	/*
	 * LIES! DAMN LIES!
	 * 
	 * The manual page resolver(3) says arg#7 is (struct rrec *) but the
	 * prototypes say (const char *), others say (const u_char *).
	 * 
	 * Note though that res_mkquery() is not used by the rest of
	 * smail-3 if OBSOLETE_ERSOLVER is defined [XXX use res_search()].
	 */
	if ((n = res_mkquery(QUERY, buf, C_IN, T_ANY, (unsigned char *) NULL, 0,
			     (struct rrec *) NULL, (unsigned char *) q,
			     sizeof(q))) < 0)
		die("impossible res_mkquery error");
	errno = 0;
	if ((n = res_send((unsigned char *) q, n, (unsigned char *) a, sizeof(a))) < 0)
		die("res_send");
	hp = (HEADER *) a;
	if (hp->rcode == NOERROR)
		return 1;
	return 0;
}
#else /*!RESOLVER*/
/*ARGSUSED*/
int
nslookup(domain)
	char *domain;
{
	return 0;	/* i guess !?! */
}
#endif /*RESOLVER*/

