*** collect.c.orig	Tue Nov  9 10:49:01 1993
--- collect.c	Fri Nov 12 08:02:57 1993
***************
*** 241,254 ****
  	}
  	else if (workbuf == buf2)	/* guarantee `buf' contains data */
  		(void) strcpy(buf, buf2);
  
  	/*
  	**  Collect the body of the message.
  	*/
  
  	for (;;)
! 	{
  		register char *bp = buf;
  
  		fixcrlf(buf, TRUE);
  
--- 241,276 ----
  	}
  	else if (workbuf == buf2)	/* guarantee `buf' contains data */
  		(void) strcpy(buf, buf2);
  
+ #ifdef EMIL
+ 
+ 	/* Connect collected header with MkMess_Root structure
+ 	 * and run the TCL scripts.
+ 	 */
+ 	if (CurEnv->e_from.q_mailer->m_charset) {
+ 	  Mk_Log(LOG_DEBUG, "Setting fromcharset %s from mailer %s",
+ 		 CurEnv->e_from.q_mailer->m_charset,
+ 		 CurEnv->e_from.q_mailer->m_name);
+ 	  MkMess_Root->fcharset = (char *)
+ 	    newstr(CurEnv->e_from.q_mailer->m_charset);
+ 	  MkMess_Root->esc = (short)CurEnv->e_from.q_mailer->m_esc;
+ 	}
+ 
+ 	MkMess_Root->header = (HDR *)CurEnv->e_header;
+ 	MkMess_Root->washeaders = TRUE;
+ 	MkMess_Root->investigate = TRUE;
+ 	Mk_Eval_Header();
+ 	linecount = 0;
+ 	MkMess_Buf->in = (char *)buf;
+ #endif /* EMIL */
+ 
  	/*
  	**  Collect the body of the message.
  	*/
  
  	for (;;)
! 	  {
  		register char *bp = buf;
  
  		fixcrlf(buf, TRUE);
  
***************
*** 269,287 ****
  		fputs(bp, tf);
  		fputs("\n", tf);
  		if (ferror(tf))
  			tferror(tf, e);
  		if (sfgets(buf, MAXLINE, InChannel, TimeOuts.to_datablock,
  				"message body read") == NULL)
  			goto readerr;
  	}
  
  	if (feof(InChannel) || ferror(InChannel))
! 	{
  readerr:
  		inputerr = TRUE;
  	}
  
  	if (fflush(tf) != 0)
  		tferror(tf, e);
  	if (fsync(fileno(tf)) < 0 || fclose(tf) < 0)
  	{
--- 291,314 ----
  		fputs(bp, tf);
  		fputs("\n", tf);
  		if (ferror(tf))
  			tferror(tf, e);
+ #ifdef EMIL
+ 		mkcollect(buf, sizeof(buf), InChannel);
+ #endif /* EMIL */
  		if (sfgets(buf, MAXLINE, InChannel, TimeOuts.to_datablock,
  				"message body read") == NULL)
  			goto readerr;
  	}
  
+ 
  	if (feof(InChannel) || ferror(InChannel))
!         {
  readerr:
  		inputerr = TRUE;
  	}
  
+ 
  	if (fflush(tf) != 0)
  		tferror(tf, e);
  	if (fsync(fileno(tf)) < 0 || fclose(tf) < 0)
  	{
***************
*** 370,377 ****
--- 397,409 ----
  		/* we haven't acked receipt yet, so just chuck this */
  		syserr("Cannot reopen %s", e->e_df);
  		finis();
  	}
