Thanks to John Cummings.
This commit is contained in:
parent
cd37451963
commit
5cdb17983a
94 changed files with 26853 additions and 0 deletions
315
src/cmd/upas/send/rewrite.c
Normal file
315
src/cmd/upas/send/rewrite.c
Normal file
|
|
@ -0,0 +1,315 @@
|
|||
#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", unsharp(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)
|
||||
print("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){
|
||||
print("\t->");
|
||||
if(dp->repl1)
|
||||
print("%s", s_to_c(dp->repl1));
|
||||
if(dp->repl2)
|
||||
print("%s", s_to_c(dp->repl2));
|
||||
print("\n");
|
||||
}
|
||||
s_free(lower);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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
|
||||
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:"...");
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue