mirror of
https://github.com/bstansell/conserver.git
synced 2024-12-24 15:06:42 +00:00
Imported from conserver-GNAC-6.05.tar.gz
This commit is contained in:
commit
decc2f8c4f
64
autologin/INSTALL
Normal file
64
autologin/INSTALL
Normal file
@ -0,0 +1,64 @@
|
||||
# $Id: INSTALL,v 1.3 94/07/11 12:38:19 ksb Exp $
|
||||
|
||||
To install this program you need root access and access to the physical
|
||||
console of the machine (either through the console server or via the physical
|
||||
world).
|
||||
|
||||
First compile this program and install it as /etc/autologin or
|
||||
/usr/local/etc/autologin. If `/' is the only file system mounted sometimes
|
||||
you'll have to use the /etc directory.
|
||||
|
||||
OK. Then login on the console as root and run
|
||||
# exec /etc/autologin -l root
|
||||
|
||||
if you get a prompt back with no warnings things look good. Next try
|
||||
to force *your* account on the console (replace `ME' with your account):
|
||||
# finger -s
|
||||
...
|
||||
# exec /etc/autologin -l ME
|
||||
$ finger -s
|
||||
...
|
||||
|
||||
You should have seen root on the console the first time you ran finger and
|
||||
`ME' on the console the second.
|
||||
|
||||
If you got this far we are ready to make the leap. Exit the autologin shell
|
||||
as `ME' and login as root *on another terminal*. Edit /etc/inittab on a
|
||||
System V machine
|
||||
|
||||
cons2:2:respawn:/usr/local/etc/autologin -t/dev/tty0 -lroot >/dev/console 2>&1
|
||||
or
|
||||
co:2:respawn:/usr/local/etc/autologin -t/dev/console -lroot
|
||||
|
||||
|
||||
or on an RIOS run commands like:
|
||||
mkitab "cons0:013456789:respawn:/etc/getty /dev/console"
|
||||
mkitab "cons2:2:respawn:/usr/local/etc/autologin -t/dev/tty0 -lroot -gsystem >/dev/console 2>&1"
|
||||
chitab "cons:0123456789:off:/etc/getty /dev/console"
|
||||
chcons -a login=disable
|
||||
|
||||
|
||||
if you are running SunOS edit /etc/ttytab and comment out the line for the
|
||||
console and add a new one for autologin:
|
||||
#console "/usr/etc/getty cons8" unknown on local
|
||||
console "/usr/local/etc/autologin -lroot -t" xterm on local secure
|
||||
|
||||
In either case restart init on the port now
|
||||
kill -1 1
|
||||
or
|
||||
telinit 2
|
||||
or what ever local custom sez.
|
||||
|
||||
One of these will look right to you.
|
||||
|
||||
|
||||
You should get a root shell on the console that you can exit and it will just
|
||||
come back. When the machine reboots it should stick the same shell up. You
|
||||
can make the login name here be `ops' or some other `operator' account to run
|
||||
backups. We use `root'.
|
||||
|
||||
|
||||
|
||||
--
|
||||
"We've got all your slack" -- net.flamer
|
||||
kayessbee, Kevin Braunsdorf, ksb@cc.purdue.edu, pur-ee!ksb, purdue!ksb
|
83
autologin/Makefile
Normal file
83
autologin/Makefile
Normal file
@ -0,0 +1,83 @@
|
||||
#
|
||||
# $Id: Make.host,v 1.13 94/06/03 15:32:46 nuspl Exp $
|
||||
#
|
||||
# Makefile for autologin
|
||||
#
|
||||
# Jeff W. Stewart, Purdue University Computing Center
|
||||
#
|
||||
|
||||
DESTDIR=
|
||||
BINDIR= ${DESTDIR}/usr/local/etc
|
||||
|
||||
INCLUDE=
|
||||
DEBUG= -g
|
||||
DEFS= -DPUCC -DSUN5
|
||||
CFLAGS= ${DEBUG} ${DEFS} ${INCLUDE}
|
||||
|
||||
GENC= main.c
|
||||
GENH= main.h
|
||||
GEN= ${GENC} ${GENH}
|
||||
HDR=
|
||||
SRC= autologin.c
|
||||
OBJ= autologin.o main.o
|
||||
SOURCE= README autologin.man autologin.m Makefile ${SRC} ${HDR}
|
||||
|
||||
|
||||
|
||||
all: autologin
|
||||
|
||||
autologin: ${OBJ}
|
||||
${CC} ${CFLAGS} -o autologin ${OBJ}
|
||||
|
||||
main.h: main.c
|
||||
|
||||
main.c: autologin.m
|
||||
mkcmd std_help.m std_version.m autologin.m
|
||||
-(cmp -s prog.c main.c || (cp prog.c main.c && echo main.c updated))
|
||||
-(cmp -s prog.h main.h || (cp prog.h main.h && echo main.h updated))
|
||||
rm -f prog.[ch]
|
||||
|
||||
# On keep (EPIX), putenv.o is extracted (ar x) from /usr/lib/libc.a
|
||||
# and setgroups.o is extracted from libbsd.a
|
||||
#
|
||||
putenv.o:
|
||||
ar x /usr/lib/libc.a $@
|
||||
|
||||
setgroups.o:
|
||||
ar x /usr/lib/libbsd.a $@
|
||||
|
||||
getut.o:
|
||||
ar x /sysv/usr/lib/libc.a $@
|
||||
|
||||
clean: FRC
|
||||
rm -f autologin *.o errs core Makefile.bak a.out lint.errs ${GEN}
|
||||
|
||||
lint: ${HDR} ${SRC} ${GEN} FRC
|
||||
lint -h ${CDEFS} ${INCLUDE} ${GEN} ${SRC}
|
||||
|
||||
install: all
|
||||
install -c -s -m 755 autologin ${BINDIR}
|
||||
|
||||
distrib:
|
||||
distrib -c ${BINDIR}/autologin
|
||||
|
||||
depend: ${HDR} ${SRC} ${GEN}
|
||||
maketd -a ${HDR} ${SRC} ${GEN}
|
||||
|
||||
spotless: clean
|
||||
rcsclean Makefile ${HDR} ${SRC}
|
||||
|
||||
source: ${SOURCE}
|
||||
|
||||
${SOURCE}:
|
||||
co -q $@
|
||||
|
||||
FRC:
|
||||
|
||||
# DO NOT DELETE THIS LINE - maketd DEPENDS ON IT
|
||||
|
||||
main.o: main.c
|
||||
|
||||
autologin.o: autologin.c main.h
|
||||
|
||||
# *** Do not add anything here - It will go away. ***
|
13
autologin/README
Normal file
13
autologin/README
Normal file
@ -0,0 +1,13 @@
|
||||
# $Id: README,v 1.3 93/04/21 16:13:37 ksb Exp $
|
||||
|
||||
This program can be used to put a root shell on the console at boot time.
|
||||
See the manual page.
|
||||
|
||||
ksb
|
||||
|
||||
Ports to: HOST OS CDEFS
|
||||
SUN3 4.1.1 -DSUNOS
|
||||
SUN4 4.1.2 -DSUNOS
|
||||
V386 ? -DSRM
|
||||
EPIX ? -DEPIX -systype posix -I/usr/include (+ extra .o files)
|
||||
IBMR2 -DIBMR2
|
654
autologin/autologin.c
Normal file
654
autologin/autologin.c
Normal file
@ -0,0 +1,654 @@
|
||||
/*
|
||||
* Perform an auto-login on a specified tty port.
|
||||
*
|
||||
* autologin [-u] [-c<command>] [-e<env=val>] [-g<group>] -l<login> -t<tty>
|
||||
*
|
||||
* Jeff W. Stewart - Purdue University Computing Center
|
||||
*
|
||||
* some of the ideas in this code are based on the Ohio State
|
||||
* console server as re-coded by Kevin Braunsdorf (PUCC)
|
||||
*
|
||||
* This program was written to be run out of inittab.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <utmp.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
#if !defined IBMR2
|
||||
extern char *sys_errlist[];
|
||||
#define strerror(Me) (sys_errlist[Me])
|
||||
#endif
|
||||
|
||||
#define NEED_PUTENV (!(defined(IBMR2) || defined(EPIX) || defined(SUNOS) || defined(SUN5)))
|
||||
|
||||
#if S81
|
||||
#include <sys/vlimit.h>
|
||||
#else
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#if SUN5
|
||||
#define USE_UTENT 1
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
static int
|
||||
getdtablesize()
|
||||
{
|
||||
auto struct rlimit rl;
|
||||
|
||||
(void)getrlimit(RLIMIT_NOFILE, &rl);
|
||||
return rl.rlim_cur;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* yucky kludges
|
||||
*/
|
||||
#ifdef EPIX
|
||||
#include "/bsd43/usr/include/ttyent.h"
|
||||
#include <posix/sys/termios.h>
|
||||
#define NGROUPS_MAX 8
|
||||
#define getsid(Mp) (Mp)
|
||||
#define getdtablesize() 64
|
||||
struct timeval {
|
||||
long tv_sec; /* seconds */
|
||||
long tv_usec; /* and microseconds */
|
||||
};
|
||||
typedef int mode_t;
|
||||
extern struct passwd *getpwnam();
|
||||
extern struct group *getgrnam();
|
||||
#define USE_TC 1
|
||||
#define USE_UTENT 1
|
||||
#else
|
||||
|
||||
#if defined IBMR2
|
||||
#include <termios.h>
|
||||
#define setsid() getpid()
|
||||
#define getsid(Mp) (Mp)
|
||||
#define HAVE_GETUSERATTR 1
|
||||
#define USE_TC 1
|
||||
#define USE_UTENT 1
|
||||
#else
|
||||
|
||||
#if defined V386
|
||||
typedef int mode_t;
|
||||
#define getdtablesize() OPEN_MAX
|
||||
#define setsid() getpid()
|
||||
#define getsid(Mp) (Mp)
|
||||
#define setgroups(x, y) 0
|
||||
#include <sys/ttold.h>
|
||||
#include <sys/ioctl.h>
|
||||
#define USE_IOCTL 1
|
||||
#define USE_TC 1
|
||||
#else
|
||||
|
||||
#if defined S81
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
typedef int mode_t;
|
||||
#define setsid() getpid()
|
||||
#define getsid(Mp) (Mp)
|
||||
#define USE_IOCTL 1
|
||||
#define USE_TC 0
|
||||
#define USE_OLD_UTENT 1
|
||||
#else
|
||||
|
||||
#if defined(NETBSD)
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/ioctl_compat.h>
|
||||
#define setsid() getpid()
|
||||
#define getsid(Mp) (Mp)
|
||||
#define USE_IOCTL 1
|
||||
#define USE_OLD_UTENT 1
|
||||
#define PATH_SU "/usr/ucb/su"
|
||||
#define UTMP_PATH "/var/run/utmp"
|
||||
#else
|
||||
|
||||
#if defined(FREEBSD)
|
||||
#include <sys/time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/ioctl_compat.h>
|
||||
#define setsid() getpid()
|
||||
#define getsid(Mp) (Mp)
|
||||
#define USE_IOCTL 1
|
||||
#define USE_OLD_UTENT 1
|
||||
#define PATH_SU "/usr/ucb/su"
|
||||
#else
|
||||
|
||||
#include <sys/termios.h>
|
||||
#endif /* NETBSD */
|
||||
#endif /* 386bsd or equiv */
|
||||
#endif /* sequent */
|
||||
#endif /* intel v386 */
|
||||
#endif /* find termios */
|
||||
#endif /* find any term stuff */
|
||||
|
||||
|
||||
#ifdef SUNOS
|
||||
#include <sys/time.h>
|
||||
#include <ttyent.h>
|
||||
#define setsid() getpid()
|
||||
#define getsid(Mp) (Mp)
|
||||
#endif
|
||||
|
||||
#if ! defined V386
|
||||
#include <sys/vnode.h>
|
||||
#endif
|
||||
|
||||
#ifdef IBMR2
|
||||
#include <sys/ioctl.h>
|
||||
#include <usersec.h>
|
||||
#endif /* IBMR2 */
|
||||
|
||||
#include "main.h"
|
||||
|
||||
|
||||
#define TTYMODE 0600
|
||||
|
||||
#ifndef O_RDWR
|
||||
#define O_RDWR 2
|
||||
#endif
|
||||
|
||||
#ifndef NGROUPS_MAX
|
||||
#define NGROUPS_MAX 8
|
||||
#endif
|
||||
|
||||
#if !defined(UTMP_FILE)
|
||||
#if defined(_PATH_UTMP)
|
||||
#define UTMP_FILE _PATH_UTMP
|
||||
#else
|
||||
#define UTMP_FILE "/etc/utmp"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(PATH_SU)
|
||||
#define PATH_SU "/bin/su"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
char *rcsid = "$Id: autologin.c,v 1.22 93/09/04 21:48:41 ksb Exp $";
|
||||
#endif /* not lint */
|
||||
char *progname;
|
||||
gid_t awGrps[NGROUPS_MAX];
|
||||
int iGrps = 0;
|
||||
|
||||
/*
|
||||
* External variables
|
||||
*/
|
||||
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
|
||||
void make_utmp();
|
||||
void usage();
|
||||
|
||||
int
|
||||
Process()
|
||||
{
|
||||
register int c;
|
||||
int iErrs = 0;
|
||||
int i, iNewGrp;
|
||||
gid_t wGid;
|
||||
uid_t wUid;
|
||||
char *pcCmd = (char *)0,
|
||||
*pcDevTty = (char *)0;
|
||||
char *pcTmp;
|
||||
#ifdef IBMR2
|
||||
char *pcGrps;
|
||||
#endif /* IBMR2 */
|
||||
struct passwd *pwd;
|
||||
struct stat st;
|
||||
#if USE_IOCTL
|
||||
auto struct sgttyb n_sty;
|
||||
#if USE_TC
|
||||
auto struct tc n_tchars;
|
||||
#else
|
||||
auto struct tchars n_tchars;
|
||||
#endif
|
||||
#if HAVE_JOBS
|
||||
auto struct ltchars n_ltchars;
|
||||
#endif
|
||||
#else
|
||||
struct termios n_tio;
|
||||
#endif
|
||||
|
||||
|
||||
if ((char *)0 != pcCommand) {
|
||||
if ((char *)0 == (pcCmd = (char *)malloc(strlen(pcCommand) + 4))) {
|
||||
(void) fprintf(stderr, "%s: malloc: %s\n", progname, strerror(errno));
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
(void)strcpy(pcCmd, "-c ");
|
||||
(void)strcat(pcCmd, pcCommand);
|
||||
}
|
||||
|
||||
if ( (char *)0 != pcGroup ) {
|
||||
iErrs += addgroup(pcGroup);
|
||||
}
|
||||
|
||||
if ( (char *)0 == pcLogin ) {
|
||||
static char acLogin[17];
|
||||
if ((struct passwd *)0 == (pwd = getpwuid(geteuid()))) {
|
||||
(void) fprintf(stderr, "%s: %d: uid unknown\n", progname, geteuid());
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
pcLogin = strcpy(acLogin, pwd->pw_name);
|
||||
} else if ((struct passwd *)0 == (pwd = getpwnam(pcLogin))) {
|
||||
(void) fprintf(stderr, "%s: %s: login name unknown\n", progname, pcLogin);
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
wUid = pwd->pw_uid;
|
||||
wGid = pwd->pw_gid;
|
||||
#ifdef HAVE_GETUSERATTR
|
||||
/* getuserattr() returns a funny list of groups:
|
||||
* "grp1\0grp2\0grp3\0\0"
|
||||
*/
|
||||
if (0 == getuserattr(pcLogin, S_SUGROUPS, &pcGrps, SEC_LIST)) {
|
||||
while ('\000' != *pcGrps) {
|
||||
/* ignore "ALL" and any group beginning with '!' */
|
||||
if ('!' == *pcGrps || 0 != strcmp(pcGrps, "ALL")) {
|
||||
iErrs += addgroup(pcGrps);
|
||||
}
|
||||
pcGrps = pcGrps + strlen(pcGrps) + 1;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_GETUSERATTR */
|
||||
|
||||
if ((char *)0 != pcTty) {
|
||||
if ( '/' == *pcTty ) {
|
||||
pcDevTty = pcTty;
|
||||
} else {
|
||||
if ( (char *)0 == (pcDevTty = (char *)malloc(strlen(pcTty)+5+1) ) ) {
|
||||
(void) fprintf(stderr, "%s: malloc: %s\n", progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
sprintf(pcDevTty, "/dev/%s", pcTty);
|
||||
}
|
||||
|
||||
|
||||
if (0 != stat(pcDevTty, &st)) {
|
||||
(void) fprintf(stderr, "%s: Can't stat %s: %s\n", progname, pcDevTty, strerror(errno));
|
||||
++iErrs;
|
||||
#ifdef IBMR2
|
||||
} else if (VCHR != st.st_type && VMPC != st.st_type) {
|
||||
(void) fprintf(stderr, "%s: %s is not a character device\n", progname, pcDevTty);
|
||||
++iErrs;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
pcDevTty = (char *)0;
|
||||
}
|
||||
|
||||
if (iErrs) {
|
||||
usage();
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
if (0 != geteuid()) {
|
||||
(void) fprintf(stderr, "%s: Must be root!!!\n", progname);
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
if (iGrps && 0 < setgroups(iGrps, awGrps)) {
|
||||
(void) fprintf(stderr, "%s: Can't setgroups(): %s\n", progname, strerror(errno));
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* Close open files
|
||||
*/
|
||||
for (i = (char *)0 == pcTty ? 3 : 0; i < getdtablesize(); ++i) {
|
||||
(void) close(i);
|
||||
}
|
||||
|
||||
/* Make us a session leader so that when we open /dev/tty
|
||||
* it will become our controlling terminal.
|
||||
*/
|
||||
if (-1 == (iNewGrp = getsid(getpid()))) {
|
||||
if (-1 == (iNewGrp = setsid())) {
|
||||
(void) fprintf(stderr, "%s: setsid: %d: %s\n", progname, iNewGrp, strerror(errno));
|
||||
iNewGrp = getpid();
|
||||
}
|
||||
}
|
||||
|
||||
/* Open the TTY for stdin, stdout and stderr
|
||||
*/
|
||||
if ((char *)0 != pcDevTty) {
|
||||
#ifdef TIOCNOTTY
|
||||
if (-1 != (i = open("/dev/tty", 2, 0))) {
|
||||
if ( ioctl(i, TIOCNOTTY, (char *)0) )
|
||||
(void) fprintf(stderr, "%s: ioctl(%d, TIOCNOTTY, (char *)0): %s\n", progname, i, strerror(errno));
|
||||
(void) close(i);
|
||||
}
|
||||
#endif
|
||||
if (0 != open(pcDevTty, O_RDWR, 0666)) {
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
dup(0);
|
||||
dup(0);
|
||||
}
|
||||
|
||||
/* put the tty in out process group
|
||||
*/
|
||||
#if ! (EPIX || SUN5)
|
||||
#if USE_TC
|
||||
if (-1 >= (i = tcgetpgrp(0))){
|
||||
(void) fprintf(stderr, "%s: tcgetpgrp: %s\n", progname, strerror(errno));
|
||||
}
|
||||
#endif
|
||||
#if USE_SETPGRP
|
||||
if (-1 != i && setpgrp(0, i) ){
|
||||
(void) fprintf(stderr, "%s: setpgrp: %s, i = %d\n", progname, strerror(errno), i);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if USE_TC
|
||||
if (tcsetpgrp(0, iNewGrp)){
|
||||
(void) fprintf(stderr, "%s: tcsetpgrp: %s\n", progname, strerror(errno));
|
||||
}
|
||||
#endif
|
||||
#if USE_SETPGRP
|
||||
if (-1 != iNewGrp && setpgrp(0, iNewGrp)){
|
||||
(void) fprintf(stderr, "%s: setpgrp: %s, iNewGrp = %d\n", progname, strerror(errno), iNewGrp);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* put the tty in the correct mode
|
||||
*/
|
||||
#if USE_IOCTL
|
||||
if (0 != ioctl(0, TIOCGETP, (char *)&n_sty)) {
|
||||
fprintf(stderr, "%s: iotcl: getp: %s\n", progname, strerror(errno));
|
||||
exit(10);
|
||||
}
|
||||
#if USE_TC
|
||||
n_sty.sg_flags &= ~(O_CBREAK);
|
||||
n_sty.sg_flags |= (O_CRMOD|O_ECHO);
|
||||
#else
|
||||
n_sty.sg_flags &= ~(CBREAK);
|
||||
n_sty.sg_flags |= (CRMOD|ECHO);
|
||||
#endif
|
||||
n_sty.sg_kill = '\025'; /* ^U */
|
||||
n_sty.sg_erase = '\010'; /* ^H */
|
||||
if (0 != ioctl(0, TIOCSETP, (char *)&n_sty)) {
|
||||
fprintf(stderr, "%s: iotcl: setp: %s\n", progname, strerror(errno));
|
||||
exit(10);
|
||||
}
|
||||
|
||||
/* stty undef all tty chars
|
||||
*/
|
||||
#if 0
|
||||
if (-1 == ioctl(0, TIOCGETC, (char *)&n_tchars)) {
|
||||
fprintf(stderr, "%s: ioctl: getc: %s\n", progname, strerror(errno));
|
||||
return;
|
||||
}
|
||||
n_tchars.t_intrc = -1;
|
||||
n_tchars.t_quitc = -1;
|
||||
if (-1 == ioctl(0, TIOCSETC, (char *)&n_tchars)) {
|
||||
fprintf(stderr, "%s: ioctl: setc: %s\n", progname, strerror(errno));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#if HAVE_JOBS
|
||||
if (-1 == ioctl(0, TIOCGLTC, (char *)&n_ltchars)) {
|
||||
fprintf(stderr, "%s: ioctl: gltc: %s\n", progname, strerror(errno));
|
||||
return;
|
||||
}
|
||||
n_ltchars.t_suspc = -1;
|
||||
n_ltchars.t_dsuspc = -1;
|
||||
n_ltchars.t_flushc = -1;
|
||||
n_ltchars.t_lnextc = -1;
|
||||
if (-1 == ioctl(0, TIOCSLTC, (char *)&n_ltchars)) {
|
||||
fprintf(stderr, "%s: ioctl: sltc: %s\n", progname, strerror(errno));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#else /* not using ioctl, using POSIX or sun stuff */
|
||||
#if USE_TC
|
||||
if (0 != tcgetattr(0, &n_tio)) {
|
||||
(void) fprintf(stderr, "%s: tcgetattr: %s\n", progname, strerror(errno));
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
#else
|
||||
if (0 != ioctl(0, TCGETS, &n_tio)) {
|
||||
(void) fprintf(stderr, "%s: iotcl: TCGETS: %s\n", progname, strerror(errno));
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
#endif
|
||||
n_tio.c_iflag &= ~(IGNCR|IUCLC);
|
||||
n_tio.c_iflag |= ICRNL|IXON|IXANY;
|
||||
n_tio.c_oflag &= ~(OLCUC|ONOCR|ONLRET|OFILL|NLDLY|CRDLY|TABDLY|BSDLY);
|
||||
n_tio.c_oflag |= OPOST|ONLCR|TAB3;
|
||||
n_tio.c_lflag &= ~(XCASE|NOFLSH|ECHOK|ECHONL);
|
||||
n_tio.c_lflag |= ISIG|ICANON|ECHO;
|
||||
n_tio.c_cc[VEOF] = '\004'; /* ^D */
|
||||
n_tio.c_cc[VEOL] = '\000'; /* EOL */
|
||||
n_tio.c_cc[VERASE] = '\010'; /* ^H */
|
||||
n_tio.c_cc[VINTR] = '\003'; /* ^C */
|
||||
n_tio.c_cc[VKILL] = '\025'; /* ^U */
|
||||
/* MIN */
|
||||
n_tio.c_cc[VQUIT] = '\034'; /* ^\ */
|
||||
n_tio.c_cc[VSTART] = '\021'; /* ^Q */
|
||||
n_tio.c_cc[VSTOP] = '\023'; /* ^S */
|
||||
n_tio.c_cc[VSUSP] = '\032'; /* ^Z */
|
||||
#if USE_TC
|
||||
if (0 != tcsetattr(0, TCSANOW, &n_tio)) {
|
||||
(void) fprintf(stderr, "%s: tcsetattr: %s\n", progname, strerror(errno));
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
#else
|
||||
if (0 != ioctl(0, TCSETS, &n_tio)) {
|
||||
(void) fprintf(stderr, "%s: ioctl: TCSETS: %s\n", progname, strerror(errno));
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
#endif
|
||||
#endif /* setup tty */
|
||||
|
||||
if (fMakeUtmp) {
|
||||
extern char *ttyname();
|
||||
make_utmp(pcLogin, (char *)0 != pcTty ? pcTty : ttyname(0));
|
||||
}
|
||||
/* Change ownership and modes on the tty.
|
||||
*/
|
||||
if ((char *)0 != pcDevTty) {
|
||||
(void) chown(pcDevTty, wUid, wGid);
|
||||
(void) chmod(pcDevTty, (mode_t) TTYMODE);
|
||||
}
|
||||
|
||||
if ((char *)0 != pcCmd) {
|
||||
execl(PATH_SU, "su", "-", pcLogin, pcCmd, (char *)0);
|
||||
} else {
|
||||
execl(PATH_SU, "su", "-", pcLogin, (char *)0);
|
||||
}
|
||||
}
|
||||
|
||||
#if NEED_PUTENV
|
||||
int
|
||||
putenv(pcAssign)
|
||||
char *pcAssign;
|
||||
{
|
||||
register char *pcEq;
|
||||
|
||||
if ((char *)0 != (pcEq = strchr(pcAssign, '='))) {
|
||||
*pcEq++ = '\000';
|
||||
(void)setenv(pcAssign, pcEq, 1);
|
||||
*--pcEq = '=';
|
||||
} else {
|
||||
unsetenv(pcAssign);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
addgroup(pcGrp)
|
||||
char *pcGrp;
|
||||
{
|
||||
struct group *grp;
|
||||
|
||||
grp = getgrnam(pcGrp);
|
||||
if ((struct group *)0 == grp) {
|
||||
(void) fprintf(stderr, "%s: Unknown group: %s\n", progname, pcGrp);
|
||||
return(1);
|
||||
}
|
||||
if (iGrps >= NGROUPS_MAX) {
|
||||
(void) fprintf(stderr, "%s: Too many groups specified with \"%s\".\n", progname, pcGrp);
|
||||
return(1);
|
||||
}
|
||||
awGrps[iGrps++] = grp->gr_gid;
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* install a utmp entry to show the use we know is here is here (ksb)
|
||||
*/
|
||||
void
|
||||
make_utmp(pclogin, pctty)
|
||||
char *pclogin;
|
||||
char *pctty;
|
||||
{
|
||||
register int iFound, iPos;
|
||||
register int fdUtmp;
|
||||
register char *pcDev;
|
||||
register struct utmp *up;
|
||||
auto struct utmp outmp, utmp;
|
||||
|
||||
|
||||
if ((char *)0 == pctty) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((fdUtmp = open(UTMP_FILE, O_RDWR, 0664)) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* create empty utmp entry
|
||||
*/
|
||||
(void)memset(&utmp, 0, sizeof(struct utmp));
|
||||
|
||||
/* Only the last portion of the tty is saved, unless it's
|
||||
* all digits. Then back up and include the previous part
|
||||
* /dev/pty/02 -> pty/02 (not just 02)
|
||||
*/
|
||||
if ((char *)0 != (pcDev = strrchr(pctty, '/'))) {
|
||||
if (! *(pcDev + strspn(pcDev, "/0123456789"))) {
|
||||
while (pcDev != pctty && *--pcDev != '/') {
|
||||
}
|
||||
}
|
||||
if (*pcDev == '/') {
|
||||
++pcDev;
|
||||
}
|
||||
} else {
|
||||
pcDev = pctty;
|
||||
}
|
||||
|
||||
#if USE_OLD_UTENT
|
||||
/* look through /etc/utmp by hand (sigh)
|
||||
*/
|
||||
iFound = iPos = 0;
|
||||
while (sizeof(utmp) == read(fdUtmp, & utmp, sizeof(utmp))) {
|
||||
if (0 == strncmp(utmp.ut_line, pcDev, sizeof(utmp.ut_line))) {
|
||||
++iFound;
|
||||
break;
|
||||
}
|
||||
iPos++;
|
||||
}
|
||||
(void)strncpy(utmp.ut_name, pclogin, sizeof(utmp.ut_name));
|
||||
#else
|
||||
#if USE_UTENT
|
||||
/* look through getutent's by pid
|
||||
*/
|
||||
(void)setutent();
|
||||
utmp.ut_pid = getpid();
|
||||
iFound = iPos = 0;
|
||||
while ((up = getutent()) != NULL) {
|
||||
if (up->ut_pid == utmp.ut_pid) {
|
||||
utmp = *up;
|
||||
++iFound;
|
||||
break;
|
||||
}
|
||||
iPos++;
|
||||
}
|
||||
(void)endutent();
|
||||
/* we were an initprocess, now we are a login shell
|
||||
*/
|
||||
utmp.ut_type = USER_PROCESS;
|
||||
(void)strncpy(utmp.ut_user, pclogin, sizeof(utmp.ut_user));
|
||||
if ('\000' == utmp.ut_line[0]) {
|
||||
(void)strncpy(utmp.ut_line, pcDev, sizeof(utmp.ut_line));
|
||||
}
|
||||
#else
|
||||
{
|
||||
register struct ttyent *ty;
|
||||
|
||||
/* look through ttyslots by line?
|
||||
*/
|
||||
(void)setttyent();
|
||||
iFound = iPos = 0;
|
||||
while ((ty = getttyent()) != NULL) {
|
||||
if (strcmp(ty->ty_name, pcDev) == 0) {
|
||||
++iFound;
|
||||
break;
|
||||
}
|
||||
iPos++;
|
||||
}
|
||||
/* fill in utmp from ty ZZZ */
|
||||
(void)endttyent();
|
||||
}
|
||||
(void)strncpy(utmp.ut_line, pcDev, sizeof(utmp.ut_line));
|
||||
(void)strncpy(utmp.ut_name, pclogin, sizeof(utmp.ut_name));
|
||||
(void)strncpy(utmp.ut_host, "(autologin)", sizeof(utmp.ut_host));
|
||||
#endif
|
||||
#endif
|
||||
utmp.ut_time = time((time_t *) 0);
|
||||
|
||||
if (0 == iFound) {
|
||||
fprintf(stderr, "%s: %s: no ttyslot\n", progname, pctty);
|
||||
} else if (-1 == lseek(fdUtmp, (off_t)(iPos*sizeof(utmp)), 0)) {
|
||||
fprintf(stderr, "%s: lseek: %s\n", progname, strerror(errno));
|
||||
} else {
|
||||
(void)write(fdUtmp, (char *)&utmp, sizeof(utmp));
|
||||
}
|
||||
(void)close(fdUtmp);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
usage()
|
||||
{
|
||||
char *u_pch;
|
||||
int u_loop;
|
||||
|
||||
for (u_loop = 0; (char *)0 != (u_pch = au_terse[u_loop]); ++u_loop) {
|
||||
fprintf(stdout, "%s: usage%s\n", progname, u_pch);
|
||||
}
|
||||
for (u_loop = 0; (char *)0 != (u_pch = u_help[u_loop]); ++u_loop) {
|
||||
fprintf(stdout, "%s\n", u_pch);
|
||||
}
|
||||
|
||||
}
|
57
autologin/autologin.m
Normal file
57
autologin/autologin.m
Normal file
@ -0,0 +1,57 @@
|
||||
# mkcmd parser for autologin program
|
||||
%%
|
||||
static char *rcsid =
|
||||
"$Id: autologin.m,v 1.2 92/07/28 13:18:34 ksb Exp $";
|
||||
%%
|
||||
|
||||
integer variable "iErrs" {
|
||||
init "0"
|
||||
}
|
||||
|
||||
char* 'c' {
|
||||
named "pcCommand"
|
||||
param "cmd"
|
||||
init '(char *)0'
|
||||
help "command to run"
|
||||
}
|
||||
|
||||
function 'e' {
|
||||
named "putenv"
|
||||
param "env=value"
|
||||
update "if (%n(%N) != 0) { (void) fprintf(stderr, \"%%s: putenv(\\\"%%s\\\"): failed\\n\", %b, %N);exit(1);}"
|
||||
help "environment variable to set"
|
||||
}
|
||||
|
||||
char* 'g' {
|
||||
named "pcGroup"
|
||||
param "group"
|
||||
init '(char *)0'
|
||||
help "initial group"
|
||||
}
|
||||
|
||||
char* 'l' {
|
||||
named "pcLogin"
|
||||
param "login"
|
||||
init '(char *)0'
|
||||
help "login name"
|
||||
}
|
||||
|
||||
char* 't' {
|
||||
named "pcTty"
|
||||
param "tty"
|
||||
init '(char *)0'
|
||||
help "attach to this terminal"
|
||||
}
|
||||
|
||||
boolean 'u' {
|
||||
named "fMakeUtmp"
|
||||
init "1"
|
||||
update "%run = 0;"
|
||||
help "do no make utmp entry"
|
||||
}
|
||||
|
||||
exit {
|
||||
named "Process"
|
||||
update "%n();"
|
||||
aborts "exit(iErrs);"
|
||||
}
|
141
autologin/autologin.man
Normal file
141
autologin/autologin.man
Normal file
@ -0,0 +1,141 @@
|
||||
.\" $Id: autologin.man,v 1.3 93/03/16 16:41:45 ksb Exp $
|
||||
.TH AUTOLOGIN 8L PUCC
|
||||
.SH NAME
|
||||
autologin \- create an automatic login session from /etc/inittab
|
||||
.SH SYNOPSIS
|
||||
.B /usr/local/etc/autologin
|
||||
[
|
||||
.B \-u
|
||||
] [
|
||||
.B \-c
|
||||
.I command
|
||||
] [
|
||||
.B \-e
|
||||
.IB env = val
|
||||
] [
|
||||
.B \-g
|
||||
.I group
|
||||
] [
|
||||
.B \-l
|
||||
.I login
|
||||
] [
|
||||
.B \-t
|
||||
.I tty
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
.I Autologin
|
||||
creates a login session for
|
||||
.I login
|
||||
by running an
|
||||
.RB ` "su \-
|
||||
.IR login '
|
||||
on the specified device
|
||||
.RI ( tty ).
|
||||
If a
|
||||
.I command
|
||||
is given, that command is executed via
|
||||
.RB ` "su \-
|
||||
.IB login " \-c
|
||||
.IR command .'
|
||||
.PP
|
||||
.I Autologin
|
||||
also changes the ownership of the tty port to the user and sets the
|
||||
mode to 0600.
|
||||
.PP
|
||||
On AIX,
|
||||
.I autologin
|
||||
uses
|
||||
.IR getuserattr ( 3 )
|
||||
to determine which groups are required to su to
|
||||
.I login
|
||||
and sets those groups for the process before executing the
|
||||
.IR su ( 1 )
|
||||
command.
|
||||
.SH OPTIONS
|
||||
.TP \w'command'u+4
|
||||
.BI \-c command
|
||||
Execute the command
|
||||
.IR command .
|
||||
The default action is to create a login shell.
|
||||
.TP
|
||||
.BI \-e env = val
|
||||
Add the evironment variable assignment
|
||||
.IB env = val
|
||||
to the environment.
|
||||
.TP
|
||||
.BI \-g group
|
||||
Add
|
||||
.I group
|
||||
to current process group set before running
|
||||
.IR su ( 1 ).
|
||||
This option probably isn't necessary since the group set should be
|
||||
properly handled through the use of
|
||||
.IR getuserattr ( 3 ).
|
||||
.TP
|
||||
.BI \-l login
|
||||
Create the login process for the user
|
||||
.IR login .
|
||||
If none is given the effective uid is used.
|
||||
.TP
|
||||
.BI \-t tty
|
||||
.I tty
|
||||
is the name of the character-special file that corresponds to the terminal
|
||||
to be logged in.
|
||||
If none is given the current controlling terminal is used.
|
||||
.TP
|
||||
.B \-u
|
||||
Don't create a utmp entry. Normally, an entry is written to
|
||||
.I /etc/utmp
|
||||
to maintain a record of users logged into the system.
|
||||
.SH EXAMPLES
|
||||
Adding the following line to
|
||||
.I /etc/inittab
|
||||
on an AIX machine establishes a root login on the console terminal
|
||||
.RI ( /dev/tty0 )
|
||||
with any error messages directed to
|
||||
.IR /dev/console :
|
||||
.br
|
||||
.na
|
||||
cons2:2:respawn:/usr/local/etc/autologin \-t/dev/tty0 \-lroot > /dev/console 2>&1
|
||||
.ad
|
||||
.PP
|
||||
Adding the following line to
|
||||
.I /etc/inittab
|
||||
on an AIX machine causes ssinfo to be logged in on
|
||||
.I /dev/tty10
|
||||
with the
|
||||
.B TERM
|
||||
environment variable set to
|
||||
.IR reg20 :
|
||||
.br
|
||||
.na
|
||||
ss10:2:respawn:/usr/local/etc/autologin \-e TERM=reg20 \-t/dev/tty10 \-lssinfo
|
||||
.ad
|
||||
.PP
|
||||
Adding the following line to \fI/etc/ttytab\fP on a Sun 4.1.\fIx\fP
|
||||
machine establishes a root login on the console device:
|
||||
.na
|
||||
console "/usr/local/etc/autologin \-lroot \-t" xterm on local secure
|
||||
.ad
|
||||
Note that \fIinit\fP provides the \fItty\fP argument on the end of the command.
|
||||
.SH FILES
|
||||
/bin/su
|
||||
.br
|
||||
/etc/inittab
|
||||
.br
|
||||
/etc/passwd
|
||||
.br
|
||||
/etc/utmp
|
||||
.SH "SEE ALSO"
|
||||
su(1),
|
||||
getuserattr(3),
|
||||
inittab(5),
|
||||
init(8).
|
||||
.SH AUTHOR
|
||||
Jeff W\. Stewart \- Purdue University Computing Center
|
||||
.SH BUGS
|
||||
Doesn't add entries to /usr/adm/wtmp??
|
||||
.br
|
||||
Doesn't add utmp entry unless it's been setup by init(8).
|
||||
.br
|
||||
Only runs on SUN4, EPIX, SUN3, IBMR2 (currently).
|
354
autologin/main.c
Normal file
354
autologin/main.c
Normal file
@ -0,0 +1,354 @@
|
||||
/*
|
||||
* machine generated cmd line parser
|
||||
* built by mkcmd version 7.6 Gamma
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
extern int errno;
|
||||
extern char *malloc(), *calloc(), *realloc();
|
||||
|
||||
#define ENVOPT 0
|
||||
#define GETARG 0
|
||||
#define GETOPT 1
|
||||
/* from std_help.m */
|
||||
/* from std_version.m */
|
||||
/* from autologin.m */
|
||||
/* $Id: T.c,v 7.2 94/07/11 00:42:06 ksb Exp $
|
||||
* literal text included from a tempate
|
||||
* based on Keith Bostic's getopt in comp.sources.unix volume1
|
||||
* modified for mkcmd use.... by ksb@cc.purdue.edu (Kevin Braunsdorf)
|
||||
*/
|
||||
|
||||
#if GETOPT || GETARG
|
||||
/* IBMR2 (AIX in the real world) defines
|
||||
* optind and optarg in <stdlib.h> and confuses the hell out
|
||||
* of the C compiler. So we use those externs. I guess we will
|
||||
* have to stop using the old names. -- ksb
|
||||
*/
|
||||
#ifdef _AIX
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
static int
|
||||
optind = 1; /* index into parent argv vector */
|
||||
static char
|
||||
*optarg; /* argument associated with option */
|
||||
#endif
|
||||
#endif /* only if we use them */
|
||||
|
||||
#if ENVOPT
|
||||
/* breakargs - break a string into a string vector for execv.
|
||||
*
|
||||
* Note, when done with the vector, merely "free" the vector.
|
||||
* Written by Stephen Uitti, PUCC, Nov '85 for the new version
|
||||
* of "popen" - "nshpopen", that doesn't use a shell.
|
||||
* (used here for the as filters, a newer option).
|
||||
*
|
||||
* breakargs is copyright (C) Purdue University, 1985
|
||||
*
|
||||
* Permission is hereby given for its free reproduction and
|
||||
* modification for All purposes.
|
||||
* This notice and all embedded copyright notices be retained.
|
||||
*/
|
||||
|
||||
/* this trys to emulate shell quoting, but I doubt it does a good job (ksb)
|
||||
* [[ but not substitution -- that would be silly ]]
|
||||
*/
|
||||
static char *
|
||||
u_mynext(u_pcScan, u_pcDest)
|
||||
register char *u_pcScan, *u_pcDest;
|
||||
{
|
||||
register int u_fQuote;
|
||||
|
||||
for (u_fQuote = 0; *u_pcScan != '\000' && (u_fQuote||(*u_pcScan != ' ' && *u_pcScan != '\t')); ++u_pcScan) {
|
||||
switch (u_fQuote) {
|
||||
default:
|
||||
case 0:
|
||||
if ('"' == *u_pcScan) {
|
||||
u_fQuote = 1;
|
||||
continue;
|
||||
} else if ('\'' == *u_pcScan) {
|
||||
u_fQuote = 2;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if ('"' == *u_pcScan) {
|
||||
u_fQuote = 0;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if ('\'' == *u_pcScan) {
|
||||
u_fQuote = 0;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ((char*)0 != u_pcDest) {
|
||||
*u_pcDest++ = *u_pcScan;
|
||||
}
|
||||
}
|
||||
if ((char*)0 != u_pcDest) {
|
||||
*u_pcDest = '\000';
|
||||
}
|
||||
return u_pcScan;
|
||||
}
|
||||
|
||||
/* given an envirionment variable insert it in the option list (ksb)
|
||||
* (exploded with the above routine)
|
||||
*/
|
||||
static int
|
||||
u_envopt(cmd, pargc, pargv)
|
||||
char *cmd, *(**pargv);
|
||||
int *pargc;
|
||||
{
|
||||
register char *p; /* tmp */
|
||||
register char **v; /* vector of commands returned */
|
||||
register unsigned sum; /* bytes for malloc */
|
||||
register int i, j; /* number of args */
|
||||
register char *s; /* save old position */
|
||||
|
||||
while (*cmd == ' ' || *cmd == '\t')
|
||||
cmd++;
|
||||
p = cmd; /* no leading spaces */
|
||||
i = 1 + *pargc;
|
||||
sum = sizeof(char *) * i;
|
||||
while (*p != '\000') { /* space for argv[]; */
|
||||
++i;
|
||||
s = p;
|
||||
p = u_mynext(p, (char *)0);
|
||||
sum += sizeof(char *) + 1 + (unsigned)(p - s);
|
||||
while (*p == ' ' || *p == '\t')
|
||||
p++;
|
||||
}
|
||||
++i;
|
||||
/* vector starts at v, copy of string follows NULL pointer
|
||||
* the extra 7 bytes on the end allow use to be alligned
|
||||
*/
|
||||
v = (char **)malloc(sum+sizeof(char *)+7);
|
||||
if (v == NULL)
|
||||
return 0;
|
||||
p = (char *)v + i * sizeof(char *); /* after NULL pointer */
|
||||
i = 0; /* word count, vector index */
|
||||
v[i++] = (*pargv)[0];
|
||||
while (*cmd != '\000') {
|
||||
v[i++] = p;
|
||||
cmd = u_mynext(cmd, p);
|
||||
p += strlen(p)+1;
|
||||
while (*cmd == ' ' || *cmd == '\t')
|
||||
++cmd;
|
||||
}
|
||||
for (j = 1; j < *pargc; ++j)
|
||||
v[i++] = (*pargv)[j];
|
||||
v[i] = NULL;
|
||||
*pargv = v;
|
||||
*pargc = i;
|
||||
return i;
|
||||
}
|
||||
#endif /* u_envopt called */
|
||||
|
||||
#if GETARG
|
||||
/*
|
||||
* return each non-option argument one at a time, EOF for end of list
|
||||
*/
|
||||
static int
|
||||
u_getarg(nargc, nargv)
|
||||
int nargc;
|
||||
char **nargv;
|
||||
{
|
||||
if (nargc <= optind) {
|
||||
optarg = (char *) 0;
|
||||
return EOF;
|
||||
}
|
||||
optarg = nargv[optind++];
|
||||
return 0;
|
||||
}
|
||||
#endif /* u_getarg called */
|
||||
|
||||
|
||||
#if GETOPT
|
||||
static int
|
||||
optopt; /* character checked for validity */
|
||||
|
||||
/* get option letter from argument vector, also does -number correctly
|
||||
* for nice, xargs, and stuff (these extras by ksb)
|
||||
* does +arg if you give a last argument of "+", else give (char *)0
|
||||
*/
|
||||
static int
|
||||
u_getopt(nargc, nargv, ostr, estr)
|
||||
int nargc;
|
||||
char **nargv, *ostr, *estr;
|
||||
{
|
||||
register char *oli; /* option letter list index */
|
||||
static char EMSG[] = ""; /* just a null place */
|
||||
static char *place = EMSG; /* option letter processing */
|
||||
|
||||
if ('\000' == *place) { /* update scanning pointer */
|
||||
if (optind >= nargc)
|
||||
return EOF;
|
||||
if (nargv[optind][0] != '-') {
|
||||
register int iLen;
|
||||
if ((char *)0 != estr && 0 == strncmp(estr, nargv[optind], iLen = strlen(estr))) {
|
||||
optarg = nargv[optind++]+iLen;
|
||||
return '+';
|
||||
}
|
||||
return EOF;
|
||||
}
|
||||
place = nargv[optind];
|
||||
if ('\000' == *++place) /* "-" (stdin) */
|
||||
return EOF;
|
||||
if (*place == '-' && '\000' == place[1]) {
|
||||
/* found "--" */
|
||||
++optind;
|
||||
return EOF;
|
||||
}
|
||||
} /* option letter okay? */
|
||||
/* if we find the letter, (not a `:')
|
||||
* or a digit to match a # in the list
|
||||
*/
|
||||
if ((optopt = *place++) == ':' ||
|
||||
((char *)0 == (oli = strchr(ostr,optopt)) &&
|
||||
(!(isdigit(optopt)||'-'==optopt) || (char *)0 == (oli = strchr(ostr, '#'))))) {
|
||||
if(!*place) ++optind;
|
||||
return('?');
|
||||
}
|
||||
if ('#' == *oli) { /* accept as -digits */
|
||||
optarg = place -1;
|
||||
++optind;
|
||||
place = EMSG;
|
||||
return '#';
|
||||
}
|
||||
if (*++oli != ':') { /* don't need argument */
|
||||
optarg = NULL;
|
||||
if ('\000' == *place)
|
||||
++optind;
|
||||
} else { /* need an argument */
|
||||
if (*place) { /* no white space */
|
||||
optarg = place;
|
||||
} else if (nargc <= ++optind) { /* no arg!! */
|
||||
place = EMSG;
|
||||
return '*';
|
||||
} else {
|
||||
optarg = nargv[optind]; /* white space */
|
||||
}
|
||||
place = EMSG;
|
||||
++optind;
|
||||
}
|
||||
return optopt; /* dump back option letter */
|
||||
}
|
||||
#endif /* u_getopt called */
|
||||
#undef ENVOPT
|
||||
#undef GETARG
|
||||
#undef GETOPT
|
||||
|
||||
char
|
||||
*progname = "$Id$",
|
||||
*au_terse[] = {
|
||||
" [-u] [-c cmd] [-e env=value] [-g group] [-l login] [-t tty]",
|
||||
" -h",
|
||||
" -V",
|
||||
(char *)0
|
||||
},
|
||||
*u_help[] = {
|
||||
"c cmd command to run",
|
||||
"e env=value environment variable to set",
|
||||
"g group initial group",
|
||||
"h print this help message",
|
||||
"l login login name",
|
||||
"t tty attach to this terminal",
|
||||
"u do no make utmp entry",
|
||||
"V show version information",
|
||||
(char *)0
|
||||
},
|
||||
*pcCommand = (char *)0,
|
||||
*pcGroup = (char *)0,
|
||||
*pcLogin = (char *)0,
|
||||
*pcTty = (char *)0;
|
||||
int
|
||||
fMakeUtmp = 1,
|
||||
iErrs = 0;
|
||||
|
||||
#ifndef u_terse
|
||||
#define u_terse (au_terse[0])
|
||||
#endif
|
||||
/* from std_help.m */
|
||||
/* from std_version.m */
|
||||
/* from autologin.m */
|
||||
|
||||
static char *rcsid =
|
||||
"$Id: autologin.m,v 1.2 92/07/28 13:18:34 ksb Exp $";
|
||||
|
||||
/*
|
||||
* parser
|
||||
*/
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
static char
|
||||
sbOpt[] = "c:e:g:hl:t:uV",
|
||||
*u_pch = (char *)0;
|
||||
static int
|
||||
u_loop = 0;
|
||||
register int u_curopt;
|
||||
extern int atoi();
|
||||
|
||||
progname = strrchr(argv[0], '/');
|
||||
if ((char *)0 == progname)
|
||||
progname = argv[0];
|
||||
else
|
||||
++progname;
|
||||
while (EOF != (u_curopt = u_getopt(argc, argv, sbOpt, (char *)0))) {
|
||||
switch (u_curopt) {
|
||||
case '*':
|
||||
fprintf(stderr, "%s: option `-%c\' needs a parameter\n", progname, optopt);
|
||||
exit(1);
|
||||
case '?':
|
||||
fprintf(stderr, "%s: unknown option `-%c\', use `-h\' for help\n", progname, optopt);
|
||||
exit(1);
|
||||
case 'c':
|
||||
pcCommand = optarg;
|
||||
continue;
|
||||
case 'e':
|
||||
if (putenv(optarg) != 0) {
|
||||
(void) fprintf(stderr, "%s: putenv(\"%s\"): failed\n", progname, optarg);
|
||||
exit(1);
|
||||
}
|
||||
continue;
|
||||
case 'g':
|
||||
pcGroup = optarg;
|
||||
continue;
|
||||
case 'h':
|
||||
for (u_loop = 0; (char *)0 != (u_pch = au_terse[u_loop]); ++u_loop) {
|
||||
if ('\000' == *u_pch) {
|
||||
fprintf(stdout, "%s: with no parameters\n", progname);
|
||||
continue;
|
||||
}
|
||||
fprintf(stdout, "%s: usage%s\n", progname, u_pch);
|
||||
}
|
||||
for (u_loop = 0; (char *)0 != (u_pch = u_help[u_loop]); ++u_loop) {
|
||||
fprintf(stdout, "%s\n", u_pch);
|
||||
}
|
||||
exit(0);
|
||||
case 'l':
|
||||
pcLogin = optarg;
|
||||
continue;
|
||||
case 't':
|
||||
pcTty = optarg;
|
||||
continue;
|
||||
case 'u':
|
||||
fMakeUtmp = 0;
|
||||
continue;
|
||||
case 'V':
|
||||
printf("%s: %s\n", progname, rcsid);
|
||||
exit(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
Process();
|
||||
exit(iErrs);
|
||||
}
|
15
autologin/main.h
Normal file
15
autologin/main.h
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* parse options
|
||||
*/
|
||||
|
||||
extern char *progname, *au_terse[4], *u_help[9];
|
||||
#ifndef u_terse
|
||||
#define u_terse (au_terse[0])
|
||||
#endif
|
||||
extern int main();
|
||||
extern int fMakeUtmp, iErrs;
|
||||
extern char *pcCommand, *pcGroup, *pcLogin, *pcTty;
|
||||
/* from std_help.m */
|
||||
/* from std_version.m */
|
||||
/* from autologin.m */
|
||||
|
26
conserver.cf/INSTALL
Normal file
26
conserver.cf/INSTALL
Normal file
@ -0,0 +1,26 @@
|
||||
# $Id: INSTALL,v 4.1 91/06/19 14:20:54 ksb Exp $
|
||||
|
||||
Prep:
|
||||
|
||||
Start in the conserver directory.
|
||||
|
||||
Now read conserver.cf.5l (if you have mk(1L) installed just mk it).
|
||||
Run:
|
||||
$ tbl conserver.cf.5l |nroff -man |${PAGER-more}
|
||||
|
||||
Now edit dummy.cf and follow the instructions there.
|
||||
[If you are just shopping stop here.]
|
||||
|
||||
Now edit conserver.cf and put your real hosts in there.
|
||||
|
||||
Edit the Makefile and change LIB.
|
||||
|
||||
|
||||
Compile:
|
||||
|
||||
None.
|
||||
|
||||
|
||||
Install:
|
||||
|
||||
Make install.
|
59
conserver.cf/Makefile
Normal file
59
conserver.cf/Makefile
Normal file
@ -0,0 +1,59 @@
|
||||
# $Id: Make.host,v 4.3 92/07/10 15:57:32 dru Exp $
|
||||
#
|
||||
# Makefile for conserver data base
|
||||
#
|
||||
|
||||
# if you edit LIB below you have to change cons.hs default config define.
|
||||
PROG= conserver.cf
|
||||
LIB= ${DESTDIR}/usr/local/lib
|
||||
DOC= ${DESTDIR}/usr/man
|
||||
|
||||
SRCs= conserver.cf
|
||||
MAN= conserver.cf.5l
|
||||
OTHER= README
|
||||
SOURCE= Makefile ${OTHER} ${MAN} ${SRCl} ${SRCs}
|
||||
|
||||
all: ${SRCl} ${PROG}
|
||||
|
||||
${PROG}: ${SRCs}
|
||||
|
||||
clean: FRC
|
||||
rm -f Makefile.bak a.out core errs lint.out tags
|
||||
|
||||
deinstall: ${MAN} ${DOC} FRC
|
||||
install -R ${LIB}/${PROG}
|
||||
mkcat -r${DOC} -D ${MAN}
|
||||
|
||||
depend: FRC
|
||||
|
||||
dirs: ${LIB} ${DOC}
|
||||
|
||||
install: all dirs FRC
|
||||
install -c ${PROG} ${LIB}/${PROG}
|
||||
|
||||
lint: FRC
|
||||
|
||||
mkcat: ${MAN} ${DOC} FRC
|
||||
mkcat -r${DOC} ${MAN}
|
||||
|
||||
print: source FRC
|
||||
lpr -J"${PROG} source" ${SOURCE}
|
||||
|
||||
source: ${SOURCE}
|
||||
|
||||
spotless: clean
|
||||
rcsclean ${SOURCE}
|
||||
|
||||
tags: FRC
|
||||
|
||||
/ ${LIB} ${LIB}:
|
||||
install -dr $@
|
||||
|
||||
${SOURCE}:
|
||||
co -q $@
|
||||
|
||||
FRC:
|
||||
|
||||
# DO NOT DELETE THIS LINE - make depend DEPENDS ON IT
|
||||
|
||||
# *** Do not add anything here - It will go away. ***
|
16
conserver.cf/README
Normal file
16
conserver.cf/README
Normal file
@ -0,0 +1,16 @@
|
||||
# $Id: README,v 4.1 91/06/19 14:21:06 ksb Exp $
|
||||
|
||||
This configuration file has been extended from the Ohio State version. We
|
||||
allow parity and baud to be set, as well as more than one console server
|
||||
machine to be in play at a time. We have too many console servers to use
|
||||
just a single Sun3... :-).
|
||||
|
||||
|
||||
We also allow another section for trusted hosts. We allow our operators root
|
||||
access by physical access to a workstation.
|
||||
|
||||
|
||||
--
|
||||
"So I try to say `Goodbye, my friend.'
|
||||
I'd like to leave you with something more..."
|
||||
kayessbee, Kevin Braunsdorf, ksb@cc.purdue.edu, pur-ee!ksb, purdue!ksb
|
76
conserver.cf/conserver.cf
Normal file
76
conserver.cf/conserver.cf
Normal file
@ -0,0 +1,76 @@
|
||||
# conserver config file
|
||||
#
|
||||
# $Id: conserver.cf,v 4.20 94/05/22 11:17:26 ksb Exp $
|
||||
#
|
||||
# list of consoles we serve
|
||||
# name : tty[@host] : baud[parity] : device : group
|
||||
# our local console
|
||||
console:|@console.cc.purdue.edu:9600p:/usr/adm/consoles/console:0
|
||||
nextwatch:|@console.cc.purdue.edu:9600p:/usr/adm/consoles/nextwatch:0
|
||||
# real machine
|
||||
speedy:/dev/ttyC12@console.cc.purdue.edu:9600s:/usr/adm/consoles/speedy:1
|
||||
nis35:/dev/ttyC13@console.cc.purdue.edu:9600s:/usr/adm/consoles/nis35:1
|
||||
sun3watch:/dev/ttyC40@console.cc.purdue.edu:9600p:/usr/adm/consoles/sun3watch:1
|
||||
keep:/dev/ttyC29@console.cc.purdue.edu:9600s:/usr/adm/consoles/keep:1
|
||||
dart:/dev/ttyC32@console.cc.purdue.edu:9600s:/usr/adm/consoles/dart:1
|
||||
lively:/dev/ttyC10@console.cc.purdue.edu:9600s:/usr/adm/consoles/lively:2
|
||||
sentinel:/dev/ttyC11@console.cc.purdue.edu:9600s:/usr/adm/consoles/sentinel:2
|
||||
ipscgate:/dev/ttyC26@console.cc.purdue.edu:9600e:/usr/adm/consoles/ipscgate:2
|
||||
snap.stat:/dev/ttyC27@console.cc.purdue.edu:9600s:/usr/adm/consoles/snap.stat:2
|
||||
b.stat:/dev/ttyC33@console.cc.purdue.edu:9600s:/usr/adm/consoles/b.stat:2
|
||||
expert:/dev/ttyC14@console.cc.purdue.edu:9600e:/usr/adm/consoles/expert:3
|
||||
quick:/dev/ttyC15@console.cc.purdue.edu:9600s:/usr/adm/consoles/quick:3
|
||||
helios:/dev/ttyC31@console.cc.purdue.edu:9600s:/usr/adm/consoles/helios:3
|
||||
probe:/dev/ttyC34@console.cc.purdue.edu:9600s:/usr/adm/consoles/probe:3
|
||||
mace:/dev/ttyC8@console.cc.purdue.edu:4800s:/usr/adm/consoles/mace:4
|
||||
sage:/dev/ttyC9@console.cc.purdue.edu:9600e:/usr/adm/consoles/sage:4
|
||||
flash:/dev/ttyC24@console.cc.purdue.edu:9600s:/usr/adm/consoles/flash:4
|
||||
labwatch:/dev/ttyC25@console.cc.purdue.edu:9600s:/usr/adm/consoles/labwatch:4
|
||||
dash:/dev/ttyC35@console.cc.purdue.edu:9600s:/usr/adm/consoles/dash:4
|
||||
icd92:/dev/ttyC4@console.cc.purdue.edu:9600s:/usr/adm/consoles/icd92:5
|
||||
pop.stat:/dev/ttyC5@console.cc.purdue.edu:9600s:/usr/adm/consoles/pop.stat:5
|
||||
icd94:/dev/ttyC20@console.cc.purdue.edu:9600s:/usr/adm/consoles/icd94:5
|
||||
oasis:/dev/ttyC21@console.cc.purdue.edu:9600s:/usr/adm/consoles/oasis:5
|
||||
deft:/dev/ttyC36@console.cc.purdue.edu:9600s:/usr/adm/consoles/deft:5
|
||||
mentor:/dev/ttyC2@console.cc.purdue.edu:9600e:/usr/adm/consoles/mentor:6
|
||||
icd84:/dev/ttyC3@console.cc.purdue.edu:9600s:/usr/adm/consoles/icd84:6
|
||||
franklin:/dev/ttyC18@console.cc.purdue.edu:9600s:/usr/adm/consoles/franklin:6
|
||||
icd82:/dev/ttyC19@console.cc.purdue.edu:9600s:/usr/adm/consoles/icd82:6
|
||||
prism:/dev/ttyC38@console.cc.purdue.edu:9600s:/usr/adm/consoles/prism:6
|
||||
rapid:/dev/ttyC6@console.cc.purdue.edu:9600s:/usr/adm/consoles/rapid:7
|
||||
tyro:/dev/ttyC7@console.cc.purdue.edu:9600e:/usr/adm/consoles/tyro:7
|
||||
staff:/dev/ttyC22@console.cc.purdue.edu:9600s:/usr/adm/consoles/staff:7
|
||||
swift:/dev/ttyC23@console.cc.purdue.edu:9600s:/usr/adm/consoles/swift:7
|
||||
quest:/dev/ttyC37@console.cc.purdue.edu:9600s:/usr/adm/consoles/quest:7
|
||||
icd96:/dev/ttyC0@console.cc.purdue.edu:9600s:/usr/adm/consoles/icd96:8
|
||||
fleet:/dev/ttyC1@console.cc.purdue.edu:9600s:/usr/adm/consoles/fleet:8
|
||||
feserve:/dev/ttyC16@console.cc.purdue.edu:9600s:/usr/adm/consoles/feserve:8
|
||||
curator:/dev/ttyC17@console.cc.purdue.edu:9600s:/usr/adm/consoles/curator:8
|
||||
soltest:/dev/ttyC39@console.cc.purdue.edu:9600s:/usr/adm/consoles/soltest:8
|
||||
mozo:/dev/ttyC41@console.cc.purdue.edu:9600s:/usr/adm/consoles/mozo:9
|
||||
notus:/dev/ttyC42@console.cc.purdue.edu:9600s:/usr/adm/consoles/notus:
|
||||
eurus:/dev/ttyC43@console.cc.purdue.edu:9600s:/usr/adm/consoles/eurus:
|
||||
boreas:/dev/ttyC44@console.cc.purdue.edu:9600s:/usr/adm/consoles/boreas:
|
||||
zephyrus:/dev/ttyC45@console.cc.purdue.edu:9600s:/usr/adm/consoles/zephyrus:
|
||||
fegrader:/dev/ttyC46@console.cc.purdue.edu:9600s:/usr/adm/consoles/fegrader:
|
||||
galaxy:/dev/ttyC47@console.cc.purdue.edu:9600s:/usr/adm/consoles/galaxy:
|
||||
# ups monitor connection (ksb -- testing)
|
||||
ups:/dev/ttyb@console.cc.purdue.edu:9600e:/usr/adm/consoles/ups:10
|
||||
# VM Group consoles
|
||||
tag:/dev/ttyC30@console.cc.purdue.edu:9600s:/usr/adm/consoles/tag:11:R85ONdmDqSwQ6
|
||||
# All remote consoles
|
||||
# on staff.cc.purdue.edu
|
||||
extra:/dev/ttyb@staff.cc.purdue.edu:9600s:/usr/adm/extra.log:0
|
||||
vet:/dev/tty0d@staff.cc.purdue.edu:9600s:/usr/adm/vet.log:1:5m6N/RqJcay6I
|
||||
bull:/dev/tty0e@staff.cc.purdue.edu:9600s:/usr/adm/bull.log:
|
||||
serval:/dev/tty0f@staff.cc.purdue.edu:9600s:/usr/adm/serval.log:
|
||||
# virtual consoles on remote hosts
|
||||
tbtape:|su - informix@oasis.cc.purdue.edu:9600p:/usr/adm/tbtape.log:0
|
||||
# so we can write on mace.cc
|
||||
wmace:|/bin/csh -i@mace.cc.purdue.edu:9600p:/usr/adm/mace.log:0
|
||||
%%
|
||||
# list of clients we allow
|
||||
# type machines
|
||||
trusted: console.cc.purdue.edu
|
||||
allowed: cc.purdue.edu stat.purdue.edu
|
||||
allowed: 128.210.10.8 128.210.33.1 128.210.7.49 127.0.0.1
|
96
conserver.cf/conserver.cf.5l
Normal file
96
conserver.cf/conserver.cf.5l
Normal file
@ -0,0 +1,96 @@
|
||||
.\" $Id: conserver.cf.5l,v 1.4 93/02/11 13:06:32 ksb Exp $
|
||||
.\" @(#)constab.5 01/06/91 OSU CIS; Thomas A. Fine
|
||||
.TH CONSERVER.CF 5L "15 February 1991" "OSU/CIS"
|
||||
.SH NAME
|
||||
conserver.cf \- table of server console terminals used by conserver(8L)
|
||||
.SH SYNOPSIS
|
||||
.B /usr/local/lib/conserver.cf
|
||||
.br
|
||||
\fIaccess hosts\fP
|
||||
.br
|
||||
\fB%%\fP
|
||||
.br
|
||||
\fIserver\fP:\fIdevice\fP:\fIbaud\fP:\fIlogfile\fP:\fIgroup\fP
|
||||
.SH DESCRIPTION
|
||||
.B Conserver.cf
|
||||
is the configuration file for
|
||||
.IR conserver (8L).
|
||||
All lines starting with the pound sign `#' are considered comment lines.
|
||||
Blank lines are ignored.
|
||||
.PP
|
||||
The first section of the file has lines that are separated into
|
||||
six colon-separated fields:
|
||||
.PP
|
||||
\fIServer\fP name - this doesn't have to be the name of the server;
|
||||
it is used to refer to the server when using the console program.
|
||||
.PP
|
||||
\fIDevice\fP file name - the full path name of the device for this server.
|
||||
This may contain a remote host name as \fItty\fP@\fIhost\fP in which case
|
||||
the conserver will send connections for this server to \fIhost\fP.
|
||||
.PP
|
||||
\fIBaud\fP is the speed and parity for this console.
|
||||
Speed may be given as an integer,
|
||||
parity only requires the first letter of any of: even, odd, mark, space.
|
||||
.PP
|
||||
\fILog\fP file name - the full path name of file where all output from
|
||||
this server is logged.
|
||||
.PP
|
||||
\fIGroup\fP number - defines which group of servers this server is with. There
|
||||
will be one process running for each group of servers in this file.
|
||||
If this field is empty the conserver program will fill groups automatically.
|
||||
.PP
|
||||
\fIPassword\fP encrypted password - allows access to any member console in
|
||||
this group. That is to say only one console in any group should set a
|
||||
password. If none set a password the superuser password is taken.
|
||||
.PP
|
||||
This section is terminated with a `%%' token on a line by itself.
|
||||
.PP
|
||||
The next section of the file contains a list of hosts and addresses
|
||||
which are allowed to connect to the console server.
|
||||
Three levels of access all allowed, ``trust'', ``allow'',
|
||||
and ``refuse''.
|
||||
The access modifier is followed by a colon and a list of addresses or
|
||||
host names.
|
||||
Any complete suffix of a host name my be used to allow access for all hosts
|
||||
in that subdomain.
|
||||
For example `cc.purdue.edu' will allow `mentor.cc.purdue.edu'
|
||||
and `mace.cc.purdue.edu', but not `pucc.purdue.edu' or `hack.purdue.edu'.
|
||||
.SH LIMITS
|
||||
.PP
|
||||
Groups should be numbered from 0, all members of a group should be contiguous
|
||||
in the file.
|
||||
The current hard limits are 20 groups, with 10 members per group.
|
||||
.SH EXAMPLE
|
||||
# server:/dev/file:baud:/usr/adm/logfile:group_num
|
||||
.br
|
||||
tree:/dev/ttyj0:9600e:/tmp/treelog:0
|
||||
.br
|
||||
fish:/dev/ttyj1:4800e:/tmp/fishlog:1
|
||||
.br
|
||||
bird:/dev/ttyj2:4800m:/tmp/birdlog:1
|
||||
.br
|
||||
solar:/dev/ttyj3:9600e:/tmp/solarlog:2
|
||||
.br
|
||||
stellar:/dev/ttyj4:9600e:/tmp/stellarlog:
|
||||
.br
|
||||
shell:/dev/ttyj5:1200e:/tmp/shelllog:3:NLKyxm2KjHrzE
|
||||
.br
|
||||
tribe:/dev/ttyj6:1200e:/tmp/tribelog:4
|
||||
.br
|
||||
reptile:/dev/ttyj7:1200e:/tmp/reptilelog:
|
||||
.br
|
||||
flower:/dev/ttyj8:1200e:/tmp/flowerlog:
|
||||
.br
|
||||
mentor:/dev/ttyh0@extra.cc.purdue.edu:2400e:/tmp/mentor.log:
|
||||
%%
|
||||
.br
|
||||
# access restrictions
|
||||
.br
|
||||
trusted: console.cc.purdue.edu 128.210.7.90
|
||||
.br
|
||||
allow: cc.purdue.edu stat.cc.purdue.edu
|
||||
.sp
|
||||
Notice that the console `shell' has a special password, all the others
|
||||
use the superuser's password.
|
||||
.SH "SEE ALSO"
|
||||
console(1L), conserver(8L)
|
22
conserver.cf/dummy.cf
Normal file
22
conserver.cf/dummy.cf
Normal file
@ -0,0 +1,22 @@
|
||||
# dummy conserver config file
|
||||
#
|
||||
# $Id: dummy.cf,v 4.3 92/07/27 12:23:59 ksb Exp $
|
||||
#
|
||||
# 1. change the `/dev/ttya' to any tty device you can put a serial device on
|
||||
# that you could talk to with kermit/cu. Put in the baud rate and parity.
|
||||
#
|
||||
# 2. change the `cc.purdue.edu' to your local domain.
|
||||
#
|
||||
# 3. !! do not leave this up, as it can give local users a root shell (login)
|
||||
# !! for extended testing change the `|' to `|su - tst' where tst is a
|
||||
# !! vanilla test acount, or comment out the `login' console.
|
||||
#
|
||||
# list of consoles we serve
|
||||
# name : tty[@host] : baud[parity] : device : group
|
||||
dumb:/dev/ttya:9600p:/tmp/dummy.log:1
|
||||
login:|:9600p:/tmp/login.log:1
|
||||
%%
|
||||
# list of clients we allow
|
||||
# type machines
|
||||
trusted: 127.0.0.1
|
||||
allowed: cc.purdue.edu
|
188
conserver.cf/label.ps
Normal file
188
conserver.cf/label.ps
Normal file
@ -0,0 +1,188 @@
|
||||
%!PS-Adobe-2.0 EPSF-1.2
|
||||
%%$Id: label.ps,v 1.8 94/01/21 09:37:42 ksb Exp $
|
||||
%%Title: RJ-11
|
||||
%%Creator: A Braunsdorf
|
||||
%%CreationDate:
|
||||
%%For: ab
|
||||
%%BoundingBox: 0 0 243 148.5
|
||||
%%EndComments
|
||||
|
||||
% Add new hosts in the parens that match the port number
|
||||
/hosts
|
||||
[
|
||||
(icd96) % C0
|
||||
(fleet)
|
||||
(mentor)
|
||||
(icd84)
|
||||
|
||||
(icd92) % C4
|
||||
(pop.stat)
|
||||
(rapid)
|
||||
(tyro)
|
||||
|
||||
(mace) % C8
|
||||
(sage)
|
||||
(lively)
|
||||
(sentinel)
|
||||
|
||||
(speedy) % C12
|
||||
(nis35)
|
||||
(expert)
|
||||
(quick)
|
||||
|
||||
(feserve) % C16
|
||||
(curator)
|
||||
(franklin)
|
||||
(icd82)
|
||||
|
||||
(icd94) % C20
|
||||
(oasis)
|
||||
(staff)
|
||||
(swift)
|
||||
|
||||
(flash) % C24
|
||||
(labwatch)
|
||||
(ipscgate)
|
||||
(snap.stat)
|
||||
|
||||
(_28) % C28
|
||||
(keep)
|
||||
(tag)
|
||||
(assist)
|
||||
] def
|
||||
|
||||
% The relative co-ords of the various RJ11 jacks
|
||||
/coords
|
||||
[
|
||||
% j# x y jack number, +x, +y
|
||||
[ 13 0.5 1.25 ]
|
||||
[ 11 1.0 1.25 ]
|
||||
[ 8 1.5 1.25 ]
|
||||
[ 14 0.5 0.625 ]
|
||||
[ 10 1.0 0.625 ]
|
||||
[ 9 1.5 0.625 ]
|
||||
[ 15 0.5 0 ]
|
||||
[ 12 1.0 0 ]
|
||||
[ 7 2.1875 1.25 ]
|
||||
[ 5 2.6875 1.25 ]
|
||||
[ 3 3.1875 1.25 ]
|
||||
[ 6 2.1875 0.625 ]
|
||||
[ 4 2.6875 0.625 ]
|
||||
[ 0 3.1875 0.625 ]
|
||||
[ 2 2.6875 0 ]
|
||||
[ 1 3.1875 0 ]
|
||||
] def
|
||||
|
||||
/str 20 string def
|
||||
|
||||
% how to build an RJ11 connector diagram
|
||||
/rj11
|
||||
{
|
||||
gsave
|
||||
1 150 div setlinewidth
|
||||
0 0 moveto
|
||||
1 2 div 0 lineto
|
||||
0 1 2 div rlineto
|
||||
1 2 div neg 0 rlineto
|
||||
closepath
|
||||
stroke
|
||||
|
||||
1 16 div 1 8 div moveto
|
||||
|
||||
0 1 4 div rlineto
|
||||
1 16 div 0 rlineto
|
||||
0 1 16 div rlineto
|
||||
3 16 div 0 rlineto
|
||||
0 2 32 div neg rlineto
|
||||
1 16 div 0 rlineto
|
||||
0 1 16 div neg rlineto
|
||||
1 16 div 0 rlineto
|
||||
|
||||
0 2 16 div neg rlineto
|
||||
|
||||
1 16 div neg 0 rlineto
|
||||
0 1 16 div neg rlineto
|
||||
1 16 div neg 0 rlineto
|
||||
0 1 16 div neg rlineto
|
||||
3 16 div neg 0 rlineto
|
||||
0 1 16 div rlineto
|
||||
closepath
|
||||
stroke
|
||||
|
||||
0 1 7
|
||||
{
|
||||
36 div 9 64 div add 1 16 div exch moveto
|
||||
0 1 72 div rlineto
|
||||
1 72 div 0 rlineto
|
||||
0 1 72 div neg rlineto
|
||||
closepath
|
||||
fill
|
||||
} for
|
||||
grestore
|
||||
/Courier findfont 1.5 8 div scalefont setfont
|
||||
2 16 div 3 16 div moveto
|
||||
str cvs
|
||||
dup length 1 eq { ( )show } if show
|
||||
} def
|
||||
|
||||
|
||||
% Page layout stuff
|
||||
72 72 scale
|
||||
-90 rotate
|
||||
-11 0 translate
|
||||
/jack 28 def
|
||||
/fudge 1 32 div def
|
||||
/Courier findfont 10 72 div scalefont
|
||||
setfont
|
||||
0 setlinewidth
|
||||
|
||||
% label the lines on the left
|
||||
1 1 8
|
||||
{
|
||||
9 div 6 mul 0.25 exch moveto
|
||||
gsave fudge dup rmoveto jack str cvs show ( ) show hosts jack
|
||||
get show grestore
|
||||
/jack jack 1 add def
|
||||
gsave 15 16 div 0 rlineto stroke grestore
|
||||
1 0 rmoveto
|
||||
gsave fudge dup rmoveto jack str cvs show ( ) show hosts jack
|
||||
get show grestore
|
||||
/jack jack 1 add def
|
||||
gsave 15 16 div 0 rlineto stroke grestore
|
||||
1 0 rmoveto
|
||||
gsave fudge dup rmoveto jack str cvs show ( ) show hosts jack
|
||||
get show grestore
|
||||
/jack jack 1 add def
|
||||
gsave 15 16 div 0 rlineto stroke grestore
|
||||
1 0 rmoveto
|
||||
gsave fudge dup rmoveto jack str cvs show ( ) show hosts jack
|
||||
get show grestore
|
||||
/jack jack 1 add def
|
||||
gsave 15 16 div 0 rlineto stroke grestore
|
||||
1 0 rmoveto
|
||||
/jack jack 8 sub def
|
||||
} for
|
||||
|
||||
% Diddle the page and layout the RJ11s
|
||||
4.5 0.75 translate
|
||||
9 8 div dup scale
|
||||
0 1 coords length 1 sub
|
||||
{
|
||||
gsave
|
||||
coords exch get
|
||||
aload pop
|
||||
translate
|
||||
rj11
|
||||
grestore
|
||||
} for
|
||||
0 1 coords length 1 sub
|
||||
{
|
||||
gsave
|
||||
coords exch get
|
||||
aload pop
|
||||
2.5 add % for the second back up 2.5 inches
|
||||
translate
|
||||
16 add rj11 % ... add 16 to the RJ11 number
|
||||
grestore
|
||||
} for
|
||||
showpage
|
23
conserver.cf/test.cf
Normal file
23
conserver.cf/test.cf
Normal file
@ -0,0 +1,23 @@
|
||||
# dummy conserver config file
|
||||
#
|
||||
# $Id: dummy.cf,v 4.3 92/07/27 12:23:59 ksb Exp $
|
||||
#
|
||||
# 1. change the `/dev/ttya' to any tty device you can put a serial device on
|
||||
# that you could talk to with kermit/cu. Put in the baud rate and parity.
|
||||
#
|
||||
# 2. change the `cc.purdue.edu' to your local domain.
|
||||
#
|
||||
# 3. !! do not leave this up, as it can give local users a root shell (login)
|
||||
# !! for extended testing change the `|' to `|su - tst' where tst is a
|
||||
# !! vanilla test acount, or comment out the `login' console.
|
||||
#
|
||||
# list of consoles we serve
|
||||
# name : tty[@host] : baud[parity] : device : group
|
||||
DOMAINHACK=
|
||||
LOGDIR=/tmp
|
||||
login3:|:9600p:&:10m
|
||||
test:!ts4:10002:&:1m
|
||||
%%
|
||||
# list of clients we allow
|
||||
# type machines
|
||||
allowed: 127.0.0.1
|
114
conserver/INSTALL
Normal file
114
conserver/INSTALL
Normal file
@ -0,0 +1,114 @@
|
||||
# $Id: INSTALL,v 4.4 94/07/19 14:48:29 ksb Exp $
|
||||
#
|
||||
# lpr this file, you need to read it with other stuff on the screen.
|
||||
#
|
||||
|
||||
Basic installation:
|
||||
|
||||
First off, this stuff isn't guaranteed to work, or compile or anything.
|
||||
Second, the Makefile doesn't even really do that much, because most people
|
||||
with large networks don't have very normal configurations (that's a lot like
|
||||
an excuse :-). Third, I assume you have the hardware set up done, and don't
|
||||
need any help there (just use normal serial lines, or see Sun-serial).
|
||||
|
||||
With that out of the way, let's get started.
|
||||
|
||||
|
||||
Prep:
|
||||
|
||||
If you are a serious kinda guy you will want to add the console service to
|
||||
/etc/services, here is the line we use:
|
||||
console 782/tcp conserver # console server
|
||||
|
||||
Otherwise you'll have to hard code a PORT in cons.h (there are a comments
|
||||
at the apropos points.
|
||||
|
||||
If you do not have the PUCC ptyd daemon (and I'll bet you don't) you have
|
||||
to edit the Makefile, look at the block that sets HAVE_PTYD.
|
||||
|
||||
Later, on the console server you will have to add a line to /etc/rc.local,
|
||||
or an atboot/cronboot job to start the console server
|
||||
nice --4 /usr/local/etc/conserver >/dev/console 2>&1 </dev/null &
|
||||
|
||||
[we run it from roots .profile on an auto-login port.]
|
||||
|
||||
|
||||
Compiling:
|
||||
|
||||
Save a copy of cons.h and edit the one in this directory to your desires.
|
||||
It should be self-explanatory.
|
||||
|
||||
Edit Makefile, setting BIN and PROG.
|
||||
|
||||
Type "make". This compiles the server. If you fail on `XTABS' in
|
||||
group.c either change XTABS to TAB3 or #if 0 the block. I've not
|
||||
had time to track this down.
|
||||
|
||||
cd ../conserver.cf and follow the INSTALL there. (Then come back here.)
|
||||
|
||||
cd ../console and follow INSTALL there. (Then come back here.)
|
||||
|
||||
If you changed from using /usr/local/{bin,etc} you may want to change the
|
||||
"FILES" section in the man page "conserver.8L".
|
||||
|
||||
If everything went well, type "make install" in each directory. You will
|
||||
probably need to run this as root, depending on where you're putting stuff.
|
||||
|
||||
This only installs things on the local machine (unless you have a kinky
|
||||
system configuration). You will have to distribute at least the client
|
||||
program to your other machines. {Compile on unlike CPU types, of course.}
|
||||
|
||||
|
||||
How did we do?
|
||||
|
||||
Now run:
|
||||
conserver -V
|
||||
|
||||
You should get something like:
|
||||
conserver: $Id: INSTALL,v 4.4 94/07/19 14:48:29 ksb Exp $
|
||||
conserver: default access type `r'
|
||||
conserver: default escape sequence `\005\143'
|
||||
conserver: configuration in `/usr/local/lib/conserver.cf'
|
||||
conserver: limited to 20 groups with 10 members
|
||||
conserver: service name `conserver'
|
||||
|
||||
Testing the console server:
|
||||
|
||||
To test it (us the dummy config you build in ../conserver.cf) run
|
||||
# conserver -C ../conserve.cf/dummy.cf -v &
|
||||
|
||||
You should get an output that looks like:
|
||||
conserver: 1: dumb is on /dev/ttya (9600e) logged to /tmp/dummy.log
|
||||
conserver: group 1 on port 1270
|
||||
conserver: access type 't' for "127.0.0.1"
|
||||
conserver: access type 'a' for "cc.purdue.edu"
|
||||
|
||||
In another login window (or this one, I guess)
|
||||
$ console -vA dumb
|
||||
You should get an output like this:
|
||||
console: attach to dumb (on localhost)
|
||||
conserver: dumb: login root@nostromo.cc.purdue.edu
|
||||
Enter `^Ec?' for help.
|
||||
[ok, attached]
|
||||
[replay]
|
||||
|
||||
You can type to your device now, and it should answer you. Use
|
||||
^Ec? for help and ^Ec. to hangup on it.
|
||||
|
||||
|
||||
If that worked...
|
||||
|
||||
You can check over the real conserver.cf and start a real console server.
|
||||
You are set.
|
||||
|
||||
|
||||
Details/limits/bugs:
|
||||
|
||||
The log files grow without bound. Move the log files to OLD (with PUCC
|
||||
install) and HUP the conserver process to get him to re-open the log files.
|
||||
Here is the install cmd we use:
|
||||
install -cq /dev/null /usr/adm/his.console
|
||||
|
||||
You might wanna start stamper with the console server, but it doesn't
|
||||
re-open log files -- some later version of the console server will assume
|
||||
stampers job.
|
109
conserver/Makefile
Normal file
109
conserver/Makefile
Normal file
@ -0,0 +1,109 @@
|
||||
# $Id: Makefile,v 1.3 1998-11-17 23:45:05-08 bryan Exp $
|
||||
#
|
||||
# Makefile for console server
|
||||
#
|
||||
# two steps (1) and (2)
|
||||
|
||||
# (1) change ETC below to where you would like the console server installed
|
||||
# I would not change the name, you have to much with the docs then...
|
||||
PROG= conserver
|
||||
ETC= ${DESTDIR}/usr/local/etc
|
||||
DOC= ${DESTDIR}/usr/local/man
|
||||
|
||||
# if we have to PUCC ptyd daemon we can use it to get ptys, else use fallback.o
|
||||
# and change the CDEFS line below to =0
|
||||
FALLBACK=fallback.o
|
||||
PUCCLIB=
|
||||
#FALLBACK=
|
||||
#PUCCLIB=-lpucc
|
||||
|
||||
I=/usr/include
|
||||
S=/usr/include/sys
|
||||
L=/usr/local/include
|
||||
P=
|
||||
|
||||
INCLUDE=
|
||||
DEBUG=-O
|
||||
CDEFS= -DSUN5 -DHAVE_PTYD=0 -DDO_VIRTUAL=1
|
||||
CFLAGS= ${DEBUG} ${CDEFS} ${INCLUDE}
|
||||
|
||||
HDR= cons.h \
|
||||
access.h client.h consent.h group.h main.h master.h \
|
||||
readcfg.h
|
||||
SRC= access.c client.c consent.c group.c main.c master.c \
|
||||
readcfg.c fallback.c
|
||||
OBJ= access.o client.o consent.o group.o main.o master.o \
|
||||
readcfg.o ${FALLBACK}
|
||||
MAN= conserver.man
|
||||
OTHER= README Sun-serial
|
||||
SOURCE= Makefile ${OTHER} ${MAN} ${HDR} ${SRC}
|
||||
|
||||
all: ${PROG}
|
||||
|
||||
${PROG}:$P ${OBJ}
|
||||
${CC} -o $@ ${CFLAGS} ${OBJ} ${PUCCLIB} -lsocket -lnsl
|
||||
|
||||
clean: FRC
|
||||
rm -f Makefile.bak ${PROG} a.out *.o core errs lint.out tags
|
||||
|
||||
deinstall: ${MAN} ${DOC} FRC
|
||||
install -R ${ETC}/${PROG}
|
||||
mkcat -r${DOC} -D ${MAN}
|
||||
|
||||
depend: ${HDR} ${SRC} FRC
|
||||
maketd ${CDEFS} ${INCLUDE} ${SRC}
|
||||
|
||||
dirs: ${ETC} ${LIB}
|
||||
|
||||
distrib: FRC
|
||||
distrib -c ${ETC}/${PROG}
|
||||
|
||||
install: all dirs FRC
|
||||
install -c -s ${PROG} ${ETC}/${PROG}
|
||||
|
||||
lint: ${HDR} ${SRC} FRC
|
||||
lint -h ${CDEFS} ${INCLUDE} ${SRC}
|
||||
|
||||
mkcat: ${MAN} ${DOC} FRC
|
||||
mkcat -r${DOC} ${MAN}
|
||||
|
||||
print: source FRC
|
||||
lpr -J"${PROG} source" ${SOURCE}
|
||||
|
||||
source: ${SOURCE}
|
||||
|
||||
spotless: clean
|
||||
rcsclean ${SOURCE}
|
||||
|
||||
tags: ${HDR} ${SRC}
|
||||
ctags -t ${HDR} ${SRC}
|
||||
|
||||
/ ${ETC} ${LIB}:
|
||||
install -dr $@
|
||||
|
||||
${SOURCE}:
|
||||
co -q $@
|
||||
|
||||
FRC:
|
||||
|
||||
# DO NOT DELETE THIS LINE - maketd DEPENDS ON IT
|
||||
|
||||
access.o: access.c access.h client.h cons.h consent.h group.h main.h readcfg.h
|
||||
|
||||
client.o: client.c client.h cons.h consent.h
|
||||
|
||||
consent.o: client.h cons.h consent.c consent.h main.h
|
||||
|
||||
group.o: access.h client.h cons.h consent.h group.c group.h main.h version.h
|
||||
|
||||
main.o: access.h client.h cons.h consent.h group.h main.c master.h readcfg.h version.h
|
||||
|
||||
master.o: access.h client.h cons.h consent.h group.h main.h master.c master.h \
|
||||
readcfg.h version.h
|
||||
|
||||
readcfg.o: access.h client.h cons.h consent.h group.h main.h master.h \
|
||||
readcfg.c readcfg.h
|
||||
|
||||
fallback.o: fallback.c
|
||||
|
||||
# *** Do not add anything here - It will go away. ***
|
73
conserver/README
Normal file
73
conserver/README
Normal file
@ -0,0 +1,73 @@
|
||||
# $Id: README,v 4.1 91/06/19 15:23:03 ksb Exp $
|
||||
#
|
||||
|
||||
The general idea...
|
||||
|
||||
The idea is you have a big network. You have several machines whose consoles
|
||||
you want to access remotely. You connect the console lines of these machines
|
||||
to serial ports on another machine, which runs the server half of this
|
||||
software. Then you can use the client program to get at the consoles from
|
||||
anywhere in the network. It also provides log file of the consoles and
|
||||
an operator stream.
|
||||
|
||||
|
||||
Who will help me?
|
||||
|
||||
Send questions, comments, and bug reports to:
|
||||
ksb@cc.purdue.edu (Kevin S Braunsdorf)
|
||||
fine@cis.ohio-state.edu (Tom Fine)
|
||||
|
||||
Permissions needed to run this?
|
||||
|
||||
The console server does not need to be run as root. As long as it
|
||||
has permission to write to all the log files, any id will be fine.
|
||||
Keep in mind, though, that log files occasionally end up with
|
||||
sensitive data in them (like root passwords when people don't watch
|
||||
for the pasword prompt).
|
||||
|
||||
|
||||
Console server process management.
|
||||
|
||||
The conserver (usually) ends up running several process: one master and
|
||||
several children. Each of the children is responsible for some of the
|
||||
consoles. Occasionally, we've had problems with one of the children becoming
|
||||
"stuck" in one sense or another. To make dealing with this easier here
|
||||
is the plan:
|
||||
|
||||
1. If you need to restart everything, run
|
||||
console -q
|
||||
which will terminate the console server on all master hosts.
|
||||
|
||||
2. If you need to restart on one host, killing the master process (on
|
||||
that host) with a SIGTERM (the default for kill) will tell the master
|
||||
process to kill everything (including itself).
|
||||
|
||||
3. If any child dies, the master process will start another one to replace
|
||||
it. So if you have a process which is "stuck" it is easy to restart.
|
||||
{Send it a TERM and let conserver respawn it.}
|
||||
|
||||
4. If a console is spewing trash use the down (`d') command to make the
|
||||
server ignore it. Use the reopen (`o') command to restore it to
|
||||
working order.
|
||||
|
||||
5. If all else fails get a real tty on a cart and push it to the poor
|
||||
machine :-). [Keep one handy -- we don't claim this software is
|
||||
any better than any other *FREE* product.]
|
||||
|
||||
|
||||
Log file time stamping
|
||||
|
||||
We use a simple script like stamper.sh, which we start from rc.local, to
|
||||
time-stamp the files from all the machines that don't do this already.
|
||||
Using this script has the advantage over crontab entries that it doesn't
|
||||
interrupt what is happening on the console, if someone is using it.
|
||||
|
||||
Use
|
||||
stamper /usr/adm/target.console /usr/adm/other.console
|
||||
to add time stamps to the log file for the `target' and `other' machines.
|
||||
|
||||
[ This stamper script will go away someday soon. -- ksb]
|
||||
|
||||
--
|
||||
"When the head an heart of it finally alope!"
|
||||
kayessbee, Kevin Braunsdorf, ksb@cc.purdue.edu, pur-ee!ksb, purdue!ksb
|
44
conserver/Sun-serial
Normal file
44
conserver/Sun-serial
Normal file
@ -0,0 +1,44 @@
|
||||
# $Id: Sun-serial,v 2.1 93/02/09 11:45:12 ldv Exp $
|
||||
|
||||
If you are going to be hooking Sun consoles to your console server, you
|
||||
will run into a problem: The sun will halt whenever the cable is unplugged.
|
||||
It will also halt when the the console server is powered off and on. To
|
||||
prevent this we modified the wiring of our serial cables at the end that
|
||||
attaches to the suns.
|
||||
|
||||
The server can still be halted by generating a software line break, which
|
||||
is can be done by sending an escape sequence to the console server.
|
||||
|
||||
WE WILL NOT BE HELD RESPONSIBLE FOR ANY DAMAGES CAUSED BY ATTEMPTING A
|
||||
PARTIAL OR COMPLETE IMPLEMENTATION OF THIS MODIFICATION.
|
||||
"WE" refers to The Ohio State University and
|
||||
specifically, the employees of CIS Department of Ohio State.
|
||||
|
||||
This is a diagram of the cable we use.
|
||||
|
||||
Sun file Console
|
||||
Server Server
|
||||
Side Side
|
||||
|
||||
|
||||
2 Tx ------------------------- ------------------------- 2 Tx
|
||||
\/
|
||||
/\
|
||||
3 Rx ------+------------------ ------------------------- 3 Rx
|
||||
|
|
||||
Z 4.7K resistor
|
||||
|
|
||||
25 -5v ------+ 25 -5v
|
||||
|
||||
7 GND ---------------------------------------------------- 7 GND
|
||||
|
||||
4 RTS --+ 4 RTS
|
||||
|
|
||||
5 CTS --+ 5 CTS
|
||||
|
||||
6 DSR --+ 6 DSR
|
||||
|
|
||||
20 DTR --+ 20 DTR
|
||||
|
||||
I'm not a hardware person, but I think the important part is adding the
|
||||
resistor. The rest is icing, more or less.
|
8
conserver/TODO
Normal file
8
conserver/TODO
Normal file
@ -0,0 +1,8 @@
|
||||
# $Id: TODO,v 5.7 92/02/18 09:52:33 ksb Exp $
|
||||
|
||||
Just finish some #if's for TERMIO/TERMIOS/V7 ttys.
|
||||
|
||||
kayessbee
|
||||
--
|
||||
"This may be a new sense of the word `robust' for you."
|
||||
kayessbee, Kevin Braunsdorf, ksb@cc.purdue.edu, pur-ee!ksb, purdue!ksb
|
181
conserver/access.c
Normal file
181
conserver/access.c
Normal file
@ -0,0 +1,181 @@
|
||||
/*
|
||||
* $Id: access.c,v 5.9 1993-05-17 07:36:01-07 ksb Exp $
|
||||
*
|
||||
* Copyright 1992 Purdue Research Foundation, West Lafayette, Indiana
|
||||
* 47907. All rights reserved.
|
||||
*
|
||||
* Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
|
||||
*
|
||||
* This software is not subject to any license of the American Telephone
|
||||
* and Telegraph Company or the Regents of the University of California.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose on
|
||||
* any computer system, and to alter it and redistribute it freely, subject
|
||||
* to the following restrictions:
|
||||
*
|
||||
* 1. Neither the authors nor Purdue University are responsible for any
|
||||
* consequences of the use of this software.
|
||||
*
|
||||
* 2. The origin of this software must not be misrepresented, either by
|
||||
* explicit claim or by omission. Credit to the authors and Purdue
|
||||
* University must appear in documentation and sources.
|
||||
*
|
||||
* 3. Altered versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*/
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"@(#) Copyright 1992 Purdue Research Foundation.\nAll rights reserved.\n";
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include "cons.h"
|
||||
#include "access.h"
|
||||
#include "consent.h"
|
||||
#include "client.h"
|
||||
#include "group.h"
|
||||
#include "readcfg.h"
|
||||
#include "main.h"
|
||||
|
||||
#if USE_STRINGS
|
||||
#include <strings.h>
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* in the routines below (the init code) we can bomb if malloc fails (ksb)
|
||||
*/
|
||||
void
|
||||
OutOfMem()
|
||||
{
|
||||
static char acNoMem[] = ": out of memory\n";
|
||||
|
||||
write(2, progname, strlen(progname));
|
||||
write(2, acNoMem, sizeof(acNoMem)-1);
|
||||
exit(45);
|
||||
}
|
||||
|
||||
|
||||
/* return the access type for a given host entry (ksb)
|
||||
*/
|
||||
char
|
||||
AccType(hp)
|
||||
struct hostent *hp;
|
||||
{
|
||||
register int i;
|
||||
register unsigned char *puc;
|
||||
register char *pcName;
|
||||
auto char acAddr[4*3+2];
|
||||
register int len;
|
||||
|
||||
puc = (unsigned char *)hp->h_addr;
|
||||
sprintf(acAddr, "%d.%d.%d.%d", puc[0], puc[1], puc[2], puc[3]);
|
||||
for (i = 0; i < iAccess; ++i) {
|
||||
if (isdigit(pACList[i].pcwho[0])) {
|
||||
/* we could allow 128.210.7 to match all on that subnet
|
||||
* here...
|
||||
*/
|
||||
if (0 == strcmp(acAddr, pACList[i].pcwho)) {
|
||||
return pACList[i].ctrust;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
pcName = hp->h_name;
|
||||
len = strlen(pcName);
|
||||
while (len >= pACList[i].ilen) {
|
||||
if (0 == strcmp(pcName, pACList[i].pcwho)) {
|
||||
return pACList[i].ctrust;
|
||||
}
|
||||
pcName = strchr(pcName, '.');
|
||||
if ((char *)0 == pcName) {
|
||||
break;
|
||||
}
|
||||
++pcName;
|
||||
len = strlen(pcName);
|
||||
}
|
||||
}
|
||||
return chDefAcc;
|
||||
}
|
||||
|
||||
/* we know iAccess == 0, we want to setup a nice default access list (ksb)
|
||||
*/
|
||||
void
|
||||
SetDefAccess(hpLocal)
|
||||
struct hostent *hpLocal;
|
||||
{
|
||||
register char *pcWho, *pcDomain;
|
||||
register unsigned char *puc;
|
||||
register int iLen;
|
||||
|
||||
pACList = (ACCESS *)calloc(3, sizeof(ACCESS));
|
||||
if ((ACCESS *)0 == pACList) {
|
||||
OutOfMem();
|
||||
}
|
||||
if ((char *)0 == (pcWho = malloc(4*3+1))) {
|
||||
OutOfMem();
|
||||
}
|
||||
puc = (unsigned char *)hpLocal->h_addr;
|
||||
sprintf(pcWho, "%d.%d.%d.%d", puc[0], puc[1], puc[2], puc[3]);
|
||||
pACList[iAccess].ctrust = 'a';
|
||||
pACList[iAccess].ilen = strlen(pcWho);
|
||||
pACList[iAccess++].pcwho = pcWho;
|
||||
|
||||
if ((char *)0 == (pcDomain = strchr(hpLocal->h_name, '.'))) {
|
||||
return;
|
||||
}
|
||||
++pcDomain;
|
||||
iLen = strlen(pcDomain);
|
||||
pcWho = malloc(iLen+1);
|
||||
pACList[iAccess].ctrust = 'a';
|
||||
pACList[iAccess].ilen = iLen;
|
||||
pACList[iAccess++].pcwho = strcpy(pcWho, pcDomain);
|
||||
}
|
||||
|
||||
/* thread ther list of uniq console server machines, aliases for (ksb)
|
||||
* machines will screw us up
|
||||
*/
|
||||
REMOTE *
|
||||
FindUniq(pRCAll)
|
||||
register REMOTE *pRCAll;
|
||||
{
|
||||
register REMOTE *pRC;
|
||||
|
||||
/* INV: tail of the list we are building always contains only
|
||||
* uniq hosts, or the empty list.
|
||||
*/
|
||||
if ((REMOTE *)0 == pRCAll) {
|
||||
return (REMOTE *)0;
|
||||
}
|
||||
|
||||
pRCAll->pRCuniq = FindUniq(pRCAll->pRCnext);
|
||||
|
||||
/* if it is in the returned list of uniq hosts, return that list
|
||||
* else add us by returning our node
|
||||
*/
|
||||
for (pRC = pRCAll->pRCuniq; (REMOTE *)0 != pRC; pRC = pRC->pRCuniq) {
|
||||
if (0 == strcmp(pRC->rhost, pRCAll->rhost)) {
|
||||
return pRCAll->pRCuniq;
|
||||
}
|
||||
}
|
||||
return pRCAll;
|
||||
}
|
||||
|
48
conserver/access.h
Normal file
48
conserver/access.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* $Id: access.h,v 5.6 1993-02-09 03:53:43-08 ldv Exp $
|
||||
*
|
||||
* Copyright 1992 Purdue Research Foundation, West Lafayette, Indiana
|
||||
* 47907. All rights reserved.
|
||||
*
|
||||
* Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
|
||||
*
|
||||
* This software is not subject to any license of the American Telephone
|
||||
* and Telegraph Company or the Regents of the University of California.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose on
|
||||
* any computer system, and to alter it and redistribute it freely, subject
|
||||
* to the following restrictions:
|
||||
*
|
||||
* 1. Neither the authors nor Purdue University are responsible for any
|
||||
* consequences of the use of this software.
|
||||
*
|
||||
* 2. The origin of this software must not be misrepresented, either by
|
||||
* explicit claim or by omission. Credit to the authors and Purdue
|
||||
* University must appear in documentation and sources.
|
||||
*
|
||||
* 3. Altered versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*/
|
||||
/*
|
||||
* keep track of network access and peer console servers (ksb)
|
||||
*/
|
||||
|
||||
typedef struct access {
|
||||
char ctrust; /* how much do we trust the host */
|
||||
int ilen; /* length (strlen) of pcwho */
|
||||
char *pcwho; /* what is the hosts name/ip number */
|
||||
} ACCESS;
|
||||
|
||||
typedef struct remote { /* console at another host */
|
||||
struct remote *pRCnext; /* next remote console we know about */
|
||||
struct remote *pRCuniq; /* list of uniq remote servers */
|
||||
char rserver[32]; /* remote server name */
|
||||
char rhost[256]; /* remote host to call to get it */
|
||||
} REMOTE;
|
||||
|
||||
extern void OutOfMem();
|
||||
extern REMOTE *FindUniq();
|
||||
extern char AccType();
|
||||
extern void SetDefAccess();
|
297
conserver/client.c
Normal file
297
conserver/client.c
Normal file
@ -0,0 +1,297 @@
|
||||
/*
|
||||
* $Id: client.c,v 5.18 1998-11-19 14:32:20-08 bryan Exp $
|
||||
*
|
||||
* Copyright 1992 Purdue Research Foundation, West Lafayette, Indiana
|
||||
* 47907. All rights reserved.
|
||||
*
|
||||
* Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
|
||||
*
|
||||
* This software is not subject to any license of the American Telephone
|
||||
* and Telegraph Company or the Regents of the University of California.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose on
|
||||
* any computer system, and to alter it and redistribute it freely, subject
|
||||
* to the following restrictions:
|
||||
*
|
||||
* 1. Neither the authors nor Purdue University are responsible for any
|
||||
* consequences of the use of this software.
|
||||
*
|
||||
* 2. The origin of this software must not be misrepresented, either by
|
||||
* explicit claim or by omission. Credit to the authors and Purdue
|
||||
* University must appear in documentation and sources.
|
||||
*
|
||||
* 3. Altered versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*/
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"@(#) Copyright 1992 Purdue Research Foundation.\nAll rights reserved.\n";
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include "cons.h"
|
||||
#include "consent.h"
|
||||
#include "client.h"
|
||||
|
||||
#if USE_STRINGS
|
||||
#include <strings.h>
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
/* find the next guy who wants to write on the console (ksb)
|
||||
*/
|
||||
CLIENT *
|
||||
FindWrite(pCL)
|
||||
CLIENT *pCL;
|
||||
{
|
||||
/* return the first guy to have the `want write' bit set
|
||||
* (tell him of the promotion, too) we could look for the
|
||||
* most recent or some such... I guess it doesn't matter that
|
||||
* much.
|
||||
*/
|
||||
for (/*passed in*/; (CLIENT *)0 != pCL; pCL = pCL->pCLnext) {
|
||||
if (!pCL->fwantwr)
|
||||
continue;
|
||||
if (!pCL->pCEto->fup || pCL->pCEto->fronly)
|
||||
break;
|
||||
pCL->fwantwr = 0;
|
||||
pCL->fwr = 1;
|
||||
if ( pCL->pCEto->nolog ) {
|
||||
CSTROUT(pCL->fd, "\r\n[attached (nologging)]\r\n");
|
||||
} else {
|
||||
CSTROUT(pCL->fd, "\r\n[attached]\r\n");
|
||||
}
|
||||
return pCL;
|
||||
}
|
||||
return (CLIENT *)0;
|
||||
}
|
||||
|
||||
#if HAVE_IDENTD
|
||||
/* use identd to verify a user at a host (ksb)
|
||||
* we have a list of login@host:passwd:trust after the general host
|
||||
* limits. We call identd/tap/auth to get info and compare
|
||||
*/
|
||||
IdentifyMe(pCL)
|
||||
CLIENT *pCL;
|
||||
{
|
||||
/* ZZZ */
|
||||
/* we would have to getsockname(fdClient)
|
||||
* getpeername(fdClient)
|
||||
* identd_client(addr, addr, acBuffer
|
||||
* check for identifier in allowed list
|
||||
* return the permision (modify in pCL)
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
|
||||
/* show a character as a string so the user cannot mistake it for (ksb)
|
||||
* another
|
||||
*
|
||||
* must pass us at least 16 characters to put fill with text
|
||||
*/
|
||||
char *
|
||||
FmtCtl(ci, pcIn)
|
||||
int ci;
|
||||
char *pcIn;
|
||||
{
|
||||
register char *pcOut = pcIn;
|
||||
unsigned char c;
|
||||
|
||||
c = ci & 0xff;
|
||||
if (c > 127) {
|
||||
c -= 128;
|
||||
*pcOut++ = 'M';
|
||||
*pcOut++ = '-';
|
||||
}
|
||||
|
||||
if (c < ' ' || c == '\177') {
|
||||
*pcOut++ = '^';
|
||||
*pcOut++ = c ^ 0100;
|
||||
*pcOut = '\000';
|
||||
} else if (c == ' ') {
|
||||
(void)strcpy(pcOut, "<space>");
|
||||
} else if (c == '^') {
|
||||
(void)strcpy(pcOut, "<circumflex>");
|
||||
} else if (c == '\\') {
|
||||
(void)strcpy(pcOut, "<backslash>");
|
||||
} else {
|
||||
*pcOut++ = c;
|
||||
*pcOut = '\000';
|
||||
}
|
||||
return pcIn;
|
||||
}
|
||||
|
||||
/* replay last iBack lines of the log file upon connect to console (ksb)
|
||||
*
|
||||
* NB: we know the console might be spewing when the replay happens,
|
||||
* we want to just output what is in the log file and get out,
|
||||
* so we don't drop chars...
|
||||
*/
|
||||
void
|
||||
Replay(fdLog, fdOut, iBack)
|
||||
int fdLog, fdOut, iBack;
|
||||
{
|
||||
register int tot, nCr;
|
||||
register char *pc;
|
||||
register off_t where;
|
||||
auto char bf[MAXREPLAY+2];
|
||||
auto struct stat stLog;
|
||||
|
||||
if (-1 == fdLog) {
|
||||
CSTROUT(fdOut, "[no log file on this console]\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* find the size of the file
|
||||
*/
|
||||
if (0 != fstat(fdLog, & stLog)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (MAXREPLAY > stLog.st_size) {
|
||||
where = 0L;
|
||||
} else {
|
||||
where = stLog.st_size - MAXREPLAY;
|
||||
}
|
||||
|
||||
#if defined(SEEK_SET)
|
||||
/* PTX and maybe other Posix systems
|
||||
*/
|
||||
if (lseek(fdLog, where, SEEK_SET) < 0) {
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (lseek(fdLog, where, L_SET) < 0) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((tot = read(fdLog, bf, MAXREPLAY)) <= 0) {
|
||||
return;
|
||||
}
|
||||
bf[tot] = '@';
|
||||
|
||||
pc = & bf[tot];
|
||||
nCr = 0;
|
||||
while (--pc != bf) {
|
||||
if ('\n' == *pc && iBack == nCr++) {
|
||||
++pc; /* get rid of a blank line */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
(void)write(fdOut, pc, tot-(pc - bf));
|
||||
}
|
||||
|
||||
|
||||
/* these bit tell us which parts of the Truth to tell the client (ksb)
|
||||
*/
|
||||
#define WHEN_SPY 0x01
|
||||
#define WHEN_ATTACH 0x02
|
||||
#define WHEN_VT100 0x04
|
||||
#define WHEN_EXPERT 0x08 /* ZZZ no way to set his yet */
|
||||
#define WHEN_ALWAYS 0x40
|
||||
|
||||
#define HALFLINE 40
|
||||
typedef struct HLnode {
|
||||
int iwhen;
|
||||
char actext[HALFLINE];
|
||||
} HELP;
|
||||
|
||||
static HELP aHLTable[] = {
|
||||
{ WHEN_ALWAYS, ". disconnect"},
|
||||
{ WHEN_ALWAYS, "a attach read/write"},
|
||||
{ WHEN_ATTACH, "c toggle flow control"},
|
||||
{ WHEN_ATTACH, "d down a console"},
|
||||
{ WHEN_ALWAYS, "e change escape sequence"},
|
||||
{ WHEN_ALWAYS, "f force attach read/write"},
|
||||
{ WHEN_ALWAYS, "g group info"},
|
||||
{ WHEN_ATTACH, "L toggle logging on/off"},
|
||||
{ WHEN_ATTACH, "l1 send break (halt host!)"},
|
||||
{ WHEN_ALWAYS, "o (re)open the tty and log file"},
|
||||
{ WHEN_ALWAYS, "p replay the last 60 lines"},
|
||||
{ WHEN_ALWAYS, "r replay the last 20 lines"},
|
||||
{ WHEN_ATTACH, "s spy read only"},
|
||||
{ WHEN_ALWAYS, "u show host status"},
|
||||
{ WHEN_ALWAYS, "v show version info"},
|
||||
{ WHEN_ALWAYS, "w who is on this console"},
|
||||
{ WHEN_ALWAYS, "x show console baud info"},
|
||||
{ WHEN_ALWAYS, "z suspend the connection"},
|
||||
{ WHEN_ALWAYS, "<cr> ignore/abort command"},
|
||||
{ WHEN_ALWAYS, "? print this message"},
|
||||
{ WHEN_ALWAYS, "^R short replay"},
|
||||
{ WHEN_ATTACH, "\\ooo send character by octal code"},
|
||||
{ WHEN_EXPERT, "^I toggle tab expansion"},
|
||||
{ WHEN_EXPERT, "; change to another console"},
|
||||
{ WHEN_EXPERT, "+(-) do (not) drop line"},
|
||||
{ WHEN_VT100, "PF1 print this message"},
|
||||
{ WHEN_VT100, "PF2 disconnect"},
|
||||
{ WHEN_VT100, "PF3 replay the last 20 lines"},
|
||||
{ WHEN_VT100, "PF4 spy read only"}
|
||||
};
|
||||
|
||||
/* list the commands we know for the user (ksb)
|
||||
*/
|
||||
void
|
||||
HelpUser(pCL)
|
||||
CLIENT *pCL;
|
||||
{
|
||||
register int i, j, iCmp;
|
||||
static char
|
||||
acH1[] = "help]\r\n",
|
||||
acH2[] = "help spy mode]\r\n",
|
||||
acEoln[] = "\r\n";
|
||||
auto char acLine[HALFLINE*2+3];
|
||||
|
||||
iCmp = WHEN_ALWAYS|WHEN_SPY;
|
||||
if (pCL->fwr) {
|
||||
(void)write(pCL->fd, acH1, sizeof(acH1)-1);
|
||||
iCmp |= WHEN_ATTACH;
|
||||
} else {
|
||||
(void)write(pCL->fd, acH2, sizeof(acH2)-1);
|
||||
}
|
||||
if ('\033' == pCL->ic[0] && 'O' == pCL->ic[1]) {
|
||||
iCmp |= WHEN_VT100;
|
||||
}
|
||||
|
||||
acLine[0] = '\000';
|
||||
for (i = 0; i < sizeof(aHLTable)/sizeof(HELP); ++i) {
|
||||
if (0 == (aHLTable[i].iwhen & iCmp)) {
|
||||
continue;
|
||||
}
|
||||
if ('\000' == acLine[0]) {
|
||||
acLine[0] = ' ';
|
||||
(void)strcpy(acLine+1, aHLTable[i].actext);
|
||||
continue;
|
||||
}
|
||||
for (j = strlen(acLine); j < HALFLINE+1; ++j) {
|
||||
acLine[j] = ' ';
|
||||
}
|
||||
(void)strcpy(acLine+j, aHLTable[i].actext);
|
||||
(void)strcat(acLine+j, acEoln);
|
||||
(void)write(pCL->fd, acLine, strlen(acLine));
|
||||
acLine[0] = '\000';
|
||||
}
|
||||
if ('\000' != acLine[0]) {
|
||||
(void)strcat(acLine, acEoln);
|
||||
(void)write(pCL->fd, acLine, strlen(acLine));
|
||||
}
|
||||
}
|
72
conserver/client.h
Normal file
72
conserver/client.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* $Id: client.h,v 5.10 1998-11-18 00:17:12-08 bryan Exp $
|
||||
*
|
||||
* Copyright 1992 Purdue Research Foundation, West Lafayette, Indiana
|
||||
* 47907. All rights reserved.
|
||||
*
|
||||
* Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
|
||||
*
|
||||
* This software is not subject to any license of the American Telephone
|
||||
* and Telegraph Company or the Regents of the University of California.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose on
|
||||
* any computer system, and to alter it and redistribute it freely, subject
|
||||
* to the following restrictions:
|
||||
*
|
||||
* 1. Neither the authors nor Purdue University are responsible for any
|
||||
* consequences of the use of this software.
|
||||
*
|
||||
* 2. The origin of this software must not be misrepresented, either by
|
||||
* explicit claim or by omission. Credit to the authors and Purdue
|
||||
* University must appear in documentation and sources.
|
||||
*
|
||||
* 3. Altered versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*/
|
||||
/* states for a server fsm
|
||||
*/
|
||||
#define S_NORMAL 0 /* just pass character */
|
||||
#define S_ESC1 1 /* first escape character received */
|
||||
#define S_CMD 2 /* second interrupt character received */
|
||||
#define S_CATTN 3 /* change 1 escape character to next input char */
|
||||
#define S_CESC 4 /* change 2 escape character to next input char */
|
||||
#define S_HALT1 5 /* we have a halt sequence in progress */
|
||||
#define S_SUSP 6 /* we are suspened, first char wakes us up */
|
||||
#define S_IDENT 7 /* probational connection (who is this) */
|
||||
#define S_HOST 8 /* still needs a host name to connect */
|
||||
#define S_PASSWD 9 /* still needs a passwd to connect */
|
||||
#define S_QUOTE 10 /* send any character we can spell */
|
||||
|
||||
typedef struct client { /* Connection Information: */
|
||||
int fd; /* file descriptor */
|
||||
short fcon; /* currently connect or not */
|
||||
short fwr; /* (client) write enable flag */
|
||||
short fwantwr; /* (client) wants to write */
|
||||
short fecho; /* echo commands (not set by machines) */
|
||||
char acid[128]; /* login and location of client */
|
||||
long tym; /* time of connect */
|
||||
long typetym; /* time of last keystroke */
|
||||
char actym[32]; /* pre-formatted time */
|
||||
struct consent
|
||||
*pCEwant, /* what machine we would like to be on */
|
||||
*pCEto; /* host a client gets output from */
|
||||
struct client
|
||||
**ppCLbscan, /* back link for scan ptr */
|
||||
*pCLscan, /* next client fd to scan after select */
|
||||
**ppCLbnext, /* back link for next ptr */
|
||||
*pCLnext; /* next person on this list */
|
||||
char ic[2]; /* two character escape sequence */
|
||||
char iState; /* state for fsm in server */
|
||||
char caccess; /* did we trust the remote machine */
|
||||
char accmd[MAXSERVLEN+1];/* the command the user issued */
|
||||
int icursor; /* the length of the command issused */
|
||||
struct sockaddr_in
|
||||
cnct_port; /* where from */
|
||||
} CLIENT;
|
||||
|
||||
extern char *FmtCtl();
|
||||
extern void Replay();
|
||||
extern void HelpUser();
|
||||
extern CLIENT *FindWrite();
|
350
conserver/cons-gnac.h
Normal file
350
conserver/cons-gnac.h
Normal file
@ -0,0 +1,350 @@
|
||||
/*
|
||||
* $Id: cons-gnac.h,v 5.38 1998-11-17 18:43:39-08 bryan Exp $
|
||||
*
|
||||
* Copyright 1992 Purdue Research Foundation, West Lafayette, Indiana
|
||||
* 47907. All rights reserved.
|
||||
*
|
||||
* Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
|
||||
*
|
||||
* This software is not subject to any license of the American Telephone
|
||||
* and Telegraph Company or the Regents of the University of California.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose on
|
||||
* any computer system, and to alter it and redistribute it freely, subject
|
||||
* to the following restrictions:
|
||||
*
|
||||
* 1. Neither the authors nor Purdue University are responsible for any
|
||||
* consequences of the use of this software.
|
||||
*
|
||||
* 2. The origin of this software must not be misrepresented, either by
|
||||
* explicit claim or by omission. Credit to the authors and Purdue
|
||||
* University must appear in documentation and sources.
|
||||
*
|
||||
* 3. Altered versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*/
|
||||
|
||||
/*
|
||||
* this is the configuration file for the Ohio State/PUCC console
|
||||
* server. Just define the macros below to somehting that looks good
|
||||
* and give it a go. It'll complain (under conserver -V) if things
|
||||
* look really bad.
|
||||
*
|
||||
* all PTX, PTX2, and PTX4 code added by gregf@sequent.com (gregf)
|
||||
*/
|
||||
/* #define IBMR2 1 /**/
|
||||
/* #define HPUX7 1 /**/
|
||||
/* #define SUN4 1 /**/
|
||||
/* #define SUN5 1 /**/
|
||||
/* #define PTX2 1 /* DYNIX/ptx v2.X */
|
||||
/* #define PTX4 1 /* DYNIX/ptx v4.0 */
|
||||
|
||||
#if (defined(PTX2) || defined(PTX4))
|
||||
#define PTX
|
||||
#endif
|
||||
|
||||
/* some machine specific details
|
||||
*/
|
||||
#if !defined(USE_OLDSEL)
|
||||
#if defined(IBMR2)
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(HAVE_UWAIT)
|
||||
#define HAVE_UWAIT !(defined(IBMR2)||defined(SUN5)||defined(HPUX8)||defined(HPUX9)||defined(PTX)||defined(IRIX5))
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_WAIT3)
|
||||
#define HAVE_WAIT3 !(defined(SUN5)||defined(PTX))
|
||||
#endif
|
||||
|
||||
/* This is the port number used in the connection. It can use either
|
||||
* /etc/services or a hardcoded port (SERVICE name has precedence).
|
||||
* (You can -D one in the Makefile to override these.)
|
||||
*/
|
||||
/* #define PORT 782 /* only if you cannot put in /etc/services */
|
||||
#if !defined(SERVICE)
|
||||
#if !defined(PORT)
|
||||
#define SERVICE "conserver"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Wait for a part of a second before slapping console server.
|
||||
* Good for CISCO terminal servers that get upset when you
|
||||
* attack with intense socket connections
|
||||
*/
|
||||
#if !defined(USLEEP_FOR_SLOW_PORTS)
|
||||
#define USLEEP_FOR_SLOW_PORTS 100000
|
||||
#endif
|
||||
|
||||
/* The name of the host which will act as the console server
|
||||
*/
|
||||
#if !defined(HOST)
|
||||
#define HOST "console"
|
||||
#endif
|
||||
|
||||
/* the default escape sequence used to give meta commands
|
||||
*/
|
||||
#define DEFATTN '\005'
|
||||
#define DEFESC 'c'
|
||||
|
||||
/* Location of the configuration file
|
||||
*/
|
||||
#if !defined(CONFIG)
|
||||
#define CONFIG "/etc/conserver.cf"
|
||||
#endif
|
||||
|
||||
/* Location of ANL designed passwd file */
|
||||
#if !defined(PASSWD_FILE)
|
||||
#define PASSWD_FILE "/etc/conserver.passwd"
|
||||
#endif
|
||||
|
||||
/* The maximum number of serial lines that can be handled by a child process
|
||||
*/
|
||||
#if !defined(MAXMEMB)
|
||||
#define MAXMEMB 8
|
||||
#endif
|
||||
|
||||
|
||||
/* The maximum number of child processes spawned.
|
||||
*/
|
||||
#if !defined(MAXGRP)
|
||||
#define MAXGRP 32
|
||||
#endif
|
||||
|
||||
/* the max number of characters conserver will replay for you (the r command)
|
||||
*/
|
||||
#if !defined(MAXREPLAY)
|
||||
#define MAXREPLAY (80*25)
|
||||
#endif
|
||||
|
||||
/* if the encrypted passwd is in a shadow file, define HAVE_SHADOW (gregf)
|
||||
*/
|
||||
#if !defined(HAVE_SHADOW)
|
||||
#define HAVE_SHADOW (defined(PTX)||defined(SUN5))
|
||||
#endif
|
||||
|
||||
/* we'd like to line buffer our output, if we know how
|
||||
*/
|
||||
#if !defined(USE_SETLINEBUF)
|
||||
#define USE_SETLINEBUF (!(defined(HPUX7)||defined(HPUX8)||defined(HPUX9)||defined(PTX)))
|
||||
#endif
|
||||
|
||||
/* we'd like to line buffer our output, if we know how; PTX uses setvbuf (gregf)
|
||||
*/
|
||||
#if !defined(USE_SETVBUF)
|
||||
#define USE_SETVBUF (defined(PTX))
|
||||
#endif
|
||||
|
||||
/* hpux doesn't have getdtablesize() and they don't provide a macro
|
||||
* in non-KERNEL cpp mode
|
||||
*/
|
||||
#if defined(HPUX7)||defined(HPUX8)||defined(HPUX9)
|
||||
#define getdtablesize() 64
|
||||
#endif
|
||||
|
||||
/* the console server will provide a pseudo-device console which
|
||||
* allows operators to run backups and such without a hard wired
|
||||
* line (this is also good for testing the server to see if you
|
||||
* might wanna use it). Turn this on only if you (might) need it.
|
||||
*/
|
||||
#if !defined(DO_VIRTUAL)
|
||||
#define DO_VIRTUAL 1
|
||||
#endif
|
||||
|
||||
#if DO_VIRTUAL
|
||||
/* if the virtual console option is on we need a source to ptys,
|
||||
* the PUCC ptyd daemon is the best source be know, else fall back
|
||||
* on some emulation code?? (XXX)
|
||||
*/
|
||||
#if !defined(HAVE_PTYD)
|
||||
#define HAVE_PTYD (defined(S81)||defined(VAX8800))
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_GETPSEUDO)
|
||||
#define HAVE_GETPSEUDO (defined(PTX2))
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_PTSNAME)
|
||||
#define HAVE_PTSNAME (defined(PTX4))
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_LDTERM)
|
||||
#define HAVE_LDTERM (defined(SUN5))
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_STTY_LD)
|
||||
#define HAVE_STTY_LD (defined(IRIX5))
|
||||
#endif
|
||||
|
||||
#endif /* virtual (process on a pseudo-tty) console support */
|
||||
|
||||
#if !defined(HAVE_SETSID)
|
||||
#define HAVE_SETSID (defined(IBMR2)||defined(SUN5)||defined(HPUX7)||defined(HPUX8)||defined(HPUX9)||defined(PTX)||defined(IRIX5))
|
||||
#endif
|
||||
|
||||
/* should we use flock to keep multiple conservers from hurting each other?
|
||||
* PTX has lockf... should probably port code to work with this (gregf)
|
||||
*/
|
||||
#if !defined(USE_FLOCK)
|
||||
#define USE_FLOCK (!(defined(IBMR2)||defined(SUN5)||defined(HPUX7)||defined(HPUX8)||defined(HPUX9)||defined(PTX)))
|
||||
#endif
|
||||
|
||||
/* should we try to pop streams modules off?
|
||||
*/
|
||||
#if !defined(USE_STREAMS)
|
||||
#define USE_STREAMS (defined(SUN4)||defined(SUN5)||defined(PTX)||defined(IRIX5))
|
||||
#endif
|
||||
|
||||
/* if we do not have old style tty emulation use termios.h
|
||||
*/
|
||||
#if !defined(USE_TERMIO)
|
||||
#define USE_TERMIO (defined(ETA10)||defined(V386))
|
||||
#endif
|
||||
#if !defined(USE_TERMIOS)
|
||||
#define USE_TERMIOS (defined(HPUX7)||defined(HPUX8)||defined(HPUX9)||defined(SUN5)||defined(PTX)||defined(IRIX5))
|
||||
#endif
|
||||
#if !defined(USE_TCBREAK)
|
||||
#define USE_TCBREAK (defined(SUN4)||defined(PTX))
|
||||
#endif
|
||||
|
||||
/* if we have <strings.h> define this to 1, else define to 0
|
||||
*/
|
||||
#if !defined(USE_STRINGS)
|
||||
#define USE_STRINGS (defined(SUN4)||defined(DYNIX)||defined(EPIX)||defined(IRIX5))
|
||||
#endif
|
||||
|
||||
#if !defined(NEED_UNISTD_H)
|
||||
#define NEED_UNISTD_H (defined(SUN5)||defined(PTX))
|
||||
#endif
|
||||
|
||||
#if !defined(USE_SYS_TIME_H)
|
||||
#define USE_SYS_TIME_H (!defined(PTX))
|
||||
#endif
|
||||
|
||||
#if USE_STRINGS
|
||||
#define strchr index
|
||||
#define strrchr rindex
|
||||
#endif
|
||||
|
||||
/* used to force the server process to clear parity, which is for farmers
|
||||
*/
|
||||
#define CPARITY 1
|
||||
|
||||
|
||||
/* if you do not have fd_set's here is a possible emulation
|
||||
*/
|
||||
#if USE_OLDSEL
|
||||
typedef long fd_set;
|
||||
|
||||
#define FD_ZERO(a) {*(a)=0;}
|
||||
#define FD_SET(d,a) {*(a) |= (1 << (d));}
|
||||
#define FD_CLR(d,a) {*(a) &= ~(1 << (d));}
|
||||
#define FD_ISSET(d,a) (*(a) & (1 << (d)))
|
||||
#endif
|
||||
|
||||
#if USE_TERMIOS
|
||||
#if defined(HPUX7)||defined(HPUX8)||defined(HPUX9)
|
||||
#define TCGETS _IOR('T', 16, struct termios)
|
||||
#define TCSETS _IOW('T', 17, struct termios)
|
||||
#endif
|
||||
#if defined(PTX2)
|
||||
#define TCGETS TCGETP
|
||||
#define TCSETS TCSETP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* which type does wait(2) take for status location
|
||||
*/
|
||||
#if HAVE_UWAIT
|
||||
#define WAIT_T union wait
|
||||
#if ! defined WEXITSTATUS
|
||||
#define WEXITSTATUS(x) ((x).w_retcode)
|
||||
#endif
|
||||
#else
|
||||
#define WAIT_T int
|
||||
#endif
|
||||
|
||||
/* which type signal handlers return on this machine
|
||||
*/
|
||||
#if defined(sun) || defined(NEXT2) || defined(SUN5) || defined(PTX) || defined(IRIX5)
|
||||
#define SIGRETS void
|
||||
#else
|
||||
#define SIGRETS int
|
||||
#endif
|
||||
|
||||
/* do we have a (working) setsockopt call
|
||||
*/
|
||||
#if !defined(HAVE_SETSOCKOPT)
|
||||
#define HAVE_SETSOCKOPT (defined(sun)||defined(PTX))
|
||||
#endif
|
||||
|
||||
/* does this system have the ANSI strerror() function?
|
||||
*/
|
||||
#if !defined(HAVE_STRERROR)
|
||||
#define HAVE_STRERROR (defined(IBMR2)||defined(ETA10)||defined(V386)||defined(SUN5)||defined(NEXT2)||defined(HPUX8)||defined(HPUX9)||defined(PTX)||defined(IRIX5))
|
||||
#endif
|
||||
#if ! HAVE_STRERROR
|
||||
extern int errno;
|
||||
extern char *sys_errlist[];
|
||||
#define strerror(Me) (sys_errlist[Me])
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_H_ERRLIST)
|
||||
#define HAVE_H_ERRLIST (defined(SUN4)||defined(SUN3)||defined(FREEBSD)|defined(NETBSD)||defined(PTX)||defined(IRIX5))
|
||||
#endif
|
||||
#if HAVE_H_ERRLIST
|
||||
extern int h_errno;
|
||||
extern char *h_errlist[];
|
||||
#define hstrerror(Me) (h_errlist[Me])
|
||||
#else
|
||||
#define hstrerror(Me) "host lookup error"
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_RLIMIT)
|
||||
#if (defined(SUN5)||defined(PTX4))
|
||||
#define HAVE_RLIMIT 1
|
||||
#else
|
||||
#define HAVE_RLIMIT 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* that's all. just run
|
||||
* make
|
||||
* ./conserver -V
|
||||
*/
|
||||
|
||||
/* communication constants
|
||||
*/
|
||||
#define OB_SUSP 'Z' /* suspended by server */
|
||||
#define OB_DROP '.' /* dropped by server */
|
||||
|
||||
/* Due to C's poor man's macros the macro below would break if statements,
|
||||
* What we want
|
||||
* macro() { stuff }
|
||||
* but the syntax gives us
|
||||
* macro() { stuff };
|
||||
*
|
||||
* the extra semicolon breaks if statements!
|
||||
* Of course, the one we use makes lint scream:
|
||||
* macro() do { stuff } while (0)
|
||||
*
|
||||
* which is a statement and makes if statements safe
|
||||
*/
|
||||
#if defined(lint)
|
||||
extern int shut_up_lint;
|
||||
#else
|
||||
#define shut_up_lint 0
|
||||
#endif
|
||||
|
||||
/* this macro efficently outputs a constant string to a fd
|
||||
* of course it doesn't check the write :-(
|
||||
*/
|
||||
#define CSTROUT(Mfd, Mstr) do { \
|
||||
static char _ac[] = Mstr; \
|
||||
write(Mfd, _ac, sizeof(_ac)-1); \
|
||||
} while (shut_up_lint)
|
||||
|
||||
extern char *calloc(), *malloc(), *realloc();
|
351
conserver/cons-test.h
Normal file
351
conserver/cons-test.h
Normal file
@ -0,0 +1,351 @@
|
||||
/*
|
||||
* $Id: cons-gnac.h,v 5.35 1997-02-23 18:32:38-08 bryan Exp $
|
||||
*
|
||||
* Copyright 1992 Purdue Research Foundation, West Lafayette, Indiana
|
||||
* 47907. All rights reserved.
|
||||
*
|
||||
* Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
|
||||
*
|
||||
* This software is not subject to any license of the American Telephone
|
||||
* and Telegraph Company or the Regents of the University of California.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose on
|
||||
* any computer system, and to alter it and redistribute it freely, subject
|
||||
* to the following restrictions:
|
||||
*
|
||||
* 1. Neither the authors nor Purdue University are responsible for any
|
||||
* consequences of the use of this software.
|
||||
*
|
||||
* 2. The origin of this software must not be misrepresented, either by
|
||||
* explicit claim or by omission. Credit to the authors and Purdue
|
||||
* University must appear in documentation and sources.
|
||||
*
|
||||
* 3. Altered versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*/
|
||||
|
||||
/*
|
||||
* this is the configuration file for the Ohio State/PUCC console
|
||||
* server. Just define the macros below to somehting that looks good
|
||||
* and give it a go. It'll complain (under conserver -V) if things
|
||||
* look really bad.
|
||||
*
|
||||
* all PTX, PTX2, and PTX4 code added by gregf@sequent.com (gregf)
|
||||
*/
|
||||
/* #define IBMR2 1 /**/
|
||||
/* #define HPUX7 1 /**/
|
||||
/* #define SUN4 1 /**/
|
||||
/* #define SUN5 1 /**/
|
||||
/* #define PTX2 1 /* DYNIX/ptx v2.X */
|
||||
/* #define PTX4 1 /* DYNIX/ptx v4.0 */
|
||||
|
||||
#if (defined(PTX2) || defined(PTX4))
|
||||
#define PTX
|
||||
#endif
|
||||
|
||||
/* some machine specific details
|
||||
*/
|
||||
#if !defined(USE_OLDSEL)
|
||||
#if defined(IBMR2)
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(HAVE_UWAIT)
|
||||
#define HAVE_UWAIT !(defined(IBMR2)||defined(SUN5)||defined(HPUX8)||defined(HPUX9)||defined(PTX)||defined(IRIX5))
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_WAIT3)
|
||||
#define HAVE_WAIT3 !(defined(SUN5)||defined(PTX))
|
||||
#endif
|
||||
|
||||
/* This is the port number used in the connection. It can use either
|
||||
* /etc/services or a hardcoded port (SERVICE name has precedence).
|
||||
* (You can -D one in the Makefile to override these.)
|
||||
*/
|
||||
/* #define PORT 782 /* only if you cannot put in /etc/services */
|
||||
#define PORT 7777
|
||||
#if !defined(SERVICE)
|
||||
#if !defined(PORT)
|
||||
#define SERVICE "conserver"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Wait for a part of a second before slapping console server.
|
||||
* Good for CISCO terminal servers that get upset when you
|
||||
* attack with intense socket connections
|
||||
*/
|
||||
#if !defined(USLEEP_FOR_SLOW_PORTS)
|
||||
#define USLEEP_FOR_SLOW_PORTS 100000
|
||||
#endif
|
||||
|
||||
/* The name of the host which will act as the console server
|
||||
*/
|
||||
#if !defined(HOST)
|
||||
#define HOST "localhost"
|
||||
#endif
|
||||
|
||||
/* the default escape sequence used to give meta commands
|
||||
*/
|
||||
#define DEFATTN '\005'
|
||||
#define DEFESC 'c'
|
||||
|
||||
/* Location of the configuration file
|
||||
*/
|
||||
#if !defined(CONFIG)
|
||||
#define CONFIG "../conserver.cf/test.cf"
|
||||
#endif
|
||||
|
||||
/* Location of ANL designed passwd file */
|
||||
#if !defined(PASSWD_FILE)
|
||||
#define PASSWD_FILE "./conserver.passwd"
|
||||
#endif
|
||||
|
||||
/* The maximum number of serial lines that can be handled by a child process
|
||||
*/
|
||||
#if !defined(MAXMEMB)
|
||||
#define MAXMEMB 8
|
||||
#endif
|
||||
|
||||
|
||||
/* The maximum number of child processes spawned.
|
||||
*/
|
||||
#if !defined(MAXGRP)
|
||||
#define MAXGRP 32
|
||||
#endif
|
||||
|
||||
/* the max number of characters conserver will replay for you (the r command)
|
||||
*/
|
||||
#if !defined(MAXREPLAY)
|
||||
#define MAXREPLAY (80*25)
|
||||
#endif
|
||||
|
||||
/* if the encrypted passwd is in a shadow file, define HAVE_SHADOW (gregf)
|
||||
*/
|
||||
#if !defined(HAVE_SHADOW)
|
||||
#define HAVE_SHADOW (defined(PTX)||defined(SUN5))
|
||||
#endif
|
||||
|
||||
/* we'd like to line buffer our output, if we know how
|
||||
*/
|
||||
#if !defined(USE_SETLINEBUF)
|
||||
#define USE_SETLINEBUF (!(defined(HPUX7)||defined(HPUX8)||defined(HPUX9)||defined(PTX)))
|
||||
#endif
|
||||
|
||||
/* we'd like to line buffer our output, if we know how; PTX uses setvbuf (gregf)
|
||||
*/
|
||||
#if !defined(USE_SETVBUF)
|
||||
#define USE_SETVBUF (defined(PTX))
|
||||
#endif
|
||||
|
||||
/* hpux doesn't have getdtablesize() and they don't provide a macro
|
||||
* in non-KERNEL cpp mode
|
||||
*/
|
||||
#if defined(HPUX7)||defined(HPUX8)||defined(HPUX9)
|
||||
#define getdtablesize() 64
|
||||
#endif
|
||||
|
||||
/* the console server will provide a pseudo-device console which
|
||||
* allows operators to run backups and such without a hard wired
|
||||
* line (this is also good for testing the server to see if you
|
||||
* might wanna use it). Turn this on only if you (might) need it.
|
||||
*/
|
||||
#if !defined(DO_VIRTUAL)
|
||||
#define DO_VIRTUAL 1
|
||||
#endif
|
||||
|
||||
#if DO_VIRTUAL
|
||||
/* if the virtual console option is on we need a source to ptys,
|
||||
* the PUCC ptyd daemon is the best source be know, else fall back
|
||||
* on some emulation code?? (XXX)
|
||||
*/
|
||||
#if !defined(HAVE_PTYD)
|
||||
#define HAVE_PTYD (defined(S81)||defined(VAX8800))
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_GETPSEUDO)
|
||||
#define HAVE_GETPSEUDO (defined(PTX2))
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_PTSNAME)
|
||||
#define HAVE_PTSNAME (defined(PTX4))
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_LDTERM)
|
||||
#define HAVE_LDTERM (defined(SUN5))
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_STTY_LD)
|
||||
#define HAVE_STTY_LD (defined(IRIX5))
|
||||
#endif
|
||||
|
||||
#endif /* virtual (process on a pseudo-tty) console support */
|
||||
|
||||
#if !defined(HAVE_SETSID)
|
||||
#define HAVE_SETSID (defined(IBMR2)||defined(SUN5)||defined(HPUX7)||defined(HPUX8)||defined(HPUX9)||defined(PTX)||defined(IRIX5))
|
||||
#endif
|
||||
|
||||
/* should we use flock to keep multiple conservers from hurting each other?
|
||||
* PTX has lockf... should probably port code to work with this (gregf)
|
||||
*/
|
||||
#if !defined(USE_FLOCK)
|
||||
#define USE_FLOCK (!(defined(IBMR2)||defined(SUN5)||defined(HPUX7)||defined(HPUX8)||defined(HPUX9)||defined(PTX)))
|
||||
#endif
|
||||
|
||||
/* should we try to pop streams modules off?
|
||||
*/
|
||||
#if !defined(USE_STREAMS)
|
||||
#define USE_STREAMS (defined(SUN4)||defined(SUN5)||defined(PTX)||defined(IRIX5))
|
||||
#endif
|
||||
|
||||
/* if we do not have old style tty emulation use termios.h
|
||||
*/
|
||||
#if !defined(USE_TERMIO)
|
||||
#define USE_TERMIO (defined(ETA10)||defined(V386))
|
||||
#endif
|
||||
#if !defined(USE_TERMIOS)
|
||||
#define USE_TERMIOS (defined(HPUX7)||defined(HPUX8)||defined(HPUX9)||defined(SUN5)||defined(PTX)||defined(IRIX5))
|
||||
#endif
|
||||
#if !defined(USE_TCBREAK)
|
||||
#define USE_TCBREAK (defined(SUN4)||defined(PTX))
|
||||
#endif
|
||||
|
||||
/* if we have <strings.h> define this to 1, else define to 0
|
||||
*/
|
||||
#if !defined(USE_STRINGS)
|
||||
#define USE_STRINGS (defined(SUN4)||defined(DYNIX)||defined(EPIX)||defined(IRIX5))
|
||||
#endif
|
||||
|
||||
#if !defined(NEED_UNISTD_H)
|
||||
#define NEED_UNISTD_H (defined(SUN5)||defined(PTX))
|
||||
#endif
|
||||
|
||||
#if !defined(USE_SYS_TIME_H)
|
||||
#define USE_SYS_TIME_H (!defined(PTX))
|
||||
#endif
|
||||
|
||||
#if USE_STRINGS
|
||||
#define strchr index
|
||||
#define strrchr rindex
|
||||
#endif
|
||||
|
||||
/* used to force the server process to clear parity, which is for farmers
|
||||
*/
|
||||
#define CPARITY 1
|
||||
|
||||
|
||||
/* if you do not have fd_set's here is a possible emulation
|
||||
*/
|
||||
#if USE_OLDSEL
|
||||
typedef long fd_set;
|
||||
|
||||
#define FD_ZERO(a) {*(a)=0;}
|
||||
#define FD_SET(d,a) {*(a) |= (1 << (d));}
|
||||
#define FD_CLR(d,a) {*(a) &= ~(1 << (d));}
|
||||
#define FD_ISSET(d,a) (*(a) & (1 << (d)))
|
||||
#endif
|
||||
|
||||
#if USE_TERMIOS
|
||||
#if defined(HPUX7)||defined(HPUX8)||defined(HPUX9)
|
||||
#define TCGETS _IOR('T', 16, struct termios)
|
||||
#define TCSETS _IOW('T', 17, struct termios)
|
||||
#endif
|
||||
#if defined(PTX2)
|
||||
#define TCGETS TCGETP
|
||||
#define TCSETS TCSETP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* which type does wait(2) take for status location
|
||||
*/
|
||||
#if HAVE_UWAIT
|
||||
#define WAIT_T union wait
|
||||
#if ! defined WEXITSTATUS
|
||||
#define WEXITSTATUS(x) ((x).w_retcode)
|
||||
#endif
|
||||
#else
|
||||
#define WAIT_T int
|
||||
#endif
|
||||
|
||||
/* which type signal handlers return on this machine
|
||||
*/
|
||||
#if defined(sun) || defined(NEXT2) || defined(SUN5) || defined(PTX) || defined(IRIX5)
|
||||
#define SIGRETS void
|
||||
#else
|
||||
#define SIGRETS int
|
||||
#endif
|
||||
|
||||
/* do we have a (working) setsockopt call
|
||||
*/
|
||||
#if !defined(HAVE_SETSOCKOPT)
|
||||
#define HAVE_SETSOCKOPT (defined(sun)||defined(PTX))
|
||||
#endif
|
||||
|
||||
/* does this system have the ANSI strerror() function?
|
||||
*/
|
||||
#if !defined(HAVE_STRERROR)
|
||||
#define HAVE_STRERROR (defined(IBMR2)||defined(ETA10)||defined(V386)||defined(SUN5)||defined(NEXT2)||defined(HPUX8)||defined(HPUX9)||defined(PTX)||defined(IRIX5))
|
||||
#endif
|
||||
#if ! HAVE_STRERROR
|
||||
extern int errno;
|
||||
extern char *sys_errlist[];
|
||||
#define strerror(Me) (sys_errlist[Me])
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_H_ERRLIST)
|
||||
#define HAVE_H_ERRLIST (defined(SUN4)||defined(SUN3)||defined(FREEBSD)|defined(NETBSD)||defined(PTX)||defined(IRIX5))
|
||||
#endif
|
||||
#if HAVE_H_ERRLIST
|
||||
extern int h_errno;
|
||||
extern char *h_errlist[];
|
||||
#define hstrerror(Me) (h_errlist[Me])
|
||||
#else
|
||||
#define hstrerror(Me) "host lookup error"
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_RLIMIT)
|
||||
#if (defined(SUN5)||defined(PTX4))
|
||||
#define HAVE_RLIMIT 1
|
||||
#else
|
||||
#define HAVE_RLIMIT 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* that's all. just run
|
||||
* make
|
||||
* ./conserver -V
|
||||
*/
|
||||
|
||||
/* communication constants
|
||||
*/
|
||||
#define OB_SUSP 'Z' /* suspended by server */
|
||||
#define OB_DROP '.' /* dropped by server */
|
||||
|
||||
/* Due to C's poor man's macros the macro below would break if statements,
|
||||
* What we want
|
||||
* macro() { stuff }
|
||||
* but the syntax gives us
|
||||
* macro() { stuff };
|
||||
*
|
||||
* the extra semicolon breaks if statements!
|
||||
* Of course, the one we use makes lint scream:
|
||||
* macro() do { stuff } while (0)
|
||||
*
|
||||
* which is a statement and makes if statements safe
|
||||
*/
|
||||
#if defined(lint)
|
||||
extern int shut_up_lint;
|
||||
#else
|
||||
#define shut_up_lint 0
|
||||
#endif
|
||||
|
||||
/* this macro efficently outputs a constant string to a fd
|
||||
* of course it doesn't check the write :-(
|
||||
*/
|
||||
#define CSTROUT(Mfd, Mstr) do { \
|
||||
static char _ac[] = Mstr; \
|
||||
write(Mfd, _ac, sizeof(_ac)-1); \
|
||||
} while (shut_up_lint)
|
||||
|
||||
extern char *calloc(), *malloc(), *realloc();
|
1
conserver/cons.h
Symbolic link
1
conserver/cons.h
Symbolic link
@ -0,0 +1 @@
|
||||
cons-test.h
|
710
conserver/consent.c
Normal file
710
conserver/consent.c
Normal file
@ -0,0 +1,710 @@
|
||||
/*
|
||||
* $Id: consent.c,v 5.30 1998-11-20 17:30:45-08 bryan Exp $
|
||||
*
|
||||
* Copyright 1992 Purdue Research Foundation, West Lafayette, Indiana
|
||||
* 47907. All rights reserved.
|
||||
*
|
||||
* Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
|
||||
*
|
||||
* This software is not subject to any license of the American Telephone
|
||||
* and Telegraph Company or the Regents of the University of California.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose on
|
||||
* any computer system, and to alter it and redistribute it freely, subject
|
||||
* to the following restrictions:
|
||||
*
|
||||
* 1. Neither the authors nor Purdue University are responsible for any
|
||||
* consequences of the use of this software.
|
||||
*
|
||||
* 2. The origin of this software must not be misrepresented, either by
|
||||
* explicit claim or by omission. Credit to the authors and Purdue
|
||||
* University must appear in documentation and sources.
|
||||
*
|
||||
* 3. Altered versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Network console modifications by Robert Olson, olson@mcs.anl.gov.
|
||||
*/
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"@(#) Copyright 1992 Purdue Research Foundation.\nAll rights reserved.\n";
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include "cons.h"
|
||||
#include "consent.h"
|
||||
#include "client.h"
|
||||
#include "main.h"
|
||||
|
||||
#if USE_TERMIO
|
||||
#include <termio.h>
|
||||
|
||||
#else
|
||||
#if USE_TERMIOS
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#else /* use ioctl stuff */
|
||||
#include <sgtty.h>
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if USE_STREAMS
|
||||
#include <stropts.h>
|
||||
#endif
|
||||
|
||||
#if USE_STRINGS
|
||||
#include <strings.h>
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
|
||||
BAUD baud [] = {
|
||||
{ "Netwk", 0 },
|
||||
#if defined(B38400)
|
||||
{ "38400", B38400 },
|
||||
#endif
|
||||
#if defined(B19200)
|
||||
{ "19200", B19200 },
|
||||
#endif
|
||||
{ "9600", B9600 },
|
||||
{ "4800", B4800 },
|
||||
{ "2400", B2400 },
|
||||
#if defined(B1800)
|
||||
{ "1800", B1800 },
|
||||
#endif
|
||||
{ "1200", B1200 },
|
||||
#if defined(B600)
|
||||
{ "600", B600 },
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
/* find a baud rate for the string "9600x" -> B9600 (ksb)
|
||||
*/
|
||||
BAUD *
|
||||
FindBaud(pcMode)
|
||||
char *pcMode;
|
||||
{
|
||||
register int i;
|
||||
|
||||
for (i = 0; i < sizeof(baud)/sizeof(struct baud); ++i) {
|
||||
if (0 != strncmp(pcMode, baud[i].acrate, strlen(baud[i].acrate)))
|
||||
continue;
|
||||
return baud+i;
|
||||
}
|
||||
return baud;
|
||||
}
|
||||
|
||||
|
||||
PARITY parity[] = {
|
||||
#if USE_TERMIOS
|
||||
#if !defined(PAREXT)
|
||||
#define PAREXT 0
|
||||
#endif
|
||||
{' ', 0, 0}, /* Blank for network */
|
||||
{'e', PARENB|CS7, 0}, /* even */
|
||||
{'m', PARENB|CS7|PARODD|PAREXT, 0}, /* mark */
|
||||
{'o', PARENB|CS7|PARODD, 0}, /* odd */
|
||||
{'p', CS8, 0}, /* pass 8 bits, no parity */
|
||||
{'s', PARENB|CS7|PAREXT, 0}, /* space */
|
||||
#else
|
||||
{' ', 0, 0}, /* Blank for network */
|
||||
{'e', EVENP, ODDP}, /* even */
|
||||
{'m', EVENP|ODDP, 0}, /* mark */
|
||||
{'o', ODDP, EVENP}, /* odd */
|
||||
#if defined(PASS8)
|
||||
{'p', PASS8,EVENP|ODDP},/* pass 8 bits, no parity */
|
||||
#endif
|
||||
{'s', 0, EVENP|ODDP} /* space */
|
||||
#endif
|
||||
};
|
||||
|
||||
/* find a parity on the end of a baud "9600even" -> EVEN (ksb)
|
||||
*/
|
||||
PARITY *
|
||||
FindParity(pcMode)
|
||||
char *pcMode;
|
||||
{
|
||||
register int i;
|
||||
auto char acFirst;
|
||||
|
||||
while (isdigit(*pcMode)) {
|
||||
++pcMode;
|
||||
}
|
||||
acFirst = *pcMode;
|
||||
if (isupper(acFirst))
|
||||
acFirst = tolower(acFirst);
|
||||
for (i = 0; i < sizeof(parity)/sizeof(struct parity); ++i) {
|
||||
if (acFirst != parity[i].ckey)
|
||||
continue;
|
||||
return parity+i;
|
||||
}
|
||||
return parity;
|
||||
}
|
||||
|
||||
|
||||
#if USE_TERMIOS
|
||||
/* setup a tty device (ksb)
|
||||
*/
|
||||
static int
|
||||
TtyDev(pCE)
|
||||
CONSENT *pCE;
|
||||
{
|
||||
struct termios termp;
|
||||
auto struct stat stPerm;
|
||||
|
||||
/* here we should fstat for `read-only' checks
|
||||
*/
|
||||
if (-1 == fstat(pCE->fdtty, & stPerm)) {
|
||||
fprintf(stderr, "%s: fstat: %s: %s\n", progname, pCE->dfile, strerror(errno));
|
||||
} else if (0 == (stPerm.st_mode & 0222)) {
|
||||
/* any device that is read-only we won't write to
|
||||
*/
|
||||
pCE->fronly = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get terminal attributes
|
||||
*/
|
||||
if (-1 == tcgetattr(pCE->fdtty, &termp)) {
|
||||
fprintf(stderr, "%s: tcgetattr: %s(%d): %s\n", progname, pCE->dfile, pCE->fdtty, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Turn off: echo
|
||||
* icrnl
|
||||
* opost No post processing
|
||||
* icanon No line editing
|
||||
* isig No signal generation
|
||||
* Turn on: ixoff
|
||||
*/
|
||||
termp.c_iflag = IXON|IXOFF|BRKINT;
|
||||
termp.c_oflag = 0;
|
||||
termp.c_cflag = CREAD;
|
||||
termp.c_cflag |= pCE->pparity->iset;
|
||||
termp.c_lflag = 0;
|
||||
/*
|
||||
* Set the VMIN == 128
|
||||
* Set the VTIME == 1 (0.1 sec)
|
||||
* Don't bother with the control characters as they are not used
|
||||
*/
|
||||
termp.c_cc[VMIN] = 128;
|
||||
termp.c_cc[VTIME] = 1;
|
||||
|
||||
if (-1 == cfsetospeed(&termp,pCE->pbaud->irate)) {
|
||||
fprintf(stderr, "%s: cfsetospeed: %s(%d): %s\n", progname, pCE->dfile, pCE->fdtty, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (-1 == cfsetispeed(&termp,pCE->pbaud->irate)) {
|
||||
fprintf(stderr, "%s: cfsetispeed: %s(%d): %s\n", progname, pCE->dfile, pCE->fdtty, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set terminal attributes
|
||||
*/
|
||||
if (-1 == tcsetattr(pCE->fdtty, TCSADRAIN, &termp)) {
|
||||
fprintf(stderr, "%s: tcsetattr: %s(%d): %s\n", progname, pCE->dfile, pCE->fdtty, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if USE_STREAMS
|
||||
/*
|
||||
* eat all the streams modules upto and including ttcompat
|
||||
*/
|
||||
while (ioctl(pCE->fdtty, I_FIND, "ttcompat") == 0) {
|
||||
(void)ioctl(pCE->fdtty, I_POP, 0);
|
||||
}
|
||||
#endif
|
||||
pCE->fup = 1;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
/* setup a tty device (ksb)
|
||||
*/
|
||||
static int
|
||||
TtyDev(pCE)
|
||||
CONSENT *pCE;
|
||||
{
|
||||
struct sgttyb sty;
|
||||
struct tchars m_tchars;
|
||||
struct ltchars m_ltchars;
|
||||
auto struct stat stPerm;
|
||||
|
||||
/* here we should fstat for `read-only' checks
|
||||
*/
|
||||
if (-1 == fstat(pCE->fdtty, & stPerm)) {
|
||||
fprintf(stderr, "%s: fstat: %s: %s\n", progname, pCE->dfile, strerror(errno));
|
||||
} else if (0 == (stPerm.st_mode & 0222)) {
|
||||
/* any device that is read-only we won't write to
|
||||
*/
|
||||
pCE->fronly = 1;
|
||||
}
|
||||
|
||||
#if USE_SOFTCAR
|
||||
#if defined(TIOCSSOFTCAR)
|
||||
if (-1 == ioctl(pCE->fdtty, TIOCSSOFTCAR, &fSoftcar)) {
|
||||
fprintf(stderr, "%s: softcar: %d: %s\n", progname, pCE->fdtty, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* stty 9600 raw cs7
|
||||
*/
|
||||
if (-1 == ioctl(pCE->fdtty, TIOCGETP, (char *)&sty)) {
|
||||
fprintf(stderr, "%s: ioctl1: %s(%d): %s\n", progname, pCE->dfile, pCE->fdtty, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
sty.sg_flags &= ~(ECHO|CRMOD|pCE->pparity->iclr);
|
||||
sty.sg_flags |= (CBREAK|TANDEM|pCE->pparity->iset);
|
||||
sty.sg_erase = -1;
|
||||
sty.sg_kill = -1;
|
||||
sty.sg_ispeed = pCE->pbaud->irate;
|
||||
sty.sg_ospeed = pCE->pbaud->irate;
|
||||
if (-1 == ioctl(pCE->fdtty, TIOCSETP, (char *)&sty)) {
|
||||
fprintf(stderr, "%s: ioctl2: %d: %s\n", progname, pCE->fdtty, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* stty undef all tty chars
|
||||
* (in cbreak mode we may not need to this... but we do)
|
||||
*/
|
||||
if (-1 == ioctl(pCE->fdtty, TIOCGETC, (char *)&m_tchars)) {
|
||||
fprintf(stderr, "%s: ioctl3: %d: %s\n", progname, pCE->fdtty, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
m_tchars.t_intrc = -1;
|
||||
m_tchars.t_quitc = -1;
|
||||
m_tchars.t_startc = -1;
|
||||
m_tchars.t_stopc = -1;
|
||||
m_tchars.t_eofc = -1;
|
||||
m_tchars.t_brkc = -1;
|
||||
if (-1 == ioctl(pCE->fdtty, TIOCSETC, (char *)&m_tchars)) {
|
||||
fprintf(stderr, "%s: ioctl4: %d: %s\n", progname, pCE->fdtty, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
if (-1 == ioctl(pCE->fdtty, TIOCGLTC, (char *)&m_ltchars)) {
|
||||
fprintf(stderr, "%s: ioctl5: %d: %s\n", progname, pCE->fdtty, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
m_ltchars.t_werasc = -1;
|
||||
m_ltchars.t_flushc = -1;
|
||||
m_ltchars.t_lnextc = -1;
|
||||
m_ltchars.t_suspc = -1;
|
||||
m_ltchars.t_dsuspc = -1;
|
||||
if (-1 == ioctl(pCE->fdtty, TIOCSLTC, (char *)&m_ltchars)) {
|
||||
fprintf(stderr, "%s: ioctl6: %d: %s\n", progname, pCE->fdtty, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
#if USE_STREAMS
|
||||
/* pop off the un-needed streams modules (on a sun3 machine esp.)
|
||||
* (Idea by jrs@ecn.purdue.edu)
|
||||
*/
|
||||
while (ioctl(pCE->fdtty, I_POP, 0) == 0) {
|
||||
/* eat all the streams modules */;
|
||||
}
|
||||
#endif
|
||||
pCE->fup = 1;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DO_VIRTUAL
|
||||
/* setup a virtual device (ksb)
|
||||
*/
|
||||
static int
|
||||
VirtDev(pCE)
|
||||
CONSENT *pCE;
|
||||
{
|
||||
#if USE_TERMIOS
|
||||
static struct termios n_tio;
|
||||
#else
|
||||
auto struct sgttyb sty;
|
||||
auto struct tchars m_tchars;
|
||||
auto struct ltchars m_ltchars;
|
||||
#endif
|
||||
#if HAVE_RLIMIT
|
||||
auto struct rlimit rl;
|
||||
#endif
|
||||
auto int i, iNewGrp;
|
||||
auto int fd;
|
||||
extern char **environ;
|
||||
register char *pcShell, **ppcArgv;
|
||||
|
||||
(void)fflush(stdout);
|
||||
|
||||
switch (pCE->ipid = fork()) {
|
||||
case -1:
|
||||
return -1;
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "%s: %d is the pid on %s\n", progname, pCE->ipid, pCE->acslave);
|
||||
(void)fflush(stderr);
|
||||
pCE->fup = 1;
|
||||
sleep(2); /* chance to open line */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* put the signals back that we trap
|
||||
*/
|
||||
signal(SIGINT, SIG_DFL);
|
||||
signal(SIGQUIT, SIG_DFL);
|
||||
signal(SIGTSTP, SIG_DFL);
|
||||
|
||||
/* setup new process with clean filew descriptors
|
||||
*/
|
||||
#if HAVE_RLIMIT
|
||||
getrlimit(RLIMIT_NOFILE, &rl);
|
||||
i = rl.rlim_cur;
|
||||
#else
|
||||
i = getdtablesize();
|
||||
#endif
|
||||
for (/* i above */; i-- > 2; ) {
|
||||
close(i);
|
||||
}
|
||||
/* leave 2 until we *have to close it*
|
||||
*/
|
||||
close(1);
|
||||
close(0);
|
||||
#if defined(TIOCNOTTY)
|
||||
if (-1 != (i = open("/dev/tty", 2, 0))) {
|
||||
ioctl(i, TIOCNOTTY, (char *)0);
|
||||
close(i);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_SETSID
|
||||
iNewGrp = setsid();
|
||||
if (-1 == iNewGrp) {
|
||||
fprintf(stderr, "%s: %s: setsid: %s\n", progname, pCE->server, strerror(errno));
|
||||
iNewGrp = getpid();
|
||||
}
|
||||
#else
|
||||
iNewGrp = getpid();
|
||||
#endif
|
||||
|
||||
if (0 != open(pCE->acslave, 2, 0) || 1 != dup(0)) {
|
||||
fprintf(stderr, "%s: %s: fd sync error\n", progname, pCE->server);
|
||||
exit(1);
|
||||
}
|
||||
#if HAVE_PTSNAME
|
||||
/* SYSVr4 semantics for opening stream ptys (gregf)
|
||||
* under PTX (others?) we have to push the compatibility
|
||||
* streams modules `ptem' and `ld'
|
||||
*/
|
||||
(void)ioctl(0, I_PUSH, "ptem");
|
||||
(void)ioctl(0, I_PUSH, "ld");
|
||||
#endif
|
||||
#if HAVE_LDTERM
|
||||
(void)ioctl(0, I_PUSH, "ptem");
|
||||
(void)ioctl(0, I_PUSH, "ldterm");
|
||||
#endif
|
||||
#if HAVE_STTY_LD
|
||||
(void)ioctl(0, I_PUSH, "stty_ld");
|
||||
#endif
|
||||
|
||||
#if USE_TERMIOS
|
||||
if (0 != ioctl(0, TCGETS, & n_tio)) {
|
||||
fprintf(stderr, "%s: iotcl: getsw: %s\n", progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
n_tio.c_iflag &= ~(IGNCR|IUCLC);
|
||||
n_tio.c_iflag |= ICRNL|IXON|IXANY;
|
||||
n_tio.c_oflag &= ~(OLCUC|ONOCR|ONLRET|OFILL|NLDLY|CRDLY|TABDLY|BSDLY);
|
||||
n_tio.c_oflag |= OPOST|ONLCR;
|
||||
n_tio.c_lflag &= ~(XCASE|NOFLSH|ECHOK|ECHONL);
|
||||
n_tio.c_lflag |= ISIG|ICANON|ECHO;
|
||||
n_tio.c_cc[VEOF] = '\004';
|
||||
n_tio.c_cc[VEOL] = '\000';
|
||||
n_tio.c_cc[VERASE] = '\010';
|
||||
n_tio.c_cc[VINTR] = '\003';
|
||||
n_tio.c_cc[VKILL] = '@';
|
||||
/* MIN */
|
||||
n_tio.c_cc[VQUIT] = '\034';
|
||||
n_tio.c_cc[VSTART] = '\021';
|
||||
n_tio.c_cc[VSTOP] = '\023';
|
||||
n_tio.c_cc[VSUSP] = '\032';
|
||||
if (0 != ioctl(0, TCSETS, & n_tio)) {
|
||||
fprintf(stderr, "%s: getarrt: %s\n", progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
tcsetpgrp(0, iNewGrp);
|
||||
#else
|
||||
/* stty 9600 raw cs7
|
||||
*/
|
||||
if (-1 == ioctl(0, TIOCGETP, (char *)&sty)) {
|
||||
fprintf(stderr, "%s: ioctl1: %s: %s\n", progname, pCE->fdtty, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
sty.sg_flags &= ~(CBREAK|TANDEM|pCE->pparity->iclr);
|
||||
sty.sg_flags |= (ECHO|CRMOD|pCE->pparity->iset);
|
||||
sty.sg_erase = '\b';
|
||||
sty.sg_kill = '\025';
|
||||
sty.sg_ispeed = pCE->pbaud->irate;
|
||||
sty.sg_ospeed = pCE->pbaud->irate;
|
||||
if (-1 == ioctl(0, TIOCSETP, (char *)&sty)) {
|
||||
fprintf(stderr, "%s: ioctl2: %s\n", progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* stty undef all tty chars
|
||||
* (in cbreak mode we may not need to this... but we do)
|
||||
*/
|
||||
if (-1 == ioctl(0, TIOCGETC, (char *)&m_tchars)) {
|
||||
fprintf(stderr, "%s: ioctl3: %s\n", progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
m_tchars.t_intrc = '\003';
|
||||
m_tchars.t_quitc = '\034';
|
||||
m_tchars.t_startc = '\021';
|
||||
m_tchars.t_stopc = '\023';
|
||||
m_tchars.t_eofc = '\004';
|
||||
m_tchars.t_brkc = '\033';
|
||||
if (-1 == ioctl(0, TIOCSETC, (char *)&m_tchars)) {
|
||||
fprintf(stderr, "%s: ioctl4: %s\n", progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (-1 == ioctl(0, TIOCGLTC, (char *)&m_ltchars)) {
|
||||
fprintf(stderr, "%s: ioctl5: %s\n", progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
m_ltchars.t_werasc = '\027';
|
||||
m_ltchars.t_flushc = '\017';
|
||||
m_ltchars.t_lnextc = '\026';
|
||||
m_ltchars.t_suspc = '\032';
|
||||
m_ltchars.t_dsuspc = '\031';
|
||||
if (-1 == ioctl(0, TIOCSLTC, (char *)&m_ltchars)) {
|
||||
fprintf(stderr, "%s: ioctl6: %s\n", progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* give us a process group to work in
|
||||
*/
|
||||
ioctl(0, TIOCGPGRP, (char *)&i);
|
||||
setpgrp(0, i);
|
||||
ioctl(0, TIOCSPGRP, (char *)&iNewGrp);
|
||||
setpgrp(0, iNewGrp);
|
||||
#endif
|
||||
|
||||
close(2);
|
||||
(void)dup(1); /* better be 2, but it is too late now */
|
||||
|
||||
/* if the command is null we should run root's shell, directly
|
||||
* if we can't find root's shell run /bin/sh
|
||||
*/
|
||||
pcShell = "/bin/sh";
|
||||
if ('\000' == pCE->pccmd[0]) {
|
||||
static char *apcArgv[] = {
|
||||
"-shell", "-i", (char *)0
|
||||
};
|
||||
register struct passwd *pwd;
|
||||
|
||||
if ((struct passwd *)0 != (pwd = getpwuid(0)) && '\000' != pwd->pw_shell[0]) {
|
||||
pcShell = pwd->pw_shell;
|
||||
}
|
||||
ppcArgv = apcArgv;
|
||||
} else {
|
||||
static char *apcArgv[] = {
|
||||
"/bin/sh", "-ce", (char *)0, (char *)0
|
||||
};
|
||||
|
||||
apcArgv[2] = pCE->pccmd;
|
||||
ppcArgv = apcArgv;
|
||||
}
|
||||
execve(pcShell, ppcArgv, environ);
|
||||
fprintf(stderr, "execve: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
#endif
|
||||
|
||||
/* down a console, virtual or real (ksb)
|
||||
*/
|
||||
void
|
||||
ConsDown(pCE, pfdSet)
|
||||
CONSENT *pCE;
|
||||
fd_set *pfdSet;
|
||||
{
|
||||
#if DO_VIRTUAL
|
||||
if (-1 != pCE->ipid) {
|
||||
if (-1 != kill(pCE->ipid, SIGHUP))
|
||||
sleep(1);
|
||||
pCE->ipid = -1;
|
||||
}
|
||||
#endif
|
||||
if (-1 != pCE->fdtty) {
|
||||
FD_CLR(pCE->fdtty, pfdSet);
|
||||
#if DO_VIRTUAL
|
||||
if (0 == pCE->fvirtual) {
|
||||
(void)close(pCE->fdtty);
|
||||
pCE->fdtty = -1;
|
||||
}
|
||||
#else
|
||||
(void)close(pCE->fdtty);
|
||||
pCE->fdtty = -1;
|
||||
#endif
|
||||
}
|
||||
if (-1 != pCE->fdlog) {
|
||||
if (pCE->nolog) {
|
||||
CSTROUT(pCE->fdlog, "[Console logging restored]\r\n");
|
||||
}
|
||||
(void)close(pCE->fdlog);
|
||||
pCE->fdlog = -1;
|
||||
}
|
||||
pCE->fup = 0;
|
||||
pCE->nolog = 0;
|
||||
}
|
||||
|
||||
/* set up a console the way it should be for use to work with it (ksb)
|
||||
* also, recover from silo over runs by dropping the line and re-opening
|
||||
* We also maintian the select set for the caller.
|
||||
*/
|
||||
void
|
||||
ConsInit(pCE, pfdSet)
|
||||
CONSENT *pCE;
|
||||
fd_set *pfdSet;
|
||||
{
|
||||
/* clean up old stuff
|
||||
*/
|
||||
ConsDown(pCE, pfdSet);
|
||||
|
||||
pCE->fronly = 0;
|
||||
pCE->nolog = 0;
|
||||
(void)strcpy(pCE->acline, pCE->server);
|
||||
pCE->inamelen = strlen(pCE->server);
|
||||
pCE->acline[pCE->inamelen++] = ':';
|
||||
pCE->acline[pCE->inamelen++] = ' ';
|
||||
pCE->iend = pCE->inamelen;
|
||||
|
||||
|
||||
/* try to open them again
|
||||
*/
|
||||
if (-1 ==
|
||||
(pCE->fdlog = open(pCE->lfile, O_RDWR|O_CREAT|O_APPEND, 0644)))
|
||||
{
|
||||
fprintf(stderr,
|
||||
"%s: open: %s: %s\n",
|
||||
progname, pCE->lfile, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
#if DO_VIRTUAL
|
||||
if (0 != pCE->fvirtual)
|
||||
{
|
||||
/* still open, never ever close it, but set the bit */
|
||||
FD_SET(pCE->fdtty, pfdSet);
|
||||
}
|
||||
else if (pCE->isNetworkConsole)
|
||||
{
|
||||
struct sockaddr_in port;
|
||||
struct hostent *hp;
|
||||
int one = 1;
|
||||
|
||||
#ifdef USLEEP_FOR_SLOW_PORTS
|
||||
usleep( USLEEP_FOR_SLOW_PORTS ); /* Sleep for slow network ports */
|
||||
#endif
|
||||
|
||||
bzero(&port, sizeof(port));
|
||||
|
||||
if ((hp = gethostbyname(pCE->networkConsoleHost)) == NULL)
|
||||
{
|
||||
fprintf(stderr, "%s: gethostbyname %s failed\n",
|
||||
progname, pCE->networkConsoleHost);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
bcopy(hp->h_addr, &port.sin_addr, hp->h_length);
|
||||
port.sin_family = hp->h_addrtype;
|
||||
port.sin_port = htons(pCE->networkConsolePort);
|
||||
|
||||
if ((pCE->fdtty = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||
{
|
||||
fprintf(stderr, "%s: socket: %s\n", progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (setsockopt(pCE->fdtty, SOL_SOCKET, SO_KEEPALIVE,
|
||||
(char *) &one, sizeof(one)) < 0)
|
||||
{
|
||||
fprintf(stderr, "%s: setsockopt SO_KEEPALIVE: %s\n",
|
||||
progname, strerror(errno));
|
||||
}
|
||||
if (connect(pCE->fdtty,
|
||||
(struct sockaddr *)&port, sizeof(port)) < 0)
|
||||
{
|
||||
fprintf(stderr, "%s: connect: %s (%d@%s): %s: forcing down\n",
|
||||
progname, pCE->server, ntohs(port.sin_port),
|
||||
pCE->networkConsoleHost, strerror(errno));
|
||||
ConsDown(pCE, pfdSet);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Poke the connection to get the annex to wake up and
|
||||
* register this connection.
|
||||
*/
|
||||
#ifdef POKE_ANNEX
|
||||
write(pCE->fdtty, "\r\n", 2);
|
||||
#endif
|
||||
} else if (-1 == (pCE->fdtty = open(pCE->dfile, O_RDWR|O_NDELAY, 0600))) {
|
||||
fprintf(stderr, "%s: open: %s: %s\n", progname, pCE->dfile, strerror(errno));
|
||||
(void)close(pCE->fdlog);
|
||||
pCE->fdlog = -1;
|
||||
return;
|
||||
}
|
||||
FD_SET(pCE->fdtty, pfdSet);
|
||||
|
||||
/* ok, now setup the device
|
||||
*/
|
||||
if (pCE->fvirtual) {
|
||||
VirtDev(pCE);
|
||||
}
|
||||
else if (pCE->isNetworkConsole)
|
||||
{
|
||||
pCE->fup = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
TtyDev(pCE);
|
||||
}
|
||||
#else
|
||||
if (-1 == (pCE->fdtty = open(pCE->dfile, O_RDWR|O_NDELAY, 0600))) {
|
||||
fprintf(stderr, "%s: open: %s: %s\n", progname, pCE->dfile, strerror(errno));
|
||||
(void)close(pCE->fdlog);
|
||||
pCE->fdlog = -1;
|
||||
return;
|
||||
}
|
||||
FD_SET(pCE->fdtty, pfdSet);
|
||||
|
||||
/* ok, now setup the device
|
||||
*/
|
||||
TtyDev(pCE);
|
||||
#endif
|
||||
}
|
89
conserver/consent.h
Normal file
89
conserver/consent.h
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* $Id: consent.h,v 5.11 1998-12-14 11:20:15-08 bryan Exp $
|
||||
*
|
||||
* Copyright 1992 Purdue Research Foundation, West Lafayette, Indiana
|
||||
* 47907. All rights reserved.
|
||||
*
|
||||
* Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
|
||||
*
|
||||
* This software is not subject to any license of the American Telephone
|
||||
* and Telegraph Company or the Regents of the University of California.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose on
|
||||
* any computer system, and to alter it and redistribute it freely, subject
|
||||
* to the following restrictions:
|
||||
*
|
||||
* 1. Neither the authors nor Purdue University are responsible for any
|
||||
* consequences of the use of this software.
|
||||
*
|
||||
* 2. The origin of this software must not be misrepresented, either by
|
||||
* explicit claim or by omission. Credit to the authors and Purdue
|
||||
* University must appear in documentation and sources.
|
||||
*
|
||||
* 3. Altered versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*/
|
||||
/*
|
||||
* Network console modifications by Robert Olson, olson@mcs.anl.gov.
|
||||
*/
|
||||
|
||||
|
||||
/* stuff to keep track of a console entry
|
||||
*/
|
||||
typedef struct baud { /* a baud rate table */
|
||||
char acrate[8];
|
||||
int irate;
|
||||
} BAUD;
|
||||
|
||||
typedef struct parity { /* a parity bits table */
|
||||
char ckey;
|
||||
int iset;
|
||||
int iclr;
|
||||
} PARITY;
|
||||
|
||||
#define MAXSERVLEN 32 /* max length of server name */
|
||||
#define MAXDEVLEN 512 /* max length of /dev/ttyax */
|
||||
#define MAXLOGLEN 1024 /* max length of /usr/adm/consoles/foo */
|
||||
#define MAXTTYLINE (133*2) /* max length of a single buf'd line */
|
||||
#define ALARMTIME 60 /* time between chimes */
|
||||
|
||||
typedef struct consent { /* console information */
|
||||
char server[MAXSERVLEN];/* server name */
|
||||
char dfile[MAXDEVLEN]; /* device file */
|
||||
char lfile[MAXLOGLEN]; /* log file */
|
||||
BAUD *pbaud; /* the baud on this console port */
|
||||
PARITY *pparity; /* the parity on this line */
|
||||
int mark; /* Mark (chime) interval */
|
||||
long nextMark; /* Next mark (chime) time */
|
||||
|
||||
/* Used if network console */
|
||||
int isNetworkConsole;
|
||||
char networkConsoleHost[MAXSERVLEN];
|
||||
int networkConsolePort;
|
||||
|
||||
#if DO_VIRTUAL
|
||||
/* used if virtual console */
|
||||
char acslave[MAXDEVLEN];/* pseudo-device slave side */
|
||||
int fvirtual; /* is a pty device we use as a console */
|
||||
char *pccmd; /* virtual console command */
|
||||
int ipid; /* pid of virtual command */
|
||||
#endif
|
||||
/* only used in child */
|
||||
int nolog; /* don't log output */
|
||||
int fdlog; /* the local log file */
|
||||
int fdtty; /* the port to talk to machine on */
|
||||
short int fup; /* we setup this line? */
|
||||
short int fronly; /* we can only read this console */
|
||||
short int iend; /* like icursor in CLIENT */
|
||||
short int inamelen; /* strlen(server) */
|
||||
struct client *pCLon; /* clients on this console */
|
||||
struct client *pCLwr; /* client that is writting on console */
|
||||
char acline[132*2+2]; /* max chars we will call a line */
|
||||
} CONSENT;
|
||||
|
||||
extern PARITY *FindParity();
|
||||
extern BAUD *FindBaud();
|
||||
extern void ConsInit();
|
||||
extern void ConsDown();
|
78
conserver/conserver.8l
Normal file
78
conserver/conserver.8l
Normal file
@ -0,0 +1,78 @@
|
||||
.\" @(#)conserver.8 01/06/91 OSU CIS; Thomas A. Fine
|
||||
.\" $Id: conserver.8l,v 2.3 93/02/09 11:51:56 ldv Exp $
|
||||
.TH CONSERVER 8L "LOCAL"
|
||||
.SH NAME
|
||||
conserver \- console server daemon
|
||||
.SH SYNOPSIS
|
||||
.B conserver [\-\fBnv\fP] [\-\fBC\fP \fIconfig\fP]
|
||||
.br
|
||||
.B conserver [\-\fBhV\fP]
|
||||
.SH DESCRIPTION
|
||||
.B Conserver
|
||||
is the daemon for the
|
||||
.IR console (1L)
|
||||
program.
|
||||
It provides remote access to the server consoles,
|
||||
and logs all console data.
|
||||
Slave hosts which have no current connection might produce important
|
||||
error messages, these unloved errors are labeled with a machine name
|
||||
and output on stdout.
|
||||
.PP
|
||||
When started, it forks a child for each group in /usr/local/etc/conserver.cf,
|
||||
and assigns each process a port number to listen on.
|
||||
The \fIconsole\fP client program knows how to request port numbers and
|
||||
forwards to find the various slave hosts.
|
||||
.PP
|
||||
.B Conserver
|
||||
completely controls any connection to a controlled host.
|
||||
All handling of escape sequenes is done by the server,
|
||||
except the suspend sequence which is
|
||||
sent as an out-of-band command to the client.
|
||||
.PP
|
||||
The
|
||||
.B conserver
|
||||
parent process will automatically respawn any child process that dies.
|
||||
If the parent process receives a SIGTERM, it will propogate the signal
|
||||
to its children.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BI \-C config
|
||||
With this option the invoker may specify an alternate confguration.
|
||||
The default \fIconfig\fP is /usr/local/lib/conserver.cf.
|
||||
.TP
|
||||
.B \-h
|
||||
Output a brief help message.
|
||||
.TP
|
||||
.B \-n
|
||||
The \fIconserver\fP will \fBnot\fP output unloved console output to
|
||||
stdout.
|
||||
.TP
|
||||
.B \-v
|
||||
Echo the configuration as it is being read (be verbose).
|
||||
.TP
|
||||
.B \-V
|
||||
Output the version of the console server (only) and exit.
|
||||
.SH EXAMPLES
|
||||
conserver: expert: login ksb
|
||||
.br
|
||||
tyro: panic: my brain hurts
|
||||
.br
|
||||
conserver: ksb shifts from expert to tyro
|
||||
.br
|
||||
conserver: tyro: logout ksb
|
||||
.br
|
||||
\...
|
||||
.SH FILES
|
||||
.TS
|
||||
l l.
|
||||
/usr/local/lib/conserver.cf description of console terminal lines
|
||||
/usr/adm/\fIhost\fP.console log files for \fIhost\fP's console
|
||||
/dev/tty?? terminal line device files
|
||||
\fIstdout\fP summary of unloved console errors
|
||||
.TE
|
||||
.SH AUTHORS
|
||||
Thomas A. Fine, Ohio State Computer Science
|
||||
.br
|
||||
Kevin S Braunsdorf, Purdue University Computing Center
|
||||
.SH "SEE ALSO"
|
||||
console(1L), conserver.cf(5L)
|
78
conserver/conserver.man
Normal file
78
conserver/conserver.man
Normal file
@ -0,0 +1,78 @@
|
||||
.\" @(#)conserver.8 01/06/91 OSU CIS; Thomas A. Fine
|
||||
.\" $Id: conserver.man,v 2.3 93/02/09 11:51:56 ldv Exp $
|
||||
.TH CONSERVER 8L "LOCAL"
|
||||
.SH NAME
|
||||
conserver \- console server daemon
|
||||
.SH SYNOPSIS
|
||||
.B conserver [\-\fBnv\fP] [\-\fBC\fP \fIconfig\fP]
|
||||
.br
|
||||
.B conserver [\-\fBhV\fP]
|
||||
.SH DESCRIPTION
|
||||
.B Conserver
|
||||
is the daemon for the
|
||||
.IR console (1L)
|
||||
program.
|
||||
It provides remote access to the server consoles,
|
||||
and logs all console data.
|
||||
Slave hosts which have no current connection might produce important
|
||||
error messages, these unloved errors are labeled with a machine name
|
||||
and output on stdout.
|
||||
.PP
|
||||
When started, it forks a child for each group in /usr/local/etc/conserver.cf,
|
||||
and assigns each process a port number to listen on.
|
||||
The \fIconsole\fP client program knows how to request port numbers and
|
||||
forwards to find the various slave hosts.
|
||||
.PP
|
||||
.B Conserver
|
||||
completely controls any connection to a controlled host.
|
||||
All handling of escape sequenes is done by the server,
|
||||
except the suspend sequence which is
|
||||
sent as an out-of-band command to the client.
|
||||
.PP
|
||||
The
|
||||
.B conserver
|
||||
parent process will automatically respawn any child process that dies.
|
||||
If the parent process receives a SIGTERM, it will propogate the signal
|
||||
to its children.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BI \-C config
|
||||
With this option the invoker may specify an alternate confguration.
|
||||
The default \fIconfig\fP is /usr/local/lib/conserver.cf.
|
||||
.TP
|
||||
.B \-h
|
||||
Output a brief help message.
|
||||
.TP
|
||||
.B \-n
|
||||
The \fIconserver\fP will \fBnot\fP output unloved console output to
|
||||
stdout.
|
||||
.TP
|
||||
.B \-v
|
||||
Echo the configuration as it is being read (be verbose).
|
||||
.TP
|
||||
.B \-V
|
||||
Output the version of the console server (only) and exit.
|
||||
.SH EXAMPLES
|
||||
conserver: expert: login ksb
|
||||
.br
|
||||
tyro: panic: my brain hurts
|
||||
.br
|
||||
conserver: ksb shifts from expert to tyro
|
||||
.br
|
||||
conserver: tyro: logout ksb
|
||||
.br
|
||||
\...
|
||||
.SH FILES
|
||||
.TS
|
||||
l l.
|
||||
/usr/local/lib/conserver.cf description of console terminal lines
|
||||
/usr/adm/\fIhost\fP.console log files for \fIhost\fP's console
|
||||
/dev/tty?? terminal line device files
|
||||
\fIstdout\fP summary of unloved console errors
|
||||
.TE
|
||||
.SH AUTHORS
|
||||
Thomas A. Fine, Ohio State Computer Science
|
||||
.br
|
||||
Kevin S Braunsdorf, Purdue University Computing Center
|
||||
.SH "SEE ALSO"
|
||||
console(1L), conserver.cf(5L)
|
4
conserver/conserver.passwd
Normal file
4
conserver/conserver.passwd
Normal file
@ -0,0 +1,4 @@
|
||||
bryan:r71mXjfALB5Ak:any
|
||||
djs:r71mXjfALB5Ak:login
|
||||
chogan:*passwd*:foobar,login,shell
|
||||
hogan:*passwd*:any
|
234
conserver/fallback.c
Normal file
234
conserver/fallback.c
Normal file
@ -0,0 +1,234 @@
|
||||
/*
|
||||
* $Id: fallback.c,v 5.18 1994-07-19 08:25:54-07 ksb Exp $
|
||||
*
|
||||
* This is a fake library interface to ptyd (mtr&ksb)
|
||||
*
|
||||
* Mike Rowan (mtr@mace.cc.purdue.edu)
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/un.h>
|
||||
#include <syslog.h>
|
||||
#include <signal.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "cons.h"
|
||||
|
||||
#if HAVE_PTSNAME
|
||||
/* for grantpt() and unlockpt() (gregf)
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#if NEED_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if USE_STRINGS
|
||||
#include <strings.h>
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#if DO_VIRTUAL && ! HAVE_PTYD
|
||||
|
||||
extern int errno;
|
||||
#if !HAVE_STRERROR
|
||||
extern char *sys_errlist[], *strchr();
|
||||
#define strerror(Me) (sys_errlist[Me])
|
||||
#endif
|
||||
|
||||
|
||||
static char *__pty_host;
|
||||
static char *__pty_fmt;
|
||||
|
||||
static int iLogPri = LOG_DEBUG;
|
||||
|
||||
|
||||
/*
|
||||
* Below is the string for finding /dev/ptyXX. For each architecture we
|
||||
* leave some pty's world writable because we don't have source for
|
||||
* everything that uses pty's. For the most part, we'll be trying to
|
||||
* make /dev/ptyq* the "free" pty's.
|
||||
*/
|
||||
#if defined(sun)
|
||||
static char charone[] =
|
||||
"prstuvwxyzPQRSTUVWq";
|
||||
#else
|
||||
#if defined(dynix)
|
||||
static char charone[] =
|
||||
"prstuvwxyzPQRSTUVWq";
|
||||
#else
|
||||
#if defined(ultrix)
|
||||
static char charone[] =
|
||||
"prstuvwxyzPQRSTUVWq";
|
||||
#else
|
||||
/* all the world's a vax ;-) */
|
||||
static char charone[] =
|
||||
"prstuvwxyzPQRSTUVWq";
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static char chartwo[] =
|
||||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
|
||||
#if (defined(_AIX) || defined(PTX4))
|
||||
static char acMaster[] =
|
||||
"/dev/ptc/XXXXXXXXX";
|
||||
static char acSlave[] =
|
||||
"/dev/pts/XXXXXXXXX";
|
||||
#else
|
||||
static char acMaster[] =
|
||||
"/dev/ptyXX";
|
||||
static char acSlave[] =
|
||||
"/dev/ttyXX";
|
||||
#endif /* _AIX */
|
||||
|
||||
#if !HAVE_GETPSEUDO
|
||||
#ifdef _AIX
|
||||
/*
|
||||
* get a pty for the user (emulate the neato sequent call) (mm)
|
||||
*/
|
||||
static int
|
||||
getpseudotty(slave, master)
|
||||
char **master, **slave;
|
||||
{
|
||||
int fd;
|
||||
char *pcName, *pcTmp;
|
||||
|
||||
if (0 > (fd = open("/dev/ptc", O_RDWR|O_NDELAY, 0))) {
|
||||
return -1;
|
||||
}
|
||||
if ((char *)0 == (pcName = ttyname(fd))) {
|
||||
return -1;
|
||||
}
|
||||
(void)strcpy(acSlave, pcName);
|
||||
*slave = acSlave;
|
||||
|
||||
(void)strcpy(acMaster, pcName);
|
||||
acMaster[7] = 'c';
|
||||
*master = acMaster;
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
#else
|
||||
#if HAVE_PTSNAME
|
||||
|
||||
/* get a pty for the user -- emulate the neato sequent call under (gregf)
|
||||
* DYNIX/ptx v4.0
|
||||
*/
|
||||
static int
|
||||
getpseudotty(slave, master)
|
||||
char **master, **slave;
|
||||
{
|
||||
int fd;
|
||||
char *pcName, *pcTmp;
|
||||
|
||||
if (0 > (fd = open("/dev/ptmx", O_RDWR, 0))) {
|
||||
return -1;
|
||||
}
|
||||
grantpt(fd); /* change permission of slave */
|
||||
unlockpt(fd); /* unlock slave */
|
||||
if ((char *)0 == (pcName = ttyname(fd))) {
|
||||
return -1;
|
||||
}
|
||||
(void)strcpy(acMaster, pcName);
|
||||
*master = acMaster;
|
||||
|
||||
if ((char *) 0 == (pcName = ptsname(fd))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
(void)strcpy(acSlave, pcName);
|
||||
*slave = acSlave;
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
#else
|
||||
/*
|
||||
* get a pty for the user (emulate the neato sequent call) (ksb)
|
||||
*/
|
||||
static int
|
||||
getpseudotty(slave, master)
|
||||
char **master, **slave;
|
||||
{
|
||||
static char *pcOne = charone, *pcTwo = chartwo;
|
||||
auto int fd, iLoop, iIndex = sizeof("/dev/pty")-1;
|
||||
auto char *pcOld1;
|
||||
auto struct stat statBuf;
|
||||
|
||||
iLoop = 0;
|
||||
pcOld1 = pcOne;
|
||||
for (;;) {
|
||||
if ('\000' == *++pcTwo) {
|
||||
pcTwo = chartwo;
|
||||
if ('\000' == *++pcOne) {
|
||||
pcOne = charone;
|
||||
if (pcOld1 == pcOne && ++iLoop > 1 || iLoop > 32)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
acMaster[iIndex] = *pcOne;
|
||||
acMaster[iIndex+1] = *pcTwo;
|
||||
|
||||
/*
|
||||
* Remeber we are root - stat the file
|
||||
* to see if it exists before we open it
|
||||
* for read/write - if it doesn't we don't
|
||||
* have any pty's left in the row
|
||||
*/
|
||||
if (-1 == stat(acMaster, &statBuf) || S_IFCHR != (statBuf.st_mode&S_IFMT)) {
|
||||
pcTwo = "l";
|
||||
continue;
|
||||
}
|
||||
|
||||
if (0 > (fd = open(acMaster, O_RDWR|O_NDELAY, 0))) {
|
||||
continue;
|
||||
}
|
||||
acSlave[iIndex] = *pcOne;
|
||||
acSlave[iIndex+1] = *pcTwo;
|
||||
if (-1 == access(acSlave, F_OK)) {
|
||||
(void) close(fd);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
*master = acMaster;
|
||||
*slave = acSlave;
|
||||
return fd;
|
||||
}
|
||||
#endif /* PTX version */
|
||||
#endif /* _AIX */
|
||||
#endif /* !HAVE_GETPSEUDO */
|
||||
|
||||
/*
|
||||
* get a Joe pty bacause the daemon is not with us, sadly. (ksb)
|
||||
*/
|
||||
int
|
||||
FallBack(pcSlave, pcMaster)
|
||||
char *pcSlave, *pcMaster;
|
||||
{
|
||||
auto int fd;
|
||||
auto char *pcTSlave, *pcTMaster;
|
||||
|
||||
if (-1 == (fd = getpseudotty(& pcTSlave, & pcTMaster))) {
|
||||
return -1;
|
||||
}
|
||||
(void) strcpy(pcSlave, pcTSlave);
|
||||
(void) strcpy(pcMaster, pcTMaster);
|
||||
return fd;
|
||||
}
|
||||
|
||||
#endif /* no code if it is not used */
|
1643
conserver/group.c
Normal file
1643
conserver/group.c
Normal file
File diff suppressed because it is too large
Load Diff
42
conserver/group.h
Normal file
42
conserver/group.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* $Id: group.h,v 5.8 1994-07-19 09:40:23-07 ksb Exp $
|
||||
*
|
||||
* Copyright 1992 Purdue Research Foundation, West Lafayette, Indiana
|
||||
* 47907. All rights reserved.
|
||||
*
|
||||
* Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
|
||||
*
|
||||
* This software is not subject to any license of the American Telephone
|
||||
* and Telegraph Company or the Regents of the University of California.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose on
|
||||
* any computer system, and to alter it and redistribute it freely, subject
|
||||
* to the following restrictions:
|
||||
*
|
||||
* 1. Neither the authors nor Purdue University are responsible for any
|
||||
* consequences of the use of this software.
|
||||
*
|
||||
* 2. The origin of this software must not be misrepresented, either by
|
||||
* explicit claim or by omission. Credit to the authors and Purdue
|
||||
* University must appear in documentation and sources.
|
||||
*
|
||||
* 3. Altered versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*/
|
||||
|
||||
#define MAXPSWDLEN 16 /* max length of encrypted password */
|
||||
|
||||
typedef struct grpent { /* group info */
|
||||
int port; /* port group listens on */
|
||||
int pid; /* pid of server for group */
|
||||
int imembers; /* number of consoles in this group */
|
||||
CONSENT *pCElist; /* list of consoles in this group */
|
||||
CLIENT *pCLall; /* all clients to scan after select */
|
||||
char passwd[MAXPSWDLEN];/* encrypted password for this group */
|
||||
} GRPENT;
|
||||
|
||||
|
||||
extern void Spawn();
|
||||
extern int CheckPass();
|
179
conserver/identd.c
Normal file
179
conserver/identd.c
Normal file
@ -0,0 +1,179 @@
|
||||
/*@Header@*/
|
||||
/*
|
||||
* ident_client.c
|
||||
*
|
||||
* Identifies the remote user of a given connection.
|
||||
*
|
||||
* Written 940112 by Luke Mewburn <lm@rmit.edu.au>
|
||||
*
|
||||
* Copyright (C) 1994 by Luke Mewburn.
|
||||
* This code may be used freely by anyone as long as this copyright remains.
|
||||
*
|
||||
* $Compile(*): ${cc-cc} ${cc_debug--g} -DTEST %f -o %F -lsocket -lnls
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "identd.h"
|
||||
|
||||
#define IDENT_PORT 113
|
||||
|
||||
|
||||
/*@Explode cli@*/
|
||||
/* (lm)
|
||||
* ident_client
|
||||
* - user interface to identd
|
||||
*
|
||||
* Args:
|
||||
* peeraddr sockaddr_in struct of peer end, from getpeername(...)
|
||||
* ouraddr sockaddr_in struct of local end, from getsockname(...)
|
||||
*
|
||||
* Returns:
|
||||
* NULL on failure to identify (for whatever reason), or pointer to
|
||||
* static character string with the identity.
|
||||
*/
|
||||
char *
|
||||
ident_client(peeraddr, ouraddr, identifier)
|
||||
struct sockaddr_in peeraddr, ouraddr;
|
||||
char *identifier/*[1024]*/;
|
||||
{
|
||||
struct sockaddr_in authcon;
|
||||
int authfd, authlen;
|
||||
struct servent *identserv;
|
||||
int identport;
|
||||
|
||||
FILE *authfpin, *authfpout;
|
||||
char buffer[8192]; /* XXX: argh! magic numbers */
|
||||
char reply_type[81];
|
||||
char opsys_or_err[81];
|
||||
int rport, lport;
|
||||
|
||||
|
||||
authfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (authfd == -1)
|
||||
return NULL;
|
||||
|
||||
identserv = getservbyname("ident", "tcp");
|
||||
if (identserv)
|
||||
identport = identserv->s_port;
|
||||
else
|
||||
identport = ntohs(IDENT_PORT);
|
||||
|
||||
memset(&authcon, 0, sizeof(authcon));
|
||||
authcon.sin_family = AF_INET;
|
||||
authcon.sin_addr.s_addr = peeraddr.sin_addr.s_addr;
|
||||
authcon.sin_port = identport;
|
||||
|
||||
authlen = sizeof(authcon);
|
||||
if (connect(authfd, (struct sockaddr *)&authcon, authlen) < 0)
|
||||
return NULL;
|
||||
|
||||
authfpin = fdopen(authfd, "r");
|
||||
authfpout = fdopen(authfd, "w");
|
||||
if (!authfpin || !authfpout)
|
||||
return NULL;
|
||||
|
||||
fprintf(authfpout, "%d , %d\n", peeraddr.sin_port, ouraddr.sin_port);
|
||||
fflush(authfpout);
|
||||
|
||||
if (fgets(buffer, sizeof(buffer)-1, authfpin) == NULL)
|
||||
return NULL;
|
||||
|
||||
shutdown(authfd, 1);
|
||||
|
||||
authlen = sscanf(buffer, "%d , %d : %[^ \t\n\r:] : %[^ \t\n\r:] : %[^\n\r]",
|
||||
&lport, &rport, reply_type, opsys_or_err, identifier);
|
||||
if (authlen < 3)
|
||||
return NULL;
|
||||
|
||||
if (0 == strcasecmp(reply_type, "ERROR")) {
|
||||
printf("error %s\n", buffer);
|
||||
return NULL;
|
||||
}
|
||||
if (0 != strcasecmp(reply_type, "USERID")) {
|
||||
printf("no-user %s\n", buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return identifier;
|
||||
} /* ident_client */
|
||||
|
||||
/*@Remove@*/
|
||||
#if defined(TEST)
|
||||
|
||||
/*@Explode main@*/
|
||||
extern int errno;
|
||||
extern char *sys_errlist[];
|
||||
#define strerror(Me) (sys_errlist[Me])
|
||||
|
||||
static struct sockaddr_in master_port, response_port;
|
||||
|
||||
char *progname = "identd-test";
|
||||
|
||||
/* test driver for the identd client module (ksb)
|
||||
* bind to a port, wait for telnets and tell them who they are
|
||||
*/
|
||||
int
|
||||
main(argc, argv, envp)
|
||||
int argc;
|
||||
char **argv, **envp;
|
||||
{
|
||||
auto struct sockaddr_in hisaddr, ouraddr;
|
||||
register int mfd, cfd;
|
||||
auto int true = 1, length, so;
|
||||
auto char them[1024];
|
||||
|
||||
(void)memset((void *)&master_port, 0, sizeof(master_port));
|
||||
master_port.sin_family = AF_INET;
|
||||
*(u_long *)&master_port.sin_addr = INADDR_ANY;
|
||||
master_port.sin_port = htons(7098);
|
||||
|
||||
if (-1 == (mfd = socket(AF_INET, SOCK_STREAM, 0))) {
|
||||
fprintf(stderr, "%s: socket: %s\n", progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
#if defined(SO_REUSEADDR) && defined(SOL_SOCKET)
|
||||
if (setsockopt(mfd, SOL_SOCKET, SO_REUSEADDR, (char *)&true, sizeof(true)) < 0) {
|
||||
fprintf(stderr, "%s: setsockopt: %s\n", progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
if (bind(mfd, (struct sockaddr *)&master_port, sizeof(master_port))<0) {
|
||||
fprintf(stderr, "%s: bind: %s\n", progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (listen(mfd, SOMAXCONN) < 0) {
|
||||
fprintf(stderr, "%s: listen: %s\n", progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
length = sizeof(ouraddr);
|
||||
if (getsockname(mfd, (struct sockaddr *)&ouraddr, &length) < 0) {
|
||||
fprintf(stderr, "%s: getsockname: %d: %s\n", progname, mfd, strerror(errno));
|
||||
|
||||
}
|
||||
|
||||
while (so = sizeof(response_port), -1 != (cfd = accept(mfd, (struct sockaddr *)&response_port, &so))) {
|
||||
printf("%d\n", cfd);
|
||||
length = sizeof(hisaddr);
|
||||
if (getpeername(cfd, (struct sockaddr *)&hisaddr, &length) < 0) {
|
||||
write(cfd, "can't get your addrees?\n", 24);
|
||||
} else if ((char *)0 != ident_client(hisaddr, ouraddr, them)) {
|
||||
write(cfd, them, strlen(them));
|
||||
write(cfd, "\n", 1);
|
||||
} else {
|
||||
write(cfd, "no identd?\n", 11);
|
||||
}
|
||||
close(cfd);
|
||||
printf("closed\n");
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
/*@Remove@*/
|
||||
#endif /* test driver */
|
26
conserver/init.script
Executable file
26
conserver/init.script
Executable file
@ -0,0 +1,26 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Startup for conserver
|
||||
#
|
||||
|
||||
PATH=/usr/bin:/usr/local/bin
|
||||
|
||||
case "$1" in
|
||||
'start')
|
||||
LF=/var/log/conserver.log
|
||||
echo "Starting console server daemon"
|
||||
[ -f $LF ] && mv $LF $LF.old
|
||||
conserver -n -d > $LF 2>&1
|
||||
;;
|
||||
|
||||
'stop')
|
||||
master=`ps -ef | grep conserver | awk '$3 == "1"{print $2}'`
|
||||
[ "$master" ] && kill -TERM $master
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage: $0 { start | stop }"
|
||||
;;
|
||||
|
||||
esac
|
||||
exit 0
|
380
conserver/main.c
Normal file
380
conserver/main.c
Normal file
@ -0,0 +1,380 @@
|
||||
/*
|
||||
* Copyright (c) 1990 The Ohio State University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by The Ohio State University and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include "cons.h"
|
||||
#include "consent.h"
|
||||
#include "client.h"
|
||||
#include "group.h"
|
||||
#include "master.h"
|
||||
#include "access.h"
|
||||
#include "readcfg.h"
|
||||
#include "version.h"
|
||||
#if USE_STRINGS
|
||||
#include <strings.h>
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
char rcsid[] =
|
||||
"$Id: main.c,v 5.27 1998-11-19 14:32:45-08 bryan Exp $";
|
||||
char *progname =
|
||||
rcsid;
|
||||
int fAll = 1, fVerbose = 0, fSoftcar = 0;
|
||||
int fDaemon = 0;
|
||||
char chDefAcc = 'r';
|
||||
char *pcConfig = CONFIG;
|
||||
int domainHack = 0;
|
||||
|
||||
#if defined(SERVICE)
|
||||
char acService[] = SERVICE;
|
||||
#endif
|
||||
|
||||
struct sockaddr_in in_port;
|
||||
char acMyAddr[4]; /* "\200\76\7\1" */
|
||||
char acMyHost[256]; /* staff.cc.purdue.edu */
|
||||
|
||||
/* become a daemon (ksb)
|
||||
*/
|
||||
static void
|
||||
daemonize()
|
||||
{
|
||||
int res, td;
|
||||
|
||||
(void) signal(SIGQUIT, SIG_IGN);
|
||||
(void) signal(SIGINT, SIG_IGN);
|
||||
#if defined(SIGTTOU)
|
||||
(void) signal(SIGTTOU, SIG_IGN);
|
||||
#endif
|
||||
#if defined(SIGTSTP)
|
||||
(void) signal(SIGTSTP, SIG_IGN);
|
||||
#endif
|
||||
|
||||
switch (res = fork()) {
|
||||
case -1:
|
||||
(void) fprintf(stderr, "%s: fork: %m\n", progname, strerror(errno));
|
||||
exit(1);
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
sleep(1);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* if we read from stdin (by accident) we don't wanna block
|
||||
*/
|
||||
close(0);
|
||||
if (0 != open("/dev/null", 2, 0644)) {
|
||||
fprintf(stderr, "%s: open: /dev/null: %s\n", progname, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Further disassociate this process from the terminal
|
||||
* Maybe this will allow you to start a daemon from rsh,
|
||||
* i.e. with no controlling terminal.
|
||||
*/
|
||||
#if HAVE_SETSID
|
||||
(void)setsid();
|
||||
#else
|
||||
(void) setpgrp(0, getpid());
|
||||
|
||||
/* lose our controlling terminal
|
||||
*/
|
||||
if (-1 != (td = open("/dev/tty", O_RDWR, 0600))) {
|
||||
(void)ioctl(td, TIOCNOTTY, (char *)0);
|
||||
close(td);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static char *apcLong[] = {
|
||||
"a type set the default access type",
|
||||
"C config give a new config file to the server process",
|
||||
"d become a daemon, output to /dev/null",
|
||||
"h output this message",
|
||||
"n do not output summary stream to stdout",
|
||||
"v be verbose on startup",
|
||||
"V output version info",
|
||||
(char *)0
|
||||
};
|
||||
|
||||
/* output a long message to the user (ksb)
|
||||
*/
|
||||
static void
|
||||
Usage(fp, ppc)
|
||||
FILE *fp;
|
||||
char **ppc;
|
||||
{
|
||||
for (/* passed */; (char *)0 != *ppc; ++ppc)
|
||||
(void)fprintf(fp, "%s\n", *ppc);
|
||||
}
|
||||
|
||||
/* show the user our version info (ksb)
|
||||
*/
|
||||
static void
|
||||
Version()
|
||||
{
|
||||
auto char acA1[16], acA2[16];
|
||||
|
||||
printf("%s: %s\n", progname, GNAC_VERSION);
|
||||
printf("%s: default access type `%c\'\n", progname, chDefAcc);
|
||||
printf("%s: default escape sequence `%s%s\'\n", progname, FmtCtl(DEFATTN, acA1), FmtCtl(DEFESC, acA2));
|
||||
printf("%s: configuration in `%s\'\n", progname, pcConfig);
|
||||
printf("%s: password in `%s\'\n", progname, PASSWD_FILE);
|
||||
printf("%s: limited to %d group%s with %d member%s\n", progname, MAXGRP, MAXGRP == 1 ? "" : "s", MAXMEMB, MAXMEMB == 1 ? "" : "s");
|
||||
#if defined(SERVICE)
|
||||
{
|
||||
struct servent *pSE;
|
||||
if ((struct servent *)0 == (pSE = getservbyname(acService, "tcp"))) {
|
||||
fprintf(stderr, "%s: getservbyname: %s: %s\n", progname, acService, strerror(errno));
|
||||
return;
|
||||
}
|
||||
printf("%s: service name `%s\'", progname, pSE->s_name);
|
||||
if (0 != strcmp(pSE->s_name, acService)) {
|
||||
printf(" (which we call `%s\')", acService);
|
||||
}
|
||||
printf(" on port %d\n", ntohs((u_short)pSE->s_port));
|
||||
}
|
||||
#else
|
||||
#if defined(PORT)
|
||||
printf("%s: on port %d\n", progname, PORT);
|
||||
#else
|
||||
printf("%s: no service or port compiled in\n", progname);
|
||||
exit(1);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* find out where/who we are (ksb)
|
||||
* parse optons
|
||||
* read in the config file, open the log file
|
||||
* spawn the kids to drive the console groups
|
||||
* become the master server
|
||||
* shutdown with grace
|
||||
* exit happy
|
||||
*/
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
register int i, j;
|
||||
register FILE *fpConfig;
|
||||
auto struct hostent *hpMe;
|
||||
static char acOpts[] = "a:C:dhnsVv",
|
||||
u_terse[] = " [-dhnsvV] [-a type] [-C config]";
|
||||
extern int optopt;
|
||||
extern char *optarg;
|
||||
auto REMOTE
|
||||
*pRCUniq; /* list of uniq console servers */
|
||||
|
||||
if ((char *)0 == (progname = strrchr(argv[0], '/'))) {
|
||||
progname = argv[0];
|
||||
} else {
|
||||
++progname;
|
||||
}
|
||||
|
||||
(void)setpwent();
|
||||
#if USE_SETLINEBUF
|
||||
setlinebuf(stderr);
|
||||
#endif
|
||||
#if USE_SETVBUF
|
||||
setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
|
||||
#endif
|
||||
|
||||
(void)gethostname(acMyHost, sizeof(acMyHost));
|
||||
if ((struct hostent *)0 == (hpMe = gethostbyname(acMyHost))) {
|
||||
fprintf(stderr, "%s: gethostbyname: %s\n", progname, hstrerror(h_errno));
|
||||
exit(1);
|
||||
}
|
||||
if (sizeof(acMyAddr) != hpMe->h_length || AF_INET != hpMe->h_addrtype) {
|
||||
fprintf(stderr, "%s: wrong address size (%d != %d) or adress family (%d != %d)\n", progname, sizeof(acMyAddr), hpMe->h_length, AF_INET, hpMe->h_addrtype);
|
||||
exit(1);
|
||||
}
|
||||
#if USE_STRINGS
|
||||
(void)bcopy(hpMe->h_addr, &acMyAddr[0], hpMe->h_length);
|
||||
#else
|
||||
(void)memcpy(&acMyAddr[0], hpMe->h_addr, hpMe->h_length);
|
||||
#endif
|
||||
|
||||
while (EOF != (i = getopt(argc, argv, acOpts))) {
|
||||
switch (i) {
|
||||
case 'a':
|
||||
chDefAcc = '\000' == *optarg ? 'r' : *optarg;
|
||||
if (isupper(chDefAcc)) {
|
||||
chDefAcc = tolower(chDefAcc);
|
||||
}
|
||||
switch (chDefAcc) {
|
||||
case 'r':
|
||||
case 'a':
|
||||
case 't':
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "%s: unknown access type `%s\'\n", progname, optarg);
|
||||
exit(3);
|
||||
}
|
||||
break;
|
||||
case 'C':
|
||||
pcConfig = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
fDaemon = 1;
|
||||
break;
|
||||
case 'h':
|
||||
fprintf(stderr, "%s: usage%s\n", progname, u_terse);
|
||||
Usage(stdout, apcLong);
|
||||
exit(0);
|
||||
case 'n':
|
||||
fAll = 0;
|
||||
break;
|
||||
case 's':
|
||||
fSoftcar ^= 1;
|
||||
break;
|
||||
case 'V':
|
||||
Version();
|
||||
exit(0);
|
||||
case 'v':
|
||||
fVerbose = 1;
|
||||
break;
|
||||
case '\?':
|
||||
fprintf(stderr, "%s: usage%s\n", progname, u_terse);
|
||||
exit(1);
|
||||
default:
|
||||
fprintf(stderr, "%s: option %c needs a parameter\n", progname, optopt);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Why force root??? Cause of getsp*() calls... */
|
||||
if (0 != geteuid()) {
|
||||
fprintf(stderr, "%s: must be the superuser\n", progname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* read the config file
|
||||
*/
|
||||
if ((FILE *)0 == (fpConfig = fopen(pcConfig, "r"))) {
|
||||
fprintf(stderr, "%s: fopen: %s: %s\n", progname, pcConfig, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
ReadCfg(pcConfig, fpConfig);
|
||||
|
||||
#if USE_FLOCK
|
||||
/* we lock the configuration file so that two identical
|
||||
* conservers will not be running together (but two with
|
||||
* different configurations can run on the same host).
|
||||
*/
|
||||
if (-1 == flock(fileno(fpConfig), LOCK_NB|LOCK_EX)) {
|
||||
fprintf(stderr, "%s: %s is locked, won\'t run more than one conserver?\n", progname, pcConfig);
|
||||
exit(3);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* if no one can use us we need to come up with a default
|
||||
*/
|
||||
if (0 == iAccess) {
|
||||
SetDefAccess(hpMe);
|
||||
}
|
||||
|
||||
#if USE_SETLINEBUF
|
||||
setlinebuf(stdout);
|
||||
#endif
|
||||
#if USE_SETVBUF
|
||||
setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
|
||||
#endif
|
||||
|
||||
(void)fflush(stdout);
|
||||
(void)fflush(stderr);
|
||||
if (fDaemon) {
|
||||
daemonize();
|
||||
}
|
||||
/* spawn all the children, so fix kids has an initial pid
|
||||
*/
|
||||
for (i = 0; i < MAXGRP; ++i) {
|
||||
if (0 == aGroups[i].imembers)
|
||||
continue;
|
||||
if (aGroups[i].imembers) {
|
||||
Spawn(& aGroups[i]);
|
||||
}
|
||||
if (fVerbose) {
|
||||
printf("%s: group %d on port %d\n", progname, i, ntohs((u_short)aGroups[i].port));
|
||||
}
|
||||
for (j = 0; j < aGroups[i].imembers; ++j) {
|
||||
if (-1 != aGroups[i].pCElist[j].fdtty)
|
||||
(void)close(aGroups[i].pCElist[j].fdtty);
|
||||
}
|
||||
}
|
||||
|
||||
if (fVerbose) {
|
||||
for (i = 0; i < iAccess; ++i) {
|
||||
printf("%s: access type '%c' for \"%s\"\n", progname, pACList[i].ctrust, pACList[i].pcwho);
|
||||
}
|
||||
}
|
||||
|
||||
pRCUniq = FindUniq(pRCList);
|
||||
/* output unique console server peers?
|
||||
*/
|
||||
if (fVerbose) {
|
||||
register REMOTE *pRC;
|
||||
for (pRC = pRCUniq; (REMOTE *)0 != pRC; pRC = pRC->pRCuniq) {
|
||||
printf("%s: peer server on `%s'\n", progname, pRC->rhost);
|
||||
}
|
||||
}
|
||||
|
||||
(void)fflush(stdout);
|
||||
(void)fflush(stderr);
|
||||
/*
|
||||
if (fDaemon) {
|
||||
daemonize();
|
||||
}
|
||||
*/
|
||||
Master(pRCUniq);
|
||||
|
||||
/* stop putting kids back, and shoot them
|
||||
*/
|
||||
(void)signal(SIGCHLD, SIG_DFL);
|
||||
for (i = 0; i < MAXGRP; ++i) {
|
||||
if (0 == aGroups[i].imembers)
|
||||
continue;
|
||||
if (-1 == kill(aGroups[i].pid, SIGTERM)) {
|
||||
fprintf(stderr, "%s: kill: %s\n", progname, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
(void)endpwent();
|
||||
(void)fclose(fpConfig);
|
||||
exit(0);
|
||||
}
|
43
conserver/main.h
Normal file
43
conserver/main.h
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* $Id: main.h,v 5.8 1998-11-17 18:42:27-08 bryan Exp $
|
||||
*
|
||||
* Copyright 1992 Purdue Research Foundation, West Lafayette, Indiana
|
||||
* 47907. All rights reserved.
|
||||
*
|
||||
* Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
|
||||
*
|
||||
* This software is not subject to any license of the American Telephone
|
||||
* and Telegraph Company or the Regents of the University of California.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose on
|
||||
* any computer system, and to alter it and redistribute it freely, subject
|
||||
* to the following restrictions:
|
||||
*
|
||||
* 1. Neither the authors nor Purdue University are responsible for any
|
||||
* consequences of the use of this software.
|
||||
*
|
||||
* 2. The origin of this software must not be misrepresented, either by
|
||||
* explicit claim or by omission. Credit to the authors and Purdue
|
||||
* University must appear in documentation and sources.
|
||||
*
|
||||
* 3. Altered versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*/
|
||||
|
||||
/* program options and stuff
|
||||
*/
|
||||
extern char rcsid[];
|
||||
extern char *progname;
|
||||
extern int fAll, fVerbose, fSoftcar, fInteractive;
|
||||
extern char chDefAcc;
|
||||
extern char *pcConfig;
|
||||
extern struct sockaddr_in in_port;
|
||||
extern char acMyHost[];
|
||||
extern int domainHack;
|
||||
|
||||
#if defined(SERVICE)
|
||||
extern char acService[];
|
||||
#endif
|
||||
|
453
conserver/master.c
Normal file
453
conserver/master.c
Normal file
@ -0,0 +1,453 @@
|
||||
/*
|
||||
* $Id: master.c,v 5.19 1998-11-17 23:14:51-08 bryan Exp $
|
||||
*
|
||||
* Copyright (c) 1990 The Ohio State University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by The Ohio State University and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include "cons.h"
|
||||
#include "consent.h"
|
||||
#include "client.h"
|
||||
#include "group.h"
|
||||
#include "access.h"
|
||||
#include "master.h"
|
||||
#include "readcfg.h"
|
||||
#include "version.h"
|
||||
#include "main.h"
|
||||
|
||||
#if USE_STRINGS
|
||||
#include <strings.h>
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#if USE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
#endif
|
||||
#include <sys/resource.h>
|
||||
|
||||
extern char *crypt();
|
||||
extern time_t time();
|
||||
|
||||
|
||||
/* check all the kids and respawn as needed. (fine)
|
||||
* Called when master process receives SIGCHLD
|
||||
*/
|
||||
static SIGRETS
|
||||
FixKids(arg)
|
||||
int arg;
|
||||
{
|
||||
register int i, pid;
|
||||
auto long tyme;
|
||||
auto WAIT_T UWbuf;
|
||||
|
||||
#if HAVE_WAIT3
|
||||
while (-1 != (pid = wait3(& UWbuf, WNOHANG, (struct rusage *)0))) {
|
||||
#else
|
||||
while (-1 != (pid = wait(& UWbuf))) {
|
||||
#endif
|
||||
if (0 == pid) {
|
||||
break;
|
||||
}
|
||||
/* stopped child is just continuted
|
||||
*/
|
||||
if (WIFSTOPPED(UWbuf) && 0 == kill(pid, SIGCONT)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXGRP; ++i) {
|
||||
if (0 == aGroups[i].imembers)
|
||||
continue;
|
||||
if (pid != aGroups[i].pid)
|
||||
continue;
|
||||
|
||||
/* this kid kid is dead, start another
|
||||
*/
|
||||
Spawn(& aGroups[i]);
|
||||
tyme = time((long *)0);
|
||||
printf("%s: %s: exit(%d), restarted %s", progname, aGroups[i].pCElist[0].server, WEXITSTATUS(UWbuf), ctime(&tyme));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int fSawQuit;
|
||||
|
||||
/* kill all the kids and exit.
|
||||
* Called when master process receives SIGTERM
|
||||
*/
|
||||
static SIGRETS
|
||||
QuitIt(arg)
|
||||
int arg;
|
||||
{
|
||||
++fSawQuit;
|
||||
}
|
||||
|
||||
|
||||
/* this routine is used by the master console server process (ksb)
|
||||
*/
|
||||
void
|
||||
Master(pRCUniq)
|
||||
REMOTE
|
||||
*pRCUniq; /* list of uniq console servers */
|
||||
{
|
||||
register char *pcArgs;
|
||||
register int i, j, cfd;
|
||||
register REMOTE *pRC, *pRCFound;
|
||||
register int nr, prnum, found, msfd;
|
||||
register struct hostent *hpPeer;
|
||||
auto char cType;
|
||||
auto int so;
|
||||
auto fd_set rmask, rmaster;
|
||||
auto char acIn[1024], acOut[BUFSIZ];
|
||||
auto struct sockaddr_in master_port, response_port;
|
||||
int true = 1;
|
||||
|
||||
/* set up signal handler */
|
||||
(void)signal(SIGCHLD, FixKids);
|
||||
(void)signal(SIGTERM, QuitIt);
|
||||
|
||||
/* set up port for master to listen on
|
||||
*/
|
||||
#if USE_STRINGS
|
||||
(void)bzero((char *)&master_port, sizeof(master_port));
|
||||
#else
|
||||
(void)memset((void *)&master_port, 0, sizeof(master_port));
|
||||
#endif
|
||||
master_port.sin_family = AF_INET;
|
||||
*(u_long *)&master_port.sin_addr = INADDR_ANY;
|
||||
#if defined(SERVICE)
|
||||
{
|
||||
struct servent *pSE;
|
||||
if ((struct servent *)0 == (pSE = getservbyname(acService, "tcp"))) {
|
||||
fprintf(stderr, "%s: getservbyname: %s: %s\n", progname, acService, strerror(errno));
|
||||
return;
|
||||
}
|
||||
master_port.sin_port = pSE->s_port;
|
||||
}
|
||||
#else
|
||||
#if defined(PORT)
|
||||
master_port.sin_port = htons((u_short)PORT);
|
||||
#else
|
||||
fprintf(stderr, "%s: no port or service compiled in?\n", progname);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if ((msfd=socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
||||
fprintf(stderr, "%s: socket: %s\n", progname, strerror(errno));
|
||||
return;
|
||||
}
|
||||
#if HAVE_SETSOCKOPT
|
||||
if (setsockopt(msfd, SOL_SOCKET, SO_REUSEADDR, (char *)&true, sizeof(true))<0) {
|
||||
fprintf(stderr, "%s: setsockopt: %s\n", progname, strerror(errno));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (bind(msfd, (struct sockaddr *)&master_port, sizeof(master_port))<0) {
|
||||
fprintf(stderr, "%s: bind: %s\n", progname, strerror(errno));
|
||||
return;
|
||||
}
|
||||
if (listen(msfd, SOMAXCONN) < 0) {
|
||||
fprintf(stderr, "%s: listen: %s\n", progname, strerror(errno));
|
||||
}
|
||||
|
||||
FD_ZERO(&rmaster);
|
||||
FD_SET(msfd, &rmaster);
|
||||
for (fSawQuit = 0; !fSawQuit; /* can't close here :-( */) {
|
||||
rmask = rmaster;
|
||||
|
||||
if (-1 == select(msfd+1, &rmask, (fd_set *)0, (fd_set *)0, (struct timeval *)0)) {
|
||||
fprintf(stderr, "%s: select: %s\n", progname, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
if (!FD_ISSET(msfd, &rmask)) {
|
||||
continue;
|
||||
}
|
||||
so = sizeof(response_port);
|
||||
cfd = accept(msfd, (struct sockaddr *)&response_port, &so);
|
||||
if (cfd < 0) {
|
||||
fprintf(stderr, "%s: accept: %s\n", progname, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
so = sizeof(in_port);
|
||||
if (-1 == getpeername(cfd, (struct sockaddr *)&in_port, &so)) {
|
||||
CSTROUT(cfd, "getpeername failed\r\n");
|
||||
(void)close(cfd);
|
||||
continue;
|
||||
}
|
||||
so = sizeof(in_port.sin_addr);
|
||||
if ((struct hostent *)0 == (hpPeer = gethostbyaddr((char *)&in_port.sin_addr, so, AF_INET))) {
|
||||
CSTROUT(cfd, "unknown peer name\r\n");
|
||||
(void)close(cfd);
|
||||
continue;
|
||||
}
|
||||
if ('r' == (cType = AccType(hpPeer))) {
|
||||
CSTROUT(cfd, "access from your host refused\r\n");
|
||||
(void)close(cfd);
|
||||
continue;
|
||||
}
|
||||
|
||||
#if TEST_FORK
|
||||
/* we should fork here, or timeout
|
||||
*/
|
||||
switch(fork()) {
|
||||
default:
|
||||
(void)close(cfd);
|
||||
continue;
|
||||
case -1:
|
||||
CSTROUT(cfd, "fork failed, try again\r\n");
|
||||
(void)close(cfd);
|
||||
continue;
|
||||
case 0:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
/* handle the connection
|
||||
* (port lookup, who, users, or quit)
|
||||
*/
|
||||
CSTROUT(cfd, "ok\r\n");
|
||||
for (i = 0; i < sizeof(acIn); /* i+=nr */) {
|
||||
if (0 >= (nr = read(cfd, &acIn[i], sizeof(acIn)-1-i))) {
|
||||
i = 0;
|
||||
break;
|
||||
}
|
||||
i += nr;
|
||||
if ('\n' == acIn[i-1]) {
|
||||
acIn[i] = '\000';
|
||||
--i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i > 0 && '\n' == acIn[i-1]) {
|
||||
acIn[--i] = '\000';
|
||||
}
|
||||
if (i > 0 && '\r' == acIn[i-1]) {
|
||||
acIn[--i] = '\000';
|
||||
}
|
||||
if (0 == i) {
|
||||
fprintf(stderr, "%s: lost connection\n", progname);
|
||||
(void)close(cfd);
|
||||
#if TEST_FORK
|
||||
exit(1);
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
if ((char *)0 != (pcArgs = strchr(acIn, ':'))) {
|
||||
*pcArgs++ = '\000';
|
||||
} else if ((char *)0 != (pcArgs = strchr(acIn, ' '))) {
|
||||
*pcArgs++ = '\000';
|
||||
}
|
||||
if (0 == strcmp(acIn, "help")) {
|
||||
static char *apcHelp[] = {
|
||||
"call provide port for given machine\r\n",
|
||||
"groups provide ports for group leaders\r\n",
|
||||
"help this help message\r\n",
|
||||
"master provide a list of master servers\r\n",
|
||||
"pid provide pid of master process\r\n",
|
||||
"quit terminate conserver\r\n",
|
||||
"version provide version info for server\r\n",
|
||||
(char *)0
|
||||
};
|
||||
register char **ppc;
|
||||
for (ppc = apcHelp; (char *)0 != *ppc; ++ppc) {
|
||||
(void)write(cfd, *ppc, strlen(*ppc));
|
||||
}
|
||||
(void)close(cfd);
|
||||
#if TEST_FORK
|
||||
exit(0);
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
if (0 == strcmp(acIn, "quit")) {
|
||||
register struct passwd *pwd;
|
||||
|
||||
if ('t' == cType) {
|
||||
CSTROUT(cfd, "trusted -- terminated\r\n");
|
||||
#if TEST_FORK
|
||||
kill(getppid(), SIGTERM);
|
||||
#else
|
||||
fSawQuit = 1;
|
||||
#endif
|
||||
} else if ((char *)0 == pcArgs) {
|
||||
CSTROUT(cfd, "must be trusted to terminate\r\n");
|
||||
} else if ((struct passwd *)0 == (pwd = getpwuid(0))) {
|
||||
CSTROUT(cfd, "no root passwd?\r\n");
|
||||
} else if (0 == CheckPass(pwd, (char *)0, pcArgs)) {
|
||||
CSTROUT(cfd, "Sorry.\r\n");
|
||||
} else {
|
||||
CSTROUT(cfd, "ok -- terminated\r\n");
|
||||
#if TEST_FORK
|
||||
kill(getppid(), SIGTERM);
|
||||
#else
|
||||
fSawQuit = 1;
|
||||
#endif
|
||||
}
|
||||
(void)close(cfd);
|
||||
#if TEST_FORK
|
||||
exit(0);
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
if (0 == strcmp(acIn, "pid")) {
|
||||
#if TEST_FORK
|
||||
sprintf(acOut, "%d\r\n", getppid());
|
||||
(void)write(cfd, acOut, strlen(acOut));
|
||||
exit(0);
|
||||
#else
|
||||
sprintf(acOut, "%d\r\n", getpid());
|
||||
(void)write(cfd, acOut, strlen(acOut));
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
if (0 == strcmp(acIn, "groups")) {
|
||||
register int iSep = 1;
|
||||
|
||||
for (i = 0; i < MAXGRP; ++i) {
|
||||
if (0 == aGroups[i].imembers)
|
||||
continue;
|
||||
sprintf(acOut, ":%d"+iSep, ntohs((u_short)aGroups[i].port));
|
||||
(void)write(cfd, acOut, strlen(acOut));
|
||||
iSep = 0;
|
||||
}
|
||||
CSTROUT(cfd, "\r\n");
|
||||
(void)close(cfd);
|
||||
#if TEST_FORK
|
||||
exit(0);
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
if (0 == strcmp(acIn, "master")) {
|
||||
register int iSep = 1;
|
||||
|
||||
if (0 != iLocal) {
|
||||
sprintf(acOut, "@%s", acMyHost);
|
||||
(void)write(cfd, acOut, strlen(acOut));
|
||||
iSep = 0;
|
||||
}
|
||||
for (pRC = pRCUniq; (REMOTE *)0 != pRC; pRC = pRC->pRCuniq) {
|
||||
sprintf(acOut, ":@%s"+iSep, pRC->rhost);
|
||||
(void)write(cfd, acOut, strlen(acOut));
|
||||
iSep = 0;
|
||||
}
|
||||
CSTROUT(cfd, "\r\n");
|
||||
(void)close(cfd);
|
||||
#if TEST_FORK
|
||||
exit(0);
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
if (0 == strcmp(acIn, "version")) {
|
||||
sprintf(acOut, "version `%s\'\r\n", GNAC_VERSION);
|
||||
(void)write(cfd, acOut, strlen(acOut));
|
||||
#if TEST_FORK
|
||||
exit(0);
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
if (0 != strcmp(acIn, "call")) {
|
||||
CSTROUT(cfd, "unknown command\r\n");
|
||||
(void)close(cfd);
|
||||
#if TEST_FORK
|
||||
exit(0);
|
||||
#else
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* look up the machine to call
|
||||
*/
|
||||
found = 0;
|
||||
pRCFound = (REMOTE *)0;
|
||||
/* look for a local machine */
|
||||
for (i = 0; i < MAXGRP; ++i) {
|
||||
if (0 == aGroups[i].imembers)
|
||||
continue;
|
||||
for (j = 0; j < aGroups[i].imembers; ++j) {
|
||||
if (0 != strcmp(pcArgs, aGroups[i].pCElist[j].server)) {
|
||||
continue;
|
||||
}
|
||||
prnum = ntohs((u_short)aGroups[i].port);
|
||||
++found;
|
||||
}
|
||||
}
|
||||
if ( found == 0 ) { /* Then look for substring matches */
|
||||
for (i = 0; i < MAXGRP; ++i) {
|
||||
if (0 == aGroups[i].imembers)
|
||||
continue;
|
||||
for (j = 0; j < aGroups[i].imembers; ++j) {
|
||||
if (0 != strncmp(pcArgs, aGroups[i].pCElist[j].server, strlen(pcArgs))) {
|
||||
continue;
|
||||
}
|
||||
prnum = ntohs((u_short)aGroups[i].port);
|
||||
++found;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* look for a remote server */
|
||||
for (pRC = pRCList; (REMOTE *)0 != pRC; pRC = pRC->pRCnext) {
|
||||
if (0 != strncmp(pcArgs, pRC->rserver, strlen(pcArgs))) {
|
||||
continue;
|
||||
}
|
||||
++found;
|
||||
pRCFound = pRC;
|
||||
}
|
||||
switch (found) {
|
||||
case 0:
|
||||
sprintf(acOut, "server %s not found\r\n", pcArgs);
|
||||
break;
|
||||
case 1:
|
||||
if ((REMOTE *)0 != pRCFound) {
|
||||
sprintf(acOut, "@%s\r\n", pRCFound->rhost, pcArgs);
|
||||
} else {
|
||||
sprintf(acOut, "%d\r\n", prnum);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
sprintf(acOut, "ambigous server abbreviation, %s\r\n", pcArgs);
|
||||
break;
|
||||
}
|
||||
(void)write(cfd, acOut, strlen(acOut));
|
||||
(void)close(cfd);
|
||||
#if TEST_FORK
|
||||
exit(0);
|
||||
#endif
|
||||
}
|
||||
}
|
32
conserver/master.h
Normal file
32
conserver/master.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* $Id: master.h,v 5.6 1993-02-09 04:01:31-08 ldv Exp $
|
||||
*
|
||||
* Copyright 1992 Purdue Research Foundation, West Lafayette, Indiana
|
||||
* 47907. All rights reserved.
|
||||
*
|
||||
* Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
|
||||
*
|
||||
* This software is not subject to any license of the American Telephone
|
||||
* and Telegraph Company or the Regents of the University of California.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose on
|
||||
* any computer system, and to alter it and redistribute it freely, subject
|
||||
* to the following restrictions:
|
||||
*
|
||||
* 1. Neither the authors nor Purdue University are responsible for any
|
||||
* consequences of the use of this software.
|
||||
*
|
||||
* 2. The origin of this software must not be misrepresented, either by
|
||||
* explicit claim or by omission. Credit to the authors and Purdue
|
||||
* University must appear in documentation and sources.
|
||||
*
|
||||
* 3. Altered versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*/
|
||||
|
||||
/*
|
||||
* stuff the master process needs
|
||||
*/
|
||||
extern void Master();
|
384
conserver/readcfg.c
Normal file
384
conserver/readcfg.c
Normal file
@ -0,0 +1,384 @@
|
||||
/*
|
||||
* $Id: readcfg.c,v 5.21 1998-12-14 11:20:15-08 bryan Exp $
|
||||
*
|
||||
* Copyright (c) 1990 The Ohio State University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by The Ohio State University and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
/*
|
||||
* Network console modifications by Robert Olson, olson@mcs.anl.gov.
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include "cons.h"
|
||||
#include "consent.h"
|
||||
#include "client.h"
|
||||
#include "group.h"
|
||||
#include "access.h"
|
||||
#include "readcfg.h"
|
||||
#include "master.h"
|
||||
#include "main.h"
|
||||
|
||||
#if USE_STRINGS
|
||||
#include <strings.h>
|
||||
#else
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
|
||||
GRPENT
|
||||
aGroups[MAXGRP]; /* even spread is OK */
|
||||
CONSENT
|
||||
aConsoles[MAXGRP*MAXMEMB]; /* gross over allocation */
|
||||
REMOTE
|
||||
*pRCList; /* list of remote consoles we know about */
|
||||
int
|
||||
iLocal; /* number of local consoles */
|
||||
|
||||
ACCESS
|
||||
*pACList; /* `who do you love' (or trust) */
|
||||
int
|
||||
iAccess; /* how many access restrictions we have */
|
||||
|
||||
/* read in the configuration file, fill in all the structs we use (ksb)
|
||||
* to manage the consoles
|
||||
*/
|
||||
void
|
||||
ReadCfg(pcFile, fp)
|
||||
char *pcFile;
|
||||
register FILE *fp;
|
||||
{
|
||||
register GRPENT *pGE;
|
||||
register int iG, minG;
|
||||
auto int iLine;
|
||||
auto char acIn[BUFSIZ];
|
||||
register GRPENT *pGEAll;
|
||||
register CONSENT *pCE;
|
||||
register REMOTE **ppRC;
|
||||
char LogDirectory[MAXLOGLEN];
|
||||
long tyme;
|
||||
|
||||
tyme = time((long *)0);
|
||||
LogDirectory[0] = '\000';
|
||||
pGEAll = aGroups; /* fill in these structs */
|
||||
pCE = aConsoles;
|
||||
ppRC = & pRCList;
|
||||
iLocal = 0;
|
||||
|
||||
iG = minG = 0;
|
||||
iLine = 0;
|
||||
while (fgets(acIn, sizeof(acIn)-1, fp) != NULL) {
|
||||
register char *pcLine, *pcMode, *pcLog, *pcRem, *pcStart, *pcMark;
|
||||
|
||||
++iLine;
|
||||
for (pcRem = acIn+strlen(acIn)-1; pcRem >= acIn; --pcRem) {
|
||||
if (!isspace(*pcRem))
|
||||
break;
|
||||
*pcRem = '\000';
|
||||
if (pcRem == acIn)
|
||||
break;
|
||||
}
|
||||
if ('#' == acIn[0] || '\000' == acIn[0]) {
|
||||
continue;
|
||||
}
|
||||
if ('%' == acIn[0] && '%' == acIn[1] && '\000' == acIn[2]) {
|
||||
break;
|
||||
}
|
||||
if ( (char *)0 == strchr(acIn, ':') &&
|
||||
(char *)0 != (pcLine = strchr(acIn, '=')) ) {
|
||||
*pcLine = '\000';
|
||||
if ( 0 == strcmp(acIn, "LOGDIR") ) {
|
||||
(void)strcpy(LogDirectory, ++pcLine);
|
||||
} else if ( 0 == strcmp(acIn, "DOMAINHACK") ) {
|
||||
domainHack = 1;
|
||||
} else {
|
||||
*pcLine = '=';
|
||||
fprintf(stderr, "%s: %s(%d) bad variable line `%s'\n", progname, pcFile, iLine, acIn);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if ( (char *)0 == (pcLine = strchr(acIn, ':')) ||
|
||||
(char *)0 == (pcMode = strchr(pcLine+1, ':')) ||
|
||||
(char *)0 == (pcLog = strchr(pcMode+1, ':'))) {
|
||||
fprintf(stderr, "%s: %s(%d) bad config line `%s'\n", progname, pcFile, iLine, acIn);
|
||||
continue;
|
||||
}
|
||||
*pcLine++ = '\000';
|
||||
*pcMode++ = '\000';
|
||||
*pcLog++ = '\000';
|
||||
|
||||
if ((char *)0 != (pcMark = strchr(pcLog, ':'))) {
|
||||
*pcMark++ = '\000';
|
||||
/* Skip null intervals */
|
||||
if ( pcMark[0] == '\000' ) pcMark = (char *)0;
|
||||
}
|
||||
|
||||
/* if this server remote?
|
||||
* (contains an '@host' where host is not us)
|
||||
* if so just add it to a linked list of remote hosts
|
||||
* I'm sure most sites will never use this code (ksb)
|
||||
*/
|
||||
if ((char *)0 != (pcRem = strchr(pcLine, '@')) &&
|
||||
((*pcRem++ = '\000'), 0 != strcmp(acMyHost, pcRem))) {
|
||||
register REMOTE *pRCTemp;
|
||||
pRCTemp = (REMOTE *)calloc(1, sizeof(REMOTE));
|
||||
if ((REMOTE *)0 == pRCTemp) {
|
||||
CSTROUT(2, "out of memory!\n");
|
||||
exit(32);
|
||||
}
|
||||
(void)strcpy(pRCTemp->rhost, pcRem);
|
||||
(void)strcpy(pRCTemp->rserver, acIn);
|
||||
*ppRC = pRCTemp;
|
||||
ppRC = & pRCTemp->pRCnext;
|
||||
if (fVerbose) {
|
||||
printf("%s: %s remote on %s\n", progname, acIn, pcRem);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* take the same group as the last line, by default
|
||||
*/
|
||||
if (MAXMEMB == pGEAll[iG].imembers) {
|
||||
++iG;
|
||||
}
|
||||
if (iG < minG || iG >= MAXGRP) {
|
||||
fprintf(stderr, "%s: %s(%d) group number out of bounds %d <= %d < %d\n", progname, pcFile, iLine, minG, iG, MAXGRP);
|
||||
exit(1);
|
||||
}
|
||||
minG = iG;
|
||||
pGE = pGEAll+iG;
|
||||
if (0 == pGE->imembers++) {
|
||||
pGE->pCElist = pCE;
|
||||
}
|
||||
if (pGE->imembers > MAXMEMB) {
|
||||
fprintf(stderr, "%s: %s(%d) group %d has more than %d members -- but we'll give it a spin\n", progname, pcFile, iLine, iG, MAXMEMB);
|
||||
}
|
||||
|
||||
/* fill in the console entry
|
||||
*/
|
||||
if (sizeof(aConsoles)/sizeof(CONSENT) == iLocal) {
|
||||
fprintf(stderr, "%s: %s(%d) %d is too many consoles for hard coded tables, adjust MAXGRP or MAXMEMB\n", progname, pcFile, iLine, iLocal);
|
||||
exit(1);
|
||||
}
|
||||
(void)strcpy(pCE->server, acIn);
|
||||
|
||||
/*
|
||||
* Here we substitute the console name for any '&' character in the
|
||||
* logfile name. That way you can just have something like
|
||||
* "/var/console/&" for each of the conserver.cf entries.
|
||||
*/
|
||||
*(pCE->lfile) = '\000';
|
||||
pcStart = pcLog;
|
||||
while ((char *)0 != (pcRem = strchr(pcStart, '&'))) {
|
||||
*pcRem = '\000';
|
||||
(void)strcat(pCE->lfile, pcStart);
|
||||
(void)strcat(pCE->lfile, acIn);
|
||||
pcStart = pcRem + 1;
|
||||
}
|
||||
(void)strcat(pCE->lfile, pcStart);
|
||||
if ( LogDirectory[0] && (pCE->lfile)[0] != '/' ) {
|
||||
char lfile[MAXLOGLEN];
|
||||
strcpy( lfile, pCE->lfile );
|
||||
strcpy( pCE->lfile, LogDirectory );
|
||||
strcat( pCE->lfile, "/" );
|
||||
strcat( pCE->lfile, lfile );
|
||||
}
|
||||
|
||||
if ( pcMark ) {
|
||||
int factor;
|
||||
char *p;
|
||||
p = pcMark + strlen(pcMark) - 1;
|
||||
if ( *p == 'm' ) {
|
||||
factor = 60;
|
||||
} else if ( *p == 'h' ) {
|
||||
factor = 60 * 60;
|
||||
} else if ( *p == 'd' ) {
|
||||
factor = 60 * 60 * 24;
|
||||
} else {
|
||||
fprintf(stderr, "%s: %s(%d) bad mark specification `%s'\n", progname, pcFile, iLine, pcMark);
|
||||
pcMark = 0;
|
||||
factor = 0;
|
||||
}
|
||||
if ( factor ) {
|
||||
*p = '\000';
|
||||
pCE->mark = atoi(pcMark) * factor;
|
||||
pCE->nextMark = tyme + pCE->mark;
|
||||
if ( pCE->mark < 0 ) {
|
||||
fprintf(stderr, "%s: %s(%d) negative mark specification `%s'\n", progname, pcFile, iLine, pcMark);
|
||||
pcMark = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !pcMark ) {
|
||||
pCE->nextMark = pCE->mark = 0;
|
||||
}
|
||||
|
||||
#if DO_VIRTUAL
|
||||
if (pcLine[0] == '!')
|
||||
{
|
||||
pCE->isNetworkConsole = 1;
|
||||
strcpy(pCE->networkConsoleHost, pcLine + 1);
|
||||
pCE->networkConsolePort = atoi(pcMode);
|
||||
|
||||
if (fVerbose) {
|
||||
printf("%s: %d: %s is network on %s/%d logged to %s\n",
|
||||
progname, iG, acIn, pCE->networkConsoleHost,
|
||||
pCE->networkConsolePort, pCE->lfile);
|
||||
}
|
||||
pCE->fvirtual = 0;
|
||||
sprintf( pCE->dfile, "%s/%d", pCE->networkConsoleHost, pCE->networkConsolePort );
|
||||
pCE->pbaud = FindBaud("Netwk");
|
||||
pCE->pparity = FindParity(" ");
|
||||
}
|
||||
else if ('|' == pcLine[0]) {
|
||||
pCE->isNetworkConsole = 0;
|
||||
pCE->fvirtual = 1;
|
||||
if ((char *)0 == (pCE->pccmd = malloc((strlen(pcLine)|7)+1))) {
|
||||
OutOfMem();
|
||||
}
|
||||
(void)strcpy(pCE->pccmd, pcLine+1);
|
||||
(void)strcpy(pCE->dfile, "/dev/null");
|
||||
} else {
|
||||
pCE->isNetworkConsole = 0;
|
||||
pCE->fvirtual = 0;
|
||||
(void)strcpy(pCE->dfile, pcLine);
|
||||
}
|
||||
pCE->ipid = -1;
|
||||
#else
|
||||
if ('|' == pcLine[0]) {
|
||||
fprintf(stderr, "%s: %s(%d) this server doesn't provide any virtual console support\n", progname, pcFile, iLine);
|
||||
exit(9);
|
||||
}
|
||||
(void)strcpy(pCE->dfile, pcLine);
|
||||
#endif
|
||||
|
||||
if (!pCE->isNetworkConsole)
|
||||
{
|
||||
/* find user baud and parity
|
||||
* default to first table entry for baud and parity
|
||||
*/
|
||||
pCE->pbaud = FindBaud(pcMode);
|
||||
pCE->pparity = FindParity(pcMode);
|
||||
if (fVerbose) {
|
||||
#if DO_VIRTUAL
|
||||
if (pCE->fvirtual)
|
||||
printf("%s: %d: %s with command `%s' logged to %s\n", progname, iG, acIn, pCE->pccmd, pCE->lfile);
|
||||
else
|
||||
#endif
|
||||
printf("%s: %d: %s is on %s (%s%c) logged to %s\n", progname, iG, acIn, pCE->dfile, pCE->pbaud->acrate, pCE->pparity->ckey, pCE->lfile);
|
||||
}
|
||||
}
|
||||
++pCE, ++iLocal;
|
||||
}
|
||||
*ppRC = (REMOTE *)0;
|
||||
|
||||
/* make a vector of access restructions
|
||||
*/
|
||||
iG = iAccess = 0;
|
||||
pACList = (ACCESS *)0;
|
||||
while (fgets(acIn, sizeof(acIn)-1, fp) != NULL) {
|
||||
register char *pcRem, *pcMach, *pcNext, *pcMem;
|
||||
auto char cType;
|
||||
auto int iLen;
|
||||
|
||||
++iLine;
|
||||
for (pcRem = acIn+strlen(acIn); pcRem >= acIn; --pcRem) {
|
||||
if (!isspace(*pcRem))
|
||||
break;
|
||||
*pcRem = '\000';
|
||||
if (pcRem == acIn)
|
||||
break;
|
||||
}
|
||||
if ('#' == acIn[0] || '\000' == acIn[0]) {
|
||||
continue;
|
||||
}
|
||||
if ('%' == acIn[0] && '%' == acIn[1] && '\000' == acIn[2]) {
|
||||
break;
|
||||
}
|
||||
if ((char *)0 == (pcNext = strchr(acIn, ':'))) {
|
||||
fprintf(stderr, "%s: %s(%d) missing colon?\n", progname, pcFile, iLine);
|
||||
exit(3);
|
||||
}
|
||||
do {
|
||||
*pcNext++ = '\000';
|
||||
} while (isspace(*pcNext));
|
||||
switch (acIn[0]) {
|
||||
case 'a': /* allowed, allow, allows */
|
||||
case 'A':
|
||||
cType = 'a';
|
||||
break;
|
||||
case 'r': /* rejected, refused, refuse */
|
||||
case 'R':
|
||||
cType = 'r';
|
||||
break;
|
||||
case 't': /* trust, trusted, trusts */
|
||||
case 'T':
|
||||
cType = 't';
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "%s: %s(%d) unknown access key `%s\'\n", progname, pcFile, iLine, acIn);
|
||||
exit(3);
|
||||
}
|
||||
while ('\000' != *(pcMach = pcNext)) {
|
||||
while (!isspace(*pcNext)) {
|
||||
++pcNext;
|
||||
}
|
||||
while ('\000' != *pcNext && isspace(*pcNext)) {
|
||||
*pcNext++ = '\000';
|
||||
}
|
||||
if (iAccess < iG) {
|
||||
/* still have room */;
|
||||
} else if (0 != iG) {
|
||||
iG += 8;
|
||||
pACList = (ACCESS *)realloc((char *)pACList, iG * sizeof(ACCESS));
|
||||
} else {
|
||||
iG = MAXGRP;
|
||||
pACList = (ACCESS *)malloc(iG * sizeof(ACCESS));
|
||||
}
|
||||
if ((ACCESS *)0 == pACList) {
|
||||
OutOfMem();
|
||||
}
|
||||
/* use loopback interface for local connections
|
||||
if (0 == strcmp(pcMach, acMyHost)) {
|
||||
pcMach = "127.0.0.1";
|
||||
}
|
||||
*/
|
||||
iLen = strlen(pcMach);
|
||||
if ((char *)0 == (pcMem = malloc(iLen+1))) {
|
||||
OutOfMem();
|
||||
}
|
||||
pACList[iAccess].ctrust = cType;
|
||||
pACList[iAccess].ilen = iLen;
|
||||
pACList[iAccess].pcwho = strcpy(pcMem, pcMach);
|
||||
++iAccess;
|
||||
}
|
||||
}
|
||||
}
|
47
conserver/readcfg.h
Normal file
47
conserver/readcfg.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* $Id: readcfg.h,v 5.6 1993-02-09 03:59:25-08 ldv Exp $
|
||||
*
|
||||
* Copyright 1992 Purdue Research Foundation, West Lafayette, Indiana
|
||||
* 47907. All rights reserved.
|
||||
*
|
||||
* Written by Kevin S Braunsdorf, ksb@cc.purdue.edu, purdue!ksb
|
||||
*
|
||||
* This software is not subject to any license of the American Telephone
|
||||
* and Telegraph Company or the Regents of the University of California.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose on
|
||||
* any computer system, and to alter it and redistribute it freely, subject
|
||||
* to the following restrictions:
|
||||
*
|
||||
* 1. Neither the authors nor Purdue University are responsible for any
|
||||
* consequences of the use of this software.
|
||||
*
|
||||
* 2. The origin of this software must not be misrepresented, either by
|
||||
* explicit claim or by omission. Credit to the authors and Purdue
|
||||
* University must appear in documentation and sources.
|
||||
*
|
||||
* 3. Altered versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
*
|
||||
* 4. This notice may not be removed or altered.
|
||||
*/
|
||||
|
||||
/* we read in which hosts to trust and which ones we proxy for
|
||||
* from a file, into these structures
|
||||
*/
|
||||
|
||||
extern GRPENT
|
||||
aGroups[MAXGRP]; /* group info */
|
||||
extern CONSENT
|
||||
aConsoles[MAXGRP*MAXMEMB]; /* console list */
|
||||
extern REMOTE
|
||||
*pRCList; /* list of remote consoles we know about */
|
||||
extern ACCESS
|
||||
*pACList; /* `who do you love' (or trust) */
|
||||
|
||||
extern int
|
||||
iAccess; /* how many access restrictions we have */
|
||||
extern int
|
||||
iLocal; /* how many local consoles we have */
|
||||
|
||||
extern void ReadCfg();
|
44
conserver/stamper.sh
Normal file
44
conserver/stamper.sh
Normal file
@ -0,0 +1,44 @@
|
||||
#!/bin/sh
|
||||
# $Id: stamper.sh,v 4.1 91/06/19 14:40:46 ksb Exp $
|
||||
#
|
||||
# The outputs a time stamp once an hour (on the hour, we hope).
|
||||
# We take a list of logfiles to stamp
|
||||
#
|
||||
PROGNAME=`basename $0 .sh`
|
||||
if [ "$#" -eq 0 ]
|
||||
then
|
||||
echo "$PROGNAME: usage files" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# sleep until the top of the hour
|
||||
# output a mark on each log file
|
||||
# sleep for nearly an hour
|
||||
while true
|
||||
do
|
||||
(
|
||||
IFS="$IFS:"
|
||||
|
||||
# _ Wed Jun 19 14:31:02 EST 1991
|
||||
# $1 $2 $3 $4 $5 $6 $7 $8 $9
|
||||
set _ `date`
|
||||
|
||||
#sleep `expr 3600 - \( $6 \* 60 + $7 \)`
|
||||
)
|
||||
|
||||
mark="[-- MARK -- `date`]"
|
||||
for file
|
||||
do
|
||||
if [ _"-" = _"$file" ]
|
||||
then
|
||||
echo "$mark"
|
||||
else
|
||||
echo "$mark" >>$file
|
||||
fi
|
||||
done
|
||||
|
||||
sleep 3530
|
||||
done
|
||||
|
||||
# NOTREACHED
|
||||
exit 0
|
1
conserver/version.h
Normal file
1
conserver/version.h
Normal file
@ -0,0 +1 @@
|
||||
#define GNAC_VERSION "GNAC version 6.05"
|
35
console/INSTALL
Normal file
35
console/INSTALL
Normal file
@ -0,0 +1,35 @@
|
||||
# $Id: INSTALL,v 4.1 91/06/19 15:27:49 ksb Exp $
|
||||
#
|
||||
|
||||
Prep:
|
||||
|
||||
Did you do the prep work in ../conserver yet? If not please start there.
|
||||
|
||||
|
||||
Compiling:
|
||||
|
||||
Try a
|
||||
make
|
||||
in this directory. If cons.h is correct this should just compile.
|
||||
|
||||
|
||||
First test:
|
||||
|
||||
Run a version command:
|
||||
./console -V
|
||||
and see something like:
|
||||
console: $Id: INSTALL,v 4.1 91/06/19 15:27:49 ksb Exp $
|
||||
console: initial master server `staff.cc.purdue.edu'
|
||||
console: default escape sequence `^Ec'
|
||||
console: loopback address for mentor.cc.purdue.edu is 127.0.0.1
|
||||
|
||||
|
||||
Finish the INSTALL in conserver now.
|
||||
|
||||
|
||||
Connect to the conserver on your dumb port,
|
||||
|
||||
Try all the commands. Especially ^Ecz and ^Ecd/^Eco.
|
||||
|
||||
Try two connections to the same console, note the cool way you can force
|
||||
the other guy off (^Ecf).
|
81
console/Makefile
Normal file
81
console/Makefile
Normal file
@ -0,0 +1,81 @@
|
||||
# $Id: Make.host,v 5.10 94/07/26 11:06:26 ksb Exp $
|
||||
#
|
||||
# Makefile for console client progran
|
||||
#
|
||||
|
||||
# edit the ETC directory below to change where the console client
|
||||
# is installed.
|
||||
PROG= console
|
||||
ETC= ${DESTDIR}/usr/local/etc
|
||||
DOC= ${DESTDIR}/usr/local/man
|
||||
|
||||
I=/usr/include
|
||||
S=/usr/include/sys
|
||||
L=/usr/local/include
|
||||
C=../conserver
|
||||
P=
|
||||
|
||||
INCLUDE= -I$C
|
||||
DEBUG=-O
|
||||
CDEFS= -DSUN5
|
||||
CFLAGS= ${DEBUG} ${CDEFS} ${INCLUDE}
|
||||
|
||||
HDR=
|
||||
ONEC= console.c
|
||||
MAN= console.man
|
||||
OTHER= README
|
||||
SOURCE= Makefile ${OTHER} ${MAN} ${HDR} ${ONEC}
|
||||
|
||||
all: ${PROG}
|
||||
|
||||
${PROG}:
|
||||
${CC} -o $@ ${CFLAGS} ${ONEC} -lsocket -lnsl
|
||||
|
||||
clean: FRC
|
||||
rm -f Makefile.bak ${PROG} a.out *.o core errs lint.out tags
|
||||
|
||||
deinstall: ${MAN} ${DOC} FRC
|
||||
install -R ${ETC}/${PROG}
|
||||
mkcat -r${DOC} -D ${MAN}
|
||||
|
||||
depend: ${HDR} ${ONEC} FRC
|
||||
maketd -b ${CDEFS} ${INCLUDE} ${ONEC}
|
||||
|
||||
dirs: ${ETC}
|
||||
|
||||
distrib: FRC
|
||||
distrib -c ${ETC}/${PROG}
|
||||
|
||||
install: all dirs FRC
|
||||
install -cs ${PROG} ${ETC}/${PROG}
|
||||
|
||||
lint: ${HDR} ${ONEC} FRC
|
||||
lint -h ${CDEFS} ${INCLUDE} ${ONEC}
|
||||
|
||||
mkcat: ${MAN} ${DOC} FRC
|
||||
mkcat -r${DOC} ${MAN}
|
||||
|
||||
print: source FRC
|
||||
lpr -J"${PROG} source" ${SOURCE}
|
||||
|
||||
source: ${SOURCE}
|
||||
|
||||
spotless: clean
|
||||
rcsclean ${SOURCE}
|
||||
|
||||
tags: ${HDR} ${ONEC}
|
||||
ctags -t ${HDR} ${ONEC}
|
||||
|
||||
/ ${ETC}:
|
||||
install -dr $@
|
||||
|
||||
${SOURCE}:
|
||||
co -q $@
|
||||
|
||||
FRC:
|
||||
|
||||
# DO NOT DELETE THIS LINE - maketd DEPENDS ON IT
|
||||
|
||||
console: $C/cons.h console.c
|
||||
|
||||
# *** Do not add anything here - It will go away. ***
|
67
console/README
Normal file
67
console/README
Normal file
@ -0,0 +1,67 @@
|
||||
# $Id: README,v 4.2 92/07/27 08:47:14 ksb Exp $
|
||||
|
||||
BUGS:
|
||||
This program depends on a header file in ../conserver/cons.h,
|
||||
which is dones't know how to make.
|
||||
|
||||
What does it do?
|
||||
|
||||
The console switch (conserver) uses some tty ports on a `switch machine' to
|
||||
read the output of many host machines. Admins can use a client program
|
||||
(console) to connect to any console under control of the `switch'. Thus from
|
||||
my terminal here on the second floor I can control the console for each of
|
||||
the machines in the machine room 3 floors below me!
|
||||
|
||||
The `switch' host is monitored by an operator who sees all the error output
|
||||
from all the consoles (in a xterm here at PUCC). This operator can call up a
|
||||
console on any machine in a flash and respond to problems. He is aware of
|
||||
problems without having to poll many CRTs stacked out in the machine room --
|
||||
he and the tape drives can be in a quiet place.
|
||||
|
||||
|
||||
What platforms?
|
||||
|
||||
It runs under 4.2/4.3bsd, IBM's AIX6000, SunOS 4.X, and HPUX.
|
||||
Only the client runs under HPUX at this release. It depends on
|
||||
select(2) and sockets.
|
||||
|
||||
|
||||
What do I need to evaluate it?
|
||||
|
||||
I believe a modem could be used in a pinch as a `host', anything that you can
|
||||
trick into producing tty I/O. Even a dumb tty, but then you must do the
|
||||
echo. Another port on the same machine was used for testing at one point...
|
||||
and an EPROM programmer might even work.
|
||||
|
||||
|
||||
Who would be interested in this kind of thing?
|
||||
|
||||
Anyone with more than one machine with a glass tty would love it, it also
|
||||
gets rid of the need for paper consoles.
|
||||
|
||||
|
||||
Is this software restricted in distribution?
|
||||
|
||||
Tom has an Ohio State copyright on the stuff, I'm sure that there will be no
|
||||
problem with distribution. {He ripped the Purdue ECN copyright off the code
|
||||
he got, I didn't change his.} Tom has not replied to any of my email in ~3
|
||||
months....
|
||||
|
||||
|
||||
Why this version rather than any other?
|
||||
|
||||
The PUCC version supports many more features (multiple `switch' machines for
|
||||
when you run out of ports; job control; down'd consoles, etc) than either the
|
||||
Ohio State or Purdue ECN versions.
|
||||
|
||||
|
||||
How much trouble is it to port?
|
||||
|
||||
The code is ~2000 lines for the server and ~1150 for the client. Not too
|
||||
hard to read in ~3 hours. It should work with a little push on any BSD type
|
||||
UNIX.
|
||||
|
||||
|
||||
--
|
||||
"When you find me here, at the end of my rope!"
|
||||
kayessbee, Kevin Braunsdorf, ksb@cc.purdue.edu, pur-ee!ksb, purdue!ksb
|
185
console/console.8l
Normal file
185
console/console.8l
Normal file
@ -0,0 +1,185 @@
|
||||
.\" $Id: console.8l,v 5.0 92/01/13 14:44:36 ksb Exp $
|
||||
.TH CONSOLE 8L "Local"
|
||||
.SH NAME
|
||||
console \- console server client program
|
||||
.SH SYNOPSIS
|
||||
\fBconsole\fP [\-\fBrv\fP] [\-\fBAFSafs\fP] [\-\fBe\fP \fIesc\fP] [\-\fBM\fP \fIserver\fP] \fIhost\fP
|
||||
.br
|
||||
\fBconsole\fP [\-\fBdDqQ\fP] [\-\fBv\fP] [\-\fBM\fP \fIserver\fP] \fIhost\fP
|
||||
.br
|
||||
\fBconsole\fP [\-\fBv\fP] [\-\fBhuVwx\fP]
|
||||
.SH DESCRIPTION
|
||||
.B Console
|
||||
is used to manipulate console terminals remotely or poll running
|
||||
\fIconserver\fP(8L) daemons for status information.
|
||||
.PP
|
||||
.B Console
|
||||
queries the user for the root passwd before
|
||||
granting interactive access to a console (on a non-trusted system)
|
||||
since such a session may provide single-user access.
|
||||
.PP
|
||||
In the non-interactive mode
|
||||
.B console
|
||||
outputs only the requested information.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-a
|
||||
Access a console with a two-way connection (this is the default).
|
||||
.TP
|
||||
.B \-d
|
||||
Display daemon versions. The \fIconsole\fP client connects to each
|
||||
server to request its version information. The uppercase varient of
|
||||
this option only requests the primary server's version.
|
||||
.TP
|
||||
.BI \-e esc
|
||||
Set the initial two character escape sequence to
|
||||
those represented by \fIesc\fP.
|
||||
Any of the forms output by \fIcat\fP(1)'s \-\fBv\fP option
|
||||
are accepted. The default value is ``^Ec''.
|
||||
.TP
|
||||
.B \-f
|
||||
Same as
|
||||
.I \-a
|
||||
except it will force any existing connection into spy mode.
|
||||
.TP
|
||||
.B \-h
|
||||
Display a brief help message.
|
||||
.TP
|
||||
.BI \-M server
|
||||
The \fIconsole\fP client program polls \fIserver\fP as the primary server,
|
||||
rather than the hard coded default (``console.cc.purdue.edu'').
|
||||
.TP
|
||||
.B \-q
|
||||
The \fIconsole\fP client requests the server daemon quit (shutdown).
|
||||
A password is sent in the protocol stream, if none is required for
|
||||
the local host to shutdown the server just press return. The uppercase
|
||||
varient of this command just acts on the primary server.
|
||||
.TP
|
||||
.B \-r
|
||||
Request a raw connection to the group control virtual console,
|
||||
this is only useful for learning the protocol used by the
|
||||
interactive sequence.
|
||||
.TP
|
||||
.B \-s
|
||||
Requests a read-only (spy mode) connection.
|
||||
If this mode all the escape sequences (below) work, or report errors,
|
||||
but all other keyboard input is discarded.
|
||||
.TP
|
||||
.B \-V
|
||||
Output the version of the console client program.
|
||||
.TP
|
||||
.B \-v
|
||||
Be more verbose during when building the connection(s).
|
||||
Use this option in combination with any of `show' options (below)
|
||||
for added benefit.
|
||||
.TP
|
||||
.B \-u
|
||||
Show a list of consoles and the users on each.
|
||||
.TP
|
||||
.B \-w
|
||||
Show a list of all connections to all consoles.
|
||||
.TP
|
||||
.B \-x
|
||||
Show a list of consoles and devices.
|
||||
.PP
|
||||
The \-\fBA\fP, \-\fBF\fP, or \-\fBS\fP options have the same effect as
|
||||
their lower case variants.
|
||||
In addition they each request the last 20 lines of the console output after
|
||||
making the connection.
|
||||
.PP
|
||||
Any default (\-\fBa\fP) connection is dropped to spy mode if
|
||||
someone else is attached read-write.
|
||||
.SH "ESCAPE SEQUENCES"
|
||||
The connection can be controlled by a two character escape sequence, followed
|
||||
by a command. The default escape sequence is ``control-E c''
|
||||
(octal 005 143). Commands are:
|
||||
.sp
|
||||
.TS
|
||||
c l.
|
||||
a switch to attach mode
|
||||
c toggle flow control (don't do this)
|
||||
d down the current console
|
||||
e change the escape sequence to the next two characters
|
||||
f force a switch to attach mode
|
||||
l1 send a 3 second serial line break (might halt a Sun)
|
||||
o reopen the line to clear errors (silo overflows)
|
||||
r replay the last 20 lines of output
|
||||
s switch to spy mode
|
||||
u show other users on this port
|
||||
v show the version of the group server
|
||||
w who is using this console
|
||||
x examine this group's devices and modes.
|
||||
z suspend this connection
|
||||
? display list of commands
|
||||
^I toggle tab expansion
|
||||
^J continue, ignore the escape sequence
|
||||
^R replay the last line only
|
||||
\. disconnect
|
||||
; provide a new login or shift to a new console
|
||||
+(-) be more (less) free with newlines
|
||||
.TE
|
||||
.sp
|
||||
.PP
|
||||
If any other character is hit after the escape sequence, all three characters
|
||||
will be discarded.
|
||||
Note that a line break or a down command
|
||||
can only be sent from a full two-way attachment.
|
||||
To send the escape sequence through the connection one must redefine
|
||||
the outer escape sequence.
|
||||
.PP
|
||||
In the \-u output, the login \fB<none>\fP indicates no one is
|
||||
viewing that console, the login \fB<spies>\fP indicates that
|
||||
no one has a full two-way attachment. When no one is attached to
|
||||
a console its output is cloned to the stdout of the server process.
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
console \-u
|
||||
Outputs something like:
|
||||
.sp
|
||||
.RS
|
||||
.TS
|
||||
l18 l l.
|
||||
dumb up <none>
|
||||
expert up ksb@mentor
|
||||
tyro up <spies>
|
||||
mentor up <none>
|
||||
sage up fine@cis
|
||||
.TE
|
||||
.RE
|
||||
.sp
|
||||
The \fB<none>\fP indicates no one is viewing \fIdumb\fP or \fImentor\fP,
|
||||
the \fB<spies>\fP indicates only read-only connections exist for \fItyro\fP,
|
||||
other \fIlogin\fP@\fIhost\fP entries are the currently attached
|
||||
\fIsage\fP and \fIexpert\fP.
|
||||
.TP
|
||||
console \-w
|
||||
Outputs something like:
|
||||
.sp
|
||||
.RS
|
||||
.TS
|
||||
l l l.
|
||||
ksb@extra on expert Fri Feb 15 16:40:36 1991
|
||||
file@cis on sage Thu Feb 14 1:04:10 1991
|
||||
dmr@alice spy tyro Thu Feb 7 10:09:59 1991
|
||||
.TE
|
||||
.RE
|
||||
.sp
|
||||
.TP
|
||||
console \-e \*(lq^[1\*(rq lv426
|
||||
Requests a connection to the host ``lv426'' with the escape characters
|
||||
set to ``escape one''.
|
||||
.SH BUGS
|
||||
Connections suspended under Dynix sometimes break the kernel when
|
||||
resumed. Suspended connections are a poor idea in general, just
|
||||
disconnect instead.
|
||||
.PP
|
||||
It is possible to create a loop of console connections, with ugly results.
|
||||
Never run \fIconsole\fP from within a console connection.
|
||||
.PP
|
||||
The \-\fBr\fP option doesn't help to explain how connections get built.
|
||||
.SH AUTHORS
|
||||
Thomas A. Fine, Ohio State Computer Science.
|
||||
.br
|
||||
Kevin Braunsdorf, Purdue University Computing Center
|
||||
.SH "SEE ALSO"
|
||||
conserver.cf(5L), conserver(8L)
|
1317
console/console.c
Normal file
1317
console/console.c
Normal file
File diff suppressed because it is too large
Load Diff
185
console/console.man
Normal file
185
console/console.man
Normal file
@ -0,0 +1,185 @@
|
||||
.\" $Id: console.man,v 5.0 92/01/13 14:44:36 ksb Exp $
|
||||
.TH CONSOLE 8L "Local"
|
||||
.SH NAME
|
||||
console \- console server client program
|
||||
.SH SYNOPSIS
|
||||
\fBconsole\fP [\-\fBrv\fP] [\-\fBAFSafs\fP] [\-\fBe\fP \fIesc\fP] [\-\fBM\fP \fIserver\fP] \fIhost\fP
|
||||
.br
|
||||
\fBconsole\fP [\-\fBdDqQ\fP] [\-\fBv\fP] [\-\fBM\fP \fIserver\fP] \fIhost\fP
|
||||
.br
|
||||
\fBconsole\fP [\-\fBv\fP] [\-\fBhuVwx\fP]
|
||||
.SH DESCRIPTION
|
||||
.B Console
|
||||
is used to manipulate console terminals remotely or poll running
|
||||
\fIconserver\fP(8L) daemons for status information.
|
||||
.PP
|
||||
.B Console
|
||||
queries the user for the root passwd before
|
||||
granting interactive access to a console (on a non-trusted system)
|
||||
since such a session may provide single-user access.
|
||||
.PP
|
||||
In the non-interactive mode
|
||||
.B console
|
||||
outputs only the requested information.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-a
|
||||
Access a console with a two-way connection (this is the default).
|
||||
.TP
|
||||
.B \-d
|
||||
Display daemon versions. The \fIconsole\fP client connects to each
|
||||
server to request its version information. The uppercase varient of
|
||||
this option only requests the primary server's version.
|
||||
.TP
|
||||
.BI \-e esc
|
||||
Set the initial two character escape sequence to
|
||||
those represented by \fIesc\fP.
|
||||
Any of the forms output by \fIcat\fP(1)'s \-\fBv\fP option
|
||||
are accepted. The default value is ``^Ec''.
|
||||
.TP
|
||||
.B \-f
|
||||
Same as
|
||||
.I \-a
|
||||
except it will force any existing connection into spy mode.
|
||||
.TP
|
||||
.B \-h
|
||||
Display a brief help message.
|
||||
.TP
|
||||
.BI \-M server
|
||||
The \fIconsole\fP client program polls \fIserver\fP as the primary server,
|
||||
rather than the hard coded default (``console.cc.purdue.edu'').
|
||||
.TP
|
||||
.B \-q
|
||||
The \fIconsole\fP client requests the server daemon quit (shutdown).
|
||||
A password is sent in the protocol stream, if none is required for
|
||||
the local host to shutdown the server just press return. The uppercase
|
||||
varient of this command just acts on the primary server.
|
||||
.TP
|
||||
.B \-r
|
||||
Request a raw connection to the group control virtual console,
|
||||
this is only useful for learning the protocol used by the
|
||||
interactive sequence.
|
||||
.TP
|
||||
.B \-s
|
||||
Requests a read-only (spy mode) connection.
|
||||
If this mode all the escape sequences (below) work, or report errors,
|
||||
but all other keyboard input is discarded.
|
||||
.TP
|
||||
.B \-V
|
||||
Output the version of the console client program.
|
||||
.TP
|
||||
.B \-v
|
||||
Be more verbose during when building the connection(s).
|
||||
Use this option in combination with any of `show' options (below)
|
||||
for added benefit.
|
||||
.TP
|
||||
.B \-u
|
||||
Show a list of consoles and the users on each.
|
||||
.TP
|
||||
.B \-w
|
||||
Show a list of all connections to all consoles.
|
||||
.TP
|
||||
.B \-x
|
||||
Show a list of consoles and devices.
|
||||
.PP
|
||||
The \-\fBA\fP, \-\fBF\fP, or \-\fBS\fP options have the same effect as
|
||||
their lower case variants.
|
||||
In addition they each request the last 20 lines of the console output after
|
||||
making the connection.
|
||||
.PP
|
||||
Any default (\-\fBa\fP) connection is dropped to spy mode if
|
||||
someone else is attached read-write.
|
||||
.SH "ESCAPE SEQUENCES"
|
||||
The connection can be controlled by a two character escape sequence, followed
|
||||
by a command. The default escape sequence is ``control-E c''
|
||||
(octal 005 143). Commands are:
|
||||
.sp
|
||||
.TS
|
||||
c l.
|
||||
a switch to attach mode
|
||||
c toggle flow control (don't do this)
|
||||
d down the current console
|
||||
e change the escape sequence to the next two characters
|
||||
f force a switch to attach mode
|
||||
l1 send a 3 second serial line break (might halt a Sun)
|
||||
o reopen the line to clear errors (silo overflows)
|
||||
r replay the last 20 lines of output
|
||||
s switch to spy mode
|
||||
u show other users on this port
|
||||
v show the version of the group server
|
||||
w who is using this console
|
||||
x examine this group's devices and modes.
|
||||
z suspend this connection
|
||||
? display list of commands
|
||||
^I toggle tab expansion
|
||||
^J continue, ignore the escape sequence
|
||||
^R replay the last line only
|
||||
\. disconnect
|
||||
; provide a new login or shift to a new console
|
||||
+(-) be more (less) free with newlines
|
||||
.TE
|
||||
.sp
|
||||
.PP
|
||||
If any other character is hit after the escape sequence, all three characters
|
||||
will be discarded.
|
||||
Note that a line break or a down command
|
||||
can only be sent from a full two-way attachment.
|
||||
To send the escape sequence through the connection one must redefine
|
||||
the outer escape sequence.
|
||||
.PP
|
||||
In the \-u output, the login \fB<none>\fP indicates no one is
|
||||
viewing that console, the login \fB<spies>\fP indicates that
|
||||
no one has a full two-way attachment. When no one is attached to
|
||||
a console its output is cloned to the stdout of the server process.
|
||||
.SH EXAMPLES
|
||||
.TP
|
||||
console \-u
|
||||
Outputs something like:
|
||||
.sp
|
||||
.RS
|
||||
.TS
|
||||
l18 l l.
|
||||
dumb up <none>
|
||||
expert up ksb@mentor
|
||||
tyro up <spies>
|
||||
mentor up <none>
|
||||
sage up fine@cis
|
||||
.TE
|
||||
.RE
|
||||
.sp
|
||||
The \fB<none>\fP indicates no one is viewing \fIdumb\fP or \fImentor\fP,
|
||||
the \fB<spies>\fP indicates only read-only connections exist for \fItyro\fP,
|
||||
other \fIlogin\fP@\fIhost\fP entries are the currently attached
|
||||
\fIsage\fP and \fIexpert\fP.
|
||||
.TP
|
||||
console \-w
|
||||
Outputs something like:
|
||||
.sp
|
||||
.RS
|
||||
.TS
|
||||
l l l.
|
||||
ksb@extra on expert Fri Feb 15 16:40:36 1991
|
||||
file@cis on sage Thu Feb 14 1:04:10 1991
|
||||
dmr@alice spy tyro Thu Feb 7 10:09:59 1991
|
||||
.TE
|
||||
.RE
|
||||
.sp
|
||||
.TP
|
||||
console \-e \*(lq^[1\*(rq lv426
|
||||
Requests a connection to the host ``lv426'' with the escape characters
|
||||
set to ``escape one''.
|
||||
.SH BUGS
|
||||
Connections suspended under Dynix sometimes break the kernel when
|
||||
resumed. Suspended connections are a poor idea in general, just
|
||||
disconnect instead.
|
||||
.PP
|
||||
It is possible to create a loop of console connections, with ugly results.
|
||||
Never run \fIconsole\fP from within a console connection.
|
||||
.PP
|
||||
The \-\fBr\fP option doesn't help to explain how connections get built.
|
||||
.SH AUTHORS
|
||||
Thomas A. Fine, Ohio State Computer Science.
|
||||
.br
|
||||
Kevin Braunsdorf, Purdue University Computing Center
|
||||
.SH "SEE ALSO"
|
||||
conserver.cf(5L), conserver(8L)
|
Loading…
Reference in New Issue
Block a user