+ #ifdef EMIL
+ 	if (!MkMess_Curr->end_line)
+ 	  MkMess_Curr->end_line = linecount;
+ 	mkcollqueueup();
+ #endif /* EMIL */
  }
  /*
  **  FLUSHEOL -- if not at EOL, throw away rest of input line.
  **
*** conf.h.orig	Tue Nov  9 10:49:10 1993
--- conf.h	Wed Nov 10 11:22:59 1993
***************
*** 88,95 ****
--- 88,99 ----
  # define USERDB		1	/* look in user database (requires NEWDB) */
  # endif
  
  /*
+ ** Define EMIL if you want to use the Emil message conversion system.
+ */
+ # define EMIL
+ /*
  **  Due to a "feature" in some operating systems such as Ultrix 4.3 and
  **  HPUX 8.0, if you receive a "No route to host" message (ICMP message
  **  ICMP_UNREACH_HOST) on _any_ connection, all connections to that host
  **  are closed.  Some firewalls return this error if you try to connect
*** deliver.c.orig	Tue Nov  9 10:49:18 1993
--- deliver.c	Tue Nov  9 12:24:36 1993
***************
*** 324,332 ****
  	int pid;
  	register ADDRESS *q;
  	char *qf;
  	char *id;
! 
  	/*
  	**  If we have had global, fatal errors, don't bother sending
  	**  the message at all if we are in SMTP mode.  Local errors
  	**  (e.g., a single address failing) will still cause the other
--- 324,334 ----
  	int pid;
  	register ADDRESS *q;
  	char *qf;
  	char *id;
! #ifdef EMIL
! 	HDR *mkroothdr;
! #endif
  	/*
  	**  If we have had global, fatal errors, don't bother sending
  	**  the message at all if we are in SMTP mode.  Local errors
  	**  (e.g., a single address failing) will still cause the other
***************
*** 431,439 ****
  	*/
  
  	e->e_nsent = 0;
  	e->e_flags |= EF_GLOBALERRS;
! 
  	/* now run through the queue */
  	for (q = e->e_sendqueue; q != NULL; q = q->q_next)
  	{
  #ifdef XDEBUG
--- 433,451 ----
  	*/
  
  	e->e_nsent = 0;
  	e->e_flags |= EF_GLOBALERRS;
! #ifdef EMIL
! 	/*
! 	 * Because Emil changes the headerstructure it is
! 	 * essential to refresh it for every copy to send
! 	 * if more than one.
! 	 */
! 	if (e->e_sendqueue->q_next != NULL)
! 	  mkroothdr = e->e_header;
! 	else
! 	  mkroothdr = NULL;
! #endif /* EMIL */
  	/* now run through the queue */
  	for (q = e->e_sendqueue; q != NULL; q = q->q_next)
  	{
  #ifdef XDEBUG
***************
*** 454,462 ****
--- 466,485 ----
  			}
  		}
  		else if (!bitset(QDONTSEND|QBADADDR, q->q_flags))
  		{
+ #ifdef EMIL
+ 		  if (mkroothdr != NULL)
+ 		    {
+ 		      Mk_Log(LOG_DEBUG, "Copying header");
+ 		      e->e_header =
+ 			(HDR *)Mk_CopyHdr(mkroothdr);
+ 		      Mk_Tcl();
+ 		      Mk_Log(LOG_DEBUG, "Done");
+ 		    }
+ #endif /* EMIL */		  
  # ifdef QUEUE
+ 		  
  			/*
  			**  Checkpoint the send list every few addresses
  			*/
  
***************
*** 1340,1356 ****
--- 1363,1429 ----
  		}
  	}
  	else if (!clever)
  	{
+ #ifdef EMIL
+ 
+ 	  /* Evaluate message and decide what conversions should
+ 	   * be done
+ 	   */
+ 	  mkdeleval(m->m_mtype);
+ #endif /* EMIL */
+   
  		/*
  		**  Format and send message.
  		*/
  
  		putfromline(mci->mci_out, m, e);
  		(*e->e_puthdr)(mci->mci_out, m, e);
  		putline("\n", mci->mci_out, m);
+ #ifdef EMIL
+ 	  /*
+ 	   * If MkMess_Root->dotunnel send message without conversions.
+ 	   */
+ 	  if (MkMess_Root->dotunnel)
+ #endif /* EMIL */
  		(*e->e_putbody)(mci->mci_out, m, e, NULL);
+ #ifdef EMIL
+ 	  else
+ 	    {
+ 	      /*
+ 	       * Send off each bodypart 
+ 	       */
+ 	      linecount = 0;
+ 	      MkMess_Curr = MkMess_Root;
+ 	      do
+ 		{
+ 		  MkMess_Buf = MkMess_Curr->buf;
+ 		  if (MkMess_Curr != MkMess_Root)
+ 		    Mk_Put_Headers(mci->mci_out, m, FALSE);
+ 		  MkMess_Curr->investigate = FALSE;
+ 		  (*e->e_putbody)(mci->mci_out, m, e, NULL);
+ 		  MkMess_Curr = MkMess_Curr->next;
+ 		} while (MkMess_Curr);
  
+ 	      Mk_Log(LOG_DEBUG, "Munging boundaries");
+ 	      if (MkMess_Curr != MkMess_Root && MkMess_Root->dosubheaders)
+ 		while (MkMess_Root->bound != NULL) 
+ 		  {
+ 		    char buf[BUFSIZE];
+ 		    char *boundbuf;
+ 		    boundbuf = (char *)getendbound();
+ 		    if (boundbuf) 
+ 		      {
+ 			strcpy(buf, boundbuf);
+ 			boundbuf = buf;
+ 			putline(boundbuf, mci->mci_out, m);
+ 		      }
+ 		    rmlastbound();
+ 		  }
+ 	    }
+ 	  Mk_Log(LOG_DEBUG, "Processing done");
+ #endif /* EMIL */
+ 
  		/* get the exit status */
  		rcode = endmailer(mci, e, pv);
  	}
  	else
