[comp.os.minix] Files I promised Vincent Broman that I'd send

ast@cs.vu.nl (Andy Tanenbaum) (10/09/88)

: This is a shar archive.  Extract with sh, not csh.
: This archive ends with exit, so do not worry about trailing junk.
: --------------------------- cut here --------------------------
PATH=/bin:/usr/bin:/usr/ucb
echo Extracting 'assert.h'
sed 's/^X//' > 'assert.h' << '+ END-OF-FILE ''assert.h'
X#ifndef NDEBUG
X#define assert(xxx) {if(!(xxx)){fprintf(stderr, "False assertion at line %d in file \"%s\"\n", __LINE__, __FILE__);  exit(1);}}
X#endif
X
X
+ END-OF-FILE assert.h
chmod 'u=rw,g=r,o=r' 'assert.h'
set `wc -c 'assert.h'`
count=$1
case $count in
152)	:;;
*)	echo 'Bad character count in ''assert.h' >&2
		echo 'Count should be 152' >&2
esac
echo Extracting 'brksize.s'
sed 's/^X//' > 'brksize.s' << '+ END-OF-FILE ''brksize.s'
X.define _brksize
X.data
X.globl endbss, _brksize
X_brksize: .word endbss
+ END-OF-FILE brksize.s
chmod 'u=rw,g=r,o=r' 'brksize.s'
set `wc -c 'brksize.s'`
count=$1
case $count in
70)	:;;
*)	echo 'Bad character count in ''brksize.s' >&2
		echo 'Count should be 70' >&2
esac
echo Extracting 'catchsig.s'
sed 's/^X//' > 'catchsig.s' << '+ END-OF-FILE ''catchsig.s'
X.define _begsig
X.globl _begsig
X.globl _vectab, _M
Xmtype = 2			| M+mtype = &M.m_type
X_begsig:
X	push ax			| after interrupt, save all regs
X	push bx
X	push cx
X	push dx
X	push si
X	push di
X	push bp
X	push ds
X	push es
X	mov bx,sp
X	mov bx,18(bx)		| bx = signal number
X	mov ax,bx		| ax = signal number
X	dec bx			| vectab[0] is for sig 1
X	add bx,bx		| pointers are two bytes on 8088
X	mov bx,_vectab(bx)	| bx = address of routine to call
X	push _M+mtype		| push status of last system call
X	push ax			| func called with signal number as arg
X	call (bx)
Xback:
X	pop ax			| get signal number off stack
X	pop _M+mtype		| restore status of previous system call
X	pop es			| signal handling finished
X	pop ds
X	pop bp
X	pop di
X	pop si
X	pop dx
X	pop cx
X	pop bx
X	pop ax
X	pop dummy		| remove signal number from stack
X	iret
X
X.data 
Xdummy: .word 0
+ END-OF-FILE catchsig.s
chmod 'u=rw,g=r,o=r' 'catchsig.s'
set `wc -c 'catchsig.s'`
count=$1
case $count in
814)	:;;
*)	echo 'Bad character count in ''catchsig.s' >&2
		echo 'Count should be 814' >&2
esac
echo Extracting 'commands:makef'
sed 's/^X//' > 'commands:makef' << '+ END-OF-FILE ''commands:makef'
X# To make  'cp', type:   make f=cp
X# To make  'ls', type:   make f=ls
X# To make  'cat', type:   make f=cat
X# Get the idea?
X
X# To make everything, use:
X#  mkdir bin
X#  for i in *.c
X#  do make f=`basename $i .c`
X#  done
X#
X# Furthermore, many commands need a different memory allocation, so chmem must
X# be run to change it.  See the shell script 'changemem' in tools.
X
Xl=/usr/lib
XCFLAGS=  -F -Di8088
X
Xfile:	$l/libc.a $f.s
X	@cc -o bin/$f $f.s
X	@chmem =3072 bin/$f >/dev/null
X	@echo "$f done ."
X
X
X
+ END-OF-FILE commands:makef
chmod 'u=rw,g=r,o=r' 'commands:makef'
set `wc -c 'commands:makef'`
count=$1
case $count in
494)	:;;
*)	echo 'Bad character count in ''commands:makef' >&2
		echo 'Count should be 494' >&2
