(* 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.