/*
**
** 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);
}
syntax highlighted by Code2HTML, v. 0.9.1