esac
echo Extracting 'elle.man'
sed 's/^X//' > 'elle.man' << '+ END-OF-FILE ''elle.man'
X1. INTRODUCTION TO ELLE
X     ELLE (ELLE Looks Like Emacs) is an Emacs clone for MINIX.  It was
Xwritten by Ken Harrenstien of SRI.  His e-mail address is klh@sri-nic.arpa.  
XELLE is not full Emacs but it has about 80 commands and is quite fast.
X
X1.1 Key bindings
X     Mined only has a small number of commands.  All of them are either of
Xthe form CTRL-x or are on the numeric keypad.  Emacs, in contrast, has so
Xmany commands, that not only are all the CTRL-x commands used up, but so
Xare all the ESC x (escape followed by x; escape is not a shift character,
Xlike CTRL).  Even this is not enough, so CTRL-X is used as a prefix for
Xadditional commands.  Thus CTRL-X CTRL-L is a command, and so is CTRL-X K.
XNote that what is conventionally written as CTRL-X K really means CTRL-X k.
X
X     As a result, many Emacs commands need three or four key strokes to 
Xexecute.  Some people think 3-4 key strokes is too many.
XFor this reason, Emacs and ELLE allow users to assign their own key bindings.
XIn ELLE this is done with "user profiles."  A user profile is a file listing
Xwhich function is invoked by which key stroke.  The user profile is then
Xcompiled by a program called ellec into binary form.  When ELLE starts up
Xit checks to see if a file .ellepro.b1 exists in $HOME.  If it does, this
Xfile is read in and overrides the default bindings.  
X
X     I have written a user profile that simulates the mined commands fairly
Xwell.  Its installation is described later.  If you have never used Emacs, 
XI suggest that you use the mined profile.  If you normally use Emacs, then
Xdo not install the mined profile.  You can also make your own.
X
X     ELLE has a character-oriented view of the world, not a line oriented
Xview, like ed.  It does not have magic characters for searching, however, you
Xcan use line feed in search patterns.  For example, to find a line consisting
Xof the three characters "foo" all by themselves on a line, using the mined
Xbindings (see below), use the pattern: CTRL-\ CTRL-J f o o CTRL-\ CTRL-J.
XThe CTRL-\ means to interpret the next character literally, in this case it
Xis CTRL-J, which is line feed.  You can also search for patterns involving 
Xmultiple lines.  For example, to find a line ending in an "x" followed by a
Xline beginning with a "y", use as pattern: x CTRL-\ CTRL-J y.
X
X2. MINED KEY BINDINGS
X
X     These are the key bindings if the binary user profile, .ellepro.b1,
Xis installed in $HOME.  The ESCAPE key followed by a number followed by a
Xcommand causes that command to be executed "number" times.  This applies
Xboth to control characters and insertable characters.  CTRL-X refers to a
X"control character."  ESC x refers to an escape character followed by x.
X^X Y refers to CTRL-X followed by y.  To abort the current command and go
Xback to the main loop of the editor, type CTRL-G, rather than CTRL-\.
X     Only a few commands are of the form CTRL-X Y.  All of these are also
Xbound to CTRL-X CTRL-Y, so you can hold down CTRL and then hit X Y, or
Xrelease control after the X, as you prefer.
X     The key bindings that are not listed should not be used.  Some of them 
Xactually do things.  For example, the ANSI escape codes ESC [ x are bound 
Xto ^X Y for a variety of y.
X     Some commands work on regions.  A region is defined as the text between
Xthe most recently set mark and the cursor.
X
X    
X2.1 Mined Commands
X
XCURSOR MOTION
X   arrows   Move the cursor in the indicated direction
X   CTRL-A   Move cursor to start of current line
X   CTRL-Z   Move cursor to end of current line
X   CTRL-F   Move cursor forward word 
X   CTRL-B   Move cursor backward to start of previous word 
X
XSCREEN MOTION
X   Home key Move to first character of the file
X   End key  Move to last character of the file
X   PgUp key Scroll window up 22 lines (closer to start of the file)
X   PgDn key Scroll window down 22 lines (closer to end of the file)
X   CTRL-U   Scroll window up 1 line
X   CTRL-D   Scroll window down 1 line
X   ESC ,    Move to top of screen
X   CTRL-_   Move to bottom of screen
X
XMODIFYING TEXT
X   DEL key  Delete the character under the cursor
X   Backsp   Delete the character to left of the cursor
X   CTRL-N   Delete the next word
X   CTRL-P   Delete the previous word
X   CTRL-T   Delete tail of line (all characters from cursor to end of line)
X   CTRL-O   Open up the line (insert line feed and back up)
X   ESC G    Get and insert a file at the cursor position (CTRL-G in mined)
X
XREGIONS
X   CTRL-^   Set mark at current position for use with CTRL-C and CTRL-K
X   CTRL-C   Copy the text between the mark and the cursor into the buffer
X   CTRL-K   Delete text between mark and cursor; also copy it to the buffer
X   CTRL-Y   Yank contents of the buffer out and insert it at the cursor
X
XMISCELLANEOUS
X   numeric +    Search forward (prompts for expression)
X   numeric \(em Search backward (prompts for expression)
X   CTRL-]   ESC n CTRL-[ goes to line n (slightly different syntax than mined)
X   CTRL-R   Global replace pattern with string (from cursor to end)
X   CTRL-L   Replace pattern with string within the current line only
X   CTRL-W   Write the edited file back to the disk
X   CTRL-S   Fork off a shell (use CTRL-D to get back to the editor)
X   CTRL-G   Abort whatever the editor was doing and wait for command (CTRL-\)
X   CTRL-E   Redraw screen with cursor line positioned in the middle
X   CTRL-V   Visit (edit) a new file
X   CTRL-Q   Write buffer to a file
X   ESC X    Exit the editor
X
X2.2 Non-Mined Commands
X
XCURSOR MOTION
X   ESC P Forward paragraph (a paragraph is a line beginning with a dot)
X   ESC ] Backward paragraph
X   ESC . Indent this line as much as the previous one
X
XMODIFYING TEXT
X   CTRL-\ Insert the next character (used for inserting control characters)
X   ESC T Transpose characters
X   ESC W Transpose words
X   ESC = Delete white space (horizontal space)
X   ESC | Delete blank lines (vertical space)
X
XREGIONS
X   ESC M Mark current paragraph
X   ESC ^ Exchange cursor and mark
X   ESC Y Yank back the next-to-the-last kill (CTRL-Y yanks the last one)
X   ESC A Append next kill to kill buffer
X
XKEYBOARD MACROS
X   ESC / Start Keyboard Macro
X   ESC \ End Keyboard Macro
X   ESC * View Keyboard Macro (the PrtSc key on the numeric pad is also a *)
X   ESC E Execute Keyboard Macro
X
XWINDOW MANAGEMENT
X   ^X 1  Enter one window mode
X   ^X 2  Enter two window mode
X   ^X L  Make the current window larger
X   ^X P  Make the window more petit/petite (Yes, Virginia, they are English)
X   ^X N  Next window
X   ^X W  New window
X
XBUFFER MANAGEMENT
X   numeric 5    Display the list of current files and buffers
X   ESC B Select a buffer
X   ESC S Select an existing buffer
X   ESC N Mark a buffer as NOT modified (even if it really is)
X  
XUPPER AND LOW CASE MANIPULATION
X   ESC I Set first character of word to upper case
X   ESC C Capitalize current word
X   ESC O Make current word ordinary (i.e., lower case)
X   ESC U Set entire region between mark and cursor to upper case
X   ESC L Set entire region between mark and cursor to lower case
X
XMISCELLANEOUS
X   ESC F Find file and read it into its own buffer
X   ESC Z Incremental search
X   ESC Q Like CTRL-R, but queries at each occurrence (type ? for options)
X   ESC R Reset the user profile from a file
X   ESC H Help (ELLE prompts for the 1 or 2 character command to describe)
X   ESC ; Insert a comment in a C program (generates /* */ for you)
X   ^X X  Exit the editor (same as ESC X and CTRL-X CTRL-X)
X
X
XThe major differences between ELLE with the mined profile and mined are:
X
X1. The definition of a "word" is different for forward and backward word
X2. The mark is set with CTRL-^ instead of CTRL-@
X3. Use CTRL-G to abort a command instead of CTRL-\
X4. Use CTRL-\ to literally insert the next character, instead of ALT
X5. CTRL-E adjusts the window to put the cursor in the middle of it
X6. To get and insert a file, use ESC G instead of CTRL-G
X7. To go to line n, type ESC n CTRL-[ instead of CTRL-[ n
X8. You exit with CTRL-X CTRL-X and then answer the question with "y".
X9. There are many new commands, windows, larger files, etc.
X
X3. EMACS KEY BINDINGS
X
XCURSOR MOVEMENT
X   CTRL-F         Forward one character.
X   CTRL-B         Backward one character.
X   CTRL-H         Same as CTRL-B: move backward one character.
X   ESC F          Forward one word.
X   ESC B          Backward one word.
X   CTRL-A         Beginning of current line.
X   CTRL-E         End of current line.
X   CTRL-N         Next line (goes to the next line).
X   CTRL-P         Previous line (goes to the previous line).
X   CTRL-V         Beginning of next screenful.
X   ESC V          Beginning of previous screenful.
X   ESC ]	  Forward Paragraph.
X   ESC [	  Backward Paragraph.
X   ESC <          Beginning of whole buffer.
X   ESC >          End of whole buffer.
X   
XDELETING
X   CTRL-D         Deletes forward one character (the one the cursor is under).
X   DELETE         Deletes backward one character (the one to left of cursor).
X   ESC D          Kills forward one word.
X   ESC DEL        Kills backward one word.
X   CTRL-K         Kills the rest of the line (to the right of the cursor).
X   ESC \          Deletes spaces around the cursor.
X   CTRL-X CTRL-O  Deletes blank lines around the cursor.
X   
XCASE CHANGE
X   ESC C          Capitalizes word : first letter becomes uppercase; rest lower
X   ESC L          Makes the whole next word lowercase.
X   ESC U          Makes the whole next word uppercase.
X   CTRL-X CTRL-L  Makes whole region lowercase.
X   CTRL-X CTRL-U  Makes whole region uppercase.
X   
XSEARCHING  (If no string is given, previous string is used)
X   CTRL-S	  Incremental Search forward; prompts "I-search:"
X   CTRL-R	  Reverse Incremental Search; prompts "R-search:"
X   	             During an incremental search, the following characters
X		     have special effects:
X   			"normal" chars	- Begin searching immediately.
X   			^G		- Cancel I-search, return to start.
X   			DEL		- Erase last char, return to last match.
X   			^S, ^R		- Repeat search (or change direction).
X	   		ESC or CR	- Exit I-search at current point.
X   	   
X   ESC %          Query Replace.  Asks for a search string, then
X   			for the replacement string, and begins searching.
X   			Stops at each match and waits for a command.
X   			Type "?" to see your options.
X   CTRL-X %	  Replace String.  Like Query Replace, but simply
X   			replaces all matches, without stopping to ask.
X   
XMARKING AREAS
X   CTRL-^          Set mark
X   CTRL-X CTRL-X   Exchange cursor and mark.
X   ESC H	   Mark Paragraph.  Sets mark and cursor to surround a para.
X   CTRL-W          Wipe-out -- kills a "region":
X   ESC W           Copy region.  Like CTRL-W then CTRL-Y but does modify buffer
X   CTRL-Y          Yanks-back (un-kills) whatever you have most recently killed.
X   ESC Y           Yanks-back (un-kills) the next most recently killed text.
X   ESC CTRL-W	   Append Next Kill.  Accumulates stuff from several kills
X   
XFILLING TEXT
X   ESC Q           Fill the paragraph to the size of the Fill Column.
X   ESC G           Fill the region.
X   CTRL-X F        Set Fill Column.  ESC Q will use this line size.
X   CTRL-X .        Set Fill Prefix.  Asks for prefix string 
X   CTRL-X T	   Toggles Auto Fill Mode.
X   
XWINDOWS
X   CTRL-X 2        Make two windows (split screen).
X   CTRL-X 1        Make one window (delete window) (make one screen).
X   CTRL-X O        Go to Other window.
X   CTRL-X ^        Grow window: makes current window bigger.
X   
XBUFFERS
X   CTRL-X CTRL-F   Find a file and make a buffer for it.
X   CTRL-X B        Select Buffer: goes to specified buffer or makes new one
X   CTRL-X CTRL-B   Show the names of the buffers used in this editing session.
X   CTRL-X K	   Kill Buffer.
X   ESC ~           Say buffer is not modified.
X   CTRL-X CTRL-M   Toggle EOL mode (per-buffer flag).
X   
XKEYBOARD MACRO
X   CTRL-X (	   Start collecting a keyboard macro.
X   CTRL-X )        Stop collecting.
X   CTRL-X E	   Execute the collected macro.
X   CTRL-X *	   Display the collected macro.
X   
XFILES
X   CTRL-X CTRL-I   Insert a file where cursor is.
X   CTRL-X CTRL-R   Read a new file into current buffer.
X   CTRL-X CTRL-V   Same as ^X ^R above (reads a file).
X   CTRL-X CTRL-W   Write buffer out to new file name.
X   CTRL-X CTRL-S   Save file: write out buffer to its file name.
X   CTRL-X CTRL-E   Write region out to new file name.
X   
XMISCELLANEOUS
X   CTRL-X CTRL-Z   Exit from ELLE.  
X   CTRL-X !        Escape to shell (CTRL-D to return)
X   CTRL-O          Open up line   
X   LINEFEED        Same as typing RETURN and TAB.
X   CTRL-T          Transposes characters.
X   ESC T	   Transposes words.
X   CTRL-U  	   Makes the next command happen four times.
X   CTRL-U number   Makes the next command happen "number" times.  
X   ESC number      Same as CTRL-U number.
X   CTRL-L          Refreshes screen.
X   CTRL-U CTRL-L   Refresh only the line cursor is on.
X   CTRL-U n CTRL-L Change window so the cursor is on line n
X   CTRL-Q          Quote: insert the next character no matter what it is.
X   CTRL-G          Quit: use to avoid answering a question.
X   ESC ;           Inserts comment (for writing C programs).
X   ESC I           Inserts indentation equal to previous line.
X   ESC M           Move to end of this line's indentation.
X   CTRL-_	   Describes a command is command database is online
X   
XUNUSED CONTROLS
X   CTRL-\          Special debugging command.  Not for normal users!
X   CTRL-^          Special debugging command.  Not for normal users!
X   CTRL-C          Not used.
X   CTRL-Z          Not used.
X   CTRL-]          Not used.
X   
X
X4. INSTALLING ELLE ON MINIX
X
X   Files:
X
X     elle	 (executable binary of the editor)
X     ellec       (executable binary of the profile compiler)
X     .ellepro.e  (mined profile in source form)
X     .ellepro.b1 (mined profile in binary form)
X     help.dat    (help file)
X
XHOW TO INSTALL ELLE
X
XStep 1:
X     Check to see if /etc/termcap is present and has an entry for 'minix'.
X
XStep 2:
X     Set the environment properly by typing:  TERM=minix.  You can also put
X     it in the appropriate .profile, but be sure to include a line: 
X     export TERM.  You can check the current environment with: printenv.  
X     If the entry TERM=minix does not appear, ELLE will not work.
X
XStep 3:
X     Install 'elle' and 'ellec' in your /bin or /usr/bin directory.
X
XStep 4:
X     Install help.dat in /usr/src/elle/help.dat
X
XStep 5:
X     If you want to use the mined-like commands, install .ellepro.b1 in $HOME
X
XStep 6:
X     Type 'elle filename' and you are up and running.
X
X
XHOW TO CREATE YOUR OWN USER PROFILE
XStep 1:
X     Modify .ellepro.e to suit your taste
X
XStep 2:
X     Install .ellepro.e in $HOME
X
XStep 3:
X     Type: ellec -Profile
X
XStep 4:
X     Check to see if $HOME/.ellepro.b1 was created
X
+ END-OF-FILE elle.man
chmod 'u=rw,g=r,o=r' 'elle.man'
set `wc -c 'elle.man'`
count=$1
case $count in
14653)	:;;
*)	echo 'Bad character count in ''elle.man' >&2
		echo 'Count should be 14653' >&2
