/* ** ** Copyright (C) 1993 Swedish University Network (SUNET) ** ** ** This program is developed by UDAC, Uppsala University by commission ** of the Swedish University Network (SUNET). ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITTNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ** ** ** Martin.Wendel@its.uu.se ** Torbjorn.Wictorin@its.uu.se ** ** ITS ** P.O. Box 887 ** S-751 08 Uppsala ** Sweden ** */ #include "emil.h" extern FILE *out_fd; extern int smtp_client; static void print_rheader(struct header *, int); /* forward */ static void print_hvalue(struct hprs *); static void print_hbody(struct data *); char *eol = NULL; void out_message(struct message *m) { if (m == NULL) return; if (eol == NULL) { if (smtp_client) eol = NEWSTR("\r\n"); else eol = NEWSTR("\n"); } if (det_sket_sig == TRUE) { m->sd->offset = 0; m->sd->bodystart = 0; m->sd->bodyend = m->sd->end; print_body(m->sd, m->parent); return; } if (m->parent != NULL && target->iformat != RFC822) if (m->parent->td->startbound != NULL) { #ifdef DEBUG if (edebug) fprintf(stderr, "+ Start boundary %s\n", m->parent->td->startbound); #endif if (target->iformat == MIME) fprintf(out_fd, "%s%s%s", eol, m->parent->td->startbound, eol); else if (m->td->encoding != EMULTI) fprintf(out_fd, "%s%s", m->parent->td->startbound, eol); } /* encode_header(m); */ if (target->iformat != RFC822 || m->level == 0) { #ifdef DEBUG if (edebug) fprintf(stderr, "+ Printing header.\n"); #endif print_rheader(m->h, target->iformat); fprintf(out_fd, "%s", eol); /* End of header */ } if (m->td->bodyend) m->td->end = m->td->bodyend; m->td->offset = m->td->bodystart; if (m->td->encoding != EMULTI) print_body(m->td, m->parent); if (m->child != NULL) out_message(m->child); if (m->td->endbound != NULL && target->iformat == MIME) { #ifdef DEBUG if (edebug) fprintf(stderr, "+ End boundary %s\n", m->td->endbound); #endif fprintf(out_fd, "%s%s%s", eol, m->td->endbound, eol); } if (m->sibling != NULL) out_message(m->sibling); fflush(out_fd); } void print_body(struct data *d, struct message *parent) { struct data *line; long count; int len; int doeol = 0; int checkeol = 0; if (d == NULL) { #ifdef DEBUG fprintf(stderr, "* print_body: Called with NULL input, ignoring...\n"); #endif return; } if ((target->iformat != MIME) || (parent == NULL)) checkeol = 1; line = (struct data *)Yalloc(sizeof(struct data)); if (det_sket_sig == TRUE) { #ifdef DEBUG if (edebug) fprintf(stderr, "*** Printing transparent.\n"); #endif count = 0; } else { count = 1; #ifdef DEBUG if (edebug) fprintf(stderr, "+ Print body.\n"); #endif } d->offset = d->bodystart; while ((len = getline(d)) != 0) { line->end = 0; append_data(line, (d->contents + d->offset), len, MED_BUF); if (checkeol) { if (index(line->contents, '\n') == NULL) { doeol = 1; #ifdef DEBUG if (edebug) fprintf(stderr, "No EOL at line starting on d->offset = %d\n", d->offset); #endif } } else doeol = 0; if (strcmp(line->contents, ".\n") == 0 || strcmp(line->contents, ".\r\n") == 0) fprintf(out_fd, "."); if (count) { if (strncmp(line->contents, "From ", 5) == 0) fprintf(out_fd, ">"); print_line(line->contents); } else { if (want_unix_from == 0) { #ifdef OLD_UNIX_FROM if (strncmp(line->contents, "From ", 5) == 0) { d->offset += len; count++; continue; } else #endif /* OLD_UNIX_FROM */ print_line(line->contents); } else { if (strncmp(line->contents, "From ", 5) == 0) print_line(line->contents); else { fprintf(out_fd, "From %s%s", sender, eol); print_line(line->contents); } } } d->offset += len; count++; fflush(out_fd); } if (doeol) fprintf(out_fd, "%s", eol); fflush(out_fd); } static void print_rheader(struct header *h, int format) { struct header *th; static int hcount = 0; for (th = h; th != NULL; th = th->next) { #ifdef OLD_UNIX_FROM if (th->type == UNIXFROM && want_unix_from == 0) continue; #endif /* OLD_UNIX_FROM */ if (hcount == 0 && want_unix_from && th->type != UNIXFROM && sender != NULL) fprintf(out_fd, "From %s%s", sender, eol); hcount++; if (th->field != NULL && th->field->end != 0 && (th->format == RFC822 || th->format == format)) { parse_rfc1522(th); #ifdef DEBUG if (edebug) fprintf(stderr, "+ Print header (%s).\n", th->field->contents); #endif /* if (*th->field->contents == '>') fprintf(out_fd, "%s", th->field->contents + 1); else */ fprintf(out_fd, "%s", th->field->contents); if (th->type != UNIXFROM) { fprintf(out_fd, ": "); if (th->hvalue != NULL) (void)print_hvalue(th->hvalue); else if (th->value != NULL && th->value->end != 0) print_line(th->value->contents); } fprintf(out_fd, "%s", eol); } } } static void print_hvalue(struct hprs *h) { #ifdef DEBUG if (edebug) fprintf(stderr, "+ Printing hvalue structure.\n"); #endif switch (h->type) { case ATOM: case DELIMITER: case RFC1522: h->td->offset = h->td->bodystart; print_hbody(h->td); break; case DLITERAL: fprintf(out_fd, "["); break; case COMMENT: fprintf(out_fd, "("); break; case HQSTRING: fprintf(out_fd, "\""); break; case RADDR: fprintf(out_fd, "<"); break; default: break; } if (h->child != NULL) print_hvalue(h->child); switch(h->type) { case DLITERAL: fprintf(out_fd, "]"); break; case COMMENT: fprintf(out_fd, ")"); break; case HQSTRING: fprintf(out_fd, "\""); break; case RADDR: fprintf(out_fd, ">"); break; default: break; } if (h->sibling != NULL) print_hvalue(h->sibling); } static void print_hbody(struct data *d) { struct data * line; line = (struct data *)Yalloc(sizeof(struct data)); append_data(line, (d->contents + d->offset), d->bodyend - d->offset, MED_BUF); print_line(line->contents); } int print_line(char *s) { char *e, *c; int len; if (s == NULL) return(OK); len = strlen(s); while ((c = index(s, '\n')) != NULL) { e = c + 1; while (*c == '\n' || *c == '\r') { *c = '\0'; c--; } fprintf(out_fd, "%s%s", s, eol); s = e; } if (*s != '\0') fprintf(out_fd, "%s", s); return(OK); }