[unix-pc.sources] STARLAN remote login program

lenny@icus.ICUS.COM (Lenny Tropiano) (06/07/90)

This program connects faster than HDB uucp /usr/bin/cu, and it works nicely.
No docs written for it, but it's usage is easy:

$ rlogin nodename

It will connect up to a STARLAN node on the network that is listening and has
the TTYSERVER ["1"] activated.

This program supports <CR>~! that will suspend the session back to the current
shell (environment $SHELL) or /bin/sh if not set, and resumes the connection
when the shell exits.

To exit, have either the STARLAN connection drop, or use <CR>~. both will
disconnect.

Enhancements, bug fixes, suggestions should be sent to me...

Take care,

-Lenny

-- cut here -- -- cut here -- -- cut here -- -- cut here -- -- cut here --
#! /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:  Makefile rlogin.c
# Wrapped by lenny@icus on Mon Jun  4 00:51:48 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f Makefile -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Makefile\"
else
echo shar: Extracting \"Makefile\" \(621 characters\)
sed "s/^X//" >Makefile <<'END_OF_Makefile'
X#
X# Makefile to compile rlogin.c  (Remote Login)
X# By Lenny Tropiano  
X# (c)1990 ICUS Software Systems  UUCP:  lenny@ICUS.COM
X#
XCFLAGS=-v -O 
XLDFLAGS=-G -s
XLIBS=-lslan /lib/crt0s.o /lib/shlib.ifile
XDEST=/usr/lbin/
XINCLUDEPATH=/usr/net/include
XLIBPATH=/usr/lib/net
X#
Xall:	rlogin 
X#
Xrlogin.o:
X	$(CC) $(CFLAGS) -I$(INCLUDEPATH) -c rlogin.c
X#
Xrlogin:  rlogin.o
X	@echo "Loading ..."
X	$(LD) $(LDFLAGS) -o rlogin rlogin.o -L$(LIBPATH) $(LIBS) 
X
X#
X# You need to be superuser to do this
X#
X$(DEST):
X	mkdir $(DEST)
X
Xinstall: all $(DEST) 
X	cp rlogin $(DEST)
X	chown bin $(DEST)rlogin
X	chgrp bin $(DEST)rlogin
X	chmod 755 $(DEST)rlogin
END_OF_Makefile
if test 621 -ne `wc -c <Makefile`; then
    echo shar: \"Makefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f rlogin.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"rlogin.c\"
