#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README Makefile srialpop.c
# Wrapped by acbhour@speelman on Mon Jun 21 12:48:39 1993
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(7010 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
X
X        S R I A L P O P -- POP over serial lines
X        (sccs info README 1.4 93/06/21)
X
X        Author: Rudi van Houten <R.vanHouten@cc.ruu.nl>
X                Ac.Comp.Centr.Utrecht (Netherlands)
X        With thanks to:
X                Steve Dorner <sdorner@qualcomm.com>
X                Scott Hannahs <sth@slipknot.mit.edu>
X                Mogen Trab Damsgaard <trab@kubism.ku.dk>
X
X        Version 1.0        11 dec '91
X        Version 1.1        nov '92 (never released)
X        Version 1.2        8 jun '93
X	Version 1.3        15 jun '93
X
X    The Macintosh POPmail client Eudora offers a possibility
X    to perform the POP and SMTP conversations over a serial
X    (dialup) connection. Therefore is needed a 'psuedo-account'
X    on a machine where Eudora can login. That account must have
X    permission to execute senndmail and popper, not only local
X    but also remote (via rsh) on all machines where a popserver
X    or smtpserver must be contacted. Eudora is secretive with
X    the password while showing its progress (if properly
X    configured), but nobody can prevent a curious Macontosh
X    owner from looking with ResEdit (or alike's). It can be a
X    security leak.
X    The same considerations apply to the IBM-PC client NUPop
X    that also can use serial tty-lines to acquire mail.
X    
X    This program srialpop is written to take care of these
X    trade off's. It must be used as the pseudo-account's
X    loginshell. The commands which are recognized by the
X    program are 'logout' and 'exit' (to finish the session
X    of course) and 'telnet <host> <port> ...' which performs
X    a TCP/IP connection with the indicated host/port. The
X    supplied portnumber is checked against a list of valid
X    portnumbers (now only POP and SMTP).
X    All other commands cause an exit with errormessage.
X    
X    So the pseudo-account doesn't need permissions to run
X    popper and sendmail, neither needed are permissions to
X    run rsh to another machine or let another machine rsh
X    in. And a diligent POPmail user who tries to login on
X    the psuedo-account will discover that there is no fun.
X    
X    The program is straightforward and rather simple, and
X    it is free. Yet I claim a copyright, with which I mean
X    that anybody who feels a need to change (parts of) this
X    program is under the obligation to document the changes
X    and the need thereof in the program distribution files.
X    Neither may this program be selled (as if anybody would
X    buy this gadget), or distributed for a fee that extends
X    a reasonable retribution for the 8k it occupies on disk
X    or other media (I don't ask money, why should you).
X    I have tested the program for some time now and found no
X    bugs/problems. That doeesn't mean of course there are not.
X    I offer this program free for everyone to use because I
X    think it can be useful and is less dangerous then the
X    shellscript originally suggested by Steve Dorner. But if
X    you stumble over an error I am in no way responsible for
X    the damage that can cause, however I don't expect disasters.
X    I should welcome (by email) any notification of changes,
X    corrections and enhancements in the form of the new program
X    source or a diff.
X
X    At A.C.C.U. we rent POP mailboxes to users as a special cheap
X    service. The users who obtain that service can only use email
X    via the POP/SMTP mechanism. The owner of a POPmail account
X    can not do any work on the UNIX machine, only change his/her
X    password (their login shell is a script that consists of a
X    call to /bin/passwd), and they don't need a home directory.
X    Hence the service can be cheap.
X
X    The passwd entry for pseudo-user srialpop is:
X    (splitted for layout reasons)
X    srialpop:passwd:uid:gid:POP dialup dummy account:\
X                        /home/srialpop:/home/srialpop/srialpop
X
X    The passwd entry for a POPmail account:
X    popuser:passwd:uid:gid:POPmailuser:/home/srialpop:/usr/local/etc/chpw
X
X    And the script /usr/local/etc/chpw used as their loginshell:
X    #!/bin/sh
X    exec /bin/passwd
X
X    (Or place /bin/passwd as "loginshell" in /etc/passwd)
X    
X    Rudi van Houten  <rudi@cc.ruu.nl>
X    Ac.Comp.Centr.Utrecht
X    Budapestlaan 6
X    3584 CD Utrecht Netherlands
X
X    ********************
X    Known bugs:
X
X    **NOTE for NUPop users **
X    If srialpop is used the end-of-line indicator must be set
X    to "^M^J" in the "Options -> Serial" menu of NUPop.
X    ****
X
X    There are some quirks with end-of-line definitions.
X    TCP/IP requires CR-LF (according to the RFC's), but I
X    never encountered a TCP/IP connection that was not satisfied
X    with only LF.
X    Someone reported that his system produced and accepted an
X    end-of-line consisting of LF-CR, I didn't save the mails and
X    forgot the details.
X    When using public datanet systems (as X.25 in Europe) there
X    can be a problem that X.25 considers CR as end-of-packet and
X    the LF that is sent thereafter by the UNIX-system or POP-client
X    is then considered as the start of a new packet, that never is
X    closed. When I will have some time to spare I will look at that,
X    but perhaps someone else will find a solution earlier (I expect
X    it can be solved by setting appropriate LF-CR translations in
X    srialpop and defining a single CR as end-of-line in Eudora/NUPop).
X
X
X    Program history:
X    9 dec 91   original version, only installed at ACCU
X               The distribution contains one file 'srialpop.c'
X    11 dec 91  some changes in IO-handling after Steve Dorner
X               viewed the program and made some sugeestions
X    - V1.0-
X    18 aug 92  added port 105 for PH service
X    20 Oct 92  changes for conditional compilation on Silicon
X               Graphics sent in by Scott Hannahs
X               <sth@slipknot.mit.edu>
X    - V1.1-
X    22 Nov 92  added a wait time before exit to satisfy the
X               Macintosh CTB Hayes Modem Tool.
X               added port 106 for password service
X	       Introduce the use of a make to enable simple
X	       definitions of symbols.
X    14 dec 92  added exclusion of tab expansion
X               (Mogen Trab Damsgaard <trab@kubism.ku.dk>)
X    - V1.2-
X    8 June 93  now change the terminal settings for the whole
X	       life of the program. Read the commands in blocks
X	       of one character and do the echo from the program.
X    - V1.3-
X    15 June 93 V1.2 did send the second character of CR-LF (or 
X	       LF-CR) line-end from the telnet command to the
X	       connected server via the socket. This character
X	       is now catched and thrown away. Some popservers
X	       couldn't handle this, but I didn't see this
X	       since popper did not have troubles.
X
XThis version of srialpop has been successfully tested on:
XConvex OS 10.1
XDEC (Philips) P9070 ATT SYS V/68 R3V6
X
XOn the next systems it compiles OK and seems to work when the
Xtty-session is emulated on keyboard input via a telnet login, but
Xit has NOT been actually tried out.
XSGI IRIX System V.3
XSUN SPARC OS 4.1.3
END_OF_FILE
if test 7010 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(1689 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X# Version 1.1  Makefile 1.4 93/06/21
X#
X# Makefile to compile and install srialpop
X# the installation will place the program in the directory defined
X# with symbol DEST, default the home directory of the user ${SRIALPOP}.
X# Also a .hushlogin, .cshrc, .login and .profile are created there.
X# The user ${SRIALPOP} is asumed to be configured to login with
X# the program srialpop as "loginshell".
X
X#DEST=		/home/srialpop
XDEST=		/usr/people/local/srialpop
XSRIALPOP=	srialpop
XGROUP=		mailusr
X
X# use this on Convexes and Suns:
X#DEFS=
X#LDFLAGS=
X# use this on Silicon Graphics IRIX systems:
XDEFS=	-DSYSV -ansi
XLDFLAGS= -lc_s -s
X# use this on not above mentioned Unix System V (e.g. ULTRIX, SysV/68)
X#DEFS=	-DSYSV
X#LDFLAGS=
X
X# On some systems it can be needed to enable or disable some
X# tty-flags (e.g. X-on/X-off). This can be done by defining
X# the symbol EXTRATTYFLAGS on the next line and writing code
X# in routine extrattyflags situated in file srialpop.c just
X# after the __STDC__ declarations.
X# The code that is there now sets X-on/X-off, but will not
X# be used since EXTRATTYFLAGS is not defined.
X#CFLAGS=	-O ${DEFS} -DEXTRATTYFLAGS
XCFLAGS=	-O ${DEFS}
X
Xsrialpop:	srialpop.o
X		${CC} $? ${LDFLAGS} -o $@
X
Xinstall:	srialpop
X		strip srialpop
X		mv srialpop ${DEST}
X		chgrp ${GROUP} ${DEST}/srialpop
X		chmod 511 ${DEST}/srialpop
X		touch ${DEST}/.hushlogin
X		echo "exit" > ${DEST}/.login
X		-ln ${DEST}/.login ${DEST}/.cshrc
X		-ln ${DEST}/.login ${DEST}/.profile
X		rm -f ${DEST}/.forward
X		chmod 644 ${DEST}/.hushlogin ${DEST}/.login
X
Xclean:
X		rm -f core srialpop *.o srialpop.shar
X
Xshar:		srialpop.shar
X		shar README Makefile srialpop.c > srialpop.shar
X
Xsrialpop.shar:	README Makefile srialpop.c
END_OF_FILE
if test 1689 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'srialpop.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'srialpop.c'\"
else
echo shar: Extracting \"'srialpop.c'\" \(7122 characters\)
sed "s/^X//" >'srialpop.c' <<'END_OF_FILE'
X/*
X
X    S R I A L P O P  (POP over serial lines)
X
X    Author: Rudi van Houten <R.vanHouten@cc.ruu.nl>
X        Ac.Comp.Centr.Utrecht (Netherlands)
X    With thanks to:
X        Steve Dorner <sdorner@qualcomm.com>
X        Scott Hannahs <sth@slipknot.mit.edu>
X        Mogen Trab Damsgaard <trab@kubism.ku.dk>
X
X    see the file README for an introduction and hints for installation
X
X*/
Xstatic char sccsid[]= "@(#)srialpop.c	1.3";
X
X#define LOGOUTGRACE 3
X/*
X    this is the time to wait (seconds) after a logout command before
X    actually breaking the connection
X*/
X
X#include <stdio.h>
X#include <signal.h>
X#include <ctype.h>
X#include <sys/types.h>
X#include <sys/socket.h>
X#include <netinet/in.h>
X#include <netdb.h>
X#include <string.h>
X#ifdef SYSV
X#define bcopy(a,b,c) memcpy(b,a,c)
X#include <termio.h>
X#else
X#include <sgtty.h>
X#endif
X#if __STDC__==1
X#include <stdarg.h>
X#else
X#include <varargs.h>
X#endif
X
X#define CRLF "\r\n"
X
X#define iBuflen 512
Xstatic char sBuf[iBuflen];
X
Xstatic short iValidPort[]=
X        {25     /* SMTP */
X        ,105    /* PH server */
X        ,106    /* password server */
X        ,109    /* POP2 */
X        ,110    /* POP3 */
X        };
X#define iValidPortsCount sizeof(iValidPort)/sizeof(short)
X
X#ifdef SYSV
Xstatic struct termio sTermHold, sTermCurr;
X#else
Xstatic struct sgttyb sTermHold, sTermCurr;
X#endif
X
X#if __STDC__==1
Xstatic void errorexit(char*, ... );
Xvoid main(void);
X# ifdef EXTRATTYFLAGS
Xstatic void extrattyflags(void);
X# endif
X#endif
X
X#ifdef EXTRATTYFLAGS
Xstatic void extrattyflags()
X{
X/*
X * here code can be placed to add/clear extra flags in
X * the tty discipline descriptions
X * here is an example that Scott Hannahs used on SGI
X */
XsTermCurr.c_iflag |= (IXON | IXOFF);
Xreturn;
X} /* void extrattyflags */
X#endif
X
X#if __STDC__==1
Xstatic void errorexit(char *sFormat, ...)
X{
X#else
Xstatic void errorexit(va_alist) va_dcl
X{
X    char *sFormat;
X#endif
X    va_list ap;
X    fputs(CRLF,stderr);
X#if __STDC__==1
X    va_start(ap,sFormat);
X#else
X    va_start(ap);
X    sFormat= va_arg(ap,char*);
X#endif
X    vfprintf(stderr,sFormat,ap);
X    va_end(ap);
X    fputs(CRLF,stderr);
X#ifdef SYSV
X    ioctl(0,TCSETAF,&sTermHold);
X#else
X    ioctl(0,TIOCSETP,&sTermHold);
X#endif
X    sleep(1); exit(1);
X} /* errorexit */
X
Xvoid main()
X{
Xint iSock, iPort, iChild;
Xregister int i, l;
Xstruct in_addr sInAddr;
Xstruct sockaddr_in sServer;
Xstruct hostent *psHost, *gethostbyname(), *gethostbyaddr();
Xchar *psCommand, *psName, *psNumber;
X
X    /* get stty structure sTermHold */
X#ifdef SYSV
Xioctl(0,TCGETA,&sTermHold);
X#else
Xioctl(0,TIOCGETP,&sTermHold);
X#endif
Xbcopy(&sTermHold,&sTermCurr,sizeof(sTermCurr));
X    /* and here prepare the line characteristics */
X#ifdef SYSV
XsTermCurr.c_iflag  &= ~(ICRNL | IXANY);
XsTermCurr.c_oflag  &= ~OPOST;
XsTermCurr.c_lflag  &= ~(ECHO | ICANON | ISIG );
XsTermCurr.c_cc[VMIN] = 1;
XsTermCurr.c_cc[VTIME] = 0;
X#else
XsTermCurr.sg_flags &= ~(ECHO | CRMOD | XTABS);
XsTermCurr.sg_flags |= CBREAK;
X#endif
X#ifdef EXTRATTYFLAGS
Xextrattyflags();
X#endif
X        /* set line characteristics to NOECHO, NOCRLF etc. */
X#ifdef SYSV
Xioctl(0,TCSETAF,&sTermCurr);
X#else
Xioctl(0,TIOCSETP,&sTermCurr);
X#endif
X
X
X/* this is the main loop, it reads the telnet or exit commandline */
Xfor (;;)
X{
X    write(1,"%",1); l= 0;
X    while(read(0,&sBuf[l],1) == 1 && sBuf[l] != '\n' && sBuf[l] != '\r')
X    {
X        write(1,&sBuf[l],1);
X        if (++l >= iBuflen) errorexit("Too long commandline",0);
X    }
X    if (sBuf[l] == '\n' || sBuf[l] == '\r') sBuf[l]= '\0'; else sBuf[++l]= '\0';
X    if (l == 0) continue;
X    write(1,CRLF,2);
X
X    if (strcmp(sBuf,"logout") == 0
X         || strcmp(sBuf,"exit") == 0
X         || strcmp(sBuf,"quit") == 0
X        )
X        break; /* finished, logout now */
X
X            /* next loop splits the commandline in its constituents */
X    i= 0; psCommand= psName= psNumber= NULL;
X    while (i < l && psNumber == NULL)
X    {
X        while (isspace(sBuf[i])) i++;
X        if (i >= l) break;
X        if (psCommand == NULL) psCommand= &sBuf[i]; /* command found */
X        else
X        if (psName == NULL) psName= &sBuf[i];       /* argument 1 */
X        else psNumber= &sBuf[i];                    /* argument 2 */
X        do { i++; } while (!isspace(sBuf[i]) && i < l);
X        sBuf[i++]= '\0';        /* terminator after last argument */
X    }
X    /* now we have a command (telnet) with two
X       arguments (1=host 2=portnumber) */
X
X    if (strcmp(psCommand,"telnet"))
X        errorexit("Sorry, don't know '%s'\n",psCommand);
X                    /* telnet is the only known command */
X
X    if (psName == NULL || psNumber == NULL)
X        errorexit("Sorry, hostname or portnumber missing\n",0);
X                        /* and both host and port are required */
X
X    if (l= strlen(psNumber))
X    {
X        for (i= 0; i < l; i++)
X            if (!isdigit(psNumber[i]))
X                errorexit("Portnumber (%s) not numeric\n",psNumber);
X        iPort= atoi(psNumber);
X    }
X    else iPort= 0;
X
X                        /* check validity of portnumber */
X    for (i=0; iPort != iValidPort[i]; i++)
X        if (i == iValidPortsCount)
X            errorexit("Sorry, %d is not a valid port\n",iPort);
X
X        /*
X           (unsigned long)(-1) = 0xffffffff, returnvalue
X           from inet_addr() if illegal address passed through.
X           I assume then it is a domain name.
X           Thanks to Edwin Kremer (edwin@cs.ruu.nl) for the trick
X        */
X    if ((sInAddr.s_addr= inet_addr(psName)) == 0xffffffff)
X        psHost= gethostbyname(psName);
X    else
X        psHost= gethostbyaddr((char*)&sInAddr,sizeof(struct in_addr),AF_INET);
X    if (psHost == 0)
X        errorexit("Cannot find server %s (host unknown)\n",psName);
X    
X        /* create socket */
X    if ((iSock= socket(AF_INET,SOCK_STREAM,0)) < 0)
X        { perror("Cannot open IP socket"); exit(1); }
X
X        /* fill socket structure .....*/
X    sServer.sin_family= AF_INET;
X    bcopy(psHost->h_addr,&(sServer.sin_addr),psHost->h_length);
X    sServer.sin_port= htons(iPort);
X    
X        /*........and connect */
X    if (connect(iSock,&sServer,sizeof(sServer)) < 0)
X        { perror("connecting stream socket"); exit(1); }
X
X        /* now fork a child to copy stdin to socket */
X    iChild= fork();
X    if (iChild < 0) { perror("Cannot fork"); exit(1); }
X    if (iChild == 0)
X    { /* the child copies stdin to the socket */
X        close(1); close(2); /* now close stdout and stderr */
X        if (read(0,sBuf,1) == 1)
X        {
X            if (sBuf[0] != '\r' && sBuf[0] != '\n') write(iSock,sBuf,1);
X            while ((l= read(0,sBuf,iBuflen)) > 0) write(iSock,sBuf,l);
X        }
X        close(0); exit(0);
X    } /* if (iChild == 0) */
X    /* no else part, child does exit
X       the parent copies the socket to stdout
X    */
X    while ((l= read(iSock,sBuf,iBuflen)) > 0) write(1,sBuf,l);
X    close(iSock);
X
X    kill(iChild,SIGTERM); /* superfluous */
X
X} /* main loop */
X
X        /* reset line characteristics */
X#ifdef SYSV
Xioctl(0,TCSETAF,&sTermHold);
X#else
Xioctl(0,TIOCSETP,&sTermHold);
X#endif
X
Xsleep(LOGOUTGRACE); /* wait to satisfy Mac's Hayes Modem Tool */
Xclose(0); close(1); close(2);
Xexit(0);
X} /* main */
END_OF_FILE
if test 7122 -ne `wc -c <'srialpop.c'`; then
    echo shar: \"'srialpop.c'\" unpacked with wrong size!
fi
# end of 'srialpop.c'
fi
echo shar: End of shell archive.
exit 0