esac
echo Extracting 'getutil.s'
sed 's/^X//' > 'getutil.s' << '+ END-OF-FILE ''getutil.s'
X.define _get_base, _get_size, _get_tot_mem
X.globl _get_base, _get_size, _get_tot_mem
X.globl endbss
X
X|*========================================================================*
X|                           utilities                                     *
X|*========================================================================*
X_get_base:			| return click at which prog starts
X	mov ax,ds
X	ret
X
X_get_size:			| return prog size in bytes (text+data+bss)
X	mov ax,#endbss		| end is compiler label at end of bss
X	ret
X
X| Find out how much memory the machine has, including vectors, kernel MM, etc.
X_get_tot_mem:
X	cli
X	push es
X	push di
X	mov ax,#16384		| start search at 256K (16384 clicks)
X	sub di,di
XL1:	mov es,ax
X	seg es
X	mov (di),#0xA5A4	| write random bit pattern to memory
X	xor bx,bx
X	seg es
X	mov bx,(di)		| read back pattern just written
X	cmp bx,#0xA5A4		| compare with expected value
X	jne L2			| if different, no memory present
X	add ax,#4096		| advance counter by 64K
X	cmp ax,#0xA000		| stop seaching at 640K
X	jne L1
XL2:	pop di
X	pop es
X	sti
X	ret
+ END-OF-FILE getutil.s
chmod 'u=rw,g=r,o=r' 'getutil.s'
set `wc -c 'getutil.s'`
count=$1
case $count in
1045)	:;;
*)	echo 'Bad character count in ''getutil.s' >&2
		echo 'Count should be 1045' >&2
