Annotation of 43BSDReno/contrib/mh/zotnet/mf/uumm.c, revision 1.1.1.1

1.1       root        1: /* uumm.c - routines to filter UUCP to MMDF 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: static char buffer[BUFSIZ],
                     35:             tmpbuf[BUFSIZ];
                     36: 
                     37: char   *shrink ();
                     38: 
                     39: long    time ();
                     40: 
                     41: /*  */
                     42: 
                     43: /*
                     44:  *    uucp2mmdf() - given a file descriptor to a uucp 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    uucp2mmdf (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 = uumm (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: int     uumm (in, out, nodelim)
                     87: FILE   *in,
                     88:        *out;
                     89: int     nodelim;
                     90: {
                     91:     int     i,
                     92:             tmp_fd;
                     93:     char    from[LINESIZ],
                     94:             date[LINESIZ];
                     95:     FILE   *tmp;
                     96: 
                     97:     for (tmp_fd = NOTOK;;) {
                     98:        if ((i = uucp_file (&tmp_fd, in, &tmp, nodelim)) == DONE)
                     99:            break;
                    100:        else
                    101:            if (i != OK)
                    102:                return i;
                    103:        if ((i = uucp_from (from, date, tmp)) != OK)
                    104:            return uucp_die (i, tmp, in, out, nodelim);
                    105:        if ((i = uucp_headers (from, date, tmp, out, nodelim)) != OK)
                    106:            return uucp_die (i, tmp, in, out, nodelim);
                    107:        if ((i = uucp_text (tmp, out, nodelim)) != OK)
                    108:            return uucp_die (i, tmp, in, out, nodelim);
                    109:     }
                    110: 
                    111:     fflush (out);
                    112: 
                    113:     return (ferror (in) || ferror (out) ? MFERR : MFOK);
                    114: }
                    115: 
                    116: /*  */
                    117: 
                    118: static int  uucp_file (tmp_fd, in, tmp, nodelim)
                    119: int    *tmp_fd,
                    120:         nodelim;
                    121: FILE * in, **tmp;
                    122: {
                    123:     int     done,
                    124:             fd;
                    125:     char    tmpfil[LINESIZ];
                    126:     FILE * out;
                    127: 
                    128:     if (nodelim)
                    129:        if (*tmp_fd != NOTOK)
                    130:            return DONE;
                    131:        else
                    132:            if ((*tmp_fd = dup (fileno (in))) == NOTOK)
                    133:                return MFERR;
                    134:            else
                    135:                if ((*tmp = fdopen (*tmp_fd, "r")) == NULL) {
                    136:                    close (*tmp_fd);
                    137:                    return MFERR;
                    138:                }
                    139:                else
                    140:                    return OK;
                    141: 
                    142:     if (*tmp_fd == NOTOK && fgets (tmpbuf, sizeof tmpbuf, in) == NULL)
                    143:        return DONE;
                    144:     else
                    145:        if (feof (in))
                    146:            return DONE;
                    147: 
                    148:     strcpy (tmpfil, "/tmp/uummXXXXXX");
                    149:     unlink (mktemp (tmpfil));
                    150:     if ((fd = creat (tmpfil, TMPMODE)) == NOTOK)
                    151:        return MFERR;
                    152:     close (fd);
                    153: 
                    154:     if ((fd = open (tmpfil, 2)) == NOTOK)
                    155:        return MFERR;
                    156:     if ((out = fdopen (fd, "w")) == NULL) {
                    157:        close (fd);
                    158:        return MFERR;
                    159:     }
                    160:     unlink (tmpfil);
                    161: 
                    162:     if ((*tmp_fd = dup (fd)) == NOTOK) {
                    163:        close (fd);
                    164:        return MFERR;
                    165:     }
                    166:     if ((*tmp = fdopen (*tmp_fd, "r")) == NULL) {
                    167:        close (fd);
                    168:        close (*tmp_fd);
                    169:        return MFERR;
                    170:     }
                    171: 
                    172: /*  */
                    173: 
                    174:     for (done = FALSE;;) {
                    175:        if (done)
                    176:            if (isfrom (tmpbuf))
                    177:                break;
                    178:            else
                    179:                putc ('\n', out);
                    180:        done = tmpbuf[0] == '\n';
                    181:        if (!done)
                    182:            fputs (tmpbuf, out);
                    183:        if (fgets (tmpbuf, sizeof tmpbuf, in) == NULL)
                    184:            break;
                    185:     }
                    186: 
                    187:     fclose (out);
                    188:     fseek (*tmp, 0L, 0);
                    189:     return OK;
                    190: }
                    191: 
                    192: /*  */
                    193: 
                    194: /* We might want to attempt recovery here.  Forget it. */
                    195: 
                    196: static int  uucp_from (from, date, in)
                    197: char   *from,
                    198:        *date;
                    199: FILE * in;
                    200: {
                    201:     char   *cp,
                    202:            *pp,
                    203:             fromwhom[LINESIZ];
                    204:     struct adrx *adrxp;
                    205: 
                    206:     if (fgets (buffer, sizeof buffer, in) == NULL || !isfrom (buffer))
                    207:        return MFROM;
                    208:     if (buffer[strlen (buffer) - 1] == '\n')
                    209:        buffer[strlen (buffer) - 1] = NULL;
                    210:     if ((cp = index (buffer, ' ')) == NULL)
                    211:        return MFROM;
                    212:     pp = ++cp;
                    213:     if ((cp = index (cp, ' ')) == NULL)
                    214:        return MFROM;
                    215:     *cp++ = NULL;
                    216:     strcpy (fromwhom, pp);
                    217:     while (isspace (*cp))
                    218:        cp++;
                    219:     sprintf (date, "%.24s", cp);
                    220: 
                    221:     for (;;) {
                    222:        if ((cp = index (cp + 1, 'r')) == NULL) {
                    223:            if (index (fromwhom, '!') || index (fromwhom, '@'))
                    224:                strcpy (from, fromwhom);
                    225:            else
                    226:                sprintf (from, "%s!%s", SystemName (), fromwhom);
                    227:            break;
                    228:        }
                    229:        if (strncmp (cp, "remote from ", 12) == 0) {
                    230:            *cp = NULL;
                    231:            sprintf (from, "%s!%s", cp + 12, fromwhom);
                    232:            break;
                    233:        }
                    234:     }
                    235: 
                    236:     if ((adrxp = seekadrx (from)) == NULL)
                    237:        return MFROM;
                    238:     addr_convert (adrxp, from, TRUE);
                    239:     while (seekadrx (NULL))
                    240:        continue;
                    241:     if (from[0] == NULL)
                    242:        return MFROM;
                    243:     date_convert (date, date);
                    244:     return (date[0] != NULL ? OK : MFROM);
                    245: }
                    246: 
                    247: /*  */
                    248: 
                    249: static int  uucp_headers (from, date, in, out, nodelim)
                    250: int     nodelim;
                    251: char   *from,
                    252:        *date;
                    253: FILE * in, *out;
                    254: {
                    255:     int     i,
                    256:             seen_from,
                    257:             seen_sender,
                    258:             seen_date;
                    259: 
                    260:     seen_from = seen_sender = seen_date = 0;
                    261:     if (!nodelim)
                    262:        fputs (mmdlm1, out);
                    263: 
                    264:     fprintf (out, "Munged: from %s to %s; %s\n",
                    265:            SystemName (), LocalName (), dtimenow ());
                    266: 
                    267:     for (;;) {
                    268:        switch (do_header (&seen_from, &seen_sender, &seen_date, in, out)) {
                    269:            case NOTOK: 
                    270:                return MFHDR;
                    271: 
                    272:            case OK: 
                    273:                continue;
                    274: 
                    275:            case DONE: 
                    276:                break;
                    277:        }
                    278:        break;
                    279:     }
                    280:                                /* extra newline separates headers and body */
                    281:     fprintf (out, "%sDate: %s\n%s: %s\n\n",
                    282:            seen_date ? "UUCP-" : NULL, date,
                    283:            seen_from ? (seen_sender ? "UUCP-Sender" : "Sender") : "From",
                    284:            from);
                    285: 
                    286:     return OK;
                    287: }
                    288: 
                    289: /*  */
                    290: 
                    291: static int  uucp_text (in, out, nodelim)
                    292: int     nodelim;
                    293: FILE * in, *out;
                    294: {
                    295:     if (feof (in))             /* probably no body */
                    296:        putc ('\n', out);
                    297:     else
                    298:        while (fgets (buffer, sizeof buffer, in) != NULL) {
                    299:            if (!nodelim && isdlm2 (buffer))
                    300:                buffer[0]++;
                    301:            fputs (buffer, out);
                    302:        }
                    303: 
                    304:     if (!nodelim)
                    305:        fputs (mmdlm2, out);
                    306:     fclose (in);
                    307: 
                    308:     return OK;
                    309: }
                    310: 
                    311: /*  */
                    312: 
                    313: static int  do_header (seen_from, seen_sender, seen_date, in, out)
                    314: int    *seen_from,
                    315:        *seen_sender,
                    316:        *seen_date;
                    317: FILE * in, *out;
                    318: {
                    319:     int     i,
                    320:             margin,
                    321:             some,
                    322:             spat,
                    323:             pos;
                    324:     char   *bp,
                    325:            *cp,
                    326:            *pp,
                    327:             line[BUFSIZ];
                    328:     struct adrx *adrxp;
                    329:     struct header  *hl;
                    330: 
                    331:     if ((i = mfgets (in, &bp)) != OK)
                    332:        return i;
                    333: 
                    334:     if ((cp = index (bp, ':')) == NULL) {
                    335:        fprintf (out, "Illegal-Field: %s\n", bp);
                    336:        return OK;
                    337:     }
                    338: 
                    339:     *cp = NULL;
                    340:     for (hl = &headers[0]; hl -> h_name; hl++)
                    341:        if (lequal (hl -> h_name, bp))
                    342:            break;
                    343: 
                    344: /*  */
                    345: 
                    346:     switch (hl -> h_type) {
                    347:        case HDATE: 
                    348:            if (lequal (hl -> h_name, "Date"))
                    349:                (*seen_date)++;
                    350:            for (pp = cp + 1; isspace (*pp); pp++)
                    351:                continue;
                    352:            date_convert (pp, line);
                    353:            if (line[0] == NULL)
                    354:                fprintf (out, "Illegal-Object: %s: %s -- %s\n",
                    355:                        hl -> h_name, pp, "illegal date construct");
                    356:            else
                    357:                fprintf (out, "%s: %s\n", hl -> h_name, line);
                    358:            break;
                    359:            
                    360:        case HOTHR: 
                    361:            *cp = ':';
                    362:            fprintf (out, "%s\n", bp);
                    363:            break;
                    364: 
                    365:        case HFROM: 
                    366:        case HSNDR: 
                    367:            if (hl -> h_type == HFROM)
                    368:                (*seen_from)++;
                    369:            else
                    370:                (*seen_sender)++;
                    371:        case HADDR: 
                    372:            spat = 0;
                    373:            some = FALSE;
                    374:            pp = ++cp;
                    375:            margin = pos = strlen (hl -> h_name) + 2;
                    376:            while (adrxp = seekadrx (pp)) {
                    377:                addr_convert (adrxp, line, FALSE);
                    378:                if (line[0] != NULL) {
                    379:                    if (!spat++)
                    380:                        fprintf (out, "%s: ", hl -> h_name);
                    381:                    if (some++)
                    382:                        fputs (", ", out), pos += 2;
                    383:                    if (pos + strlen (line) >= OWIDTH) {
                    384:                        fprintf (out, "\n%*s", margin, " ");
                    385:                        pos = margin;
                    386:                    }
                    387:                    fputs (line, out);
                    388:                    pos += strlen (line);
                    389:                }
                    390:                else {
                    391:                    if (spat)
                    392:                        putc ('\n', out);
                    393:                    fprintf (out, "Illegal-Object: %s: %s -- %s\n",
                    394:                            hl -> h_name, adrxp -> text, adrxp -> err);
                    395:                    spat = 0;
                    396:                    some = FALSE;
                    397:                    pos = margin;
                    398:                }
                    399:            }
                    400:            if (spat)
                    401:                putc ('\n', out);
                    402:            break;
                    403: 
                    404:        default: 
                    405:            return NOTOK;
                    406:     }
                    407: 
                    408:     return OK;
                    409: }
                    410: 
                    411: /*  */
                    412: 
                    413: addr_convert (adrxp, to, notice)
                    414: struct adrx *adrxp;
                    415: char   *to;
                    416: int     notice;
                    417: {
                    418:     int     addrlen,
                    419:             uucplen;
                    420:     char   *cp,
                    421:            *wp,
                    422:             addr[BUFSIZ],
                    423:             tmp[LINESIZ],
                    424:             uucp[LINESIZ];
                    425:     static char path[LINESIZ] = "";
                    426: 
                    427:     if (adrxp -> err || !adrxp -> mbox) {
                    428:        *to = NULL;
                    429:        return;
                    430:     }
                    431:     if (notice)
                    432:        if ((cp = rindex (adrxp -> mbox, '!')) != NULL)
                    433:            sprintf (path, "%.*s!", cp - adrxp -> mbox, adrxp -> mbox);
                    434:        else
                    435:            path[0] = NULL;
                    436: 
                    437:     sprintf (addr, "%s%s", path, adrxp -> mbox);
                    438:     sprintf (uucp, "%s!", SystemName ());
                    439:     uucplen = strlen (uucp);
                    440:     if ((addrlen = strlen (addr) - uucplen - 1) >= 0)
                    441:        for (cp = addr + addrlen; cp >= addr; cp--)
                    442:            if (strncmp (cp, uucp, uucplen) == NULL) {
                    443:                if (cp != addr && *(cp - 1) != '!')
                    444:                    continue;
                    445:                strcpy (addr, cp + uucplen);
                    446:                break;
                    447:            }
                    448: 
                    449: /*  */
                    450: 
                    451:     if (adrxp -> host == NULL) {
                    452:        cp = shrink (addr);
                    453: #ifdef MMDFMTS
                    454:        sprintf (uucp, "%s%%%s@%s", cp, UucpChan (), LocalName ());
                    455: #else  MMDFMTS
                    456:        if (wp = index (adrxp -> mbox, '!'))
                    457:            sprintf (uucp, "%s@%.*s.%s",
                    458:                wp + 1, wp - adrxp -> mbox, adrxp -> mbox, UucpChan ());
                    459:        else
                    460:            sprintf (uucp, "%s@%s.%s",
                    461:                adrxp -> mbox, SystemName (), UucpChan ());
                    462: #endif MMDFMTS
                    463:        if (strcmp (adrxp -> mbox, cp))
                    464:            sprintf (tmp, "\"%s\" <%s>", adrxp -> mbox, uucp);
                    465:        else
                    466:            strcpy (tmp, uucp);
                    467:     }
                    468:     else
                    469:        if ((wp = rindex (adrxp -> mbox, '!')) == NULL)
                    470:            sprintf (tmp, "%s@%s", adrxp -> mbox, adrxp -> host);
                    471:        else {
                    472:            sprintf (uucp, "%%%s", UucpChan ());
                    473:            uucplen = strlen (uucp);
                    474:            cp = (lequal (LocalName (), adrxp -> host)
                    475:                    && (addrlen = strlen (addr) - uucplen) > 0)
                    476:                ? addr + addrlen : NULL;
                    477:            if (lequal (uucp, cp))
                    478:                sprintf (tmp, "%s@%s", shrink (addr), adrxp -> host);
                    479:            else {
                    480:                if (lequal (adrxp -> mbox, ++wp))
                    481:                    sprintf (tmp, "%s@%s", wp, adrxp -> host);
                    482:                else
                    483:                    sprintf (tmp, "\"%s\" <%s@%s>", adrxp -> mbox,
                    484:                            wp, adrxp -> host);
                    485:            }
                    486:        }
                    487: 
                    488:     strcpy (to, tmp);
                    489: }
                    490: 
                    491: /*  */
                    492: 
                    493: static char *shrink (addr)
                    494: char   *addr;
                    495: {
                    496:     int     i,
                    497:             j;
                    498:     char   *cp,
                    499:            *pp,
                    500:            *wp,
                    501:            *xp;
                    502:     static char r1[BUFSIZ],
                    503:                 r2[BUFSIZ];
                    504: 
                    505:     sprintf (r2, "%s!", SystemName ());
                    506:     i = strlen (r2);
                    507:     if ((j = strlen (addr) - i - 1) >= 0)
                    508:        for (cp = &addr[j]; cp >= addr; cp--)
                    509:            if (strncmp (cp, r2, i) == NULL) {
                    510:                if (cp != addr && *(cp - 1) != '!')
                    511:                    continue;
                    512:                strcpy (addr, cp + i);
                    513:                break;
                    514:            }
                    515: 
                    516:     if ((cp = rindex (addr, '!')) == NULL) {
                    517:        sprintf (r1, "%s%s", r2, addr);
                    518:        return r1;
                    519:     }
                    520:     *cp++ = NULL;
                    521: 
                    522:     if ((pp = rindex (addr, '!')) == NULL) {
                    523:        *--cp = '!';
                    524:        strcpy (r1, addr);
                    525:        return r1;
                    526:     }
                    527:     strcpy (r1, cp);
                    528: 
                    529:     while ((pp = rindex (addr, '!')) != NULL) {
                    530:        for (pp++, xp = addr; (wp = index (xp, '!')) != NULL;) {
                    531:            *wp = NULL;
                    532:            if (strcmp (pp, xp)) {
                    533:                *wp++ = '!';
                    534:                xp = wp;
                    535:            }
                    536:            else {
                    537:                pp = xp;
                    538:                break;
                    539:            }
                    540:        }
                    541:        sprintf (r2, "%s!%s", pp, r1);
                    542:        strcpy (r1, r2);
                    543:        if (--pp > addr)
                    544:            *pp = NULL;
                    545:     }
                    546: 
                    547: /*  */
                    548: 
                    549:     if ((wp = index (r1, '!')) != NULL) {
                    550:        *wp = NULL;
                    551:        strcpy (r2, r1);
                    552:        *wp = '!';
                    553:        if (strcmp (addr, r2)) {
                    554:            sprintf (r2, "%s!%s", addr, r1);
                    555:            strcpy (r1, r2);
                    556:        }
                    557:     }
                    558: 
                    559:     return r1;
                    560: }
                    561: 
                    562: /*  */
                    563: 
                    564: date_convert (from, to)
                    565: char    from[],
                    566:        *to;
                    567: {
                    568:     static int  zone = -1,
                    569:                 flags = TW_NULL;
                    570:     char    date[LINESIZ];
                    571:     struct tws *tw;
                    572: 
                    573:     if (dparsetime (from))     /* might be OK as is */
                    574:        strcpy (date, from);
                    575:     else
                    576:        if (isdigit (from[20])) {
                    577:            if (zone == -1) {
                    578:                if (tw = dtwstime ()) {
                    579:                    zone = tw -> tw_zone;
                    580:                    flags = tw -> tw_flags;
                    581:                }
                    582:                else
                    583:                    zone = 0, flags = TW_NULL;
                    584:            }
                    585:            sprintf (date, "%.3s, %.2s %.3s %.2s %.2s:%.2s:%.2s %s",
                    586:                    from + 0, from + 8, from + 4, from + 22, from + 11,
                    587:                    from + 14, from + 17, dtimezone (zone, flags));
                    588:        }
                    589:        else
                    590:            sprintf (date, "%.3s, %.2s %.3s %.2s %.2s:%.2s:%.2s %s",
                    591:                    from + 0, from + 8, from + 4, from + 26, from + 11,
                    592:                    from + 14, from + 17, from + 20);
                    593: 
                    594:     strcpy (to, date);
                    595: }
                    596: 
                    597: /*  */
                    598: 
                    599: static int  uucp_die (error, in1, in2, out, nodelim)
                    600: int     error,
                    601:         nodelim;
                    602: FILE * in1, *in2, *out;
                    603: {
                    604:     long    clock;
                    605:     char    date[LINESIZ];
                    606: 
                    607:     if (nodelim) {
                    608:        fclose (in1);
                    609:        return error;
                    610:     }
                    611: 
                    612:     switch (error) {
                    613:        case MFHDR: 
                    614:            putc ('\n', out);
                    615:        case MFTXT: 
                    616:            fprintf (out, "\n%s", mmdlm2);
                    617:            break;
                    618:     }
                    619: 
                    620:     time (&clock);
                    621:     sprintf (date, "%.*s", sizeof date - 1, dtime (&clock));
                    622:     fprintf (out, "%sFrom: %s <%s@%s>\nDate: %s\nSubject: %s %s\n\n",
                    623:            mmdlm1, "UUCP to MMDF filter", getusr (), LocalName (), date,
                    624:            "Bad UUCP mailbox - error in",
                    625:            error == MFHDR ? "Header" : error == MFTXT ? "Body" : "Mailbox");
                    626: 
                    627:     fprintf (out, "%s: %s\n%s\n--------\n",
                    628:            "Error detected at line", buffer, "Message being processed");
                    629:     fseek (in1, 0L, 0);
                    630:     while (fgets (buffer, sizeof buffer, in1) != NULL) {
                    631:        if (isdlm2 (buffer))
                    632:            buffer[0]++;
                    633:        fputs (buffer, out);
                    634:     }
                    635:     fclose (in1);
                    636: 
                    637:     if (!feof (in2)) {
                    638:        fprintf (out, "--------\n%s\n--------\n%s",
                    639:                "Remainder of unfiltered mailbox follows", tmpbuf);
                    640:        while (fgets (buffer, sizeof buffer, in2) != NULL) {
                    641:            if (isdlm2 (buffer))
                    642:                buffer[0]++;
                    643:            fputs (buffer, out);
                    644:        }
                    645:     }
                    646: 
                    647:     fprintf (out, "--------\n%s", mmdlm2);
                    648:     fflush (out);
                    649: 
                    650:     return error;
                    651: }

unix.superglobalmegacorp.com

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