Annotation of 43BSD/contrib/mh/zotnet/mf/mmuu.c, revision 1.1.1.1

1.1       root        1: /* mmuu.c - routines to filter MMDF to UUCP mailboxes */
                      2: 
                      3: #include "mf.h"
                      4: #include "../tws/tws.h"
                      5: #include <stdio.h>
                      6: #include "../mts/mts.h"
                      7: #include <ctype.h>
                      8: #include <sys/types.h>
                      9: #include <sys/stat.h>
                     10: 
                     11: /*  */
                     12: 
                     13: static struct header {
                     14:     char   *h_name;
                     15:     int     h_type;
                     16: }                       headers[] = {
                     17:                             "From", HFROM,
                     18:                             "Sender", HSNDR,
                     19:                             "Reply-To", HADDR,
                     20:                             "To", HADDR,
                     21:                             "cc", HADDR,
                     22:                             "Bcc", HADDR,
                     23:                             "Resent-From", HADDR,
                     24:                             "Resent-Sender", HADDR,
                     25:                             "Resent-Reply-To", HADDR,
                     26:                             "Resent-To", HADDR,
                     27:                             "Resent-cc", HADDR,
                     28:                             "Resent-Bcc", HADDR,
                     29:                             "Date", HDATE,
                     30:                             "Resent-Date", HDATE,
                     31:                             NULL, HOTHR
                     32: };
                     33: 
                     34: 
                     35: static char buffer[BUFSIZ],
                     36:             tmpbuf[BUFSIZ];
                     37: 
                     38: long    time ();
                     39: char   *ctime ();
                     40: 
                     41: /*  */
                     42: 
                     43: /* 
                     44:  *    mmdf2uucp() - given a file descriptor to a mmdf mailbox, filter
                     45:  *    its contents to the file descriptor for a mmdf mailbox.  Returns
                     46:  *    non-zero on error (see mf.h for values)
                     47:  *
                     48:  *    It is assumed that the caller will have made sure that the necessary
                     49:  *    locking has been performed on the output fd.
                     50:  */
                     51: 
                     52: int    mmdf2uucp (infd, outfd, nodelim)
                     53: int     infd,
                     54:         outfd,
                     55:         nodelim;
                     56: {
                     57:     int     fd,
                     58:             result;
                     59:     struct stat st;
                     60:     FILE * in, *out;
                     61: 
                     62:     if (fstat (infd, &st) == NOTOK || fstat (outfd, &st) == NOTOK)
                     63:        return MFPRM;
                     64:     if ((in = fdopen (infd, "r")) == NULL
                     65:            || (out = fdopen (outfd, "w")) == NULL)
                     66:        return MFSIO;
                     67: 
                     68:     result = mmuu (in, out, nodelim);
                     69: 
                     70:     /* for STDIO - free up some fp:s */
                     71:     fd = dup (fileno (in));
                     72:     fclose (in);
                     73:     dup2 (fd, infd);
                     74:     close (fd);
                     75: 
                     76:     fd = dup (fileno (out));
                     77:     fclose (out);
                     78:     dup2 (fd, outfd);
                     79:     close (fd);
                     80: 
                     81:     return result;
                     82: }
                     83: 
                     84: /*  */
                     85: 
                     86: static int  mmuu (in, out, nodelim)
                     87: FILE   *in,
                     88:        *out;
                     89: int     nodelim;
                     90: {
                     91:     int     i,
                     92:             tmp_fd;
                     93:     FILE   *tmp;
                     94: 
                     95:     for (tmp_fd = NOTOK;;) {
                     96:        if ((i = mmdf_file (&tmp_fd, in, &tmp, nodelim)) == DONE)
                     97:            break;
                     98:        else
                     99:            if (i != OK)
                    100:                return i;
                    101:        if ((i = mmdf_headers (tmp, out, nodelim)) != OK)
                    102:            return mmdf_die (i, tmp, in, out, nodelim);
                    103:        if ((i = mmdf_text (tmp, out, nodelim)) != OK)
                    104:            return mmdf_die (i, tmp, in, out, nodelim);
                    105:     }
                    106: 
                    107:     fflush (out);
                    108: 
                    109:     return (ferror (in) || ferror (out) ? MFERR : MFOK);
                    110: }
                    111: 
                    112: /*  */
                    113: 
                    114: static int  mmdf_file (tmp_fd, in, tmp, nodelim)
                    115: int    *tmp_fd,
                    116:         nodelim;
                    117: FILE * in, **tmp;
                    118: {
                    119:     int     done,
                    120:             fd;
                    121:     char    tmpfil[LINESIZ];
                    122:     FILE * out;
                    123: 
                    124:     if (nodelim)
                    125:        if (*tmp_fd != NOTOK)
                    126:            return DONE;
                    127:        else
                    128:            if ((*tmp_fd = dup (fileno (in))) == NOTOK)
                    129:                return MFERR;
                    130:            else
                    131:                if ((*tmp = fdopen (*tmp_fd, "r")) == NULL) {
                    132:                    close (*tmp_fd);
                    133:                    return MFERR;
                    134:                }
                    135:                else
                    136:                    return OK;
                    137: 
                    138:     if (fgets (tmpbuf, sizeof tmpbuf, in) == NULL)
                    139:        return DONE;
                    140:     if (!isdlm1 (tmpbuf))
                    141:        return MFDLM;
                    142: 
                    143:     strcpy (tmpfil, "/tmp/mmuuXXXXXX");
                    144:     unlink (mktemp (tmpfil));
                    145:     if ((fd = creat (tmpfil, TMPMODE)) == NOTOK)
                    146:        return MFERR;
                    147:     close (fd);
                    148: 
                    149:     if ((fd = open (tmpfil, 2)) == NOTOK)
                    150:        return MFERR;
                    151:     if ((out = fdopen (fd, "w")) == NULL) {
                    152:        close (fd);
                    153:        return MFERR;
                    154:     }
                    155:     unlink (tmpfil);
                    156: 
                    157:     if ((*tmp_fd = dup (fd)) == NOTOK) {
                    158:        close (fd);
                    159:        return MFERR;
                    160:     }
                    161:     if ((*tmp = fdopen (*tmp_fd, "r")) == NULL) {
                    162:        close (fd);
                    163:        close (*tmp_fd);
                    164:        return MFERR;
                    165:     }
                    166: 
                    167: /*  */
                    168: 
                    169:     for (done = FALSE;;) {
                    170:        if (fgets (tmpbuf, sizeof tmpbuf, in) == NULL)
                    171:            return MFDLM;
                    172:        if (done && isdlm2 (tmpbuf))
                    173:            break;
                    174:        done = tmpbuf[strlen (tmpbuf) - 1] == '\n';
                    175:        fputs (tmpbuf, out);
                    176:     }
                    177: 
                    178:     fclose (out);
                    179:     fseek (*tmp, 0L, 0);
                    180:     return OK;
                    181: }
                    182: 
                    183: /*  */
                    184: 
                    185: static int  mmdf_headers (in, out, nodelim)
                    186:             FILE * in, *out;
                    187: int     nodelim;
                    188: {
                    189:     int     fd,
                    190:             i,
                    191:             tmp_fd;
                    192:     char   *cp,
                    193:             line[BUFSIZ],
                    194:             from[LINESIZ],
                    195:             date[LINESIZ],
                    196:             tmpfil[LINESIZ];
                    197:     FILE * tmp;
                    198: 
                    199:     *from = *date = NULL;
                    200: 
                    201:     strcpy (tmpfil, "/tmp/mmuuXXXXXX");
                    202:     unlink (mktemp (tmpfil));
                    203:     if ((fd = creat (tmpfil, TMPMODE)) == NOTOK)
                    204:        return MFERR;
                    205:     close (fd);
                    206:     if ((tmp_fd = open (tmpfil, 2)) == NOTOK)
                    207:        return MFERR;
                    208:     unlink (tmpfil);
                    209: 
                    210:     if ((fd = dup (tmp_fd)) == NOTOK) {
                    211:        close (tmp_fd);
                    212:        return MFERR;
                    213:     }
                    214:     if ((tmp = fdopen (fd, "w")) == NULL) {
                    215:        close (tmp_fd);
                    216:        close (fd);
                    217:        return MFERR;
                    218:     }
                    219: 
                    220:     for (;;) {
                    221:        switch (do_header (from, date, in, tmp)) {
                    222:            case NOTOK: 
                    223:                close (tmp_fd);
                    224:                fclose (tmp);
                    225:                return MFHDR;
                    226: 
                    227:            case OK: 
                    228:                continue;
                    229: 
                    230:            case DONE: 
                    231:                fclose (tmp);
                    232:                break;
                    233:        }
                    234:        break;
                    235:     }
                    236: 
                    237: /*  */
                    238: 
                    239:     if (*date == NULL || *from == NULL) {
                    240:        if (*date)
                    241:            strcpy (buffer, "No (valid) From: field found in message\n");
                    242:        else
                    243:            if (*from)
                    244:                strcpy (buffer, "No (valid) Date: field found in message\n");
                    245:            else
                    246:                strcpy (buffer,
                    247:                        "No (valid) From: or Date: fields found in message\n");
                    248:        if (nodelim) {
                    249:            if (*date == NULL) {
                    250:                long clock;
                    251: 
                    252:                time (&clock);
                    253:                sprintf (date, "%.24s", ctime (&clock));
                    254:            }
                    255:            if (*from == NULL)
                    256:                sprintf (from, "%s!%s", SystemName (), getusr ());
                    257:        }
                    258:        else
                    259:            return MFHDR;
                    260:     }
                    261:     else
                    262:        buffer[0] = NULL;
                    263:        
                    264:     if (nodelim && (cp = index (from, '!')) != NULL) {
                    265:        *cp++ = NULL;
                    266:        fprintf (out, "From %s %s remote from %s\n", cp, date, from);
                    267:     }
                    268:     else
                    269:        fprintf (out, "From %s %s\n", from, date);
                    270: 
                    271:     fprintf (out, "Munged: from %s to %s; %s\n",
                    272:            LocalName (), SystemName (), dtimenow ());
                    273:     if (buffer[0])
                    274:        fprintf (out, "Illegal-Field: %s", buffer);
                    275:     
                    276:     if ((tmp = fdopen (tmp_fd, "r")) == NULL) {
                    277:        close (tmp_fd);
                    278:        return MFERR;
                    279:     }
                    280:     fseek (tmp, 0L, 0);
                    281: 
                    282:     while ((i = fread (line, sizeof *line, sizeof line, tmp)) > 0)
                    283:        fwrite (line, sizeof *line, i, out);
                    284:     putc ('\n', out);          /* separate headers from body */
                    285:     fclose (tmp);
                    286: 
                    287:     return OK;
                    288: }
                    289: 
                    290: /*  */
                    291: 
                    292: static int  mmdf_text (in, out, nodelim)
                    293: int     nodelim;
                    294: FILE * in, *out;
                    295: {
                    296:     int     i;
                    297: 
                    298:     if (feof (in))             /* probably no body */
                    299:        putc ('\n', out);
                    300:     else
                    301:        while ((i = fread (buffer, sizeof *buffer, sizeof buffer, in)) > 0)
                    302:            fwrite (buffer, sizeof *buffer, i, out);
                    303: 
                    304:     if (!nodelim)
                    305:        putc ('\n', out);
                    306:     fclose (in);
                    307: 
                    308:     return OK;
                    309: }
                    310: 
                    311: /*  */
                    312: 
                    313: static int  do_header (from, date, in, out)
                    314: char   *from,
                    315:        *date;
                    316: FILE * in, *out;
                    317: {
                    318:     int     i,
                    319:             margin,
                    320:             some,
                    321:             spat,
                    322:             pos;
                    323:     char   *bp,
                    324:            *cp,
                    325:            *pp,
                    326:             line[BUFSIZ];
                    327:     struct adrx *adrxp;
                    328:     struct header  *hl;
                    329: 
                    330:     if ((i = mfgets (in, &bp)) != OK)
                    331:        return i;
                    332: 
                    333:     if ((cp = index (bp, ':')) == NULL) {
                    334:        fprintf (out, "Illegal-Field: %s\n", bp);
                    335:        return OK;
                    336:     }
                    337: 
                    338:     *cp = NULL;
                    339:     for (hl = &headers[0]; hl -> h_name; hl++)
                    340:        if (lequal (hl -> h_name, bp))
                    341:            break;
                    342: 
                    343: /*  */
                    344: 
                    345:     switch (hl -> h_type) {
                    346:        case HOTHR: 
                    347:            *cp = ':';
                    348:            fprintf (out, "%s\n", bp);
                    349:            break;
                    350: 
                    351:        case HDATE: 
                    352:            pp = ++cp;
                    353:            if (*date != NULL || !lequal (hl -> h_name, "Date"))
                    354:                return OK;
                    355:            date_convert (pp, date);
                    356:            if (*date == NULL)
                    357:                fprintf (out,
                    358:                        "Illegal-Object: %s: %s -- illegal date construct\n",
                    359:                        hl -> h_name, pp);
                    360:            break;
                    361: 
                    362:        case HFROM: 
                    363:            pp = ++cp;
                    364:            if (*from != NULL)
                    365:                return OK;
                    366:            if ((adrxp = getadrx (pp)) == NULL) {
                    367:                fprintf (out, "Illegal-Object: %s: %s -- %s\n",
                    368:                        hl -> h_name, pp, "no address");
                    369:                return OK;      /* catch errors later (possibly) */
                    370:            }
                    371:            addr_convert (adrxp, from, TRUE);
                    372:            if (*from == NULL)
                    373:                fprintf (out, "Illegal-Object: %s: %s -- %s\n",
                    374:                        hl -> h_name, adrxp -> text, adrxp -> err);
                    375:            while (getadrx (NULL))
                    376:                continue;
                    377:            break;
                    378: 
                    379:        case HADDR: 
                    380:        case HSNDR: 
                    381:            spat = 0;
                    382:            some = FALSE;
                    383:            pp = ++cp;
                    384:            margin = pos = strlen (hl -> h_name) + 2;
                    385:            while (adrxp = getadrx (pp)) {
                    386:                addr_convert (adrxp, line, FALSE);
                    387:                if (line[0] != NULL) {
                    388:                    if (!spat++)
                    389:                        fprintf (out, "%s: ", hl -> h_name);
                    390:                    if (some++)
                    391:                        fputs (", ", out), pos += 2;
                    392:                    if (pos + strlen (line) >= OWIDTH) {
                    393:                        fprintf (out, "\n%*s", margin, " ");
                    394:                        pos = margin;
                    395:                    }
                    396:                    fputs (line, out);
                    397:                    pos += strlen (line);
                    398:                }
                    399:                else {
                    400:                    if (spat)
                    401:                        putc ('\n', out);
                    402:                    fprintf (out, "Illegal-Object: %s: %s -- %s\n",
                    403:                            hl -> h_name, adrxp -> text, adrxp -> err);
                    404:                    spat = 0;
                    405:                    some = FALSE;
                    406:                    pos = margin;
                    407:                }
                    408:            }
                    409:            if (spat)
                    410:                putc ('\n', out);
                    411:            break;
                    412: 
                    413:        default: 
                    414:            return NOTOK;
                    415:     }
                    416: 
                    417:     return OK;
                    418: }
                    419: 
                    420: /*  */
                    421: 
                    422: static addr_convert (adrxp, to, notice)
                    423: struct adrx *adrxp;
                    424: char   *to;
                    425: int     notice;
                    426: {
                    427:     int     mboxlen,
                    428:             uucplen;
                    429:     char   *cp,
                    430:             tmp[LINESIZ],
                    431:             uucp[LINESIZ];
                    432:     static char path[LINESIZ] = "";
                    433: 
                    434:     if (path[0] == NULL)
                    435:        strcpy (path, LocalName ());
                    436: 
                    437:     if (adrxp -> err || !adrxp -> mbox) {
                    438:        *to = NULL;
                    439:        return;
                    440:     }
                    441:     if (notice)
                    442:        strcpy (path, adrxp -> host ? adrxp -> host : LocalName ());
                    443: 
                    444:     if (adrxp -> host == NULL)
                    445:        if (index (adrxp -> mbox, '!') != NULL)
                    446:            strcpy (tmp, adrxp -> mbox);
                    447:        else
                    448:            if (lequal (path, LocalName ()))
                    449:                sprintf (tmp, "%s!%s", SystemName (), adrxp -> mbox);
                    450:            else
                    451:                sprintf (tmp, "%s!%s@%s", SystemName (), adrxp -> mbox, path);
                    452:     else
                    453:        if (index (adrxp -> mbox, '!') == NULL)
                    454:            sprintf (tmp, "%s!%s@%s",
                    455:                    SystemName (), adrxp -> mbox, adrxp -> host);
                    456:        else {
                    457:            sprintf (uucp, "%%%s", UucpChan ());
                    458:            uucplen = strlen (uucp);
                    459:            cp = (lequal (LocalName (), adrxp -> host)
                    460:                    && (mboxlen = strlen (adrxp -> mbox) - uucplen) > 0)
                    461:                ? (adrxp -> mbox) + mboxlen : NULL;
                    462:            if (lequal (uucp, cp))
                    463:                sprintf (tmp, "%.*s", mboxlen, adrxp -> mbox);
                    464:            else
                    465:                if ((cp = index (adrxp -> host, '.'))
                    466:                        && lequal (UucpChan (), cp + 1))
                    467:                    sprintf (tmp, "%.*s!%s",
                    468:                        cp - adrxp -> host, adrxp -> host, adrxp -> mbox);
                    469:            else
                    470:                if (lequal (adrxp -> host, UucpChan ()))
                    471:                    strcpy (tmp, adrxp -> mbox);
                    472:            else {
                    473:                sprintf (uucp, "%s!", SystemName ());
                    474:                uucplen = strlen (uucp);
                    475:                if (strncmp (uucp, adrxp -> mbox, uucplen))
                    476:                    sprintf (tmp, "%s!%s@%s",
                    477:                            SystemName (), adrxp -> mbox, adrxp -> host);
                    478:                else
                    479:                    sprintf (tmp, "%s@%s", adrxp -> mbox, adrxp -> host);
                    480:            }
                    481:        }
                    482: 
                    483:     strcpy (to, tmp);
                    484: }
                    485: 
                    486: /*  */
                    487: 
                    488: static  date_convert (from, to)
                    489: char   *from,
                    490:        *to;
                    491: {
                    492:     char   *cp;
                    493: 
                    494:     if ((cp = dctime (dparsetime (from))) != NULL)
                    495:        sprintf (to, "%.24s", cp);
                    496:     else
                    497:        *to = NULL;
                    498: }
                    499: 
                    500: /*  */
                    501: 
                    502: static int  mmdf_die (error, in1, in2, out, nodelim)
                    503: int     error,
                    504:         nodelim;
                    505: FILE * in1, *in2, *out;
                    506: {
                    507:     int     i;
                    508:     long    clock;
                    509:     char    date[LINESIZ];
                    510: 
                    511:     if (nodelim) {
                    512:        fclose (in1);
                    513:        return error;
                    514:     }
                    515: 
                    516:     switch (error) {
                    517:        case MFTXT: 
                    518:            putc ('\n', out);
                    519:            break;
                    520:     }
                    521: 
                    522:     time (&clock);
                    523:     sprintf (date, "%.24s", ctime (&clock));
                    524:     fprintf (out, "From %s %s\nSubject: %s %s\n\n",
                    525:            getusr (), date, "Bad MMDF mailbox - error in",
                    526:            error == MFHDR ? "Header" : error == MFTXT ? "Body" : "Mailbox");
                    527: 
                    528:     fprintf (out, "%s: %s\n%s\n--------\n",
                    529:            "Error detected at line", buffer, "Message being processed");
                    530:     fseek (in1, 0L, 0);
                    531:     while ((i = fread (buffer, sizeof *buffer, sizeof buffer, in1)) > 0)
                    532:        fwrite (buffer, sizeof *buffer, i, out);
                    533:     fclose (in1);
                    534: 
                    535:     if (!feof (in2)) {
                    536:        fprintf (out, "--------\n%s\n--------\n%s",
                    537:                "Remainder of unfiltered mailbox follows", tmpbuf);
                    538:        while ((i = fread (buffer, sizeof *buffer, sizeof buffer, in2)) > 0)
                    539:            fwrite (buffer, sizeof *buffer, i, out);
                    540:     }
                    541: 
                    542:     fprintf (out, "--------\n\n");
                    543:     fflush (out);
                    544: 
                    545:     return error;
                    546: }

unix.superglobalmegacorp.com

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