***************
*** 1902,1910 ****
--- 1975,1996 ----
  			putline("<<< No Message Collected >>>", fp, m);
  	}
  	if (e->e_dfp != NULL)
  	{
+ #ifdef EMIL
+ 	  /* Just in case it screwed up
+ 	   */
+ 	  if (MkMess_Curr == NULL) {
+ 	    MkMess_Curr = MkMess_Root;
+ 	    MkMess_Root->dotunnel = TRUE;
+ 	  }
+ 	  else
+ 	    if (MkMess_Curr == MkMess_Root)
+ #endif /* EMIL */
  		rewind(e->e_dfp);
+ #ifdef EMIL
+ 	  if (MkMess_Root->dotunnel)
+ #endif /* EMIL */
  		while (!ferror(fp) && fgets(buf, sizeof buf, e->e_dfp) != NULL)
  		{
  			if (buf[0] == 'F' && bitnset(M_ESCFROM, m->m_flags) &&
  			    strncmp(buf, "From ", 5) == 0)
***************
*** 1918,1926 ****
  					(void) putc(' ', fp);
  			}
  			putline(buf, fp, m);
  		}
! 
  		if (ferror(e->e_dfp))
  		{
  			syserr("putbody: %s: read error", e->e_df);
  			ExitStat = EX_IOERR;
--- 2004,2015 ----
  					(void) putc(' ', fp);
  			}
  			putline(buf, fp, m);
  		}
