#include "common.h"
#include "send.h"

extern int debug;

/* 
 *	Routines for dealing with the rewrite rules.
 */

/* globals */
typedef struct rule rule;

#define NSUBEXP 10
struct rule {
	String *matchre;	/* address match */
	String *repl1;		/* first replacement String */
	String *repl2;		/* second replacement String */
	d_status type;		/* type of rule */
	Reprog *program;
	Resub subexp[NSUBEXP];
	rule *next;
};
static rule *rulep;
static rule *rlastp;

/* predeclared */
static String *substitute(String *, Resub *, message *);
static rule *findrule(String *, int);


/*
 *  Get the next token from `line'.  The symbol `\l' is replaced by
 *  the name of the local system.
 */
extern String *
rule_parse(String *line, char *system, int *backl)
{
	String *token;
	String *expanded;
	char *cp;

	token = s_parse(line, 0);
	if(token == 0)
		return(token);
	if(strchr(s_to_c(token), '\\')==0)
		return(token);
	expanded = s_new();
	for(cp = s_to_c(token); *cp; cp++) {
		if(*cp == '\\') switch(*++cp) {
		case 'l':
			s_append(expanded, system);
			*backl = 1;
			break;
		case '\\':
			s_putc(expanded, '\\');
			break;
		default:
			s_putc(expanded, '\\');
			s_putc(expanded, *cp);
			break;
		} else
			s_putc(expanded, *cp);
	}
	s_free(token);
	s_terminate(expanded);
	return(expanded);
}

static int
getrule(String *line, String *type, char *system)
{
	rule	*rp;
	String	*re;
	int	backl;

	backl = 0;

	/* get a rule */
	re = rule_parse(s_restart(line), system, &backl);
	if(re == 0)
		return 0;
	rp = (rule *)malloc(sizeof(rule));
	if(rp == 0) {
		perror("getrules:");
		exit(1);
	}
	rp->next = 0;
	s_tolower(re);
	rp->matchre = s_new();
	s_append(rp->matchre, s_to_c(re));
	s_restart(rp->matchre);
	s_free(re);
	s_parse(line, s_restart(type));
	rp->repl1 = rule_parse(line, system, &backl);
	rp->repl2 = rule_parse(line, system, &backl);
	rp->program = 0;
	if(strcmp(s_to_c(type), "|") == 0)
		rp->type = d_pipe;
	else if(strcmp(s_to_c(type), ">>") == 0)
		rp->type = d_cat;
	else if(strcmp(s_to_c(type), "alias") == 0)
		rp->type = d_alias;
	else if(strcmp(s_to_c(type), "translate") == 0)
		rp->type = d_translate;
	else if(strcmp(s_to_c(type), "auth") == 0)
		rp->type = d_auth;
	else {
		s_free(rp->matchre);
		s_free(rp->repl1);
		s_free(rp->repl2);
		free((char *)rp);
		fprint(2,"illegal rewrite rule: %s\n", s_to_c(line));
		return 0;
	}
	if(rulep == 0)
		rulep = rlastp = rp;
	else
		rlastp = rlastp->next = rp;
	return backl;
}

/*
 *  rules are of the form:
 *	<reg exp> <String> <repl exp> [<repl exp>]
 */
extern int
getrules(void)
{
	Biobuf	*rfp;
	String	*line;
	String	*type;
	String	*file;

	file = abspath("rewrite", UPASLIB, (String *)0);
	rfp = sysopen(s_to_c(file), "r", 0);
	if(rfp == 0) {
		rulep = 0;
		return -1;
	}
	rlastp = 0;
	line = s_new();
	type = s_new();
	while(s_getline(rfp, s_restart(line)))
		if(getrule(line, type, thissys) && altthissys)
			getrule(s_restart(line), type, altthissys);
	s_free(type);
	s_free(line);
	s_free(file);
	sysclose(rfp);
	return 0;
}

/* look up a matching rule */
static rule *
findrule(String *addrp, int authorized)
{
	rule *rp;
	static rule defaultrule;

	if(rulep == 0)
		return &defaultrule;
	for (rp = rulep; rp != 0; rp = rp->next) {
		if(rp->type==d_auth && authorized)
			continue;
		if(rp->program == 0)
			rp->program = regcomp(rp->matchre->base);
		if(rp->program == 0)
			continue;
		memset(rp->subexp, 0, sizeof(rp->subexp));
		if(debug)
			fprint(2, "matching %s aginst %s\n", s_to_c(addrp), rp->matchre->base);
		if(regexec(rp->program, s_to_c(addrp), rp->subexp, NSUBEXP))
		if(s_to_c(addrp) == rp->subexp[0].s.sp)
		if((s_to_c(addrp) + strlen(s_to_c(addrp))) == rp->subexp[0].e.ep)
			return rp;
	}
	return 0;
}

