v23i035: Run a program under a pty session, Part05/06

Rich Salz rsalz at bbn.com
Thu Oct 11 00:17:05 AEST 1990


Submitted-by: Dan Bernstein <brnstnd at kramden.acf.nyu.edu>
Posting-number: Volume 23, Issue 35
Archive-name: pty/part05

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then feed it
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix at uunet.uu.net if you want that tool.
# Contents:  CHANGES Makefile err.c file.h.old globals.c misc.c
#   patch/igntt.c pty.h sig.h sock.h tty.h util/biff.1 util/condom.1
#   util/disconnect.1 util/disconnect.c util/exclon.1 util/lock.1
#   util/lock.c util/mesg.1 util/mesg.c util/reconnect.1
#   util/reconnect.c util/script.1 util/script.tidy.1 util/sess.1
#   util/sesskill.1 util/sesskill.c util/sesslist.1 util/sessname.1
#   util/sessname.c util/sessutil.h util/u.1 util/u.c util/wall.1
#   util/wall.c util/who.1 util/who.c util/write.1
# Wrapped by rsalz at litchi.bbn.com on Wed Oct 10 10:11:41 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo '          "shar: End of archive 5 (of 6)."'
if test -f 'CHANGES' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'CHANGES'\"
else
  echo shar: Extracting \"'CHANGES'\" \(1470 characters\)
  sed "s/^X//" >'CHANGES' <<'END_OF_FILE'
X9/9/90: Patch 1.
X9/9/90: Put list of all known problems into README. Also some todos.
X9/9/90: Fixed pty -xc bug.
X
X8/22/90: Packaged for comp.sources.unix, hopefully for good this time.
X8/21/90: pty 3.001.
X
X8/21/90: INSTALL changed a bit.
X8/21/90: FILES, INSTALLREADABLE, QUESTIONS.
X8/21/90: Removed extraneous n, from commented-out FD_ZERO in file.h.old.
X8/21/90: Used $(CC) and $(NROFF) where appropriate.
X8/21/90: Shortened long Makefile lines.
X8/21/90: Switched util/exclon.1 and util/excloff.1 to correct spots.
X8/21/90: Included COPYRIGHT.
X8/21/90: Corrected \n use in a few strings.
X8/21/90: Fixed documentation of -0.
X8/21/90: Fixed bug in NO_FDPASSING reconnect code.
X8/21/90: Completely updated patch directory for new telnet.
X
X6/11/90: Packaged for comp.sources.unix.
X6/1/90: pty 3.0.
X
X5/24/90: who.
X5/23/90: lock, exclon, excloff, tiocsti, script, sess, script.tidy.
X5/19/90: All working. On to the utilities...
X5/12/90: What would it take to use vfork() safely?
X5/12/90: -xe destroys csh, not just more. Amusing. -xE default, I guess.
X5/12/90: Separated out texts.c, globals.c, sig.c.
X5/12/90: Separated out configuration into config.h (as well as Makefile).
X5/11/90: Passes lint -haxc, except bzero and some correct char * casts. Grrrr.
X5/11/90: Removed last traces of structure copying/comparing. Sigh.
X5/10/90: Mostly done. Still needs utmp, other security, ctrlr passing.
X5/6/90: Progress. Chug chug chug.
X5/1/90: Begin complete rewrite for version 3.0.
END_OF_FILE
  if test 1470 -ne `wc -c <'CHANGES'`; then
    echo shar: \"'CHANGES'\" unpacked with wrong size!
  fi
  # end of 'CHANGES'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
  echo shar: Extracting \"'Makefile'\" \(1585 characters\)
  sed "s/^X//" >'Makefile' <<'END_OF_FILE'
XCC=cc
XCCOPTS=-O2 -s
X
XNROFF=nroff
XNROFFOPTS=-man
X
Xdefault: all
X
Xall: pty pty.man
X
Xshar: pty.shar
X
Xpty: pty.o sigler.o master.o slave.o err.o tty.o texts.o sig.o globals.o logs.o sock.o misc.o Makefile
X	$(CC) $(CCOPTS) -o pty texts.o globals.o pty.o sigler.o master.o slave.o err.o tty.o sig.o logs.o sock.o misc.o
X
Xpty.o: pty.c pty.h getopt.h sigler.h master.h slave.h err.h tty.h config.h texts.h sig.h logs.h file.h misc.h Makefile
X	$(CC) $(CCOPTS) -c pty.c
X
Xsigler.o: sigler.c pty.h sigler.h config.h sig.h sock.h file.h err.h misc.h Makefile
X	$(CC) $(CCOPTS) -c sigler.c
X
Xmaster.o: master.c pty.h master.h err.h config.h sig.h tty.h file.h logs.h sock.h misc.h Makefile
X	$(CC) $(CCOPTS) -c master.c
X
Xslave.o: slave.c pty.h tty.h slave.h err.h config.h sig.h file.h logs.h Makefile
X	$(CC) $(CCOPTS) -c slave.c
X
Xerr.o: err.c err.h pty.h config.h Makefile
X	$(CC) $(CCOPTS) -c err.c
X
Xtty.o: tty.c tty.h err.h config.h file.h Makefile
X	$(CC) $(CCOPTS) -c tty.c
X
Xsig.o: sig.c sig.h config.h Makefile
X	$(CC) $(CCOPTS) -c sig.c
X
Xtexts.o: texts.c texts.h config.h Makefile
X	$(CC) $(CCOPTS) -c texts.c
X
Xglobals.o: globals.c config.h pty.h tty.h Makefile
X	$(CC) $(CCOPTS) -c globals.c
X
Xlogs.o: logs.c config.h pty.h file.h Makefile
X	$(CC) $(CCOPTS) -c logs.c
X
Xsock.o: sock.c config.h sock.h tty.h err.h Makefile
X	$(CC) $(CCOPTS) -c sock.c
X
Xmisc.o: misc.c config.h pty.h misc.h Makefile
X	$(CC) $(CCOPTS) -c misc.c
X
Xpty.man: pty.1 Makefile
X	$(NROFF) $(NROFFOPTS) < pty.1 > pty.man
X
Xpty.shar: CHANGES
X	shar `cat FILES` > pty.shar
X	chmod 400 pty.shar
X
Xpty.h: tty.h
Xsig.h: config.h
Xtty.h: config.h
END_OF_FILE
  if test 1585 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
  fi
  # end of 'Makefile'
fi
if test -f 'err.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'err.c'\"
else
  echo shar: Extracting \"'err.c'\" \(1108 characters\)
  sed "s/^X//" >'err.c' <<'END_OF_FILE'
X/* Copyright 1990, Daniel J. Bernstein. All rights reserved. */
X
X#include <stdio.h>
X#include "config.h"
X#include "pty.h"
X#include "err.h"
X
Xstatic void perr(e)
Xint e;
X{
X if (!flagquiet)
X  {
X   if ((e < 0) || (e > sys_nerr))
X     (void) fprintf(stderr,"error %d",e);
X   else
X     (void) fputs(sys_errlist[e],stderr);
X  }
X}
X
Xstatic void serr(s)
Xchar *s;
X{
X if (!flagquiet)
X   (void) fputs(s,stderr);
X}
X
Xvoid warnerr2(p,s)
Xchar *p;
Xchar *s;
X{
X if (!flagquiet)
X   (void) fprintf(stderr,p,s);
X}
X
X/* Note that accounting is based on the real uid, as it should be. */
X
Xvoid fatal(x)
Xint x;
X{
X (void) setreuid(uid,uid);
X (void) exit(x);
X /*NOTREACHED*/
X}
X
Xvoid fatalinfo(x,s)
Xint x;
Xchar **s;
X{
X while (*s)
X  {
X   serr(*(s++));
X   serr("\n");
X  }
X fatal(x);
X /*NOTREACHED*/
X}
X
Xvoid fatalerr(x,s)
Xint x;
Xchar *s;
X{
X serr(s);
X fatal(x);
X /*NOTREACHED*/
X}
X
Xvoid fatalerr2p(x,p,s,e)
Xint x;
Xchar *p;
Xchar *s;
Xint e;
X{
X warnerr2(p,s);
X serr(": ");
X perr(e);
X serr("\n");
X fatal(x);
X /*NOTREACHED*/
X}
X
Xvoid fatalerrp(x,s,e)
Xint x;
Xchar *s;
Xint e;
X{
X serr(s);
X serr(": ");
X perr(e);
X serr("\n");
X fatal(x);
X /*NOTREACHED*/
X}
END_OF_FILE
  if test 1108 -ne `wc -c <'err.c'`; then
    echo shar: \"'err.c'\" unpacked with wrong size!
  fi
  # end of 'err.c'
