(*  VERSION 0025 *)

(* Copyright 1982 Digital Research, Inc. *)

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('SPP-86 3.0  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.
 

