|
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: 4352 (0x1100) Types: TextFile Names: »BACKUP.SRC«
└─⟦295c4021d⟧ Bits:30008920 MT+ SPP 3/3 └─⟦this⟧ »BACKUP.SRC«
(* VERSION 0024 *) PROGRAM BACK_IT_UP; (* THIS PROGRAM WILL READ THE LOG.DAT AND LOG.IDX FILES AND *) (* CREATE FILECOPY.SUB. THE LOG.DAT FILE WILL BE MARKED WITH *) (* A RECORD CONTAINING DASHES TO SIGNAL THAT ALL FILES PREVIOUS *) (* TO THAT RECORD HAVE BEEN BACKED UP (IF YOU RUN THE SUBMIT) *) TYPE LOGENTRY = PACKED ARRAY Æ0..31Å OF CHAR; LOGREC = PACKED ARRAY Æ0..3Å OF LOGENTRY; NAMESTR = STRINGÆ16Å; NAMEREC = RECORD S : NAMESTR; NXT : ^NAMEREC END; VAR INFILE : FILE; LOGINDX: FILE OF INTEGER; OUTFILE: TEXT; REC : LOGREC; REC2 : LOGENTRY; (* USED FOR PUTREC *) IOR : INTEGER; I : INTEGER; S : STRING; INDEX : INTEGER; LIST : ^NAMEREC; (* SO WE CAN ELIMINATE DUPLICATES *) DATE : STRING; PROCEDURE INITIALIZE; BEGIN ASSIGN(INFILE,'LOG.DAT'); ASSIGN(LOGINDX,'LOG.IDX'); ASSIGN(OUTFILE,'FILECOPY.SUB'); RESET(INFILE); RESET(LOGINDX); REWRITE(OUTFILE); LIST := NIL; WRITE('Enter today''s date: '); READLN(DATE) END; PROCEDURE ADD_2_LIST(S:STRING); VAR LP : ^NAMEREC; BEGIN LP := LIST; WHILE LP <> NIL DO BEGIN IF LP^.S = S THEN EXIT; LP := LP^.NXT END; NEW(LP); LP^.S := S; LP^.NXT := LIST; LIST := LP END; PROCEDURE EXTRACT(VAR S:STRING; INDEX:INTEGER); VAR S1 : STRINGÆ32Å; BEGIN GETREC(INDEX); MOVE(RECÆINDEX MOD 4Å,S1,32); (* COPY THE DATA INTO THE STRING *) S1Æ0Å := CHR(POS(' ',S1)-1); (* SET THE LENGTH BYTE *) S := S1 END; PROCEDURE GETREC(INDX:INTEGER); BEGIN BLOCKREAD(INFILE,REC,IOR,128,INDX DIV 4) END; PROCEDURE PUTREC(INDX:INTEGER); BEGIN GETREC(INDX); MOVE(REC2,RECÆINDX MOD 4Å,32); BLOCKWRITE(INFILE,REC,IOR,128,INDX DIV 4) END; PROCEDURE FIND_LAST_BACKUP(VAR STARTINGPOINT : INTEGER); VAR I : INTEGER; BEGIN FOR I := LOGINDX^-1 DOWNTO 0 DO (* WORK BACKWARDS *) BEGIN GETREC(I); IF RECÆI MOD 4,28Å = '-' THEN (* THIS IS IT! *) BEGIN STARTINGPOINT := I + 1; EXIT END END; (* IF WE GET HERE THEN EITHER EMPTY FILE OR NO PREVIOUS BACKUPS *) STARTINGPOINT := 0 END; PROCEDURE DELETE_FIRST_BATCH; VAR I,J,K,L,M : INTEGER; BEGIN RESET(LOGINDX); (* RE OPEN THIS FILE *) I := 0; WHILE I < LOGINDX^ DO BEGIN GETREC(I); IF RECÆI MOD 4,29Å='-' THEN (* RECORD FOUND *) BEGIN IF I = LOGINDX^-1 THEN EXIT; (* NO PREVIOUS DATA TO DELETE *) J := LOGINDX^ - I -1 ; K := LOGINDX^; (* SAVE THE CURRENT VALUE *) REWRITE(LOGINDX); LOGINDX^ := J; PUT(LOGINDX); CLOSE(LOGINDX,IOR); (* NOW SHUFFLE TO THE LEFT *) M := 0; FOR L := I+1 TO K DO BEGIN GETREC(L); MOVE(RECÆL MOD 4Å,REC2,32); PUTREC(M); M := M + 1 END; FILLCHAR(REC2,32,CHR($1A)); PUTREC(M); EXIT END; I := I + 1 END END; BEGIN WRITELN('Pascal/MT+ ?? Backup program'); INITIALIZE; FIND_LAST_BACKUP(INDEX); (* NOW BUILD THE LIST *) FOR I := INDEX TO LOGINDX^-1 DO BEGIN EXTRACT(S,I); ADD_2_LIST(S); (* ADD TO LIST IF NOT ALREADY THERE *) END; WHILE LIST <> NIL DO BEGIN WRITELN(OUTFILE,'PIP B:=',LIST^.S); LIST := LIST^.NXT END; CLOSE(OUTFILE,IOR); I := LOGINDX^; REWRITE(LOGINDX); BLOCKREAD(INFILE,REC,IOR,128,I DIV 4); FILLCHAR(RECÆI MOD 4Å,30,'-'); MOVE(DATEÆ1Å,RECÆI MOD 4Å,LENGTH(DATE)); RECÆ(I MOD 4),30Å := CHR(13); RECÆ(I MOD 4),31Å := CHR(10); (* ADD CR/LF AT END *) IF (I+1) MOD 4 <> 0 THEN FILLCHAR(RECÆ(I+1) MOD 4Å,32,CHR($1A)); (* ADD EOF'S IF NECESSARY *) BLOCKWRITE(INFILE,REC,IOR,128,I DIV 4); LOGINDX^ := I + 1; PUT(LOGINDX); CLOSE(LOGINDX,IOR); DELETE_FIRST_BATCH; (* NOW GO AND DELETE FIRST BATCH OF RECORDS *) CLOSE(INFILE,IOR); END. «eof»