|
|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 13440 (0x3480)
Types: TextFile
Names: »RECREATE.BAS«
└─⟦57f0389e8⟧ Bits:30005761 SW1611 Access Manager v. 1.0
└─⟦this⟧ »RECREATE.BAS«
REM :::::::::::::::::::::::::::::::::::::::::::::::::::::::::
REM
REM RECREATE PROGRAM VERSION 1.02 03/03/83
REM ASSUMES AM86BUF IS AT LEAST 4844 BYTES
REM
REM :::::::::::::::::::::::::::::::::::::::::::::::::::::::::
%INCLUDE AM86EXTR.BAS
DIM DRN%(1),DEL.PTR%(1),NO.DEL%(1),UTL%(1)
YES% = 1 : NO% = 0 : CLEAR.LINE$ = " "
END.DATA.FILE% = 53
INVALID.RECORD% = 52
END.INDEX.FILE% = 23
CORRUPT.DATA% = 70
CORRUPT.INDEX% = 40
DELETE.FLAG$ = CHR$(255)
REM :::::::::::::::::::::::::::::::::::::::::::::::::::::::::
REM
REM RECREATE CAPACITIES
REM
REM :::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DIM INDEX.NAME$(9),KEY.LEN%(9,5),KEY.TYPE%(9),NO.KEY.PARTS%(9)
DIM AUTO.SUFFIX%(9),KEY.POS%(9,5),BLANK.KEY.TO.NULL$(9)
MAX.NO.KEY.PARTS% = 5
MAX.NO.KEYS% = 9
REM :::::::::::::::::::::::::::::::::::::::::::::::::::::::::
REM
REM LOCK VALUES
REM
REM :::::::::::::::::::::::::::::::::::::::::::::::::::::::::
NLOCK% = 0 REM NO LOCK REQUEST
XFILE% = 4 REM EXCLUSIVE FILE LOCK REQUEST
REM :::::::::::::::::::::::::::::::::::::::::::::::::::::::::
REM
REM RECREATE UTILITIES
REM
REM :::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DEF SPACE(FLDLEN)
STRING SPACE
INTEGER FLDLEN
REM 123456789012345678901234567890123456789012345678
SPACE = LEFT$(" ", Ø
FLDLEN)
RETURN
FEND
DEF ABANDON
PRINT "Rebuild Aborted!"
CLOSE 1
STOP
FEND
DEF EXTRACT.KEY(KEY%)
STRING EXTRACT.KEY,TEMP$
TEMP$ = ""
FOR PART% = 1 TO NO.KEY.PARTS%(KEY%)
TEMP$ = TEMP$ + MID$(INPBUF$,KEY.POS%(KEY%,PART%), Ø
KEY.LEN%(KEY%,PART%))
NEXT PART%
IF BLANK.KEY.TO.NULL$(KEY%) = "Y" AND TEMP$ = SPACE(LEN(TEMP$)) Ø
THEN EXTRACT.KEY = "" Ø
ELSE Ø
EXTRACT.KEY = TEMP$
RETURN
FEND
REM :::::::::::::::::::::::::::::::::::::::::::::::::::::::::
REM
REM PRE-INDEX SORT ROUTINES (buffer input / speed indexing)
REM
REM :::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DIM KEYVAL$(1500),DRN1%(1500),DRN2%(1500),LINK%(1500)
SORT.FLAG% = NO%
NO.SORT% = 0
MAX.SORT% = 1500
DEF ENTRY.ERROR(DR1%,DR2%)
PRINT " Error: #";ERRCOD;" (rec# ";DR1%;DR2%;")"
PRINT "during index rebuild."
DUMMY% = CLSDAT(FILE.NO%)
DUMMY% = ERAIDX(KEY.NO%)
CALL ABANDON
FEND
DEF SORT.SETUP(KEY%)
IF SORT.FLAG% = NO% THEN Ø
SORT.FLAG% = YES% Ø
ELSE Ø
FOR TEMP% = 1 TO NO.SORT% :Ø
KEYVAL$(TEMP%) = "" :Ø
NEXT TEMP%
IF FRE < 0 THEN Ø
SORT.FRE = FRE + 65536. Ø
ELSE Ø
SORT.FRE = FRE
IF MFRE < 0 THEN Ø
SORT.MFRE = MFRE + 65536. Ø
ELSE Ø
SORT.MFRE = MFRE
G.SORT = INT(SORT.MFRE / (KEY.LEN%(KEY%,0) + 4 ))
M.SORT = INT(SORT.FRE / (KEY.LEN%(KEY%,0) + 4 ))
NO.SORT% = (G.SORT + 3. * M.SORT) / 4.
IF NO.SORT% > MAX.SORT% THEN NO.SORT% = MAX.SORT%
RETURN
FEND
DEF SORT.KEYVAL(NO.READ%)
LINK%(0) = NO.READ%
LINK%(NO.READ%) = 0
IF NO.READ% < 2 THEN Ø
RETURN
FOR J% = NO.READ% - 1 TO 1 STEP -1
P% = LINK%(0)
Q% = 0
KEY.VALUE$ = KEYVAL$(J%)
L3:
IF KEY.VALUE$ <= KEYVAL$(P%) THEN GOTO L5
L4:
Q% = P%
P% = LINK%(Q%)
IF P% > 0 THEN GOTO L3
L5:
LINK%(Q%) = J%
LINK%(J%) = P%
NEXT J%
RETURN
FEND
DEF SORT.INDEX(KEY%,KEY.NO%,NO.READ%)
IF NO.READ% = 0 THEN RETURN
CALL SORT.KEYVAL(NO.READ%)
I% = LINK%(0)
INDEX.LOOP:
IF I% = 0 THEN RETURN
CALL SETDAT(DRN2%(I%))
RET.CODE% = ADDKEY(KEY.NO%,FILE.NO%,NLOCK%,KEYVAL$(I%),DRN1%(I%))
IF ERRCOD <> 0 THEN Ø
PRINT "Could not enter key value in ";INDEX.NAME$(KEY%); :Ø
CALL ENTRY.ERROR(DRN1%(I%),DRN2%(I%))
IF RET.CODE% <> 1 THEN Ø
PRINT "WARNING...ADDKEY Return Code: ";RET.CODE% :Ø
PRINT TAB(10);"while processing record # "; Ø
DRN1%(I%);DRN2%(I%);" for ";INDEX.NAME$(KEY%)
PRINT INDEX.NAME$(KEY%);DRN1%(I%);DRN2%(I%);CHR$(13);
I% = LINK%(I%)
GOTO INDEX.LOOP
FEND
DEF SORT.READ(KEY%,KEY.NO%)
DRN%(0) = BEG.REC%
DRN%(1) = 0
END.FILE% = NO%
PRINT CLEAR.LINE$;CHR$(13);
SORT.LOOP:
IF END.FILE% = YES% THEN Ø
PRINT :Ø
PRINT INDEX.NAME$(KEY%);" is rebuilt." :Ø
RETURN
NO.READ% = 0
DATA.LOOP:
CALL SETDAT(DRN%(1))
TEMP% = READAT(FILE.NO%,DRN%(0),INPBUF.PTR%)
IF TEMP% = END.DATA.FILE% OR TEMP% = INVALID.RECORD% THEN Ø
END.FILE% = YES% :Ø
GOTO BUILD.INDEX
IF TEMP% <> 0 THEN Ø
PRINT "Could not read ";FILE.NAME$; :Ø
CALL ENTRY.ERROR(DRN%(0),DRN%(1))
IF LEFT$(INPBUF$,1) = DELETE.FLAG$ THEN GOTO SKIP.RECORD
PRINT FILE.NAME$;DRN%(0);DRN%(1);CHR$(13);
NO.READ% = NO.READ% + 1
KEYVAL$(NO.READ%) = EXTRACT.KEY(KEY%)
DRN1%(NO.READ%) = DRN%(0)
DRN2%(NO.READ%) = DRN%(1)
SKIP.RECORD:
DRN%(0) = DRN%(0) + 1
IF DRN%(0) = 0 THEN Ø
DRN%(1) = DRN%(1) + 1
IF NO.READ% < NO.SORT% THEN Ø
GOTO DATA.LOOP
BUILD.INDEX:
PRINT CLEAR.LINE$;CHR$(13);
CALL SORT.INDEX(KEY%,KEY.NO%,NO.READ%)
GOTO SORT.LOOP
FEND
DEF CONV.INT(DRN)
REM
REM THIS VERSION IS LIMITED TO TWO-BYTE INTEGERS
REM
STRING CONV.INT
INTEGER DRN,MSB,LSB
MSB = INT%(DRN/256)
LSB = DRN - MSB * 256
IF LSB < 0 THEN MSB = MSB - 1
REM
REM NOTE THAT THE MSB AND LSB COULD BE COMBINED IN EITHER
REM ORDER. THE MOST IMPORTANT FACTOR IS TO ADOPT A CONVENTION
REM ON THE ORDER AND STICK WITH IT. (NUMERIC KEYS MUST HAVE LSB FIRST.)
REM
CONV.INT = CHR$(LSB) + CHR$(MSB)
RETURN
FEND
DEF INC.NO.DEL
NO.DEL%(0) = NO.DEL%(0) + 1
IF NO.DEL%(0) = 0 THEN Ø
NO.DEL%(1) = NO.DEL%(1) + 1
DEL.PTR%(0) = DRN%(0)
DEL.PTR%(1) = DRN%(1)
RETURN
FEND
DEF INC.DRN
DRN%(0)= DRN%(0) + 1
IF DRN%(0) = 0 THEN Ø
DRN%(1) = DRN%(1) + 1
RETURN
FEND
DEF WRITE.DELETE.LINK
LNKBUF$ = DELETE.FLAG$ + CONV.INT(DEL.PTR%(0)) + Ø
CONV.INT(DEL.PTR%(1)) + "DELETED"
LNKBUF.PTR% = SADD(LNKBUF$) + 2
CALL SETDAT(DRN%(1))
IF WRTDAT(FILE.NO%,DRN%(0),LNKBUF.PTR%) <> 0 THEN Ø
PRINT "Could not rewrite deleted record." :Ø
PRINT "Data file ";FILE.NAME$;" (";DRN%(0);DRN%(1);")." :Ø
CALL ABANDON
RETURN
FEND
DEF OUTHDR(LSW%,MSW%)
STRING TEMP
TEMP = CONV.INT(LSW%)
PUT 2,ASC(TEMP)
PUT 2,ASC(RIGHT$(TEMP,1))
TEMP = CONV.INT(MSW%)
PUT 2,ASC(TEMP)
PUT 2,ASC(RIGHT$(TEMP,1))
RETURN
FEND
DEF RECREATE.HEADER
OPEN FILE.NAME$ RECL 128 AS 2
REM
REM DRN% SET TO FILE SIZE
REM
DRN%(0) = DRN%(0) - 1
IF DRN%(0) = -1 THEN Ø
DRN%(1) = DRN%(1) - 1
REM
REM UTL% set to file utilzation
REM
IF NO.DEL%(0) < 0 THEN Ø
TEMP = NO.DEL%(0) + 65536. Ø
ELSE Ø
TEMP = NO.DEL%(0)
TEMP = TEMP + 65536. * NO.DEL%(1)
TEMP = TEMP + BEG.REC% - 1 REM ADJ FOR HEADER
TEMP = - TEMP
IF DRN%(0) < 0 THEN Ø
TEMP = TEMP + DRN%(0) + 65536. Ø
ELSE Ø
TEMP = TEMP + DRN%(0)
TEMP = TEMP + 65536. * DRN%(1) rem temp = size - unsued
IF TEMP < 0 THEN Ø
PRINT "Illegal value for file utilization:";TEMP :Ø
CLOSE 2 :Ø
CALL ABANDON
UTL%(1) = INT%(TEMP / 65536.)
UTL%(0) = TEMP - 65536. * UTL%(1)
REM
REM OUTPUT HEADER: DELPTR,UTL,SIZE,INTEGRITY FLAG
REM
CALL OUTHDR(DEL.PTR%(0),DEL.PTR%(1))
CALL OUTHDR(UTL%(0),UTL%(1))
CALL OUTHDR(DRN%(0),DRN%(1))
PUT 2,0
FOR TEMP% = 1 TO 115
PUT 2,32 REM FILL HEADER WITH SPACES
NEXT TEMP%
CLOSE 2
RETURN
FEND
DEF REBUILD.DATA
INTEGER REBUILD.DATA
REM
REM REBUILD.DATA RETURN VALUES
REM 0 - data file uncorrupted, no action needed
REM 1 - data file corrupted, was rebuilt
REM 2 - could not get exclusive lock, no action taken
REM 3 - no header record / apparently empty data file, no action
REM < 0 - unresolved error on open (ERRCOD = - return value),
REM no action taken
REM
STATUS% = 0
FILE.NO% = OPNDAT(-1,XFILE%,FILE.NAME$,REC.LEN%)
IF ERRCOD = END.DATA.FILE% THEN Ø
REBUILD.DATA% = 3 :Ø
DUMMY% = CLSDAT(FILE.NO%) :Ø
RETURN
IF ERRCOD = CORRUPT.DATA% THEN Ø
STATUS% = 1 :Ø
FILE.NO% = OPRDAT(-1,XFILE%,FILE.NAME$,REC.LEN%)
IF STATUS% = 0 AND ERRCOD <> 0 THEN Ø
REBUILD.DATA = -ERRCOD :Ø
DUMMY% = CLSDAT(FILE.NO%) :Ø
RETURN
IF LOKCOD <> 0 THEN Ø
REBUILD.DATA = 2 :Ø
DUMMY% = CLSDAT(FILE.NO%) :Ø
RETURN
IF BEG.REC% = 0 THEN Ø
BEG.REC% = INT%((128 + REC.LEN% - 1) / REC.LEN%) + 1
TMPBUF$ = "0123456789abcdef0123456789abcdef"
INPBUF$ = ""
NO.SEG% = INT% ((REC.LEN% + 31) / 32)
FOR TEMP% = 1 TO NO.SEG%
INPBUF$ = INPBUF$ + TMPBUF$
NEXT TEMP%
INPBUF.PTR% = SADD(INPBUF$) + 2
IF STATUS% = 0 THEN Ø
REBUILD.DATA = STATUS% :Ø
PRINT "No need to modify ";FILE.NAME$ :Ø
DUMMY% = CLSDAT(FILE.NO%) :Ø
RETURN
REM
REM CORRUPTED FILE. MUST RECREATE DELETED LINKS AND HEADER RECORD
REM
PRINT "Rebuilding data file ";FILE.NAME$
PRINT
DRN%(0) = BEG.REC%
DRN%(1) = 0
DEL.PTR%(0) = 0
DEL.PTR%(1) = 0
NO.DEL%(0) = 0
NO.DEL%(1) = 0
READ.LOOP:
CALL SETDAT(DRN%(1))
IF READAT(FILE.NO%,DRN%(0),INPBUF.PTR%) = END.DATA.FILE% THEN Ø
GOTO END.OF.FILE
IF ERRCOD <> 0 THEN Ø
REBUILD.DATA = -ERRCOD :Ø
DUMMY% = CLSDAT(FILE.NO%) :Ø
RETURN
PRINT FILE.NAME$;DRN%(0);DRN%(1);CHR$(13);
IF LEFT$(INPBUF$,1) = DELETE.FLAG$ THEN Ø
CALL WRITE.DELETE.LINK :Ø
CALL INC.NO.DEL
CALL INC.DRN
GOTO READ.LOOP
END.OF.FILE:
PRINT
PRINT FILE.NAME$;" is reorganized. Now rebuild index files."
IF CLSDAT(FILE.NO%) <> 0 THEN Ø
PRINT "Could not close data file (to recreate header)"; Ø
FILE.NAME$ :Ø
CALL ABANDON
CALL RECREATE.HEADER
REBUILD.DATA = 1
RETURN
FEND
DEF REBUILD.INDICES(REDO.DATA%)
IF NO.KEYS% < 1 THEN RETURN
FILE.NO% = OPNDAT(-1,XFILE%,FILE.NAME$,REC.LEN%)
IF ERRCOD <> 0 OR LOKCOD <> 0 THEN Ø
PRINT "Could not attempt index rebuild." :Ø
PRINT "Error/Lock Codes...";ERRCOD,LOKCOD :Ø
DUMMY% = CLSDAT(FILE.NO%) :Ø
RETURN
FOR KEY% = 1 TO NO.KEYS%
KEY.NO% = OPNIDX(-1,INDEX.NAME$(KEY%),KEY.LEN%(KEY%,0), Ø
KEY.TYPE%(KEY%),AUTO.SUFFIX%(KEY%))
IF ERRCOD = 0 AND REDO.DATA% = 0 THEN Ø
TEMP% = NOKEYS(KEY.NO%) :Ø
IF TEMP% <> 0 OR DATVAL <> 0 THEN Ø
PRINT INDEX.NAME$(KEY%);" is OK as is."; Ø
" No rebuild performed." :Ø
GOTO SKIP.INDEX
IF ERRCOD <> 0 AND ERRCOD <> CORRUPT.INDEX% AND Ø
ERRCOD <> END.INDEX.FILE% THEN Ø
PRINT "Unanticipated Error with "; :Ø
GOTO KEY.ERROR
IF ERRCOD = CORRUPT.INDEX% THEN Ø
KEY.NO% = OPRIDX(-1,INDEX.NAME$(KEY%), Ø
KEY.LEN%(KEY%,0),KEY.TYPE%(KEY%),AUTO.SUFFIX%(KEY%))
IF ERAIDX(KEY.NO%) <> 0 THEN Ø
PRINT "Could not erase old "; :Ø
GOTO KEY.ERROR
KEY.NO% = OPNIDX(-1,INDEX.NAME$(KEY%),KEY.LEN%(KEY%,0), Ø
KEY.TYPE%(KEY%),AUTO.SUFFIX%(KEY%))
IF ERRCOD <> 0 THEN Ø
PRINT "Could not re-open "; :Ø
GOTO KEY.ERROR
CALL SORT.SETUP(KEY%)
CALL SORT.READ(KEY%,KEY.NO%)
SKIP.INDEX:
DUMMY% = CLSIDX(KEY.NO%)
NEXT KEY%
DUMMY% = CLSDAT(FILE.NO%)
RETURN
KEY.ERROR:
PRINT INDEX.NAME$(KEY%);" Error: #";ERRCOD
PRINT "Index not rebuilt."
GOTO SKIP.INDEX
FEND
DEF REBUILD
READ #1;FILE.NAME$,REC.LEN%,NO.KEYS%,BEG.REC%
IF NO.KEYS% > MAX.NO.KEYS% THEN Ø
PRINT "Error in ";REC.PAR;" for data file ";FILE.NAME$ :Ø
PRINT "More than ";MAX.NO.KEYS%;" key files requested.":Ø
CLOSE 1 :Ø
STOP
IF NO.KEYS% <= 0 THEN GOTO SKIP.KEY.DESCRIPTION
FOR KEY% = 1 TO NO.KEYS%
READ #1;INDEX.NAME$(KEY%),KEY.LEN%(KEY%,0), Ø
KEY.TYPE%(KEY%),AUTO.SUFFIX%(KEY%), Ø
NO.KEY.PARTS%(KEY%),BLANK.KEY.TO.NULL$(KEY%)
BLANK.KEY.TO.NULL$(KEY%) = UCASE$(BLANK.KEY.TO.NULL$(KEY%))
IF NO.KEY.PARTS%(KEY%) < 1 OR NO.KEY.PARTS%(KEY%) > Ø
MAX.NO.KEY.PARTS% THEN GOTO KEY.ERROR
FOR PART% = 1 TO NO.KEY.PARTS%(KEY%)
READ #1;KEY.POS%(KEY%,PART%),KEY.LEN%(KEY%,PART%)
NEXT PART%
NEXT KEY%
SKIP.KEY.DESCRIPTION:
REDO.DATA% = REBUILD.DATA
IF REDO.DATA% = 2 THEN Ø
PRINT "Data file ";FILE.NAME;" could not be locked."
IF REDO.DATA% = 3 THEN Ø
PRINT "Data file ";FILE.NAME$;" apparently empty."
IF REDO.DATA% < 0 THEN Ø
PRINT "Unanticipated AM86 Error #";-REDO.DATA%; Ø
" while processing ";FILE.NAME$
IF REDO.DATA% < 0 OR REDO.DATA% > 1 THEN Ø
PRINT "No rebuild performed." :Ø
RETURN
CALL REBUILD.INDICES(REDO.DATA%)
PRINT
PRINT "Rebuild for ";FILE.NAME$;" completed."
RETURN
KEY.ERROR:
PRINT "Error in ";REC.PAR$;" for data file ";FILE.NAME$; Ø
" with key file ";INDEX.NAME$(KEY%)
PRINT "Number of key parts must satisfy -"
PRINT
PRINT TAB(10);"1 <= # PARTS <= ";MAX.NO.KEY.PARTS%
PRINT
CLOSE 1
STOP
FEND
REM +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
INPUT "Enter recreate parameter file name:";REC.PAR$
OPEN REC.PAR$ AS 1
READ #1;NO.DATA.FILES%,NODE.SECTORS%
TERMINAL% = INTUSR(-1,YES%,2)
IF ERRCOD <> 0 THEN Ø
PRINT "Could not initialize user." :Ø
STOP
BUFFER.SPACE% = 4844 - 70 - 198 REM assumes that only one key file and one
REM data file will be open at the same time.
NO.BUFFERS% = INT%(BUFFER.SPACE% / (NODE.SECTORS% * 128 + 60))
IF NO.BUFFERS% > 254 THEN NO.BUFFERS% = 254
IF SETUP(NO.BUFFERS%,1,NODE.SECTORS%,1) <> 0 THEN Ø
PRINT "Illegal SETUP parameters." :Ø
CALL ABANDON
FOR DFILE% = 1 TO NO.DATA.FILES%
CALL REBUILD
PRINT
NEXT DFILE%
PRINT
PRINT "Normal Termination."
CLOSE 1
STOP
«eof»