[comp.sources.unix] v11i021: Batch SMTP program

rs@uunet.UU.NET (Rich Salz) (08/28/87)

Submitted-by: David Herron E-Mail Hack <david@ms.uky.edu>
Posting-number: Volume 11, Issue 21
Archive-name: bsmtp


BSMTP stands for "Batch Simple Mail Transfer Protocol".  It is a form
of SMTP for use over a network where you communicate by way of files
rather than interactive channels.  Both the UUCP network and BITNET are
file oriented networks.  This protocol was originally developed for
BITNET by E. Alan Crosswell of Columbia University, and is documented
in "CUVMB BSMTP" which is available from NETSERVE's on BITNET.  I've
included a copy of CUVMB BSMTP in this distribution; it is in it's
original form (complete with fortran carraige control).  The idea is to
take the same sorts of things the sender says in an SMTP transaction,
put it all in a file, and send that to the reciever.

I'd sent you a copy of this a few months ago (April?) just
before you changed jobs.  Apparently it got lost in the shuffle,
but no matter as it allowed for a couple of bugs to be fixed.

	-- David
[  This is pitifully late because I seem to be unable to get E-mail to
   David, sigh.  --r$ ]

#! /bin/sh
: This is a shell archive, meaning:
: 1. Remove everything above the '#! /bin/sh' line.
: 2. Save the resulting text in a file.
: 3. Execute the file with /bin/sh '(not csh)' to create the files:
:	'README'
:	'CUVMB.BSMTP'
:	'Makefile'
:	'copyright'
:	'ibsmtp.1'
:	'ibsmtp.c'
:	'sendbsmtp'
: This archive created: 'Mon Jul 13 19:10:13 1987'
: By:	'David Herron -- Resident E-mail Hack ()'
export PATH; PATH=/bin:$PATH
echo shar: extracting "'README'" '(5972 characters)'
if test -f 'README'
then
	echo shar: will not over-write existing file "'README'"
else
sed 's/^X//'  >'README' <<'SHAR_EOF'
X(C) Copyright 1987,
X    David Herron and the University of Kentucky Computer Science Dept.
X
XRights are granted to use, distribute, modify, and distribute
Xmodifications of this work, provided that you subscribe to
Xbsmtp-users@ms.uky.edu and describe there any modifications you 
Xmake.
X---
X
XThis package of files contains my BSMTP programs.
X
XBSMTP stands for "Batch Simple Mail Transfer Protocol".  It is a form
Xof SMTP for use over a network where you communicate by way of files
Xrather than interactive channels.  Both the UUCP network and BITNET are
Xfile oriented networks.  This protocol was originally developed for
XBITNET by E. Alan Crosswell of Columbia University, and is documented
Xin "CUVMB BSMTP" which is available from NETSERVE's on BITNET.  I've
Xincluded a copy of CUVMB BSMTP in this distribution; it is in it's
Xoriginal form (complete with fortran carraige control).  The idea is to
Xtake the same sorts of things the sender says in an SMTP transaction,
Xput it all in a file, and send that to the reciever.
X
XExample:
X
XHELO sending-domain
XMAIL FROM: <reverse-path>	# <path> is a regular rfc-822 route/addr
XRCPT TO: <forward-path>
X   ...
XDATA
X   ...  RFC-822 style message (preferably) ...
X.
XQUIT
X
XThe other half of the conversation is to be returned to the sending
Xprocess.  Assumably the sending process will look through the file and
Xsee if there are error codes, and return an error message to the human
Xsender if there are any.  To aid in this, Crosswell added two commands
Xto the SMTP command set, "TICK <id-number>" and "VERBOSE {ON,OFF}".
XThe id-number for the TICK command isn't the Message-ID:, but is
Xsomething else and should be used to get back the message when an error
Xreply comes back.  The VERBOSE command controls the verbosity of the
Xreply file.
X
XThe TICK and VERBOSE commands are seen and ignored because we don't
Xgenerate the reply file.  Instead we just give the message to the
Xmail system and let it generate error messages as necessary.  This
Xis a policy decision that Crosswell saw in a different light than
XI saw it.  I do not know his reasoning behind deciding to generate
Xreply files; possibly to keep the SMTP model as closely as possible;
Xpossibly the crudeness of the systems at the time (1982).  Nevertheless
XI don't see any use for reply files so long as your underlying mail
Xsystem is good, and can generate error messages back to the original
Xsender as necessary.
X
XThe other "known difference" is that RFC-821 specifies that a
XReturn-Path: header be added to the beginning of the message, and that
Xeach host to handle the message add themselves to the beginning of the
XReturn-Path:.  Back in the dark ages when RFC-821 was written, that was
Xprobably a useful thing to do.  Nowadays that isn't so useful since
Xdomains point exactly at the intended host without need to be able to
Xtrace routes back through the network in order to reply.
X
X
X
X
X
XHOW TO USE "ibsmtp"
X
XRight now I'm only using it for receiving BSMTP from BITNET.  I hacked
Xon urep until we weren't using simple any more and using ibsmtp instead.
X(Basically, the hacking involved changes in profile() in daemon/dafile.c
Xand in mailer/damail.c, the sort of changes necessary should be obvious
Xonce you've gotten to those sections of the code).
X
XOn BITNET, BSMTP files arrive in "pure" form.
X
XIn RFC-976, Mark suggests a different form for using BSMTP.
XYou generate a UUCP envelope and RFC-822 envelope for a regular
Xmessage headed for b-smtp@some.site.somewhere.  The body of
Xthis message contains a BSMTP envelope with #'s prepended to
Xeach line.  I might argue with some of his reasoning in deciding
Xthat is the way to do this, however it is the documented method
Xand will definitely do the job.
X
XYet this still leaves us with the problem of using BSMTP.  We will
Xhave to have some way of knowing who can do BSMTP.  We will have
Xto come up with a way for generating routes to the sites which
Xcan do BSMTP.  Also we will have to know what domains the sites
Xwho can do BSMTP can service.
X
XAfter a few minutes thought it seems that we really need to meld this
Xin with the map in some way.  A possibility is to set a special cost of
XBSMTP which isn't really a cost, as in:
X
Xsite	.edu(BSMTP), .gov(BSMTP), ...
X
Xcould automagically generate a path ".edu ...!site!b-smtp".
X
XI think that a few people will want to implement bsmtp immediately.
X(In fact, if I had someone who wanted to do that I'd be happy go ahead
Xand implement it on our uucp side right now).  BUT those sites will
Xlikely be spread out meaning we'd have to make extra links just to do
Xbsmtp over, or have some way to get across the network.  To get started
Xit will work to have hand generated routes and the like, but if it
Xgrows big enough we'll want to have some sort of tools to help out.
X
X
X
XWHY YOU WANT TO USE "ibsmtp"
X
XThe main reason you want to use BSMTP format in your mail is
Xto avoid sending addresses through command lines, and the resultant
Xmucking that the shell can do.  The addresses are hidden in the
XBSMTP file which avoids handling by the shell, for most cases.
X
XThe other reason for using BSMTP is to bring the UUCP world
Xcloser to using domains.
X
X
X
XFUTURE NEEDS
X
X1) Need to have this running under uucp systems.
X2) Need to fix up an rmail which will handle b-smtp.  I think that
X   it would be better to hack rmail to look at the address to see
X   if it is b-smtp rather than send it on into the mail system.
X   Sending it into the mail system will be extra overhead which
X   could get nasty if this stuff ever gets used a lot.
X3) Tools to help us get bsmtp stuff across the net.
X4) Also, some way of knowing the right bsmtp capable place to send
X   things for particular domains to.
X5) "obsmtp" to create bsmtp packages.  Right now I've got a silly
X   shell script which can be used.
X6) A discussion group somewhere.  To get the ball rolling I've created
X   an alias here "bsmtp-users" and "bsmtp-users-request".  The first
X   is for discussion and the second is for administrivia.
X
SHAR_EOF
if test 5972 -ne "`wc -c < 'README'`"
then
	echo shar: error transmitting "'README'" '(should have been 5972 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'CUVMB.BSMTP'" '(12346 characters)'