fi
if test -f 'file.h.old' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'file.h.old'\"
else
  echo shar: Extracting \"'file.h.old'\" \(747 characters\)
  sed "s/^X//" >'file.h.old' <<'END_OF_FILE'
X/* Copyright 1990, Daniel J. Bernstein. All rights reserved. */
X
X#ifndef PTY_FILE_H
X#define PTY_FILE_H
X
X#include <sys/file.h>
X#ifdef BSD
X#include <limits.h>
X#endif
X#include <fcntl.h>
Xextern long lseek(); /* sigh. */
X
X#define NFDBITS	(sizeof(fd_mask) * NBBY)
X#define	FD_SET(n,p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
X#define	FD_ISSET(n,p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
X#define FD_ZERO(p) bzero((caddr_t)(p),sizeof(*(p)))
X
X/* The following are desperation versions. Ignore pointer warnings.
X#undef NFDBITS
X#undef FD_SET
X#undef FD_ISSET
X#undef FD_ZERO
X#undef fd_set
X#define fd_set long
X#define FD_SET(n,p) ((*p) |= (1 << (n)))
X#define FD_ISSET(n,p) ((*p) & (1 << (n)))
X#define FD_ZERO(p) (*p = 0L)
X*/
X
X#endif
END_OF_FILE
  if test 747 -ne `wc -c <'file.h.old'`; then
    echo shar: \"'file.h.old'\" unpacked with wrong size!
  fi
  # end of 'file.h.old'
fi
if test -f 'globals.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'globals.c'\"
else
  echo shar: Extracting \"'globals.c'\" \(958 characters\)
  sed "s/^X//" >'globals.c' <<'END_OF_FILE'
X/* Copyright 1990, Daniel J. Bernstein. All rights reserved. */
X
X#include "config.h"
X#include "pty.h"
X
Xint uid;
Xint euid;
Xint pid;
Xint pgrp;
Xlong date;
Xchar *username;
X
Xint fdin = -1;
Xint fdout = -1;
Xint fdmty = -1;
Xint fdsty = -1;
Xint fdtty = -1;
Xint fdre = -1;
Xint fdpass = -1;
X
Xint flagquiet = 0;
Xint flagdetached = 0;
Xint flagjobctrl = 1;
Xint flagttymodes = 1;
Xint flagsameerr = 0;
Xint flagfdpass = 0;
Xint flagsession = 0;
Xint flagverbose = 0;
X
Xint flagxchown = 0;
Xint flagxutmp = 0;
Xint flagxwtmp = 0;
Xint flagxexcl = 0; /* should be 1, but that would break write & friends */
Xint flagxerrwo = 0; /* should be 1, but that would break csh & more */
Xint flagxchkopen = 1;
Xint flagxskipopen = 0;
Xint flagxrandom = 1; /* random pty searching: worth the effort */
Xint flagxsetuid = 1;
X
X#include "tty.h"
X
Xstruct ttymodes tmotty; /* original tty modes */
Xstruct ttymodes tmochartty; /* tty in character mode */
Xstruct ttymodes tmopty; /* original pty modes */
END_OF_FILE
  if test 958 -ne `wc -c <'globals.c'`; then
    echo shar: \"'globals.c'\" unpacked with wrong size!
  fi
  # end of 'globals.c'
fi
if test -f 'misc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'misc.c'\"
else
  echo shar: Extracting \"'misc.c'\" \(1442 characters\)
  sed "s/^X//" >'misc.c' <<'END_OF_FILE'
X/* Copyright 1990, Daniel J. Bernstein. All rights reserved. */
X
X#include "config.h"
X#include <strings.h>
X#include <stdio.h>
X#include <pwd.h>
Xextern char *getenv(); /* grrrr */
Xextern char *ttyname(); /* grrrr */
X#include "pty.h"
X#include "misc.h"
X
Xint sessdir()
X{
X char suid[10];
X char *home;
X
X if (flagxsetuid)
X  {
X   if (chdir(PTYDIR) == -1)
X     return -1;
X  }
X else
X  {
X   if ((home = getenv("HOME")) == 0)
X     return -1;
X   else if (chdir(home) == -1)
X     return -1;
X   else if ((chdir(".pty") == -1)
X          &&((mkdir(".pty",0700) == -1)
X           ||(chdir(".pty") == -1)))
X          return -1;
X  }
X
X (void) sprintf(suid,"%d",uid);
X if ((chdir(suid) == -1)
X   &&((mkdir(suid,0700) == -1)
X    ||(chdir(suid) == -1)))
X   return -1;
X return 0;
X}
X
Xchar *real_ttyname(fd)
Xint fd; /* first guess; should be /dev/tty */
X{
X char *ttyn;
X
X if ((ttyn = ttyname(fd))
X   &&(strcmp(ttyn,"/dev/tty")))
X  {
X   /* This would actually happen if opening /dev/tty converted into */
X   /* opening the actual terminal device---which would be nice. */
X   return ttyn;
X  }
X /* So much for nice tries. */
X for (fd = getdtablesize();fd >= 0;fd--)
X  {
X   if ((ttyn = ttyname(fd))
X     &&(strcmp(ttyn,"/dev/tty")))
X     return ttyn;
X  }
X return (char *) 0;
X}
X
Xstatic struct passwd *pw;
Xstatic char nopwun[12];
X
Xvoid setusername()
X{
X if (pw = getpwuid(uid))
X   username = pw->pw_name;
X else
X  {
X   (void) sprintf(nopwun,"%d",uid);
X   username = nopwun;
X  }
X}
END_OF_FILE
  if test 1442 -ne `wc -c <'misc.c'`; then
    echo shar: \"'misc.c'\" unpacked with wrong size!
  fi
  # end of 'misc.c'
fi
if test -f 'patch/igntt.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'patch/igntt.c'\"
else
  echo shar: Extracting \"'patch/igntt.c'\" \(285 characters\)
  sed "s/^X//" >'patch/igntt.c' <<'END_OF_FILE'
X#include <signal.h>
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X switch (fork())
X  {
X   case -1: exit(1);
X   case 0: break;
X   default: exit(0);
X  }
X (void) signal(SIGTTOU,SIG_IGN);
X (void) signal(SIGTTIN,SIG_IGN);
X (void) sleep(1);
X (void) execvp(argv[1],argv + 1);
X (void) exit(1);
X}
END_OF_FILE
  if test 285 -ne `wc -c <'patch/igntt.c'`; then
    echo shar: \"'patch/igntt.c'\" unpacked with wrong size!
  fi
  # end of 'patch/igntt.c'
fi
if test -f 'pty.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'pty.h'\"
else
  echo shar: Extracting \"'pty.h'\" \(1721 characters\)
  sed "s/^X//" >'pty.h' <<'END_OF_FILE'
X/* Copyright 1990, Daniel J. Bernstein. All rights reserved. */
X
X#ifndef PTY_H
X#define PTY_H
X
Xextern int uid;
Xextern int euid;
Xextern int pid;
Xextern int pgrp;
Xextern long date;
Xextern char *username;
X
Xextern int fdin; /* input */
Xextern int fdout; /* output */
Xextern int fdmty; /* master side of pty */
Xextern int fdsty; /* slave side of pty */
Xextern int fdtty; /* current tty, if connected to one, or -1 */
Xextern int fdre; /* for reconnecting and fd passing, or -1 */
Xextern int fdpass; /* for passing master side up to controller */
X
Xextern int flagquiet; /* -q, don't make any noises at all */
Xextern int flagdetached; /* -d, we are detached to start */
Xextern int flagjobctrl; /* -j, we can stop/start */
Xextern int flagttymodes; /* -t, we change modes of original tty */
Xextern int flagsameerr; /* -e (3), we leave fds 2 (3) and up alone */
Xextern int flagfdpass; /* -fn, we pass master side up fd n */
Xextern int flagsession; /* -s, we can disconnect & reconnect */
Xextern int flagverbose; /* -v, complain about everything */
X
Xextern int flagxchown; /* -xc, change owner of pty */
Xextern int flagxutmp; /* -xu, add entry to utmp */
Xextern int flagxwtmp; /* -xw, add entry to wtmp */
Xextern int flagxexcl; /* -xx, set exclusive use */
Xextern int flagxerrwo; /* -xe, make stderr write-only */
Xextern int flagxchkopen; /* -xn, check if anyone has pty open */
Xextern int flagxskipopen; /* -xo, skip if anyone has pty open */
Xextern int flagxrandom; /* -xr, search through ptys randomly */
Xextern int flagxsetuid; /* -xs, we're running setuid */
X
X#include "tty.h"
X
Xextern struct ttymodes tmotty;
Xextern struct ttymodes tmochartty;
Xextern struct ttymodes tmopty;
X
X#define copy(dst,src,num) bcopy(src,dst,num)
X
X#endif
END_OF_FILE
  if test 1721 -ne `wc -c <'pty.h'`; then
    echo shar: \"'pty.h'\" unpacked with wrong size!
  fi
  # end of 'pty.h'
