page 80,132 ; SCCSID = @(#)tenv2.asm 1.1 85/05/14 ; SCCSID = @(#)tenv2.asm 1.1 85/05/14 TITLE Part6 COMMAND Transient routines. ; Environment utilities and misc. routines INCLUDE comsw.asm .xlist .xcref INCLUDE DOSSYM.INC INCLUDE comseg.asm INCLUDE comequ.asm .list .cref DATARES SEGMENT PUBLIC BYTE ;AC000; EXTRN pipeflag:byte DATARES ENDS TRANDATA SEGMENT PUBLIC BYTE ;AC000; EXTRN ACRLF_PTR:WORD EXTRN BadCD_Ptr:WORD EXTRN Badmkd_ptr:word EXTRN BADRMD_PTR:WORD EXTRN Extend_buf_ptr:word ;AN000; EXTRN Extend_buf_sub:byte ;AN022; EXTRN MD_exists_ptr:word ;AN006; EXTRN msg_disp_class:byte ;AC000; EXTRN NOSPACE_PTR:WORD EXTRN parse_chdir:byte ;AC000; EXTRN parse_mrdir:byte ;AC000; EXTRN PIPEEMES_PTR:WORD EXTRN string_buf_ptr:word TRANDATA ENDS TRANSPACE SEGMENT PUBLIC BYTE ;AC000; EXTRN CURDRV:BYTE EXTRN DESTINFO:BYTE EXTRN DESTTAIL:WORD EXTRN DIRCHAR:BYTE EXTRN dirflag:byte ;AN015; EXTRN KPARSE:BYTE ;AC000; 3/3/KK EXTRN msg_numb:word ;AN022; EXTRN parse1_addr:dword ;AC000; EXTRN parse1_type:byte ;AC000; EXTRN PATHPOS:WORD EXTRN RESSEG:WORD EXTRN srcxname:byte ;AC000; EXTRN string_ptr_2:word EXTRN SWITCHAR:BYTE EXTRN USERDIR1:BYTE TRANSPACE ENDS TRANCODE SEGMENT PUBLIC byte ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING EXTRN cerror:near PUBLIC $chdir PUBLIC $mkdir PUBLIC $rmdir PUBLIC crlf2 PUBLIC crprint PUBLIC delim PUBLIC error_output PUBLIC fcb_to_ascz PUBLIC pathchrcmp PUBLIC pathcrunch PUBLIC savudir PUBLIC savudir1 PUBLIC scanoff PUBLIC strcomp break $Chdir ; **************************************************************** ; * ; * ROUTINE: $CHDIR ; * ; * FUNCTION: Entry point for CHDIR command. Parse the command ; * line. If path is found, CHDIR to path. If a drive ; * letter is found, get and display the current dir ; * of the specified drive. If nothing is found, get ; * and display the current dir of the default drive. ; * ; * INPUT: command line at offset 81H ; * ; * OUTPUT: none ; * ; **************************************************************** assume ds:trangroup,es:trangroup $CHDIR: mov si,81H mov di,offset trangroup:parse_chdir ;AN000; Get adderss of PARSE_CHDIR xor cx,cx ;AN000; clear cx,dx xor dx,dx ;AN000; invoke parse_with_msg ;AC018; call parser cmp ax,end_of_line ;AC000; are we at end of line? jz bwdJ ; No args cmp ax,result_no_error ;AC000; did we have an error? jnz ChDirErr ;AC018; yes - exit cmp parse1_type,result_drive ;AC000; was a drive entered? jnz REALCD ; no ; ; D: was found. See if there is anything more. ; mov di,offset trangroup:parse_chdir ;AC000; get address of parse_chdir xor dx,dx ;AC000; invoke parse_check_eol ;AC000; call parser jnz ChDirErr ;AC000; bwdJ: invoke build_dir_for_chdir ; Drive only specified call crlf2 return REALCD: push si ;AN000; save position in line lds si,parse1_addr ;AN000; get address of filespec invoke move_to_srcbuf ;AN000; move to srcbuf pop si ;AN000; restore position in line mov di,offset trangroup:parse_chdir ;AC000; get address of parse_chdir xor dx,dx ;AC000; invoke parse_check_eol ;AC000; call parser jnz ChDirErr ;AC000; invoke SETPATH TEST [DESTINFO],2 JNZ BadChdir MOV AH,CHDIR INT int_command retnc invoke get_ext_error_number ;AN022; get the extended error cmp ax,error_path_not_found ;AN022; see if path not found jz BadChDir ;AN022; yes - issue old message call Set_Ext_Error_Subst ;AN022; jmp short chdirerr ;AN022; BadChDir: MOV DX,OFFSET TRANGROUP:BADCD_ptr ChDirErr: invoke Std_Eprintf return break $Mkdir assume ds:trangroup,es:trangroup $MKDIR: CALL SETRMMK JC MkDirErr MOV AH,MKDIR INT int_command retnc invoke get_ext_error_number ;AN022; get the extended error cmp ax,error_path_not_found ;AN022; see if path not found jz MD_other_err ;AN022; yes - issue old message cmp ax,error_access_denied ;AN022; access denied? jz badmderr ;AN022; yes - see if file exists call Set_Ext_Error_Subst ;AN022; jmp short MkDirerr ;AC022; yes - go print it BADMDERR: mov dx,offset trangroup:srcxname ;AN006; Set Disk transfer address mov ah,Set_DMA ;AN006; int int_command ;AN006; MOV AH,Find_First ;AN006; see if file/dir exists mov cx,attr_directory ;AN006; search for directory INT int_command ;AN006; jc MD_other_err ;AN006; doesn't exist - must be something else mov dl,srcxname.find_buf_attr ;AN006; we found a file/dir test dl,attr_directory ;AN006; was it a directory? jz MD_other_err ;AN006; no - must have been a file mov dx,offset trangroup:MD_exists_ptr ;AN006; set up already exists error jmp short MkDirErr ;AN006; make sure we didn't have network error MD_other_err: ;AN006; MOV DX,OFFSET TRANGROUP:BADMKD_ptr MkDirErr: invoke Std_Eprintf return Break ;**************************************************************** ;* ;* ROUTINE: SETRMMK ;* ;* FUNCTION: Parse routine for the internal MKDIR and RMDIR ;* commands. Parses the command line for a required ;* filespec. ;* ;* INPUT: command line at offset 81H ;* ;* OUTPUT: carry clear ;* DS:DX points to ASCIIZ argument ;* carry set ;* DS:DX has error message pointer ;* ;**************************************************************** SETRMMK: mov si,81H mov di,offset trangroup:parse_mrdir ;AN000; Get adderss of PARSE_MRDIR xor cx,cx ;AN000; clear cx,dx xor dx,dx ;AN000; invoke parse_with_msg ;AC000; call parser cmp ax,result_no_error ;AC000; did we have an error? jnz NOARGERR ;AC000; yes - exit mov di,offset trangroup:srcxname ;AN000; get address of srcxname push di ;AN000; save address push si ;AN000; save position in line lds si,parse1_addr ;AN000; get address of path mrdir_move_filename: ;AN000; put filespec in srcxname lodsb ;get a char from buffer stosb ;AN000; store in srcxname cmp al,end_of_line_out ;AC000; it char a terminator? jnz mrdir_move_filename ;AC000; no - keep moving pop si ;AN000; get line position back ; ; we have scanned an argument. See if any args beyond. ; mov di,offset trangroup:parse_mrdir ;AC000; get address of parse_mrdir invoke parse_check_eol ;AC000; are we at end of line? pop dx ;AC000; get address of SRCXNAME retz ;yes - return no error NOARGERR: mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer XOR AX,AX STC return break $Rmdir assume ds:trangroup,es:trangroup $RMDIR: CALL SETRMMK JC RmDirErr JNZ BADRDERR MOV AH,RMDIR INT int_command retnc invoke get_ext_error_number ;AN022; get the extended error cmp ax,error_path_not_found ;AN022; see if path not found jz badrderr ;AN022; yes - issue old message cmp ax,error_access_denied ;AN022; access denied? jz badrderr ;AN022; yes - issue old message call Set_Ext_Error_Subst ;AN022; jmp short RmDirerr ;AC022; yes - go print it BADRDERR: MOV DX,OFFSET TRANGROUP:BADRMD_ptr RmDirErr: invoke STD_Eprintf return ;**************************************************************** ;* ;* ROUTINE: Set_ext_error_subst ;* ;* FUNCTION: Sets up substitution for extended error ;* ;* INPUT: AX - extended error number ;* DX - offset of string ;* ;* OUTPUT: Extend_Buf_Ptr set up for STD_EPRINTF ;* ;**************************************************************** Set_ext_error_subst proc near ;AN022; mov msg_disp_class,ext_msg_class ;AN022; set up extended error msg class mov string_ptr_2,dx ;AN022; get address of failed string mov Extend_buf_sub,one_subst ;AN022; put number of subst in control block mov dx,offset TranGroup:Extend_Buf_ptr ;AN022; get extended message pointer mov Extend_Buf_ptr,ax ;AN022; get message number in control block ret ;AN022; return Set_ext_error_subst endp ;AN022; Break ; ; SavUDir - move the user's current directory on a drive into UserDir1 ; SavUDir1 - move the user's current directory on a drive into a specified ; buffer ; ; Inputs: DL has 1-based drive number ; ES:DI has destination buffer (SavUDir1 only) ; Outputs: Carry Clear ; DS = TranGroup ; Carry Set ; AX has error code ; Registers Modified: AX, SI ; SAVUDIR: MOV DI,OFFSET TRANGROUP:USERDIR1 SAVUDIR1: MOV AL,DL ADD AL,'@' CMP AL,'@' JNZ GOTUDRV ADD AL,[CURDRV] INC AL ; A = 1 GOTUDRV: STOSB MOV AH,[DIRCHAR] MOV AL,':' STOSW PUSH ES POP DS ASSUME DS:NOTHING MOV SI,DI MOV AH,CURRENT_DIR ; Get the Directory Text INT int_command retc PUSH CS POP DS ASSUME DS:TRANGROUP return CRLF2: PUSH DX MOV DX,OFFSET TRANGROUP:ACRLF_ptr PR: PUSH DS PUSH CS POP DS invoke std_printf POP DS POP DX return ; ; These routines (SCANOFF, DELIM) are called in batch processing when DS ; may NOT be TRANGROUP ; ASSUME DS:NOTHING,ES:NOTHING SCANOFF: LODSB CALL DELIM JZ SCANOFF DEC SI ; Point to first non-delimiter return ; ; Input: AL is character to classify ; Output: Z set if delimiter ; NZ set otherwise ; Registers modified: none ; DELIM: CMP AL,' ' retz CMP AL,'=' retz CMP AL,',' retz CMP AL,';' retz CMP AL,9 ; Check for TAB character retz CMP AL,0ah ; Check for line feed character - BAS return ASSUME DS:TRANGROUP,ES:TRANGROUP FCB_TO_ASCZ: ; Convert DS:SI to ASCIZ ES:DI MOV CX,8 MAINNAME: LODSB CMP AL,' ' JZ SKIPSPC STOSB SKIPSPC: LOOP MAINNAME LODSB CMP AL,' ' JZ GOTNAME MOV AH,AL MOV AL,dot_chr STOSB XCHG AL,AH STOSB MOV CL,2 EXTNAME: LODSB CMP AL,' ' JZ GOTNAME STOSB LOOP EXTNAME GOTNAME: XOR AL,AL STOSB return STRCOMP: ; ; Compare ASCIZ DS:SI with ES:DI. ; SI,DI destroyed. ; CMPSB retnz ; Strings not equal cmp byte ptr [SI-1],0 ; Hit NUL terminator? retz ; Yes, strings equal jmp short STRCOMP ; Equal so far, keep going CRPRINT: PUSH AX MOV AL,13 PUSH CX PUSH DI MOV DI,DX MOV CX,-1 PUSH ES PUSH DS POP ES REPNZ SCASB ; LOOK FOR TERMINATOR mov byte ptr [di-1],0 ; nul terminate the string POP ES mov string_ptr_2,dx mov dx,offset trangroup:string_buf_ptr invoke std_printf mov ds:byte ptr [di-1],13 ; now put the CR back JC ERROR_OUTPUT POP DI POP CX POP AX return ERROR_OUTPUT: PUSH CS POP DS ASSUME DS:TRANGROUP MOV ES,[RESSEG] ASSUME ES:RESGROUP MOV DX,OFFSET TRANGROUP:NOSPACE_ptr CMP [PIPEFLAG],0 JZ GO_TO_ERROR invoke PipeOff MOV DX,OFFSET TRANGROUP:PIPEEMES_ptr GO_TO_ERROR: JMP CERROR ASSUME DS:TRANGROUP,ES:TRANGROUP PATHCHRCMP: ;---- Mod for path invocation ---- PUBLIC pathchrcmp ;---- push ax mov ah,'/' CMP [SWITCHAR],ah JZ NOSLASHT CMP AL,'/' jz pccont NOSLASHT: CMP AL,'\' pccont: pop ax return ; Drive taken from FCB ; User dir saved in userdir1 ; ; Zero set if path dir, CHDIR to this dir, FCB filled with ? ; NZ set if path/file, CHDIR to file, FCB has file (parsed fill ' ') ; [DESTTAIL] points to parse point ; Carry set if no CHDIRs worked, FCB not altered. ; DESTISDIR set non zero if PATHCHRs in path (via SETPATH) ; PATHCRUNCH: mov [msg_numb],0 ;AN022; Set up message flag MOV DL,DS:[FCB] CALL SAVUDIR jc pcrunch_cderrJ ;AN022; if error on current dir - report invoke SETPATH TEST [DESTINFO],2 JNZ TRYPEEL ; If ? or * cannot be pure dir MOV AH,CHDIR INT int_command jnc chdir_worked ;AN022; no error - continue invoke get_ext_error_number ;AN022; get the extended error cmp ax,error_path_not_found ;AN022; if path not found jz trypeel ;AC022; keep trying cmp ax,error_access_denied ;AN022; if access denied jz trypeel ;AC022; keep trying mov [msg_numb],ax ;AN022; set up message flag jmp peelfail ;AN022; exit with other error chdir_worked: invoke SETREST1 MOV AL,'?' ; *.* is default file spec if pure dir MOV DI,5DH MOV CX,11 REP STOSB XOR AL,AL ; Set zero return pcrunch_cderrj: ;AN022; need this for long jmp jmp pcrunch_cderr ;AN022; TRYPEEL: MOV SI,[PATHPOS] DEC SI ; Point at NUL MOV AL,[SI-1] CMP [KPARSE],0 JNZ DELSTRT ; Last char is second KANJI byte, might be '\' CALL PATHCHRCMP JZ PEELFAIL ; Trailing '/' DELSTRT: MOV CX,SI MOV SI,DX PUSH DX DELLOOP: CMP SI,CX JZ GOTDELE LODSB invoke TESTKANJ JZ NOTKANJ8 INC SI JMP DELLOOP NOTKANJ8: CALL PATHCHRCMP JNZ DELLOOP MOV DX,SI DEC DX JMP DELLOOP GOTDELE: MOV SI,DX POP DX CMP SI,DX JZ BADRET MOV CX,SI MOV SI,DX DELLOOP2: ; Set value of KPARSE CMP SI,CX JZ TRYCD MOV [KPARSE],0 LODSB INVOKE TESTKANJ JZ DELLOOP2 INC SI INC [KPARSE] JMP DELLOOP2 TRYCD: push ax mov al,dot_chr CMP BYTE PTR [SI+1],al pop ax JZ PEELFAIL ; If . or .., pure cd should have worked mov al,[si-1] CMP al,':' ; Special case d:\file JZ BADRET CMP [KPARSE],0 JNZ NOTDOUBLESL ; Last char is second KANJI byte, might be '\' CALL PATHCHRCMP JNZ NOTDOUBLESL PEELFAIL: STC ; // return NOTDOUBLESL: MOV BYTE PTR [SI],0 MOV AH,CHDIR INT int_command JNC CDSUCC pcrunch_cderr: invoke get_ext_error_number ;AN022; get the extended error mov [msg_numb],ax ;AN022; set up message flag or si,si ;AN022; set up zero flag to not zero stc ;AN022; set up carry flag return BADRET: MOV AL,[SI] CALL PATHCHRCMP ; Special case 'DIRCHAR'file STC retnz XOR BL,BL XCHG BL,[SI+1] MOV AH,CHDIR INT int_command jc pcrunch_cderr ;AN022; go to error exit MOV [SI+1],BL CDSUCC: invoke SETREST1 INC SI ; Reset zero MOV [DESTTAIL],SI pushf ;AN015; save flags cmp dirflag,-1 ;AN015; don't do parse if in DIR jz pcrunch_end ;AN015; MOV DI,FCB MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 02H ; Parse with default drive INT int_command pcrunch_end: popf ;AN015; get flags back return trancode ends end