if test -f 'CUVMB.BSMTP'
then
	echo shar: will not over-write existing file "'CUVMB.BSMTP'"
else
sed 's/^X//'  >'CUVMB.BSMTP' <<'SHAR_EOF'
X0
X0
X0
X0
X0
X                     BATCH SIMPLE MAIL TRANSFER PROTOCOL
X+                    BATCH SIMPLE MAIL TRANSFER PROTOCOL
X+                    BATCH SIMPLE MAIL TRANSFER PROTOCOL
X0
X0
X0
X0
X0
X0
X0
X0
X0
X0
X                              E. Alan Crosswell
X0            Columbia University Center for Computing Activities
X0
X0
X0
X0
X0
X0
X0         Prepared for presentation at BITNET programmers' meeting
X0
X                              13 September 1982
X1                                                                          1
X0
X 1. Acknowledgements
X+1. Acknowledgements
X+1. Acknowledgements
X0                                                                 ______
X+  The following paper is based on electronic mail discussions on BITNET and
X0original  ideas for a Batch SMTP implementation developed by Mike O'Dell on
X0_______
X+ARPAnet.  Thanks to Greg Minshall for making Mike's ideas known.
X0
X02. Introduction
X+2. Introduction
X+2. Introduction
X0  SMTP [1] is an interactive protocol that defines  a  transaction  between
X0two  mail transport servers.  One is defined to be the sender and the other
X0the recipient.
X0
X             1      2
X   Using RSCS , UUCP , or any other store-and-forward transfer system  where
X0   ____
X+a  file  is  the  smallest unit of transmission it is clearly impossible to
X0maintain such a full-duplex transaction.  In RSCS, only files may  be  used
X0to communicate between service machines and no guarantee can be made of the
X0order  of arrival of one file with respect to another.  Also, communication
X0with other than VM systems is required.  Systems connected  via  HASP  SML,
X0NJE/NJI and other links exist (MVS, Unix, Tops-20, etc.).
X0
X0  Why  then  should SMTP be used?  Maybe it shouldn't.  However, since ARPA
X0supports it, it  will  be  well  defined  and  understood  by  the  largest
X0internet.    Also,  it  seems relatively straightforward to create programs
X0that will take a Batch SMTP (BSMTP) file and pass  it  to  a  SMTP  system,
X0
X0_______________
X0  1
X    IBM VM/370 Remote Spooling Communications Subsystem
X   2
X    Unix to Unix Communication Program
X1                                                                          2
X0
X simulating a real SMTP hookup.
X0
X03. Batch SMTP operation
X+3. Batch SMTP operation
X+3. Batch SMTP operation
X0  BSMTP uses seperate files for whole sections of a transaction rather than
X0each  line.   The idea is to create a list of commands that would be issued
X0assuming all previous commands had received OK replies.   This  transaction
X0log  could  then  be sent to the receiver BSMTP server which reads the file
X0and logs its responses.  The response log is then returned, etc.
X0
X0  An example of an SMTP transaction is in in figure 1 and an example of the
X0equivalent BSMTP transaction is in figures 2 and 3 below.
X0    S: HELO CUVMB.BITNET                   ! begin session
X     R: 250 CUVMA.DECNET                    ! acknowledgement and ID
X     S: MAIL FROM:<EACUS@CUVMB.BITNET>      ! request to send mail
X     R: 250 OK                              ! receiver agrees to accept
X     S: RCPT TO:<AC2US@CUVMA.BITNET>        ! recipient #1 is named
X     R: 250 OK                              ! receiver will do it
X     S: RCPT TO:<FOO@CUVMA.BITNET>          ! recipient #2 is named
X     R: 551 No such user                    ! denied this one
X     S: DATA                                ! ready to send data
X     R: Start mail input, end with record containing only "."
X     Date: Monday, 13-Sep-82 10:32 EST
X     From: Alan Crosswell <EACUS@CUVMB>
X     Subject: Hello
X     To: AC2US@CUVMA
X0    Hello there....
X     .
X0
X                     Figure 1:
X+                    Figure 1:
X+                    Figure 1:   Sample SMTP transaction
X1                                                                          3
X0
X     HELO CUVMB.BITNET
X     MAIL FROM:<EACUS@CUVMB.BITNET>
X     RCPT TO:<AC2US@CUVMA.BITNET>
X     RCPT TO:<FOO@CUVMA.BITNET>
X     DATA
X     Date: Monday, 13-Sep-82 10:32 EST
X     From: Alan Crosswell <EACUS@CUVMB>
X     Subject: Hello
X     To: AC2US@CUVMA
X0    Hello there....
X     .
X     QUIT
X0
X                 Figure 2:
X+                Figure 2:
X+                Figure 2:   BSMTP: File from CUVMB to CUVMA
X0
X     220 CUVMA.BITNET Batch Simple Mail Transfer Service Ready
X     250 CUVMA.BITNET
X     250 OK
X     250 OK
X     551 No such user
X     354 Start mail input.  End with "."
X     250 OK
X     221 CUVMA.BITNET Service closing transmission...
X0
X                 Figure 3:
X+                Figure 3:
X+                Figure 3:   BSMTP: File from CUVMA to CUVMB
X0
X04. Modifications to SMTP syntax
X+4. Modifications to SMTP syntax
X+4. Modifications to SMTP syntax
X0  How  does the server on CUVMB in the preceding example know which file in
X0its reader is the reply to which file it sent?  There's no way to  be  sure
X0unless  some  sort  of  extra identification is imbedded in the files.  The
X0following proposed additions to the SMTP commands would solve this and  the
X0problem of coordinating processing of replies:
X1                                                                          4
X0
X 4.1. Ticket command
X+4.1. Ticket command
X+4.1. Ticket command
X0
X     TICK
X+    TICK
X+    TICK <ticket-id>
X0
X        ______
X+  The  Ticket  command  is  used to mark a file with additional identifying
X0information.  This would be a unique message indentifier generated  by  the
X0                                     ______
X+sending BSMTP system.  By use of the ticket, the BSMTP sender would be able
X0to identify a later BSMTP reply.
X0
X 4.2. Verbose command
X+4.2. Verbose command
X+4.2. Verbose command
X0
X     
X             ON
X+            ON
X+            ON
X     VERB
X+    VERB
X+    VERB
X             OFF
X+            OFF
X+            OFF
X     
X0
X       _______
X+  The Verbose command solves the problem of coordinating BSMTP transactions
X0further  by  specifying  that  all  commands received by the receiver BSMTP
X0system be echoed in its reply along with its usual reply codes  (VERB  ON).
X0Data  other  than  that  on  command  lines need not be echoed, so the file
X0overhead is not substantial.
X0
X 4.3. Advantages
X+4.3. Advantages
X+4.3. Advantages
X0         ______     _______                             ______
X+  Use of Ticket and Verbose has several advantages, The ticket  provides  a
X0unique identifier that the sender can use to keep track of the files it has
X0shipped.   When a reply arrives, the sender simply looks up the information
X0                                ______
X+it stored when it generated the ticket and uses the information  to  inform
X0any  interested parties (the person who sent the mail) of the status of the
X0request.
X1                                                                          5
X0
X               _______
X+  The  use of verbose takes the burden off the sender to remember and later
X0synchronize the commands it sent with the replies it  receives.    Assuming
X0the  sender  trusts  the  replying BSMTP system, it has all the information
X0needed in the proper order.  This information could very easily be  "piped"
X0into a program that simulates the SMTP full-duplex interaction.
X0
X0  A  very simple sender implementation would not even have to keep track of
X0_______                _______
X+tickets as long as the verbose information is supplied to it.
X0
X05. Example of BSMTP operations
X+5. Example of BSMTP operations
X+5. Example of BSMTP operations
X0  A complete example would be as follows:
X0
X    1. The CUVMB mailer receives a file from a local user to be sent to
X       a user at CUVMA.
X0               ______
X+   2. A unique ticket is created and a file is punched to CUVMA.   The
X       ______
X+      ticket is stored for later recall.
X0   3. The CUVMA mailer receives the file from CUVMB.
X0   4. Mail is sent to the CUVMA user.
X0         ________                                               ______
X+   5. A  verbsose  reply  file  is generated which contains the ticket
X       supplied by CUVMB and is punched to the CUVMB mailer.
X0   6. The CUVMB mailer receives the file.
X0   7. The file is recognized as a reply rather than an  original  file
X       sent  from  CUVMA  by  the  presence  of reply codes rather than
X       commands.
X0   8. Each code 250 line is read and skipped.
X0   9. Each code 050 line (the echoed  command)  is  processed  to  the
X                                              TICK
X+                                             TICK
X+      degree  desired.    In  this case, the TICK is found and used to
X                  ______
X+      access the ticket that was previously saved.
X0  10. Other code 050 lines and their replies  are  processed  and  the
X                                            _____
X+      appropriate  action  is  taken (i.e. EACUS is informed that user
X       ___
X+      FOO was not found).
X1                                                                          6
X0
X     HELO CUVMB.BITNET
X     VERB ON
X     TICK 0001
X     MAIL FROM:<EACUS@CUVMB.BITNET>
X     RCPT TO:<AC2US@CUVMA.BITNET>
X     RCPT TO:<FOO@CUVMA.BITNET>
X     DATA
X     Date: Monday, 13-Sep-82 10:32 EST
X     From: Alan Crosswell <EACUS@CUVMB>
X     Subject: Hello
X     To: AC2US@CUVMA
X0    Hello there....
X     .
X     QUIT
X0
X                 Figure 4:
X+                Figure 4:
X+                Figure 4:   BSMTP: file generated by sender
X0
X     220 CUVMA.BITNET Batch Simple Mail Transfer Service Ready
X     250 CUVMA.BITNET
X     050 VERB ON
X     250 OK
X     050 TICK 0001
X     250 OK
X     050 MAIL FROM:<EACUS@CUVMB.BITNET>
X     250 OK
X     050 RCPT TO:<AC2US@CUVMA.BITNET>
X     250 OK
X     050 RCPT TO:<FOO@CUVMA.BITNET>
X     551 No such user
X     050 DATA
X     354 Start mail input.  End with "."
X     250 OK
X     050 QUIT
X     221 CUVMB.BITNET closing transmission...
X0
X                Figure 5:
X+               Figure 5:
X+               Figure 5:   BSMTP: file returned by recipient
X0
X06. Compatibility with SMTP
X+6. Compatibility with SMTP
X+6. Compatibility with SMTP
X0       ______      _______
X+  The  Ticket  and Verbose commands and 050 reply code are additions on top
X0of the current SMTP specification.  Assuming that they would be ignored  by
X0                                                   _______
X+an SMTP process, compatibility is maintained.  The Verbose command has even
X0been suggested as a debugging aid for SMTP implementers.
X1                                                                          7
X0
X                                 REFERENCES
X+                                REFERENCES
X+                                REFERENCES
X0
X [1]   Jonathan B. Postel.
X       ______ ____ ________ ________
X+      Simple Mail Transfer Protocol.
X       ARPANET Request for Comments, No. 821; Information Sciences
X          Institute, University of Southern California, 4676 Admirality Way,
X          Marina del Rey, California 90291, 1982.
X1                                                                          i
X0
X Table of Contents
X+Table of Contents
X+Table of Contents
X0     1. Acknowledgements                                                  1
X      2. Introduction                                                      1
X      3. Batch SMTP operation                                              2
X      4. Modifications to SMTP syntax                                      3
X           4.1. Ticket command                                             4
X           4.2. Verbose command                                            4
X           4.3. Advantages                                                 4
X      5. Example of BSMTP operations                                       5
X      6. Compatibility with SMTP                                           6
X1                                                                         ii
X0
X List of Figures
X+List of Figures
X+List of Figures
X0     Figure 1:
X+     Figure 1:
X+     Figure 1:   Sample SMTP transaction                                  2
X      Figure 2:
X+     Figure 2:
X+     Figure 2:   BSMTP: File from CUVMB to CUVMA                          3
X      Figure 3:
X+     Figure 3:
X+     Figure 3:   BSMTP: File from CUVMA to CUVMB                          3
X      Figure 4:
X+     Figure 4:
X+     Figure 4:   BSMTP: file generated by sender                          6
X      Figure 5:
X+     Figure 5:
X+     Figure 5:   BSMTP: file returned by recipient                        6
SHAR_EOF
if test 12346 -ne "`wc -c < 'CUVMB.BSMTP'`"
then
	echo shar: error transmitting "'CUVMB.BSMTP'" '(should have been 12346 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'Makefile'" '(1082 characters)'
