; PROGRAM: RENAME ; VERSION: 3.0 ; DATE: 18 MAY 84 ; AUTHOR: RICHARD CONN ; PREVIOUS VERSIONS: 2.0 (16 JAN 83) ; PREVIOUS VERSIONS: 1.4 (6 JAN 83), 1.3 (7 DEC 82), 1.2 (10 NOV 82) ; PREVIOUS VERSION: RENAME.ASM Version 1.1 (26 OCT 81) VERS equ 30 z3env SET 0f400h ; ; RENAME Command -- ; RENAME is used to change the name of one or more files. Unlike ; the ZCPR2-resident REN function, RENAME permits ambiguous file names ; and supports an Inspect mode that allows the user to confirm each ; rename before it is done. Additionally, there is a Control Mode which ; allows the user to manually specify the name for each file as it is ; presented to him. ; ; The RENAME command may be of the following forms: ; RENAME dir:afn1=afn2,dir:afn3=afn4,... o ; RENAME dir:afn,dir:afn1=afn2,... o ; The first form shows elements of the form ; dir:afn1=afn2 ; while the second form shows elements of the form ; dir:afn ; which is the same as ; dir:afn=afn ; and only makes sense if Control Mode is used. ; ; The option characters (o) are none or more of the following: ; C -- Control Mode; manually specify each new name ; I -- Inspect and approve each rename ; S -- Include SYStem files ; ; Examples: ; RENAME *.MAC=*.ASM <-- Rename all ASM files to MAC ; RENAME *.MAC C <-- Rename all MAC files to names ; input by the user ; RENAME *.OBJ=*.COM SI <-- Rename all COM files to OBJ ; and include SYStem files ; and Inspect and approve each ; change ; FALSE EQU 0 TRUE EQU NOT FALSE ESIZE EQU 16 ; SIZE OF DIR ENTRY (FROM SYSLIB DIRF ROUTINE) EXT DIRQ ; DIRECTORY PROCESSOR EXT Z3INIT ; INIT BUFFERS EXT ZFNAME ; FILE NAME PROCESSOR EXT Z3LOG ; Z3 DU LOG EXT F$DELETE ; DELETE FILE EXT F$RENAME ; RENAME FILE EXT BBLINE ; INPUT LINE EDITOR EXT INITFCB ; INIT FCB EXT BDOS ; BDOS ENTRY EXT PUTUD ; SAVE CURRENT USER/DISK EXT GETUD ; RESTORE CURRENT USER/DISK EXT MOVEB ; COPY ROUTINE EXT PHLDC ; PRINT HL AS DECIMAL CHARS EXT PRINT ; PRINT ROUTINE EXT COUT ; CONSOLE OUTPUT ROUTINE EXT CIN ; CONSOLE INPUT ROUTINE EXT CAPS ; CAPITALIZE ROUTINE EXT CRLF ; NEW LINE ROUTINE EXT FILLB ; FILL ROUTINE EXT CODEND ; CODE END COMPUTATION ROUTINE ; ; CP/M EQUATES ; CPM EQU 0 ; WARM BOOT FCB EQU 5CH ; FCB BUFF EQU 80H ; INPUT LINE BUFFER CR EQU 13 ; LF EQU 10 ; ; ; Environment Definition ; if z3env ne 0 ; ; External ZCPR3 Environment Descriptor ; jmp start db 'Z3ENV' ;This is a ZCPR3 Utility db 1 ;External Environment Descriptor z3eadr: dw z3env start: lhld z3eadr ;pt to ZCPR3 environment ; else ; ; Internal ZCPR3 Environment Descriptor ; MACLIB Z3BASE.LIB MACLIB SYSENV.LIB z3eadr: jmp start SYSENV start: lxi h,z3eadr ;pt to ZCPR3 environment endif ; ; Start of Program -- Initialize ZCPR3 Environment ; call z3init ;initialize the ZCPR3 Env and the VLIB Env LXI H,0 ; GET STACK PTR DAD SP SHLD STACK ; SAVE IT CALL CODEND SHLD CMDLNE ; SETUP COMMAND LINE BUFFER LXI D,100H ; BUFFER SIZE DAD D SHLD NTFCB ; SET TEMP FCB DAD D SHLD DIRBUF ; PTR TO DIR BUFFER SPHL ; NEW SP LHLD NTFCB ; SET 2ND FCB LXI D,40 DAD D SHLD OFCB CALL PUTUD ; SAVE CURRENT USER/DISK AWAY CALL PRINT DB 'RENAME Version ' DB VERS/10+'0','.',(VERS MOD 10)+'0',0 LDA FCB+1 ; GET FIRST CHAR OF FILE NAME CPI ' ' ; NO FILE SPEC? JZ HELP CPI '/' ; OPTION CAUGHT? JNZ ECONT ; PRINT HELP INFORMATION HELP: CALL PRINT DB CR,LF,'Syntax:' DB CR,LF,' RENAME dir:afn1=afn2,afn3=afn4,... o...' DB CR,LF,'Options:' DB CR,LF,' C -- Control Mode (Allow user to manually name each ' DB 'file)' DB CR,LF,' I -- Inspect Mode (Give user approval option)' DB CR,LF,' S -- Include SYS files' DB CR,LF DB 0 ; RETURN TO OS RETURN: LHLD STACK ; GET OLD STACK SPHL ; SET IT RET ; COPY BUFFER INTO TEMP BUFFER ECONT: LHLD CMDLNE ; PT TO COMMAND LINE SAVE BUFFER XCHG ; ... IN DE LXI H,BUFF+1 ; PT TO BUFFER MVI B,80H ; BUFFER SIZE CALL MOVEB ; COPY INTO COMMAND LINE BUFFER ; EXTRACT FLAGS IF PRESENT XRA A ; SET NO INSPECT, NO R/O, AND NO SYSTEM FILES STA INSPECT STA CONTROL ; SET NO CONTROL MODE MVI A,80H ; SELECT NON-SYS FILES ONLY STA SYSTEM LXI H,0 ; SET FILE COUNT SHLD FILECNT LHLD CMDLNE ; PT TO BUFFER ; SKIP TO FILE NAME STRING SBLANK: MOV A,M ; SKIP TO NON-BLANK CPI ' ' ; ? JNZ SBL1 INX H ; PT TO NEXT CHAR JMP SBLANK ; SKIP TO END OF FILE NAME STRING SBL1: MOV A,M ; SKIP TO OR EOL ORA A ; DONE? JZ OPT CPI ' ' ; JZ OPT INX H ; PT TO NEXT JMP SBL1 ; CHECK FOR LEADING SLASH ON OPTION AND SKIP IT IF SO OPT: CPI '/' ; OPTION CHAR? JNZ OPTION INX H ; SKIP SLASH ; PROCESS LIST OF OPTIONS OPTION: MOV A,M ; GET BYTE ORA A ; DONE? JZ DSPEC INX H ; PT TO NEXT CHAR CPI ' ' ; SKIP OVER SPACES JZ OPTION CPI '/' ; IF OPTION LETTER, OBVIOUS ERROR, SO HELP JZ HELP CPI 'C' ; CONTROL? JZ OPTCTRL CPI 'I' ; INSPECT? JZ OPTINS CPI 'S' ; SYSTEM FILES? JNZ HELP MVI A,0C0H ; SET FOR SYS FILES STA SYSTEM JMP OPTION OPTCTRL: MVI A,0FFH ; CONTROL MODE STA CONTROL JMP OPTION OPTINS: MVI A,0FFH ; INSPECT STA INSPECT JMP OPTION ; EXTRACT DISK, USER, AND FILE NAME INFORMATION DSPEC: LHLD CMDLNE ; PT TO BEFORE FIRST BYTE DCX H DSPEC0: INX H ; PT TO BYTE MOV A,M ; GET BYTE ORA A ; DONE? JZ HELP CPI ' ' ; ? JZ DSPEC0 ; ; MAJOR REENTRY POINT WHEN FILE SPECS ARE SEPARATED BY COMMAS ; HL PTS TO FIRST BYTE OF NEXT FILE SPEC ; DSPEC1: CALL GETUD ; RESET USER IF NECESSARY PUSH H LHLD NTFCB XCHG ; PT TO FCB IN DE POP H MVI A,0 ; DIR BEFORE DU CALL ZFNAME ; EXTRACT FILE NAME INTO FCB, AND GET DISK AND USER SHLD NEXTCH ; SAVE PTR TO DELIMITER WHICH ENDED SCAN PUSH H LHLD NTFCB XCHG ; PT TO FCB IN DE POP H CALL Z3LOG ; LOG INTO DU ; FIRST NAME IS NOW EXTRACTED -- EXTRACT POSSIBLE SECOND NAME NAME2: LHLD OFCB ; PT TO FCB FOR 2ND NAME XCHG LHLD NTFCB ; PT TO FIRST NAME MVI B,16 ; COPY 16 BYTES CALL MOVEB LHLD NEXTCH ; PT TO CHAR WHICH ENDED PARSE MOV A,M ; GET IT CPI '=' ; ASSIGNMENT? JNZ RENAME ; GO AHEAD IF NOT INX H ; PT TO CHAR AFTER '=' PUSH H LHLD OFCB ; PT TO TEMP FCB XCHG ; ... IN DE POP H MVI A,0 ; DIR BEFORE DU CALL ZFNAME ; EXTRACT FILE NAME INTO FCB, AND GET DISK AND USER SHLD NEXTCH ; SAVE PTR TO DELIMITER WHICH ENDED SCAN ; LOAD DIRECTORY AND RENAME FILES RENAME: LHLD OFCB XCHG ; PT TO FCB LHLD DIRBUF ; PT TO END OF CODE CALL INITFCB ; INIT THE FCB LDA SYSTEM ; SET FLAGS CALL DIRQ ; LOAD DIR, SELECT FILES, PACK, AND ALPHABETIZE ; REN DIR FILES; HL PTS TO FIRST FILE, BC=FILE COUNT CALL RENFILES ; CHECK FOR NEXT FILE SPEC LHLD NEXTCH ; GET PTR MOV A,M ; GET DELIM CPI ',' ; ANOTHER FILE? JNZ RENDONE INX H ; PT TO CHAR AFTER COMMA JMP DSPEC1 ; CONTINUE PROCESSING ; RENAME COMPLETE -- PRINT COUNT AND EXIT RENDONE: CALL PRCOUNT ; PRINT FILE COUNT JMP RETURN ; RENAME SELECTED FILES RENFILES: MOV A,B ; CHECK FOR ANY FILES LOADED ORA C RZ ; PRINT FILE NAME RENLP: PUSH B ; SAVE ENTRY COUNT CALL PRINT DB CR,LF,'Rename ',0 PUSH H ; SAVE PTR TO FCB LHLD NTFCB ; COPY NEW TEMPLATE INTO RENFCB LXI D,RENFCB MVI B,16 CALL MOVEB POP H ; GET PTR PUSH H ; SAVE PTR INX H ; PT TO FN OF OLD NAME INX D ; PT TO FN OF RENFCB MVI B,11 ; 11 BYTES TO FN AND FT RENLP1: LDAX D ; GET CHAR OF NEW CPI '?' ; CHANGE '?' TO OLD CHAR JNZ RENLP2 MOV A,M ; GET OLD CHAR ANI 7FH ; MASK OLD CHAR STAX D ; STORE IT AWAY AS NEW RENLP2: INX H ; PT TO NEXT CHAR INX D DCR B ; COUNT DOWN JNZ RENLP1 LXI H,RENFCB ; PT TO NEW NAME CALL PRFN ; PRINT FILE NAME CALL PRINT DB ' from ',0 POP H ; GET PTR TO OLD FILE NAME PUSH H ; SAVE IT AGAIN CALL PRFN ; PRINT FILE NAME POP H ; GET PTR ; CHECK FOR CONTROL MODE AND PERFORM CONTROL FUNCTION IF SET LDA CONTROL ; GET FLAG ORA A ; NZ=YES JNZ RENCTRL ; CHECK FOR INSPECTION AND INSPECT IF SET LDA INSPECT ; GET FLAG ORA A ; 0=NO JZ DOIT ; PROMPT USER FOR RENAME CALL RENQ ; REN QUESTION CPI 'Q' ; QUIT? JZ QUIT CPI 'Y' ; YES? JZ DOIT ; DON'T RENAME FILE NODO: CALL PRINT DB CR,LF,'NO Name Change',0 JMP RENTEST ; PRINT FILE NAME PTED TO BY HL PRFN: INX H ; PT TO FILE NAME MVI B,8 ; PRINT NAME CALL PRNT MVI A,'.' ; DECIMAL CALL COUT MVI B,3 ; PRINT TYPE CALL PRNT RET ; PROMPT USER FOR RENAME RENQ: CALL PRINT ; PRINT PROMPT DB ' -- Rename (Y/N/Q=Quit)? ',0 CALL CIN ; GET RESPONSE CALL CAPS ; CAPITALIZE CALL COUT ; ECHO RET ; CONTROL FUNCTION -- ALLOW USER TO RENAME AS HE DESIRES RENCTRL: PUSH H ; SAVE PTR TO FILE RCTRL: CALL PRINT DB CR,LF,' -- New Name (=No Change)? ',0 MVI A,0FFH ; CAPITALIZE CALL BBLINE ; INPUT LINE FROM USER ORA A ; CHECK FOR JUST JNZ RCTRL0 POP H ; GET PTR TO FILE JMP RENTEST ; PROCEED WITH NEXT ENTRY RCTRL0: LXI D,RENFCB ; PLACE INTO NEW NAME FCB CALL ZFNAME ; JUST EXTRACT NAME MVI B,11 ; CHECK FOR ANY WILD CHARS RCTRL1: INX D ; PT TO NEXT CHAR LDAX D ; GET IT CPI '?' ; CAN'T BE WILD JZ WERR CPI '*' ; CAN'T BE WILD JZ WERR DCR B ; COUNT DOWN JNZ RCTRL1 JMP RDOIT ; DONE -- PERFORM RENAME WERR: CALL PRINT DB CR,LF,'Wild Card (?,*) in Name -- Try Again',0 JMP RCTRL ; QUIT RENAME PROGRAM QUIT: CALL PRCOUNT ; PRINT COUNT OF FILES RENAMED CALL PRINT DB ' QUIT',0 JMP RETURN ; REN FILE, BUT GET PTR FIRST RDOIT: POP H ; GET PTR ; RENAME FILE; OLD NAME PTED TO BY HL, NEW NAME IN RENFCB DOIT: PUSH H ; STEP 1 -- DETERMINE IF NEW NAME ALREADY EXISTS LXI D,RENFCB ; PT TO NEW NAME CALL INITFCB MVI C,17 ; SEARCH FOR FIRST CALL BDOS INR A ; NOT FOUND? JZ DOIT1 CALL PRINT DB CR,LF,' -- File Exists -- Delete It (Y/N)? ',0 CALL CIN ; GET RESPONSE CALL CAPS CALL COUT POP H ; PREP FOR ABORT CPI 'Y' ; YES -- CONTINUE? JNZ RENTEST ; NOT YES, SO SKIP IT ; DELETE OLD FILE, SO SET ATTRIBUTES AND DO IT PUSH H ; SAVE PTR AGAIN CALL INITFCB ; CLEAR FCB MVI C,30 ; SET FILE ATTRIBUTES TO R/W IF NOT ALREADY CALL BDOS CALL INITFCB CALL F$DELETE ; DELETE FILE DOIT1: POP H ; HL PTS TO OLD NAME ; CLEAR THE OLD NAME'S ATTRIBUTES IN CASE IT WAS R/O PUSH H ; SAVE PTR TO OLD NAME PUSH H LHLD OFCB ; COPY OLD NAME XCHG POP H MVI B,16 CALL MOVEB PUSH D ; CLEAR ATTRIBUTES MVI B,11 ; 11 BYTES INX D ; PT TO FIRST DOIT2: LDAX D ; GET CHAR ANI 7FH ; CLEAR ATT STAX D ; PUT CHAR INX D ; PT TO NEXT DCR B ; COUNT DOWN JNZ DOIT2 POP D ; NOW SET ATTRIBUTES OF OLD NAME CALL INITFCB MVI C,30 ; SET ATTRIBUTES CALL BDOS CALL INITFCB ; DO THE RENAME LXI H,RENFCB ; PT TO NEW NAME XCHG CALL INITFCB ; INIT NEW FCB XCHG ; HL PTS TO NEW NAME, DE PTS TO OLD NAME CALL F$RENAME ; RENAME THE FILE ; RESTORE THE ORIGINAL ATTRIBUTE BITS POP H ; GET PTR TO OLD NAME LXI D,RENFCB+1 ; PT TO NEW NAME PUSH H ; SAVE PTR TO OLD NAME INX H ; PT TO FN OF OLD NAME XCHG ; HL PTS TO NEW NAME, DE PTS TO OLD NAME MVI B,11 ; 11 BYTES DOIT3: LDAX D ; GET ATTRIBUTE BIT OF OLD NAME ANI 80H ; LOOK ONLY AT ATTRIBUTE BIT ORA M ; MASK IN NEW NAME BYTE MOV M,A ; STORE IT AWAY INX H ; PT TO NEXT INX D DCR B ; COUNT DOWN JNZ DOIT3 ; SET THE ORIGINAL ATTRIBUTES INTO THE NEW FILE LXI D,RENFCB ; PT TO FCB CALL INITFCB MVI C,30 ; SET ATTRIBUTES CALL BDOS LHLD FILECNT ; INCREMENT FILE COUNT INX H SHLD FILECNT POP H ; GET PTR TO DIRECTORY ENTRY ; PT TO NEXT ENTRY RENTEST: LXI D,ESIZE ; PT TO NEXT ENTRY DAD D POP B ; GET COUNT DCX B ; COUNT DOWN MOV A,B ; CHECK FOR ZERO ORA C JNZ RENLP ; RETURN TO CALLER RET ; ; PRINT CHARS PTED TO BY HL FOR B BYTES ; PRNT: MOV A,M ; GET CHAR CALL COUT INX H ; PT TO NEXT DCR B ; COUNT DOWN JNZ PRNT RET ; ; PRINT COUNT OF NUMBER OF FILES RENAMED ; PRCOUNT: CALL CRLF ; NEW LINE LHLD FILECNT ; GET COUNT MOV A,L ; CHECK FOR NONE ORA H JZ PRNO CALL PHLDC ; PRINT DECIMAL COUNT JMP PRMS PRNO: CALL PRINT DB 'No ',0 PRMS: LHLD FILECNT ; 1 FILE PROTECTED? MOV A,H ; HIGH ZERO? ORA A JNZ PRMULT MOV A,L ; LOW ONE? CPI 1 JZ PRSING PRMULT: CALL PRINT DB ' Files Renamed',0 RET PRSING: CALL PRINT DB ' File Renamed',0 RET ; ; BUFFERS ; INSPECT: DS 1 ; INSPECT FLAG (0=NO, 0FFH=YES) CONTROL: DS 1 ; CONTROL FLAG (0=NO, 0FFH=YES) SYSTEM: DS 1 ; SYSTEM FLAG (80H=NON-SYS, 0C0H=SYS/NON-SYS) NEXTCH: DS 2 ; PTR TO NEXT CHAR IN MULTIFILE COMMAND LINE FILECNT: DS 2 ; COUNT OF NUMBER OF FILES RENAMED RENFCB: DS 40 ; FCB FOR RENAME OFCB: DS 2 ; FCB FOR OLD FILE NAME AND OLD FILE TEMPLATE NTFCB: DS 2 ; FCB FOR NEW FILE TEMPLATE CMDLNE: DS 2 ; PTR TO COMMAND LINE BUFFER DIRBUF: DS 2 ; PTR TO DIRECTORY BUFFER STACK: DS 2 ; OLD STACK PTR END