! #ifdef EMIL
! 	  else
! 	    mkputbodypart(e->e_dfp, fp, m);
! #endif /* EMIL */
  		if (ferror(e->e_dfp))
  		{
  			syserr("putbody: %s: read error", e->e_df);
  			ExitStat = EX_IOERR;
*** envelope.c.orig	Tue Nov  9 10:49:28 1993
--- envelope.c	Tue Nov  9 12:45:21 1993
***************
*** 246,253 ****
--- 246,257 ----
  		if (tTd(50, 1))
  			printf("\n===== Dropping [dq]f%s =====\n\n", e->e_id);
  		if (e->e_df != NULL)
  			xunlink(e->e_df);
+ #ifdef EMIL
+ 		if (e->e_mf != NULL)
+ 		  xunlink(e->e_mf);
+ #endif /* EMIL */
  		xunlink(queuename(e, 'q'));
  
  #ifdef LOG
  		if (LogLevel > 10)
***************
*** 392,400 ****
  	define('c', newstr(cbuf), e);
  
  	/* time as integer, unix time, arpa time */
  	settime(e);
! 
  #ifdef TTYNAME
  	/* tty name */
  	if (macvalue('y', e) == NULL)
  	{
--- 396,406 ----
  	define('c', newstr(cbuf), e);
  
  	/* time as integer, unix time, arpa time */
  	settime(e);
! #ifdef EMIL
! 	Mk_Tcl();
! #endif /* EMIL */
  #ifdef TTYNAME
  	/* tty name */
  	if (macvalue('y', e) == NULL)
  	{
*** queue.c.orig	Tue Nov  9 10:49:33 1993
--- queue.c	Wed Nov 10 13:53:21 1993
***************
*** 161,170 ****
  			printf("NULL\n");
  		else
  			dumpfd(fileno(e->e_lockfp), TRUE, FALSE);
  	}
! 
  	/*
  	**  If there is no data file yet, create one.
  	*/
  
  	if (e->e_df == NULL)
--- 161,180 ----
  			printf("NULL\n");
  		else
  			dumpfd(fileno(e->e_lockfp), TRUE, FALSE);
  	}
! #ifdef EMIL
  	/*
+ 	 * If there is no message control file yet, create one.
+ 	 */
+ 	if (e->e_mf == NULL)
+ 	  {
+ 	    char *qp;
+ 	    qp = queuename(e, 'm');
+ 	    e->e_mf = newstr(qp);
+ 	  }
+ #endif /* EMIL */
+ 	/*
  	**  If there is no data file yet, create one.
  	*/
  
  	if (e->e_df == NULL)
***************
*** 524,532 ****
  	**	First, read and sort the entire queue.
  	**	Then, process the work in that order.
  	**		But if you take too long, start over.
  	*/
! 
  	/* order the existing work requests */
  	(void) orderq(FALSE);
  
  	/* process them once at a time */
--- 534,544 ----
  	**	First, read and sort the entire queue.
  	**	Then, process the work in that order.
  	**		But if you take too long, start over.
  	*/
! #ifdef EMIL
! 	Mk_Tcl();
! #endif /* EMIL */
  	/* order the existing work requests */
  	(void) orderq(FALSE);
  
  	/* process them once at a time */
***************
*** 899,907 ****
  		}
  
  		e->e_flags |= EF_INQUEUE;
  		eatheader(e, requeueflag);
! 
  		if (requeueflag)
  			queueup(e, TRUE, FALSE);
  
  		/* do the delivery */
--- 911,937 ----
  		}
  
  		e->e_flags |= EF_INQUEUE;
  		eatheader(e, requeueflag);
! #ifdef EMIL
! 		e->e_mf = newstr(queuename(e, 'm'));
! 		if (TRUE)
! 		  {
! 		    FILE *mfp;
! 		    if ((mfp = fopen(e->e_mf, "r")) == NULL)
! 		      {
! 			syslog(LOG_NOTICE, "Emil: Cannot open %s ...using transparent mode",
! 			       e->e_mf);
! 			MkMess_Root->dotunnel = TRUE;
! 		      }
! 		    else
! 		      {
! 			mkreadqf(mfp, MkMess_Root);
! 			fclose(mfp);
! 		      }
! 		  }
! #endif /* EMIL */
! 				 
  		if (requeueflag)
  			queueup(e, TRUE, FALSE);
  
  		/* do the delivery */
*** readcf.c.orig	Tue Nov  9 10:49:42 1993
--- readcf.c	Tue Nov  9 13:00:43 1993
***************
*** 673,680 ****
--- 673,683 ----
  **			   A -- the argv for this mailer
  **			   S -- the sender rewriting set
  **			   R -- the recipient rewriting set
  **			   E -- the eol string
+ **                         T -- the message type
+ **                         C -- the default charset
+ **                         X -- the default escape
  **			The first word is the canonical name of the mailer.
  **
  **	Returns:
  **		none.
***************
*** 793,800 ****
--- 796,814 ----
  
  		  case 'D':		/* working directory */
  			m->m_execdir = newstr(p);
  			break;