if test -f 'Makefile'
then
	echo shar: will not over-write existing file "'Makefile'"
else
sed 's/^X//'  >'Makefile' <<'SHAR_EOF'
X# Makefile for BSMTP programs...
X#
X# Author: David Herron <david@ms.uky.edu>
X#	University of Kentucky, CS Dept.
X#	Patterson Office Tower, Room 915
X#	Lexington, KY  40506-0027
X#
X# (C) Copyright 1987,
X#     David Herron and the University of Kentucky Computer Science Dept.
X# 
X# Rights are granted to use, distribute, modify, and distribute
X# modifications of this work, provided that you subscribe to
X# bsmtp-users@ms.uky.edu and describe there any modifications you 
X# make.
X#
X# Tue Apr 21 15:38:29 EST 1987
X
XDESTDIR=/usr/lib/rscs
X
Xall: ibsmtp
X
Xinstall: all $(DESTDIR)/ibsmtp
X
X$(DESTDIR)/ibsmtp: ibsmtp
X	rm -f $(DESTDIR)/ibsmtp
X	cp ibsmtp $(DESTDIR)/ibsmtp
Xibsmtp: ibsmtp.o
X	cc ibsmtp.o -o ibsmtp $(LDFLAGS)
Xibsmtp.o: ibsmtp.c
X	cc -c ibsmtp.c $(CFLAGS)
X
Xnotes:
X	@echo
X
Xclean:
X	rm -f *.o ibsmtp obsmtp a.out core
X
Xuninstall:
X	rm -f $(DESTDIR)/ibsmtp
X
X# "addman" is a local command which basically copies the named
X# file to /usr/man/manl ... but takes care of doing it right
X# when we're doing it from the "wrong" host and it would fail
X# due to the NFS.
Xdoc:
X	addman ibsmtp.1 1
SHAR_EOF
if test 1082 -ne "`wc -c < 'Makefile'`"
then
	echo shar: error transmitting "'Makefile'" '(should have been 1082 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'copyright'" '(286 characters)'
