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 ------+