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

1.1       root        1: #include <stdio.h>
                      2: #include <ctype.h>
                      3: #include <regexp.h>
                      4: #include "mail.h"
                      5: #include "string.h"
                      6: 
                      7: /* configuration */
                      8: #define RULEFILE "rewrite"
                      9: #define BUFFERSIZE 512 
                     10: 
                     11: /* 
                     12:  *     Routines for dealing with the rewrite rules.
                     13:  */
                     14: 
                     15: /* imports */
                     16: extern char *malloc();
                     17: extern int strlen();
                     18: extern regexp *regcomp();
                     19: extern int regexec();
                     20: extern void regsub();
                     21: extern char *upaspath();
                     22: extern char *thissys;
                     23: 
                     24: /* globals */
                     25: typedef struct rule rule;
                     26: 
                     27: struct rule {
                     28:        char *matchre;          /* address match */
                     29:        char *cmdre;            /* command used to send message */
                     30:        char *machre;           /* next hop */
                     31:        char *restre;           /* address after the next hop */
                     32:        regexp *program;
                     33:        rule *next;
                     34: };
                     35: static rule *rulep;
                     36: static rule alwayslocal = {
                     37:        ".*",
                     38:        "",
                     39:        "",
                     40:        NULL
                     41: };
                     42: static int eof = 0, eol = 0;
                     43: 
                     44: 
                     45: /* predeclared */
                     46: static char *getstring();
                     47: static char *newstring();
                     48: static void substitute();
                     49: static int geteol();
                     50: 
                     51: extern int
                     52: getrules()
                     53: {
                     54:        FILE    *rfp;
                     55:        rule    *rp, *rlastp=NULL;
                     56:        char    *bp;
                     57: 
                     58:        eof = eol = 0;
                     59:        rfp = fopen(upaspath(RULEFILE), "r");
                     60:        if (rfp == NULL) {
                     61:                rulep = &alwayslocal;
                     62:                return -1;
                     63:        }
                     64:        do {
                     65:                /* ignore comments */
                     66:                bp = getstring(rfp);
                     67:                if (*bp=='#' || *bp=='\0')
                     68:                        continue;
                     69: 
                     70:                /* get a rule */
                     71:                rp = (rule *)malloc(sizeof(rule));
                     72:                if (rp == NULL)
                     73:                        return -1;
                     74:                if (rulep == NULL)
                     75:                        rulep = rlastp = rp;
                     76:                else
                     77:                        rlastp = rlastp->next = rp;
                     78:                rp->next = NULL;
                     79:                rp->matchre = newstring(bp);
                     80:                rp->cmdre = newstring(getstring(rfp));
                     81:                rp->machre = newstring(getstring(rfp));
                     82:                rp->restre = newstring(getstring(rfp));
                     83:                rp->program = NULL;
                     84:        } while (geteol(rfp));
                     85:        fclose(rfp);
                     86: #ifdef DEBUG
                     87:        dumprules();
                     88: #endif DEBUG
                     89:        return 0;
                     90: }
                     91: 
                     92: static char *
                     93: getstring(fp)
                     94:        FILE *fp;
                     95: {
                     96:        static char buf[BUFFERSIZE];
                     97:        int c, term1=' ', term2='\t';
                     98:        char *bp=buf;
                     99: 
                    100:        if (!eol) {
                    101:                /* skip whitespace */
                    102:                do {
                    103:                        c = getc(fp);
                    104: 
                    105:                        /* hack to recognize escaped newline */
                    106:                        if (c == '\\') {
                    107:                                c = getc(fp);
                    108:                                if (c == '\n')
                    109:                                        c = ' ';
                    110:                                else
                    111:                                        *bp++ = '\\';
                    112:                        }
                    113:                } while (c == ' ' || c == '\t');
                    114: 
                    115:                /* possible quoted string */
                    116:                if (c == '\'' || c == '"') {
                    117:                        term1 = term2 = c;
                    118:                        c = getc(fp);
                    119:                }
                    120: 
                    121:                while (c != term1 && c != term2 && !eol) {
                    122:                        switch (c) {
                    123:                        case EOF:
                    124:                                eof = 1;
                    125:                                /* fall through */
                    126:                        case '\n':
                    127:                                eol = 1;
                    128:                                break;
                    129:                        case '\\':
                    130:                                c = getc(fp);
                    131:                                /* hack to recognize escaped newline */
                    132:                                if (c == '\n') {
                    133:                                        c = term1;
                    134:                                        break;
                    135:                                } else {
                    136:                                        *bp++ = '\\';
                    137:                                        /* fall through */
                    138:                                }
                    139:                        default:
                    140:                                *bp++ = c;
                    141:                                c = getc(fp);
                    142:                                break;
                    143:                        }
                    144:                }
                    145: 
                    146:        }
                    147:        *bp = 0;
                    148: 
                    149:        return buf;
                    150: }
                    151: 
                    152: static int
                    153: geteol(fp)
                    154:        FILE *fp;
                    155: {
                    156:        while(!eol)
                    157:                getstring(fp);
                    158:        eol = 0;
                    159:        return !eof;
                    160: }
                    161: 
                    162: static char *
                    163: newstring(sp)
                    164:        char *sp;
                    165: {
                    166:        char *np;
                    167: 
                    168:        np = malloc(strlen(sp)+1);
                    169:        if (np == NULL) {
                    170:                fprintf(stderr, "mail: out of memory\n");
                    171:                exit(1);
                    172:        }
                    173:        strcpy(np, sp);
                    174:        return np;
                    175: }
                    176: 
                    177: static rule *
                    178: findrule(addrp)
                    179:        char *addrp;
                    180: {
                    181:        rule *rp;
                    182: 
                    183:        for (rp = rulep; rp != NULL; rp = rp->next) {
                    184:                if (rp->program == NULL)
                    185:                        rp->program = regcomp(rp->matchre);
                    186:                if (regexec(rp->program, addrp))
                    187:                        return rp;
                    188:        }
                    189:        return NULL;
                    190: }
                    191: 
                    192: /*  Transforms the address into a command.
                    193:  *  Returns:   -1 if address not matched by reules
                    194:  *              0 if address matched and ok to forward
                    195:  *              1 if address matched and not ok to forward
                    196:  */
                    197: extern int
                    198: rewrite(addrp, s, chkfl, cmdp)
                    199:        char *addrp;            /* address to rewrite */
                    200:        char *s;                /* string that matches \s */
                    201:        int chkfl;              /* non-zero if we must check forwarding */
                    202:        char *cmdp;             /* (returned) substituted strings */
                    203: {
                    204:        rule *rp;
                    205:        char dest[ADDRSIZE];    /* next hop for message */
                    206:        char rest[ADDRSIZE];    /* rest of address after hop */
                    207:        char addr[ADDRSIZE];    /* rest of address after hop */
                    208: 
                    209:        /* rewrite the address */
                    210:        rp = findrule(addrp);
                    211:        if (rp == NULL)
                    212:                return -1;
                    213:        if (cmdp != NULL)
                    214:                substitute(rp->program, rp->cmdre, cmdp, s);
                    215: 
                    216:        /* check for legal forwarding */
                    217:        if (!chkfl)
                    218:                return 0;
                    219:        while (1) {
                    220:                substitute(rp->program, rp->restre, rest, s);
                    221:                substitute(rp->program, rp->machre, dest, s);
                    222: #ifdef DEBUG
                    223:                printf("        %s %s\n", dest, rest);
                    224: #endif DEBUG
                    225:                if (dest[0] == '\0')
                    226:                        return 0;
                    227:                if (!okrmt(dest))
                    228:                        return 1;
                    229:                strcpy(addr, rest);
                    230:                rp = findrule(addr);
                    231:                if (rp == NULL)
                    232:                        return 1;
                    233:                
                    234:        }
                    235: }
                    236: 
                    237: static void
                    238: substitute(progp, sp, dp, s)
                    239:        regexp *progp;  /* context of substitution */
                    240:        char *sp;       /* source string */
                    241:        char *dp;       /* destination string */
                    242:        char *s;        /* strig to substitute for \s */
                    243: {
                    244:        char *ssp;
                    245: 
                    246:        while (*sp != '\0') {
                    247:                if (*sp == '\\') {
                    248:                        switch (*++sp) {
                    249:                        case '0':
                    250:                        case '1':
                    251:                        case '2':
                    252:                        case '3':
                    253:                        case '4':
                    254:                        case '5':
                    255:                        case '6':
                    256:                        case '7':
                    257:                        case '8':
                    258:                        case '9':
                    259:                                if (progp->startp[*sp-'0'] != NULL)
                    260:                                        for (ssp = progp->startp[*sp-'0'];
                    261:                                             ssp < progp->endp[*sp-'0'];
                    262:                                             ssp++)
                    263:                                                *dp++ = *ssp;
                    264:                                break;
                    265:                        case '\\':
                    266:                                *dp++ = '\\';
                    267:                                break;
                    268:                        case '\0':
                    269:                                sp--;
                    270:                                break;
                    271:                        case 's':
                    272:                                for(ssp = s; *ssp; ssp++)
                    273:                                        *dp++ = *ssp;
                    274:                                break;
                    275:                        default:
                    276:                                *dp++ = *sp;
                    277:                                break;
                    278:                        }
                    279:                } else if (*sp == '&') {                                
                    280:                        if (progp->startp[0] != NULL)
                    281:                                for (ssp = progp->startp[0];
                    282:                                     ssp < progp->endp[0]; ssp++)
                    283:                                        *dp++ = *ssp;
                    284:                } else
                    285:                        *dp++ = *sp;
                    286:                sp++;
                    287:        }
                    288:        *dp = '\0';
                    289: }
                    290: 
                    291: #ifdef DEBUG
                    292: regdump(subp)
                    293:        regexp *subp;
                    294: {
                    295:        int i;
                    296:        char *cp;
                    297: 
                    298:        printf ("matches are:\n");
                    299:        for (i = 0; i < NSUBEXP; i++) {
                    300:                if (subp->startp[i] != NULL) {
                    301:                        printf("\t(%d) ", i);
                    302:                        for (cp = subp->startp[i]; cp < subp->endp[i]; cp++)
                    303:                                putchar(*cp);
                    304:                        putchar('\n');
                    305:                }
                    306:        }
                    307: }
                    308: #endif DEBUG
                    309: 
                    310: #ifdef DEBUG
                    311: dumprules()
                    312: {
                    313:        rule *rp;
                    314: 
                    315:        for (rp = rulep; rp != NULL; rp = rp->next) {
                    316:                fprintf (stderr, "matchre: %s\n", rp->matchre);
                    317:                fprintf (stderr, "cmdre: %s\n", rp->cmdre);
                    318:                fprintf (stderr, "machre: %s\n", rp->machre);
                    319:                fprintf (stderr, "restre: %s\n", rp->restre);
                    320:        }
                    321: }
                    322: #endif DEBUG
                    323: 
                    324: regerror(s)
                    325: char* s;
                    326: {
                    327:        fprintf(stderr, "rewrite: %s\n", s);
                    328:        exit(1);
                    329: }

unix.superglobalmegacorp.com

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