esac
echo Extracting 'mined:makefile'
sed 's/^X//' > 'mined:makefile' << '+ END-OF-FILE ''mined:makefile'
XCFLAGS=-F -Di8088
Xl=/lib
X
Xmined:	mined1.s mined2.s mined.h
X	@cc -i -o mined  mined1.s mined2.s
X
+ END-OF-FILE mined:makefile
chmod 'u=rw,g=r,o=r' 'mined:makefile'
set `wc -c 'mined:makefile'`
count=$1
case $count in
96)	:;;
*)	echo 'Bad character count in ''mined:makefile' >&2
		echo 'Count should be 96' >&2
esac
echo Extracting 'sendrec.s'
sed 's/^X//' > 'sendrec.s' << '+ END-OF-FILE ''sendrec.s'
X.define _send,_receive,_sendrec
X
X| See ../h/com.h for C definitions
XSEND = 1
XRECEIVE = 2
XBOTH = 3
XSYSVEC = 32
X
X|*========================================================================*
X|                           send and receive                              *
X|*========================================================================*
X| send(), receive(), sendrec() all save bp, but destroy ax, bx, and cx.
X.globl _send, _receive, _sendrec
X_send:	mov cx,*SEND		| send(dest, ptr)
X	jmp L0
X
X_receive:
X	mov cx,*RECEIVE		| receive(src, ptr)
X	jmp L0
X
X_sendrec:
X	mov cx,*BOTH		| sendrec(srcdest, ptr)
X	jmp L0
X
X  L0:	push bp			| save bp
X	mov bp,sp		| can't index off sp
X	mov ax,4(bp)		| ax = dest-src
X	mov bx,6(bp)		| bx = message pointer
X	int SYSVEC		| trap to the kernel
X	pop bp			| restore bp
X	ret			| return
X
+ END-OF-FILE sendrec.s
chmod 'u=rw,g=r,o=r' 'sendrec.s'
set `wc -c 'sendrec.s'`
count=$1
case $count in
809)	:;;
*)	echo 'Bad character count in ''sendrec.s' >&2
		echo 'Count should be 809' >&2