+ #ifdef EMIL
+ 		      case 'T':
+ 			m->m_mtype = newstr(p);
+ 			break;
+ 		      case 'C':
+ 			m->m_charset = newstr(p);
+ 			break;
+ 		      case 'X':
+ 			m->m_esc = atol(p);
+ 			break;
+ #endif /* EMIL */
  		}
  
  		p = delimptr;
  	}
No differences encountered
*** sendmail.h.orig	Sun Oct 31 20:23:14 1993
--- sendmail.h	Wed Nov 10 11:27:43 1993
***************
*** 174,181 ****
--- 174,186 ----
  	short	m_rh_rwset;	/* rewrite set: recipient header addresses */
  	short	m_re_rwset;	/* rewrite set: recipient envelope addresses */
  	char	*m_eol;		/* end of line string */
  	long	m_maxsize;	/* size limit on message to this mailer */
+ #ifdef EMIL
+ 	char    *m_mtype;       /* Emil script name */
+         char    *m_charset;
+ 	short   m_esc;
+ #endif /* EMIL */
  	int	m_linelimit;	/* max # characters per line */
  	char	*m_execdir;	/* directory to chdir to before execv */
  };
  
***************
*** 305,312 ****
--- 310,321 ----
  	FILE		*e_dfp;		/* temporary file */
  	char		*e_id;		/* code for this entry in queue */
  	FILE		*e_xfp;		/* transcript file */
  	FILE		*e_lockfp;	/* the lock file for this message */
+ #ifdef EMIL
+ 	char            *e_mf;          /* location of message file */
+ 	FILE            *e_mfp;         /* message file */
+ #endif /* EMIL */
  	char		*e_message;	/* error message */
  	char		*e_statmsg;	/* stat msg (changes per delivery) */
  	char		*e_msgboundary;	/* MIME-style message part boundary */
  	char		*e_origrcpt;	/* original recipient (one only) */
***************
*** 942,945 ****
--- 951,959 ----
  extern void		usrerr();
  extern void		message();
  extern void		nmessage();
  #endif
+ # ifdef EMIL
+ #   include "../emil/charset/iso646.h"
+ #   include "../emil/charset/charset.h"
+ #   include "../emil/mkspec.h"
+ # endif /* EMIL */
*** srvrsmtp.c.orig	Fri Nov 12 08:21:08 1993
--- srvrsmtp.c	Fri Nov 12 08:28:08 1993
***************
*** 283,290 ****
--- 283,293 ----
  			if (MaxMessageSize > 0)
  				message("250-SIZE %ld", MaxMessageSize);
  			else
  				message("250-SIZE");
+ #ifdef EMIL
+ 			message("250-8BITMIME");
+ #endif
  			message("250 HELP");
  			break;
  
  		  case CMDMAIL:		/* mail -- designate sender */
*** usersmtp.c.orig	Tue Nov  9 10:50:03 1993
--- usersmtp.c	Fri Nov 12 08:50:34 1993
***************
*** 517,530 ****
  	if (timeout < (time_t) 60)
  		timeout = (time_t) 60;
  	timeout += e->e_nrcpts * 90;
  	ev = setevent(timeout, datatimeout, 0);
! 
  	/* now output the actual message */
  	(*e->e_puthdr)(mci->mci_out, m, e);
  	putline("\n", mci->mci_out, m);
  	(*e->e_putbody)(mci->mci_out, m, e, NULL);
