Annotation of researchv10no/cmd/upas/send/rewrite.c, revision 1.1.1.1

1.1       root        1: #include <stdio.h>
                      2: #include <regexp.h>
                      3: #include "mail.h"
                      4: #include "string.h"
                      5: #include "dest.h"
                      6: #include "aux.h"
                      7: 
                      8: /* configuration */
                      9: #define RULEFILE "rewrite"
                     10: 
                     11: /* 
                     12:  *     Routines for dealing with the rewrite rules.
                     13:  */
                     14: 
                     15: /* imports */
                     16: extern char *malloc();
                     17: extern regexp *regcomp();
                     18: extern int regexec();
                     19: extern void regsub();
                     20: extern void exit();
                     21: extern char *thissys;
                     22: 
                     23: /* globals */
                     24: typedef struct rule rule;
                     25: 
                     26: #define NSUBEXP 10
                     27: struct rule {
                     28:        string *matchre;        /* address match */
                     29:        string *repl1;          /* first replacement string */
                     30:        string *repl2;          /* second replacement string */
                     31:        d_status type;          /* type of rule */
                     32:        regexp *program;
                     33:        regsubexp subexp[NSUBEXP];
                     34:        rule *next;
                     35: };
                     36: static rule *rulep;
                     37: 
                     38: /* predeclared */
                     39: static string *substitute();
                     40: 
                     41: /*
                     42:  *  Get the next token from `line'.  The symbol `\l' is replaced by
                     43:  *  the name of the local system.
                     44:  */
                     45: string *
                     46: rule_parse(line)
                     47:        string *line;
                     48: {
                     49:        string *token;
                     50:        string *expanded = (string *)NULL;
                     51:        char *cp;
                     52: 
                     53:        token = s_parse(line, (string *)NULL);
                     54:        if(token == (string *)NULL)
                     55:                return(token);
                     56:        if ((cp = strchr(s_to_c(token), '\\'))==NULL)
                     57:                return(token);
                     58:        expanded = s_new();
                     59:        if (expanded == NULL) {
                     60:                s_free(token);
                     61:                return((string *)NULL);
                     62:        }
                     63:        for(cp = s_to_c(token); *cp; cp++) {
                     64:                if(*cp == '\\') switch(*++cp) {
                     65:                case 'l':
                     66:                        s_append(expanded, thissys);
                     67:                        break;
                     68:                case '\\':
                     69:                        s_putc(expanded, '\\');
                     70:                        break;
                     71:                default:
                     72:                        s_putc(expanded, '\\');
                     73:                        s_putc(expanded, *cp);
                     74:                        break;
                     75:                } else
                     76:                        s_putc(expanded, *cp);
                     77:        }
                     78:        s_free(token);
                     79:        s_terminate(expanded);
                     80:        return(expanded);
                     81: }
                     82: 
                     83: /*
                     84:  *  rules are of the form:
                     85:  *     <reg exp> <string> <repl exp> [<repl exp>]
                     86:  */
                     87: extern int
                     88: getrules()
                     89: {
                     90:        FILE    *rfp;
                     91:        rule    *rp, *rlastp=NULL;
                     92:        string  *line;
                     93:        string  *type;
                     94:        string  *file;
                     95:        string  *re;
                     96: 
                     97:        file = abspath(RULEFILE, UPASROOT, (string *)NULL);
                     98:        rfp = fopen(s_to_c(file), "r");
                     99:        if (rfp == NULL) {
                    100:                rulep = NULL;
                    101:                return -1;
                    102:        }
                    103:        line = s_new();
                    104:        type = s_new();
                    105:        while(s_getline(rfp, s_restart(line)) != NULL) {
                    106:                /* get a rule */
                    107:                rp = (rule *)malloc(sizeof(rule));
                    108:                if (rp == NULL) {
                    109:                        perror("getrules:");
                    110:                        exit(1);
                    111:                }
                    112:                rp->next = NULL;
                    113:                re = rule_parse(s_restart(line));
                    114:                s_tolower(re);
                    115:                rp->matchre = s_new();
                    116:                if(*s_to_c(re)!='^')
                    117:                        s_append(rp->matchre, "^");
                    118:                s_append(rp->matchre, s_to_c(re));
                    119:                s_append(rp->matchre, "$");
                    120:                s_restart(rp->matchre);
                    121:                s_free(re);
                    122:                s_parse(line, s_restart(type));
                    123:                rp->repl1 = rule_parse(line);
                    124:                rp->repl2 = rule_parse(line);
                    125:                rp->program = NULL;
                    126:                if (strcmp(s_to_c(type), "|") == 0)
                    127:                        rp->type = d_pipe;
                    128:                else if (strcmp(s_to_c(type), ">>") == 0)
                    129:                        rp->type = d_cat;
                    130:                else if (strcmp(s_to_c(type), "alias") == 0)
                    131:                        rp->type = d_alias;
                    132:                else if (strcmp(s_to_c(type), "translate") == 0)
                    133:                        rp->type = d_translate;
                    134:                else if (strcmp(s_to_c(type), "auth") == 0)
                    135:                        rp->type = d_auth;
                    136:                else {
                    137:                        s_free(rp->matchre);
                    138:                        s_free(rp->repl1);
                    139:                        s_free(rp->repl2);
                    140:                        free((char *)rp);
                    141:                        fprintf(stderr,"illegal rewrite rule: %s\n", s_to_c(line));
                    142:                        continue;
                    143:                }
                    144:                if (rulep == NULL)
                    145:                        rulep = rlastp = rp;
                    146:                else
                    147:                        rlastp = rlastp->next = rp;
                    148:        }
                    149:        s_free(type);
                    150:        s_free(line);
                    151:        s_free(file);
                    152:        fclose(rfp);
                    153:        return 0;
                    154: }
                    155: 
                    156: /* look up a matching rule */
                    157: static rule *
                    158: findrule(addrp, authorized)
                    159:        string *addrp;
                    160: {
                    161:        rule *rp;
                    162:        static rule defaultrule;
                    163:        string *matcher;
                    164: 
                    165:        if (rulep == NULL)
                    166:                return &defaultrule;
                    167:        for (rp = rulep; rp != NULL; rp = rp->next) {
                    168:                if (rp->type==d_auth && authorized)
                    169:                        continue;
                    170:                if (rp->program == NULL)
                    171:                        rp->program = regcomp(rp->matchre->base);
                    172:                if (rp->program == NULL)
                    173:                        continue;
                    174:                if (regexec(rp->program, s_to_c(addrp), rp->subexp, NSUBEXP))
                    175:                        return rp;
                    176:        }
                    177:        return NULL;
                    178: }
                    179: 
                    180: /*  Transforms the address into a command.
                    181:  *  Returns:   -1 if address not matched by reules
                    182:  *              0 if address matched and ok to forward
                    183:  *              1 if address matched and not ok to forward
                    184:  */
                    185: extern int
                    186: rewrite(dp, s)
                    187:        dest *dp;               /* destination to rewrite */
                    188:        char *s;                /* string that matches \s */
                    189: {
                    190:        rule *rp;               /* rewriting rule */
                    191:        string *lower;          /* lower case version of destination */
                    192:        char *cp;
                    193: 
                    194:        /*
                    195:         *  Rewrite the address.  Matching is case insensitive.
                    196:         */
                    197:        lower = s_clone(s_restart(dp->addr));
                    198:        s_tolower(s_restart(lower));
                    199:        rp = findrule(lower, dp->authorized);
                    200:        if (rp == NULL)
                    201:                return -1;
                    202:        strcpy(s_to_c(lower), s_to_c(dp->addr));
                    203:        dp->repl1 = substitute(rp->repl1, rp->subexp, s);
                    204:        dp->repl2 = substitute(rp->repl2, rp->subexp, s);
                    205:        dp->status = rp->type;
                    206:        return 0;
                    207: }
                    208: 
                    209: static string *
                    210: substitute(source, subexp, s)
                    211:        string *source;         /* substitution expression */
                    212:        regsubexp *subexp;      /* the matches */
                    213:        char *s;                /* string to substitute for \s */
                    214: {
                    215:        register char *sp;
                    216:        register char *ssp;
                    217:        register string *stp;
                    218:        register int i;
                    219:        
                    220:        if (source == NULL)
                    221:                return NULL;
                    222:        sp = s_to_c(source);
                    223: 
                    224:        /* someplace to put it */
                    225:        stp = s_new();
                    226: 
                    227:        /* do the substitution */
                    228:        while (*sp != '\0') {
                    229:                if (*sp == '\\') {
                    230:                        switch (*++sp) {
                    231:                        case '0': case '1': case '2': case '3': case '4':
                    232:                        case '5': case '6': case '7': case '8': case '9':
                    233:                                i = *sp-'0';
                    234:                                if (subexp[i].sp != NULL)
                    235:                                        for (ssp = subexp[i].sp;
                    236:                                             ssp < subexp[i].ep;
                    237:                                             ssp++)
                    238:                                                s_putc(stp, *ssp);
                    239:                                break;
                    240:                        case '\\':
                    241:                                s_putc(stp, '\\');
                    242:                                break;
                    243:                        case '\0':
                    244:                                sp--;
                    245:                                break;
                    246:                        case 's':
                    247:                                for(ssp = s; *ssp; ssp++)
                    248:                                        s_putc(stp, *ssp);
                    249:                                break;
                    250:                        default:
                    251:                                s_putc(stp, *sp);
                    252:                                break;
                    253:                        }
                    254:                } else if (*sp == '&') {                                
                    255:                        if (subexp[0].sp != NULL)
                    256:                                for (ssp = subexp[0].sp;
                    257:                                     ssp < subexp[0].ep; ssp++)
                    258:                                        s_putc(stp, *ssp);
                    259:                } else
                    260:                        s_putc(stp, *sp);
                    261:                sp++;
                    262:        }
                    263:        s_terminate(stp);
                    264: 
                    265:        return s_restart(stp);
                    266: }
                    267: 
                    268: regerror(s)
                    269: char* s;
                    270: {
                    271:        fprintf(stderr, "rewrite: %s\n", s);
                    272: }
                    273: 
                    274: dumprules()
                    275: {
                    276:        rule *rp;
                    277: 
                    278:        for (rp = rulep; rp != NULL; rp = rp->next) {
                    279:                fprintf (stderr, "'%s'", rp->matchre->base);
                    280:                switch (rp->type) {
                    281:                case d_pipe:
                    282:                        fprintf(stderr, " |");
                    283:                        break;
                    284:                case d_cat:
                    285:                        fprintf(stderr, " >>");
                    286:                        break;
                    287:                case d_alias:
                    288:                        fprintf(stderr, " alias");
                    289:                        break;
                    290:                case d_translate:
                    291:                        fprintf(stderr, " translate");
                    292:                        break;
                    293:                default:
                    294:                        fprintf(stderr, " UNKNOWN");
                    295:                        break;
                    296:                }
                    297:                fprintf (stderr, " '%s'", rp->repl1 ? rp->repl1->base:"...");
                    298:                fprintf (stderr, " '%s'\n", rp->repl2 ? rp->repl2->base:"...");
                    299:        }
                    300: }
                    301: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.