summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--COPYING2
l---------[-rw-r--r--]FAQ254
-rw-r--r--INSTALL6
-rw-r--r--Makefile1
-rw-r--r--Makefile.in277
-rw-r--r--NEWS152
-rw-r--r--NEWS.3.739
-rw-r--r--README6
-rw-r--r--TODO8
-rw-r--r--acls.c327
-rw-r--r--acls.h19
-rw-r--r--ansi.c2046
-rw-r--r--ansi.h2
-rw-r--r--attacher.c222
-rw-r--r--braille.c941
-rw-r--r--braille.h80
-rw-r--r--braille_tsi.c317
-rw-r--r--comm.c352
-rw-r--r--comm.h.dist313
-rw-r--r--comm.sh33
-rw-r--r--config.h.in144
-rwxr-xr-xconfigure3902
-rw-r--r--configure.in340
-rw-r--r--display.c1583
-rw-r--r--display.h117
-rw-r--r--doc/Makefile.in6
-rw-r--r--doc/README.DOTSCREEN151
l---------[-rwxr-xr-x]doc/install.sh120
-rw-r--r--doc/make.help51
-rw-r--r--doc/screen.11438
-rw-r--r--doc/screen.info294
-rw-r--r--doc/screen.info-1642
-rw-r--r--doc/screen.info-21008
-rw-r--r--doc/screen.info-31144
-rw-r--r--doc/screen.info-4816
-rw-r--r--doc/screen.info-5545
-rw-r--r--doc/screen.texinfo1002
-rw-r--r--doc/window_to_display.ps2959
-rwxr-xr-xetc/ccdefs45
-rw-r--r--etc/gr-braille.tbl260
-rw-r--r--etc/gs-braille.tbl261
-rwxr-xr-xetc/newsyntax3871
-rw-r--r--etc/screenrc18
-rw-r--r--etc/us-braille.tbl260
-rw-r--r--extern.h198
-rw-r--r--fileio.c150
-rw-r--r--help.c519
-rw-r--r--image.h27
-rw-r--r--input.c203
-rw-r--r--kmapdef.c.dist30
-rw-r--r--layer.c938
-rw-r--r--layer.h104
-rw-r--r--loadav.c82
-rw-r--r--logfile.c318
-rw-r--r--logfile.h82
-rw-r--r--mark.c498
-rw-r--r--mark.h2
-rw-r--r--misc.c257
-rw-r--r--nethack.c136
-rw-r--r--os.h71
-rw-r--r--osdef.h.in24
-rw-r--r--osdef.sh25
-rw-r--r--overlay.h68
-rw-r--r--patchlevel.h235
-rw-r--r--process.c2155
-rw-r--r--pty.c62
-rw-r--r--resize.c368
-rw-r--r--sched.c263
-rw-r--r--sched.h20
-rw-r--r--screen.c1995
-rw-r--r--screen.h94
-rw-r--r--search.c83
-rw-r--r--socket.c541
-rw-r--r--tek.patch68
-rw-r--r--teln.c562
-rw-r--r--term.c23
-rw-r--r--term.h.dist299
-rw-r--r--term.sh2
-rw-r--r--termcap.c173
-rw-r--r--terminfo/README3
-rw-r--r--terminfo/sco.mail65
-rw-r--r--terminfo/screencap4
-rw-r--r--terminfo/screeninfo.src4
-rw-r--r--tty.c.dist1333
-rw-r--r--tty.sh904
-rw-r--r--utmp.c827
-rw-r--r--window.c1381
-rw-r--r--window.h198
88 files changed, 27330 insertions, 10638 deletions
diff --git a/COPYING b/COPYING
index 13c9d42..55d2947 100644
--- a/COPYING
+++ b/COPYING
@@ -305,7 +305,7 @@ the "copyright" line and a pointer to where the full notice is found.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
- 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Also add information on how to contact you by electronic and paper mail.
diff --git a/FAQ b/FAQ
index 6c9c8af..1ad45dd 100644..120000
--- a/FAQ
+++ b/FAQ
@@ -1,253 +1 @@
- jw 21.10.93
- 05.05.94
-
- screen: frequently asked questions -- known problems -- unimplemented bugs
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
-
-Q: Why is it impossible to download a file with Kermit/sz/rz when
- screen is running? Do I need to set some special variables?
-
-A: Screen always interprets control-sequences sent by the
- applications and translates/optimizes them for the current
- terminal type. Screen always parses the user input for its
- escape character (CTRL-A). Both are basic screen features and
- cannot be switched off. Even if it were possible to switch
- screen into a completely transparent mode, you could never switch
- between windows, while kermit/sz/rz is downloading a file. You
- must wait til the end as kermit/sz/rz will not transmit your
- input during a file transfer and as kermit/sz/rz would be very
- confused if screen switched away the window containing the
- other kermit/sz/rz. Simply detach your screen session for each
- file transfer and start the transfer program only from the shell
- where you started screen.
-
-Q: I am using screen with a YYY terminal, which supports the XXX
- graphic language. I am very happy with it, except one thing: I
- cannot render graphics into screen windows.
-
-A: You are out of luck there. Screen provides a fixed set of escape
- sequences in order to make it possible to switch terminal types.
- Screen has to know exactly what the escape sequences do to the
- terminal because it must hold an image in memory. Otherwise
- screen could not restore the image if you switch to another
- window. Because of this you have to change screens escape
- sequence parser (ansi.c) to pass the XXX graphics sequences to
- the terminal. Of course the graphics will be lost if you switch
- to another window. Screen will only honour graphics sequences
- that are demanded by an overwhelming majority.
-
-Q: For some unknown reason, the fifo in /tmp/screens/S-myname is
- gone, and i can't resume my screen session. Is there a way to
- recreate the fifo?
-
-A: Screen checks the fifo/socket whenever it receives a SIGCHLD
- signal. If missing, the fifo/socket is recreated then. If screen
- is running non set-uid the user can issue a 'kill -CHLD
- screenpid' directly (it is -CHILD on some systems). Screenpid is
- the process-id of the screen process found in a 'ps -x' listing.
- But usually this won't work, as screen should be installed set-
- uid root. In this case you will not be able to send it a signal,
- but the kernel will. It does so, whenever a child of screen
- changes its state. Find the process-id (shellpid below) of the
- "least important" shell running inside screen. The try 'kill
- -STOP shellpid'. If the fifo/socket does not reappear, destroy
- the shell process. You sacrify one shell to save the rest. If
- nothing works, please do not forget to remove all processes
- running in the lost screen session.
-
-Q: When you start "screen" a page of text comes up to start you
- off. Is there a way to get rid of this text as a command line
- argument or by using a switch of some sort.
-
-A: Just put the following line in your ~/.screenrc:
- startup_message off
- Many peole ask this, although it is in the man page, too :-)
-
-Q: Start "screen emacs" and run emacs function suspend-emacs
- (ctrl-z). The window containing emacs vanishes.
-
-A: This is a known bug. Unfortunatly there is no easy fix
- because this is specified in the POSIX standard. When a new
- window is created Screen opens up a new session because the
- window has to get the pty as a controlling terminal (a
- session can only have one controlling terminal). With the
- setsid() call the process also creates a new process
- group. This process group is orphaned, because there is no
- process in the session which is not in the process
- group. Now if the process group leader (i.e. your program)
- gets a TTIN/TTOU/TSTP, POSIX states that the kernel must
- send a KILL signal to the process group because there is no
- one left to continue the process. Even if screen would
- try to restart the program, that would be after it received the
- KILL signal which cannot be caught or ignored.
-
- tromey@klab.caltech.edu (Tom Tromey): I've noticed this exact
- same problem. I put this in my .emacs file. It seems to work:
-
- ;; If running under screen, disable C-z.
- (if (and (getenv "STY") (not window-system))
- (global-unset-key "\C-z"))
-
-Q: Screen gets the terminal size wrong and messes up.
-
-A: Before you start screen: Check with 'stty -a' what the terminal
- driver thinks about rows and columns. Check the environment
- variables LINES and COLUMNS. Then from within screen check with
- the info command (CTRL-A i) what size screen thinks your terminal
- is. If correcting tty driver setting and environment variables
- does not help, look up the terminal capability definition. First
- the TERMCAP environment variable. If this is not set, look up the
- terminals name as defined in the environment variable TERM in
- /etc/termcap or in the terminfo database with untic or infocmp.
- There may be :li=...: and :co=...: or even :ll=...: entries
- (cols#... and lines#... when it's terminfo) defined incorrectly.
- Either construct your own TERMCAP environment variables with
- correct settings, use screens terminfo/termcap command in your
- .screenrc file or have the database corrected by the system
- administrator.
-
-Q: Screen messes up the terminal output when I use my favourite ap-
- plication. Setting the terminal size does not help.
-
-A: Probably you got the termcap/terminfo entries wrong. Fixing this
- is a three stage procedure. First, find out if terminfo or
- termcap is used. If your system only has /etc/termcap,
- but not /usr/lib/terminfo/... then you are using termcap.
- Easy. But if your system has both, then it depends how the appli-
- cation and how screen were linked. Beware, if your applica-
- tion runs on another host via rlogin, telnet or the like, you
- should check the terminfo/termcap databases there. If you cannot
- tell if terminfo or termcap is used (or you just want to be
- save), the do all steps in stage 3 in parallel for both
- systems (on all envolved hosts). Second: Understand the basic
- rules how screen does its terminal emulation. When screen is
- started or reattached, it relies on the TERM environment variable
- to correctly reflect the terminal type you have physically
- in front of you. And the entry should either exist in the system
- terminfo/termcap database or be specified via the TERMCAP en-
- vironment variable (if screen is using the termcap system). On
- the other end, screen understands one set of control codes. It
- relies on the application using these codes. This means applica-
- tions that run under screen must be able to adapt their con-
- trol codes to screen. The application should use the TERM vari-
- able and termcap or terminfo library to find out how to drive
- its terminal. When running under screen, the terminal is virtual
- and is only defined by the set of control codes that screen
- understands. The TERM variable is automatically set to
- "screen" and the "screen"-entries should exist in the data-
- bases. If your application uses hardcoded control codes rather
- than a database, you are on your own. Hint: The codes under-
- stood by screen are a superset of the very common definition
- named "vt100". Look at the documentation of screen. The
- codes are listed there. Third: Have the entry "screen" in-
- stalled on all hosts or make sure you can live with "vt100".
- Check the codes sent by your application, when the TERM variable
- is set to "screen". Do not try to set the TERM variable inside
- screen to anything other than "screen" or "vt100" or compati-
- ble. Thus your application can drive screen correctly. Also take
- care that a good entry is installed for your physical terminal
- that screen has to drive. Even if the entry was good enough
- for your application to drive the terminal directly, screen may
- find flaws, as it tries to use other capabilities while op-
- timizing the screen output. The screenrc commands
- "termcap" and/or "terminfo" may help to fine-tune capabilities
- without calling the supervisor to change the database.
-
-Q: I cannot configure screen. Sed does not work.
-
-A: The regular expressions used in our configure scrip are too
- complicated for GNU sed version 2.03. In this regard it is bug
- compatible with Ultrix 3.1 "sed": GNU sed version 2.03 dumps
- core with our configure script. Try an older release. E.g. from
- ftp.uni-erlangen.de:/pub/utilities/screen/sed-2.02b.tar.gz
-
-Q: When reattaching a session from a different Workstation, the
- DISPLAY environment variable should be updated. Even ``CTLR-A
- : setenv DISPLAY newhost:0'' does not work as expected.
-
-A: Under unix every process has its own environment. The environ-
- ment of the SCREEN process can be changed with the `setenv' com-
- mand. This however cannot affect the environment of the
- shells or applications already running under screen. Subsequently
- spawned processes will reflect the changes. One should be aware
- of this problem when running applications from very old shells.
- Screen is a means for keeping processes alive.
-
-Q: About once every 5 times I ran the program, rather than getting
- a "screen," I got someone elses IRC output/input.
-
-A: What probably happened is that an IRC process was left running on
- a pseudo tty in such a way that the kernel thought the tty was
- available for reallocation. You can fix this behaviour by
- applying the SunOS 4.1.x tty jumbo patch (100513-04).
-
-Q: Screen compiled on SunOS 5.3 cannot reattach a detached session.
-
-A: You are using /usr/ucb/cc, this compiler is wrong. Actually it
- links with a C-library that mis-interprets dirent. Try again
- with /opt/SUNWspro/bin/cc!
-
-Q: The "talk" command does not work when Screen is active.
-
-A: Talk and several other programs rely on entries in the Utmp-
- Database (/etc/utmp). On some systems this Database is world
- writable, on others it is not. If it is not, screen must be
- installed with the appropriate permissions (user or group s-bit)
- just like any program that uses PTYs (rlogin, xterm, ...). When
- screen cannot write to utmp, you will see messages on you display
- which do not belong to any screen window.
- When screen can update utmp, it is not guaranteed that it does as
- you expect. First this depends on the config.h file defining
- UTMPOK, LOGINDEFAULT, and perhaps CAREFULUTMP. Second it depends
- on the screenrc files (system wide and per user), if utmp entries
- are done. Third, you can control whether windows are logged in
- with screens ``login'' command.
-
-Q: Seteuid() does not work as expected in AIX. Attempting a multi-
- user-attach results in a screen-panic: "seteuid: not owner".
-
-A: This is not a screen problem. According to Kay Nettle
- (pkn@cs.utexas.edu) you need the AIX patch PTF 423674.
-
-Q: When I type cd directory (any directory or just blank) from
- within one of the windows in screen, the whole thing just freezes
- up.
-
-A: You display the current working directory in xterm's title bar,
- This may be caused by hardcoded ESC-sequences in the shell prompt
- or in an cd alias. In Xterm the coding is
- ESC ] n ; string_to_display ^G
- where n = 1, 2, 3 selects the location of the displayed string.
- Screen misinterprets this as the ansi operating system comment
- sequence:
- ESC ] osc_string
- and waits (according to ansi) for the string terminator
- ESC \
- Screen versions after 3.5.12 may provide a workaround.
-
-Q: Mesg or biff cannot be turned on or off while running screen.
-
-A: Screen failed to change the owner of the pty it uses. You need to
- install screen setuid-root. See the file INSTALL for details.
-
-Q: The cursor left key deletes the characters instead of just moving the
- cursor. A redisplay (^Al) brings everything back.
-
-A: Your terminal emulator treats the backspace as "destructive". You
- can probably change this somewhere in the setup. We can't think
- of a reason why anybody would want a destructive backspace, but
- if you really must have it, add the lines
- termcap <TERM> 'bc@:bs@'
- terminfo <TERM> 'bc@:bs@'
- to your ~/.screenrc (replace <TERM> with the terminal type your
- emulator uses).
-
-Q: I have an old SysV OS (like Motorola SysV68) and sometimes screen
- doesn't reset the attributes correctly. A redisplay (^Al) doesn't
- make things better.
-
-A: The libcurses library has a bug if attributes are cleared with
- the special ue/se capabilities. As a workaround (other than upgrading
- your system) modify 'rmul' (and 'rmso'?) in screen's terminfo entry:
- rmul=\E[m, rmso=\E[m
+doc/FAQ \ No newline at end of file
diff --git a/INSTALL b/INSTALL
index d382078..b6c4442 100644
--- a/INSTALL
+++ b/INSTALL
@@ -43,7 +43,7 @@ The path for ETCSCREENRC may also need to be adapted.
Run 'make'. Screen should compile without too many warnings :)
The creation of term.h, comm.h, tty.c or osdef.h may fail on some machines
for some odd reason. (E.g. the sed under SCO-unix is known to be
-case-insensitive and breaks term.h) If so, please mail a short description
+case-insensitive and breaks term.h.) If so, please mail a short description
of the problem to screen@uni-erlangen.de and use the files ending in .dist
as a replacement (or in case of osdef.h retry with an empty file).
You can then try 'make install' (if you dare).
@@ -89,7 +89,7 @@ The files screenrc and etc/etcscreenrc are instructive samples that
demonstrate what can/should be done from your private .screenrc and from
$ETCSCREENRC -- do not just copy them. Read them. Look through the
etcscreenrc file for system wide defaults that you like to set. e.g.
-autodetach off, startup_message off, vbell on, ...aak
+autodetach off, startup_message off, vbell on, ...
Since version 3.2.15 the screenrc file syntax changed slightly. All rc files
from previous versions should be run through the newsyntax script that comes
with this package.
@@ -107,4 +107,4 @@ database is up to date. See the README in the terminfo subdirectory.
To get an idea what the basic screen commands are, read the file README.
Request snail mail address for liquid and solid donations. :-)
-Juergen Weigert. (screen@uni-erlangen.de)
+Juergen & Michael. (screen@uni-erlangen.de)
diff --git a/Makefile b/Makefile
index 9458230..06b972a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,2 +1,3 @@
install all Makefiles and config:
+ rm -f config.cache
sh ./configure
diff --git a/Makefile.in b/Makefile.in
index f9fc599..add343d 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -9,13 +9,14 @@ VPATH = @srcdir@
# Where to install screen.
-prefix = /usr/local
-exec_prefix = $(prefix)
+prefix = @prefix@
+exec_prefix = @exec_prefix@
# don't forget to change mandir and infodir in doc/Makefile.
bindir = $(exec_prefix)/bin
VERSION = @VERSION@
+SCREEN = screen-$(VERSION)
ETCSCREENRC = `sed < config.h -n -e '/define ETCSCREENRC/s/^.*"\([^"]*\)"/\1/p'`
@@ -24,7 +25,7 @@ CFLAGS = -O
LDFLAGS =
LIBS = @LIBS@
-CPP_DEPEND=/lib/cpp -MM
+CPP_DEPEND=$(CC) -MM
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -35,33 +36,33 @@ AWK = @AWK@
### Chose some debug configuration options:
# -DDEBUG
# Turn on really heavy debug output. This is written to
-# /tmp/debug/screen.{front,back} Look at these files and quote
+# /tmp/debug/{SCREEN,screen}.<pid>. Look at these files and quote
# questionable sections when sending bug-reports to the author.
-# -DTMPTEST
-# Change the socket directory to a location that does not interfere
-# with the (suid-root) installed screen version. Use that in
-# combination with -DDEBUG
# -DDUMPSHADOW
-# With shadow-pw screen would never dump core. Use this option if you
-# still want to have a core. Use only for debugging.
+# With shadow-pw screen would never dump core. Use this option if
+# you still want to have a core. Use only for debugging.
# -DFORKDEBUG
# Swap roles of father and son when forking the SCREEN process.
+# Note: "detach" will be less powerfull, but "pow_detach" may be
+# more forcefull than usual.
# Useful only for debugging.
OPTIONS=
-#OPTIONS= -DDEBUG -DTMPTEST
+#OPTIONS= -DDEBUG
SHELL=/bin/sh
CFILES= screen.c ansi.c fileio.c mark.c misc.c resize.c socket.c \
search.c tty.c term.c window.c utmp.c loadav.c putenv.c help.c \
termcap.c input.c attacher.c pty.c process.c display.c comm.c \
- kmapdef.c acls.c
+ kmapdef.c acls.c braille.c braille_tsi.c logfile.c layer.c \
+ sched.c teln.c nethack.c
OFILES= screen.o ansi.o fileio.o mark.o misc.o resize.o socket.o \
search.o tty.o term.o window.o utmp.o loadav.o putenv.o help.o \
termcap.o input.o attacher.o pty.o process.o display.o comm.o \
- kmapdef.o acls.o
+ kmapdef.o acls.o braille.o braille_tsi.o logfile.o layer.o \
+ sched.o teln.o nethack.o
-all: screen screen.info
+all: screen
screen: $(OFILES)
$(CC) $(LDFLAGS) -o $@ $(OFILES) $(LIBS)
@@ -69,17 +70,23 @@ screen: $(OFILES)
.c.o:
$(CC) -c -I. -I$(srcdir) $(M_CFLAGS) $(DEFS) $(OPTIONS) $(CFLAGS) $<
-install_bin: screen
- $(INSTALL_PROGRAM) screen $(bindir)/screen-$(VERSION)
- -chown root $(bindir)/screen-$(VERSION) && chmod 4755 $(bindir)/screen-$(VERSION)
+install_bin: .version screen
+ -if [ -f $(bindir)/$(SCREEN) ] && [ ! -f $(bindir)/$(SCREEN).old ]; \
+ then mv $(bindir)/$(SCREEN) $(bindir)/$(SCREEN).old; fi
+ $(INSTALL_PROGRAM) screen $(bindir)/$(SCREEN)
+ -chown root $(bindir)/$(SCREEN) && chmod 4755 $(bindir)/$(SCREEN)
# This doesn't work if $(bindir)/screen is a symlink
-if [ -f $(bindir)/screen ] && [ ! -f $(bindir)/screen.old ]; then mv $(bindir)/screen $(bindir)/screen.old; fi
rm -f $(bindir)/screen
- ln -s screen-$(VERSION) $(bindir)/screen
+ ln -s $(SCREEN) $(bindir)/screen
+###############################################################################
install: installdirs install_bin
cd doc ; $(MAKE) install
- -tic ${srcdir}/terminfo/screeninfo.src
+ -if [ -d /usr/lib/terminfo ]; then \
+ PATH="$PATH:/usr/5bin" tic ${srcdir}/terminfo/screeninfo.src; \
+ chmod 644 /usr/lib/terminfo/s/screen*; \
+ fi
# Better do this by hand. E.g. under RCS...
# cat ${srcdir}/terminfo/screencap >> /etc/termcap
@echo "termcap entry (${srcdir}/terminfo/screencap) should be installed manually."
@@ -90,8 +97,8 @@ installdirs:
$(srcdir)/etc/mkinstalldirs $(bindir)
cd doc ; $(MAKE) installdirs
-uninstall:
- rm -f $(bindir)/screen-$(VERSION)
+uninstall: .version
+ rm -f $(bindir)/$(SCREEN)
rm -f $(bindir)/screen
-mv $(bindir)/screen.old $(bindir)/screen
rm -f $(ETCSCREENRC)
@@ -99,9 +106,12 @@ uninstall:
shadow:
mkdir shadow;
- cd shadow; ln -s ../*.[ch] ../*.in ../*.sh ../configure ../doc ../terminfo .
+ cd shadow; ln -s ../*.[ch] ../*.in ../*.sh ../configure ../doc ../terminfo ../etc .
rm -f shadow/term.h shadow/tty.c shadow/comm.h shadow/osdef.h
-
+ echo "install all Makefiles and config:" > shadow/Makefile
+ echo " rm -f config.cache" >> shadow/Makefile
+ echo " sh ./configure" >> shadow/Makefile
+
term.h: term.c term.sh
AWK=$(AWK) srcdir=$(srcdir) sh $(srcdir)/term.sh
@@ -123,78 +133,84 @@ dvi info screen.info:
-cd doc; $(MAKE) $@
mostlyclean:
- rm -f $(OFILES) screen
+ rm -f $(OFILES) screen config.cache osdef0.c osdef1.sed osdef2.sed
clean celan: mostlyclean
- rm -f tty.c term.h comm.h osdef.h
+ rm -f tty.c term.h comm.h osdef.h core
# Delete all files from the current directory that are created by
# configuring or building the program.
# building of term.h/comm.h requires awk. Keep it in the distribution
# we keep config.h, as this file knows where 'make dist' finds the ETCSCREENRC.
-distclean: mostlyclean
- rm -f screen-$(VERSION).tar screen-$(VERSION).TZ
- rm -f config.status Makefile
- rm -f osdef.h doc/Makefile
- echo "install all Makefiles and config:" > Makefile
- echo " sh ./configure" >> Makefile
+#distclean: mostlyclean
+# rm -f $(SCREEN).tar $(SCREEN).tar.gz
+# rm -f config.status Makefile
+# rm -f osdef.h doc/Makefile
+
+maintainer-clean:
+ @echo "This command is not even intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
# Delete everything from the current directory that can be
# reconstructed with this Makefile.
-realclean: distclean
- rm -f tty.c term.h comm.h
+realclean: .version mostlyclean
+ rm -f $(SCREEN).tar $(SCREEN).tar.gz
+ rm -f config.status Makefile doc/Makefile
+ rm -f tty.c term.h comm.h osdef.h
rm -f config.h
+ echo "install all Makefiles and config:" > Makefile
+ echo " sh ./configure" >> Makefile
-TAGS: $(CFILES)
- ctags $(CFILES) *.h
- ctags -e $(CFILES) *.h
+tags TAGS: $(CFILES)
+ -ctags *.sh $(CFILES) *.h
+ -ctags -e *.sh $(CFILES) *.h
-dist: screen-$(VERSION).tar.gz
+dist: .version $(SCREEN).tar.gz
-screen-$(VERSION).tar: term.h comm.h tty.c kmapdef.c
+$(SCREEN).tar: .version term.h comm.h tty.c kmapdef.c
-rm -rf dist
mkdir dist
- mkdir dist/screen-$(VERSION)
- ln acls.h ansi.h display.h extern.h mark.h os.h overlay.h \
- patchlevel.h rcs.h screen.h window.h image.h \
- osdef.h.in term.sh tty.sh comm.sh osdef.sh \
- acls.c ansi.c attacher.c comm.c display.c window.c fileio.c help.c \
- input.c loadav.c mark.c misc.c process.c pty.c putenv.c \
- screen.c search.c socket.c term.c termcap.c utmp.c resize.c \
- ChangeLog COPYING INSTALL NEWS* install.sh \
- dist/screen-$(VERSION)
- ln configure.in configure dist/screen-$(VERSION)
- sed -e 's@"/local/screens@"/tmp/screens@' -e 's@"/local@"/usr/local@g' < config.h.in > dist/screen-$(VERSION)/config.h.in
- sed -e 's@[ ]/local@ /usr/local@g' -e 's/^CFLAGS = -g/CFLAGS = -O/' < Makefile.in > dist/screen-$(VERSION)/Makefile.in
- ln term.h dist/screen-$(VERSION)/term.h.dist
- ln comm.h dist/screen-$(VERSION)/comm.h.dist
- ln tty.c dist/screen-$(VERSION)/tty.c.dist
- ln kmapdef.c dist/screen-$(VERSION)/kmapdef.c.dist
- ln README dist/screen-$(VERSION)/README
- ln tek.patch dist/screen-$(VERSION)/tek.patch
- mkdir dist/screen-$(VERSION)/terminfo
- cd terminfo; ln 8bits README checktc.c sco.mail screencap \
+ mkdir dist/$(SCREEN)
+ ln acls.h ansi.h display.h extern.h logfile.h mark.h os.h \
+ layer.h patchlevel.h rcs.h screen.h window.h image.h \
+ osdef.h.in term.sh tty.sh comm.sh osdef.sh braille.h \
+ sched.h \
+ $(CFILES) \
+ ChangeLog COPYING INSTALL NEWS* TODO install.sh \
+ dist/$(SCREEN)
+ cd dist/$(SCREEN); mv tty.c tty.c.dist
+ cd dist/$(SCREEN); mv kmapdef.c kmapdef.c.dist
+ ln configure.in configure dist/$(SCREEN)
+ sed -e 's@"/local/screens@"/tmp/screens@' -e 's@"/local@"/usr/local@g' < config.h.in > dist/$(SCREEN)/config.h.in
+ sed -e 's@[ ]/local@ /usr/local@g' -e 's/^CFLAGS = -g/CFLAGS = -O/' < Makefile.in > dist/$(SCREEN)/Makefile.in
+ ln term.h dist/$(SCREEN)/term.h.dist
+ ln comm.h dist/$(SCREEN)/comm.h.dist
+ ln README dist/$(SCREEN)/README
+ mkdir dist/$(SCREEN)/terminfo
+ cd terminfo; ln 8bits README checktc.c screencap \
screeninfo.src test.txt tetris.c \
- ../dist/screen-$(VERSION)/terminfo
- mkdir dist/screen-$(VERSION)/etc
- cd etc; ln * ../dist/screen-$(VERSION)/etc
- sed -e 's/^startup/#startup/' -e 's/^autodetach/#autodetach/' < $(ETCSCREENRC) > dist/screen-$(VERSION)/etc/etcscreenrc
- cp $(HOME)/.screenrc dist/screen-$(VERSION)/etc/screenrc
- mkdir dist/screen-$(VERSION)/doc
- sed -e 's@/local/emacs@/usr/local@g' < doc/Makefile.in > dist/screen-$(VERSION)/doc/Makefile.in
- cd doc; ln FAQ screen.1 screen.texinfo fdpat.ps \
- ../dist/screen-$(VERSION)/doc
+ ../dist/$(SCREEN)/terminfo
+ mkdir dist/$(SCREEN)/etc
+ cd etc; ln * ../dist/$(SCREEN)/etc
+ sed -e 's/^startup/#startup/' -e 's/^autodetach/#autodetach/' < $(ETCSCREENRC) > dist/$(SCREEN)/etc/etcscreenrc
+ cp $(HOME)/.screenrc dist/$(SCREEN)/etc/screenrc
+ mkdir dist/$(SCREEN)/doc
+ sed -e 's@/local/emacs@/usr/local@g' < doc/Makefile.in > dist/$(SCREEN)/doc/Makefile.in
+ cd doc; ln FAQ README.DOTSCREEN screen.1 screen.texinfo fdpat.ps make.help window_to_display.ps \
+ ../dist/$(SCREEN)/doc
cd doc; if test -f screen.info; then ln screen.info* \
- ../dist/screen-$(VERSION)/doc; fi
- cd dist/screen-$(VERSION)/doc; ln -s ../install.sh .
- cd dist/screen-$(VERSION); ln -s doc/FAQ .
- echo "install all Makefiles and config:" > dist/screen-$(VERSION)/Makefile
- echo " sh ./configure" >> dist/screen-$(VERSION)/Makefile
- cd dist; tar chf ../screen-$(VERSION).tar screen-$(VERSION)
+ ../dist/$(SCREEN)/doc; fi
+ cd dist/$(SCREEN)/doc; ln -s ../install.sh .
+ cd dist/$(SCREEN); ln -s doc/FAQ .
+ echo "install all Makefiles and config:" > dist/$(SCREEN)/Makefile
+ echo " rm -f config.cache" >> dist/$(SCREEN)/Makefile
+ echo " sh ./configure" >> dist/$(SCREEN)/Makefile
+ cd dist; tar cf ../$(SCREEN).tar $(SCREEN)
rm -rf dist
-screen-$(VERSION).tar.gz: screen-$(VERSION).tar
- gzip -f screen-$(VERSION).tar
+$(SCREEN).tar.gz: $(SCREEN).tar
+ gzip -nf $(SCREEN).tar || gzip -f $(SCREEN).tar
# Perform self-tests (if any).
check:
@@ -205,6 +221,23 @@ lint:
saber:
#load $(CFLAGS) screen.c ansi.c $(LIBS)
+config:
+ rm -f config.cache
+ sh ./configure
+
+
+###############################################################################
+
+.version:
+ @rev=`sed < $(srcdir)/patchlevel.h -n -e '/#define REV/s/#define REV *//p'`; \
+ vers=`sed < $(srcdir)/patchlevel.h -n -e '/#define VERS/s/#define VERS *//p'`; \
+ pat=`sed < $(srcdir)/patchlevel.h -n -e '/#define PATCHLEVEL/s/#define PATCHLEVEL *//p'`; \
+ if [ "$${rev}.$${vers}.$${pat}" != "$(VERSION)" ]; then \
+ echo "This distribution is screen-$${rev}.$${vers}.$${pat}, but"; \
+ echo "the Makefile is from $(VERSION). Please update!"; exit 1; fi
+
+###############################################################################
+
mdepend: $(CFILES) term.h
@rm -f DEPEND ; \
for i in ${CFILES} ; do \
@@ -218,36 +251,76 @@ mdepend: $(CFILES) term.h
done
-depend: $(CFILES) term.h
- cp Makefile Makefile~
- sed -e '/\#\#\# Dependencies/q' < Makefile > tmp_make
+depend: depend.in
+ ./config.status || ./configure
+
+depend.in: $(CFILES) term.h
+ cp Makefile.in Makefile.in~
+ sed -e '/\#\#\# Dependencies/q' < Makefile.in > tmp_make
for i in $(CFILES); do echo $$i; $(CPP_DEPEND) $$i >> tmp_make; done
- mv tmp_make Makefile
+ mv tmp_make Makefile.in
-screen.o socket.o: Makefile
+###############################################################################
### Dependencies:
-screen.o: screen.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h patchlevel.h rcs.h screen.h term.h window.h
-ansi.o: ansi.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h
-fileio.o: fileio.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h
-mark.o: mark.c acls.h ansi.h comm.h config.h display.h extern.h image.h mark.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h
-misc.o: misc.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h
-resize.o: resize.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h
-socket.o: socket.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h
-search.o: search.c acls.h ansi.h comm.h config.h display.h extern.h image.h mark.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h
-tty.o: tty.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h
+screen.o: screen.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h \
+ comm.h layer.h term.h image.h display.h window.h braille.h \
+ patchlevel.h logfile.h extern.h
+ansi.o: ansi.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h \
+ comm.h layer.h term.h image.h display.h window.h braille.h extern.h \
+ logfile.h
+fileio.o: fileio.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h \
+ comm.h layer.h term.h image.h display.h window.h extern.h
+mark.o: mark.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h \
+ comm.h layer.h term.h image.h display.h window.h mark.h extern.h
+misc.o: misc.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h \
+ comm.h layer.h term.h image.h display.h window.h extern.h
+resize.o: resize.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h \
+ comm.h layer.h term.h image.h display.h window.h extern.h
+socket.o: socket.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h \
+ comm.h layer.h term.h image.h display.h window.h extern.h
+search.o: search.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h \
+ comm.h layer.h term.h image.h display.h window.h mark.h extern.h
+tty.o: tty.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h comm.h \
+ layer.h term.h image.h display.h window.h extern.h
term.o: term.c rcs.h term.h
-window.o: window.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h
-utmp.o: utmp.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h
-loadav.o: loadav.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h
-putenv.o: putenv.c config.h rcs.h
-help.o: help.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h
-termcap.o: termcap.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h
-input.o: input.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h
-attacher.o: attacher.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h
-pty.o: pty.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h
-process.o: process.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h
-display.o: display.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h
-comm.o: comm.c acls.h comm.h config.h rcs.h
+window.o: window.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h \
+ comm.h layer.h term.h image.h display.h window.h extern.h logfile.h
+utmp.o: utmp.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h \
+ comm.h layer.h term.h image.h display.h window.h extern.h
+loadav.o: loadav.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h \
+ comm.h layer.h term.h image.h display.h window.h extern.h
+putenv.o: putenv.c rcs.h config.h
+help.o: help.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h \
+ comm.h layer.h term.h image.h display.h window.h extern.h
+termcap.o: termcap.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h \
+ comm.h layer.h term.h image.h display.h window.h extern.h
+input.o: input.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h \
+ comm.h layer.h term.h image.h display.h window.h extern.h
+attacher.o: attacher.c rcs.h config.h screen.h os.h osdef.h ansi.h \
+ acls.h comm.h layer.h term.h image.h display.h window.h extern.h
+pty.o: pty.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h comm.h \
+ layer.h term.h image.h display.h window.h extern.h
+process.o: process.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h \
+ comm.h layer.h term.h image.h display.h window.h extern.h logfile.h
+display.o: display.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h \
+ comm.h layer.h term.h image.h display.h window.h extern.h braille.h
+comm.o: comm.c rcs.h config.h acls.h comm.h
kmapdef.o: kmapdef.c config.h
-acls.o: acls.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h
+acls.o: acls.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h comm.h \
+ layer.h term.h image.h display.h window.h extern.h
+braille.o: braille.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h \
+ comm.h layer.h term.h image.h display.h window.h extern.h braille.h
+braille_tsi.o: braille_tsi.c config.h screen.h os.h osdef.h ansi.h \
+ acls.h comm.h layer.h term.h image.h display.h window.h extern.h \
+ braille.h
+logfile.o: logfile.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h \
+ comm.h layer.h term.h image.h display.h window.h extern.h logfile.h
+layer.o: layer.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h \
+ comm.h layer.h term.h image.h display.h window.h extern.h
+sched.o: sched.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h \
+ comm.h layer.h term.h image.h display.h window.h extern.h logfile.h
+teln.o: teln.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h \
+ comm.h layer.h term.h image.h display.h window.h extern.h
+nethack.o: nethack.c rcs.h config.h screen.h os.h osdef.h ansi.h acls.h \
+ comm.h layer.h term.h image.h display.h window.h extern.h
diff --git a/NEWS b/NEWS
index 0224ff3..b0ecf3b 100644
--- a/NEWS
+++ b/NEWS
@@ -1,80 +1,102 @@
----------------------------
- What's new in screen-3.7 ?
+ What's new in screen-3.9 ?
----------------------------
-* Color support. Screen understands the following capabilities:
- AF (setaf) = Set foreground color (ANSI compatible)
- AB (setab) = Set background color (ANSI compatible)
- AX = Does understand ANSI set default fg/bg color
- (\E[39m / \E[49m)
- The tweaks for the color xterm would be:
- termcap xterm 'AF=\E[3%dm:AB=\E[4%dm'
- terminfo xterm 'AF=\E[3%p1%dm:AB=\E[4%p1%dm'
- Caution: Screen exposes a bug in X11R6 color xterm. Either use the
- patch ftp.uni-erlangen.de:pub/utilities/screen/color_xterm_patch
- or a clean rewrite of xterm: rxvt.
+* real multiuser support
+ A window can now be displayed on more than one attached displays.
+ Screen does all the necessary clipping if the window size doesn't
+ fit the display.
+ New command:
+ ^AF - fit the window size into the display size.
-* Resize code completely rewritten. Long lines now get rewrapped,
- no information gets lost when a window is narrowed and widened. This
- affects both the visible window and its scrollback buffer. It is a
- big improvement for the latter. In previous versions the scrollback
- buffer was clipped when the window narrowed and padded with
- whitespace when it widened.
+* split screen support
+ A display may now host multiple windows.
+ New commands:
+ ^AS - split horizontally. This add another region to the display
+ ^A<Tab> - move the focus to the next region
+ ^AX - kill the current region
+ ^AQ - kill all other regions
-* Input handling changed. The command key can now be a prefix
- of a function key sequence (hello wyse users :) )
+* hardstatus emulation support
+ The last line of the display may now be used as a hardstatus
+ line if the terminal doesn't have the 'hs' capability.
+ New commands:
+ hardstatus [always]lastline
+ hardstatus [always]message
+ hardstatus [always]ignore
-* An empty argument to the escape command is allowed to disable
- command key processing. This is only allowed if some key
- is bound to the "command" command. This example makes F1 the
- new command key and allows the previous command key (usually ^A)
- to be typed directly:
- bindkey -k k1 command
- escape ""
+* configurable window seperator and hardstatus strings
+ The window (region) seperator and the hardstatus can be set to an
+ arbitrary string containing screen's % escape sequences.
+ The window's hardstatus is just another escape sequence, '%h'.
+ New commands:
+ hardstatus string [string]
+ caption string [string]
+ The default strings are "%h" (hardstatus) and "%3n %t" (caption).
-* New 'digraph' command (bound to ^A^V)
- ^A^Va" or ^A^V0344 input an a-umlaut
- This helps if you want to work in an ISO-latin1 environment but your
- terminal's keyboard lacks a some of the more special characters.
+* permanent window seperator
+ The window seperator can be set to stay on screen even if
+ the display contains only one region
+ New commands:
+ caption always
+ caption splitonly
-* activity/bell message strings can now include the window title
- and the current date/time:
- %t - title
- %n - number (a single % still works)
- %d - day
- %D - weekday name
- %m - month
- %M - month name
- %y - year (2 digit)
- %Y - year (4 digit)
- %w - hour:minutes (24h format)
- %W - hour:minutes (12h format)
- %s - seconds
- %a - am/pm
- %A - AM/PM
- Please do not use a single '%' character for window titles any more.
- It is obsoleted by '%n' and will vanish in future releases.
+* many new escapes
+ %c - current time HH:MM (*CHANGE*: this was %w in screen-3.7)
+ %C - current time HH:MM in 24h format
+ %l - the load of the system
+ %h - hardstatus of the window
+ %w - all window names
+ %W - all window names except the current window
+ %u - all other users on this window
+ %? - the part to the next %? is displayed only if an escape
+ expands to an nonempty string.
+ %: - "else" part of %?
+ Some escapes like %c may be qualified with a '0' (like %0c)
+ to make screen use '0' instead of space as a filler.
+ Others understand a length qualifier, like %3n.
+ If escapes like the current time are used as hardstatus/caption
+ string screen will update them so that you can always have
+ the current time onscreen.
+ *CHANGE* ~ is no longer used as bell character, use ^G instead!
-* 'defhstatus' command to give every window a default
- hardstatus line. '^E' is used as a string escape instead of '%'.
- All the above substitution codes apply, but you must use ^E (octal
- 005) here, as '%' is likely to appear in automaticaly generated
- hardstatus lines. Try 'defhstatus "Screen: window ^E (^Et)"'.
+* logfile timestamps and flush timeout
+ New commands:
+ logfile flush <secs>
+ logtstamp [on|off]
+ logtstamp string [string]
+ logtstamp after [secs]
-* In screenrc files and colon command mode: Input parser changed to
- also understand caret notation ('^') to mean "Control-" (as in
- the ^E example above).
+* configurable breaktype
+ You can now choose one of TIOCSBRK, TCSBRK, tcsendbreak.
+ New commands:
+ breaktype
+ defbreaktype
-* "logdir" command changed to "logfile". You can now specify the
- filename instead of the directory. The same directives as
- understood by the activity/bell messages can be used.
- The default is "screenlog.%n".
+* other new commands:
+ hstatus - set the window's hardstatus
+ defslowpaste
+ defsilence
-* Special terminfo workaround make delay processing work for
- the first time! If you had trouble with padding, then try again.
+* optional builtin telnet.
+ This is useful if screen is used as frontend to a terminal
+ multiplexor. Use //telnet to access the builtin telnet program,
+ as in: 'screen //telnet host [port]'
-* New incomprehensible capability XC added to specify character
- translation depending on the terminal type. See the manual for
- more details and examples.
+* remote detach and reattach change:
+ '-d' is now ignored if the screen is already detached and you
+ want to reattach. You can also use '-RR' to make screen use
+ the first session found if more than one session is available.
+ Thus '-d -RR' or '-x -RR' always gets you a screen.
+
+* support for history compaction
+ You can tell screen to suppress trailing blank lines when
+ scolling up text into the history buffer. (Wayne Davison)
+ New command:
+ compacthist
+
+* optional Braille support. If you can read Braille and have one of
+ the devices listed in README.DOTSCREEN, please compile with
+ -DHAVE_BRAILLE and let us know if this feature is useful.
diff --git a/NEWS.3.7 b/NEWS.3.7
new file mode 100644
index 0000000..e398f95
--- /dev/null
+++ b/NEWS.3.7
@@ -0,0 +1,39 @@
+
+
+ ----------------------------
+ What's new in screen-3.7 ?
+ ----------------------------
+
+* Color support. Screen understands the following capabilities:
+ AF (setaf) = Set foreground color (ANSI compatible)
+ AB (setab) = Set background color (ANSI compatible)
+ AX = Does understand ANSI set default fg/bg color
+ (\E[39m / \E[49m)
+ The tweaks for the color xterm would be:
+ termcap xterm 'AF=\E[3%dm:AB=\E[4%dm'
+ terminfo xterm 'AF=\E[3%p1%dm:AB=\E[4%p1%dm'
+
+* New 'digraph' command (bound to ^A^V)
+ ^A^Va" or ^A^V0344 input an a-umlaut
+
+* activity/bell message strings can now include the window title:
+ %t - title
+ %n - number (a single % still works)
+
+* 'defhstatus' command to give everey window a default
+ hardstatus line. ^E is used as a string escape instead of %
+ (see above). Try 'defhstatus "Screen: window ^E (^Et)"'
+
+* Input parser changed to understand '^' (see ^E above).
+
+Note that the linux color xterm has a stupid bug: the characters
+get the color of the cursor, therefore if you change color and move
+the cursor around all the characters will get the new color...
+Here is a patch:
+ pub/utilities/screen/color_xterm_patch
+Btw.: rxvt works fine.
+
+* Optional Braille support. If you can read Braille and have one of
+ the devices listed in README.DOTSCREEN, please compile with
+ -DHAVE_BRAILLE and let us know if this feature is useful.
+
diff --git a/README b/README
index 362674f..217573e 100644
--- a/README
+++ b/README
@@ -1,16 +1,16 @@
[If you just got the screen package, it pays to read the file INSTALL]
[This intro only describes the most common features to get you started]
+ [A full description of all features is contained in the source package]
-Short introduction to screen (Version 3.6.0) lvirden 8-8-93
- [note that this intro only describes the most common screen features]
+Short introduction to screen (Version 3.6.0) lvirden 8-8-93
Send bugreports, fixes, enhancements, t-shirts, money, beer & pizza to
screen@uni-erlangen.de
-iscreen provides you with an ANSI/vt100 terminal emulator, which can multiplex
+Screen provides you with an ANSI/vt100 terminal emulator, which can multiplex
up to 10 pseudo-terminals. On startup, it executes $SHELL in window 0.
Then it reads $HOME/.screenrc to learn configuration, keybindings, and
possibly open more windows.
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..2493216
--- /dev/null
+++ b/TODO
@@ -0,0 +1,8 @@
+- display size adaption (Activate)
+- better kanji
+- message protocol (send screen command)
+- esc-sequence for screen commands
+- process.c cleanup via comm splitting
+- writelocks?
+- partial?
+- nonblock?
diff --git a/acls.c b/acls.c
index 1157af5..74378d1 100644
--- a/acls.c
+++ b/acls.c
@@ -26,6 +26,24 @@ RCS_ID("$Id: acls.c,v 1.12 1994/05/31 12:31:21 mlschroe Exp $ FAU")
#include <sys/types.h>
#include "config.h"
+
+
+/* XXX: WHY IS THIS HERE?? :XXX */
+
+#ifdef CHECKLOGIN
+# ifdef _SEQUENT_
+# include <stdio.h> /* needed by <pwd.h> */
+# endif /* _SEQUENT_ */
+# include <pwd.h>
+# ifdef SHADOWPW
+# include <shadow.h>
+# endif /* SHADOWPW */
+#endif /* CHECKLOGIN */
+
+#ifndef NOSYSLOG
+# include <syslog.h>
+#endif
+
#include "screen.h" /* includes acls.h */
#include "extern.h"
@@ -37,6 +55,7 @@ RCS_ID("$Id: acls.c,v 1.12 1994/05/31 12:31:21 mlschroe Exp $ FAU")
extern struct comm comms[];
extern struct win *windows, *wtab[];
extern char NullStr[];
+extern char SockPath[];
extern struct display *display, *displays;
struct user *users;
@@ -52,9 +71,9 @@ static AclBits userbits;
*/
static char default_w_bit[ACL_BITS_PER_WIN] =
{
- 0, /* EXEC */
- 0, /* WRITE */
- 0 /* READ */
+ 1, /* EXEC */
+ 1, /* WRITE */
+ 1 /* READ */
};
static char default_c_bit[ACL_BITS_PER_CMD] =
@@ -70,7 +89,11 @@ static char default_c_bit[ACL_BITS_PER_CMD] =
*/
static int GrowBitfield __P((AclBits *, int, int, int));
-
+static struct usergroup **FindGroupPtr __P((struct usergroup **, struct user *, int));
+static int AclSetPermCmd __P((struct user *, char *, struct comm *));
+static int AclSetPermWin __P((struct user *, struct user *, char *, struct win *));
+static int UserAcl __P((struct user *, struct user **, int, char **));
+static int UserAclCopy __P((struct user **, struct user **));
static int
@@ -160,6 +183,8 @@ struct user **up;
(*up)->u_password = SaveStr(pass);
if (!(*up)->u_password)
(*up)->u_password = NullStr;
+ (*up)->u_detachwin = -1;
+ (*up)->u_detachotherwin = -1;
#ifdef MULTIUSER
(*up)->u_group = NULL;
@@ -275,6 +300,25 @@ struct user **up;
return 0;
}
+#if 0
+/* change user's password */
+int
+UserSetPass(name, pass, up)
+char *name, *pass;
+struct user **up;
+{
+ if (!up)
+ up = FindUserPtr(name);
+ if (!*up)
+ return UserAdd(name, pass, up);
+ if (!strcmp(name, "nobody")) /* he remains without password */
+ return -1;
+ strncpy((*up)->u_password, pass ? pass : "", 20);
+ (*up)->u_password[20] = '\0';
+ return 0;
+}
+#endif
+
/*
* Remove a user from the list.
* Destroy all his permissions and completely detach him from the session.
@@ -360,20 +404,16 @@ UserFreeCopyBuffer(u)
struct user *u;
{
struct win *w;
+ struct paster *pa;
if (!u->u_copybuffer)
return 1;
for (w = windows; w; w = w->w_next)
{
- if (w->w_pasteptr >= u->u_copybuffer &&
- w->w_pasteptr - u->u_copybuffer < u->u_copylen)
- {
- if (w->w_pastebuf)
- free((char *)w->w_pastebuf);
- w->w_pastebuf = 0;
- w->w_pasteptr = 0;
- w->w_pastelen = 0;
- }
+ pa = &w->w_paster;
+ if (pa->pa_pasteptr >= u->u_copybuffer &&
+ pa->pa_pasteptr - u->u_copybuffer < u->u_copylen)
+ FreePaster(pa);
}
free((char *)u->u_copybuffer);
u->u_copylen = 0;
@@ -382,6 +422,171 @@ struct user *u;
}
#endif /* COPY_PASTE */
+#ifdef MULTIUSER
+/*
+ * Traverses group nodes. It searches for a node that references user u.
+ * If recursive is true, nodes found in the users are also searched using
+ * depth first method. If none of the nodes references u, the address of
+ * the last next pointer is returned. This address will contain NULL.
+ */
+static struct usergroup **
+FindGroupPtr(gp, u, recursive)
+struct usergroup **gp;
+struct user *u;
+int recursive;
+{
+ struct usergroup **g;
+
+ ASSERT(recursive < 1000); /* Ouch, cycle detection failed */
+ while (*gp)
+ {
+ if ((*gp)->u == u)
+ return gp; /* found him here. */
+ if (recursive &&
+ *(g = FindGroupPtr(&(*gp)->u->u_group, u, recursive + 1)))
+ return g; /* found him there. */
+ gp = &(*gp)->next;
+ }
+ return gp; /* *gp is NULL */
+}
+
+/*
+ * Returns nonzero if failed or already linked.
+ * Both users are created on demand.
+ * Cyclic links are prevented.
+ */
+int
+AclLinkUser(from, to)
+char *from, *to;
+{
+ struct user **u1, **u2;
+ struct usergroup **g;
+
+ if (!*(u1 = FindUserPtr(from)) && UserAdd(from, NULL, u1))
+ return -1;
+ if (!*(u2 = FindUserPtr(to)) && UserAdd(to, NULL, u2))
+ return -1; /* hmm, could not find both users. */
+
+ if (*FindGroupPtr(&(*u2)->u_group, *u1, 1))
+ return 1; /* cyclic link detected! */
+ if (*(g = FindGroupPtr(&(*u1)->u_group, *u2, 0)))
+ return 2; /* aha, we are already linked! */
+
+ if (!(*g = (struct usergroup *)malloc(sizeof(struct usergroup))))
+ return -1; /* Could not alloc link. Poor screen */
+ (*g)->u = (*u2);
+ (*g)->next = NULL;
+ return 0;
+}
+
+/*
+ * The user pointer stored at *up will be substituted by a pointer
+ * to the named user's structure, if passwords match.
+ * returns NULL if successfull, an static error string otherwise
+ */
+char *
+DoSu(up, name, pw1, pw2)
+struct user **up;
+char *name, *pw1, *pw2;
+{
+ struct user *u;
+ int sorry = 0;
+
+ if (!(u = *FindUserPtr(name)))
+ sorry++;
+ else
+ {
+#ifdef CHECKLOGIN
+ struct passwd *pp;
+#ifdef SHADOWPW
+ struct spwd *ss;
+ int t, c;
+#endif
+ char *pass = "";
+
+ if (!(pp = getpwnam(name)))
+ {
+ debug1("getpwnam(\"%s\") failed\n", name);
+ if (!(pw1 && *pw1 && *pw1 != '\377'))
+ {
+ debug("no unix account, no screen passwd\n");
+ sorry++;
+ }
+ }
+ else
+ pass = pp->pw_passwd;
+#ifdef SHADOWPW
+ for (t = 0; t < 13; t++)
+ {
+ c = pass[t];
+ if (!(c == '.' || c == '/' ||
+ (c >= '0' && c <= '9') ||
+ (c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z')))
+ break;
+ }
+ if (t < 13)
+ {
+ if (!(ss = getspnam(name)))
+ {
+ debug1("getspnam(\"%s\") failed\n", name);
+ sorry++;
+ }
+ else
+ pass = ss->sp_pwdp;
+ }
+#endif /* SHADOWPW */
+
+ if (pw2 && *pw2 && *pw2 != '\377') /* provided a system password */
+ {
+ if (!*pass || /* but needed none */
+ strcmp(crypt(pw2, pass), pass))
+ {
+ debug("System password mismatch\n");
+ sorry++;
+ }
+ }
+ else /* no pasword provided */
+ if (*pass) /* but need one */
+ sorry++;
+#endif
+ if (pw1 && *pw1 && *pw1 != '\377') /* provided a screen password */
+ {
+ if (!*u->u_password || /* but needed none */
+ strcmp(crypt(pw1, u->u_password), u->u_password))
+ {
+ debug("screen password mismatch\n");
+ sorry++;
+ }
+ }
+ else /* no pasword provided */
+ if (*u->u_password) /* but need one */
+ sorry++;
+ }
+
+ debug2("syslog(LOG_NOTICE, \"screen %s: \"su %s\" ", SockPath, name);
+ debug2("%s for \"%s\"\n", sorry ? "failed" : "succeded", (*up)->u_name);
+#ifndef NOSYSLOG
+# ifdef BSD_42
+ openlog("screen", LOG_PID);
+# else
+ openlog("screen", LOG_PID, LOG_AUTH);
+# endif /* BSD_42 */
+ syslog(LOG_NOTICE, "%s: \"su %s\" %s for \"%s\"", SockPath, name,
+ sorry ? "failed" : "succeded", (*up)->u_name);
+ closelog();
+#else
+ debug("NOT LOGGED.\n");
+#endif /* NOSYSLOG */
+
+ if (sorry)
+ return "Sorry.";
+ else
+ *up = u; /* substitute user now */
+ return NULL;
+}
+#endif /* MULTIUSER */
+
/************************************************************************
* end of user managing code *
************************************************************************/
@@ -411,6 +616,8 @@ struct user *u;
{
while (--j >= 0)
free((char *)w->w_userbits[j]);
+ free((char *)w->w_mon_notify);
+ free((char *)w->w_lio_notify);
return -1;
}
for (i = 0; i < maxusercount; i++)
@@ -421,6 +628,19 @@ struct user *u;
return 0;
}
+void
+FreeWindowAcl(w)
+struct win *w;
+{
+ int i;
+
+ for (i = 0; i < ACL_BITS_PER_WIN; i++)
+ free((char *)w->w_userbits[i]);
+ free((char *)w->w_mon_notify);
+ free((char *)w->w_lio_notify);
+}
+
+
/* if mode starts with '-' we remove the users exec bit for cmd */
/*
* NOTE: before you make this function look the same as
@@ -593,7 +813,7 @@ char *mode, *s;
AclSetPermWin(uu, u, mode, (struct win *)1);
else /* .. or all windows */
for (w = windows; w; w = w->w_next)
- AclSetPermWin(NULL, u, mode, w);
+ AclSetPermWin((struct user *)0, u, mode, w);
s++;
break;
case '?':
@@ -612,7 +832,7 @@ char *mode, *s;
if ((i = FindCommnr(s)) != RC_ILLEGAL)
AclSetPermCmd(u, mode, &comms[i]);
else if (((i = WindowByNoN(s)) >= 0) && wtab[i])
- AclSetPermWin(NULL, u, mode, wtab[i]);
+ AclSetPermWin((struct user *)0, u, mode, wtab[i]);
else
/* checking group name */
return -1;
@@ -774,44 +994,65 @@ char **argv;
return 0;
}
-#if 0
-void
-AclWinSwap(a, b)
-int a, b;
+/*
+ * Preprocess argments, so that umask can be set with UsersAcl
+ *
+ * all current users umask ±rwxn
+ * one specific user umask user1±rwxn
+ * several users umask user1,user2,...±rwxn
+ * default_w_bits umask ?±rwxn
+ * default_c_bits umask ??±rwxn
+ */
+int
+AclUmask(u, str, errp)
+struct user *u;
+char *str;
+char **errp;
{
- int a_bit = 0, b_bit = 0;
- AclGroupList **g;
- AclBits p;
+ char mode[16];
+ char *av[3];
+ char *p, c = '\0';
- debug2("acl lists swapping windows %d and %d\n", a, b);
-
- for (g = &aclgrouproot; *g; g = &(*g)->next)
+ /* split str into user and bits section. */
+ for (p = str; *p; p++)
+ if ((c = *p) == '+' || c == '-')
+ break;
+ if (!*p)
+ {
+ *errp = "Bad argument. Should be ``[user[,user...]{+|-}rwxn''.";
+ return -1;
+ }
+ strncpy(mode, p, 15);
+ mode[15] = '\0';
+ *p = '\0';
+
+ /* construct argument vector */
+ if (!strcmp("??", str))
+ {
+ str++;
+ av[2] = "?";
+ }
+ else
+ av[2] = "#";
+ av[1] = mode;
+ av[0] = *str ? str : "*";
+ /* call UsersAcl */
+ if (UsersAcl(u, 3, av))
{
- p = (*g)->group->winbits;
- /* see if there was a bit for window a. zap it */
- if (a >= 0)
- if ((a_bit = ACLBIT(a) & ACLBYTE(p, a)))
- ACLBYTE(p, a) &= ~ACLBIT(a);
- /* see if there was a bit for window b. zap it */
- if (b >= 0)
- if ((b_bit = ACLBIT(b) & ACLBYTE(p, b)))
- ACLBYTE(p, b) &= ~ACLBIT(b);
- /* b may cause a set */
- if (b_bit && a >= 0)
- ACLBYTE(p, a) |= ACLBIT(a);
- /* a may cause b set */
- if (a_bit && b >= 0)
- ACLBYTE(p, b) |= ACLBIT(b);
+ *errp = "UsersAcl failed. Hmmm.";
+ *p = c;
+ return -1;
}
+ *p = c;
+ return 0;
}
-#else
+
void
AclWinSwap(a, b)
int a, b;
{
- debug2("AclWinSwap(%d, %d) DUMMY\n", a, b);
+ debug2("AclWinSwap(%d, %d) NOP.\n", a, b);
}
-#endif
struct user *EffectiveAclUser = NULL; /* hook for AT command permission */
diff --git a/acls.h b/acls.h
index b30f714..1438113 100644
--- a/acls.h
+++ b/acls.h
@@ -39,25 +39,6 @@
typedef unsigned char * AclBits;
-/* a bitfield for windows and one for commands */
-typedef struct
-{
- char name[20 + 1];
- AclBits wins, cmds;
-} AclGroup;
-
-/*
- * An AclGroupList is a chaind list of pointers to AclGroups.
- * Each user has such a list to reference groups he is in.
- * The aclgrouproot anchors all AclGroups. Delete and create
- * groups there.
- */
-typedef struct grouplist
-{
- AclGroup *group;
- struct grouplist *next;
-} AclGroupList;
-
/*
* How a user joins a group.
* Here is the node to construct one list per user.
diff --git a/ansi.c b/ansi.c
index 1bb02c2..d2a4244 100644
--- a/ansi.c
+++ b/ansi.c
@@ -25,7 +25,6 @@
RCS_ID("$Id: ansi.c,v 1.22 1994/05/31 12:31:25 mlschroe Exp $ FAU")
#include <sys/types.h>
-#include <signal.h>
#include <fcntl.h>
#ifndef sun /* we want to know about TIOCPKT. */
# include <sys/ioctl.h>
@@ -33,27 +32,30 @@ RCS_ID("$Id: ansi.c,v 1.22 1994/05/31 12:31:25 mlschroe Exp $ FAU")
#include "config.h"
#include "screen.h"
+#include "braille.h"
#include "extern.h"
+#include "logfile.h"
-extern struct win *windows; /* linked list of all windows */
-extern struct win *fore;
extern struct display *display, *displays;
-extern int force_vt;
-extern int all_norefresh; /* => display */
-extern int ZombieKey_destroy, ZombieKey_resurrect;
-extern int real_uid, real_gid;
-extern time_t Now;
extern struct NewWindow nwin_default; /* for ResetWindow() */
-extern int nversion;
+extern int nversion; /* numerical version of screen */
+extern int log_flush, logtstamp_on, logtstamp_after;
+extern char *logtstamp_string;
+extern char *captionstring;
+extern char *hstatusstring;
+#ifdef COPY_PASTE
+extern int compacthist;
+#endif
int Z0width, Z1width; /* widths for Z0/Z1 switching */
+/* globals set in WriteString */
static struct win *curr; /* window we are working on */
static int rows, cols; /* window size of the curr window */
int visual_bell = 0;
-int use_hardstatus = 1;
+int use_hardstatus = 1; /* display status line in hs */
char *printcmd = 0;
char *blank; /* line filled with spaces */
@@ -67,25 +69,48 @@ struct mchar mchar_null;
struct mchar mchar_blank = {' ' /* , 0, 0, ... */};
struct mchar mchar_so = {' ', A_SO /* , 0, 0, ... */};
-static void WinProcess __P((char **, int *));
-static void WinRedisplayLine __P((int, int, int, int));
-static void WinClearLine __P((int, int, int));
-static int WinRewrite __P((int, int, int, int));
-static void WinSetCursor __P((void));
-static int WinResize __P((int, int));
-static void WinRestore __P((void));
+/* keep string_t and string_t_string in sync! */
+static char *string_t_string[] =
+{
+ "NONE",
+ "DCS", /* Device control string */
+ "OSC", /* Operating system command */
+ "APC", /* Application program command */
+ /* - used for status change */
+ "PM", /* Privacy message */
+ "AKA", /* title for current screen */
+ "GM", /* Global message to every display */
+ "STATUS" /* User hardstatus line */
+};
+
+/* keep state_t and state_t_string in sync! */
+static char *state_t_string[] =
+{
+ "LIT", /* Literal input */
+ "ESC", /* Start of escape sequence */
+ "ASTR", /* Start of control string */
+ "STRESC", /* ESC seen in control string */
+ "CSI", /* Reading arguments in "CSI Pn ;...*/
+ "PRIN", /* Printer mode */
+ "PRINESC", /* ESC seen in printer mode */
+ "PRINCSI", /* CSI seen in printer mode */
+ "PRIN4" /* CSI 4 seen in printer mode */
+};
+
static int Special __P((int));
static void DoESC __P((int, int));
static void DoCSI __P((int, int));
-static void SetChar __P((int));
-static void StartString __P((enum string_t));
-static void SaveChar __P((int));
+static void StringStart __P((enum string_t));
+static void StringChar __P((int));
+static int StringEnd __P((void));
static void PrintStart __P((void));
static void PrintChar __P((int));
static void PrintFlush __P((void));
+#ifdef FONT
static void DesignateCharset __P((int, int));
static void MapCharset __P((int));
static void MapCharsetR __P((int));
+#endif
static void SaveCursor __P((void));
static void RestoreCursor __P((void));
static void BackSpace __P((void));
@@ -97,18 +122,13 @@ static void InsertChar __P((int));
static void DeleteChar __P((int));
static void DeleteLine __P((int));
static void InsertLine __P((int));
-static void ScrollUpMap __P((int));
-static void ScrollDownMap __P((int));
static void Scroll __P((char *, int, int, char *));
static void ForwardTab __P((void));
static void BackwardTab __P((void));
static void ClearScreen __P((void));
static void ClearFromBOS __P((void));
static void ClearToEOS __P((void));
-static void ClearFullLine __P((void));
-static void ClearToEOL __P((void));
-static void ClearFromBOL __P((void));
-static void ClearInLine __P((int, int, int));
+static void ClearLineRegion __P((int, int));
static void CursorRight __P((int));
static void CursorUp __P((int));
static void CursorDown __P((int));
@@ -117,271 +137,28 @@ static void ASetMode __P((int));
static void SelectRendition __P((void));
static void RestorePosRendition __P((void));
static void FillWithEs __P((void));
-static void UpdateLine __P((struct mline *, int, int, int ));
static void FindAKA __P((void));
static void Report __P((char *, int, int));
-static void FixLine __P((void));
static void ScrollRegion __P((int));
-static void CheckLP __P((int));
-#ifdef COPY_PASTE
static void AddLineToHist __P((struct win *, struct mline *));
-#endif
-
-
-/*
- * The window layer functions
- */
-
-struct LayFuncs WinLf =
-{
- WinProcess,
- 0,
- WinRedisplayLine,
- WinClearLine,
- WinRewrite,
- WinSetCursor,
- WinResize,
- WinRestore
-};
-
-static void
-WinProcess(bufpp, lenp)
-char **bufpp;
-int *lenp;
-{
- int addlf, l2 = 0, f, *ilen, l = *lenp;
- char *ibuf, *p, *buf = *bufpp;
-
- fore = D_fore;
- /* if w_wlock is set, only one user may write, else we check acls */
- if (fore->w_ptyfd < 0)
- {
- while ((*lenp)-- > 0)
- {
- f = *(*bufpp)++;
- if (f == ZombieKey_destroy)
- {
- debug2("Turning undead: %d(%s)\n", fore->w_number, fore->w_title);
- KillWindow(fore);
- l2--;
- break;
- }
- if (f == ZombieKey_resurrect)
- {
- SetCurr(fore);
-
- debug1("Resurrecting Zombie: %d\n", fore->w_number);
- LineFeed(2);
- RemakeWindow(fore);
- l2++;
- break;
- }
- }
- if (!l2)
- {
- char b1[10], b2[10];
-
- b1[AddXChar(b1, ZombieKey_destroy)] = '\0';
- b2[AddXChar(b2, ZombieKey_resurrect)] = '\0';
- Msg(0, "Press %s to destroy or %s to resurrect window", b1, b2);
- }
- *bufpp += *lenp;
- *lenp = 0;
- return;
- }
-#ifdef MULTIUSER
- if ((fore->w_wlock == WLOCK_OFF) ?
- AclCheckPermWin(D_user, ACL_WRITE, fore) :
- (D_user != fore->w_wlockuser))
- {
- SetCurr(fore);
- Special('\007');
- *bufpp += *lenp;
- *lenp = 0;
- return;
- }
-#endif /* MULTIUSER */
-#ifdef PSEUDOS
- if (W_UWP(fore))
- {
- /* we send the user input to our pseudowin */
- ibuf = fore->w_pwin->p_inbuf; ilen = &fore->w_pwin->p_inlen;
- f = sizeof(fore->w_pwin->p_inbuf) - *ilen;
- }
- else
-#endif /* PSEUDOS */
- {
- /* we send the user input to the window */
- ibuf = fore->w_inbuf; ilen = &fore->w_inlen;
- f = sizeof(fore->w_inbuf) - *ilen;
- }
+static void LogString __P((struct win *, char *, int));
+static void WReverseVideo __P((struct win *, int));
+static void MFixLine __P((struct win *, int, struct mchar *));
+static void MScrollH __P((struct win *, int, int, int, int));
+static void MScrollV __P((struct win *, int, int, int));
+static void MClear __P((struct win *, int, int, int, int));
+static void MInsChar __P((struct win *, struct mchar *, int, int));
+static void MPutChar __P((struct win *, struct mchar *, int, int));
+static void MWrapChar __P((struct win *, struct mchar *, int, int, int, int));
+static int WindowChangedCheck __P((char *, int, int *));
- buf = *bufpp;
- while (l)
- {
- l2 = l;
- addlf = 0;
- if (fore->w_autolf)
- {
- for (p = buf; l2; p++, l2--)
- if (*p == '\r')
- {
- l2--;
- addlf = 1;
- break;
- }
- l2 = l - l2;
- }
- if (l2 + addlf > f)
- {
- debug1("Yuck! pty buffer full (%d chars missing). lets beep\n", l - f);
- SetCurr(fore);
- Special('\007');
- l = l2 = f;
- addlf = 0;
- }
- if (l2 > 0)
- {
- bcopy(buf, ibuf + *ilen, l2);
- *ilen += l2;
- f -= l2;
- buf += l2;
- l -= l2;
- if (f && addlf)
- {
- ibuf[(*ilen)++] = '\n';
- f--;
- }
- }
- }
- *bufpp += *lenp;
- *lenp = 0;
-}
-
-static void
-WinRedisplayLine(y, from, to, isblank)
-int y, from, to, isblank;
-{
- if (y < 0)
- return;
- fore = D_fore;
- DisplayLine(isblank ? &mline_blank : &mline_null, &fore->w_mlines[y],
- y, from, to);
-}
-
-static int
-WinRewrite(y, x1, x2, doit)
-int y, x1, x2, doit;
-{
- register int cost, dx;
- register char *p, *f, *i;
-#ifdef COLOR
- register char *c;
-#endif
-
- fore = D_fore;
- dx = x2 - x1;
- if (doit)
- {
- i = fore->w_mlines[y].image + x1;
- while (dx-- > 0)
- PUTCHAR(*i++);
- return 0;
- }
- p = fore->w_mlines[y].attr + x1;
- f = fore->w_mlines[y].font + x1;
-#ifdef COLOR
- c = fore->w_mlines[y].color + x1;
-#endif
-
- cost = dx = x2 - x1;
- if (D_insert)
- cost += D_EIcost + D_IMcost;
- while(dx-- > 0)
- {
-#ifdef COLOR
- if (*p++ != D_rend.attr || *f++ != D_rend.font || *c++ != D_rend.color)
- return EXPENSIVE;
-#else
- if (*p++ != D_rend.attr || *f++ != D_rend.font)
- return EXPENSIVE;
-#endif
- }
- return cost;
-}
-
-static void
-WinClearLine(y, xs, xe)
-int y, xs, xe;
-{
- fore = D_fore;
- DisplayLine(&fore->w_mlines[y], &mline_blank, y, xs, xe);
-}
-
-static void
-WinSetCursor()
-{
- fore = D_fore;
- GotoPos(fore->w_x, fore->w_y);
-}
-
-static int
-WinResize(wi, he)
-int wi, he;
-{
- fore = D_fore;
- if (fore)
- ChangeWindowSize(fore, wi, he, fore->w_histheight);
- return 0;
-}
-
-static void
-WinRestore()
-{
- fore = D_fore;
- ChangeScrollRegion(fore->w_top, fore->w_bot);
- KeypadMode(fore->w_keypad);
- CursorkeysMode(fore->w_cursorkeys);
- SetFlow(fore->w_flow & FLOW_NOW);
- InsertMode(fore->w_insert);
- ReverseVideo(fore->w_revvid);
- CursorVisibility(fore->w_curinv ? -1 : fore->w_curvvis);
- fore->w_active = 1;
-}
-
-/*
- * Activate - make fore window active
- * norefresh = -1 forces a refresh, disregard all_norefresh then.
- */
void
-Activate(norefresh)
-int norefresh;
+ResetAnsiState(p)
+struct win *p;
{
- debug1("Activate(%d)\n", norefresh);
- if (display == 0)
- return;
- if (D_status)
- {
- Msg(0, "%s", ""); /* wait till mintime (keep gcc quiet) */
- RemoveStatus();
- }
- fore = D_fore;
- if (fore)
- {
- ASSERT(fore->w_display == display);
- fore->w_active = D_layfn == &WinLf;
- if (fore->w_monitor != MON_OFF)
- fore->w_monitor = MON_ON;
- fore->w_bell = BELL_OFF;
- if (ResizeDisplay(fore->w_width, fore->w_height))
- {
- debug2("Cannot resize from (%d,%d)", D_width, D_height);
- debug2(" to (%d,%d) -> resize window\n", fore->w_width, fore->w_height);
- DoResize(D_width, D_height);
- }
- }
- Redisplay(norefresh + all_norefresh);
+ p->w_state = LIT;
+ p->w_StringType = NONE;
}
void
@@ -409,16 +186,47 @@ register struct win *p;
for (i = 8; i < p->w_width; i += 8)
p->w_tabs[i] = 1;
p->w_rend = mchar_null;
+#ifdef FONT
ResetCharsets(p);
+#endif
}
-#ifdef KANJI
+/* adds max 22 bytes */
+int
+GetAnsiStatus(w, buf)
+struct win *w;
+char *buf;
+{
+ char *p = buf;
+
+ if (w->w_state == LIT)
+ return 0;
+
+ strcpy(p, state_t_string[w->w_state]);
+ p += strlen(p);
+ if (w->w_intermediate)
+ {
+ *p++ = '-';
+ if (w->w_intermediate > 0xff)
+ p += AddXChar(p, w->w_intermediate >> 8);
+ p += AddXChar(p, w->w_intermediate & 0xff);
+ }
+ if (w->w_state == ASTR || w->w_state == STRESC)
+ sprintf(p, "-%s", string_t_string[w->w_StringType]);
+ p += strlen(p);
+ return p - buf;
+}
+
+
+#ifdef FONT
+
+# ifdef KANJI
static char *kanjicharsets[3] = {
"BBBB02", /* jis */
"B\002IB01", /* euc */
"BIBB01" /* sjis */
};
-#endif
+# endif
void
ResetCharsets(p)
@@ -458,50 +266,22 @@ char *s;
p->w_FontL = p->w_charsets[p->w_Charset];
p->w_FontR = p->w_charsets[p->w_CharsetR];
}
-
-static void
-FixLine()
-{
- struct mline *ml = &curr->w_mlines[curr->w_y];
- if (curr->w_rend.attr && ml->attr == null)
- {
- if ((ml->attr = (char *)malloc(curr->w_width + 1)) == 0)
- {
- ml->attr = null;
- curr->w_rend.attr = 0;
- Msg(0, "Warning: no space for attr - turned off");
- }
- bzero(ml->attr, curr->w_width + 1);
- }
- if ((curr->w_FontL || curr->w_FontR) && ml->font == null)
- {
- if ((ml->font = (char *)malloc(curr->w_width + 1)) == 0)
- {
- ml->font = null;
- curr->w_FontL = curr->w_charsets[curr->w_ss ? curr->w_ss : curr->w_Charset] = 0;
- curr->w_FontR = curr->w_charsets[curr->w_ss ? curr->w_ss : curr->w_CharsetR] = 0;
- curr->w_rend.font = 0;
- Msg(0, "Warning: no space for font - turned off");
- }
- bzero(ml->font, curr->w_width + 1);
- }
-#ifdef COLOR
- if (curr->w_rend.color && ml->color == null)
- {
- if ((ml->color = (char *)malloc(curr->w_width + 1)) == 0)
- {
- ml->color = null;
- curr->w_rend.color = 0;
- Msg(0, "Warning: no space for color - turned off");
- }
- bzero(ml->color, curr->w_width + 1);
- }
#endif
-}
+
+/*****************************************************************/
/*
* Here comes the vt100 emulator
+ * - writes logfiles,
+ * - sets timestamp and flags activity in window.
+ * - record program output in window scrollback
+ * - translate program output for the display and put it into the obuf.
+ *
+ * Output is only supressed, where obuf is beyond maximum and the flag
+ * nonblock is set. Then we set nonblock from 1 to 2 and output a '~'
+ * character instead. nonblock should be reset to 1 by a successfull
+ * write. Where nonblock isn't set, the obufmax is ignored.
*/
void
WriteString(wp, buf, len)
@@ -509,42 +289,52 @@ struct win *wp;
register char *buf;
register int len;
{
- register int c, font;
+ register int c;
+#ifdef FONT
+ register int font;
+#endif
+ struct canvas *cv;
if (!len)
return;
- if (wp->w_logfp != NULL)
- if ((int)fwrite(buf, len, 1, wp->w_logfp) < 1)
- {
- Msg(errno, "Error writing logfile");
- fclose(wp->w_logfp);
- wp->w_logfp = NULL;
- }
- /*
- * SetCurr() here may prevent output, as it may set display = 0
- */
- SetCurr(wp);
- if (display)
+ if (wp->w_log)
+ LogString(wp, buf, len);
+
+ /* set global variables (yuck!) */
+ curr = wp;
+ cols = curr->w_width;
+ rows = curr->w_height;
+
+ /* The status should be already gone, so this is "Just in Case" */
+ for (cv = wp->w_layer.l_cvlist; cv; cv = cv->c_lnext)
{
- if (D_status && !(use_hardstatus && D_HS))
+ display = cv->c_display;
+ if (D_status == STATUS_ON_WIN)
RemoveStatus();
- }
- else
- {
- if (curr->w_tstamp.seconds)
- curr->w_tstamp.lastio = Now;
-
- if (curr->w_monitor == MON_ON || curr->w_monitor == MON_DONE)
+ if (D_nonblock == 1 && (D_obufp - D_obuf > D_obufmax))
{
- debug2("ACTIVITY %d %d\n", curr->w_monitor, curr->w_bell);
- curr->w_monitor = MON_FOUND;
+ /* one last surprising '~' means: lost data */
+ AddChar('~');
+ /* private flag that prevents more output */
+ D_nonblock = 2;
}
}
+ if (curr->w_silence)
+ SetTimeout(&curr->w_silenceev, curr->w_silencewait * 1000);
+
+ if (curr->w_monitor == MON_ON)
+ {
+ debug2("ACTIVITY %d %d\n", curr->w_monitor, curr->w_bell);
+ curr->w_monitor = MON_FOUND;
+ }
+
do
{
c = (unsigned char)*buf++;
+#ifdef FONT
curr->w_rend.font = curr->w_FontL; /* Default: GL */
+#endif
/* The next part is only for speedup
* (therefore no mchars are used) */
@@ -553,65 +343,40 @@ register int len;
curr->w_FontL != KANJI && curr->w_FontL != KANA && !curr->w_mbcs &&
#endif
c >= ' ' &&
- ((c & 0x80) == 0 || ((c >= 0xa0 || !curr->w_c1) && !curr->w_gr)) &&
- !curr->w_insert && !curr->w_ss && curr->w_x < cols - 1)
+ ((c & 0x80) == 0 || ((c >= 0xa0 || !curr->w_c1) && !curr->w_gr)) && !curr->w_ss &&
+ !curr->w_insert && curr->w_x < cols - 1)
{
register int currx;
- register char *imp, *atp, *fop, at, fo;
+ register char *imp, *atp, at;
+#ifdef FONT
+ register char *fop, fo;
+#endif
#ifdef COLOR
register char *cop, co;
#endif
- register char **xtable = 0;
- register char *c0tab = 0;
if (c == '\177')
continue;
- FixLine();
+ MFixLine(curr, curr->w_y, &curr->w_rend);
currx = curr->w_x;
imp = curr->w_mlines[curr->w_y].image + currx;
atp = curr->w_mlines[curr->w_y].attr + currx;
- fop = curr->w_mlines[curr->w_y].font + currx;
at = curr->w_rend.attr;
+#ifdef FONT
+ fop = curr->w_mlines[curr->w_y].font + currx;
fo = curr->w_rend.font;
+#endif
#ifdef COLOR
cop = curr->w_mlines[curr->w_y].color + currx;
co = curr->w_rend.color;
#endif
- if (display)
- {
- if (D_x != currx || D_y != curr->w_y)
- GotoPos(currx, curr->w_y);
- /* This is not SetRendition because the compiler would
- * not use registers if at/fo/co would be an mchar */
- if (at != D_rend.attr)
- SetAttr(at);
-#ifdef COLOR
- if (co != D_rend.color)
- SetColor(co);
-#endif
- if (fo != D_rend.font)
- SetFont(fo);
- if (D_insert)
- InsertMode(0);
- if (D_xtable)
- xtable = D_xtable[(int)(unsigned char)D_rend.font];
- if (D_rend.font == '0')
- c0tab = D_c0_tab;
- }
while (currx < cols - 1)
{
- if (display)
- {
- if (xtable && xtable[c])
- AddStr(xtable[c]);
- else if (c0tab)
- AddChar(c0tab[c]);
- else
- AddChar(c);
- }
*imp++ = c;
*atp++ = at;
+#ifdef FONT
*fop++ = fo;
+#endif
#ifdef COLOR
*cop++ = co;
#endif
@@ -624,9 +389,12 @@ skip: if (--len == 0)
if (c < ' ' || ((c & 0x80) && ((c < 0xa0 && curr->w_c1) || curr->w_gr)))
break;
}
- curr->w_x = currx;
- if (display)
- D_x = currx;
+ currx -= curr->w_x;
+ if (currx > 0)
+ {
+ LPutStr(&curr->w_layer, imp - currx, currx, &curr->w_rend, curr->w_x, curr->w_y);
+ curr->w_x += currx;
+ }
if (len == 0)
break;
}
@@ -700,10 +468,11 @@ skip: if (--len == 0)
break;
}
/* special xterm hack: accept SetStatus sequence. Yucc! */
+ /* allow ^E for title escapes */
if (!(curr->w_StringType == OSC && c < ' ' && c != '\005'))
if (!curr->w_c1 || c != ('\\' ^ 0xc0))
{
- SaveChar(c);
+ StringChar(c);
break;
}
c = '\\';
@@ -712,76 +481,31 @@ skip: if (--len == 0)
switch (c)
{
case '\\':
- curr->w_state = LIT;
- *curr->w_stringp = '\0';
- switch (curr->w_StringType)
+ if (StringEnd() == 0 || len <= 1)
+ break;
+ /* check if somewhere a status is displayed */
+ for (cv = curr->w_layer.l_cvlist; cv; cv = cv->c_lnext)
{
- case OSC: /* special xterm compatibility hack */
- if (curr->w_stringp - curr->w_string < 2 ||
- curr->w_string[0] < '0' ||
- curr->w_string[0] > '2' ||
- curr->w_string[1] != ';')
- break;
- curr->w_stringp -= 2;
- if (curr->w_stringp > curr->w_string)
- bcopy(curr->w_string + 2, curr->w_string, curr->w_stringp - curr->w_string);
- *curr->w_stringp = '\0';
- /* FALLTHROUGH */
- case APC:
- if (curr->w_hstatus)
- {
- if (strcmp(curr->w_hstatus, curr->w_string) == 0)
- break; /* not changed */
- free(curr->w_hstatus);
- curr->w_hstatus = 0;
- }
- if (curr->w_string != curr->w_stringp)
- curr->w_hstatus = SaveStr(curr->w_string);
- if (display)
- RefreshStatus();
- break;
- case GM:
- {
- struct display *old = display;
- for (display = displays; display; display = display->d_next)
- if (display != old)
- MakeStatus(curr->w_string);
- display = old;
- }
- /*FALLTHROUGH*/
- case PM:
- if (!display)
+ display = cv->c_display;
+ if (D_status == STATUS_ON_WIN)
break;
- MakeStatus(curr->w_string);
- if (D_status && !(use_hardstatus && D_HS) && len > 1)
- {
- curr->w_outlen = len - 1;
- bcopy(buf, curr->w_outbuf, curr->w_outlen);
- return;
- }
- break;
- case DCS:
- if (display)
- AddStr(curr->w_string);
- break;
- case AKA:
- if (curr->w_title == curr->w_akabuf && !*curr->w_string)
- break;
- ChangeAKA(curr, curr->w_string, 20);
- if (!*curr->w_string)
- curr->w_autoaka = curr->w_y + 1;
- break;
- default:
- break;
+ }
+ if (cv)
+ {
+ if (len > IOSIZE + 1)
+ len = IOSIZE + 1;
+ curr->w_outlen = len - 1;
+ bcopy(buf, curr->w_outbuf, len - 1);
+ return; /* wait till status is gone */
}
break;
case '\033':
- SaveChar('\033');
+ StringChar('\033');
break;
default:
curr->w_state = ASTR;
- SaveChar('\033');
- SaveChar(c);
+ StringChar('\033');
+ StringChar(c);
break;
}
break;
@@ -795,23 +519,23 @@ skip: if (--len == 0)
curr->w_state = CSI;
break;
case ']':
- StartString(OSC);
+ StringStart(OSC);
break;
case '_':
- StartString(APC);
+ StringStart(APC);
break;
case 'P':
- StartString(DCS);
+ StringStart(DCS);
break;
case '^':
- StartString(PM);
+ StringStart(PM);
break;
case '!':
- StartString(GM);
+ StringStart(GM);
break;
case '"':
case 'k':
- StartString(AKA);
+ StringStart(AKA);
break;
default:
if (Special(c))
@@ -823,12 +547,14 @@ skip: if (--len == 0)
if (c >= ' ' && c <= '/')
{
if (curr->w_intermediate)
+ {
#ifdef KANJI
- if (curr->w_intermediate == '$')
- c |= '$' << 8;
- else
+ if (curr->w_intermediate == '$')
+ c |= '$' << 8;
+ else
#endif
- c = -1;
+ c = -1;
+ }
curr->w_intermediate = c;
}
else if (c >= '0' && c <= '~')
@@ -879,14 +605,16 @@ skip: if (--len == 0)
break;
case LIT:
default:
+#ifdef KANJI
+ if (c <= ' ' || c == 0x7f || (c >= 0x80 && c < 0xa0 && curr->w_c1))
+ curr->w_mbcs = 0;
+#endif
if (c < ' ')
{
if (c == '\033')
{
curr->w_intermediate = 0;
curr->w_state = ESC;
- if (display && D_lp_missing && (D_CIC || D_IC || D_IM))
- UpdateLine(&mline_blank, D_bot, cols - 2, cols - 1);
if (curr->w_autoaka < 0)
curr->w_autoaka = 0;
}
@@ -902,13 +630,11 @@ skip: if (--len == 0)
case 0xc0 ^ 'E':
case 0xc0 ^ 'H':
case 0xc0 ^ 'M':
- case 0xc0 ^ 'N':
- case 0xc0 ^ 'O':
+ case 0xc0 ^ 'N': /* SS2 */
+ case 0xc0 ^ 'O': /* SS3 */
DoESC(c ^ 0xc0, 0);
break;
case 0xc0 ^ '[':
- if (display && D_lp_missing && (D_CIC || D_IC || D_IM))
- UpdateLine(&mline_blank, D_bot, cols - 2, cols - 1);
if (curr->w_autoaka < 0)
curr->w_autoaka = 0;
curr->w_NumArgs = 0;
@@ -917,7 +643,7 @@ skip: if (--len == 0)
curr->w_state = CSI;
break;
case 0xc0 ^ 'P':
- StartString(DCS);
+ StringStart(DCS);
break;
default:
break;
@@ -925,8 +651,9 @@ skip: if (--len == 0)
break;
}
+#ifdef FONT
font = curr->w_rend.font = (c >= 0x80 ? curr->w_FontR : curr->w_FontL);
-#ifdef KANJI
+# ifdef KANJI
if (font == KANA && curr->w_kanji == SJIS && curr->w_mbcs == 0)
{
/* Lets see if it is the first byte of a kanji */
@@ -938,6 +665,8 @@ skip: if (--len == 0)
break;
}
}
+ if (font == KANJI && c == ' ')
+ font = curr->w_rend.font = 0;
if (font == KANJI || curr->w_mbcs)
{
int t = c;
@@ -985,108 +714,93 @@ skip: if (--len == 0)
curr->w_mbcs = t;
}
kanjiloop:
-#endif
+# endif
if (curr->w_gr)
{
c &= 0x7f;
if (c < ' ') /* this is ugly but kanji support */
goto tryagain; /* prevents nicer programming */
}
+#endif /* FONT */
if (c == '\177')
break;
- if (display)
- SetRendition(&curr->w_rend);
+ curr->w_rend.image = c;
if (curr->w_x < cols - 1)
{
if (curr->w_insert)
InsertAChar(c);
else
{
- if (display)
- PUTCHAR(c);
- SetChar(c);
+ MPutChar(curr, &curr->w_rend, curr->w_x, curr->w_y);
+ LPutChar(&curr->w_layer, &curr->w_rend, curr->w_x, curr->w_y);
curr->w_x++;
}
}
else if (curr->w_x == cols - 1)
{
- if (display && curr->w_wrap && (D_CLP || !force_vt || D_COP))
- {
- RAW_PUTCHAR(c); /* don't care about D_insert */
- SetChar(c);
- curr->w_x++;
- if (D_AM && !D_CLP)
- {
- SetChar(0);
- LineFeed(0); /* terminal auto-wrapped */
- }
- }
- else
- {
- if (display)
- {
- if (D_CLP || curr->w_y != D_bot)
- {
- RAW_PUTCHAR(c);
- GotoPos(curr->w_x, curr->w_y);
- }
- else
- CheckLP(c);
- }
- SetChar(c);
- if (curr->w_wrap)
- curr->w_x++;
- }
+ MPutChar(curr, &curr->w_rend, curr->w_x, curr->w_y);
+ LPutChar(&curr->w_layer, &curr->w_rend, curr->w_x, curr->w_y);
+ if (curr->w_wrap)
+ curr->w_x++;
}
- else /* curr->w_x > cols - 1 */
+ else
{
- SetChar(0); /* we wrapped */
- if (curr->w_insert)
- {
- LineFeed(2); /* cr+lf, handle LP */
- InsertAChar(c);
- }
- else
- {
- if (display && D_AM && D_x != cols) /* write char again */
- {
- SetRenditionMline(&curr->w_mlines[curr->w_y], cols - 1);
- RAW_PUTCHAR(curr->w_mlines[curr->w_y].image[cols - 1]);
- SetRendition(&curr->w_rend);
- if (curr->w_y == D_bot)
- D_lp_missing = 0; /* just wrote it */
- }
- LineFeed((display == 0 || D_AM) ? 0 : 2);
- if (display)
- PUTCHAR(c);
- SetChar(c);
- curr->w_x = 1;
- }
+ MWrapChar(curr, &curr->w_rend, curr->w_y, curr->w_top, curr->w_bot, curr->w_insert);
+ LWrapChar(&curr->w_layer, &curr->w_rend, curr->w_y, curr->w_top, curr->w_bot, curr->w_insert);
+ if (curr->w_y != curr->w_bot && curr->w_y != curr->w_height - 1)
+ curr->w_y++;
+ curr->w_x = 1;
}
-#ifdef KANJI
+#ifdef FONT
+# ifdef KANJI
if (curr->w_mbcs)
{
c = curr->w_mbcs;
curr->w_mbcs = 0;
goto kanjiloop; /* what a hack! */
}
-#endif
+# endif
if (curr->w_ss)
{
curr->w_FontL = curr->w_charsets[curr->w_Charset];
curr->w_FontR = curr->w_charsets[curr->w_CharsetR];
- SetFont(curr->w_FontL);
+ curr->w_rend.font = curr->w_FontL;
+ LSetRendition(&curr->w_layer, &curr->w_rend);
curr->w_ss = 0;
}
+#endif /* FONT */
break;
}
}
while (--len);
- curr->w_outlen = 0;
- if (curr->w_state == PRIN)
+ if (!printcmd && curr->w_state == PRIN)
PrintFlush();
}
+static void
+LogString(p, buf, len)
+struct win *p;
+char *buf;
+int len;
+{
+ if (!p->w_log)
+ return;
+ if (logtstamp_on && p->w_logsilence >= logtstamp_after * 2)
+ {
+ char *t = MakeWinMsg(logtstamp_string, p, '%');
+ logfwrite(p->w_log, t, strlen(t)); /* long time no write */
+ }
+ p->w_logsilence = 0;
+ if (logfwrite(p->w_log, buf, len) < 1)
+ {
+ WMsg(p, errno, "Error writing logfile");
+ logfclose(p->w_log);
+ p->w_log = 0;
+ }
+ if (!log_flush)
+ logfflush(p->w_log);
+}
+
static int
Special(c)
register int c;
@@ -1105,30 +819,19 @@ register int c;
LineFeed(1);
return 1;
case '\007':
- if (display == 0)
- curr->w_bell = BELL_ON;
- else
- {
- if (!visual_bell)
- PutStr(D_BL);
- else
- {
- if (!D_VB)
- curr->w_bell = BELL_VISUAL;
- else
- PutStr(D_VB);
- }
- }
+ WBell(curr, visual_bell);
return 1;
case '\t':
ForwardTab();
return 1;
+#ifdef FONT
case '\017': /* SI */
MapCharset(G0);
return 1;
case '\016': /* SO */
MapCharset(G1);
return 1;
+#endif
}
return 0;
}
@@ -1167,24 +870,30 @@ int c, intermediate;
case 'c':
ClearScreen();
ResetWindow(curr);
+ LKeypadMode(&curr->w_layer, 0);
+ LCursorkeysMode(&curr->w_layer, 0);
+#ifndef TIOCPKT
+ NewAutoFlow(curr, 1);
+#endif
+ /* XXX
SetRendition(&mchar_null);
InsertMode(0);
- KeypadMode(0);
- CursorkeysMode(0);
ChangeScrollRegion(0, rows - 1);
+ */
break;
case '=':
- KeypadMode(curr->w_keypad = 1);
+ LKeypadMode(&curr->w_layer, curr->w_keypad = 1);
#ifndef TIOCPKT
NewAutoFlow(curr, 0);
#endif /* !TIOCPKT */
break;
case '>':
- KeypadMode(curr->w_keypad = 0);
+ LKeypadMode(&curr->w_layer, curr->w_keypad = 0);
#ifndef TIOCPKT
NewAutoFlow(curr, 1);
#endif /* !TIOCPKT */
break;
+#ifdef FONT
case 'n': /* LS2 */
MapCharset(G2);
break;
@@ -1194,6 +903,7 @@ int c, intermediate;
case '~':
MapCharsetR(G1); /* LS1R */
break;
+ /* { */
case '}':
MapCharsetR(G2); /* LS2R */
break;
@@ -1203,7 +913,7 @@ int c, intermediate;
case 'N': /* SS2 */
if (curr->w_charsets[curr->w_Charset] != curr->w_charsets[G2]
|| curr->w_charsets[curr->w_CharsetR] != curr->w_charsets[G2])
- curr->w_FontR = curr->w_FontL = curr->w_charsets[curr->w_ss = G2];
+ curr->w_FontR = curr->w_FontL = curr->w_charsets[curr->w_ss = G2];
else
curr->w_ss = 0;
break;
@@ -1214,13 +924,9 @@ int c, intermediate;
else
curr->w_ss = 0;
break;
+#endif /* FONT */
case 'g': /* VBELL, private screen sequence */
- if (display == 0)
- curr->w_bell = BELL_ON;
- else if (!D_VB)
- curr->w_bell = BELL_VISUAL;
- else
- PutStr(D_VB);
+ WBell(curr, 1);
break;
}
break;
@@ -1232,6 +938,7 @@ int c, intermediate;
break;
}
break;
+#ifdef FONT
case '(':
DesignateCharset(c, G0);
break;
@@ -1244,7 +951,7 @@ int c, intermediate;
case '+':
DesignateCharset(c, G3);
break;
-#ifdef KANJI
+# ifdef KANJI
/*
* ESC $ ( Fn: invoke multi-byte charset, Fn, to G0
* ESC $ Fn: same as above. (old sequence)
@@ -1265,7 +972,8 @@ int c, intermediate;
case '$'<<8 | '+':
DesignateCharset(c & 037, G3);
break;
-#endif
+# endif
+#endif /* FONT */
}
}
@@ -1294,7 +1002,7 @@ int c, intermediate;
a2 = 1;
if (a2 > cols)
a2 = cols;
- GotoPos(--a2, --a1);
+ LGotoPos(&curr->w_layer, --a2, --a1);
curr->w_x = a2;
curr->w_y = a1;
if (curr->w_autoaka)
@@ -1313,7 +1021,7 @@ int c, intermediate;
break;
case 2:
ClearScreen();
- GotoPos(curr->w_x, curr->w_y);
+ LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
break;
}
break;
@@ -1323,16 +1031,20 @@ int c, intermediate;
switch (a1)
{
case 0:
- ClearToEOL();
+ ClearLineRegion(curr->w_x, cols - 1);
break;
case 1:
- ClearFromBOL();
+ ClearLineRegion(0, curr->w_x);
break;
case 2:
- ClearFullLine();
+ ClearLineRegion(0, cols - 1);
break;
}
break;
+ case 'X':
+ a1 = curr->w_x + (a1 ? a1 - 1 : 0);
+ ClearLineRegion(curr->w_x, a1 < cols ? a1 : cols - 1);
+ break;
case 'A':
CursorUp(a1 ? a1 : 1);
break;
@@ -1345,6 +1057,27 @@ int c, intermediate;
case 'D':
CursorLeft(a1 ? a1 : 1);
break;
+ case 'E':
+ curr->w_x = 0;
+ CursorDown(a1 ? a1 : 1); /* positions cursor */
+ break;
+ case 'F':
+ curr->w_x = 0;
+ CursorUp(a1 ? a1 : 1); /* positions cursor */
+ break;
+ case 'G':
+ case '`': /* HPA */
+ curr->w_x = a1 ? a1 - 1 : 0;
+ if (curr->w_x >= cols)
+ curr->w_x = cols - 1;
+ LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
+ break;
+ case 'd': /* VPA */
+ curr->w_y = a1 ? a1 - 1 : 0;
+ if (curr->w_y >= rows)
+ curr->w_y = rows - 1;
+ LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
+ break;
case 'm':
SelectRendition();
break;
@@ -1363,18 +1096,15 @@ int c, intermediate;
break;
curr->w_top = a1 - 1;
curr->w_bot = a2 - 1;
- ChangeScrollRegion(curr->w_top, curr->w_bot);
+ /* ChangeScrollRegion(curr->w_top, curr->w_bot); */
if (curr->w_origin)
{
- GotoPos(0, curr->w_top);
curr->w_y = curr->w_top;
curr->w_x = 0;
}
else
- {
- GotoPos(0, 0);
- curr->w_y = curr->w_x = 0;
- }
+ curr->w_y = curr->w_x = 0;
+ LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
break;
case 's':
SaveCursor();
@@ -1387,18 +1117,9 @@ int c, intermediate;
a1 = curr->w_width;
if (a2 < 1)
a2 = curr->w_height;
- if (display && D_CWS == NULL)
- {
- a2 = curr->w_height;
- if (D_CZ0 == NULL || (a1 != Z0width && a1 != Z1width))
- a1 = curr->w_width;
- }
- if (a1 == curr->w_width && a2 == curr->w_height)
- break;
- ChangeWindowSize(curr, a1, a2, curr->w_histheight);
- SetCurr(curr);
- if (display)
- Activate(0);
+ WChangeSize(curr, a1, a2);
+ cols = curr->w_width;
+ rows = curr->w_height;
break;
case 'u':
RestoreCursor();
@@ -1433,15 +1154,9 @@ int c, intermediate;
case 'l':
ASetMode(0);
break;
- case 'i':
- {
- struct display *odisplay = display;
- if (display == 0 && displays && displays->d_next == 0)
- display = displays;
- if (display && a1 == 5)
- PrintStart();
- display = odisplay;
- }
+ case 'i': /* MC Media Control */
+ if (a1 == 5)
+ PrintStart();
break;
case 'n':
if (a1 == 5) /* Report terminal status */
@@ -1461,13 +1176,14 @@ int c, intermediate;
if (a1 == 6 || a1 == 7)
{
curr->w_curinv = 7 - a1;
- CursorVisibility(curr->w_curinv ? -1 : curr->w_curvvis);
+ LCursorVisibility(&curr->w_layer, curr->w_curinv ? -1 : curr->w_curvvis);
}
break;
- case 'S': /* obscure code from a 97801 term */
+ case 'S': /* code from a 97801 term / DEC vt400 */
ScrollRegion(a1 ? a1 : 1);
break;
- case 'T': /* obscure code from a 97801 term */
+ case 'T': /* code from a 97801 term / DEC vt400 */
+ case '^': /* SD as per ISO 6429 */
ScrollRegion(a1 ? -a1 : -1);
break;
}
@@ -1483,7 +1199,7 @@ int c, intermediate;
switch (a1)
{
case 1: /* CKM: cursor key mode */
- CursorkeysMode(curr->w_cursorkeys = i);
+ LCursorkeysMode(&curr->w_layer, curr->w_cursorkeys = i);
#ifndef TIOCPKT
NewAutoFlow(curr, !i);
#endif /* !TIOCPKT */
@@ -1491,50 +1207,30 @@ int c, intermediate;
case 2: /* ANM: ansi/vt52 mode */
if (i)
{
-#ifdef KANJI
+#ifdef FONT
+# ifdef KANJI
if (curr->w_kanji)
break;
-#endif
+# endif
curr->w_charsets[0] = curr->w_charsets[1] =
curr->w_charsets[2] = curr->w_charsets[2] =
curr->w_FontL = curr->w_FontR = ASCII;
curr->w_Charset = 0;
curr->w_CharsetR = 2;
curr->w_ss = 0;
+#endif
}
break;
case 3: /* COLM: column mode */
i = (i ? Z0width : Z1width);
- if (curr->w_width != i && (display == 0 || (D_CZ0 || D_CWS)))
- {
- ChangeWindowSize(curr, i, curr->w_height, curr->w_histheight);
- SetCurr(curr); /* update rows/cols */
- if (display)
- Activate(0);
- }
+ WChangeSize(curr, i, curr->w_height);
+ cols = curr->w_width;
+ rows = curr->w_height;
break;
/* case 4: SCLM: scrolling mode */
case 5: /* SCNM: screen mode */
- /* This should be reverse video.
- * Because it is used in some termcaps to emulate
- * a visual bell we do this hack here.
- * (screen uses \Eg as special vbell sequence)
- */
- if (i)
- ReverseVideo(1);
- else
- {
- if (display && D_CVR)
- ReverseVideo(0);
- else
- if (curr->w_revvid)
- {
- if (display && D_VB)
- PutStr(D_VB);
- else
- curr->w_bell = BELL_VISUAL;
- }
- }
+ if (i != curr->w_revvid)
+ WReverseVideo(curr, i);
curr->w_revvid = i;
break;
case 6: /* OM: origin mode */
@@ -1545,8 +1241,7 @@ int c, intermediate;
}
else
curr->w_y = curr->w_x = 0;
- if (display)
- GotoPos(curr->w_x, curr->w_y);
+ LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
break;
case 7: /* AWM: auto wrap mode */
curr->w_wrap = i;
@@ -1558,13 +1253,21 @@ int c, intermediate;
/* case 13: SCFDM: space compression / field delimiting */
/* case 14: TEM: transmit execution mode */
/* case 16: EKEM: edit key execution mode */
+ /* case 18: PFF: Printer term form feed */
+ /* case 19: PEX: Printer extend screen / scroll. reg */
case 25: /* TCEM: text cursor enable mode */
curr->w_curinv = !i;
- CursorVisibility(curr->w_curinv ? -1 : curr->w_curvvis);
+ LCursorVisibility(&curr->w_layer, curr->w_curinv ? -1 : curr->w_curvvis);
break;
- /* case 40: 132 col enable */
+ /* case 34: RLM: Right to left mode */
+ /* case 35: HEBM: hebrew keyboard map */
+ /* case 36: HEM: hebrew encoding */
+ /* case 38: TeK Mode */
+ /* case 40: 132 col enable */
/* case 42: NRCM: 7bit NRC character mode */
- /* case 44: margin bell enable */
+ /* case 44: margin bell enable */
+ /* case 66: NKM: Numeric keypad appl mode */
+ /* case 68: KBUM: Keyboard usage mode (data process) */
}
}
break;
@@ -1581,25 +1284,8 @@ int c, intermediate;
}
-/*
- * Store char in mline. Be sure, that w_Font is set correctly!
- */
-
-static void
-SetChar(c)
-register int c;
-{
- register struct win *p = curr;
- register struct mline *ml;
-
- FixLine();
- ml = &p->w_mlines[p->w_y];
- p->w_rend.image = c;
- copy_mchar2mline(&p->w_rend, ml, p->w_x);
-}
-
static void
-StartString(type)
+StringStart(type)
enum string_t type;
{
curr->w_StringType = type;
@@ -1608,7 +1294,7 @@ enum string_t type;
}
static void
-SaveChar(c)
+StringChar(c)
int c;
{
if (curr->w_stringp >= curr->w_string + MAXSTR - 1)
@@ -1617,44 +1303,99 @@ int c;
*(curr->w_stringp)++ = c;
}
+/*
+ * Do string processing. Returns -1 if output should be suspended
+ * until status is gone.
+ */
+static int
+StringEnd()
+{
+ struct canvas *cv;
+
+ curr->w_state = LIT;
+ *curr->w_stringp = '\0';
+ switch (curr->w_StringType)
+ {
+ case OSC: /* special xterm compatibility hack */
+ if (curr->w_stringp - curr->w_string < 2 ||
+ curr->w_string[0] < '0' ||
+ curr->w_string[0] > '2' ||
+ curr->w_string[1] != ';')
+ break;
+ curr->w_stringp -= 2;
+ if (curr->w_stringp > curr->w_string)
+ bcopy(curr->w_string + 2, curr->w_string, curr->w_stringp - curr->w_string);
+ *curr->w_stringp = '\0';
+ /* FALLTHROUGH */
+ case APC:
+ if (curr->w_hstatus)
+ {
+ if (strcmp(curr->w_hstatus, curr->w_string) == 0)
+ break; /* not changed */
+ free(curr->w_hstatus);
+ curr->w_hstatus = 0;
+ }
+ if (curr->w_string != curr->w_stringp)
+ curr->w_hstatus = SaveStr(curr->w_string);
+ WindowChanged(curr, 'h');
+ break;
+ case PM:
+ case GM:
+ for (display = displays; display; display = display->d_next)
+ {
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ if (cv->c_layer->l_bottom == &curr->w_layer)
+ break;
+ if (cv || curr->w_StringType == GM)
+ MakeStatus(curr->w_string);
+ }
+ return -1;
+ case DCS:
+ LAY_DISPLAYS(&curr->w_layer, AddStr(curr->w_string));
+ break;
+ case AKA:
+ if (curr->w_title == curr->w_akabuf && !*curr->w_string)
+ break;
+ ChangeAKA(curr, curr->w_string, 20);
+ if (!*curr->w_string)
+ curr->w_autoaka = curr->w_y + 1;
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
static void
PrintStart()
{
- int pi[2];
+ curr->w_pdisplay = 0;
- if (printcmd == 0 && D_PO == 0)
- return;
+ /* find us a nice display to print on, fore prefered */
+ for (display = displays; display; display = display->d_next)
+ if (curr == D_fore && (printcmd || D_PO))
+ break;
+ if (!display)
+ {
+ struct canvas *cv;
+ for (cv = curr->w_layer.l_cvlist; cv; cv = cv->c_lnext)
+ {
+ display = cv->c_display;
+ if (printcmd || D_PO)
+ break;
+ }
+ if (!cv)
+ {
+ display = displays;
+ if (!display || display->d_next || !(printcmd || D_PO))
+ return;
+ }
+ }
curr->w_pdisplay = display;
curr->w_stringp = curr->w_string;
curr->w_state = PRIN;
- if (printcmd == 0 || curr->w_pdisplay->d_printfd >= 0)
- return;
- if (pipe(pi))
- {
- Msg(errno, "printing pipe");
- return;
- }
- switch (fork())
- {
- case -1:
- Msg(errno, "printing fork");
- return;
- case 0:
- close(0);
- dup(pi[0]);
- closeallfiles(0);
- if (setuid(real_uid) || setgid(real_gid))
- _exit(1);
-#ifdef SIGPIPE
- signal(SIGPIPE, SIG_DFL);
-#endif
- execl("/bin/sh", "sh", "-c", printcmd, 0);
- _exit(1);
- default:
- break;
- }
- close(pi[0]);
- curr->w_pdisplay->d_printfd = pi[1];
+ if (printcmd && curr->w_pdisplay->d_printfd < 0)
+ curr->w_pdisplay->d_printfd = printpipe(curr, printcmd);
}
static void
@@ -1669,8 +1410,6 @@ int c;
static void
PrintFlush()
{
- struct display *odisp = display;
-
display = curr->w_pdisplay;
if (display && printcmd)
{
@@ -1682,7 +1421,7 @@ PrintFlush()
r = write(display->d_printfd, bp, len);
if (r <= 0)
{
- Msg(errno, "printing aborted");
+ WMsg(curr, errno, "printing aborted");
close(display->d_printfd);
display->d_printfd = -1;
break;
@@ -1699,7 +1438,6 @@ PrintFlush()
Flush();
}
curr->w_stringp = curr->w_string;
- display = odisp;
}
@@ -1709,31 +1447,36 @@ struct win *win;
int on;
{
debug1("NewAutoFlow: %d\n", on);
- SetCurr(win);
if (win->w_flow & FLOW_AUTOFLAG)
win->w_flow = FLOW_AUTOFLAG | (FLOW_AUTO|FLOW_NOW) * on;
else
win->w_flow = (win->w_flow & ~FLOW_AUTO) | FLOW_AUTO * on;
- if (display)
- SetFlow(win->w_flow & FLOW_NOW);
+ LSetFlow(&win->w_layer, win->w_flow & FLOW_NOW);
}
+
+#ifdef FONT
+
static void
DesignateCharset(c, n)
int c, n;
{
curr->w_ss = 0;
-#ifdef KANJI
+# ifdef KANJI
if (c == ('@' & 037))
c = KANJI;
-#endif
+# endif
if (c == 'B' || c == 'J')
c = ASCII;
if (curr->w_charsets[n] != c)
{
curr->w_charsets[n] = c;
if (curr->w_Charset == n)
- SetFont(curr->w_FontL = c);
+ {
+ curr->w_FontL = c;
+ curr->w_rend.font = curr->w_FontL;
+ LSetRendition(&curr->w_layer, &curr->w_rend);
+ }
if (curr->w_CharsetR == n)
curr->w_FontR = c;
}
@@ -1747,7 +1490,9 @@ int n;
if (curr->w_Charset != n)
{
curr->w_Charset = n;
- SetFont(curr->w_FontL = curr->w_charsets[n]);
+ curr->w_FontL = curr->w_charsets[n];
+ curr->w_rend.font = curr->w_FontL;
+ LSetRendition(&curr->w_layer, &curr->w_rend);
}
}
@@ -1764,6 +1509,8 @@ int n;
curr->w_gr = 1;
}
+#endif /* FONT */
+
static void
SaveCursor()
{
@@ -1771,30 +1518,33 @@ SaveCursor()
curr->w_Saved_x = curr->w_x;
curr->w_Saved_y = curr->w_y;
curr->w_SavedRend= curr->w_rend;
+#ifdef FONT
curr->w_SavedCharset = curr->w_Charset;
curr->w_SavedCharsetR = curr->w_CharsetR;
bcopy((char *) curr->w_charsets, (char *) curr->w_SavedCharsets,
4 * sizeof(int));
+#endif
}
static void
RestoreCursor()
{
- if (curr->w_saved)
- {
- GotoPos(curr->w_Saved_x, curr->w_Saved_y);
- curr->w_x = curr->w_Saved_x;
- curr->w_y = curr->w_Saved_y;
- curr->w_rend = curr->w_SavedRend;
- bcopy((char *) curr->w_SavedCharsets, (char *) curr->w_charsets,
- 4 * sizeof(int));
- curr->w_Charset = curr->w_SavedCharset;
- curr->w_CharsetR = curr->w_SavedCharsetR;
- curr->w_ss = 0;
- curr->w_FontL = curr->w_charsets[curr->w_Charset];
- curr->w_FontR = curr->w_charsets[curr->w_CharsetR];
- SetRendition(&curr->w_rend);
- }
+ if (!curr->w_saved)
+ return;
+ LGotoPos(&curr->w_layer, curr->w_Saved_x, curr->w_Saved_y);
+ curr->w_x = curr->w_Saved_x;
+ curr->w_y = curr->w_Saved_y;
+ curr->w_rend = curr->w_SavedRend;
+#ifdef FONT
+ bcopy((char *) curr->w_SavedCharsets, (char *) curr->w_charsets,
+ 4 * sizeof(int));
+ curr->w_Charset = curr->w_SavedCharset;
+ curr->w_CharsetR = curr->w_SavedCharsetR;
+ curr->w_ss = 0;
+ curr->w_FontL = curr->w_charsets[curr->w_Charset];
+ curr->w_FontR = curr->w_charsets[curr->w_CharsetR];
+#endif
+ LSetRendition(&curr->w_layer, &curr->w_rend);
}
static void
@@ -1809,19 +1559,16 @@ BackSpace()
curr->w_x = cols - 1;
curr->w_y--;
}
- if (display)
- GotoPos(curr->w_x, curr->w_y);
+ LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
}
static void
Return()
{
- if (curr->w_x > 0)
- {
- curr->w_x = 0;
- if (display)
- GotoPos(curr->w_x, curr->w_y);
- }
+ if (curr->w_x == 0)
+ return;
+ curr->w_x = 0;
+ LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
}
static void
@@ -1835,17 +1582,17 @@ int out_mode;
{
if (curr->w_y < rows-1)
curr->w_y++;
- if (out_mode && display)
- GotoPos(curr->w_x, curr->w_y);
+ if (out_mode)
+ LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
return;
}
- ScrollUpMap(1);
+ MScrollV(curr, 1, curr->w_top, curr->w_bot);
if (curr->w_autoaka > 1)
curr->w_autoaka--;
- if (out_mode && display)
+ if (out_mode)
{
- ScrollV(0, curr->w_top, cols - 1, curr->w_bot, 1);
- GotoPos(curr->w_x, curr->w_y);
+ LScrollV(&curr->w_layer, 1, curr->w_top, curr->w_bot);
+ LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
}
}
@@ -1854,11 +1601,9 @@ ReverseLineFeed()
{
if (curr->w_y == curr->w_top)
{
- ScrollDownMap(1);
- if (!display)
- return;
- ScrollV(0, curr->w_top, cols - 1, curr->w_bot, -1);
- GotoPos(curr->w_x, curr->w_y);
+ MScrollV(curr, -1, curr->w_top, curr->w_bot);
+ LScrollV(&curr->w_layer, -1, curr->w_top, curr->w_bot);
+ LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
}
else if (curr->w_y > 0)
CursorUp(1);
@@ -1870,24 +1615,11 @@ int c;
{
register int y = curr->w_y, x = curr->w_x;
- if (x == cols)
- x--;
save_mline(&curr->w_mlines[y], cols);
- if (cols - x - 1 > 0)
- bcopy_mline(&curr->w_mlines[y], x, x + 1, cols - x - 1);
- SetChar(c);
+ curr->w_rend.image = c;
+ MInsChar(curr, &curr->w_rend, x, y);
curr->w_x = x + 1;
- if (!display)
- return;
- if (D_CIC || D_IC || D_IM)
- {
- InsertMode(curr->w_insert);
- INSERTCHAR(c);
- if (y == D_bot)
- D_lp_missing = 0;
- }
- else
- UpdateLine(&mline_old, y, x, cols - 1);
+ LInsChar(&curr->w_layer, &curr->w_rend, x, y, &mline_old);
}
static void
@@ -1901,16 +1633,9 @@ int n;
if (x == cols)
x--;
save_mline(&curr->w_mlines[y], cols);
- if (n >= cols - x)
- n = cols - x;
- else
- bcopy_mline(&curr->w_mlines[y], x, x + n, cols - x - n);
-
- ClearInLine(y, x, x + n - 1);
- if (!display)
- return;
- ScrollH(y, x, curr->w_width - 1, -n, &mline_old);
- GotoPos(x, y);
+ MScrollH(curr, -n, y, x, curr->w_width - 1);
+ LScrollH(&curr->w_layer, -n, y, x, curr->w_width - 1, &mline_old);
+ LGotoPos(&curr->w_layer, x, y);
}
static void
@@ -1922,137 +1647,46 @@ int n;
if (x == cols)
x--;
save_mline(&curr->w_mlines[y], cols);
-
- if (n >= cols - x)
- n = cols - x;
- else
- bcopy_mline(&curr->w_mlines[y], x + n, x, cols - x - n);
- ClearInLine(y, cols - n, cols - 1);
- if (!display)
- return;
- ScrollH(y, x, curr->w_width - 1, n, &mline_old);
- GotoPos(x, y);
+ MScrollH(curr, n, y, x, curr->w_width - 1);
+ LScrollH(&curr->w_layer, n, y, x, curr->w_width - 1, &mline_old);
+ LGotoPos(&curr->w_layer, x, y);
}
static void
DeleteLine(n)
int n;
{
- register int old = curr->w_top;
-
if (curr->w_y < curr->w_top || curr->w_y > curr->w_bot)
return;
if (n > curr->w_bot - curr->w_y + 1)
n = curr->w_bot - curr->w_y + 1;
- curr->w_top = curr->w_y;
- ScrollUpMap(n);
- curr->w_top = old;
- if (!display)
- return;
- ScrollV(0, curr->w_y, cols - 1, curr->w_bot, n);
- GotoPos(curr->w_x, curr->w_y);
+ MScrollV(curr, n, curr->w_y, curr->w_bot);
+ LScrollV(&curr->w_layer, n, curr->w_y, curr->w_bot);
+ LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
}
static void
InsertLine(n)
int n;
{
- register int old = curr->w_top;
-
if (curr->w_y < curr->w_top || curr->w_y > curr->w_bot)
return;
if (n > curr->w_bot - curr->w_y + 1)
n = curr->w_bot - curr->w_y + 1;
- curr->w_top = curr->w_y;
- ScrollDownMap(n);
- curr->w_top = old;
- if (!display)
- return;
- ScrollV(0, curr->w_y, cols - 1, curr->w_bot, -n);
- GotoPos(curr->w_x, curr->w_y);
+ MScrollV(curr, -n, curr->w_y, curr->w_bot);
+ LScrollV(&curr->w_layer, -n, curr->w_y, curr->w_bot);
+ LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
}
static void
ScrollRegion(n)
int n;
{
- if (n > 0)
- ScrollUpMap(n);
- else
- ScrollDownMap(-n);
- if (!display)
- return;
- ScrollV(0, curr->w_top, cols - 1, curr->w_bot, n);
- GotoPos(curr->w_x, curr->w_y);
-}
-
-static void
-ScrollUpMap(n)
-int n;
-{
- char tmp[256 * sizeof(struct mline)];
- register int i, cnt1, cnt2;
- struct mline *ml;
-#ifdef COPY_PASTE
- register int ii;
-#endif
-
- i = curr->w_top + n;
- cnt1 = n * sizeof(struct mline);
- cnt2 = (curr->w_bot - i + 1) * sizeof(struct mline);
-#ifdef COPY_PASTE
- for(ii = curr->w_top; ii < i; ii++)
- AddLineToHist(curr, &curr->w_mlines[ii]);
-#endif
- ml = curr->w_mlines + i;
- for (i = n; i; --i)
- {
- --ml;
- clear_mline(ml, 0, cols + 1);
- }
- Scroll((char *) ml, cnt1, cnt2, tmp);
+ MScrollV(curr, n, curr->w_top, curr->w_bot);
+ LScrollV(&curr->w_layer, n, curr->w_top, curr->w_bot);
+ LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
}
-static void
-ScrollDownMap(n)
-int n;
-{
- char tmp[256 * sizeof(struct mline)];
- register int i, cnt1, cnt2;
- struct mline *ml;
-
- i = curr->w_top;
- cnt1 = (curr->w_bot - i - n + 1) * sizeof(struct mline);
- cnt2 = n * sizeof(struct mline);
- ml = curr->w_mlines + i;
- Scroll((char *) ml, cnt1, cnt2, tmp);
- for (i = n; i; --i)
- {
- clear_mline(ml, 0, cols + 1);
- ml++;
- }
-}
-
-static void
-Scroll(cp, cnt1, cnt2, tmp)
-char *cp, *tmp;
-int cnt1, cnt2;
-{
- if (!cnt1 || !cnt2)
- return;
- if (cnt1 <= cnt2)
- {
- bcopy(cp, tmp, cnt1);
- bcopy(cp + cnt1, cp, cnt2);
- bcopy(tmp, cp + cnt2, cnt1);
- }
- else
- {
- bcopy(cp + cnt1, tmp, cnt2);
- bcopy(cp, cp + cnt2, cnt1);
- bcopy(tmp, cp, cnt2);
- }
-}
static void
ForwardTab()
@@ -2068,8 +1702,8 @@ ForwardTab()
x++;
while (x < cols - 1 && !curr->w_tabs[x])
x++;
- GotoPos(x, curr->w_y);
curr->w_x = x;
+ LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
}
static void
@@ -2081,107 +1715,57 @@ BackwardTab()
x--;
while (x > 0 && !curr->w_tabs[x])
x--;
- GotoPos(x, curr->w_y);
curr->w_x = x;
+ LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
}
static void
ClearScreen()
{
- register int i;
- register struct mline *ml = curr->w_mlines;
-
- for (i = 0; i < rows; ++i)
- {
+ LClear(&curr->w_layer, 0, 0, curr->w_width - 1, curr->w_height - 1, 1);
#ifdef COPY_PASTE
- AddLineToHist(curr, ml);
+ MScrollV(curr, curr->w_height, 0, curr->w_height - 1);
+#else
+ MClear(curr, 0, 0, curr->w_width - 1, curr->w_height - 1);
#endif
- clear_mline(ml, 0, cols + 1);
- ml++;
- }
- if (display)
- ClearDisplay();
}
static void
ClearFromBOS()
{
- register int n, y = curr->w_y, x = curr->w_x;
+ register int y = curr->w_y, x = curr->w_x;
- if (display)
- Clear(0, 0, 0, cols - 1, x, y, 1);
- for (n = 0; n < y; ++n)
- ClearInLine(n, 0, cols - 1);
- ClearInLine(y, 0, x);
+ LClear(&curr->w_layer, 0, 0, x, y, 1);
+ MClear(curr, 0, 0, x, y);
RestorePosRendition();
}
static void
ClearToEOS()
{
- register int n, y = curr->w_y, x = curr->w_x;
+ register int y = curr->w_y, x = curr->w_x;
if (x == 0 && y == 0)
{
ClearScreen();
return;
}
- if (display)
- Clear(x, y, 0, cols - 1, cols - 1, rows - 1, 1);
- ClearInLine(y, x, cols - 1);
- for (n = y + 1; n < rows; n++)
- ClearInLine(n, 0, cols - 1);
+ LClear(&curr->w_layer, x, y, cols - 1, rows - 1, 1);
+ MClear(curr, x, y, cols - 1, rows - 1);
RestorePosRendition();
}
static void
-ClearFullLine()
+ClearLineRegion(from, to)
+int from, to;
{
register int y = curr->w_y;
-
- if (display)
- Clear(0, y, 0, cols - 1, cols - 1, y, 1);
- ClearInLine(y, 0, cols - 1);
- RestorePosRendition();
-}
-
-static void
-ClearToEOL()
-{
- register int y = curr->w_y, x = curr->w_x;
-
- if (display)
- Clear(x, y, 0, cols - 1, cols - 1, y, 1);
- ClearInLine(y, x, cols - 1);
+ LClear(&curr->w_layer, from, y, to, y, 1);
+ MClear(curr, from, y, to, y);
RestorePosRendition();
}
static void
-ClearFromBOL()
-{
- register int y = curr->w_y, x = curr->w_x;
-
- if (display)
- Clear(0, y, 0, cols - 1, x, y, 1);
- ClearInLine(y, 0, x);
- RestorePosRendition();
-}
-
-static void
-ClearInLine(y, x1, x2)
-int y, x1, x2;
-{
- register int n;
-
- if (x1 == cols)
- x1--;
- if (x2 == cols - 1)
- x2++;
- if ((n = x2 - x1 + 1) != 0)
- clear_mline(&curr->w_mlines[y], x1, n);
-}
-
-static void
CursorRight(n)
register int n;
{
@@ -2194,7 +1778,7 @@ register int n;
}
if ((curr->w_x += n) >= cols)
curr->w_x = cols - 1;
- GotoPos(curr->w_x, curr->w_y);
+ LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
}
static void
@@ -2209,7 +1793,7 @@ register int n;
else
if ((curr->w_y -= n) < curr->w_top)
curr->w_y = curr->w_top;
- GotoPos(curr->w_x, curr->w_y);
+ LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
}
static void
@@ -2224,7 +1808,7 @@ register int n;
else
if ((curr->w_y += n) > curr->w_bot)
curr->w_y = curr->w_bot;
- GotoPos(curr->w_x, curr->w_y);
+ LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
}
static void
@@ -2233,7 +1817,7 @@ register int n;
{
if ((curr->w_x -= n) < 0)
curr->w_x = 0;
- GotoPos(curr->w_x, curr->w_y);
+ LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
}
static void
@@ -2246,16 +1830,18 @@ int on;
{
switch (curr->w_args[i])
{
- case 4:
+ /* case 2: KAM: Lock keyboard */
+ case 4: /* IRM: Insert mode */
curr->w_insert = on;
- InsertMode(on);
+ LAY_DISPLAYS(&curr->w_layer, InsertMode(on));
break;
- case 20:
+ /* case 12: SRM: Echo mode on */
+ case 20: /* LNM: Linefeed mode */
curr->w_autolf = on;
break;
case 34:
curr->w_curvvis = !on;
- CursorVisibility(curr->w_curinv ? -1 : curr->w_curvvis);
+ LCursorVisibility(&curr->w_layer, curr->w_curinv ? -1 : curr->w_curvvis);
break;
default:
break;
@@ -2298,12 +1884,11 @@ SelectRendition()
a |= j;
}
while (++i < curr->w_NumArgs);
- if (curr->w_rend.attr != a)
- SetAttr(curr->w_rend.attr = a);
+ curr->w_rend.attr = a;
#ifdef COLOR
- if (curr->w_rend.color != c)
- SetColor(curr->w_rend.color = c);
+ curr->w_rend.color = c;
#endif
+ LSetRendition(&curr->w_layer, &curr->w_rend);
}
static void
@@ -2312,6 +1897,7 @@ FillWithEs()
register int i;
register char *p, *ep;
+ ClearLayer(&curr->w_layer, 1);
curr->w_y = curr->w_x = 0;
for (i = 0; i < rows; ++i)
{
@@ -2321,58 +1907,10 @@ FillWithEs()
while (p < ep)
*p++ = 'E';
}
- if (display)
- Redisplay(0);
+ RedisplayLayer(&curr->w_layer, 1);
}
-static void
-UpdateLine(oml, y, from, to)
-struct mline *oml;
-int from, to, y;
-{
- ASSERT(display);
- DisplayLine(oml, &curr->w_mlines[y], y, from, to);
- RestorePosRendition();
-}
-
-
-static void
-CheckLP(n_ch)
-int n_ch;
-{
- register int x;
- register struct mline *ml;
-
- ASSERT(display);
- ml = &curr->w_mlines[D_bot];
- x = cols - 1;
-
- curr->w_rend.image = n_ch;
-
- D_lpchar = curr->w_rend;
- D_lp_missing = 0;
-
- if (cmp_mchar_mline(&curr->w_rend, ml, x))
- return;
- if (!cmp_mchar(&mchar_blank, &curr->w_rend)) /* is new not blank */
- D_lp_missing = 1;
- if (!cmp_mchar_mline(&mchar_blank, ml, x)) /* is old char not blank? */
- {
- /* old char not blank, new blank, try to delete */
- if (D_UT)
- SetRendition(&mchar_null);
- if (D_CE)
- PutStr(D_CE);
- else if (D_DC)
- PutStr(D_DC);
- else if (D_CDC)
- CPutStr(D_CDC, 1);
- else
- D_lp_missing = 1;
- }
-}
-
/*
* Ugly autoaka hack support:
* ChangeAKA() sets a new aka
@@ -2393,14 +1931,9 @@ int l;
if (p->w_akachange != p->w_akabuf)
if (p->w_akachange[0] == 0 || p->w_akachange[-1] == ':')
p->w_title = p->w_akabuf + strlen(p->w_akabuf) + 1;
-
- /* yucc */
- if (p->w_hstatus)
- {
- display = p->w_display;
- if (display)
- RefreshStatus();
- }
+ WindowChanged(p, 't');
+ WindowChanged((struct win *)0, 'w');
+ WindowChanged((struct win *)0, 'W');
}
static void
@@ -2452,25 +1985,11 @@ FindAKA()
wp->w_autoaka = 0;
}
-void
-SetCurr(wp)
-struct win *wp;
-{
- curr = wp;
- if (curr == 0)
- return;
- cols = curr->w_width;
- rows = curr->w_height;
- display = curr->w_active ? curr->w_display : 0;
-}
-
static void
RestorePosRendition()
{
- if (!display)
- return;
- GotoPos(curr->w_x, curr->w_y);
- SetRendition(&curr->w_rend);
+ LGotoPos(&curr->w_layer, curr->w_x, curr->w_y);
+ LSetRendition(&curr->w_layer, &curr->w_rend);
}
/* Send a terminal report as if it were typed. */
@@ -2492,6 +2011,294 @@ int n1, n2;
}
}
+
+
+/*
+ *====================================================================*
+ *====================================================================*
+ */
+
+/**********************************************************************
+ *
+ * Memory subsystem.
+ *
+ */
+
+static void
+MFixLine(p, y, mc)
+struct win *p;
+int y;
+struct mchar *mc;
+{
+ struct mline *ml = &p->w_mlines[y];
+ if (mc->attr && ml->attr == null)
+ {
+ if ((ml->attr = (char *)malloc(p->w_width + 1)) == 0)
+ {
+ ml->attr = null;
+ mc->attr = p->w_rend.attr = 0;
+ WMsg(p, 0, "Warning: no space for attr - turned off");
+ }
+ bzero(ml->attr, p->w_width + 1);
+ }
+#ifdef FONT
+ if (mc->font && ml->font == null)
+ {
+ if ((ml->font = (char *)malloc(p->w_width + 1)) == 0)
+ {
+ ml->font = null;
+ p->w_FontL = p->w_charsets[p->w_ss ? p->w_ss : p->w_Charset] = 0;
+ p->w_FontR = p->w_charsets[p->w_ss ? p->w_ss : p->w_CharsetR] = 0;
+ mc->font = p->w_rend.font = 0;
+ WMsg(p, 0, "Warning: no space for font - turned off");
+ }
+ bzero(ml->font, p->w_width + 1);
+ }
+#endif
+#ifdef COLOR
+ if (mc->color && ml->color == null)
+ {
+ if ((ml->color = (char *)malloc(p->w_width + 1)) == 0)
+ {
+ ml->color = null;
+ mc->color = p->w_rend.color = 0;
+ WMsg(p, 0, "Warning: no space for color - turned off");
+ }
+ bzero(ml->color, p->w_width + 1);
+ }
+#endif
+}
+
+/*****************************************************************/
+
+static void
+MScrollH(p, n, y, xs, xe)
+struct win *p;
+int n, y, xs, xe;
+{
+ struct mline *ml;
+
+ if (n == 0)
+ return;
+ ml = &p->w_mlines[y];
+ if (n > 0)
+ {
+ if (xe - xs + 1 > n)
+ bcopy_mline(ml, xs + n, xs, xe + 1 - xs - n);
+ else
+ n = xe - xs + 1;
+ clear_mline(ml, xe + 1 - n, n);
+ }
+ else
+ {
+ n = -n;
+ if (xe - xs + 1 > n)
+ bcopy_mline(ml, xs, xs + n, xe + 1 - xs - n);
+ else
+ n = xe - xs + 1;
+ clear_mline(ml, xs, n);
+ }
+}
+
+static void
+MScrollV(p, n, ys, ye)
+struct win *p;
+int n;
+int ys, ye;
+{
+ int i, cnt1, cnt2;
+ struct mline *tmp[256];
+ struct mline *ml;
+
+ if (n == 0)
+ return;
+ if (n > 0)
+ {
+ if (n > 256)
+ {
+ MScrollV(p, n - 256, ys, ye);
+ n = 256;
+ }
+ if (ye - ys + 1 < n)
+ n = ye - ys + 1;
+#ifdef COPY_PASTE
+ if (compacthist)
+ {
+ ye = MFindUsedLine(p, ye, ys);
+ if (ye - ys + 1 < n)
+ n = ye - ys + 1;
+ if (n <= 0)
+ return;
+ }
+#endif
+ /* Clear lines */
+ ml = p->w_mlines + ys;
+ for (i = ys; i < ys + n; i++, ml++)
+ {
+#ifdef COPY_PASTE
+ if (ys == p->w_top)
+ AddLineToHist(p, ml);
+#endif
+ if (ml->attr != null)
+ free(ml->attr);
+ ml->attr = null;
+#ifdef FONT
+ if (ml->font != null)
+ free(ml->font);
+ ml->font = null;
+#endif
+#ifdef COLOR
+ if (ml->color != null)
+ free(ml->color);
+ ml->color = null;
+#endif
+ bclear(ml->image, p->w_width + 1);
+ }
+ /* switch 'em over */
+ cnt1 = n * sizeof(struct mline);
+ cnt2 = (ye - ys + 1 - n) * sizeof(struct mline);
+ if (cnt1 && cnt2)
+ Scroll((char *)(p->w_mlines + ys), cnt1, cnt2, (char *)tmp);
+ }
+ else
+ {
+ if (n < -256)
+ {
+ MScrollV(p, n + 256, ys, ye);
+ n = -256;
+ }
+ n = -n;
+ if (ye - ys + 1 < n)
+ n = ye - ys + 1;
+
+ ml = p->w_mlines + ye;
+ /* Clear lines */
+ for (i = ye; i > ye - n; i--, ml--)
+ {
+ if (ml->attr != null)
+ free(ml->attr);
+ ml->attr = null;
+#ifdef FONT
+ if (ml->font != null)
+ free(ml->font);
+ ml->font = null;
+#endif
+#ifdef COLOR
+ if (ml->color != null)
+ free(ml->color);
+ ml->color = null;
+#endif
+ bclear(ml->image, p->w_width + 1);
+ }
+ cnt1 = n * sizeof(struct mline);
+ cnt2 = (ye - ys + 1 - n) * sizeof(struct mline);
+ if (cnt1 && cnt2)
+ Scroll((char *)(p->w_mlines + ys), cnt2, cnt1, (char *)tmp);
+ }
+}
+
+static void
+Scroll(cp, cnt1, cnt2, tmp)
+char *cp, *tmp;
+int cnt1, cnt2;
+{
+ if (!cnt1 || !cnt2)
+ return;
+ if (cnt1 <= cnt2)
+ {
+ bcopy(cp, tmp, cnt1);
+ bcopy(cp + cnt1, cp, cnt2);
+ bcopy(tmp, cp + cnt2, cnt1);
+ }
+ else
+ {
+ bcopy(cp + cnt1, tmp, cnt2);
+ bcopy(cp, cp + cnt2, cnt1);
+ bcopy(tmp, cp, cnt2);
+ }
+}
+
+static void
+MClear(p, xs, ys, xe, ye)
+struct win *p;
+int xs, ys, xe, ye;
+{
+ int n, y;
+ int xxe;
+ struct mline *ml;
+
+ /* check for magic margin condition */
+ if (xs >= p->w_width)
+ xs = p->w_width - 1;
+ if (xe >= p->w_width)
+ xe = p->w_width - 1;
+
+ ml = p->w_mlines + ys;
+ for (y = ys; y <= ye; y++, ml++)
+ {
+ xxe = (y == ye) ? xe : p->w_width - 1;
+ n = xxe - xs + 1;
+ if (n > 0)
+ clear_mline(ml, xs, n);
+ xs = 0;
+ }
+}
+
+static void
+MInsChar(p, c, x, y)
+struct win *p;
+struct mchar *c;
+int x, y;
+{
+ int n;
+ struct mline *ml;
+
+ ASSERT(x >= 0 && x < p->w_width);
+ MFixLine(p, y, c);
+ ml = p->w_mlines + y;
+ n = p->w_width - x - 1;
+ if (n > 0)
+ bcopy_mline(ml, x, x + 1, n);
+ copy_mchar2mline(c, ml, x);
+}
+
+static void
+MPutChar(p, c, x, y)
+struct win *p;
+struct mchar *c;
+int x, y;
+{
+ struct mline *ml;
+
+ MFixLine(p, y, c);
+ ml = &p->w_mlines[y];
+ copy_mchar2mline(c, ml, x);
+}
+
+
+static void
+MWrapChar(p, c, y, top, bot, ins)
+struct win *p;
+struct mchar *c;
+int y, top, bot;
+int ins;
+{
+ struct mline *ml;
+
+ MFixLine(p, y, c);
+ ml = &p->w_mlines[y];
+ copy_mchar2mline(&mchar_null, ml, p->w_width);
+ if (y == bot)
+ MScrollV(p, 1, top, bot);
+ else if (y < p->w_height - 1)
+ y++;
+ MFixLine(p, y, c);
+ ml = &p->w_mlines[y];
+ if (ins && p->w_width > 1)
+ bcopy_mline(ml, 0, 1, p->w_width - 1);
+ copy_mchar2mline(c, ml, 0);
+}
+
#ifdef COPY_PASTE
static void
AddLineToHist(wp, ml)
@@ -2510,9 +2317,11 @@ struct mline *ml;
if (o != null)
free(o);
+#ifdef FONT
q = ml->font; o = hml->font; hml->font = q; ml->font = null;
if (o != null)
free(o);
+#endif
#ifdef COLOR
q = ml->color; o = hml->color; hml->color = q; ml->color = null;
@@ -2525,3 +2334,238 @@ struct mline *ml;
}
#endif
+int
+MFindUsedLine(p, ye, ys)
+struct win *p;
+int ys, ye;
+{
+ int y;
+ struct mline *ml = p->w_mlines + ye;
+
+ debug2("MFindUsedLine: %d %d\n", ye, ys);
+ for (y = ye; y >= ys; y--, ml--)
+ {
+ if (bcmp((char*)ml->image, blank, p->w_width))
+ break;
+ if (ml->attr != null && bcmp((char*)ml->attr, null, p->w_width))
+ break;
+#ifdef COLOR
+ if (ml->color != null && bcmp((char*)ml->color, null, p->w_width))
+ break;
+#endif
+ }
+ debug1("MFindUsedLine returning %d\n", y);
+ return y;
+}
+
+
+/*
+ *====================================================================*
+ *====================================================================*
+ */
+
+/*
+ * Tricky: send only one bell even if the window is displayed
+ * more than one times.
+ */
+void
+WBell(p, visual)
+struct win *p;
+int visual;
+{
+ struct canvas *cv;
+ for (display = displays; display; display = display->d_next)
+ {
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ if (cv->c_layer->l_bottom == &p->w_layer)
+ break;
+ if (cv && !visual)
+ PutStr(D_BL);
+ else if (cv && D_VB)
+ PutStr(D_VB);
+ else
+ p->w_bell = visual ? BELL_VISUAL : BELL_FOUND;
+ }
+}
+
+/*
+ * This should be reverse video.
+ * Only change video if window is fore.
+ * Because it is used in some termcaps to emulate
+ * a visual bell we do this hack here.
+ * (screen uses \Eg as special vbell sequence)
+ */
+static void
+WReverseVideo(p, on)
+struct win *p;
+int on;
+{
+ struct canvas *cv;
+ for (cv = p->w_layer.l_cvlist; cv; cv = cv->c_lnext)
+ {
+ display = cv->c_display;
+ if (cv != D_forecv)
+ continue;
+ ReverseVideo(on);
+ if (!on && p->w_revvid && !D_CVR)
+ {
+ if (D_VB)
+ PutStr(D_VB);
+ else
+ p->w_bell = BELL_VISUAL;
+ }
+ }
+}
+
+void
+WMsg(p, err, str)
+struct win *p;
+int err;
+char *str;
+{
+ extern struct layer *flayer;
+ struct layer *oldflayer = flayer;
+ flayer = &p->w_layer;
+ LMsg(err, str);
+ flayer = oldflayer;
+}
+
+void
+WChangeSize(p, w, h)
+struct win *p;
+int w, h;
+{
+ int wok = 0;
+ struct canvas *cv;
+
+ if (p->w_layer.l_cvlist == 0)
+ {
+ /* window not displayed -> works always */
+ ChangeWindowSize(p, w, h, p->w_histheight);
+ return;
+ }
+ for (cv = p->w_layer.l_cvlist; cv; cv = cv->c_lnext)
+ {
+ display = cv->c_display;
+ if (p != D_fore)
+ continue; /* change only fore */
+ if (D_CWS)
+ break;
+ if (D_CZ0 && (w == Z0width || w == Z1width))
+ wok = 1;
+ }
+ if (cv == 0 && wok == 0) /* can't change any display */
+ return;
+ if (!D_CWS)
+ h = p->w_height;
+ ChangeWindowSize(p, w, h, p->w_histheight);
+ for (display = displays; display; display = display->d_next)
+ {
+ if (p == D_fore)
+ {
+ if (D_cvlist && D_cvlist->c_next == 0)
+ ResizeDisplay(w, h);
+ else
+ ResizeDisplay(w, D_height);
+ ResizeLayersToCanvases(); /* XXX Hmm ? */
+ continue;
+ }
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ if (cv->c_layer->l_bottom == &p->w_layer)
+ break;
+ if (cv)
+ Redisplay(0);
+ }
+}
+
+static int
+WindowChangedCheck(s, what, hp)
+char *s;
+int what;
+int *hp;
+{
+ int h = 0;
+ while(*s)
+ {
+ if (*s++ != '%')
+ continue;
+ while (*s >= '0' && *s <= '9')
+ s++;
+ if (*s == 'h')
+ h = 1;
+ if (*s == what || what == 'd')
+ break;
+ if (*s)
+ s++;
+ }
+ if (hp)
+ *hp = h;
+ return *s ? 1 : 0;
+}
+
+void
+WindowChanged(p, what)
+struct win *p;
+int what;
+{
+ int inwstr, inhstr;
+ int inwstrh, inhstrh;
+ int got, ox, oy;
+ struct display *olddisplay = display;
+ struct canvas *cv;
+
+ inwstr = inhstr = 0;
+
+ inwstr = WindowChangedCheck(captionstring, what, &inwstrh);
+ inhstr = WindowChangedCheck(hstatusstring, what, &inhstrh);
+
+ if (p == 0)
+ {
+ for (display = displays; display; display = display->d_next)
+ {
+ ox = D_x;
+ oy = D_y;
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ {
+ p = Layer2Window(cv->c_layer);
+ if (inwstr || (inwstrh && p && p->w_hstatus && *p->w_hstatus && WindowChangedCheck(p->w_hstatus, what, (int *)0)))
+ if (cv->c_ye + 1 < D_height)
+ RefreshLine(cv->c_ye + 1, 0, D_width - 1, 0);
+ }
+ p = D_fore;
+ if (inhstr || (inhstrh && p && p->w_hstatus && *p->w_hstatus && WindowChangedCheck(p->w_hstatus, what, (int *)0)))
+ RefreshHStatus();
+ if (ox != -1 && ox != -1)
+ GotoPos(ox, oy);
+ }
+ display = olddisplay;
+ return;
+ }
+
+ if (p->w_hstatus && *p->w_hstatus && (inwstrh || inhstrh) && WindowChangedCheck(p->w_hstatus, what, (int *)0))
+ {
+ inwstr |= inwstrh;
+ inhstr |= inhstrh;
+ }
+ if (!inwstr && !inhstr)
+ return;
+ for (display = displays; display; display = display->d_next)
+ {
+ got = 0;
+ ox = D_x;
+ oy = D_y;
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ {
+ if (Layer2Window(cv->c_layer) != p)
+ continue;
+ got = 1;
+ if (inwstr && cv->c_ye + 1 < D_height)
+ RefreshLine(cv->c_ye + 1, 0, D_width - 1, 0);
+ }
+ if (got && inhstr && p == D_fore)
+ RefreshHStatus();
+ if (ox != -1 && ox != -1)
+ GotoPos(ox, oy);
+ }
+ display = olddisplay;
+}
diff --git a/ansi.h b/ansi.h
index 1746f28..b34d7bd 100644
--- a/ansi.h
+++ b/ansi.h
@@ -46,6 +46,7 @@
/*
* Parser state
*/
+/* keep state_t and state_t_string in sync! */
enum state_t
{
LIT, /* Literal input */
@@ -59,6 +60,7 @@ enum state_t
PRIN4 /* CSI 4 seen in printer mode */
};
+/* keep string_t and string_t_string in sync! */
enum string_t
{
NONE,
diff --git a/attacher.c b/attacher.c
index 447994f..db953ad 100644
--- a/attacher.c
+++ b/attacher.c
@@ -26,6 +26,7 @@ RCS_ID("$Id: attacher.c,v 1.8 1994/05/31 12:31:32 mlschroe Exp $ FAU")
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/ioctl.h>
#include <fcntl.h>
#include <signal.h>
#include "config.h"
@@ -35,9 +36,6 @@ RCS_ID("$Id: attacher.c,v 1.8 1994/05/31 12:31:32 mlschroe Exp $ FAU")
#include <pwd.h>
static sigret_t AttacherSigInt __P(SIGPROTOARG);
-#ifdef PASSWORD
-static void trysend __P((int, struct msg *, char *));
-#endif
#if defined(SIGWINCH) && defined(TIOCGWINSZ)
static sigret_t AttacherWinch __P(SIGPROTOARG);
#endif
@@ -50,15 +48,17 @@ static void screen_builtin_lck __P((void));
#ifdef DEBUG
static sigret_t AttacherChld __P(SIGPROTOARG);
#endif
+#ifdef MULTIUSER
+static sigret_t AttachSigCont __P(SIGPROTOARG);
+#endif
extern int real_uid, real_gid, eff_uid, eff_gid;
extern char *SockName, *SockMatch, SockPath[];
extern struct passwd *ppp;
-extern char *attach_tty, *attach_term, *LoginName;
+extern char *attach_tty, *attach_term, *LoginName, *preselect;
extern int xflag, dflag, rflag, quietflag, adaptflag;
extern struct mode attach_Mode;
extern int MasterPid;
-extern int nethackflag;
#ifdef MULTIUSER
extern char *multi;
@@ -70,6 +70,18 @@ static int multipipe[2];
#endif
+#ifdef MULTIUSER
+static int ContinuePlease;
+
+static sigret_t
+AttachSigCont SIGDEFARG
+{
+ debug("SigCont()\n");
+ ContinuePlease = 1;
+ SIGRETURN;
+}
+#endif
+
/*
* Send message to a screen backend.
@@ -164,6 +176,7 @@ int how;
bzero((char *) &m, sizeof(m));
m.type = how;
+ m.protocol_revision = MSG_REVISION;
strncpy(m.m_tty, attach_tty, sizeof(m.m_tty) - 1);
m.m_tty[sizeof(m.m_tty) - 1] = 0;
@@ -191,7 +204,7 @@ int how;
switch (n)
{
case 0:
- if (rflag == 2)
+ if (rflag && (rflag & 1) == 0)
return 0;
if (quietflag)
eexit(10);
@@ -203,9 +216,12 @@ int how;
case 1:
break;
default:
- if (quietflag)
- eexit(10 + n);
- Panic(0, "Type \"screen [-d] -r [pid.]tty.host\" to resume one of them.");
+ if (rflag < 3)
+ {
+ if (quietflag)
+ eexit(10 + n);
+ Panic(0, "Type \"screen [-d] -r [pid.]tty.host\" to resume one of them.");
+ }
/* NOTREACHED */
}
}
@@ -220,7 +236,10 @@ int how;
setuid(real_uid);
#if defined(MULTIUSER) && defined(USE_SETEUID)
else
- xseteuid(real_uid); /* multi_uid, allow backend to send signals */
+ {
+ /* This call to xsetuid should also set the saved uid */
+ xseteuid(real_uid); /* multi_uid, allow backend to send signals */
+ }
#endif
setgid(real_gid);
eff_uid = real_uid;
@@ -240,6 +259,17 @@ int how;
Panic(errno, "stat %s", SockPath);
if ((st.st_mode & 0600) != 0600)
Panic(0, "Socket is in wrong mode (%03o)", (int)st.st_mode);
+
+ /*
+ * Change: if -x or -r ignore failing -d
+ */
+ if ((xflag || rflag) && dflag && (st.st_mode & 0700) == 0600)
+ dflag = 0;
+
+ /*
+ * Without -x, the mode must match.
+ * With -x the mode is irrelevant unless -d.
+ */
if ((dflag || !xflag) && (st.st_mode & 0700) != (dflag ? 0700 : 0600))
Panic(0, "That screen is %sdetached.", dflag ? "already " : "not ");
#ifdef REMOTE_DETACH
@@ -273,6 +303,10 @@ int how;
strncpy(m.m.attach.auser, LoginName, sizeof(m.m.attach.auser) - 1);
m.m.attach.auser[sizeof(m.m.attach.auser) - 1] = 0;
+ m.m.attach.esc = DefaultEsc;
+ m.m.attach.meta_esc = DefaultMetaEsc;
+ strncpy(m.m.attach.preselect, preselect ? preselect : "", sizeof(m.m.attach.preselect) - 1);
+ m.m.attach.preselect[sizeof(m.m.attach.preselect) - 1] = 0;
m.m.attach.apid = getpid();
m.m.attach.adaptflag = adaptflag;
m.m.attach.lines = m.m.attach.columns = 0;
@@ -281,23 +315,23 @@ int how;
if ((s = getenv("COLUMNS")))
m.m.attach.columns = atoi(s);
-#ifdef PASSWORD
- if (how == MSG_ATTACH || how == MSG_CONT)
- trysend(lasts, &m, m.m.attach.password);
- else
+#ifdef MULTIUSER
+ /* setup CONT signal handler to repair the terminal mode */
+ if (multi && (how == MSG_ATTACH || how == MSG_CONT))
+ signal(SIGCONT, AttachSigCont);
#endif
- {
- if (write(lasts, (char *) &m, sizeof(m)) != sizeof(m))
- Panic(errno, "write");
- close(lasts);
- }
+
+ if (write(lasts, (char *) &m, sizeof(m)) != sizeof(m))
+ Panic(errno, "write");
+ close(lasts);
debug1("Attach(%d): sent\n", m.type);
#ifdef MULTIUSER
if (multi && (how == MSG_ATTACH || how == MSG_CONT))
{
-# ifndef PASSWORD
- pause();
-# endif
+ while (!ContinuePlease)
+ pause(); /* wait for SIGCONT */
+ signal(SIGCONT, SIG_DFL);
+ ContinuePlease = 0;
# ifndef USE_SETEUID
close(multipipe[1]);
# else
@@ -315,77 +349,11 @@ int how;
}
-#ifdef PASSWORD
-
-static trysendstatok, trysendstatfail;
-
-static sigret_t
-trysendok SIGDEFARG
-{
- trysendstatok = 1;
-}
-
-static sigret_t
-trysendfail SIGDEFARG
-{
-# ifdef SYSVSIGS
- signal(SIG_PW_FAIL, trysendfail);
-# endif /* SYSVSIGS */
- trysendstatfail = 1;
-}
-
-static char screenpw[9];
-
-static void
-trysend(fd, m, pwto)
-int fd;
-struct msg *m;
-char *pwto;
-{
- char *npw = NULL;
- sigret_t (*sighup)__P(SIGPROTOARG);
- sigret_t (*sigusr1)__P(SIGPROTOARG);
- int tries;
-
- sigusr1 = signal(SIG_PW_OK, trysendok);
- sighup = signal(SIG_PW_FAIL, trysendfail);
- for (tries = 0; ; )
- {
- strncpy(pwto, screenpw, 9);
- trysendstatok = trysendstatfail = 0;
- if (write(fd, (char *) m, sizeof(*m)) != sizeof(*m))
- Panic(errno, "write");
- close(fd);
- while (trysendstatok == 0 && trysendstatfail == 0)
- pause();
- if (trysendstatok)
- {
- signal(SIG_PW_OK, sigusr1);
- signal(SIG_PW_FAIL, sighup);
- if (trysendstatfail)
- kill(getpid(), SIG_PW_FAIL);
- return;
- }
- if (++tries > 1 || (npw = getpass("Screen Password:")) == 0 || *npw == 0)
- {
-#ifdef NETHACK
- if (nethackflag)
- Panic(0, "The guard slams the door in your face.");
- else
+#if defined(DEBUG) || !defined(DO_NOT_POLL_MASTER)
+static int AttacherPanic;
#endif
- Panic(0, "Password incorrect.");
- }
- strncpy(screenpw, npw, 8);
- if ((fd = MakeClientSocket(0)) == -1)
- Panic(0, "Cannot contact screen again. Sigh.");
- }
-}
-#endif /* PASSWORD */
-
#ifdef DEBUG
-static int AttacherPanic;
-
static sigret_t
AttacherChld SIGDEFARG
{
@@ -394,6 +362,17 @@ AttacherChld SIGDEFARG
}
#endif
+static sigret_t
+AttacherSigAlarm SIGDEFARG
+{
+#ifdef DEBUG
+ static int tick_cnt = 0;
+ if ((tick_cnt = (tick_cnt + 1) % 4) == 0)
+ debug("tick\n");
+#endif
+ SIGRETURN;
+}
+
/*
* the frontend's Interrupt handler
* we forward SIGINT to the poor backend
@@ -430,6 +409,7 @@ AttacherFinit SIGDEFARG
debug1("attach_tty is %s\n", attach_tty);
m.m.detach.dpid = getpid();
m.type = MSG_HANGUP;
+ m.protocol_revision = MSG_REVISION;
if ((s = MakeClientSocket(0)) >= 0)
{
write(s, (char *)&m, sizeof(m));
@@ -471,6 +451,23 @@ AttacherFinitBye SIGDEFARG
}
#endif
+#if defined(DEBUG) && defined(SIG_NODEBUG)
+static sigret_t
+AttacherNoDebug SIGDEFARG
+{
+ debug("AttacherNoDebug()\n");
+ signal(SIG_NODEBUG, AttacherNoDebug);
+ if (dfp)
+ {
+ debug("debug: closing debug file.\n");
+ fflush(dfp);
+ fclose(dfp);
+ dfp = NULL;
+ }
+ SIGRETURN;
+}
+#endif /* SIG_NODEBUG */
+
static int SuspendPlease;
static sigret_t
@@ -521,6 +518,9 @@ Attacher()
#ifdef POW_DETACH
signal(SIG_POWER_BYE, AttacherFinitBye);
#endif
+#if defined(DEBUG) && defined(SIG_NODEBUG)
+ signal(SIG_NODEBUG, AttacherNoDebug);
+#endif
#ifdef LOCK
signal(SIG_LOCK, DoLock);
#endif
@@ -541,8 +541,11 @@ Attacher()
#endif
for (;;)
{
-#ifdef DEBUG
- sleep(1);
+#ifndef DO_NOT_POLL_MASTER
+ signal(SIGALRM, AttacherSigAlarm);
+ alarm(15);
+ pause();
+ alarm(0);
if (kill(MasterPid, 0) < 0 && errno != EPERM)
{
debug1("attacher: Panic! MasterPid %d does not exist.\n", MasterPid);
@@ -551,16 +554,17 @@ Attacher()
#else
pause();
#endif
-/*
- debug("attacher: ding!\n");
-*/
-#ifdef DEBUG
+#if defined(DEBUG) || !defined(DO_NOT_POLL_MASTER)
if (AttacherPanic)
{
+# ifdef FORKDEBUG
+ exit(0);
+# else
fcntl(0, F_SETFL, 0);
SetTTY(0, &attach_Mode);
printf("\nSuddenly the Dungeon collapses!! - You die...\n");
eexit(1);
+# endif
}
#endif
#ifdef BSDJOBS
@@ -660,14 +664,7 @@ LockTerminal()
exit(errno);
}
if (pid == -1)
- {
-#ifdef NETHACK
- if (nethackflag)
- Msg(errno, "Cannot fork terminal - lock failed");
- else
-#endif
- Msg(errno, "Cannot lock terminal - fork failed");
- }
+ Msg(errno, "Cannot lock terminal - fork failed");
else
{
#ifdef BSDWAIT
@@ -732,21 +729,6 @@ screen_builtin_lck()
char fullname[100], *cp1, message[100 + 100];
char *pass, mypass[9];
-#ifdef undef
- /* get password entry */
- if ((ppp = getpwuid(real_uid)) == NULL)
- {
- fprintf(stderr, "screen_builtin_lck: No passwd entry.\007\n");
- sleep(2);
- return;
- }
- if (!isatty(0))
- {
- fprintf(stderr, "screen_builtin_lck: Not a tty.\007\n");
- sleep(2);
- return;
- }
-#endif
pass = ppp->pw_passwd;
if (pass == 0 || *pass == 0)
{
@@ -778,6 +760,7 @@ screen_builtin_lck()
debug("screen_builtin_lck looking in gcos field\n");
strncpy(fullname, ppp->pw_gecos, sizeof(fullname) - 9);
fullname[sizeof(fullname) - 9] = 0;
+
if ((cp1 = index(fullname, ',')) != NULL)
*cp1 = '\0';
if ((cp1 = index(fullname, '&')) != NULL)
@@ -801,7 +784,6 @@ screen_builtin_lck()
AttacherFinit(SIGARG);
/* NOTREACHED */
}
- debug3("getpass(%d): %x == %s\n", errno, (unsigned int)cp1, cp1);
if (pass)
{
if (!strncmp(crypt(cp1, pass), pass, strlen(pass)))
diff --git a/braille.c b/braille.c
new file mode 100644
index 0000000..8a05599
--- /dev/null
+++ b/braille.c
@@ -0,0 +1,941 @@
+/*
+ * A braille interface to unix tty terminals
+ *
+ * Authors: Hadi Bargi Rangin bargi@dots.physics.orst.edu
+ * Bill Barry barryb@dots.physics.orst.edu
+ *
+ * Copyright (c) 1995 by Science Access Project, Oregon State University.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING); if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ ****************************************************************
+ */
+#include "rcs.h"
+RCS_ID("$Id: braille.c,v 1.1 1995/09/06 15:45:26 jnweiger Exp jnweiger $")
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#include "config.h"
+#include "screen.h"
+#include "extern.h"
+#include "braille.h"
+
+#ifdef HAVE_BRAILLE
+
+
+extern int bd_init_powerbraille_40 __P((void));
+extern int bd_init_powerbraille_80 __P((void));
+extern int bd_init_navigator_40 __P((void));
+
+extern struct layer *flayer;
+extern struct display *displays, *display;
+extern char *rc_name;
+
+
+
+
+/* global variables */
+
+struct braille_display bd;
+
+struct bd_type {
+ char *name;
+ int (*init) __P((void));
+};
+
+static struct bd_type bd_typelist[] =
+{
+ {"powerbraille_40", bd_init_powerbraille_40},
+ {"powerbraille_80", bd_init_powerbraille_80},
+ {"navigator_40" , bd_init_navigator_40}
+};
+
+static void position_braille_cursor __P((void));
+static int initialize_braille_display_type __P((char *));
+static int open_braille_device __P(());
+static int load_braille_table __P((char *));
+static void bd_signal __P((void));
+static void bd_bc_left __P((void));
+static void bd_bc_right __P((void));
+static void bd_bc_up __P((void));
+static void bd_bc_down __P((void));
+static void bd_upper_left __P((void));
+static void bd_upper_right __P((void));
+static void bd_lower_left __P((void));
+static void bd_lower_right __P((void));
+static int bd_do_search __P((int, int, int));
+static void bd_normalize __P((int, int));
+static void bd_readev_fn __P((struct event *, char *));
+static void bd_writeev_fn __P((struct event *, char *));
+static void bd_selectev_fn __P((struct event *, char *));
+
+static unsigned char btable_local [] =
+{
+ 0xC8,0xC1,0xC3,0xC9,0xD9,0xD1,0xCB,0xDB,
+ 0xD3,0xCA,0xDA,0xC5,0xC7,0xCD,0xDD,0xD5,
+ 0xCF,0xDF,0xD7,0xCE,0xDE,0xE5,0xE7,0xFA,
+ 0xED,0xFD,0xF5,0xEA,0xF3,0xFB,0xD8,0xF8,
+ 0x00,0x2E,0x10,0x3C,0x2B,0x29,0x2F,0x04,
+ 0x37,0x3E,0x21,0x2C,0x20,0x24,0x28,0x0C,
+ 0x34,0x02,0x06,0x12,0x32,0x22,0x16,0x36,
+ 0x26,0x14,0x31,0x30,0x23,0x3F,0x1C,0x39,
+ 0x48,0x41,0x43,0x49,0x59,0x51,0x4B,0x5B,
+ 0x53,0x4A,0x5A,0x45,0x47,0x4D,0x5D,0x55,
+ 0x4F,0x5F,0x57,0x4E,0x5E,0x65,0x67,0x7A,
+ 0x6D,0x7D,0x75,0x6A,0x73,0x7B,0x58,0x38,
+ 0x08,0x01,0x03,0x09,0x19,0x11,0x0B,0x1B,
+ 0x13,0x0A,0x1A,0x05,0x07,0x0D,0x1D,0x15,
+ 0x0F,0x1F,0x17,0x0E,0x1E,0x25,0x27,0x3A,
+ 0x2D,0x3D,0x35,0x2A,0x33,0x3B,0x18,0x78,
+ 0x88,0x81,0x83,0x89,0x99,0x91,0x8B,0x9B,
+ 0x93,0x8A,0x9A,0x85,0x87,0x8D,0x9D,0x95,
+ 0x8F,0x9F,0x97,0x8E,0x9E,0xA5,0xA7,0xBA,
+ 0xAD,0xBD,0xB5,0xAA,0xB3,0xBB,0x98,0xB8,
+ 0x40,0x6E,0x50,0x7C,0x6B,0x69,0x6F,0x44,
+ 0x77,0x7E,0x61,0x6C,0x60,0x64,0x68,0x4C,
+ 0x74,0x42,0x46,0x52,0x72,0x62,0x56,0x76,
+ 0x66,0x54,0x71,0x70,0x63,0x7F,0x5C,0x79,
+ 0xC0,0xEE,0xD0,0xFC,0xEB,0xE9,0xEF,0xC4,
+ 0xF7,0xFE,0xE1,0xEC,0xE0,0xE4,0xE8,0xCC,
+ 0xF4,0xC2,0xC6,0xD2,0xF2,0xE2,0xD6,0xF6,
+ 0xE6,0xD4,0xF1,0xF0,0xE3,0xFF,0xDC,0xF9,
+ 0x80,0xAE,0x90,0xBC,0xAB,0xA9,0xAF,0x84,
+ 0xB7,0xBE,0xA1,0xAC,0xA0,0xA4,0xA8,0x8C,
+ 0xB4,0x82,0x86,0x92,0xB2,0xA2,0x96,0xB6,
+ 0xA6,0x94,0xB1,0xB0,0xA3,0xBF,0x9C,0xB9
+};
+
+void
+InitBraille()
+{
+ bd.bd_start_braille=0;
+ bd.bd_port = 0;
+ bd.bd_braille_table = SaveStr("internal us-braille.tbl");
+ bd.bd_type = 0;
+ bd.bd_baud = 9600;
+ bd.bd_bell = 1;
+ bd.bd_eightdot = 1;
+ bd.bd_info = 0;
+ bd.bd_link = 1;
+ bd.bd_ncells = 0;
+ bd.bd_width = 0;
+ bd.bd_ncrc = 1;
+ bd.bd_scroll = 1;
+ bd.bd_skip = 0;
+ bd.bd_using_braille = 0;
+ bd.bd_obuflen = 0;
+ bd.bd_fd = -1;
+ bcopy((char *)btable_local, bd.bd_btable, 256);
+}
+
+static int
+initialize_braille_display_type(s)
+char *s;
+{
+ int i;
+
+ for (i = 0; i < sizeof(bd_typelist)/sizeof(*bd_typelist); i++)
+ if (!strcmp(s, bd_typelist[i].name))
+ break;
+ if (i == sizeof(bd_typelist)/sizeof(*bd_typelist))
+ {
+ Msg(0, "No entry for bd_type: %s ", s);
+ return -1;
+ }
+ bd.bd_type = bd_typelist[i].name;
+ if ((*bd_typelist[i].init)())
+ return -1;
+
+ if (!bd.bd_width)
+ bd.bd_width = bd.bd_ncells;
+
+ return 0;
+}
+
+void
+StartBraille()
+{
+ bd.bd_dpy = displays;
+
+ debug("StartBraille called\n");
+ evdeq(&bd.bd_readev);
+ evdeq(&bd.bd_writeev);
+ evdeq(&bd.bd_selectev);
+ bd.bd_using_braille = 0;
+
+ if (!bd.bd_start_braille)
+ return;
+
+ if (bd.bd_type == 0 || bd.bd_port == 0)
+ return;
+
+ if (bd.bd_fd < 0 && open_braille_device())
+ {
+ Msg(0, "bd_port turned off");
+ free(bd.bd_port);
+ bd.bd_port = 0;
+ return;
+ }
+
+ /* check if braille display is connected and turned on */
+ if (bd.bd_response_test())
+ {
+ Msg(0, "Make sure that braille display is connected and turned on. ");
+ Msg(0, "start_braille turned off");
+ bd.bd_start_braille = 0;
+ }
+ else
+ {
+ bd.bd_using_braille = 1;
+ bd.bd_readev.fd = bd.bd_writeev.fd = bd.bd_fd;
+ bd.bd_readev.type = EV_READ;
+ bd.bd_writeev.type = EV_WRITE;
+ bd.bd_selectev.type = EV_ALWAYS;
+ bd.bd_readev.data = bd.bd_writeev.data = bd.bd_selectev.data = (char *)&bd;
+ bd.bd_readev.handler = bd_readev_fn;
+ bd.bd_writeev.handler = bd_writeev_fn;
+ bd.bd_selectev.handler = bd_selectev_fn;
+ evenq(&bd.bd_readev);
+ bd.bd_writeev.condpos = &bd.bd_obuflen;
+ bd.bd_writeev.condneg = 0;
+ evenq(&bd.bd_writeev);
+ bd.bd_selectev.pri = -20;
+ evenq(&bd.bd_selectev);
+ }
+}
+
+
+static int
+load_braille_table(tablename)
+char *tablename;
+{
+ int i, j, c, p;
+ FILE *fp;
+ char buffer[80], a[10];
+
+ if ((fp = fopen(tablename, "r")) == 0)
+ {
+ Msg(0, "Braille table not found: %s ", tablename);
+ return -1;
+ }
+ bzero(bd.bd_btable, 256);
+ while (fgets(buffer, sizeof(buffer), fp))
+ {
+ if (buffer[0] == '#')
+ continue;
+ sscanf(buffer,"%d %x %s", &i, &j, a);
+ for (j=1, p=1, c=0; j<9; j++, p*=2)
+ if (a[j] == '0' + j)
+ c += p;
+ bd.bd_btable[i] = c;
+ }
+ fclose(fp);
+ return 0;
+}
+
+
+static int
+open_braille_device(s)
+char *s;
+{
+ char str[256];
+
+ sprintf(str, "%d cs8 -istrip ixon ixoff", bd.bd_baud);
+ bd.bd_fd = OpenTTY(bd.bd_port, str);
+ if (bd.bd_fd == -1)
+ {
+ Msg(errno, "open comm port failed: %s ", bd.bd_port);
+ return -1;
+ }
+ fcntl(bd.bd_fd, F_SETFL, FNBLOCK);
+ return 0;
+}
+
+
+static void
+position_braille_cursor()
+{
+ int sx = bd.bd_sx;
+ int bx = BD_FORE->w_bd_x;
+ int eol = BD_FORE->w_width;
+ int w = bd.bd_width;
+
+ if (bd.bd_scroll)
+ bx = sx - w + bd.bd_ncrc; /* keep rc centered in window */
+ else
+ bx = w * (int)(sx / w); /* increase bc in integral steps */
+
+ if (bx > eol - w)
+ bx = eol - w;
+ if (bx < 0)
+ bx = 0;
+ BD_FORE->w_bd_x = bx;
+ BD_FORE->w_bd_y = bd.bd_sy;
+}
+
+
+void
+RefreshBraille()
+{
+ int i, y, xs, xe;
+ int cursor_pos;
+
+ if (!bd.bd_using_braille)
+ return;
+ if (!BD_FORE)
+ return;
+ bcopy(bd.bd_line, bd.bd_oline, bd.bd_ncells);
+ bd.bd_refreshing = 1;
+ flayer = bd.bd_dpy->d_forecv->c_layer;
+ bd.bd_sx = flayer->l_x;
+ bd.bd_sy = flayer->l_y;
+ display = bd.bd_dpy;
+ if ((D_obufp != D_obuf) && bd.bd_link)
+ {
+ /* jump to real cursor */
+ debug("calling position_braille_cursor\n");
+ position_braille_cursor();
+ }
+ bclear(bd.bd_line, bd.bd_ncells);
+
+ y = BD_FORE->w_bd_y;
+ xs = BD_FORE->w_bd_x;
+
+ if (bd.bd_info & 1)
+ {
+ sprintf(bd.bd_line, "%02d%02d", (BD_FORE->w_bd_x + 1) % 100, (BD_FORE->w_bd_y + 1) % 100);
+ bd.bd_line[4] = ' ';
+ }
+ if (bd.bd_info & 2)
+ {
+ sprintf(bd.bd_line + bd.bd_ncells - 4, "%02d%02d",(bd.bd_sx +1) % 100, (bd.bd_sy +1) % 100);
+ }
+
+ xe = xs + bd.bd_width - 1;
+
+ if (xs > flayer->l_width - 1)
+ xs = flayer->l_width - 1;
+ if (xe > flayer->l_width - 1)
+ xe = flayer->l_width - 1;
+
+ if (D_status)
+ {
+ sprintf(bd.bd_line, "**%-*.*s", bd.bd_ncells - 2, bd.bd_ncells - 2, D_status_lastmsg ? D_status_lastmsg : "unknown msg");
+ xs = xe = -1;
+ }
+ else if (xs <= xe)
+ {
+ RedisplayLine(-1, xs, xe, 1);
+ RedisplayLine(y, xs, xe, 1);
+ }
+
+ debug1("Braille: got >%s<\n", bd.bd_line);
+
+ bd.bd_refreshing = 0;
+
+ if (y == bd.bd_sy && xs <= bd.bd_sx && bd.bd_sx <= xe)
+ cursor_pos = bd.bd_sx - xs + (bd.bd_info & 1 ? 4 : 0);
+ else
+ cursor_pos = bd.bd_ncells;
+ for (i = 0; i < bd.bd_ncells; i++)
+ if (bd.bd_line[i] != bd.bd_oline[i])
+ break;
+ if (bd.bd_cursorpos != cursor_pos || i < bd.bd_ncells)
+ bd.write_line_braille(bd.bd_line, bd.bd_ncells, cursor_pos);
+ bd.bd_cursorpos = cursor_pos;
+}
+
+
+/**********************************************************************
+ *
+ */
+
+/*
+ * So, why is there a Flush() down below? The reason is simple: the
+ * cursor warp (if bd_link is on) checks the obuf to see if something
+ * happened. If there would be no Flush, screen would warp the
+ * bd cursor if a bd movement command tries to ring the bell.
+ * (In other words: this is a gross hack!)
+ */
+static void
+bd_signal()
+{
+ if (!bd.bd_bell)
+ return;
+ display = bd.bd_dpy;
+ if (D_obufp != D_obuf)
+ PutStr(D_BL);
+ else
+ {
+ PutStr(D_BL);
+ Flush();
+ }
+}
+
+static int
+bd_do_search(y, xs, xe)
+int y, xs, xe;
+{
+ int oy = BD_FORE->w_bd_y;
+
+ if (!bd.bd_skip) /* no skip mode, found it */
+ {
+ if (xs > xe)
+ return 0;
+ bd.bd_searchmin = xs;
+ bd.bd_searchmax = xe;
+ return 1;
+ }
+ flayer = bd.bd_dpy->d_forecv->c_layer;
+ bd.bd_searchmax = -1;
+ bd.bd_searchmin = flayer->l_width;
+ if (xs <= xe)
+ {
+ BD_FORE->w_bd_y = y; /* stupid hack */
+ bd.bd_refreshing = bd.bd_searching = 1;
+ bd.bd_searchstart = xs;
+ bd.bd_searchend = xe;
+ RedisplayLine(-1, xs, xe, 1);
+ RedisplayLine(y, xs, xe, 1);
+ bd.bd_refreshing = bd.bd_searching = 0;
+ BD_FORE->w_bd_y = oy;
+ }
+ return bd.bd_searchmax >= 0;
+}
+
+static void
+bd_normalize(x, y)
+int x, y;
+{
+ if (x > BD_FORE->w_width - bd.bd_width)
+ x = BD_FORE->w_width - bd.bd_width;
+ if (x < 0)
+ x = 0;
+ if (y < 0)
+ {
+ bd_signal();
+ y = 0;
+ }
+ if (y >= BD_FORE->w_height)
+ {
+ bd_signal();
+ y = BD_FORE->w_height - 1;
+ }
+ if (x != BD_FORE->w_bd_x || y != BD_FORE->w_bd_y)
+ bd.bd_moved = 1;
+ BD_FORE->w_bd_x = x;
+ BD_FORE->w_bd_y = y;
+}
+
+static void
+bd_bc_left()
+{
+ int bx = BD_FORE->w_bd_x, by = BD_FORE->w_bd_y;
+ int ex;
+
+ ex = bx - 1;
+ bx = 0;
+ for (; by >= 0; by--)
+ {
+ if (bd_do_search(by, 0, ex))
+ {
+ if (!bd.bd_skip && by != BD_FORE->w_bd_y)
+ bd_signal();
+ bx = bd.bd_searchmax + 1 - bd.bd_width;
+ break;
+ }
+ ex = BD_FORE->w_width - 1;
+ }
+ bd_normalize(bx, by);
+}
+
+static void
+bd_bc_right()
+{
+ int bx = BD_FORE->w_bd_x, by = BD_FORE->w_bd_y;
+ int sx;
+
+ sx = bx + bd.bd_width;
+ bx = BD_FORE->w_width - bd.bd_width;
+ for (; by < BD_FORE->w_height; by++)
+ {
+ if (bd_do_search(by, sx, BD_FORE->w_width - 1))
+ {
+ if (!bd.bd_skip && by != BD_FORE->w_bd_y)
+ bd_signal();
+ bx = bd.bd_searchmin;
+ break;
+ }
+ sx = 0;
+ }
+ bd_normalize(bx, by);
+}
+
+static void
+bd_bc_up()
+{
+ int bx = BD_FORE->w_bd_x, by = BD_FORE->w_bd_y;
+
+ for (by--; by >= 0; by--)
+ if (bd_do_search(by, bx, bx + bd.bd_width - 1))
+ break;
+ bd_normalize(bx, by);
+}
+
+static void
+bd_bc_down()
+{
+ int bx = BD_FORE->w_bd_x, by = BD_FORE->w_bd_y;
+
+ for (by++; by < BD_FORE->w_height; by++)
+ if (bd_do_search(by, bx, bx + bd.bd_width - 1))
+ break;
+ bd_normalize(bx, by);
+}
+
+
+static void
+bd_upper_left()
+{
+ bd_normalize(0, 0);
+}
+
+
+static void
+bd_upper_right()
+{
+ bd_normalize(BD_FORE->w_width - bd.bd_width, 0);
+}
+
+
+static void
+bd_lower_left()
+{
+ bd_normalize(0, BD_FORE->w_height - 1);
+}
+
+
+static void
+bd_lower_right()
+{
+ bd_normalize(BD_FORE->w_width - bd.bd_width, BD_FORE->w_height -1);
+}
+
+/**********************************************************************
+ *
+ */
+
+
+static void
+bd_check(x, c)
+int x, c;
+{
+ if (c == ' ')
+ return;
+ if (x < bd.bd_searchstart || x > bd.bd_searchend)
+ return;
+ if (x > bd.bd_searchmax)
+ bd.bd_searchmax = x;
+ if (x < bd.bd_searchmin)
+ bd.bd_searchmin = x;
+}
+
+
+
+/*ARGSUSED*/
+void
+BGotoPos(la, x, y)
+struct layer *la;
+int x, y;
+{
+}
+
+/*ARGSUSED*/
+void
+BCDisplayLine(la, ml, y, xs, xe, isblank)
+struct layer *la;
+struct mline *ml;
+int y, xs, xe;
+int isblank;
+{
+ int x;
+ int sx, ex;
+ char *l;
+
+ if (y != BD_FORE->w_bd_y)
+ return;
+ if (bd.bd_searching)
+ {
+ for (x = xs; x <= xe; x++)
+ bd_check(x, ml->image[x]);
+ return;
+ }
+ l = bd.bd_line;
+ sx = BD_FORE->w_bd_x;
+ ex = sx + bd.bd_width - 1;
+ if (bd.bd_info & 1)
+ l += 4;
+ for (x = xs; x <= xe; x++)
+ if (x >= sx && x <= ex)
+ l[x - sx] = ml->image[x];
+}
+
+/*ARGSUSED*/
+void
+BPutChar(la, c, x, y)
+struct layer *la;
+struct mchar *c;
+int x, y;
+{
+ int sx, ex;
+ char *l;
+
+ if (y != BD_FORE->w_bd_y)
+ return;
+ if (bd.bd_searching)
+ {
+ bd_check(x, c->image);
+ return;
+ }
+ l = bd.bd_line;
+ sx = BD_FORE->w_bd_x;
+ ex = sx + bd.bd_width - 1;
+ if (bd.bd_info & 1)
+ l += 4;
+ if (x >= sx && x <= ex)
+ l[x - sx] = c->image;
+}
+
+/*ARGSUSED*/
+void
+BPutStr(la, s, n, r, x, y)
+struct layer *la;
+char *s;
+int n;
+struct mchar *r;
+int x, y;
+{
+ int sx, ex;
+ char *l;
+
+ if (y != BD_FORE->w_bd_y)
+ return;
+ if (bd.bd_searching)
+ {
+ for (; n > 0; n--, s++, x++)
+ bd_check(x, *s);
+ return;
+ }
+ l = bd.bd_line;
+ sx = BD_FORE->w_bd_x;
+ ex = sx + bd.bd_width - 1;
+ if (bd.bd_info & 1)
+ l += 4;
+ for (; n > 0; n--, s++, x++)
+ if (x >= sx && x <= ex)
+ l[x - sx] = *s;
+}
+
+
+
+/**********************************************************************
+ *
+ */
+
+static char *infonames[] = {"none", "bc", "sc", "bc+sc"};
+
+void
+DoBrailleAction(act, msgok)
+struct action *act;
+int msgok;
+{
+ int nr, dosig;
+ int n, l, o;
+ char *s, **args;
+ struct stat st;
+
+ nr = act->nr;
+ args = act->args;
+ dosig = display && !*rc_name;
+
+ switch(nr)
+ {
+ case RC_BD_BELL:
+ if (ParseSwitch(act, &bd.bd_bell) || !msgok)
+ {
+ bd_signal();
+ break;
+ }
+ Msg(0, bd.bd_bell ? "bd_bell is on." : "bd_bell is off.");
+ break;
+
+ case RC_BD_EIGHTDOT:
+ if (ParseSwitch(act, &bd.bd_eightdot) || !msgok)
+ break;
+ Msg(0, "switched to %d-dots system.", bd.bd_eightdot ? 8 : 6);
+ break;
+
+ case RC_BD_INFO:
+ n = bd.bd_info;
+ if (*args)
+ {
+ if (strlen(*args) == 4)
+ n = args[0][n] - '0';
+ else if (ParseNum(act, &n))
+ break;
+ }
+ if (n < 0 && n > 3)
+ {
+ Msg(0, "Out of range; 0 <= bd_info >= 3 ");
+ break;
+ }
+ /* bd_width at the beginning is unknown */
+ if (bd.bd_width == 0)
+ break;
+
+ o = (bd.bd_info * 2 + 2) & 12;
+ l = (n * 2 + 2) & 12;
+ if (l >= bd.bd_ncells)
+ {
+ Msg(0, "bd_info is too large for braille display.");
+ break;
+ }
+ if (l >= bd.bd_width + o)
+ {
+ Msg(0, "bd_info is too large for bd_width.");
+ break;
+ }
+ bd.bd_width += o - l;
+ bd.bd_info = n;
+
+ if (msgok)
+ Msg(0, "bd_info is %s.", infonames[n]);
+ position_braille_cursor();
+ break;
+
+ case RC_BD_LINK:
+ if (*args == 0 && bd.bd_moved)
+ bd.bd_link = 0;
+ if (ParseSwitch(act, &bd.bd_link))
+ break;
+ if (bd.bd_link)
+ {
+ bd.bd_moved = 0;
+ if (dosig)
+ bd_signal();
+ position_braille_cursor();
+ }
+ if (msgok)
+ Msg(0, bd.bd_link ? "bd_link is on." : "bd_link is off.");
+ break;
+
+ case RC_BD_SKIP:
+ if (ParseSwitch(act, &bd.bd_skip))
+ break;
+ if (bd.bd_skip && dosig)
+ bd_signal();
+ if (msgok)
+ Msg(0, bd.bd_skip ? "bd_skip is on." : "bd_skip is off.");
+ break;
+
+ case RC_BD_SCROLL:
+ if (ParseSwitch(act, &bd.bd_scroll) || !msgok)
+ {
+ position_braille_cursor();
+ break;
+ }
+ Msg(0, bd.bd_scroll ? "bd_scroll is on." : "bd_scroll is off.");
+ break;
+
+ case RC_BD_NCRC:
+ n = bd.bd_ncrc;
+ if (*args)
+ {
+ if (args[0][0] == '+')
+ n = (n + atoi(*args + 1)) % bd.bd_width + 1;
+ else if (args[0][0] == '-')
+ n = (n - atoi(*args + 1)) % bd.bd_width + 1;
+ else if (ParseNum(act, &n))
+ break;
+ }
+ if (n < 1 || n > bd.bd_width)
+ {
+ Msg(0, "Out of range; 1 <= bd_ncrc >= %d", bd.bd_width);
+ break;
+ }
+ bd.bd_ncrc = n;
+ if (msgok)
+ Msg(0, "bd_ncrc status is: %d ", bd.bd_ncrc);
+ position_braille_cursor();
+ break;
+
+ case RC_BD_BRAILLE_TABLE:
+ s = 0;
+ if (*args)
+ {
+ if (ParseSaveStr(act, &s))
+ break;
+ if (load_braille_table(s))
+ {
+ free(s);
+ break;
+ }
+ if (bd.bd_braille_table)
+ free(bd.bd_braille_table);
+ bd.bd_braille_table = s;
+ }
+ if (msgok)
+ Msg(0, "bd_braille_table is: %s ", bd.bd_braille_table);
+ break;
+
+ case RC_BD_PORT:
+ s = 0;
+ if (*args)
+ {
+ if (ParseSaveStr(act, &s))
+ break;
+
+ if (stat(s, &st) || !S_ISCHR(st.st_mode) || access(s, R_OK|W_OK))
+ {
+ Msg(0, "Cannot access braille device port %s", s);
+ free(s);
+ break;
+ }
+ if (bd.bd_fd >= 0)
+ close(bd.bd_fd);
+ bd.bd_fd = -1;
+ if (bd.bd_port)
+ free(bd.bd_port);
+ bd.bd_port = s;
+ }
+ if (msgok)
+ Msg(0, "bd_port is: %s ", bd.bd_port ? bd.bd_port : "not set");
+ StartBraille();
+ break;
+
+ case RC_BD_TYPE:
+ s = 0;
+ if (*args)
+ if (ParseSaveStr(act, &s) || initialize_braille_display_type(s))
+ break;
+ if (msgok)
+ Msg(0, "bd_type is: %s ", bd.bd_type ? bd.bd_type : "not set");
+ StartBraille();
+ break;
+
+ case RC_BD_START_BRAILLE:
+ if (ParseSwitch(act, &bd.bd_start_braille))
+ break;
+ if (msgok)
+ Msg(0, bd.bd_start_braille ? "bd_start_braille is on." : "bd_start_braille is off.");
+ StartBraille();
+ break;
+
+ case RC_BD_WIDTH:
+ n = bd.bd_width;
+ if (*args)
+ {
+ if (ParseNum(act, &n))
+ break;
+ }
+ if (n <= 0)
+ {
+ Msg(0, "Invalid value for bd_width: %d ", n);
+ break;
+ }
+ l = (bd.bd_info * 2 + 2) & 12;
+ if (n > bd.bd_ncells - l || n < l)
+ {
+ Msg(0, "bd_info is too large for bd_width.");
+ break;
+ }
+ bd.bd_width = n;
+ if (msgok)
+ Msg(0, "bd_width is: %d ", bd.bd_width);
+ break;
+
+ case RC_BD_BC_LEFT:
+ bd_bc_left();
+ break;
+
+ case RC_BD_BC_RIGHT:
+ bd_bc_right();
+ break;
+
+ case RC_BD_BC_UP:
+ bd_bc_up();
+ break;
+
+ case RC_BD_BC_DOWN:
+ bd_bc_down();
+ break;
+
+ case RC_BD_UPPER_LEFT:
+ bd_upper_left();
+ break;
+
+ case RC_BD_UPPER_RIGHT:
+ bd_upper_right();
+ break;
+
+ case RC_BD_LOWER_LEFT:
+ bd_lower_left();
+ break;
+
+ case RC_BD_LOWER_RIGHT:
+ bd_lower_right();
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void
+bd_readev_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ bd.buttonpress();
+}
+
+static void
+bd_writeev_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ int len;
+
+ if (bd.bd_obuflen == 0)
+ return;
+ if ((len = write(bd.bd_fd, bd.bd_obuf, bd.bd_obuflen)) < 0)
+ len = bd.bd_obuflen; /* dead braille display */
+ if ((bd.bd_obuflen -= len))
+ bcopy(bd.bd_obuf + len, bd.bd_obuf, bd.bd_obuflen);
+}
+
+static void
+bd_selectev_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ RefreshBraille();
+}
+
+#endif /* HAVE_BRAILLE */
diff --git a/braille.h b/braille.h
new file mode 100644
index 0000000..4d751b8
--- /dev/null
+++ b/braille.h
@@ -0,0 +1,80 @@
+/*
+ * Authors: Hadi Bargi Rangin bargi@dots.physics.orst.edu
+ * Bill Barry barryb@dots.physics.orst.edu
+ * Randy Lundquist randyl@dots.physics.orst.edu
+ *
+ * Modifications Copyright (c) 1995 by
+ * Science Access Project, Oregon State University.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING); if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ ****************************************************************
+ * $Id: braille.h,v 1.1 1995/09/06 15:51:18 jnweiger Exp jnweiger $ FAU
+ */
+
+extern void StartBraille __P((void));
+
+struct braille_display
+{
+ struct display *bd_dpy; /* display we are connected to */
+ int bd_start_braille; /* screenrc var to request to turn braille on */
+ int bd_using_braille; /* all is fine, use braille */
+ struct event bd_readev;
+ struct event bd_writeev;
+ struct event bd_selectev;
+ int bd_fd; /* file descriptor */
+ int bd_obuflen; /* current number of charactors in output buffer */
+ char bd_obuf[IOSIZE];
+ int bd_info; /* default, no info, 0,1,2,3 */
+ int bd_ncrc; /* default 1, numbers of cells on the right side of real cursor, 1...bd_width */
+ int bd_skip; /* default off, on/off */
+ int bd_link; /* default, linked, on/off */
+ int bd_width; /* length of braille display to use, <=bd_ncells */
+ int bd_scroll; /* default on, scroll on/off */
+ char *bd_braille_table; /* braille code */
+
+ int bd_bell; /* bell used for navigation on/off */
+ int bd_ncells; /* real number of cells on braille display */
+ int bd_eightdot; /* eightdot on/off */
+ int bd_baud; /* communication baudrate between port and braille display */
+ char *bd_port; /* serial port to use */
+ char *bd_type; /* kind of braille display */
+ double bd_version; /* rom version of braille display */
+ char bd_btable[256]; /* braille translation table */
+
+ /* functions which communicate with braille displays */
+ int (*write_line_braille) __P((char [],int, int));
+ void (*buttonpress) __P((void));
+ int (*bd_response_test) __P((void));
+
+ int bd_refreshing; /* are we doing a refresh? */
+ char bd_line[40+1]; /* bd_ncells chars displayed on braille */
+ int bd_cursorpos; /* cursor position on braille */
+ char bd_oline[40+1]; /* bd_ncells chars displayed on braille */
+ int bd_sx, bd_sy; /* screen cursor pos */
+ int bd_moved; /* used braille move keys */
+
+ int bd_searching; /* are we seaching (bd_skip is on) */
+ int bd_searchmax; /* search: max x */
+ int bd_searchmin; /* search: min x */
+ int bd_searchstart;
+ int bd_searchend;
+};
+
+extern struct braille_display bd;
+
+#define BD_FORE bd.bd_dpy->d_fore
+
diff --git a/braille_tsi.c b/braille_tsi.c
new file mode 100644
index 0000000..672a85d
--- /dev/null
+++ b/braille_tsi.c
@@ -0,0 +1,317 @@
+/* bd-tsi.c, TSI specific key bindings and display commands
+ *
+ * dotscreen
+ * A braille interface to unix tty terminals
+ * Authors: Hadi Bargi Rangin bargi@dots.physics.orst.edu
+ * Bill Barry barryb@dots.physics.orst.edu
+ *
+ * Copyright (c) 1995 by Science Access Project, Oregon State University.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING); if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ ****************************************************************
+ * $Id: bd-tsi.c,v 1.1 1995/09/06 15:46:36 jnweiger Exp jnweiger $
+ */
+
+#include "config.h"
+#include "screen.h"
+#include "extern.h"
+#include "braille.h"
+
+#ifdef HAVE_BRAILLE
+
+extern struct display *display;
+
+struct key2rc {
+ int key;
+ int nr;
+ char *arg1;
+ char *arg2;
+};
+
+
+static int tsi_ctype = 1; /* cursor type, 0,1,2 */
+
+static int tsi_line_type; /* indicates number of cells on powerbraille
+ display 01=20 cells 02=40 cells 03=80 cells */
+
+static int display_status_tsi __P((void));
+static int write_line_tsi __P((char *, int, int));
+static void buttonpress_tsi __P((struct key2rc *));
+static void buttonpress_navigator_40 __P((void));
+static void buttonpress_powerbraille_40 __P((void));
+static void buttonpress_powerbraille_80 __P((void));
+
+int
+bd_init_powerbraille_40()
+{
+ bd.write_line_braille = write_line_tsi;
+ bd.buttonpress = buttonpress_powerbraille_40;
+ bd.bd_response_test = display_status_tsi;
+ bd.bd_ncells = 40;
+ tsi_line_type = 2;
+ return 0;
+}
+
+int
+bd_init_powerbraille_80()
+{
+ bd.write_line_braille = write_line_tsi;
+ bd.buttonpress = buttonpress_powerbraille_80;
+ bd.bd_response_test = display_status_tsi;
+ bd.bd_ncells = 80;
+ tsi_line_type = 3;
+ return 0;
+}
+
+int
+bd_init_navigator_40()
+{
+ bd.write_line_braille = write_line_tsi;
+ bd.buttonpress = buttonpress_navigator_40;
+ bd.bd_response_test = display_status_tsi;
+ bd.bd_ncells = 40;
+ tsi_line_type = 2;
+ return 0;
+}
+
+static int
+display_status_tsi()
+{
+ char obuf[3],ibuf[20];
+ int r;
+
+ obuf[0] = 0xff;
+ obuf[1] = 0xff;
+ obuf[2] = 0x0a;
+ r = read(bd.bd_fd, ibuf, 20); /* flush the input port */
+ r = write(bd.bd_fd, obuf, 3);
+ if (r != 3)
+ return -1;
+
+ /* we have written to the display asking for a response
+ we wait 1 second for the response, read it and if no
+ response we wait 2 seconds, if still no response,
+ return -1 to indicate no braille display available */
+ sleep(1);
+ r = read(bd.bd_fd, ibuf, 2);
+ if (r == -1)
+ {
+ sleep(2);
+ r = read(bd.bd_fd, ibuf, 2);
+ }
+ debug2("first chars from braille display %d %d\n",ibuf[0],ibuf[1]);
+ if (r != 2 || ibuf[0] != 0 || ibuf[1] != 5)
+ return -1;
+
+ r= read(bd.bd_fd,ibuf,2);
+ if (r != 2)
+ return -1;
+ debug2("braille display size:%d dots:%d\n", ibuf[0], ibuf[1]);
+ bd.bd_ncells = (unsigned char)ibuf[0];
+ if (bd.bd_ncells <= 1)
+ return -1;
+ r = read(bd.bd_fd,ibuf,1);
+ if (r != 1)
+ return -1;
+ if (r != -1)
+ if (ibuf[0] == 'V')
+ r = read(bd.bd_fd, ibuf, 3);
+ else
+ r = read(bd.bd_fd, ibuf + 1, 2) + 1;
+ if (r != 3)
+ return -1;
+ ibuf[3] = 0;
+ debug1("braille display version %s\n", ibuf);
+ bd.bd_version = atof(ibuf);
+ return 0;
+}
+
+
+static int
+write_line_tsi (bstr,line_length, cursor_pos)
+char *bstr;
+int line_length, cursor_pos;
+{
+ int obp, i;
+ bd.bd_obuf[0] = 0xff;
+ bd.bd_obuf[1] = 0xff;
+ bd.bd_obuf[2] = tsi_line_type;
+ bd.bd_obuf[3] = 0x07;
+ bd.bd_obuf[4] = cursor_pos;
+ bd.bd_obuf[5] = tsi_ctype;
+ obp=6;
+
+ for (i=0; i < line_length; i++)
+ {
+ bd.bd_obuf[2*i+obp] = 0;
+ bd.bd_obuf[2*i+1+obp] = bd.bd_btable[(int)(unsigned char)bstr[i]];
+ }
+ for (i=line_length; i < bd.bd_ncells; i++)
+ {
+ bd.bd_obuf[2*i+obp] = 0;
+ bd.bd_obuf[2*i+1+obp] = bd.bd_btable[(int)' '];
+ }
+
+ bd.bd_obuflen = 2*bd.bd_ncells + obp ;
+ return 0;
+}
+
+static struct key2rc keys_navigator_40[] = {
+ {0x4000000, RC_STUFF, "-k", "kl"}, /* 1 */
+ {0x10000000, RC_STUFF, "-k", "kr"}, /* 3 */
+ {0x8000000, RC_STUFF, "-k", "ku"}, /* 2 */
+ {0x20000000, RC_STUFF, "-k", "kd"}, /* 4 */
+ {0x2000, RC_BD_BC_LEFT, 0, 0}, /* 6 */
+ {0x8000, RC_BD_BC_RIGHT, 0, 0}, /* 8 */
+ {0x4000, RC_BD_BC_UP, 0, 0}, /* 7 */
+ {0x10000, RC_BD_BC_DOWN, 0, 0}, /* 9 */
+ {0x6000, RC_BD_UPPER_LEFT, 0, 0}, /* 6, 7 */
+ {0xc000, RC_BD_UPPER_RIGHT, 0, 0}, /* 7, 8 */
+ {0x12000, RC_BD_LOWER_LEFT, 0, 0}, /* 6, 9 */
+ {0x18000, RC_BD_LOWER_RIGHT, 0, 0}, /* 8, 9 */
+ {0xa000, RC_BD_INFO, "1032", 0}, /* bc 6, 8 */
+ {0x14000000, RC_BD_INFO, "2301", 0}, /* sc 1, 3 */
+ {0x4008000, RC_BD_INFO, "3330", 0}, /* bc+sc 1, 8 */
+ {0x8010000, RC_BD_BELL, 0, 0}, /* 2, 9 */
+ {0x8004000, RC_BD_EIGHTDOT, 0, 0}, /* 2, 7 */
+ {0x40000000, RC_STUFF, "\015", 0}, /* 5 */
+ {0x20000, RC_BD_LINK, 0, 0}, /* 10 */
+ {0x10002000, RC_BD_SCROLL, 0, 0}, /* 3, 6 */
+ {0x20010000, RC_BD_NCRC, "+", 0}, /* 4, 9 */
+ {0x14000, RC_BD_SKIP, 0, 0}, /* 7, 9*/
+ {-1, RC_ILLEGAL, 0, 0}
+};
+
+static struct key2rc keys_powerbraille_40[] = {
+ {0x4000000, RC_STUFF, "-k", "kl"}, /* 1 */
+ {0x10000000, RC_STUFF, "-k", "kr"}, /* 3 */
+ {0x8000000, RC_STUFF, "-k", "ku"}, /* 2 */
+ {0x20000000, RC_STUFF, "-k", "kd"}, /* 4 */
+ {0x2000, RC_BD_BC_LEFT, 0, 0}, /* 6 */
+ {0x8000, RC_BD_BC_RIGHT, 0, 0}, /* 8 */
+ {0x4000, RC_BD_BC_UP, 0, 0}, /* 7 */
+ {0x10000, RC_BD_BC_DOWN, 0, 0}, /* 9 */
+ {0x8002000, RC_BD_UPPER_LEFT, 0, 0}, /* 2, 6 */
+ {0xc000, RC_BD_UPPER_RIGHT, 0, 0}, /* 7, 8 */
+ {0x20002000, RC_BD_LOWER_LEFT, 0, 0}, /* 3, 6 */
+ {0x18000, RC_BD_LOWER_RIGHT, 0, 0}, /* 8, 9 */
+ {0x8008000, RC_BD_INFO, "1032", 0}, /* bc 2, 8 */
+ {0x6000, RC_BD_INFO, "2301", 0}, /* 6, 7 */
+ {0x8004000, RC_BD_INFO, "3330", 0}, /* bc+sc 2, 7 */
+ {0x8010000, RC_BD_BELL, 0, 0}, /* 2, 9 */
+ {0x20008000, RC_BD_EIGHTDOT, 0, 0}, /* 4, 6 */
+ {0x40000000, RC_STUFF, "\015", 0}, /* 5 */
+ {0x20000, RC_BD_LINK, 0, 0}, /* 10 */
+ {0xa000, RC_BD_SCROLL, 0, 0}, /* 6, 8 */
+ {0x20010000, RC_BD_NCRC, "+", 0}, /* 4, 9 */
+ {0x20004000, RC_BD_SKIP, 0, 0}, /* 4, 7 */
+ {-1, RC_ILLEGAL, 0, 0}
+};
+
+
+static struct key2rc keys_powerbraille_80[] = {
+ {0x4000000, RC_STUFF, "-k", "kl"}, /* 1 */
+ {0x10000000, RC_STUFF, "-k", "kr"}, /* 3 */
+ {0x8000000, RC_STUFF, "-k", "ku"}, /* 2 */
+ {0x20000000, RC_STUFF, "-k", "kd"}, /* 4 */
+ {0x40000, RC_BD_BC_LEFT, 0, 0}, /* 6 */
+ {0x100000, RC_BD_BC_RIGHT, 0, 0}, /* 8 */
+ {0x4000, RC_BD_BC_UP, 0, 0}, /* 7 */
+ {0x10000, RC_BD_BC_DOWN, 0, 0}, /* 9 */
+ {0x44000, RC_BD_UPPER_LEFT, 0, 0}, /* 6, 7 */
+ {0x104000, RC_BD_UPPER_RIGHT, 0, 0}, /* 7, 8 */
+ {0x50000, RC_BD_LOWER_LEFT, 0, 0}, /* 6, 9 */
+ {0x110000, RC_BD_LOWER_RIGHT, 0, 0}, /* 8, 9 */
+ {0x8100000, RC_BD_INFO, "1032", 0}, /* 2, 8 */
+ {0x8040000, RC_BD_INFO, "2301", 0}, /* 2, 6 */
+ {0x140000, RC_BD_INFO, "3330", 0}, /* 6, 8 */
+ {0x8010000, RC_BD_BELL, 0, 0}, /* 2, 9 */
+ {0x8004000, RC_BD_EIGHTDOT, 0, 0}, /* 2, 7 */
+ {0x40000000, RC_STUFF, "\015", 0}, /* 5 */
+ {0x20000, RC_BD_LINK, 0, 0}, /* 10 */
+ {0x20004000, RC_BD_SCROLL, 0, 0}, /* 4, 7 */
+ {0x20010000, RC_BD_NCRC, "+", 0}, /* 4, 9 */
+ {0x40010000, RC_BD_SKIP, 0, 0}, /* 5, 9 */
+ {-1, RC_ILLEGAL, 0, 0}
+};
+
+static void
+buttonpress_tsi(tab)
+struct key2rc *tab;
+{
+ int i, nb;
+ int bkeys;
+ unsigned char buf[10];
+ nb = read(bd.bd_fd, buf, 10);
+ debug1("buttonpress_tsi: read %d bytes\n", nb);
+ for (i=0, bkeys=0; i < nb; i++)
+ {
+ switch (buf[i] & 0xE0)
+ {
+ case 0x00: bkeys += ((int)(buf[i] & 0x1f) ); break;
+ case 0x20: bkeys += ((int)(buf[i] & 0x1f) << 5 ); break;
+ case 0x40: bkeys += ((int)(buf[i] & 0x1f) << 9 ); break;
+ case 0x60: bkeys += ((int)(buf[i] & 0x1f) << 13 ); break;
+ case 0xA0: bkeys += ((int)(buf[i] & 0x1f) << 18 ); break;
+ case 0xC0: bkeys += ((int)(buf[i] & 0x1f) << 22 ); break;
+ case 0xE0: bkeys += ((int)(buf[i] & 0x1f) << 26 ); break;
+ default: break;
+ }
+ }
+ debug1("bkeys %x\n", bkeys);
+ for (i = 0; tab[i].key != -1; i++)
+ if (bkeys == tab[i].key)
+ break;
+ debug1("bkey index %d\n", i);
+ if (tab[i].key != -1 && tab[i].nr != RC_ILLEGAL)
+ {
+ char *args[3];
+
+ struct action act;
+ args[0] = tab[i].arg1;
+ args[1] = tab[i].arg2;
+ args[2] = 0;
+ act.nr = tab[i].nr;
+ act.args = args;
+ display = bd.bd_dpy;
+ DoAction(&act, -2);
+ }
+}
+
+
+static void
+buttonpress_navigator_40()
+{
+ buttonpress_tsi(keys_navigator_40);
+}
+
+static void
+buttonpress_powerbraille_40()
+{
+ buttonpress_tsi(keys_powerbraille_40);
+}
+
+static void
+buttonpress_powerbraille_80()
+{
+ buttonpress_tsi(keys_powerbraille_80);
+}
+
+#endif /* HAVE_BRAILLE */
+
+
diff --git a/comm.c b/comm.c
index 1679929..ab468e6 100644
--- a/comm.c
+++ b/comm.c
@@ -3,6 +3,15 @@
* Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
* Copyright (c) 1987 Oliver Laumann
*
+#ifdef HAVE_BRAILLE
+ * Modified by:
+ * Authors: Hadi Bargi Rangin bargi@dots.physics.orst.edu
+ * Bill Barry barryb@dots.physics.orst.edu
+ *
+ * Modifications Copyright (c) 1995 by
+ * Science Access Project, Oregon State University.
+#endif
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
@@ -28,196 +37,251 @@ RCS_ID("$Id: comm.c,v 1.10 1993/11/30 19:28:07 mlschroe Exp $ FAU")
#include "acls.h"
#include "comm.h"
+#define bcopy :-( /* or include screen.h here */
+
/* Must be in alpha order ! */
struct comm comms[RC_LAST + 1] =
{
#ifdef MULTIUSER
- { "acladd", ARGS_ONE },
- { "aclchg", ARGS_THREE },
- { "acldel", ARGS_ONE },
- { "aclgrp", ARGS_ONE },
-#endif
- { "activity", ARGS_ONE },
- { "aka", NEED_FORE|ARGS_ZEROONE }, /* TO BE REMOVED */
- { "allpartial", NEED_DISPLAY|ARGS_ONE },
- { "at", NEED_DISPLAY|ARGS_TWO|ARGS_ORMORE },
- { "autodetach", ARGS_ONE },
+ { "acladd", ARGS_1234 },
+ { "aclchg", ARGS_23 },
+ { "acldel", ARGS_1 },
+ { "aclgrp", ARGS_12 },
+ { "aclumask", ARGS_1|ARGS_ORMORE },
+#endif
+ { "activity", ARGS_1 },
+#ifdef MULTIUSER
+ { "addacl", ARGS_1234 },
+#endif
+ { "allpartial", NEED_DISPLAY|ARGS_1 },
+ { "at", NEED_DISPLAY|ARGS_2|ARGS_ORMORE },
+ { "autodetach", ARGS_1 },
#ifdef AUTO_NUKE
- { "autonuke", NEED_DISPLAY|ARGS_ONE },
+ { "autonuke", NEED_DISPLAY|ARGS_1 },
#endif
- { "bell", ARGS_ZEROONE },
- { "bell_msg", ARGS_ZEROONE },
- { "bind", ARGS_ONE|ARGS_ORMORE },
+
+#ifdef HAVE_BRAILLE
+/* keywords for braille display (bd) */
+ { "bd_bc_down", ARGS_0 },
+ { "bd_bc_left", ARGS_0 },
+ { "bd_bc_right", ARGS_0 },
+ { "bd_bc_up", ARGS_0 },
+ { "bd_bell", ARGS_01 },
+ { "bd_braille_table", ARGS_01 },
+ { "bd_eightdot", ARGS_01 },
+ { "bd_info", ARGS_01 },
+ { "bd_link", ARGS_01 },
+ { "bd_lower_left", ARGS_0 },
+ { "bd_lower_right", ARGS_0 },
+ { "bd_ncrc", ARGS_01 },
+ { "bd_port", ARGS_01 },
+ { "bd_scroll", ARGS_01 },
+ { "bd_skip", ARGS_01 },
+ { "bd_start_braille", ARGS_01 },
+ { "bd_type", ARGS_01 },
+ { "bd_upper_left", ARGS_0 },
+ { "bd_upper_right", ARGS_0 },
+ { "bd_width", ARGS_01 },
+#endif
+
+ { "bell", ARGS_01 },
+ { "bell_msg", ARGS_01 },
+ { "bind", ARGS_1|ARGS_ORMORE },
#ifdef MAPKEYS
- { "bindkey", ARGS_ZERO|ARGS_ORMORE },
+ { "bindkey", ARGS_0|ARGS_ORMORE },
#endif
- { "break", NEED_FORE|ARGS_ZEROONE },
+ { "break", NEED_FORE|ARGS_01 },
+ { "breaktype", NEED_FORE|ARGS_01 },
#ifdef COPY_PASTE
- { "bufferfile", ARGS_ZEROONE },
+ { "bufferfile", ARGS_01 },
#endif
- { "c1", NEED_FORE|ARGS_ZEROONE },
- { "charset", NEED_FORE|ARGS_ONE },
- { "chdir", ARGS_ZEROONE },
- { "clear", NEED_FORE|ARGS_ZERO },
-#ifdef MULTI
- { "clone", NEED_DISPLAY|ARGS_ONE|ARGS_ORMORE },
+ { "c1", NEED_FORE|ARGS_01 },
+ { "caption", ARGS_12 },
+#ifdef MULTIUSER
+ { "chacl", ARGS_23 },
+#endif
+ { "charset", NEED_FORE|ARGS_1 },
+ { "chdir", ARGS_01 },
+ { "clear", NEED_FORE|ARGS_0 },
+ { "colon", NEED_DISPLAY|ARGS_01 },
+ { "command", NEED_DISPLAY|ARGS_0 },
+#ifdef COPY_PASTE
+ { "compacthist", ARGS_01 },
#endif
- { "colon", NEED_DISPLAY|ARGS_ZEROONE },
- { "command", NEED_DISPLAY|ARGS_ZERO },
- { "console", NEED_FORE|ARGS_ZEROONE },
+ { "console", NEED_FORE|ARGS_01 },
#ifdef COPY_PASTE
- { "copy", NEED_FORE|ARGS_ZERO },
- { "crlf", ARGS_ZEROONE },
+ { "copy", NEED_FORE|ARGS_0 },
+ { "crlf", ARGS_01 },
#endif
- { "debug", ARGS_ZEROONE },
+ { "debug", ARGS_01 },
#ifdef AUTO_NUKE
- { "defautonuke", ARGS_ONE },
-#endif
- { "defc1", ARGS_ONE },
- { "defcharset", ARGS_ZEROONE },
- { "defescape", ARGS_ONE },
- { "defflow", ARGS_ONETWO },
- { "defgr", ARGS_ONE },
- { "defhstatus", ARGS_ZEROONE },
+ { "defautonuke", ARGS_1 },
+#endif
+ { "defbreaktype", ARGS_01 },
+ { "defc1", ARGS_1 },
+ { "defcharset", ARGS_01 },
+ { "defescape", ARGS_1 },
+ { "defflow", ARGS_12 },
+ { "defgr", ARGS_1 },
+ { "defhstatus", ARGS_01 },
#ifdef KANJI
- { "defkanji", ARGS_ONE },
+ { "defkanji", ARGS_1 },
#endif
#if defined(UTMPOK) && defined(LOGOUTOK)
- { "deflogin", ARGS_ONE },
+ { "deflogin", ARGS_1 },
#endif
- { "defmode", ARGS_ONE },
- { "defmonitor", ARGS_ONE },
- { "defobuflimit", ARGS_ONE },
+ { "defmode", ARGS_1 },
+ { "defmonitor", ARGS_1 },
+ { "defobuflimit", ARGS_1 },
#ifdef COPY_PASTE
- { "defscrollback", ARGS_ONE },
-#endif
- { "defwrap", ARGS_ONE },
- { "defwritelock", ARGS_ONE },
- { "detach", NEED_DISPLAY|ARGS_ZERO },
- { "digraph", NEED_DISPLAY|ARGS_ZEROONE },
- { "displays", NEED_DISPLAY|ARGS_ZERO },
- { "dumptermcap", NEED_FORE|ARGS_ZERO },
- { "echo", ARGS_ONETWO },
- { "escape", NEED_DISPLAY|ARGS_ONE },
+ { "defscrollback", ARGS_1 },
+#endif
+ { "defshell", ARGS_1 },
+ { "defsilence", ARGS_1 },
+ { "defslowpaste", ARGS_1 },
+ { "defwrap", ARGS_1 },
+ { "defwritelock", ARGS_1 },
+#ifdef DETACH
+ { "detach", NEED_DISPLAY|ARGS_0 },
+#endif
+ { "digraph", NEED_DISPLAY|ARGS_01 },
+ { "displays", NEED_DISPLAY|ARGS_0 },
+ { "dumptermcap", NEED_FORE|ARGS_0 },
+ { "echo", ARGS_12 },
+ { "escape", NEED_DISPLAY|ARGS_1 },
#ifdef PSEUDOS
- { "exec", NEED_FORE|ARGS_ZERO|ARGS_ORMORE },
-#endif
- { "flow", NEED_FORE|ARGS_ZEROONE },
- { "gr", NEED_FORE|ARGS_ZEROONE },
- { "hardcopy", NEED_FORE|ARGS_ZERO },
- { "hardcopy_append", ARGS_ONE },
- { "hardcopydir", ARGS_ONE },
- { "hardstatus", NEED_DISPLAY|ARGS_ZEROONE },
- { "height", NEED_DISPLAY|ARGS_ZEROONE },
- { "help", NEED_DISPLAY|ARGS_ZERO },
+ { "exec", NEED_FORE|ARGS_0|ARGS_ORMORE },
+#endif
+ { "fit", NEED_DISPLAY|ARGS_0 },
+ { "flow", NEED_FORE|ARGS_01 },
+ { "focus", NEED_DISPLAY|ARGS_0 },
+ { "gr", NEED_FORE|ARGS_01 },
+ { "hardcopy", NEED_FORE|ARGS_0 },
+ { "hardcopy_append", ARGS_1 },
+ { "hardcopydir", ARGS_1 },
+ { "hardstatus", ARGS_012 },
+ { "height", NEED_DISPLAY|ARGS_01 },
+ { "help", NEED_DISPLAY|ARGS_0 },
#ifdef COPY_PASTE
- { "history", NEED_FORE|ARGS_ZERO },
+ { "history", NEED_FORE|ARGS_0 },
#endif
- { "info", NEED_DISPLAY|ARGS_ZERO },
+ { "hstatus", NEED_FORE|ARGS_1 },
+ { "info", NEED_DISPLAY|ARGS_0 },
#ifdef KANJI
- { "kanji", NEED_FORE|ARGS_ONETWO },
+ { "kanji", NEED_FORE|ARGS_12 },
#endif
- { "kill", NEED_FORE|ARGS_ZERO },
- { "lastmsg", NEED_DISPLAY|ARGS_ZERO },
- { "license", NEED_DISPLAY|ARGS_ZERO },
+ { "kill", NEED_FORE|ARGS_0 },
+ { "lastmsg", NEED_DISPLAY|ARGS_0 },
+ { "license", NEED_DISPLAY|ARGS_0 },
#ifdef LOCK
- { "lockscreen", NEED_DISPLAY|ARGS_ZERO },
+ { "lockscreen", NEED_DISPLAY|ARGS_0 },
#endif
- { "log", NEED_FORE|ARGS_ZEROONE },
- { "logfile", ARGS_ZEROONE },
+ { "log", NEED_FORE|ARGS_01 },
+ { "logfile", ARGS_012 },
#if defined(UTMPOK) && defined(LOGOUTOK)
- { "login", NEED_FORE|ARGS_ZEROONE },
+ { "login", NEED_FORE|ARGS_01 },
#endif
+ { "logtstamp", ARGS_012 },
#ifdef MAPKEYS
- { "mapdefault", NEED_DISPLAY|ARGS_ZERO },
- { "mapnotnext", NEED_DISPLAY|ARGS_ZERO },
- { "maptimeout", ARGS_ZEROONE },
+ { "mapdefault", NEED_DISPLAY|ARGS_0 },
+ { "mapnotnext", NEED_DISPLAY|ARGS_0 },
+ { "maptimeout", ARGS_01 },
#endif
#ifdef COPY_PASTE
- { "markkeys", ARGS_ONE },
+ { "markkeys", ARGS_1 },
#endif
- { "meta", NEED_DISPLAY|ARGS_ZERO },
- { "monitor", NEED_FORE|ARGS_ZEROONE },
- { "msgminwait", ARGS_ONE },
- { "msgwait", ARGS_ONE },
+ { "meta", NEED_DISPLAY|ARGS_0 },
+ { "monitor", NEED_FORE|ARGS_01 },
+ { "msgminwait", ARGS_1 },
+ { "msgwait", ARGS_1 },
#ifdef MULTIUSER
- { "multiuser", ARGS_ONE },
+ { "multiuser", ARGS_1 },
#endif
#ifdef NETHACK
- { "nethack", ARGS_ONE },
+ { "nethack", ARGS_1 },
+#endif
+ { "next", NEED_DISPLAY|ARGS_0 },
+#ifdef MULTI
+ { "nonblock", NEED_DISPLAY|ARGS_01 },
#endif
- { "next", NEED_DISPLAY|NEED_FORE|ARGS_ZERO },
- { "number", NEED_FORE|ARGS_ZEROONE },
- { "obuflimit", NEED_DISPLAY|ARGS_ZEROONE },
- { "other", NEED_DISPLAY|NEED_FORE|ARGS_ZERO },
- { "partial", NEED_FORE|ARGS_ZEROONE },
+ { "number", NEED_FORE|ARGS_01 },
+ { "obuflimit", NEED_DISPLAY|ARGS_01 },
+ { "only", NEED_DISPLAY|ARGS_0 },
+ { "other", NEED_DISPLAY|ARGS_0 },
+ { "partial", NEED_FORE|ARGS_01 },
#ifdef PASSWORD
- { "password", ARGS_ZEROONE },
+ { "password", ARGS_01 },
#endif
#ifdef COPY_PASTE
- { "paste", NEED_DISPLAY|ARGS_ZEROONETWO },
- { "pastefont", ARGS_ZEROONE },
-#endif
- { "pow_break", NEED_FORE|ARGS_ZEROONE },
-#ifdef POW_DETACH
- { "pow_detach", NEED_DISPLAY|ARGS_ZERO },
- { "pow_detach_msg", ARGS_ZEROONE },
-#endif
- { "prev", NEED_DISPLAY|NEED_FORE|ARGS_ZERO },
- { "printcmd", ARGS_ZEROONE },
- { "process", NEED_DISPLAY|ARGS_ZEROONE },
- { "quit", ARGS_ZERO },
+ { "paste", NEED_DISPLAY|ARGS_012 },
+ { "pastefont", ARGS_01 },
+#endif
+ { "pow_break", NEED_FORE|ARGS_01 },
+#if defined(DETACH) && defined(POW_DETACH)
+ { "pow_detach", NEED_DISPLAY|ARGS_0 },
+ { "pow_detach_msg", ARGS_01 },
+#endif
+ { "prev", NEED_DISPLAY|ARGS_0 },
+ { "printcmd", ARGS_01 },
+ { "process", NEED_DISPLAY|ARGS_01 },
+ { "quit", ARGS_0 },
#ifdef COPY_PASTE
- { "readbuf", NEED_DISPLAY|ARGS_ZERO },
+ { "readbuf", NEED_DISPLAY|ARGS_0 },
#endif
- { "readreg", ARGS_ZEROONETWO },
- { "redisplay", NEED_DISPLAY|ARGS_ZERO },
- { "register", ARGS_TWO },
+ { "readreg", ARGS_012 },
+ { "redisplay", NEED_DISPLAY|ARGS_0 },
+ { "register", ARGS_2 },
+ { "remove", NEED_DISPLAY|ARGS_0 },
#ifdef COPY_PASTE
- { "removebuf", ARGS_ZERO },
+ { "removebuf", ARGS_0 },
#endif
- { "reset", NEED_FORE|ARGS_ZERO },
- { "screen", ARGS_ZERO|ARGS_ORMORE },
+ { "reset", NEED_FORE|ARGS_0 },
+ { "screen", ARGS_0|ARGS_ORMORE },
#ifdef COPY_PASTE
- { "scrollback", NEED_FORE|ARGS_ONE },
-#endif
- { "select", ARGS_ZEROONE },
- { "sessionname", ARGS_ZEROONE },
- { "setenv", ARGS_ZEROONETWO },
- { "shell", ARGS_ONE },
- { "shellaka", ARGS_ONE }, /* TO BE REMOVED */
- { "shelltitle", ARGS_ONE },
- { "silence", NEED_FORE|ARGS_ZEROONE },
- { "silencewait", ARGS_ONE },
- { "sleep", ARGS_ONE },
- { "slowpaste", ARGS_ONE },
- { "sorendition", ARGS_ZEROONETWO },
- { "startup_message", ARGS_ONE },
- { "stuff", NEED_DISPLAY|ARGS_ONE },
+ { "scrollback", NEED_FORE|ARGS_1 },
+#endif
+ { "select", ARGS_01 },
+ { "sessionname", ARGS_01 },
+ { "setenv", ARGS_012 },
+ { "shell", ARGS_1 },
+ { "shelltitle", ARGS_1 },
+ { "silence", NEED_FORE|ARGS_01 },
+ { "silencewait", ARGS_1 },
+ { "sleep", ARGS_1 },
+ { "slowpaste", NEED_FORE|ARGS_01 },
+ { "sorendition", ARGS_012 },
+ { "split", NEED_DISPLAY|ARGS_0 },
+ { "startup_message", ARGS_1 },
+ { "stuff", NEED_DISPLAY|ARGS_12 },
+#ifdef MULTIUSER
+ { "su", NEED_DISPLAY|ARGS_012 },
+#endif
#ifdef BSDJOBS
- { "suspend", NEED_DISPLAY|ARGS_ZERO },
-#endif
- { "term", ARGS_ONE },
- { "termcap", ARGS_TWOTHREE },
- { "termcapinfo", ARGS_TWOTHREE },
- { "terminfo", ARGS_TWOTHREE },
- { "time", ARGS_ZERO },
- { "title", NEED_FORE|ARGS_ZEROONE },
- { "unsetenv", ARGS_ONE },
- { "vbell", ARGS_ZEROONE },
- { "vbell_msg", ARGS_ZEROONE },
- { "vbellwait", ARGS_ONE },
- { "version", ARGS_ZERO },
- { "wall", NEED_DISPLAY|ARGS_ONE|ARGS_ORMORE },
- { "width", NEED_DISPLAY|ARGS_ZEROONE },
- { "windows", NEED_DISPLAY|ARGS_ZERO },
- { "wrap", NEED_FORE|ARGS_ZEROONE },
+ { "suspend", NEED_DISPLAY|ARGS_0 },
+#endif
+ { "term", ARGS_1 },
+ { "termcap", ARGS_23 },
+ { "termcapinfo", ARGS_23 },
+ { "terminfo", ARGS_23 },
+ { "time", ARGS_0 },
+ { "title", NEED_FORE|ARGS_01 },
+ { "umask", ARGS_1|ARGS_ORMORE },
+ { "unsetenv", ARGS_1 },
+ { "vbell", ARGS_01 },
+ { "vbell_msg", ARGS_01 },
+ { "vbellwait", ARGS_1 },
+ { "verbose", ARGS_01 },
+ { "version", ARGS_0 },
+ { "wall", NEED_DISPLAY|ARGS_1},
+ { "width", ARGS_01 },
+ { "windows", NEED_DISPLAY|ARGS_0 },
+ { "wrap", NEED_FORE|ARGS_01 },
#ifdef COPY_PASTE
- { "writebuf", NEED_DISPLAY|ARGS_ZERO },
+ { "writebuf", NEED_DISPLAY|ARGS_0 },
#endif
- { "writelock", NEED_FORE|ARGS_ZEROONE },
- { "xoff", NEED_DISPLAY|ARGS_ZERO },
- { "xon", NEED_DISPLAY|ARGS_ZERO },
- { "zombie", ARGS_ZEROONE }
+ { "writelock", NEED_FORE|ARGS_01 },
+ { "xoff", NEED_DISPLAY|ARGS_0 },
+ { "xon", NEED_DISPLAY|ARGS_0 },
+ { "zombie", ARGS_01 }
};
diff --git a/comm.h.dist b/comm.h.dist
index bbe0052..d004f71 100644
--- a/comm.h.dist
+++ b/comm.h.dist
@@ -13,23 +13,28 @@ struct comm
#define ARGS_MASK (3)
-#define ARGS_ZERO (0)
-#define ARGS_ONE (1)
-#define ARGS_TWO (2)
-#define ARGS_THREE (3)
+#define ARGS_0 (0)
+#define ARGS_1 (1)
+#define ARGS_2 (2)
+#define ARGS_3 (3)
-#define ARGS_PLUSONE (1<<2)
-#define ARGS_PLUSTWO (1<<3)
-#define ARGS_ORMORE (1<<4)
+#define ARGS_PLUS1 (1<<2)
+#define ARGS_PLUS2 (1<<3)
+#define ARGS_PLUS3 (1<<4)
+#define ARGS_ORMORE (1<<5)
-#define NEED_FORE (1<<5) /* this command needs a fore window */
-#define NEED_DISPLAY (1<<6) /* this command needs a display */
+#define NEED_FORE (1<<6) /* this command needs a fore window */
+#define NEED_DISPLAY (1<<7) /* this command needs a display */
-#define ARGS_ZEROONE (ARGS_ZERO|ARGS_PLUSONE)
-#define ARGS_ONETWO (ARGS_ONE |ARGS_PLUSONE)
-#define ARGS_TWOTHREE (ARGS_TWO |ARGS_PLUSONE)
-#define ARGS_ZEROTWO (ARGS_ZERO|ARGS_PLUSTWO)
-#define ARGS_ZEROONETWO (ARGS_ZERO|ARGS_PLUSONE|ARGS_PLUSTWO)
+#define ARGS_01 (ARGS_0 | ARGS_PLUS1)
+#define ARGS_02 (ARGS_0 | ARGS_PLUS2)
+#define ARGS_12 (ARGS_1 | ARGS_PLUS1)
+#define ARGS_23 (ARGS_2 | ARGS_PLUS1)
+#define ARGS_34 (ARGS_3 | ARGS_PLUS1)
+#define ARGS_012 (ARGS_0 | ARGS_PLUS1 | ARGS_PLUS2)
+#define ARGS_123 (ARGS_1 | ARGS_PLUS1 | ARGS_PLUS2)
+#define ARGS_124 (ARGS_1 | ARGS_PLUS1 | ARGS_PLUS3)
+#define ARGS_1234 (ARGS_1 | ARGS_PLUS1 | ARGS_PLUS2 | ARGS_PLUS3)
struct action
{
@@ -43,135 +48,153 @@ struct action
#define RC_ACLCHG 1
#define RC_ACLDEL 2
#define RC_ACLGRP 3
-#define RC_ACTIVITY 4
-#define RC_AKA 5
-#define RC_ALLPARTIAL 6
-#define RC_AT 7
-#define RC_AUTODETACH 8
-#define RC_AUTONUKE 9
-#define RC_BELL 10
-#define RC_BELL_MSG 11
-#define RC_BIND 12
-#define RC_BINDKEY 13
-#define RC_BREAK 14
-#define RC_BUFFERFILE 15
-#define RC_C1 16
-#define RC_CHARSET 17
-#define RC_CHDIR 18
-#define RC_CLEAR 19
-#define RC_CLONE 20
-#define RC_COLON 21
-#define RC_COMMAND 22
-#define RC_CONSOLE 23
-#define RC_COPY 24
-#define RC_CRLF 25
-#define RC_DEBUG 26
-#define RC_DEFAUTONUKE 27
-#define RC_DEFC1 28
-#define RC_DEFCHARSET 29
-#define RC_DEFESCAPE 30
-#define RC_DEFFLOW 31
-#define RC_DEFGR 32
-#define RC_DEFHSTATUS 33
-#define RC_DEFKANJI 34
-#define RC_DEFLOGIN 35
-#define RC_DEFMODE 36
-#define RC_DEFMONITOR 37
-#define RC_DEFOBUFLIMIT 38
-#define RC_DEFSCROLLBACK 39
-#define RC_DEFWRAP 40
-#define RC_DEFWRITELOCK 41
-#define RC_DETACH 42
-#define RC_DIGRAPH 43
-#define RC_DISPLAYS 44
-#define RC_DUMPTERMCAP 45
-#define RC_ECHO 46
-#define RC_ESCAPE 47
-#define RC_EXEC 48
-#define RC_FLOW 49
-#define RC_GR 50
-#define RC_HARDCOPY 51
-#define RC_HARDCOPY_APPEND 52
-#define RC_HARDCOPYDIR 53
-#define RC_HARDSTATUS 54
-#define RC_HEIGHT 55
-#define RC_HELP 56
-#define RC_HISTORY 57
-#define RC_INFO 58
-#define RC_KANJI 59
-#define RC_KILL 60
-#define RC_LASTMSG 61
-#define RC_LICENSE 62
-#define RC_LOCKSCREEN 63
-#define RC_LOG 64
-#define RC_LOGFILE 65
-#define RC_LOGIN 66
-#define RC_MAPDEFAULT 67
-#define RC_MAPNOTNEXT 68
-#define RC_MAPTIMEOUT 69
-#define RC_MARKKEYS 70
-#define RC_META 71
-#define RC_MONITOR 72
-#define RC_MSGMINWAIT 73
-#define RC_MSGWAIT 74
-#define RC_MULTIUSER 75
-#define RC_NETHACK 76
-#define RC_NEXT 77
-#define RC_NUMBER 78
-#define RC_OBUFLIMIT 79
-#define RC_OTHER 80
-#define RC_PARTIAL 81
-#define RC_PASSWORD 82
-#define RC_PASTE 83
-#define RC_PASTEFONT 84
-#define RC_POW_BREAK 85
-#define RC_POW_DETACH 86
-#define RC_POW_DETACH_MSG 87
-#define RC_PREV 88
-#define RC_PRINTCMD 89
-#define RC_PROCESS 90
-#define RC_QUIT 91
-#define RC_READBUF 92
-#define RC_READREG 93
-#define RC_REDISPLAY 94
-#define RC_REGISTER 95
-#define RC_REMOVEBUF 96
-#define RC_RESET 97
-#define RC_SCREEN 98
-#define RC_SCROLLBACK 99
-#define RC_SELECT 100
-#define RC_SESSIONNAME 101
-#define RC_SETENV 102
-#define RC_SHELL 103
-#define RC_SHELLAKA 104
-#define RC_SHELLTITLE 105
-#define RC_SILENCE 106
-#define RC_SILENCEWAIT 107
-#define RC_SLEEP 108
-#define RC_SLOWPASTE 109
-#define RC_SORENDITION 110
-#define RC_STARTUP_MESSAGE 111
-#define RC_STUFF 112
-#define RC_SUSPEND 113
-#define RC_TERM 114
-#define RC_TERMCAP 115
-#define RC_TERMCAPINFO 116
-#define RC_TERMINFO 117
-#define RC_TIME 118
-#define RC_TITLE 119
-#define RC_UNSETENV 120
-#define RC_VBELL 121
-#define RC_VBELL_MSG 122
-#define RC_VBELLWAIT 123
-#define RC_VERSION 124
-#define RC_WALL 125
-#define RC_WIDTH 126
-#define RC_WINDOWS 127
-#define RC_WRAP 128
-#define RC_WRITEBUF 129
-#define RC_WRITELOCK 130
-#define RC_XOFF 131
-#define RC_XON 132
-#define RC_ZOMBIE 133
+#define RC_ACLUMASK 4
+#define RC_ACTIVITY 5
+#define RC_ADDACL 6
+#define RC_ALLPARTIAL 7
+#define RC_AT 8
+#define RC_AUTODETACH 9
+#define RC_AUTONUKE 10
+#define RC_BELL 11
+#define RC_BELL_MSG 12
+#define RC_BIND 13
+#define RC_BINDKEY 14
+#define RC_BREAK 15
+#define RC_BREAKTYPE 16
+#define RC_BUFFERFILE 17
+#define RC_C1 18
+#define RC_CAPTION 19
+#define RC_CHACL 20
+#define RC_CHARSET 21
+#define RC_CHDIR 22
+#define RC_CLEAR 23
+#define RC_COLON 24
+#define RC_COMMAND 25
+#define RC_COMPACTHIST 26
+#define RC_CONSOLE 27
+#define RC_COPY 28
+#define RC_CRLF 29
+#define RC_DEBUG 30
+#define RC_DEFAUTONUKE 31
+#define RC_DEFBREAKTYPE 32
+#define RC_DEFC1 33
+#define RC_DEFCHARSET 34
+#define RC_DEFESCAPE 35
+#define RC_DEFFLOW 36
+#define RC_DEFGR 37
+#define RC_DEFHSTATUS 38
+#define RC_DEFKANJI 39
+#define RC_DEFLOGIN 40
+#define RC_DEFMODE 41
+#define RC_DEFMONITOR 42
+#define RC_DEFOBUFLIMIT 43
+#define RC_DEFSCROLLBACK 44
+#define RC_DEFSHELL 45
+#define RC_DEFSILENCE 46
+#define RC_DEFSLOWPASTE 47
+#define RC_DEFWRAP 48
+#define RC_DEFWRITELOCK 49
+#define RC_DETACH 50
+#define RC_DIGRAPH 51
+#define RC_DISPLAYS 52
+#define RC_DUMPTERMCAP 53
+#define RC_ECHO 54
+#define RC_ESCAPE 55
+#define RC_EXEC 56
+#define RC_FIT 57
+#define RC_FLOW 58
+#define RC_FOCUS 59
+#define RC_GR 60
+#define RC_HARDCOPY 61
+#define RC_HARDCOPY_APPEND 62
+#define RC_HARDCOPYDIR 63
+#define RC_HARDSTATUS 64
+#define RC_HEIGHT 65
+#define RC_HELP 66
+#define RC_HISTORY 67
+#define RC_HSTATUS 68
+#define RC_INFO 69
+#define RC_KANJI 70
+#define RC_KILL 71
+#define RC_LASTMSG 72
+#define RC_LICENSE 73
+#define RC_LOCKSCREEN 74
+#define RC_LOG 75
+#define RC_LOGFILE 76
+#define RC_LOGIN 77
+#define RC_LOGTSTAMP 78
+#define RC_MAPDEFAULT 79
+#define RC_MAPNOTNEXT 80
+#define RC_MAPTIMEOUT 81
+#define RC_MARKKEYS 82
+#define RC_META 83
+#define RC_MONITOR 84
+#define RC_MSGMINWAIT 85
+#define RC_MSGWAIT 86
+#define RC_MULTIUSER 87
+#define RC_NETHACK 88
+#define RC_NEXT 89
+#define RC_NONBLOCK 90
+#define RC_NUMBER 91
+#define RC_OBUFLIMIT 92
+#define RC_ONLY 93
+#define RC_OTHER 94
+#define RC_PARTIAL 95
+#define RC_PASSWORD 96
+#define RC_PASTE 97
+#define RC_PASTEFONT 98
+#define RC_POW_BREAK 99
+#define RC_POW_DETACH 100
+#define RC_POW_DETACH_MSG 101
+#define RC_PREV 102
+#define RC_PRINTCMD 103
+#define RC_PROCESS 104
+#define RC_QUIT 105
+#define RC_READBUF 106
+#define RC_READREG 107
+#define RC_REDISPLAY 108
+#define RC_REGISTER 109
+#define RC_REMOVE 110
+#define RC_REMOVEBUF 111
+#define RC_RESET 112
+#define RC_SCREEN 113
+#define RC_SCROLLBACK 114
+#define RC_SELECT 115
+#define RC_SESSIONNAME 116
+#define RC_SETENV 117
+#define RC_SHELL 118
+#define RC_SHELLTITLE 119
+#define RC_SILENCE 120
+#define RC_SILENCEWAIT 121
+#define RC_SLEEP 122
+#define RC_SLOWPASTE 123
+#define RC_SORENDITION 124
+#define RC_SPLIT 125
+#define RC_STARTUP_MESSAGE 126
+#define RC_STUFF 127
+#define RC_SU 128
+#define RC_SUSPEND 129
+#define RC_TERM 130
+#define RC_TERMCAP 131
+#define RC_TERMCAPINFO 132
+#define RC_TERMINFO 133
+#define RC_TIME 134
+#define RC_TITLE 135
+#define RC_UMASK 136
+#define RC_UNSETENV 137
+#define RC_VBELL 138
+#define RC_VBELL_MSG 139
+#define RC_VBELLWAIT 140
+#define RC_VERBOSE 141
+#define RC_VERSION 142
+#define RC_WALL 143
+#define RC_WIDTH 144
+#define RC_WINDOWS 145
+#define RC_WRAP 146
+#define RC_WRITEBUF 147
+#define RC_WRITELOCK 148
+#define RC_XOFF 149
+#define RC_XON 150
+#define RC_ZOMBIE 151
-#define RC_LAST 133
+#define RC_LAST 151
diff --git a/comm.sh b/comm.sh
index 9aa0a20..d5fd8b0 100644
--- a/comm.sh
+++ b/comm.sh
@@ -27,23 +27,28 @@ struct comm
#define ARGS_MASK (3)
-#define ARGS_ZERO (0)
-#define ARGS_ONE (1)
-#define ARGS_TWO (2)
-#define ARGS_THREE (3)
+#define ARGS_0 (0)
+#define ARGS_1 (1)
+#define ARGS_2 (2)
+#define ARGS_3 (3)
-#define ARGS_PLUSONE (1<<2)
-#define ARGS_PLUSTWO (1<<3)
-#define ARGS_ORMORE (1<<4)
+#define ARGS_PLUS1 (1<<2)
+#define ARGS_PLUS2 (1<<3)
+#define ARGS_PLUS3 (1<<4)
+#define ARGS_ORMORE (1<<5)
-#define NEED_FORE (1<<5) /* this command needs a fore window */
-#define NEED_DISPLAY (1<<6) /* this command needs a display */
+#define NEED_FORE (1<<6) /* this command needs a fore window */
+#define NEED_DISPLAY (1<<7) /* this command needs a display */
-#define ARGS_ZEROONE (ARGS_ZERO|ARGS_PLUSONE)
-#define ARGS_ONETWO (ARGS_ONE |ARGS_PLUSONE)
-#define ARGS_TWOTHREE (ARGS_TWO |ARGS_PLUSONE)
-#define ARGS_ZEROTWO (ARGS_ZERO|ARGS_PLUSTWO)
-#define ARGS_ZEROONETWO (ARGS_ZERO|ARGS_PLUSONE|ARGS_PLUSTWO)
+#define ARGS_01 (ARGS_0 | ARGS_PLUS1)
+#define ARGS_02 (ARGS_0 | ARGS_PLUS2)
+#define ARGS_12 (ARGS_1 | ARGS_PLUS1)
+#define ARGS_23 (ARGS_2 | ARGS_PLUS1)
+#define ARGS_34 (ARGS_3 | ARGS_PLUS1)
+#define ARGS_012 (ARGS_0 | ARGS_PLUS1 | ARGS_PLUS2)
+#define ARGS_123 (ARGS_1 | ARGS_PLUS1 | ARGS_PLUS2)
+#define ARGS_124 (ARGS_1 | ARGS_PLUS1 | ARGS_PLUS3)
+#define ARGS_1234 (ARGS_1 | ARGS_PLUS1 | ARGS_PLUS2 | ARGS_PLUS3)
struct action
{
diff --git a/config.h.in b/config.h.in
index 4ed1791..34af7e2 100644
--- a/config.h.in
+++ b/config.h.in
@@ -15,7 +15,8 @@
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING); if not, write to the
- * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
****************************************************************
* $Id: config.h.in,v 1.12 1994/05/31 12:31:36 mlschroe Exp $ FAU
@@ -30,7 +31,10 @@
* User Configuration Section
*/
-
+/*
+ * Maximum of simultaneously allowed windows per screen session.
+ */
+#define MAXWIN 40
/*
* Define SOCKDIR to be the directory to contain the named sockets
@@ -40,17 +44,13 @@
* "sticky" bit is on, but this isn't required.
* If SOCKDIR is not defined screen will put the named sockets in
* the user's home directory. Notice that this can cause you problems
- * if some user's HOME directories are NFS-mounted and don't support
- * named sockets.
+ * if some user's HOME directories are AFS- or NFS-mounted. Especially
+ * AFS is unlikely to support named sockets.
+ *
* Screen will name the subdirectories "S-$USER" (e.g /tmp/S-davison).
- * Do not define TMPTEST unless it's for debugging purpose.
*/
-#ifndef TMPTEST
-# define SOCKDIR "/tmp/screens"
-#else
-# define SOCKDIR "/tmp/testscreens"
-#endif
+#define SOCKDIR (eff_uid ? "/tmp/uscreens" : "/tmp/screens")
/*
* Screen sources two startup files. First a global file with a path
@@ -69,6 +69,17 @@
*/
#define ALLOW_SYSSCREENRC 1
+/*
+ * Define CHECKLOGIN to force Screen users to enter their Unix password
+ * in addition to the screen password.
+ *
+ * Define NOSYSLOG if yo do not have logging facilities. Currently
+ * syslog() will be used to trace ``su'' commands only.
+ */
+#define CHECKLOGIN 1
+#undef NOSYSLOG
+
+
/*
* define PTYMODE if you do not like the default of 0622, which allows
* public write to your pty.
@@ -96,18 +107,30 @@
#undef TOPSTAT
/*
+ * define DETACH can detach a session. An absolute 'must'.
+ */
+#define DETACH
+
+/*
* here come the erlangen extensions to screen:
* define LOCK if you want to use a lock program for a screenlock.
* define PASSWORD for secure reattach of your screen.
* define COPY_PASTE to use the famous hacker's treasure zoo.
- * define POW_DETACH to have a detach_and_logout key.
+ * define POW_DETACH to have a detach_and_logout key (requires DETACH).
* define REMOTE_DETACH (-d option) to move screen between terminals.
* define AUTO_NUKE to enable Tim MacKenzies clear screen nuking
* define PSEUDOS to allow window input/output filtering
* define MULTI to allow multiple attaches.
* define MULTIUSER to allow other users attach to your session
* (if they are in the acl, of course)
- * (jw)
+ * define MAPKEYS to include input keyboard translation.
+ * define FONT to support ISO2022/alternet charset support
+ * define COLOR to include ansi color support. This may expose
+ * a bug in x11r6-color-xterm.
+ * define KANJI to include support for japanese character sets.
+ * Needs FONT to work.
+ * define BUILTIN_TELNET to add telnet support to screen.
+ * Syntax: screen //telnet host [port]
*/
#undef SIMPLESCREEN
#ifndef SIMPLESCREEN
@@ -122,8 +145,20 @@
# define MULTIUSER
# define MAPKEYS
# define COLOR
+# define FONT
+# define KANJI
#endif /* SIMPLESCREEN */
-#define KANJI
+
+#undef BUILTIN_TELNET
+
+
+/*
+ * If you have a braille display you should define HAVE_BRAILLE.
+ * The code inside #ifdef HAVE_BRAILLE was contributed by Hadi Bargi
+ * Rangin (bargi@dots.physics.orst.edu).
+ */
+#undef HAVE_BRAILLE
+
/*
* As error messages are mostly meaningless to the user, we
@@ -153,11 +188,16 @@
* Disabling this feature only makes sense if you have a secure /etc/utmp
* database.
* Negative examples: suns usually have a world writable utmp file,
- * xterm and script will run perfectly without s-bit.
- * If LOGOUTOK is undefined and UTMPOK is defined, all windows are initially
- * and permanently logged in.
+ * xterm will run perfectly without s-bit.
+ *
+ * If LOGOUTOK is undefined and UTMPOK is defined, all windows are
+ * initially and permanently logged in.
+ *
+ * Set CAREFULUTMP to one (1) if you want that users have at least one
+ * window per screen session logged in.
*/
#define LOGOUTOK 1
+#undef CAREFULUTMP
/*
@@ -170,6 +210,36 @@
*/
#undef USRLIMIT
+/*
+ * both must be defined if you want to favor tcsendbreak over
+ * other calls to generate a break condition on serial lines.
+ * (Do not bother, if you are not using plain tty windows.)
+ */
+#define POSIX_HAS_A_GOOD_TCSENDBREAK
+#define SUNOS4_AND_WE_TRUST_TCSENDBREAK
+
+/*
+ * to lower the interrupt load on the host machine, you may want to
+ * adjust the VMIN and VTIME settings used for plain tty windows.
+ * See the termio(4) manual page (Non-Canonical Mode Input Processing)
+ * for details.
+ * if undefined, VMIN=1, VTIME=0 is used as a default - this gives you
+ * best user responsiveness, but highest interrupt frequency.
+ * (Do not bother, if you are not using plain tty windows.)
+ */
+#define TTYVMIN 100
+#define TTYVTIME 2
+
+/*
+ * looks like the above values are ignored by setting FNDELAY.
+ * This is default for all pty/ttys, you may disable it for
+ * ttys here. After playing with it for a while, one may find out
+ * that this feature may cause screen to lock up.
+ */
+#ifdef bsdi
+# define TTY_DISABLE_FNBLOCK /* select barfs without it ... */
+#endif
+
/*
* Some terminals, e.g. Wyse 120, use a bitfield to select attributes.
@@ -300,9 +370,10 @@
#endif
/*
- * Define DIRENT if your system has <dirent.h> instead of <sys/dir.h>
+ * Define HAVE_DIRENT_H if your system has <dirent.h> instead of
+ * <sys/dir.h>
*/
-#undef DIRENT
+#undef HAVE_DIRENT_H
/*
* If your system has getutent(), pututline(), etc. to write to the
@@ -316,6 +387,11 @@
#undef UTHOST
/*
+ * Define if you have the utempter utmp helper program
+ */
+#undef HAVE_UTEMPTER
+
+/*
* If ttyslot() breaks getlogin() by returning indexes to utmp entries
* of type DEAD_PROCESS, then our getlogin() replacement should be
* selected by defining BUGGYGETLOGIN.
@@ -326,7 +402,6 @@
* If your system has the calls setreuid() and setregid(),
* define HAVE_SETREUID. Otherwise screen will use a forked process to
* safely create output files without retaining any special privileges.
- * (Output logging will be disabled, however.)
*/
#undef HAVE_SETREUID
@@ -367,8 +442,10 @@
* undefined, screen uses its own (probably slower) version of bcopy().
*
* SYSV machines may have a working memcpy() -- Oh, this is
- * quite unlikely. Tell me if you see one. (Juergen)
- * But then, memmove() should work, if at all available.
+ * quite unlikely. Tell me if you see one.
+ * "But then, memmove() should work, if at all available" he thought...
+ * Boing, never say "works everywhere" unless you checked SCO UNIX.
+ * Their memove fails the test in the configure script. Sigh. (Juergen)
*/
#undef USEBCOPY
#undef USEMEMCPY
@@ -434,9 +511,9 @@
#undef NAME_MAX
/*
- * define NEED_RENAME if your system doesn't have a rename() function
+ * define HAVE_RENAME if your system has a rename() function
*/
-#undef NEED_RENAME
+#undef HAVE_RENAME
/*
* define HAVE__EXIT if your system has the _exit() call.
@@ -454,16 +531,37 @@
#undef HAVE_UTIMES
/*
+ * define HAVE_FCHOWN if your system has the fchown() call.
+ */
+#undef HAVE_FCHOWN
+
+/*
+ * define HAVE_FCHMOD if your system has the fchmod() call.
+ */
+#undef HAVE_FCHMOD
+
+/*
* define HAVE_VSNPRINTF if your system has vsnprintf() (GNU lib).
*/
#undef HAVE_VSNPRINTF
/*
+ * define HAVE_GETCWD if your system has the getcwd() call.
+ */
+#undef HAVE_GETCWD
+
+/*
* define HAVE_DEV_PTC if you have a /dev/ptc character special
* device.
*/
#undef HAVE_DEV_PTC
+/*
+ * define HAVE_SVR4_PTYS if you have a /dev/ptmx character special
+ * device and support the ptsname(), grantpt(), unlockpt() functions.
+ */
+#undef HAVE_SVR4_PTYS
+
/*
* define PTYRANGE0 and or PTYRANGE1 if you want to adapt screen
* to unusual environments. E.g. For SunOs the defaults are "qpr" and
diff --git a/configure b/configure
index 8a04ae8..be6c524 100755
--- a/configure
+++ b/configure
@@ -1,66 +1,56 @@
-#!/bin/sh
-# From configure.in Revision: 1.17
-#!/bin/sh
-# Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 1.11
-# Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
-
-# This configure script is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as published
-# by the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This script is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-# Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-# Save the original args to write them into config.status later.
-configure_args="$*"
-
-# Only options that might do something get documented.
-ac_usage="Usage: configure [options] [host]
-Options: [defaults in brackets after descriptions]
---build=BUILD configure for building on BUILD [BUILD=HOST]
---disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
---enable-FEATURE[=ARG] include FEATURE [ARG=yes]
---exec-prefix=PREFIX install host dependent files in PREFIX [/usr/local]
---help print this message
---host=HOST configure for HOST [guessed]
---prefix=PREFIX install host independent files in PREFIX [/usr/local]
---quiet, --silent do not print \`checking for...' messages
---srcdir=DIR find the sources in DIR [configure dir or ..]
---target=TARGET configure for TARGET [TARGET=HOST]
---verbose print results of checks
---version print the version of autoconf that created configure
---with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
---without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
---x-includes=DIR X include files are in DIR
---x-libraries=DIR X library files are in DIR"
+#! /bin/sh
+
+# From configure.in Revision: 1.18 # Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.12
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
# Initialize some variables set by options.
# The variables have the same names as the options, with
# dashes changed to underlines.
build=NONE
-exec_prefix=
+cache_file=./config.cache
+exec_prefix=NONE
host=NONE
no_create=
nonopt=NONE
-norecursion=
-prefix=
-program_prefix=
-program_suffix=
-program_transform_name=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
silent=
+site=
srcdir=
target=NONE
verbose=
-x_includes=
-x_libraries=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
ac_prev=
for ac_option
@@ -73,35 +63,52 @@ do
continue
fi
- # Accept (but ignore some of) the important Cygnus configure
- # options, so we can diagnose typos.
-
case "$ac_option" in
-*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
*) ac_optarg= ;;
esac
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
case "$ac_option" in
- -build | --build | --buil | --bui | --bu | --b)
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
ac_prev=build ;;
- -build=* | --build=* | --buil=* | --bui=* | --bu=* | --b=*)
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
build="$ac_optarg" ;;
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
-disable-* | --disable-*)
ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
- # Reject names that aren't valid shell variable names.
+ # Reject names that are not valid shell variable names.
if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
- echo "configure: $ac_feature: invalid feature name" >&2; exit 1
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
fi
ac_feature=`echo $ac_feature| sed 's/-/_/g'`
eval "enable_${ac_feature}=no" ;;
-enable-* | --enable-*)
ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
- # Reject names that aren't valid shell variable names.
+ # Reject names that are not valid shell variable names.
if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
- echo "configure: $ac_feature: invalid feature name" >&2; exit 1
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
fi
ac_feature=`echo $ac_feature| sed 's/-/_/g'`
case "$ac_option" in
@@ -110,7 +117,6 @@ do
esac
eval "enable_${ac_feature}='$ac_optarg'" ;;
- # For backward compatibility, recognize -exec-prefix and --exec_prefix.
-exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
| --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
| --exec | --exe | --ex)
@@ -121,12 +127,62 @@ do
exec_prefix="$ac_optarg" ;;
-gas | --gas | --ga | --g)
- with_gas=yes ;; # Obsolete; use --with-gas.
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
-help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
cat << EOF
-$ac_usage
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
exit 0 ;;
-host | --host | --hos | --ho)
@@ -134,16 +190,64 @@ EOF
-host=* | --host=* | --hos=* | --ho=*)
host="$ac_optarg" ;;
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
-nfp | --nfp | --nf)
- with_fp=no ;; # Obsolete; use --without-fp.
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
-no-create | --no-create | --no-creat | --no-crea | --no-cre \
| --no-cr | --no-c)
no_create=yes ;;
- -norecursion | --norecursion | --norecursio | --norecursi \
- | --norecurs | --norecur | --norecu | --norec | --nore | --nor)
- norecursion=yes ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
-prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
ac_prev=prefix ;;
@@ -185,11 +289,40 @@ EOF
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
-srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
ac_prev=srcdir ;;
-srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
srcdir="$ac_optarg" ;;
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
-target | --target | --targe | --targ | --tar | --ta | --t)
ac_prev=target ;;
-target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
@@ -199,14 +332,14 @@ EOF
verbose=yes ;;
-version | --version | --versio | --versi | --vers)
- echo "configure generated by autoconf version 1.11"
+ echo "configure generated by autoconf version 2.12"
exit 0 ;;
-with-* | --with-*)
ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
- # Reject names that aren't valid shell variable names.
+ # Reject names that are not valid shell variable names.
if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
- echo "configure: $ac_package: invalid package name" >&2; exit 1
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
fi
ac_package=`echo $ac_package| sed 's/-/_/g'`
case "$ac_option" in
@@ -217,14 +350,16 @@ EOF
-without-* | --without-*)
ac_package=`echo $ac_option|sed -e 's/-*without-//'`
- # Reject names that aren't valid shell variable names.
+ # Reject names that are not valid shell variable names.
if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
- echo "configure: $ac_package: invalid package name" >&2; exit 1
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
fi
ac_package=`echo $ac_package| sed 's/-/_/g'`
eval "with_${ac_package}=no" ;;
- --x) with_x=yes ;; # Obsolete; use --with-x.
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
-x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
| --x-incl | --x-inc | --x-in | --x-i)
@@ -240,15 +375,15 @@ EOF
| --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
x_libraries="$ac_optarg" ;;
- -*) echo "configure: $ac_option: invalid option; use --help to show usage" >&2; exit 1
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
;;
- *)
+ *)
if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
- echo "configure: warning: $ac_option: invalid host type" >&2
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
fi
if test "x$nonopt" != xNONE; then
- echo "configure: can only configure for one host and one target at a time" >&2; exit 1
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
fi
nonopt="$ac_option"
;;
@@ -257,31 +392,56 @@ EOF
done
if test -n "$ac_prev"; then
- echo "configure: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" >&2; exit 1
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
fi
-trap 'rm -fr conftest* confdefs* core $ac_clean_files; exit 1' 1 2 15
-trap 'rm -fr confdefs* $ac_clean_files' 0
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
-# Save the original args if we used an alternate arg parser.
-ac_configure_temp="${configure_args-$*}"
-# Strip out --no-create and --norecursion so they don't pile up.
-configure_args=
-for ac_arg in $ac_configure_temp; do
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
case "$ac_arg" in
-no-create | --no-create | --no-creat | --no-crea | --no-cre \
| --no-cr | --no-c) ;;
- -norecursion | --norecursion | --norecursio | --norecursi \
- | --norecurs | --norecur | --norecu | --norec | --nore | --nor) ;;
- *) configure_args="$configure_args $ac_arg" ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
esac
done
# NLS nuisances.
-# These must not be set unconditionally because not all systems understand
-# e.g. LANG=C (notably SCO).
-if test "${LC_ALL+set}" = 'set'; then LC_ALL=C; export LC_ALL; fi
-if test "${LANG+set}" = 'set'; then LANG=C; export LANG; fi
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
# confdefs.h avoids OS command line length limits that DEFS can exceed.
rm -rf conftest* confdefs.h
@@ -295,7 +455,7 @@ ac_unique_file=screen.c
# Find the source files, if location was not specified.
if test -z "$srcdir"; then
ac_srcdir_defaulted=yes
- # Try the directory containing this script, then `..'.
+ # Try the directory containing this script, then its parent.
ac_prog=$0
ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
@@ -303,18 +463,59 @@ if test -z "$srcdir"; then
if test ! -r $srcdir/$ac_unique_file; then
srcdir=..
fi
+else
+ ac_srcdir_defaulted=no
fi
if test ! -r $srcdir/$ac_unique_file; then
- if test x$ac_srcdir_defaulted = xyes; then
- echo "configure: can not find sources in ${ac_confdir} or .." >&2; exit 1
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
else
- echo "configure: can not find sources in ${srcdir}" >&2; exit 1
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
fi
fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='${CPP}'
-ac_compile='${CC-cc} $CFLAGS $LDFLAGS conftest.${ac_ext} -o conftest $LIBS >/dev/null 2>&1'
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
@@ -324,168 +525,449 @@ rev=`sed < ${srcdir}/patchlevel.h -n -e '/#define REV/s/#define REV *//p'`
vers=`sed < ${srcdir}/patchlevel.h -n -e '/#define VERS/s/#define VERS *//p'`
pat=`sed < ${srcdir}/patchlevel.h -n -e '/#define PATCHLEVEL/s/#define PATCHLEVEL *//p'`
VERSION="$rev.$vers.$pat"
-test -n "$silent" || echo "this is screen version $VERSION"
+echo "this is screen version $VERSION" 1>&6
-if test -z "$prefix"
-then
- test -n "$silent" || echo "checking for gzip to derive installation directory prefix"
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="$IFS:"
+
+if test "x$prefix" = xNONE; then
+echo $ac_n "checking for prefix by $ac_c" 1>&6
+# Extract the first word of "screen", so it can be a program name with args.
+set dummy screen; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:537: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_SCREEN'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$SCREEN" in
+ /*)
+ ac_cv_path_SCREEN="$SCREEN" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_SCREEN="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+fi
+SCREEN="$ac_cv_path_SCREEN"
+if test -n "$SCREEN"; then
+ echo "$ac_t""$SCREEN" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -n "$ac_cv_path_SCREEN"; then
+ prefix=`echo $ac_cv_path_SCREEN|sed 's%/[^/][^/]*//*[^/][^/]*$%%'`
+ fi
+fi
+
+if test "x$prefix" = xNONE; then
+echo $ac_n "checking for prefix by $ac_c" 1>&6
+# Extract the first word of "gzip", so it can be a program name with args.
+set dummy gzip; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:575: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GZIP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$GZIP" in
+ /*)
+ ac_cv_path_GZIP="$GZIP" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
for ac_dir in $PATH; do
test -z "$ac_dir" && ac_dir=.
- if test $ac_dir != . && test -f $ac_dir/gzip; then
- # Not all systems have dirname.
- prefix=`echo $ac_dir|sed 's%/[^/][^/]*$%%'`
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_GZIP="$ac_dir/$ac_word"
break
fi
done
IFS="$ac_save_ifs"
- test -n "$verbose" && echo " chose installation directory prefix ${prefix}"
+ ;;
+esac
+fi
+GZIP="$ac_cv_path_GZIP"
+if test -n "$GZIP"; then
+ echo "$ac_t""$GZIP" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -n "$ac_cv_path_GZIP"; then
+ prefix=`echo $ac_cv_path_GZIP|sed 's%/[^/][^/]*//*[^/][^/]*$%%'`
+ fi
fi
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:612: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
if test -z "$CC"; then
- # Extract the first word of `gcc', so it can be a program name with args.
- set ac_dummy gcc; ac_word=$2
- test -n "$silent" || echo "checking for $ac_word"
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:641: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ ac_prog_rejected=no
for ac_dir in $PATH; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
- CC="gcc"
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
break
fi
done
IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
fi
-test -z "$CC" && CC="cc"
-test -n "$CC" && test -n "$verbose" && echo " setting CC to $CC"
-# Find out if we are using GNU C, under whatever name.
-cat > conftest.c <<EOF
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:689: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext <<EOF
+#line 699 "configure"
+#include "confdefs.h"
+main(){return(0);}
+EOF
+if { (eval echo configure:703: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:723: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:728: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
#ifdef __GNUC__
- yes
+ yes;
#endif
EOF
-${CC-cc} -E conftest.c > conftest.out 2>&1
-if egrep yes conftest.out >/dev/null 2>&1; then
- GCC=1 # For later tests.
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:737: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+ ac_test_CFLAGS="${CFLAGS+set}"
+ ac_save_CFLAGS="$CFLAGS"
+ CFLAGS=
+ echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:752: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
fi
rm -f conftest*
-test -n "$silent" || echo "checking how to run the C preprocessor"
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+ if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+ elif test $ac_cv_prog_cc_g = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-O2"
+ fi
+else
+ GCC=
+ test "${CFLAGS+set}" = set || CFLAGS="-g"
+fi
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:780: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
if test -z "$CPP"; then
- # This must be in double quotes, not single quotes, because CPP may get
- # substituted into the Makefile and ``${CC-cc}'' will simply confuse
- # make. It must be expanded now.
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
CPP="${CC-cc} -E"
- cat > conftest.${ac_ext} <<EOF
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 795 "configure"
#include "confdefs.h"
-#include <stdio.h>
+#include <assert.h>
Syntax Error
EOF
-# Some shells (Coherent) do redirections in the wrong order, so need
-# the parens.
-ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"`
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:801: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
:
else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
CPP="${CC-cc} -E -traditional-cpp"
- cat > conftest.${ac_ext} <<EOF
+ cat > conftest.$ac_ext <<EOF
+#line 812 "configure"
#include "confdefs.h"
-#include <stdio.h>
+#include <assert.h>
Syntax Error
EOF
-# Some shells (Coherent) do redirections in the wrong order, so need
-# the parens.
-ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"`
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:818: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
:
else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
CPP=/lib/cpp
fi
rm -f conftest*
fi
rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
fi
-test -n "$verbose" && echo " setting CPP to $CPP"
+echo "$ac_t""$CPP" 1>&6
-if test -n "$GCC"; then
- test -n "$silent" || echo "checking whether -traditional is needed"
- ac_pattern="Autoconf.*'x'"
- ac_prog='#include <sgtty.h>
-Autoconf TIOCGETP'
- cat > conftest.${ac_ext} <<EOF
+if test $ac_cv_prog_gcc = yes; then
+ echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
+echo "configure:842: checking whether ${CC-cc} needs -traditional" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_pattern="Autoconf.*'x'"
+ cat > conftest.$ac_ext <<EOF
+#line 848 "configure"
#include "confdefs.h"
-$ac_prog
+#include <sgtty.h>
+Autoconf TIOCGETP
EOF
-eval "$ac_cpp conftest.${ac_ext} > conftest.out 2>&1"
-if egrep "$ac_pattern" conftest.out >/dev/null 2>&1; then
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "$ac_pattern" >/dev/null 2>&1; then
rm -rf conftest*
- ac_need_trad=1
-
+ ac_cv_prog_gcc_traditional=yes
+else
+ rm -rf conftest*
+ ac_cv_prog_gcc_traditional=no
fi
rm -f conftest*
- if test -z "$ac_need_trad"; then
- ac_prog='#include <termio.h>
-Autoconf TCGETA'
- cat > conftest.${ac_ext} <<EOF
+ if test $ac_cv_prog_gcc_traditional = no; then
+ cat > conftest.$ac_ext <<EOF
+#line 866 "configure"
#include "confdefs.h"
-$ac_prog
+#include <termio.h>
+Autoconf TCGETA
EOF
-eval "$ac_cpp conftest.${ac_ext} > conftest.out 2>&1"
-if egrep "$ac_pattern" conftest.out >/dev/null 2>&1; then
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "$ac_pattern" >/dev/null 2>&1; then
rm -rf conftest*
- ac_need_trad=1
-
+ ac_cv_prog_gcc_traditional=yes
fi
rm -f conftest*
fi
- test -n "$ac_need_trad" && CC="$CC -traditional"
fi
-test -n "$silent" || echo "checking for POSIXized ISC"
+echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6
+ if test $ac_cv_prog_gcc_traditional = yes; then
+ CC="$CC -traditional"
+ fi
+fi
+
+echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6
+echo "configure:888: checking for POSIXized ISC" >&5
if test -d /etc/conf/kconfig.d &&
grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
then
- ISC=1 # If later tests want to check for ISC.
-
-{
-test -n "$verbose" && \
-echo " defining _POSIX_SOURCE"
-echo "#define" _POSIX_SOURCE "1" >> confdefs.h
-DEFS="$DEFS -D_POSIX_SOURCE=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}_POSIX_SOURCE\${ac_dB}_POSIX_SOURCE\${ac_dC}1\${ac_dD}
-\${ac_uA}_POSIX_SOURCE\${ac_uB}_POSIX_SOURCE\${ac_uC}1\${ac_uD}
-\${ac_eA}_POSIX_SOURCE\${ac_eB}_POSIX_SOURCE\${ac_eC}1\${ac_eD}
-"
-}
+ echo "$ac_t""yes" 1>&6
+ ISC=yes # If later tests want to check for ISC.
+ cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
- if test -n "$GCC"; then
+ if test "$GCC" = yes; then
CC="$CC -posix"
else
CC="$CC -Xp"
fi
+else
+ echo "$ac_t""no" 1>&6
+ ISC=
fi
-cat > conftest.${ac_ext} <<EOF
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 913 "configure"
#include "confdefs.h"
main(){exit(0);}
EOF
-eval $ac_compile
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
+if { (eval echo configure:917: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
:
else
- echo "configure: Can't run the compiler - sorry" >&2; exit 1
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+
+if test $CC != cc ; then
+echo "Your $CC failed - restarting with CC=cc" 1>&6
+
+echo "" 1>&6
+
+CC=cc
+export CC
+exec $0 $configure_args
+fi
+
fi
rm -fr conftest*
+fi
+
-cat > conftest.${ac_ext} <<EOF
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 944 "configure"
+#include "confdefs.h"
+main(){exit(0);}
+EOF
+if { (eval echo configure:948: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ exec 5>&2
+eval $ac_link
+echo "CC=$CC; CFLAGS=$CFLAGS; LIBS=$LIBS;" 1>&6
+
+echo "$ac_compile" 1>&6
+
+{ echo "configure: error: Can't run the compiler - sorry" 1>&2; exit 1; }
+fi
+rm -fr conftest*
+fi
+
+
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 971 "configure"
#include "confdefs.h"
main()
@@ -495,61 +977,94 @@ main()
}
EOF
-eval $ac_compile
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
- echo "configure: Your compiler does not set the exit status - sorry" >&2; exit 1
-
+if { (eval echo configure:981: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ { echo "configure: error: Your compiler does not set the exit status - sorry" 1>&2; exit 1; }
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -fr conftest*
+fi
+
for ac_prog in mawk gawk nawk awk
do
-if test -z "$AWK"; then
- # Extract the first word of `$ac_prog', so it can be a program name with args.
- set ac_dummy $ac_prog; ac_word=$2
- test -n "$silent" || echo "checking for $ac_word"
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:997: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
for ac_dir in $PATH; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
- AWK="$ac_prog"
+ ac_cv_prog_AWK="$ac_prog"
break
fi
done
IFS="$ac_save_ifs"
fi
-
-test -n "$AWK" && test -n "$verbose" && echo " setting AWK to $AWK"
+fi
+AWK="$ac_cv_prog_AWK"
+if test -n "$AWK"; then
+ echo "$ac_t""$AWK" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
test -n "$AWK" && break
done
-# Make sure to not get the incompatible SysV /etc/install and
-# /usr/sbin/install, which might be in PATH before a BSD-like install,
-# or the SunOS /usr/etc/install directory, or the AIX /bin/install,
-# or the AFS install, which mishandles nonexistent args, or
-# /usr/ucb/install on SVR4, which tries to use the nonexistent group
-# `staff', or /sbin/install on IRIX which has incompatible command-line
-# syntax. Sigh.
-#
-# On most BSDish systems install is in /usr/bin, not /usr/ucb
-# anyway.
-# This turns out not to be true, so the mere pathname isn't an indication
-# of whether the program works. What we really need is a set of tests for
-# the install program to see if it actually works in all the required ways.
-#
-# Avoid using ./install, which might have been erroneously created
-# by make from ./install.sh.
-if test -z "${INSTALL}"; then
- test -n "$silent" || echo "checking for a BSD compatible install"
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:1056: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:"
for ac_dir in $PATH; do
- case "$ac_dir" in
- ''|.|/etc|/sbin|/usr/sbin|/usr/etc|/usr/afsws/bin|/usr/ucb) ;;
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
*)
# OSF1 and SCO ODT 3.0 have their own names for install.
- for ac_prog in installbsd scoinst install; do
+ for ac_prog in ginstall installbsd scoinst install; do
if test -f $ac_dir/$ac_prog; then
if test $ac_prog = install &&
grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
@@ -557,7 +1072,7 @@ if test -z "${INSTALL}"; then
# OSF/1 installbsd also uses dspmsg, but is usable.
:
else
- INSTALL="$ac_dir/$ac_prog -c"
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
break 2
fi
fi
@@ -565,139 +1080,136 @@ if test -z "${INSTALL}"; then
;;
esac
done
- IFS="$ac_save_ifs"
-fi
+ IFS="$ac_save_IFS"
-if test -z "$INSTALL"; then
- # As a last resort, use the slow shell script.
- for ac_dir in ${srcdir} ${srcdir}/.. ${srcdir}/../..; do
- if test -f $ac_dir/install.sh; then
- INSTALL="$ac_dir/install.sh -c"; break
- fi
- done
fi
-if test -z "$INSTALL"; then
- echo "configure: can not find install.sh in ${srcdir} or ${srcdir}/.. or ${srcdir}/../.." >&2; exit 1
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
fi
-test -n "$verbose" && echo " setting INSTALL to $INSTALL"
+echo "$ac_t""$INSTALL" 1>&6
-# Use test -z because SunOS4 sh mishandles ${INSTALL_PROGRAM-'${INSTALL}'}.
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
# It thinks the first close brace ends the variable substitution.
test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
-test -n "$verbose" && echo " setting INSTALL_PROGRAM to $INSTALL_PROGRAM"
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
-test -n "$verbose" && echo " setting INSTALL_DATA to $INSTALL_DATA"
if test -f etc/toolcheck; then
-test -n "$silent" || echo "checking for buggy tools"
-sh etc/toolcheck
+echo "checking for buggy tools" 1>&6
+echo "configure:1108: checking for buggy tools" >&5
+sh etc/toolcheck 1>&6
fi
if test -n "$ISC"; then
-
-{
-test -n "$verbose" && \
-echo " defining ISC"
-echo "#define" ISC "1" >> confdefs.h
-DEFS="$DEFS -DISC=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}ISC\${ac_dB}ISC\${ac_dC}1\${ac_dD}
-\${ac_uA}ISC\${ac_uB}ISC\${ac_uC}1\${ac_uD}
-\${ac_eA}ISC\${ac_eB}ISC\${ac_eC}1\${ac_eD}
-"
-}
+ cat >> confdefs.h <<\EOF
+#define ISC 1
+EOF
LIBS="$LIBS -linet"
fi
if test -f /sysV68 ; then
-
-{
-test -n "$verbose" && \
-echo " defining sysV68"
-echo "#define" sysV68 "1" >> confdefs.h
-DEFS="$DEFS -DsysV68=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}sysV68\${ac_dB}sysV68\${ac_dC}1\${ac_dD}
-\${ac_uA}sysV68\${ac_uB}sysV68\${ac_uC}1\${ac_uD}
-\${ac_eA}sysV68\${ac_eB}sysV68\${ac_eC}1\${ac_eD}
-"
-}
+cat >> confdefs.h <<\EOF
+#define sysV68 1
+EOF
fi
-test -n "$silent" || echo "checking for MIPS"
+echo "checking for MIPS" 1>&6
+echo "configure:1128: checking for MIPS" >&5
if test -f /lib/libmld.a || test -f /usr/lib/libmld.a || test -f /usr/lib/cmplrs/cc/libmld.a; then
+oldlibs="$LIBS"
test -f /bin/mx || LIBS="$LIBS -lmld" # for nlist. But not on alpha.
-if test -r /dev/ptc; then
+echo "checking mld library" 1>&6
+echo "configure:1133: checking mld library" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1135 "configure"
+#include "confdefs.h"
-{
-test -n "$verbose" && \
-echo " defining MIPS"
-echo "#define" MIPS "1" >> confdefs.h
-DEFS="$DEFS -DMIPS=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}MIPS\${ac_dB}MIPS\${ac_dC}1\${ac_dD}
-\${ac_uA}MIPS\${ac_uB}MIPS\${ac_uC}1\${ac_uD}
-\${ac_eA}MIPS\${ac_eB}MIPS\${ac_eC}1\${ac_eD}
-"
-}
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1142: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ LIBS="$oldlibs"
+fi
+rm -f conftest*
+if test -r /dev/ptc; then
+cat >> confdefs.h <<\EOF
+#define MIPS 1
+EOF
-test -n "$silent" || echo "checking for wait3"
-cat > conftest.${ac_ext} <<EOF
+echo "checking wait3" 1>&6
+echo "configure:1157: checking wait3" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1159 "configure"
#include "confdefs.h"
-int main() { return 0; }
-int t() { wait3();; return 0; }
+int main() {
+wait3();
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:1166: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
:
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
- test -n "$silent" || echo "checking for wait2"
-cat > conftest.${ac_ext} <<EOF
+ echo "checking wait2" 1>&6
+echo "configure:1173: checking wait2" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1175 "configure"
#include "confdefs.h"
-int main() { return 0; }
-int t() { wait2();; return 0; }
+int main() {
+wait2();
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:1182: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining USE_WAIT2"
-echo "#define" USE_WAIT2 "1" >> confdefs.h
-DEFS="$DEFS -DUSE_WAIT2=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}USE_WAIT2\${ac_dB}USE_WAIT2\${ac_dC}1\${ac_dD}
-\${ac_uA}USE_WAIT2\${ac_uB}USE_WAIT2\${ac_uC}1\${ac_uD}
-\${ac_eA}USE_WAIT2\${ac_eB}USE_WAIT2\${ac_eC}1\${ac_eD}
-"
-}
+ cat >> confdefs.h <<\EOF
+#define USE_WAIT2 1
+EOF
LIBS="$LIBS -lbsd" ; CC="$CC -I/usr/include/bsd"
-
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -f conftest*
-
fi
rm -f conftest*
-
fi
fi
-test -n "$silent" || echo "checking for Ultrix"
-cat > conftest.${ac_ext} <<EOF
+
+echo "checking for Ultrix" 1>&6
+echo "configure:1201: checking for Ultrix" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1203 "configure"
#include "confdefs.h"
#if defined(ultrix) || defined(__ultrix)
- yes
+ yes;
#endif
EOF
-eval "$ac_cpp conftest.${ac_ext} > conftest.out 2>&1"
-if egrep "yes" conftest.out >/dev/null 2>&1; then
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
rm -rf conftest*
ULTRIX=1
-
fi
rm -f conftest*
@@ -705,49 +1217,45 @@ rm -f conftest*
if test -f /usr/lib/libpyr.a ; then
oldlibs="$LIBS"
LIBS="$LIBS -lpyr"
-test -n "$silent" || echo "checking for Pyramid OSX"
-cat > conftest.${ac_ext} <<EOF
+echo "checking Pyramid OSX" 1>&6
+echo "configure:1222: checking Pyramid OSX" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1224 "configure"
#include "confdefs.h"
-int main() { return 0; }
-int t() { open_controlling_pty("");; return 0; }
+int main() {
+open_controlling_pty("")
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:1231: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining OSX"
-echo "#define" OSX "1" >> confdefs.h
-DEFS="$DEFS -DOSX=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}OSX\${ac_dB}OSX\${ac_dC}1\${ac_dD}
-\${ac_uA}OSX\${ac_uB}OSX\${ac_uC}1\${ac_uD}
-\${ac_eA}OSX\${ac_eB}OSX\${ac_eC}1\${ac_eD}
-"
-}
-
+ cat >> confdefs.h <<\EOF
+#define OSX 1
+EOF
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
- LIBS="oldlibs"
+ LIBS="$oldlibs"
fi
rm -f conftest*
-
fi
-test -n "$silent" || echo "checking for butterfly"
-cat > conftest.${ac_ext} <<EOF
+echo "checking for butterfly" 1>&6
+echo "configure:1247: checking for butterfly" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1249 "configure"
#include "confdefs.h"
#if defined(butterfly)
- yes
+ yes;
#endif
EOF
-eval "$ac_cpp conftest.${ac_ext} > conftest.out 2>&1"
-if egrep "yes" conftest.out >/dev/null 2>&1; then
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
rm -rf conftest*
butterfly=1
-
fi
rm -f conftest*
@@ -756,192 +1264,207 @@ if test -z "$butterfly"; then
if test -n "$ULTRIX"; then
test -z "$GCC" && CC="$CC -YBSD"
fi
-test -n "$silent" || echo "checking for POSIX.1"
-cat > conftest.${ac_ext} <<EOF
+echo "checking for POSIX.1" 1>&6
+echo "configure:1269: checking for POSIX.1" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1271 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <unistd.h>
main () {
#ifdef _POSIX_VERSION
- yes
+ yes;
#endif
EOF
-eval "$ac_cpp conftest.${ac_ext} > conftest.out 2>&1"
-if egrep "yes" conftest.out >/dev/null 2>&1; then
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
rm -rf conftest*
- test -n "$silent" || echo "- you have a POSIX system"
-{
-test -n "$verbose" && \
-echo " defining POSIX"
-echo "#define" POSIX "1" >> confdefs.h
-DEFS="$DEFS -DPOSIX=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}POSIX\${ac_dB}POSIX\${ac_dC}1\${ac_dD}
-\${ac_uA}POSIX\${ac_uB}POSIX\${ac_uC}1\${ac_uD}
-\${ac_eA}POSIX\${ac_eB}POSIX\${ac_eC}1\${ac_eD}
-"
-}
+ echo "- you have a POSIX system" 1>&6
+ cat >> confdefs.h <<\EOF
+#define POSIX 1
+EOF
posix=1
-
fi
rm -f conftest*
fi
-test -n "$silent" || echo "checking for System V"
-cat > conftest.${ac_ext} <<EOF
+echo "checking for System V" 1>&6
+echo "configure:1295: checking for System V" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1297 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <signal.h>
#include <fcntl.h>
-int main() { return 0; }
-int t() { int x = SIGCHLD | FNDELAY;; return 0; }
+int main() {
+int x = SIGCHLD | FNDELAY;
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:1306: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
:
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining SYSV"
-echo "#define" SYSV "1" >> confdefs.h
-DEFS="$DEFS -DSYSV=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}SYSV\${ac_dB}SYSV\${ac_dC}1\${ac_dD}
-\${ac_uA}SYSV\${ac_uB}SYSV\${ac_uC}1\${ac_uD}
-\${ac_eA}SYSV\${ac_eB}SYSV\${ac_eC}1\${ac_eD}
-"
-}
+ cat >> confdefs.h <<\EOF
+#define SYSV 1
+EOF
fi
rm -f conftest*
-
-test -n "$silent" || echo "checking for sequent/ptx"
-cat > conftest.${ac_ext} <<EOF
+echo "checking for sequent/ptx" 1>&6
+echo "configure:1320: checking for sequent/ptx" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1322 "configure"
#include "confdefs.h"
#ifdef _SEQUENT_
- yes
+ yes;
#endif
EOF
-eval "$ac_cpp conftest.${ac_ext} > conftest.out 2>&1"
-if egrep "yes" conftest.out >/dev/null 2>&1; then
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
rm -rf conftest*
LIBS="$LIBS -lsocket -linet";seqptx=1
-
fi
rm -f conftest*
oldlibs="$LIBS"
LIBS="$LIBS -lelf"
-test -n "$silent" || echo "checking for SVR4"
-cat > conftest.${ac_ext} <<EOF
+echo "checking SVR4" 1>&6
+echo "configure:1340: checking SVR4" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1342 "configure"
#include "confdefs.h"
#include <utmpx.h>
-int main() { return 0; }
-int t() { ; return 0; }
+int main() {
+
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:1350: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
- test -n "$silent" || echo "checking for dwarf.h"
-cat > conftest.${ac_ext} <<EOF
+ ac_safe=`echo "dwarf.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for dwarf.h""... $ac_c" 1>&6
+echo "configure:1354: checking for dwarf.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1359 "configure"
#include "confdefs.h"
#include <dwarf.h>
EOF
-# Some shells (Coherent) do redirections in the wrong order, so need
-# the parens.
-ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"`
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1364: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining SVR4"
-echo "#define" SVR4 "1" >> confdefs.h
-DEFS="$DEFS -DSVR4=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}SVR4\${ac_dB}SVR4\${ac_dC}1\${ac_dD}
-\${ac_uA}SVR4\${ac_uB}SVR4\${ac_uC}1\${ac_uD}
-\${ac_eA}SVR4\${ac_eB}SVR4\${ac_eC}1\${ac_eD}
-"
-}
-
-{
-test -n "$verbose" && \
-echo " defining BUGGYGETLOGIN"
-echo "#define" BUGGYGETLOGIN "1" >> confdefs.h
-DEFS="$DEFS -DBUGGYGETLOGIN=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}BUGGYGETLOGIN\${ac_dB}BUGGYGETLOGIN\${ac_dC}1\${ac_dD}
-\${ac_uA}BUGGYGETLOGIN\${ac_uB}BUGGYGETLOGIN\${ac_uC}1\${ac_uD}
-\${ac_eA}BUGGYGETLOGIN\${ac_eB}BUGGYGETLOGIN\${ac_eC}1\${ac_eD}
-"
-}
-
-
+ eval "ac_cv_header_$ac_safe=yes"
else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
- test -n "$silent" || echo "checking for elf.h"
-cat > conftest.${ac_ext} <<EOF
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define SVR4 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define BUGGYGETLOGIN 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+ac_safe=`echo "elf.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for elf.h""... $ac_c" 1>&6
+echo "configure:1391: checking for elf.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1396 "configure"
#include "confdefs.h"
#include <elf.h>
EOF
-# Some shells (Coherent) do redirections in the wrong order, so need
-# the parens.
-ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"`
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1401: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining SVR4"
-echo "#define" SVR4 "1" >> confdefs.h
-DEFS="$DEFS -DSVR4=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}SVR4\${ac_dB}SVR4\${ac_dC}1\${ac_dD}
-\${ac_uA}SVR4\${ac_uB}SVR4\${ac_uC}1\${ac_uD}
-\${ac_eA}SVR4\${ac_eB}SVR4\${ac_eC}1\${ac_eD}
-"
-}
-
-{
-test -n "$verbose" && \
-echo " defining BUGGYGETLOGIN"
-echo "#define" BUGGYGETLOGIN "1" >> confdefs.h
-DEFS="$DEFS -DBUGGYGETLOGIN=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}BUGGYGETLOGIN\${ac_dB}BUGGYGETLOGIN\${ac_dC}1\${ac_dD}
-\${ac_uA}BUGGYGETLOGIN\${ac_uB}BUGGYGETLOGIN\${ac_uC}1\${ac_uD}
-\${ac_eA}BUGGYGETLOGIN\${ac_eB}BUGGYGETLOGIN\${ac_eC}1\${ac_eD}
-"
-}
-
-
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
fi
rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define SVR4 1
+EOF
+ cat >> confdefs.h <<\EOF
+#define BUGGYGETLOGIN 1
+EOF
+else
+ echo "$ac_t""no" 1>&6
fi
-rm -f conftest*
+fi
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
LIBS="$oldlibs"
fi
rm -f conftest*
+echo "checking for Solaris 2.x" 1>&6
+echo "configure:1440: checking for Solaris 2.x" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1442 "configure"
+#include "confdefs.h"
+#if defined(SVR4) && defined(sun)
+ yes
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
+ rm -rf conftest*
+ LIBS="$LIBS -lsocket -lnsl -lkstat"
+fi
+rm -f conftest*
-test -n "$silent" || echo "checking for BSD job control"
-cat > conftest.${ac_ext} <<EOF
+echo "checking BSD job jontrol" 1>&6
+echo "configure:1460: checking BSD job jontrol" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1462 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/ioctl.h>
-int main() { return 0; }
-int t() {
+int main() {
+
#ifdef POSIX
tcsetpgrp(0, 0);
#else
@@ -952,127 +1475,128 @@ setpgrp();
int y = TIOCNOTTY;
#endif
#endif
+
; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:1482: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
- test -n "$silent" || echo "- you have jobcontrol"
-{
-test -n "$verbose" && \
-echo " defining BSDJOBS"
-echo "#define" BSDJOBS "1" >> confdefs.h
-DEFS="$DEFS -DBSDJOBS=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}BSDJOBS\${ac_dB}BSDJOBS\${ac_dC}1\${ac_dD}
-\${ac_uA}BSDJOBS\${ac_uB}BSDJOBS\${ac_uC}1\${ac_uD}
-\${ac_eA}BSDJOBS\${ac_eB}BSDJOBS\${ac_eC}1\${ac_eD}
-"
-}
-
+ echo "- you have jobcontrol" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BSDJOBS 1
+EOF
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
- test -n "$silent" || echo "- you don't have jobcontrol"
+ echo "- you don't have jobcontrol" 1>&6
+
fi
rm -f conftest*
-
-test -n "$silent" || echo "checking for setreuid"
-cat > conftest.${ac_ext} <<EOF
+echo "checking setreuid" 1>&6
+echo "configure:1499: checking setreuid" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1501 "configure"
#include "confdefs.h"
-int main() { return 0; }
-int t() {
+int main() {
+
#ifdef __hpux
setresuid(0, 0, 0);
#else
setreuid(0, 0);
#endif
+
; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:1514: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining HAVE_SETREUID"
-echo "#define" HAVE_SETREUID "1" >> confdefs.h
-DEFS="$DEFS -DHAVE_SETREUID=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE_SETREUID\${ac_dB}HAVE_SETREUID\${ac_dC}1\${ac_dD}
-\${ac_uA}HAVE_SETREUID\${ac_uB}HAVE_SETREUID\${ac_uC}1\${ac_uD}
-\${ac_eA}HAVE_SETREUID\${ac_eB}HAVE_SETREUID\${ac_eC}1\${ac_eD}
-"
-}
-
+ cat >> confdefs.h <<\EOF
+#define HAVE_SETREUID 1
+EOF
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -f conftest*
-
-test -n "$silent" || echo "checking for seteuid"
-cat > conftest.${ac_ext} <<EOF
+echo "checking seteuid" 1>&6
+echo "configure:1526: checking seteuid" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1528 "configure"
#include "confdefs.h"
-int main() { return 0; }
-int t() {
+int main() {
+
#if defined(linux) || defined(NeXT) || defined(_AUX_SOURCE) || defined(AUX) || defined(ultrix) || (defined(sun) && defined(SVR4)) || defined(ISC) || defined(sony_news)
seteuid_is_broken(0);
#else
seteuid(0);
#endif
+
; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:1541: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining HAVE_SETEUID"
-echo "#define" HAVE_SETEUID "1" >> confdefs.h
-DEFS="$DEFS -DHAVE_SETEUID=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE_SETEUID\${ac_dB}HAVE_SETEUID\${ac_dC}1\${ac_dD}
-\${ac_uA}HAVE_SETEUID\${ac_uB}HAVE_SETEUID\${ac_uC}1\${ac_uD}
-\${ac_eA}HAVE_SETEUID\${ac_eB}HAVE_SETEUID\${ac_eC}1\${ac_eD}
-"
-}
-
+ cat >> confdefs.h <<\EOF
+#define HAVE_SETEUID 1
+EOF
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -f conftest*
-test -n "$silent" || echo "checking for select"
-cat > conftest.${ac_ext} <<EOF
+echo "checking select" 1>&6
+echo "configure:1555: checking select" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1557 "configure"
#include "confdefs.h"
-int main() { return 0; }
-int t() { select(0, 0, 0, 0, 0);; return 0; }
+int main() {
+select(0, 0, 0, 0, 0);
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:1564: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
:
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
LIBS="$LIBS -lnet -lnsl"
-test -n "$silent" || echo "checking for select with $LIBS"
-cat > conftest.${ac_ext} <<EOF
+echo "checking select with $LIBS" 1>&6
+echo "configure:1572: checking select with $LIBS" >&5
+cat > conftest.$ac_ext <<EOF
+#line 1574 "configure"
#include "confdefs.h"
-int main() { return 0; }
-int t() { select(0, 0, 0, 0, 0);; return 0; }
+int main() {
+select(0, 0, 0, 0, 0);
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:1581: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
:
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
- echo "configure: !!! no select - no screen" >&2; exit 1
+ { echo "configure: error: !!! no select - no screen" 1>&2; exit 1; }
fi
rm -f conftest*
-
fi
rm -f conftest*
-
-test -n "$silent" || echo "checking fifos"
-cat > conftest.${ac_ext} <<EOF
+echo "checking fifos" 1>&6
+echo "configure:1595: checking fifos" >&5
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1600 "configure"
#include "confdefs.h"
#include <sys/types.h>
@@ -1132,19 +1656,30 @@ main()
}
EOF
-eval $ac_compile
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
- test -n "$silent" || echo "- your fifos are usable";fifo=1
-
+if { (eval echo configure:1660: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ echo "- your fifos are usable" 1>&6
+ fifo=1
else
- test -n "$silent" || echo "- your fifos are not usable"
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ echo "- your fifos are not usable" 1>&6
+
fi
rm -fr conftest*
+fi
+
rm -f /tmp/conftest*
if test -n "$fifo"; then
-test -n "$silent" || echo "checking for broken fifo implementation"
-cat > conftest.${ac_ext} <<EOF
+echo "checking for broken fifo implementation" 1>&6
+echo "configure:1678: checking for broken fifo implementation" >&5
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1683 "configure"
#include "confdefs.h"
#include <sys/types.h>
@@ -1184,31 +1719,34 @@ main()
}
EOF
-eval $ac_compile
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
- test -n "$silent" || echo "- your implementation is ok"
+if { (eval echo configure:1723: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ echo "- your implementation is ok" 1>&6
else
- test -n "$silent" || echo "- you have a broken implementation"
-{
-test -n "$verbose" && \
-echo " defining BROKEN_PIPE"
-echo "#define" BROKEN_PIPE "1" >> confdefs.h
-DEFS="$DEFS -DBROKEN_PIPE=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}BROKEN_PIPE\${ac_dB}BROKEN_PIPE\${ac_dC}1\${ac_dD}
-\${ac_uA}BROKEN_PIPE\${ac_uB}BROKEN_PIPE\${ac_uC}1\${ac_uD}
-\${ac_eA}BROKEN_PIPE\${ac_eB}BROKEN_PIPE\${ac_eC}1\${ac_eD}
-"
-}
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ echo "- you have a broken implementation" 1>&6
+ cat >> confdefs.h <<\EOF
+#define BROKEN_PIPE 1
+EOF
fifobr=1
fi
rm -fr conftest*
+fi
+
rm -f /tmp/conftest*
fi
-test -n "$silent" || echo "checking sockets"
-cat > conftest.${ac_ext} <<EOF
+echo "checking sockets" 1>&6
+echo "configure:1745: checking sockets" >&5
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1750 "configure"
#include "confdefs.h"
#include <sys/types.h>
@@ -1253,19 +1791,30 @@ main()
}
EOF
-eval $ac_compile
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
- test -n "$silent" || echo "- your sockets are usable";sock=1
-
+if { (eval echo configure:1795: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ echo "- your sockets are usable" 1>&6
+ sock=1
else
- test -n "$silent" || echo "- your sockets are not usable"
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ echo "- your sockets are not usable" 1>&6
+
fi
rm -fr conftest*
+fi
+
rm -f /tmp/conftest*
if test -n "$sock"; then
-test -n "$silent" || echo "checking socket implementation"
-cat > conftest.${ac_ext} <<EOF
+echo "checking socket implementation" 1>&6
+echo "configure:1813: checking socket implementation" >&5
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1818 "configure"
#include "confdefs.h"
#include <sys/types.h>
@@ -1294,26 +1843,24 @@ main()
}
EOF
-eval $ac_compile
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
- test -n "$silent" || echo "- you are normal"
+if { (eval echo configure:1847: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ echo "- you are normal" 1>&6
else
- test -n "$silent" || echo "- unix domain sockets are not kept in the filesystem"
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ echo "- unix domain sockets are not kept in the filesystem" 1>&6
-{
-test -n "$verbose" && \
-echo " defining SOCK_NOT_IN_FS"
-echo "#define" SOCK_NOT_IN_FS "1" >> confdefs.h
-DEFS="$DEFS -DSOCK_NOT_IN_FS=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}SOCK_NOT_IN_FS\${ac_dB}SOCK_NOT_IN_FS\${ac_dC}1\${ac_dD}
-\${ac_uA}SOCK_NOT_IN_FS\${ac_uB}SOCK_NOT_IN_FS\${ac_uC}1\${ac_uD}
-\${ac_eA}SOCK_NOT_IN_FS\${ac_eB}SOCK_NOT_IN_FS\${ac_eC}1\${ac_eD}
-"
-}
+cat >> confdefs.h <<\EOF
+#define SOCK_NOT_IN_FS 1
+EOF
socknofs=1
fi
rm -fr conftest*
+fi
+
rm -f /tmp/conftest*
fi
@@ -1321,60 +1868,46 @@ fi
if test -n "$fifo"; then
if test -n "$sock"; then
if test -n "$nore"; then
- test -n "$silent" || echo "- hmmm... better take the fifos"
-
-{
-test -n "$verbose" && \
-echo " defining NAMEDPIPE"
-echo "#define" NAMEDPIPE "1" >> confdefs.h
-DEFS="$DEFS -DNAMEDPIPE=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}NAMEDPIPE\${ac_dB}NAMEDPIPE\${ac_dC}1\${ac_dD}
-\${ac_uA}NAMEDPIPE\${ac_uB}NAMEDPIPE\${ac_uC}1\${ac_uD}
-\${ac_eA}NAMEDPIPE\${ac_eB}NAMEDPIPE\${ac_eC}1\${ac_eD}
-"
-}
+ echo "- hmmm... better take the fifos" 1>&6
+
+ cat >> confdefs.h <<\EOF
+#define NAMEDPIPE 1
+EOF
elif test -n "$fifobr"; then
- test -n "$silent" || echo "- as your fifos are broken lets use the sockets."
+ echo "- as your fifos are broken lets use the sockets." 1>&6
+
else
- test -n "$silent" || echo "- both sockets and fifos usable. let's take fifos."
-
-{
-test -n "$verbose" && \
-echo " defining NAMEDPIPE"
-echo "#define" NAMEDPIPE "1" >> confdefs.h
-DEFS="$DEFS -DNAMEDPIPE=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}NAMEDPIPE\${ac_dB}NAMEDPIPE\${ac_dC}1\${ac_dD}
-\${ac_uA}NAMEDPIPE\${ac_uB}NAMEDPIPE\${ac_uC}1\${ac_uD}
-\${ac_eA}NAMEDPIPE\${ac_eB}NAMEDPIPE\${ac_eC}1\${ac_eD}
-"
-}
+ echo "- both sockets and fifos usable. let's take fifos." 1>&6
+
+ cat >> confdefs.h <<\EOF
+#define NAMEDPIPE 1
+EOF
fi
else
- test -n "$silent" || echo "- using named pipes"
-
-{
-test -n "$verbose" && \
-echo " defining NAMEDPIPE"
-echo "#define" NAMEDPIPE "1" >> confdefs.h
-DEFS="$DEFS -DNAMEDPIPE=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}NAMEDPIPE\${ac_dB}NAMEDPIPE\${ac_dC}1\${ac_dD}
-\${ac_uA}NAMEDPIPE\${ac_uB}NAMEDPIPE\${ac_uC}1\${ac_uD}
-\${ac_eA}NAMEDPIPE\${ac_eB}NAMEDPIPE\${ac_eC}1\${ac_eD}
-"
-}
+ echo "- using named pipes" 1>&6
+
+ cat >> confdefs.h <<\EOF
+#define NAMEDPIPE 1
+EOF
fi
elif test -n "$sock"; then
- test -n "$silent" || echo "- using unix-domain sockets"
+ echo "- using unix-domain sockets" 1>&6
+
else
- echo "configure: you have neither usable sockets nor usable pipes -> no screen" >&2; exit 1
+ { echo "configure: error: you have neither usable sockets nor usable pipes -> no screen" 1>&2; exit 1; }
fi
-test -n "$silent" || echo "checking select return value"
-cat > conftest.${ac_ext} <<EOF
+echo "checking select return value" 1>&6
+echo "configure:1906: checking select return value" >&5
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1911 "configure"
#include "confdefs.h"
#include <sys/types.h>
@@ -1399,7 +1932,7 @@ main()
#ifdef __FreeBSD__
/* From Andrew A. Chernov (ache@astral.msk.su):
- * opening RDWR fifo fails in BSD 4.4, but select return values is
+ * opening RDWR fifo fails in BSD 4.4, but select return values are
* right.
*/
exit(0);
@@ -1463,82 +1996,116 @@ main()
}
EOF
-eval $ac_compile
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
- test -n "$silent" || echo "- select is ok"
+if { (eval echo configure:2000: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ echo "- select is ok" 1>&6
else
- test -n "$silent" || echo "- it is not usable"
-{
-test -n "$verbose" && \
-echo " defining SELECT_BROKEN"
-echo "#define" SELECT_BROKEN "1" >> confdefs.h
-DEFS="$DEFS -DSELECT_BROKEN=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}SELECT_BROKEN\${ac_dB}SELECT_BROKEN\${ac_dC}1\${ac_dD}
-\${ac_uA}SELECT_BROKEN\${ac_uB}SELECT_BROKEN\${ac_uC}1\${ac_uD}
-\${ac_eA}SELECT_BROKEN\${ac_eB}SELECT_BROKEN\${ac_eC}1\${ac_eD}
-"
-}
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ echo "- it is not usable" 1>&6
+ cat >> confdefs.h <<\EOF
+#define SELECT_BROKEN 1
+EOF
fi
rm -fr conftest*
+fi
+
-test -n "$silent" || echo "checking for tgetent"
+echo "checking for tgetent" 1>&6
+echo "configure:2019: checking for tgetent" >&5
olibs="$LIBS"
LIBS="-lcurses $olibs"
-test -n "$silent" || echo "checking for libcurses"
-cat > conftest.${ac_ext} <<EOF
+echo "checking libcurses" 1>&6
+echo "configure:2023: checking libcurses" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2025 "configure"
#include "confdefs.h"
-int main() { return 0; }
-int t() {
+int main() {
+
#ifdef __hpux
__sorry_hpux_libcurses_is_totally_broken_in_10_10();
#else
tgetent((char *)0, (char *)0);
#endif
+
; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:2038: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
:
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
LIBS="-ltermcap $olibs"
-test -n "$silent" || echo "checking for libtermcap"
-cat > conftest.${ac_ext} <<EOF
+echo "checking libtermcap" 1>&6
+echo "configure:2046: checking libtermcap" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2048 "configure"
#include "confdefs.h"
-int main() { return 0; }
-int t() { tgetent((char *)0, (char *)0);; return 0; }
+int main() {
+tgetent((char *)0, (char *)0);
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:2055: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
:
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
LIBS="-ltermlib $olibs"
-test -n "$silent" || echo "checking for libtermlib"
-cat > conftest.${ac_ext} <<EOF
+echo "checking libtermlib" 1>&6
+echo "configure:2063: checking libtermlib" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2065 "configure"
#include "confdefs.h"
-int main() { return 0; }
-int t() { tgetent((char *)0, (char *)0);; return 0; }
+int main() {
+tgetent((char *)0, (char *)0);
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:2072: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
:
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
- echo "configure: !!! no tgetent - no screen" >&2; exit 1
+ LIBS="-lncurses $olibs"
+echo "checking libncurses" 1>&6
+echo "configure:2080: checking libncurses" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2082 "configure"
+#include "confdefs.h"
+
+int main() {
+tgetent((char *)0, (char *)0);
+; return 0; }
+EOF
+if { (eval echo configure:2089: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ { echo "configure: error: !!! no tgetent - no screen" 1>&2; exit 1; }
+fi
+rm -f conftest*
fi
rm -f conftest*
-
fi
rm -f conftest*
-
fi
rm -f conftest*
-
-cat > conftest.${ac_ext} <<EOF
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2109 "configure"
#include "confdefs.h"
main()
@@ -1546,107 +2113,125 @@ main()
exit(strcmp(tgoto("%p1%d", 0, 1), "1") ? 0 : 1);
}
EOF
-eval $ac_compile
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
- test -n "$silent" || echo "- you use the termcap database"
+if { (eval echo configure:2117: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ echo "- you use the termcap database" 1>&6
else
- test -n "$silent" || echo "- you use the terminfo database"
-{
-test -n "$verbose" && \
-echo " defining TERMINFO"
-echo "#define" TERMINFO "1" >> confdefs.h
-DEFS="$DEFS -DTERMINFO=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}TERMINFO\${ac_dB}TERMINFO\${ac_dC}1\${ac_dD}
-\${ac_uA}TERMINFO\${ac_uB}TERMINFO\${ac_uC}1\${ac_uD}
-\${ac_eA}TERMINFO\${ac_eB}TERMINFO\${ac_eC}1\${ac_eD}
-"
-}
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ echo "- you use the terminfo database" 1>&6
+ cat >> confdefs.h <<\EOF
+#define TERMINFO 1
+EOF
fi
rm -fr conftest*
-test -n "$silent" || echo "checking for ospeed"
-cat > conftest.${ac_ext} <<EOF
+fi
+
+echo "checking ospeed" 1>&6
+echo "configure:2135: checking ospeed" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2137 "configure"
#include "confdefs.h"
extern short ospeed;
-int main() { return 0; }
-int t() { ospeed=5;; return 0; }
+int main() {
+ospeed=5;
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:2144: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
:
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining NEED_OSPEED"
-echo "#define" NEED_OSPEED "1" >> confdefs.h
-DEFS="$DEFS -DNEED_OSPEED=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}NEED_OSPEED\${ac_dB}NEED_OSPEED\${ac_dC}1\${ac_dD}
-\${ac_uA}NEED_OSPEED\${ac_uB}NEED_OSPEED\${ac_uC}1\${ac_uD}
-\${ac_eA}NEED_OSPEED\${ac_eB}NEED_OSPEED\${ac_eC}1\${ac_eD}
-"
-}
+ cat >> confdefs.h <<\EOF
+#define NEED_OSPEED 1
+EOF
fi
rm -f conftest*
-
-test -n "$silent" || echo "checking for /dev/ptc"
+echo "checking for /dev/ptc" 1>&6
+echo "configure:2158: checking for /dev/ptc" >&5
if test -r /dev/ptc; then
+cat >> confdefs.h <<\EOF
+#define HAVE_DEV_PTC 1
+EOF
-{
-test -n "$verbose" && \
-echo " defining HAVE_DEV_PTC"
-echo "#define" HAVE_DEV_PTC "1" >> confdefs.h
-DEFS="$DEFS -DHAVE_DEV_PTC=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE_DEV_PTC\${ac_dB}HAVE_DEV_PTC\${ac_dC}1\${ac_dD}
-\${ac_uA}HAVE_DEV_PTC\${ac_uB}HAVE_DEV_PTC\${ac_uC}1\${ac_uD}
-\${ac_eA}HAVE_DEV_PTC\${ac_eB}HAVE_DEV_PTC\${ac_eC}1\${ac_eD}
-"
-}
+fi
+
+echo "checking for SVR4 ptys" 1>&6
+echo "configure:2167: checking for SVR4 ptys" >&5
+if test -c /dev/ptmx ; then
+cat > conftest.$ac_ext <<EOF
+#line 2170 "configure"
+#include "confdefs.h"
+
+int main() {
+ptsname(0);grantpt(0);unlockpt(0);
+; return 0; }
+EOF
+if { (eval echo configure:2177: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ cat >> confdefs.h <<\EOF
+#define HAVE_SVR4_PTYS 1
+EOF
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
fi
-test -n "$silent" || echo "checking for ptyranges"
+echo "checking for ptyranges" 1>&6
+echo "configure:2191: checking for ptyranges" >&5
if test -d /dev/ptym ; then
pdir='/dev/ptym'
else
pdir='/dev'
fi
-ptys=`echo $pdir/pty??`
+cat > conftest.$ac_ext <<EOF
+#line 2198 "configure"
+#include "confdefs.h"
+#ifdef M_UNIX
+ yes;
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ptys=`echo /dev/ptyp??`
+else
+ rm -rf conftest*
+ ptys=`echo $pdir/pty??`
+fi
+rm -f conftest*
+
if test "$ptys" != "$pdir/pty??" ; then
p0=`echo $ptys | tr ' ' '\012' | sed -e 's/^.*\(.\).$/\1/g' | sort -u | tr -d '\012'`
p1=`echo $ptys | tr ' ' '\012' | sed -e 's/^.*\(.\)$/\1/g' | sort -u | tr -d '\012'`
+cat >> confdefs.h <<EOF
+#define PTYRANGE0 "$p0"
+EOF
-{
-test -n "$verbose" && \
-echo " defining" PTYRANGE0 to be "\"$p0\""
-echo "#define" PTYRANGE0 "\"$p0\"" >> confdefs.h
-DEFS="$DEFS -DPTYRANGE0=\"$p0\""
-ac_sed_defs="${ac_sed_defs}\${ac_dA}PTYRANGE0\${ac_dB}PTYRANGE0\${ac_dC}\"$p0\"\${ac_dD}
-\${ac_uA}PTYRANGE0\${ac_uB}PTYRANGE0\${ac_uC}\"$p0\"\${ac_uD}
-\${ac_eA}PTYRANGE0\${ac_eB}PTYRANGE0\${ac_eC}\"$p0\"\${ac_eD}
-"
-}
-
-
-{
-test -n "$verbose" && \
-echo " defining" PTYRANGE1 to be "\"$p1\""
-echo "#define" PTYRANGE1 "\"$p1\"" >> confdefs.h
-DEFS="$DEFS -DPTYRANGE1=\"$p1\""
-ac_sed_defs="${ac_sed_defs}\${ac_dA}PTYRANGE1\${ac_dB}PTYRANGE1\${ac_dC}\"$p1\"\${ac_dD}
-\${ac_uA}PTYRANGE1\${ac_uB}PTYRANGE1\${ac_uC}\"$p1\"\${ac_uD}
-\${ac_eA}PTYRANGE1\${ac_eB}PTYRANGE1\${ac_eC}\"$p1\"\${ac_eD}
-"
-}
+cat >> confdefs.h <<EOF
+#define PTYRANGE1 "$p1"
+EOF
fi
-test -n "$silent" || echo "checking default tty permissions/group"
+echo "checking default tty permissions/group" 1>&6
+echo "configure:2229: checking default tty permissions/group" >&5
rm -f conftest_grp
-cat > conftest.${ac_ext} <<EOF
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2235 "configure"
#include "confdefs.h"
#include <sys/types.h>
@@ -1678,51 +2263,45 @@ main()
}
EOF
-eval $ac_compile
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
+if { (eval echo configure:2267: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
if test -f conftest_grp; then
ptygrp=`cat conftest_grp`
- test -n "$silent" || echo "- pty mode: 0620"
-
-{
-test -n "$verbose" && \
-echo " defining" PTYMODE to be "0620"
-echo "#define" PTYMODE "0620" >> confdefs.h
-DEFS="$DEFS -DPTYMODE=0620"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}PTYMODE\${ac_dB}PTYMODE\${ac_dC}0620\${ac_dD}
-\${ac_uA}PTYMODE\${ac_uB}PTYMODE\${ac_uC}0620\${ac_uD}
-\${ac_eA}PTYMODE\${ac_eB}PTYMODE\${ac_eC}0620\${ac_eD}
-"
-}
+ echo "- pty mode: 0620" 1>&6
-
-{
-test -n "$verbose" && \
-echo " defining" PTYGROUP to be "$ptygrp"
-echo "#define" PTYGROUP "$ptygrp" >> confdefs.h
-DEFS="$DEFS -DPTYGROUP=$ptygrp"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}PTYGROUP\${ac_dB}PTYGROUP\${ac_dC}$ptygrp\${ac_dD}
-\${ac_uA}PTYGROUP\${ac_uB}PTYGROUP\${ac_uC}$ptygrp\${ac_uD}
-\${ac_eA}PTYGROUP\${ac_eB}PTYGROUP\${ac_eC}$ptygrp\${ac_eD}
-"
-}
+ cat >> confdefs.h <<\EOF
+#define PTYMODE 0620
+EOF
+
+ cat >> confdefs.h <<EOF
+#define PTYGROUP $ptygrp
+EOF
else
- test -n "$silent" || echo "- ptys are world accessable"
- fi
+ echo "- ptys are world accessable" 1>&6
+ fi
else
- test -n "$silent" || echo "- can't determine - assume ptys are world accessable"
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ echo "- can't determine - assume ptys are world accessable" 1>&6
+
fi
rm -fr conftest*
+fi
+
rm -f conftest_grp
-test -n "$silent" || echo "checking for getutent"
-cat > conftest.${ac_ext} <<EOF
+echo "checking getutent" 1>&6
+echo "configure:2301: checking getutent" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2303 "configure"
#include "confdefs.h"
+
#include <time.h> /* to get time_t on SCO */
#include <sys/types.h>
#if defined(SVR4) && !defined(DGUX)
@@ -1735,31 +2314,28 @@ cat > conftest.${ac_ext} <<EOF
#define pututline _pututline
#endif
-int main() { return 0; }
-int t() { int x = DEAD_PROCESS; struct utmp *y = pututline((struct utmp *)0); getutent();; return 0; }
+int main() {
+int x = DEAD_PROCESS; pututline((struct utmp *)0); getutent();
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:2322: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining GETUTENT"
-echo "#define" GETUTENT "1" >> confdefs.h
-DEFS="$DEFS -DGETUTENT=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}GETUTENT\${ac_dB}GETUTENT\${ac_dC}1\${ac_dD}
-\${ac_uA}GETUTENT\${ac_uB}GETUTENT\${ac_uC}1\${ac_uD}
-\${ac_eA}GETUTENT\${ac_eB}GETUTENT\${ac_eC}1\${ac_eD}
-"
-}
-
+ cat >> confdefs.h <<\EOF
+#define GETUTENT 1
+EOF
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
olibs="$LIBS"
LIBS="$LIBS -lgen"
-test -n "$silent" || echo "checking for getutent with -lgen"
-cat > conftest.${ac_ext} <<EOF
+echo "checking getutent with -lgen" 1>&6
+echo "configure:2335: checking getutent with -lgen" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2337 "configure"
#include "confdefs.h"
+
#include <time.h>
#include <sys/types.h>
#if defined(SVR4) && !defined(DGUX)
@@ -1772,37 +2348,32 @@ cat > conftest.${ac_ext} <<EOF
#define pututline _pututline
#endif
-int main() { return 0; }
-int t() { int x = DEAD_PROCESS; struct utmp *y = pututline((struct utmp *)0); getutent();; return 0; }
+int main() {
+int x = DEAD_PROCESS; pututline((struct utmp *)0); getutent();
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:2356: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining GETUTENT"
-echo "#define" GETUTENT "1" >> confdefs.h
-DEFS="$DEFS -DGETUTENT=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}GETUTENT\${ac_dB}GETUTENT\${ac_dC}1\${ac_dD}
-\${ac_uA}GETUTENT\${ac_uB}GETUTENT\${ac_uC}1\${ac_uD}
-\${ac_eA}GETUTENT\${ac_eB}GETUTENT\${ac_eC}1\${ac_eD}
-"
-}
-
+ cat >> confdefs.h <<\EOF
+#define GETUTENT 1
+EOF
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
LIBS="$olibs"
fi
rm -f conftest*
-
fi
rm -f conftest*
-
-test -n "$silent" || echo "checking for ut_host"
-cat > conftest.${ac_ext} <<EOF
+echo "checking ut_host" 1>&6
+echo "configure:2373: checking ut_host" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2375 "configure"
#include "confdefs.h"
+
#include <time.h>
#include <sys/types.h>
#if defined(SVR4) && !defined(DGUX)
@@ -1812,188 +2383,217 @@ cat > conftest.${ac_ext} <<EOF
#include <utmp.h>
#endif
-int main() { return 0; }
-int t() { struct utmp u; u.ut_host[0] = 0;; return 0; }
+int main() {
+struct utmp u; u.ut_host[0] = 0;
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:2391: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining UTHOST"
-echo "#define" UTHOST "1" >> confdefs.h
-DEFS="$DEFS -DUTHOST=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}UTHOST\${ac_dB}UTHOST\${ac_dC}1\${ac_dD}
-\${ac_uA}UTHOST\${ac_uB}UTHOST\${ac_uC}1\${ac_uD}
-\${ac_eA}UTHOST\${ac_eB}UTHOST\${ac_eC}1\${ac_eD}
-"
-}
-
+ cat >> confdefs.h <<\EOF
+#define UTHOST 1
+EOF
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ac_safe=`echo "utempter.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for utempter.h""... $ac_c" 1>&6
+echo "configure:2404: checking for utempter.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2409 "configure"
+#include "confdefs.h"
+#include <utempter.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2414: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
fi
rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ have_utempter=yes
+else
+ echo "$ac_t""no" 1>&6
+have_utempter=no
+fi
+if test "$have_utempter" = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_UTEMPTER 1
+EOF
+ LIBS="$LIBS -lutempter"
+fi
-test -n "$silent" || echo "checking for libutil(s)"
+echo "checking for libutil(s)" 1>&6
+echo "configure:2445: checking for libutil(s)" >&5
test -f /usr/lib/libutils.a && LIBS="$LIBS -lutils"
test -f /usr/lib/libutil.a && LIBS="$LIBS -lutil"
-test -n "$silent" || echo "checking for getloadavg"
-cat > conftest.${ac_ext} <<EOF
+echo "checking getloadavg" 1>&6
+echo "configure:2450: checking getloadavg" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2452 "configure"
#include "confdefs.h"
-int main() { return 0; }
-int t() { getloadavg((double *)0, 0);; return 0; }
+int main() {
+getloadavg((double *)0, 0);
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:2459: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining LOADAV_GETLOADAVG"
-echo "#define" LOADAV_GETLOADAVG "1" >> confdefs.h
-DEFS="$DEFS -DLOADAV_GETLOADAVG=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}LOADAV_GETLOADAVG\${ac_dB}LOADAV_GETLOADAVG\${ac_dC}1\${ac_dD}
-\${ac_uA}LOADAV_GETLOADAVG\${ac_uB}LOADAV_GETLOADAVG\${ac_uC}1\${ac_uD}
-\${ac_eA}LOADAV_GETLOADAVG\${ac_eB}LOADAV_GETLOADAVG\${ac_eC}1\${ac_eD}
-"
-}
+ cat >> confdefs.h <<\EOF
+#define LOADAV_GETLOADAVG 1
+EOF
load=1
-
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
if test -f /usr/lib/libkvm.a ; then
olibs="$LIBS"
LIBS="$LIBS -lkvm"
-test -n "$silent" || echo "checking for getloadavg with -lkvm"
-cat > conftest.${ac_ext} <<EOF
+echo "checking getloadavg with -lkvm" 1>&6
+echo "configure:2473: checking getloadavg with -lkvm" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2475 "configure"
#include "confdefs.h"
-int main() { return 0; }
-int t() { getloadavg((double *)0, 0);; return 0; }
+int main() {
+getloadavg((double *)0, 0);
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:2482: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining LOADAV_GETLOADAVG"
-echo "#define" LOADAV_GETLOADAVG "1" >> confdefs.h
-DEFS="$DEFS -DLOADAV_GETLOADAVG=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}LOADAV_GETLOADAVG\${ac_dB}LOADAV_GETLOADAVG\${ac_dC}1\${ac_dD}
-\${ac_uA}LOADAV_GETLOADAVG\${ac_uB}LOADAV_GETLOADAVG\${ac_uC}1\${ac_uD}
-\${ac_eA}LOADAV_GETLOADAVG\${ac_eB}LOADAV_GETLOADAVG\${ac_eC}1\${ac_eD}
-"
-}
+ cat >> confdefs.h <<\EOF
+#define LOADAV_GETLOADAVG 1
+EOF
load=1
-
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
LIBS="$olibs"
fi
rm -f conftest*
-
fi
fi
rm -f conftest*
-
if test -z "$load" ; then
-cat > conftest.${ac_ext} <<EOF
+cat > conftest.$ac_ext <<EOF
+#line 2502 "configure"
#include "confdefs.h"
#if defined(NeXT) || defined(apollo) || defined(linux)
- yes
+ yes;
#endif
EOF
-eval "$ac_cpp conftest.${ac_ext} > conftest.out 2>&1"
-if egrep "yes" conftest.out >/dev/null 2>&1; then
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
rm -rf conftest*
load=1
-
fi
rm -f conftest*
fi
if test -z "$load" ; then
-test -n "$silent" || echo "checking for kernelfile"
+echo "checking for kernelfile" 1>&6
+echo "configure:2519: checking for kernelfile" >&5
for core in /unix /vmunix /dynix /hp-ux /xelos /dev/ksyms /kernel/unix /kernel/genunix /unicos /mach /netbsd /386bsd /dgux /bsd /stand/vmunix; do
if test -f $core || test -c $core; then
break
fi
done
if test ! -f $core && test ! -c $core ; then
- test -n "$silent" || echo "- no kernelfile found"
+ echo "- no kernelfile found" 1>&6
+
else
- test -n "$silent" || echo "- using kernelfile '$core'"
-
-{
-test -n "$verbose" && \
-echo " defining" LOADAV_UNIX to be "\"$core\""
-echo "#define" LOADAV_UNIX "\"$core\"" >> confdefs.h
-DEFS="$DEFS -DLOADAV_UNIX=\"$core\""
-ac_sed_defs="${ac_sed_defs}\${ac_dA}LOADAV_UNIX\${ac_dB}LOADAV_UNIX\${ac_dC}\"$core\"\${ac_dD}
-\${ac_uA}LOADAV_UNIX\${ac_uB}LOADAV_UNIX\${ac_uC}\"$core\"\${ac_uD}
-\${ac_eA}LOADAV_UNIX\${ac_eB}LOADAV_UNIX\${ac_eC}\"$core\"\${ac_eD}
-"
-}
+ echo "- using kernelfile '$core'" 1>&6
+
+ if test -r $core ; then
+ cat >> confdefs.h <<EOF
+#define LOADAV_UNIX "$core"
+EOF
- test -n "$silent" || echo "checking for nlist.h"
-cat > conftest.${ac_ext} <<EOF
+ ac_safe=`echo "nlist.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for nlist.h""... $ac_c" 1>&6
+echo "configure:2538: checking for nlist.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2543 "configure"
#include "confdefs.h"
#include <nlist.h>
EOF
-# Some shells (Coherent) do redirections in the wrong order, so need
-# the parens.
-ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"`
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2548: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining NLIST_STRUCT"
-echo "#define" NLIST_STRUCT "1" >> confdefs.h
-DEFS="$DEFS -DNLIST_STRUCT=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}NLIST_STRUCT\${ac_dB}NLIST_STRUCT\${ac_dC}1\${ac_dD}
-\${ac_uA}NLIST_STRUCT\${ac_uB}NLIST_STRUCT\${ac_uC}1\${ac_uD}
-\${ac_eA}NLIST_STRUCT\${ac_eB}NLIST_STRUCT\${ac_eC}1\${ac_eD}
-"
-}
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define NLIST_STRUCT 1
+EOF
- test -n "$silent" || echo "checking for n_un in struct nlist"
-cat > conftest.${ac_ext} <<EOF
+ echo "checking n_un in struct nlist" 1>&6
+echo "configure:2569: checking n_un in struct nlist" >&5
+ cat > conftest.$ac_ext <<EOF
+#line 2571 "configure"
#include "confdefs.h"
#include <nlist.h>
-int main() { return 0; }
-int t() { struct nlist n; n.n_un.n_name = 0;; return 0; }
+int main() {
+struct nlist n; n.n_un.n_name = 0;
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:2578: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining NLIST_NAME_UNION"
-echo "#define" NLIST_NAME_UNION "1" >> confdefs.h
-DEFS="$DEFS -DNLIST_NAME_UNION=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}NLIST_NAME_UNION\${ac_dB}NLIST_NAME_UNION\${ac_dC}1\${ac_dD}
-\${ac_uA}NLIST_NAME_UNION\${ac_uB}NLIST_NAME_UNION\${ac_uC}1\${ac_uD}
-\${ac_eA}NLIST_NAME_UNION\${ac_eB}NLIST_NAME_UNION\${ac_eC}1\${ac_eD}
-"
-}
-
+ cat >> confdefs.h <<\EOF
+#define NLIST_NAME_UNION 1
+EOF
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -f conftest*
-
-
+else
+ echo "$ac_t""no" 1>&6
fi
-rm -f conftest*
- test -n "$silent" || echo "checking for nlist declaration"
- cat > conftest.${ac_ext} <<EOF
+ echo "checking for nlist declaration" 1>&6
+echo "configure:2595: checking for nlist declaration" >&5
+ cat > conftest.$ac_ext <<EOF
+#line 2597 "configure"
#include "confdefs.h"
#ifdef NLIST_STRUCT
@@ -2003,29 +2603,25 @@ rm -f conftest*
#endif
EOF
-eval "$ac_cpp conftest.${ac_ext} > conftest.out 2>&1"
-if egrep "nlist(( | )( | )*.*\(|\()" conftest.out >/dev/null 2>&1; then
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "nlist(( | )( | )*.*\(|\()" >/dev/null 2>&1; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining NLIST_DECLARED"
-echo "#define" NLIST_DECLARED "1" >> confdefs.h
-DEFS="$DEFS -DNLIST_DECLARED=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}NLIST_DECLARED\${ac_dB}NLIST_DECLARED\${ac_dC}1\${ac_dD}
-\${ac_uA}NLIST_DECLARED\${ac_uB}NLIST_DECLARED\${ac_uC}1\${ac_uD}
-\${ac_eA}NLIST_DECLARED\${ac_eB}NLIST_DECLARED\${ac_eC}1\${ac_eD}
-"
-}
-
+ cat >> confdefs.h <<\EOF
+#define NLIST_DECLARED 1
+EOF
fi
rm -f conftest*
- test -n "$silent" || echo "checking for avenrun symbol"
+ echo "checking for avenrun symbol" 1>&6
+echo "configure:2619: checking for avenrun symbol" >&5
for av in avenrun _avenrun _Loadavg ; do
- cat > conftest.${ac_ext} <<EOF
+ if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2625 "configure"
#include "confdefs.h"
#include <sys/types.h>
@@ -2036,7 +2632,7 @@ rm -f conftest*
#endif
#ifdef __sgi
-# if _MIPS_SZLONG == 64
+# if _MIPS_SZLONG == 64 || (defined(_MIPS_ISA) && _MIPS_ISA > 2)
# define nlist nlist64
# endif
#endif
@@ -2061,31 +2657,45 @@ main()
}
EOF
-eval $ac_compile
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
+if { (eval echo configure:2661: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
avensym=$av;break
-
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -fr conftest*
+fi
+
done
if test -z "$avensym" ; then
- test -n "$silent" || echo "- no avenrun symbol found"
+ echo "- no avenrun symbol found" 1>&6
+
else
- test -n "$silent" || echo "- using avenrun symbol '$avensym'"
-
-{
-test -n "$verbose" && \
-echo " defining" LOADAV_AVENRUN to be "\"$avensym\""
-echo "#define" LOADAV_AVENRUN "\"$avensym\"" >> confdefs.h
-DEFS="$DEFS -DLOADAV_AVENRUN=\"$avensym\""
-ac_sed_defs="${ac_sed_defs}\${ac_dA}LOADAV_AVENRUN\${ac_dB}LOADAV_AVENRUN\${ac_dC}\"$avensym\"\${ac_dD}
-\${ac_uA}LOADAV_AVENRUN\${ac_uB}LOADAV_AVENRUN\${ac_uC}\"$avensym\"\${ac_uD}
-\${ac_eA}LOADAV_AVENRUN\${ac_eB}LOADAV_AVENRUN\${ac_eC}\"$avensym\"\${ac_eD}
-"
-}
+ echo "- using avenrun symbol '$avensym'" 1>&6
+
+ cat >> confdefs.h <<EOF
+#define LOADAV_AVENRUN "$avensym"
+EOF
load=1
fi
+ else
+ echo "Can't configure the load average display feature" 1>&6
+
+ echo "because $core is not readable by you." 1>&6
+
+ echo "To configure the load average display feature" 1>&6
+
+ echo "re-run configure as root if possible." 1>&6
+
+ echo "If you are not the system administrator then disregard" 1>&6
+
+ echo "this warning. You can still use screen without" 1>&6
+
+ echo "the load average display feature." 1>&6
+
+ fi
fi
fi
@@ -2096,7 +2706,7 @@ cat > conftest.c <<EOF
_CUT_HERE_
-#if ((defined(hp300) && !defined(__hpux)) || defined(sun) || (defined(ultrix) && defined(mips)) || defined(_SEQUENT_) || defined(sgi) || defined(SVR4) || defined(sony_news) || defined(__alpha) || defined(_IBMR2) || defined(_AUX_SOURCE) || defined(AUX) || defined(m88k))
+#if ((defined(hp300) && !defined(__hpux)) || defined(sun) || (defined(ultrix) && defined(mips)) || defined(_SEQUENT_) || defined(sgi) || defined(SVR4) || defined(sony_news) || !(defined(__osf__) && defined(__alpha)) || defined(_IBMR2) || defined(_AUX_SOURCE) || defined(AUX) || defined(m88k))
loadtype=long
# if defined(apollo) || defined(_IBMR2) || defined(_AUX_SOURCE) || defined(AUX)
loadscale=65536
@@ -2106,8 +2716,8 @@ loadscale=65536
loadscale=FSCALE
# else
# ifdef sgi
-loadscale=1024
loadtype=int
+loadscale=1024
# else
# if defined(MIPS) || defined(SVR4) || defined(m88k)
loadscale=256
@@ -2128,81 +2738,43 @@ loadnum=3
#endif
EOF
-$CPP $DEFS conftest.c 2>/dev/null | sed -e '1,/_CUT_HERE_/d' > conftest.out
+eval "$ac_cpp conftest.c 2>&5 | sed -e '1,/_CUT_HERE_/d' > conftest.out"
. ./conftest.out
rm -f conftest*
-if test -n "$load" ; then
-{
-test -n "$verbose" && \
-echo " defining LOADAV"
-echo "#define" LOADAV "1" >> confdefs.h
-DEFS="$DEFS -DLOADAV=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}LOADAV\${ac_dB}LOADAV\${ac_dC}1\${ac_dD}
-\${ac_uA}LOADAV\${ac_uB}LOADAV\${ac_uC}1\${ac_uD}
-\${ac_eA}LOADAV\${ac_eB}LOADAV\${ac_eC}1\${ac_eD}
-"
-}
+if test -n "$load" ; then cat >> confdefs.h <<\EOF
+#define LOADAV 1
+EOF
fi
-if test -n "$loadtype" ; then
-{
-test -n "$verbose" && \
-echo " defining" LOADAV_TYPE to be "$loadtype"
-echo "#define" LOADAV_TYPE "$loadtype" >> confdefs.h
-DEFS="$DEFS -DLOADAV_TYPE=$loadtype"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}LOADAV_TYPE\${ac_dB}LOADAV_TYPE\${ac_dC}$loadtype\${ac_dD}
-\${ac_uA}LOADAV_TYPE\${ac_uB}LOADAV_TYPE\${ac_uC}$loadtype\${ac_uD}
-\${ac_eA}LOADAV_TYPE\${ac_eB}LOADAV_TYPE\${ac_eC}$loadtype\${ac_eD}
-"
-}
+if test -n "$loadtype" ; then cat >> confdefs.h <<EOF
+#define LOADAV_TYPE $loadtype
+EOF
fi
-if test -n "$loadnum" ; then
-{
-test -n "$verbose" && \
-echo " defining" LOADAV_NUM to be "$loadnum"
-echo "#define" LOADAV_NUM "$loadnum" >> confdefs.h
-DEFS="$DEFS -DLOADAV_NUM=$loadnum"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}LOADAV_NUM\${ac_dB}LOADAV_NUM\${ac_dC}$loadnum\${ac_dD}
-\${ac_uA}LOADAV_NUM\${ac_uB}LOADAV_NUM\${ac_uC}$loadnum\${ac_uD}
-\${ac_eA}LOADAV_NUM\${ac_eB}LOADAV_NUM\${ac_eC}$loadnum\${ac_eD}
-"
-}
+if test -n "$loadnum" ; then cat >> confdefs.h <<EOF
+#define LOADAV_NUM $loadnum
+EOF
fi
-if test -n "$loadscale" ; then
-{
-test -n "$verbose" && \
-echo " defining" LOADAV_SCALE to be "$loadscale"
-echo "#define" LOADAV_SCALE "$loadscale" >> confdefs.h
-DEFS="$DEFS -DLOADAV_SCALE=$loadscale"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}LOADAV_SCALE\${ac_dB}LOADAV_SCALE\${ac_dC}$loadscale\${ac_dD}
-\${ac_uA}LOADAV_SCALE\${ac_uB}LOADAV_SCALE\${ac_uC}$loadscale\${ac_uD}
-\${ac_eA}LOADAV_SCALE\${ac_eB}LOADAV_SCALE\${ac_eC}$loadscale\${ac_eD}
-"
-}
+if test -n "$loadscale" ; then cat >> confdefs.h <<EOF
+#define LOADAV_SCALE $loadscale
+EOF
fi
-
if test -n "$posix" ; then
-test -n "$silent" || echo "assuming posix signal definition"
+echo "assuming posix signal definition" 1>&6
-{
-test -n "$verbose" && \
-echo " defining SIGVOID"
-echo "#define" SIGVOID "1" >> confdefs.h
-DEFS="$DEFS -DSIGVOID=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}SIGVOID\${ac_dB}SIGVOID\${ac_dC}1\${ac_dD}
-\${ac_uA}SIGVOID\${ac_uB}SIGVOID\${ac_uC}1\${ac_uD}
-\${ac_eA}SIGVOID\${ac_eB}SIGVOID\${ac_eC}1\${ac_eD}
-"
-}
+cat >> confdefs.h <<\EOF
+#define SIGVOID 1
+EOF
else
-test -n "$silent" || echo "checking for return type of signal handlers"
-cat > conftest.${ac_ext} <<EOF
+echo "checking return type of signal handlers" 1>&6
+echo "configure:2776: checking return type of signal handlers" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2778 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <signal.h>
@@ -2210,63 +2782,58 @@ cat > conftest.${ac_ext} <<EOF
#undef signal
#endif
extern void (*signal ()) ();
-int main() { return 0; }
-int t() { int i;; return 0; }
+int main() {
+int i;
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:2790: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining SIGVOID"
-echo "#define" SIGVOID "1" >> confdefs.h
-DEFS="$DEFS -DSIGVOID=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}SIGVOID\${ac_dB}SIGVOID\${ac_dC}1\${ac_dD}
-\${ac_uA}SIGVOID\${ac_uB}SIGVOID\${ac_uC}1\${ac_uD}
-\${ac_eA}SIGVOID\${ac_eB}SIGVOID\${ac_eC}1\${ac_eD}
-"
-}
-
+ cat >> confdefs.h <<\EOF
+#define SIGVOID 1
+EOF
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -f conftest*
-
-test -n "$silent" || echo "checking for sigset"
-cat > conftest.${ac_ext} <<EOF
+echo "checking sigset" 1>&6
+echo "configure:2802: checking sigset" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2804 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <signal.h>
-int main() { return 0; }
-int t() {
+int main() {
+
#ifdef SIGVOID
sigset(0, (void (*)())0);
#else
sigset(0, (int (*)())0);
#endif
+
; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:2820: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining USESIGSET"
-echo "#define" USESIGSET "1" >> confdefs.h
-DEFS="$DEFS -DUSESIGSET=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}USESIGSET\${ac_dB}USESIGSET\${ac_dC}1\${ac_dD}
-\${ac_uA}USESIGSET\${ac_uB}USESIGSET\${ac_uC}1\${ac_uD}
-\${ac_eA}USESIGSET\${ac_eB}USESIGSET\${ac_eC}1\${ac_eD}
-"
-}
-
+ cat >> confdefs.h <<\EOF
+#define USESIGSET 1
+EOF
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -f conftest*
-
-test -n "$silent" || echo "checking signal implementation"
-cat > conftest.${ac_ext} <<EOF
+echo "checking signal implementation" 1>&6
+echo "configure:2832: checking signal implementation" >&5
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2837 "configure"
#include "confdefs.h"
#include <sys/types.h>
@@ -2303,136 +2870,207 @@ main()
}
EOF
-eval $ac_compile
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
+if { (eval echo configure:2874: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
:
else
-
-{
-test -n "$verbose" && \
-echo " defining SYSVSIGS"
-echo "#define" SYSVSIGS "1" >> confdefs.h
-DEFS="$DEFS -DSYSVSIGS=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}SYSVSIGS\${ac_dB}SYSVSIGS\${ac_dC}1\${ac_dD}
-\${ac_uA}SYSVSIGS\${ac_uB}SYSVSIGS\${ac_uC}1\${ac_uD}
-\${ac_eA}SYSVSIGS\${ac_eB}SYSVSIGS\${ac_eC}1\${ac_eD}
-"
-}
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ cat >> confdefs.h <<\EOF
+#define SYSVSIGS 1
+EOF
fi
rm -fr conftest*
+fi
+
fi
-test -n "$silent" || echo "checking for crypt and sec libraries"
+echo "checking for crypt and sec libraries" 1>&6
+echo "configure:2894: checking for crypt and sec libraries" >&5
test -f /lib/libcrypt_d.a || test -f /usr/lib/libcrypt_d.a && LIBS="$LIBS -lcrypt_d"
-test -f /lib/libcrypt.a || test -f /usr/lib/libcrypt.a && LIBS="$LIBS -lcrypt"
+oldlibs="$LIBS"
+LIBS="$LIBS -lcrypt"
+echo "checking crypt" 1>&6
+echo "configure:2899: checking crypt" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2901 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:2908: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ LIBS="$oldlibs"
+fi
+rm -f conftest*
test -f /lib/libsec.a || test -f /usr/lib/libsec.a && LIBS="$LIBS -lsec"
test -f /lib/libshadow.a || test -f /usr/lib/libshadow.a && LIBS="$LIBS -lshadow"
-
oldlibs="$LIBS"
LIBS="$LIBS -lsun"
-test -n "$silent" || echo "checking for IRIX sun library"
-cat > conftest.${ac_ext} <<EOF
+echo "checking IRIX sun library" 1>&6
+echo "configure:2922: checking IRIX sun library" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2924 "configure"
#include "confdefs.h"
-int main() { return 0; }
-int t() { ; return 0; }
+int main() {
+
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:2931: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
:
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
LIBS="$oldlibs"
fi
rm -f conftest*
+echo "checking syslog" 1>&6
+echo "configure:2942: checking syslog" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2944 "configure"
+#include "confdefs.h"
+
+int main() {
+closelog();
+; return 0; }
+EOF
+if { (eval echo configure:2951: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ oldlibs="$LIBS"
+LIBS="$LIBS -lbsd"
+echo "checking syslog in libbsd.a" 1>&6
+echo "configure:2960: checking syslog in libbsd.a" >&5
+cat > conftest.$ac_ext <<EOF
+#line 2962 "configure"
+#include "confdefs.h"
+int main() {
+closelog();
+; return 0; }
+EOF
+if { (eval echo configure:2969: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ rm -rf conftest*
+ echo "- found." 1>&6
-test -n "$silent" || echo "checking for wait union"
-cat > conftest.${ac_ext} <<EOF
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ LIBS="oldlibs"
+echo "- bad news: syslog missing." 1>&6
+ cat >> confdefs.h <<\EOF
+#define NOSYSLOG 1
+EOF
+
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+
+cat > conftest.$ac_ext <<EOF
+#line 2989 "configure"
+#include "confdefs.h"
+#ifdef M_UNIX
+ yes;
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
+ rm -rf conftest*
+ LIBS="$LIBS -lsocket -lcrypt_i"
+fi
+rm -f conftest*
+
+
+echo "checking wait union" 1>&6
+echo "configure:3005: checking wait union" >&5
+cat > conftest.$ac_ext <<EOF
+#line 3007 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/wait.h>
-int main() { return 0; }
-int t() {
+int main() {
+
union wait x;
int y;
#ifdef WEXITSTATUS
y = WEXITSTATUS(x);
#endif
+
; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:3022: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining BSDWAIT"
-echo "#define" BSDWAIT "1" >> confdefs.h
-DEFS="$DEFS -DBSDWAIT=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}BSDWAIT\${ac_dB}BSDWAIT\${ac_dC}1\${ac_dD}
-\${ac_uA}BSDWAIT\${ac_uB}BSDWAIT\${ac_uC}1\${ac_uD}
-\${ac_eA}BSDWAIT\${ac_eB}BSDWAIT\${ac_eC}1\${ac_eD}
-"
-}
-
+ cat >> confdefs.h <<\EOF
+#define BSDWAIT 1
+EOF
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -f conftest*
-
if test -z "$butterfly"; then
-test -n "$silent" || echo "checking for termio or termios"
-cat > conftest.${ac_ext} <<EOF
+echo "checking for termio or termios" 1>&6
+echo "configure:3036: checking for termio or termios" >&5
+cat > conftest.$ac_ext <<EOF
+#line 3038 "configure"
#include "confdefs.h"
#include <termio.h>
EOF
-# Some shells (Coherent) do redirections in the wrong order, so need
-# the parens.
-ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"`
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3043: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining TERMIO"
-echo "#define" TERMIO "1" >> confdefs.h
-DEFS="$DEFS -DTERMIO=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}TERMIO\${ac_dB}TERMIO\${ac_dC}1\${ac_dD}
-\${ac_uA}TERMIO\${ac_uB}TERMIO\${ac_uC}1\${ac_uD}
-\${ac_eA}TERMIO\${ac_eB}TERMIO\${ac_eC}1\${ac_eD}
-"
-}
-
+ cat >> confdefs.h <<\EOF
+#define TERMIO 1
+EOF
else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
if test -n "$posix"; then
-cat > conftest.${ac_ext} <<EOF
+cat > conftest.$ac_ext <<EOF
+#line 3058 "configure"
#include "confdefs.h"
#include <termios.h>
EOF
-# Some shells (Coherent) do redirections in the wrong order, so need
-# the parens.
-ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"`
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:3063: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining TERMIO"
-echo "#define" TERMIO "1" >> confdefs.h
-DEFS="$DEFS -DTERMIO=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}TERMIO\${ac_dB}TERMIO\${ac_dC}1\${ac_dD}
-\${ac_uA}TERMIO\${ac_uB}TERMIO\${ac_uC}1\${ac_uD}
-\${ac_eA}TERMIO\${ac_eB}TERMIO\${ac_eC}1\${ac_eD}
-"
-}
-
+ cat >> confdefs.h <<\EOF
+#define TERMIO 1
+EOF
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -f conftest*
fi
@@ -2441,60 +3079,57 @@ fi
rm -f conftest*
fi
-test -n "$silent" || echo "checking for getspnam"
-cat > conftest.${ac_ext} <<EOF
+echo "checking getspnam" 1>&6
+echo "configure:3084: checking getspnam" >&5
+cat > conftest.$ac_ext <<EOF
+#line 3086 "configure"
#include "confdefs.h"
#include <shadow.h>
-int main() { return 0; }
-int t() { getspnam("x");; return 0; }
+int main() {
+getspnam("x");
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:3093: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining SHADOWPW"
-echo "#define" SHADOWPW "1" >> confdefs.h
-DEFS="$DEFS -DSHADOWPW=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}SHADOWPW\${ac_dB}SHADOWPW\${ac_dC}1\${ac_dD}
-\${ac_uA}SHADOWPW\${ac_uB}SHADOWPW\${ac_uC}1\${ac_uD}
-\${ac_eA}SHADOWPW\${ac_eB}SHADOWPW\${ac_eC}1\${ac_eD}
-"
-}
-
+ cat >> confdefs.h <<\EOF
+#define SHADOWPW 1
+EOF
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -f conftest*
-
-test -n "$silent" || echo "checking for getttyent"
-cat > conftest.${ac_ext} <<EOF
+echo "checking getttyent" 1>&6
+echo "configure:3106: checking getttyent" >&5
+cat > conftest.$ac_ext <<EOF
+#line 3108 "configure"
#include "confdefs.h"
-int main() { return 0; }
-int t() { getttyent();; return 0; }
+int main() {
+getttyent();
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:3115: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining GETTTYENT"
-echo "#define" GETTTYENT "1" >> confdefs.h
-DEFS="$DEFS -DGETTTYENT=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}GETTTYENT\${ac_dB}GETTTYENT\${ac_dC}1\${ac_dD}
-\${ac_uA}GETTTYENT\${ac_uB}GETTTYENT\${ac_uC}1\${ac_uD}
-\${ac_eA}GETTTYENT\${ac_eB}GETTTYENT\${ac_eC}1\${ac_eD}
-"
-}
-
+ cat >> confdefs.h <<\EOF
+#define GETTTYENT 1
+EOF
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -f conftest*
-
-test -n "$silent" || echo "checking whether memcpy/memmove/bcopy handles overlapping arguments"
-cat > conftest.${ac_ext} <<EOF
+echo "checking whether memcpy/memmove/bcopy handles overlapping arguments" 1>&6
+echo "configure:3128: checking whether memcpy/memmove/bcopy handles overlapping arguments" >&5
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3133 "configure"
#include "confdefs.h"
main() {
@@ -2510,25 +3145,25 @@ main() {
exit(0); /* libc version works properly. */
}
EOF
-eval $ac_compile
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-
-{
-test -n "$verbose" && \
-echo " defining USEBCOPY"
-echo "#define" USEBCOPY "1" >> confdefs.h
-DEFS="$DEFS -DUSEBCOPY=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}USEBCOPY\${ac_dB}USEBCOPY\${ac_dC}1\${ac_dD}
-\${ac_uA}USEBCOPY\${ac_uB}USEBCOPY\${ac_uC}1\${ac_uD}
-\${ac_eA}USEBCOPY\${ac_eB}USEBCOPY\${ac_eC}1\${ac_eD}
-"
-}
-
+if { (eval echo configure:3149: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ cat >> confdefs.h <<\EOF
+#define USEBCOPY 1
+EOF
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -fr conftest*
+fi
-cat > conftest.${ac_ext} <<EOF
+
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3167 "configure"
#include "confdefs.h"
#define bcopy(s,d,l) memmove(d,s,l)
@@ -2545,26 +3180,26 @@ main() {
exit(0); /* libc version works properly. */
}
EOF
-eval $ac_compile
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-
-{
-test -n "$verbose" && \
-echo " defining USEMEMMOVE"
-echo "#define" USEMEMMOVE "1" >> confdefs.h
-DEFS="$DEFS -DUSEMEMMOVE=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}USEMEMMOVE\${ac_dB}USEMEMMOVE\${ac_dC}1\${ac_dD}
-\${ac_uA}USEMEMMOVE\${ac_uB}USEMEMMOVE\${ac_uC}1\${ac_uD}
-\${ac_eA}USEMEMMOVE\${ac_eB}USEMEMMOVE\${ac_eC}1\${ac_eD}
-"
-}
-
+if { (eval echo configure:3184: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ cat >> confdefs.h <<\EOF
+#define USEMEMMOVE 1
+EOF
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -fr conftest*
+fi
-cat > conftest.${ac_ext} <<EOF
+
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3203 "configure"
#include "confdefs.h"
#define bcopy(s,d,l) memcpy(d,s,l)
@@ -2581,481 +3216,372 @@ main() {
exit(0); /* libc version works properly. */
}
EOF
-eval $ac_compile
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-
-{
-test -n "$verbose" && \
-echo " defining USEMEMCPY"
-echo "#define" USEMEMCPY "1" >> confdefs.h
-DEFS="$DEFS -DUSEMEMCPY=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}USEMEMCPY\${ac_dB}USEMEMCPY\${ac_dC}1\${ac_dD}
-\${ac_uA}USEMEMCPY\${ac_uB}USEMEMCPY\${ac_uC}1\${ac_uD}
-\${ac_eA}USEMEMCPY\${ac_eB}USEMEMCPY\${ac_eC}1\${ac_eD}
-"
-}
-
+if { (eval echo configure:3220: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ cat >> confdefs.h <<\EOF
+#define USEMEMCPY 1
+EOF
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
fi
rm -fr conftest*
+fi
+
-test -n "$silent" || echo "checking for long file names"
+echo $ac_n "checking long file names""... $ac_c" 1>&6
+echo "configure:3235: checking long file names" >&5
(echo 1 > /tmp/conftest9012345) 2>/dev/null
(echo 2 > /tmp/conftest9012346) 2>/dev/null
val=`cat /tmp/conftest9012345 2>/dev/null`
-if test -f /tmp/conftest9012345 && test "$val" = 1; then :
-else
-{
-test -n "$verbose" && \
-echo " defining" NAME_MAX to be "14"
-echo "#define" NAME_MAX "14" >> confdefs.h
-DEFS="$DEFS -DNAME_MAX=14"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}NAME_MAX\${ac_dB}NAME_MAX\${ac_dC}14\${ac_dD}
-\${ac_uA}NAME_MAX\${ac_uB}NAME_MAX\${ac_uC}14\${ac_uD}
-\${ac_eA}NAME_MAX\${ac_eB}NAME_MAX\${ac_eC}14\${ac_eD}
-"
-}
+if test -f /tmp/conftest9012345 && test "$val" = 1; then
+echo "$ac_t""yes" 1>&6
+else
+echo "$ac_t""no" 1>&6
+cat >> confdefs.h <<\EOF
+#define NAME_MAX 14
+EOF
fi
rm -f /tmp/conftest*
-test -n "$silent" || echo "checking for vsprintf"
-cat > conftest.${ac_ext} <<EOF
+echo $ac_n "checking for vsprintf""... $ac_c" 1>&6
+echo "configure:3251: checking for vsprintf" >&5
+cat > conftest.$ac_ext <<EOF
+#line 3253 "configure"
#include "confdefs.h"
-#include <stdio.h>
-int main() { return 0; }
-int t() { vsprintf(0,0,0);; return 0; }
+int main() {
+vsprintf(0,0,0);
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:3260: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining USEVARARGS"
-echo "#define" USEVARARGS "1" >> confdefs.h
-DEFS="$DEFS -DUSEVARARGS=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}USEVARARGS\${ac_dB}USEVARARGS\${ac_dC}1\${ac_dD}
-\${ac_uA}USEVARARGS\${ac_uB}USEVARARGS\${ac_uC}1\${ac_uD}
-\${ac_eA}USEVARARGS\${ac_eB}USEVARARGS\${ac_eC}1\${ac_eD}
-"
-}
-
+ echo "$ac_t""yes" 1>&6;cat >> confdefs.h <<\EOF
+#define USEVARARGS 1
+EOF
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ echo "$ac_t""no" 1>&6
fi
rm -f conftest*
-
-test -n "$silent" || echo "checking for directory library header"
-ac_dir_header=
-if test -z "$ac_dir_header"; then
- test -n "$silent" || echo "checking for dirent.h"
-cat > conftest.${ac_ext} <<EOF
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
+echo "configure:3279: checking for $ac_hdr that defines DIR" >&5
+if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3284 "configure"
#include "confdefs.h"
#include <sys/types.h>
-#include <dirent.h>
-int main() { return 0; }
-int t() { DIR *dirp = 0;; return 0; }
+#include <$ac_hdr>
+int main() {
+DIR *dirp = 0;
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:3292: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining DIRENT"
-echo "#define" DIRENT "1" >> confdefs.h
-DEFS="$DEFS -DDIRENT=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}DIRENT\${ac_dB}DIRENT\${ac_dC}1\${ac_dD}
-\${ac_uA}DIRENT\${ac_uB}DIRENT\${ac_uC}1\${ac_uD}
-\${ac_eA}DIRENT\${ac_eB}DIRENT\${ac_eC}1\${ac_eD}
-"
-}
- ac_dir_header=dirent.h
-
-fi
-rm -f conftest*
-fi
-if test -z "$ac_dir_header"; then
- test -n "$silent" || echo "checking for sys/ndir.h"
-cat > conftest.${ac_ext} <<EOF
-#include "confdefs.h"
-#include <sys/types.h>
-#include <sys/ndir.h>
-int main() { return 0; }
-int t() { DIR *dirp = 0;; return 0; }
-EOF
-if eval $ac_compile; then
+ eval "ac_cv_header_dirent_$ac_safe=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining SYSNDIR"
-echo "#define" SYSNDIR "1" >> confdefs.h
-DEFS="$DEFS -DSYSNDIR=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}SYSNDIR\${ac_dB}SYSNDIR\${ac_dC}1\${ac_dD}
-\${ac_uA}SYSNDIR\${ac_uB}SYSNDIR\${ac_uC}1\${ac_uD}
-\${ac_eA}SYSNDIR\${ac_eB}SYSNDIR\${ac_eC}1\${ac_eD}
-"
-}
- ac_dir_header=sys/ndir.h
-
+ eval "ac_cv_header_dirent_$ac_safe=no"
fi
rm -f conftest*
fi
-if test -z "$ac_dir_header"; then
- test -n "$silent" || echo "checking for sys/dir.h"
-cat > conftest.${ac_ext} <<EOF
-#include "confdefs.h"
-#include <sys/types.h>
-#include <sys/dir.h>
-int main() { return 0; }
-int t() { DIR *dirp = 0;; return 0; }
+if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
EOF
-if eval $ac_compile; then
- rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining SYSDIR"
-echo "#define" SYSDIR "1" >> confdefs.h
-DEFS="$DEFS -DSYSDIR=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}SYSDIR\${ac_dB}SYSDIR\${ac_dC}1\${ac_dD}
-\${ac_uA}SYSDIR\${ac_uB}SYSDIR\${ac_uC}1\${ac_uD}
-\${ac_eA}SYSDIR\${ac_eB}SYSDIR\${ac_eC}1\${ac_eD}
-"
-}
- ac_dir_header=sys/dir.h
-
-fi
-rm -f conftest*
+ ac_header_dirent=$ac_hdr; break
+else
+ echo "$ac_t""no" 1>&6
fi
-if test -z "$ac_dir_header"; then
- test -n "$silent" || echo "checking for ndir.h"
-cat > conftest.${ac_ext} <<EOF
-#include "confdefs.h"
-#include <sys/types.h>
-#include <ndir.h>
-int main() { return 0; }
-int t() { DIR *dirp = 0;; return 0; }
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
+echo "configure:3317: checking for opendir in -ldir" >&5
+ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldir $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3325 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:3336: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining NDIR"
-echo "#define" NDIR "1" >> confdefs.h
-DEFS="$DEFS -DNDIR=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}NDIR\${ac_dB}NDIR\${ac_dC}1\${ac_dD}
-\${ac_uA}NDIR\${ac_uB}NDIR\${ac_uC}1\${ac_uD}
-\${ac_eA}NDIR\${ac_eB}NDIR\${ac_eC}1\${ac_eD}
-"
-}
- ac_dir_header=ndir.h
-
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
-fi
+LIBS="$ac_save_LIBS"
-test -n "$silent" || echo "checking for closedir return value"
-cat > conftest.${ac_ext} <<EOF
-#include "confdefs.h"
-#include <sys/types.h>
-#include <$ac_dir_header>
-int closedir(); main() { exit(closedir(opendir(".")) != 0); }
-EOF
-eval $ac_compile
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
- :
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -ldir"
else
-
-{
-test -n "$verbose" && \
-echo " defining VOID_CLOSEDIR"
-echo "#define" VOID_CLOSEDIR "1" >> confdefs.h
-DEFS="$DEFS -DVOID_CLOSEDIR=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}VOID_CLOSEDIR\${ac_dB}VOID_CLOSEDIR\${ac_dC}1\${ac_dD}
-\${ac_uA}VOID_CLOSEDIR\${ac_uB}VOID_CLOSEDIR\${ac_uC}1\${ac_uD}
-\${ac_eA}VOID_CLOSEDIR\${ac_eB}VOID_CLOSEDIR\${ac_eC}1\${ac_eD}
-"
-}
-
+ echo "$ac_t""no" 1>&6
fi
-rm -fr conftest*
-
-test -n "$silent" || echo "checking for Xenix"
-cat > conftest.${ac_ext} <<EOF
-#include "confdefs.h"
-#if defined(M_XENIX) && !defined(M_UNIX)
- yes
-#endif
+else
+echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
+echo "configure:3358: checking for opendir in -lx" >&5
+ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lx $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3366 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
EOF
-eval "$ac_cpp conftest.${ac_ext} > conftest.out 2>&1"
-if egrep "yes" conftest.out >/dev/null 2>&1; then
+if { (eval echo configure:3377: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
- XENIX=1
-
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
+LIBS="$ac_save_LIBS"
-if test -n "$XENIX"; then
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
LIBS="$LIBS -lx"
- case "$DEFS" in
- *SYSNDIR*) ;;
- *) LIBS="-ldir $LIBS" ;; # Make sure -ldir precedes any -lx.
- esac
+else
+ echo "$ac_t""no" 1>&6
fi
+fi
-test -n "$silent" || echo "checking for setenv"
-cat > conftest.${ac_ext} <<EOF
+
+echo $ac_n "checking for setenv""... $ac_c" 1>&6
+echo "configure:3401: checking for setenv" >&5
+cat > conftest.$ac_ext <<EOF
+#line 3403 "configure"
#include "confdefs.h"
-int main() { return 0; }
-int t() { setenv((char *)0,(char *)0);unsetenv((char *)0);; return 0; }
+int main() {
+setenv((char *)0,(char *)0);unsetenv((char *)0);
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:3410: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining USESETENV"
-echo "#define" USESETENV "1" >> confdefs.h
-DEFS="$DEFS -DUSESETENV=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}USESETENV\${ac_dB}USESETENV\${ac_dC}1\${ac_dD}
-\${ac_uA}USESETENV\${ac_uB}USESETENV\${ac_uC}1\${ac_uD}
-\${ac_eA}USESETENV\${ac_eB}USESETENV\${ac_eC}1\${ac_eD}
-"
-}
-
+ echo "$ac_t""yes" 1>&6;cat >> confdefs.h <<\EOF
+#define USESETENV 1
+EOF
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
- test -n "$silent" || echo "checking for putenv"
-cat > conftest.${ac_ext} <<EOF
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for putenv""... $ac_c" 1>&6
+echo "configure:3422: checking for putenv" >&5
+cat > conftest.$ac_ext <<EOF
+#line 3424 "configure"
#include "confdefs.h"
-int main() { return 0; }
-int t() { putenv((char *)0);unsetenv((char *)0);; return 0; }
+int main() {
+putenv((char *)0);unsetenv((char *)0);
+; return 0; }
EOF
-if eval $ac_compile; then
- :
-else
+if { (eval echo configure:3431: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining NEEDPUTENV"
-echo "#define" NEEDPUTENV "1" >> confdefs.h
-DEFS="$DEFS -DNEEDPUTENV=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}NEEDPUTENV\${ac_dB}NEEDPUTENV\${ac_dC}1\${ac_dD}
-\${ac_uA}NEEDPUTENV\${ac_uB}NEEDPUTENV\${ac_uC}1\${ac_uD}
-\${ac_eA}NEEDPUTENV\${ac_eB}NEEDPUTENV\${ac_eC}1\${ac_eD}
-"
-}
-
-
-fi
-rm -f conftest*
-
-fi
-rm -f conftest*
-
-
-test -n "$silent" || echo "checking for rename"
-cat > conftest.${ac_ext} <<EOF
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() { rename(0,0);; return 0; }
-EOF
-if eval $ac_compile; then
- :
+ echo "$ac_t""yes" 1>&6
else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining NEED_RENAME"
-echo "#define" NEED_RENAME "1" >> confdefs.h
-DEFS="$DEFS -DNEED_RENAME=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}NEED_RENAME\${ac_dB}NEED_RENAME\${ac_dC}1\${ac_dD}
-\${ac_uA}NEED_RENAME\${ac_uB}NEED_RENAME\${ac_uC}1\${ac_uD}
-\${ac_eA}NEED_RENAME\${ac_eB}NEED_RENAME\${ac_eC}1\${ac_eD}
-"
-}
-
-fi
-rm -f conftest*
-
-test -n "$silent" || echo "checking for _exit"
-cat > conftest.${ac_ext} <<EOF
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() { _exit(0);; return 0; }
+ echo "$ac_t""no" 1>&6;cat >> confdefs.h <<\EOF
+#define NEEDPUTENV 1
EOF
-if eval $ac_compile; then
- rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining HAVE__EXIT"
-echo "#define" HAVE__EXIT "1" >> confdefs.h
-DEFS="$DEFS -DHAVE__EXIT=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE__EXIT\${ac_dB}HAVE__EXIT\${ac_dC}1\${ac_dD}
-\${ac_uA}HAVE__EXIT\${ac_uB}HAVE__EXIT\${ac_uC}1\${ac_uD}
-\${ac_eA}HAVE__EXIT\${ac_eB}HAVE__EXIT\${ac_eC}1\${ac_eD}
-"
-}
fi
rm -f conftest*
-
-test -n "$silent" || echo "checking for lstat"
-cat > conftest.${ac_ext} <<EOF
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() { lstat(0,0);; return 0; }
-EOF
-if eval $ac_compile; then
- rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining HAVE_LSTAT"
-echo "#define" HAVE_LSTAT "1" >> confdefs.h
-DEFS="$DEFS -DHAVE_LSTAT=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE_LSTAT\${ac_dB}HAVE_LSTAT\${ac_dC}1\${ac_dD}
-\${ac_uA}HAVE_LSTAT\${ac_uB}HAVE_LSTAT\${ac_uC}1\${ac_uD}
-\${ac_eA}HAVE_LSTAT\${ac_eB}HAVE_LSTAT\${ac_eC}1\${ac_eD}
-"
-}
-
-
fi
rm -f conftest*
-test -n "$silent" || echo "checking for strerror"
-cat > conftest.${ac_ext} <<EOF
-#include "confdefs.h"
+for ac_func in rename fchmod fchown strerror lstat _exit utimes vsnprintf getcwd
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3451: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3456 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
-int main() { return 0; }
-int t() { strerror(0);; return 0; }
+; return 0; }
EOF
-if eval $ac_compile; then
+if { (eval echo configure:3479: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining HAVE_STRERROR"
-echo "#define" HAVE_STRERROR "1" >> confdefs.h
-DEFS="$DEFS -DHAVE_STRERROR=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE_STRERROR\${ac_dB}HAVE_STRERROR\${ac_dC}1\${ac_dD}
-\${ac_uA}HAVE_STRERROR\${ac_uB}HAVE_STRERROR\${ac_uC}1\${ac_uD}
-\${ac_eA}HAVE_STRERROR\${ac_eB}HAVE_STRERROR\${ac_eC}1\${ac_eD}
-"
-}
-
-
-fi
-rm -f conftest*
-
-test -n "$silent" || echo "checking for utimes"
-cat > conftest.${ac_ext} <<EOF
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() { utimes(0,0);; return 0; }
-EOF
-if eval $ac_compile; then
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining HAVE_UTIMES"
-echo "#define" HAVE_UTIMES "1" >> confdefs.h
-DEFS="$DEFS -DHAVE_UTIMES=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE_UTIMES\${ac_dB}HAVE_UTIMES\${ac_dC}1\${ac_dD}
-\${ac_uA}HAVE_UTIMES\${ac_uB}HAVE_UTIMES\${ac_uC}1\${ac_uD}
-\${ac_eA}HAVE_UTIMES\${ac_eB}HAVE_UTIMES\${ac_eC}1\${ac_eD}
-"
-}
-
-
+ eval "ac_cv_func_$ac_func=no"
fi
rm -f conftest*
+fi
-test -n "$silent" || echo "checking for vsnprintf"
-cat > conftest.${ac_ext} <<EOF
-#include "confdefs.h"
-
-int main() { return 0; }
-int t() { vsnprintf(0,0,0);; return 0; }
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
EOF
-if eval $ac_compile; then
- rm -rf conftest*
-
-{
-test -n "$verbose" && \
-echo " defining HAVE_VSNPRINTF"
-echo "#define" HAVE_VSNPRINTF "1" >> confdefs.h
-DEFS="$DEFS -DHAVE_VSNPRINTF=1"
-ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE_VSNPRINTF\${ac_dB}HAVE_VSNPRINTF\${ac_dC}1\${ac_dD}
-\${ac_uA}HAVE_VSNPRINTF\${ac_uB}HAVE_VSNPRINTF\${ac_uC}1\${ac_uD}
-\${ac_eA}HAVE_VSNPRINTF\${ac_eB}HAVE_VSNPRINTF\${ac_eC}1\${ac_eD}
-"
-}
-
-
+
+else
+ echo "$ac_t""no" 1>&6
fi
-rm -f conftest*
+done
-test -n "$seqptx" && LIBS="-ltermcap -lc -lsocket -linet -lsec -lseq"
+test -n "$seqptx" && LIBS="-ltermcap -lc -lsocket -linet -lnsl -lsec -lseq"
-cat > conftest.${ac_ext} <<EOF
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3510 "configure"
#include "confdefs.h"
main(){exit(0);}
EOF
-eval $ac_compile
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
+if { (eval echo configure:3514: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
:
else
- echo "configure: Can't run the compiler - internal error. Sorry." >&2; exit 1
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ { echo "configure: error: Can't run the compiler - internal error. Sorry." 1>&2; exit 1; }
fi
rm -fr conftest*
-if test -n "$prefix"; then
-
-{
-test -n "$verbose" && \
-echo " defining" ETCSCREENRC to be "\"$prefix/etc/screenrc\""
-echo "#define" ETCSCREENRC "\"$prefix/etc/screenrc\"" >> confdefs.h
-DEFS="$DEFS -DETCSCREENRC=\"$prefix/etc/screenrc\""
-ac_sed_defs="${ac_sed_defs}\${ac_dA}ETCSCREENRC\${ac_dB}ETCSCREENRC\${ac_dC}\"$prefix/etc/screenrc\"\${ac_dD}
-\${ac_uA}ETCSCREENRC\${ac_uB}ETCSCREENRC\${ac_uC}\"$prefix/etc/screenrc\"\${ac_uD}
-\${ac_eA}ETCSCREENRC\${ac_eB}ETCSCREENRC\${ac_eC}\"$prefix/etc/screenrc\"\${ac_eD}
-"
-}
-
fi
-
-# The preferred way to propogate these variables is regular @ substitutions.
if test -n "$prefix"; then
- ac_prsub="s%^prefix\\([ ]*\\)=\\([ ]*\\).*$%prefix\\1=\\2$prefix%"
-else
- prefix=/usr/local
+cat >> confdefs.h <<EOF
+#define ETCSCREENRC "$prefix/etc/screenrc"
+EOF
+
fi
-if test -n "$exec_prefix"; then
- ac_prsub="$ac_prsub
-s%^exec_prefix\\([ ]*\\)=\\([ ]*\\).*$%exec_prefix\\1=\\2$exec_prefix%"
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
else
- exec_prefix='${prefix}' # Let make expand it.
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
# Any assignment to VPATH causes Sun make to only execute
# the first set of double-colon rules, so remove it if not needed.
@@ -3064,36 +3590,36 @@ if test "x$srcdir" = x.; then
ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
fi
-# Quote sed substitution magic chars in DEFS.
-cat >conftest.def <<EOF
-$DEFS
-EOF
-ac_escape_ampersand_and_backslash='s%[&\\]%\\&%g'
-DEFS=`sed "$ac_escape_ampersand_and_backslash" <conftest.def`
-rm -f conftest.def
-# Substitute for predefined variables.
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
-trap 'rm -f config.status; exit 1' 1 2 15
-echo creating config.status
-rm -f config.status
-cat > config.status <<EOF
-#!/bin/sh
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
# Generated automatically by configure.
# Run this file to recreate the current configuration.
# This directory was configured as follows,
# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
#
-# $0 $configure_args
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
-ac_cs_usage="Usage: config.status [--recheck] [--version] [--help]"
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
for ac_option
do
case "\$ac_option" in
-recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
- echo running \${CONFIG_SHELL-/bin/sh} $0 $configure_args --no-create
- exec \${CONFIG_SHELL-/bin/sh} $0 $configure_args --no-create ;;
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
-version | --version | --versio | --versi | --vers | --ver | --ve | --v)
- echo "config.status generated by autoconf version 1.11"
+ echo "$CONFIG_STATUS generated by autoconf version 2.12"
exit 0 ;;
-help | --help | --hel | --he | --h)
echo "\$ac_cs_usage"; exit 0 ;;
@@ -3101,44 +3627,116 @@ do
esac
done
-trap 'rm -fr Makefile doc/Makefile config.h conftest*; exit 1' 1 2 15
-VERSION='$VERSION'
-CC='$CC'
-CPP='$CPP'
-AWK='$AWK'
-INSTALL='$INSTALL'
-INSTALL_PROGRAM='$INSTALL_PROGRAM'
-INSTALL_DATA='$INSTALL_DATA'
-LIBS='$LIBS'
-srcdir='$srcdir'
-top_srcdir='$top_srcdir'
-prefix='$prefix'
-exec_prefix='$exec_prefix'
-ac_prsub='$ac_prsub'
-ac_vpsub='$ac_vpsub'
-extrasub='$extrasub'
-EOF
-cat >> config.status <<\EOF
-
ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile doc/Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@VERSION@%$VERSION%g
+s%@SCREEN@%$SCREEN%g
+s%@GZIP@%$GZIP%g
+s%@CC@%$CC%g
+s%@CPP@%$CPP%g
+s%@AWK@%$AWK%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile doc/Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
-CONFIG_FILES=${CONFIG_FILES-"Makefile doc/Makefile"}
-for ac_file in .. ${CONFIG_FILES}; do if test "x$ac_file" != x..; then
# Remove last slash and all that follows it. Not all systems have dirname.
ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
# The file is in a subdirectory.
test ! -d "$ac_dir" && mkdir "$ac_dir"
- ac_dir_suffix="/$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
else
- ac_dir_suffix=
+ ac_dir_suffix= ac_dots=
fi
- # A "../" for each directory in $ac_dir_suffix.
- ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
case "$ac_given_srcdir" in
.) srcdir=.
- if test -z "$ac_dir_suffix"; then top_srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
/*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
*) # Relative path.
@@ -3146,152 +3744,154 @@ for ac_file in .. ${CONFIG_FILES}; do if test "x$ac_file" != x..; then
top_srcdir="$ac_dots$ac_given_srcdir" ;;
esac
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
echo creating "$ac_file"
rm -f "$ac_file"
- comment_str="Generated automatically from `echo $ac_file|sed 's|.*/||'`.in by configure."
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
case "$ac_file" in
- *.c | *.h | *.C | *.cc | *.m ) echo "/* $comment_str */" > "$ac_file" ;;
- * ) echo "# $comment_str" > "$ac_file" ;;
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
esac
- sed -e "
-$ac_prsub
-$ac_vpsub
-$extrasub
-s%@VERSION@%$VERSION%g
-s%@CC@%$CC%g
-s%@CPP@%$CPP%g
-s%@AWK@%$AWK%g
-s%@INSTALL@%$INSTALL%g
-s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
-s%@INSTALL_DATA@%$INSTALL_DATA%g
-s%@LIBS@%$LIBS%g
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
s%@srcdir@%$srcdir%g
s%@top_srcdir@%$top_srcdir%g
-s%@prefix@%$prefix%g
-s%@exec_prefix@%$exec_prefix%g
-s%@DEFS@%-DHAVE_CONFIG_H%" $ac_given_srcdir/${ac_file}.in >> $ac_file
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
fi; done
+rm -f conftest.s*
-# These sed commands are put into ac_sed_defs when defining a macro.
-# They are broken into pieces to make the sed script easier to manage.
-# They are passed to sed as "A NAME B NAME C VALUE D", where NAME
-# is the cpp macro being defined and VALUE is the value it is being given.
-# Each defining turns into a single global substitution command.
-# Hopefully no one uses "!" as a variable value.
-# Other candidates for the sed separators, like , and @, do get used.
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
#
# ac_d sets the value in "#define NAME VALUE" lines.
-ac_dA='s!^\([ ]*\)#\([ ]*define[ ][ ]*\)'
-ac_dB='\([ ][ ]*\)[^ ]*!\1#\2'
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
ac_dC='\3'
-ac_dD='!g'
+ac_dD='%g'
# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
-ac_uA='s!^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
-ac_uB='\([ ]\)!\1#\2define\3'
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
ac_uC=' '
-ac_uD='\4!g'
+ac_uD='\4%g'
# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
-ac_eA='s!^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
-ac_eB='$!\1#\2define\3'
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
ac_eC=' '
-ac_eD='!g'
-rm -f conftest.sed
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
EOF
-# Turn off quoting long enough to insert the sed commands.
-rm -f conftest.sh
-cat > conftest.sh <<EOF
-$ac_sed_defs
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="config.h"
EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
-# Break up $ac_sed_defs (now in conftest.sh) because some shells have a limit
-# on the size of here documents.
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
-# Maximum number of lines to put in a single here document.
-ac_max_sh_lines=9
+EOF
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
while :
do
- # wc gives bogus results for an empty file on some AIX systems.
- ac_lines=`grep -c . conftest.sh`
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
- rm -f conftest.s1 conftest.s2
- sed ${ac_max_sh_lines}q conftest.sh > conftest.s1 # Like head -9.
- sed 1,${ac_max_sh_lines}d conftest.sh > conftest.s2 # Like tail +10.
- # Write a limited-size here document to append to conftest.sed.
- echo 'cat >> conftest.sed <<CONFEOF' >> config.status
- cat conftest.s1 >> config.status
- echo 'CONFEOF' >> config.status
- rm -f conftest.s1 conftest.sh
- mv conftest.s2 conftest.sh
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
done
-rm -f conftest.sh
-
-# Now back to your regularly scheduled config.status.
-cat >> config.status <<\EOF
-# This sed command replaces #undef's with comments. This is necessary, for
-# example, in the case of _POSIX_SOURCE, which is predefined and required
-# on some systems where configure will not decide to define it in
-# config.h.
-cat >> conftest.sed <<\CONFEOF
-s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
-CONFEOF
-rm -f conftest.h
-# Break up the sed commands because old seds have small limits.
-ac_max_sed_lines=20
-
-CONFIG_HEADERS=${CONFIG_HEADERS-"config.h"}
-for ac_file in .. ${CONFIG_HEADERS}; do if test "x$ac_file" != x..; then
- echo creating $ac_file
+rm -f conftest.vals
- cp $ac_given_srcdir/$ac_file.in conftest.h1
- cp conftest.sed conftest.stm
- while :
- do
- ac_lines=`grep -c . conftest.stm`
- if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
- rm -f conftest.s1 conftest.s2 conftest.h2
- sed ${ac_max_sed_lines}q conftest.stm > conftest.s1 # Like head -20.
- sed 1,${ac_max_sed_lines}d conftest.stm > conftest.s2 # Like tail +21.
- sed -f conftest.s1 < conftest.h1 > conftest.h2
- rm -f conftest.s1 conftest.h1 conftest.stm
- mv conftest.h2 conftest.h1
- mv conftest.s2 conftest.stm
- done
- rm -f conftest.stm conftest.h
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
- cat conftest.h1 >> conftest.h
- rm -f conftest.h1
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
if cmp -s $ac_file conftest.h 2>/dev/null; then
- # The file exists and we would not be changing it.
echo "$ac_file is unchanged"
rm -f conftest.h
else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
rm -f $ac_file
mv conftest.h $ac_file
fi
fi; done
-rm -f conftest.sed
-
-
-exit 0
EOF
-chmod +x config.status
-# Some shells look in PATH for config.status without the "./".
-test -n "$no_create" || ${CONFIG_SHELL-/bin/sh} ./config.status
+cat >> $CONFIG_STATUS <<EOF
+EOF
+cat >> $CONFIG_STATUS <<\EOF
# a hook for preserving undef directive in config.h
-if test -z "$no_create" ; then
-mv config.h conftest
-sed -e 's@^\(.*\)defin.\( .*\) .*/\*\(.*KEEP_UNDEF_HERE\)@\1undef\2 /\*\3@' < conftest > config.h
-rm -f conftest
-fi
-cat >> config.status << EOF
mv config.h conftest
sed -e 's@^\(.*\)defin.\( .*\) .*/\*\(.*KEEP_UNDEF_HERE\)@\1undef\2 /\*\3@' < conftest > config.h
rm -f conftest
+
+exit 0
EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
echo ""
if test -z "$AWK"; then
diff --git a/configure.in b/configure.in
index 92c4c58..f10734d 100644
--- a/configure.in
+++ b/configure.in
@@ -1,30 +1,31 @@
dnl Process this file with autoconf to produce a configure script.
dnl
-dnl $Id: configure.in,v 1.17 1994/05/31 12:31:46 mlschroe Exp $ FAU
+dnl $Id: configure.in,v 1.18 1994/09/06 16:59:54 mlschroe Exp $ FAU
dnl
dnl Many thanks to David MacKenzie for writing autoconf and
dnl providing a sample configure.in file for screen.
dnl
-AC_REVISION($Revision: 1.17 $)dnl
+AC_REVISION($Revision: 1.18 $)dnl
AC_INIT(screen.c)
AC_CONFIG_HEADER(config.h)
dnl
dnl Define some useful macros
dnl
-define(AC_PROGRAM_SOURCE,
+AC_DEFUN(AC_PROGRAM_SOURCE,
[AC_REQUIRE([AC_PROG_CPP])AC_PROVIDE([$0])cat > conftest.c <<EOF
[$1]
_CUT_HERE_
[$2]
EOF
-$CPP $DEFS conftest.c 2>/dev/null | sed -e '1,/_CUT_HERE_/d' > conftest.out
+eval "$ac_cpp conftest.c 2>&5 | sed -e '1,/_CUT_HERE_/d' > conftest.out"
. ./conftest.out
rm -f conftest*
])dnl
dnl
define(AC_NOTE,
-[test -n "$silent" || echo "$1"])dnl
+[echo "$1" 1>&AC_FD_MSG
+])dnl
dnl
dnl Extract version from patchlevel.h
@@ -35,22 +36,38 @@ pat=`sed < ${srcdir}/patchlevel.h -n -e '/#define PATCHLEVEL/s/#define PATCHLEVE
VERSION="$rev.$vers.$pat"
AC_NOTE(this is screen version $VERSION)
AC_SUBST(VERSION)
-AC_PREFIX(gzip)
+AC_PREFIX_PROGRAM(screen)
+AC_PREFIX_PROGRAM(gzip)
AC_PROG_CC
AC_PROG_CPP
-AC_GCC_TRADITIONAL
+AC_PROG_GCC_TRADITIONAL
AC_ISC_POSIX
-AC_TEST_PROGRAM(main(){exit(0);},,AC_ERROR(Can't run the compiler - sorry))
+AC_TRY_RUN(main(){exit(0);},,[
+if test $CC != cc ; then
+AC_NOTE(Your $CC failed - restarting with CC=cc)
+AC_NOTE()
+CC=cc
+export CC
+exec $0 $configure_args
+fi
+])
+
+AC_TRY_RUN(main(){exit(0);},,
+exec 5>&2
+eval $ac_link
+AC_NOTE(CC=$CC; CFLAGS=$CFLAGS; LIBS=$LIBS;)
+AC_NOTE($ac_compile)
+AC_MSG_ERROR(Can't run the compiler - sorry))
-AC_TEST_PROGRAM([
+AC_TRY_RUN([
main()
{
int __something_strange_();
__something_strange_(0);
}
-],AC_ERROR(Your compiler does not set the exit status - sorry))
+],AC_MSG_ERROR(Your compiler does not set the exit status - sorry))
AC_PROG_AWK
@@ -58,7 +75,7 @@ AC_PROG_INSTALL
if test -f etc/toolcheck; then
AC_CHECKING(for buggy tools)
-sh etc/toolcheck
+sh etc/toolcheck 1>&AC_FD_MSG
fi
dnl
@@ -81,13 +98,19 @@ fi
AC_CHECKING(for MIPS)
if test -f /lib/libmld.a || test -f /usr/lib/libmld.a || test -f /usr/lib/cmplrs/cc/libmld.a; then
+oldlibs="$LIBS"
test -f /bin/mx || LIBS="$LIBS -lmld" # for nlist. But not on alpha.
dnl djm@eng.umd.edu: "... for one thing, it doubles the size of the executable"
+AC_CHECKING(mld library)
+AC_TRY_LINK(,,,LIBS="$oldlibs")
+dnl
dnl
if test -r /dev/ptc; then
AC_DEFINE(MIPS)
-AC_COMPILE_CHECK(wait3, , [wait3();], ,
-AC_COMPILE_CHECK(wait2, , [wait2();],
+AC_CHECKING(wait3)
+AC_TRY_LINK(,[wait3();], ,
+AC_CHECKING(wait2)
+AC_TRY_LINK(,[wait2();],
dnl John Rouillard (rouilj@sni-usa.com):
dnl need -I/usr/include/bsd in RISCOS otherwise sockets are broken, no
dnl job control etc.
@@ -97,26 +120,28 @@ AC_DEFINE(USE_WAIT2) LIBS="$LIBS -lbsd" ; CC="$CC -I/usr/include/bsd"
fi
fi
+
AC_CHECKING(for Ultrix)
-AC_PROGRAM_EGREP(yes,
+AC_EGREP_CPP(yes,
[#if defined(ultrix) || defined(__ultrix)
- yes
+ yes;
#endif
], ULTRIX=1)
if test -f /usr/lib/libpyr.a ; then
oldlibs="$LIBS"
LIBS="$LIBS -lpyr"
-AC_COMPILE_CHECK(Pyramid OSX,,[open_controlling_pty("");],AC_DEFINE(OSX),LIBS="oldlibs")
+AC_CHECKING(Pyramid OSX)
+AC_TRY_LINK(,[open_controlling_pty("")], AC_DEFINE(OSX), LIBS="$oldlibs")
fi
dnl ghazi@caip.rutgers.edu (Kaveh R. Ghazi):
dnl BBN butterfly is not POSIX, but a MACH BSD system.
dnl Do not define POSIX and TERMIO.
AC_CHECKING(for butterfly)
-AC_PROGRAM_EGREP(yes,
+AC_EGREP_CPP(yes,
[#if defined(butterfly)
- yes
+ yes;
#endif
], butterfly=1)
@@ -125,58 +150,70 @@ if test -n "$ULTRIX"; then
test -z "$GCC" && CC="$CC -YBSD"
fi
AC_CHECKING(for POSIX.1)
-AC_PROGRAM_EGREP(yes,
+AC_EGREP_CPP(yes,
[#include <sys/types.h>
#include <unistd.h>
main () {
#ifdef _POSIX_VERSION
- yes
+ yes;
#endif
], AC_NOTE(- you have a POSIX system) AC_DEFINE(POSIX) posix=1)
fi
-AC_COMPILE_CHECK([System V],
+AC_CHECKING(for System V)
+AC_TRY_COMPILE(
[#include <sys/types.h>
#include <signal.h>
#include <fcntl.h>], [int x = SIGCHLD | FNDELAY;], , AC_DEFINE(SYSV))
AC_CHECKING(for sequent/ptx)
-AC_PROGRAM_EGREP(yes,
+AC_EGREP_CPP(yes,
[#ifdef _SEQUENT_
- yes
+ yes;
#endif
], LIBS="$LIBS -lsocket -linet";seqptx=1)
oldlibs="$LIBS"
LIBS="$LIBS -lelf"
-AC_COMPILE_CHECK(SVR4,[#include <utmpx.h>
+AC_CHECKING(SVR4)
+AC_TRY_LINK([#include <utmpx.h>
],,
-AC_HEADER_CHECK(dwarf.h, AC_DEFINE(SVR4) AC_DEFINE(BUGGYGETLOGIN),
-AC_HEADER_CHECK(elf.h, AC_DEFINE(SVR4) AC_DEFINE(BUGGYGETLOGIN)))
+AC_CHECK_HEADER(dwarf.h, AC_DEFINE(SVR4) AC_DEFINE(BUGGYGETLOGIN),
+AC_CHECK_HEADER(elf.h, AC_DEFINE(SVR4) AC_DEFINE(BUGGYGETLOGIN)))
,LIBS="$oldlibs")
+AC_CHECKING(for Solaris 2.x)
+AC_EGREP_CPP(yes,
+[#if defined(SVR4) && defined(sun)
+ yes
+#endif
+], LIBS="$LIBS -lsocket -lnsl -lkstat")
dnl
dnl **** typedefs ****
dnl
+dnl (currently not used)
+dnl
dnl AC_CHECKING(for pid_t)
-dnl AC_PROGRAM_EGREP(pid_t,[#include <sys/types.h>
+dnl AC_EGREP_CPP(pid_t,[#include <sys/types.h>
dnl ],AC_DEFINE(PID_T_DEFINED))
dnl
dnl AC_CHECKING(for sig_t)
-dnl AC_PROGRAM_EGREP(sig_t,[#include <sys/types.h>
+dnl AC_EGREP_CPP(sig_t,[#include <sys/types.h>
dnl #include <signal.h>
dnl ],AC_DEFINE(SIG_T_DEFINED))
dnl
dnl AC_CHECKING(for uid_t)
-dnl AC_PROGRAM_EGREP(uid_t,[#include <sys/types.h>
+dnl AC_EGREP_CPP(uid_t,[#include <sys/types.h>
dnl ],AC_DEFINE(UID_T_DEFINED))
+dnl
dnl
dnl **** Job control ****
dnl
-AC_COMPILE_CHECK([BSD job control],
+AC_CHECKING(BSD job jontrol)
+AC_TRY_LINK(
[#include <sys/types.h>
#include <sys/ioctl.h>
], [
@@ -195,7 +232,8 @@ int y = TIOCNOTTY;
dnl
dnl **** setreuid(), seteuid() ****
dnl
-AC_COMPILE_CHECK(setreuid, , [
+AC_CHECKING(setreuid)
+AC_TRY_LINK(,[
#ifdef __hpux
setresuid(0, 0, 0);
#else
@@ -208,28 +246,32 @@ dnl linux seteuid was broken before V1.1.11
dnl NeXT, AUX, ISC, and ultrix are still broken (no saved uid support)
dnl Solaris seteuid doesn't change the saved uid, bad for
dnl multiuser screen sessions
-AC_COMPILE_CHECK(seteuid, , [
+AC_CHECKING(seteuid)
+AC_TRY_LINK(,[
#if defined(linux) || defined(NeXT) || defined(_AUX_SOURCE) || defined(AUX) || defined(ultrix) || (defined(sun) && defined(SVR4)) || defined(ISC) || defined(sony_news)
seteuid_is_broken(0);
#else
seteuid(0);
#endif
], AC_DEFINE(HAVE_SETEUID))
+
dnl
dnl **** select() ****
dnl
-AC_COMPILE_CHECK(select,,[select(0, 0, 0, 0, 0);],,
+AC_CHECKING(select)
+AC_TRY_LINK(,[select(0, 0, 0, 0, 0);],,
LIBS="$LIBS -lnet -lnsl"
-AC_COMPILE_CHECK(select with $LIBS,,[select(0, 0, 0, 0, 0);],,
-AC_ERROR(!!! no select - no screen))
+AC_CHECKING(select with $LIBS)
+AC_TRY_LINK(,[select(0, 0, 0, 0, 0);],,
+AC_MSG_ERROR(!!! no select - no screen))
)
dnl
dnl **** FIFO tests ****
dnl
AC_CHECKING(fifos)
-AC_TEST_PROGRAM([
+AC_TRY_RUN([
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -285,13 +327,13 @@ main()
exit(1);
exit(0);
}
-], AC_NOTE(- your fifos are usable);fifo=1,
+], AC_NOTE(- your fifos are usable) fifo=1,
AC_NOTE(- your fifos are not usable))
rm -f /tmp/conftest*
if test -n "$fifo"; then
AC_CHECKING(for broken fifo implementation)
-AC_TEST_PROGRAM([
+AC_TRY_RUN([
#include <sys/types.h>
#include <fcntl.h>
#include <sys/time.h>
@@ -339,7 +381,7 @@ dnl may need LIBS="$LIBS -lsocket" here
dnl
AC_CHECKING(sockets)
-AC_TEST_PROGRAM([
+AC_TRY_RUN([
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
@@ -380,13 +422,13 @@ main()
exit(1);
exit(0);
}
-], AC_NOTE(- your sockets are usable);sock=1,
+], AC_NOTE(- your sockets are usable) sock=1,
AC_NOTE(- your sockets are not usable))
rm -f /tmp/conftest*
if test -n "$sock"; then
AC_CHECKING(socket implementation)
-AC_TEST_PROGRAM([
+AC_TRY_RUN([
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
@@ -439,7 +481,7 @@ if test -n "$fifo"; then
elif test -n "$sock"; then
AC_NOTE(- using unix-domain sockets, of course)
else
- AC_ERROR(you have neither usable sockets nor usable pipes -> no screen)
+ AC_MSG_ERROR(you have neither usable sockets nor usable pipes -> no screen)
fi
dnl
@@ -447,7 +489,7 @@ dnl **** check the select implementation ****
dnl
AC_CHECKING(select return value)
-AC_TEST_PROGRAM([
+AC_TRY_RUN([
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -470,7 +512,7 @@ main()
#ifdef __FreeBSD__
/* From Andrew A. Chernov (ache@astral.msk.su):
- * opening RDWR fifo fails in BSD 4.4, but select return values is
+ * opening RDWR fifo fails in BSD 4.4, but select return values are
* right.
*/
exit(0);
@@ -541,7 +583,8 @@ dnl
AC_CHECKING(for tgetent)
olibs="$LIBS"
LIBS="-lcurses $olibs"
-AC_COMPILE_CHECK(libcurses,,[
+AC_CHECKING(libcurses)
+AC_TRY_LINK(,[
#ifdef __hpux
__sorry_hpux_libcurses_is_totally_broken_in_10_10();
#else
@@ -549,18 +592,24 @@ tgetent((char *)0, (char *)0);
#endif
],,
LIBS="-ltermcap $olibs"
-AC_COMPILE_CHECK(libtermcap,,tgetent((char *)0, (char *)0);,,
+AC_CHECKING(libtermcap)
+AC_TRY_LINK(,tgetent((char *)0, (char *)0);,,
LIBS="-ltermlib $olibs"
-AC_COMPILE_CHECK(libtermlib,,tgetent((char *)0, (char *)0);,,
-AC_ERROR(!!! no tgetent - no screen))))
-
-AC_TEST_PROGRAM([
+AC_CHECKING(libtermlib)
+AC_TRY_LINK(,tgetent((char *)0, (char *)0);,,
+LIBS="-lncurses $olibs"
+AC_CHECKING(libncurses)
+AC_TRY_LINK(,tgetent((char *)0, (char *)0);,,
+AC_MSG_ERROR(!!! no tgetent - no screen)))))
+
+AC_TRY_RUN([
main()
{
exit(strcmp(tgoto("%p1%d", 0, 1), "1") ? 0 : 1);
}], AC_NOTE(- you use the termcap database),
AC_NOTE(- you use the terminfo database) AC_DEFINE(TERMINFO))
-AC_COMPILE_CHECK(ospeed,extern short ospeed;,ospeed=5;,,AC_DEFINE(NEED_OSPEED))
+AC_CHECKING(ospeed)
+AC_TRY_LINK(extern short ospeed;,ospeed=5;,,AC_DEFINE(NEED_OSPEED))
dnl
dnl **** PTY specific things ****
@@ -570,18 +619,33 @@ if test -r /dev/ptc; then
AC_DEFINE(HAVE_DEV_PTC)
fi
+AC_CHECKING(for SVR4 ptys)
+if test -c /dev/ptmx ; then
+AC_TRY_LINK([],[ptsname(0);grantpt(0);unlockpt(0);],AC_DEFINE(HAVE_SVR4_PTYS))
+fi
+
AC_CHECKING(for ptyranges)
if test -d /dev/ptym ; then
pdir='/dev/ptym'
else
pdir='/dev'
fi
-ptys=`echo $pdir/pty??`
+dnl SCO uses ptyp%d
+AC_EGREP_CPP(yes,
+[#ifdef M_UNIX
+ yes;
+#endif
+], ptys=`echo /dev/ptyp??`, ptys=`echo $pdir/pty??`)
+dnl if test -c /dev/ptyp19; then
+dnl ptys=`echo /dev/ptyp??`
+dnl else
+dnl ptys=`echo $pdir/pty??`
+dnl fi
if test "$ptys" != "$pdir/pty??" ; then
p0=`echo $ptys | tr ' ' '\012' | sed -e 's/^.*\(.\).$/\1/g' | sort -u | tr -d '\012'`
p1=`echo $ptys | tr ' ' '\012' | sed -e 's/^.*\(.\)$/\1/g' | sort -u | tr -d '\012'`
-AC_DEFINE_UNQUOTED(PTYRANGE0,\"$p0\")
-AC_DEFINE_UNQUOTED(PTYRANGE1,\"$p1\")
+AC_DEFINE_UNQUOTED(PTYRANGE0,"$p0")
+AC_DEFINE_UNQUOTED(PTYRANGE1,"$p1")
fi
dnl **** pty mode/group handling ****
@@ -589,7 +653,7 @@ dnl
dnl support provided by Luke Mewburn <lm@rmit.edu.au>, 931222
AC_CHECKING(default tty permissions/group)
rm -f conftest_grp
-AC_TEST_PROGRAM([
+AC_TRY_RUN([
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
@@ -634,8 +698,9 @@ rm -f conftest_grp
dnl
dnl **** utmp handling ****
dnl
-dnl linux has a void pututline, grrr, gcc will error when evaluating it.
-AC_COMPILE_CHECK(getutent, [#include <time.h> /* to get time_t on SCO */
+AC_CHECKING(getutent)
+AC_TRY_LINK([
+#include <time.h> /* to get time_t on SCO */
#include <sys/types.h>
#if defined(SVR4) && !defined(DGUX)
#include <utmpx.h>
@@ -647,10 +712,12 @@ AC_COMPILE_CHECK(getutent, [#include <time.h> /* to get time_t on SCO */
#define pututline _pututline
#endif
],
-[int x = DEAD_PROCESS; struct utmp *y = pututline((struct utmp *)0); getutent();], AC_DEFINE(GETUTENT),
+[int x = DEAD_PROCESS; pututline((struct utmp *)0); getutent();], AC_DEFINE(GETUTENT),
olibs="$LIBS"
LIBS="$LIBS -lgen"
-AC_COMPILE_CHECK(getutent with -lgen, [#include <time.h>
+AC_CHECKING(getutent with -lgen)
+AC_TRY_LINK([
+#include <time.h>
#include <sys/types.h>
#if defined(SVR4) && !defined(DGUX)
#include <utmpx.h>
@@ -662,9 +729,11 @@ AC_COMPILE_CHECK(getutent with -lgen, [#include <time.h>
#define pututline _pututline
#endif
],
-[int x = DEAD_PROCESS; struct utmp *y = pututline((struct utmp *)0); getutent();], AC_DEFINE(GETUTENT), LIBS="$olibs")
+[int x = DEAD_PROCESS; pututline((struct utmp *)0); getutent();], AC_DEFINE(GETUTENT), LIBS="$olibs")
)
-AC_COMPILE_CHECK(ut_host, [#include <time.h>
+AC_CHECKING(ut_host)
+AC_TRY_COMPILE([
+#include <time.h>
#include <sys/types.h>
#if defined(SVR4) && !defined(DGUX)
#include <utmpx.h>
@@ -673,7 +742,11 @@ AC_COMPILE_CHECK(ut_host, [#include <time.h>
#include <utmp.h>
#endif
],[struct utmp u; u.ut_host[0] = 0;], AC_DEFINE(UTHOST))
-
+AC_CHECK_HEADER(utempter.h, have_utempter=yes, have_utempter=no)
+if test "$have_utempter" = yes; then
+ AC_DEFINE(HAVE_UTEMPTER)
+ LIBS="$LIBS -lutempter"
+fi
dnl
dnl **** loadav ****
@@ -682,20 +755,22 @@ AC_CHECKING(for libutil(s))
test -f /usr/lib/libutils.a && LIBS="$LIBS -lutils"
test -f /usr/lib/libutil.a && LIBS="$LIBS -lutil"
-AC_COMPILE_CHECK(getloadavg, , [getloadavg((double *)0, 0);],
+AC_CHECKING(getloadavg)
+AC_TRY_LINK(,[getloadavg((double *)0, 0);],
AC_DEFINE(LOADAV_GETLOADAVG) load=1,
if test -f /usr/lib/libkvm.a ; then
olibs="$LIBS"
LIBS="$LIBS -lkvm"
-AC_COMPILE_CHECK(getloadavg with -lkvm, , [getloadavg((double *)0, 0);],
+AC_CHECKING(getloadavg with -lkvm)
+AC_TRY_LINK(,[getloadavg((double *)0, 0);],
AC_DEFINE(LOADAV_GETLOADAVG) load=1, LIBS="$olibs")
fi
)
if test -z "$load" ; then
-AC_PROGRAM_EGREP(yes,
+AC_EGREP_CPP(yes,
[#if defined(NeXT) || defined(apollo) || defined(linux)
- yes
+ yes;
#endif
], load=1)
fi
@@ -710,15 +785,17 @@ if test ! -f $core && test ! -c $core ; then
AC_NOTE(- no kernelfile found)
else
AC_NOTE(- using kernelfile '$core')
- AC_DEFINE_UNQUOTED(LOADAV_UNIX,\"$core\")
- AC_HEADER_CHECK(nlist.h,
+ if test -r $core ; then
+ AC_DEFINE_UNQUOTED(LOADAV_UNIX,"$core")
+ AC_CHECK_HEADER(nlist.h,
[AC_DEFINE(NLIST_STRUCT)
- AC_COMPILE_CHECK(n_un in struct nlist, [#include <nlist.h>],
+ AC_CHECKING(n_un in struct nlist)
+ AC_TRY_COMPILE([#include <nlist.h>],
[struct nlist n; n.n_un.n_name = 0;],
AC_DEFINE(NLIST_NAME_UNION))])
AC_CHECKING(for nlist declaration)
- AC_PROGRAM_EGREP([nlist(( | )( | )*.*\(|\()],[
+ AC_EGREP_CPP([nlist(( | )( | )*.*\(|\()],[
#ifdef NLIST_STRUCT
# include <nlist.h>
#else
@@ -728,7 +805,7 @@ else
AC_CHECKING(for avenrun symbol)
for av in avenrun _avenrun _Loadavg ; do
- AC_TEST_PROGRAM([
+ AC_TRY_RUN([
#include <sys/types.h>
#ifdef NLIST_STRUCT
#include <nlist.h>
@@ -737,7 +814,7 @@ else
#endif
#ifdef __sgi
-# if _MIPS_SZLONG == 64
+# if _MIPS_SZLONG == 64 || (defined(_MIPS_ISA) && _MIPS_ISA > 2)
# define nlist nlist64
# endif
#endif
@@ -766,9 +843,18 @@ main()
AC_NOTE(- no avenrun symbol found)
else
AC_NOTE(- using avenrun symbol '$avensym')
- AC_DEFINE_UNQUOTED(LOADAV_AVENRUN,\"$avensym\")
+ AC_DEFINE_UNQUOTED(LOADAV_AVENRUN,"$avensym")
load=1
fi
+ else
+ AC_NOTE( Can't configure the load average display feature)
+ AC_NOTE( because $core is not readable by you.)
+ AC_NOTE( To configure the load average display feature,)
+ AC_NOTE( re-run configure as root if possible.)
+ AC_NOTE( If you are not the system administrator then disregard)
+ AC_NOTE( this warning. You can still use screen without)
+ AC_NOTE( the load average display feature.)
+ fi
fi
fi
@@ -776,7 +862,7 @@ AC_PROGRAM_SOURCE([
#include <sys/types.h>
#include <sys/param.h>
],[
-#if ((defined(hp300) && !defined(__hpux)) || defined(sun) || (defined(ultrix) && defined(mips)) || defined(_SEQUENT_) || defined(sgi) || defined(SVR4) || defined(sony_news) || defined(__alpha) || defined(_IBMR2) || defined(_AUX_SOURCE) || defined(AUX) || defined(m88k))
+#if ((defined(hp300) && !defined(__hpux)) || defined(sun) || (defined(ultrix) && defined(mips)) || defined(_SEQUENT_) || defined(sgi) || defined(SVR4) || defined(sony_news) || !(defined(__osf__) && defined(__alpha)) || defined(_IBMR2) || defined(_AUX_SOURCE) || defined(AUX) || defined(m88k))
loadtype=long
# if defined(apollo) || defined(_IBMR2) || defined(_AUX_SOURCE) || defined(AUX)
loadscale=65536
@@ -786,8 +872,8 @@ loadscale=65536
loadscale=FSCALE
# else
# ifdef sgi
-loadscale=1024
loadtype=int
+loadscale=1024
# else
# if defined(MIPS) || defined(SVR4) || defined(m88k)
loadscale=256
@@ -813,7 +899,6 @@ if test -n "$loadtype" ; then AC_DEFINE_UNQUOTED(LOADAV_TYPE,$loadtype) fi
if test -n "$loadnum" ; then AC_DEFINE_UNQUOTED(LOADAV_NUM,$loadnum) fi
if test -n "$loadscale" ; then AC_DEFINE_UNQUOTED(LOADAV_SCALE,$loadscale) fi
-
dnl
dnl **** signal handling ****
dnl
@@ -825,17 +910,19 @@ AC_DEFINE(SIGVOID)
else
-AC_COMPILE_CHECK([return type of signal handlers],
+AC_CHECKING(return type of signal handlers)
+AC_TRY_COMPILE(
[#include <sys/types.h>
#include <signal.h>
#ifdef signal
#undef signal
#endif
extern void (*signal ()) ();], [int i;], AC_DEFINE(SIGVOID))
-AC_COMPILE_CHECK(sigset, [
+AC_CHECKING(sigset)
+AC_TRY_LINK([
#include <sys/types.h>
#include <signal.h>
-], [
+],[
#ifdef SIGVOID
sigset(0, (void (*)())0);
#else
@@ -843,7 +930,7 @@ sigset(0, (int (*)())0);
#endif
], AC_DEFINE(USESIGSET))
AC_CHECKING(signal implementation)
-AC_TEST_PROGRAM([
+AC_TRY_RUN([
#include <sys/types.h>
#include <signal.h>
@@ -886,19 +973,35 @@ dnl
AC_CHECKING(for crypt and sec libraries)
test -f /lib/libcrypt_d.a || test -f /usr/lib/libcrypt_d.a && LIBS="$LIBS -lcrypt_d"
-test -f /lib/libcrypt.a || test -f /usr/lib/libcrypt.a && LIBS="$LIBS -lcrypt"
+oldlibs="$LIBS"
+LIBS="$LIBS -lcrypt"
+AC_CHECKING(crypt)
+AC_TRY_LINK(,,,LIBS="$oldlibs")
test -f /lib/libsec.a || test -f /usr/lib/libsec.a && LIBS="$LIBS -lsec"
test -f /lib/libshadow.a || test -f /usr/lib/libshadow.a && LIBS="$LIBS -lshadow"
-
oldlibs="$LIBS"
LIBS="$LIBS -lsun"
-AC_COMPILE_CHECK(IRIX sun library,,,,LIBS="$oldlibs")
-
+AC_CHECKING(IRIX sun library)
+AC_TRY_LINK(,,,LIBS="$oldlibs")
+
+AC_CHECKING(syslog)
+AC_TRY_LINK(,[closelog();], , [oldlibs="$LIBS"
+LIBS="$LIBS -lbsd"
+AC_CHECKING(syslog in libbsd.a)
+AC_TRY_LINK(, [closelog();], AC_NOTE(- found.), [LIBS="oldlibs"
+AC_NOTE(- bad news: syslog missing.) AC_DEFINE(NOSYSLOG)])])
+
+AC_EGREP_CPP(yes,
+[#ifdef M_UNIX
+ yes;
+#endif
+], LIBS="$LIBS -lsocket -lcrypt_i")
dnl
dnl **** misc things ****
dnl
-AC_COMPILE_CHECK(wait union,[#include <sys/types.h>
+AC_CHECKING(wait union)
+AC_TRY_COMPILE([#include <sys/types.h>
#include <sys/wait.h>
],[
union wait x;
@@ -910,21 +1013,22 @@ AC_COMPILE_CHECK(wait union,[#include <sys/types.h>
if test -z "$butterfly"; then
AC_CHECKING(for termio or termios)
-AC_TEST_CPP([#include <termio.h>], AC_DEFINE(TERMIO),
+AC_TRY_CPP([#include <termio.h>], AC_DEFINE(TERMIO),
if test -n "$posix"; then
-AC_TEST_CPP([#include <termios.h>], AC_DEFINE(TERMIO))
+AC_TRY_CPP([#include <termios.h>], AC_DEFINE(TERMIO))
fi
)
fi
-dnl AC_HEADER_CHECK(shadow.h, AC_DEFINE(SHADOWPW))
-AC_COMPILE_CHECK(getspnam, [#include <shadow.h>], [getspnam("x");],
- AC_DEFINE(SHADOWPW))
+dnl AC_CHECK_HEADER(shadow.h, AC_DEFINE(SHADOWPW))
+AC_CHECKING(getspnam)
+AC_TRY_LINK([#include <shadow.h>], [getspnam("x");],AC_DEFINE(SHADOWPW))
-AC_COMPILE_CHECK(getttyent, , [getttyent();], AC_DEFINE(GETTTYENT))
+AC_CHECKING(getttyent)
+AC_TRY_LINK(,[getttyent();], AC_DEFINE(GETTTYENT))
AC_CHECKING(whether memcpy/memmove/bcopy handles overlapping arguments)
-AC_TEST_PROGRAM([
+AC_TRY_RUN([
main() {
char buf[10];
strcpy(buf, "abcdefghi");
@@ -938,7 +1042,7 @@ main() {
exit(0); /* libc version works properly. */
}], AC_DEFINE(USEBCOPY))
-AC_TEST_PROGRAM([
+AC_TRY_RUN([
#define bcopy(s,d,l) memmove(d,s,l)
main() {
char buf[10];
@@ -954,7 +1058,7 @@ main() {
}], AC_DEFINE(USEMEMMOVE))
-AC_TEST_PROGRAM([
+AC_TRY_RUN([
#define bcopy(s,d,l) memcpy(d,s,l)
main() {
char buf[10];
@@ -969,57 +1073,49 @@ main() {
exit(0); /* libc version works properly. */
}], AC_DEFINE(USEMEMCPY))
-AC_CHECKING(for long file names)
+AC_MSG_CHECKING(long file names)
(echo 1 > /tmp/conftest9012345) 2>/dev/null
(echo 2 > /tmp/conftest9012346) 2>/dev/null
val=`cat /tmp/conftest9012345 2>/dev/null`
-if test -f /tmp/conftest9012345 && test "$val" = 1; then :
-else AC_DEFINE(NAME_MAX, 14)
+if test -f /tmp/conftest9012345 && test "$val" = 1; then
+AC_MSG_RESULT(yes)
+else
+AC_MSG_RESULT(no)
+AC_DEFINE(NAME_MAX, 14)
fi
rm -f /tmp/conftest*
-AC_COMPILE_CHECK(vsprintf, [
-#include <stdio.h>], [vsprintf(0,0,0);], AC_DEFINE(USEVARARGS))
+AC_MSG_CHECKING(for vsprintf)
+AC_TRY_LINK(,[vsprintf(0,0,0);], AC_MSG_RESULT(yes);AC_DEFINE(USEVARARGS), AC_MSG_RESULT(no))
-AC_DIR_HEADER
-AC_XENIX_DIR
+AC_HEADER_DIRENT
-AC_COMPILE_CHECK(setenv, , [setenv((char *)0,(char *)0);unsetenv((char *)0);], AC_DEFINE(USESETENV),
-AC_COMPILE_CHECK(putenv, , [putenv((char *)0);unsetenv((char *)0);], ,
-AC_DEFINE(NEEDPUTENV)
+AC_MSG_CHECKING(for setenv)
+AC_TRY_LINK(,[setenv((char *)0,(char *)0);unsetenv((char *)0);], AC_MSG_RESULT(yes);AC_DEFINE(USESETENV),
+AC_MSG_RESULT(no)
+AC_MSG_CHECKING(for putenv)
+AC_TRY_LINK(,[putenv((char *)0);unsetenv((char *)0);], AC_MSG_RESULT(yes) , AC_MSG_RESULT(no);AC_DEFINE(NEEDPUTENV)
))
-AC_COMPILE_CHECK(rename, , [rename(0,0);], , AC_DEFINE(NEED_RENAME))
-AC_COMPILE_CHECK(_exit, , [_exit(0);], AC_DEFINE(HAVE__EXIT))
-AC_COMPILE_CHECK(lstat, , [lstat(0,0);], AC_DEFINE(HAVE_LSTAT))
-AC_COMPILE_CHECK(strerror, ,[strerror(0);], AC_DEFINE(HAVE_STRERROR))
-AC_COMPILE_CHECK(utimes, ,[utimes(0,0);], AC_DEFINE(HAVE_UTIMES))
-AC_COMPILE_CHECK(vsnprintf, ,[vsnprintf(0,0,0);], AC_DEFINE(HAVE_VSNPRINTF))
+AC_CHECK_FUNCS(rename fchmod fchown strerror lstat _exit utimes vsnprintf getcwd)
dnl
dnl **** the end ****
dnl
dnl Ptx bug workaround -- insert -lc after -ltermcap
-test -n "$seqptx" && LIBS="-ltermcap -lc -lsocket -linet -lsec -lseq"
+test -n "$seqptx" && LIBS="-ltermcap -lc -lsocket -linet -lnsl -lsec -lseq"
-AC_TEST_PROGRAM(main(){exit(0);},,AC_ERROR(Can't run the compiler - internal error. Sorry.))
+AC_TRY_RUN(main(){exit(0);},,AC_MSG_ERROR(Can't run the compiler - internal error. Sorry.))
if test -n "$prefix"; then
-AC_DEFINE_UNQUOTED(ETCSCREENRC,\"$prefix/etc/screenrc\")
+AC_DEFINE_UNQUOTED(ETCSCREENRC,"$prefix/etc/screenrc")
fi
-AC_OUTPUT(Makefile doc/Makefile)
-
+AC_OUTPUT(Makefile doc/Makefile, [[
# a hook for preserving undef directive in config.h
-if test -z "$no_create" ; then
mv config.h conftest
sed -e 's@^\(.*\)defin.\( .*\) .*/\*\(.*KEEP_UNDEF_HERE\)@\1undef\2 /\*\3@' < conftest > config.h
rm -f conftest
-fi
-cat >> config.status << EOF
-mv config.h conftest
-sed -e 's@^\(.*\)defin.\( .*\) .*/\*\(.*KEEP_UNDEF_HERE\)@\1undef\2 /\*\3@' < conftest > config.h
-rm -f conftest
-EOF
+]])
echo ""
if test -z "$AWK"; then
diff --git a/display.c b/display.c
index 3a47928..68133f0 100644
--- a/display.c
+++ b/display.c
@@ -31,21 +31,41 @@ RCS_ID("$Id: display.c,v 1.16 1994/05/31 12:31:50 mlschroe Exp $ FAU")
#include "config.h"
#include "screen.h"
#include "extern.h"
+#include "braille.h"
-static void CountChars __P((int));
-static void PutChar __P((int));
+static int CountChars __P((int));
+static int PutChar __P((int));
static int BlankResize __P((int, int));
+static int CallRewrite __P((int, int, int, int));
+static void FreeCanvas __P((struct canvas *));
+static void disp_readev_fn __P((struct event *, char *));
+static void disp_writeev_fn __P((struct event *, char *));
+static void disp_status_fn __P((struct event *, char *));
+static void disp_hstatus_fn __P((struct event *, char *));
+static void cv_winid_fn __P((struct event *, char *));
+#ifdef MAPKEYS
+static void disp_map_fn __P((struct event *, char *));
+#endif
+static void WriteLP __P((int, int));
+static void INSERTCHAR __P((int));
+static void RAW_PUTCHAR __P((int));
+extern struct layer *flayer;
extern struct win *windows;
+extern struct LayFuncs WinLf;
extern int use_hardstatus;
-extern int MsgMinWait;
+extern int MsgWait, MsgMinWait;
extern int Z0width, Z1width;
extern char *blank, *null;
extern struct mline mline_blank, mline_null;
extern struct mchar mchar_null, mchar_blank, mchar_so;
+/* XXX shouldn't be here */
+extern char *hstatusstring;
+extern char *captionstring;
+
/*
* tputs needs this to calculate the padding
*/
@@ -68,6 +88,8 @@ int defobuflimit = OBUF_MAX;
#ifdef AUTO_NUKE
int defautonuke = 0;
#endif
+int captionalways;
+int hardstatusemu = HSTATUS_IGNORE;
/*
* Default layer management
@@ -94,23 +116,18 @@ void
DefClearLine(y, xs, xe)
int y, xs, xe;
{
- DisplayLine(&mline_null, &mline_blank, y, xs, xe);
+ LClearLine(flayer, y, xs, xe, (struct mline *)0);
}
/*ARGSUSED*/
int
-DefRewrite(y, xs, xe, doit)
+DefRewrite(y, xs, xe, rend, doit)
int y, xs, xe, doit;
+struct mchar *rend;
{
return EXPENSIVE;
}
-void
-DefSetCursor()
-{
- GotoPos(0, 0);
-}
-
/*ARGSUSED*/
int
DefResize(wi, he)
@@ -122,13 +139,13 @@ int wi, he;
void
DefRestore()
{
- InsertMode(0);
- ChangeScrollRegion(0, D_height - 1);
- KeypadMode(0);
- CursorkeysMode(0);
- CursorVisibility(0);
- SetRendition(&mchar_null);
- SetFlow(FLOW_NOW);
+ LAY_DISPLAYS(flayer, InsertMode(0));
+ /* ChangeScrollRegion(0, D_height - 1); */
+ LKeypadMode(flayer, 0);
+ LCursorkeysMode(flayer, 0);
+ LCursorVisibility(flayer, 0);
+ LSetRendition(flayer, &mchar_null);
+ LSetFlow(flayer, FLOW_NOW);
}
/*
@@ -142,30 +159,25 @@ struct LayFuncs BlankLf =
DefRedisplayLine,
DefClearLine,
DefRewrite,
- DefSetCursor,
BlankResize,
DefRestore
};
-struct layer BlankLayer =
-{
- 0,
- 0,
- &BlankLf,
- 0
-};
-
/*ARGSUSED*/
static int
BlankResize(wi, he)
int wi, he;
{
+ flayer->l_width = wi;
+ flayer->l_height = he;
return 0;
}
/*
- * Generate new display
+ * Generate new display, start with a blank layer.
+ * The termcap arrays are not initialised here.
+ * The new display is placed in the displays list.
*/
struct display *
@@ -175,14 +187,14 @@ int fd, pid;
struct mode *Mode;
{
struct user **u;
+ struct baud_values *b;
if (!*(u = FindUserPtr(uname)) && UserAdd(uname, (char *)0, u))
return 0; /* could not find or add user */
#ifdef MULTI
- if ((display = (struct display *)malloc(sizeof(*display))) == 0)
+ if ((display = (struct display *)calloc(1, sizeof(*display))) == 0)
return 0;
- bzero((char *) display, sizeof(*display));
#else
if (displays)
return 0;
@@ -193,106 +205,102 @@ struct mode *Mode;
D_flow = 1;
D_nonblock = 0;
D_userfd = fd;
+ D_readev.fd = D_writeev.fd = fd;
+ D_readev.type = EV_READ;
+ D_writeev.type = EV_WRITE;
+ D_readev.data = D_writeev.data = (char *)display;
+ D_readev.handler = disp_readev_fn;
+ D_writeev.handler = disp_writeev_fn;
+ evenq(&D_readev);
+ D_writeev.condpos = &D_obuflen;
+ D_writeev.condneg = &D_obuffree;
+ evenq(&D_writeev);
+ D_statusev.type = EV_TIMEOUT;
+ D_statusev.data = (char *)display;
+ D_statusev.handler = disp_status_fn;
+ D_hstatusev.type = EV_TIMEOUT;
+ D_hstatusev.data = (char *)display;
+ D_hstatusev.handler = disp_hstatus_fn;
+#ifdef MAPKEYS
+ D_mapev.type = EV_TIMEOUT;
+ D_mapev.data = (char *)display;
+ D_mapev.handler = disp_map_fn;
+#endif
D_OldMode = *Mode;
Resize_obuf(); /* Allocate memory for buffer */
D_obufmax = defobuflimit;
+ D_obuflenmax = D_obuflen - D_obufmax;
#ifdef AUTO_NUKE
D_auto_nuke = defautonuke;
#endif
D_obufp = D_obuf;
D_printfd = -1;
D_userpid = pid;
-#if defined(POSIX) || defined(TERMIO)
-# ifdef POSIX
- switch (cfgetospeed(&D_OldMode.tio))
+
+#ifdef POSIX
+ if ((b = lookup_baud((int)cfgetospeed(&D_OldMode.tio))))
+ D_dospeed = b->idx;
+#else
+# ifdef TERMIO
+ if ((b = lookup_baud(D_OldMode.tio.c_cflag & CBAUD)))
+ D_dospeed = b->idx;
# else
- switch (D_OldMode.tio.c_cflag & CBAUD)
+ D_dospeed = (short)D_OldMode.m_ttyb.sg_ospeed;
# endif
- {
-#ifdef B0
- case B0: D_dospeed = 0; break;
-#endif
-#ifdef B50
- case B50: D_dospeed = 1; break;
-#endif
-#ifdef B75
- case B75: D_dospeed = 2; break;
-#endif
-#ifdef B110
- case B110: D_dospeed = 3; break;
-#endif
-#ifdef B134
- case B134: D_dospeed = 4; break;
-#endif
-#ifdef B150
- case B150: D_dospeed = 5; break;
#endif
-#ifdef B200
- case B200: D_dospeed = 6; break;
-#endif
-#ifdef B300
- case B300: D_dospeed = 7; break;
-#endif
-#ifdef B600
- case B600: D_dospeed = 8; break;
-#endif
-#ifdef B1200
- case B1200: D_dospeed = 9; break;
-#endif
-#ifdef B1800
- case B1800: D_dospeed = 10; break;
-#endif
-#ifdef B2400
- case B2400: D_dospeed = 11; break;
-#endif
-#ifdef B4800
- case B4800: D_dospeed = 12; break;
-#endif
-#ifdef B9600
- case B9600: D_dospeed = 13; break;
-#endif
-#ifdef EXTA
- case EXTA: D_dospeed = 14; break;
-#endif
-#ifdef EXTB
- case EXTB: D_dospeed = 15; break;
-#endif
-#ifdef B57600
- case B57600: D_dospeed = 16; break;
-#endif
-#ifdef B115200
- case B115200: D_dospeed = 17; break;
-#endif
- default: ;
- }
-#else /* POSIX || TERMIO */
- D_dospeed = (short) D_OldMode.m_ttyb.sg_ospeed;
-#endif /* POSIX || TERMIO */
+
debug1("New displays ospeed = %d\n", D_dospeed);
strncpy(D_usertty, utty, sizeof(D_usertty) - 1);
D_usertty[sizeof(D_usertty) - 1] = 0;
strncpy(D_termname, term, sizeof(D_termname) - 1);
D_termname[sizeof(D_termname) - 1] = 0;
D_user = *u;
- D_lay = &BlankLayer;
- D_layfn = BlankLayer.l_layfn;
+ D_processinput = ProcessInput;
return display;
}
+
void
FreeDisplay()
{
struct win *p;
+ struct canvas *cv, *cvp;
#ifdef MULTI
struct display *d, **dp;
#endif
+#ifdef FONT
FreeTransTable();
+#endif
+ if (D_userfd >= 0)
+ {
+ Flush();
+ SetTTY(D_userfd, &D_OldMode);
+ fcntl(D_userfd, F_SETFL, 0);
+ }
freetty();
if (D_tentry)
free(D_tentry);
D_tentry = 0;
+ if (D_processinputdata)
+ free(D_processinputdata);
+ D_processinputdata = 0;
D_tcinited = 0;
+ evdeq(&D_hstatusev);
+ evdeq(&D_statusev);
+ evdeq(&D_readev);
+ evdeq(&D_writeev);
+#ifdef MAPKEYS
+ evdeq(&D_mapev);
+#endif
+#ifdef HAVE_BRAILLE
+ if (bd.bd_dpy == display)
+ {
+ bd.bd_start_braille = 0;
+ StartBraille();
+ }
+#endif
+
#ifdef MULTI
for (dp = &displays; (d = *dp) ; dp = &d->d_next)
if (d == display)
@@ -303,22 +311,329 @@ FreeDisplay()
if (D_obuf)
free(D_obuf);
*dp = display->d_next;
- free((char *)display);
+ cv = display->d_cvlist;
#else /* MULTI */
ASSERT(display == displays);
ASSERT(display == &TheDisplay);
+ cv = display->d_cvlist;
+ display->d_cvlist = 0;
displays = 0;
#endif /* MULTI */
+
for (p = windows; p; p = p->w_next)
{
- if (p->w_display == display)
- p->w_display = 0;
if (p->w_pdisplay == display)
p->w_pdisplay = 0;
}
+ for (; cv; cv = cvp)
+ {
+ cvp = cv->c_next;
+ FreeCanvas(cv);
+ }
+#ifdef MULTI
+ free((char *)display);
+#endif
display = 0;
}
+int
+MakeDefaultCanvas()
+{
+ struct canvas *cv;
+
+ ASSERT(display);
+ if ((cv = (struct canvas *)calloc(1, sizeof *cv)) == 0)
+ return -1;
+ cv->c_xs = 0;
+ cv->c_xe = D_width - 1;
+ cv->c_ys = 0;
+ cv->c_ye = D_height - 1 - (D_has_hstatus == HSTATUS_LASTLINE) - captionalways;
+ cv->c_xoff = 0;
+ cv->c_yoff = 0;
+ cv->c_next = 0;
+ cv->c_display = display;
+ cv->c_vplist = 0;
+ cv->c_captev.type = EV_TIMEOUT;
+ cv->c_captev.data = (char *)cv;
+ cv->c_captev.handler = cv_winid_fn;
+
+ cv->c_blank.l_cvlist = cv;
+ cv->c_blank.l_width = cv->c_xe - cv->c_xs + 1;
+ cv->c_blank.l_height = cv->c_ye - cv->c_ys + 1;
+ cv->c_blank.l_x = cv->c_blank.l_y = 0;
+ cv->c_blank.l_layfn = &BlankLf;
+ cv->c_blank.l_data = 0;
+ cv->c_blank.l_next = 0;
+ cv->c_blank.l_bottom = &cv->c_blank;
+ cv->c_blank.l_blocking = 0;
+ cv->c_layer = &cv->c_blank;
+ cv->c_lnext = 0;
+
+ D_cvlist = cv;
+ RethinkDisplayViewports();
+ D_forecv = cv; /* default input focus */
+ return 0;
+}
+
+void
+FreeCanvas(cv)
+struct canvas *cv;
+{
+ struct viewport *vp, *nvp;
+ struct win *p;
+
+ p = Layer2Window(cv->c_layer);
+ SetCanvasWindow(cv, 0);
+ if (p)
+ WindowChanged(p, 'u');
+ if (flayer == cv->c_layer)
+ flayer = 0;
+ for (vp = cv->c_vplist; vp; vp = nvp)
+ {
+ vp->v_canvas = 0;
+ nvp = vp->v_next;
+ vp->v_next = 0;
+ free(vp);
+ }
+ evdeq(&cv->c_captev);
+ free(cv);
+}
+
+int
+AddCanvas()
+{
+ int hh, h, i, j;
+ struct canvas *cv, **cvpp;
+
+ for (cv = D_cvlist, j = 0; cv; cv = cv->c_next)
+ j++;
+ j++; /* new canvas */
+ h = D_height - (D_has_hstatus == HSTATUS_LASTLINE);
+ if (h / j <= 1)
+ return -1;
+
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ if (cv == D_forecv)
+ break;
+ ASSERT(cv);
+ cvpp = &cv->c_next;
+
+ if ((cv = (struct canvas *)calloc(1, sizeof *cv)) == 0)
+ return -1;
+
+ cv->c_xs = 0;
+ cv->c_xe = D_width - 1;
+ cv->c_ys = 0;
+ cv->c_ye = D_height - 1;
+ cv->c_xoff = 0;
+ cv->c_yoff = 0;
+ cv->c_display = display;
+ cv->c_vplist = 0;
+ cv->c_captev.type = EV_TIMEOUT;
+ cv->c_captev.data = (char *)cv;
+ cv->c_captev.handler = cv_winid_fn;
+
+ cv->c_blank.l_cvlist = cv;
+ cv->c_blank.l_width = cv->c_xe - cv->c_xs + 1;
+ cv->c_blank.l_height = cv->c_ye - cv->c_ys + 1;
+ cv->c_blank.l_x = cv->c_blank.l_y = 0;
+ cv->c_blank.l_layfn = &BlankLf;
+ cv->c_blank.l_data = 0;
+ cv->c_blank.l_next = 0;
+ cv->c_blank.l_bottom = &cv->c_blank;
+ cv->c_blank.l_blocking = 0;
+ cv->c_layer = &cv->c_blank;
+ cv->c_lnext = 0;
+
+ cv->c_next = *cvpp;
+ *cvpp = cv;
+
+ i = 0;
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ {
+ hh = h / j-- - 1;
+ cv->c_ys = i;
+ cv->c_ye = i + hh - 1;
+ cv->c_yoff = i;
+ i += hh + 1;
+ h -= hh + 1;
+ }
+
+ RethinkDisplayViewports();
+ ResizeLayersToCanvases();
+ return 0;
+}
+
+void
+RemCanvas()
+{
+ int hh, h, i, j;
+ struct canvas *cv, **cvpp;
+ int did = 0;
+
+ h = D_height - (D_has_hstatus == HSTATUS_LASTLINE);
+ for (cv = D_cvlist, j = 0; cv; cv = cv->c_next)
+ j++;
+ if (j == 1)
+ return;
+ i = 0;
+ j--;
+ for (cvpp = &D_cvlist; (cv = *cvpp); cvpp = &cv->c_next)
+ {
+ if (cv == D_forecv && !did)
+ {
+ *cvpp = cv->c_next;
+ FreeCanvas(cv);
+ cv = *cvpp;
+ D_forecv = cv ? cv : D_cvlist;
+ D_fore = Layer2Window(D_forecv->c_layer);
+ flayer = D_forecv->c_layer;
+ if (cv == 0)
+ break;
+ did = 1;
+ }
+ hh = h / j-- - 1;
+ if (!captionalways && i == 0 && j == 0)
+ hh++;
+ cv->c_ys = i;
+ cv->c_ye = i + hh - 1;
+ cv->c_yoff = i;
+ i += hh + 1;
+ h -= hh + 1;
+ }
+ RethinkDisplayViewports();
+ ResizeLayersToCanvases();
+}
+
+void
+OneCanvas()
+{
+ struct canvas *mycv = D_forecv;
+ struct canvas *cv, **cvpp;
+
+ for (cvpp = &D_cvlist; (cv = *cvpp);)
+ {
+ if (cv == mycv)
+ {
+ cv->c_ys = 0;
+ cv->c_ye = D_height - 1 - (D_has_hstatus == HSTATUS_LASTLINE) - captionalways;
+ cv->c_yoff = 0;
+ cvpp = &cv->c_next;
+ }
+ else
+ {
+ *cvpp = cv->c_next;
+ FreeCanvas(cv);
+ }
+ }
+ RethinkDisplayViewports();
+ ResizeLayersToCanvases();
+}
+
+int
+RethinkDisplayViewports()
+{
+ struct canvas *cv;
+ struct viewport *vp, *vpn;
+
+ /* free old viewports */
+ for (cv = display->d_cvlist; cv; cv = cv->c_next)
+ {
+ for (vp = cv->c_vplist; vp; vp = vpn)
+ {
+ vp->v_canvas = 0;
+ vpn = vp->v_next;
+ bzero((char *)vp, sizeof(*vp));
+ free(vp);
+ }
+ cv->c_vplist = 0;
+ }
+ display->d_vpxmin = -1;
+ display->d_vpxmax = -1;
+
+ for (cv = display->d_cvlist; cv; cv = cv->c_next)
+ {
+ if ((vp = (struct viewport *)malloc(sizeof *vp)) == 0)
+ return -1;
+#ifdef HOLE
+ vp->v_canvas = cv;
+ vp->v_xs = cv->c_xs;
+ vp->v_ys = (cv->c_ys + cv->c_ye) / 2;
+ vp->v_xe = cv->c_xe;
+ vp->v_ye = cv->c_ye;
+ vp->v_xoff = cv->c_xoff;
+ vp->v_yoff = cv->c_yoff;
+ vp->v_next = cv->c_vplist;
+ cv->c_vplist = vp;
+
+ if ((vp = (struct viewport *)malloc(sizeof *vp)) == 0)
+ return -1;
+ vp->v_canvas = cv;
+ vp->v_xs = (cv->c_xs + cv->c_xe) / 2;
+ vp->v_ys = (3 * cv->c_ys + cv->c_ye) / 4;
+ vp->v_xe = cv->c_xe;
+ vp->v_ye = (cv->c_ys + cv->c_ye) / 2 - 1;
+ vp->v_xoff = cv->c_xoff;
+ vp->v_yoff = cv->c_yoff;
+ vp->v_next = cv->c_vplist;
+ cv->c_vplist = vp;
+
+ if ((vp = (struct viewport *)malloc(sizeof *vp)) == 0)
+ return -1;
+ vp->v_canvas = cv;
+ vp->v_xs = cv->c_xs;
+ vp->v_ys = (3 * cv->c_ys + cv->c_ye) / 4;
+ vp->v_xe = (3 * cv->c_xs + cv->c_xe) / 4 - 1;
+ vp->v_ye = (cv->c_ys + cv->c_ye) / 2 - 1;
+ vp->v_xoff = cv->c_xoff;
+ vp->v_yoff = cv->c_yoff;
+ vp->v_next = cv->c_vplist;
+ cv->c_vplist = vp;
+
+ if ((vp = (struct viewport *)malloc(sizeof *vp)) == 0)
+ return -1;
+ vp->v_canvas = cv;
+ vp->v_xs = cv->c_xs;
+ vp->v_ys = cv->c_ys;
+ vp->v_xe = cv->c_xe;
+ vp->v_ye = (3 * cv->c_ys + cv->c_ye) / 4 - 1;
+ vp->v_xoff = cv->c_xoff;
+ vp->v_yoff = cv->c_yoff;
+ vp->v_next = cv->c_vplist;
+ cv->c_vplist = vp;
+#else
+ vp->v_canvas = cv;
+ vp->v_xs = cv->c_xs;
+ vp->v_ys = cv->c_ys;
+ vp->v_xe = cv->c_xe;
+ vp->v_ye = cv->c_ye;
+ vp->v_xoff = cv->c_xoff;
+ vp->v_yoff = cv->c_yoff;
+ vp->v_next = cv->c_vplist;
+ cv->c_vplist = vp;
+#endif
+
+ if (cv->c_xs < display->d_vpxmin || display->d_vpxmin == -1)
+ display->d_vpxmin = cv->c_xs;
+ if (cv->c_xe > display->d_vpxmax || display->d_vpxmax == -1)
+ display->d_vpxmax = cv->c_xe;
+ }
+ return 0;
+}
+
+void
+RethinkViewportOffsets(cv)
+struct canvas *cv;
+{
+ struct viewport *vp;
+
+ for (vp = cv->c_vplist; vp; vp = vp->v_next)
+ {
+ vp->v_xoff = cv->c_xoff;
+ vp->v_yoff = cv->c_yoff;
+ }
+}
+
/*
* if the adaptflag is on, we keep the size of this display, else
* we may try to restore our old window sizes.
@@ -336,11 +651,11 @@ int adapt;
if (D_IM && strcmp(D_IM, D_EI))
PutStr(D_EI);
D_insert = 0;
- /* Check for toggle */
#ifdef MAPKEYS
PutStr(D_KS);
PutStr(D_CCS);
#else
+ /* Check for toggle */
if (D_KS && strcmp(D_KS, D_KE))
PutStr(D_KE);
if (D_CCS && strcmp(D_CCS, D_CCE))
@@ -372,16 +687,22 @@ FinitTerm()
if (D_tcinited)
{
ResizeDisplay(D_defwidth, D_defheight);
- DefRestore();
+ InsertMode(0);
+ ChangeScrollRegion(0, D_height - 1);
+ KeypadMode(0);
+ CursorkeysMode(0);
+ CursorVisibility(0);
SetRendition(&mchar_null);
+ SetFlow(FLOW_NOW);
#ifdef MAPKEYS
PutStr(D_KE);
PutStr(D_CCE);
#endif
if (D_hstatus)
- PutStr(D_DS);
+ ShowHStatus((char *)0);
D_x = D_y = -1;
GotoPos(0, D_height - 1);
+ AddChar('\r');
AddChar('\n');
PutStr(D_TE);
}
@@ -389,7 +710,7 @@ FinitTerm()
}
-void
+static void
INSERTCHAR(c)
int c;
{
@@ -444,6 +765,10 @@ int c;
D_lp_missing = 1;
D_rend.image = c;
D_lpchar = D_rend;
+#ifdef KANJI
+ D_lp_mbcs = D_mbcs;
+ D_mbcs = 0;
+#endif
}
/*
@@ -451,20 +776,24 @@ int c;
* NOTE: charset Nr. 0 has a conversion table, but c1, c2, ... don't.
*/
-void
+STATIC void
RAW_PUTCHAR(c)
int c;
{
ASSERT(display);
-#ifdef KANJI
+
+#ifdef FONT
+# ifdef KANJI
if (D_rend.font == KANJI)
{
int t = c;
if (D_mbcs == 0)
{
D_mbcs = c;
+ D_x++;
return;
}
+ D_x--;
if (D_x == D_width - 1)
D_x += D_AM ? 1 : -1;
c = D_mbcs;
@@ -493,11 +822,14 @@ int c;
c |= 0x80;
}
kanjiloop:
-#endif
+# endif
if (D_xtable && D_xtable[(int)(unsigned char)D_rend.font] && D_xtable[(int)(unsigned char)D_rend.font][(int)(unsigned char)c])
AddStr(D_xtable[(int)(unsigned char)D_rend.font][(int)(unsigned char)c]);
else
AddChar(D_rend.font != '0' ? c : D_c0_tab[(int)(unsigned char)c]);
+#else /* FONT */
+ AddChar(c);
+#endif /* FONT */
if (++D_x >= D_width)
{
@@ -520,12 +852,13 @@ int c;
#endif
}
-static void
+static int
PutChar(c)
int c;
{
/* this PutChar for ESC-sequences only (AddChar is a macro) */
AddChar(c);
+ return c;
}
void
@@ -561,7 +894,7 @@ int on;
if (display && on != D_insert && D_IM)
{
D_insert = on;
- if (D_insert)
+ if (on)
PutStr(D_IM);
else
PutStr(D_EI);
@@ -581,7 +914,7 @@ int on;
if (display && D_keypad != on && D_KS)
{
D_keypad = on;
- if (D_keypad)
+ if (on)
PutStr(D_KS);
else
PutStr(D_KE);
@@ -600,7 +933,7 @@ int on;
if (display && D_cursorkeys != on && D_CCS)
{
D_cursorkeys = on;
- if (D_cursorkeys)
+ if (on)
PutStr(D_CCS);
else
PutStr(D_CCE);
@@ -644,11 +977,12 @@ int v;
static int StrCost;
/* ARGSUSED */
-static void
+static int
CountChars(c)
int c;
{
StrCost++;
+ return c;
}
int
@@ -656,14 +990,74 @@ CalcCost(s)
register char *s;
{
ASSERT(display);
- if (!s)
+ if (s)
+ {
+ StrCost = 0;
+ ospeed = D_dospeed;
+ tputs(s, 1, CountChars);
+ return StrCost;
+ }
+ else
return EXPENSIVE;
- StrCost = 0;
- ospeed = D_dospeed;
- tputs(s, 1, CountChars);
- return StrCost;
}
+static int
+CallRewrite(y, xs, xe, doit)
+int y, xs, xe, doit;
+{
+ struct canvas *cv, *cvlist, *cvlnext;
+ struct viewport *vp;
+ struct layer *oldflayer;
+ int cost;
+
+ debug3("CallRewrite %d %d %d\n", y, xs, xe);
+ ASSERT(display);
+ ASSERT(xe >= xs);
+
+ vp = 0;
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ {
+ if (y < cv->c_ys || y > cv->c_ye || xe < cv->c_xs || xs > cv->c_xe)
+ continue;
+ for (vp = cv->c_vplist; vp; vp = vp->v_next)
+ if (y >= vp->v_ys && y <= vp->v_ye && xe >= vp->v_xs && xs <= vp->v_xe)
+ break;
+ if (vp)
+ break;
+ }
+ if (doit)
+ {
+ oldflayer = flayer;
+ flayer = cv->c_layer;
+ cvlist = flayer->l_cvlist;
+ cvlnext = cv->c_lnext;
+ flayer->l_cvlist = cv;
+ cv->c_lnext = 0;
+ Rewrite(y - vp->v_yoff, xs - vp->v_xoff, xe - vp->v_xoff, &D_rend, 1);
+ flayer->l_cvlist = cvlist;
+ cv->c_lnext = cvlnext;
+ flayer = oldflayer;
+ return 0;
+ }
+ if (cv == 0 || cv->c_layer == 0)
+ return EXPENSIVE; /* not found or nothing on it */
+ if (xs < vp->v_xs || xe > vp->v_xe)
+ return EXPENSIVE; /* crosses viewport boundaries */
+ if (y - vp->v_yoff < 0 || y - vp->v_yoff >= cv->c_layer->l_height)
+ return EXPENSIVE; /* line not on layer */
+ if (xs - vp->v_xoff < 0 || xe - vp->v_xoff >= cv->c_layer->l_width)
+ return EXPENSIVE; /* line not on layer */
+ oldflayer = flayer;
+ flayer = cv->c_layer;
+ debug3("Calling Rewrite %d %d %d\n", y - vp->v_yoff, xs - vp->v_xoff, xe - vp->v_xoff);
+ cost = Rewrite(y - vp->v_yoff, xs - vp->v_xoff, xe - vp->v_xoff, &D_rend, 0);
+ flayer = oldflayer;
+ if (D_insert)
+ cost += D_EIcost + D_IMcost;
+ return cost;
+}
+
+
void
GotoPos(x2, y2)
int x2, y2;
@@ -682,16 +1076,20 @@ int x2, y2;
y1 = D_y;
if (x1 == D_width)
- if (D_CLP && D_AM)
- x1 = -1; /* don't know how the terminal treats this */
- else
- x1--;
+ {
+ if (D_CLP && D_AM)
+ x1 = -1; /* don't know how the terminal treats this */
+ else
+ x1--;
+ }
if (x2 == D_width)
x2--;
dx = x2 - x1;
dy = y2 - y1;
if (dy == 0 && dx == 0)
return;
+ debug2("GotoPos (%d,%d)", x1, y1);
+ debug2(" -> (%d,%d)\n", x2, y2);
if (!D_MS) /* Safe to move ? */
SetRendition(&mchar_null);
if (y1 < 0 /* don't know the y position */
@@ -731,7 +1129,7 @@ int x2, y2;
xm = M_RI;
}
/* Speedup: dx <= Rewrite() */
- if (dx < costx && (m = Rewrite(y1, x1, x2, 0)) < costx)
+ if (dx < costx && (m = CallRewrite(y1, x1, x2 - 1, 0)) < costx)
{
costx = m;
xm = M_RW;
@@ -754,7 +1152,7 @@ int x2, y2;
costx = 0;
}
/* Speedup: Rewrite() >= x2 */
- if (x2 + D_CRcost < costx && (m = (x2 ? Rewrite(y1, 0, x2, 0) : 0) + D_CRcost) < costx)
+ if (x2 + D_CRcost < costx && (m = (x2 ? CallRewrite(y1, 0, x2 - 1, 0) : 0) + D_CRcost) < costx)
{
costx = m;
xm = M_CR;
@@ -822,7 +1220,7 @@ int x2, y2;
/* FALLTHROUGH */
case M_RW:
if (x1 < x2)
- (void) Rewrite(y1, x1, x2, 1);
+ (void) CallRewrite(y1, x1, x2 - 1, 1);
break;
default:
break;
@@ -864,7 +1262,12 @@ Clear(x1, y1, xs, xe, x2, y2, uselayfn)
int x1, y1, xs, xe, x2, y2, uselayfn;
{
int y, xxe;
+ struct canvas *cv;
+ struct viewport *vp;
+ debug2("Clear %d,%d", x1, y1);
+ debug2(" %d-%d", xs, xe);
+ debug3(" %d,%d uselayfn=%d\n", x2, y2, uselayfn);
ASSERT(display);
if (x1 == D_width)
x1--;
@@ -924,9 +1327,37 @@ int x1, y1, xs, xe, x2, y2, uselayfn;
continue;
}
if (uselayfn)
- ClearLine(y, x1, xxe);
- else
- DisplayLine(&mline_null, &mline_blank, y, x1, xxe);
+ {
+ vp = 0;
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ {
+ if (y < cv->c_ys || y > cv->c_ye || xxe < cv->c_xs || x1 > cv->c_xe)
+ continue;
+ for (vp = cv->c_vplist; vp; vp = vp->v_next)
+ if (y >= vp->v_ys && y <= vp->v_ye && xxe >= vp->v_xs && x1 <= vp->v_xe)
+ break;
+ if (vp)
+ break;
+ }
+ if (cv && cv->c_layer && x1 >= vp->v_xs && xxe <= vp->v_xe &&
+ y - vp->v_yoff >= 0 && y - vp->v_yoff < cv->c_layer->l_height &&
+ xxe - vp->v_xoff >= 0 && x1 - vp->v_xoff < cv->c_layer->l_width)
+ {
+ struct layer *oldflayer = flayer;
+ struct canvas *cvlist, *cvlnext;
+ flayer = cv->c_layer;
+ cvlist = flayer->l_cvlist;
+ cvlnext = cv->c_lnext;
+ flayer->l_cvlist = cv;
+ cv->c_lnext = 0;
+ ClearLine(y - vp->v_yoff, x1 - vp->v_xoff, xxe - vp->v_xoff);
+ flayer->l_cvlist = cvlist;
+ cv->c_lnext = cvlnext;
+ flayer = oldflayer;
+ continue;
+ }
+ }
+ DisplayLine(&mline_null, &mline_blank, y, x1, xxe);
}
}
@@ -940,9 +1371,19 @@ Redisplay(cur_only)
int cur_only;
{
register int i, stop;
+ struct canvas *cv;
ASSERT(display);
- DefRestore();
+
+ /* XXX do em all? */
+ InsertMode(0);
+ ChangeScrollRegion(0, D_height - 1);
+ KeypadMode(0);
+ CursorkeysMode(0);
+ CursorVisibility(0);
+ SetRendition(&mchar_null);
+ SetFlow(FLOW_NOW);
+
ClearDisplay();
stop = D_height;
i = 0;
@@ -952,15 +1393,32 @@ int cur_only;
stop++;
}
else
- RedisplayLine(-1, 0, D_width - 1, 1);
- for (; i < stop; i++)
- RedisplayLine(i, 0, D_width - 1, 1);
- RefreshStatus();
- Restore();
- SetCursor();
+ {
+ debug("Signalling full refresh!\n");
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ {
+ CV_CALL(cv, RedisplayLine(-1, -1, -1, 1));
+ display = cv->c_display; /* just in case! */
+ }
+ }
+ RefreshArea(0, i, D_width - 1, stop - 1, 1);
+ RefreshHStatus();
+
+ CV_CALL(D_forecv, Restore();SetCursor());
+}
+
+void
+RedisplayDisplays(cur_only)
+int cur_only;
+{
+ struct display *olddisplay = display;
+ for (display = displays; display; display = display->d_next)
+ Redisplay(cur_only);
+ display = olddisplay;
}
+/* XXX: use oml! */
void
ScrollH(y, xs, xe, n, oml)
int y, xs, xe, n;
@@ -1028,7 +1486,7 @@ struct mline *oml;
if (D_lp_missing && y == D_bot)
{
if (n > 0)
- FixLP(D_width - 1 - n, y);
+ WriteLP(D_width - 1 - n, y);
D_lp_missing = 0;
}
}
@@ -1051,9 +1509,9 @@ int xs, ys, xe, ye, n;
Clear(xs, ys, xs, xe, xe, ye, 0);
return;
}
- if (xs != 0 || xe != D_width - 1)
+ if (xs > D_vpxmin || xe < D_vpxmax)
{
- Redisplay(0);
+ RefreshArea(xs, ys, xe, ye, 0);
return;
}
@@ -1080,10 +1538,10 @@ int xs, ys, xe, ye, n;
oldtop = D_top;
oldbot = D_bot;
- if (D_bot != ye)
+ if (ys < D_top || D_bot != ye)
ChangeScrollRegion(ys, ye);
- alok = (D_AL || D_CAL || (ye == D_bot && up));
- dlok = (D_DL || D_CDL || (ye == D_bot && !up));
+ alok = (D_AL || D_CAL || (ys >= D_top && ye == D_bot && up));
+ dlok = (D_DL || D_CDL || (ys >= D_top && ye == D_bot && !up));
if (D_top != ys && !(alok && dlok))
ChangeScrollRegion(ys, ye);
@@ -1091,18 +1549,20 @@ int xs, ys, xe, ye, n;
(oldbot != D_bot ||
(oldbot == D_bot && up && D_top == ys && D_bot == ye)))
{
- FixLP(D_width - 1, oldbot);
+ WriteLP(D_width - 1, oldbot);
if (oldbot == D_bot) /* have scrolled */
{
if (--n == 0)
{
+/* XXX
ChangeScrollRegion(oldtop, oldbot);
+*/
return;
}
}
}
- aldlfaster = (n > 1 && ye == D_bot && ((up && D_CDL) || (!up && D_CAL)));
+ aldlfaster = (n > 1 && ys >= D_top && ye == D_bot && ((up && D_CDL) || (!up && D_CAL)));
if (D_UT)
SetRendition(&mchar_null);
@@ -1144,14 +1604,16 @@ int xs, ys, xe, ye, n;
}
else
{
- Redisplay(0);
+ RefreshArea(xs, ys, xe, ye, 0);
return;
}
if (D_lp_missing && missy != D_bot)
- FixLP(D_width - 1, missy);
+ WriteLP(D_width - 1, missy);
+/* XXX
ChangeScrollRegion(oldtop, oldbot);
if (D_lp_missing && missy != D_bot)
- FixLP(D_width - 1, missy);
+ WriteLP(D_width - 1, missy);
+*/
}
void
@@ -1163,11 +1625,11 @@ register int new;
if (!display || (old = D_rend.attr) == new)
return;
#if defined(TERMINFO) && defined(USE_SGR)
- debug1("USE_SGR defined, sa is %s\n", D_SA ? D_SA : "undefined");
if (D_SA)
{
char *tparm();
SetFont(ASCII);
+ ospeed = D_dospeed;
tputs(tparm(D_SA, new & A_SO, new & A_US, new & A_RV, new & A_BL,
new & A_DI, new & A_BD, 0 , 0 ,
0), 1, PutChar);
@@ -1215,6 +1677,7 @@ register int new;
D_atyp = typ;
}
+#ifdef FONT
void
SetFont(new)
int new;
@@ -1248,6 +1711,7 @@ int new;
else
CPutStr(D_CS0, new);
}
+#endif
#ifdef COLOR
void
@@ -1263,7 +1727,7 @@ int new;
f = new & 0xf;
b = (new >> 4) & 0xf;
- if (!D_CAX && ((f == 0 && f != of) || (b == 0 && b != ob)))
+ if (!D_CAX && (D_CAF || D_CAB) && ((f == 0 && f != of) || (b == 0 && b != ob)))
{
int oattr;
@@ -1297,8 +1761,10 @@ struct mchar *mc;
if (D_rend.color != mc->color)
SetColor(mc->color);
#endif
+#ifdef FONT
if (D_rend.font != mc->font)
SetFont(mc->font);
+#endif
}
void
@@ -1314,8 +1780,10 @@ int x;
if (D_rend.color != ml->color[x])
SetColor(ml->color[x]);
#endif
+#ifdef FONT
if (D_rend.font != ml->font[x])
SetFont(ml->font[x]);
+#endif
}
void
@@ -1331,6 +1799,8 @@ char *msg;
if (!D_tcinited)
{
debug("tc not inited, just writing msg\n");
+ if (D_processinputdata)
+ return; /* XXX: better */
AddStr(msg);
AddStr("\r\n");
Flush();
@@ -1346,9 +1816,16 @@ char *msg;
max = D_WS;
if (D_status)
{
+ /* same message? */
+ if (strcmp(msg, D_status_lastmsg) == 0)
+ {
+ debug("same message - increase timeout");
+ SetTimeout(&D_statusev, MsgWait * 1000);
+ return;
+ }
if (!D_status_bell)
{
- ti = time((time_t *) 0) - D_status_time;
+ ti = time((time_t *)0) - D_status_time;
if (ti < MsgMinWait)
sleep(MsgMinWait - ti);
}
@@ -1360,144 +1837,228 @@ char *msg;
else if ((unsigned char)*s >= ' ' && *s != 0177)
*t++ = *s;
*t = '\0';
- if (t > msg)
+ if (t == msg)
+ return;
+ if (t - msg >= D_status_buflen)
{
- if (t - msg >= D_status_buflen)
- {
- char *buf;
- if (D_status_lastmsg)
- buf = realloc(D_status_lastmsg, t - msg + 1);
- else
- buf = malloc(t - msg + 1);
- if (buf)
- {
- D_status_lastmsg = buf;
- D_status_buflen = t - msg + 1;
- }
- }
- if (t - msg < D_status_buflen)
- strcpy(D_status_lastmsg, msg);
- D_status = 1;
- D_status_len = t - msg;
- D_status_lastx = D_x;
- D_status_lasty = D_y;
- if (!use_hardstatus || !D_HS)
+ char *buf;
+ if (D_status_lastmsg)
+ buf = realloc(D_status_lastmsg, t - msg + 1);
+ else
+ buf = malloc(t - msg + 1);
+ if (buf)
{
- debug1("using STATLINE %d\n", STATLINE);
- GotoPos(0, STATLINE);
- SetRendition(&mchar_so);
- InsertMode(0);
- AddStr(msg);
- D_x = -1;
+ D_status_lastmsg = buf;
+ D_status_buflen = t - msg + 1;
}
- else
+ }
+ if (t - msg < D_status_buflen)
+ strcpy(D_status_lastmsg, msg);
+ D_status_len = t - msg;
+ D_status_lastx = D_x;
+ D_status_lasty = D_y;
+ if (!use_hardstatus || D_has_hstatus == HSTATUS_IGNORE || D_has_hstatus == HSTATUS_MESSAGE)
+ {
+ if (D_status_delayed != -1 && t - msg < D_status_buflen)
{
- debug("using HS\n");
- SetRendition(&mchar_null);
- InsertMode(0);
- if (D_hstatus)
- PutStr(D_DS);
- CPutStr(D_TS, 0);
- AddStr(msg);
- PutStr(D_FS);
- D_hstatus = 1;
+ D_status_delayed = 1; /* not yet... */
+ D_status = 0;
+ return;
}
- Flush();
- (void) time(&D_status_time);
+ D_status = STATUS_ON_WIN;
+ debug1("using STATLINE %d\n", STATLINE);
+ GotoPos(0, STATLINE);
+ SetRendition(&mchar_so);
+ InsertMode(0);
+ AddStr(msg);
+ if (D_status_len < max)
+ {
+ /* Wayne Davison: add extra space for readability */
+ D_status_len++;
+ SetRendition(&mchar_null);
+ AddChar(' ');
+ if (D_status_len < max)
+ {
+ D_status_len++;
+ AddChar(' ');
+ AddChar('\b');
+ }
+ AddChar('\b');
+ }
+ D_x = -1;
}
+ else
+ {
+ D_status = STATUS_ON_HS;
+ ShowHStatus(msg);
+ }
+ D_status_delayed = 0;
+ Flush();
+ (void) time(&D_status_time);
+ SetTimeout(&D_statusev, MsgWait * 1000);
+ evenq(&D_statusev);
+#ifdef HAVE_BRAILLE
+ RefreshBraille(); /* let user see multiple Msg()s */
+#endif
}
void
RemoveStatus()
{
- struct win *p;
+ struct display *olddisplay;
+ struct layer *oldflayer;
+ int where;
if (!display)
return;
- if (!D_status)
+ if (!(where = D_status))
return;
- /*
- * UGLY HACK ALERT - this should NOT be in display.c
- * We need to find the window that caused an activity or bell
- * message, to reenable this function there.
- */
- for (p = windows; p; p = p->w_next)
- {
- if (p->w_display != display)
- continue;
- if (p->w_monitor == MON_MSG)
- {
- debug1("RemoveStatus clearing monitor win %d\n", p->w_number);
- p->w_monitor = MON_DONE;
- }
- if (p->w_bell == BELL_MSG)
- {
- debug1("RemoveStatus clearing bell win %d\n", p->w_number);
- p->w_bell = BELL_DONE;
- }
- }
D_status = 0;
D_status_bell = 0;
- if (!use_hardstatus || !D_HS)
+ evdeq(&D_statusev);
+ olddisplay = display;
+ oldflayer = flayer;
+ if (where == STATUS_ON_WIN)
{
GotoPos(0, STATLINE);
RefreshLine(STATLINE, 0, D_status_len - 1, 0);
GotoPos(D_status_lastx, D_status_lasty);
}
else
+ RefreshHStatus();
+ flayer = D_forecv->c_layer;
+ if (flayer)
+ SetCursor();
+ display = olddisplay;
+ flayer = oldflayer;
+}
+
+/* refresh the display's hstatus line */
+void
+ShowHStatus(str)
+char *str;
+{
+ int l, i, ox, oy;
+
+ if (D_status == STATUS_ON_WIN && D_has_hstatus == HSTATUS_LASTLINE && STATLINE == D_height-1)
+ return; /* sorry, in use */
+
+ if (D_HS && D_has_hstatus == HSTATUS_HS)
{
- /*
+ if (!D_hstatus && (str == 0 || *str == 0))
+ return;
+ debug("ShowHStatus: using HS\n");
SetRendition(&mchar_null);
+ InsertMode(0);
if (D_hstatus)
- PutStr(D_DS);
- */
- RefreshStatus();
+ PutStr(D_DS);
+ D_hstatus = 0;
+ if (str == 0 || *str == 0)
+ return;
+ CPutStr(D_TS, 0);
+ if (strlen(str) > D_WS)
+ AddStrn(str, D_WS);
+ else
+ AddStr(str);
+ PutStr(D_FS);
+ D_hstatus = 1;
+ }
+ else if (D_has_hstatus == HSTATUS_LASTLINE)
+ {
+ debug("ShowHStatus: using last line\n");
+ ox = D_x;
+ oy = D_y;
+ str = str ? str : "";
+ l = strlen(str);
+ if (l > D_width)
+ l = D_width;
+ GotoPos(0, D_height - 1);
+ SetRendition(captionalways || D_cvlist == 0 || D_cvlist->c_next ? &mchar_null: &mchar_so);
+ for (i = 0; i < l; i++)
+ PUTCHARLP(str[i]);
+ if (!captionalways && D_cvlist && !D_cvlist->c_next)
+ while (l++ < D_width)
+ PUTCHARLP(' ');
+ if (l < D_width)
+ Clear(l, D_height - 1, l, D_width - 1, D_width - 1, D_height - 1, 0);
+ if (ox != -1 && oy != -1)
+ GotoPos(ox, oy);
+ D_hstatus = *str ? 1 : 0;
+ SetRendition(&mchar_null);
+ }
+ else if (str && *str && D_has_hstatus == HSTATUS_MESSAGE)
+ {
+ debug("ShowHStatus: using message\n");
+ Msg(0, "%s", str);
}
- SetCursor();
}
+
/*
- * Refreshes the harstatus of the _window_. Shouldn't be here...
+ * Refreshes the harstatus of the fore window. Shouldn't be here...
*/
-
void
-RefreshStatus()
+RefreshHStatus()
{
char *buf;
- if (D_HS)
+ evdeq(&D_hstatusev);
+ if (D_status == STATUS_ON_HS)
+ return;
+ buf = MakeWinMsgEv(hstatusstring, D_fore, '%', &D_hstatusev);
+ if (buf && *buf)
{
- SetRendition(&mchar_null);
- if (D_hstatus)
- PutStr(D_DS);
- if (D_fore && D_fore->w_hstatus)
- {
- buf = MakeWinMsg(D_fore->w_hstatus, D_fore, '\005');
- CPutStr(D_TS, 0);
- if (strlen(buf) > D_WS)
- AddStrn(buf, D_WS);
- else
- AddStr(buf);
- PutStr(D_FS);
- D_hstatus = 1;
- }
+ ShowHStatus(buf);
+ if (D_has_hstatus != HSTATUS_IGNORE && D_hstatusev.timeout.tv_sec)
+ evenq(&D_hstatusev);
}
- else if (D_fore && D_fore->w_hstatus)
+ else
+ ShowHStatus((char *)0);
+}
+
+/*********************************************************************/
+/*
+ * Here come the routines that refresh an arbitrary part of the screen.
+ */
+
+void
+RefreshArea(xs, ys, xe, ye, isblank)
+int xs, ys, xe, ye, isblank;
+{
+ int y;
+ ASSERT(display);
+ debug2("Refresh Area: %d,%d", xs, ys);
+ debug3(" - %d,%d (isblank=%d)\n", xe, ye, isblank);
+ if (!isblank && xs == 0 && xe == D_width - 1 && ye == D_height - 1 && (ys == 0 || D_CD))
{
- buf = MakeWinMsg(D_fore->w_hstatus, D_fore, '\005');
- Msg(0, "%s", buf);
+ Clear(xs, ys, xs, xe, xe, ye, 0);
+ isblank = 1;
}
+ for (y = ys; y <= ye; y++)
+ RefreshLine(y, xs, xe, isblank);
}
void
RefreshLine(y, from, to, isblank)
int y, from, to, isblank;
{
+ struct viewport *vp, *lvp;
+ struct canvas *cv, *lcv, *cvlist, *cvlnext;
+ struct layer *oldflayer;
+ int xx, yy;
+ char *buf;
+ struct win *p;
+
ASSERT(display);
+
debug2("RefreshLine %d %d", y, from);
debug2(" %d %d\n", to, isblank);
- if (isblank == 0 && D_CE && to == D_width - 1)
+
+ if (D_status == STATUS_ON_WIN && y == STATLINE)
+ return; /* can't refresh status */
+
+ if (isblank == 0 && D_CE && to == D_width - 1 && from < to)
{
GotoPos(from, y);
if (D_UT)
@@ -1505,17 +2066,129 @@ int y, from, to, isblank;
PutStr(D_CE);
isblank = 1;
}
- RedisplayLine(y, from, to, isblank);
+ while (from <= to)
+ {
+ lcv = 0;
+ lvp = 0;
+ for (cv = display->d_cvlist; cv; cv = cv->c_next)
+ {
+ if (y < cv->c_ys || y > cv->c_ye || to < cv->c_xs || from > cv->c_xe)
+ continue;
+ debug2("- canvas hit: %d %d", cv->c_xs, cv->c_ys);
+ debug2(" %d %d\n", cv->c_xe, cv->c_ye);
+ for (vp = cv->c_vplist; vp; vp = vp->v_next)
+ {
+ debug2(" - vp: %d %d", vp->v_xs, vp->v_ys);
+ debug2(" %d %d\n", vp->v_xe, vp->v_ye);
+ /* find leftmost overlapping vp */
+ if (y >= vp->v_ys && y <= vp->v_ye && from <= vp->v_xe && to >= vp->v_xs && (lvp == 0 || lvp->v_xs > vp->v_xs))
+ {
+ lcv = cv;
+ lvp = vp;
+ }
+ }
+ }
+ if (lvp == 0)
+ break;
+ if (from < lvp->v_xs)
+ {
+ if (!isblank)
+ DisplayLine(&mline_null, &mline_blank, y, from, lvp->v_xs - 1);
+ from = lvp->v_xs;
+ }
+
+ /* call RedisplayLine on canvas lcv viewport lvp */
+ yy = y - lvp->v_yoff;
+ xx = to < lvp->v_xe ? to : lvp->v_xe;
+
+ if (lcv->c_layer && yy == lcv->c_layer->l_height)
+ {
+ GotoPos(from, y);
+ SetRendition(&mchar_blank);
+ while (from <= lvp->v_xe && from - lvp->v_xoff < lcv->c_layer->l_width)
+ {
+ PUTCHARLP('-');
+ from++;
+ }
+ if (from >= lvp->v_xe + 1)
+ continue;
+ }
+ if (lcv->c_layer == 0 || yy >= lcv->c_layer->l_height || from - lvp->v_xoff >= lcv->c_layer->l_width)
+ {
+ if (!isblank)
+ DisplayLine(&mline_null, &mline_blank, y, from, lvp->v_xe);
+ from = lvp->v_xe + 1;
+ continue;
+ }
+
+ if (xx - lvp->v_xoff >= lcv->c_layer->l_width)
+ xx = lcv->c_layer->l_width + lvp->v_xoff - 1;
+ oldflayer = flayer;
+ flayer = lcv->c_layer;
+ cvlist = flayer->l_cvlist;
+ cvlnext = lcv->c_lnext;
+ flayer->l_cvlist = lcv;
+ lcv->c_lnext = 0;
+ RedisplayLine(yy, from - lvp->v_xoff, xx - lvp->v_xoff, isblank);
+ flayer->l_cvlist = cvlist;
+ lcv->c_lnext = cvlnext;
+ flayer = oldflayer;
+
+ from = xx + 1;
+ }
+ if (from > to)
+ return; /* all done */
+
+ if (y == D_height - 1 && D_has_hstatus == HSTATUS_LASTLINE)
+ {
+ RefreshHStatus();
+ return;
+ }
+
+ for (cv = display->d_cvlist; cv; cv = cv->c_next)
+ if (y == cv->c_ye + 1)
+ break;
+ if (cv == 0)
+ {
+ if (!isblank)
+ DisplayLine(&mline_null, &mline_blank, y, from, to);
+ return;
+ }
+
+ p = Layer2Window(cv->c_layer);
+ buf = MakeWinMsgEv(captionstring, p, '%', &cv->c_captev);
+ if (cv->c_captev.timeout.tv_sec)
+ evenq(&cv->c_captev);
+ xx = strlen(buf);
+ GotoPos(from, y);
+ SetRendition(&mchar_so);
+ while (from <= to && from < xx)
+ {
+ PUTCHARLP(buf[from]);
+ from++;
+ }
+ while (from++ <= to)
+ PUTCHARLP(' ');
}
-void
-FixLP(x2, y2)
-register int x2, y2;
+/*********************************************************************/
+
+/* clear lp_missing by writing the char on the screen. The
+ * position must be safe.
+ */
+static void
+WriteLP(x2, y2)
+int x2, y2;
{
struct mchar oldrend;
ASSERT(display);
+ ASSERT(D_lp_missing);
oldrend = D_rend;
+#ifdef KANJI
+ if (D_lpchar.font == KANJI && (D_mbcs = D_lp_mbcs) != 0 && x2 > 0)
+ x2--;
+#endif
GotoPos(x2, y2);
SetRendition(&D_lpchar);
PUTCHAR(D_lpchar.image);
@@ -1536,29 +2209,42 @@ int from, to, y;
ASSERT(from >= 0 && from < D_width);
ASSERT(to >= 0 && to < D_width);
if (!D_CLP && y == D_bot && to == D_width - 1)
- if (D_lp_missing || !cmp_mline(oml, ml, to))
- {
- if ((D_IC || D_IM) && from < to)
- {
- to -= 2;
- last2flag = 1;
- D_lp_missing = 0;
- }
- else
- {
- to--;
- delete_lp = (D_CE || D_DC || D_CDC);
- D_lp_missing = !cmp_mchar_mline(&mchar_blank, ml, to);
- copy_mline2mchar(&D_lpchar, ml, to);
- }
- }
- else
- to--;
+ {
+ if (D_lp_missing || !cmp_mline(oml, ml, to))
+ {
+ if ((D_IC || D_IM) && from < to)
+ {
+ to -= 2;
+ last2flag = 1;
+ D_lp_missing = 0;
+ }
+ else
+ {
+ to--;
+ delete_lp = (D_CE || D_DC || D_CDC);
+ D_lp_missing = !cmp_mchar_mline(&mchar_blank, ml, to);
+ copy_mline2mchar(&D_lpchar, ml, to);
+ }
+ }
+ else
+ to--;
+ }
+#ifdef KANJI
+ if (D_mbcs)
+ {
+ /* finish kanji (can happen after a wrap) */
+ SetRenditionMline(ml, from);
+ PUTCHAR(ml->image[from]);
+ from++;
+ }
+#endif
for (x = from; x <= to; x++)
{
+#if 0 /* no longer needed */
if (x || D_x != D_width || D_y != y - 1)
+#endif
{
- if (x < to || x != D_width - 1 || ml->image[x + 1] == ' ')
+ if (x < to || x != D_width - 1 || ml->image[x + 1])
if (cmp_mline(oml, ml, x))
continue;
GotoPos(x, y);
@@ -1567,8 +2253,11 @@ int from, to, y;
if (badkanji(ml->font, x))
{
x--;
+ debug1("DisplayLine badkanji - x now %d\n", x);
GotoPos(x, y);
}
+ if (ml->font[x] == KANJI && x == to)
+ break; /* don't start new kanji */
#endif
SetRenditionMline(ml, x);
PUTCHAR(ml->image[x]);
@@ -1577,8 +2266,11 @@ int from, to, y;
PUTCHAR(ml->image[++x]);
#endif
}
- if (to == D_width - 1 && y < D_height - 1 && ml->image[to + 1] == ' ')
+#if 0 /* not needed any longer */
+ /* compare != 0 because ' ' can happen when clipping occures */
+ if (to == D_width - 1 && y < D_height - 1 && D_x == D_width && ml->image[to + 1])
GotoPos(0, y + 1);
+#endif
if (last2flag)
{
GotoPos(x, y);
@@ -1591,9 +2283,7 @@ int from, to, y;
else if (delete_lp)
{
if (D_UT)
- {
- SetRendition(&mchar_null);
- }
+ SetRendition(&mchar_null);
if (D_DC)
PutStr(D_DC);
else if (D_CDC)
@@ -1604,12 +2294,118 @@ int from, to, y;
}
void
-SetLastPos(x,y)
-int x,y;
+InsChar(c, x, xe, y, oml)
+struct mchar *c;
+int x, xe, y;
+struct mline *oml;
{
- ASSERT(display);
- D_x = x;
+ GotoPos(x, y);
+ if (y == D_bot && !D_CLP)
+ {
+ if (x == D_width - 1)
+ {
+ D_lpchar = *c;
+ return;
+ }
+ if (xe == D_width - 1)
+ D_lp_missing = 0;
+ }
+ if (x == xe)
+ {
+ if (xe != D_width - 1)
+ InsertMode(0);
+ SetRendition(c);
+ RAW_PUTCHAR(c->image);
+ return;
+ }
+ if (!(D_IC || D_CIC || D_IM) || xe != D_width - 1)
+ {
+ RefreshLine(y, x, xe, 0);
+ GotoPos(x + 1, y);
+ /* UpdateLine(oml, y, x, xe); */
+ return;
+ }
+ InsertMode(1);
+ if (!D_insert)
+ {
+ if (D_IC)
+ PutStr(D_IC);
+ else
+ CPutStr(D_CIC, 1);
+ }
+ SetRendition(c);
+ RAW_PUTCHAR(c->image);
+}
+
+void
+WrapChar(c, x, y, xs, ys, xe, ye, ins)
+struct mchar *c;
+int x, y;
+int xs, ys, xe, ye;
+int ins;
+{
+ debug("WrapChar:");
+ debug2(" x %d y %d", x, y);
+ debug2(" Dx %d Dy %d", D_x, D_y);
+ debug2(" xs %d ys %d", xs, ys);
+ debug3(" xe %d ye %d ins %d\n", xe, ye, ins);
+ if (xs != 0 || x != D_width || !D_AM)
+ {
+ if (y == ye)
+ ScrollV(xs, ys, xe, ye, 1);
+ else if (y < D_height - 1)
+ y++;
+ GotoPos(xs, y);
+ if (ins)
+ {
+ InsChar(c, xs, xe, y, 0);
+ return;
+ }
+ SetRendition(c);
+ RAW_PUTCHAR(c->image);
+ return;
+ }
+ if (y == ye) /* we have to scroll */
+ {
+ debug("- scrolling\n");
+ ChangeScrollRegion(ys, ye);
+ if (D_bot != y)
+ {
+ debug("- have to call ScrollV\n");
+ ScrollV(xs, ys, xe, ye, 1);
+ y--;
+ }
+ }
+ else if (y == D_bot)
+ ChangeScrollRegion(ys, ye); /* remove unusable region */
+ if (D_x != D_width || D_y != y)
+ {
+ if (D_CLP && y >= 0) /* don't even try if !LP */
+ RefreshLine(y, D_width - 1, D_width - 1, 0);
+ debug2("- refresh last char -> x,y now %d,%d\n", D_x, D_y);
+ if (D_x != D_width || D_y != y) /* sorry, no bonus */
+ {
+ if (y == ye)
+ ScrollV(xs, ys, xe, ye, 1);
+ GotoPos(xs, y == ye || y == D_height - 1 ? y : y + 1);
+ }
+ }
+ debug("- writeing new char");
+ if (y != ye && y < D_height - 1)
+ y++;
+ if (ins != D_insert)
+ InsertMode(ins);
+ if (ins && !D_insert)
+ {
+ InsChar(c, 0, xe, y, 0);
+ debug2(" -> done with insert (%d,%d)\n", D_x, D_y);
+ return;
+ }
+ SetRendition(c);
D_y = y;
+ D_x = 0;
+ RAW_PUTCHAR(c->image);
+ debug2(" -> done (%d,%d)\n", D_x, D_y);
}
int
@@ -1623,6 +2419,13 @@ int wi, he;
debug("ResizeDisplay: No change\n");
return 0;
}
+ if (D_width != wi && (D_height == he || !D_CWS) && D_CZ0 && (wi == Z0width || wi == Z1width))
+ {
+ debug("ResizeDisplay: using Z0/Z1\n");
+ PutStr(wi == Z0width ? D_CZ0 : D_CZ1);
+ ChangeScreenSize(wi, D_height, 0);
+ return (he == D_height) ? 0 : -1;
+ }
if (D_CWS)
{
debug("ResizeDisplay: using WS\n");
@@ -1630,13 +2433,6 @@ int wi, he;
ChangeScreenSize(wi, he, 0);
return 0;
}
- else if (D_CZ0 && (wi == Z0width || wi == Z1width))
- {
- debug("ResizeDisplay: using Z0/Z1\n");
- PutStr(wi == Z0width ? D_CZ0 : D_CZ1);
- ChangeScreenSize(wi, D_height, 0);
- return (he == D_height) ? 0 : -1;
- }
return -1;
}
@@ -1646,6 +2442,10 @@ int newtop, newbot;
{
if (display == 0)
return;
+ if (newtop == -1)
+ newtop = 0;
+ if (newbot == -1)
+ newbot = D_height - 1;
if (D_CS == 0)
{
D_top = 0;
@@ -1663,73 +2463,6 @@ int newtop, newbot;
/*
- * Layer creation / removal
- */
-
-int
-InitOverlayPage(datasize, lf, block)
-int datasize;
-struct LayFuncs *lf;
-int block;
-{
- char *data;
- struct layer *newlay;
-
- RemoveStatus();
- debug3("Entering new layer display %#x D_fore %#x oldlay %#x\n",
- (unsigned int)display, (unsigned int)D_fore, (unsigned int)D_lay);
- if ((newlay = (struct layer *)malloc(sizeof(struct layer))) == 0)
- {
- Msg(0, "No memory for layer struct");
- return -1;
- }
- data = 0;
- if (datasize)
- {
- if ((data = malloc(datasize)) == 0)
- {
- free((char *)newlay);
- Msg(0, "No memory for layer data");
- return -1;
- }
- bzero(data, datasize);
- }
- newlay->l_layfn = lf;
- newlay->l_block = block | D_lay->l_block;
- newlay->l_data = data;
- newlay->l_next = D_lay;
- if (D_fore)
- {
- D_fore->w_lay = newlay; /* XXX: CHECK */
- D_fore->w_active = 0; /* XXX: CHECK */
- }
- D_lay = newlay;
- D_layfn = newlay->l_layfn;
- Restore();
- return 0;
-}
-
-void
-ExitOverlayPage()
-{
- struct layer *oldlay;
-
- debug3("Exiting layer display %#x fore %#x D_lay %#x\n",
- (unsigned int)display, (unsigned int)D_fore, (unsigned int)D_lay);
- oldlay = D_lay;
- if (oldlay->l_data)
- free(oldlay->l_data);
- D_lay = oldlay->l_next;
- D_layfn = D_lay->l_layfn;
- free((char *)oldlay);
- if (D_fore)
- D_fore->w_lay = D_lay; /* XXX: Is this necessary ? */
- Restore();
- SetCursor();
-}
-
-
-/*
* Output buffering routines
*/
@@ -1740,6 +2473,7 @@ char *str;
register char c;
ASSERT(display);
+
while ((c = *str++))
AddChar(c);
}
@@ -1796,6 +2530,8 @@ Flush()
}
D_obuffree += l;
D_obufp = D_obuf;
+ if (D_nonblock > 1)
+ D_nonblock = 1; /* reenable flow control for WriteString */
if (fcntl(D_userfd, F_SETFL, FNBLOCK))
debug1("Warning: NBLOCK fcntl failed: %d\n", errno);
}
@@ -1813,6 +2549,7 @@ freetty()
free(D_obuf);
D_obuf = 0;
D_obuflen = 0;
+ D_obuflenmax = -D_obufmax;
}
/*
@@ -1843,6 +2580,7 @@ Resize_obuf()
if (!D_obuf)
Panic(0, "Out of memory");
D_obufp = D_obuf + ind;
+ D_obuflenmax = D_obuflen - D_obufmax;
debug1("ResizeObuf: resized to %d\n", D_obuflen);
}
@@ -1879,10 +2617,13 @@ NukePending()
PutStr(D_ME);
else
{
+#ifdef COLOR
+ if (D_CAF)
+ AddStr("\033[m"); /* why is D_ME not set? */
+#endif
PutStr(D_SE);
PutStr(D_UE);
}
- /* FIXME: reset color! */
/* Check for toggle */
if (D_IM && strcmp(D_IM, D_EI))
PutStr(D_EI);
@@ -1933,11 +2674,163 @@ char *f;
int x;
{
int i, j;
- if (f[x] != KANJI)
+
+ f += x;
+ if (*f-- != KANJI)
return 0;
- for (i = j = 0; i < x; i++)
- if (*f++ == KANJI)
- j ^= 1;
+ for (j = 0, i = x - 1; i >= 0; i--, j ^= 1)
+ if (*f-- != KANJI)
+ break;
return j;
}
#endif
+
+static void
+disp_writeev_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ int len, size = OUTPUT_BLOCK_SIZE;
+
+ display = (struct display *)data;
+ len = D_obufp - D_obuf;
+ if (len < size)
+ size = len;
+ ASSERT(len >= 0);
+ size = write(D_userfd, D_obuf, size);
+ if (size >= 0)
+ {
+ len -= size;
+ if (len)
+ {
+ bcopy(D_obuf + size, D_obuf, len);
+ debug2("ASYNC: wrote %d - remaining %d\n", size, len);
+ }
+ /* Great, reenable flow control for WriteString now. */
+ if ((D_nonblock > 1) && (len < D_obufmax/2))
+ D_nonblock = 1;
+ D_obufp -= size;
+ D_obuffree += size;
+ }
+ else
+ {
+ if (errno != EINTR)
+# ifdef EWOULDBLOCK
+ if (errno != EWOULDBLOCK)
+# endif
+ Msg(errno, "Error writing output to display");
+ }
+}
+
+static void
+disp_readev_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ int size;
+ char buf[IOSIZE];
+ struct canvas *cv;
+
+ display = (struct display *)data;
+
+ /* Hmmmm... a bit ugly... */
+ if (D_forecv)
+ for (cv = D_forecv->c_layer->l_cvlist; cv; cv = cv->c_lnext)
+ {
+ display = cv->c_display;
+ if (D_status == STATUS_ON_WIN)
+ RemoveStatus();
+ }
+
+ display = (struct display *)data;
+ if (D_fore == 0)
+ size = IOSIZE;
+ else
+ {
+#ifdef PSEUDOS
+ if (W_UWP(D_fore))
+ size = sizeof(D_fore->w_pwin->p_inbuf) - D_fore->w_pwin->p_inlen;
+ else
+#endif
+ size = sizeof(D_fore->w_inbuf) - D_fore->w_inlen;
+ }
+
+ if (size > IOSIZE)
+ size = IOSIZE;
+ if (size <= 0)
+ size = 1; /* Always allow one char for command keys */
+
+ size = read(D_userfd, buf, size);
+ if (size < 0)
+ {
+ if (errno == EINTR)
+ return;
+ debug1("Read error: %d - SigHup()ing!\n", errno);
+ SigHup(SIGARG);
+ sleep(1);
+ return;
+ }
+ else if (size == 0)
+ {
+ debug("Found EOF - SigHup()ing!\n");
+ SigHup(SIGARG);
+ sleep(1);
+ return;
+ }
+ (*D_processinput)(buf, size);
+}
+
+static void
+disp_status_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ display = (struct display *)data;
+ if (D_status)
+ RemoveStatus();
+}
+
+static void
+disp_hstatus_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ display = (struct display *)data;
+ RefreshHStatus();
+}
+
+static void
+cv_winid_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ int ox, oy;
+ struct canvas *cv = (struct canvas *)data;
+
+ display = cv->c_display;
+ ox = D_x;
+ oy = D_y;
+ if (cv->c_ye + 1 < D_height)
+ RefreshLine(cv->c_ye + 1, 0, D_width - 1, 0);
+ if (ox != -1 && oy != -1)
+ GotoPos(ox, oy);
+}
+
+#ifdef MAPKEYS
+static void
+disp_map_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ char *p;
+ int l;
+ display = (struct display *)data;
+ debug("Flushing map sequence\n");
+ if (!(l = D_seql))
+ return;
+ p = D_seqp - l;
+ D_seqp = D_kmaps[0].seq;
+ D_seql = 0;
+ ProcessInput2(p, l);
+}
+#endif
diff --git a/display.h b/display.h
index 87d0944..eef58b4 100644
--- a/display.h
+++ b/display.h
@@ -22,7 +22,6 @@
* $Id: display.h,v 1.9 1994/05/31 12:31:54 mlschroe Exp $ FAU
*/
-
#ifdef MAPKEYS
struct kmap
{
@@ -44,15 +43,48 @@ struct kmap
struct win; /* forward declaration */
+struct canvas
+{
+ struct canvas *c_next; /* next canvas on display */
+ struct display *c_display; /* back pointer to display */
+ struct viewport *c_vplist;
+ struct layer *c_layer; /* layer on this canvas */
+ struct canvas *c_lnext; /* next canvas that displays layer */
+ struct layer c_blank; /* bottom layer, always blank */
+ int c_xoff; /* canvas x offset on display */
+ int c_yoff; /* canvas y offset on display */
+ int c_xs;
+ int c_xe;
+ int c_ys;
+ int c_ye;
+ struct event c_captev; /* caption changed event */
+};
+
+struct viewport
+{
+ struct viewport *v_next; /* next vp on canvas */
+ struct canvas *v_canvas; /* back pointer to canvas */
+ int v_xoff; /* layer x offset on display */
+ int v_yoff; /* layer y offset on display */
+ int v_xs; /* vp upper left */
+ int v_xe; /* vp upper right */
+ int v_ys; /* vp lower left */
+ int v_ye; /* vp lower right */
+};
+
struct display
{
struct display *d_next; /* linked list */
struct user *d_user; /* user who owns that display */
- struct LayFuncs *d_layfn; /* current layer functions */
- struct layer *d_lay; /* layers on the display */
+ struct canvas *d_cvlist; /* the canvases of this display */
+ struct canvas *d_forecv; /* current input focus */
+ void (*d_processinput) __P((char *, int));
+ char *d_processinputdata; /* data for processinput */
+ int d_vpxmin, d_vpxmax; /* min/max used position on display */
struct win *d_fore; /* pointer to fore window */
struct win *d_other; /* pointer to other window */
- char d_nonblock; /* don't block when d_obufmax reached */
+ char d_nonblock; /* 1: don't block if obufmax reached */
+ /* 2: obufmax is reached, discard */
char d_termname[20 + 1]; /* $TERM */
char *d_tentry; /* buffer for tgetstr */
char d_tcinited; /* termcap inited flag */
@@ -65,33 +97,41 @@ struct display
#ifdef KANJI
int d_mbcs; /* saved char for multibytes charset */
int d_kanji; /* what kanji type the display is */
+ int d_lp_mbcs; /* mbcs part of lp_missing */
#endif
int d_insert; /* insert mode flag */
int d_keypad; /* application keypad flag */
int d_cursorkeys; /* application cursorkeys flag */
int d_revvid; /* reverse video */
int d_curvis; /* cursor visibility */
+ int d_has_hstatus; /* display has hardstatus line */
int d_hstatus; /* hardstatus used */
int d_lp_missing; /* last character on bot line missing */
struct mchar d_lpchar; /* missing char */
time_t d_status_time; /* time of status display */
- char d_status; /* is status displayed? */
+ int d_status; /* is status displayed? */
char d_status_bell; /* is it only a vbell? */
int d_status_len; /* length of status line */
char *d_status_lastmsg; /* last displayed message */
int d_status_buflen; /* last message buffer len */
int d_status_lastx; /* position of the cursor */
int d_status_lasty; /* before status was displayed */
+ int d_status_delayed; /* status not displayed yet */
+ struct event d_statusev; /* timeout event */
+ struct event d_hstatusev; /* hstatus changed event */
int d_ESCseen; /* Was the last char an ESC (^a) */
int d_userpid; /* pid of attacher */
char d_usertty[MAXPATHLEN]; /* tty we are attached to */
int d_userfd; /* fd of the tty */
+ struct event d_readev; /* userfd read event */
+ struct event d_writeev; /* userfd write event */
struct mode d_OldMode; /* tty mode when screen was started */
struct mode d_NewMode; /* New tty mode */
int d_flow; /* tty's flow control on/off flag*/
char *d_obuf; /* output buffer */
int d_obuflen; /* len of buffer */
int d_obufmax; /* len where we are blocking the pty */
+ int d_obuflenmax; /* len - max */
char *d_obufp; /* pointer in buffer */
int d_obuffree; /* free bytes in buffer */
#ifdef AUTO_NUKE
@@ -101,7 +141,7 @@ struct display
int d_nseqs; /* number of valid mappings */
char *d_seqp; /* pointer into keymap array */
int d_seql; /* number of parsed chars */
- int d_seqruns; /* number of select calls */
+ struct event d_mapev; /* timeout event */
int d_dontmap; /* do not map next */
int d_mapdefault; /* do map next to default */
struct kmap d_kmaps[KMAP_KEYS+KMAP_EXT]; /* keymaps */
@@ -110,14 +150,17 @@ struct display
char *d_attrtab[NATTR]; /* attrib emulation table */
char d_attrtyp[NATTR]; /* attrib group table */
short d_dospeed; /* baudrate of tty */
+#ifdef FONT
char d_c0_tab[256]; /* conversion for C0 */
char ***d_xtable; /* char translation table */
+#endif
int d_UPcost, d_DOcost, d_LEcost, d_NDcost;
int d_CRcost, d_IMcost, d_EIcost, d_NLcost;
int d_printfd; /* fd for vt100 print sequence */
#ifdef UTMPOK
slot_t d_loginslot; /* offset, where utmp_logintty belongs */
struct utmp d_utmp_logintty; /* here the original utmp structure is stored */
+ int d_loginttymode;
# ifdef _SEQUENT_
char d_loginhost[100+1];
# endif /* _SEQUENT_ */
@@ -133,8 +176,12 @@ extern struct display TheDisplay;
#define D_user DISPLAY(d_user)
#define D_username (DISPLAY(d_user) ? DISPLAY(d_user)->u_name : 0)
-#define D_layfn DISPLAY(d_layfn)
-#define D_lay DISPLAY(d_lay)
+#define D_cvlist DISPLAY(d_cvlist)
+#define D_forecv DISPLAY(d_forecv)
+#define D_processinput DISPLAY(d_processinput)
+#define D_processinputdata DISPLAY(d_processinputdata)
+#define D_vpxmin DISPLAY(d_vpxmin)
+#define D_vpxmax DISPLAY(d_vpxmax)
#define D_fore DISPLAY(d_fore)
#define D_other DISPLAY(d_other)
#define D_nonblock DISPLAY(d_nonblock)
@@ -153,11 +200,13 @@ extern struct display TheDisplay;
#define D_atyp DISPLAY(d_atyp)
#define D_mbcs DISPLAY(d_mbcs)
#define D_kanji DISPLAY(d_kanji)
+#define D_lp_mbcs DISPLAY(d_lp_mbcs)
#define D_insert DISPLAY(d_insert)
#define D_keypad DISPLAY(d_keypad)
#define D_cursorkeys DISPLAY(d_cursorkeys)
#define D_revvid DISPLAY(d_revvid)
#define D_curvis DISPLAY(d_curvis)
+#define D_has_hstatus DISPLAY(d_has_hstatus)
#define D_hstatus DISPLAY(d_hstatus)
#define D_lp_missing DISPLAY(d_lp_missing)
#define D_lpchar DISPLAY(d_lpchar)
@@ -169,6 +218,9 @@ extern struct display TheDisplay;
#define D_status_buflen DISPLAY(d_status_buflen)
#define D_status_lastx DISPLAY(d_status_lastx)
#define D_status_lasty DISPLAY(d_status_lasty)
+#define D_status_delayed DISPLAY(d_status_delayed)
+#define D_statusev DISPLAY(d_statusev)
+#define D_hstatusev DISPLAY(d_hstatusev)
#define D_ESCseen DISPLAY(d_ESCseen)
#define D_userpid DISPLAY(d_userpid)
#define D_usertty DISPLAY(d_usertty)
@@ -179,13 +231,13 @@ extern struct display TheDisplay;
#define D_obuf DISPLAY(d_obuf)
#define D_obuflen DISPLAY(d_obuflen)
#define D_obufmax DISPLAY(d_obufmax)
+#define D_obuflenmax DISPLAY(d_obuflenmax)
#define D_obufp DISPLAY(d_obufp)
#define D_obuffree DISPLAY(d_obuffree)
#define D_auto_nuke DISPLAY(d_auto_nuke)
#define D_nseqs DISPLAY(d_nseqs)
#define D_seqp DISPLAY(d_seqp)
#define D_seql DISPLAY(d_seql)
-#define D_seqruns DISPLAY(d_seqruns)
#define D_dontmap DISPLAY(d_dontmap)
#define D_mapdefault DISPLAY(d_mapdefault)
#define D_kmaps DISPLAY(d_kmaps)
@@ -206,17 +258,50 @@ extern struct display TheDisplay;
#define D_printfd DISPLAY(d_printfd)
#define D_loginslot DISPLAY(d_loginslot)
#define D_utmp_logintty DISPLAY(d_utmp_logintty)
+#define D_loginttymode DISPLAY(d_loginttymode)
#define D_loginhost DISPLAY(d_loginhost)
+#define D_readev DISPLAY(d_readev)
+#define D_writeev DISPLAY(d_writeev)
+#define D_mapev DISPLAY(d_mapev)
-#define GRAIN 4096 /* Allocation grain size for output buffer */
-#define OBUF_MAX 256 /* default for obuflimit */
+#define GRAIN 4096 /* Allocation grain size for output buffer */
+#define OBUF_MAX 256 /* default for obuflimit */
#define OUTPUT_BLOCK_SIZE 256 /* Block size of output to tty */
-#define AddChar(c) do { \
- if (--D_obuffree == 0) \
- Resize_obuf(); \
- *D_obufp++ = (c); \
-} while (0)
+#define AddChar(c) \
+do \
+ { \
+ if (--D_obuffree == 0) \
+ Resize_obuf(); \
+ *D_obufp++ = (c); \
+ } \
+while (0)
+
+#define CV_CALL(cv, cmd) \
+{ \
+ struct display *olddisplay = display; \
+ struct layer *oldflayer = flayer; \
+ struct layer *l = cv->c_layer; \
+ struct canvas *cvlist = l->l_cvlist; \
+ struct canvas *cvlnext = cv->c_lnext; \
+ flayer = l; \
+ l->l_cvlist = cv; \
+ cv->c_lnext = 0; \
+ cmd; \
+ flayer = oldflayer; \
+ l->l_cvlist = cvlist; \
+ cv->c_lnext = cvlnext; \
+ display = olddisplay; \
+}
+
+#define STATUS_OFF 0
+#define STATUS_ON_WIN 1
+#define STATUS_ON_HS 2
+#define HSTATUS_IGNORE 0
+#define HSTATUS_LASTLINE 1
+#define HSTATUS_MESSAGE 2
+#define HSTATUS_HS 3
+#define HSTATUS_ALWAYS (1<<2)
diff --git a/doc/Makefile.in b/doc/Makefile.in
index 74dcc37..f42a3ca 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -3,9 +3,9 @@
srcdir = @srcdir@
VPATH = @srcdir@
-prefix = /usr/local
-mandir = $(prefix)/man
-infodir = $(prefix)/info
+prefix = @prefix@
+mandir = @mandir@
+infodir = @infodir@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
diff --git a/doc/README.DOTSCREEN b/doc/README.DOTSCREEN
new file mode 100644
index 0000000..f17fa37
--- /dev/null
+++ b/doc/README.DOTSCREEN
@@ -0,0 +1,151 @@
+From bargi@dots.physics.orst.edu Thu Aug 31 23:42 MET 1995
+Received: from faui45.informatik.uni-erlangen.de (root@faui45.informatik.uni-erlangen.de [131.188.34.45]) by immd4.informatik.uni-erlangen.de with ESMTP
+ id XAA14775 (8.6.12/7.4f-FAU);; Thu, 31 Aug 1995 23:42:15 +0200
+Received: from dots.physics.orst.edu (bargi@dots.PHYSICS.ORST.EDU [128.193.96.106]) by uni-erlangen.de with ESMTP
+ id XAA03048 (8.6.12/7.4f-FAU); for <screen@uni-erlangen.de>; Thu, 31 Aug 1995 23:42:03 +0200
+Received: (from bargi@localhost) by dots.physics.orst.edu (8.6.11/8.6.9) id OAA15627; Thu, 31 Aug 1995 14:41:47 -0700
+From: Hadi Bargi Rangin <bargi@dots.physics.orst.edu>
+Message-Id: <199508312141.OAA15627@dots.physics.orst.edu>
+Subject: README.DOTSCREEN
+To: screen@uni-erlangen.de
+Date: Thu, 31 Aug 1995 14:41:47 -0700 (PDT)
+Cc: bargi@dots.physics.orst.edu (Hadi Bargi Rangin)
+X-Mailer: ELM [version 2.4 PL24]
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Content-Type: text/plain; charset=US-ASCII
+Content-Length: 5423
+Status: RO
+
+Hallo,
+
+ leider war readme file fuer dotscreen nicht in unserem dotscreen-Packet,
+deshalb schicke ich es Euch nachtraeglich. Nachdem Ihr unseren packet
+getestet habt, koennen wir Euch anrufen und vielleicht mehr ueber die
+Einzelnheiten sprechen, ob wir unsere Weiterentwicklung koordinieren
+wollen.
+
+Danke,
+
+Gruss,
+Hadi
+
+===============================================================================
+Quick introduction to dotscreen
+-------------------------------
+
+1. Introduction
+2. Is dotscreen different as screen?
+3. Installation instructions
+4. Functions description
+5. Further development
+
+
+1. Introduction
+===============
+
+Dotscreen, is a system which allow a person direct access to unix via
+a braille display. The emphasis is on direct, because the braille
+display is connected directly to the serial port on the unix
+machine. You no longer must use a dos machine running a terminal
+emulation logged into a unix machine. Dotscreen is built on top of
+screen, a powerful full-screen window manager for unix tty terminals.
+Screen keeps track of what is being displayed in each window that it
+is managing so that it can easily switch back and forth between these
+windows. Dotscreen makes this stored window information available via
+a braille display. Dotscreen only allows access to tty terminal
+sessions, it does not allow access to X-Windows, however, it will run
+in an xterm window. Currently, it works with the TSI Navigator 40 and
+the TSI PowerBraille 40 braille displays. We plan to support other
+displays as demand and information about other displays is made
+available to us
+
+2. Is dotscreen different than screen?
+======================================
+
+All of screens functions still work in dotscreen. A few of the
+functions are not accessible via braille, but we expect to remedy that
+in future releases.
+
+3. Installation instructions
+============================
+
+Please read the INSTALL file for full installation instructions.
+In addition to those instructions, note that you must create
+a .screenrc file and that file must contain the type of braille
+display that you are using and the serial device that the display
+is connected to. A minimal .screenrc file should contain something
+like the following four lines, (these are only examples, please
+customize them for your configuration)
+
+
+# example of .screenrc when using braille display
+bd_start_braille on
+bd_type powerbraille_40
+bd_port /dev/ttyS0
+bd_braille_table /home/gardner/us-braille.tbl
+# end of example
+
+
+4. Functions description
+========================
+
+The basic operation of screen is described in README. The braille
+navigation commands are similar to commands usually found on dos
+braille screenreaders. Also, because dotscreen is built on top of
+screen, the user can switch back and forth easily between many running
+applications. The braille commands can be changed any time after
+starting screen using the internal screen "C-a :" command line. All
+braille commands begin with "bd_"; following is the list of braille
+commands:
+
+bd_start_braille on/off # Starts/stops using braille features on screen
+bd_link on/off # links/unlinks braille cursor to/from screen cursor
+bd_bell on/off # turn on/off sending bell-signal to terminal
+bd_scroll on/off # enables/disables scrolling
+bd_skip on/off # skip/don't skip balnk lines
+bd_width <integer-value> # number of braille cells that user want to use,
+ # this value is always <= total number of cells
+bd_ncrc <interger-value> # number of cells displayed on the right side
+ # of physical cursor (default = 1)
+bd_info <integer-value> # displays braille/screen cursor position
+ # depending on its value, (no info: 0, only
+ # bc-info: 1, only sc-info: 2, bc- and sc-info: 3
+bd_port <serial-device> # serial port which braille display is connected to
+bd_braille_table <bl-table> # braille table to be used. German, US and GS
+ # braille tables are provided
+bd_type <braille-display-type>
+ # braille display type being used
+
+Note: currently valid value for some parameters:
+bd_type:
+ 1. navigator_40
+ 2. powerbraille_40.
+
+bd_braille_table:
+ 1. gr-braille.tbl German braille code
+ 2. us-braille.tbl US computer braille code
+ 3. gs-braille.tbl GS braille code
+
+Since the braille tables are in files, you should give the full
+pathnames of the files either in .screenrc or using the
+internal screen "C-a :" command line.
+
+5. Further development
+======================
+
+As mentioned above, currently Dotscreen works with Telesensory braille
+displays the PowerBraille and the Navigator because Telesensory has
+given us the information needed to program their braille display. We
+plan to add support for other braille displays when and if we get the
+requisite information from the braille display manufacturer.
+Also some things such as cursor navigation from the braille display
+have not been implemented. If you find a feature missing that
+you wish to have, please contact us.
+
+This software has been developed within the Science Access Project at
+Oregon State University under the direction of John Gardner.
+
+Authors: Hadi Bargi Rangin (bargi@dots.physics.orst.edu)
+ Bill Barry (barryb@dots.physics.orst.edu)
+
diff --git a/doc/install.sh b/doc/install.sh
index 8c07c50..3f44f99 100755..120000
--- a/doc/install.sh
+++ b/doc/install.sh
@@ -1,119 +1 @@
-#! /bin/sh
-
-#
-# install - install a program, script, or datafile
-# This comes from X11R5; it is not part of GNU.
-#
-# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch.
-#
-
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
-
-
-# put in absolute paths if you don't have them in your path; or use env. vars.
-
-mvprog="${MVPROG-mv}"
-cpprog="${CPPROG-cp}"
-chmodprog="${CHMODPROG-chmod}"
-chownprog="${CHOWNPROG-chown}"
-chgrpprog="${CHGRPPROG-chgrp}"
-stripprog="${STRIPPROG-strip}"
-rmprog="${RMPROG-rm}"
-
-instcmd="$mvprog"
-chmodcmd=""
-chowncmd=""
-chgrpcmd=""
-stripcmd=""
-rmcmd="$rmprog -f"
-mvcmd="$mvprog"
-src=""
-dst=""
-
-while [ x"$1" != x ]; do
- case $1 in
- -c) instcmd="$cpprog"
- shift
- continue;;
-
- -m) chmodcmd="$chmodprog $2"
- shift
- shift
- continue;;
-
- -o) chowncmd="$chownprog $2"
- shift
- shift
- continue;;
-
- -g) chgrpcmd="$chgrpprog $2"
- shift
- shift
- continue;;
-
- -s) stripcmd="$stripprog"
- shift
- continue;;
-
- *) if [ x"$src" = x ]
- then
- src=$1
- else
- dst=$1
- fi
- shift
- continue;;
- esac
-done
-
-if [ x"$src" = x ]
-then
- echo "install: no input file specified"
- exit 1
-fi
-
-if [ x"$dst" = x ]
-then
- echo "install: no destination specified"
- exit 1
-fi
-
-
-# If destination is a directory, append the input filename; if your system
-# does not like double slashes in filenames, you may need to add some logic
-
-if [ -d $dst ]
-then
- dst="$dst"/`basename $src`
-fi
-
-# Make a temp file name in the proper directory.
-
-dstdir=`dirname $dst`
-dsttmp=$dstdir/#inst.$$#
-
-# Move or copy the file name to the temp name
-
-$doit $instcmd $src $dsttmp
-
-# and set any options; do chmod last to preserve setuid bits
-
-if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi
-if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi
-if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi
-if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi
-
-# Now rename the file to the real destination.
-
-$doit $rmcmd $dst
-$doit $mvcmd $dsttmp $dst
-
-
-exit 0
+../install.sh \ No newline at end of file
diff --git a/doc/make.help b/doc/make.help
new file mode 100644
index 0000000..5871773
--- /dev/null
+++ b/doc/make.help
@@ -0,0 +1,51 @@
+######
+######
+###### The following lines should be obsolete because of the 'configure' script.
+###### It is here only for reference if 'configure' needs human help.
+######
+
+
+### If you choose to compile with the tried and true:
+#CC= cc
+#CFLAGS= -O
+#CFLAGS= -g
+### gcc specific CFLAGS:
+#CC= gcc
+# If your system include files are bad, don't use -Wall
+#CFLAGS= -O6 -g #-Wall
+#CFLAGS = -g -fstrength-reduce -fcombine-regs -finline-functions #-Wall
+
+### On some machines special CFLAGS are required:
+#M_CFLAGS=
+#M_CFLAGS= -D__NetBSD__ # NetBsd Machines like this (a.kalb@rrze)
+#M_CFLAGS= -Dapollo -A cpu,mathchip -A nansi # Apollo DN3000/4000/4500
+#M_CFLAGS= -DISC -D_POSIX_SOURCE # isc
+#M_CFLAGS= -systype bsd43 -DMIPS # mips
+#M_CFLAGS= -fforce-mem -fforce-addr\
+# -fomit-frame-pointer -finline-functions -bsd # NeXT
+#M_CFLAGS= -qlanglvl=ansi # RS6000/AIX
+#M_CFLAGS= -qlanglvl=ansi -D_AIX32 # RS6000/AIX 3.2
+#M_CFLAGS= -ansi # sgi/IRIX 3.x ansi
+#M_CFLAGS= -xansi # sgi/IRIX 4.x ext ansi
+#M_CFLAGS= -YBSD # Ultrix 4.x
+#M_CFLAGS= -DSVR4=1 # Bob Kline rvk@blink.att.com 80386 Unix SVR4.0
+#M_CFLAGS= -D_CX_UX # Ken Beal kbeal@amber.ssd.csd.harris.com Harris CX/UX
+#M_CFLAGS= -K pentium # Thanh Ma tma@encore.com Unixware, SVR4-2
+
+### Choose one of the LIBS setting below:
+#LIBS= -ltermcap -lc -lsocket -linet -lsec -lseq # Sequent/ptx
+#LIBS= -lcurses -lelf -lcrypt -lsocket -lnsl # Solaris, when it sucks
+#LIBS= -ltermcap # SunOS, Linux, Apollo,
+# gould_np1, NeXT, Ultrix
+#LIBS= -ltermcap -lelf # SVR4
+#LIBS= -ltermlib -linet -lcposix # isc
+#LIBS= -ltermcap -lmld # mips (nlist is in mld)
+#LIBS= -ltermlib -lsun -lmld #-lc_s # sgi/IRIX
+#LIBS= -lcurses # RS6000/AIX
+#LIBS= -lcrypt_d -ltinfo # sco32
+#LIBS= -lcrypt_i -ltinfo # sco32
+#LIBS= -lcrypt -lsec # sco322 (msilano@sra.com)
+#LIBS= -ltermcap -lcrypt.o -ldir -lx # SCO XENIX 2.3.4
+#LIBS= -ltermcap -lcrypt -ldir -l2.3 -lx # SCO UNIX XENIX cross dev.
+#LIBS= -ltermcap -lelf -lcrypt -lsocket -lnet -lnsl # Bob Kline SVR4
+#LIBS= -lcurses -lelf -lcrypt -lgen # Thanh Ma, Unixware, SVR4-2
diff --git a/doc/screen.1 b/doc/screen.1
index d30e94e..74c35d4 100644
--- a/doc/screen.1
+++ b/doc/screen.1
@@ -1,5 +1,5 @@
.\" vi:set wm=5
-.TH SCREEN 1 "15 Oct 1995"
+.TH SCREEN 1 "10 Jun 1999"
.if n .ds Q \&"
.if n .ds U \&"
.if t .ds Q ``
@@ -20,7 +20,10 @@ screen \- screen manager with VT100/ANSI terminal emulation
] ]
.br
.B screen \-r
-[ [\fIpid.\fP]\fItty\fP[\fI.host\fP] ]
+[[\fIpid\fP\fB.\fP]\fItty\fP[\fB.\fP\fIhost\fP]]
+.br
+.B screen \-r
+\fIsessionowner\fP\fB/\fP[[\fIpid\fP\fB.\fP]\fItty\fP[\fB.\fP\fIhost\fP]]
.ta .5i 1.8i
@@ -31,7 +34,7 @@ multiplexes a physical terminal between several processes (typically
interactive shells).
Each virtual terminal provides the functions
of a DEC VT100 terminal and, in addition, several control functions
-from the ANSI X3.64 (ISO 6429) and ISO 2022 standards
+from the ISO 6492 (ECMA 48, ANSI X3.64) and ISO 2022 standards
(e.\|g. insert/delete line and support for multiple character sets).
There is a scrollback history buffer for each virtual terminal and a
copy-and-paste mechanism that allows moving text regions between
@@ -46,8 +49,11 @@ Then, at any time, you can create new (full-screen) windows with other programs
in them (including more shells), kill existing windows, view a list of
windows, turn output logging on and off, copy-and-paste text between
windows, view the scrollback history, switch between windows
-in whatever manner you wish, etc.
-When a program terminates,
+in whatever manner you wish, etc. All windows run their programs completely
+independent of each other. Programs continue to run when their window
+is currently not visible and even when the whole
+.I screen
+session is detached from the user's terminal. When a program terminates,
.I screen
(per default) kills the window that contained it.
If this window was in the foreground, the display switches to the previous
@@ -63,6 +69,17 @@ now on), and is followed by one other keystroke.
The command character and all the key bindings can be fully customized
to be anything you like, though they are always two characters in length.
.PP
+.I Screen
+does not understand the prefix \*QC-\*U to mean control.
+Please use the caret notation (\*Q^A\*U instead of \*QC-a\*U) as arguments
+to e.g. the
+.I escape
+command or the
+.I -e
+option.
+.I Screen
+will also print out control characters in caret notation.
+.PP
The standard way to create a new window is to type \*QC-a c\*U.
This creates a new window running a shell and switches to that
window immediately, regardless of the state of the process running
@@ -120,8 +137,9 @@ automatic margins turned \fIoff\fP. This will ensure an accurate and
optimal update of the screen in all circumstances. Most terminals
nowadays have \*Qmagic\*U margins (automatic margins plus usable last
column). This is the VT100 style type and perfectly suited for
-\fIscreen\fP.
-If all you've got is a \*Qtrue\*U auto-margin terminal \fIscreen\fP
+.IR screen .
+If all you've got is a \*Qtrue\*U auto-margin terminal
+.I screen
will be content to use it, but updating a character put into the last
position on the screen may not be possible until the screen scrolls or
the character is moved into a safe position in some other way. This
@@ -155,12 +173,34 @@ does not start
but detaches the elsewhere running
.I screen
session. It has the same effect as typing \*QC-a d\*U from
-.I screen's
+.IR screen 's
controlling terminal. \fB\-D\fP is the equivalent to the power detach key.
-If no session can be detached, this option is ignored.
-The combination \*Qscreen \-D \-r\*U can be used to `transport' the elsewhere
-running session to this terminal and logout there.
-Note: It is a good idea to have the status of your sessions checked by means of
+If no session can be detached, this option is ignored. In combination with the
+\fB\-r\fP/\fB\-R\fP option more powerful effects can be achieved:
+.TP 8
+.B \-d \-r
+Reattach a session and if necessary detach it first.
+.TP 8
+.B \-d \-R
+Reattach a session and if necessary detach or even create it first.
+.TP 8
+.B \-d \-RR
+Reattach a session and if necessary detach or create it. Use the first
+session if more than one session is available.
+.TP 8
+.B \-D \-r
+Reattach a session. If necessary detach and logout remotely first.
+.TP 8
+.B \-D \-R
+Attach here and now. In detail this means: If a session is running, then
+reattach. If necessary detach and logout remotely first.
+If it was not running create it and notify the user. This is the
+author's favorite.
+.TP 8
+.B \-D \-RR
+Attach here and now. Whatever that means, just do it.
+.IP "" 5
+Note: It is always a good idea to check the status of your sessions by means of
\*Qscreen \-list\*U.
.TP 5
.BI "\-e " xy
@@ -202,17 +242,22 @@ strings identifying your
.I screen
sessions.
Sessions marked `detached' can be resumed with \*Qscreen -r\*U. Those marked
-`attached' are running and have a controlling terminal. Sessions marked as
-`dead' should be thoroughly checked and removed. Ask your system administrator
-if you are not sure. Remove sessions with the \fB-wipe\fP option.
+`attached' are running and have a controlling terminal. If the session runs in
+multiuser mode, it is marked `multi'. Sessions marked as `unreachable' either
+live on a different host or are `dead'.
+An unreachable session is considered dead, when its name
+matches either the name of the local host, or the specified parameter, if any.
+See the \fB-r\fP flag for a description how to construct matches.
+Sessions marked as `dead' should be thoroughly checked and removed.
+Ask your system administrator if you are not sure. Remove sessions with the
+\fB-wipe\fP option.
.TP 5
.B \-L
tells
.I screen
your auto-margin terminal has a writable last-position on
-the screen.
-This can also be set in your .screenrc by specifying `LP' in a \*Qtermcap\*U
-command.
+the screen. This can also be set in your .screenrc by specifying `LP' in a
+\*Qtermcap\*U command.
.TP 5
.B \-m
causes
@@ -222,7 +267,18 @@ a new session is enforced, regardless whether
.I screen
is called from within another
.I screen
-session or not.
+session or not. This flag has a special meaning in connection
+with the `-d' option:
+.TP 8
+.B \-m \-d
+Start
+.I screen
+in \*Qdetached\*U mode. This creates a new session but doesn't
+attach to it. This is useful for system startup scripts.
+.TP 8
+.B \-m \-D
+This also starts screen in \*Qdetached\*U mode, but doesn't fork
+a new process. The command exits if the session terminates.
.TP 5
.B \-O
selects a more optimal output mode for your terminal rather than true VT100
@@ -230,27 +286,42 @@ emulation (only affects auto-margin terminals without `LP').
This can also be set in your .screenrc by specifying `OP' in a \*Qtermcap\*U
command.
.TP 5
+.B \-q
+Suppress printing of error messages. In combination with \*Q-ls\*U the exit
+value is as follows: 9 indicates a directory without sessions. 10
+indicates a directory with running but not attachable sessions. 11 (or more)
+indicates 1 (or more) usable sessions.
+In combination with \*Q-r\*U the exit value is as follows: 10 indicates that
+there is no session to resume. 12 (or more) indicates that there are 2 (or
+more) sessions to resume and you should specify which one to choose.
+In all other cases \*Q-q\*U has no effect.
+.TP 5
.BR \-r " [" \fIpid.tty.host ]
+.PD 0
+.TP 5
+.BR \-r " \fIsessionowner/[" \fIpid.tty.host ]
+.PD
resumes a detached
.I screen
-session.
-No other options (except \*Q-d -r\*U or \*Q-D -r\*U) may be specified, though
-an optional prefix of [\fIpid.\fP]\fItty.host\fP
+session. No other options (except combinations with \fB\-d\fP/\fB\-D\fP) may
+be specified, though an optional prefix of [\fIpid.\fP]\fItty.host\fP
may be needed to distinguish between multiple detached
.I screen
-sessions.
+sessions. The second form is used to connect to another user's screen session
+which runs in multiuser mode. This indicates that screen should look for
+sessions in another user's directory. This requires setuid-root.
.TP 5
.B \-R
attempts to resume the first detached
.I screen
-session it finds.
-If successful, all other command-line options are ignored.
+session it finds. If successful, all other command-line options are ignored.
If no detached session exists, starts a new session using the specified
options, just as if
.B \-R
had not been specified. The option is set by default if
.I screen
is run as a login-shell.
+For combinations with the \fB\-d\fP/\fB\-D\fP option see there.
.TP 5
.B \-s
sets the default shell to the program specified, instead of the value
@@ -270,9 +341,12 @@ See also the \*Qshelltitle\*U .screenrc command.
.B \-v
Print version number.
.TP 5
-.B \-wipe
+.BR \-wipe " [" \fImatch ]
does the same as \*Qscreen -ls\*U, but removes destroyed sessions instead of
marking them as `dead'.
+An unreachable session is considered dead, when its name matches either
+the name of the local host, or the explicitly given parameter, if any.
+See the \fB-r\fP flag for a description how to construct matches.
.TP 5
.B \-x
Attach to a not detached
@@ -303,13 +377,17 @@ Prompt for a window name or number to switch to.
.PD 0
.IP "\fB ... \fP ..."
.IP "\fBC-a 9\fP (select 9)"
+.IP "\fBC-a -\fP (select -)"
+.PD
+Switch to window number 0 \- 9, or to the blank window.
+.IP "\fBC-a tab\fP (focus)"
.PD
-Switch to window number 0 \- 9.
+Switch the input focus to the next region.
.IP "\fBC-a C-a\fP (other)"
Toggle to the window displayed previously.
Note that this binding defaults to the command character typed twice,
-unless overridden; for instance, if you use the option \*Q\fB\-e]x\fP\*U,
-this command becomes \*Q]]\*U, not \*Q]C-a\*U.
+unless overridden. For instance, if you use the option \*Q\fB\-e]x\fP\*U,
+this command becomes \*Q]]\*U.
.IP "\fBC-a a\fP (meta)"
Send the command character (C-a) to window. See \fIescape\fP command.
.IP "\fBC-a A\fP (title)"
@@ -342,6 +420,8 @@ Detach and logout.
.IP "\fBC-a C-f\fP (flow)"
.PD
Toggle flow \fIon\fP, \fIoff\fP or \fIauto\fP.
+.IP "\fBC-a F\fP (fit)"
+Resize the window to the current region size.
.IP "\fBC-a C-g\fP (vbell)"
Toggles
.I screen's
@@ -397,6 +477,8 @@ Switch to the previous window (opposite of \fBC-a n\fP).
.IP "\fBC-a C-q\fP (xon)"
.PD
Send a control-q to the current window.
+.IP "\fBC-a Q\fP (only)"
+Delete all regions but the current one.
.IP "\fBC-a r\fP"
.PD 0
.IP "\fBC-a C-r\fP (wrap)"
@@ -408,6 +490,8 @@ automatic margins on and off).
.IP "\fBC-a C-s\fP (xoff)"
.PD
Send a control-s to the current window.
+.IP "\fBC-a S\fP (split)"
+Split the current region into two new ones.
.IP "\fBC-a t\fP"
.PD 0
.IP "\fBC-a C-t\fP (time)"
@@ -431,6 +515,8 @@ Toggle 80/132 columns.
.IP "\fBC-a C-x\fP (lockscreen)"
.PD
Lock this terminal.
+.IP "\fBC-a X\fP (remove)"
+Kill the current region.
.IP "\fBC-a z\fP"
.PD 0
.IP "\fBC-a C-z\fP (suspend)"
@@ -458,7 +544,7 @@ Enter copy/scrollback mode.
.IP "\fBC-a ]\fP (paste .)"
.PD
Write the contents of the paste buffer to the stdin queue of the
-current window.
+current window.
.IP "\fBC-a {\fP
.PD 0
.IP "\fBC-a }\fP (history)"
@@ -476,6 +562,8 @@ Shows where
comes from, where it went to and why you can use it.
.IP "\fBC-a _\fP (silence)"
Start/stop monitoring the current window for inactivity.
+.IP "\fBC-a *\fP (displays)"
+Show a listing of all currently attached displays.
.SH CUSTOMIZATION
@@ -487,7 +575,7 @@ should compile
.I screen
with an adequate (not NFS mounted) socket directory. If
.I screen
-is not running setuid-root, the user can specify any mode 777 directory
+is not running setuid-root, the user can specify any mode 700 directory
in the environment variable $SCREENDIR.
.PP
When
@@ -496,12 +584,12 @@ is invoked, it executes initialization commands from the files
\*Q/usr/local/etc/screenrc\*U and
\*Q.screenrc\*U in the user's home directory. These are the \*Qprogrammer's
defaults\*U that can be overridden in the following ways: for the
-global screenrc file
+global screenrc file
.I screen
searches for the environment variable $SYSSCREENRC (this override feature
may be disabled at compile-time). The user specific
-screenrc file is searched in $ISCREENRC, then $SCREENRC, then $HOME/.iscreenrc
-and finally defaults to $HOME/.screenrc. The command line option \fB-c\fP takes
+screenrc file is searched in $SCREENRC, then $HOME/.screenrc.
+The command line option \fB-c\fP takes
precedence over the above user screenrc files.
.PP
Commands in these files are used to set options, bind functions to
@@ -514,51 +602,66 @@ A command's arguments are separated by tabs or spaces, and may be
surrounded by single or double quotes.
A `#' turns the rest of the line into a comment, except in quotes.
Unintelligible lines are warned about and ignored.
-Commands may contain references to environment variables. The
-syntax is the shell-like "$VAR " or "${VAR}". Note that this causes
-incompatibility with previous
+Commands may contain references to environment variables. The
+syntax is the shell-like "$VAR " or "${VAR}". Note that this causes
+incompatibility with previous
.I screen
versions, as now the '$'-character has to be protected with '\e' if no
variable substitution shall be performed. A string in single-quotes is also
protected from variable substitution.
.PP
+Two configuration files are shipped as examples with your screen distribution:
+\*Qetc/screenrc\*U and \*Qetc/etcscreenrc\*U. They contain a number of
+useful examples for various commands.
+.PP
Customization can also be done 'on-line'. To enter the command mode type
`C-a :'. Note that commands starting with \*Qdef\*U change default values,
while others change current settings.
.PP
The following commands are available:
-.sp
+.sp
.ne 3
.BI acladd " usernames"
+.RI [ crypted-pw ]
+.br
+.BI addacl " usernames"
.PP
Enable users to fully access this screen session. \fIUsernames\fP can be one
-user or a comma seperated list of users. This command enables to attach to the
+user or a comma separated list of users. This command enables to attach to the
.I screen
session and performs the equivalent of `aclchg \fIusernames\fP +rwx \&"#?\&"'.
executed. To add a user with restricted access, use the `aclchg' command below.
+If an optional second parameter is supplied, it should be a crypted password
+for the named user(s). `Addacl' is a synonym to `acladd'.
Multi user mode only.
-.sp
+.sp
.ne 3
.BI aclchg " usernames permbits list"
+.br
+.BI chacl " usernames permbits list"
.PP
-Change permissions for a comma seperated list of users. Permission bits are
-represented as `r', `w' and `x'. Prefixing `+' grants the permission, `-'
-removes it. The third parameter is a comma seperated list of commands and/or
-windows (specified either by number or title). The special list `#' refers to
+Change permissions for a comma separated list of users. Permission bits are
+represented as `r', `w' and `x'. Prefixing `+' grants the permission, `-'
+removes it. The third parameter is a comma separated list of commands and/or
+windows (specified either by number or title). The special list `#' refers to
all windows, `?' to all commands. if \fIusernames\fP consists of a single `*',
all known users are affected.
A command can be executed when the user has the `x' bit for it.
The user can type input to a window when he has its `w' bit set and no other
-user obtains a writelock for this window.
-Other bits are currently ignored.
+user obtains a writelock for this window.
+Other bits are currently ignored.
To withdraw the writelock from another user in window 2:
`aclchg \fIusername\fP -w+w 2'.
-To allow readonly access to the session: `aclchg \fIusername\fP
--w \&"#\&"'. As soon as a user's name is known to
-.I screen
-he can attach to the session and (per default) has full permissions for all
+To allow read-only access to the session: `aclchg \fIusername\fP
+-w \&"#\&"'. As soon as a user's name is known to
+.I screen
+he can attach to the session and (per default) has full permissions for all
command and windows. Execution permission for the acl commands, `at' and others
should also be removed or the user may be able to regain write permission.
+Rights of the special username
+.B nobody
+cannot be changed (see the \*Qsu\*U command).
+`Chacl' is a synonym to `aclchg'.
Multi user mode only.
.sp
.ne 3
@@ -571,6 +674,42 @@ user's displays are detached from the session. He cannot attach again.
Multi user mode only.
.sp
.ne 3
+.BI aclgrp " username"
+.RI [ groupname ]
+.PP
+Creates groups of users that share common access rights. The name of the
+group is the username of the group leader. Each member of the group inherits
+the permissions that are granted to the group leader. That means, if a user
+fails an access check, another check is made for the group leader.
+A user is removed from all groups the special value \*Qnone\*U is used for
+.IR groupname .
+If the second parameter is omitted all groups the user is in are listed.
+.sp
+.ne 3
+.B aclumask
+.RI [[ users ] +bits
+.RI |[ users ] -bits " .... ]"
+.B umask
+.RI [[ users ] +bits
+.RI |[ users ] -bits " .... ]"
+.PP
+This specifies the access other users have to windows that will be created by
+the caller of the command.
+.I Users
+may be no, one or a comma separated list of known usernames. If no users are
+specified, a list of all currently known users is assumed.
+.I Bits
+is any combination of access control bits allowed defined with the
+\*Qaclchg\*U command. The special username \*Q?\*U predefines the access
+that not yet known users will be granted to any window initially.
+The special username \*Q??\*U predefines the access that not yet known
+users are granted to any command.
+Rights of the special username
+.B nobody
+cannot be changed (see the \*Qsu\*U command).
+`Umask' is a synonym to `aclumask'.
+.sp
+.ne 3
.BI activity " message"
.PP
When any activity occurs in a background window that is being monitored,
@@ -580,11 +719,11 @@ The notification message can be re-defined by means of the \*Qactivity\*U
command.
Each occurrence of `%' in \fImessage\fP is replaced by
the number of the window in which activity has occurred,
-and each occurrence of `~' is replaced by the definition for bell
+and each occurrence of `^G' is replaced by the definition for bell
in your termcap (usually an audible bell).
The default message is
.sp
- 'Activity in window %'
+ 'Activity in window %n'
.sp
Note that monitoring is off for all windows by default, but can be altered
by use of the \*Qmonitor\*U command (C-a M).
@@ -593,11 +732,11 @@ by use of the \*Qmonitor\*U command (C-a M).
.BR "allpartial on" | off
.PP
If set to on, only the current cursor line is refreshed on window change.
-This affects all windows and is useful for slow terminal lines. The
+This affects all windows and is useful for slow terminal lines. The
previous setting of full/partial refresh for each window is restored
with \*Qallpartial off\*U. This is a global flag that immediately takes effect
on all windows overriding the \*Qpartial\*U settings. It does not change the
-default redraw behaviour of newly created windows.
+default redraw behavior of newly created windows.
.sp
.ne 3
.BR "at " "[\fIidentifier\fP][" "#\fP|\fP*\fP|\fP%\fP] "
@@ -605,34 +744,56 @@ default redraw behaviour of newly created windows.
.PP
Execute a command at other displays or windows as if it had been entered there.
\*QAt\*U changes the context (the `current window' or `current display'
-setting) of the command. If the first parameter describes a
-non-unique context, the command will be executed multiple times. If the first
+setting) of the command. If the first parameter describes a
+non-unique context, the command will be executed multiple times. If the first
parameter is of the form `\fIidentifier\fP*' then identifier is matched against
-user names. The command is executed once for each display of the selected
-user(s). If the first parameter is of the form `\fIidentifier\fP%' identifier
-is matched against displays. Displays are named after the ttys they
+user names. The command is executed once for each display of the selected
+user(s). If the first parameter is of the form `\fIidentifier\fP%' identifier
+is matched against displays. Displays are named after the ttys they
attach. The prefix `/dev/' or `/dev/tty' may be omitted from the identifier.
-If \fIidentifier\fP has a `#' or nothing appended it is matched against
-window numbers and titles. Omitting an identifier in front of the `#', `*' or
+If \fIidentifier\fP has a `#' or nothing appended it is matched against
+window numbers and titles. Omitting an identifier in front of the `#', `*' or
`%'-character selects all users, displays or windows because a prefix-match is
performed. Note that on the affected display(s) a short message will describe
-what happened. Caution: Permission is checked for the owners or the
-affected display(s), not for the initiator of the `at' command.
+what happened. Permission is checked for initiator of the \*Qat\*U command,
+not for the owners of the affected display(s).
+Note that the '#' character works as a comment introducer when it is preceded by
+whitespace. This can be escaped by prefixing a '\e'.
+Permission is checked for the initiator of the \*Qat\*U command, not for the
+owners of the affected display(s).
+.br
+Caveat:
+When matching against windows, the command is executed at least
+once per window. Commands that change the internal arrangement of windows
+(like \*Qother\*U) may be called again. In shared windows the command will
+be repeated for each attached display. Beware, when issuing toggle commands
+like \*Qlogin\*U!
+Some commands (e.g. \*Qstuff\*U, \*Qprocess\*U or \*Qpaste\*U) require that
+a display is associated with the target windows. These commands may not work
+correctly under \*Qat\*U looping over windows.
.sp
.ne 3
.BR "autodetach on" | off
.PP
-Sets whether
+Sets whether
.I screen
will automatically detach upon hangup, which
saves all your running programs until they are resumed with a
.B "screen -r"
command.
-When turned off, a hangup signal will terminate
+When turned off, a hangup signal will terminate
.I screen
and all the processes it contains. Autodetach is on by default.
.sp
.ne 3
+.BR "autofixterm on" | off
+.PP
+Sets whether
+.I screen
+will add missing capabilities to the termcap/info entry. It is on
+by default.
+.sp
+.ne 3
.BR "autonuke on" | off
.PP
Sets whether a clear screen sequence should nuke all the output
@@ -640,26 +801,27 @@ that has not been written to the terminal. See also
\*Qobuflimit\*U.
.sp
.ne 3
-.BI "bell " message
+.B bell_msg
+.RI [ message ]
.PP
When a bell character is sent to a background window,
.I screen
displays a notification in the message line.
-The notification message can be re-defined by means of the \*Qbell\*U
-command.
+The notification message can be re-defined by this command.
Each occurrence of `%' in \fImessage\fP is replaced by
the number of the window to which a bell has been sent,
-and each occurrence of `~' is replaced by the definition for bell
+and each occurrence of `^G' is replaced by the definition for bell
in your termcap (usually an audible bell).
The default message is
.sp
- 'Bell in window %'
+ 'Bell in window %n'
.sp
-An empty message can be supplied to the \*Qbell\*U command to suppress
-output of a message line (bell "").
+An empty message can be supplied to the \*Qbell_msg\*U command to suppress
+output of a message line (bell_msg "").
+Without parameter, the current message is shown.
.sp
.ne 3
-.BI "bind " key
+.BI "bind " key
.RI [ command " [" args ]]
.PP
Bind a command to a key.
@@ -683,17 +845,22 @@ Some examples:
.PP
.nf
bind ' ' windows
+ bind ^k
+ bind k
+ bind K kill
bind ^f screen telnet foobar
bind \e033 screen -ln -t root -h 1000 9 su
.fi
.PP
would bind the space key to the command that displays a list
of windows (so that the command usually invoked by \*QC-a C-w\*U
-would also be available as \*QC-a space\*U),
-bind \*QC-f\*U to the command \*Qcreate a window with a TELNET
+would also be available as \*QC-a space\*U). The next three lines
+remove the default kill binding from \*QC-a C-k\*U and \*QC-a k\*U.
+\*QC-a K\*U is then bound to the kill command. Then it
+binds \*QC-f\*U to the command \*Qcreate a window with a TELNET
connection to foobar\*U, and bind \*Qescape\*U to the command
that creates an non-login window with a.\|k.\|a. \*Qroot\*U in slot #9, with
-a super-user shell and a scrollback buffer of 1000 lines.
+a superuser shell and a scrollback buffer of 1000 lines.
.sp
.ne 3
.B bindkey
@@ -735,15 +902,15 @@ option.
.br
The
.B -t
-option tells screen not to do intercharacter timing. One cannot
-turn off the timing if a termcap capabilty is used.
+option tells screen not to do inter-character timing. One cannot
+turn off the timing if a termcap capability is used.
.br
.I Cmd
can be any of screen's commands with an arbitrary number of
.IR args .
If
.I cmd
-is omitted the keybinding is removed from the table.
+is omitted the key-binding is removed from the table.
.br
Here are some examples of keyboard bindings:
.sp
@@ -761,13 +928,13 @@ Make the "F1" key switch to window one.
.nf
bindkey -t foo stuff barfoo
.fi
-Make "foo" an abrevation of the word "barfoo". Timeout is disabled
+Make "foo" an abbreviation of the word "barfoo". Timeout is disabled
so that users can type slowly.
.sp
.nf
bindkey "\e024" mapdefault
.fi
-This keybinding makes \*Q^T\*U an escape character for keybindings. If
+This key-binding makes \*Q^T\*U an escape character for key-bindings. If
you did the above \*Qstuff barfoo\*U binding, you can enter the word
\*Qfoo\*U by typing \*Q^Tfoo\*U. If you want to insert a \*Q^T\*U
you have to press the key twice (i.e. escape the escape binding).
@@ -783,17 +950,31 @@ escape (besides ^A).
.RI [ duration ]
.PP
Send a break signal for \fIduration\fP*0.25 seconds to this window.
-Most useful if a character device is
-attached to the window rather than a shell process.
+For non-Posix systems the time interval may be rounded up to full seconds.
+Most useful if a character device is attached to the window rather than
+a shell process (See also chapter \*QWINDOW TYPES\*U). The maximum duration of
+a break signal is limited to 15 seconds.
+.sp
+.ne 3
+.B breaktype
+.RI [ tcsendbreak | TIOCSBRK
+.RI | TCSBRK ]
+.PP
+Choose one of the available methods of generating a break signal for
+terminal devices. This command should affect the current window only.
+But it still behaves identical to \*Qdefbreaktype\*U. This will be changed in
+the future.
+Calling \*Qbreaktype\*U with no parameter displays the break method for the
+current window.
.sp
.ne 3
.B bufferfile
.RI [ exchange-file ]
.PP
Change the filename used for reading and writing with the paste buffer.
-If the optional argument to the \*Qbufferfile\*U command is omitted,
+If the optional argument to the \*Qbufferfile\*U command is omitted,
the default setting (\*Q/tmp/screen-exchange\*U) is reactivated.
-The following example will paste the system's password file into
+The following example will paste the system's password file into
the
.I screen
window (using the paste buffer, where a copy remains):
@@ -816,6 +997,27 @@ Users with fonts that have usable characters in the
c1 positions may want to turn this off.
.sp
.ne 3
+.BR "caption always" | splitonly
+.RI [ string ]
+.br
+.B "caption string"
+.RI [ string ]
+.PP
+This command controls the display of the window captions. Normally
+a caption is only used if more than one window is shown on the
+display (split screen mode). But if the type is set to
+.B always
+screen shows a caption even if only one window is displayed. The default
+is
+.BR splitonly .
+.P
+The second form changes the text used for the caption. You can use
+all escapes from the \*QSTRING ESCAPES\*U chapter. Screen uses
+a default of `%3n %t'.
+.P
+You can mix both forms by providing a string as an additional argument.
+.sp
+.ne 3
.BI "charset " set
.PP
Change the current character set slot designation and charset
@@ -861,28 +1063,37 @@ Clears the current window and saves its image to the scrollback buffer.
.B colon
.RI [ prefix ]
.PP
-Allows you to enter \*Q.screenrc\*U command lines. Useful
-for on-the-fly modification of key bindings,
+Allows you to enter \*Q.screenrc\*U command lines. Useful
+for on-the-fly modification of key bindings,
specific window creation and changing settings. Note that the \*Qset\*U
-keyword no longer exists! Usually commands affect the current window rather
+keyword no longer exists! Usually commands affect the current window rather
than default settings for future windows. Change defaults with commands
-starting with 'def...'.
+starting with 'def...'.
-If you consider this as the `Ex command mode' of
+If you consider this as the `Ex command mode' of
.IR screen ,
you may regard \*QC-a esc\*U (copy mode) as its `Vi command mode'.
-.sp
+.sp
.ne 3
.B command
.PP
This command has the same effect as typing the screen escape
character (^A). It is probably only useful for key bindings.
See also \*Qbindkey\*U.
-.sp
+.sp
+.ne 3
+.BR "compacthist " [ on | off ]
+.PP
+This tells screen weather to suppress trailing blank lines when
+scrolling up text into the history buffer.
+.sp
.ne 3
.BR "console " [ on | off ]
.PP
-Grabs or ungrabs the machines console output to a window.
+Grabs or un-grabs the machines console output to a window.
+.IR Note :
+Only the owner of /dev/console can grab the console output.
+This command is only available if the machine supports the ioctl TIOCCONS.
.sp
.ne 3
.B copy
@@ -895,7 +1106,7 @@ window and its history into the paste buffer. In this mode a vi-like
.br
.in +4n
.ti -2n
-\fBh\fP, \fBj\fP, \fBk\fP, \fBl\fP move the cursor line by line or
+\fBh\fP, \fBj\fP, \fBk\fP, \fBl\fP move the cursor line by line or
column by column.
.br
.ti -2n
@@ -904,23 +1115,23 @@ non-whitespace character on the line.
.br
.ti -2n
\fBH\fP, \fBM\fP and \fBL\fP move the cursor to the leftmost column
-of the top, center or bottom line of the window.
+of the top, center or bottom line of the window.
.br
.ti -2n
\fB+\fP and \fB\-\fP positions one line up and down.
.br
.ti -2n
\fBG\fP moves to the specified absolute line (default: end of buffer).
-.br
+.br
.ti -2n
\fB|\fP moves to the specified absolute column.
.br
.ti -2n
\fBw\fP, \fBb\fP, \fBe\fP move the cursor word by word.
-.br
+.br
.ti -2n
-\fBC-u\fP and \fBC-d\fP scroll the display up/down by the specified amount of
-lines while preserving the cursor position. (Default: half screen-full).
+\fBC-u\fP and \fBC-d\fP scroll the display up/down by the specified amount of
+lines while preserving the cursor position. (Default: half screen-full).
.br
.ti -2n
\fBC-b\fP and \fBC-f\fP scroll the display up/down a full screen.
@@ -936,36 +1147,36 @@ lines while preserving the cursor position. (Default: half screen-full).
.IR Note :
.br
Emacs style movement keys can be customized by a .screenrc command.
-(E.\|g. markkeys "h=^B:l=^F:$=^E") There is no simple method for a full
+(E.\|g. markkeys "h=^B:l=^F:$=^E") There is no simple method for a full
emacs-style keymap, as this involves multi-character codes.
.br
.ti -4n
.IR Marking :
.br
-The copy range is specified by setting two marks. The text between these marks
-will be highlighted. Press
+The copy range is specified by setting two marks. The text between these marks
+will be highlighted. Press
.br
.ti -2n
\fBspace\fP to set the first or second mark
respectively.
.br
.ti -2n
-\fBY\fP and \fBy\fP used to mark one whole line or to mark from
+\fBY\fP and \fBy\fP used to mark one whole line or to mark from
start of line.
.br
.ti -2n
-\fBW\fP marks exactly one word.
-.br
+\fBW\fP marks exactly one word.
+.br
.ti -4n
.IR "Repeat count" :
.br
-Any of these commands can be prefixed with a repeat count number by pressing
-digits
+Any of these commands can be prefixed with a repeat count number by pressing
+digits
.br
.ti -2n
\fB0\fP..\fB9\fP which
-is taken as a repeat count.
+is taken as a repeat count.
.br
Example: \*QC-a C-[ H 10 j 5 Y\*U will copy lines
11 to 15 into the paste buffer.
@@ -976,7 +1187,7 @@ Example: \*QC-a C-[ H 10 j 5 Y\*U will copy lines
\fB/\fP \fIVi\fP-like search forward.
.ti -2n
\fB?\fP \fIVi\fP-like search backward.
-.ti -2n
+.ti -2n
\fBC-a s\fP \fIEmacs\fP style incremental search forward.
.ti -2n
\fBC-r\fP \fIEmacs\fP style reverse i-search.
@@ -988,13 +1199,13 @@ There are however some keys that act differently than in
.I Vi
does not allow one to yank rectangular blocks of text, but
.I screen
-does. Press
+does. Press
.br
.ti -2n
\fBc\fP or \fBC\fP to set the left or right margin respectively. If no repeat count is
-given, both default to the current cursor position.
+given, both default to the current cursor position.
.br
-Example: Try this on a rather full text screen:
+Example: Try this on a rather full text screen:
\*QC-a [ M 20 l SPACE c 10 l 5 j C SPACE\*U.
This moves one to the middle line of the screen, moves in 20 columns left,
@@ -1007,16 +1218,16 @@ the paste buffer. Now try:
and notice the difference in the amount of text copied.
.br
.ti -2n
-\fBJ\fP joins lines. It toggles between
-3 modes: lines separated by a newline character (012), lines glued seamless,
-lines separated by a single whitespace. Note that you can prepend the newline
+\fBJ\fP joins lines. It toggles between 4 modes: lines separated by a
+newline character (012), lines glued seamless, lines separated by a single
+whitespace and comma separated lines. Note that you can prepend the newline
character with a carriage return character, by issuing a \*Qcrlf on\*U.
.br
.ti -2n
\fBv\fP is for all the
-.I vi
+.I vi
users with \*Q:set numbers\*U \- it toggles the left margin between column 9
-and 1. Press
+and 1. Press
.br
.ti -2n
\fBa\fP before the final space key to toggle in append mode. Thus
@@ -1027,10 +1238,10 @@ the contents of the paste buffer will not be overwritten, but is appended to.
.br
.ti -2n
\fB>\fP sets the (second) mark and writes the contents of the paste buffer to
-the screen-exchange file (/tmp/screen-exchange per default) once copy-mode is
-finished.
+the screen-exchange file (/tmp/screen-exchange per default) once copy-mode is
+finished.
.br
-This example demonstrates how to dump the whole scrollback buffer
+This example demonstrates how to dump the whole scrollback buffer
to that file: \*QC-A [ g SPACE G $ >\*U.
.br
.ti -2n
@@ -1054,20 +1265,22 @@ All keys not described here exit copy mode.
No longer exists, use \*Qreadreg\*U instead.
.sp
.ne 3
-.BR "crlf on" | off
+.BR "crlf " [ on | off ]
.PP
This affects the copying of text regions with the `C-a [' command. If it is set
-to `on', lines will be separated by the two character sequence `CR' - `LF'.
+to `on', lines will be separated by the two character sequence `CR' - `LF'.
Otherwise (default) only `LF' is used.
+When no parameter is given, the state is toggled.
.sp
.ne 3
.BR "debug on" | off
.PP
-Turns runtime debugging on or off. If
+Turns runtime debugging on or off. If
.I screen
-has been compiled with option -DDEBUG debugging available and is turned on per
-default. Note that this command only affects debugging output from the main
-\*QSCREEN\*U process.
+has been compiled with option -DDEBUG debugging available and is turned on per
+default. Note that this command only affects debugging output from the main
+\*QSCREEN\*U process correctly. Debug output from attacher processes can only
+be turned off once and forever.
.sp
.ne 3
.BR "defc1 on" | off
@@ -1083,6 +1296,26 @@ Note that you can use the special `AN' terminal capability if you
want to have a dependency on the terminal type.
.sp
.ne 3
+.B defbreaktype
+.RI [ tcsendbreak | TIOCSBRK
+.RI | TCSBRK ]
+.PP
+Choose one of the available methods of generating a break signal for
+terminal devices. The preferred methods are
+.IR tcsendbreak " and " TIOCSBRK .
+The third,
+.IR TCSBRK ,
+blocks the complete
+.I screen
+session for the duration
+of the break, but it may be the only way to generate long breaks.
+.IR Tcsendbreak " and " TIOCSBRK
+may or may not produce long breaks with spikes (e.g. 4 per
+second). This is not only system dependant, this also differs between
+serial board drivers.
+Calling \*Qdefbreaktype\*U with no parameter displays the current setting.
+.sp
+.ne 3
.BR "defcharset " [ \fIset ]
.PP
Like the \fBcharset\fP command except that the default setting for
@@ -1092,22 +1325,22 @@ argument.
.ne 3
.BI "defescape " xy
.PP
-Set the default command characters. This is equivalent to the
+Set the default command characters. This is equivalent to the
\*Qescape\*U except that it is useful multiuser sessions only. In a
multiuser session \*Qescape\*U changes the command character of the
calling user, where \*Qdefescape\*U changes the default command
characters for users that will be added later.
.sp
.ne 3
-.BR "defflow on" | off | auto
+.BR "defflow on" | off | auto
.RB [ interrupt ]
.PP
-Same as the \fBflow\fP command except that the default setting for new windows
+Same as the \fBflow\fP command except that the default setting for new windows
is changed. Initial setting is `auto'.
Specifying \*Qdefflow auto interrupt\*U is the same as the command-line options
.B \-fa
and
-.BR \-i .
+.BR \-i .
.sp
.ne 3
.BR "defgr on" | off
@@ -1125,7 +1358,7 @@ display the window number or title or the like.
.I Status
may contain the same directives as in the window messages, but
the directive escape character is '^E' (octal 005) instead of '%'.
-This was done to make a misinterpretion of program generated
+This was done to make a misinterpretation of program generated
hardstatus lines impossible.
If the parameter
.I status
@@ -1141,7 +1374,7 @@ windows is changed. Initial setting is `off', i.e. `jis'.
.ne 3
.BR "deflogin on" | off
.PP
-Same as the \fBlogin\fP command except that the default setting for new windows
+Same as the \fBlogin\fP command except that the default setting for new windows
is changed. This is initialized with `on' as distributed (see config.h.in).
.sp
.ne 3
@@ -1154,7 +1387,7 @@ When no \*Qdefmode\*U command is given, mode 0622 is used.
.ne 3
.BR "defmonitor on" | off
.PP
-Same as the \fBmonitor\fP command except that the default setting for new
+Same as the \fBmonitor\fP command except that the default setting for new
windows is changed. Initial setting is `off'.
.sp
.ne 3
@@ -1167,21 +1400,38 @@ want to have a dependency on the terminal type.
.ne 3
.BI "defscrollback " num
.PP
-Same as the \fBscrollback\fP command except that the default setting for new
+Same as the \fBscrollback\fP command except that the default setting for new
windows is changed. Initial setting is 100.
.sp
.ne 3
+.BI "defshell " command
+.PP
+Synonym to the \fBshell\fP command. See there.
+.sp
+.ne 3
+.BR "defsilence on" | off
+.PP
+Same as the \fBsilence\fP command except that the default setting for new
+windows is changed. Initial setting is `off'.
+.sp
+.ne 3
+.BI "defslowpaste " msec"
+.PP
+Same as the \fBslowpaste\fP command except that the default setting for new
+windows is changed. Initial setting is 0 milliseconds, meaning `off'.
+.sp
+.ne 3
.BR "defwrap on" | off
.PP
-Same as the \fBwrap\fP command except that the default setting for new
-windows is changed. Initially line-wrap is on and can be toggled with the
+Same as the \fBwrap\fP command except that the default setting for new
+windows is changed. Initially line-wrap is on and can be toggled with the
\*Qwrap\*U command (\*QC-a r\*U) or by means of "C-a : wrap on|off".
.sp
.ne 3
.BR "defwritelock on" | off | auto
.PP
-Same as the \fBwritelock\fP command except that the default setting for new
-windows is changed. Initially writelocks will operate in automatic mode.
+Same as the \fBwritelock\fP command except that the default setting for new
+windows is changed. Initially writelocks will off.
.sp
.ne 3
.BR "defzombie " [\fIkeys\fP]
@@ -1192,7 +1442,7 @@ See there.
.ne 3
.B detach
.PP
-Detach the
+Detach the
.I screen
session (disconnect it from the terminal and put it into the background).
This returns you to the shell where you invoked
@@ -1206,6 +1456,12 @@ with the
option. (See also section \*QCOMMAND-LINE OPTIONS\*U.)
.sp
.ne 3
+.B displays
+.PP
+Shows a tabular listing of all currently connected user front-ends (displays).
+This is most useful for multiuser sessions.
+.sp
+.ne 3
.BR "digraph " [ \fIpreset ]
.PP
This command prompts the user for a digraph sequence. The next
@@ -1214,7 +1470,7 @@ resulting character is inserted in the input stream. For example,
if the user enters 'a"', an a-umlaut will be inserted. If the
first character entered is a 0 (zero),
.I screen
-will treat the following charcters (up to three) as an octal
+will treat the following characters (up to three) as an octal
number instead. The optional argument
.I preset
is treated as user input, thus one can create an \*Qumlaut\*U key.
@@ -1225,35 +1481,37 @@ to generate an a-umlaut by typing CTRL-K a.
.B dumptermcap
.PP
Write the termcap entry for the virtual terminal optimized for the currently
-active window to the file \*Q.termcap\*U in the user's
-\*Q$HOME/.screen\*U directory (or wherever
+active window to the file \*Q.termcap\*U in the user's
+\*Q$HOME/.screen\*U directory (or wherever
.I screen
stores its sockets. See the \*QFILES\*U section below).
This termcap entry is identical to the value of the environment variable
$TERMCAP that is set up by
.I screen
for each window. For terminfo based systems you will need to run a converter
-like
+like
.IR captoinfo
-and then compile the entry with
+and then compile the entry with
.IR tic .
.sp
.ne 3
.BR "echo " [ -n ]
.I message
.PP
-The echo command may be used to annoy
+The echo command may be used to annoy
.I screen
users with a 'message of the
-day'. Typically installed in a global /local/etc/screenrc. See also
-\*Qsleep\*U.
+day'. Typically installed in a global /local/etc/screenrc.
+The option \*Q-n\*U may be used to suppress the line feed.
+See also \*Qsleep\*U.
Echo is also useful for online checking of environment variables.
.sp
.ne 3
.BI "escape " xy
.PP
Set the command character to \fIx\fP and the character generating a literal
-command character to \fIy\fP (just like in the \-e option).
+command character (by triggering the \*Qmeta\*U command) to \fIy\fP (similar
+to the \-e option).
Each argument is either a single character, a two-character sequence
of the form \*Q^x\*U (meaning \*QC-x\*U), a backslash followed by an octal
number (specifying the ASCII code of the character), or a backslash followed
@@ -1265,38 +1523,42 @@ The default is \*Q^Aa\*U.
.RI [[ fdpat ]
.IR "newcommand " [ "args ..." ]]
.PP
-Run a subprocess (newcommand) in the current window. The flow of data between
-newcommand's stdin/stdout/stderr, the process already running (shell) and
-screen itself (window) is controlled by the filedescriptor pattern fdpat.
+Run a unix subprocess (specified by an executable path \fInewcommand\fP and its
+optional arguments) in the current window. The flow of data between
+newcommands stdin/stdout/stderr, the process originally started in the window
+(let us call it "application-process") and screen itself (window) is
+controlled by the filedescriptor pattern fdpat.
This pattern is basically a three character sequence representing stdin, stdout
and stderr of newcommand. A dot (.) connects the file descriptor
to
.IR screen .
An exclamation mark (!) causes the file
-descriptor to be connected to the already running process. A colon (:) combines
+descriptor to be connected to the application-process. A colon (:) combines
both.
-User input will go to newcommand unless newcommand requests the old process'
-output (fdpats first character is `!' or `:') or a pipe (|) is added to
-the end of fdpat.
+User input will go to newcommand unless newcommand receives the
+application-process'
+output (fdpats first character is `!' or `:') or a pipe symbol (|) is added
+(as a fourth character) to the end of fdpat.
.br
Invoking `exec' without arguments shows name and arguments of the currently
-running subprocess in this window.
+running subprocess in this window. Only one subprocess a time can be running
+in each window.
.br
When a subprocess is running the `kill' command will affect it instead of the
windows process.
.br
-Refer to the postscript file `fdpat.ips' for a confusing illustration
+Refer to the postscript file `doc/fdpat.ps' for a confusing illustration
of all 21 possible combinations. Each drawing shows the digits 2,1,0
representing the three file descriptors of newcommand. The box marked
-`W' is usual pty that has the application-process on its slave side.
+`W' is the usual pty that has the application-process on its slave side.
The box marked `P' is the secondary pty that now has
.I screen
at its master side.
.sp
-Abbreviations:
+Abbreviations:
.br
-Whitespace between the word `exec' and fdpat and the command
-can be omitted. Trailing dots and a fdpat consisting only of dots can be
+Whitespace between the word `exec' and fdpat and the command
+can be omitted. Trailing dots and a fdpat consisting only of dots can be
omitted. A simple `|' is synonymous for the pattern `!..|'; the word exec can
be omitted here and can always be replaced by `!'.
.sp
@@ -1308,7 +1570,7 @@ exec /bin/sh
.br
!/bin/sh
.PP
-Creates another shell in the same window, while the original shell is still
+Creates another shell in the same window, while the original shell is still
running. Output of both shells is displayed and user input is sent to the new
/bin/sh.
.IP
@@ -1318,15 +1580,15 @@ exec ! stty 19200
.br
!!stty 19200
.PP
-Set the speed of the window's tty. If your stty command operates on stdout, then
-add another `!'.
+Set the speed of the window's tty. If your stty command operates on stdout,
+then add another `!'.
.IP
exec !..| less
.br
|less
.PP
This adds a pager to the window output. The special character `|' is needed to
-give the user control over the pager although it gets its input from the
+give the user control over the pager although it gets its input from the
window's process. This works, because
.I less
listens on stderr (a behavior that
@@ -1347,21 +1609,34 @@ This will cause "Bell in window x" messages, whenever the string "Error"
appears in the window.
.sp
.ne 3
+.B fit
+.PP
+Change the window size to the size of the current region. This
+command is needed because screen doesn't adapt the window size
+automatically if the window is displayed more than once.
+.sp
+.ne 3
.B flow
.RB [ on | off | "auto\fR]\fP"
.PP
Sets the flow-control mode for this window.
-Without parameters it cycles the current window's flow-control setting from
+Without parameters it cycles the current window's flow-control setting from
"automatic" to "on" to "off".
-See the discussion on \*QFLOW-CONTROL\*U later on in this document for full
+See the discussion on \*QFLOW-CONTROL\*U later on in this document for full
details and note, that this is subject to change in future releases.
Default is set by `defflow'.
.sp
.ne 3
+.B focus
+.PP
+Move the input focus to the next region. This is done in a cyclic
+way so that the top region is selected after the bottom one.
+.sp
+.ne 3
.BR "gr " [ on | off ]
.PP
-Turn GR charset switching on/off. Whenever screens sees an input
-char with an 8th bit set, it will use the charset stored in the
+Turn GR charset switching on/off. Whenever screen sees an input
+character with the 8th bit set, it will use the charset stored in the
GR slot and print the character with the 8th bit stripped. The
default (see also \*Qdefgr\*U) is not to process GR switching because
otherwise the ISO88591 charset would not work.
@@ -1371,15 +1646,15 @@ otherwise the ISO88591 charset would not work.
.PP
Writes out the currently displayed image to a file \fIhardcopy.n\fP
in the window's default directory, where \fIn\fP is the number
-of the current window.
+of the current window.
This either appends or overwrites the file if it exists. See below.
.sp
.ne 3
.BR "hardcopy_append on" | off
.PP
-If set to "on",
+If set to "on",
.I screen
-will append to the "hardcopy.n" files created by the command \*QC-a h\*U,
+will append to the "hardcopy.n" files created by the command \*QC-a h\*U,
otherwise these files are overwritten each time.
Default is `off'.
.sp
@@ -1393,14 +1668,52 @@ current working directory.
.sp
.ne 3
.BR "hardstatus " [ on | off ]
-.PP
-Toggles the use of the terminal's hardware status line. If "on",
-.I screen
-will use this facility to display one line messages. Otherwise these messages
-are overlayed in reverse video mode at the display line. Note that the
-hardstatus feature can only be used if the termcap/terminfo capabilities
-"hs", "ts", "fs" and "ds" are set properly. Default is `on' whenever the "hs"
-capability is present.
+.br
+.BR "hardstatus \fR[\fBalways\fR]\fBlastline" | message | ignore
+.RI [ string ]
+.br
+.B "hardstatus string"
+.RI [ string ]
+.PP
+This command configures the use and emulation of the terminal's
+hardstatus line. The first form
+toggles whether
+.I screen
+will use the hardware status line to display messages. If the
+flag is set to `off', these messages
+are overlaid in reverse video mode at the display line. The default
+setting is `on'.
+.P
+The second form tells
+.I screen
+what to do if the terminal doesn't
+have a hardstatus line (i.e. the termcap/terminfo capabilities
+"hs", "ts", "fs" and "ds" are not set). If the type
+\*Qlastline\*U is used,
+.I screen
+will reserve the last line of the
+display for
+the hardstatus. \*Qmessage\*U uses
+.I screen's
+message mechanism and
+\*Qignore\*U tells
+.I screen
+never to display the hardstatus.
+If you prepend the word \*Qalways\*U to the type,
+.I screen
+will use the type even if the terminal supports a hardstatus.
+.P
+The third form specifies the contents of the hardstatus line.
+'%h' is used as default string, i.e. the stored hardstatus of the
+current window (settable via \\E]0;^G or \\E_\\\\) is displayed.
+You can customize this to any string you like including
+the escapes from the \*QSTRING ESCAPES\*U chapter. If you leave
+out the argument
+.IR string ,
+the current string is displayed.
+.P
+You can mix the second and third form by providing the string as
+additional argument.
.sp
.ne 3
.BR "height " [ \fIlines\fP ]
@@ -1411,8 +1724,10 @@ is given it toggles between 24 and 42 lines display.
.ne 3
.B help
.PP
-Not really a online help, but
-displays a help screen showing you all the key bindings.
+Not really a online help, but
+displays a help
+.I screen
+showing you all the key bindings.
The first pages list all the internal commands followed by their current
bindings.
Subsequent pages will display the custom commands, one command per key.
@@ -1424,29 +1739,56 @@ See also \*QDEFAULT KEY BINDINGS\*U section.
.B history
.PP
Usually users work with a shell that allows easy access to previous commands.
-For example csh has the command \*Q!!\*U to repeat the last command executed.
+For example csh has the command \*Q!!\*U to repeat the last command executed.
.I Screen
allows you to have a primitive way of re-calling \*Qthe command that
started ...\*U: You just type the first letter of that command, then hit
`C-a {' and
.I screen
-tries to find a previous line that matches with the `prompt character'
+tries to find a previous line that matches with the `prompt character'
to the left of the cursor. This line is pasted into this window's input queue.
Thus you have a crude command history (made up by the visible window and its
-scrollback buffer).
+scrollback buffer).
+.sp
+.ne 3
+.BI "hstatus " status
+.PP
+Change the window's hardstatus line to the string \fIstatus\fP.
.sp
.ne 3
.B info
.PP
Uses the message line to display some information about the current window:
the cursor position in the form \*Q(column,row)\*U starting with \*Q(1,1)\*U,
-the terminal width and height plus the size of the scrollback buffer in lines,
-like in \*U(80,24)+50\*U, various flag settings (flow-control, insert mode,
-origin mode, wrap mode, application-keypad mode, output logging, activity
-monitoring and redraw (`+' indicates enabled, `\-' not)),
-the currently active character set (\fIG0\fP, \fIG1\fP, \fIG2\fP,
-or \fIG3\fP), and in square brackets the terminal character sets that are
-currently designated as \fIG0\fP through \fIG3\fP.
+the terminal width and height plus the size of the scrollback buffer in lines,
+like in \*Q(80,24)+50\*U, the current state of window XON/XOFF flow control
+is shown like this (See also section FLOW CONTROL):
+
+.nf
+ +flow automatic flow control, currently on.
+ -flow automatic flow control, currently off.
+ +(+)flow flow control enabled. Agrees with automatic control.
+ -(+)flow flow control disabled. Disagrees with automatic control.
+ +(-)flow flow control enabled. Disagrees with automatic control.
+ -(-)flow flow control disabled. Agrees with automatic control.
+.fi
+
+The current line wrap setting (`+wrap' indicates enabled, `\-wrap' not) is
+also shown. The flags `ins', `org', `app', `log', `mon' or `nored' are
+displayed when the window is in insert mode, origin mode,
+application-keypad mode, has output logging,
+insert mode, origin mode, application-keypad mode, output logging,
+activity monitoring or partial redraw enabled.
+
+The currently active character set (\fIG0\fP, \fIG1\fP, \fIG2\fP,
+or \fIG3\fP) and in square brackets the terminal character sets that are
+currently designated as \fIG0\fP through \fIG3\fP is shown.
+
+Additional modes depending on the type of the window are displayed at the end of the status line (See also chapter \*QWINDOW TYPES\*U).
+.br
+If the state machine of the terminal emulator is in a non-default state,
+the info line is started with a string identifying the current state.
+.br
For system information use the \*Qtime\*U command.
.sp
.ne 3
@@ -1459,9 +1801,12 @@ No longer exists, use \*Qpaste\*U instead.
.BR jis | euc | sjis
.RB [ jis | euc | sjis\fR]
.PP
-Tell screen how to process kanji input/output. The first argument
+Tell
+.I screen
+how to process kanji input/output. The first argument
sets the kanji type of the current window. Each window can emulate
-a different type. The optional second parameter tells screen
+a different type. The optional second parameter tells
+.I screen
how to write the kanji codes to the connected terminal. The preferred
method of setting the display type is to use the \*QKJ\*U termcap
entry.
@@ -1472,15 +1817,19 @@ window.
.B kill
.PP
Kill current window.
-.br
+.br
If there is an `exec' command running then it is killed. Otherwise the process
-(shell) running in the window receives a HANGUP condition, the window structure
-is removed and
-.I screen
-switches to the previously displayed window.
-When the last window is destroyed,
+(shell) running in the window receives a HANGUP condition,
+the window structure is removed and
+.I screen
+(your display) switches to another
+window. When the last window is destroyed,
.I screen
exits.
+After a kill
+.I screen
+switches to the previously displayed window.
+.br
Note:
.I Emacs
users should keep this command in mind, when killing a line.
@@ -1492,7 +1841,7 @@ escape key or to rebind kill to \*QC-a K\*U.
.B lastmsg
.PP
Redisplay the last contents of the message/status line.
-Useful if you're typing when a message appears, because the message goes
+Useful if you're typing when a message appears, because the message goes
away when you press a key (unless your terminal has a hardware status line).
Refer to the commands \*Qmsgwait\*U and \*Qmsgminwait\*U for fine tuning.
.sp
@@ -1501,7 +1850,7 @@ Refer to the commands \*Qmsgwait\*U and \*Qmsgminwait\*U for fine tuning.
.PP
Display the disclaimer page. This is done whenever
.I screen
-is started without options, which should be often enough. See also
+is started without options, which should be often enough. See also
the \*Qstartup_message\*U command.
.sp
.ne 3
@@ -1510,29 +1859,40 @@ the \*Qstartup_message\*U command.
Lock this display.
Call a screenlock program (/local/bin/lck or /usr/bin/lock or a builtin if no
other is available). Screen does not accept any command keys until this program
-terminates. Meanwhile processes in the windows may continue, as the windows
+terminates. Meanwhile processes in the windows may continue, as the windows
are in the `detached' state. The screenlock program may be changed through the
-environment variable $LOCKPRG (which must be set in the shell from which
+environment variable $LOCKPRG (which must be set in the shell from which
.I screen
is started) and is executed with the user's uid and gid.
+.br
+Warning:
+When you leave other shells unlocked and you have no password set on
+.IR screen ,
+the lock is void: One could easily re-attach from an unlocked
+shell. This feature should rather be called `lockterminal'.
.sp
.ne 3
.BR "log " [ on | off ]
.PP
-Start/stop writing output of the current window to a file
-\*Qscreenlog.\fIn\fP\*U in the window's default directory, where \fIn\fP
+Start/stop writing output of the current window to a file
+\*Qscreenlog.\fIn\fP\*U in the window's default directory, where \fIn\fP
is the number of the current window. This filename can be changed with
the `logfile' command. If no parameter is given, the state
-of logging is toggled. The session log is appended to the previous contents
-of the file if it already exists. The current contents and the contents
+of logging is toggled. The session log is appended to the previous contents
+of the file if it already exists. The current contents and the contents
of the scrollback history are not included in the session log.
Default is `off'.
.sp
.ne 3
.BI "logfile " filename
+.br
+.BI "logfile flush " secs
.PP
Defines the name the logfiles will get. The default is
-\*Qscreenlog.%n\*U.
+\*Qscreenlog.%n\*U. The second form changes the number of seconds
+.I screen
+will wait before flushing the logfile buffer to the file-system. The
+default value is 10 seconds.
.sp
.ne 3
.BR "login " [ on | off ]
@@ -1543,18 +1903,43 @@ When no parameter is given, the login state of the window is toggled.
Additionally to that toggle, it is convenient having a `log in' and a `log out'
key. E.\|g. `bind I login on' and `bind O login off' will map these
keys to be C-a I and C-a O.
-The default setting (in config.h.in) should be \*Qon\*U for a
+The default setting (in config.h.in) should be \*Qon\*U for a
.I screen
that runs under suid-root.
-Use the \*Qdeflogin\*U command to change the default login state for new
-windows. Both commands are only present when
+Use the \*Qdeflogin\*U command to change the default login state for new
+windows. Both commands are only present when
.I screen
has been compiled with utmp support.
.sp
.ne 3
+.BR "logtstamp " [ on | off ]
+.br
+.B "logtstamp after"
+.RI [ secs ]
+.br
+.B "logtstamp string"
+.RI [ string ]
+.PP
+This command controls logfile time-stamp mechanism of
+.I screen.
+If
+time-stamps are turned \*Qon\*U,
+.I screen
+adds a string containing
+the current time to the logfile after two minutes of inactivity.
+When output continues and more than another two minutes have passed,
+a second time-stamp is added to document the restart of the
+output. You can change this timeout with the second form
+of the command. The third form is used for customizing the time-stamp
+string (`-- %n:%t -- time-stamp -- %M/%d/%y %c:%s --\\n' by
+default).
+.sp
+.ne 3
.B mapdefault
.PP
-Tell screen that the next input character should only be looked up
+Tell
+.I screen
+that the next input character should only be looked up
in the default bindkey table. See also \*Qbindkey\*U.
.sp
.ne 3
@@ -1566,7 +1951,7 @@ Like mapdefault, but don't even look in the default bindkey table.
.B maptimeout
.RI [ timo ]
.PP
-Set the intercharacter timer for input sequence detection to a timeout
+Set the inter-character timer for input sequence detection to a timeout
of
.I timo
ms. The default timeout is 300ms. Maptimeout with no arguments shows
@@ -1578,11 +1963,17 @@ See also \*Qbindkey\*U.
.PP
This is a method of changing the keymap used for copy/history mode.
The string is made up of \fIoldchar\fP=\fInewchar\fP pairs which are
-separated by `:'. Example: The string \*QB=^B:F=^F\*U will change the
+separated by `:'. Example: The string \*QB=^B:F=^F\*U will change the
keys `C-b' and `C-f' to the vi style binding (scroll up/down fill page).
This happens to be the default binding for `B' and `F'.
The command \*Qmarkkeys h=^B:l=^F:$=^E\*U would set the mode for an emacs-style
binding.
+If your terminal sends characters, that cause you to abort copy mode,
+then this command may help by binding these characters to do nothing.
+The no-op character is `@' and is used like this: \*Qmarkkeys
+@=L=H\*U if you do not want to use the `H' or `L' commands any longer.
+As shown in this example, multiple keys can be assigned to one function in a
+single statement.
.sp
.ne 3
.B meta
@@ -1602,15 +1993,15 @@ Monitoring is initially off for all windows.
.ne 3
.BI "msgminwait " sec
.PP
-Defines the time
-.I screen
-delays a new message when one message is currently displayed.
+Defines the time
+.I screen
+delays a new message when one message is currently displayed.
The default is 1 second.
.sp
.ne 3
.BI "msgwait " sec
.PP
-Defines the time a message is displayed if
+Defines the time a message is displayed if
.I screen
is not disturbed by other activity. The default is 5 seconds.
.sp
@@ -1620,8 +2011,10 @@ is not disturbed by other activity. The default is 5 seconds.
Switch between singleuser and multiuser mode. Standard
.I screen
operation is singleuser. In multiuser mode the commands `acladd',
-`aclchg' and `acldel'
-can be used to enable (and disable) other users accessing this screen.
+`aclchg', `aclgrp' and `acldel'
+can be used to enable (and disable) other users accessing this
+.I screen
+session.
.sp
.ne 3
.BR "nethack on" | off
@@ -1633,11 +2026,11 @@ nethack-style messages which will often blur the facts a little, but are
much funnier to read. Anyway, standard messages often tend to be unclear as
well.
.br
-This option is only
+This option is only
available if
.I screen
was compiled with the NETHACK flag defined. The
-default setting is then determined by the presence of the environment
+default setting is then determined by the presence of the environment
variable $NETHACKOPTIONS.
.sp
.ne 3
@@ -1647,9 +2040,18 @@ Switch to the next window.
This command can be used repeatedly to cycle through the list of windows.
.sp
.ne 3
+.B nonblock
+.RB [ on | off ]
+.PP
+Enable or disable flow control for the current user interface (display).
+It is used to prevent a slow display from slowing down the processing of
+data output by a window. This command may be helpful when multiple displays
+show the same window. Nonblock is initially off for all displays.
+.sp
+.ne 3
.BR "number " [ \fIn ]
.PP
-Change the current windows number. If the given number \fIn\fP is already
+Change the current windows number. If the given number \fIn\fP is already
used by another window, both windows exchange their numbers. If no argument is
specified, the current window number (and title) is shown.
.sp
@@ -1663,9 +2065,15 @@ display (like xterm), you can set it to some higher value. If no
argument is specified, the current setting is displayed.
.sp
.ne 3
+.B only
+.PP
+Kill all regions but the current one.
+.sp
+.ne 3
.B other
.PP
-Switch to the window displayed previously.
+Switch to the window displayed previously. If this window does no longer exist,
+\fIother\fP has the same effect as \fInext\fP.
.sp
.ne 3
.BR "partial on" | off
@@ -1673,7 +2081,7 @@ Switch to the window displayed previously.
Defines whether the display should be refreshed (as with \fIredisplay\fP) after
switching to the current window. This command only affects the current window.
To immediately affect all windows use the \fIallpartial\fP command.
-Default is `off', of course. This default is fixed, as there is currently no
+Default is `off', of course. This default is fixed, as there is currently no
\fIdefpartial\fP command.
.sp
.ne 3
@@ -1699,27 +2107,29 @@ Default is `none', this disables password checking.
.PP
Write the (concatenated) contents of the specified registers to the stdin queue
of the current window. The register '.' is treated as the
-paste buffer. If no parameter is given the user is prompted for a single
+paste buffer. If no parameter is given the user is prompted for a single
register to paste.
-The paste buffer can be filled with the \fIcopy\fP, \fIhistory\fP and
-\fIreadbuf\fP commands.
-Other registers can be filled with the \fIregister\fP, \fIreadreg\fP and
+The paste buffer can be filled with the \fIcopy\fP, \fIhistory\fP and
+\fIreadbuf\fP commands.
+Other registers can be filled with the \fIregister\fP, \fIreadreg\fP and
\fIpaste\fP commands.
If \fIpaste\fP is called with a second argument, the contents of the specified
-registers is pasted into the named destination register rather than
+registers is pasted into the named destination register rather than
the window. If '.' is used as the second argument, the displays paste buffer is
the destination.
-Note, that \*Qpaste\*U uses a wide variety of resources: Whenever a second
+Note, that \*Qpaste\*U uses a wide variety of resources: Whenever a second
argument is specified no current window is needed. When the source specification
-only contains registers (not the paste buffer) then there need not be a current
-display (terminal attached), as the registers are a global resource. The
+only contains registers (not the paste buffer) then there need not be a current
+display (terminal attached), as the registers are a global resource. The
paste buffer exists once for every user.
.sp
.ne 3
.BR "pastefont " [ on | off ]
.PP
-Tell screen to include font information in the paste buffer. The
-default is not to do so. This command is especially usefull for
+Tell
+.I screen
+to include font information in the paste buffer. The
+default is not to do so. This command is especially useful for
multi character fonts like kanji.
.sp
.ne 3
@@ -1730,20 +2140,22 @@ Reopen the window's terminal line and send a break condition. See `break'.
.ne 3
.B pow_detach
.PP
-Power detach.
+Power detach.
Mainly the same as \fIdetach\fP, but also sends a HANGUP signal to
the parent process of
.IR screen .
-CAUTION: This will result in a logout, when
+CAUTION: This will result in a logout, when
.I screen
was started from your login shell.
.sp
.ne 3
-.BI "pow_detach_msg " message
+.B pow_detach_msg
+.RI [ message ]
.PP
The \fImessage\fP specified here is output whenever a `Power detach' was
-performed. It may be used as a replacement for a logout message or to reset
-baud rate, etc.
+performed. It may be used as a replacement for a logout message or to reset
+baud rate, etc.
+Without parameter, the current message is shown.
.sp
.ne 3
.B prev
@@ -1757,7 +2169,9 @@ This command can be used repeatedly to cycle through the list of windows.
.PP
If
.I cmd
-is not an empty string, screen will not use the terminal capabilities
+is not an empty string,
+.I screen
+will not use the terminal capabilities
\*Qpo/pf\*U if it detects an ansi print sequence
.BR "ESC [ 5 i" ,
but pipe the output into
@@ -1776,7 +2190,8 @@ access to your terminal, they will be able to fire off print commands.
.ne 3
.BR process " [" \fIkey ]
.PP
-Stuff the contents of the specified register into \fIscreen\fP's
+Stuff the contents of the specified register into
+.IR screen 's
input queue. If no argument is given you are prompted for a
register name. The text is parsed as if it had been typed in from the user's
keyboard. This command can be used to bind multiple actions to a single key.
@@ -1794,20 +2209,22 @@ Use the empty bind command (as in \*Qbind '^\e'\*U) to remove a key binding.
.ne 3
.B readbuf
.PP
-Reads the contents of the current screen-exchange file into the paste buffer.
+Reads the contents of the current screen-exchange file into the paste buffer.
See also \*Qbufferfile\*U command.
.sp
.ne 3
-.B readreg
+.B readreg
.RI [ register " [" filename ]]
.PP
Does one of two things, dependent on number of arguments: with zero or one
arguments it it duplicates the paste buffer contents into the register specified
-or entered at the prompt. With two arguments it reads the contents of the named
+or entered at the prompt. With two arguments it reads the contents of the named
file into the register, just as \fIreadbuf\fP reads the screen-exchange file
into the paste buffer.
-The following example will paste the system's password file into
-the screen window (using register p, where a copy remains):
+The following example will paste the system's password file into
+the
+.I screen
+window (using register p, where a copy remains):
.PP
.nf
C-a : readreg p /etc/passwd
@@ -1827,14 +2244,19 @@ Save the specified \fIstring\fP to the register \fIkey\fP. See also the
\*Qpaste\*U command.
.sp
.ne 3
+.B "remove"
+.PP
+Kill the current region. This is a no-op if there is only one region.
+.sp
+.ne 3
.B "removebuf"
.PP
-Unlinks the screen-exchange file used by the commands \*Qwritebuf\*U and
-\*Qreadbuf\*U.
+Unlinks the screen-exchange file used by the commands \*Qwritebuf\*U and
+\*Qreadbuf\*U.
.sp
.ne 3
.B "reset"
-.PP
+.PP
Reset the virtual terminal to its \*Qpower-on\*U values. Useful when strange
settings (like scroll regions or graphics character set) are left over from
an application.
@@ -1845,8 +2267,10 @@ an application.
Establish a new window.
The flow-control options (\fB\-f\fP, \fB\-fn\fP and \fB\-fa\fP),
title (a.\|k.\|a.) option (\fB\-t\fP), login options (\fB-l\fP and \fB-ln\fP)
-, terminal type option (\fB-T <term>\fP) and scrollback option (\fB-h\fP <num>)
-may be specified for each command.
+, terminal type option (\fB-T\fP <term>), the all-capability-flag (\fB-a\fP)
+and scrollback option (\fB-h\fP <num>) may be specified with each command.
+The option (\fB-M\fP) turns monitoring on for this window.
+The option (\fB-L\fP) turns output logging on for this window.
If an optional number \fIn\fP in the range 0..9 is given, the window
number \fIn\fP is assigned to the newly created window (or, if this
number is already in-use, the next available number).
@@ -1857,53 +2281,58 @@ Thus, if your \*Q.screenrc\*U contains the lines
.nf
# example for .screenrc:
screen 1
- screen -fn -t foobar 2 telnet foobar
+ screen -fn -t foobar -L 2 telnet foobar
.fi
.sp
.I screen
creates a shell window (in window #1) and a window with a TELNET connection
to the machine foobar (with no flow-control using the title \*Qfoobar\*U
-in window #2). Note, that unlike previous versions of
+in window #2) and will write a logfile (\*Qscreenlog.2\*U) of the telnet
+session.
+Note, that unlike previous versions of
.I screen
-no additional default window is created when \*Qscreen\*U commands are
+no additional default window is created when \*Qscreen\*U commands are
included in your \*Q.screenrc\*U file. When the initialization is completed,
.I screen
switches to the last window specified in your .screenrc file or, if none,
opens a default window #0.
+.br
+Screen has built in some functionality of \*Qcu\*U and \*Qtelnet\*U.
+See also chapter \*QWINDOW TYPES\*U.
.sp
.ne 3
.B "scrollback \fP\fInum\fP"
.PP
-Set the size of the scrollback buffer for the current windows to \fInum\fP
+Set the size of the scrollback buffer for the current windows to \fInum\fP
lines. The default scrollback is 100 lines.
-See also the \*Qdefscrollback\*U command and use \*QC-a i\*U to view the
+See also the \*Qdefscrollback\*U command and use \*QC-a i\*U to view the
current setting.
.sp
.ne 3
-.BR "select " [ \fIn ]
+.BR "select " [ \fIWindowID ]
.PP
-Switch to the window with the number \fIn\fP.
-If no window number is specified, you get prompted for an
-identifier. This can be title (alphanumeric window name) or a number.
+Switch to the window identified by \fIWindowID\fP.
+This can be a prefix of a window title (alphanumeric window name) or a window
+number.
+The parameter is optional and if omitted, you get prompted for an identifier.
When a new window is established, the first available number
is assigned to this window.
-Thus, the first window can be activated by \*Qselect 0\*U (there can be no more
-than 10 windows present simultaneously unless
-.I screen
-was compiled with a higher MAXWIN setting).
+Thus, the first window can be activated by \*Qselect 0\*U.
+The number of windows is limited at compile-time by the MAXWIN
+configuration parameter.
.sp
.ne
.BR "sessionname " [ \fIname ]
.PP
Rename the current session. Note, that for \*Qscreen -list\*U the
name shows up with the process-id prepended. If the argument \*Qname\*U
-is omitted, the name of this session is displayed. Caution: The $STY
-environment variables still reflects the old name. This may result in
-confusion.
+is omitted, the name of this session is displayed. Caution: The $STY
+environment variables still reflects the old name. This may result in
+confusion.
The default is constructed from the tty and host names.
.sp
.ne 3
-.B "setenv "
+.B "setenv "
.RI [ var " [" string ]]
.PP
Set the environment variable \fIvar\fP to value \fIstring\fP.
@@ -1935,7 +2364,7 @@ Toggles silence monitoring of windows.
When silence is turned on and an affected window is switched into the
background, you will receive the silence notification message in the
status line after a specified period of inactivity (silence). The default
-timeout can be changed with the `silencewait' command or by specifying a
+timeout can be changed with the `silencewait' command or by specifying a
number of seconds instead of `on' or `off'.
Silence is initially off for all windows.
.sp
@@ -1953,33 +2382,44 @@ Keyboard activity will end the sleep.
It may be used to give users a chance to read the messages output by \*Qecho\*U.
.sp
.ne 3
-.B "slowpaste \fIusec\fP"
+.B "slowpaste \fImsec\fP"
.PP
-Define the speed at which text is inserted by the paste ("C-a ]") command.
+Define the speed at which text is inserted into the current window by the
+paste ("C-a ]") command.
If the slowpaste value is nonzero text is written character by character.
.I screen
-will make a pause of \fIusec\fP milliseconds after each single character write
-to allow the application to process its input. Only use slowpaste if your
-underlying system exposes flow control problems while pasting large amounts of
-text.
+will make a pause of \fImsec\fP milliseconds after each single character write
+to allow the application to process its input. Only use slowpaste if your
+underlying system exposes flow control problems while pasting large amounts of
+text.
.sp
.ne 3
.B sorendition
.RB [ "\fIattr\fR " [ \fIcolor ]]
.PP
-Change the way screen does highlighting for text marking and printing
-messages.
+Change the way
+.I screen
+does highlighting for text marking and printing messages.
.I Attr
is a hexadecimal number and describes the attributes (inverse,
underline, ...) the text will get.
.I Color
is a 2 digit number and changes the
-forground/background of the highlighted text.
-Some knowledge of screen's internal character representation is
+foreground/background of the highlighted text.
+Some knowledge of
+.IR screen 's
+internal character representation is
needed to make the characters appear in the desired way. The default
is currently 10 99 (standout, default colors).
.sp
.ne 3
+.B split
+.PP
+Split the current region into two new ones. All regions on the
+display are resized to make room for the new region. The blank
+window is displayed on the new region.
+.sp
+.ne 3
.B "startup_message on\fP|\fBoff"
.PP
Select whether you want to see the copyright notice during startup.
@@ -1994,16 +2434,39 @@ Stuff the string
in the input buffer of the current window.
This is like the \*Qpaste\*U command but with much less overhead.
You cannot paste
-large buffers with the \*stuff\*U command. It is most useful for key
+large buffers with the \*Qstuff\*U command. It is most useful for key
bindings. See also \*Qbindkey\*U.
.sp
.ne 3
+.B su
+.RB [ username " [" password
+.RB [ password2 ]]
+.PP
+Substitute the user of a display. The command prompts for all parameters that
+are omitted. If passwords are specified as parameters, they have to be
+specified un-crypted. The first password is matched against the systems
+passwd database, the second password is matched against the
+.I screen
+password as set with the commands \*Qacladd\*U or \*Qpassword\*U.
+\*QSu\*U may be useful for the
+.I screen
+administrator to test multiuser setups.
+.\" XXX removed in 3.8.0 XXX
+.\" but it is mainly used implicitly
+.\" by the \*Qconnect\*U command to identify users that access a remote session.
+When the identification fails, the user has access to the commands available
+for user
+.BR nobody .
+These are \*Qdetach\*U, \*Qlicense\*U, \*Qversion\*U, \*Qhelp\*U and
+\*Qdisplays\*U.
+.sp
+.ne 3
.B "suspend"
.PP
Suspend
.IR screen .
-The windows are in the `detached' state, while
-.IR screen
+The windows are in the `detached' state, while
+.I screen
is suspended. This feature relies on the shell being able to do job control.
.sp
.ne 3
@@ -2011,10 +2474,10 @@ is suspended. This feature relies on the shell being able to do job control.
.PP
In each window's environment
.I screen
-opens, the $TERM variable is set to \*Qscreen\*U by default.
+opens, the $TERM variable is set to \*Qscreen\*U by default.
But when no description for \*Qscreen\*U is installed in the local termcap
or terminfo data base, you set $TERM to \- say \-
-\*Qvt100\*U. This won't do much harm, as
+\*Qvt100\*U. This won't do much harm, as
.I screen
is VT100/ANSI compatible.
The use of the \*Qterm\*U command is discouraged for non-default purpose.
@@ -2032,14 +2495,16 @@ rlogin othermachine\*U rather than setting and resetting the default.
.BI termcapinfo " term terminal-tweaks"
.RI [ window-tweaks ]
.PP
-Use this command to modify your terminal's termcap entry without going through
-all the hassles involved in creating a custom termcap entry.
+Use this command to modify your terminal's termcap entry without going
+through all the hassles involved in creating a custom termcap entry.
Plus, you can optionally customize the termcap generated for the windows.
-If your system works with terminfo-database rather than with
-termcap,
-.I screen
-will understand the `terminfo' command, which has the same effects as
-the `termcap' command. Two separate commands are provided, as there are subtle
+You have to place these commands in one of the screenrc startup files, as
+they are meaningless once the terminal emulator is booted.
+.br
+If your system works uses the terminfo database rather than termcap,
+.I screen
+will understand the `terminfo' command, which has the same effects as the
+`termcap' command. Two separate commands are provided, as there are subtle
syntactic differences, e.g. when parameter interpolation (using `%') is
required. Note that termcap names of the capabilities have to be used
with the `terminfo' command.
@@ -2126,7 +2591,7 @@ For window specific information use \*Qinfo\*U.
.ne 3
.BR "title " [ \fIwindowalias ]
.PP
-Set the name of the current window to \fIwindowalias\fP. If no name is
+Set the name of the current window to \fIwindowalias\fP. If no name is
specified,
.I screen
prompts for one. This command was known as `aka' in previous
@@ -2138,29 +2603,45 @@ releases.
Unset an environment variable.
.sp
.ne 3
-.BR "vbell on" | off
+.B vbell
+.RB [ on | off ]
.PP
-If your terminal does not support
-a visual bell, a `vbell-message' is displayed in the status line.
-Sets the visual bell setting for this window. If your terminal does not support
-a visual bell, a `vbell-message' is displayed in the status line.
-Refer to the termcap variable `vb' (terminfo: 'flash').
+Sets the visual bell setting for this window. Omitting the parameter
+toggles the setting. If vbell is switched on, but your terminal does not
+support a visual bell, a `vbell-message' is displayed in the status line when
+the bell character (^G) is received.
+Visual bell support of a terminal is defined by the termcap variable `vb'
+(terminfo: 'flash').
+.br
+Per default, vbell is off, thus the audible bell is used.
+See also `bell_msg'.
.sp
.ne 3
-.BI "vbell_msg " message
+.B vbell_msg
+.RI [ message ]
.PP
Sets the visual bell message. \fImessage\fP is printed to the status line if
-the window receives a bell character (^G) and vbell is set to \*Qon\*U.
+the window receives a bell character (^G), vbell is set to \*Qon\*U, but the
+terminal does not support a visual bell.
The default message is \*QWuff, Wuff!!\*U.
+Without parameter, the current message is shown.
.sp
.ne 3
.BI "vbellwait " sec
.PP
-Define a delay in seconds after each display of
+Define a delay in seconds after each display of
.IR screen 's
visual bell message. The default is 1 second.
.sp
.ne 3
+.B verbose
+.RB [ on | off ]
+.PP
+If verbose is switched on, the command name is echoed, whenever a window
+is created (or resurrected from zombie state). Default is off.
+Without parameter, the current setting is shown.
+.sp
+.ne 3
.B version
.PP
Print the current version and the compile date in the status line.
@@ -2174,8 +2655,8 @@ status line.
.ne 3
.BR "width " [ \fInum ]
.PP
-Toggle the window width between 80 and 132 columns or set it to \fInum\fP
-columns if an argument is specified.
+Toggle the window width between 80 and 132 columns or set it to \fInum\fP
+columns if an argument is specified.
This requires a capable terminal and the termcap entries \*QZ0\*U and \*QZ1\*U.
See the \*Qtermcap\*U command for more information.
.sp
@@ -2191,7 +2672,7 @@ all the windows that are \*Qlogged in\*U are marked with a `$';
a background window that has received a bell is marked with a `!';
a background window that is being monitored and has had activity occur
is marked with an `@';
-a window which has output logging turned on is marked with `(L)';
+a window which has output logging turned on is marked with `(L)';
windows occupied by other users are marked with `&';
windows in the zombie state are marked with `Z'.
If this list is too long to fit on the terminal's status line only the
@@ -2224,7 +2705,7 @@ the same window at once. Per default, writelock is in `auto' mode and
grants exclusive input permission to the user who is the first to switch
to the particular window. When he leaves the window, other users may obtain
the writelock (automatically). The writelock of the current window is disabled
-by the command \*Qwritelock off\*U. If the user issues the command
+by the command \*Qwritelock off\*U. If the user issues the command
\*Qwritelock on\*U he keeps the exclusive write permission while switching
to other windows.
.sp
@@ -2242,14 +2723,16 @@ current window.
.BR "defzombie " [\fIkeys\fP]
.PP
Per default
-.I screen
+.I screen
windows are removed from the window list as soon as
the windows process (e.g. shell) exits. When a string of two keys is
specified to the zombie command, `dead' windows will remain in the list.
-The \fBkill\fP kommand may be used to remove such a window. Pressing the
-first key in the dead window has the same effect. When pressing the second
-key, screen will attempt to resurrect the window. The process that was
-initially running in the window will be launched again. Calling \fBzombie\fP
+The \fBkill\fP command may be used to remove such a window. Pressing the
+first key in the dead window has the same effect. When pressing the second
+key,
+.I screen
+will attempt to resurrect the window. The process that was
+initially running in the window will be launched again. Calling \fBzombie\fP
without parameters will clear the zombie setting, thus making windows disappear
when their process exits.
@@ -2281,6 +2764,173 @@ echo '<esc>^Hello world from window '$WINDOW'<esc>\e\e'
where '<esc>' is an \fIescape\fP, '^' is a literal up-arrow,
and '\e\e' turns into a single backslash.
+.SH "WINDOW TYPES"
+Screen provides three different window types. New windows are created with
+.IR screen 's
+.B screen
+command (see also the entry in chapter \*QCUSTOMIZATION\*U). The first
+parameter to the
+.B screen
+command defines which type of window is created. The different window types are
+all special cases of the normal type. They have been added in order
+to allow
+.I screen
+to be used efficiently as a console multiplexer with 100 or more windows.
+
+.IP \(bu 3
+The normal window contains a shell (default, if no parameter is given) or any
+other system command that could be executed from a shell (e.g.
+.BR slogin ,
+etc...)
+
+.IP \(bu
+If a tty (character special device) name (e.g. \*Q/dev/ttya\*U)
+is specified as the first parameter, then the window is directly connected to
+this device.
+This window type is similar to \*Qscreen cu -l /dev/ttya\*U.
+Read and write access is required on the device node, an exclusive open is
+attempted on the node to mark the connection line as busy.
+An optional parameter is allowed consisting of a comma separated list of flags
+in the notation used by stty(1):
+.RS
+.IP <baud_rate>
+Usually 300, 1200, 9600 or 19200. This affects transmission as well as receive speed.
+.IP "cs8 or cs7"
+Specify the transmission of eight (or seven) bits per byte.
+.IP "ixon or -ixon"
+Enables (or disables) software flow-control (CTRL-S/CTRL-Q) for sending data.
+.IP "ixoff or -ixon"
+Enables (or disables) software flow-control for receiving data.
+.IP "istrip or -istrip"
+Clear (or keep) the eight bit in each received byte.
+.PP
+You may want to specify as many of these options as applicable. Unspecified
+options cause the terminal driver to make up the parameter values of the
+connection. These values are system dependant and may be in defaults or values
+saved from a previous connection.
+.PP
+For tty windows, the
+.B info
+command shows some of the modem control lines
+in the status line. These may include `RTS', `CTS', 'DTR', `DSR', `CD' and more.
+This depends on the available ioctl()'s and system header files as well as the
+on the physical capabilities of the serial board.
+Signals that are logical low (inactive) have their name preceded by
+an exclamation mark (!), otherwise the signal is logical high (active).
+Signals not supported by the hardware but available to the ioctl() interface
+are usually shown low.
+.br
+When the CLOCAL status bit is true, the whole set of modem signals is placed
+inside curly braces ({ and }).
+When the CRTSCTS or TIOCSOFTCAR bit is set, the signals `CTS' or `CD'
+are shown in parenthesis, respectively.
+
+
+For tty windows, the command
+.B break
+causes the Data transmission line (TxD) to go low for a specified period of
+time. This is expected to be interpreted as break signal on the other side.
+No data is sent and no modem control line is changed when a
+.B break
+is issued.
+.RE
+.IP \(bu
+If the first parameter is \*Q//telnet\*U, the second parameter is expected to
+be a host name, and an optional third parameter may specify a TCP port number
+(default decimal 23). Screen will connect to a server listening on the remote
+host and use the telnet protocol to communicate with that server.
+.br
+.br
+For telnet windows, the command
+.B info
+shows details about the connection in square brackets ([ and ]) at the end of
+the status line.
+.RS
+.IP b
+BINARY. The connection is in binary mode.
+.IP e
+ECHO. Local echo is disabled.
+.IP c
+SGA. The connection is in `character mode' (default: `line mode').
+.IP t
+TTYPE. The terminal type has been requested by the remote host.
+Screen sends the name \*Qscreen\*U unless instructed otherwise (see also
+the command `term').
+.IP w
+NAWS. The remote site is notified about window size changes.
+.IP f
+LFLOW. The remote host will send flow control information.
+(Ignored at the moment.)
+.PP
+Additional flags for debugging are x, t and n (XDISPLOC, TSPEED and
+NEWENV).
+.PP
+For telnet windows, the command
+.B break
+sends the telnet code IAC BREAK (decimal 243) to the remote host.
+
+
+This window type is only available if
+.I screen
+was compiled with the BUILTIN_TELNET option defined.
+.RE
+
+
+.SH "STRING ESCAPES"
+Screen provides an escape mechanism to insert information like the
+current time into messages or file names. The escape character
+is '%' with one exception: inside of a window's hardstatus '^%' ('^E')
+is used instead.
+
+Here is the full list of supported escapes:
+.IP %
+the escape character itself
+.IP a
+either 'am' or 'pm'
+.IP A
+either 'AM' or 'PM'
+.IP c
+current time HH:MM in 24h format
+.IP C
+current time HH:MM in 12h format
+.IP d
+day number
+.IP D
+weekday name
+.IP h
+hardstatus of the window
+.IP l
+current load of the system
+.IP m
+month number
+.IP M
+month name
+.IP n
+window number
+.IP s
+seconds
+.IP t
+window title
+.IP u
+all other users on this window
+.IP w
+all window numbers and names
+.IP W
+all window numbers and names except the current one
+.IP y
+last two digits of the year number
+.IP Y
+full year number
+.IP ?
+the part to the next '%?' is displayed only if an escape expands to an
+nonempty string
+.IP :
+else part of '%?'
+.P
+The 'c' and 'C' escape may be qualified with a '0' to make
+.I screen
+use zero instead of space as fill character. The 'n' escape understands
+a length qualifier (e.g. '%3n').
.SH "FLOW-CONTROL"
Each window has a flow-control setting that determines how
@@ -2479,7 +3129,7 @@ PROMPT_COMMAND='echo -n -e "\e033k\e033\e134"'
Each window in a
.I screen
session emulates a VT100 terminal, with some extra functions added. The
-VT100 emulator is hardcoded, no other terminal types can be emulated.
+VT100 emulator is hard-coded, no other terminal types can be emulated.
.br
Usually
.I screen
@@ -2500,10 +3150,10 @@ But if you do a
rlogin on another machine or your machine supports only
terminfo this method fails. Because of this,
.I screen
-offers a way to deal with these cases.
+offers a way to deal with these cases.
Here is how it works:
.PP
-When
+When
.I screen
tries to figure out a terminal name for itself,
it first looks
@@ -2556,7 +3206,7 @@ window's $TERMCAP variable.
This can either be the full terminal definition, or a filename where the
terminal \*Qscreen\*U (and/or \*Qscreen-w\*U) is defined.
.PP
-Note that
+Note that
.I screen
honors the \*Qterminfo\*U .screenrc command if the system uses the
terminfo database rather than termcap.
@@ -2579,9 +3229,9 @@ When the `G0' capability is present,
.I screen
evaluates the capabilities
`S0', `E0', and `C0' if present. `S0' is the sequence the terminal uses
-to enable and start the graphics character set rather than \fISI\fP.
+to enable and start the graphics character set rather than \fISI\fP.
`E0' is the corresponding replacement for \fISO\fP. `C0' gives a character
-by character translation string that is used during semi-graphics mode. This
+by character translation string that is used during semi-graphics mode. This
string is built like the `acsc' terminfo capability.
.PP
When the `po' and `pf' capabilities are present in the terminal's
@@ -2594,13 +3244,17 @@ other windows are still active (the printer port is enabled
and disabled again for each chunk of output).
As a side-effect, programs running in different windows can
send output to the printer simultaneously.
-Data sent to the printer is not displayed in the window.
+Data sent to the printer is not displayed in the window. The
+.I info
+command displays a line starting `PRIN' while the printer is active.
.PP
.I Screen
maintains a hardstatus line for every window. If a window
gets selected, the display's hardstatus will be updated to match
the window's hardstatus line. If the display has no hardstatus
-the line will be displayed as a standard screen message.
+the line will be displayed as a standard
+.I screen
+message.
The hardstatus line can be changed with the ANSI Application
Program Command (APC): \*QESC_<string>ESC\e\*U. As a convenience
for xterm users the sequence \*QESC]0..2;<string>^G\*U is
@@ -2611,7 +3265,7 @@ variable of the virtual terminal if they can be efficiently
implemented by the physical terminal.
For instance, `dl' (delete line) is only put into the $TERMCAP
variable if the terminal supports either delete line itself or
-scrolling regions. Note that this may provoke confusion, when
+scrolling regions. Note that this may provoke confusion, when
the session is reattached on a different terminal, as the value
of $TERMCAP cannot be modified by parent processes.
.PP
@@ -2730,7 +3384,7 @@ Designate character set as G3
Direct Cursor Addressing
.TP 27
.B "ESC [ \fPPn\fB ; \fPPn\fB f"
-Direct Cursor Addressing
+same as above
.TP 27
.B "ESC [ \fPPn\fB J"
Erase in Display
@@ -2768,6 +3422,21 @@ Cursor Right
.B "ESC [ \fPPn\fB D"
Cursor Left
.TP 27
+.B "ESC [ \fPPn\fB E"
+Cursor next line
+.TP 27
+.B "ESC [ \fPPn\fB F"
+Cursor previous line
+.TP 27
+.B "ESC [ \fPPn\fB G"
+Cursor horizontal position
+.TP 27
+.B "ESC [ \fPPn\fB `"
+same as above
+.TP 27
+.B "ESC [ \fPPn\fB d"
+Cursor vertical position
+.TP 27
.B "ESC [ \fPPs\fB ;\fP...\fB; \fPPs\fB m"
Select Graphic Rendition
.TP 27
@@ -2879,6 +3548,9 @@ Scroll Scrolling Region Up
.B "ESC [ \fPPn\fB T"
Scroll Scrolling Region Down
.TP 27
+.B "ESC [ \fPPn\fB ^"
+same as above
+.TP 27
.B "ESC [ \fPPs\fB ;\fP...\fB; \fPPs\fB h"
Set Mode
.TP 27
@@ -2935,11 +3607,13 @@ Send Cursor Position Report
.SH "INPUT TRANSLATION"
-In order to do a full VT100 emulation \fIscreen\fP has to detect
+In order to do a full VT100 emulation
+.I screen
+has to detect
that a sequence of characters in the input stream was generated
by a keypress on the user's keyboard and insert the VT100
style escape sequence. \fIScreen\fP has a very flexible way of doing
-this by making it posible to map arbitrary commands on arbitrary
+this by making it possible to map arbitrary commands on arbitrary
sequences of characters. For standard VT100 emulation the command
will always insert a string in the input buffer of the window
(see also command \fBstuff\fP in the command table).
@@ -3028,8 +3702,9 @@ Keypad enter fe stuff \e015
.SH SPECIAL TERMINAL CAPABILITIES
The following table describes all terminal capabilities
-that are recognized by \fIscreen\fP and are not in the
-termcap(5) manual.
+that are recognized by
+.I screen
+and are not in the termcap(5) manual.
You can place these capabilities in your termcap entries (in
`/etc/termcap') or use them with the commands `termcap', `terminfo' and
`termcapinfo' in your screenrc files. It is often not possible to place
@@ -3039,8 +3714,9 @@ these capabilities in the terminfo database.
.TP 13
.BI LP " (bool)"
Terminal has VT100 style margins (`magic margins'). Note that
-this capability is obsolete because \fIscreen\fP uses the standard 'xn'
-instead.
+this capability is obsolete because
+.I screen
+uses the standard 'xn' instead.
.TP 13
.BI Z0 " (str)"
Change width to 132 columns.
@@ -3073,10 +3749,10 @@ Use the string as a conversion table for font '0'. See
the 'ac' capability for more details.
.TP 13
.BI CS " (str)"
-Switch cursorkeys to application mode.
+Switch cursor-keys to application mode.
.TP 13
.BI CE " (str)"
-Switch cursorkeys back to normal mode.
+Switch cursor-keys back to normal mode.
.TP 13
.BI AN " (bool)"
Turn on autonuke. See the 'autonuke' command for more details.
@@ -3089,7 +3765,7 @@ Set the kanji type of the terminal. Valid strings are \*Qjis\*U,
\*Qeuc\*U and \*Qsjis\*U.
.TP 13
.BI AF " (str)"
-Change character forground color in an ANSI conform way. This
+Change character foreground color in an ANSI conform way. This
capability will almost always be set to '\eE[3%dm' ('\eE[3%p1%dm'
on terminfo machines).
.TP 13
@@ -3102,6 +3778,9 @@ Does understand ANSI set default fg/bg color (\eE[39m / \eE[49m).
.BI XC " (str)"
Describe a translation of characters to strings depending on the
current font. More details follow in the next section.
+.TP 13
+.BI TF " (bool)"
+Add missing capabilities to the termcap/info entry. (Set by default).
.SH CHARACTER TRANSLATION
\fIScreen\fP has a powerful mechanism to translate characters to arbitrary
@@ -3119,12 +3798,14 @@ Syntax:
The things in braces may be repeated any number of times.
-A \fI<charset-mapping>\fP tells \fIscreen\fP how to map characters
+A \fI<charset-mapping>\fP tells
+.I screen
+how to map characters
in font \fI<designator>\fP ('B': Ascii, 'A': UK, 'K': german, etc.)
to strings. Every \fI<mapping>\fP describes to what string a single
character will be translated. A template mechanism is used, as
most of the time the codes have a lot in common (for example
-strings to switch to and from another charset). Each occurence
+strings to switch to and from another charset). Each occurrence
of '%' in \fI<template>\fP gets substituted with the \fI<template-arg>\fP
specified together with the character. If your strings are not
similar at all, then use '%' as a template and place the full
@@ -3136,7 +3817,9 @@ Here is an example:
termcap hp700 'XC=B\eE(K%\eE(B,\e304[,\e326\e\e\e\e,\e334]'
-This tells \fIscreen\fP, how to translate ISOlatin1 (charset 'B')
+This tells .I
+screen
+how to translate ISOlatin1 (charset 'B')
upper case umlaut characters on a hp700 terminal that has a
german charset. '\e304' gets translated to '\eE(K[\eE(B' and so on.
Note that this line gets parsed *three* times before the internal
@@ -3145,9 +3828,11 @@ create a single '\e'.
Another extension was added to allow more emulation: If a mapping
translates the unquoted '%' char, it will be sent to the terminal
-whenever \fIscreen\fP switches to the corresponding \fI<designator>\fP. In this
+whenever
+.I screen
+switches to the corresponding \fI<designator>\fP. In this
special case the template is assumed to be just '%' because
-the charset switch sequence and the character mappings normaly
+the charset switch sequence and the character mappings normally
haven't much in common.
This example shows one use of the extension:
@@ -3155,7 +3840,9 @@ This example shows one use of the extension:
termcap xterm 'XC=K%,%\eE(B,[\e304,\e\e\e\e\e326,]\e334'
Here, a part of the german ('K') charset is emulated on an xterm.
-If \fIscreen\fP has to change to the 'K' charset, '\eE(B' will be sent
+If
+.I screen
+has to change to the 'K' charset, '\eE(B' will be sent
to the terminal, i.e. the ASCII charset is used instead. The
template is just '%', so the mapping is straightforward: '['
to '\e304', '\e' to '\e326', and ']' to '\e334'.
@@ -3166,9 +3853,7 @@ to '\e304', '\e' to '\e326', and ']' to '\e334'.
Number of columns on the terminal (overrides termcap entry).
.IP HOME
Directory in which to look for .screenrc.
-.IP ISCREENRC
-Alternate user screenrc file.
-.IP LINES
+.IP LINES
Number of lines on the terminal (overrides termcap entry).
.IP LOCKPRG
Screen lock program.
@@ -3196,15 +3881,18 @@ Terminal description.
.SH FILES
.PD 0
-.IP $SYSSCREENRC 28
-.IP /local/etc/screenrc
-\fIscreen\fP initialization commands
-.IP $ISCREENRC
+.IP .../screen-3.?.??/etc/screenrc 34
+.IP .../screen-3.?.??/etc/etcscreenrc
+Examples in the
+.I screen
+distribution package for private and global initialization files.
+.IP $SYSSCREENRC
+.IP /usr/local/etc/screenrc
+.I screen
+initialization commands
.IP $SCREENRC
-.IP $HOME/.iscreenrc
.IP $HOME/.screenrc
-Read in after /local/etc/screenrc
-.IP $ISCREENDIR/S-<login>
+Read in after /usr/local/etc/screenrc
.IP $SCREENDIR/S-<login>
.IP /local/screens/S-<login>
Socket directories (default)
@@ -3215,7 +3903,8 @@ Written by the "termcap" output function
.IP /usr/tmp/screens/screen-exchange
or
.IP /tmp/screen-exchange
-\fIscreen\fP `interprocess communication buffer'
+.I screen
+`interprocess communication buffer'
.IP hardcopy.[0-9]
Screen images created by the hardcopy function
.IP screenlog.[0-9]
@@ -3240,7 +3929,7 @@ produced by Wayne Davison, Juergen Weigert and Michael Schroeder.
.SH COPYLEFT
.nf
-Copyright (C) 1993
+Copyright (C) 1999
Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
Copyright (C) 1987 Oliver Laumann
@@ -3265,7 +3954,7 @@ Free Software Foundation, Inc.,
.nf
Ken Beal (kbeal@amber.ssd.csd.harris.com),
Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de),
-Toerless Eckert (eckert@immd4.informatik.uni-erlangen.de),
+Toerless Eckert (eckert@immd4.informatik.uni-erlangen.de),
Wayne Davison (davison@borland.com),
Patrick Wolfe (pat@kai.com, kailand!pat),
Bart Schaefer (schaefer@cse.ogi.edu),
@@ -3284,7 +3973,7 @@ Frank van der Linden (vdlinden@fwi.uva.nl),
Martin Schweikert (schweik@cpp.ob.open.de),
David Vrona (dave@sashimi.lcu.com),
E. Tye McQueen (tye%spillman.UUCP@uunet.uu.net),
-Matthew Green (mrgreen@mame.mu.oz.au),
+Matthew Green (mrg@mame.mu.oz.au),
Christopher Williams (cgw@unt.edu),
Matt Mosley (mattm@access.digex.net),
Gregory Neil Shapiro (gshapiro@wpi.WPI.EDU).
@@ -3292,11 +3981,22 @@ Gregory Neil Shapiro (gshapiro@wpi.WPI.EDU).
.SH VERSION
-This is version 3.7.0. Its roots are a merge of a custom version
+This is version 3.9 Its roots are a merge of a custom version
2.3PR7 by Wayne Davison
and several enhancements to Oliver Laumann's version 2.0. Note that all versions
-numbered 2.x are copyright by Oliver Laumann.
+numbered 2.x are copyright by Oliver Laumann.
+.SH AVAILABILITY
+The latest official release of
+.I screen
+available via anonymous ftp from prep.ai.mit.edu, nic.funet.fi or any other
+.I GNU
+distribution site. The home site of
+.I screen
+is ftp.uni-erlangen.de (131.188.3.71), in the directory
+pub/utilities/screen. The subdirectory `private' contains the latest beta
+testing release. If you want to help, send a note to
+screen@uni-erlangen.de.
.SH BUGS
.PD
@@ -3306,12 +4006,12 @@ correctly (they are ignored). `xn' is treated as a magic-margin
indicator.
.IP \(bu
.I Screen
-has no clue about double-high or double-wide characters.
-But this is the only area where
+has no clue about double-high or double-wide characters.
+But this is the only area where
.I vttest
is allowed to fail.
.IP \(bu
-It is not possible to change the environment variable $TERMCAP when
+It is not possible to change the environment variable $TERMCAP when
reattaching under a different terminal type.
.IP \(bu
The support of terminfo based systems is very limited. Adding extra
@@ -3321,9 +4021,9 @@ capabilities to $TERMCAP may not have any effects.
does not make use of hardware tabs.
.IP \(bu
.I Screen
-must be installed as set-uid with owner root in order to be able
-to correctly change the owner of the tty device file for each
-window.
+must be installed as set-uid with owner root on most systems in order
+to be able to correctly change the owner of the tty device file for
+each window.
Special permission may also be required to write the file \*Q/etc/utmp\*U.
.IP \(bu
Entries in \*Q/etc/utmp\*U are not removed when
@@ -3335,16 +4035,28 @@ to advertise that a user is logged on who really isn't.
.I Screen
may give a strange warning when your tty has no utmp entry.
.IP \(bu
-When the modem line was hung up,
+When the modem line was hung up,
.I screen
may not automatically detach (or quit)
-unless the device driver is configured to send a HANGUP signal.
-To detach a
+unless the device driver is configured to send a HANGUP signal.
+To detach a
.I screen
session use the -D or -d command line option.
.IP \(bu
+If a password is set, the command line options -d and -D still detach a
+session without asking.
+.IP \(bu
+Both \*Qbreaktype\*U and \*Qdefbreaktype\*U change the break generating
+method used by all terminal devices. The first should change a window
+specific setting, where the latter should change only the default for new
+windows.
+.IP \(bu
+When attaching to a multiuser session, the user's .screenrc file is not
+sourced. Each user's personal settings have to be included in the .screenrc
+file from which the session is booted, or have to be changed manually.
+.IP \(bu
A weird imagination is most useful to gain full advantage of all the features.
.IP \(bu
-Send bugreports, fixes, enhancements, t-shirts, money, beer & pizza to
+Send bug-reports, fixes, enhancements, t-shirts, money, beer & pizza to
.BR screen@uni-erlangen.de .
diff --git a/doc/screen.info b/doc/screen.info
index 06243df..11447c5 100644
--- a/doc/screen.info
+++ b/doc/screen.info
@@ -3,7 +3,7 @@ file ./screen.texinfo.
This file documents the `Screen' virtual terminal manager.
- Copyright (c) 1993 Free Software Foundation, Inc.
+ Copyright (c) 1993-1995 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
@@ -21,147 +21,161 @@ translation approved by the Foundation.

Indirect:
-screen.info-1: 873
-screen.info-2: 50135
-screen.info-3: 99940
-screen.info-4: 149859
+screen.info-1: 878
+screen.info-2: 50660
+screen.info-3: 100483
+screen.info-4: 150213

Tag Table:
(Indirect)
-Node: Top873
-Node: Overview2756
-Node: Getting Started6129
-Node: Invoking Screen7887
-Node: Customization13559
-Node: Startup Files14046
-Node: Colon15692
-Node: Commands16314
-Node: Default Key Bindings17272
-Node: Command Summary22227
-Node: New Window32611
-Node: Chdir33374
-Node: Screen Command34345
-Node: Setenv35983
-Node: Shell36503
-Node: Term37176
-Node: Selecting37936
-Node: Next and Previous38473
-Node: Other Window38999
-Node: Select39408
-Node: Session Management40011
-Node: Detach40848
-Node: Power Detach42133
-Node: Lock42772
-Node: Multiuser Session43658
-Node: Multiuser44416
-Node: Acladd44803
-Node: Aclchg45298
-Node: Acldel46621
-Node: Wall46954
-Node: Writelock47192
-Node: Session Name48085
-Node: Suspend48632
-Node: Quit48964
-Node: Window Settings49389
-Node: Naming Windows50135
-Node: Title Command51635
-Node: Dynamic Titles51909
-Node: Title Prompts53443
-Node: Title Screenrc54524
-Node: Console56163
-Node: Kill56605
-Node: Login57428
-Node: Mode58247
-Node: Monitor58645
-Node: Windows60056
-Node: Hardstatus61065
-Node: Virtual Terminal62236
-Node: Control Sequences63293
-Node: Input Translation69794
-Node: Digraph74310
-Node: Bell75102
-Node: Clear76940
-Node: Info77143
-Node: Redisplay77969
-Node: Wrap79101
-Node: Reset79852
-Node: Window Size80170
-Node: Character Processing80785
-Node: Copy and Paste83657
-Node: Copy84262
-Node: Line Termination85107
-Node: Scrollback85516
-Node: Copy Mode Keys86005
-Node: Movement86820
-Node: Marking87974
-Node: Repeat count88349
-Node: Searching88663
-Node: Specials88925
-Node: Paste90857
-Node: Registers93418
-Node: Screen-Exchange94424
-Node: History95507
-Node: Subprocess Execution96247
-Node: Exec96611
-Node: Using Exec98201
-Node: Key Binding99940
-Node: Bind100583
-Node: Bind Examples101570
-Node: Command Character102250
-Node: Help103758
-Node: Bindkey104271
-Node: Bindkey Examples105814
-Node: Bindkey Control106699
-Node: Flow Control107296
-Node: Flow Control Summary107872
-Node: Flow110806
-Node: XON/XOFF111580
-Node: Termcap111953
-Node: Window Termcap112810
-Node: Dump Termcap117968
-Node: Termcap Syntax118683
-Node: Termcap Examples120843
-Node: Special Capabilities122884
-Node: Autonuke125348
-Node: Obuflimit125998
-Node: Character Translation126827
-Node: Message Line129438
-Node: Privacy Message130349
-Node: Hardware Status Line130846
-Node: Last Message131475
-Node: Message Wait131902
-Node: Logging132328
-Node: Hardcopy132652
-Node: Log133448
-Node: Startup134196
-Node: echo134603
-Node: sleep135009
-Node: Startup Message135350
-Node: Miscellaneous135623
-Node: At136612
-Node: Break137920
-Node: Debug138323
-Node: License138707
-Node: Nethack138972
-Node: Number139648
-Node: Silence140017
-Node: Time140784
-Node: Version141158
-Node: Zombie141364
-Node: Printcmd142418
-Node: Sorendition143124
-Node: Environment143775
-Node: Files144857
-Node: Credits145983
-Node: Bugs147900
-Node: Known Bugs148370
-Node: Reporting Bugs149859
-Node: Availability150635
-Node: Installation151081
-Node: Socket Directory151471
-Node: Compiling Screen152001
-Node: Concept Index153393
-Node: Command Index155173
-Node: Keystroke Index162058
+Node: Top878
+Node: Overview2886
+Node: Getting Started6518
+Node: Invoking Screen8276
+Node: Customization16304
+Node: Startup Files16791
+Node: Colon18437
+Node: Commands19059
+Node: Default Key Bindings20017
+Node: Command Summary25596
+Node: New Window37785
+Node: Chdir38617
+Node: Screen Command39588
+Node: Setenv41289
+Node: Shell41809
+Node: Term42575
+Node: Window Types43356
+Node: Selecting47674
+Node: Next and Previous48228
+Node: Other Window48754
+Node: Select49163
+Node: Session Management49831
+Node: Detach50660
+Node: Power Detach51945
+Node: Lock52584
+Node: Multiuser Session53470
+Node: Multiuser54432
+Node: Acladd54819
+Node: Aclchg55384
+Node: Acldel56790
+Node: Aclgrp57125
+Node: Displays57776
+Node: Umask58070
+Node: Wall59051
+Node: Writelock59288
+Node: Su60184
+Node: Session Name60984
+Node: Suspend61531
+Node: Quit61863
+Node: Regions62288
+Node: Split62773
+Node: Focus63063
+Node: Only63325
+Node: Remove63489
+Node: Caption63698
+Node: Window Settings64443
+Node: Naming Windows65178
+Node: Title Command66678
+Node: Dynamic Titles66952
+Node: Title Prompts68486
+Node: Title Screenrc69567
+Node: Console71206
+Node: Kill71649
+Node: Login72541
+Node: Mode73360
+Node: Monitor73759
+Node: Windows75172
+Node: Hardstatus76234
+Node: Virtual Terminal77427
+Node: Control Sequences78485
+Node: Input Translation85315
+Node: Digraph89831
+Node: Bell90623
+Node: Clear92502
+Node: Info92705
+Node: Redisplay94567
+Node: Wrap95698
+Node: Reset96449
+Node: Window Size96767
+Node: Character Processing97612
+Node: Copy and Paste100483
+Node: Copy101088
+Node: Line Termination101933
+Node: Scrollback102342
+Node: Copy Mode Keys103079
+Node: Movement103894
+Node: Marking105048
+Node: Repeat count105423
+Node: Searching105737
+Node: Specials105999
+Node: Paste107953
+Node: Registers110625
+Node: Screen-Exchange111631
+Node: History112714
+Node: Subprocess Execution113454
+Node: Exec113818
+Node: Using Exec115564
+Node: Key Binding117403
+Node: Bind118046
+Node: Bind Examples119033
+Node: Command Character119713
+Node: Help121254
+Node: Bindkey121767
+Node: Bindkey Examples123313
+Node: Bindkey Control124202
+Node: Flow Control124799
+Node: Flow Control Summary125375
+Node: Flow128309
+Node: XON/XOFF129083
+Node: Termcap129456
+Node: Window Termcap130313
+Node: Dump Termcap135556
+Node: Termcap Syntax136271
+Node: Termcap Examples138438
+Node: Special Capabilities140479
+Node: Autonuke143042
+Node: Obuflimit143692
+Node: Character Translation144521
+Node: Message Line147134
+Node: Privacy Message148045
+Node: Hardware Status Line148542
+Node: Last Message150213
+Node: Message Wait150640
+Node: Logging151066
+Node: Hardcopy151390
+Node: Log152186
+Node: Startup153802
+Node: echo154209
+Node: sleep154617
+Node: Startup Message154958
+Node: Miscellaneous155231
+Node: At156339
+Node: Break158333
+Node: Debug159980
+Node: License160457
+Node: Nethack160722
+Node: Nonblock161400
+Node: Number161854
+Node: Silence162224
+Node: Time163160
+Node: Verbose163534
+Node: Version163868
+Node: Zombie164077
+Node: Printcmd165131
+Node: Sorendition165837
+Node: String Escapes166489
+Node: Environment167814
+Node: Files168849
+Node: Credits169936
+Node: Bugs171849
+Node: Known Bugs172319
+Node: Reporting Bugs174413
+Node: Availability175179
+Node: Installation175723
+Node: Socket Directory176113
+Node: Compiling Screen176643
+Node: Concept Index178035
+Node: Command Index180092
+Node: Keystroke Index188392

End Tag Table
diff --git a/doc/screen.info-1 b/doc/screen.info-1
index 6d39c2c..d9d4b04 100644
--- a/doc/screen.info-1
+++ b/doc/screen.info-1
@@ -3,7 +3,7 @@ file ./screen.texinfo.
This file documents the `Screen' virtual terminal manager.
- Copyright (c) 1993 Free Software Foundation, Inc.
+ Copyright (c) 1993-1995 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
@@ -26,7 +26,7 @@ Screen
******
This file documents the `Screen' virtual terminal manager, version
-3.7.0.
+3.9.0.
* Menu:
@@ -37,8 +37,9 @@ Screen
* Commands:: List all of the commands.
* New Window:: Running a program in a new window.
* Selecting:: Selecting a window to display.
-* Session Management:: Suspending or detaching a session.
-* Window Settings:: titles, logging, etc.
+* Session Management:: Suspend/detach, grant access, connect sessions.
+* Regions:: Split-screen commands.
+* Window Settings:: Titles, logging, etc.
* Virtual Terminal:: Controlling the `screen' VT100 emulation.
* Copy and Paste:: Exchanging text between windows and sessions.
* Subprocess Execution:: I/O filtering with `exec'.
@@ -49,6 +50,7 @@ Screen
* Logging:: Keeping a record of your session.
* Startup:: Functions only useful at `screen' startup.
* Miscellaneous:: Various other commands.
+* String Escapes:: Inserting current information into strings
* Environment:: Environment variables used by `screen'.
* Files:: Files used by `screen'.
* Credits:: Who's who of `screen'.
@@ -67,11 +69,11 @@ Overview
Screen is a full-screen window manager that multiplexes a physical
terminal between several processes, typically interactive shells. Each
virtual terminal provides the functions of the DEC VT100 terminal and,
-in addition, several control functions from the ANSI X3.64 (ISO 6429)
-and ISO 2022 standards (e.g. insert/delete line and support for multiple
-character sets). There is a scrollback history buffer for each virtual
-terminal and a copy-and-paste mechanism that allows the user to move
-text regions between windows.
+in addition, several control functions from the ISO 6429 (ECMA 48, ANSI
+X3.64) and ISO 2022 standards (e.g. insert/delete line and support for
+multiple character sets). There is a scrollback history buffer for
+each virtual terminal and a copy-and-paste mechanism that allows the
+user to move text regions between windows.
When `screen' is called, it creates a single window with a shell in
it (or the specified command) and then gets out of your way so that you
@@ -82,7 +84,7 @@ windows, turn output logging on and off, copy text between windows, view
the scrollback history, switch between windows, etc. All windows run
their programs completely independent of each other. Programs continue
to run when their window is currently not visible and even when the
-whole screen session is detached from the users terminal.
+whole screen session is detached from the user's terminal.
When a program terminates, `screen' (per default) kills the window
that contained it. If this window was in the foreground, the display
@@ -98,6 +100,11 @@ Character::.) and all the key bindings (*note Key Binding::.) can be
fully customized to be anything you like, though they are always two
characters in length.
+ `Screen' does not understand the prefix `C-' to mean control.
+Please use the caret notation (`^A' instead of `C-a') as arguments to
+e.g. the `escape' command or the `-e' option. `Screen' will also print
+out control characters in caret notation.
+
The standard way to create a new window is to type `C-a c'. This
creates a new window running a shell and switches to that window
immediately, regardless of the state of the process running in the
@@ -188,11 +195,35 @@ Invoking `Screen'
running elsewhere (*note Detach::.). `-d' has the same effect as
typing `C-a d' from the controlling terminal for the session.
`-D' is the equivalent to the power detach key. If no session can
- be detached, this option is ignored. The combination `screen -D
- -r' can be used to log out from a remote terminal and transport the
- session running there to your current terminal. *Note*: It is a
- good idea to check the status of your sessions with `screen -list'
- before using this option.
+ be detached, this option is ignored. In combination with the
+ `-r'/`-R' option more powerful effects can be achieved:
+
+ `-d -r'
+ Reattach a session and if necessary detach it first.
+
+ `-d -R'
+ Reattach a session and if necessary detach or even create
+ it first.
+
+ `-d -RR'
+ Reattach a session and if necessary detach or create it. Use
+ the first session if more than one session is available.
+
+ `-D -r'
+ Reattach a session. If necessary detach and logout remotely
+ first.
+
+ `-D -R'
+ Attach here and now. In detail this means: If a session is
+ running, then reattach. If necessary detach and logout
+ remotely first. If it was not running create it and notify
+ the user. This is the author's favorite.
+
+ `-D -RR'
+ Attach here and now. Whatever that means, just do it.
+
+ *Note*: It is a good idea to check the status of your sessions
+ with `screen -list' before using this option.
`-e XY'
Set the command character to X, and the character generating a
@@ -228,16 +259,21 @@ Invoking `Screen'
Turn login mode on or off (for `/etc/utmp' updating). This option
is equivalent to the `deflogin' command (*note Login::.).
-`-ls'
-`-list'
+`-ls [MATCH]'
+`-list [MATCH]'
Do not start `screen', but instead print a list of session
identification strings (usually of the form PID.TTY.HOST; *note
Session Name::.). Sessions marked `detached' can be resumed with
`screen -r'. Those marked `attached' are running and have a
- controlling terminal. Sessions marked as `dead' should be
- thoroughly checked and removed. Ask your system administrator if
- you are not sure why they died. Remove sessions with the `-wipe'
- option.
+ controlling terminal. If the session runs in multiuser mode, it
+ is marked `multi'. Sessions marked as `unreachable' either live
+ on a different host or are dead. An unreachable session is
+ considered dead, when its name matches either the name of the
+ local host, or the specified parameter, if any. See the `-r' flag
+ for a description how to construct matches. Sessions marked as
+ `dead' should be thoroughly checked and removed. Ask your system
+ administrator if you are not sure. Remove sessions with the
+ `-wipe' option.
`-L'
Tell `screen' that your auto-margin terminal allows programs to
@@ -249,24 +285,44 @@ Invoking `Screen'
Tell `screen' to ignore the `$STY' environment variable. When
this option is used, a new session will always be created,
regardless of whether `screen' is being called from within another
- `screen' session or not.
+ `screen' session or not. This flag has a special meaning in
+ connection with the `-d' option:
+ `-m -d'
+ Start `screen' in *detached* mode. This creates a new session
+ but doesn't attach to it. This is useful for system startup
+ scripts.
+
+ `-m -D'
+ This also starts `screen' in *detached* mode, but doesn't fork
+ a new process. The command exits if the session terminates.
+
+`-q'
+ Suppress printing of error messages. In combination with `-ls' the
+ exit value is set as follows: 9 indicates a directory without
+ sessions. 10 indicates a directory with running but not attachable
+ sessions. 11 (or more) indicates 1 (or more) usable sessions. In
+ combination with `-r' the exit value is as follows: 10 indicates
+ that there is no session to resume. 12 (or more) indicates that
+ there are 2 (or more) sessions to resume and you should specify
+ which one to choose. In all other cases `-q' has no effect.
`-r [PID.SESSIONNAME]'
`-r SESSIONOWNER/[PID.SESSIONNAME]'
- Resume a detached `screen' session. No other options (except `-d'
- or `-D') may be specified, though the session name (*note Session
- Name::.) may be needed to distinguish between multiple detached
- `screen' sessions. The second form is used to connect to another
- users screen session which runs in multi-user mode. This indicates
- that screen should look for sessions in another users directory.
- This requires setuid-root.
+ Resume a detached `screen' session. No other options (except
+ combinations with `-d' or `-D') may be specified, though the
+ session name (*note Session Name::.) may be needed to distinguish
+ between multiple detached `screen' sessions. The second form is
+ used to connect to another user's screen session which runs in
+ multiuser mode. This indicates that screen should look for
+ sessions in another user's directory. This requires setuid-root.
`-R'
Resume the first appropriate detached `screen' session. If
successful, all other command-line options are ignored. If no
detached session exists, start a new session using the specified
options, just as if `-R' had not been specified. This option is
- set by default if screen is run as a login-shell.
+ set by default if screen is run as a login-shell. For combinations
+ with the `-D'/`-d' option see there.
`-s PROGRAM'
Set the default shell to be PROGRAM. By default, `screen' uses
@@ -289,9 +345,12 @@ Invoking `Screen'
`-v'
Print the version number.
-`-wipe'
+`-wipe [MATCH]'
List available screens like `screen -ls', but remove destroyed
- sessions instead of marking them as `dead'.
+ sessions instead of marking them as `dead'. An unreachable
+ session is considered dead, when its name matches either the name
+ of the local host, or the explicitly given parameter, if any. See
+ the `-r' flag for a description how to construct matches.
`-x'
Attach to a session which is already attached elsewhere
@@ -408,13 +467,20 @@ Thus, both `C-a c' and `C-a C-c' can be used to create a window.
(select)
Prompt for a window identifier and switch. *Note Selecting::.
-`C-a 0...9'
- (select 0...select 9)
- Switch to window number 0...9. *Note Selecting::.
+`C-a 0...9, -'
+ (select 0...select 9, select -)
+ Switch to window number 0...9, or the blank window. *Note
+ Selecting::.
+
+`C-a Tab'
+ (focus)
+ Switch the input focus to the next region. *Note Regions::.
`C-a C-a'
(other)
- Toggle to the window displayed previously. *Note Selecting::.
+ Toggle to the window displayed previously. If this window does no
+ longer exist, `other' has the same effect as `next'. *Note
+ Selecting::.
`C-a a'
(meta)
@@ -427,7 +493,8 @@ Thus, both `C-a c' and `C-a C-c' can be used to create a window.
Naming Windows::.
`C-a b'
- itemx `C-a C-b' (break)
+`C-a C-b'
+ (break)
Send a break to the tty. *Note Break::.
`C-a B'
@@ -458,6 +525,10 @@ Thus, both `C-a c' and `C-a C-c' can be used to create a window.
(flow)
Cycle flow among `on', `off' or `auto'. *Note Flow::.
+`C-a F'
+ (fit)
+ Resize the window to the current region size. *Note Window Size::.
+
`C-a C-g'
(vbell)
Toggle visual bell mode. *Note Bell::.
@@ -524,6 +595,10 @@ Thus, both `C-a c' and `C-a C-c' can be used to create a window.
(xon)
Send a ^Q (ASCII XON) to the current window. *Note XON/XOFF::.
+`C-a Q'
+ (only)
+ Delete all regions but the current one. *Note Regions::.
+
`C-a r'
`C-a C-r'
(wrap)
@@ -535,6 +610,10 @@ Thus, both `C-a c' and `C-a C-c' can be used to create a window.
(xoff)
Send a ^S (ASCII XOFF) to the current window. *Note XON/XOFF::.
+`C-a S'
+ (split)
+ Split the current region into two new ones. *Note Regions::.
+
`C-a t'
`C-a C-t'
(time)
@@ -562,6 +641,10 @@ Thus, both `C-a c' and `C-a C-c' can be used to create a window.
(lockscreen)
Lock your terminal. *Note Lock::.
+`C-a X'
+ (remove)
+ Kill the current region. *Note Regions::.
+
`C-a z'
`C-a C-z'
(suspend)
@@ -601,6 +684,7 @@ Thus, both `C-a c' and `C-a C-c' can be used to create a window.
current window. *Note Paste::.
`C-a {'
+`C-a }'
(history)
Copy and paste a previous (command) line. *Note History::.
@@ -627,6 +711,10 @@ Thus, both `C-a c' and `C-a C-c' can be used to create a window.
(license)
Show the copyright page.
+`C-a *'
+ (displays)
+ Show the listing of attached displays.
+

File: screen.info, Node: Command Summary, Prev: Default Key Bindings, Up: Commands
@@ -642,9 +730,19 @@ Command Summary
`acldel USERNAME'
Disallow other user in this session. *Note Multiuser Session::.
+`aclgrp USRNAME [GROUPNAME]'
+ Inherit permissions granted to a group leader. *Note Multiuser
+ Session::.
+
+`aclumask [USERS]+\-BITS ...'
+ Predefine access to new windows. *Note Umask::.
+
`activity MESSAGE'
Set the activity notification message. *Note Monitor::.
+`addacl USERNAMES'
+ Synonym to `acladd'. *Note Multiuser Session::.
+
`allpartial STATE'
Set all windows to partial refresh. *Note Redisplay::.
@@ -658,7 +756,7 @@ Command Summary
Enable a clear screen to discard unwritten output. *Note
Autonuke::.
-`bell_msg MESSAGE'
+`bell_msg [MESSAGE]'
Set the bell notification message. *Note Bell::.
`bind KEY [COMMAND [ARGS]]'
@@ -670,12 +768,21 @@ Command Summary
`break [DURATION]'
Send a break signal to the current window. *Note Break::.
+`breaktype [TCSENDBREAK | TCSBRK | TIOCSBRK]'
+ Specify how to generate breaks. *Note Break::.
+
`bufferfile [EXCHANGE-FILE]'
Select a file for screen-exchange. *Note Screen-Exchange::.
`c1 [STATE]'
Change c1 code processing. *Note Character Processing::.
+`caption MODE [STRING]'
+ Change caption mode and string. *Note Regions::.
+
+`chacl USERNAMES PERMBITS LIST'
+ Synonym to `aclchg'. *Note Multiuser Session::.
+
`charset SET'
Change character set slot designation. *Note Character
Processing::.
@@ -692,6 +799,9 @@ Command Summary
`command'
Simulate the screen escape key. *Note Command Character::.
+`compacthist [STATE]'
+ Selects compaction of trailing empty lines. *Note Scrollback::.
+
`console [STATE]'
Grab or ungrab console output. *Note Console::.
@@ -710,6 +820,9 @@ Command Summary
`defautonuke STATE'
Select default autonuke behavior. *Note Autonuke::.
+`defbreaktype [TCSENDBREAK | TCSBRK | TIOCSBRK]'
+ Specify the default for generating breaks. *Note Break::.
+
`defc1 STATE'
Select default c1 processing behavior. *Note Character
Processing::.
@@ -751,11 +864,21 @@ Command Summary
`defscrollback NUM'
Set default lines of scrollback. *Note Scrollback::.
+`defshell COMMAND'
+ Set the default program for new windows. *Note Shell::.
+
+`defsilence STATE'
+ Select default idle monitoring behavior. *Note Silence::.
+
+`defslowpaste MSEC'
+ Select the default inter-character timeout when pasting. *Note
+ Paste::.
+
`defwrap STATE'
Set default line-wrapping behavior. *Note Wrap::.
`defwritelock ON|OFF|AUTO'
- Set default writelock behavior. *Note Multiuser::.
+ Set default writelock behavior. *Note Multiuser Session::.
`defzombie [KEYS]'
Keep dead windows. *Note Zombie::.
@@ -766,6 +889,9 @@ Command Summary
`digraph'
Enter digraph sequence. *Note Digraph::.
+`displays'
+ List currently active user interfaces. *Note Displays::.
+
`dumptermcap'
Write the window's termcap entry to a file. *Note Dump Termcap::.
@@ -778,9 +904,15 @@ Command Summary
`exec [[FDPAT] COMMAND [ARGS ...]]'
Run a subprocess (filter). *Note Exec::.
+`fit'
+ Change window size to current display size. *Note Window Size::.
+
`flow [FSTATE]'
Set flow control behavior. *Note Flow::.
+`focus'
+ Move focus to next region. *Note Regions::.
+
`gr [STATE]'
Change GR charset processing. *Note Character Processing::.
@@ -805,6 +937,9 @@ Command Summary
`history'
Find previous command beginning .... *Note History::.
+`hstatus STATUS'
+ Change the window's hardstatus line. *Note Hardstatus::.
+
`info'
Display terminal settings. *Note Info::.
@@ -835,6 +970,9 @@ Command Summary
`login [STATE]'
Log the window in `/etc/utmp'. *Note Login::.
+`logtstamp [STATE]'
+ Configure logfile time-stamps. *Note Log::.
+
`mapdefault'
Use only the default mapping table for the next keystroke. *Note
Bindkey Control::.
@@ -844,7 +982,7 @@ Command Summary
Control::.
`maptimeout TIMO'
- Set the intercharacter timeout used for keymapping. *Note Bindkey
+ Set the inter-character timeout used for keymapping. *Note Bindkey
Control::.
`markkeys STRING'
@@ -871,12 +1009,18 @@ Command Summary
`next'
Switch to the next window. *Note Selecting::.
+`nonblock STATE'
+ Disable flow control to the current display. *Note Nonblock::.
+
`number [N]'
Change/display the current window's number. *Note Number::.
`obuflimit [LIMIT]'
Select output buffer limit. *Note Obuflimit::.
+`only'
+ Kill all other regions. *Note Regions::.
+
`other'
Switch to the window you were in last. *Note Selecting::.
@@ -927,6 +1071,9 @@ Command Summary
`register KEY STRING'
Store a string to a register. *Note Registers::.
+`remove'
+ Kill current region. *Note Regions::.
+
`removebuf'
Delete the screen-exchange file. *Note Screen-Exchange::.
@@ -969,12 +1116,18 @@ Command Summary
`sorendition [ATTR [COLOR]]'
Change text highlighting. *Note Sorendition::.
+`split'
+ Split region into two parts. *Note Regions::.
+
`startup_message STATE'
Display copyright notice on startup. *Note Startup::.
`stuff STRING'
Stuff a string in the input buffer of a window. *Note Paste::.
+`su [USERNAME [PASSWORD [PASSWORD2]]]'
+ Identify a user. *Note Multiuser Session::.
+
`suspend'
Put session in background. *Note Suspend::.
@@ -997,6 +1150,9 @@ Command Summary
`title [WINDOWTITLE]'
Set the name of the current window. *Note Title Command::.
+`umask [USERS]+\-BITS ...'
+ Synonym to `aclumask'. *Note Umask::.
+
`unsetenv VAR'
Unset environment variable for new windows. *Note Setenv::.
@@ -1059,6 +1215,7 @@ with a higher MAXWIN setting.
* Setenv:: Set environment variables for new windows.
* Shell:: Parameters for shell windows.
* Term:: Set the terminal type for new windows.
+* Window Types:: Creating different types of windows.

File: screen.info, Node: Chdir, Next: Screen Command, Up: New Window
@@ -1091,32 +1248,33 @@ Screen Command
(`C-a c', `C-a C-c')
Establish a new window. The flow-control options (`-f', `-fn' and
`-fa'), title option (`-t'), login options (`-l' and `-ln') ,
- terminal type option (`-T TERM') and scrollback option (`-h NUM')
- may be specified for each command. If an optional number N in the
- range 0...9 is given, the window number N is assigned to the newly
- created window (or, if this number is already in-use, the next
- available number). If a command is specified after `screen', this
- command (with the given arguments) is started in the window;
- otherwise, a shell is created.
-
- If a tty (character special device) name (e.g. `/dev/ttyS0') is
- specified as cmd, then the window is directly connected to this
- device. This is similar to the cmd `kermit -l /dev/ttyS0 -c' but
- saves resources and is more efficient.
+ terminal type option (`-T TERM'), the all-capability-flag (`-a')
+ and scrollback option (`-h NUM') may be specified with each
+ command. The option (`-M') turns monitoring on for this window.
+ The option (`-L') turns output logging on for this window. If an
+ optional number N in the range 0...9 is given, the window number N
+ is assigned to the newly created window (or, if this number is
+ already in-use, the next available number). If a command is
+ specified after `screen', this command (with the given arguments)
+ is started in the window; otherwise, a shell is created.
+
+ Screen has built in some functionality of `cu' and `telnet'.
+ *Note Window Types::.
Thus, if your `.screenrc' contains the lines
# example for .screenrc:
screen 1
- screen -fn -t foobar 2 telnet foobar
+ screen -fn -t foobar 2 -L telnet foobar
`screen' creates a shell window (in window #1) and a window with a
TELNET connection to the machine foobar (with no flow-control using the
-title `foobar' in window #2). If you do not include any `screen'
-commands in your `.screenrc' file, then `screen' defaults to creating a
-single shell window, number zero. When the initialization is
-completed, `screen' switches to the last window specified in your
-.screenrc file or, if none, it opens default window #0.
+title `foobar' in window #2) and will write a logfile `screenlog.2' of
+the telnet session. If you do not include any `screen' commands in
+your `.screenrc' file, then `screen' defaults to creating a single
+shell window, number zero. When the initialization is completed,
+`screen' switches to the last window specified in your .screenrc file
+or, if none, it opens default window #0.

File: screen.info, Node: Setenv, Next: Shell, Prev: Screen Command, Up: New Window
@@ -1143,6 +1301,7 @@ Shell
=====
- Command: shell COMMAND
+ - Command: defshell COMMAND
(none)
Set the command to be used to create a new shell. This overrides
the value of the environment variable `$SHELL'. This is useful if
@@ -1150,6 +1309,8 @@ Shell
program specified in `$SHELL'. If the command begins with a `-'
character, the shell will be started as a login-shell.
+ `defshell' is currently a synonym to the `shell' command.
+
- Command: shelltitle TITLE
(none)
Set the title for all shells created during startup or by the C-a
@@ -1157,7 +1318,7 @@ Shell
titles are.

-File: screen.info, Node: Term, Prev: Shell, Up: New Window
+File: screen.info, Node: Term, Next: Window Types, Prev: Shell, Up: New Window
Term
====
@@ -1176,6 +1337,108 @@ Term
and resetting the default.

+File: screen.info, Node: Window Types, Prev: Term, Up: New Window
+
+Window Types
+============
+
+ Screen provides three different window types. New windows are created
+with `screen''s `screen' command (*note Screen Command::.). The first
+parameter to the `screen' command defines which type of window is
+created. The different window types are all special cases of the normal
+type. They have been added in order to allow `screen' to be used
+efficiently as a console with 100 or more windows.
+ * The normal window contains a shell (default, if no parameter is
+ given) or any other system command that could be executed from a
+ shell. (e.g. `slogin', etc...).
+
+ * If a tty (character special device) name (e.g. `/dev/ttya') is
+ specified as the first parameter, then the window is directly
+ connected to this device. This window type is similar to `screen
+ cu -l /dev/ttya'. Read and write access is required on the device
+ node, an exclusive open is attempted on the node to mark the
+ connection line as busy. An optional parameter is allowed
+ consisting of a comma separated list of flags in the notation used
+ by `stty(1)':
+ `<baud_rate>'
+ Usually 300, 1200, 9600 or 19200. This affects transmission
+ as well as receive speed.
+
+ `cs8 or cs7'
+ Specify the transmission of eight (or seven) bits per byte.
+
+ `ixon or -ixon'
+ Enables (or disables) software flow-control (CTRL-S/CTRL-Q)
+ for sending data.
+
+ `ixoff or -ixoff'
+ Enables (or disables) software flow-control for receiving
+ data.
+
+ `istrip or -istrip'
+ Clear (or keep) the eight bit in each received byte.
+
+ You may want to specify as many of these options as applicable.
+ Unspecified options cause the terminal driver to make up the
+ parameter values of the connection. These values are system
+ dependant and may be in defaults or values saved from a previous
+ connection.
+
+ For tty windows, the `info' command shows some of the modem
+ control lines in the status line. These may include `RTS', `CTS',
+ `DTR', `CD' and more. This depends rather on on the available
+ `ioctl()''s and system header files than on the physical
+ capabilities of the serial board. The name of a logical low
+ (inactive) signal is preceded by an exclamation mark (`!'),
+ otherwise the signal is logical high (active). Unsupported but
+ shown signals are usually shown low. When the `CLOCAL' status bit
+ is true, the whole set of modem signals is placed inside curly
+ braces (`{' and `}'). When the `CRTSCTS' or `TIOCSOFTCAR' bit is
+ true, the signals `CTS' or `CD' are shown in parenthesis,
+ respectively.
+
+ For tty windows, the command `break' causes the Data transmission
+ line (TxD) to go low for a specified period of time. This is
+ expected to be interpreted as break signal on the other side. No
+ data is sent and no modem control line is changed when a `break'
+ is issued.
+
+ * If the first parameter is `//telnet', the second parameter is
+ expected to be a host name, and an optional third parameter may
+ specify a TCP port number (default decimal 23). Screen will
+ connect to a server listening on the remote host and use the
+ telnet protocol to communicate with that server.
+
+ For telnet windows, the command `info' shows details about the
+ connection in square brackets (`[' and `]') at the end of the
+ status line.
+ `b'
+ BINARY. The connection is in binary mode.
+
+ `e'
+ ECHO. Local echo is disabled.
+
+ `c'
+ SGA. The connection is in `character mode' (default: `line
+ mode').
+
+ `t'
+ TTYPE. The terminal type has been requested by the remote
+ host. Screen sends the name `screen' unless instructed
+ otherwise (see also the command `term').
+
+ `w'
+ NAWS. The remote site is notified about window size changes.
+
+ `f'
+ LFLOW. The remote host will send flow control information.
+ (Ignored at the moment.) Additional flags for debugging are
+ `x', `t' and `n' (XDISPLOC, TSPEED and NEWENV).
+
+ For telnet windows, the command `break' sends the telnet code `IAC
+ BREAK' (decimal 243) to the remote host.
+
+
File: screen.info, Node: Selecting, Next: Session Management, Prev: New Window, Up: Top
Selecting a Window
@@ -1189,7 +1452,7 @@ created in that order by default (*note New Window::.).
* Next and Previous:: Forward or back one window.
* Other Window:: Switch back and forth between two windows.
-* Select:: Specify a particular window.
+* Select:: Switch to a window (and to one after `kill').

File: screen.info, Node: Next and Previous, Next: Other Window, Up: Selecting
@@ -1235,10 +1498,11 @@ Select
established, the lowest available number is assigned to this
window. Thus, the first window can be activated by `select 0';
there can be no more than 10 windows present simultaneously
- (unless screen is compiled with a higher MAXWIN setting).
+ (unless screen is compiled with a higher MAXWIN setting). The
+ special command `select -' switches to a blank window.

-File: screen.info, Node: Session Management, Next: Window Settings, Prev: Selecting, Up: Top
+File: screen.info, Node: Session Management, Next: Regions, Prev: Selecting, Up: Top
Session Management Commands
***************************
@@ -1258,257 +1522,3 @@ unexpected loss of carrier.
* Suspend:: Suspend your session.
* Quit:: Terminate your session.
-
-File: screen.info, Node: Detach, Next: Power Detach, Up: Session Management
-
-Detach
-======
-
- - Command: autodetach STATE
- (none)
- Sets whether `screen' will automatically detach upon hangup, which
- saves all your running programs until they are resumed with a
- `screen -r' command. When turned off, a hangup signal will
- terminate `screen' and all the processes it contains. Autodetach is
- on by default.
-
- - Command: detach
- (`C-a d', `C-a C-d')
- Detach the `screen' session (disconnect it from the terminal and
- put it into the background). A detached `screen' can be resumed by
- invoking `screen' with the `-r' option. (*note Invoking Screen::.)
-
- - Command: password [CRYPTED_PW]
- (none)
- Present a crypted password in your `.screenrc' file and screen will
- ask for it, whenever someone attempts to resume a detached
- session. This is useful, if you have privileged programs running
- under `screen' and you want to protect your session from reattach
- attempts by users that managed to assume your uid. (I.e. any
- superuser.) If no crypted password is specified, screen prompts
- twice a password and places its encryption in the paste buffer.
- Default is `none', which disables password checking.
-
-
-File: screen.info, Node: Power Detach, Next: Lock, Prev: Detach, Up: Session Management
-
-Power Detach
-============
-
- - Command: pow_detach
- (`C-a D')
- Mainly the same as `detach', but also sends a HANGUP signal to the
- parent process of `screen'.
- *Caution*: This will result in a logout if `screen' was started
- from your login shell.
-
- - Command: pow_detach_msg [MESSAGE]
- (none)
- The MESSAGE specified here is output whenever a power detach is
- performed. It may be used as a replacement for a logout message or
- to reset baud rate, etc. Without parameter, the current message
- is shown.
-
-
-File: screen.info, Node: Lock, Next: Multiuser Session, Prev: Power Detach, Up: Session Management
-
-Lock
-====
-
- - Command: lockscreen
- (`C-a x', `C-a C-x')
- Call a screenlock program (`/local/bin/lck' or `/usr/bin/lock' or
- a builtin, if no other is available). Screen does not accept any
- command keys until this program terminates. Meanwhile processes in
- the windows may continue, as the windows are in the detached state.
- The screenlock program may be changed through the environment
- variable `$LOCKPRG' (which must be set in the shell from which
- `screen' is started) and is executed with the user's uid and gid.
-
- Warning: When you leave other shells unlocked and have no password
- set on `screen', the lock is void: One could easily re-attach from
- an unlocked shell. This feature should rather be called
- `lockterminal'.
-
-
-File: screen.info, Node: Multiuser Session, Next: Session Name, Prev: Lock, Up: Session Management
-
-Multiuser Session
-=================
-
- These commands allow other users to gain access to one single
-`screen' session. When attaching to a multiuser `screen' the
-sessionname is specified as `username/sessionname' to the `-S' command
-line option. `Screen' must be compiled with multiuser support to
-enable features described here.
-
-* Menu:
-
-* Multiuser:: Enable / Disable multiuser mode.
-* Acladd:: Enable a specific user.
-* Aclchg:: Change a users permissions.
-* Acldel:: Disable a specific user.
-* Wall:: Write a message to all users.
-* Writelock:: Grant exclusive window access.
-
-
-File: screen.info, Node: Multiuser, Next: Acladd, Up: Multiuser Session
-
-Multiuser
----------
-
- - Command: multiuser STATE
- (none)
- Switch between single-user and multi-user mode. Standard screen
- operation is single-user. In multi-user mode the commands
- `acladd', `aclchg' and `acldel' can be used to enable (and
- disable) other users accessing this `screen'.
-
-
-File: screen.info, Node: Acladd, Next: Aclchg, Prev: Multiuser, Up: Multiuser Session
-
-Acladd
-------
-
- - Command: acladd USERNAMES
- (none)
- Enable users to fully access this screen session. USERNAMES can be
- one user or a comma seperated list of users. This command enables
- to attach to the `screen' session and performs the equivalent of
- `aclchg USERNAMES +rwx "#?"'. To add a user with restricted access,
- use the `aclchg' command below. Multi-user mode only.
-
-
-File: screen.info, Node: Aclchg, Next: Acldel, Prev: Acladd, Up: Multiuser Session
-
-Aclchg
-------
-
- - Command: aclchg USERNAMES PERMBITS LIST
- (none)
- Change permissions for a comma seperated list of users.
- Permission bits are represented as `r', `w' and `x'. Prefixing
- `+' grants the permission, `-' removes it. The third parameter is
- a comma seperated list of commands or windows (specified either by
- number or title). The special list `#' refers to all windows, `?'
- to all commands. If USERNAMES consists of a single `*', all known
- users is affected. A command can be executed when the user has
- the `x' bit for it. The user can type input to a window when he
- has its `w' bit set and no other user obtains a writelock for this
- window. Other bits are currently ignored. To withdraw the
- writelock from another user in e.g. window 2: `aclchg USERNAME
- -w+w 2'. To allow readonly access to the session: `aclchg USERNAME
- -w "#"'. As soon as a user's name is known to screen, he can
- attach to the session and (per default) has full permissions for
- all command and windows. Execution permission for the acl
- commands, `at' and others should also be removed or the user may
- be able to regain write permission. Multi-user mode only.
-
-
-File: screen.info, Node: Acldel, Next: Wall, Prev: Aclchg, Up: Multiuser Session
-
-Acldel
-------
-
- - Command: acldel USERNAME
- (none)
- Remove a user from screen's access control list. If currently
- attached, all the user's displays are detached from the session.
- He cannot attach again. Multi-user mode only.
-
-
-File: screen.info, Node: Wall, Next: Writelock, Prev: Acldel, Up: Multiuser Session
-
-Wall
-----
-
- - Command: wall MESSAGE
- (none)
- Write a message to all displays. The message will appear in the
- terminal's status line.
-
-
-File: screen.info, Node: Writelock, Prev: Wall, Up: Multiuser Session
-
-Writelock
----------
-
- - Command: writelock ON|OFF|AUTO
- (none)
- In addition to access control lists, not all users may be able to
- write to the same window at once. Per default, writelock is in
- `auto' mode and grants exclusive input permission to the user who
- is the first to switch to the particular window. When he leaves
- the window, other users may obtain the writelock (automatically).
- The writelock of the current window is disabled by the command
- `writelock off'. If the user issues the command `writelock on' he
- keeps the exclusive write permission while switching to other
- windows.
-
- - Command: defwritelock ON|OFF|AUTO
- (none)
- Sets the default writelock behaviour for new windows. Initially
- all windows will be created with automatic writelocks.
-
-
-File: screen.info, Node: Session Name, Next: Suspend, Prev: Multiuser Session, Up: Session Management
-
-Session Name
-============
-
- - Command: sessionname [NAME]
- (none)
- Rename the current session. Note that for `screen -list' the name
- shows up with the process-id prepended. If the argument NAME is
- omitted, the name of this session is displayed.
- *Caution*: The `$STY' environment variable still reflects the old
- name. This may result in confusion. The default is constructed
- from the tty and host names.
-
-
-File: screen.info, Node: Suspend, Next: Quit, Prev: Session Name, Up: Session Management
-
-Suspend
-=======
-
- - Command: suspend
- (`C-a z', `C-a C-z')
- Suspend `screen'. The windows are in the detached state while
- `screen' is suspended. This feature relies on the parent shell
- being able to do job control.
-
-
-File: screen.info, Node: Quit, Prev: Suspend, Up: Session Management
-
-Quit
-====
-
- - Command: quit
- (`C-a C-\')
- Kill all windows and terminate `screen'. Note that on VT100-style
- terminals the keys `C-4' and `C-\' are identical. So be careful
- not to type `C-a C-4' when selecting window no. 4. Use the empty
- bind command (as in `bind "^\"') to remove a key binding (*note
- Key Binding::.).
-
-
-File: screen.info, Node: Window Settings, Next: Virtual Terminal, Prev: Session Management, Up: Top
-
-Window Settings
-***************
-
- These commands control the way `screen' treats individual windows in
-a session. *Note Virtual Terminal::, for commands to control the
-terminal emulation itself.
-
-* Menu:
-
-* Naming Windows:: Control the name of the window
-* Console:: See the host's console messages
-* Kill:: Destroy an unwanted window
-* Login:: Control `/etc/utmp' logging
-* Mode:: Control the file mode of the pty
-* Monitor:: Watch for activity in a window
-* Windows:: List the active windows
-* Hardstatus:: Set a window's hardstatus line
-
diff --git a/doc/screen.info-2 b/doc/screen.info-2
index dfeec60..2995343 100644
--- a/doc/screen.info-2
+++ b/doc/screen.info-2
@@ -3,7 +3,7 @@ file ./screen.texinfo.
This file documents the `Screen' virtual terminal manager.
- Copyright (c) 1993 Free Software Foundation, Inc.
+ Copyright (c) 1993-1995 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
@@ -20,6 +20,420 @@ versions, except that this permission notice may be stated in a
translation approved by the Foundation.

+File: screen.info, Node: Detach, Next: Power Detach, Up: Session Management
+
+Detach
+======
+
+ - Command: autodetach STATE
+ (none)
+ Sets whether `screen' will automatically detach upon hangup, which
+ saves all your running programs until they are resumed with a
+ `screen -r' command. When turned off, a hangup signal will
+ terminate `screen' and all the processes it contains. Autodetach is
+ on by default.
+
+ - Command: detach
+ (`C-a d', `C-a C-d')
+ Detach the `screen' session (disconnect it from the terminal and
+ put it into the background). A detached `screen' can be resumed by
+ invoking `screen' with the `-r' option. (*note Invoking Screen::.)
+
+ - Command: password [CRYPTED_PW]
+ (none)
+ Present a crypted password in your `.screenrc' file and screen will
+ ask for it, whenever someone attempts to resume a detached
+ session. This is useful, if you have privileged programs running
+ under `screen' and you want to protect your session from reattach
+ attempts by users that managed to assume your uid. (I.e. any
+ superuser.) If no crypted password is specified, screen prompts
+ twice a password and places its encryption in the paste buffer.
+ Default is `none', which disables password checking.
+
+
+File: screen.info, Node: Power Detach, Next: Lock, Prev: Detach, Up: Session Management
+
+Power Detach
+============
+
+ - Command: pow_detach
+ (`C-a D')
+ Mainly the same as `detach', but also sends a HANGUP signal to the
+ parent process of `screen'.
+ *Caution*: This will result in a logout if `screen' was started
+ from your login shell.
+
+ - Command: pow_detach_msg [MESSAGE]
+ (none)
+ The MESSAGE specified here is output whenever a power detach is
+ performed. It may be used as a replacement for a logout message or
+ to reset baud rate, etc. Without parameter, the current message
+ is shown.
+
+
+File: screen.info, Node: Lock, Next: Multiuser Session, Prev: Power Detach, Up: Session Management
+
+Lock
+====
+
+ - Command: lockscreen
+ (`C-a x', `C-a C-x')
+ Call a screenlock program (`/local/bin/lck' or `/usr/bin/lock' or
+ a builtin, if no other is available). Screen does not accept any
+ command keys until this program terminates. Meanwhile processes in
+ the windows may continue, as the windows are in the detached state.
+ The screenlock program may be changed through the environment
+ variable `$LOCKPRG' (which must be set in the shell from which
+ `screen' is started) and is executed with the user's uid and gid.
+
+ Warning: When you leave other shells unlocked and have no password
+ set on `screen', the lock is void: One could easily re-attach from
+ an unlocked shell. This feature should rather be called
+ `lockterminal'.
+
+
+File: screen.info, Node: Multiuser Session, Next: Session Name, Prev: Lock, Up: Session Management
+
+Multiuser Session
+=================
+
+ These commands allow other users to gain access to one single
+`screen' session. When attaching to a multiuser `screen' the
+sessionname is specified as `username/sessionname' to the `-S' command
+line option. `Screen' must be compiled with multiuser support to
+enable features described here.
+
+* Menu:
+
+* Multiuser:: Enable / Disable multiuser mode.
+* Acladd:: Enable a specific user.
+* Aclchg:: Change a users permissions.
+* Acldel:: Disable a specific user.
+* Aclgrp:: Grant a user permissions to other users.
+* Displays:: List all active users at their displays.
+* Umask:: Predefine access to new windows.
+* Wall:: Write a message to all users.
+* Writelock:: Grant exclusive window access.
+* Su:: Substitute user.
+
+
+File: screen.info, Node: Multiuser, Next: Acladd, Up: Multiuser Session
+
+Multiuser
+---------
+
+ - Command: multiuser STATE
+ (none)
+ Switch between single-user and multi-user mode. Standard screen
+ operation is single-user. In multi-user mode the commands
+ `acladd', `aclchg' and `acldel' can be used to enable (and
+ disable) other users accessing this `screen'.
+
+
+File: screen.info, Node: Acladd, Next: Aclchg, Prev: Multiuser, Up: Multiuser Session
+
+Acladd
+------
+
+ - Command: acladd USERNAMES
+ - Command: addacl USERNAMES
+ (none)
+ Enable users to fully access this screen session. USERNAMES can be
+ one user or a comma separated list of users. This command enables
+ to attach to the `screen' session and performs the equivalent of
+ `aclchg USERNAMES +rwx "#?"'. To add a user with restricted access,
+ use the `aclchg' command below. `Addacl' is a synonym to `acladd'.
+ Multi-user mode only.
+
+
+File: screen.info, Node: Aclchg, Next: Acldel, Prev: Acladd, Up: Multiuser Session
+
+Aclchg
+------
+
+ - Command: aclchg USERNAMES PERMBITS LIST
+ - Command: chacl USERNAMES PERMBITS LIST
+ (none)
+ Change permissions for a comma separated list of users.
+ Permission bits are represented as `r', `w' and `x'. Prefixing
+ `+' grants the permission, `-' removes it. The third parameter is
+ a comma separated list of commands or windows (specified either by
+ number or title). The special list `#' refers to all windows, `?'
+ to all commands. If USERNAMES consists of a single `*', all known
+ users is affected. A command can be executed when the user has
+ the `x' bit for it. The user can type input to a window when he
+ has its `w' bit set and no other user obtains a writelock for this
+ window. Other bits are currently ignored. To withdraw the
+ writelock from another user in e.g. window 2: `aclchg USERNAME
+ -w+w 2'. To allow read-only access to the session: `aclchg
+ USERNAME -w "#"'. As soon as a user's name is known to screen, he
+ can attach to the session and (per default) has full permissions
+ for all command and windows. Execution permission for the acl
+ commands, `at' and others should also be removed or the user may
+ be able to regain write permission. `Chacl' is a synonym to
+ `aclchg'. Multi-user mode only.
+
+
+File: screen.info, Node: Acldel, Next: Aclgrp, Prev: Aclchg, Up: Multiuser Session
+
+Acldel
+------
+
+ - Command: acldel USERNAME
+ (none)
+ Remove a user from screen's access control list. If currently
+ attached, all the user's displays are detached from the session.
+ He cannot attach again. Multi-user mode only.
+
+
+File: screen.info, Node: Aclgrp, Next: Displays, Prev: Acldel, Up: Multiuser Session
+
+Aclgrp
+------
+
+ - Command: aclgrp USERNAME [GROUPNAME]
+ (none)
+ Creates groups of users that share common access rights. The name
+ of the group is the username of the group leader. Each member of
+ the group inherits the permissions that are granted to the
+ group leader. That means, if a user fails an access check, another
+ check is made for the group leader. A user is removed from all
+ groups the special value `none' is used for GROUPNAME. If the
+ second parameter is omitted all groups the user is in are listed.
+
+
+File: screen.info, Node: Displays, Next: Umask, Prev: Aclgrp, Up: Multiuser Session
+
+Displays
+--------
+
+ - Command: displays
+ (`C-a *')
+ Shows a tabular listing of all currently connected user
+ front-ends (displays). This is most useful for multiuser
+ sessions.
+
+
+File: screen.info, Node: Umask, Next: Wall, Prev: Displays, Up: Multiuser Session
+
+aclumask
+--------
+
+ - Command: aclumask [[USERS]+BITS |[USERS]-BITS .... ]
+ - Command: umask [[USERS]+BITS |[USERS]-BITS .... ]
+ (none)
+ This specifies the access other users have to windows that will
+ be created by the caller of the command. USERS may be no, one
+ or a comma separated list of known usernames. If no users are
+ specified, a list of all currently known users is assumed. BITS
+ is any combination of access control bits allowed defined
+ with the `aclchg' command. The special username `?' predefines the
+ access that not yet known users will be granted to any
+ window initially. The special username `??' predefines the access
+ that not yet known users are granted to any command. Rights of
+ the special username nobody cannot be changed (see the `su'
+ command). `Umask' is a synonym to `aclumask'.
+
+
+File: screen.info, Node: Wall, Next: Writelock, Prev: Umask, Up: Multiuser Session
+
+Wall
+----
+
+ - Command: wall MESSAGE
+ (none)
+ Write a message to all displays. The message will appear in the
+ terminal's status line.
+
+
+File: screen.info, Node: Writelock, Next: Su, Prev: Wall, Up: Multiuser Session
+
+Writelock
+---------
+
+ - Command: writelock ON|OFF|AUTO
+ (none)
+ In addition to access control lists, not all users may be able to
+ write to the same window at once. Per default, writelock is in
+ `auto' mode and grants exclusive input permission to the user who
+ is the first to switch to the particular window. When he leaves
+ the window, other users may obtain the writelock (automatically).
+ The writelock of the current window is disabled by the command
+ `writelock off'. If the user issues the command `writelock on' he
+ keeps the exclusive write permission while switching to other
+ windows.
+
+ - Command: defwritelock ON|OFF|AUTO
+ (none)
+ Sets the default writelock behavior for new windows. Initially all
+ windows will be created with no writelocks.
+
+
+File: screen.info, Node: Su, Prev: Writelock, Up: Multiuser Session
+
+Su
+--
+
+ - Command: su [USERNAME [PASSWORD [PASSWORD2]]]
+ (none)
+ Substitute the user of a display. The command prompts for all
+ parameters that are omitted. If passwords are specified as
+ parameters, they have to be specified un-crypted. The first
+ password is matched against the systems passwd database, the
+ second password is matched against the `screen' password as
+ set with the commands `acladd' or `password'. `Su' may be useful
+ for the `screen' administrator to test multiuser setups. When
+ the identification fails, the user has access to the commands
+ available for user `nobody'. These are `detach', `license',
+ `version', `help' and `displays'.
+
+
+File: screen.info, Node: Session Name, Next: Suspend, Prev: Multiuser Session, Up: Session Management
+
+Session Name
+============
+
+ - Command: sessionname [NAME]
+ (none)
+ Rename the current session. Note that for `screen -list' the name
+ shows up with the process-id prepended. If the argument NAME is
+ omitted, the name of this session is displayed.
+ *Caution*: The `$STY' environment variable still reflects the old
+ name. This may result in confusion. The default is constructed
+ from the tty and host names.
+
+
+File: screen.info, Node: Suspend, Next: Quit, Prev: Session Name, Up: Session Management
+
+Suspend
+=======
+
+ - Command: suspend
+ (`C-a z', `C-a C-z')
+ Suspend `screen'. The windows are in the detached state while
+ `screen' is suspended. This feature relies on the parent shell
+ being able to do job control.
+
+
+File: screen.info, Node: Quit, Prev: Suspend, Up: Session Management
+
+Quit
+====
+
+ - Command: quit
+ (`C-a C-\')
+ Kill all windows and terminate `screen'. Note that on VT100-style
+ terminals the keys `C-4' and `C-\' are identical. So be careful
+ not to type `C-a C-4' when selecting window no. 4. Use the empty
+ bind command (as in `bind "^\"') to remove a key binding (*note
+ Key Binding::.).
+
+
+File: screen.info, Node: Regions, Next: Window Settings, Prev: Session Management, Up: Top
+
+Regions
+*******
+
+ Screen has the ability to display more than one window on the user's
+display. This is done by splitting the screen in regions, which can
+contain different windows.
+
+* Menu:
+
+* Split:: Split a region into two
+* Focus:: Change to the next region
+* Only:: Delete all other regions
+* Remove:: Delete the current region
+* Caption:: Control the window's caption
+
+
+File: screen.info, Node: Split, Next: Focus, Up: Regions
+
+Split
+=====
+
+ - Command: split
+ (`C-a S')
+ Split the current region into two new ones. All regions on the
+ display are resized to make room for the new region. The blank
+ window is displayed on the new region.
+
+
+File: screen.info, Node: Focus, Next: Only, Prev: Split, Up: Regions
+
+Focus
+=====
+
+ - Command: focus
+ (`C-a Tab')
+ Move the input focus to the next region. This is done in a cyclic
+ way so that the top region is selected after the bottom one.
+
+
+File: screen.info, Node: Only, Next: Remove, Prev: Focus, Up: Regions
+
+Only
+====
+
+ - Command: only
+ (`C-a Q')
+ Kill all regions but the current one.
+
+
+File: screen.info, Node: Remove, Next: Caption, Prev: Only, Up: Regions
+
+Remove
+======
+
+ - Command: remove
+ (`C-a X')
+ Kill the current region. This is a no-op if there is only one
+ region.
+
+
+File: screen.info, Node: Caption, Prev: Remove, Up: Regions
+
+Caption
+=======
+
+ - Command: caption `always'|`splitonly' [STRING]
+ - Command: caption `string' [STRING]
+ (none)
+ This command controls the display of the window captions. Normally
+ a caption is only used if more than one window is shown on the
+ display (split screen mode). But if the type is set to `always',
+ `screen' shows a caption even if only one window is displayed. The
+ default is `splitonly'.
+
+ The second form changes the text used for the caption. You can use
+ all string escapes (*Note String Escapes::). `Screen' uses a
+ default of `%3n %t'.
+
+ You can mix both forms by providing the string as an additional
+ argument.
+
+
+File: screen.info, Node: Window Settings, Next: Virtual Terminal, Prev: Regions, Up: Top
+
+Window Settings
+***************
+
+ These commands control the way `screen' treats individual windows in
+a session. *Note Virtual Terminal::, for commands to control the
+terminal emulation itself.
+
+* Menu:
+
+* Naming Windows:: Control the name of the window
+* Console:: See the host's console messages
+* Kill:: Destroy an unwanted window
+* Login:: Control `/etc/utmp' logging
+* Mode:: Control the file mode of the pty
+* Monitor:: Watch for activity in a window
+* Windows:: List the active windows
+* Hardstatus:: Set a window's hardstatus line
+
+
File: screen.info, Node: Naming Windows, Next: Console, Up: Window Settings
Naming Windows (Titles)
@@ -178,9 +592,9 @@ Console
- Command: console [STATE]
(none)
- Grabs or ungrabs the machines console output to a window. When the
- argument is omitted the current state is displayed. *Note*: Only
- the owner of `/dev/console' can grab the console output. This
+ Grabs or un-grabs the machines console output to a window. When
+ the argument is omitted the current state is displayed. *Note*:
+ Only the owner of `/dev/console' can grab the console output. This
command is only available if the host supports the ioctl
`TIOCCONS'.
@@ -196,8 +610,9 @@ Kill
If there is an `exec' command running (*note Exec::.) then it is
killed. Otherwise the process (e.g. shell) running in the window
receives a `HANGUP' condition, the window structure is removed and
- screen switches to the previously displayed window. When the last
- window is destroyed, `screen' exits.
+ screen (your display) switches to another window. When the last
+ window is destroyed, `screen' exits. After a kill screen switches
+ to the previously displayed window.
*Caution*: `emacs' users may find themselves killing their `emacs'
session when trying to delete the current line. For this reason,
it is probably wise to use a different command character (*note
@@ -237,7 +652,7 @@ Mode
The mode of each newly allocated pseudo-tty is set to MODE. MODE
is an octal number as used by chmod(1). Defaults to 0622 for
windows which are logged in, 0600 for others (e.g. when `-ln' was
- specified for creation. *Note Screen Command::).
+ specified for creation. *note Screen Command::.).

File: screen.info, Node: Monitor, Next: Windows, Prev: Mode, Up: Window Settings
@@ -252,10 +667,10 @@ Monitoring
The notification message can be redefined by means of the
`activity' command. Each occurrence of `%' in MESSAGE is replaced
by the number of the window in which activity has occurred, and
- each occurrence of `~' is replaced by the definition for bell in
+ each occurrence of `^G' is replaced by the definition for bell in
your termcap (usually an audible bell). The default message is
- 'Activity in window %'
+ 'Activity in window %n'
Note that monitoring is off for all windows by default, but can be
altered by use of the `monitor' command (`C-a M').
@@ -284,17 +699,20 @@ Windows
(`C-a w', `C-a C-w')
Uses the message line to display a list of all the windows. Each
window is listed by number with the name of the program running in
- the window (or its title); the current window is marked with a `*';
- the previous window is marked with a `-'; all the windows that are
- logged in are marked with a `$' (*note Login::.); a background
- window that has received a bell is marked with a `!'; a background
- window that is being monitored and has had activity occur is
- marked with an `@' (*note Monitor::.); a window which has output
- logging turned on is marked with `(L)'; windows occupied by other
- users are marked with `&'; windows in the zombie state are marked
- with `Z'. If this list is too long to fit on the terminal's
- status line only the portion around the current window is
- displayed.
+ the window (or its title).
+
+ The current window is marked with a `*'; the previous window is
+ marked with a `-'; all the windows that are logged in are marked
+ with a `$' (*note Login::.); a background window that has received
+ a bell is marked with a `!'; a background window that is being
+ monitored and has had activity occur is marked with an `@' (*note
+ Monitor::.); a window which has output logging turned on is marked
+ with `(L)'; windows occupied by other users are marked with `&' or
+ `&&' if the window is shared by other users; windows in the zombie
+ state are marked with `Z'.
+
+ If this list is too long to fit on the terminal's status line only
+ the portion around the current window is displayed.

File: screen.info, Node: Hardstatus, Prev: Windows, Up: Window Settings
@@ -304,24 +722,27 @@ Hardstatus
`Screen' maintains a hardstatus line for every window. If a window
gets selected, the display's hardstatus will be updated to match the
-window's hardstatus line. If the display has no hardstatus the line
-will be displayed as a standard screen message. The hardstatus line
-can be changed with the ANSI Application Program Command (APC):
-`ESC_<string>ESC\'. As a convenience for xterm users the sequence
-`ESC]0..2;<string>^G' is also accepted.
+window's hardstatus line. The hardstatus line can be changed with the
+ANSI Application Program Command (APC): `ESC_<string>ESC\'. As a
+convenience for xterm users the sequence `ESC]0..2;<string>^G' is also
+accepted.
- - Command: defhstatus
+ - Command: defhstatus [STATUS]
(none)
The hardstatus line that all new windows will get is set to STATUS.
This command is useful to make the hardstatus of every window
display the window number or title or the like. STATUS may
contain the same directives as in the window messages, but the
directive escape character is `^E' (octal 005) instead of `%'.
- This was done to make a misinterpretion of program generated
+ This was done to make a misinterpretation of program generated
hardstatus lines impossible. If the parameter STATUS is omitted,
the current default string is displayed. Per default the
hardstatus line of new windows is empty.
+ - Command: hstatus STATUS
+ (none)
+ Changes the current window's hardstatus line to STATUS.
+

File: screen.info, Node: Virtual Terminal, Next: Copy and Paste, Prev: Window Settings, Up: Top
@@ -329,7 +750,7 @@ Virtual Terminal
****************
Each window in a `screen' session emulates a VT100 terminal, with
-some extra functions added. The VT100 emulator is hardcoded, no other
+some extra functions added. The VT100 emulator is hard-coded, no other
terminal types can be emulated. The commands described here modify the
terminal emulation.
@@ -395,7 +816,7 @@ functions, respectively.
ESC * Pcs (A) Designate character set as G2
ESC + Pcs (A) Designate character set as G3
ESC [ Pn ; Pn H Direct Cursor Addressing
- ESC [ Pn ; Pn f Direct Cursor Addressing
+ ESC [ Pn ; Pn f same as above
ESC [ Pn J Erase in Display
Pn = None or 0 From Cursor to End of Screen
1 From Beginning of Screen to Cursor
@@ -408,6 +829,11 @@ functions, respectively.
ESC [ Pn B Cursor Down
ESC [ Pn C Cursor Right
ESC [ Pn D Cursor Left
+ ESC [ Pn E Cursor next line
+ ESC [ Pn F Cursor previous line
+ ESC [ Pn G Cursor horizontal position
+ ESC [ Pn ` same as above
+ ESC [ Pn d Cursor vertical position
ESC [ Ps ;...; Ps m Select Graphic Rendition
Ps = None or 0 Default Rendition
1 Bold
@@ -445,6 +871,7 @@ functions, respectively.
ESC [ Pn P (A) Delete Character
ESC [ Pn S Scroll Scrolling Region Up
ESC [ Pn T Scroll Scrolling Region Down
+ ESC [ Pn ^ same as above
ESC [ Ps ;...; Ps h Set Mode
ESC [ Ps ;...; Ps l Reset Mode
Ps = 4 (A) Insert Mode
@@ -567,9 +994,9 @@ Digraph
resulting character is inserted in the input stream. For example,
if the user enters `a"', an a-umlaut will be inserted. If the
first character entered is a 0 (zero), `screen' will treat the
- following charcters (up to three) as an octal number instead. The
- optional argument PRESET is treated as user input, thus one can
- create an "umlaut" key. For example the command `bindkey ^K
+ following characters (up to three) as an octal number instead.
+ The optional argument PRESET is treated as user input, thus one
+ can create an "umlaut" key. For example the command `bindkey ^K
digraph '"'' enables the user to generate an a-umlaut by typing
`CTRL-K a'.
@@ -583,16 +1010,17 @@ Bell
(none)
When a bell character is sent to a background window, `screen'
displays a notification in the message line. The notification
- message can be re-defined by means of the `bell' command. Each
- occurrence of `%' in MESSAGE is replaced by the number of the
- window to which a bell has been sent, and each occurrence of `~'
- is replaced by the definition for bell in your termcap (usually an
- audible bell). The default message is
+ message can be re-defined by this command. Each occurrence of `%'
+ in MESSAGE is replaced by the number of the window to which a bell
+ has been sent, and each occurrence of `^G' is replaced by the
+ definition for bell in your termcap (usually an audible bell).
+ The default message is
- 'Bell in window %'
+ 'Bell in window %n'
An empty message can be supplied to the `bell_msg' command to
- suppress output of a message line (`bell_msg ""').
+ suppress output of a message line (`bell_msg ""'). Without
+ parameter, the current message is shown.
- Command: vbell [STATE]
(`C-a C-g')
@@ -640,13 +1068,34 @@ Info
Uses the message line to display some information about the current
window: the cursor position in the form `(COLUMN,ROW)' starting
with `(1,1)', the terminal width and height plus the size of the
- scrollback buffer in lines, like in `(80,24)+50', various flag
- settings (flow-control, insert mode, origin mode, wrap mode,
- application-keypad mode, output logging, activity monitoring, and
- redraw (`+' indicates enabled, `-' not)), the currently active
- character set (`G0', `G1', `G2', or `G3'), and in square brackets
- the terminal character sets that are currently designated as `G0'
- through `G3'. For system information use `time'.
+ scrollback buffer in lines, like in `(80,24)+50', the current
+ state of window XON/XOFF flow control is shown like this (see also
+ *Note Flow Control::):
+ +flow automatic flow control, currently on.
+ -flow automatic flow control, currently off.
+ +(+)flow flow control enabled. Agrees with automatic control.
+ -(+)flow flow control disabled. Disagrees with automatic control.
+ +(-)flow flow control enabled. Disagrees with automatic control.
+ -(-)flow flow control disabled. Agrees with automatic control.
+
+ The current line wrap setting (`+wrap' indicates enabled, `-wrap'
+ not) is also shown. The flags `ins', `org', `app', `log', `mon'
+ and `nored' are displayed when the window is in insert mode,
+ origin mode, application-keypad mode, has output logging, insert
+ mode, origin mode, application-keypad mode, output logging,
+ activity monitoring or partial redraw enabled.
+
+ The currently active character set (`G0', `G1', `G2', or `G3'),
+ and in square brackets the terminal character sets that are
+ currently designated as `G0' through `G3'. Additional modes
+ depending on the type of the window are displayed at the end of
+ the status line (*note Window Types::.).
+
+ If the state machine of the terminal emulator is in a non-default
+ state, the info line is started with a string identifying the
+ current state.
+
+ For system information use `time'.

File: screen.info, Node: Redisplay, Next: Wrap, Prev: Info, Up: Virtual Terminal
@@ -661,8 +1110,8 @@ Redisplay
lines. The previous setting of full/partial refresh for each
window is restored with `allpartial off'. This is a global flag
that immediately takes effect on all windows overriding the
- `partial' settings. It does not change the default redraw
- behaviour of newly created windows.
+ `partial' settings. It does not change the default redraw behavior
+ of newly created windows.
- Command: partial STATE
(none)
@@ -729,6 +1178,12 @@ Window Size
Set the display height to a specified number of lines. When no
argument is given it toggles between 24 and 42 lines display.
+ - Command: fit
+ (`C-a F')
+ Change the window size to the size of the current region. This
+ command is needed because screen doesn't adapt the window size
+ automatically if the window is displayed more than once.
+

File: screen.info, Node: Character Processing, Prev: Window Size, Up: Virtual Terminal
@@ -748,7 +1203,7 @@ Character Processing
- Command: gr [STATE]
(none)
- Turn GR charset switching on/off. Whenever screens sees an input
+ Turn GR charset switching on/off. Whenever screen sees an input
char with an 8th bit set, it will use the charset stored in the GR
slot and print the character with the 8th bit stripped. The
default (see also `defgr') is not to process GR switching because
@@ -798,458 +1253,3 @@ Character Processing
windows is changed. Shows current default if called without
argument.
-
-File: screen.info, Node: Copy and Paste, Next: Subprocess Execution, Prev: Virtual Terminal, Up: Top
-
-Copy and Paste
-**************
-
- For those confined to a hardware terminal, these commands provide a
-cut and paste facility more powerful than those provided by most
-windowing systems.
-
-* Menu:
-
-* Copy:: Copy from scrollback to buffer
-* Paste:: Paste from buffer into window
-* Registers:: Longer-term storage
-* Screen-Exchange:: Sharing data between screen users
-* History:: Recalling previous input
-
-
-File: screen.info, Node: Copy, Next: Paste, Up: Copy and Paste
-
-Copying
-=======
-
- - Command: copy
- (`C-a [', `C-a C-[', `C-a ESC')
- Enter copy/scrollback mode. This allows you to copy text from the
- current window and its history into the paste buffer. In this mode
- a `vi'-like full screen editor is active, with controls as
- outlined below.
-
-* Menu:
-
-* Line Termination:: End copied lines with CR/LF
-* Scrollback:: Set the size of the scrollback buffer
-* Copy Mode Keys:: Remap keys in copy mode
-* Movement:: Move around in the scrollback buffer
-* Marking:: Select the text you want
-* Repeat count:: Repeat a command
-* Searching:: Find the text you want
-* Specials:: Other random keys
-
-
-File: screen.info, Node: Line Termination, Next: Scrollback, Up: Copy
-
-CR/LF
------
-
- - Command: crlf [STATE]
- (none)
- This affects the copying of text regions with the `C-a [' command.
- If it is set to `on', lines will be separated by the two character
- sequence `CR'/`LF'. Otherwise only `LF' is used. `crlf' is off
- by default. When no parameter is given, the state is toggled.
-
-
-File: screen.info, Node: Scrollback, Next: Copy Mode Keys, Prev: Line Termination, Up: Copy
-
-Scrollback
-----------
-
- - Command: defscrollback NUM
- (none)
- Same as the `scrollback' command except that the default setting
- for new windows is changed. Defaults to 100.
-
- - Command: scrollback NUM
- (none)
- Set the size of the scrollback buffer for new windows to NUM
- lines. The default scrollback is 100 lines. Use `C-a i' to view
- the current setting.
-
-
-File: screen.info, Node: Copy Mode Keys, Next: Movement, Prev: Scrollback, Up: Copy
-
-markkeys
---------
-
- - Command: markkeys STRING
- (none)
- This is a method of changing the keymap used for copy/history
- mode. The string is made up of OLDCHAR=NEWCHAR pairs which are
- separated by `:'. Example: The command `markkeys h=^B:l=^F:$=^E'
- would set some keys to be more familiar to `emacs' users. If your
- terminal sends characters, that cause you to abort copy mode, then
- this command may help by binding these characters to do nothing.
- The no-op character is `' and is used like this: `markkeys @=L=H'
- if you do not want to use the `H' or `L' commands any longer. As
- shown in this example, multiple keys can be assigned to one
- function in a single statement.
-
-
-File: screen.info, Node: Movement, Next: Marking, Prev: Copy Mode Keys, Up: Copy
-
-Movement Keys
--------------
-
-`h', `j', `k', `l' move the cursor line by line or column by column.
-
-`0', `^' and `$' move to the leftmost column or to the first or last
-non-whitespace character on the line.
-
-`H', `M' and `L' move the cursor to the leftmost column of the top,
-center or bottom line of the window.
-
-`+' and `-' move the cursor to the leftmost column of the next or
-previous line.
-
-`G' moves to the specified absolute line (default: end of buffer).
-
-`|' moves to the specified absolute column.
-
-`w', `b', `e' move the cursor word by word.
-
-`C-u' and `C-d' scroll the display up/down by the specified amount of
-lines while preserving the cursor position. (Default: half screenfull).
-
-`C-b' and `C-f' move the cursor up/down a full screen.
-
-`g' moves to the beginning of the buffer.
-
-`%' jumps to the specified percentage of the buffer.
-
- Note that Emacs-style movement keys can be specified by a .screenrc
-command. (`markkeys "h=^B:l=^F:$=^E"') There is no simple method for a
-full emacs-style keymap, however, as this involves multi-character
-codes.
-
-
-File: screen.info, Node: Marking, Next: Repeat count, Prev: Movement, Up: Copy
-
-Marking
--------
-
- The copy range is specified by setting two marks. The text between
-these marks will be highlighted. Press `space' to set the first or
-second mark respectively.
-
-`Y' and `y' can be used to mark one whole line or to mark from start of
-line.
-
-`W' marks exactly one word.
-
-
-File: screen.info, Node: Repeat count, Next: Searching, Prev: Marking, Up: Copy
-
-Repeat Count
-------------
-
- Any command in copy mode can be prefixed with a number (by pressing
-digits `0...9') which is taken as a repeat count. Example: `C-a C-[ H
-10 j 5 Y' will copy lines 11 to 15 into the paste buffer.
-
-
-File: screen.info, Node: Searching, Next: Specials, Prev: Repeat count, Up: Copy
-
-Searching
----------
-
-`/' `vi'-like search forward.
-
-`?' `vi'-like search backward.
-
-`C-a s' `emacs' style incremental search forward.
-
-`C-r' `emacs' style reverse i-search.
-
-
-File: screen.info, Node: Specials, Prev: Searching, Up: Copy
-
-Specials
---------
-
- There are, however, some keys that act differently here from in
-`vi'. `Vi' does not allow to yank rectangular blocks of text, but
-`screen' does. Press
-
-`c' or `C' to set the left or right margin respectively. If no repeat
-count is given, both default to the current cursor position.
-Example: Try this on a rather full text screen: `C-a [ M 20 l SPACE c
-10 l 5 j C SPACE'.
-
-This moves one to the middle line of the screen, moves in 20 columns
-left, marks the beginning of the paste buffer, sets the left column,
-moves 5 columns down, sets the right column, and then marks the end of
-the paste buffer. Now try:
-`C-a [ M 20 l SPACE 10 l 5 j SPACE'
-
-and notice the difference in the amount of text copied.
-
-`J' joins lines. It toggles between 3 modes: lines separated by a
-newline character (012), lines glued seamless, or lines separated by a
-single space. Note that you can prepend the newline character with a
-carriage return character, by issuing a `set crlf on'.
-
-`v' is for all the `vi' users who use `:set numbers' - it toggles the
-left margin between column 9 and 1.
-
-`a' before the final space key turns on append mode. Thus the contents
-of the paste buffer will not be overwritten, but appended to.
-
-`A' turns on append mode and sets a (second) mark.
-
-`>' sets the (second) mark and writes the contents of the paste buffer
-to the screen-exchange file (`/tmp/screen-exchange' per default) once
-copy-mode is finished. *Note Screen-Exchange::.
-This example demonstrates how to dump the whole scrollback buffer to
-that file:
-`C-a [ g SPACE G $ >'.
-
-`C-g' gives information about the current line and column.
-
-`x' exchanges the first mark and the current cursor position. You can
-use this to adjust an already placed mark.
-
-`@' does nothing. Absolutely nothing. Does not even exit copy mode.
-
-All keys not described here exit copy mode.
-
-
-File: screen.info, Node: Paste, Next: Registers, Prev: Copy, Up: Copy and Paste
-
-Paste
-=====
-
- - Command: paste [REGISTERS [DESTINATION]]
- (`C-a ]', `C-a C-]')
- Write the (concatenated) contents of the specified registers to
- the stdin stream of the current window. The register `.' is
- treated as the paste buffer. If no parameter is specified the user
- is prompted to enter a single register. The paste buffer can be
- filled with the `copy', `history' and `readbuf' commands. Other
- registers can be filled with the `register', `readreg' and `paste'
- commands. If `paste' is called with a second argument, the
- contents of the specified registers is pasted into the named
- destination register rather than the window. If `.' is used as the
- second argument, the display's paste buffer is the destination.
- Note, that `paste' uses a wide variety of resources: Usually both,
- a current window and a current display are required. But whenever
- a second argument is specified no current window is needed. When
- the source specification only contains registers (not the paste
- buffer) then there need not be a current display (terminal
- attached), as the registers are a global resource. The paste
- buffer exists once for every user.
-
- - Command: pastefont [STATE]
- Tell screen to include font information in the paste buffer. The
- default is not to do so. This command is especially usefull for
- multi character fonts like kanji.
-
- - Command: slowpaste MSEC
- (none)
- Define the speed text is inserted by the `paste' command. If the
- slowpaste value is nonzero text is written character by character.
- `screen' will pause for MSEC milliseconds after each write to
- allow the application to process the input. only use `slowpaste' if
- your underlying system exposes flow control problems while pasting
- large amounts of text.
-
- - Command: readreg [REGISTER [FILENAME]]
- (none)
- Does one of two things, dependent on number of arguments: with
- zero or one arguments it it duplicates the paste buffer contents
- into the register specified or entered at the prompt. With two
- arguments it reads the contents of the named file into the
- register, just as `readbuf' reads the screen-exchange file into
- the paste buffer. The following example will paste the system's
- password file into the screen window (using register p, where a
- copy remains):
-
- C-a : readreg p /etc/passwd
- C-a : paste p
-
-
-File: screen.info, Node: Registers, Next: Screen-Exchange, Prev: Paste, Up: Copy and Paste
-
-Registers
-=========
-
- - Command: copy_reg [KEY]
- (none)
- Removed. Use `readreg' instead.
-
- - Command: ins_reg [KEY]
- (none)
- Removed. Use `paste' instead.
-
- - Command: process [KEY]
- (none)
- Stuff the contents of the specified register into the `screen'
- input queue. If no argument is given you are prompted for a
- register name. The text is parsed as if it had been typed in from
- the user's keyboard. This command can be used to bind multiple
- actions to a single key.
-
- - Command: register KEY STRING
- (none)
- Save the specified STRING to the register KEY.
-
- - Command: stuff STRING
- (none)
- Stuff the string STRING in the input buffer of the current window.
- This is like the `paste' command, but with much less overhead.
- You cannot paste large buffers with the `stuff' command. It is most
- useful for key bindings. *Note Bindkey::
-
-
-
-File: screen.info, Node: Screen-Exchange, Next: History, Prev: Registers, Up: Copy and Paste
-
-Screen-Exchange
-===============
-
- - Command: bufferfile [EXCHANGE-FILE]
- (none)
- Change the filename used for reading and writing with the paste
- buffer. If the EXCHANGE-FILE parameter is omitted, `screen'
- reverts to the default of `/tmp/screen-exchange'. The following
- example will paste the system's password file into the screen
- window (using the paste buffer, where a copy remains):
-
- C-a : bufferfile /etc/passwd
- C-a < C-a ]
- C-a : bufferfile
-
- - Command: readbuf
- (`C-a <')
- Reads the contents of the current screen-exchange file into the
- paste buffer.
-
- - Command: removebuf
- (`C-a =')
- Unlinks the screen-exchange file.
-
- - Command: writebuf
- (`C-a >')
- Writes the contents of the paste buffer to a public accessible
- screen-exchange file. This is thought of as a primitive means of
- communication between `screen' users on the same host. See also
- `C-a ESC' (*note Copy::.).
-
-
-File: screen.info, Node: History, Prev: Screen-Exchange, Up: Copy and Paste
-
-History
-=======
-
- - Command: history
- (`C-a {')
- Usually users work with a shell that allows easy access to previous
- commands. For example, `csh' has the command `!!' to repeat the
- last command executed. `screen' provides a primitive way of
- recalling "the command that started ...": You just type the first
- letter of that command, then hit `C-a {' and `screen' tries to
- find a previous line that matches with the prompt character to the
- left of the cursor. This line is pasted into this window's input
- queue. Thus you have a crude command history (made up by the
- visible window and its scrollback buffer).
-
-
-File: screen.info, Node: Subprocess Execution, Next: Key Binding, Prev: Copy and Paste, Up: Top
-
-Subprocess Execution
-********************
-
- Control Input or Output of a window by another filter process. Use
-with care!
-
-* Menu:
-
-* Exec:: The `exec' command syntax.
-* Using Exec:: Weird things that filters can do.
-
-
-File: screen.info, Node: Exec, Next: Using Exec, Up: Subprocess Execution
-
-Exec
-====
-
- - Command: exec [[FDPAT] NEWCOMMAND [ARGS ... ]]
- (none)
- Run a unix subprocess (specified by an executable path NEWCOMMAND
- and its optional arguments) in the current window. The flow of
- data between newcommand's stdin/stdout/stderr, the process already
- running (shell) and screen itself (window) is controlled by the
- filedescriptor pattern FDPAT. This pattern is basically a three
- character sequence representing stdin, stdout and stderr of
- newcommand. A dot (`.') connects the file descriptor to screen. An
- exclamation mark (`!') causes the file descriptor to be connected
- to the already running process. A colon (`:') combines both.
- User input will go to newcommand unless newcommand requests the
- old process' output (FDPATs first character is `!' or `:') or a
- pipe symbol (`|') is added to the end of FDPAT.
- Invoking `exec' without arguments shows name and arguments of the
- currently running subprocess in this window.
- When a subprocess is running the `kill' command will affect it
- instead of the window's process.
- Refer to the postscript file `doc/fdpat.ps' for a confusing
- illustration of all 21 possible combinations. Each drawing shows
- the digits 2, 1, 0 representing the three file descriptors of
- newcommand. The box marked `W' is usual pty that has the
- application-process on its slave side. The box marked `P' is the
- secondary pty that now has screen at its master side.
-
-
-File: screen.info, Node: Using Exec, Prev: Exec, Up: Subprocess Execution
-
-Using Exec
-==========
-
-Abbreviations:
-
- * Whitespace between the word `exec' and FDPAT and the command name
- can be omitted.
-
- * Trailing dots and a FDPAT consisting only of dots can be omitted.
-
- * A simple `|' is synonymous for the `!..|' pattern.
-
- * The word `exec' can be omitted when the `|' abbreviation is used.
-
- * The word `exec' can always be replaced by leading `!'.
-
-Examples:
-
-`!/bin/sh'
-`exec /bin/sh'
-`exec ... /bin/sh'
- Creates another shell in the same window, while the original shell
- is still running. Output of both shells is displayed and user
- input is sent to the new `/bin/sh'.
-
-`!!stty 19200'
-`exec!stty 19200'
-`exec !.. stty 19200'
- Set the speed of the window's tty. If your stty command operates
- on stdout, then add another `!'. This is a useful command, when a
- screen window is directly connected to a serial line that needs to
- be configured.
-
-`|less'
-`exec !..| less'
- This adds a pager to the window output. The special character `|'
- is needed to give the user control over the pager although it gets
- its input from the window's process. This works, because `less'
- listens on stderr (a behavior that `screen' would not expect
- without the `|') when its stdin is not a tty. `Less' versions
- newer than 177 fail miserably here; good old `pg' still works.
-
-`!:sed -n s/.*Error.*/\007/p'
- Sends window output to both, the user and the sed command. The sed
- inserts an additional bell character (oct. 007) to the window
- output seen by screen. This will cause 'Bell in window x'
- messages, whenever the string `Error' appears in the window.
-
diff --git a/doc/screen.info-3 b/doc/screen.info-3
index 66f750a..809a4e8 100644
--- a/doc/screen.info-3
+++ b/doc/screen.info-3
@@ -3,7 +3,7 @@ file ./screen.texinfo.
This file documents the `Screen' virtual terminal manager.
- Copyright (c) 1993 Free Software Foundation, Inc.
+ Copyright (c) 1993-1995 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
@@ -20,6 +20,475 @@ versions, except that this permission notice may be stated in a
translation approved by the Foundation.

+File: screen.info, Node: Copy and Paste, Next: Subprocess Execution, Prev: Virtual Terminal, Up: Top
+
+Copy and Paste
+**************
+
+ For those confined to a hardware terminal, these commands provide a
+cut and paste facility more powerful than those provided by most
+windowing systems.
+
+* Menu:
+
+* Copy:: Copy from scrollback to buffer
+* Paste:: Paste from buffer into window
+* Registers:: Longer-term storage
+* Screen-Exchange:: Sharing data between screen users
+* History:: Recalling previous input
+
+
+File: screen.info, Node: Copy, Next: Paste, Up: Copy and Paste
+
+Copying
+=======
+
+ - Command: copy
+ (`C-a [', `C-a C-[', `C-a ESC')
+ Enter copy/scrollback mode. This allows you to copy text from the
+ current window and its history into the paste buffer. In this mode
+ a `vi'-like full screen editor is active, with controls as
+ outlined below.
+
+* Menu:
+
+* Line Termination:: End copied lines with CR/LF
+* Scrollback:: Set the size of the scrollback buffer
+* Copy Mode Keys:: Remap keys in copy mode
+* Movement:: Move around in the scrollback buffer
+* Marking:: Select the text you want
+* Repeat count:: Repeat a command
+* Searching:: Find the text you want
+* Specials:: Other random keys
+
+
+File: screen.info, Node: Line Termination, Next: Scrollback, Up: Copy
+
+CR/LF
+-----
+
+ - Command: crlf [STATE]
+ (none)
+ This affects the copying of text regions with the `C-a [' command.
+ If it is set to `on', lines will be separated by the two character
+ sequence `CR'/`LF'. Otherwise only `LF' is used. `crlf' is off
+ by default. When no parameter is given, the state is toggled.
+
+
+File: screen.info, Node: Scrollback, Next: Copy Mode Keys, Prev: Line Termination, Up: Copy
+
+Scrollback
+----------
+
+ - Command: defscrollback NUM
+ (none)
+ Same as the `scrollback' command except that the default setting
+ for new windows is changed. Defaults to 100.
+
+ - Command: scrollback NUM
+ (none)
+ Set the size of the scrollback buffer for the current window to
+ NUM lines. The default scrollback is 100 lines. Use `C-a i' to
+ view the current setting.
+
+ - Command: compacthist [STATE]
+ (none)
+ This tells screen weather to suppress trailing blank lines when
+ scrolling up text into the history buffer. Turn compacting `on' to
+ hold more useful lines in your scrollback buffer.
+
+
+File: screen.info, Node: Copy Mode Keys, Next: Movement, Prev: Scrollback, Up: Copy
+
+markkeys
+--------
+
+ - Command: markkeys STRING
+ (none)
+ This is a method of changing the keymap used for copy/history
+ mode. The string is made up of OLDCHAR=NEWCHAR pairs which are
+ separated by `:'. Example: The command `markkeys h=^B:l=^F:$=^E'
+ would set some keys to be more familiar to `emacs' users. If your
+ terminal sends characters, that cause you to abort copy mode, then
+ this command may help by binding these characters to do nothing.
+ The no-op character is `' and is used like this: `markkeys @=L=H'
+ if you do not want to use the `H' or `L' commands any longer. As
+ shown in this example, multiple keys can be assigned to one
+ function in a single statement.
+
+
+File: screen.info, Node: Movement, Next: Marking, Prev: Copy Mode Keys, Up: Copy
+
+Movement Keys
+-------------
+
+`h', `j', `k', `l' move the cursor line by line or column by column.
+
+`0', `^' and `$' move to the leftmost column or to the first or last
+non-whitespace character on the line.
+
+`H', `M' and `L' move the cursor to the leftmost column of the top,
+center or bottom line of the window.
+
+`+' and `-' move the cursor to the leftmost column of the next or
+previous line.
+
+`G' moves to the specified absolute line (default: end of buffer).
+
+`|' moves to the specified absolute column.
+
+`w', `b', `e' move the cursor word by word.
+
+`C-u' and `C-d' scroll the display up/down by the specified amount of
+lines while preserving the cursor position. (Default: half screenfull).
+
+`C-b' and `C-f' move the cursor up/down a full screen.
+
+`g' moves to the beginning of the buffer.
+
+`%' jumps to the specified percentage of the buffer.
+
+ Note that Emacs-style movement keys can be specified by a .screenrc
+command. (`markkeys "h=^B:l=^F:$=^E"') There is no simple method for a
+full emacs-style keymap, however, as this involves multi-character
+codes.
+
+
+File: screen.info, Node: Marking, Next: Repeat count, Prev: Movement, Up: Copy
+
+Marking
+-------
+
+ The copy range is specified by setting two marks. The text between
+these marks will be highlighted. Press `space' to set the first or
+second mark respectively.
+
+`Y' and `y' can be used to mark one whole line or to mark from start of
+line.
+
+`W' marks exactly one word.
+
+
+File: screen.info, Node: Repeat count, Next: Searching, Prev: Marking, Up: Copy
+
+Repeat Count
+------------
+
+ Any command in copy mode can be prefixed with a number (by pressing
+digits `0...9') which is taken as a repeat count. Example: `C-a C-[ H
+10 j 5 Y' will copy lines 11 to 15 into the paste buffer.
+
+
+File: screen.info, Node: Searching, Next: Specials, Prev: Repeat count, Up: Copy
+
+Searching
+---------
+
+`/' `vi'-like search forward.
+
+`?' `vi'-like search backward.
+
+`C-a s' `emacs' style incremental search forward.
+
+`C-r' `emacs' style reverse i-search.
+
+
+File: screen.info, Node: Specials, Prev: Searching, Up: Copy
+
+Specials
+--------
+
+ There are, however, some keys that act differently here from in
+`vi'. `Vi' does not allow to yank rectangular blocks of text, but
+`screen' does. Press
+
+`c' or `C' to set the left or right margin respectively. If no repeat
+count is given, both default to the current cursor position.
+Example: Try this on a rather full text screen: `C-a [ M 20 l SPACE c
+10 l 5 j C SPACE'.
+
+This moves one to the middle line of the screen, moves in 20 columns
+left, marks the beginning of the paste buffer, sets the left column,
+moves 5 columns down, sets the right column, and then marks the end of
+the paste buffer. Now try:
+`C-a [ M 20 l SPACE 10 l 5 j SPACE'
+
+and notice the difference in the amount of text copied.
+
+`J' joins lines. It toggles between 4 modes: lines separated by a
+newline character (012), lines glued seamless, lines separated by a
+single space or comma separated lines. Note that you can prepend the
+newline character with a carriage return character, by issuing a `set
+crlf on'.
+
+`v' is for all the `vi' users who use `:set numbers' - it toggles the
+left margin between column 9 and 1.
+
+`a' before the final space key turns on append mode. Thus the contents
+of the paste buffer will not be overwritten, but appended to.
+
+`A' turns on append mode and sets a (second) mark.
+
+`>' sets the (second) mark and writes the contents of the paste buffer
+to the screen-exchange file (`/tmp/screen-exchange' per default) once
+copy-mode is finished. *Note Screen-Exchange::.
+This example demonstrates how to dump the whole scrollback buffer to
+that file:
+`C-a [ g SPACE G $ >'.
+
+`C-g' gives information about the current line and column.
+
+`x' exchanges the first mark and the current cursor position. You can
+use this to adjust an already placed mark.
+
+`@' does nothing. Absolutely nothing. Does not even exit copy mode.
+
+All keys not described here exit copy mode.
+
+
+File: screen.info, Node: Paste, Next: Registers, Prev: Copy, Up: Copy and Paste
+
+Paste
+=====
+
+ - Command: paste [REGISTERS [DESTINATION]]
+ (`C-a ]', `C-a C-]')
+ Write the (concatenated) contents of the specified registers to
+ the stdin stream of the current window. The register `.' is
+ treated as the paste buffer. If no parameter is specified the user
+ is prompted to enter a single register. The paste buffer can be
+ filled with the `copy', `history' and `readbuf' commands. Other
+ registers can be filled with the `register', `readreg' and `paste'
+ commands. If `paste' is called with a second argument, the
+ contents of the specified registers is pasted into the named
+ destination register rather than the window. If `.' is used as the
+ second argument, the display's paste buffer is the destination.
+ Note, that `paste' uses a wide variety of resources: Usually both,
+ a current window and a current display are required. But whenever
+ a second argument is specified no current window is needed. When
+ the source specification only contains registers (not the paste
+ buffer) then there need not be a current display (terminal
+ attached), as the registers are a global resource. The paste
+ buffer exists once for every user.
+
+ - Command: pastefont [STATE]
+ Tell screen to include font information in the paste buffer. The
+ default is not to do so. This command is especially usefull for
+ multi character fonts like kanji.
+
+ - Command: slowpaste MSEC
+ - Command: defslowpaste MSEC
+ (none)
+ Define the speed text is inserted in the current window by the
+ `paste' command. If the slowpaste value is nonzero text is written
+ character by character. `screen' will pause for MSEC milliseconds
+ after each write to allow the application to process the input.
+ only use `slowpaste' if your underlying system exposes flow
+ control problems while pasting large amounts of text.
+ `defslowpaste' specifies the default for new windows.
+
+ - Command: readreg [REGISTER [FILENAME]]
+ (none)
+ Does one of two things, dependent on number of arguments: with
+ zero or one arguments it it duplicates the paste buffer contents
+ into the register specified or entered at the prompt. With two
+ arguments it reads the contents of the named file into the
+ register, just as `readbuf' reads the screen-exchange file into
+ the paste buffer. The following example will paste the system's
+ password file into the screen window (using register p, where a
+ copy remains):
+
+ C-a : readreg p /etc/passwd
+ C-a : paste p
+
+
+File: screen.info, Node: Registers, Next: Screen-Exchange, Prev: Paste, Up: Copy and Paste
+
+Registers
+=========
+
+ - Command: copy_reg [KEY]
+ (none)
+ Removed. Use `readreg' instead.
+
+ - Command: ins_reg [KEY]
+ (none)
+ Removed. Use `paste' instead.
+
+ - Command: process [KEY]
+ (none)
+ Stuff the contents of the specified register into the `screen'
+ input queue. If no argument is given you are prompted for a
+ register name. The text is parsed as if it had been typed in from
+ the user's keyboard. This command can be used to bind multiple
+ actions to a single key.
+
+ - Command: register KEY STRING
+ (none)
+ Save the specified STRING to the register KEY.
+
+ - Command: stuff STRING
+ (none)
+ Stuff the string STRING in the input buffer of the current window.
+ This is like the `paste' command, but with much less overhead.
+ You cannot paste large buffers with the `stuff' command. It is most
+ useful for key bindings. *Note Bindkey::
+
+
+
+File: screen.info, Node: Screen-Exchange, Next: History, Prev: Registers, Up: Copy and Paste
+
+Screen-Exchange
+===============
+
+ - Command: bufferfile [EXCHANGE-FILE]
+ (none)
+ Change the filename used for reading and writing with the paste
+ buffer. If the EXCHANGE-FILE parameter is omitted, `screen'
+ reverts to the default of `/tmp/screen-exchange'. The following
+ example will paste the system's password file into the screen
+ window (using the paste buffer, where a copy remains):
+
+ C-a : bufferfile /etc/passwd
+ C-a < C-a ]
+ C-a : bufferfile
+
+ - Command: readbuf
+ (`C-a <')
+ Reads the contents of the current screen-exchange file into the
+ paste buffer.
+
+ - Command: removebuf
+ (`C-a =')
+ Unlinks the screen-exchange file.
+
+ - Command: writebuf
+ (`C-a >')
+ Writes the contents of the paste buffer to a public accessible
+ screen-exchange file. This is thought of as a primitive means of
+ communication between `screen' users on the same host. See also
+ `C-a ESC' (*note Copy::.).
+
+
+File: screen.info, Node: History, Prev: Screen-Exchange, Up: Copy and Paste
+
+History
+=======
+
+ - Command: history
+ (`C-a {')
+ Usually users work with a shell that allows easy access to previous
+ commands. For example, `csh' has the command `!!' to repeat the
+ last command executed. `screen' provides a primitive way of
+ recalling "the command that started ...": You just type the first
+ letter of that command, then hit `C-a {' and `screen' tries to
+ find a previous line that matches with the prompt character to the
+ left of the cursor. This line is pasted into this window's input
+ queue. Thus you have a crude command history (made up by the
+ visible window and its scrollback buffer).
+
+
+File: screen.info, Node: Subprocess Execution, Next: Key Binding, Prev: Copy and Paste, Up: Top
+
+Subprocess Execution
+********************
+
+ Control Input or Output of a window by another filter process. Use
+with care!
+
+* Menu:
+
+* Exec:: The `exec' command syntax.
+* Using Exec:: Weird things that filters can do.
+
+
+File: screen.info, Node: Exec, Next: Using Exec, Up: Subprocess Execution
+
+Exec
+====
+
+ - Command: exec [[FDPAT] NEWCOMMAND [ARGS ... ]]
+ (none)
+ Run a unix subprocess (specified by an executable path NEWCOMMAND
+ and its optional arguments) in the current window. The flow of
+ data between newcommands stdin/stdout/stderr, the process
+ originally started (let us call it "application-process") and
+ screen itself (window) is controlled by the filedescriptor pattern
+ FDPAT. This pattern is basically a three character sequence
+ representing stdin, stdout and stderr of newcommand. A dot (`.')
+ connects the file descriptor to screen. An exclamation mark (`!')
+ causes the file descriptor to be connected to the
+ application-process. A colon (`:') combines both.
+ User input will go to newcommand unless newcommand receives the
+ application-process' output (FDPATs first character is `!' or `:')
+ or a pipe symbol (`|') is added to the end of FDPAT.
+ Invoking `exec' without arguments shows name and arguments of the
+ currently running subprocess in this window. Only one subprocess
+ can be running per window.
+ When a subprocess is running the `kill' command will affect it
+ instead of the windows process. Only one subprocess a time can be
+ running in each window.
+ Refer to the postscript file `doc/fdpat.ps' for a confusing
+ illustration of all 21 possible combinations. Each drawing shows
+ the digits 2, 1, 0 representing the three file descriptors of
+ newcommand. The box marked `W' is usual pty that has the
+ application-process on its slave side. The box marked `P' is the
+ secondary pty that now has screen at its master side.
+
+
+File: screen.info, Node: Using Exec, Prev: Exec, Up: Subprocess Execution
+
+Using Exec
+==========
+
+Abbreviations:
+
+ * Whitespace between the word `exec' and FDPAT and the command name
+ can be omitted.
+
+ * Trailing dots and a FDPAT consisting only of dots can be omitted.
+
+ * A simple `|' is synonymous for the `!..|' pattern.
+
+ * The word `exec' can be omitted when the `|' abbreviation is used.
+
+ * The word `exec' can always be replaced by leading `!'.
+
+Examples:
+
+`!/bin/sh'
+`exec /bin/sh'
+`exec ... /bin/sh'
+ All of the above are equivalent. Creates another shell in the
+ same window, while the original shell is still running. Output of
+ both shells is displayed and user input is sent to the new
+ `/bin/sh'.
+
+`!!stty 19200'
+`exec!stty 19200'
+`exec !.. stty 19200'
+ All of the above are equivalent. Set the speed of the window's
+ tty. If your stty command operates on stdout, then add another
+ `!'. This is a useful command, when a screen window is directly
+ connected to a serial line that needs to be configured.
+
+`|less'
+`exec !..| less'
+ Both are equivalent. This adds a pager to the window output. The
+ special character `|' is needed to give the user control over the
+ pager although it gets its input from the window's process. This
+ works, because `less' listens on stderr (a behavior that `screen'
+ would not expect without the `|') when its stdin is not a tty.
+ `Less' versions newer than 177 fail miserably here; good old `pg'
+ still works.
+
+`!:sed -n s/.*Error.*/\007/p'
+ Sends window output to both, the user and the sed command. The sed
+ inserts an additional bell character (oct. 007) to the window
+ output seen by screen. This will cause 'Bell in window x'
+ messages, whenever the string `Error' appears in the window.
+
+
File: screen.info, Node: Key Binding, Next: Flow Control, Prev: Subprocess Execution, Up: Top
Key Binding
@@ -78,7 +547,7 @@ would bind the space key to the command that displays a list of windows
available as `C-a space'), bind `C-f' to the command "create a window
with a TELNET connection to foobar", and bind ESC to the command that
creates an non-login window with title `root' in slot #9, with a
-super-user shell and a scrollbackbuffer of 1000 lines.
+superuser shell and a scrollback buffer of 1000 lines.

File: screen.info, Node: Command Character, Next: Help, Prev: Bind Examples, Up: Key Binding
@@ -89,13 +558,13 @@ Command Character
- Command: escape XY
(none)
Set the command character to X and the character generating a
- literal command character to Y (just like with the `-e' option).
- Each argument is either a single character, a two-character
- sequence of the form `^x' (meaning `C-x'), a backslash followed by
- an octal number (specifying the ASCII code of the character), or a
- backslash followed by a second character, such as `\^' or `\\'.
- The default is `^Aa', but ```' is recommended by one of the
- authors.
+ literal command character (by triggering the `meta' command) to Y
+ (similar to the `-e' option). Each argument is either a single
+ character, a two-character sequence of the form `^x' (meaning
+ `C-x'), a backslash followed by an octal number (specifying the
+ ASCII code of the character), or a backslash followed by a second
+ character, such as `\^' or `\\'. The default is `^Aa', but ```'
+ is recommended by one of the authors.
- Command: defescape XY
(none)
@@ -161,11 +630,11 @@ Bindkey
have two entries in the translation table. You can select the
application mode entry by specifying the `-a' option.
- The `-t' option tells screen not to do intercharacter timing. One
- cannot turn off the timing if a termcap capabilty is used.
+ The `-t' option tells screen not to do inter-character timing. One
+ cannot turn off the timing if a termcap capability is used.
`cmd' can be any of screen's commands with an arbitrary number of
- `args'. If `cmd' is omitted the keybinding is removed from the
+ `args'. If `cmd' is omitted the key-binding is removed from the
table.

@@ -187,15 +656,15 @@ Make the "F1" key switch to window one.
bindkey -t foo stuff barfoo
-Make `foo' an abrevation of the word `barfoo'. Timeout is disabled so
+Make `foo' an abbreviation of the word `barfoo'. Timeout is disabled so
that users can type slowly.
bindkey "\024" mapdefault
-This keybinding makes `C-t' an escape character for keybindings. If you
-did the above `stuff barfoo' binding, you can enter the word `foo' by
-typing `C-t foo'. If you want to insert a `C-t' you have to press the
-key twice (i.e. escape the escape binding).
+This key-binding makes `C-t' an escape character for key-bindings. If
+you did the above `stuff barfoo' binding, you can enter the word `foo'
+by typing `C-t foo'. If you want to insert a `C-t' you have to press
+the key twice (i.e. escape the escape binding).
bindkey -k F1 command
@@ -430,7 +899,8 @@ the terminal, while all other windows are still active (the printer
port is enabled and disabled again for each chunk of output). As a
side-effect, programs running in different windows can send output to
the printer simultaneously. Data sent to the printer is not displayed
-in the window.
+in the window. The `info' command displays a line starting with `PRIN'
+while the printer is active.
Some capabilities are only put into the `$TERMCAP' variable of the
virtual terminal if they can be efficiently implemented by the physical
@@ -473,15 +943,15 @@ The `termcap' command
going through all the hassles involved in creating a custom
termcap entry. Plus, you can optionally customize the termcap
generated for the windows. You have to place these commands in
- one of the screenrc starup files, as they are meaningless once the
- terminal emulator is booted.
+ one of the screenrc startup files, as they are meaningless once
+ the terminal emulator is booted.
If your system uses the terminfo database rather than termcap,
- `screen' will understand the `terminfo' command which has the same
- effects as the `termcap' command. Two separate commands are
+ `screen' will understand the `terminfo' command, which has the
+ same effects as the `termcap' command. Two separate commands are
provided, as there are subtle syntactic differences, e.g. when
parameter interpolation (using `%') is required. Note that the
- termcap names of the capabilities have to be used with the
+ termcap names of the capabilities should also be used with the
`terminfo' command.
In many cases, where the arguments are valid in both terminfo and
@@ -608,11 +1078,11 @@ often not possible to place these capabilities in the terminfo database.
`CS'
(str)
- Switch cursor keys to application mode.
+ Switch cursor-keys to application mode.
`CE'
(str)
- Switch cursor keys to cursor mode.
+ Switch cursor-keys to cursor mode.
`AN'
(bool)
@@ -631,7 +1101,7 @@ often not possible to place these capabilities in the terminfo database.
`AF'
(str)
- Change character forground color in an ANSI conform way. This
+ Change character foreground color in an ANSI conform way. This
capability will almost always be set to `\E[3%dm' (`\E[3%p1%dm' on
terminfo machines).
@@ -648,6 +1118,11 @@ often not possible to place these capabilities in the terminfo database.
Describe a translation of characters to strings depending on the
current font. (*note Character Translation::.).
+`TF'
+ (bool)
+ Add missing capabilities to the termcap/info entry. (Set by
+ default).
+

File: screen.info, Node: Autonuke, Next: Obuflimit, Prev: Special Capabilities, Up: Termcap
@@ -714,7 +1189,7 @@ characters over several national language font pages.
<MAPPING> describes to what string a single character will be
translated. A template mechanism is used, as most of the time the codes
have a lot in common (for example strings to switch to and from another
-charset). Each occurence of `%' in <TEMPLATE> gets substituted with the
+charset). Each occurrence of `%' in <TEMPLATE> gets substituted with the
TEMPLATE-ARG specified together with the character. If your strings are
not similar at all, then use `%' as a template and place the full
string in <TEMPLATE-ARG>. A quoting mechanism was added to make it
@@ -735,7 +1210,7 @@ therefore a lot of quoting is needed to create a single `\'.
translates the unquoted `%' char, it will be sent to the terminal
whenever screen switches to the corresponding <DESIGNATOR>. In this
special case the template is assumed to be just `%' because the charset
-switch sequence and the character mappings normaly haven't much in
+switch sequence and the character mappings normally haven't much in
common.
This example shows one use of the extension:
@@ -790,592 +1265,31 @@ Hardware Status Line
====================
- Command: hardstatus [STATE]
+ - Command: hardstatus [`always']`lastline'|`message'|`ignore' [STRING]
+ - Command: hardstatus `string' [STRING]
(none)
- Toggles the use of the terminal's hardware status line. If `on',
- `screen' will use this facility to display one line messages.
- Otherwise these messages are overlayed in reverse video mode at the
- display line. Note that the hardstatus feature can only be used if
- the termcap/terminfo capabilities "hs", "ts", "fs" and "ds" are set
- properly. Default is `on' whenever the "hs" capability is present.
-
-
-File: screen.info, Node: Last Message, Next: Message Wait, Prev: Hardware Status Line, Up: Message Line
-
-Display Last Message
-====================
-
- - Command: lastmsg
- (`C-a m', `C-a C-m')
- Repeat the last message displayed in the message line. Useful if
- you're typing when a message appears, because (unless your
- terminal has a hardware status line) the message goes away when
- you press a key.
-
-
-File: screen.info, Node: Message Wait, Prev: Last Message, Up: Message Line
-
-Message Wait
-============
-
- - Command: msgminwait SEC
- (none)
- Defines the time `screen' delays a new message when another is
- currently displayed. Defaults to 1 second.
-
- - Command: msgwait SEC
- (none)
- Defines the time a message is displayed, if `screen' is not
- disturbed by other activity. Defaults to 5 seconds.
-
-
-File: screen.info, Node: Logging, Next: Startup, Prev: Message Line, Up: Top
-
-Logging
-*******
-
- This section describes the commands for keeping a record of your
-session.
-
-* Menu:
-
-* Hardcopy:: Dump the current screen to a file
-* Log:: Log the output of a window to a file
-
-
-File: screen.info, Node: Hardcopy, Next: Log, Up: Logging
-
-hardcopy
-========
-
- - Command: hardcopy
- (`C-a h', `C-a C-h')
- Writes out the current display contents to the file `hardcopy.N'
- in the window's default directory, where N is the number of the
- current window. This either appends or overwrites the file if it
- exists, as determined by the `hardcopy_append' command.
-
- - Command: hardcopy_append STATE
- (none)
- If set to `on', `screen' will append to the `hardcopy.N' files
- created by the command `hardcopy'; otherwise, these files are
- overwritten each time.
-
- - Command: hardcopydir DIRECTORY
- (none)
- Defines a directory where hardcopy files will be placed. If unset
- hardcopys are dumped in screen's current working directory.
-
-
-File: screen.info, Node: Log, Prev: Hardcopy, Up: Logging
-
-log
-===
-
- - Command: log [STATE]
- (`C-a H')
- Begins/ends logging of the current window to the file
- `screenlog.N' in the window's default directory, where N is the
- number of the current window. This filename can be changed with
- the `logfile' command. If no parameter is given, the logging
- state is toggled. The session log is appended to the previous
- contents of the file if it already exists. The current contents
- and the contents of the scrollback history are not included in the
- session log. Default is `off'.
-
- - Command: logfile FILENAME
- (none)
- Defines the name the logfiles will get. The default is
- `screenlog.%n'.
-
-
-File: screen.info, Node: Startup, Next: Miscellaneous, Prev: Logging, Up: Top
-
-Startup
-*******
-
- This section describes commands which are only useful in the
-`.screenrc' file, for use at startup.
-
-* Menu:
-
-* echo:: Display a message.
-* sleep:: Pause execution of the `.screenrc'.
-* Startup Message:: Control display of the copyright notice.
-
-
-File: screen.info, Node: echo, Next: sleep, Up: Startup
-
-echo
-====
-
- - Command: echo [-n] MESSAGE
- (none)
- The echo command may be used to annoy `screen' users with a
- 'message of the day'. Typically installed in a global screenrc.
- The option `-n' may be used to suppress the line feed. See also
- `sleep'. Echo is also useful for online checking of environment
- variables.
-
-
-File: screen.info, Node: sleep, Next: Startup Message, Prev: echo, Up: Startup
-
-sleep
-=====
-
- - Command: sleep NUM
- (none)
- This command will pause the execution of a .screenrc file for NUM
- seconds. Keyboard activity will end the sleep. It may be used to
- give users a chance to read the messages output by `echo'.
-
-
-File: screen.info, Node: Startup Message, Prev: sleep, Up: Startup
-
-Startup Message
-===============
-
- - Command: startup_message STATE
- (none)
- Select whether you want to see the copyright notice during startup.
- Default is `on', as you probably noticed.
-
-
-File: screen.info, Node: Miscellaneous, Next: Environment, Prev: Startup, Up: Top
-
-Miscellaneous commands
-**********************
-
- The commands described here do not fit well under any of the other
-categories.
-
-* Menu:
-
-* At:: Execute a command at other displays or windows.
-* Break:: Send a break signal to the window.
-* Debug:: Suppress/allow debugging output.
-* License:: Display the disclaimer page.
-* Nethack:: Use `nethack'-like error messages.
-* Number:: Change the current window's number.
-* Silence:: Notify on inactivity.
-* Time:: Display the time and load average.
-* Version:: Display the version of `screen'.
-* Zombie:: Keep dead windows.
-* Printcmd:: Set command for VT100 printer port emulation.
-* Sorendition:: Change the text highlighting method.
-
-
-File: screen.info, Node: At, Next: Break, Up: Miscellaneous
-
-At
-==
-
- - Command: at [IDENTIFIER][#|*|%] COMMAND [ARGS]
- (none)
- Execute a command at other displays or windows as if it had been
- entered there. `At' changes the context (the `current window' or
- `current display' setting) of the command. If the first parameter
- describes a non-unique context, the command will be executed
- multiple times. If the first parameter is of the form
- `IDENTIFIER*' then identifier is matched against user names. The
- command is executed once for each display of the selected user(s).
- If the first parameter is of the form `IDENTIFIER%' identifier is
- matched against displays. Displays are named after the ttys they
- attach. The prefix `/dev/' or `/dev/tty' may be omitted from the
- identifier. If IDENTIFIER has a `#' or nothing appended it is
- matched against window numbers and titles. Omitting an identifier
- in front of the `#', `*' or `%' character selects all users,
- displays or windows because a prefix-match is performed. Note that
- on the affected display(s) a short message will describe what
- happened. Caution: Permission is checked for the owners or the
- affected display(s), not for the initiator of the `at' command.
-
-
-File: screen.info, Node: Break, Next: Debug, Prev: At, Up: Miscellaneous
-
-Break
-=====
-
- - Command: break [DURATION]
- (none)
- Send a break signal for DURATION*0.25 seconds to this window.
- Most useful if a character device is attached to the window rather
- than a shell process.
-
- - Command: pow_break
- (none)
- Reopen the window's terminal line and send a break condition.
-
-
-File: screen.info, Node: Debug, Next: License, Prev: Break, Up: Miscellaneous
-
-Debug
-=====
-
- - Command: debug [ON|OFF]
- (none)
- Turns runtime debugging on or off. If `screen' has been compiled
- with option `-DDEBUG' debugging is available and is turned on per
- default. Note that this command only affects debugging output
- from the main `SCREEN' process.
-
-
-File: screen.info, Node: License, Next: Nethack, Prev: Debug, Up: Miscellaneous
-
-License
-=======
-
- - Command: license
- (none)
- Display the disclaimer page. This is done whenever `screen' is
- started without options, which should be often enough.
-
-
-File: screen.info, Node: Nethack, Next: Number, Prev: License, Up: Miscellaneous
-
-Nethack
-=======
-
- - Command: nethack STATE
- (none)
- Changes the kind of error messages used by `screen'. When you are
- familiar with the game `nethack', you may enjoy the nethack-style
- messages which will often blur the facts a little, but are much
- funnier to read. Anyway, standard messages often tend to be
- unclear as well.
-
- This option is only available if `screen' was compiled with the
- NETHACK flag defined (*note Installation::.). The default setting
- is then determined by the presence of the environment variable
- `$NETHACKOPTIONS'.
-
-
-File: screen.info, Node: Number, Next: Silence, Prev: Nethack, Up: Miscellaneous
-
-Number
-======
-
- - Command: number [N]
- (`C-a N')
- Change the current window's number. If the given number N is
- already used by another window, both windows exchange their
- numbers. If no argument is specified, the current window number
- (and title) is shown.
-
-
-File: screen.info, Node: Silence, Next: Time, Prev: Number, Up: Miscellaneous
-
-Silence
-=======
-
- - Command: silence [STATE|SEC]
- (none)
- Toggles silence monitoring of windows. When silence is turned on
- and an affected window is switched into the background, you will
- receive the silence notification message in the status line after
- a specified period of inactivity (silence). The default timeout
- can be changed with the `silencewait' command or by specifying a
- number of seconds instead of `on' or `off'. Silence is initially
- off for all windows.
-
- - Command: silencewait SECONDS
- (none)
- Define the time that all windows monitored for silence should wait
- before displaying a message. Default is 30 seconds.
-
-
-File: screen.info, Node: Time, Next: Version, Prev: Silence, Up: Miscellaneous
-
-Time
-====
-
- - Command: time
- (`C-a t', `C-a C-t')
- Uses the message line to display the time of day, the host name,
- and the load averages over 1, 5, and 15 minutes (if this is
- available on your system). For window-specific information use
- `info' (*note Info::.).
-
-
-File: screen.info, Node: Version, Next: Zombie, Prev: Time, Up: Miscellaneous
-
-Version
-=======
-
- - Command: version
- (`C-a v')
- Display the version and modification date in the message line.
-
-
-File: screen.info, Node: Zombie, Next: Printcmd, Prev: Version, Up: Miscellaneous
-
-Zombie
-======
-
- - Command: zombie [KEYX]
- - Command: defzombie [KEYX]
- (none)
- Per default windows are removed from the window list as soon as the
- windows process (e.g. shell) exits. When a string of two keys is
- specified to the zombie command, `dead' windows will remain in the
- list. The `kill' kommand may be used to remove the window.
- Pressing the first key in the dead window has the same effect.
- Pressing the second key, however, screen will attempt to resurrect
- the window. The process that was initially running in the window
- will be launched again. Calling `zombie' without parameters will
- clear the zombie setting, thus making windows disappear when the
- process terminates.
-
- As the zombie setting is affected globally for all windows, this
- command should only be called `defzombie'. Until we need this as a
- per window setting, the commands `zombie' and `defzombie' are
- synonymous.
-
-
-File: screen.info, Node: Printcmd, Next: Sorendition, Prev: Zombie, Up: Miscellaneous
-
-Printcmd
-========
-
- - Command: printcmd [CMD]
- (none)
- If CMD is not an empty string, screen will not use the terminal
- capabilities `po/pf' for printing if it detects an ansi print
- sequence `ESC [ 5 i', but pipe the output into CMD. This should
- normally be a command like `lpr' or `cat > /tmp/scrprint'.
- `Printcmd' without an argument displays the current setting. The
- ansi sequence `ESC \' ends printing and closes the pipe.
-
- Warning: Be careful with this command! If other user have write
- access to your terminal, they will be able to fire off print
- commands.
-
-
-File: screen.info, Node: Sorendition, Prev: Printcmd, Up: Miscellaneous
-
-Sorendition
-===========
-
- - Command: sorendition [ATTR [COLOR]]
- (none)
- Change the way screen does highlighting for text marking and
- printing messages. ATTR is a hexadecimal number and describes the
- attributes (inverse, underline, ...) the text will get. COLOR is
- a 2 digit number and changes the forground/background of the
- highlighted text. Some knowledge of screen's internal character
- representation is needed to make the characters appear in the
- desired way. The default is currently `10 99' (standout, default
- colors).
-
-
-File: screen.info, Node: Environment, Next: Files, Prev: Miscellaneous, Up: Top
-
-Environment Variables
-*********************
-
-`COLUMNS'
- Number of columns on the terminal (overrides termcap entry).
-
-`HOME'
- Directory in which to look for .screenrc.
-
-`ISCREENRC'
- Alternate user screenrc file.
-
-`LINES'
- Number of lines on the terminal (overrides termcap entry).
-
-`LOCKPRG'
- Screen lock program.
-
-`NETHACKOPTIONS'
- Turns on `nethack' option.
-
-`PATH'
- Used for locating programs to run.
-
-`SCREENCAP'
- For customizing a terminal's `TERMCAP' value.
-
-`SCREENDIR'
- Alternate socket directory.
-
-`SCREENRC'
- Alternate user screenrc file.
-
-`SHELL'
- Default shell program for opening windows (default `/bin/sh').
-
-`STY'
- Alternate socket name. If `screen' is invoked, and the environment
- variable `STY' is set, then it creates only a window in the
- running `screen' session rather than starting a new session.
-
-`SYSSCREENRC'
- Alternate system screenrc file.
-
-`TERM'
- Terminal name.
-
-`TERMCAP'
- Terminal description.
-
-
-File: screen.info, Node: Files, Next: Credits, Prev: Environment, Up: Top
-
-Files Referenced
-****************
-
-`.../screen-3.?.??/etc/screenrc'
-`.../screen-3.?.??/etc/etcscreenrc'
- Examples in the `screen' distribution package for private and
- global initialization files.
-
-``$SYSSCREENRC''
-`/local/etc/screenrc'
- `screen' initialization commands
-
-``$ISCREENRC''
-``$SCREENRC''
-``$HOME'/.iscreenrc'
-``$HOME'/.screenrc'
- Read in after /local/etc/screenrc
-
-``$ISCREENDIR'/S-LOGIN'
-``$SCREENDIR'/S-LOGIN'
-`/local/screens/S-LOGIN'
- Socket directories (default)
-
-`/usr/tmp/screens/S-LOGIN'
- Alternate socket directories.
-
-`SOCKET DIRECTORY/.termcap'
- Written by the `dumptermcap' command
-
-`/usr/tmp/screens/screen-exchange or'
-`/tmp/screen-exchange'
- `screen' interprocess communication buffer
-
-`hardcopy.[0-9]'
- Screen images created by the hardcopy command
-
-`screenlog.[0-9]'
- Output log files created by the log command
-
-`/usr/lib/terminfo/?/* or'
-`/etc/termcap'
- Terminal capability databases
-
-`/etc/utmp'
- Login records
-
-``$LOCKPRG''
- Program for locking the terminal.
-
-
-File: screen.info, Node: Credits, Next: Bugs, Prev: Files, Up: Top
-
-Credits
-*******
-
-Authors
-=======
-
- Originally created by Oliver Laumann, this latest version was
-produced by Wayne Davison, Juergen Weigert and Michael Schroeder.
-
-Contributors
-============
-
- Ken Beal (kbeal@amber.ssd.csd.harris.com),
- Rudolf Koenig (rfkoenig@informatik.uni-erlangen.de),
- Toerless Eckert (eckert@informatik.uni-erlangen.de),
- Wayne Davison (davison@borland.com),
- Patrick Wolfe (pat@kai.com, kailand!pat),
- Bart Schaefer (schaefer@cse.ogi.edu),
- Nathan Glasser (nathan@brokaw.lcs.mit.edu),
- Larry W. Virden (lvirden@cas.org),
- Howard Chu (hyc@hanauma.jpl.nasa.gov),
- Tim MacKenzie (tym@dibbler.cs.monash.edu.au),
- Markku Jarvinen (mta@{cc,cs,ee}.tut.fi),
- Marc Boucher (marc@CAM.ORG),
- Doug Siebert (dsiebert@isca.uiowa.edu),
- Ken Stillson (stillson@tsfsrv.mitre.org),
- Ian Frechett (frechett@spot.Colorado.EDU),
- Brian Koehmstedt (bpk@gnu.ai.mit.edu),
- Don Smith (djs6015@ultb.isc.rit.edu),
- Frank van der Linden (vdlinden@fwi.uva.nl),
- Martin Schweikert (schweik@cpp.ob.open.de),
- David Vrona (dave@sashimi.lcu.com),
- E. Tye McQueen (tye%spillman.UUCP@uunet.uu.net),
- Matthew Green (mrgreen@mame.mu.oz.au),
- Christopher Williams (cgw@unt.edu),
- Matt Mosley (mattm@access.digex.net),
- Gregory Neil Shapiro (gshapiro@wpi.WPI.EDU),
- Jason Merrill (jason@jarthur.Claremont.EDU).
-
-Version
-=======
-
- This manual describes version 3.7.0 of the `screen' program. Its
-roots are a merge of a custom version 2.3PR7 by Wayne Davison and
-several enhancements to Oliver Laumann's version 2.0. Note that all
-versions numbered 2.x are copyright by Oliver Laumann.
-
- See also *Note Availability::.
-
-
-File: screen.info, Node: Bugs, Next: Installation, Prev: Credits, Up: Top
-
-Bugs
-****
-
- Just like any other significant piece of software, `screen' has a
-few bugs and missing features. Please send in a bug report if you have
-found a bug not mentioned here.
-
-* Menu:
-
-* Known Bugs:: Problems we know about.
-* Reporting Bugs:: How to contact the maintainers.
-* Availability:: Where to find the lastest screen version.
-
-
-File: screen.info, Node: Known Bugs, Next: Reporting Bugs, Up: Bugs
-
-Known Bugs
-==========
-
- * `dm' (delete mode) and `xs' are not handled correctly (they are
- ignored). `xn' is treated as a magic-margin indicator.
-
- * `screen' has no clue about double-high or double-wide characters.
- But this is the only area where `vttest' is allowed to fail.
-
- * It is not possible to change the environment variable `$TERMCAP'
- when reattaching under a different terminal type.
-
- * The support of terminfo based systems is very limited. Adding extra
- capabilities to `$TERMCAP' may not have any effects.
-
- * `screen' does not make use of hardware tabs.
-
- * `screen' must be installed setuid root in order to be able to
- correctly change the owner of the tty device file for each window.
- Special permission may also be required to write the file
- `/etc/utmp'.
-
- * Entries in `/etc/utmp' are not removed when `screen' is killed
- with SIGKILL. This will cause some programs (like "w" or "rwho")
- to advertise that a user is logged on who really isn't.
-
- * `screen' may give a strange warning when your tty has no utmp
- entry.
-
- * When the modem line was hung up, `screen' may not automatically
- detach (or quit) unless the device driver sends a HANGUP signal.
- To detach such a `screen' session use the -D or -d command line
- option.
-
- * A weird imagination is most useful to gain full advantage of all
- the features.
+ This command configures the use and emulation of the terminal's
+ hardstatus line. The first form toggles whether `screen' will use
+ the hardware status line to display messages. If the flag is set
+ to `off', these messages are overlaid in reverse video mode at the
+ display line. The default setting is `on'.
+
+ The second form tells screen what to do if the terminal doesn't
+ have a hardstatus line (i.e. the termcap/terminfo capabilities
+ "hs", "ts", "fs" and "ds" are not set). If the type `lastline' is
+ used, screen will reserve the last line of the display for the
+ hardstatus. `message' uses `screen''s message mechanism and
+ `ignore' tells `screen' never to display the hardstatus. If you
+ prepend the word `always' to the type, `screen' will use the type
+ even if the terminal supports a hardstatus line.
+
+ The third form specifies the contents of the hardstatus line.
+ `%h' is used as default string, i.e. the stored hardstatus of the
+ current window (settable via `\E]0;^G' or `\E_\\') is displayed.
+ You can customize this to any string you like including string
+ escapes (*Note String Escapes::). If you leave out the argument
+ STRING, the current string is displayed.
+
+ You can mix the second and third form by providing the string as
+ additional argument.
diff --git a/doc/screen.info-4 b/doc/screen.info-4
index f466b1a..727e2af 100644
--- a/doc/screen.info-4
+++ b/doc/screen.info-4
@@ -3,7 +3,7 @@ file ./screen.texinfo.
This file documents the `Screen' virtual terminal manager.
- Copyright (c) 1993 Free Software Foundation, Inc.
+ Copyright (c) 1993-1995 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
@@ -20,6 +20,755 @@ versions, except that this permission notice may be stated in a
translation approved by the Foundation.

+File: screen.info, Node: Last Message, Next: Message Wait, Prev: Hardware Status Line, Up: Message Line
+
+Display Last Message
+====================
+
+ - Command: lastmsg
+ (`C-a m', `C-a C-m')
+ Repeat the last message displayed in the message line. Useful if
+ you're typing when a message appears, because (unless your
+ terminal has a hardware status line) the message goes away when
+ you press a key.
+
+
+File: screen.info, Node: Message Wait, Prev: Last Message, Up: Message Line
+
+Message Wait
+============
+
+ - Command: msgminwait SEC
+ (none)
+ Defines the time `screen' delays a new message when another is
+ currently displayed. Defaults to 1 second.
+
+ - Command: msgwait SEC
+ (none)
+ Defines the time a message is displayed, if `screen' is not
+ disturbed by other activity. Defaults to 5 seconds.
+
+
+File: screen.info, Node: Logging, Next: Startup, Prev: Message Line, Up: Top
+
+Logging
+*******
+
+ This section describes the commands for keeping a record of your
+session.
+
+* Menu:
+
+* Hardcopy:: Dump the current screen to a file
+* Log:: Log the output of a window to a file
+
+
+File: screen.info, Node: Hardcopy, Next: Log, Up: Logging
+
+hardcopy
+========
+
+ - Command: hardcopy
+ (`C-a h', `C-a C-h')
+ Writes out the current display contents to the file `hardcopy.N'
+ in the window's default directory, where N is the number of the
+ current window. This either appends or overwrites the file if it
+ exists, as determined by the `hardcopy_append' command.
+
+ - Command: hardcopy_append STATE
+ (none)
+ If set to `on', `screen' will append to the `hardcopy.N' files
+ created by the command `hardcopy'; otherwise, these files are
+ overwritten each time.
+
+ - Command: hardcopydir DIRECTORY
+ (none)
+ Defines a directory where hardcopy files will be placed. If unset
+ hardcopys are dumped in screen's current working directory.
+
+
+File: screen.info, Node: Log, Prev: Hardcopy, Up: Logging
+
+log
+===
+
+ - Command: log [STATE]
+ (`C-a H')
+ Begins/ends logging of the current window to the file
+ `screenlog.N' in the window's default directory, where N is the
+ number of the current window. This filename can be changed with
+ the `logfile' command. If no parameter is given, the logging
+ state is toggled. The session log is appended to the previous
+ contents of the file if it already exists. The current contents
+ and the contents of the scrollback history are not included in the
+ session log. Default is `off'.
+
+ - Command: logfile FILENAME
+ - Command: logfile FLUSH SECS
+ (none)
+ Defines the name the logfiles will get. The default is
+ `screenlog.%n'. The second form changes the number of seconds
+ `screen' will wait before flushing the logfile buffer to the
+ file-system. The default value is 10 seconds.
+
+ - Command: logtstamp [STATE]
+ - Command: logtstamp `after' SECS
+ - Command: logtstamp `string' STRING
+ (none)
+ This command controls logfile time-stamp mechanism of screen. If
+ time-stamps are turned `on', screen adds a string containing the
+ current time to the logfile after two minutes of inactivity. When
+ output continues and more than another two minutes have passed, a
+ second time-stamp is added to document the restart of the output.
+ You can change this timeout with the second form of the command.
+ The third form is used for customizing the time-stamp string (`--
+ %n:%t -- time-stamp -- %M/%d/%y %c:%s --\n' by default).
+
+
+File: screen.info, Node: Startup, Next: Miscellaneous, Prev: Logging, Up: Top
+
+Startup
+*******
+
+ This section describes commands which are only useful in the
+`.screenrc' file, for use at startup.
+
+* Menu:
+
+* echo:: Display a message.
+* sleep:: Pause execution of the `.screenrc'.
+* Startup Message:: Control display of the copyright notice.
+
+
+File: screen.info, Node: echo, Next: sleep, Up: Startup
+
+echo
+====
+
+ - Command: echo [`-n'] MESSAGE
+ (none)
+ The echo command may be used to annoy `screen' users with a
+ 'message of the day'. Typically installed in a global screenrc.
+ The option `-n' may be used to suppress the line feed. See also
+ `sleep'. Echo is also useful for online checking of environment
+ variables.
+
+
+File: screen.info, Node: sleep, Next: Startup Message, Prev: echo, Up: Startup
+
+sleep
+=====
+
+ - Command: sleep NUM
+ (none)
+ This command will pause the execution of a .screenrc file for NUM
+ seconds. Keyboard activity will end the sleep. It may be used to
+ give users a chance to read the messages output by `echo'.
+
+
+File: screen.info, Node: Startup Message, Prev: sleep, Up: Startup
+
+Startup Message
+===============
+
+ - Command: startup_message STATE
+ (none)
+ Select whether you want to see the copyright notice during startup.
+ Default is `on', as you probably noticed.
+
+
+File: screen.info, Node: Miscellaneous, Next: String Escapes, Prev: Startup, Up: Top
+
+Miscellaneous commands
+**********************
+
+ The commands described here do not fit well under any of the other
+categories.
+
+* Menu:
+
+* At:: Execute a command at other displays or windows.
+* Break:: Send a break signal to the window.
+* Debug:: Suppress/allow debugging output.
+* License:: Display the disclaimer page.
+* Nethack:: Use `nethack'-like error messages.
+* Nonblock:: Disable flow-control to a display.
+* Number:: Change the current window's number.
+* Silence:: Notify on inactivity.
+* Time:: Display the time and load average.
+* Verbose:: Display window creation commands.
+* Version:: Display the version of `screen'.
+* Zombie:: Keep dead windows.
+* Printcmd:: Set command for VT100 printer port emulation.
+* Sorendition:: Change the text highlighting method.
+
+
+File: screen.info, Node: At, Next: Break, Up: Miscellaneous
+
+At
+==
+
+ - Command: at [IDENTIFIER][#|*|%] COMMAND [ARGS]
+ (none)
+ Execute a command at other displays or windows as if it had been
+ entered there. `At' changes the context (the `current window' or
+ `current display' setting) of the command. If the first parameter
+ describes a non-unique context, the command will be executed
+ multiple times. If the first parameter is of the form
+ `IDENTIFIER*' then identifier is matched against user names. The
+ command is executed once for each display of the selected user(s).
+ If the first parameter is of the form `IDENTIFIER%' identifier is
+ matched against displays. Displays are named after the ttys they
+ attach. The prefix `/dev/' or `/dev/tty' may be omitted from the
+ identifier. If IDENTIFIER has a `#' or nothing appended it is
+ matched against window numbers and titles. Omitting an identifier
+ in front of the `#', `*' or `%' character selects all users,
+ displays or windows because a prefix-match is performed. Note that
+ on the affected display(s) a short message will describe what
+ happened. Note that the `#' character works as a comment
+ introducer when it is preceded by whitespace. This can be escaped
+ by prefixing `#' with a `\'. Permission is checked for the
+ initiator of the `at' command, not for the owners of the affected
+ display(s). Caveat: When matching against windows, the command is
+ executed at least once per window. Commands that change the
+ internal arrangement of windows (like `other') may be called
+ again. In shared windows the command will be repeated for each
+ attached display. Beware, when issuing toggle commands like
+ `login'! Some commands (e.g. `stuff', `\*Qprocess' or `paste')
+ require that a display is associated with the target windows.
+ These commands may not work correctly under `at' looping over
+ windows.
+
+
+File: screen.info, Node: Break, Next: Debug, Prev: At, Up: Miscellaneous
+
+Break
+=====
+
+ - Command: break [DURATION]
+ (none)
+ Send a break signal for DURATION*0.25 seconds to this window. For
+ non-Posix systems the time interval is rounded up to full seconds.
+ Most useful if a character device is attached to the window rather
+ than a shell process (*note Window Types::.). The maximum duration
+ of a break signal is limited to 15 seconds.
+
+ - Command: pow_break
+ (none)
+ Reopen the window's terminal line and send a break condition.
+
+ - Command: breaktype [TCSENDBREAK|TIOCSBRK|TCSBRK]
+ (none)
+ Choose one of the available methods of generating a break signal
+ for terminal devices. This command should affect the current
+ window only. But it still behaves identical to `defbreaktype'.
+ This will be changed in the future. Calling `breaktype' with no
+ parameter displays the break setting for the current window.
+
+ - Command: defbreaktype [TCSENDBREAK|TIOCSBRK|TCSBRK]
+ (none)
+ Choose one of the available methods of generating a break signal
+ for terminal devices opened afterwards. The preferred methods are
+ `tcsendbreak' and `TIOCSBRK'. The third, `TCSBRK', blocks the
+ complete `screen' session for the duration of the break, but it
+ may be the only way to generate long breaks. `tcsendbreak' and
+ `TIOCSBRK' may or may not produce long breaks with spikes (e.g. 4
+ per second). This is not only system dependant, this also differs
+ between serial board drivers. Calling `defbreaktype' with no
+ parameter displays the current setting.
+
+
+File: screen.info, Node: Debug, Next: License, Prev: Break, Up: Miscellaneous
+
+Debug
+=====
+
+ - Command: debug [ON|OFF]
+ (none)
+ Turns runtime debugging on or off. If `screen' has been compiled
+ with option `-DDEBUG' debugging is available and is turned on per
+ default. Note that this command only affects debugging output
+ from the main `SCREEN' process correctly. Debug output from
+ attacher processes can only be turned off once and forever.
+
+
+File: screen.info, Node: License, Next: Nethack, Prev: Debug, Up: Miscellaneous
+
+License
+=======
+
+ - Command: license
+ (none)
+ Display the disclaimer page. This is done whenever `screen' is
+ started without options, which should be often enough.
+
+
+File: screen.info, Node: Nethack, Next: Nonblock, Prev: License, Up: Miscellaneous
+
+Nethack
+=======
+
+ - Command: nethack STATE
+ (none)
+ Changes the kind of error messages used by `screen'. When you are
+ familiar with the game `nethack', you may enjoy the nethack-style
+ messages which will often blur the facts a little, but are much
+ funnier to read. Anyway, standard messages often tend to be
+ unclear as well.
+
+ This option is only available if `screen' was compiled with the
+ NETHACK flag defined (*note Installation::.). The default setting
+ is then determined by the presence of the environment variable
+ `$NETHACKOPTIONS'.
+
+
+File: screen.info, Node: Nonblock, Next: Number, Prev: Nethack, Up: Miscellaneous
+
+Nonblock
+========
+
+ - Command: nonblock STATE
+ Enable or disable flow control for the current user interface
+ (display). It is used to prevent a slow display from slowing down
+ the processing of data output by a window. This command may be
+ helpful when multiple displays show the same window. `Nonblock'
+ is initially off for all displays.
+
+
+File: screen.info, Node: Number, Next: Silence, Prev: Nonblock, Up: Miscellaneous
+
+Number
+======
+
+ - Command: number [N]
+ (`C-a N')
+ Change the current window's number. If the given number N is
+ already used by another window, both windows exchange their
+ numbers. If no argument is specified, the current window number
+ (and title) is shown.
+
+
+File: screen.info, Node: Silence, Next: Time, Prev: Number, Up: Miscellaneous
+
+Silence
+=======
+
+ - Command: silence [STATE|SEC]
+ (none)
+ Toggles silence monitoring of windows. When silence is turned on
+ and an affected window is switched into the background, you will
+ receive the silence notification message in the status line after
+ a specified period of inactivity (silence). The default timeout
+ can be changed with the `silencewait' command or by specifying a
+ number of seconds instead of `on' or `off'. Silence is initially
+ off for all windows.
+
+ - Command: defsilence STATE
+ (none)
+ Same as the `silence' command except that the default setting for
+ new windows is changed. Initial setting is `off'.
+
+ - Command: silencewait SECONDS
+ (none)
+ Define the time that all windows monitored for silence should wait
+ before displaying a message. Default is 30 seconds.
+
+
+File: screen.info, Node: Time, Next: Verbose, Prev: Silence, Up: Miscellaneous
+
+Time
+====
+
+ - Command: time
+ (`C-a t', `C-a C-t')
+ Uses the message line to display the time of day, the host name,
+ and the load averages over 1, 5, and 15 minutes (if this is
+ available on your system). For window-specific information use
+ `info' (*note Info::.).
+
+
+File: screen.info, Node: Verbose, Next: Version, Prev: Time, Up: Miscellaneous
+
+Verbose
+=======
+
+ - Command: verbose [ON|OFF]
+ If verbose is switched on, the command name is echoed, whenever a
+ window is created (or resurrected from zombie state). Default is
+ off. Without parameter, the current setting is shown.
+
+
+File: screen.info, Node: Version, Next: Zombie, Prev: Verbose, Up: Miscellaneous
+
+Version
+=======
+
+ - Command: version
+ (`C-a v')
+ Display the version and modification date in the message line.
+
+
+File: screen.info, Node: Zombie, Next: Printcmd, Prev: Version, Up: Miscellaneous
+
+Zombie
+======
+
+ - Command: zombie [KEYS]
+ - Command: defzombie [KEYS]
+ (none)
+ Per default windows are removed from the window list as soon as the
+ windows process (e.g. shell) exits. When a string of two keys is
+ specified to the zombie command, `dead' windows will remain in the
+ list. The `kill' command may be used to remove the window.
+ Pressing the first key in the dead window has the same effect.
+ Pressing the second key, however, screen will attempt to resurrect
+ the window. The process that was initially running in the window
+ will be launched again. Calling `zombie' without parameters will
+ clear the zombie setting, thus making windows disappear when the
+ process terminates.
+
+ As the zombie setting is affected globally for all windows, this
+ command should only be called `defzombie'. Until we need this as a
+ per window setting, the commands `zombie' and `defzombie' are
+ synonymous.
+
+
+File: screen.info, Node: Printcmd, Next: Sorendition, Prev: Zombie, Up: Miscellaneous
+
+Printcmd
+========
+
+ - Command: printcmd [CMD]
+ (none)
+ If CMD is not an empty string, screen will not use the terminal
+ capabilities `po/pf' for printing if it detects an ansi print
+ sequence `ESC [ 5 i', but pipe the output into CMD. This should
+ normally be a command like `lpr' or `cat > /tmp/scrprint'.
+ `Printcmd' without an argument displays the current setting. The
+ ansi sequence `ESC \' ends printing and closes the pipe.
+
+ Warning: Be careful with this command! If other user have write
+ access to your terminal, they will be able to fire off print
+ commands.
+
+
+File: screen.info, Node: Sorendition, Prev: Printcmd, Up: Miscellaneous
+
+Sorendition
+===========
+
+ - Command: sorendition [ATTR [COLOR]]
+ (none)
+ Change the way screen does highlighting for text marking and
+ printing messages. ATTR is a hexadecimal number and describes the
+ attributes (inverse, underline, ...) the text will get. COLOR is
+ a 2 digit number and changes the foreground/background of the
+ highlighted text. Some knowledge of screen's internal character
+ representation is needed to make the characters appear in the
+ desired way. The default is currently `10 99' (standout, default
+ colors).
+
+
+File: screen.info, Node: String Escapes, Next: Environment, Prev: Miscellaneous, Up: Top
+
+String Escapes
+**************
+
+ Screen provides an escape mechanism to insert information like the
+current time into messages or file names. The escape character is `%'
+with one exception: inside of a window's hardstatus `^%' (`^E') is used
+instead.
+
+ Here is the full list of supported escapes:
+
+`%'
+ the escape character itself
+
+`a'
+ either `am' or `pm'
+
+`A'
+ either `AM' or `PM'
+
+`c'
+ current time `HH:MM' in 24h format
+
+`C'
+ current time `HH:MM' in 12h format
+
+`d'
+ day number
+
+`D'
+ weekday name
+
+`h'
+ hardstatus of the window
+
+`l'
+ current load of the system
+
+`m'
+ month number
+
+`M'
+ month name
+
+`n'
+ window number
+
+`s'
+ seconds
+
+`t'
+ window title
+
+`u'
+ all other users on this window
+
+`w'
+ all window numbers and names
+
+`W'
+ all window numbers and names except the current one
+
+`y'
+ last two digits of the year number
+
+`Y'
+ full year number
+
+`?'
+ the part to the next `%?' is displayed only if an escape expands
+ to an nonempty string
+
+`:'
+ else part of `%?' The `c' and `C' escape may be qualified with a
+`0' to make screen use zero instead of space as fill character. The `n'
+escape understands a length qualifier (e.g. `%3n').
+
+
+File: screen.info, Node: Environment, Next: Files, Prev: String Escapes, Up: Top
+
+Environment Variables
+*********************
+
+`COLUMNS'
+ Number of columns on the terminal (overrides termcap entry).
+
+`HOME'
+ Directory in which to look for .screenrc.
+
+`LINES'
+ Number of lines on the terminal (overrides termcap entry).
+
+`LOCKPRG'
+ Screen lock program.
+
+`NETHACKOPTIONS'
+ Turns on `nethack' option.
+
+`PATH'
+ Used for locating programs to run.
+
+`SCREENCAP'
+ For customizing a terminal's `TERMCAP' value.
+
+`SCREENDIR'
+ Alternate socket directory.
+
+`SCREENRC'
+ Alternate user screenrc file.
+
+`SHELL'
+ Default shell program for opening windows (default `/bin/sh').
+
+`STY'
+ Alternate socket name. If `screen' is invoked, and the environment
+ variable `STY' is set, then it creates only a window in the
+ running `screen' session rather than starting a new session.
+
+`SYSSCREENRC'
+ Alternate system screenrc file.
+
+`TERM'
+ Terminal name.
+
+`TERMCAP'
+ Terminal description.
+
+
+File: screen.info, Node: Files, Next: Credits, Prev: Environment, Up: Top
+
+Files Referenced
+****************
+
+`.../screen-3.?.??/etc/screenrc'
+`.../screen-3.?.??/etc/etcscreenrc'
+ Examples in the `screen' distribution package for private and
+ global initialization files.
+
+``$SYSSCREENRC''
+`/local/etc/screenrc'
+ `screen' initialization commands
+
+``$SCREENRC''
+``$HOME'/.iscreenrc'
+``$HOME'/.screenrc'
+ Read in after /local/etc/screenrc
+
+``$SCREENDIR'/S-LOGIN'
+`/local/screens/S-LOGIN'
+ Socket directories (default)
+
+`/usr/tmp/screens/S-LOGIN'
+ Alternate socket directories.
+
+`SOCKET DIRECTORY/.termcap'
+ Written by the `dumptermcap' command
+
+`/usr/tmp/screens/screen-exchange or'
+`/tmp/screen-exchange'
+ `screen' interprocess communication buffer
+
+`hardcopy.[0-9]'
+ Screen images created by the hardcopy command
+
+`screenlog.[0-9]'
+ Output log files created by the log command
+
+`/usr/lib/terminfo/?/* or'
+`/etc/termcap'
+ Terminal capability databases
+
+`/etc/utmp'
+ Login records
+
+``$LOCKPRG''
+ Program for locking the terminal.
+
+
+File: screen.info, Node: Credits, Next: Bugs, Prev: Files, Up: Top
+
+Credits
+*******
+
+Authors
+=======
+
+ Originally created by Oliver Laumann, this latest version was
+produced by Wayne Davison, Juergen Weigert and Michael Schroeder.
+
+Contributors
+============
+
+ Ken Beal (kbeal@amber.ssd.csd.harris.com),
+ Rudolf Koenig (rfkoenig@informatik.uni-erlangen.de),
+ Toerless Eckert (eckert@informatik.uni-erlangen.de),
+ Wayne Davison (davison@borland.com),
+ Patrick Wolfe (pat@kai.com, kailand!pat),
+ Bart Schaefer (schaefer@cse.ogi.edu),
+ Nathan Glasser (nathan@brokaw.lcs.mit.edu),
+ Larry W. Virden (lvirden@cas.org),
+ Howard Chu (hyc@hanauma.jpl.nasa.gov),
+ Tim MacKenzie (tym@dibbler.cs.monash.edu.au),
+ Markku Jarvinen (mta@{cc,cs,ee}.tut.fi),
+ Marc Boucher (marc@CAM.ORG),
+ Doug Siebert (dsiebert@isca.uiowa.edu),
+ Ken Stillson (stillson@tsfsrv.mitre.org),
+ Ian Frechett (frechett@spot.Colorado.EDU),
+ Brian Koehmstedt (bpk@gnu.ai.mit.edu),
+ Don Smith (djs6015@ultb.isc.rit.edu),
+ Frank van der Linden (vdlinden@fwi.uva.nl),
+ Martin Schweikert (schweik@cpp.ob.open.de),
+ David Vrona (dave@sashimi.lcu.com),
+ E. Tye McQueen (tye%spillman.UUCP@uunet.uu.net),
+ Matthew Green (mrg@mame.mu.oz.au),
+ Christopher Williams (cgw@unt.edu),
+ Matt Mosley (mattm@access.digex.net),
+ Gregory Neil Shapiro (gshapiro@wpi.WPI.EDU),
+ Jason Merrill (jason@jarthur.Claremont.EDU).
+
+Version
+=======
+
+ This manual describes version 3.9.0 of the `screen' program. Its
+roots are a merge of a custom version 2.3PR7 by Wayne Davison and
+several enhancements to Oliver Laumann's version 2.0. Note that all
+versions numbered 2.x are copyright by Oliver Laumann.
+
+ See also *Note Availability::.
+
+
+File: screen.info, Node: Bugs, Next: Installation, Prev: Credits, Up: Top
+
+Bugs
+****
+
+ Just like any other significant piece of software, `screen' has a
+few bugs and missing features. Please send in a bug report if you have
+found a bug not mentioned here.
+
+* Menu:
+
+* Known Bugs:: Problems we know about.
+* Reporting Bugs:: How to contact the maintainers.
+* Availability:: Where to find the lastest screen version.
+
+
+File: screen.info, Node: Known Bugs, Next: Reporting Bugs, Up: Bugs
+
+Known Bugs
+==========
+
+ * `dm' (delete mode) and `xs' are not handled correctly (they are
+ ignored). `xn' is treated as a magic-margin indicator.
+
+ * `screen' has no clue about double-high or double-wide characters.
+ But this is the only area where `vttest' is allowed to fail.
+
+ * It is not possible to change the environment variable `$TERMCAP'
+ when reattaching under a different terminal type.
+
+ * The support of terminfo based systems is very limited. Adding extra
+ capabilities to `$TERMCAP' may not have any effects.
+
+ * `screen' does not make use of hardware tabs.
+
+ * `screen' must be installed setuid root on most systems in order to
+ be able to correctly change the owner of the tty device file for
+ each window. Special permission may also be required to write the
+ file `/etc/utmp'.
+
+ * Entries in `/etc/utmp' are not removed when `screen' is killed
+ with SIGKILL. This will cause some programs (like "w" or "rwho")
+ to advertise that a user is logged on who really isn't.
+
+ * `screen' may give a strange warning when your tty has no utmp
+ entry.
+
+ * When the modem line was hung up, `screen' may not automatically
+ detach (or quit) unless the device driver sends a HANGUP signal.
+ To detach such a `screen' session use the -D or -d command line
+ option.
+
+ * If a password is set, the command line options -d and -D still
+ detach a session without asking.
+
+ * Both `breaktype' and `defbreaktype' change the break generating
+ method used by all terminal devices. The first should change a
+ window specific setting, where the latter should change only the
+ default for new windows.
+
+ * When attaching to a multiuser session, the user's `.screenrc' file
+ is not sourced. Each users personal settings have to be included
+ in the `.screenrc' file from which the session is booted, or have
+ to be changed manually.
+
+ * A weird imagination is most useful to gain full advantage of all
+ the features.
+
+
File: screen.info, Node: Reporting Bugs, Next: Availability, Prev: Known Bugs, Up: Bugs
Reporting Bugs
@@ -30,11 +779,11 @@ Reporting Bugs
Include the version number of `Screen' which you are using. Also
include in your message the hardware and operating system, the compiler
used to compile, a description of the bug behavior, and the conditions
-that triggered the bug. Please recompile `screen' with the `-DDEBUG
--DTMPTEST' options enabled, reproduce the bug, and have a look at the
-debug output written to the directory `/tmp/debug'. If necessary quote
-suspect passages from the debug output and show the contents of your
-`config.h' if it matters.
+that triggered the bug. Please recompile `screen' with the `-DDEBUG'
+options enabled, reproduce the bug, and have a look at the debug output
+written to the directory `/tmp/debug'. If necessary quote suspect
+passages from the debug output and show the contents of your `config.h'
+if it matters.

File: screen.info, Node: Availability, Prev: Reporting Bugs, Up: Bugs
@@ -46,9 +795,10 @@ Availability
The latest official release of `screen' available via anonymous ftp
from `prep.ai.mit.edu', `nic.funet.fi' or any other `GNU' distribution
-site. The latest beta testing release of `screen' is available from
-`ftp.uni-erlangen.de (131.188.1.43)', in the directory
-`pub/utilities/screen'.
+site. The home site of `screen' is `ftp.uni-erlangen.de
+(131.188.3.71)', in the directory `pub/utilities/screen'. The
+subdirectory `private' contains the latest beta testing release. If
+you want to help, send a note to screen@uni-erlangen.de.

File: screen.info, Node: Installation, Next: Concept Index, Prev: Bugs, Up: Top
@@ -76,7 +826,7 @@ Socket Directory
compile-time. If `screen' is installed setuid root, then the
administrator should compile screen with an adequate (not NFS mounted)
`SOCKDIR'. If `screen' is not running setuid-root, the user can specify
-any mode 777 directory in the environment variable `$SCREENDIR'.
+any mode 700 directory in the environment variable `$SCREENDIR'.

File: screen.info, Node: Compiling Screen, Prev: Socket Directory, Up: Installation
@@ -126,6 +876,7 @@ Concept Index
* bug report: Reporting Bugs.
* bugs: Bugs.
* capabilities: Special Capabilities.
+* command character: Command Character.
* command line options: Invoking Screen.
* command summary: Command Summary.
* compiling screen: Compiling Screen.
@@ -133,6 +884,7 @@ Concept Index
* copy and paste: Copy and Paste.
* customization: Customization.
* environment: Environment.
+* escape character: Command Character.
* files: Files.
* flow control: Flow Control.
* input translation: Input Translation.
@@ -145,11 +897,14 @@ Concept Index
* multiuser session: Multiuser Session.
* options: Invoking Screen.
* overview: Overview.
+* regions: Regions.
* screenrc: Startup Files.
* scrollback: Copy.
* socket directory: Socket Directory.
+* string escapes: String Escapes.
* terminal capabilities: Special Capabilities.
* title: Naming Windows.
+* window types: Window Types.

File: screen.info, Node: Command Index, Next: Keystroke Index, Prev: Concept Index, Up: Top
@@ -164,7 +919,10 @@ Command Index
* acladd: Acladd.
* aclchg: Aclchg.
* acldel: Acldel.
+* aclgrp: Aclgrp.
+* aclumask: Umask.
* activity: Monitor.
+* addacl: Acladd.
* allpartial: Redisplay.
* at: At.
* autodetach: Detach.
@@ -173,19 +931,25 @@ Command Index
* bind: Bind.
* bindkey: Bindkey.
* break: Break.
+* breaktype: Break.
* bufferfile: Screen-Exchange.
* c1: Character Processing.
+* caption: Caption.
+* caption: Caption.
+* chacl: Aclchg.
* charset: Character Processing.
* chdir: Chdir.
* clear: Clear.
* colon: Colon.
* command: Command Character.
+* compacthist: Scrollback.
* console: Console.
* copy: Copy.
* copy_reg: Registers.
* crlf: Line Termination.
* debug: Debug.
* defautonuke: Autonuke.
+* defbreaktype: Break.
* defc1: Character Processing.
* defcharset: Character Processing.
* defescape: Command Character.
@@ -198,24 +962,33 @@ Command Index
* defmonitor: Monitor.
* defobuflimit: Obuflimit.
* defscrollback: Scrollback.
+* defshell: Shell.
+* defsilence: Silence.
+* defslowpaste: Paste.
* defwrap: Wrap.
* defwritelock: Writelock.
* defzombie: Zombie.
* detach: Detach.
* digraph: Digraph.
+* displays: Displays.
* dumptermcap: Dump Termcap.
* echo: echo.
* escape: Command Character.
* exec: Exec.
+* fit: Window Size.
* flow: Flow.
+* focus: Focus.
* gr: Character Processing.
* hardcopy: Hardcopy.
* hardcopydir: Hardcopy.
* hardcopy_append: Hardcopy.
* hardstatus: Hardware Status Line.
+* hardstatus: Hardware Status Line.
+* hardstatus: Hardware Status Line.
* height: Window Size.
* help: Help.
* history: History.
+* hstatus: Hardstatus.
* info: Info.
* ins_reg: Registers.
* kanji: Character Processing.
@@ -225,7 +998,11 @@ Command Index
* lockscreen: Lock.
* log: Log.
* logfile: Log.
+* logfile: Log.
* login: Login.
+* logtstamp: Log.
+* logtstamp: Log.
+* logtstamp: Log.
* mapdefault: Bindkey Control.
* mapnotnext: Bindkey Control.
* maptimeout: Bindkey Control.
@@ -237,8 +1014,10 @@ Command Index
* multiuser: Multiuser.
* nethack: Nethack.
* next: Next and Previous.
+* nonblock: Nonblock.
* number: Number.
* obuflimit: Obuflimit.
+* only: Only.
* other: Other Window.
* partial: Redisplay.
* password: Detach.
@@ -255,6 +1034,7 @@ Command Index
* readreg: Paste.
* redisplay: Redisplay.
* register: Registers.
+* remove: Remove.
* removebuf: Screen-Exchange.
* reset: Reset.
* screen: Screen Command.
@@ -269,8 +1049,10 @@ Command Index
* sleep: sleep.
* slowpaste: Paste.
* sorendition: Sorendition.
+* split: Split.
* startup_message: Startup Message.
* stuff: Registers.
+* su: Su.
* suspend: Suspend.
* term: Term.
* termcap: Termcap Syntax.
@@ -278,10 +1060,12 @@ Command Index
* terminfo: Termcap Syntax.
* time: Time.
* title: Title Command.
+* umask: Umask.
* unsetenv: Setenv.
* vbell: Bell.
* vbellwait: Bell.
* vbell_msg: Bell.
+* verbose: Verbose.
* version: Version.
* wall: Wall.
* width: Window Size.
@@ -308,6 +1092,7 @@ omitted from the key sequences, since it is the same for all bindings.
* ": Select.
* ': Select.
+* *: Displays.
* .: Dump Termcap.
* 0...9: Select.
* :: Colon.
@@ -316,8 +1101,8 @@ omitted from the key sequences, since it is the same for all bindings.
* >: Screen-Exchange.
* ?: Help.
* {: History.
-* a: Command Character.
* A: Title Command.
+* a: Command Character.
* c: Screen Command.
* C: Clear.
* C-a: Other Window.
@@ -346,29 +1131,34 @@ omitted from the key sequences, since it is the same for all bindings.
* D: Power Detach.
* d: Detach.
* ESC: Copy.
+* F: Window Size.
* f: Flow.
* H: Log.
* h: Hardcopy.
* i: Info.
* k: Kill.
-* L: Login.
* l: Redisplay.
+* L: Login.
* m: Last Message.
* M: Monitor.
* N: Number.
* n: Next and Previous.
* p: Next and Previous.
* q: XON/XOFF.
+* Q: Only.
* r: Wrap.
+* S: Split.
* s: XON/XOFF.
* SPC: Next and Previous.
* t: Time.
+* TAB: Focus.
* v: Version.
* w: Windows.
* W: Window Size.
* x: Lock.
-* Z: Reset.
+* X: Remove.
* z: Suspend.
+* Z: Reset.
* [: Copy.
* ]: Paste.
diff --git a/doc/screen.info-5 b/doc/screen.info-5
new file mode 100644
index 0000000..e45ab2b
--- /dev/null
+++ b/doc/screen.info-5
@@ -0,0 +1,545 @@
+This is Info file screen.info, produced by Makeinfo-1.55 from the input
+file ./screen.texinfo.
+
+ This file documents the `Screen' virtual terminal manager.
+
+ Copyright (c) 1993-1995 Free Software Foundation, Inc.
+
+ Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+ Permission is granted to copy and distribute modified versions of
+this manual under the conditions for verbatim copying, provided that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+ Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be stated in a
+translation approved by the Foundation.
+
+
+File: screen.info, Node: Credits, Next: Bugs, Prev: Files, Up: Top
+
+Credits
+*******
+
+ Authors
+ =======
+
+ Originally created by Oliver Laumann, this
+latest version was produced by Wayne Davison, Juergen Weigert and
+Michael Schroeder.
+
+ Contributors
+ ============
+
+ Ken Beal (kbeal@amber.ssd.csd.harris.com),
+ Rudolf Koenig (rfkoenig@informatik.uni-erlangen.de),
+ Toerless Eckert (eckert@informatik.uni-erlangen.de),
+ Wayne Davison (davison@borland.com),
+ Patrick Wolfe (pat@kai.com, kailand!pat),
+ Bart Schaefer (schaefer@cse.ogi.edu),
+ Nathan Glasser (nathan@brokaw.lcs.mit.edu),
+ Larry W. Virden (lvirden@cas.org),
+ Howard Chu (hyc@hanauma.jpl.nasa.gov),
+ Tim MacKenzie (tym@dibbler.cs.monash.edu.au),
+ Markku Jarvinen (mta@{cc,cs,ee}.tut.fi),
+ Marc Boucher (marc@CAM.ORG),
+ Doug Siebert (dsiebert@isca.uiowa.edu),
+ Ken Stillson (stillson@tsfsrv.mitre.org),
+ Ian Frechett (frechett@spot.Colorado.EDU),
+ Brian Koehmstedt (bpk@gnu.ai.mit.edu),
+ Don Smith (djs6015@ultb.isc.rit.edu),
+ Frank van der Linden (vdlinden@fwi.uva.nl),
+ Martin Schweikert (schweik@cpp.ob.open.de),
+ David Vrona (dave@sashimi.lcu.com),
+ E. Tye McQueen (tye%spillman.UUCP@uunet.uu.net),
+ Matthew Green (mrg@mame.mu.oz.au),
+ Christopher Williams (cgw@unt.edu),
+ Matt Mosley (mattm@access.digex.net),
+ Gregory Neil Shapiro (gshapiro@wpi.WPI.EDU),
+ Jason Merrill (jason@jarthur.Claremont.EDU).
+
+ Version
+ =======
+
+ This manual describes version 3.8.0 of the
+`screen' program. Its roots are a merge of a custom version 2.3PR7 by
+Wayne Davison and several enhancements to Oliver Laumann's version 2.0.
+Note that all versions numbered 2.x are copyright by Oliver Laumann.
+
+ See also *Note Availability::.
+
+
+File: screen.info, Node: Bugs, Next: Installation, Prev: Credits, Up: Top
+
+Bugs
+****
+
+ Just like any other significant piece of
+software, `screen' has a few bugs and missing features. Please send in
+a bug report if you have found a bug not mentioned here.
+
+ * Menu:
+
+ * Known Bugs:: Problems we know about.
+ * Reporting Bugs:: How to contact the maintainers.
+ * Availability:: Where to find the lastest screen version.
+
+
+File: screen.info, Node: Known Bugs, Next: Reporting Bugs, Up: Bugs
+
+Known Bugs
+==========
+
+ * `dm' (delete mode) and `xs' are not handled
+ correctly (they are ignored). `xn' is treated
+ as a magic-margin indicator.
+
+ * `screen' has no clue about double-high or
+ double-wide characters. But this is the only
+ area where `vttest' is allowed to fail.
+
+ * It is not possible to change the environment
+ variable `$TERMCAP' when reattaching under a
+ different terminal type.
+
+ * The support of terminfo based systems is very
+ limited. Adding extra capabilities to
+ `$TERMCAP' may not have any effects.
+
+ * `screen' does not make use of hardware tabs.
+
+ * `screen' must be installed setuid root in
+ order to be able to correctly change the owner
+ of the tty device file for each window.
+ Special permission may also be required to
+ write the file `/etc/utmp'.
+
+ * Entries in `/etc/utmp' are not removed when
+ `screen' is killed with SIGKILL. This will
+ cause some programs (like "w" or "rwho") to
+ advertise that a user is logged on who really
+ isn't.
+
+ * `screen' may give a strange warning when your
+ tty has no utmp entry.
+
+ * When the modem line was hung up, `screen' may
+ not automatically detach (or quit) unless the
+ device driver sends a HANGUP signal. To detach
+ such a `screen' session use the -D or -d
+ command line option.
+
+ * If a password is set, the command line options
+ -d and -D still detach a session without
+ asking.
+
+ * Read permission on windows is never checked
+ for. All users that can attach to the session
+ can read window contents.
+
+ * Both `breaktype' and `defbreaktype' change the
+ break generating method used by all terminal
+ devices. The first should change a window
+ specific setting, where the latter should
+ change only the default for new windows.
+
+ * When attaching to a multiuser session, the
+ user's `.screenrc' file is not sourced. Each
+ users personal settings have to be included in
+ the `.screenrc' file from which the session is
+ booted, or have to be changed manually.
+
+ * A weird imagination is most useful to gain
+ full advantage of all the features.
+
+
+File: screen.info, Node: Reporting Bugs, Next: Availability, Prev: Known Bugs, Up: Bugs
+
+Reporting Bugs
+==============
+
+ If you find a bug in `Screen', please send
+electronic mail to `screen@uni-erlangen.de', and also to
+`bug-gnu-utils@prep.ai.mit.edu'. Include the version number of
+`Screen' which you are using. Also include in your message the
+hardware and operating system, the compiler used to compile, a
+description of the bug behavior, and the conditions that triggered the
+bug. Please recompile `screen' with the `-DDEBUG -DTMPTEST' options
+enabled, reproduce the bug, and have a look at the debug output written
+to the directory `/tmp/debug'. If necessary quote suspect passages from
+the debug output and show the contents of your `config.h' if it matters.
+
+
+File: screen.info, Node: Availability, Prev: Reporting Bugs, Up: Bugs
+
+Availability
+============
+
+ `Screen' is available under the `GNU' copyleft.
+
+ The latest official release of `screen'
+available via anonymous ftp from `prep.ai.mit.edu', `nic.funet.fi' or
+any other `GNU' distribution site. The home site of `screen' is
+`ftp.uni-erlangen.de (131.188.1.43)', in the directory
+`pub/utilities/screen'. The subdirectory `private' contains the latest
+beta testing release. If you want to help, send a note to
+screen@uni-erlangen.de.
+
+
+File: screen.info, Node: Installation, Next: Concept Index, Prev: Bugs, Up: Top
+
+Installation
+************
+
+ Since `screen' uses pseudo-ttys, the select
+system call, and UNIX-domain sockets/named pipes, it will not run under
+a system that does not include these features of 4.2 and 4.3 BSD UNIX.
+
+ * Menu:
+
+ * Socket Directory:: Where screen stores its handle.
+ * Compiling Screen::
+
+
+File: screen.info, Node: Socket Directory, Next: Compiling Screen, Up: Installation
+
+Socket Directory
+================
+
+ The socket directory defaults either to
+`$HOME/.screen' or simply to `/tmp/screens' or preferably to
+`/usr/local/screens' chosen at compile-time. If `screen' is installed
+setuid root, then the administrator should compile screen with an
+adequate (not NFS mounted) `SOCKDIR'. If `screen' is not running
+setuid-root, the user can specify any mode 700 directory in the
+environment variable `$SCREENDIR'.
+
+
+File: screen.info, Node: Compiling Screen, Prev: Socket Directory, Up: Installation
+
+Compiling Screen
+================
+
+ To compile and install screen:
+
+ The `screen' package comes with a `GNU Autoconf'
+configuration script. Before you compile the package run
+
+ `sh ./configure'
+
+ This will create a `config.h' and `Makefile' for
+your machine. If `configure' fails for some reason, then look at the
+examples and comments found in the `Makefile.in' and `config.h.in'
+templates. Rename `config.status' to `config.status.MACHINE' when you
+want to keep configuration data for multiple architectures. Running `sh
+./config.status.MACHINE' recreates your configuration significantly
+faster than rerunning `configure'.
+ Read through the "User Configuration" section of
+`config.h', and verify that it suits your needs. A comment near the
+top of this section explains why it's best to install screen setuid to
+root. Check for the place for the global `screenrc'-file and for the
+socket directory.
+ Check the compiler used in `Makefile', the prefix
+path where to install `screen'. Then run
+
+ `make'
+
+ If `make' fails to produce one of the files
+`term.h', `comm.h' or `tty.c', then use `FILENAME.X.dist' instead. For
+additional information about installation of `screen' refer to the file
+`INSTALLATION', coming with this package.
+
+
+File: screen.info, Node: Concept Index, Next: Command Index, Prev: Installation, Up: Top
+
+Concept Index
+*************
+
+ * Menu:
+
+ * .screenrc: Startup Files.
+ * availability: Availability.
+ * binding: Key Binding.
+ * bug report: Reporting Bugs.
+ * bugs: Bugs.
+ * capabilities: Special Capabilities.
+ * Command Character: Command Character.
+ * command line options: Invoking Screen.
+ * command summary: Command Summary.
+ * compiling screen: Compiling Screen.
+ * control sequences: Control Sequences.
+ * copy and paste: Copy and Paste.
+ * customization: Customization.
+ * environment: Environment.
+ * Escape Character: Command Character.
+ * files: Files.
+ * flow control: Flow Control.
+ * input translation: Input Translation.
+ * installation: Installation.
+ * introduction: Getting Started.
+ * invoking: Invoking Screen.
+ * key binding: Key Binding.
+ * marking: Copy.
+ * message line: Message Line.
+ * multiuser session: Multiuser Session.
+ * options: Invoking Screen.
+ * overview: Overview.
+ * regions: Regions.
+ * screenrc: Startup Files.
+ * scrollback: Copy.
+ * socket directory: Socket Directory.
+ * terminal capabilities: Special Capabilities.
+ * title: Naming Windows.
+
+
+File: screen.info, Node: Command Index, Next: Keystroke Index, Prev: Concept Index, Up: Top
+
+Command Index
+*************
+
+ This is a list of all the commands supported by
+`screen'.
+
+ * Menu:
+
+ * acladd: Acladd.
+ * aclchg: Aclchg.
+ * acldel: Acldel.
+ * aclgrp: Aclgrp.
+ * aclumask: Umask.
+ * activity: Monitor.
+ * addacl: Acladd.
+ * allpartial: Redisplay.
+ * at: At.
+ * autodetach: Detach.
+ * autonuke: Autonuke.
+ * bell_msg: Bell.
+ * bind: Bind.
+ * bindkey: Bindkey.
+ * break: Break.
+ * breaktype: Break.
+ * bufferfile: Screen-Exchange.
+ * c1: Character Processing.
+ * chacl: Aclchg.
+ * charset: Character Processing.
+ * chdir: Chdir.
+ * clear: Clear.
+ * colon: Colon.
+ * command: Command Character.
+ * console: Console.
+ * copy: Copy.
+ * copy_reg: Registers.
+ * crlf: Line Termination.
+ * debug: Debug.
+ * defautonuke: Autonuke.
+ * defbreaktype: Break.
+ * defc1: Character Processing.
+ * defcharset: Character Processing.
+ * defescape: Command Character.
+ * defflow: Flow.
+ * defgr: Character Processing.
+ * defhstatus: Hardstatus.
+ * defkanji: Character Processing.
+ * deflogin: Login.
+ * defmode: Mode.
+ * defmonitor: Monitor.
+ * defobuflimit: Obuflimit.
+ * defscrollback: Scrollback.
+ * defshell: Shell.
+ * defsilence: Silence.
+ * defslowpaste: Paste.
+ * defwrap: Wrap.
+ * defwritelock: Writelock.
+ * defzombie: Zombie.
+ * detach: Detach.
+ * digraph: Digraph.
+ * displays: Displays.
+ * dumptermcap: Dump Termcap.
+ * echo: echo.
+ * escape: Command Character.
+ * exec: Exec.
+ * flow: Flow.
+ * focus: Focus.
+ * gr: Character Processing.
+ * hardcopy: Hardcopy.
+ * hardcopydir: Hardcopy.
+ * hardcopy_append: Hardcopy.
+ * hardstatus: Hardware Status Line.
+ * height: Window Size.
+ * help: Help.
+ * history: History.
+ * info: Info.
+ * ins_reg: Registers.
+ * kanji: Character Processing.
+ * kill: Kill.
+ * lastmsg: Last Message.
+ * license: License.
+ * lockscreen: Lock.
+ * log: Log.
+ * logfile: Log.
+ * login: Login.
+ * mapdefault: Bindkey Control.
+ * mapnotnext: Bindkey Control.
+ * maptimeout: Bindkey Control.
+ * markkeys: Copy Mode Keys.
+ * meta: Command Character.
+ * monitor: Monitor.
+ * msgminwait: Message Wait.
+ * msgwait: Message Wait.
+ * multiuser: Multiuser.
+ * nethack: Nethack.
+ * next: Next and Previous.
+ * nonblock: Nonblock.
+ * number: Number.
+ * obuflimit: Obuflimit.
+ * one: One.
+ * other: Other Window.
+ * partial: Redisplay.
+ * password: Detach.
+ * paste: Paste.
+ * pastefont: Paste.
+ * pow_break: Break.
+ * pow_detach: Power Detach.
+ * pow_detach_msg: Power Detach.
+ * preselect: Select.
+ * prev: Next and Previous.
+ * printcmd: Printcmd.
+ * process: Registers.
+ * quit: Quit.
+ * readbuf: Screen-Exchange.
+ * readreg: Paste.
+ * redisplay: Redisplay.
+ * register: Registers.
+ * remove: Remove.
+ * removebuf: Screen-Exchange.
+ * reset: Reset.
+ * screen: Screen Command.
+ * scrollback: Scrollback.
+ * select: Select.
+ * sessionname: Session Name.
+ * setenv: Setenv.
+ * shell: Shell.
+ * shelltitle: Shell.
+ * silence: Silence.
+ * silencewait: Silence.
+ * sleep: sleep.
+ * slowpaste: Paste.
+ * sorendition: Sorendition.
+ * split: Split.
+ * startup_message: Startup Message.
+ * stuff: Registers.
+ * su: Su.
+ * suspend: Suspend.
+ * term: Term.
+ * termcap: Termcap Syntax.
+ * termcapinfo: Termcap Syntax.
+ * terminfo: Termcap Syntax.
+ * time: Time.
+ * title: Title Command.
+ * umask: Umask.
+ * unsetenv: Setenv.
+ * vbell: Bell.
+ * vbellwait: Bell.
+ * vbell_msg: Bell.
+ * verbose: Verbose.
+ * version: Version.
+ * wall: Wall.
+ * width: Window Size.
+ * windows: Windows.
+ * wrap: Wrap.
+ * writebuf: Screen-Exchange.
+ * writelock: Writelock.
+ * xoff: XON/XOFF.
+ * xon: XON/XOFF.
+ * zombie: Zombie.
+
+
+File: screen.info, Node: Keystroke Index, Prev: Command Index, Up: Top
+
+Keystroke Index
+***************
+
+ This is a list of the default key bindings.
+
+ The leading escape character (*note Command
+Character::.) has been omitted from the key sequences, since it is the
+same for all bindings.
+
+ * Menu:
+
+ * ": Select.
+ * ': Select.
+ * *: Displays.
+ * .: Dump Termcap.
+ * 0...9: Select.
+ * :: Colon.
+ * <: Screen-Exchange.
+ * =: Screen-Exchange.
+ * >: Screen-Exchange.
+ * ?: Help.
+ * {: History.
+ * A: Title Command.
+ * a: Command Character.
+ * C: Clear.
+ * c: Screen Command.
+ * C-a: Other Window.
+ * C-c: Screen Command.
+ * C-d: Detach.
+ * C-f: Flow.
+ * C-g: Bell.
+ * C-h: Hardcopy.
+ * C-i: Info.
+ * C-k: Kill.
+ * C-l: Redisplay.
+ * C-m: Last Message.
+ * C-n: Next and Previous.
+ * C-p: Next and Previous.
+ * C-q: XON/XOFF.
+ * C-r: Wrap.
+ * C-s: XON/XOFF.
+ * C-t: Time.
+ * C-v: Digraph.
+ * C-w: Windows.
+ * C-x: Lock.
+ * C-z: Suspend.
+ * C-[: Copy.
+ * C-\: Quit.
+ * C-]: Paste.
+ * d: Detach.
+ * D: Power Detach.
+ * ESC: Copy.
+ * F: Focus.
+ * f: Flow.
+ * h: Hardcopy.
+ * H: Log.
+ * i: Info.
+ * k: Kill.
+ * L: Login.
+ * l: Redisplay.
+ * M: Monitor.
+ * m: Last Message.
+ * n: Next and Previous.
+ * N: Number.
+ * p: Next and Previous.
+ * q: XON/XOFF.
+ * Q: One.
+ * r: Wrap.
+ * s: XON/XOFF.
+ * S: Split.
+ * SPC: Next and Previous.
+ * t: Time.
+ * v: Version.
+ * W: Window Size.
+ * w: Windows.
+ * x: Lock.
+ * X: Remove.
+ * z: Suspend.
+ * Z: Reset.
+ * [: Copy.
+ * ]: Paste.
+
+
diff --git a/doc/screen.texinfo b/doc/screen.texinfo
index a500018..1267d94 100644
--- a/doc/screen.texinfo
+++ b/doc/screen.texinfo
@@ -1,11 +1,12 @@
\input texinfo @c -*-texinfo-*-
@c %**start of header
+@c vi:set wm=5
@setfilename screen.info
@settitle Screen User's Manual
@finalout
@setchapternewpage odd
@c %**end of header
-@set version 3.7.0
+@set version 3.9.0
@c For examples, use a literal escape in info.
@ifinfo
@@ -18,7 +19,7 @@
@ifinfo
This file documents the @code{Screen} virtual terminal manager.
-Copyright (c) 1993 Free Software Foundation, Inc.
+Copyright (c) 1993-1995 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
@@ -46,11 +47,11 @@ by the Foundation.
@title Screen
@subtitle The virtual terminal manager
@subtitle for Version @value{version}
-@subtitle Oct 1995
+@subtitle Jul 1999
@page
@vskip 0pt plus 1filll
-Copyright @copyright{} 1993 Free Software Foundation, Inc.
+Copyright @copyright{} 1993-1995 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
@@ -83,8 +84,9 @@ This file documents the @code{Screen} virtual terminal manager, version
* Commands:: List all of the commands.
* New Window:: Running a program in a new window.
* Selecting:: Selecting a window to display.
-* Session Management:: Suspending or detaching a session.
-* Window Settings:: titles, logging, etc.
+* Session Management:: Suspend/detach, grant access, connect sessions.
+* Regions:: Split-screen commands.
+* Window Settings:: Titles, logging, etc.
* Virtual Terminal:: Controlling the @code{screen} VT100 emulation.
* Copy and Paste:: Exchanging text between windows and sessions.
* Subprocess Execution:: I/O filtering with @code{exec}.
@@ -95,6 +97,7 @@ This file documents the @code{Screen} virtual terminal manager, version
* Logging:: Keeping a record of your session.
* Startup:: Functions only useful at @code{screen} startup.
* Miscellaneous:: Various other commands.
+* String Escapes:: Inserting current information into strings
* Environment:: Environment variables used by @code{screen}.
* Files:: Files used by @code{screen}.
* Credits:: Who's who of @code{screen}.
@@ -112,7 +115,7 @@ This file documents the @code{Screen} virtual terminal manager, version
Screen is a full-screen window manager that multiplexes a physical
terminal between several processes, typically interactive shells. Each
virtual terminal provides the functions of the DEC VT100 terminal and,
-in addition, several control functions from the ANSI X3.64 (ISO 6429)
+in addition, several control functions from the ISO 6429 (ECMA 48, ANSI X3.64)
and ISO 2022 standards (e.g. insert/delete line and support for multiple
character sets). There is a scrollback history buffer for each virtual
terminal and a copy-and-paste mechanism that allows the user to move
@@ -127,7 +130,7 @@ windows, turn output logging on and off, copy text between windows, view
the scrollback history, switch between windows, etc. All windows run
their programs completely independent of each other. Programs continue
to run when their window is currently not visible and even when the
-whole screen session is detached from the users terminal.
+whole screen session is detached from the user's terminal.
When a program terminates, @code{screen} (per default) kills the window
that contained it. If this window was in the foreground, the display
@@ -143,6 +146,11 @@ Character}) and all the key bindings (@pxref{Key Binding}) can be fully
customized to be anything you like, though they are always two
characters in length.
+@code{Screen} does not understand the prefix @kbd{C-} to mean control.
+Please use the caret notation (@kbd{^A} instead of @kbd{C-a}) as arguments
+to e.g. the @code{escape} command or the @code{-e} option. @code{Screen}
+will also print out control characters in caret notation.
+
The standard way to create a new window is to type @kbd{C-a c}. This
creates a new window running a shell and switches to that window
immediately, regardless of the state of the process running in the
@@ -236,9 +244,28 @@ Do not start @code{screen}, but instead detach a @code{screen} session
running elsewhere (@pxref{Detach}). @samp{-d} has the same effect as
typing @kbd{C-a d} from the controlling terminal for the session.
@samp{-D} is the equivalent to the power detach key. If no session can
-be detached, this option is ignored. The combination @code{screen -D
--r} can be used to log out from a remote terminal and transport the
-session running there to your current terminal.
+be detached, this option is ignored. In combination with the
+@code{-r}/@code{-R} option more powerful effects can be achieved:
+
+@table @code
+@item -d -r
+Reattach a session and if necessary detach it first.
+@item -d -R
+Reattach a session and if necessary detach or even create it first.
+@item -d -RR
+Reattach a session and if necessary detach or create it.
+Use the first session if more than one session is available.
+@item -D -r
+Reattach a session. If necessary detach and logout remotely first.
+@item -D -R
+Attach here and now. In detail this means: If a session is running,
+then reattach. If necessary detach and logout remotely first. If it
+was not running create it and notify the user.
+This is the author's favorite.
+@item -D -RR
+Attach here and now. Whatever that means, just do it.
+@end table
+
@emph{Note}: It is a good idea to check the status of your sessions
with @code{screen -list} before using this option.
@@ -251,7 +278,7 @@ sets the default command caracter. In a multiuser session all users
added will start off with this command character. But when attaching
to an already running session, this option only changes the command
character of the attaching user.
-This option is equivalent to the commands @code{defescape} or
+This option is equivalent to the commands @code{defescape} or
@code{escape} respectively. (@pxref{Command Character}).
@item -f
@@ -276,15 +303,21 @@ Control}). Its use is discouraged.
Turn login mode on or off (for @file{/etc/utmp} updating). This option
is equivalent to the @code{deflogin} command (@pxref{Login}).
-@item -ls
-@itemx -list
+@item -ls [@var{match}]
+@itemx -list [@var{match}]
Do not start @code{screen}, but instead print a list of session
identification strings (usually of the form @var{pid.tty.host};
@pxref{Session Name}). Sessions marked @samp{detached} can be resumed
with @code{screen -r}. Those marked @samp{attached} are running and
-have a controlling terminal. Sessions marked as @samp{dead} should be
-thoroughly checked and removed. Ask your system administrator if you are
-not sure why they died. Remove sessions with the @samp{-wipe} option.
+have a controlling terminal. If the session runs in multiuser mode,
+it is marked @samp{multi}. Sessions marked as @samp{unreachable} either
+live on a different host or are dead.
+An unreachable session is considered dead, when its name matches either the
+name of the local host, or the specified parameter, if any.
+See the @code{-r} flag for a description how to construct matches.
+Sessions marked as @samp{dead} should be thoroughly checked and removed.
+Ask your system administrator if you are not sure.
+Remove sessions with the @samp{-wipe} option.
@item -L
Tell @code{screen} that your auto-margin terminal allows programs to
@@ -296,24 +329,46 @@ scrolling. This can also be set in your @file{.screenrc} by specifying
Tell @code{screen} to ignore the @code{$STY} environment variable. When
this option is used, a new session will always be created, regardless of
whether @code{screen} is being called from within another @code{screen}
-session or not.
+session or not. This flag has a special meaning in connection
+with the @samp{-d} option:
+@table @code
+@item -m -d
+Start @code{screen} in @emph{detached} mode. This creates a new
+session but doesn't attach to it. This is useful for system startup
+scripts.
+@item -m -D
+This also starts @code{screen} in @emph{detached} mode, but doesn't fork
+a new process. The command exits if the session terminates.
+@end table
+
+@item -q
+Suppress printing of error messages. In combination with @samp{-ls} the exit
+value is set as follows: 9 indicates a directory without sessions. 10
+indicates a directory with running but not attachable sessions. 11 (or more)
+indicates 1 (or more) usable sessions.
+In combination with @samp{-r} the exit value is as follows: 10 indicates that
+there is no session to resume. 12 (or more) indicates that there are 2 (or
+more) sessions to resume and you should specify which one to choose.
+In all other cases @samp{-q} has no effect.
@item -r [@var{pid.sessionname}]
@itemx -r @var{sessionowner/[pid.sessionname]}
Resume a detached @code{screen} session. No other options (except
-@samp{-d} or @samp{-D}) may be specified, though the session name
+combinations with @samp{-d} or @samp{-D}) may be specified, though
+the session name
(@pxref{Session Name}) may be needed to distinguish between multiple
detached @code{screen} sessions.
-The second form is used to connect to another users screen session which
-runs in multi-user mode. This indicates that screen should look for
-sessions in another users directory. This requires setuid-root.
+The second form is used to connect to another user's screen session which
+runs in multiuser mode. This indicates that screen should look for
+sessions in another user's directory. This requires setuid-root.
@item -R
Resume the first appropriate detached @code{screen} session. If
successful, all other command-line options are ignored. If no detached
session exists, start a new session using the specified options, just as
if @samp{-R} had not been specified. This option is set by default if
-screen is run as a login-shell.
+screen is run as a login-shell. For combinations with the
+@samp{-D}/@samp{-d} option see there.
@item -s @var{program}
Set the default shell to be @var{program}. By default, @code{screen}
@@ -336,9 +391,12 @@ This option is equivalent to the @code{shelltitle} command
@item -v
Print the version number.
-@item -wipe
+@item -wipe [@var{match}]
List available screens like @code{screen -ls}, but remove destroyed
-sessions instead of marking them as @samp{dead}.
+sessions instead of marking them as @samp{dead}.
+An unreachable session is considered dead, when its name matches either
+the name of the local host, or the explicitly given parameter, if any.
+See the @code{-r} flag for a description how to construct matches.
@item -x
Attach to a session which is already attached elsewhere (multi-display
@@ -452,13 +510,20 @@ The following table shows the default key bindings:
Prompt for a window identifier and switch.
@xref{Selecting}.
-@item @kbd{C-a 0@dots{}9}
-(select 0@dots{}select 9)@*
-Switch to window number 0@dots{}9. @xref{Selecting}.
+@item @kbd{C-a 0@dots{}9, -}
+(select 0@dots{}select 9, select -)@*
+Switch to window number 0@dots{}9, or the blank window.
+@xref{Selecting}.
+
+@item @kbd{C-a @key{Tab}}
+(focus)@*
+Switch the input focus to the next region. @xref{Regions}.
@item @kbd{C-a C-a}
(other)@*
-Toggle to the window displayed previously. @xref{Selecting}.
+Toggle to the window displayed previously. If this window does no
+longer exist, @code{other} has the same effect as @code{next}.
+@xref{Selecting}.
@item @kbd{C-a a}
(meta)@*
@@ -471,7 +536,7 @@ Allow the user to enter a title for the current window.
@xref{Naming Windows}.
@item @kbd{C-a b}
-itemx @kbd{C-a C-b}
+@itemx @kbd{C-a C-b}
(break)@*
Send a break to the tty.
@xref{Break}.
@@ -505,6 +570,10 @@ Detach and logout. @xref{Power Detach}.
(flow)@*
Cycle flow among @samp{on}, @samp{off} or @samp{auto}. @xref{Flow}.
+@item @kbd{C-a F}
+(fit)@*
+Resize the window to the current region size. @xref{Window Size}.
+
@item @kbd{C-a C-g}
(vbell)@*
Toggle visual bell mode. @xref{Bell}.
@@ -571,6 +640,10 @@ Switch to the previous window (opposite of @kbd{C-a n}).
(xon)@*
Send a ^Q (ASCII XON) to the current window. @xref{XON/XOFF}.
+@item @kbd{C-a Q}
+(only)@*
+Delete all regions but the current one. @xref{Regions}.
+
@item @kbd{C-a r}
@itemx @kbd{C-a C-r}
(wrap)@*
@@ -582,6 +655,10 @@ automatic margins on or off). @xref{Wrap}.
(xoff)@*
Send a ^S (ASCII XOFF) to the current window. @xref{XON/XOFF}.
+@item @kbd{C-a S}
+(split)@*
+Split the current region into two new ones. @xref{Regions}.
+
@item @kbd{C-a t}
@itemx @kbd{C-a C-t}
(time)@*
@@ -609,6 +686,10 @@ Toggle between 80 and 132 columns. @xref{Window Size}.
(lockscreen)@*
Lock your terminal. @xref{Lock}.
+@item @kbd{C-a X}
+(remove)@*
+Kill the current region. @xref{Regions}.
+
@item @kbd{C-a z}
@itemx @kbd{C-a C-z}
(suspend)@*
@@ -648,6 +729,7 @@ Write the contents of the paste buffer to the stdin queue of the
current window. @xref{Paste}.
@item @kbd{C-a @{}
+@itemx @kbd{C-a @}}
(history)@*
Copy and paste a previous (command) line. @xref{History}.
@@ -672,6 +754,10 @@ Start/stop monitoring the current window for inactivity. @xref{Silence},
@item @kbd{C-a ,}
(license)@*
Show the copyright page.
+
+@item @kbd{C-a *}
+(displays)@*
+Show the listing of attached displays.
@end table
@node Command Summary, , Default Key Bindings, Commands
@@ -685,8 +771,14 @@ Allow other users in this session. @xref{Multiuser Session}.
Change a user's permissions. @xref{Multiuser Session}.
@item acldel @var{username}
Disallow other user in this session. @xref{Multiuser Session}.
+@item aclgrp @var{usrname [groupname]}
+Inherit permissions granted to a group leader. @xref{Multiuser Session}.
+@item aclumask @var{[users]+\-bits ...}
+Predefine access to new windows. @xref{Umask}.
@item activity @var{message}
Set the activity notification message. @xref{Monitor}.
+@item addacl @var{usernames}
+Synonym to @code{acladd}. @xref{Multiuser Session}.
@item allpartial @var{state}
Set all windows to partial refresh. @xref{Redisplay}.
@item at @var{[ident][@kbd{#}@var{|}@kbd{*}@var{|}@kbd{%}] command [args]}
@@ -695,7 +787,7 @@ Execute a command at other displays or windows. @xref{At}.
Automatically detach the session on SIGHUP. @xref{Detach}.
@item autonuke @var{state}
Enable a clear screen to discard unwritten output. @xref{Autonuke}.
-@item bell_msg @var{message}
+@item bell_msg @var{[message]}
Set the bell notification message. @xref{Bell}.
@item bind @var{key [command [args]]}
Bind a command to a key. @xref{Bind}.
@@ -703,10 +795,16 @@ Bind a command to a key. @xref{Bind}.
Bind a string to a series of keystrokes. @xref{Bindkey}.
@item break @var{[duration]}
Send a break signal to the current window. @xref{Break}.
+@item breaktype @var{[tcsendbreak | TCSBRK | TIOCSBRK]}
+Specify how to generate breaks. @xref{Break}.
@item bufferfile @var{[exchange-file]}
Select a file for screen-exchange. @xref{Screen-Exchange}.
@item c1 @var{[state]}
Change c1 code processing. @xref{Character Processing}.
+@item caption @var{mode} @var{[string]}
+Change caption mode and string. @xref{Regions}.
+@item chacl @var{usernames permbits list}
+Synonym to @code{aclchg}. @xref{Multiuser Session}.
@item charset @var{set}
Change character set slot designation. @xref{Character Processing}.
@item chdir @var{[directory]}
@@ -717,6 +815,8 @@ Clear the window screen. @xref{Clear}.
Enter a @code{screen} command. @xref{Colon}.
@item command
Simulate the screen escape key. @xref{Command Character}.
+@item compacthist @var{[state]}
+Selects compaction of trailing empty lines. @xref{Scrollback}.
@item console @var{[state]}
Grab or ungrab console output. @xref{Console}.
@item copy
@@ -729,6 +829,8 @@ Select line break behavior for copying. @xref{Line Termination}.
Suppress/allow debugging output. @xref{Debug}.
@item defautonuke @var{state}
Select default autonuke behavior. @xref{Autonuke}.
+@item defbreaktype @var{[tcsendbreak | TCSBRK | TIOCSBRK]}
+Specify the default for generating breaks. @xref{Break}.
@item defc1 @var{state}
Select default c1 processing behavior. @xref{Character Processing}.
@item defcharset @var{[set]}
@@ -753,16 +855,24 @@ Select default activity monitoring behavior. @xref{Monitor}.
Select default output buffer limit. @xref{Obuflimit}.
@item defscrollback @var{num}
Set default lines of scrollback. @xref{Scrollback}.
+@item defshell @var{command}
+Set the default program for new windows. @xref{Shell}.
+@item defsilence @var{state}
+Select default idle monitoring behavior. @xref{Silence}.
+@item defslowpaste @var{msec}
+Select the default inter-character timeout when pasting. @xref{Paste}.
@item defwrap @var{state}
Set default line-wrapping behavior. @xref{Wrap}.
@item defwritelock @var{on|off|auto}
-Set default writelock behavior. @xref{Multiuser}.
+Set default writelock behavior. @xref{Multiuser Session}.
@item defzombie @var{[keys]}
Keep dead windows. @xref{Zombie}.
@item detach
Disconnect @code{screen} from the terminal. @xref{Detach}.
@item digraph
Enter digraph sequence. @xref{Digraph}.
+@item displays
+List currently active user interfaces. @xref{Displays}.
@item dumptermcap
Write the window's termcap entry to a file. @xref{Dump Termcap}.
@item echo [-n] @var{message}
@@ -771,8 +881,12 @@ Display a message on startup. @xref{Startup}.
Set the command and @code{meta} characters. @xref{Command Character}.
@item exec @var{[[fdpat] command [args ...]]}
Run a subprocess (filter). @xref{Exec}.
+@item fit
+Change window size to current display size. @xref{Window Size}.
@item flow @var{[fstate]}
Set flow control behavior. @xref{Flow}.
+@item focus
+Move focus to next region. @xref{Regions}.
@item gr @var{[state]}
Change GR charset processing. @xref{Character Processing}.
@item hardcopy
@@ -789,6 +903,8 @@ Set display height. @xref{Window Size}.
Display current key bindings. @xref{Help}.
@item history
Find previous command beginning @dots{}. @xref{History}.
+@item hstatus @var{status}
+Change the window's hardstatus line. @xref{Hardstatus}.
@item info
Display terminal settings. @xref{Info}.
@item ins_reg @var{[key]}
@@ -809,12 +925,14 @@ Log all output in the current window. @xref{Log}.
Place where to collect logfiles. @xref{Log}.
@item login @var{[state]}
Log the window in @file{/etc/utmp}. @xref{Login}.
+@item logtstamp @var{[state]}
+Configure logfile time-stamps. @xref{Log}.
@item mapdefault
Use only the default mapping table for the next keystroke. @xref{Bindkey Control}.
@item mapnotnext
Don't try to do keymapping on the next keystroke. @xref{Bindkey Control}.
@item maptimeout @var{timo}
-Set the intercharacter timeout used for keymapping. @xref{Bindkey Control}.
+Set the inter-character timeout used for keymapping. @xref{Bindkey Control}.
@item markkeys @var{string}
Rebind keys in copy mode. @xref{Copy Mode Keys}.
@item meta
@@ -831,10 +949,14 @@ Go into single or multi user mode. @xref{Multiuser Session}.
Use @code{nethack}-like error messages. @xref{Nethack}.
@item next
Switch to the next window. @xref{Selecting}.
+@item nonblock @var{state}
+Disable flow control to the current display. @xref{Nonblock}.
@item number @var{[n]}
Change/display the current window's number. @xref{Number}.
@item obuflimit @var{[limit]}
Select output buffer limit. @xref{Obuflimit}.
+@item only
+Kill all other regions. @xref{Regions}.
@item other
Switch to the window you were in last. @xref{Selecting}.
@item partial @var{state}
@@ -867,6 +989,8 @@ Load a register from paste buffer or file. @xref{Registers}.
Redisplay the current window. @xref{Redisplay}.
@item register @var{key string}
Store a string to a register. @xref{Registers}.
+@item remove
+Kill current region. @xref{Regions}.
@item removebuf
Delete the screen-exchange file. @xref{Screen-Exchange}.
@item reset
@@ -895,10 +1019,14 @@ Pause during startup. @xref{Startup}.
Slow down pasting in windows. @xref{Paste}.
@item sorendition @var{[attr [color]]}
Change text highlighting. @xref{Sorendition}.
+@item split
+Split region into two parts. @xref{Regions}.
@item startup_message @var{state}
Display copyright notice on startup. @xref{Startup}.
@item stuff @var{string}
Stuff a string in the input buffer of a window. @xref{Paste}.
+@item su @var{[username [password [password2]]]}
+Identify a user. @xref{Multiuser Session}.
@item suspend
Put session in background. @xref{Suspend}.
@item term @var{term}
@@ -913,6 +1041,8 @@ Ditto, for both systems. @xref{Termcap Syntax}.
Display time and load average. @xref{Time}.
@item title @var{[windowtitle]}
Set the name of the current window. @xref{Title Command}.
+@item umask @var{[users]+\-bits ...}
+Synonym to @code{aclumask}. @xref{Umask}.
@item unsetenv @var{var}
Unset environment variable for new windows. @xref{Setenv}.
@item vbell @var{[state]}
@@ -948,9 +1078,9 @@ Keep dead windows. @xref{Zombie}.
This section describes the commands for creating a new window for
running programs. When a new window is created, the first available
-number from the range 0@dots{}9 is assigned to it. There can be no more
-than 10 windows active at any one time unless @code{screen} was compiled
-with a higher MAXWIN setting.
+number from the range 0@dots{}9 is assigned to it.
+The number of windows is limited at compile-time by the MAXWIN
+configuration parameter.
@menu
* Chdir:: Change the working directory for new windows.
@@ -958,6 +1088,7 @@ with a higher MAXWIN setting.
* Setenv:: Set environment variables for new windows.
* Shell:: Parameters for shell windows.
* Term:: Set the terminal type for new windows.
+* Window Types:: Creating different types of windows.
@end menu
@node Chdir, Screen Command, , New Window
@@ -986,18 +1117,19 @@ affect all the windows you create interactively.
(@kbd{C-a c}, @kbd{C-a C-c})@*
Establish a new window. The flow-control options (@samp{-f}, @samp{-fn}
and @samp{-fa}), title option (@samp{-t}), login options
-(@samp{-l} and @samp{-ln}) , terminal type option (@samp{-T @var{term}})
-and scrollback option (@samp{-h @var{num}}) may be specified for each
-command. If an optional number @var{n} in the range 0@dots{}9 is given,
+(@samp{-l} and @samp{-ln}) , terminal type option (@samp{-T @var{term}}),
+the all-capability-flag (@samp{-a}) and scrollback option
+(@samp{-h @var{num}}) may be specified with each command.
+The option (@samp{-M}) turns monitoring on for this window.
+The option (@samp{-L}) turns output logging on for this window.
+If an optional number @var{n} in the range 0@dots{}9 is given,
the window number @var{n} is assigned to the newly created window (or,
if this number is already in-use, the next available number). If a
command is specified after @code{screen}, this command (with the given
arguments) is started in the window; otherwise, a shell is created.
-If a tty (character special device) name (e.g. @samp{/dev/ttyS0})
-is specified as cmd, then the window is directly connected to this
-device. This is similar to the cmd @samp{kermit -l /dev/ttyS0 -c} but
-saves resources and is more efficient.
+Screen has built in some functionality of @samp{cu} and @samp{telnet}.
+@xref{Window Types}.
@end deffn
Thus, if your @file{.screenrc} contains the lines
@@ -1005,13 +1137,14 @@ Thus, if your @file{.screenrc} contains the lines
@example
# example for .screenrc:
screen 1
-screen -fn -t foobar 2 telnet foobar
+screen -fn -t foobar 2 -L telnet foobar
@end example
@noindent
@code{screen} creates a shell window (in window #1) and a window with a
TELNET connection to the machine foobar (with no flow-control using the
-title @samp{foobar} in window #2). If you do not include any
+title @samp{foobar} in window #2) and will write a logfile @samp{screenlog.2}
+of the telnet session. If you do not include any
@code{screen} commands in your @file{.screenrc} file, then @code{screen}
defaults to creating a single shell window, number zero. When the
initialization is completed, @code{screen} switches to the last window
@@ -1036,12 +1169,15 @@ Unset an environment variable.
@node Shell, Term, Setenv, New Window
@section Shell
@deffn Command shell command
+@deffnx Command defshell command
(none)@*
Set the command to be used to create a new shell. This overrides the
value of the environment variable @code{$SHELL}. This is useful if
you'd like to run a tty-enhancer which is expecting to execute the
program specified in @code{$SHELL}. If the command begins with
a @samp{-} character, the shell will be started as a login-shell.
+
+@code{defshell} is currently a synonym to the @code{shell} command.
@end deffn
@deffn Command shelltitle title
@@ -1050,13 +1186,13 @@ Set the title for all shells created during startup or by the C-a C-c
command. @xref{Naming Windows}, for details about what titles are.
@end deffn
-@node Term, , Shell, New Window
+@node Term, Window Types , Shell, New Window
@section Term
@deffn Command term term
(none)@*
In each window @code{screen} opens, it sets the @code{$TERM}
-variable to @samp{screen} by default, unless no description for
-@samp{screen} is installed in the local termcap or terminfo data base.
+variable to @code{screen} by default, unless no description for
+@code{screen} is installed in the local termcap or terminfo data base.
In that case it pretends that the terminal emulator is @samp{vt100}.
This won't do much harm, as @code{screen} is VT100/ANSI compatible. The
use of the @code{term} command is discouraged for non-default purpose.
@@ -1066,6 +1202,106 @@ the next @code{screen rlogin othermachine} command. Use the command
and resetting the default.
@end deffn
+@node Window Types, , Term, New Window
+@section Window Types
+@cindex window types
+Screen provides three different window types. New windows are created
+with @code{screen}'s @samp{screen} command (@pxref{Screen Command}).
+The first parameter to the @samp{screen} command defines which
+type of window is created. The different window types are all
+special cases of the normal type. They have been added in order
+to allow @code{screen} to be used efficiently as a console
+with 100 or more windows.
+@itemize @bullet
+@item
+The normal window contains a shell (default, if no parameter is given)
+or any other system command that could be executed from a shell.
+(e.g. @samp{slogin}, etc...).
+
+@item
+If a tty (character special device) name (e.g. @samp{/dev/ttya})
+is specified as the first parameter, then the window is directly
+connected to this device.
+This window type is similar to @samp{screen cu -l /dev/ttya}.
+Read and write access is required on the device node,
+an exclusive open is attempted on the node to mark the connection line
+as busy.
+An optional parameter is allowed consisting of a comma separated
+list of flags in the notation used by @samp{stty(1)}:
+@table @code
+@item <baud_rate>
+Usually 300, 1200, 9600 or 19200. This affects transmission as well as
+receive speed.
+@item cs8 or cs7
+Specify the transmission of eight (or seven) bits per byte.
+@item ixon or -ixon
+Enables (or disables) software flow-control (CTRL-S/CTRL-Q) for sending
+data.
+@item ixoff or -ixoff
+Enables (or disables) software flow-control for receiving data.
+@item istrip or -istrip
+Clear (or keep) the eight bit in each received byte.
+@end table
+
+You may want to specify as many of these options as applicable.
+Unspecified options cause the terminal driver to make up the parameter
+values of the connection. These values are system dependant and may be
+in defaults or values saved from a previous connection.
+
+For tty windows, the @code{info} command shows some of the modem
+control lines in the status line.
+These may include @samp{RTS}, @samp{CTS}, @samp{DTR}, @samp{CD} and
+more. This depends rather on on the available @code{ioctl()}'s and system
+header files than on the physical capabilities of the serial board.
+The name of a logical low (inactive) signal is preceded by an
+exclamation mark (@samp{!}), otherwise the signal is logical high (active).
+Unsupported but shown signals are usually shown low.
+When the @code{CLOCAL} status bit is true, the whole set of modem signals is
+placed inside curly braces (@samp{@{} and @samp{@}}).
+When the @code{CRTSCTS} or @code{TIOCSOFTCAR} bit is true, the signals
+@samp{CTS} or @samp{CD} are shown in parenthesis, respectively.
+
+For tty windows, the command @code{break} causes the Data transmission
+line (TxD) to go low for a specified period of time. This is expected
+to be interpreted as break signal on the other side.
+No data is sent and no modem control line is changed when a
+@code{break} is issued.
+
+@item
+If the first parameter is @code{//telnet}, the second parameter is
+expected to be a host name, and an optional third parameter may specify
+a TCP port number (default decimal 23). Screen will connect to a
+server listening on the remote host and use the telnet protocol to
+communicate with that server.
+
+For telnet windows, the command @code{info} shows details about
+the connection in square brackets (@samp{[} and @samp{]}) at the end of
+the status line.
+@table @code
+@item b
+BINARY. The connection is in binary mode.
+@item e
+ECHO. Local echo is disabled.
+@item c
+SGA. The connection is in `character mode' (default: `line mode').
+@item t
+TTYPE. The terminal type has been requested by the remote host. Screen
+sends the name @code{screen} unless instructed otherwise (see also the
+command @samp{term}).
+@item w
+NAWS. The remote site is notified about window size changes.
+@item f
+LFLOW. The remote host will send flow control information.
+(Ignored at the moment.)
+@end table
+Additional flags for debugging are @samp{x}, @samp{t} and @samp{n}
+(XDISPLOC, TSPEED and NEWENV).
+
+For telnet windows, the command @code{break} sends the telnet code
+@code{IAC BREAK} (decimal 243) to the remote host.
+
+@end itemize
+
@node Selecting, Session Management, New Window, Top
@chapter Selecting a Window
@@ -1076,7 +1312,7 @@ in that order by default (@pxref{New Window}).
@menu
* Next and Previous:: Forward or back one window.
* Other Window:: Switch back and forth between two windows.
-* Select:: Specify a particular window.
+* Select:: Switch to a window (and to one after @code{kill}).
@end menu
@node Next and Previous, Other Window, , Selecting
@@ -1125,9 +1361,10 @@ is assigned to this window.
Thus, the first window can be activated by @code{select 0}; there
can be no more than 10 windows present simultaneously (unless screen is
compiled with a higher MAXWIN setting).
+The special command @code{select -} switches to a blank window.
@end deffn
-@node Session Management, Window Settings, Selecting, Top
+@node Session Management, Regions, Selecting, Top
@chapter Session Management Commands
Perhaps the most useful feature of @code{screen} is the way it allows
@@ -1234,8 +1471,12 @@ described here.
* Acladd:: Enable a specific user.
* Aclchg:: Change a users permissions.
* Acldel:: Disable a specific user.
+* Aclgrp:: Grant a user permissions to other users.
+* Displays:: List all active users at their displays.
+* Umask:: Predefine access to new windows.
* Wall:: Write a message to all users.
* Writelock:: Grant exclusive window access.
+* Su:: Substitute user.
@end menu
@node Multiuser, Acladd, , Multiuser Session
@@ -1251,22 +1492,26 @@ single-user. In multi-user mode the commands @code{acladd}, @code{aclchg} and
@node Acladd, Aclchg, Multiuser, Multiuser Session
@subsection Acladd
@deffn Command acladd @var{usernames}
+@deffnx Command addacl @var{usernames}
(none)@*
Enable users to fully access this screen session. @var{Usernames} can be one
-user or a comma seperated list of users. This command enables to attach to
+user or a comma separated list of users. This command enables to attach to
the @code{screen} session and performs the equivalent of
@code{aclchg @var{usernames} +rwx "#?"}. To add a user with restricted access,
-use the @code{aclchg} command below. Multi-user mode only.
+use the @code{aclchg} command below.
+@code{Addacl} is a synonym to @code{acladd}.
+Multi-user mode only.
@end deffn
@node Aclchg, Acldel, Acladd, Multiuser Session
@subsection Aclchg
@deffn Command aclchg @var{usernames permbits list}
+@deffnx Command chacl @var{usernames permbits list}
(none)@*
-Change permissions for a comma seperated list of users.
+Change permissions for a comma separated list of users.
Permission bits are represented as @samp{r}, @samp{w} and @samp{x}.
Prefixing @samp{+} grants the permission, @samp{-} removes it. The third
-parameter is a comma seperated list of commands or windows (specified either
+parameter is a comma separated list of commands or windows (specified either
by number or title). The special list @samp{#} refers to all windows, @samp{?}
to all commands. If @var{usernames} consists of a single @samp{*}, all
known users is affected.
@@ -1274,16 +1519,17 @@ A command can be executed when the user has the @samp{x} bit for it. The user
can type input to a window when he has its @samp{w} bit set and no other
user obtains a writelock for this window. Other bits are currently ignored.
To withdraw the writelock from another user in e.g. window 2:
-@samp{aclchg @var{username} -w+w 2}. To allow readonly access
+@samp{aclchg @var{username} -w+w 2}. To allow read-only access
to the session: @samp{aclchg @var{username} -w "#"}. As soon as a user's name
is known to screen, he can attach to the session and (per default) has full
permissions for all command and windows. Execution permission for the acl
commands, @code{at} and others should also be removed or the user may be able
to regain write permission.
+@code{Chacl} is a synonym to @code{aclchg}.
Multi-user mode only.
@end deffn
-@node Acldel, Wall, Aclchg, Multiuser Session
+@node Acldel, Aclgrp, Aclchg, Multiuser Session
@subsection Acldel
@deffn Command acldel @var{username}
(none)@*
@@ -1292,7 +1538,51 @@ user's displays are detached from the session. He cannot attach again.
Multi-user mode only.
@end deffn
-@node Wall, Writelock, Acldel, Multiuser Session
+@node Aclgrp, Displays, Acldel, Multiuser Session
+@subsection Aclgrp
+@deffn Command aclgrp @var{username [groupname]}
+(none)@*
+Creates groups of users that share common access rights. The
+name of the group is the username of the group leader. Each
+member of the group inherits the permissions that are
+granted to the group leader. That means, if a user fails an
+access check, another check is made for the group leader.
+A user is removed from all groups the special value @samp{none}
+is used for @var{groupname}. If the second parameter is omitted
+all groups the user is in are listed.
+@end deffn
+
+@node Displays, Umask, Aclgrp, Multiuser Session
+@subsection Displays
+@kindex *
+@deffn Command displays
+(@kbd{C-a *})@*
+Shows a tabular listing of all currently connected user
+front-ends (displays). This is most useful for multiuser
+sessions.
+@end deffn
+
+@node Umask, Wall, Displays, Multiuser Session
+@subsection aclumask
+@deffn Command aclumask @var{[[users]+bits |[users]-bits .... ]}
+@deffnx Command umask @var{[[users]+bits |[users]-bits .... ]}
+(none)@*
+This specifies the access other users have to windows that
+will be created by the caller of the command. @var{Users} may be no,
+one or a comma separated list of known usernames. If no users are
+specified, a list of all currently known users is assumed.
+@var{Bits} is any combination of access control bits allowed
+defined with the @code{aclchg} command. The special username @samp{?}
+predefines the access that not yet known users will be
+granted to any window initially. The special username @samp{??}
+predefines the access that not yet known users are granted
+to any command. Rights of the special username nobody cannot
+be changed (see the @code{su} command).
+@code{Umask} is a synonym to @code{aclumask}.
+@end deffn
+
+
+@node Wall, Writelock, Umask, Multiuser Session
@subsection Wall
@deffn Command wall @var{message}
(none)@*
@@ -1300,7 +1590,7 @@ Write a message to all displays. The message will appear in the terminal's
status line.
@end deffn
-@node Writelock, , Wall, Multiuser Session
+@node Writelock, Su , Wall, Multiuser Session
@subsection Writelock
@deffn Command writelock @var{on|off|auto}
(none)@*
@@ -1316,14 +1606,31 @@ to other windows.
@deffn Command defwritelock @var{on|off|auto}
(none)@*
-Sets the default writelock behaviour for new windows. Initially all windows
-will be created with automatic writelocks.
+Sets the default writelock behavior for new windows. Initially all windows
+will be created with no writelocks.
@end deffn
+@node Su, , Writelock, Multiuser Session
+@subsection Su
+@deffn Command su @var{[username [password [password2]]]}
+(none)@*
+Substitute the user of a display. The command prompts for
+all parameters that are omitted. If passwords are specified
+as parameters, they have to be specified un-crypted. The
+first password is matched against the systems passwd database,
+the second password is matched against the @code{screen}
+password as set with the commands @code{acladd} or @code{password}.
+@code{Su} may be useful for the @code{screen} administrator to test
+multiuser setups.
+When the identification fails, the user has
+access to the commands available for user @samp{nobody}. These are
+@code{detach}, @code{license}, @code{version}, @code{help} and
+@code{displays}.
+@end deffn
@node Session Name, Suspend, Multiuser Session, Session Management
@section Session Name
-@deffn Command sessionname [name]
+@deffn Command sessionname @var{[name]}
(none)@*
Rename the current session. Note that for @code{screen -list} the name
shows up with the process-id prepended. If the argument @var{name} is
@@ -1356,7 +1663,77 @@ bind command (as in @code{bind "^\"}) to remove a key binding
(@pxref{Key Binding}).
@end deffn
-@node Window Settings, Virtual Terminal, Session Management, Top
+@node Regions, Window Settings, Session Management, Top
+@chapter Regions
+@cindex regions
+Screen has the ability to display more than one window on the
+user's display. This is done by splitting the screen in regions,
+which can contain different windows.
+
+@menu
+* Split:: Split a region into two
+* Focus:: Change to the next region
+* Only:: Delete all other regions
+* Remove:: Delete the current region
+* Caption:: Control the window's caption
+@end menu
+
+@node Split, Focus, , Regions
+@section Split
+@kindex S
+@deffn Command split
+(@kbd{C-a S})@*
+Split the current region into two new ones. All regions on the
+display are resized to make room for the new region. The blank
+window is displayed on the new region.
+@end deffn
+
+@node Focus, Only, Split, Regions
+@section Focus
+@kindex TAB
+@deffn Command focus
+(@kbd{C-a @key{Tab}})@*
+Move the input focus to the next region. This is done in a cyclic
+way so that the top region is selected after the bottom one.
+@end deffn
+
+@node Only, Remove, Focus, Regions
+@section Only
+@kindex Q
+@deffn Command only
+(@kbd{C-a Q})@*
+Kill all regions but the current one.
+@end deffn
+
+@node Remove, Caption, Only, Regions
+@section Remove
+@kindex X
+@deffn Command remove
+(@kbd{C-a X})@*
+Kill the current region. This is a no-op if there is only one region.
+@end deffn
+
+@node Caption, , Remove, Regions
+@section Caption
+@deffn Command caption @code{always}|@code{splitonly} [string]
+@deffnx Command caption @code{string} [string]
+(none)@*
+This command controls the display of the window captions. Normally
+a caption is only used if more than one window is shown on the
+display (split screen mode). But if the type is set to
+@code{always}, @code{screen} shows a caption
+even if only one window is displayed. The default
+is @samp{splitonly}.
+
+The second form changes the text used for the caption. You can use
+all string escapes (@xref{String Escapes}). @code{Screen} uses
+a default of @samp{%3n %t}.
+
+You can mix both forms by providing the string as an additional
+argument.
+@end deffn
+
+@node Window Settings, Virtual Terminal, Regions, Top
@chapter Window Settings
These commands control the way @code{screen} treats individual windows
@@ -1533,7 +1910,7 @@ current window's title to @samp{(unknown)} (C-a u).
@section Console
@deffn Command console @var{[state]}
(none)@*
-Grabs or ungrabs the machines console output to a window. When the argument
+Grabs or un-grabs the machines console output to a window. When the argument
is omitted the current state is displayed.
@emph{Note}: Only the owner of @file{/dev/console} can grab the console
output. This command is only available if the host supports the ioctl
@@ -1551,8 +1928,9 @@ Kill the current window.@*
If there is an @code{exec} command running (@pxref{Exec}) then it is killed.
Otherwise the process (e.g. shell) running in the window receives a
@code{HANGUP} condition,
-the window structure is removed and screen switches to the previously
-displayed window. When the last window is destroyed, @code{screen} exits.
+the window structure is removed and screen (your display) switches to another
+window. When the last window is destroyed, @code{screen} exits.
+After a kill screen switches to the previously displayed window.
@*
@emph{Caution}: @code{emacs} users may find themselves killing their
@code{emacs} session when trying to delete the current line. For this
@@ -1590,7 +1968,7 @@ login off} will map these keys to be @kbd{C-a I} and @kbd{C-a O}
The mode of each newly allocated pseudo-tty is set to @var{mode}.
@var{mode} is an octal number as used by chmod(1). Defaults to 0622 for
windows which are logged in, 0600 for others (e.g. when @code{-ln} was
-specified for creation. @xref{Screen Command}).
+specified for creation. @pxref{Screen Command}).
@end deffn
@node Monitor, Windows, Mode, Window Settings
@@ -1603,11 +1981,11 @@ When any activity occurs in a background window that is being monitored,
notification message can be redefined by means of the @code{activity}
command. Each occurrence of @samp{%} in @var{message} is replaced by
the number of the window in which activity has occurred, and each
-occurrence of @samp{~} is replaced by the definition for bell in your
+occurrence of @samp{^G} is replaced by the definition for bell in your
termcap (usually an audible bell). The default message is
@example
-'Activity in window %'
+'Activity in window %n'
@end example
Note that monitoring is off for all windows by default, but can be altered
@@ -1639,14 +2017,19 @@ the window-status display (@pxref{Windows}). Monitoring defaults to
(@kbd{C-a w}, @kbd{C-a C-w})@*
Uses the message line to display a list of all the windows. Each
window is listed by number with the name of the program running in the
-window (or its title); the current window is marked with a @samp{*};
-the previous window is marked with a @samp{-}; all the windows that are
-logged in are marked with a @samp{$} (@pxref{Login}); a background
-window that has received a bell is marked with a @samp{!}; a background
-window that is being monitored and has had activity occur is marked with
-an @samp{@@} (@pxref{Monitor}); a window which has output logging turned
-on is marked with @samp{(L)}; windows occupied by other users are marked with
-@samp{&}; windows in the zombie state are marked with @samp{Z}.
+window (or its title).
+
+The current window is marked with a @samp{*};
+the previous window is marked with a @samp{-};
+all the windows that are logged in are marked with a @samp{$} (@pxref{Login});
+a background window that has received a bell is marked with a @samp{!};
+a background window that is being monitored and has had activity occur is
+marked with an @samp{@@} (@pxref{Monitor});
+a window which has output logging turned on is marked with @samp{(L)};
+windows occupied by other users are marked with @samp{&}
+or @samp{&&} if the window is shared by other users;
+windows in the zombie state are marked with @samp{Z}.
+
If this list is too long to fit on the terminal's status line only the
portion around the current window is displayed.
@end deffn
@@ -1656,14 +2039,13 @@ portion around the current window is displayed.
@code{Screen} maintains a hardstatus line for every window. If a window
gets selected, the display's hardstatus will be updated to match
-the window's hardstatus line. If the display has no hardstatus
-the line will be displayed as a standard screen message.
+the window's hardstatus line.
The hardstatus line can be changed with the ANSI Application
Program Command (APC): @samp{ESC_<string>ESC\}. As a convenience
for xterm users the sequence @samp{ESC]0..2;<string>^G} is
also accepted.
-@deffn Command defhstatus
+@deffn Command defhstatus [status]
(none)@*
The hardstatus line that all new windows will get is set to
@var{status}.
@@ -1671,18 +2053,23 @@ This command is useful to make the hardstatus of every window
display the window number or title or the like. @var{status}
may contain the same directives as in the window messages, but
the directive escape character is @samp{^E} (octal 005) instead
-of @samp{%}. This was done to make a misinterpretion of program
+of @samp{%}. This was done to make a misinterpretation of program
generated hardstatus lines impossible.
If the parameter @var{status}
is omitted, the current default string is displayed.
Per default the hardstatus line of new windows is empty.
@end deffn
+@deffn Command hstatus status
+(none)@*
+Changes the current window's hardstatus line to @var{status}.
+@end deffn
+
@node Virtual Terminal, Copy and Paste, Window Settings, Top
@chapter Virtual Terminal
Each window in a @code{screen} session emulates a VT100 terminal, with
-some extra functions added. The VT100 emulator is hardcoded, no other
+some extra functions added. The VT100 emulator is hard-coded, no other
terminal types can be emulated.
The commands described here modify the terminal emulation.
@@ -1746,7 +2133,7 @@ ESC ) Pcs (A) Designate character set as G1
ESC * Pcs (A) Designate character set as G2
ESC + Pcs (A) Designate character set as G3
ESC [ Pn ; Pn H Direct Cursor Addressing
-ESC [ Pn ; Pn f Direct Cursor Addressing
+ESC [ Pn ; Pn f same as above
ESC [ Pn J Erase in Display
Pn = None or 0 From Cursor to End of Screen
1 From Beginning of Screen to Cursor
@@ -1759,6 +2146,11 @@ ESC [ Pn A Cursor Up
ESC [ Pn B Cursor Down
ESC [ Pn C Cursor Right
ESC [ Pn D Cursor Left
+ESC [ Pn E Cursor next line
+ESC [ Pn F Cursor previous line
+ESC [ Pn G Cursor horizontal position
+ESC [ Pn ` same as above
+ESC [ Pn d Cursor vertical position
ESC [ Ps ;...; Ps m Select Graphic Rendition
Ps = None or 0 Default Rendition
1 Bold
@@ -1796,6 +2188,7 @@ ESC [ Pn @@ (A) Insert Character
ESC [ Pn P (A) Delete Character
ESC [ Pn S Scroll Scrolling Region Up
ESC [ Pn T Scroll Scrolling Region Down
+ESC [ Pn ^ same as above
ESC [ Ps ;...; Ps h Set Mode
ESC [ Ps ;...; Ps l Reset Mode
Ps = 4 (A) Insert Mode
@@ -1920,7 +2313,7 @@ two characters typed are looked up in a builtin table and the
resulting character is inserted in the input stream. For example,
if the user enters @samp{a"}, an a-umlaut will be inserted. If the
first character entered is a 0 (zero), @code{screen}
-will treat the following charcters (up to three) as an octal
+will treat the following characters (up to three) as an octal
number instead. The optional argument @var{preset}
is treated as user input, thus one can create an "umlaut" key.
For example the command @samp{bindkey ^K digraph '"'} enables the user
@@ -1934,30 +2327,31 @@ to generate an a-umlaut by typing @samp{CTRL-K a}.
(none)@*
When a bell character is sent to a background window, @code{screen}
displays a notification in the message line. The notification message
-can be re-defined by means of the @code{bell} command. Each occurrence
+can be re-defined by this command. Each occurrence
of @samp{%} in @var{message} is replaced by the number of the window to
-which a bell has been sent, and each occurrence of @samp{~} is replaced
+which a bell has been sent, and each occurrence of @samp{^G} is replaced
by the definition for bell in your termcap (usually an audible bell).
The default message is
@example
-'Bell in window %'
+'Bell in window %n'
@end example
An empty message can be supplied to the @code{bell_msg} command to suppress
output of a message line (@code{bell_msg ""}).
+Without parameter, the current message is shown.
@end deffn
@kindex C-g
@deffn Command vbell [state]
(@kbd{C-a C-g})@*
-Sets or toggles the visual bell setting for the current window. If
+Sets or toggles the visual bell setting for the current window. If
@code{vbell} is switched to @samp{on}, but your
terminal does not support a visual bell, the visual bell message is
-displayed in the status line when the bell character is received.
-Visual bell support of a terminal is
-defined by the termcap variable @code{vb}. @xref{Bell, , Visual Bell,
-termcap, The Termcap Manual}, for more information on visual bells.
+displayed in the status line when the bell character is received.
+Visual bell support of a terminal is
+defined by the termcap variable @code{vb}. @xref{Bell, , Visual Bell,
+termcap, The Termcap Manual}, for more information on visual bells.
The equivalent terminfo capability is @code{flash}.
Per default, @code{vbell} is @samp{off}, thus the audible bell is used.
@@ -1995,14 +2389,36 @@ Clears the screen and saves its contents to the scrollback buffer.
Uses the message line to display some information about the current
window: the cursor position in the form @samp{(@var{column},@var{row})}
starting with @samp{(1,1)}, the terminal width and height plus the size
-of the scrollback buffer in lines, like in @samp{(80,24)+50}, various
-flag settings (flow-control, insert mode, origin mode, wrap mode,
-application-keypad mode, output logging, activity monitoring, and redraw
-(@samp{+} indicates enabled, @samp{-} not)), the currently active
+of the scrollback buffer in lines, like in @samp{(80,24)+50},
+the current state of window XON/XOFF flow control is shown like this
+(see also @xref{Flow Control}):
+@example
+ +flow automatic flow control, currently on.
+ -flow automatic flow control, currently off.
+ +(+)flow flow control enabled. Agrees with automatic control.
+ -(+)flow flow control disabled. Disagrees with automatic control.
+ +(-)flow flow control enabled. Disagrees with automatic control.
+ -(-)flow flow control disabled. Agrees with automatic control.
+@end example
+
+The current line wrap setting (@samp{+wrap} indicates enabled, @samp{-wrap}
+not) is also shown. The flags @samp{ins}, @samp{org}, @samp{app}, @samp{log},
+@samp{mon} and @samp{nored} are displayed when the window is in insert mode,
+origin mode, application-keypad mode, has output logging,
+insert mode, origin mode, application-keypad mode, output logging,
+activity monitoring or partial redraw enabled.
+
+The currently active
character set (@samp{G0}, @samp{G1}, @samp{G2}, or @samp{G3}), and in
square brackets the terminal character sets that are currently
-designated as @samp{G0} through @samp{G3}. For system information use
-@code{time}.
+designated as @samp{G0} through @samp{G3}.
+Additional modes depending on the type of the window are displayed at
+the end of the status line (@pxref{Window Types}).
+
+If the state machine of the terminal emulator is in a non-default state,
+the info line is started with a string identifying the current state.
+
+For system information use @code{time}.
@end deffn
@node Redisplay, Wrap, Info, Virtual Terminal
@@ -2015,7 +2431,7 @@ This affects all windows and is useful for slow terminal lines. The
previous setting of full/partial refresh for each window is restored
with @code{allpartial off}. This is a global flag that immediately takes effect
on all windows overriding the @code{partial} settings. It does not change the
-default redraw behaviour of newly created windows.
+default redraw behavior of newly created windows.
@end deffn
@deffn Command partial state
@@ -2083,6 +2499,14 @@ Set the display height to a specified number of lines. When no
argument is given it toggles between 24 and 42 lines display.
@end deffn
+@kindex F
+@deffn Command fit
+(@kbd{C-a F})@*
+Change the window size to the size of the current region. This
+command is needed because screen doesn't adapt the window size
+automatically if the window is displayed more than once.
+@end deffn
+
@node Character Processing, ,Window Size, Virtual Terminal
@section Character Processing
@@ -2099,7 +2523,7 @@ c1 positions may want to turn this off.
@end deffn
@deffn Command gr [state]
(none)@*
-Turn GR charset switching on/off. Whenever screens sees an input
+Turn GR charset switching on/off. Whenever screen sees an input
char with an 8th bit set, it will use the charset stored in the
GR slot and print the character with the 8th bit stripped. The
default (see also @samp{defgr}) is not to process GR switching because
@@ -2221,9 +2645,16 @@ for new windows is changed. Defaults to 100.
@deffn Command scrollback num
(none)@*
-Set the size of the scrollback buffer for new windows to @var{num}
-lines. The default scrollback is 100 lines. Use @kbd{C-a i} to view
-the current setting.
+Set the size of the scrollback buffer for the current window to
+@var{num} lines. The default scrollback is 100 lines. Use @kbd{C-a i}
+to view the current setting.
+@end deffn
+
+@deffn Command compacthist [state]
+(none)@*
+This tells screen weather to suppress trailing blank lines when
+scrolling up text into the history buffer. Turn compacting @samp{on}
+to hold more useful lines in your scrollback buffer.
@end deffn
@node Copy Mode Keys, Movement, Scrollback, Copy
@@ -2238,7 +2669,7 @@ users.
If your terminal sends characters, that cause you to abort copy mode,
then this command may help by binding these characters to do nothing.
The no-op character is `@' and is used like this: @code{markkeys @@=L=H}
-if you do not want to use the `H' or `L' commands any longer.
+if you do not want to use the `H' or `L' commands any longer.
As shown in this example, multiple keys can be assigned to one function
in a single statement.
@end deffn
@@ -2349,10 +2780,11 @@ the paste buffer. Now try:@*
and notice the difference in the amount of text copied.
@noindent
-@kbd{J} joins lines. It toggles between 3 modes: lines separated by a
-newline character (012), lines glued seamless, or lines separated by a
-single space. Note that you can prepend the newline character with
-a carriage return character, by issuing a @code{set crlf on}.
+@kbd{J} joins lines. It toggles between 4 modes: lines separated by a
+newline character (012), lines glued seamless, lines separated by a single
+space or comma separated lines. Note that you can prepend the newline
+character with a carriage return character, by issuing a @code{set crlf
+on}.
@noindent
@kbd{v} is for all the @code{vi} users who use @code{:set numbers} - it
@@ -2419,13 +2851,16 @@ multi character fonts like kanji.
@end deffn
@deffn Command slowpaste msec
+@deffnx Command defslowpaste msec
(none)@*
-Define the speed text is inserted by the @code{paste} command.
-If the slowpaste value is nonzero text is written character by character.
+Define the speed text is inserted in the current window by the @code{paste}
+command. If the slowpaste value is nonzero text is written character by
+character.
@code{screen} will pause for @var{msec} milliseconds after each write
to allow the application to process the input. only use @code{slowpaste} if
your underlying system exposes flow control problems while pasting large
-amounts of text.
+amounts of text.
+@code{defslowpaste} specifies the default for new windows.
@end deffn
@deffn Command readreg [register [filename]]
@@ -2551,22 +2986,25 @@ Use with care!
(none)@*
Run a unix subprocess (specified by an executable path @var{newcommand} and
its optional arguments) in the current window. The flow of data between
-newcommand's stdin/stdout/stderr, the process already running (shell) and
+newcommands stdin/stdout/stderr, the process originally started (let us call it
+"application-process") and
screen itself (window) is controlled by the filedescriptor pattern @var{fdpat}.
This pattern is basically a three character sequence representing stdin, stdout
and stderr of newcommand. A dot (@code{.}) connects the file descriptor
to screen. An exclamation mark (@code{!}) causes the file descriptor to be
-connected to the already running process. A colon (@code{:}) combines both.
+connected to the application-process. A colon (@code{:}) combines both.
@*
-User input will go to newcommand unless newcommand requests the old process'
+User input will go to newcommand unless newcommand receives the
+application-process'
output (@var{fdpat}s first character is @samp{!} or @samp{:}) or a pipe symbol
(@samp{|}) is added to the end of @var{fdpat}.
@*
Invoking @code{exec} without arguments shows name and arguments of the currently
-running subprocess in this window.
+running subprocess in this window. Only one subprocess can be running per
+window.
@*
When a subprocess is running the @code{kill} command will affect it instead of
-the window's process.
+the windows process. Only one subprocess a time can be running in each window.
@*
Refer to the postscript file @file{doc/fdpat.ps} for a confusing
illustration of all 21 possible combinations. Each drawing shows the digits
@@ -2606,6 +3044,7 @@ Examples:
@item !/bin/sh
@itemx exec /bin/sh
@itemx exec ... /bin/sh
+All of the above are equivalent.
Creates another shell in the same window, while the original shell is still
running. Output of both shells is displayed and user input is sent to the new
@file{/bin/sh}.
@@ -2613,12 +3052,14 @@ running. Output of both shells is displayed and user input is sent to the new
@item !!stty 19200
@itemx exec!stty 19200
@itemx exec !.. stty 19200
-Set the speed of the window's tty. If your stty command operates on stdout, then
-add another @samp{!}. This is a useful command, when a screen window is
-directly connected to a serial line that needs to be configured.
+All of the above are equivalent.
+Set the speed of the window's tty. If your stty command operates on stdout,
+then add another @samp{!}. This is a useful command, when a screen window
+is directly connected to a serial line that needs to be configured.
@item |less
@itemx exec !..| less
+Both are equivalent.
This adds a pager to the window output. The special character @samp{|} is
needed to give the user control over the pager although it gets its input from
the window's process. This works, because @samp{less} listens on stderr
@@ -2688,17 +3129,20 @@ would bind the space key to the command that displays a list of windows
available as @kbd{C-a space}), bind @kbd{C-f} to the command
``create a window with a TELNET connection to foobar'', and bind
@key{ESC} to the command that creates an non-login window with title
-@samp{root} in slot #9, with a super-user shell and a scrollbackbuffer
+@samp{root} in slot #9, with a superuser shell and a scrollback buffer
of 1000 lines.
@node Command Character, Help, Bind Examples, Key Binding
+@cindex escape character
+@cindex command character
@section Command Character
@deffn Command escape xy
(none)@*
Set the command character to @var{x} and the character generating a
-literal command character to @var{y} (just like with the @samp{-e}
-option). Each argument is either a single character, a two-character
+literal command character (by triggering the @code{meta} command)
+to @var{y} (similar to the @samp{-e} option).
+Each argument is either a single character, a two-character
sequence of the form @samp{^x} (meaning @kbd{C-x}), a backslash followed
by an octal number (specifying the ASCII code of the character), or a
backslash followed by a second character, such as @samp{\^} or
@@ -2708,10 +3152,10 @@ one of the authors.
@deffn Command defescape xy
(none)@*
-Set the default command characters. This is equivalent to the command
-@code{escape} except that it is useful for multiuser sessions only.
+Set the default command characters. This is equivalent to the command
+@code{escape} except that it is useful for multiuser sessions only.
In a multiuser session
-@code{escape} changes the command character of the calling user, where
+@code{escape} changes the command character of the calling user, where
@code{defescape} changes the default command characters for users that
will be added later.
@end deffn
@@ -2771,12 +3215,12 @@ Such keys have two entries in the translation table. You can
select the application mode entry by specifying the @samp{-a}
option.
-The @samp{-t} option tells screen not to do intercharacter
-timing. One cannot turn off the timing if a termcap capabilty is
+The @samp{-t} option tells screen not to do inter-character
+timing. One cannot turn off the timing if a termcap capability is
used.
@samp{cmd} can be any of screen's commands with an arbitrary
-number of @samp{args}. If @samp{cmd} is omitted the keybinding is
+number of @samp{args}. If @samp{cmd} is omitted the key-binding is
removed from the table.
@end deffn
@@ -2802,14 +3246,14 @@ Make the "F1" key switch to window one.
bindkey -t foo stuff barfoo
@end example
@noindent
-Make @samp{foo} an abrevation of the word @samp{barfoo}. Timeout is
+Make @samp{foo} an abbreviation of the word @samp{barfoo}. Timeout is
disabled so that users can type slowly.
@example
bindkey "\024" mapdefault
@end example
@noindent
-This keybinding makes @samp{C-t} an escape character for keybindings. If
+This key-binding makes @samp{C-t} an escape character for key-bindings. If
you did the above @samp{stuff barfoo} binding, you can enter the word
@samp{foo} by typing @samp{C-t foo}. If you want to insert a
@samp{C-t} you have to press the key twice (i.e. escape the escape
@@ -2975,7 +3419,7 @@ terminfo this method fails. Because of this @code{screen} offers a way
to deal with these cases. Here is how it works:
When @code{screen} tries to figure out a terminal name for itself, it
-first looks for an entry named @samp{screen.@var{term}}, where
+first looks for an entry named @code{screen.@var{term}}, where
@var{term} is the contents of your @code{$TERM} variable. If no such entry
exists, @code{screen} tries @samp{screen} (or @samp{screen-w}, if the
terminal is wide (132 cols or more)). If even this entry cannot be
@@ -3041,7 +3485,8 @@ connected to the terminal, while all other windows are still active (the
printer port is enabled and disabled again for each chunk of output).
As a side-effect, programs running in different windows can send output
to the printer simultaneously. Data sent to the printer is not
-displayed in the window.
+displayed in the window. The @code{info} command displays a line starting
+with @samp{PRIN} while the printer is active.
Some capabilities are only put into the @code{$TERMCAP} variable of the virtual
terminal if they can be efficiently implemented by the physical
@@ -3077,16 +3522,16 @@ to run a converter like @code{captoinfo} and then compile the entry with
Use this command to modify your terminal's termcap entry without going
through all the hassles involved in creating a custom termcap entry.
Plus, you can optionally customize the termcap generated for the
-windows.
-You have to place these commands in one of the screenrc starup files, as
-they are meaningless once the terminal emulator is booted.
+windows.
+You have to place these commands in one of the screenrc startup files, as they
+are meaningless once the terminal emulator is booted.
-If your system uses the terminfo database rather than
-termcap, @code{screen} will understand the @code{terminfo} command which
-has the same effects as the @code{termcap} command. Two separate commands are
+If your system uses the terminfo database rather than termcap,
+@code{screen} will understand the @code{terminfo} command, which has the
+same effects as the @code{termcap} command. Two separate commands are
provided, as there are subtle syntactic differences, e.g. when parameter
interpolation (using @samp{%}) is required. Note that the termcap names of
-the capabilities have to be used with the @code{terminfo} command.
+the capabilities should also be used with the @code{terminfo} command.
In many cases, where the arguments are valid in both terminfo and termcap
syntax, you can use the command @code{termcapinfo}, which is just a
@@ -3223,11 +3668,11 @@ the @samp{ac} capability for more details.
@item CS
(str)@*
-Switch cursor keys to application mode.
+Switch cursor-keys to application mode.
@item CE
(str)@*
-Switch cursor keys to cursor mode.
+Switch cursor-keys to cursor mode.
@item AN
(bool)@*
@@ -3246,7 +3691,7 @@ Set the kanji type of the terminal. Valid strings are @samp{jis},
@item AF
(str)@*
-Change character forground color in an ANSI conform way. This
+Change character foreground color in an ANSI conform way. This
capability will almost always be set to @samp{\E[3%dm}
(@samp{\E[3%p1%dm} on terminfo machines).
@@ -3262,6 +3707,10 @@ Does understand ANSI set default fg/bg color (@samp{\E[39m / \E[49m}).
(str)@*
Describe a translation of characters to strings depending on the
current font. (@pxref{Character Translation}).
+
+@item TF
+(bool)@*
+Add missing capabilities to the termcap/info entry. (Set by default).
@end table
@node Autonuke, Obuflimit, Special Capabilities, Termcap
@@ -3324,7 +3773,7 @@ in font @var{<designator>} (@samp{B}: Ascii, @samp{A}: UK,
to strings. Every @var{<mapping>} describes to what string a single
character will be translated. A template mechanism is used, as
most of the time the codes have a lot in common (for example
-strings to switch to and from another charset). Each occurence
+strings to switch to and from another charset). Each occurrence
of @samp{%} in @var{<template>} gets substituted with the
@var{template-arg}
specified together with the character. If your strings are not
@@ -3352,7 +3801,7 @@ translates the unquoted @samp{%} char, it will be sent to the terminal
whenever screen switches to the corresponding @var{<designator>}.
In this
special case the template is assumed to be just @samp{%} because
-the charset switch sequence and the character mappings normaly
+the charset switch sequence and the character mappings normally
haven't much in common.
This example shows one use of the extension:
@@ -3404,13 +3853,37 @@ up-arrow.
@node Hardware Status Line, Last Message, Privacy Message, Message Line
@section Hardware Status Line
@deffn Command hardstatus [state]
+@deffnx Command hardstatus [@code{always}]@code{lastline}|@code{message}|@code{ignore} [string]
+@deffnx Command hardstatus @code{string} [string]
(none)@*
-Toggles the use of the terminal's hardware status line. If @samp{on},
-@code{screen} will use this facility to display one line messages.
-Otherwise these messages are overlayed in reverse video mode at the
-display line. Note that the hardstatus feature can only be used if the
-termcap/terminfo capabilities "hs", "ts", "fs" and "ds" are set
-properly. Default is @samp{on} whenever the "hs" capability is present.
+This command configures the use and emulation of the terminal's
+hardstatus line. The first form toggles whether @code{screen}
+will use the hardware status line to display messages. If the
+flag is set to @samp{off}, these messages
+are overlaid in reverse video mode at the display line. The default
+setting is @samp{on}.
+
+The second form tells screen what to do if the terminal doesn't
+have a hardstatus line (i.e. the termcap/terminfo capabilities
+"hs", "ts", "fs" and "ds" are not set). If the type
+@code{lastline} is used, screen will reserve the last line of the
+display for the hardstatus. @code{message} uses
+@code{screen}'s message mechanism and
+@code{ignore} tells @code{screen} never to display the hardstatus.
+If you prepend the word @code{always} to the type, @code{screen} will use
+the type even if the terminal supports a hardstatus line.
+
+The third form specifies the contents of the hardstatus line.
+@code{%h} is used as default string, i.e. the stored hardstatus of the
+current window (settable via @samp{\E]0;^G} or @samp{\E_\\}) is
+displayed.
+You can customize this to any string you like including
+string escapes (@xref{String Escapes}).
+If you leave
+out the argument @var{string}, the current string is displayed.
+
+You can mix the second and third form by providing the string as
+additional argument.
@end deffn
@node Last Message, Message Wait, Hardware Status Line, Message Line
@@ -3479,7 +3952,7 @@ directory.
@kindex H
@deffn Command log [state]
(@kbd{C-a H})@*
-Begins/ends logging of the current window to the file
+Begins/ends logging of the current window to the file
@file{screenlog.@var{n}} in the window's default directory, where
@var{n} is the number of the current window.
This filename can be changed with the @samp{logfile} command.
@@ -3491,8 +3964,27 @@ included in the session log. Default is @samp{off}.
@end deffn
@deffn Command logfile filename
+@deffnx Command logfile flush secs
(none)@*
Defines the name the logfiles will get. The default is @samp{screenlog.%n}.
+The second form changes the number of seconds @code{screen}
+will wait before flushing the logfile buffer to the file-system. The
+default value is 10 seconds.
+@end deffn
+
+@deffn Command logtstamp [state]
+@deffnx Command logtstamp @code{after} secs
+@deffnx Command logtstamp @code{string} string
+(none)@*
+This command controls logfile time-stamp mechanism of screen. If
+time-stamps are turned @samp{on}, screen adds a string containing
+the current time to the logfile after two minutes of inactivity.
+When output continues and more than another two minutes have passed,
+a second time-stamp is added to document the restart of the
+output. You can change this timeout with the second form
+of the command. The third form is used for customizing the time-stamp
+string (@samp{-- %n:%t -- time-stamp -- %M/%d/%y %c:%s --\n} by
+default).
@end deffn
@node Startup, Miscellaneous, Logging, Top
@@ -3509,12 +4001,12 @@ This section describes commands which are only useful in the
@node echo, sleep, , Startup
@section echo
-@deffn Command echo [@t{-n}] message
+@deffn Command echo [@samp{-n}] message
(none)@*
The echo command may be used to annoy @code{screen} users with a
-'message of the day'. Typically installed in a global screenrc.
+'message of the day'. Typically installed in a global screenrc.
The option @samp{-n} may be used to suppress the line feed.
-See also @code{sleep}.
+See also @code{sleep}.
Echo is also useful for online checking of environment variables.
@end deffn
@@ -3535,7 +4027,7 @@ Select whether you want to see the copyright notice during startup.
Default is @samp{on}, as you probably noticed.
@end deffn
-@node Miscellaneous, Environment, Startup, Top
+@node Miscellaneous, String Escapes, Startup, Top
@chapter Miscellaneous commands
The commands described here do not fit well under any of the other
@@ -3547,9 +4039,11 @@ categories.
* Debug:: Suppress/allow debugging output.
* License:: Display the disclaimer page.
* Nethack:: Use @code{nethack}-like error messages.
+* Nonblock:: Disable flow-control to a display.
* Number:: Change the current window's number.
* Silence:: Notify on inactivity.
* Time:: Display the time and load average.
+* Verbose:: Display window creation commands.
* Version:: Display the version of @code{screen}.
* Zombie:: Keep dead windows.
* Printcmd:: Set command for VT100 printer port emulation.
@@ -3573,8 +4067,21 @@ If @var{identifier} has a @code{#} or nothing appended it is matched against
window numbers and titles. Omitting an identifier in front of the @code{#},
@code{*} or @code{%} character selects all users, displays or windows because
a prefix-match is performed. Note that on the affected display(s) a short
-message will describe what happened. Caution: Permission is checked for the
-owners or the affected display(s), not for the initiator of the `at' command.
+message will describe what happened.
+Note that the @code{#} character works as a comment introducer when it is
+preceded by whitespace. This can be escaped by prefixing @code{#} with a
+@code{\}.
+Permission is checked for the initiator of the @code{at} command, not for the
+owners of the affected display(s).
+Caveat:
+When matching against windows, the command is executed at least
+once per window. Commands that change the internal arrangement of windows
+(like @code{other}) may be called again. In shared windows the command will
+be repeated for each attached display. Beware, when issuing toggle commands
+like @code{login}!
+Some commands (e.g. @code{stuff}, @code{\*Qprocess} or @code{paste}) require
+that a display is associated with the target windows. These commands may not
+work correctly under @code{at} looping over windows.
@end deffn
@node Break, Debug, At, Miscellaneous
@@ -3582,8 +4089,10 @@ owners or the affected display(s), not for the initiator of the `at' command.
@deffn Command break [duration]
(none)@*
Send a break signal for @var{duration}*0.25 seconds to this window.
+For non-Posix systems the time interval is rounded up to full seconds.
Most useful if a character device is attached to the window rather than
-a shell process.
+a shell process (@pxref{Window Types}). The maximum duration of
+a break signal is limited to 15 seconds.
@end deffn
@deffn Command pow_break
@@ -3591,6 +4100,29 @@ a shell process.
Reopen the window's terminal line and send a break condition.
@end deffn
+@deffn Command breaktype [tcsendbreak|TIOCSBRK|TCSBRK]
+(none)@*
+Choose one of the available methods of generating a break signal for
+terminal devices. This command should affect the current window only.
+But it still behaves identical to @code{defbreaktype}. This will be changed in
+the future.
+Calling @code{breaktype} with no parameter displays the break setting for the
+current window.
+@end deffn
+
+@deffn Command defbreaktype [tcsendbreak|TIOCSBRK|TCSBRK]
+(none)@*
+Choose one of the available methods of generating a break signal for
+terminal devices opened afterwards. The preferred methods are
+@code{tcsendbreak} and
+@code{TIOCSBRK}. The third, @code{TCSBRK}, blocks the complete @code{screen}
+session for the duration of the break, but it may be the only way to
+generate long breaks. @code{tcsendbreak} and @code{TIOCSBRK} may or may not
+produce long breaks with spikes (e.g. 4 per second). This is not only system
+dependant, this also differs between serial board drivers.
+Calling @code{defbreaktype} with no parameter displays the current setting.
+@end deffn
+
@node Debug, License, Break, Miscellaneous
@section Debug
@deffn Command debug [on|off]
@@ -3598,7 +4130,8 @@ Reopen the window's terminal line and send a break condition.
Turns runtime debugging on or off. If @code{screen} has been compiled with
option @code{-DDEBUG} debugging is available and is turned on per default.
Note that this command only affects debugging output from the main
-@samp{SCREEN} process.
+@samp{SCREEN} process correctly. Debug output from attacher processes can only
+be turned off once and forever.
@end deffn
@node License, Nethack, Debug, Miscellaneous
@@ -3609,7 +4142,7 @@ Display the disclaimer page. This is done whenever @code{screen} is
started without options, which should be often enough.
@end deffn
-@node Nethack, Number, License, Miscellaneous
+@node Nethack, Nonblock, License, Miscellaneous
@section Nethack
@deffn Command nethack state
(none)@*
@@ -3624,7 +4157,17 @@ determined by the presence of the environment variable
@code{$NETHACKOPTIONS}.
@end deffn
-@node Number, Silence, Nethack, Miscellaneous
+@node Nonblock, Number, Nethack, Miscellaneous
+@section Nonblock
+@deffn Command nonblock @var{state}
+Enable or disable flow control for the current user interface
+(display). It is used to prevent a slow display from slowing
+down the processing of data output by a window. This command
+may be helpful when multiple displays show the same window.
+@code{Nonblock} is initially off for all displays.
+@end deffn
+
+@node Number, Silence, Nonblock, Miscellaneous
@section Number
@kindex N
@deffn Command number @var{[n]}
@@ -3646,13 +4189,19 @@ of inactivity (silence). The default timeout can be changed with the
@code{on} or @code{off}. Silence is initially off for all windows.
@end deffn
+@deffn Command defsilence state
+(none)@*
+Same as the @code{silence} command except that the default setting for
+new windows is changed. Initial setting is `off'.
+@end deffn
+
@deffn Command silencewait @var{seconds}
(none)@*
Define the time that all windows monitored for silence should wait
before displaying a message. Default is 30 seconds.
@end deffn
-@node Time, Version, Silence, Miscellaneous
+@node Time, Verbose, Silence, Miscellaneous
@section Time
@kindex t
@kindex C-t
@@ -3663,7 +4212,15 @@ load averages over 1, 5, and 15 minutes (if this is available on your
system). For window-specific information use @code{info} (@pxref{Info}).
@end deffn
-@node Version, Zombie, Time, Miscellaneous
+@node Verbose, Version, Time, Miscellaneous
+@section Verbose
+@deffn Command verbose [on|off]
+If verbose is switched on, the command name is echoed, whenever a window
+is created (or resurrected from zombie state). Default is off.
+Without parameter, the current setting is shown.
+@end deffn
+
+@node Version, Zombie, Verbose, Miscellaneous
@section Version
@kindex v
@deffn Command version
@@ -3673,13 +4230,13 @@ Display the version and modification date in the message line.
@node Zombie, Printcmd, Version, Miscellaneous
@section Zombie
-@deffn Command zombie @var{[keyx]}
-@deffnx Command defzombie @var{[keyx]}
+@deffn Command zombie @var{[keys]}
+@deffnx Command defzombie @var{[keys]}
(none)@*
Per default windows are removed from the window list as soon as the
windows process (e.g. shell) exits. When a string of two keys is
specified to the zombie command, `dead' windows will remain in the list.
-The @code{kill} kommand may be used to remove the window. Pressing the first key
+The @code{kill} command may be used to remove the window. Pressing the first key
in the dead window has the same effect. Pressing the second key, however,
screen will attempt to resurrect the window. The process that was initially
running in the window will be launched again. Calling @code{zombie} without
@@ -3716,13 +4273,73 @@ messages.
@var{attr} is a hexadecimal number and describes the attributes
(inverse, underline, ...) the text will get. @var{color}
is a 2 digit number and changes the
-forground/background of the highlighted text.
+foreground/background of the highlighted text.
Some knowledge of screen's internal character representation is
needed to make the characters appear in the desired way. The default
is currently @samp{10 99} (standout, default colors).
@end deffn
-@node Environment, Files, Miscellaneous, Top
+@node String Escapes, Environment, Miscellaneous, Top
+@chapter String Escapes
+@cindex string escapes
+Screen provides an escape mechanism to insert information like the
+current time into messages or file names. The escape character
+is @code{%} with one exception: inside of a window's hardstatus
+@code{^%} (@code{^E}) is used instead.
+
+Here is the full list of supported escapes:
+
+@table @code
+@item %
+the escape character itself
+@item a
+either @code{am} or @code{pm}
+@item A
+either @code{AM} or @code{PM}
+@item c
+current time @code{HH:MM} in 24h format
+@item C
+current time @code{HH:MM} in 12h format
+@item d
+day number
+@item D
+weekday name
+@item h
+hardstatus of the window
+@item l
+current load of the system
+@item m
+month number
+@item M
+month name
+@item n
+window number
+@item s
+seconds
+@item t
+window title
+@item u
+all other users on this window
+@item w
+all window numbers and names
+@item W
+all window numbers and names except the current one
+@item y
+last two digits of the year number
+@item Y
+full year number
+@item ?
+the part to the next @code{%?} is displayed only if an escape expands
+to an nonempty string
+@item :
+else part of @code{%?}
+@end table
+The @code{c} and @code{C} escape may be qualified with a @code{0} to
+make screen use
+zero instead of space as fill character. The @code{n} escape understands
+a length qualifier (e.g. @code{%3n}).
+
+@node Environment, Files, String Escapes, Top
@chapter Environment Variables
@cindex environment
@@ -3733,9 +4350,6 @@ Number of columns on the terminal (overrides termcap entry).
@item HOME
Directory in which to look for .screenrc.
-@item ISCREENRC
-Alternate user screenrc file.
-
@item LINES
Number of lines on the terminal (overrides termcap entry).
@@ -3789,14 +4403,12 @@ global initialization files.
@itemx /local/etc/screenrc
@code{screen} initialization commands
-@item @code{$ISCREENRC}
-@itemx @code{$SCREENRC}
+@item @code{$SCREENRC}
@itemx @code{$HOME}/.iscreenrc
@itemx @code{$HOME}/.screenrc
Read in after /local/etc/screenrc
-@item @code{$ISCREENDIR}/S-@var{login}
-@itemx @code{$SCREENDIR}/S-@var{login}
+@item @code{$SCREENDIR}/S-@var{login}
@item /local/screens/S-@var{login}
Socket directories (default)
@@ -3864,7 +4476,7 @@ Contributors @*
Martin Schweikert (schweik@@cpp.ob.open.de),
David Vrona (dave@@sashimi.lcu.com),
E. Tye McQueen (tye%spillman.UUCP@@uunet.uu.net),
- Matthew Green (mrgreen@@mame.mu.oz.au),
+ Matthew Green (mrg@@mame.mu.oz.au),
Christopher Williams (cgw@@unt.edu),
Matt Mosley (mattm@@access.digex.net),
Gregory Neil Shapiro (gshapiro@@wpi.WPI.EDU),
@@ -3905,7 +4517,7 @@ found a bug not mentioned here.
are ignored). @samp{xn} is treated as a magic-margin indicator.
@item
-@code{screen} has no clue about double-high or double-wide characters.
+@code{screen} has no clue about double-high or double-wide characters.
But this is the only area where @code{vttest} is allowed to fail.
@item
@@ -3920,7 +4532,8 @@ capabilities to @code{$TERMCAP} may not have any effects.
@code{screen} does not make use of hardware tabs.
@item
-@code{screen} must be installed setuid root in order to be able to
+@code{screen} must be installed setuid root on most systems
+in order to be able to
correctly change the owner of the tty device file for each window.
Special permission may also be required to write the file
@file{/etc/utmp}.
@@ -3935,10 +4548,25 @@ advertise that a user is logged on who really isn't.
entry.
@item
-When the modem line was hung up, @code{screen} may not automatically
-detach (or quit) unless the device driver sends a HANGUP signal.
-To detach such a @code{screen} session use the -D or -d command
-line option.
+When the modem line was hung up, @code{screen} may not automatically detach
+(or quit) unless the device driver sends a HANGUP signal. To detach such a
+@code{screen} session use the -D or -d command line option.
+
+@item
+If a password is set, the command line options -d and -D still detach a
+session without asking.
+
+@item
+Both @code{breaktype} and @code{defbreaktype} change the break generating
+method used by all terminal devices. The first should change a window
+specific setting, where the latter should change only the default for new
+windows.
+
+@item
+When attaching to a multiuser session, the user's @file{.screenrc} file is not
+sourced. Each users personal settings have to be included in the
+@file{.screenrc} file from which the session is booted, or have to be
+changed manually.
@item
A weird imagination is most useful to gain full advantage of all the
@@ -3955,7 +4583,7 @@ If you find a bug in @code{Screen}, please send electronic mail to
of @code{Screen} which you are using. Also include in your message the
hardware and operating system, the compiler used to compile, a
description of the bug behavior, and the conditions that triggered the
-bug. Please recompile @code{screen} with the @samp{-DDEBUG -DTMPTEST} options
+bug. Please recompile @code{screen} with the @samp{-DDEBUG} options
enabled, reproduce the bug, and have a look at the debug output written to
the directory @file{/tmp/debug}. If necessary quote suspect passages from the
debug output and show the contents of your @file{config.h} if it matters.
@@ -3968,9 +4596,11 @@ debug output and show the contents of your @file{config.h} if it matters.
The latest official release of @code{screen} available via anonymous
ftp from @samp{prep.ai.mit.edu}, @samp{nic.funet.fi} or any other
-@code{GNU} distribution site. The latest beta testing release of
-@code{screen} is available from @samp{ftp.uni-erlangen.de
-(131.188.1.43)}, in the directory @file{pub/utilities/screen}.
+@code{GNU} distribution site. The home site of
+@code{screen} is @samp{ftp.uni-erlangen.de
+(131.188.3.71)}, in the directory @file{pub/utilities/screen}.
+The subdirectory @samp{private} contains the latest beta testing release.
+If you want to help, send a note to screen@@uni-erlangen.de.
@node Installation, Concept Index, Bugs, Top
@chapter Installation
@@ -3994,7 +4624,7 @@ The socket directory defaults either to @file{$HOME/.screen} or simply to
compile-time. If @code{screen} is installed
setuid root, then the administrator should compile screen with an
adequate (not NFS mounted) @code{SOCKDIR}. If @code{screen} is not
-running setuid-root, the user can specify any mode 777 directory in the
+running setuid-root, the user can specify any mode 700 directory in the
environment variable @code{$SCREENDIR}.
@node Compiling Screen, , Socket Directory, Installation
diff --git a/doc/window_to_display.ps b/doc/window_to_display.ps
new file mode 100644
index 0000000..cee66b3
--- /dev/null
+++ b/doc/window_to_display.ps
@@ -0,0 +1,2959 @@
+%!PS-Adobe-2.0 EPSF-1.2
+%%Creator: idraw
+%%DocumentFonts: Courier Times-Bold
+%%Pages: 1
+%%BoundingBox: 20 154 576 782
+%%EndComments
+
+%%BeginIdrawPrologue
+/arrowhead {
+0 begin
+transform originalCTM itransform
+/taily exch def
+/tailx exch def
+transform originalCTM itransform
+/tipy exch def
+/tipx exch def
+/dy tipy taily sub def
+/dx tipx tailx sub def
+/angle dx 0 ne dy 0 ne or { dy dx atan } { 90 } ifelse def
+gsave
+originalCTM setmatrix
+tipx tipy translate
+angle rotate
+newpath
+arrowHeight neg arrowWidth 2 div moveto
+0 0 lineto
+arrowHeight neg arrowWidth 2 div neg lineto
+patternNone not {
+originalCTM setmatrix
+/padtip arrowHeight 2 exp 0.25 arrowWidth 2 exp mul add sqrt brushWidth mul
+arrowWidth div def
+/padtail brushWidth 2 div def
+tipx tipy translate
+angle rotate
+padtip 0 translate
+arrowHeight padtip add padtail add arrowHeight div dup scale
+arrowheadpath
+ifill
+} if
+brushNone not {
+originalCTM setmatrix
+tipx tipy translate
+angle rotate
+arrowheadpath
+istroke
+} if
+grestore
+end
+} dup 0 9 dict put def
+
+/arrowheadpath {
+newpath
+arrowHeight neg arrowWidth 2 div moveto
+0 0 lineto
+arrowHeight neg arrowWidth 2 div neg lineto
+} def
+
+/leftarrow {
+0 begin
+y exch get /taily exch def
+x exch get /tailx exch def
+y exch get /tipy exch def
+x exch get /tipx exch def
+brushLeftArrow { tipx tipy tailx taily arrowhead } if
+end
+} dup 0 4 dict put def
+
+/rightarrow {
+0 begin
+y exch get /tipy exch def
+x exch get /tipx exch def
+y exch get /taily exch def
+x exch get /tailx exch def
+brushRightArrow { tipx tipy tailx taily arrowhead } if
+end
+} dup 0 4 dict put def
+
+%%EndIdrawPrologue
+
+/arrowHeight 8 def
+/arrowWidth 4 def
+
+/IdrawDict 52 dict def
+IdrawDict begin
+
+/reencodeISO {
+dup dup findfont dup length dict begin
+{ 1 index /FID ne { def }{ pop pop } ifelse } forall
+/Encoding ISOLatin1Encoding def
+currentdict end definefont
+} def
+
+/ISOLatin1Encoding [
+/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright
+/parenleft/parenright/asterisk/plus/comma/minus/period/slash
+/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon
+/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N
+/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright
+/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m
+/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde
+/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef
+/.notdef/dotlessi/grave/acute/circumflex/tilde/macron/breve
+/dotaccent/dieresis/.notdef/ring/cedilla/.notdef/hungarumlaut
+/ogonek/caron/space/exclamdown/cent/sterling/currency/yen/brokenbar
+/section/dieresis/copyright/ordfeminine/guillemotleft/logicalnot
+/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior
+/acute/mu/paragraph/periodcentered/cedilla/onesuperior/ordmasculine
+/guillemotright/onequarter/onehalf/threequarters/questiondown
+/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla
+/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex
+/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis
+/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute
+/Thorn/germandbls/agrave/aacute/acircumflex/atilde/adieresis
+/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/igrave
+/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute/ocircumflex
+/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis
+/yacute/thorn/ydieresis
+] def
+/Courier reencodeISO def
+/Times-Bold reencodeISO def
+
+/none null def
+/numGraphicParameters 17 def
+/stringLimit 65535 def
+
+/Begin {
+save
+numGraphicParameters dict begin
+} def
+
+/End {
+end
+restore
+} def
+
+/SetB {
+dup type /nulltype eq {
+pop
+false /brushRightArrow idef
+false /brushLeftArrow idef
+true /brushNone idef
+} {
+/brushDashOffset idef
+/brushDashArray idef
+0 ne /brushRightArrow idef
+0 ne /brushLeftArrow idef
+/brushWidth idef
+false /brushNone idef
+} ifelse
+} def
+
+/SetCFg {
+/fgblue idef
+/fggreen idef
+/fgred idef
+} def
+
+/SetCBg {
+/bgblue idef
+/bggreen idef
+/bgred idef
+} def
+
+/SetF {
+/printSize idef
+/printFont idef
+} def
+
+/SetP {
+dup type /nulltype eq {
+pop true /patternNone idef
+} {
+dup -1 eq {
+/patternGrayLevel idef
+/patternString idef
+} {
+/patternGrayLevel idef
+} ifelse
+false /patternNone idef
+} ifelse
+} def
+
+/BSpl {
+0 begin
+storexyn
+newpath
+n 1 gt {
+0 0 0 0 0 0 1 1 true subspline
+n 2 gt {
+0 0 0 0 1 1 2 2 false subspline
+1 1 n 3 sub {
+/i exch def
+i 1 sub dup i dup i 1 add dup i 2 add dup false subspline
+} for
+n 3 sub dup n 2 sub dup n 1 sub dup 2 copy false subspline
+} if
+n 2 sub dup n 1 sub dup 2 copy 2 copy false subspline
+patternNone not brushLeftArrow not brushRightArrow not and and { ifill } if
+brushNone not { istroke } if
+0 0 1 1 leftarrow
+n 2 sub dup n 1 sub dup rightarrow
+} if
+end
+} dup 0 4 dict put def
+
+/Circ {
+newpath
+0 360 arc
+patternNone not { ifill } if
+brushNone not { istroke } if
+} def
+
+/CBSpl {
+0 begin
+dup 2 gt {
+storexyn
+newpath
+n 1 sub dup 0 0 1 1 2 2 true subspline
+1 1 n 3 sub {
+/i exch def
+i 1 sub dup i dup i 1 add dup i 2 add dup false subspline
+} for
+n 3 sub dup n 2 sub dup n 1 sub dup 0 0 false subspline
+n 2 sub dup n 1 sub dup 0 0 1 1 false subspline
+patternNone not { ifill } if
+brushNone not { istroke } if
+} {
+Poly
+} ifelse
+end
+} dup 0 4 dict put def
+
+/Elli {
+0 begin
+newpath
+4 2 roll
+translate
+scale
+0 0 1 0 360 arc
+patternNone not { ifill } if
+brushNone not { istroke } if
+end
+} dup 0 1 dict put def
+
+/Line {
+0 begin
+2 storexyn
+newpath
+x 0 get y 0 get moveto
+x 1 get y 1 get lineto
+brushNone not { istroke } if
+0 0 1 1 leftarrow
+0 0 1 1 rightarrow
+end
+} dup 0 4 dict put def
+
+/MLine {
+0 begin
+storexyn
+newpath
+n 1 gt {
+x 0 get y 0 get moveto
+1 1 n 1 sub {
+/i exch def
+x i get y i get lineto
+} for
+patternNone not brushLeftArrow not brushRightArrow not and and { ifill } if
+brushNone not { istroke } if
+0 0 1 1 leftarrow
+n 2 sub dup n 1 sub dup rightarrow
+} if
+end
+} dup 0 4 dict put def
+
+/Poly {
+3 1 roll
+newpath
+moveto
+-1 add
+{ lineto } repeat
+closepath
+patternNone not { ifill } if
+brushNone not { istroke } if
+} def
+
+/Rect {
+0 begin
+/t exch def
+/r exch def
+/b exch def
+/l exch def
+newpath
+l b moveto
+l t lineto
+r t lineto
+r b lineto
+closepath
+patternNone not { ifill } if
+brushNone not { istroke } if
+end
+} dup 0 4 dict put def
+
+/Text {
+ishow
+} def
+
+/idef {
+dup where { pop pop pop } { exch def } ifelse
+} def
+
+/ifill {
+0 begin
+gsave
+patternGrayLevel -1 ne {
+fgred bgred fgred sub patternGrayLevel mul add
+fggreen bggreen fggreen sub patternGrayLevel mul add
+fgblue bgblue fgblue sub patternGrayLevel mul add setrgbcolor
+eofill
+} {
+eoclip
+originalCTM setmatrix
+pathbbox /t exch def /r exch def /b exch def /l exch def
+/w r l sub ceiling cvi def
+/h t b sub ceiling cvi def
+/imageByteWidth w 8 div ceiling cvi def
+/imageHeight h def
+bgred bggreen bgblue setrgbcolor
+eofill
+fgred fggreen fgblue setrgbcolor
+w 0 gt h 0 gt and {
+l w add b translate w neg h scale
+w h true [w 0 0 h neg 0 h] { patternproc } imagemask
+} if
+} ifelse
+grestore
+end
+} dup 0 8 dict put def
+
+/istroke {
+gsave
+brushDashOffset -1 eq {
+[] 0 setdash
+1 setgray
+} {
+brushDashArray brushDashOffset setdash
+fgred fggreen fgblue setrgbcolor
+} ifelse
+brushWidth setlinewidth
+originalCTM setmatrix
+stroke
+grestore
+} def
+
+/ishow {
+0 begin
+gsave
+fgred fggreen fgblue setrgbcolor
+/fontDict printFont printSize scalefont dup setfont def
+/descender fontDict begin 0 [FontBBox] 1 get FontMatrix end
+transform exch pop def
+/vertoffset 1 printSize sub descender sub def {
+0 vertoffset moveto show
+/vertoffset vertoffset printSize sub def
+} forall
+grestore
+end
+} dup 0 3 dict put def
+/patternproc {
+0 begin
+/patternByteLength patternString length def
+/patternHeight patternByteLength 8 mul sqrt cvi def
+/patternWidth patternHeight def
+/patternByteWidth patternWidth 8 idiv def
+/imageByteMaxLength imageByteWidth imageHeight mul
+stringLimit patternByteWidth sub min def
+/imageMaxHeight imageByteMaxLength imageByteWidth idiv patternHeight idiv
+patternHeight mul patternHeight max def
+/imageHeight imageHeight imageMaxHeight sub store
+/imageString imageByteWidth imageMaxHeight mul patternByteWidth add string def
+0 1 imageMaxHeight 1 sub {
+/y exch def
+/patternRow y patternByteWidth mul patternByteLength mod def
+/patternRowString patternString patternRow patternByteWidth getinterval def
+/imageRow y imageByteWidth mul def
+0 patternByteWidth imageByteWidth 1 sub {
+/x exch def
+imageString imageRow x add patternRowString putinterval
+} for
+} for
+imageString
+end
+} dup 0 12 dict put def
+
+/min {
+dup 3 2 roll dup 4 3 roll lt { exch } if pop
+} def
+
+/max {
+dup 3 2 roll dup 4 3 roll gt { exch } if pop
+} def
+
+/midpoint {
+0 begin
+/y1 exch def
+/x1 exch def
+/y0 exch def
+/x0 exch def
+x0 x1 add 2 div
+y0 y1 add 2 div
+end
+} dup 0 4 dict put def
+
+/thirdpoint {
+0 begin
+/y1 exch def
+/x1 exch def
+/y0 exch def
+/x0 exch def
+x0 2 mul x1 add 3 div
+y0 2 mul y1 add 3 div
+end
+} dup 0 4 dict put def
+
+/subspline {
+0 begin
+/movetoNeeded exch def
+y exch get /y3 exch def
+x exch get /x3 exch def
+y exch get /y2 exch def
+x exch get /x2 exch def
+y exch get /y1 exch def
+x exch get /x1 exch def
+y exch get /y0 exch def
+x exch get /x0 exch def
+x1 y1 x2 y2 thirdpoint
+/p1y exch def
+/p1x exch def
+x2 y2 x1 y1 thirdpoint
+/p2y exch def
+/p2x exch def
+x1 y1 x0 y0 thirdpoint
+p1x p1y midpoint
+/p0y exch def
+/p0x exch def
+x2 y2 x3 y3 thirdpoint
+p2x p2y midpoint
+/p3y exch def
+/p3x exch def
+movetoNeeded { p0x p0y moveto } if
+p1x p1y p2x p2y p3x p3y curveto
+end
+} dup 0 17 dict put def
+
+/storexyn {
+/n exch def
+/y n array def
+/x n array def
+n 1 sub -1 0 {
+/i exch def
+y i 3 2 roll put
+x i 3 2 roll put
+} for
+} def
+
+/SSten {
+fgred fggreen fgblue setrgbcolor
+dup true exch 1 0 0 -1 0 6 -1 roll matrix astore
+} def
+
+/FSten {
+dup 3 -1 roll dup 4 1 roll exch
+newpath
+0 0 moveto
+dup 0 exch lineto
+exch dup 3 1 roll exch lineto
+0 lineto
+closepath
+bgred bggreen bgblue setrgbcolor
+eofill
+SSten
+} def
+
+/Rast {
+exch dup 3 1 roll 1 0 0 -1 0 6 -1 roll matrix astore
+} def
+
+%%EndProlog
+
+%I Idraw 10 Grid 8 8
+
+%%Page: 1 1
+
+Begin
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t
+[ 0.95606 0 0 0.95606 0 0 ] concat
+/originalCTM matrix currentmatrix def
+
+Begin %I BSpl
+%I b 65535
+1 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -4 119 ] concat
+%I 6
+276 433
+276 449
+292 449
+364 449
+380 449
+380 433
+6 BSpl
+%I 1
+End
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t u
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t
+[ 1 0 0 1 -400 -208 ] concat
+
+Begin %I CBSpl
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg LtGray
+0.762951 0.762951 0.762951 SetCBg
+%I p
+0.5 SetP
+%I t
+[ 0.5 0 0 0.5 350 330.5 ] concat
+%I 12
+340 107
+340 123
+340 187
+340 203
+356 203
+468 203
+484 203
+484 187
+484 123
+484 107
+468 107
+356 107
+12 CBSpl
+End
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 535.5 381 ] concat
+%I
+[
+(w_ptyfd)
+] Text
+End
+
+End %I eop
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t
+[ 1 0 0 1 88 -23.9999 ] concat
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t
+[ -4.37114e-08 -1 1 -4.37114e-08 -608 640 ] concat
+
+Begin %I Poly
+none SetB %I b n
+%I cfg Black
+0 0 0 SetCFg
+%I cbg LtGray
+0.762951 0.762951 0.762951 SetCBg
+%I p
+0.5 SetP
+%I t
+[ 0.5 0 0 0.5 238 522.5 ] concat
+%I 4
+164 315
+228 315
+228 363
+164 363
+4 Poly
+End
+
+Begin %I Rect
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 111 317 ] concat
+%I
+233 363 241 387 Rect
+End
+
+Begin %I Line
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 111 317 ] concat
+%I
+225 387 225 363 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 111 317 ] concat
+%I
+217 387 217 363 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 111 317 ] concat
+%I
+233 363 201 363 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 111 317 ] concat
+%I
+201 387 233 387 Line
+%I 1
+End
+
+End %I eop
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 66.5 285 ] concat
+%I
+[
+(d_obuf)
+] Text
+End
+
+End %I eop
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 153.5 244 ] concat
+%I
+[
+(write\(\))
+] Text
+End
+
+Begin %I BSpl
+%I b 65535
+2 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg Black
+0 0 0 SetCBg
+none SetP %I p n
+%I t
+[ 0.5 0 0 0.5 56 123.5 ] concat
+%I 3
+272 281
+288 249
+272 201
+3 BSpl
+%I 2
+End
+
+End %I eop
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t u
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t
+[ 1 0 0 1 -239.5 -207.5 ] concat
+
+Begin %I CBSpl
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg LtGray
+0.762951 0.762951 0.762951 SetCBg
+%I p
+0.5 SetP
+%I t
+[ 0.5 0 0 0.5 350 330.5 ] concat
+%I 12
+340 107
+340 123
+340 187
+340 203
+356 203
+468 203
+484 203
+484 187
+484 123
+484 107
+468 107
+356 107
+12 CBSpl
+End
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 535.5 381 ] concat
+%I
+[
+(w_ptyfd)
+] Text
+End
+
+End %I eop
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t
+[ 1 0 0 1 248.5 -23.5 ] concat
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t
+[ -4.37114e-08 -1 1 -4.37114e-08 -608 640 ] concat
+
+Begin %I Poly
+none SetB %I b n
+%I cfg Black
+0 0 0 SetCFg
+%I cbg LtGray
+0.762951 0.762951 0.762951 SetCBg
+%I p
+0.5 SetP
+%I t
+[ 0.5 0 0 0.5 238 522.5 ] concat
+%I 4
+164 315
+228 315
+228 363
+164 363
+4 Poly
+End
+
+Begin %I Rect
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 111 317 ] concat
+%I
+233 363 241 387 Rect
+End
+
+Begin %I Line
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 111 317 ] concat
+%I
+225 387 225 363 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 111 317 ] concat
+%I
+217 387 217 363 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 111 317 ] concat
+%I
+233 363 201 363 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 111 317 ] concat
+%I
+201 387 233 387 Line
+%I 1
+End
+
+End %I eop
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 66.5 285 ] concat
+%I
+[
+(d_obuf)
+] Text
+End
+
+End %I eop
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 314 244.5 ] concat
+%I
+[
+(write\(\))
+] Text
+End
+
+Begin %I BSpl
+%I b 65535
+2 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg Black
+0 0 0 SetCBg
+none SetP %I p n
+%I t
+[ 0.5 0 0 0.5 216.5 124 ] concat
+%I 3
+272 281
+288 249
+272 201
+3 BSpl
+%I 2
+End
+
+End %I eop
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t u
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t
+[ 1 0 0 1 -79.5 -207.5 ] concat
+
+Begin %I CBSpl
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg LtGray
+0.762951 0.762951 0.762951 SetCBg
+%I p
+0.5 SetP
+%I t
+[ 0.5 0 0 0.5 350 330.5 ] concat
+%I 12
+340 107
+340 123
+340 187
+340 203
+356 203
+468 203
+484 203
+484 187
+484 123
+484 107
+468 107
+356 107
+12 CBSpl
+End
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 535.5 381 ] concat
+%I
+[
+(w_ptyfd)
+] Text
+End
+
+End %I eop
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t
+[ 1 0 0 1 408.5 -23.5 ] concat
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t
+[ -4.37114e-08 -1 1 -4.37114e-08 -608 640 ] concat
+
+Begin %I Poly
+none SetB %I b n
+%I cfg Black
+0 0 0 SetCFg
+%I cbg LtGray
+0.762951 0.762951 0.762951 SetCBg
+%I p
+0.5 SetP
+%I t
+[ 0.5 0 0 0.5 238 522.5 ] concat
+%I 4
+164 315
+228 315
+228 363
+164 363
+4 Poly
+End
+
+Begin %I Rect
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 111 317 ] concat
+%I
+233 363 241 387 Rect
+End
+
+Begin %I Line
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 111 317 ] concat
+%I
+225 387 225 363 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 111 317 ] concat
+%I
+217 387 217 363 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 111 317 ] concat
+%I
+233 363 201 363 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 111 317 ] concat
+%I
+201 387 233 387 Line
+%I 1
+End
+
+End %I eop
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 66.5 285 ] concat
+%I
+[
+(d_obuf)
+] Text
+End
+
+End %I eop
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 474 244.5 ] concat
+%I
+[
+(write\(\))
+] Text
+End
+
+Begin %I BSpl
+%I b 65535
+2 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg Black
+0 0 0 SetCBg
+none SetP %I p n
+%I t
+[ 0.5 0 0 0.5 376.5 124 ] concat
+%I 3
+272 281
+288 249
+272 201
+3 BSpl
+%I 2
+End
+
+End %I eop
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 289 540 ] concat
+%I
+[
+(WriteString\(\))
+] Text
+End
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t
+[ 1 0 0 1 0 168 ] concat
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t
+[ 1 0 0 1 32 56 ] concat
+
+Begin %I Rect
+%I b 65535
+3 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg LtGray
+0.762951 0.762951 0.762951 SetCBg
+%I p
+0.5 SetP
+%I t
+[ 1 0 0 1 61 197 ] concat
+%I
+195 243 259 291 Rect
+End
+
+Begin %I Line
+%I b 65535
+1 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 61 197 ] concat
+%I
+203 283 251 283 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+1 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 61 197 ] concat
+%I
+203 275 251 275 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+1 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 61 197 ] concat
+%I
+203 267 251 267 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+1 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 61 197 ] concat
+%I
+203 259 251 259 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+1 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 61 197 ] concat
+%I
+203 251 251 251 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+0 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 61 197 ] concat
+%I
+203 299 251 299 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+0 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 61 197 ] concat
+%I
+203 307 251 307 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+0 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 61 197 ] concat
+%I
+203 315 251 315 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+0 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 61 197 ] concat
+%I
+203 323 251 323 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+0 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 53 197 ] concat
+%I
+203 331 251 331 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+0 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 0.5 0 0 0.5 162 329 ] concat
+%I
+188 318 188 366 Line
+%I 2
+End
+
+Begin %I Line
+%I b 65535
+0 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 0.5 0 0 0.5 162 329 ] concat
+%I
+316 318 316 366 Line
+%I 2
+End
+
+Begin %I BSpl
+%I b 65535
+0 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 0.5 0 0 0.5 162 329 ] concat
+%I 3
+316 366
+316 398
+300 398
+3 BSpl
+%I 2
+End
+
+Begin %I BSpl
+%I b 65535
+0 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 0.5 0 0 0.5 162 329 ] concat
+%I 3
+188 366
+188 398
+172 398
+3 BSpl
+%I 2
+End
+
+End %I eop
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 296 492.5 ] concat
+%I
+[
+(w_image[])
+] Text
+End
+
+End %I eop
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 312 567 ] concat
+%I
+[
+(\(CB8\))
+] Text
+End
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t
+[ 1 0 0 1 1.52588e-05 16 ] concat
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t
+[ -4.37114e-08 -1 1 -4.37114e-08 -567.5 808.5 ] concat
+
+Begin %I Poly
+none SetB %I b n
+%I cfg Black
+0 0 0 SetCFg
+%I cbg LtGray
+0.762951 0.762951 0.762951 SetCBg
+%I p
+0.5 SetP
+%I t
+[ 0.5 0 0 0.5 238 522.5 ] concat
+%I 4
+164 315
+228 315
+228 363
+164 363
+4 Poly
+End
+
+Begin %I Rect
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 111 317 ] concat
+%I
+233 363 241 387 Rect
+End
+
+Begin %I Line
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 111 317 ] concat
+%I
+225 387 225 363 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 111 317 ] concat
+%I
+217 387 217 363 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 111 317 ] concat
+%I
+233 363 201 363 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 111 317 ] concat
+%I
+201 387 233 387 Line
+%I 1
+End
+
+End %I eop
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 101 453.5 ] concat
+%I
+[
+(w_string)
+] Text
+End
+
+End %I eop
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t u
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t u
+
+Begin %I Poly
+none SetB %I b n
+%I cfg Black
+0 0 0 SetCFg
+%I cbg LtGray
+0.762951 0.762951 0.762951 SetCBg
+%I p
+0.5 SetP
+%I t
+[ 0.5 0 0 0.5 230 434.5 ] concat
+%I 4
+164 315
+228 315
+228 363
+164 363
+4 Poly
+End
+
+Begin %I Pict
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t
+[ 1 0 0 1 -32 32 ] concat
+
+Begin %I Rect
+%I b 65535
+3 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 135 197.5 ] concat
+%I
+233 363 241 387 Rect
+End
+
+Begin %I Line
+%I b 65535
+3 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 135 197.5 ] concat
+%I
+225 387 225 363 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+3 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 135 197.5 ] concat
+%I
+217 387 217 363 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+3 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 135 197.5 ] concat
+%I
+233 363 201 363 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+3 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 135 197.5 ] concat
+%I
+201 387 233 387 Line
+%I 1
+End
+
+End %I eop
+
+End %I eop
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 300.5 589 ] concat
+%I
+[
+(w_outbuf)
+] Text
+End
+
+End %I eop
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-times-bold-r-normal-*-14-*-*-*-*-*-*-*
+Times-Bold 14 SetF
+%I t
+[ 1 0 0 1 185 814 ] concat
+%I
+[
+(Window to display data flow in Screen)
+] Text
+End
+
+Begin %I BSpl
+%I b 65535
+1 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -4 119 ] concat
+%I 4
+108 361
+60 361
+44 361
+44 345
+4 BSpl
+%I 1
+End
+
+Begin %I BSpl
+%I b 65535
+1 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -4 119 ] concat
+%I 4
+148 361
+156 361
+172 361
+172 345
+4 BSpl
+%I 1
+End
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 34 491 ] concat
+%I
+[
+(PrintFlush\(\))
+] Text
+End
+
+Begin %I BSpl
+%I b 65535
+1 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -4 119 ] concat
+%I 7
+300 409
+276 409
+276 433
+276 457
+276 481
+300 481
+308 481
+7 BSpl
+%I 1
+End
+
+Begin %I BSpl
+%I b 65535
+1 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -4 119 ] concat
+%I 4
+356 481
+380 481
+380 457
+380 449
+4 BSpl
+%I 1
+End
+
+Begin %I BSpl
+%I b 65535
+1 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -4 119 ] concat
+%I 5
+220 505
+220 529
+220 553
+244 553
+252 553
+5 BSpl
+%I 1
+End
+
+Begin %I BSpl
+%I b 65535
+1 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -4 119 ] concat
+%I 6
+276 409
+252 409
+252 433
+252 529
+252 553
+284 553
+6 BSpl
+%I 1
+End
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t
+[ 1 0 0 1 0 136 ] concat
+
+Begin %I CBSpl
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg LtGray
+0.762951 0.762951 0.762951 SetCBg
+%I p
+0.5 SetP
+%I t
+[ 0.5 0 0 0.5 350 330.5 ] concat
+%I 12
+340 107
+340 123
+340 187
+340 203
+356 203
+468 203
+484 203
+484 187
+484 123
+484 107
+468 107
+356 107
+12 CBSpl
+End
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 535.5 381 ] concat
+%I
+[
+(w_ptyfd)
+] Text
+End
+
+End %I eop
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t
+[ 1 0 0 1 0 88 ] concat
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t u
+
+Begin %I Rect
+none SetB %I b n
+%I cfg Black
+0 0 0 SetCFg
+%I cbg LtGray
+0.762951 0.762951 0.762951 SetCBg
+%I p
+0.5 SetP
+%I t
+[ 0.5 -0 -0 0.5 380.5 362.5 ] concat
+%I
+71 123 135 171 Rect
+End
+
+Begin %I Pict
+%I b 65535
+2 0 0 [] 0 SetB
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t
+[ 1 0 0 1 24 -136 ] concat
+
+Begin %I Rect
+%I b 65535
+3 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 135 197.5 ] concat
+%I
+257 363 265 387 Rect
+End
+
+Begin %I Line
+%I b 65535
+3 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 135 197.5 ] concat
+%I
+273 387 273 363 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+3 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 135 197.5 ] concat
+%I
+281 387 281 363 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+3 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 135 197.5 ] concat
+%I
+265 363 297 363 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65535
+3 0 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 135 197.5 ] concat
+%I
+265 387 297 387 Line
+%I 1
+End
+
+End %I eop
+
+End %I eop
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 416.5 419 ] concat
+%I
+[
+(main:buf)
+] Text
+End
+
+End %I eop
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 464 538 ] concat
+%I
+[
+(read\(\))
+] Text
+End
+
+Begin %I BSpl
+%I b 65535
+2 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 -4 111 ] concat
+%I 3
+516 409
+484 417
+460 409
+3 BSpl
+%I 1
+End
+
+Begin %I BSpl
+%I b 65535
+1 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -4 119 ] concat
+%I 7
+412 401
+396 401
+396 385
+396 361
+396 345
+412 345
+420 345
+7 BSpl
+%I 1
+End
+
+Begin %I BSpl
+%I b 65535
+1 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -4 119 ] concat
+%I 3
+36 337
+36 305
+76 257
+3 BSpl
+%I 1
+End
+
+Begin %I BSpl
+%I b 65535
+1 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -4 119 ] concat
+%I 3
+44 337
+52 297
+108 265
+3 BSpl
+%I 1
+End
+
+Begin %I BSpl
+%I b 65535
+1 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -4 119 ] concat
+%I 3
+52 337
+68 297
+132 273
+3 BSpl
+%I 1
+End
+
+Begin %I BSpl
+%I b 65535
+1 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -4 119 ] concat
+%I 3
+164 337
+164 321
+172 273
+3 BSpl
+%I 1
+End
+
+Begin %I BSpl
+%I b 65535
+1 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -4 119 ] concat
+%I 3
+172 337
+172 321
+204 289
+3 BSpl
+%I 1
+End
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t
+[ 1 0 0 1 0 104 ] concat
+
+Begin %I Rect
+none SetB %I b n
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+%I p
+1 SetP
+%I t
+[ 1 -0 -0 1 -4 119 ] concat
+%I
+28 201 92 217 Rect
+End
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 29.5 332 ] concat
+%I
+[
+(AddStrn\(\))
+] Text
+End
+
+End %I eop
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t u
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 471 481 ] concat
+%I
+[
+(write\(\))
+] Text
+End
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+none SetP %I p n
+%I t
+[ 1 0 0 1 0 -120 ] concat
+
+Begin %I CBSpl
+%I b 65520
+2 0 0 [12 4] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg LtGray
+0.762951 0.762951 0.762951 SetCBg
+%I p
+0.5 SetP
+%I t
+[ 0.5 0 0 0.5 350 482.5 ] concat
+%I 12
+340 107
+340 123
+340 187
+340 203
+356 203
+468 203
+484 203
+484 187
+484 123
+484 107
+468 107
+356 107
+12 CBSpl
+End
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 511.5 533 ] concat
+%I
+[
+(w_pwin->p_ptyfd)
+] Text
+End
+
+End %I eop
+
+Begin %I BSpl
+%I b 65535
+1 1 0 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -4 119 ] concat
+%I 3
+516 345
+492 353
+468 345
+3 BSpl
+%I 1
+End
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t u
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 391.5 445.5 ] concat
+%I
+[
+(w_pwin->p_inbuf)
+] Text
+End
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t u
+
+Begin %I Poly
+none SetB %I b n
+%I cfg Black
+0 0 0 SetCFg
+%I cbg LtGray
+0.762951 0.762951 0.762951 SetCBg
+none SetP %I p n
+%I t
+[ 0.5 0 0 0.5 342 290.5 ] concat
+%I 4
+164 315
+228 315
+228 363
+164 363
+4 Poly
+End
+
+Begin %I Rect
+%I b 65520
+2 0 0 [12 4] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 215 85.0002 ] concat
+%I
+233 363 241 387 Rect
+End
+
+Begin %I Line
+%I b 65520
+2 0 0 [12 4] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 215 85.0002 ] concat
+%I
+225 387 225 363 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65520
+2 0 0 [12 4] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 215 85.0002 ] concat
+%I
+233 363 201 363 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65520
+2 0 0 [12 4] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 0 0 1 215 85.0002 ] concat
+%I
+201 387 233 387 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65520
+2 0 0 [12 4] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 119 140 ] concat
+%I
+313 308 313 332 Line
+%I 1
+End
+
+End %I eop
+
+End %I eop
+
+End %I eop
+
+Begin %I Line
+%I b 65520
+0 0 0 [12 4] 0 SetB
+%I cfg LtGray
+0.762951 0.762951 0.762951 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -22 198.5 ] concat
+%I
+222 210 358 106 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65520
+0 0 0 [12 4] 0 SetB
+%I cfg LtGray
+0.762951 0.762951 0.762951 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -22 198.5 ] concat
+%I
+190 194 198 106 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65520
+0 0 0 [12 4] 0 SetB
+%I cfg LtGray
+0.762951 0.762951 0.762951 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -22 198.5 ] concat
+%I
+150 194 518 106 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65520
+0 0 0 [12 4] 0 SetB
+%I cfg LtGray
+0.762951 0.762951 0.762951 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -22 198.5 ] concat
+%I
+126 186 358 106 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65520
+0 0 0 [12 4] 0 SetB
+%I cfg LtGray
+0.762951 0.762951 0.762951 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -22 198.5 ] concat
+%I
+94 178 198 106 Line
+%I 1
+End
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t u
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 184 615 ] concat
+%I
+[
+(Special\(\))
+] Text
+End
+
+Begin %I BSpl
+%I b 65535
+1 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -4 127 ] concat
+%I 6
+220 505
+220 529
+196 529
+164 529
+140 529
+140 505
+6 BSpl
+%I 1
+End
+
+Begin %I BSpl
+%I b 65535
+1 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -22 198.5 ] concat
+%I 3
+166 425
+166 409
+198 378
+3 BSpl
+%I 1
+End
+
+Begin %I BSpl
+%I b 65535
+1 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -22 198.5 ] concat
+%I 3
+158 425
+158 410
+182 370
+3 BSpl
+%I 1
+End
+
+Begin %I BSpl
+%I b 65535
+1 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -22 198.5 ] concat
+%I 3
+150 425
+150 409
+158 362
+3 BSpl
+%I 1
+End
+
+End %I eop
+
+Begin %I BSpl
+%I b 65535
+1 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -22 198.5 ] concat
+%I 3
+198 257
+198 241
+254 210
+3 BSpl
+%I 1
+End
+
+Begin %I Pict
+%I b u
+%I cfg u
+%I cbg u
+%I f u
+%I p u
+%I t
+[ 1 0 0 1 120 48 ] concat
+
+Begin %I Rect
+none SetB %I b n
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+%I p
+1 SetP
+%I t
+[ 1 -0 -0 1 -4 119 ] concat
+%I
+28 257 108 273 Rect
+End
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 28.5 388 ] concat
+%I
+[
+(MakeStatus\(\))
+] Text
+End
+
+End %I eop
+
+Begin %I Line
+%I b 65520
+0 0 0 [12 4] 0 SetB
+%I cfg LtGray
+0.762951 0.762951 0.762951 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -22 198.5 ] concat
+%I
+254 210 518 106 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65520
+0 0 0 [12 4] 0 SetB
+%I cfg LtGray
+0.762951 0.762951 0.762951 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -22 198.5 ] concat
+%I
+198 378 518 106 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65520
+0 0 0 [12 4] 0 SetB
+%I cfg LtGray
+0.762951 0.762951 0.762951 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -22 198.5 ] concat
+%I
+182 370 358 106 Line
+%I 1
+End
+
+Begin %I Line
+%I b 65520
+0 0 0 [12 4] 0 SetB
+%I cfg LtGray
+0.762951 0.762951 0.762951 SetCFg
+%I cbg Black
+0 0 0 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -22 198.5 ] concat
+%I
+158 362 198 106 Line
+%I 1
+End
+
+Begin %I BSpl
+%I b 65535
+2 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -4 119 ] concat
+%I 4
+268 337
+268 281
+180 241
+180 185
+4 BSpl
+%I 1
+End
+
+Begin %I BSpl
+%I b 65535
+2 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 0.5 -0 -0 0.5 197.5 193.5 ] concat
+%I 4
+181 525
+181 413
+277 333
+277 221
+4 BSpl
+%I 2
+End
+
+Begin %I BSpl
+%I b 65535
+2 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -4 119 ] concat
+%I 4
+316 337
+316 281
+500 241
+500 185
+4 BSpl
+%I 1
+End
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 0.587415 -0.809286 0.809286 0.587415 298.171 395.796 ] concat
+%I
+[
+(AddChar\(\))
+] Text
+End
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 0.810117 0.586269 -0.586269 0.810117 198.687 362.705 ] concat
+%I
+[
+(AddChar\(\))
+] Text
+End
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 0.954268 -0.298951 0.298951 0.954268 391.408 381.739 ] concat
+%I
+[
+(AddChar\(\))
+] Text
+End
+
+Begin %I BSpl
+%I b 65535
+2 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg Black
+0 0 0 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -4 119 ] concat
+%I 5
+412 409
+308 409
+292 409
+292 393
+292 361
+5 BSpl
+%I 1
+End
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 232.5 473.5 ] concat
+%I
+[
+(w_dlist->next->next...)
+] Text
+End
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 134 540 ] concat
+%I
+[
+(PrintChar\(\))
+] Text
+End
+
+Begin %I Text
+%I cfg Black
+0 0 0 SetCFg
+%I f -*-courier-medium-r-normal-*-10-*-*-*-*-*-*-*
+Courier 10 SetF
+%I t
+[ 1 0 0 1 139 525 ] concat
+%I
+[
+(SaveChar\(\))
+] Text
+End
+
+Begin %I BSpl
+%I b 65535
+1 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg Black
+0 0 0 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -4 119 ] concat
+%I 5
+412 409
+292 409
+148 409
+132 409
+132 393
+5 BSpl
+%I 1
+End
+
+Begin %I BSpl
+%I b 65535
+1 0 1 [] 0 SetB
+%I cfg Black
+0 0 0 SetCFg
+%I cbg White
+1 1 1 SetCBg
+none SetP %I p n
+%I t
+[ 1 -0 -0 1 -4 119 ] concat
+%I 4
+244 409
+220 409
+220 433
+220 481
+4 BSpl
+%I 1
+End
+
+End %I eop
+
+showpage
+
+%%Trailer
+
+end
diff --git a/etc/ccdefs b/etc/ccdefs
new file mode 100755
index 0000000..2358fcd
--- /dev/null
+++ b/etc/ccdefs
@@ -0,0 +1,45 @@
+#!/bin/sh
+cd /tmp
+umask 022
+
+CC=cc
+CPP=/lib/cpp
+
+TEMP=def$$
+trap 'rm -f ${TEMP}*; trap 0; exit' 0 1 2 3 15
+
+set `type $CC`
+q=$#
+set x `type $CC`
+shift $q
+cc=$1
+
+set `type $CPP`
+q=$#
+set x `type $CPP`
+shift $q
+cpp=$1
+
+strings - "$cc" 2>/dev/null | tr ' ' '\012' > ${TEMP}.x
+
+if test -x "$cpp"; then
+strings - "$cpp" 2>/dev/null | tr ' ' '\012' >> ${TEMP}.x
+else
+echo "Warning: cpp not found."
+fi
+
+sort < ${TEMP}.x | uniq | awk '
+/^-D[A-Za-z_][A-Za-z_0-9]*$/ {
+ printf("#ifdef %s\n", substr($0,3))
+ printf("\"%s\": %s\n", substr($0,3), substr($0,3))
+ print "#endif"
+ }
+/^[A-Za-z_][A-Za-z_0-9]*$/ {
+ printf("#ifdef %s\n", $0)
+ printf("\"%s\": %s\n", $0, $0)
+ print "#endif"
+ }
+' > ${TEMP}.c
+
+echo "Defines in cc are:"
+cc -E ${TEMP}.c | sed -n -e 's/"\([^:]*\)":/\1:/p' | sort | uniq
diff --git a/etc/gr-braille.tbl b/etc/gr-braille.tbl
new file mode 100644
index 0000000..34407b7
--- /dev/null
+++ b/etc/gr-braille.tbl
@@ -0,0 +1,260 @@
+# GERMAN BRAILLE TABLE
+#
+# Dec Hex Braille Description
+# ------------------------------------------------------------------------
+ 0 00 (--345--8) NUL
+ 1 01 (1------8) SOH
+ 2 02 (12-----8) STX
+ 3 03 (1--4---8) ETX
+ 4 04 (1--45--8) EOT
+ 5 05 (1---5--8) ENQ
+ 6 06 (12-4---8) ACK
+ 7 07 (12-45--8) BEL
+ 8 08 (12--5--8) BS
+ 9 09 (-2-4---8) HT
+ 10 OA (-2-45--8) LF
+ 11 0B (1-3----8) VT
+ 12 OC (123----8) FF
+ 13 0D (1-34---8) CR
+ 14 0E (1-345--8) SO
+ 15 OF (1-3-5--8) SI
+ 16 10 (1234---8) DLE
+ 17 11 (12345--8) DC1
+ 18 12 (123-5--8) DC2
+ 19 13 (-234---8) DC3
+ 20 14 (-2345--8) DC4
+ 21 15 (1-3--6-8) NAK
+ 22 16 (123--6-8) SYN
+ 23 17 (-2-456-8) ETB
+ 24 18 (1-34-6-8) CAN
+ 25 19 (1-3456-8) EM
+ 26 1A (1-3-56-8) SUB
+ 27 lB (123-56-8) ESC
+ 28 lC (--34---8) FS
+ 29 1D (-23456-8) GS
+ 30 lE (-234-6-8) RS
+ 31 1F (---456-8) US
+ 32 20 (--------) Space
+ 33 21 (----5---) !
+ 34 22 (---4----) "
+ 35 23 (--3456--) #
+ 36 24 (---4-6--) $
+ 37 25 (123456--) %
+ 38 26 (1234-6--) &
+ 39 27 (-----6--) '
+ 40 28 (-23--6--) (
+ 41 29 (--3-56--) )
+ 42 2A (--3-5---) *
+ 43 2B (-23-5---) +
+ 44 2C (-2------) ,
+ 45 2D (--3--6--) -
+ 46 2E (--3-----) .
+ 47 2F (-2--56--) /
+ 48 30 (--34-6--) 0
+ 49 31 (1----6--) 1
+ 50 32 (12---6--) 2
+ 51 33 (1--4-6--) 3
+ 52 34 (1--456--) 4
+ 53 35 (1---56--) 5
+ 54 36 (12-4-6--) 6
+ 55 37 (12-456--) 7
+ 56 38 (12--56--) 8
+ 57 39 (-2-4-6--) 9
+ 58 3A (-2--5---) :
+ 59 3B (-23-----) ;
+ 60 3C (----56--) <
+ 61 3D (-23-56--)
+ 62 3E (---45---) >
+ 63 3F (-2---6--) ?
+ 64 40 (--345---) Special sign
+ 65 41 (1-----7-) A
+ 66 42 (12----7-) B
+ 67 43 (1--4--7-) C
+ 68 44 (1--45-7-) D
+ 69 45 (1---5-7-) E
+ 70 46 (12-4--7-) F
+ 71 47 (12-45-7-) G
+ 72 48 (12--5-7-) H
+ 73 49 (-2-4--7-) I
+ 74 4A (-2-45-7-) j
+ 75 4B (1-3---7-) K
+ 76 4C (123---7-) L
+ 77 4D (1-34--7-) M
+ 78 4E (1-345-7-) N
+ 79 4F (1-3-5-7-) O
+ 80 50 (1234--7-) P
+ 81 51 (12345-7-) Q
+ 82 52 (123-5-7-) R
+ 83 53 (-234--7-) S
+ 84 54 (-2345-7-) T
+ 85 55 (1-3--67-) U
+ 86 56 (123--67-) V
+ 87 57 (-2-4567-) W
+ 88 58 (1-34-67-) X
+ 89 59 (1-34567-) Y
+ 90 5A (1-3-567-) Z
+ 91 5B (123-567-) [ or A umlaut
+ 92 5C (--34--7-) \ or umlaut O
+ 93 5D (-234567-) ] or umlaut U
+ 94 5E (-234-67-) ^ or tilde
+ 95 5F (---456--) _
+ 96 60 (--345--8) '
+ 97 61 (1-------) a
+ 98 62 (12------) b
+ 99 63 (1--4----) c
+ 100 64 (1--45---) d
+ 101 65 (1---5---) e
+ 102 66 (12-4----) f
+ 103 67 (12-45---) g
+ 104 68 (12--5---) h
+ 105 69 (-2-4----) i
+ 106 6A (-2-45---) j
+ 107 6B (1-3-----) k
+ 108 6C (123-----) l
+ 109 6D (1-34----) m
+ 110 6E (1-345---) n
+ 111 6F (1-3-5---) o
+ 112 70 (1234----) p
+ 113 71 (12345---) q
+ 114 72 (123-5---) r
+ 115 73 (-234----) s
+ 116 74 (-2345---) t
+ 117 75 (1-3--6--) u
+ 118 76 (123--6--) v
+ 119 77 (-2-456--) w
+ 120 78 (1-34-6--) x
+ 121 79 (1-3456--) y
+ 122 7A (1-3-56--) z
+ 123 7B (123-56--) { or umlaut a
+ 124 7C (--34----) | or umlaut o
+ 125 7D (-23456--) } or umlaut u
+ 126 7E (-234-6--) '
+ 127 7F (---456-8) DEL
+ 128 80 (1234-67-) C Cedilla (upper case)
+ 129 81 (12-456--) u Umlaut (lower case)
+ 130 82 (123456-8) e Acute (lower case)
+ 131 83 (1----6-8) a Circumflex
+ 132 84 (123-56--) a Umlaut (lower case)
+ 133 85 (123-56-8) a Grave
+ 134 86 (-2-----8) a Ring (lower case)
+ 135 87 (1234-6-8) c Cedilla (lower case)
+ 136 88 (12---6-8) e Circumflex
+ 137 89 (12-4-6-8) e Umlaut (lower case)
+ 138 8A (-234-6-8) e Grave
+ 139 8B (12-456-8) i Umlaut (lower case)
+ 140 8C (1--4-6-8) i Circumflex
+ 141 8D (-2-4---8) I Grave
+ 142 8E (123-567-) A Umlaut (upper case)
+ 143 8F (1----67-) A Ring (upper case)
+ 144 90 (1234567-) E Acute (upper case)
+ 145 91 (123-56--) ae Digraph (lower case)
+ 146 92 (123-567-) AE Digraph (upper case)
+ 147 93 (1--456-8) o Circumflex
+ 148 94 (--34----) o Umlaut (lower case)
+ 149 95 (--34-6-8) o Grave
+ 150 96 (1---56-8) u Circumflex
+ 151 97 (-23456-8) u Grave
+ 152 98 (1-3456-8) y Umlaut
+ 153 99 (--34--7-) O Umlaut (upper case)
+ 154 9A (-234567-) U Umlaut (upper case)
+ 155 9B (-23-5678) Cent
+ 156 9C (----56-8) Pound/Sterling
+ 157 9D (-2--5678) Yen
+ 158 9E (-23-5--8) Peseta
+ 159 9F (12-4---8) Franc
+ 160 A0 (-23--678) a Acute (lower case)
+ 161 Al (----5-7-) i Acute (lower case)
+ 162 A2 (----5-78) o Acute (lower case)
+ 163 A3 (--3-5678) u Acute (lower case)
+ 164 A4 (1-345--8) n Tilde (lower case)
+ 165 A5 (--345-7-) N Tilde (upper case)
+ 166 A6 (1------8) Feminine Spanish Ordinal
+ 167 A7 (1-3-5--8) Masculine Spanish Ordinal
+ 168 A8 (--3----8) Inverted Question Mark
+ 169 A9 (--3--67-) Left square corner
+ 170 AA (--3--6-8) Right square corner
+ 171 AB (-23----8) 1/2
+ 172 AC (-2--56-8) 1/4
+ 173 AD (----5--8) Inverted Exclamation Mark
+ 174 AE (--3----8) Left Double Guillemet
+ 175 AF (--3---7-) Right Double Guillemet
+ 176 B0 (--34-67-) Box [Shade 1]
+ 177 B1 (---4-678) Box [Shade 2]
+ 178 B2 (12---67-) Box [Shade 3]
+ 179 B3 (1--4-67-) Box [top bottom]
+ 180 B4 (1--4567-) Box [left top bottom]
+ 181 B5 (1---567-) Box [LEFT top bottom]
+ 182 B6 (12-4-67-) Box [left TOP BOTTOM]
+ 183 B7 (12-4567-) Box [left BOTTOM]
+ 184 B8 (12--567-) Box [LEFT bottom]
+ 185 B9 (-2-4-67-) Box [LEFT TOP BOTTOM]
+ 186 BA (-2--5-7-) Box [TOP BOTTOM]
+ 187 BB (-23---7-) Box [LEFT BOTTOM]
+ 188 BC (----567-) Box [LEFT TOP]
+ 189 BD (-23-567-) Box [left TOP]
+ 190 BE (---45-7-) Box [LEFT top]
+ 191 BF (-2---67-) Box [left bottom]
+ 192 CO (--345--8) Box [top right]
+ 193 C1 (--3---78) Box [left top right]
+ 194 C2 (1--45678) Box [left right bottom]
+ 195 C3 (-2-4-678) Box [top right bottom]
+ 196 C4 (1--45--8) Box [left right]
+ 197 C5 (1---5--8) Box [left top right bottom]
+ 198 C6 (-2--5-78) Box [top RIGHT bottom]
+ 199 C7 (12-45--8) Box [TOP right BOTTOM]
+ 200 C8 (------78) Box [TOP RIGHT]
+ 201 C9 (-2--5--8) Box [RIGHT BOTTOM]
+ 202 CA (-2-45--8) Box [LEFT TOP RIGHT]
+ 203 CB (1-3----8) Box [LEFT RIGHT BOTTOM]
+ 204 CC (123----8) Box [TOP RIGHT BOTTOM]
+ 205 CD (1-34---8) Box [LEFT RIGHT]
+ 206 CE (---4--78) Box [LEFT TOP RIGHT BOTTOM]
+ 207 CF (--345678) Box [LEFT top RIGHT]
+ 208 DO (123----8) Box [left TOP right]
+ 209 D1 (12345--8) Box [LEFT RIGHT bottom]
+ 210 D2 (123-5--8) Box [left right BOTTOM]
+ 211 D3 (-234---8) Box [TOP right]
+ 212 D4 (-2345--8) Box [top RIGHT]
+ 213 D5 (1-3--6-8) Box [RIGHT bottom]
+ 214 D6 (123--6-8) Box [right BOTTOM]
+ 215 D7 (-2-456-8) Box [left TOP right BOTTOM]
+ 216 D8 (1-34-6-8) Box [LEFT top RIGHT bottom]
+ 217 D9 (12345678) Box [left top]
+ 218 DA (1-3-56-8) Box [right bottom]
+ 219 DB (-----678) Box [Shade 4]
+ 220 DC (--34-678) Box [box bottom]
+ 221 DD (1234-678) Box [box right]
+ 222 DE (--3-5-78) Box [box left]
+ 223 DF (---4567-) Box [box top]
+ 224 E0 (------7-) Alpha (lower case)
+ 225 E1 (-234-6--) Beta (lower case)
+ 226 E2 (-23-5-78) Gamma (upper case)
+ 227 E3 (-23-5-7-) Pi (lower case)
+ 228 E4 (---4-6-8) Sigma (upper case)
+ 229 E5 (-2----78) Sigma (lower case)
+ 230 E6 (--3--678) Mu (lower case)
+ 231 E7 (-----6-8) Tau (lower case)
+ 232 E8 (-23--6-8) Phi (upper case)
+ 233 E9 (--3-56-8) Theta (lower case)
+ 234 EA (--3-5--8) Omega (upper case)
+ 235 EB (1----678) Delta (lower case)
+ 236 EC (12---678) infinity
+ 237 ED (1--4-678) Phi (lower case)
+ 238 EE (1---5678) Epsilon (lower case)
+ 239 EF (12-4-678) Intersection
+ 240 F0 (12-45678) Equivalent (Member)
+ 241 F1 (12--5678) Plus or minus
+ 242 F2 (------7-) Greater than or equal
+ 243 F3 (--34567-) Less than or equal
+ 244 F4 (---4-67-) Integral [top]
+ 245 F5 (-23---78) Integral [bottom]
+ 246 F6 (-----67-) Division
+ 247 F7 (-23--67-) Approximately equal
+ 248 F8 (12--56-8) Small circle
+ 249 F9 (-2-4-6-8) Bullet
+ 250 FA (-2--5--8) Small bullet
+ 251 FB (--3-567-) Bent Radical
+ 252 FC (----56-8) Power of n
+ 253 FD (-23-56-8) Power of 2
+ 254 FE (---45--8) Large square bullet
+ 255 FF (-2---6-8) blank (hard space)
diff --git a/etc/gs-braille.tbl b/etc/gs-braille.tbl
new file mode 100644
index 0000000..0c5ef9b
--- /dev/null
+++ b/etc/gs-braille.tbl
@@ -0,0 +1,261 @@
+# GS BRAILLE TABLE
+#
+# Dec Hex Braille Description
+# ------------------------------------------------------------------------
+ 0 0 (--------) NUL
+ 1 1 (--------) SOH
+ 2 2 (--------) STX
+ 3 3 (--------) ETX
+ 4 4 (--------) EOT
+ 5 5 (--------) ENQ
+ 6 6 (--------) ACK
+ 7 7 (--------) BEL
+ 8 8 (--------) BS
+ 9 9 (--------) HT
+ 10 A (--------) LF
+ 11 B (--------) VT
+ 12 C (--------) FF
+ 13 D (--------) CR
+ 14 E (--------) SO
+ 15 F (--------) SI
+ 16 10 (--------) DLE
+ 17 11 (--------) DC1
+ 18 12 (--------) DC2
+ 19 13 (--------) DC3
+ 20 14 (--------) DC4
+ 21 15 (--------) NAK
+ 22 16 (--------) SYN
+ 23 17 (--------) ETB
+ 24 18 (--------) CAN
+ 25 19 (--------) EM
+ 26 1A (--------) SUB
+ 27 1B (--------) ESC
+ 28 1C (--------) FS
+ 29 1D (--------) GS
+ 30 1E (--------) RS
+ 31 1F (--------) US
+ 32 20 (--------) space
+ 33 21 (-23-5---) bang
+ 34 22 (--3--678) unidirectional double quote
+ 35 23 (----5678) # (number or hash) symbol
+ 36 24 (--34567-) $
+ 37 25 (--34---8) % symbol
+ 38 26 (-23-5-78) & symbol
+ 39 27 (--3-----) apostrophe
+ 40 28 (-23----8) left parenthesis symbol
+ 41 29 (----567-) right parenthesis symbol
+ 42 2A (--34--7-) asterisk
+ 43 2B (-2--5-7-) plus symbol
+ 44 2C (-2------) comma
+ 45 2D (--3--6--) dash, also used as over/under bar.
+ 46 2E (-2--56--) period, decimal point
+ 47 2F (--34--78) / symbol
+ 48 30 (-2-45-78) zero
+ 49 31 (1-----78) one
+ 50 32 (12----78) two
+ 51 33 (1--4--78) three
+ 52 34 (1--45-78) four
+ 53 35 (1---5-78) five
+ 54 36 (12-4--78) six
+ 55 37 (12-45-78) seven
+ 56 38 (12--5-78) eight
+ 57 39 (-2-4--78) nine
+ 58 3A (-2--5---) colon
+ 59 3B (-23-----) semicolon
+ 60 3C (1234567-) open angle bracket
+ 61 3D (-2--5-78) equals symbol
+ 62 3E (123456-8) close angle bracket
+ 63 3F (-23--6--) question mark
+ 64 40 (--345-78) @ sign
+ 65 41 (1-----7-) A
+ 66 42 (12----7-) B
+ 67 43 (1--4--7-) C
+ 68 44 (1--45-7-) D
+ 69 45 (1---5-7-) E
+ 70 46 (12-4--7-) F
+ 71 47 (12-45-7-) G
+ 72 48 (12--5-7-) H
+ 73 49 (-2-4--7-) I
+ 74 4A (-2-45-7-) J
+ 75 4B (1-3---7-) K
+ 76 4C (123---7-) L
+ 77 4D (1-34--7-) M
+ 78 4E (1-345-7-) N
+ 79 4F (1-3-5-7-) O
+ 80 50 (1234--7-) P
+ 81 51 (12345-7-) Q
+ 82 52 (123-5-7-) R
+ 83 53 (-234--7-) S
+ 84 54 (-2345-7-) T
+ 85 55 (1-3--67-) U
+ 86 56 (123--67-) V
+ 87 57 (-2-4567-) W
+ 88 58 (1-34-67-) X
+ 89 59 (1-34567-) Y
+ 90 5A (1-3-567-) Z
+ 91 5B (-23--678) [ symbol
+ 92 5C (1----678) \ symbol
+ 93 5D (--3-5678) ] symbol
+ 94 5E (--345-7-) ^
+ 95 5F (-2---6-8) _
+ 96 60 (--3----8) opening single quote
+ 97 61 (1-------) a
+ 98 62 (12------) b
+ 99 63 (1--4----) c
+ 100 64 (1--45---) d
+ 101 65 (1---5---) e
+ 102 66 (12-4----) f
+ 103 67 (12-45---) g
+ 104 68 (12--5---) h
+ 105 69 (-2-4----) i
+ 106 6A (-2-45---) j
+ 107 6B (1-3-----) k
+ 108 6C (123-----) l
+ 109 6D (1-34----) m
+ 110 6E (1-345---) n
+ 111 6F (1-3-5---) o
+ 112 70 (1234----) p
+ 113 71 (12345---) q
+ 114 72 (123-5---) r
+ 115 73 (-234----) s
+ 116 74 (-2345---) t
+ 117 75 (1-3--6--) u
+ 118 76 (123--6--) v
+ 119 77 (-2-456--) w
+ 120 78 (1-34-6--) x
+ 121 79 (1-3456--) y
+ 122 7A (1-3-56--) z
+ 123 7B (123-5678) { symbol
+ 124 7C (--34-678) |
+ 125 7D (-2345678) } symbol
+ 126 7E (--34-67-) ~
+ 127 7F (1--4-678) del, nabla sign
+ 128 80 (--3-5-7-) negative power indicator
+ 129 81 (--34-67-) ~
+ 130 82 (--3---78) opening double quote
+ 131 83 (--34----) complex fraction line indicator
+ 132 84 (--3-5-78) left superscript
+ 133 85 (--345678) start extended math mode
+ 134 86 (-23---7-) end of line in 2-D array
+ 135 87 (-23--67-) right arrow sign
+ 136 88 (-23-567-) proportional to sign
+ 137 89 (-23---78) ` (grave accent)
+ 138 8A (-234-678) integral sign
+ 139 8B (-23-5678) identically equals sign
+ 140 8C (--3-5--8) < (less) symbol
+ 141 8D (-2---67-) > (greater) symbol
+ 142 8E (123--678) end extended math mode.
+ 143 8F (12345678) infinity sign
+ 144 90 (1--4-6--) overscript indicator
+ 145 91 (1---56--) slashed symbol or NOT indicator
+ 146 92 (1--456--) function indicator
+ 147 93 (---45-7-) bold symbol indicator
+ 148 94 (---4-67-) italic symbol indicator
+ 149 95 (---4567-) special (text default=underlined) symbol indicator
+ 150 96 (------78) minus sign
+ 151 97 (---4--78) gothic font symbol indicator
+ 152 98 (----5-78) divide by sign
+ 153 99 (---45-78) special font 1 symbol indicator
+ 154 9A (-----678) closing double quote
+ 155 9B (---4-678) special font 2 symbol indicator
+ 156 9C (---45678) special font 3 symbol indicator
+ 157 9D (-2----78) times cross sign
+ 158 9E (-2---678) left subscript
+ 159 9F (--3---7-) end of element in 2-D array
+ 160 A0 (-2-4-6--) radical indicator
+ 161 A1 (-----67-) closing single quote
+ 162 A2 (----5---) In 8 dot code in shapes and as a soft hyphen.
+ 163 A3 (---45---) To be used for foreign indicators and/or phonetic indicators.
+ 164 A4 (-----6--) 04 never appears in 8 dot code except shapes.
+ 165 A5 (---4-6--) 05 never appears in 8 dot code except shapes.
+ 166 A6 (----56--) grade 1 indicator in both codes.
+ 167 A7 (---456--) Converts upper cell to cell + dot-67, other root to root + dot-78.
+ 168 A8 (-------8) Under user control can indicate hyperlinks or font enhancements or...
+ 169 A9 (---4---8) start shape beginning with 01 and ending at first root cell
+ 170 AA (----5--8) start shape beginning with 02
+ 171 AB (---45--8) start shape beginning with 03
+ 172 AC (-----6-8) start shape beginning with 04
+ 173 AD (---4-6-8) start shape beginning with 05
+ 174 AE (----56-8) start shape beginning with 06
+ 175 AF (---456-8) start shape beginning with 07
+ 176 B0 (1--4---8) Copyright sign
+ 177 B1 (1--4-6-8) partial differential sign
+ 178 B2 (-2---6--) subscript indicator
+ 179 B3 (1------8) alpha
+ 180 B4 (12-----8) beta
+ 181 B5 (12-45--8) gamma
+ 182 B6 (1--45--8) delta
+ 183 B7 (1---5--8) epsilon
+ 184 B8 (1-3-56-8) zeta
+ 185 B9 (1---56-8) eta
+ 186 BA (1--456-8) theta
+ 187 BB (-2-4---8) iota
+ 188 BC (1-3----8) kappa
+ 189 BD (123----8) lambda
+ 190 BE (1-34---8) mu
+ 191 BF (1-345--8) nu
+ 192 C0 (1-34-6-8) xi
+ 193 C1 (1-3-5--8) omichron
+ 194 C2 (1234---8) pi
+ 195 C3 (123-5--8) rho
+ 196 C4 (-234---8) sigma
+ 197 C5 (-2345--8) tau
+ 198 C6 (1-3--6-8) upsilon
+ 199 C7 (12-4---8) phi
+ 200 C8 (1234-6-8) chi
+ 201 C9 (1-3456-8) psi
+ 202 CA (-2-456-8) omega
+ 203 CB (1----67-) cap Alpha
+ 204 CC (12---67-) cap Beta
+ 205 CD (12-4567-) cap Gamma
+ 206 CE (1--4567-) cap Delta
+ 207 CF (1---567-) cap Epsilon
+ 208 D0 (1-3-5678) cap zeta
+ 209 D1 (1---5678) cap Eta
+ 210 D2 (1--45678) cap Theta
+ 211 D3 (-2-4-67-) cap Iota
+ 212 D4 (1-3---78) cap kappa
+ 213 D5 (123---78) cap lambda
+ 214 D6 (1-34--78) cap mu
+ 215 D7 (1-345-78) cap nu
+ 216 D8 (1-34-678) cap xi
+ 217 D9 (1-3-5-78) cap omichron
+ 218 DA (1234--78) cap pi
+ 219 DB (123-5-78) cap rho
+ 220 DC (-234--78) cap sigma
+ 221 DD (-2345-78) cap tau
+ 222 DE (1-3--678) cap upsilon
+ 223 DF (12-4-67-) cap Phi
+ 224 E0 (1234-678) cap chi
+ 225 E1 (1-345678) cap psi
+ 226 E2 (-2-45678) cap omega
+ 227 E3 (-2--5--8) times dot sign
+ 228 E4 (-2-45--8) small circle sign
+ 229 E5 (-2-4-6-8) radical sign, not operator
+ 230 E6 (12---6--) open braille bracket
+ 231 E7 (12-4-6--) horizontal combination symbol indicator
+ 232 E8 (12--56--) vertical stack symbol indicator
+ 233 E9 (12-456--) superimposed combination symbol indicator
+ 234 EA (12--56-8) absolute value bar sign
+ 235 EB (--3-5---) superscript indicator
+ 236 EC (--345---) close braille bracket
+ 237 ED (--34-6--) underscript indicator
+ 238 EE (--3-56--) start math word indicator
+ 239 EF (--3456--) Number indicator (6 dot code)
+ 240 F0 (---4----) Accent mark
+ 241 F1 (--3--6-8) ellipses sign
+ 242 F2 (--34-6-8) dagger, transpose sign
+ 243 F3 (--3-56-8) left arrow sign
+ 244 F4 (--3456-8) UK pound
+ 245 F5 (-234-6--) two dimensional array indicator
+ 246 F6 (1----6--) simple fraction line indicator
+ 247 F7 (-23-56--) contraction indicator.
+ 248 F8 (-23456--) close fraction indicator
+ 249 F9 (-234-6-8) end of two dimensional array
+ 250 FA (-23-56-8) approximately equals sign, single tilde over single bar.
+ 251 FB (1234-6--) Large symbol indicator.
+ 252 FC (123-56--) open fraction indicator
+ 253 FD (123456--) quantity indicator
+ 254 FE (------7-) prime mark
+ 255 FF (---4--7-) script font symbol indicator
+
diff --git a/etc/newsyntax38 b/etc/newsyntax38
new file mode 100755
index 0000000..b22850d
--- /dev/null
+++ b/etc/newsyntax38
@@ -0,0 +1,71 @@
+#! /bin/sh
+#
+# newsyntax38 -- update a screenrc file from 3.3 to 3.8 syntax
+#
+# Please bring your scripts up to syntax level 3.3 before running this script.
+# Please check all comments after running this script and watch out
+# for funny passages.
+#
+# * aka and shellaka are replaced by title and shelltitle.
+#
+# * Pairs of termcap and terminfo commands are folded into a single
+# termcapinfo command where possible.
+#
+# * trailing blanks are zapped. Unintentionally.
+#
+# 12.10.95, jnweiger, use at your own risk.
+#
+if [ $# != 1 ]; then
+ echo "usage $0 screenrcfile"
+ echo ""
+ echo "The named file will be updated in place to the syntax of screen 3.8"
+ echo "A backup copy will be written to <screenrcfile>.bak"
+ exit 1;
+fi
+
+#Ultrix 4.2 /bin/sh does not handle "read a < $1"
+#Dean Gaudet <dgaudet@watdragon.uwaterloo.ca>
+exec < $1
+read a
+
+if [ "$a" = "#3.8" ]; then
+ echo "$1 already updated"
+ exit 0
+fi
+
+rm -f $1.old $1.dups
+
+cp $1 $1.old
+echo "#3.8" > $1
+echo "# Do not remove the above line. This screen rc file was updated" >> $1
+echo "# by the newsyntax script." >> $1
+
+# termcap and terminfo lines can only be folded when there is no parameter
+# expansion in the codes. Parameters are denoted differently in
+# termcap and termcap syntax. Everything else is identical, I assume.
+# Thus codes not containing '%' can be savely folded.
+
+sed < $1.old > $1.dups \
+-e 's/^\([ #]*\)aka/\1title/' \
+-e 's/^\([ #]*\)shellaka/\1shelltitle/' \
+-e 's/^\([ #]*\)termcap[ ][ ]*\([^%]*$\)/\1termcapinfo \2/' \
+-e 's/^\([ #]*\)terminfo[ ][ ]*\([^%]*$\)/\1termcapinfo \2/' \
+-e 's/\\/\\\\/g'
+
+# Oh, my bourne shell seems to gobble backslashes while reading.
+# Thus the sed above duplicates them in advance.
+# Hope this is not just another silly bash featureism.
+# It still zaps trailing blanks. I do not know why. But that is nice.
+
+exec < $1.dups
+while read a ; do
+ if [ "$a" = "$b" ]; then
+ case "$a" in
+ *termcapinfo*) continue ;;
+ esac
+ fi
+ echo "$a" >> $1
+ b="$a"
+done
+
+rm -f $1.dups
diff --git a/etc/screenrc b/etc/screenrc
index 76fc888..c718364 100644
--- a/etc/screenrc
+++ b/etc/screenrc
@@ -28,7 +28,7 @@ pow_detach_msg "Screen session of \$LOGNAME \$:cr:\$:nl:ended."
# shellaka '$ |sh'
# set every new windows hardstatus line to somenthing descriptive
-# defhstatus "screen: ^E (^Et)"
+# defhstatus "screen: ^En (^Et)"
defscrollback 1000
@@ -60,11 +60,7 @@ termcapinfo xterm 'k1=\E[11~:k2=\E[12~:k3=\E[13~:k4=\E[14~'
termcapinfo xterm 'kh=\E[1~:kI=\E[2~:kD=\E[3~:kH=\E[4~:kP=\E[H:kN=\E[6~'
# special xterm hardstatus: use the window title.
-termcapinfo xterm 'hs:ts=\E]2;:fs=\007:ds=\E]0;screen\007'
-
-# our xterm has colors! (rxvt, too)
-termcap xterm 'AF=\E[3%dm:AB=\E[4%dm'
-terminfo xterm 'AF=\E[3%p1%dm:AB=\E[4%p1%dm'
+termcapinfo xterm 'hs:ts=\E]2;:fs=\007:ds=\E]2;screen\007'
#terminfo xterm 'vb=\E[?5h$<200/>\E[?5l'
termcapinfo xterm 'vi=\E[?25l:ve=\E[34h\E[?25h:vs=\E[34l'
@@ -72,6 +68,10 @@ termcapinfo xterm 'vi=\E[?25l:ve=\E[34h\E[?25h:vs=\E[34l'
# emulate part of the 'K' charset
termcapinfo xterm 'XC=K%,%\E(B,[\304,\\\\\326,]\334,{\344,|\366,}\374,~\337'
+# xterm-52 tweaks:
+# - uses background color for delete operations
+termcapinfo xterm ut
+
################
#
# wyse terminals
@@ -111,7 +111,6 @@ bind \\
bind ^h
bind h
#make them better
-bind '\\' quit
bind 'K' kill
bind 'I' login on
bind 'O' login off
@@ -132,3 +131,8 @@ bind ^] paste [.]
# screen -t local 0
# screen -t mail 1 elm
# screen -t 40 2 rlogin faui40
+
+# caption always "%3n %t%? @%u%?%? [%h]%?"
+# hardstatus alwaysignore
+# hardstatus alwayslastline "%w"
+
diff --git a/etc/us-braille.tbl b/etc/us-braille.tbl
new file mode 100644
index 0000000..640f62f
--- /dev/null
+++ b/etc/us-braille.tbl
@@ -0,0 +1,260 @@
+# U.S. BRAILLE TABLE
+#
+# Dec Hex Braille Description
+# ------------------------------------------------------------------------
+ 0 00 (---4--78) NUL
+ 1 01 (1-----78) SOH
+ 2 02 (12----78) STX
+ 3 03 (1--4--78) ETX
+ 4 04 (1--45-78) EOT
+ 5 05 (1---5-78) ENQ
+ 6 06 (12-4--78) ACK
+ 7 07 (12-45-78) BEL
+ 8 08 (12--5-78) BS
+ 9 09 (-2-4--78) HT
+ 10 OA (-2-45-78) LF
+ 11 0B (1-3---78) VT
+ 12 OC (123---78) FF
+ 13 0D (1-34--78) CR
+ 14 0E (1-345-78) SO
+ 15 OF (1-3-5-78) SI
+ 16 10 (1234--78) DLE
+ 17 11 (12345-78) DC1
+ 18 12 (123-5-78) DC2
+ 19 13 (-234--78) DC3
+ 20 14 (-2345-78) DC4
+ 21 15 (1-3--678) NAK
+ 22 16 (123--678) SYN
+ 23 17 (-2-45678) ETB
+ 24 18 (1-34-678) CAN
+ 25 19 (1-345678) EM
+ 26 1A (1-3-5678) SUB
+ 27 lB (-2-4-678) ESC
+ 28 lC (12--5678) FS
+ 29 1D (12-45678) GS
+ 30 lE (---45-78) RS
+ 31 1F (---45678) US
+ 32 20 (--------) Space
+ 33 21 (-234-6--) !
+ 34 22 (----5---) "
+ 35 23 (--3456--) #
+ 36 24 (12-4-6--) $
+ 37 25 (1--4-6--) %
+ 38 26 (1234-6--) &
+ 39 27 (--3-----) '
+ 40 28 (123-56--) (
+ 41 29 (-23456--) )
+ 42 2A (1----6--) *
+ 43 2B (--34-6--) +
+ 44 2C (-----6--) ,
+ 45 2D (--3--6--) -
+ 46 2E (---4-6--) .
+ 47 2F (--34----) /
+ 48 30 (--3-56--) 0
+ 49 31 (-2------) 1
+ 50 32 (-23-----) 2
+ 51 33 (-2--5---) 3
+ 52 34 (-2--56--) 4
+ 53 35 (-2---6--) 5
+ 54 36 (-23-5---) 6
+ 55 37 (-23-56--) 7
+ 56 38 (-23--6--) 8
+ 57 39 (--3-5---) 9
+ 58 3A (1---56--) :
+ 59 3B (----56--) ;
+ 60 3C (12---6--) <
+ 61 3D (123456--) -
+ 62 3E (--345---) >
+ 63 3F (1--456--) ?
+ 64 40 (---4--7-) @
+ 65 41 (1-----7-) A
+ 66 42 (12----7-) B
+ 67 43 (1--4--7-) C
+ 68 44 (1--45-7-) D
+ 69 45 (1---5-7-) E
+ 70 46 (12-4--7-) F
+ 71 47 (12-45-7-) G
+ 72 48 (12--5-7-) H
+ 73 49 (-2-4--7-) I
+ 74 4A (-2-45-7-) J
+ 75 4B (1-3---7-) K
+ 76 4C (123---7-) L
+ 77 4D (1-34--7-) M
+ 78 4E (1-345-7-) N
+ 79 4F (1-3-5-7-) O
+ 80 50 (1234--7-) P
+ 81 51 (12345-7-) Q
+ 82 52 (123-5-7-) R
+ 83 53 (-234--7-) S
+ 84 54 (-2345-7-) T
+ 85 55 (1-3--67-) U
+ 86 56 (123--67-) V
+ 87 57 (-2-4567-) W
+ 88 58 (1-34-67-) X
+ 89 59 (1-34567-) Y
+ 90 5A (1-3-567-) Z
+ 91 5B (-2-4-67-) [
+ 92 5C (12--567-) \
+ 93 5D (12-4567-) ]
+ 94 5E (---45-7-) ^
+ 95 5F (---4567-) _
+ 96 60 (---4----) '
+ 97 61 (1-------) a
+ 98 62 (12------) b
+ 99 63 (1--4----) c
+ 100 64 (1--45---) d
+ 101 65 (1---5---) e
+ 102 66 (12-4----) f
+ 103 67 (12-45---) g
+ 104 68 (12--5---) h
+ 105 69 (-2-4----) i
+ 106 6A (-2-45---) j
+ 107 6B (1-3-----) k
+ 108 6C (123-----) l
+ 109 6D (1-34----) m
+ 110 6E (1-345---) n
+ 111 6F (1-3-5---) o
+ 112 70 (1234----) p
+ 113 71 (12345---) q
+ 114 72 (123-5---) r
+ 115 73 (-234----) s
+ 116 74 (-2345---) t
+ 117 75 (1-3--6--) u
+ 118 76 (123--6--) v
+ 119 77 (-2-456--) w
+ 120 78 (1-34-6--) x
+ 121 79 (1-3456--) y
+ 122 7A (1-3-56--) z
+ 123 7B (-2-4-6--) {
+ 124 7C (12--56--) |
+ 125 7D (12-456--) }
+ 126 7E (---45---) ~
+ 127 7F (---456--) DEL
+ 128 80 (---4---8) C Cedilla (upper case)
+ 129 81 (1------8) u Umlaut (lower case)
+ 130 82 (12-----8) e Acute (lower case)
+ 131 83 (1--4---8) a Circumflex
+ 132 84 (1--45--8) a Umlaut (lower case)
+ 133 85 (1---5--8) a Grave
+ 134 86 (12-4---8) a Ring (lower case)
+ 135 87 (12-45--8) c Cedilla (lower case)
+ 136 88 (12--5--8) e Circumflex
+ 137 89 (-2-4---8) e Umlaut (lower case)
+ 138 8A (--2-45-8) e Grave
+ 139 8B (1-3----8) i Umlaut (lower case)
+ 140 8C (123----8) i Circumflex
+ 141 8D (1-34---8) I Grave
+ 142 8E (1-345--8) A Umlaut (upper case)
+ 143 8F (1-3-5--8) A Ring (upper case)
+ 144 90 (1234---8) E Acute (upper case)
+ 145 91 (12345--8) ae Digraph (lower case)
+ 146 92 (123-5--8) AE Digraph (upper case)
+ 147 93 (-234---8) o Circumflex
+ 148 94 (-2345--8) o Umlaut (lower case)
+ 149 95 (1-3--6-8) o Grave
+ 150 96 (123--6-8) u Circumflex
+ 151 97 (-2-456-8) u Grave
+ 152 98 (1-34-6-8) y Umlaut
+ 153 99 (1-3456-8) O Umlaut (upper case)
+ 154 9A (1-3-56-8) U Umlaut (upper case)
+ 155 9B (-2-4-6-8) Cent
+ 156 9C (12--56-8) Pound/Sterling
+ 157 9D (12-456-8) Yen
+ 158 9E (---45--8) Peseta
+ 159 9F (---456-8) Franc
+ 160 A0 (------7-) a Acute (lower case)
+ 161 Al (-234-67-) i Acute (lower case)
+ 162 A2 (----5-7-) o Acute (lower case)
+ 163 A3 (--34567-) u Acute (lower case)
+ 164 A4 (12-4-67-) n Tilde (lower case)
+ 165 A5 (1--4-67-) N Tilde (upper case)
+ 166 A6 (1234-67-) Feminine Spanish Ordinal
+ 167 A7 (--3---7-) Masculine Spanish Ordinal
+ 168 A8 (123-567-) Inverted Question Mark
+ 169 A9 (-234567-) Left square corner
+ 170 AA (1----67-) Right square corner
+ 171 AB (--34-67-) 1/2
+ 172 AC (-----67-) 1/4
+ 173 AD (--3--67-) Inverted Exclamation Mark
+ 174 AE (---4-67-) Left Double Guillemet
+ 175 AF (--34--7-) Right Double Guillemet
+ 176 B0 (--3-567-) Box [Shade 1]
+ 177 B1 (-2----7-) Box [Shade 2]
+ 178 B2 (-23---7-) Box [Shade 3]
+ 179 B3 (-2--5-7-) Box [top bottom]
+ 180 B4 (-2--567-) Box [left top bottom]
+ 181 B5 (-2---67-) Box [LEFT top bottom]
+ 182 B6 (-23-5-7-) Box [left TOP BOTTOM]
+ 183 B7 (-23-567-) Box [left BOTTOM]
+ 184 B8 (-23--67-) Box [LEFT bottom]
+ 185 B9 (--3-5-7-) Box [LEFT TOP BOTTOM]
+ 186 BA (1---567-) Box [TOP BOTTOM]
+ 187 BB (----567-) Box [LEFT BOTTOM]
+ 188 BC (12---67-) Box [LEFT TOP]
+ 189 BD (1234567-) Box [left TOP]
+ 190 BE (--345-7-) Box [LEFT top]
+ 191 BF (1--4567-) Box [left bottom]
+ 192 CO (------78) Box [top right]
+ 193 C1 (-234-678) Box [left top right]
+ 194 C2 (----5-78) Box [left right bottom]
+ 195 C3 (--345678) Box [top right bottom]
+ 196 C4 (12-4-678) Box [left right]
+ 197 C5 (1--4-678) Box [left top right bottom]
+ 198 C6 (1234-678) Box [top RIGHT bottom]
+ 199 C7 (--3---78) Box [TOP right BOTTOM]
+ 200 C8 (123-5678) Box [TOP RIGHT]
+ 201 C9 (-2345678) Box [RIGHT BOTTOM]
+ 202 CA (1----678) Box [LEFT TOP RIGHT]
+ 203 CB (--34-678) Box [LEFT RIGHT BOTTOM]
+ 204 CC (-----678) Box [TOP RIGHT BOTTOM]
+ 205 CD (--3--678) Box [LEFT RIGHT]
+ 206 CE (---4-678) Box [LEFT TOP RIGHT BOTTOM]
+ 207 CF (--34--78) Box [LEFT top RIGHT]
+ 208 DO (--3-5678) Box [left TOP right]
+ 209 D1 (-2----78) Box [LEFT RIGHT bottom]
+ 210 D2 (-23---78) Box [left right BOTTOM]
+ 211 D3 (-2--5-78) Box [TOP right]
+ 212 D4 (-2--5678) Box [top RIGHT]
+ 213 D5 (-2---678) Box [RIGHT bottom]
+ 214 D6 (-23-5-78) Box [right BOTTOM]
+ 215 D7 (-23-5678) Box [left TOP right BOTTOM]
+ 216 D8 (-23--678) Box [LEFT top RIGHT bottom]
+ 217 D9 (--3-5-78) Box [left top]
+ 218 DA (1---5678) Box [right bottom]
+ 219 DB (----5678) Box [Shade 4]
+ 220 DC (12---678) Box [box bottom]
+ 221 DD (12345678) Box [box right]
+ 222 DE (--345-78) Box [box left]
+ 223 DF (1--45678) Box [box top]
+ 224 E0 (-------8) Alpha (lower case)
+ 225 E1 (-234-6-8) Beta (lower case)
+ 226 E2 (----5--8) Gamma (upper case)
+ 227 E3 (--3456-8) Pi (lower case)
+ 228 E4 (12-4-6-8) Sigma (upper case)
+ 229 E5 (1--4-6-8) Sigma (lower case)
+ 230 E6 (1234-6-8) Mu (lower case)
+ 231 E7 (--3----8) Tau (lower case)
+ 232 E8 (123-56-8) Phi (upper case)
+ 233 E9 (-23456-8) Theta (lower case)
+ 234 EA (1----6-8) Omega (upper case)
+ 235 EB (--34-6-8) Delta (lower case)
+ 236 EC (-----6-8) infinity
+ 237 ED (--3--6-8) Phi (lower case)
+ 238 EE (---4-6-8) Epsilon (lower case)
+ 239 EF (--34---8) Intersection
+ 240 F0 (--3-56-8) Equivalent (Member)
+ 241 F1 (-2-----8) Plus or minus
+ 242 F2 (-23----8) Greater than or equal
+ 243 F3 (-2--5--8) Less than or equal
+ 244 F4 (-2--56-8) Integral [top]
+ 245 F5 (-2---6-8) Integral [bottom]
+ 246 F6 (-23-5--8) Division
+ 247 F7 (-23-56-8) Approximately equal
+ 248 F8 (-23--6-8) Small circle
+ 249 F9 (--3-5--8) Bullet
+ 250 FA (1---56-8) Small bullet
+ 251 FB (----56-8) Bent Radical
+ 252 FC (12---6-8) Power of n
+ 253 FD (123456-8) Power of 2
+ 254 FE (--345--8) Large square bullet
+ 255 FF (1--456-8) blank (hard space)
diff --git a/extern.h b/extern.h
index 61b39a1..6663ad0 100644
--- a/extern.h
+++ b/extern.h
@@ -22,6 +22,10 @@
* $Id: extern.h,v 1.18 1994/05/31 12:31:57 mlschroe Exp $ FAU
*/
+#if !defined(__GNUC__) || __GNUC__ < 2
+#undef __attribute__
+#define __attribute__(x)
+#endif
/* screen.c */
extern int main __P((int, char **));
@@ -30,16 +34,8 @@ extern void eexit __P((int));
extern void Detach __P((int));
extern void Kill __P((int, int));
#ifdef USEVARARGS
-extern void Msg __P((int, char *, ...))
-# if __GNUC__ > 1
-__attribute__ ((format (printf, 2, 3)))
-# endif
-;
-extern void Panic __P((int, char *, ...))
-# if __GNUC__ > 1
-__attribute__ ((format (printf, 2, 3)))
-# endif
-;
+extern void Msg __P((int, char *, ...)) __attribute__((format(printf, 2, 3)));
+extern void Panic __P((int, char *, ...)) __attribute__((format(printf, 2, 3)));
#else
extern void Msg __P(());
extern void Panic __P(());
@@ -48,17 +44,23 @@ extern void DisplaySleep __P((int));
extern void Finit __P((int));
extern void MakeNewEnv __P((void));
extern char *MakeWinMsg __P((char *, struct win *, int));
+extern char *MakeWinMsgEv __P((char *, struct win *, int, struct event *));
+extern void WindowDied __P((struct win *));
/* ansi.c */
-extern void Activate __P((int));
+extern void ResetAnsiState __P((struct win *));
extern void ResetWindow __P((struct win *));
extern void ResetCharsets __P((struct win *));
extern void WriteString __P((struct win *, char *, int));
extern void NewAutoFlow __P((struct win *, int));
-extern void Redisplay __P((int));
-extern void SetCurr __P((struct win *));
+extern void WBell __P((struct win *, int));
extern void ChangeAKA __P((struct win *, char *, int));
extern void SetCharsets __P((struct win *, char *));
+extern int GetAnsiStatus __P((struct win *, char *));
+extern void WMsg __P((struct win *, int, char *));
+extern void WChangeSize __P((struct win *, int, int));
+extern void WindowChanged __P((struct win *, int));
+extern int MFindUsedLine __P((struct win *, int, int));
/* fileio.c */
extern void StartRc __P((char *));
@@ -69,22 +71,27 @@ extern int secopen __P((char *, int, int));
extern void WriteFile __P((int));
extern char *ReadFile __P((char *, int *));
extern void KillBuffers __P((void));
-extern char *expand_vars __P((char *, struct display *));
+extern int printpipe __P((struct win *, char *));
/* tty.c */
-extern int OpenTTY __P((char *));
+extern int OpenTTY __P((char *, char *));
extern void InitTTY __P((struct mode *, int));
extern void GetTTY __P((int, struct mode *));
extern void SetTTY __P((int, struct mode *));
-extern void SetMode __P((struct mode *, struct mode *));
+extern void SetMode __P((struct mode *, struct mode *, int, int));
extern void SetFlow __P((int));
extern void SendBreak __P((struct win *, int, int));
extern int TtyGrabConsole __P((int, int, char *));
+extern char *TtyGetModemStatus __P((int, char *));
#ifdef DEBUG
extern void DebugTTY __P((struct mode *));
#endif /* DEBUG */
extern int fgtty __P((int));
extern void brktty __P((int));
+extern struct baud_values *lookup_baud __P((int bps));
+extern int SetBaud __P((struct mode *, int, int));
+extern int SttyMode __P((struct mode *, char *));
+
/* mark.c */
extern int GetHistory __P((void));
@@ -92,6 +99,8 @@ extern void MarkRoutine __P((void));
extern void revto_line __P((int, int, int));
extern void revto __P((int, int));
extern int InMark __P((void));
+extern void MakePaster __P((struct paster *, char *, int, int));
+extern void FreePaster __P((struct paster *));
/* search.c */
extern void Search __P((int));
@@ -99,7 +108,7 @@ extern void ISearch __P((int));
/* input.c */
extern void inp_setprompt __P((char *, char *));
-extern void Input __P((char *, int, int, void (*)(), char *));
+extern void Input __P((char *, int, int, void (*)(char *, int, char *), char *));
extern int InInput __P((void));
/* help.c */
@@ -117,10 +126,13 @@ extern void FreeWindow __P((struct win *));
extern int winexec __P((char **));
extern void FreePseudowin __P((struct win *));
#endif
-#ifdef MULTI
-extern int execclone __P((char **));
-#endif
extern void nwin_compose __P((struct NewWindow *, struct NewWindow *, struct NewWindow *));
+extern int DoStartLog __P((struct win *, char *, int));
+extern int ReleaseAutoWritelock __P((struct display *, struct win *));
+extern int ObtainAutoWritelock __P((struct display *, struct win *));
+extern void CloseDevice __P((struct win *));
+extern void paste_rethink __P((struct win *));
+
/* utmp.c */
#ifdef UTMPOK
@@ -134,6 +146,12 @@ extern void SlotToggle __P((int));
#ifdef USRLIMIT
extern int CountUsers __P((void));
#endif
+#ifdef CAREFULUTMP
+extern void CarefulUtmp __P((void));
+#else
+# define CarefulUtmp() /* nothing */
+#endif /* CAREFULUTMP */
+
/* loadav.c */
#ifdef LOADAV
@@ -143,6 +161,7 @@ extern void AddLoadav __P((char *));
/* pty.c */
extern int OpenPTY __P((char **));
+extern void InitPTY __P((int));
/* process.c */
extern void InitKeytab __P((void));
@@ -150,17 +169,22 @@ extern void ProcessInput __P((char *, int));
#ifdef MAPKEYS
extern void ProcessInput2 __P((char *, int));
#endif
+extern void DoProcess __P((struct win *, char **, int *, struct paster *));
+extern void DoAction __P((struct action *, int));
extern int FindCommnr __P((char *));
extern void DoCommand __P((char **));
+extern void Activate __P((int));
extern void KillWindow __P((struct win *));
-extern int ReleaseAutoWritelock __P((struct display *, struct win *));
extern void SetForeWindow __P((struct win *));
extern int Parse __P((char *, char **));
extern int ParseEscape __P((struct user *, char *));
extern void DoScreen __P((char *, char **));
extern int IsNumColon __P((char *, int, char *, int));
-extern void ShowWindows __P((void));
+extern void ShowWindows __P((int));
+extern char *AddWindows __P((char *, int, int, int));
+extern char *AddOtherUsers __P((char *, int, struct win *));
extern int WindowByNoN __P((char *));
+extern struct win *FindNiceWindow __P((struct win *, char *));
#ifdef COPY_PASTE
extern int CompileKeys __P((char *, unsigned char *));
#endif
@@ -187,30 +211,30 @@ extern void FreeDisplay __P((void));
extern void DefProcess __P((char **, int *));
extern void DefRedisplayLine __P((int, int, int, int));
extern void DefClearLine __P((int, int, int));
-extern int DefRewrite __P((int, int, int, int));
-extern void DefSetCursor __P((void));
+extern int DefRewrite __P((int, int, int, struct mchar *, int));
extern int DefResize __P((int, int));
extern void DefRestore __P((void));
extern void PutStr __P((char *));
extern void CPutStr __P((char *, int));
extern void InitTerm __P((int));
extern void FinitTerm __P((void));
-extern void INSERTCHAR __P((int));
extern void PUTCHAR __P((int));
extern void PUTCHARLP __P((int));
-extern void RAW_PUTCHAR __P((int));
extern void ClearDisplay __P((void));
extern void Clear __P((int, int, int, int, int, int, int));
+extern void Redisplay __P((int));
+extern void RedisplayDisplays __P((int));
+extern void RefreshArea __P((int, int, int, int, int));
extern void RefreshLine __P((int, int, int, int));
-extern void RefreshStatus __P((void));
+extern void ShowHStatus __P((char *));
+extern void RefreshHStatus __P((void));
extern void DisplayLine __P((struct mline *, struct mline *, int, int, int));
-
-extern void CDisplayLine __P((struct mline *, int, int, int, int, int));
-extern void FixLP __P((int, int));
extern void GotoPos __P((int, int));
extern int CalcCost __P((char *));
extern void ScrollH __P((int, int, int, int, struct mline *));
extern void ScrollV __P((int, int, int, int, int));
+extern void InsChar __P((struct mchar *, int, int, int, struct mline *));
+extern void WrapChar __P((struct mchar *, int, int, int, int, int, int, int));
extern void ChangeScrollRegion __P((int, int));
extern void InsertMode __P((int));
extern void KeypadMode __P((int));
@@ -224,10 +248,7 @@ extern void SetRendition __P((struct mchar *));
extern void SetRenditionMline __P((struct mline *, int));
extern void MakeStatus __P((char *));
extern void RemoveStatus __P((void));
-extern void SetLastPos __P((int, int));
extern int ResizeDisplay __P((int, int));
-extern int InitOverlayPage __P((int, struct LayFuncs *, int));
-extern void ExitOverlayPage __P((void));
extern void AddStr __P((char *));
extern void AddStrn __P((char *, int));
extern void Flush __P((void));
@@ -239,6 +260,13 @@ extern void NukePending __P((void));
#ifdef KANJI
extern int badkanji __P((char *, int));
#endif
+extern void SetCanvasWindow __P((struct canvas *, struct win *));
+extern int MakeDefaultCanvas __P((void));
+extern int AddCanvas __P((void));
+extern void RemCanvas __P((void));
+extern void OneCanvas __P((void));
+extern int RethinkDisplayViewports __P((void));
+extern void RethinkViewportOffsets __P((struct canvas *));
/* resize.c */
extern int ChangeWindowSize __P((struct win *, int, int, int));
@@ -246,6 +274,15 @@ extern void ChangeScreenSize __P((int, int, int));
extern void CheckScreenSize __P((int));
extern void DoResize __P((int, int));
extern char *xrealloc __P((char *, int));
+extern void ResizeLayersToCanvases __P((void));
+extern void ResizeLayer __P((struct layer *, int, int, struct display *));
+extern int MayResizeLayer __P((struct layer *));
+
+/* sched.c */
+extern void evenq __P((struct event *));
+extern void evdeq __P((struct event *));
+extern void SetTimeout __P((struct event *, int));
+extern void sched __P((void));
/* socket.c */
extern int FindSocket __P((int *, int *, int *, char *));
@@ -253,24 +290,18 @@ extern int MakeClientSocket __P((int));
extern int MakeServerSocket __P((void));
extern int RecoverSocket __P((void));
extern int chsock __P((void));
-extern void ReceiveMsg __P(());
+extern void ReceiveMsg __P((void));
extern void SendCreateMsg __P((char *, struct NewWindow *));
-#ifdef USEVARARGS
-extern void SendErrorMsg __P((char *, ...))
-# if __GNUC__ > 1
-__attribute__ ((format (printf, 1, 2)))
-# endif
-;
-#else
-extern void SendErrorMsg __P(());
-#endif
+extern int SendErrorMsg __P((char *, char *));
/* misc.c */
extern char *SaveStr __P((const char *));
+extern char *InStr __P((char *, const char *));
#ifndef HAVE_STRERROR
extern char *strerror __P((int));
#endif
-extern void centerline __P((char *));
+extern void centerline __P((char *, int));
+extern void leftline __P((char *, int));
extern char *Filename __P((char *));
extern char *stripdev __P((char *));
#ifdef NEED_OWN_BCOPY
@@ -284,7 +315,7 @@ extern int UserStatus __P((void));
#if defined(POSIX) || defined(hpux)
extern void (*xsignal __P((int, void (*)SIGPROTOARG))) __P(SIGPROTOARG);
#endif
-#ifdef NEED_RENAME
+#ifndef HAVE_RENAME
extern int rename __P((char *, char *));
#endif
#if defined(HAVE_SETEUID) || defined(HAVE_SETREUID)
@@ -293,7 +324,12 @@ extern void xsetegid __P((int));
#endif
extern int AddXChar __P((char *, int));
extern int AddXChars __P((char *, int, char *));
+extern void xsetenv __P((char *, char *));
+extern char *expand_vars __P((char *, struct display *));
+extern void sleep1000 __P((int));
+#ifdef DEBUG
extern void opendebug __P((int, int));
+#endif
#ifdef USEVARARGS
# ifndef HAVE_VSNPRINTF
extern int xvsnprintf __P((char *, int, char *, va_list));
@@ -302,24 +338,84 @@ extern int xvsnprintf __P((char *, int, char *, va_list));
extern int xsnprintf __P(());
#endif
+
/* acl.c */
#ifdef MULTIUSER
extern int AclInit __P((char *));
extern int AclSetPass __P((char *, char *));
extern int AclDelUser __P((char *));
-extern int UserFreeCopyBuffer __P((struct user *));
-extern int AclAddGroup __P((char *));
-extern int AclSetGroupPerm __P((char *, char *));
-extern int AclDelGroup __P((char *));
-extern int AclUserAddGroup __P((char *, char *));
-extern int AclUserDelGroup __P((char *, char *));
extern int AclCheckPermWin __P((struct user *, int, struct win *));
extern int AclCheckPermCmd __P((struct user *, int, struct comm *));
extern int AclSetPerm __P((struct user *, struct user *, char *, char *));
+extern int AclUmask __P((struct user *, char *, char **));
extern int UsersAcl __P((struct user *, int, char **));
extern void AclWinSwap __P((int, int));
extern int NewWindowAcl __P((struct win *, struct user *));
+extern void FreeWindowAcl __P((struct win *));
+extern char *DoSu __P((struct user **, char *, char *, char *));
+extern int AclLinkUser __P((char *, char *));
#endif /* MULTIUSER */
+extern int UserFreeCopyBuffer __P((struct user *));
extern struct user **FindUserPtr __P((char *));
extern int UserAdd __P((char *, char *, struct user **));
extern int UserDel __P((char *, struct user **));
+
+
+
+
+
+extern void InitBraille __P((void));
+extern void RefreshBraille __P((void));
+extern void DoBrailleAction __P((struct action *, int));
+extern void BGotoPos __P((struct layer *, int, int));
+extern void BPutChar __P((struct layer *, struct mchar *, int, int));
+extern void BPutStr __P((struct layer *, char *, int, struct mchar *, int, int));
+extern void BCDisplayLine __P((struct layer *, struct mline *, int, int, int, int));
+
+
+extern int ParseSaveStr __P((struct action *act, char **));
+extern int ParseNum __P((struct action *act, int *));
+extern int ParseSwitch __P((struct action *, int *));
+
+
+/* layer.c */
+extern void LGotoPos __P((struct layer *, int, int));
+extern void LPutChar __P((struct layer *, struct mchar *, int, int));
+extern void LInsChar __P((struct layer *, struct mchar *, int, int, struct mline *));
+extern void LPutStr __P((struct layer *, char *, int, struct mchar *, int, int));
+extern void LScrollH __P((struct layer *, int, int, int, int, struct mline *));
+extern void LScrollV __P((struct layer *, int, int, int));
+extern void LClear __P((struct layer *, int, int, int, int, int));
+extern void LClearLine __P((struct layer *, int, int, int, struct mline *));
+extern void LCDisplayLine __P((struct layer *, struct mline *, int, int, int, int));
+extern void LSetRendition __P((struct layer *, struct mchar *));
+extern void LWrapChar __P((struct layer *, struct mchar *, int, int, int, int));
+extern void LCursorVisibility __P((struct layer *, int));
+extern void LSetFlow __P((struct layer *, int));
+extern void LKeypadMode __P((struct layer *, int));
+extern void LCursorkeysMode __P((struct layer *, int));
+
+#ifdef USEVARARGS
+extern void LMsg __P((int, char *, ...)) __attribute__((format(printf, 2, 3)));
+#else
+extern void LMsg __P(());
+#endif
+extern void ClearLayer __P((struct layer *, int));
+extern void RedisplayLayer __P((struct layer *, int));
+extern void KillLayerChain __P((struct layer *));
+extern int InitOverlayPage __P((int, struct LayFuncs *, int));
+extern void ExitOverlayPage __P((void));
+
+/* teln.c */
+extern int TelOpen __P((char **));
+extern int TelConnect __P((struct win *));
+extern int TelIsline __P((struct win *p));
+extern void TelProcessLine __P((char **, int *));
+extern int DoTelnet __P((char *, int *, int));
+extern int TelIn __P((struct win *, char *, int, int));
+extern void TelBreak __P((struct win *));
+extern void TelWindowSize __P((struct win *));
+extern void TelStatus __P((struct win *, char *, int));
+
+/* nethack.c */
+extern char *DoNLS __P((char *));
diff --git a/fileio.c b/fileio.c
index 32c73c5..665b4b6 100644
--- a/fileio.c
+++ b/fileio.c
@@ -37,11 +37,7 @@ RCS_ID("$Id: fileio.c,v 1.10 1994/05/31 12:32:01 mlschroe Exp $ FAU")
#include "screen.h"
#include "extern.h"
-#ifdef NETHACK
-extern nethackflag;
-#endif
-
-extern struct display *display;
+extern struct display *display, *displays;
extern struct win *fore;
extern int real_uid, eff_uid;
extern int real_gid, eff_gid;
@@ -55,6 +51,7 @@ extern int hardcopy_append;
extern char *hardcopydir;
static char *CatExtra __P((char *, char *));
+static char *findrcfile __P((char *));
static FILE *fp = NULL;
@@ -108,14 +105,9 @@ char *rcfile;
else
{
debug("findrcfile: you specified nothing...\n");
- if ((p = getenv("ISCREENRC")) != NULL && *p != '\0')
- {
- debug1(" ... but $ISCREENRC has: '%s'\n", p);
- rc = SaveStr(p);
- }
- else if ((p = getenv("SCREENRC")) != NULL && *p != '\0')
+ if ((p = getenv("SCREENRC")) != NULL && *p != '\0')
{
- debug1(" ... but $SCREENRC has: '%s'\n", p);
+ debug1(" $SCREENRC has: '%s'\n", p);
rc = SaveStr(p);
}
else
@@ -123,9 +115,7 @@ char *rcfile;
debug(" ...nothing in $SCREENRC, defaulting $HOME/.screenrc\n");
if (strlen(home) > sizeof(buf) - 12)
Panic(0, "Rc: home too large");
- sprintf(buf, "%s/.iscreenrc", home);
- if (access(buf, R_OK))
- sprintf(buf, "%s/.screenrc", home);
+ sprintf(buf, "%s/.screenrc", home);
rc = SaveStr(buf);
}
}
@@ -143,12 +133,13 @@ char *rcfilename;
{
register int argc, len;
register char *p, *cp;
- char buf[256];
+ char buf[2048];
char *args[MAXARGS];
+ /* always fix termcap/info capabilities */
+ extra_incap = CatExtra("TF", extra_incap);
/* Special settings for vt100 and others */
-
if (display && (!strncmp(D_termname, "vt", 2) || !strncmp(D_termname, "xterm", 5)))
extra_incap = CatExtra("xn:f0=\033Op:f1=\033Oq:f2=\033Or:f3=\033Os:f4=\033Ot:f5=\033Ou:f6=\033Ov:f7=\033Ow:f8=\033Ox:f9=\033Oy:f.=\033On:f,=\033Ol:fe=\033OM:f+=\033Ok:f-=\033Om:f*=\033Oj:f/=\033Oo:fq=\033OX", extra_incap);
@@ -248,7 +239,7 @@ void
FinishRc(rcfilename)
char *rcfilename;
{
- char buf[256];
+ char buf[2048];
rc_name = findrcfile(rcfilename);
@@ -279,18 +270,44 @@ char *rcfilename;
rc_name = "";
}
+/*
+ * Running a Command Line in the environment determined by the display.
+ * The fore window is taken from the display as well as the user.
+ * This is bad when we run detached.
+ */
void
RcLine(ubuf)
char *ubuf;
{
char *args[MAXARGS], *buf;
+#ifdef MULTIUSER
+ extern struct user *EffectiveAclUser; /* acl.c */
+ extern struct user *users; /* acl.c */
+#endif
- buf = expand_vars(ubuf, display);
+ if (display)
+ fore = D_fore;
+ buf = expand_vars(ubuf, display);
if (Parse(buf, args) <= 0)
return;
+#ifdef MULTIUSER
+ if (!display)
+ {
+ /* the session owner does it, when there is no display here */
+ EffectiveAclUser = users;
+ debug1("RcLine: WARNING, no display no user! Session owner does: %s",
+ ubuf);
+ }
+#endif
DoCommand(args);
+#ifdef MULTIUSER
+ EffectiveAclUser = 0;
+#endif
}
+/*
+ * needs display for copybuffer access and termcap dumping
+ */
void
WriteFile(dump)
int dump;
@@ -306,6 +323,18 @@ int dump;
register FILE *f;
char fn[1024];
char *mode = "w";
+#ifdef COPY_PASTE
+ int public = 0;
+# ifdef _MODE_T
+ mode_t old_umask;
+# else
+ int old_umask;
+# endif
+# ifdef HAVE_LSTAT
+ struct stat stb, stb2;
+ int fd, exists = 0;
+# endif
+#endif
switch (dump)
{
@@ -328,7 +357,15 @@ int dump;
case DUMP_EXCHANGE:
strncpy(fn, BufferFile, sizeof(fn) - 1);
fn[sizeof(fn) - 1] = 0;
- umask(0);
+ public = !strcmp(fn, DEFAULT_BUFFERFILE);
+# ifdef HAVE_LSTAT
+ exists = !lstat(fn, &stb);
+ if (public && exists && (S_ISLNK(stb.st_mode) || stb.st_nlink > 1))
+ {
+ Msg(0, "No write to links, please.");
+ return;
+ }
+# endif
break;
#endif
}
@@ -337,7 +374,36 @@ int dump;
if (UserContext() > 0)
{
debug("Writefile: usercontext\n");
- if ((f = fopen(fn, mode)) == NULL)
+#ifdef COPY_PASTE
+ if (dump == DUMP_EXCHANGE && public)
+ {
+ old_umask = umask(0);
+# ifdef HAVE_LSTAT
+ if (exists)
+ {
+ if ((fd = open(fn, O_WRONLY, 0666)) >= 0)
+ {
+ if (fstat(fd, &stb2) == 0 && stb.st_dev == stb2.st_dev && stb.st_ino == stb2.st_ino)
+ ftruncate(fd, 0);
+ else
+ {
+ close(fd);
+ fd = -1;
+ }
+ }
+ }
+ else
+ fd = open(fn, O_WRONLY|O_CREAT|O_EXCL, 0666);
+ f = fd >= 0 ? fdopen(fd, mode) : 0;
+# else
+ f = fopen(fn, mode);
+# endif
+ umask(old_umask);
+ }
+ else
+#endif /* COPY_PASTE */
+ f = fopen(fn, mode);
+ if (f == NULL)
{
debug2("WriteFile: fopen(%s,\"%s\") failed\n", fn, mode);
UserReturn(0);
@@ -448,11 +514,6 @@ int *lenp;
{
if (l < 0)
l = 0;
-#ifdef NETHACK
- if (nethackflag)
- Msg(errno, "You choke on your food: %d bytes from %s", l, fn);
- else
-#endif
Msg(errno, "Got only %d bytes from %s", l, fn);
close(i);
}
@@ -614,3 +675,40 @@ int mode;
return fd;
#endif
}
+
+
+int
+printpipe(p, cmd)
+struct win *p;
+char *cmd;
+{
+ int pi[2];
+ if (pipe(pi))
+ {
+ WMsg(p, errno, "printing pipe");
+ return -1;
+ }
+ switch (fork())
+ {
+ case -1:
+ WMsg(p, errno, "printing fork");
+ return -1;
+ case 0:
+ display = p->w_pdisplay;
+ displays = 0;
+ close(0);
+ dup(pi[0]);
+ closeallfiles(0);
+ if (setgid(real_gid) || setuid(real_uid))
+ Panic(errno, "printpipe setuid");
+#ifdef SIGPIPE
+ signal(SIGPIPE, SIG_DFL);
+#endif
+ execl("/bin/sh", "sh", "-c", cmd, 0);
+ Panic(errno, "/bin/sh");
+ default:
+ break;
+ }
+ close(pi[0]);
+ return pi[1];
+}
diff --git a/help.c b/help.c
index 88745fc..bcd74ae 100644
--- a/help.c
+++ b/help.c
@@ -33,9 +33,13 @@ RCS_ID("$Id: help.c,v 1.7 1994/05/31 12:32:04 mlschroe Exp $ FAU")
char version[40]; /* initialised by main() */
-extern struct display *display;
+extern struct layer *flayer;
+extern struct display *displays;
extern char *noargs[];
-extern struct mchar mchar_null;
+extern struct mchar mchar_blank;
+extern char *blank;
+
+static void PadStr __P((char *, int, int, int));
void
@@ -44,35 +48,38 @@ char *myname, *message, *arg;
{
printf("Use: %s [-opts] [cmd [args]]\n", myname);
printf(" or: %s -r [host.tty]\n\nOptions:\n", myname);
- printf("-a Force all capabilities into each window's termcap.\n");
- printf("-A -[r|R] Adapt all windows to the new display width & height.\n");
- printf("-c file Read configuration file instead of '.screenrc'.\n");
+ printf("-a Force all capabilities into each window's termcap.\n");
+ printf("-A -[r|R] Adapt all windows to the new display width & height.\n");
+ printf("-c file Read configuration file instead of '.screenrc'.\n");
#ifdef REMOTE_DETACH
- printf("-d (-r) Detach the elsewhere running screen (and reattach here).\n");
- printf("-D (-r) Detach and logout remote (and reattach here).\n");
+ printf("-d (-r) Detach the elsewhere running screen (and reattach here).\n");
+ printf("-dmS name Start as daemon: Screen session in detached mode.\n");
+ printf("-D (-r) Detach and logout remote (and reattach here).\n");
+ printf("-D -RR Do whatever is needed to get a screen session.\n");
#endif
- printf("-e xy Change command characters.\n");
- printf("-f Flow control on, -fn = off, -fa = auto.\n");
- printf("-h lines Set the size of the scrollback history buffer.\n");
- printf("-i Interrupt output sooner when flow control is on.\n");
+ printf("-e xy Change command characters.\n");
+ printf("-f Flow control on, -fn = off, -fa = auto.\n");
+ printf("-h lines Set the size of the scrollback history buffer.\n");
+ printf("-i Interrupt output sooner when flow control is on.\n");
#if defined(LOGOUTOK) && defined(UTMPOK)
- printf("-l Login mode on (update %s), -ln = off.\n", UTMPFILE);
+ printf("-l Login mode on (update %s), -ln = off.\n", UTMPFILE);
#endif
- printf("-list or -ls. Do nothing, just list our SockDir.\n");
- printf("-L Terminal's last character can be safely updated.\n");
- printf("-m ignore $STY variable, do create a new screen session.\n");
- printf("-O Choose optimal output rather than exact vt100 emulation.\n");
- printf("-q Quiet startup. Exits with non-zero return code if unsuccessful.\n");
- printf("-r Reattach to a detached screen process.\n");
- printf("-R Reattach if possible, otherwise start a new session.\n");
- printf("-s shell Shell to execute rather than $SHELL.\n");
- printf("-S sockname Name this session <pid>.sockname instead of <pid>.<tty>.<host>.\n");
- printf("-t title Set title. (window's name).\n");
- printf("-T term Use term as $TERM for windows, rather than \"screen\".\n");
- printf("-v Print \"Screen version %s\".\n", version);
- printf("-wipe Do nothing, just clean up SockDir.\n");
+ printf("-list or -ls. Do nothing, just list our SockDir.\n");
+ printf("-L Terminal's last character can be safely updated.\n");
+ printf("-m ignore $STY variable, do create a new screen session.\n");
+ printf("-O Choose optimal output rather than exact vt100 emulation.\n");
+ printf("-p window Preselect the named window if it exists.\n");
+ printf("-q Quiet startup. Exits with non-zero return code if unsuccessful.\n");
+ printf("-r Reattach to a detached screen process.\n");
+ printf("-R Reattach if possible, otherwise start a new session.\n");
+ printf("-s shell Shell to execute rather than $SHELL.\n");
+ printf("-S sockname Name this session <pid>.sockname instead of <pid>.<tty>.<host>.\n");
+ printf("-t title Set title. (window's name).\n");
+ printf("-T term Use term as $TERM for windows, rather than \"screen\".\n");
+ printf("-v Print \"Screen version %s\".\n", version);
+ printf("-wipe Do nothing, just clean up SockDir.\n");
#ifdef MULTI
- printf("-x Attach to a not detached screen. (Multi display mode).\n");
+ printf("-x Attach to a not detached screen. (Multi display mode).\n");
#endif /* MULTI */
if (message && *message)
{
@@ -83,7 +90,6 @@ char *myname, *message, *arg;
exit(1);
}
-
/*
** Here come the help page routines
*/
@@ -94,9 +100,8 @@ extern struct action ktab[];
static void HelpProcess __P((char **, int *));
static void HelpAbort __P((void));
static void HelpRedisplayLine __P((int, int, int, int));
-static void HelpSetCursor __P((void));
static void add_key_to_buf __P((char *, int));
-static int AddAction __P((struct action *, int));
+static void AddAction __P((struct action *, int, int));
static int helppage __P((void));
struct helpdata
@@ -118,7 +123,6 @@ static struct LayFuncs HelpLf =
HelpRedisplayLine,
DefClearLine,
DefRewrite,
- HelpSetCursor,
DefResize,
DefRestore
};
@@ -131,15 +135,15 @@ display_help()
struct helpdata *helpdata;
int used[RC_LAST + 1];
- if (D_height < 6)
+ if (flayer->l_height < 6)
{
- Msg(0, "Window height too small for help page");
+ LMsg(0, "Window height too small for help page");
return;
}
if (InitOverlayPage(sizeof(*helpdata), &HelpLf, 0))
return;
- helpdata = (struct helpdata *)D_lay->l_data;
+ helpdata = (struct helpdata *)flayer->l_data;
helpdata->num_names = helpdata->command_bindings = 0;
helpdata->command_search = 0;
for (n = 0; n <= RC_LAST; n++)
@@ -175,14 +179,14 @@ display_help()
if (mkey > MAXKLEN)
mkey = MAXKLEN;
- helpdata->numcols = (D_width - !D_CLP)/(mcom + mkey + 1);
+ helpdata->numcols = flayer->l_width / (mcom + mkey + 1);
if (helpdata->numcols == 0)
{
HelpAbort();
- Msg(0, "Width too small");
+ LMsg(0, "Width too small");
return;
}
- helpdata->inter = (D_width - !D_CLP - (mcom + mkey) * helpdata->numcols) / (helpdata->numcols + 1);
+ helpdata->inter = (flayer->l_width - (mcom + mkey) * helpdata->numcols) / (helpdata->numcols + 1);
if (helpdata->inter <= 0)
helpdata->inter = 1;
debug1("inter: %d\n", helpdata->inter);
@@ -190,34 +194,29 @@ display_help()
helpdata->mkey = mkey;
helpdata->numrows = (helpdata->num_names + helpdata->numcols - 1) / helpdata->numcols;
debug1("Numrows: %d\n", helpdata->numrows);
- helpdata->numskip = D_height-5 - (2 + helpdata->numrows);
+ helpdata->numskip = flayer->l_height-5 - (2 + helpdata->numrows);
while (helpdata->numskip < 0)
- helpdata->numskip += D_height-5;
- helpdata->numskip %= D_height-5;
+ helpdata->numskip += flayer->l_height-5;
+ helpdata->numskip %= flayer->l_height-5;
debug1("Numskip: %d\n", helpdata->numskip);
- if (helpdata->numskip > D_height/3 || helpdata->numskip > helpdata->command_bindings)
+ if (helpdata->numskip > flayer->l_height/3 || helpdata->numskip > helpdata->command_bindings)
helpdata->numskip = 1;
helpdata->maxrow = 2 + helpdata->numrows + helpdata->numskip + helpdata->command_bindings;
helpdata->grow = 0;
- helpdata->numpages = (helpdata->maxrow + D_height-6) / (D_height-5);
+ helpdata->numpages = (helpdata->maxrow + flayer->l_height-6) / (flayer->l_height-5);
+ flayer->l_x = 0;
+ flayer->l_y = flayer->l_height - 1;
helppage();
}
static void
-HelpSetCursor()
-{
- GotoPos(0, D_height - 1);
-}
-
-static void
HelpProcess(ppbuf, plen)
char **ppbuf;
int *plen;
{
int done = 0;
- GotoPos(0, D_height-1);
while (!done && *plen > 0)
{
switch (**ppbuf)
@@ -243,7 +242,7 @@ int *plen;
static void
HelpAbort()
{
- LAY_CALL_UP(Activate(0));
+ LAY_CALL_UP(RedisplayLayer(flayer, 0));
ExitOverlayPage();
}
@@ -252,10 +251,10 @@ static int
helppage()
{
struct helpdata *helpdata;
- int col, crow, n, key;
+ int col, crow, n, key, x;
char buf[MAXKLEN], Esc_buf[5], cbuf[256];
- helpdata = (struct helpdata *)D_lay->l_data;
+ helpdata = (struct helpdata *)flayer->l_data;
if (helpdata->grow >= helpdata->maxrow)
return -1;
@@ -263,46 +262,53 @@ helppage()
helpdata->refcommand_search = helpdata->command_search;
/* Clear the help screen */
- SetRendition(&mchar_null);
- ClearDisplay();
+ ClearLayer(flayer, 0);
- sprintf(cbuf,"Screen key bindings, page %d of %d.", helpdata->grow / (D_height-5) + 1, helpdata->numpages);
- centerline(cbuf);
- AddChar('\n');
+ sprintf(cbuf,"Screen key bindings, page %d of %d.", helpdata->grow / (flayer->l_height-5) + 1, helpdata->numpages);
+ centerline(cbuf, 0);
crow = 2;
*Esc_buf = '\0';
- add_key_to_buf(Esc_buf, D_user->u_Esc);
+ *buf = '\0';
+ /* XXX fix escape character */
+ if (flayer->l_cvlist && flayer->l_cvlist->c_display)
+ {
+ add_key_to_buf(buf, flayer->l_cvlist->c_display->d_user->u_MetaEsc);
+ add_key_to_buf(Esc_buf, flayer->l_cvlist->c_display->d_user->u_Esc);
+ }
+ else
+ {
+ strcpy(Esc_buf, "??");
+ strcpy(buf, "??");
+ }
- for (; crow < D_height - 3; crow++)
+ for (; crow < flayer->l_height - 3; crow++)
{
if (helpdata->grow < 1)
{
- *buf = '\0';
- add_key_to_buf(buf, D_user->u_MetaEsc);
sprintf(cbuf,"Command key: %s Literal %s: %s", Esc_buf, Esc_buf, buf);
- centerline(cbuf);
+ centerline(cbuf, crow);
helpdata->grow++;
}
else if (helpdata->grow >= 2 && helpdata->grow-2 < helpdata->numrows)
{
+ x = 0;
for (col = 0; col < helpdata->numcols && (n = helpdata->numrows * col + (helpdata->grow-2)) < helpdata->num_names; col++)
{
- AddStrn("", helpdata->inter - !col);
+ x += helpdata->inter - !col;
n = helpdata->nact[n];
- debug1("help: searching key %d\n", n);
buf[0] = '\0';
for (key = 0; key < 256; key++)
if (ktab[key].nr == n && ktab[key].args == noargs && strlen(buf) < sizeof(buf) - 7)
-
{
strcat(buf, " ");
add_key_to_buf(buf, key);
}
- AddStrn(comms[n].name, helpdata->mcom);
- AddStrn(buf, helpdata->mkey);
+ PadStr(comms[n].name, helpdata->mcom, x, crow);
+ x += helpdata->mcom;
+ PadStr(buf, helpdata->mkey, x, crow);
+ x += helpdata->mkey;
}
- AddStr("\r\n");
helpdata->grow++;
}
else if (helpdata->grow-2-helpdata->numrows >= helpdata->numskip
@@ -316,43 +322,45 @@ helppage()
}
buf[0] = '\0';
add_key_to_buf(buf, helpdata->command_search);
- AddStrn(buf, 4);
- AddAction(&ktab[helpdata->command_search++], D_width - 5);
- AddStr("\r\n");
+ PadStr(buf, 4, 0, crow);
+ AddAction(&ktab[helpdata->command_search++], 4, crow);
helpdata->grow++;
}
else
- {
- AddChar('\n');
- helpdata->grow++;
- }
+ helpdata->grow++;
}
- AddChar('\n');
sprintf(cbuf,"[Press Space %s Return to end.]",
helpdata->grow < helpdata->maxrow ? "for next page;" : "or");
- centerline(cbuf);
- SetLastPos(0, D_height-1);
+ centerline(cbuf, flayer->l_height - 2);
+ SetCursor();
return 0;
}
-static int
-AddAction(act, fr)
+static void
+AddAction(act, x, y)
struct action *act;
-int fr;
+int x, y;
{
char buf[256];
int del, l;
char *bp, *cp, **pp;
+ int fr;
+ struct mchar mchar_dol;
+ mchar_dol = mchar_blank;
+ mchar_dol.image = '$';
+
+ fr = flayer->l_width - 1 - x;
if (fr <= 0)
- return 0;
+ return;
l = strlen(comms[act->nr].name);
if (l + 1 > fr)
l = fr - 1;
- AddStrn(comms[act->nr].name, l);
+ PadStr(comms[act->nr].name, l, x, y);
+ x += l;
fr -= l + 1;
- AddChar(fr ? ' ' : '$');
+ LPutChar(flayer, fr ? &mchar_blank : &mchar_dol, x++, y);
pp = act->args;
while (pp && (cp = *pp) != NULL)
@@ -375,17 +383,17 @@ int fr;
{
fr += bp - buf;
if (fr > 0)
- AddStrn(buf, fr);
+ PadStr(buf, fr, x, y);
if (fr == 0)
- AddChar('$');
- return 0;
+ LPutChar(flayer, &mchar_dol, x, y);
+ return;
}
- AddStr(buf);
+ PadStr(buf, strlen(buf), x, y);
+ x += strlen(buf);
pp++;
if (*pp)
- AddChar(fr ? ' ' : '$');
+ LPutChar(flayer, fr ? &mchar_blank : &mchar_dol, x++, y);
}
- return fr;
}
static void
@@ -393,7 +401,6 @@ add_key_to_buf(buf, key)
char *buf;
int key;
{
- debug1("help: key found: %c\n", key);
buf += strlen(buf);
if (key < 0)
strcpy(buf, "unset");
@@ -412,17 +419,16 @@ int y, xs, xe, isblank;
{
struct helpdata *helpdata;
- helpdata = (struct helpdata *)D_lay->l_data;
+ helpdata = (struct helpdata *)flayer->l_data;
helpdata->grow = helpdata->refgrow;
helpdata->command_search = helpdata->refcommand_search;
helppage();
return;
}
- if (y != 0 && y != D_height - 1)
+ if (y != 0 && y != flayer->l_height - 1)
return;
- if (isblank)
- return;
- Clear(xs, y, xs, xe, xe, y, 0);
+ if (!isblank)
+ LClear(flayer, xs, y, xe, y, 0);
}
@@ -435,7 +441,6 @@ int y, xs, xe, isblank;
static void CopyrightProcess __P((char **, int *));
static void CopyrightRedisplayLine __P((int, int, int, int));
static void CopyrightAbort __P((void));
-static void CopyrightSetCursor __P((void));
static void copypage __P((void));
struct copydata
@@ -451,7 +456,6 @@ static struct LayFuncs CopyrightLf =
CopyrightRedisplayLine,
DefClearLine,
DefRewrite,
- CopyrightSetCursor,
DefResize,
DefRestore
};
@@ -460,7 +464,7 @@ static const char cpmsg[] = "\
\n\
Screen version %v\n\
\n\
-Copyright (c) 1993 Juergen Weigert, Michael Schroeder\n\
+Copyright (c) 1993-1999 Juergen Weigert, Michael Schroeder\n\
Copyright (c) 1987 Oliver Laumann\n\
\n\
This program is free software; you can redistribute it and/or \
@@ -483,12 +487,6 @@ screen@uni-erlangen.de\n";
static void
-CopyrightSetCursor()
-{
- GotoPos(0, D_height - 1);
-}
-
-static void
CopyrightProcess(ppbuf, plen)
char **ppbuf;
int *plen;
@@ -496,8 +494,7 @@ int *plen;
int done = 0;
struct copydata *copydata;
- copydata = (struct copydata *)D_lay->l_data;
- GotoPos(0, D_height - 1);
+ copydata = (struct copydata *)flayer->l_data;
while (!done && *plen > 0)
{
switch (**ppbuf)
@@ -525,7 +522,7 @@ int *plen;
static void
CopyrightAbort()
{
- LAY_CALL_UP(Activate(0));
+ LAY_CALL_UP(RedisplayLayer(flayer, 0));
ExitOverlayPage();
}
@@ -534,16 +531,18 @@ display_copyright()
{
struct copydata *copydata;
- if (D_width < 10 || D_height < 5)
+ if (flayer->l_width < 10 || flayer->l_height < 5)
{
- Msg(0, "Window size too small for copyright page");
+ LMsg(0, "Window size too small for copyright page");
return;
}
if (InitOverlayPage(sizeof(*copydata), &CopyrightLf, 0))
return;
- copydata = (struct copydata *)D_lay->l_data;
+ copydata = (struct copydata *)flayer->l_data;
copydata->cps = (char *)cpmsg;
copydata->savedcps = 0;
+ flayer->l_x = 0;
+ flayer->l_y = flayer->l_height - 1;
copypage();
}
@@ -556,14 +555,15 @@ copypage()
char cbuf[80];
struct copydata *copydata;
- copydata = (struct copydata *)D_lay->l_data;
- SetRendition(&mchar_null);
- ClearDisplay();
+ ASSERT(flayer);
+ copydata = (struct copydata *)flayer->l_data;
+
+ ClearLayer(flayer, 0);
x = y = 0;
cps = copydata->cps;
copydata->refcps = cps;
copydata->refsavedcps = copydata->savedcps;
- while (*cps && y < D_height - 3)
+ while (*cps && y < flayer->l_height - 3)
{
ws = cps;
while (*cps == ' ')
@@ -578,22 +578,21 @@ copypage()
cps++;
l = cps - ws;
cps = ws;
- if (l > D_width - 1)
- l = D_width - 1;
- if (x && x + l >= D_width - 2)
+ if (l > flayer->l_width - 1)
+ l = flayer->l_width - 1;
+ if (x && x + l >= flayer->l_width - 2)
{
- AddStr("\r\n");
x = 0;
y++;
continue;
}
if (x)
{
- AddChar(' ');
+ LPutChar(flayer, &mchar_blank, x, y);
x++;
}
if (l)
- AddStrn(ws, l);
+ LPutStr(flayer, ws, l, &mchar_blank, x, y);
x += l;
cps += l;
if (*cps == 0 && copydata->savedcps)
@@ -603,7 +602,6 @@ copypage()
}
if (*cps == '\n')
{
- AddStr("\r\n");
x = 0;
y++;
}
@@ -612,42 +610,221 @@ copypage()
}
while (*cps == '\n')
cps++;
- while (y++ < D_height - 2)
- AddStr("\r\n");
sprintf(cbuf,"[Press Space %s Return to end.]",
*cps ? "for next page;" : "or");
- centerline(cbuf);
- SetLastPos(0, D_height-1);
+ centerline(cbuf, flayer->l_height - 2);
copydata->cps = cps;
+ SetCursor();
}
static void
CopyrightRedisplayLine(y, xs, xe, isblank)
int y, xs, xe, isblank;
{
+ ASSERT(flayer);
if (y < 0)
{
struct copydata *copydata;
- copydata = (struct copydata *)D_lay->l_data;
+ copydata = (struct copydata *)flayer->l_data;
copydata->cps = copydata->refcps;
copydata->savedcps = copydata->refsavedcps;
copypage();
return;
}
- if (y != 0 && y != D_height - 1)
+ if (y != 0 && y != flayer->l_height - 1)
return;
if (isblank)
return;
- Clear(xs, y, xs, xe, xe, y, 0);
+ LClear(flayer, xs, y, xe, y, 0);
+}
+
+
+
+/*
+**
+** here is all the displays stuff
+**
+*/
+
+static void DisplaysProcess __P((char **, int *));
+static void DisplaysRedisplayLine __P((int, int, int, int));
+static void displayspage __P((void));
+
+struct displaysdata
+{
+ int dummy_element_for_solaris;
+};
+
+static struct LayFuncs DisplaysLf =
+{
+ DisplaysProcess,
+ HelpAbort,
+ DisplaysRedisplayLine,
+ DefClearLine,
+ DefRewrite,
+ DefResize,
+ DefRestore
+};
+
+static void
+DisplaysProcess(ppbuf, plen)
+char **ppbuf;
+int *plen;
+{
+ int done = 0;
+ struct displaysdata *displaysdata;
+
+ ASSERT(flayer);
+ displaysdata = (struct displaysdata *)flayer->l_data;
+ while (!done && *plen > 0)
+ {
+ switch (**ppbuf)
+ {
+ case ' ':
+ displayspage();
+ break;
+ /* FALLTHROUGH */
+ case '\r':
+ case '\n':
+ HelpAbort();
+ done = 1;
+ break;
+ default:
+ break;
+ }
+ ++*ppbuf;
+ --*plen;
+ }
}
-void
+void
display_displays()
{
+ struct displaysdata *displaysdata;
+
+ if (flayer->l_width < 10 || flayer->l_height < 5)
+ {
+ LMsg(0, "Window size too small for displays page");
+ return;
+ }
+ if (InitOverlayPage(sizeof(*displaysdata), &DisplaysLf, 0))
+ return;
+ displaysdata = (struct displaysdata *)flayer->l_data;
+ flayer->l_x = 0;
+ flayer->l_y = flayer->l_height - 1;
+ displayspage();
+}
+
+/*
+ * layout of the displays page is as follows:
+
+xterm 80x42 jnweiger@/dev/ttyp4 0(m11) &rWx
+facit 80x24 nb mlschroe@/dev/ttyhf 11(tcsh) rwx
+xterm 80x42 jnhollma@/dev/ttyp5 0(m11) &R.x
+
+ | | | | | | | | ¦___ window permissions
+ | | | | | | | | (R. is locked r-only,
+ | | | | | | | | W has wlock)
+ | | | | | | | |___ Window is shared
+ | | | | | | |___ Name/Title of window
+ | | | | | |___ Number of window
+ | | | | |___ Name of the display (the attached device)
+ | | | |___ Username who is logged in at the display
+ | | |___ Display is in nonblocking mode. Shows 'NB' if obuf is full.
+ | |___ Displays geometry as width x height.
+ |___ the terminal type known by screen for this display.
+
+ */
+
+static void
+displayspage()
+{
+ int y, l;
+ char tbuf[80];
+ struct displaysdata *displaysdata;
+ struct display *d;
+ struct win *w;
+
+ displaysdata = (struct displaysdata *)flayer->l_data;
+
+ ClearLayer(flayer, 0);
+
+ leftline("term-type size user interface window", 0);
+ leftline("---------- ------- ---------- ----------------- ----------", 1);
+ y = 2;
+
+ for (d = displays; d; d = d->d_next)
+ {
+ w = d->d_fore;
+
+ if (y >= flayer->l_height - 3)
+ break;
+ sprintf(tbuf, "%-10.10s%4dx%-4d%10.10s@%-16.16s%s",
+ d->d_termname, d->d_width, d->d_height, d->d_user->u_name,
+ d->d_usertty,
+ d->d_nonblock ? ((( d->d_obufp - d->d_obuf) > d->d_obufmax) ?
+ "NB" : "nb") : " ");
+
+ if (w)
+ {
+ l = 10 - strlen(w->w_title);
+ if (l < 0)
+ l = 0;
+ sprintf(tbuf + strlen(tbuf), "%3d(%.10s)%*s%c%c%c%c",
+ w->w_number, w->w_title, l, "",
+ /* w->w_dlist->next */ 0 ? '&' : ' ',
+ /*
+ * The rwx triple:
+ * -,r,R no read, read, read only due to foreign wlock
+ * -,.,w,W no write, write suppressed by foreign wlock,
+ * write, own wlock
+ * -,x no execute, execute
+ */
+#ifdef MULTIUSER
+ (AclCheckPermWin(d->d_user, ACL_READ, w) ? '-' :
+ ((w->w_wlock == WLOCK_OFF || d->d_user == w->w_wlockuser) ?
+ 'r' : 'R')),
+ (AclCheckPermWin(d->d_user, ACL_READ, w) ? '-' :
+ ((w->w_wlock == WLOCK_OFF) ? 'w' :
+ ((d->d_user == w->w_wlockuser) ? 'W' : 'v'))),
+ (AclCheckPermWin(d->d_user, ACL_READ, w) ? '-' : 'x')
+#else
+ 'r', 'w', 'x'
+#endif
+ );
+ }
+ leftline(tbuf, y);
+ y++;
+ }
+ sprintf(tbuf,"[Press Space %s Return to end.]",
+ 1 ? "to refresh;" : "or");
+ centerline(tbuf, flayer->l_height - 2);
+ SetCursor();
+}
+
+static void
+DisplaysRedisplayLine(y, xs, xe, isblank)
+int y, xs, xe, isblank;
+{
+ ASSERT(flayer);
+ if (y < 0)
+ {
+ struct displaysdata *displaysdata;
+
+ displaysdata = (struct displaysdata *)flayer->l_data;
+ displayspage();
+ return;
+ }
+ if (y != 0 && y != flayer->l_height - 1)
+ return;
+ if (isblank)
+ return;
+ LClear(flayer, xs, y, xe, y, 0);
/* To be filled in... */
}
+
/*
**
** The bindkey help page
@@ -663,7 +840,6 @@ extern struct term term[];
static void BindkeyProcess __P((char **, int *));
static void BindkeyAbort __P((void));
static void BindkeyRedisplayLine __P((int, int, int, int));
-static void BindkeySetCursor __P((void));
static void bindkeypage __P((void));
struct bindkeydata
@@ -683,7 +859,6 @@ static struct LayFuncs BindkeyLf =
BindkeyRedisplayLine,
DefClearLine,
DefRewrite,
- BindkeySetCursor,
DefResize,
DefRestore
};
@@ -697,17 +872,15 @@ struct action *tab;
struct bindkeydata *bindkeydata;
int i, n;
- if (display == 0)
- return;
- if (D_height < 6)
+ if (flayer->l_height < 6)
{
- Msg(0, "Window height too small for bindkey page");
+ LMsg(0, "Window height too small for bindkey page");
return;
}
if (InitOverlayPage(sizeof(*bindkeydata), &BindkeyLf, 0))
return;
- bindkeydata = (struct bindkeydata *)D_lay->l_data;
+ bindkeydata = (struct bindkeydata *)flayer->l_data;
bindkeydata->title = title;
bindkeydata->tab = tab;
@@ -719,22 +892,18 @@ struct action *tab;
}
bindkeydata->pos = 0;
bindkeydata->page = 1;
- bindkeydata->pages = (n + D_height - 6) / (D_height - 5);
+ bindkeydata->pages = (n + flayer->l_height - 6) / (flayer->l_height - 5);
if (bindkeydata->pages == 0)
bindkeydata->pages = 1;
+ flayer->l_x = 0;
+ flayer->l_y = flayer->l_height - 1;
bindkeypage();
}
static void
-BindkeySetCursor()
-{
- GotoPos(0, D_height - 1);
-}
-
-static void
BindkeyAbort()
{
- LAY_CALL_UP(Activate(0));
+ LAY_CALL_UP(RedisplayLayer(flayer, 0));
ExitOverlayPage();
}
@@ -747,16 +916,14 @@ bindkeypage()
struct action *act;
char *xch, *s, *p;
- bindkeydata = (struct bindkeydata *)D_lay->l_data;
+ bindkeydata = (struct bindkeydata *)flayer->l_data;
- SetRendition(&mchar_null);
- ClearDisplay();
+ ClearLayer(flayer, 0);
sprintf(tbuf, "%s key bindings, page %d of %d.", bindkeydata->title, bindkeydata->page, bindkeydata->pages);
- centerline(tbuf);
- AddChar('\n');
- y = D_height - 5;
- for (i = bindkeydata->pos; i < KMAP_KEYS+KMAP_AKEYS+KMAP_EXT && y; i++)
+ centerline(tbuf, 0);
+ y = 2;
+ for (i = bindkeydata->pos; i < KMAP_KEYS+KMAP_AKEYS+KMAP_EXT && y < flayer->l_height - 3; i++)
{
p = tbuf;
act = &bindkeydata->tab[i];
@@ -790,23 +957,20 @@ bindkeypage()
*p++ = ' ';
sprintf(p, "%s -> ", xch);
p += 7;
- if (p - tbuf > D_width - 1)
+ if (p - tbuf > flayer->l_width - 1)
{
- tbuf[D_width - 2] = '$';
- tbuf[D_width - 1] = 0;
+ tbuf[flayer->l_width - 2] = '$';
+ tbuf[flayer->l_width - 1] = 0;
}
- AddStr(tbuf);
- AddAction(act, D_width - 1 - strlen(tbuf));
- AddStr("\r\n");
- y--;
+ PadStr(tbuf, strlen(tbuf), 0, y);
+ AddAction(act, strlen(tbuf), y);
+ y++;
}
y++;
- while(y--)
- AddChar('\n');
bindkeydata->last = i;
sprintf(tbuf,"[Press Space %s Return to end.]", bindkeydata->page < bindkeydata->pages ? "for next page;" : "or");
- centerline(tbuf);
- SetLastPos(0, D_height-1);
+ centerline(tbuf, flayer->l_height - 2);
+ SetCursor();
}
static void
@@ -817,8 +981,7 @@ int *plen;
int done = 0;
struct bindkeydata *bindkeydata;
- bindkeydata = (struct bindkeydata *)D_lay->l_data;
- GotoPos(0, D_height-1);
+ bindkeydata = (struct bindkeydata *)flayer->l_data;
while (!done && *plen > 0)
{
switch (**ppbuf)
@@ -855,11 +1018,29 @@ int y, xs, xe, isblank;
bindkeypage();
return;
}
- if (y != 0 && y != D_height - 1)
+ if (y != 0 && y != flayer->l_height - 1)
return;
- if (isblank)
- return;
- Clear(xs, y, xs, xe, xe, y, 0);
+ if (!isblank)
+ LClear(flayer, xs, y, xe, y, 0);
+}
+
+#endif /* MAPKEYS */
+
+
+
+
+static void
+PadStr(str, n, x, y)
+char *str;
+int n, x, y;
+{
+ int l;
+
+ l = strlen(str);
+ if (l > n)
+ l = n;
+ LPutStr(flayer, str, l, &mchar_blank, x, y);
+ if (l < n)
+ LPutStr(flayer, blank, n - l, &mchar_blank, x + l, y);
}
-#endif
diff --git a/image.h b/image.h
index dbca3e5..6dc74be 100644
--- a/image.h
+++ b/image.h
@@ -23,8 +23,15 @@
*/
+#undef IFFONT
#undef IFCOLOR
+#ifdef FONT
+# define IFFONT(x) x
+#else
+# define IFFONT(x)
+#endif
+
#ifdef COLOR
# define IFCOLOR(x) x
#else
@@ -35,14 +42,14 @@
struct mchar {
char image;
char attr;
- char font;
+IFFONT( char font;)
IFCOLOR(char color;)
};
struct mline {
char *image;
char *attr;
- char *font;
+IFFONT( char *font;)
IFCOLOR(char *color;)
};
@@ -51,56 +58,56 @@ IFCOLOR(char *color;)
#define save_mline(ml, n) do { \
bcopy((ml)->image, mline_old.image, (n)); \
bcopy((ml)->attr, mline_old.attr, (n)); \
- bcopy((ml)->font, mline_old.font, (n)); \
+IFFONT( bcopy((ml)->font, mline_old.font, (n)); )\
IFCOLOR(bcopy((ml)->color, mline_old.color, (n)); )\
} while (0)
#define bcopy_mline(ml, xf, xt, n) do { \
bcopy((ml)->image + (xf), (ml)->image + (xt), (n)); \
bcopy((ml)->attr + (xf), (ml)->attr + (xt), (n)); \
- bcopy((ml)->font + (xf), (ml)->font + (xt), (n)); \
+IFFONT( bcopy((ml)->font + (xf), (ml)->font + (xt), (n)); )\
IFCOLOR(bcopy((ml)->color + (xf), (ml)->color + (xt), (n)); )\
} while (0)
#define clear_mline(ml, x, n) do { \
bclear((ml)->image + (x), (n)); \
if ((ml)->attr != null) bzero((ml)->attr + (x), (n)); \
- if ((ml)->font != null) bzero((ml)->font + (x), (n)); \
+IFFONT( if ((ml)->font != null) bzero((ml)->font + (x), (n)); )\
IFCOLOR(if ((ml)->color!= null) bzero((ml)->color + (x), (n)); )\
} while (0)
#define cmp_mline(ml1, ml2, x) ( \
(ml1)->image[x] == (ml2)->image[x] \
&& (ml1)->attr[x] == (ml2)->attr[x] \
- && (ml1)->font[x] == (ml2)->font[x] \
+IFFONT( && (ml1)->font[x] == (ml2)->font[x] )\
IFCOLOR(&& (ml1)->color[x] == (ml2)->color[x] )\
)
#define cmp_mchar(mc1, mc2) ( \
(mc1)->image == (mc2)->image \
&& (mc1)->attr == (mc2)->attr \
- && (mc1)->font == (mc2)->font \
+IFFONT( && (mc1)->font == (mc2)->font )\
IFCOLOR(&& (mc1)->color == (mc2)->color )\
)
#define cmp_mchar_mline(mc, ml, x) ( \
(mc)->image == (ml)->image[x] \
&& (mc)->attr == (ml)->attr[x] \
- && (mc)->font == (ml)->font[x] \
+IFFONT( && (mc)->font == (ml)->font[x] )\
IFCOLOR(&& (mc)->color == (ml)->color[x] )\
)
#define copy_mchar2mline(mc, ml, x) do { \
(ml)->image[x] = (mc)->image; \
(ml)->attr[x] = (mc)->attr; \
- (ml)->font[x] = (mc)->font; \
+IFFONT( (ml)->font[x] = (mc)->font; )\
IFCOLOR((ml)->color[x] = (mc)->color; )\
} while (0)
#define copy_mline2mchar(mc, ml, x) do { \
(mc)->image = (ml)->image[x]; \
(mc)->attr = (ml)->attr[x]; \
- (mc)->font = (ml)->font[x]; \
+IFFONT( (mc)->font = (ml)->font[x]; )\
IFCOLOR((mc)->color = (ml)->color[x]; )\
} while (0)
diff --git a/input.c b/input.c
index 6edff14..cf2ebf7 100644
--- a/input.c
+++ b/input.c
@@ -29,33 +29,35 @@ RCS_ID("$Id: input.c,v 1.2 1994/05/31 12:32:08 mlschroe Exp $ FAU")
#include "screen.h"
#include "extern.h"
+#define INPUTLINE (flayer->l_height - 1)
+
static void InpProcess __P((char **, int *));
static void InpAbort __P((void));
static void InpRedisplayLine __P((int, int, int, int));
-static void InpSetCursor __P((void));
+extern struct layer *flayer;
extern struct display *display;
extern struct mchar mchar_blank, mchar_so;
struct inpline
{
char buf[101]; /* text buffer */
- int len; /* length of the editible string */
- int pos; /* cursor position in editable string */
+ int len; /* length of the editible string */
+ int pos; /* cursor position in editable string */
};
-static struct inpline inphist; /* XXX: should be a dynamic list */
+static struct inpline inphist; /* XXX: should be a dynamic list */
struct inpdata
{
struct inpline inp;
- int inpmaxlen; /* 100, or less, if caller has shorter buffer */
- char *inpstring; /* the prompt */
- int inpstringlen; /* length of the prompt */
- int inpmode; /* INP_NOECHO, INP_RAW, INP_EVERY */
- void (*inpfinfunc) __P((char *buf, int len, char *priv));
- char *priv;
+ int inpmaxlen; /* 100, or less, if caller has shorter buffer */
+ char *inpstring; /* the prompt */
+ int inpstringlen; /* length of the prompt */
+ int inpmode; /* INP_NOECHO, INP_RAW, INP_EVERY */
+ void (*inpfinfunc) __P((char *buf, int len, char *priv));
+ char *priv; /* private data for finfunc */
};
static struct LayFuncs InpLf =
@@ -65,7 +67,6 @@ static struct LayFuncs InpLf =
InpRedisplayLine,
DefClearLine,
DefRewrite,
- InpSetCursor,
DefResize,
DefRestore
};
@@ -74,13 +75,14 @@ static struct LayFuncs InpLf =
** Here is the input routine
*/
+/* called once, after InitOverlayPage in Input() or Isearch() */
void
inp_setprompt(p, s)
char *p, *s;
{
struct inpdata *inpdata;
- inpdata = (struct inpdata *)D_lay->l_data;
+ inpdata = (struct inpdata *)flayer->l_data;
if (p)
{
inpdata->inpstringlen = strlen(p);
@@ -93,7 +95,7 @@ char *p, *s;
inpdata->inp.buf[sizeof(inpdata->inp.buf) - 1] = 0;
inpdata->inp.pos = inpdata->inp.len = strlen(inpdata->inp.buf);
}
- RefreshLine(STATLINE, 0, D_width - 1, 0);
+ InpRedisplayLine(INPUTLINE, 0, flayer->l_width - 1, 0);
}
/*
@@ -117,44 +119,30 @@ char *data;
int maxlen;
struct inpdata *inpdata;
- if (!display)
- {
- Msg(0, "Input: cannot interact with user w/o display. Try other form of command\n");
- return;
- }
if (len > 100)
len = 100;
if (!(mode & INP_NOECHO))
{
- maxlen = D_width - strlen(istr);
- if (!D_CLP && STATLINE == D_bot)
- maxlen--;
+ maxlen = flayer->l_width - 1 - strlen(istr);
if (len > maxlen)
len = maxlen;
}
if (len < 0)
{
- Msg(0, "Width %d chars too small", -len);
+ LMsg(0, "Width %d chars too small", -len);
return;
}
if (InitOverlayPage(sizeof(*inpdata), &InpLf, 1))
return;
- inpdata = (struct inpdata *)D_lay->l_data;
+ inpdata = (struct inpdata *)flayer->l_data;
inpdata->inpmaxlen = len;
inpdata->inpfinfunc = finfunc;
inpdata->inp.pos = inpdata->inp.len = 0;
inpdata->inpmode = mode;
inpdata->priv = data;
inp_setprompt(istr, (char *)NULL);
-}
-
-static void
-InpSetCursor()
-{
- struct inpdata *inpdata;
-
- inpdata = (struct inpdata *)D_lay->l_data;
- GotoPos(inpdata->inpstringlen + (inpdata->inpmode & INP_NOECHO ? 0 : inpdata->inp.pos), STATLINE);
+ flayer->l_x = inpdata->inpstringlen;
+ flayer->l_y = INPUTLINE;
}
static void
@@ -166,10 +154,12 @@ int *plen;
char *pbuf;
char ch;
struct inpdata *inpdata;
-
- inpdata = (struct inpdata *)D_lay->l_data;
+ struct display *inpdisplay;
- GotoPos(inpdata->inpstringlen + (inpdata->inpmode & INP_NOECHO ? 0 : inpdata->inp.pos), STATLINE);
+ inpdata = (struct inpdata *)flayer->l_data;
+ inpdisplay = display;
+
+ LGotoPos(flayer, inpdata->inpstringlen + (inpdata->inpmode & INP_NOECHO ? 0 : inpdata->inp.pos), INPUTLINE);
if (ppbuf == 0)
{
InpAbort();
@@ -188,11 +178,13 @@ int *plen;
{
inpdata->inp.buf[inpdata->inp.len] = ch;
inpdata->inp.buf[inpdata->inp.len + 1] = ch; /* gross */
+ display = inpdisplay;
(*inpdata->inpfinfunc)(inpdata->inp.buf, inpdata->inp.len, inpdata->priv);
ch = inpdata->inp.buf[inpdata->inp.len];
}
else if (inpdata->inpmode & INP_RAW)
{
+ display = inpdisplay;
(*inpdata->inpfinfunc)(&ch, 1, inpdata->priv); /* raw */
if (ch)
continue;
@@ -201,20 +193,25 @@ int *plen;
{
if (inpdata->inp.len > inpdata->inp.pos)
bcopy(p, p+1, inpdata->inp.len - inpdata->inp.pos);
- inpdata->inp.len++;
inpdata->inp.buf[inpdata->inp.pos++] = ch;
+ inpdata->inp.len++;
if (!(inpdata->inpmode & INP_NOECHO))
{
- GotoPos(x, STATLINE);
- SetRendition(&mchar_so);
- PUTCHAR(*p++);
+ struct mchar mc;
+ mc = mchar_so;
+ mc.image = *p++;
+ LPutChar(flayer, &mc, x, INPUTLINE);
x++;
if (p < inpdata->inp.buf+inpdata->inp.len)
{
while (p < inpdata->inp.buf+inpdata->inp.len)
- PUTCHAR(*p++);
- GotoPos(x, STATLINE);
+ {
+ mc.image = *p++;
+ LPutChar(flayer, &mc, x++, INPUTLINE);
+ }
+ x = inpdata->inpstringlen + inpdata->inp.pos;
+ LGotoPos(flayer, x, INPUTLINE);
}
}
}
@@ -225,60 +222,90 @@ int *plen;
inpdata->inp.len--;
inpdata->inp.pos--;
p--;
- if (!(inpdata->inpmode & 1))
+
+ if (!(inpdata->inpmode & INP_NOECHO))
{
+ struct mchar mc;
+ mc = mchar_so;
x--;
- GotoPos(x, STATLINE);
- SetRendition(&mchar_so);
while (p < inpdata->inp.buf+inpdata->inp.len)
- PUTCHAR(*p++);
- SetRendition(&mchar_blank);
- PUTCHAR(' ');
- GotoPos(x, STATLINE);
+ {
+ mc.image = *p++;
+ LPutChar(flayer, &mc, x++, INPUTLINE);
+ }
+ LPutChar(flayer, &mchar_blank, x, INPUTLINE);
+ x = inpdata->inpstringlen + inpdata->inp.pos;
+ LGotoPos(flayer, x, INPUTLINE);
}
}
+ else if (ch == '\025') /* CTRL-U */
+ {
+ x = inpdata->inpstringlen;
+ if (inpdata->inp.len && !(inpdata->inpmode & INP_NOECHO))
+ {
+ LClear(flayer, x, INPUTLINE, x + inpdata->inp.len - 1, INPUTLINE, 0);
+ LGotoPos(flayer, x, INPUTLINE);
+ }
+ inpdata->inp.len = inpdata->inp.pos = 0;
+ }
+ else if (ch == '\013') /* CTRL-K */
+ {
+ x = inpdata->inpstringlen + inpdata->inp.pos;
+ if (inpdata->inp.len > inpdata->inp.pos && !(inpdata->inpmode & INP_NOECHO))
+ {
+ LClear(flayer, x, INPUTLINE, x + inpdata->inp.len - inpdata->inp.pos - 1, INPUTLINE, 0);
+ LGotoPos(flayer, x, INPUTLINE);
+ }
+ inpdata->inp.len = inpdata->inp.pos;
+ }
else if (ch == '\001' || (unsigned char)ch == 0201) /* CTRL-A */
{
- GotoPos(x -= inpdata->inp.pos, STATLINE);
+ LGotoPos(flayer, x -= inpdata->inp.pos, INPUTLINE);
inpdata->inp.pos = 0;
}
else if ((ch == '\002' || (unsigned char)ch == 0202) && inpdata->inp.pos > 0) /* CTRL-B */
{
- GotoPos(--x, STATLINE);
+ LGotoPos(flayer, --x, INPUTLINE);
inpdata->inp.pos--;
}
else if (ch == '\005' || (unsigned char)ch == 0205) /* CTRL-E */
{
- GotoPos(x += inpdata->inp.len - inpdata->inp.pos, STATLINE);
+ LGotoPos(flayer, x += inpdata->inp.len - inpdata->inp.pos, INPUTLINE);
inpdata->inp.pos = inpdata->inp.len;
}
else if ((ch == '\006' || (unsigned char)ch == 0206) && inpdata->inp.pos < inpdata->inp.len) /* CTRL-F */
{
- GotoPos(++x, STATLINE);
+ LGotoPos(flayer, ++x, INPUTLINE);
inpdata->inp.pos++;
}
else if (ch == '\020' || (unsigned char)ch == 0220) /* CTRL-P */
{
- p = inpdata->inp.buf;
- GotoPos(inpdata->inpstringlen, STATLINE);
- SetRendition(&mchar_blank);
- while (p++ < inpdata->inp.buf+inpdata->inp.len)
- PUTCHAR(' ');
+ struct mchar mc;
+ mc = mchar_so;
+ if (inpdata->inp.len && !(inpdata->inpmode & INP_NOECHO))
+ LClear(flayer, inpdata->inpstringlen, INPUTLINE, inpdata->inpstringlen + inpdata->inp.len - 1, INPUTLINE, 0);
inpdata->inp = inphist; /* structure copy */
if (inpdata->inp.len > inpdata->inpmaxlen)
inpdata->inp.len = inpdata->inpmaxlen;
if (inpdata->inp.pos > inpdata->inp.len)
inpdata->inp.pos = inpdata->inp.len;
- x = inpdata->inpstringlen + inpdata->inp.pos;
+ x = inpdata->inpstringlen;
p = inpdata->inp.buf;
- GotoPos(inpdata->inpstringlen, STATLINE);
- SetRendition(&mchar_so);
- while (p < inpdata->inp.buf+inpdata->inp.len)
- PUTCHAR(*p++);
- GotoPos(x, STATLINE);
+
+ if (!(inpdata->inpmode & INP_NOECHO))
+ {
+ while (p < inpdata->inp.buf+inpdata->inp.len)
+ {
+ mc.image = *p++;
+ LPutChar(flayer, &mc, x++, INPUTLINE);
+ }
+ }
+ x = inpdata->inpstringlen + inpdata->inp.pos;
+ LGotoPos(flayer, x, INPUTLINE);
}
+
else if (ch == '\004' || ch == '\003' || ch == '\007' || ch == '\033' ||
ch == '\000' || ch == '\n' || ch == '\r')
{
@@ -286,14 +313,15 @@ int *plen;
inpdata->inp.len = 0;
inpdata->inp.buf[inpdata->inp.len] = 0;
- if (inpdata->inp.len)
+ if (inpdata->inp.len && inpdata->inpmode == 0)
inphist = inpdata->inp; /* structure copy */
- D_lay->l_data = 0;
- InpAbort(); /* redisplays... */
+ flayer->l_data = 0;
+ InpAbort(); /* redisplays... */
*ppbuf = pbuf;
*plen = len;
- if ((inpdata->inpmode & INP_RAW) == 0)
+ display = inpdisplay;
+ if ((inpdata->inpmode & INP_RAW) == 0)
(*inpdata->inpfinfunc)(inpdata->inp.buf, inpdata->inp.len, inpdata->priv);
else
(*inpdata->inpfinfunc)(pbuf - 1, 0, inpdata->priv);
@@ -301,6 +329,11 @@ int *plen;
return;
}
}
+ if (!(inpdata->inpmode & INP_RAW))
+ {
+ flayer->l_x = inpdata->inpstringlen + (inpdata->inpmode & INP_NOECHO ? 0 : inpdata->inp.pos);
+ flayer->l_y = INPUTLINE;
+ }
*ppbuf = pbuf;
*plen = len;
}
@@ -308,7 +341,7 @@ int *plen;
static void
InpAbort()
{
- LAY_CALL_UP(RefreshLine(STATLINE, 0, D_width - 1, 0));
+ LAY_CALL_UP(RedisplayLine(INPUTLINE, 0, flayer->l_width - 1, 0));
ExitOverlayPage();
}
@@ -319,26 +352,23 @@ int y, xs, xe, isblank;
int q, r, s, l, v;
struct inpdata *inpdata;
- inpdata = (struct inpdata *)D_lay->l_data;
-
- if (y != STATLINE)
+ inpdata = (struct inpdata *)flayer->l_data;
+ if (y != INPUTLINE)
{
- LAY_CALL_UP(RefreshLine(y, xs, xe, isblank));
+ LAY_CALL_UP(RedisplayLine(y, xs, xe, isblank));
return;
}
inpdata->inp.buf[inpdata->inp.len] = 0;
- GotoPos(xs, y);
q = xs;
v = xe - xs + 1;
s = 0;
r = inpdata->inpstringlen;
if (v > 0 && q < r)
{
- SetRendition(&mchar_so);
l = v;
- if (l > r-q)
- l = r-q;
- AddStrn(inpdata->inpstring + q - s, l);
+ if (l > r - q)
+ l = r - q;
+ LPutStr(flayer, inpdata->inpstring + q - s, l, &mchar_so, q, y);
q += l;
v -= l;
}
@@ -346,32 +376,29 @@ int y, xs, xe, isblank;
r += inpdata->inp.len;
if (!(inpdata->inpmode & INP_NOECHO) && v > 0 && q < r)
{
- SetRendition(&mchar_so);
l = v;
- if (l > r-q)
- l = r-q;
- AddStrn(inpdata->inp.buf + q - s, l);
+ if (l > r - q)
+ l = r - q;
+ LPutStr(flayer, inpdata->inp.buf + q - s, l, &mchar_so, q, y);
q += l;
v -= l;
}
s = r;
- r = D_width;
+ r = flayer->l_width;
if (!isblank && v > 0 && q < r)
{
- SetRendition(&mchar_blank);
l = v;
- if (l > r-q)
- l = r-q;
- AddStrn("", l);
+ if (l > r - q)
+ l = r - q;
+ LClear(flayer, q, y, q + l - 1, y, 0);
q += l;
}
- SetLastPos(q, y);
}
int
InInput()
{
- if (display && D_layfn->LayProcess == InpProcess)
+ if (flayer && flayer->l_layfn == &InpLf)
return 1;
return 0;
}
diff --git a/kmapdef.c.dist b/kmapdef.c.dist
index fef98ed..fd7bfbb 100644
--- a/kmapdef.c.dist
+++ b/kmapdef.c.dist
@@ -28,8 +28,6 @@ char *kmapdef[] = {
0,
0,
0,
-"\010",
-"\033[1~",
0,
0,
0,
@@ -39,21 +37,23 @@ char *kmapdef[] = {
0,
0,
0,
-"\033[3~",
0,
0,
-"\033[4~",
-"\033[2~",
0,
0,
-"\033[6~",
-"\033[5~",
0,
0,
0,
0,
0,
+"\033[1~",
0,
+"\033[4~",
+0,
+"\033[6~",
+"\033[5~",
+"\033[2~",
+"\033[3~",
"\033[A",
"\033[B",
"\033[C",
@@ -104,29 +104,19 @@ char *kmapadef[] = {
};
char *kmapmdef[] = {
-"\201",
-0,
-0,
-0,
-0,
-0,
+"\004",
0,
0,
+"\025",
0,
0,
0,
+"\201",
0,
-"\004",
"\205",
0,
-0,
-0,
"\006",
"\002",
-"\025",
-0,
-0,
-0,
0,
0,
"\220",
diff --git a/layer.c b/layer.c
new file mode 100644
index 0000000..dfd40a8
--- /dev/null
+++ b/layer.c
@@ -0,0 +1,938 @@
+/* Copyright (c) 1993
+ * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
+ * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
+ * Copyright (c) 1987 Oliver Laumann
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING); if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ ****************************************************************
+ */
+
+#include "rcs.h"
+RCS_ID("$Id: search.c,v 1.2 1994/05/31 12:32:57 mlschroe Exp $ FAU")
+
+#include <sys/types.h>
+
+#include "config.h"
+#include "screen.h"
+#include "mark.h"
+#include "extern.h"
+#include "braille.h"
+
+extern struct display *display, *displays;
+
+extern struct mline mline_blank;
+extern struct mline mline_null;
+extern struct mchar mchar_null;
+extern struct mchar mchar_blank;
+
+extern struct layer *flayer; /* sigh */
+extern struct LayFuncs WinLf;
+extern struct LayFuncs BlankLf;
+
+
+static struct mline *mloff __P((struct mline *, int));
+
+/*
+ * Layer subsystem.
+ *
+ * ...here is all the clipping code... beware!
+ *
+ * XXX: add some speedup code!
+ *
+ */
+
+static struct mline *
+mloff(ml, off)
+struct mline *ml;
+int off;
+{
+ static struct mline mml;
+
+ if (ml == 0)
+ return 0;
+ mml.image = ml->image + off;
+ mml.attr = ml->attr + off;
+#ifdef FONT
+ mml.font = ml->font + off;
+#endif
+#ifdef COLOR
+ mml.color = ml->color + off;
+#endif
+ return &mml;
+}
+
+void
+LGotoPos(l, x, y)
+struct layer *l;
+int x, y;
+{
+ struct canvas *cv;
+ struct viewport *vp;
+ int x2, y2;
+
+#ifdef HAVE_BRAILLE
+ if (bd.bd_refreshing)
+ return;
+#endif
+ for (cv = l->l_cvlist; cv; cv = cv->c_lnext)
+ {
+ display = cv->c_display;
+ if (cv != D_forecv)
+ continue;
+ x2 = x + cv->c_xoff;
+ y2 = y + cv->c_yoff;
+ debug2("---LGotoPos %d %d\n", x2, y2);
+ if (x2 < cv->c_xs)
+ x2 = cv->c_xs;
+ if (y2 < cv->c_ys)
+ y2 = cv->c_ys;
+ if (x2 > cv->c_xe)
+ x2 = cv->c_xe;
+ if (y2 > cv->c_ye)
+ y2 = cv->c_ye;
+ for (vp = cv->c_vplist; vp; vp = vp->v_next)
+ {
+ if (x2 < vp->v_xs || x2 > vp->v_xe)
+ continue;
+ if (y2 < vp->v_ys || y2 > vp->v_ye)
+ continue;
+ GotoPos(x2, y2);
+ break;
+ }
+ }
+}
+
+void
+LScrollH(l, n, y, xs, xe, ol)
+struct layer *l;
+int n, y, xs, xe;
+struct mline *ol;
+{
+ struct canvas *cv;
+ struct viewport *vp;
+ int y2, xs2, xe2;
+
+ if (n == 0)
+ return;
+ for (cv = l->l_cvlist; cv; cv = cv->c_lnext)
+ for (vp = cv->c_vplist; vp; vp = vp->v_next)
+ {
+ y2 = y + vp->v_yoff;
+ if (y2 < vp->v_ys || y2 > vp->v_ye)
+ continue;
+ xs2 = xs + vp->v_xoff;
+ xe2 = xe + vp->v_xoff;
+ if (xs2 < vp->v_xs)
+ xs2 = vp->v_xs;
+ if (xe2 > vp->v_xe)
+ xe2 = vp->v_xe;
+ if (xs2 > xe2)
+ continue;
+ display = cv->c_display;
+ ScrollH(y2, xs2, xe2, n, ol ? mloff(ol, -vp->v_xoff) : 0);
+ if (xe2 - xs2 == xe - xs)
+ continue;
+ if (n > 0)
+ {
+ xs2 = xe2 + 1 - n;
+ xe2 = xe + vp->v_xoff - n;
+ }
+ else
+ {
+ xe2 = xs2 - 1 - n;
+ xs2 = xs + vp->v_xoff - n;
+ }
+ if (xs2 < vp->v_xs)
+ xs2 = vp->v_xs;
+ if (xe2 > vp->v_xe)
+ xe2 = vp->v_xe;
+ if (xs2 <= xe2)
+ RefreshArea(xs2, y2, xe2, y2, 1);
+ }
+}
+
+void
+LScrollV(l, n, ys, ye)
+struct layer *l;
+int n;
+int ys, ye;
+{
+ struct canvas *cv;
+ struct viewport *vp;
+ int ys2, ye2, xs2, xe2;
+ if (n == 0)
+ return;
+ for (cv = l->l_cvlist; cv; cv = cv->c_lnext)
+ for (vp = cv->c_vplist; vp; vp = vp->v_next)
+ {
+ xs2 = vp->v_xoff;
+ xe2 = l->l_width - 1 + vp->v_xoff;
+ ys2 = ys + vp->v_yoff;
+ ye2 = ye + vp->v_yoff;
+ if (xs2 < vp->v_xs)
+ xs2 = vp->v_xs;
+ if (xe2 > vp->v_xe)
+ xe2 = vp->v_xe;
+ if (ys2 < vp->v_ys)
+ ys2 = vp->v_ys;
+ if (ye2 > vp->v_ye)
+ ye2 = vp->v_ye;
+ if (ys2 > ye2 || xs2 > xe2)
+ continue;
+ display = cv->c_display;
+#if 0
+ ScrollV(xs2, ys2, xe2, ye2, n);
+#else
+ ScrollV(vp->v_xs, ys2, vp->v_xe, ye2, n);
+#endif
+ debug2("LScrollV: %d %d", ys, ye);
+ debug2(" -> %d %d\n", ys2, ye2);
+ if (ye2 - ys2 == ye - ys)
+ continue;
+ if (n > 0)
+ {
+ ys2 = ye2 + 1 - n;
+ ye2 = ye + vp->v_yoff - n;
+ }
+ else
+ {
+ ye2 = ys2 - 1 - n;
+ ys2 = ys + vp->v_yoff - n;
+ }
+ debug2("LScrollV: - %d %d\n", ys2, ye2);
+ if (ys2 < vp->v_ys)
+ ys2 = vp->v_ys;
+ if (ye2 > vp->v_ye)
+ ye2 = vp->v_ye;
+ debug2("LScrollV: - %d %d\n", ys2, ye2);
+ if (ys2 <= ye2)
+ RefreshArea(xs2, ys2, xe2, ye2, 1);
+ }
+}
+
+void
+LInsChar(l, c, x, y, ol)
+struct layer *l;
+struct mchar *c;
+int x, y;
+struct mline *ol;
+{
+ struct canvas *cv;
+ struct viewport *vp;
+ int xs2, xe2, y2, f;
+ struct mchar *c2, cc;
+
+ for (cv = l->l_cvlist; cv; cv = cv->c_lnext)
+ for (vp = cv->c_vplist; vp; vp = vp->v_next)
+ {
+ y2 = y + vp->v_yoff;
+ if (y2 < vp->v_ys || y2 > vp->v_ye)
+ continue;
+ xs2 = x + vp->v_xoff;
+ xe2 = l->l_width - 1 + vp->v_xoff;
+ c2 = c;
+ f = 0;
+ if (xs2 < vp->v_xs)
+ {
+ xs2 = vp->v_xs;
+ c2 = &mchar_blank;
+ if (ol)
+ {
+ int i;
+ i = xs2 - vp->v_xoff - 1;
+ if (i >= 0 && i < l->l_width)
+ {
+ copy_mline2mchar(&cc, ol, i);
+ c2 = &cc;
+ }
+ }
+ else
+ f = 1;
+ }
+ if (xe2 > vp->v_xe)
+ xe2 = vp->v_xe;
+ if (xs2 > xe2)
+ continue;
+ display = cv->c_display;
+ InsChar(c2, xs2, xe2, y2, mloff(ol, -vp->v_xoff));
+ if (f)
+ RefreshArea(xs2, y2, xs2, y2, 1);
+ }
+}
+
+void
+LPutChar(l, c, x, y)
+struct layer *l;
+struct mchar *c;
+int x, y;
+{
+ struct canvas *cv;
+ struct viewport *vp;
+ int x2, y2;
+#ifdef HAVE_BRAILLE
+ if (bd.bd_refreshing)
+ {
+ BPutChar(l, c, x, y);
+ return;
+ }
+#endif
+ for (cv = l->l_cvlist; cv; cv = cv->c_lnext)
+ for (vp = cv->c_vplist; vp; vp = vp->v_next)
+ {
+ y2 = y + vp->v_yoff;
+ if (y2 < vp->v_ys || y2 > vp->v_ye)
+ continue;
+ x2 = x + vp->v_xoff;
+ if (x2 < vp->v_xs || x2 > vp->v_xe)
+ continue;
+ display = cv->c_display;
+ GotoPos(x2, y2);
+ SetRendition(c);
+ PUTCHARLP(c->image);
+ if (D_AM && !D_CLP && x2 == D_width - 1)
+ GotoPos(x2, y2);
+ }
+}
+
+void
+LPutStr(l, s, n, r, x, y)
+struct layer *l;
+char *s;
+int n;
+struct mchar *r;
+int x, y;
+{
+ struct canvas *cv;
+ struct viewport *vp;
+ char *s2;
+ int xs2, xe2, y2;
+
+ if (x + n > l->l_width)
+ n = l->l_width - x;
+#ifdef HAVE_BRAILLE
+ if (bd.bd_refreshing)
+ {
+ BPutStr(l, s, n, r, x, y);
+ return;
+ }
+#endif
+ for (cv = l->l_cvlist; cv; cv = cv->c_lnext)
+ for (vp = cv->c_vplist; vp; vp = vp->v_next)
+ {
+ y2 = y + vp->v_yoff;
+ if (y2 < vp->v_ys || y2 > vp->v_ye)
+ continue;
+ xs2 = x + vp->v_xoff;
+ xe2 = xs2 + n - 1;
+ if (xs2 < vp->v_xs)
+ xs2 = vp->v_xs;
+ if (xe2 > vp->v_xe)
+ xe2 = vp->v_xe;
+ if (xs2 > xe2)
+ continue;
+ display = cv->c_display;
+ GotoPos(xs2, y2);
+ SetRendition(r);
+ s2 = s + xs2 - x - vp->v_xoff;
+ while (xs2++ <= xe2)
+ PUTCHARLP(*s2++);
+ }
+}
+
+void
+LClearLine(l, y, xs, xe, ol)
+struct layer *l;
+int xs, xe;
+struct mline *ol;
+{
+ struct canvas *cv;
+ struct viewport *vp;
+ int y2, xs2, xe2;
+
+ /* check for magic margin condition */
+ if (xs >= l->l_width)
+ xs = l->l_width - 1;
+ if (xe >= l->l_width)
+ xe = l->l_width - 1;
+ for (cv = l->l_cvlist; cv; cv = cv->c_lnext)
+ for (vp = cv->c_vplist; vp; vp = vp->v_next)
+ {
+ xs2 = xs + vp->v_xoff;
+ xe2 = xe + vp->v_xoff;
+ y2 = y + vp->v_yoff;
+ if (y2 < vp->v_ys || y2 > vp->v_ye)
+ continue;
+ if (xs2 < vp->v_xs)
+ xs2 = vp->v_xs;
+ if (xe2 > vp->v_xe)
+ xe2 = vp->v_xe;
+ if (xs2 > xe2)
+ continue;
+ display = cv->c_display;
+ DisplayLine(ol ? mloff(ol, -vp->v_xoff) : &mline_null, &mline_blank, y2, xs2, xe2);
+ }
+}
+
+void
+LClear(l, xs, ys, xe, ye, uself)
+struct layer *l;
+int xs, ys, xe, ye;
+int uself;
+{
+ struct canvas *cv;
+ struct viewport *vp;
+ int xs2, ys2, xe2, ye2;
+#ifdef HAVE_BRAILLE
+ if (bd.bd_refreshing)
+ return;
+#endif
+ /* check for magic margin condition */
+ if (xs >= l->l_width)
+ xs = l->l_width - 1;
+ if (xe >= l->l_width)
+ xe = l->l_width - 1;
+ for (cv = l->l_cvlist; cv; cv = cv->c_lnext)
+ for (vp = cv->c_vplist; vp; vp = vp->v_next)
+ {
+ xs2 = xs + vp->v_xoff;
+ xe2 = xe + vp->v_xoff;
+ ys2 = ys + vp->v_yoff;
+ ye2 = ye + vp->v_yoff;
+ if (xs2 < vp->v_xs)
+ xs2 = vp->v_xs;
+ if (xe2 > vp->v_xe)
+ xe2 = vp->v_xe;
+ if (xs2 > vp->v_xe)
+ ys2++;
+ if (xe2 < vp->v_xs)
+ ye2--;
+ if (ys2 < vp->v_ys)
+ ys2 = vp->v_ys;
+ if (ye2 > vp->v_ye)
+ ye2 = vp->v_ye;
+ if (ys2 > ye2)
+ continue;
+#if 0
+ xcs = vp->v_xoff;
+ xce = l->l_width - 1 + vp->v_xoff;
+ if (xcs < vp->v_xs)
+ xcs = vp->v_xs;
+ if (xce > vp->v_xe)
+ xce = vp->v_xe;
+ if (xcs > xce)
+ continue;
+ if (ys2 != ys + vp->v_yoff)
+ xs2 = xcs;
+ if (ye2 != ye + vp->v_yoff)
+ xe2 = xce;
+ display = cv->c_display;
+ Clear(xs2, ys2, xcs, xce, xe2, ye2, uself);
+#else
+ if (xs == 0 || ys2 != ys + vp->v_yoff)
+ xs2 = vp->v_xs;
+ if (xe == l->l_width - 1 || ye2 != ye + vp->v_yoff)
+ xe2 = vp->v_xe;
+ display = cv->c_display;
+ Clear(xs2, ys2, vp->v_xs, vp->v_xe, xe2, ye2, uself);
+#endif
+ }
+}
+
+void
+LCDisplayLine(l, ml, y, xs, xe, isblank)
+struct layer *l;
+struct mline *ml;
+int y, xs, xe;
+int isblank;
+{
+ struct canvas *cv;
+ struct viewport *vp;
+ int xs2, xe2, y2;
+#ifdef HAVE_BRAILLE
+ if (bd.bd_refreshing)
+ {
+ BCDisplayLine(l, ml, y, xs, xe, isblank);
+ return;
+ }
+#endif
+ for (cv = l->l_cvlist; cv; cv = cv->c_lnext)
+ for (vp = cv->c_vplist; vp; vp = vp->v_next)
+ {
+ xs2 = xs + vp->v_xoff;
+ xe2 = xe + vp->v_xoff;
+ y2 = y + vp->v_yoff;
+ if (y2 < vp->v_ys || y2 > vp->v_ye)
+ continue;
+ if (xs2 < vp->v_xs)
+ xs2 = vp->v_xs;
+ if (xe2 > vp->v_xe)
+ xe2 = vp->v_xe;
+ if (xs2 > xe2)
+ continue;
+ display = cv->c_display;
+ debug3("LCDisplayLine: DisplayLine %d, %d-%d", y2, xs2, xe2);
+ debug1(" mloff = %d\n", -vp->v_xoff);
+ DisplayLine(isblank ? &mline_blank : &mline_null, mloff(ml, -vp->v_xoff), y2, xs2, xe2);
+ }
+}
+
+void
+LSetRendition(l, r)
+struct layer *l;
+struct mchar *r;
+{
+ struct canvas *cv;
+ struct viewport *vp;
+
+ for (cv = l->l_cvlist; cv; cv = cv->c_lnext)
+ for (vp = cv->c_vplist; vp; vp = vp->v_next)
+ {
+ display = cv->c_display;
+ SetRendition(r);
+ }
+}
+
+void
+LWrapChar(l, c, y, top, bot, ins)
+struct layer *l;
+struct mchar *c;
+int y, top, bot;
+int ins;
+{
+ struct canvas *cv, *cvlist, *cvlnext;
+ struct viewport *vp, *evp, **vpp;
+ int yy, y2, yy2, top2, bot2;
+
+ if (y != bot)
+ {
+ /* simple case: no scrolling */
+
+ /* cursor after wrapping */
+ yy = y == l->l_height - 1 ? y : y + 1;
+
+ for (cv = l->l_cvlist; cv; cv = cv->c_lnext)
+ {
+ display = cv->c_display;
+ /* find the viewport of the wrapped character */
+ for (vp = cv->c_vplist; vp; vp = vp->v_next)
+ {
+ y2 = y + vp->v_yoff;
+ yy2 = yy + vp->v_yoff;
+ if (yy2 >= vp->v_ys && yy2 <= vp->v_ye && vp->v_xoff >= vp->v_xs && vp->v_xoff <= vp->v_xe)
+ break;
+ }
+ if (vp == 0)
+ continue; /* nothing to do, character not visible */
+ /* find the viewport of the character at the end of the line*/
+ for (evp = cv->c_vplist; evp; evp = evp->v_next)
+ if (y2 >= evp->v_ys && y2 <= evp->v_ye && evp->v_xoff + l->l_width - 1 >= evp->v_xs && evp->v_xoff + l->l_width - 1 <= evp->v_xe)
+ break; /* gotcha! */
+ if (evp == 0 || (ins && vp->v_xoff + l->l_width - 1 > vp->v_ye))
+ {
+ /* no wrapping possible */
+ debug("LWrap: can't wrap!\n");
+ cvlist = l->l_cvlist;
+ cvlnext = cv->c_lnext;
+ l->l_cvlist = cv;
+ cv->c_lnext = 0;
+ if (ins)
+ LInsChar(l, c, 0, yy, 0);
+ else
+ LPutChar(l, c, 0, yy);
+ l->l_cvlist = cvlist;
+ cv->c_lnext = cvlnext;
+ }
+ else
+ WrapChar(c, vp->v_xoff + l->l_width, y2, vp->v_xoff, -1, vp->v_xoff + l->l_width - 1, -1, ins);
+ }
+ }
+ else
+ {
+ /* hard case: scroll up*/
+
+ for (cv = l->l_cvlist; cv; cv = cv->c_lnext)
+ {
+ display = cv->c_display;
+ /* search for wrap viewport */
+ for (vpp = &cv->c_vplist; (vp = *vpp); vpp = &vp->v_next)
+ {
+ yy2 = bot + vp->v_yoff;
+ if (yy2 >= vp->v_ys && yy2 <= vp->v_ye && vp->v_xoff >= vp->v_xs && vp->v_xoff + l->l_width - 1 <= vp->v_xe)
+ break;
+ }
+
+ if (vp)
+ {
+ /* great, can use Wrap on the vp */
+ /* temporarily remove vp from cvlist */
+ *vpp = vp->v_next;
+ }
+ if (cv->c_vplist)
+ {
+ /* scroll all viewports != vp */
+ cvlist = l->l_cvlist;
+ cvlnext = cv->c_lnext;
+ l->l_cvlist = cv;
+ cv->c_lnext = 0;
+ LScrollV(l, 1, top, bot);
+ if (!vp)
+ {
+ if (ins)
+ LInsChar(l, c, 0, bot, 0);
+ else
+ LPutChar(l, c, 0, bot);
+ }
+ l->l_cvlist = cvlist;
+ cv->c_lnext = cvlnext;
+ }
+ if (vp)
+ {
+ /* add vp back to cvlist */
+ *vpp = vp;
+ top2 = top + vp->v_yoff;
+ bot2 = bot + vp->v_yoff;
+ if (top2 < vp->v_ys)
+ top2 = vp->v_ys;
+ WrapChar(c, vp->v_xoff + l->l_width, bot2, vp->v_xoff, top2, vp->v_xoff + l->l_width - 1, bot2, ins);
+ }
+ }
+ }
+}
+
+
+void
+LCursorVisibility(l, vis)
+struct layer *l;
+int vis;
+{
+ struct canvas *cv;
+ for (cv = l->l_cvlist; cv; cv = cv->c_lnext)
+ {
+ display = cv->c_display;
+ if (cv != D_forecv)
+ continue;
+ CursorVisibility(vis);
+ }
+}
+
+void
+LSetFlow(l, flow)
+struct layer *l;
+int flow;
+{
+ struct canvas *cv;
+ for (cv = l->l_cvlist; cv; cv = cv->c_lnext)
+ {
+ display = cv->c_display;
+ if (cv != D_forecv)
+ continue;
+ SetFlow(flow);
+ }
+}
+
+void
+LKeypadMode(l, on)
+struct layer *l;
+int on;
+{
+ struct canvas *cv;
+ for (cv = l->l_cvlist; cv; cv = cv->c_lnext)
+ {
+ display = cv->c_display;
+ if (cv != D_forecv)
+ continue;
+ KeypadMode(on);
+ }
+}
+
+void
+LCursorkeysMode(l, on)
+struct layer *l;
+int on;
+{
+ struct canvas *cv;
+ for (cv = l->l_cvlist; cv; cv = cv->c_lnext)
+ {
+ display = cv->c_display;
+ if (cv != D_forecv)
+ continue;
+ CursorkeysMode(on);
+ }
+}
+
+
+/*******************************************************************/
+
+void
+ClearLayer(l, uself)
+struct layer *l;
+int uself;
+{
+ LClear(l, 0, 0, l->l_width - 1, l->l_height - 1, uself);
+}
+
+void
+RedisplayLayer(l, isblank)
+struct layer *l;
+int isblank;
+{
+ struct layer *oldflayer;
+ int y;
+
+ debug1("RedisplayLayer isblank=%d\n", isblank);
+ oldflayer = flayer;
+ flayer = l;
+ if (!isblank)
+ LClear(l, 0, 0, l->l_width - 1, l->l_height - 1, 0);
+ /* signal full refresh */
+ RedisplayLine(-1, -1, -1, 1);
+ for (y = 0; y < l->l_height; y++)
+ RedisplayLine(y, 0, l->l_width - 1, 1);
+ flayer = oldflayer;
+}
+
+
+void
+KillLayerChain(lay)
+struct layer *lay;
+{
+ struct canvas *cv, *ncv;
+ struct layer *l, *oldflayer;
+
+ oldflayer = flayer;
+ debug1("KillLayerChain %#x\n", lay);
+ for (l = lay; l; l = l->l_next)
+ {
+ if (l->l_layfn == &WinLf || l->l_layfn == &BlankLf)
+ break;
+ debug1("- killing %#x\n", l);
+ if (oldflayer == l)
+ oldflayer = 0;
+ for (cv = l->l_cvlist; cv; cv = ncv)
+ {
+ ncv = cv->c_lnext;
+ cv->c_layer = 0;
+ cv->c_lnext = 0;
+ }
+ }
+ flayer = lay;
+ while (flayer != l)
+ ExitOverlayPage();
+ flayer = oldflayer;
+}
+
+
+/*******************************************************************/
+/*******************************************************************/
+
+/*
+ * Layer creation / removal
+ */
+
+int
+InitOverlayPage(datasize, lf, block)
+int datasize;
+struct LayFuncs *lf;
+int block;
+{
+ char *data;
+ struct layer *newlay;
+ struct canvas *cv, *cvp, **cvpp;
+ struct win *p;
+
+ ASSERT(flayer);
+
+ cv = 0;
+ if (display && D_forecv->c_layer == flayer)
+ cv = D_forecv; /* work only on this cv! */
+
+ if ((newlay = (struct layer *)calloc(1, sizeof(struct layer))) == 0)
+ {
+ Msg(0, "No memory for layer struct");
+ return -1;
+ }
+ debug2("Entering new layer on top of %#x: %#x\n", (unsigned int)flayer, newlay);
+ data = 0;
+ if (datasize)
+ {
+ if ((data = malloc(datasize)) == 0)
+ {
+ free((char *)newlay);
+ Msg(0, "No memory for layer data");
+ return -1;
+ }
+ bzero(data, datasize);
+ }
+
+ p = Layer2Window(flayer);
+
+ if (p && (p->w_savelayer == flayer || (block && flayer->l_next == 0)))
+ {
+ if (p->w_savelayer && p->w_savelayer != flayer && p->w_savelayer->l_cvlist == 0)
+ KillLayerChain(p->w_savelayer);
+ p->w_savelayer = newlay;
+ }
+
+ if (cv && flayer->l_next == 0 && !block)
+ {
+ struct display *olddisplay = display;
+ display = cv->c_display;
+ RemoveStatus();
+ display = olddisplay;
+
+ /* new branch -> just get canvas vps */
+ for (cvpp = &flayer->l_cvlist; (cvp = *cvpp); cvpp = &cvp->c_lnext)
+ if (cvp == cv)
+ break;
+ ASSERT(cvp);
+ *cvpp = cv->c_lnext;
+ newlay->l_cvlist = cv;
+ cv->c_lnext = 0;
+ cv->c_layer = newlay;
+ }
+ else
+ {
+ LAY_DISPLAYS(flayer, RemoveStatus());
+ if (block)
+ debug("layer is blocking\n");
+ if (block && flayer->l_layfn == &WinLf)
+ {
+ debug("...and is first, so window gets blocked\n");
+ ASSERT(p->w_blocked == 0);
+ p->w_blocked++;
+ newlay->l_blocking = 1;
+ }
+ /* change all canvases */
+ newlay->l_cvlist = flayer->l_cvlist;
+ for (cvp = newlay->l_cvlist; cvp; cvp = cvp->c_lnext)
+ cvp->c_layer = newlay;
+ flayer->l_cvlist = 0;
+ }
+ newlay->l_width = flayer->l_width;
+ newlay->l_height = flayer->l_height;
+ newlay->l_layfn = lf;
+ newlay->l_data = data;
+ newlay->l_next = flayer;
+ newlay->l_bottom = flayer->l_bottom;
+ flayer = newlay;
+ Restore();
+ return 0;
+}
+
+void
+ExitOverlayPage()
+{
+ struct layer *oldlay;
+ struct win *p;
+ int doredisplay = 0;
+ struct canvas *cv, *ocv;
+
+ ASSERT(flayer);
+ debug1("Exiting layer %#x\n", (unsigned int)flayer);
+ oldlay = flayer;
+ if (oldlay->l_data)
+ free(oldlay->l_data);
+
+ p = Layer2Window(flayer);
+
+ flayer = oldlay->l_next;
+ if (flayer->l_layfn == &WinLf)
+ {
+ if (oldlay->l_blocking)
+ {
+ ASSERT(p->w_blocked > 0);
+ p->w_blocked--;
+ debug1("layer was blocking, -> w_blocked now %d\n", p->w_blocked);
+ }
+ /* don't warp dead layers: check cvlist */
+ if (p->w_blocked && p->w_savelayer && p->w_savelayer != flayer && oldlay->l_cvlist)
+ {
+ debug("warping to top of blocking chain!\n");
+ /* warp ourself into savelayer */
+ flayer = p->w_savelayer;
+ doredisplay = 1;
+ }
+ }
+ if (p && p->w_savelayer == oldlay)
+ p->w_savelayer = flayer;
+#ifdef COPY_PASTE
+ if (p && oldlay == p->w_paster.pa_pastelayer)
+ p->w_paster.pa_pastelayer = 0;
+#endif
+
+ /* add all canvases back into next layer's canvas list */
+ for (ocv = 0, cv = oldlay->l_cvlist; cv; cv = cv->c_lnext)
+ {
+ cv->c_layer = flayer;
+ ocv = cv;
+ }
+ if (ocv)
+ {
+ cv = flayer->l_cvlist;
+ ocv->c_lnext = 0;
+ flayer->l_cvlist = oldlay->l_cvlist;
+ /* redisplay only the warped cvs */
+ if (doredisplay)
+ RedisplayLayer(flayer, 0);
+ ocv->c_lnext = cv;
+ }
+ oldlay->l_cvlist = 0;
+ free((char *)oldlay);
+ Restore();
+ SetCursor();
+}
+
+void
+/*VARARGS2*/
+#if defined(USEVARARGS) && defined(__STDC__)
+LMsg(int err, char *fmt, VA_DOTS)
+#else
+LMsg(err, fmt, VA_DOTS)
+int err;
+char *fmt;
+VA_DECL
+#endif
+{
+ VA_LIST(ap)
+ char buf[MAXPATHLEN*2];
+ char *p = buf;
+ struct canvas *cv;
+
+ VA_START(ap, fmt);
+ fmt = DoNLS(fmt);
+ (void)vsnprintf(p, sizeof(buf) - 100, fmt, VA_ARGS(ap));
+ VA_END(ap);
+ if (err)
+ {
+ p += strlen(p);
+ *p++ = ':';
+ *p++ = ' ';
+ strncpy(p, strerror(err), buf + sizeof(buf) - p - 1);
+ buf[sizeof(buf) - 1] = 0;
+ }
+ debug2("LMsg('%s') (%#x);\n", buf, (unsigned int)flayer);
+ for (display = displays; display; display = display->d_next)
+ {
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ if (cv->c_layer == flayer)
+ break;
+ if (cv == 0)
+ continue;
+ MakeStatus(buf);
+ }
+}
+
diff --git a/layer.h b/layer.h
new file mode 100644
index 0000000..037fe24
--- /dev/null
+++ b/layer.h
@@ -0,0 +1,104 @@
+/* Copyright (c) 1993
+ * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
+ * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
+ * Copyright (c) 1987 Oliver Laumann
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING); if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ ****************************************************************
+ * $Id: overlay.h,v 1.3 1994/05/31 12:32:31 mlschroe Exp $ FAU
+ */
+
+/*
+ * This is the overlay structure. It is used to create a seperate
+ * layer over the current windows.
+ */
+
+struct mchar; /* forward declaration */
+
+struct LayFuncs
+{
+ void (*LayProcess) __P((char **, int *));
+ void (*LayAbort) __P((void));
+ void (*LayRedisplayLine) __P((int, int, int, int));
+ void (*LayClearLine) __P((int, int, int));
+ int (*LayRewrite) __P((int, int, int, struct mchar *, int));
+ int (*LayResize) __P((int, int));
+ void (*LayRestore) __P((void));
+};
+
+struct layer
+{
+ struct canvas *l_cvlist; /* list of canvases displaying layer */
+ int l_width;
+ int l_height;
+ int l_x; /* cursor position */
+ int l_y;
+ struct LayFuncs *l_layfn;
+ char *l_data;
+
+ struct layer *l_next; /* layer stack, should be in data? */
+ struct layer *l_bottom; /* bottom element of layer stack */
+ int l_blocking;
+};
+
+#define Process (*flayer->l_layfn->LayProcess)
+#define Abort (*flayer->l_layfn->LayAbort)
+#define RedisplayLine (*flayer->l_layfn->LayRedisplayLine)
+#define ClearLine (*flayer->l_layfn->LayClearLine)
+#define Rewrite (*flayer->l_layfn->LayRewrite)
+#define Resize (*flayer->l_layfn->LayResize)
+#define Restore (*flayer->l_layfn->LayRestore)
+
+#define SetCursor() LGotoPos(flayer, flayer->l_x, flayer->l_y)
+#define CanResize(l) (l->l_layfn->LayResize != DefResize)
+
+/* XXX: AArgh! think again! */
+
+#define LAY_CALL_UP(fn) do \
+ { \
+ struct layer *oldlay = flayer; \
+ struct canvas *oldcvlist, *cv; \
+ debug("LayCallUp\n"); \
+ flayer = flayer->l_next; \
+ oldcvlist = flayer->l_cvlist; \
+ debug1("oldcvlist: %x\n", oldcvlist); \
+ flayer->l_cvlist = oldlay->l_cvlist; \
+ for (cv = flayer->l_cvlist; cv; cv = cv->c_lnext) \
+ cv->c_layer = flayer; \
+ fn; \
+ flayer = oldlay; \
+ for (cv = flayer->l_cvlist; cv; cv = cv->c_lnext) \
+ cv->c_layer = flayer; \
+ flayer->l_next->l_cvlist = oldcvlist; \
+ } while(0)
+
+#define LAY_DISPLAYS(l, fn) do \
+ { \
+ struct display *olddisplay = display; \
+ struct canvas *cv; \
+ for (display = displays; display; display = display->d_next) \
+ { \
+ for (cv = D_cvlist; cv; cv = cv->c_next) \
+ if (cv->c_layer == l) \
+ break; \
+ if (cv == 0) \
+ continue; \
+ fn; \
+ } \
+ display = olddisplay; \
+ } while(0)
+
diff --git a/loadav.c b/loadav.c
index 0e34327..82bf176 100644
--- a/loadav.c
+++ b/loadav.c
@@ -156,6 +156,84 @@ GetLoadav()
/***************************************************************/
+#if defined(sun) && defined(SVR4) && !defined(LOADAV_DONE)
+#define LOADAV_DONE
+
+#include <kstat.h>
+
+static kstat_ctl_t *kc;
+
+void
+InitLoadav()
+{
+ loadok = (kc = kstat_open()) != 0;
+}
+
+static int
+GetLoadav()
+{
+ kstat_t *ks;
+ kstat_named_t *avgs[3];
+ int i;
+
+ kstat_chain_update(kc);
+ if ((ks = kstat_lookup(kc, "unix", -1, "system_misc")) == 0 || kstat_read(kc, ks, (void *)0) == -1)
+ return (loadok = 0);
+ avgs[0] = kstat_data_lookup(ks, "avenrun_1min");
+ avgs[1] = kstat_data_lookup(ks, "avenrun_5min");
+ avgs[2] = kstat_data_lookup(ks, "avenrun_15min");
+ for (i = 0; i < 3; i++)
+ {
+ if (avgs[i] == 0 || avgs[i]->data_type != KSTAT_DATA_ULONG)
+ return (loadok = 0);
+ loadav[i] = avgs[i]->value.ul;
+ }
+ return 3;
+}
+
+#endif
+
+/***************************************************************/
+
+#if defined(__osf__) && defined(__alpha) && !defined(LOADAV_DONE)
+#define LOADAV_DONE
+
+struct rtentry; struct mbuf; /* shut up gcc on OSF/1 4.0 */
+#include <sys/table.h>
+
+void
+InitLoadav()
+{
+ loadok = 1;
+}
+
+static int
+GetLoadav()
+{
+ struct tbl_loadavg tbl;
+ int i;
+
+ if (table(TBL_LOADAVG, 0, &tbl, 1, sizeof(struct tbl_loadavg)) != 1)
+ return 0;
+
+ if (tbl.tl_lscale)
+ {
+ /* in long */
+ for (i = 0; i < LOADAV_NUM; i++)
+ loadav[i] = (double) tbl.tl_avenrun.l[i] / tbl.tl_lscale;
+ }
+ else
+ {
+ /* in double */
+ for (i = 0; i < LOADAV_NUM; i++)
+ loadav[i] = tbl.tl_avenrun.d[i];
+ }
+ return LOADAV_NUM;
+}
+#endif
+
+/***************************************************************/
+
#if !defined(LOADAV_DONE)
/*
* The old fashion way: open kernel and read avenrun
@@ -173,7 +251,7 @@ extern int nlist __P((char *, struct nlist *));
# endif
#ifdef __sgi
-# if _MIPS_SZLONG == 64
+# if _MIPS_SZLONG == 64 || (defined(_MIPS_ISA) && _MIPS_ISA > 2)
# define nlist nlist64
# endif
#endif
@@ -241,7 +319,7 @@ char *p;
j = GetLoadav();
for (i = 0; i < j; i++)
{
- sprintf(p, " %2.2f", FIX_TO_DBL(loadav[i]));
+ sprintf(p, " %2.2f" + !i, FIX_TO_DBL(loadav[i]));
p += strlen(p);
}
}
diff --git a/logfile.c b/logfile.c
new file mode 100644
index 0000000..ed9842f
--- /dev/null
+++ b/logfile.c
@@ -0,0 +1,318 @@
+/* Copyright (c) 1993
+ * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
+ * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
+ * Copyright (c) 1987 Oliver Laumann
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING); if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ ****************************************************************
+ */
+
+#include "rcs.h"
+RCS_ID("$Id: logfile.c,v 1.4 1994/05/31 12:32:12 jnweiger Exp $ FAU")
+
+#include <sys/types.h> /* dev_t, ino_t, off_t, ... */
+#include <sys/stat.h> /* struct stat */
+#include <fcntl.h> /* O_WRONLY for logfile_reopen */
+
+
+#if 1
+#include "config.h"
+#include "screen.h"
+#include "extern.h"
+#define strdup SaveStr
+#else
+extern void *malloc();
+extern void free();
+extern int fwrite();
+extern int fflush();
+extern void fclose();
+extern char *strdup();
+# define debug(a)
+# define debug1(a)
+# define debug2(a)
+# ifndef __P
+# if defined(__STDC__)
+# define __P(a) a
+# else
+# define __P(a) ()
+# endif
+# endif
+#endif
+
+#include "logfile.h"
+
+static void changed_logfile __P((struct logfile *));
+static struct logfile *lookup_logfile __P((char *));
+static int stolen_logfile __P((struct logfile *));
+
+static struct logfile *logroot = NULL;
+
+static void
+changed_logfile(l)
+struct logfile *l;
+{
+ struct stat o, *s = l->st;
+
+ if (fstat(fileno(l->fp), &o) < 0) /* get trouble later */
+ return;
+ if (o.st_size > s->st_size) /* aha, appended text */
+ {
+ s->st_size = o.st_size; /* this should have changed */
+ s->st_mtime = o.st_mtime; /* only size and mtime */
+ }
+}
+
+/*
+ * Requires fd to be open and need_fd to be closed.
+ * If possible, need_fd will be open afterwards and refer to
+ * the object originally reffered by fd. fd will be closed then.
+ * Works just like ``fcntl(fd, DUPFD, need_fd); close(fd);''
+ *
+ * need_fd is returned on success, else -1 is returned.
+ */
+int
+lf_move_fd(fd, need_fd)
+int need_fd, fd;
+{
+ int r = -1;
+
+ if (fd == need_fd)
+ return fd;
+ if (fd >=0 && fd < need_fd)
+ r = lf_move_fd(dup(fd), need_fd);
+ close(fd);
+ return r;
+}
+
+static int
+logfile_reopen(name, wantfd, l)
+char *name;
+int wantfd;
+struct logfile *l;
+{
+ int got_fd;
+
+ close(wantfd);
+ if (((got_fd = open(name, O_WRONLY | O_CREAT | O_APPEND, 0666)) < 0) ||
+ lf_move_fd(got_fd, wantfd) < 0)
+ {
+ logfclose(l);
+ debug1("logfile_reopen: failed for %s\n", name);
+ return -1;
+ }
+ changed_logfile(l);
+ debug2("logfile_reopen: %d = %s\n", wantfd, name);
+ return 0;
+}
+
+static int (* lf_reopen_fn)() = logfile_reopen;
+
+/*
+ * Whenever logfwrite discoveres that it is required to close and
+ * reopen the logfile, the function registered here is called.
+ * If you do not register anything here, the above logfile_reopen()
+ * will be used instead.
+ * Your function should perform the same steps as logfile_reopen():
+ * a) close the original filedescriptor without flushing any output
+ * b) open a new logfile for future output on the same filedescriptor number.
+ * c) zero out st_dev, st_ino to tell the stolen_logfile() indcator to
+ * reinitialise itself.
+ * d) return 0 on success.
+ */
+void
+logreopen_register(fn)
+int (*fn) __P((char *, int, struct logfile *));
+{
+ lf_reopen_fn = fn ? fn : logfile_reopen;
+}
+
+/*
+ * If the logfile has been removed, truncated, unlinked or the like,
+ * return nonzero.
+ * The l->st structure initialised by logfopen is updated
+ * on every call.
+ */
+static int
+stolen_logfile(l)
+struct logfile *l;
+{
+ struct stat o, *s = l->st;
+
+ o = *s;
+ if (fstat(fileno(l->fp), s) < 0) /* remember that stat failed */
+ s->st_ino = s->st_dev = 0;
+ ASSERT(s == l->st);
+ if (!o.st_dev && !o.st_ino) /* nothing to compare with */
+ return 0;
+
+ if ((!s->st_dev && !s->st_ino) || /* stat failed, that's new! */
+ !s->st_nlink || /* red alert: file unlinked */
+ (s->st_size < o.st_size) || /* file truncated */
+ (s->st_mtime != o.st_mtime) || /* file modified */
+ ((s->st_ctime != o.st_ctime) && /* file changed (moved) */
+ !(s->st_mtime == s->st_ctime && /* and it was not a change */
+ o.st_ctime < s->st_ctime))) /* due to delayed nfs write */
+ {
+ debug1("stolen_logfile: %s stolen!\n", l->name);
+ debug3("st_dev %d, st_ino %d, st_nlink %d\n",
+ (int)s->st_dev, (int)s->st_ino, (int)s->st_nlink);
+ debug2("s->st_size %d, o.st_size %d\n", (int)s->st_size, (int)o.st_size);
+ debug2("s->st_mtime %d, o.st_mtime %d\n",
+ (int)s->st_mtime, (int)o.st_mtime);
+ debug2("s->st_ctime %d, o.st_ctime %d\n",
+ (int)s->st_ctime, (int)o.st_ctime);
+ return -1;
+ }
+
+ debug1("stolen_logfile: %s o.k.\n", l->name);
+ return 0;
+}
+
+static struct logfile *
+lookup_logfile(name)
+char *name;
+{
+ struct logfile *l;
+
+ for (l = logroot; l; l = l->next)
+ if (!strcmp(name, l->name))
+ return l;
+ return NULL;
+}
+
+struct logfile *
+logfopen(name, fp)
+char *name;
+FILE *fp;
+{
+ struct logfile *l;
+
+ if (!fp)
+ {
+ if (!(l = lookup_logfile(name)))
+ return NULL;
+ l->opencount++;
+ return l;
+ }
+
+ if (!(l = (struct logfile *)malloc(sizeof(struct logfile))))
+ return NULL;
+ if (!(l->st = (struct stat *)malloc(sizeof(struct stat))))
+ {
+ free((char *)l);
+ return NULL;
+ }
+
+ if (!(l->name = strdup(name)))
+ {
+ free((char *)l->st);
+ free((char *)l);
+ return NULL;
+ }
+ l->fp = fp;
+ l->opencount = 1;
+ l->writecount = 0;
+ l->flushcount = 0;
+ changed_logfile(l);
+
+ l->next = logroot;
+ logroot = l;
+ return l;
+}
+
+int
+islogfile(name)
+char *name;
+{
+ if (!name)
+ return logroot ? 1 : 0;
+ return lookup_logfile(name) ? 1 : 0;
+}
+
+int
+logfclose(l)
+struct logfile *l;
+{
+ struct logfile **lp;
+
+ for (lp = &logroot; *lp; lp = &(*lp)->next)
+ if (*lp == l)
+ break;
+
+ if (!*lp)
+ return -1;
+
+ if ((--l->opencount) > 0)
+ return 0;
+ if (l->opencount < 0)
+ abort();
+
+ *lp = l->next;
+ fclose(l->fp);
+ free(l->name);
+ free((char *)l);
+ return 0;
+}
+
+/*
+ * XXX
+ * write and flush both *should* check the file's stat, if it disappeared
+ * or changed, re-open it.
+ */
+int
+logfwrite(l, buf, n)
+struct logfile *l;
+char *buf;
+int n;
+{
+ int r;
+
+ if (stolen_logfile(l) && lf_reopen_fn(l->name, fileno(l->fp), l))
+ return -1;
+ r = fwrite(buf, n, 1, l->fp);
+ l->writecount += l->flushcount + 1;
+ l->flushcount = 0;
+ changed_logfile(l);
+ return r;
+}
+
+int
+logfflush(l)
+struct logfile *l;
+{
+ int r = 0;
+
+ if (!l)
+ for (l = logroot; l; l = l->next)
+ {
+ if (stolen_logfile(l) && lf_reopen_fn(l->name, fileno(l->fp), l))
+ return -1;
+ r |= fflush(l->fp);
+ l->flushcount++;
+ changed_logfile(l);
+ }
+ else
+ {
+ if (stolen_logfile(l) && lf_reopen_fn(l->name, fileno(l->fp), l))
+ return -1;
+ r = fflush(l->fp);
+ l->flushcount++;
+ changed_logfile(l);
+ }
+ return r;
+}
+
diff --git a/logfile.h b/logfile.h
new file mode 100644
index 0000000..77ec431
--- /dev/null
+++ b/logfile.h
@@ -0,0 +1,82 @@
+/* Copyright (c) 1993
+ * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
+ * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
+ * Copyright (c) 1987 Oliver Laumann
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING); if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ ****************************************************************
+ * $Id: logfile.h,v 1.11 1994/05/31 12:33:27 jnweiger Exp $ FAU
+ */
+
+struct logfile
+{
+ struct logfile *next;
+ FILE *fp; /* a hopefully uniq filepointer to the log file */
+ char *name; /* the name. used to reopen, when stat fails. */
+ int opencount; /* synchronize logfopen() and logfclose() */
+ int writecount; /* increments at logfwrite(), counts write() and fflush() */
+ int flushcount; /* increments at logfflush(), zeroed at logfwrite() */
+ struct stat *st; /* how the file looks like */
+};
+
+/*
+ * open a logfile, The second argument must be NULL, when the named file
+ * is already a logfile or must be a appropriatly opened file pointer
+ * otherwise.
+ * example: l = logfopen(name, islogfile(name) : NULL ? fopen(name, "a"));
+ */
+struct logfile *logfopen __P((char *name, FILE *fp));
+
+/*
+ * lookup a logfile by name. This is useful, so that we can provide
+ * logfopen with a nonzero second argument, exactly when needed.
+ * islogfile(NULL); returns nonzero if there are any open logfiles at all.
+ */
+int islogfile __P((char *name));
+
+/*
+ * logfclose does free()
+ */
+int logfclose __P((struct logfile *));
+int logfwrite __P((struct logfile *, char *, int));
+
+/*
+ * logfflush should be called periodically. If no argument is passed,
+ * all logfiles are flushed, else the specified file
+ * the number of flushed filepointers is returned
+ */
+int logfflush __P((struct logfile *ifany));
+
+/*
+ * a reopen function may be registered here, in case you want to bring your
+ * own (more secure open), it may come along with a private data pointer.
+ * this function is called, whenever logfwrite/logfflush detect that the
+ * file has been (re)moved, truncated or changed by someone else.
+ * if you provide NULL as parameter to logreopen_register, the builtin
+ * reopen function will be reactivated.
+ */
+void logreopen_register __P((int (*fn) __P((char *, int, struct logfile *)) ));
+
+/*
+ * Your custom reopen function is required to reuse the exact
+ * filedescriptor.
+ * See logfile.c for further specs and an example.
+ *
+ * lf_move_fd may help you here, if you do not have dup2(2).
+ * It closes fd and opens wantfd to access whatever fd accessed.
+ */
+int lf_move_fd __P((int fd, int wantfd));
diff --git a/mark.c b/mark.c
index e85d29a..3bf21f4 100644
--- a/mark.c
+++ b/mark.c
@@ -33,6 +33,15 @@ RCS_ID("$Id: mark.c,v 1.6 1994/05/31 12:32:15 mlschroe Exp $ FAU")
#ifdef COPY_PASTE
+/*
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ *
+ * WARNING: these routines use the global variables "fore" and
+ * "flayer" to make things easier.
+ *
+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ */
+
static int is_letter __P((int));
static void nextword __P((int *, int *, int, int));
static int linestart __P((int));
@@ -45,20 +54,18 @@ static int MarkScrollUpDisplay __P((int));
static void MarkProcess __P((char **, int *));
static void MarkAbort __P((void));
static void MarkRedisplayLine __P((int, int, int, int));
-static int MarkRewrite __P((int, int, int, int));
-static void MarkSetCursor __P((void));
+static int MarkRewrite __P((int, int, int, struct mchar *, int));
+extern struct layer *flayer;
+extern struct display *display, *displays;
extern struct win *fore;
-extern struct display *display;
extern char *null, *blank;
extern struct mline mline_blank, mline_null;
extern struct mchar mchar_so;
-#ifdef NETHACK
-extern nethackflag;
-#endif
-
+#ifdef FONT
int pastefont = 1;
+#endif
static struct LayFuncs MarkLf =
{
@@ -67,12 +74,13 @@ static struct LayFuncs MarkLf =
MarkRedisplayLine,
DefClearLine,
MarkRewrite,
- MarkSetCursor,
DefResize,
DefRestore
};
int join_with_cr = 0;
+int compacthist = 0;
+
unsigned char mark_key_tab[256]; /* this array must be initialised first! */
static struct markdata *markdata;
@@ -107,10 +115,10 @@ int y;
register int x;
register char *i;
- for (x = markdata->left_mar, i = WIN(y)->image + x; x < D_width - 1; x++)
+ for (x = markdata->left_mar, i = WIN(y)->image + x; x < fore->w_width - 1; x++)
if (*i++ != ' ')
break;
- if (x == D_width - 1)
+ if (x == fore->w_width - 1)
x = markdata->left_mar;
return x;
}
@@ -147,7 +155,7 @@ static void
nextword(xp, yp, flags, num)
int *xp, *yp, flags, num;
{
- int xx = D_width, yy = fore->w_histheight + D_height;
+ int xx = fore->w_width, yy = fore->w_histheight + fore->w_height;
register int sx, oq, q, x, y;
struct mline *ml;
@@ -208,10 +216,14 @@ rem(x1, y1, x2, y2, redisplay, pt, yend)
int x1, y1, x2, y2, redisplay, yend;
char *pt;
{
- int i, j, from, to, ry, c, cf, font;
+ int i, j, from, to, ry, c;
int l = 0;
- char *im, *fo;
+ char *im;
struct mline *ml;
+#ifdef FONT
+ int cf, font;
+ char *fo;
+#endif
markdata->second = 0;
if (y2 < y1 || ((y2 == y1) && (x2 < x1)))
@@ -224,7 +236,7 @@ char *pt;
x1 = i;
}
ry = y1 - markdata->hist_offset;
-
+
i = y1;
if (redisplay != 2 && pt == 0 && ry <0)
{
@@ -239,7 +251,7 @@ char *pt;
from = (i == y1) ? x1 : 0;
if (from < markdata->left_mar)
from = markdata->left_mar;
- for (to = D_width, im = ml->image + to; to >= 0; to--)
+ for (to = fore->w_width, im = ml->image + to; to >= 0; to--)
if (*im-- != ' ')
break;
if (i == y2 && x2 < to)
@@ -255,12 +267,17 @@ char *pt;
if (badkanji(ml->font, j))
j--;
#endif
+ im = ml->image + j;
+#ifdef FONT
+ fo = ml->font + j;
font = ASCII;
- for (im = ml->image + j, fo = ml->font + j; j <= to; j++)
+#endif
+ for (; j <= to; j++)
{
- cf = *fo++;
c = *im++;
-#ifdef KANJI
+#ifdef FONT
+ cf = *fo++;
+# ifdef KANJI
if (cf == KANJI)
{
int t;
@@ -277,7 +294,7 @@ char *pt;
else if (fore->w_kanji == SJIS)
{
t += (c & 1) ? ((t <= 0x5f) ? 0x1f : 0x20) : 0x7e;
- c = (c - 0x21) / 2 + ((c < 0x5e) ? 0x81 : 0xc1);
+ c = (c - 0x21) / 2 + ((c < 0x5f) ? 0x81 : 0xc1);
}
else
{
@@ -296,10 +313,10 @@ char *pt;
c = t;
}
else
-#endif
+# endif /* KANJI */
if (pastefont)
{
-#ifdef KANJI
+# ifdef KANJI
if (cf == KANA)
{
if (fore->w_kanji == EUC)
@@ -323,7 +340,7 @@ char *pt;
}
}
else
-#endif
+#endif /* KANJI */
{
if (cf != font)
{
@@ -338,10 +355,12 @@ char *pt;
}
}
}
+#endif /* FONT */
if (pt)
*pt++ = c;
l++;
}
+#ifdef FONT
if (pastefont && font != ASCII)
{
if (pt)
@@ -351,9 +370,10 @@ char *pt;
}
l += 3;
}
- if (i != y2 && (to != D_width - 1 || ml->image[to + 1] == ' '))
+#endif
+ if (i != y2 && (to != fore->w_width - 1 || ml->image[to + 1] == ' '))
{
- /*
+ /*
* this code defines, what glues lines together
*/
switch (markdata->nonl)
@@ -376,13 +396,18 @@ char *pt;
*pt++ = ' ';
l++;
break;
+ case 3: /* seperate by comma, for csh junkies */
+ if (pt)
+ *pt++ = ',';
+ l++;
+ break;
}
}
}
return l;
}
-/* Check if two chars are identical. All digits are treatened
+/* Check if two chars are identical. All digits are treated
* as same. Used for GetHistory()
*/
@@ -400,6 +425,8 @@ int a, b;
}
+/**********************************************************************/
+
int
GetHistory() /* return value 1 if u_copybuffer changed */
{
@@ -407,9 +434,10 @@ GetHistory() /* return value 1 if u_copybuffer changed */
char *linep;
struct mline *ml;
+ ASSERT(display && fore);
x = fore->w_x;
- if (x >= D_width)
- x = D_width - 1;
+ if (x >= fore->w_width)
+ x = fore->w_width - 1;
y = fore->w_y + fore->w_histheight;
debug2("cursor is at x=%d, y=%d\n", x, y);
ml = WIN(y);
@@ -423,7 +451,7 @@ GetHistory() /* return value 1 if u_copybuffer changed */
linep = ml->image;
if (xx < 0 || eq(linep[xx], q))
{ /* line is matching... */
- for (i = D_width - 1, linep += i; i >= x; i--)
+ for (i = fore->w_width - 1, linep += i; i >= x; i--)
if (*linep-- != ' ')
break;
if (i >= x)
@@ -436,7 +464,7 @@ GetHistory() /* return value 1 if u_copybuffer changed */
UserFreeCopyBuffer(D_user);
if ((D_user->u_copybuffer = malloc((unsigned) (i - x + 2))) == NULL)
{
- Msg(0, "Not enough memory... Sorry.");
+ LMsg(0, "Not enough memory... Sorry.");
return 0;
}
bcopy(linep - i + x + 1, D_user->u_copybuffer, i - x + 1);
@@ -444,47 +472,44 @@ GetHistory() /* return value 1 if u_copybuffer changed */
return 1;
}
+/**********************************************************************/
+
+
void
MarkRoutine()
{
int x, y;
-
- ASSERT(fore->w_active);
+
+ ASSERT(fore && display && D_user);
+
+ debug2("MarkRoutine called: fore nr %d, display %s\n",
+ fore->w_number, D_usertty);
+
if (InitOverlayPage(sizeof(*markdata), &MarkLf, 1))
return;
- markdata = (struct markdata *)D_lay->l_data;
+ markdata = (struct markdata *)flayer->l_data;
+ markdata->md_user = D_user; /* XXX: Correct? */
+ markdata->md_window = fore;
markdata->second = 0;
markdata->rep_cnt = 0;
markdata->append_mode = 0;
markdata->write_buffer = 0;
markdata->nonl = 0;
markdata->left_mar = 0;
- markdata->right_mar = D_width - 1;
+ markdata->right_mar = fore->w_width - 1;
markdata->hist_offset = fore->w_histheight;
x = fore->w_x;
y = D2W(fore->w_y);
- if (x >= D_width)
- x = D_width - 1;
-
- GotoPos(x, W2D(y));
-#ifdef NETHACK
- if (nethackflag)
- Msg(0, "Welcome to hacker's treasure zoo - Column %d Line %d(+%d) (%d,%d)",
- x + 1, W2D(y + 1), fore->w_histheight, D_width, D_height);
- else
-#endif
- Msg(0, "Copy mode - Column %d Line %d(+%d) (%d,%d)",
- x + 1, W2D(y + 1), fore->w_histheight, D_width, D_height);
+ if (x >= fore->w_width)
+ x = fore->w_width - 1;
+
+ LGotoPos(flayer, x, W2D(y));
+ LMsg(0, "Copy mode - Column %d Line %d(+%d) (%d,%d)",
+ x + 1, W2D(y + 1), fore->w_histheight, fore->w_width, fore->w_height);
markdata->cx = markdata->x1 = x;
markdata->cy = markdata->y1 = y;
-}
-
-static void
-MarkSetCursor()
-{
- markdata = (struct markdata *)D_lay->l_data;
- fore = D_fore;
- GotoPos(markdata->cx, W2D(markdata->cy));
+ flayer->l_x = x;
+ flayer->l_y = W2D(y);
}
static void
@@ -498,20 +523,22 @@ int *inlenp;
int newcopylen = 0, od;
int in_mark;
int rep_cnt;
-
+ struct user *md_user;
+
/*
char *extrap = 0, extrabuf[100];
*/
-
- markdata = (struct markdata *)D_lay->l_data;
- fore = D_fore;
+
+ markdata = (struct markdata *)flayer->l_data;
+ fore = markdata->md_window;
+ md_user = markdata->md_user;
if (inbufp == 0)
{
MarkAbort();
return;
}
-
- GotoPos(markdata->cx, W2D(markdata->cy));
+
+ LGotoPos(flayer, markdata->cx, W2D(markdata->cy));
inbuf= *inbufp;
inlen= *inlenp;
pt = inbuf;
@@ -554,6 +581,7 @@ int *inlenp;
cy = markdata->cy;
switch (od)
{
+ case 'o':
case 'x':
if (!markdata->second)
break;
@@ -565,7 +593,7 @@ int *inlenp;
break;
case '\014': /* CTRL-L Redisplay */
Redisplay(0);
- GotoPos(cx, W2D(cy));
+ LGotoPos(flayer, cx, W2D(cy));
break;
case 0202: /* M-C-b */
case '\010': /* CTRL-H Backspace */
@@ -585,8 +613,8 @@ int *inlenp;
if (rep_cnt == 0)
rep_cnt = 1;
j = cy + rep_cnt;
- if (j > fore->w_histheight + D_height - 1)
- j = fore->w_histheight + D_height - 1;
+ if (j > fore->w_histheight + fore->w_height - 1)
+ j = fore->w_histheight + fore->w_height - 1;
revto(linestart(j), j);
break;
case '-':
@@ -622,7 +650,7 @@ int *inlenp;
break;
case '\004': /* CTRL-D down half screen */
if (rep_cnt == 0)
- rep_cnt = (D_height + 1) >> 1;
+ rep_cnt = (fore->w_height + 1) >> 1;
revto_line(cx, cy + rep_cnt, W2D(cy));
break;
case '$':
@@ -638,27 +666,27 @@ int *inlenp;
break;
case '\025': /* CTRL-U up half screen */
if (rep_cnt == 0)
- rep_cnt = (D_height + 1) >> 1;
+ rep_cnt = (fore->w_height + 1) >> 1;
revto_line(cx, cy - rep_cnt, W2D(cy));
break;
case '\007': /* CTRL-G show cursorpos */
- if (markdata->left_mar == 0 && markdata->right_mar == D_width - 1)
- Msg(0, "Column %d Line %d(+%d)", cx+1, W2D(cy)+1,
+ if (markdata->left_mar == 0 && markdata->right_mar == fore->w_width - 1)
+ LMsg(0, "Column %d Line %d(+%d)", cx+1, W2D(cy)+1,
markdata->hist_offset);
else
- Msg(0, "Column %d(%d..%d) Line %d(+%d)", cx+1,
+ LMsg(0, "Column %d(%d..%d) Line %d(+%d)", cx+1,
markdata->left_mar+1, markdata->right_mar+1, W2D(cy)+1, markdata->hist_offset);
break;
case '\002': /* CTRL-B back one page */
if (rep_cnt == 0)
rep_cnt = 1;
- rep_cnt *= D_height;
+ rep_cnt *= fore->w_height;
revto(cx, cy - rep_cnt);
break;
case '\006': /* CTRL-F forward one page */
if (rep_cnt == 0)
rep_cnt = 1;
- rep_cnt *= D_height;
+ rep_cnt *= fore->w_height;
revto(cx, cy + rep_cnt);
break;
case '\005': /* CTRL-E scroll up */
@@ -668,16 +696,16 @@ int *inlenp;
if (cy < D2W(0))
revto(cx, D2W(0));
else
- GotoPos(cx, W2D(cy));
+ LGotoPos(flayer, cx, W2D(cy));
break;
case '\031': /* CTRL-Y scroll down */
if (rep_cnt == 0)
rep_cnt = 1;
rep_cnt = MarkScrollDownDisplay(rep_cnt);
- if (cy > D2W(D_height-1))
- revto(cx, D2W(D_height-1));
+ if (cy > D2W(fore->w_height-1))
+ revto(cx, D2W(fore->w_height-1));
else
- GotoPos(cx, W2D(cy));
+ LGotoPos(flayer, cx, W2D(cy));
break;
case '@':
/* it may be usefull to have a key that does nothing */
@@ -689,7 +717,7 @@ int *inlenp;
rep_cnt = 0;
if (rep_cnt > 100)
rep_cnt = 100;
- revto_line(markdata->left_mar, (rep_cnt * (fore->w_histheight + D_height)) / 100, (D_height - 1) / 2);
+ revto_line(markdata->left_mar, (rep_cnt * (fore->w_histheight + fore->w_height)) / 100, (fore->w_height - 1) / 2);
break;
case 0201:
case 'g':
@@ -699,17 +727,17 @@ int *inlenp;
case 'G':
/* rep_cnt is here the WIN line number */
if (rep_cnt == 0)
- rep_cnt = fore->w_histheight + D_height;
- revto_line(markdata->left_mar, --rep_cnt, (D_height - 1) / 2);
+ rep_cnt = fore->w_histheight + fore->w_height;
+ revto_line(markdata->left_mar, --rep_cnt, (fore->w_height - 1) / 2);
break;
case 'H':
revto(markdata->left_mar, D2W(0));
break;
case 'M':
- revto(markdata->left_mar, D2W((D_height - 1) / 2));
+ revto(markdata->left_mar, D2W((fore->w_height - 1) / 2));
break;
case 'L':
- revto(markdata->left_mar, D2W(D_height - 1));
+ revto(markdata->left_mar, D2W(fore->w_height - 1));
break;
case '|':
revto(--rep_cnt, cy);
@@ -735,7 +763,7 @@ int *inlenp;
case 'a':
markdata->append_mode = 1 - markdata->append_mode;
debug1("append mode %d--\n", markdata->append_mode);
- Msg(0, (markdata->append_mode) ? ":set append" : ":set noappend");
+ LMsg(0, (markdata->append_mode) ? ":set append" : ":set noappend");
break;
case 'v':
case 'V':
@@ -750,7 +778,7 @@ int *inlenp;
/* set start column (c) and end column (C) */
if (markdata->second)
{
- rem(markdata->x1, markdata->y1, cx, cy, 1, (char *)0, D_height-1); /* Hack */
+ rem(markdata->x1, markdata->y1, cx, cy, 1, (char *)0, fore->w_height-1); /* Hack */
markdata->second = 1; /* rem turns off second */
}
rep_cnt--;
@@ -774,24 +802,27 @@ int *inlenp;
revto(cx, cy);
}
if (od == 'v' || od == 'V')
- Msg(0, (markdata->left_mar != 8) ? ":set nonu" : ":set nu");
+ LMsg(0, (markdata->left_mar != 8) ? ":set nonu" : ":set nu");
break;
case 'J':
/* how do you join lines in VI ? */
- markdata->nonl = (markdata->nonl + 1) % 3;
+ markdata->nonl = (markdata->nonl + 1) % 4;
switch (markdata->nonl)
{
case 0:
if (join_with_cr)
- Msg(0, "Multiple lines (CR/LF)");
+ LMsg(0, "Multiple lines (CR/LF)");
else
- Msg(0, "Multiple lines (LF)");
+ LMsg(0, "Multiple lines (LF)");
break;
case 1:
- Msg(0, "Lines joined");
+ LMsg(0, "Lines joined");
break;
case 2:
- Msg(0, "Lines joined with blanks");
+ LMsg(0, "Lines joined with blanks");
+ break;
+ case 3:
+ LMsg(0, "Lines joined with comma");
break;
}
break;
@@ -856,13 +887,7 @@ int *inlenp;
markdata->x1 = cx;
markdata->y1 = cy;
revto(cx, cy);
-#ifdef NETHACK
- if (nethackflag)
- Msg(0, "You drop a magic marker - Column %d Line %d",
- cx+1, W2D(cy)+1);
- else
-#endif
- Msg(0, "First mark set - Column %d Line %d", cx+1, W2D(cy)+1);
+ LMsg(0, "First mark set - Column %d Line %d", cx+1, W2D(cy)+1);
break;
}
else
@@ -873,70 +898,76 @@ int *inlenp;
x2 = cx;
y2 = cy;
newcopylen = rem(markdata->x1, markdata->y1, x2, y2, 2, (char *)0, 0); /* count */
- if (D_user->u_copybuffer != NULL && !append_mode)
- UserFreeCopyBuffer(D_user);
+ if (md_user->u_copybuffer != NULL && !append_mode)
+ UserFreeCopyBuffer(md_user);
+ yend = fore->w_height - 1;
+ if (fore->w_histheight - markdata->hist_offset < fore->w_height)
+ {
+ markdata->second = 0;
+ yend -= MarkScrollUpDisplay(fore->w_histheight - markdata->hist_offset);
+ }
if (newcopylen > 0)
{
/* the +3 below is for : cr + lf + \0 */
- if (D_user->u_copybuffer != NULL)
- D_user->u_copybuffer = realloc(D_user->u_copybuffer,
- (unsigned) (D_user->u_copylen + newcopylen + 3));
+ if (md_user->u_copybuffer != NULL)
+ md_user->u_copybuffer = realloc(md_user->u_copybuffer,
+ (unsigned) (md_user->u_copylen + newcopylen + 3));
else
{
- D_user->u_copylen = 0;
- D_user->u_copybuffer = malloc((unsigned) (newcopylen + 3));
+ md_user->u_copylen = 0;
+ md_user->u_copybuffer = malloc((unsigned) (newcopylen + 3));
}
- if (D_user->u_copybuffer == NULL)
+ if (md_user->u_copybuffer == NULL)
{
MarkAbort();
in_mark = 0;
- Msg(0, "Not enough memory... Sorry.");
- D_user->u_copylen = 0;
- D_user->u_copybuffer = NULL;
+ LMsg(0, "Not enough memory... Sorry.");
+ md_user->u_copylen = 0;
+ md_user->u_copybuffer = NULL;
break;
}
if (append_mode)
{
switch (markdata->nonl)
{
- /*
+ /*
* this code defines, what glues lines together
*/
case 0:
if (join_with_cr)
{
- D_user->u_copybuffer[D_user->u_copylen] = '\r';
- D_user->u_copylen++;
+ md_user->u_copybuffer[md_user->u_copylen] = '\r';
+ md_user->u_copylen++;
}
- D_user->u_copybuffer[D_user->u_copylen] = '\n';
- D_user->u_copylen++;
+ md_user->u_copybuffer[md_user->u_copylen] = '\n';
+ md_user->u_copylen++;
break;
case 1:
break;
case 2:
- D_user->u_copybuffer[D_user->u_copylen] = ' ';
- D_user->u_copylen++;
+ md_user->u_copybuffer[md_user->u_copylen] = ' ';
+ md_user->u_copylen++;
+ break;
+ case 3:
+ md_user->u_copybuffer[md_user->u_copylen] = ',';
+ md_user->u_copylen++;
break;
}
}
- yend = D_height - 1;
- if (fore->w_histheight - markdata->hist_offset < D_height)
- {
- markdata->second = 0;
- yend -= MarkScrollUpDisplay(fore->w_histheight - markdata->hist_offset);
- }
- D_user->u_copylen += rem(markdata->x1, markdata->y1, x2, y2,
- markdata->hist_offset == fore->w_histheight,
- D_user->u_copybuffer + D_user->u_copylen, yend);
+ md_user->u_copylen += rem(markdata->x1, markdata->y1, x2, y2,
+ markdata->hist_offset == fore->w_histheight,
+ md_user->u_copybuffer + md_user->u_copylen, yend);
}
if (markdata->hist_offset != fore->w_histheight)
- LAY_CALL_UP(Activate(0));
+ {
+ LAY_CALL_UP(RedisplayLayer(flayer, 0));
+ }
ExitOverlayPage();
if (append_mode)
- Msg(0, "Appended %d characters to buffer",
+ LMsg(0, "Appended %d characters to buffer",
newcopylen);
else
- Msg(0, "Copied %d characters into buffer", D_user->u_copylen);
+ LMsg(0, "Copied %d characters into buffer", md_user->u_copylen);
if (write_buffer)
WriteFile(DUMP_EXCHANGE);
in_mark = 0;
@@ -944,18 +975,18 @@ int *inlenp;
}
default:
MarkAbort();
-#ifdef NETHACK
- if (nethackflag)
- Msg(0, "You escaped the dungeon.");
- else
-#endif
- Msg(0, "Copy mode aborted");
+ LMsg(0, "Copy mode aborted");
in_mark = 0;
break;
}
if (in_mark) /* markdata may be freed */
markdata->rep_cnt = 0;
}
+ if (in_mark)
+ {
+ flayer->l_x = markdata->cx;
+ flayer->l_y = W2D(markdata->cy);
+ }
*inbufp = pt;
*inlenp = inlen;
}
@@ -972,37 +1003,45 @@ int tx, ty, line;
{
int fx, fy;
int x, y, t, revst, reven, qq, ff, tt, st, en, ce = 0;
- int ystart = 0, yend = D_height-1;
+ int ystart = 0, yend = fore->w_height-1;
int i, ry;
char *wi;
struct mline *ml;
- struct mchar mchar_marked;
-
- mchar_marked = mchar_so;
+ struct mchar mc;
if (tx < 0)
tx = 0;
- else if (tx > D_width - 1)
- tx = D_width -1;
+ else if (tx > fore->w_width - 1)
+ tx = fore->w_width -1;
if (ty < 0)
ty = 0;
- else if (ty > fore->w_histheight + D_height - 1)
- ty = fore->w_histheight + D_height - 1;
-
+ else if (ty > fore->w_histheight + fore->w_height - 1)
+ ty = fore->w_histheight + fore->w_height - 1;
+
fx = markdata->cx; fy = markdata->cy;
+
+#ifdef KANJI
+ /* don't just move inside of a kanji, the user wants to see something */
+ ml = WIN(ty);
+ if (ty == fy && fx + 1 == tx && badkanji(ml->font, tx) && tx < D_width - 1)
+ tx++;
+ if (ty == fy && fx - 1 == tx && badkanji(ml->font, fx) && tx)
+ tx--;
+#endif
+
markdata->cx = tx; markdata->cy = ty;
-
+
/*
- * if we go to a position that is currently offscreen
+ * if we go to a position that is currently offscreen
* then scroll the screen
*/
i = 0;
- if (line >= 0 && line < D_height)
+ if (line >= 0 && line < fore->w_height)
i = W2D(ty) - line;
else if (ty < markdata->hist_offset)
i = ty - markdata->hist_offset;
- else if (ty > markdata->hist_offset + (D_height - 1))
- i = ty - markdata->hist_offset - (D_height - 1);
+ else if (ty > markdata->hist_offset + (fore->w_height - 1))
+ i = ty - markdata->hist_offset - (fore->w_height - 1);
if (i > 0)
yend -= MarkScrollUpDisplay(i);
else if (i < 0)
@@ -1010,14 +1049,14 @@ int tx, ty, line;
if (markdata->second == 0)
{
- GotoPos(tx, W2D(ty));
+ LGotoPos(flayer, tx, W2D(ty));
return;
}
-
- qq = markdata->x1 + markdata->y1 * D_width;
- ff = fx + fy * D_width; /* "from" offset in WIN coords */
- tt = tx + ty * D_width; /* "to" offset in WIN coords*/
-
+
+ qq = markdata->x1 + markdata->y1 * fore->w_width;
+ ff = fx + fy * fore->w_width; /* "from" offset in WIN coords */
+ tt = tx + ty * fore->w_width; /* "to" offset in WIN coords*/
+
if (ff > tt)
{
st = tt; en = ff;
@@ -1048,13 +1087,13 @@ int tx, ty, line;
{
y += (ystart - ry);
x = 0;
- st = y * D_width;
+ st = y * fore->w_width;
ry = ystart;
}
ml = WIN(y);
for (t = st; t <= en; t++, x++)
{
- if (x >= D_width)
+ if (x >= fore->w_width)
{
x = 0;
y++, ry++;
@@ -1064,13 +1103,12 @@ int tx, ty, line;
break;
if (t == st || x == 0)
{
- wi = ml->image + D_width;
- for (ce = D_width; ce >= 0; ce--, wi--)
+ wi = ml->image + fore->w_width;
+ for (ce = fore->w_width; ce >= 0; ce--, wi--)
if (*wi != ' ')
break;
}
- if (x <= ce && x >= markdata->left_mar && x <= markdata->right_mar
- && (D_CLP || x < D_width-1 || ry < D_bot))
+ if (x <= ce && x >= markdata->left_mar && x <= markdata->right_mar)
{
#ifdef KANJI
if (badkanji(ml->font, x))
@@ -1079,30 +1117,34 @@ int tx, ty, line;
x--;
}
#endif
- GotoPos(x, W2D(y));
#ifdef KANJI
if (t >= revst - (ml->font[x] == KANJI) && t <= reven)
#else
if (t >= revst && t <= reven)
#endif
{
+ mc = mchar_so;
+#ifdef FONT
if (pastefont)
- mchar_marked.font = ml->font[x];
- SetRendition(&mchar_marked);
+ mc.font = ml->font[x];
+#endif
+ mc.image = ml->image[x];
}
else
- SetRenditionMline(ml, x);
- PUTCHARLP(ml->image[x]);
+ copy_mline2mchar(&mc, ml, x);
+ LPutChar(flayer, &mc, x, W2D(y));
#ifdef KANJI
if (ml->font[x] == KANJI)
{
- PUTCHARLP(ml->image[++x]);
+ x++;
+ mc.image = ml->image[x];
+ LPutChar(flayer, &mc, x, W2D(y));
t++;
}
#endif
}
}
- GotoPos(tx, W2D(ty));
+ LGotoPos(flayer, tx, W2D(ty));
}
static void
@@ -1111,18 +1153,18 @@ MarkAbort()
int yend, redisp;
debug("MarkAbort\n");
- markdata = (struct markdata *)D_lay->l_data;
- fore = D_fore;
- yend = D_height - 1;
+ markdata = (struct markdata *)flayer->l_data;
+ fore = markdata->md_window;
+ yend = fore->w_height - 1;
redisp = markdata->second;
- if (fore->w_histheight - markdata->hist_offset < D_height)
+ if (fore->w_histheight - markdata->hist_offset < fore->w_height)
{
markdata->second = 0;
yend -= MarkScrollUpDisplay(fore->w_histheight - markdata->hist_offset);
}
if (markdata->hist_offset != fore->w_histheight)
{
- LAY_CALL_UP(Activate(0));
+ LAY_CALL_UP(RedisplayLayer(flayer, 0));
}
else
{
@@ -1141,44 +1183,48 @@ int isblank;
int wy, x, i, rm;
int sta, sto, cp; /* NOTE: these 3 are in WINDOW coords system */
char *wi;
- struct mline *oml, *ml;
+ struct mline *ml;
struct mchar mchar_marked;
if (y < 0) /* No special full page handling */
return;
- markdata = (struct markdata *)D_lay->l_data;
- fore = D_fore;
+ markdata = (struct markdata *)flayer->l_data;
+ fore = markdata->md_window;
mchar_marked = mchar_so;
-
- oml = isblank ? &mline_blank : &mline_null;
wy = D2W(y);
ml = WIN(wy);
if (markdata->second == 0)
{
- DisplayLine(oml, ml, y, xs, xe);
+ if (xs == 0 && y > 0 && wy > 0 && WIN(wy - 1)->image[flayer->l_width] == 0)
+ {
+ struct mchar nc;
+ copy_mline2mchar(&nc, ml, 0);
+ LWrapChar(flayer, &nc, y - 1, -1, -1, 0);
+ xs++;
+ }
+ LCDisplayLine(flayer, ml, y, xs, xe, isblank);
return;
}
-
- sta = markdata->y1 * D_width + markdata->x1;
- sto = markdata->cy * D_width + markdata->cx;
+ sta = markdata->y1 * fore->w_width + markdata->x1;
+ sto = markdata->cy * fore->w_width + markdata->cx;
if (sta > sto)
{
i=sta; sta=sto; sto=i;
}
- cp = wy * D_width + xs;
-
+ cp = wy * fore->w_width + xs;
+
rm = markdata->right_mar;
- for (x = D_width, wi = ml->image + D_width; x >= 0; x--, wi--)
+ for (x = fore->w_width, wi = ml->image + fore->w_width; x >= 0; x--, wi--)
if (*wi != ' ')
break;
if (x < rm)
rm = x;
-
+
for (x = xs; x <= xe; x++, cp++)
if (cp >= sta && x >= markdata->left_mar)
break;
@@ -1187,26 +1233,29 @@ int isblank;
x--;
#endif
if (x > xs)
- DisplayLine(oml, ml, y, xs, x - 1);
+ LCDisplayLine(flayer, ml, y, xs, x - 1, isblank);
for (; x <= xe; x++, cp++)
{
- if (cp > sto || x > rm || (!D_CLP && x >= D_width-1 && y == D_bot))
+ if (cp > sto || x > rm)
break;
+#ifdef FONT
if (pastefont)
mchar_marked.font = ml->font[x];
- GotoPos(x, y);
- SetRendition(&mchar_marked);
- PUTCHARLP(ml->image[x]);
+#endif
+ mchar_marked.image = ml->image[x];
+ LPutChar(flayer, &mchar_marked, x, y);
#ifdef KANJI
if (ml->font[x] == KANJI)
{
- PUTCHARLP(ml->image[++x]);
+ x++;
+ mchar_marked.image = ml->image[x];
+ LPutChar(flayer, &mchar_marked, x, y);
cp++;
}
#endif
}
if (x <= xe)
- DisplayLine(oml, ml, y, x, xe);
+ LCDisplayLine(flayer, ml, y, x, xe, isblank);
}
@@ -1214,8 +1263,9 @@ int isblank;
* This ugly routine is to speed up GotoPos()
*/
static int
-MarkRewrite(ry, xs, xe, doit)
+MarkRewrite(ry, xs, xe, rend, doit)
int ry, xs, xe, doit;
+struct mchar *rend;
{
int dx, x, y, st, en, t, rm;
char *i;
@@ -1224,32 +1274,33 @@ int ry, xs, xe, doit;
mchar_marked = mchar_so;
- markdata = (struct markdata *)D_lay->l_data;
- fore = D_fore;
+ debug3("MarkRewrite %d, %d-%d\n", ry, xs, xe);
+ markdata = (struct markdata *)flayer->l_data;
+ fore = markdata->md_window;
y = D2W(ry);
ml = WIN(y);
- dx = xe - xs;
+ dx = xe - xs + 1;
if (doit)
{
i = ml->image + xs;
while (dx--)
- PUTCHARLP(*i++);
+ PUTCHAR(*i++);
return 0;
}
-
+
if (markdata->second == 0)
st = en = -1;
else
{
- st = markdata->y1 * D_width + markdata->x1;
- en = markdata->cy * D_width + markdata->cx;
+ st = markdata->y1 * fore->w_width + markdata->x1;
+ en = markdata->cy * fore->w_width + markdata->cx;
if (st > en)
{
t = st; st = en; en = t;
}
}
- t = y * D_width + xs;
- for (rm = D_width, i = ml->image + D_width; rm >= 0; rm--)
+ t = y * fore->w_width + xs;
+ for (rm = fore->w_width, i = ml->image + fore->w_width; rm >= 0; rm--)
if (*i-- != ' ')
break;
if (rm > markdata->right_mar)
@@ -1259,19 +1310,23 @@ int ry, xs, xe, doit;
{
if (t >= st && t <= en && x >= markdata->left_mar && x <= rm)
{
+#ifdef FONT
if (pastefont)
mchar_marked.font = ml->font[x];
- if (!cmp_mchar(&D_rend, &mchar_marked))
+#endif
+ rend->image = mchar_marked.image;
+ if (!cmp_mchar(rend, &mchar_marked))
return EXPENSIVE;
}
else
{
- if (!cmp_mchar_mline(&D_rend, ml, x))
+ rend->image = ml->image[x];
+ if (!cmp_mchar_mline(rend, ml, x))
return EXPENSIVE;
}
x++;
}
- return xe - xs;
+ return xe - xs + 1;
}
@@ -1288,11 +1343,11 @@ int n;
return 0;
if (n > fore->w_histheight - markdata->hist_offset)
n = fore->w_histheight - markdata->hist_offset;
- i = (n < D_height) ? n : (D_height);
- ScrollV(0, 0, D_width - 1, D_height - 1, i);
markdata->hist_offset += n;
+ i = (n < flayer->l_height) ? n : (flayer->l_height);
+ LScrollV(flayer, i, 0, flayer->l_height - 1);
while (i-- > 0)
- MarkRedisplayLine(D_height - i - 1, 0, D_width - 1, 1);
+ MarkRedisplayLine(flayer->l_height - i - 1, 0, flayer->l_width - 1, 1);
return n;
}
@@ -1307,20 +1362,49 @@ int n;
return 0;
if (n > markdata->hist_offset)
n = markdata->hist_offset;
- i = (n < D_height) ? n : (D_height);
- ScrollV(0, 0, D_width - 1, D_height - 1, -i);
markdata->hist_offset -= n;
+ i = (n < flayer->l_height) ? n : (flayer->l_height);
+ LScrollV(flayer, -i, 0, fore->w_height - 1);
while (i-- > 0)
- MarkRedisplayLine(i, 0, D_width - 1, 1);
+ MarkRedisplayLine(i, 0, flayer->l_width - 1, 1);
return n;
}
int
InMark()
{
- if (display && D_layfn->LayProcess == MarkProcess)
+ if (flayer && flayer->l_layfn == &MarkLf)
return 1;
return 0;
}
+void
+MakePaster(pa, buf, len, bufiscopy)
+struct paster *pa;
+char *buf;
+int len;
+int bufiscopy;
+{
+ FreePaster(pa);
+ pa->pa_pasteptr = buf;
+ pa->pa_pastelen = len;
+ if (bufiscopy)
+ pa->pa_pastebuf = buf;
+ pa->pa_pastelayer = flayer;
+ DoProcess(Layer2Window(flayer), &pa->pa_pasteptr, &pa->pa_pastelen, pa);
+}
+
+void
+FreePaster(pa)
+struct paster *pa;
+{
+ if (pa->pa_pastebuf)
+ free(pa->pa_pastebuf);
+ pa->pa_pastebuf = 0;
+ pa->pa_pasteptr = 0;
+ pa->pa_pastelayer = 0;
+ evdeq(&pa->pa_slowev);
+}
+
#endif /* COPY_PASTE */
+
diff --git a/mark.h b/mark.h
index 5117569..4c3dd14 100644
--- a/mark.h
+++ b/mark.h
@@ -24,6 +24,8 @@
struct markdata
{
+ struct win *md_window;/* pointer to window we are working on */
+ struct user *md_user; /* The user who brought us up */
int cx, cy; /* cursor Position in WIN coords*/
int x1, y1; /* first mark in WIN coords */
int second; /* first mark dropped flag */
diff --git a/misc.c b/misc.c
index 0a73e22..7fdef8e 100644
--- a/misc.c
+++ b/misc.c
@@ -36,10 +36,12 @@ RCS_ID("$Id: misc.c,v 1.5 1994/05/31 12:32:19 mlschroe Exp $ FAU")
# include <sys/resource.h>
#endif
-extern struct display *display;
+extern struct layer *flayer;
+
extern int eff_uid, real_uid;
extern int eff_gid, real_gid;
extern struct mline mline_old;
+extern struct mchar mchar_blank;
extern char *null, *blank;
char *
@@ -55,6 +57,19 @@ register const char *str;
return cp;
}
+/* cheap strstr replacement */
+char *
+InStr(str, pat)
+char *str;
+const char *pat;
+{
+ int npat = strlen(pat);
+ for (;*str; str++)
+ if (!strncmp(str, pat, npat))
+ return str;
+ return 0;
+}
+
#ifndef HAVE_STRERROR
char *
strerror(err)
@@ -72,22 +87,41 @@ int err;
#endif
void
-centerline(str)
+centerline(str, y)
char *str;
+int y;
{
int l, n;
- ASSERT(display);
+ ASSERT(flayer);
n = strlen(str);
- if (n > D_width - 1)
- n = D_width - 1;
- l = (D_width - 1 - n) / 2;
- if (l > 0)
- AddStrn("", l);
- AddStrn(str, n);
- AddStr("\r\n");
+ if (n > flayer->l_width - 1)
+ n = flayer->l_width - 1;
+ l = (flayer->l_width - 1 - n) / 2;
+ LPutStr(flayer, str, n, &mchar_blank, l, y);
}
+void
+leftline(str, y)
+char *str;
+int y;
+{
+ int l, n;
+ struct mchar mchar_dol;
+
+ mchar_dol = mchar_blank;
+ mchar_dol.image = '$';
+
+ ASSERT(flayer);
+ l = n = strlen(str);
+ if (n > flayer->l_width - 1)
+ n = flayer->l_width - 1;
+ LPutStr(flayer, str, n, &mchar_blank, 0, y);
+ if (n != l)
+ LPutChar(flayer, &mchar_dol, n, y);
+}
+
+
char *
Filename(s)
char *s;
@@ -110,11 +144,6 @@ char *nam;
if (nam == NULL)
return NULL;
- if (p = strstr(nam,"/dev/"))
- return p + 5;
-#else /* apollo */
- if (nam == NULL)
- return NULL;
# ifdef SVR4
/* unixware has /dev/pts012 as synonym for /dev/pts/12 */
if (!strncmp(nam, "/dev/pts", 8) && nam[8] >= '0' && nam[8] <= '9')
@@ -124,6 +153,11 @@ char *nam;
return b;
}
# endif /* SVR4 */
+ if (p = strstr(nam,"/dev/"))
+ return p + 5;
+#else /* apollo */
+ if (nam == NULL)
+ return NULL;
if (strncmp(nam, "/dev/", 5) == 0)
return nam + 5;
#endif /* apollo */
@@ -284,7 +318,7 @@ int except;
f = rl.rlim_max;
else
#endif /* SVR4 */
-#if defined(SYSV) && !defined(ISC)
+#if defined(SYSV) && defined(NOFILE) && !defined(ISC)
f = NOFILE;
#else /* SYSV && !ISC */
f = getdtablesize();
@@ -294,6 +328,8 @@ int except;
close(f);
}
+
+
/*
* Security - switch to real uid
*/
@@ -382,7 +418,7 @@ UserStatus()
#endif
}
-#ifdef NEED_RENAME
+#ifndef HAVE_RENAME
int
rename (old, new)
char *old;
@@ -443,6 +479,7 @@ int len;
return p - buf;
}
+
#ifdef DEBUG
void
opendebug(new, shout)
@@ -470,6 +507,140 @@ int new, shout;
}
#endif /* DEBUG */
+void
+sleep1000(msec)
+int msec;
+
+{
+ struct timeval t;
+
+ t.tv_sec = (long) (msec / 1000);
+ t.tv_usec = (long) ((msec % 1000) * 1000);
+ select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
+}
+
+
+#if 0
+struct win **
+GlobWindows(pattern)
+char *pattern;
+{
+ static struct win *wv[MAXWIN + 1];
+ extern struct win *windows;
+ struct win *w;
+ struct win **av;
+ char *p;
+ int t, l, ll, i;
+
+ av = wv;
+
+ if (!pattern)
+ return NULL;
+ debug1("GlobWindows pattern '%s'\n", pattern);
+ t = 0;
+ p = pattern;
+ if (*p == '*')
+ {
+ t++;
+ p++;
+ }
+ l = strlen(p);
+ if (l && p[l - 1] == '*')
+ {
+ l--;
+ p[l] = '\0';
+ t += 2;
+ }
+
+ for (w = windows; w; w = w->w_next)
+ {
+ switch (t)
+ {
+ case 0: /* exact match */
+ if (!strcmp(p, w->w_title))
+ *av++ = w;
+ break;
+ case 1: /* suffix match */
+ ll = strlen(w->w_title);
+ if (l < ll && !strncmp(p, w->w_title + ll - l, l))
+ *av++ = w;
+ break;
+ case 2: /* prefix match */
+ if (!strncmp(p, w->w_title, l))
+ *av++ = w;
+ break;
+ default: /* 3: infix match */
+ ll = strlen(w->w_title);
+ for (i = ll - l; i >= 0; i--)
+ {
+ if (!strncmp(p, w->w_title + i, l))
+ {
+ *av++ = w;
+ break;
+ }
+ }
+ }
+ }
+ *av = NULL;
+#ifdef DEBUG
+ {
+ struct win **pp = wv;
+
+ while (--pp >= wv)
+ debug1("GlobWindows: '%s'\n", (*pp)->w_title);
+ }
+#endif
+ return (av != wv) ? wv : NULL;
+}
+#endif
+
+/*
+ * This uses either setenv() or putenv(). If it is putenv() we cannot dare
+ * to free the buffer after putenv(), unless it it the one found in putenv.c
+ */
+void
+xsetenv(var, value)
+char *var;
+char *value;
+{
+#ifndef USESETENV
+ char *buf;
+ int l;
+
+ if ((buf = (char *)malloc((l = strlen(var)) +
+ strlen(value) + 2)) == NULL)
+ {
+ Msg(0, strnomem);
+ return;
+ }
+ strcpy(buf, var);
+ buf[l] = '=';
+ strcpy(buf + l + 1, value);
+ putenv(buf);
+# ifdef NEEDPUTENV
+ /*
+ * we use our own putenv(), knowing that it does a malloc()
+ * the string space, we can free our buf now.
+ */
+ free(buf);
+# else /* NEEDSETENV */
+ /*
+ * For all sysv-ish systems that link a standard putenv()
+ * the string-space buf is added to the environment and must not
+ * be freed, or modified.
+ * We are sorry to say that memory is lost here, when setting
+ * the same variable again and again.
+ */
+# endif /* NEEDSETENV */
+#else /* USESETENV */
+# if defined(linux) || defined(__convex__) || (BSD >= 199103)
+ setenv(var, value, 0);
+# else
+ setenv(var, value);
+# endif /* linux || convex || BSD >= 199103 */
+#endif /* USESETENV */
+}
+
/*
* "$HOST blafoo" -> "localhost blafoo"
* "${HOST}blafoo" -> "localhostblafoo"
@@ -493,14 +664,14 @@ char *ss;
struct display *d;
{
static char ebuf[2048];
- register int esize = 2047, vtype, quofl = 0;
+ int esize = sizeof(ebuf) - 1, vtype, quofl = 0;
register char *e = ebuf;
register char *s = ss;
register char *v;
char xbuf[11];
int i;
- while (s && *s != '\0' && *s != '\n' && esize > 0)
+ while (*s && *s != '\0' && *s != '\n' && esize > 0)
{
if (*s == '\'')
quofl ^= 1;
@@ -516,19 +687,19 @@ struct display *d;
while (*p != '}')
if (*p++ == '\0')
return ss;
- vtype = 0; /* env var */
+ vtype = 0; /* env var */
break;
case ':':
p = ++s;
while (*p != ':')
if (*p++ == '\0')
return ss;
- vtype = 1; /* termcap string */
+ vtype = 1; /* termcap string */
break;
default:
- while (*p != ' ' && *p != '\0' && *p != '\n')
+ while ((*p >='a' && *p <= 'z') || (*p >='A' && *p <= 'Z') || (*p >='0' && *p <= '9') || *p == '_')
p++;
- vtype = 0; /* env var */
+ vtype = 0; /* env var */
}
c = *p;
debug1("exp: c='%c'\n", c);
@@ -616,6 +787,7 @@ struct display *d;
if (esize <= 0)
Msg(0, "expand_vars: buffer overflow\n");
*e = '\0';
+ debug1("expand_var returns '%s'\n", ebuf);
return ebuf;
}
@@ -627,7 +799,7 @@ struct display *d;
int
_delay(delay, outc)
register int delay;
-int (*outc)();
+int (*outc) __P((int));
{
int pad;
extern short ospeed;
@@ -643,7 +815,42 @@ int (*outc)();
(*outc)(0);
return 0;
}
-#endif
+
+# ifdef linux
+
+/* stupid stupid linux ncurses! It won't to padding with
+ * zeros but sleeps instead. This breaks CalcCost, of course.
+ * Also, the ncurses wait functions use a global variable
+ * to store the current outc function. Oh well...
+ */
+
+int (*save_outc) __P((int));
+
+# undef tputs
+
+void
+xtputs(str, affcnt, outc)
+char *str;
+int affcnt;
+int (*outc) __P((int));
+{
+ extern int tputs __P((const char *, int, int (*)(int)));
+ save_outc = outc;
+ tputs(str, affcnt, outc);
+}
+
+int
+_nc_timed_wait(mode, ms, tlp)
+int mode, ms, *tlp;
+{
+ _delay(ms * 10, save_outc);
+ return 0;
+}
+
+# endif /* linux */
+
+#endif /* TERMINFO */
+
#ifndef USEVARARGS
diff --git a/nethack.c b/nethack.c
new file mode 100644
index 0000000..904cc2d
--- /dev/null
+++ b/nethack.c
@@ -0,0 +1,136 @@
+/* Copyright (c) 1993
+ * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
+ * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
+ * Copyright (c) 1987 Oliver Laumann
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING); if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ ****************************************************************
+ */
+
+#include "rcs.h"
+RCS_ID("$Id: nethack.c,v 1.01 1999/07/26 19:35:25 mlschroe Exp $ FAU")
+
+#include "config.h"
+#include "screen.h"
+
+#ifdef NETHACK
+extern int nethackflag;
+#endif
+
+struct nlstrans {
+ char *from;
+ char *to;
+};
+
+#ifdef NETHACK
+struct nlstrans nethacktrans[] = {
+{"Cannot lock terminal - fork failed",
+ "Cannot fork terminal - lock failed"},
+{"Got only %d bytes from %s",
+ "You choke on your food: %d bytes from %s"},
+{"Copy mode - Column %d Line %d(+%d) (%d,%d)",
+ "Welcome to hacker's treasure zoo - Column %d Line %d(+%d) (%d,%d)"},
+{"First mark set - Column %d Line %d",
+ "You drop a magic marker - Column %d Line %d"},
+{"Copy mode aborted",
+ "You escaped the dungeon."},
+{"Filter removed.",
+ "You have a sad feeling for a moment..."},
+{"Window %d (%s) killed.",
+ "You destroy poor window %d (%s)."},
+{"Window %d (%s) is now being monitored for all activity.",
+ "You feel like someone is watching you..."},
+{"Window %d (%s) is no longer being monitored for activity.",
+ "You no longer sense the watcher's presence."},
+{"empty buffer",
+ "Nothing happens."},
+{"switched to audible bell.",
+ "Suddenly you can't see your bell!"},
+{"switched to visual bell.",
+ "Your bell is no longer invisible."},
+{"The window is now being monitored for %d sec. silence.",
+ "You feel like someone is waiting for %d sec. silence..."},
+{"The window is no longer being monitored for silence.",
+ "You no longer sense the watcher's silence."},
+{"No other window.",
+ "You cannot escape from window %d!"},
+{"Logfile \"%s\" closed.",
+ "You put away your scroll of logging named \"%s\"." },
+{"Error opening logfile \"%s\"",
+ "You don't seem to have a scroll of logging named \"%s\"."},
+{"Creating logfile \"%s\".",
+ "You start writing on your scroll of logging named \"%s\"."},
+{"Appending to logfile \"%s\".",
+ "You add to your scroll of logging named \"%s\"."},
+{"Detach aborted.",
+ "The blast of disintegration whizzes by you!"},
+{"Empty register.",
+ "Nothing happens."},
+{"[ Passwords don't match - checking turned off ]",
+ "[ Passwords don't match - your armor crumbles away ]"},
+{"Aborted because of window size change.",
+ "KAABLAMM!!! You triggered a land mine!"},
+{"Out of memory.",
+ "Who was that Maude person anyway?"},
+{"getpwuid() can't identify your account!",
+ "An alarm sounds through the dungeon...\nThe Keystone Kops are after you!"},
+{"Must be connected to a terminal.",
+ "You must play from a terminal."},
+{"No Sockets found in %s.\n",
+ "This room is empty (%s).\n"},
+{"New screen...",
+ "Be careful! New screen tonight."},
+{"Child has been stopped, restarting.",
+ "You regain consciousness."},
+{"There are screens on:",
+ "Your inventory:"},
+{"There is a screen on:",
+ "Your inventory:"},
+{"There are several screens on:",
+ "Prove thyself worthy or perish:"},
+{"There is a suitable screen on:",
+ "You see here a good looking screen:"},
+{"There are several suitable screens on:",
+ "You may wish for a screen, what do you want?"},
+{"%d socket%s wiped out.",
+ "You hear %d distant explosion%s."},
+{"Remove dead screens with 'screen -wipe'.",
+ "The dead screen%s touch%s you. Try 'screen -wipe'."},
+{"Illegal reattach attempt from terminal %s.",
+ "'%s' tries to touch your session, but fails."},
+{"Could not write %s",
+ "%s is too hard to dig in"},
+{0, 0}
+};
+#endif
+
+char *
+DoNLS(from)
+char *from;
+{
+#ifdef NETHACK
+ struct nlstrans *t;
+
+ if (nethackflag)
+ {
+ for (t = nethacktrans; t->from; t++)
+ if (strcmp(from, t->from) == 0)
+ return t->to;
+ }
+#endif
+ return from;
+}
diff --git a/os.h b/os.h
index bdba088..56743f8 100644
--- a/os.h
+++ b/os.h
@@ -24,17 +24,22 @@
#include <stdio.h>
#include <errno.h>
-#include <sys/param.h>
+#ifdef __hpux
+/* workaround for HPUX-11 which manages to include sys/user.h! */
+# define _SYS_USER_INCLUDED
+#endif
+
+#include <sys/param.h>
/* In strict ANSI mode, HP-UX machines define __hpux but not hpux */
#if defined(__hpux) && !defined(hpux)
# define hpux
#endif
-#if defined(BSDI) || defined(__386BSD__) || defined(_CX_UX) || defined(hpux)
+#if defined(__bsdi__) || defined(__386BSD__) || defined(_CX_UX) || defined(hpux) || defined(_IBMR2)
# include <signal.h>
-#endif /* BSDI || __386BSD__ || _CX_UX */
+#endif /* __bsdi__ || __386BSD__ || _CX_UX || hpux || _IBMR2 */
#ifdef ISC
# ifdef ENAMETOOLONG
@@ -83,9 +88,9 @@ extern int errno;
# define strlen ___strlen___
# include <string.h>
# undef strlen
-# ifndef NEWSOS
+# if !defined(NEWSOS) && !defined(__hpux)
extern size_t strlen(const char *);
-# endif /* NEWSOS */
+# endif
# else /* SVR4 */
# include <string.h>
# endif /* SVR4 */
@@ -94,9 +99,30 @@ extern int errno;
#ifdef USEVARARGS
# if defined(__STDC__)
# include <stdarg.h>
+# define VA_LIST(var) va_list var;
+# define VA_DOTS ...
+# define VA_DECL
+# define VA_START(ap, fmt) va_start(ap, fmt)
+# define VA_ARGS(ap) ap
+# define VA_END(ap) va_end(ap)
# else
# include <varargs.h>
+# define VA_LIST(var) va_list var;
+# define VA_DOTS va_alist
+# define VA_DECL va_dcl
+# define VA_START(ap, fmt) va_start(ap)
+# define VA_ARGS(ap) ap
+# define VA_END(ap) va_end(ap)
# endif
+#else
+# define VA_LIST(var)
+# define VA_DOTS p1, p2, p3, p4, p5, p6
+# define VA_DECL unsigned long VA_DOTS;
+# define VA_START(ap, fmt)
+# define VA_ARGS(ap) VA_DOTS
+# define VA_END(ap)
+# undef vsnprintf
+# define vsnprintf xsnprintf
#endif
#if !defined(sun) && !defined(B43) && !defined(ISC) && !defined(pyr) && !defined(_CX_UX)
@@ -104,9 +130,10 @@ extern int errno;
#endif
#include <sys/time.h>
-#if (defined(TIOCGWINSZ) || defined(TIOCSWINSZ)) && defined(M_UNIX)
+#ifdef M_UNIX /* SCO */
# include <sys/stream.h>
# include <sys/ptem.h>
+# define ftruncate(fd, s) chsize(fd, s)
#endif
#ifdef SYSV
@@ -115,7 +142,9 @@ extern int errno;
# define bzero(poi,len) memset(poi,0,len)
# define bcmp memcmp
# define killpg(pgrp,sig) kill( -(pgrp), sig)
-#else
+#endif
+
+#ifndef HAVE_GETCWD
# define getcwd(b,l) getwd(b)
#endif
@@ -142,7 +171,7 @@ extern int errno;
#endif
#if !defined(HAVE__EXIT) && !defined(_exit)
-# define _exit(x) exit(x)
+#define _exit(x) exit(x)
#endif
#ifndef HAVE_UTIMES
@@ -152,6 +181,10 @@ extern int errno;
# define vsnprintf xvsnprintf
#endif
+#ifdef BUILTIN_TELNET
+# include <netinet/in.h>
+#endif
+
/*****************************************************************
* terminal handling
*/
@@ -206,6 +239,15 @@ extern int errno;
# undef TIOCPKT
#endif
+/* linux ncurses is broken, we have to use our own tputs */
+#if defined(linux) && defined(TERMINFO)
+# define tputs xtputs
+#endif
+
+/* Alexandre Oliva: SVR4 style ptys don't work with osf */
+#ifdef __osf__
+# undef HAVE_SVR4_PTYS
+#endif
/*****************************************************************
* utmp handling
@@ -218,7 +260,7 @@ extern int errno;
#endif
#if defined(UTMPOK) || defined(BUGGYGETLOGIN)
-# if defined(SVR4) && !defined(DGUX)
+# if defined(SVR4) && !defined(DGUX) && !defined(__hpux) && !defined(linux)
# include <utmpx.h>
# define UTMPFILE UTMPX_FILE
# define utmp utmpx
@@ -241,10 +283,6 @@ extern int errno;
*/
# define UTNOKEEP
# endif /* apollo */
-# ifdef linux
- /* pututline is useless so we do it ourself... */
-# define UT_UNSORTED
-# endif
# ifndef UTMPFILE
# ifdef UTMP_FILE
@@ -318,6 +356,9 @@ extern int errno;
#if defined(S_IFDIR) && defined(S_IFMT) && !defined(S_ISDIR)
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#endif
+#if defined(S_IFLNK) && defined(S_IFMT) && !defined(S_ISLNK)
+#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
+#endif
/*
* SunOS 4.1.3: `man 2V open' has only one line that mentions O_NOBLOCK:
@@ -370,7 +411,7 @@ extern int errno;
#endif
/* Geeeee, reverse it? */
-#if defined(SVR4) || (defined(SYSV) && defined(ISC)) || defined(_AIX) || defined(linux) || defined(ultrix) || defined(__386BSD__) || defined(BSDI) || defined(POSIX) || defined(NeXT)
+#if defined(SVR4) || (defined(SYSV) && defined(ISC)) || defined(_AIX) || defined(linux) || defined(ultrix) || defined(__386BSD__) || defined(__bsdi__) || defined(POSIX) || defined(NeXT)
# define SIGHASARG
#endif
@@ -406,7 +447,7 @@ extern int errno;
* Wait stuff
*/
-#if (!defined(sysV68) && !defined(M_XENIX)) || defined(NeXT)
+#if (!defined(sysV68) && !defined(M_XENIX)) || defined(NeXT) || defined(M_UNIX)
# include <sys/wait.h>
#endif
diff --git a/osdef.h.in b/osdef.h.in
index 419434e..af82f8b 100644
--- a/osdef.h.in
+++ b/osdef.h.in
@@ -15,7 +15,8 @@
*
* You should have received a copy of the GNU General Public License
* along with this program (see the file COPYING); if not, write to the
- * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
****************************************************************
* $Id: osdef.h.in,v 1.2 1994/05/31 12:32:25 mlschroe Exp $ FAU
@@ -30,9 +31,20 @@
extern int printf __P((char *, ...));
extern int fprintf __P((FILE *, char *, ...));
extern int sprintf __P((char *, char *, ...));
+#ifdef USEVARARGS
+extern int vsprintf __P((char *, char *, char *));
+#endif
+
+#ifdef LOG_NOTICE
+extern int openlog __P((char *, int, int));
+extern int syslog __P((int, char *, ... ));
+extern int closelog __P((void));
+#endif
+
#if defined(sun) || defined(_SEQUENT_)
extern int _flsbuf __P((int, FILE *));
#endif
+
#ifdef SYSV
extern char *strchr __P((char *, int));
extern char *strrchr __P((char *, int));
@@ -88,9 +100,10 @@ extern char *crypt __P((char *, char *));
extern int putenv __P((char *));
extern int tgetent __P((char *, char *));
+extern char *tgetstr __P((char *, char **));
extern int tgetnum __P((char *));
extern int tgetflag __P((char *));
-extern void tputs __P((char *, int, void (*)(int)));
+extern void tputs __P((char *, int, int (*)(int)));
extern char *tgoto __P((char *, int, int));
#ifdef POSIX
@@ -156,12 +169,11 @@ extern int fvhangup __P((char *));
#endif
#endif
-#ifdef USEVARARGS
-extern int vsprintf __P((char *, char *, va_list));
-#endif
struct timeval; /* for select __P */
extern int select __P((int, fd_set *, fd_set *, fd_set *, struct timeval *));
+#ifdef HAVE_UTIMES
extern int utimes __P((char *, struct timeval *));
+#endif
extern void unsetenv __P((char *));
@@ -180,4 +192,6 @@ struct stat;
extern int stat __P((char *, struct stat *));
extern int lstat __P((char *, struct stat *));
extern int fstat __P((int, struct stat *));
+extern int fchmod __P((int, int));
+extern int fchown __P((int, int, int));
diff --git a/osdef.sh b/osdef.sh
index 3ecc4d7..d92ade1 100644
--- a/osdef.sh
+++ b/osdef.sh
@@ -7,6 +7,8 @@ if test -z "$srcdir"; then
srcdir=.
fi
+rm -f core*
+
sed < $srcdir/osdef.h.in -n -e '/^extern/s@.*[)* ][)* ]*\([^ *]*\) __P.*@/[)*, ]\1[ (]/i\\\
\\/\\[^a-zA-Z_\\]\1 __P\\/d@p' > osdef1.sed
cat << EOF > osdef0.c
@@ -22,9 +24,16 @@ cat << EOF > osdef0.c
#ifndef sun
#include <sys/ioctl.h>
#endif
+#ifdef linux
+#include <string.h>
+#include <stdlib.h>
+#endif
#ifndef NAMEDPIPE
#include <sys/socket.h>
#endif
+#ifndef NOSYSLOG
+#include <syslog.h>
+#endif
#include "os.h"
#if defined(UTMPOK) && defined (GETTTYENT) && !defined(GETUTENT)
#include <ttyent.h>
@@ -44,3 +53,19 @@ EOF
$CC -I. -I$srcdir -E osdef0.c | sed -n -f osdef1.sed >> osdef2.sed
sed -f osdef2.sed < $srcdir/osdef.h.in > osdef.h
rm osdef0.c osdef1.sed osdef2.sed
+
+if test -f core*; then
+ file core*
+ echo " Sorry, your sed is broken. Call the system administrator."
+ echo " Meanwhile, you may try to compile screen with an empty osdef.h file."
+ echo " But if your compiler needs to have all functions declared, you should"
+ echo " retry 'make' now and only remove offending lines from osdef.h later."
+ exit 1
+fi
+if eval test "`diff osdef.h osdef.h.in | wc -l`" -eq 4; then
+ echo " Hmm, sed is very pessimistic about your system header files."
+ echo " But it did not dump core -- strange! Let's continue carefully..."
+ echo " If this fails, you may want to remove offending lines from osdef.h"
+ echo " or try with an empty osdef.h file, if your compiler can do without"
+ echo " function declarations."
+fi
diff --git a/overlay.h b/overlay.h
deleted file mode 100644
index 62702b5..0000000
--- a/overlay.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/* Copyright (c) 1993
- * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
- * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
- * Copyright (c) 1987 Oliver Laumann
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING); if not, write to the
- * Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- ****************************************************************
- * $Id: overlay.h,v 1.3 1994/05/31 12:32:31 mlschroe Exp $ FAU
- */
-
-/*
- * This is the overlay structure. It is used to create a seperate
- * layer over the current windows.
- */
-
-struct LayFuncs
-{
- void (*LayProcess) __P((char **, int *));
- void (*LayAbort) __P((void));
- void (*LayRedisplayLine) __P((int, int, int, int));
- void (*LayClearLine) __P((int, int, int));
- int (*LayRewrite) __P((int, int, int, int));
- void (*LaySetCursor) __P((void));
- int (*LayResize) __P((int, int));
- void (*LayRestore) __P((void));
-};
-
-struct layer
-{
- struct layer *l_next;
- int l_block;
- struct LayFuncs *l_layfn;
- char *l_data; /* should be void * */
-};
-
-#define Process (*D_layfn->LayProcess)
-#define Abort (*D_layfn->LayAbort)
-#define RedisplayLine (*D_layfn->LayRedisplayLine)
-#define ClearLine (*D_layfn->LayClearLine)
-#define Rewrite (*D_layfn->LayRewrite)
-#define SetCursor (*D_layfn->LaySetCursor)
-#define Resize (*D_layfn->LayResize)
-#define Restore (*D_layfn->LayRestore)
-
-#define LAY_CALL_UP(fn) \
- { \
- struct layer *oldlay = D_lay; \
- D_lay = D_lay->l_next; \
- D_layfn = D_lay->l_layfn; \
- fn; \
- D_lay = oldlay; \
- D_layfn = D_lay->l_layfn; \
- }
-
diff --git a/patchlevel.h b/patchlevel.h
index f25e500..9b81154 100644
--- a/patchlevel.h
+++ b/patchlevel.h
@@ -40,11 +40,11 @@
* 09.09.91 -- 3.01.00 backspace bug fixed.
* 03.10.91 -- 3.01.01 ansi.c: null-ptr fixed, CLS now saves to scrollback.
* Using setresuid on hpux. Memory leak fixed.
- * Better GotoPos(). Support for IC. Another resize bug.
+ * Better GotoPos(). Support for IC. Another resize bug.
* Detach() w/o fore crashed. -T and -A(dapt) option.
* GNU copyleft.
* 19.12.91 -- 3.01.02 flow now really automatic (autoflow killed).
- * 7 bit restriction removed from WriteString().
+ * 7 bit restriction removed from WriteString().
* 09.01.92 -- 3.01.03 flow reattach bug fixed. VDISCARD bug fixed.
* 13.01.92 -- 3.01.04 new flow concept: ^Af toggles now three states
* 21.01.92 -- 3.01.05 '^A:screen 11' bug fixed. aflag in DoScreen().
@@ -64,33 +64,33 @@
* 05.05.92 -- 3.02.04 very nasty initialisation bug fixed.
* 09.05.92 -- 3.02.05 parsing for $:cl: termcap strings and \012 octal notation
* in screenrc file. More structuring. Detached startup
- * with 'screen -d -m -S...' bugfixed.
+ * with 'screen -d -m -S...' bugfixed.
* 11.05.92 -- 3.02.06 setreuid() bugs cleared, C-a : setenv added.
- * "xn" capability in TERMCAP needed since "am" is there.
+ * "xn" capability in TERMCAP needed since "am" is there.
* 25.06.92 -- 3.02.07 The multi display test version. Have merci.
* 15.07.92 -- 3.02.08 :B8: supports automatic charset switching for 8-bit
* 26.09.92 -- 3.02.09 Ported to linux. Ignoring bad files in $SCREENDIR
* 22.10.92 -- 3.02.10 screen.c/ansi.c splitted in several pieces.
- * Better ISearch. Cleanup of loadav.c
+ * Better ISearch. Cleanup of loadav.c
* 29.10.92 -- 3.02.11 Key mechanism rewritten. New command names.
- * New iscreenrc syntax.
+ * New iscreenrc syntax.
* 02.11.92 -- 3.02.12 'bind g copy_reg' and 'bind x ins_reg' as suggested by
- * stillson@tsfsrv.mitre.org (Ken Stillson).
+ * stillson@tsfsrv.mitre.org (Ken Stillson).
* 03.11.92 -- 3.02.13 Ported to SunOs 4.1.2. Gulp. Some NULL ptrs fixed and
- * misc. braindamage fixed.
+ * misc. braindamage fixed.
* 03.11.92 -- 3.02.14 Argument number checking, AKA fixed.
* 05.11.92 -- 3.02.15 Memory leaks in Detach() and KillWindow() fixed.
* Lockprg powerdetaches on SIGHUP.
* 12.11.92 -- 3.02.16 Introduced two new termcaps: "CS" and "CE".
- * (Switch cursorkeys in application mode)
- * Tim's async output patch.
- * Fixed an ugly bug in WriteString().
- * New command: 'process'
+ * (Switch cursorkeys in application mode)
+ * Tim's async output patch.
+ * Fixed an ugly bug in WriteString().
+ * New command: 'process'
* 16.11.92 -- 3.02.17 Nuking unsent tty output is now optional, (toxic
- * ESC radiation).
+ * ESC radiation).
* 30.11.92 -- 3.02.18 Lots of multi display bugs fixed. New layer
- * function 'Restore'. MULTIUSER code cleanup.
- * Rudimental acls added for multiuser.
+ * function 'Restore'. MULTIUSER code cleanup.
+ * Rudimental acls added for multiuser.
* No more error output, when output gives write errors.
* 02.12.92 -- 3.02.19 BROKEN_PIPE and SOCK_NOT_IN_FS defines added for
* braindead systems. Bug in recover socket code fixed.
@@ -139,12 +139,49 @@
* acladd/aclchg syntax improved. Updated
* documentation. Bug in at command fixed.
* MakeWindow() now obeys perm defaults.
+ * 03.10.93 -- 3.05.90 Multiple displays can now share the same window.
+ * Layers now belong to Windows. "Select -" yields a blank
+ * page. Debug output can be switched on/off at runtime.
+ * Number command changes window number and utmp-slot.
+ * 14.10.93 -- 3.05.91 Mechanism to find the "best" window added. Much
+ * debugging done and still needed. Slowpaste setting now
+ * per window. Preserving fore AND other window when
+ * detached. Per user settings for `monitor' and `silence'.
+ * New command `su'. BlankWindow performs now ColonInput.
+ * History command fixed, it depended on paste code that
+ * was previously changed to allow concatenation of buffers.
+ * Fixing umask problem with WriteFile() reported by Jamie
+ * Mason.
* 30.11.93 -- 3.05.04 Kanji support added. New keymap feature:
* bindkey and various map commands. GR and C1
* flags now define the character processing.
+ * 30.11.93 -- 3.05.92 Kanji support added. New keymap feature:
+ * bindkey and various map commands. GR and C1
+ * flags now define the character processing.
+ * 17.12.93 -- 3.05.93 Tcon authentification mechanism. AddChar macro broken up
+ * into 2 functions. Acl.c, network.c, misc.c, termcap.c
+ * and tty.c are now display free!
+ * 27.12.93 -- 3.05.94 Telnet login works, can export one window per mux.
+ * Acl-groups added. Export rights is an acl.
+ * connect works, can create shadow window thus import
+ * command channel and switch windows. Can detach sessions
+ * from each other. Can renumber imported and exported
+ * windows. DL_LOOP prevents now SEGV, sessions have names
+ * and can be connected to very flexible.
+ * 03.01.94 -- 3.05.95 Import and export of any number of channels works,
+ * except a small bug with margin handling when exporting.
+ * Window titles are forwarded, break is forwarded and
+ * tcon learned the mux protocoll. A few more bugs in
+ * network.c fixed. Tcon has Mux arrays, Protocoll is '\0'
+ * free.
+ * 08.01.94 -- 3.05.96 More tcon work. Solaris debugging.
+ *
* 14.01.94 -- 3.05.05 New FindSocket() code. Nicer socket handling.
* 20.01.94 -- 3.05.06 New attribute handling code. NeXT fixes.
* 04.02.94 -- 3.05.07 Ugly bug in ScrollH fixed. Keymap defaults.
+ * 10.03.94 -- 3.05.97 'defsilence' by Lloyd Zusman. Zombie resurrekt key.
+ * -b, -p options. Fixed Compilekeys(), gulp. config.h
+ * allows choice of VMIN/VTIME/NDELAY for ttys.
* 13.04.94 -- 3.05.08 Kanji bug fixed. POSIX sigaction support.
* os.h cleanup. UTNOKEEP splitted into
* UT_CLOSE and UT_UNSORTED. linux no longer
@@ -156,11 +193,48 @@
* password workaround.
* 09.05.94 -- 3.05.11 seteuid() support added. Security fixes.
* _IBMR2 kludge makes call to sleep obsolete.
- * Small fixes in uname() code.
+ * Small fixes in uname() code. djm suggests replace of
+ * BSDI by __bsdi__.
* 27.07.94 -- 3.05.12 seteuid attacher bug fixed. ks/ke changed
* in termcap/info and termcap.c
+ * 01.09.94 -- 3.05.58 (There are a few more patches to come, subtracted 40)
+ * breaktype command to select how we cause breaks.
+ * Testing logfile.c. Manual and texinfo documentation
+ * updated to explain all new commands except keymapping.
+ * Added modem lines to info of plain ttys. Using
+ * cfset{i,o}speed() for POSIX is better, much better.
+ * 07.09.94 -- 3.05.59 Flushing logfiles every 5 seconds. Testing new
+ * resize linewrap code. Resize with care.
+ * Resurrect now displays its command string.
+ * 11.09.94 -- 3.05.60 Lines are now correctly wrapped, when window size
+ * changes; this prevents loss of text.
+ * 15.09.94 -- 3.05.61 umask renamed to aclumask, bell renamed to bell_msg.
+ * *_msg commands show message when called w/o parameter.
+ * Many changes in the manual, thanks to Sven Guckes.
+ * -O removed.
* 27.09.94 -- 3.05.13 defwlock stupidity fixed. MakeTermcap ks/ke
* ':' removed. Termcap entry improved.
+ * copy_reg and ins_reg obsoleted by better paste command:
+ * paste => paste .
+ * copy_reg r => paste . r
+ * ins_reg r => paste r
+ * ins_reg => paste
+ * 18.10.94 -- 3.05.62 breaktype changed. -L option added to enable logging
+ * from both command line and screenrc. SIGXFSZ ignored.
+ * 28.11.94 -- 3.05.63 ACL's sharpened. No user has any rights, unless
+ * explicitly given. Only two exceptions: 1) "acladd user"
+ * without further parameters. 2) Evry user has a default
+ * umask that gives himself all permissions on the windows
+ * he creates. Bug with colon input on shared windows fixed.
+ * The commad is now executed by the user typing the final
+ * Enter-Key rather by a random user.
+ * 30.11.94 -- 3.05.64 On demand grabbing of pending auto writelocks.
+ * Solaris troubles us with kill(pid, 0) ... not fixed...
+ * defbreaktype added. (breaktype is also global, still...)
+ * SIGARGHACK cleared, to pamper poor little Ultrix4.4 cfe.
+ * defescape added.
+ * w_status changed to w_hstatus, it's a #define in
+ * Domain/OS reported by ejackson@iastate.edu.
* 05.12.94 -- 3.05.17 SVR4 pty bug fixed, don't update window status
* line if not changed, onyx support. Manual
* pages updated.
@@ -170,6 +244,11 @@
* Ugly seteuid bug in ForkWindow() fixed.
* 20.12.94 -- 3.06.00 Solaris has broken seteuid().
* osf loadav patches. -- DISTRIBUTED
+ * 08.01.95 -- 3.05.65 Bug with LOGOUTOK and -ln fixed. redundant secfopen()
+ * avoided, when logfflush() looks at delayed nfs updates.
+ * Option parser now allowes condensed options. -A fixed.
+ * New commands 'preselect' and 'defpreselect'. New option
+ * -WdmS starts a detached screen session with watchdog.
* 16.01.95 -- 3.06.01 KANJI patch. doc/Makefile.in fixed.
* Install now calls doc/Makefile install.
* Don't use 'ds' too often, breaks MSkermit.
@@ -178,6 +257,19 @@
* Use \r (not \n) to join lines in pastebuf.
* bindkey can now remove sequences.
* InitTTY fixed for PLAIN. -- DISTRIBUTED
+ * 06.02.95 -- 3.05.66 DisplayLine() does now clipping to reduce coredump-
+ * frequency. Window size is adapted to the display that
+ * types input, to reduce multi-user confusion. Scrollback
+ * mode still may get the wrong size.
+ * 07.02.95 -- 3.05.67 WinRewrite() also needs to clip. Users without unix
+ * account, but with screen password allowed. Chacl
+ * allows password change, su prompts for user name too.
+ * 01.03.95 -- 3.05.68 Leaving a window may now cause a resize to match a
+ * remaining display. Simple ESC-CR fix in the vt100
+ * state machine.
+ * 26.03.95 -- 3.05.69 Markroutine() needs to resize the window to avoid
+ * coredumps, just like WinProcess() already does.
+ * More NEED_ flags added in comm.c to avoid coredumps.
* 04.04.95 -- 3.06.02 Simple ESC-CR fix in the vt100 state machine.
* Now compiles again with all extras disabled.
* Zombie resurrect added. defc1, defgr, defkanji
@@ -189,12 +281,52 @@
* Paste bug fixed (only worked with KANJI).
* Check bcopy before memcpy/memmove.
* FindSocket code much fixed & improved.
+ * 10.04.95 -- 3.05.70 Display_displays() now shows the users permissions on
+ * the currently displayed window, this is easier than a
+ * full featured lsacl, but also helps. chacl can now copy
+ * users, but we need to copy windows.
+ * 26.04.95 -- 3.05.71 Multi digit screen numbers in utmp. MakeWindow() now
+ * echoes what it does, just like RemakeWindow() when
+ * 'verbose on' (default off).
+ * `screen -ls myname/' will find own(!) non-multi sessions.
+ * Command line option -q improved and documented.
+ * 'debug off' also shuts attacher debugging off now.
+ * 03.05.95 -- 3.05.72 'connect' command bugfixed. colon prompt improved.
+ * open(O_NONBLOCK) does not work on 4.1.3, using O_NDELAY.
+ * There are writes to exp_wid2chan[-1], XXX I just added
+ * fillers to the mux structure, please debug this ASAP!
+ * WindowByName() prefers exact matches now. Esc forwarding
+ * from Frontend to Backend suppressed unless specified.
+ * 26.06.95 -- 3.05.73 Improving the combination of dflag and rflag: If both
+ * are set, a screen session is reattached, regardless
+ * if it was previously detached or attached elseewhere.
+ * "screen -D -RR" is thus most powerful: Give me my screen
+ * session here and now. No matter, if this means creating
+ * a new session (due to the second R without warning
+ * message), detching the session first (and due to the
+ * capitalised D logging out), or simply attaching to it.
+ * 13.07.95 -- 3.05.74 Markroutine learned new join mode: comma seperated.
+ * Can disable the detach feature from config.h.
+ * Configure.in now calls etc/toolcheck. Password is no
+ * longer a static array.
+ * 30.07.95 -- 3.05.75 Karl Heuer wants to install with a relative symlink.
+ * Command line option -k removed (try -t).
* 31.08.95 -- 3.06.03 Color support, digraph command, code
* cleanup (struct mchar/mline added).
- * 13.09.95 -- 3.06.04 SetRendition display check. Solaris unblock
+ * 03.09.95 -- 3.06.04 SetRendition display check. Solaris unblock
* SIGHUP. w_curchar->w_rend, lintified.
* Shadow-password code moved and rewritten
* (includes sun C2).
+ * 06.09.95 -- 3.05.76 Added support for braille displays (by Hadi Bargi Rangin
+ * and Bill Barry, {bargy,barryb}@dots.physics.orst.edu
+ * Added baud, cs8, istrip, ixon, ixoff options for plain
+ * tty windows. Untested.
+ * 09.09.95 -- 3.07.99 Merged 3.7.76 back into the main distribution but
+ * without network, blankwindow and dlist support.
+ * Global variable Password removed.
+ * Resize code completely rewritten.
+ * New commands: sorendition, (def)charset.
+ * strftime-like message generation.
* 26.09.95 -- 3.06.05 resize code completely rewritten.
* Very visible cursor added. vbell sequence
* \Eb added. _delay for terminfo libs added
@@ -204,6 +336,21 @@
* Changed logdir command to logfile. It now uses
* MakeWinMsg() to create the filename.
* Updated the manuals.
+ * 03.10.95 -- 3.08.00 Merged 3.07.99 back into my 3.06.05.
+ * pause removed. NONROOT now in config.h.
+ * sysV68 configure test. Socket protocol got
+ * revision number. New command termcapinfo.
+ * Screenrcs, docs & configure.in updated
+ * 18.10.95 -- 3.08.01 Info shows parser state.
+ * Very visible cursor added. vbell sequence
+ * \Eb added. _delay for terminfo libs added
+ * to make the padding work for the first time.
+ * Braille code almost completely reworked.
+ * New ProcessInput() makes "command command"
+ * work. '[def]escape ""' clears escape chars.
+ * Command logdir -> logfile and uses MakeWinMsg.
+ * Updated the manuals. New mark command 'x'.
+ * stuff has new "-k" parameter.
* 28.10.95 -- 3.06.06 Added new 'XC' capability to provide
* a method for character translation.
* 17.11.95 -- 3.07.00 Added CheckEscape() function.
@@ -214,6 +361,18 @@
* -lgen added to GETUTENT configure test.
* 20.11.95 -- 3.07.01 corrected vbell null ptr reference.
* -- DISTRIBUTED
+ * 27.11.95 -- 3.08.02 Added CheckEscape() function.
+ * acl -> acls because of hpux10 nameclash
+ * /stand/vmunix added to kernel list (hpux10)
+ * stripdev changed to translate
+ * /dev/pts<n> to /dev/pts/<n> (unixware)
+ * -lgen added to GETUTENT configure test.
+ * corrected vbell null ptr reference
+ * -- 3.08.03 etc/toolcheck is now shouting louder.
+ * Solaris 2.5 has /kernel/genunix.
+ * Touching socket when detach/attach.
+ * FindWindow corrected. AIX4 patch
+ * from robert@mayday.cix.co.uk.
* 1.09.96 -- 3.07.02 added #ifdef MAPKEYS for CheckEscape.
* etc/toolcheck is now shouting louder.
* Touching socket when detach/attach.
@@ -241,11 +400,45 @@
* vsnprintf() support. exit -> _exit in window.c.
* AddXChars now tolerates NULL string.
* -- DISTRIBUTED
+ * 10.11.98 -- 3.07.05 Wayne's resize.c patch to keep the cursor
+ * onscreen. FindWindow corrected. AIX4 patch
+ * from robert@mayday.cix.co.uk.
+ * Fixed kanji am & markcursor bugs.
+ * SCO support (Gert Doering).
+ * Wayne's statusline extra space. New flag nospc
+ * for MakeWinMsg. New TF capability: add missing
+ * termcap/info caps. screen-exchange security
+ * fix. Use kstat for Solaris' loadavg.
+ * Check for mode 775 if screen runs setgid.
+ * Fixed typo in silence command.
+ * Allow detach with no tty. HPUX10.20 ltchars
+ * hack. Use @1/@7 as replacement for kh/kH.
+ * Use seteuid before calling tgetent.
+ * Check for displays in Msg().
+ * Linux ncurses hack: redefine _nc_timed_wait.
+ * Configure check for ncurses (sigh).
+ * ITOH Yasufumi: kanji fixes, osf support,
+ * bug fixes. More secure Rewrite().
+ * Increased line buffer size to 2048 bytes.
+ * SCO-5 Fixes (Brian L. Gentry).
+ * 25.11.98 -- 3.07.06 resize code now handles tabs correctly.
+ * -- DISTRIBUTED
+ * -- 3.09.00 loads'o'bugs fixed, 3.8 merged with 3.7, new region
+ * clip code. Many new features (see NEWS file).
+ * 3.08.99 -- 3.09.02 -- DISTRIBUTED
+ * 11.08.99 -- 3.09.04 small utmp fix, BSD chflags fix, tty mode fix
+ * -- DISTRIBUTED
+ * 1.09.99 -- 3.09.05 linux SVR4_PTYS fixes, better ShowWindos(),
+ * Panic() displays bug fixed, strerror fixed,
+ * missing $srcdir & bad prefix in Makefiles.
+ * console grabbing with SRIOCSREDIR.
+ * linux utmp workaround added. Some KANJI bugs
+ * fixed. Stupid StuffKey() bug fixed.
*/
#define ORIGIN "FAU"
#define REV 3
-#define VERS 7
-#define PATCHLEVEL 4
-#define DATE "23-Jun-97"
-#define STATE ""
+#define VERS 9
+#define PATCHLEVEL 5
+#define DATE "1-Sep-99"
+#define STATE ""
diff --git a/process.c b/process.c
index 737a348..e6ba1ac 100644
--- a/process.c
+++ b/process.c
@@ -22,7 +22,7 @@
*/
#include "rcs.h"
-RCS_ID("$Id: process.c,v 1.27 1994/05/31 12:32:39 mlschroe Exp $ FAU")
+RCS_ID("$Id: process.c,v 1.28 1994/09/06 17:00:12 mlschroe Exp $ FAU")
#include <sys/types.h>
#include <sys/stat.h>
@@ -39,27 +39,33 @@ RCS_ID("$Id: process.c,v 1.27 1994/05/31 12:32:39 mlschroe Exp $ FAU")
#include "config.h"
+/* for solaris 2.1, Unixware (SVR4.2) and possibly others: */
#ifdef SVR4
# include <sys/stropts.h>
#endif
#include "screen.h"
#include "extern.h"
+#include "logfile.h"
extern struct comm comms[];
extern char *rc_name;
extern char *RcFileName, *home;
extern char *BellString, *ActivityString, *ShellProg, *ShellArgs[];
-extern char *hardcopydir, *screenlogfile;
+extern char *hstatusstring, *captionstring;
+extern int captionalways;
+extern char *hardcopydir, *screenlogfile, *logtstamp_string;
+extern int log_flush, logtstamp_on, logtstamp_after;
extern char *VisualBellString;
extern int VBellWait, MsgWait, MsgMinWait, SilenceWait;
extern char SockPath[], *SockName;
extern int TtyMode, auto_detach;
extern int iflag;
extern int use_hardstatus, visual_bell;
+extern int hardstatusemu;
extern char *printcmd;
extern int default_startup;
-extern int slowpaste, defobuflimit;
+extern int defobuflimit;
extern int ZombieKey_destroy;
extern int ZombieKey_resurrect;
#ifdef AUTO_NUKE
@@ -68,23 +74,29 @@ extern int defautonuke;
extern int intrc, origintrc; /* display? */
extern struct NewWindow nwin_default, nwin_undef;
#ifdef COPY_PASTE
-extern int join_with_cr, pastefont;
+extern int join_with_cr;
+extern int compacthist;
+# ifdef FONT
+extern int pastefont;
+# endif
extern unsigned char mark_key_tab[];
extern char *BufferFile;
#endif
#ifdef POW_DETACH
extern char *BufferFile, *PowDetachString;
#endif
-extern time_t Now;
-#ifdef MAPKEYS
+#ifdef MULTIUSER
+extern struct user *EffectiveAclUser; /* acl.c */
+#endif
extern struct term term[]; /* terminal capabilities */
+#ifdef MAPKEYS
extern int maptimeout;
extern char *kmapdef[];
extern char *kmapadef[];
extern char *kmapmdef[];
#endif
-extern struct mchar mchar_so;
-
+extern struct mchar mchar_so, mchar_null;
+extern int VerboseCreate;
static int CheckArgNum __P((int, char **));
static void ClearAction __P((struct action *));
@@ -98,11 +110,7 @@ static void SwitchWindow __P((int));
static char **SaveArgs __P((char **));
static struct win *WindowByName __P((char *));
static int WindowByNumber __P((char *));
-static void DoAction __P((struct action *, int));
-static int ParseSwitch __P((struct action *, int *));
static int ParseOnOff __P((struct action *, int *));
-static int ParseSaveStr __P((struct action *act, char **));
-static int ParseNum __P((struct action *act, int *));
static int ParseWinNum __P((struct action *act, int *));
static int ParseBase __P((struct action *act, char *, int *, int, char *));
static char *ParseChar __P((char *, char *));
@@ -111,6 +119,10 @@ static void Colonfin __P((char *, int, char *));
static void InputSelect __P((void));
static void InputSetenv __P((char *));
static void InputAKA __P((void));
+#ifdef MULTIUSER
+static int InputSu __P((struct win *, struct user **, char *));
+static void su_fin __P((char *, int, char *));
+#endif
static void AKAfin __P((char *, int, char *));
#ifdef COPY_PASTE
static void copy_reg_fn __P((char *, int, char *));
@@ -125,12 +137,14 @@ static void pass2 __P((char *, int, char *));
static void pow_detach_fn __P((char *, int, char *));
#endif
static void digraph_fn __P((char *, int, char *));
+static void confirm_fn __P((char *, int, char *));
#ifdef MAPKEYS
static int StuffKey __P((int));
#endif
+static int IsOnDisplay __P((struct win *));
-
+extern struct layer *flayer;
extern struct display *display, *displays;
extern struct win *fore, *console_window, *windows;
extern struct user *users;
@@ -138,7 +152,6 @@ extern struct user *users;
extern char screenterm[], HostName[], version[];
extern struct NewWindow nwin_undef, nwin_default;
extern struct LayFuncs WinLf;
-extern struct layer BlankLayer;
extern int Z0width, Z1width;
extern int real_uid, real_gid;
@@ -154,11 +167,7 @@ struct win *wtab[MAXWIN]; /* window table, should be dynamic */
extern char *multi;
extern int maxusercount;
#endif
-char NullStr[] = ""; /* not really used */
-#ifdef PASSWORD
-int CheckPassword;
-char Password[30];
-#endif
+char NullStr[] = "";
struct plop plop_tab[MAX_PLOP_DEFS];
@@ -281,7 +290,7 @@ static const unsigned char digraphs[][3] = {
{'u', '"', 252}, /* ü */
{'y', '\'', 253}, /* ý */
{'i', 'p', 254}, /* þ */
- {'y', '"', 255}, /* y", make poor lint happy*/
+ {'y', '"', 255}, /* ÿ */
{'"', '[', 196}, /* Ä */
{'"', '\\', 214}, /* Ö */
{'"', ']', 220}, /* Ü */
@@ -384,7 +393,12 @@ InitKeytab()
ktab['W'].nr = RC_WIDTH;
ktab['.'].nr = RC_DUMPTERMCAP;
ktab[Ctrl('\\')].nr = RC_QUIT;
+#ifdef DETACH
ktab['d'].nr = ktab[Ctrl('d')].nr = RC_DETACH;
+# ifdef POW_DETACH
+ ktab['D'].nr = RC_POW_DETACH;
+# endif
+#endif
ktab['r'].nr = ktab[Ctrl('r')].nr = RC_WRAP;
ktab['f'].nr = ktab[Ctrl('f')].nr = RC_FLOW;
ktab['C'].nr = RC_CLEAR;
@@ -392,6 +406,7 @@ InitKeytab()
ktab['H'].nr = RC_LOG;
ktab['M'].nr = RC_MONITOR;
ktab['?'].nr = RC_HELP;
+ ktab['*'].nr = RC_DISPLAYS;
for (i = 0; i < ((MAXWIN < 10) ? MAXWIN : 10); i++)
{
char *args[2], arg1[10];
@@ -429,6 +444,20 @@ InitKeytab()
ktab['b'].nr = ktab[Ctrl('b')].nr = RC_BREAK;
ktab['B'].nr = RC_POW_BREAK;
ktab['_'].nr = RC_SILENCE;
+ ktab['S'].nr = RC_SPLIT;
+ ktab['Q'].nr = RC_ONLY;
+ ktab['X'].nr = RC_REMOVE;
+ ktab['F'].nr = RC_FIT;
+ ktab['\t'].nr = RC_FOCUS;
+ {
+ char *args[2];
+ args[0] = "-";
+ args[1] = NULL;
+
+ ktab['-'].nr = RC_SELECT;
+ ktab['-'].args = SaveArgs(args);
+ }
+ /* These come last; they may want overwrite others: */
if (DefaultEsc >= 0)
ktab[DefaultEsc].nr = RC_OTHER;
if (DefaultMetaEsc >= 0)
@@ -452,12 +481,16 @@ struct action *act;
act->args = noargs;
}
+/*
+ * ProcessInput: process input from display and feed it into
+ * the layer on canvas D_forecv.
+ */
#ifdef MAPKEYS
/*
* This ProcessInput just does the keybindings and passes
- * everything on to ProcessInput2
+ * everything else on to ProcessInput2.
*/
void
@@ -468,64 +501,90 @@ int ilen;
int ch, slen;
unsigned char *s;
int i, l;
+ char *p;
+ debug1("ProcessInput: %d bytes\n", ilen);
if (display == 0 || ilen == 0)
return;
+ if (D_seql)
+ evdeq(&D_mapev);
slen = ilen;
s = (unsigned char *)ibuf;
while(ilen-- > 0)
{
ch = *s++;
- if (D_dontmap)
- D_dontmap = 0;
- else if (D_nseqs)
- for (;;)
- {
- if (*(unsigned char *)D_seqp != ch)
- {
- l = *((unsigned char *)D_seqp + (KMAP_OFF - KMAP_SEQ));
- if (l)
- {
- D_seqp += sizeof(struct kmap) * l;
- continue;
- }
- if (D_seql)
- {
- D_seqp -= D_seql;
- ProcessInput2(D_seqp, D_seql);
- D_seql = 0;
- }
- D_seqp = D_kmaps[0].seq;
- D_mapdefault = 0;
- break;
- }
- if (D_seql++ == 0)
- {
- /* Finish old stuff */
- slen -= ilen + 1;
- ProcessInput2(ibuf, slen);
- D_seqruns = 0;
- }
- ibuf = (char *)s;
- slen = ilen;
- ch = -1;
- if (*++D_seqp == 0)
- {
- i = (struct kmap *)(D_seqp - D_seql - KMAP_SEQ) - D_kmaps;
- debug1("Mapping #%d", i);
- i = D_kmaps[i].nr & ~KMAP_NOTIMEOUT;
- if (StuffKey(i))
- {
- D_seqp -= D_seql;
- ProcessInput2(D_seqp, D_seql);
- }
- if (display == 0)
- return;
- D_seql = 0;
- D_seqp = D_kmaps[0].seq;
- }
- break;
- }
+ if (D_dontmap || !D_nseqs)
+ {
+ D_dontmap = 0;
+ continue;
+ }
+ for (;;)
+ {
+ if (*(unsigned char *)D_seqp != ch)
+ {
+ l = *((unsigned char *)D_seqp + (KMAP_OFF - KMAP_SEQ));
+ if (l)
+ {
+ D_seqp += sizeof(struct kmap) * l;
+ continue;
+ }
+ D_mapdefault = 0;
+ l = D_seql;
+ p = D_seqp - l;
+ D_seql = 0;
+ D_seqp = D_kmaps[0].seq;
+ if (l)
+ {
+ ProcessInput2(p, l);
+ if (display == 0)
+ return;
+ }
+ break;
+ }
+ if (D_seql++ == 0)
+ {
+ /* Finish old stuff */
+ slen -= ilen + 1;
+ ProcessInput2(ibuf, slen);
+ if (display == 0)
+ return;
+ }
+ ibuf = (char *)s;
+ slen = ilen;
+ ch = -1;
+ if (*++D_seqp == 0)
+ {
+ i = (struct kmap *)(D_seqp - D_seql - KMAP_SEQ) - D_kmaps;
+ debug1("Mapping #%d - ", i);
+ i = D_kmaps[i].nr & ~KMAP_NOTIMEOUT;
+ l = D_seql;
+ p = D_seqp - l;
+ D_seql = 0;
+ D_seqp = D_kmaps[0].seq;
+ if (StuffKey(i))
+ ProcessInput2(p, l);
+ if (display == 0)
+ return;
+ }
+ break;
+ }
+ }
+ if (D_seql)
+ {
+ struct kmap *km;
+ debug("am in sequence -> check for timeout\n");
+ km = (struct kmap *)(D_seqp - D_seql - KMAP_SEQ);
+ i = *(D_seqp - 1 + (KMAP_OFF - KMAP_SEQ));
+ if (i == 0)
+ i = D_nseqs - (km - D_kmaps);
+ for (; i; km++, i--)
+ if (km->nr & KMAP_NOTIMEOUT)
+ break;
+ if (i == 0)
+ {
+ SetTimeout(&D_mapev, maptimeout/1000);
+ evenq(&D_mapev);
+ }
}
ProcessInput2(ibuf, slen);
}
@@ -536,8 +595,7 @@ int ilen;
/*
- * Here the screen escape commands are handled, the remaining
- * chars are passed to the layer's input handler.
+ * Here only the screen escape commands are handled.
*/
void
@@ -548,8 +606,10 @@ int ilen;
char *s;
int ch, slen;
- while (display)
+ debug1("ProcessInput2: %d bytes\n", ilen);
+ while (ilen && display)
{
+ flayer = D_forecv->c_layer;
fore = D_fore;
slen = ilen;
s = ibuf;
@@ -562,8 +622,8 @@ int ilen;
ilen--;
}
slen -= ilen;
- while (slen)
- Process(&ibuf, &slen);
+ if (slen)
+ DoProcess(fore, &ibuf, &slen, 0);
if (--ilen == 0)
D_ESCseen = 1;
}
@@ -576,7 +636,7 @@ int ilen;
* As users have different esc characters, but a common ktab[],
* we fold back the users esc and meta-esc key to the Default keys
* that can be looked up in the ktab[]. grmbl. jw.
- * FIXME: make ktab[] a per user thing.
+ * XXX: make ktab[] a per user thing.
*/
if (ch == D_user->u_Esc)
ch = DefaultEsc;
@@ -590,6 +650,64 @@ int ilen;
}
}
+void
+DoProcess(p, bufp, lenp, pa)
+struct win *p;
+char **bufp;
+int *lenp;
+struct paster *pa;
+{
+ int oldlen;
+ struct display *d = display;
+
+#ifdef COPY_PASTE
+ if (!pa && p && p->w_paster.pa_pastelen)
+ {
+ debug("layer is busy - beep!\n");
+ WBell(p, visual_bell);
+ *bufp += *lenp;
+ *lenp = 0;
+ display = d;
+ return;
+ }
+ /* XXX -> PasteStart */
+ if (pa && *lenp > 1 && p && p->w_slowpaste)
+ {
+ /* schedule slowpaste event */
+ SetTimeout(&p->w_paster.pa_slowev, p->w_slowpaste);
+ evenq(&p->w_paster.pa_slowev);
+ return;
+ }
+#endif
+ while (flayer && *lenp)
+ {
+ oldlen = *lenp;
+ Process(bufp, lenp);
+#ifdef COPY_PASTE
+ if (pa && !pa->pa_pastelayer)
+ break; /* flush rest of paste */
+#endif
+ if (*lenp == oldlen)
+ {
+ if (pa)
+ {
+ display = d;
+ return;
+ }
+ /* We're full, let's beep */
+ debug("layer is full - beep!\n");
+ WBell(p, visual_bell);
+ break;
+ }
+ }
+ *bufp += *lenp;
+ *lenp = 0;
+ display = d;
+#ifdef COPY_PASTE
+ if (pa && pa->pa_pastelen == 0)
+ FreePaster(pa);
+#endif
+}
int
FindCommnr(str)
@@ -616,7 +734,14 @@ int nr;
char **args;
{
int i, n;
- static char *argss[] = {"no", "one", "two", "three"};
+ static char *argss[] = {"no", "one", "two", "three", "four", "OOPS"};
+ static char *orformat[] =
+ {
+ "%s: %s: %s argument%s required",
+ "%s: %s: %s or %s argument%s required",
+ "%s: %s: %s, %s or %s argument%s required",
+ "%s: %s: %s, %s, %s or %s argument%s required"
+ };
n = comms[nr].flags & ARGS_MASK;
for (i = 0; args[i]; i++)
@@ -625,47 +750,89 @@ char **args;
{
if (i < n)
{
- Msg(0, "%s: %s: at least %s argument%s required", rc_name, comms[nr].name, argss[n], n != 1 ? "s" : "");
+ Msg(0, "%s: %s: at least %s argument%s required",
+ rc_name, comms[nr].name, argss[n], n != 1 ? "s" : "");
return -1;
}
}
- else if ((comms[nr].flags & ARGS_PLUSONE) && (comms[nr].flags & ARGS_PLUSTWO))
+ else if ((comms[nr].flags & ARGS_PLUS1) &&
+ (comms[nr].flags & ARGS_PLUS2) &&
+ (comms[nr].flags & ARGS_PLUS3))
{
- if (i != n && i != n + 1 && i != n + 2)
+ if (i != n && i != n + 1 && i != n + 2 && i != n + 3)
{
- Msg(0, "%s: %s: %s, %s or %s argument%s required", rc_name,
- comms[nr].name, argss[n], argss[n + 1], argss[n + 2],
- n != 0 ? "s" : "");
+ Msg(0, orformat[3], rc_name, comms[nr].name, argss[n],
+ argss[n + 1], argss[n + 2], argss[n + 3], "");
return -1;
}
}
- else if (comms[nr].flags & ARGS_PLUSONE)
+ else if ((comms[nr].flags & ARGS_PLUS1) &&
+ (comms[nr].flags & ARGS_PLUS2))
{
- if (i != n && i != n + 1)
+ if (i != n && i != n + 1 && i != n + 2)
{
- Msg(0, "%s: %s: %s or %s argument%s required", rc_name, comms[nr].name, argss[n], argss[n + 1], n != 0 ? "s" : "");
+ Msg(0, orformat[2], rc_name, comms[nr].name, argss[n],
+ argss[n + 1], argss[n + 2], "");
return -1;
}
}
- else if (comms[nr].flags & ARGS_PLUSTWO)
+ else if ((comms[nr].flags & ARGS_PLUS1) &&
+ (comms[nr].flags & ARGS_PLUS3))
+ {
+ if (i != n && i != n + 1 && i != n + 3)
+ {
+ Msg(0, orformat[2], rc_name, comms[nr].name, argss[n],
+ argss[n + 1], argss[n + 3], "");
+ return -1;
+ }
+ }
+ else if ((comms[nr].flags & ARGS_PLUS2) &&
+ (comms[nr].flags & ARGS_PLUS3))
+ {
+ if (i != n && i != n + 2 && i != n + 3)
+ {
+ Msg(0, orformat[2], rc_name, comms[nr].name, argss[n],
+ argss[n + 2], argss[n + 3], "");
+ return -1;
+ }
+ }
+ else if (comms[nr].flags & ARGS_PLUS1)
+ {
+ if (i != n && i != n + 1)
+ {
+ Msg(0, orformat[1], rc_name, comms[nr].name, argss[n],
+ argss[n + 1], n != 0 ? "s" : "");
+ return -1;
+ }
+ }
+ else if (comms[nr].flags & ARGS_PLUS2)
{
if (i != n && i != n + 2)
{
- Msg(0, "%s: %s: %s or %s argument%s required", rc_name,
- comms[nr].name, argss[n], argss[n + 2], n != 0 ? "s" : "");
+ Msg(0, orformat[1], rc_name, comms[nr].name, argss[n],
+ argss[n + 2], "");
+ return -1;
+ }
+ }
+ else if (comms[nr].flags & ARGS_PLUS3)
+ {
+ if (i != n && i != n + 3)
+ {
+ Msg(0, orformat[1], rc_name, comms[nr].name, argss[n],
+ argss[n + 3], "");
return -1;
}
}
else if (i != n)
{
- Msg(0, "%s: %s: %s argument%s required", rc_name, comms[nr].name, argss[n], n != 1 ? "s" : "");
+ Msg(0, orformat[0], rc_name, comms[nr].name, argss[n], n != 1 ? "s" : "");
return -1;
}
- return 0;
+ return i;
}
/*ARGSUSED*/
-static void
+void
DoAction(act, key)
struct action *act;
int key;
@@ -673,7 +840,7 @@ int key;
int nr = act->nr;
char **args = act->args;
struct win *p;
- int i, n, msgok;
+ int argc, i, n, msgok;
char *s;
char ch;
@@ -693,21 +860,31 @@ int key;
Msg(0, "%s: %s: window required", rc_name, comms[nr].name);
return;
}
- if (CheckArgNum(nr, args))
+ if ((argc = CheckArgNum(nr, args)) < 0)
return;
#ifdef MULTIUSER
- if (multi && display)
+ if (display)
{
if (AclCheckPermCmd(D_user, ACL_EXEC, &comms[nr]))
- return;
+ {
+ Msg(0, "%s: %s: permission denied (user %s)",
+ rc_name, comms[nr].name, D_user->u_name);
+ return;
+ }
}
#endif /* MULTIUSER */
+
msgok = display && !*rc_name;
switch(nr)
{
case RC_SELECT:
if (!*args)
InputSelect();
+ else if (args[0][0] == '-' && !args[0][1])
+ {
+ SetForeWindow((struct win *)0);
+ Activate(0);
+ }
else if (ParseWinNum(act, &n) == 0)
SwitchWindow(n);
break;
@@ -727,13 +904,17 @@ int key;
if (ParseNum(act, &defobuflimit) == 0 && msgok)
Msg(0, "Default limit set to %d", defobuflimit);
if (display && *rc_name)
- D_obufmax = defobuflimit;
+ {
+ D_obufmax = defobuflimit;
+ D_obuflenmax = D_obuflen - D_obufmax;
+ }
break;
case RC_OBUFLIMIT:
if (*args == 0)
Msg(0, "Limit is %d, current buffer size is %d", D_obufmax, D_obuflen);
else if (ParseNum(act, &D_obufmax) == 0 && msgok)
Msg(0, "Limit set to %d", D_obufmax);
+ D_obuflenmax = D_obuflen - D_obufmax;
break;
case RC_DUMPTERMCAP:
WriteFile(DUMP_TERMCAP);
@@ -742,7 +923,7 @@ int key;
WriteFile(DUMP_HARDCOPY);
break;
case RC_LOG:
- n = fore->w_logfp ? 1 : 0;
+ n = fore->w_log ? 1 : 0;
ParseSwitch(act, &n);
LogToggle(n);
break;
@@ -763,39 +944,40 @@ int key;
{
char *name;
+ if (key >= 0)
+ {
+ Input(fore->w_pwin ? "Really kill this filter [y/n]" : "Really kill this window [y/n]", 1, INP_RAW, confirm_fn, (char *)RC_KILL);
+ break;
+ }
n = fore->w_number;
#ifdef PSEUDOS
if (fore->w_pwin)
{
FreePseudowin(fore);
-#ifdef NETHACK
- if (nethackflag)
- Msg(0, "You have a sad feeling for a moment...");
- else
-#endif
Msg(0, "Filter removed.");
break;
}
#endif
name = SaveStr(fore->w_title);
KillWindow(fore);
-#ifdef NETHACK
- if (nethackflag)
- Msg(0, "You destroy poor window %d (%s).", n, name);
- else
-#endif
Msg(0, "Window %d (%s) killed.", n, name);
if (name)
free(name);
break;
}
case RC_QUIT:
+ if (key >= 0)
+ {
+ Input("Really quit and kill all your windows [y/n]", 1, INP_RAW, confirm_fn, (char *)RC_QUIT);
+ break;
+ }
Finit(0);
/* NOTREACHED */
+#ifdef DETACH
case RC_DETACH:
Detach(D_DETACH);
break;
-#ifdef POW_DETACH
+# ifdef POW_DETACH
case RC_POW_DETACH:
if (key >= 0)
{
@@ -807,6 +989,7 @@ int key;
else
Detach(D_POWER); /* detach and kill Attacher's parent */
break;
+# endif
#endif
case RC_DEBUG:
#ifdef DEBUG
@@ -827,52 +1010,55 @@ int key;
}
if (strcmp("off", *args))
opendebug(0, 1);
+# ifdef SIG_NODEBUG
+ else if (display)
+ kill(D_userpid, SIG_NODEBUG); /* a one shot item, but hey... */
+# endif /* SIG_NODEBUG */
#else
- Msg(0, "Sorry, screen was compiled without -DDEBUG option.");
+ if (*args == 0 || strcmp("off", *args))
+ Msg(0, "Sorry, screen was compiled without -DDEBUG option.");
#endif
break;
case RC_ZOMBIE:
{
char ch2 = 0;
-
- if (!(s = *args))
- {
- ZombieKey_destroy = 0;
- break;
- }
- if (!(s = ParseChar(s, &ch)) || *s)
- {
- if (!s || !(s = ParseChar(s, &ch2)) || *s)
- {
- Msg(0, "%s:zombie: one or two characters expected.", rc_name);
- break;
- }
- }
- ZombieKey_destroy = ch;
- ZombieKey_resurrect = ch2;
- break;
+
+ if (!(s = *args))
+ {
+ ZombieKey_destroy = 0;
+ break;
+ }
+ if (!(s = ParseChar(s, &ch)) || *s)
+ {
+ if (!s || !(s = ParseChar(s, &ch2)) || *s)
+ {
+ Msg(0, "%s:zombie: one or two characters expected.", rc_name);
+ break;
+ }
+ }
+ ZombieKey_destroy = ch;
+ ZombieKey_resurrect = ch2;
}
+ break;
case RC_WALL:
- for (n = 0, s = *args; args[n]; n++)
- {
- /* glue the vector together again. Brute force method. */
- while (*s)
- s++;
- while (s < args[n+1])
- *s++ = ' ';
- }
#ifdef MULTIUSER
s = D_user->u_name;
#else
s = D_usertty;
#endif
- display = NULL; /* a message without display will cause a broadcast */
- Msg(0, "%s: %s", s, *args);
+ {
+ struct display *olddisplay = display;
+ display = 0; /* no display will cause a broadcast */
+ Msg(0, "%s: %s", s, *args);
+ display = olddisplay;
+ }
break;
case RC_AT:
/* where this AT command comes from: */
#ifdef MULTIUSER
s = SaveStr(D_user->u_name);
+ /* DO NOT RETURN FROM HERE WITHOUT RESETTING THIS: */
+ EffectiveAclUser = D_user;
#else
s = SaveStr(D_usertty);
#endif
@@ -885,7 +1071,7 @@ int key;
*/
switch (args[0][n])
{
- case '*':
+ case '*': /* user */
{
struct display *nd;
struct user *u;
@@ -903,6 +1089,9 @@ int key;
for (display = displays; display; display = nd)
{
nd = display->d_next;
+ if (D_forecv == 0)
+ continue;
+ flayer = D_forecv->c_layer;
fore = D_fore;
if (D_user != u)
continue;
@@ -912,12 +1101,12 @@ int key;
Msg(0, "command from %s: %s %s",
s, args[1], args[2] ? args[2] : "");
display = NULL;
+ flayer = 0;
fore = NULL;
}
- free(s);
- return;
+ break;
}
- case '%':
+ case '%': /* display */
{
struct display *nd;
@@ -925,7 +1114,10 @@ int key;
for (display = displays; display; display = nd)
{
nd = display->d_next;
+ if (D_forecv == 0)
+ continue;
fore = D_fore;
+ flayer = D_forecv->c_layer;
if (strncmp(args[0], D_usertty, n) &&
(strncmp("/dev/", D_usertty, 5) ||
strncmp(args[0], D_usertty + 5, n)) &&
@@ -939,11 +1131,11 @@ int key;
s, args[1], args[2] ? args[2] : "");
display = NULL;
fore = NULL;
+ flayer = 0;
}
- free(s);
- return;
+ break;
}
- case '#':
+ case '#': /* window */
n--;
/* FALLTHROUGH */
default:
@@ -972,12 +1164,14 @@ int key;
* what you mean, even when you adress your context wrong.
*/
i = 0;
- if (fore->w_display)
- display = fore->w_display;
+ /* XXX: other displays? */
+ if (fore->w_layer.l_cvlist)
+ display = fore->w_layer.l_cvlist->c_display;
+ flayer = fore->w_savelayer ? fore->w_savelayer : &fore->w_layer;
DoCommand(args + 1); /* may destroy our display */
- if ((fore->w_display))
+ if (fore && fore->w_layer.l_cvlist)
{
- display = fore->w_display;
+ display = fore->w_layer.l_cvlist->c_display;
Msg(0, "command from %s: %s %s",
s, args[1], args[2] ? args[2] : "");
}
@@ -986,36 +1180,42 @@ int key;
fore = NULL;
if (i < 0)
Msg(0, "%s: at '%s': no such window.\n", rc_name, args[0]);
- free(s);
- return;
+ break;
}
else if (i < MAXWIN && (fore = wtab[i]))
{
args[0][n] = ch; /* must restore string in case of bind */
debug2("AT window %d (%s)\n", fore->w_number, fore->w_title);
- if (fore->w_display)
- display = fore->w_display;
+ if (fore->w_layer.l_cvlist)
+ display = fore->w_layer.l_cvlist->c_display;
DoCommand(args + 1);
- if ((display = fore->w_display))
- Msg(0, "command from %s: %s %s",
- s, args[1], args[2] ? args[2] : "");
+ if (fore && fore->w_layer.l_cvlist)
+ {
+ display = fore->w_layer.l_cvlist->c_display;
+ Msg(0, "command from %s: %s %s",
+ s, args[1], args[2] ? args[2] : "");
+ }
display = NULL;
fore = NULL;
- free(s);
- return;
}
+ else
+ Msg(0, "%s: at [identifier][%%|*|#] command [args]", rc_name);
+ break;
}
}
- Msg(0, "%s: at [identifier][%%|*|#] command [args]", rc_name);
free(s);
+#ifdef MULTIUSER
+ EffectiveAclUser = NULL;
+#endif
break;
+
#ifdef COPY_PASTE
case RC_READREG:
/*
* Without arguments we prompt for a destination register.
* It will receive the copybuffer contents.
- * This is not done by RC_PASTE, as we prompt for source (not dest)
- * there.
+ * This is not done by RC_PASTE, as we prompt for source
+ * (not dest) there.
*/
if ((s = *args) == NULL)
{
@@ -1024,8 +1224,7 @@ int key;
}
if (((s = ParseChar(s, &ch)) == NULL) || *s)
{
- Msg(0, "%s: copyreg: character, ^x, or (octal) \\032 expected.",
- rc_name);
+ Msg(0, "%s: copyreg: character, ^x, or (octal) \\032 expected.", rc_name);
break;
}
/*
@@ -1054,8 +1253,7 @@ int key;
#endif
case RC_REGISTER:
if ((s = ParseChar(*args, &ch)) == NULL || *s)
- Msg(0, "%s: register: character, ^x, or (octal) \\032 expected.",
- rc_name);
+ Msg(0, "%s: register: character, ^x, or (octal) \\032 expected.", rc_name);
else
{
struct plop *plp = plop_tab + (int)(unsigned char)ch;
@@ -1074,14 +1272,37 @@ int key;
}
if ((s = ParseChar(s, &ch)) == NULL || *s)
{
- Msg(0, "%s: process: character, ^x, or (octal) \\032 expected.",
- rc_name);
+ Msg(0, "%s: process: character, ^x, or (octal) \\032 expected.", rc_name);
break;
}
process_fn(&ch, 0, NULL);
break;
case RC_STUFF:
s = *args;
+ if (args[1])
+ {
+ if (strcmp(s, "-k"))
+ {
+ Msg(0, "%s: stuff: invalid option %s", rc_name, s);
+ break;
+ }
+ s = args[1];
+ for (i = T_CAPS; i < T_OCAPS; i++)
+ if (strcmp(term[i].tcname, s) == 0)
+ break;
+ if (i == T_OCAPS)
+ {
+ Msg(0, "%s: stuff: unknown key '%s'", rc_name, s);
+ break;
+ }
+#ifdef MAPKEYS
+ if (StuffKey(i - T_CAPS) == 0)
+ break;
+#endif
+ s = D_tcs[i].str;
+ if (s == 0)
+ break;
+ }
n = strlen(s);
while(n)
Process(&s, &n);
@@ -1090,7 +1311,7 @@ int key;
Activate(-1);
break;
case RC_WINDOWS:
- ShowWindows();
+ ShowWindows(-1);
break;
case RC_VERSION:
Msg(0, "screen %s", version);
@@ -1114,7 +1335,7 @@ int key;
SwitchWindow(D_other ? D_other->w_number : NextWindow());
break;
case RC_META:
- if (D_user->u_Esc < 0)
+ if (D_user->u_Esc == -1)
break;
ch = D_user->u_Esc;
s = &ch;
@@ -1133,6 +1354,40 @@ int key;
n = 1;
Process(&s, &n);
break;
+ case RC_DEFBREAKTYPE:
+ case RC_BREAKTYPE:
+ {
+ static char *types[] = { "TIOCSBRK", "TCSBRK", "tcsendbreak", NULL };
+ extern int breaktype;
+
+ if (*args)
+ {
+ if (ParseNum(act, &n))
+ for (n = 0; n < sizeof(types)/sizeof(*types); n++)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ ch = args[0][i];
+ if (ch >= 'a' && ch <= 'z')
+ ch -= 'a' - 'A';
+ if (ch != types[n][i] && (ch + ('a' - 'A')) != types[n][i])
+ break;
+ }
+ if (i == 4)
+ break;
+ }
+ if (n < 0 || n >= sizeof(types)/sizeof(*types))
+ Msg(0, "%s invalid, chose one of %s, %s or %s", *args, types[0], types[1], types[2]);
+ else
+ {
+ breaktype = n;
+ Msg(0, "breaktype set to (%d) %s", n, types[n]);
+ }
+ }
+ else
+ Msg(0, "breaktype is (%d) %s", breaktype, types[breaktype]);
+ }
+ break;
case RC_POW_BREAK:
case RC_BREAK:
n = 0;
@@ -1153,6 +1408,8 @@ int key;
}
else
{
+ if (display == 0)
+ break;
if (D_width == Z0width)
n = Z1width;
else if (D_width == Z1width)
@@ -1167,12 +1424,18 @@ int key;
Msg(0, "Illegal width");
break;
}
+ if (display == 0 && fore)
+ {
+ WChangeSize(fore, n, fore->w_height);
+ break;
+ }
if (n == D_width)
break;
if (ResizeDisplay(n, D_height) == 0)
{
- DoResize(D_width, D_height);
Activate(D_fore ? D_fore->w_norefresh : 0);
+ /* autofit */
+ ResizeLayer(D_forecv->c_layer, D_forecv->c_xe - D_forecv->c_xs + 1, D_forecv->c_ye - D_forecv->c_ys + 1, 0);
}
else
Msg(0, "Your termcap does not specify how to change the terminal's width to %d.", n);
@@ -1205,13 +1468,12 @@ int key;
break;
if (ResizeDisplay(D_width, n) == 0)
{
- DoResize(D_width, D_height);
+ /* DoResize(D_width, D_height); */
Activate(D_fore ? D_fore->w_norefresh : 0);
}
else
Msg(0, "Your termcap does not specify how to change the terminal's height to %d.", n);
break;
- case RC_AKA:
case RC_TITLE:
if (*args == 0)
InputAKA();
@@ -1266,6 +1528,7 @@ int key;
Msg(0, "%cflow%s", (fore->w_flow & FLOW_NOW) ? '+' : '-',
(fore->w_flow & FLOW_AUTOFLAG) ? "(auto)" : "");
break;
+#ifdef MULTIUSER
case RC_DEFWRITELOCK:
if (args[0][0] == 'a')
nwin_default.wlock = WLOCK_AUTO;
@@ -1277,7 +1540,6 @@ int key;
}
break;
case RC_WRITELOCK:
-#ifdef MULTIUSER
if (*args)
{
if (args[0][0] == 'a')
@@ -1297,16 +1559,16 @@ int key;
if (!AclCheckPermWin(D_user, ACL_WRITE, fore))
fore->w_wlockuser = D_user;
}
-#endif
Msg(0, "writelock %s", (fore->w_wlock == WLOCK_AUTO) ? "auto" :
((fore->w_wlock == WLOCK_OFF) ? "off" : "on"));
break;
+#endif
case RC_CLEAR:
- if (fore->w_state == LIT)
- WriteString(fore, "\033[H\033[J", 6);
+ ResetAnsiState(fore);
+ WriteString(fore, "\033[H\033[J", 6);
break;
case RC_RESET:
- fore->w_state = LIT;
+ ResetAnsiState(fore);
WriteString(fore, "\033c", 2);
break;
case RC_MONITOR:
@@ -1315,23 +1577,33 @@ int key;
break;
if (n)
{
- fore->w_monitor = MON_ON;
-#ifdef NETHACK
- if (nethackflag)
- Msg(0, "You feel like someone is watching you...");
+#ifdef MULTIUSER
+ if (display) /* we tell only this user */
+ ACLBYTE(fore->w_mon_notify, D_user->u_id) |= ACLBIT(D_user->u_id);
else
+ for (i = 0; i < maxusercount; i++)
+ ACLBYTE(fore->w_mon_notify, i) |= ACLBIT(i);
#endif
+ if (fore->w_monitor == MON_OFF)
+ fore->w_monitor = MON_ON;
Msg(0, "Window %d (%s) is now being monitored for all activity.",
fore->w_number, fore->w_title);
}
else
{
- fore->w_monitor = MON_OFF;
-#ifdef NETHACK
- if (nethackflag)
- Msg(0, "You no longer sense the watcher's presence.");
+#ifdef MULTIUSER
+ if (display) /* we remove only this user */
+ ACLBYTE(fore->w_mon_notify, D_user->u_id)
+ &= ~ACLBIT(D_user->u_id);
else
+ for (i = 0; i < maxusercount; i++)
+ ACLBYTE(fore->w_mon_notify, i) &= ~ACLBIT(i);
+ for (i = maxusercount - 1; i >= 0; i--)
+ if (ACLBYTE(fore->w_mon_notify, i))
+ break;
+ if (i < 0)
#endif
+ fore->w_monitor = MON_OFF;
Msg(0, "Window %d (%s) is no longer being monitored for activity.",
fore->w_number, fore->w_title);
}
@@ -1347,7 +1619,7 @@ int key;
break;
#ifdef COPY_PASTE
case RC_COPY:
- if (D_layfn != &WinLf)
+ if (flayer->l_layfn != &WinLf)
{
Msg(0, "Must be on a window layer");
break;
@@ -1357,7 +1629,8 @@ int key;
case RC_HISTORY:
{
static char *pasteargs[] = {".", 0};
- if (D_layfn != &WinLf)
+
+ if (flayer->l_layfn != &WinLf)
{
Msg(0, "Must be on a window layer");
break;
@@ -1407,11 +1680,6 @@ int key;
}
if (l == 0)
{
-#ifdef NETHACK
- if (nethackflag)
- Msg(0, "Nothing happens.");
- else
-#endif
Msg(0, "empty buffer");
break;
}
@@ -1422,18 +1690,8 @@ int key;
*/
if (s[1] == 0 && args[1] == 0)
{
- if (fore == 0)
- break;
- fore->w_pasteptr = 0;
- fore->w_pastelen = 0;
- if (fore->w_pastebuf)
- free(fore->w_pastebuf);
- fore->w_pastebuf = 0; /* this flags we only have a pointer */
- if (*s == '.')
- fore->w_pasteptr = D_user->u_copybuffer;
- else
- fore->w_pasteptr = plop_tab[(int)(unsigned char)*s].buf;
- fore->w_pastelen = l;
+ if (fore)
+ MakePaster(&fore->w_paster, *s == '.' ? D_user->u_copybuffer : plop_tab[(int)(unsigned char)*s].buf, l, 0);
break;
}
/*
@@ -1474,11 +1732,7 @@ int key;
free(dbuf); /* no window? zap our buffer */
break;
}
- if (fore->w_pastebuf)
- free(fore->w_pastebuf);
- fore->w_pastebuf = dbuf;
- fore->w_pasteptr = fore->w_pastebuf;
- fore->w_pastelen = l;
+ MakePaster(&fore->w_paster, dbuf, l, 1);
}
else
{
@@ -1513,11 +1767,6 @@ int key;
case RC_WRITEBUF:
if (D_user->u_copybuffer == NULL)
{
-#ifdef NETHACK
- if (nethackflag)
- Msg(0, "Nothing happens.");
- else
-#endif
Msg(0, "empty buffer");
break;
}
@@ -1542,14 +1791,14 @@ int key;
Msg(0, "%s: two characters required after escape.", rc_name);
break;
}
- /* Change defescape if only one user. This is because we only
+ /* Change defescape if master user. This is because we only
* have one ktab.
*/
- if (users->u_next)
- break;
+ if (display && D_user != users)
+ break;
/* FALLTHROUGH */
case RC_DEFESCAPE:
- if (ParseEscape((struct user *)0, *args))
+ if (ParseEscape(NULL, *args))
{
Msg(0, "%s: two characters required after defescape.", rc_name);
break;
@@ -1564,6 +1813,7 @@ int key;
Msg(errno, "%s", s);
break;
case RC_SHELL:
+ case RC_DEFSHELL:
if (ParseSaveStr(act, &ShellProg) == 0)
ShellArgs[0] = ShellProg;
break;
@@ -1572,18 +1822,59 @@ int key;
break;
case RC_LOGFILE:
if (*args)
- if (ParseSaveStr(act, &screenlogfile) || !msgok)
- break;
+ {
+ if (args[1] && !(strcmp(*args, "flush")))
+ {
+ log_flush = atoi(args[1]);
+ if (msgok)
+ Msg(0, "log flush timeout set to %ds\n", log_flush);
+ break;
+ }
+ if (ParseSaveStr(act, &screenlogfile) || !msgok)
+ break;
+ }
Msg(0, "logfile is '%s'", screenlogfile);
break;
+ case RC_LOGTSTAMP:
+ if (!*args || !strcmp(*args, "on") || !strcmp(*args, "off"))
+ {
+ if (ParseSwitch(act, &logtstamp_on) == 0 && msgok)
+ Msg(0, "timestamps turned %s", logtstamp_on ? "on" : "off");
+ }
+ else if (!strcmp(*args, "string"))
+ {
+ if (args[1])
+ {
+ if (logtstamp_string)
+ free(logtstamp_string);
+ logtstamp_string = SaveStr(args[1]);
+ }
+ if (msgok)
+ Msg(0, "logfile timestamp is '%s'", logtstamp_string);
+ }
+ else if (!strcmp(*args, "after"))
+ {
+ if (args[1])
+ {
+ logtstamp_after = atoi(args[1]);
+ if (!msgok)
+ break;
+ }
+ Msg(0, "timestamp printed after %ds\n", logtstamp_after);
+ }
+ else
+ Msg(0, "usage: logtstamp [after [n]|string [str]|on|off]");
+ break;
case RC_SHELLTITLE:
- case RC_SHELLAKA:
(void)ParseSaveStr(act, &nwin_default.aka);
break;
- case RC_SLEEP:
case RC_TERMCAP:
- case RC_TERMINFO:
case RC_TERMCAPINFO:
+ case RC_TERMINFO:
+ if (!rc_name || rc_name == "")
+ Msg(0, "Sorry, too late now. Place that in your .screenrc file.");
+ break;
+ case RC_SLEEP:
break; /* Already handled */
case RC_TERM:
s = NULL;
@@ -1598,31 +1889,30 @@ int key;
strcpy(screenterm, s);
free(s);
debug1("screenterm set to %s\n", screenterm);
- MakeTermcap(display == 0);
+ MakeTermcap((display == 0));
debug("new termcap made\n");
break;
case RC_ECHO:
- if (msgok)
- {
- /*
- * D_user typed ^A:echo... well, echo isn't FinishRc's job,
- * but as he wanted to test us, we show good will
- */
- if (*args && (args[1] == 0 || (strcmp(args[1], "-n") == 0 && args[2] == 0)))
- Msg(0, "%s", args[1] ? args[1] : *args);
- else
- Msg(0, "%s: 'echo [-n] \"string\"' expected.", rc_name);
- }
+ if (!msgok)
+ break;
+ /*
+ * D_user typed ^A:echo... well, echo isn't FinishRc's job,
+ * but as he wanted to test us, we show good will
+ */
+ if (*args && (args[1] == 0 || (strcmp(args[1], "-n") == 0 && args[2] == 0)))
+ Msg(0, "%s", args[1] ? args[1] : *args);
+ else
+ Msg(0, "%s: 'echo [-n] \"string\"' expected.", rc_name);
break;
case RC_BELL:
case RC_BELL_MSG:
if (*args == 0)
- {
+ {
char buf[256];
- AddXChars(buf, sizeof(buf), BellString);
+ AddXChars(buf, sizeof(buf), BellString);
Msg(0, "bell_msg is '%s'", buf);
break;
- }
+ }
(void)ParseSaveStr(act, &BellString);
break;
#ifdef COPY_PASTE
@@ -1632,13 +1922,13 @@ int key;
else if (ParseSaveStr(act, &BufferFile))
break;
if (msgok)
- Msg(0, "Bufferfile is now '%s'\n", BufferFile);
+ Msg(0, "Bufferfile is now '%s'", BufferFile);
break;
#endif
case RC_ACTIVITY:
(void)ParseSaveStr(act, &ActivityString);
break;
-#ifdef POW_DETACH
+#if defined(DETACH) && defined(POW_DETACH)
case RC_POW_DETACH_MSG:
if (*args == 0)
{
@@ -1646,7 +1936,7 @@ int key;
AddXChars(buf, sizeof(buf), PowDetachString);
Msg(0, "pow_detach_msg is '%s'", buf);
break;
- }
+ }
(void)ParseSaveStr(act, &PowDetachString);
break;
#endif
@@ -1664,17 +1954,19 @@ int key;
if (args[0] && args[1] && args[1][0] == 'i')
{
iflag = 1;
- if ((intrc == VDISABLE) && (origintrc != VDISABLE))
+ for (display = displays; display; display = display->d_next)
{
+ if ((intrc == VDISABLE) && (origintrc != VDISABLE))
+ {
#if defined(TERMIO) || defined(POSIX)
- intrc = D_NewMode.tio.c_cc[VINTR] = origintrc;
- D_NewMode.tio.c_lflag |= ISIG;
+ intrc = D_NewMode.tio.c_cc[VINTR] = origintrc;
+ D_NewMode.tio.c_lflag |= ISIG;
#else /* TERMIO || POSIX */
- intrc = D_NewMode.m_tchars.t_intrc = origintrc;
+ intrc = D_NewMode.m_tchars.t_intrc = origintrc;
#endif /* TERMIO || POSIX */
- if (display)
- SetTTY(D_userfd, &D_NewMode);
+ SetTTY(D_userfd, &D_NewMode);
+ }
}
}
if (args[0] && args[0][0] == 'a')
@@ -1695,9 +1987,112 @@ int key;
if (ParseOnOff(act, &n) == 0)
nwin_default.monitor = (n == 0) ? MON_OFF : MON_ON;
break;
+ case RC_DEFSILENCE:
+ if (ParseOnOff(act, &n) == 0)
+ nwin_default.silence = (n == 0) ? SILENCE_OFF : SILENCE_ON;
+ break;
+ case RC_VERBOSE:
+ if (!*args)
+ Msg(0, "W%s echo command when creating windows.",
+ VerboseCreate ? "ill" : "on't");
+ else if (ParseOnOff(act, &n) == 0)
+ VerboseCreate = n;
+ break;
case RC_HARDSTATUS:
- RemoveStatus();
+ if (display)
+ RemoveStatus();
+ if (args[0] && strcmp(args[0], "on") && strcmp(args[0], "off"))
+ {
+ struct display *olddisplay = display;
+ int old_use, new_use = -1;
+
+ s = args[0];
+ if (!strncmp(s, "always", 6))
+ s += 6;
+ if (!strcmp(s, "lastline"))
+ new_use = HSTATUS_LASTLINE;
+ else if (!strcmp(s, "ignore"))
+ new_use = HSTATUS_IGNORE;
+ else if (!strcmp(s, "message"))
+ new_use = HSTATUS_MESSAGE;
+ else if (!strcmp(args[0], "string"))
+ {
+ if (!args[1])
+ {
+ char buf[256];
+ AddXChars(buf, sizeof(buf), hstatusstring);
+ Msg(0, "hardstatus string is '%s'", buf);
+ break;
+ }
+ }
+ else
+ {
+ Msg(0, "%s: usage: hardstatus [always]lastline|ignore|message|string [string]", rc_name);
+ break;
+ }
+ if (new_use != -1)
+ {
+ hardstatusemu = new_use | (s == args[0] ? 0 : HSTATUS_ALWAYS);
+ for (display = displays; display; display = display->d_next)
+ {
+ RemoveStatus();
+ new_use = hardstatusemu & ~HSTATUS_ALWAYS;
+ if (D_HS && s == args[0])
+ new_use = HSTATUS_HS;
+ ShowHStatus((char *)0);
+ old_use = D_has_hstatus;
+ D_has_hstatus = new_use;
+ if ((new_use == HSTATUS_LASTLINE && old_use != HSTATUS_LASTLINE) || (new_use != HSTATUS_LASTLINE && old_use == HSTATUS_LASTLINE))
+ ChangeScreenSize(D_width, D_height, 1);
+ RefreshHStatus();
+ }
+ }
+ if (args[1])
+ {
+ if (hstatusstring)
+ free(hstatusstring);
+ hstatusstring = SaveStr(args[1]);
+ for (display = displays; display; display = display->d_next)
+ RefreshHStatus();
+ }
+ display = olddisplay;
+ break;
+ }
(void)ParseSwitch(act, &use_hardstatus);
+ if (msgok)
+ Msg(0, "messages displayed on %s", use_hardstatus ? "hardstatus line" : "window");
+ break;
+ case RC_CAPTION:
+ if (strcmp(args[0], "always") == 0 || strcmp(args[0], "splitonly") == 0)
+ {
+ struct display *olddisplay = display;
+
+ captionalways = args[0][0] == 'a';
+ for (display = displays; display; display = display->d_next)
+ ChangeScreenSize(D_width, D_height, 1);
+ display = olddisplay;
+ }
+ else if (strcmp(args[0], "string") == 0)
+ {
+ if (!args[1])
+ {
+ char buf[256];
+ AddXChars(buf, sizeof(buf), captionstring);
+ Msg(0, "caption string is '%s'", buf);
+ break;
+ }
+ }
+ else
+ {
+ Msg(0, "%s: usage: caption always|splitonly|string <string>", rc_name);
+ break;
+ }
+ if (!args[1])
+ break;
+ if (captionstring)
+ free(captionstring);
+ captionstring = SaveStr(args[1]);
+ RedisplayDisplays(0);
break;
case RC_CONSOLE:
n = (console_window != 0);
@@ -1731,23 +2126,9 @@ int key;
if (ParseSwitch(act, &visual_bell) || !msgok)
break;
if (visual_bell == 0)
- {
-#ifdef NETHACK
- if (nethackflag)
- Msg(0, "Suddenly you can't see your bell!");
- else
-#endif
- Msg(0, "switched to audible bell.");
- }
+ Msg(0, "switched to audible bell.");
else
- {
-#ifdef NETHACK
- if (nethackflag)
- Msg(0, "Your bell is no longer invisible.");
- else
-#endif
- Msg(0, "switched to visual bell.");
- }
+ Msg(0, "switched to visual bell.");
break;
case RC_VBELLWAIT:
if (ParseNum(act, &VBellWait) == 0 && msgok)
@@ -1767,8 +2148,7 @@ int key;
if (SilenceWait < 1)
SilenceWait = 1;
for (p = windows; p; p = p->w_next)
- if (p->w_tstamp.seconds)
- p->w_tstamp.seconds = SilenceWait;
+ p->w_silencewait = SilenceWait;
Msg(0, "silencewait set to %d seconds", SilenceWait);
}
break;
@@ -1788,26 +2168,38 @@ int key;
if (p)
p->w_number = old;
#ifdef MULTIUSER
+ /* exchange the acls for these windows. */
AclWinSwap(old, n);
#endif
- /* yucc */
- if (fore->w_hstatus)
+#ifdef UTMPOK
+ /* exchange the utmp-slots for these windows */
+ if ((fore->w_slot != (slot_t) -1) && (fore->w_slot != (slot_t) 0))
{
- display = fore->w_display;
- if (display)
- RefreshStatus();
+ RemoveUtmp(fore);
+ SetUtmp(fore);
}
+ if (p && (p->w_slot != (slot_t) -1) && (p->w_slot != (slot_t) 0))
+ {
+ /* XXX: first display wins? */
+ display = fore->w_layer.l_cvlist ? fore->w_layer.l_cvlist->c_display : 0;
+ RemoveUtmp(p);
+ SetUtmp(p);
+ }
+#endif
+
+ WindowChanged(fore, 'n');
+ WindowChanged((struct win *)0, 'w');
+ WindowChanged((struct win *)0, 'W');
}
break;
case RC_SILENCE:
- n = fore->w_tstamp.seconds != 0;
- i = SilenceWait;
- if (args[0] &&
- (args[0][0] == '-' || (args[0][0] >= '0' && args[0][0] <= '9')))
+ n = fore->w_silence != 0;
+ i = fore->w_silencewait;
+ if (args[0] && (args[0][0] == '-' || (args[0][0] >= '0' && args[0][0] <= '9')))
{
if (ParseNum(act, &i))
break;
- n = i;
+ n = i > 0;
}
else if (ParseSwitch(act, &n))
break;
@@ -1817,22 +2209,17 @@ int key;
if (display) /* we tell only this user */
ACLBYTE(fore->w_lio_notify, D_user->u_id) |= ACLBIT(D_user->u_id);
else
- for (i = 0; i < maxusercount; i++)
- ACLBYTE(fore->w_mon_notify, i) |= ACLBIT(i);
- if (!fore->w_tstamp.seconds)
+ for (n = 0; n < maxusercount; n++)
+ ACLBYTE(fore->w_lio_notify, n) |= ACLBIT(n);
#endif
- fore->w_tstamp.lastio = time(0);
- fore->w_tstamp.seconds = i;
+ fore->w_silencewait = i;
+ fore->w_silence = SILENCE_ON;
+ SetTimeout(&fore->w_silenceev, fore->w_silencewait * 1000);
+ evenq(&fore->w_silenceev);
+
if (!msgok)
break;
-#ifdef NETHACK
- if (nethackflag)
- Msg(0, "You feel like someone is waiting for %d sec. silence...",
- fore->w_tstamp.seconds);
- else
-#endif
- Msg(0, "Window %d (%s) is now being monitored for %d sec. silence.",
- fore->w_number, fore->w_title, fore->w_tstamp.seconds);
+ Msg(0, "The window is now being monitored for %d sec. silence.", fore->w_silencewait);
}
else
{
@@ -1841,26 +2228,20 @@ int key;
ACLBYTE(fore->w_lio_notify, D_user->u_id)
&= ~ACLBIT(D_user->u_id);
else
- for (i = 0; i < maxusercount; i++)
- ACLBYTE(fore->w_lio_notify, i) &= ~ACLBIT(i);
+ for (n = 0; n < maxusercount; n++)
+ ACLBYTE(fore->w_lio_notify, n) &= ~ACLBIT(n);
for (i = maxusercount - 1; i >= 0; i--)
if (ACLBYTE(fore->w_lio_notify, i))
break;
if (i < 0)
#endif
{
- fore->w_tstamp.lastio = (time_t)0;
- fore->w_tstamp.seconds = 0;
+ fore->w_silence = SILENCE_OFF;
+ evdeq(&fore->w_silenceev);
}
if (!msgok)
break;
-#ifdef NETHACK
- if (nethackflag)
- Msg(0, "You no longer sense the watcher's silence.");
- else
-#endif
- Msg(0, "Window %d (%s) is no longer being monitored for silence.",
- fore->w_number, fore->w_title);
+ Msg(0, "The window is no longer being monitored for silence.");
}
break;
#ifdef COPY_PASTE
@@ -1881,7 +2262,7 @@ int key;
{
char buf[MAXPATHLEN];
- s = NULL;
+ s = 0;
if (ParseSaveStr(act, &s))
break;
if (!*s || strlen(s) + (SockName - SockPath) > MAXPATHLEN - 13)
@@ -1915,57 +2296,33 @@ int key;
InputSetenv(args[0]);
}
else
-#ifndef USESETENV
- {
- char *buf;
- int l;
-
- if ((buf = (char *)malloc((l = strlen(args[0])) +
- strlen(args[1]) + 2)) == NULL)
- {
- Msg(0, strnomem);
- break;
- }
- strcpy(buf, args[0]);
- buf[l] = '=';
- strcpy(buf + l + 1, args[1]);
- putenv(buf);
-# ifdef NEEDPUTENV
- /*
- * we use our own putenv(), knowing that it does a malloc()
- * the string space, we can free our buf now.
- */
- free(buf);
-# else /* NEEDSETENV */
- /*
- * For all sysv-ish systems that link a standard putenv()
- * the string-space buf is added to the environment and must not
- * be freed, or modified.
- * We are sorry to say that memory is lost here, when setting
- * the same variable again and again.
- */
-# endif /* NEEDSETENV */
- }
-#else /* USESETENV */
-# if defined(linux) || defined(__convex__) || (BSD >= 199103)
- setenv(args[0], args[1], 0);
-# else
- setenv(args[0], args[1]);
-# endif /* linux || convex || BSD >= 199103 */
-#endif /* USESETENV */
- MakeNewEnv();
+ {
+ xsetenv(args[0], args[1]);
+ MakeNewEnv();
+ }
break;
case RC_UNSETENV:
unsetenv(*args);
MakeNewEnv();
break;
+#ifdef COPY_PASTE
+ case RC_DEFSLOWPASTE:
+ (void)ParseNum(act, &nwin_default.slow);
+ break;
case RC_SLOWPASTE:
- if (ParseNum(act, &slowpaste) == 0 && msgok)
- Msg(0, "slowpaste set to %d milliseconds", slowpaste);
+ if (*args == 0)
+ Msg(0, fore->w_slowpaste ?
+ "Slowpaste in window %d is %d milliseconds." :
+ "Slowpaste in window %d is unset.",
+ fore->w_number, fore->w_slowpaste);
+ else if (ParseNum(act, &fore->w_slowpaste) == 0 && msgok)
+ Msg(0, fore->w_slowpaste ?
+ "Slowpaste in window %d set to %d milliseconds." :
+ "Slowpaste in window %d now unset.",
+ fore->w_number, fore->w_slowpaste);
break;
-#ifdef COPY_PASTE
case RC_MARKKEYS:
- s = NULL;
+ s = 0;
if (ParseSaveStr(act, &s))
break;
if (CompileKeys(s, mark_key_tab))
@@ -1977,13 +2334,19 @@ int key;
debug1("markkeys %s\n", *args);
free(s);
break;
+# ifdef FONT
case RC_PASTEFONT:
if (ParseSwitch(act, &pastefont) == 0 && msgok)
Msg(0, "Will %spaste font settings", pastefont ? "" : "not ");
break;
+# endif
case RC_CRLF:
(void)ParseSwitch(act, &join_with_cr);
break;
+ case RC_COMPACTHIST:
+ if (ParseSwitch(act, &compacthist) == 0 && msgok)
+ Msg(0, "%scompacting history lines", compacthist ? "" : "not ");
+ break;
#endif
#ifdef NETHACK
case RC_NETHACK:
@@ -1994,18 +2357,18 @@ int key;
(void)ParseOnOff(act, &hardcopy_append);
break;
case RC_VBELL_MSG:
- if (*args == 0)
- {
+ if (*args == 0)
+ {
char buf[256];
AddXChars(buf, sizeof(buf), VisualBellString);
Msg(0, "vbell_msg is '%s'", buf);
- break;
- }
+ break;
+ }
(void)ParseSaveStr(act, &VisualBellString);
debug1(" new vbellstr '%s'\n", VisualBellString);
break;
case RC_DEFMODE:
- if (ParseBase(act, *args, &n, 8, "oct"))
+ if (ParseBase(act, *args, &n, 8, "octal"))
break;
if (n < 0 || n > 0777)
{
@@ -2024,27 +2387,34 @@ int key;
break;
#ifdef PASSWORD
case RC_PASSWORD:
- CheckPassword = 1;
if (*args)
{
- strncpy(Password, *args, sizeof(Password) - 1);
- if (!strcmp(Password, "none"))
- CheckPassword = 0;
+ struct user *u = display ? D_user : users;
+
+ n = (*u->u_password) ? 1 : 0;
+ if (u->u_password != NullStr) free((char *)u->u_password);
+ u->u_password = SaveStr(*args);
+ if (!strcmp(u->u_password, "none"))
+ {
+ if (n)
+ Msg(0, "Password checking disabled");
+ free(u->u_password);
+ u->u_password = NullStr;
+ }
}
else
{
- if (display == 0)
+ if (!fore)
{
- debug("prompting for password on no display???\n");
+ Msg(0, "%s: password: window required", rc_name);
break;
}
- Input("New screen password:", sizeof(Password) - 1, INP_NOECHO,
- pass1, NULL);
+ Input("New screen password:", 100, INP_NOECHO, pass1, (char *)D_user);
}
break;
#endif /* PASSWORD */
case RC_BIND:
- if ((s = ParseChar(*args, &ch)) == NULL || *s)
+ if ((s = ParseChar(*args, &ch)) == 0 || *s)
{
Msg(0, "%s: bind: character, ^x, or (octal) \\032 expected.",
rc_name);
@@ -2059,7 +2429,7 @@ int key;
Msg(0, "%s: bind: unknown command '%s'", rc_name, args[1]);
break;
}
- if (CheckArgNum(i, args + 2))
+ if (CheckArgNum(i, args + 2) < 0)
break;
ktab[n].nr = i;
if (args[2])
@@ -2165,7 +2535,7 @@ int key;
Msg(0, "%s: bindkey: unknown command '%s'", rc_name, args[1]);
break;
}
- if (CheckArgNum(newnr, args + 2))
+ if (CheckArgNum(newnr, args + 2) < 0)
break;
newact->nr = newnr;
if (args[2])
@@ -2218,9 +2588,9 @@ int key;
#ifdef MULTIUSER
case RC_ACLCHG:
case RC_ACLADD:
- for (n = 0; args[n]; n++)
- ;
- UsersAcl(NULL, n, args);
+ case RC_ADDACL:
+ case RC_CHACL:
+ UsersAcl(NULL, argc, args);
break;
case RC_ACLDEL:
if (UserDel(args[0], NULL))
@@ -2229,9 +2599,73 @@ int key;
Msg(0, "%s removed from acl database", args[0]);
break;
case RC_ACLGRP:
- {
- break;
+ /*
+ * modify a user to gain or lose rights granted to a group.
+ * This group is actually a normal user whose rights were defined
+ * with chacl in the usual way.
+ */
+ if (args[1])
+ {
+ if (strcmp(args[1], "none")) /* link a user to another user */
+ {
+ if (AclLinkUser(args[0], args[1]))
+ break;
+ if (msgok)
+ Msg(0, "User %s joined acl-group %s", args[0], args[1]);
+ }
+ else /* remove all groups from user */
+ {
+ struct user *u;
+ struct usergroup *g;
+
+ if (!(u = *FindUserPtr(args[0])))
+ break;
+ while ((g = u->u_group))
+ {
+ u->u_group = g->next;
+ free((char *)g);
+ }
+ }
+ }
+ else /* show all groups of user */
+ {
+ char buf[256], *p = buf;
+ int ngroups = 0;
+ struct user *u;
+ struct usergroup *g;
+
+ if (!(u = *FindUserPtr(args[0])))
+ {
+ if (msgok)
+ Msg(0, "User %s does not exist.", args[0]);
+ break;
+ }
+ g = u->u_group;
+ while (g)
+ {
+ ngroups++;
+ sprintf(p, "%s ", g->u->u_name);
+ p += strlen(p);
+ if (p > buf+200)
+ break;
+ g = g->next;
+ }
+ if (ngroups)
+ *(--p) = '\0';
+ Msg(0, "%s's group%s: %s.", args[0], (ngroups == 1) ? "" : "s",
+ (ngroups == 0) ? "none" : buf);
}
+ break;
+ case RC_ACLUMASK:
+ case RC_UMASK:
+ while ((s = *args++))
+ {
+ char *err = 0;
+
+ if (AclUmask(display ? D_user : users, s, &err))
+ Msg(0, "umask: %s\n", err);
+ }
+ break;
case RC_MULTIUSER:
if (ParseOnOff(act, &n))
break;
@@ -2247,8 +2681,10 @@ int key;
break;
#endif
#ifdef MULTI
- case RC_CLONE:
- execclone(args);
+ case RC_NONBLOCK:
+ if (!ParseSwitch(act, &i) && msgok)
+ Msg(0, "display set to %sblocking mode.", D_nonblock ? "non" : "");
+ D_nonblock = i;
break;
#endif
case RC_GR:
@@ -2274,7 +2710,7 @@ int key;
else
{
Msg(0, "kanji: illegal argument (%s)", args[i]);
- break;
+ break;
}
if (i == 0)
fore->w_kanji = n;
@@ -2294,11 +2730,12 @@ int key;
else
{
Msg(0, "defkanji: illegal argument (%s)", *args);
- break;
+ break;
}
nwin_default.kanji = n;
break;
#endif
+
case RC_PRINTCMD:
if (*args)
{
@@ -2309,11 +2746,15 @@ int key;
printcmd = SaveStr(*args);
}
if (*args == 0 || msgok)
- if (printcmd)
- Msg(0, "using '%s' as print command", printcmd);
- else
- Msg(0, "using termcap entries for printing");
+ {
+ if (printcmd)
+ Msg(0, "using '%s' as print command", printcmd);
+ else
+ Msg(0, "using termcap entries for printing");
+ break;
+ }
break;
+
case RC_DIGRAPH:
Input("Enter digraph: ", 10, INP_EVERY, digraph_fn, NULL);
if (*args && **args)
@@ -2323,9 +2764,10 @@ int key;
Process(&s, &n);
}
break;
+
case RC_DEFHSTATUS:
if (*args == 0)
- {
+ {
char buf[256];
*buf = 0;
if (nwin_default.hstatus)
@@ -2340,6 +2782,17 @@ int key;
nwin_default.hstatus = 0;
}
break;
+ case RC_HSTATUS:
+ (void)ParseSaveStr(act, &fore->w_hstatus);
+ if (*fore->w_hstatus == 0)
+ {
+ free(fore->w_hstatus);
+ fore->w_hstatus = 0;
+ }
+ WindowChanged(fore, 'h');
+ break;
+
+#ifdef FONT
case RC_DEFCHARSET:
case RC_CHARSET:
if (*args == 0)
@@ -2373,6 +2826,7 @@ int key;
free(nwin_default.charset);
nwin_default.charset = SaveStr(*args);
break;
+#endif
case RC_SORENDITION:
i = mchar_so.attr;
if (*args && **args)
@@ -2406,7 +2860,61 @@ int key;
Msg(0, "Standout attributes 0x%02x", (unsigned char)mchar_so.attr);
#endif
break;
+
+#ifdef MULTIUSER
+ case RC_SU:
+ s = NULL;
+ if (!*args)
+ {
+ Msg(0, "%s:%s screen login", HostName, SockPath);
+ InputSu(D_fore, &D_user, NULL);
+ }
+ else if (!args[1])
+ InputSu(D_fore, &D_user, args[0]);
+ else if (!args[2])
+ s = DoSu(&D_user, args[0], args[1], "\377");
+ else
+ s = DoSu(&D_user, args[0], args[1], args[2]);
+ if (s)
+ Msg(0, "%s", s);
+ break;
+#endif /* MULTIUSER */
+ case RC_SPLIT:
+ AddCanvas();
+ Activate(-1);
+ break;
+ case RC_REMOVE:
+ RemCanvas();
+ Activate(-1);
+ break;
+ case RC_ONLY:
+ OneCanvas();
+ Activate(-1);
+ break;
+ case RC_FIT:
+ D_forecv->c_xoff = D_forecv->c_xs;
+ D_forecv->c_yoff = D_forecv->c_ys;
+ RethinkViewportOffsets(D_forecv);
+ ResizeLayer(D_forecv->c_layer, D_forecv->c_xe - D_forecv->c_xs + 1, D_forecv->c_ye - D_forecv->c_ys + 1, 0);
+ /* XXX: only on canvas? */
+ flayer = D_forecv->c_layer;
+ SetCursor();
+ break;
+ case RC_FOCUS:
+ D_forecv = D_forecv->c_next ? D_forecv->c_next : D_cvlist;
+ D_fore = Layer2Window(D_forecv->c_layer);
+ fore = D_fore;
+ RefreshHStatus();
+ /* XXX: only on canvas? */
+ flayer = D_forecv->c_layer;
+ Restore();
+ SetCursor();
+ break;
default:
+#ifdef HAVE_BRAILLE
+ /* key == -2: input from braille keybord, msgok always 0 */
+ DoBrailleAction(act, key == -2 ? 0 : msgok);
+#endif
break;
}
}
@@ -2533,6 +3041,15 @@ char *buf, **args;
}
}
+/*
+ * buf is split into argument vector args.
+ * leading whitespace is removed.
+ * @!| abbreviations are expanded.
+ * the end of buffer is recognized by '\0' or an un-escaped '#'.
+ * " and ' are interpreted.
+ *
+ * argc is returned.
+ */
int
ParseEscape(u, p)
struct user *u;
@@ -2541,11 +3058,9 @@ char *p;
unsigned char buf[2];
int e, me;
-#ifdef MAPKEYS
if (*p == 0)
e = me = -1;
else
-#endif
{
if ((p = ParseChar(p, (char *)buf)) == NULL ||
(p = ParseChar(p, (char *)buf+1)) == NULL || *p)
@@ -2586,7 +3101,7 @@ char *p;
return 0;
}
-static int
+int
ParseSwitch(act, var)
struct action *act;
int *var;
@@ -2623,7 +3138,7 @@ int *var;
return 0;
}
-static int
+int
ParseSaveStr(act, var)
struct action *act;
char **var;
@@ -2640,7 +3155,7 @@ char **var;
return 0;
}
-static int
+int
ParseNum(act, var)
struct action *act;
int *var;
@@ -2751,7 +3266,6 @@ int *var;
return 0;
}
-
static int
ParseBase(act, p, var, base, bname)
struct action *act;
@@ -2840,7 +3354,7 @@ int base, psize;
char *s, *p;
{
char *q;
- if ((q = rindex(s, ':')) != NULL)
+ if ((q = rindex(s, ':')) != 0)
{
strncpy(p, q + 1, psize - 1);
p[psize - 1] = '\0';
@@ -2858,11 +3372,19 @@ int n;
struct win *p;
debug1("SwitchWindow %d\n", n);
+ if (n < 0 || n >= MAXWIN)
+ {
+ ShowWindows(-1);
+ return;
+ }
+ if ((p = wtab[n]) == 0)
+ {
+ ShowWindows(n);
+ return;
+ }
if (display == 0)
- return;
- if (n < 0 || n >= MAXWIN || (p = wtab[n]) == 0)
{
- ShowWindows();
+ fore = p;
return;
}
if (p == D_fore)
@@ -2870,110 +3392,175 @@ int n;
Msg(0, "This IS window %d (%s).", n, p->w_title);
return;
}
- if (p->w_display)
+#ifdef MULTIUSER
+ if (AclCheckPermWin(D_user, ACL_READ, p))
{
- Msg(0, "Window %d (%s) is on another display (%s@%s).", n, p->w_title,
- p->w_display->d_user->u_name, p->w_display->d_usertty);
+ Msg(0, "Access to window %d denied.", p->w_number);
return;
}
+#endif
SetForeWindow(p);
Activate(fore->w_norefresh);
-}
+}
-/*
- * returns 0, if the lock really has been released
- */
-int
-ReleaseAutoWritelock(dis, w)
-struct display *dis;
-struct win *w;
+
+void
+SetCanvasWindow(cv, wi)
+struct canvas *cv;
+struct win *wi;
{
- /* release auto writelock when user has no other display here */
- if (w->w_wlock == WLOCK_AUTO && w->w_wlockuser == D_user)
- {
- struct display *d;
+ struct win *p = 0, **pp;
+ struct layer *l;
+ struct canvas *cvp, **cvpp;
+
+ l = cv->c_layer;
+ display = cv->c_display;
- for (d = displays; d; d = d->d_next)
- if ((d != display) && (d->d_fore == w))
+ if (l)
+ {
+ /* remove old layer */
+ for (cvpp = &l->l_cvlist; (cvp = *cvpp); cvpp = &cvp->c_lnext)
+ if (cvp == cv)
break;
- debug3("%s %s autolock on win %d\n",
- D_user->u_name, d?"keeps":"releases", w->w_number);
- if (!d)
- {
- w->w_wlockuser = NULL;
- return 0;
+ ASSERT(cvp);
+ *cvpp = cvp->c_lnext;
+
+ p = Layer2Window(l);
+ l = cv->c_layer;
+ cv->c_layer = 0;
+
+ if (p && cv == D_forecv)
+ {
+#ifdef MULTIUSER
+ ReleaseAutoWritelock(display, p);
+#endif
+ if (p->w_silence)
+ {
+ SetTimeout(&p->w_silenceev, p->w_silencewait * 1000);
+ evenq(&p->w_silenceev);
+ }
+ D_other = fore;
+ D_fore = 0;
+ }
+ if (l->l_cvlist == 0 && (p == 0 || l != p->w_savelayer))
+ KillLayerChain(l);
+ }
+
+ /* find right layer to display on canvas */
+ if (wi)
+ {
+ l = &wi->w_layer;
+ if (wi->w_savelayer && (wi->w_blocked || wi->w_savelayer->l_cvlist == 0))
+ l = wi->w_savelayer;
+ }
+ else
+ l = &cv->c_blank;
+
+ /* add our canvas to the layer's canvaslist */
+ cv->c_lnext = l->l_cvlist;
+ l->l_cvlist = cv;
+ cv->c_layer = l;
+ cv->c_xoff = cv->c_xs;
+ cv->c_yoff = cv->c_ys;
+ RethinkViewportOffsets(cv);
+
+ if (flayer == 0)
+ flayer = l;
+
+ if (wi && D_other == wi)
+ D_other = wi->w_next; /* Might be 0, but that's OK. */
+ if (cv == D_forecv)
+ {
+ D_fore = wi;
+ fore = D_fore; /* XXX ? */
+ if (wi)
+ {
+#ifdef MULTIUSER
+ ObtainAutoWritelock(display, wi);
+#endif
+ /*
+ * Place the window at the head of the most-recently-used list
+ */
+ for (pp = &windows; (p = *pp); pp = &p->w_next)
+ if (p == wi)
+ break;
+ ASSERT(p);
+ *pp = p->w_next;
+ p->w_next = windows;
+ windows = p;
}
}
- return 1;
}
+
+/*
+ * SetForeWindow changes the window in the input focus of the display.
+ * Puts window wi in canvas display->d_forecv.
+ */
void
SetForeWindow(wi)
struct win *wi;
{
- struct win *p, **pp;
- struct layer *l;
- /*
- * If we come from another window, make it inactive.
- */
- if (display)
+ struct win *p;
+ if (display == 0)
{
- fore = D_fore;
- if (fore)
- {
- ReleaseAutoWritelock(display, fore);
- /* deactivate old window. */
- if (fore->w_tstamp.seconds)
- fore->w_tstamp.lastio = Now;
- D_other = fore;
- fore->w_active = 0;
- fore->w_display = 0;
- }
- else
+ fore = wi;
+ return;
+ }
+ p = Layer2Window(D_forecv->c_layer);
+ SetCanvasWindow(D_forecv, wi);
+ if (p)
+ WindowChanged(p, 'u');
+ if (wi)
+ WindowChanged(wi, 'u');
+ flayer = D_forecv->c_layer;
+ /* Activate called afterwards, so no RefreshHStatus needed */
+}
+
+
+/*****************************************************************/
+
+/*
+ * Activate - make fore window active
+ * norefresh = -1 forces a refresh, disregard all_norefresh then.
+ */
+void
+Activate(norefresh)
+int norefresh;
+{
+ debug1("Activate(%d)\n", norefresh);
+ if (display == 0)
+ return;
+ if (D_status)
+ {
+ Msg(0, "%s", ""); /* wait till mintime (keep gcc quiet) */
+ RemoveStatus();
+ }
+
+ if (MayResizeLayer(D_forecv->c_layer))
+ ResizeLayer(D_forecv->c_layer, D_forecv->c_xe - D_forecv->c_xs + 1, D_forecv->c_ye - D_forecv->c_ys + 1, display);
+
+ fore = D_fore;
+ if (fore)
+ {
+ /* XXX ? */
+ if (fore->w_monitor != MON_OFF)
+ fore->w_monitor = MON_ON;
+ fore->w_bell = BELL_ON;
+
+#if 0
+ if (ResizeDisplay(fore->w_width, fore->w_height))
{
- /* put all the display layers on the window. */
- for (l = D_lay; l; l = l->l_next)
- if (l->l_next == &BlankLayer)
- {
- l->l_next = wi->w_lay;
- wi->w_lay = D_lay;
- for (l = D_lay; l != wi->w_lay; l = l->l_next)
- l->l_block |= wi->w_lay->l_block;
- break;
- }
+ debug2("Cannot resize from (%d,%d)", D_width, D_height);
+ debug2(" to (%d,%d) -> resize window\n", fore->w_width, fore->w_height);
+ DoResize(D_width, D_height);
}
- D_fore = wi;
- if (D_other == wi)
- D_other = 0;
- D_lay = wi->w_lay;
- D_layfn = D_lay->l_layfn;
- if ((wi->w_wlock == WLOCK_AUTO) &&
-#ifdef MULTIUSER
- !AclCheckPermWin(D_user, ACL_WRITE, wi) &&
#endif
- !wi->w_wlockuser)
- {
- debug2("%s obtained auto writelock for window %d\n",
- D_user->u_name, wi->w_number);
- wi->w_wlockuser = D_user;
- }
}
- fore = wi;
- fore->w_display = display;
- if (!fore->w_lay)
- fore->w_active = 1;
- /*
- * Place the window at the head of the most-recently-used list.
- */
- for (pp = &windows; (p = *pp); pp = &p->w_next)
- if (p == wi)
- break;
- ASSERT(p);
- *pp = p->w_next;
- p->w_next = windows;
- windows = p;
+ Redisplay(norefresh + all_norefresh);
}
+
static int
NextWindow()
{
@@ -3009,19 +3596,14 @@ PreviousWindow()
static int
MoreWindows()
{
- if (windows && windows->w_next)
+ if (windows && (fore == 0 || windows->w_next))
return 1;
if (fore == 0)
{
Msg(0, "No window available");
return 0;
}
-#ifdef NETHACK
- if (nethackflag)
- Msg(0, "You cannot escape from window %d!", fore->w_number);
- else
-#endif
- Msg(0, "No other window.");
+ Msg(0, "No other window.", fore->w_number); /* other arg for nethack */
return 0;
}
@@ -3030,42 +3612,46 @@ KillWindow(wi)
struct win *wi;
{
struct win **pp, *p;
+ struct canvas *cv;
+ int gotone;
- display = wi->w_display;
- if (display)
- {
- if (wi == D_fore)
- {
- RemoveStatus();
- if (D_lay != &wi->w_winlay)
- ExitOverlayPage();
- D_fore = 0;
- D_lay = &BlankLayer;
- D_layfn = BlankLayer.l_layfn;
- }
- }
-
+ /*
+ * Remove window from linked list.
+ */
for (pp = &windows; (p = *pp); pp = &p->w_next)
if (p == wi)
break;
ASSERT(p);
*pp = p->w_next;
- /*
- * Remove window from linked list.
- */
wi->w_inlen = 0;
wtab[wi->w_number] = 0;
- FreeWindow(wi);
+
+ if (windows == 0)
+ {
+ FreeWindow(wi);
+ Finit(0);
+ }
+
/*
- * If the foreground window disappeared check the head of the linked list
- * of windows for the most recently used window. If no window is alive at
- * all, exit.
+ * switch to different window on all canvases
*/
- if (display && D_fore)
- return;
- if (windows == 0)
- Finit(0);
- SwitchWindow(windows->w_number);
+ for (display = displays; display; display = display->d_next)
+ {
+ gotone = 0;
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ {
+ if (Layer2Window(cv->c_layer) != wi)
+ continue;
+ /* switch to other window */
+ SetCanvasWindow(cv, FindNiceWindow(D_other, 0));
+ gotone = 1;
+ }
+ if (gotone)
+ Activate(-1);
+ }
+ FreeWindow(wi);
+ WindowChanged((struct win *)0, 'w');
+ WindowChanged((struct win *)0, 'W');
}
static void
@@ -3074,62 +3660,53 @@ int on;
{
char buf[1024];
- if ((fore->w_logfp != 0) == on)
+ if ((fore->w_log != 0) == on)
{
if (display && !*rc_name)
Msg(0, "You are %s logging.", on ? "already" : "not");
return;
}
- strncpy(buf, MakeWinMsg(screenlogfile, fore, '%'), 1023);
- buf[1023] = 0;
- if (fore->w_logfp != NULL)
+ if (fore->w_log != 0)
{
-#ifdef NETHACK
- if (nethackflag)
- Msg(0, "You put away your scroll of logging named \"%s\".", buf);
- else
-#endif
- Msg(0, "Logfile \"%s\" closed.", buf);
- fclose(fore->w_logfp);
- fore->w_logfp = NULL;
+ Msg(0, "Logfile \"%s\" closed.", fore->w_log->name);
+ logfclose(fore->w_log);
+ fore->w_log = 0;
return;
}
- if ((fore->w_logfp = secfopen(buf, "a")) == NULL)
+ if (DoStartLog(fore, buf, sizeof(buf)))
{
-#ifdef NETHACK
- if (nethackflag)
- Msg(0, "You don't seem to have a scroll of logging named \"%s\".", buf);
- else
-#endif
Msg(errno, "Error opening logfile \"%s\"", buf);
return;
}
-#ifdef NETHACK
- if (nethackflag)
- Msg(0, "You %s your scroll of logging named \"%s\".",
- ftell(fore->w_logfp) ? "add to" : "start writing on", buf);
+ if (ftell(fore->w_log->fp) == 0)
+ Msg(0, "Creating logfile \"%s\".", fore->w_log->name);
else
-#endif
- Msg(0, "%s logfile \"%s\"", ftell(fore->w_logfp) ? "Appending to" : "Creating", buf);
+ Msg(0, "Appending to logfile \"%s\".", fore->w_log->name);
}
-void
-ShowWindows()
+char *
+AddWindows(buf, len, flags, where)
+char *buf;
+int len;
+int flags;
+int where;
{
- char buf[1024];
register char *s, *ss;
register struct win **pp, *p;
register char *cmd;
- ASSERT(display);
s = ss = buf;
for (pp = wtab; pp < wtab + MAXWIN; pp++)
{
+ if (pp - wtab == where && ss == buf)
+ ss = s;
if ((p = *pp) == 0)
continue;
+ if ((flags & 1) && display && p == D_fore)
+ continue;
cmd = p->w_title;
- if (s - buf + strlen(cmd) > sizeof(buf) - 24)
+ if (s - buf + strlen(cmd) > len - 24)
break;
if (s > buf)
{
@@ -3137,49 +3714,99 @@ ShowWindows()
*s++ = ' ';
}
sprintf(s, "%d", p->w_number);
+ if (p->w_number == where)
+ ss = s;
s += strlen(s);
- if (p == fore)
- {
- ss = s;
- *s++ = '*';
- }
- else if (p == D_other)
- *s++ = '-';
- if (p->w_display && p->w_display != display)
- *s++ = '&';
- if (p->w_monitor == MON_DONE || p->w_monitor == MON_MSG)
- *s++ = '@';
- if (p->w_bell == BELL_DONE || p->w_bell == BELL_MSG)
- *s++ = '!';
+
+ if (display && p == D_fore)
+ *s++ = '*';
+
+ if (!(flags & 2))
+ {
+ if (display && p == D_other)
+ *s++ = '-';
+ if (p->w_layer.l_cvlist && p->w_layer.l_cvlist->c_lnext)
+ *s++ = '&';
+ if (p->w_monitor == MON_DONE)
+ *s++ = '@';
+ if (p->w_bell == BELL_DONE)
+ *s++ = '!';
#ifdef UTMPOK
- if (p->w_slot != (slot_t) 0 && p->w_slot != (slot_t) -1)
- *s++ = '$';
+ if (p->w_slot != (slot_t) 0 && p->w_slot != (slot_t) -1)
+ *s++ = '$';
#endif
- if (p->w_logfp != NULL)
- {
- strcpy(s, "(L)");
- s += 3;
+ if (p->w_log != 0)
+ {
+ strcpy(s, "(L)");
+ s += 3;
+ }
+ if (p->w_ptyfd < 0)
+ *s++ = 'Z';
}
- if (p->w_ptyfd < 0)
- *s++ = 'Z';
*s++ = ' ';
strcpy(s, cmd);
s += strlen(s);
- if (p == fore)
+ }
+ *s = 0;
+ return ss;
+}
+
+char *
+AddOtherUsers(buf, len, p)
+char *buf;
+int len;
+struct win *p;
+{
+ struct display *d, *olddisplay = display;
+ struct canvas *cv;
+ char *s;
+ int l;
+
+ s = buf;
+ for (display = displays; display; display = display->d_next)
+ {
+ if (D_user == olddisplay->d_user)
+ continue;
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ if (Layer2Window(cv->c_layer) == p)
+ break;
+ if (!cv)
+ continue;
+ for (d = displays; d && d != display; d = d->d_next)
+ if (D_user == d->d_user)
+ break;
+ if (d && d != display)
+ continue;
+ if (len > 1 && s != buf)
{
- /*
- * this is usually done by Activate(), but when looking
- * on your current window, you may get annoyed, as there is still
- * that temporal '!' and '@' displayed.
- * So we remove that after displaying it once.
- */
- p->w_bell = BELL_OFF;
- if (p->w_monitor != MON_OFF)
- p->w_monitor = MON_ON;
+ *s++ = ',';
+ len--;
}
+ l = strlen(D_user->u_name);
+ if (l + 1 > len)
+ break;
+ strcpy(s, D_user->u_name);
+ s += l;
+ len -= l;
}
- *s++ = ' ';
- *s = '\0';
+ *s = 0;
+ display = olddisplay;
+ return buf;
+}
+
+void
+ShowWindows(where)
+int where;
+{
+ char buf[1024];
+ char *s, *ss;
+
+ if (!display)
+ return;
+ if (where == -1 && D_fore)
+ where = D_fore->w_number;
+ ss = AddWindows(buf, sizeof(buf), 0, where);
+ s = buf + strlen(buf);
if (ss - buf > D_width / 2)
{
ss -= D_width / 2;
@@ -3195,7 +3822,6 @@ ShowWindows()
Msg(0, "%s", ss);
}
-
static void
ShowTime()
{
@@ -3208,6 +3834,7 @@ ShowTime()
sprintf(buf, "%2d:%02d:%02d %s", tp->tm_hour, tp->tm_min, tp->tm_sec,
HostName);
#ifdef LOADAV
+ strcat(buf, " ");
AddLoadav(buf + strlen(buf));
#endif /* LOADAV */
Msg(0, "%s", buf);
@@ -3225,25 +3852,30 @@ ShowInfo()
Msg(0, "(%d,%d)/(%d,%d) no window", D_x + 1, D_y + 1, D_width, D_height);
return;
}
+ p = buf;
+ if (buf < (p += GetAnsiStatus(wp, p)))
+ *p++ = ' ';
+ sprintf(p, "(%d,%d)/(%d,%d)",
+ wp->w_x + 1, wp->w_y + 1, wp->w_width, wp->w_height);
#ifdef COPY_PASTE
- sprintf(buf, "(%d,%d)/(%d,%d)+%d %c%sflow %cins %corg %cwrap %capp %clog %cmon %cr",
-#else
- sprintf(buf, "(%d,%d)/(%d,%d) %c%sflow %cins %corg %cwrap %capp %clog %cmon %cr",
+ sprintf(p += strlen(p), "+%d", wp->w_histheight);
#endif
- wp->w_x + 1, wp->w_y + 1, wp->w_width, wp->w_height,
-#ifdef COPY_PASTE
- wp->w_histheight,
-#endif
- (wp->w_flow & FLOW_NOW) ? '+' : '-',
- (wp->w_flow & FLOW_AUTOFLAG) ? "" : ((wp->w_flow & FLOW_AUTO) ? "(+)" : "(-)"),
- wp->w_insert ? '+' : '-', wp->w_origin ? '+' : '-',
- wp->w_wrap ? '+' : '-', wp->w_keypad ? '+' : '-',
- (wp->w_logfp != NULL) ? '+' : '-',
- (wp->w_monitor != MON_OFF) ? '+' : '-',
- wp->w_norefresh ? '-' : '+');
+ sprintf(p += strlen(p), " %c%sflow %cwrap",
+ (wp->w_flow & FLOW_NOW) ? '+' : '-',
+ (wp->w_flow & FLOW_AUTOFLAG) ? "" :
+ ((wp->w_flow & FLOW_AUTO) ? "(+)" : "(-)"),
+ wp->w_wrap ? '+' : '-');
+ if (wp->w_insert) sprintf(p += strlen(p), " ins");
+ if (wp->w_origin) sprintf(p += strlen(p), " org");
+ if (wp->w_keypad) sprintf(p += strlen(p), " app");
+ if (wp->w_log) sprintf(p += strlen(p), " log");
+ if (wp->w_monitor != MON_OFF) sprintf(p += strlen(p), " mon");
+ if (wp->w_norefresh) sprintf(p += strlen(p), " nored");
+
+ p += strlen(p);
+#ifdef FONT
if (D_CC0 || (D_CS0 && *D_CS0))
{
- p = buf + strlen(buf);
if (wp->w_gr)
sprintf(p++, " G%c%c [", wp->w_Charset + '0', wp->w_CharsetR + '0');
else
@@ -3262,15 +3894,29 @@ ShowInfo()
}
}
*p++ = ']';
+ *p = 0;
#ifdef KANJI
strcpy(p, wp->w_kanji == EUC ? " euc" : wp->w_kanji == SJIS ? " sjis" : "");
p += strlen(p);
#endif
- *p = 0;
}
- Msg(0, "%s", buf);
-}
+#endif
+ if (wp->w_type == W_TYPE_PLAIN)
+ {
+ /* add info about modem control lines */
+ *p++ = ' ';
+ TtyGetModemStatus(wp->w_ptyfd, p);
+ }
+#ifdef BUILTIN_TELNET
+ else if (wp->w_type == W_TYPE_TELNET)
+ {
+ *p++ = ' ';
+ TelStatus(wp, p, sizeof(buf) - 1 - (p - buf));
+ }
+#endif
+ Msg(0, "%s %d(%s)", buf, wp->w_number, wp->w_title);
+}
static void
AKAfin(buf, len, data)
@@ -3309,6 +3955,12 @@ char *data; /* dummy */
if (!len || !display)
return;
+ if (len == 1 && *buf == '-')
+ {
+ SetForeWindow((struct win *)0);
+ Activate(0);
+ return;
+ }
if ((n = WindowByNoN(buf)) < 0)
return;
SwitchWindow(n);
@@ -3340,18 +3992,11 @@ char *buf;
int len;
char *data; /* dummy */
{
- struct action act;
- char *args[3];
-
if (!len || !display)
return;
- act.nr = RC_SETENV;
- args[0] = setenv_var;
- args[1] = buf;
- args[2] = NULL;
- act.args = args;
debug2("SetenvFin2: setenv '%s' '%s'\n", setenv_var, buf);
- DoAction(&act, -1);
+ xsetenv(setenv_var, buf);
+ MakeNewEnv();
}
static void
@@ -3384,10 +4029,8 @@ char *fn, **av;
struct NewWindow nwin;
register int num;
char buf[20];
- char termbuf[25];
nwin = nwin_undef;
- termbuf[0] = '\0';
while (av && *av && av[0][0] == '-')
{
if (av[0][1] == '-')
@@ -3416,8 +4059,7 @@ char *fn, **av;
break;
}
break;
- case 'k':
- case 't':
+ case 't': /* no more -k */
if (av[0][2])
nwin.aka = &av[0][2];
else if (*++av)
@@ -3465,6 +4107,9 @@ char *fn, **av;
case 'M':
nwin.monitor = MON_ON;
break;
+ case 'L':
+ nwin.Lflag = 1;
+ break;
default:
Msg(0, "%s: screen: invalid option -%c.", fn, av[0][1]);
break;
@@ -3545,13 +4190,14 @@ unsigned char *array;
* Asynchronous input functions
*/
-#if defined(POW_DETACH)
+#if defined(DETACH) && defined(POW_DETACH)
static void
pow_detach_fn(buf, len, data)
char *buf;
int len;
char *data; /* dummy */
{
+ debug("pow_detach_fn called\n");
if (len)
{
*buf = 0;
@@ -3561,10 +4207,7 @@ char *data; /* dummy */
{
if (display)
write(D_userfd, "\007", 1);
-#ifdef NETHACK
- if (nethackflag)
- Msg(0, "The blast of disintegration whizzes by you!");
-#endif
+ Msg(0, "Detach aborted.");
}
else
Detach(D_POWER);
@@ -3587,12 +4230,17 @@ char *data; /* dummy */
}
if (pp->buf)
free(pp->buf);
- if ((pp->buf = (char *)malloc(D_user->u_copylen)) == NULL)
+ pp->buf = 0;
+ pp->len = 0;
+ if (D_user->u_copylen)
{
- Msg(0, strnomem);
- return;
+ if ((pp->buf = (char *)malloc(D_user->u_copylen)) == NULL)
+ {
+ Msg(0, strnomem);
+ return;
+ }
+ bcopy(D_user->u_copybuffer, pp->buf, D_user->u_copylen);
}
- bcopy(D_user->u_copybuffer, pp->buf, D_user->u_copylen);
pp->len = D_user->u_copylen;
Msg(0, "Copied %d characters into register %c", D_user->u_copylen, *buf);
}
@@ -3617,18 +4265,9 @@ char *data; /* dummy */
}
if (pp->buf)
{
- if (fore->w_pastebuf)
- free(fore->w_pastebuf);
- fore->w_pastebuf = 0;
- fore->w_pasteptr = pp->buf;
- fore->w_pastelen = pp->len;
+ MakePaster(&fore->w_paster, pp->buf, pp->len, 0);
return;
}
-#ifdef NETHACK
- if (nethackflag)
- Msg(0, "Nothing happens.");
- else
-#endif
Msg(0, "Empty register.");
}
#endif /* COPY_PASTE */
@@ -3651,29 +4290,122 @@ char *data; /* dummy */
ProcessInput(pp->buf, pp->len);
return;
}
-#ifdef NETHACK
- if (nethackflag)
- Msg(0, "Nothing happens.");
- else
-#endif
Msg(0, "Empty register.");
}
+static void
+quit_fn(buf, len, data)
+char *buf;
+int len;
+char *data; /* dummy */
+{
+ if (len || (*buf != 'y' && *buf != 'Y'))
+ {
+ *buf = 0;
+ return;
+ }
+ Finit(0);
+}
+
+static void
+confirm_fn(buf, len, data)
+char *buf;
+int len;
+char *data; /* dummy */
+{
+ struct action act;
+
+ if (len || (*buf != 'y' && *buf != 'Y'))
+ {
+ *buf = 0;
+ return;
+ }
+ act.nr = (int)data;
+ act.args = noargs;
+ DoAction(&act, -1);
+}
+
+#ifdef MULTIUSER
+struct inputsu
+{
+ struct user **up;
+ char name[24];
+ char pw1[130]; /* FreeBSD crypts to 128 bytes */
+ char pw2[130];
+};
+
+static void
+su_fin(buf, len, data)
+char *buf;
+int len;
+char *data;
+{
+ struct inputsu *i = (struct inputsu *)data;
+ char *p;
+ int l;
+
+ if (!*i->name)
+ { p = i->name; l = sizeof(i->name) - 1; }
+ else if (!*i->pw1)
+ { strcpy(p = i->pw1, "\377"); l = sizeof(i->pw1) - 1; }
+ else
+ { strcpy(p = i->pw2, "\377"); l = sizeof(i->pw2) - 1; }
+ if (buf && len)
+ strncpy(p, buf, 1 + (l < len) ? l : len);
+ if (!*i->name)
+ Input("Screen User: ", sizeof(i->name) - 1, INP_COOKED, su_fin, (char *)i);
+ else if (!*i->pw1)
+ Input("User's UNIX Password: ", sizeof(i->pw1)-1, INP_COOKED|INP_NOECHO, su_fin, (char *)i);
+ else if (!*i->pw2)
+ Input("User's Screen Password: ", sizeof(i->pw2)-1, INP_COOKED|INP_NOECHO, su_fin, (char *)i);
+ else
+ {
+ if ((p = DoSu(i->up, i->name, i->pw2, i->pw1)))
+ Msg(0, "%s", p);
+ free((char *)i);
+ }
+}
+
+static int
+InputSu(w, up, name)
+struct win *w;
+struct user **up;
+char *name;
+{
+ struct inputsu *i;
+
+ if (!(i = (struct inputsu *)calloc(1, sizeof(struct inputsu))))
+ return -1;
+
+ i->up = up;
+ if (name && *name)
+ su_fin(name, (int)strlen(name), (char *)i); /* can also initialise stuff */
+ else
+ su_fin((char *)0, 0, (char *)i);
+ return 0;
+}
+#endif /* MULTIUSER */
#ifdef PASSWORD
-/* ARGSUSED */
static void
pass1(buf, len, data)
char *buf;
int len;
char *data;
{
- strncpy(Password, buf, sizeof(Password) - 1);
- Input("Retype new password:", sizeof(Password) - 1, INP_NOECHO, pass2, NULL);
+ struct user *u = (struct user *)data;
+
+ if (!*buf)
+ return;
+ ASSERT(u);
+ if (u->u_password != NullStr)
+ free((char *)u->u_password);
+ u->u_password = SaveStr(buf);
+ bzero(buf, strlen(buf));
+ Input("Retype new password:", 100, INP_NOECHO, pass2, data);
}
-/* ARGSUSED */
static void
pass2(buf, len, data)
char *buf;
@@ -3682,47 +4414,50 @@ char *data;
{
int st;
char salt[2];
+ struct user *u = (struct user *)data;
- if (buf == 0 || strcmp(Password, buf))
+ ASSERT(u);
+ if (!buf || strcmp(u->u_password, buf))
{
-#ifdef NETHACK
- if (nethackflag)
- Msg(0, "[ Passwords don't match - your armor crumbles away ]");
- else
-#endif /* NETHACK */
- Msg(0, "[ Passwords don't match - checking turned off ]");
- CheckPassword = 0;
+ Msg(0, "[ Passwords don't match - checking turned off ]");
+ if (u->u_password != NullStr)
+ {
+ bzero(u->u_password, strlen(u->u_password));
+ free((char *)u->u_password);
+ }
+ u->u_password = NullStr;
}
- if (Password[0] == '\0')
+ else if (u->u_password[0] == '\0')
{
Msg(0, "[ No password - no secure ]");
- CheckPassword = 0;
+ if (buf)
+ bzero(buf, strlen(buf));
}
- for (st = 0; st < 2; st++)
- salt[st] = 'A' + (int)((time(0) >> 6 * st) % 26);
- strncpy(Password, crypt(Password, salt), sizeof(Password) - 1);
- if (CheckPassword)
+
+ if (u->u_password != NullStr)
{
+ for (st = 0; st < 2; st++)
+ salt[st] = 'A' + (int)((time(0) >> 6 * st) % 26);
+ buf = crypt(u->u_password, salt);
+ bzero(u->u_password, strlen(u->u_password));
+ free((char *)u->u_password);
+ u->u_password = SaveStr(buf);
+ bzero(buf, strlen(buf));
#ifdef COPY_PASTE
- if (D_user->u_copybuffer)
- UserFreeCopyBuffer(D_user);
- D_user->u_copylen = strlen(Password);
- if ((D_user->u_copybuffer = (char *) malloc(D_user->u_copylen + 1)) == NULL)
+ if (u->u_copybuffer)
+ UserFreeCopyBuffer(u);
+ u->u_copylen = strlen(u->u_password);
+ if (!(u->u_copybuffer = SaveStr(u->u_password)))
{
Msg(0, strnomem);
D_user->u_copylen = 0;
}
else
- {
- strcpy(D_user->u_copybuffer, Password);
- Msg(0, "[ Password moved into copybuffer ]");
- }
+ Msg(0, "[ Password moved into copybuffer ]");
#else /* COPY_PASTE */
- Msg(0, "[ Crypted password is \"%s\" ]", Password);
+ Msg(0, "[ Crypted password is \"%s\" ]", u->u_password);
#endif /* COPY_PASTE */
}
- if (buf)
- bzero(buf, strlen(buf));
}
#endif /* PASSWORD */
@@ -3804,6 +4539,7 @@ int i;
else if (i >= T_KEYPAD - T_CAPS && i < T_OCAPS - T_CAPS && D_keypad)
i += T_OCAPS - T_CURSOR;
debug1(" - action %d\n", i);
+ flayer = D_forecv->c_layer;
fore = D_fore;
act = 0;
#ifdef COPY_PASTE
@@ -3822,3 +4558,134 @@ int i;
}
#endif
+
+static int
+IsOnDisplay(wi)
+struct win *wi;
+{
+ struct canvas *cv;
+ ASSERT(display);
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ if (Layer2Window(cv->c_layer) == wi)
+ return 1;
+ return 0;
+}
+
+struct win *
+FindNiceWindow(wi, presel)
+struct win *wi;
+char *presel;
+{
+ int i;
+
+ debug2("FindNiceWindow %d %s\n", wi ? wi->w_number : -1 , presel ? presel : "NULL");
+ ASSERT(display);
+ if (presel)
+ {
+ i = WindowByNoN(presel);
+ if (i >= 0)
+ wi = wtab[i];
+ }
+#ifdef MULTIUSER
+ if (wi && AclCheckPermWin(D_user, ACL_READ, wi))
+ wi = 0;
+#endif
+ if (!wi || (IsOnDisplay(wi) && !presel))
+ {
+ /* try to get another window */
+ wi = 0;
+#ifdef MULTIUSER
+ for (wi = windows; wi; wi = wi->w_next)
+ if (!wi->w_layer.l_cvlist && !AclCheckPermWin(D_user, ACL_WRITE, wi))
+ break;
+ if (!wi)
+ for (wi = windows; wi; wi = wi->w_next)
+ if (wi->w_layer.l_cvlist && !IsOnDisplay(wi) && !AclCheckPermWin(D_user, ACL_WRITE, wi))
+ break;
+ if (!wi)
+ for (wi = windows; wi; wi = wi->w_next)
+ if (!wi->w_layer.l_cvlist && !AclCheckPermWin(D_user, ACL_READ, wi))
+ break;
+ if (!wi)
+ for (wi = windows; wi; wi = wi->w_next)
+ if (wi->w_layer.l_cvlist && !IsOnDisplay(wi) && !AclCheckPermWin(D_user, ACL_READ, wi))
+ break;
+#endif
+ if (!wi)
+ for (wi = windows; wi; wi = wi->w_next)
+ if (!wi->w_layer.l_cvlist)
+ break;
+ if (!wi)
+ for (wi = windows; wi; wi = wi->w_next)
+ if (wi->w_layer.l_cvlist && !IsOnDisplay(wi))
+ break;
+ }
+#ifdef MULTIUSER
+ if (wi && AclCheckPermWin(D_user, ACL_READ, wi))
+ wi = 0;
+#endif
+ return wi;
+}
+
+#if 0
+
+/* sorted list of all commands */
+static struct comm **commtab;
+static int ncommtab;
+
+void
+AddComms(cos, hand)
+struct comm *cos;
+void (*hand) __P((struct comm *, char **, int));
+{
+ int n, i, j, r;
+ for (n = 0; cos[n].name; n++)
+ ;
+ if (n == 0)
+ return;
+ if (commtab)
+ commtab = (struct commt *)realloc(commtab, sizeof(*commtab) * (ncommtab + n));
+ else
+ commtab = (struct commt *)malloc(sizeof(*commtab) * (ncommtab + n));
+ if (!commtab)
+ Panic(0, strnomem);
+ for (i = 0; i < n; i++)
+ {
+ for (j = 0; j < ncommtab; j++)
+ {
+ r = strcmp(cos[i].name, commtab[j]->name);
+ if (r == 0)
+ Panic(0, "Duplicate command: %s\n", cos[i].name);
+ if (r < 0)
+ break;
+ }
+ for (r = ncommtab; r > j; r--)
+ commtab[r] = commtab[r - 1];
+ commtab[j] = cos + i;
+ cos[i].handler = hand;
+ bzero(cos[i].userbits, sizeof(cos[i].userbits));
+ ncommtab++;
+ }
+}
+
+struct comm *
+FindComm(str)
+char *str;
+{
+ int x, m, l = 0, r = ncommtab - 1;
+ while (l <= r)
+ {
+ m = (l + r) / 2;
+ x = strcmp(str, commtab[m]->name);
+ if (x > 0)
+ l = m + 1;
+ else if (x < 0)
+ r = m - 1;
+ else
+ return commtab[m];
+ }
+ return 0;
+}
+
+#endif
+
diff --git a/pty.c b/pty.c
index b2d43a5..69d4355 100644
--- a/pty.c
+++ b/pty.c
@@ -33,11 +33,16 @@ RCS_ID("$Id: pty.c,v 1.6 1994/05/31 12:32:44 mlschroe Exp $ FAU")
#include "screen.h"
#ifndef sun
-#include <sys/ioctl.h>
+# include <sys/ioctl.h>
+#endif
+
+/* for solaris 2.1, Unixware (SVR4.2) and possibly others */
+#ifdef HAVE_SVR4_PTYS
+# include <sys/stropts.h>
#endif
#if defined(sun) && defined(LOCKPTY) && !defined(TIOCEXCL)
-#include <sys/ttold.h>
+# include <sys/ttold.h>
#endif
#ifdef ISC
@@ -62,22 +67,32 @@ RCS_ID("$Id: pty.c,v 1.6 1994/05/31 12:32:44 mlschroe Exp $ FAU")
# define PTYRANGE1 "0123456789abcdef"
#endif
+/* SVR4 pseudo ttys don't seem to work with SCO-5 */
+#ifdef M_UNIX
+# undef HAVE_SVR4_PTYS
+#endif
+
extern int eff_uid;
/* used for opening a new pty-pair: */
static char PtyName[32], TtyName[32];
-#if !(defined(sequent) || defined(_SEQUENT_) || defined(SVR4))
+#if !(defined(sequent) || defined(_SEQUENT_) || defined(HAVE_SVR4_PTYS))
# ifdef hpux
static char PtyProto[] = "/dev/ptym/ptyXY";
static char TtyProto[] = "/dev/pty/ttyXY";
# else
+# ifdef M_UNIX
+static char PtyProto[] = "/dev/ptypXY";
+static char TtyProto[] = "/dev/ttypXY";
+# else
static char PtyProto[] = "/dev/ptyXY";
static char TtyProto[] = "/dev/ttyXY";
+# endif
# endif /* hpux */
#endif
-static void initpty __P((int));
+static void initmaster __P((int));
/*
* Open all ptys with O_NOCTTY, just to be on the safe side
@@ -90,7 +105,7 @@ static void initpty __P((int));
/***************************************************************/
static void
-initpty(f)
+initmaster(f)
int f;
{
#ifdef POSIX
@@ -105,6 +120,24 @@ int f;
#endif
}
+void
+InitPty(f)
+int f;
+{
+ if (f < 0)
+ return;
+#if defined(I_PUSH) && defined(HAVE_SVR4_PTYS) && !defined(sgi) && !defined(linux) && !defined(__osf__) && !defined(M_UNIX)
+ if (ioctl(f, I_PUSH, "ptem"))
+ Panic(errno, "InitPty: cannot I_PUSH ptem");
+ if (ioctl(f, I_PUSH, "ldterm"))
+ Panic(errno, "InitPty: cannot I_PUSH ldterm");
+# ifdef sun
+ if (ioctl(f, I_PUSH, "ttcompat"))
+ Panic(errno, "InitPty: cannot I_PUSH ttcompat");
+# endif
+#endif
+}
+
/***************************************************************/
#if defined(OSX) && !defined(PTY_DONE)
@@ -116,7 +149,7 @@ char **ttyn;
register int f;
if ((f = open_controlling_pty(TtyName)) < 0)
return -1;
- initpty(f);
+ initmaster(f);
*ttyn = TtyName;
return f;
#endif
@@ -139,7 +172,7 @@ char **ttyn;
#endif
strncpy(PtyName, m, sizeof(PtyName));
strncpy(TtyName, s, sizeof(TtyName));
- initpty(f);
+ initmaster(f);
*ttyn = TtyName;
return f;
}
@@ -154,7 +187,7 @@ OpenPTY(ttyn)
char **ttyn;
{
int f;
- char *name;
+ char *name, *_getpty();
sigret_t (*sigcld)__P(SIGPROTOARG);
/*
@@ -167,7 +200,7 @@ char **ttyn;
if (name == 0)
return -1;
- initpty(f);
+ initmaster(f);
*ttyn = name;
return f;
}
@@ -193,7 +226,7 @@ char **ttyn;
return -1;
}
sprintf(TtyName, "/dev/ttyq%d", minor(buf.st_rdev));
- initpty(f);
+ initmaster(f);
*ttyn = TtyName;
return f;
}
@@ -201,7 +234,7 @@ char **ttyn;
/***************************************************************/
-#if defined(SVR4) && !defined(PTY_DONE)
+#if defined(HAVE_SVR4_PTYS) && !defined(PTY_DONE)
#define PTY_DONE
int
OpenPTY(ttyn)
@@ -229,7 +262,7 @@ char **ttyn;
}
signal(SIGCHLD, sigcld);
strncpy(TtyName, m, sizeof(TtyName));
- initpty(f);
+ initmaster(f);
*ttyn = TtyName;
return f;
}
@@ -260,7 +293,7 @@ char **ttyn;
close(f);
return -1;
}
- initpty(f);
+ initmaster(f);
# ifdef _IBMR2
if (aixhack >= 0)
close(aixhack);
@@ -321,7 +354,7 @@ char **ttyn;
}
}
#endif
- initpty(f);
+ initmaster(f);
*ttyn = TtyName;
return f;
}
@@ -329,3 +362,4 @@ char **ttyn;
return -1;
}
#endif
+
diff --git a/resize.c b/resize.c
index 9a21c81..2357643 100644
--- a/resize.c
+++ b/resize.c
@@ -44,16 +44,16 @@ static void CheckMaxSize __P((int));
static void FreeMline __P((struct mline *));
static int AllocMline __P((struct mline *ml, int));
static void MakeBlankLine __P((char *, int));
+static void kaablamm __P((void));
+static int BcopyMline __P((struct mline *, int, struct mline *, int, int, int));
+extern struct layer *flayer;
extern struct display *display, *displays;
extern char *blank, *null;
extern struct mline mline_blank, mline_null, mline_old;
extern struct win *windows;
extern int Z0width, Z1width;
-
-#ifdef NETHACK
-extern int nethackflag;
-#endif
+extern int captionalways;
#if defined(TIOCGWINSZ) || defined(TIOCSWINSZ)
struct winsize glwz;
@@ -61,8 +61,10 @@ extern int nethackflag;
static struct mline mline_zero = {
(char *)0,
- (char *)0,
(char *)0
+#ifdef FONT
+ ,(char *)0
+#endif
#ifdef COLOR
,(char *)0
#endif
@@ -82,15 +84,12 @@ CheckScreenSize(change_flag)
int change_flag;
{
int wi, he;
- struct win *p;
- struct layer *oldlay;
if (display == 0)
{
debug("CheckScreenSize: No display -> no check.\n");
return;
}
- oldlay = D_lay;
#ifdef TIOCGWINSZ
if (ioctl(D_userfd, TIOCGWINSZ, (char *)&glwz) != 0)
{
@@ -114,6 +113,7 @@ int change_flag;
debug2("CheckScreenSize: screen is (%d,%d)\n", wi, he);
+#if 0 /* XXX: Fixme */
if (change_flag == 2)
{
debug("Trying to adapt all windows (-A)\n");
@@ -121,6 +121,7 @@ int change_flag;
if (p->w_display == 0 || p->w_display == display)
ChangeWindowSize(p, wi, he, p->w_histheight);
}
+#endif
if (D_width == wi && D_height == he)
{
debug("CheckScreenSize: No change -> return.\n");
@@ -128,16 +129,7 @@ int change_flag;
}
ChangeScreenSize(wi, he, change_flag);
if (change_flag == 1)
- Activate(D_fore ? D_fore->w_norefresh : 0);
- if (D_lay != oldlay)
- {
-#ifdef NETHACK
- if (nethackflag)
- Msg(0, "KAABLAMM!!! You triggered a land mine!");
- else
-#endif
- Msg(0, "Aborted because of window size change.");
- }
+ Redisplay(D_fore ? D_fore->w_norefresh : 0);
}
void
@@ -146,15 +138,60 @@ int wi, he;
int change_fore;
{
struct win *p;
+ struct canvas *cv, **cvpp;
int wwi;
+ int y, h, hn;
- if (D_width == wi && D_height == he)
- {
- debug("ChangeScreenSize: no change\n");
- return;
- }
debug2("ChangeScreenSize from (%d,%d) ", D_width, D_height);
debug3("to (%d,%d) (change_fore: %d)\n",wi, he, change_fore);
+
+ /*
+ * STRATEGY: keep the ratios.
+ * if canvas doesn't fit anymore, throw it off.
+ * (ATTENTION: cvlist must be sorted!)
+ */
+ y = 0;
+ h = he;
+ if (D_has_hstatus == HSTATUS_LASTLINE)
+ h--;
+ for (cvpp = &D_cvlist; (cv = *cvpp); )
+ {
+ if (h < 2)
+ {
+ /* kill canvas */
+ SetCanvasWindow(cv, 0);
+ *cvpp = cv->c_next;
+ free(cv);
+ if (D_forecv == cv)
+ D_forecv = 0;
+ continue;
+ }
+ hn = (cv->c_ye - cv->c_ys + 1) * he / D_height;
+ if (hn == 0)
+ hn = 1;
+ if (hn + 2 >= h || cv->c_next == 0)
+ hn = h - 1;
+ if (!captionalways && cv == D_cvlist && h - hn < 2)
+ hn = h;
+ ASSERT(hn > 0);
+ cv->c_xs = 0;
+ cv->c_xe = wi - 1;
+ cv->c_ys = y;
+ cv->c_ye = y + hn - 1;
+
+ cv->c_xoff = cv->c_xs;
+ cv->c_yoff = cv->c_ys;
+
+ y += hn + 1;
+ h -= hn + 1;
+ cvpp = &cv->c_next;
+ }
+ RethinkDisplayViewports();
+ if (D_forecv == 0)
+ D_forecv = D_cvlist;
+ if (D_forecv)
+ D_fore = Layer2Window(D_forecv->c_layer);
+
D_width = wi;
D_height = he;
@@ -175,7 +212,7 @@ int change_fore;
}
debug2("Default size: (%d,%d)\n", D_defwidth, D_defheight);
if (change_fore)
- DoResize(wi, he);
+ ResizeLayersToCanvases();
if (D_CWS == NULL && displays->d_next == 0)
{
/* adapt all windows - to be removed ? */
@@ -183,40 +220,179 @@ int change_fore;
{
debug1("Trying to change window %d.\n", p->w_number);
wwi = wi;
- if (D_CZ0 && (wi == Z0width || wi == Z1width))
+#if 0
+ if (D_CZ0 && p->w_width != wi && (wi == Z0width || wi == Z1width))
{
if (p->w_width > (Z0width + Z1width) / 2)
wwi = Z0width;
else
wwi = Z1width;
}
+#endif
+ if (p->w_savelayer && p->w_savelayer->l_cvlist == 0)
+ ResizeLayer(p->w_savelayer, wwi, he, 0);
+#if 0
ChangeWindowSize(p, wwi, he, p->w_histheight);
+#endif
}
}
}
void
-DoResize(wi, he)
-int wi, he;
+ResizeLayersToCanvases()
{
- struct layer *oldlay;
- int q = 0;
+ struct canvas *cv;
+ struct layer *l;
+ int lx, ly;
- for(;;)
+ debug("ResizeLayersToCanvases\n");
+ for (cv = D_cvlist; cv; cv = cv->c_next)
{
- oldlay = D_lay;
- for (; D_lay; D_lay = D_lay->l_next)
+ l = cv->c_layer;
+ if (l == 0)
+ continue;
+ debug("Doing canvas: ");
+ if (l->l_width == cv->c_xe - cv->c_xs + 1 &&
+ l->l_height == cv->c_ye - cv->c_ys + 1)
+ {
+ debug("already fitting.\n");
+ continue;
+ }
+ if (!MayResizeLayer(l))
+ {
+ debug("may not resize.\n");
+ }
+ else
{
- D_layfn = D_lay->l_layfn;
- if ((q = Resize(wi, he)))
- break;
+ debug("doing resize.\n");
+ ResizeLayer(l, cv->c_xe - cv->c_xs + 1, cv->c_ye - cv->c_ys + 1, display);
+ }
+
+ /* normalize window, see screen.c */
+ lx = cv->c_layer->l_x;
+ ly = cv->c_layer->l_y;
+ if (ly + cv->c_yoff < cv->c_ys)
+ {
+ cv->c_yoff = cv->c_ys - ly;
+ RethinkViewportOffsets(cv);
+ }
+ else if (ly + cv->c_yoff > cv->c_ye)
+ {
+ cv->c_yoff = cv->c_ye - ly;
+ RethinkViewportOffsets(cv);
+ }
+ if (lx + cv->c_xoff < cv->c_xs)
+ {
+ int n = cv->c_xs - (lx + cv->c_xoff);
+ if (n < (cv->c_xe - cv->c_xs + 1) / 2)
+ n = (cv->c_xe - cv->c_xs + 1) / 2;
+ if (cv->c_xoff + n > cv->c_xs)
+ n = cv->c_xs - cv->c_xoff;
+ cv->c_xoff += n;
+ RethinkViewportOffsets(cv);
+ }
+ else if (lx + cv->c_xoff > cv->c_xe)
+ {
+ int n = lx + cv->c_xoff - cv->c_xe;
+ if (n < (cv->c_xe - cv->c_xs + 1) / 2)
+ n = (cv->c_xe - cv->c_xs + 1) / 2;
+ if (cv->c_xoff - n + cv->c_layer->l_width - 1 < cv->c_xe)
+ n = cv->c_xoff + cv->c_layer->l_width - 1 - cv->c_xe;
+ cv->c_xoff -= n;
+ RethinkViewportOffsets(cv);
}
- D_lay = oldlay;
- D_layfn = D_lay->l_layfn;
- if (q == 0)
- break;
- ExitOverlayPage();
}
+ Redisplay(0);
+}
+
+int
+MayResizeLayer(l)
+struct layer *l;
+{
+ int cvs = 0;
+ debug("MayResizeLayer:\n");
+ for (; l; l = l->l_next)
+ {
+ if (l->l_cvlist)
+ if (++cvs > 1 || l->l_cvlist->c_lnext)
+ {
+ debug1("may not - cvs %d\n", cvs);
+ return 0;
+ }
+ }
+ debug("may resize\n");
+ return 1;
+}
+
+/*
+ * Easy implementation: rely on the fact that the only layers
+ * supporting resize are Win and Blank. So just kill all overlays.
+ *
+ * This is a lot harder if done the right way...
+ */
+
+static void
+kaablamm()
+{
+ /* this only works because of the status_delayed hack... */
+ Msg(0, "Aborted because of window size change.");
+}
+
+void
+ResizeLayer(l, wi, he, norefdisp)
+struct layer *l;
+int wi, he;
+struct display *norefdisp;
+{
+ struct win *p;
+ struct canvas *cv;
+ struct layer *oldflayer = flayer;
+ struct display *d, *olddisplay = display;
+
+ if (l->l_width == wi && l->l_height == he)
+ return;
+ p = Layer2Window(l);
+
+ if (oldflayer && (l == oldflayer || Layer2Window(oldflayer) == p))
+ while(oldflayer->l_next)
+ oldflayer = oldflayer->l_next;
+
+ if (p)
+ {
+ for (d = displays; d; d = d->d_next)
+ for (cv = d->d_cvlist; cv; cv = cv->c_next)
+ {
+ if (p == Layer2Window(cv->c_layer))
+ {
+ flayer = cv->c_layer;
+ if (flayer->l_next)
+ kaablamm();
+ while(flayer->l_next)
+ ExitOverlayPage();
+ }
+ }
+ l = p->w_savelayer;
+ }
+ flayer = l;
+ if (flayer->l_next)
+ kaablamm();
+ while(flayer->l_next)
+ ExitOverlayPage();
+ if (p)
+ flayer = &p->w_layer;
+ Resize(wi, he);
+ /* now everybody is on flayer, redisplay */
+ l = flayer;
+ for (display = displays; display; display = display->d_next)
+ {
+ if (display == norefdisp)
+ continue;
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ if (cv->c_layer == l)
+ RefreshArea(cv->c_xs, cv->c_ys, cv->c_xe, cv->c_ye, 0);
+ }
+ flayer = oldflayer;
+ display = olddisplay;
}
@@ -228,8 +404,10 @@ struct mline *ml;
free(ml->image);
if (ml->attr && ml->attr != null)
free(ml->attr);
+#ifdef FONT
if (ml->font && ml->font != null)
free(ml->font);
+#endif
#ifdef COLOR
if (ml->color && ml->color != null)
free(ml->color);
@@ -244,7 +422,9 @@ int w;
{
ml->image = malloc(w);
ml->attr = null;
+#ifdef FONT
ml->font = null;
+#endif
#ifdef COLOR
ml->color = null;
#endif
@@ -270,6 +450,7 @@ int xf, xt, l, w;
}
if (mlt->attr != null)
bcopy(mlf->attr + xf, mlt->attr + xt, l);
+#ifdef FONT
if (mlf->font != null && mlt->font == null)
{
if ((mlt->font = malloc(w)) == 0)
@@ -278,6 +459,7 @@ int xf, xt, l, w;
}
if (mlt->font != null)
bcopy(mlf->font + xf, mlt->font + xt, l);
+#endif
#ifdef COLOR
if (mlf->color != null && mlt->color == null)
{
@@ -324,38 +506,32 @@ int wi;
mline_old.attr = malloc((unsigned) maxwidth);
else
mline_old.attr = xrealloc(mline_old.attr, maxwidth);
+#ifdef FONT
if (mline_old.font == 0)
mline_old.font = malloc((unsigned) maxwidth);
else
mline_old.font = xrealloc(mline_old.font, maxwidth);
+#endif
#ifdef COLOR
if (mline_old.color == 0)
mline_old.color = malloc((unsigned) maxwidth);
else
mline_old.color = xrealloc(mline_old.color, maxwidth);
- if (!(blank && null && mline_old.image && mline_old.attr
- && mline_old.font && mline_old.color))
- {
- Panic(0, "Out of memory -> Game over!!");
- /*NOTREACHED*/
- }
-#else
- if (!(blank && null && mline_old.image && mline_old.attr
- && mline_old.font))
- {
- Panic(0, "Out of memory -> Game over!!");
- /*NOTREACHED*/
- }
#endif
+ if (!(blank && null && mline_old.image && mline_old.attr IFFONT(&& mline_old.font) IFCOLOR(&& mline_old.color)))
+ Panic(0, strnomem);
+
MakeBlankLine(blank, maxwidth);
bzero(null, maxwidth);
mline_blank.image = blank;
mline_blank.attr = null;
- mline_blank.font = null;
mline_null.image = null;
mline_null.attr = null;
+#ifdef FONT
+ mline_blank.font = null;
mline_null.font = null;
+#endif
#ifdef COLOR
mline_blank.color = null;
mline_null.color = null;
@@ -371,8 +547,10 @@ int wi;
{
if (ml->attr == oldnull)
ml->attr = null;
+#ifdef FONT
if (ml->font == oldnull)
ml->font = null;
+#endif
#ifdef COLOR
if (ml->color== oldnull)
ml->color= null;
@@ -384,8 +562,10 @@ int wi;
{
if (ml->attr == oldnull)
ml->attr = null;
+# ifdef FONT
if (ml->font == oldnull)
ml->font = null;
+# endif
# ifdef COLOR
if (ml->color== oldnull)
ml->color= null;
@@ -445,6 +625,7 @@ int wi, he, hi;
struct mline *mlf = 0, *mlt = 0, *ml, *nmlines, *nhlines;
int fy, ty, l, lx, lf, lt, yy, oty, addone;
int ncx, ncy, naka, t;
+ int y, shift;
if (wi == 0)
he = hi = 0;
@@ -457,12 +638,15 @@ int wi, he, hi;
CheckMaxSize(wi);
+ /* XXX */
+#if 0
/* just in case ... */
if (wi && (p->w_width != wi || p->w_height != he) && p->w_lay != &p->w_winlay)
{
debug("ChangeWindowSize: No resize because of overlay?\n");
return -1;
}
+#endif
debug("ChangeWindowSize");
debug3(" from (%d,%d)+%d", p->w_width, p->w_height, p->w_histheight);
@@ -519,6 +703,38 @@ int wi, he, hi;
p->w_x--;
}
+ /* handle the cursor and autoaka lines now if the widths are equal */
+ if (p->w_width == wi)
+ {
+ ncx = p->w_x + addone;
+ ncy = p->w_y + he - p->w_height;
+ /* never lose sight of the line with the cursor on it */
+ shift = -ncy;
+ for (yy = p->w_y + p->w_histheight - 1; yy >= 0 && ncy + shift < he; yy--)
+ {
+ ml = OLDWIN(yy);
+ if (ml->image[p->w_width] == ' ')
+ break;
+ shift++;
+ }
+ if (shift < 0)
+ shift = 0;
+ else
+ debug1("resize: cursor out of bounds, shifting %d\n", shift);
+ ncy += shift;
+ if (p->w_autoaka > 0)
+ {
+ naka = p->w_autoaka + he - p->w_height + shift;
+ if (naka < 1 || naka > he)
+ naka = 0;
+ }
+ while (shift-- > 0)
+ {
+ ml = OLDWIN(fy);
+ FreeMline(ml);
+ fy--;
+ }
+ }
debug2("fy %d ty %d\n", fy, ty);
if (fy >= 0)
mlf = OLDWIN(fy);
@@ -532,13 +748,6 @@ int wi, he, hi;
/* here is a simple shortcut: just copy over */
*mlt = *mlf;
*mlf = mline_zero;
- if (fy == p->w_y + p->w_histheight)
- {
- ncx = p->w_x + addone;
- ncy = ty - hi >= 0 ? ty - hi : 0;
- }
- if (p->w_autoaka > 0 && fy == p->w_autoaka - 1 + p->w_histheight)
- naka = ty - hi >= 0 ? 1 + ty - hi : 0;
if (--fy >= 0)
mlf = OLDWIN(fy);
if (--ty >= 0)
@@ -584,7 +793,30 @@ int wi, he, hi;
if (fy == p->w_y + p->w_histheight && lf - lx <= p->w_x && lf > p->w_x)
{
ncx = p->w_x + lt - lf + addone;
- ncy = ty - hi >= 0 ? ty - hi : 0;
+ ncy = ty - hi;
+ shift = wi ? -ncy + (l - lx) / wi : 0;
+ if (ty + shift > hi + he - 1)
+ shift = hi + he - 1 - ty;
+ if (shift > 0)
+ {
+ debug3("resize: cursor out of bounds, shifting %d [%d/%d]\n", shift, lt - lx, wi);
+ for (y = hi + he - 1; y >= ty; y--)
+ {
+ mlt = NEWWIN(y);
+ FreeMline(mlt);
+ if (y - shift < ty)
+ continue;
+ ml = NEWWIN(y - shift);
+ *mlt = *ml;
+ *ml = mline_zero;
+ }
+ ncy += shift;
+ ty += shift;
+ mlt = NEWWIN(ty);
+ if (naka > 0)
+ naka = naka + shift > he ? 0 : naka + shift;
+ }
+ ASSERT(ncy >= 0);
}
/* did we copy autoaka line ? */
if (p->w_autoaka > 0 && fy == p->w_autoaka - 1 + p->w_histheight && lf - lx <= 0)
@@ -652,7 +884,7 @@ int wi, he, hi;
{
/* tabs get wi+1 because 0 <= x <= wi */
p->w_tabs = malloc((unsigned) wi + 1);
- t = 8;
+ t = 0;
}
else
{
@@ -680,8 +912,9 @@ int wi, he, hi;
Msg(0, strnomem);
return -1;
}
- for (t = (t + 7) & 8; t < wi; t += 8)
- p->w_tabs[t] = 1;
+ for (; t < wi; t++)
+ p->w_tabs[t] = t && !(t & 7) ? 1 : 0;
+ p->w_tabs[wi] = 0;
}
else
{
@@ -735,6 +968,11 @@ int wi, he, hi;
p->w_histheight = hi;
#endif
+#ifdef BUILTIN_TELNET
+ if (p->w_type == W_TYPE_TELNET)
+ TelWindowSize(p);
+#endif
+
#ifdef DEBUG
/* Test if everything was ok */
for (fy = 0; fy < p->w_height + p->w_histheight; fy++)
diff --git a/sched.c b/sched.c
new file mode 100644
index 0000000..c45f08e
--- /dev/null
+++ b/sched.c
@@ -0,0 +1,263 @@
+#include <sys/types.h>
+#if !defined(sun) && !defined(B43) && !defined(ISC) && !defined(pyr) && !defined(_CX_UX)
+# include <time.h>
+#endif
+#include <sys/time.h>
+
+#include "config.h"
+#include "screen.h"
+#include "extern.h"
+
+static struct event *evs;
+static struct event *tevs;
+static struct event *nextev;
+static int calctimeout;
+
+static struct event *calctimo __P((void));
+#if (defined(sgi) && defined(SVR4)) || defined(__osf__)
+static int sgihack __P((void));
+#endif
+
+void
+evenq(ev)
+struct event *ev;
+{
+ struct event *evp, **evpp;
+ debug3("New event fd %d type %d queued %d\n", ev->fd, ev->type, ev->queued);
+ if (ev->queued)
+ return;
+ evpp = &evs;
+ if (ev->type == EV_TIMEOUT)
+ {
+ calctimeout = 1;
+ evpp = &tevs;
+ }
+ for (; (evp = *evpp); evpp = &evp->next)
+ if (ev->pri > evp->pri)
+ break;
+ ev->next = evp;
+ *evpp = ev;
+ ev->queued = 1;
+}
+
+void
+evdeq(ev)
+struct event *ev;
+{
+ struct event *evp, **evpp;
+ debug3("Deq event fd %d type %d queued %d\n", ev->fd, ev->type, ev->queued);
+ if (!ev->queued)
+ return;
+ evpp = &evs;
+ if (ev->type == EV_TIMEOUT)
+ {
+ calctimeout = 1;
+ evpp = &tevs;
+ }
+ for (; (evp = *evpp); evpp = &evp->next)
+ if (evp == ev)
+ break;
+ ASSERT(evp);
+ *evpp = ev->next;
+ ev->queued = 0;
+ if (ev == nextev)
+ nextev = nextev->next;
+}
+
+static struct event *
+calctimo()
+{
+ struct event *ev, *min;
+ long mins;
+
+ if ((min = tevs) == 0)
+ return 0;
+ mins = min->timeout.tv_sec;
+ for (ev = tevs->next; ev; ev = ev->next)
+ {
+ ASSERT(ev->type == EV_TIMEOUT);
+ if (mins < ev->timeout.tv_sec)
+ continue;
+ if (mins > ev->timeout.tv_sec || min->timeout.tv_usec > ev->timeout.tv_usec)
+ {
+ min = ev;
+ mins = ev->timeout.tv_sec;
+ }
+ }
+ return min;
+}
+
+void
+sched()
+{
+ struct event *ev;
+ fd_set r, w, *set;
+ struct event *timeoutev = 0;
+ struct timeval timeout;
+ int nsel;
+
+ for (;;)
+ {
+ if (calctimeout)
+ timeoutev = calctimo();
+ if (timeoutev)
+ {
+ gettimeofday(&timeout, NULL);
+ /* tp - timeout */
+ timeout.tv_sec = timeoutev->timeout.tv_sec - timeout.tv_sec;
+ timeout.tv_usec = timeoutev->timeout.tv_usec - timeout.tv_usec;
+ if (timeout.tv_usec < 0)
+ {
+ timeout.tv_usec += 1000000;
+ timeout.tv_sec--;
+ }
+ if (timeout.tv_sec < 0)
+ {
+ timeout.tv_usec = 0;
+ timeout.tv_sec = 0;
+ }
+ }
+#ifdef DEBUG
+ debug("waiting for events");
+ if (timeoutev)
+ debug2(" timeout %d secs %d usecs", timeout.tv_sec, timeout.tv_usec);
+ debug(":\n");
+ for (ev = evs; ev; ev = ev->next)
+ debug3(" - fd %d type %d pri %d\n", ev->fd, ev->type, ev->pri);
+ if (tevs)
+ debug("timed events:\n");
+ for (ev = tevs; ev; ev = ev->next)
+ debug3(" - pri %d sec %d usec %d\n", ev->pri, ev->timeout.tv_sec, ev->timeout.tv_usec);
+#endif
+
+ FD_ZERO(&r);
+ FD_ZERO(&w);
+ for (ev = evs; ev; ev = ev->next)
+ {
+ if (ev->condpos && *ev->condpos <= (ev->condneg ? *ev->condneg : 0))
+ {
+ debug2(" - cond ev fd %d type %d failed\n", ev->fd, ev->type);
+ continue;
+ }
+ if (ev->type == EV_READ)
+ FD_SET(ev->fd, &r);
+ else if (ev->type == EV_WRITE)
+ FD_SET(ev->fd, &w);
+ }
+
+#ifdef DEBUG
+ debug("readfds:");
+ for (nsel = 0; nsel < FD_SETSIZE; nsel++)
+ if (FD_ISSET(nsel, &r))
+ debug1(" %d", nsel);
+ debug("\n");
+ debug("writefds:");
+ for (nsel = 0; nsel < FD_SETSIZE; nsel++)
+ if (FD_ISSET(nsel, &w))
+ debug1(" %d", nsel);
+ debug("\n");
+#endif
+
+ nsel = select(FD_SETSIZE, &r, &w, (fd_set *)0, timeoutev ? &timeout : (struct timeval *) 0);
+ if (nsel < 0)
+ {
+ if (errno != EINTR)
+ {
+#if defined(sgi) && defined(SVR4)
+ if (errno == EIO && sgihack())
+ continue;
+#endif
+#ifdef __osf__
+ /* OSF/1 3.x bug: EBADF */
+ /* OSF/1 4.x bug: EIO */
+ if ((errno == EIO || errno == EBADF) && sgihack())
+ continue;
+#endif
+ Panic(errno, "select");
+ }
+ nsel = 0;
+ }
+ else if (nsel == 0) /* timeout */
+ {
+ debug("TIMEOUT!\n");
+ ASSERT(timeoutev);
+ evdeq(timeoutev);
+ timeoutev->handler(timeoutev, timeoutev->data);
+ }
+#ifdef SELECT_BROKEN
+ /*
+ * Sequents select emulation counts a descriptor which is
+ * readable and writeable only as one hit. Waaaaa.
+ */
+ debug2("nsel %d, was %d; ", nsel ? 2 * FD_SETSIZE : nsel, nsel);
+ if (nsel)
+ nsel = 2 * FD_SETSIZE;
+#endif
+
+ for (ev = evs; ev; ev = nextev)
+ {
+ nextev = ev->next;
+ if (ev->type != EV_ALWAYS)
+ {
+ set = ev->type == EV_READ ? &r : &w;
+ if (nsel == 0 || !FD_ISSET(ev->fd, set))
+ continue;
+ nsel--;
+ }
+ if (ev->condpos && *ev->condpos <= (ev->condneg ? *ev->condneg : 0))
+ continue;
+ debug2(" + hit ev fd %d type %d!\n", ev->fd, ev->type);
+ ev->handler(ev, ev->data);
+ }
+ }
+}
+
+void
+SetTimeout(ev, timo)
+struct event *ev;
+int timo;
+{
+ ASSERT(ev->type == EV_TIMEOUT);
+ debug2("event %x new timeout %d ms\n", ev, timo);
+ gettimeofday(&ev->timeout, NULL);
+ ev->timeout.tv_sec += timo / 1000;
+ ev->timeout.tv_usec += (timo % 1000) * 1000;
+ if (ev->timeout.tv_usec > 1000000)
+ {
+ ev->timeout.tv_usec -= 1000000;
+ ev->timeout.tv_sec++;
+ }
+ if (ev->queued)
+ calctimeout = 1;
+}
+
+
+#if (defined(sgi) && defined(SVR4)) || defined(__osf__)
+
+extern struct display *display, *displays;
+static int sgihack()
+{
+ fd_set r, w;
+ struct timeval tv;
+
+ debug("IRIX5.2 workaround: searching for bad display\n");
+ for (display = displays; display; )
+ {
+ FD_ZERO(&r);
+ FD_ZERO(&w);
+ FD_SET(D_userfd, &r);
+ FD_SET(D_userfd, &w);
+ tv.tv_sec = tv.tv_usec = 0;
+ if (select(FD_SETSIZE, &r, &w, (fd_set *)0, &tv) == -1)
+ {
+ if (errno == EINTR)
+ continue;
+ SigHup(SIGARG); /* goodbye display */
+ return 1;
+ }
+ display = display->d_next;
+ }
+ return 0;
+}
+
+#endif
diff --git a/sched.h b/sched.h
new file mode 100644
index 0000000..853cee0
--- /dev/null
+++ b/sched.h
@@ -0,0 +1,20 @@
+
+struct event
+{
+ struct event *next;
+ void (*handler) __P((struct event *, char *));
+ char *data;
+ int fd;
+ int type;
+ int pri;
+ struct timeval timeout;
+ int queued; /* in evs queue */
+ int active; /* in fdset */
+ int *condpos; /* only active if condpos - condneg > 0 */
+ int *condneg;
+};
+
+#define EV_TIMEOUT 0
+#define EV_READ 1
+#define EV_WRITE 2
+#define EV_ALWAYS 3
diff --git a/screen.c b/screen.c
index dea1311..bf7b4cd 100644
--- a/screen.c
+++ b/screen.c
@@ -2,6 +2,15 @@
* Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
* Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
* Copyright (c) 1987 Oliver Laumann
+#ifdef HAVE_BRAILLE
+ * Modified by:
+ * Authors: Hadi Bargi Rangin bargi@dots.physics.orst.edu
+ * Bill Barry barryb@dots.physics.orst.edu
+ * Randy Lundquist randyl@dots.physics.orst.edu
+ *
+ * Modifications Copyright (c) 1995 by
+ * Science Access Project, Oregon State University.
+#endif
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,7 +31,7 @@
*/
#include "rcs.h"
-RCS_ID("$Id: screen.c,v 1.23 1994/05/31 12:32:51 mlschroe Exp $ FAU")
+RCS_ID("$Id: screen.c,v 1.24 1994/09/06 17:00:20 mlschroe Exp $ FAU")
#include <sys/types.h>
@@ -68,6 +77,9 @@ RCS_ID("$Id: screen.c,v 1.23 1994/05/31 12:32:51 mlschroe Exp $ FAU")
#endif
#include "screen.h"
+#ifdef HAVE_BRAILLE
+# include "braille.h"
+#endif
#include "patchlevel.h"
@@ -85,6 +97,7 @@ RCS_ID("$Id: screen.c,v 1.23 1994/05/31 12:32:51 mlschroe Exp $ FAU")
# include <shadow.h>
#endif /* SHADOWPW */
+#include "logfile.h" /* islogfile, logfflush */
#ifdef DEBUG
FILE *dfp;
@@ -98,13 +111,12 @@ int VBellWait, MsgWait, MsgMinWait, SilenceWait;
extern struct plop plop_tab[];
extern struct user *users;
extern struct display *displays, *display;
-extern struct layer BlankLayer;
/* tty.c */
extern int intrc;
-extern int use_hardstatus;
+extern int visual_bell;
#ifdef COPY_PASTE
extern unsigned char mark_key_tab[];
#endif
@@ -117,14 +129,20 @@ char *ShellArgs[2];
extern struct NewWindow nwin_undef, nwin_default, nwin_options;
+static struct passwd *getpwbyname __P((char *, struct passwd *));
static void SigChldHandler __P((void));
static sigret_t SigChld __P(SIGPROTOARG);
static sigret_t SigInt __P(SIGPROTOARG);
static sigret_t CoreDump __P(SIGPROTOARG);
static sigret_t FinitHandler __P(SIGPROTOARG);
static void DoWait __P((void));
-static void WindowDied __P((struct win *));
-
+static void serv_read_fn __P((struct event *, char *));
+static void serv_select_fn __P((struct event *, char *));
+static void logflush_fn __P((struct event *, char *));
+static int IsSymbol __P((char *, char *));
+#ifdef DEBUG
+static void fds __P((void));
+#endif
int nversion; /* numerical version, used for secondary DA */
@@ -136,16 +154,23 @@ char *LoginName;
struct mode attach_Mode;
char SockPath[MAXPATHLEN + 2 * MAXSTR];
-char *SockName, *SockMatch; /* SockName is pointer in SockPath */
+char *SockName; /* SockName is pointer in SockPath */
+char *SockMatch = NULL; /* session id command line argument */
int ServerSocket = -1;
+struct event serv_read;
+struct event serv_select;
+struct event logflushev;
char **NewEnv = NULL;
char *RcFileName = NULL;
-extern char Esc;
char *home;
-char *screenlogfile;
+char *screenlogfile; /* filename layout */
+int log_flush = 10; /* flush interval in seconds */
+int logtstamp_on = 0; /* tstamp disabled */
+char *logtstamp_string; /* stamp layout */
+int logtstamp_after = 120; /* first tstamp after 120s */
char *hardcopydir = NULL;
char *BellString;
char *VisualBellString;
@@ -156,12 +181,12 @@ char *BufferFile;
#ifdef POW_DETACH
char *PowDetachString;
#endif
+char *hstatusstring;
+char *captionstring;
int auto_detach = 1;
int iflag, rflag, dflag, lsflag, quietflag, wipeflag, xflag;
int adaptflag;
-time_t Now;
-
#ifdef MULTIUSER
char *multi;
char *multi_home;
@@ -176,8 +201,8 @@ char HostName[MAXSTR];
int MasterPid;
int real_uid, real_gid, eff_uid, eff_gid;
int default_startup;
-int slowpaste;
int ZombieKey_destroy, ZombieKey_resurrect;
+char *preselect = NULL; /* only used in Attach() */
#ifdef NETHACK
int nethackflag = 0;
@@ -187,6 +212,7 @@ int maptimeout = 300000;
#endif
+struct layer *flayer;
struct win *fore;
struct win *windows;
struct win *console_window;
@@ -198,139 +224,110 @@ struct win *console_window;
*/
#include "extern.h"
-
-#ifdef NETHACK
-char strnomem[] = "Who was that Maude person anyway?";
-#else
char strnomem[] = "Out of memory.";
-#endif
static int InterruptPlease;
static int GotSigChld;
-
-static void
-mkfdsets(rp, wp)
-fd_set *rp, *wp;
+static int
+lf_secreopen(name, wantfd, l)
+char *name;
+int wantfd;
+struct logfile *l;
{
- register struct win *p;
+ int got_fd;
- FD_ZERO(rp);
- FD_ZERO(wp);
- for (display = displays; display; display = display->d_next)
+ close(wantfd);
+ if (((got_fd = secopen(name, O_WRONLY | O_CREAT | O_APPEND, 0666)) < 0) ||
+ lf_move_fd(got_fd, wantfd) < 0)
{
- if (D_obufp != D_obuf)
- FD_SET(D_userfd, wp);
-
- FD_SET(D_userfd, rp); /* Do that always */
-
- /* read from terminal if there is room in the destination buffer
- *
- * Removed, so we can always input a command sequence
- *
- * if (D_fore == 0)
- * continue;
- * if (W_UWP(D_fore))
- * {
- * check pseudowin buffer
- * if (D_fore->w_pwin->p_inlen < sizeof(D_fore->w_pwin->p_inbuf))
- * FD_SET(D_userfd, rp);
- * }
- * else
- * {
- * check window buffer
- * if (D_fore->w_inlen < sizeof(D_fore->w_inbuf))
- * FD_SET(D_userfd, rp);
- * }
- */
+ logfclose(l);
+ debug1("lf_secreopen: failed for %s\n", name);
+ return -1;
}
- for (p = windows; p; p = p->w_next)
- {
- if (p->w_ptyfd < 0)
- continue;
-#ifdef COPY_PASTE
- if (p->w_pastelen)
- {
- /* paste to win/pseudo */
-# ifdef PSEUDOS
- FD_SET(W_UWP(p) ? p->w_pwin->p_ptyfd : p->w_ptyfd, wp);
-# else
- FD_SET(p->w_ptyfd, wp);
-# endif
- }
+ l->st->st_ino = l->st->st_dev = 0;
+ debug2("lf_secreopen: %d = %s\n", wantfd, name);
+ return 0;
+}
+
+/********************************************************************/
+/********************************************************************/
+/********************************************************************/
+
+
+struct passwd *
+getpwbyname(name, ppp)
+char *name;
+struct passwd *ppp;
+{
+ int n;
+#ifdef SHADOWPW
+ struct spwd *sss = NULL;
+ static char *spw = NULL;
#endif
- /* query window buffer */
- if (p->w_inlen > 0)
- FD_SET(p->w_ptyfd, wp);
-#ifdef PSEUDOS
- /* query pseudowin buffer */
- if (p->w_pwin && p->w_pwin->p_inlen > 0)
- FD_SET(p->w_pwin->p_ptyfd, wp);
+
+ if (!(ppp = getpwnam(name)))
+ return NULL;
+
+ /* Do password sanity check..., allow ##user for SUN_C2 security */
+#ifdef SHADOWPW
+pw_try_again:
#endif
+ n = 0;
+ if (ppp->pw_passwd[0] == '#' && ppp->pw_passwd[1] == '#' &&
+ strcmp(ppp->pw_passwd + 2, ppp->pw_name) == 0)
+ n = 13;
+ for (; n < 13; n++)
+ {
+ char c = ppp->pw_passwd[n];
+ if (!(c == '.' || c == '/' ||
+ (c >= '0' && c <= '9') ||
+ (c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z')))
+ break;
+ }
- display = p->w_display;
- if (p->w_active && D_status && !D_status_bell && !(use_hardstatus && D_HS))
- continue;
- if (p->w_outlen > 0)
- continue;
- if (p->w_lay->l_block)
- continue;
- /*
- * Don't accept input from window or pseudowin if there is to much
- * output pending on display .
- */
- if (p->w_active && (D_obufp - D_obuf) > D_obufmax)
- {
- debug1("too much output pending, window %d\n", p->w_number);
- continue;
- }
-#ifdef PSEUDOS
- if (W_RW(p))
- {
- /* Check free space if we stuff window output in pseudo */
- if (p->w_pwin && W_WTOP(p) && (p->w_pwin->p_inlen >= sizeof(p->w_pwin->p_inbuf)))
- {
- debug2("pseudowin %d buffer full (%d bytes)\n", p->w_number, p->w_pwin->p_inlen);
- }
- else
- FD_SET(p->w_ptyfd, rp);
- }
- if (W_RP(p))
+#ifdef SHADOWPW
+ /* try to determine real password */
+ if (n < 13 && sss == 0)
+ {
+ sss = getspnam(ppp->pw_name);
+ if (sss)
{
- /* Check free space if we stuff pseudo output in window */
- if (W_PTOW(p) && p->w_inlen >= sizeof(p->w_inbuf))
- {
- debug2("window %d buffer full (%d bytes)\n", p->w_number, p->w_inlen);
- }
- else
- FD_SET(p->w_pwin->p_ptyfd, rp);
+ if (spw)
+ free(spw);
+ ppp->pw_passwd = spw = SaveStr(sss->sp_pwdp);
+ endspent(); /* this should delete all buffers ... */
+ goto pw_try_again;
}
-#else /* PSEUDOS */
- FD_SET(p->w_ptyfd, rp);
-#endif /* PSEUDOS */
+ endspent(); /* this should delete all buffers ... */
}
- FD_SET(ServerSocket, rp);
+#endif
+ if (n < 13)
+ ppp->pw_passwd = 0;
+#ifdef linux
+ if (ppp->pw_passwd && strlen(ppp->pw_passwd) == 13 + 11)
+ ppp->pw_passwd[13] = 0; /* beware of linux's long passwords */
+#endif
+
+ return ppp;
}
+
int
main(ac, av)
int ac;
char **av;
{
- register int n, len;
- register struct win *p;
+ register int n;
char *ap;
char *av0;
char socknamebuf[2 * MAXSTR];
- fd_set r, w;
int mflag = 0;
- struct timeval tv;
- int nsel;
- char buf[IOSIZE], *myname = (ac == 0) ? "screen" : av[0];
+ char *myname = (ac == 0) ? "screen" : av[0];
char *SockDir;
struct stat st;
- int buflen, tmp;
#ifdef _MODE_T /* (jw) */
mode_t oumask;
#else
@@ -341,13 +338,9 @@ char **av;
#endif
struct NewWindow nwin;
int detached = 0; /* start up detached */
- struct display *ndisplay;
#ifdef MULTIUSER
char *sockp;
#endif
-#ifdef MAPKEYS
- int kmaptimeout;
-#endif
#if (defined(AUX) || defined(_AUX_SOURCE)) && defined(POSIX)
setcompat(COMPAT_POSIX|COMPAT_BSDPROT); /* turn on seteuid support */
@@ -422,10 +415,13 @@ char **av;
debug1("NAME_MAX = %d\n", NAME_MAX);
#endif
- BellString = SaveStr("Bell in window %");
+ BellString = SaveStr("Bell in window %n");
VisualBellString = SaveStr(" Wuff, Wuff!! ");
- ActivityString = SaveStr("Activity in window %");
+ ActivityString = SaveStr("Activity in window %n");
screenlogfile = SaveStr("screenlog.%n");
+ logtstamp_string = SaveStr("-- %n:%t -- time-stamp -- %M/%d/%y %c:%s --\n");
+ hstatusstring = SaveStr("%h");
+ captionstring = SaveStr("%3n %t");
#ifdef COPY_PASTE
BufferFile = SaveStr(DEFAULT_BUFFERFILE);
#endif
@@ -435,24 +431,32 @@ char **av;
#endif
default_startup = (ac > 1) ? 0 : 1;
adaptflag = 0;
- slowpaste = 0;
VBellWait = VBELLWAIT;
MsgWait = MSGWAIT;
MsgMinWait = MSGMINWAIT;
SilenceWait = SILENCEWAIT;
+#ifdef HAVE_BRAILLE
+ InitBraille();
+#endif
+
#ifdef COPY_PASTE
CompileKeys((char *)NULL, mark_key_tab);
#endif
nwin = nwin_undef;
nwin_options = nwin_undef;
+ strcpy(screenterm, "screen");
+
+ logreopen_register(lf_secreopen);
av0 = *av;
- /* if this is a login screen, assume -R */
+ /* if this is a login screen, assume -RR */
if (*av0 == '-')
{
- rflag = 2;
+ rflag = 4;
#ifdef MULTI
xflag = 1;
+#else
+ dflag = 1;
#endif
ShellProg = SaveStr(DefaultShell); /* to prevent nasty circles */
}
@@ -467,214 +471,211 @@ char **av;
ac--;
break;
}
- switch (ap[1])
+ while (ap && *ap && *++ap)
{
- case 'a':
- nwin_options.aflag = 1;
- break;
- case 'A':
- adaptflag = 1;
- break;
- case 'c':
- if (ap[2])
- RcFileName = ap + 2;
- else
+ switch (*ap)
{
- if (--ac == 0)
- exit_with_usage(myname, "Specify an alternate rc-filename with -c", NULL);
- RcFileName = *++av;
- }
- break;
- case 'e':
- if (ap[2])
- ap += 2;
- else
- {
- if (--ac == 0)
- exit_with_usage(myname, "Specify command escape characters with -e", NULL);
- ap = *++av;
- }
- if (ParseEscape((struct user *)0, ap))
- Panic(0, "Two characters are required with -e option, not '%s'", ap);
- ap = NULL;
- break;
- case 'f':
- switch (ap[2])
- {
- case 'n':
- case '0':
- nwin_options.flowflag = FLOW_NOW * 0;
+ case 'a':
+ nwin_options.aflag = 1;
break;
- case 'y':
- case '1':
- case '\0':
- nwin_options.flowflag = FLOW_NOW * 1;
+ case 'A':
+ adaptflag = 1;
break;
- case 'a':
- nwin_options.flowflag = FLOW_AUTOFLAG;
+ case 'p': /* preselect */
+ if (*++ap)
+ preselect = ap;
+ else
+ {
+ if (!--ac)
+ exit_with_usage(myname, "Specify a window to preselect with -p", NULL);
+ preselect = *++av;
+ }
+ ap = NULL;
break;
- default:
- exit_with_usage(myname, "Unknown flow option -%s", --ap);
- }
- break;
- case 'h':
- if (ap[2])
- nwin_options.histheight = atoi(ap + 2);
- else
- {
+#ifdef HAVE_BRAILLE
+ case 'B':
+ bd.bd_start_braille = 1;
+ break;
+#endif
+ case 'c':
+ if (*++ap)
+ RcFileName = ap;
+ else
+ {
+ if (--ac == 0)
+ exit_with_usage(myname, "Specify an alternate rc-filename with -c", NULL);
+ RcFileName = *++av;
+ }
+ ap = NULL;
+ break;
+ case 'e':
+ if (!*++ap)
+ {
+ if (--ac == 0)
+ exit_with_usage(myname, "Specify command characters with -e", NULL);
+ ap = *++av;
+ }
+ if (ParseEscape(NULL, ap))
+ Panic(0, "Two characters are required with -e option, not '%s'.", ap);
+ ap += 3; /* estimated size of notation */
+ break;
+ case 'f':
+ ap++;
+ switch (*ap++)
+ {
+ case 'n':
+ case '0':
+ nwin_options.flowflag = FLOW_NOW * 0;
+ break;
+ case '\0':
+ ap--;
+ /* FALLTHROUGH */
+ case 'y':
+ case '1':
+ nwin_options.flowflag = FLOW_NOW * 1;
+ break;
+ case 'a':
+ nwin_options.flowflag = FLOW_AUTOFLAG;
+ break;
+ default:
+ exit_with_usage(myname, "Unknown flow option -%s", --ap);
+ }
+ break;
+ case 'h':
if (--ac == 0)
exit_with_usage(myname, NULL, NULL);
nwin_options.histheight = atoi(*++av);
- }
- if (nwin_options.histheight < 0)
- exit_with_usage(myname, "-h %s: negative scrollback size?",*av);
- break;
- case 'i':
- iflag = 1;
- break;
- case 't':
- case 'k': /* obsolete */
- if (ap[2])
- nwin_options.aka = ap + 2;
- else
- {
+ if (nwin_options.histheight < 0)
+ exit_with_usage(myname, "-h: %s: negative scrollback size?", *av);
+ break;
+ case 'i':
+ iflag = 1;
+ break;
+ case 't': /* title, the former AkA == -k */
if (--ac == 0)
exit_with_usage(myname, "Specify a new window-name with -t", NULL);
nwin_options.aka = *++av;
- }
- break;
- case 'l':
- switch (ap[2])
- {
- case 'n':
- case '0':
- nwin_options.lflag = 0;
break;
- case 'y':
- case '1':
- case '\0':
- nwin_options.lflag = 1;
+ case 'l':
+ ap++;
+ switch (*ap++)
+ {
+ case 'n':
+ case '0':
+ nwin_options.lflag = 0;
+ break;
+ case '\0':
+ ap--;
+ /* FALLTHROUGH */
+ case 'y':
+ case '1':
+ nwin_options.lflag = 1;
+ break;
+ case 's': /* -ls */
+ case 'i': /* -list */
+ lsflag = 1;
+ if (ac > 1 && !SockMatch)
+ {
+ SockMatch = *++av;
+ ac--;
+ }
+ ap = NULL;
+ break;
+ default:
+ exit_with_usage(myname, "%s: Unknown suboption to -l", --ap);
+ }
break;
- case 's':
- case 'i':
+ case 'w':
lsflag = 1;
- if (ac > 1)
+ wipeflag = 1;
+ if (ac > 1 && !SockMatch)
{
SockMatch = *++av;
ac--;
}
break;
- default:
- exit_with_usage(myname, "%s: Unknown suboption to -l", ap);
- }
- break;
- case 'w':
- lsflag = 1;
- wipeflag = 1;
- break;
- case 'L':
- assume_LP = 1;
- break;
- case 'm':
- mflag = 1;
- break;
- case 'O':
- force_vt = 0;
- break;
- case 'T':
- if (ap[2])
- {
- if (strlen(ap+2) < 20)
- strcpy(screenterm, ap + 2);
- }
- else
- {
- if (--ac == 0)
+ case 'L':
+ nwin_options.Lflag = 1;
+ break;
+ case 'm':
+ mflag = 1;
+ break;
+ case 'O': /* to be (or not to be?) deleted. jw. */
+ force_vt = 0;
+ break;
+ case 'T':
+ if (--ac == 0)
exit_with_usage(myname, "Specify terminal-type with -T", NULL);
if (strlen(*++av) < 20)
- strcpy(screenterm, *av);
- }
- nwin_options.term = screenterm;
- break;
- case 'q':
- quietflag = 1;
- break;
- case 'r':
- case 'R':
+ strcpy(screenterm, *av);
+ else
+ Panic(0, "-T: terminal name too long. (max. 20 char)");
+ nwin_options.term = screenterm;
+ break;
+ case 'q':
+ quietflag = 1;
+ break;
+ case 'r':
+ case 'R':
#ifdef MULTI
- case 'x':
+ case 'x':
#endif
- if (ap[2])
- {
- SockMatch = ap + 2;
- if (ac != 1)
- exit_with_usage(myname, "must have exact one parameter after %s", ap);
- }
- else if (ac > 1 && *av[1] != '-')
- {
- SockMatch = *++av;
- ac--;
- }
+ if (ac > 1 && *av[1] != '-' && !SockMatch)
+ {
+ SockMatch = *++av;
+ ac--;
+ debug2("rflag=%d, SockMatch=%s\n", dflag, SockMatch);
+ }
#ifdef MULTI
- if (ap[1] == 'x')
- xflag = 1;
- else
+ if (*ap == 'x')
+ xflag = 1;
#endif
- rflag = (ap[1] == 'r') ? 1 : 2;
- break;
+ if (rflag)
+ rflag = 2;
+ rflag += (*ap == 'R') ? 2 : 1;
+ break;
#ifdef REMOTE_DETACH
- case 'd':
- dflag = 1;
- /* FALLTHROUGH */
- case 'D':
- if (!dflag)
- dflag = 2;
- if (ap[2])
- SockMatch = ap + 2;
- if (ac == 2)
- {
- if (*av[1] != '-')
+ case 'd':
+ dflag = 1;
+ /* FALLTHROUGH */
+ case 'D':
+ if (!dflag)
+ dflag = 2;
+ if (ac == 2)
{
- SockMatch = *++av;
- ac--;
+ if (*av[1] != '-' && !SockMatch)
+ {
+ SockMatch = *++av;
+ ac--;
+ debug2("dflag=%d, SockMatch=%s\n", dflag, SockMatch);
+ }
}
- }
- break;
+ break;
#endif
- case 's':
- if (ap[2])
- {
- if (ShellProg)
- free(ShellProg);
- ShellProg = SaveStr(ap + 2);
- }
- else
- {
+ case 's':
if (--ac == 0)
exit_with_usage(myname, "Specify shell with -s", NULL);
if (ShellProg)
free(ShellProg);
ShellProg = SaveStr(*++av);
- }
- debug1("ShellProg: '%s'\n", ShellProg);
- break;
- case 'S':
- if (ap[2])
- SockMatch = ap + 2;
- else
- {
- if (--ac == 0)
- exit_with_usage(myname, "Specify session-name with -S", NULL);
- SockMatch = *++av;
+ debug1("ShellProg: '%s'\n", ShellProg);
+ break;
+ case 'S':
+ if (!SockMatch)
+ {
+ if (--ac == 0)
+ exit_with_usage(myname, "Specify session-name with -S", NULL);
+ SockMatch = *++av;
+ }
if (!*SockMatch)
- exit_with_usage(myname, "-S: Empty session-name?", NULL);
+ exit_with_usage(myname, "Empty session-name?", NULL);
+ break;
+ case 'v':
+ Panic(0, "Screen version %s", version);
+ /* NOTREACHED */
+ default:
+ exit_with_usage(myname, "Unknown option %s", --ap);
}
- break;
- case 'v':
- Panic(0, "Screen version %s", version);
- /* NOTREACHED */
- default:
- exit_with_usage(myname, "Unknown option %s", ap);
}
}
else
@@ -682,7 +683,7 @@ char **av;
}
if (SockMatch && strlen(SockMatch) >= MAXSTR)
Panic(0, "Ridiculously long socketname - try again.");
- if (dflag && mflag && SockMatch && !(rflag || xflag))
+ if (dflag && mflag && !(rflag || xflag))
detached = 1;
nwin = nwin_options;
if (ac)
@@ -697,7 +698,7 @@ char **av;
* handler routine that resets the s-bit, so that we get a
* core file anyway.
*/
-#ifdef SIGBUS /* OOPS, linux has no bus errors ??? */
+#ifdef SIGBUS /* OOPS, linux has no bus errors! */
signal(SIGBUS, CoreDump);
#endif /* SIGBUS */
signal(SIGSEGV, CoreDump);
@@ -715,7 +716,8 @@ char **av;
* with a core dump.
*/
signal(SIGXFSZ, SIG_IGN);
-#endif
+#endif /* SIGXFSZ */
+
#ifdef SIGPIPE
signal(SIGPIPE, SIG_IGN);
#endif
@@ -728,8 +730,19 @@ char **av;
ShellProg = SaveStr(sh ? sh : DefaultShell);
}
ShellArgs[0] = ShellProg;
+ home = getenv("HOME");
+
#ifdef NETHACK
- nethackflag = (getenv("NETHACKOPTIONS") != NULL);
+ if (!(nethackflag = (getenv("NETHACKOPTIONS") != NULL)))
+ {
+ char nethackrc[MAXPATHLEN];
+
+ if (home && (strlen(home) < (MAXPATHLEN - 20)))
+ {
+ sprintf(nethackrc,"%s/.nethackrc", home);
+ nethackflag = !access(nethackrc, F_OK);
+ }
+ }
#endif
#ifdef MULTIUSER
@@ -748,15 +761,13 @@ char **av;
Panic(0, "Cannot identify account '%s'.", multi);
multi_uid = mppp->pw_uid;
multi_home = SaveStr(mppp->pw_dir);
- if (strlen(multi_home) > MAXPATHLEN - 10)
+ if (strlen(multi_home) > MAXPATHLEN - 10)
Panic(0, "home directory path too long");
# ifdef MULTI
+ /* always fake multi attach mode */
if (rflag || lsflag)
- {
- xflag = 1;
- rflag = 0;
- }
-# endif
+ xflag = 1;
+# endif /* MULTI */
detached = 0;
multiattach = 1;
}
@@ -775,58 +786,15 @@ char **av;
{
if ((ppp = getpwuid(real_uid)) == 0)
{
-#ifdef NETHACK
- if (nethackflag)
- Panic(0, "An alarm sounds through the dungeon...\nWarning, the kops are coming.");
- else
-#endif
Panic(0, "getpwuid() can't identify your account!");
exit(1);
}
LoginName = ppp->pw_name;
}
- /* Do password sanity check..., allow ##user for SUN_C2 security */
-#ifdef SHADOWPW
-pw_try_again:
-#endif
- n = 0;
- if (ppp->pw_passwd[0] == '#' && ppp->pw_passwd[1] == '#' &&
- strcmp(ppp->pw_passwd + 2, ppp->pw_name) == 0)
- n = 13;
- for (; n < 13; n++)
- {
- char c = ppp->pw_passwd[n];
- if (!(c == '.' || c == '/' ||
- (c >= '0' && c <= '9') ||
- (c >= 'a' && c <= 'z') ||
- (c >= 'A' && c <= 'Z')))
- break;
- }
-#ifdef SHADOWPW
- /* try to determine real password */
- {
- static struct spwd *sss;
- if (n < 13 && sss == 0)
- {
- sss = getspnam(ppp->pw_name);
- if (sss)
- {
- ppp->pw_passwd = SaveStr(sss->sp_pwdp);
- endspent(); /* this should delete all buffers ... */
- goto pw_try_again;
- }
- endspent(); /* this should delete all buffers ... */
- }
- }
-#endif
- if (n < 13)
- ppp->pw_passwd = 0;
-#ifdef linux
- if (ppp->pw_passwd && strlen(ppp->pw_passwd) == 13 + 11)
- ppp->pw_passwd[13] = 0; /* beware of linux's long passwords */
-#endif
+ LoginName = SaveStr(LoginName);
+
+ ppp = getpwbyname(LoginName, ppp);
- home = getenv("HOME");
#if !defined(SOCKDIR) && defined(MULTIUSER)
if (multi && !multiattach)
{
@@ -834,6 +802,7 @@ pw_try_again:
Panic(0, "$HOME must match passwd entry for multiuser screens.");
}
#endif
+
if (home == 0 || *home == '\0')
home = ppp->pw_dir;
if (strlen(LoginName) > 20)
@@ -845,25 +814,18 @@ pw_try_again:
if (strlen(home) > MAXPATHLEN - 25)
Panic(0, "$HOME too long - sorry.");
- if (!detached && !lsflag)
+ attach_tty = "";
+ if (!detached && !lsflag && !(dflag && !mflag && !rflag && !xflag))
{
/* ttyname implies isatty */
if (!(attach_tty = ttyname(0)))
- {
-#ifdef NETHACK
- if (nethackflag)
- Panic(0, "You must play from a terminal.");
- else
-#endif
- Panic(0, "Must be connected to a terminal.");
- exit(1);
- }
+ Panic(0, "Must be connected to a terminal.");
if (strlen(attach_tty) >= MAXPATHLEN)
Panic(0, "TtyName too long - sorry.");
if (stat(attach_tty, &st))
Panic(errno, "Cannot access '%s'", attach_tty);
#ifdef MULTIUSER
- tty_mode = st.st_mode & 0777;
+ tty_mode = (int)st.st_mode & 0777;
#endif
if ((n = secopen(attach_tty, O_RDWR, 0)) < 0)
Panic(0, "Cannot open your terminal '%s' - please check.", attach_tty);
@@ -885,22 +847,21 @@ pw_try_again:
if ((oumask = umask(0)) == -1)
Panic(errno, "Cannot change umask to zero");
#endif
- if ((SockDir = getenv("ISCREENDIR")) == NULL)
- SockDir = getenv("SCREENDIR");
+ SockDir = getenv("SCREENDIR");
if (SockDir)
{
if (strlen(SockDir) >= MAXPATHLEN - 1)
- Panic(0, "Ridiculously long $(I)SCREENDIR - try again.");
+ Panic(0, "Ridiculously long $SCREENDIR - try again.");
#ifdef MULTIUSER
if (multi)
- Panic(0, "No $(I)SCREENDIR with multi screens, please.");
+ Panic(0, "No $SCREENDIR with multi screens, please.");
#endif
}
#ifdef MULTIUSER
if (multiattach)
{
# ifndef SOCKDIR
- sprintf(SockPath, "%s/.iscreen", multi_home);
+ sprintf(SockPath, "%s/.screen", multi_home);
SockDir = SockPath;
# else
SockDir = SOCKDIR;
@@ -913,7 +874,7 @@ pw_try_again:
#ifndef SOCKDIR
if (SockDir == 0)
{
- sprintf(SockPath, "%s/.iscreen", home);
+ sprintf(SockPath, "%s/.screen", home);
SockDir = SockPath;
}
#endif
@@ -940,6 +901,13 @@ pw_try_again:
SockDir = SOCKDIR;
if (lstat(SockDir, &st))
{
+ n = (eff_uid == 0) ? 0755 :
+ (eff_gid != real_gid) ? 0775 :
+#ifdef S_ISVTX
+ 0777|S_ISVTX;
+#else
+ 0777;
+#endif
if (mkdir(SockDir, eff_uid ? 0777 : 0755) == -1)
Panic(errno, "Cannot make directory '%s'", SockDir);
}
@@ -947,9 +915,11 @@ pw_try_again:
{
if (!S_ISDIR(st.st_mode))
Panic(0, "'%s' must be a directory.", SockDir);
- if (eff_uid == 0 && st.st_uid != eff_uid)
+ if (eff_uid == 0 && real_uid && st.st_uid != eff_uid)
Panic(0, "Directory '%s' must be owned by root.", SockDir);
- n = eff_uid ? 0777 : 0755;
+ n = (eff_uid == 0 && (real_uid || (st.st_mode & 0777) != 0777)) ? 0755 :
+ (eff_gid == st.st_gid && eff_gid != real_gid) ? 0775 :
+ 0777;
if ((st.st_mode & 0777) != n)
Panic(0, "Directory '%s' must have mode %03o.", SockDir, n);
}
@@ -966,6 +936,7 @@ pw_try_again:
if (stat(SockPath, &st) == -1)
Panic(errno, "Cannot access %s", SockPath);
+ else
if (!S_ISDIR(st.st_mode))
Panic(0, "%s is not a directory.", SockPath);
#ifdef MULTIUSER
@@ -1013,16 +984,9 @@ pw_try_again:
eff_gid = real_gid;
i = FindSocket((int *)NULL, &fo, &oth, SockMatch);
if (quietflag)
- exit(8 + (fo ? ((oth || i) ? 2 : 1) : 0) + i);
+ exit(8 + (fo ? ((oth || i) ? 2 : 1) : 0) + i);
if (fo == 0)
- {
-#ifdef NETHACK
- if (nethackflag)
- Panic(0, "This room is empty (%s).\n", SockPath);
- else
-#endif /* NETHACK */
- Panic(0, "No Sockets found in %s.\n", SockPath);
- }
+ Panic(0, "No Sockets found in %s.\n", SockPath);
Panic(0, "%d Socket%s in %s.\n", fo, fo > 1 ? "s" : "", SockPath);
/* NOTREACHED */
}
@@ -1145,13 +1109,14 @@ pw_try_again:
n = -1;
freopen("/dev/null", "r", stdin);
freopen("/dev/null", "w", stdout);
+
#ifdef DEBUG
if (dfp != stderr)
#endif
freopen("/dev/null", "w", stderr);
debug("-- screen.back debug started\n");
- /*
+ /*
* This guarantees that the session owner is listed, even when we
* start detached. From now on we should not refer to 'LoginName'
* any more, use users->u_name instead.
@@ -1217,6 +1182,7 @@ pw_try_again:
Kill(D_userpid, SIG_BYE);
eexit(1);
}
+ MakeDefaultCanvas();
InitTerm(0);
#ifdef UTMPOK
RemoveLoginSlot();
@@ -1224,7 +1190,6 @@ pw_try_again:
}
else
MakeTermcap(1);
-
#ifdef LOADAV
InitLoadav();
#endif /* LOADAV */
@@ -1237,10 +1202,11 @@ pw_try_again:
signal(SIGTTIN, SIG_IGN);
signal(SIGTTOU, SIG_IGN);
#endif
+
if (display)
{
brktty(D_userfd);
- SetMode(&D_OldMode, &D_NewMode);
+ SetMode(&D_OldMode, &D_NewMode, display->d_flow, iflag);
/* Note: SetMode must be called _before_ FinishRc. */
SetTTY(D_userfd, &D_NewMode);
if (fcntl(D_userfd, F_SETFL, FNBLOCK))
@@ -1270,566 +1236,40 @@ pw_try_again:
/* NOTREACHED */
}
}
+
+#ifdef HAVE_BRAILLE
+ StartBraille();
+#endif
+
if (display && default_startup)
display_copyright();
signal(SIGCHLD, SigChld);
signal(SIGINT, SigInt);
- tv.tv_usec = 0;
- if (rflag == 2)
+ if (rflag && (rflag & 1) == 0)
{
-#ifdef NETHACK
- if (nethackflag)
- Msg(0, "I can't seem to find a... Hey, wait a minute! Here comes a screen now.");
- else
-#endif
Msg(0, "New screen...");
rflag = 0;
}
- Now = time((time_t *)0);
-
- for (;;)
- {
- tv.tv_sec = 0;
- /*
- * check for silence
- */
- for (p = windows; p; p = p->w_next)
- {
- int time_left;
-
- if (p->w_tstamp.seconds == 0)
- continue;
- debug1("checking silence win %d\n", p->w_number);
- time_left = p->w_tstamp.lastio + p->w_tstamp.seconds - Now;
- if (time_left > 0)
- {
- if (tv.tv_sec == 0 || time_left < tv.tv_sec)
- tv.tv_sec = time_left;
- }
- else
- {
- for (display = displays; display; display = display->d_next)
- if (p != D_fore)
- Msg(0, "Window %d: silence for %d seconds",
- p->w_number, p->w_tstamp.seconds);
- p->w_tstamp.lastio = Now;
- }
- }
-
- /*
- * check to see if message line should be removed
- */
- for (display = displays; display; display = display->d_next)
- {
- int time_left;
-
- if (D_status == 0)
- continue;
- debug("checking status...\n");
- time_left = D_status_time + (D_status_bell?VBellWait:MsgWait) - Now;
- if (time_left > 0)
- {
- if (tv.tv_sec == 0 || time_left < tv.tv_sec)
- tv.tv_sec = time_left;
- debug(" not yet.\n");
- }
- else
- {
- debug(" removing now.\n");
- RemoveStatus();
- }
- }
- /*
- * check to see if a mapping timeout should happen
- */
-#ifdef MAPKEYS
- kmaptimeout = 0;
- tv.tv_usec = 0;
- for (display = displays; display; display = display->d_next)
- if (D_seql)
- {
- int j;
- struct kmap *km;
-
- km = (struct kmap *)(D_seqp - D_seql - KMAP_SEQ);
- j = *(D_seqp - 1 + (KMAP_OFF - KMAP_SEQ));
- if (j == 0)
- j = D_nseqs - (km - D_kmaps);
- for (; j; km++, j--)
- if (km->nr & KMAP_NOTIMEOUT)
- break;
- if (j)
- continue;
- tv.tv_sec = 0;
- tv.tv_usec = maptimeout;
- kmaptimeout = 1;
- break;
- }
-#endif
- /*
- * check for I/O on all available I/O descriptors
- */
-#ifdef DEBUG
- if (tv.tv_sec)
- debug1("select timeout %d seconds\n", (int)tv.tv_sec);
-#endif
- mkfdsets(&r, &w);
- if (GotSigChld && !tv.tv_sec)
- {
- SigChldHandler();
- continue;
- }
- if ((nsel = select(FD_SETSIZE, &r, &w, (fd_set *)0, (tv.tv_sec || tv.tv_usec) ? &tv : (struct timeval *) 0)) < 0)
- {
- debug1("Bad select - errno %d\n", errno);
-#if defined(sgi) && defined(SVR4)
- /* Ugly workaround for braindead IRIX5.2 select.
- * read() should return EIO, not select()!
- */
- if (errno == EIO)
- {
- debug("IRIX5.2 workaround: searching for bad display\n");
- for (display = displays; display; )
- {
- FD_ZERO(&r);
- FD_ZERO(&w);
- FD_SET(D_userfd, &r);
- FD_SET(D_userfd, &w);
- tv.tv_sec = tv.tv_usec = 0;
- if (select(FD_SETSIZE, &r, &w, (fd_set *)0, &tv) == -1)
- {
- if (errno == EINTR)
- continue;
- SigHup(SIGARG);
- break;
- }
- display = display->d_next;
- }
- }
- else
-#endif
- if (errno != EINTR)
- Panic(errno, "select");
- errno = 0;
- nsel = 0;
- }
-#ifdef MAPKEYS
- else
- for (display = displays; display; display = display->d_next)
- {
- if (D_seql == 0)
- continue;
- if ((nsel == 0 && kmaptimeout) || D_seqruns++ * 50000 > maptimeout)
- {
- debug1("Flushing map sequence (%d runs)\n", D_seqruns);
- fore = D_fore;
- D_seqp -= D_seql;
- ProcessInput2(D_seqp, D_seql);
- D_seqp = D_kmaps[0].seq;
- D_seql = 0;
- }
- }
-#endif
-#ifdef SELECT_BROKEN
- /*
- * Sequents select emulation counts an descriptor which is
- * readable and writeable only as one. waaaaa.
- */
- if (nsel)
- nsel = 2 * FD_SETSIZE;
-#endif
- if (GotSigChld && !tv.tv_sec)
- {
- SigChldHandler();
- continue;
- }
- if (InterruptPlease)
- {
- debug("Backend received interrupt\n");
- if (fore)
- {
- char ibuf;
- ibuf = intrc;
-#ifdef PSEUDOS
- write(W_UWP(fore) ? fore->w_pwin->p_ptyfd : fore->w_ptyfd,
- &ibuf, 1);
- debug1("Backend wrote interrupt to %d", fore->w_number);
- debug1("%s\n", W_UWP(fore) ? " (pseudowin)" : "");
-#else
- write(fore->w_ptyfd, &ibuf, 1);
- debug1("Backend wrote interrupt to %d\n", fore->w_number);
-#endif
- }
- InterruptPlease = 0;
- }
-
- /*
- * Process a client connect attempt and message
- */
- if (nsel && FD_ISSET(ServerSocket, &r))
- {
- nsel--;
- debug("Knock - knock!\n");
- ReceiveMsg();
- continue;
- }
+ serv_read.type = EV_READ;
+ serv_read.fd = ServerSocket;
+ serv_read.handler = serv_read_fn;
+ evenq(&serv_read);
- /*
- * Write the (already processed) user input to the window
- * descriptors first. We do not want to choke, if he types fast.
- */
- if (nsel)
- {
- for (p = windows; p; p = p->w_next)
- {
- int pastefd = -1;
-
- if (p->w_ptyfd < 0)
- continue;
-#ifdef COPY_PASTE
- if (p->w_pastelen)
- {
- /*
- * Write the copybuffer contents first, if any.
- */
-#ifdef PSEUDOS
- pastefd = W_UWP(p) ? p->w_pwin->p_ptyfd : p->w_ptyfd;
-#else
- pastefd = p->w_ptyfd;
-#endif
- if (FD_ISSET(pastefd, &w))
- {
- debug1("writing pastebuffer (%d)\n", p->w_pastelen);
- len = write(pastefd, p->w_pasteptr,
- (slowpaste > 0) ? 1 :
- (p->w_pastelen > IOSIZE ?
- IOSIZE : p->w_pastelen));
- if (len < 0) /* Problems... window is dead */
- p->w_pastelen = 0;
- if (len > 0)
- {
- p->w_pasteptr += len;
- p->w_pastelen -= len;
- }
- debug1("%d bytes pasted\n", len);
- if (p->w_pastelen == 0)
- {
- if (p->w_pastebuf)
- free(p->w_pastebuf);
- p->w_pastebuf = 0;
- p->w_pasteptr = 0;
- pastefd = -1;
- }
- if (slowpaste > 0)
- {
- struct timeval t;
+ serv_select.pri = -10;
+ serv_select.type = EV_ALWAYS;
+ serv_select.handler = serv_select_fn;
+ evenq(&serv_select);
- debug1("slowpaste %d\n", slowpaste);
- t.tv_sec = (long) (slowpaste / 1000);
- t.tv_usec = (long) ((slowpaste % 1000) * 1000);
- select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
- }
- if (--nsel == 0)
- break;
- }
- }
-#endif
-
-#ifdef PSEUDOS
- if (p->w_pwin && p->w_pwin->p_inlen > 0)
- {
- /* stuff w_pwin->p_inbuf into pseudowin */
- tmp = p->w_pwin->p_ptyfd;
- if (tmp != pastefd && FD_ISSET(tmp, &w))
- {
- if ((len = write(tmp, p->w_pwin->p_inbuf,
- p->w_pwin->p_inlen)) > 0)
- {
- if ((p->w_pwin->p_inlen -= len))
- bcopy(p->w_pwin->p_inbuf + len, p->w_pwin->p_inbuf,
- p->w_pwin->p_inlen);
- }
- if (--nsel == 0)
- break;
- }
- }
-#endif
- if (p->w_inlen > 0)
- {
- /* stuff w_inbuf buffer into window */
- tmp = p->w_ptyfd;
- if (tmp != pastefd && FD_ISSET(tmp, &w))
- {
- if ((len = write(tmp, p->w_inbuf, p->w_inlen)) > 0)
- {
- if ((p->w_inlen -= len))
- bcopy(p->w_inbuf + len, p->w_inbuf, p->w_inlen);
- }
- if (--nsel == 0)
- break;
- }
- }
- }
- }
-
- Now = time((time_t *)0);
-
- if (nsel)
- {
- for (display = displays; display; display = ndisplay)
- {
- int maxlen;
+ logflushev.type = EV_TIMEOUT;
+ logflushev.handler = logflush_fn;
- ndisplay = display->d_next;
- /*
- * stuff D_obuf into user's tty
- */
- if (FD_ISSET(D_userfd, &w))
- {
- int size = OUTPUT_BLOCK_SIZE;
-
- len = D_obufp - D_obuf;
- if (len < size)
- size = len;
- ASSERT(len >= 0);
- size = write(D_userfd, D_obuf, size);
- if (size >= 0)
- {
- len -= size;
- if (len)
- {
- bcopy(D_obuf + size, D_obuf, len);
- debug2("ASYNC: wrote %d - remaining %d\n", size, len);
- }
- D_obufp -= size;
- D_obuffree += size;
- }
- else
- {
- if (errno != EINTR)
-# ifdef EWOULDBLOCK
- if (errno != EWOULDBLOCK)
-# endif
- Msg(errno, "Error writing output to display");
- }
- if (--nsel == 0)
- break;
- }
- /*
- * O.k. All streams are fed, now look what comes back
- * to us. First of all: user input.
- */
- if (! FD_ISSET(D_userfd, &r))
- continue;
- if (D_status && !(use_hardstatus && D_HS))
- RemoveStatus();
- if (D_fore == 0)
- maxlen = IOSIZE;
- else
- {
-#ifdef PSEUDOS
- if (W_UWP(D_fore))
- maxlen = sizeof(D_fore->w_pwin->p_inbuf) - D_fore->w_pwin->p_inlen;
- else
-#endif
- maxlen = sizeof(D_fore->w_inbuf) - D_fore->w_inlen;
- }
- if (maxlen > IOSIZE)
- maxlen = IOSIZE;
- if (maxlen <= 0)
- maxlen = 1; /* Allow one char for command keys */
- buflen = read(D_userfd, buf, maxlen);
- if (buflen < 0)
- {
- if (errno == EINTR)
- continue;
-#ifdef EAGAIN
- /* IBM's select() doesn't always tell the truth */
- if (errno == EAGAIN)
- continue;
-#endif
- debug1("Read error: %d - SigHup()ing!\n", errno);
- SigHup(SIGARG);
- sleep(1);
- }
- else if (buflen == 0)
- {
- debug("Found EOF - SigHup()ing!\n");
- SigHup(SIGARG);
- sleep(1);
- }
- else
- {
- /* This refills inbuf or p_inbuf */
- ProcessInput(buf, buflen);
- }
- if (--nsel == 0)
- break;
- }
- }
-
- /*
- * Read and process the output from the window descriptors
- */
- for (p = windows; p; p = p->w_next)
- {
- if (p->w_lay->l_block)
- continue;
- display = p->w_display;
- if (p->w_outlen)
- WriteString(p, p->w_outbuf, p->w_outlen);
- else if (p->w_ptyfd >= 0)
- {
-#ifdef PSEUDOS
- /* gather pseudowin output */
- if (W_RP(p) && nsel && FD_ISSET(p->w_pwin->p_ptyfd, &r))
- {
- nsel--;
- n = 0;
- if (W_PTOW(p))
- {
- /* Window wants a copy of the pseudowin output */
- tmp = sizeof(p->w_inbuf) - p->w_inlen;
- ASSERT(tmp > 0);
- n++;
- }
- else
- tmp = IOSIZE;
- if ((len = read(p->w_pwin->p_ptyfd, buf, tmp)) <= 0)
- {
- if (errno != EINTR)
-#ifdef EWOULDBLOCK
- if (errno != EWOULDBLOCK)
-#endif
- {
- debug2("Window %d: pseudowin read error (errno %d) -- removing pseudowin\n", p->w_number, len ? errno : 0);
- FreePseudowin(p);
- }
- }
-/* HERE WE ASSUME THAT THERE IS NO PACKET MODE ON PSEUDOWINS */
- else
- {
- if (n)
- {
- bcopy(buf, p->w_inbuf + p->w_inlen, len);
- p->w_inlen += len;
- }
- WriteString(p, buf, len);
- }
- }
-#endif /* PSEUDOS */
- /* gather window output */
- if (nsel && FD_ISSET(p->w_ptyfd, &r))
- {
- nsel--;
-#ifdef PSEUDOS
- n = 0;
- ASSERT(W_RW(p));
- if (p->w_pwin && W_WTOP(p))
- {
- /* Pseudowin wants a copy of the window output */
- tmp = sizeof(p->w_pwin->p_inbuf) - p->w_pwin->p_inlen;
- ASSERT(tmp > 0);
- n++;
- }
- else
-#endif
- tmp = IOSIZE;
- if ((len = read(p->w_ptyfd, buf, tmp)) <= 0)
- {
- if (errno == EINTR)
- continue;
-#ifdef EWOULDBLOCK
- if (errno == EWOULDBLOCK)
- continue;
-#endif
- debug2("Window %d: read error (errno %d) - killing window\n", p->w_number, len ? errno : 0);
- WindowDied(p);
- nsel = 0; /* KillWindow may change window order */
- break; /* so we just break */
- }
-#ifdef TIOCPKT
- if ((p->w_t.flags & TTY_FLAG_PLAIN) == 0)
- {
- if (buf[0])
- {
- debug1("PAKET %x\n", buf[0]);
- if (buf[0] & TIOCPKT_NOSTOP)
- NewAutoFlow(p, 0);
- if (buf[0] & TIOCPKT_DOSTOP)
- NewAutoFlow(p, 1);
- }
- if (len > 1)
- {
-#ifdef PSEUDOS
- if (n)
- {
- bcopy(buf + 1,
- p->w_pwin->p_inbuf + p->w_pwin->p_inlen,
- len - 1);
- p->w_pwin->p_inlen += len - 1;
- }
-#endif
- WriteString(p, buf + 1, len - 1);
- }
- }
- else
-#endif /* TIOCPKT */
- {
- if (len > 0)
- {
-#ifdef PSEUDOS
- if (n)
- {
- bcopy(buf, p->w_pwin->p_inbuf + p->w_pwin->p_inlen,
- len);
- p->w_pwin->p_inlen += len;
- }
-#endif
- WriteString(p, buf, len);
- }
- }
- }
- }
- if (p->w_bell == BELL_ON)
- {
- p->w_bell = BELL_MSG;
- for (display = displays; display; display = display->d_next)
- Msg(0, "%s", MakeWinMsg(BellString, p, '%'));
- if (p->w_monitor == MON_FOUND)
- p->w_monitor = MON_DONE;
- }
- else if (p->w_bell == BELL_VISUAL)
- {
- if (display && !D_status_bell)
- {
- /*
- * Stop the '!' appearing in the ^A^W display if it is an
- * active at the time of the bell. (Tim MacKenzie)
- */
- p->w_bell = BELL_OFF;
- Msg(0, VisualBellString);
- if (D_status)
- D_status_bell = 1;
- }
- }
- if (p->w_monitor == MON_FOUND)
- {
- p->w_monitor = MON_MSG;
- for (display = displays; display; display = display->d_next)
- Msg(0, "%s", MakeWinMsg(ActivityString, p, '%'));
- }
- }
-#if defined(DEBUG) && !defined(SELECT_BROKEN)
- if (nsel)
- debug1("*** Left over nsel: %d\n", nsel);
-#endif
- }
+ sched();
/* NOTREACHED */
+ return 0;
}
-static void
+void
WindowDied(p)
struct win *p;
{
@@ -1851,28 +1291,29 @@ struct win *p;
p->w_slot = 0; /* "detached" */
}
#endif
- (void) chmod(p->w_tty, 0666);
- (void) chown(p->w_tty, 0, 0);
- close(p->w_ptyfd);
- p->w_ptyfd = -1;
-#ifdef UTMPOK
- /* zap saved utmp as the slot may change */
- bzero((char *)&p->w_savut, sizeof(p->w_savut));
-#endif
+ CloseDevice(p);
+
p->w_pid = 0;
ResetWindow(p);
- p->w_y = p->w_bot;
+ /* p->w_y = p->w_bot; */
+ p->w_y = MFindUsedLine(p, p->w_bot, 1);
sprintf(buf, "\n\r=== Window terminated (%s) ===", s ? s : "?");
WriteString(p, buf, strlen(buf));
}
else
KillWindow(p);
+#ifdef UTMPOK
+ CarefulUtmp();
+#endif
}
static void
SigChldHandler()
{
struct stat st;
+#ifdef DEBUG
+ fds();
+#endif
while (GotSigChld)
{
GotSigChld = 0;
@@ -1973,6 +1414,7 @@ CoreDump SIGDEFARG
for (disp = displays; disp; disp = disp->d_next)
{
fcntl(disp->d_userfd, F_SETFL, 0);
+ SetTTY(disp->d_userfd, &D_OldMode);
write(disp->d_userfd, buf, strlen(buf));
Kill(disp->d_userpid, SIG_BYE);
}
@@ -2042,11 +1484,6 @@ DoWait()
}
#endif
/* Try to restart process */
-# ifdef NETHACK
- if (nethackflag)
- Msg(0, "You regain consciousness.");
- else
-# endif /* NETHACK */
Msg(0, "Child has been stopped, restarting.");
if (killpg(p->w_pid, SIGCONT))
kill(p->w_pid, SIGCONT);
@@ -2151,15 +1588,14 @@ int e;
exit(e);
}
-
/*
* Detach now has the following modes:
- * D_DETACH SIG_BYE detach backend and exit attacher
- * D_STOP SIG_STOP stop attacher (and detach backend)
- * D_REMOTE SIG_BYE remote detach -- reattach to new attacher
- * D_POWER SIG_POWER_BYE power detach -- attacher kills his parent
- * D_REMOTE_POWER SIG_POWER_BYE remote power detach -- both
- * D_LOCK SIG_LOCK lock the attacher
+ *D_DETACH SIG_BYE detach backend and exit attacher
+ *D_STOP SIG_STOP stop attacher (and detach backend)
+ *D_REMOTE SIG_BYE remote detach -- reattach to new attacher
+ *D_POWER SIG_POWER_BYE power detach -- attacher kills his parent
+ *D_REMOTE_POWER SIG_POWER_BYE remote power detach -- both
+ *D_LOCK SIG_LOCK lock the attacher
* (jw)
* we always remove our utmp slots. (even when "lock" or "stop")
* Note: Take extra care here, we may be called by interrupt!
@@ -2169,12 +1605,12 @@ Detach(mode)
int mode;
{
int sign = 0, pid;
-#ifdef UTMPOK
+ struct canvas *cv;
struct win *p;
-#endif
if (display == 0)
return;
+
signal(SIGHUP, SIG_IGN);
debug1("Detach(%d)\n", mode);
if (D_status)
@@ -2229,46 +1665,45 @@ int mode;
if (displays->d_next == 0)
{
for (p = windows; p; p = p->w_next)
- if (p->w_slot != (slot_t) -1)
- {
- RemoveUtmp(p);
- /*
- * Set the slot to 0 to get the window
- * logged in again.
- */
- p->w_slot = (slot_t) 0;
- }
- if (console_window)
- {
- if (TtyGrabConsole(console_window->w_ptyfd, 0, "detach"))
+ {
+ if (p->w_slot != (slot_t) -1)
{
- debug("could not release console - killing window\n");
- KillWindow(console_window);
- display = displays;
+ RemoveUtmp(p);
+ /*
+ * Set the slot to 0 to get the window
+ * logged in again.
+ */
+ p->w_slot = (slot_t) 0;
}
}
}
RestoreLoginSlot();
#endif
+ if (displays->d_next == 0 && console_window)
+ {
+ if (TtyGrabConsole(console_window->w_ptyfd, 0, "detach"))
+ {
+ debug("could not release console - killing window\n");
+ KillWindow(console_window);
+ display = displays; /* restore display */
+ }
+ }
if (D_fore)
{
+#ifdef MULTIUSER
ReleaseAutoWritelock(display, D_fore);
- if (D_fore->w_tstamp.seconds)
- D_fore->w_tstamp.lastio = Now;
- D_fore->w_active = 0;
- D_fore->w_display = 0;
- D_lay = &BlankLayer;
- D_layfn = D_lay->l_layfn;
+#endif
D_user->u_detachwin = D_fore->w_number;
+ D_user->u_detachotherwin = D_other ? D_other->w_number : -1;
}
- while (D_lay != &BlankLayer)
- ExitOverlayPage();
- if (D_userfd >= 0)
+ for (cv = D_cvlist; cv; cv = cv->c_next)
{
- Flush();
- SetTTY(D_userfd, &D_OldMode);
- fcntl(D_userfd, F_SETFL, 0);
+ p = Layer2Window(cv->c_layer);
+ SetCanvasWindow(cv, 0);
+ if (p)
+ WindowChanged(p, 'u');
}
+
pid = D_userpid;
debug2("display: %#x displays: %#x\n", (unsigned int)display, (unsigned int)displays);
FreeDisplay();
@@ -2276,7 +1711,7 @@ int mode;
/* Flag detached-ness */
(void) chsock();
/*
- * tell father to father what to do. We do that after we
+ * tell father what to do. We do that after we
* freed the tty, thus getty feels more comfortable on hpux
* if it was a power detach.
*/
@@ -2288,7 +1723,7 @@ int mode;
static int
IsSymbol(e, s)
-register char *e, *s;
+char *e, *s;
{
register int l;
@@ -2321,7 +1756,6 @@ MakeNewEnv()
for (op = environ; *op; ++op)
{
-debug1("MakeNewEnv: %s\n", *op);
if (!IsSymbol(*op, "TERM") && !IsSymbol(*op, "TERMCAP")
&& !IsSymbol(*op, "STY") && !IsSymbol(*op, "WINDOW")
&& !IsSymbol(*op, "SCREENCAP") && !IsSymbol(*op, "SHELL")
@@ -2333,100 +1767,100 @@ debug1("MakeNewEnv: %s\n", *op);
}
void
-#ifdef USEVARARGS
/*VARARGS2*/
-# if defined(__STDC__)
-Msg(int err, char *fmt, ...)
-# else /* __STDC__ */
-Msg(err, fmt, va_alist)
-int err;
-char *fmt;
-va_dcl
-# endif /* __STDC__ */
-{
- static va_list ap;
-#else /* USEVARARRGS */
-/*VARARGS2*/
-Msg(err, fmt, p1, p2, p3, p4, p5, p6)
+#if defined(USEVARARGS) && defined(__STDC__)
+Msg(int err, char *fmt, VA_DOTS)
+#else
+Msg(err, fmt, VA_DOTS)
int err;
char *fmt;
-unsigned long p1, p2, p3, p4, p5, p6;
+VA_DECL
+#endif
{
-#endif /* USEVARARRGS */
+ VA_LIST(ap)
char buf[MAXPATHLEN*2];
char *p = buf;
-#ifdef USEVARARGS
-# if defined(__STDC__)
- va_start(ap, fmt);
-# else /* __STDC__ */
- va_start(ap);
-# endif /* __STDC__ */
- (void) vsnprintf(p, sizeof(buf) - 100, fmt, ap);
- va_end(ap);
-#else /* USEVARARRGS */
- xsnprintf(p, sizeof(buf) - 100, fmt, p1, p2, p3, p4, p5, p6);
-#endif /* USEVARARRGS */
+ VA_START(ap, fmt);
+ fmt = DoNLS(fmt);
+ (void)vsnprintf(p, sizeof(buf) - 100, fmt, VA_ARGS(ap));
+ VA_END(ap);
if (err)
{
p += strlen(p);
- sprintf(p, ": %s", strerror(err));
+ *p++ = ':';
+ *p++ = ' ';
+ strncpy(p, strerror(err), buf + sizeof(buf) - p - 1);
+ buf[sizeof(buf) - 1] = 0;
}
debug2("Msg('%s') (%#x);\n", buf, (unsigned int)display);
- if (display)
+
+ if (display && displays)
MakeStatus(buf);
else if (displays)
{
for (display = displays; display; display = display->d_next)
MakeStatus(buf);
}
+ else if (display)
+ {
+ /* no displays but a display - must have forked.
+ * send message to backend!
+ */
+ char *tty = D_usertty;
+ struct display *olddisplay = display;
+ display = 0; /* only send once */
+ SendErrorMsg(tty, buf);
+ display = olddisplay;
+ }
else
printf("%s\r\n", buf);
}
+/*
+ * Call FinitTerm for all displays, write a message to each and call eexit();
+ */
void
-#ifdef USEVARARGS
/*VARARGS2*/
-# if defined(__STDC__)
-Panic(int err, char *fmt, ...)
-# else /* __STDC__ */
-Panic(err, fmt, va_alist)
-int err;
-char *fmt;
-va_dcl
-# endif /* __STDC__ */
-{
- static va_list ap;
-#else /* USEVARARRGS */
-/*VARARGS2*/
-Panic(err, fmt, p1, p2, p3, p4, p5, p6)
+#if defined(USEVARARGS) && defined(__STDC__)
+Panic(int err, char *fmt, VA_DOTS)
+#else
+Panic(err, fmt, VA_DOTS)
int err;
char *fmt;
-unsigned long p1, p2, p3, p4, p5, p6;
+VA_DECL
+#endif
{
-#endif /* USEVARARRGS */
+ VA_LIST(ap)
char buf[MAXPATHLEN*2];
char *p = buf;
-#ifdef USEVARARGS
-# if defined(__STDC__)
- va_start(ap, fmt);
-# else /* __STDC__ */
- va_start(ap);
-# endif /* __STDC__ */
- (void) vsnprintf(p, sizeof(buf) - 100, fmt, ap);
- va_end(ap);
-#else /* USEVARARRGS */
- xsnprintf(p, sizeof(buf) - 100, fmt, p1, p2, p3, p4, p5, p6);
-#endif /* USEVARARRGS */
+ VA_START(ap, fmt);
+ fmt = DoNLS(fmt);
+ (void)vsnprintf(p, sizeof(buf) - 100, fmt, VA_ARGS(ap));
+ VA_END(ap);
if (err)
{
p += strlen(p);
- sprintf(p, ": %s", strerror(err));
+ *p++ = ':';
+ *p++ = ' ';
+ strncpy(p, strerror(err), buf + sizeof(buf) - p - 1);
+ buf[sizeof(buf) - 1] = 0;
}
- debug1("Panic('%s');\n", buf);
- if (displays == 0)
+ debug3("Panic('%s'); display=%x displays=%x\n", buf, display, displays);
+ if (displays == 0 && display == 0)
printf("%s\r\n", buf);
+ else if (displays == 0)
+ {
+ /* no displays but a display - must have forked.
+ * send message to backend!
+ */
+ char *tty = D_usertty;
+ display = 0;
+ SendErrorMsg(tty, buf);
+ sleep(2);
+ _exit(1);
+ }
else
for (display = displays; display; display = display->d_next)
{
@@ -2450,7 +1884,7 @@ unsigned long p1, p2, p3, p4, p5, p6;
{
# ifdef USE_SETEUID
if (setuid(own_uid))
- xseteuid(own_uid); /* XXX: may be a loop. sigh. */
+ xseteuid(own_uid); /* may be a loop. sigh. */
# else
setuid(own_uid);
# endif
@@ -2474,21 +1908,30 @@ static const char days[] = "SunMonTueWedThuFriSat";
static const char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
char *
-MakeWinMsg(s, win, esc)
-register char *s;
+MakeWinMsgEv(str, win, esc, ev)
+char *str;
struct win *win;
int esc;
+struct event *ev;
{
static char buf[MAXSTR];
+ static int tick;
+ char *s = str;
register char *p = buf;
register int ctrl;
- time_t now;
+ struct timeval now;
struct tm *tm;
int l;
-
+ int num;
+ int zeroflg;
+ int qmflag = 0, omflag = 0;
+ char *qmpos = 0;
+
+ tick = 0;
tm = 0;
ctrl = 0;
- for (; *s && (l = buf + MAXSTR - 1 - p) > 0; s++, p++, l--)
+ gettimeofday(&now, NULL);
+ for (; *s && (l = buf + MAXSTR - 1 - p) > 0; s++, p++)
{
*p = *s;
if (ctrl)
@@ -2504,9 +1947,11 @@ int esc;
{
switch (*s)
{
+#if 0
case '~':
*p = BELL;
break;
+#endif
case '^':
ctrl = 1;
*p-- = '^';
@@ -2517,88 +1962,224 @@ int esc;
}
continue;
}
- if (s[1] == esc) /* double escape ? */
- {
- s++;
- continue;
- }
- switch (s[1])
+ if (*++s == esc) /* double escape ? */
+ continue;
+ if ((zeroflg = *s == '0') != 0)
+ s++;
+ num = 0;
+ while(*s >= '0' && *s <= '9')
+ num = num * 10 + (*s++ - '0');
+ switch (*s)
{
+ case '?':
+ p--;
+ if (qmpos)
+ {
+ if ((!qmflag && !omflag) || omflag == 1)
+ p = qmpos;
+ qmpos = 0;
+ break;
+ }
+ qmpos = p;
+ qmflag = omflag = 0;
+ break;
+ case ':':
+ p--;
+ if (!qmpos)
+ break;
+ if (qmflag && omflag != 1)
+ {
+ omflag = 1;
+ qmpos = p;
+ }
+ else
+ {
+ p = qmpos;
+ omflag = -1;
+ }
+ break;
case 'd': case 'D': case 'm': case 'M': case 'y': case 'Y':
- case 'a': case 'A': case 's': case 'w': case 'W':
- s++;
+ case 'a': case 'A': case 's': case 'c': case 'C':
if (l < 4)
break;
if (tm == 0)
- {
- (void)time(&now);
- tm = localtime(&now);
- }
+ tm = localtime(&now.tv_sec);
+ qmflag = 1;
switch (*s)
{
case 'd':
sprintf(p, "%02d", tm->tm_mday % 100);
+ tick |= 4;
break;
case 'D':
sprintf(p, "%3.3s", days + 3 * tm->tm_wday);
+ tick |= 4;
break;
case 'm':
sprintf(p, "%02d", tm->tm_mon + 1);
+ tick |= 4;
break;
case 'M':
sprintf(p, "%3.3s", months + 3 * tm->tm_mon);
+ tick |= 4;
break;
case 'y':
sprintf(p, "%02d", tm->tm_year % 100);
+ tick |= 4;
break;
case 'Y':
sprintf(p, "%04d", tm->tm_year + 1900);
+ tick |= 4;
break;
case 'a':
sprintf(p, tm->tm_hour >= 12 ? "pm" : "am");
+ tick |= 4;
break;
case 'A':
sprintf(p, tm->tm_hour >= 12 ? "PM" : "AM");
+ tick |= 4;
break;
case 's':
sprintf(p, "%02d", tm->tm_sec);
+ tick |= 1;
break;
- case 'w':
- sprintf(p, "%2d:%02d", tm->tm_hour, tm->tm_min);
+ case 'c':
+ sprintf(p, zeroflg ? "%02d:%02d" : "%2d:%02d", tm->tm_hour, tm->tm_min);
+ tick |= 2;
break;
- case 'W':
- sprintf(p, "%2d:%02d", (tm->tm_hour + 11) % 12 + 1, tm->tm_min);
+ case 'C':
+ sprintf(p, zeroflg ? "%02d:%02d" : "%2d:%02d", (tm->tm_hour + 11) % 12 + 1, tm->tm_min);
+ tick |= 2;
break;
default:
break;
}
p += strlen(p) - 1;
break;
+ case 'l':
+#ifdef LOADAV
+ *p = 0;
+ if (l > 20)
+ AddLoadav(p);
+ if (*p)
+ {
+ qmflag = 1;
+ p += strlen(p) - 1;
+ }
+ else
+ *p = '?';
+ tick |= 2;
+#else
+ *p = '?';
+#endif
+ p += strlen(p) - 1;
+ break;
+ case 'h':
+ if (win == 0 || win->w_hstatus == 0 || *win->w_hstatus == 0 || str == win->w_hstatus)
+ p--;
+ else
+ {
+ char savebuf[sizeof(buf)];
+ int oldtick = tick;
+
+ *p = 0;
+ strcpy(savebuf, buf);
+ MakeWinMsg(win->w_hstatus, win, '\005');
+ tick |= oldtick; /* small hack... */
+ if (strlen(buf) < l)
+ strcat(savebuf, buf);
+ strcpy(buf, savebuf);
+ if (*p)
+ qmflag = 1;
+ p += strlen(p) - 1;
+ }
+ break;
+ case 'w':
+ case 'W':
+ {
+ struct win *oldfore = 0;
+ if (display)
+ {
+ oldfore = D_fore;
+ D_fore = win;
+ }
+ AddWindows(p, l - 1, *s == 'w' ? 2 : 3, -1);
+ if (display)
+ D_fore = oldfore;
+ }
+ if (*p)
+ qmflag = 1;
+ p += strlen(p) - 1;
+ break;
+ case 'u':
+ *p = 0;
+ if (win)
+ AddOtherUsers(p, l - 1, win);
+ if (*p)
+ qmflag = 1;
+ p += strlen(p) - 1;
+ break;
case 't':
- if (strlen(win->w_title) < l)
+ *p = 0;
+ if (win && strlen(win->w_title) < l)
{
strcpy(p, win->w_title);
- p += strlen(p) - 1;
+ if (*p)
+ qmflag = 1;
}
- /* FALLTHROUGH */
- s++;
+ p += strlen(p) - 1;
break;
case 'n':
s++;
/* FALLTHROUGH */
default:
- if (l > 10)
+ s--;
+ if (l > 10 + num)
{
- sprintf(p, "%d", win->w_number);
+ if (num == 0)
+ num = 1;
+ if (!win)
+ sprintf(p, "%*s", num, num > 1 ? "--" : "-");
+ else
+ sprintf(p, "%*d", num, win->w_number);
+ qmflag = 1;
p += strlen(p) - 1;
}
break;
}
}
+ if (qmpos && !qmflag)
+ p = qmpos + 1;
*p = '\0';
+ if (ev)
+ {
+ evdeq(ev); /* just in case */
+ ev->timeout.tv_sec = 0;
+ ev->timeout.tv_usec = 0;
+ }
+ if (ev && tick)
+ {
+ now.tv_usec = 0;
+ if (tick & 1)
+ now.tv_sec++;
+ else if (tick & 2)
+ now.tv_sec += 60 - (now.tv_sec % 60);
+ else if (tick & 4)
+ now.tv_sec += 3600 - (now.tv_sec % 3600);
+ ev->timeout = now;
+ }
return buf;
}
+char *
+MakeWinMsg(s, win, esc)
+char *s;
+struct win *win;
+int esc;
+{
+ return MakeWinMsgEv(s, win, esc, (struct event *)0);
+}
+
void
DisplaySleep(n)
int n;
@@ -2625,3 +2206,281 @@ int n;
debug1("DisplaySleep(%d) ending\n", n);
}
+
+#ifdef DEBUG
+static void
+fds1(i, j)
+int i, j;
+{
+ while (i < j)
+ {
+ debug1("%d ", i);
+ i++;
+ }
+ if ((j = open("/dev/null", 0)) >= 0)
+ {
+ fds1(i + 1, j);
+ close(j);
+ }
+ else
+ {
+ while (dup(++i) < 0 && errno != EBADF)
+ debug1("%d ", i);
+ debug1(" [%d]\n", i);
+ }
+}
+
+static void
+fds()
+{
+ debug("fds: ");
+ fds1(-1, -1);
+}
+#endif
+
+static void
+serv_read_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ debug("Knock - knock!\n");
+ ReceiveMsg();
+}
+
+static void
+serv_select_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ struct win *p;
+
+ debug("serv_select_fn called\n");
+ /* XXX: messages?? */
+ if (GotSigChld)
+ {
+ SigChldHandler();
+ }
+ if (InterruptPlease)
+ {
+ debug("Backend received interrupt\n");
+ /* This approach is rather questionable in a multi-display
+ * environment */
+ if (fore)
+ {
+ char ibuf = intrc;
+#ifdef PSEUDOS
+ write(W_UWP(fore) ? fore->w_pwin->p_ptyfd : fore->w_ptyfd,
+ &ibuf, 1);
+ debug1("Backend wrote interrupt to %d", fore->w_number);
+ debug1("%s\n", W_UWP(fore) ? " (pseudowin)" : "");
+#else
+ write(fore->w_ptyfd, &ibuf, 1);
+ debug1("Backend wrote interrupt to %d\n", fore->w_number);
+#endif
+ }
+ InterruptPlease = 0;
+ }
+
+ for (display = displays; display; display = display->d_next)
+ {
+ if (D_status_delayed > 0)
+ {
+ D_status_delayed = -1;
+ MakeStatus(D_status_lastmsg);
+ }
+ }
+
+ for (p = windows; p; p = p->w_next)
+ {
+ if (p->w_bell == BELL_FOUND || p->w_bell == BELL_VISUAL)
+ {
+ struct canvas *cv;
+ int visual = p->w_bell == BELL_VISUAL || visual_bell;
+ p->w_bell = BELL_ON;
+ for (display = displays; display; display = display->d_next)
+ {
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ if (cv->c_layer->l_bottom == &p->w_layer)
+ break;
+ if (cv == 0)
+ {
+ p->w_bell = BELL_DONE;
+ D_status_delayed = -1;
+ Msg(0, "%s", MakeWinMsg(BellString, p, '%'));
+ }
+ else if (visual && !D_VB && (!D_status || !D_status_bell))
+ {
+ D_status_delayed = -1;
+ Msg(0, VisualBellString);
+ if (D_status)
+ {
+ D_status_bell = 1;
+ debug1("using vbell timeout %d\n", VBellWait);
+ SetTimeout(&D_statusev, VBellWait * 1000);
+ }
+ }
+ }
+ /* don't annoy the user with two messages */
+ if (p->w_monitor == MON_FOUND)
+ p->w_monitor = MON_DONE;
+ }
+ if (p->w_monitor == MON_FOUND)
+ {
+ struct canvas *cv;
+ p->w_monitor = MON_ON;
+ for (display = displays; display; display = display->d_next)
+ {
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ if (cv->c_layer->l_bottom == &p->w_layer)
+ break;
+ if (cv)
+ continue; /* user already sees window */
+#ifdef MULTIUSER
+ if (!(ACLBYTE(p->w_mon_notify, D_user->u_id) & ACLBIT(D_user->u_id)))
+ continue; /* user doesn't care */
+#endif
+ D_status_delayed = -1;
+ Msg(0, "%s", MakeWinMsg(ActivityString, p, '%'));
+ p->w_monitor = MON_DONE;
+ }
+ }
+ }
+
+ for (display = displays; display; display = display->d_next)
+ {
+ struct canvas *cv;
+ if (D_status == STATUS_ON_WIN)
+ continue;
+ /* XXX: should use display functions! */
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ {
+ int lx, ly;
+
+ /* normalize window, see resize.c */
+ lx = cv->c_layer->l_x;
+ ly = cv->c_layer->l_y;
+ if (lx == cv->c_layer->l_width)
+ lx--;
+ if (ly + cv->c_yoff < cv->c_ys)
+ {
+ int i, n = cv->c_ys - (ly + cv->c_yoff);
+ cv->c_yoff = cv->c_ys - ly;
+ RethinkViewportOffsets(cv);
+ if (n > cv->c_layer->l_height)
+ n = cv->c_layer->l_height;
+ CV_CALL(cv,
+ LScrollV(flayer, -n, 0, flayer->l_height - 1);
+ RedisplayLine(-1, -1, -1, 1);
+ for (i = 0; i < n; i++)
+ RedisplayLine(i, 0, flayer->l_width - 1, 1);
+ if (cv == cv->c_display->d_forecv)
+ SetCursor();
+ );
+ }
+ else if (ly + cv->c_yoff > cv->c_ye)
+ {
+ int i, n = ly + cv->c_yoff - cv->c_ye;
+ cv->c_yoff = cv->c_ye - ly;
+ RethinkViewportOffsets(cv);
+ if (n > cv->c_layer->l_height)
+ n = cv->c_layer->l_height;
+ CV_CALL(cv,
+ LScrollV(flayer, n, 0, cv->c_layer->l_height - 1);
+ RedisplayLine(-1, -1, -1, 1);
+ for (i = 0; i < n; i++)
+ RedisplayLine(i + flayer->l_height - n, 0, flayer->l_width - 1, 1);
+ if (cv == cv->c_display->d_forecv)
+ SetCursor();
+ );
+ }
+ if (lx + cv->c_xoff < cv->c_xs)
+ {
+ int i, n = cv->c_xs - (lx + cv->c_xoff);
+ if (n < (cv->c_xe - cv->c_xs + 1) / 2)
+ n = (cv->c_xe - cv->c_xs + 1) / 2;
+ if (cv->c_xoff + n > cv->c_xs)
+ n = cv->c_xs - cv->c_xoff;
+ cv->c_xoff += n;
+ RethinkViewportOffsets(cv);
+ if (n > cv->c_layer->l_width)
+ n = cv->c_layer->l_width;
+ CV_CALL(cv,
+ RedisplayLine(-1, -1, -1, 1);
+ for (i = 0; i < flayer->l_height; i++)
+ {
+ LScrollH(flayer, -n, i, 0, flayer->l_width - 1, 0);
+ RedisplayLine(i, 0, n - 1, 1);
+ }
+ if (cv == cv->c_display->d_forecv)
+ SetCursor();
+ );
+ }
+ else if (lx + cv->c_xoff > cv->c_xe)
+ {
+ int i, n = lx + cv->c_xoff - cv->c_xe;
+ if (n < (cv->c_xe - cv->c_xs + 1) / 2)
+ n = (cv->c_xe - cv->c_xs + 1) / 2;
+ if (cv->c_xoff - n + cv->c_layer->l_width - 1 < cv->c_xe)
+ n = cv->c_xoff + cv->c_layer->l_width - 1 - cv->c_xe;
+ cv->c_xoff -= n;
+ RethinkViewportOffsets(cv);
+ if (n > cv->c_layer->l_width)
+ n = cv->c_layer->l_width;
+ CV_CALL(cv,
+ RedisplayLine(-1, -1, -1, 1);
+ for (i = 0; i < flayer->l_height; i++)
+ {
+ LScrollH(flayer, n, i, 0, flayer->l_width - 1, 0);
+ RedisplayLine(i, flayer->l_width - n, flayer->l_width - 1, 1);
+ }
+ if (cv == cv->c_display->d_forecv)
+ SetCursor();
+ );
+ }
+ }
+ }
+
+ for (display = displays; display; display = display->d_next)
+ {
+ if (D_status == STATUS_ON_WIN || D_cvlist == 0 || D_cvlist->c_next == 0)
+ continue;
+ debug1("serv_select_fn: Restore on cv %#x\n", (int)D_forecv);
+ CV_CALL(D_forecv, Restore();SetCursor());
+ }
+}
+
+static void
+logflush_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ struct win *p;
+ char *buf;
+ int n;
+
+ if (!islogfile(NULL))
+ return; /* no more logfiles */
+ logfflush(NULL);
+ n = log_flush ? log_flush : (logtstamp_after + 4) / 5;
+ if (n)
+ {
+ SetTimeout(ev, n * 1000);
+ evenq(ev); /* re-enqueue ourself */
+ }
+ if (!logtstamp_on)
+ return;
+ /* write fancy time-stamp */
+ for (p = windows; p; p = p->w_next)
+ {
+ if (!p->w_log)
+ continue;
+ p->w_logsilence += n;
+ if (p->w_logsilence < logtstamp_after)
+ continue;
+ if (p->w_logsilence - n >= logtstamp_after)
+ continue;
+ buf = MakeWinMsg(logtstamp_string, p, '%');
+ logfwrite(p->w_log, buf, strlen(buf));
+ }
+}
+
diff --git a/screen.h b/screen.h
index 72b6697..ae6155d 100644
--- a/screen.h
+++ b/screen.h
@@ -38,24 +38,33 @@
#include "osdef.h"
#include "ansi.h"
+#include "sched.h"
#include "acls.h"
#include "comm.h"
-#include "overlay.h"
+#include "layer.h"
#include "term.h"
#ifdef DEBUG
-# define DEBUGDIR "/tmp/debug"
-# define debug(x) {if(dfp){fprintf(dfp,x);fflush(dfp);}}
-# define debug1(x,a) {if(dfp){fprintf(dfp,x,a);fflush(dfp);}}
-# define debug2(x,a,b) {if(dfp){fprintf(dfp,x,a,b);fflush(dfp);}}
-# define debug3(x,a,b,c) {if(dfp){fprintf(dfp,x,a,b,c);fflush(dfp);}}
- extern FILE *dfp;
+# define STATIC /* a function that the debugger should see */
#else
-# define debug(x) {}
-# define debug1(x,a) {}
-# define debug2(x,a,b) {}
-# define debug3(x,a,b,c) {}
+# define STATIC static
+#endif
+
+#ifdef DEBUG
+# define DEBUGDIR "/tmp/debug"
+# define debugf(a) do {if(dfp){fprintf a;fflush(dfp);}} while (0)
+# define debug(x) debugf((dfp,x))
+# define debug1(x,a) debugf((dfp,x,a))
+# define debug2(x,a,b) debugf((dfp,x,a,b))
+# define debug3(x,a,b,c) debugf((dfp,x,a,b,c))
+ extern FILE *dfp;
+#else
+# define debugf(a) do {} while (0)
+# define debug(x) debugf(x)
+# define debug1(x,a) debugf(x)
+# define debug2(x,a,b) debugf(x)
+# define debug3(x,a,b,c) debugf(x)
#endif
#ifndef DEBUG
@@ -69,7 +78,7 @@
# define ASSERT(lousy_cpp) do {if (!(lousy_cpp)) {if (!dfp) opendebug(0, 1);debug2("ASSERT(lousy_cpp) failed file %s line %d\n", __FILE__, __LINE__);abort();}} while (0)
# endif
#else
-# define ASSERT(lousy_cpp) {;}
+# define ASSERT(lousy_cpp) do {} while (0)
#endif
/* here comes my own Free: jw. */
@@ -89,22 +98,24 @@
*/
#define MAXHISTHEIGHT 3000
#define DEFAULTHISTHEIGHT 100
-#define DEFAULT_BUFFERFILE "/tmp/screen-exchange"
+#ifdef NAME_MAX
+# define DEFAULT_BUFFERFILE "/tmp/screen-xchg"
+#else
+# define DEFAULT_BUFFERFILE "/tmp/screen-exchange"
+#endif
-#define TTY_FLAG_PLAIN 0x01
-struct tty_attr
-{
- int flags; /* a PLAIN tty or a process behind */
-};
+#if defined(hpux) && !(defined(VSUSP) && defined(VDSUSP) && defined(VWERASE) && defined(VLNEXT))
+# define HPUX_LTCHARS_HACK
+#endif
struct mode
{
#ifdef POSIX
struct termios tio;
-# ifdef hpux
+# ifdef HPUX_LTCHARS_HACK
struct ltchars m_ltchars;
-# endif /* hpux */
+# endif /* HPUX_LTCHARS_HACK */
#else /* POSIX */
# ifdef TERMIO
struct termio tio;
@@ -120,13 +131,15 @@ struct mode
int m_ldisc;
int m_lmode;
# endif /* TERMIO */
-#if defined(KANJI) && defined(TIOCKSET) && defined(KM_ASCII) && defined(KM_SYSSJIS)
+#if defined(KANJI) && defined(TIOCKSET)
struct jtchars m_jtchars;
int m_knjmode;
# endif
#endif /* POSIX */
};
+
+/* #include "logfile.h" */ /* (requires stat.h) struct logfile */
#include "image.h"
#include "display.h"
#include "window.h"
@@ -153,8 +166,15 @@ struct mode
#define MSG_WINCH 6
#define MSG_HANGUP 7
+/*
+ * versions of struct msg:
+ * 0: screen version 3.6.6 (version count introduced)
+ */
+#define MSG_VERSION 0
+#define MSG_REVISION (('m'<<24) | ('s'<<16) | ('g'<<8) | MSG_VERSION)
struct msg
{
+ int protocol_revision; /* reduce harm done by incompatible messages */
int type;
char m_tty[MAXPATHLEN]; /* ttyname */
union
@@ -177,14 +197,15 @@ struct msg
int apid; /* pid of frontend */
int adaptflag; /* adapt window size? */
int lines, columns; /* display size */
- char password[20];
+ char preselect[20];
+ int esc; /* his new escape character unless -1 */
+ int meta_esc; /* his new meta esc character unless -1 */
char envterm[20 + 1]; /* terminal type */
}
attach;
struct
{
char duser[20 + 1]; /* username */
- char password[20];
int dpid; /* pid of frontend */
}
detach;
@@ -199,29 +220,32 @@ struct msg
#define SIG_POWER_BYE SIGUSR1
#define SIG_LOCK SIGUSR2
#define SIG_STOP SIGTSTP
-#define SIG_PW_OK SIGUSR1
-#define SIG_PW_FAIL SIG_BYE
+#ifdef SIGIO
+#define SIG_NODEBUG SIGIO /* triggerd by command 'debug off' */
+#endif
#define BELL (Ctrl('g'))
#define VBELLWAIT 1 /* No. of seconds a vbell will be displayed */
-#define BELL_OFF 0 /* No bell has occurred in the window */
-#define BELL_ON 1 /* A bell has occurred, but user not yet notified */
-#define BELL_MSG 2 /* A bell has occured, user sees a message */
-#define BELL_DONE 3 /* A bell has occured, user has been notified */
-#define BELL_VISUAL 4 /* A bell has occured in fore win, notify him visually */
+#define BELL_ON 0 /* No bell has occurred in the window */
+#define BELL_FOUND 1 /* A bell has occurred, but user not yet notified */
+#define BELL_DONE 2 /* A bell has occured, user has been notified */
+
+#define BELL_VISUAL 3 /* A bell has occured in fore win, notify him visually */
#define MON_OFF 0 /* Monitoring is off in the window */
#define MON_ON 1 /* No activity has occurred in the window */
#define MON_FOUND 2 /* Activity has occured, but user not yet notified */
-#define MON_MSG 3 /* Activity has occured, user sees a message */
-#define MON_DONE 4 /* Activity has occured, user has been notified */
+#define MON_DONE 3 /* Activity has occured, user has been notified */
#define DUMP_TERMCAP 0 /* WriteFile() options */
#define DUMP_HARDCOPY 1
#define DUMP_EXCHANGE 2
+#define SILENCE_OFF 0
+#define SILENCE_ON 1
+
extern char strnomem[];
/*
@@ -249,3 +273,9 @@ struct plop
int len;
};
+struct baud_values
+{
+ int idx; /* the index in the bsd-is padding lookup table */
+ int bps; /* bits per seconds */
+ int sym; /* symbol defined in ttydev.h */
+};
diff --git a/search.c b/search.c
index 513dc32..51730ae 100644
--- a/search.c
+++ b/search.c
@@ -31,10 +31,12 @@ RCS_ID("$Id: search.c,v 1.2 1994/05/31 12:32:57 mlschroe Exp $ FAU")
#include "mark.h"
#include "extern.h"
-#ifdef COPY_PASTE
+#define INPUTLINE (flayer->l_height - 1)
+extern struct layer *flayer;
extern struct win *fore;
-extern struct display *display;
+
+#ifdef COPY_PASTE
/********************************************************************
* VI style Search
@@ -51,13 +53,13 @@ int dir;
struct markdata *markdata;
if (dir == 0)
{
- markdata = (struct markdata *)D_lay->l_data;
+ markdata = (struct markdata *)flayer->l_data;
if (markdata->isdir > 0)
searchend(0, 0, NULL);
else if (markdata->isdir < 0)
backsearchend(0, 0, NULL);
else
- Msg(0, "No previous pattern");
+ LMsg(0, "No previous pattern");
}
else
Input((dir > 0 ? "/" : "?"), sizeof(markdata->isstr)-1, INP_COOKED,
@@ -72,22 +74,24 @@ char *data; /* dummy */
{
int x = 0, sx, ex, y;
struct markdata *markdata;
+ struct win *p;
- markdata = (struct markdata *)D_lay->l_data;
+ markdata = (struct markdata *)flayer->l_data;
+ p = markdata->md_window;
markdata->isdir = 1;
if (len)
strcpy(markdata->isstr, buf);
sx = markdata->cx + 1;
- ex = D_width - 1;
- for (y = markdata->cy; y < fore->w_histheight + D_height; y++, sx = 0)
+ ex = flayer->l_width - 1;
+ for (y = markdata->cy; y < p->w_histheight + flayer->l_height; y++, sx = 0)
{
if ((x = matchword(markdata->isstr, y, sx, ex)) >= 0)
break;
}
- if (y >= fore->w_histheight + D_height)
+ if (y >= p->w_histheight + flayer->l_height)
{
- GotoPos(markdata->cx, W2D(markdata->cy));
- Msg(0, "Pattern not found");
+ LGotoPos(flayer, markdata->cx, W2D(markdata->cy));
+ LMsg(0, "Pattern not found");
}
else
revto(x, y);
@@ -102,12 +106,12 @@ char *data; /* dummy */
int sx, ex, x = -1, y;
struct markdata *markdata;
- markdata = (struct markdata *)D_lay->l_data;
+ markdata = (struct markdata *)flayer->l_data;
markdata->isdir = -1;
if (len)
strcpy(markdata->isstr, buf);
ex = markdata->cx - 1;
- for (y = markdata->cy; y >= 0; y--, ex = D_width - 1)
+ for (y = markdata->cy; y >= 0; y--, ex = flayer->l_width - 1)
{
sx = 0;
while ((sx = matchword(markdata->isstr, y, sx, ex)) >= 0)
@@ -117,8 +121,8 @@ char *data; /* dummy */
}
if (y < 0)
{
- GotoPos(markdata->cx, W2D(markdata->cy));
- Msg(0, "Pattern not found");
+ LGotoPos(flayer, markdata->cx, W2D(markdata->cy));
+ LMsg(0, "Pattern not found");
}
else
revto(x, y);
@@ -132,9 +136,12 @@ int y, sx, ex;
char *ip, *ipe, *cp, *pp;
struct mline *ml;
+ /* *sigh* to make WIN work */
+ fore = ((struct markdata *)flayer->l_data)->md_window;
+
ml = WIN(y);
ip = ml->image + sx;
- ipe = ml->image + D_width;
+ ipe = ml->image + flayer->l_width;
for (;sx <= ex; sx++)
{
cp = ip++;
@@ -172,8 +179,10 @@ int l, p, end, dir;
int tab[256];
int i, q;
char *s, c;
- int w = D_width;
+ int w = flayer->l_width;
+ /* *sigh* to make WIN work */
+ fore = ((struct markdata *)flayer->l_next->l_data)->md_window;
debug2("is_bm: searching for %s len %d\n", str, l);
debug3("start at %d end %d dir %d\n", p, end, dir);
if (p < 0 || p + l > end)
@@ -222,11 +231,11 @@ char *data; /* dummy */
if (n == 0)
return;
- markdata = (struct markdata *)D_lay->l_next->l_data;
ASSERT(p);
+ markdata = (struct markdata *)flayer->l_next->l_data;
- pos = markdata->cx + markdata->cy * D_width;
- GotoPos(markdata->cx, W2D(markdata->cy));
+ pos = markdata->cx + markdata->cy * flayer->l_width;
+ LGotoPos(flayer, markdata->cx, W2D(markdata->cy));
switch (*p)
{
@@ -273,22 +282,30 @@ char *data; /* dummy */
debug2("New char: %c - left %d\n", *p, (int)sizeof(markdata->isistr) - markdata->isistrl);
}
if (*p && *p != '\b')
- pos = is_bm(markdata->isstr, markdata->isstrl, pos, D_width * (fore->w_histheight + D_height), markdata->isdir);
+ pos = is_bm(markdata->isstr, markdata->isstrl, pos, flayer->l_width * (markdata->md_window->w_histheight + flayer->l_height), markdata->isdir);
if (pos >= 0)
{
- x = pos % D_width;
- y = pos / D_width;
+ x = pos % flayer->l_width;
+ y = pos / flayer->l_width;
LAY_CALL_UP
(
- RefreshLine(STATLINE, 0, D_width - 1, 0);
+ RedisplayLine(INPUTLINE, 0, flayer->l_width - 1, 0);
revto(x, y);
- if (W2D(markdata->cy) == STATLINE)
- revto_line(markdata->cx, markdata->cy, STATLINE > 0 ? STATLINE - 1 : 1);
+ if (W2D(markdata->cy) == INPUTLINE)
+ revto_line(markdata->cx, markdata->cy, INPUTLINE > 0 ? INPUTLINE - 1 : 1);
);
}
if (*p)
inp_setprompt(isprompts[markdata->isdir + (pos < 0) + 1], markdata->isstrl ? markdata->isstr : "");
- GotoPos(markdata->cx, W2D(markdata->cy));
+ flayer->l_x = markdata->cx;
+ flayer->l_y = W2D(markdata->cy);
+ LGotoPos(flayer, flayer->l_x, flayer->l_y);
+ if (!*p)
+ {
+ /* we are about to finish, keep cursor position */
+ flayer->l_next->l_x = markdata->cx;
+ flayer->l_next->l_y = W2D(markdata->cy);
+ }
}
static int
@@ -312,7 +329,7 @@ struct markdata *markdata;
markdata->isstr[markdata->isstrl++] = c;
if (pos >= 0)
{
- npos = is_bm(markdata->isstr, markdata->isstrl, pos, D_width * (fore->w_histheight + D_height), dir);
+ npos = is_bm(markdata->isstr, markdata->isstrl, pos, flayer->l_width * (markdata->md_window->w_histheight + flayer->l_height), dir);
if (npos >= 0)
pos = npos;
}
@@ -328,15 +345,17 @@ int dir;
{
struct markdata *markdata;
- markdata = (struct markdata *)D_lay->l_data;
+ markdata = (struct markdata *)flayer->l_data;
markdata->isdir = markdata->isstartdir = dir;
- markdata->isstartpos = markdata->cx + markdata->cy * D_width;
+ markdata->isstartpos = markdata->cx + markdata->cy * flayer->l_width;
markdata->isistrl = markdata->isstrl = 0;
- if (W2D(markdata->cy) == STATLINE)
- revto_line(markdata->cx, markdata->cy, STATLINE > 0 ? STATLINE - 1 : 1);
+ if (W2D(markdata->cy) == INPUTLINE)
+ revto_line(markdata->cx, markdata->cy, INPUTLINE > 0 ? INPUTLINE - 1 : 1);
Input(isprompts[dir + 1], sizeof(markdata->isstr) - 1, INP_RAW,
is_process, NULL);
- GotoPos(markdata->cx, W2D(markdata->cy));
+ LGotoPos(flayer, markdata->cx, W2D(markdata->cy));
+ flayer->l_x = markdata->cx;
+ flayer->l_y = W2D(markdata->cy);
}
#endif /* COPY_PASTE */
diff --git a/socket.c b/socket.c
index 0b93cb1..ad133a7 100644
--- a/socket.c
+++ b/socket.c
@@ -39,7 +39,7 @@ RCS_ID("$Id: socket.c,v 1.23 1994/05/31 12:33:00 mlschroe Exp $ FAU")
#include "screen.h"
-#ifdef DIRENT
+#ifdef HAVE_DIRENT_H
# include <dirent.h>
#else
# include <sys/dir.h>
@@ -54,6 +54,8 @@ static void ExecCreate __P((struct msg *));
# define connect sconnect /* _SEQUENT_ has braindamaged connect */
static int sconnect __P((int, struct sockaddr *, int));
#endif
+static void FinishAttach __P((struct msg *));
+static void AskPassword __P((struct msg *));
extern char *RcFileName, *extra_incap, *extra_outcap;
@@ -63,20 +65,14 @@ extern char *attach_tty, *LoginName, HostName[];
extern struct display *display, *displays;
extern struct win *fore, *wtab[], *console_window, *windows;
extern struct NewWindow nwin_undef;
-#ifdef NETHACK
-extern nethackflag;
-#endif
#ifdef MULTIUSER
extern char *multi;
#endif
-#ifdef PASSWORD
-extern int CheckPassword;
-extern char Password[];
-#endif
extern char *getenv();
extern char SockPath[];
+extern struct event serv_read;
#ifdef MULTIUSER
# define SOCKMODE (S_IWRITE | S_IREAD | (displays ? S_IEXEC : 0) | (multi ? 1 : 0))
@@ -89,18 +85,20 @@ extern char SockPath[];
* Socket directory manager
*
* fdp: pointer to store the first good socket.
- * nfoundp: pointer to store the number of sockets found.
+ * nfoundp: pointer to store the number of sockets found matching.
+ * notherp: pointer to store the number of sockets not matching.
* match: string to match socket name.
*
* The socket directory must be in SockPath!
- * The global variables LoginName, multi, rflag, xflag, dflag, quietflag,
- * nethackflag, SockPath are used.
- *
+ * The global variables LoginName, multi, rflag, xflag, dflag,
+ * quietflag, SockPath are used.
+ *
* The first good socket is stored in fdp and its name is
* appended to SockPath.
* If none exists or fdp is NULL SockPath is not changed.
*
* Returns: number of good sockets.
+ *
*/
int
@@ -117,7 +115,7 @@ char *match;
int matchlen = 0;
char *name, *n;
int firsts = -1, sockfd;
- char *firstn = 0;
+ char *firstn = NULL;
int nfound = 0, ngood = 0, ndead = 0, nwipe = 0, npriv = 0;
struct sent
{
@@ -148,7 +146,7 @@ char *match;
#endif
if ((dirp = opendir(SockPath)) == 0)
- Panic(errno, "Cannot opendir %s\n", SockPath);
+ Panic(errno, "Cannot opendir %s", SockPath);
slist = 0;
slisttail = &slist;
@@ -161,7 +159,7 @@ char *match;
if (matchlen)
{
n = name;
- /* if we don't want to match digits swip them */
+ /* if we don't want to match digits. Skip them */
if ((*match <= '0' || *match > '9') && (*n > '0' && *n <= '9'))
{
while (*n >= '0' && *n <= '9')
@@ -180,10 +178,10 @@ char *match;
debug1("stat %s\n", SockPath);
errno = 0;
- debug2("uid = %d, gid = %d\n", (int)getuid(), (int)getgid());
- debug2("euid = %d, egid = %d\n", (int)geteuid(), (int)getegid());
+ debug2("uid = %d, gid = %d\n", getuid(), getgid());
+ debug2("euid = %d, egid = %d\n", geteuid(), getegid());
if (stat(SockPath, &st))
- {
+ {
debug1("errno = %d\n", errno);
continue;
}
@@ -191,23 +189,25 @@ char *match;
#ifndef SOCK_NOT_IN_FS
# ifdef NAMEDPIPE
# ifdef S_ISFIFO
+ debug("S_ISFIFO?\n");
if (!S_ISFIFO(st.st_mode))
continue;
# endif
# else
# ifdef S_ISSOCK
+ debug("S_ISSOCK?\n");
if (!S_ISSOCK(st.st_mode))
continue;
# endif
# endif
#endif
- debug2("st.st_uid = %d, real_uid = %d\n", (int)st.st_uid, real_uid);
+ debug2("st.st_uid = %d, real_uid = %d\n", st.st_uid, real_uid);
if (st.st_uid != real_uid)
continue;
- mode = st.st_mode & 0777;
+ mode = (int)st.st_mode & 0777;
debug1(" has mode 0%03o\n", mode);
-#ifdef MULTIUSER
+#ifdef MULTIUSER
if (multi && ((mode & 0677) != 0601))
{
debug(" is not a MULTI-USER session");
@@ -240,7 +240,7 @@ char *match;
if (sockfd == -1)
{
debug2(" MakeClientSocket failed, unreachable? %d %d\n",
- matchlen, wipeflag);
+ matchlen, wipeflag);
sent->mode = -3;
/* Unreachable - it is dead if we detect that it's local
* or we specified a match
@@ -261,7 +261,7 @@ char *match;
}
}
}
- npriv++;
+ npriv++; /* a good socket that was not for us */
continue;
}
@@ -275,13 +275,13 @@ char *match;
* mode 700: socket is attached.
* xflag implies rflag here.
*
- * fail, when socket mode is not 600 or 700
+ * fail, when socket mode mode is not 600 or 700
* fail, when we want to detach w/o reattach, but it already is detached.
* fail, when we only want to attach, but mode 700 and not xflag.
* fail, if none of dflag, rflag, xflag is set.
*/
if ((mode != 0700 && mode != 0600) ||
- (dflag && !rflag && mode == 0600) ||
+ (dflag && !rflag && !xflag && mode == 0600) ||
(!dflag && rflag && mode == 0700 && !xflag) ||
(!dflag && !rflag && !xflag))
{
@@ -295,13 +295,13 @@ char *match;
{
firsts = sockfd;
firstn = sent->name;
- debug(" taken\n");
+ debug(" taken.\n");
}
else
{
debug(" discarded.\n");
close(sockfd);
- }
+ }
}
(void)closedir(dirp);
if (nfound && (lsflag || ngood != 1) && !quietflag)
@@ -309,28 +309,14 @@ char *match;
switch(ngood)
{
case 0:
-#ifdef NETHACK
- if (nethackflag)
- printf(lsflag ? "Your inventory:\n" : "Nothing fitting exists in the game:\n");
- else
-#endif
- printf(nfound > 1 ? "There are screens on:\n" : "There is a screen on:\n");
+ Msg(0, nfound > 1 ? "There are screens on:" : "There is a screen on:");
break;
case 1:
-#ifdef NETHACK
- if (nethackflag)
- printf(nfound > 1 ? "Prove thyself worthy or perish:\n" : "You see here a good looking screen:\n");
- else
-#endif
- printf(nfound > 1 ? "There are several screens on:\n" : "There is a possible screen on:\n");
+ Msg(0, nfound > 1 ? "There are several screens on:" : "There is a suitable screen on:");
break;
default:
-#ifdef NETHACK
- if (nethackflag)
- printf("You may wish for a screen, what do you want?\n");
- else
-#endif
- printf("There are several screens on:\n");
+ Msg(0, "There are several suitable screens on:");
+ break;
}
for (sent = slist; sent; sent = sent->next)
{
@@ -359,6 +345,7 @@ char *match;
break;
case -3:
printf("\t%s\t(Remote or dead)\n", sent->name);
+ break;
case -4:
printf("\t%s\t(Private)\n", sent->name);
break;
@@ -368,25 +355,9 @@ char *match;
if (ndead && !quietflag)
{
if (wipeflag)
- {
-#ifdef NETHACK
- if (nethackflag)
- printf("You hear%s distant explosion%s.\n",
- ndead > 1 ? "" : " a", ndead > 1 ? "s" : "");
- else
-#endif
- printf("%d socket%s wiped out.\n", nwipe, ndead > 1 ? "s" : "");
- }
+ Msg(0, "%d socket%s wiped out.", nwipe, nwipe > 1 ? "s" : "");
else
- {
-#ifdef NETHACK
- if (nethackflag)
- printf("The dead screen%s touch%s you. Try 'screen -wipe'.\n",
- ndead > 1 ? "s" : "", ndead > 1 ? "" : "es");
- else
-#endif
- printf("Remove dead screens with 'screen -wipe'.\n");
- }
+ Msg(0, "Remove dead screens with 'screen -wipe'.", ndead > 1 ? "s" : "", ndead > 1 ? "" : "es"); /* other args for nethack */
}
if (firsts != -1)
{
@@ -677,87 +648,34 @@ struct NewWindow *nwin;
if (nwin->term != nwin_undef.term)
strncpy(m.m.create.screenterm, nwin->term, 19);
m.m.create.screenterm[19] = '\0';
+ m.protocol_revision = MSG_REVISION;
debug1("SendCreateMsg writing '%s'\n", m.m.create.line);
if (write(s, (char *) &m, sizeof m) != sizeof m)
Msg(errno, "write");
close(s);
}
-void
-#ifdef USEVARARGS
-/*VARARGS1*/
-# if defined(__STDC__)
-SendErrorMsg(char *fmt, ...)
-# else /* __STDC__ */
-SendErrorMsg(fmt, va_alist)
-char *fmt;
-va_dcl
-# endif /* __STDC__ */
-{ /* } */
- static va_list ap;
-#else /* USEVARARGS */
-/*VARARGS1*/
-SendErrorMsg(fmt, p1, p2, p3, p4, p5, p6)
-char *fmt;
-unsigned long p1, p2, p3, p4, p5, p6;
+int
+SendErrorMsg(tty, buf)
+char *tty, *buf;
{
-#endif /* USEVARARGS */
- register int s;
+ int s;
struct msg m;
-#ifdef USEVARARGS
-# if defined(__STDC__)
- va_start(ap, fmt);
-# else /* __STDC__ */
- va_start(ap);
-# endif /* __STDC__ */
- (void) vsnprintf(m.m.message, sizeof(m.m.message), fmt, ap);
- va_end(ap);
-#else /* USEVARARGS */
- xsnprintf(m.m.message, sizeof(m.m.message), fmt, p1, p2, p3, p4, p5, p6);
-#endif /* USEVARARGS */
- debug1("SendErrorMsg: '%s'\n", m.m.message);
- if (display == 0)
- return;
+ strncpy(m.m.message, buf, sizeof(m.m.message) - 1);
+ m.m.message[sizeof(m.m.message) - 1] = 0;
s = MakeClientSocket(0);
+ if (s < 0)
+ return -1;
m.type = MSG_ERROR;
- strncpy(m.m_tty, D_usertty, sizeof(m.m_tty) - 1);
+ strncpy(m.m_tty, tty, sizeof(m.m_tty) - 1);
m.m_tty[sizeof(m.m_tty) - 1] = 0;
+ m.protocol_revision = MSG_REVISION;
debug1("SendErrorMsg(): writing to '%s'\n", SockPath);
(void) write(s, (char *) &m, sizeof m);
close(s);
- sleep(2);
-}
-
-
-#ifdef PASSWORD
-static int
-CheckPasswd(pwd, pid, utty)
-int pid;
-char *pwd, *utty;
-{
- if (CheckPassword && *Password &&
- strncmp(crypt(pwd, (strlen(Password) > 1) ? Password : "JW"), Password, strlen(Password)))
- {
- if (*pwd)
- {
-# ifdef NETHACK
- if (nethackflag)
- Msg(0, "'%s' tries to explode in the sky, but fails.", utty);
- else
-# endif /* NETHACK */
- Msg(0, "Illegal reattach attempt from terminal %s.", utty);
- }
- debug1("CheckPass() wrong password kill(%d, SIG_PW_FAIL)\n", pid);
- Kill(pid, SIG_PW_FAIL);
- return 0;
- }
- debug1("CheckPass() from %d happy\n", pid);
- Kill(pid, SIG_PW_OK);
- return 1;
+ return 0;
}
-#endif /* PASSWORD */
-
static void
ExecCreate(mp)
@@ -865,6 +783,7 @@ ReceiveMsg()
#ifdef REMOTE_DETACH
struct display *next;
#endif
+ struct display *olddisplays = displays;
#ifdef NAMEDPIPE
debug("Ha, there was someone knocking on my fifo??\n");
@@ -901,6 +820,9 @@ ReceiveMsg()
close(ServerSocket);
if ((ServerSocket = secopen(SockPath, O_RDONLY | O_NONBLOCK, 0)) < 0)
Panic(errno, "reopen fifo %s", SockPath);
+ evdeq(&serv_read);
+ serv_read.fd = ServerSocket;
+ evenq(&serv_read);
# endif
#else
close(ns);
@@ -919,6 +841,12 @@ ReceiveMsg()
debug("No data on socket.\n");
return;
}
+ if (m.protocol_revision != MSG_REVISION)
+ {
+ Msg(0, "Invalid message (magic 0x%08x).", m.protocol_revision);
+ return;
+ }
+
debug2("*** RecMsg: type %d tty %s\n", m.type, m.m_tty);
for (display = displays; display; display = display->d_next)
if (TTYCMP(D_usertty, m.m_tty) == 0)
@@ -930,7 +858,8 @@ ReceiveMsg()
for (wi = windows; wi; wi = wi->w_next)
if (!TTYCMP(m.m_tty, wi->w_tty))
{
- display = wi->w_display;
+ /* XXX: hmmm, rework this? */
+ display = wi->w_layer.l_cvlist ? wi->w_layer.l_cvlist->c_display : 0;
debug2("but window %s %sfound.\n", m.m_tty, display ? "" :
"(backfacing)");
break;
@@ -941,6 +870,9 @@ ReceiveMsg()
if (display && D_status)
RemoveStatus();
+ if (display && !D_tcinited && m.type != MSG_HANGUP)
+ return; /* ignore messages for bad displays */
+
switch (m.type)
{
case MSG_WINCH:
@@ -964,6 +896,7 @@ ReceiveMsg()
break; /* Intruder Alert */
debug2("RecMsg: apid=%d,was %d\n", m.m.attach.apid, display ? D_userpid : 0);
/* FALLTHROUGH */
+
case MSG_ATTACH:
if (CheckPid(m.m.attach.apid))
{
@@ -976,19 +909,14 @@ ReceiveMsg()
Kill(m.m.attach.apid, SIG_BYE);
break;
}
-#ifdef PASSWORD
- if (!CheckPasswd(m.m.attach.password, m.m.attach.apid, m.m_tty))
- {
- debug3("RcvMsg:Checkpass(%s,%d,%s) failed\n",
- m.m.attach.password, m.m.attach.apid, m.m_tty);
- close(i);
- break;
- }
-#else
# ifdef MULTIUSER
Kill(m.m.attach.apid, SIGCONT);
# endif
-#endif /* PASSWORD */
+
+#if defined(ultrix) || defined(pyr) || defined(NeXT)
+ brktty(i); /* for some strange reason this must be done */
+#endif
+
if (display || wi)
{
write(i, "Attaching from inside of screen?\n", 33);
@@ -1011,19 +939,6 @@ ReceiveMsg()
#endif
debug2("RecMsg: apid %d is o.k. and we just opened '%s'\n", m.m.attach.apid, m.m_tty);
- /* turn off iflag on a multi-attach... */
- if (iflag && displays)
- {
- iflag = 0;
- display = displays;
-#if defined(TERMIO) || defined(POSIX)
- D_NewMode.tio.c_cc[VINTR] = VDISABLE;
- D_NewMode.tio.c_lflag &= ~ISIG;
-#else /* TERMIO || POSIX */
- D_NewMode.m_tchars.t_intrc = -1;
-#endif /* TERMIO || POSIX */
- SetTTY(D_userfd, &D_NewMode);
- }
/* create new display */
GetTTY(i, &Mode);
@@ -1035,110 +950,29 @@ ReceiveMsg()
Kill(m.m.attach.apid, SIG_BYE);
break;
}
-#if defined(ultrix) || defined(pyr) || defined(NeXT)
- brktty(D_userfd); /* for some strange reason this must be done */
-#endif
-#if defined(pyr) || defined(xelos) || defined(sequent)
- /*
- * Kludge for systems with braindamaged termcap routines,
- * which evaluate $TERMCAP, regardless weather it describes
- * the correct terminal type or not.
- */
- debug("unsetenv(TERMCAP) in case of a different terminal");
- unsetenv("TERMCAP");
-#endif
-
- /*
- * We reboot our Terminal Emulator. Forget all we knew about
- * the old terminal, reread the termcap entries in .screenrc
- * (and nothing more from .screenrc is read. Mainly because
- * I did not check, weather a full reinit is save. jw)
- * and /etc/screenrc, and initialise anew.
- */
- if (extra_outcap)
- free(extra_outcap);
- if (extra_incap)
- free(extra_incap);
- extra_incap = extra_outcap = 0;
- debug2("Message says size (%dx%d)\n", m.m.attach.columns, m.m.attach.lines);
-#ifdef ETCSCREENRC
-# ifdef ALLOW_SYSSCREENRC
- if ((p = getenv("SYSSCREENRC")))
- StartRc(p);
- else
-# endif
- StartRc(ETCSCREENRC);
-#endif
- StartRc(RcFileName);
- if (InitTermcap(m.m.attach.columns, m.m.attach.lines))
+ /* turn off iflag on a multi-attach... */
+ if (iflag && olddisplays)
{
- FreeDisplay();
- Kill(m.m.attach.apid, SIG_BYE);
- break;
+ iflag = 0;
+#if defined(TERMIO) || defined(POSIX)
+ olddisplays->d_NewMode.tio.c_cc[VINTR] = VDISABLE;
+ olddisplays->d_NewMode.tio.c_lflag &= ~ISIG;
+#else /* TERMIO || POSIX */
+ olddisplays->d_NewMode.m_tchars.t_intrc = -1;
+#endif /* TERMIO || POSIX */
+ SetTTY(olddisplays->d_userfd, &olddisplays->d_NewMode);
}
- InitTerm(m.m.attach.adaptflag);
- if (displays->d_next == 0)
- (void) chsock();
- signal(SIGHUP, SigHup);
-#ifdef UTMPOK
- /*
- * we set the Utmp slots again, if we were detached normally
- * and if we were detached by ^Z.
- */
- RemoveLoginSlot();
- if (displays->d_next == 0)
- for (wi = windows; wi; wi = wi->w_next)
- if (wi->w_ptyfd >= 0 && wi->w_slot != (slot_t) -1)
- SetUtmp(wi);
-#endif
- SetMode(&D_OldMode, &D_NewMode);
+ SetMode(&D_OldMode, &D_NewMode, D_flow, iflag);
SetTTY(D_userfd, &D_NewMode);
+ if (fcntl(D_userfd, F_SETFL, FNBLOCK))
+ Msg(errno, "Warning: NBLOCK fcntl failed");
- D_fore = NULL;
- /* there may be a window that we remember from last detach: */
- if (D_user->u_detachwin >= 0)
- fore = wtab[D_user->u_detachwin];
- /* Wayne wants us to restore the other window too. */
- if (D_user->u_detachotherwin >= 0)
- D_other = wtab[D_user->u_detachotherwin];
- /*
- * We want a window to start with.
- * It is the window we left from, which is not occupied and
- * grants us full read/write permissions.
- */
-#ifdef MULTIUSER
- if (!fore || fore->w_display || AclCheckPermWin(D_user, ACL_WRITE, fore))
-#else
- if (!fore || fore->w_display)
-#endif
- {
- /* try to get another window */
-#ifdef MULTIUSER
- for (wi = windows; wi; wi = wi->w_next)
- if (!wi->w_display && !AclCheckPermWin(D_user, ACL_WRITE, fore))
- break;
- if (!wi)
- for (wi = windows; wi; wi = wi->w_next)
- if (!wi->w_display && !AclCheckPermWin(D_user, ACL_READ, fore))
- break;
- if (!wi)
+#ifdef PASSWORD
+ if (D_user->u_password && *D_user->u_password)
+ AskPassword(&m);
+ else
#endif
- for (wi = windows; wi; wi = wi->w_next)
- if (!wi->w_display)
- break;
- fore = wi;
- }
- if (fore)
- SetForeWindow(fore);
- Activate(0);
- if (!D_fore)
- ShowWindows();
- if (displays->d_next == 0 && console_window)
- {
- if (TtyGrabConsole(console_window->w_ptyfd, 1, "reattach") == 0)
- Msg(0, "console %s is on window %d", HostName, console_window->w_number);
- }
- debug("activated...\n");
+ FinishAttach(&m);
break;
case MSG_ERROR:
Msg(0, "%s", m.m.message);
@@ -1220,7 +1054,6 @@ chsock()
return r;
}
-
/*
* Try to recreate the socket/pipe
*/
@@ -1239,5 +1072,209 @@ RecoverSocket()
if ((ServerSocket = MakeServerSocket()) < 0)
return 0;
+ evdeq(&serv_read);
+ serv_read.fd = ServerSocket;
+ evenq(&serv_read);
return 1;
}
+
+
+static void
+FinishAttach(m)
+struct msg *m;
+{
+ char *p;
+ int pid;
+ struct win *wi;
+
+ ASSERT(display);
+ pid = D_userpid;
+
+#if defined(pyr) || defined(xelos) || defined(sequent)
+ /*
+ * Kludge for systems with braindamaged termcap routines,
+ * which evaluate $TERMCAP, regardless weather it describes
+ * the correct terminal type or not.
+ */
+ debug("unsetenv(TERMCAP) in case of a different terminal");
+ unsetenv("TERMCAP");
+#endif
+
+ /*
+ * We reboot our Terminal Emulator. Forget all we knew about
+ * the old terminal, reread the termcap entries in .screenrc
+ * (and nothing more from .screenrc is read. Mainly because
+ * I did not check, weather a full reinit is save. jw)
+ * and /etc/screenrc, and initialise anew.
+ */
+ if (extra_outcap)
+ free(extra_outcap);
+ if (extra_incap)
+ free(extra_incap);
+ extra_incap = extra_outcap = 0;
+ debug2("Message says size (%dx%d)\n", m->m.attach.columns, m->m.attach.lines);
+#ifdef ETCSCREENRC
+# ifdef ALLOW_SYSSCREENRC
+ if ((p = getenv("SYSSCREENRC")))
+ StartRc(p);
+ else
+# endif
+ StartRc(ETCSCREENRC);
+#endif
+ StartRc(RcFileName);
+ if (InitTermcap(m->m.attach.columns, m->m.attach.lines))
+ {
+ FreeDisplay();
+ Kill(pid, SIG_BYE);
+ return;
+ }
+ MakeDefaultCanvas();
+ InitTerm(m->m.attach.adaptflag); /* write init string on fd */
+ if (displays->d_next == 0)
+ (void) chsock();
+ signal(SIGHUP, SigHup);
+ if (m->m.attach.esc != -1 && m->m.attach.meta_esc != -1)
+ {
+ D_user->u_Esc = m->m.attach.esc;
+ D_user->u_MetaEsc = m->m.attach.meta_esc;
+ }
+
+#ifdef UTMPOK
+ /*
+ * we set the Utmp slots again, if we were detached normally
+ * and if we were detached by ^Z.
+ * don't log zomies back in!
+ */
+ RemoveLoginSlot();
+ if (displays->d_next == 0)
+ for (wi = windows; wi; wi = wi->w_next)
+ if (wi->w_ptyfd >= 0 && wi->w_slot != (slot_t) -1)
+ SetUtmp(wi);
+#endif
+
+ D_fore = NULL;
+ /*
+ * there may be a window that we remember from last detach:
+ */
+ debug1("D_user->u_detachwin = %d\n", D_user->u_detachwin);
+ if (D_user->u_detachwin >= 0)
+ fore = wtab[D_user->u_detachwin];
+ else
+ fore = 0;
+
+ /* Wayne wants us to restore the other window too. */
+ if (D_user->u_detachotherwin >= 0)
+ D_other = wtab[D_user->u_detachotherwin];
+
+ fore = FindNiceWindow(fore, *m->m.attach.preselect ? m->m.attach.preselect : 0);
+ if (fore)
+ SetForeWindow(fore);
+ Activate(0);
+ if (!D_fore)
+ ShowWindows(-1);
+ if (displays->d_next == 0 && console_window)
+ {
+ if (TtyGrabConsole(console_window->w_ptyfd, 1, "reattach") == 0)
+ Msg(0, "console %s is on window %d", HostName, console_window->w_number);
+ }
+ debug("activated...\n");
+
+# if defined(DEBUG) && defined(SIG_NODEBUG)
+ if (!dfp)
+ {
+ sleep(1);
+ debug1("Attacher %d must not debug, as we have debug off.\n", pid);
+ kill(pid, SIG_NODEBUG);
+ }
+# endif /* SIG_NODEBUG */
+}
+
+
+#ifdef PASSWORD
+static void PasswordProcessInput __P((char *, int));
+
+struct pwdata {
+ int l;
+ char buf[8];
+ struct msg m;
+};
+
+static void
+AskPassword(m)
+struct msg *m;
+{
+ struct pwdata *pwdata;
+ ASSERT(display);
+ pwdata = (struct pwdata *)malloc(sizeof(struct pwdata));
+ if (!pwdata)
+ Panic(0, strnomem);
+ pwdata->l = 0;
+ pwdata->m = *m;
+ D_processinputdata = (char *)pwdata;
+ D_processinput = PasswordProcessInput;
+ AddStr("Screen password: ");
+}
+
+static void
+PasswordProcessInput(ibuf, ilen)
+char *ibuf;
+int ilen;
+{
+ struct pwdata *pwdata;
+ int c, l;
+ char *up;
+ int pid = D_userpid;
+
+ pwdata = (struct pwdata *)D_processinputdata;
+ l = pwdata->l;
+ while (ilen-- > 0)
+ {
+ c = *(unsigned char *)ibuf++;
+ if (c == '\r' || c == '\n')
+ {
+ up = D_user->u_password;
+ pwdata->buf[l] = 0;
+ if (strncmp(crypt(pwdata->buf, up), up, strlen(up)))
+ {
+ /* uh oh, user failed */
+ bzero(pwdata->buf, sizeof(pwdata->buf));
+ AddStr("\r\nPassword incorrect.\r\n");
+ D_processinputdata = 0; /* otherwise freed by FreeDis */
+ FreeDisplay();
+ Msg(0, "Illegal reattach attempt from terminal %s.", pwdata->m.m_tty);
+ free(pwdata);
+ Kill(pid, SIG_BYE);
+ return;
+ }
+ /* great, pw matched, all is fine */
+ bzero(pwdata->buf, sizeof(pwdata->buf));
+ D_processinputdata = 0;
+ D_processinput = ProcessInput;
+ FinishAttach(&pwdata->m);
+ free(pwdata);
+ return;
+ }
+ if (c == Ctrl('c'))
+ {
+ AddStr("\r\n");
+ FreeDisplay();
+ Kill(pid, SIG_BYE);
+ return;
+ }
+ if (c == '\b' || c == 0177)
+ {
+ if (l > 0)
+ l--;
+ continue;
+ }
+ if (c == Ctrl('u'))
+ {
+ l = 0;
+ continue;
+ }
+ if (l < 8)
+ pwdata->buf[l++] = c;
+ }
+ pwdata->l = l;
+}
+#endif
diff --git a/tek.patch b/tek.patch
deleted file mode 100644
index b057347..0000000
--- a/tek.patch
+++ /dev/null
@@ -1,68 +0,0 @@
-*** ./ansi.h.orig Tue Jan 9 19:16:35 1996
---- ./ansi.h Sat Jun 14 22:38:37 1997
-***************
-*** 56,62 ****
- PRIN, /* Printer mode */
- PRINESC, /* ESC seen in printer mode */
- PRINCSI, /* CSI seen in printer mode */
-! PRIN4 /* CSI 4 seen in printer mode */
- };
-
- enum string_t
---- 56,65 ----
- PRIN, /* Printer mode */
- PRINESC, /* ESC seen in printer mode */
- PRINCSI, /* CSI seen in printer mode */
-! PRIN4, /* CSI 4 seen in printer mode */
-! TEK, /* Tektronix mode */
-! TEKESC, /* Tektronix escape */
-! TEKEND /* Tektronix ending sequence */
- };
-
- enum string_t
-*** ./ansi.c.orig Thu May 1 17:33:31 1997
---- ./ansi.c Sat Jun 14 22:38:37 1997
-***************
-*** 813,818 ****
---- 813,823 ----
- case 'k':
- StartString(AKA);
- break;
-+ case '\014':
-+ curr->w_state = TEK;
-+ RAW_PUTCHAR('\033');
-+ RAW_PUTCHAR(c);
-+ break;
- default:
- if (Special(c))
- {
-***************
-*** 876,881 ****
---- 881,907 ----
- goto tryagain;
- }
- }
-+ break;
-+ case TEK:
-+ switch (c)
-+ {
-+ case '@':
-+ if ((unsigned char)*(buf - 2) == ' ') /* XXX: Yucc! */
-+ curr->w_state = TEKESC;
-+ /* FALLTHROUGH */
-+ default:
-+ RAW_PUTCHAR(c);
-+ break;
-+ }
-+ break;
-+ case TEKESC:
-+ curr->w_state = (c == '\037') ? TEKEND : TEK;
-+ RAW_PUTCHAR(c);
-+ break;
-+ case TEKEND:
-+ if (c == '\030')
-+ curr->w_state = LIT;
-+ RAW_PUTCHAR(c);
- break;
- case LIT:
- default:
diff --git a/teln.c b/teln.c
new file mode 100644
index 0000000..04baf2c
--- /dev/null
+++ b/teln.c
@@ -0,0 +1,562 @@
+/* Copyright (c) 1993
+ * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
+ * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
+ * Copyright (c) 1987 Oliver Laumann
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program (see the file COPYING); if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ ****************************************************************
+ */
+
+#include "rcs.h"
+RCS_ID("$Id: teln.c,v 1.6 1994/05/31 12:32:15 mlschroe Exp $ FAU")
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+
+#include "config.h"
+
+#ifdef BUILTIN_TELNET
+
+#include "screen.h"
+#include "extern.h"
+
+extern struct win *fore;
+extern struct layer *flayer;
+extern int visual_bell;
+extern char screenterm[];
+
+static void TelReply __P((struct win *, char *, int));
+static void TelDocmd __P((struct win *, int, int));
+static void TelDosub __P((struct win *));
+
+#define TEL_DEFPORT 23
+#define TEL_CONNECTING (-2)
+
+#define TC_IAC 255
+#define TC_DONT 254
+#define TC_DO 253
+#define TC_WONT 252
+#define TC_WILL 251
+#define TC_SB 250
+#define TC_BREAK 243
+#define TC_SE 240
+
+#define TC_S "S b swWdDc"
+
+#define TO_BINARY 0
+#define TO_ECHO 1
+#define TO_SGA 3
+#define TO_TM 6
+#define TO_TTYPE 24
+#define TO_NAWS 31
+#define TO_TSPEED 32
+#define TO_LFLOW 33
+#define TO_XDISPLOC 35
+#define TO_NEWENV 39
+
+#define TO_S "be c t wsf xE E"
+
+
+static unsigned char tn_init[] = {
+ TC_IAC, TC_DO, TO_SGA,
+ TC_IAC, TC_WILL, TO_TTYPE,
+ TC_IAC, TC_WILL, TO_NAWS,
+ TC_IAC, TC_WILL, TO_LFLOW,
+};
+
+static void
+tel_connev_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ struct win *p = (struct win *)data;
+ if (connect(p->w_ptyfd, (struct sockaddr *)&p->w_telsa, sizeof(p->w_telsa)) && errno != EISCONN)
+ {
+ char buf[1024];
+ buf[0] = ' ';
+ strncpy(buf + 1, strerror(errno), sizeof(buf) - 2);
+ buf[sizeof(buf) - 1] = 0;
+ WriteString(p, buf, strlen(buf));
+ WindowDied(p);
+ return;
+ }
+ WriteString(p, "connected.\r\n", 12);
+ evdeq(&p->w_telconnev);
+ p->w_telstate = 0;
+}
+
+int
+TelOpen(args)
+char **args;
+{
+ int fd;
+ int on = 1;
+
+ if ((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
+ {
+ Msg(errno, "TelOpen: socket");
+ return -1;
+ }
+ if (setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on)))
+ Msg(errno, "TelOpen: setsockopt SO_OOBINLINE");
+ return fd;
+}
+
+int
+TelConnect(p)
+struct win *p;
+{
+ int port = TEL_DEFPORT;
+ struct hostent *hp;
+ char **args;
+ char buf[256];
+
+ args = p->w_cmdargs + 1;
+
+ if (!*args)
+ {
+ Msg(0, "Usage: screen //telnet host [port]");
+ return -1;
+ }
+ if (args[1])
+ port = atoi(args[1]);
+ p->w_telsa.sin_family = AF_INET;
+ if((p->w_telsa.sin_addr.s_addr = inet_addr(*args)) == -1)
+ {
+ if ((hp = gethostbyname(*args)) == NULL)
+ {
+ Msg(0, "unknown host: %s", *args);
+ return -1;
+ }
+ bcopy((char *)hp->h_addr,(char *)&p->w_telsa.sin_addr.s_addr, hp->h_length);
+ p->w_telsa.sin_family = hp->h_addrtype;
+ }
+ p->w_telsa.sin_port = htons(port);
+ if (port != TEL_DEFPORT)
+ sprintf(buf, "Trying %s %d...", inet_ntoa(p->w_telsa.sin_addr), port);
+ else
+ sprintf(buf, "Trying %s...", inet_ntoa(p->w_telsa.sin_addr));
+ WriteString(p, buf, strlen(buf));
+ if (connect(p->w_ptyfd, (struct sockaddr *)&p->w_telsa, sizeof(p->w_telsa)))
+ {
+ if (errno == EINPROGRESS)
+ {
+ p->w_telstate = TEL_CONNECTING;
+ p->w_telconnev.fd = p->w_ptyfd;
+ p->w_telconnev.handler = tel_connev_fn;
+ p->w_telconnev.data = (char *)p;
+ p->w_telconnev.type = EV_WRITE;
+ p->w_telconnev.pri = 1;
+ debug("telnet connect in progress...\n");
+ evenq(&p->w_telconnev);
+ }
+ else
+ {
+ Msg(errno, "TelOpen: connect");
+ return -1;
+ }
+ }
+ else
+ WriteString(p, "connected.\r\n", 12);
+ if (port == TEL_DEFPORT)
+ TelReply(p, (char *)tn_init, sizeof(tn_init));
+ return 0;
+}
+
+int
+TelIsline(p)
+struct win *p;
+{
+ return !fore->w_telropts[TO_SGA];
+}
+
+void
+TelProcessLine(bufpp, lenp)
+char **bufpp;
+int *lenp;
+{
+ int echo = !fore->w_telropts[TO_ECHO];
+ unsigned char c;
+ char *tb;
+ int tl;
+
+ char *buf = *bufpp;
+ int l = *lenp;
+ while (l--)
+ {
+ c = *(unsigned char *)buf++;
+ if (fore->w_telbufl + 2 >= IOSIZE)
+ {
+ WBell(fore, visual_bell);
+ continue;
+ }
+ if (c == '\r')
+ {
+ if (echo)
+ WriteString(fore, "\r\n", 2);
+ fore->w_telbuf[fore->w_telbufl++] = '\r';
+ fore->w_telbuf[fore->w_telbufl++] = '\n';
+ tb = fore->w_telbuf;
+ tl = fore->w_telbufl;
+ Process(&tb, &tl);
+ fore->w_telbufl = 0;
+ continue;
+ }
+ if (c == '\b' && fore->w_telbufl > 0)
+ {
+ if (echo)
+ {
+ WriteString(fore, (char *)&c, 1);
+ WriteString(fore, " ", 1);
+ WriteString(fore, (char *)&c, 1);
+ }
+ fore->w_telbufl--;
+ }
+ if ((c >= 0x20 && c <= 0x7e) || (c >= 0xa0 && c <= 0xff))
+ {
+ if (echo)
+ WriteString(fore, (char *)&c, 1);
+ fore->w_telbuf[fore->w_telbufl++] = c;
+ }
+ }
+ *lenp = 0;
+}
+
+int
+DoTelnet(buf, lenp, f)
+char *buf;
+int *lenp;
+int f;
+{
+ int echo = !fore->w_telropts[TO_ECHO];
+ int cmode = fore->w_telropts[TO_SGA];
+ int bin = fore->w_telropts[TO_BINARY];
+ char *p = buf, *sbuf;
+ int trunc = 0;
+ int c;
+ int l = *lenp;
+
+ sbuf = p;
+ while (l-- > 0)
+ {
+ c = *(unsigned char *)p++;
+ if (c == TC_IAC || (c == '\r' && (l ==0 || *p != '\n') && cmode && !bin))
+ {
+ if (cmode && echo)
+ {
+ WriteString(fore, sbuf, p - sbuf);
+ sbuf = p;
+ }
+ if (f-- <= 0)
+ {
+ trunc++;
+ l--;
+ }
+ if (l < 0)
+ {
+ p--; /* drop char */
+ break;
+ }
+ if (l)
+ bcopy(p, p + 1, l);
+ if (c == TC_IAC)
+ *p++ = c;
+ else if (c == '\r')
+ *p++ = 0;
+ else if (c == '\n')
+ {
+ p[-1] = '\r';
+ *p++ = '\n';
+ }
+ }
+ }
+ *lenp = p - buf;
+ return trunc;
+}
+
+/* modifies data in-place, returns new length */
+int
+TelIn(p, buf, len, free)
+struct win *p;
+char *buf;
+int len;
+int free;
+{
+ char *rp, *wp;
+ int c;
+
+ rp = wp = buf;
+ while (len-- > 0)
+ {
+ c = *(unsigned char *)rp++;
+
+ if (p->w_telstate >= TC_WILL && p->w_telstate <= TC_DONT)
+ {
+ TelDocmd(p, p->w_telstate, c);
+ p->w_telstate = 0;
+ continue;
+ }
+ if (p->w_telstate == TC_SB || p->w_telstate == TC_SE)
+ {
+ if (p->w_telstate == TC_SE && c == TC_IAC)
+ p->w_telsubidx--;
+ if (p->w_telstate == TC_SE && c == TC_SE)
+ {
+ p->w_telsubidx--;
+ TelDosub(p);
+ p->w_telstate = 0;
+ continue;
+ }
+ if (p->w_telstate == TC_SB && c == TC_IAC)
+ p->w_telstate = TC_SE;
+ else
+ p->w_telstate = TC_SB;
+ p->w_telsubbuf[p->w_telsubidx] = c;
+ if (p->w_telsubidx < sizeof(p->w_telsubbuf) - 1)
+ p->w_telsubidx++;
+ continue;
+ }
+ if (p->w_telstate == TC_IAC)
+ {
+ if ((c >= TC_WILL && c <= TC_DONT) || c == TC_SB)
+ {
+ p->w_telsubidx = 0;
+ p->w_telstate = c;
+ continue;
+ }
+ p->w_telstate = 0;
+ if (c != TC_IAC)
+ continue;
+ }
+ else if (c == TC_IAC)
+ {
+ p->w_telstate = c;
+ continue;
+ }
+ if (p->w_telstate == '\r')
+ {
+ p->w_telstate = 0;
+ if (c == 0)
+ continue; /* suppress trailing \0 */
+ }
+ else if (c == '\n' && !p->w_telropts[TO_SGA])
+ {
+ /* oops... simulate terminal line mode: insert \r */
+ if (wp + 1 == rp)
+ {
+ if (free-- > 0)
+ {
+ if (len)
+ bcopy(rp, rp + 1, len);
+ rp++;
+ *wp++ = '\r';
+ }
+ }
+ else
+ *wp++ = '\r';
+ }
+ if (c == '\r')
+ p->w_telstate = c;
+ *wp++ = c;
+ }
+ return wp - buf;
+}
+
+static void
+TelReply(p, str, len)
+struct win *p;
+char *str;
+int len;
+{
+ if (len <= 0)
+ return;
+ if (p->w_inlen + len > IOSIZE)
+ {
+ Msg(0, "Warning: telnet protocol overrun!");
+ return;
+ }
+ bcopy(str, p->w_inbuf + p->w_inlen, len);
+ p->w_inlen += len;
+}
+
+static void
+TelDocmd(p, cmd, opt)
+struct win *p;
+int cmd, opt;
+{
+ unsigned char b[3];
+ int repl = 0;
+
+ if (cmd == TC_WONT)
+ debug2("[WONT %c %d]\n", TO_S[opt], opt);
+ if (cmd == TC_WILL)
+ debug2("[WILL %c %d]\n", TO_S[opt], opt);
+ if (cmd == TC_DONT)
+ debug2("[DONT %c %d]\n", TO_S[opt], opt);
+ if (cmd == TC_DO)
+ debug2("[DO %c %d]\n", TO_S[opt], opt);
+
+ switch(cmd)
+ {
+ case TC_WILL:
+ if (p->w_telropts[opt] || opt == TO_TM)
+ return;
+ repl = TC_DONT;
+ if (opt == TO_ECHO || opt == TO_SGA || opt == TO_BINARY)
+ {
+ p->w_telropts[opt] = 1;
+ /* setcon(); */
+ repl = TC_DO;
+ }
+ break;
+ case TC_WONT:
+ if (!p->w_telropts[opt] || opt == TO_TM)
+ return;
+ repl = TC_DONT;
+#if 0
+ if (opt == TO_ECHO || opt == TO_SGA)
+ setcon();
+#endif
+ p->w_telropts[opt] = 0;
+ break;
+ case TC_DO:
+ if (p->w_telmopts[opt])
+ return;
+ repl = TC_WONT;
+ if (opt == TO_TTYPE || opt == TO_SGA || opt == TO_BINARY || opt == TO_NAWS || opt == TO_TM || opt == TO_LFLOW)
+ {
+ repl = TC_WILL;
+ p->w_telmopts[opt] = 1;
+ }
+ p->w_telmopts[TO_TM] = 0;
+ break;
+ case TC_DONT:
+ if (!p->w_telmopts[opt])
+ return;
+ repl = TC_WONT;
+ p->w_telmopts[opt] = 0;
+ break;
+ }
+ b[0] = TC_IAC;
+ b[1] = repl;
+ b[2] = opt;
+ TelReply(p, (char *)b, 3);
+ if (cmd == TC_DO && opt == TO_NAWS)
+ TelWindowSize(p);
+}
+
+
+static void
+TelDosub(p)
+struct win *p;
+{
+ char trepl[20 + 6 + 1];
+ int l;
+
+ switch(p->w_telsubbuf[0])
+ {
+ case TO_TTYPE:
+ if (p->w_telsubidx != 2 || p->w_telsubbuf[1] != 1)
+ return;
+ l = strlen(screenterm);
+ ASSERT(l < 20);
+ sprintf(trepl, "%c%c%c%c%s%c%c", TC_IAC, TC_SB, TO_TTYPE, 0, screenterm, TC_IAC, TC_SE);
+ TelReply(p, trepl, l + 6);
+ break;
+ case TO_LFLOW:
+ if (p->w_telsubidx != 2)
+ return;
+ debug1("[FLOW %d]\r\n", p->w_telsubbuf[1]);
+ break;
+ default:
+ break;
+ }
+}
+
+void
+TelBreak(p)
+struct win *p;
+{
+ static unsigned char tel_break[] = { TC_IAC, TC_BREAK };
+ TelReply(p, (char *)tel_break, 2);
+}
+
+void
+TelWindowSize(p)
+struct win *p;
+{
+ char s[20], trepl[20], *t;
+ int i;
+
+ debug2("TelWindowSize %d %d\n", p->w_width, p->w_height);
+ if (p->w_width == 0 || p->w_height == 0 || !p->w_telmopts[TO_NAWS])
+ return;
+ sprintf(s, "%c%c%c%c%c%c%c%c%c", TC_SB, TC_SB, TO_NAWS, p->w_width / 256, p->w_width & 255, p->w_height / 256, p->w_height & 255, TC_SE, TC_SE);
+ t = trepl;
+ for (i = 0; i < 9; i++)
+ if ((unsigned char)(*t++ = s[i]) == TC_IAC)
+ *t++ = TC_IAC;
+ trepl[0] = TC_IAC;
+ t[-2] = TC_IAC;
+ debug(" - sending");
+ for (i = 0; trepl + i < t; i++)
+ debug1(" %02x", (unsigned char)trepl[i]);
+ debug("\n");
+ TelReply(p, trepl, t - trepl);
+}
+
+static char tc_s[] = TC_S;
+static char to_s[] = TO_S;
+
+void
+TelStatus(p, buf, l)
+struct win *p;
+char *buf;
+int l;
+{
+ int i;
+
+ *buf++ = '[';
+ for (i = 0; to_s[i]; i++)
+ {
+ if (to_s[i] == ' ' || p->w_telmopts[i] == 0)
+ continue;
+ *buf++ = to_s[i];
+ }
+ *buf++ = ':';
+ for (i = 0; to_s[i]; i++)
+ {
+ if (to_s[i] == ' ' || p->w_telropts[i] == 0)
+ continue;
+ *buf++ = to_s[i];
+ }
+ if (p->w_telstate == TEL_CONNECTING)
+ buf[-1] = 'C';
+ else if (p->w_telstate && p->w_telstate != '\r')
+ {
+ *buf++ = ':';
+ *buf++ = tc_s[p->w_telstate - TC_SE];
+ }
+ *buf++ = ']';
+ *buf = 0;
+ return;
+}
+
+#endif /* BUILTIN_TELNET */
diff --git a/term.c b/term.c
index 23e10a3..ccf123c 100644
--- a/term.c
+++ b/term.c
@@ -22,7 +22,7 @@
*/
#include "rcs.h"
-RCS_ID("$Id: term.c,v 1.4 1994/05/31 12:33:04 mlschroe Exp $ FAU")
+RCS_ID("$Id: term.c,v 1.5 1994/09/06 17:00:23 mlschroe Exp $ FAU")
#include "term.h"
@@ -117,6 +117,8 @@ struct term term[T_N] =
{ "AB", T_STR },
{ "Sf", T_STR },
{ "Sb", T_STR },
+ { "op", T_STR },
+ { "be", T_FLG },
{ "AX", T_FLG },
/* keypad/cursorkeys */
@@ -156,6 +158,7 @@ struct term term[T_N] =
{ "KJ", T_STR },
{ "VR", T_STR },
{ "VN", T_STR },
+ { "TF", T_FLG },
/* d_font setting */
{ "G0", T_FLG },
@@ -194,8 +197,7 @@ struct term term[T_N] =
{ "F9", T_STR },
{ "FA", T_STR },
- { "kb", T_STR }, KMAPDEF("\010")
- { "kh", T_STR }, KMAPDEF("\033[1~") KMAPMDEF("\201")
+ { "kb", T_STR },
{ "K1", T_STR },
{ "K2", T_STR },
{ "K3", T_STR },
@@ -206,21 +208,26 @@ struct term term[T_N] =
{ "ka", T_STR },
{ "kB", T_STR },
{ "kC", T_STR },
- { "kD", T_STR }, KMAPDEF("\033[3~")
{ "kE", T_STR },
{ "kF", T_STR }, KMAPMDEF("\004")
- { "kH", T_STR }, KMAPDEF("\033[4~") KMAPMDEF("\205")
- { "kI", T_STR }, KMAPDEF("\033[2~")
{ "kL", T_STR },
{ "kM", T_STR },
- { "kN", T_STR }, KMAPDEF("\033[6~") KMAPMDEF("\006")
- { "kP", T_STR }, KMAPDEF("\033[5~") KMAPMDEF("\002")
{ "kR", T_STR }, KMAPMDEF("\025")
{ "kS", T_STR },
{ "kT", T_STR },
{ "kt", T_STR },
+
+/* keys above the cursor */
+/* define T_NAVIGATE */
+ { "kh", T_STR }, KMAPDEF("\033[1~") KMAPMDEF("\201")
{ "@1", T_STR },
+ { "kH", T_STR }, KMAPDEF("\033[4~") KMAPMDEF("\205")
{ "@7", T_STR },
+ { "kN", T_STR }, KMAPDEF("\033[6~") KMAPMDEF("\006")
+ { "kP", T_STR }, KMAPDEF("\033[5~") KMAPMDEF("\002")
+ { "kI", T_STR }, KMAPDEF("\033[2~")
+ { "kD", T_STR }, KMAPDEF("\033[3~")
+
/* keys that can have two bindings */
/* define T_CURSOR */
{ "ku", T_STR }, KMAPDEF("\033[A") KMAPADEF("\033OA") KMAPMDEF("\220")
diff --git a/term.h.dist b/term.h.dist
index 7dd41b8..b41db31 100644
--- a/term.h.dist
+++ b/term.h.dist
@@ -19,219 +19,226 @@ union tcu
char *str;
};
-#define d_LI d_tcs[0].num
+#define d_LI d_tcs[0].num
#define D_LI (D_tcs[0].num)
-#define d_CO d_tcs[1].num
+#define d_CO d_tcs[1].num
#define D_CO (D_tcs[1].num)
-#define d_HC d_tcs[2].flg
+#define d_HC d_tcs[2].flg
#define D_HC (D_tcs[2].flg)
-#define d_OS d_tcs[3].flg
+#define d_OS d_tcs[3].flg
#define D_OS (D_tcs[3].flg)
-#define d_NS d_tcs[4].flg
+#define d_NS d_tcs[4].flg
#define D_NS (D_tcs[4].flg)
-#define d_CM d_tcs[5].str
+#define d_CM d_tcs[5].str
#define D_CM (D_tcs[5].str)
-#define d_HO d_tcs[6].str
+#define d_HO d_tcs[6].str
#define D_HO (D_tcs[6].str)
-#define d_CR d_tcs[7].str
+#define d_CR d_tcs[7].str
#define D_CR (D_tcs[7].str)
-#define d_UP d_tcs[8].str
+#define d_UP d_tcs[8].str
#define D_UP (D_tcs[8].str)
-#define d_CUP d_tcs[9].str
+#define d_CUP d_tcs[9].str
#define D_CUP (D_tcs[9].str)
-#define d_DO d_tcs[10].str
+#define d_DO d_tcs[10].str
#define D_DO (D_tcs[10].str)
-#define d_CDO d_tcs[11].str
+#define d_CDO d_tcs[11].str
#define D_CDO (D_tcs[11].str)
-#define d_BS d_tcs[12].flg
+#define d_BS d_tcs[12].flg
#define D_BS (D_tcs[12].flg)
-#define d_BC d_tcs[13].str
+#define d_BC d_tcs[13].str
#define D_BC (D_tcs[13].str)
-#define d_LE d_tcs[14].str
+#define d_LE d_tcs[14].str
#define D_LE (D_tcs[14].str)
-#define d_CLE d_tcs[15].str
+#define d_CLE d_tcs[15].str
#define D_CLE (D_tcs[15].str)
-#define d_ND d_tcs[16].str
+#define d_ND d_tcs[16].str
#define D_ND (D_tcs[16].str)
-#define d_CRI d_tcs[17].str
+#define d_CRI d_tcs[17].str
#define D_CRI (D_tcs[17].str)
-#define d_CS d_tcs[18].str
+#define d_CS d_tcs[18].str
#define D_CS (D_tcs[18].str)
-#define d_NL d_tcs[19].str
+#define d_NL d_tcs[19].str
#define D_NL (D_tcs[19].str)
-#define d_SF d_tcs[20].str
+#define d_SF d_tcs[20].str
#define D_SF (D_tcs[20].str)
-#define d_SR d_tcs[21].str
+#define d_SR d_tcs[21].str
#define D_SR (D_tcs[21].str)
-#define d_AL d_tcs[22].str
+#define d_AL d_tcs[22].str
#define D_AL (D_tcs[22].str)
-#define d_CAL d_tcs[23].str
+#define d_CAL d_tcs[23].str
#define D_CAL (D_tcs[23].str)
-#define d_DL d_tcs[24].str
+#define d_DL d_tcs[24].str
#define D_DL (D_tcs[24].str)
-#define d_CDL d_tcs[25].str
+#define d_CDL d_tcs[25].str
#define D_CDL (D_tcs[25].str)
-#define d_IN d_tcs[26].flg
+#define d_IN d_tcs[26].flg
#define D_IN (D_tcs[26].flg)
-#define d_IM d_tcs[27].str
+#define d_IM d_tcs[27].str
#define D_IM (D_tcs[27].str)
-#define d_EI d_tcs[28].str
+#define d_EI d_tcs[28].str
#define D_EI (D_tcs[28].str)
-#define d_IC d_tcs[29].str
+#define d_IC d_tcs[29].str
#define D_IC (D_tcs[29].str)
-#define d_CIC d_tcs[30].str
+#define d_CIC d_tcs[30].str
#define D_CIC (D_tcs[30].str)
-#define d_DC d_tcs[31].str
+#define d_DC d_tcs[31].str
#define D_DC (D_tcs[31].str)
-#define d_CDC d_tcs[32].str
+#define d_CDC d_tcs[32].str
#define D_CDC (D_tcs[32].str)
-#define d_UT d_tcs[33].flg
+#define d_UT d_tcs[33].flg
#define D_UT (D_tcs[33].flg)
-#define d_CL d_tcs[34].str
+#define d_CL d_tcs[34].str
#define D_CL (D_tcs[34].str)
-#define d_CD d_tcs[35].str
+#define d_CD d_tcs[35].str
#define D_CD (D_tcs[35].str)
-#define d_CCD d_tcs[36].str
+#define d_CCD d_tcs[36].str
#define D_CCD (D_tcs[36].str)
-#define d_CE d_tcs[37].str
+#define d_CE d_tcs[37].str
#define D_CE (D_tcs[37].str)
-#define d_CB d_tcs[38].str
+#define d_CB d_tcs[38].str
#define D_CB (D_tcs[38].str)
-#define d_IS d_tcs[39].str
+#define d_IS d_tcs[39].str
#define D_IS (D_tcs[39].str)
-#define d_TI d_tcs[40].str
+#define d_TI d_tcs[40].str
#define D_TI (D_tcs[40].str)
-#define d_TE d_tcs[41].str
+#define d_TE d_tcs[41].str
#define D_TE (D_tcs[41].str)
-#define d_BL d_tcs[42].str
+#define d_BL d_tcs[42].str
#define D_BL (D_tcs[42].str)
-#define d_VB d_tcs[43].str
+#define d_VB d_tcs[43].str
#define D_VB (D_tcs[43].str)
-#define d_CWS d_tcs[44].str
+#define d_CWS d_tcs[44].str
#define D_CWS (D_tcs[44].str)
-#define d_CZ0 d_tcs[45].str
+#define d_CZ0 d_tcs[45].str
#define D_CZ0 (D_tcs[45].str)
-#define d_CZ1 d_tcs[46].str
+#define d_CZ1 d_tcs[46].str
#define D_CZ1 (D_tcs[46].str)
#define T_ATTR 47
-#define d_MH d_tcs[47].str
+#define d_MH d_tcs[47].str
#define D_MH (D_tcs[47].str)
-#define d_US d_tcs[48].str
+#define d_US d_tcs[48].str
#define D_US (D_tcs[48].str)
-#define d_MD d_tcs[49].str
+#define d_MD d_tcs[49].str
#define D_MD (D_tcs[49].str)
-#define d_MR d_tcs[50].str
+#define d_MR d_tcs[50].str
#define D_MR (D_tcs[50].str)
-#define d_SO d_tcs[51].str
+#define d_SO d_tcs[51].str
#define D_SO (D_tcs[51].str)
-#define d_MB d_tcs[52].str
+#define d_MB d_tcs[52].str
#define D_MB (D_tcs[52].str)
-#define d_UE d_tcs[53].str
+#define d_UE d_tcs[53].str
#define D_UE (D_tcs[53].str)
-#define d_SE d_tcs[54].str
+#define d_SE d_tcs[54].str
#define D_SE (D_tcs[54].str)
-#define d_ME d_tcs[55].str
+#define d_ME d_tcs[55].str
#define D_ME (D_tcs[55].str)
-#define d_MS d_tcs[56].flg
+#define d_MS d_tcs[56].flg
#define D_MS (D_tcs[56].flg)
-#define d_SG d_tcs[57].num
+#define d_SG d_tcs[57].num
#define D_SG (D_tcs[57].num)
-#define d_UG d_tcs[58].num
+#define d_UG d_tcs[58].num
#define D_UG (D_tcs[58].num)
-#define d_SA d_tcs[59].str
+#define d_SA d_tcs[59].str
#define D_SA (D_tcs[59].str)
-#define d_CAF d_tcs[60].str
+#define d_CAF d_tcs[60].str
#define D_CAF (D_tcs[60].str)
-#define d_CAB d_tcs[61].str
+#define d_CAB d_tcs[61].str
#define D_CAB (D_tcs[61].str)
-#define d_CSF d_tcs[62].str
+#define d_CSF d_tcs[62].str
#define D_CSF (D_tcs[62].str)
-#define d_CSB d_tcs[63].str
+#define d_CSB d_tcs[63].str
#define D_CSB (D_tcs[63].str)
-#define d_CAX d_tcs[64].flg
-#define D_CAX (D_tcs[64].flg)
-#define d_KS d_tcs[65].str
-#define D_KS (D_tcs[65].str)
-#define d_KE d_tcs[66].str
-#define D_KE (D_tcs[66].str)
-#define d_CCS d_tcs[67].str
-#define D_CCS (D_tcs[67].str)
-#define d_CCE d_tcs[68].str
-#define D_CCE (D_tcs[68].str)
-#define d_PO d_tcs[69].str
-#define D_PO (D_tcs[69].str)
-#define d_PF d_tcs[70].str
-#define D_PF (D_tcs[70].str)
-#define d_HS d_tcs[71].flg
-#define D_HS (D_tcs[71].flg)
-#define d_WS d_tcs[72].num
-#define D_WS (D_tcs[72].num)
-#define d_TS d_tcs[73].str
-#define D_TS (D_tcs[73].str)
-#define d_FS d_tcs[74].str
-#define D_FS (D_tcs[74].str)
-#define d_DS d_tcs[75].str
-#define D_DS (D_tcs[75].str)
-#define d_VI d_tcs[76].str
-#define D_VI (D_tcs[76].str)
-#define d_VS d_tcs[77].str
-#define D_VS (D_tcs[77].str)
-#define d_VE d_tcs[78].str
-#define D_VE (D_tcs[78].str)
-#define d_AM d_tcs[79].flg
-#define D_AM (D_tcs[79].flg)
-#define d_XV d_tcs[80].flg
-#define D_XV (D_tcs[80].flg)
-#define d_XN d_tcs[81].flg
-#define D_XN (D_tcs[81].flg)
-#define d_COP d_tcs[82].flg
-#define D_COP (D_tcs[82].flg)
-#define d_CLP d_tcs[83].flg
-#define D_CLP (D_tcs[83].flg)
-#define d_CNF d_tcs[84].flg
-#define D_CNF (D_tcs[84].flg)
-#define d_NX d_tcs[85].flg
-#define D_NX (D_tcs[85].flg)
-#define d_CAN d_tcs[86].flg
-#define D_CAN (D_tcs[86].flg)
-#define d_COL d_tcs[87].num
-#define D_COL (D_tcs[87].num)
-#define d_CKJ d_tcs[88].str
-#define D_CKJ (D_tcs[88].str)
-#define d_CVR d_tcs[89].str
-#define D_CVR (D_tcs[89].str)
-#define d_CVN d_tcs[90].str
-#define D_CVN (D_tcs[90].str)
-#define d_CG0 d_tcs[91].flg
-#define D_CG0 (D_tcs[91].flg)
-#define d_CS0 d_tcs[92].str
-#define D_CS0 (D_tcs[92].str)
-#define d_CE0 d_tcs[93].str
-#define D_CE0 (D_tcs[93].str)
-#define d_CC0 d_tcs[94].str
-#define D_CC0 (D_tcs[94].str)
-#define d_AS d_tcs[95].str
-#define D_AS (D_tcs[95].str)
-#define d_AE d_tcs[96].str
-#define D_AE (D_tcs[96].str)
-#define d_AC d_tcs[97].str
-#define D_AC (D_tcs[97].str)
-#define d_EA d_tcs[98].str
-#define D_EA (D_tcs[98].str)
-#define d_CXC d_tcs[99].str
-#define D_CXC (D_tcs[99].str)
-#define T_CAPS 100
-#define T_CURSOR 147
-#define T_KEYPAD 151
-#define T_OCAPS 169
-#define T_ECAPS 182
-#define T_N 182
+#define d_OP d_tcs[64].str
+#define D_OP (D_tcs[64].str)
+#define d_BE d_tcs[65].flg
+#define D_BE (D_tcs[65].flg)
+#define d_CAX d_tcs[66].flg
+#define D_CAX (D_tcs[66].flg)
+#define d_KS d_tcs[67].str
+#define D_KS (D_tcs[67].str)
+#define d_KE d_tcs[68].str
+#define D_KE (D_tcs[68].str)
+#define d_CCS d_tcs[69].str
+#define D_CCS (D_tcs[69].str)
+#define d_CCE d_tcs[70].str
+#define D_CCE (D_tcs[70].str)
+#define d_PO d_tcs[71].str
+#define D_PO (D_tcs[71].str)
+#define d_PF d_tcs[72].str
+#define D_PF (D_tcs[72].str)
+#define d_HS d_tcs[73].flg
+#define D_HS (D_tcs[73].flg)
+#define d_WS d_tcs[74].num
+#define D_WS (D_tcs[74].num)
+#define d_TS d_tcs[75].str
+#define D_TS (D_tcs[75].str)
+#define d_FS d_tcs[76].str
+#define D_FS (D_tcs[76].str)
+#define d_DS d_tcs[77].str
+#define D_DS (D_tcs[77].str)
+#define d_VI d_tcs[78].str
+#define D_VI (D_tcs[78].str)
+#define d_VS d_tcs[79].str
+#define D_VS (D_tcs[79].str)
+#define d_VE d_tcs[80].str
+#define D_VE (D_tcs[80].str)
+#define d_AM d_tcs[81].flg
+#define D_AM (D_tcs[81].flg)
+#define d_XV d_tcs[82].flg
+#define D_XV (D_tcs[82].flg)
+#define d_XN d_tcs[83].flg
+#define D_XN (D_tcs[83].flg)
+#define d_COP d_tcs[84].flg
+#define D_COP (D_tcs[84].flg)
+#define d_CLP d_tcs[85].flg
+#define D_CLP (D_tcs[85].flg)
+#define d_CNF d_tcs[86].flg
+#define D_CNF (D_tcs[86].flg)
+#define d_NX d_tcs[87].flg
+#define D_NX (D_tcs[87].flg)
+#define d_CAN d_tcs[88].flg
+#define D_CAN (D_tcs[88].flg)
+#define d_COL d_tcs[89].num
+#define D_COL (D_tcs[89].num)
+#define d_CKJ d_tcs[90].str
+#define D_CKJ (D_tcs[90].str)
+#define d_CVR d_tcs[91].str
+#define D_CVR (D_tcs[91].str)
+#define d_CVN d_tcs[92].str
+#define D_CVN (D_tcs[92].str)
+#define d_CTF d_tcs[93].flg
+#define D_CTF (D_tcs[93].flg)
+#define d_CG0 d_tcs[94].flg
+#define D_CG0 (D_tcs[94].flg)
+#define d_CS0 d_tcs[95].str
+#define D_CS0 (D_tcs[95].str)
+#define d_CE0 d_tcs[96].str
+#define D_CE0 (D_tcs[96].str)
+#define d_CC0 d_tcs[97].str
+#define D_CC0 (D_tcs[97].str)
+#define d_AS d_tcs[98].str
+#define D_AS (D_tcs[98].str)
+#define d_AE d_tcs[99].str
+#define D_AE (D_tcs[99].str)
+#define d_AC d_tcs[100].str
+#define D_AC (D_tcs[100].str)
+#define d_EA d_tcs[101].str
+#define D_EA (D_tcs[101].str)
+#define d_CXC d_tcs[102].str
+#define D_CXC (D_tcs[102].str)
+#define T_CAPS 103
+#define T_NAVIGATE 142
+#define T_CURSOR 150
+#define T_KEYPAD 154
+#define T_OCAPS 172
+#define T_ECAPS 185
+#define T_N 185
#ifdef MAPKEYS
-# define KMAPDEFSTART 100
+# define KMAPDEFSTART 103
# define NKMAPDEF 69
-# define KMAPADEFSTART 147
+# define KMAPADEFSTART 150
# define NKMAPADEF 22
-# define KMAPMDEFSTART 122
-# define NKMAPMDEF 29
+# define KMAPMDEFSTART 135
+# define NKMAPMDEF 19
#endif
diff --git a/term.sh b/term.sh
index 721a762..6815a20 100644
--- a/term.sh
+++ b/term.sh
@@ -58,7 +58,7 @@ sed < ${srcdir}/term.c \
a=substr($2,2,length($2)-3);
b=substr($3,3,3);
if (nolist == 0) {
- printf "#define d_%s d_tcs[%d].%s\n",a,s,b
+ printf "#define d_%s d_tcs[%d].%s\n",a,s,b
printf "#define D_%s (D_tcs[%d].%s)\n",a,s,b
}
s++;
diff --git a/termcap.c b/termcap.c
index bb2a854..1ebaccf 100644
--- a/termcap.c
+++ b/termcap.c
@@ -22,7 +22,7 @@
*/
#include "rcs.h"
-RCS_ID("$Id: termcap.c,v 1.8 1994/05/31 12:33:13 mlschroe Exp $ FAU")
+RCS_ID("$Id: termcap.c,v 1.9 1994/09/06 17:00:31 mlschroe Exp $ FAU")
#include <sys/types.h>
#include "config.h"
@@ -30,36 +30,39 @@ RCS_ID("$Id: termcap.c,v 1.8 1994/05/31 12:33:13 mlschroe Exp $ FAU")
#include "extern.h"
extern struct display *display, *displays;
+extern int real_uid, real_gid, eff_uid, eff_gid;
+extern struct term term[]; /* terminal capabilities */
+extern struct NewWindow nwin_undef, nwin_default, nwin_options;
+extern int force_vt, assume_LP;
+extern int Z0width, Z1width;
+extern int hardstatusemu;
+#ifdef MAPKEYS
+extern struct action umtab[];
+extern struct action mmtab[];
+extern struct action dmtab[];
+extern char *kmap_extras[];
+extern int kmap_extras_fl[];
+extern int DefaultEsc;
+#endif
+
static void AddCap __P((char *));
static void MakeString __P((char *, char *, int, char *));
static char *findcap __P((char *, char **, int));
static int copyarg __P((char **, char *));
+static int e_tgetent __P((char *, char *));
static char *e_tgetstr __P((char *, char **));
static int e_tgetflag __P((char *));
static int e_tgetnum __P((char *));
#ifdef MAPKEYS
static int addmapseq __P((char *, int));
static int remmapseq __P((char *));
-#ifdef DEBUG
+#ifdef DEBUGG
static void dumpmap __P((void));
#endif
#endif
-extern struct term term[]; /* terminal capabilities */
-extern struct NewWindow nwin_undef, nwin_default, nwin_options;
-extern int force_vt, assume_LP;
-extern int Z0width, Z1width;
-#ifdef MAPKEYS
-extern struct action umtab[];
-extern struct action mmtab[];
-extern struct action dmtab[];
-extern char *kmap_extras[];
-extern int kmap_extras_fl[];
-extern int DefaultEsc;
-#endif
-
char Termcap[TERMCAP_BUFSIZE + 8]; /* new termcap +8:"TERMCAP=" */
static int Termcaplen;
static int tcLineLen;
@@ -92,6 +95,11 @@ char *s;
return 0;
}
+/*
+ * Compile the terminal capabilities for a display.
+ * Input: tgetent(, D_termname) extra_incap, extra_outcap.
+ * Effect: display initialisation.
+ */
int
InitTermcap(wi, he)
int wi;
@@ -105,7 +113,7 @@ int he;
ASSERT(display);
bzero(tbuf, sizeof(tbuf));
debug1("InitTermcap: looking for tgetent('%s')\n", D_termname);
- if (*D_termname == 0 || tgetent(tbuf, D_termname) != 1)
+ if (*D_termname == 0 || e_tgetent(tbuf, D_termname) != 1)
{
#ifdef TERMINFO
Msg(0, "Cannot find terminfo entry for '%s'.", D_termname);
@@ -114,7 +122,7 @@ int he;
#endif
return -1;
}
- debug1("got it:\n%s\n",tbuf);
+ debug1("got it:\n%s\n", tbuf);
#ifdef DEBUG
if (extra_incap)
debug1("Extra incap: %s\n", extra_incap);
@@ -128,6 +136,9 @@ int he;
return -1;
}
+ /*
+ * loop through all needed capabilities, record their values in the display
+ */
tp = D_tentry;
for (i = 0; i < T_N; i++)
{
@@ -150,6 +161,10 @@ int he;
/*NOTREACHED*/
}
}
+
+ /*
+ * Now a good deal of sanity checks on the retrieved capabilities.
+ */
if (D_HC)
{
Msg(0, "You can't run screen on a hardcopy terminal.");
@@ -183,12 +198,33 @@ int he;
if (D_LI <= 0)
D_LI = 24;
+ if (D_CTF)
+ {
+ /* standard fixes for xterms etc */
+ /* assume color for everything that looks ansi-compatible */
+ if (!D_CAF && D_ME && InStr(D_ME, "\033[m"))
+ {
+#ifdef TERMINFO
+ D_CAF = "\033[3%p1%dm";
+ D_CAB = "\033[4%p1%dm";
+#else
+ D_CAF = "\033[3%dm";
+ D_CAB = "\033[4%dm";
+#endif
+ }
+ if (D_OP && InStr(D_OP, "\033[39;49m"))
+ D_CAX = 1;
+ if (strcmp(D_termname, "xterm-color") == 0)
+ D_BE = 1;
+ /* ISO2022 */
+ if ((D_EA && InStr(D_EA, "\033(B")) || (D_AS && InStr(D_AS, "\033(0")))
+ D_CG0 = 1;
+ }
if (nwin_options.flowflag == nwin_undef.flowflag)
nwin_default.flowflag = D_CNF ? FLOW_NOW * 0 :
D_NX ? FLOW_NOW * 1 :
FLOW_AUTOFLAG;
- D_CLP |= (assume_LP || !D_AM || D_XV || D_XN ||
- (!extra_incap && !strncmp(D_termname, "vt", 2)));
+ D_CLP |= (assume_LP || !D_AM || D_XV || D_XN);
if (!D_BL)
D_BL = "\007";
if (!D_BC)
@@ -290,6 +326,8 @@ int he;
D_CAF = D_CSF;
D_CAB = D_CSB;
}
+ if (D_BE)
+ D_UT = 1; /* screen erased with background color */
if (!D_DO)
D_DO = D_NL;
@@ -310,6 +348,8 @@ int he;
D_VI = D_VS = 0;
if (D_CCE == 0)
D_CCS = 0;
+
+#ifdef FONT
if (D_CG0)
{
if (D_CS0 == 0)
@@ -321,6 +361,7 @@ int he;
if (D_CE0 == 0)
D_CE0 = "\033(B";
D_AC = 0;
+ D_EA = 0;
}
else if (D_AC || (D_AS && D_AE)) /* some kind of graphics */
{
@@ -348,13 +389,16 @@ int he;
for (i = strlen(D_CC0) & ~1; i >= 0; i -= 2)
D_c0_tab[(int)(unsigned char)D_CC0[i]] = D_CC0[i + 1];
debug1("ISO2022 = %d\n", D_CG0);
+#endif /* FONT */
if (D_PF == 0)
D_PO = 0;
debug2("terminal size is %d, %d (says TERMCAP)\n", D_CO, D_LI);
+#ifdef FONT
if (D_CXC)
if (CreateTransTable(D_CXC))
return -1;
+#endif
/* Termcap fields Z0 & Z1 contain width-changing sequences. */
if (D_CZ1 == 0)
@@ -372,6 +416,10 @@ int he;
if (D_WS <= 0)
D_WS = D_width;
}
+ D_has_hstatus = hardstatusemu & ~HSTATUS_ALWAYS;
+ if (D_HS && !(hardstatusemu & HSTATUS_ALWAYS))
+ D_has_hstatus = HSTATUS_HS;
+
#ifdef KANJI
D_kanji = 0;
if (D_CKJ)
@@ -382,6 +430,10 @@ int he;
D_kanji = SJIS;
}
#endif
+ if (!D_tcs[T_NAVIGATE].str && D_tcs[T_NAVIGATE + 1].str)
+ D_tcs[T_NAVIGATE].str = D_tcs[T_NAVIGATE + 1].str; /* kh = @1 */
+ if (!D_tcs[T_NAVIGATE + 2].str && D_tcs[T_NAVIGATE + 3].str)
+ D_tcs[T_NAVIGATE + 2].str = D_tcs[T_NAVIGATE + 3].str; /* kH = @7 */
D_UPcost = CalcCost(D_UP);
D_DOcost = CalcCost(D_DO);
@@ -403,6 +455,7 @@ int he;
{
debug1("termcap has OL (%d), setting limit\n", D_COL);
D_obufmax = D_COL;
+ D_obuflenmax = D_obuflen - D_obufmax;
}
#ifdef MAPKEYS
D_nseqs = 0;
@@ -493,13 +546,13 @@ CheckEscape()
for (display = displays; display; display = display->d_next)
{
for (i = 0; i < D_nseqs; i++)
- {
- nr = D_kmaps[i].nr & ~KMAP_NOTIMEOUT;
- if (umtab[nr].nr == RC_COMMAND)
- break;
- if (umtab[nr].nr == RC_ILLEGAL && dmtab[nr].nr == RC_COMMAND)
- break;
- }
+ {
+ nr = D_kmaps[i].nr & ~KMAP_NOTIMEOUT;
+ if (umtab[nr].nr == RC_COMMAND)
+ break;
+ if (umtab[nr].nr == RC_ILLEGAL && dmtab[nr].nr == RC_COMMAND)
+ break;
+ }
if (i >= D_nseqs)
break;
}
@@ -509,8 +562,10 @@ CheckEscape()
return;
}
ParseEscape((struct user *)0, "^aa");
- if (odisplay->d_user->u_Esc <= 0)
+ if (odisplay->d_user->u_Esc == -1)
odisplay->d_user->u_Esc = DefaultEsc;
+ if (odisplay->d_user->u_MetaEsc == -1)
+ odisplay->d_user->u_MetaEsc = DefaultMetaEsc;
display = 0;
Msg(0, "Warning: escape char set back to ^A");
display = odisplay;
@@ -570,7 +625,7 @@ int nr;
continue;
(*o)++;
}
-#ifdef DEBUG
+#ifdef DEBUGG
dumpmap();
#endif
return 0;
@@ -599,13 +654,13 @@ char *seq;
for (j = i + 1; j < D_nseqs; j++)
D_kmaps[j - 1] = D_kmaps[j];
D_nseqs--;
-#ifdef DEBUG
+#ifdef DEBUGG
dumpmap();
#endif
return 0;
}
-#ifdef DEBUG
+#ifdef DEBUGG
static void
dumpmap()
{
@@ -627,10 +682,13 @@ dumpmap()
debug2(" ==> %d%s\n", n & ~KMAP_NOTIMEOUT, (n & KMAP_NOTIMEOUT) ? " (no timeout)" : "");
}
}
-#endif
+#endif /* DEBUGG */
-#endif
+#endif /* MAPKEYS */
+/*
+ * Appends to the static variable Termcap
+ */
static void
AddCap(s)
char *s;
@@ -653,6 +711,10 @@ char *s;
Panic(0, "TERMCAP overflow - sorry.");
}
+/*
+ * Reads a displays capabilities and reconstructs a termcap entry in the
+ * global buffer "Termcap". A pointer to this buffer is returned.
+ */
char *
MakeTermcap(aflag)
int aflag;
@@ -696,17 +758,17 @@ int aflag;
if (!aflag && strlen(screenterm) + strlen(tname) < MAXSTR-1)
{
sprintf(p, "%s.%s", screenterm, tname);
- if (tgetent(buf, p) == 1)
+ if (e_tgetent(buf, p) == 1)
break;
}
if (wi >= 132)
{
sprintf(p, "%s-w", screenterm);
- if (tgetent(buf, p) == 1)
+ if (e_tgetent(buf, p) == 1)
break;
}
strcpy(p, screenterm);
- if (tgetent(buf, p) == 1)
+ if (e_tgetent(buf, p) == 1)
break;
strcpy(p, "vt100");
}
@@ -714,22 +776,21 @@ int aflag;
/* check for compatibility problems, displays == 0 after fork */
{
- char *tgetstr(), xbuf[TERMCAP_BUFSIZE], *xbp = xbuf;
+ char xbuf[TERMCAP_BUFSIZE], *xbp = xbuf;
if (tgetstr("im", &xbp) && tgetstr("ic", &xbp) && displays)
{
#ifdef TERMINFO
- Msg(0, "Warning: smir and ich1 set in %s terminfo entry", p);
+ Msg(0, "Warning: smir and ich1 set in %s terminfo entry", p);
#else
- Msg(0, "Warning: im and ic set in %s termcap entry", p);
+ Msg(0, "Warning: im and ic set in %s termcap entry", p);
#endif
}
}
-
+
tcLineLen = 100; /* Force NL */
if (strlen(Term) > TERMCAP_BUFSIZE - 40)
strcpy(Term, "too_long");
- sprintf(Termcap,
- "TERMCAP=SC|%s|VT 100/ANSI X3.64 virtual terminal", Term + 5);
+ sprintf(Termcap, "TERMCAP=SC|%s|VT 100/ANSI X3.64 virtual terminal:", Term + 5);
Termcaplen = strlen(Termcap);
debug1("MakeTermcap decided '%s'\n", p);
if (extra_outcap && *extra_outcap)
@@ -831,7 +892,7 @@ int aflag;
}
#endif
if (D_CG0)
- AddCap("G0:");
+ AddCap("G0:");
if (D_CC0 || (D_CS0 && *D_CS0))
{
AddCap("as=\\E(0:");
@@ -962,6 +1023,7 @@ char *s;
#define QUOTES(p) \
(*p == '\\' && (p[1] == '\\' || p[1] == ',' || p[1] == '%'))
+#ifdef FONT
int
CreateTransTable(s)
char *s;
@@ -1048,7 +1110,7 @@ char *s;
*sx++ = *p;
}
*sx = 0;
- ASSERT(ctable[c] + l == sx);
+ ASSERT(ctable[c] + l * templnsub + templlen == sx);
debug3("XC: %c %c->%s\n", curchar, c, ctable[c]);
}
if (*s == ',')
@@ -1073,10 +1135,11 @@ FreeTransTable()
for (j = 0; j < 257; j++, q++)
if (*q)
free(*q);
- free((char *)*p);
+ free(*p);
}
- free((char *)D_xtable);
+ free(D_xtable);
}
+#endif /* FONT */
static int
copyarg(pp, s)
@@ -1106,6 +1169,24 @@ char **pp, *s;
**
*/
+static int
+e_tgetent(bp, name)
+char *bp, *name;
+{
+ int r;
+
+#ifdef USE_SETEUID
+ xseteuid(real_uid);
+ xsetegid(real_gid);
+#endif
+ r = tgetent(bp, name);
+#ifdef USE_SETEUID
+ xseteuid(eff_uid);
+ xsetegid(eff_gid);
+#endif
+ return r;
+}
+
/* findcap:
* cap = capability we are looking for
@@ -1230,7 +1311,7 @@ e_tgetstr(cap, tepp)
char *cap;
char **tepp;
{
- char *tep, *tgetstr();
+ char *tep;
if ((tep = findcap(cap, tepp, 0)))
return (*tep == '@') ? 0 : tep;
return tgetstr(cap, tepp);
diff --git a/terminfo/README b/terminfo/README
index ccbf488..45b39e6 100644
--- a/terminfo/README
+++ b/terminfo/README
@@ -2,7 +2,8 @@
This directory contains various file for termcap/terminfo installation
and testing:
-screencap Termcap entry for screen. Add to /etc/termcap.
+screencap Termcap entry for screen. Add it to /etc/termcap.
+ On NetBSD, you should run /usr/bin/cap_mkdb afterwards.
screeninfo.src Terminfo entry. Use 'tic screeninfo.src'
to install (Sun: /usr/5bin/tic).
diff --git a/terminfo/sco.mail b/terminfo/sco.mail
deleted file mode 100644
index bd95e4f..0000000
--- a/terminfo/sco.mail
+++ /dev/null
@@ -1,65 +0,0 @@
-From root%mjbtn.UUCP@uunet.UU.NET Tue Oct 22 03:09:14 1991
-Received: from relay2.UU.NET by immd4.informatik.uni-erlangen.de with SMTP (5.64+/7.3a-FAU)
- id AA10018; Tue, 22 Oct 91 03:09:04 +0100
-Received: from uunet.uu.net (via LOCALHOST.UU.NET) by relay2.UU.NET with SMTP
- (5.61/UUNET-internet-primary) id AA09640; Mon, 21 Oct 91 22:09:07 -0400
-Received: from mjbtn.UUCP by uunet.uu.net with UUCP/RMAIL
- (queueing-rmail) id 220830.17203; Mon, 21 Oct 1991 22:08:30 EDT
-Received: by mjbtn.jobsoft.com (/\==/\ Smail3.1.21.1); Mon, 21 Oct 91 20:49 CDT
-Message-Id: <m0kZBFd-0007XHC@mjbtn.jobsoft.com>
-From: root@mjbtn.jobsoft.com (Mark J. Bailey [ADMIN])
-Subject: Re: oh yes
-To: jnweiger%immd4.informatik.uni-erlangen.de%uunet.UUCP@uunet.UU.NET (Juergen Weigert)
-Date: Mon, 21 Oct 91 20:49:49 CDT
-In-Reply-To: <9110212148.AA01737@faui43.informatik.uni-erlangen.de>; from "Juergen Weigert" at Oct 21, 91 10:48 pm
-X-Mailer: ELM [version 2.3 PL11]
-Status: OR
-
-Hi,
-
-Well, more playing and finally some progress! :-)
-
-This is my .screenrc:
-
-terminfo ansi G0:hs@:am:LP@:OP
-
-Now, I am not worried about its total accurracy, but I just wanted to show
-you what I tried. I also fixed a screen-25 terminfo entry:
-
-screen-25|VT 100/ANSI X3.64 virtual terminal,
- am, msgr, xon,
- cols#80, it#8, lines#25,
- bel=^G, blink=\E[5m, bold=\E[1m, cbt=\E[Z,
- clear=\E[H\E[J, cr=\r, csr=\E[%i%p1%d;%p2%dr,
- cub=\E[%p1%dD, cub1=\b, cud=\E[%p1%dB, cud1=\n,
- cuf=\E[%p1%dC, cuf1=\E[C, cup=\E[%i%p1%d;%p2%dH,
- cuu=\E[%p1%dA, cuu1=\EM, dl=\E[%p1%dM, dl1=\E[M,
- ed=\E[J, el=\E[K, home=\E[H, ht=\t, hts=\EH,
- il=\E[%p1%dL, il1=\E[L, ind=\n, is2=\E)0, kbs=\b,
- kcub1=\EOD, kcud1=\EOB, kcuf1=\EOC, kcuu1=\EOA,
- kf1=\EOP, kf2=\EOQ, kf3=\EOR, kf4=\EOS, khome=\E?,
- ll=\E[25H, nel=\EE, rc=\E8, rev=\E[7m, ri=\EM,
- rmkx=\E>, rmso=\E[23m, rmul=\E[24m, rs2=\Ec, sc=\E7,
- sgr0=\E[m, smkx=\E=, smso=\E[3m, smul=\E[4m,
- tbc=\E[3g,
-
-And notice for SCO Unix that I added 'am' to the entry for screen-25. Even
-though the external (login shell) type 'ansi' was modified with the .screenrc,
-when I added 'am' to the screen window term screen-25, it functioned flawlessly
-and I am not sure why. Anyway, vi and all the others seem to work great
-now. Next, I need to work on the G0 -> C0 graphics character mappings. I
-don't fully understand that yet. Anyway, this should be of help to others
-under SCO. BTW, that copy of the message you got from me that I sent to
-Ronald Khoo -- I applied SCO SLS patch xnx141 (for xenix) to fix the bug
-in select() when dealing with pipes, and it solved my problems on xenix.
-
-Mark.
-
---
-Mark J. Bailey, N4XHX _______/====X11====\_______
-USMAIL: 511 Memorial Blvd., Murfreesboro, TN 37129 | JobSoft |
-VOICE: +1 615 893 0098 | Design & Development Co.|
-UUCP: ...!uunet!mjbtn!mjb, ...!raider!mjbtn!mjb | Murfreesboro, TN USA |
-DOMAIN: mjb@mjbtn.JOBSOFT.COM CIS: 76314,160 ---------------------------
-<KA9Q-UNIX-USERS Mailing List-Subscribe: ka9q-unix-requests@mjbtn.jobsoft.com>
-
diff --git a/terminfo/screencap b/terminfo/screencap
index 5738532..d2becd4 100644
--- a/terminfo/screencap
+++ b/terminfo/screencap
@@ -12,8 +12,8 @@ SC|screen|VT 100/ANSI X3.64 virtual terminal:\
:ku=\EOA:kd=\EOB:kr=\EOC:kl=\EOD:kb=^H:\
:k1=\EOP:k2=\EOQ:k3=\EOR:k4=\EOS:k5=\E[15~:k6=\E[17~:\
:k7=\E[18~:k8=\E[19~:k9=\E[20~:k;=\E[21~:F1=\E[23~:F2=\E[24~:\
- :kh=\E[1~:kI=\E[2~:kD=\E[3~:kH=\E[4~:kP=\E[5~:kN=\E[6~:\
- :eA=\E(B\E)0:as=^N:ae=^O:\
+ :kh=\E[1~:kI=\E[2~:kD=\E[3~:kH=\E[4~:@7=\E[4~:kP=\E[5~:\
+ :kN=\E[6~:eA=\E(B\E)0:as=^N:ae=^O:\
:vi=\E[?25l:ve=\E[34h\E[?25h:vs=\E[34l:\
:Co#8:pa#64:AF=\E[3%dm:AB=\E[4%dm:op=\E[39;49m:AX:\
:ac=``aaffggjjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~..--++,,hhII00:
diff --git a/terminfo/screeninfo.src b/terminfo/screeninfo.src
index ab17d2d..b7e0c7f 100644
--- a/terminfo/screeninfo.src
+++ b/terminfo/screeninfo.src
@@ -13,7 +13,7 @@ screen|VT 100/ANSI X3.64 virtual terminal,
kcuf1=\EOC, kcuu1=\EOA, kdch1=\E[3~, kf1=\EOP,
kf10=\E[21~, kf11=\E[23~, kf12=\E[24~, kf2=\EOQ,
kf3=\EOR, kf4=\EOS, kf5=\E[15~, kf6=\E[17~,
- kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, khome=\E[1~,
+ kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, khome=\E[1~, kend=\E[4~,
kich1=\E[2~, kll=\E[4~, knp=\E[6~, kpp=\E[5~, nel=\EE,
rc=\E8, rev=\E[7m, ri=\EM, rmir=\E[4l, rmkx=\E[?1l\E>,
rmso=\E[23m, rmul=\E[24m, rs2=\Ec, sc=\E7, sgr0=\E[m,
@@ -37,7 +37,7 @@ screen-w|VT 100/ANSI X3.64 virtual terminal with 132 cols,
kcuf1=\EOC, kcuu1=\EOA, kdch1=\E[3~, kf1=\EOP,
kf10=\E[21~, kf11=\E[23~, kf12=\E[24~, kf2=\EOQ,
kf3=\EOR, kf4=\EOS, kf5=\E[15~, kf6=\E[17~,
- kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, khome=\E[1~,
+ kf7=\E[18~, kf8=\E[19~, kf9=\E[20~, khome=\E[1~, kend=\E[4~,
kich1=\E[2~, kll=\E[4~, knp=\E[6~, kpp=\E[5~, nel=\EE,
rc=\E8, rev=\E[7m, ri=\EM, rmir=\E[4l, rmkx=\E[?1l\E>,
rmso=\E[23m, rmul=\E[24m, rs2=\Ec, sc=\E7, sgr0=\E[m,
diff --git a/tty.c.dist b/tty.c.dist
index 572a3ff..2ce97b4 100644
--- a/tty.c.dist
+++ b/tty.c.dist
@@ -42,6 +42,9 @@ RCS_ID("$Id: tty.sh,v 1.13 1994/05/31 12:33:17 mlschroe Exp $ FAU")
# include <sys/ttold.h> /* needed for TIOCEXCL */
# endif
#endif
+#ifdef __hpux
+# include <sys/modem.h>
+#endif
#ifdef ISC
# include <sys/tty.h>
@@ -50,11 +53,27 @@ RCS_ID("$Id: tty.sh,v 1.13 1994/05/31 12:33:17 mlschroe Exp $ FAU")
#endif
#include "config.h"
+#ifdef SVR4
+#include <sys/stropts.h> /* for I_POP */
+#endif
+
#include "screen.h"
#include "extern.h"
+#if !defined(TIOCCONS) && defined(sun) && defined(SVR4)
+# include <sys/strredir.h>
+#endif
+
extern struct display *display, *displays;
extern int iflag;
+#if !defined(TIOCCONS) && defined(SRIOCSREDIR)
+extern struct win *console_window;
+static void consredir_readev_fn __P((struct event *, char *));
+#endif
+
+static void DoSendBreak __P((int, int, int));
+static sigret_t SigAlrmDummy __P(SIGPROTOARG);
+
/* Frank Schulz (fschulz@pyramid.com):
* I have no idea why VSTART is not defined and my fix is probably not
@@ -67,6 +86,18 @@ extern int iflag;
#define VSTOP _VSTOP
#endif
+#ifndef O_NOCTTY
+# define O_NOCTTY 0
+#endif
+
+#ifndef TTYVMIN
+# define TTYVMIN 1
+#endif
+#ifndef TTYVTIME
+#define TTYVTIME 0
+#endif
+
+
static sigret_t
SigAlrmDummy SIGDEFARG
{
@@ -75,27 +106,41 @@ SigAlrmDummy SIGDEFARG
}
/*
- * Carefully open a charcter device. Not used to open ttys.
+ * Carefully open a charcter device. Not used to open display ttys.
+ * The second parameter is parsed for a few stty style options.
*/
int
-OpenTTY(line)
-char *line;
+OpenTTY(line, opt)
+char *line, *opt;
{
int f;
+ struct mode Mode;
sigret_t (*sigalrm)__P(SIGPROTOARG);
sigalrm = signal(SIGALRM, SigAlrmDummy);
alarm(2);
+
/* this open only succeeds, if real uid is allowed */
- if ((f = secopen(line, O_RDWR | O_NONBLOCK, 0)) == -1)
+ if ((f = secopen(line, O_RDWR | O_NONBLOCK | O_NOCTTY, 0)) == -1)
{
- Msg(errno, "Cannot open line '%s' for R/W", line);
+ if (errno == EINTR)
+ Msg(0, "Cannot open line '%s' for R/W: open() blocked, aborted.", line);
+ else
+ Msg(errno, "Cannot open line '%s' for R/W", line);
alarm(0);
signal(SIGALRM, sigalrm);
return -1;
}
-#ifdef I_POP
+ if (!isatty(f))
+ {
+ Msg(0, "'%s' is not a tty", line);
+ alarm(0);
+ signal(SIGALRM, sigalrm);
+ close(f);
+ return -1;
+ }
+#if defined(I_POP) && defined(POP_TTYMODULES)
debug("OpenTTY I_POP\n");
while (ioctl(f, I_POP, (char *)0) >= 0)
;
@@ -109,7 +154,7 @@ char *line;
errno = 0;
if (ioctl(f, TIOCEXCL, (char *) 0) < 0)
Msg(errno, "%s: ioctl TIOCEXCL failed", line);
- debug3("%d %d %d\n", (int)getuid(), (int)geteuid(), (int)getpid());
+ debug3("%d %d %d\n", getuid(), geteuid(), getpid());
debug2("%s TIOCEXCL errno %d\n", line, errno);
#endif /* TIOCEXCL */
/*
@@ -119,22 +164,18 @@ char *line;
if (display)
{
debug1("OpenTTY: using mode of display for %s\n", line);
- SetTTY(f, &D_NewMode);
-#ifdef DEBUG
- DebugTTY(&D_NewMode);
-#endif
+ Mode = D_NewMode;
}
else
-#endif
- {
- struct mode Mode;
-
- InitTTY(&Mode, TTY_FLAG_PLAIN);
+#endif
+ InitTTY(&Mode, W_TYPE_PLAIN);
+
+ SttyMode(&Mode, opt);
#ifdef DEBUG
- DebugTTY(&Mode);
+ DebugTTY(&Mode);
#endif
- SetTTY(f, &Mode);
- }
+ SetTTY(f, &Mode);
+
brktty(f);
alarm(0);
signal(SIGALRM, sigalrm);
@@ -152,7 +193,7 @@ int intrc, origintrc = VDISABLE; /* display? */
#else
int intrc, origintrc = -1; /* display? */
#endif
-static startc, stopc; /* display? */
+static int startc, stopc; /* display? */
void
@@ -165,151 +206,196 @@ int ttyflag;
/* struct termios tio
* defaults, as seen on SunOS 4.1.3
*/
- debug1("InitTTY: POSIX: termios defaults a la SunOS 4.1.3 (%d)\n", ttyflag);
+ debug1("InitTTY: POSIX: termios defaults based on SunOS 4.1.3, but better (%d)\n", ttyflag);
#if defined(BRKINT)
- m->tio.c_iflag |= BRKINT;
+ m->tio.c_iflag |= BRKINT;
#endif /* BRKINT */
#if defined(IGNPAR)
- m->tio.c_iflag |= IGNPAR;
+ m->tio.c_iflag |= IGNPAR;
#endif /* IGNPAR */
-#if defined(ISTRIP)
- m->tio.c_iflag |= ISTRIP;
-#endif /* ISTRIP */
+/* IF{ISTRIP} m->tio.c_iflag |= ISTRIP; may be needed, let's try. jw. */
#if defined(IXON)
- m->tio.c_iflag |= IXON;
+ m->tio.c_iflag |= IXON;
#endif /* IXON */
-#if defined(IMAXBEL)
- m->tio.c_iflag |= IMAXBEL;
-#endif /* IMAXBEL */
+/* IF{IMAXBEL} m->tio.c_iflag |= IMAXBEL; sorry, this one is ridiculus. jw */
if (!ttyflag) /* may not even be good for ptys.. */
{
#if defined(ICRNL)
- m->tio.c_iflag |= ICRNL;
+ m->tio.c_iflag |= ICRNL;
#endif /* ICRNL */
#if defined(ONLCR)
- m->tio.c_oflag |= ONLCR;
+ m->tio.c_oflag |= ONLCR;
#endif /* ONLCR */
#if defined(TAB3)
- m->tio.c_oflag |= TAB3;
+ m->tio.c_oflag |= TAB3;
#endif /* TAB3 */
-#if defined(PARENB)
- m->tio.c_cflag |= PARENB;
-#endif /* PARENB */
+#if defined(OXTABS)
+ m->tio.c_oflag |= OXTABS;
+#endif /* OXTABS */
+/* IF{PARENB} m->tio.c_cflag |= PARENB; nah! jw. */
}
#if defined(OPOST)
- m->tio.c_oflag |= OPOST;
+ m->tio.c_oflag |= OPOST;
#endif /* OPOST */
+/*
+ * Or-ing the speed into c_cflags is dangerous.
+ * It breaks on bsdi, where c_ispeed and c_ospeed are extra longs.
+ *
+ * IF{B9600} m->tio.c_cflag |= B9600;
+ * IF{IBSHIFT) && defined(B9600} m->tio.c_cflag |= B9600 << IBSHIFT;
+ *
+ * We hope that we have the posix calls to do it right:
+ * If these are not available you might try the above.
+ */
#if defined(B9600)
- m->tio.c_cflag |= B9600;
+ cfsetospeed(&m->tio, B9600);
#endif /* B9600 */
+#if defined(B9600)
+ cfsetispeed(&m->tio, B9600);
+#endif /* B9600 */
+
#if defined(CS8)
- m->tio.c_cflag |= CS8;
+ m->tio.c_cflag |= CS8;
#endif /* CS8 */
#if defined(CREAD)
- m->tio.c_cflag |= CREAD;
+ m->tio.c_cflag |= CREAD;
#endif /* CREAD */
-#if defined(IBSHIFT) && defined(B9600)
- m->tio.c_cflag |= B9600 << IBSHIFT;
-#endif /* IBSHIFT) && defined(B9600 */
-/* IF{CLOCAL} m->tio.c_cflag |= CLOCAL; */
+#if defined(CLOCAL)
+ m->tio.c_cflag |= CLOCAL;
+#endif /* CLOCAL */
#if defined(ECHOCTL)
- m->tio.c_lflag |= ECHOCTL;
+ m->tio.c_lflag |= ECHOCTL;
#endif /* ECHOCTL */
#if defined(ECHOKE)
- m->tio.c_lflag |= ECHOKE;
+ m->tio.c_lflag |= ECHOKE;
#endif /* ECHOKE */
if (!ttyflag)
{
#if defined(ISIG)
- m->tio.c_lflag |= ISIG;
+ m->tio.c_lflag |= ISIG;
#endif /* ISIG */
#if defined(ICANON)
- m->tio.c_lflag |= ICANON;
+ m->tio.c_lflag |= ICANON;
#endif /* ICANON */
#if defined(ECHO)
- m->tio.c_lflag |= ECHO;
+ m->tio.c_lflag |= ECHO;
#endif /* ECHO */
}
#if defined(ECHOE)
- m->tio.c_lflag |= ECHOE;
+ m->tio.c_lflag |= ECHOE;
#endif /* ECHOE */
#if defined(ECHOK)
- m->tio.c_lflag |= ECHOK;
+ m->tio.c_lflag |= ECHOK;
#endif /* ECHOK */
#if defined(IEXTEN)
- m->tio.c_lflag |= IEXTEN;
+ m->tio.c_lflag |= IEXTEN;
#endif /* IEXTEN */
-#if defined(VINTR) && VINTR < MAXCC
- m->tio.c_cc[VINTR] = Ctrl('C');
+#if defined(VINTR)
+#if (VINTR < MAXCC)
+ m->tio.c_cc[VINTR] = Ctrl('C');
+#endif
#endif /* VINTR */
-#if defined(VQUIT) && VQUIT < MAXCC
- m->tio.c_cc[VQUIT] = Ctrl('\\');
+#if defined(VQUIT)
+#if (VQUIT < MAXCC)
+ m->tio.c_cc[VQUIT] = Ctrl('\\');
+#endif
#endif /* VQUIT */
-#if defined(VERASE) && VERASE < MAXCC
- m->tio.c_cc[VERASE] = 0x7f; /* DEL */
+#if defined(VERASE)
+#if (VERASE < MAXCC)
+ m->tio.c_cc[VERASE] = 0x7f; /* DEL */
+#endif
#endif /* VERASE */
-#if defined(VKILL) && VKILL < MAXCC
- m->tio.c_cc[VKILL] = Ctrl('H');
+#if defined(VKILL)
+#if (VKILL < MAXCC)
+ m->tio.c_cc[VKILL] = Ctrl('H');
+#endif
#endif /* VKILL */
-#if defined(VEOF) && VEOF < MAXCC
- m->tio.c_cc[VEOF] = Ctrl('D');
+#if defined(VEOF)
+#if (VEOF < MAXCC)
+ m->tio.c_cc[VEOF] = Ctrl('D');
+#endif
#endif /* VEOF */
-#if defined(VEOL) && VEOL < MAXCC
- m->tio.c_cc[VEOL] = 0000;
+#if defined(VEOL)
+#if (VEOL < MAXCC)
+ m->tio.c_cc[VEOL] = 0000;
+#endif
#endif /* VEOL */
-#if defined(VEOL2) && VEOL2 < MAXCC
- m->tio.c_cc[VEOL2] = 0000;
+#if defined(VEOL2)
+#if (VEOL2 < MAXCC)
+ m->tio.c_cc[VEOL2] = 0000;
+#endif
#endif /* VEOL2 */
-#if defined(VSWTCH) && VSWTCH < MAXCC
- m->tio.c_cc[VSWTCH] = 0000;
+#if defined(VSWTCH)
+#if (VSWTCH < MAXCC)
+ m->tio.c_cc[VSWTCH] = 0000;
+#endif
#endif /* VSWTCH */
-#if defined(VSTART) && VSTART < MAXCC
- m->tio.c_cc[VSTART] = Ctrl('Q');
+#if defined(VSTART)
+#if (VSTART < MAXCC)
+ m->tio.c_cc[VSTART] = Ctrl('Q');
+#endif
#endif /* VSTART */
-#if defined(VSTOP) && VSTOP < MAXCC
- m->tio.c_cc[VSTOP] = Ctrl('S');
+#if defined(VSTOP)
+#if (VSTOP < MAXCC)
+ m->tio.c_cc[VSTOP] = Ctrl('S');
+#endif
#endif /* VSTOP */
-#if defined(VSUSP) && VSUSP < MAXCC
- m->tio.c_cc[VSUSP] = Ctrl('Z');
+#if defined(VSUSP)
+#if (VSUSP < MAXCC)
+ m->tio.c_cc[VSUSP] = Ctrl('Z');
+#endif
#endif /* VSUSP */
-#if defined(VDSUSP) && VDSUSP < MAXCC
- m->tio.c_cc[VDSUSP] = Ctrl('Y');
+#if defined(VDSUSP)
+#if (VDSUSP < MAXCC)
+ m->tio.c_cc[VDSUSP] = Ctrl('Y');
+#endif
#endif /* VDSUSP */
-#if defined(VREPRINT) && VREPRINT < MAXCC
- m->tio.c_cc[VREPRINT] = Ctrl('R');
+#if defined(VREPRINT)
+#if (VREPRINT < MAXCC)
+ m->tio.c_cc[VREPRINT] = Ctrl('R');
+#endif
#endif /* VREPRINT */
-#if defined(VDISCARD) && VDISCARD < MAXCC
- m->tio.c_cc[VDISCARD] = Ctrl('O');
+#if defined(VDISCARD)
+#if (VDISCARD < MAXCC)
+ m->tio.c_cc[VDISCARD] = Ctrl('O');
+#endif
#endif /* VDISCARD */
-#if defined(VWERASE) && VWERASE < MAXCC
- m->tio.c_cc[VWERASE] = Ctrl('W');
+#if defined(VWERASE)
+#if (VWERASE < MAXCC)
+ m->tio.c_cc[VWERASE] = Ctrl('W');
+#endif
#endif /* VWERASE */
-#if defined(VLNEXT) && VLNEXT < MAXCC
- m->tio.c_cc[VLNEXT] = Ctrl('V');
+#if defined(VLNEXT)
+#if (VLNEXT < MAXCC)
+ m->tio.c_cc[VLNEXT] = Ctrl('V');
+#endif
#endif /* VLNEXT */
-#if defined(VSTATUS) && VSTATUS < MAXCC
- m->tio.c_cc[VSTATUS] = Ctrl('T');
+#if defined(VSTATUS)
+#if (VSTATUS < MAXCC)
+ m->tio.c_cc[VSTATUS] = Ctrl('T');
+#endif
#endif /* VSTATUS */
if (ttyflag)
{
- m->tio.c_cc[VMIN] = 1;
- m->tio.c_cc[VTIME] = 0;
+ m->tio.c_cc[VMIN] = TTYVMIN;
+ m->tio.c_cc[VTIME] = TTYVTIME;
}
-# ifdef hpux
+
+# ifdef HPUX_LTCHARS_HACK
m->m_ltchars.t_suspc = Ctrl('Z');
m->m_ltchars.t_dsuspc = Ctrl('Y');
m->m_ltchars.t_rprntc = Ctrl('R');
m->m_ltchars.t_flushc = Ctrl('O');
m->m_ltchars.t_werasc = Ctrl('W');
m->m_ltchars.t_lnextc = Ctrl('V');
-# endif /* hpux */
+# endif /* HPUX_LTCHARS_HACK */
#else /* POSIX */
@@ -323,87 +409,109 @@ int ttyflag;
* local: enable signals, erase/kill processing, echo on.
*/
#if defined(ISTRIP)
- m->tio.c_iflag |= ISTRIP;
+ m->tio.c_iflag |= ISTRIP;
#endif /* ISTRIP */
#if defined(IXON)
- m->tio.c_iflag |= IXON;
+ m->tio.c_iflag |= IXON;
#endif /* IXON */
#if defined(OPOST)
- m->tio.c_oflag |= OPOST;
+ m->tio.c_oflag |= OPOST;
#endif /* OPOST */
if (!ttyflag) /* may not even be good for ptys.. */
{
#if defined(ICRNL)
- m->tio.c_iflag |= ICRNL;
+ m->tio.c_iflag |= ICRNL;
#endif /* ICRNL */
#if defined(ONLCR)
- m->tio.c_oflag |= ONLCR;
+ m->tio.c_oflag |= ONLCR;
#endif /* ONLCR */
#if defined(TAB3)
- m->tio.c_oflag |= TAB3;
+ m->tio.c_oflag |= TAB3;
#endif /* TAB3 */
}
+#ifdef __bsdi__
+ )-: cannot handle BSDI without POSIX
+#else
#if defined(B9600)
- m->tio.c_cflag = B9600;
+ m->tio.c_cflag = B9600;
#endif /* B9600 */
+#endif
#if defined(CS8)
- m->tio.c_cflag |= CS8;
+ m->tio.c_cflag |= CS8;
#endif /* CS8 */
#if defined(CREAD)
- m->tio.c_cflag |= CREAD;
+ m->tio.c_cflag |= CREAD;
#endif /* CREAD */
if (!ttyflag)
{
#if defined(ISIG)
- m->tio.c_lflag |= ISIG;
+ m->tio.c_lflag |= ISIG;
#endif /* ISIG */
#if defined(ICANON)
- m->tio.c_lflag |= ICANON;
+ m->tio.c_lflag |= ICANON;
#endif /* ICANON */
#if defined(ECHO)
- m->tio.c_lflag |= ECHO;
+ m->tio.c_lflag |= ECHO;
#endif /* ECHO */
}
#if defined(ECHOE)
- m->tio.c_lflag |= ECHOE;
+ m->tio.c_lflag |= ECHOE;
#endif /* ECHOE */
#if defined(ECHOK)
- m->tio.c_lflag |= ECHOK;
+ m->tio.c_lflag |= ECHOK;
#endif /* ECHOK */
-#if defined(VINTR) && VINTR < MAXCC
- m->tio.c_cc[VINTR] = Ctrl('C');
+#if defined(VINTR)
+#if (VINTR < MAXCC)
+ m->tio.c_cc[VINTR] = Ctrl('C');
+#endif
#endif /* VINTR */
-#if defined(VQUIT) && VQUIT < MAXCC
- m->tio.c_cc[VQUIT] = Ctrl('\\');
+#if defined(VQUIT)
+#if (VQUIT < MAXCC)
+ m->tio.c_cc[VQUIT] = Ctrl('\\');
+#endif
#endif /* VQUIT */
-#if defined(VERASE) && VERASE < MAXCC
- m->tio.c_cc[VERASE] = 0177; /* DEL */
+#if defined(VERASE)
+#if (VERASE < MAXCC)
+ m->tio.c_cc[VERASE] = 0177; /* DEL */
+#endif
#endif /* VERASE */
-#if defined(VKILL) && VKILL < MAXCC
- m->tio.c_cc[VKILL] = Ctrl('H');
+#if defined(VKILL)
+#if (VKILL < MAXCC)
+ m->tio.c_cc[VKILL] = Ctrl('H');
+#endif
#endif /* VKILL */
-#if defined(VEOF) && VEOF < MAXCC
- m->tio.c_cc[VEOF] = Ctrl('D');
+#if defined(VEOF)
+#if (VEOF < MAXCC)
+ m->tio.c_cc[VEOF] = Ctrl('D');
+#endif
#endif /* VEOF */
-#if defined(VEOL) && VEOL < MAXCC
- m->tio.c_cc[VEOL] = 0377;
+#if defined(VEOL)
+#if (VEOL < MAXCC)
+ m->tio.c_cc[VEOL] = 0377;
+#endif
#endif /* VEOL */
-#if defined(VEOL2) && VEOL2 < MAXCC
- m->tio.c_cc[VEOL2] = 0377;
+#if defined(VEOL2)
+#if (VEOL2 < MAXCC)
+ m->tio.c_cc[VEOL2] = 0377;
+#endif
#endif /* VEOL2 */
-#if defined(VSWTCH) && VSWTCH < MAXCC
- m->tio.c_cc[VSWTCH] = 0000;
+#if defined(VSWTCH)
+#if (VSWTCH < MAXCC)
+ m->tio.c_cc[VSWTCH] = 0000;
+#endif
#endif /* VSWTCH */
+
if (ttyflag)
- {
- m->tio.c_cc[VMIN] = 1;
- m->tio.c_cc[VTIME] = 0;
- }
+ {
+ m->tio.c_cc[VMIN] = TTYVMIN;
+ m->tio.c_cc[VTIME] = TTYVTIME;
+ }
+
# else /* TERMIO */
debug1("InitTTY: BSD: defaults a la SunOS 4.1.3 (%d)\n", ttyflag);
m->m_ttyb.sg_ispeed = B9600;
@@ -413,13 +521,13 @@ int ttyflag;
if (!ttyflag)
m->m_ttyb.sg_flags = CRMOD | ECHO
#if defined(ANYP)
- | ANYP
+ | ANYP
#endif /* ANYP */
;
else
m->m_ttyb.sg_flags = CBREAK
#if defined(ANYP)
- | ANYP
+ | ANYP
#endif /* ANYP */
;
@@ -438,33 +546,33 @@ int ttyflag;
m->m_ltchars.t_lnextc = Ctrl('V');
#if defined(NTTYDISC)
- m->m_ldisc = NTTYDISC;
+ m->m_ldisc = NTTYDISC;
#endif /* NTTYDISC */
m->m_lmode = 0
#if defined(LDECCTQ)
- | LDECCTQ
+ | LDECCTQ
#endif /* LDECCTQ */
#if defined(LCTLECH)
- | LCTLECH
+ | LCTLECH
#endif /* LCTLECH */
#if defined(LPASS8)
- | LPASS8
+ | LPASS8
#endif /* LPASS8 */
#if defined(LCRTKIL)
- | LCRTKIL
+ | LCRTKIL
#endif /* LCRTKIL */
#if defined(LCRTERA)
- | LCRTERA
+ | LCRTERA
#endif /* LCRTERA */
#if defined(LCRTBS)
- | LCRTBS
+ | LCRTBS
#endif /* LCRTBS */
-;
+ ;
# endif /* TERMIO */
#endif /* POSIX */
-#if defined(KANJI) && defined(TIOCKSET) && defined(KM_ASCII) && defined(KM_SYSSJIS)
+#if defined(KANJI) && defined(TIOCKSET)
m->m_jtchars.t_ascii = 'J';
m->m_jtchars.t_kanji = 'B';
m->m_knjmode = KM_ASCII | KM_SYSSJIS;
@@ -479,7 +587,7 @@ struct mode *mp;
errno = 0;
#ifdef POSIX
tcsetattr(fd, TCSADRAIN, &mp->tio);
-# ifdef hpux
+# ifdef HPUX_LTCHARS_HACK
ioctl(fd, TIOCSLTC, (char *)&mp->m_ltchars);
# endif
#else
@@ -502,7 +610,7 @@ struct mode *mp;
ioctl(fd, TIOCSLTC, (char *)&mp->m_ltchars); /* moved here for apollo. jw */
# endif
#endif
-#if defined(KANJI) && defined(TIOCKSET) && defined(KM_ASCII) && defined(KM_SYSSJIS)
+#if defined(KANJI) && defined(TIOCKSET)
ioctl(fd, TIOCKSETC, &mp->m_jtchars);
ioctl(fd, TIOCKSET, &mp->m_knjmode);
#endif
@@ -518,7 +626,7 @@ struct mode *mp;
errno = 0;
#ifdef POSIX
tcgetattr(fd, &mp->tio);
-# ifdef hpux
+# ifdef HPUX_LTCHARS_HACK
ioctl(fd, TIOCGLTC, (char *)&mp->m_ltchars);
# endif
#else
@@ -546,7 +654,7 @@ struct mode *mp;
ioctl(fd, TIOCGETD, (char *)&mp->m_ldisc);
# endif
#endif
-#if defined(KANJI) && defined(TIOCKSET) && defined(KM_ASCII) && defined(KM_SYSSJIS)
+#if defined(KANJI) && defined(TIOCKSET)
ioctl(fd, TIOCKGETC, &mp->m_jtchars);
ioctl(fd, TIOCKGET, &mp->m_knjmode);
#endif
@@ -554,9 +662,13 @@ struct mode *mp;
Msg(errno, "GetTTY (fd %d): ioctl failed", fd);
}
+/*
+ * needs interrupt = iflag and flow = d->d_flow
+ */
void
-SetMode(op, np)
+SetMode(op, np, flow, interrupt)
struct mode *op, *np;
+int flow, interrupt;
{
*np = *op;
@@ -567,17 +679,21 @@ struct mode *op, *np;
np->tio.c_line = 0;
# endif
#if defined(ICRNL)
- np->tio.c_iflag &= ~ICRNL;
+ np->tio.c_iflag &= ~ICRNL;
#endif /* ICRNL */
+#if defined(ISTRIP)
+ np->tio.c_iflag &= ~ISTRIP;
+#endif /* ISTRIP */
#if defined(ONLCR)
- np->tio.c_oflag &= ~ONLCR;
+ np->tio.c_oflag &= ~ONLCR;
#endif /* ONLCR */
np->tio.c_lflag &= ~(ICANON | ECHO);
/*
* From Andrew Myers (andru@tonic.lcs.mit.edu)
+ * to avoid ^V^V-Problem on OSF1
*/
#if defined(IEXTEN)
- np->tio.c_lflag &= ~IEXTEN;
+ np->tio.c_lflag &= ~IEXTEN;
#endif /* IEXTEN */
/*
@@ -589,23 +705,31 @@ struct mode *op, *np;
* tty) and forwards it to the master [kill(MasterPid, SIGINT)].
* Marc Boucher (marc@CAM.ORG)
*/
- if (iflag)
+ if (interrupt)
np->tio.c_lflag |= ISIG;
else
np->tio.c_lflag &= ~ISIG;
/*
* careful, careful catche monkey..
* never set VMIN and VTIME to zero, if you want blocking io.
+ *
+ * We may want to do a VMIN > 0, VTIME > 0 read on the ptys too, to
+ * reduce interrupt frequency. But then we would not know how to
+ * handle read returning 0. jw.
*/
np->tio.c_cc[VMIN] = 1;
np->tio.c_cc[VTIME] = 0;
-#if defined(VSTART) && VSTART < MAXCC
- startc = op->tio.c_cc[VSTART];
+#if defined(VSTART)
+#if (VSTART < MAXCC)
+ startc = op->tio.c_cc[VSTART];
+#endif
#endif /* VSTART */
-#if defined(VSTOP) && VSTOP < MAXCC
- stopc = op->tio.c_cc[VSTOP];
+#if defined(VSTOP)
+#if (VSTOP < MAXCC)
+ stopc = op->tio.c_cc[VSTOP];
+#endif
#endif /* VSTOP */
- if (iflag)
+ if (interrupt)
origintrc = intrc = op->tio.c_cc[VINTR];
else
{
@@ -613,57 +737,79 @@ struct mode *op, *np;
intrc = np->tio.c_cc[VINTR] = VDISABLE;
}
np->tio.c_cc[VQUIT] = VDISABLE;
- if (D_flow == 0)
+ if (flow == 0)
{
np->tio.c_cc[VINTR] = VDISABLE;
-#if defined(VSTART) && VSTART < MAXCC
- np->tio.c_cc[VSTART] = VDISABLE;
+#if defined(VSTART)
+#if (VSTART < MAXCC)
+ np->tio.c_cc[VSTART] = VDISABLE;
+#endif
#endif /* VSTART */
-#if defined(VSTOP) && VSTOP < MAXCC
- np->tio.c_cc[VSTOP] = VDISABLE;
+#if defined(VSTOP)
+#if (VSTOP < MAXCC)
+ np->tio.c_cc[VSTOP] = VDISABLE;
+#endif
#endif /* VSTOP */
np->tio.c_iflag &= ~IXON;
}
-#if defined(VDISCARD) && VDISCARD < MAXCC
- np->tio.c_cc[VDISCARD] = VDISABLE;
+#if defined(VDISCARD)
+#if (VDISCARD < MAXCC)
+ np->tio.c_cc[VDISCARD] = VDISABLE;
+#endif
#endif /* VDISCARD */
-#if defined(VLNEXT) && VLNEXT < MAXCC
- np->tio.c_cc[VLNEXT] = VDISABLE;
+#if defined(VLNEXT)
+#if (VLNEXT < MAXCC)
+ np->tio.c_cc[VLNEXT] = VDISABLE;
+#endif
#endif /* VLNEXT */
-#if defined(VSTATUS) && VSTATUS < MAXCC
- np->tio.c_cc[VSTATUS] = VDISABLE;
+#if defined(VSTATUS)
+#if (VSTATUS < MAXCC)
+ np->tio.c_cc[VSTATUS] = VDISABLE;
+#endif
#endif /* VSTATUS */
-#if defined(VSUSP) && VSUSP < MAXCC
- np->tio.c_cc[VSUSP] = VDISABLE;
+#if defined(VSUSP)
+#if (VSUSP < MAXCC)
+ np->tio.c_cc[VSUSP] = VDISABLE;
+#endif
#endif /* VSUSP */
-#if defined(VERASE) && VERASE < MAXCC
- np->tio.c_cc[VERASE] = VDISABLE;
+#if defined(VERASE)
+#if (VERASE < MAXCC)
+ np->tio.c_cc[VERASE] = VDISABLE;
+#endif
#endif /* VERASE */
-#if defined(VKILL) && VKILL < MAXCC
- np->tio.c_cc[VKILL] = VDISABLE;
+#if defined(VKILL)
+#if (VKILL < MAXCC)
+ np->tio.c_cc[VKILL] = VDISABLE;
+#endif
#endif /* VKILL */
-# ifdef hpux
+# ifdef HPUX_LTCHARS_HACK
np->m_ltchars.t_suspc = VDISABLE;
np->m_ltchars.t_dsuspc = VDISABLE;
np->m_ltchars.t_rprntc = VDISABLE;
np->m_ltchars.t_flushc = VDISABLE;
np->m_ltchars.t_werasc = VDISABLE;
np->m_ltchars.t_lnextc = VDISABLE;
-# else /* hpux */
-#if defined(VDSUSP) && VDSUSP < MAXCC
- np->tio.c_cc[VDSUSP] = VDISABLE;
+# else /* HPUX_LTCHARS_HACK */
+#if defined(VDSUSP)
+#if (VDSUSP < MAXCC)
+ np->tio.c_cc[VDSUSP] = VDISABLE;
+#endif
#endif /* VDSUSP */
-#if defined(VREPRINT) && VREPRINT < MAXCC
- np->tio.c_cc[VREPRINT] = VDISABLE;
+#if defined(VREPRINT)
+#if (VREPRINT < MAXCC)
+ np->tio.c_cc[VREPRINT] = VDISABLE;
+#endif
#endif /* VREPRINT */
-#if defined(VWERASE) && VWERASE < MAXCC
- np->tio.c_cc[VWERASE] = VDISABLE;
+#if defined(VWERASE)
+#if (VWERASE < MAXCC)
+ np->tio.c_cc[VWERASE] = VDISABLE;
+#endif
#endif /* VWERASE */
-# endif /* hpux */
+# endif /* HPUX_LTCHARS_HACK */
#else /* TERMIO || POSIX */
startc = op->m_tchars.t_startc;
stopc = op->m_tchars.t_stopc;
- if (iflag)
+ if (interrupt)
origintrc = intrc = op->m_tchars.t_intrc;
else
{
@@ -677,7 +823,7 @@ struct mode *op, *np;
np->m_ttyb.sg_flags |= CS_8BITS;
# endif
np->m_tchars.t_quitc = -1;
- if (D_flow == 0)
+ if (flow == 0)
{
np->m_tchars.t_intrc = -1;
np->m_tchars.t_startc = -1;
@@ -690,6 +836,7 @@ struct mode *op, *np;
#endif /* defined(TERMIO) || defined(POSIX) */
}
+/* operates on display */
void
SetFlow(on)
int on;
@@ -701,22 +848,30 @@ int on;
if (on)
{
D_NewMode.tio.c_cc[VINTR] = intrc;
-#if defined(VSTART) && VSTART < MAXCC
- D_NewMode.tio.c_cc[VSTART] = startc;
+#if defined(VSTART)
+#if (VSTART < MAXCC)
+ D_NewMode.tio.c_cc[VSTART] = startc;
+#endif
#endif /* VSTART */
-#if defined(VSTOP) && VSTOP < MAXCC
- D_NewMode.tio.c_cc[VSTOP] = stopc;
+#if defined(VSTOP)
+#if (VSTOP < MAXCC)
+ D_NewMode.tio.c_cc[VSTOP] = stopc;
+#endif
#endif /* VSTOP */
D_NewMode.tio.c_iflag |= IXON;
}
else
{
D_NewMode.tio.c_cc[VINTR] = VDISABLE;
-#if defined(VSTART) && VSTART < MAXCC
- D_NewMode.tio.c_cc[VSTART] = VDISABLE;
+#if defined(VSTART)
+#if (VSTART < MAXCC)
+ D_NewMode.tio.c_cc[VSTART] = VDISABLE;
+#endif
#endif /* VSTART */
-#if defined(VSTOP) && VSTOP < MAXCC
- D_NewMode.tio.c_cc[VSTOP] = VDISABLE;
+#if defined(VSTOP)
+#if (VSTOP < MAXCC)
+ D_NewMode.tio.c_cc[VSTOP] = VDISABLE;
+#endif
#endif /* VSTOP */
D_NewMode.tio.c_iflag &= ~IXON;
}
@@ -745,6 +900,97 @@ int on;
D_flow = on;
}
+/* parse commands from opt and modify m */
+int
+SttyMode(m, opt)
+struct mode *m;
+char *opt;
+{
+ static const char sep[] = " \t:;,";
+
+ if (!opt)
+ return 0;
+
+ while (*opt)
+ {
+ while (index(sep, *opt)) opt++;
+ if (*opt >= '0' && *opt <= '9')
+ {
+ if (SetBaud(m, atoi(opt), atoi(opt)))
+ return -1;
+ }
+ else if (!strncmp("cs7", opt, 3))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_cflag &= ~CSIZE;
+ m->tio.c_cflag |= CS7;
+#else
+ m->m_lmode &= ~LPASS8;
+#endif
+ }
+ else if (!strncmp("cs8", opt, 3))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_cflag &= ~CSIZE;
+ m->tio.c_cflag |= CS8;
+#else
+ m->m_lmode |= LPASS8;
+#endif
+ }
+ else if (!strncmp("istrip", opt, 6))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_iflag |= ISTRIP;
+#else
+ m->m_lmode &= ~LPASS8;
+#endif
+ }
+ else if (!strncmp("-istrip", opt, 7))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_iflag &= ~ISTRIP;
+#else
+ m->m_lmode |= LPASS8;
+#endif
+ }
+ else if (!strncmp("ixon", opt, 4))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_iflag |= IXON;
+#else
+ debug("SttyMode: no ixon in old bsd land.\n");
+#endif
+ }
+ else if (!strncmp("-ixon", opt, 5))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_iflag &= ~IXON;
+#else
+ debug("SttyMode: no -ixon in old bsd land.\n");
+#endif
+ }
+ else if (!strncmp("ixoff", opt, 5))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_iflag |= IXOFF;
+#else
+ m->m_ttyb.sg_flags |= TANDEM;
+#endif
+ }
+ else if (!strncmp("-ixoff", opt, 6))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_iflag &= ~IXOFF;
+#else
+ m->m_ttyb.sg_flags &= ~TANDEM;
+#endif
+ }
+ else
+ return -1;
+ while (*opt && !index(sep, *opt)) opt++;
+ }
+ return 0;
+}
/*
* Job control handling
@@ -792,6 +1038,9 @@ int fd;
/* The next lines should be obsolete. Can anybody check if they
* are really needed on the BSD platforms?
+ *
+ * this is to avoid the message:
+ * fgtty: Not a typewriter (25)
*/
# if defined(__osf__) || (BSD >= 199103) || defined(ISC)
setsid(); /* should be already done */
@@ -818,19 +1067,154 @@ int fd;
return 0;
}
+/*
+ * The alm boards on our sparc center 1000 have a lousy driver.
+ * We cannot generate long breaks unless we use the most ugly form
+ * of ioctls. jw.
+ */
+#ifdef POSIX
+int breaktype = 2;
+#else /* POSIX */
+# ifdef TCSBRK
+int breaktype = 1;
+# else
+int breaktype = 0;
+# endif
+#endif /* POSIX */
+
+#if defined(sun) && !defined(SVR4)
+# define HAVE_SUPER_TCSENDBREAK
+#endif
+
+/*
+ * type:
+ * 0: TIOCSBRK / TIOCCBRK
+ * 1: TCSBRK
+ * 2: tcsendbreak()
+ * n: approximate duration in 1/4 seconds.
+ */
+static void
+DoSendBreak(fd, n, type)
+int fd, n, type;
+{
+ switch (type)
+ {
+ case 2: /* tcsendbreak() =============================== */
+#ifdef POSIX
+# ifdef HAVE_SUPER_TCSENDBREAK
+ /* There is one rare case that I have tested, where tcsendbreak works
+ * really great: this was an alm driver that came with SunOS 4.1.3
+ * If you have this one, define the above symbol.
+ * here we can use the second parameter to specify the duration.
+ */
+ debug2("tcsendbreak(fd=%d, %d)\n", fd, n);
+ if (tcsendbreak(fd, n) < 0)
+ Msg(errno, "cannot send BREAK (tcsendbreak)");
+# else
+ /*
+ * here we hope, that multiple calls to tcsendbreak() can
+ * be concatenated to form a long break, as we do not know
+ * what exact interpretation the second parameter has:
+ *
+ * - sunos 4: duration in quarter seconds
+ * - sunos 5: 0 a short break, nonzero a tcdrain()
+ * - hpux, irix: ignored
+ * - mot88: duration in milliseconds
+ * - aix: duration in milliseconds, but 0 is 25 milliseconds.
+ */
+ debug2("%d * tcsendbreak(fd=%d, 0)\n", n, fd);
+ {
+ int i;
+
+ for (i = 0; i < n; i++)
+ if (tcsendbreak(fd, 0) < 0)
+ {
+ Msg(errno, "cannot send BREAK (tcsendbreak SVR4)");
+ return;
+ }
+ }
+# endif
+#else /* POSIX */
+ Msg(0, "tcsendbreak() not available, change breaktype");
+#endif /* POSIX */
+ break;
+
+ case 1: /* TCSBRK ======================================= */
+#ifdef TCSBRK
+ if (!n)
+ n++;
+ /*
+ * Here too, we assume that short breaks can be concatenated to
+ * perform long breaks. But for SOLARIS, this is not true, of course.
+ */
+ debug2("%d * TCSBRK fd=%d\n", n, fd);
+ {
+ int i;
+
+ for (i = 0; i < n; i++)
+ if (ioctl(fd, TCSBRK, (char *)0) < 0)
+ {
+ Msg(errno, "Cannot send BREAK (TCSBRK)");
+ return;
+ }
+ }
+#else /* TCSBRK */
+ Msg(0, "TCSBRK not available, change breaktype");
+#endif /* TCSBRK */
+ break;
+
+ case 0: /* TIOCSBRK / TIOCCBRK ========================== */
+#if defined(TIOCSBRK) && defined(TIOCCBRK)
+ /*
+ * This is very rude. Screen actively celebrates the break.
+ * But it may be the only save way to issue long breaks.
+ */
+ debug("TIOCSBRK TIOCCBRK\n");
+ if (ioctl(fd, TIOCSBRK, (char *)0) < 0)
+ {
+ Msg(errno, "Can't send BREAK (TIOCSBRK)");
+ return;
+ }
+ sleep1000(n ? n * 250 : 250);
+ if (ioctl(fd, TIOCCBRK, (char *)0) < 0)
+ {
+ Msg(errno, "BREAK stuck!!! -- HELP! (TIOCCBRK)");
+ return;
+ }
+#else /* TIOCSBRK && TIOCCBRK */
+ Msg(0, "TIOCSBRK/CBRK not available, change breaktype");
+#endif /* TIOCSBRK && TIOCCBRK */
+ break;
+
+ default: /* unknown ========================== */
+ Msg(0, "Internal SendBreak error: method %d unknown", type);
+ }
+}
/*
* Send a break for n * 0.25 seconds. Tty must be PLAIN.
+ * The longest possible break allowed here is 15 seconds.
*/
-void SendBreak(wp, n, closeopen)
+void
+SendBreak(wp, n, closeopen)
struct win *wp;
int n, closeopen;
{
- if ((wp->w_t.flags & TTY_FLAG_PLAIN) == 0)
+ sigret_t (*sigalrm)__P(SIGPROTOARG);
+
+#ifdef BUILTIN_TELNET
+ if (wp->w_type == W_TYPE_TELNET)
+ {
+ TelBreak(wp);
+ return;
+ }
+#endif
+ if (wp->w_type != W_TYPE_PLAIN)
return;
debug3("break(%d, %d) fd %d\n", n, closeopen, wp->w_ptyfd);
+
#ifdef POSIX
(void) tcflush(wp->w_ptyfd, TCIOFLUSH);
#else
@@ -838,11 +1222,12 @@ int n, closeopen;
(void) ioctl(wp->w_ptyfd, TIOCFLUSH, (char *)0);
# endif /* TIOCFLUSH */
#endif /* POSIX */
+
if (closeopen)
{
close(wp->w_ptyfd);
- sleep((n + 3) / 4);
- if ((wp->w_ptyfd = OpenTTY(wp->w_tty)) < 1)
+ sleep1000(n ? n * 250 : 250);
+ if ((wp->w_ptyfd = OpenTTY(wp->w_tty, wp->w_cmdargs[1])) < 1)
{
Msg(0, "Ouch, cannot reopen line %s, please try harder", wp->w_tty);
return;
@@ -851,56 +1236,56 @@ int n, closeopen;
}
else
{
-#ifdef POSIX
- debug("tcsendbreak\n");
- if (tcsendbreak(wp->w_ptyfd, n) < 0)
- {
- Msg(errno, "cannot send BREAK");
- return;
- }
-#else
- if (!n)
- n++;
-# ifdef TCSBRK
- debug("TCSBRK\n");
- {
- int i;
- for (i = 0; i < n; i++)
- if (ioctl(wp->w_ptyfd, TCSBRK, (char *)0) < 0)
- {
- Msg(errno, "Cannot send BREAK");
- return;
- }
- }
-# else /* TCSBRK */
-# if defined(TIOCSBRK) && defined(TIOCCBRK)
- debug("TIOCSBRK TIOCCBRK\n");
- if (ioctl(wp->w_ptyfd, TIOCSBRK, (char *)0) < 0)
- {
- Msg(errno, "Can't send BREAK");
- return;
- }
- sleep((n + 3) / 4);
- if (ioctl(wp->w_ptyfd, TIOCCBRK, (char *)0) < 0)
- {
- Msg(errno, "BREAK stuck!!! -- HELP!");
- return;
- }
-# else /* TIOCSBRK && TIOCCBRK */
- Msg(0, "Break not simulated yet");
- return;
-# endif /* TIOCSBRK && TIOCCBRK */
-# endif /* TCSBRK */
-#endif /* POSIX */
- debug(" broken\n");
+ sigalrm = signal(SIGALRM, SigAlrmDummy);
+ alarm(15);
+
+ DoSendBreak(wp->w_ptyfd, n, breaktype);
+
+ alarm(0);
+ signal(SIGALRM, sigalrm);
}
+ debug(" broken.\n");
}
-
/*
* Console grabbing
*/
+#if !defined(TIOCCONS) && defined(SRIOCSREDIR)
+
+struct event consredir_ev;
+int consredirfd[2] = {-1, -1};
+
+static void
+consredir_readev_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ char *p, *n, buf[256];
+ int l;
+
+ if (!console_window || (l = read(consredirfd[0], buf, sizeof(buf))) <= 0)
+ {
+ close(consredirfd[0]);
+ close(consredirfd[1]);
+ consredirfd[0] = consredirfd[1] = -1;
+ evdeq(ev);
+ return;
+ }
+ for (p = n = buf; l > 0; n++, l--)
+ if (*n == '\n')
+ {
+ if (n > p)
+ WriteString(console_window, p, n - p);
+ WriteString(console_window, "\r\n", 2);
+ p = n + 1;
+ }
+ if (n > p)
+ WriteString(console_window, p, n - p);
+}
+
+#endif
+
/*ARGSUSED*/
int
TtyGrabConsole(fd, on, rc_name)
@@ -908,12 +1293,32 @@ int fd, on;
char *rc_name;
{
#ifdef TIOCCONS
- char *slave;
- int sfd = -1, ret = 0;
struct display *d;
+ int ret = 0;
+ int sfd = -1;
+
+ if (on < 0)
+ return; /* pty close will ungrab */
+ if (on)
+ {
+ if (displays == 0)
+ {
+ Msg(0, "I need a display");
+ return -1;
+ }
+ for (d = displays; d; d = d->d_next)
+ if (strcmp(d->d_usertty, "/dev/console") == 0)
+ break;
+ if (d)
+ {
+ Msg(0, "too dangerous - screen is running on /dev/console");
+ return -1;
+ }
+ }
if (!on)
{
+ char *slave;
if ((fd = OpenPTY(&slave)) < 0)
{
Msg(errno, "%s: could not open detach pty master", rc_name);
@@ -926,7 +1331,24 @@ char *rc_name;
return -1;
}
}
- else
+ if (UserContext() == 1)
+ UserReturn(ioctl(fd, TIOCCONS, (char *)&on));
+ ret = UserStatus();
+ if (ret)
+ Msg(errno, "%s: ioctl TIOCCONS failed", rc_name);
+ if (!on)
+ {
+ close(sfd);
+ close(fd);
+ }
+ return ret;
+
+#else
+# ifdef SRIOCSREDIR
+ struct display *d;
+ int cfd;
+
+ if (on > 0)
{
if (displays == 0)
{
@@ -942,23 +1364,434 @@ char *rc_name;
return -1;
}
}
- if (UserContext() == 1)
- UserReturn(ioctl(fd, TIOCCONS, (char *)&on));
- ret = UserStatus();
- if (ret)
- Msg(errno, "%s: ioctl TIOCCONS failed", rc_name);
- if (!on)
+ if (consredirfd[0] >= 0)
{
- close(sfd);
- close(fd);
+ evdeq(&consredir_ev);
+ close(consredirfd[0]);
+ close(consredirfd[1]);
+ consredirfd[0] = consredirfd[1] = -1;
}
- return ret;
-#else /* TIOCCONS */
- Msg(0, "%s: no TIOCCONS on this machine", rc_name);
+ if (on <= 0)
+ return 0;
+ if ((cfd = secopen("/dev/console", O_RDWR|O_NOCTTY, 0)) == -1)
+ {
+ Msg(errno, "/dev/console");
+ return -1;
+ }
+ if (pipe(consredirfd))
+ {
+ Msg(errno, "pipe");
+ close(cfd);
+ consredirfd[0] = consredirfd[1] = -1;
+ return -1;
+ }
+ if (ioctl(cfd, SRIOCSREDIR, consredirfd[1]))
+ {
+ Msg(errno, "SRIOCSREDIR ioctl");
+ close(cfd);
+ close(consredirfd[0]);
+ close(consredirfd[1]);
+ consredirfd[0] = consredirfd[1] = -1;
+ return -1;
+ }
+
+ consredir_ev.fd = consredirfd[0];
+ consredir_ev.type = EV_READ;
+ consredir_ev.handler = consredir_readev_fn;
+ evenq(&consredir_ev);
+ close(cfd);
+ return 0;
+# else
+ if (on > 0)
+ Msg(0, "%s: don't know how to grab the console", rc_name);
return -1;
-#endif /* TIOCCONS */
+# endif
+#endif
}
+/*
+ * Read modem control lines of a physical tty and write them to buf
+ * in a readable format.
+ * Will not write more than 256 characters to buf.
+ * Returns buf;
+ */
+char *
+TtyGetModemStatus(fd, buf)
+int fd;
+char *buf;
+{
+ char *p = buf;
+#ifdef TIOCGSOFTCAR
+ unsigned int softcar;
+#endif
+#if defined(TIOCMGET) || defined(TIOCMODG)
+ unsigned int mflags;
+#else
+# ifdef MCGETA
+ /* this is yet another interface, found on hpux. grrr */
+ mflag mflags;
+#if defined(MDTR)
+# define TIOCM_DTR MDTR
+#endif /* MDTR */
+#if defined(MRTS)
+# define TIOCM_RTS MRTS
+#endif /* MRTS */
+#if defined(MDSR)
+# define TIOCM_DSR MDSR
+#endif /* MDSR */
+#if defined(MDCD)
+# define TIOCM_CAR MDCD
+#endif /* MDCD */
+#if defined(MRI)
+# define TIOCM_RNG MRI
+#endif /* MRI */
+#if defined(MCTS)
+# define TIOCM_CTS MCTS
+#endif /* MCTS */
+# endif
+#endif
+#if defined(CLOCAL) || defined(CRTSCTS)
+ struct mode mtio; /* screen.h */
+#endif
+#if defined(CRTSCTS) || defined(TIOCM_CTS)
+ int rtscts;
+#endif
+ int clocal;
+
+#if defined(CLOCAL) || defined(CRTSCTS)
+ GetTTY(fd, &mtio);
+#endif
+#ifdef CLOCAL
+ if (mtio.tio.c_cflag & CLOCAL)
+ {
+ clocal = 1;
+ *p++ = '{';
+ }
+ else
+#endif
+ clocal = 0;
+
+#ifdef TIOCM_CTS
+# ifdef CRTSCTS
+ if (!(mtio.tio.c_cflag & CRTSCTS))
+ rtscts = 0;
+ else
+# endif /* CRTSCTS */
+ rtscts = 1;
+#endif /* TIOCM_CTS */
+
+#ifdef TIOCGSOFTCAR
+ if (ioctl(fd, TIOCGSOFTCAR, (char *)&softcar) < 0)
+ softcar = 0;
+#endif
+
+#if defined(TIOCMGET) || defined(TIOCMODG) || defined(MCGETA)
+# ifdef TIOCMGET
+ if (ioctl(fd, TIOCMGET, (char *)&mflags) < 0)
+# else
+# ifdef TIOCMODG
+ if (ioctl(fd, TIOCMODG, (char *)&mflags) < 0)
+# else
+ if (ioctl(fd, TIOCMODG, &mflags) < 0)
+# endif
+# endif
+ {
+#ifdef TIOCGSOFTCAR
+ sprintf(p, "NO-TTY? %s", softcar ? "(CD)" : "CD");
+#else
+ sprintf(p, "NO-TTY?");
+#endif
+ p += strlen(p);
+ }
+ else
+ {
+ char *s;
+# ifdef FANCY_MODEM
+# ifdef TIOCM_LE
+ if (!(mflags & TIOCM_LE))
+ for (s = "!LE "; *s; *p++ = *s++);
+# endif
+# endif /* FANCY_MODEM */
+
+# ifdef TIOCM_RTS
+ s = "!RTS "; if (mflags & TIOCM_RTS) s++;
+ while (*s) *p++ = *s++;
+# endif
+# ifdef TIOCM_CTS
+ if (!rtscts)
+ {
+ *p++ = '(';
+ s = "!CTS) ";
+ }
+ if (mflags & TIOCM_CTS) s++;
+ while (*s) *p++ = *s++;
+# endif
+
+# ifdef TIOCM_DTR
+ s = "!DTR "; if (mflags & TIOCM_DTR) s++;
+ while (*s) *p++ = *s++;
+# endif
+# ifdef TIOCM_DSR
+ s = "!DSR "; if (mflags & TIOCM_DSR) s++;
+ while (*s) *p++ = *s++;
+# endif
+# if defined(TIOCM_CD) || defined(TIOCM_CAR)
+# ifdef TIOCGSOFTCAR
+ if (softcar)
+ {
+ *p++ = '(';
+ s = "!CD) ";
+ }
+ else
+# endif
+ s = "!CD ";
+# ifdef TIOCM_CD
+ if (mflags & TIOCM_CD) s++;
+# else
+ if (mflags & TIOCM_CAR) s++;
+# endif
+ while (*s) *p++ = *s++;
+# endif
+# if defined(TIOCM_RI) || defined(TIOCM_RNG)
+# ifdef TIOCM_RI
+ if (mflags & TIOCM_RI)
+# else
+ if (mflags & TIOCM_RNG)
+# endif
+ for (s = "RI "; *s; *p++ = *s++);
+# endif
+# ifdef FANCY_MODEM
+# ifdef TIOCM_ST
+ s = "!ST "; if (mflags & TIOCM_ST) s++;
+ while (*s) *p++ = *s++;
+# endif
+# ifdef TIOCM_SR
+ s = "!SR "; if (mflags & TIOCM_SR) s++;
+ while (*s) *p++ = *s++;
+# endif
+# endif /* FANCY_MODEM */
+ if (p > buf && p[-1] == ' ')
+ p--;
+ *p = '\0';
+ }
+#else
+# ifdef TIOCGSOFTCAR
+ sprintf(p, " %s", softcar ? "(CD)", "CD");
+ p += strlen(p);
+# endif
+#endif
+ if (clocal)
+ *p++ = '}';
+ *p = '\0';
+ return buf;
+}
+
+/*
+ * Old bsd-ish machines may not have any of the baudrate B... symbols.
+ * We hope to detect them here, so that the btable[] below always has
+ * many entries.
+ */
+#ifndef POSIX
+# ifndef TERMIO
+# if !defined(B9600) && !defined(B2400) && !defined(B1200) && !defined(B300)
+#if !defined(B0)
+#define B0 0
+#endif /* B0 */
+#if !defined(B50)
+#define B50 1
+#endif /* B50 */
+#if !defined(B75)
+#define B75 2
+#endif /* B75 */
+#if !defined(B110)
+#define B110 3
+#endif /* B110 */
+#if !defined(B134)
+#define B134 4
+#endif /* B134 */
+#if !defined(B150)
+#define B150 5
+#endif /* B150 */
+#if !defined(B200)
+#define B200 6
+#endif /* B200 */
+#if !defined(B300)
+#define B300 7
+#endif /* B300 */
+#if !defined(B600)
+#define B600 8
+#endif /* B600 */
+#if !defined(B1200)
+#define B1200 9
+#endif /* B1200 */
+#if !defined(B1800)
+#define B1800 10
+#endif /* B1800 */
+#if !defined(B2400)
+#define B2400 11
+#endif /* B2400 */
+#if !defined(B4800)
+#define B4800 12
+#endif /* B4800 */
+#if !defined(B9600)
+#define B9600 13
+#endif /* B9600 */
+#if !defined(EXTA)
+#define EXTA 14
+#endif /* EXTA */
+#if !defined(EXTB)
+#define EXTB 15
+#endif /* EXTB */
+# endif
+# endif
+#endif
+
+/*
+ * On hpux, idx and sym will be different.
+ * Rumor has it that, we need idx in D_dospeed to make tputs
+ * padding correct.
+ * Frequently used entries come first.
+ */
+static struct baud_values btable[] =
+{
+#if defined(B9600)
+ { 13, 9600, B9600 },
+#endif /* B9600 */
+#if defined(B19200)
+ { 14, 19200, B19200 },
+#endif /* B19200 */
+#if defined(EXTA)
+ { 14, 19200, EXTA },
+#endif /* EXTA */
+#if defined(B38400)
+ { 15, 38400, B38400 },
+#endif /* B38400 */
+#if defined(EXTB)
+ { 15, 38400, EXTB },
+#endif /* EXTB */
+#if defined(B57600)
+ { 16, 57600, B57600 },
+#endif /* B57600 */
+#if defined(B115200)
+ { 17, 115200, B115200 },
+#endif /* B115200 */
+#if defined(B230400)
+ { 18, 230400, B230400 },
+#endif /* B230400 */
+#if defined(B460800)
+ { 19, 460800, B460800 },
+#endif /* B460800 */
+#if defined(B7200)
+ { 13, 7200, B7200 },
+#endif /* B7200 */
+#if defined(B4800)
+ { 12, 4800, B4800 },
+#endif /* B4800 */
+#if defined(B3600)
+ { 12, 3600, B3600 },
+#endif /* B3600 */
+#if defined(B2400)
+ { 11, 2400, B2400 },
+#endif /* B2400 */
+#if defined(B1800)
+ { 10, 1800, B1800 },
+#endif /* B1800 */
+#if defined(B1200)
+ { 9, 1200, B1200 },
+#endif /* B1200 */
+#if defined(B900)
+ { 9, 900, B900 },
+#endif /* B900 */
+#if defined(B600)
+ { 8, 600, B600 },
+#endif /* B600 */
+#if defined(B300)
+ { 7, 300, B300 },
+#endif /* B300 */
+#if defined(B200)
+ { 6, 200, B200 },
+#endif /* B200 */
+#if defined(B150)
+ { 5, 150, B150 },
+#endif /* B150 */
+#if defined(B134)
+ { 4, 134, B134 },
+#endif /* B134 */
+#if defined(B110)
+ { 3, 110, B110 },
+#endif /* B110 */
+#if defined(B75)
+ { 2, 75, B75 },
+#endif /* B75 */
+#if defined(B50)
+ { 1, 50, B50 },
+#endif /* B50 */
+#if defined(B0)
+ { 0, 0, B0 },
+#endif /* B0 */
+ { -1, -1, -1 }
+};
+
+/*
+ * baud may either be a bits-per-second value or a symbolic
+ * value as returned by cfget?speed()
+ */
+struct baud_values *
+lookup_baud(baud)
+int baud;
+{
+ struct baud_values *p;
+
+ for (p = btable; p->idx >= 0; p++)
+ if (baud == p->bps || baud == p->sym)
+ return p;
+ return NULL;
+}
+
+/*
+ * change the baud rate in a mode structure.
+ * ibaud and obaud are given in bit/second, or at your option as
+ * termio B... symbols as defined in e.g. suns sys/ttydev.h
+ * -1 means don't change.
+ */
+int
+SetBaud(m, ibaud, obaud)
+struct mode *m;
+int ibaud, obaud;
+{
+ struct baud_values *ip, *op;
+
+ if ((!(ip = lookup_baud(ibaud)) && ibaud != -1) ||
+ (!(op = lookup_baud(obaud)) && obaud != -1))
+ return -1;
+
+#ifdef POSIX
+ if (ip) cfsetispeed(&m->tio, ip->sym);
+ if (op) cfsetospeed(&m->tio, op->sym);
+#else /* POSIX */
+# ifdef TERMIO
+ if (ip)
+ {
+# ifdef IBSHIFT
+ m->tio.c_cflag &= ~(CBAUD << IBSHIFT);
+ m->tio.c_cflag |= (ip->sym & CBAUD) << IBSHIFT;
+# else /* IBSHIFT */
+ if (ibaud != obaud)
+ return -1;
+# endif /* IBSHIFT */
+ }
+ if (op)
+ {
+ m->tio.c_cflag &= ~CBAUD;
+ m->tio.c_cflag |= op->sym & CBAUD;
+ }
+# else /* TERMIO */
+ if (ip) m->m_ttyb.sg_ispeed = ip->idx;
+ if (op) m->m_ttyb.sg_ospeed = op->idx;
+# endif /* TERMIO */
+#endif /* POSIX */
+ return 0;
+}
/*
* Write out the mode struct in a readable form
@@ -977,18 +1810,20 @@ struct mode *m;
debug1("c_oflag = %#x\n", (unsigned int)m->tio.c_oflag);
debug1("c_cflag = %#x\n", (unsigned int)m->tio.c_cflag);
debug1("c_lflag = %#x\n", (unsigned int)m->tio.c_lflag);
+ debug1("cfgetospeed() = %d\n", (int)cfgetospeed(&m->tio));
+ debug1("cfgetispeed() = %d\n", (int)cfgetispeed(&m->tio));
for (i = 0; i < sizeof(m->tio.c_cc)/sizeof(*m->tio.c_cc); i++)
{
debug2("c_cc[%d] = %#x\n", i, m->tio.c_cc[i]);
}
-# ifdef hpux
+# ifdef HPUX_LTCHARS_HACK
debug1("suspc = %#02x\n", m->m_ltchars.t_suspc);
debug1("dsuspc = %#02x\n", m->m_ltchars.t_dsuspc);
debug1("rprntc = %#02x\n", m->m_ltchars.t_rprntc);
debug1("flushc = %#02x\n", m->m_ltchars.t_flushc);
debug1("werasc = %#02x\n", m->m_ltchars.t_werasc);
debug1("lnextc = %#02x\n", m->m_ltchars.t_lnextc);
-# endif /* hpux */
+# endif /* HPUX_LTCHARS_HACK */
#else /* POSIX */
# ifdef TERMIO
debug("struct termio tio:\n");
diff --git a/tty.sh b/tty.sh
index 6733136..e32454f 100644
--- a/tty.sh
+++ b/tty.sh
@@ -3,13 +3,22 @@
# This inserts all the needed #ifdefs for IF{} statements
# and generates tty.c
+#
+# Stupid cpp on A/UX barfs on ``#if defined(FOO) && FOO < 17'' when
+# FOO is undefined. Reported by Robert C. Tindall (rtindall@uidaho.edu)
+#
rm -f $1
-sed -e '1,17d' \
--e 's%^IF{\(.*\)}\(.*\)%#if defined(\1)\
- \2\
+sed -e '1,26d' \
+-e 's%^IF{\([^}]*\)}\(.*\)%#if defined(\1)\
+\2\
#endif /* \1 */%' \
--e 's%^XIF{\(.*\)}\(.*\)%#if defined(\1) \&\& \1 < MAXCC\
- \2\
+-e 's%^IFN{\([^}]*\)}\(.*\)%#if !defined(\1)\
+\2\
+#endif /* \1 */%' \
+-e 's%^XIF{\([^}]*\)}\(.*\)%#if defined(\1)\
+#if (\1 < MAXCC)\
+\2\
+#endif \
#endif /* \1 */%' \
< $0 > $1
chmod -w $1
@@ -59,6 +68,9 @@ RCS_ID("$Id: tty.sh,v 1.13 1994/05/31 12:33:17 mlschroe Exp $ FAU")
# include <sys/ttold.h> /* needed for TIOCEXCL */
# endif
#endif
+#ifdef __hpux
+# include <sys/modem.h>
+#endif
#ifdef ISC
# include <sys/tty.h>
@@ -67,11 +79,27 @@ RCS_ID("$Id: tty.sh,v 1.13 1994/05/31 12:33:17 mlschroe Exp $ FAU")
#endif
#include "config.h"
+#ifdef SVR4
+#include <sys/stropts.h> /* for I_POP */
+#endif
+
#include "screen.h"
#include "extern.h"
+#if !defined(TIOCCONS) && defined(sun) && defined(SVR4)
+# include <sys/strredir.h>
+#endif
+
extern struct display *display, *displays;
extern int iflag;
+#if !defined(TIOCCONS) && defined(SRIOCSREDIR)
+extern struct win *console_window;
+static void consredir_readev_fn __P((struct event *, char *));
+#endif
+
+static void DoSendBreak __P((int, int, int));
+static sigret_t SigAlrmDummy __P(SIGPROTOARG);
+
/* Frank Schulz (fschulz@pyramid.com):
* I have no idea why VSTART is not defined and my fix is probably not
@@ -84,6 +112,18 @@ extern int iflag;
#define VSTOP _VSTOP
#endif
+#ifndef O_NOCTTY
+# define O_NOCTTY 0
+#endif
+
+#ifndef TTYVMIN
+# define TTYVMIN 1
+#endif
+#ifndef TTYVTIME
+#define TTYVTIME 0
+#endif
+
+
static sigret_t
SigAlrmDummy SIGDEFARG
{
@@ -92,27 +132,41 @@ SigAlrmDummy SIGDEFARG
}
/*
- * Carefully open a charcter device. Not used to open ttys.
+ * Carefully open a charcter device. Not used to open display ttys.
+ * The second parameter is parsed for a few stty style options.
*/
int
-OpenTTY(line)
-char *line;
+OpenTTY(line, opt)
+char *line, *opt;
{
int f;
+ struct mode Mode;
sigret_t (*sigalrm)__P(SIGPROTOARG);
sigalrm = signal(SIGALRM, SigAlrmDummy);
alarm(2);
+
/* this open only succeeds, if real uid is allowed */
- if ((f = secopen(line, O_RDWR | O_NONBLOCK, 0)) == -1)
+ if ((f = secopen(line, O_RDWR | O_NONBLOCK | O_NOCTTY, 0)) == -1)
+ {
+ if (errno == EINTR)
+ Msg(0, "Cannot open line '%s' for R/W: open() blocked, aborted.", line);
+ else
+ Msg(errno, "Cannot open line '%s' for R/W", line);
+ alarm(0);
+ signal(SIGALRM, sigalrm);
+ return -1;
+ }
+ if (!isatty(f))
{
- Msg(errno, "Cannot open line '%s' for R/W", line);
+ Msg(0, "'%s' is not a tty", line);
alarm(0);
signal(SIGALRM, sigalrm);
+ close(f);
return -1;
}
-#ifdef I_POP
+#if defined(I_POP) && defined(POP_TTYMODULES)
debug("OpenTTY I_POP\n");
while (ioctl(f, I_POP, (char *)0) >= 0)
;
@@ -126,7 +180,7 @@ char *line;
errno = 0;
if (ioctl(f, TIOCEXCL, (char *) 0) < 0)
Msg(errno, "%s: ioctl TIOCEXCL failed", line);
- debug3("%d %d %d\n", (int)getuid(), (int)geteuid(), (int)getpid());
+ debug3("%d %d %d\n", getuid(), geteuid(), getpid());
debug2("%s TIOCEXCL errno %d\n", line, errno);
#endif /* TIOCEXCL */
/*
@@ -136,22 +190,18 @@ char *line;
if (display)
{
debug1("OpenTTY: using mode of display for %s\n", line);
- SetTTY(f, &D_NewMode);
-#ifdef DEBUG
- DebugTTY(&D_NewMode);
-#endif
+ Mode = D_NewMode;
}
else
-#endif
- {
- struct mode Mode;
-
- InitTTY(&Mode, TTY_FLAG_PLAIN);
+#endif
+ InitTTY(&Mode, W_TYPE_PLAIN);
+
+ SttyMode(&Mode, opt);
#ifdef DEBUG
- DebugTTY(&Mode);
+ DebugTTY(&Mode);
#endif
- SetTTY(f, &Mode);
- }
+ SetTTY(f, &Mode);
+
brktty(f);
alarm(0);
signal(SIGALRM, sigalrm);
@@ -169,7 +219,7 @@ int intrc, origintrc = VDISABLE; /* display? */
#else
int intrc, origintrc = -1; /* display? */
#endif
-static startc, stopc; /* display? */
+static int startc, stopc; /* display? */
void
@@ -182,28 +232,40 @@ int ttyflag;
/* struct termios tio
* defaults, as seen on SunOS 4.1.3
*/
- debug1("InitTTY: POSIX: termios defaults a la SunOS 4.1.3 (%d)\n", ttyflag);
+ debug1("InitTTY: POSIX: termios defaults based on SunOS 4.1.3, but better (%d)\n", ttyflag);
IF{BRKINT} m->tio.c_iflag |= BRKINT;
IF{IGNPAR} m->tio.c_iflag |= IGNPAR;
-IF{ISTRIP} m->tio.c_iflag |= ISTRIP;
+/* IF{ISTRIP} m->tio.c_iflag |= ISTRIP; may be needed, let's try. jw. */
IF{IXON} m->tio.c_iflag |= IXON;
-IF{IMAXBEL} m->tio.c_iflag |= IMAXBEL;
+/* IF{IMAXBEL} m->tio.c_iflag |= IMAXBEL; sorry, this one is ridiculus. jw */
if (!ttyflag) /* may not even be good for ptys.. */
{
IF{ICRNL} m->tio.c_iflag |= ICRNL;
IF{ONLCR} m->tio.c_oflag |= ONLCR;
IF{TAB3} m->tio.c_oflag |= TAB3;
-IF{PARENB} m->tio.c_cflag |= PARENB;
+IF{OXTABS} m->tio.c_oflag |= OXTABS;
+/* IF{PARENB} m->tio.c_cflag |= PARENB; nah! jw. */
}
IF{OPOST} m->tio.c_oflag |= OPOST;
-IF{B9600} m->tio.c_cflag |= B9600;
+/*
+ * Or-ing the speed into c_cflags is dangerous.
+ * It breaks on bsdi, where c_ispeed and c_ospeed are extra longs.
+ *
+ * IF{B9600} m->tio.c_cflag |= B9600;
+ * IF{IBSHIFT) && defined(B9600} m->tio.c_cflag |= B9600 << IBSHIFT;
+ *
+ * We hope that we have the posix calls to do it right:
+ * If these are not available you might try the above.
+ */
+IF{B9600} cfsetospeed(&m->tio, B9600);
+IF{B9600} cfsetispeed(&m->tio, B9600);
+
IF{CS8} m->tio.c_cflag |= CS8;
IF{CREAD} m->tio.c_cflag |= CREAD;
-IF{IBSHIFT) && defined(B9600} m->tio.c_cflag |= B9600 << IBSHIFT;
-/* IF{CLOCAL} m->tio.c_cflag |= CLOCAL; */
+IF{CLOCAL} m->tio.c_cflag |= CLOCAL;
IF{ECHOCTL} m->tio.c_lflag |= ECHOCTL;
IF{ECHOKE} m->tio.c_lflag |= ECHOKE;
@@ -238,17 +300,18 @@ XIF{VSTATUS} m->tio.c_cc[VSTATUS] = Ctrl('T');
if (ttyflag)
{
- m->tio.c_cc[VMIN] = 1;
- m->tio.c_cc[VTIME] = 0;
+ m->tio.c_cc[VMIN] = TTYVMIN;
+ m->tio.c_cc[VTIME] = TTYVTIME;
}
-# ifdef hpux
+
+# ifdef HPUX_LTCHARS_HACK
m->m_ltchars.t_suspc = Ctrl('Z');
m->m_ltchars.t_dsuspc = Ctrl('Y');
m->m_ltchars.t_rprntc = Ctrl('R');
m->m_ltchars.t_flushc = Ctrl('O');
m->m_ltchars.t_werasc = Ctrl('W');
m->m_ltchars.t_lnextc = Ctrl('V');
-# endif /* hpux */
+# endif /* HPUX_LTCHARS_HACK */
#else /* POSIX */
@@ -273,7 +336,11 @@ IF{ONLCR} m->tio.c_oflag |= ONLCR;
IF{TAB3} m->tio.c_oflag |= TAB3;
}
+#ifdef __bsdi__
+ )-: cannot handle BSDI without POSIX
+#else
IF{B9600} m->tio.c_cflag = B9600;
+#endif
IF{CS8} m->tio.c_cflag |= CS8;
IF{CREAD} m->tio.c_cflag |= CREAD;
@@ -294,11 +361,13 @@ 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;
+
if (ttyflag)
- {
- m->tio.c_cc[VMIN] = 1;
- m->tio.c_cc[VTIME] = 0;
- }
+ {
+ m->tio.c_cc[VMIN] = TTYVMIN;
+ m->tio.c_cc[VTIME] = TTYVTIME;
+ }
+
# else /* TERMIO */
debug1("InitTTY: BSD: defaults a la SunOS 4.1.3 (%d)\n", ttyflag);
m->m_ttyb.sg_ispeed = B9600;
@@ -337,11 +406,11 @@ IF{LPASS8} | LPASS8
IF{LCRTKIL} | LCRTKIL
IF{LCRTERA} | LCRTERA
IF{LCRTBS} | LCRTBS
-;
+ ;
# endif /* TERMIO */
#endif /* POSIX */
-#if defined(KANJI) && defined(TIOCKSET) && defined(KM_ASCII) && defined(KM_SYSSJIS)
+#if defined(KANJI) && defined(TIOCKSET)
m->m_jtchars.t_ascii = 'J';
m->m_jtchars.t_kanji = 'B';
m->m_knjmode = KM_ASCII | KM_SYSSJIS;
@@ -356,7 +425,7 @@ struct mode *mp;
errno = 0;
#ifdef POSIX
tcsetattr(fd, TCSADRAIN, &mp->tio);
-# ifdef hpux
+# ifdef HPUX_LTCHARS_HACK
ioctl(fd, TIOCSLTC, (char *)&mp->m_ltchars);
# endif
#else
@@ -379,7 +448,7 @@ struct mode *mp;
ioctl(fd, TIOCSLTC, (char *)&mp->m_ltchars); /* moved here for apollo. jw */
# endif
#endif
-#if defined(KANJI) && defined(TIOCKSET) && defined(KM_ASCII) && defined(KM_SYSSJIS)
+#if defined(KANJI) && defined(TIOCKSET)
ioctl(fd, TIOCKSETC, &mp->m_jtchars);
ioctl(fd, TIOCKSET, &mp->m_knjmode);
#endif
@@ -395,7 +464,7 @@ struct mode *mp;
errno = 0;
#ifdef POSIX
tcgetattr(fd, &mp->tio);
-# ifdef hpux
+# ifdef HPUX_LTCHARS_HACK
ioctl(fd, TIOCGLTC, (char *)&mp->m_ltchars);
# endif
#else
@@ -423,7 +492,7 @@ struct mode *mp;
ioctl(fd, TIOCGETD, (char *)&mp->m_ldisc);
# endif
#endif
-#if defined(KANJI) && defined(TIOCKSET) && defined(KM_ASCII) && defined(KM_SYSSJIS)
+#if defined(KANJI) && defined(TIOCKSET)
ioctl(fd, TIOCKGETC, &mp->m_jtchars);
ioctl(fd, TIOCKGET, &mp->m_knjmode);
#endif
@@ -431,9 +500,13 @@ struct mode *mp;
Msg(errno, "GetTTY (fd %d): ioctl failed", fd);
}
+/*
+ * needs interrupt = iflag and flow = d->d_flow
+ */
void
-SetMode(op, np)
+SetMode(op, np, flow, interrupt)
struct mode *op, *np;
+int flow, interrupt;
{
*np = *op;
@@ -444,10 +517,12 @@ struct mode *op, *np;
np->tio.c_line = 0;
# endif
IF{ICRNL} np->tio.c_iflag &= ~ICRNL;
+IF{ISTRIP} np->tio.c_iflag &= ~ISTRIP;
IF{ONLCR} np->tio.c_oflag &= ~ONLCR;
np->tio.c_lflag &= ~(ICANON | ECHO);
/*
* From Andrew Myers (andru@tonic.lcs.mit.edu)
+ * to avoid ^V^V-Problem on OSF1
*/
IF{IEXTEN} np->tio.c_lflag &= ~IEXTEN;
@@ -460,19 +535,23 @@ IF{IEXTEN} np->tio.c_lflag &= ~IEXTEN;
* tty) and forwards it to the master [kill(MasterPid, SIGINT)].
* Marc Boucher (marc@CAM.ORG)
*/
- if (iflag)
+ if (interrupt)
np->tio.c_lflag |= ISIG;
else
np->tio.c_lflag &= ~ISIG;
/*
* careful, careful catche monkey..
* never set VMIN and VTIME to zero, if you want blocking io.
+ *
+ * We may want to do a VMIN > 0, VTIME > 0 read on the ptys too, to
+ * reduce interrupt frequency. But then we would not know how to
+ * handle read returning 0. jw.
*/
np->tio.c_cc[VMIN] = 1;
np->tio.c_cc[VTIME] = 0;
XIF{VSTART} startc = op->tio.c_cc[VSTART];
XIF{VSTOP} stopc = op->tio.c_cc[VSTOP];
- if (iflag)
+ if (interrupt)
origintrc = intrc = op->tio.c_cc[VINTR];
else
{
@@ -480,7 +559,7 @@ XIF{VSTOP} stopc = op->tio.c_cc[VSTOP];
intrc = np->tio.c_cc[VINTR] = VDISABLE;
}
np->tio.c_cc[VQUIT] = VDISABLE;
- if (D_flow == 0)
+ if (flow == 0)
{
np->tio.c_cc[VINTR] = VDISABLE;
XIF{VSTART} np->tio.c_cc[VSTART] = VDISABLE;
@@ -493,22 +572,22 @@ XIF{VSTATUS} np->tio.c_cc[VSTATUS] = VDISABLE;
XIF{VSUSP} np->tio.c_cc[VSUSP] = VDISABLE;
XIF{VERASE} np->tio.c_cc[VERASE] = VDISABLE;
XIF{VKILL} np->tio.c_cc[VKILL] = VDISABLE;
-# ifdef hpux
+# ifdef HPUX_LTCHARS_HACK
np->m_ltchars.t_suspc = VDISABLE;
np->m_ltchars.t_dsuspc = VDISABLE;
np->m_ltchars.t_rprntc = VDISABLE;
np->m_ltchars.t_flushc = VDISABLE;
np->m_ltchars.t_werasc = VDISABLE;
np->m_ltchars.t_lnextc = VDISABLE;
-# else /* hpux */
+# else /* HPUX_LTCHARS_HACK */
XIF{VDSUSP} np->tio.c_cc[VDSUSP] = VDISABLE;
XIF{VREPRINT} np->tio.c_cc[VREPRINT] = VDISABLE;
XIF{VWERASE} np->tio.c_cc[VWERASE] = VDISABLE;
-# endif /* hpux */
+# endif /* HPUX_LTCHARS_HACK */
#else /* TERMIO || POSIX */
startc = op->m_tchars.t_startc;
stopc = op->m_tchars.t_stopc;
- if (iflag)
+ if (interrupt)
origintrc = intrc = op->m_tchars.t_intrc;
else
{
@@ -522,7 +601,7 @@ XIF{VWERASE} np->tio.c_cc[VWERASE] = VDISABLE;
np->m_ttyb.sg_flags |= CS_8BITS;
# endif
np->m_tchars.t_quitc = -1;
- if (D_flow == 0)
+ if (flow == 0)
{
np->m_tchars.t_intrc = -1;
np->m_tchars.t_startc = -1;
@@ -535,6 +614,7 @@ XIF{VWERASE} np->tio.c_cc[VWERASE] = VDISABLE;
#endif /* defined(TERMIO) || defined(POSIX) */
}
+/* operates on display */
void
SetFlow(on)
int on;
@@ -582,6 +662,97 @@ XIF{VSTOP} D_NewMode.tio.c_cc[VSTOP] = VDISABLE;
D_flow = on;
}
+/* parse commands from opt and modify m */
+int
+SttyMode(m, opt)
+struct mode *m;
+char *opt;
+{
+ static const char sep[] = " \t:;,";
+
+ if (!opt)
+ return 0;
+
+ while (*opt)
+ {
+ while (index(sep, *opt)) opt++;
+ if (*opt >= '0' && *opt <= '9')
+ {
+ if (SetBaud(m, atoi(opt), atoi(opt)))
+ return -1;
+ }
+ else if (!strncmp("cs7", opt, 3))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_cflag &= ~CSIZE;
+ m->tio.c_cflag |= CS7;
+#else
+ m->m_lmode &= ~LPASS8;
+#endif
+ }
+ else if (!strncmp("cs8", opt, 3))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_cflag &= ~CSIZE;
+ m->tio.c_cflag |= CS8;
+#else
+ m->m_lmode |= LPASS8;
+#endif
+ }
+ else if (!strncmp("istrip", opt, 6))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_iflag |= ISTRIP;
+#else
+ m->m_lmode &= ~LPASS8;
+#endif
+ }
+ else if (!strncmp("-istrip", opt, 7))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_iflag &= ~ISTRIP;
+#else
+ m->m_lmode |= LPASS8;
+#endif
+ }
+ else if (!strncmp("ixon", opt, 4))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_iflag |= IXON;
+#else
+ debug("SttyMode: no ixon in old bsd land.\n");
+#endif
+ }
+ else if (!strncmp("-ixon", opt, 5))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_iflag &= ~IXON;
+#else
+ debug("SttyMode: no -ixon in old bsd land.\n");
+#endif
+ }
+ else if (!strncmp("ixoff", opt, 5))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_iflag |= IXOFF;
+#else
+ m->m_ttyb.sg_flags |= TANDEM;
+#endif
+ }
+ else if (!strncmp("-ixoff", opt, 6))
+ {
+#if defined(POSIX) || defined(TERMIO)
+ m->tio.c_iflag &= ~IXOFF;
+#else
+ m->m_ttyb.sg_flags &= ~TANDEM;
+#endif
+ }
+ else
+ return -1;
+ while (*opt && !index(sep, *opt)) opt++;
+ }
+ return 0;
+}
/*
* Job control handling
@@ -629,6 +800,9 @@ int fd;
/* The next lines should be obsolete. Can anybody check if they
* are really needed on the BSD platforms?
+ *
+ * this is to avoid the message:
+ * fgtty: Not a typewriter (25)
*/
# if defined(__osf__) || (BSD >= 199103) || defined(ISC)
setsid(); /* should be already done */
@@ -655,19 +829,154 @@ int fd;
return 0;
}
+/*
+ * The alm boards on our sparc center 1000 have a lousy driver.
+ * We cannot generate long breaks unless we use the most ugly form
+ * of ioctls. jw.
+ */
+#ifdef POSIX
+int breaktype = 2;
+#else /* POSIX */
+# ifdef TCSBRK
+int breaktype = 1;
+# else
+int breaktype = 0;
+# endif
+#endif /* POSIX */
+
+#if defined(sun) && !defined(SVR4)
+# define HAVE_SUPER_TCSENDBREAK
+#endif
+
+/*
+ * type:
+ * 0: TIOCSBRK / TIOCCBRK
+ * 1: TCSBRK
+ * 2: tcsendbreak()
+ * n: approximate duration in 1/4 seconds.
+ */
+static void
+DoSendBreak(fd, n, type)
+int fd, n, type;
+{
+ switch (type)
+ {
+ case 2: /* tcsendbreak() =============================== */
+#ifdef POSIX
+# ifdef HAVE_SUPER_TCSENDBREAK
+ /* There is one rare case that I have tested, where tcsendbreak works
+ * really great: this was an alm driver that came with SunOS 4.1.3
+ * If you have this one, define the above symbol.
+ * here we can use the second parameter to specify the duration.
+ */
+ debug2("tcsendbreak(fd=%d, %d)\n", fd, n);
+ if (tcsendbreak(fd, n) < 0)
+ Msg(errno, "cannot send BREAK (tcsendbreak)");
+# else
+ /*
+ * here we hope, that multiple calls to tcsendbreak() can
+ * be concatenated to form a long break, as we do not know
+ * what exact interpretation the second parameter has:
+ *
+ * - sunos 4: duration in quarter seconds
+ * - sunos 5: 0 a short break, nonzero a tcdrain()
+ * - hpux, irix: ignored
+ * - mot88: duration in milliseconds
+ * - aix: duration in milliseconds, but 0 is 25 milliseconds.
+ */
+ debug2("%d * tcsendbreak(fd=%d, 0)\n", n, fd);
+ {
+ int i;
+
+ for (i = 0; i < n; i++)
+ if (tcsendbreak(fd, 0) < 0)
+ {
+ Msg(errno, "cannot send BREAK (tcsendbreak SVR4)");
+ return;
+ }
+ }
+# endif
+#else /* POSIX */
+ Msg(0, "tcsendbreak() not available, change breaktype");
+#endif /* POSIX */
+ break;
+
+ case 1: /* TCSBRK ======================================= */
+#ifdef TCSBRK
+ if (!n)
+ n++;
+ /*
+ * Here too, we assume that short breaks can be concatenated to
+ * perform long breaks. But for SOLARIS, this is not true, of course.
+ */
+ debug2("%d * TCSBRK fd=%d\n", n, fd);
+ {
+ int i;
+
+ for (i = 0; i < n; i++)
+ if (ioctl(fd, TCSBRK, (char *)0) < 0)
+ {
+ Msg(errno, "Cannot send BREAK (TCSBRK)");
+ return;
+ }
+ }
+#else /* TCSBRK */
+ Msg(0, "TCSBRK not available, change breaktype");
+#endif /* TCSBRK */
+ break;
+
+ case 0: /* TIOCSBRK / TIOCCBRK ========================== */
+#if defined(TIOCSBRK) && defined(TIOCCBRK)
+ /*
+ * This is very rude. Screen actively celebrates the break.
+ * But it may be the only save way to issue long breaks.
+ */
+ debug("TIOCSBRK TIOCCBRK\n");
+ if (ioctl(fd, TIOCSBRK, (char *)0) < 0)
+ {
+ Msg(errno, "Can't send BREAK (TIOCSBRK)");
+ return;
+ }
+ sleep1000(n ? n * 250 : 250);
+ if (ioctl(fd, TIOCCBRK, (char *)0) < 0)
+ {
+ Msg(errno, "BREAK stuck!!! -- HELP! (TIOCCBRK)");
+ return;
+ }
+#else /* TIOCSBRK && TIOCCBRK */
+ Msg(0, "TIOCSBRK/CBRK not available, change breaktype");
+#endif /* TIOCSBRK && TIOCCBRK */
+ break;
+
+ default: /* unknown ========================== */
+ Msg(0, "Internal SendBreak error: method %d unknown", type);
+ }
+}
/*
* Send a break for n * 0.25 seconds. Tty must be PLAIN.
+ * The longest possible break allowed here is 15 seconds.
*/
-void SendBreak(wp, n, closeopen)
+void
+SendBreak(wp, n, closeopen)
struct win *wp;
int n, closeopen;
{
- if ((wp->w_t.flags & TTY_FLAG_PLAIN) == 0)
+ sigret_t (*sigalrm)__P(SIGPROTOARG);
+
+#ifdef BUILTIN_TELNET
+ if (wp->w_type == W_TYPE_TELNET)
+ {
+ TelBreak(wp);
+ return;
+ }
+#endif
+ if (wp->w_type != W_TYPE_PLAIN)
return;
debug3("break(%d, %d) fd %d\n", n, closeopen, wp->w_ptyfd);
+
#ifdef POSIX
(void) tcflush(wp->w_ptyfd, TCIOFLUSH);
#else
@@ -675,11 +984,12 @@ int n, closeopen;
(void) ioctl(wp->w_ptyfd, TIOCFLUSH, (char *)0);
# endif /* TIOCFLUSH */
#endif /* POSIX */
+
if (closeopen)
{
close(wp->w_ptyfd);
- sleep((n + 3) / 4);
- if ((wp->w_ptyfd = OpenTTY(wp->w_tty)) < 1)
+ sleep1000(n ? n * 250 : 250);
+ if ((wp->w_ptyfd = OpenTTY(wp->w_tty, wp->w_cmdargs[1])) < 1)
{
Msg(0, "Ouch, cannot reopen line %s, please try harder", wp->w_tty);
return;
@@ -688,56 +998,56 @@ int n, closeopen;
}
else
{
-#ifdef POSIX
- debug("tcsendbreak\n");
- if (tcsendbreak(wp->w_ptyfd, n) < 0)
- {
- Msg(errno, "cannot send BREAK");
- return;
- }
-#else
- if (!n)
- n++;
-# ifdef TCSBRK
- debug("TCSBRK\n");
- {
- int i;
- for (i = 0; i < n; i++)
- if (ioctl(wp->w_ptyfd, TCSBRK, (char *)0) < 0)
- {
- Msg(errno, "Cannot send BREAK");
- return;
- }
- }
-# else /* TCSBRK */
-# if defined(TIOCSBRK) && defined(TIOCCBRK)
- debug("TIOCSBRK TIOCCBRK\n");
- if (ioctl(wp->w_ptyfd, TIOCSBRK, (char *)0) < 0)
- {
- Msg(errno, "Can't send BREAK");
- return;
- }
- sleep((n + 3) / 4);
- if (ioctl(wp->w_ptyfd, TIOCCBRK, (char *)0) < 0)
- {
- Msg(errno, "BREAK stuck!!! -- HELP!");
- return;
- }
-# else /* TIOCSBRK && TIOCCBRK */
- Msg(0, "Break not simulated yet");
- return;
-# endif /* TIOCSBRK && TIOCCBRK */
-# endif /* TCSBRK */
-#endif /* POSIX */
- debug(" broken\n");
+ sigalrm = signal(SIGALRM, SigAlrmDummy);
+ alarm(15);
+
+ DoSendBreak(wp->w_ptyfd, n, breaktype);
+
+ alarm(0);
+ signal(SIGALRM, sigalrm);
}
+ debug(" broken.\n");
}
-
/*
* Console grabbing
*/
+#if !defined(TIOCCONS) && defined(SRIOCSREDIR)
+
+struct event consredir_ev;
+int consredirfd[2] = {-1, -1};
+
+static void
+consredir_readev_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ char *p, *n, buf[256];
+ int l;
+
+ if (!console_window || (l = read(consredirfd[0], buf, sizeof(buf))) <= 0)
+ {
+ close(consredirfd[0]);
+ close(consredirfd[1]);
+ consredirfd[0] = consredirfd[1] = -1;
+ evdeq(ev);
+ return;
+ }
+ for (p = n = buf; l > 0; n++, l--)
+ if (*n == '\n')
+ {
+ if (n > p)
+ WriteString(console_window, p, n - p);
+ WriteString(console_window, "\r\n", 2);
+ p = n + 1;
+ }
+ if (n > p)
+ WriteString(console_window, p, n - p);
+}
+
+#endif
+
/*ARGSUSED*/
int
TtyGrabConsole(fd, on, rc_name)
@@ -745,12 +1055,32 @@ int fd, on;
char *rc_name;
{
#ifdef TIOCCONS
- char *slave;
- int sfd = -1, ret = 0;
struct display *d;
+ int ret = 0;
+ int sfd = -1;
+
+ if (on < 0)
+ return; /* pty close will ungrab */
+ if (on)
+ {
+ if (displays == 0)
+ {
+ Msg(0, "I need a display");
+ return -1;
+ }
+ for (d = displays; d; d = d->d_next)
+ if (strcmp(d->d_usertty, "/dev/console") == 0)
+ break;
+ if (d)
+ {
+ Msg(0, "too dangerous - screen is running on /dev/console");
+ return -1;
+ }
+ }
if (!on)
{
+ char *slave;
if ((fd = OpenPTY(&slave)) < 0)
{
Msg(errno, "%s: could not open detach pty master", rc_name);
@@ -763,7 +1093,24 @@ char *rc_name;
return -1;
}
}
- else
+ if (UserContext() == 1)
+ UserReturn(ioctl(fd, TIOCCONS, (char *)&on));
+ ret = UserStatus();
+ if (ret)
+ Msg(errno, "%s: ioctl TIOCCONS failed", rc_name);
+ if (!on)
+ {
+ close(sfd);
+ close(fd);
+ }
+ return ret;
+
+#else
+# ifdef SRIOCSREDIR
+ struct display *d;
+ int cfd;
+
+ if (on > 0)
{
if (displays == 0)
{
@@ -779,23 +1126,340 @@ char *rc_name;
return -1;
}
}
- if (UserContext() == 1)
- UserReturn(ioctl(fd, TIOCCONS, (char *)&on));
- ret = UserStatus();
- if (ret)
- Msg(errno, "%s: ioctl TIOCCONS failed", rc_name);
- if (!on)
+ if (consredirfd[0] >= 0)
{
- close(sfd);
- close(fd);
+ evdeq(&consredir_ev);
+ close(consredirfd[0]);
+ close(consredirfd[1]);
+ consredirfd[0] = consredirfd[1] = -1;
}
- return ret;
-#else /* TIOCCONS */
- Msg(0, "%s: no TIOCCONS on this machine", rc_name);
+ if (on <= 0)
+ return 0;
+ if ((cfd = secopen("/dev/console", O_RDWR|O_NOCTTY, 0)) == -1)
+ {
+ Msg(errno, "/dev/console");
+ return -1;
+ }
+ if (pipe(consredirfd))
+ {
+ Msg(errno, "pipe");
+ close(cfd);
+ consredirfd[0] = consredirfd[1] = -1;
+ return -1;
+ }
+ if (ioctl(cfd, SRIOCSREDIR, consredirfd[1]))
+ {
+ Msg(errno, "SRIOCSREDIR ioctl");
+ close(cfd);
+ close(consredirfd[0]);
+ close(consredirfd[1]);
+ consredirfd[0] = consredirfd[1] = -1;
+ return -1;
+ }
+
+ consredir_ev.fd = consredirfd[0];
+ consredir_ev.type = EV_READ;
+ consredir_ev.handler = consredir_readev_fn;
+ evenq(&consredir_ev);
+ close(cfd);
+ return 0;
+# else
+ if (on > 0)
+ Msg(0, "%s: don't know how to grab the console", rc_name);
return -1;
-#endif /* TIOCCONS */
+# endif
+#endif
+}
+
+/*
+ * Read modem control lines of a physical tty and write them to buf
+ * in a readable format.
+ * Will not write more than 256 characters to buf.
+ * Returns buf;
+ */
+char *
+TtyGetModemStatus(fd, buf)
+int fd;
+char *buf;
+{
+ char *p = buf;
+#ifdef TIOCGSOFTCAR
+ unsigned int softcar;
+#endif
+#if defined(TIOCMGET) || defined(TIOCMODG)
+ unsigned int mflags;
+#else
+# ifdef MCGETA
+ /* this is yet another interface, found on hpux. grrr */
+ mflag mflags;
+IF{MDTR}# define TIOCM_DTR MDTR
+IF{MRTS}# define TIOCM_RTS MRTS
+IF{MDSR}# define TIOCM_DSR MDSR
+IF{MDCD}# define TIOCM_CAR MDCD
+IF{MRI}# define TIOCM_RNG MRI
+IF{MCTS}# define TIOCM_CTS MCTS
+# endif
+#endif
+#if defined(CLOCAL) || defined(CRTSCTS)
+ struct mode mtio; /* screen.h */
+#endif
+#if defined(CRTSCTS) || defined(TIOCM_CTS)
+ int rtscts;
+#endif
+ int clocal;
+
+#if defined(CLOCAL) || defined(CRTSCTS)
+ GetTTY(fd, &mtio);
+#endif
+#ifdef CLOCAL
+ if (mtio.tio.c_cflag & CLOCAL)
+ {
+ clocal = 1;
+ *p++ = '{';
+ }
+ else
+#endif
+ clocal = 0;
+
+#ifdef TIOCM_CTS
+# ifdef CRTSCTS
+ if (!(mtio.tio.c_cflag & CRTSCTS))
+ rtscts = 0;
+ else
+# endif /* CRTSCTS */
+ rtscts = 1;
+#endif /* TIOCM_CTS */
+
+#ifdef TIOCGSOFTCAR
+ if (ioctl(fd, TIOCGSOFTCAR, (char *)&softcar) < 0)
+ softcar = 0;
+#endif
+
+#if defined(TIOCMGET) || defined(TIOCMODG) || defined(MCGETA)
+# ifdef TIOCMGET
+ if (ioctl(fd, TIOCMGET, (char *)&mflags) < 0)
+# else
+# ifdef TIOCMODG
+ if (ioctl(fd, TIOCMODG, (char *)&mflags) < 0)
+# else
+ if (ioctl(fd, TIOCMODG, &mflags) < 0)
+# endif
+# endif
+ {
+#ifdef TIOCGSOFTCAR
+ sprintf(p, "NO-TTY? %s", softcar ? "(CD)" : "CD");
+#else
+ sprintf(p, "NO-TTY?");
+#endif
+ p += strlen(p);
+ }
+ else
+ {
+ char *s;
+# ifdef FANCY_MODEM
+# ifdef TIOCM_LE
+ if (!(mflags & TIOCM_LE))
+ for (s = "!LE "; *s; *p++ = *s++);
+# endif
+# endif /* FANCY_MODEM */
+
+# ifdef TIOCM_RTS
+ s = "!RTS "; if (mflags & TIOCM_RTS) s++;
+ while (*s) *p++ = *s++;
+# endif
+# ifdef TIOCM_CTS
+ if (!rtscts)
+ {
+ *p++ = '(';
+ s = "!CTS) ";
+ }
+ if (mflags & TIOCM_CTS) s++;
+ while (*s) *p++ = *s++;
+# endif
+
+# ifdef TIOCM_DTR
+ s = "!DTR "; if (mflags & TIOCM_DTR) s++;
+ while (*s) *p++ = *s++;
+# endif
+# ifdef TIOCM_DSR
+ s = "!DSR "; if (mflags & TIOCM_DSR) s++;
+ while (*s) *p++ = *s++;
+# endif
+# if defined(TIOCM_CD) || defined(TIOCM_CAR)
+# ifdef TIOCGSOFTCAR
+ if (softcar)
+ {
+ *p++ = '(';
+ s = "!CD) ";
+ }
+ else
+# endif
+ s = "!CD ";
+# ifdef TIOCM_CD
+ if (mflags & TIOCM_CD) s++;
+# else
+ if (mflags & TIOCM_CAR) s++;
+# endif
+ while (*s) *p++ = *s++;
+# endif
+# if defined(TIOCM_RI) || defined(TIOCM_RNG)
+# ifdef TIOCM_RI
+ if (mflags & TIOCM_RI)
+# else
+ if (mflags & TIOCM_RNG)
+# endif
+ for (s = "RI "; *s; *p++ = *s++);
+# endif
+# ifdef FANCY_MODEM
+# ifdef TIOCM_ST
+ s = "!ST "; if (mflags & TIOCM_ST) s++;
+ while (*s) *p++ = *s++;
+# endif
+# ifdef TIOCM_SR
+ s = "!SR "; if (mflags & TIOCM_SR) s++;
+ while (*s) *p++ = *s++;
+# endif
+# endif /* FANCY_MODEM */
+ if (p > buf && p[-1] == ' ')
+ p--;
+ *p = '\0';
+ }
+#else
+# ifdef TIOCGSOFTCAR
+ sprintf(p, " %s", softcar ? "(CD)", "CD");
+ p += strlen(p);
+# endif
+#endif
+ if (clocal)
+ *p++ = '}';
+ *p = '\0';
+ return buf;
+}
+
+/*
+ * Old bsd-ish machines may not have any of the baudrate B... symbols.
+ * We hope to detect them here, so that the btable[] below always has
+ * many entries.
+ */
+#ifndef POSIX
+# ifndef TERMIO
+# if !defined(B9600) && !defined(B2400) && !defined(B1200) && !defined(B300)
+IFN{B0}#define B0 0
+IFN{B50}#define B50 1
+IFN{B75}#define B75 2
+IFN{B110}#define B110 3
+IFN{B134}#define B134 4
+IFN{B150}#define B150 5
+IFN{B200}#define B200 6
+IFN{B300}#define B300 7
+IFN{B600}#define B600 8
+IFN{B1200}#define B1200 9
+IFN{B1800}#define B1800 10
+IFN{B2400}#define B2400 11
+IFN{B4800}#define B4800 12
+IFN{B9600}#define B9600 13
+IFN{EXTA}#define EXTA 14
+IFN{EXTB}#define EXTB 15
+# endif
+# endif
+#endif
+
+/*
+ * On hpux, idx and sym will be different.
+ * Rumor has it that, we need idx in D_dospeed to make tputs
+ * padding correct.
+ * Frequently used entries come first.
+ */
+static struct baud_values btable[] =
+{
+IF{B9600} { 13, 9600, B9600 },
+IF{B19200} { 14, 19200, B19200 },
+IF{EXTA} { 14, 19200, EXTA },
+IF{B38400} { 15, 38400, B38400 },
+IF{EXTB} { 15, 38400, EXTB },
+IF{B57600} { 16, 57600, B57600 },
+IF{B115200} { 17, 115200, B115200 },
+IF{B230400} { 18, 230400, B230400 },
+IF{B460800} { 19, 460800, B460800 },
+IF{B7200} { 13, 7200, B7200 },
+IF{B4800} { 12, 4800, B4800 },
+IF{B3600} { 12, 3600, B3600 },
+IF{B2400} { 11, 2400, B2400 },
+IF{B1800} { 10, 1800, B1800 },
+IF{B1200} { 9, 1200, B1200 },
+IF{B900} { 9, 900, B900 },
+IF{B600} { 8, 600, B600 },
+IF{B300} { 7, 300, B300 },
+IF{B200} { 6, 200, B200 },
+IF{B150} { 5, 150, B150 },
+IF{B134} { 4, 134, B134 },
+IF{B110} { 3, 110, B110 },
+IF{B75} { 2, 75, B75 },
+IF{B50} { 1, 50, B50 },
+IF{B0} { 0, 0, B0 },
+ { -1, -1, -1 }
+};
+
+/*
+ * baud may either be a bits-per-second value or a symbolic
+ * value as returned by cfget?speed()
+ */
+struct baud_values *
+lookup_baud(baud)
+int baud;
+{
+ struct baud_values *p;
+
+ for (p = btable; p->idx >= 0; p++)
+ if (baud == p->bps || baud == p->sym)
+ return p;
+ return NULL;
}
+/*
+ * change the baud rate in a mode structure.
+ * ibaud and obaud are given in bit/second, or at your option as
+ * termio B... symbols as defined in e.g. suns sys/ttydev.h
+ * -1 means don't change.
+ */
+int
+SetBaud(m, ibaud, obaud)
+struct mode *m;
+int ibaud, obaud;
+{
+ struct baud_values *ip, *op;
+
+ if ((!(ip = lookup_baud(ibaud)) && ibaud != -1) ||
+ (!(op = lookup_baud(obaud)) && obaud != -1))
+ return -1;
+
+#ifdef POSIX
+ if (ip) cfsetispeed(&m->tio, ip->sym);
+ if (op) cfsetospeed(&m->tio, op->sym);
+#else /* POSIX */
+# ifdef TERMIO
+ if (ip)
+ {
+# ifdef IBSHIFT
+ m->tio.c_cflag &= ~(CBAUD << IBSHIFT);
+ m->tio.c_cflag |= (ip->sym & CBAUD) << IBSHIFT;
+# else /* IBSHIFT */
+ if (ibaud != obaud)
+ return -1;
+# endif /* IBSHIFT */
+ }
+ if (op)
+ {
+ m->tio.c_cflag &= ~CBAUD;
+ m->tio.c_cflag |= op->sym & CBAUD;
+ }
+# else /* TERMIO */
+ if (ip) m->m_ttyb.sg_ispeed = ip->idx;
+ if (op) m->m_ttyb.sg_ospeed = op->idx;
+# endif /* TERMIO */
+#endif /* POSIX */
+ return 0;
+}
/*
* Write out the mode struct in a readable form
@@ -814,18 +1478,20 @@ struct mode *m;
debug1("c_oflag = %#x\n", (unsigned int)m->tio.c_oflag);
debug1("c_cflag = %#x\n", (unsigned int)m->tio.c_cflag);
debug1("c_lflag = %#x\n", (unsigned int)m->tio.c_lflag);
+ debug1("cfgetospeed() = %d\n", (int)cfgetospeed(&m->tio));
+ debug1("cfgetispeed() = %d\n", (int)cfgetispeed(&m->tio));
for (i = 0; i < sizeof(m->tio.c_cc)/sizeof(*m->tio.c_cc); i++)
{
debug2("c_cc[%d] = %#x\n", i, m->tio.c_cc[i]);
}
-# ifdef hpux
+# ifdef HPUX_LTCHARS_HACK
debug1("suspc = %#02x\n", m->m_ltchars.t_suspc);
debug1("dsuspc = %#02x\n", m->m_ltchars.t_dsuspc);
debug1("rprntc = %#02x\n", m->m_ltchars.t_rprntc);
debug1("flushc = %#02x\n", m->m_ltchars.t_flushc);
debug1("werasc = %#02x\n", m->m_ltchars.t_werasc);
debug1("lnextc = %#02x\n", m->m_ltchars.t_lnextc);
-# endif /* hpux */
+# endif /* HPUX_LTCHARS_HACK */
#else /* POSIX */
# ifdef TERMIO
debug("struct termio tio:\n");
diff --git a/utmp.c b/utmp.c
index befe6cb..2a172d4 100644
--- a/utmp.c
+++ b/utmp.c
@@ -25,20 +25,6 @@
RCS_ID("$Id: utmp.c,v 1.7 1994/05/31 12:33:21 mlschroe Exp $ FAU")
-/*
- * An explanation of some weird things:
- *
- * linux should have GETUTENT, but their pututline() doesn't have
- * a return value.
- *
- * UTNOKEEP: A (ugly) hack for apollo that does two things:
- * 1) Always close and reopen the utmp file descriptor. (I don't know
- * for what reason this is done...)
- * 2) Implement an unsorted utmp file much like GETUTENT.
- * (split into UT_CLOSE and UT_UNSORTED)
- */
-
-
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -47,13 +33,19 @@ RCS_ID("$Id: utmp.c,v 1.7 1994/05/31 12:33:21 mlschroe Exp $ FAU")
#include "screen.h"
#include "extern.h"
-
extern struct display *display;
extern struct win *fore;
extern char *LoginName;
-#ifdef NETHACK
-extern nethackflag;
-#endif
+extern int real_uid, eff_uid;
+
+
+/*
+ * UTNOKEEP: A (ugly) hack for apollo that does two things:
+ * 1) Always close and reopen the utmp file descriptor. (I don't know
+ * for what reason this is done...)
+ * 2) Implement an unsorted utmp file much like GETUTENT.
+ * (split into UT_CLOSE and UT_UNSORTED)
+ */
#ifdef UTNOKEEP
@@ -61,16 +53,52 @@ extern nethackflag;
# define UT_UNSORTED
#endif
+#ifdef UT_CLOSE
+# undef UT_CLOSE
+# define UT_CLOSE endutent()
+#else
+# define UT_CLOSE
+#endif
+
+
+/*
+ * we have a suid-root helper app that changes the utmp for us
+ * (won't work for login-slots)
+ */
+#if (defined(sun) && defined(SVR4) && defined(GETUTENT)) || defined(HAVE_UTEMPTER)
+# define UTMP_HELPER
+#endif
+
+
#ifdef UTMPOK
+
static slot_t TtyNameSlot __P((char *));
+static void makeuser __P((struct utmp *, char *, char *, int));
+static void makedead __P((struct utmp *));
+static int pututslot __P((slot_t, struct utmp *, char *, struct win *));
+static struct utmp *getutslot __P((slot_t));
+#ifndef GETUTENT
+static struct utmp *getutent __P((void));
+static void endutent __P((void));
+static int initutmp __P((void));
+static void setutent __P((void));
+#endif
+#if defined(linux) && defined(GETUTENT)
+static struct utmp *xpututline __P((struct utmp *utmp));
+# define pututline xpututline
+#endif
+
-static int utmpok, utmpfd = -1;
+static int utmpok;
static char UtmpName[] = UTMPFILE;
+#ifndef UTMP_HELPER
+static int utmpfd = -1;
+#endif
-# if defined(GETUTENT) && !defined(SVR4)
+# if defined(GETUTENT) && (!defined(SVR4) || defined(__hpux))
# if defined(hpux) /* cruel hpux release 8.0 */
# define pututline _pututline
# endif /* hpux */
@@ -79,7 +107,7 @@ extern struct utmp *getutline(), *pututline();
extern struct utmp *ut_add_user(), *ut_delete_user();
extern char *ut_find_host();
# ifndef UTHOST
-# define UTHOST /* _SEQUENT_ has got ut_find_host() */
+# define UTHOST /* _SEQUENT_ has ut_find_host() */
# endif
# endif /* _SEQUENT_ */
# endif /* GETUTENT && !SVR4 */
@@ -94,9 +122,17 @@ static struct ttyent *getttyent __P((void));
# endif
# endif /* !GETUTENT && !UT_UNSORTED */
-#endif /* UTMPOK */
+#ifndef _SEQUENT_
+# undef D_loginhost
+# define D_loginhost D_utmp_logintty.ut_host
+#endif
+#ifndef UTHOST
+# undef D_loginhost
+# define D_loginhost ((char *)0)
+#endif
+#endif /* UTMPOK */
/*
@@ -109,28 +145,51 @@ static struct ttyent *getttyent __P((void));
* w_slot = 0 window not logged in, but should be logged in.
* (unable to write utmp, or detached).
*/
+
+#ifndef UTMPOK
void
SlotToggle(how)
int how;
{
- debug1("SlotToggle %d\n", how);
+ debug1("SlotToggle (!UTMPOK) %d\n", how);
+# ifdef UTMPFILE
+ Msg(0, "Unable to modify %s.\n", UTMPFILE);
+# else
+ Msg(0, "Unable to modify utmp-database.\n");
+# endif
+}
+#endif
+
+
+
#ifdef UTMPOK
+
+void
+SlotToggle(how)
+int how;
+{
+ debug1("SlotToggle %d\n", how);
+ if (fore->w_type != W_TYPE_PTY)
+ {
+ Msg(0, "Can only work with normal windows.\n");
+ return;
+ }
if (how)
{
debug(" try to log in\n");
if ((fore->w_slot == (slot_t) -1) || (fore->w_slot == (slot_t) 0))
{
-# ifdef USRLIMIT
+#ifdef USRLIMIT
if (CountUsers() >= USRLIMIT)
- Msg(0, "User limit reached.");
- else
-# endif
- {
- if (SetUtmp(fore) == 0)
- Msg(0, "This window is now logged in.");
- else
- Msg(0, "This window should now be logged in.");
- }
+ {
+ Msg(0, "User limit reached.");
+ return;
+ }
+#endif
+ if (SetUtmp(fore) == 0)
+ Msg(0, "This window is now logged in.");
+ else
+ Msg(0, "This window should now be logged in.");
}
else
Msg(0, "This window is already logged in.");
@@ -153,28 +212,48 @@ int how;
Msg(0, "What? Cannot remove Utmp slot?");
else
Msg(0, "This window is no longer logged in.");
+#ifdef CAREFULUTMP
+ CarefulUtmp();
+#endif
}
}
-#else /* !UTMPOK */
-# ifdef UTMPFILE
- Msg(0, "Unable to modify %s.\n", UTMPFILE);
-# else
- Msg(0, "Unable to modify utmp-database.\n");
-# endif
-#endif
}
+#ifdef CAREFULUTMP
+/* CAREFULUTMP: goodie for paranoid sysadmins: always leave one
+ * window logged in
+ */
+void
+CarefulUtmp()
+{
+ struct win *p;
-#ifdef UTMPOK
-
+ if (!windows) /* hopeless */
+ return;
+ debug("CarefulUtmp counting slots\n");
+ for (p = windows; p; p = p->w_next)
+ if (p->w_ptyfd >= 0 && p->w_slot != (slot_t)-1)
+ return; /* found one, nothing to do */
+
+ debug("CarefulUtmp: no slots, log one in again.\n");
+ for (p = windows; p; p = p->w_next)
+ if (p->w_ptyfd >= 0) /* no zombies please */
+ break;
+ if (!p)
+ return; /* really hopeless */
+ SetUtmp(p);
+ Msg(0, "Window %d is now logged in.\n", p->w_number);
+}
+#endif /* CAREFULUTMP */
void
InitUtmp()
{
debug1("InitUtmp testing '%s'...\n", UtmpName);
+#ifndef UTMP_HELPER
if ((utmpfd = open(UtmpName, O_RDWR)) == -1)
{
if (errno != EACCES)
@@ -183,10 +262,11 @@ InitUtmp()
utmpok = 0;
return;
}
-#ifdef GETUTENT
+# ifdef GETUTENT
close(utmpfd); /* it was just a test */
utmpfd = -1;
-#endif /* GETUTENT */
+# endif /* GETUTENT */
+#endif /* UTMP_HELPER */
utmpok = 1;
}
@@ -195,34 +275,18 @@ InitUtmp()
int
CountUsers()
{
-# ifdef GETUTENT
- struct utmp *ut, *getutent();
-# else /* GETUTENT */
- struct utmp utmpbuf;
-# endif /* GETUTENT */
+ struct utmp *ut;
int UserCount;
-# ifdef UT_CLOSE
- InitUtmp();
-# endif /* UT_CLOSE */
debug1("CountUsers() - utmpok=%d\n", utmpok);
if (!utmpok)
return 0;
UserCount = 0;
-# ifdef GETUTENT
setutent();
while (ut = getutent())
- if (ut->ut_type == USER_PROCESS)
+ if (SLOT_USED(ut))
UserCount++;
-# else /* GETUTENT */
- (void) lseek(utmpfd, (off_t) 0, 0);
- while (read(utmpfd, &utmpbuf, sizeof(utmpbuf)) == sizeof(utmpbuf))
- if (utmpbuf.ut_name[0] != '\0')
- UserCount++;
-# endif /* GETUTENT */
-# ifdef UT_CLOSE
- close(utmpfd);
-# endif /* UT_CLOSE */
+ UT_CLOSE;
return UserCount;
}
#endif /* USRLIMIT */
@@ -236,97 +300,62 @@ CountUsers()
void
RemoveLoginSlot()
{
-#ifdef GETUTENT
- struct utmp *uu;
-#endif /* GETUTENT */
- struct utmp u; /* 'empty' slot that we write back */
-#ifdef _SEQUENT_
- char *p;
-#endif /* _SEQUENT_ */
+ struct utmp u, *uu;
ASSERT(display);
debug("RemoveLoginSlot: removing your logintty\n");
D_loginslot = TtyNameSlot(D_usertty);
if (D_loginslot == (slot_t)0 || D_loginslot == (slot_t)-1)
return;
-#ifdef UT_CLOSE
- InitUtmp();
-#endif /* UT_CLOSE */
+#ifdef UTMP_HELPER
+ if (eff_uid) /* helpers can't do login slots. sigh. */
+#else
if (!utmpok)
+#endif
{
+ D_loginslot = 0;
debug("RemoveLoginSlot: utmpok == 0\n");
- return;
}
-
+ else
+ {
#ifdef _SEQUENT_
- if (p = ut_find_host(D_loginslot))
- strncpy(D_loginhost, p, sizeof(D_loginhost) - 1);
- D_loginhost[sizeof(D_loginhost) - 1] = 0;
+ {
+ char *p;
+ if ((p = ut_find_host(D_loginslot)) != 0)
+ strncpy(D_loginhost, p, sizeof(D_loginhost) - 1);
+ D_loginhost[sizeof(D_loginhost) - 1] = 0;
+ }
#endif /* _SEQUENT_ */
- bzero((char *) &u, sizeof(u));
-
-#ifdef GETUTENT
- setutent();
- strncpy(u.ut_line, D_loginslot, sizeof(u.ut_line));
- if ((uu = getutline(&u)) == 0)
- {
- Msg(0, "Utmp slot not found -> not removed");
- return;
- }
- D_utmp_logintty = *uu;
-# ifdef _SEQUENT_
- if (ut_delete_user(D_loginslot, uu->ut_pid, 0, 0) == 0)
-# else /* _SEQUENT_ */
- u = *uu;
- /*
- * Ed Hill (ed-hill@uiowa.edu) screen-3.5.2 under AIX 3.2.5
- * when you are down to a single screen, and you log out of it (thus exiting
- * screen), it leaves a stray entry in the utmp file. Seems better:
- * u.ut_type = EMPTY;
- */
- u.ut_type = DEAD_PROCESS;
- u.ut_user[0] = '\0'; /* for Digital UNIX 3.2C, kilbi@rad.rwth-aachen.de */
- u.ut_exit.e_termination = 0;
- u.ut_exit.e_exit= 0;
- if (pututline(&u) == 0)
-# endif /* _SEQUENT_ */
-
-#else /* GETUTENT */
-
- bzero((char *)&D_utmp_logintty, sizeof(u));
- (void) lseek(utmpfd, (off_t) (D_loginslot * sizeof(u)), 0);
- if (read(utmpfd, (char *) &D_utmp_logintty, sizeof(u)) != sizeof(u))
- {
- Msg(errno, "cannot read %s ??", UtmpName);
- sleep(1);
- }
-# ifdef UT_UNSORTED
- /* copy tty line */
- bcopy((char *)&D_utmp_logintty, (char *)&u, sizeof(u));
- bzero(u.ut_name, sizeof(u.ut_name));
- bzero(u.ut_host, sizeof(u.ut_host));
-# ifdef linux
- u.ut_type = DEAD_PROCESS;
-# endif
-# endif /* UT_UNSORTED */
- (void) lseek(utmpfd, (off_t) (D_loginslot * sizeof(u)), 0);
- if (write(utmpfd, (char *) &u, sizeof(u)) != sizeof(u))
-
-#endif /* GETUTENT */
-
- {
-#ifdef NETHACK
- if (nethackflag)
- Msg(errno, "%s is too hard to dig in", UtmpName);
+ if ((uu = getutslot(D_loginslot)) == 0)
+ {
+ debug("Utmp slot not found -> not removed");
+ D_loginslot = 0;
+ }
else
-#endif /* NETHACK */
- Msg(errno, "Could not write %s", UtmpName);
+ {
+ D_utmp_logintty = *uu;
+ u = *uu;
+ makedead(&u);
+ if (pututslot(D_loginslot, &u, (char *)0, (struct win *)0) == 0)
+ D_loginslot = 0;
+ }
+ UT_CLOSE;
}
-#ifdef UT_CLOSE
- close(utmpfd);
-#endif /* UT_CLOSE */
debug1(" slot %d zapped\n", (int)D_loginslot);
+ if (D_loginslot == (slot_t)0)
+ {
+ /* couldn't remove slot, do a 'mesg n' at least. */
+ struct stat stb;
+ char *tty;
+ debug("couln't zap slot -> do mesg n\n");
+ D_loginttymode = 0;
+ if ((tty = ttyname(D_userfd)) && stat(tty, &stb) == 0 && stb.st_uid == real_uid && ((int)stb.st_mode & 0777) != 0666)
+ {
+ D_loginttymode = (int)stb.st_mode & 0777;
+ chmod(D_usertty, stb.st_mode & 0600);
+ }
+ }
}
/*
@@ -335,74 +364,27 @@ RemoveLoginSlot()
void
RestoreLoginSlot()
{
+ char *tty;
+
debug("RestoreLoginSlot()\n");
ASSERT(display);
-#ifdef UT_CLOSE
- InitUtmp();
-#endif /* UT_CLOSE */
if (utmpok && D_loginslot != (slot_t)0 && D_loginslot != (slot_t)-1)
{
-#ifdef GETUTENT
-# ifdef _SEQUENT_
- int fail;
- debug1(" logging you in again (slot %s)\n", D_loginslot);
-/*
- * We have problems if we add the console and use ut_add_user()
- * because the id will be 'scon' instead of 'co'. So we
- * restore it with pututline(). The reason why we don't use
- * pututline all the time is that we want to set the host field.
- * Unfortunatelly this can only be done with ut_add_user().
- */
- if (*D_loginhost)
- {
- fail = (ut_add_user(D_utmp_logintty.ut_name, D_loginslot, D_utmp_logintty.ut_pid,
- *D_loginhost ? D_loginhost : (char *)0) == 0);
- }
- else
- {
- setutent();
- fail = (pututline(&D_utmp_logintty) == 0);
- }
- if (fail)
-# else /* _SEQUENT_ */
- debug1(" logging you in again (slot %s)\n", D_loginslot);
- setutent();
- if (pututline(&D_utmp_logintty) == 0)
-# endif /* _SEQUENT */
-#else /* GETUTENT */
- debug1(" logging you in again (slot %d)\n", D_loginslot);
-# ifdef sequent
- /*
- * call sequent undocumented routine to count logins
- * and add utmp entry if possible
- */
- if (add_utmp(D_loginslot, &D_utmp_logintty) == -1)
-# else /* sequent */
- (void) lseek(utmpfd, (off_t) (D_loginslot * sizeof(struct utmp)), 0);
- if (write(utmpfd, (char *) &D_utmp_logintty, sizeof(struct utmp))
- != sizeof(struct utmp))
-# endif /* sequent */
-#endif /* GETUTENT */
- {
-#ifdef NETHACK
- if (nethackflag)
- Msg(errno, "%s is too hard to dig in", UtmpName);
- else
-#endif /* NETHACK */
- Msg(errno,"Could not write %s", UtmpName);
- }
+ debug1(" logging you in again (slot %#x)\n", (int)D_loginslot);
+ if (pututslot(D_loginslot, &D_utmp_logintty, D_loginhost, (struct win *)0) == 0)
+ Msg(errno,"Could not write %s", UtmpName);
}
-#ifdef UT_CLOSE
- close(utmpfd);
-#endif /* UT_CLOSE */
- D_loginslot = (slot_t) 0;
+ UT_CLOSE;
+ D_loginslot = (slot_t)0;
+ if (D_loginttymode && (tty = ttyname(D_userfd)))
+ chmod(tty, D_loginttymode);
}
/*
* Construct a utmp entry for window wi.
- * the hostname field reflects what we know about the user (i.e. display)
+ * the hostname field reflects what we know about the user (display)
* location. If d_loginhost is not set, then he is local and we write
* down the name of his terminal line; else he is remote and we keep
* the hostname here. The letter S and the window id will be appended.
@@ -415,21 +397,16 @@ struct win *wi;
{
register char *p;
register slot_t slot;
-#ifndef _SEQUENT_
- char *line;
-#endif
struct utmp u;
int saved_ut;
#ifdef UTHOST
-# ifdef _SEQUENT_
- char host[100+5];
-# else /* _SEQUENT_ */
- char host[sizeof(D_utmp_logintty.ut_host)+5];
-# endif /* _SEQUENT_ */
+ char host[sizeof(D_loginhost) + 15];
+#else
+ int host = 0;
#endif /* UTHOST */
wi->w_slot = (slot_t)0;
- if (!utmpok)
+ if (!utmpok || wi->w_type != W_TYPE_PTY)
return -1;
if ((slot = TtyNameSlot(wi->w_tty)) == (slot_t)0)
{
@@ -437,24 +414,20 @@ struct win *wi;
return -1;
}
debug2("SetUtmp %d will get slot %d...\n", wi->w_number, (int)slot);
-#ifdef UT_CLOSE
- InitUtmp();
-#endif /* UT_CLOSE */
- bzero((char *) &u, sizeof(u));
- if ((saved_ut = bcmp((char *) &wi->w_savut, (char *) &u, sizeof(u))))
+ bzero((char *)&u, sizeof(u));
+ if ((saved_ut = bcmp((char *) &wi->w_savut, (char *)&u, sizeof(u))))
/* restore original, of which we will adopt all fields but ut_host */
- bcopy((char *) &wi->w_savut, (char *) &u, sizeof(u));
+ bcopy((char *)&wi->w_savut, (char *) &u, sizeof(u));
+
+ if (!saved_ut)
+ makeuser(&u, stripdev(wi->w_tty), LoginName, wi->w_pid);
#ifdef UTHOST
- host[sizeof(host)-5] = '\0';
+ host[sizeof(host) - 15] = '\0';
if (display)
{
-# ifdef _SEQUENT_
- strncpy(host, D_loginhost, sizeof(host) - 5);
-# else /* _SEQUENT */
- strncpy(host, D_utmp_logintty.ut_host, sizeof(host) - 5);
-# endif /* _SEQUENT */
+ strncpy(host, D_loginhost, sizeof(host) - 15);
if (D_loginslot != (slot_t)0 && D_loginslot != (slot_t)-1 && host[0] != '\0')
{
/*
@@ -463,6 +436,7 @@ struct win *wi;
* "faui45:s.0" or
* "132.199.81.4:s.0" (even this may hurt..), but not
* "faui45.informati"......:s.0
+ * HPUX uses host:0.0, so chop at "." and ":" (Eric Backus)
*/
for (p = host; *p; p++)
if ((*p < '0' || *p > '9') && (*p != '.'))
@@ -470,7 +444,7 @@ struct win *wi;
if (*p)
{
for (p = host; *p; p++)
- if (*p == '.')
+ if (*p == '.' || (*p == ':' && p != host))
{
*p = '\0';
break;
@@ -479,90 +453,34 @@ struct win *wi;
}
else
{
- strncpy(host + 1, stripdev(D_usertty), sizeof(host) - 6);
+ strncpy(host + 1, stripdev(D_usertty), sizeof(host) - 15 - 1);
host[0] = ':';
}
}
else
- strncpy(host, "local", sizeof(host) - 5);
- sprintf(host + strlen(host), ":S.%c", '0' + wi->w_number);
+ strncpy(host, "local", sizeof(host) - 15);
+
+ sprintf(host + strlen(host), ":S.%d", wi->w_number);
debug1("rlogin hostname: '%s'\n", host);
+
# if !defined(_SEQUENT_) && !defined(sequent)
strncpy(u.ut_host, host, sizeof(u.ut_host));
# endif
#endif /* UTHOST */
-#ifdef _SEQUENT_
- if (ut_add_user(saved_ut ? u.ut_user : LoginName, slot, saved_ut ? u.ut_pid : wi->w_pid, host) == 0)
-#else /* _SEQUENT_ */
- if (!saved_ut)
- { /* make new utmp from scratch */
- line = stripdev(wi->w_tty);
-# ifdef GETUTENT
- strncpy(u.ut_user, LoginName, sizeof(u.ut_user));
- /* Now the tricky part... guess ut_id */
-# ifdef sgi
- strncpy(u.ut_id, line + 3, sizeof(u.ut_id));
-# else /* sgi */
-# ifdef _IBMR2
- strncpy(u.ut_id, line, sizeof(u.ut_id));
-# else
- strncpy(u.ut_id, line + strlen(line) - 2, sizeof(u.ut_id));
-# endif
-# endif /* sgi */
- strncpy(u.ut_line, line, sizeof(u.ut_line));
- u.ut_pid = wi->w_pid;
- u.ut_type = USER_PROCESS;
- (void) time((time_t *)&u.ut_time);
- } /* !saved_ut {-: */
- setutent();
- if (pututline(&u) == 0)
-# else /* GETUTENT */
- strncpy(u.ut_line, line, sizeof(u.ut_line));
- strncpy(u.ut_name, LoginName, sizeof(u.ut_name));
-# if defined(linux) /* should have GETUTENT */
- u.ut_type = USER_PROCESS;
- u.ut_pid = wi->w_pid;
- strncpy(u.ut_id, line + 3, sizeof(u.ut_id));
-# endif /* linux */
- (void) time((time_t *)&u.ut_time); /* cast needed for ultrix */
- } /* !saved_ut */
-# ifdef sequent
- /*
- * call sequent undocumented routine to count logins and
- * add utmp entry if possible
- */
- if (add_utmp(slot, &u) == -1)
-# else /* sequent */
- (void) lseek(utmpfd, (off_t) (slot * sizeof(u)), 0);
- if (write(utmpfd, (char *) &u, sizeof(u)) != sizeof(u))
-# endif /* sequent */
-# endif /* GETUTENT */
-#endif /* _SEQUENT_ */
-
+ if (pututslot(slot, &u, host, wi) == 0)
{
-#ifdef NETHACK
- if (nethackflag)
- Msg(errno, "%s is too hard to dig in", UtmpName);
- else
-#endif /* NETHACK */
Msg(errno,"Could not write %s", UtmpName);
-#ifdef UT_CLOSE
- close(utmpfd);
-#endif /* UT_CLOSE */
+ UT_CLOSE;
return -1;
}
debug("SetUtmp successful\n");
wi->w_slot = slot;
-#ifdef UT_CLOSE
- close(utmpfd);
-#endif /* UT_CLOSE */
- bcopy((char *) &u, (char *) &wi->w_savut, sizeof(u));
+ bcopy((char *)&u, (char *)&wi->w_savut, sizeof(u));
+ UT_CLOSE;
return 0;
}
-
-
/*
* if slot could be removed or was 0, wi->w_slot = -1;
* else not changed.
@@ -572,152 +490,281 @@ int
RemoveUtmp(wi)
struct win *wi;
{
-#ifdef GETUTENT
- struct utmp *uu;
-#endif /* GETUTENT */
- struct utmp u;
+ struct utmp u, *uu;
slot_t slot;
slot = wi->w_slot;
-#ifdef GETUTENT
- debug1("RemoveUtmp(%s)\n", (slot == (slot_t) 0) ?
- "no slot (0)":((slot == (slot_t) -1) ? "no slot (-1)" : slot));
-#else /* GETUTENT */
- debug1("RemoveUtmp(wi.slot: %d)\n", slot);
-#endif /* GETUTENT */
-#ifdef UT_CLOSE
- InitUtmp();
-#endif /* UT_CLOSE */
+ debug1("RemoveUtmp slot=%#x\n", slot);
if (!utmpok)
return -1;
- if (slot == (slot_t) 0 || slot == (slot_t) -1)
+ if (slot == (slot_t)0 || slot == (slot_t)-1)
{
- debug1("There is no utmp-slot to be removed(%d)\n", (int)slot);
- wi->w_slot = (slot_t) -1;
+ wi->w_slot = (slot_t)-1;
return 0;
}
bzero((char *) &u, sizeof(u));
-#ifdef GETUTENT
- setutent();
-# ifdef sgi
- bcopy((char *) &wi->w_savut, (char *) &u, sizeof(u));
+#ifdef sgi
+ bcopy((char *)&wi->w_savut, (char *)&u, sizeof(u));
uu = &u;
-# else
- strncpy(u.ut_line, slot, sizeof(u.ut_line));
- if ((uu = getutline(&u)) == 0)
+#else
+ if ((uu = getutslot(slot)) == 0)
{
Msg(0, "Utmp slot not found -> not removed");
return -1;
}
bcopy((char *)uu, (char *)&wi->w_savut, sizeof(wi->w_savut));
-# endif
-# ifdef _SEQUENT_
- if (ut_delete_user(slot, uu->ut_pid, 0, 0) == 0)
-# else /* _SEQUENT_ */
+#endif
u = *uu;
- u.ut_type = DEAD_PROCESS;
- u.ut_exit.e_termination = 0;
- u.ut_exit.e_exit= 0;
- if (pututline(&u) == 0)
-# endif /* _SEQUENT_ */
-#else /* GETUTENT */
- (void) lseek(utmpfd, (off_t) (slot * sizeof(u)), 0);
- if (read(utmpfd, (char *) &wi->w_savut, sizeof(u)) != sizeof(u))
+ makedead(&u);
+ if (pututslot(slot, &u, (char *)0, wi) == 0)
{
- bzero((char *)&wi->w_savut, sizeof(wi->w_savut));
- Msg(errno, "cannot read %s?", UtmpName);
- sleep(1);
- }
-# ifdef UT_UNSORTED
- bcopy((char *)&wi->w_savut, (char *)&u, sizeof(u));
- bzero(u.ut_name, sizeof(u.ut_name));
- bzero(u.ut_host, sizeof(u.ut_host));
-# ifdef linux
- u.ut_type = DEAD_PROCESS;
-# endif
-# endif /* UT_UNSORTED */
- (void) lseek(utmpfd, (off_t) (slot * sizeof(u)), 0);
- if (write(utmpfd, (char *) &u, sizeof(u)) != sizeof(u))
-#endif /* GETUTENT */
- {
-#ifdef NETHACK
- if (nethackflag)
- Msg(errno, "%s is too hard to dig in", UtmpName);
- else
-#endif /* NETHACK */
Msg(errno,"Could not write %s", UtmpName);
-#ifdef UT_CLOSE
- close(utmpfd);
-#endif /* UT_CLOSE */
+ UT_CLOSE;
return -1;
}
debug("RemoveUtmp successfull\n");
- wi->w_slot = (slot_t) -1;
-#ifdef UT_CLOSE
- close(utmpfd);
-#endif /* UT_CLOSE */
+ wi->w_slot = (slot_t)-1;
+ UT_CLOSE;
return 0;
}
-/*
- * TtyNameSlot:
- * return an index, where the named tty is found in utmp.
+/*********************************************************************
+ *
+ * routines using the getut* api
*/
-static slot_t
+#ifdef GETUTENT
+
+#define SLOT_USED(u) (u->ut_type == USER_PROCESS)
+
+static struct utmp *
+getutslot(slot)
+slot_t slot;
+{
+ struct utmp u;
+ bzero((char *)&u, sizeof(u));
+ strncpy(u.ut_line, slot, sizeof(u.ut_line));
+ setutent();
+ return getutline(&u);
+}
+
+static int
+pututslot(slot, u, host, wi)
+slot_t slot;
+struct utmp *u;
+char *host;
+struct win *wi;
+{
+#ifdef _SEQUENT_
+ if (SLOT_USED(u) && host && *host)
+ return ut_add_user(u.ut_name, slot, u.ut_pid, host) != 0;
+ if (!SLOT_USED(u))
+ return ut_delete_user(slot, u.ut_pid, 0, 0) != 0;
+#endif
+#ifdef HAVE_UTEMPTER
+ if (eff_uid && wi->w_ptyfd != -1)
+ {
+ /* sigh, linux hackers made the helper functions void */
+ if (SLOT_USED(u))
+ addToUtmp(wi->w_tty, host, wi->w_ptyfd);
+ else
+ removeLineFromUtmp(wi->w_tty, wi->w_ptyfd);
+ return 1; /* pray for success */
+ }
+#endif
+ setutent();
+ return pututline(u) != 0;
+}
+
+static void
+makedead(u)
+struct utmp *u;
+{
+ u->ut_type = DEAD_PROCESS;
+#if !defined(linux) || defined(EMPTY)
+ u->ut_exit.e_termination = 0;
+ u->ut_exit.e_exit = 0;
+#endif
+#if !defined(sun) || !defined(SVR4)
+ u->ut_user[0] = 0; /* for Digital UNIX, kilbi@rad.rwth-aachen.de */
+#endif
+}
+
+static void
+makeuser(u, line, user, pid)
+struct utmp *u;
+char *line, *user;
+int pid;
+{
+ u->ut_type = USER_PROCESS;
+ strncpy(u->ut_user, user, sizeof(u->ut_user));
+ /* Now the tricky part... guess ut_id */
+#if defined(sgi) || defined(linux)
+ strncpy(u->ut_id, line + 3, sizeof(u->ut_id));
+#else /* sgi */
+# ifdef _IBMR2
+ strncpy(u->ut_id, line, sizeof(u->ut_id));
+# else
+ strncpy(u->ut_id, line + strlen(line) - 2, sizeof(u->ut_id));
+# endif
+#endif /* sgi */
+ strncpy(u->ut_line, line, sizeof(u->ut_line));
+ u->ut_pid = pid;
+ (void)time((time_t *)&u->ut_time);
+}
+
+static slot_t
TtyNameSlot(nam)
char *nam;
{
- char *name;
- register slot_t slot;
+ return stripdev(nam);
+}
+
+
+#else /* GETUTENT */
+
+/*********************************************************************
+ *
+ * getut emulation for systems lacking the api
+ */
+
+static struct utmp uent;
+
+#define SLOT_USED(u) (u.ut_name[0] != 0)
+
+static int
+initutmp()
+{
+ if (utmpfd >= 0)
+ return 1;
+ return (utmpfd = open(UtmpName, O_RDWR)) >= 0;
+}
+
+static void
+setutent()
+{
+ if (utmpfd >= 0)
+ (void)lseek(utmpfd, (off_t)0, 0);
+}
+
+static void
+endutent()
+{
+ if (utmpfd >= 0)
+ close(utmpfd);
+ utmpfd = -1;
+}
+
+static struct utmp *
+getutent()
+{
+ if (utmpfd < 0 && !initutmp())
+ return 0;
+ if (read(utmpfd, &uent, sizeof(uent)) != sizeof(uent))
+ return 0;
+ return &uent;
+}
+
+static struct utmp *
+getutslot(slot)
+slot_t slot;
+{
+ if (utmpfd < 0 && !initutmp())
+ return 0;
+ lseek(utmpfd, (off_t)(slot * sizeof(struct utmp)), 0);
+ if (read(utmpfd, &uent, sizeof(uent)) != sizeof(uent))
+ return 0;
+ return &uent;
+}
+
+static int
+pututslot(slot, u, host, wi)
+slot_t slot;
+struct utmp *u;
+char *host;
+struct win *wi;
+{
+#ifdef sequent
+ if (SLOT_USED(u))
+ return add_utmp(slot, u) != -1;
+#endif
+ if (utmpfd < 0 && !initutmp())
+ return 0;
+ lseek(utmpfd, (off_t)(slot * sizeof(*u)), 0);
+ if (write(utmpfd, u, sizeof(*u)) != sizeof(*u))
+ return 0;
+ return 1;
+}
+
+
+static void
+makedead(u)
+struct utmp *u;
+{
#ifdef UT_UNSORTED
- struct utmp u;
+ bzero(u->ut_name, sizeof(u->ut_name));
+# ifdef UTHOST
+ bzero(u->ut_host, sizeof(u->ut_host));
+# endif
#else
-# ifndef GETUTENT
- register struct ttyent *tp;
-# endif /* GETUTENT */
-#endif /* UT_UNSORTED */
+ bzero((char *)u, sizeof(*u));
+#endif
+}
- debug1("TtyNameSlot(%s)\n", nam);
-#ifdef UT_CLOSE
- InitUtmp();
-#endif /* UT_CLOSE */
- if (!utmpok || nam == 0)
- return (slot_t)0;
- name = stripdev(nam);
-#ifdef GETUTENT
- slot = name;
-#else /* GETUTENT */
-# ifdef UT_UNSORTED
- slot = 0;
- (void) lseek(utmpfd, (off_t) 0, 0);
- while ((read(utmpfd, (char *)&u, sizeof(u)) == sizeof(u))
- && (strcmp(u.ut_line, name)))
- slot++;
-# else /* UT_UNSORTED*/
+
+static void
+makeuser(u, line, user, pid)
+struct utmp *u;
+char *line, *user;
+int pid;
+{
+ strncpy(u->ut_line, line, sizeof(u->ut_line));
+ strncpy(u->ut_name, user, sizeof(u->ut_name));
+ (void)time((time_t *)&u->ut_time);
+}
+
+static slot_t
+TtyNameSlot(nam)
+char *nam;
+{
+ slot_t slot;
+ char *line;
+#ifndef UT_UNSORTED
+ struct ttyent *tp;
+#endif
+
+ line = stripdev(nam);
+#ifdef UT_UNSORTED
+ setutent();
+ if (utmpfd < 0)
+ return -1;
+ for (slot = 0; getutent(); slot++)
+ if (strcmp(uent.ut_line, line) == 0)
+ break;
+ UT_CLOSE;
+#else
slot = 1;
setttyent();
- while ((tp = getttyent()) != 0 && strcmp(name, tp->ty_name) != 0)
+ while ((tp = getttyent()) != 0 && strcmp(line, tp->ty_name) != 0)
slot++;
-# endif /* UTNOKEEP */
-#endif /* GETUTENT */
-
-#ifdef UT_CLOSE
- close(utmpfd);
#endif
return slot;
}
+#endif /* GETUTENT */
-#if !defined(GETTTYENT) && !defined(GETUTENT) && !defined(UT_UNSORTED)
-/*
+/*********************************************************************
+ *
* Cheap plastic imitation of ttyent routines.
*/
+#if !defined(GETTTYENT) && !defined(GETUTENT) && !defined(UT_UNSORTED)
+
+
static char *tt, *ttnext;
static char ttys[] = "/etc/ttys";
@@ -805,3 +852,21 @@ getlogin()
}
# endif /* BUGGYGETLOGIN */
+#if defined(linux) && defined(GETUTENT)
+# undef pututline
+
+/* aargh, linux' pututline returns void! */
+struct utmp *
+xpututline(u)
+struct utmp *u;
+{
+ struct utmp *u2;
+ pututline(u);
+ setutent();
+ u2 = getutline(u);
+ if (u2 == 0)
+ return u->ut_type == DEAD_PROCESS ? u : 0;
+ return u->ut_type == u2->ut_type ? u : 0;
+}
+#endif
+
diff --git a/window.c b/window.c
index fc2e62d..f898c8b 100644
--- a/window.c
+++ b/window.c
@@ -29,29 +29,32 @@ RCS_ID("$Id: window.c,v 1.20 1994/05/31 12:33:24 mlschroe Exp $ FAU")
#include <signal.h>
#include <fcntl.h>
#ifndef sun
-#include <sys/ioctl.h>
+# include <sys/ioctl.h>
#endif
#include "config.h"
-#ifdef SVR4
-# include <sys/stropts.h>
-#endif
-
#include "screen.h"
#include "extern.h"
+#include "logfile.h" /* logfopen() */
extern struct display *displays, *display;
extern struct win *windows, *fore, *wtab[], *console_window;
extern char *ShellArgs[];
extern char *ShellProg;
extern char screenterm[];
+extern char *screenlogfile;
extern char HostName[];
extern int TtyMode;
-extern struct LayFuncs WinLf;
+extern int SilenceWait;
extern int real_uid, real_gid, eff_uid, eff_gid;
extern char Termcap[];
extern char **NewEnv;
+extern int visual_bell;
+extern struct event logflushev;
+extern int log_flush, logtstamp_after;
+extern int ZombieKey_destroy, ZombieKey_resurrect;
+extern struct layer *flayer;
#if defined(TIOCSWINSZ) || defined(TIOCGWINSZ)
extern struct winsize glwz;
@@ -61,56 +64,441 @@ extern struct winsize glwz;
extern int aixhack;
#endif
+static void WinProcess __P((char **, int *));
+static void WinRedisplayLine __P((int, int, int, int));
+static void WinClearLine __P((int, int, int));
+static int WinRewrite __P((int, int, int, struct mchar *, int));
+static int WinResize __P((int, int));
+static void WinRestore __P((void));
+static int DoAutolf __P((char *, int *, int));
+static void ZombieProcess __P((char **, int *));
+static void win_readev_fn __P((struct event *, char *));
+static void win_writeev_fn __P((struct event *, char *));
+static int muchpending __P((struct win *, struct event *));
+#ifdef COPY_PASTE
+static void paste_slowev_fn __P((struct event *, char *));
+#endif
+#ifdef PSEUDOS
+static void pseu_readev_fn __P((struct event *, char *));
+static void pseu_writeev_fn __P((struct event *, char *));
+#endif
+static void win_silenceev_fn __P((struct event *, char *));
-static int OpenDevice __P((char *, int, int *, char **));
-static int ForkWindow __P((char **, char *, char *, char *, struct win *));
+static int OpenDevice __P((char **, int, int *, char **));
+static int ForkWindow __P((struct win *, char **, char *));
static void execvpe __P((char *, char **, char **));
+int VerboseCreate = 0; /* XXX move this to user.h */
+
char DefaultShell[] = "/bin/sh";
static char DefaultPath[] = ":/usr/ucb:/bin:/usr/bin";
-
+/* keep this in sync with the structure definition in window.h */
struct NewWindow nwin_undef =
{
- -1, (char *)0, (char **)0, (char *)0, (char *)0, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, (char *)0, (char *)0
+ -1, /* StartAt */
+ (char *)0, /* aka */
+ (char **)0, /* args */
+ (char *)0, /* dir */
+ (char *)0, /* term */
+ -1, /* aflag */
+ -1, /* flowflag */
+ -1, /* lflag */
+ -1, /* histheight */
+ -1, /* monitor */
+ -1, /* wlock */
+ -1, /* silence */
+ -1, /* wrap */
+ -1, /* logging */
+ -1, /* slowpaste */
+ -1, /* c1 */
+ -1, /* gr */
+ -1, /* kanji */
+ (char *)0, /* hstatus */
+ (char *)0 /* charset */
};
struct NewWindow nwin_default =
{
- 0, (char *)0, ShellArgs, (char *)0, screenterm, 0, 1*FLOW_NOW,
- LOGINDEFAULT, DEFAULTHISTHEIGHT, MON_OFF, WLOCK_AUTO,
- 1, 1, 0, 0, (char *)0, (char *)0
+ 0, /* StartAt */
+ 0, /* aka */
+ ShellArgs, /* args */
+ 0, /* dir */
+ screenterm, /* term */
+ 0, /* aflag */
+ 1*FLOW_NOW, /* flowflag */
+ LOGINDEFAULT, /* lflag */
+ DEFAULTHISTHEIGHT, /* histheight */
+ MON_OFF, /* monitor */
+ WLOCK_OFF, /* wlock */
+ 0, /* silence */
+ 1, /* wrap */
+ 0, /* logging */
+ 0, /* slowpaste */
+ 1, /* c1 */
+ 0, /* gr */
+ 0, /* kanji */
+ (char *)0, /* hstatus */
+ (char *)0 /* charset */
};
struct NewWindow nwin_options;
+static int const_IOSIZE = IOSIZE;
+static int const_one = 1;
+
void
nwin_compose(def, new, res)
struct NewWindow *def, *new, *res;
{
- res->StartAt = new->StartAt != nwin_undef.StartAt ? new->StartAt : def->StartAt;
- res->aka = new->aka != nwin_undef.aka ? new->aka : def->aka;
- res->args = new->args != nwin_undef.args ? new->args : def->args;
- res->dir = new->dir != nwin_undef.dir ? new->dir : def->dir;
- res->term = new->term != nwin_undef.term ? new->term : def->term;
- res->aflag = new->aflag != nwin_undef.aflag ? new->aflag : def->aflag;
- res->flowflag = new->flowflag != nwin_undef.flowflag ? new->flowflag : def->flowflag;
- res->lflag = new->lflag != nwin_undef.lflag ? new->lflag : def->lflag;
- res->histheight = new->histheight != nwin_undef.histheight ? new->histheight : def->histheight;
- res->monitor = new->monitor != nwin_undef.monitor ? new->monitor : def->monitor;
- res->wlock = new->wlock != nwin_undef.wlock ? new->wlock : def->wlock;
- res->wrap = new->wrap != nwin_undef.wrap ? new->wrap : def->wrap;
- res->c1 = new->c1 != nwin_undef.c1 ? new->c1 : def->c1;
- res->gr = new->gr != nwin_undef.gr ? new->gr : def->gr;
-#ifdef KANJI
- res->kanji = new->kanji != nwin_undef.kanji ? new->kanji : def->kanji;
+#define COMPOSE(x) res->x = new->x != nwin_undef.x ? new->x : def->x
+ COMPOSE(StartAt);
+ COMPOSE(aka);
+ COMPOSE(args);
+ COMPOSE(dir);
+ COMPOSE(term);
+ COMPOSE(aflag);
+ COMPOSE(flowflag);
+ COMPOSE(lflag);
+ COMPOSE(histheight);
+ COMPOSE(monitor);
+ COMPOSE(wlock);
+ COMPOSE(silence);
+ COMPOSE(wrap);
+ COMPOSE(Lflag);
+ COMPOSE(slow);
+ COMPOSE(c1);
+ COMPOSE(gr);
+ COMPOSE(kanji);
+ COMPOSE(hstatus);
+ COMPOSE(charset);
+#undef COMPOSE
+}
+
+/*****************************************************************
+ *
+ * The window layer functions
+ */
+
+struct LayFuncs WinLf =
+{
+ WinProcess,
+ 0,
+ WinRedisplayLine,
+ WinClearLine,
+ WinRewrite,
+ WinResize,
+ WinRestore
+};
+
+static int
+DoAutolf(buf, lenp, fr)
+char *buf;
+int *lenp;
+int fr;
+{
+ char *p;
+ int len = *lenp;
+ int trunc = 0;
+
+ for (p = buf; len > 0; p++, len--)
+ {
+ if (*p != '\r')
+ continue;
+ if (fr-- <= 0)
+ {
+ trunc++;
+ len--;
+ }
+ if (len == 0)
+ break;
+ bcopy(p, p + 1, len++);
+ p[1] = '\n';
+ }
+ *lenp = p - buf;
+ return trunc;
+}
+
+static void
+WinProcess(bufpp, lenp)
+char **bufpp;
+int *lenp;
+{
+ int l2 = 0, f, *ilen, l = *lenp, trunc;
+ char *ibuf;
+
+ debug1("WinProcess: %d bytes\n", *lenp);
+ fore = (struct win *)flayer->l_data;
+
+ if (fore->w_ptyfd < 0) /* zombie? */
+ {
+ ZombieProcess(bufpp, lenp);
+ return;
+ }
+#ifdef MULTIUSER
+ /* a pending writelock is this:
+ * fore->w_wlock == WLOCK_AUTO, fore->w_wlockuse = NULL
+ * The user who wants to use this window next, will get the lock, if he can.
+ */
+ if (display && fore->w_wlock == WLOCK_AUTO &&
+ !fore->w_wlockuser && !AclCheckPermWin(D_user, ACL_WRITE, fore))
+ {
+ fore->w_wlockuser = D_user;
+ debug2("window %d: pending writelock grabbed by user %s\n",
+ fore->w_number, fore->w_wlockuser->u_name);
+ }
+ /* if w_wlock is set, only one user may write, else we check acls */
+ if (display && ((fore->w_wlock == WLOCK_OFF) ?
+ AclCheckPermWin(D_user, ACL_WRITE, fore) :
+ (D_user != fore->w_wlockuser)))
+ {
+ debug2("window %d, user %s: ", fore->w_number, D_user->u_name);
+ debug2("writelock %d (wlockuser %s)\n", fore->w_wlock,
+ fore->w_wlockuser ? fore->w_wlockuser->u_name : "NULL");
+ /* XXX FIXME only display !*/
+ WBell(fore, visual_bell);
+ *bufpp += *lenp;
+ *lenp = 0;
+ return;
+ }
+#endif /* MULTIUSER */
+
+#ifdef BUILTIN_TELNET
+ if (fore->w_type == W_TYPE_TELNET && TelIsline(fore) && *bufpp != fore->w_telbuf)
+ {
+ TelProcessLine(bufpp, lenp);
+ return;
+ }
+#endif
+
+#ifdef PSEUDOS
+ if (W_UWP(fore))
+ {
+ /* we send the user input to our pseudowin */
+ ibuf = fore->w_pwin->p_inbuf; ilen = &fore->w_pwin->p_inlen;
+ f = sizeof(fore->w_pwin->p_inbuf) - *ilen;
+ }
+ else
+#endif /* PSEUDOS */
+ {
+ /* we send the user input to the window */
+ ibuf = fore->w_inbuf; ilen = &fore->w_inlen;
+ f = sizeof(fore->w_inbuf) - *ilen;
+ }
+
+ if (l > f)
+ l = f;
+#ifdef BUILTIN_TELNET
+ while (l > 0)
+#else
+ if (l > 0)
#endif
- res->hstatus = new->hstatus != nwin_undef.hstatus ? new->hstatus : def->hstatus;
- res->charset = new->charset != nwin_undef.charset ? new->charset : def->charset;
+ {
+ l2 = l;
+ bcopy(*bufpp, ibuf + *ilen, l2);
+ if (fore->w_autolf && (trunc = DoAutolf(ibuf + *ilen, &l2, f - l2)))
+ l -= trunc;
+#ifdef BUILTIN_TELNET
+ if (fore->w_type == W_TYPE_TELNET && (trunc = DoTelnet(ibuf + *ilen, &l2, f - l2)))
+ {
+ l -= trunc;
+ if (fore->w_autolf)
+ continue; /* need exact value */
+ }
+#endif
+ *ilen += l2;
+ *bufpp += l;
+ *lenp -= l;
+ return;
+ }
+}
+
+static void
+ZombieProcess(bufpp, lenp)
+char **bufpp;
+int *lenp;
+{
+ int l = *lenp;
+ char *buf = *bufpp, b1[10], b2[10];
+
+ debug1("ZombieProcess: %d bytes\n", *lenp);
+ fore = (struct win *)flayer->l_data;
+
+ ASSERT(fore->w_ptyfd < 0);
+ *bufpp += *lenp;
+ *lenp = 0;
+ for (; l-- > 0; buf++)
+ {
+ if (*(unsigned char *)buf == ZombieKey_destroy)
+ {
+ debug1("Turning undead: %d\n", fore->w_number);
+ KillWindow(fore);
+ return;
+ }
+ if (*(unsigned char *)buf == ZombieKey_resurrect)
+ {
+ debug1("Resurrecting Zombie: %d\n", fore->w_number);
+ WriteString(fore, "\r\n", 2);
+ RemakeWindow(fore);
+ return;
+ }
+ }
+ b1[AddXChar(b1, ZombieKey_destroy)] = '\0';
+ b2[AddXChar(b2, ZombieKey_resurrect)] = '\0';
+ Msg(0, "Press %s to destroy or %s to resurrect window", b1, b2);
+}
+
+static void
+WinRedisplayLine(y, from, to, isblank)
+int y, from, to, isblank;
+{
+ debug3("WinRedisplayLine %d %d %d\n", y, from, to);
+ if (y < 0)
+ return;
+ fore = (struct win *)flayer->l_data;
+ if (from == 0 && y > 0 && fore->w_mlines[y - 1].image[fore->w_width] == 0)
+ {
+ struct mchar nc;
+ copy_mline2mchar(&nc, &fore->w_mlines[y], 0);
+ LWrapChar(&fore->w_layer, &nc, y - 1, -1, -1, 0);
+ from++;
+ }
+ LCDisplayLine(&fore->w_layer, &fore->w_mlines[y], y, from, to, isblank);
+}
+
+static int
+WinRewrite(y, x1, x2, rend, doit)
+int y, x1, x2, doit;
+struct mchar *rend;
+{
+ register int cost, dx;
+ register char *p, *i;
+#ifdef FONT
+ register char *f;
+#endif
+#ifdef COLOR
+ register char *c;
+#endif
+
+ debug3("WinRewrite %d, %d-%d\n", y, x1, x2);
+ fore = (struct win *)flayer->l_data;
+ dx = x2 - x1 + 1;
+ if (doit)
+ {
+ i = fore->w_mlines[y].image + x1;
+ while (dx-- > 0)
+ PUTCHAR(*i++);
+ return 0;
+ }
+ p = fore->w_mlines[y].attr + x1;
+#ifdef FONT
+ f = fore->w_mlines[y].font + x1;
+#endif
+#ifdef COLOR
+ c = fore->w_mlines[y].color + x1;
+#endif
+
+ cost = dx = x2 - x1 + 1;
+ while(dx-- > 0)
+ {
+ if (*p++ != rend->attr)
+ return EXPENSIVE;
+#ifdef FONT
+ if (*f++ != rend->font)
+ return EXPENSIVE;
+#endif
+#ifdef COLOR
+ if (*c++ != rend->color)
+ return EXPENSIVE;
+#endif
+ }
+ return cost;
+}
+
+static void
+WinClearLine(y, xs, xe)
+int y, xs, xe;
+{
+ fore = (struct win *)flayer->l_data;
+ LClearLine(flayer, y, xs, xe, &fore->w_mlines[y]);
}
+static int
+WinResize(wi, he)
+int wi, he;
+{
+ fore = (struct win *)flayer->l_data;
+ ChangeWindowSize(fore, wi, he, fore->w_histheight);
+ return 0;
+}
+
+static void
+WinRestore()
+{
+ struct canvas *cv;
+ fore = (struct win *)flayer->l_data;
+ debug1("WinRestore: win %x\n", fore);
+ for (cv = flayer->l_cvlist; cv; cv = cv->c_next)
+ {
+ display = cv->c_display;
+ if (cv != D_forecv)
+ continue;
+ /* ChangeScrollRegion(fore->w_top, fore->w_bot); */
+ KeypadMode(fore->w_keypad);
+ CursorkeysMode(fore->w_cursorkeys);
+ SetFlow(fore->w_flow & FLOW_NOW);
+ InsertMode(fore->w_insert);
+ ReverseVideo(fore->w_revvid);
+ CursorVisibility(fore->w_curinv ? -1 : fore->w_curvvis);
+ }
+}
+
+/*****************************************************************/
+
+
+/*
+ * DoStartLog constructs a path for the "want to be logfile" in buf and
+ * attempts logfopen.
+ *
+ * returns 0 on success.
+ */
+int
+DoStartLog(w, buf, bufsize)
+struct win *w;
+char *buf;
+int bufsize;
+{
+ int n;
+ if (!w || !buf)
+ return -1;
+
+ strncpy(buf, MakeWinMsg(screenlogfile, w, '%'), bufsize - 1);
+ buf[bufsize - 1] = 0;
+
+ debug2("DoStartLog: win %d, file %s\n", w->w_number, buf);
+
+ if (w->w_log != NULL)
+ logfclose(w->w_log);
+
+ if ((w->w_log = logfopen(buf, islogfile(buf) ? NULL : secfopen(buf, "a"))) == NULL)
+ return -2;
+ if (!logflushev.queued)
+ {
+ n = log_flush ? log_flush : (logtstamp_after + 4) / 5;
+ if (n)
+ {
+ SetTimeout(&logflushev, n * 1000);
+ evenq(&logflushev);
+ }
+ }
+ return 0;
+}
+
+/*
+ * Umask & wlock are set for the user of the display,
+ * The display d (if specified) switches to that window.
+ */
int
MakeWindow(newwin)
struct NewWindow *newwin;
@@ -119,7 +507,7 @@ struct NewWindow *newwin;
register int n, i;
int f = -1;
struct NewWindow nwin;
- int ttyflag;
+ int type;
char *TtyName;
#ifdef MULTIUSER
extern struct user *users;
@@ -129,9 +517,12 @@ struct NewWindow *newwin;
debug1("NewWindow: aka %s\n", newwin->aka?newwin->aka:"NULL");
debug1("NewWindow: dir %s\n", newwin->dir?newwin->dir:"NULL");
debug1("NewWindow: term %s\n", newwin->term?newwin->term:"NULL");
+
nwin_compose(&nwin_default, newwin, &nwin);
debug1("NWin: aka %s\n", nwin.aka ? nwin.aka : "NULL");
debug1("NWin: wlock %d\n", nwin.wlock);
+ debug1("NWin: Lflag %d\n", nwin.Lflag);
+
pp = wtab + nwin.StartAt;
do
@@ -161,25 +552,37 @@ struct NewWindow *newwin;
n = pp - wtab;
debug1("Makewin creating %d\n", n);
- if ((f = OpenDevice(nwin.args[0], nwin.lflag, &ttyflag, &TtyName)) < 0)
+ if ((f = OpenDevice(nwin.args, nwin.lflag, &type, &TtyName)) < 0)
return -1;
- if ((p = (struct win *) malloc(sizeof(struct win))) == 0)
+ if ((p = (struct win *)malloc(sizeof(struct win))) == 0)
{
close(f);
Msg(0, strnomem);
return -1;
}
- bzero((char *) p, (int) sizeof(struct win)); /* looks like a calloc above */
+ bzero((char *)p, (int)sizeof(struct win));
+
+#ifdef UTMPOK
+ if (type != W_TYPE_PTY)
+ nwin.lflag = 0;
+#endif
+
+ p->w_type = type;
/* save the command line so that zombies can be resurrected */
for (i = 0; nwin.args[i] && i < MAXARGS - 1; i++)
p->w_cmdargs[i] = SaveStr(nwin.args[i]);
p->w_cmdargs[i] = 0;
+ if (nwin.dir)
+ p->w_dir = SaveStr(nwin.dir);
+ if (nwin.term)
+ p->w_term = SaveStr(nwin.term);
+ p->w_number = n;
#ifdef MULTIUSER
- /*
- * This is dangerous: without a display we use creators umask
+ /*
+ * This is dangerous: without a display we use creators umask
* This is intended to be usefull for detached startup.
* But is still better than default bits with a NULL user.
*/
@@ -191,19 +594,18 @@ struct NewWindow *newwin;
return -1;
}
#endif
- p->w_winlay.l_next = 0;
- p->w_winlay.l_layfn = &WinLf;
- p->w_winlay.l_data = (char *)p;
- p->w_lay = &p->w_winlay;
- p->w_display = display;
+ p->w_layer.l_next = 0;
+ p->w_layer.l_bottom = &p->w_layer;
+ p->w_layer.l_layfn = &WinLf;
+ p->w_layer.l_data = (char *)p;
+ p->w_savelayer = &p->w_layer;
p->w_pdisplay = 0;
+
#ifdef MULTIUSER
if (display && !AclCheckPermWin(D_user, ACL_WRITE, p))
-#else
- if (display)
-#endif
p->w_wlockuser = D_user;
- p->w_number = n;
+ p->w_wlock = nwin.wlock;
+#endif
p->w_ptyfd = f;
p->w_aflag = nwin.aflag;
p->w_flow = nwin.flowflag | ((nwin.flowflag & FLOW_AUTOFLAG) ? (FLOW_AUTO|FLOW_NOW) : FLOW_AUTO);
@@ -222,13 +624,23 @@ struct NewWindow *newwin;
if (nwin.hstatus)
p->w_hstatus = SaveStr(nwin.hstatus);
p->w_monitor = nwin.monitor;
+ /*
+ * defsilence by Lloyd Zusman (zusman_lloyd@jpmorgan.com)
+ */
+ p->w_silence = nwin.silence;
+ p->w_silencewait = SilenceWait;
+#ifdef COPY_PASTE
+ p->w_slowpaste = nwin.slow;
+#else
+ nwin.histheight = 0;
+#endif
+
p->w_norefresh = 0;
strncpy(p->w_tty, TtyName, MAXSTR - 1);
-#ifndef COPY_PASTE
- nwin.histheight = 0;
-#endif
- if (ChangeWindowSize(p, display ? D_defwidth : 80, display ? D_defheight : 24, nwin.histheight))
+ if (ChangeWindowSize(p, display ? D_defwidth : 80,
+ display ? D_defheight : 24,
+ nwin.histheight))
{
FreeWindow(p);
return -1;
@@ -237,29 +649,55 @@ struct NewWindow *newwin;
p->w_kanji = nwin.kanji;
#endif
ResetWindow(p); /* sets w_wrap, w_c1, w_gr */
+#ifdef FONT
if (nwin.charset)
SetCharsets(p, nwin.charset);
+#endif
- if (ttyflag == TTY_FLAG_PLAIN)
+ if (VerboseCreate)
{
- p->w_t.flags |= TTY_FLAG_PLAIN;
- p->w_pid = 0;
+ struct display *d = display; /* WriteString zaps display */
+
+ WriteString(p, ":screen (", 9);
+ WriteString(p, p->w_title, strlen(p->w_title));
+ WriteString(p, "):", 2);
+ for (f = 0; p->w_cmdargs[f]; f++)
+ {
+ WriteString(p, " ", 1);
+ WriteString(p, p->w_cmdargs[f], strlen(p->w_cmdargs[f]));
+ }
+ WriteString(p, "\r\n", 2);
+ display = d;
}
- else
- {
- debug("forking...\n");
+
+ p->w_pid = 0;
#ifdef PSEUDOS
- p->w_pwin = NULL;
+ p->w_pwin = 0;
#endif
- p->w_pid = ForkWindow(nwin.args, nwin.dir, nwin.term, TtyName, p);
+
+#ifdef BUILTIN_TELNET
+ if (type == W_TYPE_TELNET)
+ {
+ if (TelConnect(p))
+ {
+ FreeWindow(p);
+ return -1;
+ }
+ }
+ else
+#endif
+ if (type == W_TYPE_PTY)
+ {
+ p->w_pid = ForkWindow(p, nwin.args, TtyName);
if (p->w_pid < 0)
{
FreeWindow(p);
return -1;
}
}
+
/*
- * Place the newly created window at the head of the most-recently-used list.
+ * Place the new window at the head of the most-recently-used list.
*/
if (display && D_fore)
D_other = D_fore;
@@ -267,22 +705,58 @@ struct NewWindow *newwin;
p->w_next = windows;
windows = p;
#ifdef UTMPOK
- p->w_slot = (slot_t) -1;
+ p->w_slot = (slot_t)-1;
# ifdef LOGOUTOK
debug1("MakeWindow will %slog in.\n", nwin.lflag?"":"not ");
if (nwin.lflag)
# else /* LOGOUTOK */
- debug1("MakeWindow will log in, LOGOUTOK undefined in config.h%s.\n",
- nwin.lflag?"":" (although lflag=0)");
+ debug1("MakeWindow will log in, LOGOUTOK undefined in config.h%s.\n",
+ nwin.lflag?"":" (although lflag=0)");
# endif /* LOGOUTOK */
{
- p->w_slot = (slot_t) 0;
+ p->w_slot = (slot_t)0;
if (display)
SetUtmp(p);
}
+# ifdef CAREFULUTMP
+ CarefulUtmp(); /* If all 've been zombies, we've had no slot */
+# endif
+#endif /* UTMPOK */
+
+ if (nwin.Lflag)
+ {
+ char buf[1024];
+ DoStartLog(p, buf, sizeof(buf));
+ }
+
+ p->w_readev.fd = p->w_writeev.fd = p->w_ptyfd;
+ p->w_readev.type = EV_READ;
+ p->w_writeev.type = EV_WRITE;
+ p->w_readev.data = p->w_writeev.data = (char *)p;
+ p->w_readev.handler = win_readev_fn;
+ p->w_writeev.handler = win_writeev_fn;
+ p->w_writeev.condpos = &p->w_inlen;
+ evenq(&p->w_readev);
+ evenq(&p->w_writeev);
+#ifdef COPY_PASTE
+ p->w_paster.pa_slowev.type = EV_TIMEOUT;
+ p->w_paster.pa_slowev.data = (char *)&p->w_paster;
+ p->w_paster.pa_slowev.handler = paste_slowev_fn;
#endif
+ p->w_silenceev.type = EV_TIMEOUT;
+ p->w_silenceev.data = (char *)p;
+ p->w_silenceev.handler = win_silenceev_fn;
+ if (p->w_silence > 0)
+ {
+ debug("New window has silence enabled.\n");
+ SetTimeout(&p->w_silenceev, p->w_silencewait * 1000);
+ evenq(&p->w_silenceev);
+ }
+
SetForeWindow(p);
Activate(p->w_norefresh);
+ WindowChanged((struct win*)0, 'w');
+ WindowChanged((struct win*)0, 'W');
return n;
}
@@ -296,55 +770,95 @@ int
RemakeWindow(p)
struct win *p;
{
- int ttyflag;
char *TtyName;
int lflag, f;
lflag = nwin_default.lflag;
- if ((f = OpenDevice(p->w_cmdargs[0], lflag, &ttyflag, &TtyName)) < 0)
+ if ((f = OpenDevice(p->w_cmdargs, lflag, &p->w_type, &TtyName)) < 0)
return -1;
strncpy(p->w_tty, *TtyName ? TtyName : p->w_title, MAXSTR - 1);
p->w_ptyfd = f;
+ p->w_readev.fd = f;
+ p->w_writeev.fd = f;
+ evenq(&p->w_readev);
+ evenq(&p->w_writeev);
- p->w_t.flags &= ~TTY_FLAG_PLAIN;
- if (ttyflag == TTY_FLAG_PLAIN)
+ if (VerboseCreate)
{
- p->w_t.flags |= TTY_FLAG_PLAIN; /* Just in case... */
- WriteString(p, p->w_cmdargs[0], strlen(p->w_cmdargs[0]));
- WriteString(p, ": ", 2);
+ struct display *d = display; /* WriteString zaps display */
+
+ WriteString(p, ":screen (", 9);
WriteString(p, p->w_title, strlen(p->w_title));
- WriteString(p, "\r\n", 2);
- p->w_pid = 0;
- }
- else
- {
+ WriteString(p, "):", 2);
for (f = 0; p->w_cmdargs[f]; f++)
{
- if (f)
- WriteString(p, " ", 1);
+ WriteString(p, " ", 1);
WriteString(p, p->w_cmdargs[f], strlen(p->w_cmdargs[f]));
}
WriteString(p, "\r\n", 2);
- p->w_pid = ForkWindow(p->w_cmdargs, (char *)0, nwin_default.term, TtyName, p);
+ display = d;
+ }
+
+ p->w_pid = 0;
+#ifdef BUILTIN_TELNET
+ if (p->w_type == W_TYPE_TELNET)
+ {
+ if (TelConnect(p))
+ return -1;
+ }
+ else
+#endif
+ if (p->w_type == W_TYPE_PTY)
+ {
+ p->w_pid = ForkWindow(p, p->w_cmdargs, TtyName);
if (p->w_pid < 0)
- return -1;
+ return -1;
}
#ifdef UTMPOK
if (display && p->w_slot == (slot_t)0)
SetUtmp(p);
+# ifdef CAREFULUTMP
+ CarefulUtmp(); /* If all 've been zombies, we've had no slot */
+# endif
#endif
return p->w_number;
}
void
+CloseDevice(wp)
+struct win *wp;
+{
+ if (wp->w_ptyfd < 0)
+ return;
+ if (wp->w_type == W_TYPE_PTY)
+ {
+ /* pty 4 SALE */
+ (void)chmod(wp->w_tty, 0666);
+ (void)chown(wp->w_tty, 0, 0);
+ }
+ close(wp->w_ptyfd);
+ wp->w_ptyfd = -1;
+ wp->w_tty[0] = 0;
+ evdeq(&wp->w_readev);
+ evdeq(&wp->w_writeev);
+#ifdef BUILTIN_TELNET
+ evdeq(&wp->w_telconnev);
+#endif
+ wp->w_readev.fd = wp->w_writeev.fd = -1;
+}
+
+void
FreeWindow(wp)
struct win *wp;
{
struct display *d;
int i;
+ struct canvas *cv, *ncv;
+ struct layer *l;
+ debug1("FreeWindow %d\n", wp ? wp->w_number: -1);
#ifdef PSEUDOS
if (wp->w_pwin)
FreePseudowin(wp);
@@ -352,42 +866,94 @@ struct win *wp;
#ifdef UTMPOK
RemoveUtmp(wp);
#endif
- if (wp->w_ptyfd >= 0)
+ CloseDevice(wp);
+
+ if (wp == console_window)
{
- (void) chmod(wp->w_tty, 0666);
- (void) chown(wp->w_tty, 0, 0);
- close(wp->w_ptyfd);
- wp->w_ptyfd = -1;
+ TtyGrabConsole(-1, -1, "free");
+ console_window = 0;
}
- if (wp == console_window)
- console_window = 0;
- if (wp->w_logfp != NULL)
- fclose(wp->w_logfp);
+ if (wp->w_log != NULL)
+ logfclose(wp->w_log);
ChangeWindowSize(wp, 0, 0, 0);
+
if (wp->w_hstatus)
free(wp->w_hstatus);
for (i = 0; wp->w_cmdargs[i]; i++)
free(wp->w_cmdargs[i]);
+ if (wp->w_dir)
+ free(wp->w_dir);
+ if (wp->w_term)
+ free(wp->w_term);
for (d = displays; d; d = d->d_next)
- if (d->d_other == wp)
- d->d_other = 0;
+ {
+ if (d->d_other == wp)
+ d->d_other = d->d_fore && d->d_fore->w_next != wp ? d->d_fore->w_next : wp->w_next;
+ if (d->d_fore == wp)
+ d->d_fore = NULL;
+ for (cv = d->d_cvlist; cv; cv = cv->c_next)
+ {
+ for (l = cv->c_layer; l; l = l->l_next)
+ if (l->l_layfn == &WinLf)
+ break;
+ if (!l)
+ continue;
+ if ((struct win *)l->l_data != wp)
+ continue;
+ if (cv->c_layer == wp->w_savelayer)
+ wp->w_savelayer = 0;
+ KillLayerChain(cv->c_layer);
+ }
+ }
+ if (wp->w_savelayer)
+ KillLayerChain(wp->w_savelayer);
+ for (cv = wp->w_layer.l_cvlist; cv; cv = ncv)
+ {
+ ncv = cv->c_lnext;
+ cv->c_layer = &cv->c_blank;
+ cv->c_blank.l_cvlist = cv;
+ cv->c_lnext = 0;
+ cv->c_xoff = cv->c_xs;
+ cv->c_yoff = cv->c_ys;
+ RethinkViewportOffsets(cv);
+ }
+ wp->w_layer.l_cvlist = 0;
+
#ifdef MULTIUSER
- for (i = 0; i < ACL_BITS_PER_WIN; i++)
- free((char *)wp->w_userbits[i]);
+ FreeWindowAcl(wp);
+#endif /* MULTIUSER */
+ evdeq(&wp->w_readev); /* just in case */
+ evdeq(&wp->w_writeev); /* just in case */
+ evdeq(&wp->w_silenceev);
+#ifdef COPY_PASTE
+ FreePaster(&wp->w_paster);
#endif
free((char *)wp);
}
static int
-OpenDevice(arg, lflag, typep, namep)
-char *arg;
+OpenDevice(args, lflag, typep, namep)
+char **args;
int lflag;
int *typep;
char **namep;
{
+ char *arg = args[0];
struct stat st;
int f;
+ if (!arg)
+ return -1;
+#ifdef BUILTIN_TELNET
+ if (strcmp(arg, "//telnet") == 0)
+ {
+ f = TelOpen(args + 1);
+ lflag = 0;
+ *typep = W_TYPE_TELNET;
+ *namep = "telnet";
+ }
+ else
+#endif
if ((stat(arg, &st)) == 0 && S_ISCHR(st.st_mode))
{
if (access(arg, R_OK | W_OK) == -1)
@@ -396,14 +962,15 @@ char **namep;
return -1;
}
debug("OpenDevice: OpenTTY\n");
- if ((f = OpenTTY(arg)) < 0)
+ if ((f = OpenTTY(arg, args[1])) < 0)
return -1;
- *typep = TTY_FLAG_PLAIN;
+ lflag = 0;
+ *typep = W_TYPE_PLAIN;
*namep = arg;
}
else
{
- *typep = 0; /* for now we hope it is a program */
+ *typep = W_TYPE_PTY;
f = OpenPTY(namep);
if (f == -1)
{
@@ -413,7 +980,6 @@ char **namep;
#ifdef TIOCPKT
{
int flag = 1;
-
if (ioctl(f, TIOCPKT, (char *)&flag))
{
Msg(errno, "TIOCPKT ioctl");
@@ -423,34 +989,52 @@ char **namep;
}
#endif /* TIOCPKT */
}
+ debug1("fcntl(%d, F_SETFL, FNBLOCK)\n", f);
(void) fcntl(f, F_SETFL, FNBLOCK);
#ifdef linux
/*
- * Tenebreux (zeus@ns.acadiacom.net) has Linux 1.3.70 where select gets
- * confused in the following condition:
- * Open a pty-master side, request a flush on it, then set packet mode.
- * and call select(). Select will return a possible read, where the
- * one byte response to the flush can be found. Select will thereafter
- * return a possible read, which yields I/O error.
+ * Tenebreux (zeus@ns.acadiacom.net) has Linux 1.3.70 where select
+ * gets confused in the following condition:
+ * Open a pty-master side, request a flush on it, then set packet
+ * mode and call select(). Select will return a possible read, where
+ * the one byte response to the flush can be found. Select will
+ * thereafter return a possible read, which yields I/O error.
+ *
+ * If we request another flush *after* switching into packet mode,
+ * this I/O error does not occur. We receive a single response byte
+ * although we send two flush requests now.
*
- * If we request another flush *after* switching into packet mode, this
- * I/O error does not occur. We receive a single response byte although we
- * send two flush requests now. Maybe we should not flush at all.
+ * Maybe we should not flush at all.
*
* 10.5.96 jw.
*/
- tcflush(f, TCIOFLUSH);
+ if (*typep == W_TYPE_PTY || *typep == W_TYPE_PLAIN)
+ tcflush(f, TCIOFLUSH);
#endif
+
+ if (*typep != W_TYPE_PTY)
+ return f;
+
#ifdef PTYGROUP
- (void) chown(*namep, real_uid, PTYGROUP);
+ if (chown(*namep, real_uid, PTYGROUP) && !eff_uid)
#else
- (void) chown(*namep, real_uid, real_gid);
+ if (chown(*namep, real_uid, real_gid) && !eff_uid)
#endif
+ {
+ Msg(errno, "chown tty");
+ close(f);
+ return -1;
+ }
#ifdef UTMPOK
- (void) chmod(*namep, lflag ? TtyMode : (TtyMode & ~022));
+ if (chmod(*namep, lflag ? TtyMode : (TtyMode & ~022)) && !eff_uid)
#else
- (void) chmod(*namep, TtyMode);
+ if (chmod(*namep, TtyMode) && !eff_uid)
#endif
+ {
+ Msg(errno, "chmod tty");
+ close(f);
+ return -1;
+ }
return f;
}
@@ -462,9 +1046,9 @@ char **namep;
*
*/
static int
-ForkWindow(args, dir, term, ttyn, win)
-char **args, *dir, *term, *ttyn;
+ForkWindow(win, args, ttyn)
struct win *win;
+char **args, *ttyn;
{
int pid;
char tebuf[25];
@@ -482,6 +1066,7 @@ struct win *win;
struct pseudowin *pwin = win->w_pwin;
#endif
+ debug("forking...\n");
proc = *args;
if (proc == 0)
{
@@ -511,19 +1096,16 @@ struct win *win;
signal(SIGXFSZ, SIG_DFL);
#endif
- displays = 0; /* beware of Panic() */
- if (setuid(real_uid) || setgid(real_gid))
- {
- SendErrorMsg("Setuid/gid: %s", strerror(errno));
- _exit(1);
- }
+ displays = 0; /* beware of Panic() */
+ if (setgid(real_gid) || setuid(real_uid))
+ Panic(errno, "Setuid/gid");
eff_uid = real_uid;
eff_gid = real_gid;
- if (dir && *dir && chdir(dir) == -1)
- {
- SendErrorMsg("Cannot chdir to %s: %s", dir, strerror(errno));
- _exit(1);
- }
+#ifdef PSEUDOS
+ if (!pwin) /* ignore directory if pseudo */
+#endif
+ if (win->w_dir && *win->w_dir && chdir(win->w_dir))
+ Panic(errno, "Cannot chdir to %s", win->w_dir);
if (display)
{
@@ -546,6 +1128,7 @@ struct win *win;
aixhack = dup(0);
#endif
#ifdef DEBUG
+ if (dfp) /* do not produce child debug, when debug is "off" */
{
char buf[256];
@@ -566,7 +1149,7 @@ struct win *win;
* distribute filedescriptors between the ttys
*/
#ifdef PSEUDOS
- pat = pwin ? pwin->fdpat :
+ pat = pwin ? pwin->p_fdpat :
((F_PFRONT<<(F_PSHIFT*2)) | (F_PFRONT<<F_PSHIFT) | F_PFRONT);
wfdused = 0;
for(i = 0; i < 3; i++)
@@ -576,10 +1159,7 @@ struct win *win;
if (newfd < 0)
{
if ((newfd = open(ttyn, O_RDWR)) < 0)
- {
- SendErrorMsg("Cannot open %s: %s", ttyn, strerror(errno));
- _exit(1);
- }
+ Panic(errno, "Cannot open %s", ttyn);
}
else
dup(newfd);
@@ -598,14 +1178,11 @@ struct win *win;
*/
debug1("Clearing NBLOCK on window-fd(%d)\n", win->w_ptyfd);
if (fcntl(win->w_ptyfd, F_SETFL, 0))
- SendErrorMsg("Warning: ForkWindow clear NBLOCK fcntl failed, %d", errno);
+ Msg(errno, "Warning: clear NBLOCK fcntl failed");
}
#else /* PSEUDOS */
if ((newfd = open(ttyn, O_RDWR)) != 0)
- {
- SendErrorMsg("Cannot open %s: %s", ttyn, strerror(errno));
- _exit(1);
- }
+ Panic(errno, "Cannot open %s", ttyn);
dup(0);
dup(0);
#endif /* PSEUDOS */
@@ -613,29 +1190,12 @@ struct win *win;
#ifdef _IBMR2
close(aixhack);
#endif
-
if (newfd >= 0)
{
struct mode fakemode, *modep;
-#if defined(SVR4) && !defined(sgi)
- if (ioctl(newfd, I_PUSH, "ptem"))
- {
- SendErrorMsg("Cannot I_PUSH ptem %s %s", ttyn, strerror(errno));
- _exit(1);
- }
- if (ioctl(newfd, I_PUSH, "ldterm"))
- {
- SendErrorMsg("Cannot I_PUSH ldterm %s %s", ttyn, strerror(errno));
- _exit(1);
- }
- if (ioctl(newfd, I_PUSH, "ttcompat"))
- {
- SendErrorMsg("Cannot I_PUSH ttcompat %s %s", ttyn, strerror(errno));
- _exit(1);
- }
-#endif
+ InitPty(newfd);
if (fgtty(newfd))
- SendErrorMsg("fgtty: %s (%d)", strerror(errno), errno);
+ Msg(errno, "fgtty");
if (display)
{
debug("ForkWindow: using display tty mode for new child.\n");
@@ -693,14 +1253,14 @@ struct win *win;
shellbuf[sizeof(shellbuf) - 1] = 0;
NewEnv[4] = shellbuf;
debug1("ForkWindow: NewEnv[4] = '%s'\n", shellbuf);
- if (term && *term && strcmp(screenterm, term) &&
- (strlen(term) < 20))
+ if (win->w_term && *win->w_term && strcmp(screenterm, win->w_term) &&
+ (strlen(win->w_term) < 20))
{
char *s1, *s2, tl;
- sprintf(tebuf, "TERM=%s", term);
+ sprintf(tebuf, "TERM=%s", win->w_term);
debug2("Makewindow %d with %s\n", win->w_number, tebuf);
- tl = strlen(term);
+ tl = strlen(win->w_term);
NewEnv[1] = tebuf;
if ((s1 = index(NewEnv[2], '|')))
{
@@ -709,7 +1269,7 @@ struct win *win;
if (strlen(NewEnv[2]) - (s2 - s1) + tl < 1024)
{
bcopy(s2, s1 + tl, strlen(s2) + 1);
- bcopy(term, s1, tl);
+ bcopy(win->w_term, s1, tl);
}
}
}
@@ -724,8 +1284,7 @@ struct win *win;
debug1("calling execvpe %s\n", proc);
execvpe(proc, args, NewEnv);
debug1("exec error: %d\n", errno);
- SendErrorMsg("Cannot exec '%s': %s", proc, strerror(errno));
- _exit(1);
+ Panic(errno, "Cannot exec '%s'", proc);
default:
break;
}
@@ -752,12 +1311,12 @@ char *prog, **args, **env;
do
{
for (p = buf; *path && *path != ':'; path++)
- if (p - buf < sizeof(buf) - 2)
- *p++ = *path;
+ if (p - buf < sizeof(buf) - 2)
+ *p++ = *path;
if (p > buf)
*p++ = '/';
if (p - buf + strlen(prog) >= sizeof(buf) - 1)
- continue;
+ continue;
strcpy(p, prog);
execve(buf, args, env);
switch (errno)
@@ -795,7 +1354,8 @@ char **av;
extern struct display *display;
extern struct win *windows;
struct pseudowin *pwin;
-
+ int type;
+
if ((w = display ? fore : windows) == NULL)
return -1;
if (!*av || w->w_pwin)
@@ -864,8 +1424,8 @@ char **av;
if (!(l & F_PBACK))
l |= F_UWP;
*t++ = ' ';
- pwin->fdpat = l;
- debug1("winexec: '%#x'\n", pwin->fdpat);
+ pwin->p_fdpat = l;
+ debug1("winexec: '%#x'\n", pwin->p_fdpat);
l = MAXSTR - 4;
for (pp = av; *pp; pp++)
@@ -880,17 +1440,17 @@ char **av;
*--t = '\0';
debug1("%s\n", pwin->p_cmd);
- if ((pwin->p_ptyfd = OpenDevice(av[0], 0, &l, &t)) < 0)
+ if ((pwin->p_ptyfd = OpenDevice(av, 0, &type, &t)) < 0)
{
free((char *)pwin);
return -1;
}
strncpy(pwin->p_tty, t, MAXSTR - 1);
w->w_pwin = pwin;
- if (l == TTY_FLAG_PLAIN)
+ if (type != W_TYPE_PTY)
{
FreePseudowin(w);
- Msg(0, "Cannot handle a TTY as a pseudo win.");
+ Msg(0, "Cannot only use commands as pseudo win.");
return -1;
}
#ifdef TIOCPKT
@@ -905,7 +1465,17 @@ char **av;
}
}
#endif /* TIOCPKT */
- pwin->p_pid = ForkWindow(av, (char *)0, (char *)0, t, w);
+
+ pwin->p_readev.fd = pwin->p_writeev.fd = pwin->p_ptyfd;
+ pwin->p_readev.type = EV_READ;
+ pwin->p_writeev.type = EV_WRITE;
+ pwin->p_readev.data = pwin->p_writeev.data = (char *)w;
+ pwin->p_readev.handler = pseu_readev_fn;
+ pwin->p_writeev.handler = pseu_writeev_fn;
+ pwin->p_writeev.condpos = &pwin->p_inlen;
+ evenq(&pwin->p_readev);
+ evenq(&pwin->p_writeev);
+ pwin->p_pid = ForkWindow(w, av, t);
if ((r = pwin->p_pid) < 0)
FreePseudowin(w);
return r;
@@ -920,10 +1490,13 @@ struct win *w;
ASSERT(pwin);
if (fcntl(w->w_ptyfd, F_SETFL, FNBLOCK))
Msg(errno, "Warning: FreePseudowin: NBLOCK fcntl failed");
- (void) chmod(pwin->p_tty, 0666);
- (void) chown(pwin->p_tty, 0, 0);
+ /* should be able to use CloseDevice() here */
+ (void)chmod(pwin->p_tty, 0666);
+ (void)chown(pwin->p_tty, 0, 0);
if (pwin->p_ptyfd >= 0)
close(pwin->p_ptyfd);
+ evdeq(&pwin->p_readev);
+ evdeq(&pwin->p_writeev);
free((char *)pwin);
w->w_pwin = NULL;
}
@@ -931,194 +1504,346 @@ struct win *w;
#endif /* PSEUDOS */
-#ifdef MULTI
-
-/*
- * Clone routines. To be removed...
+#ifdef MULTIUSER
+/*
+ * returns 0, if the lock really has been released
*/
+int
+ReleaseAutoWritelock(dis, w)
+struct display *dis;
+struct win *w;
+{
+ debug2("ReleaseAutoWritelock: user %s, window %d\n",
+ dis->d_user->u_name, w->w_number);
-static int CloneTermcap __P((struct display *));
-extern char **environ;
+ /* release auto writelock when user has no other display here */
+ if (w->w_wlock == WLOCK_AUTO && w->w_wlockuser == dis->d_user)
+ {
+ struct display *d;
+ for (d = displays; d; d = d->d_next)
+ if (( d != dis) && (d->d_fore == w) && (d->d_user == dis->d_user))
+ break;
+ debug3("%s %s autolock on win %d\n",
+ dis->d_user->u_name, d ? "keeps" : "releases", w->w_number);
+ if (!d)
+ {
+ w->w_wlockuser = NULL;
+ return 0;
+ }
+ }
+ return 1;
+}
+/*
+ * returns 0, if the lock really could be obtained
+ */
int
-execclone(av)
-char **av;
+ObtainAutoWritelock(d, w)
+struct display *d;
+struct win *w;
{
- int f, sf;
- char specialbuf[6];
- struct display *old = display;
- char **avp, *namep;
+ if ((w->w_wlock == WLOCK_AUTO) &&
+ !AclCheckPermWin(d->d_user, ACL_WRITE, w) &&
+ !w->w_wlockuser)
+ {
+ debug2("%s obtained auto writelock for exported window %d\n",
+ d->d_user->u_name, w->w_number);
+ w->w_wlockuser = d->d_user;
+ return 0;
+ }
+ return 1;
+}
- sf = OpenPTY(&namep);
- if (sf == -1)
+#endif /* MULTIUSER */
+
+
+
+/********************************************************************/
+
+#ifdef COPY_PASTE
+static void
+paste_slowev_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ struct paster *pa = (struct paster *)data;
+ struct win *p;
+
+ int l = 1;
+ flayer = pa->pa_pastelayer;
+ if (!flayer)
+ pa->pa_pastelen = 0;
+ if (!pa->pa_pastelen)
+ return;
+ p = Layer2Window(flayer);
+ DoProcess(p, &pa->pa_pasteptr, &l, pa);
+ pa->pa_pastelen -= 1 - l;
+ if (pa->pa_pastelen > 0)
{
- Msg(0, "No more PTYs.");
- return -1;
+ SetTimeout(&pa->pa_slowev, p->w_slowpaste);
+ evenq(&pa->pa_slowev);
}
-#ifdef _IBMR2
- close(aixhack);
- aixhack = -1;
+}
#endif
- f = open(namep, O_RDWR);
- if (f == -1)
+
+
+static int
+muchpending(p, ev)
+struct win *p;
+struct event *ev;
+{
+ struct canvas *cv;
+ for (cv = p->w_layer.l_cvlist; cv; cv = cv->c_lnext)
{
- close(sf);
- Msg(errno, "Cannot open slave");
- return -1;
+ display = cv->c_display;
+ if (D_status == STATUS_ON_WIN && !D_status_bell)
+ {
+ /* wait 'til status is gone */
+ debug("BLOCKING because of status\n");
+ ev->condpos = &const_one;
+ ev->condneg = &D_status;
+ return 1;
+ }
+ if (D_obufp - D_obuf > D_obufmax)
+ {
+ debug("BLOCKING because of full obuf\n");
+ ev->condpos = &D_obuffree;
+ ev->condneg = &D_obuflenmax;
+ return 1;
+ }
}
- brktty(f);
- signal(SIGHUP, SIG_IGN); /* No hangups, please */
- if (MakeDisplay(D_username, namep, D_termname, f, -1, &D_OldMode) == 0)
+ return 0;
+}
+
+static void
+win_readev_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ struct win *p = (struct win *)data;
+ char buf[IOSIZE], *bp;
+ int size, len;
+#ifdef PSEUDOS
+ int wtop;
+#endif
+
+ bp = buf;
+ size = IOSIZE;
+
+#ifdef PSEUDOS
+ wtop = p->w_pwin && W_WTOP(p);
+ if (wtop)
{
- display = old;
- Msg(0, "Could not make display.");
- close(f);
- close(sf);
- return -1;
+ ASSERT(sizeof(p->w_pwin->p_inbuf) == IOSIZE);
+ size = IOSIZE - p->w_pwin->p_inlen;
+ if (size <= 0)
+ {
+ ev->condpos = &const_IOSIZE;
+ ev->condneg = &p->w_pwin->p_inlen;
+ return;
+ }
}
- if (CloneTermcap(old))
+#endif
+ if (p->w_layer.l_cvlist && muchpending(p, ev))
+ return;
+ if (p->w_blocked)
{
- FreeDisplay();
- display = old;
- close(sf);
- return -1;
+ ev->condpos = &const_one;
+ ev->condneg = &p->w_blocked;
+ return;
}
+ if (ev->condpos)
+ ev->condpos = ev->condneg = 0;
- SetMode(&D_OldMode, &D_NewMode);
- SetTTY(f, &D_NewMode);
+ if ((len = p->w_outlen))
+ {
+ p->w_outlen = 0;
+ WriteString(p, p->w_outbuf, len);
+ return;
+ }
- fflush(stdout);
- fflush(stderr);
- switch (fork())
+ debug1("going to read from window fd %d\n", ev->fd);
+ if ((len = read(ev->fd, buf, size)) <= 0)
{
- case -1:
- FreeDisplay();
- display = old;
- Msg(errno, "fork");
- close(sf);
- return -1;
- case 0:
- D_usertty[0] = 0; /* for SendErrorMsg */
- displays = 0; /* beware of Panic() */
- if (setuid(real_uid) || setgid(real_gid))
- {
- SendErrorMsg("Setuid/gid: %s", strerror(errno));
- _exit(1);
- }
- eff_uid = real_uid;
- eff_gid = real_gid;
- closeallfiles(sf);
- close(1);
- dup(sf);
- close(sf);
-#ifdef DEBUG
+ if (errno == EINTR || errno == EAGAIN)
+ return;
+#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
+ if (errno == EWOULDBLOCK)
+ return;
+#endif
+ debug2("Window %d: read error (errno %d) - killing window\n", p->w_number, len ? errno : 0);
+ WindowDied(p);
+ return;
+ }
+ debug1(" -> %d bytes\n", len);
+#ifdef TIOCPKT
+ if (p->w_type == W_TYPE_PTY)
+ {
+ if (buf[0])
{
- char buf[256];
-
- sprintf(buf, "%s/screen.child", DEBUGDIR);
- if ((dfp = fopen(buf, "a")) == 0)
- dfp = stderr;
- else
- (void) chmod(buf, 0666);
+ debug1("PAKET %x\n", buf[0]);
+ if (buf[0] & TIOCPKT_NOSTOP)
+ NewAutoFlow(p, 0);
+ if (buf[0] & TIOCPKT_DOSTOP)
+ NewAutoFlow(p, 1);
}
- debug1("=== Clone: pid %d\n", (int)getpid());
+ bp++;
+ len--;
+ }
#endif
- for (avp = av; *avp; avp++)
- {
- if (strcmp(*avp, "%p") == 0)
- *avp = namep;
- if (strcmp(*avp, "%X") == 0)
- *avp = specialbuf;
- }
- strcpy(specialbuf, "-SXX1");
- namep += strlen(namep);
- specialbuf[3] = *--namep;
- specialbuf[2] = *--namep;
-#ifdef DEBUG
- debug("Calling:");
- for (avp = av; *avp; avp++)
- debug1(" %s", *avp);
- debug("\n");
+#ifdef BUILTIN_TELNET
+ if (p->w_type == W_TYPE_TELNET)
+ len = TelIn(p, bp, len, buf + sizeof(buf) - (bp + len));
#endif
- execvpe(*av, av, environ);
- SendErrorMsg("Cannot exec '%s': %s", *av, strerror(errno));
- _exit(1);
- default:
- break;
+ if (len == 0)
+ return;
+#ifdef PSEUDOS
+ if (wtop)
+ {
+ bcopy(bp, p->w_pwin->p_inbuf + p->w_pwin->p_inlen, len);
+ p->w_pwin->p_inlen += len;
}
- close(sf);
- InitTerm(0);
- Activate(0);
- if (D_fore == 0)
- ShowWindows();
- return 0;
+#endif
+ WriteString(p, bp, len);
+ return;
}
-extern struct term term[]; /* terminal capabilities */
-static int
-CloneTermcap(old)
-struct display *old;
+static void
+win_writeev_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ struct win *p = (struct win *)data;
+ int len;
+ if (p->w_inlen)
+ {
+ debug2("writing %d bytes to win %d\n", p->w_inlen, p->w_number);
+ if ((len = write(ev->fd, p->w_inbuf, p->w_inlen)) <= 0)
+ len = p->w_inlen; /* dead window */
+ if ((p->w_inlen -= len))
+ bcopy(p->w_inbuf + len, p->w_inbuf, p->w_inlen);
+ }
+#ifdef COPY_PASTE
+ if (p->w_paster.pa_pastelen && !p->w_slowpaste)
+ {
+ struct paster *pa = &p->w_paster;
+ flayer = pa->pa_pastelayer;
+ if (flayer)
+ DoProcess(p, &pa->pa_pasteptr, &pa->pa_pastelen, pa);
+ }
+#endif
+ return;
+}
+
+
+
+#ifdef PSEUDOS
+
+static void
+pseu_readev_fn(ev, data)
+struct event *ev;
+char *data;
{
- char *tp;
- int i, l;
+ struct win *p = (struct win *)data;
+ char buf[IOSIZE];
+ int size, ptow, len;
+
+ size = IOSIZE;
- l = 0;
- for (i = 0; i < T_N; i++)
- if (term[i].type == T_STR && old->d_tcs[i].str)
- l += strlen(old->d_tcs[i].str) + 1;
- if ((D_tentry = (char *)malloc(l)) == 0)
+ ptow = W_PTOW(p);
+ if (ptow)
{
- Msg(0, strnomem);
- return -1;
+ ASSERT(sizeof(p->w_inbuf) == IOSIZE);
+ size = IOSIZE - p->w_inlen;
+ if (size <= 0)
+ {
+ ev->condpos = &const_IOSIZE;
+ ev->condneg = &p->w_inlen;
+ return;
+ }
+ }
+ if (p->w_layer.l_cvlist && muchpending(p, ev))
+ return;
+ if (p->w_blocked)
+ {
+ ev->condpos = &const_one;
+ ev->condneg = &p->w_blocked;
+ return;
}
+ if (ev->condpos)
+ ev->condpos = ev->condneg = 0;
- tp = D_tentry;
- for (i = 0; i < T_N; i++)
+ if ((len = p->w_outlen))
{
- switch(term[i].type)
- {
- case T_FLG:
- D_tcs[i].flg = old->d_tcs[i].flg;
- break;
- case T_NUM:
- D_tcs[i].num = old->d_tcs[i].num;
- break;
- case T_STR:
- D_tcs[i].str = old->d_tcs[i].str;
- if (D_tcs[i].str)
- {
- strcpy(tp, D_tcs[i].str);
- D_tcs[i].str = tp;
- tp += strlen(tp) + 1;
- }
- break;
- default:
- Panic(0, "Illegal tc type in entry #%d", i);
- }
- }
- CheckScreenSize(0);
- for (i = 0; i < NATTR; i++)
- D_attrtab[i] = old->d_attrtab[i];
- for (i = 0; i < 256; i++)
- D_c0_tab[i] = old->d_c0_tab[i];
- D_UPcost = old->d_UPcost;
- D_DOcost = old->d_DOcost;
- D_NLcost = old->d_NLcost;
- D_LEcost = old->d_LEcost;
- D_NDcost = old->d_NDcost;
- D_CRcost = old->d_CRcost;
- D_IMcost = old->d_IMcost;
- D_EIcost = old->d_EIcost;
-#ifdef AUTO_NUKE
- D_auto_nuke = old->d_auto_nuke;
+ p->w_outlen = 0;
+ WriteString(p, p->w_outbuf, len);
+ return;
+ }
+
+ if ((len = read(ev->fd, buf, size)) <= 0)
+ {
+ if (errno == EINTR || errno == EAGAIN)
+ return;
+#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
+ if (errno == EWOULDBLOCK)
+ return;
#endif
- if (D_CXC)
- CreateTransTable(D_CXC);
- D_tcinited = 1;
- return 0;
+ debug2("Window %d: pseudowin read error (errno %d) -- removing pseudowin\n", p->w_number, len ? errno : 0);
+ FreePseudowin(p);
+ return;
+ }
+ /* no packet mode on pseudos! */
+ if (ptow)
+ {
+ bcopy(buf, p->w_inbuf + p->w_inlen, len);
+ p->w_inlen += len;
+ }
+ WriteString(p, buf, len);
+ return;
}
-#endif
+static void
+pseu_writeev_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ struct win *p = (struct win *)data;
+ struct pseudowin *pw = p->w_pwin;
+ int len;
+
+ ASSERT(pw);
+ if (pw->p_inlen == 0)
+ return;
+ if ((len = write(ev->fd, pw->p_inbuf, pw->p_inlen)) <= 0)
+ len = pw->p_inlen; /* dead pseudo */
+ if ((p->w_pwin->p_inlen -= len))
+ bcopy(p->w_pwin->p_inbuf + len, p->w_pwin->p_inbuf, p->w_pwin->p_inlen);
+}
+
+
+#endif /* PSEUDOS */
+static void
+win_silenceev_fn(ev, data)
+struct event *ev;
+char *data;
+{
+ struct win *p = (struct win *)data;
+ struct canvas *cv;
+ debug1("FOUND silence win %d\n", p->w_number);
+ for (display = displays; display; display = display->d_next)
+ {
+ for (cv = D_cvlist; cv; cv = cv->c_next)
+ if (cv->c_layer->l_bottom == &p->w_layer)
+ break;
+ if (cv)
+ continue; /* user already sees window */
+#ifdef MULTIUSER
+ if (!(ACLBYTE(p->w_lio_notify, D_user->u_id) & ACLBIT(D_user->u_id)))
+ continue;
+#endif
+ Msg(0, "Window %d: silence for %d seconds", p->w_number, p->w_silencewait);
+ }
+}
diff --git a/window.h b/window.h
index 4a14eeb..600b19d 100644
--- a/window.h
+++ b/window.h
@@ -22,11 +22,8 @@
* $Id: window.h,v 1.11 1994/05/31 12:33:27 mlschroe Exp $ FAU
*/
-#ifndef MAXWIN
-# define MAXWIN 10
-#endif
-
+/* keep this in sync with the initialisations in window.c */
struct NewWindow
{
int StartAt; /* where to start the search for the slot */
@@ -40,7 +37,10 @@ struct NewWindow
int histheight;
int monitor;
int wlock; /* default writelock setting */
+ int silence;
int wrap;
+ int Lflag; /* logging */
+ int slow; /* inter character milliseconds */
int c1;
int gr;
int kanji;
@@ -48,18 +48,19 @@ struct NewWindow
char *charset;
};
-
#ifdef PSEUDOS
struct pseudowin
{
- int fdpat;
- int p_pid;
- int p_ptyfd;
- char p_cmd[MAXSTR];
- char p_tty[MAXSTR];
- char p_inbuf[IOSIZE]; /* buffered writing to p_ptyfd */
- int p_inlen;
+ int p_fdpat;
+ int p_pid;
+ int p_ptyfd;
+ struct event p_readev;
+ struct event p_writeev;
+ char p_cmd[MAXSTR];
+ char p_tty[MAXSTR];
+ char p_inbuf[IOSIZE]; /* buffered writing to p_ptyfd */
+ int p_inlen;
};
/* bits for fdpat: */
@@ -73,87 +74,112 @@ struct pseudowin
/* The screen process ...)
* ... wants to write to pseudo */
-#define W_WP(w) ((w)->w_pwin && ((w)->w_pwin->fdpat & F_PFRONT))
+#define W_WP(w) ((w)->w_pwin && ((w)->w_pwin->p_fdpat & F_PFRONT))
/* ... wants to write to window: user writes to window
* or stdout/stderr of pseudo are duplicated to window */
#define W_WW(w) (!((w)->w_pwin) || \
-(((w)->w_pwin->fdpat & F_PMASK) == F_PBACK) || \
-((((w)->w_pwin->fdpat >> F_PSHIFT) & F_PMASK) == F_PBOTH) || \
-((((w)->w_pwin->fdpat >> (F_PSHIFT * 2)) & F_PMASK) == F_PBOTH))
+(((w)->w_pwin->p_fdpat & F_PMASK) == F_PBACK) || \
+((((w)->w_pwin->p_fdpat >> F_PSHIFT) & F_PMASK) == F_PBOTH) || \
+((((w)->w_pwin->p_fdpat >> (F_PSHIFT * 2)) & F_PMASK) == F_PBOTH))
/* ... wants to read from pseudowin */
-#define W_RP(w) ((w)->w_pwin && ((w)->w_pwin->fdpat & \
+#define W_RP(w) ((w)->w_pwin && ((w)->w_pwin->p_fdpat & \
((F_PFRONT << (F_PSHIFT * 2)) | (F_PFRONT << F_PSHIFT)) ))
/* ... wants to read from window */
-#define W_RW(w) (!((w)->w_pwin) || ((w)->w_pwin->fdpat & F_PFRONT))
+#define W_RW(w) (!((w)->w_pwin) || ((w)->w_pwin->p_fdpat & F_PFRONT))
/* user input is written to pseudo */
-#define W_UWP(w) ((w)->w_pwin && ((w)->w_pwin->fdpat & F_UWP))
+#define W_UWP(w) ((w)->w_pwin && ((w)->w_pwin->p_fdpat & F_UWP))
/* pseudo output has to be stuffed in window */
#define W_PTOW(w) (\
-((w)->w_pwin->fdpat & F_PMASK << F_PSHIFT) == F_PBOTH << F_PSHIFT || \
-((w)->w_pwin->fdpat & F_PMASK << F_PSHIFT * 2) == F_PBOTH << F_PSHIFT * 2 )
+((w)->w_pwin->p_fdpat & F_PMASK << F_PSHIFT) == F_PBOTH << F_PSHIFT || \
+((w)->w_pwin->p_fdpat & F_PMASK << F_PSHIFT * 2) == F_PBOTH << F_PSHIFT * 2 )
/* window output has to be stuffed in pseudo */
-#define W_WTOP(w) (((w)->w_pwin->fdpat & F_PMASK) == F_PBOTH)
+#define W_WTOP(w) (((w)->w_pwin->p_fdpat & F_PMASK) == F_PBOTH)
#endif /* PSEUDOS */
+/* definitions for wlocktype */
+#define WLOCK_OFF 0 /* all in w_userbits can write */
+#define WLOCK_AUTO 1 /* who selects first, can write */
+#define WLOCK_ON 2 /* user writes even if deselected */
+#ifdef COPY_PASTE
+struct paster
+{
+ char *pa_pastebuf; /* this gets pasted in the window */
+ char *pa_pasteptr; /* pointer in pastebuf */
+ int pa_pastelen; /* bytes left to paste */
+ struct layer *pa_pastelayer; /* layer to paste into */
+ struct event pa_slowev; /* slowpaste event */
+};
+#else
+struct paster;
+#endif
struct win
{
struct win *w_next; /* next window */
+ int w_type; /* type of window */
+ void *w_data;
+ struct layer w_layer; /* our layer */
+ struct layer *w_savelayer; /* the layer to keep */
+ int w_blocked; /* block input */
#ifdef PSEUDOS
struct pseudowin *w_pwin; /* ptr to pseudo */
#endif
- struct display *w_display; /* pointer to our display */
struct display *w_pdisplay; /* display for printer relay */
int w_number; /* window number */
- int w_active; /* is window fore and has no layer? */
- struct layer *w_lay; /* the layer of the window */
- struct layer w_winlay; /* the layer of the window */
- int w_pid; /* process at the other end of ptyfd */
- char *w_cmdargs[MAXARGS]; /* command line argument vector */
+ struct event w_readev;
+ struct event w_writeev;
+ struct event w_silenceev; /* silence event */
int w_ptyfd; /* fd of the master pty */
- int w_aflag; /* (used for DUMP_TERMCAP) */
char w_inbuf[IOSIZE];
int w_inlen;
char w_outbuf[IOSIZE];
int w_outlen;
+ int w_aflag; /* (-a option) */
char *w_title; /* name of the window */
char *w_akachange; /* autoaka hack */
- int w_autoaka; /* autoaka hack */
char w_akabuf[MAXSTR]; /* aka buffer */
- char w_tty[MAXSTR];
- struct tty_attr w_t;
+ int w_autoaka; /* autoaka hack */
int w_intermediate; /* char used while parsing ESC-seq */
- int w_args[MAXARGS];
+ int w_args[MAXARGS]; /* emulator args */
int w_NumArgs;
- slot_t w_slot; /* utmp slot */
-#if defined (UTMPOK)
- struct utmp w_savut; /* utmp entry of this window */
+
+#ifdef MULTIUSER
+ int w_wlock; /* WLOCK_AUTO, WLOCK_OFF, WLOCK_ON */
+ struct user *w_wlockuser; /* NULL when unlocked or user who writes */
+ AclBits w_userbits[ACL_BITS_PER_WIN];
+ AclBits w_lio_notify; /* whom to tell when lastio+seconds < time() */
+ AclBits w_mon_notify; /* whom to tell monitor statis */
#endif
+
+ enum state_t w_state; /* parser state */
+ enum string_t w_StringType;
struct mline *w_mlines;
- int w_x, w_y; /* Cursor position */
- int w_width, w_height; /* window size */
struct mchar w_rend; /* current rendition */
+#ifdef FONT
char w_FontL; /* character font GL */
char w_FontR; /* character font GR */
int w_Charset; /* charset number GL */
int w_CharsetR; /* charset number GR */
int w_charsets[4]; /* Font = charsets[Charset] */
+#endif
int w_ss;
int w_saved;
int w_Saved_x, w_Saved_y;
struct mchar w_SavedRend;
+#ifdef FONT
int w_SavedCharset;
int w_SavedCharsetR;
int w_SavedCharsets[4];
+#endif
int w_top, w_bot; /* scrollregion */
int w_wrap; /* autowrap */
int w_origin; /* origin mode */
@@ -165,18 +191,6 @@ struct win
int w_curvvis; /* cursor very visible */
int w_autolf; /* automatic linefeed */
char *w_hstatus; /* hardstatus line */
-#ifdef COPY_PASTE
- char *w_pastebuf; /* this gets pasted in the window */
- char *w_pasteptr; /* pointer in pastebuf */
- int w_pastelen; /* bytes left to paste */
- int w_histheight; /* all histbases are malloced with width * histheight */
- int w_histidx; /* 0 <= histidx < histheight; where we insert lines */
- struct mline *w_hlines; /* history buffer */
-#else
- int w_histheight; /* always 0 */
-#endif
- enum state_t w_state; /* parser state */
- enum string_t w_StringType;
int w_gr; /* enable GR flag */
int w_c1; /* enable C1 flag */
#ifdef KANJI
@@ -188,36 +202,74 @@ struct win
char *w_tabs; /* line with tabs */
int w_bell; /* bell status of this window */
int w_flow; /* flow flags */
- FILE *w_logfp; /* log to file */
+ struct logfile *w_log; /* log to file */
+ int w_logsilence; /* silence in secs */
int w_monitor; /* monitor status */
- struct lastio_s
- {
- time_t lastio; /* timestamp of last filedescriptor activity */
- int seconds; /* tell us when lastio + seconds < time() */
- } w_tstamp;
+ int w_silencewait; /* wait for silencewait secs */
+ int w_silence; /* silence status (Lloyd Zusman) */
+ char w_vbwait;
char w_norefresh; /* dont redisplay when switching to that win */
- char w_wlock; /* WLOCK_AUTO, WLOCK_OFF, WLOCK_ON */
- struct user *w_wlockuser; /* NULL when unlocked or user who writes */
-#ifdef MULTIUSER
- AclBits w_userbits[ACL_BITS_PER_WIN];
- AclBits w_lio_notify; /* whom to tell when lastio+seconds < time() */
- AclBits w_mon_notify; /* whom to tell monitor statis */
+#ifdef HAVE_BRAILLE
+ int w_bd_x, w_bd_y; /* Braille cursor position */
+#endif
+
+#ifdef COPY_PASTE
+ int w_slowpaste; /* do careful writes to the window */
+ int w_histheight; /* all histbases are malloced with width * histheight */
+ int w_histidx; /* 0 <= histidx < histheight; where we insert lines */
+ struct mline *w_hlines; /* history buffer */
+ struct paster w_paster; /* paste info */
+#else
+ int w_histheight; /* always 0 */
+#endif
+ int w_pid; /* process at the other end of ptyfd */
+
+ char *w_cmdargs[MAXARGS]; /* command line argument vector */
+ char *w_dir; /* directory for chdir */
+ char *w_term; /* TERM to be set instead of "screen" */
+
+ slot_t w_slot; /* utmp slot */
+#if defined (UTMPOK)
+ struct utmp w_savut; /* utmp entry of this window */
+#endif
+
+ char w_tty[MAXSTR];
+
+#ifdef BUILTIN_TELNET
+ struct sockaddr_in w_telsa;
+ char w_telbuf[IOSIZE];
+ int w_telbufl;
+ char w_telmopts[256];
+ char w_telropts[256];
+ int w_telstate;
+ char w_telsubbuf[128];
+ int w_telsubidx;
+ struct event w_telconnev;
#endif
};
-/* definitions for wlocktype */
-#define WLOCK_OFF 0 /* all who are in w_userbits can write */
-#define WLOCK_AUTO 1 /* who selects first, can write */
-#define WLOCK_ON 2 /* w_wlockuser writes even if deselected */
+
+#define w_width w_layer.l_width
+#define w_height w_layer.l_height
+#define w_x w_layer.l_x
+#define w_y w_layer.l_y
+
+/* definitions for w_type */
+#define W_TYPE_PTY 0
+#define W_TYPE_PLAIN 1
+#define W_TYPE_TELNET 2
+
/*
* Definitions for flow
- * 000 -(-)
- * 001 +(-)
- * 010 -(+)
- * 011 +(+)
- * 100 -(a)
- * 111 +(a)
+ * 000 -(-) flow off, auto would be off
+ * 001 +(-) flow on , auto would be off
+ * 010 -(+) flow off, auto would be on
+ * 011 +(+) flow on , auto would be on
+ * 100 - flow auto, currently off
+ * 111 + flow auto, currently on
+ * Application controls auto_flow via TIOCPKT, if available,
+ * else via application keypad mode.
*/
#define FLOW_NOW (1<<0)
#define FLOW_AUTO (1<<1)
@@ -233,3 +285,5 @@ struct win
#define WIN(y) ((y < fore->w_histheight) ? \
&fore->w_hlines[(fore->w_histidx + y) % fore->w_histheight] \
: &fore->w_mlines[y - fore->w_histheight])
+
+#define Layer2Window(l) ((struct win *)(l)->l_bottom->l_data)