home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume10
/
sh_dos
/
part06
< prev
next >
Wrap
Text File
|
1990-02-13
|
30KB
|
1,324 lines
Newsgroups: comp.sources.misc
organization: ITM Sector, Data Logic Ltd. (A Raytheon Company)
From: istewart@datlog.co.uk (Ian Stewartson)
subject: v10i058: MSDOS Shell (sh) Implementation - Part 05 of 05
Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
Posting-number: Volume 10, Issue 58
Submitted-by: istewart@datlog.co.uk (Ian Stewartson)
Archive-name: sh_dos/part06
#!/bin/sh
# this is part 5 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file shell/sh0.asm continued
#
CurArch=5
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
exit 1; fi
( read Scheck
if test "$Scheck" != $CurArch
then echo "Please unpack part $Scheck next!"
exit 1;
else exit 0; fi
) < s2_seq_.tmp || exit 1
echo "x - Continuing file shell/sh0.asm"
sed 's/^X//' << 'SHAR_EOF' >> shell/sh0.asm
X call $GDT_src_load
X
X;
X; Check for end of copy - BX contains the file handler for disk write
X;
X
X$Write_loop:
X or si, si
X je $Write_Complete
X
X; OK - Copy next 0x4000 bytes - switch on device
X
X mov ax, word ptr cs: _SW_Mode
X dec ax
X jz $Write_disk
X dec ax
X jz $W_extend
X jmp $W_expand
X
X; Write to disk
X
X$Write_disk:
X mov ax, 04000H ; Set up to write
X mov cx, ax ; Load count
X xor dx, dx ; Clear start address
X push bx ; Save FP
X push si ; Save count and Data Segment
X
X int 021H ; Write the data
X
X pop si ; Restore Regs
X pop bx
X jc $Write_error ; NO - abort
X
X$Write_Incr:
X dec si ; Decrement block count
X mov ax, ds ; Increment offset
X add ax, 0400H
X mov ds, ax
X jmp $Write_loop
X
X; Write to extended memory
X
X$W_extend:
X call $Write_extend
X jc $Write_error ; NO - abort
X
X dec si ; Decrement block count
X call $Inc_Extend
X jmp $Write_loop
X
X; Write to expanded memory
X; BX - handler
X; SI - count
X; DS - source segment
X;
X$W_expand:
X call $map_ems_page ; Map in the current EMS page
X jnz $Write_error
X
X push ds ; Save DS and SI
X push si
X mov es, word ptr cs:_SW_EMSFrame ; Set Dest Seg
X xor si, si ; Clear start
X xor di, di
X mov cx, 02000H ; move 16K
X pushf ; Save direction flag
X cld
X rep movsw
X popf ; Restore direction flag
X pop si ; And DS, SI
X pop ds
X jmp $Write_Incr ; Increment DS and dec SI
X
X;
X; Error - abort. The error code is in AH.
X;
X
X$Write_error:
X mov ds, word ptr cs:S_ds ; Restore DS
X mov al, ah
X xor ah, ah
X mov word ptr ds:_errno, ax ; Save error code
X mov ax, 0FFFEH
X jmp $SA_spawn_Exit ; Exit
X
X;
X; Swap file is now written, set up environment
X;
X$Write_Complete:
X mov ds, word ptr cs:exec_env ; Load Env seg.
X xor si, si ; Clear start offset
X
X;
X; Copy into Env Seg
X;
X
X$Copy_Env:
X les bx, dword ptr ss:[bp + 6] ; Check for end of loop
X mov ax, word ptr es:[bx + 0]
X or ax, word ptr es:[bx + 2]
X je $Copy_End
X
X;
X; Save start address
X;
X add word ptr ss:[bp + 6], 4 ; Increment environment by 4
X
X mov cx, word ptr es:[bx + 0] ; Load address of cur Env string
X mov ax, word ptr es:[bx + 2] ; into es:bx
X mov es, ax
X mov bx, cx
X
X;
X; Copy this value
X;
X
X$Copy_Val:
X mov al, byte ptr es:[bx] ; Copy across
X mov byte ptr ds:[si], al
X inc bx ; Increment pointers
X inc si
X or al, al
X jne $Copy_Val
X jmp $Copy_Env
X
X;
X; Set up exec parameter block - DS is on stack
X;
X$Copy_End:
X xor ax, ax
X mov word ptr ds:[si], ax ; Terminate environment
X add si, 2
X
X;
X; Set up new program length
X;
X add si, 16 ; Round up paras
X mov dx, si ; Save end offset in DX
X mov bx, ds
X
X mov cl, 4
X shr si, cl ; # paras used by Env
X add si, bx ; End para number
X
X mov bx, word ptr cs:N_mcb ; Load our MCB address in BX
X mov ax, bx
X inc ax
X sub si, ax
X mov cx, si ; Save new max paras in CX
X
X;
X; Use interrupt 4a to shrink memory. First release all memory above us.
X;
X push ax
X push cx ; Save Max paras and location
X mov ds, bx ; Set up the segement for MCB
X mov cx, word ptr ds:3 ; Get the MCB length
X
X; Are we the only one in the chain?
X
X cmp byte ptr ds:0, 'Z' ; End of chain ?
X jz $Shrink_First
X
X;
X; Loop round releasing memory blocks
X;
X; CX - original length of block;
X; DS - segement of the previous block
X;
X$Shrink_Next:
X mov ax, ds ; Move to the next block
X add cx, ax
X inc cx
X mov ds, cx
X
X cmp byte ptr ds:0, 'Z' ; End of chain ?
X jz $Shrink_First
X
X mov cx, word ptr ds:3 ; Save the length of this block
X
X mov ax, ds ; Advance to the block itself
X inc ax
X mov es, ax ; Set up Block address
X
X mov ah, 049H
X int 021H
X jmp $Shrink_Next
X
X;
X; Shrink the PSP segment
X;
X
X$Shrink_First:
X pop cx
X pop ax
X mov es, ax ; Set PSP address
X mov bx, cx ; Set max length
X mov ah, 04aH
X int 021H
X
X;
X; Execute function
X;
X
X mov word ptr cs: S_sp, sp ; Save the current stack
X mov word ptr cs: S_ss, ss
X
X;
X; Move to the local stack so that it doesn't get overwritten.
X;
X mov ax, cs
X cli
X mov sp, offset Local_Stack
X mov ss, ax
X sti
X
X; Clear out Interrupts
X
X mov ah, 00bH ; Check Keyboard status
X int 021H
X
X;
X; Check for interrupt 23 detected
X;
X mov ax, word ptr cs:_SW_intr
X xor ax, ax
X jz $I23_Cf ; No - continue;
X
X;
X; Interrupt 23 detected - abort
X;
X mov ax, cs ; Set up for reload
X cli
X mov sp, offset Local_Stack
X mov ss, ax
X sti
X
X mov ds, word ptr cs:S_ds ; Restore DS
X mov word ptr ds:_errno, 4 ; Set to EINTR
X jmp $Exec_Error
X
X;
X; No interrupts - continue
X;
X$I23_Cf:
X mov ax, cs ; Set up segments
X mov es, ax
X mov ds, ax
X
X mov ax, 04b00H ; Load and execute function
X mov dx, offset _path_line ; Load path
X mov bx, offset exec_parms ; Load the execute structure
X mov byte ptr cs:InShell, 1 ; Set not In shell flag for Interrupt 23
X int 021H
X mov byte ptr cs:InShell, 0 ; Set In shell flag for Interrupt 23
X
X; Disable interrupts while we restore the stack to the local one
X
X mov ax, cs
X cli
X mov sp, offset Local_Stack
X mov ss, ax
X sti
X
X;
X; Did an error occur?
X;
X jnc $Exec_OK
X
X;
X; Error
X;
X mov ds, word ptr cs:S_ds ; Restore DS
X mov ah, al
X call far ptr __maperror ; Map the error
X
X$Exec_Error:
X mov ax, 0FFFFH
X jmp $Exec_Complete
X
X;
X; No - get the exit code and check for interrupts
X;
X
X$Exec_OK:
X mov ax, 04d00H
X int 021H
X dec ah ; Interrupt termination ?
X jnz $Exec_OK1
X
X inc word ptr ds:_SW_intr ; Set Interrupt 23 detected.
X
X$Exec_OK1:
X xor ah, ah
X
X;
X; Save the result code
X;
X
X$Exec_Complete:
X mov word ptr cs:Result, ax ; Save response
X
X;
X; Very Dangerous - Restore Environment
X;
X; Seek to 0x4000 in file
X;
X mov bx, word ptr cs:_SW_fp ; Load File Handler
X mov ax, word ptr cs: _SW_Mode ; Skip if not disk
X dec ax
X jnz $Seek_OK
X
X; Seek in file to skip 16K
X
X mov dx, 04000H
X call $Seek_Disk
X
X;
X; Load from N_mcb:0x4000 to end of file.
X;
X
X$Seek_OK:
X mov si, word ptr cs:_SW_Blocks ; Load number of transfers
X dec si ; Skip first block
X
X;
X; set up ES register with start of load
X;
X mov ax, word ptr cs:N_mcb ; Load the start address
X add ax, 0400H
X mov ds, ax
X
X; load up extended memory GDT for destination
X
X call $GDT_reload
X call $Inc_Extend ; Increment addresses by 16K
X
X;
X; Check for end of copy - BX - File Handler for disk
X;
X
X$Read_loop:
X or si, si
X je $Read_Complete
X
X; OK - Copy next 0x4000 bytes - switch on device
X
X mov ax, word ptr cs: _SW_Mode
X dec ax
X jz $R_disk
X dec ax
X jz $R_extend
X jmp $R_expand
X
X; Read from disk
X
X$R_disk:
X call $Read_disk
X jmp $Read_loop
X
X; Read from extended memory
X
X$R_extend:
X call $Read_extend
X jmp $Read_loop
X
X; Read from expanded memory
X
X$R_expand:
X call $Read_EMS
X jmp $Read_loop
X
X;
X; Re-load is now complete, Restore original stack which has just been
X; reloaded. BX contains FP
X;
X
X$Read_Complete:
X cli
X mov sp, word ptr cs: S_sp ; Save the current stack
X mov ss, word ptr cs: S_ss
X sti
X
X; Save exit code
X
X push word ptr cs:Result ; Save response
X
X;
X; Read in the first block - BX - File Handler
X;
X
X mov ax, word ptr cs: _SW_Mode ; Skip if not disk
X dec ax
X jnz $Seek1_OK
X
X; Seek to 0 in file
X
X xor dx, dx
X call $Seek_Disk
X
X;
X; Load one block at N_mcb:0x0000
X;
X$Seek1_OK:
X mov ds, word ptr cs:N_mcb ; Load the start address
X call $GDT_reload ; Load the GDT for extend mem
X
X mov ax, word ptr cs: _SW_Mode ; Skip if not disk
X dec ax
X jz $R1_Disk
X dec ax
X jz $R1_Extend
X jmp $R1_Expand
X
X$R1_Disk:
X call $Read_disk
X jmp $Read1_OK
X
X$R1_Extend:
X call $Read_extend
X jmp $Read1_OK
X
X$R1_Expand:
X mov si, word ptr cs:_SW_Blocks ; Read first block
X call $Read_EMS
X
X;
X; Complete - load error code and return
X;
X
X$Read1_OK:
X pop ax
X
X;
X; Exit function - Restore Control Interrupt handler
X;
X
X$SA_spawn_Exit:
X push ax ; Save exit code
X mov ax, 02523H ; Set Control C Interrupt
X mov ds, word ptr cs:_SW_I23_V_ES
X mov dx, word ptr cs:_SW_I23_V_BX
X int 021H
X
X mov ax, 02523H ; Set Divide Zero Interrupt
X mov ds, word ptr cs:_SW_I0_V_ES
X mov dx, word ptr cs:_SW_I0_V_BX
X
X;
X
X mov di, word ptr cs:S_di ; Restore saved registers
X mov si, word ptr cs:S_si
X mov ds, word ptr cs:S_ds
X
X; If interrupt 23 detected - raise the flag
X
X mov ax, word ptr cs:_SW_intr ; Set Interrupt 23 detected.
X or ax, ax
X jz $SA_Exit1
X
X mov ax, 02H
X push ax ; Set SIGINT
X call _raise
X add sp, 2
X
X$SA_Exit1:
X pop ax ; Restore result
X mov sp,bp
X pop bp
X ret
X
X_SA_spawn endp
X
X;
X; READ DISK FUNCTION
X;
X; BX - file handler
X; SI - Block count
X; DS - Output data segement
X;
X
X$Read_disk proc near
X
X mov ax, 03f00H ; Set up to read
X mov cx, 04000H ; Load count
X xor dx, dx ; Clear start address
X
X int 021H ; Read the data
X
X jnc $Read_OK ; NO - abort
X jmp Load_Error ; Abort - swap file error
X
X;
X; Read OK - next block
X;
X
X$Read_OK:
X dec si ; Decrement block count
X mov ax, ds ; Increment offset
X add ax, 0400H
X mov ds, ax
X ret
X
X$Read_disk endp
X
X;
X; READ EMS FUNCTION
X;
X; BX - file handler
X; SI - Block count - counts from max
X; DS - Output data segement
X;
X
X$Read_EMS proc near
X
X call $map_ems_page ; Map in the current EMS page
X jnz Load_Error
X
X push ds ; Save DS and SI
X push si
X mov ax, ds
X mov es, ax
X mov ds, word ptr cs:_SW_EMSFrame ; Set Dest Seg
X xor si, si ; Clear start
X xor di, di
X mov cx, 02000H ; move 16K
X pushf ; Save direction flag
X cld
X rep movsw
X popf ; Restore direction flag
X pop si ; And DS, SI
X pop ds
X jmp $Read_OK ; Increment DS and dec SI
X
X$Read_EMS endp
X
X;
X; MAP IN THE CURRENT EMS PAGE
X;
X; BX - file handler
X; SI - Block count - counts from max
X; DS - Output data segement
X;
X
X$map_ems_page proc near
X
X push bx ; Need to save BX
X mov ax, 04400h ; Map into physical page zero
X mov dx, bx ; Set up handler
X mov bx, word ptr cs: _SW_Blocks
X sub bx, si
X
X int 067H
X pop bx
X
X or ah, ah
X ret
X
X$map_ems_page endp
X
X;
X; DISK SEEK FUNCTION
X;
X; BX - file handler
X; DX - offset
X;
X$Seek_Disk proc near
X
X mov ax, 04200H ; Set seek
X xor cx, cx
X int 021H
X jc Load_Error ; Abort - swap file error
X ret
X
X$Seek_Disk endp
X
X;
X; PANIC - Abort
X;
X
XLoad_Error proc near
X
X mov ax, 00900H
X mov dx, offset Swap_PANIC
X mov bx, cs
X mov ds, bx
X int 021H
X$Wait_L:
X sti
X hlt
X jmp $Wait_L
X
XLoad_Error endp
X
X;
X; WRITE EXTENDED MEMORY
X;
X; SI - Block count
X;
X$Write_extend proc near
X
X push si ; Save SI (block counter)
X mov cx, 02000H ; Copy a 16K block
X mov ax, cs ; Set up GDT address
X mov es, ax
X mov si, offset GD_table
X
X mov ah, 087H ; EMS function
X int 015H
X pop si
X ret
X
X$Write_extend endp
X
X;
X; READ FROM EXTENDED MEMORY
X;
X; SI - Block count
X;
X
X$Read_extend proc near
X
X call $Write_extend
X jc Load_Error ; NO - abort
X
X dec si ; Decrement block count
X
X$Read_extend endp
X
X;
X; INCREMENT Extended MEMORY GDT
X;
X; AX - used
X;
X$Inc_Extend proc near
X
X mov ax, 04000H ; Increment address by 16K
X add word ptr cs:GDT_dest_low, ax
X adc byte ptr cs:GDT_dest_high, 0
X add word ptr cs:GDT_src_low, ax
X adc byte ptr cs:GDT_src_high, 0
X ret
X
X$Inc_Extend endp
X
X;
X; LOAD SOURCE GDT ADDRESS
X;
X; AX - low order
X; DL - high order
X;
X$GDT_src_load proc near
X
X
X mov word ptr cs:GDT_src_low, ax
X mov byte ptr cs:GDT_src_high, dl
X ret
X
X$GDT_src_load endp
X
X;
X; LOAD DESTINATION GDT ADDRESS
X;
X; AX - low order
X; DL - high order
X;
X$GDT_dest_load proc near
X
X mov word ptr cs:GDT_dest_low, ax
X mov byte ptr cs:GDT_dest_high, dl
X ret
X
X$GDT_dest_load endp
X
X;
X; LOAD the GDT for reloading
X;
X
X$GDT_reload proc near
X mov ax, word ptr cs:_SW_EMstart ; Load Full start address
X mov dl, byte ptr cs:_SW_EMstart + 2
X call $GDT_src_load
X
X mov ax, word ptr cs:SW_LMstart ; Load Full start address
X mov dl, byte ptr cs:SW_LMstart + 2
X call $GDT_dest_load
X ret
X$GDT_reload endp
X
X;
X; CONTROL C INTERRUPT HANDLER - IGNORE
X;
X
XSA_IRET proc far
X push ax
X push bp ; Save the AX and DS registers
X push ds
X mov bp, seg SH0_TEXT ; Get my segment
X mov ds, bp
X inc word ptr ds:_SW_intr ; Set Interrupt 23 detected.
X cmp byte ptr ds:InShell, 0 ; Are we in the shell ?
X jz $SA_Ins
X
X; In another program - move the stack around
X
X mov bp, sp
X pop ds ; Unstack values
X pop bp
X pop ax
X stc
X ret
X
X
X; In shell - ignore interrupt 23 for the moment
X
X$SA_Ins:
X pop ds ; Restore regs
X pop bp
X pop ax
X iret
X
XSA_IRET endp
X
X;
X; DIVIDE BY ZERO INTERRUPT HANDLER - Output message
X;
X
XSA_DZERO proc far
X
X mov ax, 00900H
X mov dx, offset Swap_DZERO
X mov bx, cs
X mov ds, bx
X int 021H
X
X mov ax, 04CFFh ; Exit
X int 021H
X
XSA_DZERO endp
X
X;
X; Start of overwrite area for environment. Align on a paragraph
X;
X ALIGN 16
XEnv_OWrite:
XSH0_TEXT ends
X end
SHAR_EOF
echo "File shell/sh0.asm is complete"
chmod 0644 shell/sh0.asm || echo "restore of shell/sh0.asm fails"
set `wc -c shell/sh0.asm`;Sum=$1
if test "$Sum" != "17894"
then echo original size 17894, current size $Sum;fi
echo "x - extracting shell/sh.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > shell/sh.h &&
X/* MS-DOS SHELL - Header File
X *
X * MS-DOS SHELL - Copyright (c) 1990 Data Logic Limited and Charles Forsyth
X *
X * This code is based on (in part) the shell program written by Charles
X * Forsyth and is subject to the following copyright restrictions:
X *
X * 1. Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice is duplicated in the
X * source form and the copyright notice in file sh6.c is displayed
X * on entry to the program.
X *
X * 2. The sources (or parts thereof) or objects generated from the sources
X * (or parts of sources) cannot be sold under any circumstances.
X *
X * $Header: sh.h 1.1 90/01/29 17:46:51 MS_user Exp $
X *
X * $Log: sh.h $
X * Revision 1.1 90/01/29 17:46:51 MS_user
X * Initial revision
X *
X *
X */
X
X#define LINE_MAX 1000 /* Command line length */
X#define HISTORY_MAX 100 /* History array length */
X /* Space for full file name */
X#define FFNAME_MAX (PATH_MAX + NAME_MAX + 4)
X#define CMD_LINE_MAX 127 /* Max command line length */
X#define SSAVE_IO_SIZE 4 /* Save IO array malloc increment */
X
X#define NPUSH 8 /* limit to input nesting */
X
X#define NOFILE 20 /* Number of open files */
X#define NUFILE 10 /* Number of user-accessible files */
X#define FDBASE 10 /* First file usable by Shell */
X
X#define NL '\n'
X#define SP ' '
X#define NOT '^'
X /* Open in create mode */
X#define O_CMASK (O_WRONLY | O_CREAT | O_TRUNC | O_TEXT)
X /* Open in create mode for a pipe */
X#define O_PMASK (O_RDWR | O_CREAT | O_TRUNC | O_TEXT)
X /* Open in create mode for swap file */
X#define O_SMASK (O_RDWR | O_CREAT | O_TRUNC | O_BINARY)
X#define O_RMASK (O_RDONLY | O_NOINHERIT | O_TEXT)
X
X/*
X * shell components
X */
X
X#define QUOTE 0200
X#define CMASK 0377
X#define QMASK (CMASK & ~QUOTE)
X
X#define NOBLOCK ((C_Op *)NULL)
X#define NOWORD ((char *)NULL)
X#define NOWORDS ((char **)NULL)
X#define NOPIPE (-1)
X
X/*
X * Description of a command or an operation on commands.
X * Might eventually use a union.
X */
X
Xtypedef struct op {
X int type; /* operation type, see below */
X char **words; /* arguments to a command */
X struct ioword **ioact; /* IO actions (eg, < > >>) */
X struct op *left;
X struct op *right;
X char *str; /* identifier for case and for */
X} C_Op;
X
X#define TCOM 1 /* command */
X#define TPAREN 2 /* (c-list) */
X#define TPIPE 3 /* a | b */
X#define TLIST 4 /* a [&;] b */
X#define TOR 5 /* || */
X#define TAND 6 /* && */
X#define TFOR 7 /* FOR */
X#define TDO 8 /* DO */
X#define TCASE 9 /* CASE */
X#define TIF 10 /* IF */
X#define TWHILE 11 /* WHILE */
X#define TUNTIL 12 /* UNTIL */
X#define TELIF 13 /* ELSE IF */
X#define TPAT 14 /* pattern in case */
X#define TBRACE 15 /* {c-list} */
X#define TASYNC 16 /* c & */
X#define TFUNC 17 /* c () {c-list} */
X
X/* Built in Command list */
X
Xstruct builtin {
X char *command;
X int (*fn)(C_Op *);
X};
X
X/*
X * actions determining the environment of a process
X */
X
X#define FEXEC 0x0001 /* execute without forking */
X
X/* MSDOS Memory Control Block chain structure */
X
X#pragma pack (1)
Xstruct MCB_list {
X char MCB_type; /* M or Z */
X unsigned int MCB_pid; /* Process ID */
X unsigned int MCB_len; /* MCB length */
X};
X#pragma pack ()
X
X#define MCB_CON 'M' /* More MCB's */
X#define MCB_END 'Z' /* Last MCB's */
X
X/* Externs for Swapper assembler function */
X
Xextern char cmd_line[]; /* Command line */
Xextern char path_line[]; /* Process path */
Xextern unsigned int SW_intr; /* interrupt pending */
Xextern unsigned int SW_Blocks; /* Number of blocks to read */
Xextern int SW_fp; /* File or EMS Handler */
Xextern unsigned int SW_I0_V_BX; /* Out interrupt Zero address */
Xextern unsigned int SW_I0_V_ES;
Xextern unsigned int SW_I23_V_ES; /* Our Interrupt 23 address */
Xextern unsigned int SW_I23_V_BX;
Xextern unsigned long SW_EMstart; /* Start addr of extend mem */
Xextern unsigned int SW_Mode; /* Type of swapping to do */
X /* 1 - disk */
X /* 2 - Extended memory */
X /* 3 - Expanded memory */
Xextern unsigned int SW_EMSFrame; /* EMS Frame segment */
X
Xextern int Swap_Mode; /* Swapping mode */
X
X/* If you change these values, change sh7, swap_device as well */
X
X#define SWAP_OFF 0x0000 /* No swapping */
X#define SWAP_DISK 0x0001 /* Disk only */
X#define SWAP_EXTEND 0x0002 /* Extended memory */
X#define SWAP_EXPAND 0x0004 /* Expanded memory */
X
X/*
X * flags to control evaluation of words
X */
X
X#define DOSUB 0x01 /* interpret $, `, and quotes */
X#define DOBLANK 0x02 /* perform blank interpretation */
X#define DOGLOB 0x04 /* interpret [?* */
X#define DOKEY 0x08 /* move words with `=' to 2nd arg. list */
X#define DOTRIM 0x01 /* trim resulting string */
X
X#define DOALL (DOSUB | DOBLANK | DOGLOB | DOKEY | DOTRIM)
X
Xextern char *Copy_Right1;
Xextern char *Copy_Right2;
Xextern char **dolv; /* $<numeric> values */
Xextern int dolc; /* $<numeric> count */
Xextern int fn_area_number; /* Next function area number */
Xextern int exstat;
Xextern char gflg;
Xextern int talking; /* interactive (talking-type */
Xextern int execflg;
Xextern int multiline; /* \n changed to ; */
Xextern int *failpt;
Xextern int *errpt;
Xextern int inparse; /* In parser flag */
Xextern int Current_Event; /* Current history event */
X
X/*
X * Break/Continue (in for and while), Return and Exit handler
X */
X
Xtypedef struct brkcon {
X jmp_buf brkpt;
X struct brkcon *nextlev;
X} Break_C;
X /* Values returned by longjmp */
X#define BC_LOAD 0 /* Load condition */
X#define BC_BREAK 1 /* Break condition */
X#define BC_CONTINUE 2 /* Continue condition */
X
Xextern Break_C *Break_List; /* Break list for FOR/WHILE */
Xextern Break_C *Return_List; /* Return list for RETURN */
Xextern Break_C *SShell_List; /* SubShell list for EXIT */
Xextern bool level0; /* Level zero (read profile) */
Xextern bool r_flag; /* Read only shell */
Xextern bool History_Enabled;
X
X/*
X * Save Standard Input/Output/Error structure
X */
X
Xtypedef struct save_io {
X int depth; /* Execute recursive depth */
X int fp[STDERR_FILENO + 1]; /* File handlers */
X} Save_IO;
X
Xextern Save_IO *SSave_IO; /* Save IO array */
Xextern int NSave_IO_E; /* Number of entries */
Xextern int MSave_IO_E; /* Max Number of entries */
X
X/*
X * Function tree processing
X */
X
Xtypedef struct fun_op {
X struct fun_op *next; /* Link */
X C_Op *tree; /* The tree itself */
X} Fun_Ops;
X
Xextern Fun_Ops *fun_list; /* List header */
X
X/*
X * redirection
X */
X
Xtypedef struct ioword {
X short io_unit; /* unit affected */
X short io_flag; /* action (below) */
X char *io_name; /* file name */
X} IO_Actions;
X
X#define IOREAD 1 /* < */
X#define IOHERE 2 /* << (here file) */
X#define IOWRITE 4 /* > */
X#define IOCAT 8 /* >> */
X#define IOXHERE 16 /* ${}, ` in << */
X#define IODUP 32 /* >&digit */
X#define IOCLOSE 64 /* >&- */
X
X#define IODEFAULT (-1) /* token for default IO unit */
X
X/*
X * parsing & execution environment
X */
X
Xtypedef struct env {
X char *cline; /* Current line buffer */
X char *linep; /* Current pointer in line */
X char *eline; /* End of line pointer */
X struct io *iobase;
X struct io *iop;
X int *errpt;
X int iofd;
X struct env *oenv; /* Previous environment */
X} Environ;
X
Xextern Environ e;
X
X/*
X * here documents
X */
X
Xtypedef struct here {
X char *h_tag;
X int h_dosub;
X IO_Actions *h_iop;
X struct here *h_next;
X} Here_D;
X
X/*
X * flags:
X *
X * -a: Set all environment variables to exported
X * -e: Quit on error
X * -f: Disable file name expansion
X * -k: Look for name=value everywhere on command line
X * -n: No execution
X * -t: exit after reading and executing one command
X * -u: Abort if environment variable is not set
X * -v: Echo as read
X * -x: Trace
X */
X
X#define FL_TEST(x) (flags & (1L << ((x) - 'a')))
X#define FL_SET(x) flags |= (1L << ((x) - 'a'))
X#define FL_CLEAR(x) flags &= (~(1L << ((x) - 'a')))
X
Xextern long flags;
Xextern char *null; /* null value for variable */
Xextern long ourtrap; /* Signal processing required */
Xextern int trapset; /* trap pending */
Xextern int yynerrs; /* yacc */
Xextern int Execute_stack_depth; /* execute function recursion */
X /* depth */
X
X/*
X * Variable list
X */
X
Xtypedef struct var {
X char *value; /* Value */
X char *name; /* Name */
X struct var *next; /* Link */
X char status; /* Type, see below */
X} Var_List;
X
X#define COPYV 1 /* flag to setval, suggesting copy */
X#define RONLY 0x01 /* variable is read-only */
X#define EXPORT 0x02 /* variable is to be exported */
X#define GETCELL 0x04 /* name & value space was got with getcell */
X#define PONLY 0x08 /* PATH Value - no unset */
X#define C_MSDOS 0x10 /* Convert to MSDOS format */
X
Xextern Var_List *vlist; /* dictionary */
Xextern Var_List **S_UL; /* Start address update location */
Xextern Var_List *path; /* search path for commands */
Xextern Var_List *ps1; /* Prompt 1 */
Xextern Var_List *ps2; /* Prompt 2 */
Xextern Var_List *ifs; /* Interfield separators */
Xextern Var_List *C_dir; /* Current directory */
Xextern char *last_prompt; /* Last prompt output */
Xextern char *home; /* Home string */
Xextern char *shell; /* Shell string */
Xextern char *hsymbol; /* Hash string */
Xextern char *msymbol; /* Minus string */
Xextern char *spcl2;
Xextern char *history_file;
X
X/*
X * SubShell Save Structure
X */
X
Xtypedef struct subshell {
X int depth; /* Sub_Shell Depth */
X Var_List *header; /* Header start */
X} S_SubShell;
X
Xextern S_SubShell *SubShells; /* Save Vars array */
Xextern int NSubShells; /* Number of entries */
Xextern int MSubShells; /* Max Number of entries */
X
X/* io buffer */
X
Xtypedef struct iobuf {
X unsigned int id; /* buffer id */
X char buf[512]; /* buffer */
X char *bufp; /* pointer into buffer */
X char *ebufp; /* pointer to end of buffer */
X} IO_Buf;
X
X/* possible arguments to an IO function */
X
Xtypedef struct ioarg {
X char *aword;
X char **awordlist;
X int afile; /* file descriptor */
X unsigned int afid; /* buffer id */
X long afpos; /* file position */
X IO_Buf *afbuf; /* buffer for this file */
X} IO_Args;
X
X#define AFID_NOBUF (~0)
X#define AFID_ID 0
X
Xextern IO_Args ioargstack[NPUSH]; /* IO argument stack */
X
X/* an input generator's state */
X
Xtypedef struct io {
X int (*iofn)(struct io *);
X IO_Args *argp;
X int peekc;
X char prev; /* previous character read by readc() */
X char nlcount; /* for `'s */
X char xchar; /* for `'s */
X char task; /* reason for pushed IO */
X char dflag; /* Special processing flag */
X} IO_State;
X
X#define DSA_NULL 0x00 /* No special processing req */
X#define DSA_STAR 0x01 /* Special processing for "$*" */
X#define DSA_AMP 0x02 /* Special processing for "$@" */
X#define DSA_MODE 0x03 /* Mode flag */
X#define DSA_END 0x04 /* Last word processing */
X#define DSA_START 0x08 /* First word processed? */
X#define DSA_START1 0x10 /* Subsequent word processed */
X#define DSA_END1 0x20 /* End processing for word */
X
Xextern IO_State iostack[NPUSH]; /* IO Stack */
X
X#define XOTHER 0 /* none of the below */
X#define XDOLL 1 /* expanding ${} */
X#define XGRAVE 2 /* expanding `'s */
X#define XIO 3 /* file IO */
X
X/* in substitution */
X
X#define INSUB() (e.iop->task == XGRAVE || e.iop->task == XDOLL)
X
X/*
X * IO control
X */
X
Xextern IO_Args temparg; /* temporary for PUSHIO */
X#define PUSHIO(what,arg,gen) ((temparg.what = (arg)), pushio(&temparg,(gen)))
X#define RUN(what,arg,gen) ((temparg.what = (arg)), run(&temparg,(gen)))
X
Xtypedef struct wdblock {
X short w_bsize;
X short w_nword;
X char *w_words[1];
X} Word_B;
X
Xextern Word_B *wdlist;
Xextern Word_B *iolist;
X
X/*
X * storage allocation
X */
X
Xextern int areanum; /* current allocation area */
X
X#define NEW(type) (type *)getcell (sizeof (type))
X#define DELETE(obj) freecell ((char *)obj)
X
X/* Functions */
X
Xextern void main (int, char **);
Xextern void setdash (void);
Xextern void fail (void);
Xextern void leave (void);
Xextern void print_warn (char *, ...);
Xextern void print_error (char *, ...);
Xextern bool newenv (int);
Xextern void quitenv (void);
Xextern char *putn (int);
Xextern void next (int);
Xextern void onintr (int);
Xextern char *space (int);
Xextern char *strsave (char *, int);
Xextern void sig (int);
Xextern void runtrap (int);
Xextern Var_List *lookup (char *, bool);
Xextern void setval (Var_List *, char *);
Xextern void s_vstatus (Var_List *, int);
Xextern bool isassign (char *);
Xextern bool assign (char *, int);
Xextern bool gmatch (char *, char *, bool);
Xextern char *getcell (unsigned int);
Xextern void freecell (char *);
Xextern void freearea (int);
Xextern void setarea (char *, int);
Xextern int getarea (char *);
Xextern C_Op *yyparse (void);
Xextern int execute (C_Op *, int, int, int);
Xextern int run (IO_Args *, int (*)(IO_State *));
Xextern int Getc (int);
Xextern void unget (int);
Xextern int eofc (void);
Xextern int readc (void);
Xextern void pushio (IO_Args *, int (*)(IO_State *));
Xextern int nlchar (IO_State *);
Xextern int wdchar (IO_State *);
Xextern int dol_char (IO_State *);
Xextern int strchar (IO_State *);
Xextern int qstrchar (IO_State *);
Xextern int filechar (IO_State *);
Xextern int gravechar (IO_State *);
Xextern int qgravechar (IO_State *);
Xextern int linechar (IO_State *);
Xextern void closeall (void);
Xextern int remap (int);
Xextern int openpipe (void);
Xextern void closepipe (int);
Xextern void markhere (char *, IO_Actions *);
Xextern void gethere (void);
Xextern int herein (char *, int);
Xextern void scraphere (void);
Xextern void freehere (int);
X
Xextern char **eval (char **, int);
Xextern char **makenv (void);
Xextern char *evalstr (char *, int);
Xextern int subgetc (char, int);
Xextern Word_B *addword (char *, Word_B *);
Xextern char **getwords (Word_B *);
Xextern void put_prompt (char *);
Xextern bool eqname (char *, char *);
Xextern bool any (char, char *);
Xextern int (*inbuilt (char *))();
Xextern char *path_append (char *, char *, char *);
Xextern void unset (char *, bool);
Xextern int S_open (bool, char *, int, ...);
Xextern int S_close (int, bool);
Xextern int S_dup (int);
Xextern int S_dup2 (int, int);
Xextern void S_Remap (int, int);
Xextern void S_Delete (int);
Xextern void Getcwd (void);
Xextern char *g_tempname (void);
Xextern void S_puts (char *);
Xextern void S_putc (int);
Xextern bool check_rsh (char *);
Xextern int O_for_execute (char *);
Xextern int SA_spawn (char **);
Xextern char *findeq (char *);
Xextern int restore_std (int);
Xextern void Load_History (void);
Xextern void Dump_History (void);
Xextern void Display_History (void);
Xextern void Clear_History (void);
Xextern void v1_puts (char *);
Xextern void v1a_puts (char *);
Xextern void v1_putc (char);
Xextern void v1printf (char *, ...);
Xextern int Get_stdin (IO_Args *);
Xextern int Process_Escape (char **);
Xextern void Add_History (bool);
Xextern void Convert_Slashes (char *);
Xextern void Print_ExTree (C_Op *);
Xextern Fun_Ops *Fun_Search (char *);
Xextern void Save_Function (C_Op *, bool);
Xextern int getn (char *);
Xextern int Create_NG_VL (void);
Xextern void Delete_G_VL (void);
Xextern void Restore_Dir (void);
Xextern void Restore_Environment (int, int);
Xextern int sort_compare (char **, char **);
Xextern int Check_Script (char *);
SHAR_EOF
chmod 0644 shell/sh.h || echo "restore of shell/sh.h fails"
set `wc -c shell/sh.h`;Sum=$1
if test "$Sum" != "15317"
then echo original size 15317, current size $Sum;fi
rm -f s2_seq_.tmp
echo "You have unpacked the last part"
exit 0
--
Regards,
Ian Stewartson
Data Logic Ltd.