Removed the MTS and post; now we always use /usr/sbin/sendmail -t
authormarkus schnalke <meillo@marmaro.de>
Tue, 4 Oct 2011 16:36:14 +0000 (18:36 +0200)
committermarkus schnalke <meillo@marmaro.de>
Tue, 4 Oct 2011 16:36:14 +0000 (18:36 +0200)
Mmh won't talk SMTP (nor POP).
Also moved OfficialName() from /mts/smtp/hosts.c to sbr/addrsbr.c.

22 files changed:
INSTALL
Makefile.in
config/config.c
configure.in
etc/Makefile.in
etc/mts.conf.in
h/mts.h
h/rcvmail.h
man/mh-tailor.man
man/post.man
mts/Makefile.in [deleted file]
mts/smtp/Makefile.in [deleted file]
mts/smtp/hosts.c [deleted file]
mts/smtp/smtp.c [deleted file]
mts/smtp/smtp.h [deleted file]
sbr/addrsbr.c
sbr/mts.c
uip/Makefile.in
uip/mhl.c
uip/post.c [deleted file]
uip/scansbr.c
uip/show.c

diff --git a/INSTALL b/INSTALL
index 9db70d2..d4f7f24 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -61,17 +61,7 @@ need an ANSI C compiler such as gcc.
    The default `mts.conf' file assumes you retrieve new mail from
    a local (or NFS mounted) maildrop, and send outgoing mail by
    injecting the message to a mail transfer agent (such as sendmail)
-   on the local machine via SMTP.
-
-   If, instead, all your mail sending and receiving occurs on a 
-   remote SMTP server, you will need to look at the values of the 
-   variables "localname" and "servers":
-
-    a) "localname" defines the hostname that nmh considers local.
-       If not set, then nmh queries your OS for this value.
-
-    b) "servers" defines the server to which you send outgoing SMTP
-       traffic.
+   on the local machine.
 
    Check the `mh-tailor' man page for a list of all the available options
    for this file ("masquerade" may be of particular interest).
@@ -154,7 +144,7 @@ Options for configure
      nmh's binaries (show, inc, comp, ...) are installed here.
 
 --libdir=DIR     (DEFAULT is ${prefix}/lib)
-     nmh's support binaries (post, slocal, mhl, ...) are installed here.
+     nmh's support binaries (spost, slocal, mhl, ...) are installed here.
 
 --sysconfdir=DIR     (DEFAULT is ${prefix}/etc)
      nmh's config files (mts.conf, mhn.defaults, ...) are installed here.
@@ -204,28 +194,6 @@ Options for configure
      is not world- or user-writeable, and thus a lock file cannot
      be created.
 
---with-mts=MTS   (DEFAULT is smtp)
-     Specify the default mail transport system you want to use.  The two
-     acceptable options are "smtp" (which is the default), and
-     "sendmail".  This value will be put into the mts.conf file.  You
-     may find it convenient to specify a value at configure-time,
-     however, so that each time nmh is reinstalled, the right value will
-     be there.
-
-     If you use "smtp", this will enable a direct SMTP (simple mail
-     transport protocol) interface in nmh.  When sending mail, instead
-     of passing the message to the mail transport agent, `post' will
-     open a socket connection to the mail port on the machine specified
-     in the `mts.conf' file (default is localhost), and speak SMTP
-     directly.
-
-     If you use "sendmail", then `post' will send messages by forking a
-     local copy of sendmail.  Currently it will still speak SMTP with
-     this local copy of sendmail.
-
-     If you wish to use a transport agent other than sendmail, you will
-     need to use a `sendmail wrapper'.
-
 --with-ndbm=LIB    (DEFAULT is to autodetect)
 --with-ndbmheader=HEADER     (DEFAULT is to autodetect)
      Specify the header file (eg ndbm.h) and library (eg ndbm) to use
index 1fe2d38..81f7067 100644 (file)
@@ -74,7 +74,7 @@ DIST = ChangeLog COPYRIGHT DATE INSTALL MACHINES README VERSION               \
        config.sub config.guess
 
 # subdirectories in distribution
-SUBDIRS = h config sbr mts uip etc man docs
+SUBDIRS = h config sbr uip etc man docs
 
 # ========== DEPENDENCIES FOR BUILDING AND INSTALLING ==========
 
index de9e343..0603340 100644 (file)
@@ -196,7 +196,7 @@ char *faceproc = NULL;
 
 /*
  * This program is usually called directly by users, but it is
- * also invoked by the post program to process an "Fcc", or by
+ * also invoked by the spost program to process an "Fcc", or by
  * comp/repl/forw/dist to refile a draft message.
  */
 
@@ -243,7 +243,7 @@ char *moreproc = DEFAULT_PAGER;
  * used by mhn to filter and display the message headers of
  * MIME messages.  It is used by repl/forw (with -filter)
  * to filter the message to which you are replying/forwarding.
- * It is used by send/post (with -filter) to filter the message
+ * It is used by send/spost (with -filter) to filter the message
  * for "Bcc:" recipients.
  */
 
index 7f0dabb..6a4dfff 100644 (file)
@@ -144,15 +144,6 @@ else
   AC_DEFINE(DOT_LOCKING)dnl
 fi
 
-dnl What method of posting should post use?
-dnl We'll always use sendmail now. (mmh)
-MTS="sendmail"
-dnl #AC_SUBST(MTS)dnl
-
-dnl Both the smtp and sendmail mail transport services use the smtp code
-AC_DEFINE(SMTPMTS, 1,
-  [Define if you want SMTP (simple mail transport protocol) support.])dnl
-
 dnl What should be the default pager?
 AC_ARG_WITH(pager,
   AS_HELP_STRING([--with-pager=PAGER],[specify the default pager]))
@@ -923,7 +914,6 @@ dnl ----------------
 dnl OUTPUT MAKEFILES
 dnl ----------------
 AC_CONFIG_FILES(Makefile config/Makefile h/Makefile sbr/Makefile uip/Makefile \
-                mts/Makefile mts/smtp/Makefile \
                etc/Makefile docs/Makefile man/Makefile)
 AC_CONFIG_COMMANDS([stamp],[test -z "$CONFIG_HEADERS" || echo > stamp-h])
 AC_OUTPUT
@@ -955,7 +945,6 @@ library install path       : ${nmhlib}
 config files install path  : ${nmhsysconf}
 man page install path      : ${nmhman}
 backup prefix              : ${backup_prefix}
-transport system           : ${MTS}
 file locking type          : ${LOCKTYPE}
 default editor             : ${editorpath}
 default pager              : ${pagerpath}
index 0580723..faefd09 100644 (file)
@@ -14,7 +14,6 @@ bindir      = @bindir@
 libdir      = @libdir@
 etcdir      = @sysconfdir@
 
-MTS         = @MTS@
 mailspool   = @mailspool@
 masquerade  = @masquerade@
 
@@ -70,8 +69,7 @@ mhn.defaults: $(srcdir)/mhn.defaults.sh $(MHNSEARCHPROG)
 
 mts.conf: $(srcdir)/mts.conf.in Makefile
        rm -f $@
-       $(SED) -e 's,%mts%,$(MTS),' \
-              -e 's,%mailspool%,$(mailspool),' \
+       $(SED) -e 's,%mailspool%,$(mailspool),' \
               -e 's,%etcdir%,$(etcdir),' \
               -e 's,%masquerade%,$(masquerade),' < $(srcdir)/mts.conf.in > $@
 
index f6a1cca..b86878b 100644 (file)
@@ -5,16 +5,6 @@
 # all the available options for this file.
 #
 
-# The delivery method to use.  Supported values are `smtp' and `sendmail'.
-# When `smtp', nmh will open a socket connection to the mail port on the
-# machine specified below, and speak SMTP directly.
-# When `sendmail', nmh will pipe messages directly to the sendmail program.
-mts: %mts%
-
-# Name that nmh considers `local'.  If not set, nmh will
-# query the system for this value (gethostname, etc...).
-#localname: foo.bar.com
-
 # The following directive allows email address masquerading.  The string
 # "draft_from mmailid username_extension" will allow all three types.
 masquerade: %masquerade%
diff --git a/h/mts.h b/h/mts.h
index 9894a5d..c760618 100644 (file)
--- a/h/mts.h
+++ b/h/mts.h
@@ -42,20 +42,7 @@ void mts_init (char *);
 /*
  * MTS specific variables
  */
-#if defined (SMTPMTS)
-
-/* whether to speak SMTP to localhost:25 or to /usr/sbin/sendmail */
-#define MTS_SMTP     0
-#define MTS_SENDMAIL 1
-extern int sm_mts;
-
 extern char *sendmail;
-#endif
-
-/*
- * SMTP stuff
- */
-extern char *clientname;
 
 /*
  * Global MailDelivery File
index 37fba4d..b2a355e 100644 (file)
@@ -3,25 +3,11 @@
  * rcvmail.h -- rcvmail hook definitions
  */
 
-#if defined(SMTPMTS)
 # include <ctype.h>
 # include <errno.h>
 # include <setjmp.h>
 # include <stdio.h>
 # include <sys/types.h>
-# include <mts/smtp/smtp.h>
-#endif /* SMTPMTS */
 
-
-#if defined(SMTPMTS)
 # define RCV_MOK       0
 # define RCV_MBX       1
-#endif /* SMTPMTS */
-
-
-#ifdef NRTC                    /* sigh */
-# undef RCV_MOK
-# undef RCV_MBX
-# define RCV_MOK       RP_MOK
-# define RCV_MBX       RP_MECH
-#endif /* NRTC */
index 86659df..7623a7e 100644 (file)
@@ -27,60 +27,16 @@ Each option should be given on a single line.  Blank lines and lines
 which begin with `#' are ignored.  The options available along with
 default values and a description of their meanings are listed below:
 .PP
-.BR mts :
-.RS 5
-The mail transport method to use.  The two acceptable options are
-.B smtp
-(which is the default), and
-.BR sendmail .
-.PP
-If you use
-.BR smtp ,
-this will enable a direct SMTP (simple mail transport
-protocol) interface in
-.BR nmh .
-When sending mail, instead of passing the
-message to the mail transport agent,
-.B post
-will open a socket connection
-to the mail port on the machine specified in the
-.B servers
-entry.
-.PP
-If you use
-.BR sendmail ,
-then
-.B post
+.B spost
 will send messages by forking a
 local copy of
 .BR sendmail .
-Currently it will still speak SMTP with this local
-copy of
-.BR sendmail .
-.RE
-.PP
-.BR localname :
-.RS 5
-The hostname
-.B nmh
-considers local.  It should typically be a fully
-qualified hostname.  If this is not set, depending on the version of
-UNIX you're running,
-.B nmh
-will query the system for this value
-(e.g. uname, gethostname, etc.), and attempt to fully qualify this
-value.
 .PP
 If you are using POP to retrieve new messages, you may want to set this
 value to the name of the POP server, so that outgoing message appear to
 have originated on the POP server.
 .RE
 .PP
-.BR localdomain :
-.RS 5
-If this is set, a `.' followed by this string will be appended to your
-hostname.
-.PP
 This should only be needed, if for some reason
 .B nmh
 is not able to
@@ -88,55 +44,6 @@ fully qualify the hostname returned by the system (e.g. uname,
 gethostname, etc.).
 .RE
 .PP