if test -f 'copyright'
then
	echo shar: will not over-write existing file "'copyright'"
else
sed 's/^X//'  >'copyright' <<'SHAR_EOF'
X(C) Copyright 1987,
X    David Herron and the University of Kentucky Computer Science Dept.
X
XRights are granted to use, distribute, modify, and distribute
Xmodifications of this work, provided that you subscribe to
Xbsmtp-users@ms.uky.edu and describe there any modifications you 
Xmake.
SHAR_EOF
if test 286 -ne "`wc -c < 'copyright'`"
then
	echo shar: error transmitting "'copyright'" '(should have been 286 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'ibsmtp.1'" '(1724 characters)'
if test -f 'ibsmtp.1'
then
	echo shar: will not over-write existing file "'ibsmtp.1'"
else
sed 's/^X//'  >'ibsmtp.1' <<'SHAR_EOF'
X.\" (C) Copyright 1987,
X.\"     David Herron and the University of Kentucky Computer Science Dept.
X.\" 
X.\" Rights are granted to use, distribute, modify, and distribute
X.\" modifications of this work, provided that you subscribe to
X.\" bsmtp-users@ms.uky.edu and describe there any modifications you 
X.\" make.
X.\"
X.TH IBSMTP 8 "April 20, 1987"
X.UC 4
X.SH NAME
Xibsmtp \- Input BSMTP format mail into the mail system.
X.SH SYNOPSIS
X.B ibsmtp
X[
X.B -c
Xmmdf-channel ] [
X.B -d
Xfile-name ] [
X.B -D
Xour-domain ] [ file ... ]
X.br
X.SH DESCRIPTION
X.B Ibsmtp
Xreads the specified files
X(or standard input if there are no files given),
Xand extracts the RFC-822 style messages embedded in the BSMTP information.
XOnce the message (or messages) are extracted,
Xit is handed over to the mail system for delivery.
X.IP -c
XThis specifies which mmdf channel to bring the mail in through.
XThis only makes sense for mmdf sites.
X.IP -d
XThis enables debugging output to the named file.
X.IP -D
XSpecifies what the domain name of this host is.
X.PP
XOther arguments are taken to be BSMTP files,
Xthe standard input is specified by saying just "-".
X.SH "SEE ALSO"
Xsendmail(8), recvprog(8), mail(1)
X.br
XBSMTP is documented in the file "CUVMB BSMTP",
Xavailable on the NETSERV's on BITNET.
X.SH BUGS
XGiving the domain name on the command line is bogus.
XWe should look in the environment somewhere,
Xbut there is no standard place to look.
X.PP
XFor MMDF we use recvprog to put the message into the system,
Xinstead of the mm_*() routines.
XThis is for ease of implementation, and version 2
Xmight use those routines.
X.PP
XInstead of specifying at compile time what mail system is
Xon the host,
Xthe program tries all of them in turn and uses the
Xfirst one which works.
SHAR_EOF
if test 1724 -ne "`wc -c < 'ibsmtp.1'`"
then
	echo shar: error transmitting "'ibsmtp.1'" '(should have been 1724 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'ibsmtp.c'" '(16498 characters)'
if test -f 'ibsmtp.c'
then
	echo shar: will not over-write existing file "'ibsmtp.c'"
