1 /* mmuu.c - routines to filter MMDF to UUCP mailboxes */
4 #include "../tws/tws.h"
6 #include "../mts/mts.h"
13 static struct header {
24 "Resent-Sender", HADDR,
25 "Resent-Reply-To", HADDR,
35 static char buffer[BUFSIZ],
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)
48 * It is assumed that the caller will have made sure that the necessary
49 * locking has been performed on the output fd.
52 int mmdf2uucp (infd, outfd, nodelim)
62 if (fstat (infd, &st) == NOTOK || fstat (outfd, &st) == NOTOK)
64 if ((in = fdopen (infd, "r")) == NULL
65 || (out = fdopen (outfd, "w")) == NULL)
68 result = mmuu (in, out, nodelim);
70 /* for STDIO - free up some fp:s */
71 fd = dup (fileno (in));
76 fd = dup (fileno (out));
86 static int mmuu (in, out, nodelim)
95 for (tmp_fd = NOTOK;;) {
96 if ((i = mmdf_file (&tmp_fd, in, &tmp, nodelim)) == DONE)
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);
109 return (ferror (in) || ferror (out) ? MFERR : MFOK);
114 static int mmdf_file (tmp_fd, in, tmp, nodelim)
121 char tmpfil[LINESIZ];
125 if (*tmp_fd != NOTOK)
128 if ((*tmp_fd = dup (fileno (in))) == NOTOK)
131 if ((*tmp = fdopen (*tmp_fd, "r")) == NULL) {
138 if (fgets (tmpbuf, sizeof tmpbuf, in) == NULL)
140 if (!isdlm1 (tmpbuf))
143 strcpy (tmpfil, "/tmp/mmuuXXXXXX");
144 unlink (mktemp (tmpfil));
145 if ((fd = creat (tmpfil, TMPMODE)) == NOTOK)
149 if ((fd = open (tmpfil, 2)) == NOTOK)
151 if ((out = fdopen (fd, "w")) == NULL) {
157 if ((*tmp_fd = dup (fd)) == NOTOK) {
161 if ((*tmp = fdopen (*tmp_fd, "r")) == NULL) {
169 for (done = FALSE;;) {
170 if (fgets (tmpbuf, sizeof tmpbuf, in) == NULL)
172 if (done && isdlm2 (tmpbuf))
174 done = tmpbuf[strlen (tmpbuf) - 1] == '\n';
185 static int mmdf_headers (in, out, nodelim)
199 *from = *date = NULL;
201 strcpy (tmpfil, "/tmp/mmuuXXXXXX");
202 unlink (mktemp (tmpfil));
203 if ((fd = creat (tmpfil, TMPMODE)) == NOTOK)
206 if ((tmp_fd = open (tmpfil, 2)) == NOTOK)
210 if ((fd = dup (tmp_fd)) == NOTOK) {
214 if ((tmp = fdopen (fd, "w")) == NULL) {
221 switch (do_header (from, date, in, tmp)) {
239 if (*date == NULL || *from == NULL) {
241 strcpy (buffer, "No (valid) From: field found in message\n");
244 strcpy (buffer, "No (valid) Date: field found in message\n");
247 "No (valid) From: or Date: fields found in message\n");
253 sprintf (date, "%.24s", ctime (&clock));
256 sprintf (from, "%s!%s", SystemName (), getusr ());
264 if (nodelim && (cp = index (from, '!')) != NULL) {
266 fprintf (out, "From %s %s remote from %s\n", cp, date, from);
269 fprintf (out, "From %s %s\n", from, date);
271 fprintf (out, "Munged: from %s to %s; %s\n",
272 LocalName (), SystemName (), dtimenow ());
274 fprintf (out, "Illegal-Field: %s", buffer);
276 if ((tmp = fdopen (tmp_fd, "r")) == NULL) {
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 */
292 static int mmdf_text (in, out, nodelim)
298 if (feof (in)) /* probably no body */
301 while ((i = fread (buffer, sizeof *buffer, sizeof buffer, in)) > 0)
302 fwrite (buffer, sizeof *buffer, i, out);
313 static int do_header (from, date, in, out)
330 if ((i = mfgets (in, &bp)) != OK)
333 if ((cp = index (bp, ':')) == NULL) {
334 fprintf (out, "Illegal-Field: %s\n", bp);
339 for (hl = &headers[0]; hl -> h_name; hl++)
340 if (lequal (hl -> h_name, bp))
345 switch (hl -> h_type) {
348 fprintf (out, "%s\n", bp);
353 if (*date != NULL || !lequal (hl -> h_name, "Date"))
355 date_convert (pp, date);
358 "Illegal-Object: %s: %s -- illegal date construct\n",
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) */
371 addr_convert (adrxp, from, TRUE);
373 fprintf (out, "Illegal-Object: %s: %s -- %s\n",
374 hl -> h_name, adrxp -> text, adrxp -> err);
375 while (getadrx (NULL))
384 margin = pos = strlen (hl -> h_name) + 2;
385 while (adrxp = getadrx (pp)) {
386 addr_convert (adrxp, line, FALSE);
387 if (line[0] != NULL) {
389 fprintf (out, "%s: ", hl -> h_name);
391 fputs (", ", out), pos += 2;
392 if (pos + strlen (line) >= OWIDTH) {
393 fprintf (out, "\n%*s", margin, " ");
397 pos += strlen (line);
402 fprintf (out, "Illegal-Object: %s: %s -- %s\n",
403 hl -> h_name, adrxp -> text, adrxp -> err);
422 static addr_convert (adrxp, to, notice)
432 static char path[LINESIZ] = "";
435 strcpy (path, LocalName ());
437 if (adrxp -> err || !adrxp -> mbox) {
442 strcpy (path, adrxp -> host ? adrxp -> host : LocalName ());
444 if (adrxp -> host == NULL)
445 if (index (adrxp -> mbox, '!') != NULL)
446 strcpy (tmp, adrxp -> mbox);
448 if (lequal (path, LocalName ()))
449 sprintf (tmp, "%s!%s", SystemName (), adrxp -> mbox);
451 sprintf (tmp, "%s!%s@%s", SystemName (), adrxp -> mbox, path);
453 if (index (adrxp -> mbox, '!') == NULL)
454 sprintf (tmp, "%s!%s@%s",
455 SystemName (), adrxp -> mbox, adrxp -> host);
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);
465 if ((cp = index (adrxp -> host, '.'))
466 && lequal (UucpChan (), cp + 1))
467 sprintf (tmp, "%.*s!%s",
468 cp - adrxp -> host, adrxp -> host, adrxp -> mbox);
470 if (lequal (adrxp -> host, UucpChan ()))
471 strcpy (tmp, adrxp -> mbox);
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);
479 sprintf (tmp, "%s@%s", adrxp -> mbox, adrxp -> host);
488 static date_convert (from, to)
494 if ((cp = dctime (dparsetime (from))) != NULL)
495 sprintf (to, "%.24s", cp);
502 static int mmdf_die (error, in1, in2, out, nodelim)
505 FILE * in1, *in2, *out;
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");
528 fprintf (out, "%s: %s\n%s\n--------\n",
529 "Error detected at line", buffer, "Message being processed");
531 while ((i = fread (buffer, sizeof *buffer, sizeof buffer, in1)) > 0)
532 fwrite (buffer, sizeof *buffer, i, out);
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);
542 fprintf (out, "--------\n\n");