|
|
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»