else
sed 's/^X//'  >'ibsmtp.c' <<'SHAR_EOF'
Xchar *ProgramId = "(C) Copyright 1987,\
X    David Herron and the University of Kentucky Computer Science Dept.\n\
X    ibsmtp Version 1.0";
X
X/*
X * Rights are granted to use, distribute, modify, and distribute
X * modifications of this work, provided that you subscribe to
X * bsmtp-users@ms.uky.edu and describe there any modifications you 
X * make.
X */
X
X/*
X * ibsmtp.c -- Input BSMTP style mail messages into the system.
X *
X * Originally written by David S. Herron, Thu Nov 20 16:47:29 EST 1986.
X *
X *	My E-mail addresses are:
X *		{BITNET,UUCP}:   david@ukma
X *		CSNET, Internet: david@ms.uky.edu
X *
X *--------------
X * This is the first official release of my BSMTP programs.  They've
X * been held up while mod.sources/comp.sources.unix were in flux,
X * but that allowed for Sjoerd Mullender <sjoerd@cs.vu.nl> to find
X * and fix a couple of bugs.  (Thanks muchly)!
X *	David Herron, Mon Jul 13 19:08:04 EDT 1987
X */
X
X#include <sys/types.h>
X#include <time.h>
X#include <stdio.h>
X#include <ctype.h>
X#include <sys/wait.h>
X
X/*
X * Path names for the various possible mail daemons.
X * If one fails, domail() tries the next one in line.
X */
X#define RECVPROG "/usr/mmdf/chans/recvprog"
X#define SENDMAIL "/usr/lib/sendmail"
X#define BINMAIL "/bin/mail"
X
Xextern char **environ;
X
Xchar *ReversePath = NULL;
Xchar *Channel = NULL;
Xchar *SendingDomain = NULL;
Xchar *OurDomain = NULL;
X
X/*
X * C PURISTS BEWARE!  This data structure is of a type which usually
X * causes confusion.  "ForwardPaths" is being used as a list (char *)'s.
X * Normally this would be declared as "char *a[size];" but I didn't
X * want to leave a limit on the number of ForwardPaths.  ForwardPaths
X * is manipulated ONLY in addpath().  Note the hook that if nForwardPaths
X * is 0 but ForwardPaths points somewhere, that the memory allocated
X * to it is free()'d.
X */
Xchar **ForwardPaths = (char **)NULL;
Xint nForwardPaths = 0;
X
Xint Errors = 0;		/* bumped every time we have an error.
X			 * If we have some, then we exit with
X			 * an error status, and our calling shell
X			 * script will be able to save the output
X			 * for us.
X			 */
X
XFILE *dbgout;
X
X
X/***********   First, some utility functions.    *****************/
X
X
X/*
X * arpadate() -- make a string saying what time it is as specified
X * in RFC-822.  Note the year is %'d by 100 because the spec says
X * that the year is a 2DIGIT.  Won't this cause problems in another
X * 13 years or so?
X *
X * This routine was written on 4.3BSD, but using the SysVr3 manuals
X * for reference.  In particluar, the 4.3 manuals claim that time()
X * returns a long instead of a time_t.  Anyway, it works and it should
X * work everywhere.
X */
Xchar *
Xarpadate()
X{
X	time_t now;
X	struct tm *tmnow;
X	static char buf[BUFSIZ];
X	extern time_t time();
X	static char *days[] = 
X		{ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL };
X	static char *months[] = 
X		{ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
X		  "Aug", "Sep", "Oct", "Nov", "Dec", NULL };
X
X	now = time((long *)0);
X	tmnow = gmtime(&now);
X	(void) sprintf(buf, "%s, %d %s %d %02d:%02d:%02d GMT",
X		days[tmnow->tm_wday], tmnow->tm_mday, months[tmnow->tm_mon],
X		tmnow->tm_year % 100, tmnow->tm_hour, tmnow->tm_min,
X		tmnow->tm_sec);
X	return(buf);
X}
X
X/*
X * killnl(s) -- kill a newline in s.
X */
Xvoid
Xkillnl(s)
Xchar *s;
X{	
X	char *s2, *index();
X
X	if ((s2=index(s, '\n')) != NULL)
X		*s2 = '\0';
X}
X
X/*
X * copystr(s) -- make a copy of the string.
X */
Xchar *
Xcopystr(s)
Xchar *s;
X{
X	char *rval, *malloc(), *strcpy();
X
X	if (!s)
X		return((char *)NULL);
X	rval = malloc((unsigned)(sizeof(char)*strlen(s)+1));
X	return(strcpy(rval, s));
X}
X
X/*
X * copypath(s) -- make a copy of a string, but strip leading '<' 
X * and trailing '>'.  (i.e. suitable for copying <path> out of 
X * one of the BSMTP command lines.
X */
Xchar *
Xcopypath(s)
Xchar *s;
X{
X	char *rval, *s2, *index(), *malloc(), *strcpy();
X
X	if (!s)
X		return(NULL);
X	rval = malloc((unsigned)(strlen(s)+1));
X	if ((s2=index(s, '<')) != NULL)
X		(void) strcpy(rval, s2+1);
X	else
X		(void) strcpy(rval, s);
X	if ((s2=index(rval, '>')) != NULL)
X		*s2 = '\0';
X	return(rval);
X}
X
X/*
X * stripsp(s) -- Strip out excess spacing from a string.
X *		(Only from the front and back of the string).
X */
Xvoid
Xstripsp(s)
Xchar *s;
X{
X	char *outs, *ins;
X
X	if (!s)
X		return;
X	outs = s;
X	ins = s;
X	while (*ins != '\0') {
X		if (*ins == '\t')
X			*ins = ' ';
X		if (*ins == ' ') {
X			if (*(ins-1) != ' ' && outs != s)
X				*outs++ = *ins;
X		}
X		else
X			*outs++ = *ins;
X		ins++;
X	}
X	*outs++ = '\0';
X}
X
X
X/*
X * split(s) -- split a character string into its fields.
X *
X * The return value is a group of pointers into a pair of
X * static areas.  The first (veclist) is a pointer to the 
X * base of a vector of pointers which point at various parts
X * of the second area (buf).  
X *
X * The upshot of that is:
X *
X *	1) Don't expect the data to remain after a call to split,
X *	   so be prepared to make a copy of it.
X *	2) Be nice and don't muck with split()'s copy.
X *
X * Oh, one last thing.  Notice that the last element in veclist[]
X * is marked by being NULL.
X */
Xchar **
Xsplit(s)
Xchar *s;
X{
X	static char *buf = (char *)NULL;
X	static int buflen = 0;
X	static char **veclist = (char **)NULL;
X	int nvecs;
X	int slen;
X	register char *sp, *lastp, *s2;
X	char *malloc(), *realloc(), *index();
X
X	if (!s)
X		return((char **)NULL);
X	if (veclist) {
X		free((char *)veclist);
X	}
X	veclist = (char **)malloc((unsigned)(sizeof(char *)));
X	veclist[0] = (char *)NULL;
X	nvecs = 1;
X	stripsp(s);
X	slen = strlen(s);
X	if (dbgout) fprintf(dbgout, "Original string \"%s\"\n", s);
X	if (buflen < (slen+1)) {
X		buflen = slen+1;
X		if (buf)
X			buf = realloc(buf, (unsigned)(sizeof(char)*buflen));
X		else
X			buf = malloc((unsigned)(sizeof(char)*buflen));
X	}
X	(void) strcpy(buf, s);
X	for (lastp = sp = buf; *sp != '\0'; sp++) {
X		if (*sp == ' ') {
X			nvecs++;
X			veclist = (char **)realloc((char *)veclist, 
X				(unsigned)(sizeof(char *)*nvecs));
X			(*(veclist+nvecs-1)) = (char *)NULL;
X			(*(veclist+nvecs-2)) = lastp;
X			*sp = '\0';
X			if ((s2=index(lastp, '\n')) != NULL)
X				*s2 = '\0';
X			if (dbgout) 
X				fprintf(dbgout, 
X					"Part %d \"%s\"\n", 
X					nvecs-2, veclist[nvecs-2]);
X			lastp = sp+1;
X		}
X	}
X	nvecs++;
X	veclist = (char **)realloc((char *)veclist, 
X		(unsigned)(sizeof(char *)*nvecs));
X	veclist[nvecs-1] = (char *)NULL;
X	veclist[nvecs-2] = lastp;
X	if (dbgout) fprintf(dbgout, "Part %d \"%s\"\n", nvecs-2, lastp);
X	return(veclist);
X}
X
X/*
X * lexequ(s1, s2) -- strcmp of s1 and s2, but ignoring case.
X */
Xint
Xlexequ(s1, s2)
Xregister char *s1, *s2;
X{
X	register char c1, c2;
X
X	if (dbgout) fprintf(dbgout, "lexequ(\"%s\", \"%s\")\n", s1, s2);
X	if (!s1 && !s2)
X		return(0);
X	if (!s1 && s2)
X		return(-1);
X	if (s1 && !s2)
X		return(1);
X	while (*s1 && *s2) {
X		if (islower(*s1))
X			c1 = toupper(*s1);
X		else
X			c1 = *s1;
X		if (islower(*s2))
X			c2 = toupper(*s2);
X		else
X			c2 = *s2;
X		/* printf("<%c,0%o> == <%c,0%o>?\n", c1, c1, c2, c2); */
X		if (c1 != c2)
X			break;
X		s1++;
X		s2++;
X	}
X	return(c1 - c2);
X}
X
X/********     Next, specific stuff for bsmtp processing    *******/
X
X/*
X * addpath(s) -- Add address in s to address list.
X */
Xvoid
Xaddpath(s)
Xchar *s;
X{
X	int i;
X	char *malloc(), *realloc();
X
X	if (!s)
X		return;
X	if (!ForwardPaths || nForwardPaths==0) {
X		if (ForwardPaths) {
X			for (i=0; ForwardPaths[i]; i++)
X				if (ForwardPaths[i])
X					free(ForwardPaths[i]);
X			free((char *)ForwardPaths);
X		}
X		nForwardPaths = 1;
X		ForwardPaths = (char **)malloc((unsigned)(sizeof(char *)));
X		ForwardPaths[0] = copypath(s);
X		if (dbgout) fprintf(dbgout, "addpath(%s, 0)\n", ForwardPaths[0]);
X	}
X	else {
X		nForwardPaths++;
X		ForwardPaths = (char **)realloc((char *)ForwardPaths, 
X					(unsigned)(sizeof(char *)*nForwardPaths));
X		ForwardPaths[nForwardPaths-1] = copypath(s);
X		if (dbgout) fprintf(dbgout, "addpath(%s, %d)\n", 
X			ForwardPaths[nForwardPaths-1], nForwardPaths-1);
X	}
X}
X
X/*
X * domail(f) -- Process that part of the input stream which is the
X * mail message (Between "DATA" and ".") and send it to the addresses
X * which have already been saved away.
X *
X * According to RFC821, lines in the DATA part which should have 
X * a leading "." have the dot doubled.  We need to remove the 
X * doubled dot here.
X */
Xint
Xdomail(f)
XFILE *f;
X{
X	FILE *tmpfil;
X	char fname[40], buf[BUFSIZ], **argv;
X	int argc, argp, i, pid;
X	union wait status;
X	extern char *mktemp();
X
X	(void) strcpy(fname, "/tmp/bsmtxtXXXXXX");
X	(void) mktemp(fname);
X	(void) close(creat(fname, 0644));
X	tmpfil = fopen(fname, "w");
X	fprintf(tmpfil, "Received: ");
X	if (SendingDomain)
X		fprintf(tmpfil, "from %s ", SendingDomain);
X	if (OurDomain)
X		fprintf(tmpfil, "by %s ", OurDomain);
X	if (ReversePath)
X		fprintf(tmpfil, "for %s ", ReversePath);
X	fprintf(tmpfil, "with BSMTP (1.0);\n\t%s\n", arpadate());
X	while (fgets(buf, BUFSIZ, f) != NULL) {
X		if (buf[0] == '.') {
X			if (buf[1] == '\n' || buf[1] == '\0')
X				break;
X			else {
X				(void) fputs(&(buf[1]), tmpfil);
X				if (dbgout) (void) fputs(&(buf[1]), dbgout);
X			}
X		}
X		else {
X			(void) fputs(&(buf[0]), tmpfil);
X			if (dbgout) (void) fputs(&(buf[0]), dbgout);
X		}
X	}
X	(void) fclose(tmpfil);
X	if (nForwardPaths == 0)
X		return(1);
X	if ((pid=fork()) == 0) {
X		/* In child process */
X
X		/* Need to exec a mailer with the file on stdin */
X		(void) fclose(stdin);
X		tmpfil = fopen(fname, "r");
X
X/* First try RECVPROG */
X		argc = 1 + 			/* "recvprog" */
X			(Channel?2:0) +		/* -c Channel */
X			(SendingDomain?2:0) +	/* -h SendingDomain */
X			(ReversePath?2:0) +	/* -s ReversePath */
X			nForwardPaths;
X		argv = (char **)malloc((unsigned)(sizeof(char *)*(argc+1)));
X		argp = 0;
X		if (dbgout) fputs("recvprog", dbgout);
X		argv[argp++] = "recvprog";
X		if (Channel) {
X			argv[argp++] = "-c";
X			argv[argp++] = Channel;
X			if (dbgout) fputs(Channel, dbgout);
X		}
X		if (SendingDomain) {
X			argv[argp++] = "-h";
X			argv[argp++] = SendingDomain;
X			if (dbgout) fputs(SendingDomain, dbgout);
X		}
X		if (ReversePath) {
X			argv[argp++] = "-s";
X			argv[argp++] = ReversePath;
X			if (dbgout) fputs(ReversePath, dbgout);
X		}
X		for (i=0; i<nForwardPaths; i++) {
X			argv[argp++] = ForwardPaths[i];
X			if (dbgout) fputs(argv[argp-1], dbgout);
X		}
X		argv[argp++] = NULL;
X		if (dbgout) (void) fflush(dbgout);
X		execve(RECVPROG, argv, environ);
X
X		perror("recvprog failed, trying sendmail");
X
X/* Gosh, it didn't work, try SENDMAIL */
X		free((char *)argv);
X		argc = 1 +			/* "sendmail" */
X			(SendingDomain?1:0) +	/* "-ffrom" */
X			nForwardPaths;
X		argv = (char **)malloc((unsigned)(sizeof(char *)*(argc+1)));
X		argp = 0;
X		if (dbgout) fputs("sendmail", dbgout);
X		argv[argp++] = "sendmail";
X		if (ReversePath) {
X			/* We won't need buf below here */
X			(void) sprintf(buf, "-f%s", ReversePath);
X			argv[argp++] = buf;
X			if (dbgout) fputs(argv[argp-1], dbgout);
X		}
X		for (i=0; i<nForwardPaths; i++) {
X			argv[argp++] = ForwardPaths[i];
X			if (dbgout) fputs(argv[argp-1], dbgout);
X		}
X		argv[argp++] = NULL;
X		if (dbgout) (void) fflush(dbgout);
X		execve(SENDMAIL, argv, environ);
X
X		perror("sendmail failed, trying binmail");
X
X/* Gosh, it still didn't work... next try BINMAIL */
X		free((char *)argv);
X		argc = 1 +			/* "mail" */
X			(ReversePath?2:0) +	/* -f from */
X			nForwardPaths;
X		argv = (char **)malloc((unsigned)(sizeof(char *)*(argc+1)));
X		argp = 0;
X		if (dbgout) fputs("mail", dbgout);
X		argv[argp++] = "mail";
X		if (ReversePath) {
X			/* We won't need buf below here */
X			argv[argp++] = "-f";
X			argv[argp++] = ReversePath;
X			if (dbgout) fputs(argv[argp-1], dbgout);
X		}
X		for (i=0; i<nForwardPaths; i++) {
X			argv[argp++] = ForwardPaths[i];
X			if (dbgout) fputs(argv[argp-1], dbgout);
X		}
X		argv[argp++] = NULL;
X		if (dbgout) (void) fflush(dbgout);
X		execve(BINMAIL, argv, environ);
X
X		perror("binmail failed, nowhere to turn");
X
X		/* Gosh, it STILL didn't work, but we tried everything! */
X		if (dbgout) fputs("AAAARRRRGGGGHHHH!!!!", dbgout);
X		exit(1);
X	}
X	else {
X		/* In parent, first order of business is to wait for the child */
X		while (wait(&status) != pid)
X			;
X		/*
X		 * Need to do something in case status indicates error.
X		 * Right now, it'll just disappear into thin air.
X		 * Well, not exactly... 
X		 */
X		(void) unlink(fname);
X		if (status.w_status != 0)
X			return(1);
X		else
X			return(0);
X	}
X	return(1);
X}
X
X
X
X
X/*
X * parse(f) -- parse the bsmtp thing on the given file.
X */
Xint
Xparse(f)
XFILE *f;
X{
X	char **words;
X	char buf[BUFSIZ];
X
Xinit_state:
X	if (fgets(buf, BUFSIZ, f) == NULL) {
X		/* early EOF */
X		goto seen_QUIT;
X	}
X	killnl(buf);
X	words = split(buf);
X	if (lexequ("HELO", words[0]) == 0) {
X		if (dbgout) 
X			fprintf(dbgout, "Howdy %s, how the hell are ya?\n", words[1]);
X		SendingDomain = copystr(words[1]);
X		goto seen_HELO;
X	}
X	else if (lexequ("NOOP", words[0]) == 0)
X		goto init_state;
X	else if (lexequ("RSET", words[0]) == 0)
X		goto init_state;
X	else
X		goto seen_ERROR;
X
Xseen_HELO:
X	if (fgets(buf, BUFSIZ, f) == NULL)
X		goto seen_QUIT;
X	killnl(buf);
X	words = split(buf);
X	if (lexequ("MAIL", words[0]) == 0) {
X		if (lexequ("FROM:", words[1])) {
X			/* MAIL FROM: <path> */
X			ReversePath = copypath(words[2]);
X		}
X		else {
X			/* MAIL FROM:<path> */
X			ReversePath = copypath(index(words[1], ':'));
X		}
X		if (dbgout) 
X			fprintf(dbgout, "Oh, you're sending from %s eh?\n", ReversePath);
X		goto seen_MAIL;
X	}
X	else if (lexequ("NOOP", words[0]) == 0)
X		goto seen_HELO;
X	else if (lexequ("TICK", words[0]) == 0)
X		goto seen_HELO;
X	else if (lexequ("VERB", words[0]) == 0)
X		goto seen_HELO;
X	else if (lexequ("QUIT", words[0]) == 0)
X		goto seen_QUIT;
X	else if (lexequ("RSET", words[0]) == 0)
X		goto seen_RSET;
X	else
X		goto seen_ERROR;
X
Xseen_MAIL:
X	if (fgets(buf, BUFSIZ, f) == NULL)
X		goto seen_QUIT;
X	killnl(buf);
X	words = split(buf);
X	if (lexequ("RCPT", words[0]) == 0) {
X		if (lexequ("TO:", words[1])) {
X			/* RCPT TO: <path> */
X			addpath(words[2]);
X		}
X		else {
X			/* RCTP TO:<path> */
X			addpath(index(words[1], ':'));
X		}
X		goto seen_MAIL;
X	}
X	else if (lexequ("DATA", words[0]) == 0)
X		goto seen_DATA;
X	else if (lexequ("RSET", words[0]) == 0)
X		goto seen_RSET;
X	else if (lexequ("NOOP", words[0]) == 0)
X		goto seen_MAIL;
X	else if (lexequ("TICK", words[0]) == 0)
X		goto seen_MAIL;
X	else if (lexequ("VERB", words[0]) == 0)
X		goto seen_MAIL;
X	else if (lexequ("QUIT", words[0]) == 0)
X		goto seen_QUIT;
X	else
X		goto seen_ERROR;
X
Xseen_RSET:
X	if (ReversePath) {
X		free(ReversePath);
X		ReversePath = (char *)NULL;
X	}
X	nForwardPaths = 0;
X	goto seen_HELO;
X
Xseen_DATA:
X	if (domail(f) != 0) {
X		if (dbgout) fprintf(dbgout, "oops\n");
X		Errors++;
X	}
X	goto seen_RSET;
X
Xseen_QUIT:
X	return(0);
X
Xseen_ERROR:
X	return(1);
X}
X
X
X/*
X * doparse(s) -- open file named in s and run parse on it.
X */
Xvoid
Xdoparse(s)
Xchar *s;
X{
X	char fname[BUFSIZ], buf[BUFSIZ];
X	FILE *infile;
X
X	if (!s) {
X		/*
X		 * If the creat() fails then everything else will
X		 * fail and the whole file will be dropped on the
X		 * floor.  What's a mother to do?
X		 */
X		(void) strcpy(fname, "/tmp/bsinXXXXXX");
X		(void) mktemp(fname);
X		(void) close(creat(fname, 0600));
X		infile = fopen(fname, "w");
X		while (fgets(buf, BUFSIZ, stdin) != NULL)
X			fputs(buf, infile);
X		(void) fclose(infile);
X		infile = fopen(fname, "r");
X	}
X	else {
X		infile = fopen(s, "r");
X	}
X	if (infile && parse(infile)) {
X		Errors++;
X	}
X	else {
X		(void) unlink(fname);
X	}
X}
X
X/*
X * main(argc, argv) -- main program.
X */
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X	int i;
X	int didanything = 0;
X
X	Errors = 0;
X	for (i=1; i<argc; i++) {
X		if (argv[i][0] == '-') {
X			switch (argv[i][1]) {
X			case '\0': /* "-" 	read stdin */
X				if (dbgout) fprintf(dbgout, "doparse(NULL)\n");
X				didanything++;
X				doparse((char *)NULL);
X				break;
X			case 'c': /* -c channel	specify a channel */
X				if (dbgout)
X					fprintf(dbgout, "Channel = %s\n", argv[i+1]);
X				Channel = argv[i+1];
X				i++;
X				break;
X			case 'd': /* -d file	enable debugging messages */
X				dbgout = fopen(argv[i+1], "w");
X				if (!dbgout) perror("opening dbgout");
X				i++;
X				break;
X			case 'D': /* -D domain	specify the local domain name */
X				if (dbgout)
X					fprintf(dbgout, "OurDomain = %s\n", argv[i+1]);
X				OurDomain = argv[i+1];
X				i++;
X				break;
X			default: /* eh? */
X				if (dbgout)
X					fprintf(dbgout, "Unknown option %c i=%d\n",
X						argv[i][1], i);
X				break;
X			}
X		} 
X		else {		/* anything else is a file to parse */
X			if (dbgout) fprintf(dbgout, "doparse(%s)\n", argv[i]);
X			didanything++;
X			doparse(argv[i]);
X		}
X	}
X	if (!didanything) {
X		/* Specifying no files means to try stdin */
X		if (dbgout) fprintf(dbgout, "doparse(stdin)\n");
X		didanything++;
X		doparse((char *)NULL);
X	}
X	if (Errors > 0)
X		exit(1);
X	else
X		exit(0);
X	/*NOTREACHED*/
X}
SHAR_EOF
if test 16498 -ne "`wc -c < 'ibsmtp.c'`"
then
	echo shar: error transmitting "'ibsmtp.c'" '(should have been 16498 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'sendbsmtp'" '(1458 characters)'
