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

Defined functions

addr_convert defined in line 422; used 2 times
date_convert defined in line 488; used 1 times
do_header defined in line 313; used 1 times
mmdf_die defined in line 502; used 2 times
mmdf_file defined in line 114; used 1 times
  • in line 96
mmdf_headers defined in line 185; used 1 times
mmdf_text defined in line 292; used 1 times
mmuu defined in line 86; used 1 times
  • in line 68

Defined variables

buffer defined in line 35; used 22 times
headers defined in line 16; used 1 times
tmpbuf defined in line 36; used 10 times

Defined struct's

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