PROGRAM MODHED C C LOGICAL*1 VOLNAM(12),PASSW(6),P(6),YN,IBYTE(512),IOS(4) LOGICAL*1 NUMRB(2),FNAME(18),FNAM(18) LOGICAL CHANGE INTEGER*4 NBL,ITOT,NBLIND EQUIVALENCE (NBL,IPARAM(5)),(IOS(1),IOSB(1)),(ITO(1),ITOT) EQUIVALENCE (VOLNAM(1),IBUF(8)),(IBUF(1),IBYTE(1)) EQUIVALENCE (NUMR,NUMRB(1)) DIMENSION IBUF(256),IPARAM(6),IOSB(2),ITO(2),IPARM(6) DATA P/'J','O','I','S','T','R'/ C WRITE(5,1) 1 FORMAT(/' *** WARNING *** THE PURPOSE OF THIS PROGRAM IS TO $ MODIFY FILE HEADERS.'/17X,'THIS IS A VERY DANGEROUS OPERATION AND $ THEREFORE...'/17X,'IF YOUR SYSTEM MANAGER THINKS YOU ARE CLEVER $ ENOUGH TO'/17X,'DO THIS, HE''LL GIVE YOU THE PASSWORD TO $ PROCEED.'/) C C C THE PROGRAM ASKS FOR A PASSWORD AND PERFORMS A QIO WITH C NO ECHO. TO LET THE CODING PROCEED AFTER THIS QIO, THE TASK C MUST BE NON-CHECKPOINTABLE AND FOR SOME REASON THE TASK C SHOULD DISABLE AST RECOGNITION. NOW WE CAN TEST FOR TIME-OUT. C C WRITE(5,2) 2 FORMAT(' *** PASSWORD?') CALL GETADR(IPARM(1),PASSW(1)) IPARM(2)=6 CALL DSASTR CALL DISCKP CALL MARK(2,10,2) CALL QIO("1020,5,1,,IOSB,IPARM) CALL WFLOR(1,2) CALL READEF(2,IDS) IF(IDS.EQ.2) GO TO 500 C C C IF WRONG PASSWORD, STOP C C DO 3 I=1,6 3 IF(PASSW(I).NE.P(I)-I) STOP 'WRONG PASSWORD' C C C ASK TO CONTINUE OR NOT C C WRITE(5,4) 4 FORMAT(/' *** LOGICAL UNIT NUMBER #1 IS USED FOR LOGICAL READ $/WRITE ON DM1:'/' *** IF YOU WANT TO CHANGE THIS, YOU HAVE TO $ INSTALL "MODHED" FIRST'/' *** AND THEN PERFORM A REASSIGNMENT. $ [E.G. REA MODHED 1 DM0:]'//'$*** CONTINUE? [Y/N]: ') READ(5,44) YN 44 FORMAT(A1) IF(YN.NE.'Y') GO TO 100 C C C TRY TO ATTACH DEVICE ON LUN #1 C IF IT FAILS... STOP C C CALL WTQIO("1400,1,1,,IOSB) IF(IOS(1).EQ.1) GO TO 10 WRITE(5,5) IOS 5 FORMAT(/' *** FATAL *** FAILED TO ATTACH DEVICE -- STATUS: ',4O5/) GO TO 100 C C C START PROCEDURE TO READ THE HOME BLOCK. C THE HOME BLOCK IS POSITIONED ON LOGICAL BLOCK #1 OR ON C LOGICAL BLOCK #MULTIPLE OF 256. C THE PROGRAM CHECKS THE VALIDITY OF THE HOME BLOCK ON ITS C TWO CHECKSUMS ON LOCATION 30 AND 256, AND ON ITS HAVING SET C AT LEAST 1 BIT. AFTER 200 TRIES (LOG.BL. #52100) THE PROGRAM C STOPS WITH ERROR. C C 10 CALL GETADR(IPARAM(1),IBUF(1)) IPARAM(2)=512 NBL=1 NHOM=0 11 CALL WTQIO("1000,1,1,,IOSB,IPARAM) IF(IOSB(1).EQ.1) GO TO 12 13 WRITE(5,15) IOS 15 FORMAT(/' *** FATAL *** READ ERROR -- STATUS: ',4O5/) GO TO 100 12 ITOT=0 DO 16 I=1,29 16 ITOT=ITOT+IBUF(I) IF(ITO(1).EQ.IBUF(30).AND.ITOT.NE.0) GO TO 17 NHOM=NHOM+1 IF(NHOM.GE.200) STOP 'HOME BLOCK READ ERROR' NBL=NHOM*256 GO TO 11 17 ITOT=0 DO 18 I=1,255 18 ITOT=ITOT+IBUF(I) IF(ITO(1).EQ.IBUF(256).AND.ITOT.NE.0) GO TO 19 NHOM=NHOM+1 IF(NHOM.GE.200) STOP 'HOME BLOCK READ ERROR' NBL=NHOM*256 GO TO 11 C C C START TRYING TO READ THE INDEX FILE HEADER. C ITS POSITION IS FOUND BY ADDING ITEMS 1 AND 3 OF THE HOME BLOCK. C IF THE FILE ID OF THE INDEX FILE HEADER .NE. 1,1.... STOP C C 19 NOFF=2+IBUF(1) MAXFIL=IBUF(4) WRITE(5,21) VOLNAM 21 FORMAT(/' ***** VOLUME LABEL: ',12A1,' *****'/) NBL=IBUF(1)+IBUF(3) NBLIND=NBL 23 NBL=NBLIND CALL WTQIO("1000,1,1,,IOSB,IPARAM) IF(IOSB(1).NE.1) GO TO 13 IF(IBUF(2).NE.1.OR.IBUF(3).NE.1) STOP 'INDEXFILE FILE-ID NOT 1,1' C C C ASK FOR THE FILE'S FILE ID. C IF THE NUMBER OF RETRIEVAL POINTERS IN THE INDEXFILE .GT. 102... C ... STOP. (NO MULTI HEADER FOR THE INDEXFILE SUPPORTED). C C WRITE(5,25) 25 FORMAT('$ENTER FILE ID [2O8,^Z =READY]: ') READ(5,30,END=100,ERR=23) IBL1,IBL2 30 FORMAT(2O8) IF(IBL1.LE.0.OR.IBL1.GT.MAXFIL) STOP 'FILE ID OUT OF RANGE' NRTRP=IBYTE(101) IF(NRTRP.GT.102) STOP 'TOO MANY RETRIEVAL POINTERS' IVBLN=2 IRTRP=6 IOF=112 C C C FIND THE CLUSTER IN WHICH THE FILE WANTED IS POSITIONED. C C 31 NUMRB(1)=IBYTE(IOF) IF(IBL1+3.LE.IVBLN+NUMR+1) GO TO 32 IF(IRTRP.GE.NRTRP.OR.IRTRP.GT.204) STOP 'EXCEEDED MAX NUMBER $ OF RETRIEVAL POINTERS' IRTRP=IRTRP+2 IVBLN=IVBLN+NUMR+1 IOF=IOF+4 GO TO 31 C C C NOW CALCULATE THE LOGICAL BLOCK NUMBER OF THE FILE HEADER WANTED C AND READ THIS BLOCK. C IF FILE ID .EQ. FILE ID IN THIS BLOCK (LOCATION 2,3)... THIS IS C THE FILE HEADER WANTED!!!!!! C C 32 IOF1=IOF/2+1 NBL=IBUF(IOF1)+NOFF+IBL1-IVBLN-1 CALL WTQIO("1000,1,1,,IOSB,IPARAM) IF(IOS(1).NE.1) GO TO 13 IF(IBL1.EQ.IBUF(2).AND.IBL2.EQ.IBUF(3)) GO TO 35 WRITE(5,33) IBUF(2),IBUF(3),IPARAM(5) 33 FORMAT(/' *** FATAL *** FILE ID MISMATCH [',O6,',',O6,']', $/15X,'LOGICAL BLOCK NUMBER [OCTAL]:',O7//) GO TO 23 C C C WRITE ON TERMINAL THE FILENAME AND THE CONTENTS OF THE HEADER. C C 35 FNAME(10)='.' FNAME(14)=';' CALL R50ASC(9,IBUF(24),FNAME(1)) CALL R50ASC(3,IBUF(27),FNAME(11)) ENCODE(3,37,FNAME(15)) IBUF(28) 37 FORMAT(I3) NF=0 DO 38 I=1,18 IF(FNAME(I).EQ.32) GO TO 38 NF=NF+1 FNAM(NF)=FNAME(I) 38 CONTINUE WRITE(5,36) (FNAM(I),I=1,NF) 36 FORMAT(/' ***** FILE HEADER OF FILE ',<NF>A1,' *****'//) WRITE(5,40) IBUF 40 FORMAT(32(1X,8O8/)) C C C ASK FOR ITEM TO CHANGE, PRINT THE CONTENTS AND ASK FOR NEW ONE. C THE CONTENTS WILL NOT CHANGE IF JUST A <CR> WAS ENTERED. C KEEP LOOPING UNTIL ALL CHANGES ARE MADE. C C CHANGE=.FALSE. 45 WRITE(5,50) 50 FORMAT('$ENTER ITEM TO CHANGE [DECIMAL,<CR>=READY]: ') READ(5,55) IT 55 FORMAT(I5) IF(IT.LE.0) GO TO 70 IF(IT.GT.256) GO TO 45 57 CALL CLOSE(5) CALL ASSIGN(5,'TI:') WRITE(5,60) IBUF(IT) 60 FORMAT('$CONTENTS OLD: ',O8,' NEW [OCTAL, <CR>=DON''T]: ') READ(5,65,END=57,ERR=57) NC,NEWIT 65 FORMAT(Q,O8) IF(NC.LE.0) GO TO 45 IBUF(IT)=NEWIT CHANGE=.TRUE. GO TO 45 C C C CALCULATE NEW CHECKSUM AND WRITE NEW FILE HEADER TO DISK. C IF NO CHANGES WERE MADE, DON'T WRITE. C IF ANY WRITE ERROR, SAY SO AND EXIT. C C 70 IF(.NOT.CHANGE) GO TO 23 ITOT=0 DO 80 I=1,255 80 ITOT=ITOT+IBUF(I) IBUF(256)=ITO(1) WRITE(5,85) IBUF(256) 85 FORMAT(/' ***** NEW CHECKSUM WILL BE: ',O6' *****'/) CALL WTQIO("400,1,1,,IOSB,IPARAM) IF(IOS(1).EQ.1) GO TO 23 WRITE(5,90) IOS 90 FORMAT(/' *** FATAL *** WRITE ERROR -- STATUS: ',4O5/) 100 STOP C C C HERE, IF NO PASSWORD WAS ENTERED WITHIN 10 SECONDS. C BECAUSE A READ FROM TERMINAL IS OUTSTANDING, A WRITE C HAS TO WAIT BEFORE ITS COMPLETION. THEREFORE, A QIO WITH C A FUNCTION CODE IO.KIL HAS TO BE SENT TO CLEAR THE TERMINAL C I/O QUEUE. AFTER THAT SOMETHING CAN BE WRITTEN TO THE TERMINAL C AGAIN. C C 500 CALL QIO("12,5) STOP 'TIME-OUT COUNT EXCEEDED' END