! 
  	clrevent(ev);
  
  	if (ferror(mci->mci_out))
  	{
--- 517,565 ----
  	if (timeout < (time_t) 60)
  		timeout = (time_t) 60;
  	timeout += e->e_nrcpts * 90;
  	ev = setevent(timeout, datatimeout, 0);
! #ifdef EMIL
! 	if (mci->mci_flags & MCIF_8BITMIME)
! 	  mkdeleval("8bitmime");
! 	else
! 	  mkdeleval(m->m_mtype);
! #endif /* EMIL */
  	/* now output the actual message */
  	(*e->e_puthdr)(mci->mci_out, m, e);
  	putline("\n", mci->mci_out, m);
+ #ifdef EMIL
+ 	if (MkMess_Root->dotunnel)
+ #endif /* EMIL */
  	(*e->e_putbody)(mci->mci_out, m, e, NULL);
! #ifdef EMIL
! 	else
! 	  {
! 	    linecount = 0;
! 	    MkMess_Curr = MkMess_Root;
! 	    do
! 	      {
! 		MkMess_Buf = MkMess_Curr->buf;
! 		if (MkMess_Curr != MkMess_Root)
! 		  Mk_Put_Headers(mci->mci_out, m, FALSE);
! 		MkMess_Curr->investigate = FALSE;
! 		(*e->e_putbody)(mci->mci_out, m, e, NULL);
! 		MkMess_Curr = MkMess_Curr->next;
! 	      } while (MkMess_Curr);
! 	    while (MkMess_Root->bound != NULL) {
! 	      char buf[BUFSIZE];
! 	      char *boundbuf;
! 	      boundbuf = (char *)getendbound();
! 	      if (boundbuf) {
! 		strcpy(buf, boundbuf);
! 		boundbuf = buf;
! 		putline(boundbuf, mci->mci_out, m);
! 	      }
! 	      rmlastbound();
! 	    }
! 	  }
! 	Mk_Log(LOG_DEBUG, "Processing done");
! #endif /* EMIL */
  	clrevent(ev);
  
  	if (ferror(mci->mci_out))
  	{
*** util.c.orig	Sun Oct 31 22:05:43 1993
--- util.c	Thu Nov 11 13:55:19 1993
***************
*** 106,113 ****
--- 106,117 ----
  		syserr("Out of memory!!");
  		abort();
  		/* exit(EX_UNAVAILABLE); */
  	}
+ #ifdef EMIL
+ 	/* Emil depends on xalloc bzeroing the areas */
+ 	bzero(p, (unsigned)sz);
+ #endif /* EMIL */
  	return (p);
  }
  /*
  **  COPYPLIST -- copy list of pointers.
***************
*** 665,680 ****
  {
  	register char *p;
  	register char svchar;
  
  	/* strip out 0200 bits -- these can look like TELNET protocol */
  	if (bitnset(M_7BITS, m->m_flags))
  	{
  		for (p = l; (svchar = *p) != '\0'; ++p)
  			if (bitset(0200, svchar))
  				*p = svchar &~ 0200;
  	}
! 
  	do
  	{
  		/* find the end of the line */
  		p = strchr(l, '\n');
--- 669,685 ----
  {
  	register char *p;
  	register char svchar;
  
+ #ifndef EMIL
  	/* strip out 0200 bits -- these can look like TELNET protocol */
  	if (bitnset(M_7BITS, m->m_flags))
  	{
  		for (p = l; (svchar = *p) != '\0'; ++p)
  			if (bitset(0200, svchar))
  				*p = svchar &~ 0200;
  	}
! #endif
  	do
  	{
  		/* find the end of the line */
  		p = strchr(l, '\n');
***************
*** 857,867 ****
--- 862,874 ----
  		return (NULL);
  	}
  	if (TrafficLogFile != NULL)
  		fprintf(TrafficLogFile, "%05d <<< %s", getpid(), buf);
+ #ifndef EMIL
  	if (SevenBit)
  		for (p = buf; *p != '\0'; p++)
  			*p &= ~0200;
+ #endif
  	return (buf);
  }
  
  static
*** version.c.orig	Tue Nov  9 10:50:11 1993
--- version.c	Fri Nov 12 15:52:17 1993
***************
*** 35,39 ****
--- 35,43 ----
  #ifndef lint
  static char sccsid[] = "@(#)version.c	8.6.1.4 (Berkeley) 10/31/93";
  #endif /* not lint */
  
+ #ifdef EMIL
+ char    Version[] = "8.6.4+Emil1.1";
+ #else
  char	Version[] = "8.6.4";
+ #endif
