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: }

Defined functions

addr_convert defined in line 413; used 2 times
date_convert defined in line 564; used 2 times
do_header defined in line 313; used 1 times
shrink defined in line 493; used 3 times
uucp_die defined in line 599; used 3 times
uucp_file defined in line 118; used 1 times
  • in line 98
uucp_from defined in line 196; used 1 times
uucp_headers defined in line 249; used 1 times
uucp_text defined in line 291; used 1 times
uumm defined in line 86; used 1 times
  • in line 68

Defined variables

buffer defined in line 34; used 24 times
headers defined in line 16; used 1 times
tmpbuf defined in line 35; used 8 times

Defined struct's

header defined in line 13; used 2 times
  • in line 329(2)
Last modified: 1986-04-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1830
Valid CSS Valid XHTML 1.0 Strict