2 ; SCCSID = @(#)tcmd2b.asm 4.1 85/09/22
3 ; SCCSID = @(#)tcmd2b.asm 4.1 85/09/22
4 TITLE PART5 COMMAND Transient routines
.
16 CODERES
SEGMENT PUBLIC BYTE ;AC000;
20 DATARES
SEGMENT PUBLIC BYTE ;AC000;
21 EXTRN crit_msg_off
:word ;AC000;
22 EXTRN crit_msg_seg
:word ;AC000;
26 ;AD060; EXTRN pars_msg_off:word ;AC000;
27 ;AD060; EXTRN pars_msg_seg:word ;AC000;
28 EXTRN PERMCOM
:BYTE ;AN045;
32 TRANDATA
SEGMENT PUBLIC BYTE ;AC000;
33 EXTRN ACRLF_PTR
:WORD ;AN007;
35 EXTRN CP_active_Ptr
:word
36 EXTRN CP_not_all_Ptr
:word
37 EXTRN CP_not_set_Ptr
:word
38 EXTRN Extend_buf_ptr
:word ;AN000;
39 EXTRN Extend_buf_sub
:byte ;AN000;
40 EXTRN inv_code_page
:word ;AC000;
41 EXTRN msg_disp_class
:byte ;AN000;
42 EXTRN NLSFUNC_Ptr
:word ;AC000;
43 EXTRN parse_chcp
:byte ;AC000;
44 EXTRN parse_chdir
:byte ;AC000;
45 EXTRN parse_ctty
:byte ;AC000;
46 EXTRN string_buf_ptr
:word ;AC000;
50 TRANSPACE
SEGMENT PUBLIC BYTE ;AC000;
52 EXTRN parse_last
:word ;AN018;
53 EXTRN parse1_addr
:dword ;AC000;
54 EXTRN parse1_type
:byte ;AC000;
57 EXTRN srcxname
:byte ;AC000;
58 EXTRN string_ptr_2
:word
59 EXTRN system_cpage
:word
63 TRANCODE
SEGMENT PUBLIC BYTE
65 ASSUME
CS:TRANGROUP
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
69 TRANSPACE
SEGMENT PUBLIC BYTE ;AC000;
70 EXTRN arg
:byte ; the arg structure!
79 PUBLIC parse_check_eol
;AN000;
80 PUBLIC parse_with_msg
;AN018;
81 PUBLIC setup_parse_error_msg
;AN018;
82 PUBLIC truename
;AN000;
85 assume
ds:trangroup
,es:trangroup
87 ; ****************************************************************
89 ; * ROUTINE: CTTY - Change console
91 ; * SYNTAX: CTTY device
93 ; * FUNCTION: If a valid console device is specified, CTTY will
94 ; * duplicate the device handle to STDIN, STDOUT and
95 ; * STDERR. This routine returns to LODCOM1.
97 ; * INPUT: command line at offset 81H
101 ; ****************************************************************
104 push ds ;AN000; Get local ES
106 mov si,81H
;AC000; Get command argument for CTTY
108 mov di,offset trangroup
:parse_ctty
;AC000; Get adderss of PARSE_CTTY
109 xor cx,cx ;AC000; clear cx,dx
111 invoke cmd_parse
;AC000; call parser
112 cmp ax,end_of_line
;AN000; are we at end of line?
113 jz ctty_error
;AN000; yes - error
114 cmp ax,result_no_error
;AN000; did an error occur
115 jnz ctty_error
;AN000; YES -ERROR
117 push si ;AN000; save position in line
118 lds si,parse1_addr
;AN000; get address of filespec
119 mov di,offset trangroup
:srcbuf
;AN000; get address of srcbuf
121 ctty_move_filename: ;AN000; put filespec in srcbuf
122 lodsb ;AN000; get a char from buffer
123 stosb ;AN000; store in srcbuf
124 cmp al,end_of_line_out
;AN000; it char a terminator?
125 jnz ctty_move_filename
;AN000; no - keep moving
126 pop si ;AN000; get line position back
127 mov di,offset trangroup
:parse_ctty
;AC000; Get adderss of PARSE_CTTY
128 call parse_check_eol
;AN000; are we at end of line?
129 jz nocolon
;AN000; yes - continue
132 jmp isbaddev
;AC000; yes - exit
135 mov dx,offset trangroup
:srcbuf
;AN000; get address of srcbuf
136 MOV AX,(OPEN
SHL 8) OR 2 ; Read and write
137 INT int_command
; Open new device
146 MOV AH,CLOSE
; Close initial handle
150 MOV DX,OFFSET TRANGROUP
:BADDEV_ptr
155 push dx ;AN007; save device info
156 mov ax,acrlf_ptr
;AN021; get message number for 0d, 0a
157 mov dh,util_msg_class
;AN021; this is a utility message
158 push bx ;AN021; save handle
159 invoke Tsysgetmsg
;AN021; get the address of the message
160 mov dx,si ;AN021; get address into dx
161 mov ax,(write
shl 8) ;AN007; write to device
162 mov cx,2 ;AN007; write two bytes
163 int int_command
;AN007;
164 pop bx ;AN021; get back handle
165 pop dx ;AN007; get back device info
166 jc closedev
;AN007; if error, quit
168 OR DL,3 ; Make sure has CON attributes
169 MOV AX,(IOCTL
SHL 8) OR 1
171 PUSH BX ; Save handle
175 ICLLOOP: ; Close basic handles
182 INT int_command
; Dup it to 0
184 INT int_command
; Dup to 1
186 INT int_command
; Dup to 2
187 MOV AH,CLOSE
; Close initial handle
194 MOV AX,WORD PTR DS:[PDB_JFN_Table
] ; Get new 0 and 1
196 MOV AX,OFFSET RESGROUP
:LODCOM1
200 RET ; Force header to be checked
205 ;****************************************************************
207 ;* ROUTINE: CHCP - Change code page internal command
208 ;* (added DOS 3.30 07/21/86)
210 ;* SYNTAX: CHCP [xxx]
211 ;* where xxx is a valid code page
213 ;* FUNCTION: If xxx is specified, CHCP will use INT 21H function
214 ;* 6402H to set the code page to xxxx. If no parameters
215 ;* are specified, CHCP will use INT 21H function 6401H
216 ;* to get global code page and display it to the user.
218 ;* INPUT: command line at offset 81H
222 ;****************************************************************
224 NLSFUNC_installed equ
0ffh
228 assume
ds:trangroup
,es:trangroup
231 push ds ;AN000; Get local ES
233 mov si,81H
;AC000; Get command argument for CHCP
235 mov di,offset trangroup
:parse_chcp
;AN000; Get adderss of PARSE_CHCP
236 xor cx,cx ;AC000; clear cx,dx
238 call parse_with_msg
;AC018; call parser
239 cmp ax,end_of_line
;AN000; are we at end of line?
241 jnz setcp
;AC000; no go get number & set code page
242 jmp getcp
;AC000; yes - no parm - get code page
245 cmp ax,result_no_error
;AN000; did we have an error?
246 jne cp_error
;AC018; yes - go issue message
248 push cx ;AN000; save positional count
249 mov bx,offset trangroup
:parse1_addr
;AN000; get number returned
250 mov cx,word ptr [bx] ;AN000; into cx
251 mov system_cpage
,cx ;AN000; save user input number
252 pop cx ;AC000; restore positional count
253 mov di,offset trangroup
:parse_chcp
;AN000; Get adderss of PARSE_CHCP
254 call parse_check_eol
;AN000; are we at end of line?
255 jnz cp_error
;AC000; no - exit
258 mov ah,NLSFUNC
;AN000; see if NLSFUNC installed
261 cmp al,NLSFUNC_installed
;AN000;
262 jz got_NLS
;AN000; Yes - continue
263 mov dx,offset trangroup
:NLSFUNC_ptr
;AN000; no - set up error message
264 jmp short cp_error
;AN000; error exit
267 mov bx,system_cpage
;AN000; get user input code page
268 mov ah,getsetcdpg
;get/set global code page function
269 mov al,set_global_cp
;minor - set
271 jnc chcp_return
;no error - exit
275 cmp ax,error_file_not_found
;p716 was the error file not found?
276 jnz chcp_other_error
;no - country.sys was found
278 mov ah,GetExtendedError
;p850 see if error is invalid data
279 xor bx,bx ; which is file was found but CP
280 int int_command
; information was not found.
281 cmp ax,error_invalid_data
;AC000; invalid code page
282 jnz no_countrysys
;no - use file not found
283 mov dx,offset trangroup
:inv_code_page
;AN000; get message
284 jmp short cp_error
;AC000; error exit
287 mov msg_disp_class
,ext_msg_class
;AN000; set up extended error msg class
288 mov dx,offset TranGroup
:Extend_Buf_ptr
;AC000; get extended message pointer
289 mov Extend_Buf_ptr
,error_file_not_found
;AN000; get message number in control block
290 jmp short cp_error
;AC000; error exit
296 mov ah,GetExtendedError
;error - see what it is
299 cmp ax,65 ;was it access denied?
300 jnz none_set
;no - assume all failed
301 mov dx,offset trangroup
:cp_not_all_ptr
;set up message
302 jmp short cp_error
;AC000; error exit
305 mov dx,offset trangroup
:cp_not_set_ptr
;set up message
310 mov ah,getsetcdpg
;get/set global code page function
311 mov al,get_global_cp
;minor - get
313 mov system_cpage
,bx ;get active cp for output
314 mov dx,offset trangroup
:cp_active_ptr
315 invoke std_printf
;print it out
321 break TRUENAME
;AN000;
324 ; ****************************************************************
326 ; * ROUTINE: TRUENAME
328 ; * FUNCTION: Entry point for the internal TRUENAME command.
329 ; * Parses the command line. If a path is found, set
330 ; * SRCXNAME to path. If only a drive letter is
331 ; * found, set SRCXNAME to the drive letter. If
332 ; * no path is found, set the path of SRCXNAME to
333 ; * dot (.) for current directory. Use the NAME
334 ; * TRANSLATE system call to get the real name and
335 ; * then display the real name. If an error occurs
336 ; * issue an error message and transfer control to
339 ; * INPUT: command line at offset 81H
343 ; ****************************************************************
345 assume
ds:trangroup
,es:trangroup
;AN000;
347 TRUENAME: ;AN000; TRUENAME entry point
348 push ds ;AN000; Get local ES
350 mov si,81H
;AN000; Get command line
351 mov di,offset trangroup
:parse_chdir
;AN000; Get adderss of PARSE_CHDIR
352 xor cx,cx ;AN000; clear cx,dx
354 call parse_with_msg
;AC018; call parser
356 mov di,offset trangroup
:srcxname
;AN000; get address of srcxname
357 cmp ax,end_of_line
;AN000; are we at end of line?
358 je tn_eol
;AN000; yes - go process
359 cmp ax,result_no_error
;AN000; did we have an error?
360 jne tn_parse_error
;AN000; yes - go issue message
361 cmp parse1_type
,result_drive
;AN000; was a drive entered?
362 je tn_drive
;AN000; yes - go process
363 jmp short tn_filespec
;AN000; nothing else - must be filespec
365 tn_eol: ;AN000; no parameters on line
366 mov ah,end_of_line_out
;AN000; set buffer to .
367 mov al,dot_chr
;AN000; for current dir
368 stosw ;AN000; store in srcxname
369 jmp short tn_doit
;AN000; go do command
371 tn_drive: ;AN000; a drive was entered
372 push si ;AN000; save position in line
373 mov si,offset trangroup
:parse1_addr
;AN000; get address of drive
374 lodsb ;AN000; get the drive number
375 add al,"A"-1 ;AN000; convert it to char
376 stosb ;AN000; store it in srcxname
377 mov ax,dot_colon
;AN000; get colon and . and
378 stosw ;AN000; store in srcxname
379 mov al,end_of_line_out
;AN000; put a terminator char
381 pop si ;AN000; get line position back
382 jmp short tn_check_eol
;AN000; check to make sure eol
384 tn_filespec: ;AN000; a filespec was entered
385 push si ;AN000; save position in line
386 lds si,parse1_addr
;AN000; get address of filespec
388 tn_move_filename: ;AN000; put filespec in srcxname
389 lodsb ;AN000; get a char from buffer
390 stosb ;AN000; store in srcxname
391 cmp al,end_of_line_out
;AN000; it char a terminator?
392 jnz tn_move_filename
;AN000; no - keep moving
393 pop si ;AN000; get line position back
395 tn_check_eol: ;AN000; make sure no extra parms
396 mov di,offset trangroup
:parse_chdir
;AN000; get address of parse_chdir
397 call parse_check_eol
;AN000; are we at end of line?
398 je tn_doit
;AN000; Yes - do the command
400 tn_parse_error: ;AN000; A parse error occurred
401 jmp cerror
;AN000; Go to error routine
404 mov si,offset trangroup
:srcxname
;AN000; set up srcxname as source
405 mov di,offset trangroup
:combuf
;AN000; set up combuf as target (need big target)
406 mov ah,xnametrans
;AN000; do name translate call
407 int int_command
;AN000;
408 jnc tn_print_xname
;AN000; If no error - print result
410 invoke Set_ext_error_msg
;AN000; get extended message
411 mov string_ptr_2
,offset trangroup
:srcxname
;AN000; get address of failed string
412 mov Extend_buf_sub
,one_subst
;AN000; put number of subst in control block
413 jmp cerror
;AN000; Go to error routine
415 tn_print_xname: ;AN000;
416 mov string_ptr_2
,offset Trangroup
:combuf
;AN000; Set up address of combuf
417 mov dx,offset trangroup
:string_buf_ptr
;AN000; Set up address of print control block
418 invoke crlf2
;AN000; print a crlf
419 invoke printf_crlf
;AN000; print it out
425 assume
ds:trangroup
,es:trangroup
428 push ds ;AN000; save data segment
429 mov ds,[resseg
] ;AN000; get resident data segment
431 assume
ds:resgroup
;AN000;
433 cmp [permcom
],0 ;AN045; is this a permanent COMMAND?
434 jnz no_reset
;AN045; Yes - don't do anything
435 ;AD060; mov ah,multdos ;AN000; reset parse message pointers
436 ;AD060; mov al,message_2f ;AN000; call for message retriever
437 ;AD060; mov dl,set_parse_msg ;AN000; set up parse message address
438 ;AD060; mov di,pars_msg_off ;AN000; old offset of parse messages
439 ;AD060; mov es,pars_msg_seg ;AN000; old segment of parse messages
440 ;AD060; int 2fh ;AN000; go set it
442 ;AD060; mov ah,multdos ;AN000; set up to call DOS through int 2fh
443 ;AD060; mov al,message_2f ;AN000; call for message retriever
444 mov ax,(multdos
shl 8 or message_2f
);AN060; reset parse message pointers
445 mov dl,set_critical_msg
;AN000; set up critical error message address
446 mov di,crit_msg_off
;AN000; old offset of critical messages
447 mov es,crit_msg_seg
;AN000; old segment of critical messages
448 int 2fh
;AN000; go set it
450 pop ds ;AN000; restore local data segment
452 assume
ds:trangroup
;AN000;
459 MOV WORD PTR ES:[PDB_Parent_PID
],AX
460 MOV AX,WORD PTR OldTerm
461 MOV WORD PTR ES:[PDB_Exit
],AX
462 MOV AX,WORD PTR OldTerm
+2
463 MOV WORD PTR ES:[PDB_Exit
+2],AX
468 INT int_command
; Now running in "free" space
472 MOV AL,BYTE PTR RetCode
476 ; ****************************************************************
478 ; * ROUTINE: PARSE_CHECK_EOL
480 ; * FUNCTION: Calls parser to see if end of line occurred.
481 ; * If not end of line, set up to print parse
482 ; * error message. ASSUMES NO MORE PARAMETERS ARE
485 ; * INPUT: DS:SI last output from parser
486 ; * ES:DI points to parse block
487 ; * CX last output from parser
489 ; * OUTPUT: AX parser return code
491 ; * if end of line found
494 ; * MSG_DISPLAY_CLASS set to parse error
496 ; ****************************************************************
498 ASSUME
CS:TRANGROUP
,DS:TRANGROUP
,ES:NOTHING
;AN000;
500 parse_check_eol Proc
near ;AN000;
503 mov [parse_last
],si ;AN018; save start of parameter
504 invoke cmd_parse
;AN000; call parser
505 cmp al,end_of_line
;AN000; Are we at end of line?
506 jz parse_good_eol
;AN000; yes - no problem
508 cmp ax,result_no_error
;AN018; was any error found?
509 jnz ok_to_setup_pmsg
;AN018; yes - continue
510 inc ax ;AN018; set AX to 1 and turn off zero flag
513 call setup_parse_error_msg
;AN018; go set up error message
518 parse_check_eol endp
;AN000;
520 ; ****************************************************************
522 ; * ROUTINE: PARSE_WITH_MSG
524 ; * FUNCTION: Calls parser. If an error occurred, the error
525 ; * message is set up.
527 ; * INPUT: DS:SI last output from parser
528 ; * ES:DI points to parse block
529 ; * CX last output from parser
531 ; * OUTPUT: AX parser return code
534 ; * outputs from parser
536 ; * MSG_DISPLAY_CLASS set to parse error
537 ; * error message set up for STD_PRINTF
539 ; ****************************************************************
541 ASSUME
CS:TRANGROUP
,DS:TRANGROUP
,ES:NOTHING
;AN018;
543 parse_with_msg Proc
near ;AN018;
545 mov [parse_last
],si ;AN018; save start of parameter
546 invoke cmd_parse
;AN018; call parser
547 cmp al,end_of_line
;AN018; Are we at end of line?
548 jz parse_msg_good
;AN018; yes - no problem
549 cmp ax,result_no_error
;AN018; did an error occur
550 jz parse_msg_good
;AN018; yes - no problem
552 call setup_parse_error_msg
;AN018; go set up error message
557 parse_with_msg endp
;AN018;
559 ; ****************************************************************
561 ; * ROUTINE: SETUP_PARSE_ERROR_MSG
563 ; * FUNCTION: Calls parser. If an error occurred, the error
564 ; * message is set up.
566 ; * INPUT: AX Parse error number
567 ; * SI Set to past last parameter
568 ; * Parse_last Set to start of last parameter
570 ; * OUTPUT: MSG_DISPLAY_CLASS set to parse error
571 ; * error message set up for STD_PRINTF
573 ; ****************************************************************
575 ASSUME
CS:TRANGROUP
,DS:TRANGROUP
,ES:NOTHING
;AN018;
577 SETUP_PARSE_ERROR_MSG Proc
near ;AN018;
579 mov msg_disp_class
,parse_msg_class
;AC018; Set up parse message class
580 mov dx,offset TranGroup
:Extend_Buf_ptr
;AC018; get extended message pointer
581 mov byte ptr [si],end_of_line_out
;AC018; terminate the parameter string
582 mov Extend_Buf_ptr
,ax ;AC018; get message number in control block
583 cmp ax,lessargs_ptr
;AC018; if required parameter missing
584 jz Setup_parse_msg_ret
;AN018; no subst
585 mov si,[parse_last
] ;AC018; get start of parameter
586 mov string_ptr_2
,si ;AC018; get address of failed string
587 mov Extend_buf_sub
,one_subst
;AC018; put number of subst in control block
590 inc si ;AN018; make sure zero flag not set
594 SETUP_PARSE_ERROR_MSG Endp
;AN018;