/*
**
** Copyright (C) 1994 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@udac.uu.se
**                                        Torbjorn.Wictorin@udac.uu.se
**
**                                        UDAC	
**                                        P.O. Box 174
**                                        S-751 04 Uppsala
**                                        Sweden
**
*/


#include "emil.h"
extern FILE *out_fd;

static	void	print_rheader(struct header *, int); /* forward */
static void print_hvalue(struct hprs *);
static void	print_hbody(struct data *);

void	out_message(struct message *m)
{
  if (m->parent != NULL && target->iformat != RFC822)
    if (m->parent->td->startbound != NULL)
      {
#ifdef DEBUG
	if (edebug)
	  fprintf(stderr, "+ Start boundary.\n");
#endif
	if (target->iformat == MIME)
	  fprintf(out_fd, "\n%s\n", m->parent->td->startbound);
	else
	  if (m->td->encoding != EMULTI)
	    fprintf(out_fd, "%s\n", m->parent->td->startbound);
      }
  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, "\n"); /* 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);

  if (m->child != NULL)
    out_message(m->child);
  if (m->sibling != NULL)
    out_message(m->sibling);
  if (m->td->endbound != NULL && target->iformat == MIME)
    {
#ifdef DEBUG
      if (edebug)
	fprintf(stderr, "+ End boundary.\n");
#endif
      fprintf(out_fd, "\n%s\n", m->td->endbound);
    }
  fflush(out_fd);
}

void	print_body(struct data *d)
{
  char line[LINELEN + 1];
  long count;
  int len;
  
  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
    }
  while ((len = getline(d)) != 0)
    {
      bzero(line, LINELEN + 1);
      strncpy(line, (d->contents + d->offset), len);
      if (strcmp(line, ".\n") == 0)
	fprintf(out_fd, ".");
      if (count)
	{
	  if (strncmp(line, "From ", 5) == 0)
	    fprintf(out_fd, ">");
	  fprintf(out_fd, "%s", line);
	}
      else
	{
	  if (*line == '>')
	    fprintf(out_fd, "%s", line + 1);
	  else
	    fprintf(out_fd, "%s", line);
	}
      d->offset += len;
      count++;
    }
/*  if (*(d->contents + d->offset - 1) != '\n')
    fprintf(out_fd, "\n"); */
  fflush(out_fd);
}

static	void print_rheader(struct header *h, int format)
{
  struct header *th;
  for (th = h; th != NULL; th = th->next)
    {
      if (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)
		  fprintf(out_fd, "%s", th->value->contents);
	    }
	  fprintf(out_fd, "\n");
      }
    }
}

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)
{
  char line[LINELEN + 1];
  int rest;

  while ((d->offset + LINELEN) < d->bodyend)
    {
      bzero(line, LINELEN + 1);
      strncpy(line, (d->contents + d->offset), LINELEN);
      fprintf(out_fd, "%s", line);
      d->offset += LINELEN;
    }
  if ((rest = d->bodyend - d->offset) > 0)
    {
      bzero(line, LINELEN + 1);
      strncpy(line, (d->contents + d->offset), rest);
      fprintf(out_fd, "%s", line);
    }
}

  
  
  
  
      
  