fi
if test -f 'sig.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sig.h'\"
else
  echo shar: Extracting \"'sig.h'\" \(565 characters\)
  sed "s/^X//" >'sig.h' <<'END_OF_FILE'
X/* Copyright 1990, Daniel J. Bernstein. All rights reserved. */
X
X#ifndef PTY_SIG_H
X#define PTY_SIG_H
X
X#include "config.h"
X#include <signal.h>
X
Xtypedef void (*sig_handler)();
Xtypedef SIGRET_TYPE (*sig_syshandler)();
X
Xextern void nothing();
X
X#define SIGNUM 32
Xtypedef int sig_num;
X
Xextern void sig_init();
Xextern void sig_restore();
X
Xextern void sig_ignore();
Xextern void sig_default();
Xextern void sig_handle();
X
X#ifdef SIGINTERRUPT
Xextern void sig_interrupt();
X#endif
X
Xextern void sig_sethandler();
X
Xextern void sig_startring();
Xextern void sig_stopring();
X
X#endif
END_OF_FILE
  if test 565 -ne `wc -c <'sig.h'`; then
    echo shar: \"'sig.h'\" unpacked with wrong size!
  fi
  # end of 'sig.h'
fi
if test -f 'sock.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sock.h'\"
else
  echo shar: Extracting \"'sock.h'\" \(579 characters\)
  sed "s/^X//" >'sock.h' <<'END_OF_FILE'
X/* Copyright 1990, Daniel J. Bernstein. All rights reserved. */
X
X#ifndef PTY_SOCK_H
X#define PTY_SOCK_H
X
Xextern int pty_readsock();
Xextern int pty_writesock();
Xextern int pty_acceptsock();
X
X/* -1 fail, 0 success */
Xextern int pty_putgetstr();
Xextern int pty_putgetfd();
Xextern int pty_putgetonefd();
Xextern int pty_putgetint();
Xextern int pty_putgettty();
Xextern int pty_getch();
X
X/* -1 fail, 0 success, 1 refused */
Xextern int pty_sendstr();
Xextern int pty_sendfd();
Xextern int pty_sendonefd();
Xextern int pty_sendint();
Xextern int pty_sendtty();
Xextern int pty_putch();
X
X#endif
END_OF_FILE
  if test 579 -ne `wc -c <'sock.h'`; then
    echo shar: \"'sock.h'\" unpacked with wrong size!
  fi
  # end of 'sock.h'
fi
if test -f 'tty.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tty.h'\"
else
  echo shar: Extracting \"'tty.h'\" \(1104 characters\)
  sed "s/^X//" >'tty.h' <<'END_OF_FILE'
X/* Copyright 1990, Daniel J. Bernstein. All rights reserved. */
X
X#ifndef PTY_TTY_H
X#define PTY_TTY_H
X
X#include "config.h"
X#include <sgtty.h>
X
Xstruct ttymodes
X {
X  int di;
X  struct sgttyb sg;
X  struct tchars tc;
X  long lb;
X  struct ltchars lt;
X#ifdef TTY_WINDOWS
X  struct winsize ws;
X#endif
X#ifdef TTY_AUXCHARS
X  struct auxchars au;
X#endif
X }
X;
X
Xextern int tty_getctrl();
Xextern tty_setexcl(/* int fd */);
Xextern tty_setpgrp(/* int fd; int pg; */);
Xextern tty_dissoc(/* int fd */);
Xextern tty_getmodes(/* int fd; s ttymodes *tmo */);
Xextern tty_setmodes(/* int fd; s ttymodes *tmo */);
Xextern tty_modifymodes(/* int fd; s ttymodes *tmonew; s ttymodes *tmoold */);
X
X/* The following don't do any ioctls; they just mangle internal ttymodes. */
X
Xextern void tty_copymodes(/* s ttymodes *tmonew; s ttymodes *tmoold */);
Xextern void tty_copywin(/* s ttymodes *tmonew; s ttymodes *tmoold */);
Xextern void tty_charmode(/* s ttymodes *tmo */);
Xextern void tty_mungemodes(/* s ttymodes *tmo;cbreak;new;echo;crmod;raw;crt */);
Xextern void tty_initmodes(/* s ttymodes *tmo;cbreak;new;echo;crmod;raw;crt */);
X
X#endif
END_OF_FILE
  if test 1104 -ne `wc -c <'tty.h'`; then
    echo shar: \"'tty.h'\" unpacked with wrong size!
  fi
  # end of 'tty.h'
fi
if test -f 'util/biff.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/biff.1'\"
else
  echo shar: Extracting \"'util/biff.1'\" \(897 characters\)
  sed "s/^X//" >'util/biff.1' <<'END_OF_FILE'
X.TH biff 1
X.SH NAME
Xbiff \- be notified if mail arrives and who it is from
X.SH SYNOPSIS
X.B biff
X[
X.B n
X] [
X.B y
X]
X.SH DESCRIPTION
XAfter
X.I biff y,
Xthe system will display
Xthe top of incoming mail on your screen,
Xas described in
X.I comsat(8).
X.I biff n
Xturns this off.
X.I biff
Xapplies to your current terminal session;
Xtypically you'd put a
X.I biff y
Xinto your
X.I \&.login,
X.I \&.cshrc,
Xor
X.I \&.profile.
X.PP
X.I biff
Xwithout an argument tells you your current
X``biffing'' status.
X.PP
X.I biff
Xoperates asynchronously.
XFor synchronous notification use the MAIL variable of
X.IR sh (1)
Xor the
X.I mail
Xvariable of
X.IR csh (1).
X.PP
X.I biff
Xrequires its input to be your terminal session
X(or at least a session you own). All it really
Xdoes is handle the owner-execute bit on the terminal.
X.PP
X.I biff
Xonly looks at the first letter of its first argument.
X.SH "SEE ALSO"
Xcsh(1),
Xsh(1),
Xmail(1),
Xcomsat(8C)
END_OF_FILE
  if test 897 -ne `wc -c <'util/biff.1'`; then
    echo shar: \"'util/biff.1'\" unpacked with wrong size!
  fi
  # end of 'util/biff.1'
fi
if test -f 'util/condom.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/condom.1'\"
else
  echo shar: Extracting \"'util/condom.1'\" \(1176 characters\)
  sed "s/^X//" >'util/condom.1' <<'END_OF_FILE'
X.TH condom 1
X.SH NAME
Xcondom \- wrap a pseudo-terminal around a program
X.SH SYNOPSIS
X.B condom
X.I program
X.B [
X.I arg ...
X.B ]
X.SH DESCRIPTION
X.I condom,
Xwhich is really just
X.I pty -0,
Xruns a program under a pseudo-terminal
Xwith as little interpretation as possible.
XThe following are the most noticeable effects of
X.I condom:
X.PP
X1. The
X.I stdio(3)
Xroutines
Xwill, by default,
Xline-buffer their output rather than
Xwaiting for a big block of output
Xto accumulate.
X.PP
X2.
X.I condom
Xalways exits with exit code 0,
Xprovided nothing unusual happens.
X.PP
X3.
XThe original terminal
Xis always in line-by-line,
Xecho mode (or whatever mode it is
Xin originally).
X.PP
X4.
XEnd-of-file
Xis ignored in the input.
X(This is an inherent and unfortunate restriction
Xof the current pseudo-terminal design, and may not
Xbe true under other versions of
X.I pty.)
XIf the input really does end,
X.I pty
Xwill just sit around wasting CPU time.
X.PP
X5.
XIf
X.I program
Xrefers to /dev/tty,
Xit will see the pseudo-terminal
X(i.e., its input and output)
Xrather than its original terminal.
X.PP
X6.
XVarious signals
Xto
X.I condom
Xwill be forwarded to
X.I program
Xas HUPs instead.
X.SH "SEE ALSO"
Xpty(1),
Xsetbuf(3),
Xpty(4)
END_OF_FILE
  if test 1176 -ne `wc -c <'util/condom.1'`; then
    echo shar: \"'util/condom.1'\" unpacked with wrong size!
  fi
  # end of 'util/condom.1'