esac
echo Extracting 'setjmp.s'
sed 's/^X//' > 'setjmp.s' << '+ END-OF-FILE ''setjmp.s'
X.define _setjmp,_longjmp
X.globl _setjmp, _longjmp
X.text
X_setjmp:	mov	bx,sp
X		mov	ax,(bx)
X		mov	bx,*2(bx)
X		mov	(bx),bp
X		mov	*2(bx),sp
X		mov	*4(bx),ax
X		xor	ax,ax
X		ret
X
X_longjmp:	xor	ax,ax
X		push	bp
X		mov	bp,sp
X		mov	bx,*4(bp)
X		mov	ax,*6(bp)
X		or	ax,ax
X		jne	L1
X		inc	ax
XL1:		mov	cx,(bx)
XL2:		cmp	cx,*0(bp)
X		je	L3
X		mov	bp,*0(bp)
X		or	bp,bp
X		jne	L2
X		hlt
XL3:
X		mov	bp,*0(bp)
X		mov	sp,*2(bx)
X		mov	cx,*4(bx)
X		mov	bx,sp
X		mov	(bx),cx
X		ret
X
X
+ END-OF-FILE setjmp.s
chmod 'u=rw,g=r,o=r' 'setjmp.s'
set `wc -c 'setjmp.s'`
count=$1
case $count in
445)	:;;
*)	echo 'Bad character count in ''setjmp.s' >&2
		echo 'Count should be 445' >&2
esac
echo Extracting 'sgtty.h'
sed 's/^X//' > 'sgtty.h' << '+ END-OF-FILE ''sgtty.h'
X/* Data structures for IOCTL. */
X
Xstruct sgttyb {
X  char sg_ispeed;		/* input speed */
X  char sg_ospeed;		/* output speed */
X  char sg_erase;		/* erase character */
X  char sg_kill;			/* kill character */
X  int  sg_flags;		/* mode flags */
X};
X
Xstruct tchars {
X  char t_intrc;			/* SIGINT char */
X  char t_quitc;			/* SIGQUIT char */
X  char t_startc;		/* start output (initially CTRL-Q) */
X  char t_stopc;			/* stop output	(initially CTRL-S) */
X  char t_eofc;			/* EOF (initially CTRL-D) */
X  char t_brkc;			/* input delimiter (like nl) */
X};
X
X/* Field names */
X#define XTABS	     0006000	/* do tab expansion */
X#define BITS8        0001400	/* 8 bits/char */
X#define BITS7        0001000	/* 7 bits/char */
X#define BITS6        0000400	/* 6 bits/char */
X#define BITS5        0000000	/* 5 bits/char */
X#define EVENP        0000200	/* even parity */
X#define ODDP         0000100	/* odd parity */
X#define RAW	     0000040	/* enable raw mode */
X#define CRMOD	     0000020	/* map lf to cr + lf */
X#define ECHO	     0000010	/* echo input */
X#define CBREAK	     0000002	/* enable cbreak mode */
X#define COOKED       0000000	/* neither CBREAK nor RAW */
X
X/* Line speeds */
X#define B110		   1
X#define B300		   3
X#define B1200		  12
X#define B2400		  24
X#define B4800		  48
X#define B9600 		  96
X
X#define TIOCGETP (('t'<<8) | 8)
X#define TIOCSETP (('t'<<8) | 9)
X#define TIOCGETC (('t'<<8) | 18)
X#define TIOCSETC (('t'<<8) | 17)
+ END-OF-FILE sgtty.h
chmod 'u=rw,g=r,o=r' 'sgtty.h'
set `wc -c 'sgtty.h'`
count=$1
case $count in
1412)	:;;
*)	echo 'Bad character count in ''sgtty.h' >&2
		echo 'Count should be 1412' >&2