-.BR clientname :
-.RS 5
-This option specifies the host name that
-.B nmh
-will give in the
-SMTP
-.B HELO
-(and
-.BR EHLO )
-command, when posting mail.  If not
-set, the default is to use the host name that
-.B nmh
-considers local
-(see
-.B localname
-above).  If this option is set, but empty, no
-.B HELO
-command will be given.
-.PP
-Although the
-/B HELO
-command is required by RFC\-821, many SMTP servers
-do not require it.  Early versions of
-.I SendMail
-will fail if the hostname
-given in the
-.B HELO
-command is the local host.  Later versions of
-.I SendMail
-will complain if you omit the
-.B HELO
-command.  If you run
-.IR SendMail ,
-find out what your system expects and set this field if needed.
-.RE
-.PP
-.BR systemname :
-.RS 5
-This option is only used for UUCP mail.  It specifies the name of the
-local host in the UUCP \*(lqdomain\*(rq.  If not set, depending
-on the version of UNIX you're running,
-.B nmh
-will query the system
-for this value.  This has no equivalent in the
-.B nmh
-configuration
-file.
-.RE
-.PP
 .BR mmdfldir :
 %mailspool%
 .RS 5
@@ -262,11 +169,6 @@ login shell equivalent to the given value (e.g., \*(lq/bin/csh\*(rq)
 indicates that mail for \*(lqeveryone\*(rq should not be sent to them.
 This is useful for handling admin, dummy, and guest logins.
 .SS "SendMail"
-This option is only available if you set
-.B mts
-to
-.BR sendmail .
-.PP
 .BR sendmail :
 %sendmailpath%
 .RS 5
index b6e395e..0f62631 100644 (file)
@@ -115,11 +115,8 @@ Under normal circumstances,
 .B post
 constructs the \*(lqFrom:\*(rq line of the
 message from the user's login name, the full name from the GECOS field of the
-passwd file, and the fully\-qualified name of the local machine (or the
-value of
-\*(lqlocalname\*(rq in
-.IR mts.conf ,
-if set).  An example is \*(lqFrom: Dan Harkless
+passwd file, and the fully\-qualified name of the local machine.
+An example is \*(lqFrom: Dan Harkless
 <dan@machine.company.com>\*(rq.  There are four ways to override these values,
 however.  Note that they apply equally to \*(lqResent\-From:\*(rq lines in messages sent
 with
diff --git a/mts/Makefile.in b/mts/Makefile.in
deleted file mode 100644 (file)
index eeafd3a..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-#
-# Makefile for mts subdirectory
-#
-
-SHELL = /bin/sh
-
-srcdir = @srcdir@
-VPATH  = @srcdir@
-
-# flags passed to recursive makes in subdirectories
-MAKEDEFS = CC='$(CC)' CPPFLAGS='$(CPPFLAGS)' DEFS='$(DEFS)' \
-CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' LIBS='$(LIBS)' \
-prefix='$(prefix)' exec_prefix='$(exec_prefix)' bindir='$(bindir)' \
-etcdir='$(etcdir)' libdir='$(libdir)' mandir='$(mandir)' \
-mailspool='$(mailspool)' sendmailpath='$(sendmailpath)' \
-default_editor='$(default_editor)' default_pager='$(default_pager)'
-
-LORDER = @LORDER@
-TSORT  = @TSORT@
-RANLIB = @RANLIB@
-LIBTOOL = @LIBTOOL@
-GNU_LIBTOOL = @GNU_LIBTOOL@
-
-# object files that go into libmts.a
-OBJS =  smtp/hosts.o smtp/smtp.o
-
-# auxiliary files
-AUX = Makefile.in
-
-# all files in this directory included in the distribution
-DIST = $(AUX)
-
-# subdirectories
-SUBDIRS = smtp
-
-# ========= DEPENDENCIES FOR BUILDING AND INSTALLING ==========
-
-all: all-recursive libmts.a
-
-all-recursive:
-       for subdir in $(SUBDIRS); do \
-         (cd $$subdir && $(MAKE) $(MAKEDEFS) all) || exit 1; \
-       done
-
-libmts.a: $(OBJS)
-       rm -f $@
-       if test x$(LIBTOOL) != x -a x$(GNU_LIBTOOL) = x ; then \
-         $(LIBTOOL) -static -c $(OBJS) -o $@  ; \
-       else \
-         ar cr $@ `$(LORDER) $(OBJS) | $(TSORT) 2>/dev/null`  ; \
-         $(RANLIB) $@  ; \
-       fi 
-
-install uninstall:
-
-# ========== DEPENDENCIES FOR CLEANUP ==========
-
-mostlyclean: mostlyclean-recursive mostlyclean-local
-clean:       clean-recursive       clean-local
-distclean:   distclean-recursive   distclean-local
-realclean:   realclean-recursive   realclean-local
-superclean:  superclean-recursive  superclean-local
-
-mostlyclean-local:
-       rm -f *~
-
-clean-local: mostlyclean-local
-       rm -f libmts.a
-distclean-local: clean-local
-       rm -f Makefile
-
-realclean-local: distclean-local
-
-superclean-local: realclean-local
-
-mostlyclean-recursive clean-recursive distclean-recursive realclean-recursive superclean-recursive:
-       for subdir in $(SUBDIRS); do \
-         target=`echo $@ | sed 's/-recursive//'`; \
-         (cd $$subdir && $(MAKE) $(MAKEDEFS) $$target) || exit 1; \
-       done
-
-# ========== DEPENDENCIES FOR LINT =================
-
-lint:
-       for subdir in $(SUBDIRS); do \
-         ( cd $$subdir && $(MAKE) $(MAKEDEFS) lint ) || exit 1; \
-       done
-
-# ========== DEPENDENCIES FOR MAINTENANCE ==========
-
-subdir = mts
-
-Makefile: Makefile.in ../config.status
-       cd .. && ./config.status $(subdir)/$@
-distdir = ../`cat ../distname`/$(subdir)
-nmhdist: $(DIST)
-       @echo "Copying distribution files in $(subdir)"
-       @for file in $(DIST); do \
-         cp -p $(srcdir)/$$file $(distdir); \
-       done
-       @for subdir in $(SUBDIRS); do \
-         mkdir $(distdir)/$$subdir; \
-         chmod 755 $(distdir)/$$subdir; \
-         (cd $$subdir && $(MAKE) $@) || exit 1; \
-       done
-
diff --git a/mts/smtp/Makefile.in b/mts/smtp/Makefile.in
deleted file mode 100644 (file)
index b2a4059..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-#
-# Makefile for mts/smtp subdirectory
-#
-
-SHELL = /bin/sh
-
-top_srcdir = @top_srcdir@
-srcdir     = @srcdir@
-VPATH      = @srcdir@
-
-prefix      = @prefix@
-exec_prefix = @exec_prefix@
-bindir      = @bindir@
-libdir      = @libdir@
-etcdir      = @sysconfdir@
-
-CC       = @CC@
-CFLAGS   = @CFLAGS@
-DEFS     = @DEFS@
-INCLUDES = -I../.. -I$(srcdir) -I$(top_srcdir) @CPPFLAGS@
-LINT   = @LINT@
-LINTFLAGS = @LINTFLAGS@
-
-COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CFLAGS)
-
-.SUFFIXES:
-.SUFFIXES: .c .o
-
-.c.o:
-       $(COMPILE) $<
-
-# header files
-HDRS = smtp.h
-
-# source
-SRCS = hosts.c smtp.c
-
-# object files in libsmtp.a
-OBJS = hosts.o smtp.o
-
-# auxiliary files
-AUX = Makefile.in
-
-# all files in this directory included in the distribution
-DIST = $(HDRS) $(SRCS) $(AUX)
-
-# ========= DEPENDENCIES FOR BUILDING AND INSTALLING ==========
-
-all: $(OBJS)
-
-install:
-
-uninstall:
-
-# ========== DEPENDENCIES FOR CLEANUP ==========
-
-mostlyclean:
-       rm -f *.o *~
-
-clean: mostlyclean
-
-distclean: clean
-       rm -f Makefile
-
-realclean: distclean
-
-superclean: realclean
-
-# ========== DEPENDENCIES FOR LINT =================
-
-lint: 
-       $(LINT) $(LINTFLAGS) $(INCLUDES) $(DEFS) $(SRCS)
-
-# ========== DEPENDENCIES FOR MAINTENANCE ==========
-
-subdir = mts/smtp
-
-Makefile: Makefile.in ../../config.status
-       cd ../.. && ./config.status $(subdir)/$@
-distdir = ../../`cat ../../distname`/$(subdir)
-nmhdist: $(DIST)
-       @echo "Copying distribution files in $(subdir)"
-       @for file in $(DIST); do \
-         cp -p $(srcdir)/$$file $(distdir); \
-       done
-
diff --git a/mts/smtp/hosts.c b/mts/smtp/hosts.c
deleted file mode 100644 (file)
index ec73e86..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-
-/*
- * hosts.c -- find out the official name of a host
- *
- * This code is Copyright (c) 2002, by the authors of nmh.  See the
- * COPYRIGHT file in the root directory of the nmh distribution for
- * complete copyright information.
- */
-
-/*
- * In the SendMail world, we really don't know what the valid
- * hosts are.  We could poke around in the sendmail.cf file, but
- * that still isn't a guarantee.  As a result, we'll say that
- * everything is a valid host, and let SendMail worry about it.
- */
-
-#include <h/mh.h>
-#include <h/mts.h>
-#include <netdb.h>
-
-
-char *
-OfficialName (char *name)
-{
-    unsigned char *p;
-    char *q, site[BUFSIZ];
-    struct addrinfo hints, *res;
-
-    static char buffer[BUFSIZ];
-
-    for (p = name, q = site; *p && (q - site < sizeof(site) - 1); p++, q++)
-       *q = isupper (*p) ? tolower (*p) : *p;
-    *q = '\0';
-    q = site;
-
-    if (!mh_strcasecmp (LocalName(), site))
-       return LocalName();
-
-    memset(&hints, 0, sizeof(hints));
-    hints.ai_flags = AI_CANONNAME;
-    hints.ai_family = PF_UNSPEC;
-
-    if (getaddrinfo(q, NULL, &hints, &res) == 0) {
-       strncpy (buffer, res->ai_canonname, sizeof(buffer));
-       buffer[sizeof(buffer) - 1] = '\0';
-       freeaddrinfo(res);
-       return buffer;
-    }
-
-    strncpy (buffer, site, sizeof(buffer));
-    return buffer;
-}
diff --git a/mts/smtp/smtp.c b/mts/smtp/smtp.c
deleted file mode 100644 (file)
index e7a64a0..0000000
+++ /dev/null
@@ -1,1713 +0,0 @@
-/*
- * smtp.c -- nmh SMTP interface
- *
- * This code is Copyright (c) 2002, by the authors of nmh.  See the
- * COPYRIGHT file in the root directory of the nmh distribution for
- * complete copyright information.
- */
-
-#include <h/mh.h>
-#include "smtp.h"
-#include <h/mts.h>
-#include <signal.h>
-#include <h/signals.h>
-
-#ifdef CYRUS_SASL
-#include <sasl/sasl.h>
-#include <sasl/saslutil.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <errno.h>
-#endif /* CYRUS_SASL */
-
-#ifdef TLS_SUPPORT
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#endif /* TLS_SUPPORT */
-
-/*
- * This module implements an interface to SendMail very similar
- * to the MMDF mm_(3) routines.  The sm_() routines herein talk
- * SMTP to a sendmail process, mapping SMTP reply codes into
- * RP_-style codes.
- */
-
-/*
- * On older 4.2BSD machines without the POSIX function `sigaction',
- * the alarm handing stuff for time-outs will NOT work due to the way
- * syscalls get restarted.  This is not really crucial, since SendMail
- * is generally well-behaved in this area.
- */
-
-#ifdef SENDMAILBUG
-/*
- * It appears that some versions of Sendmail will return Code 451
- * when they don't really want to indicate a failure.
- * "Code 451 almost always means sendmail has deferred; we don't
- * really want bomb out at this point since sendmail will rectify
- * things later."  So, if you define SENDMAILBUG, Code 451 is
- * considered the same as Code 250.  Yuck!
- */
-#endif
-
-#define        TRUE    1
-#define        FALSE   0
-
-#define        NBITS ((sizeof (int)) * 8)
-
-/*
- * these codes must all be different!
- */
-#define        SM_OPEN  300      /* Changed to 5 minutes to comply with a SHOULD in RFC 1123 */
-#define        SM_HELO  20
-#define        SM_RSET  15
-#define        SM_MAIL  301      /* changed to 5 minutes and a second (for uniqueness), see above */
-#define        SM_RCPT  302      /* see above */
-#define        SM_DATA  120      /* see above */
-#define        SM_TEXT 180     /* see above */
-#define        SM_DOT  600     /* see above */
-#define        SM_QUIT  30
-#define        SM_CLOS  10
-#define        SM_AUTH  45
-
-static int sm_addrs = 0;
-static int sm_alarmed = 0;
-static int sm_child = NOTOK;
-static int sm_debug = 0;
-static int sm_nl = TRUE;
-static int sm_verbose = 0;
-
-static FILE *sm_rfp = NULL;
-static FILE *sm_wfp = NULL;
-
-#ifdef CYRUS_SASL
-/*
- * Some globals needed by SASL
- */
-
-static sasl_conn_t *conn = NULL;       /* SASL connection state */
-static int sasl_complete = 0;          /* Has authentication succeded? */
-static sasl_ssf_t sasl_ssf;            /* Our security strength factor */
-static char *sasl_pw_context[2];       /* Context to pass into sm_get_pass */
-static int maxoutbuf;                  /* Maximum crypto output buffer */
-static char *sasl_outbuffer;           /* SASL output buffer for encryption */
-static int sasl_outbuflen;             /* Current length of data in outbuf */
-static int sm_get_user(void *, int, const char **, unsigned *);
-static int sm_get_pass(sasl_conn_t *, void *, int, sasl_secret_t **);
-
-static sasl_callback_t callbacks[] = {
-    { SASL_CB_USER, sm_get_user, NULL },
-#define SM_SASL_N_CB_USER 0
-    { SASL_CB_PASS, sm_get_pass, NULL },
-#define SM_SASL_N_CB_PASS 1
-    { SASL_CB_AUTHNAME, sm_get_user, NULL },
-#define SM_SASL_N_CB_AUTHNAME 2
-    { SASL_CB_LIST_END, NULL, NULL },
-};
-
-#else /* CYRUS_SASL */
-int sasl_ssf = 0;
-#endif /* CYRUS_SASL */
-
-#ifdef TLS_SUPPORT
-static SSL_CTX *sslctx = NULL;
-static SSL *ssl = NULL;
-static BIO *sbior = NULL;
-static BIO *sbiow = NULL;
-#endif /* TLS_SUPPORT */
-
-#if defined(CYRUS_SASL) || defined(TLS_SUPPORT)
-#define SASL_MAXRECVBUF 65536
-static int sm_fgetc(FILE *);
-static char *sasl_inbuffer;            /* SASL input buffer for encryption */
-static char *sasl_inptr;               /* Pointer to current inbuf position */
-static int sasl_inbuflen;              /* Current length of data in inbuf */
-#else
-#define sm_fgetc fgetc
-#endif
-
-static int tls_active = 0;
-
-static char *sm_noreply = "No reply text given";
-static char *sm_moreply = "; ";
-
-struct smtp sm_reply;          /* global... */
-
-#define        MAXEHLO 20
-
-static int doingEHLO;
-char *EHLOkeys[MAXEHLO + 1];
-
-/*
- * static prototypes
- */
-static int smtp_init (char *, char *, char *, int, int, int, int, int, int,
-                     char *, char *, int);
-static int sendmail_init (char *, char *, int, int, int, int, int, int,
-                          char *, char *);
-
-static int rclient (char *, char *);
-static int sm_ierror (char *fmt, ...);
-static int smtalk (int time, char *fmt, ...);
-static int sm_wrecord (char *, int);
-static int sm_wstream (char *, int);
-static int sm_werror (void);
-static int smhear (void);
-static int sm_rrecord (char *, int *);
-static int sm_rerror (int);
-static RETSIGTYPE alrmser (int);
-static char *EHLOset (char *);
-static int sm_fwrite(char *, int);
-static int sm_fputs(char *);
-static int sm_fputc(int);
-static void sm_fflush(void);
-static int sm_fgets(char *, int, FILE *);
-
-#ifdef CYRUS_SASL
-/*
- * Function prototypes needed for SASL
- */
-
-static int sm_auth_sasl(char *, char *, char *);
-#endif /* CYRUS_SASL */
-
-int
-sm_init (char *client, char *server, char *port, int watch, int verbose,
-         int debug, int onex, int queued, int sasl, char *saslmech,
-         char *user, int tls)
-{
-    if (sm_mts == MTS_SMTP)
-       return smtp_init (client, server, port, watch, verbose,
-                         debug, onex, queued, sasl, saslmech, user, tls);
-    else
-       return sendmail_init (client, server, watch, verbose,
-                              debug, onex, queued, sasl, saslmech, user);
-}
-
-static int
-smtp_init (char *client, char *server, char *port, int watch, int verbose,
-          int debug, int onex, int queued,
-           int sasl, char *saslmech, char *user, int tls)
-{
-#ifdef CYRUS_SASL
-    char *server_mechs;
-#endif /* CYRUS_SASL */
-    int result, sd1, sd2;
-
-    if (watch)
-       verbose = TRUE;
-
-    sm_verbose = verbose;
-    sm_debug = debug;
-
-    if (sm_rfp != NULL && sm_wfp != NULL)
-       goto send_options;
-
-    if (client == NULL || *client == '\0') {
-       if (clientname) {
-           client = clientname;
-       } else {
-           client = LocalName();       /* no clientname -> LocalName */
-       }
-    }
-
-    /*
-     * Last-ditch check just in case client still isn't set to anything
-     */
-
-    if (client == NULL || *client == '\0')
-       client = "localhost";
-
-#if defined(CYRUS_SASL) || defined(TLS_SUPPORT)
-    sasl_inbuffer = malloc(SASL_MAXRECVBUF);
-    if (!sasl_inbuffer)
-       return sm_ierror("Unable to allocate %d bytes for read buffer",
-                        SASL_MAXRECVBUF);
-#endif /* CYRUS_SASL || TLS_SUPPORT */
-
-    if ((sd1 = rclient (server, port)) == NOTOK)
-       return RP_BHST;
-
-    if ((sd2 = dup (sd1)) == NOTOK) {
-       close (sd1);
-       return sm_ierror ("unable to dup");
-    }
-
-    SIGNAL (SIGALRM, alrmser);
-    SIGNAL (SIGPIPE, SIG_IGN);
-
-    if ((sm_rfp = fdopen (sd1, "r")) == NULL
-           || (sm_wfp = fdopen (sd2, "w")) == NULL) {
-       close (sd1);
-       close (sd2);
-       sm_rfp = sm_wfp = NULL;
-       return sm_ierror ("unable to fdopen");
-    }
-
-    tls_active = 0;
-
-    sm_alarmed = 0;
-    alarm (SM_OPEN);
-    result = smhear ();
-    alarm (0);
-
-    switch (result) {
-       case 220: 
-           break;
-
-       default: 
-           sm_end (NOTOK);
-           return RP_RPLY;
-    }
-
-    /*
-     * Give EHLO or HELO command
-     */
-
-    doingEHLO = 1;
-    result = smtalk (SM_HELO, "EHLO %s", client);
-    doingEHLO = 0;
-
-    if (result >= 500 && result <= 599)
-       result = smtalk (SM_HELO, "HELO %s", client);
-
-    if (result != 250) {
-       sm_end (NOTOK);
-       return RP_RPLY;
-    }
-
-#ifdef TLS_SUPPORT
-    /*
-     * If the user requested TLS support, then try to do the STARTTLS command
-     * as part of the initial dialog.  Assuming this works, we then need to
-     * restart the EHLO dialog after TLS negotiation is complete.
-     */
-
-    if (tls) {
-       if (! EHLOset("STARTTLS")) {
-           sm_end(NOTOK);
-           return sm_ierror("SMTP server does not support TLS");
-       }
-
-       result = smtalk(SM_HELO, "STARTTLS");
-
-       if (result != 220) {
-           sm_end(NOTOK);
-           return RP_RPLY;
-       }
-
-       /*
-        * Okay, the other side should be waiting for us to start TLS
-        * negotiation.  Oblige them.
-        */
-
-       if (! sslctx) {
-           SSL_METHOD *method;
-
-           SSL_library_init();
-           SSL_load_error_strings();
-
-           method = TLSv1_client_method();     /* Not sure about this */
-
-           sslctx = SSL_CTX_new(method);
-
-           if (! sslctx) {
-               sm_end(NOTOK);
-               return sm_ierror("Unable to initialize OpenSSL context: %s",
-                                ERR_error_string(ERR_get_error(), NULL));
-           }
-       }
-
-       ssl = SSL_new(sslctx);
-
-       if (! ssl) {
-           sm_end(NOTOK);
-           return sm_ierror("Unable to create SSL connection: %s",
-                            ERR_error_string(ERR_get_error(), NULL));
-       }
-
-       sbior = BIO_new_socket(fileno(sm_rfp), BIO_NOCLOSE);
-       sbiow = BIO_new_socket(fileno(sm_wfp), BIO_NOCLOSE);
-
-       if (sbior == NULL || sbiow == NULL) {
-           sm_end(NOTOK);
-           return sm_ierror("Unable to create BIO endpoints: %s",
-                            ERR_error_string(ERR_get_error(), NULL));
-       }
-
-       SSL_set_bio(ssl, sbior, sbiow);
-
-       if (SSL_connect(ssl) < 1) {
-           sm_end(NOTOK);
-           return sm_ierror("Unable to negotiate SSL connection: %s",
-                            ERR_error_string(ERR_get_error(), NULL));
-       }
-
-       if (sm_debug) {
-           SSL_CIPHER *cipher = SSL_get_current_cipher(ssl);
-           printf("SSL negotiation successful: %s(%d) %s\n",
-                  SSL_CIPHER_get_name(cipher),
-                  SSL_CIPHER_get_bits(cipher, NULL),
-                  SSL_CIPHER_get_version(cipher));
-
-       }
-
-       tls_active = 1;
-
-       doingEHLO = 1;
-       result = smtalk (SM_HELO, "EHLO %s", client);
-       doingEHLO = 0;
-
-       if (result != 250) {
-           sm_end (NOTOK);
-           return RP_RPLY;
-       }
-    }
-#endif /* TLS_SUPPORT */
-
-#ifdef CYRUS_SASL
-    /*
-     * If the user asked for SASL, then check to see if the SMTP server
-     * supports it.  Otherwise, error out (because the SMTP server
-     * might have been spoofed; we don't want to just silently not
-     * do authentication
-     */
-
-    if (sasl) {
-       if (! (server_mechs = EHLOset("AUTH"))) {
-           sm_end(NOTOK);
-           return sm_ierror("SMTP server does not support SASL");
-       }
-
-       if (saslmech && stringdex(saslmech, server_mechs) == -1) {
-           sm_end(NOTOK);
-           return sm_ierror("Requested SASL mech \"%s\" is not in the "
-                            "list of supported mechanisms:\n%s",
-                            saslmech, server_mechs);
-       }
-
-       if (sm_auth_sasl(user, saslmech ? saslmech : server_mechs,
-                        server) != RP_OK) {
-           sm_end(NOTOK);
-           return NOTOK;
-       }
-    }
-#endif /* CYRUS_SASL */
-
-send_options: ;
-    if (watch && EHLOset ("XVRB"))
-       smtalk (SM_HELO, "VERB on");
-    if (onex && EHLOset ("XONE"))
-       smtalk (SM_HELO, "ONEX");
-    if (queued && EHLOset ("XQUE"))
-       smtalk (SM_HELO, "QUED");
-
-    return RP_OK;
-}
-
-int
-sendmail_init (char *client, char *server, int watch, int verbose,
-               int debug, int onex, int queued,
-               int sasl, char *saslmech, char *user)
-{
-#ifdef CYRUS_SASL
-    char *server_mechs;
-#endif /* CYRUS_SASL */
-    int i, result, vecp;
-    int pdi[2], pdo[2];
-    char *vec[15];
-
-    if (watch)
-       verbose = TRUE;
-
-    sm_verbose = verbose;
-    sm_debug = debug;
-    if (sm_rfp != NULL && sm_wfp != NULL)
-       return RP_OK;
-
-    if (client == NULL || *client == '\0') {
-       if (clientname)
-           client = clientname;
-       else
-           client = LocalName();       /* no clientname -> LocalName */
-    }
-
-    /*
-     * Last-ditch check just in case client still isn't set to anything
-     */
-
-    if (client == NULL || *client == '\0')
-       client = "localhost";
-
-#if defined(CYRUS_SASL) || defined(TLS_SUPPORT)
-    sasl_inbuffer = malloc(SASL_MAXRECVBUF);
-    if (!sasl_inbuffer)
-       return sm_ierror("Unable to allocate %d bytes for read buffer",
-                        SASL_MAXRECVBUF);
-#endif /* CYRUS_SASL || TLS_SUPPORT */
-
-    if (pipe (pdi) == NOTOK)
-       return sm_ierror ("no pipes");
-    if (pipe (pdo) == NOTOK) {
-       close (pdi[0]);
-       close (pdi[1]);
-       return sm_ierror ("no pipes");
-    }
-
-    for (i = 0; (sm_child = fork ()) == NOTOK && i < 5; i++)
-       sleep (5);
-
-    switch (sm_child) {
-       case NOTOK: 
-           close (pdo[0]);
-           close (pdo[1]);
-           close (pdi[0]);
-           close (pdi[1]);
-           return sm_ierror ("unable to fork");
-
-       case OK: 
-           if (pdo[0] != fileno (stdin))
-               dup2 (pdo[0], fileno (stdin));
-           if (pdi[1] != fileno (stdout))
-               dup2 (pdi[1], fileno (stdout));
-           if (pdi[1] != fileno (stderr))
-               dup2 (pdi[1], fileno (stderr));
-           for (i = fileno (stderr) + 1; i < NBITS; i++)
-               close (i);
-
-           vecp = 0;
-           vec[vecp++] = r1bindex (sendmail, '/');
-           vec[vecp++] = "-bs";
-           vec[vecp++] = watch ? "-odi" : queued ? "-odq" : "-odb";
-           vec[vecp++] = "-oem";
-           vec[vecp++] = "-om";
-# ifndef RAND
-           if (verbose)
-               vec[vecp++] = "-ov";
-# endif /* not RAND */
-           vec[vecp++] = NULL;
-
-           setgid (getegid ());
-           setuid (geteuid ());
-           execvp (sendmail, vec);
-           fprintf (stderr, "unable to exec ");
-           perror (sendmail);
-           _exit (-1);         /* NOTREACHED */
-
-       default: 
-           SIGNAL (SIGALRM, alrmser);
-           SIGNAL (SIGPIPE, SIG_IGN);
-
-           close (pdi[1]);
-           close (pdo[0]);
-           if ((sm_rfp = fdopen (pdi[0], "r")) == NULL
-                   || (sm_wfp = fdopen (pdo[1], "w")) == NULL) {
-               close (pdi[0]);
-               close (pdo[1]);
-               sm_rfp = sm_wfp = NULL;
-               return sm_ierror ("unable to fdopen");
-           }
-           sm_alarmed = 0;
-           alarm (SM_OPEN);
-           result = smhear ();
-           alarm (0);
-           switch (result) {
-               case 220: 
-                   break;
-
-               default: 
-                   sm_end (NOTOK);
-                   return RP_RPLY;
-           }
-
-           doingEHLO = 1;
-           result = smtalk (SM_HELO, "EHLO %s", client);
-           doingEHLO = 0;
-
-           if (500 <= result && result <= 599)
-               result = smtalk (SM_HELO, "HELO %s", client);
-
-           switch (result) {
-               case 250:
-                   break;
-
-               default:
-                   sm_end (NOTOK);
-                   return RP_RPLY;
-           }
-
-#ifdef CYRUS_SASL
-    /*
-     * If the user asked for SASL, then check to see if the SMTP server
-     * supports it.  Otherwise, error out (because the SMTP server
-     * might have been spoofed; we don't want to just silently not
-     * do authentication
-     */
-
-    if (sasl) {
-       if (! (server_mechs = EHLOset("AUTH"))) {
-           sm_end(NOTOK);
-           return sm_ierror("SMTP server does not support SASL");
-       }
-
-       if (saslmech && stringdex(saslmech, server_mechs) == -1) {
-           sm_end(NOTOK);
-           return sm_ierror("Requested SASL mech \"%s\" is not in the "
-                            "list of supported mechanisms:\n%s",
-                            saslmech, server_mechs);
-       }
-
-       if (sm_auth_sasl(user, saslmech ? saslmech : server_mechs,
-                        server) != RP_OK) {
-           sm_end(NOTOK);
-           return NOTOK;
-       }
-    }
-#endif /* CYRUS_SASL */
-
-           if (onex)
-               smtalk (SM_HELO, "ONEX");
-           if (watch)
-               smtalk (SM_HELO, "VERB on");
-
-           return RP_OK;
-    }
-}
-
-static int
-rclient (char *server, char *service)
-{
-    int sd;
-    char response[BUFSIZ];
-
-    if ((sd = client (server, service, response, sizeof(response),
-                     sm_debug)) != NOTOK)
-       return sd;
-
-    sm_ierror ("%s", response);
-    return NOTOK;
-}
-
-int
-sm_winit (int mode, char *from)
-{
-    char *smtpcom = NULL;
-
-    switch (mode) {
-       case S_MAIL:
-           smtpcom = "MAIL";
-           break;
-
-       case S_SEND:
-           smtpcom = "SEND";
-           break;
-
-       case S_SOML:
-           smtpcom = "SOML";
-           break;
-
-       case S_SAML:
-           smtpcom = "SAML";
-           break;
-
-        default:
-            /* Hopefully, we do not get here. */
-            break;
-    }
-
-    switch (smtalk (SM_MAIL, "%s FROM:<%s>", smtpcom, from)) {
-       case 250: 
-           sm_addrs = 0;
-           return RP_OK;
-
-       case 500: 
-       case 501: 
-       case 552: 
-           return RP_PARM;
-
-       default: 
-           return RP_RPLY;
-    }
-}
-
-
-int
-sm_wadr (char *mbox, char *host, char *path)
-{
-    switch (smtalk (SM_RCPT, host && *host ? "RCPT TO:<%s%s@%s>"
-                                          : "RCPT TO:<%s%s>",
-                            path ? path : "", mbox, host)) {
-       case 250: 
-       case 251: 
-           sm_addrs++;
-           return RP_OK;
-
-       case 451: 
-#ifdef SENDMAILBUG
-           sm_addrs++;
-           return RP_OK;
-#endif /* SENDMAILBUG */
-       case 421: 
-       case 450: 
-       case 452: 
-           return RP_NO;
-
-       case 500: 
-       case 501: 
-           return RP_PARM;
-
-       case 550: 
-       case 551: 
-       case 552: 
-       case 553: 
-           return RP_USER;
-
-       default: 
-           return RP_RPLY;
-    }
-}
-
-
-int
-sm_waend (void)
-{
-    switch (smtalk (SM_DATA, "DATA")) {
-       case 354: 
-           sm_nl = TRUE;
-           return RP_OK;
-
-       case 451: 
-#ifdef SENDMAILBUG
-           sm_nl = TRUE;
-           return RP_OK;
-#endif /* SENDMAILBUG */
-       case 421: 
-           return RP_NO;
-
-       case 500: 
-       case 501: 
-       case 503: 
-       case 554: 
-           return RP_NDEL;
-
-       default: 
-           return RP_RPLY;
-    }
-}
-
-
-int
-sm_wtxt (char *buffer, int len)
-{
-    int result;
-
-    sm_alarmed = 0;
-    alarm (SM_TEXT);
-    result = sm_wstream (buffer, len);
-    alarm (0);
-
-    return (result == NOTOK ? RP_BHST : RP_OK);
-}
-
-
-int
-sm_wtend (void)
-{
-    if (sm_wstream ((char *) NULL, 0) == NOTOK)
-       return RP_BHST;
-
-    switch (smtalk (SM_DOT + 3 * sm_addrs, ".")) {
-       case 250: 
-       case 251: 
-           return RP_OK;
-
-       case 451: 
-#ifdef SENDMAILBUG
-           return RP_OK;
-#endif /* SENDMAILBUG */
-       case 452: 
-       default: 
-           return RP_NO;
-
-       case 552: 
-       case 554: 
-           return RP_NDEL;
-    }
-}
-
-
-int
-sm_end (int type)
-{
-    int status;
-    struct smtp sm_note;
-
-    if (sm_mts == MTS_SENDMAIL) {
-       switch (sm_child) {
-           case NOTOK: 
-           case OK: 
-               return RP_OK;
-
-           default: 
-               break;
-       }
-    }
-
-    if (sm_rfp == NULL && sm_wfp == NULL)
-       return RP_OK;
-
-    switch (type) {
-       case OK: 
-           smtalk (SM_QUIT, "QUIT");
-           break;
-
-       case NOTOK: 
-           sm_note.code = sm_reply.code;
-           sm_note.length = sm_reply.length;
-           memcpy (sm_note.text, sm_reply.text, sm_reply.length + 1);/* fall */
-       case DONE: 
-           if (smtalk (SM_RSET, "RSET") == 250 && type == DONE)
-               return RP_OK;
-           if (sm_mts == MTS_SMTP)
-               smtalk (SM_QUIT, "QUIT");
-           else {
-               kill (sm_child, SIGKILL);
-               discard (sm_rfp);
-               discard (sm_wfp);
-           }
-           if (type == NOTOK) {
-               sm_reply.code = sm_note.code;
-               sm_reply.length = sm_note.length;
-               memcpy (sm_reply.text, sm_note.text, sm_note.length + 1);
-           }
-           break;
-    }
-
-#ifdef TLS_SUPPORT
-    if (tls_active) {
-       SSL_shutdown(ssl);
-       SSL_free(ssl);
-    }
-#endif /* TLS_SUPPORT */
-
-    if (sm_rfp != NULL) {
-       alarm (SM_CLOS);
-       fclose (sm_rfp);
-       alarm (0);
-    }
-    if (sm_wfp != NULL) {
-       alarm (SM_CLOS);
-       fclose (sm_wfp);
-       alarm (0);
-    }
-
-    if (sm_mts == MTS_SMTP) {
-       status = 0;
-#ifdef CYRUS_SASL
-       if (conn) {
-           sasl_dispose(&conn);
-           if (sasl_outbuffer) {
-               free(sasl_outbuffer);
-           }
-       }
-       if (sasl_inbuffer)
-           free(sasl_inbuffer);
-#endif /* CYRUS_SASL */
-    } else {
-       status = pidwait (sm_child, OK);
-       sm_child = NOTOK;
-    }
-
-    sm_rfp = sm_wfp = NULL;
-    return (status ? RP_BHST : RP_OK);
-}
-
-#ifdef CYRUS_SASL
-/*
- * This function implements SASL authentication for SMTP.  If this function
- * completes successfully, then authentication is successful and we've
- * (optionally) negotiated a security layer.
- */
-static int
-sm_auth_sasl(char *user, char *mechlist, char *inhost)
-{
-    int result, status;
-    unsigned int buflen, outlen;
-    char *buf, outbuf[BUFSIZ], host[NI_MAXHOST];
-    const char *chosen_mech;
-    sasl_security_properties_t secprops;
-    sasl_ssf_t *ssf;
-    int *outbufmax;
-
-    /*
-     * Initialize the callback contexts
-     */
-
-    if (user == NULL)
-       user = getusername();
-
-    callbacks[SM_SASL_N_CB_USER].context = user;
-    callbacks[SM_SASL_N_CB_AUTHNAME].context = user;
-
-    /*
-     * This is a _bit_ of a hack ... but if the hostname wasn't supplied
-     * to us on the command line, then call getpeername and do a
-     * reverse-address lookup on the IP address to get the name.
-     */
-
-    memset(host, 0, sizeof(host));
-
-    if (!inhost) {
-       struct sockaddr_storage sin;
-       socklen_t len = sizeof(sin);
-       int result;
-
-       if (getpeername(fileno(sm_wfp), (struct sockaddr *) &sin, &len) < 0) {
-           sm_ierror("getpeername on SMTP socket failed: %s",
-                     strerror(errno));
-           return NOTOK;
-       }
-
-       result = getnameinfo((struct sockaddr *) &sin, len, host, sizeof(host),
-                            NULL, 0, NI_NAMEREQD);
-       if (result != 0) {
-           sm_ierror("Unable to look up name of connected host: %s",
-                     gai_strerror(result));
-           return NOTOK;
-       }
-    } else {
-       strncpy(host, inhost, sizeof(host) - 1);
-    }
-
-    sasl_pw_context[0] = host;
-    sasl_pw_context[1] = user;
-
-    callbacks[SM_SASL_N_CB_PASS].context = sasl_pw_context;
-
-    result = sasl_client_init(callbacks);
-
-    if (result != SASL_OK) {
-       sm_ierror("SASL library initialization failed: %s",
-                 sasl_errstring(result, NULL, NULL));
-       return NOTOK;
-    }
-
-    result = sasl_client_new("smtp", host, NULL, NULL, NULL, 0, &conn);
-
-    if (result != SASL_OK) {
-       sm_ierror("SASL client initialization failed: %s",
-                 sasl_errstring(result, NULL, NULL));
-       return NOTOK;
-    }
-
-    /*
-     * Initialize the security properties.  But if TLS is active, then
-     * don't negotiate encryption here.
-     */
-
-    memset(&secprops, 0, sizeof(secprops));
-    secprops.maxbufsize = SASL_MAXRECVBUF;
-    secprops.max_ssf = tls_active ? 0 : UINT_MAX;
-
-    result = sasl_setprop(conn, SASL_SEC_PROPS, &secprops);
-
-    if (result != SASL_OK) {
-       sm_ierror("SASL security property initialization failed: %s",
-                 sasl_errstring(result, NULL, NULL));
-       return NOTOK;
-    }
-
-    /*
-     * Start the actual protocol.  Feed the mech list into the library
-     * and get out a possible initial challenge
-     */
-
-    result = sasl_client_start(conn, mechlist, NULL, (const char **) &buf,
-                              &buflen, (const char **) &chosen_mech);
-
-    if (result != SASL_OK && result != SASL_CONTINUE) {
-       sm_ierror("SASL client start failed: %s", sasl_errdetail(conn));
-       return NOTOK;
-    }
-
-    /*
-     * If we got an initial challenge, send it as part of the AUTH
-     * command; otherwise, just send a plain AUTH command.
-     */
-
-    if (buflen) {
-       status = sasl_encode64(buf, buflen, outbuf, sizeof(outbuf), NULL);
-       if (status != SASL_OK) {
-           sm_ierror("SASL base64 encode failed: %s",
-                     sasl_errstring(status, NULL, NULL));
-           return NOTOK;
-       }
-
-       status = smtalk(SM_AUTH, "AUTH %s %s", chosen_mech, outbuf);
-    } else
-       status = smtalk(SM_AUTH, "AUTH %s", chosen_mech);
-
-    /*
-     * Now we loop until we either fail, get a SASL_OK, or a 235
-     * response code.  Receive the challenges and process them until
-     * we're all done.
-     */
-
-    while (result == SASL_CONTINUE) {
-
-       /*
-        * If we get a 235 response, that means authentication has
-        * succeeded and we need to break out of the loop (yes, even if
-        * we still get SASL_CONTINUE from sasl_client_step()).
-        *
-        * Otherwise, if we get a message that doesn't seem to be a
-        * valid response, then abort
-        */
-
-       if (status == 235)
-           break;
-       else if (status < 300 || status > 399)
-           return RP_BHST;
-       
-       /*
-        * Special case; a zero-length response from the SMTP server
-        * is returned as a single =.  If we get that, then set buflen
-        * to be zero.  Otherwise, just decode the response.
-        */
-       
-       if (strcmp("=", sm_reply.text) == 0) {
-           outlen = 0;
-       } else {
-           result = sasl_decode64(sm_reply.text, sm_reply.length,
-                                  outbuf, sizeof(outbuf), &outlen);
-       
-           if (result != SASL_OK) {
-               smtalk(SM_AUTH, "*");
-               sm_ierror("SASL base64 decode failed: %s",
-                         sasl_errstring(result, NULL, NULL));
-               return NOTOK;
-           }
-       }
-
-       result = sasl_client_step(conn, outbuf, outlen, NULL,
-                                 (const char **) &buf, &buflen);
-
-       if (result != SASL_OK && result != SASL_CONTINUE) {
-           smtalk(SM_AUTH, "*");
-           sm_ierror("SASL client negotiation failed: %s",
-                     sasl_errstring(result, NULL, NULL));
-           return NOTOK;
-       }
-
-       status = sasl_encode64(buf, buflen, outbuf, sizeof(outbuf), NULL);
-
-       if (status != SASL_OK) {
-           smtalk(SM_AUTH, "*");
-           sm_ierror("SASL base64 encode failed: %s",
-                     sasl_errstring(status, NULL, NULL));
-           return NOTOK;
-       }
-       
-       status = smtalk(SM_AUTH, outbuf);
-    }
-
-    /*
-     * Make sure that we got the correct response
-     */
-
-    if (status < 200 || status > 299)
-       return RP_BHST;
-
-    /*
-     * We _should_ have completed the authentication successfully.
-     * Get a few properties from the authentication exchange.
-     */
-
-    result = sasl_getprop(conn, SASL_MAXOUTBUF, (const void **) &outbufmax);
-
-    if (result != SASL_OK) {
-       sm_ierror("Cannot retrieve SASL negotiated output buffer size: %s",
-                 sasl_errstring(result, NULL, NULL));
-       return NOTOK;
-    }
-
-    maxoutbuf = *outbufmax;
-
-    result = sasl_getprop(conn, SASL_SSF, (const void **) &ssf);
-
-    sasl_ssf = *ssf;
-
-    if (result != SASL_OK) {
-       sm_ierror("Cannot retrieve SASL negotiated security strength "
-                 "factor: %s", sasl_errstring(result, NULL, NULL));
-       return NOTOK;
-    }
-
-    if (sasl_ssf > 0) {
-       sasl_outbuffer = malloc(maxoutbuf);
-
-       if (sasl_outbuffer == NULL) {
-               sm_ierror("Unable to allocate %d bytes for SASL output "
-                         "buffer", maxoutbuf);
-               return NOTOK;
-       }
-       sasl_outbuflen = 0;
-       sasl_inbuflen = 0;
-       sasl_inptr = sasl_inbuffer;
-    } else {
-       sasl_outbuffer = NULL;
-        /* Don't NULL out sasl_inbuffer because it could be used in
-           sm_fgetc (). */
-    }
-
-    sasl_complete = 1;
-
-    return RP_OK;
-}
-
-/*
- * Our callback functions to feed data to the SASL library
- */
-
-static int
-sm_get_user(void *context, int id, const char **result, unsigned *len)
-{
-    char *user = (char *) context;
-
-    if (! result || ((id != SASL_CB_USER) && (id != SASL_CB_AUTHNAME)))
-       return SASL_BADPARAM;
-
-    *result = user;
-    if (len)
-       *len = strlen(user);
-
-    return SASL_OK;
-}
-
-static int
-sm_get_pass(sasl_conn_t *conn, void *context, int id,
-           sasl_secret_t **psecret)
-{
-    char **pw_context = (char **) context;
-    char *pass = NULL;
-    int len;
-
-    if (! psecret || id != SASL_CB_PASS)
-       return SASL_BADPARAM;
-
-    ruserpass(pw_context[0], &(pw_context[1]), &pass);
-
-    len = strlen(pass);
-
-    *psecret = (sasl_secret_t *) malloc(sizeof(sasl_secret_t) + len);
-
-    if (! *psecret) {
-       free(pass);
-       return SASL_NOMEM;
-    }
-
-    (*psecret)->len = len;
-    strcpy((char *) (*psecret)->data, pass);
-/*    free(pass); */
-
-    return SASL_OK;
-}
-#endif /* CYRUS_SASL */
-
-static int
-sm_ierror (char *fmt, ...)
-{
-    va_list ap;
-
-    va_start(ap, fmt);
-    vsnprintf (sm_reply.text, sizeof(sm_reply.text), fmt, ap);
-    va_end(ap);
-
-    sm_reply.length = strlen (sm_reply.text);
-    sm_reply.code = NOTOK;
-
-    return RP_BHST;
-}
-
-static int
-smtalk (int time, char *fmt, ...)
-{
-    va_list ap;
-    int result;
-    char buffer[BUFSIZ];
-
-    va_start(ap, fmt);
-    vsnprintf (buffer, sizeof(buffer), fmt, ap);
-    va_end(ap);
-
-    if (sm_debug) {
-       if (sasl_ssf)
-               printf("(sasl-encrypted) ");
-       if (tls_active)
-               printf("(tls-encrypted) ");
-       printf ("=> %s\n", buffer);
-       fflush (stdout);
-    }
-
-    sm_alarmed = 0;
-    alarm ((unsigned) time);
-    if ((result = sm_wrecord (buffer, strlen (buffer))) != NOTOK)
-       result = smhear ();
-    alarm (0);
-
-    return result;
-}
-
-
-/*
- * write the buffer to the open SMTP channel
- */
-
-static int
-sm_wrecord (char *buffer, int len)
-{
-    if (sm_wfp == NULL)
-       return sm_werror ();
-
-    sm_fwrite (buffer, len);
-    sm_fputs ("\r\n");
-    sm_fflush ();
-
-    return (ferror (sm_wfp) ? sm_werror () : OK);
-}
-
-
-static int
-sm_wstream (char *buffer, int len)
-{
-    char  *bp;
-    static char lc = '\0';
-
-    if (sm_wfp == NULL)
-       return sm_werror ();
-
-    if (buffer == NULL && len == 0) {
-       if (lc != '\n')
-           sm_fputs ("\r\n");
-       lc = '\0';
-       return (ferror (sm_wfp) ? sm_werror () : OK);
-    }
-
-    for (bp = buffer; len > 0; bp++, len--) {
-       switch (*bp) {
-           case '\n': 
-               sm_nl = TRUE;
-               sm_fputc ('\r');
-               break;
-
-           case '.': 
-               if (sm_nl)
-                   sm_fputc ('.');/* FALL THROUGH */
-           default: 
-               sm_nl = FALSE;
-       }
-       sm_fputc (*bp);
-       if (ferror (sm_wfp))
-           return sm_werror ();
-    }
-
-    if (bp > buffer)
-       lc = *--bp;
-    return (ferror (sm_wfp) ? sm_werror () : OK);
-}
-
-/*
- * Write out to the network, but do buffering for SASL (if enabled)
- */
-
-static int
-sm_fwrite(char *buffer, int len)
-{
-#ifdef CYRUS_SASL
-    const char *output;
-    unsigned int outputlen;
-
-    if (sasl_complete == 0 || sasl_ssf == 0) {
-#endif /* CYRUS_SASL */
-#ifdef TLS_SUPPORT
-       if (tls_active) {
-           int ret;
-
-           ret = SSL_write(ssl, buffer, len);
-
-           if (SSL_get_error(ssl, ret) != SSL_ERROR_NONE) {
-               sm_ierror("TLS error during write: %s",
-                         ERR_error_string(ERR_get_error(), NULL));
-               return NOTOK;
-           }
-       } else
-#endif /* TLS_SUPPORT */
-       fwrite(buffer, sizeof(*buffer), len, sm_wfp);
-#ifdef CYRUS_SASL
-    } else {
-       while (len >= maxoutbuf - sasl_outbuflen) {
-           memcpy(sasl_outbuffer + sasl_outbuflen, buffer,
-                  maxoutbuf - sasl_outbuflen);
-           len -= maxoutbuf - sasl_outbuflen;
-           sasl_outbuflen = 0;
-
-           if (sasl_encode(conn, sasl_outbuffer, maxoutbuf,
-                           &output, &outputlen) != SASL_OK) {
-               sm_ierror("Unable to SASL encode connection data: %s",
-                         sasl_errdetail(conn));
-               return NOTOK;
-           }
-
-           fwrite(output, sizeof(*output), outputlen, sm_wfp);
-       }
-
-       if (len > 0) {
-           memcpy(sasl_outbuffer + sasl_outbuflen, buffer, len);
-           sasl_outbuflen += len;
-       }
-    }
-#endif /* CYRUS_SASL */
-    return ferror(sm_wfp) ? NOTOK : RP_OK;
-}
-
-/*
- * Convenience functions to replace occurences of fputs() and fputc()
- */
-
-static int
-sm_fputs(char *buffer)
-{
-    return sm_fwrite(buffer, strlen(buffer));
-}
-
-static int
-sm_fputc(int c)
-{
-    char h = c;
-
-    return sm_fwrite(&h, 1);
-}
-
-/*
- * Flush out any pending data on the connection
- */
-
-static void
-sm_fflush(void)
-{
-#ifdef CYRUS_SASL
-    const char *output;
-    unsigned int outputlen;
-    int result;
-
-    if (sasl_complete == 1 && sasl_ssf > 0 && sasl_outbuflen > 0) {
-       result = sasl_encode(conn, sasl_outbuffer, sasl_outbuflen,
-                            &output, &outputlen);
-       if (result != SASL_OK) {
-           sm_ierror("Unable to SASL encode connection data: %s",
-                     sasl_errdetail(conn));
-           return;
-       }
-
-       fwrite(output, sizeof(*output), outputlen, sm_wfp);
-       sasl_outbuflen = 0;
-    }
-#endif /* CYRUS_SASL */
-
-    fflush(sm_wfp);
-}
-
-static int
-sm_werror (void)
-{
-    sm_reply.length =
-       strlen (strcpy (sm_reply.text, sm_wfp == NULL ? "no socket opened"
-           : sm_alarmed ? "write to socket timed out"
-           : "error writing to socket"));
-
-    return (sm_reply.code = NOTOK);
-}
-
-
-static int
-smhear (void)
-{
-    int i, code, cont, bc = 0, rc, more;
-    unsigned char *bp;
-    char *rp;
-    char **ehlo = NULL, buffer[BUFSIZ];
-
-    if (doingEHLO) {
-       static int at_least_once = 0;
-
-       if (at_least_once) {
-           char *ep;
-
-           for (ehlo = EHLOkeys; *ehlo; ehlo++) {
-               ep = *ehlo;
-               free (ep);
-           }
-       } else {
-           at_least_once = 1;
-       }
-
-       ehlo = EHLOkeys;
-       *ehlo = NULL;
-    }
-
-again: ;
-
-    sm_reply.length = 0;
-    sm_reply.text[0] = 0;
-    rp = sm_reply.text;
-    rc = sizeof(sm_reply.text) - 1;
-
-    for (more = FALSE; sm_rrecord ((char *) (bp = (unsigned char *) buffer),
-                                  &bc) != NOTOK ; ) {
-       if (sm_debug) {
-           if (sasl_ssf > 0)
-               printf("(sasl-decrypted) ");
-           if (tls_active)
-               printf("(tls-decrypted) ");
-           printf ("<= %s\n", buffer);
-           fflush (stdout);
-       }
-
-       if (doingEHLO
-               && strncmp (buffer, "250", sizeof("250") - 1) == 0
-               && (buffer[3] == '-' || doingEHLO == 2)
-               && buffer[4]) {
-           if (doingEHLO == 2) {
-               if ((*ehlo = malloc ((size_t) (strlen (buffer + 4) + 1)))) {
-                   strcpy (*ehlo++, buffer + 4);
-                   *ehlo = NULL;
-                   if (ehlo >= EHLOkeys + MAXEHLO)
-                       doingEHLO = 0;
-               }
-               else
-                   doingEHLO = 0;
-           }
-           else
-               doingEHLO = 2;
-       }
-
-       for (; bc > 0 && (!isascii (*bp) || !isdigit (*bp)); bp++, bc--)
-           continue;
-
-       cont = FALSE;
-       code = atoi ((char *) bp);
-       bp += 3, bc -= 3;
-       for (; bc > 0 && isspace (*bp); bp++, bc--)
-           continue;
-       if (bc > 0 && *bp == '-') {
-           cont = TRUE;
-           bp++, bc--;
-           for (; bc > 0 && isspace (*bp); bp++, bc--)
-               continue;
-       }
-
-       if (more) {
-           if (code != sm_reply.code || cont)
-               continue;
-           more = FALSE;
-       } else {
-           sm_reply.code = code;
-           more = cont;
-           if (bc <= 0) {
-               /* can never fail to 0-terminate because of size of buffer vs fixed string */
-               strncpy (buffer, sm_noreply, sizeof(buffer));
-               bp = (unsigned char *) buffer;
-               bc = strlen (sm_noreply);
-           }
-       }
-
-       if ((i = min (bc, rc)) > 0) {
-           memcpy (rp, bp, i);
-           rp += i;
-           rc -= i;
-           i = strlen(sm_moreply);
-           if (more && rc > i + 1) {
-               memcpy (rp, sm_moreply, i); /* safe because of check in if() */
-               rp += i;
-               rc -= i;
-           }
-       }
-       if (more)
-           continue;
-       if (sm_reply.code < 100) {
-           if (sm_verbose) {
-               printf ("%s\n", sm_reply.text);
-               fflush (stdout);
-           }
-           goto again;
-       }
-
-       sm_reply.length = rp - sm_reply.text;
-       sm_reply.text[sm_reply.length] = 0;
-       return sm_reply.code;
-    }
-    return NOTOK;
-}
-
-
-static int
-sm_rrecord (char *buffer, int *len)
-{
-    int retval;
-
-    if (sm_rfp == NULL)
-       return sm_rerror(0);
-
-    buffer[*len = 0] = 0;
-
-    if ((retval = sm_fgets (buffer, BUFSIZ, sm_rfp)) != RP_OK)
-       return retval;
-    *len = strlen (buffer);
-    /* *len should be >0 except on EOF, but check for safety's sake */
-    if (*len == 0)
-       return sm_rerror (RP_EOF);
-    if (buffer[*len - 1] != '\n')
-       while ((retval = sm_fgetc (sm_rfp)) != '\n' && retval != EOF &&
-              retval != -2)
-           continue;
-    else
-       if ((*len > 1) && (buffer[*len - 2] == '\r'))
-           *len -= 1;
-    *len -= 1;
-    buffer[*len] = 0;
-
-    return OK;
-}
-
-/*
- * Our version of fgets, which calls our private fgetc function
- */
-
-static int
-sm_fgets(char *buffer, int size, FILE *f)
-{
-    int c;
-
-     do {
-       c = sm_fgetc(f);
-
-       if (c == EOF)
-           return RP_EOF;
-
-       if (c == -2)
-           return NOTOK;
-
-       *buffer++ = c;
-     } while (size > 1 && c != '\n');
-
-     *buffer = '\0';
-
-     return RP_OK;
-}
-
-
-#if defined(CYRUS_SASL) || defined(TLS_SUPPORT)
-/*
- * Read from the network, but do SASL or TLS encryption
- */
-
-static int
-sm_fgetc(FILE *f)
-{
-    char tmpbuf[BUFSIZ], *retbuf;
-    unsigned int retbufsize = 0;
-    int cc, result;
-
-    /*
-     * If we have leftover data, return it
-     */
-
-    if (sasl_inbuflen) {
-       sasl_inbuflen--;
-       return (int) *sasl_inptr++;
-    }
-
-    /*
-     * If not, read from the network until we have some data to return
-     */
-
-    while (retbufsize == 0) {
-
-#ifdef TLS_SUPPORT
-       if (tls_active) {
-           cc = SSL_read(ssl, tmpbuf, sizeof(tmpbuf));
-
-           if (cc == 0) {
-               result = SSL_get_error(ssl, cc);
-
-               if (result != SSL_ERROR_ZERO_RETURN) {
-                   sm_ierror("TLS peer aborted connection");
-               }
-
-               return EOF;
-           }
-
-           if (cc < 0) {
-               sm_ierror("SSL_read failed: %s",
-                         ERR_error_string(ERR_get_error(), NULL));
-               return -2;
-           }
-       } else
-#endif /* TLS_SUPPORT */
-
-       cc = read(fileno(f), tmpbuf, sizeof(tmpbuf));
-
-       if (cc == 0)
-           return EOF;
-
-       if (cc < 0) {
-           sm_ierror("Unable to read from network: %s", strerror(errno));
-           return -2;
-       }
-
-       /*
-        * Don't call sasl_decode unless sasl is complete and we have
-        * encryption working
-        */
-
-#ifdef CYRUS_SASL
-       if (sasl_complete == 0 || sasl_ssf == 0) {
-           retbuf = tmpbuf;
-           retbufsize = cc;
-       } else {
-           result = sasl_decode(conn, tmpbuf, cc, (const char **) &retbuf,
-                                &retbufsize);
-
-           if (result != SASL_OK) {
-               sm_ierror("Unable to decode SASL network data: %s",
-                         sasl_errdetail(conn));
-               return -2;
-           }
-       }
-#else /* ! CYRUS_SASL */
-       retbuf = tmpbuf;
-       retbufsize = cc;
-#endif /* CYRUS_SASL */
-    }
-
-    if (retbufsize > SASL_MAXRECVBUF) {
-       sm_ierror("Received data (%d bytes) is larger than the buffer "
-                 "size (%d bytes)", retbufsize, SASL_MAXRECVBUF);
-       return -2;
-    }
-
-    memcpy(sasl_inbuffer, retbuf, retbufsize);
-    sasl_inptr = sasl_inbuffer + 1;
-    sasl_inbuflen = retbufsize - 1;
-
-    return (int) sasl_inbuffer[0];
-}
-#endif /* CYRUS_SASL || TLS_SUPPORT */
-
-static int
-sm_rerror (int rc)
-{
-    if (sm_mts == MTS_SMTP)
-       sm_reply.length =
-           strlen (strcpy (sm_reply.text, sm_rfp == NULL ? "no socket opened"
-               : sm_alarmed ? "read from socket timed out"
-               : rc == RP_EOF ? "premature end-of-file on socket"
-               : "error reading from socket"));
-    else
-       sm_reply.length =
-           strlen (strcpy (sm_reply.text, sm_rfp == NULL ? "no pipe opened"
-               : sm_alarmed ? "read from pipe timed out"
-               : rc == RP_EOF ? "premature end-of-file on pipe"
-               : "error reading from pipe"));
-
-    return (sm_reply.code = NOTOK);
-}
-
-
-static RETSIGTYPE
-alrmser (int i)
-{
-#ifndef        RELIABLE_SIGNALS
-    SIGNAL (SIGALRM, alrmser);
-#endif
-
-    sm_alarmed++;
-    if (sm_debug) {
-       printf ("timed out...\n");
-       fflush (stdout);
-    }
-}
-
-
-char *
-rp_string (int code)
-{
-    char *text;
-    static char buffer[BUFSIZ];
-
-    switch (sm_reply.code != NOTOK ? code : NOTOK) {
-       case RP_AOK:
-           text = "AOK";
-           break;
-
-       case RP_MOK:
-           text = "MOK";
-           break;
-
-       case RP_OK: 
-           text = "OK";
-           break;
-
-       case RP_RPLY: 
-           text = "RPLY";
-           break;
-
-       case RP_BHST: 
-       default: 
-           text = "BHST";
-           snprintf (buffer, sizeof(buffer), "[%s] %s", text, sm_reply.text);
-           return buffer;
-
-       case RP_PARM: 
-           text = "PARM";
-           break;
-
-       case RP_NO: 
-           text = "NO";
-           break;
-
-       case RP_USER: 
-           text = "USER";
-           break;
-
-       case RP_NDEL: 
-           text = "NDEL";
-           break;
-    }
-
-    snprintf (buffer, sizeof(buffer), "[%s] %3d %s",
-               text, sm_reply.code, sm_reply.text);
-    return buffer;
-}
-
-static char *
-EHLOset (char *s)
-{
-    size_t len;
-    char *ep, **ehlo;
-
-    len = strlen (s);
-
-    for (ehlo = EHLOkeys; *ehlo; ehlo++) {
-       ep = *ehlo;
-       if (strncmp (ep, s, len) == 0) {
-           for (ep += len; *ep == ' '; ep++)
-               continue;
-           return ep;
-       }
-    }
-
-    return 0;
-}
diff --git a/mts/smtp/smtp.h b/mts/smtp/smtp.h
deleted file mode 100644 (file)
index c88620e..0000000
+++ /dev/null
@@ -1,291 +0,0 @@
-
-/*
- * smtp.h -- definitions for the nmh SMTP Interface
- */
-
-/* various modes for SMTP */
-#define        S_MAIL  0
-#define        S_SEND  1
-#define        S_SOML  2
-#define        S_SAML  3
-
-/* length is the length of the string in text[], which is also NUL
- * terminated, so s.text[s.length] should always be 0.
- */
-struct smtp {
-    int code;
-    int length;
-    char text[BUFSIZ];
-};
-
-/*
- * prototypes
- */
-/* int client (); */
-int sm_init (char *, char *, char *, int, int, int, int, int, int, char *, char *, int);
-int sm_winit (int, char *);
-int sm_wadr (char *, char *, char *);
-int sm_waend (void);
-int sm_wtxt (char *, int);
-int sm_wtend (void);
-int sm_end (int);
-char *rp_string (int);
-
-/* The remainder of this file is derived from "mmdf.h" */
-
-/*
- *     Copyright (C) 1979,1980,1981,1982,1983  University of Delaware
- *     Used by permission, May, 1984.
- */
-
-/*
- *     MULTI-CHANNEL MEMO DISTRIBUTION FACILITY  (MMDF)
- *     
- *
- *     Copyright (C) 1979,1980,1981,1982,1983  University of Delaware
- *     
- *     Department of Electrical Engineering
- *     University of Delaware
- *     Newark, Delaware  19711
- *
- *     Phone:  (302) 738-1163
- *     
- *     
- *     This program module was developed as part of the University
- *     of Delaware's Multi-Channel Memo Distribution Facility (MMDF).
- *     
- *     Acquisition, use, and distribution of this module and its listings
- *     are subject restricted to the terms of a license agreement.
- *     Documents describing systems using this module must cite its source.
- *
- *     The above statements must be retained with all copies of this
- *     program and may not be removed without the consent of the
- *     University of Delaware.
- *     
- */
-
-/*                      Reply Codes for MMDF
- *
- *  Based on: "Revised FTP Reply Codes", by Jon Postel & Nancy Neigus Arpanet
- *      RFC 640 / NIC 30843, in the "Arpanet Protocol Handbook", E.  Feinler
- *      and J. Postel (eds.), NIC 7104, Network Information Center, SRI
- *      International:  Menlo Park, CA.  (NTIS AD-A0038901)
- *
- *  Actual values are different, but scheme is same.  Codes must fit into
- *  8-bits (to pass on exit() calls); fields are packed 2-3-3 and interpreted
- *  as octal numbers.
- *
- *  Basic format:
- *
- *      0yz: positive completion; entire action done
- *      1yz: positive intermediate; only part done
- *      2yz: Transient negative completion; may work later
- *      3yz: Permanent negative completion; you lose forever
- *
- *      x0z: syntax
- *      x1z: general; doesn't fit any other category
- *      x2z: connections; truly transfer-related
- *      x3z: user/authentication/account
- *      x4x: mail
- *      x5z: file system
- *
- *      3-bit z field is unique to the reply.  In the following,
- *      the RP_xVAL defines are available for masking to obtain a field.
- */
-
-/*
- * FIELD DEFINITIONS & BASIC VALUES
- */
-
-/* FIELD 1:  Basic degree of success (2-bits) */
-
-#define RP_BTYP '\200'      /* good vs. bad; on => bad            */
-#define RP_BVAL '\300'      /* basic degree of success            */
-
-#define RP_BOK  '\000'      /* went fine; all done                */
-#define RP_BPOK '\100'      /* only the first part got done       */
-#define RP_BTNO '\200'      /* temporary failure; try later       */
-#define RP_BNO  '\300'      /* not now, nor never; you lose       */
-
-/* FIELD 2:  Basic domain of discourse (3-bits) */
-
-#define RP_CVAL '\070'      /* basic category (domain) of reply   */
-
-#define RP_CSYN '\000'      /* purely a matter of form            */
-#define RP_CGEN '\010'      /* couldn't find anywhere else for it */
-#define RP_CCON '\020'      /* data-transfer-related issue        */
-#define RP_CUSR '\030'      /* pertaining to the user             */
-#define RP_CMAI '\040'      /* specific to mail semantics         */
-#define RP_CFIL '\050'      /* file system                        */
-#define RP_CLIO '\060'      /* local i/o system                   */
-
-/* FIELD 3:  Specific value for this reply (3-bits) */
-
-#define RP_SVAL '\007'      /* specific value of reply            */
-
-
-/*
- * SPECIFIC SUCCESS VALUES
- */
-
-/*
- * Complete Success
- */
-
-/* done (e.g., w/transaction) */
-#define RP_DONE (RP_BOK | RP_CGEN | '\000')
-
-/* general-purpose OK */
-#define RP_OK   (RP_BOK | RP_CGEN | '\001')
-
-/* message is accepted (w/text) */
-#define RP_MOK  (RP_BOK | RP_CMAI | '\000')
-
-
-/*
- * Partial Success
- */
-
-/* you are the requestor */
-#define RP_MAST (RP_BPOK| RP_CGEN | '\000')
-
-/* you are the requestee */
-#define RP_SLAV (RP_BPOK| RP_CGEN | '\001')
-
-/* message address is accepted */
-#define RP_AOK  (RP_BPOK| RP_CMAI | '\000')
-
-
-/*
- * SPECIFIC FALURE VALUES
- */
-
-/*
- * Partial Failure
- */
-
-/* not now; maybe later */
-#define RP_AGN  (RP_BTNO | RP_CGEN | '\000')
-
-/* timeout */
-#define RP_TIME (RP_BTNO | RP_CGEN | '\001')
-
-/* no-op; nothing done, this time */
-#define RP_NOOP (RP_BTNO | RP_CGEN | '\002')
-
-/* encountered an end of file */
-#define RP_EOF  (RP_BTNO | RP_CGEN | '\003')
-
-/* channel went bad */
-#define RP_NET  (RP_BTNO | RP_CCON | '\000')
-
-/* foreign host screwed up */
-#define RP_BHST (RP_BTNO | RP_CCON | '\001')
-
-/* host went away */
-#define RP_DHST (RP_BTNO | RP_CCON | '\002')
-
-/* general net i/o problem */
-#define RP_NIO  (RP_BTNO | RP_CCON | '\004')
-
-/* error reading/writing file */
-#define RP_FIO  (RP_BTNO | RP_CFIL | '\000')
-
-/* unable to create file */
-#define RP_FCRT (RP_BTNO | RP_CFIL | '\001')
-
-/* unable to open file */
-#define RP_FOPN (RP_BTNO | RP_CFIL | '\002')
-
-/* general local i/o problem */
-#define RP_LIO  (RP_BTNO | RP_CLIO | '\000')
-
-/* resource currently locked */
-#define RP_LOCK (RP_BTNO | RP_CLIO | '\001')
-
-
-/*
- * Complete Failure
- */
-
-/* bad mechanism/path; try alternate? */
-#define RP_MECH (RP_BNO | RP_CGEN | '\000')
-
-/* general-purpose NO */
-#define RP_NO   (RP_BNO | RP_CGEN | '\001')
-
-/* general prototocol error */
-#define RP_PROT (RP_BNO | RP_CCON | '\000')
-
-/* bad reply code (PERMANENT ERROR) */
-#define RP_RPLY (RP_BNO | RP_CCON | '\001')
-
-/* couldn't deliver */
-#define RP_NDEL (RP_BNO | RP_CMAI | '\000')
-
-/* couldn't parse the request */
-#define RP_HUH  (RP_BNO | RP_CSYN | '\000')
-
-/* no such command defined */
-#define RP_NCMD (RP_BNO | RP_CSYN | '\001')
-
-/* bad parameter */
-#define RP_PARM (RP_BNO | RP_CSYN | '\002')
-
-/* command not implemented */
-#define RP_UCMD (RP_BNO | RP_CSYN | '\003')
-
-/* unknown user */
-#define RP_USER (RP_BNO | RP_CUSR | '\000')
-
-
-/*
- * Macros to access reply info
- */
-
-/* get the entire return value */
-#define rp_gval(val)    ((signed char) (val))
-
-
-/*
- * The next three give the field's bits, within the whole value
- */
-
-/* get the basic part of return value */
-#define rp_gbval(val)   (rp_gval (val) & RP_BVAL)
-
-/* get the domain part of value */
-#define rp_gcval(val)   (rp_gval (val) & RP_CVAL)
-
-/* get the specific part of value */
-#define rp_gsval(val)   (rp_gval (val) & RP_SVAL)
-
-
-/*
- * The next three give the numeric value withing the field
- */
-
-/* get the basic part right-shifted */
-#define rp_gbbit(val)   ((rp_gval (val) >> 6) & 03)
-
-/* get the domain part right-shifted */
-#define rp_gcbit(val)   ((rp_gval (val) >> 3) & 07)
-
-/* get the specific part right-shifted */
-#define rp_gsbit(val)   (rp_gval (val) & 07)
-
-
-/*
- * MACHINE DEPENDENCY
- *
- * The following treat the value as strictly numeric.
- * It relies on the negative values being numerically
- * negative.
- */
-
-/* is return value positive? */
-#define rp_isgood(val)  (rp_gval (val) >= 0)
-
-/* is return value negative? */
-#define rp_isbad(val)   (rp_gval (val) < 0)
-
index 484ec5e..79d7afe 100644 (file)
@@ -526,3 +526,51 @@ local_test: ;
 
     return 0;
 }
+
+
+/*
+ * Moved from hosts.c -- find out the official name of a host
+ */
+
+/*
+ * In the SendMail world, we really don't know what the valid
+ * hosts are.  We could poke around in the sendmail.cf file, but
+ * that still isn't a guarantee.  As a result, we'll say that
+ * everything is a valid host, and let SendMail worry about it.
+ */
+
+#include <h/mts.h>
+#include <netdb.h>
+
+
+char *
+OfficialName (char *name)
+{
+    unsigned char *p;
+    char *q, site[BUFSIZ];
+    struct addrinfo hints, *res;
+
+    static char buffer[BUFSIZ];
+
+    for (p = name, q = site; *p && (q - site < sizeof(site) - 1); p++, q++)
+       *q = isupper (*p) ? tolower (*p) : *p;
+    *q = '\0';
+    q = site;
+
+    if (!mh_strcasecmp (LocalName(), site))
+       return LocalName();
+
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_flags = AI_CANONNAME;
+    hints.ai_family = PF_UNSPEC;
+
+    if (getaddrinfo(q, NULL, &hints, &res) == 0) {
+       strncpy (buffer, res->ai_canonname, sizeof(buffer));
+       buffer[sizeof(buffer) - 1] = '\0';
+       freeaddrinfo(res);
+       return buffer;
+    }
+
+    strncpy (buffer, site, sizeof(buffer));
+    return buffer;
+}
index 46f5990..3588fec 100644 (file)
--- a/sbr/mts.c
+++ b/sbr/mts.c
@@ -48,10 +48,6 @@ static void mts_read_conf_file (FILE *fp);
  */
 static char *mtsconf = nmhetcdir(/mts.conf);
 
-static char *localname   = "";
-static char *localdomain = "";
-static char *systemname  = "";
-
 char *mmdfldir = MAILSPOOL;
 char *mmdflfil = "";
 char *uucpldir = "/usr/spool/mail";
@@ -65,7 +61,7 @@ static char username[BUFSIZ];
 static char fullname[BUFSIZ];
 
 /* Variables for username masquerading: */
-       boolean  draft_from_masquerading = FALSE;  /* also used from post.c */
+       boolean  draft_from_masquerading = FALSE;
 static boolean  mmailid_masquerading = FALSE;
        boolean  username_extension_masquerading = FALSE;  /* " from addrsbr.c */
 static char*    masquerade = "";
@@ -73,16 +69,7 @@ static char*    masquerade = "";
 /*
  * MTS specific variables
  */
-#if defined(SMTPMTS)
-static char *sm_method = "sendmail";
-int  sm_mts    = MTS_SENDMAIL;
 char *sendmail = SENDMAILPATH;
-#endif
-
-/*
- * SMTP stuff
- */
-char *clientname = NULL;
 
 /*
  * Global MailDelivery file
@@ -108,9 +95,6 @@ struct bind {
 };
 
 static struct bind binds[] = {
-    { "localname", &localname },
-    { "localdomain", &localdomain },
-    { "systemname", &systemname },
     { "mmdfldir", &mmdfldir },
     { "mmdflfil", &mmdflfil },
     { "uucpldir", &uucpldir },
@@ -118,14 +102,7 @@ static struct bind binds[] = {
     { "mmdelim1", &mmdlm1 },
     { "mmdelim2", &mmdlm2 },
     { "masquerade", &masquerade },
-
-#if defined(SMTPMTS)
-    { "mts",      &sm_method },
-    { "sendmail", &sendmail  },
-#endif
-
-    { "clientname",  &clientname },
-
+    { "sendmail", &sendmail },
     { "maildelivery", &maildelivery },
     { "everyone", &everyone },
     { "noshell", &NoShell },
@@ -242,37 +219,23 @@ LocalName (void)
 
     mts_init ("mts");
 
-    /* check if the mts.conf file specifies a "localname" */
-    if (*localname) {
-       strncpy (buffer, localname, sizeof(buffer));
-    } else {
-       memset(buffer, 0, sizeof(buffer));
+    memset(buffer, 0, sizeof(buffer));
 #ifdef HAVE_UNAME
-       /* first get our local name */
-       uname (&name);
-       strncpy (buffer, name.nodename, sizeof(buffer) - 1);
+    /* first get our local name */
+    uname (&name);
+    strncpy (buffer, name.nodename, sizeof(buffer) - 1);
 #else
-       /* first get our local name */
-       gethostname (buffer, sizeof(buffer) - 1);
+    /* first get our local name */
+    gethostname (buffer, sizeof(buffer) - 1);
 #endif
-       /* now fully qualify our name */
-
-       memset(&hints, 0, sizeof(hints));
-       hints.ai_flags = AI_CANONNAME;
-       hints.ai_family = PF_UNSPEC;
-       if (getaddrinfo(buffer, NULL, &hints, &res) == 0) {
-           strncpy(buffer, res->ai_canonname, sizeof(buffer) - 1);
-           freeaddrinfo(res);
-       }
-    }
-
-    /*
-     * If the mts.conf file specifies a "localdomain",
-     * we append that now.  This should rarely be needed.
-     */
-    if (*localdomain) {
-       strcat (buffer, ".");
-       strcat (buffer, localdomain);
+    /* now fully qualify our name */
+
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_flags = AI_CANONNAME;
+    hints.ai_family = PF_UNSPEC;
+    if (getaddrinfo(buffer, NULL, &hints, &res) == 0) {
+       strncpy(buffer, res->ai_canonname, sizeof(buffer) - 1);
+       freeaddrinfo(res);
     }
 
     return buffer;
@@ -299,12 +262,6 @@ SystemName (void)
 
     mts_init ("mts");
 
-    /* check if mts.conf file specifies a "systemname" */
-    if (*systemname) {
-       strncpy (buffer, systemname, sizeof(buffer));
-       return buffer;
-    }
-
 #ifdef HAVE_UNAME
     uname (&name);
     strncpy (buffer, name.nodename, sizeof(buffer));
index 691bfe6..7b483fe 100644 (file)
@@ -21,7 +21,8 @@ INCLUDES = -I.. -I$(srcdir) -I$(top_srcdir) @CPPFLAGS@
 LDFLAGS  = @LDFLAGS@
 
 LIBS     = @LIBS@
-MTSLIB   = ../mts/libmts.a
+MTSLIB   = 
+# ../mts/libmts.a
 NDBM_LIBS = @NDBM_LIBS@
 LOCALLIBS = ../config/version.o ../config/config.o $(MTSLIB) ../sbr/libmh.a
 LINKLIBS = $(LOCALLIBS) $(LIBS)
index de12dde..fdbd679 100644 (file)
--- a/uip/mhl.c
+++ b/uip/mhl.c
@@ -22,17 +22,3 @@ main (int argc, char **argv)
     done (mhl (argc, argv));
     return 1;
 }
-
-
-/*
- * Cheat: we are loaded with adrparse, which wants a routine called
- * OfficialName().  We call adrparse:getm() with the correct arguments
- * to prevent OfficialName() from being called.  Hence, the following
- * is to keep the loader happy.
- */
-
-char *
-OfficialName(char *name)
-{
-    return name;
-}
diff --git a/uip/post.c b/uip/post.c
deleted file mode 100644 (file)
index d5760a2..0000000
+++ /dev/null
@@ -1,1740 +0,0 @@
-
-/*
- * post.c -- enter messages into the mail transport system
- *
- * This code is Copyright (c) 2002, by the authors of nmh.  See the
- * COPYRIGHT file in the root directory of the nmh distribution for
- * complete copyright information.
- */
-
-#include <h/mh.h>
-#include <fcntl.h>
-#include <h/signals.h>
-#include <h/addrsbr.h>
-#include <h/aliasbr.h>
-#include <h/dropsbr.h>
-#include <h/mime.h>
-#include <h/utils.h>
-
-#include <h/tws.h>
-#include <h/mts.h>
-
-#include <errno.h>
-#include <setjmp.h>
-#include <signal.h>
-
-#ifdef TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# ifdef TM_IN_SYS_TIME
-#  include <sys/time.h>
-# else
-#  include <time.h>
-# endif
-#endif
-
-#ifdef SMTPMTS
-# include <mts/smtp/smtp.h>
-#endif
-
-#ifndef CYRUS_SASL
-# define SASLminc(a) (a)
-#else /* CYRUS_SASL */
-# define SASLminc(a)  0
-#endif /* CYRUS_SASL */
-
-#ifndef TLS_SUPPORT
-# define TLSminc(a)  (a)
-#else /* TLS_SUPPORT */
-# define TLSminc(a)   0
-#endif /* TLS_SUPPORT */
-
-#define FCCS           10      /* max number of fccs allowed */
-
-#define        uptolow(c)      ((isalpha(c) && isupper (c)) ? tolower (c) : c)
-
-/* In the following array of structures, the numeric second field of the
-   structures (minchars) is apparently used like this:
-
-   -# : Switch can be abbreviated to # characters; switch hidden in -help.
-   0  : Switch can't be abbreviated;               switch shown in -help.
-   #  : Switch can be abbreviated to # characters; switch shown in -help. */
-
-static struct swit switches[] = {
-#define        ALIASW                    0
-    { "alias aliasfile", 0 },
-#define        CHKSW                     1
-    { "check", -5 },                   /* interface from whom */
-#define        NCHKSW                    2
-    { "nocheck", -7 },                 /* interface from whom */
-#define        DEBUGSW                   3
-    { "debug", -5 },
-#define        DISTSW                    4
-    { "dist", -4 },                    /* interface from dist */
-#define        FILTSW                    5
-    { "filter filterfile", 0 },
-#define        NFILTSW                   6
-    { "nofilter", 0 },
-#define        FRMTSW                    7
-    { "format", 0 },
-#define        NFRMTSW                   8
-    { "noformat", 0 },
-#define        LIBSW                     9
-    { "library directory", -7 },       /* interface from send, whom */
-#define        MIMESW                   10
-    { "mime", 0 },
-#define        NMIMESW                  11
-    { "nomime", 0 },
-#define        MSGDSW                   12
-    { "msgid", 0 },
-#define        NMSGDSW                  13
-    { "nomsgid", 0 },
-#define        VERBSW                   14
-    { "verbose", 0 },
-#define        NVERBSW                  15
-    { "noverbose", 0 },
-#define        WATCSW                   16
-    { "watch", 0 },
-#define        NWATCSW                  17
-    { "nowatch", 0 },
-#define        WHOMSW                   18
-    { "whom", -4 },                    /* interface from whom */
-#define        WIDTHSW                  19
-    { "width columns", 0 },
-#define VERSIONSW                20
-    { "version", 0 },
-#define        HELPSW                   21
-    { "help", 0 },
-#define BITSTUFFSW               22
-    { "dashstuffing", -12 },           /* should we dashstuff BCC messages? */
-#define NBITSTUFFSW              23
-    { "nodashstuffing", -14 },
-#define        MAILSW                   24
-    { "mail", -4 },                    /* specify MAIL smtp mode */
-#define        SAMLSW                   25
-    { "saml", -4 },                    /* specify SAML smtp mode */
-#define        SENDSW                   26
-    { "send", -4 },                    /* specify SEND smtp mode */
-#define        SOMLSW                   27
-    { "soml", -4 },                    /* specify SOML smtp mode */
-#define        ANNOSW                   28
-    { "idanno number", -6 },           /* interface from send    */
-#define        DLVRSW                   29
-    { "deliver address-list", -7 },
-#define        CLIESW                   30
-    { "client host", -6 },
-#define        SERVSW                   31
-    { "server host", -6 },             /* specify alternate SMTP server */
-#define        SNOOPSW                  32
-    { "snoop", -5 },                   /* snoop the SMTP transaction */
-#define        FILLSW                   33
-    { "fill-in file", -7 },
-#define        FILLUSW                  34
-    { "fill-up", -7 },
-#define        PARTSW                   35
-    { "partno", -6 },
-#define        QUEUESW                  36
-    { "queued", -6 },
-#define SASLSW                   37
-    { "sasl", SASLminc(-4) },
-#define SASLMECHSW               38
-    { "saslmech", SASLminc(-5) },
-#define USERSW                   39
-    { "user", SASLminc(-4) },
-#define PORTSW                  40
-    { "port server port name/number", 4 },
-#define TLSSW                   41
-    { "tls", TLSminc(-3) },
-    { NULL, 0 }
-};
-
-
-struct headers {
-    char *value;
-    unsigned int flags;
-    unsigned int set;
-};
-
-/*
- * flags for headers->flags
- */
-#define        HNOP  0x0000            /* just used to keep .set around          */
-#define        HBAD  0x0001            /* bad header - don't let it through      */
-#define        HADR  0x0002            /* header has an address field            */
-#define        HSUB  0x0004            /* Subject: header                        */
-#define        HTRY  0x0008            /* try to send to addrs on header         */
-#define        HBCC  0x0010            /* don't output this header               */
-#define        HMNG  0x0020            /* munge this header                      */
-#define        HNGR  0x0040            /* no groups allowed in this header       */
-#define        HFCC  0x0080            /* FCC: type header                       */
-#define        HNIL  0x0100            /* okay for this header not to have addrs */
-#define        HIGN  0x0200            /* ignore this header                     */
-#define        HDCC  0x0400            /* another undocumented feature           */
-
-/*
- * flags for headers->set
- */
-#define        MFRM  0x0001            /* we've seen a From:        */
-#define        MDAT  0x0002            /* we've seen a Date:        */
-#define        MRFM  0x0004            /* we've seen a Resent-From: */
-#define        MVIS  0x0008            /* we've seen sighted addrs  */
-#define        MINV  0x0010            /* we've seen blind addrs    */
-
-
-static struct headers NHeaders[] = {
-    { "Return-Path", HBAD,                0 },
-    { "Received",    HBAD,                0 },
-    { "Reply-To",    HADR|HNGR,           0 },
-    { "From",        HADR|HNGR,           MFRM },
-    { "Sender",      HADR|HBAD,           0 },
-    { "Date",        HBAD,                0 },
-    { "Subject",     HSUB,                0 },
-    { "To",          HADR|HTRY,           MVIS },
-    { "cc",          HADR|HTRY,           MVIS },
-    { "Bcc",         HADR|HTRY|HBCC|HNIL, MINV },
-    { "Dcc",         HADR|HTRY|HDCC|HNIL, MVIS },      /* sorta cc & bcc combined */
-    { "Message-ID",  HBAD,                0 },
-    { "Fcc",         HFCC,                0 },
-    { NULL,          0,                   0 }
-};
-
-static struct headers RHeaders[] = {
-    { "Resent-Reply-To",   HADR|HNGR,           0 },
-    { "Resent-From",       HADR|HNGR,           MRFM },
-    { "Resent-Sender",     HADR|HBAD,           0 },
-    { "Resent-Date",       HBAD,                0 },
-    { "Resent-Subject",    HSUB,                0 },
-    { "Resent-To",         HADR|HTRY,           MVIS },
-    { "Resent-cc",         HADR|HTRY,           MVIS },
-    { "Resent-Bcc",        HADR|HTRY|HBCC,      MINV },
-    { "Resent-Message-ID", HBAD,                0 },
-    { "Resent-Fcc",        HFCC,                0 },
-    { "Reply-To",          HADR,                0 },
-    { "From",              HADR|HNGR,           MFRM },
-    { "Sender",            HADR|HNGR,           0 },
-    { "Date",              HNOP,                MDAT },
-    { "To",                HADR|HNIL,           0 },
-    { "cc",                HADR|HNIL,           0 },
-    { "Bcc",               HADR|HTRY|HBCC|HNIL, 0 },
-    { "Fcc",               HIGN,                0 },
-    { NULL,                0,                   0 }
-};
-
-static short fccind = 0;       /* index into fccfold[] */
-static short outputlinelen = OUTPUTLINELEN;
-
-static int pfd = NOTOK;                /* fd to write annotation list to        */
-static uid_t myuid= -1;                /* my user id                            */
-static gid_t mygid= -1;                /* my group id                           */
-static int recipients = 0;     /* how many people will get a copy       */
-static int unkadr = 0;         /* how many of those were unknown        */
-static int badadr = 0;         /* number of bad addrs                   */
-static int badmsg = 0;         /* message has bad semantics             */
-static int verbose = 0;                /* spell it out                          */
-static int format = 1;         /* format addresses                      */
-static int mime = 0;           /* use MIME-style encapsulations for Bcc */
-static int msgid = 0;          /* add msgid                             */
-static int debug = 0;          /* debugging post                        */
-static int watch = 0;          /* watch the delivery process            */
-static int whomsw = 0;         /* we are whom not post                  */
-static int checksw = 0;                /* whom -check                           */
-static int linepos=0;          /* putadr()'s position on the line       */
-static int nameoutput=0;       /* putadr() has output header name       */
-static int sasl=0;             /* Use SASL auth for SMTP                */
-static char *saslmech=NULL;    /* Force use of particular SASL mech     */
-static char *user=NULL;                /* Authenticate as this user             */
-static char *port="smtp";      /* Name of server port for SMTP          */
-static int tls=0;              /* Use TLS for encryption                */
-
-static unsigned msgflags = 0;  /* what we've seen */
-
-#define        NORMAL 0
-#define        RESENT 1
-static int msgstate = NORMAL;
-
-static time_t tclock = 0;      /* the time we started (more or less) */
-
-static SIGNAL_HANDLER hstat, istat, qstat, tstat;
-
-static char tmpfil[BUFSIZ];
-static char bccfil[BUFSIZ];
-
-static char from[BUFSIZ];      /* my network address            */
-static char signature[BUFSIZ]; /* my signature                  */
-static char *filter = NULL;    /* the filter for BCC'ing        */
-static char *subject = NULL;   /* the subject field for BCC'ing */
-static char *fccfold[FCCS];    /* foldernames for FCC'ing       */
-
-static struct headers  *hdrtab;        /* table for the message we're doing */
-
-static struct mailname localaddrs={NULL};      /* local addrs     */
-static struct mailname netaddrs={NULL};                /* network addrs   */
-static struct mailname uuaddrs={NULL};         /* uucp addrs      */
-static struct mailname tmpaddrs={NULL};                /* temporary queue */
-
-#ifdef SMTPMTS
-static int snoop      = 0;
-static int smtpmode   = S_MAIL;
-static char *clientsw = NULL;
-static char *serversw = NULL;
-
-extern struct smtp sm_reply;
-#endif /* SMTPMTS */
-
-static char prefix[] = "----- =_aaaaaaaaaa";
-
-static int fill_up = 0;
-static char *fill_in = NULL;
-static char *partno = NULL;
-static int queued = 0;
-
-extern boolean  draft_from_masquerading;  /* defined in mts.c */
-
-/*
- * static prototypes
- */
-static void putfmt (char *, char *, FILE *);
-static void start_headers (void);
-static void finish_headers (FILE *);
-static int get_header (char *, struct headers *);
-static int putadr (char *, char *, struct mailname *, FILE *, unsigned int);
-static void putgrp (char *, char *, FILE *, unsigned int);
-static int insert (struct mailname *);
-static void pl (void);
-static void anno (void);
-static int annoaux (struct mailname *);
-static void insert_fcc (struct headers *, unsigned char *);
-static void make_bcc_file (int);
-static void verify_all_addresses (int);
-static void chkadr (void);
-static void sigon (void);
-static void sigoff (void);
-static void p_refile (char *);
-static void fcc (char *, char *);
-static void die (char *, char *, ...);
-static void post (char *, int, int);
-static void do_text (char *file, int fd);
-static void do_an_address (struct mailname *, int);
-static void do_addresses (int, int);
-static int find_prefix (void);
-
-
-int
-main (int argc, char **argv)
-{
-    int state, compnum, dashstuff = 0;
-    char *cp, *msg = NULL, **argp, **arguments;
-    char buf[BUFSIZ], name[NAMESZ];
-    FILE *in, *out;
-
-#ifdef LOCALE
-    setlocale(LC_ALL, "");
-#endif
-    invo_name = r1bindex (argv[0], '/');
-
-    /* foil search of user profile/context */
-    if (context_foil (NULL) == -1)
-       done (1);
-
-    mts_init (invo_name);
-    arguments = getarguments (invo_name, argc, argv, 0);
-    argp = arguments;
-
-    while ((cp = *argp++)) {
-       if (*cp == '-') {
-           switch (smatch (++cp, switches)) {
-               case AMBIGSW: 
-                   ambigsw (cp, switches);
-                   done (1);
-               case UNKWNSW: 
-                   adios (NULL, "-%s unknown", cp);
-
-               case HELPSW: 
-                   snprintf (buf, sizeof(buf), "%s [switches] file", invo_name);
-                   print_help (buf, switches, 0);
-                   done (1);
-               case VERSIONSW:
-                   print_version(invo_name);
-                   done (1);
-
-               case LIBSW:
-                   if (!(cp = *argp++) || *cp == '-')
-                       adios (NULL, "missing argument to %s", argp[-2]);
-                   /* create a minimal context */
-                   if (context_foil (cp) == -1)
-                       done (1);
-                   continue;
-
-               case ALIASW: 
-                   if (!(cp = *argp++) || *cp == '-')
-                       adios (NULL, "missing argument to %s", argp[-2]);
-                   if ((state = alias (cp)) != AK_OK)
-                       adios (NULL, "aliasing error in %s - %s",
-                               cp, akerror (state));
-                   continue;
-
-               case CHKSW: 
-                   checksw++;
-                   continue;
-               case NCHKSW: 
-                   checksw = 0;
-                   continue;
-
-               case DEBUGSW: 
-                   debug++;
-                   continue;
-
-               case DISTSW:
-                   msgstate = RESENT;
-                   continue;
-
-               case FILTSW:
-                   if (!(filter = *argp++) || *filter == '-')
-                       adios (NULL, "missing argument to %s", argp[-2]);
-                   mime = 0;
-                   continue;
-               case NFILTSW:
-                   filter = NULL;
-                   continue;
-               
-               case FRMTSW: 
-                   format++;
-                   continue;
-               case NFRMTSW: 
-                   format = 0;
-                   continue;
-
-               case BITSTUFFSW:
-                   dashstuff = 1;
-                   continue;
-               case NBITSTUFFSW:
-                   dashstuff = -1;
-                   continue;
-
-               case MIMESW:
-                   mime++;
-                   filter = NULL;
-                   continue;
-               case NMIMESW: 
-                   mime = 0;
-                   continue;
-
-               case MSGDSW: 
-                   msgid++;
-                   continue;
-               case NMSGDSW: 
-                   msgid = 0;
-                   continue;
-
-               case VERBSW: 
-                   verbose++;
-                   continue;
-               case NVERBSW: 
-                   verbose = 0;
-                   continue;
-
-               case WATCSW: 
-                   watch++;
-                   continue;
-               case NWATCSW: 
-                   watch = 0;
-                   continue;
-
-               case WHOMSW: 
-                   whomsw++;
-                   continue;
-
-               case WIDTHSW: 
-                   if (!(cp = *argp++) || *cp == '-')
-                       adios (NULL, "missing argument to %s", argp[-2]);
-                   if ((outputlinelen = atoi (cp)) < 10)
-                       adios (NULL, "impossible width %d", outputlinelen);
-                   continue;
-
-               case ANNOSW: 
-                   if (!(cp = *argp++) || *cp == '-')
-                       adios (NULL, "missing argument to %s", argp[-2]);
-                   if ((pfd = atoi (cp)) <= 2)
-                       adios (NULL, "bad argument %s %s", argp[-2], cp);
-                   continue;
-
-               case DLVRSW:
-                   if (!(cp = *argp++) || *cp == '-')
-                       adios (NULL, "missing argument to %s", argp[-2]);
-                   continue;
-
-#ifndef        SMTPMTS
-               case CLIESW:
-               case SERVSW:
-                   if (!(cp = *argp++) || *cp == '-')
-                       adios (NULL, "missing argument to %s", argp[-2]);
-                   continue;
-
-               case SNOOPSW:
-                   continue;
-#else /* SMTPMTS */
-               case MAILSW:
-                   smtpmode = S_MAIL;
-                   continue;
-               case SAMLSW:
-                   smtpmode = S_SAML;
-                   continue;
-               case SOMLSW:
-                   smtpmode = S_SOML;
-                   continue;
-               case SENDSW:
-                   smtpmode = S_SEND;
-                   continue;
-               case CLIESW:
-                   if (!(clientsw = *argp++) || *clientsw == '-')
-                       adios (NULL, "missing argument to %s", argp[-2]);
-                   continue;
-               case SERVSW:
-                   if (!(serversw = *argp++) || *serversw == '-')
-                       adios (NULL, "missing argument to %s", argp[-2]);
-                   continue;
-               case SNOOPSW:
-                   snoop++;
-                   continue;
-#endif /* SMTPMTS */
-
-               case FILLSW:
-                   if (!(fill_in = *argp++) || *fill_in == '-')
-                       adios (NULL, "missing argument to %s", argp[-2]);
-                   continue;
-               case FILLUSW:
-                   fill_up++;
-                   continue;
-               case PARTSW:
-                   if (!(partno = *argp++) || *partno == '-')
-                       adios (NULL, "missing argument to %s", argp[-2]);
-                   continue;
-
-               case QUEUESW:
-                   queued++;
-                   continue;
-               
-               case SASLSW:
-                   sasl++;
-                   continue;
-               
-               case SASLMECHSW:
-                   if (!(saslmech = *argp++) || *saslmech == '-')
-                       adios (NULL, "missing argument to %s", argp[-2]);
-                   continue;
-               
-               case USERSW:
-                   if (!(user = *argp++) || *user == '-')
-                       adios (NULL, "missing argument to %s", argp[-2]);
-                   continue;
-
-               case PORTSW:
-                   if (!(port = *argp++) || *port == '-')
-                       adios (NULL, "missing argument to %s", argp[-2]);
-                   continue;
-
-               case TLSSW:
-                   tls++;
-                   continue;
-           }
-       }
-       if (msg)
-           adios (NULL, "only one message at a time!");
-       else
-           msg = cp;
-    }
-
-    alias (AliasFile);
-
-    if (!msg)
-       adios (NULL, "usage: %s [switches] file", invo_name);
-
-    if (outputlinelen < 10)
-       adios (NULL, "impossible width %d", outputlinelen);
-
-    if ((in = fopen (msg, "r")) == NULL)
-       adios (msg, "unable to open");
-
-    start_headers ();
-    if (debug) {
-       verbose++;
-       discard (out = stdout); /* XXX: reference discard() to help loader */
-    } else {
-       if (whomsw) {
-           if ((out = fopen (fill_in ? fill_in : "/dev/null", "w")) == NULL)
-               adios ("/dev/null", "unable to open");
-       } else {
-            char *cp = m_mktemp(m_maildir(invo_name), NULL, &out);
-            if (cp == NULL) {
-                cp = m_mktemp2(NULL, invo_name, NULL, &out);
-                if (cp == NULL) {
-                   adios ("post", "unable to create temporary file");
-                }
-            }
-            strncpy(tmpfil, cp, sizeof(tmpfil));
-           chmod (tmpfil, 0600);
-       }
-    }
-
-    hdrtab = msgstate == NORMAL ? NHeaders : RHeaders;
-
-    for (compnum = 1, state = FLD;;) {
-       switch (state = m_getfld (state, name, buf, sizeof(buf), in)) {
-           case FLD: 
-           case FLDEOF: 
-           case FLDPLUS: 
-               compnum++;
-               cp = add (buf, NULL);
-               while (state == FLDPLUS) {
-                   state = m_getfld (state, name, buf, sizeof(buf), in);
-                   cp = add (buf, cp);
-               }
-               putfmt (name, cp, out);
-               free (cp);
-               if (state != FLDEOF)
-                   continue;
-               finish_headers (out);
-               break;
-
-           case BODY: 
-           case BODYEOF: 
-               finish_headers (out);
-               if (whomsw && !fill_in)
-                   break;
-               fprintf (out, "\n%s", buf);
-               while (state == BODY) {
-                   state = m_getfld (state, name, buf, sizeof(buf), in);
-                   fputs (buf, out);
-               }
-               break;
-
-           case FILEEOF: 
-               finish_headers (out);
-               break;
-
-           case LENERR: 
-           case FMTERR: 
-               adios (NULL, "message format error in component #%d", compnum);
-
-           default: 
-               adios (NULL, "getfld() returned %d", state);
-       }
-       break;
-    }
-
-    if (pfd != NOTOK)
-       anno ();
-    fclose (in);
-
-    if (debug) {
-       pl ();
-       done (0);
-    } else {
-       fclose (out);
-    }
-
-    /* If we are doing a "whom" check */
-    if (whomsw) {
-       if (!fill_up)
-           verify_all_addresses (1);
-       done (0);
-    }
-
-    if (msgflags & MINV) {
-       make_bcc_file (dashstuff);
-       if (msgflags & MVIS) {
-           verify_all_addresses (verbose);
-           post (tmpfil, 0, verbose);
-       }
-       post (bccfil, 1, verbose);
-       unlink (bccfil);
-    } else {
-       post (tmpfil, 0, isatty (1));
-    }
-
-    p_refile (tmpfil);
-    unlink (tmpfil);
-
-    if (verbose)
-       printf (partno ? "Partial Message #%s Processed\n" : "Message Processed\n",
-               partno);
-    done (0);
-    return 1;
-}
-
-
-/*
- * DRAFT GENERATION
- */
-
-static void
-putfmt (char *name, char *str, FILE *out)
-{
-    int count, grp, i, keep;
-    char *cp, *pp, *qp;
-    char namep[BUFSIZ];
-    struct mailname *mp = NULL, *np = NULL;
-    struct headers *hdr;
-
-    while (*str == ' ' || *str == '\t')
-       str++;
-
-    if (msgstate == NORMAL && uprf (name, "resent")) {
-       advise (NULL, "illegal header line -- %s:", name);
-       badmsg++;
-       return;
-    }
-
-    if ((i = get_header (name, hdrtab)) == NOTOK) {
-       fprintf (out, "%s: %s", name, str);
-       return;
-    }
-
-    hdr = &hdrtab[i];
-    if (hdr->flags & HIGN) {
-       if (fill_in)
-           fprintf (out, "%s: %s", name, str);
-       return;
-    }
-    if (hdr->flags & HBAD) {
-       if (fill_in)
-           fprintf (out, "%s: %s", name, str);
-       else {
-           advise (NULL, "illegal header line -- %s:", name);
-           badmsg++;
-       }
-       return;
-    }
-    msgflags |= (hdr->set & ~(MVIS | MINV));
-
-    if (hdr->flags & HSUB)
-       subject = subject ? add (str, add ("\t", subject)) : getcpy (str);
-    if (hdr->flags & HFCC) {
-       if (fill_in) {
-           fprintf (out, "%s: %s", name, str);
-           return;
-       }
-
-       if ((cp = strrchr(str, '\n')))
-           *cp = 0;
-       for (cp = pp = str; (cp = strchr(pp, ',')); pp = cp) {
-           *cp++ = 0;
-           insert_fcc (hdr, pp);
-       }
-       insert_fcc (hdr, pp);
-       return;
-    }
-
-    if (!(hdr->flags & HADR)) {
-       fprintf (out, "%s: %s", name, str);
-       return;
-    }
-
-    tmpaddrs.m_next = NULL;
-    for (count = 0; (cp = getname (str)); count++)
-       if ((mp = getm (cp, NULL, 0, AD_HOST, NULL))) {
-           if (tmpaddrs.m_next)
-               np->m_next = mp;
-           else
-               tmpaddrs.m_next = mp;
-           np = mp;
-       }
-       else
-           if (hdr->flags & HTRY)
-               badadr++;
-           else
-               badmsg++;
-
-    if (count < 1) {
-       if (hdr->flags & HNIL)
-           fprintf (out, "%s: %s", name, str);
-       else {
-#ifdef notdef
-           advise (NULL, "%s: field requires at least one address", name);
-           badmsg++;
-#endif /* notdef */
-       }
-       return;
-    }
-
-    nameoutput = linepos = 0;
-    snprintf (namep, sizeof(namep), "%s%s",
-               !fill_in && (hdr->flags & HMNG) ? "Original-" : "", name);
-
-    for (grp = 0, mp = tmpaddrs.m_next; mp; mp = np)
-       if (mp->m_nohost) {     /* also used to test (hdr->flags & HTRY) */
-           /* The address doesn't include a host, so it might be an alias. */
-           pp = akvalue (mp->m_mbox);  /* do mh alias substitution */
-           qp = akvisible () ? mp->m_mbox : "";
-           np = mp;
-           if (np->m_gname)
-               putgrp (namep, np->m_gname, out, hdr->flags);
-           while ((cp = getname (pp))) {
-               if (!(mp = getm (cp, NULL, 0, AD_HOST, NULL))) {
-                   badadr++;
-                   continue;
-               }
-
-               if (draft_from_masquerading && ((msgstate == RESENT)
-                                               ? (hdr->set & MRFM)
-                                               : (hdr->set & MFRM)))
-                   /* The user manually specified a [Resent-]From: address in
-                      their draft and the "masquerade:" line in mts.conf
-                      doesn't contain "draft_from", so we'll set things up to
-                      use the actual email address embedded in the draft
-                      [Resent-]From: (after alias substitution, and without the
-                      GECOS full name or angle brackets) as the envelope
-                      From:. */
-                   strncpy(from, auxformat(mp, 0), sizeof(from) - 1);
-
-               if (hdr->flags & HBCC)
-                   mp->m_bcc++;
-               if (np->m_ingrp)
-                   mp->m_ingrp = np->m_ingrp;
-               else
-                   if (mp->m_gname)
-                       putgrp (namep, mp->m_gname, out, hdr->flags);
-               if (mp->m_ingrp)
-                   grp++;
-               if (putadr (namep, qp, mp, out, hdr->flags))
-                   msgflags |= (hdr->set & (MVIS | MINV));
-               else
-                   mnfree (mp);
-           }
-           mp = np;
-           np = np->m_next;
-           mnfree (mp);
-       }
-       else {
-           /* Address includes a host, so no alias substitution is needed. */
-           if (draft_from_masquerading && ((msgstate == RESENT)
-                                           ? (hdr->set & MRFM)
-                                           : (hdr->set & MFRM)))
-               /* The user manually specified a [Resent-]From: address in
-                  their draft and the "masquerade:" line in mts.conf
-                  doesn't contain "draft_from", so we'll set things up to
-                  use the actual email address embedded in the draft
-                  [Resent-]From: (after alias substitution, and without the
-                  GECOS full name or angle brackets) as the envelope
-                  From:. */
-               strncpy(from, auxformat(mp, 0), sizeof(from) - 1);
-
-           if (hdr->flags & HBCC)
-               mp->m_bcc++;
-           if (mp->m_gname)
-               putgrp (namep, mp->m_gname, out, hdr->flags);
-           if (mp->m_ingrp)
-               grp++;
-           keep = putadr (namep, "", mp, out, hdr->flags);
-           np = mp->m_next;
-           if (keep) {
-               mp->m_next = NULL;
-               msgflags |= (hdr->set & (MVIS | MINV));
-           }
-           else
-               mnfree (mp);
-       }
-
-    if (grp > 0 && (hdr->flags & HNGR)) {
-       advise (NULL, "%s: field does not allow groups", name);
-       badmsg++;
-    }
-    if (linepos) {
-       if (fill_in && grp > 0)
-           putc (';', out);
-       putc ('\n', out);
-    }
-}
-
-
-static void
-start_headers (void)
-{
-    unsigned char  *cp;
-    char myhost[BUFSIZ], sigbuf[BUFSIZ];
-    struct mailname *mp;
-
-    myuid = getuid ();
-    mygid = getgid ();
-    time (&tclock);
-
-    strncpy (from, adrsprintf (NULL, NULL), sizeof(from));
-    strncpy (myhost, LocalName (), sizeof(myhost));
-
-    for (cp = myhost; *cp; cp++)
-       *cp = uptolow (*cp);
-
-    if ((cp = getfullname ()) && *cp) {
-       strncpy (sigbuf, cp, sizeof(sigbuf));
-       snprintf (signature, sizeof(signature), "%s <%s>",
-               sigbuf, adrsprintf (NULL, NULL));
-       if ((cp = getname (signature)) == NULL)
-           adios (NULL, "getname () failed -- you lose extraordinarily big");
-       if ((mp = getm (cp, NULL, 0, AD_HOST, NULL)) == NULL)
-           adios (NULL, "bad signature '%s'", sigbuf);
-       mnfree (mp);
-       while (getname (""))
-           continue;
-    } else {
-       strncpy (signature, adrsprintf (NULL, NULL), sizeof(signature));
-    }
-}
-
-
-/*
- * Now that we've outputted the header fields in the draft
- * message, we will now output any remaining header fields
- * that we need to add/create.
- */
-
-static void
-finish_headers (FILE *out)
-{
-    switch (msgstate) {
-       case NORMAL: 
-           if (whomsw && !fill_up)
-               break;
-
-           fprintf (out, "Date: %s\n", dtime (&tclock, 0));
-           if (msgid)
-               fprintf (out, "Message-ID: <%d.%ld@%s>\n",
-                       (int) getpid (), (long) tclock, LocalName ());
-           if (msgflags & MFRM) {
-               /* There was already a From: in the draft.  Don't add one. */
-               if (!draft_from_masquerading)
-                   /* mts.conf didn't contain "masquerade:[...]draft_from[...]"
-                      so we'll reveal the user's actual account@thismachine
-                      address in a Sender: header (and use it as the envelope
-                      From: later). */
-                   fprintf (out, "Sender: %s\n", from);
-           }
-           else
-               /* Construct a From: header. */
-               fprintf (out, "From: %s\n", signature);
-           if (whomsw)
-               break;
-
-           if (!(msgflags & MVIS))
-               fprintf (out, "Bcc: Blind Distribution List: ;\n");
-           break;
-
-       case RESENT: 
-           if (!(msgflags & MDAT)) {
-               advise (NULL, "message has no Date: header");
-               badmsg++;
-           }
-           if (!(msgflags & MFRM)) {
-               advise (NULL, "message has no From: header");
-               badmsg++;
-           }
-           if (whomsw && !fill_up)
-               break;
-
-           fprintf (out, "Resent-Date: %s\n", dtime (&tclock, 0));
-           if (msgid)
-               fprintf (out, "Resent-Message-ID: <%d.%ld@%s>\n",
-                       (int) getpid (), (long) tclock, LocalName ());
-           if (msgflags & MRFM) {
-               /* There was already a Resent-From: in draft.  Don't add one. */
-               if (!draft_from_masquerading)
-                   /* mts.conf didn't contain "masquerade:[...]draft_from[...]"
-                      so we'll reveal the user's actual account@thismachine
-                      address in a Sender: header (and use it as the envelope
-                      From: later). */
-                   fprintf (out, "Resent-Sender: %s\n", from);
-           }
-           else
-               /* Construct a Resent-From: header. */
-               fprintf (out, "Resent-From: %s\n", signature);
-           if (whomsw)
-               break;
-           if (!(msgflags & MVIS))
-               fprintf (out, "Resent-Bcc: Blind Re-Distribution List: ;\n");
-           break;
-    }
-
-    if (badmsg)
-       adios (NULL, "re-format message and try again");
-    if (!recipients)
-       adios (NULL, "no addressees");
-}
-
-
-static int
-get_header (char *header, struct headers *table)
-{
-    struct headers *h;
-
-    for (h = table; h->value; h++)
-       if (!mh_strcasecmp (header, h->value))
-           return (h - table);
-
-    return NOTOK;
-}
-
-
-static int
-putadr (char *name, char *aka, struct mailname *mp, FILE *out, unsigned int flags)
-{
-    int len;
-    char *cp;
-    char buffer[BUFSIZ];
-
-    if (mp->m_mbox == NULL || ((flags & HTRY) && !insert (mp)))
-       return 0;
-    if ((!fill_in && (flags & (HBCC | HDCC))) || mp->m_ingrp)
-       return 1;
-
-    if (!nameoutput) {
-       fprintf (out, "%s: ", name);
-       linepos += (nameoutput = strlen (name) + 2);
-    }
-
-    if (*aka && mp->m_type != UUCPHOST && !mp->m_pers)
-       mp->m_pers = getcpy (aka);
-    if (format) {
-       if (mp->m_gname && !fill_in) {
-           snprintf (buffer, sizeof(buffer), "%s;", mp->m_gname);
-           cp = buffer;
-       } else {
-           cp = adrformat (mp);
-       }
-    } else {
-       cp = mp->m_text;
-    }
-    len = strlen (cp);
-
-    if (linepos != nameoutput) {
-       if (len + linepos + 2 > outputlinelen)
-           fprintf (out, ",\n%*s", linepos = nameoutput, "");
-       else {
-           fputs (", ", out);
-           linepos += 2;
-       }
-    }
-
-    fputs (cp, out);
-    linepos += len;
-
-    return (flags & HTRY);
-}
-
-
-static void
-putgrp (char *name, char *group, FILE *out, unsigned int flags)
-{
-    int len;
-    char *cp;
-
-    if (!fill_in && (flags & HBCC))
-       return;
-
-    if (!nameoutput) {
-       fprintf (out, "%s: ", name);
-       linepos += (nameoutput = strlen (name) + 2);
-       if (fill_in)
-           linepos -= strlen (group);
-    }
-
-    cp = fill_in ? group : concat (group, ";", NULL);
-    len = strlen (cp);
-
-    if (linepos > nameoutput) {
-       if (len + linepos + 2 > outputlinelen) {
-           fprintf (out, ",\n%*s", nameoutput, "");
-           linepos = nameoutput;
-       }
-       else {
-           fputs (", ", out);
-           linepos += 2;
-       }
-    }
-
-    fputs (cp, out);
-    linepos += len;
-}
-
-
-static int
-insert (struct mailname *np)
-{
-    struct mailname *mp;
-
-    if (np->m_mbox == NULL)
-       return 0;
-
-    for (mp = np->m_type == LOCALHOST ? &localaddrs
-           : np->m_type == UUCPHOST ? &uuaddrs
-           : &netaddrs;
-           mp->m_next;
-           mp = mp->m_next)
-       if (!mh_strcasecmp (np->m_host, mp->m_next->m_host)
-               && !mh_strcasecmp (np->m_mbox, mp->m_next->m_mbox)
-               && np->m_bcc == mp->m_next->m_bcc)
-           return 0;
-
-    mp->m_next = np;
-    recipients++;
-    return 1;
-}
-
-
-static void
-pl (void)
-{
-    int i;
-    struct mailname *mp;
-
-    printf ("-------\n\t-- Addresses --\nlocal:\t");
-    for (mp = localaddrs.m_next; mp; mp = mp->m_next)
-       printf ("%s%s%s", mp->m_mbox,
-               mp->m_bcc ? "[BCC]" : "",
-               mp->m_next ? ",\n\t" : "");
-
-    printf ("\nnet:\t");
-    for (mp = netaddrs.m_next; mp; mp = mp->m_next)
-       printf ("%s%s@%s%s%s", mp->m_path ? mp->m_path : "",
-               mp->m_mbox, mp->m_host,
-               mp->m_bcc ? "[BCC]" : "",
-               mp->m_next ? ",\n\t" : "");
-
-    printf ("\nuucp:\t");
-    for (mp = uuaddrs.m_next; mp; mp = mp->m_next)
-       printf ("%s!%s%s%s", mp->m_host, mp->m_mbox,
-               mp->m_bcc ? "[BCC]" : "",
-               mp->m_next ? ",\n\t" : "");
-
-    printf ("\n\t-- Folder Copies --\nfcc:\t");
-    for (i = 0; i < fccind; i++)
-       printf ("%s%s", fccfold[i], i + 1 < fccind ? ",\n\t" : "");
-    printf ("\n");
-}
-
-
-static void
-anno (void)
-{
-    struct mailname *mp;
-
-    for (mp = localaddrs.m_next; mp; mp = mp->m_next)
-       if (annoaux (mp) == NOTOK)
-           goto oops;
-
-    for (mp = netaddrs.m_next; mp; mp = mp->m_next)
-       if (annoaux (mp) == NOTOK)
-           goto oops;
-
-    for (mp = uuaddrs.m_next; mp; mp = mp->m_next)
-       if (annoaux (mp) == NOTOK)
-           break;
-
-oops: ;
-    close (pfd);
-    pfd = NOTOK;
-}
-
-
-static int
-annoaux (struct mailname *mp)
-{
-    int i;
-    char buffer[BUFSIZ];
-
-    snprintf (buffer, sizeof(buffer), "%s\n", adrformat (mp));
-    i = strlen (buffer);
-
-    return (write (pfd, buffer, i) == i ? OK : NOTOK);
-}
-
-
-static void
-insert_fcc (struct headers *hdr, unsigned char *pp)
-{
-    unsigned char *cp;
-
-    for (cp = pp; isspace (*cp); cp++)
-       continue;
-    for (pp += strlen (pp) - 1; pp > cp && isspace (*pp); pp--)
-       continue;
-    if (pp >= cp)
-       *++pp = 0;
-    if (*cp == 0)
-       return;
-
-    if (fccind >= FCCS)
-       adios (NULL, "too many %ss", hdr->value);
-    fccfold[fccind++] = getcpy (cp);
-}
-
-/*
- * BCC GENERATION
- */
-
-static void
-make_bcc_file (int dashstuff)
-{
-    int fd, i;
-    pid_t child_id;
-    char *vec[6];
-    FILE *out;
-    char *tfile = NULL;
-
-    tfile = m_mktemp2(NULL, "bccs", NULL, &out);
-    if (tfile == NULL) adios("bcc", "unable to create temporary file");
-    chmod (bccfil, 0600);
-    strncpy (bccfil, tfile, sizeof(bccfil));
-
-    fprintf (out, "Date: %s\n", dtime (&tclock, 0));
-    if (msgid)
-       fprintf (out, "Message-ID: <%d.%ld@%s>\n",
-               (int) getpid (), (long) tclock, LocalName ());
-    if (msgflags & MFRM) {
-      /* There was already a From: in the draft.  Don't add one. */
-      if (!draft_from_masquerading)
-        /* mts.conf didn't contain "masquerade:[...]draft_from[...]"
-           so we'll reveal the user's actual account@thismachine
-           address in a Sender: header (and use it as the envelope
-           From: later). */
-        fprintf (out, "Sender: %s\n", from);
-    }
-    else
-      /* Construct a From: header. */
-      fprintf (out, "From: %s\n", signature);
-    if (subject)
-       fprintf (out, "Subject: %s", subject);
-    fprintf (out, "BCC:\n");
-
-    /*
-     * Use MIME encapsulation for Bcc messages
-     */
-    if (mime) {
-       char *cp;
-
-       /*
-        * Check if any lines in the message clash with the
-        * prefix for the MIME multipart separator.  If there
-        * is a clash, increment one of the letters in the
-        * prefix and check again.
-        */
-       if ((cp = strchr(prefix, 'a')) == NULL)
-           adios (NULL, "lost prefix start");
-       while (find_prefix () == NOTOK) {
-           if (*cp < 'z')
-               (*cp)++;
-           else
-               if (*++cp == 0)
-                   adios (NULL, "can't find a unique delimiter string");
-               else
-                   (*cp)++;
-       }
-
-       fprintf (out, "%s: %s\n%s: multipart/digest; boundary=\"",
-                VRSN_FIELD, VRSN_VALUE, TYPE_FIELD);
-       fprintf (out, "%s\"\n\n--%s\n\n", prefix, prefix);
-    } else {
-       fprintf (out, "\n------- Blind-Carbon-Copy\n\n");
-    }
-
-    fflush (out);
-
-    /*
-     * Do mhl filtering of Bcc messages instead
-     * of MIME encapsulation.
-     */
-    if (filter != NULL) {
-       vec[0] = r1bindex (mhlproc, '/');
-
-       for (i = 0; (child_id = fork()) == NOTOK && i < 5; i++)
-           sleep (5);
-       switch (child_id) {
-           case NOTOK: 
-               adios ("fork", "unable to");
-
-           case OK: 
-               dup2 (fileno (out), 1);
-
-               i = 1;
-               vec[i++] = "-forward";
-               vec[i++] = "-form";
-               vec[i++] = filter;
-               vec[i++] = tmpfil;
-
-               /* was the flag -[no]dashstuffing specified? */
-               if (dashstuff > 0)
-                   vec[i++] = "-dashstuffing";
-               else if (dashstuff < 0)
-                   vec[i++] = "-nodashstuffing";
-               vec[i] = NULL;
-
-               execvp (mhlproc, vec);
-               fprintf (stderr, "unable to exec ");
-               perror (mhlproc);
-               _exit (-1);
-
-           default: 
-               pidXwait (child_id, mhlproc);
-               break;
-       }
-    } else {
-       if ((fd = open (tmpfil, O_RDONLY)) == NOTOK)
-           adios (tmpfil, "unable to re-open");
-
-       /*
-        * If using MIME encapsulation, or if the -nodashstuffing
-        * flag was given, then just copy message.  Else do
-        * RFC934 quoting (dashstuffing).
-        */
-       if (mime || dashstuff < 0)
-           cpydata (fd, fileno (out), tmpfil, bccfil);
-       else
-           cpydgst (fd, fileno (out), tmpfil, bccfil);
-       close (fd);
-    }
-
-    fseek (out, 0L, SEEK_END);
-    if (mime)
-       fprintf (out, "\n--%s--\n", prefix);
-    else
-       fprintf (out, "\n------- End of Blind-Carbon-Copy\n");
-    fclose (out);
-}
-
-
-/*
- * Scan message to check if any lines clash with
- * the prefix of the MIME multipart separator.
- */
-
-static int
-find_prefix (void)
-{
-    int        len, result;
-    unsigned char buffer[BUFSIZ];
-    FILE *in;
-
-    if ((in = fopen (tmpfil, "r")) == NULL)
-       adios (tmpfil, "unable to re-open");
-
-    len = strlen (prefix);
-
-    result = OK;
-    while (fgets (buffer, sizeof(buffer) - 1, in))
-       if (buffer[0] == '-' && buffer[1] == '-') {
-           unsigned char *cp;
-
-           for (cp = buffer + strlen (buffer) - 1; cp >= buffer; cp--)
-               if (!isspace (*cp))
-                   break;
-           *++cp = '\0';
-           if (strcmp (buffer + 2, prefix) == 0) {
-               result = NOTOK;
-               break;
-           }
-       }
-
-    fclose (in);
-    return result;
-}
-
-
-#define        plural(x) (x == 1 ? "" : "s")
-
-static void
-chkadr (void)
-{
-    if (badadr && unkadr)
-       die (NULL, "%d address%s unparsable, %d addressee%s undeliverable",
-               badadr, plural (badadr), unkadr, plural (badadr));
-    if (badadr)
-       die (NULL, "%d address%s unparsable", badadr, plural (badadr));
-    if (unkadr)
-       die (NULL, "%d addressee%s undeliverable", unkadr, plural (unkadr));
-}
-
-
-static void
-do_addresses (int bccque, int talk)
-{
-    int retval;
-    int        state;
-    struct mailname *lp;
-
-    state = 0;
-    for (lp = localaddrs.m_next; lp; lp = lp->m_next)
-       if (lp->m_bcc ? bccque : !bccque) {
-           if (talk && !state)
-               printf ("  -- Local Recipients --\n");
-           do_an_address (lp, talk);
-           state++;
-       }
-
-    state = 0;
-    for (lp = uuaddrs.m_next; lp; lp = lp->m_next)
-       if (lp->m_bcc ? bccque : !bccque) {
-           if (talk && !state)
-               printf ("  -- UUCP Recipients --\n");
-           do_an_address (lp, talk);
-           state++;
-       }
-
-    state = 0;
-    for (lp = netaddrs.m_next; lp; lp = lp->m_next)
-       if (lp->m_bcc ? bccque : !bccque) {
-           if (talk && !state)
-               printf ("  -- Network Recipients --\n");
-           do_an_address (lp, talk);
-           state++;
-       }
-
-    chkadr ();
-
-#ifdef SMTPMTS
-    if (rp_isbad (retval = sm_waend ()))
-       die (NULL, "problem ending addresses; %s", rp_string (retval));
-#endif /* SMTPMTS */
-}
-
-
-/*
- * MTS-SPECIFIC INTERACTION
- */
-
-
-/*
- * SENDMAIL/SMTP routines
- */
-
-#ifdef SMTPMTS
-
-static void
-post (char *file, int bccque, int talk)
-{
-    int fd, onex;
-    int        retval;
-
-    onex = !(msgflags & MINV) || bccque;
-    if (verbose) {
-       if (msgflags & MINV)
-           printf (" -- Posting for %s Recipients --\n",
-                   bccque ? "Blind" : "Sighted");
-       else
-           printf (" -- Posting for All Recipients --\n");
-    }
-
-    sigon ();
-
-    if (rp_isbad (retval = sm_init (clientsw, serversw, port, watch, verbose,
-                                   snoop, onex, queued, sasl, saslmech,
-                                   user, tls))
-           || rp_isbad (retval = sm_winit (smtpmode, from)))
-       die (NULL, "problem initializing server; %s", rp_string (retval));
-
-    do_addresses (bccque, talk && verbose);
-    if ((fd = open (file, O_RDONLY)) == NOTOK)
-       die (file, "unable to re-open");
-    do_text (file, fd);
-    close (fd);
-    fflush (stdout);
-
-    sm_end (onex ? OK : DONE);
-    sigoff ();
-
-    if (verbose) {
-       if (msgflags & MINV)
-           printf (" -- %s Recipient Copies Posted --\n",
-                   bccque ? "Blind" : "Sighted");
-       else
-           printf (" -- Recipient Copies Posted --\n");
-    }
-
-    fflush (stdout);
-}
-
-
-/* Address Verification */
-
-static void
-verify_all_addresses (int talk)
-{
-    int retval;
-    struct mailname *lp;
-
-    sigon ();
-
-    if (!whomsw || checksw)
-       if (rp_isbad (retval = sm_init (clientsw, serversw, port, watch,
-                                       verbose, snoop, 0, queued, sasl,
-                                       saslmech, user, tls))
-               || rp_isbad (retval = sm_winit (smtpmode, from)))
-           die (NULL, "problem initializing server; %s", rp_string (retval));
-
-    if (talk && !whomsw)
-       printf (" -- Address Verification --\n");
-    if (talk && localaddrs.m_next)
-       printf ("  -- Local Recipients --\n");
-    for (lp = localaddrs.m_next; lp; lp = lp->m_next)
-       do_an_address (lp, talk);
-
-    if (talk && uuaddrs.m_next)
-       printf ("  -- UUCP Recipients --\n");
-    for (lp = uuaddrs.m_next; lp; lp = lp->m_next)
-       do_an_address (lp, talk);
-
-    if (talk && netaddrs.m_next)
-       printf ("  -- Network Recipients --\n");
-    for (lp = netaddrs.m_next; lp; lp = lp->m_next)
-       do_an_address (lp, talk);
-
-    chkadr ();
-    if (talk && !whomsw)
-       printf (" -- Address Verification Successful --\n");
-
-    if (!whomsw || checksw)
-       sm_end (DONE);
-
-    fflush (stdout);
-    sigoff ();
-}
-
-
-static void
-do_an_address (struct mailname *lp, int talk)
-{
-    int retval;
-    char *mbox, *host;
-    char addr[BUFSIZ];
-
-    switch (lp->m_type) {
-       case LOCALHOST: 
-           mbox = lp->m_mbox;
-           host = lp->m_host;
-           strncpy (addr, mbox, sizeof(addr));
-           break;
-
-       case UUCPHOST: 
-           mbox = auxformat (lp, 0);
-           host = NULL;
-           snprintf (addr, sizeof(addr), "%s!%s", lp->m_host, lp->m_mbox);
-           break;
-
-       default:                /* let SendMail decide if the host is bad  */
-           mbox = lp->m_mbox;
-           host = lp->m_host;
-           snprintf (addr, sizeof(addr), "%s at %s", mbox, host);
-           break;
-    }
-
-    if (talk)
-       printf ("  %s%s", addr, whomsw && lp->m_bcc ? "[BCC]" : "");
-
-    if (whomsw && !checksw) {
-       putchar ('\n');
-       return;
-    }
-    if (talk)
-       printf (": ");
-    fflush (stdout);
-
-    switch (retval = sm_wadr (mbox, host,
-                        lp->m_type != UUCPHOST ? lp->m_path : NULL)) {
-       case RP_OK: 
-           if (talk)
-               printf ("address ok\n");
-           break;
-
-       case RP_NO: 
-       case RP_USER: 
-           if (!talk)
-               fprintf (stderr, "  %s: ", addr);
-           fprintf (talk ? stdout : stderr, "loses; %s\n",
-                       rp_string (retval));
-           unkadr++;
-           break;
-
-       default: 
-           if (!talk)
-               fprintf (stderr, "  %s: ", addr);
-           die (NULL, "unexpected response; %s", rp_string (retval));
-    }
-
-    fflush (stdout);
-}
-
-
-static void
-do_text (char *file, int fd)
-{
-    int retval, state;
-    char buf[BUFSIZ];
-
-    lseek (fd, (off_t) 0, SEEK_SET);
-
-    while ((state = read (fd, buf, sizeof(buf))) > 0) {
-       if (rp_isbad (retval = sm_wtxt (buf, state)))
-           die (NULL, "problem writing text; %s\n", rp_string (retval));
-    }
-
-    if (state == NOTOK)
-       die (file, "problem reading from");
-
-    switch (retval = sm_wtend ()) {
-       case RP_OK: 
-           break;
-
-       case RP_NO: 
-       case RP_NDEL: 
-           die (NULL, "posting failed; %s", rp_string (retval));
-
-       default: 
-           die (NULL, "unexpected response; %s", rp_string (retval));
-    }
-}
-
-#endif /* SMTPMTS */
-
-
-/*
- * SIGNAL HANDLING
- */
-
-static RETSIGTYPE
-sigser (int i)
-{
-#ifndef RELIABLE_SIGNALS
-    SIGNAL (i, SIG_IGN);
-#endif
-
-    unlink (tmpfil);
-    if (msgflags & MINV)
-       unlink (bccfil);
-
-#ifdef SMTPMTS
-    if (!whomsw || checksw)
-       sm_end (NOTOK);
-#endif /* SMTPMTS */
-
-    done (1);
-}
-
-
-static void
-sigon (void)
-{
-    if (debug)
-       return;
-
-    hstat = SIGNAL2 (SIGHUP, sigser);
-    istat = SIGNAL2 (SIGINT, sigser);
-    qstat = SIGNAL2 (SIGQUIT, sigser);
-    tstat = SIGNAL2 (SIGTERM, sigser);
-}
-
-
-static void
-sigoff (void)
-{
-    if (debug)
-       return;
-
-    SIGNAL (SIGHUP, hstat);
-    SIGNAL (SIGINT, istat);
-    SIGNAL (SIGQUIT, qstat);
-    SIGNAL (SIGTERM, tstat);
-}
-
-/*
- * FCC INTERACTION
- */
-
-static void
-p_refile (char *file)
-{
-    int i;
-
-    if (fccind == 0)
-       return;
-
-    if (verbose)
-       printf (" -- Filing Folder Copies --\n");
-    for (i = 0; i < fccind; i++)
-       fcc (file, fccfold[i]);
-    if (verbose)
-       printf (" -- Folder Copies Filed --\n");
-}
-
-
-/*
- * Call the `fileproc' to add the file to the folder.
- */
-
-static void
-fcc (char *file, char *folder)
-{
-    pid_t child_id;
-    int i, status;
-    char fold[BUFSIZ];
-
-    if (verbose)
-       printf ("  %sFcc %s: ", msgstate == RESENT ? "Resent-" : "", folder);
-    fflush (stdout);
-
-    for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++)
-       sleep (5);
-
-    switch (child_id) {
-       case NOTOK: 
-           if (!verbose)
-               fprintf (stderr, "  %sFcc %s: ",
-                       msgstate == RESENT ? "Resent-" : "", folder);
-           fprintf (verbose ? stdout : stderr, "no forks, so not ok\n");
-           break;
-
-       case OK: 
-           /* see if we need to add `+' */
-           snprintf (fold, sizeof(fold), "%s%s",
-                   *folder == '+' || *folder == '@' ? "" : "+", folder);
-
-           /* now exec the fileproc */
-           execlp (fileproc, r1bindex (fileproc, '/'),
-                   "-link", "-file", file, fold, NULL);
-           _exit (-1);
-
-       default: 
-           if ((status = pidwait (child_id, OK))) {
-               if (!verbose)
-                   fprintf (stderr, "  %sFcc %s: ",
-                           msgstate == RESENT ? "Resent-" : "", folder);
-               pidstatus (status, verbose ? stdout : stderr, NULL);
-           } else {
-               if (verbose)
-                   printf ("folder ok\n");
-           }
-    }
-
-    fflush (stdout);
-}
-
-/*
- * TERMINATION
- */
-
-static void
-die (char *what, char *fmt, ...)
-{
-    va_list ap;
-
-    unlink (tmpfil);
-    if (msgflags & MINV)
-       unlink (bccfil);
-
-#ifdef SMTPMTS
-    if (!whomsw || checksw)
-       sm_end (NOTOK);
-#endif /* SMTPMTS */
-
-    va_start(ap, fmt);
-    advertise (what, NULL, fmt, ap);
-    va_end(ap);
-    done (1);
-}
index 04dc215..dd0e498 100644 (file)
@@ -377,20 +377,6 @@ finished:
     return (state != FILEEOF ? SCNERR : encrypted ? SCNENC : SCNMSG);
 }
 
-
-/*
- * Cheat:  we are loaded with adrparse, which wants a routine called
- * OfficialName().  We call adrparse:getm() with the correct arguments
- * to prevent OfficialName() from being called.  Hence, the following
- * is to keep the loader happy.
- */
-char *
-OfficialName (char *name)
-{
-    return name;
-}
-
-
 static int
 mh_fputs(char *s, FILE *stream)
 {
index a59e10c..b5b48c5 100644 (file)
@@ -363,20 +363,6 @@ go_to_it: ;
 }
 
 /*
- * Cheat:  we are loaded with adrparse, which wants a routine called
- * OfficialName().  We call adrparse:getm() with the correct arguments
- * to prevent OfficialName() from being called.  Hence, the following
- * is to keep the loader happy.
- */
-
-char *
-OfficialName (char *name)
-{
-    return name;
-}
-
-
-/*
  * Check if a message or file contains any non-text parts
  */
 static int