fi
if test -f 'util/disconnect.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/disconnect.1'\"
else
  echo shar: Extracting \"'util/disconnect.1'\" \(1184 characters\)
  sed "s/^X//" >'util/disconnect.1' <<'END_OF_FILE'
X.TH disconnect 1
X.SH NAME
Xdisconnect \- disconnect current pty session
X.SH SYNOPSIS
X.B disconnect
X.SH DESCRIPTION
X.I disconnect
Xdisconnects the current
Xsession,
Xas if the connection
Xhad been hung up.
XLater you can use
X.I reconnect
Xto get back to the session
Xexactly where you left off.
X.PP
XBecause
X.I disconnect
Xdoesn't actually hang up the connection,
Xbut merely severs its association with
Xthe current session,
Xa
X.I reconnect
Xon that connection will take effect
Ximmediately.
XThis leads to a useful trick:
Xyou can switch rapidly from session
X.I xx
Xto disconnected session
X.I yy
Xby typing
X.EX
Xreconnect yy;disconnect
X.EE
XThen
X.I xx
Xand
X.I yy
Xwill be reversed,
Xand you can switch back and forth without trouble.
X.PP
X.I xdisconnect
Xworks just like
X.I disconnect
Xbut applies to session started with
X.B\-xS.
X.SH DIAGNOSTICS
X.TP
X.I cannot find session
X.TP
X.I you don't own session
XThe standard input to
X.I reconnect
Xis not a pty session you own.
X.TP
X.I not child of session slave
XThe parent to
X.I reconnect
Xis not the head process in the session.
X.TP
X.I cannot disconnect
X.I reconnect
Xis unable to communicate with
Xthe
Xpseudo-terminal
Xmanager.
X.SH "SEE ALSO"
Xpty(1),
Xsess(1),
Xreconnect(1)
END_OF_FILE
  if test 1184 -ne `wc -c <'util/disconnect.1'`; then
    echo shar: \"'util/disconnect.1'\" unpacked with wrong size!
  fi
  # end of 'util/disconnect.1'
fi
if test -f 'util/disconnect.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/disconnect.c'\"
else
  echo shar: Extracting \"'util/disconnect.c'\" \(694 characters\)
  sed "s/^X//" >'util/disconnect.c' <<'END_OF_FILE'
X/* Public domain. */
X
X#include <stdio.h>
X#include <signal.h>
X#include "sessutil.h"
Xextern unsigned short getuid();
X
Xmain()
X{
X struct pty_session ps;
X int uid;
X
X uid = getuid();
X
X if (pty_get_sess(0,uid,&ps) == -1)
X  {
X   (void) fputs("sessname: fatal: cannot find session\n",stderr);
X   (void) exit(1);
X  }
X if (ps.uid != uid)
X  {
X   (void) fputs("sessname: fatal: you don't own session\n",stderr);
X   (void) exit(1);
X  }
X if (ps.slavepid != getppid())
X  {
X   (void) fputs("sessname: fatal: not child of session slave\n",stderr);
X   (void) exit(1);
X  }
X if (kill(ps.siglerpid,SIGUSR1) == -1)
X  {
X   (void) perror("sessname: fatal: cannot disconnect");
X   (void) exit(1);
X  }
X (void) exit(0);
X}
END_OF_FILE
  if test 694 -ne `wc -c <'util/disconnect.c'`; then
    echo shar: \"'util/disconnect.c'\" unpacked with wrong size!
  fi
  # end of 'util/disconnect.c'
fi
if test -f 'util/exclon.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/exclon.1'\"
else
  echo shar: Extracting \"'util/exclon.1'\" \(692 characters\)
  sed "s/^X//" >'util/exclon.1' <<'END_OF_FILE'
X.TH excl 1
X.SH NAME
Xexclon, excloff \- reserve tty for exclusive use
X.SH SYNOPSIS
X.B exclon
X.PP
X.B excloff
X.SH DESCRIPTION
XThe
X.B exclon
Xcommand reserves your terminal for exclusive use with
Xthe TIOCEXCL ioctl.
XThis means that any process attempting to open your terminal
Xwill fail, including other users attempting to write or cat,
Xand including reference to /dev/tty by yourself.
X.PP
XTalk is not affected at all by exclon.
X.PP
XTo unreserve your terminal, use excloff.
XIt is polite to do this at the end of a session,
Xthough it is automatic when the terminal is closed.
X.SH AUTHOR
XI hesitate to claim authorship for a one-statement program.
X.SH "SEE ALSO"
Xtalk(1), stty(1), ioctl(2), tty(4)
END_OF_FILE
  if test 692 -ne `wc -c <'util/exclon.1'`; then
    echo shar: \"'util/exclon.1'\" unpacked with wrong size!
  fi
  # end of 'util/exclon.1'
fi
if test -f 'util/lock.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/lock.1'\"
else
  echo shar: Extracting \"'util/lock.1'\" \(485 characters\)
  sed "s/^X//" >'util/lock.1' <<'END_OF_FILE'
X.TH lock 1
X.SH NAME
Xlock \- reserve a terminal
X.SH SYNOPSIS
X.B lock
X.SH DESCRIPTION
X.I lock
Xrequests a password from the user, reads it again for verification,
Xand then sits around doing nothing until the password is typed a third
Xtime.
X.PP
XThis clone version of
X.I lock
Xcorrects several of the original's failings, by being much simpler:
Xit doesn't accept
X.I hasta la vista;
Xit doesn't accept
Xthe root password;
Xit doesn't time out;
Xand it does print a message for each bad password.
END_OF_FILE
  if test 485 -ne `wc -c <'util/lock.1'`; then
    echo shar: \"'util/lock.1'\" unpacked with wrong size!
  fi
  # end of 'util/lock.1'
fi
if test -f 'util/lock.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/lock.c'\"
else
  echo shar: Extracting \"'util/lock.c'\" \(852 characters\)
  sed "s/^X//" >'util/lock.c' <<'END_OF_FILE'
X/* Public domain. */
X#include <curses.h>
X#include <signal.h>
X#include <strings.h>
X
Xmain()
X{
X char key[100];
X char key2[100];
X struct sigvec vec;
X int i;
X
X vec.sv_handler = SIG_IGN;
X vec.sv_mask = 0;
X for (i = 31;i > 0;i--)
X   (void) sigvec(i,&vec,(struct sigvec *) 0);
X (void) savetty();
X (void) crmode();
X (void) noecho();
X (void) printf("Key: ");
X if (fgets(key,sizeof(key) - 2,stdin))
X  {
X   (void) printf("\nAgain: ");
X   if (fgets(key2,sizeof(key2) - 2,stdin))
X    {
X     if (!strcmp(key,key2))
X      {
X       (void) printf("\n");
X       while ((fgets(key2,sizeof(key2),stdin) == NULL) || strcmp(key,key2))
X	{
X	 (void) printf("Bad password!\n");
X	 (void) sleep(1);
X	}
X      }
X     else (void) printf("\n");
X    }
X   else (void) printf("\n");
X  }
X else (void) printf("\n");
X (void) resetty();
X (void) exit(0);
X /*NOTREACHED*/
X}
END_OF_FILE
  echo shar: 20 control characters may be missing from \"'util/lock.c'\"
  if test 852 -ne `wc -c <'util/lock.c'`; then
    echo shar: \"'util/lock.c'\" unpacked with wrong size!
  fi
  # end of 'util/lock.c'
fi
if test -f 'util/mesg.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/mesg.1'\"
else
  echo shar: Extracting \"'util/mesg.1'\" \(814 characters\)
  sed "s/^X//" >'util/mesg.1' <<'END_OF_FILE'
X.TH mesg 1
X.SH NAME
Xmesg \- permit or deny messages
X.SH SYNOPSIS
X.B mesg
X[
X.B n
X] [
X.B y
X]
X.SH DESCRIPTION
XAfter
X.I mesg y,
Xother users can
Xuse
X.I write(1)
Xor
X.I talk(1)
Xto send messages to your terminal.
X.I mesg n
Xturns this off.
X.I mesg
Xapplies to your current terminal session;
Xtypically you'd put a
X.I mesg y
Xinto your
X.I \&.login,
X.I \&.cshrc,
Xor
X.I \&.profile.
X.PP
X.I mesg
Xwithout an argument tells you your current
Xmessaging status.
X.PP
X.I mesg
Xrequires its input to be your terminal session
X(or at least a session you own). All it really
Xdoes is handle the group-write bit on the terminal.
X.PP
X.I mesg
Xonly looks at the first letter of its first argument.
X.SH "EXIT VALUE"
XWithout an argument,
X.I mesg
Xexits with value 0 if messages are receivable,
X1 if not,
X2 upon error.
X.SH "SEE ALSO"
Xwrite(1), talk(1)
END_OF_FILE
  if test 814 -ne `wc -c <'util/mesg.1'`; then
    echo shar: \"'util/mesg.1'\" unpacked with wrong size!
  fi
  # end of 'util/mesg.1'
