Newsgroups: comp.sources.unix From: screen@uni-erlangen.de (Juergen & Michael) Subject: v27i015: screen-3.5.1 - full-screen window manager/multiplexor, Part02/10 References: <1.744844979.5722@gw.home.vix.com> Sender: unix-sources-moderator@gw.home.vix.com Approved: vixie@gw.home.vix.com Submitted-By: screen@uni-erlangen.de (Juergen & Michael) Posting-Number: Volume 27, Issue 15 Archive-Name: screen-3.5.1/part02 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'ChangeLog' <<'END_OF_FILE' X31.7.93 -- 3.5.1 X================ X X* writelock, number, paste with arg, at, zombie and wall commands added. X X* Access Control Lists and more multi-user support added. X X* select and setenv commands enhanced. X X* socket.c: motorola bugfix. X X* configure.in: --srcdir support. X X* configure.in: recognize alpha and SUNOS3 correctly. X X* doc/screen.texinfo: Documentation by Jason Merrill. X X13.05.93 -- 3.3.3 X================= X X* defautonuke, silence commands added. X X* exec command added. X X* hardcopydir, logdir commands added. X X* Made a superb configure script. X X* BROKEN_PIPE, SOCK_NOT_IN_FS added for braindamaged systems. X X* multi display, multi user support. X X* process command. CS, CE switch cursorkeycap in application mode. X X* lockprg pow_detaches on SIGHUP X X* ins_reg copy_reg commands. X X* new screenrc syntax. X X* split up screen.c and ansi.c X X21.10.92 -- 3.2.9 X================ X X* ChangeLog: replaces CHANGES and is in GNUish format. X X* Makefile (CFLAGS, M_CFLAGS, LIBS, OPTIONS): moved user config here, X merged all Makefiles, GNUified X X* socket.c (FindSocket): ignoring bad files in $SCREENDIR X X* config/config.linux: ported. X X* utmp.c, exec.c, loadav.c: split apart from screen.c/fileio.c X X15.07.92 -- 3.2.8 X================= X X* ansi.c (WriteString): automatic character set switching for 8bit support X X3.2.3-3.2.7 X=========== X X* concept changes: Display structure, Multi attacher X X... X X3.2.2 X===== X X* screen.c (main): -m option, "_M_ake always new session", ignore $STY X X* screen.c (main): -Ssessionname X* fileio.c (RcLine): ^A:sessionname give your session a nicer name. X X* screen.c (main): supporting detached startup via screen -d -m -Ssockname X X* fileio.c (stripdev): moved, could not compile X X* overlay.h: "stackable overlay concept" X X* search.c: vi-like / and ? search AND emacs-like ^S and ^R incremental search X in scrollback X X* mark.c: I meant BSDI not BSD X X* concept change: struct display and struct newwin introduced. X X* screen.c (main): -v option prints version. X X* screen.c (MakeWindow): ^A:screen /dev/ttya opens a character device X instead of forking ShellProg with a pty pair. X X3.2.0 X===== X XUltrix port X XIrix 3.3 SGI port X Xshadow password suite supported X Xdata loss on stdin overflow fixed X X"refresh off" keyword added. X X3.1.1 X------ X XScreen is now under the GNU copyleft license. See file COPYING. X Xcommand line option -A. $LINES, $COLUMNS improved. X XC-A : vbellwait X XXENIX support (Ronald Khoo) X XSYSV has uname() instead of gethostname(). X Xhpux has setresuid. X XClearScreen now saves image to scrollback buffer. X Xmips has setenv. X Xnumerous bugfixes. X X3.1 finally released version. X============================= X X3.0.99: last minute changes: X---------------------------- X XMIPS support (J{rvinen Markku) X XSVR4 support (Marc Boucher) X Xsecopen() secfopen() calls replace stat/access/open. XC-a : echo improved. X'register int' X XChanges up to Screen 3.0 Patchlevel 7 X===================================== X XBetter terminfo support: Screen now checks if a termcap/info Xentry which the name "screen.$TERM" does exist. Look in the X"VIRTUAL TERMINAL" section of the manual for more details. X XMany security improvements. X XScrollRegion() bug fixed which caused slow scrolling if AL Xor DL was used. X XPyramid and Ultrix support added. (Tim and Larry) X XENVIRONMENT support. X /local/etc/screenrc checks for $SYSSCREENRC X $HOME/.screenrc checks for $ISCREENRC and $SCREENRC X /local/screens checks for $ISCREENDIR and $SCREENDIR X .screenrc understands ${VAR} and $VAR . X Xscreen 3.0 Patchlevel 6 X======================= X X.screenrc: X screen now only opens the windows you explicitly ask for. if you X specify none, you still get one window, of course. X Xscreen 3.0. Patchlevel 5 X======================== X XAnsi prototyping by Christos. X Xcopy mode: CTRL-U / CTRL-D exchanged. code cleanup. X Xchanges to screen 3.0 patchlevel 4 X================================== X Xmarkkeys "string" X allows to rebind the keys used in copy/history mode. X string is made up of pairs "=" which are separated X by a colon. Oldchar and newchar are either single ascii characters, X or the two character sequence ^x, where x is an ascii character, or X a 3 digit octal value prepended with '\'. the string "\040=.:^M=q" X rebinds '.' to set marks, and the return rey will abort copy mode. X Xset scrollback 100 X resizes the scrollback history buffer to 100 lines. a default of 50 X is installed. X XA Howard Chu like scrollback history is installed. Many vi-like keys X are added to the copy mode. The '?' key reports on cursor position. X Xscreen 3.0 Patchlevel 3 X======================= X XWriteString fixed, it did kill the display variable. X XYet another LP bugfix. X Xnon vt100 semi-graphics character support. X Xwaynes patch fixed X Xscreen 3.0 Patchlevel 2 X======================= X Xwayne patches cursor motion outside scrollregions. X X.screenrc X monitor on|off X Xchanges in Screen 3.0 Patchlevel 1 X================================== X Xscreen -wipe X X^A : set vbell_msg "Wuff Wuff" X XThousand enhancements: help resizible, copy'n'paste in main X socket loop, and no more '\0' hackin'. :WS=\E8;%d;%dt: X Xscreen can now resize windows under sunview. X X^A : set crlf on|off X effects markroutine join. X Xscreen learned about sized windows under X X Xscreen -ls (-d) -q X quiet option. We count the number of detached (attached) sessions and set X a return value of 10+n. The -q option inhibits all startup X warnings/messages. i.e. screen -R -q may return with code 12 or higher X or start a new/old session. X Xpow_detach_msg "text string" X new command, allows messages, terminal reset, etc. on logout caused X by pow_detach. X X^A : learned a new keyword "set": X commands like "login on" , "vbell off", ... affect the default for X windows to be created. But commands like "set login off" affect X the actual setting of this window. and not the default. X such commands may be bound to keys. example: X bind 'O' set login off X is valid in your .screenrc as well as typed at the ':' prompt. X a bonus is ":set all" which is synonym to ":help". X At the Colon prompt also KeyNames can be entered, alothough that makes X not always sense. X X^A x uses a builtin lockprg, if X a) we don't find our lockprg, or X b) user supplies us with the environmet variable LOCKPRG set to "builtin" X the builtin locks until your login password is typed. on systems using X "shadow password files" you are prompted for a password. X Xmarkroutine can append joined. X Xscreen removes the "controlling tty" from utmp while ptys are attached. X Xmarkroutine performs CR+NL when '\n' is pressed X Xscreen may die quietly, when no TERMCAP entry for "screen" is Xfound, and screen is run under X-windows X X_SEQUENT_ marks sequent386_ptx X Xscreen runs now under SunOS4.1.1 (we need setsid()!). X Xbug in SetForeWindow fixed. X Xrare markroutine bug fixed. X Xwe dont open every file the attacher tells us. X Xwe have now our wonderful "Wuff, Wuff" visual_bell X Xwe have now the interprocess-communication-buffer. secure version. X X'^A =' removes the interprocess-communication-buffer. X Xmarkroutine as in 2.1 X Xmarkroutine: 'a' toggles append mode, X '>' like ' ', but immediately WriteFile(DUMP_EXCHANGE) then. X 'A' like ' ', but first switch to append mode. X X.screenrc understands "screen 2:faui09 rlogin faui09 -l jnweiger" X and "password none" X and "vbell [on|off]" X X'^A :' allows .screenrc commands "online". X Xscreen now receives new $TERM from attacher, when it is reattached X XMakeClientSocket() fifo version does now test for access. X X.screenrc learns "hardstatus {on|off}" X Xtermcap's VB is used for vbell if available. X XAttach() code rewritten: X screen now lists socket directory, if it does not find a suitable socket X screen -d [host.tty] detaches a running screen. X Xscreen -[ls|list] X list all sockets that we find in our sockdir X Xwhen the socket has been removed, send a SIGCHLD to the poor SCREEN Xprocess and it will try to recover. then try a 'screen -r' again. Xall the socket stuff lives now in an extra file. X XMajor changes in version 2.4: X============================= X X* Test version that presents the erlangen extensions from 2.0 in a 2.3 X screen. X X* window resize support X X* screen locking C-a x X X* support for SYSV X X* password protection X X* copy & paste across screens X X* remote detach and power detach X XMajor changes in version 2.3: X X* Terminal emulation has been significantly enhanced and bugfixed. X X* We now fully update the last character on the screen for true auto- X margin terminals, though there may be some delay before the character X can be safely added to the screen. If your terminal has character X insert it will be used to shorten the delay. X X* Added the "termcap" .screenrc command to tweak your terminal's termcap X entry AND to customize the termcap generated for the virtual terminals. X See also the -L and -O command-line options, and the SCREENCAP environ- X ment variable. X X* Fixed screen's character handling when detached or suspended to NOT block X the child processes in their windows -- output continues to be processed X in the background. X X* Added a.k.a.s (window-name aliases) that allow you to customize the X window-information line, including being able to change the name on- X the-fly to reflect what's currently running in the window (see the X -k option, shellaka command, and ALSO KNOWN AS discussion in the doc). X X* Added the ability to log the output of a window to a file (see the X "C-a H" (log) command). X X* Flow-control can now be set for each window and switched interactively X (see the "flow" command, -f option, and FLOW CONTROL discussion). X X* Individual windows can be included or excluded from mention in the X /etc/utmp file (see the "login" command and -l option). X X* Added an activity monitor, which allows you to have a window watched for X the start of any output and alert you when it occurs (see the "C-a M" X (monitor) command). X X* Enhanced the information in the window-information line to keep track of X windows that have: logging turned on '(L)'; beeped in the background '!'; X became active while being monitored '@' (see the "C-a w" (windows) command). X X* Added an on-line help display that lists all the commands and their X key bindings (see the "C-a ?" (help) command). X X* Extended handling of the beep message (and also the new activity message) X to allow '~' to specify a literal beep (see the "beep" and "activity" X .screenrc commands). X X* You can now set the default action on receipt of a hangup signal: detach X or terminate (see the "autodetach" .screenrc command). X X* Routing of characters to their virtual terminals has been enhanced to X not drop characters nor (in rare circumstances) hang up screen. X X* The NFS compatibility has been enhanced. X XMajor changes in version 2.0a: X X* Screen allows you to `detach' the "screen" session from the physical X terminal and resume it at a later point in time (possibly on a X different terminal or in a different login session). X X To get an impression of this functionality do the following: X X - call "screen" and create a couple of windows X - type Control-A Control-D (screen terminates; you are back X in the shell) X - call "screen -r" to resume the detached screen X X* Screen supports multiple character sets and the ISO 2022 control X functions to designate and switch between character sets. X This allows you, for instance, to make use of the VT100 graphics X character set or national character sets. END_OF_FILE if test 11540 -ne `wc -c <'ChangeLog'`; then echo shar: \"'ChangeLog'\" unpacked with wrong size! fi # end of 'ChangeLog' fi if test -f 'Makefile.in' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile.in'\" else echo shar: Extracting \"'Makefile.in'\" \(10792 characters\) sed "s/^X//" >'Makefile.in' <<'END_OF_FILE' X# X# Makefile template for screen X# X# See machine dependant config.h for more configuration options. X# X Xsrcdir = @srcdir@ XVPATH = @srcdir@ X X# Where to install screen. X Xprefix = /usr/local Xexec_prefix = $(prefix) X Xbindir = $(exec_prefix)/bin Xmandir = $(prefix)/man X XVERSION = @VERSION@ X XETCSCREENRC = `sed < config.h -n -e '/define ETCSCREENRC/s/^.*"\([^"]*\)"/\1/p'` X XCC = @CC@ XCFLAGS = -O XLDFLAGS = XLIBS = @LIBS@ X XCPP_DEPEND=/lib/cpp -MM X XINSTALL = @INSTALL@ XINSTALL_PROGRAM = @INSTALL_PROGRAM@ XINSTALL_DATA = @INSTALL_DATA@ X XAWK = @AWK@ X X### Chose some debug configuration options: X# -DDEBUG X# Turn on really heavy debug output. This is written to X# /tmp/debug/screen.{front,back} Look at these files and quote X# questionable sections when sending bug-reports to the author. X# -DTMPTEST X# Change the socket directory to a location that does not interfere X# with the (suid-root) installed screen version. Use that in X# combination with -DDEBUG X# -DDUMPSHADOW X# With shadow-pw screen would never dump core. Use this option if you X# still want to have a core. Use only for debugging. X# -DFORKDEBUG X# Swap roles of father and son when forking the SCREEN process. X# Useful only for debugging. XOPTIONS= X#OPTIONS= -DDEBUG -DTMPTEST X X X###### X###### X###### The following lines should be obsolete because of the 'configure' script. X###### X###### X X X### If you choose to compile with the tried and true: X#CC= cc X#CFLAGS= -O X#CFLAGS= -g X### gcc specific CFLAGS: X#CC= gcc X# If your system include files are bad, don't use -Wall X#CFLAGS= -O6 -g #-Wall X#CFLAGS = -g -fstrength-reduce -fcombine-regs -finline-functions #-Wall X X### On some machines special CFLAGS are required: X#M_CFLAGS= X#M_CFLAGS= -Dapollo -A cpu,mathchip -A nansi # Apollo DN3000/4000/4500 X#M_CFLAGS= -DBSDI # bsd386 X#M_CFLAGS= -DISC -D_POSIX_SOURCE # isc X#M_CFLAGS= -systype bsd43 -DMIPS # mips X#M_CFLAGS= -fforce-mem -fforce-addr\ X# -fomit-frame-pointer -finline-functions -bsd # NeXT X#M_CFLAGS= -qlanglvl=ansi # RS6000/AIX X#M_CFLAGS= -qlanglvl=ansi -D_AIX32 # RS6000/AIX 3.2 X#M_CFLAGS= -ansi # sgi/IRIX 3.x ansi X#M_CFLAGS= -xansi # sgi/IRIX 4.x ext ansi X#M_CFLAGS= -YBSD # Ultrix 4.x X#M_CFLAGS= -DSVR4=1 # Bob Kline rvk@blink.att.com 80386 Unix SVR4.0 X#M_CFLAGS= -D_CX_UX # Ken Beal kbeal@amber.ssd.csd.harris.com Harris CX/UX X X### Choose one of the LIBS setting below: X#LIBS= -ltermcap -lc -lsocket -linet -lsec -lseq # Sequent/ptx X#LIBS= -ltermcap # SunOS, Linux, Apollo, X# gould_np1, NeXT, Ultrix X#LIBS= -ltermcap -lelf # SVR4 X#LIBS= -ltermlib -linet -lcposix # isc X#LIBS= -ltermcap -lmld # mips (nlist is in mld) X#LIBS= -ltermlib -lsun -lmld #-lc_s # sgi/IRIX X#LIBS= -lcurses # RS6000/AIX X#LIBS= -lcrypt_d -ltinfo # sco32 X#LIBS= -lcrypt_i -ltinfo # sco32 X#LIBS= -lcrypt -lsec # sco322 (msilano@sra.com) X#LIBS= -ltermcap -lcrypt.o -ldir -lx # SCO XENIX 2.3.4 X#LIBS= -ltermcap -lcrypt -ldir -l2.3 -lx # SCO UNIX XENIX cross dev. X#LIBS= -ltermcap -lelf -lcrypt -lsocket -lnet -lnsl # Bob Kline SVR4 X X###### X###### X###### end of obsolete lines X###### X###### X X XSHELL=/bin/sh X XCFILES= screen.c ansi.c fileio.c mark.c misc.c resize.c socket.c \ X search.c tty.c term.c window.c utmp.c loadav.c putenv.c help.c \ X termcap.c input.c attacher.c pty.c process.c display.c comm.c acl.c XOFILES= screen.o ansi.o fileio.o mark.o misc.o resize.o socket.o \ X search.o tty.o term.o window.o utmp.o loadav.o putenv.o help.o \ X termcap.o input.o attacher.o pty.o process.o display.o comm.o acl.o X Xall: screen X Xscreen: $(OFILES) X $(CC) $(LDFLAGS) -o $@ $(OFILES) $(LIBS) X X.c.o: X $(CC) -c -I. -I$(srcdir) $(M_CFLAGS) $(DEFS) $(OPTIONS) $(CFLAGS) $< X Xinstall_bin: screen X $(INSTALL_PROGRAM) screen $(bindir)/screen-$(VERSION) X -chown root $(bindir)/screen-$(VERSION) && chmod 4755 $(bindir)/screen-$(VERSION) X# This doesn't work if $(bindir)/screen is a symlink X -if [ -f $(bindir)/screen ] && [ ! -f $(bindir)/screen.old ]; then mv $(bindir)/screen $(bindir)/screen.old; fi X rm -f $(bindir)/screen X ln -s $(bindir)/screen-$(VERSION) $(bindir)/screen X Xinstall: install_bin X -$(INSTALL_DATA) $(srcdir)/etcscreenrc $(ETCSCREENRC) X -$(INSTALL_DATA) $(srcdir)/doc/screen.1 $(mandir)/man1/screen.1 X -tic ${srcdir}/terminfo/screeninfo.src X# Better do this by hand. E.g. under RCS... X# cat ${srcdir}/terminfo/screencap >> /etc/termcap X @echo termcap entry not installed. X Xinstalldirs: mkinstalldirs X# Path leading to ETCSCREENRC and Socketdirectory not checked. X $(srcdir)/mkinstalldirs $(bindir) $(mandir) X Xuninstall: X rm -f $(bindir)/screen-$(VERSION) X rm -f $(bindir)/screen X mv $(bindir)/screen.old $(bindir)/screen X rm -f $(ETCSCREENRC) X rm -f $(mandir)/man1/screen.1 X Xshadow: X mkdir shadow; X cd shadow; ln -s ../*.[ch] ../*.in ../*.sh ../configure ../doc ../terminfo . X rm -f shadow/term.h shadow/tty.c shadow/comm.h shadow/osdef.h X Xterm.h: term.c term.sh X AWK=$(AWK) srcdir=$(srcdir) . $(srcdir)/term.sh X Xtty.c: tty.sh X sh $(srcdir)/tty.sh tty.c X Xcomm.h: comm.c comm.sh config.h X AWK=$(AWK) CC="$(CC)" srcdir=${srcdir} . $(srcdir)/comm.sh X Xosdef.h: osdef.sh config.h osdef.h.in X CC="$(CC)" srcdir=${srcdir} . $(srcdir)/osdef.sh X Xdocs: X cd doc; $(MAKE) dvi info X Xdvi info: X cd doc; $(MAKE) $@ X Xmostlyclean: X rm -f $(OFILES) screen X Xclean celan: mostlyclean X rm -f tty.c term.h comm.h osdef.h X X# Delete all files from the current directory that are created by X# configuring or building the program. X# building of term.h/comm.h requires awk. Keep it in the distribution X# we keep config.h, as this file knows where 'make dist' finds the ETCSCREENRC. Xdistclean: mostlyclean X rm -f screen-$(VERSION).tar screen-$(VERSION).TZ X rm -f config.status Makefile X X# Delete everything from the current directory that can be X# reconstructed with this Makefile. Xrealclean: distclean X rm -f config.h X XTAGS: $(CFILES) X ctags $(CFILES) *.h X ctags -e $(CFILES) *.h X Xdist: screen-$(VERSION).tar.z X Xscreen-$(VERSION).tar: term.h comm.h tty.c X -rm -rf dist X mkdir dist X mkdir dist/screen-$(VERSION) X ln acl.h ansi.h display.h extern.h mark.h os.h overlay.h \ X patchlevel.h rcs.h screen.h window.h osdef.h.in \ X term.sh tty.sh comm.sh osdef.sh newsyntax \ X acl.c ansi.c attacher.c comm.c display.c window.c fileio.c help.c \ X input.c loadav.c mark.c misc.c process.c pty.c putenv.c \ X screen.c search.c socket.c term.c termcap.c utmp.c resize.c \ X ChangeLog COPYING INSTALL NEWS \ X dist/screen-$(VERSION) X ln configure.in configure dist/screen-$(VERSION) X sed -e 's@"/local/screens@"/tmp/screens@' -e 's@"/local@"/usr/local@g' < config.h.in > dist/screen-$(VERSION)/config.h.in X sed -e 's@[ ]/local@ /usr/local@g' -e 's/^CFLAGS = -g/CFLAGS = -O/' < Makefile.in > dist/screen-$(VERSION)/Makefile.in X ln term.h dist/screen-$(VERSION)/term.h.dist X ln comm.h dist/screen-$(VERSION)/comm.h.dist X ln tty.c dist/screen-$(VERSION)/tty.c.dist X ln README dist/screen-$(VERSION)/README X mkdir dist/screen-$(VERSION)/terminfo X cd terminfo; ln 8bits README checktc.c screen-sco.mail screencap \ X screeninfo.src test.txt tetris.c \ X ../dist/screen-$(VERSION)/terminfo X sed -e 's/^startup/#startup/' -e 's/^autodetach/#autodetach/' < $(ETCSCREENRC) > dist/screen-$(VERSION)/etcscreenrc X cp $(HOME)/.iscreenrc dist/screen-$(VERSION)/.iscreenrc X mkdir dist/screen-$(VERSION)/doc X ln doc/fdpat.ips dist/screen-$(VERSION)/doc/fdpat.ps X sed -e 's@/local/emacs@/usr/local@g' < doc/Makefile.in > dist/screen-$(VERSION)/doc/Makefile.in X cd doc; ln screen.1 screen.texinfo \ X ../dist/screen-$(VERSION)/doc X cd dist; tar chf ../screen-$(VERSION).tar screen-$(VERSION) X rm -rf dist X Xscreen-$(VERSION).tar.z: screen-$(VERSION).tar X gzip -f screen-$(VERSION).tar X X# Perform self-tests (if any). Xcheck: X Xlint: X lint -I. $(CFILES) X Xsaber: X #load $(CFLAGS) screen.c ansi.c $(LIBS) X Xmdepend: $(CFILES) term.h X @rm -f DEPEND ; \ X for i in ${CFILES} ; do \ X echo "$$i" ; \ X echo `echo "$$i" | sed -e 's/.c$$/.o/'`": $$i" `\ X cc -E $$i |\ X grep '^# .*"\./.*\.h"' |\ X sort -t'"' -u +1 -2 |\ X sed -e 's/.*"\.\/\(.*\)".*/\1/'\ X ` >> DEPEND ; \ X done X X Xdepend: $(CFILES) term.h X cp Makefile Makefile~ X sed -e '/\#\#\# Dependencies/q' < Makefile > tmp_make X for i in $(CFILES); do echo $$i; $(CPP_DEPEND) $$i >> tmp_make; done X mv tmp_make Makefile X Xscreen.o socket.o: Makefile X X### Dependencies: Xscreen.o: screen.c rcs.h config.h screen.h os.h ansi.h comm.h overlay.h term.h \ X display.h window.h patchlevel.h extern.h osdef.h Xansi.o: ansi.c rcs.h config.h screen.h os.h ansi.h comm.h overlay.h term.h \ X display.h window.h extern.h osdef.h Xfileio.o: fileio.c rcs.h config.h screen.h os.h ansi.h comm.h overlay.h term.h \ X display.h window.h extern.h osdef.h Xmark.o: mark.c rcs.h config.h screen.h os.h ansi.h comm.h overlay.h term.h \ X display.h window.h mark.h extern.h osdef.h Xmisc.o: misc.c rcs.h config.h screen.h os.h ansi.h comm.h overlay.h term.h \ X display.h window.h extern.h osdef.h Xresize.o: resize.c rcs.h config.h screen.h os.h ansi.h comm.h overlay.h term.h \ X display.h window.h extern.h osdef.h Xsocket.o: socket.c rcs.h config.h screen.h os.h ansi.h comm.h overlay.h term.h \ X display.h window.h extern.h osdef.h Xsearch.o: search.c rcs.h config.h screen.h os.h ansi.h comm.h overlay.h term.h \ X display.h window.h mark.h extern.h osdef.h Xtty.o: tty.c rcs.h config.h screen.h os.h ansi.h comm.h overlay.h term.h \ X display.h window.h extern.h osdef.h Xterm.o: term.c rcs.h term.h Xwindow.o: window.c rcs.h config.h screen.h os.h ansi.h comm.h overlay.h term.h \ X display.h window.h extern.h osdef.h Xutmp.o: utmp.c rcs.h config.h screen.h os.h ansi.h comm.h overlay.h term.h \ X display.h window.h extern.h osdef.h Xloadav.o: loadav.c rcs.h config.h screen.h os.h ansi.h comm.h overlay.h term.h \ X display.h window.h extern.h osdef.h Xputenv.o: putenv.c rcs.h config.h Xhelp.o: help.c rcs.h config.h screen.h os.h ansi.h comm.h overlay.h term.h \ X display.h window.h extern.h osdef.h Xtermcap.o: termcap.c rcs.h config.h screen.h os.h ansi.h comm.h overlay.h \ X term.h display.h window.h extern.h osdef.h Xinput.o: input.c rcs.h config.h screen.h os.h ansi.h comm.h overlay.h term.h \ X display.h window.h extern.h osdef.h Xattacher.o: attacher.c rcs.h config.h screen.h os.h ansi.h comm.h overlay.h \ X term.h display.h window.h extern.h osdef.h Xpty.o: pty.c rcs.h config.h screen.h os.h ansi.h comm.h overlay.h term.h \ X display.h window.h extern.h osdef.h Xprocess.o: process.c rcs.h config.h screen.h os.h ansi.h comm.h overlay.h \ X term.h display.h window.h extern.h osdef.h Xdisplay.o: display.c rcs.h config.h screen.h os.h ansi.h comm.h overlay.h \ X term.h display.h window.h extern.h osdef.h Xcomm.o: comm.c rcs.h config.h comm.h Xacl.o: acl.c rcs.h config.h screen.h os.h ansi.h comm.h overlay.h term.h \ X display.h window.h extern.h acl.h osdef.h END_OF_FILE if test 10792 -ne `wc -c <'Makefile.in'`; then echo shar: \"'Makefile.in'\" unpacked with wrong size! fi # end of 'Makefile.in' fi if test -f 'acl.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'acl.c'\" else echo shar: Extracting \"'acl.c'\" \(12121 characters\) sed "s/^X//" >'acl.c' <<'END_OF_FILE' X/* Copyright (c) 1993 X * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) X * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) X * Copyright (c) 1987 Oliver Laumann X * X * This program is free software; you can redistribute it and/or modify X * it under the terms of the GNU General Public License as published by X * the Free Software Foundation; either version 2, or (at your option) X * any later version. X * X * This program is distributed in the hope that it will be useful, X * but WITHOUT ANY WARRANTY; without even the implied warranty of X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the X * GNU General Public License for more details. X * X * You should have received a copy of the GNU General Public License X * along with this program (see the file COPYING); if not, write to the X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. X * X **************************************************************** X */ X#include "rcs.h" XRCS_ID("$Id: acl.c,v 1.9 1993/08/05 14:23:25 mlschroe Exp $ FAU") X X#include X X#include "config.h" X#include "screen.h" /* includes acl.h */ X#include "extern.h" X X X/************************************************************************ X * user managing code, this does not really belong into the acl stuff * X ************************************************************************/ X Xextern struct comm comms[]; Xextern struct win *windows, *wtab[]; Xextern struct display *display, *displays; Xstruct user *users; X X#ifdef MULTIUSER X/* record given user ids here */ Xstatic AclBits userbits; X X/* rights a new unknown user will have on windows and cmds */ Xstatic char default_w_bit[ACL_BITS_PER_WIN] = X{ X 1, /* EXEC */ X 1, /* WRITE */ X 1 /* READ */ X}; X Xstatic char default_c_bit[ACL_BITS_PER_CMD] = X{ X 1 /* EXEC */ X}; X X/* rights of all users per newly created window */ Xstatic AclBits default_w_userbits[ACL_BITS_PER_WIN]; X X/* Xstatic AclBits default_c_userbits[ACL_BITS_PER_CMD]; X*/ X Xstatic int maxusercount = 0; X Xstatic int GrowBitfield __P((AclBits *, int, int, int)); X X X Xstatic int XGrowBitfield(bfp, len, delta, defaultbit) XAclBits *bfp; Xint len, delta, defaultbit; X{ X AclBits n, o = *bfp; X int i; X X if (!(n = (AclBits)calloc(1, (unsigned long)(&ACLBYTE((char *)0, len + delta + 1))))) X return -1; X for (i = 0; i < (len + delta); i++) X { X if (((i < len) && (ACLBIT(i) & ACLBYTE(o, i))) || X ((i >= len) && (defaultbit))) X ACLBYTE(n, i) |= ACLBIT(i); X } X if (len) X free(o); X *bfp = n; X return 0; X} X X#endif /* MULTIUSER */ X X/* X * Returns an nonzero Address. Its contents is either a User-ptr, X * or NULL which may be replaced by a User-ptr to create the entry. X */ Xstruct user ** XFindUserPtr(name) Xchar *name; X{ X struct user **u; X X for (u = &users; *u; u = &(*u)->u_next) X if (!strcmp((*u)->u_name, name)) X break; X#ifdef MULTIUSER X debug3("FindUserPtr %s %sfound, id %d\n", name, (*u)?"":"not ", X (*u)?(*u)->id:-1); X#else X debug2("FindUserPtr %s %sfound\n", name, (*u)?"":"not "); X#endif X return u; X} X Xchar DefaultEsc = Ctrl('a'); Xchar DefaultMetaEsc = 'a'; X X/* X * Add a new user. His password may be NULL or "" if none. X * He is in no groups and thus has no rights. X */ Xint XUserAdd(name, pass, up) Xchar *name, *pass; Xstruct user **up; X{ X if (!up) X up = FindUserPtr(name); X if (*up) X return 1; /* he is already there */ X *up = (struct user *)calloc(1, sizeof(struct user)); X if (!*up) X return -1; /* he still does not exist */ X (*up)->u_copybuffer = NULL; X (*up)->u_copylen = 0; X (*up)->u_Esc = DefaultEsc; X (*up)->u_MetaEsc = DefaultMetaEsc; X strncpy((*up)->u_name, name, 20); X if (pass) X strncpy((*up)->u_password, pass, 20); X X#ifdef MULTIUSER X /* now find an unused index */ X for ((*up)->id = 0; (*up)->id < maxusercount; (*up)->id++) X if (!(ACLBIT((*up)->id) & ACLBYTE(userbits, (*up)->id))) X break; X debug2("UserAdd %s id %d\n", name, (*up)->id); X if ((*up)->id == maxusercount) X { X int i, j; X struct win *w; X X debug2("growing all bitfields %d += %d\n", maxusercount, USER_CHUNK); X /* the bitfields are full, grow a chunk */ X /* first, the used_uid_indicator: */ X if (GrowBitfield(&userbits, maxusercount, USER_CHUNK, 0)) X { X free(*up); *up = NULL; return -1; X } X /* second, default command bits */ X /* (only if we generate commands dynamically) */ X/* X for (j = 0; j < ACL_BITS_PER_CMD; j++) X if (GrowBitfield(&default_c_userbits[j], maxusercount, USER_CHUNK, X default_c_bit[j])) X { X free(*up); *up = NULL; return -1; X } X*/ X /* third, the bits for each commands */ X for (i = 0; i <= RC_LAST; i++) X for (j = 0; j < ACL_BITS_PER_CMD; j++) X if (GrowBitfield(&comms[i].userbits[j], maxusercount, USER_CHUNK, X default_c_bit[j])) X { X free(*up); *up = NULL; return -1; X } X /* fourth, default window and bits */ X for (j = 0; j < ACL_BITS_PER_WIN; j++) X if (GrowBitfield(&default_w_userbits[j], maxusercount, USER_CHUNK, X default_w_bit[j])) X { X free(*up); *up = NULL; return -1; X } X /* fifth, the bits for each window */ X for (w = windows; w; w = w->w_next) X for (j = 0; j < ACL_BITS_PER_WIN; j++) X if (GrowBitfield(&w->w_userbits[j], maxusercount, USER_CHUNK, X default_w_bit[j])) X { X free(*up); *up = NULL; return -1; X } X maxusercount += USER_CHUNK; X } X ACLBYTE(userbits, (*up)->id) |= ACLBIT((*up)->id); X#else /* MULTIUSER */ X debug1("UserAdd %s\n", name); X#endif /* MULTIUSER */ X return 0; X} X X/* change user's password */ Xint XUserSetPass(name, pass, up) Xchar *name, *pass; Xstruct user **up; X{ X if (!up) X up = FindUserPtr(name); X if (!*up) X return UserAdd(name, pass, up); X strncpy((*up)->u_password, pass ? pass : "", 20); X (*up)->u_password[20] = '\0'; X return 0; X} X X/* X * Remove a user from the list. X * Decrease reference count of all his groups X * Free his grouplist. X */ Xint XUserDel(name, up) Xchar *name; Xstruct user **up; X{ X struct user *u; X struct display *old, *next; X X if (!up) X up = FindUserPtr(name); X if (!(u = *up)) X return -1; /* he who does not exist cannot be removed */ X old = display; X for (display = displays; display; display = next) X { X next = display->_d_next; X if (d_user != u) X continue; X if (display == old) X old = 0; X Detach(D_REMOTE); X } X display = old; X *up = u->u_next; X#ifdef MULTIUSER X ACLBYTE(userbits, u->id) &= ~ACLBIT(u->id); X AclSetPerm(u, "-rwx", "#?"); X#endif X debug1("FREEING user structure for %s\n", u->u_name); X UserFreeCopyBuffer(u); X free(u); X return 0; X} X X/* X * returns 0 if the copy buffer was really deleted. X * Also removes any references into the users copybuffer X */ Xint XUserFreeCopyBuffer(u) Xstruct user *u; X{ X struct win *w; X X if (!u->u_copybuffer) X return 1; X for (w = windows; w; w = w->w_next) X { X if (w->w_pasteptr >= u->u_copybuffer && X w->w_pasteptr - u->u_copybuffer < u->u_copylen) X { X if (w->w_pastebuf) X free(w->w_pastebuf); X w->w_pastebuf = 0; X w->w_pasteptr = 0; X w->w_pastelen = 0; X } X } X free(u->u_copybuffer); X d_user->u_copylen = 0; X u->u_copybuffer = NULL; X return 0; X} X X/************************************************************************ X * end of user managing code * X ************************************************************************/ X X X#ifdef MULTIUSER X Xextern char *multi; /* username */ X X/* This gives the users default rights to the new window */ Xint XNewWindowAcl(w) Xstruct win *w; X{ X int i, j; X X debug1("NewWindowAcl default_w_userbits for window %d\n", w->w_number); X for (j = 0; j < ACL_BITS_PER_WIN; j++) X { X /* we start with len 0 for the new bitfield size and add maxusercount */ X if (GrowBitfield(&w->w_userbits[j], 0, maxusercount, 0)) X { X while (--j >= 0) X free(w->w_userbits[j]); X return -1; X } X for (i = 0; i < maxusercount; i++) X if (ACLBIT(i) & ACLBYTE(default_w_userbits[j], i)) X ACLBYTE(w->w_userbits[j], i) |= ACLBIT(i); X } X return 0; X} X X/* if mode starts with '-' we remove the users exec bit for cmd */ Xint XAclSetPermCmd(u, mode, cmd) Xstruct user *u; Xchar *mode; Xstruct comm *cmd; X{ X int neg = 0; X X if (!multi) X return 0; X debug3("AclSetPermCmd %s %s %s\n", u->u_name, mode, cmd->name); X while (*mode) X { X switch (*mode++) X { X case '-': X neg = 1; X continue; X case '+': X neg = 0; X continue; X case 'e': X case 'x': X if (neg) X ACLBYTE(cmd->userbits[ACL_EXEC], u->id) &= ~ACLBIT(u->id); X else X ACLBYTE(cmd->userbits[ACL_EXEC], u->id) |= ACLBIT(u->id); X break; X case 'r': X case 'w': X break; X default: X return -1; X } X } X return 0; X} X X/* mode strings of the form +rwx -w+rx r -wx are parsed and evaluated */ Xint XAclSetPermWin(u, mode, win) Xstruct user *u; Xchar *mode; Xstruct win *win; X{ X int neg = 0; X int bit; X X if (!multi) X return 0; X debug3("AclSetPermWin %s %s %d\n", u->u_name, mode, win->w_number); X while (*mode) X { X switch (*mode++) X { X case '-': X neg = 1; X continue; X case '+': X neg = 0; X continue; X case 'r': X bit = ACL_READ; X break; X case 'w': X bit = ACL_WRITE; X break; X case 'x': X bit = ACL_EXEC; X break; X default: X return -1; X } X if (neg) X ACLBYTE(win->w_userbits[bit], u->id) &= ~ACLBIT(u->id); X else X ACLBYTE(win->w_userbits[bit], u->id) |= ACLBIT(u->id); X } X return 0; X} X X/* string is broken down into comand and window names, mode applies */ Xint XAclSetPerm(u, mode, s) Xstruct user *u; Xchar *mode, *s; X{ X struct win *w; X int i; X char *p; X X while (*s) X { X switch (*s) X { X case '*': /* all windows and all commands */ X return AclSetPerm(u, mode, "#?"); X case '#': /* all windows */ X for (w = windows; w; w = w->w_next) X AclSetPermWin(u, mode, w); X s++; X break; X case '?': /* all commands */ X for (i = 0; i <= RC_LAST; i++) X AclSetPermCmd(u, mode, &comms[i]); X s++; X break; X default: X for (p = s; *p && *p != ' ' && *p != '\t' && *p != ','; p++) X ; X if (*p) X *p++ = '\0'; X else X *p = '\0'; X if ((i = FindCommnr(s)) != RC_ILLEGAL) X AclSetPermCmd(u, mode, &comms[i]); X else if (((i = WindowByNoN(s)) >= 0) && wtab[i]) X AclSetPermWin(u, mode, wtab[i]); X else X /* checking group name */ X return -1; X s = p; X } X } X return 0; X} X X#if 0 Xvoid XAclWinSwap(a, b) Xint a, b; X{ X int a_bit = 0, b_bit = 0; X AclGroupList **g; X AclBits p; X X debug2("acl lists swapping windows %d and %d\n", a, b); X X for (g = &aclgrouproot; *g; g = &(*g)->next) X { X p = (*g)->group->winbits; X /* see if there was a bit for window a. zap it */ X if (a >= 0) X if ((a_bit = ACLBIT(a) & ACLBYTE(p, a))) X ACLBYTE(p, a) &= ~ACLBIT(a); X /* see if there was a bit for window b. zap it */ X if (b >= 0) X if ((b_bit = ACLBIT(b) & ACLBYTE(p, b))) X ACLBYTE(p, b) &= ~ACLBIT(b); X /* b may cause a set */ X if (b_bit && a >= 0) X ACLBYTE(p, a) |= ACLBIT(a); X /* a may cause b set */ X if (a_bit && b >= 0) X ACLBYTE(p, b) |= ACLBIT(b); X } X} X#else Xvoid XAclWinSwap(a, b) Xint a, b; X{ X debug2("AclWinSwap(%d, %d) DUMMY\n", a, b); X} X#endif X Xint XAclCheckPermWin(u, mode, w) Xstruct user *u; Xint mode; Xstruct win *w; X{ X if (!multi) X return 0; X if (mode < 0 || mode >= ACL_BITS_PER_WIN) X return -1; X debug3("AclCheckPermWin(%s, %d, %d) = ", u->u_name, mode, w->w_number); X debug1("%d\n", !(ACLBYTE(w->w_userbits[mode], u->id) & ACLBIT(u->id))); X return !(ACLBYTE(w->w_userbits[mode], u->id) & ACLBIT(u->id)); X} X Xint XAclCheckPermCmd(u, mode, c) Xstruct user *u; Xint mode; Xstruct comm *c; X{ X if (!multi) X return 0; X if (mode < 0 || mode >= ACL_BITS_PER_CMD) X return -1; X debug3("AclCheckPermCmd(%s %d %s) = ", u->u_name, mode, c->name); X debug1("%d\n", !(ACLBYTE(c->userbits[mode], u->id) & ACLBIT(u->id))); X return !(ACLBYTE(c->userbits[mode], u->id) & ACLBIT(u->id)); X} X X#endif /* MULTIUSER */ END_OF_FILE if test 12121 -ne `wc -c <'acl.c'`; then echo shar: \"'acl.c'\" unpacked with wrong size! fi # end of 'acl.c' fi if test -f 'config.h.in' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'config.h.in'\" else echo shar: Extracting \"'config.h.in'\" \(11060 characters\) sed "s/^X//" >'config.h.in' <<'END_OF_FILE' X/* Copyright (c) 1993 X * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) X * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) X * Copyright (c) 1987 Oliver Laumann X * X * This program is free software; you can redistribute it and/or modify X * it under the terms of the GNU General Public License as published by X * the Free Software Foundation; either version 2, or (at your option) X * any later version. X * X * This program is distributed in the hope that it will be useful, X * but WITHOUT ANY WARRANTY; without even the implied warranty of X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the X * GNU General Public License for more details. X * X * You should have received a copy of the GNU General Public License X * along with this program (see the file COPYING); if not, write to the X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. X * X **************************************************************** X * $Id: config.h.in,v 1.7 1993/08/05 14:23:35 mlschroe Exp $ FAU X */ X X X X X X/********************************************************************** X * X * User Configuration Section X */ X X X X/* X * Define SOCKDIR to be the directory to contain the named sockets X * screen creates. This should be in a common subdirectory, such as X * /usr/local or /tmp. It makes things a little more secure if you X * choose a directory which is not writable by everyone or where the X * "sticky" bit is on, but this isn't required. X * If SOCKDIR is not defined screen will put the named sockets in X * the user's home directory. Notice that this can cause you problems X * if some user's HOME directories are NFS-mounted and don't support X * named sockets. X * Screen will name the subdirectories "S-$USER" (e.g /tmp/S-davison). X * Do not define TMPTEST unless it's for debugging purpose. X */ X X#ifndef TMPTEST X# define SOCKDIR "/tmp/screens" X#else X# define SOCKDIR "/tmp/testscreens" X#endif X X/* X * Screen sources two startup files. First a global file with a path X * specified here, second your local $HOME/.screenrc X * Don't define this, if you don't want it. X */ X#ifndef ETCSCREENRC X# define ETCSCREENRC "/usr/local/etc/screenrc" X#endif X X/* X * Screen can look for the environment variable $SYSSCREENRC and -if it X * exists- load the file specified in that variable as global screenrc. X * If you want to enable this feature, define ALLOW_SYSSCREENRC to one (1). X * Otherwise ETCSCREENRC is always loaded. X */ X#define ALLOW_SYSSCREENRC 1 X X/* X * define PTYMODE if you do not like the default of 0622, which allows X * public write to your pty. X * define PTYGROUP to some numerical group-id if you do not want the X * tty to be in "your" group. X * Note, screen is unable to change mode or group of the pty if it X * is not installed with sufficient privilege. (e.g. set-uid-root) X */ X#undef PTYMODE X#undef PTYGROUP X X/* X * If screen is NOT installed set-uid root, screen can provide tty X * security by exclusively locking the ptys. While this keeps other X * users from opening your ptys, it also keeps your own subprocesses X * from being able to open /dev/tty. Define LOCKPTY to add this X * exclusive locking. X */ X#undef LOCKPTY X X/* X * If you'd rather see the status line on the first line of your X * terminal rather than the last, define TOPSTAT. X */ X#undef TOPSTAT X X/* X * here come the erlangen extensions to screen: X * define LOCK if you want to use a lock program for a screenlock. X * define PASSWORD for secure reattach of your screen. X * define COPY_PASTE to use the famous hacker's treasure zoo. X * define POW_DETACH to have a detach_and_logout key. X * define REMOTE_DETACH (-d option) to move screen between terminals. X * define AUTO_NUKE to enable Tim MacKenzies clear screen nuking X * define PSEUDOS to allow window input/output filtering X * define MULTI to allow multiple attaches. X * define MULTIUSER to allow other users attach to your session X * (if they are in the acl, of course) X * (jw) X */ X#undef SIMPLESCREEN X#ifndef SIMPLESCREEN X# define LOCK X# define PASSWORD X# define COPY_PASTE X# define REMOTE_DETACH X# define POW_DETACH X# define AUTO_NUKE X# define PSEUDOS X# define MULTI X# define MULTIUSER X#endif /* SIMPLESCREEN */ X X/* X * As error messages are mostly meaningless to the user, we X * try to throw out phrases that are somewhat more familiar X * to ...well, at least familiar to us NetHack players. X */ X#ifndef NONETHACK X# define NETHACK X#endif /* NONETHACK */ X X/* X * If screen is installed with permissions to update /etc/utmp (such X * as if it is installed set-uid root), define UTMPOK. X */ X#define UTMPOK X X/* Set LOGINDEFAULT to one (1) X * if you want entries added to /etc/utmp by default, else set it to X * zero (0). X * LOGINDEFAULT will be one (1) whenever LOGOUTOK is undefined! X */ X#define LOGINDEFAULT 1 X X/* Set LOGOUTOK to one (1) X * if you want the user to be able to log her/his windows out. X * (Meaning: They are there, but not visible in /etc/utmp). X * Disabling this feature only makes sense if you have a secure /etc/utmp X * database. X * Negative examples: suns usually have a world writable utmp file, X * xterm will run perfectly without s-bit. X */ X#define LOGOUTOK 1 X X X/* X * If UTMPOK is defined and your system (incorrectly) counts logins by X * counting non-null entries in /etc/utmp (instead of counting non-null X * entries with no hostname that are not on a pseudo tty), define USRLIMIT X * to have screen put an upper-limit on the number of entries to write X * into /etc/utmp. This helps to keep you from exceeding a limited-user X * license. X */ X#undef USRLIMIT X X X X/********************************************************************** X * X * End of User Configuration Section X * X * Rest of this file is modified by 'configure' X * Change at your own risk! X * X */ X X/* X * Some defines to identify special unix variants X */ X#ifndef SVR4 X#undef SVR4 X#endif X X#ifndef OSF1 X#undef OSF1 X#endif X X#ifndef MIPS X#undef MIPS X#endif X X/* X * Define POSIX if your system supports IEEE Std 1003.1-1988 (POSIX). X */ X#undef POSIX X X/* X * Define BSDJOBS if you have BSD-style job control (both process X * groups and a tty that deals correctly with them). X */ X#undef BSDJOBS X X/* X * Define TERMIO if you have struct termio instead of struct sgttyb. X * This is usually the case for SVID systems, where BSD uses sgttyb. X * POSIX systems should define this anyway, even though they use X * struct termios. X */ X#undef TERMIO X X/* X * Define TERMINFO if your machine emulates the termcap routines X * with the terminfo database. X * Thus the .screenrc file is parsed for X * the command 'terminfo' and not 'termcap'. X */ X#undef TERMINFO X X/* X * If your library does not define ospeed, define this. X */ X#undef NEED_OSPEED X X/* X * Define SYSV if your machine is SYSV complient (Sys V, HPUX, A/UX) X */ X#ifndef SYSV X#undef SYSV X#endif X X/* X * Define SIGVOID if your signal handlers return void. On older X * systems, signal returns int, but on newer ones, it returns void. X */ X#undef SIGVOID X X/* X * Define USESIGSET if you have sigset for BSD 4.1 reliable signals. X */ X#undef USESIGSET X X/* X * Define SYSVSIGS if signal handlers must be reinstalled after X * they have been called. X */ X#undef SYSVSIGS X X/* X * Define BSDWAIT if your system defines a 'union wait' in X * X * Only allow BSDWAIT i.e. wait3 on nonposix systems, since X * posix implies wait(3) and waitpid(3). vdlinden@fwi.uva.nl X * X */ X#ifndef POSIX X#undef BSDWAIT X#endif X X/* X * On RISCOS we prefer wait2() over wait3(). rouilj@sni-usa.com X */ X#ifdef BSDWAIT X#undef USE_WAIT2 X#endif X X/* X * Define DIRENT if your system has instead of X */ X#undef DIRENT X X/* X * If your system has getutent(), pututline(), etc. to write to the X * utmp file, define GETUTENT. X */ X#undef GETUTENT X X/* X * Define UTHOST if the utmp file has a host field. X */ X#undef UTHOST X X/* X * If ttyslot() breaks getlogin() by returning indexes to utmp entries X * of type DEAD_PROCESS, then our getlogin() replacement should be X * selected by defining BUGGYGETLOGIN. X */ X#undef BUGGYGETLOGIN X X/* X * If your system does not have the calls setreuid() and setregid(), X * define NOREUID to force screen to use a forked process to safely X * create output files without retaining any special privileges. X * (Output logging will be disabled, however.) X */ X#undef NOREUID X X/* X * If you want the "time" command to display the current load average X * define LOADAV. Maybe you must install screen with the needed X * privileges to read /dev/kmem. X * Note that NLIST_ stuff is only checked, when getloadavg() is not available. X */ X#undef LOADAV X X#undef LOADAV_NUM X#undef LOADAV_TYPE X#undef LOADAV_SCALE X#undef LOADAV_GETLOADAVG X#undef LOADAV_UNIX X#undef LOADAV_AVENRUN X X#undef NLIST_DECLARED X#undef NLIST_STRUCT X#undef NLIST_NAME_UNION X X/* X * If your system has the new format /etc/ttys (like 4.3 BSD) and the X * getttyent(3) library functions, define GETTTYENT. X */ X#undef GETTTYENT X X/* X * Define USEBCOPY if the bcopy/memcpy from your system's C library X * supports the overlapping of source and destination blocks. When X * undefined, screen uses its own (probably slower) version of bcopy(). X * X * SYSV machines may have a working memcpy() -- Oh, this is X * quite unlikely. Tell me if you see one. (Juergen) X * But then, memmove() should work, if at all available. X */ X#undef USEBCOPY X#undef USEMEMCPY X#undef USEMEMMOVE X X/* X * If your system has vsprintf() and requires the use of the macros in X * "varargs.h" to use functions with variable arguments, X * define USEVARARGS. X */ X#undef USEVARARGS X X/* X * If the select return value doesn't treat a descriptor that is X * usable for reading and writing as two hits, define SELECT_BROKEN. X */ X#undef SELECT_BROKEN X X/* X * Define this if your system supports named pipes. X */ X#undef NAMEDPIPE X X/* X * Define this if your system exits select() immediatly if a pipe is X * opened read-only and no writer has opened it. X */ X#undef BROKEN_PIPE X X/* X * Define this if the unix-domain socket implementation doesn't X * create a socket in the filesystem. X */ X#undef SOCK_NOT_IN_FS X X/* X * If your system has setenv() and unsetenv() define USESETENV X */ X#undef USESETENV X X/* X * If your system does not come with a setenv()/putenv()/getenv() X * functions, you may bring in our own code by defining NEEDPUTENV. X */ X#undef NEEDPUTENV X X/* X * If the passwords are stored in a shadow file and you want the X * builtin lock to work properly, define SHADOWPW. X */ X#undef SHADOWPW X X/* X * If you are on a SYS V machine that restricts filename length to 14 X * characters, you may need to enforce that by setting NAME_MAX to 14 X */ X#undef NAME_MAX /* KEEP_UNDEF_HERE override system value */ X#undef NAME_MAX X X/* X * define PTYRANGE0 and or PTYRANGE1 if you want to adapt screen X * to unusual environments. E.g. For SunOs the defaults are "qpr" and X * "0123456789abcdef". For SunOs 4.1.2 X * #define PTYRANGE0 "pqrstuvwxyzPQRST" X * is recommended by Dan Jacobson. X */ X#undef PTYRANGE0 X#undef PTYRANGE1 X X/* X * some defines to prevent retypedefs X */ X#undef SIG_T_DEFINED X#undef PID_T_DEFINED X#undef UID_T_DEFINED X END_OF_FILE if test 11060 -ne `wc -c <'config.h.in'`; then echo shar: \"'config.h.in'\" unpacked with wrong size! fi # end of 'config.h.in' fi if test -f 'extern.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'extern.h'\" else echo shar: Extracting \"'extern.h'\" \(9523 characters\) sed "s/^X//" >'extern.h' <<'END_OF_FILE' X/* Copyright (c) 1993 X * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) X * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) X * Copyright (c) 1987 Oliver Laumann X * X * This program is free software; you can redistribute it and/or modify X * it under the terms of the GNU General Public License as published by X * the Free Software Foundation; either version 2, or (at your option) X * any later version. X * X * This program is distributed in the hope that it will be useful, X * but WITHOUT ANY WARRANTY; without even the implied warranty of X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the X * GNU General Public License for more details. X * X * You should have received a copy of the GNU General Public License X * along with this program (see the file COPYING); if not, write to the X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. X * X **************************************************************** X * $Id: extern.h,v 1.13 1993/08/04 00:42:34 mlschroe Exp $ FAU X */ X X X/* screen.c */ Xextern void main __P((int, char **)); Xextern sig_t SigHup __P(SIGPROTOARG); Xextern void eexit __P((int)); Xextern void Detach __P((int)); Xextern void Kill __P((int, int)); X#ifdef USEVARARGS Xextern void Msg __P((int, char *, ...)) X# ifdef __GNUC__ X__attribute__ ((format (printf, 2, 3))) X# endif X; Xextern void Panic __P((int, char *, ...)) X# ifdef __GNUC__ X__attribute__ ((format (printf, 2, 3))) X# endif X; X#else Xextern void Msg __P(()); Xextern void Panic __P(()); X#endif Xextern void DisplaySleep __P((int)); Xextern sig_t Finit __P((int)); Xextern void MakeNewEnv __P((void)); X X/* ansi.c */ Xextern void Activate __P((int)); Xextern void ResetWindow __P((struct win *)); Xextern void WriteString __P((struct win *, char *, int)); Xextern void NewAutoFlow __P((struct win *, int)); Xextern void Redisplay __P((int)); Xextern void CheckLP __P((int)); Xextern void MakeBlankLine __P((char *, int)); Xextern void SetCurr __P((struct win *)); Xextern void ChangeAKA __P((struct win *, char *, int)); Xextern void AddLineToHist __P((struct win *, char **, char **, char **)); X X/* fileio.c */ Xextern void StartRc __P((char *)); Xextern void FinishRc __P((char *)); Xextern void RcLine __P((char *)); Xextern FILE *secfopen __P((char *, char *)); Xextern int secopen __P((char *, int, int)); Xextern void WriteFile __P((int)); Xextern void ReadFile __P((void)); Xextern void KillBuffers __P((void)); Xextern char *expand_vars __P((char *)); X X/* tty.c */ Xextern int OpenTTY __P((char *)); Xextern void InitTTY __P((struct mode *, int)); Xextern void GetTTY __P((int, struct mode *)); Xextern void SetTTY __P((int, struct mode *)); Xextern void SetMode __P((struct mode *, struct mode *)); Xextern void SetFlow __P((int)); Xextern void SendBreak __P((struct win *, int, int)); Xextern int TtyGrabConsole __P((int, int, char *)); X#ifdef DEBUG Xextern void DebugTTY __P((struct mode *)); X#endif /* DEBUG */ Xextern int fgtty __P((int)); Xextern void brktty __P((int)); X X/* mark.c */ Xextern int GetHistory __P((void)); Xextern void MarkRoutine __P((void)); Xextern void revto_line __P((int, int, int)); Xextern void revto __P((int, int)); X X/* search.c */ Xextern void Search __P((int)); Xextern void ISearch __P((int)); X X/* input.c */ Xextern void inp_setprompt __P((char *, char *)); Xextern void Input __P((char *, int, void (*)(), int)); X X/* help.c */ Xextern void exit_with_usage __P((char *)); Xextern void display_help __P((void)); Xextern void display_copyright __P((void)); Xextern void display_displays __P((void)); X X/* window.c */ Xextern int MakeWindow __P((struct NewWindow *)); Xextern void FreeWindow __P((struct win *)); X#ifdef PSEUDOS Xextern int winexec __P((char **)); Xextern void FreePseudowin __P((struct win *)); X#endif X#ifdef MULTI Xextern int execclone __P((char **)); X#endif Xextern void nwin_compose __P((struct NewWindow *, struct NewWindow *, struct NewWindow *)); X X/* utmp.c */ X#ifdef UTMPOK Xextern void InitUtmp __P((void)); Xextern void RemoveLoginSlot __P((void)); Xextern void RestoreLoginSlot __P((void)); Xextern int SetUtmp __P((struct win *)); Xextern int RemoveUtmp __P((struct win *)); X#endif /* UTMPOK */ Xextern void SlotToggle __P((int)); X#ifdef USRLIMIT Xextern int CountUsers __P((void)); X#endif X X/* loadav.c */ X#ifdef LOADAV Xextern void InitLoadav __P((void)); Xextern void AddLoadav __P((char *)); X#endif X X/* pty.c */ Xextern int OpenPTY __P((char **)); X X/* process.c */ Xextern void InitKeytab __P((void)); Xextern void ProcessInput __P((char *, int)); Xextern int FindCommnr __P((char *)); Xextern void DoCommand __P((char **)); Xextern void KillWindow __P((struct win *)); Xextern int ReleaseAutoWritelock __P((struct display *, struct win *)); Xextern void SetForeWindow __P((struct win *)); Xextern int Parse __P((char *, char **)); Xextern int ParseEscape __P((struct user *, char *)); Xextern void DoScreen __P((char *, char **)); Xextern void ShowWindows __P((void)); Xextern int WindowByNoN __P((char *)); X#ifdef COPY_PASTE Xextern int CompileKeys __P((char *, char *)); X#endif X X/* termcap.c */ Xextern int InitTermcap __P((int, int)); Xextern char *MakeTermcap __P((int)); Xextern char *gettermcapstring __P((char *)); X X/* attacher.c */ Xextern int Attach __P((int)); Xextern void Attacher __P((void)); Xextern sig_t AttacherFinit __P(SIGPROTOARG); X X/* display.c */ Xextern struct display *MakeDisplay __P((char *, char *, char *, int, int, struct mode *)); Xextern void FreeDisplay __P((void)); Xextern void DefProcess __P((char **, int *)); Xextern void DefRedisplayLine __P((int, int, int, int)); Xextern void DefClearLine __P((int, int, int)); Xextern int DefRewrite __P((int, int, int, int)); Xextern void DefSetCursor __P((void)); Xextern int DefResize __P((int, int)); Xextern void DefRestore __P((void)); Xextern void PutStr __P((char *)); Xextern void CPutStr __P((char *, int)); Xextern void InitTerm __P((int)); Xextern void FinitTerm __P((void)); Xextern void INSERTCHAR __P((int)); Xextern void PUTCHAR __P((int)); Xextern void PUTCHARLP __P((int)); Xextern void RAW_PUTCHAR __P((int)); Xextern void ClearDisplay __P((void)); Xextern void Clear __P((int, int, int, int)); Xextern void RefreshLine __P((int, int, int, int)); Xextern void DisplayLine __P((char *, char *, char *, char *, char *, char *, int, int, int)); Xextern void FixLP __P((int, int)); Xextern void GotoPos __P((int, int)); Xextern int CalcCost __P((char *)); Xextern void ScrollRegion __P((int, int, int)); Xextern void ChangeScrollRegion __P((int, int)); Xextern void InsertMode __P((int)); Xextern void KeypadMode __P((int)); Xextern void CursorkeysMode __P((int)); Xextern void SetFont __P((int)); Xextern void SetAttr __P((int)); Xextern void SetAttrFont __P((int, int)); Xextern void MakeStatus __P((char *)); Xextern void RemoveStatus __P((void)); Xextern void SetLastPos __P((int, int)); Xextern int ResizeDisplay __P((int, int)); Xextern int InitOverlayPage __P((int, struct LayFuncs *, int)); Xextern void ExitOverlayPage __P((void)); Xextern void AddStr __P((char *)); Xextern void AddStrn __P((char *, int)); Xextern void Flush __P((void)); Xextern void freetty __P((void)); Xextern void Resize_obuf __P((void)); X#ifdef AUTO_NUKE Xextern void NukePending __P((void)); X#endif X X/* resize.c */ Xextern int ChangeScrollback __P((struct win *, int, int)); Xextern int ChangeWindowSize __P((struct win *, int, int)); Xextern void ChangeScreenSize __P((int, int, int)); Xextern void CheckScreenSize __P((int)); Xextern void DoResize __P((int, int)); Xextern char *xrealloc __P((char *, int)); X X/* socket.c */ Xextern int FindSocket __P((int, int *)); Xextern int MakeClientSocket __P((int, char *)); Xextern int MakeServerSocket __P((void)); Xextern int RecoverSocket __P((void)); Xextern int chsock __P((void)); Xextern void ReceiveMsg __P(()); Xextern void SendCreateMsg __P((int, struct NewWindow *)); X#ifdef USEVARARGS Xextern void SendErrorMsg __P((char *, ...)) X# ifdef __GNUC__ X__attribute__ ((format (printf, 1, 2))) X# endif X; X#else Xextern void SendErrorMsg __P(()); X#endif X X/* misc.c */ Xextern char *SaveStr __P((const char *)); Xextern void centerline __P((char *)); Xextern char *Filename __P((char *)); Xextern char *stripdev __P((char *)); X#if !defined(MEMFUNCS_DECLARED) && !defined(bcopy) Xextern void bcopy __P((char *, char *, int)); X#endif /* !MEMFUNCS_DECLARED && !bcopy */ Xextern void bclear __P((char *, int)); Xextern void closeallfiles __P((int)); Xextern int UserContext __P((void)); Xextern void UserReturn __P((int)); Xextern int UserStatus __P((void)); X X/* acl.c */ X#ifdef MULTIUSER Xextern int AclInit __P((char *)); Xextern int AclSetPass __P((char *, char *)); Xextern int AclDelUser __P((char *)); Xextern int UserFreeCopyBuffer __P((struct user *)); Xextern int AclAddGroup __P((char *)); Xextern int AclSetGroupPerm __P((char *, char *)); Xextern int AclDelGroup __P((char *)); Xextern int AclUserAddGroup __P((char *, char *)); Xextern int AclUserDelGroup __P((char *, char *)); Xextern int AclCheckPermWin __P((struct user *, int, struct win *)); Xextern int AclCheckPermCmd __P((struct user *, int, struct comm *)); Xextern int AclSetPerm __P((struct user *, char *, char *)); Xextern void AclWinSwap __P((int, int)); Xextern int NewWindowAcl __P((struct win *)); X#endif /* MULTIUSER */ Xextern struct user **FindUserPtr __P((char *)); Xextern int UserAdd __P((char *, char *, struct user **)); Xextern int UserDel __P((char *, struct user **)); END_OF_FILE if test 9523 -ne `wc -c <'extern.h'`; then echo shar: \"'extern.h'\" unpacked with wrong size! fi # end of 'extern.h' fi if test -f 'help.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'help.c'\" else echo shar: Extracting \"'help.c'\" \(15145 characters\) sed "s/^X//" >'help.c' <<'END_OF_FILE' X/* Copyright (c) 1993 X * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) X * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) X * Copyright (c) 1987 Oliver Laumann X * X * This program is free software; you can redistribute it and/or modify X * it under the terms of the GNU General Public License as published by X * the Free Software Foundation; either version 2, or (at your option) X * any later version. X * X * This program is distributed in the hope that it will be useful, X * but WITHOUT ANY WARRANTY; without even the implied warranty of X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the X * GNU General Public License for more details. X * X * You should have received a copy of the GNU General Public License X * along with this program (see the file COPYING); if not, write to the X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. X * X **************************************************************** X */ X X#include "rcs.h" XRCS_ID("$Id: help.c,v 1.4 1993/08/05 14:23:47 mlschroe Exp $ FAU") X X#include X#include X X#include "config.h" X X#include "screen.h" X#include "extern.h" X Xchar version[40]; /* initialised by main() */ X Xextern struct display *display; Xextern char *noargs[]; X X Xvoid Xexit_with_usage(myname) Xchar *myname; X{ X printf("Use: %s [-opts] [cmd [args]]\n", myname); X printf(" or: %s -r [host.tty]\n\nOptions:\n", myname); X printf("-a Force all capabilities into each window's termcap.\n"); X printf("-A -[r|R] Adapt all windows to the new display width & height.\n"); X printf("-c file Read configuration file instead of '.screenrc'.\n"); X#ifdef REMOTE_DETACH X printf("-d (-r) Detach the elsewhere running screen (and reattach here).\n"); X printf("-D (-r) Detach and logout remote (and reattach here).\n"); X#endif X printf("-e xy Change command characters.\n"); X printf("-f Flow control on, -fn = off, -fa = auto.\n"); X printf("-h lines Set the size of the scrollback history buffer.\n"); X printf("-i Interrupt output sooner when flow control is on.\n"); X#ifdef LOGOUTOK X printf("-l Login mode on (update %s), -ln = off.\n", UTMPFILE); X#endif X printf("-list or -ls. Do nothing, just list our SockDir.\n"); X printf("-L Terminal's last character can be safely updated.\n"); X printf("-m ignore $STY variable, do create a new screen session.\n"); X printf("-O Choose optimal output rather than exact vt100 emulation.\n"); X printf("-q Quiet startup. Exits with non-zero return code if unsuccessful.\n"); X printf("-r Reattach to a detached screen process.\n"); X printf("-R Reattach if possible, otherwise start a new session.\n"); X printf("-s shell Shell to execute rather than $SHELL.\n"); X printf("-S sockname Name this session .sockname instead of ...\n"); X printf("-t title Set title. (window's name).\n"); X printf("-T term Use term as $TERM for windows, rather than \"screen\".\n"); X printf("-v Print \"Screen version %s\".\n", version); X printf("-wipe Do nothing, just clean up SockDir.\n"); X#ifdef MULTI X printf("-x Attach to a not detached screen. (Multi display mode).\n"); X#endif /* MULTI */ X exit(1); X} X X X/* X** Here come the help page routines X*/ X Xextern struct comm comms[]; Xextern struct action ktab[]; X Xstatic void HelpProcess __P((char **, int *)); Xstatic void HelpAbort __P((void)); Xstatic void HelpRedisplayLine __P((int, int, int, int)); Xstatic void HelpSetCursor __P((void)); Xstatic void add_key_to_buf __P((char *, int)); Xstatic int helppage __P((void)); X Xstruct helpdata X{ X int maxrow, grow, numcols, numrows, num_names; X int numskip, numpages; X int command_search, command_bindings; X int refgrow, refcommand_search; X int inter, mcom, mkey; X int nact[RC_LAST + 1]; X}; X X#define MAXKLEN 256 X Xstatic struct LayFuncs HelpLf = X{ X HelpProcess, X HelpAbort, X HelpRedisplayLine, X DefClearLine, X DefRewrite, X HelpSetCursor, X DefResize, X DefRestore X}; X X Xvoid Xdisplay_help() X{ X int i, n, key, mcom, mkey, l; X struct helpdata *helpdata; X int used[RC_LAST + 1]; X X if (d_height < 6) X { X Msg(0, "Window height too small for help page"); X return; X } X if (InitOverlayPage(sizeof(*helpdata), &HelpLf, 0)) X return; X X helpdata = (struct helpdata *)d_lay->l_data; X helpdata->num_names = helpdata->command_bindings = 0; X helpdata->command_search = 0; X for (n = 0; n <= RC_LAST; n++) X used[n] = 0; X mcom = 0; X mkey = 0; X for (key = 0; key < 256; key++) X { X n = ktab[key].nr; X if (n == RC_ILLEGAL) X continue; X if (ktab[key].args == noargs) X { X used[n] += (key <= ' ' || key == 0x7f) ? 3 : X (key > 0x7f) ? 5 : 2; X } X else X helpdata->command_bindings++; X } X for (n = i = 0; n <= RC_LAST; n++) X if (used[n]) X { X l = strlen(comms[n].name); X if (l > mcom) X mcom = l; X if (used[n] > mkey) X mkey = used[n]; X helpdata->nact[i++] = n; X } X debug1("help: %d commands bound to keys with no arguments\n", i); X debug2("mcom: %d mkey: %d\n", mcom, mkey); X helpdata->num_names = i; X X if (mkey > MAXKLEN) X mkey = MAXKLEN; X helpdata->numcols = (d_width - !CLP)/(mcom + mkey + 1); X if (helpdata->numcols == 0) X { X HelpAbort(); X Msg(0, "Width too small"); X return; X } X helpdata->inter = (d_width - !CLP - (mcom + mkey) * helpdata->numcols) / (helpdata->numcols + 1); X if (helpdata->inter <= 0) X helpdata->inter = 1; X debug1("inter: %d\n", helpdata->inter); X helpdata->mcom = mcom; X helpdata->mkey = mkey; X helpdata->numrows = (helpdata->num_names + helpdata->numcols - 1) / helpdata->numcols; X debug1("Numrows: %d\n", helpdata->numrows); X helpdata->numskip = d_height-5 - (2 + helpdata->numrows); X while (helpdata->numskip < 0) X helpdata->numskip += d_height-5; X helpdata->numskip %= d_height-5; X debug1("Numskip: %d\n", helpdata->numskip); X if (helpdata->numskip > d_height/3 || helpdata->numskip > helpdata->command_bindings) X helpdata->numskip = 1; X helpdata->maxrow = 2 + helpdata->numrows + helpdata->numskip + helpdata->command_bindings; X helpdata->grow = 0; X X helpdata->numpages = (helpdata->maxrow + d_height-6) / (d_height-5); X helppage(); X} X Xstatic void XHelpSetCursor() X{ X GotoPos(0, d_height - 1); X} X Xstatic void XHelpProcess(ppbuf, plen) Xchar **ppbuf; Xint *plen; X{ X int done = 0; X X GotoPos(0, d_height-1); X while (!done && *plen > 0) X { X switch (**ppbuf) X { X case ' ': X if (helppage() == 0) X break; X /* FALLTHROUGH */ X case '\r': X case '\n': X done = 1; X break; X default: X break; X } X ++*ppbuf; X --*plen; X } X if (done) X HelpAbort(); X} X Xstatic void XHelpAbort() X{ X LAY_CALL_UP(Activate(0)); X ExitOverlayPage(); X} X X Xstatic int Xhelppage() X{ X struct helpdata *helpdata; X int col, crow, n, key; X char buf[MAXKLEN], Esc_buf[5], cbuf[256]; X X helpdata = (struct helpdata *)d_lay->l_data; X X if (helpdata->grow >= helpdata->maxrow) X { X return(-1); X } X helpdata->refgrow = helpdata->grow; X helpdata->refcommand_search = helpdata->command_search; X X /* Clear the help screen */ X SetAttrFont(0, ASCII); X ClearDisplay(); X X sprintf(cbuf,"Screen key bindings, page %d of %d.", helpdata->grow / (d_height-5) + 1, helpdata->numpages); X centerline(cbuf); X AddChar('\n'); X crow = 2; X X *Esc_buf = '\0'; X add_key_to_buf(Esc_buf, d_user->u_Esc); X X for (; crow < d_height - 3; crow++) X { X if (helpdata->grow < 1) X { X *buf = '\0'; X add_key_to_buf(buf, d_user->u_MetaEsc); X sprintf(cbuf,"Command key: %s Literal %s: %s", Esc_buf, Esc_buf, buf); X centerline(cbuf); X helpdata->grow++; X } X else if (helpdata->grow >= 2 && helpdata->grow-2 < helpdata->numrows) X { X for (col = 0; col < helpdata->numcols && (n = helpdata->numrows * col + (helpdata->grow-2)) < helpdata->num_names; col++) X { X AddStrn("", helpdata->inter - !col); X n = helpdata->nact[n]; X debug1("help: searching key %d\n", n); X buf[0] = '\0'; X for (key = 0; key < 256; key++) X if (ktab[key].nr == n && ktab[key].args == noargs) X { X strcat(buf, " "); X add_key_to_buf(buf, key); X } X AddStrn(comms[n].name, helpdata->mcom); X AddStrn(buf, helpdata->mkey); X } X AddStr("\r\n"); X helpdata->grow++; X } X else if (helpdata->grow-2-helpdata->numrows >= helpdata->numskip X && helpdata->grow-2-helpdata->numrows-helpdata->numskip < helpdata->command_bindings) X { X char **pp, *cp; X X while ((n = ktab[helpdata->command_search].nr) == RC_ILLEGAL X || ktab[helpdata->command_search].args == noargs) X { X if (++helpdata->command_search >= 256) X return -1; X } X buf[0] = '\0'; X add_key_to_buf(buf, helpdata->command_search); X AddStrn(buf, 4); X col = 4; X AddStr(comms[n].name); X AddChar(' '); X col += strlen(comms[n].name) + 1; X pp = ktab[helpdata->command_search++].args; X while (pp && (cp = *pp) != NULL) X { X if (!*cp || (index(cp, ' ') != NULL)) X { X if (index(cp, '\'') != NULL) X *buf = '"'; X else X *buf = '\''; X sprintf(buf + 1, "%s%c", cp, *buf); X cp = buf; X } X if ((col += strlen(cp) + 1) >= d_width) X { X col = d_width - (col - (strlen(cp) + 1)) - 2; X if (col >= 0) X { X n = cp[col]; X cp[col] = '\0'; X AddStr(*pp); X AddChar('$'); X cp[col] = (char) n; X } X break; X } X AddStr(cp); X AddChar((d_width - col != 1 || !pp[1]) ? ' ' : '$'); X pp++; X } X AddStr("\r\n"); X helpdata->grow++; X } X else X { X AddChar('\n'); X helpdata->grow++; X } X } X AddChar('\n'); X sprintf(cbuf,"[Press Space %s Return to end.]", X helpdata->grow < helpdata->maxrow ? "for next page;" : "or"); X centerline(cbuf); X SetLastPos(0, d_height-1); X return(0); X} X Xstatic void Xadd_key_to_buf(buf, key) Xchar *buf; Xint key; X{ X debug1("help: key found: %c\n", key); X buf += strlen(buf); X if (key == ' ') X sprintf(buf, "sp"); X else if (key < ' ' || key == 0x7f) X sprintf(buf, "^%c", (key ^ 0x40)); X else if (key >= 0x80) X sprintf(buf, "\\%03o", key); X else X sprintf(buf, "%c", key); X} X X Xstatic void XHelpRedisplayLine(y, xs, xe, isblank) Xint y, xs, xe, isblank; X{ X if (y < 0) X { X struct helpdata *helpdata; X X helpdata = (struct helpdata *)d_lay->l_data; X helpdata->grow = helpdata->refgrow; X helpdata->command_search = helpdata->refcommand_search; X helppage(); X return; X } X if (y != 0 && y != d_height - 1) X return; X if (isblank) X return; X Clear(xs, y, xe, y); X} X X X/* X** X** here is all the copyright stuff X** X*/ X Xstatic void CopyrightProcess __P((char **, int *)); Xstatic void CopyrightRedisplayLine __P((int, int, int, int)); Xstatic void CopyrightAbort __P((void)); Xstatic void CopyrightSetCursor __P((void)); Xstatic void copypage __P((void)); X Xstruct copydata X{ X char *cps, *savedcps; /* position in the message */ X char *refcps, *refsavedcps; /* backup for redisplaying */ X}; X Xstatic struct LayFuncs CopyrightLf = X{ X CopyrightProcess, X CopyrightAbort, X CopyrightRedisplayLine, X DefClearLine, X DefRewrite, X CopyrightSetCursor, X DefResize, X DefRestore X}; X Xstatic const char cpmsg[] = "\ X\n\ XScreen version %v\n\ X\n\ XCopyright (c) 1993 Juergen Weigert, Michael Schroeder\n\ XCopyright (c) 1987 Oliver Laumann\n\ X\n\ XThis program is free software; you can redistribute it and/or \ Xmodify it under the terms of the GNU General Public License as published \ Xby the Free Software Foundation; either version 2, or (at your option) \ Xany later version.\n\ X\n\ XThis program is distributed in the hope that it will be useful, \ Xbut WITHOUT ANY WARRANTY; without even the implied warranty of \ XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the \ XGNU General Public License for more details.\n\ X\n\ XYou should have received a copy of the GNU General Public License \ Xalong with this program (see the file COPYING); if not, write to the \ XFree Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\ X\n\ XSend bugreports, fixes, enhancements, t-shirts, money, beer & pizza to \ Xscreen@uni-erlangen.de\n"; X X Xstatic void XCopyrightSetCursor() X{ X GotoPos(0, d_height - 1); X} X Xstatic void XCopyrightProcess(ppbuf, plen) Xchar **ppbuf; Xint *plen; X{ X int done = 0; X struct copydata *copydata; X X copydata = (struct copydata *)d_lay->l_data; X GotoPos(0, d_height - 1); X while (!done && *plen > 0) X { X switch (**ppbuf) X { X case ' ': X if (*copydata->cps) X { X copypage(); X break; X } X /* FALLTHROUGH */ X case '\r': X case '\n': X CopyrightAbort(); X done = 1; X break; X default: X break; X } X ++*ppbuf; X --*plen; X } X} X Xstatic void XCopyrightAbort() X{ X LAY_CALL_UP(Activate(0)); X ExitOverlayPage(); X} X Xvoid Xdisplay_copyright() X{ X struct copydata *copydata; X X if (d_width < 10 || d_height < 5) X { X Msg(0, "Window size too small for copyright page"); X return; X } X if (InitOverlayPage(sizeof(*copydata), &CopyrightLf, 0)) X return; X copydata = (struct copydata *)d_lay->l_data; X copydata->cps = (char *)cpmsg; X copydata->savedcps = 0; X copypage(); X} X Xstatic void Xcopypage() X{ X register char *cps; X char *ws; X int x, y, l; X char cbuf[80]; X struct copydata *copydata; X X copydata = (struct copydata *)d_lay->l_data; X SetAttrFont(0, ASCII); X ClearDisplay(); X x = y = 0; X cps = copydata->cps; X copydata->refcps = cps; X copydata->refsavedcps = copydata->savedcps; X while (*cps && y < d_height - 3) X { X ws = cps; X while (*cps == ' ') X cps++; X if (strncmp(cps, "%v", 2) == 0) X { X copydata->savedcps = cps + 2; X cps = version; X continue; X } X while (*cps && *cps != ' ' && *cps != '\n') X cps++; X l = cps - ws; X cps = ws; X if (l > d_width - 1) X l = d_width - 1; X if (x && x + l >= d_width - 2) X { X AddStr("\r\n"); X x = 0; X y++; X continue; X } X if (x) X { X AddChar(' '); X x++; X } X if (l) X AddStrn(ws, l); X x += l; X cps += l; X if (*cps == 0 && copydata->savedcps) X { X cps = copydata->savedcps; X copydata->savedcps = 0; X } X if (*cps == '\n') X { X AddStr("\r\n"); X x = 0; X y++; X } X if (*cps == ' ' || *cps == '\n') X cps++; X } X while (*cps == '\n') X cps++; X while (y++ < d_height - 2) X AddStr("\r\n"); X sprintf(cbuf,"[Press Space %s Return to end.]", X *cps ? "for next page;" : "or"); X centerline(cbuf); X SetLastPos(0, d_height-1); X copydata->cps = cps; X} X Xstatic void XCopyrightRedisplayLine(y, xs, xe, isblank) Xint y, xs, xe, isblank; X{ X if (y < 0) X { X struct copydata *copydata; X X copydata = (struct copydata *)d_lay->l_data; X copydata->cps = copydata->refcps; X copydata->savedcps = copydata->refsavedcps; X copypage(); X return; X } X if (y != 0 && y != d_height - 1) X return; X if (isblank) X return; X Clear(xs, y, xe, y); X} X Xvoid Xdisplay_displays() X{ X /* To be filled in... */ X} X END_OF_FILE if test 15145 -ne `wc -c <'help.c'`; then echo shar: \"'help.c'\" unpacked with wrong size! fi # end of 'help.c' fi if test -f 'os.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'os.h'\" else echo shar: Extracting \"'os.h'\" \(8724 characters\) sed "s/^X//" >'os.h' <<'END_OF_FILE' X/* Copyright (c) 1993 X * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) X * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) X * Copyright (c) 1987 Oliver Laumann X * X * This program is free software; you can redistribute it and/or modify X * it under the terms of the GNU General Public License as published by X * the Free Software Foundation; either version 2, or (at your option) X * any later version. X * X * This program is distributed in the hope that it will be useful, X * but WITHOUT ANY WARRANTY; without even the implied warranty of X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the X * GNU General Public License for more details. X * X * You should have received a copy of the GNU General Public License X * along with this program (see the file COPYING); if not, write to the X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. X * X **************************************************************** X * $Id: os.h,v 1.4 1993/08/05 14:23:53 mlschroe Exp $ FAU X */ X X#include X#include X#include X X#if defined(BSDI) || defined(__386BSD__) || defined(_CX_UX) X# include X#endif /* BSDI || __386BSD__ || _CX_UX */ X X#ifdef ISC X# ifdef ENAMETOOLONG X# undef ENAMETOOLONG X# endif X# ifdef ENOTEMPTY X# undef ENOTEMPTY X# endif X# include X#endif X X#ifdef hpux X# ifndef GETUTENT X# define GETUTENT 1 X# endif X#endif X X#ifndef linux /* all done in */ Xextern int errno; Xextern int sys_nerr; Xextern char *sys_errlist[]; X#endif /* linux */ X X#ifdef sun X# define getpgrp __getpgrp X# define exit __exit X#endif X X#ifdef POSIX X# include X# if defined(__STDC__) X# include X# endif /* __STDC__ */ X#endif /* POSIX */ X X#ifdef sun X# undef getpgrp X# undef exit X#endif /* sun */ X X#ifdef POSIX X# include X# ifdef hpux X# include X# endif /* hpux */ X# ifdef NCCS X# define MAXCC NCCS X# else X# define MAXCC 256 X# endif X#else /* POSIX */ X# ifdef TERMIO X# include X# ifdef NCC X# define MAXCC NCC X# else X# define MAXCC 256 X# endif X# else /* TERMIO */ X# include X# endif /* TERMIO */ X#endif /* POSIX */ X X#ifndef SYSV X# ifdef NEWSOS X# define strlen ___strlen___ X# include X# undef strlen X# else /* NEWSOS */ X# include X# endif /* NEWSOS */ X#else /* BSD */ X# if defined(SVR4) || defined(NEWSOS) X# define strlen ___strlen___ X# include X# undef strlen X# ifndef NEWSOS X extern size_t strlen(const char *); X# endif /* NEWSOS */ X# else /* SVR4 */ X# include X# endif /* SVR4 */ X#endif /* BSD */ X X#ifdef USEVARARGS X# if defined(__STDC__) X# include X# else X# include X# endif X#endif X X#if !defined(sun) && !defined(B43) && !defined(ISC) && !defined(pyr) && !defined(_CX_UX) X# include X#endif X#include X X#if (defined(TIOCGWINSZ) || defined(TIOCSWINSZ)) && defined(M_UNIX) X# include X# include X#endif X X#ifdef UTMPOK X# ifdef SVR4 X# include X# define UTMPFILE UTMPX_FILE X# define utmp utmpx X# define getutent getutxent X# define getutid getutxid X# define getutline getutxline X# define pututline pututxline X# define setutent setutxent X# define endutent endutxent X# define ut_time ut_xtime X# else /* SVR4 */ X# include X# endif /* SVR4 */ X# if defined(apollo) || defined(linux) X /* X * We don't have GETUTENT, so we dig into utmp ourselves. X * But we save the permanent filedescriptor and X * open utmp just when we need to. X * This code supports an unsorted utmp. jw. X */ X# define UTNOKEEP X# endif /* apollo || linux */ X#endif X X#ifndef UTMPFILE X# ifdef UTMP_FILE X# define UTMPFILE UTMP_FILE X# else X# ifdef _PATH_UTMP X# define UTMPFILE _PATH_UTMP X# else X# define UTMPFILE "/etc/utmp" X# endif /* _PATH_UTMP */ X# endif X#endif X X#ifndef UTMPOK X# ifdef USRLIMIT X# undef USRLIMIT X# endif X#endif X X#ifdef LOGOUTOK X# ifndef LOGINDEFAULT X# define LOGINDEFAULT 0 X# endif X#else X# undef LOGINDEFAULT X# define LOGINDEFAULT 1 X#endif X X#ifndef F_OK X#define F_OK 0 X#endif X#ifndef X_OK X#define X_OK 1 X#endif X#ifndef W_OK X#define W_OK 2 X#endif X#ifndef R_OK X#define R_OK 4 X#endif X X#ifndef S_IFIFO X#define S_IFIFO 0010000 X#endif X#ifndef S_IREAD X#define S_IREAD 0000400 X#endif X#ifndef S_IWRITE X#define S_IWRITE 0000200 X#endif X#ifndef S_IEXEC X#define S_IEXEC 0000100 X#endif X X#if defined(S_IFIFO) && defined(S_IFMT) && !defined(S_ISFIFO) X#define S_ISFIFO(mode) ((mode & S_IFMT) == S_IFIFO) X#endif X#if defined(S_IFSOCK) && defined(S_IFMT) && !defined(S_ISSOCK) X#define S_ISSOCK(mode) ((mode & S_IFMT) == S_IFSOCK) X#endif X X#ifndef TERMCAP_BUFSIZE X# define TERMCAP_BUFSIZE 1024 X#endif X X#ifndef MAXPATHLEN X# define MAXPATHLEN 1024 X#endif X X#ifndef SIG_T_DEFINED X# ifdef SIGVOID X# if defined(ultrix) X# define sig_t void X# else /* nice compilers: */ X typedef void sig_t; X# endif X# else X typedef int sig_t; /* (* sig_t) */ X# endif X#else X# if defined (__alpha) X# define sig_t void /* From: Dietrich Wiegandt */ X# endif X#endif /* SIG_T_DEFINED */ X X#if defined(SVR4) || (defined(SYSV) && defined(ISC)) || defined(_AIX) || defined(linux) || defined(ultrix) || defined(__386BSD__) || defined(BSDI) X# define SIGPROTOARG (int) X# define SIGDEFARG int sigsig X# define SIGARG 0 X#else X# define SIGPROTOARG (void) X# define SIGDEFARG X# define SIGARG X#endif X X#ifndef SIGCHLD X#define SIGCHLD SIGCLD X#endif X X#ifdef USESIGSET X# define signal sigset X#endif /* USESIGSET */ X X#ifndef PID_T_DEFINED Xtypedef int pid_t; X#endif X X#ifndef UID_T_DEFINED Xtypedef int gid_t; Xtypedef int uid_t; X#endif X X#ifdef GETUTENT X typedef char *slot_t; X#else X typedef int slot_t; X#endif X X#ifdef SYSV X# define index strchr X# define rindex strrchr X# define bzero(poi,len) memset(poi,0,len) X# define bcmp memcmp X# define killpg(pgrp,sig) kill( -(pgrp), sig) X#endif /* SYSV */ X X#ifndef USEBCOPY X# ifdef USEMEMCPY X# define bcopy(s,d,len) memcpy(d,s,len) X# else X# ifdef USEMEMMOVE X# define bcopy(s,d,len) memmove(d,s,len) X# else X# define NEED_OWN_BCOPY X# endif X# endif X#endif X X#if defined(_POSIX_SOURCE) && defined(ISC) X# ifndef O_NDELAY X# define O_NDELAY O_NONBLOCK X# endif X#endif X X#ifdef hpux X# define setreuid(ruid, euid) setresuid(ruid, euid, -1) X# define setregid(rgid, egid) setresgid(rgid, egid, -1) X#endif X X#if (!defined(sysV68) && !defined(M_XENIX)) || defined(NeXT) X# include X#endif X X#ifndef WTERMSIG X# ifndef BSDWAIT /* if wait is NOT a union: */ X# define WTERMSIG(status) (status & 0177) X# else X# define WTERMSIG(status) status.w_T.w_Termsig X# endif X#endif X X#ifndef WSTOPSIG X# ifndef BSDWAIT /* if wait is NOT a union: */ X# define WSTOPSIG(status) ((status >> 8) & 0377) X# else X# define WSTOPSIG(status) status.w_S.w_Stopsig X# endif X#endif X X/* NET-2 uses WCOREDUMP */ X#if defined(WCOREDUMP) && !defined(WIFCORESIG) X# define WIFCORESIG(status) WCOREDUMP(status) X#endif X X#ifndef WIFCORESIG X# ifndef BSDWAIT /* if wait is NOT a union: */ X# define WIFCORESIG(status) (status & 0200) X# else X# define WIFCORESIG(status) status.w_T.w_Coredump X# endif X#endif X X#ifndef WEXITSTATUS X# ifndef BSDWAIT /* if wait is NOT a union: */ X# define WEXITSTATUS(status) ((status >> 8) & 0377) X# else X# define WEXITSTATUS(status) status.w_T.w_Retcode X# endif X#endif X X#if defined(M_XENIX) || defined(M_UNIX) || defined(_SEQUENT_) X#include /* for timeval + FD... */ X#endif X X X/* X * SunOS 3.5 - Tom Schmidt - Micron Semiconductor, Inc - 27-Jul-93 X * tschmidt@vax.micron.com X */ X#ifndef FD_SET X# ifdef SUNOS3 Xtypedef struct fd_set X{ X int fds_bits[1]; X} fd_set; X# endif X# define FD_ZERO(fd) ((fd)->fds_bits[0] = 0) X# define FD_SET(b, fd) ((fd)->fds_bits[0] |= 1 << (b)) X# define FD_ISSET(b, fd) ((fd)->fds_bits[0] & 1 << (b)) X# define FD_SETSIZE 32 X#endif X X X#if defined(sgi) X/* on IRIX, regardless of the stream head's read mode (RNORM/RMSGN/RMSGD) X * TIOCPKT mode causes data loss if our buffer is too small (IOSIZE) X * to hold the whole packet at first read(). X * (Marc Boucher) X */ X# undef TIOCPKT X#endif X X#if !defined(VDISABLE) X# ifdef _POSIX_VDISABLE X# define VDISABLE _POSIX_VDISABLE X# else X# define VDISABLE 0377 X# endif /* _POSIX_VDISABLE */ X#endif /* !VDISABLE */ X X#if !defined(FNDELAY) && defined(O_NDELAY) X# define FNDELAY O_NDELAY X#endif X X/*typedef long off_t; */ /* Someone might need this */ X X X/* X * 4 <= IOSIZE <=1000 X * you may try to vary this value. Use low values if your (VMS) system X * tends to choke when pasting. Use high values if you want to test X * how many characters your pty's can buffer. X */ X#define IOSIZE 4096 X X/* used in screen.c and attacher.c */ X#if !defined(NSIG) /* kbeal needs these w/o SYSV */ X# define NSIG 32 X#endif /* !NSIG */ X END_OF_FILE if test 8724 -ne `wc -c <'os.h'`; then echo shar: \"'os.h'\" unpacked with wrong size! fi # end of 'os.h' fi if test -f 'patchlevel.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'patchlevel.h'\" else echo shar: Extracting \"'patchlevel.h'\" \(7856 characters\) sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE' X/* Copyright (c) 1993 X * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) X * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) X * Copyright (c) 1987 Oliver Laumann X * X * This program is free software; you can redistribute it and/or modify X * it under the terms of the GNU General Public License as published by X * the Free Software Foundation; either version 2, or (at your option) X * any later version. X * X * This program is distributed in the hope that it will be useful, X * but WITHOUT ANY WARRANTY; without even the implied warranty of X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the X * GNU General Public License for more details. X * X * You should have received a copy of the GNU General Public License X * along with this program (see the file COPYING); if not, write to the X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. X * X **************************************************************** X * $Id: patchlevel.h,v 1.8 1993/08/05 14:23:58 mlschroe Exp $ FAU X */ X X/**************************************************************** X * X * patchlevel.h: Our life story. X * X * 08.07.91 -- 3.00.01 -wipe and a 'setenv TERM dumb' bugfix. X * 17.07.91 -- 3.00.02 another patchlevel by Wayne Davison X * 31.07.91 -- 3.00.03 E0, S0, C0 for flexible semi-graphics, nonblocking X * window title input and 'C-a :' command input. X * 10.08.91 -- 3.00.04 scrollback, markkeys and some bugfixes. X * 13.08.91 -- 3.00.05 mark routine improved, ansi prototypes added. X * 20.08.91 -- 3.00.06 screen -h, faster GotoPos in overlay, termcap %. X * instead of %c X * 28.08.91 -- 3.00.07 environment variable support. security. terminfo. X * pyramid and ultrix support. X * 07.09.91 -- 3.00.99 secopen(), MIPS support, SVR4 support. X * 09.09.91 -- 3.01.00 backspace bug fixed. X * 03.10.91 -- 3.01.01 ansi.c: null-ptr fixed, CLS now saves to scrollback. X * Using setresuid on hpux. Memory leak fixed. X * Better GotoPos(). Support for IC. Another resize bug. X * Detach() w/o fore crashed. -T and -A(dapt) option. X * GNU copyleft. X * 19.12.91 -- 3.01.02 flow now really automatic (autoflow killed). X * 7 bit restriction removed from WriteString(). X * 09.01.92 -- 3.01.03 flow reattach bug fixed. VDISCARD bug fixed. X * 13.01.92 -- 3.01.04 new flow concept: ^Af toggles now three states X * 21.01.92 -- 3.01.05 '^A:screen 11' bug fixed. aflag in DoScreen(). X * Some code cleanup. attach_tty and display_tty[] X * added. X * 26.01.92 -- 3.01.06 apollo support, "hardcopy_append on", "bufferfile", X * SECURITY PROBLEM cleared.. X * 28.01.92 -- 3.01.07 screen after su allowed. Pid became part of X * SockName. sysvish 14 character restriction considered. X * 31.01.92 -- 3.02.00 Ultrix port, Irix 3.3 SGI port, shadow pw support, X * data loss on stdin overflow fixed. "refresh off". X * 12.02.92 -- 3.02.02 stripdev() moved, -S introduced, bufferfile improved, X * ShellProg coredump cleared. SVR4 bugfixes. X * I/O code speedup added. X * 24.04.92 -- 3.02.03 perfectly stackable overlays. One scrollback per window, X * not per display. X * 05.05.92 -- 3.02.04 very nasty initialisation bug fixed. X * 09.05.92 -- 3.02.05 parsing for $:cl: termcap strings and \012 octal notation X * in screenrc file. More structuring. Detached startup X * with 'screen -d -m -S...' bugfixed. X * 11.05.92 -- 3.02.06 setreuid() bugs cleared, C-a : setenv added. X * "xn" capability in TERMCAP needed since "am" is there. X * 25.06.92 -- 3.02.07 The multi display test version. Have merci. X * 15.07.92 -- 3.02.08 :B8: supports automatic charset switching for 8-bit X * 26.09.92 -- 3.02.09 Ported to linux. Ignoring bad files in $SCREENDIR X * 22.10.92 -- 3.02.10 screen.c/ansi.c splitted in several pieces. X * Better ISearch. Cleanup of loadav.c X * 29.10.92 -- 3.02.11 Key mechanism rewritten. New command names. X * New iscreenrc syntax. X * 02.11.92 -- 3.02.12 'bind g copy_reg' and 'bind x ins_reg' as suggested by X * stillson@tsfsrv.mitre.org (Ken Stillson). X * 03.11.92 -- 3.02.13 Ported to SunOs 4.1.2. Gulp. Some NULL ptrs fixed and X * misc. braindamage fixed. X * 03.11.92 -- 3.02.14 Argument number checking, AKA fixed. X * 05.11.92 -- 3.02.15 Memory leaks in Detach() and KillWindow() fixed. X * Lockprg powerdetaches on SIGHUP. X * 12.11.92 -- 3.02.16 Introduced two new termcaps: "CS" and "CE". X * (Switch cursorkeys in application mode) X * Tim's async output patch. X * Fixed an ugly bug in WriteString(). X * New command: 'process' X * 16.11.92 -- 3.02.17 Nuking unsent tty output is now optional, (toxic X * ESC radiation). X * 30.11.92 -- 3.02.18 Lots of multi display bugs fixed. New layer X * function 'Restore'. MULTIUSER code cleanup. X * Rudimental acls added for multiuser. X * No more error output, when output gives write errors. X * 02.12.92 -- 3.02.19 BROKEN_PIPE and SOCK_NOT_IN_FS defines added for X * braindead systems. Bug in recover socket code fixed. X * Can create windows again from shell. X * 22.12.92 -- 3.02.20 Made a superb configure script. STY and break fixed. X * 01.02.93 -- 3.02.21 Coredump bug fixed: 8-bit output in background windows. X * Console grabbing somewhat more useable. X * 23.02.93 -- 3.02.22 Added ^:exec command, but not tested at all. X * 23.02.93 -- 3.02.23 Added 'hardcopydir' and 'logdir' commands. X * 11.03.93 -- 3.02.24 Prefixed display and window structure elements. X * Screen now handles autowrapped lines correctly X * in the redisplay and mark function. X * 19.03.93 -- 3.03.00 Patched for BSD386. pseudos work. X * 31.03.93 -- 3.03.01 Don't allocate so much empty attr and font lines. X * 04.04.93 -- 3.03.02 fixed :exec !..| less and :|less, patched BELL_DONE & X * ^B/^F. Fixed auto_nuke attribute resetting. Better linux X * configure. ^AW shows '&' when window has other attacher. X * MAXWIN > 10 patch. KEEP_UNDEF in config.h.in, shellaka X * bug fixed. dec alpha port. Solaris port. X * 02.05.93 -- 3.03.03 Configure tweaked for sgi. Update environment with X * setenv command. Silence on|off, silencewait , X * defautonuke commands added. Manual page updated. X * 13.05.93 -- 3.03.04 exit in newsyntax script, finished _CX_UX port. X * Texinfo page added by Jason Merrill. Much longish debug X * output removed. Select window by title (or number). X * 16.06.93 -- 3.04.00 Replaced ^A- by ^A^H to be complementary to ^A SPACE. X * Moved into CVS. Yacc. X * 28.06.93 -- 3.04.01 Fixed selecting windows with numeric title. Silence X * now works without nethackoption set. X * 01.07.93 -- 3.04.02 Implementing real acls. X * 22.07.93 -- 3.05.00 Fixed SVR4, some multiuser bugs, -- DISTRIBUTED X * 08.08.93 -- 3.05.01 ${srcdir} feature added. Shellprog bug fixed. X * Motorola reattach bug fixed. Writelock bug fixed. X * Copybuffer moved into struct user. Configure.in X * uglified for Autoconf1.5. Paste may now have an X * argument. Interactive setenv. Right margin bug X * fixed. IRIX 5 patches. -- DISTRIBUTED X */ X X#define ORIGIN "FAU" X#define REV 3 X#define VERS 5 X#define PATCHLEVEL 1 X#define DATE "8-Aug-93" X#define STATE "" END_OF_FILE if test 7856 -ne `wc -c <'patchlevel.h'`; then echo shar: \"'patchlevel.h'\" unpacked with wrong size! fi # end of 'patchlevel.h' fi if test -f 'resize.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'resize.c'\" else echo shar: Extracting \"'resize.c'\" \(13731 characters\) sed "s/^X//" >'resize.c' <<'END_OF_FILE' X/* Copyright (c) 1993 X * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) X * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) X * Copyright (c) 1987 Oliver Laumann X * X * This program is free software; you can redistribute it and/or modify X * it under the terms of the GNU General Public License as published by X * the Free Software Foundation; either version 2, or (at your option) X * any later version. X * X * This program is distributed in the hope that it will be useful, X * but WITHOUT ANY WARRANTY; without even the implied warranty of X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the X * GNU General Public License for more details. X * X * You should have received a copy of the GNU General Public License X * along with this program (see the file COPYING); if not, write to the X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. X * X **************************************************************** X */ X X#include "rcs.h" XRCS_ID("$Id: resize.c,v 1.3 1993/08/04 00:42:51 mlschroe Exp $ FAU") X X#include X#include X#include X#ifndef sun X#include X#endif X X#ifdef ISC X# include X# include X# include X#endif X X#include "config.h" X#include "screen.h" X#include "extern.h" X Xstatic void CheckMaxSize __P((int)); Xstatic int ResizeScreenArray __P((struct win *, char ***, int, int, int)); Xstatic void FreeArray __P((char ***, int)); X#ifdef COPY_PASTE Xstatic int ResizeHistArray __P((struct win *, char ***, int, int, int)); Xstatic void FreeScrollback __P((struct win *)); X#endif X Xextern int maxwidth; Xextern struct display *display, *displays; Xextern char *blank, *null, *OldImage, *OldAttr; Xextern char *OldFont; Xextern struct win *windows; Xextern int Z0width, Z1width; X X#ifdef NETHACK Xextern int nethackflag; X#endif X X#if defined(TIOCGWINSZ) || defined(TIOCSWINSZ) X struct winsize glwz; X#endif X X/* X * ChangeFlag: 0: try to modify no window X * 1: modify fore (and try to modify no d_other) + redisplay X * 2: modify all windows X * X * Note: Activate() is only called if change_flag == 1 X * i.e. on a WINCH event X */ X Xvoid XCheckScreenSize(change_flag) Xint change_flag; X{ X int wi, he; X struct win *p; X struct layer *oldlay; X X if (display == 0) X { X debug("CheckScreenSize: No display -> no check.\n"); X return; X } X oldlay = d_lay; X#ifdef TIOCGWINSZ X if (ioctl(d_userfd, TIOCGWINSZ, (char *)&glwz) != 0) X { X debug2("CheckScreenSize: ioctl(%d, TIOCGWINSZ) errno %d\n", d_userfd, errno); X wi = CO; X he = LI; X } X else X { X wi = glwz.ws_col; X he = glwz.ws_row; X if (wi == 0) X wi = CO; X if (he == 0) X he = LI; X } X#else X wi = CO; X he = LI; X#endif X X debug2("CheckScreenSize: screen is (%d,%d)\n", wi, he); X X if (change_flag == 2) X { X debug("Trying to adapt all windows (-A)\n"); X for (p = windows; p; p = p->w_next) X if (p->w_display == 0 || p->w_display == display) X ChangeWindowSize(p, wi, he); X } X if (d_width == wi && d_height == he) X { X debug("CheckScreenSize: No change -> return.\n"); X return; X } X ChangeScreenSize(wi, he, change_flag); X if (change_flag == 1) X Activate(d_fore ? d_fore->w_norefresh : 0); X if (d_lay != oldlay) X { X#ifdef NETHACK X if (nethackflag) X Msg(0, "KAABLAMM!!! You triggered a land mine!"); X else X#endif X Msg(0, "Aborted because of window size change."); X } X} X Xvoid XChangeScreenSize(wi, he, change_fore) Xint wi, he; Xint change_fore; X{ X struct win *p; X int wwi; X X if (d_width == wi && d_height == he) X { X debug("ChangeScreenSize: no change\n"); X return; X } X debug2("ChangeScreenSize from (%d,%d) ", d_width, d_height); X debug3("to (%d,%d) (change_fore: %d)\n",wi, he, change_fore); X d_width = wi; X d_height = he; X X CheckMaxSize(wi); X if (CWS) X { X d_defwidth = CO; X d_defheight = LI; X } X else X { X if (CZ0 && (wi == Z0width || wi == Z1width) && X (CO == Z0width || CO == Z1width)) X d_defwidth = CO; X else X d_defwidth = wi; X d_defheight = he; X } X debug2("Default size: (%d,%d)\n", d_defwidth, d_defheight); X if (change_fore) X DoResize(wi, he); X if (CWS == NULL && displays->_d_next == 0) X { X /* adapt all windows - to be removed ? */ X for (p = windows; p; p = p->w_next) X { X debug1("Trying to change window %d.\n", p->w_number); X wwi = wi; X if (CZ0 && (wi == Z0width || wi == Z1width)) X { X if (p->w_width > (Z0width + Z1width) / 2) X wwi = Z0width; X else X wwi = Z1width; X } X ChangeWindowSize(p, wwi, he); X } X } X} X Xvoid XDoResize(wi, he) Xint wi, he; X{ X struct layer *oldlay; X int q = 0; X X for(;;) X { X oldlay = d_lay; X for (; d_lay; d_lay = d_lay->l_next) X { X d_layfn = d_lay->l_layfn; X if ((q = Resize(wi, he))) X break; X } X d_lay = oldlay; X d_layfn = d_lay->l_layfn; X if (q == 0) X break; X ExitOverlayPage(); X } X} X X#ifdef COPY_PASTE X Xint XChangeScrollback(p, histheight, histwidth) Xstruct win *p; Xint histheight, histwidth; X{ X if (histheight > MAXHISTHEIGHT) X histheight = MAXHISTHEIGHT; X debug2("ChangeScrollback(..., %d, %d)\n", histheight, histwidth); X debug2(" was %d, %d\n", p->w_histheight, p->w_width); X X if (histheight == 0) X { X FreeScrollback(p); X return 0; X } X X if (ResizeHistArray(p, &p->w_ihist, histwidth, histheight, 1) X || ResizeHistArray(p, &p->w_ahist, histwidth, histheight, 0) X || ResizeHistArray(p, &p->w_fhist, histwidth, histheight, 0)) X { X debug(" failed, removing all histbuf\n"); X FreeScrollback(p); X Msg(0, strnomem); X return -1; X } X if (p->w_histheight != histheight) X p->w_histidx = 0; X p->w_histheight = histheight; X X return 0; X} X Xstatic void XFreeScrollback(p) Xstruct win *p; X{ X FreeArray(&p->w_ihist, p->w_histheight); X FreeArray(&p->w_ahist, p->w_histheight); X FreeArray(&p->w_fhist, p->w_histheight); X p->w_histheight = 0; X} X Xstatic int XResizeHistArray(p, arr, wi, hi, fillblank) Xstruct win *p; Xchar ***arr; Xint wi, hi, fillblank; X{ X char **narr, **np, **onp, **onpe; X int t, x, first; X X if (p->w_width == wi && p->w_histheight == hi) X return(0); X if (p->w_histheight != hi) X { X if ((narr = (char **)calloc(sizeof(char *), hi)) == NULL) X { X FreeArray(arr, p->w_histheight); X return(-1); X } X np = narr; X onp = (*arr) + p->w_histidx; X onpe = (*arr) + p->w_histheight; X first = p->w_histheight - hi; X if (first < 0) X np -= first; X for(t = 0; t < p->w_histheight; t++) X { X ASSERT(*onp); X if (t - first >= 0 && t - first < hi) X *np++ = *onp; X else if (*onp != null) X free(*onp); X if (++onp == onpe) X onp = *arr; X } X if (*arr) X free(*arr); X } X else X narr = *arr; X X for (t=0, np=narr; t < hi; t++, np++) X { X if ((!fillblank && *np == 0) || *np == null) X { X *np = null; X continue; X } X x = p->w_width; X if (*np == 0) X { X *np = (char *)malloc(wi + 1); X x = 0; X } X else if (p->w_width != wi) X { X *np = (char *)xrealloc(*np, wi + 1); X } X if (*np == 0) X { X FreeArray(&narr, hi); X return -1; X } X if (x > wi) X x = wi; X if (fillblank) X bclear(*np + x, wi + 1 - x); X else X bzero(*np + x, wi + 1 - x); X } X *arr = narr; X return 0; X} X#endif /* COPY_PASTE */ X X Xstatic int XResizeScreenArray(p, arr, wi, hi, fillblank) Xstruct win *p; Xchar ***arr; Xint wi, hi, fillblank; X{ X int minr; X char **cp; X X if (p->w_width == wi && p->w_height == hi) X return(0); X X if (hi > p->w_height) X minr = p->w_height; X else X minr = hi; X X if (p->w_height > hi) X { X for (cp = *arr; cp < *arr + (p->w_height - hi); cp++) X if (*cp != null) X free(*cp); X bcopy((char *)(*arr + (p->w_height - hi)), (char *)(*arr), X hi * sizeof(char *)); X } X if (*arr && p->w_width != wi) X for (cp = *arr; cp < *arr + minr; cp++) X { X int x = p->w_width; X X if (*cp == null) X continue; X if ((*cp = (char *)xrealloc(*cp, (unsigned) wi + 1)) == 0) X { X FreeArray(arr, p->w_height); X return(-1); X } X if (x > wi) X x = wi; X if (fillblank) X bclear(*cp + x, wi + 1 - x); X else X bzero(*cp + x, wi + 1 - x); X } X if (*arr) X *arr = (char **) xrealloc((char *) *arr, (unsigned) hi * sizeof(char *)); X else X *arr = (char **) malloc((unsigned) hi * sizeof(char *)); X if (*arr == NULL) X return -1; X for (cp = *arr + p->w_height; cp < *arr + hi; cp++) X { X if (!fillblank) X { X *cp = null; X continue; X } X if ((*cp = malloc((unsigned) wi + 1)) == 0) X { X while (--cp >= *arr) X free(*cp); X free(*arr); X *arr = NULL; X return -1; X } X bclear(*cp, wi + 1); X } X return 0; X} X Xstatic void XFreeArray(arr, hi) Xchar ***arr; Xint hi; X{ X register char **p; X register int t; X X if (*arr == 0) X return; X for (t = hi, p = *arr; t--; p++) X if (*p && *p != null) X free(*p); X free(*arr); X *arr = 0; X} X X Xstatic void XCheckMaxSize(wi) Xint wi; X{ X char *oldnull = null; X struct win *p; X int i; X X wi = ((wi + 1) + 255) & ~255; X if (wi <= maxwidth) X return; X maxwidth = wi; X debug1("New maxwidth: %d\n", maxwidth); X if (blank == 0) X blank = malloc((unsigned) maxwidth); X else X blank = xrealloc(blank, (unsigned) maxwidth); X if (null == 0) X null = malloc((unsigned) maxwidth); X else X null = xrealloc(null, (unsigned) maxwidth); X if (OldImage == 0) X OldImage = malloc((unsigned) maxwidth); X else X OldImage = xrealloc(OldImage, (unsigned) maxwidth); X if (OldAttr == 0) X OldAttr = malloc((unsigned) maxwidth); X else X OldAttr = xrealloc(OldAttr, (unsigned) maxwidth); X if (OldFont == 0) X OldFont = malloc((unsigned) maxwidth); X else X OldFont = xrealloc(OldFont, (unsigned) maxwidth); X if (!(blank && null && OldImage && OldAttr && OldFont)) X { X Panic(0, "Out of memory -> Game over!!"); X /*NOTREACHED*/ X } X MakeBlankLine(blank, maxwidth); X bzero(null, maxwidth); X X /* We have to run through all windows to substitute X * the null references. X */ X for (p = windows; p; p = p->w_next) X { X for (i = 0; i < p->w_height; i++) X { X if (p->w_attr[i] == oldnull) X p->w_attr[i] = null; X if (p->w_font[i] == oldnull) X p->w_font[i] = null; X } X#ifdef COPY_PASTE X for (i = 0; i < p->w_histheight; i++) X { X if (p->w_ahist[i] == oldnull) X p->w_ahist[i] = null; X if (p->w_fhist[i] == oldnull) X p->w_fhist[i] = null; X } X#endif X } X} X X Xint XChangeWindowSize(p, wi, he) Xstruct win *p; Xint wi, he; X{ X int t, scr; X X CheckMaxSize(wi); X X if (wi == p->w_width && he == p->w_height) X { X debug("ChangeWindowSize: No change.\n"); X return 0; X } X X debug2("ChangeWindowSize from (%d,%d) to ", p->w_width, p->w_height); X debug2("(%d,%d)\n", wi, he); X if (p->w_lay != &p->w_winlay) X { X debug("ChangeWindowSize: No resize because of overlay.\n"); X return -1; X } X if (wi == 0 && he == 0) X { X FreeArray(&p->w_image, p->w_height); X FreeArray(&p->w_attr, p->w_height); X FreeArray(&p->w_font, p->w_height); X if (p->w_tabs) X free(p->w_tabs); X p->w_tabs = NULL; X p->w_width = 0; X p->w_height = 0; X#ifdef COPY_PASTE X FreeScrollback(p); X#endif X return 0; X } X X /* when window gets smaller, scr is the no. of lines we scroll up */ X scr = p->w_height - he; X if (scr < 0) X scr = 0; X#ifdef COPY_PASTE X for (t = 0; t < scr; t++) X AddLineToHist(p, p->w_image+t, p->w_attr+t, p->w_font+t); X#endif X if (ResizeScreenArray(p, &p->w_image, wi, he, 1) X || ResizeScreenArray(p, &p->w_attr, wi, he, 0) X || ResizeScreenArray(p, &p->w_font, wi, he, 0)) X { Xnomem: KillWindow(p); X Msg(0, "Out of memory -> Window destroyed !!"); X return -1; X } X /* this won't change the d_height of the scrollback history buffer, but X * it will check the d_width of the lines. X */ X#ifdef COPY_PASTE X ChangeScrollback(p, p->w_histheight, wi); X#endif X X if (p->w_tabs == 0) X { X /* tabs get d_width+1 because 0 <= x <= wi */ X if ((p->w_tabs = malloc((unsigned) wi + 1)) == 0) X goto nomem; X t = 8; X } X else X { X if ((p->w_tabs = xrealloc(p->w_tabs, (unsigned) wi + 1)) == 0) X goto nomem; X t = p->w_width; X } X for (t = (t + 7) & 8; t < wi; t += 8) X p->w_tabs[t] = 1; X p->w_height = he; X p->w_width = wi; X if (p->w_x >= wi) X p->w_x = wi - 1; X if ((p->w_y -= scr) < 0) X p->w_y = 0; X if (p->w_Saved_x >= wi) X p->w_Saved_x = wi - 1; X if ((p->w_Saved_y -= scr) < 0) X p->w_Saved_y = 0; X if (p->w_autoaka > 0) X if ((p->w_autoaka -= scr) < 1) X p->w_autoaka = 1; X p->w_top = 0; X p->w_bot = he - 1; X#ifdef TIOCSWINSZ X if (p->w_ptyfd && p->w_pid) X { X glwz.ws_col = wi; X glwz.ws_row = he; X debug("Setting pty winsize.\n"); X if (ioctl(p->w_ptyfd, TIOCSWINSZ, (char *)&glwz)) X debug2("SetPtySize: errno %d (fd:%d)\n", errno, p->w_ptyfd); X# if defined(STUPIDTIOCSWINSZ) && defined(SIGWINCH) X# ifdef POSIX X pgrp = tcgetpgrp(p->w_ptyfd); X# else /* POSIX */ X if (ioctl(p->w_ptyfd, TIOCGPGRP, (char *)&pgrp)) X pgrp = 0; X# endif /* POSIX */ X if (pgrp) X { X debug1("Sending SIGWINCH to pgrp %d.\n", pgrp); X if (killpg(pgrp, SIGWINCH)) X debug1("killpg: errno %d\n", errno); X } X else X debug1("Could not get pgrp: errno %d\n", errno); X# endif /* STUPIDTIOCSWINSZ */ X } X#endif /* TIOCSWINSZ */ X return 0; X} X X Xchar * Xxrealloc(mem, len) Xchar *mem; Xint len; X{ X register char *nmem; X X if ((nmem = realloc(mem, len))) X return(nmem); X free(mem); X return((char *)0); X} END_OF_FILE if test 13731 -ne `wc -c <'resize.c'`; then echo shar: \"'resize.c'\" unpacked with wrong size! fi # end of 'resize.c' fi if test -f 'search.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'search.c'\" else echo shar: Extracting \"'search.c'\" \(7998 characters\) sed "s/^X//" >'search.c' <<'END_OF_FILE' X/* Copyright (c) 1993 X * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) X * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) X * Copyright (c) 1987 Oliver Laumann X * X * This program is free software; you can redistribute it and/or modify X * it under the terms of the GNU General Public License as published by X * the Free Software Foundation; either version 2, or (at your option) X * any later version. X * X * This program is distributed in the hope that it will be useful, X * but WITHOUT ANY WARRANTY; without even the implied warranty of X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the X * GNU General Public License for more details. X * X * You should have received a copy of the GNU General Public License X * along with this program (see the file COPYING); if not, write to the X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. X * X **************************************************************** X */ X X#include "rcs.h" XRCS_ID("$Id: search.c,v 1.1.1.1 1993/06/16 23:51:17 jnweiger Exp $ FAU") X X#include X X#include "config.h" X#include "screen.h" X#include "mark.h" X#include "extern.h" X X#ifdef COPY_PASTE X Xextern struct win *fore; Xextern struct display *display; X X/******************************************************************** X * VI style Search X */ X Xstatic int matchword __P((char *, int, int, int)); Xstatic void searchend __P((char *, int)); Xstatic void backsearchend __P((char *, int)); X Xvoid XSearch(dir) Xint dir; X{ X struct markdata *markdata; X if (dir == 0) X { X markdata = (struct markdata *)d_lay->l_data; X if (markdata->isdir > 0) X searchend(0, 0); X else if (markdata->isdir < 0) X backsearchend(0, 0); X else X Msg(0, "No previous pattern"); X } X else X Input((dir > 0 ? "/" : "?"), sizeof(markdata->isstr)-1, (dir > 0 ? searchend : backsearchend), INP_COOKED); X} X Xstatic void Xsearchend(buf, len) Xchar *buf; Xint len; X{ X int x = 0, sx, ex, y; X struct markdata *markdata; X X markdata = (struct markdata *)d_lay->l_data; X markdata->isdir = 1; X if (len) X strcpy(markdata->isstr, buf); X sx = markdata->cx + 1; X ex = d_width - 1; X for (y = markdata->cy; y < fore->w_histheight + d_height; y++, sx = 0) X { X if ((x = matchword(markdata->isstr, y, sx, ex)) >= 0) X break; X } X if (y >= fore->w_histheight + d_height) X { X GotoPos(markdata->cx, W2D(markdata->cy)); X Msg(0, "Pattern not found"); X } X else X revto(x, y); X} X Xstatic void Xbacksearchend(buf, len) Xchar *buf; Xint len; X{ X int sx, ex, x = -1, y; X struct markdata *markdata; X X markdata = (struct markdata *)d_lay->l_data; X markdata->isdir = -1; X if (len) X strcpy(markdata->isstr, buf); X ex = markdata->cx - 1; X for (y = markdata->cy; y >= 0; y--, ex = d_width - 1) X { X sx = 0; X while ((sx = matchword(markdata->isstr, y, sx, ex)) >= 0) X x = sx++; X if (x >= 0) X break; X } X if (y < 0) X { X GotoPos(markdata->cx, W2D(markdata->cy)); X Msg(0, "Pattern not found"); X } X else X revto(x, y); X} X Xstatic int Xmatchword(pattern, y, sx, ex) Xchar *pattern; Xint y, sx, ex; X{ X char *ip, *ipe, *cp, *pp; X X ip = iWIN(y) + sx; X ipe = iWIN(y) + d_width; X for (;sx <= ex; sx++) X { X cp = ip++; X pp = pattern; X while (*cp++ == *pp++) X if (*pp == 0) X return sx; X else if (cp == ipe) X break; X } X return -1; X} X X X/******************************************************************** X * Emacs style ISearch X */ X Xstatic char *isprompts[] = { X "I-search backward: ", "failing I-search backward: ", X "I-search: ", "failing I-search: " X}; X X Xstatic int is_redo __P((struct markdata *)); Xstatic void is_process __P((char *, int)); Xstatic int is_bm __P((char *, int, int, int, int)); X X Xstatic int Xis_bm(str, l, p, end, dir) Xchar *str; Xint l, p, end, dir; X{ X int tab[256]; X int i, q; X char *s, c; X int w = d_width; X X debug2("is_bm: searching for %s len %d\n", str, l); X debug3("start at %d end %d dir %d\n", p, end, dir); X if (p < 0 || p + l > end) X return -1; X if (l == 0) X return p; X if (dir < 0) X str += l - 1; X for (i = 0; i < 256; i++) X tab[i] = l * dir; X for (i = 0; i < l - 1; i++, str += dir) X tab[(int)(unsigned char) *str] = (l - 1 - i) * dir; X if (dir > 0) X p += l - 1; X debug1("first char to match: %c\n", *str); X while (p >= 0 && p < end) X { X q = p; X s = str; X for (i = 0;;) X { X c = iWIN(q / w)[q % w]; X if (i == 0) X p += tab[(int)(unsigned char) c]; X if (c != *s) X break; X q -= dir; X s -= dir; X if (++i == l) X return q + (dir > 0 ? 1 : -l); X } X } X return -1; X} X X X/*ARGSUSED*/ Xstatic void Xis_process(p, n) Xchar *p; Xint n; X{ X int pos, x, y, dir; X struct markdata *markdata; X X if (n == 0) X return; X markdata = (struct markdata *)d_lay->l_next->l_data; X ASSERT(p); X X pos = markdata->cx + markdata->cy * d_width; X GotoPos(markdata->cx, W2D(markdata->cy)); X X switch (*p) X { X case '\007': /* CTRL-G */ X pos = markdata->isstartpos; X /*FALLTHROUGH*/ X case '\033': /* ESC */ X *p = 0; X break; X case '\013': /* CTRL-K */ X case '\027': /* CTRL-W */ X markdata->isistrl = 1; X /*FALLTHROUGH*/ X case '\b': X case '\177': X if (markdata->isistrl == 0) X return; X markdata->isistrl--; X pos = is_redo(markdata); X *p = '\b'; X break; X case '\023': /* CTRL-S */ X case '\022': /* CTRL-R */ X if (markdata->isistrl >= sizeof(markdata->isistr)) X return; X dir = (*p == '\023') ? 1 : -1; X pos += dir; X if (markdata->isdir == dir && markdata->isistrl == 0) X { X strcpy(markdata->isistr, markdata->isstr); X markdata->isistrl = markdata->isstrl = strlen(markdata->isstr); X break; X } X markdata->isdir = dir; X markdata->isistr[markdata->isistrl++] = *p; X break; X default: X if (*p < ' ' || markdata->isistrl >= sizeof(markdata->isistr) X || markdata->isstrl >= sizeof(markdata->isstr) - 1) X return; X markdata->isstr[markdata->isstrl++] = *p; X markdata->isistr[markdata->isistrl++] = *p; X markdata->isstr[markdata->isstrl] = 0; X debug2("New char: %c - left %d\n", *p, sizeof(markdata->isistr) - markdata->isistrl); X } X if (*p && *p != '\b') X pos = is_bm(markdata->isstr, markdata->isstrl, pos, d_width * (fore->w_histheight + d_height), markdata->isdir); X if (pos >= 0) X { X x = pos % d_width; X y = pos / d_width; X LAY_CALL_UP X ( X RefreshLine(STATLINE, 0, d_width - 1, 0); X revto(x, y); X if (W2D(markdata->cy) == STATLINE) X { X revto_line(markdata->cx, markdata->cy, STATLINE > 0 ? STATLINE - 1 : 1); X } X ); X } X if (*p) X inp_setprompt(isprompts[markdata->isdir + (pos < 0) + 1], markdata->isstrl ? markdata->isstr : ""); X GotoPos(markdata->cx, W2D(markdata->cy)); X} X Xstatic int Xis_redo(markdata) Xstruct markdata *markdata; X{ X int i, pos, dir; X char c; X X pos = markdata->isstartpos; X dir = markdata->isstartdir; X markdata->isstrl = 0; X for (i = 0; i < markdata->isistrl; i++) X { X c = markdata->isistr[i]; X if (c == '\022') X pos += (dir = -1); X else if (c == '\023') X pos += (dir = 1); X else X markdata->isstr[markdata->isstrl++] = c; X if (pos >= 0) X pos = is_bm(markdata->isstr, markdata->isstrl, pos, d_width * (fore->w_histheight + d_height), dir); X } X markdata->isstr[markdata->isstrl] = 0; X markdata->isdir = dir; X return pos; X} X Xvoid XISearch(dir) Xint dir; X{ X struct markdata *markdata; X markdata = (struct markdata *)d_lay->l_data; X markdata->isdir = markdata->isstartdir = dir; X markdata->isstartpos = markdata->cx + markdata->cy * d_width; X markdata->isistrl = markdata->isstrl = 0; X if (W2D(markdata->cy) == STATLINE) X { X revto_line(markdata->cx, markdata->cy, STATLINE > 0 ? STATLINE - 1 : 1); X } X Input(isprompts[dir + 1], sizeof(markdata->isstr) - 1, is_process, INP_RAW); X GotoPos(markdata->cx, W2D(markdata->cy)); X} X X#endif /* COPY_PASTE */ END_OF_FILE if test 7998 -ne `wc -c <'search.c'`; then echo shar: \"'search.c'\" unpacked with wrong size! fi # end of 'search.c' fi if test -f 'termcap.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'termcap.c'\" else echo shar: Extracting \"'termcap.c'\" \(14829 characters\) sed "s/^X//" >'termcap.c' <<'END_OF_FILE' X/* Copyright (c) 1993 X * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) X * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) X * Copyright (c) 1987 Oliver Laumann X * X * This program is free software; you can redistribute it and/or modify X * it under the terms of the GNU General Public License as published by X * the Free Software Foundation; either version 2, or (at your option) X * any later version. X * X * This program is distributed in the hope that it will be useful, X * but WITHOUT ANY WARRANTY; without even the implied warranty of X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the X * GNU General Public License for more details. X * X * You should have received a copy of the GNU General Public License X * along with this program (see the file COPYING); if not, write to the X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. X * X **************************************************************** X */ X X#include "rcs.h" XRCS_ID("$Id: termcap.c,v 1.3 1993/07/21 15:43:35 mlschroe Exp $ FAU") X X#include X#include "config.h" X#include "screen.h" X#include "extern.h" X Xextern struct display *display; X Xstatic void AddCap __P((char *)); Xstatic void MakeString __P((char *, char *, int, char *)); Xstatic char *findcap __P((char *, char **, int)); Xstatic char *e_tgetstr __P((char *, char **)); Xstatic int e_tgetflag __P((char *)); Xstatic int e_tgetnum __P((char *)); X Xextern struct term term[]; /* terminal capabilities */ Xextern struct NewWindow nwin_undef, nwin_default, nwin_options; Xextern int force_vt, assume_LP; Xextern int Z0width, Z1width; X Xchar Termcap[TERMCAP_BUFSIZE + 8]; /* new termcap +8:"TERMCAP=" */ Xstatic int Termcaplen; Xstatic int tcLineLen; Xchar Term[MAXSTR+5]; /* +5: "TERM=" */ Xchar screenterm[20]; /* new $TERM, usually "screen" */ X Xchar *extra_incap, *extra_outcap; X Xstatic const char TermcapConst[] = "\\\n\ X\t:DO=\\E[%dB:LE=\\E[%dD:RI=\\E[%dC:UP=\\E[%dA:bs:bt=\\E[Z:\\\n\ X\t:cd=\\E[J:ce=\\E[K:cl=\\E[H\\E[J:cm=\\E[%i%d;%dH:ct=\\E[3g:\\\n\ X\t:do=^J:nd=\\E[C:pt:rc=\\E8:rs=\\Ec:sc=\\E7:st=\\EH:up=\\EM:\\\n\ X\t:le=^H:bl=^G:cr=^M:it#8:ho=\\E[H:nw=\\EE:ta=^I:is=\\E)0:"; X Xchar * Xgettermcapstring(s) Xchar *s; X{ X int i; X X if (display == 0 || s == 0) X return 0; X for (i = 0; i < T_N; i++) X { X if (term[i].type != T_STR) X continue; X if (strcmp(term[i].tcname, s) == 0) X return d_tcs[i].str; X } X return 0; X} X Xint XInitTermcap(wi, he) Xint wi; Xint he; X{ X register char *s; X int i; X char tbuf[TERMCAP_BUFSIZE], *tp; X X ASSERT(display); X bzero(tbuf, sizeof(tbuf)); X debug1("InitTermcap: looking for tgetent('%s')\n", d_termname); X if (tgetent(tbuf, d_termname) != 1) X { X Msg(0, "Cannot find termcap entry for %s.", d_termname); X return -1; X } X debug1("got it:\n%s\n",tbuf); X#ifdef DEBUG X if (extra_incap) X debug1("Extra incap: %s\n", extra_incap); X if (extra_outcap) X debug1("Extra outcap: %s\n", extra_outcap); X#endif X tp = d_tentry; X X for (i = 0; i < T_N; i++) X { X switch(term[i].type) X { X case T_FLG: X d_tcs[i].flg = e_tgetflag(term[i].tcname); X break; X case T_NUM: X d_tcs[i].num = e_tgetnum(term[i].tcname); X break; X case T_STR: X d_tcs[i].str = e_tgetstr(term[i].tcname, &tp); X /* no empty strings, please */ X if (d_tcs[i].str && *d_tcs[i].str == 0) X d_tcs[i].str = 0; X break; X default: X Panic(0, "Illegal tc type in entry #%d", i); X /*NOTREACHED*/ X } X } X if (HC) X { X Msg(0, "You can't run screen on a hardcopy terminal."); X return -1; X } X if (OS) X { X Msg(0, "You can't run screen on a terminal that overstrikes."); X return -1; X } X if (NS) X { X Msg(0, "Terminal must support scrolling."); X return -1; X } X if (!CL) X { X Msg(0, "Clear screen capability required."); X return -1; X } X if (!CM) X { X Msg(0, "Addressable cursor capability required."); X return -1; X } X if ((s = getenv("COLUMNS")) && (i = atoi(s)) > 0) X CO = i; X if ((s = getenv("LINES")) && (i = atoi(s)) > 0) X LI = i; X if (wi) X CO = wi; X if (he) X LI = he; X if (CO <= 0) X CO = 80; X if (LI <= 0) X LI = 24; X X if (nwin_options.flowflag == nwin_undef.flowflag) X nwin_default.flowflag = CNF ? FLOW_NOW * 0 : X XO ? FLOW_NOW * 1 : X FLOW_AUTOFLAG; X CLP |= assume_LP || !AM || XV || XN || X (!extra_incap && !strncmp(d_termname, "vt", 2)); X if (!(BL = e_tgetstr("bl", &tp))) X if (!BL) X BL = "\007"; X if (!BC) X { X if (BS) X BC = "\b"; X else X BC = LE; X } X if (!CR) X CR = "\r"; X if (!NL) X NL = "\n"; X if (SG <= 0 && UG <= 0) X { X /* X * Does ME also reverse the effect of SO and/or US? This is not X * clearly specified by the termcap manual. Anyway, we should at X * least look whether ME and SE/UE are equal: X */ X if (UE && ((SE && strcmp(SE, UE) == 0) || (ME && strcmp(ME, UE) == 0))) X UE = 0; X if (SE && (ME && strcmp(ME, SE) == 0)) X SE = 0; X X for (i = 0; i < NATTR; i++) X d_attrtab[i] = d_tcs[T_ATTR + i].str; X /* Set up missing entries */ X s = 0; X for (i = NATTR-1; i >= 0; i--) X if (d_attrtab[i]) X s = d_attrtab[i]; X for (i = 0; i < NATTR; i++) X { X if (d_attrtab[i] == 0) X d_attrtab[i] = s; X else X s = d_attrtab[i]; X } X } X else X { X MS = 1; X for (i = 0; i < NATTR; i++) X d_attrtab[i] = d_tcs[T_ATTR + i].str = 0; X } X if (!DO) X DO = NL; X if (!SF) X SF = NL; X if (IN) X IC = IM = 0; X if (EI == 0) X IM = 0; X /* some strange termcap entries have IC == IM */ X if (IC && IM && strcmp(IC, IM) == 0) X IC = 0; X if (KE == 0) X KS = 0; X if (CCE == 0) X CCS = 0; X if (CG0) X { X if (CS0 == 0) X#ifdef TERMINFO X CS0 = "\033(%p1%c"; X#else X CS0 = "\033(%."; X#endif X if (CE0 == 0) X CE0 = "\033(B"; X } X else if (AS && AE) X { X CG0 = 1; X CS0 = AS; X CE0 = AE; X CC0 = AC; X } X else X { X CS0 = CE0 = ""; X CC0 = "g.h.i'j-k-l-m-n+o~p\"q-r-s_t+u+v+w+x|y"; X } X for (i = 0; i < 256; i++) X d_c0_tab[i] = i; X if (CC0) X for (i = strlen(CC0) & ~1; i >= 0; i -= 2) X d_c0_tab[(unsigned int)CC0[i]] = CC0[i + 1]; X debug1("ISO2022 = %d\n", CG0); X if (PF == 0) X PO = 0; X debug2("terminal size is %d, %d (says TERMCAP)\n", CO, LI); X X /* Termcap fields Z0 & Z1 contain width-changing sequences. */ X if (CZ1 == 0) X CZ0 = 0; X Z0width = 132; X Z1width = 80; X X CheckScreenSize(0); X X if (TS == 0 || FS == 0 || DS == 0) X HS = 0; X if (HS) X { X debug("oy! we have a hardware status line, says termcap\n"); X if (WS <= 0) X WS = d_width; X } X X d_UPcost = CalcCost(UP); X d_DOcost = CalcCost(DO); X d_NLcost = CalcCost(NL); X d_LEcost = CalcCost(BC); X d_NDcost = CalcCost(ND); X d_CRcost = CalcCost(CR); X d_IMcost = CalcCost(IM); X d_EIcost = CalcCost(EI); X X#ifdef AUTO_NUKE X if (CAN) X { X debug("termcap has AN, setting autonuke\n"); X d_auto_nuke = 1; X } X#endif X if (COL > 0) X { X debug1("termcap has OL (%d), setting limit\n", COL); X d_obufmax = COL; X } X X d_tcinited = 1; X MakeTermcap(0); X return 0; X} X X Xstatic void XAddCap(s) Xchar *s; X{ X register int n; X X if (tcLineLen + (n = strlen(s)) > 55 && Termcaplen < TERMCAP_BUFSIZE - 4) X { X strcpy(Termcap + Termcaplen, "\\\n\t:"); X Termcaplen += 4; X tcLineLen = 0; X } X if (Termcaplen + n < TERMCAP_BUFSIZE) X { X strcpy(Termcap + Termcaplen, s); X Termcaplen += n; X tcLineLen += n; X } X else X Panic(0, "TERMCAP overflow - sorry."); X} X Xchar * XMakeTermcap(aflag) Xint aflag; X{ X char buf[TERMCAP_BUFSIZE]; X register char *p, *cp, *s, ch, *tname; X int i, wi, he; X X if (display) X { X wi = d_width; X he = d_height; X tname = d_termname; X } X else X { X wi = 80; X he = 24; X tname = "vt100"; X } X debug1("MakeTermcap(%d)\n", aflag); X if ((s = getenv("SCREENCAP")) && strlen(s) < TERMCAP_BUFSIZE) X { X sprintf(Termcap, "TERMCAP=%s", s); /* TERMCAP_BUFSIZE + ... ? XXX */ X sprintf(Term, "TERM=screen"); X debug("getenvSCREENCAP o.k.\n"); X return Termcap; X } X Termcaplen = 0; X debug1("MakeTermcap screenterm='%s'\n", screenterm); X debug1("MakeTermcap termname='%s'\n", tname); X if (*screenterm == '\0') X { X debug("MakeTermcap sets screenterm=screen\n"); X strcpy(screenterm, "screen"); X } X do X { X sprintf(Term, "TERM="); X p = Term + 5; X if (!aflag && strlen(screenterm) + strlen(tname) < MAXSTR-1) X { X sprintf(p, "%s.%s", screenterm, tname); X if (tgetent(buf, p) == 1) X break; X } X if (wi >= 132) X { X sprintf(p, "%s-w", screenterm); X if (tgetent(buf, p) == 1) X break; X } X sprintf(p, "%s", screenterm); X if (tgetent(buf, p) == 1) X break; X sprintf(p, "vt100"); X } X while (0); /* Goto free programming... */ X tcLineLen = 100; /* Force NL */ X sprintf(Termcap, X "TERMCAP=SC|%s|VT 100/ANSI X3.64 virtual terminal|", Term + 5); X Termcaplen = strlen(Termcap); X debug1("MakeTermcap decided '%s'\n", p); X if (extra_outcap && *extra_outcap) X { X for (cp = extra_outcap; (p = index(cp, ':')); cp = p) X { X ch = *++p; X *p = '\0'; X AddCap(cp); X *p = ch; X } X tcLineLen = 100; /* Force NL */ X } X debug1("MakeTermcap after outcap '%s'\n", (char *)TermcapConst); X if (Termcaplen + strlen(TermcapConst) < TERMCAP_BUFSIZE) X { X strcpy(Termcap + Termcaplen, (char *)TermcapConst); X Termcaplen += strlen(TermcapConst); X } X sprintf(buf, "li#%d:co#%d:", he, wi); X AddCap(buf); X AddCap("am:"); X if (aflag || (force_vt && !COP) || CLP || !AM) X { X AddCap("xn:"); X AddCap("xv:"); X AddCap("LP:"); X } X if (aflag || (CS && SR) || AL || CAL) X { X AddCap("sr=\\EM:"); X AddCap("al=\\E[L:"); X AddCap("AL=\\E[%dL:"); X } X else if (SR) X AddCap("sr=\\EM:"); X if (aflag || CS) X AddCap("cs=\\E[%i%d;%dr:"); X if (aflag || CS || DL || CDL) X { X AddCap("dl=\\E[M:"); X AddCap("DL=\\E[%dM:"); X } X if (aflag || DC || CDC) X { X AddCap("dc=\\E[P:"); X AddCap("DC=\\E[%dP:"); X } X if (aflag || CIC || IC || IM) X { X AddCap("im=\\E[4h:"); X AddCap("ei=\\E[4l:"); X AddCap("mi:"); X AddCap("IC=\\E[%d@:"); X } X if (display) X { X if (US) X { X AddCap("us=\\E[4m:"); X AddCap("ue=\\E[24m:"); X } X if (SO) X { X AddCap("so=\\E[3m:"); X AddCap("se=\\E[23m:"); X } X if (MB) X AddCap("mb=\\E[5m:"); X if (MD) X AddCap("md=\\E[1m:"); X if (MH) X AddCap("mh=\\E[2m:"); X if (MR) X AddCap("mr=\\E[7m:"); X if (MB || MD || MH || MR) X AddCap("me=\\E[m:ms:"); X if (VB) X AddCap("vb=\\E[?5h\\E[?5l:"); X if (KS) X { X AddCap("ks=\\E=:"); X AddCap("ke=\\E>:"); X } X if (CCS) X { X AddCap("CS=\\E[?1h:"); X AddCap("CE=\\E[?1l:"); X } X if (CG0) X { X AddCap("G0:"); X AddCap("as=\\E(0:"); X AddCap("ae=\\E(B:"); X } X if (PO) X { X AddCap("po=\\E[5i:"); X AddCap("pf=\\E[4i:"); X } X if (CZ0) X { X AddCap("Z0=\\E[?3h:"); X AddCap("Z1=\\E[?3l:"); X } X if (CWS) X AddCap("WS=\\E[8;%d;%dt:"); X for (i = T_CAPS; i < T_ECAPS; i++) X { X switch(term[i].type) X { X case T_STR: X if (d_tcs[i].str == 0) X break; X MakeString(term[i].tcname, buf, sizeof(buf), d_tcs[i].str); X AddCap(buf); X break; X case T_FLG: X if (d_tcs[i].flg == 0) X break; X sprintf(buf, "%s:", term[i].tcname); X AddCap(buf); X break; X default: X break; X } X } X } X debug("MakeTermcap: end\n"); X return Termcap; X} X Xstatic void XMakeString(cap, buf, buflen, s) Xchar *cap, *buf; Xint buflen; Xchar *s; X{ X register char *p, *pmax; X register unsigned int c; X X p = buf; X pmax = p + buflen - (3+4+2); X *p++ = *cap++; X *p++ = *cap; X *p++ = '='; X while ((c = *s++) && (p < pmax)) X { X switch (c) X { X case '\033': X *p++ = '\\'; X *p++ = 'E'; X break; X case ':': X sprintf(p, "\\072"); X p += 4; X break; X case '^': X case '\\': X *p++ = '\\'; X *p++ = c; X break; X default: X if (c >= 200) X { X sprintf(p, "\\%03o", c & 0377); X p += 4; X } X else if (c < ' ') X { X *p++ = '^'; X *p++ = c + '@'; X } X else X *p++ = c; X } X } X *p++ = ':'; X *p = '\0'; X} X X X/* X** X** Termcap routines that use our extra_incap X** X*/ X X X/* findcap: X * cap = capability we are looking for X * tepp = pointer to bufferpointer X * n = size of buffer (0 = infinity) X */ X Xstatic char * Xfindcap(cap, tepp, n) Xchar *cap; Xchar **tepp; Xint n; X{ X char *tep; X char c, *p, *cp; X int mode; /* mode: 0=LIT 1=^ 2=\x 3,4,5=\nnn */ X int num = 0, capl; X X if (!extra_incap) X return (0); X tep = *tepp; X capl = strlen(cap); X cp = 0; X mode = 0; X for (p = extra_incap; *p; ) X { X if (strncmp(p, cap, capl) == 0) X { X p += capl; X c = *p; X if (c && c != ':' && c != '@') X p++; X if (c == 0 || c == '@' || c == '=' || c == ':' || c == '#') X cp = tep; X } X while ((c = *p)) X { X p++; X if (mode == 0) X { X if (c == ':') X break; X if (c == '^') X mode = 1; X if (c == '\\') X mode = 2; X } X else if (mode == 1) X { X mode = 0; X c = c & 0x1f; X } X else if (mode == 2) X { X mode = 0; X switch(c) X { X case '0': X case '1': X case '2': X case '3': X case '4': X case '5': X case '6': X case '7': X case '8': X case '9': X mode = 3; X num = 0; X break; X case 'E': X c = 27; X break; X case 'n': X c = '\n'; X break; X case 'r': X c = '\r'; X break; X case 't': X c = '\t'; X break; X case 'b': X c = '\b'; X break; X case 'f': X c = '\f'; X break; X } X } X if (mode > 2) X { X num = num * 8 + (c - '0'); X if (mode++ == 5 || (*p < '0' || *p > '9')) X { X c = num; X mode = 0; X } X } X if (mode) X continue; X X if (cp && n != 1) X { X *cp++ = c; X n--; X } X } X if (cp) X { X *cp++ = 0; X *tepp = cp; X debug2("'%s' found in extra_incap -> %s\n", cap, tep); X return(tep); X } X } X return(0); X} X Xstatic char * Xe_tgetstr(cap, tepp) Xchar *cap; Xchar **tepp; X{ X char *tep, *tgetstr(); X if ((tep = findcap(cap, tepp, 0))) X return((*tep == '@') ? 0 : tep); X return (tgetstr(cap, tepp)); X} X Xstatic int Xe_tgetflag(cap) Xchar *cap; X{ X char buf[2], *bufp; X char *tep; X bufp = buf; X if ((tep = findcap(cap, &bufp, 2))) X return((*tep == '@') ? 0 : 1); X return (tgetflag(cap)); X} X Xstatic int Xe_tgetnum(cap) Xchar *cap; X{ X char buf[20], *bufp; X char *tep, c; X int res, base = 10; X X bufp = buf; X if ((tep = findcap(cap, &bufp, 20))) X { X c = *tep; X if (c == '@') X return(-1); X if (c == '0') X base = 8; X res = 0; X while ((c = *tep++) >= '0' && c <= '9') X res = res * base + (c - '0'); X return(res); X } X return (tgetnum(cap)); X} END_OF_FILE if test 14829 -ne `wc -c <'termcap.c'`; then echo shar: \"'termcap.c'\" unpacked with wrong size! fi # end of 'termcap.c' fi echo shar: End of archive 2 \(of 10\). cp /dev/null ark2isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 10 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0