esac
echo Extracting 'termcap.c'
sed 's/^X//' > 'termcap.c' << '+ END-OF-FILE ''termcap.c'
X/* termcap - print termcap settings	Author: Terrence Holm */
X
X#include <stdio.h>
X
X#define  TC_BUFFER  1024	/* Size of termcap(3) buffer	*/
X
Xchar *getenv();
Xchar *tgetstr();
X
X/****************************************************************/
X/*								*/
X/*    termcap  [ type ]						*/
X/*								*/
X/*    Prints out all of the termcap capabilities as described	*/
X/*    in termcap(4). If "type" is not supplied then $TERM is	*/
X/*    used.							*/
X/*								*/
X/****************************************************************/
X
X
Xmain( argc, argv )
X  int   argc;
X  char *argv[];
X
X  {
X  char *term;
X  char  buffer[ TC_BUFFER ];
X
X
X  /*  Check for an argument  */
X
X  if ( argc > 2 )
X    Error( "Usage:  %s  [ type ]\n", argv[0] );
X
X  if ( argc == 2 )
X    term = argv[1];
X  else
X    term = getenv( "TERM" );
X
X  if ( term == NULL )
X    Error( "termcap:  $TERM is not defined\n", "" );
X
X
X  /*  Read in the termcap entry  */
X
X  if ( tgetent( buffer, term ) != 1 )
X    Error( "termcap:  No termcap entry for %s\n", term );
X
X
X  /*  Print out the entry's contents  */
X
X  printf( "TERM = %s\n\n", term );
X
X  if ( tgetflag( "am" ) == 1 )
X    printf( "End of line wraps to next line   (am)\n" );
X
X  if ( tgetflag( "bs" ) == 1 )
X    printf( "Ctrl/H performs a backspace      (bs)\n" );
X
X  printf( "Number of columns                (co) = %d\n", tgetnum( "co" ) );
X  printf( "Number of lines                  (li) = %d\n", tgetnum( "li" ) );
X
X  Print( "Clear to end of line", 	  "ce" );
X  Print( "Clear to end of screen", 	  "cd" );
X  Print( "Clear the whole screen",	  "cl" );
X
X  Print( "Start \"stand out\" mode",	  "so" );
X  Print( "End \"stand out\" mode",	  "se" );
X  Print( "Start underscore mode",	  "us" );
X  Print( "End underscore mode",		  "ue" );
X  Print( "Start blinking mode",		  "mb" );
X  Print( "Start bold mode",		  "md" );
X  Print( "Start reverse mode",		  "mr" );
X  Print( "Return to normal mode",	  "me" );
X
X  Print( "Scroll backwards",		  "sr" );
X  Print( "Cursor motion",		  "cm" );
X
X  Print( "Up one line",			  "up" );
X  Print( "Down one line",		  "do" );
X  Print( "Left one space",		  "le" );
X  Print( "Right one space",		  "nd" );
X  Print( "Move to top left corner",	  "ho" );
X
X  Print( "Generated by \"UP\"",		  "ku" );
X  Print( "Generated by \"DOWN\"",	  "kd" );
X  Print( "Generated by \"LEFT\"",	  "kl" );
X  Print( "Generated by \"RIGHT\"",	  "kr" );
X  Print( "Generated by \"HOME\"",	  "kh" );
X  Print( "Generated by \"END\"",	  "k0" );
X  Print( "Generated by \"PGUP\"",	  "k1" );
X  Print( "Generated by \"PGDN\"",	  "k2" );
X  Print( "Generated by numeric \"+\"",	  "k3" );
X  Print( "Generated by numeric \"-\"",	  "k4" );
X  Print( "Generated by numeric \"5\"",	  "k5" );
X
X  exit( 0 );
X  }
X
X
X
X
X
X
X/****************************************************************/
X/*								*/
X/*    	Print( comment, name )					*/
X/*								*/
X/*    		If a termcap entry exists for "name", then	*/
X/*		print out "comment" and the entry. Control	*/
X/*		characters are printed as ^x.			*/
X/*								*/
X/****************************************************************/
X
X
XPrint( comment, name )
X  char *comment;
X  char *name;
X
X  {
X  char  entry[ 50 ];
X  char *p = entry;
X
X  if ( tgetstr( name, &p ) == NULL )
X    return;
X    
X  printf( "%-32s (%s) = ", comment, name );
X
X  for ( p = entry;  *p != '\0';  ++p )
X    if ( *p < ' ' )
X      printf( "^%c", *p + '@' );
X    else if ( *p == '\177' )
X      printf( "^?" );
X    else
X      putchar( *p );
X
X  putchar( '\n' );
X  }
X
X
X
X
X
X
X/****************************************************************/
X/*								*/
X/*    	Error( message, arg )					*/
X/*								*/
X/*    		Printf the "message" and abort.			*/
X/*								*/
X/****************************************************************/
X
X
XError( message, arg )
X  char *message;
X  char *arg;
X
X  {
X  fprintf( stderr, message, arg );
X  exit( 1 );
X  }
+ END-OF-FILE termcap.c
chmod 'u=rw,g=r,o=r' 'termcap.c'
set `wc -c 'termcap.c'`
count=$1
case $count in
3832)	:;;
*)	echo 'Bad character count in ''termcap.c' >&2
		echo 'Count should be 3832' >&2