fi
if test -f 'util/mesg.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/mesg.c'\"
else
  echo shar: Extracting \"'util/mesg.c'\" \(1079 characters\)
  sed "s/^X//" >'util/mesg.c' <<'END_OF_FILE'
X/* Public domain. */
X
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <stdio.h>
X#include "sessutil.h"
Xextern unsigned short getuid();
X
X#define FOO (void) fstat(0,&st); \
Xif (which) (void) fchmod(0,(int) (st.st_mode | 0020)); \
Xelse (void) fchmod(0,(int) (st.st_mode & ~0020));
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X struct stat st;
X struct pty_session ps;
X int uid;
X int which;
X
X uid = getuid();
X
X if (argc == 1)
X  {
X   (void) setreuid(uid,uid);
X   (void) fstat(0,&st);
X   if (which = st.st_mode & 0020)
X     (void) printf("is y\n");
X   else
X     (void) printf("is n\n");
X   (void) exit(1 - which);
X  }
X else
X  {
X   switch(argv[1][0])
X    {
X     case 'y': which = 1; break;
X     case 'n': which = 0; break;
X     default: (void) fprintf(stderr,"mesg: usage: mesg [y] [n]\n"); exit(1);
X    }
X   if (pty_get_sess(0,uid,&ps) == -1)
X    {
X     (void) setreuid(uid,uid);
X     FOO
X    }
X   else
X     if (ps.uid != uid)
X       (void) fprintf(stderr,"not your session\n");
X     else
X      {
X       FOO
X       (void) setreuid(uid,uid);
X       FOO
X      }
X  }
X (void) exit(0);
X}
END_OF_FILE
  if test 1079 -ne `wc -c <'util/mesg.c'`; then
    echo shar: \"'util/mesg.c'\" unpacked with wrong size!
  fi
  # end of 'util/mesg.c'
fi
if test -f 'util/reconnect.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/reconnect.1'\"
else
  echo shar: Extracting \"'util/reconnect.1'\" \(1604 characters\)
  sed "s/^X//" >'util/reconnect.1' <<'END_OF_FILE'
X.TH reconnect 1
X.SH NAME
Xreconnect \- reconnect to a pty session
X.SH SYNOPSIS
X.B reconnect
X.I sn
X.SH DESCRIPTION
X.I reconnect
X.I sn
Xmeans
X``When this session finishes or is disconnected,
Xreconnect to the session named
X.I sn.''
XThis lets you get back to a
Xsession abandoned by
X.I disconnect
Xor by a previously hung up connection.
X.PP
XIf you are not currently
Xunder a
X.I pty
Xsession,
Xor if you would like to reconnect
Ximmediately without waiting for
Xthe current session to finish,
Xyou can use
X.EX
Xsess reconnect xx
X.EE
X.PP
XIf you leave out
Xa session name,
Xthe connection will simply drop
Xwhen its association with the
Xcurrent session is severed.
XThis is the normal behavior.
X.PP
XA
X.I reconnect
Xreplaces each that came before it.
X.PP
XOn systems
Xwhere
X.I pty
Xuses
Xfile descriptor passing,
Xa reconnected session is
Xhandled just as efficiently as
Xa session connected for the first time.
X.PP
X.I xreconnect
Xworks just like
X.I reconnect
Xbut handles sessions
Xstarted with
X.B\-xS.
X.SH DIAGNOSTICS
X.TP
X.I cannot find session
X.TP
X.I you don't own session
XThe standard input to
X.I reconnect
Xis not a pty session you own.
X.TP
X.I cannot find reconnector
X.I sn
Xis not the name of a currently disconnected session
Xthat you own.
X.TP
X.I cannot set reconnector
X.TP
X.I cannot unset reconnector
X.I reconnect
Xis unable to change this connection's
Xreconnection status.
X.TP
X.I xx set, will reconnect after yy drops
X.TP
X.I xx unset, won't reconnect after yy drops
XSuccess: you are using session
X.I yy,
Xand will reconnect to session
X.I xx
X(or to no session at all)
Xwhen this one drops.
X.SH "SEE ALSO"
Xpty(1),
Xsess(1),
Xdisconnect(1)
END_OF_FILE
  if test 1604 -ne `wc -c <'util/reconnect.1'`; then
    echo shar: \"'util/reconnect.1'\" unpacked with wrong size!
  fi
  # end of 'util/reconnect.1'
fi
if test -f 'util/reconnect.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/reconnect.c'\"
else
  echo shar: Extracting \"'util/reconnect.c'\" \(1244 characters\)
  sed "s/^X//" >'util/reconnect.c' <<'END_OF_FILE'
X/* Public domain. */
X
X#include <stdio.h>
X#include <signal.h>
X#include <errno.h>
Xextern int errno;
X#include "sessutil.h"
Xextern unsigned short getuid();
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X struct pty_session ps;
X int uid;
X
X uid = getuid();
X
X if (pty_get_sess(0,uid,&ps) == -1)
X  {
X   (void) fputs("reconnect: fatal: cannot find session\n",stderr);
X   (void) exit(1);
X  }
X if (ps.uid != uid)
X  {
X   (void) fputs("reconnect: fatal: you don't own session\n",stderr);
X   (void) exit(1);
X  }
X if (argv[1])
X   if (pty_get_rebyext(argv[1][0],argv[1][1],uid) == -1)
X    {
X     (void) fputs("reconnect: fatal: cannot find reconnector\n",stderr);
X     (void) exit(1);
X    }
X if (argv[1])
X  {
X   if (pty_set_sig(argv[1][0],argv[1][1],uid,&ps) == -1)
X    {
X     (void) fputs("reconnect: fatal: cannot set reconnector\n",stderr);
X     (void) exit(1);
X    }
X   (void) printf("reconnect: %c%c set, will reconnect after %c%c drops\n",
X		 argv[1][0],argv[1][1],ps.ext1,ps.ext2);
X  }
X else
X  {
X   if (pty_unset_sig(uid,&ps) == -1)
X    {
X     (void) fputs("reconnect: fatal: cannot unset reconnector\n",stderr);
X     (void) exit(1);
X    }
X   (void) printf("reconnect: unset, won't reconnect after %c%c drops\n",
X		 ps.ext1,ps.ext2);
X  }
X (void) exit(0);
X}
END_OF_FILE
  if test 1244 -ne `wc -c <'util/reconnect.c'`; then
    echo shar: \"'util/reconnect.c'\" unpacked with wrong size!
  fi
  # end of 'util/reconnect.c'
fi
if test -f 'util/script.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/script.1'\"
else
  echo shar: Extracting \"'util/script.1'\" \(1100 characters\)
  sed "s/^X//" >'util/script.1' <<'END_OF_FILE'
X.TH script 1
X.SH NAME
Xscript \- make typescript of terminal session
X.SH SYNOPSIS
X.B script
X[
X.B \-a
X] [
X.I file
X]
X.SH DESCRIPTION
X.I script
Xmakes a typescript of everything printed on your terminal.
XThe typescript is written to
X.I file,
Xor appended to
X.I file
Xif the
X.B \-a
Xoption is given.
XYou can print it later with
X.I lpr.
XIf you don't give a filename,
Xthe typescript is saved in the file
X.I typescript.
X.PP
XActually,
Xthis clone version of
X.I script
Xjust passes its options through to
X.I tee,
Xso you can list multiple files if you want.
X.PP
X.I script
Xruns whatever shell is in environment variable
X.I SHELL.
XThis clone version uses
X.I pty
Xto allocate a pseudo-terminal,
Xso the session is listed in
X.I /etc/utmp,
Xand lots of things work right that
Xdidn't work in the original.
XFor example:
X.I talk(1)
Xworks;
X.I mail(1)
Xworks;
Xyou can stop and restart the shell,
Xwith
X.B control-Z
Xin
X.I sh
Xor
X.B suspend
Xin
X.I csh;
Xand so on.
X.PP
XThe script ends when the forked shell exits.
XThis clone version is more careful than the original to
Xlet every last bit of output appear.
X.SH "SEE ALSO"
Xscript.tidy(1)
END_OF_FILE
  if test 1100 -ne `wc -c <'util/script.1'`; then
    echo shar: \"'util/script.1'\" unpacked with wrong size!
  fi
  # end of 'util/script.1'