if test -f 'sendbsmtp'
then
	echo shar: will not over-write existing file "'sendbsmtp'"
else
sed 's/^X//'  >'sendbsmtp' <<'SHAR_EOF'
X#! /bin/sh
X# sendbsmtp -- send a bsmtp packet given a destination and file.
X#
X# USAGE:  sendbsmtp mailer dest [ file ]
X
XPATH=/bin:/usr/bin:/usr/local:/usr/ucb:.
Xexport PATH
X
XFROM=`whoami`@ukma
XMAILER=${1}
XTO=${2}
XFILE=${3}
X
X#		 NOTICE!!!!
X#
X# We're zapping the command line args here, so if you need them
X# take care of getting them before now!
Xset `date`
XDAY=${1}
XMONTH=${2}
XDATE=${3}
XTIME=${4}
XTIMEZONE=${5}
XYEAR=${6}
XARPADATE="${DAY}, ${DATE} ${MONTH} ${YEAR} ${TIME} ${TIMEZONE}"
X
Xif test -z "${MAILER}" -o -z "${TO}"; then
X	echo Usage: sendbsmtp mailer dest \[ file \]
X	echo
X	echo where, mailer is user@host id of the mailer to send this to, and
X	echo        dest is the address to send the mail to.
X	exit 1
Xfi
X
Xif test -z "${FILE}"; then
X	echo No file name given, stdin used
Xfi
X
X( echo HELO ukma
X  echo MAIL FROM:\<${FROM}\>
X  echo RCPT TO:\<${TO}\>
X  echo DATA
X  echo "From:    " ${FROM}
X  echo "To:      " ${TO}
X  echo "Date:    " ${ARPADATE}
X  echo -n "Subject: " File sent from ukma.bitnet \(or ms.uky.edu\) " "
X  if test -z "${FILE}"; then
X  	echo -- Unknown name
X  else
X  	echo -- ${FILE}
X  fi
X  echo " "
X  if test ! -z "${FILE}"; then
X  	if test -f ${FILE} -a -r ${FILE}; then
X		# This sed command looks for lines beginning with a '.',
X		# and adds a '.' to the beginning of the line.  This is
X		# as per the [B]SMTP spec.
X  		sed '/^\./s/^\..*$/.&/' ${FILE}
X  	fi
X  else
X	sed '/^\./s/^\..*$/.&/'
X  fi
X  echo .
X  echo QUIT ) >bsmtp.in
X
Xexit 0
SHAR_EOF
if test 1458 -ne "`wc -c < 'sendbsmtp'`"
then
	echo shar: error transmitting "'sendbsmtp'" '(should have been 1458 characters)'
fi
chmod +x 'sendbsmtp'
fi # end of overwriting check
:	End of shell archive
exit 0
--
----- David Herron,  Local E-Mail Hack,  david@ms.uky.edu, david@ms.uky.csnet
-----                            {uunet,cbosgd}!ukma!david, david@UKMA.BITNET
----- bsmtp-users@ms.uky.edu for bsmtp discussion
----- bsmtp-users-request@ms.uky.edu for administrivia
-- 

Rich $alz
Cronus Project, BBN Labs			rsalz@bbn.com
Moderator, comp.sources.unix			sources@uunet.uu.net