From decwrl!sdd.hp.com!cs.utexas.edu!uunet!allbery Mon May 7 07:37:08 PDT 1990 Article 1499 of comp.sources.misc: Path: decwrl!sdd.hp.com!cs.utexas.edu!uunet!allbery From: istewart@datlog.co.uk Newsgroups: comp.sources.misc Subject: v12i020: MS_SH 1.6 Upgrade Kit - Part 02 of 08 Message-ID: <87522@uunet.UU.NET> Date: 5 May 90 17:05:53 GMT Sender: allbery@uunet.UU.NET Lines: 1817 Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) Posting-number: Volume 12, Issue 20 Submitted-by: istewart@datlog.co.uk Archive-name: ms_sh-1.6/part02 #!/bin/sh # this is part 2 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # file Patch1.6 continued # CurArch=2 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 Patch1.6" sed 's/^X//' << 'SHAR_EOF' >> Patch1.6 X X ; X ; Some addition variables X--- 88,118 ---- X public _SW_fp X public _SW_I0_V X public _SW_I23_V X public _SW_EMstart X public _SW_Mode X public _SW_EMSFrame X public _SW_Int24 X+ public _SW_XMS_Driver X+ public _SW_XMS_Gversion X+ public _SW_XMS_Allocate X+ public _SW_XMS_Free X X+ X _cmd_line db 129 dup (?) ; Command line X _path_line db 80 dup (?) ; Path line X _SW_Blocks dw 0 ; Number of blocks to read/write X _SW_fp dw 0 ; File ID X _SW_I0_V dd 0 ; Our Interrupt Zero address X _SW_I23_V dd 0 ; Our Interrupt 23 address X _SW_EMstart dd 0100000H ; Default Extended Mem start X _SW_Mode dw 0 ; Type of swapping to do X ; 1 - disk X ; 2 - Extended memory X! ; 3 - EMS driver X! ; 4 - XMS driver X _SW_EMSFrame dw 0 ; EMS Frame segment X _SW_intr dw 0 ; Interrupt 23 detected. X+ _SW_XMS_Driver dd 0 ; XMS Driver Interface X X ; X ; Some addition variables X*************** X*** 120,128 **** X FCB2 dw 16 dup (?) X X ; X! ; Extended Memory Global Descriptor tables X ; X X GD_table equ $ X GDT_Dummy dw 4 dup (0) ; Dummy X GDT_self dw 4 dup (0) ; For self X--- 141,160 ---- X FCB2 dw 16 dup (?) X X ; X! ; XMS Driver Move structure X ; X X+ XMS_DIF equ $ X+ XMS_Length dd 0 ; Number of bytes X+ XMS_SHandle dw 0 ; Source Handler X+ XMS_Soffset dd 0 ; Source Offset X+ XMS_DHandle dw 0 ; Destination Handler X+ XMS_Doffset dd 0 ; Destination Offset X+ X+ ; X+ ; Extended Memory Global Descriptor tables X+ ; X+ org XMS_DIF X GD_table equ $ X GDT_Dummy dw 4 dup (0) ; Dummy X GDT_self dw 4 dup (0) ; For self X*************** X*** 297,315 **** 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--- 329,396 ---- X X $Write_loop: X or si, si X! jnz $Write_L1 X! jmp $Write_Complete X X ; OK - Copy next 0x4000 bytes - switch on device X X+ $Write_L1: X mov ax, word ptr cs: _SW_Mode X dec ax X jz $Write_disk X dec ax X! jnz $Write_L2 X! jmp $W_extend X! $Write_L2: X! dec ax X! jnz $W_xms X jmp $W_expand X X! ; X! ; Write to XMS driver. In this case, we do one write and let the driver X! ; sort out the blocking X! ; X! $W_xms: X! xor ax, ax X! mov word ptr cs:XMS_SHandle, ax ; Source - normal memory X! mov word ptr cs:XMS_DHandle, bx ; Dest - XMS X X+ mov word ptr cs:XMS_Doffset, ax ; Dest offset - zero X+ mov word ptr cs:XMS_Doffset + 2, ax X+ X+ mov word ptr cs:XMS_Soffset, ax ; Source offset DS:0 X+ mov ax, ds X+ mov word ptr cs:XMS_Soffset + 2, ax X+ X+ ; X+ ; Set up number of bytes SW_Block * 16 * 1024 X+ ; X+ X+ mov ax, si X+ mov dx, si X+ mov cl, 14 X+ shl ax, cl X+ mov cl, 2 X+ shr dx, cl X+ mov word ptr cs:XMS_Length, ax ; Load number of bytes X+ mov word ptr cs:XMS_Length + 2, dx X+ X+ mov ah, 0BH ; Set up parameters X+ mov dx, cs X+ mov ds, dx X+ mov si, offset XMS_DIF X+ call cs:[_SW_XMS_Driver] X+ or ax, ax X+ jnz $Write_Complete X+ X+ ; XMS error - abort X+ X+ mov ah, bl X+ jmp $Write_error X+ X+ ; X+ ; Write to disk X+ ; X $Write_disk: X mov ax, 04000H ; Set up to write X mov cx, ax ; Load count X*************** X*** 321,328 **** 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--- 402,425 ---- X X pop si ; Restore Regs X pop bx X! jnc $Write_disk1 ; NO error - continue X X+ ; X+ ; Error - abort X+ ; X+ mov ds, word ptr cs:S_ds ; Restore DS X+ mov ah, al X+ call far ptr __maperror ; Map the error X+ jmp $Write_Error1 X+ X+ ; Check for 16K write X+ X+ $Write_disk1: X+ cmp ax, 04000H X+ jz $Write_Incr X+ mov ax,01c1cH ; Set disk full X+ jmp $Write_error ; NO - abort X+ X $Write_Incr: X dec si ; Decrement block count X mov ax, ds ; Increment offset X*************** X*** 372,377 **** X--- 469,475 ---- X mov al, ah X xor ah, ah X mov word ptr ds:_errno, ax ; Save error code X+ $Write_Error1: X mov ax, 0FFFEH X jmp $SA_spawn_Exit ; Exit X X*************** X*** 642,651 **** 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--- 740,757 ---- X jz $R_disk X dec ax X jz $R_extend X! dec ax X! jz $R_expand X X! ; X! ; Read from XMS driver. In this case, we do one read and let the driver X! ; sort out the blocking X! ; X! call $Read_XMS X! jmp $Read_Complete X X+ ; Read from disk X+ X $R_disk: X call $Read_disk X jmp $Read_loop X*************** X*** 676,681 **** X--- 782,788 ---- X ; Save exit code X X push word ptr cs:Result ; Save response X+ push word ptr cs:_SW_intr ; and interrupt flag X X ; X ; Read in the first block - BX - File Handler X*************** X*** 702,709 **** 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--- 809,821 ---- X jz $R1_Disk X dec ax X jz $R1_Extend X! dec ax X! jz $R1_Expand X X+ mov si, 1 ; Read one block X+ call $Read_XMS X+ jmp $Read1_OK X+ X $R1_Disk: X call $Read_disk X jmp $Read1_OK X*************** X*** 721,726 **** X--- 833,839 ---- X ; X X $Read1_OK: X+ pop word ptr cs:_SW_intr ; Restore interrupt flag X pop ax X X ; X*************** X*** 757,776 **** 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--- 870,941 ---- 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 XMS DRIVER FUNCTION X ; X ; BX - file handler X ; SI - Block count X ; DS - Output data segement X ; X+ $Read_XMS proc near X+ xor ax, ax X+ mov word ptr cs:XMS_SHandle, bx ; Source - XMS X+ mov word ptr cs:XMS_DHandle, ax ; Dest - normal memory X X+ mov word ptr cs:XMS_Soffset, ax ; Source offset - zero X+ mov word ptr cs:XMS_Soffset + 2, ax X+ X+ mov word ptr cs:XMS_Doffset, ax ; Dest offset DS:0 X+ mov ax, ds X+ mov word ptr cs:XMS_Doffset + 2, ax X+ X+ cmp si, 1 ; If first block, the X+ jz $Read_X1 ; source offset is X+ ; 4000H X+ mov word ptr cs:XMS_Soffset, 04000H X+ X+ ; X+ ; Set up number of bytes: si * 16 * 1024 X+ ; X+ X+ $Read_X1: X+ mov ax, si X+ mov dx, si X+ mov cl, 14 X+ shl ax, cl X+ mov cl, 2 X+ shr dx, cl X+ mov word ptr cs:XMS_Length, ax ; Load number of bytes X+ mov word ptr cs:XMS_Length + 2, dx X+ X+ mov ah, 0BH ; Set up parameters X+ mov dx, cs X+ mov ds, dx X+ mov si, offset XMS_DIF X+ call cs:[_SW_XMS_Driver] X+ or ax, ax X+ jnz $Read_XMS1 X+ jmp Load_Error ; XMS error - abort X+ X+ $Read_XMS1: X+ ret X+ X+ $Read_XMS 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*************** X*** 872,882 **** X X Load_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--- 1037,1046 ---- X X Load_Error proc near X X! mov di, offset Swap_PANIC X mov bx, cs X mov ds, bx X! call I24_Display X $Wait_L: X sti X hlt X*************** X*** 1021,1059 **** X ; X ; INTERRUPT 24 - ERROR HANDLER - Output message X ; X X! _SW_Int24 proc far X! pushf ; Save flags X! call dword ptr cs:_SW_I24_V X X! cmp byte ptr cs:InShell, 0 ; Are we in the shell ? X! jnz $SW_int24c ; No - no processing X X! test ah, 010h X! jnz $SW_int24a X! test ah, 008h X! jnz $SW_int24b X X! mov al, 003h ; Fail system call X X- $SW_int24c: X- iret X- X ; X! $SW_int24a: X! xor al, al ; Ignore error X! iret X! X ; X! $SW_int24b: X! mov al, 001h ; Retry error X iret X _SW_Int24 endp X X ; X! ; Start of overwrite area for environment. Align on a paragraph X ; X ALIGN 16 X Env_OWrite: X SH0_TEXT ends X end X--- 1185,1690 ---- X ; X ; INTERRUPT 24 - ERROR HANDLER - Output message X ; X+ ; AH - Bit 7 = 0 Disk error X+ ; = 1 FAT error if block device X+ ; Error code in DI if character device X+ ; Bit 6 UNUSED X+ ; Bit 5 = 1 Ignore allowed X+ ; Bit 4 = 1 Retry allowed X+ ; Bit 3 = 1 Fail allowed X+ ; Bits 2 & 1 = Disk Area X+ ; Bit 0 = 1 Writing error X+ ; AL = Disk drive number X+ ; DI = Error code X+ ; BP:SI = Header of device driver for which error occured X+ ; X+ ; X+ ; Return X+ ; AL = 0 Ignore Error X+ ; = 1 Retry operation X+ ; = 2 Abort program X+ ; = 3 Fail system call X+ ; X X! I24_Errors equ $ X! I24_EC00: db 'Write protect error$' X! I24_EC01: db 'Unknown unit$' X! I24_EC02: db 'Drive not ready$' X! I24_EC03: db 'Unknown command$' X! I24_EC04: db 'Data error$' X! I24_EC05: db 'Bad request$' X! I24_EC06: db 'Seek error$' X! I24_EC07: db 'Unknown media type$' X! I24_EC08: db 'Sector not found$' X! I24_EC09: db 'Paper out$' X! I24_EC0A: db 'Write fault$' X! I24_EC0B: db 'Read fault$' X! I24_EC0C: db 'General failure$' X! I24_EC0D: db 'Unknown code$' X! I24_EC0F: db 'Invalid disk change$' X! I24_EC10: db 'FCB unavailable$' X! I24_EC11: db 'Sharing buffer overflow$' X X! ; X! ; Error message address table X! ; X X! I24_ECTABLE: dw offset I24_EC00 X! dw offset I24_EC01 X! dw offset I24_EC02 X! dw offset I24_EC03 X! dw offset I24_EC04 X! dw offset I24_EC05 X! dw offset I24_EC06 X! dw offset I24_EC07 X! dw offset I24_EC08 X! dw offset I24_EC09 X! dw offset I24_EC0A X! dw offset I24_EC0B X! dw offset I24_EC0C X! dw offset I24_EC0D X! dw offset I24_EC0D ; 0E - no message X! dw offset I24_EC0F X! dw offset I24_EC10 X! dw offset I24_EC11 X X! I24_ECON: db ' when $' X! I24_ECREAD: db 'reading $' X! I24_ECWRITE: db 'writing $' X! I24_ECDEVICE: db 'device $' X! I24_ECDISK: db 'disk $' X! I24_EABORT: db 'Abort$' X! I24_EFAIL: db ', Fail$' X! I24_EIGNORE: db ', Ignore$' X! I24_ERETRY: db ', Retry$' X! I24_EDRIVE: db '?$' X! I24_EQUESTION db '? $' X! I24_RESPONSE: db ' ' X! I24_ENL: db 0dH, 0aH, '$' X! I24_EBELL: db 07H, '$' X! I24_EDNAME: db '12345678$' X! I24_EXTECODE: db 0dH, 0aH, '(Extended Code: ' X! I24_E_AL: db ' ' X! db ' Class: ' X! I24_E_BH: db ' ' X! db ' Action: ' X! I24_E_BL: db ' ' X! db ' Locus: ' X! I24_E_CH: db ' )', 0dH, 0aH, '$' X X ; X! ; Save DS, ES, BX, CX, DX X ; X! _SW_Int24 proc far X! push ds ; Save registers X! push es X! push bx X! push cx X! push dx X! X! push cs ; Set up data segment X! pop ds X! X! mov cx, ax ; Save the error information in CX X! X! push di X! mov di, offset I24_ENL X! call I24_Display X! pop di X! X! ; X! ; Check inside message range X! ; X! cmp di, 012H X! jb SWI24a X! mov di, 0dH X! X! ; X! ; Write the error message X! ; X! X! SWI24a: X! add di, di X! X! mov di, word ptr ds:I24_ECTABLE[di] X! call I24_Display X! X! ; X! ; Output on message X! ; X! X! mov di, offset I24_ECON X! call I24_Display X! X! ; X! ; Output reading or write message X! ; X! X! mov di, offset I24_ECWRITE X! test ch, 01H X! jnz SWI24b X! mov di, offset I24_ECREAD X! X! SWI24b: X! call I24_Display X! X! ; X! ; Output device message X! ; X! X! test ch, 080H X! jz SWI24c X! X! mov di, offset I24_ECDEVICE X! call I24_Display X! X! ; X! ; Output device name - up to eight characters X! ; X! X! add si, 0aH ; Move to device name X! push ds X! mov ds, bp X! xor di, di ; Set counter X! X! SWI24b1: X! mov dl, byte ptr ds:[si] ; Get next character in name X! cmp dl, ' ' X! jz SWI24d X! X! mov byte ptr cs:[I24_EDNAME + di], dl X! X! inc si X! inc di X! cmp di, 8 X! jnz SWI24b1 X! ; X! ; Append a $ X! ; X! X! SWI24d: X! pop ds X! mov byte ptr cs:[I24_EDNAME + di], '$' X! mov di, offset I24_EDNAME X! jmp SWI24e X! X! ; X! ; Write disk error X! ; X! SWI24c: X! mov di, offset I24_ECDISK X! call I24_Display X! X! mov dl, cl X! add dl, 'A' X! mov byte ptr cs:I24_EDRIVE, dl X! X! mov di, offset I24_EDRIVE X! SWI24e: X! call I24_Display X! X! ; X! ; Get extended error codes X! ; X! push cx X! push ds X! mov ah, 059H X! xor bx, bx X! int 021H X! X! ; X! ; Save responses X! ; X! X! mov byte ptr cs:I24_E_AL, al X! mov byte ptr cs:I24_E_BL, bl X! mov byte ptr cs:I24_E_BH, bh X! mov byte ptr cs:I24_E_CH, ch X! pop ds X! pop cx X! X! ; Convert to display Hex. X! X! mov di, offset I24_E_AL X! call I24_Convert X! mov di, offset I24_E_BL X! call I24_Convert X! mov di, offset I24_E_BH X! call I24_Convert X! mov di, offset I24_E_CH X! call I24_Convert X! mov di, offset I24_EXTECODE X! call I24_Display X! ; X! ; Output Options X! ; X! mov di, offset I24_EABORT X! call I24_Display X! X! test ch, 020H ; Ignore allowed ? X! jz SWI24f X! mov di, offset I24_EIGNORE X! call I24_Display X! X! SWI24f: X! test ch, 010H ; Retry allowed ? X! jz SWI24g X! mov di, offset I24_ERETRY X! call I24_Display X! X! SWI24g: X! test ch, 08H ; Fail allowed ? X! jz SWI24h X! mov di, offset I24_EFAIL X! call I24_Display X! X! ; X! ; Append a question mark. X! ; X! X! SWI24h: X! mov di, offset I24_EQUESTION X! call I24_Display X! X! ; X! ; Get the valid key codes X! ; X! SWI24j: X! xor ax, ax ; Read a keyboard character X! int 16H X! and al, 05fH ; Upper case X! X! xor ah, ah ; Clear counter X! cmp al, 'I' ; Ignore ? X! jnz SWI24k X! test ch, 020H X! jnz SWI24n X! SWI24k: X! inc ah X! cmp al, 'R' ; Retry ? X! jnz SWI24l X! test ch, 010H X! jnz SWI24n X! SWI24l: X! inc ah X! cmp al, 'A' ; Abort ? X! jz SWI24n X! X! inc ah X! cmp al, 'F' ; Fail ? X! jnz SWI24m X! test ch, 08H X! jnz SWI24n X! SWI24m: X! mov di, offset I24_EBELL X! call I24_Display X! jmp SWI24j X! X! ; X! ; OK - got code X! ; X! SWI24n: X! mov cl, ah X! mov byte ptr ds:I24_RESPONSE, al X! mov di, offset I24_RESPONSE X! call I24_Display X! mov ax, cx X! X! ; X! ; Are we in the shell ? X! ; X! cmp byte ptr cs:InShell, 0 ; Are we in the shell ? X! jnz $SW_int24a ; No - no processing X! X! cmp al, 02H ; Abort? X! jnz $SW_int24a ; No - exit X! X! test ah, 008h ; If fail allowed - convert to fail X! jz $SW_int24a X! X! mov al, 003h ; Fail system call X! X! $SW_int24a: X! pop dx ; Restore registers X! pop cx X! pop bx X! pop es X! pop ds X iret X _SW_Int24 endp X X ; X! ; Convert Hex code to display code X ; X+ ; ds:di Offset of code to replace X+ ; ax is available X+ ; X+ I24_Convert proc near X+ push cx X+ mov al, byte ptr ds:[di] ; Get the code X+ mov ah, al X+ mov cl, 4 X+ shr ah, cl X+ and ah, 0fh X+ X+ cmp ah, 10 X+ jb I24_C1 X+ add ah, 'A' - 10 X+ jmp I24_C2 X+ I24_C1: X+ add ah, '0' X+ I24_C2: X+ mov byte ptr ds:[di], ah X+ X+ ; Now LSB X+ X+ and al, 0fh X+ cmp al, 10 X+ jb I24_C3 X+ add al, 'A' - 10 X+ jmp I24_C4 X+ I24_C3: X+ add al, '0' X+ I24_C4: X+ mov byte ptr ds:[di + 1], al X+ pop cx X+ ret X+ I24_Convert endp X+ ; X+ ; Display message function for Interrupt 24 processing X+ ; X+ ; DS:DI message X+ ; AX is available X+ ; X+ X+ I24_Display proc near X+ mov ah, 08H ; Get foreground colour X+ xor bx, bx X+ int 10H X+ mov bl, ah X+ and bl, 07h X+ X+ ; X+ ; Loop until a $ is hit, outputting the characters X+ ; X+ I24D: X+ mov al, byte ptr ds:[di] X+ cmp al, '$' X+ jnz I24Da X+ ret X+ X+ I24Da: X+ push di X+ mov ah, 0EH X+ int 10H X+ pop di X+ inc di X+ jmp I24D X+ X+ I24_Display endp X+ X+ ; X+ ; Start of overwrite area for environment. Align on a paragraph X+ ; X+ ; Also the XMS driver functions used by SH3.C live here X+ ; X ALIGN 16 X Env_OWrite: X+ X+ ; X+ ; XMS INTERFACE X+ ; X+ ; Get Version number. Return the release number in AX X+ ; X+ X+ _SW_XMS_Gversion proc far X+ X+ push bp ; Save stack info X+ mov bp, sp X+ X+ xor ax, ax X+ call cs:[_SW_XMS_Driver] X+ X+ mov sp, bp X+ pop bp X+ ret X+ X+ _SW_XMS_Gversion endp X+ X+ ; X+ ; Allocate N kbytes. Return the Handler in AX or -1 and error code in X+ ; errno. X+ ; X+ ; Size will be in bp + 6. X+ ; X+ X+ _SW_XMS_Allocate proc far X+ X+ push bp ; Save stack info X+ mov bp, sp X+ X+ mov dx, word ptr ss:[bp + 6] X+ mov ah, 09H X+ call cs:[_SW_XMS_Driver] X+ or ax, ax X+ jnz $SW_A1 X+ X+ ; X+ ; Allocate Failed - return error code X+ ; X+ xor ax, ax X+ neg ax X+ xor bh, bh X+ mov word ptr ds:_errno, bx ; Save error code X+ jmp $SW_F2 X+ X+ ; X+ ; Allocate OK - return handler X+ ; X+ X+ $SW_A1: X+ mov ax, dx X+ X+ $SW_A2: X+ mov sp, bp X+ pop bp X+ ret X+ X+ _SW_XMS_Allocate endp X+ X+ ; X+ ; Release handler. Return 0 or error code. X+ ; X+ ; Handler will be in bp + 6. X+ ; X+ X+ _SW_XMS_Free proc far X+ X+ push bp ; Save stack info X+ mov bp, sp X+ X+ mov dx, word ptr ss:[bp + 6] X+ mov ah, 0AH X+ call cs:[_SW_XMS_Driver] X+ or ax, ax X+ jnz $SW_F1 X+ ; X+ ; Free Failed - return error code X+ ; X+ mov al, bl X+ jmp $SW_F2 X+ X+ ; X+ ; Free OK - return zero X+ ; X+ $SW_F1: X+ xor ax, ax X+ X+ $SW_F2: X+ mov sp, bp X+ pop bp X+ ret X+ X+ _SW_XMS_Free endp X SH0_TEXT ends X end XIndex: shell/sh2.c XPrereq: 1.1 X*** ../sh15/shell/sh2.c Fri Feb 16 19:22:55 1990 X--- shell/sh2.c Tue May 1 19:48:35 1990 X*************** X*** 13,21 **** 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: sh2.c 1.1 90/01/25 13:41:12 MS_user Exp $ X * X * $Log: sh2.c $ X * Revision 1.1 90/01/25 13:41:12 MS_user X * Initial revision X * X--- 13,34 ---- 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: sh2.c 1.5 90/04/25 09:18:38 MS_user Exp $ X * X * $Log: sh2.c $ X+ * Revision 1.5 90/04/25 09:18:38 MS_user X+ * Fix for ... do to not require terminating colon X+ * X+ * Revision 1.4 90/03/14 19:30:06 MS_user X+ * Make collect a global for here document processing. X+ * Add IOTHERE support to detect <<- redirection X+ * X+ * Revision 1.3 90/03/06 16:49:42 MS_user X+ * Add disable history option X+ * X+ * Revision 1.2 90/03/05 13:49:41 MS_user X+ * Change talking checks X+ * X * Revision 1.1 90/01/25 13:41:12 MS_user X * Initial revision X * X*************** X*** 98,104 **** X static IO_Actions *io (int, int, char *); X static void yyerror (char *); X static int yylex (int); X- static int collect (int, int); X static int dual (int); X static void diag (int); X static char *tree (unsigned int); X--- 111,116 ---- X*************** X*** 339,347 **** X multiline++; X t->words = wordlist (); X X! if (((c = yylex (0)) != NL) && (c != ';')) X! yyerror (syntax_err); X X t->left = dogroup (0); X multiline--; X break; X--- 351,366 ---- X multiline++; X t->words = wordlist (); X X! /* CHeck for "for word in word...; do" versus "for word do" */ X X+ c = yylex (0); X+ X+ if ((t->words == (char **)NULL) && (c != NL)) X+ peeksym = c; X+ X+ else if ((t->words != (char **)NULL) && (c != NL) && (c != ';')) X+ yyerror (syntax_err); X+ X t->left = dogroup (0); X multiline--; X break; X*************** X*** 353,359 **** X t->type = (c == WHILE) ? TWHILE : TUNTIL; X t->left = c_list (FALSE); X t->right = dogroup (1); X! t->words = NULL; X multiline--; X break; X X--- 372,378 ---- X t->type = (c == WHILE) ? TWHILE : TUNTIL; X t->left = c_list (FALSE); X t->right = dogroup (1); X! t->words = (char **)NULL; X multiline--; X break; X X*************** X*** 531,537 **** X X static C_Op *block (type, t1, t2, wp) X C_Op *t1, *t2; X! char **wp; X { X register C_Op *t = (C_Op *)tree (sizeof (C_Op)); X X--- 550,556 ---- X X static C_Op *block (type, t1, t2, wp) X C_Op *t1, *t2; X! char **wp; X { X register C_Op *t = (C_Op *)tree (sizeof (C_Op)); X X*************** X*** 643,649 **** X { X yynerrs++; X X! if (talking && e.iop <= iostack) X { X multiline = 0; X X--- 662,668 ---- X { X yynerrs++; X X! if (Interactive ()) X { X multiline = 0; X X*************** X*** 759,767 **** X X if (multiline || (cf & CONTIN)) X { X! if (talking && e.iop <= iostack) X { X Add_History (FALSE); X put_prompt (ps2->value); X } X X--- 778,788 ---- X X if (multiline || (cf & CONTIN)) X { X! if (Interactive ()) X { X+ #ifndef NO_HISTORY X Add_History (FALSE); X+ #endif X put_prompt (ps2->value); X } X X*************** X*** 801,816 **** X return WORD; X } X X! static int collect (c, c1) X register int c, c1; X { X char *s = "x\n"; X X! *e.linep++ = (char)c; X X while ((c = Getc (c1)) != c1) X { X! if (c == 0) X { X unget (c); X *s = (char)c1; X--- 822,839 ---- X return WORD; X } X X! /* Read input until we read the specified end character */ X! X! int collect (c, c1) X register int c, c1; X { X char *s = "x\n"; X X! *e.linep++ = (char)c; /* Save the current character */ X X while ((c = Getc (c1)) != c1) X { X! if (c == 0) /* End of file - abort */ X { X unget (c); X *s = (char)c1; X*************** X*** 819,827 **** X return YYERRCODE; X } X X! if (talking && (c == NL) && (e.iop <= iostack)) X { X Add_History (FALSE); X put_prompt (ps2->value); X } X X--- 842,852 ---- X return YYERRCODE; X } X X! if (Interactive () && (c == NL)) X { X+ #ifndef NO_HISTORY X Add_History (FALSE); X+ #endif X put_prompt (ps2->value); X } X X*************** X*** 873,879 **** X else X yylval.i = (ec == '>') ? IOWRITE : IOREAD; X X! if ((c != '&') || (yylval.i == IOHERE)) X unget (c); X X else X--- 898,909 ---- X else X yylval.i = (ec == '>') ? IOWRITE : IOREAD; X X! /* Check for >&, <& and <<- */ X! X! if ((c == '-') && (yylval.i == IOHERE)) X! yylval.i |= IOTHERE; X! X! else if ((c != '&') || (yylval.i == IOHERE)) X unget (c); X X else XIndex: shell/sh3.c XPrereq: 1.2 X*** ../sh15/shell/sh3.c Fri Feb 16 19:10:04 1990 X--- shell/sh3.c Tue May 1 19:48:50 1990 X*************** X*** 13,21 **** 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: sh3.c 1.2 90/02/14 04:47:06 MS_user Exp $ X * X * $Log: sh3.c $ X * Revision 1.2 90/02/14 04:47:06 MS_user X * Clean up Interrupt 23 and 0 processing, change EMS version error message X * X--- 13,67 ---- 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: sh3.c 1.15 90/04/30 19:50:11 MS_user Exp $ X * X * $Log: sh3.c $ X+ * Revision 1.15 90/04/30 19:50:11 MS_user X+ * Stop search path if second character of name is colon X+ * X+ * Revision 1.14 90/04/26 17:27:52 MS_user X+ * Fix problem with Picnix Utilities - full path name of executable required X+ * X+ * Revision 1.13 90/04/25 22:34:39 MS_user X+ * Fix case in TELIF where then and else parts are not defined X+ * Fix rsh check for execution path declared X+ * X+ * Revision 1.12 90/04/11 19:49:35 MS_user X+ * Another problem with new command line processing X+ * X+ * Revision 1.11 90/04/11 12:55:49 MS_user X+ * Change command line to look exactly like COMMAND.COM X+ * X+ * Revision 1.10 90/03/27 20:33:10 MS_user X+ * Clear extended file name on interrupt X+ * X+ * Revision 1.9 90/03/27 20:09:21 MS_user X+ * Clear_Extended_File required in SH1 for interrupt clean up X+ * X+ * Revision 1.8 90/03/26 20:57:14 MS_user X+ * Change I/O restore so that "exec >filename" works X+ * X+ * Revision 1.7 90/03/22 13:47:24 MS_user X+ * MSDOS does not handle /dev/ files after find_first correctly X+ * X+ * Revision 1.6 90/03/14 16:44:49 MS_user X+ * Add quoting of arguments with white space on command line X+ * Add IOTHERE processing to iosetup X+ * X+ * Revision 1.5 90/03/06 15:10:28 MS_user X+ * Get doeval, dodot and runtrap working correctly in run so that a sub-shell X+ * is not created and environment variables can be changed. X+ * X+ * Revision 1.4 90/03/05 13:50:04 MS_user X+ * Add XMS driver X+ * Fix bug with extended line file not being deleted X+ * Get run to support eval and dot functionality correctly X+ * Get trap processing to work X+ * Add COMMAND.COM support for .bat files X+ * X+ * Revision 1.3 90/02/22 16:38:20 MS_user X+ * Add XMS support X+ * X * Revision 1.2 90/02/14 04:47:06 MS_user X * Clean up Interrupt 23 and 0 processing, change EMS version error message X * X*************** X*** 38,43 **** X--- 84,91 ---- X #include X #include X #include X+ #include X+ #include X X #include "sh.h" X X*************** X*** 48,69 **** X static C_Op **find1case (C_Op *, char *); X static C_Op *findcase (C_Op *, char *); X static void echo (char **); X- static void setsig (int, int (*)()); X static int rexecve (char *, char **, char **, bool); X static int Execute_program (char *, char **, char **, bool); X static int S_spawnve (char *, char **, char **); X! static void get_sys_info (void); X! static void EMS_error (char *, int); X static int EMS_Close (void); X static int build_command_line (char *, char **, char **); X- static void Clear_Extended_File (void); X static int setstatus (int); X X static char *AE2big = "arg/env list too big"; X static char *EMS_emsg = "Warning: EMS Error (%x)\n"; X /* Extended Command line processing file name */ X static char *Extend_file = (char *)NULL; X- static unsigned int SW_EMsize; /* Number of extend memory blks */ X X /* X * execute tree recursively X--- 96,121 ---- X static C_Op **find1case (C_Op *, char *); X static C_Op *findcase (C_Op *, char *); X static void echo (char **); X static int rexecve (char *, char **, char **, bool); X static int Execute_program (char *, char **, char **, bool); X static int S_spawnve (char *, char **, char **); X! static bool Get_EMS_Driver (void); X! static bool Get_XMS_Driver (void); X! static bool EMS_error (char *, int); X static int EMS_Close (void); X+ static bool XMS_error (char *, int); X+ static int XMS_Close (void); X static int build_command_line (char *, char **, char **); X static int setstatus (int); X+ static bool Check_for_bat_file (char *); X+ static size_t white_space_len (char *, bool *); X+ static char *Gen_Full_Path_Name (char *); X X static char *AE2big = "arg/env list too big"; X static char *EMS_emsg = "Warning: EMS Error (%x)\n"; X+ static char *XMS_emsg = "Warning: XMS Error (%x)\n"; X /* Extended Command line processing file name */ X static char *Extend_file = (char *)NULL; X X /* X * execute tree recursively X*************** X*** 301,307 **** X X case TIF: /* IF and ELSE IF functions */ X case TELIF: X! rv = !execute (t->left, pin, pout, 0) X ? execute (t->right->left, pin, pout, 0) X : execute (t->right->right, pin, pout, 0); X break; X--- 353,360 ---- X X case TIF: /* IF and ELSE IF functions */ X case TELIF: X! if (t->right != (C_Op *)NULL) X! rv = !execute (t->left, pin, pout, 0) X ? execute (t->right->left, pin, pout, 0) X : execute (t->right->right, pin, pout, 0); X break; X*************** X*** 334,347 **** X X areanum = Local_areanum; X X- /* Check for interrupts */ X- X- if (talking && SW_intr) X- { X- closeall (); X- fail (); X- } X- X /* Check for traps */ X X if ((i = trapset) != 0) X--- 387,392 ---- X*************** X*** 350,355 **** X--- 395,408 ---- X runtrap (i); X } X X+ /* Check for interrupts */ X+ X+ if (Interactive () && SW_intr) X+ { X+ closeall (); X+ fail (); X+ } X+ X return rv; X } X X*************** X*** 387,392 **** X--- 440,446 ---- X char *cp; X IO_Actions **iopp; X int resetsig = 0; X+ void (*sig_int)(); X char **owp = wp; X bool spawn = FALSE; X Fun_Ops *fop; X*************** X*** 426,437 **** X { X spawn = TRUE; X X! if (talking) X { X #ifdef SIGQUIT X signal (SIGQUIT, SIG_IGN); X #endif X! signal (SIGINT, SIG_IGN); X resetsig = 1; X } X } X--- 480,491 ---- X { X spawn = TRUE; X X! if (Interactive ()) X { X #ifdef SIGQUIT X signal (SIGQUIT, SIG_IGN); X #endif X! sig_int = signal (SIGINT, SIG_IGN); X resetsig = 1; X } X } X*************** X*** 472,478 **** X } X X if (shcom) X! return restore_std (setstatus ((*shcom)(t))); X X /* All fids above 10 are autoclosed in the exec file because we have used X * the O_NOINHERIT flag. Note I patched open.obj to pass this flag to the X--- 526,532 ---- X } X X if (shcom) X! return restore_std (setstatus ((*shcom)(t)), TRUE); X X /* All fids above 10 are autoclosed in the exec file because we have used X * the O_NOINHERIT flag. Note I patched open.obj to pass this flag to the X*************** X*** 484,501 **** X #ifdef SIGQUIT X signal (SIGQUIT, SIG_IGN); X #endif X! signal (SIGINT, onintr); X } X X if (t->type == TPAREN) X! return restore_std (execute (t->left, NOPIPE, NOPIPE, FEXEC)); X X /* Are we just changing the I/O re-direction for the shell ? */ X X if (wp[0] == NULL) X { X if (spawn) X! restore_std (0); X X return 0; X } X--- 538,555 ---- X #ifdef SIGQUIT X signal (SIGQUIT, SIG_IGN); X #endif X! signal (SIGINT, sig_int); X } X X if (t->type == TPAREN) X! return restore_std (execute (t->left, NOPIPE, NOPIPE, FEXEC), TRUE); X X /* Are we just changing the I/O re-direction for the shell ? */ X X if (wp[0] == NULL) X { X if (spawn) X! restore_std (0, TRUE); X X return 0; X } X*************** X*** 548,556 **** X return rv; X } X X! /* Ok - execute the program */ X X! return restore_std (rexecve (wp[0], wp, makenv (), spawn)); X } X X /* X--- 602,615 ---- X return rv; X } X X! /* Check for another drive or directory in the restricted shell */ X X! if (anys (":/\\", wp[0]) && check_rsh (wp[0])) X! return restore_std (-1, TRUE); X! X! /* Ok - execute the program */ X! X! return restore_std (rexecve (wp[0], wp, makenv (), spawn), TRUE); X } X X /* X*************** X*** 564,570 **** X Execute_stack_depth = stack; X Delete_G_VL (); X Restore_Dir (); X! restore_std (setstatus (retval)); X } X X /* X--- 623,629 ---- X Execute_stack_depth = stack; X Delete_G_VL (); X Restore_Dir (); X! restore_std (setstatus (retval), TRUE); X } X X /* X*************** X*** 613,628 **** X iop->io_flag &= ~(IOREAD | IOWRITE); X } X X! /* Open the file in the appropriate mode */ X X! switch (iop->io_flag) X { X case IOREAD: /* < */ X u = S_open (FALSE, cp, O_RDONLY); X break; X X case IOHERE: /* << */ X- case IOHERE | IOXHERE: X u = herein (iop->io_name, iop->io_flag & IOXHERE); X cp = "here file"; X break; X--- 672,695 ---- X iop->io_flag &= ~(IOREAD | IOWRITE); X } X X! /* X! * When writing to /dev/???, we have to cheat because MSDOS appears to X! * have a problem with /dev/ files after find_first/find_next. X! */ X X! if (((iop->io_flag & ~(IOXHERE | IOTHERE)) == IOWRITE) && X! (strnicmp (cp, "/dev/", 5) == 0)) X! iop->io_flag |= IOCAT; X! X! /* Open the file in the appropriate mode */ X! X! switch (iop->io_flag & ~(IOXHERE | IOTHERE)) X { X case IOREAD: /* < */ X u = S_open (FALSE, cp, O_RDONLY); X break; X X case IOHERE: /* << */ X u = herein (iop->io_name, iop->io_flag & IOXHERE); X cp = "here file"; X break; X*************** X*** 748,755 **** X } X X /* X! * PATH-searching interface to execve. If getenv ("PATH") were kept X! * up-to-date, execvp might be used. X */ X X static int rexecve (c, v, envp, d_flag) X--- 815,821 ---- X } X X /* X! * PATH-searching interface to execve. X */ X X static int rexecve (c, v, envp, d_flag) X*************** X*** 759,782 **** X bool d_flag; X { X register char *sp; X! int res; X! char *em; X! bool eloop; X X /* If the environment is null - It is too big - error */ X X if (envp == (char **)NULL) X em = AE2big; X X else X { X- sp = any ('/', c) ? null : path->value; X X do X { X! sp = path_append (sp, c, e.linep); X X! if ((res = Execute_program (e.linep, v, envp, d_flag)) != -1) X return res; X X eloop = TRUE; X--- 825,869 ---- X bool d_flag; X { X register char *sp; X! int res; /* Result */ X! char *em; /* Exit error message */ X! bool eloop; /* Re-try flag */ X! char **new_argv; X! int batfile; /* .bat file flag */ X! int argc = 0; /* Original # of argcs */ X! char *params; /* Script parameters */ X! int nargc = 0; /* # script args */ X! char *p_name; /* Program name */ X! int i; X X /* If the environment is null - It is too big - error */ X X if (envp == (char **)NULL) X em = AE2big; X X+ else if ((p_name = getcell (FFNAME_MAX)) == (char *)NULL) X+ em = strerror (ENOMEM); X+ X else X { X X+ /* Count the number of arguments to the program in case of shell script or X+ * bat file X+ */ X+ X+ while (v[argc++] != (char *)NULL); X+ X+ ++argc; /* Including the null */ X+ X+ /* Start off on the search path for the executable file */ X+ X+ sp = (any ('/', c) || (*(c + 1) == ':')) ? null : path->value; X+ X do X { X! sp = path_append (sp, c, p_name); X X! if ((res = Execute_program (p_name, v, envp, d_flag)) != -1) X return res; X X eloop = TRUE; X*************** X*** 788,812 **** X * script X */ X case ENOENT: X! if ((res = O_for_execute (e.linep)) >= 0) X { X S_close (res, TRUE); X- *v = e.linep; X- em = *--v; X- *v = e.linep; X- res = Execute_program (lookup (shell, FALSE)->value, X- v, envp, d_flag); X- *v = em; X- X- if (res != -1) X- return res; X- X- em = "no Shell"; X } X X! else X em = "not found"; X X eloop = FALSE; X break; X X--- 875,963 ---- X * script X */ X case ENOENT: X! if ((res = O_for_execute (p_name, ¶ms, &nargc)) >= 0) X { X+ batfile = 1; X S_close (res, TRUE); X } X X! else if (!Check_for_bat_file (p_name)) X! { X em = "not found"; X+ eloop = FALSE; X+ break; X+ } X X+ else X+ { X+ Convert_Slashes (p_name); X+ batfile = 0; X+ nargc = 0; X+ } X+ X+ /* Ok - either a shell script or a bat file (batfile = 0) */ X+ X+ nargc = (nargc < 2) ? 0 : nargc - 1; X+ if ((new_argv = (char **)getcell (sizeof (char *) * X+ (argc + nargc + 2))) X+ == (char **)NULL) X+ { X+ em = strerror (ENOMEM); X+ break; X+ } X+ X+ memcpy (&new_argv[2 + nargc], &v[0], sizeof(char *) * argc); X+ X+ /* If BAT file, use command.com else use sh */ X+ X+ if (!batfile) X+ { X+ new_argv[0] = lookup ("COMSPEC", FALSE)->value; X+ new_argv[1] = "/c"; X+ } X+ X+ /* Stick in the pre-fix arguments */ X+ X+ else if (nargc) X+ { X+ i = 1; X+ em = params; X+ X+ while (*em) X+ { X+ while (isspace (*em)) X+ *(em++) = 0; X+ X+ if (*em) X+ new_argv[i++] = em; X+ X+ while (!isspace (*em) && *em) X+ ++em; X+ } X+ } X+ X+ else if (params != null) X+ new_argv[1] = params; X+ X+ else X+ new_argv[1] = lookup (shell, FALSE)->value; X+ X+ new_argv[2 + nargc] = p_name; X+ X+ res = rexecve (new_argv[batfile], &new_argv[batfile], X+ envp, d_flag); X+ /* Release allocated space */ X+ X+ DELETE (new_argv); X+ X+ if (params != null) X+ DELETE (params); X+ X+ if (res != -1) X+ return res; X+ /* No - shell */ X+ X+ em = "no Shell"; X eloop = FALSE; X break; X X*************** X*** 838,850 **** X return -1; X } X X /* X * Run the command produced by generator `f' applied to stream `arg'. X */ X X! int run (argp, f) X IO_Args *argp; X int (*f)(IO_State *); X { X Word_B *swdlist = wdlist; X Word_B *siolist = iolist; X--- 989,1036 ---- X return -1; X } X X+ /* Check to see if this is a bat file */ X+ X+ static bool Check_for_bat_file (name) X+ char *name; X+ { X+ char *local_path; X+ char *cp; X+ bool res; X+ X+ if ((local_path = getcell (strlen (name) + 5)) == (char *)NULL) X+ return FALSE; X+ X+ /* Work on a copy of the path */ X+ X+ if ((cp = strrchr (strcpy (local_path, name), '/')) == (char *)NULL) X+ cp = local_path; X+ X+ else X+ ++cp; X+ X+ if ((cp = strrchr (cp, '.')) == (char *)NULL) X+ strcat (local_path, ".bat"); X+ X+ else if (stricmp (cp, ".bat") != 0) X+ { SHAR_EOF echo "End of part 2" echo "File Patch1.6 is continued in part 3" echo "3" > s2_seq_.tmp exit 0