/*  Transforms the address into a command.
 *  Returns:	-1 ifaddress not matched by reules
 *		 0 ifaddress matched and ok to forward
 *		 1 ifaddress matched and not ok to forward
 */
extern int
rewrite(dest *dp, message *mp)
{
	rule *rp;		/* rewriting rule */
	String *lower;		/* lower case version of destination */

	/*
	 *  Rewrite the address.  Matching is case insensitive.
	 */
	lower = s_clone(dp->addr);
	s_tolower(s_restart(lower));
	rp = findrule(lower, dp->authorized);
	if(rp == 0){
		s_free(lower);
		return -1;
	}
	strcpy(s_to_c(lower), s_to_c(dp->addr));
	dp->repl1 = substitute(rp->repl1, rp->subexp, mp);
	dp->repl2 = substitute(rp->repl2, rp->subexp, mp);
	dp->status = rp->type;
	if(debug){
		fprint(2, "\t->");
		if(dp->repl1)
			fprint(2, "%s", s_to_c(dp->repl1));
		if(dp->repl2)
			fprint(2, "%s", s_to_c(dp->repl2));
		fprint(2, "\n");
	}
	s_free(lower);
	return 0;
}

/* stolen from rc/lex.c */
static int
idchr(int c)
{
	return c>' ' && !strchr("!\"#$%&'()+,-./:;<=>?@[\\]^`{|}~", c);
}

static char*
getrcvar(char* p, char** rv)
{
	char* p0;
	char buf[128];
	char* bufe;

	*rv = 0;
	p0=p;
	bufe=buf+sizeof buf-1;
	while(p<bufe && idchr(*p))
		p++;

	memcpy(buf, p0, p-p0);
	buf[p-p0]=0;
	*rv = getenv(buf);
	if (debug)
		fprint(2, "varsubst: %s → %s\n", buf, *rv);
	return p;
}

static String *
substitute(String *source, Resub *subexp, message *mp)
{
	int i;
	char *s;
	char *sp;
	String *stp;
	
	if(source == 0)
		return 0;
	sp = s_to_c(source);

	/* someplace to put it */
	stp = s_new();

	/* do the substitution */
	while (*sp != '\0') {
		if(*sp == '\\') {
			switch (*++sp) {
			case '0': case '1': case '2': case '3': case '4':
			case '5': case '6': case '7': case '8': case '9':
				i = *sp-'0';
				if(subexp[i].s.sp != 0)
					for (s = subexp[i].s.sp;
					     s < subexp[i].e.ep;
					     s++)
						s_putc(stp, *s);
				break;
			case '\\':
				s_putc(stp, '\\');
				break;
			case '\0':
				sp--;
				break;
			case 's':
				for(s = s_to_c(mp->replyaddr); *s; s++)
					s_putc(stp, *s);
				break;
			case 'p':
				if(mp->bulk)
					s = "bulk";
				else
					s = "normal";
				for(;*s; s++)
					s_putc(stp, *s);
				break;
			default:
				s_putc(stp, *sp);
				break;
			}
		} else if(*sp == '&') {			
			if(subexp[0].s.sp != 0)
				for (s = subexp[0].s.sp;
				     s < subexp[0].e.ep; s++)
					s_putc(stp, *s);
		} else if(*sp == '$') {
			sp = getrcvar(sp+1, &s);
			s_append(stp, s);
			free(s);
			sp--;	/* counter sp++ below */
		} else
			s_putc(stp, *sp);
		sp++;
	}
	s_terminate(stp);

	return s_restart(stp);
}

extern void
regerror(char* s)
{
	fprint(2, "rewrite: %s\n", s);
}

extern void
dumprules(void)
{
	rule *rp;

	for (rp = rulep; rp != 0; rp = rp->next) {
		fprint(2, "'%s'", rp->matchre->base);
		switch (rp->type) {
		case d_pipe:
			fprint(2, " |");
			break;
		case d_cat:
			fprint(2, " >>");
			break;
		case d_alias:
			fprint(2, " alias");
			break;
		case d_translate:
			fprint(2, " translate");
			break;
		default:
			fprint(2, " UNKNOWN");
			break;
		}
		fprint(2, " '%s'", rp->repl1 ? rp->repl1->base:"...");
		fprint(2, " '%s'\n", rp->repl2 ? rp->repl2->base:"...");
	}
}

