2 ; SCCSID = @(#)tmisc1.asm 4.1 85/09/22
3 ; SCCSID = @(#)tmisc1.asm 4.1 85/09/22
4 TITLE Part7 COMMAND Transient Routines
19 CODERES
SEGMENT PUBLIC BYTE ;AC000;
23 DATARES
SEGMENT PUBLIC BYTE ;AC000;
36 TRANDATA
SEGMENT PUBLIC BYTE ;AC000;
39 EXTRN COMTAB
:BYTE ;AC000;
40 EXTRN extend_buf_ptr
:word ;AN000;
41 EXTRN msg_disp_class
:byte ;AN000;
44 TRANSPACE
SEGMENT PUBLIC BYTE ;AC000;
45 EXTRN arg
:byte ; the arg structure!
46 EXTRN APPEND_EXEC
:BYTE ;AN041;
53 EXTRN KPARSE
:BYTE ;AC000;
61 EXTRN switch_list
:byte
72 TRANCODE
SEGMENT PUBLIC byte
74 ASSUME
CS:TRANGROUP
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
76 EXTRN APPEND_PARSE
:NEAR ;AN010;
97 ;---------------------------
98 ; We can get rid of this switch processing code if we can take
99 ; care of the remaining two calls to switch, later in the file.
100 ; However, I have not checked whether or not any other files use
101 ; switch -- after all, it IS public!
102 ;---------------------------
104 XCHG AX,BX ; Put switches in AX
108 XOR BX,BX ; Initialize - no switches set
110 INVOKE SCANOFF
; Skip any delimiters
111 CMP AL,[SWITCHAR
] ; Is it a switch specifier?
112 JNZ RETSW
; No -- we're finished
113 OR BX,fSwitch
; Indicate there is a switch specified
114 INC SI ; Skip over the switch character
119 ; Convert lower case input to upper case
121 MOV DI,OFFSET TRANGROUP
:switch_list
123 REPNE SCASB ; Look for matching switch
126 SHL AX,CL ; Set a bit for the switch
133 SWCOUNT EQU
5 ; Length of switch_list
136 MOV DX,OFFSET TRANGROUP
:BADDRV_ptr
142 fndcom: ; search the internal command table
143 OR AL,AL ; Get real length of first arg
144 jz externalj
; If 0, it must begin with "\" so has
146 ; barryf code starts here
149 call test_append
; see if APPEND installed
150 je contcom
; not loaded
153 mov cl,TRANGROUP
:IDLEN
156 inc append_exec
;AN041; set APPEND to ON
158 invoke ioset
; re-direct the o'l io
160 mov SI, offset TRANGROUP
:IDLEN
; address command name, DS already set
161 mov DX,-1 ; set invoke function
162 mov di,offset TRANGROUP
:APPEND_PARSE
;AN010; Get the entry point for PARSE for APPEND
164 int 2FH
; execute command
165 cmp TRANGROUP
:IDLEN
,0 ; execute requested
169 contcom: ; continue with internal scan
172 ; barryf code ends here
174 mov DI, OFFSET TRANGROUP
:COMTAB
178 mov SI, offset TRANGROUP
:IDLEN
+1 ; pointer to command argument
179 mov CL, [DI] ; load length of internal command
180 inc di ; advance past length
181 jcxz externalj
; if it's zero, we're out of internals
182 cmp CL, IDLEN
; that of the command argument
183 jnz abcd
; lengths not equal ==> strings not eq
184 MOV PathPos
,CX ; store length of command
188 lahf ; save the good ol' flags
189 add DI, CX ; skip over remaining internal, if any
190 mov AL, BYTE PTR [DI] ; load drive-check indicator byte (DCIB)
191 mov [CHKDRV
], AL ; save command flag byte in chkdrv
192 inc DI ; increment DI (OK, OK, I'll stop)
193 mov BX, WORD PTR [DI] ; load internal command address
194 inc DI ; skip over the puppy
196 sahf ; remember those flags?
197 jnz findcom
; well, if all the cmps worked...
199 ; All messages get redirected.
201 cmp append_exec
,0 ;AN041; APPEND just executed?
202 jnz dont_set_io
;AN041; Yes - this junk is already set
203 invoke ioset
; re-direct the ol' i/o
206 invoke SETSTDINON
;AN026; turn on critical error on STDIN
207 invoke SETSTDOUTOFF
;AN026; turn off critical error on STDOUT
208 test [CHKDRV
], fCheckDrive
; did we wanna check those drives?
210 mov AL, [PARM1
] ; parse_file_descriptor results tell
211 or AL, [PARM2
] ; us whether those drives were OK
218 ; The user may have omitted the space between the command and its arguments.
219 ; We need to copy the remainder of the user's command line into the buffer.
220 ; Note that thisdoes not screw up the arg structure; it points into COMBUF not
221 ; into the command line at 80.
227 test [CHKDRV
], fSwitchAllowed
; Does the command take switches
228 jnz realwork
; Yes, process the command
229 call noswit
; No, check to see if any switches
230 jnz realwork
; None, process the command
231 mov msg_disp_class
,parse_msg_class
;AN000; set up parse error msg class
232 MOV DX,OFFSET TranGroup
:Extend_Buf_ptr
;AC000; get extended message pointer
233 mov Extend_Buf_ptr
,BadSwt_ptr
;AN000; get "Invalid switch" message number
234 jmp CERROR
; Print error and chill out...
236 call BX ; do some real work, at last
238 ; See if we're in a batch CALL command. If we are, reprocess the command line,
239 ; otherwise, go get another command.
242 push cs ; g restore data segment
244 push ds ; g save data segment
245 mov ds,[resseg
] ; g get segment containing call flag
247 cmp call_flag
, call_in_progress
; G Is a call in progress?
248 mov call_flag
, 0 ; G Either way, reset flag
249 pop ds ; g get data segment back
251 jmp tcommand
; chill out...
258 mov di,81h
; di = ptr to command args
259 mov si,80h
; Get address of length of command args
261 mov cl,al ; Move length to cl
263 mov al,[SWITCHAR
] ; al = switch character
264 cmp al,0 ; Turn off ZF
265 repnz scasb ; Scan for a switch character and return
266 pop di ; with ZF set if one was found
272 call test_append
; check to see if append installed
273 je not_barryf
; no - truly external command
274 jmp append_internal
; yes - go to Barryf code
286 MOV DX,OFFSET TRANGROUP
:IDLEN
297 MOV DI,OFFSET TRANGROUP
:EXECPATH
298 MOV BYTE PTR [DI],0 ; Initialize to current directory
305 invoke path_search
; find the mother (result in execpath)
306 or AX, AX ; did we find anything?
307 je badcomj45
; null means no (sob)
308 cmp AX, 04H ; 04H and 08H are .exe and .com
309 jl rsrch_br1
; fuckin' sixteen-bit machine ought
310 jmp execute
; to be able to handle a SIXTEEN-BIT
311 rsrch_br1: ; DISPLACEMENT!!
312 jmp batcom
; 02H is .bat
316 ASSUME
DS:TRANGROUP
,ES:TRANGROUP
321 invoke SETSTDINOFF
;AN026; turn off critical error on STDIN
322 invoke SETSTDOUTOFF
;AN026; turn off critical error on STDOUT
325 INT int_command
; Now running in "free" space
328 INC [EXTCOM
] ; Indicate external command
329 MOV [RESTDIR
],0 ; Since USERDIR1 is in transient, insure
330 ; this flag value for re-entry to COMMAND
333 MOV CX,052H ; moving (100h-5Ch)/2 = 80h-2Eh
334 REP MOVSW ; Transfer parameters to resident header
335 MOV DX,OFFSET TRANGROUP
:EXECPATH
336 MOV BX,OFFSET RESGROUP
:EXEC_BLOCK
345 ; we are now running in free space. anything we do from here on may get
346 ; trashed. Move the stack (also in free space) to allocated space because
347 ; since EXEC restores the stack, somebody may trash what is on the stack.
351 MOV SP,OFFSET RESGROUP
:RSTACK
352 JMP [EXEC_ADDR
] ; Jmp to the EXEC in the resident
357 MOV DX,OFFSET TRANGROUP
:BADNAM_ptr
364 ; Prescan converts the input buffer into a canonicalized form. All
365 ; redirections and pipes are removed.
367 PRESCAN: ; Cook the input buffer
369 ASSUME
DS:TRANGROUP
,ES:TRANGROUP
374 MOV SI,OFFSET TRANGROUP
:COMBUF
+2
379 CMP AL,22h
; is it a quote?
380 JNZ CountEnd
; no, try for end of road
382 JMP CountQuotes
; go get next char
385 CMP AL,13 ; end of road?
386 JNZ CountQuotes
; no, go back for next char
390 MOV SI,DI ; get back beginning of buffer
394 INVOKE TestKanj
; is it a leadin byte
395 JZ KanjiQuote
; no, check for quotes
396 MOV AH,AL ; save leadin
397 LODSB ; get trailing byte
398 CMP AX,8140h
; is it Kanji space
399 JNZ KanjiScan
; no, go get next
400 MOV [SI-2],2020h
; replace with spaces
401 JMP KanjiScan
; go get next char
404 CMP AL,22h
; beginning of quoted string
405 JNZ KanjiEnd
; no, check for end
407 JZ KanjiScan
; if count is zero, no quoting
410 LODSB ; get next byte
411 CMP AL,22h
; is it another quote
412 JNZ KanjiQuoteLoop
; no, get another
413 DEC CH ; yes, drop count
414 JMP KanjiScan
; go get next char
417 CMP AL,13 ; end of line character?
418 JNZ KanjiScan
; go back to beginning
419 POP CX ; get back original count
422 MOV SI,DI ; restore pointer to begining
431 INC DI ; fake STOSB into DS
432 LODSB ; grab second byte
433 MOV [DI],AL ; fake stosb into DS
442 CMP AL,'"' ; " character
452 CMP AL,'"' ; " character
460 ; We have found a ">" char. We need to see if there is another ">"
466 INC [RE_OUT_APP
] ; Flag >>
470 ; Now we attempt to find the file name. First, scan off all whitespace
473 CMP AL,labracket
;AN040; was there no filename?
474 JZ REOUT_ERRSET
;AN040; yes - set up error
478 ; There was no file present. Set us up at end-of-line.
480 REOUT_ERRSET: ;AN040; set up for an error
481 mov byte ptr [di], 0dh ; Clobber first ">"
482 MOV WORD PTR [RE_OUTSTR
],09H ; Cause an error later
487 MOV DI,OFFSET RESGROUP
:RE_OUTSTR
491 SETREOUTSTR: ; Get the output redirection name
499 CMP AL,'"' ;AN033; Is the character a quote?
500 JZ PIPEERRSYNJ5
;AN033; Yes - get out quick - or system crashes
501 CMP AL,labracket
;AN002; Is char for input redirection
502 JZ ABRACKET_TERM
;AN002; yes - end of string
503 CMP AL,rabracket
;AN002; Is char for output redirection
504 JNZ NO_ABRACKET
;AN002; no - not end of string
506 abracket_term: ;AN002; have end of string by < or >
507 DEC SI ;AN002; back up over symbol
508 MOV AL,BLANK
;AN002; show delimiter as char
509 JMP SHORT GOTRESTR
;AN002; go process it
511 no_abracket: ;AN002; not at end of string
512 STOSB ; store it into resgroup
513 JMP SHORT SETREOUTSTR
518 mov bx,si ; Save loc of "<"
520 CMP AL,rabracket
;AN040; was there no filename?
521 JZ REIN_ERRSET
;AN040; yes - set up error
525 REIN_ERRSET: ;AN040; set up for error
526 mov byte ptr [di],0dh ; Clobber "<"
527 MOV WORD PTR [RE_INSTR
],09H ; Cause an error later
532 MOV DI,OFFSET TranGROUP
:RE_INSTR
536 POP ES ; store in TRANGROUP
537 JMP SHORT SETREOUTSTR
; Get the input redirection name
548 ; Only push the echo flag if we are entering the pipe for the first time.
552 SHL EchoFlag
,1 ; push echo state and turn it off
560 CMP AL,vbar
; Double '|'?
565 POP DS ; DS->RESGROUP
569 ; Trailing :s are allowed on devices. Check to be sure that there is more
570 ; than just a : in the redir string.
575 SUB BX,DI ; compute negatinve of number of chars
576 CMP BX,-1 ; is there just a :?
577 JZ NotTrailCol
; yep, don't change
578 CMP BYTE PTR ES:[DI-1],al ; Trailing ':' OK on devices
580 DEC DI ; Back up over trailing ':'
584 STOSB ; NUL terminate the string
586 POP DI ; Remember the start
589 MOV [DI],AH ; "delete" the redirection string
599 MOV DI,OFFSET RESGROUP
:PIPESTR
601 MOV SI,OFFSET TRANGROUP
:COMBUF
+2
604 PIPESETLP: ; Transfer the pipe into the resident
619 MOV SI,OFFSET TRANGROUP
:COMBUF
+2
620 INVOKE Scanoff
; advance past separators...
634 mov byte ptr ds:[80h
],cl ; Store count
640 test_append proc
near
642 mov BX,offset TRANGROUP
:COMBUF
; barry can address
643 mov SI, offset TRANGROUP
:IDLEN
; address command name, DS already set
644 mov DX,-1 ; set install check function
646 int 2FH
; see if loaded