esac
echo Extracting 'tsort.c'
sed 's/^X//' > 'tsort.c' << '+ END-OF-FILE ''tsort.c'
X/*
X * tsort - do a topological sort on the ordered pairs of names
X *
X * syntax - tsort [ file ]
X *
X * based on the discussion in 'The AWK programming Language', by
X * Aho, Kernighan, & Weinberger.
X *	
X * author:	Monty Walls
X * written:	1/28/88
X * Copyright:	Copyright (c) 1988 by Monty Walls.
X *		Not derived from licensed software.
X *
X *		Permission to copy and/or distribute granted under the
X *		following conditions:
X *	
X *		1). This notice must remain intact.
X *		2). The author is not responsible for the consequences of use
X *			this software, no matter how awful, even if they
X *			arise from defects in it.
X *		3). Altered version must not be represented as being the 
X *			original software.
X *
X * change log:
X *	possible bug in ungetc(), fixed readone() to avoid - 2/19/88 - mrw
X *	massive design error, rewrote dump logic - 3/15/88 - mrw
X */
X
X#include <stdio.h>
X#include <errno.h>
X#include <ctype.h>
X
X#define printmem(_s)	(fprintf(stdout,"%s ",(_s)))
X#define MAXNAMELEN	32
X#define MAXMEMBERS	1024
X
Xstruct dependents {
X	struct node *nd;
X	struct dependents *next;
X};
X
Xstruct node {
X	char *name;
X	int pcnt, scnt, visited;
X	struct dependents *succ, *pred;
X	struct node *left, *right;
X};
X
Xchar *progname;
X
Xextern struct node *readnode(), *findnode();
Xextern char *malloc(), *xalloc(), *readone(), *strsave();
Xextern struct dependents *finddep();
Xextern void dumptree(), walktree(), emptytree(), addqueue(), walklist();
X
Xextern int errno;
Xextern char *sys_errlist[];
X
Xstruct node *tree, *lastnode, *q[MAXMEMBERS];
Xstruct dependents *lastdepd;
Xint node_cnt, rc, front, back;
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X	progname = argv[0];
X	if (argc > 1) 
X		if (freopen(argv[1], "r", stdin) == (FILE *)NULL) {
X			fprintf(stderr,"Error: %s - %s\n",progname, sys_errlist[errno]);
X			exit(1);
X		}
X
X	/* read in the tree of entries */
X	while (readnode() != (struct node *)NULL) 
X		;	
X	dumptree(tree);
X	fflush(stdout);
X
X	if (node_cnt != back) {
X		fprintf(stderr,"Error: %s - input contains a cycle\n",progname);
X		rc = 1;
X	}
X
X	exit(rc);
X}
X
X
Xstruct node *
Xreadnode()
X{
X	char *s1, *s2;
X	register struct node *n1, *n2;
X	struct dependents *pd;
X
X	if ((s1 = readone()) != (char *)NULL) {
X		if ((n1 = findnode(s1)) == (struct node *)NULL) {
X			/* is a new node so build it */
X			n1 = (struct node *)xalloc(sizeof(struct node));
X			n1->name = strsave(s1);
X			n1->succ = (struct dependents *)NULL;
X			n1->pred = (struct dependents *)NULL;
X			n1->left = (struct node *)NULL;
X			n1->right = (struct node *)NULL;
X			n1->pcnt = 0;
X			n1->scnt = 0;
X			n1->visited = 0;
X			linknode(n1);
X		}
X		if ((s2 = readone()) != (char *)NULL) {
X			if ((n2 = findnode(s2)) == (struct node *)NULL) {
X				/* is a new node so build it */
X				n2 = (struct node *)xalloc(sizeof(struct node));
X				n2->name = strsave(s2);
X				n2->succ = (struct dependents *)NULL;
X				n2->pred = (struct dependents *)NULL;
X				n2->left = (struct node *)NULL;
X				n2->right = (struct node *)NULL;
X				n2->pcnt = 0;
X				n2->scnt = 0;
X				n2->visited = 0;
X				linknode(n2);
X			}
X			if (n1 != n2) {
X				if (finddep(n2->pred,s1) == (struct dependents *)NULL) {
X					/* new dependence here */
X					pd = (struct dependents *)xalloc(sizeof(struct dependents));
X					pd->nd = n1;
X					pd->next = (struct dependents *)NULL;
X					n2->pcnt++;
X					if (n2->pred == (struct dependents *)NULL) 
X						n2->pred = pd;
X					else
X						lastdepd->next = pd;
X				}
X				if (finddep(n1->succ,s2) == (struct dependents *)NULL) {
X					/* new dependence here */
X					pd = (struct dependents *)xalloc(sizeof(struct dependents));
X					pd->nd = n2;
X					pd->next = (struct dependents *)NULL;
X					n1->scnt++;
X					if (n1->succ == (struct dependents *)NULL) 
X						n1->succ = pd;
X					else
X						lastdepd->next = pd;
X				}
X			}
X			return (n1);
X		}
X		else
X			return ((struct node *)NULL);
X	}
X	else
X		return ((struct node *)NULL);
X}
X
Xvoid
Xdumptree(top)
Xregister struct node *top;
X{
X	walktree(top);		/* get all entries in order with no predecessors */
X	for (front = 1; front <= back; front++) {
X		printmem(q[front]->name);
X		walklist(q[front]->succ);
X	}
X	emptytree(top);		/* dumps all isolated nodes left over */
X}
X
Xvoid
Xwalklist(s)
Xregister struct dependents *s;
X{
X	for (; s; s = s->next) {
X		if (--s->nd->pcnt == 0) {
X			addqueue(s->nd);
X			s->nd->visited = 1;
X			walklist(s->nd->succ);
X		}
X	}
X}
X
Xvoid
Xwalktree(t)
Xregister struct node *t;
X{
X	if (t) {
X		node_cnt++;
X		walktree(t->right);
X		if (t->pcnt == 0) {
X			addqueue(t);
X			t->visited = 1;
X		}
X		walktree(t->left);
X	}
X}
X
Xvoid
Xemptytree(t)
Xregister struct node *t;
X{
X	struct dependents *s;
X
X	/* t  - represents a remaining entry which is in a cycle */
X	if (t) {
X		emptytree(t->right);
X		if (t->visited == 0) {
X			t->visited = 1;
X			printmem(t->name);
X			for (s = t->succ; s; s = s->next)
X				if (s->nd->visited == 0) {
X					fprintf(stderr,"Error: %s - %s and %s are in a cycle\n",progname, t->name, s->nd->name);
X				}
X		}
X		emptytree(t->left);
X	}
X}
X
Xvoid
Xaddqueue(t)
Xstruct node *t;
X{
X	if (++back >= MAXMEMBERS) {
X		fprintf(stderr,"Error: %s - member queue overflow\n",progname);
X		exit(1);
X	}
X	else
X		q[back] = t;
X}
X
Xchar *
Xreadone()
X{
X	register int c, n = 0;
X	static char name[MAXNAMELEN];
X
X	/* eat up leading spaces */
X	while ((c = getchar()) != EOF && isspace(c))
X		;
X
X	if (c != EOF) {
X		name[n++] = c;	/* save into name first non blank */
X		while ((c = getchar()) != EOF && !isspace(c)) {
X			if (n < MAXNAMELEN)
X				name[n++] = c;
X		}
X		name[n] = '\0';
X		return (name);
X	}
X	else
X		return ((char *)NULL);
X
X}
X
Xstruct node *
Xfindnode(s)
Xchar *s;
X{
X	register struct node *n;
X	register int cmp;
X
X	if (tree) {
X		lastnode = n = tree;
X		while (n && n->name) {
X			lastnode = n;
X			if (!(cmp = strcmp(s,n->name)))
X				return (n);
X			else if (cmp > 0)
X				n = n->left;
X			else
X				n = n->right;
X		}
X	}
X	return ((struct node *)NULL);
X}
X
Xstruct dependents *
Xfinddep(dp, s)
Xregister struct dependents *dp;
Xregister char *s;
X{
X	lastdepd = (struct dependents *)NULL;
X	while (dp && dp->nd) {
X		lastdepd = dp;
X		if (strcmp(dp->nd->name,s) == 0)
X			return (dp);
X		else {
X			dp = dp->next;
X		}
X	}
X	return ((struct dependents *)NULL);
X}
X
Xlinknode(n)
Xregister struct node *n;
X{
X	register int cmp;
X
X	if (tree) {
X		cmp = strcmp(n->name,lastnode->name);
X		if (cmp > 0)
X			lastnode->left = n;
X		else
X			lastnode->right = n;
X	}
X	else
X		tree = n;
X}
X
Xchar *
Xxalloc(n)
Xint n;
X{
X	char *p;
X	
X	if ((p = malloc(n)) != (char *)NULL)
X		return (p);
X	else {
X		fprintf(stderr,"Error: %s out of memory\n",progname);
X		exit(1);
X	}
X}
X
Xchar *
Xstrsave(s)
Xchar *s;
X{
X	char *p;
X
X	p = xalloc(strlen(s)+1);
X	strcpy(p,s);
X	return (p);
X}
+ END-OF-FILE tsort.c
chmod 'u=rw,g=r,o=r' 'tsort.c'
set `wc -c 'tsort.c'`
count=$1
case $count in
6563)	:;;
*)	echo 'Bad character count in ''tsort.c' >&2
		echo 'Count should be 6563' >&2