fi
if test -f 'util/script.tidy.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/script.tidy.1'\"
else
  echo shar: Extracting \"'util/script.tidy.1'\" \(319 characters\)
  sed "s/^X//" >'util/script.tidy.1' <<'END_OF_FILE'
X.TH script.tidy 1
X.SH NAME
Xscript.tidy \- remove extra carriage returns and backspaces
X.SH SYNOPSIS
X.B script.tidy
X.SH DESCRIPTION
XThis filter
Xdoes a bit of postprocessing,
Xtypically on a typescript produced by
X.I script.
XIt removes extra carriage returns,
Xand wipes out backspaced characters.
X.SH "SEE ALSO"
Xscript(1)
END_OF_FILE
  if test 319 -ne `wc -c <'util/script.tidy.1'`; then
    echo shar: \"'util/script.tidy.1'\" unpacked with wrong size!
  fi
  # end of 'util/script.tidy.1'
fi
if test -f 'util/sess.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/sess.1'\"
else
  echo shar: Extracting \"'util/sess.1'\" \(1184 characters\)
  sed "s/^X//" >'util/sess.1' <<'END_OF_FILE'
X.TH sess 1
X.SH NAME
Xsess \- run a program under a disconnectable pty session
X.SH SYNOPSIS
X.B sess
X.I program
X.B [
X.I arg ...
X.B ]
X.SH DESCRIPTION
X.I sess,
Xwhich is really just
X.I pty -s,
Xruns a program under a pseudo-terminal
Xsession that can be easily disconnected and reconnected,
Xeven into the middle of a pipe.
X.PP
X.I sess
Xhas all the effects of
X.I condom,
Xbut sets the original
Xterminal to character mode
Xand lets the pseudo-terminal do
Xtty processing.
XThis means that changes to the terminal modes by
X.I program
Xwill take effect,
Xthough
Xthe original modes will be
Xrestored when
X.I program
Xstops or exits.
X.PP
X.I sess
Xalso enters the user into
X/etc/utmp by default;
Xthis can be turned off with
X.B\-xU.
X.PP
XWhen
X.I sess
Xreceives a HUP signal,
Xi.e., when the connection is manually hung up,
Xit disconnects
X.I program
Xfrom the outside world
Xand waits for a
X.I reconnect.
X.PP
XSessions are named by
Xtheir pseudo-terminal extension:
Xfor example,
Xa session under /dev/ttyp5
Xhas name p5.
XYou can use
X.I sessname
Xto give them more descriptive names,
Xprinted by
X.I sesslist.
X.SH "SEE ALSO"
Xpty(1),
Xcondom(1),
Xdisconnect(1),
Xreconnect(1),
Xsessname(1),
Xsesskill(1),
Xsesslist(1),
Xsessuser(1)
END_OF_FILE
  if test 1184 -ne `wc -c <'util/sess.1'`; then
    echo shar: \"'util/sess.1'\" unpacked with wrong size!
  fi
  # end of 'util/sess.1'
fi
if test -f 'util/sesskill.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/sesskill.1'\"
else
  echo shar: Extracting \"'util/sesskill.1'\" \(817 characters\)
  sed "s/^X//" >'util/sesskill.1' <<'END_OF_FILE'
X.TH sesskill 1
X.SH NAME
Xsesskill \- kill an outdated pty session
X.SH SYNOPSIS
X.B sesskill
X.I sn
X.SH DESCRIPTION
XNormally,
Xa disconnected pty session will
Xwait to be connected
X(and in the foreground)
Xbefore it produces output.
XEven if the program run under the session dies,
X.I pty
Xwill stick around, saving any last output.
X.I sesskill
X.I sn
Xkills the session named
X.I sn,
Xforcing it to throw away the output and exit.
X.PP
X.I xsesskill
Xis just like
X.I sesskill
Xbut applies to sessions started
Xwith
X.B\-xS.
X.SH DIAGNOSTICS
X.TP
X.I cannot find session
X.TP
X.I you don't own session
X.I sn
Xis not a session that you own.
X.TP
X.I session slave still alive
XSelf-explanatory.
X.TP
X.I cannot kill session master
X.I sesskill
Xis unable to communicate with
Xthe 
Xpseudo-terminal
Xmanager.
X.SH "SEE ALSO"
Xpty(1),
Xsess(1),
Xreconnect(1)
END_OF_FILE
  if test 817 -ne `wc -c <'util/sesskill.1'`; then
    echo shar: \"'util/sesskill.1'\" unpacked with wrong size!
  fi
  # end of 'util/sesskill.1'
fi
if test -f 'util/sesskill.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/sesskill.c'\"
else
  echo shar: Extracting \"'util/sesskill.c'\" \(1004 characters\)
  sed "s/^X//" >'util/sesskill.c' <<'END_OF_FILE'
X/* Public domain. */
X
X#include <stdio.h>
X#include <signal.h>
X#include <errno.h>
Xextern int errno;
X#include "sessutil.h"
Xextern unsigned short getuid();
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X struct pty_session ps;
X int uid;
X
X uid = getuid();
X
X if (!argv[1])
X  {
X   (void) fputs("Usage: sesskill ext\n",stderr);
X   (void) exit(1);
X  }
X if (pty_get_sessbyext(argv[1][0],argv[1][1],uid,&ps) == -1)
X  {
X   (void) fputs("sesskill: fatal: cannot find session\n",stderr);
X   (void) exit(1);
X  }
X if (ps.uid != uid)
X  {
X   (void) fputs("sesskill: fatal: you don't own session\n",stderr);
X   (void) exit(1);
X  }
X if ((kill(ps.slavepid,0) != -1) || (errno != ESRCH))
X  {
X   /* If all goes wrong, this test could allow a denial of service */
X   /* attack. Sigh. */
X   (void) fputs("sesskill: fatal: session slave still alive\n",stderr);
X   (void) exit(1);
X  }
X if (kill(ps.masterpid,SIGXCPU) == -1)
X  {
X   (void) perror("sesskill: fatal: cannot kill session master");
X   (void) exit(1);
X  }
X (void) exit(0);
X}
END_OF_FILE
  if test 1004 -ne `wc -c <'util/sesskill.c'`; then
    echo shar: \"'util/sesskill.c'\" unpacked with wrong size!
  fi
  # end of 'util/sesskill.c'
fi
if test -f 'util/sesslist.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/sesslist.1'\"
else
  echo shar: Extracting \"'util/sesslist.1'\" \(1155 characters\)
  sed "s/^X//" >'util/sesslist.1' <<'END_OF_FILE'
X.TH sesslist 1
X.SH NAME
Xsesslist \- list all pty sessions you own
X.SH SYNOPSIS
X.B sesslist
X.SH DESCRIPTION
X.I sesslist
Xinterprets each file in the
X.I pty
Xsession directory,
Xprinting the results on the standard output.
X.PP
X``session sn disconnected''
Xmeans that the named session is waiting for a
X.I reconnect.
X.PP
X``session sn sigler p1 master p2 slave p3''
Xmeans that there is a
X.I pty
Xsession named
X.I sn.
XThe session program is
X``slave'' process p3,
Xcontrolled by a
X``master'' process p2,
Xcurrently connected to a
X``signaller'' process p1.
X(If the session is disconnected,
Xthe signaller is not meaningful.)
XAt the end of the line,
X.I sesslist
Xwill print any name provided by
X.I sessname.
X.PP
X``session xx will drop into session yy''
Xmeans that the current connection to session xx
Xwill reconnect to session yy when it is severed.
X.PP
X.I xsesslist
Xis just like
X.I sesslist
Xbut applies to sessions started
Xwith
X.B\-xS.
X.SH DIAGNOSTICS
X.TP
X.I unknown file type
X.I sesslist
Xdoes not understand a file name.
X.TP
X.I cannot open
X.TP
X.I cannot open
XThese should not happen.
XReport them to your system administrator.
X.SH "SEE ALSO"
Xpty(1),
Xsess(1),
Xsessname(1)
END_OF_FILE
  if test 1155 -ne `wc -c <'util/sesslist.1'`; then
    echo shar: \"'util/sesslist.1'\" unpacked with wrong size!
  fi
  # end of 'util/sesslist.1'
fi
if test -f 'util/sessname.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/sessname.1'\"
else
  echo shar: Extracting \"'util/sessname.1'\" \(1007 characters\)
  sed "s/^X//" >'util/sessname.1' <<'END_OF_FILE'