else
echo shar: Extracting \"rlogin.c\" \(7262 characters\)
sed "s/^X//" >rlogin.c <<'END_OF_rlogin.c'
X/************************************************************************\
X**                                                                      **
X** Program name: rlogin.c (Remote Login to STARLAN Node)                **
X**                                                                      **
X** Programmer:   Lenny Tropiano        EMAIL: lenny@ICUS.COM            **
X** Organization: ICUS Software Systems (c)1990 All rights reserved      **
X** Date:         June 4, 1990                                           **
X** Version:      1.0                                                    **
X**************************************************************************
X**                                                                      **
X** Program use:  Execute program with one argument, the remote node to  **
X**               connect to, and this will call up a remote STARLAN     **
X**               tty server for the interactive session.  Two "cu"-like **
X**               commands "~!" for a shell and "~." to disconnect are   **
X**               included in this program.                              **
X**                                                                      **
X**************************************************************************
X** Permission granted to redistribute without profit in the public      **
X** domain only.  This header must remain in-tact as is.  This program   **
X** carries no warranties, express or implied, and all consequences      **
X** resulting from the use of this program are the sole responsibility   **
X** of the user.  Any modifications of this program must be mailed to    **
X** the author.                                                          **
X\************************************************************************/
X
X#include <stdio.h>
X#include <signal.h>
X#include <errno.h>
X#include <sys/types.h>
X#include <net/sys/tiuser.h>
X#include <termio.h>
X
Xstruct	termio	sttyparam;		/* stty parameters	*/
Xint	netd;				/* network descriptor	*/
Xchar	*progname,			/* program name		*/
X	*remotenode;			/* system connected to  */
Xchar	*getenv();			/* getenv() call	*/
Xint	command_process();		/* shell command	*/
Xvoid	set_rawmode(),			/* void function decl.	*/
X	set_normalmode(),
X	disconnect(),
X	establish_connection(),
X	input_process(),
X	output_process(),
X	run_shell();
X
X#define	TTYSERVER	"1"		/* service number of tty server */
X#define	TILDE		'~'
X
X/*
X** main process, startup, set terminal, establish connection, and fork the
X** processes to do input and output (I/O)
X*/
X
Xmain(argc, argv)
Xint	argc;
Xchar	*argv[];
X{
X	int	cpid;			/* child process pid	*/
X
X	progname = argv[0];
X
X	if(argc != 2) {
X		fprintf(stderr, "Usage: %s node\n", progname);
X		exit(1);
X	}
X
X	remotenode = argv[1];
X
X	(void)establish_connection();
X
X	set_rawmode();
X
X	/*
X	** fork a process to handle the output, as the other process will
X	** handle the input, much like /usr/bin/cu does it.
X	*/
X
X	if (cpid = fork())
X		(void)input_process();
X	else
X		(void)output_process();
X
X	/*
X	** if the parent process falls through to this point, we've 
X	** encountered some sort of error, kill the child process to avoid
X	** defunct ones out there
X	*/
X
X	kill(cpid, SIGHUP);		/* send hangup signal */
X
X	(void)disconnect();
X
X}
X
X/*
X** establish a network service connection to the remote node tty server
X*/
X
Xvoid establish_connection()
X{
X	printf("\nEstablishing connection to %s ... ", remotenode);
X	fflush(stdout);
X
X	/*
X	** establish a connection and get a network descriptor for the 
X	** node in question
X	*/
X	netd = nlsestablish(remotenode, (char *)NULL);
X	if (netd < 0) {
X		printf("\n%s: node not listening on STARLAN network.\n",
X			remotenode);
X		exit(1);
X	}
X
X	/*
X	** request a server on the established network connection to start
X	** using the network descriptor for communication
X	*/
X	if (nlsrequest(netd, TTYSERVER) < 0) {
X		printf("\n%s: node does not have TTY server.\n",
X			remotenode);
X		t_close(netd);
X		exit(1);
X	}
X
X	/*
X	** check the status of the network device
X	*/
X	if (t_getstate(netd) != T_DATAXFER) {
X		printf("\n%s: after connection, unknown error received.\n",
X			remotenode);
X		t_snddis(netd, (char *)NULL);
X		t_unbind(netd);
X		t_close(netd);
X		exit(1);
X	}
X
X	/*
X	** Ok, we connected successfully...
X	*/
X	printf("\007Connected.\n\n");
X	return;
X}
X
X/*
X** input process to read characters from keyboard and write them to the
X** network device
X*/
X
Xvoid input_process()
X{
X	char	ch, lastch;
X
X	signal(SIGUSR1, disconnect);	/* catch the signal to disconnect */
X
X	for(;;) {
X		read(0, &ch, 1);
X		if (ch == TILDE && (lastch == '\n' || lastch == '\r')) {
X			if (command_process() == 1)
X				break;
X		} else
X			t_snd(netd, &ch, 1, 0);
X
X		lastch = ch;
X	}
X}
X
X/*
X** output process to output characters read from network device
X** to standard output
X*/
X
Xvoid output_process()
X{
X	char	buffer[BUFSIZ];
X	int	flag, nbytes_read;
X
X	signal(SIGINT, SIG_IGN);
X	signal(SIGQUIT, SIG_IGN);
X
X	close(0);			/* we don't need stdin here */
X
X	for (;;) {
X		nbytes_read = t_rcv(netd, buffer, BUFSIZ, &flag);
X		if(nbytes_read < 0 || t_getstate(netd) != T_DATAXFER)
X			break;
X		write(1, buffer, nbytes_read);
X	}
X
X	kill(getppid(), SIGUSR1);	/* terminate the input process */
X
X	exit(1);
X}
X
X/*
X** a ~(tilde) command was received, no check to see if the next character
X** is a valid one, otherwise output it to the network device 
X*/
X
Xint command_process()
X{
X	char	ch;
X
X	read(0, &ch, 1);
X	switch (ch) {
X	case '!':			/* ~! = suspend to shell */
X		run_shell();
X	break;
X	case '.':			/* ~. = disconnect process */
X		return(1);
X	break;
X	default:
X		t_snd(netd, "~", 1, 0);
X	case '~':
X		t_snd(netd, &ch, 1, 0);
X	break;
X	}
X	return(0);
X}
X
X/*
X** suspend to shell back to calling machine
X*/
X
Xvoid run_shell()
X{
X	char	*shell;
X
X	set_normalmode();
X	printf("\n");
X	shell = (char *)getenv("SHELL");
X	if (shell == (char *)NULL)
X		shell = "/bin/sh";
X
X	printf("\r\n%s: STARLAN Session Suspended\n\n", remotenode);
X	if(fork()) {
X		signal(SIGINT, SIG_IGN);
X		signal(SIGQUIT, SIG_IGN);
X		wait(0);
X	} else {
X		signal(SIGINT, SIG_DFL);
X		signal(SIGQUIT, SIG_DFL);
X		(void)execl(shell, shell + 5, (char *)0);
X		perror(progname);
X		exit(1);
X	}
X	printf("\r\n%s: STARLAN Session Resumed\n\n", remotenode);
X
X	set_rawmode();
X
X	signal(SIGINT, SIG_DFL);
X	signal(SIGQUIT, SIG_DFL);
X}
X
X/*
X** set current terminal in RAW mode
X** save old parameters for restoration in sttyparam
X*/
X
Xvoid set_rawmode()
X{
X	struct	termio	rawmode;
X
X        if (ioctl(0,TCGETA,&sttyparam) < 0) 
X		return;
X
X	memcpy(&rawmode, &sttyparam, sizeof(struct termio));
X
X        rawmode.c_cflag |= CS8|CREAD;
X        rawmode.c_cflag &= ~PARENB;
X        rawmode.c_iflag |= IGNBRK;
X        rawmode.c_iflag &= ~(IXOFF|IXON|INPCK|ISTRIP|IGNPAR|BRKINT);
X        rawmode.c_lflag &= ~(ISIG|ICANON|ECHO|XCASE|ECHOE|ECHOK|ECHONL);
X        rawmode.c_cc[VMIN] = 1;         /* 1 char canconical input */
X
X        if (ioctl(0,TCSETA,&rawmode) < 0) 
X		return;
X}
X
X/*
X** reset back to the normal saved parameters
X*/
X
Xvoid set_normalmode()
X{
X        (void)ioctl(0,TCSETA,&sttyparam);
X}
X
X/*
X** disconnect from STARLAN and restore terminal back to correct stty params
X*/
X
Xvoid disconnect()
X{
X	set_normalmode();
X
X	printf("\n\rNode %s: STARLAN Disconnected.\n\n", remotenode);
X
X	t_snddis(netd, (char *)NULL);
X	t_unbind(netd);
X	t_close(netd);
X
X	exit(0);
X}
X
END_OF_rlogin.c
if test 7262 -ne `wc -c <rlogin.c`; then
    echo shar: \"rlogin.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0
-- 
| Lenny Tropiano           ICUS Software Systems        lenny@icus.ICUS.COM |
| {ames,pacbell,decuac,sbcs,hombre,rayssd}!icus!lenny   attmail!icus!lenny  |
+------ ICUS Software Systems --  PO Box 1;  Islip Terrace, NY  11752 ------+