home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-07-25 | 111.6 KB | 4,699 lines |
- Newsgroups: comp.sources.unix
- From: mlschroe@immd4.informatik.uni-erlangen.de (Michael Schroeder)
- Subject: v26i303: screen-3.5 - screen manager with VT100/ANSI terminal emulation, V3.5, Part04/10
- Sender: unix-sources-moderator@gw.home.vix.com
- Approved: vixie@gw.home.vix.com
-
- Submitted-By: mlschroe@immd4.informatik.uni-erlangen.de (Michael Schroeder)
- Posting-Number: Volume 26, Issue 303
- Archive-Name: screen-3.5/part04
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 4 (of 10)."
- # Contents: configure.in mark.c tty.c.dist tty.sh window.c
- # Wrapped by vixie@gw.home.vix.com on Sun Jul 25 12:57:18 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'configure.in' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'configure.in'\"
- else
- echo shar: Extracting \"'configure.in'\" \(20123 characters\)
- sed "s/^X//" >'configure.in' <<'END_OF_FILE'
- Xdnl Process this file with autoconf to produce a configure script.
- Xdnl
- Xdnl $Id: configure.in,v 1.4 1993/07/21 15:42:59 mlschroe Exp $ FAU
- Xdnl
- Xdnl Many thanks to David McKenzie for writing autoconf and
- Xdnl providing a sample configure.in file for screen.
- Xdnl
- XAC_INIT(screen.c)
- XAC_CONFIG_HEADER(config.h)
- X
- Xdnl
- Xdnl Define some useful macros
- Xdnl
- Xdefine(AC_PROGRAM_SOURCE,
- X[AC_REQUIRE([AC_PROG_CPP])AC_PROVIDE([$0])cat > conftest.c <<EOF
- X[$1]
- X_CUT_HERE_
- X[$2]
- XEOF
- Xeval "$CPP $DEFS conftest.c 2>/dev/null | sed -e '1,/_CUT_HERE_/d' > conftest.out"
- X. ./conftest.out
- Xrm -f conftest*
- X])dnl
- X
- Xrev=`sed < patchlevel.h -n -e '/#define REV/s/#define REV *//p'`
- Xvers=`sed < patchlevel.h -n -e '/#define VERS/s/#define VERS *//p'`
- Xpat=`sed < patchlevel.h -n -e '/#define PATCHLEVEL/s/#define PATCHLEVEL *//p'`
- XVERSION="$rev.$vers.$pat"
- Xecho "this is screen version $VERSION"
- XAC_SUBST(VERSION)
- X
- XAC_PROG_CC
- XAC_PROG_CPP
- XAC_GCC_TRADITIONAL
- XAC_ISC_POSIX
- X
- X
- XAC_TEST_PROGRAM(main(){exit(0);},,echo "Can't run the compiler - sorry";exit)
- XAC_PROG_AWK
- X
- XAC_PROG_INSTALL
- X
- Xdnl
- Xdnl **** special unix variants ****
- Xdnl
- Xif test -n "$ISC"; then
- X AC_DEFINE(ISC) LIBS="$LIBS -linet"
- Xfi
- X
- Xecho checking for MIPS
- Xif test -f /lib/libmld.a || test -f /usr/lib/libmld.a || test -f /usr/lib/cmplrs/cc/libmld.a; then
- XAC_DEFINE(MIPS) LIBS="$LIBS -lmld" # for nlist.
- XAC_COMPILE_CHECK(wait3, , [wait3();], ,
- XAC_COMPILE_CHECK(wait2, , [wait2();],
- Xdnl John Rouillard (rouilj@sni-usa.com):
- Xdnl need -I/usr/include/bsd in RISCOS otherwise sockets are broken, no
- Xdnl job control etc.
- Xdnl Detect RISCOS if wait2 is present, but not wait3.
- XAC_DEFINE(USE_WAIT2) LIBS="$LIBS -lbsd" ; CC="$CC -I/usr/include/bsd"
- X))
- Xfi
- X
- Xecho checking for Ultrix
- XAC_PROGRAM_EGREP(yes,
- X[#if defined(ultrix) || defined(__ultrix)
- X yes
- X#endif
- X], ULTRIX=1)
- X
- Xif test -n "$ULTRIX"; then
- X test -z "$GCC" && CC="$CC -YBSD"
- Xelse
- X # POSIX termios is broken on Ultrix so don't look for it.
- Xecho checking for POSIX.1
- XAC_PROGRAM_EGREP(yes,
- X[#include <sys/types.h>
- X#include <unistd.h>
- Xmain () {
- X#ifdef _POSIX_VERSION
- X yes
- X#endif
- X], echo "- you have a POSIX system";AC_DEFINE(POSIX))
- Xfi
- X
- XAC_COMPILE_CHECK([System V],
- X[#include <sys/types.h>
- X#include <signal.h>
- X#include <fcntl.h>], [int x = SIGCHLD | FNDELAY;], , AC_DEFINE(SYSV))
- X
- Xecho checking for sequent/ptx
- XAC_PROGRAM_EGREP(yes,
- X[#ifdef _SEQUENT_
- X yes
- X#endif
- X], LIBS="$LIBS -lsocket -linet";seqptx=1)
- X
- Xoldlibs="$LIBS"
- XLIBS="$LIBS -lelf"
- XAC_COMPILE_CHECK(SVR4,,,
- XAC_HEADER_CHECK(dwarf.h, AC_DEFINE(SVR4) ; AC_DEFINE(BUGGYGETLOGIN) ; LIBS="$LIBS -lelf",
- XAC_HEADER_CHECK(elf.h, AC_DEFINE(SVR4) ; AC_DEFINE(BUGGYGETLOGIN) ; LIBS="$LIBS -lelf"))
- X,LIBS="$oldlibs")
- X
- X
- Xdnl
- Xdnl **** typedefs / declarations ****
- Xdnl
- X
- Xecho checking for putenv declaration
- XAC_PROGRAM_EGREP([putenv( | |\()],[#include <sys/types.h>
- X#include <unistd.h>
- X#include <stdlib.h>
- X],AC_DEFINE(PUTENV_DECLARED))
- X
- Xecho checking for getdtablesize declaration
- XAC_PROGRAM_EGREP([getdtablesize( | |\()],[#include <sys/types.h>
- X#include <unistd.h>
- X],AC_DEFINE(GETDTABLESIZE_DECLARED))
- X
- Xecho checking for select declaration
- XAC_PROGRAM_EGREP([select( | |\()],[#include <sys/types.h>
- X#include <sys/time.h>
- X#include <unistd.h>
- X],AC_DEFINE(SELECT_DECLARED))
- X
- Xecho checking for vsprintf declaration
- XAC_PROGRAM_EGREP([vsprintf( | |\()],[#include <sys/types.h>
- X#include <stdio.h>
- X#ifdef __STDC__
- X#include <stdarg.h>
- X#else
- X#include <varargs.h>
- X#endif
- X],AC_DEFINE(VPRNT_DECLARED))
- X
- Xecho checking for setreuid declaration
- XAC_PROGRAM_EGREP([setres?uid( | |\()],[#include <sys/types.h>
- X#include <unistd.h>
- X],AC_DEFINE(REUID_DECLARED))
- X
- Xecho checking for wait declaration
- XAC_PROGRAM_EGREP([wait( | |\()],[#include <sys/types.h>
- X#include <signal.h>
- X#include <sys/wait.h>
- X],AC_DEFINE(WAITSTUFF_DECLARED))
- X
- Xecho checking for memfuncs declaration
- XAC_PROGRAM_EGREP([(memcpy|memmove|bcopy)( | |\()],[#include <sys/types.h>
- X#include <unistd.h>
- X#include <string.h>
- X#include <strings.h>
- X],AC_DEFINE(MEMFUNCS_DECLARED))
- X
- Xecho checking for [index] declaration
- XAC_PROGRAM_EGREP([[index( | |\()]],[#include <sys/types.h>
- X#include <strings.h>
- X],AC_DEFINE(INDEX_DECLARED))
- X
- Xecho checking for crypt declaration
- XAC_PROGRAM_EGREP([crypt( | |\()],[#include <sys/types.h>
- X#include <unistd.h>
- X],AC_DEFINE(CRYPT_DECLARED))
- X
- Xecho checking for mknod declaration
- XAC_PROGRAM_EGREP([mknod( | |\()],[#include <sys/types.h>
- X#include <sys/stat.h>
- X],AC_DEFINE(MKNOD_DECLARED))
- X
- Xecho checking for setpgid declaration
- XAC_PROGRAM_EGREP([setpgid( | |\()],[#include <sys/types.h>
- X#include <unistd.h>
- X],AC_DEFINE(SETPGID_DECLARED))
- X
- Xecho checking for kill declaration
- XAC_PROGRAM_EGREP([kill( | |\()],[#include <sys/types.h>
- X#include <unistd.h>
- X#include <signal.h>
- X],AC_DEFINE(KILLSTUFF_DECLARED))
- X
- Xecho checking for gethostname declaration
- XAC_PROGRAM_EGREP([gethostname( | |\()],[#include <sys/types.h>
- X#include <unistd.h>
- X],AC_DEFINE(GETHOSTNAME_DECLARED))
- X
- Xecho checking for pid_t
- XAC_PROGRAM_EGREP(pid_t,[#include <sys/types.h>
- X],AC_DEFINE(PID_T_DEFINED))
- X
- Xecho checking for sig_t
- XAC_PROGRAM_EGREP(sig_t,[#include <sys/types.h>
- X#include <signal.h>
- X],AC_DEFINE(SIG_T_DEFINED))
- X
- Xecho checking for uid_t
- XAC_PROGRAM_EGREP(uid_t,[#include <sys/types.h>
- X],AC_DEFINE(UID_T_DEFINED))
- X
- Xdnl
- Xdnl **** Job control ****
- Xdnl
- X
- XAC_COMPILE_CHECK([BSD job control],
- X[#include <sys/types.h>
- X#include <sys/ioctl.h>
- X], [
- X#ifdef POSIX
- Xtcsetpgrp(0, 0);
- X#else
- Xint x = TIOCSPGRP;
- X#ifdef SYSV
- Xsetpgrp();
- X#else
- Xint y = TIOCNOTTY;
- X#endif
- X#endif
- X], echo "- you have jobcontrol";AC_DEFINE(BSDJOBS), echo "- you don't have jobcontrol")
- X
- Xdnl
- Xdnl **** setreuid() ****
- Xdnl
- XAC_COMPILE_CHECK(setreuid, ,
- X[
- X#ifdef hpux
- Xsetresuid(0, 0, 0);
- X#else
- Xsetreuid(0, 0);
- X#endif
- X], , AC_DEFINE(NOREUID))
- X
- X
- Xdnl **** select() ****
- Xdnl
- X
- XAC_COMPILE_CHECK(select,,[select(0, 0, 0, 0, 0);],,
- XLIBS="$LIBS -lnet -lnsl"
- XAC_COMPILE_CHECK(select with $LIBS,,[select(0, 0, 0, 0, 0);],,
- Xecho '!!! no select - no screen';exit)
- X)
- Xdnl
- Xdnl **** FIFO tests ****
- Xdnl
- X
- Xecho checking fifos
- XAC_TEST_PROGRAM([
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <fcntl.h>
- X
- X#ifndef O_NDELAY
- X#define O_NDELAY O_NONBLOCK
- X#endif
- X#ifndef S_IFIFO
- X#define S_IFIFO 0010000
- X#endif
- X
- Xchar *fin = "/tmp/conftest$$";
- X
- Xmain()
- X{
- X struct stat stb;
- X int f;
- X
- X (void)alarm(5);
- X if (mknod(fin, S_IFIFO|0777, 0))
- X exit(1);
- X if (stat(fin, &stb) || (stb.st_mode & S_IFIFO) != S_IFIFO)
- X exit(1);
- X close(0);
- X if (open(fin, O_RDWR | O_NDELAY))
- X exit(1);
- X if (write(0, "TEST", 4) == -1)
- X exit(1);
- X f = 1;
- X if (select(1, &f, 0, 0, 0) == -1)
- X exit(1);
- X exit(0);
- X}
- X], echo "- your fifos are usable"; fifo=1, echo "- your fifos are not usable")
- Xrm -f /tmp/conftest*
- X
- Xif test -n "$fifo"; then
- Xecho "checking for broken fifo implementation"
- XAC_TEST_PROGRAM([
- X#include <sys/types.h>
- X#include <fcntl.h>
- X#include <sys/time.h>
- X#include <sys/stat.h>
- X
- X#ifndef O_NDELAY
- X#define O_NDELAY O_NONBLOCK
- X#endif
- X#ifndef S_IFIFO
- X#define S_IFIFO 0010000
- X#endif
- X
- Xchar *fin = "/tmp/conftest$$";
- X
- Xmain()
- X{
- X struct timeval tv;
- X int r, x;
- X
- X if (mknod(fin, S_IFIFO|0600))
- X exit(1);
- X close(0);
- X if (open(fin, O_RDONLY|O_NDELAY))
- X exit(1);
- X r = 1;
- X tv.tv_sec = 1;
- X tv.tv_usec = 0;
- X if (select(1, &r, 0, 0, &tv))
- X exit(1);
- X exit(0);
- X}
- X], echo "- your implementation is ok", echo "- you have a broken implementation";AC_DEFINE(BROKEN_PIPE);fifobr=1)
- Xrm -f /tmp/conftest*
- Xfi
- X
- Xdnl
- Xdnl **** SOCKET tests ****
- Xdnl
- X
- Xecho checking sockets
- XAC_TEST_PROGRAM([
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <sys/un.h>
- X#include <fcntl.h>
- X
- X#ifndef O_NDELAY
- X#define O_NDELAY O_NONBLOCK
- X#endif
- X#ifndef FNDELAY
- X#define FNDELAY O_NDELAY
- X#endif
- X
- Xchar *son = "/tmp/conftest$$";
- X
- Xmain()
- X{
- X int s1, s2, s3, l;
- X struct sockaddr_un a;
- X
- X (void)alarm(5);
- X if ((s1 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
- X exit(1);
- X a.sun_family = AF_UNIX;
- X strcpy(a.sun_path, son);
- X (void) unlink(son);
- X if (bind(s1, (struct sockaddr *) &a, strlen(son)+2) == -1)
- X exit(1);
- X if (listen(s1, 2))
- X exit(1);
- X if (fork() == 0)
- X {
- X if ((s2 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
- X kill(getppid(), 3);
- X (void)connect(s2, &a, strlen(son) + 2);
- X if (write(s2, "HELLO", 5) == -1)
- X kill(getppid(), 3);
- X exit(0);
- X }
- X l = sizeof(a);
- X close(0);
- X if (accept(s1, &a, &l))
- X exit(1);
- X l = 1;
- X if (select(1, &l, 0, 0, 0) == -1)
- X exit(1);
- X exit(0);
- X}
- X], echo "- your sockets are usable"; sock=1, echo "- your sockets are not usable")
- Xrm -f /tmp/conftest*
- X
- Xif test -n "$sock"; then
- Xecho "checking socket implementation"
- XAC_TEST_PROGRAM([
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <sys/socket.h>
- X#include <sys/un.h>
- X
- Xchar *son = "/tmp/conftest$$";
- X
- Xmain()
- X{
- X int s;
- X struct stat stb;
- X struct sockaddr_un a;
- X if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
- X exit(0);
- X a.sun_family = AF_UNIX;
- X strcpy(a.sun_path, son);
- X (void) unlink(son);
- X if (bind(s, (struct sockaddr *) &a, strlen(son)+2) == -1)
- X exit(0);
- X if (stat(son, &stb))
- X exit(1);
- X close(s);
- X exit(0);
- X}
- X],echo "- you are normal",echo "- unix domain sockets are not kept in the filesystem";AC_DEFINE(SOCK_NOT_IN_FS);socknofs=1)
- Xrm -f /tmp/conftest*
- Xfi
- X
- X
- Xdnl
- Xdnl **** choose sockets or fifos ****
- Xdnl
- Xif test -n "$fifo"; then
- X if test -n "$sock"; then
- X if test -n "$nore"; then
- X echo "- hmmm... better take the fifos"
- X AC_DEFINE(NAMEDPIPE)
- X elif test -n "$fifobr"; then
- X echo "- as your fifos are broken lets use the sockets."
- X else
- X echo "- both sockets and fifos usable. let's take fifos."
- X AC_DEFINE(NAMEDPIPE)
- X fi
- X else
- X echo "- using named pipes, of course"
- X AC_DEFINE(NAMEDPIPE)
- X fi
- Xelif test -n "$sock"; then
- X echo "- using unix-domain sockets, of course"
- Xelse
- X echo "!!! you have neither usable sockets nor usable pipes -> no screen"
- X exit
- Xfi
- X
- Xdnl
- Xdnl **** check the select implementation ****
- Xdnl
- X
- Xecho "checking select return value"
- XAC_TEST_PROGRAM([
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <fcntl.h>
- X
- Xchar *nam = "/tmp/conftest$$";
- X
- X#ifdef NAMEDPIPE
- X
- X#ifndef O_NDELAY
- X#define O_NDELAY O_NONBLOCK
- X#endif
- X#ifndef S_IFIFO
- X#define S_IFIFO 0010000
- X#endif
- X
- X
- Xmain()
- X{
- X int l;
- X
- X (void)alarm(5);
- X if (mknod(nam, S_IFIFO|0777, 0))
- X exit(1);
- X close(0);
- X if (open(nam, O_RDWR | O_NDELAY))
- X exit(1);
- X if (write(0, "TEST", 4) == -1)
- X exit(1);
- X
- X#else
- X
- X#include <sys/types.h>
- X#include <sys/socket.h>
- X#include <sys/un.h>
- X
- Xmain()
- X{
- X int s1, s2, s3, l;
- X struct sockaddr_un a;
- X
- X (void)alarm(5);
- X if ((s1 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
- X exit(1);
- X a.sun_family = AF_UNIX;
- X strcpy(a.sun_path, nam);
- X (void) unlink(nam);
- X if (bind(s1, (struct sockaddr *) &a, strlen(nam)+2) == -1)
- X exit(1);
- X if (listen(s1, 2))
- X exit(1);
- X if (fork() == 0)
- X {
- X if ((s2 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
- X kill(getppid(), 3);
- X (void)connect(s2, &a, strlen(nam) + 2);
- X if (write(s2, "HELLO", 5) == -1)
- X kill(getppid(), 3);
- X exit(0);
- X }
- X l = sizeof(a);
- X close(0);
- X if (accept(s1, &a, &l))
- X exit(1);
- X#endif
- X
- X
- X l = 1;
- X if (select(1, &l, 0, 0, 0) == -1)
- X exit(1);
- X if (select(1, &l, &l, 0, 0) != 2)
- X exit(1);
- X exit(0);
- X}
- X],echo "- select is ok",echo "- it is not usable";AC_DEFINE(SELECT_BROKEN))
- X
- Xdnl
- Xdnl **** termcap or terminfo ****
- Xdnl
- Xecho searching for tgetent
- Xolibs="$LIBS"
- XLIBS="-ltermcap $LIBS"
- XAC_COMPILE_CHECK(libtermcap,,tgetent((char *)0, (char *)0);,,
- XLIBS="-lcurses $olibs"
- XAC_COMPILE_CHECK(libcurses,,tgetent((char *)0, (char *)0);,,
- Xecho "!!! no tgetent - no screen";exit)
- X)
- XTERMCAP="xx|scrdumm:xx:"
- XTERM=scrdumm
- Xexport TERMCAP
- Xexport TERM
- XAC_TEST_PROGRAM([
- Xmain()
- X{
- X char buf[1024];
- X if (tgetent(buf, "scrdumm") != 1)
- X exit(1);
- X exit(0);
- X}], echo "- you use the termcap database", echo "- you use the terminfo database";AC_DEFINE(TERMINFO))
- XAC_COMPILE_CHECK(ospeed,extern short ospeed;,ospeed=5;,,AC_DEFINE(NEED_OSPEED))
- X
- Xdnl
- Xdnl **** PTY ranges ****
- Xdnl
- Xecho checking for ptyranges
- Xif test -d /dev/ptym ; then
- Xpdir='/dev/ptym'
- Xelse
- Xpdir='/dev'
- Xfi
- Xptys=`echo $pdir/pty??`
- Xif test "$ptys" != "$pdir/pty??" ; then
- Xp0=`echo $ptys | tr ' ' '\012' | sed -e 's/^.*\(.\).$/\1/g' | tr ' ' '\012' | sort -u | sed -n -e H -e g -e 's/\n//g' -e '$p'`
- Xp1=`echo $ptys | tr ' ' '\012' | sed -e 's/^.*\(.\)$/\1/g' | tr ' ' '\012' | sort -u | sed -n -e H -e g -e 's/\n//g' -e '$p'`
- XAC_DEFINE(PTYRANGE0,\"$p0\")
- XAC_DEFINE(PTYRANGE1,\"$p1\")
- Xfi
- X
- X
- Xdnl
- Xdnl **** utmp handling ****
- Xdnl
- Xdnl linux has a void pututline, grrr, gcc will error when evaluating it.
- XAC_COMPILE_CHECK(getutent, [#include <time.h> /* to get time_t on SCO */
- X#include <sys/types.h>
- X#ifdef SVR4
- X#include <utmpx.h>
- X#else
- X#include <utmp.h>
- X#endif
- X#ifdef hpux
- X#define pututline _pututline
- X#endif
- X],
- X[int x = DEAD_PROCESS; struct utmp *y = pututline((struct utmp *)0); getutent();], AC_DEFINE(GETUTENT))
- XAC_COMPILE_CHECK(ut_host, [#include <time.h>
- X#include <sys/types.h>
- X#ifdef SVR4
- X#include <utmpx.h>
- X#else
- X#include <utmp.h>
- X#endif
- X],[struct utmp u; u.ut_host[0] = 0;], AC_DEFINE(UTHOST))
- X
- X
- Xdnl
- Xdnl **** loadav ****
- Xdnl
- Xecho "checking for libutil(s)"
- Xtest -f /usr/lib/libutils.a && LIBS="$LIBS -lutils"
- Xtest -f /usr/lib/libutil.a && LIBS="$LIBS -lutil"
- X
- XAC_COMPILE_CHECK(getloadavg, , [getloadavg((double *)0, 0);],
- XAC_DEFINE(LOADAV_GETLOADAVG);load=1)
- Xif test -z "$load" ; then
- XAC_PROGRAM_EGREP(yes,
- X[#if defined(NeXT) || defined(apollo) || defined(linux)
- X yes
- X#endif
- X], load=1)
- Xfi
- Xif test -z "$load" ; then
- Xecho "searching for kernelfile"
- Xfor core in /unix /vmunix /dynix /hp-ux /xelos /386bsd /kernel/unix ; do
- X if test -f $core ; then
- X break
- X fi
- Xdone
- Xif test ! -f $core ; then
- X echo "- no kernelfile found"
- Xelse
- X echo "- using kernelfile '$core'"
- X AC_DEFINE(LOADAV_UNIX,\"$core\")
- X AC_HEADER_CHECK(nlist.h,
- X [AC_DEFINE(NLIST_STRUCT)
- X AC_COMPILE_CHECK(n_un in struct nlist, [#include <nlist.h>],
- X [struct nlist n; n.n_un.n_name = 0;],
- X AC_DEFINE(NLIST_NAME_UNION))])
- X
- X echo checking for nlist declaration
- X AC_PROGRAM_EGREP([nlist( | |\()],[
- X#ifdef NLIST_STRUCT
- X# include <nlist.h>
- X#else
- X# include <a.out.h>
- X#endif
- X],AC_DEFINE(NLIST_DECLARED))
- X
- X echo searching for avenrun symbol
- X for av in avenrun _avenrun _Loadavg ; do
- X AC_TEST_PROGRAM([
- X#include <sys/types.h>
- X#ifdef NLIST_STRUCT
- X#include <nlist.h>
- X#else
- X#include <a.out.h>
- X#endif
- X
- Xstruct nlist nl[2];
- X
- Xmain()
- X{
- X#ifdef NLIST_NAME_UNION
- X nl[0].n_un.n_name = "$av";
- X#else
- X nl[0].n_name = "$av";
- X#endif
- X nlist(LOADAV_UNIX, nl);
- X if (nl[0].n_value == 0)
- X exit(1);
- X exit(0);
- X}
- X ],avensym=$av;break)
- X done
- X if test -z "$avensym" ; then
- X echo "- no avenrun symbol found"
- X else
- X echo "- using avenrun symbol '$avensym'"
- X AC_DEFINE(LOADAV_AVENRUN,\"$avensym\");
- X load=1
- X fi
- Xfi
- Xfi
- X
- XAC_PROGRAM_SOURCE([
- X#include <sys/types.h>
- X#include <sys/param.h>
- X],[
- X#if ((defined(hp300) && !defined(hpux)) || defined(sun) || (defined(ultrix) && defined(mips)) || defined(_SEQUENT_) || defined(sgi) || defined(SVR4) || defined(sony_news))
- Xloadtype=long
- X# ifdef apollo
- Xloadscale=65536
- X# else
- X# ifdef FSCALE
- X# undef FSCALE
- Xloadscale=FSCALE
- X# else
- X# ifdef sgi
- Xloadscale=1024
- X# else
- X# if defined(MIPS) || defined(SVR4)
- Xloadscale=256
- X# else /* not MIPS */
- Xloadscale=1000 /* our default value */
- X# endif /* MIPS */
- X# endif /* sgi */
- X# endif /* not FSCALE */
- X# endif /* not apollo */
- X#else
- Xloadtype=double
- Xloadscale=1
- X#endif
- X#ifdef alliant
- Xloadnum=4
- X#else
- Xloadnum=3
- X#endif
- X])
- X
- Xif test -n "$load" ; then AC_DEFINE(LOADAV) ; fi
- Xif test -n "$loadtype" ; then AC_DEFINE(LOADAV_TYPE,$loadtype) ; fi
- Xif test -n "$loadnum" ; then AC_DEFINE(LOADAV_NUM,$loadnum) ; fi
- Xif test -n "$loadscale" ; then AC_DEFINE(LOADAV_SCALE,$loadscale) ; fi
- X
- X
- Xdnl
- Xdnl **** signal handling ****
- Xdnl
- XAC_HEADER_EGREP([(void|sighandler_t).*signal], signal.h,
- X AC_DEFINE(SIGVOID))
- XAC_COMPILE_CHECK(sigset, [
- X#include <sys/types.h>
- X#include <signal.h>
- X], [
- X#ifdef SIGVOID
- Xsigset(0, (void (*)())0);
- X#else
- Xsigset(0, (int (*)())0);
- X#endif
- X], AC_DEFINE(USESIGSET))
- Xecho checking signal implementation
- XAC_TEST_PROGRAM([
- X#include <sys/types.h>
- X#include <signal.h>
- X
- X#ifndef SIGCHLD
- X#define SIGCHLD SIGCLD
- X#endif
- X#ifdef USESIGSET
- X#define signal sigset
- X#endif
- X
- Xint got;
- X
- X#ifdef SIGVOID
- Xvoid
- X#endif
- Xhand()
- X{
- X got++;
- X}
- X
- Xmain()
- X{
- X (void)signal(SIGCHLD, hand);
- X kill(getpid(), SIGCHLD);
- X kill(getpid(), SIGCHLD);
- X if (got < 2)
- X exit(1);
- X exit(0);
- X}
- X],,AC_DEFINE(SYSVSIGS))
- X
- Xdnl
- Xdnl **** libraries ****
- Xdnl
- X
- Xecho checking for crypt and sec libraries
- Xtest -f /lib/libcrypt_d.a || test -f /usr/lib/libcrypt_d.a && LIBS="$LIBS -lcrypt_d"
- Xtest -f /lib/libcrypt.a || test -f /usr/lib/libcrypt.a && LIBS="$LIBS -lcrypt"
- Xtest -f /lib/libsec.a || test -f /usr/lib/libsec.a && LIBS="$LIBS -lsec"
- X
- Xoldlibs="$LIBS"
- XLIBS="$LIBS -lsun"
- XAC_COMPILE_CHECK(IRIX sun library,,,,LIBS="$oldlibs")
- X
- X
- Xdnl
- Xdnl **** misc things ****
- Xdnl
- XAC_COMPILE_CHECK(wait union,[#include <sys/types.h>
- X#include <sys/wait.h>
- X],[
- X union wait x;
- X int y;
- X#ifdef WEXITSTATUS
- X y = WEXITSTATUS(x);
- X#endif
- X],AC_DEFINE(BSDWAIT))
- X
- Xecho checking for termio or termios
- XAC_TEST_CPP([#include <termios.h>], AC_DEFINE(TERMIO),
- X AC_TEST_CPP([#include <termio.h>], AC_DEFINE(TERMIO)))
- X
- Xdnl AC_HEADER_CHECK(shadow.h, AC_DEFINE(SHADOWPW))
- XAC_COMPILE_CHECK(getspnam, [#include <shadow.h>], [getspnam();],
- X AC_DEFINE(SHADOWPW))
- X
- XAC_COMPILE_CHECK(getttyent, , [getttyent();], AC_DEFINE(GETTTYENT))
- X
- Xecho checking whether memcpy/memmove/bcopy handles overlapping arguments
- XAC_TEST_PROGRAM([
- Xmain() {
- X char buf[10];
- X strcpy(buf, "abcdefghi");
- X bcopy(buf, buf + 2, 3);
- X if (strncmp(buf, "ababcf", 6))
- X exit(1);
- X strcpy(buf, "abcdefghi");
- X bcopy(buf + 2, buf, 3);
- X if (strncmp(buf, "cdedef", 6))
- X exit(1);
- X exit(0); /* libc version works properly. */
- X}], AC_DEFINE(USEBCOPY))
- X
- XAC_TEST_PROGRAM([
- X#define bcopy(s,d,l) memmove(d,s,l)
- Xmain() {
- X char buf[10];
- X strcpy(buf, "abcdefghi");
- X bcopy(buf, buf + 2, 3);
- X if (strncmp(buf, "ababcf", 6))
- X exit(1);
- X strcpy(buf, "abcdefghi");
- X bcopy(buf + 2, buf, 3);
- X if (strncmp(buf, "cdedef", 6))
- X exit(1);
- X exit(0); /* libc version works properly. */
- X}], AC_DEFINE(USEMEMMOVE))
- X
- X
- XAC_TEST_PROGRAM([
- X#define bcopy(s,d,l) memcpy(d,s,l)
- Xmain() {
- X char buf[10];
- X strcpy(buf, "abcdefghi");
- X bcopy(buf, buf + 2, 3);
- X if (strncmp(buf, "ababcf", 6))
- X exit(1);
- X strcpy(buf, "abcdefghi");
- X bcopy(buf + 2, buf, 3);
- X if (strncmp(buf, "cdedef", 6))
- X exit(1);
- X exit(0); /* libc version works properly. */
- X}], AC_DEFINE(USEMEMCPY))
- X
- Xecho checking for long file names
- X(echo 1 > /tmp/conftest9012345) 2>/dev/null
- X(echo 2 > /tmp/conftest9012346) 2>/dev/null
- Xval=`cat /tmp/conftest9012345 2>/dev/null`
- Xif test -f /tmp/conftest9012345 && test "$val" = 1; then :
- Xelse AC_DEFINE(NAME_MAX, 14)
- Xfi
- Xrm -f /tmp/conftest*
- X
- XAC_COMPILE_CHECK(vsprintf, [#include <varargs.h>
- X#include <stdio.h>], [vsprintf();], AC_DEFINE(USEVARARGS))
- X
- XAC_DIR_HEADER
- XAC_XENIX_DIR
- X
- XAC_COMPILE_CHECK(setenv, , [setenv((char *)0,(char *)0);unsetenv((char *)0);], AC_DEFINE(USESETENV),
- XAC_COMPILE_CHECK(putenv, , [putenv((char *)0);unsetenv((char *)0);], ,
- XAC_DEFINE(NEEDPUTENV)
- X))
- X
- Xdnl
- Xdnl **** the end ****
- Xdnl
- Xdnl Ptx bug workaround -- insert -lc after -ltermcap
- Xtest -n "$seqptx" && LIBS="-ltermcap -lc -lsocket -linet -lsec -lseq"
- X
- XAC_TEST_PROGRAM(main(){exit(0);},,echo "Can't run the compiler - internal error. Sorry.";exit)
- XAC_OUTPUT(Makefile)
- X
- X# a hook for preserving undef directive in config.h
- Xif test -z "$no_create" ; then
- Xmv config.h conftest
- Xsed -e 's@^\(.*\)defin.\( .*\) .*/\*\(.*KEEP_UNDEF_HERE\)@\1undef\2 /\*\3@' < conftest > config.h
- Xrm -f conftest
- Xfi
- Xcat >> config.status << EOF
- Xmv config.h conftest
- Xsed -e 's@^\(.*\)defin.\( .*\) .*/\*\(.*KEEP_UNDEF_HERE\)@\1undef\2 /\*\3@' < conftest > config.h
- Xrm -f conftest
- XEOF
- X
- Xecho ""
- Xif test -z "$AWK"; then
- Xecho "!!! Since you have no awk you must copy the files 'comm.h.dist'"
- Xecho "!!! and 'term.h.dist' to 'comm.h' and 'term.h'."
- Xecho "!!! Do _not_ change the user configuration section in config.h!"
- Xecho "Please check the pathnames in the Makefile."
- Xelse
- Xecho "Now please check the pathnames in the Makefile and the user"
- Xecho "configuration section in config.h."
- Xfi
- Xecho "Then type 'make' to make screen. Good luck."
- Xecho ""
- END_OF_FILE
- if test 20123 -ne `wc -c <'configure.in'`; then
- echo shar: \"'configure.in'\" unpacked with wrong size!
- fi
- # end of 'configure.in'
- fi
- if test -f 'mark.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mark.c'\"
- else
- echo shar: Extracting \"'mark.c'\" \(25607 characters\)
- sed "s/^X//" >'mark.c' <<'END_OF_FILE'
- X/* Copyright (c) 1993
- X * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
- X * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
- X * Copyright (c) 1987 Oliver Laumann
- X *
- X * This program is free software; you can redistribute it and/or modify
- X * it under the terms of the GNU General Public License as published by
- X * the Free Software Foundation; either version 2, or (at your option)
- X * any later version.
- X *
- X * This program is distributed in the hope that it will be useful,
- X * but WITHOUT ANY WARRANTY; without even the implied warranty of
- X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X * GNU General Public License for more details.
- X *
- X * You should have received a copy of the GNU General Public License
- X * along with this program (see the file COPYING); if not, write to the
- X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X *
- X ****************************************************************
- X */
- X
- X#include "rcs.h"
- XRCS_ID("$Id: mark.c,v 1.2 1993/07/21 15:43:11 mlschroe Exp $ FAU")
- X
- X#include <sys/types.h>
- X
- X#include "config.h"
- X#include "screen.h"
- X#include "mark.h"
- X#include "extern.h"
- X
- X#ifdef COPY_PASTE
- X
- Xstatic int is_letter __P((int));
- Xstatic void nextword __P((int *, int *, int, int));
- Xstatic int linestart __P((int));
- Xstatic int lineend __P((int));
- Xstatic int rem __P((int, int , int , int , int , char *, int));
- Xstatic int eq __P((int, int ));
- Xstatic int MarkScrollDownDisplay __P((int));
- Xstatic int MarkScrollUpDisplay __P((int));
- X
- Xstatic void MarkProcess __P((char **, int *));
- Xstatic void MarkAbort __P((void));
- Xstatic void MarkRedisplayLine __P((int, int, int, int));
- Xstatic int MarkRewrite __P((int, int, int, int));
- Xstatic void MarkSetCursor __P((void));
- X
- Xextern struct win *fore;
- Xextern struct display *display;
- Xextern char *null, *blank;
- Xextern char Esc, MetaEsc;
- X
- X#ifdef NETHACK
- Xextern nethackflag;
- X#endif
- X
- Xstatic struct LayFuncs MarkLf =
- X{
- X MarkProcess,
- X MarkAbort,
- X MarkRedisplayLine,
- X DefClearLine,
- X MarkRewrite,
- X MarkSetCursor,
- X DefResize,
- X DefRestore
- X};
- X
- Xint join_with_cr = 0;
- Xchar mark_key_tab[256]; /* this array must be initialised first! */
- X
- Xstatic struct markdata *markdata;
- X
- X
- X/*
- X * VI like is_letter: 0 - whitespace
- X * 1 - letter
- X * 2 - other
- X */
- Xstatic int is_letter(c)
- Xchar c;
- X{
- X if ((c >= 'a' && c <= 'z') ||
- X (c >= 'A' && c <= 'Z') ||
- X (c >= '0' && c <= '9') ||
- X c == '_' || c == '.' ||
- X c == '@' || c == ':' ||
- X c == '%' || c == '!' ||
- X c == '-' || c == '+')
- X /* thus we can catch email-addresses as a word :-) */
- X return 1;
- X else if (c != ' ')
- X return 2;
- X return 0;
- X}
- X
- Xstatic int
- Xlinestart(y)
- Xint y;
- X{
- X register int x;
- X register char *i;
- X
- X for (x = markdata->left_mar, i = iWIN(y) + x; x < d_width - 1; x++)
- X if (*i++ != ' ')
- X break;
- X if (x == d_width - 1)
- X x = markdata->left_mar;
- X return(x);
- X}
- X
- Xstatic int
- Xlineend(y)
- Xint y;
- X{
- X register int x;
- X register char *i;
- X
- X for (x = markdata->right_mar, i = iWIN(y) + x; x >= 0; x--)
- X if (*i-- != ' ')
- X break;
- X if (x < 0)
- X x = markdata->left_mar;
- X return(x);
- X}
- X
- X
- X/*
- X * nextword calculates the cursor position of the num'th word.
- X * If the cursor is on a word, it counts as the first.
- X * NW_BACK: search backward
- X * NW_ENDOFWORD: find the end of the word
- X * NW_MUSTMOVE: move at least one char
- X */
- X
- X#define NW_BACK (1<<0)
- X#define NW_ENDOFWORD (1<<1)
- X#define NW_MUSTMOVE (1<<2)
- X
- Xstatic void
- Xnextword(xp, yp, flags, num)
- Xint *xp, *yp, flags, num;
- X{
- X int xx = d_width, yy = fore->w_histheight + d_height;
- X register int sx, oq, q, x, y;
- X
- X x = *xp;
- X y = *yp;
- X sx = (flags & NW_BACK) ? -1 : 1;
- X if ((flags & NW_ENDOFWORD) && (flags & NW_MUSTMOVE))
- X x += sx;
- X for (oq = -1; ; x += sx, oq = q)
- X {
- X if (x >= xx || x < 0)
- X q = 0;
- X else
- X q = is_letter(iWIN(y)[x]);
- X if (oq >= 0 && oq != q)
- X {
- X if (oq == 0 || !(flags & NW_ENDOFWORD))
- X *xp = x;
- X else
- X *xp = x-sx;
- X *yp = y;
- X if ((!(flags & NW_ENDOFWORD) && q) ||
- X ((flags & NW_ENDOFWORD) && oq))
- X {
- X if (--num <= 0)
- X return;
- X }
- X }
- X if (x == xx)
- X {
- X x = -1;
- X if (++y >= yy)
- X return;
- X }
- X else if (x < 0)
- X {
- X x = xx;
- X if (--y < 0)
- X return;
- X }
- X }
- X}
- X
- X
- X/*
- X * y1, y2 are WIN coordinates
- X *
- X * redisplay: 0 - just copy
- X * 1 - redisplay + copy
- X * 2 - count + copy, don't redisplay
- X */
- X
- Xstatic int
- Xrem(x1, y1, x2, y2, redisplay, pt, yend)
- Xint x1, y1, x2, y2, redisplay, yend;
- Xchar *pt;
- X{
- X int i, j, from, to, ry;
- X int l = 0;
- X char *im;
- X
- X markdata->second = 0;
- X if (y2 < y1 || ((y2 == y1) && (x2 < x1)))
- X {
- X i = y2;
- X y2 = y1;
- X y1 = i;
- X i = x2;
- X x2 = x1;
- X x1 = i;
- X }
- X ry = y1 - markdata->hist_offset;
- X
- X i = y1;
- X if (redisplay != 2 && pt == 0 && ry <0)
- X {
- X i -= ry;
- X ry = 0;
- X }
- X for (; i <= y2; i++, ry++)
- X {
- X if (redisplay != 2 && pt == 0 && ry > yend)
- X break;
- X from = (i == y1) ? x1 : 0;
- X if (from < markdata->left_mar)
- X from = markdata->left_mar;
- X for (to = d_width, im = iWIN(i) + to; to >= 0; to--)
- X if (*im-- != ' ')
- X break;
- X if (i == y2 && x2 < to)
- X to = x2;
- X if (to > markdata->right_mar)
- X to = markdata->right_mar;
- X if (redisplay == 1 && from <= to && ry >=0 && ry <= yend)
- X MarkRedisplayLine(ry, from, to, 0);
- X if (redisplay != 2 && pt == 0) /* don't count/copy */
- X continue;
- X for (j = from, im = iWIN(i)+from; j <= to; j++)
- X {
- X if (pt)
- X *pt++ = *im++;
- X l++;
- X }
- X if (i != y2 && (to != d_width - 1 || iWIN(i)[to + 1] == ' '))
- X {
- X /*
- X * this code defines, what glues lines together
- X */
- X switch (markdata->nonl)
- X {
- X case 0: /* lines separated by newlines */
- X if (join_with_cr)
- X {
- X if (pt)
- X *pt++ = '\r';
- X l++;
- X }
- X if (pt)
- X *pt++ = '\n';
- X l++;
- X break;
- X case 1: /* nothing to separate lines */
- X break;
- X case 2: /* lines separated by blanks */
- X if (pt)
- X *pt++ = ' ';
- X l++;
- X break;
- X }
- X }
- X }
- X return(l);
- X}
- X
- X/* Check if two chars are identical. All digits are treatened
- X * as same. Used for GetHistory()
- X */
- X
- Xstatic int
- Xeq(a, b)
- Xint a, b;
- X{
- X if (a == b)
- X return 1;
- X if (a == 0 || b == 0)
- X return 1;
- X if (a <= '9' && a >= '0' && b <= '9' && b >= '0')
- X return 1;
- X return 0;
- X}
- X
- X
- Xint
- XGetHistory() /* return value 1 if d_copybuffer changed */
- X{
- X int i = 0, q = 0, xx, yy, x, y;
- X char *linep;
- X
- X x = fore->w_x;
- X if (x >= d_width)
- X x = d_width - 1;
- X y = fore->w_y + fore->w_histheight;
- X debug2("cursor is at x=%d, y=%d\n", x, y);
- X for (xx = x - 1, linep = iWIN(y) + xx; xx >= 0; xx--)
- X if ((q = *linep--) != ' ' )
- X break;
- X debug3("%c at (%d,%d)\n", q, xx, y);
- X for (yy = y - 1; yy >= 0; yy--)
- X {
- X linep = iWIN(yy);
- X if (xx < 0 || eq(linep[xx], q))
- X { /* line is matching... */
- X for (i = d_width - 1, linep += i; i >= x; i--)
- X if (*linep-- != ' ')
- X break;
- X if (i >= x)
- X break;
- X }
- X }
- X if (yy < 0)
- X return 0;
- X if (d_copybuffer != NULL)
- X free(d_copybuffer);
- X if ((d_copybuffer = malloc((unsigned) (i - x + 2))) == NULL)
- X {
- X Msg(0, "Not enough memory... Sorry.");
- X return 0;
- X }
- X bcopy(linep - i + x + 1, d_copybuffer, i - x + 1);
- X d_copylen = i - x + 1;
- X return 1;
- X}
- X
- Xvoid
- XMarkRoutine()
- X{
- X int x, y;
- X
- X ASSERT(fore->w_active);
- X if (InitOverlayPage(sizeof(*markdata), &MarkLf, 1))
- X return;
- X markdata = (struct markdata *)d_lay->l_data;
- X markdata->second = 0;
- X markdata->rep_cnt = 0;
- X markdata->append_mode = 0;
- X markdata->write_buffer = 0;
- X markdata->nonl = 0;
- X markdata->left_mar = 0;
- X markdata->right_mar = d_width - 1;
- X markdata->hist_offset = fore->w_histheight;
- X x = fore->w_x;
- X y = D2W(fore->w_y);
- X if (x >= d_width)
- X x = d_width - 1;
- X
- X GotoPos(x, W2D(y));
- X#ifdef NETHACK
- X if (nethackflag)
- X Msg(0, "Welcome to hacker's treasure zoo - Column %d Line %d(+%d) (%d,%d)",
- X x + 1, W2D(y + 1), fore->w_histheight, d_width, d_height);
- X else
- X#endif
- X Msg(0, "Copy mode - Column %d Line %d(+%d) (%d,%d)",
- X x + 1, W2D(y + 1), fore->w_histheight, d_width, d_height);
- X markdata->cx = markdata->x1 = x;
- X markdata->cy = markdata->y1 = y;
- X}
- X
- Xstatic void
- XMarkSetCursor()
- X{
- X markdata = (struct markdata *)d_lay->l_data;
- X fore = d_fore;
- X GotoPos(markdata->cx, W2D(markdata->cy));
- X}
- X
- Xstatic void
- XMarkProcess(inbufp,inlenp)
- Xchar **inbufp;
- Xint *inlenp;
- X{
- X char *inbuf, *pt;
- X int inlen;
- X int cx, cy, x2, y2, j, yend;
- X int newcopylen = 0, od;
- X int in_mark;
- X int rep_cnt;
- X
- X/*
- X char *extrap = 0, extrabuf[100];
- X*/
- X
- X markdata = (struct markdata *)d_lay->l_data;
- X fore = d_fore;
- X if (inbufp == 0)
- X {
- X MarkAbort();
- X return;
- X }
- X
- X GotoPos(markdata->cx, W2D(markdata->cy));
- X inbuf= *inbufp;
- X inlen= *inlenp;
- X pt = inbuf;
- X in_mark = 1;
- X while (in_mark && (inlen /* || extrap */))
- X {
- X/*
- X if (extrap)
- X {
- X od = *extrap++;
- X if (*extrap == 0)
- X extrap = 0;
- X }
- X else
- X*/
- X {
- X od = mark_key_tab[(unsigned int)*pt++];
- X inlen--;
- X }
- X rep_cnt = markdata->rep_cnt;
- X if (od >= '0' && od <= '9')
- X {
- X if (rep_cnt < 1001 && (od != '0' || rep_cnt != 0))
- X {
- X markdata->rep_cnt = 10 * rep_cnt + od - '0';
- X continue;
- X /*
- X * Now what is that 1001 here? Well, we have a screen with
- X * 25 * 80 = 2000 characters. Movement is at most across the full
- X * screen. This we do with word by word movement, as character by
- X * character movement never steps over line boundaries. The most words
- X * we can place on the screen are 1000 single letter words. Thus 1001
- X * is sufficient. Users with bigger screens never write in single letter
- X * words, as they should be more advanced. jw.
- X * Oh, wrong. We still give even the experienced user a factor of ten.
- X */
- X }
- X }
- X cx = markdata->cx;
- X cy = markdata->cy;
- X switch (od)
- X {
- X case '\014': /* CTRL-L Redisplay */
- X Redisplay(0);
- X GotoPos(cx, W2D(cy));
- X break;
- X case '\010': /* CTRL-H Backspace */
- X case 'h':
- X if (rep_cnt == 0)
- X rep_cnt = 1;
- X revto(cx - rep_cnt, cy);
- X break;
- X case '\016': /* CTRL-N */
- X case 'j':
- X if (rep_cnt == 0)
- X rep_cnt = 1;
- X revto(cx, cy + rep_cnt);
- X break;
- X case '+':
- X if (rep_cnt == 0)
- X rep_cnt = 1;
- X j = cy + rep_cnt;
- X if (j > fore->w_histheight + d_height - 1)
- X j = fore->w_histheight + d_height - 1;
- X revto(linestart(j), j);
- X break;
- X case '-':
- X if (rep_cnt == 0)
- X rep_cnt = 1;
- X cy -= rep_cnt;
- X if (cy < 0)
- X cy = 0;
- X revto(linestart(cy), cy);
- X break;
- X case '^':
- X revto(linestart(cy), cy);
- X break;
- X case '\n':
- X revto(markdata->left_mar, cy + 1);
- X break;
- X case 'k':
- X case '\020': /* CTRL-P */
- X if (rep_cnt == 0)
- X rep_cnt = 1;
- X revto(cx, cy - rep_cnt);
- X break;
- X case 'l':
- X if (rep_cnt == 0)
- X rep_cnt = 1;
- X revto(cx + rep_cnt, cy);
- X break;
- X case '\001': /* CTRL-A from tcsh/emacs */
- X case '0':
- X revto(markdata->left_mar, cy);
- X break;
- X case '\004': /* CTRL-D down half screen */
- X if (rep_cnt == 0)
- X rep_cnt = (d_height + 1) >> 1;
- X revto_line(cx, cy + rep_cnt, W2D(cy));
- X break;
- X case '$':
- X revto(lineend(cy), cy);
- X break;
- X case '\022': /* CTRL-R emacs style backwards search */
- X ISearch(-1);
- X in_mark = 0;
- X break;
- X case '\023': /* CTRL-S emacs style search */
- X ISearch(1);
- X in_mark = 0;
- X break;
- X case '\025': /* CTRL-U up half screen */
- X if (rep_cnt == 0)
- X rep_cnt = (d_height + 1) >> 1;
- X revto_line(cx, cy - rep_cnt, W2D(cy));
- X break;
- X case '\007': /* CTRL-G show cursorpos */
- X if (markdata->left_mar == 0 && markdata->right_mar == d_width - 1)
- X Msg(0, "Column %d Line %d(+%d)", cx+1, W2D(cy)+1,
- X markdata->hist_offset);
- X else
- X Msg(0, "Column %d(%d..%d) Line %d(+%d)", cx+1,
- X markdata->left_mar+1, markdata->right_mar+1, W2D(cy)+1, markdata->hist_offset);
- X break;
- X case '\002': /* CTRL-B back one page */
- X if (rep_cnt == 0)
- X rep_cnt = 1;
- X rep_cnt *= d_height;
- X revto(cx, cy - rep_cnt);
- X break;
- X case '\006': /* CTRL-F forward one page */
- X if (rep_cnt == 0)
- X rep_cnt = 1;
- X rep_cnt *= d_height;
- X revto(cx, cy + rep_cnt);
- X break;
- X case '\005': /* CTRL-E scroll up */
- X if (rep_cnt == 0)
- X rep_cnt = 1;
- X rep_cnt = MarkScrollUpDisplay(rep_cnt);
- X if (cy < D2W(0))
- X revto(cx, D2W(0));
- X else
- X GotoPos(cx, W2D(cy));
- X break;
- X case '\031': /* CTRL-Y scroll down */
- X if (rep_cnt == 0)
- X rep_cnt = 1;
- X rep_cnt = MarkScrollDownDisplay(rep_cnt);
- X if (cy > D2W(d_height-1))
- X revto(cx, D2W(d_height-1));
- X else
- X GotoPos(cx, W2D(cy));
- X break;
- X case '@':
- X /* it may be usefull to have a key that does nothing */
- X break;
- X case '%':
- X rep_cnt--;
- X /* rep_cnt is a percentage for the history buffer */
- X if (rep_cnt < 0)
- X rep_cnt = 0;
- X if (rep_cnt > 100)
- X rep_cnt = 100;
- X revto_line(markdata->left_mar, (rep_cnt * (fore->w_histheight + d_height)) / 100, (d_height - 1) / 2);
- X break;
- X case 'g':
- X rep_cnt = 1;
- X /* FALLTHROUGH */
- X case 'G':
- X /* rep_cnt is here the WIN line number */
- X if (rep_cnt == 0)
- X rep_cnt = fore->w_histheight + d_height;
- X revto_line(markdata->left_mar, --rep_cnt, (d_height - 1) / 2);
- X break;
- X case 'H':
- X revto(markdata->left_mar, D2W(0));
- X break;
- X case 'M':
- X revto(markdata->left_mar, D2W((d_height - 1) / 2));
- X break;
- X case 'L':
- X revto(markdata->left_mar, D2W(d_height - 1));
- X break;
- X case '|':
- X revto(--rep_cnt, cy);
- X break;
- X case 'w':
- X if (rep_cnt == 0)
- X rep_cnt = 1;
- X nextword(&cx, &cy, NW_MUSTMOVE, rep_cnt);
- X revto(cx, cy);
- X break;
- X case 'e':
- X if (rep_cnt == 0)
- X rep_cnt = 1;
- X nextword(&cx, &cy, NW_ENDOFWORD|NW_MUSTMOVE, rep_cnt);
- X revto(cx, cy);
- X break;
- X case 'b':
- X if (rep_cnt == 0)
- X rep_cnt = 1;
- X nextword(&cx, &cy, NW_BACK|NW_ENDOFWORD|NW_MUSTMOVE, rep_cnt);
- X revto(cx, cy);
- X break;
- X case 'a':
- X markdata->append_mode = 1 - markdata->append_mode;
- X debug1("append mode %d--\n", markdata->append_mode);
- X Msg(0, (markdata->append_mode) ? ":set append" : ":set noappend");
- X break;
- X case 'v':
- X case 'V':
- X /* this sets start column to column 9 for VI :set nu users */
- X if (markdata->left_mar == 8)
- X rep_cnt = 1;
- X else
- X rep_cnt = 9;
- X /* FALLTHROUGH */
- X case 'c':
- X case 'C':
- X /* set start column (c) and end column (C) */
- X if (markdata->second)
- X {
- X rem(markdata->x1, markdata->y1, cx, cy, 1, (char *)0, d_height-1); /* Hack */
- X markdata->second = 1; /* rem turns off second */
- X }
- X rep_cnt--;
- X if (rep_cnt < 0)
- X rep_cnt = cx;
- X if (od != 'C')
- X {
- X markdata->left_mar = rep_cnt;
- X if (markdata->left_mar > markdata->right_mar)
- X markdata->left_mar = markdata->right_mar;
- X }
- X else
- X {
- X markdata->right_mar = rep_cnt;
- X if (markdata->left_mar > markdata->right_mar)
- X markdata->right_mar = markdata->left_mar;
- X }
- X if (markdata->second)
- X {
- X markdata->cx = markdata->x1; markdata->cy = markdata->y1;
- X revto(cx, cy);
- X }
- X if (od == 'v' || od == 'V')
- X Msg(0, (markdata->left_mar != 8) ? ":set nonu" : ":set nu");
- X break;
- X case 'J':
- X /* how do you join lines in VI ? */
- X markdata->nonl = (markdata->nonl + 1) % 3;
- X switch (markdata->nonl)
- X {
- X case 0:
- X if (join_with_cr)
- X Msg(0, "Multiple lines (CR/LF)");
- X else
- X Msg(0, "Multiple lines (LF)");
- X break;
- X case 1:
- X Msg(0, "Lines joined");
- X break;
- X case 2:
- X Msg(0, "Lines joined with blanks");
- X break;
- X }
- X break;
- X case '/':
- X Search(1);
- X in_mark = 0;
- X break;
- X case '?':
- X Search(-1);
- X in_mark = 0;
- X break;
- X case 'n':
- X Search(0);
- X break;
- X case 'y':
- X case 'Y':
- X if (markdata->second == 0)
- X {
- X revto(linestart(cy), cy);
- X markdata->second++;
- X cx = markdata->x1 = markdata->cx;
- X cy = markdata->y1 = markdata->cy;
- X }
- X if (--rep_cnt > 0)
- X revto(cx, cy + rep_cnt);
- X revto(lineend(markdata->cy), markdata->cy);
- X if (od == 'y')
- X break;
- X /* FALLTHROUGH */
- X case 'W':
- X if (od == 'W')
- X {
- X if (rep_cnt == 0)
- X rep_cnt = 1;
- X if (!markdata->second)
- X {
- X nextword(&cx, &cy, NW_BACK|NW_ENDOFWORD, 1);
- X revto(cx, cy);
- X markdata->second++;
- X cx = markdata->x1 = markdata->cx;
- X cy = markdata->y1 = markdata->cy;
- X }
- X nextword(&cx, &cy, NW_ENDOFWORD, rep_cnt);
- X revto(cx, cy);
- X }
- X cx = markdata->cx;
- X cy = markdata->cy;
- X /* FALLTHROUGH */
- X case 'A':
- X if (od == 'A')
- X markdata->append_mode = 1;
- X /* FALLTHROUGH */
- X case '>':
- X if (od == '>')
- X markdata->write_buffer = 1;
- X /* FALLTHROUGH */
- X case ' ':
- X case '\r':
- X if (!markdata->second)
- X {
- X markdata->second++;
- X markdata->x1 = cx;
- X markdata->y1 = cy;
- X revto(cx, cy);
- X#ifdef NETHACK
- X if (nethackflag)
- X Msg(0, "You drop a magic marker - Column %d Line %d",
- X cx+1, W2D(cy)+1);
- X else
- X#endif
- X Msg(0, "First mark set - Column %d Line %d", cx+1, W2D(cy)+1);
- X break;
- X }
- X else
- X {
- X int append_mode = markdata->append_mode;
- X int write_buffer = markdata->write_buffer;
- X
- X x2 = cx;
- X y2 = cy;
- X newcopylen = rem(markdata->x1, markdata->y1, x2, y2, 2, (char *)0, 0); /* count */
- X if (d_copybuffer != NULL && !append_mode)
- X {
- X d_copylen = 0;
- X free(d_copybuffer);
- X d_copybuffer = NULL;
- X }
- X if (newcopylen > 0)
- X {
- X /* the +3 below is for : cr + lf + \0 */
- X if (d_copybuffer != NULL)
- X d_copybuffer = realloc(d_copybuffer,
- X (unsigned) (d_copylen + newcopylen + 3));
- X else
- X {
- X d_copylen = 0;
- X d_copybuffer = malloc((unsigned) (newcopylen + 3));
- X }
- X if (d_copybuffer == NULL)
- X {
- X MarkAbort();
- X in_mark = 0;
- X Msg(0, "Not enough memory... Sorry.");
- X d_copylen = 0;
- X d_copybuffer = NULL;
- X break;
- X }
- X if (append_mode)
- X {
- X switch (markdata->nonl)
- X {
- X /*
- X * this code defines, what glues lines together
- X */
- X case 0:
- X if (join_with_cr)
- X {
- X d_copybuffer[d_copylen] = '\r';
- X d_copylen++;
- X }
- X d_copybuffer[d_copylen] = '\n';
- X d_copylen++;
- X break;
- X case 1:
- X break;
- X case 2:
- X d_copybuffer[d_copylen] = ' ';
- X d_copylen++;
- X break;
- X }
- X }
- X yend = d_height - 1;
- X if (fore->w_histheight - markdata->hist_offset < d_height)
- X {
- X markdata->second = 0;
- X yend -= MarkScrollUpDisplay(fore->w_histheight - markdata->hist_offset);
- X }
- X d_copylen += rem(markdata->x1, markdata->y1, x2, y2, markdata->hist_offset == fore->w_histheight, d_copybuffer + d_copylen, yend);
- X }
- X if (markdata->hist_offset != fore->w_histheight)
- X LAY_CALL_UP(Activate(0));
- X ExitOverlayPage();
- X if (append_mode)
- X Msg(0, "Appended %d characters to buffer",
- X newcopylen);
- X else
- X Msg(0, "Copied %d characters into buffer", d_copylen);
- X if (write_buffer)
- X WriteFile(DUMP_EXCHANGE);
- X in_mark = 0;
- X break;
- X }
- X default:
- X MarkAbort();
- X#ifdef NETHACK
- X if (nethackflag)
- X Msg(0, "You escaped the dungeon.");
- X else
- X#endif
- X Msg(0, "Copy mode aborted");
- X in_mark = 0;
- X break;
- X }
- X if (in_mark) /* markdata may be freed */
- X markdata->rep_cnt = 0;
- X }
- X *inbufp = pt;
- X *inlenp = inlen;
- X}
- X
- Xvoid revto(tx, ty)
- Xint tx, ty;
- X{
- X revto_line(tx, ty, -1);
- X}
- X
- X/* tx, ty: WINDOW, line: DISPLAY */
- Xvoid revto_line(tx, ty, line)
- Xint tx, ty, line;
- X{
- X int fx, fy;
- X int x, y, t, revst, reven, qq, ff, tt, st, en, ce = 0;
- X int ystart = 0, yend = d_height-1;
- X int i, ry;
- X
- X if (tx < 0)
- X tx = 0;
- X else if (tx > d_width - 1)
- X tx = d_width -1;
- X if (ty < 0)
- X ty = 0;
- X else if (ty > fore->w_histheight + d_height - 1)
- X ty = fore->w_histheight + d_height - 1;
- X
- X fx = markdata->cx; fy = markdata->cy;
- X markdata->cx = tx; markdata->cy = ty;
- X
- X /*
- X * if we go to a position that is currently offscreen
- X * then scroll the screen
- X */
- X i = 0;
- X if (line >= 0 && line < d_height)
- X i = W2D(ty) - line;
- X else if (ty < markdata->hist_offset)
- X i = ty - markdata->hist_offset;
- X else if (ty > markdata->hist_offset + (d_height-1))
- X i = ty-markdata->hist_offset-(d_height-1);
- X if (i > 0)
- X yend -= MarkScrollUpDisplay(i);
- X else if (i < 0)
- X ystart += MarkScrollDownDisplay(-i);
- X
- X if (markdata->second == 0)
- X {
- X GotoPos(tx, W2D(ty));
- X return;
- X }
- X
- X qq = markdata->x1 + markdata->y1 * d_width;
- X ff = fx + fy * d_width; /* "from" offset in WIN coords */
- X tt = tx + ty * d_width; /* "to" offset in WIN coords*/
- X
- X if (ff > tt)
- X {
- X st = tt; en = ff;
- X x = tx; y = ty;
- X }
- X else
- X {
- X st = ff; en = tt;
- X x = fx; y = fy;
- X }
- X if (st > qq)
- X {
- X st++;
- X x++;
- X }
- X if (en < qq)
- X en--;
- X if (tt > qq)
- X {
- X revst = qq; reven = tt;
- X }
- X else
- X {
- X revst = tt; reven = qq;
- X }
- X ry = y - markdata->hist_offset;
- X if (ry < ystart)
- X {
- X y += (ystart - ry);
- X x = 0;
- X st = y * d_width;
- X ry = ystart;
- X }
- X for (t = st; t <= en; t++, x++)
- X {
- X if (x >= d_width)
- X {
- X x = 0;
- X y++, ry++;
- X }
- X if (ry > yend)
- X break;
- X if (t == st || x == 0)
- X {
- X for (ce = d_width; ce >= 0; ce--)
- X if (iWIN(y)[ce] != ' ')
- X break;
- X }
- X if (x <= ce && x >= markdata->left_mar && x <= markdata->right_mar
- X && (CLP || x < d_width-1 || ry < d_bot))
- X {
- X GotoPos(x, W2D(y));
- X if (t >= revst && t <= reven)
- X SetAttrFont(A_SO, ASCII);
- X else
- X SetAttrFont(aWIN(y)[x], fWIN(y)[x]);
- X PUTCHARLP(iWIN(y)[x]);
- X }
- X }
- X GotoPos(tx, W2D(ty));
- X}
- X
- Xstatic void
- XMarkAbort()
- X{
- X int yend, redisp;
- X
- X debug("MarkAbort\n");
- X markdata = (struct markdata *)d_lay->l_data;
- X fore = d_fore;
- X yend = d_height - 1;
- X redisp = markdata->second;
- X if (fore->w_histheight - markdata->hist_offset < d_height)
- X {
- X markdata->second = 0;
- X yend -= MarkScrollUpDisplay(fore->w_histheight - markdata->hist_offset);
- X }
- X if (markdata->hist_offset != fore->w_histheight)
- X {
- X LAY_CALL_UP(Activate(0));
- X }
- X else
- X {
- X rem(markdata->x1, markdata->y1, markdata->cx, markdata->cy, redisp, (char *)0, yend);
- X }
- X ExitOverlayPage();
- X}
- X
- X
- Xstatic void
- XMarkRedisplayLine(y, xs, xe, isblank)
- Xint y; /* NOTE: y is in DISPLAY coords system! */
- Xint xs, xe;
- Xint isblank;
- X{
- X int x, i, rm;
- X int sta, sto, cp; /* NOTE: these 3 are in WINDOW coords system */
- X char *wi, *wa, *wf, *oldi;
- X
- X if (y < 0) /* No special full page handling */
- X return;
- X
- X markdata = (struct markdata *)d_lay->l_data;
- X fore = d_fore;
- X
- X wi = iWIN(D2W(y));
- X wa = aWIN(D2W(y));
- X wf = fWIN(D2W(y));
- X oldi = isblank ? blank : null;
- X
- X if (markdata->second == 0)
- X {
- X DisplayLine(oldi, null, null, wi, wa, wf, y, xs, xe);
- X return;
- X }
- X
- X sta = markdata->y1 * d_width + markdata->x1;
- X sto = markdata->cy * d_width + markdata->cx;
- X if (sta > sto)
- X {
- X i=sta; sta=sto; sto=i;
- X }
- X cp = D2W(y) * d_width + xs;
- X
- X rm = markdata->right_mar;
- X for (x = d_width; x >= 0; x--)
- X if (wi[x] != ' ')
- X break;
- X if (x < rm)
- X rm = x;
- X
- X for (x = xs; x <= xe; x++, cp++)
- X if (cp >= sta && x >= markdata->left_mar)
- X break;
- X if (x > xs)
- X DisplayLine(oldi, null, null, wi, wa, wf, y, xs, x-1);
- X for (; x <= xe; x++, cp++)
- X {
- X if (cp > sto || x > rm || (!CLP && x >= d_width-1 && y == d_bot))
- X break;
- X GotoPos(x, y);
- X SetAttrFont(A_SO, ASCII);
- X PUTCHARLP(wi[x]);
- X }
- X if (x <= xe)
- X DisplayLine(oldi, null, null, wi, wa, wf, y, x, xe);
- X}
- X
- X
- X/*
- X * This ugly routine is to speed up GotoPos()
- X */
- Xstatic int
- XMarkRewrite(ry, xs, xe, doit)
- Xint ry, xs, xe, doit;
- X{
- X int dx, x, y, st, en, t, rm;
- X char *a, *f, *i;
- X
- X markdata = (struct markdata *)d_lay->l_data;
- X fore = d_fore;
- X y = D2W(ry);
- X dx = xe - xs;
- X if (doit)
- X {
- X i = iWIN(y) + xs;
- X while (dx--)
- X PUTCHARLP(*i++);
- X return(0);
- X }
- X
- X a = aWIN(y) + xs,
- X f = fWIN(y) + xs;
- X if (markdata->second == 0)
- X st = en = -1;
- X else
- X {
- X st = markdata->y1 * d_width + markdata->x1;
- X en = markdata->cy * d_width + markdata->cx;
- X if (st > en)
- X {
- X t = st; st = en; en = t;
- X }
- X }
- X t = y * d_width + xs;
- X for (rm=d_width, i=iWIN(y) + d_width; rm>=0; rm--)
- X if (*i-- != ' ')
- X break;
- X if (rm > markdata->right_mar)
- X rm = markdata->right_mar;
- X x = xs;
- X while (dx--)
- X {
- X if (t >= st && t <= en && x >= markdata->left_mar && x <= rm)
- X {
- X if (d_attr != A_SO || d_font != ASCII)
- X return(EXPENSIVE);
- X }
- X else
- X {
- X if (d_attr != *a || d_font != *f)
- X return(EXPENSIVE);
- X }
- X a++, f++, t++, x++;
- X }
- X return(xe - xs);
- X}
- X
- X
- X/*
- X * scroll the screen contents up/down.
- X */
- Xstatic int MarkScrollUpDisplay(n)
- Xint n;
- X{
- X int i;
- X
- X debug1("MarkScrollUpDisplay(%d)\n", n);
- X if (n <= 0)
- X return 0;
- X if (n > fore->w_histheight - markdata->hist_offset)
- X n = fore->w_histheight - markdata->hist_offset;
- X i = (n < d_height) ? n : (d_height);
- X ScrollRegion(0, d_height - 1, i);
- X markdata->hist_offset += n;
- X while (i-- > 0)
- X MarkRedisplayLine(d_height - i - 1, 0, d_width - 1, 1);
- X return n;
- X}
- X
- Xstatic int MarkScrollDownDisplay(n)
- Xint n;
- X{
- X int i;
- X
- X debug1("MarkScrollDownDisplay(%d)\n", n);
- X if (n <= 0)
- X return 0;
- X if (n > markdata->hist_offset)
- X n = markdata->hist_offset;
- X i = (n < d_height) ? n : (d_height);
- X ScrollRegion(0, d_height - 1, -i);
- X markdata->hist_offset -= n;
- X while (i-- > 0)
- X MarkRedisplayLine(i, 0, d_width - 1, 1);
- X return n;
- X}
- X
- X#endif /* COPY_PASTE */
- END_OF_FILE
- if test 25607 -ne `wc -c <'mark.c'`; then
- echo shar: \"'mark.c'\" unpacked with wrong size!
- fi
- # end of 'mark.c'
- fi
- if test -f 'tty.c.dist' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'tty.c.dist'\"
- else
- echo shar: Extracting \"'tty.c.dist'\" \(21390 characters\)
- sed "s/^X//" >'tty.c.dist' <<'END_OF_FILE'
- X/* Copyright (c) 1993
- X * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
- X * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
- X * Copyright (c) 1987 Oliver Laumann
- X *
- X * This program is free software; you can redistribute it and/or modify
- X * it under the terms of the GNU General Public License as published by
- X * the Free Software Foundation; either version 2, or (at your option)
- X * any later version.
- X *
- X * This program is distributed in the hope that it will be useful,
- X * but WITHOUT ANY WARRANTY; without even the implied warranty of
- X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X * GNU General Public License for more details.
- X *
- X * You should have received a copy of the GNU General Public License
- X * along with this program (see the file COPYING); if not, write to the
- X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X *
- X ****************************************************************
- X */
- X
- X/*
- X * NOTICE: tty.c is automatically generated from tty.sh
- X * Do not change anything here. If you then change tty.sh.
- X */
- X
- X#include "rcs.h"
- XRCS_ID("$Id: tty.sh,v 1.2 1993/06/17 17:32:23 mlschroe Exp $ FAU")
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <signal.h>
- X#include <fcntl.h>
- X#ifndef sun
- X# include <sys/ioctl.h> /* collosions with termios.h */
- X#else
- X# include <sys/ttold.h> /* needed for TIOCEXCL */
- X#endif
- X
- X#ifdef ISC
- X# include <sys/tty.h>
- X# include <sys/sioctl.h>
- X# include <sys/pty.h>
- X#endif
- X
- X#include "config.h"
- X#include "screen.h"
- X#include "extern.h"
- X
- Xextern struct display *display, *displays;
- Xextern int iflag;
- X
- X
- X/*
- X * Carefully open a charcter device. Not used to open ttys.
- X */
- X
- Xint
- XOpenTTY(line)
- Xchar *line;
- X{
- X int f;
- X sig_t (*sigalrm)__P(SIGPROTOARG);
- X
- X sigalrm = signal(SIGALRM, SIG_IGN);
- X alarm(2);
- X /* this open only succeeds, if real uid is allowed */
- X if ((f = secopen(line, O_RDWR | O_NDELAY, 0)) == -1)
- X {
- X Msg(errno, "Cannot open line '%s' for R/W", line);
- X alarm(0);
- X signal(SIGALRM, sigalrm);
- X return -1;
- X }
- X#ifdef I_POP
- X debug("OpenTTY I_POP\n");
- X while (ioctl(f, I_POP) >= 0)
- X ;
- X#endif
- X /*
- X * We come here exclusively. This is to stop all kermit and cu type things
- X * accessing the same tty line.
- X * Perhaps we should better create a lock in some /usr/spool/locks directory?
- X */
- X#ifdef TIOCEXCL
- X errno = 0;
- X ioctl(f, TIOCEXCL, (char *) 0);
- X debug3("%d %d %d\n", getuid(), geteuid(), getpid());
- X debug2("%s TIOCEXCL errno %d\n", line, errno);
- X#endif /* TIOCEXCL */
- X /*
- X * We create a sane tty mode. We do not copy things from the display tty
- X */
- X#if WE_REALLY_WANT_TO_COPY_THE_TTY_MODE
- X if (display)
- X {
- X debug1("OpenTTY: using mode of display for %s\n", line);
- X SetTTY(f, &d_NewMode);
- X#ifdef DEBUG
- X DebugTTY(&d_NewMode);
- X#endif
- X }
- X else
- X#endif
- X {
- X struct mode Mode;
- X
- X InitTTY(&Mode, TTY_FLAG_PLAIN);
- X#ifdef DEBUG
- X DebugTTY(&Mode);
- X#endif
- X SetTTY(f, &Mode);
- X }
- X brktty(f);
- X alarm(0);
- X signal(SIGALRM, sigalrm);
- X debug2("'%s' CONNECT fd=%d.\n", line, f);
- X return f;
- X}
- X
- X
- X/*
- X * Tty mode handling
- X */
- X
- X#if defined(TERMIO) || defined(POSIX)
- Xint intrc, origintrc = VDISABLE; /* display? */
- X#else
- Xint intrc, origintrc = -1; /* display? */
- X#endif
- Xstatic startc, stopc; /* display? */
- X
- X
- Xvoid
- XInitTTY(m, ttyflag)
- Xstruct mode *m;
- Xint ttyflag;
- X{
- X bzero((char *)m, sizeof(*m));
- X#ifdef POSIX
- X /* struct termios tio
- X * defaults, as seen on SunOS 4.1.3
- X */
- X debug1("InitTTY: POSIX: termios defaults a la SunOS 4.1.3 (%d)\n", ttyflag);
- X#if defined(BRKINT)
- X m->tio.c_iflag |= BRKINT;
- X#endif /* BRKINT */
- X#if defined(IGNPAR)
- X m->tio.c_iflag |= IGNPAR;
- X#endif /* IGNPAR */
- X#if defined(ISTRIP)
- X m->tio.c_iflag |= ISTRIP;
- X#endif /* ISTRIP */
- X#if defined(IXON)
- X m->tio.c_iflag |= IXON;
- X#endif /* IXON */
- X#if defined(IMAXBEL)
- X m->tio.c_iflag |= IMAXBEL;
- X#endif /* IMAXBEL */
- X
- X if (!ttyflag) /* may not even be good for ptys.. */
- X {
- X#if defined(ICRNL)
- X m->tio.c_iflag |= ICRNL;
- X#endif /* ICRNL */
- X#if defined(ONLCR)
- X m->tio.c_oflag |= ONLCR;
- X#endif /* ONLCR */
- X#if defined(TAB3)
- X m->tio.c_oflag |= TAB3;
- X#endif /* TAB3 */
- X#if defined(PARENB)
- X m->tio.c_cflag |= PARENB;
- X#endif /* PARENB */
- X }
- X
- X#if defined(OPOST)
- X m->tio.c_oflag |= OPOST;
- X#endif /* OPOST */
- X
- X#if defined(B9600)
- X m->tio.c_cflag |= B9600;
- X#endif /* B9600 */
- X#if defined(CS8)
- X m->tio.c_cflag |= CS8;
- X#endif /* CS8 */
- X#if defined(CREAD)
- X m->tio.c_cflag |= CREAD;
- X#endif /* CREAD */
- X#if defined(IBSHIFT) && defined(B9600)
- X m->tio.c_cflag |= B9600 << IBSHIFT;
- X#endif /* IBSHIFT) && defined(B9600 */
- X/* IF{CLOCAL} m->tio.c_cflag |= CLOCAL; */
- X
- X#if defined(ECHOCTL)
- X m->tio.c_lflag |= ECHOCTL;
- X#endif /* ECHOCTL */
- X#if defined(ECHOKE)
- X m->tio.c_lflag |= ECHOKE;
- X#endif /* ECHOKE */
- X
- X if (!ttyflag)
- X {
- X#if defined(ISIG)
- X m->tio.c_lflag |= ISIG;
- X#endif /* ISIG */
- X#if defined(ICANON)
- X m->tio.c_lflag |= ICANON;
- X#endif /* ICANON */
- X#if defined(ECHO)
- X m->tio.c_lflag |= ECHO;
- X#endif /* ECHO */
- X }
- X#if defined(ECHOE)
- X m->tio.c_lflag |= ECHOE;
- X#endif /* ECHOE */
- X#if defined(ECHOK)
- X m->tio.c_lflag |= ECHOK;
- X#endif /* ECHOK */
- X#if defined(IEXTEN)
- X m->tio.c_lflag |= IEXTEN;
- X#endif /* IEXTEN */
- X
- X#if defined(VINTR)
- X m->tio.c_cc[VINTR] = Ctrl('C');
- X#endif /* VINTR */
- X#if defined(VQUIT)
- X m->tio.c_cc[VQUIT] = Ctrl('\\');
- X#endif /* VQUIT */
- X#if defined(VERASE)
- X m->tio.c_cc[VERASE] = 0x7f; /* DEL */
- X#endif /* VERASE */
- X#if defined(VKILL)
- X m->tio.c_cc[VKILL] = Ctrl('H');
- X#endif /* VKILL */
- X#if defined(VEOF)
- X m->tio.c_cc[VEOF] = Ctrl('D');
- X#endif /* VEOF */
- X#if defined(VEOL)
- X m->tio.c_cc[VEOL] = 0000;
- X#endif /* VEOL */
- X#if defined(VEOL2)
- X m->tio.c_cc[VEOL2] = 0000;
- X#endif /* VEOL2 */
- X#if defined(VSWTCH)
- X m->tio.c_cc[VSWTCH] = 0000;
- X#endif /* VSWTCH */
- X#if defined(VSTART)
- X m->tio.c_cc[VSTART] = Ctrl('Q');
- X#endif /* VSTART */
- X#if defined(VSTOP)
- X m->tio.c_cc[VSTOP] = Ctrl('S');
- X#endif /* VSTOP */
- X#if defined(VSUSP)
- X m->tio.c_cc[VSUSP] = Ctrl('Z');
- X#endif /* VSUSP */
- X#if defined(VDSUSP)
- X m->tio.c_cc[VDSUSP] = Ctrl('Y');
- X#endif /* VDSUSP */
- X#if defined(VREPRINT)
- X m->tio.c_cc[VREPRINT] = Ctrl('R');
- X#endif /* VREPRINT */
- X#if defined(VDISCARD)
- X m->tio.c_cc[VDISCARD] = Ctrl('O');
- X#endif /* VDISCARD */
- X#if defined(VWERASE)
- X m->tio.c_cc[VWERASE] = Ctrl('W');
- X#endif /* VWERASE */
- X#if defined(VLNEXT)
- X m->tio.c_cc[VLNEXT] = Ctrl('V');
- X#endif /* VLNEXT */
- X#if defined(VSTATUS)
- X m->tio.c_cc[VSTATUS] = Ctrl('T');
- X#endif /* VSTATUS */
- X
- X# ifdef hpux
- X m->m_ltchars.t_suspc = Ctrl('Z');
- X m->m_ltchars.t_dsuspc = Ctrl('Y');
- X m->m_ltchars.t_rprntc = Ctrl('R');
- X m->m_ltchars.t_flushc = Ctrl('O');
- X m->m_ltchars.t_werasc = Ctrl('W');
- X m->m_ltchars.t_lnextc = Ctrl('V');
- X# endif /* hpux */
- X
- X#else /* POSIX */
- X
- X# ifdef TERMIO
- X debug1("InitTTY: nonPOSIX, struct termio a la Motorola SYSV68 (%d)\n", ttyflag);
- X /* struct termio tio
- X * defaults, as seen on Mototola SYSV68:
- X * input: 7bit, CR->NL, ^S/^Q flow control
- X * output: POSTprocessing: NL->NL-CR, Tabs to spaces
- X * control: 9600baud, 8bit CSIZE, enable input
- X * local: enable signals, erase/kill processing, echo on.
- X */
- X#if defined(ISTRIP)
- X m->tio.c_iflag |= ISTRIP;
- X#endif /* ISTRIP */
- X#if defined(IXON)
- X m->tio.c_iflag |= IXON;
- X#endif /* IXON */
- X
- X#if defined(OPOST)
- X m->tio.c_oflag |= OPOST;
- X#endif /* OPOST */
- X
- X if (!ttyflag) /* may not even be good for ptys.. */
- X {
- X#if defined(ICRNL)
- X m->tio.c_iflag |= ICRNL;
- X#endif /* ICRNL */
- X#if defined(ONLCR)
- X m->tio.c_oflag |= ONLCR;
- X#endif /* ONLCR */
- X#if defined(TAB3)
- X m->tio.c_oflag |= TAB3;
- X#endif /* TAB3 */
- X }
- X
- X#if defined(B9600)
- X m->tio.c_cflag = B9600;
- X#endif /* B9600 */
- X#if defined(CS8)
- X m->tio.c_cflag |= CS8;
- X#endif /* CS8 */
- X#if defined(CREAD)
- X m->tio.c_cflag |= CREAD;
- X#endif /* CREAD */
- X
- X if (!ttyflag)
- X {
- X#if defined(ISIG)
- X m->tio.c_lflag |= ISIG;
- X#endif /* ISIG */
- X#if defined(ICANON)
- X m->tio.c_lflag |= ICANON;
- X#endif /* ICANON */
- X#if defined(ECHO)
- X m->tio.c_lflag |= ECHO;
- X#endif /* ECHO */
- X }
- X#if defined(ECHOE)
- X m->tio.c_lflag |= ECHOE;
- X#endif /* ECHOE */
- X#if defined(ECHOK)
- X m->tio.c_lflag |= ECHOK;
- X#endif /* ECHOK */
- X
- X#if defined(VINTR)
- X m->tio.c_cc[VINTR] = Ctrl('C');
- X#endif /* VINTR */
- X#if defined(VQUIT)
- X m->tio.c_cc[VQUIT] = Ctrl('\\');
- X#endif /* VQUIT */
- X#if defined(VERASE)
- X m->tio.c_cc[VERASE] = 0177; /* DEL */
- X#endif /* VERASE */
- X#if defined(VKILL)
- X m->tio.c_cc[VKILL] = Ctrl('H');
- X#endif /* VKILL */
- X#if defined(VEOF)
- X m->tio.c_cc[VEOF] = Ctrl('D');
- X#endif /* VEOF */
- X#if defined(VEOL)
- X m->tio.c_cc[VEOL] = 0377;
- X#endif /* VEOL */
- X#if defined(VEOL2)
- X m->tio.c_cc[VEOL2] = 0377;
- X#endif /* VEOL2 */
- X#if defined(VSWTCH)
- X m->tio.c_cc[VSWTCH] = 0000;
- X#endif /* VSWTCH */
- X# else /* TERMIO */
- X debug1("InitTTY: BSD: defaults a la SunOS 4.1.3 (%d)\n", ttyflag);
- X m->m_ttyb.sg_ispeed = B9600;
- X m->m_ttyb.sg_ospeed = B9600;
- X m->m_ttyb.sg_erase = 0177; /*DEL */
- X m->m_ttyb.sg_kill = Ctrl('H');
- X if (!ttyflag)
- X m->m_ttyb.sg_flags = CRMOD | ECHO
- X#if defined(ANYP)
- X | ANYP
- X#endif /* ANYP */
- X ;
- X else
- X m->m_ttyb.sg_flags = CBREAK
- X#if defined(ANYP)
- X | ANYP
- X#endif /* ANYP */
- X ;
- X
- X m->m_tchars.t_intrc = Ctrl('C');
- X m->m_tchars.t_quitc = Ctrl('\\');
- X m->m_tchars.t_startc = Ctrl('Q');
- X m->m_tchars.t_stopc = Ctrl('S');
- X m->m_tchars.t_eofc = Ctrl('D');
- X m->m_tchars.t_brkc = -1;
- X
- X m->m_ltchars.t_suspc = Ctrl('Z');
- X m->m_ltchars.t_dsuspc = Ctrl('Y');
- X m->m_ltchars.t_rprntc = Ctrl('R');
- X m->m_ltchars.t_flushc = Ctrl('O');
- X m->m_ltchars.t_werasc = Ctrl('W');
- X m->m_ltchars.t_lnextc = Ctrl('V');
- X
- X#if defined(NTTYDISC)
- X m->m_ldisc = NTTYDISC;
- X#endif /* NTTYDISC */
- X
- X m->m_lmode = 0
- X#if defined(LDECCTQ)
- X | LDECCTQ
- X#endif /* LDECCTQ */
- X#if defined(LCTLECH)
- X | LCTLECH
- X#endif /* LCTLECH */
- X#if defined(LPASS8)
- X | LPASS8
- X#endif /* LPASS8 */
- X#if defined(LCRTKIL)
- X | LCRTKIL
- X#endif /* LCRTKIL */
- X#if defined(LCRTERA)
- X | LCRTERA
- X#endif /* LCRTERA */
- X#if defined(LCRTBS)
- X | LCRTBS
- X#endif /* LCRTBS */
- X;
- X# endif /* TERMIO */
- X#endif /* POSIX */
- X}
- X
- Xvoid
- XSetTTY(fd, mp)
- Xint fd;
- Xstruct mode *mp;
- X{
- X errno = 0;
- X#ifdef POSIX
- X tcsetattr(fd, TCSADRAIN, &mp->tio);
- X# ifdef hpux
- X ioctl(fd, TIOCSLTC, &mp->m_ltchars);
- X# endif
- X#else
- X# ifdef TERMIO
- X ioctl(fd, TCSETAW, &mp->tio);
- X# else
- X /* ioctl(fd, TIOCSETP, &mp->m_ttyb); */
- X ioctl(fd, TIOCSETC, &mp->m_tchars);
- X ioctl(fd, TIOCLSET, &mp->m_lmode);
- X ioctl(fd, TIOCSETD, &mp->m_ldisc);
- X ioctl(fd, TIOCSETP, &mp->m_ttyb);
- X ioctl(fd, TIOCSLTC, &mp->m_ltchars); /* moved here for apollo. jw */
- X# endif
- X#endif
- X if (errno)
- X Msg(errno, "SetTTY (fd %d): ioctl failed", fd);
- X}
- X
- Xvoid
- XGetTTY(fd, mp)
- Xint fd;
- Xstruct mode *mp;
- X{
- X errno = 0;
- X#ifdef POSIX
- X tcgetattr(fd, &mp->tio);
- X# ifdef hpux
- X ioctl(fd, TIOCGLTC, &mp->m_ltchars);
- X# endif
- X#else
- X# ifdef TERMIO
- X ioctl(fd, TCGETA, &mp->tio);
- X# else
- X ioctl(fd, TIOCGETP, &mp->m_ttyb);
- X ioctl(fd, TIOCGETC, &mp->m_tchars);
- X ioctl(fd, TIOCGLTC, &mp->m_ltchars);
- X ioctl(fd, TIOCLGET, &mp->m_lmode);
- X ioctl(fd, TIOCGETD, &mp->m_ldisc);
- X# endif
- X#endif
- X if (errno)
- X Msg(errno, "GetTTY (fd %d): ioctl failed", fd);
- X}
- X
- Xvoid
- XSetMode(op, np)
- Xstruct mode *op, *np;
- X{
- X *np = *op;
- X
- X#if defined(TERMIO) || defined(POSIX)
- X np->tio.c_iflag &= ~ICRNL;
- X# ifdef ONLCR
- X np->tio.c_oflag &= ~ONLCR;
- X# endif
- X np->tio.c_lflag &= ~(ICANON | ECHO);
- X
- X /*
- X * Unfortunately, the master process never will get SIGINT if the real
- X * terminal is different from the one on which it was originaly started
- X * (process group membership has not been restored or the new tty could not
- X * be made controlling again). In my solution, it is the attacher who
- X * receives SIGINT (because it is always correctly associated with the real
- X * tty) and forwards it to the master [kill(MasterPid, SIGINT)].
- X * Marc Boucher (marc@CAM.ORG)
- X */
- X if (iflag)
- X np->tio.c_lflag |= ISIG;
- X else
- X np->tio.c_lflag &= ~ISIG;
- X /*
- X * careful, careful catche monkey..
- X * never set VMIN and VTIME to zero, if you want blocking io.
- X */
- X np->tio.c_cc[VMIN] = 1;
- X np->tio.c_cc[VTIME] = 0;
- X#if defined(VSTART)
- X startc = op->tio.c_cc[VSTART];
- X#endif /* VSTART */
- X#if defined(VSTOP)
- X stopc = op->tio.c_cc[VSTOP];
- X#endif /* VSTOP */
- X if (iflag)
- X origintrc = intrc = op->tio.c_cc[VINTR];
- X else
- X {
- X origintrc = op->tio.c_cc[VINTR];
- X intrc = np->tio.c_cc[VINTR] = VDISABLE;
- X }
- X np->tio.c_cc[VQUIT] = VDISABLE;
- X if (d_flow == 0)
- X {
- X np->tio.c_cc[VINTR] = VDISABLE;
- X#if defined(VSTART)
- X np->tio.c_cc[VSTART] = VDISABLE;
- X#endif /* VSTART */
- X#if defined(VSTOP)
- X np->tio.c_cc[VSTOP] = VDISABLE;
- X#endif /* VSTOP */
- X np->tio.c_iflag &= ~IXON;
- X }
- X#if defined(VDISCARD)
- X np->tio.c_cc[VDISCARD] = VDISABLE;
- X#endif /* VDISCARD */
- X#if defined(VSUSP)
- X np->tio.c_cc[VSUSP] = VDISABLE;
- X#endif /* VSUSP */
- X# ifdef hpux
- X np->m_ltchars.t_suspc = VDISABLE;
- X np->m_ltchars.t_dsuspc = VDISABLE;
- X np->m_ltchars.t_rprntc = VDISABLE;
- X np->m_ltchars.t_flushc = VDISABLE;
- X np->m_ltchars.t_werasc = VDISABLE;
- X np->m_ltchars.t_lnextc = VDISABLE;
- X# else /* hpux */
- X#if defined(VDSUSP)
- X np->tio.c_cc[VDSUSP] = VDISABLE;
- X#endif /* VDSUSP */
- X# endif /* hpux */
- X#else /* TERMIO || POSIX */
- X startc = op->m_tchars.t_startc;
- X stopc = op->m_tchars.t_stopc;
- X if (iflag)
- X origintrc = intrc = op->m_tchars.t_intrc;
- X else
- X {
- X origintrc = op->m_tchars.t_intrc;
- X intrc = np->m_tchars.t_intrc = -1;
- X }
- X np->m_ttyb.sg_flags &= ~(CRMOD | ECHO);
- X np->m_ttyb.sg_flags |= CBREAK;
- X np->m_tchars.t_quitc = -1;
- X if (d_flow == 0)
- X {
- X np->m_tchars.t_intrc = -1;
- X np->m_tchars.t_startc = -1;
- X np->m_tchars.t_stopc = -1;
- X }
- X np->m_ltchars.t_suspc = -1;
- X np->m_ltchars.t_dsuspc = -1;
- X np->m_ltchars.t_flushc = -1;
- X np->m_ltchars.t_lnextc = -1;
- X#endif /* defined(TERMIO) || defined(POSIX) */
- X}
- X
- Xvoid
- XSetFlow(on)
- Xint on;
- X{
- X ASSERT(display);
- X if (d_flow == on)
- X return;
- X#if defined(TERMIO) || defined(POSIX)
- X if (on)
- X {
- X d_NewMode.tio.c_cc[VINTR] = intrc;
- X#if defined(VSTART)
- X d_NewMode.tio.c_cc[VSTART] = startc;
- X#endif /* VSTART */
- X#if defined(VSTOP)
- X d_NewMode.tio.c_cc[VSTOP] = stopc;
- X#endif /* VSTOP */
- X d_NewMode.tio.c_iflag |= IXON;
- X }
- X else
- X {
- X d_NewMode.tio.c_cc[VINTR] = VDISABLE;
- X#if defined(VSTART)
- X d_NewMode.tio.c_cc[VSTART] = VDISABLE;
- X#endif /* VSTART */
- X#if defined(VSTOP)
- X d_NewMode.tio.c_cc[VSTOP] = VDISABLE;
- X#endif /* VSTOP */
- X d_NewMode.tio.c_iflag &= ~IXON;
- X }
- X# ifdef POSIX
- X if (tcsetattr(d_userfd, TCSANOW, &d_NewMode.tio))
- X# else
- X if (ioctl(d_userfd, TCSETAW, &d_NewMode.tio) != 0)
- X# endif
- X debug1("SetFlow: ioctl errno %d\n", errno);
- X#else /* POSIX || TERMIO */
- X if (on)
- X {
- X d_NewMode.m_tchars.t_intrc = intrc;
- X d_NewMode.m_tchars.t_startc = startc;
- X d_NewMode.m_tchars.t_stopc = stopc;
- X }
- X else
- X {
- X d_NewMode.m_tchars.t_intrc = -1;
- X d_NewMode.m_tchars.t_startc = -1;
- X d_NewMode.m_tchars.t_stopc = -1;
- X }
- X if (ioctl(d_userfd, TIOCSETC, &d_NewMode.m_tchars) != 0)
- X debug1("SetFlow: ioctl errno %d\n", errno);
- X#endif /* POSIX || TERMIO */
- X d_flow = on;
- X}
- X
- X
- X/*
- X * Job control handling
- X */
- X
- X/*ARGSUSED*/
- Xvoid
- Xbrktty(fd)
- Xint fd;
- X{
- X#ifdef POSIX
- X setsid(); /* will break terminal affiliation */
- X# ifdef BSD
- X ioctl(fd, TIOCSCTTY, 0);
- X# endif /* BSD */
- X#else /* POSIX */
- X# ifdef SYSV
- X setpgrp(); /* will break terminal affiliation */
- X# else /* SYSV */
- X# ifdef BSDJOBS
- X int devtty;
- X
- X if ((devtty = open("/dev/tty", O_RDWR | O_NDELAY)) >= 0)
- X {
- X if (ioctl(devtty, TIOCNOTTY, (char *)0))
- X debug2("brktty: ioctl(devtty=%d, TIOCNOTTY, 0) = %d\n", devtty, errno);
- X close(devtty);
- X }
- X# endif /* BSDJOBS */
- X# endif /* SYSV */
- X#endif /* POSIX */
- X}
- X
- Xint
- Xfgtty(fd)
- Xint fd;
- X{
- X#ifdef BSDJOBS
- X int mypid;
- X
- X mypid = getpid();
- X
- X# if defined(BSDI) || defined(__386BSD__) || defined(__osf__)
- X setsid(); /* should be already done */
- X ioctl(fd, TIOCSCTTY, 0);
- X# endif /* BSDI || __386BSD__ */
- X
- X# ifdef POSIX
- X if (tcsetpgrp(fd, mypid))
- X {
- X debug1("fgtty: tcsetpgrp: %d\n", errno);
- X return -1;
- X }
- X# else /* POSIX */
- X if (ioctl(fd, TIOCSPGRP, &mypid) != 0)
- X debug1("fgtty: TIOSETPGRP: %d\n", errno);
- X# ifndef SYSV /* Already done in brktty():setpgrp() */
- X if (setpgrp(fd, mypid))
- X debug1("fgtty: setpgrp: %d\n", errno);
- X# endif
- X# endif /* POSIX */
- X#endif /* BSDJOBS */
- X return 0;
- X}
- X
- X
- X/*
- X * Send a break for n * 0.25 seconds. Tty must be PLAIN.
- X */
- X
- Xvoid SendBreak(wp, n, closeopen)
- Xstruct win *wp;
- Xint n, closeopen;
- X{
- X if ((wp->w_t.flags & TTY_FLAG_PLAIN) == 0)
- X return;
- X
- X debug3("break(%d, %d) fd %d\n", n, closeopen, wp->w_ptyfd);
- X#ifdef POSIX
- X (void) tcflush(wp->w_ptyfd, TCIOFLUSH);
- X#else
- X# ifdef TIOCFLUSH
- X (void) ioctl(wp->w_ptyfd, TIOCFLUSH, (char *)0);
- X# endif /* TIOCFLUSH */
- X#endif /* POSIX */
- X if (closeopen)
- X {
- X close(wp->w_ptyfd);
- X sleep((n + 3) / 4);
- X if ((wp->w_ptyfd = OpenTTY(wp->w_tty)) < 1)
- X {
- X Msg(0, "Ouch, cannot reopen line %s, please try harder", wp->w_tty);
- X return;
- X }
- X }
- X else
- X {
- X#ifdef POSIX
- X debug("tcsendbreak\n");
- X if (tcsendbreak(wp->w_ptyfd, n) < 0)
- X {
- X Msg(errno, "cannot send BREAK");
- X return;
- X }
- X#else
- X if (!n)
- X n++;
- X# ifdef TCSBRK
- X debug("TCSBRK\n");
- X {
- X int i;
- X for (i = 0; i < n; i++)
- X if (ioctl(wp->w_ptyfd, TCSBRK, (char *)0) < 0)
- X {
- X Msg(errno, "Cannot send BREAK");
- X return;
- X }
- X }
- X# else /* TCSBRK */
- X# if defined(TIOCSBRK) && defined(TIOCCBRK)
- X debug("TIOCSBRK TIOCCBRK\n");
- X if (ioctl(wp->w_ptyfd, TIOCSBRK, (char *)0) < 0)
- X {
- X Msg(errno, "Can't send BREAK");
- X return;
- X }
- X sleep((n + 3) / 4);
- X if (ioctl(wp->w_ptyfd, TIOCCBRK, (char *)0) < 0)
- X {
- X Msg(errno, "BREAK stuck!!! -- HELP!");
- X return;
- X }
- X# else /* TIOCSBRK && TIOCCBRK */
- X Msg(0, "Break not simulated yet");
- X return;
- X# endif /* TIOCSBRK && TIOCCBRK */
- X# endif /* TCSBRK */
- X#endif /* POSIX */
- X debug(" broken\n");
- X }
- X}
- X
- X
- X/*
- X * Console grabbing
- X */
- X
- X/*ARGSUSED*/
- Xint
- XTtyGrabConsole(fd, on, rc_name)
- Xint fd, on;
- Xchar *rc_name;
- X{
- X#ifdef TIOCCONS
- X char *slave;
- X int sfd = -1, ret = 0;
- X struct display *d;
- X
- X if (!on)
- X {
- X if ((fd = OpenPTY(&slave)) < 0)
- X {
- X Msg(errno, "%s: could not open detach pty master", rc_name);
- X return -1;
- X }
- X if ((sfd = open(slave, O_RDWR)) < 0)
- X {
- X Msg(errno, "%s: could not open detach pty slave", rc_name);
- X close(fd);
- X return -1;
- X }
- X }
- X else
- X {
- X if (displays == 0)
- X {
- X Msg(0, "I need a display");
- X return -1;
- X }
- X for (d = displays; d; d = d->_d_next)
- X if (strcmp(d->_d_usertty, "/dev/console") == 0)
- X break;
- X if (d)
- X {
- X Msg(0, "too dangerous - screen is running on /dev/console");
- X return -1;
- X }
- X }
- X if (UserContext() == 1)
- X UserReturn(ioctl(fd, TIOCCONS, &on));
- X ret = UserStatus();
- X if (ret)
- X Msg(errno, "%s: ioctl TIOCCONS failed", rc_name);
- X if (!on)
- X {
- X close(sfd);
- X close(fd);
- X }
- X return ret;
- X#else /* TIOCCONS */
- X Msg(0, "%s: no TIOCCONS on this machine", rc_name);
- X return -1;
- X#endif /* TIOCCONS */
- X}
- X
- X
- X/*
- X * Write out the mode struct in a readable form
- X */
- X
- X#ifdef DEBUG
- Xvoid
- XDebugTTY(m)
- Xstruct mode *m;
- X{
- X int i;
- X
- X#ifdef POSIX
- X debug("struct termios tio:\n");
- X debug1("c_iflag = %#x\n", m->tio.c_iflag);
- X debug1("c_oflag = %#x\n", m->tio.c_oflag);
- X debug1("c_cflag = %#x\n", m->tio.c_cflag);
- X debug1("c_lflag = %#x\n", m->tio.c_lflag);
- X for (i = 0; i < NCCS; i++)
- X {
- X debug2("c_cc[%d] = %#x\n", i, m->tio.c_cc[i]);
- X }
- X# ifdef hpux
- X debug1("suspc = %#02x\n", m->m_ltchars.t_suspc);
- X debug1("dsuspc = %#02x\n", m->m_ltchars.t_dsuspc);
- X debug1("rprntc = %#02x\n", m->m_ltchars.t_rprntc);
- X debug1("flushc = %#02x\n", m->m_ltchars.t_flushc);
- X debug1("werasc = %#02x\n", m->m_ltchars.t_werasc);
- X debug1("lnextc = %#02x\n", m->m_ltchars.t_lnextc);
- X# endif /* hpux */
- X#else /* POSIX */
- X# ifdef TERMIO
- X debug("struct termio tio:\n");
- X debug1("c_iflag = %04o\n", m->tio.c_iflag);
- X debug1("c_oflag = %04o\n", m->tio.c_oflag);
- X debug1("c_cflag = %04o\n", m->tio.c_cflag);
- X debug1("c_lflag = %04o\n", m->tio.c_lflag);
- X for (i = 0; i < NCC; i++)
- X {
- X debug2("c_cc[%d] = %04o\n", i, m->tio.c_cc[i]);
- X }
- X# else /* TERMIO */
- X debug1("sg_ispeed = %d\n", m->m_ttyb.sg_ispeed);
- X debug1("sg_ospeed = %d\n", m->m_ttyb.sg_ospeed);
- X debug1("sg_erase = %#02x\n", m->m_ttyb.sg_erase);
- X debug1("sg_kill = %#02x\n", m->m_ttyb.sg_kill);
- X debug1("sg_flags = %#04x\n", (unsigned short)m->m_ttyb.sg_flags);
- X debug1("intrc = %#02x\n", m->m_tchars.t_intrc);
- X debug1("quitc = %#02x\n", m->m_tchars.t_quitc);
- X debug1("startc = %#02x\n", m->m_tchars.t_startc);
- X debug1("stopc = %#02x\n", m->m_tchars.t_stopc);
- X debug1("eofc = %#02x\n", m->m_tchars.t_eofc);
- X debug1("brkc = %#02x\n", m->m_tchars.t_brkc);
- X debug1("suspc = %#02x\n", m->m_ltchars.t_suspc);
- X debug1("dsuspc = %#02x\n", m->m_ltchars.t_dsuspc);
- X debug1("rprntc = %#02x\n", m->m_ltchars.t_rprntc);
- X debug1("flushc = %#02x\n", m->m_ltchars.t_flushc);
- X debug1("werasc = %#02x\n", m->m_ltchars.t_werasc);
- X debug1("lnextc = %#02x\n", m->m_ltchars.t_lnextc);
- X debug1("ldisc = %d\n", m->m_ldisc);
- X debug1("lmode = %#x\n", m->m_lmode);
- X# endif /* TERMIO */
- X#endif /* POSIX */
- X}
- X#endif /* DEBUG */
- END_OF_FILE
- if test 21390 -ne `wc -c <'tty.c.dist'`; then
- echo shar: \"'tty.c.dist'\" unpacked with wrong size!
- fi
- # end of 'tty.c.dist'
- fi
- if test -f 'tty.sh' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'tty.sh'\"
- else
- echo shar: Extracting \"'tty.sh'\" \(19054 characters\)
- sed "s/^X//" >'tty.sh' <<'END_OF_FILE'
- X#!/bin/sh
- X# sh tty.sh tty.c
- X# This inserts all the needed #ifdefs for IF{} statements
- X# and generates tty.c
- X
- Xrm -f $1
- Xsed -e '1,12d' -e 's%^IF{\(.*\)}\(.*\)%#if defined(\1)\
- X \2\
- X#endif /* \1 */%' < $0 > $1
- Xchmod -w $1
- Xexit 0
- X
- X/* Copyright (c) 1993
- X * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
- X * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
- X * Copyright (c) 1987 Oliver Laumann
- X *
- X * This program is free software; you can redistribute it and/or modify
- X * it under the terms of the GNU General Public License as published by
- X * the Free Software Foundation; either version 2, or (at your option)
- X * any later version.
- X *
- X * This program is distributed in the hope that it will be useful,
- X * but WITHOUT ANY WARRANTY; without even the implied warranty of
- X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X * GNU General Public License for more details.
- X *
- X * You should have received a copy of the GNU General Public License
- X * along with this program (see the file COPYING); if not, write to the
- X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X *
- X ****************************************************************
- X */
- X
- X/*
- X * NOTICE: tty.c is automatically generated from tty.sh
- X * Do not change anything here. If you then change tty.sh.
- X */
- X
- X#include "rcs.h"
- XRCS_ID("$Id: tty.sh,v 1.2 1993/06/17 17:32:23 mlschroe Exp $ FAU")
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <signal.h>
- X#include <fcntl.h>
- X#ifndef sun
- X# include <sys/ioctl.h> /* collosions with termios.h */
- X#else
- X# include <sys/ttold.h> /* needed for TIOCEXCL */
- X#endif
- X
- X#ifdef ISC
- X# include <sys/tty.h>
- X# include <sys/sioctl.h>
- X# include <sys/pty.h>
- X#endif
- X
- X#include "config.h"
- X#include "screen.h"
- X#include "extern.h"
- X
- Xextern struct display *display, *displays;
- Xextern int iflag;
- X
- X
- X/*
- X * Carefully open a charcter device. Not used to open ttys.
- X */
- X
- Xint
- XOpenTTY(line)
- Xchar *line;
- X{
- X int f;
- X sig_t (*sigalrm)__P(SIGPROTOARG);
- X
- X sigalrm = signal(SIGALRM, SIG_IGN);
- X alarm(2);
- X /* this open only succeeds, if real uid is allowed */
- X if ((f = secopen(line, O_RDWR | O_NDELAY, 0)) == -1)
- X {
- X Msg(errno, "Cannot open line '%s' for R/W", line);
- X alarm(0);
- X signal(SIGALRM, sigalrm);
- X return -1;
- X }
- X#ifdef I_POP
- X debug("OpenTTY I_POP\n");
- X while (ioctl(f, I_POP) >= 0)
- X ;
- X#endif
- X /*
- X * We come here exclusively. This is to stop all kermit and cu type things
- X * accessing the same tty line.
- X * Perhaps we should better create a lock in some /usr/spool/locks directory?
- X */
- X#ifdef TIOCEXCL
- X errno = 0;
- X ioctl(f, TIOCEXCL, (char *) 0);
- X debug3("%d %d %d\n", getuid(), geteuid(), getpid());
- X debug2("%s TIOCEXCL errno %d\n", line, errno);
- X#endif /* TIOCEXCL */
- X /*
- X * We create a sane tty mode. We do not copy things from the display tty
- X */
- X#if WE_REALLY_WANT_TO_COPY_THE_TTY_MODE
- X if (display)
- X {
- X debug1("OpenTTY: using mode of display for %s\n", line);
- X SetTTY(f, &d_NewMode);
- X#ifdef DEBUG
- X DebugTTY(&d_NewMode);
- X#endif
- X }
- X else
- X#endif
- X {
- X struct mode Mode;
- X
- X InitTTY(&Mode, TTY_FLAG_PLAIN);
- X#ifdef DEBUG
- X DebugTTY(&Mode);
- X#endif
- X SetTTY(f, &Mode);
- X }
- X brktty(f);
- X alarm(0);
- X signal(SIGALRM, sigalrm);
- X debug2("'%s' CONNECT fd=%d.\n", line, f);
- X return f;
- X}
- X
- X
- X/*
- X * Tty mode handling
- X */
- X
- X#if defined(TERMIO) || defined(POSIX)
- Xint intrc, origintrc = VDISABLE; /* display? */
- X#else
- Xint intrc, origintrc = -1; /* display? */
- X#endif
- Xstatic startc, stopc; /* display? */
- X
- X
- Xvoid
- XInitTTY(m, ttyflag)
- Xstruct mode *m;
- Xint ttyflag;
- X{
- X bzero((char *)m, sizeof(*m));
- X#ifdef POSIX
- X /* struct termios tio
- X * defaults, as seen on SunOS 4.1.3
- X */
- X debug1("InitTTY: POSIX: termios defaults a la SunOS 4.1.3 (%d)\n", ttyflag);
- XIF{BRKINT} m->tio.c_iflag |= BRKINT;
- XIF{IGNPAR} m->tio.c_iflag |= IGNPAR;
- XIF{ISTRIP} m->tio.c_iflag |= ISTRIP;
- XIF{IXON} m->tio.c_iflag |= IXON;
- XIF{IMAXBEL} m->tio.c_iflag |= IMAXBEL;
- X
- X if (!ttyflag) /* may not even be good for ptys.. */
- X {
- XIF{ICRNL} m->tio.c_iflag |= ICRNL;
- XIF{ONLCR} m->tio.c_oflag |= ONLCR;
- XIF{TAB3} m->tio.c_oflag |= TAB3;
- XIF{PARENB} m->tio.c_cflag |= PARENB;
- X }
- X
- XIF{OPOST} m->tio.c_oflag |= OPOST;
- X
- XIF{B9600} m->tio.c_cflag |= B9600;
- XIF{CS8} m->tio.c_cflag |= CS8;
- XIF{CREAD} m->tio.c_cflag |= CREAD;
- XIF{IBSHIFT) && defined(B9600} m->tio.c_cflag |= B9600 << IBSHIFT;
- X/* IF{CLOCAL} m->tio.c_cflag |= CLOCAL; */
- X
- XIF{ECHOCTL} m->tio.c_lflag |= ECHOCTL;
- XIF{ECHOKE} m->tio.c_lflag |= ECHOKE;
- X
- X if (!ttyflag)
- X {
- XIF{ISIG} m->tio.c_lflag |= ISIG;
- XIF{ICANON} m->tio.c_lflag |= ICANON;
- XIF{ECHO} m->tio.c_lflag |= ECHO;
- X }
- XIF{ECHOE} m->tio.c_lflag |= ECHOE;
- XIF{ECHOK} m->tio.c_lflag |= ECHOK;
- XIF{IEXTEN} m->tio.c_lflag |= IEXTEN;
- X
- XIF{VINTR} m->tio.c_cc[VINTR] = Ctrl('C');
- XIF{VQUIT} m->tio.c_cc[VQUIT] = Ctrl('\\');
- XIF{VERASE} m->tio.c_cc[VERASE] = 0x7f; /* DEL */
- XIF{VKILL} m->tio.c_cc[VKILL] = Ctrl('H');
- XIF{VEOF} m->tio.c_cc[VEOF] = Ctrl('D');
- XIF{VEOL} m->tio.c_cc[VEOL] = 0000;
- XIF{VEOL2} m->tio.c_cc[VEOL2] = 0000;
- XIF{VSWTCH} m->tio.c_cc[VSWTCH] = 0000;
- XIF{VSTART} m->tio.c_cc[VSTART] = Ctrl('Q');
- XIF{VSTOP} m->tio.c_cc[VSTOP] = Ctrl('S');
- XIF{VSUSP} m->tio.c_cc[VSUSP] = Ctrl('Z');
- XIF{VDSUSP} m->tio.c_cc[VDSUSP] = Ctrl('Y');
- XIF{VREPRINT} m->tio.c_cc[VREPRINT] = Ctrl('R');
- XIF{VDISCARD} m->tio.c_cc[VDISCARD] = Ctrl('O');
- XIF{VWERASE} m->tio.c_cc[VWERASE] = Ctrl('W');
- XIF{VLNEXT} m->tio.c_cc[VLNEXT] = Ctrl('V');
- XIF{VSTATUS} m->tio.c_cc[VSTATUS] = Ctrl('T');
- X
- X# ifdef hpux
- X m->m_ltchars.t_suspc = Ctrl('Z');
- X m->m_ltchars.t_dsuspc = Ctrl('Y');
- X m->m_ltchars.t_rprntc = Ctrl('R');
- X m->m_ltchars.t_flushc = Ctrl('O');
- X m->m_ltchars.t_werasc = Ctrl('W');
- X m->m_ltchars.t_lnextc = Ctrl('V');
- X# endif /* hpux */
- X
- X#else /* POSIX */
- X
- X# ifdef TERMIO
- X debug1("InitTTY: nonPOSIX, struct termio a la Motorola SYSV68 (%d)\n", ttyflag);
- X /* struct termio tio
- X * defaults, as seen on Mototola SYSV68:
- X * input: 7bit, CR->NL, ^S/^Q flow control
- X * output: POSTprocessing: NL->NL-CR, Tabs to spaces
- X * control: 9600baud, 8bit CSIZE, enable input
- X * local: enable signals, erase/kill processing, echo on.
- X */
- XIF{ISTRIP} m->tio.c_iflag |= ISTRIP;
- XIF{IXON} m->tio.c_iflag |= IXON;
- X
- XIF{OPOST} m->tio.c_oflag |= OPOST;
- X
- X if (!ttyflag) /* may not even be good for ptys.. */
- X {
- XIF{ICRNL} m->tio.c_iflag |= ICRNL;
- XIF{ONLCR} m->tio.c_oflag |= ONLCR;
- XIF{TAB3} m->tio.c_oflag |= TAB3;
- X }
- X
- XIF{B9600} m->tio.c_cflag = B9600;
- XIF{CS8} m->tio.c_cflag |= CS8;
- XIF{CREAD} m->tio.c_cflag |= CREAD;
- X
- X if (!ttyflag)
- X {
- XIF{ISIG} m->tio.c_lflag |= ISIG;
- XIF{ICANON} m->tio.c_lflag |= ICANON;
- XIF{ECHO} m->tio.c_lflag |= ECHO;
- X }
- XIF{ECHOE} m->tio.c_lflag |= ECHOE;
- XIF{ECHOK} m->tio.c_lflag |= ECHOK;
- X
- XIF{VINTR} m->tio.c_cc[VINTR] = Ctrl('C');
- XIF{VQUIT} m->tio.c_cc[VQUIT] = Ctrl('\\');
- XIF{VERASE} m->tio.c_cc[VERASE] = 0177; /* DEL */
- XIF{VKILL} m->tio.c_cc[VKILL] = Ctrl('H');
- XIF{VEOF} m->tio.c_cc[VEOF] = Ctrl('D');
- XIF{VEOL} m->tio.c_cc[VEOL] = 0377;
- XIF{VEOL2} m->tio.c_cc[VEOL2] = 0377;
- XIF{VSWTCH} m->tio.c_cc[VSWTCH] = 0000;
- X# else /* TERMIO */
- X debug1("InitTTY: BSD: defaults a la SunOS 4.1.3 (%d)\n", ttyflag);
- X m->m_ttyb.sg_ispeed = B9600;
- X m->m_ttyb.sg_ospeed = B9600;
- X m->m_ttyb.sg_erase = 0177; /*DEL */
- X m->m_ttyb.sg_kill = Ctrl('H');
- X if (!ttyflag)
- X m->m_ttyb.sg_flags = CRMOD | ECHO
- XIF{ANYP} | ANYP
- X ;
- X else
- X m->m_ttyb.sg_flags = CBREAK
- XIF{ANYP} | ANYP
- X ;
- X
- X m->m_tchars.t_intrc = Ctrl('C');
- X m->m_tchars.t_quitc = Ctrl('\\');
- X m->m_tchars.t_startc = Ctrl('Q');
- X m->m_tchars.t_stopc = Ctrl('S');
- X m->m_tchars.t_eofc = Ctrl('D');
- X m->m_tchars.t_brkc = -1;
- X
- X m->m_ltchars.t_suspc = Ctrl('Z');
- X m->m_ltchars.t_dsuspc = Ctrl('Y');
- X m->m_ltchars.t_rprntc = Ctrl('R');
- X m->m_ltchars.t_flushc = Ctrl('O');
- X m->m_ltchars.t_werasc = Ctrl('W');
- X m->m_ltchars.t_lnextc = Ctrl('V');
- X
- XIF{NTTYDISC} m->m_ldisc = NTTYDISC;
- X
- X m->m_lmode = 0
- XIF{LDECCTQ} | LDECCTQ
- XIF{LCTLECH} | LCTLECH
- XIF{LPASS8} | LPASS8
- XIF{LCRTKIL} | LCRTKIL
- XIF{LCRTERA} | LCRTERA
- XIF{LCRTBS} | LCRTBS
- X;
- X# endif /* TERMIO */
- X#endif /* POSIX */
- X}
- X
- Xvoid
- XSetTTY(fd, mp)
- Xint fd;
- Xstruct mode *mp;
- X{
- X errno = 0;
- X#ifdef POSIX
- X tcsetattr(fd, TCSADRAIN, &mp->tio);
- X# ifdef hpux
- X ioctl(fd, TIOCSLTC, &mp->m_ltchars);
- X# endif
- X#else
- X# ifdef TERMIO
- X ioctl(fd, TCSETAW, &mp->tio);
- X# else
- X /* ioctl(fd, TIOCSETP, &mp->m_ttyb); */
- X ioctl(fd, TIOCSETC, &mp->m_tchars);
- X ioctl(fd, TIOCLSET, &mp->m_lmode);
- X ioctl(fd, TIOCSETD, &mp->m_ldisc);
- X ioctl(fd, TIOCSETP, &mp->m_ttyb);
- X ioctl(fd, TIOCSLTC, &mp->m_ltchars); /* moved here for apollo. jw */
- X# endif
- X#endif
- X if (errno)
- X Msg(errno, "SetTTY (fd %d): ioctl failed", fd);
- X}
- X
- Xvoid
- XGetTTY(fd, mp)
- Xint fd;
- Xstruct mode *mp;
- X{
- X errno = 0;
- X#ifdef POSIX
- X tcgetattr(fd, &mp->tio);
- X# ifdef hpux
- X ioctl(fd, TIOCGLTC, &mp->m_ltchars);
- X# endif
- X#else
- X# ifdef TERMIO
- X ioctl(fd, TCGETA, &mp->tio);
- X# else
- X ioctl(fd, TIOCGETP, &mp->m_ttyb);
- X ioctl(fd, TIOCGETC, &mp->m_tchars);
- X ioctl(fd, TIOCGLTC, &mp->m_ltchars);
- X ioctl(fd, TIOCLGET, &mp->m_lmode);
- X ioctl(fd, TIOCGETD, &mp->m_ldisc);
- X# endif
- X#endif
- X if (errno)
- X Msg(errno, "GetTTY (fd %d): ioctl failed", fd);
- X}
- X
- Xvoid
- XSetMode(op, np)
- Xstruct mode *op, *np;
- X{
- X *np = *op;
- X
- X#if defined(TERMIO) || defined(POSIX)
- X np->tio.c_iflag &= ~ICRNL;
- X# ifdef ONLCR
- X np->tio.c_oflag &= ~ONLCR;
- X# endif
- X np->tio.c_lflag &= ~(ICANON | ECHO);
- X
- X /*
- X * Unfortunately, the master process never will get SIGINT if the real
- X * terminal is different from the one on which it was originaly started
- X * (process group membership has not been restored or the new tty could not
- X * be made controlling again). In my solution, it is the attacher who
- X * receives SIGINT (because it is always correctly associated with the real
- X * tty) and forwards it to the master [kill(MasterPid, SIGINT)].
- X * Marc Boucher (marc@CAM.ORG)
- X */
- X if (iflag)
- X np->tio.c_lflag |= ISIG;
- X else
- X np->tio.c_lflag &= ~ISIG;
- X /*
- X * careful, careful catche monkey..
- X * never set VMIN and VTIME to zero, if you want blocking io.
- X */
- X np->tio.c_cc[VMIN] = 1;
- X np->tio.c_cc[VTIME] = 0;
- XIF{VSTART} startc = op->tio.c_cc[VSTART];
- XIF{VSTOP} stopc = op->tio.c_cc[VSTOP];
- X if (iflag)
- X origintrc = intrc = op->tio.c_cc[VINTR];
- X else
- X {
- X origintrc = op->tio.c_cc[VINTR];
- X intrc = np->tio.c_cc[VINTR] = VDISABLE;
- X }
- X np->tio.c_cc[VQUIT] = VDISABLE;
- X if (d_flow == 0)
- X {
- X np->tio.c_cc[VINTR] = VDISABLE;
- XIF{VSTART} np->tio.c_cc[VSTART] = VDISABLE;
- XIF{VSTOP} np->tio.c_cc[VSTOP] = VDISABLE;
- X np->tio.c_iflag &= ~IXON;
- X }
- XIF{VDISCARD} np->tio.c_cc[VDISCARD] = VDISABLE;
- XIF{VSUSP} np->tio.c_cc[VSUSP] = VDISABLE;
- X# ifdef hpux
- X np->m_ltchars.t_suspc = VDISABLE;
- X np->m_ltchars.t_dsuspc = VDISABLE;
- X np->m_ltchars.t_rprntc = VDISABLE;
- X np->m_ltchars.t_flushc = VDISABLE;
- X np->m_ltchars.t_werasc = VDISABLE;
- X np->m_ltchars.t_lnextc = VDISABLE;
- X# else /* hpux */
- XIF{VDSUSP} np->tio.c_cc[VDSUSP] = VDISABLE;
- X# endif /* hpux */
- X#else /* TERMIO || POSIX */
- X startc = op->m_tchars.t_startc;
- X stopc = op->m_tchars.t_stopc;
- X if (iflag)
- X origintrc = intrc = op->m_tchars.t_intrc;
- X else
- X {
- X origintrc = op->m_tchars.t_intrc;
- X intrc = np->m_tchars.t_intrc = -1;
- X }
- X np->m_ttyb.sg_flags &= ~(CRMOD | ECHO);
- X np->m_ttyb.sg_flags |= CBREAK;
- X np->m_tchars.t_quitc = -1;
- X if (d_flow == 0)
- X {
- X np->m_tchars.t_intrc = -1;
- X np->m_tchars.t_startc = -1;
- X np->m_tchars.t_stopc = -1;
- X }
- X np->m_ltchars.t_suspc = -1;
- X np->m_ltchars.t_dsuspc = -1;
- X np->m_ltchars.t_flushc = -1;
- X np->m_ltchars.t_lnextc = -1;
- X#endif /* defined(TERMIO) || defined(POSIX) */
- X}
- X
- Xvoid
- XSetFlow(on)
- Xint on;
- X{
- X ASSERT(display);
- X if (d_flow == on)
- X return;
- X#if defined(TERMIO) || defined(POSIX)
- X if (on)
- X {
- X d_NewMode.tio.c_cc[VINTR] = intrc;
- XIF{VSTART} d_NewMode.tio.c_cc[VSTART] = startc;
- XIF{VSTOP} d_NewMode.tio.c_cc[VSTOP] = stopc;
- X d_NewMode.tio.c_iflag |= IXON;
- X }
- X else
- X {
- X d_NewMode.tio.c_cc[VINTR] = VDISABLE;
- XIF{VSTART} d_NewMode.tio.c_cc[VSTART] = VDISABLE;
- XIF{VSTOP} d_NewMode.tio.c_cc[VSTOP] = VDISABLE;
- X d_NewMode.tio.c_iflag &= ~IXON;
- X }
- X# ifdef POSIX
- X if (tcsetattr(d_userfd, TCSANOW, &d_NewMode.tio))
- X# else
- X if (ioctl(d_userfd, TCSETAW, &d_NewMode.tio) != 0)
- X# endif
- X debug1("SetFlow: ioctl errno %d\n", errno);
- X#else /* POSIX || TERMIO */
- X if (on)
- X {
- X d_NewMode.m_tchars.t_intrc = intrc;
- X d_NewMode.m_tchars.t_startc = startc;
- X d_NewMode.m_tchars.t_stopc = stopc;
- X }
- X else
- X {
- X d_NewMode.m_tchars.t_intrc = -1;
- X d_NewMode.m_tchars.t_startc = -1;
- X d_NewMode.m_tchars.t_stopc = -1;
- X }
- X if (ioctl(d_userfd, TIOCSETC, &d_NewMode.m_tchars) != 0)
- X debug1("SetFlow: ioctl errno %d\n", errno);
- X#endif /* POSIX || TERMIO */
- X d_flow = on;
- X}
- X
- X
- X/*
- X * Job control handling
- X */
- X
- X/*ARGSUSED*/
- Xvoid
- Xbrktty(fd)
- Xint fd;
- X{
- X#ifdef POSIX
- X setsid(); /* will break terminal affiliation */
- X# ifdef BSD
- X ioctl(fd, TIOCSCTTY, 0);
- X# endif /* BSD */
- X#else /* POSIX */
- X# ifdef SYSV
- X setpgrp(); /* will break terminal affiliation */
- X# else /* SYSV */
- X# ifdef BSDJOBS
- X int devtty;
- X
- X if ((devtty = open("/dev/tty", O_RDWR | O_NDELAY)) >= 0)
- X {
- X if (ioctl(devtty, TIOCNOTTY, (char *)0))
- X debug2("brktty: ioctl(devtty=%d, TIOCNOTTY, 0) = %d\n", devtty, errno);
- X close(devtty);
- X }
- X# endif /* BSDJOBS */
- X# endif /* SYSV */
- X#endif /* POSIX */
- X}
- X
- Xint
- Xfgtty(fd)
- Xint fd;
- X{
- X#ifdef BSDJOBS
- X int mypid;
- X
- X mypid = getpid();
- X
- X# if defined(BSDI) || defined(__386BSD__) || defined(__osf__)
- X setsid(); /* should be already done */
- X ioctl(fd, TIOCSCTTY, 0);
- X# endif /* BSDI || __386BSD__ */
- X
- X# ifdef POSIX
- X if (tcsetpgrp(fd, mypid))
- X {
- X debug1("fgtty: tcsetpgrp: %d\n", errno);
- X return -1;
- X }
- X# else /* POSIX */
- X if (ioctl(fd, TIOCSPGRP, &mypid) != 0)
- X debug1("fgtty: TIOSETPGRP: %d\n", errno);
- X# ifndef SYSV /* Already done in brktty():setpgrp() */
- X if (setpgrp(fd, mypid))
- X debug1("fgtty: setpgrp: %d\n", errno);
- X# endif
- X# endif /* POSIX */
- X#endif /* BSDJOBS */
- X return 0;
- X}
- X
- X
- X/*
- X * Send a break for n * 0.25 seconds. Tty must be PLAIN.
- X */
- X
- Xvoid SendBreak(wp, n, closeopen)
- Xstruct win *wp;
- Xint n, closeopen;
- X{
- X if ((wp->w_t.flags & TTY_FLAG_PLAIN) == 0)
- X return;
- X
- X debug3("break(%d, %d) fd %d\n", n, closeopen, wp->w_ptyfd);
- X#ifdef POSIX
- X (void) tcflush(wp->w_ptyfd, TCIOFLUSH);
- X#else
- X# ifdef TIOCFLUSH
- X (void) ioctl(wp->w_ptyfd, TIOCFLUSH, (char *)0);
- X# endif /* TIOCFLUSH */
- X#endif /* POSIX */
- X if (closeopen)
- X {
- X close(wp->w_ptyfd);
- X sleep((n + 3) / 4);
- X if ((wp->w_ptyfd = OpenTTY(wp->w_tty)) < 1)
- X {
- X Msg(0, "Ouch, cannot reopen line %s, please try harder", wp->w_tty);
- X return;
- X }
- X }
- X else
- X {
- X#ifdef POSIX
- X debug("tcsendbreak\n");
- X if (tcsendbreak(wp->w_ptyfd, n) < 0)
- X {
- X Msg(errno, "cannot send BREAK");
- X return;
- X }
- X#else
- X if (!n)
- X n++;
- X# ifdef TCSBRK
- X debug("TCSBRK\n");
- X {
- X int i;
- X for (i = 0; i < n; i++)
- X if (ioctl(wp->w_ptyfd, TCSBRK, (char *)0) < 0)
- X {
- X Msg(errno, "Cannot send BREAK");
- X return;
- X }
- X }
- X# else /* TCSBRK */
- X# if defined(TIOCSBRK) && defined(TIOCCBRK)
- X debug("TIOCSBRK TIOCCBRK\n");
- X if (ioctl(wp->w_ptyfd, TIOCSBRK, (char *)0) < 0)
- X {
- X Msg(errno, "Can't send BREAK");
- X return;
- X }
- X sleep((n + 3) / 4);
- X if (ioctl(wp->w_ptyfd, TIOCCBRK, (char *)0) < 0)
- X {
- X Msg(errno, "BREAK stuck!!! -- HELP!");
- X return;
- X }
- X# else /* TIOCSBRK && TIOCCBRK */
- X Msg(0, "Break not simulated yet");
- X return;
- X# endif /* TIOCSBRK && TIOCCBRK */
- X# endif /* TCSBRK */
- X#endif /* POSIX */
- X debug(" broken\n");
- X }
- X}
- X
- X
- X/*
- X * Console grabbing
- X */
- X
- X/*ARGSUSED*/
- Xint
- XTtyGrabConsole(fd, on, rc_name)
- Xint fd, on;
- Xchar *rc_name;
- X{
- X#ifdef TIOCCONS
- X char *slave;
- X int sfd = -1, ret = 0;
- X struct display *d;
- X
- X if (!on)
- X {
- X if ((fd = OpenPTY(&slave)) < 0)
- X {
- X Msg(errno, "%s: could not open detach pty master", rc_name);
- X return -1;
- X }
- X if ((sfd = open(slave, O_RDWR)) < 0)
- X {
- X Msg(errno, "%s: could not open detach pty slave", rc_name);
- X close(fd);
- X return -1;
- X }
- X }
- X else
- X {
- X if (displays == 0)
- X {
- X Msg(0, "I need a display");
- X return -1;
- X }
- X for (d = displays; d; d = d->_d_next)
- X if (strcmp(d->_d_usertty, "/dev/console") == 0)
- X break;
- X if (d)
- X {
- X Msg(0, "too dangerous - screen is running on /dev/console");
- X return -1;
- X }
- X }
- X if (UserContext() == 1)
- X UserReturn(ioctl(fd, TIOCCONS, &on));
- X ret = UserStatus();
- X if (ret)
- X Msg(errno, "%s: ioctl TIOCCONS failed", rc_name);
- X if (!on)
- X {
- X close(sfd);
- X close(fd);
- X }
- X return ret;
- X#else /* TIOCCONS */
- X Msg(0, "%s: no TIOCCONS on this machine", rc_name);
- X return -1;
- X#endif /* TIOCCONS */
- X}
- X
- X
- X/*
- X * Write out the mode struct in a readable form
- X */
- X
- X#ifdef DEBUG
- Xvoid
- XDebugTTY(m)
- Xstruct mode *m;
- X{
- X int i;
- X
- X#ifdef POSIX
- X debug("struct termios tio:\n");
- X debug1("c_iflag = %#x\n", m->tio.c_iflag);
- X debug1("c_oflag = %#x\n", m->tio.c_oflag);
- X debug1("c_cflag = %#x\n", m->tio.c_cflag);
- X debug1("c_lflag = %#x\n", m->tio.c_lflag);
- X for (i = 0; i < NCCS; i++)
- X {
- X debug2("c_cc[%d] = %#x\n", i, m->tio.c_cc[i]);
- X }
- X# ifdef hpux
- X debug1("suspc = %#02x\n", m->m_ltchars.t_suspc);
- X debug1("dsuspc = %#02x\n", m->m_ltchars.t_dsuspc);
- X debug1("rprntc = %#02x\n", m->m_ltchars.t_rprntc);
- X debug1("flushc = %#02x\n", m->m_ltchars.t_flushc);
- X debug1("werasc = %#02x\n", m->m_ltchars.t_werasc);
- X debug1("lnextc = %#02x\n", m->m_ltchars.t_lnextc);
- X# endif /* hpux */
- X#else /* POSIX */
- X# ifdef TERMIO
- X debug("struct termio tio:\n");
- X debug1("c_iflag = %04o\n", m->tio.c_iflag);
- X debug1("c_oflag = %04o\n", m->tio.c_oflag);
- X debug1("c_cflag = %04o\n", m->tio.c_cflag);
- X debug1("c_lflag = %04o\n", m->tio.c_lflag);
- X for (i = 0; i < NCC; i++)
- X {
- X debug2("c_cc[%d] = %04o\n", i, m->tio.c_cc[i]);
- X }
- X# else /* TERMIO */
- X debug1("sg_ispeed = %d\n", m->m_ttyb.sg_ispeed);
- X debug1("sg_ospeed = %d\n", m->m_ttyb.sg_ospeed);
- X debug1("sg_erase = %#02x\n", m->m_ttyb.sg_erase);
- X debug1("sg_kill = %#02x\n", m->m_ttyb.sg_kill);
- X debug1("sg_flags = %#04x\n", (unsigned short)m->m_ttyb.sg_flags);
- X debug1("intrc = %#02x\n", m->m_tchars.t_intrc);
- X debug1("quitc = %#02x\n", m->m_tchars.t_quitc);
- X debug1("startc = %#02x\n", m->m_tchars.t_startc);
- X debug1("stopc = %#02x\n", m->m_tchars.t_stopc);
- X debug1("eofc = %#02x\n", m->m_tchars.t_eofc);
- X debug1("brkc = %#02x\n", m->m_tchars.t_brkc);
- X debug1("suspc = %#02x\n", m->m_ltchars.t_suspc);
- X debug1("dsuspc = %#02x\n", m->m_ltchars.t_dsuspc);
- X debug1("rprntc = %#02x\n", m->m_ltchars.t_rprntc);
- X debug1("flushc = %#02x\n", m->m_ltchars.t_flushc);
- X debug1("werasc = %#02x\n", m->m_ltchars.t_werasc);
- X debug1("lnextc = %#02x\n", m->m_ltchars.t_lnextc);
- X debug1("ldisc = %d\n", m->m_ldisc);
- X debug1("lmode = %#x\n", m->m_lmode);
- X# endif /* TERMIO */
- X#endif /* POSIX */
- X}
- X#endif /* DEBUG */
- END_OF_FILE
- if test 19054 -ne `wc -c <'tty.sh'`; then
- echo shar: \"'tty.sh'\" unpacked with wrong size!
- fi
- # end of 'tty.sh'
- fi
- if test -f 'window.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'window.c'\"
- else
- echo shar: Extracting \"'window.c'\" \(20351 characters\)
- sed "s/^X//" >'window.c' <<'END_OF_FILE'
- X/* Copyright (c) 1993
- X * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
- X * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
- X * Copyright (c) 1987 Oliver Laumann
- X *
- X * This program is free software; you can redistribute it and/or modify
- X * it under the terms of the GNU General Public License as published by
- X * the Free Software Foundation; either version 2, or (at your option)
- X * any later version.
- X *
- X * This program is distributed in the hope that it will be useful,
- X * but WITHOUT ANY WARRANTY; without even the implied warranty of
- X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X * GNU General Public License for more details.
- X *
- X * You should have received a copy of the GNU General Public License
- X * along with this program (see the file COPYING); if not, write to the
- X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X *
- X ****************************************************************
- X */
- X
- X#include "rcs.h"
- XRCS_ID("$Id: window.c,v 1.9 1993/07/21 15:43:41 mlschroe Exp $ FAU")
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <signal.h>
- X#include <fcntl.h>
- X#ifndef sun
- X#include <sys/ioctl.h>
- X#endif
- X
- X#include "config.h"
- X#include "screen.h"
- X#include "extern.h"
- X
- X#ifdef SVR4 /* for solaris 2.1 */
- X# include <sys/stropts.h>
- X#endif
- X
- Xextern struct display *displays, *display;
- Xextern struct win *windows, *fore, *wtab[], *console_window;
- Xextern char *ShellArgs[];
- Xextern char screenterm[];
- Xextern char HostName[];
- Xextern int default_monitor, TtyMode;
- Xextern struct LayFuncs WinLf;
- Xextern int real_uid, real_gid;
- Xextern char Termcap[];
- Xextern char **NewEnv;
- X
- X#if defined(TIOCSWINSZ) || defined(TIOCGWINSZ)
- Xextern struct winsize glwz;
- X#endif
- X
- X
- Xstatic int OpenDevice __P((char *, int, int *, char **));
- Xstatic int ForkWindow __P((char **, char *, char *, char *, struct win *));
- Xstatic void execvpe __P((char *, char **, char **));
- X
- X
- Xchar DefaultShell[] = "/bin/sh";
- Xstatic char DefaultPath[] = ":/usr/ucb:/bin:/usr/bin";
- X
- X
- Xstruct NewWindow nwin_undef =
- X{
- X -1, (char *)0, (char **)0, (char *)0, (char *)0, -1, -1,
- X -1, -1, -1
- X};
- X
- Xstruct NewWindow nwin_default =
- X{
- X 0, 0, ShellArgs, 0, screenterm, 0, 1*FLOW_NOW,
- X LOGINDEFAULT, DEFAULTHISTHEIGHT, -1
- X};
- X
- Xstruct NewWindow nwin_options;
- X
- Xvoid
- Xnwin_compose(def, new, res)
- Xstruct NewWindow *def, *new, *res;
- X{
- X res->StartAt = new->StartAt != nwin_undef.StartAt ? new->StartAt : def->StartAt;
- X res->aka = new->aka != nwin_undef.aka ? new->aka : def->aka;
- X res->args = new->args != nwin_undef.args ? new->args : def->args;
- X res->dir = new->dir != nwin_undef.dir ? new->dir : def->dir;
- X res->term = new->term != nwin_undef.term ? new->term : def->term;
- X res->aflag = new->aflag != nwin_undef.aflag ? new->aflag : def->aflag;
- X res->flowflag = new->flowflag != nwin_undef.flowflag ? new->flowflag : def->flowflag;
- X res->lflag = new->lflag != nwin_undef.lflag ? new->lflag : def->lflag;
- X res->histheight = new->histheight != nwin_undef.histheight ? new->histheight : def->histheight;
- X res->monitor = new->monitor != nwin_undef.monitor ? new->monitor : def->monitor;
- X}
- X
- Xint
- XMakeWindow(newwin)
- Xstruct NewWindow *newwin;
- X{
- X register struct win **pp, *p;
- X register int n;
- X int f = -1;
- X struct NewWindow nwin;
- X int ttyflag;
- X char *TtyName;
- X
- X debug1("NewWindow: StartAt %d\n", newwin->StartAt);
- X debug1("NewWindow: aka %s\n", newwin->aka?newwin->aka:"NULL");
- X debug1("NewWindow: dir %s\n", newwin->dir?newwin->dir:"NULL");
- X debug1("NewWindow: term %s\n", newwin->term?newwin->term:"NULL");
- X nwin_compose(&nwin_default, newwin, &nwin);
- X debug1("NWin: aka %s\n", nwin.aka ? nwin.aka : "NULL");
- X pp = wtab + nwin.StartAt;
- X
- X do
- X {
- X if (*pp == 0)
- X break;
- X if (++pp == wtab + MAXWIN)
- X pp = wtab;
- X }
- X while (pp != wtab + nwin.StartAt);
- X if (*pp)
- X {
- X Msg(0, "No more windows.");
- X return -1;
- X }
- X
- X#if defined(USRLIMIT) && defined(UTMPOK)
- X /*
- X * Count current number of users, if logging windows in.
- X */
- X if (nwin.lflag && CountUsers() >= USRLIMIT)
- X {
- X Msg(0, "User limit reached. Window will not be logged in.");
- X nwin.lflag = 0;
- X }
- X#endif
- X n = pp - wtab;
- X debug1("Makewin creating %d\n", n);
- X
- X if ((f = OpenDevice(nwin.args[0], nwin.lflag, &ttyflag, &TtyName)) < 0)
- X return -1;
- X
- X if ((p = (struct win *) malloc(sizeof(struct win))) == 0)
- X {
- X close(f);
- X Msg(0, strnomem);
- X return -1;
- X }
- X bzero((char *) p, (int) sizeof(struct win));
- X#ifdef MULTIUSER
- X if (NewWindowAcl(p))
- X {
- X free(p);
- X close(f);
- X Msg(0, strnomem);
- X return -1;
- X }
- X#endif
- X p->w_wlock = WLOCK_AUTO;
- X p->w_dupto = -1;
- X p->w_winlay.l_next = 0;
- X p->w_winlay.l_layfn = &WinLf;
- X p->w_winlay.l_data = (char *)p;
- X p->w_lay = &p->w_winlay;
- X p->w_display = display;
- X if (display)
- X p->w_wlockuser = d_user;
- X p->w_number = n;
- X p->w_ptyfd = f;
- X p->w_aflag = nwin.aflag;
- X p->w_flow = nwin.flowflag | ((nwin.flowflag & FLOW_AUTOFLAG) ? (FLOW_AUTO|FLOW_NOW) : FLOW_AUTO);
- X if (!nwin.aka)
- X nwin.aka = Filename(nwin.args[0]);
- X strncpy(p->w_akabuf, nwin.aka, MAXSTR - 1);
- X if ((nwin.aka = rindex(p->w_akabuf, '|')) != NULL)
- X {
- X p->w_autoaka = 0;
- X *nwin.aka++ = 0;
- X p->w_aka = nwin.aka;
- X p->w_akachange = nwin.aka + strlen(nwin.aka);
- X }
- X else
- X p->w_aka = p->w_akachange = p->w_akabuf;
- X if ((p->w_monitor = nwin.monitor) == -1)
- X p->w_monitor = default_monitor;
- X p->w_norefresh = 0;
- X strncpy(p->w_tty, TtyName, MAXSTR - 1);
- X
- X if (ChangeWindowSize(p, display ? d_defwidth : 80, display ? d_defheight : 24))
- X {
- X FreeWindow(p);
- X return -1;
- X }
- X#ifdef COPY_PASTE
- X ChangeScrollback(p, nwin.histheight, p->w_width);
- X#endif
- X ResetWindow(p); /* sets p->w_wrap */
- X
- X if (ttyflag == TTY_FLAG_PLAIN)
- X {
- X p->w_t.flags |= TTY_FLAG_PLAIN;
- X p->w_pid = 0;
- X }
- X else
- X {
- X debug("forking...\n");
- X#ifdef PSEUDOS
- X p->w_pwin = NULL;
- X#endif
- X p->w_pid = ForkWindow(nwin.args, nwin.dir, nwin.term, TtyName, p);
- X if (p->w_pid < 0)
- X {
- X FreeWindow(p);
- X return -1;
- X }
- X }
- X /*
- X * Place the newly created window at the head of the most-recently-used list.
- X */
- X if (display && d_fore)
- X d_other = d_fore;
- X *pp = p;
- X p->w_next = windows;
- X windows = p;
- X#ifdef UTMPOK
- X debug1("MakeWindow will %slog in.\n", nwin.lflag?"":"not ");
- X if (nwin.lflag == 1)
- X {
- X if (display)
- X SetUtmp(p);
- X else
- X p->w_slot = (slot_t) 0;
- X }
- X else
- X p->w_slot = (slot_t) -1;
- X#endif
- X SetForeWindow(p);
- X Activate(p->w_norefresh);
- X return n;
- X}
- X
- Xvoid
- XFreeWindow(wp)
- Xstruct win *wp;
- X{
- X struct display *d;
- X
- X#ifdef PSEUDOS
- X if (wp->w_pwin)
- X FreePseudowin(wp);
- X#endif
- X#ifdef UTMPOK
- X RemoveUtmp(wp);
- X#endif
- X (void) chmod(wp->w_tty, 0666);
- X (void) chown(wp->w_tty, 0, 0);
- X close(wp->w_ptyfd);
- X if (wp == console_window)
- X console_window = 0;
- X if (wp->w_logfp != NULL)
- X fclose(wp->w_logfp);
- X ChangeWindowSize(wp, 0, 0);
- X for (d = displays; d; d = d->_d_next)
- X if (d->_d_other == wp)
- X d->_d_other = 0;
- X free(wp);
- X}
- X
- Xstatic int
- XOpenDevice(arg, lflag, typep, namep)
- Xchar *arg;
- Xint lflag;
- Xint *typep;
- Xchar **namep;
- X{
- X struct stat st;
- X int f;
- X
- X if ((stat(arg, &st)) == 0 && (st.st_mode & S_IFCHR))
- X {
- X if (access(arg, R_OK | W_OK) == -1)
- X {
- X Msg(errno, "Cannot access line '%s' for R/W", arg);
- X return -1;
- X }
- X debug("OpenDevice: OpenTTY\n");
- X if ((f = OpenTTY(arg)) < 0)
- X return -1;
- X *typep = TTY_FLAG_PLAIN;
- X *namep = arg;
- X }
- X else
- X {
- X *typep = 0; /* for now we hope it is a program */
- X f = OpenPTY(namep);
- X if (f == -1)
- X {
- X Msg(0, "No more PTYs.");
- X return -1;
- X }
- X#ifdef TIOCPKT
- X {
- X int flag = 1;
- X
- X if (ioctl(f, TIOCPKT, &flag))
- X {
- X Msg(errno, "TIOCPKT ioctl");
- X close(f);
- X return -1;
- X }
- X }
- X#endif /* TIOCPKT */
- X }
- X (void) fcntl(f, F_SETFL, FNDELAY);
- X#ifdef PTYGROUP
- X (void) chown(*namep, real_uid, PTYGROUP);
- X#else
- X (void) chown(*namep, real_uid, real_gid);
- X#endif
- X#ifdef UTMPOK
- X (void) chmod(*namep, lflag ? TtyMode : (TtyMode & ~022));
- X#else
- X (void) chmod(*namep, TtyMode);
- X#endif
- X return f;
- X}
- X
- X/*
- X * Fields w_width, w_height, aflag, number (and w_tty)
- X * are read from struct win *win. No fields written.
- X * If pwin is nonzero, filedescriptors are distributed
- X * between win->w_tty and open(ttyn)
- X *
- X */
- Xstatic int
- XForkWindow(args, dir, term, ttyn, win)
- Xchar **args, *dir, *term, *ttyn;
- Xstruct win *win;
- X{
- X int pid;
- X char tebuf[25];
- X char ebuf[10];
- X char shellbuf[7 + MAXPATHLEN];
- X char *proc;
- X#ifndef TIOCSWINSZ
- X char libuf[20], cobuf[20];
- X#endif
- X int newfd;
- X int w = win->w_width;
- X int h = win->w_height;
- X#ifdef PSEUDOS
- X int i, pat, wfdused;
- X struct pseudowin *pwin = win->w_pwin;
- X#endif
- X
- X switch (pid = fork())
- X {
- X case -1:
- X Msg(errno, "fork");
- X return -1;
- X case 0:
- X signal(SIGHUP, SIG_DFL);
- X signal(SIGINT, SIG_DFL);
- X signal(SIGQUIT, SIG_DFL);
- X signal(SIGTERM, SIG_DFL);
- X#ifdef BSDJOBS
- X signal(SIGTTIN, SIG_DFL);
- X signal(SIGTTOU, SIG_DFL);
- X#endif
- X if (setuid(real_uid) || setgid(real_gid))
- X {
- X SendErrorMsg("Setuid/gid: %s", sys_errlist[errno]);
- X eexit(1);
- X }
- X if (dir && *dir && chdir(dir) == -1)
- X {
- X SendErrorMsg("Cannot chdir to %s: %s", dir, sys_errlist[errno]);
- X eexit(1);
- X }
- X
- X if (display)
- X {
- X brktty(d_userfd);
- X freetty();
- X }
- X else
- X brktty(-1);
- X#ifdef DEBUG
- X if (dfp != stderr)
- X fclose(dfp);
- X#endif
- X closeallfiles(win->w_ptyfd);
- X#ifdef DEBUG
- X if ((dfp = fopen("/tmp/debug/screen.child", "a")) == 0)
- X dfp = stderr;
- X else
- X (void) chmod("/tmp/debug/screen.child", 0666);
- X debug1("=== ForkWindow: pid %d\n", getpid());
- X#endif
- X /* Close the three /dev/null descriptors */
- X close(0);
- X close(1);
- X close(2);
- X newfd = -1;
- X /*
- X * distribute filedescriptors between the ttys
- X */
- X#ifdef PSEUDOS
- X pat = pwin ? pwin->fdpat :
- X ((F_PFRONT<<(F_PSHIFT*2)) | (F_PFRONT<<F_PSHIFT) | F_PFRONT);
- X wfdused = 0;
- X for(i = 0; i < 3; i++)
- X {
- X if (pat & F_PFRONT << F_PSHIFT * i)
- X {
- X if (newfd < 0)
- X {
- X if ((newfd = open(ttyn, O_RDWR)) < 0)
- X {
- X SendErrorMsg("Cannot open %s: %s",
- X ttyn, sys_errlist[errno]);
- X eexit(1);
- X }
- X }
- X else
- X dup(newfd);
- X }
- X else
- X {
- X dup(win->w_ptyfd);
- X wfdused = 1;
- X }
- X }
- X if (wfdused)
- X {
- X /*
- X * the pseudo window process should not be surprised with a
- X * nonblocking filedescriptor. Poor Backend!
- X */
- X debug1("Clearing NDELAY on window-fd(%d)\n", win->w_ptyfd);
- X if (fcntl(win->w_ptyfd, F_SETFL, 0))
- X SendErrorMsg("Warning: ForkWindow clear NDELAY fcntl failed, %d", errno);
- X }
- X#else /* PSEUDOS */
- X if ((newfd = open(ttyn, O_RDWR)) != 0)
- X {
- X SendErrorMsg("Cannot open %s: %s", ttyn, sys_errlist[errno]);
- X eexit(1);
- X }
- X dup(0);
- X dup(0);
- X#endif /* PSEUDOS */
- X close(win->w_ptyfd);
- X
- X if (newfd >= 0)
- X {
- X struct mode fakemode, *modep;
- X#ifdef SVR4
- X if (ioctl(newfd, I_PUSH, "ptem"))
- X {
- X SendErrorMsg("Cannot I_PUSH ptem %s %s", ttyn, sys_errlist[errno]);
- X eexit(1);
- X }
- X if (ioctl(newfd, I_PUSH, "ldterm"))
- X {
- X SendErrorMsg("Cannot I_PUSH ldterm %s %s", ttyn, sys_errlist[errno]);
- X eexit(1);
- X }
- X if (ioctl(newfd, I_PUSH, "ttcompat"))
- X {
- X SendErrorMsg("Cannot I_PUSH ttcompat %s %s", ttyn, sys_errlist[errno]);
- X eexit(1);
- X }
- X#endif
- X if (fgtty(newfd))
- X SendErrorMsg("fgtty: %s (%d)", sys_errlist[errno], errno);
- X if (display)
- X {
- X debug("ForkWindow: using display tty mode for new child.\n");
- X modep = &d_OldMode;
- X }
- X else
- X {
- X debug("No display - creating tty setting\n");
- X modep = &fakemode;
- X InitTTY(modep, 0);
- X#ifdef DEBUG
- X DebugTTY(modep);
- X#endif
- X }
- X /* We only want echo if the users input goes to the pseudo
- X * and the pseudo's stdout is not send to the window.
- X */
- X#ifdef PSEUDOS
- X if (pwin && (!(pat & F_UWP) || (pat & F_PBACK << F_PSHIFT)))
- X {
- X debug1("clearing echo on pseudywin fd (pat %x)\n", pat);
- X# if defined(POSIX) || defined(TERMIO)
- X modep->tio.c_lflag &= ~ECHO;
- X modep->tio.c_iflag &= ~ICRNL;
- X# else
- X modep->m_ttyb.sg_flags &= ~ECHO;
- X# endif
- X }
- X#endif
- X SetTTY(newfd, modep);
- X#ifdef TIOCSWINSZ
- X glwz.ws_col = w;
- X glwz.ws_row = h;
- X (void) ioctl(newfd, TIOCSWINSZ, &glwz);
- X#endif
- X }
- X#ifndef TIOCSWINSZ
- X sprintf(libuf, "LINES=%d", h);
- X sprintf(cobuf, "COLUMNS=%d", w);
- X NewEnv[5] = libuf;
- X NewEnv[6] = cobuf;
- X#endif
- X if (win->w_aflag)
- X NewEnv[2] = MakeTermcap(1);
- X else
- X NewEnv[2] = Termcap;
- X proc = *args;
- X if (*proc == '-')
- X proc++;
- X strcpy(shellbuf, "SHELL=");
- X strncpy(shellbuf + 6, proc, MAXPATHLEN);
- X shellbuf[MAXPATHLEN + 6] = 0;
- X NewEnv[4] = shellbuf;
- X if (term && *term && strcmp(screenterm, term) &&
- X (strlen(term) < 20))
- X {
- X char *s1, *s2, tl;
- X
- X sprintf(tebuf, "TERM=%s", term);
- X debug2("Makewindow %d with %s\n", win->w_number, tebuf);
- X tl = strlen(term);
- X NewEnv[1] = tebuf;
- X if ((s1 = index(Termcap, '|')))
- X {
- X if ((s2 = index(++s1, '|')))
- X {
- X if (strlen(Termcap) - (s2 - s1) + tl < 1024)
- X {
- X bcopy(s2, s1 + tl, strlen(s2) + 1);
- X bcopy(term, s1, tl);
- X }
- X }
- X }
- X }
- X sprintf(ebuf, "WINDOW=%d", win->w_number);
- X NewEnv[3] = ebuf;
- X
- X debug1("calling execvpe %s\n", proc);
- X execvpe(proc, args, NewEnv);
- X debug1("exec error: %d\n", errno);
- X SendErrorMsg("Cannot exec %s: %s", proc, sys_errlist[errno]);
- X exit(1);
- X default:
- X return pid;
- X } /* end fork switch */
- X /* NOTREACHED */
- X}
- X
- Xstatic void
- Xexecvpe(prog, args, env)
- Xchar *prog, **args, **env;
- X{
- X register char *path = NULL, *p;
- X char buf[1024];
- X char *shargs[MAXARGS + 1];
- X register int i, eaccess = 0;
- X
- X for (i = 0; i < 3; i++)
- X if (!strncmp("../" + i, prog, 3 - i))
- X path = "";
- X if (!path && !(path = getenv("PATH")))
- X path = DefaultPath;
- X do
- X {
- X p = buf;
- X while (*path && *path != ':')
- X *p++ = *path++;
- X if (p > buf)
- X *p++ = '/';
- X strcpy(p, prog);
- X execve(buf, args, env);
- X switch (errno)
- X {
- X case ENOEXEC:
- X shargs[0] = DefaultShell;
- X shargs[1] = buf;
- X for (i = 1; (shargs[i + 1] = args[i]) != NULL; ++i)
- X ;
- X execve(DefaultShell, shargs, env);
- X return;
- X case EACCES:
- X eaccess = 1;
- X break;
- X case ENOMEM:
- X case E2BIG:
- X case ETXTBSY:
- X return;
- X }
- X } while (*path++);
- X if (eaccess)
- X errno = EACCES;
- X}
- X
- X#ifdef PSEUDOS
- X
- Xint
- Xwinexec(av)
- Xchar **av;
- X{
- X char **pp;
- X char *p, *s, *t;
- X int i, r = 0, l = 0;
- X struct win *w;
- X extern struct display *display;
- X extern struct win *windows;
- X struct pseudowin *pwin;
- X
- X if ((w = display ? fore : windows) == NULL)
- X return -1;
- X if (!*av || w->w_pwin)
- X {
- X Msg(0, "Filter running: %s", w->w_pwin ? w->w_pwin->p_cmd : "(none)");
- X return -1;
- X }
- X if (!(pwin = (struct pseudowin *)malloc(sizeof(struct pseudowin))))
- X {
- X Msg(0, strnomem);
- X return -1;
- X }
- X bzero((char *)pwin, (int)sizeof(*pwin));
- X
- X /* allow ^a:!!./ttytest as a short form for ^a:exec !.. ./ttytest */
- X for (s = *av; *s == ' '; s++)
- X ;
- X for (p = s; *p == ':' || *p == '.' || *p == '!'; p++)
- X ;
- X if (*p != '|')
- X while (*p && p > s && p[-1] == '.')
- X p--;
- X if (*p == '|')
- X {
- X l = F_UWP;
- X p++;
- X }
- X if (*p)
- X av[0] = p;
- X else
- X av++;
- X
- X t = pwin->p_cmd;
- X for (i = 0; i < 3; i++)
- X {
- X *t = (s < p) ? *s++ : '.';
- X switch (*t++)
- X {
- X case '.':
- X case '|':
- X l |= F_PFRONT << (i * F_PSHIFT);
- X break;
- X case '!':
- X l |= F_PBACK << (i * F_PSHIFT);
- X break;
- X case ':':
- X l |= F_PBOTH << (i * F_PSHIFT);
- X break;
- X }
- X }
- X
- X if (l & F_UWP)
- X {
- X *t++ = '|';
- X if ((l & F_PMASK) == F_PFRONT)
- X {
- X *pwin->p_cmd = '!';
- X l ^= F_PFRONT | F_PBACK;
- X }
- X }
- X if (!(l & F_PBACK))
- X l |= F_UWP;
- X *t++ = ' ';
- X pwin->fdpat = l;
- X debug1("winexec: '%#x'\n", pwin->fdpat);
- X
- X l = MAXSTR - 4;
- X for (pp = av; *pp; pp++)
- X {
- X p = *pp;
- X while (*p && l-- > 0)
- X *t++ = *p++;
- X if (l <= 0)
- X break;
- X *t++ = ' ';
- X }
- X *--t = '\0';
- X debug1("%s\n", pwin->p_cmd);
- X
- X if ((pwin->p_ptyfd = OpenDevice(av[0], 0, &l, &t)) < 0)
- X {
- X free(pwin);
- X return -1;
- X }
- X strncpy(pwin->p_tty, t, MAXSTR - 1);
- X w->w_pwin = pwin;
- X if (l == TTY_FLAG_PLAIN)
- X {
- X FreePseudowin(w);
- X Msg(0, "Cannot handle a TTY as a pseudo win.");
- X return -1;
- X }
- X#ifdef TIOCPKT
- X {
- X int flag = 0;
- X
- X if (ioctl(pwin->p_ptyfd, TIOCPKT, &flag))
- X {
- X Msg(errno, "TIOCPKT ioctl");
- X FreePseudowin(w);
- X return -1;
- X }
- X }
- X#endif /* TIOCPKT */
- X pwin->p_pid = ForkWindow(av, NULL, NULL, t, w);
- X if ((r = pwin->p_pid) < 0)
- X FreePseudowin(w);
- X return r;
- X}
- X
- Xvoid
- XFreePseudowin(w)
- Xstruct win *w;
- X{
- X struct pseudowin *pwin = w->w_pwin;
- X
- X ASSERT(pwin);
- X if (fcntl(w->w_ptyfd, F_SETFL, FNDELAY))
- X Msg(errno, "Warning: FreePseudowin: NDELAY fcntl failed");
- X (void) chmod(pwin->p_tty, 0666);
- X (void) chown(pwin->p_tty, 0, 0);
- X if (pwin->p_ptyfd >= 0)
- X close(pwin->p_ptyfd);
- X free(pwin);
- X w->w_pwin = NULL;
- X}
- X
- X#endif /* PSEUDOS */
- X
- X
- X#ifdef MULTI
- X
- Xstatic void CloneTermcap __P((struct display *));
- Xextern char **environ;
- X
- Xint
- Xexecclone(av)
- Xchar **av;
- X{
- X int f, sf;
- X char specialbuf[6];
- X struct display *old = display;
- X char **avp, *namep;
- X
- X sf = OpenPTY(&namep);
- X if (sf == -1)
- X {
- X Msg(0, "No more PTYs.");
- X return -1;
- X }
- X f = open(namep, O_RDWR);
- X if (f == -1)
- X {
- X close(sf);
- X Msg(errno, "Cannot open slave");
- X return -1;
- X }
- X brktty(f);
- X signal(SIGHUP, SIG_IGN); /* No hangups, please */
- X if (MakeDisplay(d_username, namep, d_termname, f, -1, &d_OldMode) == 0)
- X {
- X display = old;
- X Msg(0, "Could not make display.");
- X close(f);
- X return -1;
- X }
- X SetMode(&d_OldMode, &d_NewMode);
- X SetTTY(f, &d_NewMode);
- X switch (fork())
- X {
- X case -1:
- X FreeDisplay();
- X display = old;
- X Msg(errno, "fork");
- X return -1;
- X case 0:
- X setuid(real_uid);
- X setgid(real_gid);
- X d_usertty[0] = 0;
- X closeallfiles(sf);
- X close(1);
- X dup(sf);
- X close(sf);
- X#ifdef DEBUG
- X if ((dfp = fopen("/tmp/debug/screen.child", "a")) == 0)
- X dfp = stderr;
- X else
- X (void) chmod("/tmp/debug/screen.child", 0666);
- X debug1("=== Clone: pid %d\n", getpid());
- X#endif
- X for (avp = av; *avp; avp++)
- X {
- X if (strcmp(*avp, "%p") == 0)
- X *avp = namep;
- X if (strcmp(*avp, "%X") == 0)
- X *avp = specialbuf;
- X }
- X sprintf(specialbuf, "-SXX1");
- X namep += strlen(namep);
- X specialbuf[3] = *--namep;
- X specialbuf[2] = *--namep;
- X#ifdef DEBUG
- X debug("Calling:");
- X for (avp = av; *avp; avp++)
- X debug1(" %s", *avp);
- X debug("\n");
- X#endif
- X execvpe(*av, av, environ);
- X SendErrorMsg("Cannot exec %s: %s", *av, sys_errlist[errno]);
- X exit(1);
- X default:
- X break;
- X }
- X close(sf);
- X CloneTermcap(old);
- X InitTerm(0);
- X Activate(0);
- X if (d_fore == 0)
- X ShowWindows();
- X return 0;
- X}
- X
- Xextern struct term term[]; /* terminal capabilities */
- X
- Xstatic void
- XCloneTermcap(old)
- Xstruct display *old;
- X{
- X char *tp;
- X int i;
- X
- X tp = d_tentry;
- X for (i = 0; i < T_N; i++)
- X {
- X switch(term[i].type)
- X {
- X case T_FLG:
- X d_tcs[i].flg = old->_d_tcs[i].flg;
- X break;
- X case T_NUM:
- X d_tcs[i].num = old->_d_tcs[i].num;
- X break;
- X case T_STR:
- X d_tcs[i].str = old->_d_tcs[i].str;
- X if (d_tcs[i].str)
- X {
- X strcpy(tp, d_tcs[i].str);
- X d_tcs[i].str = tp;
- X tp += strlen(tp) + 1;
- X }
- X break;
- X default:
- X Panic(0, "Illegal tc type in entry #%d", i);
- X }
- X }
- X CheckScreenSize(0);
- X for (i = 0; i < NATTR; i++)
- X d_attrtab[i] = old->_d_attrtab[i];
- X for (i = 0; i < 256; i++)
- X d_c0_tab[i] = old->_d_c0_tab[i];
- X d_UPcost = old->_d_UPcost;
- X d_DOcost = old->_d_DOcost;
- X d_NLcost = old->_d_NLcost;
- X d_LEcost = old->_d_LEcost;
- X d_NDcost = old->_d_NDcost;
- X d_CRcost = old->_d_CRcost;
- X d_IMcost = old->_d_IMcost;
- X d_EIcost = old->_d_EIcost;
- X#ifdef AUTO_NUKE
- X d_auto_nuke = old->_d_auto_nuke;
- X#endif
- X d_tcinited = 1;
- X}
- X
- X#endif
- X
- END_OF_FILE
- if test 20351 -ne `wc -c <'window.c'`; then
- echo shar: \"'window.c'\" unpacked with wrong size!
- fi
- # end of 'window.c'
- fi
- echo shar: End of archive 4 \(of 10\).
- cp /dev/null ark4isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 10 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-