home *** CD-ROM | disk | FTP | other *** search
- PAGE 58,132
- TITLE PUSH 10-8-90 [12-12-91]
-
- ;Disassembled via good old ASMGEN.
- ;Commented, no changes (per copyright requirements).
- ;However, if you were to happen to "/dTOADTWEAK" when you
- ;assembled this sucker ...
- ;
- ;Warning: I couldn't test the original PUSH.COM (renamed to
- ;PUSH0.COM) or this disassembly because I only have DOS 3.1.
- ;The original PUSH.COM requires DOS 3.3 minimum.
- ;
- ;Since all seems to work just fine with PC-DOS 3.1
- ;(and presumably earlier versions as well),
- ;TOADTWEAK will extend legal versions down to DOS 2.0
- ;(below which we lose handles).
- ;We also patch "@echo off" to be a simple " echo off"
- ;since earlier DOS versions don't seem to like that '@' character.
- ;
- ;David Kirschbaum
- ;Toad Hall
- ;kirsch@usasoc.soc.mil
-
- LF EQU 0AH
- CR EQU 0DH
-
- CSEG SEGMENT
- ASSUME DS:CSEG, SS:CSEG ,CS:CSEG ,ES:CSEG
-
- ORG 100H
-
- _Push proc near
- MOV SP,OFFSET stacktop_84A ;stack top
- MOV DX,OFFSET msg62E ;'PUSH (c) ...'
- MOV AH,9
- INT 21H
-
- MOV AH,30H ;get DOS version
- INT 21H
- XCHG AH,AL
- CMP AX,031EH ;version 3.30?
- JNB Skp11F ;yep, or higher
-
- IFDEF TOADTWEAK
- ;Everything works fine with PC-DOS 3.1
- ;except for a problem with that "@echo off" command
- ;written to the batch file.
- ;Let's just say if <DOS3.3, we delete that "@" character, eh?
- ;And let's choke&die if <DOS2.0.
-
- mov byte ptr txt47F,' ' ;blank out that feelthy '@'
- cmp ax,0200H ;< DOS 2.0?
- jnb Skp11F ;nope, drive on
-
- ENDIF
- MOV DX,OFFSET msg6F7 ;'Requires DOS 3.3 or later'
- ;(or maybe 'DOS 2.0 or later')
- MOV CX,LEN6F7 ;25H ;msg length
- JMP MsgTerm_3BD ;display msg, terminate ERROR 1
-
- Skp11F:
- MOV AH,19H ;report current drive
- INT 21H
- ADD AL,'A' ;Asciify it
- MOV currdriv_5E0,AL ;save in string
- MOV AH,47H ;get current directory
- IFNDEF TOADTWEAK
- MOV DL,0 ;0 = current drive
- ELSE ;v1.1
- xor dl,dl ;0 = current drive v1.1
- ENDIF
- MOV SI,OFFSET currdir_5E8 ;directory string buffer
- INT 21H
- PUSH ES
- MOV ES,DS:2CH ;environment segment
- MOV CS:envseg_3DD,ES ;save it
- ASSUME ES:NOTHING ;actually environment segment
-
- ;Scan environment
- IFNDEF TOADTWEAK
- MOV DI,0FFFFH
- ELSE ;v1.1
- mov cx,0FFFFH ;handy constant v1.1
- mov di,cx ;initialize pointer v1.1
- ENDIF
- XOR AX,AX ;scan for environ string end
-
- EnvLup_140:
- INC DI
- CMP ES:[DI],AX ;hit msg end?
- JNZ EnvLup_140 ;not yet
- ADD DI,4 ;bump to next string
- MOV envptr_3DB,DI ;save env string pointer
- CMP WORD PTR ES:[DI+1],'\:' ;need drive in PATH
- JZ PathOk_15F
- MOV DX,OFFSET msg71C ;'Bad PATH - must include drive.'
- MOV CX,LEN71C ;20H ;msg length
- JMP NotPushed_3B3 ;'not pushed', terminate
-
- PathOk_15F:
- CLD ;insure fwd scan
- IFNDEF TOADTWEAK
- MOV CX,0FFFFH ;max scan
- MOV AL,0 ;dumb, AX is still 0
- ELSE ;v1.1
- ;AL is still 0.
- ;CX is still initialized to 0FFFFH for max scan.
- ENDIF
- REPNZ SCASB ;to find PATH string end
- NEG CX ;adjust
- STD ;now scan backwards
- MOV AL,'\' ;scan for directory separator
- REPNZ SCASB
- INC CX ;adjust
- MOV ofs_3DF,CX ;save offset to PATH '\'
- CLD ;insure fwd again
- POP ES
- ASSUME ES:CSEG
-
- MOV DI,OFFSET path3E1 ;path buffer
- CALL CopyPath_399 ;copy PATH from environment to buffer
- MOV SI,OFFSET batname_3C6 ;'POP.BAT',0,CR,LF,'$'
- MOV CX,LEN3C6 ;0BH ;chars to copy
- REPZ MOVSB ;add to PATH
- SUB DI,OFFSET path3E1 ;minus start
- MOV pathlen42D,DI ;save length of POP.BAT path
-
- MOV DI,OFFSET path42F ;another PATH buffer
- CALL CopyPath_399 ;copy PATH from environment to buffer
- MOV SI,OFFSET batname_3C6 ;'POP.BAT',0,CR,LF,'$'
- MOV CX,4 ;just move the 'POP.'
- REPZ MOVSB
- MOV WORD PTR [DI],'1' ;now add a "1" and 0 to the path
- MOV dot1ptr_479,DI ;save pointer to POP.1
-
- RenameLup_1A2:
- MOV AH,56H ;Rename file
- MOV DX,OFFSET path3E1 ;from POP.BAT
- MOV DI,OFFSET path42F ;to POP.1
- INT 21H
- JNB RenamedOk_1EC ;renamed ok
-
- CMP AL,2 ;file not found?
- JZ Skp204 ;yep
- CMP AL,5 ;access denied?
- JZ Skp1C3 ;yep
- MOV DX,OFFSET msg73C ;'Error renaming '
- MOV CX,LEN73C ;0FH ;msg length
- CALL PrMsg_Fname_386 ;display err msg, filename
- JMP NotPushed_3B6 ;'Env not pushed', die
-
- Skp1C3: MOV SI,dot1ptr_479 ;pointer to POP.1 end
- ;Bump a bunch of digit characters to the next higher digit
- INC BYTE PTR [SI] ;bump to next digit
- INC BYTE PTR nr_51C ;'1' of 'POP.1 goto :rename'
- INC BYTE PTR nr_54E ;another POP.1
- INC BYTE PTR nr_5AB ;'1 pop.bat'
- INC BYTE PTR nr_5C3 ;'1 POP(s) remaining.',CR,LF
- INC BYTE PTR nr_6A0 ;'Level 1'
- CMP BYTE PTR [SI],'9' ;maxed out yet?
- JBE RenameLup_1A2 ;not yet, try for one higher
-
- MOV DX,OFFSET msg74B ;'PUSHes may only be nested 10 levels deep.'
- MOV CX,LEN74B ;2BH ;msg length
- JMP NotPushed_3B3 ;'not pushed', terminate
-
- RenamedOk_1EC:
- MOV BYTE PTR bflag_47B,1 ;pass 2
- MOV SI,OFFSET nr_6A0 ;'1' of Level 1
- INC BYTE PTR [SI] ;bump to '2' or whatever
- CMP BYTE PTR [SI],'9'+1 ;go beyond '9'?
- JNZ Skp204 ;not yet
- MOV WORD PTR [SI],'01' ;actually '10'
- MOV BYTE PTR [SI+2],'.'
-
- Skp204: MOV AH,5BH ;Create new file
- MOV DX,OFFSET path3E1 ;use the new PATH\POP.xx
- IFNDEF TOADTWEAK
- MOV CX,0 ;normal attributes
- ELSE ;v1.1
- xor cx,cx ;normal attributes v1.1
- ENDIF
- INT 21H
- MOV fhandle_47C,AX ;save file handle
- JNB CreateOk_220 ;created ok
- MOV DX,OFFSET msg776 ;'Error creating '
- MOV CX,LEN776 ;0FH ;msg length
- CALL PrMsg_Fname_386 ;display err msg, filename
- JMP Recover_35D ;attempt to recover old POP.BAT
- ;Terminate in any case
-
- CreateOk_220:
- MOV DX,OFFSET txt47F ;'@echo off'
- MOV CX,LEN47F ;9 ;length
- CALL WriteFile_334 ;write to POP.x file
- CMP BYTE PTR bflag_47B,0 ;pass 1?
- JZ Pass1_268 ;yep
-
- ;Only do this on pass 2
- MOV DX,OFFSET txt488 ;'pass_2' text
- MOV CX,LEN488 ;27H ;length
- CALL WriteFile_334
- MOV AX,7 ;PATH + 7 chars (POP.BAT?)
- CALL WritePath_3A6 ;write to POP.x file
- MOV DX,OFFSET txt3DA ;' '
- MOV CX,1 ;1 char
- CALL WriteFile_334
- XOR AX,AX ;just PATH\
- CALL WritePath_3A6
- MOV DX,OFFSET txt3D1 ;'pop_2.bat'
- MOV CX,LEN3D1 ;9 ;length
- CALL WriteFile_334
- MOV DX,OFFSET txt4AF ;'>nul', more
- MOV CX,LEN4AF ;25H ;length
- CALL WriteFile_334
- MOV AX,7 ;PATH\7 chars
- CALL WritePath_3A6
-
- Pass1_268:
- PUSH ES
- MOV ES,envseg_3DD
- ASSUME ES:NOTHING ;actually environment seg
- IFDEF TOADTWEAK
- xor di,di ;base v1.1
- ELSE
- MOV DI,0 ;base
- ENDIF
-
- SetLup_270:
- MOV DX,OFFSET txt4D4 ;CR/LF,'set '
- MOV CX,LEN4D4 ;6 ;length
- CALL WriteFile_334
- PUSH DS
- PUSH ES
- POP DS
- ASSUME DS:NOTHING,ES:NOTHING ;actually environment seg
-
- MOV DX,DI ;write from here
- IFDEF TOADTWEAK
- xor al,al ;scan for string end v1.1
- ELSE
- MOV AL,0 ;scan for string end
- ENDIF
- MOV CX,0FFFFH ;max scan
- REPNZ SCASB
- NOT CX ;flip
- DEC CX ;adjust, CX = length
- PUSH DI ;save pointer
- CALL WriteFile_334 ;write to POP.x file
- POP DI ;restore pointer
- CMP BYTE PTR [DI],0 ;end of environment?
- POP DS
- ASSUME DS:CSEG
-
- JNZ SetLup_270 ;nope, repeat
-
- POP ES
- ASSUME DS:CSEG,ES:CSEG
-
- MOV DX,OFFSET txt4DA ;'echo Environment popped'
- MOV CX,LEN4DA ;32H ;length
- CMP BYTE PTR bflag_47B,0 ;pass 1?
- JNZ Skp2A4 ;nope
- DEC CX ;yep, write 1 less char
- Skp2A4: CALL WriteFile_334
- MOV DX,OFFSET txt50C
- MOV CX,LEN50C ;7 ;length
- CALL WriteFile_334
- CMP BYTE PTR bflag_47B,0 ;pass 1?
- JZ Pass1_2E2 ;yep
-
- ;Write this to POP.x file on pass 2
- MOV DX,OFFSET txt513 ;'if exist %1'
- MOV CX,LEN513 ;9 ;length
- CALL WriteFile_334
- MOV AX,4
- CALL WritePath_3A6
- MOV DX,OFFSET nr_51C ;'1 goto :rename',CR,LF
- MOV CX,LEN51C ;8FH ;text length
- CALL WriteFile_334
- MOV AX,4 ;PATH\ + 4 chars
- CALL WritePath_3A6
- MOV DX,OFFSET nr_5AB ;'1 pop.bat',CR,LF
- MOV CX,LEN5AB ;35H ;text length
- CALL WriteFile_334
-
- Pass1_2E2:
- MOV DX,OFFSET currdriv_5E0 ;x: cd \' etc etc
- MOV CX,LEN5E0 ;4EH ;length
- CALL WriteFile_334
- XOR AX,AX ;PATH\, no additional chars
- CALL WritePath_3A6
- MOV DX,OFFSET batname_3C6 ;'POP.BAT',0,CR,LF,'$'
- MOV CX,7 ;move the 'POP.BAT'
- CMP BYTE PTR bflag_47B,0 ;pass 1?
- JZ Pass1_304
- MOV DX,OFFSET txt3D1 ;'pop_2.bat'
- MOV CX,LEN3D1 ;9 ;length
- Pass1_304:
- CALL WriteFile_334
- MOV DX,OFFSET txt47E ;^Z
- MOV CX,1 ;1 char
- CALL WriteFile_334
- MOV AH,3EH ;close file handle
- MOV BX,fhandle_47C ;POP.x file handle
- INT 21H
- JB Delete_340 ;close failed, delete, cleanup, die
-
- MOV DX,OFFSET msg67D ;'current environment pushed'
- MOV AH,9 ;display msg
- INT 21H
- MOV DX,OFFSET path3E1 ;POP.BAT path
- MOV AH,9
- INT 21H
- MOV DX,OFFSET msg6B6 ;'POP <any parameter> will display '
- ;'popped environment variables.'
- MOV AH,9
- INT 21H
- MOV AX,4C00H ;terminate, ERRORLEVEL 0
- INT 21H
- _Push endp
-
-
- ;Write text at DX (length in CX) to POP.x file.
- ;Choke&die if write failure
- WriteFile_334 proc near
- MOV AH,40H ;write to file/device
- MOV BX,CS:fhandle_47C ;POP.x file handle
- INT 21H
- JB Delete_340 ;write failed
- RET ;_NEAR
- WriteFile_334 endp
-
-
- ;Something went wrong in POP create, write, whatever.
- ;Delete it, clean up, terminate.
- Delete_340 proc near
-
- IFDEF TOADTWEAK ;v1.1
- mov ax,CS
- mov DS,ax
- mov ES,ax
- ELSE
- PUSH CS
- PUSH CS
- POP DS
- POP ES
- ENDIF
- ASSUME DS:CSEG,ES:CSEG
-
- MOV DX,OFFSET msg785 ;'Error writing to '
- MOV CX,LEN785 ;11H ;length
- CALL PrMsg_Fname_386 ;display err msg, filename
- MOV AH,3EH ;Close file handle
- MOV BX,fhandle_47C ;POP.x file handle
- INT 21H
- MOV AH,41H ;Delete file
- MOV DX,OFFSET path3E1 ;POP.BAT
- INT 21H
-
- Recover_35D:
- CMP BYTE PTR bflag_47B,0 ;pass 1?
- JZ NotPushed_3B6 ;yep, 'Env not pushed', die
-
- MOV AH,56H ;Rename file
- MOV DX,OFFSET path42F ;from POP.n
- MOV DI,OFFSET path3E1 ;to POP.BAT
- INT 21H
- MOV DX,OFFSET msg796 ;'Previous POP.BAT recovered.'
- MOV CX,LEN796 ;1DH ;msg length
- JNB NotPushed_3B3 ;rename failed. 'not pushed', terminate
- MOV DX,OFFSET msg7CC ;'Can't recover previous POP.BAT',
- MOV CX,LEN7CC ;3EH ;msg length
- CALL PrMsg_391 ;display
- MOV AX,4C02H ;terminate, ERRORLEVEL 2
- INT 21H
- Delete_340 endp
-
-
- PrMsg_Fname_386 proc near
- CALL PrMsg_391 ;display msg in DX/CX
- MOV DX,OFFSET path3E1 ;'POP.BAT'
- MOV CX,pathlen42D ;msg length
- DEC CX ;adjust
- PrMsg_391:
- MOV AH,40H ;Write to file/device
- MOV BX,2 ;StdErr
- INT 21H
- RET ;_NEAR
- PrMsg_Fname_386 endp
-
-
- CopyPath_399 proc near
- PUSH DS
- MOV CX,ofs_3DF ;offset to PATH '\'
- LDS SI,DWORD PTR envptr_3DB ;pointer to PATH in environment
- REPZ MOVSB ;move into ES:DI buffer
- POP DS
- RET ;_NEAR
- CopyPath_399 endp
-
-
- ;Write PATH plus AX characters to PATH.x file
- WritePath_3A6 proc near
- MOV DX,OFFSET path3E1
- MOV CX,ofs_3DF ;offset to PATH '\'
- ADD CX,AX ;plus length of added string
- CALL WriteFile_334
- RET ;_NEAR
- WritePath_3A6 endp
-
-
- ;Fatal error. Display error msg, more, terminate.
- NotPushed_3B3 proc near
- CALL PrMsg_391 ;display msg in DX/CX
- NotPushed_3B6:
- MOV DX,OFFSET msg7B3 ;'Environment not PUSHed.'
- MOV CX,LEN7B3 ;19H ;msg length
-
- MsgTerm_3BD:
- CALL PrMsg_391 ;display msg in DX/CX
- MOV AX,4C01H ;Terminate, ERRORLEVEL 1
- INT 21H
- NotPushed_3B3 endp
-
-
- ; DB 0
- batname_3C6 DB 'POP.BAT',0,CR,LF,'$'
- LEN3C6 EQU $-batname_3C6
- txt3D1 DB 'pop_2.bat'
- LEN3D1 EQU $-txt3D1
- txt3DA DB ' '
- envptr_3DB dw 0 ;saved environment string ptr
- envseg_3DD dw 0 ;saved environment segment
- ofs_3DF dw 0 ;offset in PATH str to '\'
-
- IFNDEF TOADTWEAK
- path3E1 DB 4CH DUP(0) ;PATH\POP.BAT buffer
- ELSE ;v1.1
- ;v1.1 Moved to dynamic buffers outside program space.
- ENDIF
-
- pathlen42D dw 0 ;length of POP.BAT path
-
- IFNDEF TOADTWEAK
- path42F DB 4AH DUP(0) ;PATH\POP.1 buffer
- ELSE ;v1.1
- ;v1.1 Moved to dynamic buffers outside program space.
- ENDIF
-
- dot1ptr_479 dw 0 ;pointer to POP.1 string
- bflag_47B DB 0 ;flag pass 1 (0) or pass 2 (1)
- fhandle_47C dw 0 ;file handle
- txt47E DB 1AH
-
- txt47F DB '@echo off'
- LEN47F EQU $-txt47F
- txt488 DB CR,LF
- DB "if '%2'=='pass_2' goto :pass_2",CR,LF
- DB 'copy '
- LEN488 EQU $-txt488
- txt4AF DB ' >nul',CR,LF
- DB '%0_2 _%1 pass_2',CR,LF
- DB ':pass_2',CR,LF
- DB 'del '
- LEN4AF EQU $-txt4AF
- txt4D4 DB CR,LF
- DB 'set '
- LEN4D4 EQU $-txt4D4
- txt4DA DB CR,LF
- DB 'echo Environment popped.',CR,LF
- DB 'echo.',CR,LF
- DB "if not '%1'=='_"
- LEN4DA EQU $-txt4DA
- txt50C DB "' set",CR,LF
- LEN50C EQU $-txt50C
- txt513 DB 'if exist '
- LEN513 EQU $-txt513
- nr_51C DB '1 goto :rename',CR,LF
- DB 'echo WARNING: Could not find POP.'
- nr_54E DB '1',CR,LF
- DB 'echo Previous environment(s) lost!',7,CR,LF
- DB 'set pop_error=1',CR,LF
- DB 'goto :drive',CR,LF
- DB ':rename',CR,LF
- DB 'ren '
- LEN51C EQU $-nr_51C
-
- nr_5AB DB '1 pop.bat',CR,LF
- DB 'echo ',0FFH
- DB CR,LF
- DB 'echo '
- LEN5AB EQU $-nr_5AB
-
- nr_5C3 DB '1 POP(s) remaining.',CR,LF
- DB ':drive',CR,LF
- currdriv_5E0 DB ' :',CR,LF
- DB 'cd \'
- currdir_5E8 DB 40H DUP(0) ;current directory
- DB CR,LF
- DB 'del '
- LEN5E0 EQU $-currdriv_5E0
-
- IFNDEF TOADTWEAK
- msg62E DB 'PUSH (c) Mitch Ames 1990. May be copied freely, '
- DB 'but not modified or sold.',CR,LF,LF,'$'
- ELSE ;v1.1
- msg62E db 'PUSH v1.1 (c) Mitch Ames 1990.',CR,LF,'$'
- db 'May be copied freely, but not modified or sold.',0
- db 'Toad Hall Tweak',0
- ENDIF
-
- msg67D DB 'Current environment pushed: Level '
- nr_6A0 DB '1. ',CR,LF
- DB 'To restore, run $'
- msg6B6 DB 'POP <any parameter> will display popped environment '
- db 'variables.',CR,LF,'$'
-
- IFNDEF TOADTWEAK
- msg6F7 DB 'Requires DOS version 3.30 or later.',CR,LF
- ELSE ;v1.1
- msg6F7 db 'Requires DOS 2.0 or later.',CR,LF ;v1.1
- ENDIF
- LEN6F7 EQU $-msg6F7
-
- msg71C DB 'Bad PATH - must include drive.',CR,LF
- LEN71C EQU $-msg71C
- msg73C DB 'Error renaming '
- LEN73C EQU $-msg73C
- msg74B DB 'PUSHes may only be nested 10 levels deep.',CR,LF
- LEN74B EQU $-msg74B
- msg776 DB 'Error creating '
- LEN776 EQU $-msg776
- msg785 DB 'Error writing to '
- LEN785 EQU $-msg785
- msg796 DB 'Previous POP.BAT recovered.',CR,LF
- LEN796 EQU $-msg796
- msg7B3 DB 'Environment not PUSHed.',CR,LF
- LEN7B3 EQU $-msg7B3
- msg7CC DB "Can't recover previous POP.BAT",CR,LF
- DB 'Previous environments lost!',7,CR,LF
- LEN7CC EQU $-msg7CC
- IFNDEF TOADTWEAK
- DB 'stack stack stack stack '
- db 'stack stack stack stack '
- stacktop_84A EQU $-0H
- ELSE ;v1.1
-
- ;Use dynamic variables outside program space.
- ;This reduces compiled program's size.
-
- PROGEND EQU $
- stacktop_84A EQU PROGEND+(8*8)
- path3E1 EQU stacktop_84A+2 ;DB 4CH DUP(0) ;PATH\POP.BAT buffer
- path42F EQU path3E1+4CH ;DB 4AH DUP(0) ;PATH\POP.1 buffer
- ENDIF
-
- CSEG ENDS
- END _Push