X.TH sessname 1
X.SH NAME
Xsessname \- provide a more descriptive name for the current pty session
X.SH SYNOPSIS
X.B sessname
X[
X.I name
X]
X.SH DESCRIPTION
X.I sessname
Xadds
X.I name
Xto the information listed by
X.I sesslist.
XDon't confuse this extra name with
Xthe base name of the session,
Xwhich is the last two characters of the
Xpseudo-terminal filename.
X.PP
XWithout an argument,
X.I sessname
Xprints the name of the current session.
X.PP
X.I xsessname
Xis just like
X.I sessname
Xbut applies to sessions started
Xwith
X.B\-xS.
X.SH DIAGNOSTICS
X.TP
X.I cannot find session
X.TP
X.I you don't own session
XThe standard input to
X.I sessname
Xis not a session that you own.
X.TP
X.I not child of session slave
XThe parent to
X.I sessname
Xis not the head process in the session.
X.TP
X.I renaming failed
X.I sessname
Xis unable to set the long name of the session.
XThis shouldn't happen.
X.SH RESTRICTIONS
X.I name
Xis limited to 100 characters.
X.PP
XAt the moment,
Xthere's no way to unname a session.
X.SH "SEE ALSO"
Xpty(1),
Xsess(1),
Xsesslist(1)
END_OF_FILE
  if test 1007 -ne `wc -c <'util/sessname.1'`; then
    echo shar: \"'util/sessname.1'\" unpacked with wrong size!
  fi
  # end of 'util/sessname.1'
fi
if test -f 'util/sessname.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/sessname.c'\"
else
  echo shar: Extracting \"'util/sessname.c'\" \(1052 characters\)
  sed "s/^X//" >'util/sessname.c' <<'END_OF_FILE'
X/* Public domain. */
X
X#include <stdio.h>
X#include <strings.h>
X#include "sessutil.h"
Xextern unsigned short getuid();
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X struct pty_session ps;
X int uid;
X char buf[100];
X int s;
X
X uid = getuid();
X
X if (pty_get_sess(0,uid,&ps) == -1)
X  {
X   (void) fputs("sessname: fatal: cannot find session\n",stderr);
X   (void) exit(1);
X  }
X if (ps.uid != uid)
X  {
X   (void) fputs("sessname: fatal: you don't own session\n",stderr);
X   (void) exit(1);
X  }
X if (ps.slavepid != getppid())
X  {
X   (void) fputs("sessname: fatal: not child of session slave\n",stderr);
X   (void) exit(1);
X  }
X if (argc == 1)
X   if (pty_get_sessname(0,uid,buf,sizeof(buf)) == -1)
X     (void) printf("session %c%c unnamed\n",ps.ext1,ps.ext2);
X   else
X     (void) printf("session %c%c: %s\n",ps.ext1,ps.ext2,buf);
X else
X  {
X   s = strlen(argv[1]) + 1;
X   if (s > 100)
X     s = 100;
X   if (pty_set_sessname(0,uid,argv[1],s) == -1)
X    {
X     (void) fputs("sessname: fatal: renaming failed\n",stderr);
X     (void) exit(1);
X    }
X  }
X  
X (void) exit(0);
X}
END_OF_FILE
  if test 1052 -ne `wc -c <'util/sessname.c'`; then
    echo shar: \"'util/sessname.c'\" unpacked with wrong size!
  fi
  # end of 'util/sessname.c'
fi
if test -f 'util/sessutil.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/sessutil.h'\"
else
  echo shar: Extracting \"'util/sessutil.h'\" \(357 characters\)
  sed "s/^X//" >'util/sessutil.h' <<'END_OF_FILE'
X#ifndef SESSUTIL_H
X#define SESSUTIL_H
X
Xstruct pty_session
X {
X  char ext1;
X  char ext2;
X  int uid;
X  int siglerpid;
X  int masterpid;
X  int slavepid;
X }
X;
X
Xint pty_sessdir();
Xint pty_get_sess();
Xint pty_get_sessbyext();
Xint pty_set_sess();
Xint pty_get_sessname();
Xint pty_set_sessname();
Xint pty_get_rebyext();
Xint pty_set_sig();
Xint pty_unset_sig();
X
X#endif
END_OF_FILE
  if test 357 -ne `wc -c <'util/sessutil.h'`; then
    echo shar: \"'util/sessutil.h'\" unpacked with wrong size!
  fi
  # end of 'util/sessutil.h'
fi
if test -f 'util/u.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/u.1'\"
else
  echo shar: Extracting \"'util/u.1'\" \(434 characters\)
  sed "s/^X//" >'util/u.1' <<'END_OF_FILE'