esac
echo Extracting 'who.c'
sed 's/^X//' > 'who.c' << '+ END-OF-FILE ''who.c'
X/* who - tell who is currently logged in	Author: Andy Tanenbaum */
X
X/* Who reads the file /usr/adm/wtmp and prints a list of who is curently
X * logged in.  The format of this file is a sequence of 20-character records,
X * as defined by struct wtmprec below.  There is an implicit assumption that
X * all terminal names are of the form ttyn, where n is a single decimal digit.
X */
X
X#define SLOTS   10
X#define WTMPSIZE 8
X#define DIGIT    3
X
Xchar *wtmpfile = "/usr/adm/wtmp";
X
Xstruct wtmprec {
X  char wt_line[WTMPSIZE];	/* tty name */
X  char wt_name[WTMPSIZE];	/* user id */
X  long wt_time;			/* time */
X} wtmp;
X
Xstruct wtmprec user[SLOTS];
Xextern char *ctime();
X
Xmain()
X{
X  int fd;
X
X  fd = open(wtmpfile, 0);
X  if (fd < 0) {
X	printf("The file %s cannot be opened.\n", wtmpfile);
X	printf("To enable login accounting (required by who),");
X	printf("create an empty file with this name.\n");
X	exit(1);
X  }
X
X  readwtmp(fd);
X  printwtmp();
X}
X
X
Xreadwtmp(fd)
Xint fd;
X{
X/* Read the /usr/adm/wtmp file and build up a log of current users. */
X
X  int i, ttynr;
X
X  while (read(fd, &wtmp, sizeof(wtmp)) == sizeof(wtmp)) {
X	if (strcmp(wtmp.wt_line, "~") == 0) {
X		/* This line means that the system was rebooted. */
X		for (i = 0; i < SLOTS; i++) user[i].wt_line[0] = 0;
X		continue;
X	}
X	ttynr = wtmp.wt_line[DIGIT] - '0';
X	if (ttynr < 0 || ttynr >= SLOTS) continue;
X	if (wtmp.wt_name[0] == 0) {
X		user[ttynr].wt_line[0] = 0 ;
X		continue;
X	}
X	user[ttynr] = wtmp;
X  }
X}
X
Xprintwtmp()
X{
X  struct wtmprec *w;
X  char *p;
X
X  for (w = &user[0]; w < &user[SLOTS]; w++) {
X	if (w->wt_line[0] == 0) continue;
X	printf("%s	%s	", w->wt_name, w->wt_line);
X	p = ctime(&w->wt_time);
X	*(p+16) = 0;
X	printf("%s\n", p);
X  }
X}
+ END-OF-FILE who.c
chmod 'u=rw,g=r,o=r' 'who.c'
set `wc -c 'who.c'`
count=$1
case $count in
1686)	:;;
*)	echo 'Bad character count in ''who.c' >&2
		echo 'Count should be 1686' >&2
esac
echo Extracting 'whoami.c'
sed 's/^X//' > 'whoami.c' << '+ END-OF-FILE ''whoami.c'
X/* whoami - print the current user name 	Author: Terrence W. Holm */
X
X#include <stdio.h>
X#include <pwd.h>
X
Xstruct passwd *getpwuid();
X
Xmain()
X{
X  struct passwd *pw_entry;
X
X  pw_entry = getpwuid(geteuid());
X  if (pw_entry == NULL) exit(1);
X  puts(pw_entry->pw_name);
X  exit(0);
X}
+ END-OF-FILE whoami.c
chmod 'u=rw,g=r,o=r' 'whoami.c'
set `wc -c 'whoami.c'`
count=$1
case $count in
279)	:;;
*)	echo 'Bad character count in ''whoami.c' >&2
		echo 'Count should be 279' >&2
esac
exit 0