2 ; SCCSID = @(#)tcmd1b.asm 1.1 85/05/14
3 ; SCCSID = @(#)tcmd1b.asm 1.1 85/05/14
4 TITLE PART4 COMMAND Transient routines
.
6 ; Internal commands DIR,PAUSE,ERASE,TYPE,VOL,VER
12 INCLUDE comsw
.asm
;AC000;
14 INCLUDE ioctl
.inc ;AN000;
15 INCLUDE ea
.inc ;AN030;
20 TRANDATA
SEGMENT PUBLIC BYTE ;AC000;
21 EXTRN badcpmes_ptr
:word ;AC022;
22 EXTRN Extend_buf_ptr
:word ;AC000;
23 EXTRN Extend_buf_sub
:byte ;AN000;
24 EXTRN inornot_ptr
:word
25 EXTRN msg_disp_class
:byte ;AC000;
26 EXTRN parse_erase
:byte ;AC000;
27 EXTRN parse_mrdir
:byte ;AC000;
28 EXTRN parse_rename
:byte ;AC000;
29 EXTRN parse_vol
:byte ;AC000;
30 EXTRN PauseMes_ptr
:word
32 EXTRN slash_p_syn
:word ;AC000;
33 EXTRN volmes_ptr
:word ;AC000;
34 EXTRN volmes_ptr_2
:word ;AC000;
35 EXTRN volsermes_ptr
:word ;AC000;
36 EXTRN xa_cp
:byte ;AN030;
39 TRANSPACE
SEGMENT PUBLIC BYTE ;AC000;
43 EXTRN cpyflag
:byte ;AC000;
48 EXTRN msg_numb
:word ;AN022;
49 EXTRN one_char_val
:byte
50 EXTRN parse1_addr
:dword ;AN000;
51 EXTRN parse1_syn
:word ;AN000;
52 EXTRN srcbuf
:byte ;AN000;
53 EXTRN string_ptr_2
:word ;AN000;
56 EXTRN vol_ioctl_buf
:byte ;AC000;
57 EXTRN vol_label
:byte ;AC000;
58 EXTRN vol_serial
:dword ;AC000;
59 EXTRN xa_cp_out
:byte ;AN030;
60 EXTRN xa_cp_length
:word ;AN030;
61 EXTRN xa_list_attr
:word ;AC030;
65 TRANCODE
SEGMENT PUBLIC BYTE
67 ASSUME
CS:TRANGROUP
,DS:NOTHING
,ES:NOTHING
,SS:NOTHING
71 TRANSPACE
SEGMENT PUBLIC BYTE ;AC000;
72 EXTRN arg
:byte ; the arg structure!
77 EXTRN error_output
:near
79 EXTRN slashp_erase
:near ;AN000;
83 PUBLIC badpath_err
;AN022;
86 PUBLIC extend_setup
;AN022;
87 PUBLIC Get_ext_error_number
;AN022;
88 PUBLIC Get_file_code_page_tag
;AN000;
90 PUBLIC Set_ext_error_msg
;AN000;
91 PUBLIC set_file_code_page
;AN000;
96 assume
ds:trangroup
,es:trangroup
99 assume
ds:trangroup
,es:trangroup
102 mov dx,offset trangroup
:pausemes_ptr
110 ;****************************************************************
112 ;* ROUTINE: DEL/ERASE - erase file(s)
114 ;* FUNCTION: PARSE command line for file or path name and /P
115 ;* and invoke PATHCRUNCH. If an error occurs, set
116 ;* up an error message and transfer control to CERROR.
117 ;* Otherwise, transfer control to NOTEST2 if /P not
118 ;* entered or SLASHP_ERASE if /P entered.
120 ;* INPUT: command line at offset 81H
122 ;* OUTPUT: if no error:
123 ;* FCB at 5ch set up with filename(s) entered
124 ;* Current directory set to entered directory
126 ;****************************************************************
128 assume
ds:trangroup
,es:trangroup
131 mov si,81H
;AC000; get command line
132 mov comsw
,0 ;AN000; clear switch indicator
133 mov di,offset trangroup
:parse_erase
;AN000; Get adderss of PARSE_erase
134 xor cx,cx ;AN000; clear cx,dx
138 invoke parse_with_msg
;AC018; call parser
139 cmp ax,end_of_line
;AN000; are we at end of line?
140 jz good_line
;AN000; yes - done parsing
141 cmp ax,result_no_error
;AC000; did we have an error?
142 jnz errj2
;AC000; yes exit
144 cmp parse1_syn
,offset trangroup
:slash_p_syn
;AN000; was /P entered?
145 je set_erase_prompt
;AN000; yes - go set prompt
148 ; Must be filespec since no other matches occurred. move filename to srcbuf
150 push si ;AC000; save position in line
151 lds si,parse1_addr
;AC000; get address of filespec
152 cmp byte ptr[si+1],colon_char
;AC000; drive specified?
153 jnz Erase_drive_ok
;AC000; no - continue
154 cmp byte ptr[si+2],end_of_line_out
;AC000; was only drive entered?
155 jnz erase_drive_ok
;AC000; no - continue
156 mov ax,error_file_not_found
;AN022; get message number in control block
157 jmp short extend_setup
;AC000; exit
160 invoke move_to_srcbuf
;AC000; move to srcbuf
161 pop si ;AC000; get position back
162 jmp short erase_scan
;AN000; continue parsing
165 cmp comsw
,0 ;AN018; was /P already entered?
166 jz ok_to_set_erase_prompt
;AN018; no go set switch
167 mov ax,moreargs_ptr
;AN018; set up too many arguments
168 invoke setup_parse_error_msg
;AN018; set up an error message
169 jmp short errj2
;AN018; exit
171 ok_to_set_erase_prompt: ;AN018;
172 inc comsw
;AN000; indicate /p specified
173 jmp short erase_scan
;AN000; continue parsing
175 good_line: ;G We know line is good
178 mov ax,[msg_numb
] ;AN022; get message number
179 cmp ax,0 ;AN022; was message flag set?
180 jnz extend_setup
;AN022; yes - print out message
181 cmp [destisdir
],0 ; No CHDIRs worked
182 jnz badpath_err
;AC022; see if they should have
185 cmp comsw
,0 ;AN000; was /p specified
186 jz notest2j
;AN000; no - go to notest2
187 jmp slashp_erase
;AN000; yes - go to slashp_erase
192 badpath_err: ;AN022; "Path not found" message
193 mov ax,error_path_not_found
;AN022; set up error number
195 extend_setup: ;AN022;
196 mov msg_disp_class
,ext_msg_class
;AN022; set up extended error msg class
197 mov dx,offset TranGroup
:Extend_Buf_ptr
;AC022; get extended message pointer
198 mov Extend_Buf_ptr
,ax ;AN022; get message number in control block
199 errj2: ;AC022; exit jump
204 ; ****************************************************************
206 ; * ROUTINE: CRENAME - rename file(s)
208 ; * FUNCTION: PARSE command line for one full filespec and one
209 ; * filename. Invoke PATHCRUNCH on the full filespec.
210 ; * Make sure the second filespec only contains a
211 ; * filename. If both openands are valid, attempt
212 ; * to rename the file.
214 ; * INPUT: command line at offset 81H
218 ; ****************************************************************
220 assume
ds:trangroup
,es:trangroup
224 mov si,81H
;AC000; Point to command line
225 mov di,offset trangroup
:parse_rename
;AN000; Get adderss of PARSE_RENAME
226 xor cx,cx ;AN000; clear cx,dx
228 invoke parse_with_msg
;AC018; call parser
229 cmp ax,result_no_error
;AC000; did we have an error?
230 jz crename_no_parse_error
;AC000; no - continue
231 JMP crename_parse_error
;AC000; Yes, fail. (need long jump)
234 ; Get first file name returned from parse into our buffer
236 crename_no_parse_error:
237 push si ;AN000; save position in line
238 lds si,parse1_addr
;AN000; get address of filespec
239 invoke move_to_srcbuf
;AN000; move to srcbuf
240 pop si ;AN000; restore position in line
242 xor dx,dx ;AN000; clear dx
243 invoke parse_with_msg
;AC018; call parser
244 cmp ax,result_no_error
;AN000; did we have an error?
245 JNZ crename_parse_error
;AN000; Yes, fail.
248 ; Check the second file name for drive letter colon
250 push si ;AN000; save position in line
251 lds si,parse1_addr
;AC000; get address of path
254 cmp [si+1],al ;AC000; Does the 2nd parm have a drive spec?
255 jnz ren_no_drive
;AN000; Yes, error
256 mov msg_disp_class
,parse_msg_class
;AN000; set up parse error msg class
257 mov dx,offset TranGroup
:Extend_Buf_ptr
;AC000; get extended message pointer
258 mov Extend_Buf_ptr
,BadParm_ptr
;AN000; get "Invalid parameter" message number
261 crename_parse_error: ;AC022;
262 jmp short errj
;AC000;
265 ; Get second file name returned from parse into the fCB. Save
266 ; character after file name so we can later check to make sure it
267 ; isn't a path character.
271 mov di,FCB
+10H
;AC000; set up to parse second file name
272 mov ax,(Parse_File_Descriptor
SHL 8) OR 01H ;AC000;
273 int int_command
;AC000; do the function
274 lodsb ;AC000; Load char after filename
275 mov one_char_val
,al ;AN000; save char after filename
276 pop si ;AN000; get line position back
279 ; We have source and target. See if any args beyond.
282 mov di,offset trangroup
:parse_rename
;AC000; get address of parse_rename
283 invoke parse_check_eol
;AC000; are we at end of line?
284 jnz crename_parse_error
;AN000; no, fail.
287 mov dx,offset trangroup
:badcpmes_ptr
288 jz errj2
; If 1st parm a dir, print error msg
290 mov ax,[msg_numb
] ;AN022; get message number
291 cmp ax,0 ;AN022; was message flag set?
292 jnz extend_setup
;AN022; yes - print out message
293 cmp [destisdir
],0 ; No CHDIRs worked
294 jz notest3
; see if they should have
295 Jmp badpath_err
;AC022; set up error
298 mov al,one_char_val
;AN000; move char into AX
299 mov dx,offset trangroup
:inornot_ptr
; Load invalid fname error ptr
300 invoke pathchrcmp
; Is the char in al a path sep?
301 jz errj
; Yes, error - 2nd arg must be
307 cmp al, 0FFH ; Did an error occur??
310 invoke get_ext_error_number
;AN022; get extended error
311 SaveReg
<AX> ;AC022; Save results
312 mov al, 0FFH ; Restore original error state
321 RestoreReg
<AX> ;AC022; get the error number back
322 cmp ax,error_file_not_found
;AN022; error file not found?
323 jz use_renerr
;AN022; yes - use generic error message
324 cmp ax,error_access_denied
;AN022; error file not found?
325 jz use_renerr
;AN022; yes - use generic error message
326 jmp extend_setup
;AN022; need long jump - use extended error
329 mov dx,offset trangroup
:RenErr_ptr
;AC022;
338 ;****************************************************************
340 ;* ROUTINE: TYPEFIL - Display the contents of a file to the
341 ;* standard output device
343 ;* SYNTAX: TYPE filespec
345 ;* FUNCTION: If a valid filespec is found, read the file until
346 ;* 1Ah and display the contents to STDOUT.
348 ;* INPUT: command line at offset 81H
352 ;****************************************************************
354 assume
ds:trangroup
,es:trangroup
358 mov di,offset trangroup
:parse_mrdir
;AN000; Get adderss of PARSE_MRDIR
359 xor cx,cx ;AN000; clear cx,dx
361 invoke parse_with_msg
;AC018; call parser
362 cmp ax,result_no_error
;AC000; did we have an error?
363 jnz typefil_parse_error
;AN000; yes - issue error message
365 push si ;AC000; save position in line
366 lds si,parse1_addr
;AC000; get address of filespec
367 invoke move_to_srcbuf
;AC000; move to srcbuf
368 pop si ;AC000; get position back
369 mov di,offset trangroup
:parse_mrdir
;AC000; get address of parse_mrdir
370 invoke parse_check_eol
;AC000; are we at end of line?
371 jz gottarg
;AC000; yes - continue
373 typefil_parse_error: ;AN000; no - set up error message and exit
378 test [destinfo
],00000010b ; Does the filespec contain wildcards
379 jz nowilds
; No, continue processing
380 mov dx,offset trangroup
:inornot_ptr
; Yes, report error
383 mov ax,ExtOpen
SHL 8 ;AC000; open the file
384 mov bx,read_open_mode
;AN000; get open mode for TYPE
385 xor cx,cx ;AN000; no special files
386 mov dx,read_open_flag
;AN000; set up open flags
387 mov di,-1 ;AN030; no parm list
388 mov si,offset trangroup
:srcbuf
;AN030; get file name
390 jnc typecont
; If open worked, continue. Otherwise load
393 push cs ;AN022; make sure we have local segment
395 invoke set_ext_error_msg
;AN022;
398 mov string_ptr_2
,offset trangroup
:srcbuf
;AC022; get address of failed string
399 mov Extend_buf_sub
,one_subst
;AC022; put number of subst in control block
400 jmp cerror
;AC022; exit
403 mov bx,ax ;AC000; get Handle
404 mov cx,stdout
;AN000; set output to STDOUT
405 call set_file_code_page
;AN000; Set code page on output device
406 jc typerr2
;AN022; exit if error
408 mov zflag
,0 ; Reset ^Z flag
414 cmp cs:[zflag
],0 ;AC050; Is the ^Z flag set?
416 mov cx,cs:[bytcnt
] ;AC056; No, continue
419 jc typerr
;AN022; Exit if error
421 jcxz typelp_ret
;AC000; exit if nothing read
423 pop es ; Check to see if a ^Z was read.
432 jnz foundz
; Yes, handle it
433 cmp byte ptr [di-1],1
ah ; No, double check
434 jnz typecont2
; No ^Z, continue
437 sub cx,ax ; Otherwise change cx so that only those
438 dec cx ; bytes up to but NOT including the ^Z
439 push cs ; will be typed.
442 not zflag
; Turn on ^Z flag so that the routine
444 typecont2: ; will quit after this write.
455 retz
; One less byte OK (^Z)
462 retnz
; If device, no error message
469 assume
ds:trangroup
,es:trangroup
472 ; VOLUME command displays the volume ID on the specified drive
477 mov di,offset trangroup
:parse_vol
;AN000; Get adderss of PARSE_VOL
478 xor cx,cx ;AN000; clear cx,dx
480 invoke parse_with_msg
;AC018; call parser
481 cmp ax,end_of_line
;AC000; are we at end of line?
482 jz OkVolArg
;AC000; Yes, display default volume ID
483 cmp ax,result_no_error
;AC000; did we have an error?
484 jnz BadVolArg
;AC000; Yes, fail.
486 ; We have parsed off the drive. See if there are any more chars left
489 mov di,offset trangroup
:parse_vol
;AC000; get address of parse_vol
491 invoke parse_check_eol
;AC000; call parser
492 jz OkVolArg
;AC000; yes, end of road
494 ; The line was not interpretable. Report an error.
499 ; Find the Volume ID on the disk.
504 mov al,blank
;AN051; Print out a blank
505 invoke print_char
;AN051; before volume message
509 ; Volume IDs are only findable via extended FCBs or find_first with attributes
513 mov di,FCB
-7 ; Point to extended FCB beginning
514 mov al,-1 ; Tag to indicate Extention
516 xor ax,ax ; Zero padding to volume label
520 mov al,attr_volume_ID
; Look for volume label
522 inc di ; Skip drive byte; it is already set
523 mov cx,11 ; fill in remainder of file
527 ; Set up transfer address (destination of search first information)
529 mov dx,offset trangroup
:dirbuf
536 mov ah,Dir_Search_First
539 ;********************************
540 ; Print volume ID info
542 push ax ;AC000; AX return from SEARCH_FIRST for VOL ID
543 mov al,DS:[FCB
] ;AC000; get drive letter
550 mov vol_drv
,al ;AC000; get drive letter into argument
551 pop ax ;AC000; get return code back
552 or al,al ;AC000; volume label found?
553 jz Get_vol_name
;AC000; volume label exists - go get it
554 mov dx,offset trangroup
:VolMes_ptr_2
;AC000; set up no volume message
555 jmp short print_serial
;AC000; go print it
558 mov di,offset trangroup
:charbuf
560 mov si,offset trangroup
:dirbuf
+ 8 ;AN000; 3/3/KK
561 mov cx,11 ;AN000; 3/3/KK
562 rep movsb ;AN000; 3/3/KK
564 xor al,al ;AC000; store a zero to terminate the string
566 mov dx,offset trangroup
:VolMes_ptr
;AC000; set up message
571 ; Attempt to get the volume serial number from the disk. If an error
572 ; occurs, do not print volume serial number.
575 push dx ;AN000; save message offset
576 mov ax,(GetSetMediaID
SHL 8) ;AC036; Get the volume serial info
577 mov bl,DS:[FCB
] ;AN000; get drive number from FCB
578 mov dx,offset trangroup
:vol_ioctl_buf
;AN000;target buffer
579 int int_command
;AN000; do the call
580 pop dx ;AN000; get message offset back
581 jc printvol_end
;AN000; if error, just go print label
582 call std_printf
;AC000; go print volume message
583 mov al,blank
;AN051; Print out a blank
584 invoke print_char
;AN051; before volume message
585 mov dx,offset trangroup
:VolSerMes_ptr
;AN000; get serial number message
588 jmp std_printf
;AC000; go print and exit
590 ;****************************************************************
592 ;* ROUTINE: Set file Code page
594 ;* FUNCTION: Check CPSW status, if CPSW is on, get the file's
595 ;* code page and attempt to invoke it on the
598 ;* INPUT: file handle in BX - unless copyflg is set
599 ;* handle of output device in CX
601 ;* OUTPUT: if carry set (code page invoke failed)
602 ;* ax = extended error
607 ;****************************************************************
609 Set_file_code_page proc
near ;AN000;
611 push bx ;AN000; save registers
615 cmp cpyflag
,1 ;AN000; were we called from COPY?
616 jz Already_have_cp
;AN000; yes - already have code page
617 call get_file_code_page_tag
;AN000; get the file's code page
618 jc cp_set_error
;AN000; if error - just continue
620 already_have_cp: ;AN000; See what was returned.
621 mov ax,(file_times
SHL 8)+set_XA
;AC030; set code page
622 mov di,offset trangroup
:xa_cp_out
;AC030; offset of attr list
623 mov bx,cx ;AN000; get handle of output device
624 int int_command
;AN000;
625 jnc set_file_cp_end
;AN000; all okay - return
627 pop dx ;AC030; we don't restore DX for error -
628 call Set_Ext_Error_msg
;AN000; we return error message
629 jmp short set_file_cp_exit
;AC030; exit
631 set_file_cp_end: ;AN000; finished
632 pop dx ;AN000; restore registers
640 Set_file_code_page endp
;AN000;
643 ;****************************************************************
645 ;* ROUTINE: Get file Code page tag
647 ;* FUNCTION: Get code page file attribute.
649 ;* INPUT: file handle in BX
651 ;* OUTPUT: if error - carry set
652 ;* otherwise - xa_list_attr set to file's code page
654 ;* AX and DI modified
656 ;****************************************************************
659 Get_file_code_page_tag proc
near ;AN000;
664 mov xa_list_attr
,0 ;AN030; initialize code page
665 mov ax,(file_times
SHL 8)+get_XA
;AC030; get extended attributes
666 mov si,offset trangroup
:xa_cp
;AN030; get xa request buffer
667 mov di,offset trangroup
:xa_cp_out
;AC030; get xa output buffer
668 mov cx,xa_cp_length
;AN030; length of buffer
669 int int_command
;AN000;
676 Get_file_code_page_tag endp
;AN000;
679 ;****************************************************************
681 ;* ROUTINE: Set_ext_error_msg
683 ;* FUNCTION: Sets up extended error message for printing
685 ;* INPUT: return from INT 21
687 ;* OUTPUT: extended error message set up in extended error
690 ;****************************************************************
692 Set_ext_error_msg proc
near ;AN000;
694 call get_ext_error_number
;AC022; get the extended error
695 mov msg_disp_class
,ext_msg_class
;AN000; set up extended error msg class
696 mov dx,offset TranGroup
:Extend_Buf_ptr
;AC000; get extended message pointer
697 mov Extend_Buf_ptr
,ax ;AN000; get message number in control block
698 stc ;AN000; make sure carry is set
702 Set_ext_error_msg endp
;AN000;
704 ;****************************************************************
706 ;* ROUTINE: Get_ext_error_number
708 ;* FUNCTION: Does get extended error function call
710 ;* INPUT: return from INT 21
712 ;* OUTPUT: AX - extended error number
714 ;****************************************************************
716 Get_ext_error_number proc
near ;AN022;
718 SaveReg
<BX,CX,DX,SI,DI,BP,ES,DS> ;AN022; save registers
719 mov ah,GetExtendedError
;AN022; get extended error
720 xor bx,bx ;AN022; clear BX
721 int int_command
;AN022;
722 RestoreReg
<DS,ES,BP,DI,SI,DX,CX,BX> ;AN022; restore registers
726 Get_ext_error_number endp
;AN022;