X.TH u 1
X.SH NAME
Xu \- compact list of users who are on the system
X.SH SYNOPSIS
X.B u
X.SH DESCRIPTION
X.I u
Xlists the login names of the users currently on the system in a compact,
Xsorted,
Xone-line format.
X.PP
XThe original version of this program eliminates duplicates.
X(Actually, it doesn't even do that correctly.)
XThis clone version prints exactly each user as many times
Xas /etc/utmp lists.
X.SH FILES
X/etc/utmp
X.SH "SEE ALSO"
Xwho(1)
END_OF_FILE
  if test 434 -ne `wc -c <'util/u.1'`; then
    echo shar: \"'util/u.1'\" unpacked with wrong size!
  fi
  # end of 'util/u.1'
fi
if test -f 'util/u.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/u.c'\"
else
  echo shar: Extracting \"'util/u.c'\" \(933 characters\)
  sed "s/^X//" >'util/u.c' <<'END_OF_FILE'
X/* Public domain. */
X#include <stdio.h>
X#include <utmp.h>
X#include <strings.h>
Xextern char *malloc();
X#define PTYUTMP_FILE "/etc/utmp"
X
Xint compar(s,t)
Xchar (**s)[8];
Xchar (**t)[8];
X{
X return -strncmp(&(**s)[0],&(**t)[0],8);
X}
X
Xmain()
X{
X register FILE *fi;
X struct utmp ut;
X char (*us)[8];
X char (**up)[8];
X int lines = 0;
X int i = 0;
X 
X if (fi = fopen(PTYUTMP_FILE,"r"))
X   while (fread((char *) &ut,sizeof(ut),1,fi))
X     if (ut.ut_name[0])
X       lines++;
X (void) fclose(fi);
X us = malloc(sizeof(*us) * (lines + 50));
X up = malloc(sizeof(*up) * (lines + 50));
X if (fi = fopen(PTYUTMP_FILE,"r"))
X   while (fread((char *) &ut,sizeof(ut),1,fi))
X     if ((ut.ut_name[0]) && (i < lines + 50))
X      {
X       (void) strncpy(us[i],ut.ut_name,8);
X       up[i] = us + i;
X       i++;
X      }
X (void) fclose(fi);
X (void) qsort(up,i,sizeof(*up),compar);
X
X while (i-- > 0)
X   (void) printf((i ? "%.8s " : "%.8s\n"),up[i]);
X
X (void) exit(0);
X}
END_OF_FILE
  if test 933 -ne `wc -c <'util/u.c'`; then
    echo shar: \"'util/u.c'\" unpacked with wrong size!
  fi
  # end of 'util/u.c'
fi
if test -f 'util/wall.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/wall.1'\"
else
  echo shar: Extracting \"'util/wall.1'\" \(412 characters\)
  sed "s/^X//" >'util/wall.1' <<'END_OF_FILE'
X.TH wall 1
X.SH NAME
Xwall \- write to all users
X.SH SYNOPSIS
X.B wall
X.SH DESCRIPTION
X.I wall
Xprompts for a message with
X``Broadcast Message,''
Xthen reads its standard input until end-of-file.
XIt then sends this message
Xto all logged in users.
X.PP
XNaturally,
X.I mesg
Xprotections apply.
X.SH FILES
X/dev/tty*
X.br
X/etc/utmp
X.SH RESTRICTIONS
XThe message is limited to 10000 characters.
X.SH "SEE ALSO"
Xmesg(1),
Xwrite(1)
END_OF_FILE
  if test 412 -ne `wc -c <'util/wall.1'`; then
    echo shar: \"'util/wall.1'\" unpacked with wrong size!
  fi
  # end of 'util/wall.1'
fi
if test -f 'util/wall.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/wall.c'\"
else
  echo shar: Extracting \"'util/wall.c'\" \(1577 characters\)
  sed "s/^X//" >'util/wall.c' <<'END_OF_FILE'
X/* Public domain. */
X
X#include <sys/types.h>
X#include <sys/timeb.h>
X#include <sys/file.h>
X#ifdef BSD
X#include <limits.h>
X#endif
X#include <stdio.h>
X#include <strings.h>
X#include <utmp.h>
X#include <pwd.h>
X#include <time.h>
X#include <ctype.h>
Xextern unsigned short getuid();
Xextern char *ttyname();
Xextern long time();
X#define PTYUTMP_FILE "/etc/utmp"
X
Xmain()
X{ 
X register FILE *fi;
X struct utmp ut;
X char fntty[30];
X int fd;
X char buf[10000];
X char *username;
X struct passwd *pw;
X char hostname[64];
X char *ttyn;
X long t;
X struct tm *tm;
X int r;
X int pos;
X
X if (!(pw = getpwuid((int) getuid())))
X  {
X   (void) fprintf(stderr,"write: who are you?\n");
X   (void) exit(1);
X  }
X username = pw->pw_name;
X
X (void) gethostname(hostname,sizeof(hostname));
X
X if (!(ttyn = ttyname(2)))
X  {
X   (void) fprintf(stderr,"wall: Can't find your tty\n");
X   (void) exit(1);
X  }
X
X t = time((long *) 0);
X tm = localtime(&t);
X
X (void) sprintf(buf,"\nBroadcast message from %s@%s on %s at %d:%02d ...\n\n",
X		username,hostname,ttyn + 5,tm->tm_hour,tm->tm_min);
X pos = strlen(buf);
X (void) write(1,buf + 1,pos - 1);
X while ((pos < 10000) && ((r = read(0,buf + pos,10000 - pos)) > 0))
X   pos += r;
X
X if (fi = fopen(PTYUTMP_FILE,"r"))
X   while (fread((char *) &ut,sizeof(ut),1,fi))
X     if (ut.ut_name[0])
X      {
X       (void) sprintf(fntty,"/dev/%.8s",ut.ut_line);
X       if ((fd = open(fntty,O_WRONLY)) == -1)
X         (void) fprintf(stderr,"wall: cannot write to %.8s\n",ut.ut_line);
X       else
X        {
X	 (void) write(fd,buf,pos);
X         (void) close(fd);
X        }
X      }
X
X (void) exit(0);
X}
END_OF_FILE
  echo shar: 1 control character may be missing from \"'util/wall.c'\"
  if test 1577 -ne `wc -c <'util/wall.c'`; then
    echo shar: \"'util/wall.c'\" unpacked with wrong size!
  fi
  # end of 'util/wall.c'
fi
if test -f 'util/who.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/who.1'\"
else
  echo shar: Extracting \"'util/who.1'\" \(693 characters\)
  sed "s/^X//" >'util/who.1' <<'END_OF_FILE'
X.TH who 1
X.SH NAME
Xwho \- who is on the system
X.SH SYNOPSIS
X.B who
X[
X.I file
X] [
X.B "am I"
X]
X.SH DESCRIPTION
X.I who
Xlists the login name, terminal name, and login time
Xfor each current user.
XNormally
X.I who
Xuses
X.I /etc/utmp,
Xand omits
Xlogged-out terminals.
XIf you give it a
X.I file,
Xsuch as
X/usr/adm/wtmp,
Xit will use that file instead,
Xand include logouts as lines with a blank username.
XReboots have an x in place of 
X.I ttyxx.
X.PP
XWith two arguments,
Xas in
X.I who am I
X(and also 
X.I who are you),
X.I who
Xtells who you are logged in as.
XNote that in this clone version,
X.I who
Xgives a meaningful error when its input is not a terminal.
X.SH FILES
X/etc/utmp
X.SH "SEE ALSO"
Xgetuid(2), utmp(5)
END_OF_FILE
  if test 693 -ne `wc -c <'util/who.1'`; then
    echo shar: \"'util/who.1'\" unpacked with wrong size!
  fi
  # end of 'util/who.1'
fi
if test -f 'util/who.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/who.c'\"
else
  echo shar: Extracting \"'util/who.c'\" \(1208 characters\)
  sed "s/^X//" >'util/who.c' <<'END_OF_FILE'
X/* Public domain. */
X#include <stdio.h>
X#include <utmp.h>
X#include <strings.h>
X#include <time.h>
Xextern char *ttyname();
X#define PTYUTMP_FILE "/etc/utmp"
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X FILE *fi;
X struct utmp ut;
X char fn[100];
X char ttyn[100];
X char hostname[120];
X int whoami = 0;
X 
X if (argc > 3) exit(0);
X if (argc > 2)
X  {
X   whoami = 1;
X   if (!isatty(0))
X    {
X     fprintf(stderr,"who: Not a tty\n");
X     exit(1);
X    }
X   (void) strcpy(ttyn,ttyname(0) + 5);
X   (void) gethostname(hostname,120);
X  }
X if (argc == 2)
X   (void) strncpy(fn,argv[1],100);
X else
X   (void) strncpy(fn,PTYUTMP_FILE,100);
X
X if ((fi = fopen(fn,"r")) == NULL)
X  {
X   (void) sprintf(hostname,"who: %s",fn);
X   (void) perror(hostname);
X   (void) exit(1);
X  }
X
X while (fread((char *) &ut,sizeof(ut),1,fi))
X  {
X   if (ut.ut_name[0] || (argc > 1))
X     if ((!whoami) || (!strncmp(ut.ut_line,ttyn,8)))
X      {
X       if (whoami)
X	 (void) printf("%s!",hostname);
X       (void) printf("%-8.8s %-8.8s%-12.12s",ut.ut_name,ut.ut_line,
X		     asctime(localtime(&ut.ut_time)) + 4);
X       if (ut.ut_host[0])
X	 (void) printf("	(%.16s)",ut.ut_host);
X       (void) printf("\n");
X      }
X  }
X (void) fclose(fi);
X (void) exit(0);
X}
END_OF_FILE
  if test 1208 -ne `wc -c <'util/who.c'`; then
    echo shar: \"'util/who.c'\" unpacked with wrong size!
  fi
  # end of 'util/who.c'
fi
if test -f 'util/write.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'util/write.1'\"
else
  echo shar: Extracting \"'util/write.1'\" \(1761 characters\)
  sed "s/^X//" >'util/write.1' <<'END_OF_FILE'
X.TH write 1
X.SH NAME
Xwrite \- write to another user
X.SH SYNOPSIS
X.B write
X.I user
X[
X.I ttyname
X]
X.SH DESCRIPTION
X.I write
Xcopies lines from your terminal to that of
Xanother user.
XThis clone version
Xstarts and (if you don't kill the process)
Xends your message with identifying lines.
XIt also
Xprecedes each line with your username.
X.PP
XIf you want to write to a user who is logged in more than once,
Xinclude the terminal name as
X.I ttyname.
X(This reflects several failures in the pseudo-terminal model.)
X.PP
XThe other user can use
X.I mesg
Xto allow or deny
X.I write
Xpermission.
XIn many recent versions of
X.I write,
Xyou cannot write to a user unless you are also allowing messages;
Xunfortunately, this adds absolutely no security, because you can
Xturn messages right back off after starting
X.I write.
XThis clone version exhibits the right behavior:
Xit checks
X.I mesg
Xpermission on the other end
Xbefore writing each line.
X.PP
XThis version of
X.I write
Xdoes not
Xallow shell escapes.
X.PP
XThere are many popular ways of using
X.I write
X(perhaps the most common being to
Xuse
X.I talk
Xinstead).
XTypically each user ends each series of lines
Xwith a distinctive signal, such as
X``ga'' (go ahead),
Xso that the other user can type without
Xworrying about messed-up output.
XThe number of abbreviations used in
Xscreen conversation is immense.
X.PP
XThis clone version of
X.I write
Xuses the standard input,
Xrather than the standard error,
Xto determine your tty.
X.PP
X.I write
Xreplaces unprintable characters by
Xcarets upon output.
X.SH RESTRICTIONS
XLines longer than 500 characters
Xwill be split in two.
X.PP
X.I write
Xsleeps for a second after sending each line.
XThis restriction means that you can't
Xflood someone else's screen with a large text.
X.SH "SEE ALSO"
Xmesg(1),
Xwho(1),
Xmail(1)
END_OF_FILE
  if test 1761 -ne `wc -c <'util/write.1'`; then
    echo shar: \"'util/write.1'\" unpacked with wrong size!
  fi
  # end of 'util/write.1'
fi
echo shar: End of archive 5 \(of 6\).
cp /dev/null ark5isdone
MISSING=""
for I in 1 2 3 4 5 6 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 6 archives.
    rm -f ark[1-9]isdone
else
    echo You still must unpack the following archives:
    echo "        " ${MISSING}
fi
exit 0
exit 0 # Just in case...
-- 
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.



More information about the Comp.sources.unix mailing list