! This version differs from the standard only in its treatment of a 'full
! tape' condition - it stops rather than reuse an old tape.
!FILE LAST CHANGED ON 11/02/83
! *******************************************************************
! * *
! * THE JOURNAL SYSTEM: PACKAGE A. *
! * THIS PACKAGE IS THE MANAGEMENT SECTION OF THE EMAS 2900 *
! * JOURNAL SYSTEM. *
! * *
! * DESIGNED AND WRITTEN BY JOHN HENSHALL *
! * *
! * JOHN MURISON VERSION: 015 *
! * *
! * *
! *******************************************************************
constinteger kent = 0, ercc = 1
constinteger journalsite = kent
!********** SYSTEM ROUTINE SPECS
recordformat rf(integer conad, filetype, datastart, dataend)
systemroutinespec connect(string (31) file, integer mode, hole,
project, record (rf)name r, integername flag)
systemroutinespec destroy(string (31) s, integername flag)
systemroutinespec disconnect( string (31) file, integername flag)
systemroutinespec move(integer l, f, t)
systemroutinespec outfile(string (31) s, integer size, hole,
protection, integername conad, flag)
systemroutinespec oper(integer operno, string (255) s)
systemroutinespec sdisconnect(string (31) file c
integer fsys, integername flag)
!**********EXTERNAL ROUTINE SPECS.
externalroutinespec cherish(string (255) s)
externalroutinespec copy(string (255) s)
externalroutinespec define(string (255) s)
recordformat f rep b(integer dest, srce, byteinteger flag,
string (6) file, string (15) output q)
externalroutinespec dpoff(record (f rep b)name p)
recordformat f parm(integer dest, srce, p1, p2, p3, p4, p5, p6)
externalintegerfnspec exist(string (31) file)
externalintegerfnspec dspool(record (f parm)name p, integer len, adr)
externalroutinespec newpdfile(string (255) s)
externalroutinespec journal analysis(string (255) s)
externalroutinespec prompt(string (255) s)
externalroutinespec rename(string (255) s)
externalroutinespec readmag(integer chnl, addr, integername len, flag)
externalroutinespec write tmmag(integer chnl, integername flag)
externalroutinespec unload mag(integer chnl)
externalroutinespec open mag(integer chnl, string (7) tsn)
externalroutinespec write mag(integer chnl, addr, len, integername c
flag)
externalroutinespec skip mag(integer chnl, blocks)
externalroutinespec skip tm mag(integer chnl, marks)
externalroutinespec f skip tm mag(integer chnl, marks,
integername flag)
externalstringfnspec date
externalroutinespec send(string (255) s)
externalstringfnspec time
!**********ROUTINE AND FUNCTION SPECS.
routinespec identify index(string (*)name keyword, byteintegername c
id char, data type, integername entry)
routinespec line to atoms(integername word count,
stringarrayname atom, byteintegerarrayname buff)
routinespec master file failure(string (*)name file, integer flag)
routinespec journal(string (255) s)
routinespec new journal index(string (255) s)
routinespec new journal tape(string (255) s)
externalroutinespec journal backpass(string (255) s)
externalroutinespec create jfile(string (11) name, integer cells, cellsize,
headersize, integername conad, flag)
externalroutinespec read prompt reply(string (*)name reply)
externalintegerfnspec s to i(string (*)name s)
externalintegerfnspec cyclic(integer from, direction)
externalstringfnspec intostr(integer value)
systemintegerfnspec pack date and time(string (8) date, time)
systemintegerfnspec dt word(integer old form)
externalintegerfnspec minutes between(integer from,to)
systemstringfnspec unpack date(integer packed)
systemstringfnspec unpack time(integer packed)
systemintegerfnspec current packed dt
externalintegerfnspec uinfi(integer entry)
!**********RECORD FORMATS
recordformat f chapter header(string (6) tape name, user name,
string (15) file name, string (8) date, time, type,
byteinteger spare0, spare1, spare2, integer chapter, epages,
fsys, perms)
recordformat f index entry(integer file id, starting, finishing,
chapter, string (6) tape, byteinteger status) {24 bytes}
recordformat f index list(byteinteger id char,
data type, string (12) identity) {15 bytes}
recordformat f parameters(string (4) lower file, upper file,
string (12) keyword, analysis)
recordformat f queue(string (15) name,
halfintegerarray streams(0:15),
string (7) default user,
string (31) default delivery,
integer default start, default priority, default time,
default outlim, default forms, default mode, default copies,
default rerun, length, head, max length, maxacr, q by, spare,
amount)
recordformat f tape cycle(string (6) tsn, integer age)
!**********CONSTANT ARRAYS.
conststring (3) array ocptimereq(0:16)= c
"600", "600", "600", "420", "300", "300", "300", "600", "600", "600", "600",
"600", "600", "600", "600", "600", "600"
conststring (60) array journal status(0:4)= c
"Failure occurred at undefined point!!",
"Failure occurred during file collection from Spooler",
"Last run opted out of tape dump",
"Failure occurred whilst dumping files to tape",
"Next run is clear to rerun tape dump"
conststring (9) array system keyword(0:9)= c
"MAINLOG", "VOLUMS", "SPOOLR", "ACCOUNTS", "DIRECT", "BACK&ARCH",
"UPDATES", "MAILER", "SPARE3", "SPARE4"
!THE SYSTEM INDICES RECOGNITION KEYWORDS.
!**********CONSTANTS.
constinteger block = 4096
!BYTES IN EPAGE.
constinteger index top = 9999
!THE PHYSICAL TOP OF AN INDEX.
constinteger system indices = 9
constinteger used system indices = 7
constinteger nsys = 99
!THE MAXIMUM NUMBER OF FILE SYSTEMS ON EMAS.
!THE TOTAL NUMBER OF SYSTEM INDICES.
constinteger total indices = 99
!MAXIMUM NUMBER OF INDICES ON THE SYSTEM.
conststring (9) jtxt="Journal: "
ownstring (8) control="JJMASTER"
!THE IDENTITY OF THE SYSTEM CONTROL FILE.
conststring (8) pdstore="JJ#PD"
!THE JOURNAL SYSTEM STORAGE FILE.
conststring (6) spool="SPOOLR"
conststring (6) me = "JOURNL"
conststring (8) prime start time="09.30.00"
conststring (8) prime end time="17.00.00"
!THESE PRIME TIMES DECIDE WHEN RESTRICTED TRIGGERING(TEST C)
!OF THE JOURNAL HOUSEKEEPING IS IN FORCE.
constinteger yes = 1
constinteger no = 0
conststring (1) snl="
"
externalinteger chpointer
externalinteger flen
externalinteger endflag
!THESE LAST THREE INTEGERS ARE CONNECTED WITH THE 'ATOM'
!READING FUNCTIONS.
!**********EXTERNAL ROUTINE LIST
! THE FOLLOWING EXTERNAL ROUTINES EXIST IN THIS MODULE AND ARE IN
! ALPHABETIC ORDER OF APPEARANCE:
! ABORT JOURNAL FILES: THIS IS USED WHEN THERE HAS BEEN AN ABNORMAL NUMBER
! OF FILES QUEUED FOR JOURNL IN SPOOLR SUCH THAT JOURNAL'S INDEX FILLS
! WHEN IT TRIES TO TAKE THEM OFF SPOOLR. USING THIS COMMAND WE DESTROY
! ALL THE FILES TAKEN FROM SPOOLR WAITING TO BE INDEXED IN THE JOURNAL
! SYSTEM AND HENCE CLEARING THE JOURNL PROCESS DOWN.
! THIS WILL MEAN THAT THE FILES WILL BE LOST FOR GOOD BUT THE FILES WILL
! PROBABLY BE RUBBISH PRODUCED FROM MONITORING IN THE FIRST PLACE
! AND HENCE DISCARDABLE.
! ABORT JOURNAL TAPE: USED WHEN A TAPE HAS BEEN COMPLETELY SCREWED
! AND WE WANT TO USE ANOTHER AND CLEAR DOWN THE INDEX ENTRIES FOR
! THE FILES ON THIS TAPE(SINCE THEY ARE EFFECTIVELY LOST). THIS CAN
! BE USED FOR EITHER THE CURRENT MASTER TAPE OR FOR ANY OTHER TAPE
! THAT MAY BE LOST? ETC.
! CREATE JOURNAL SYSTEM: THIS ROUTINE INITIALISES THE JOURNAL SYSTEM
! AND CAN ONLY BE RUN WHEN THE SYSTEM CONTROL FILE DOES NOT EXIST.
! THE FILE 'JJMASTER' IS CREATED BY THIS ROUTINE
! TOGETHER WITH ALL THE "SYSTEM FILE" INDICES DEFINED IN THE ABOVE
! CONSTARRAY 'SYSTEM KEYWORD'.
! JOURNAL: THIS IS THE MAIN CONTROL ROUTINE OF THE JOURNAL SYSTEM.
! IT IS RUN AT LEAST ONCE EVERY 24 HOURS AND IS RESPONSIBLE FOR THE
! COLLECTING, PARTITIONING, DUMPING TO TAPE OF ALL JOURNAL AND DONOR
! FILES. IT ALSO PRODUCES THE AUTOMATIC ANALYSES SUCH AS THE ERROR
! LOG COMPONENTS.
! IF IT IS OBVIOUS THAT A FILE IS CAUSING REPEATED CRASHES
! THEN THE SYSTEM MANAGER CAN USE THE PARAMETER "KILLFILE" WHICH
! WILL RESULT IN THE FILE LOGGED AS BEING THE LAST FAILING FILE
! IN THE MASTER CONTROL FILE WILL BE REMOVED FROM SPOOLER QUEUE.
! THE SYSTEM CAN BE RUN WITHOUT THE TAPE DUMP BY GIVING THE
! PARAMETER "TAPESKIP" AND WITHOUT AUTO ANALYSIS USING "ANALSKIP"
! JOURNAL STATE:THIS ROUTINE WILL GIVE A SUMMARY OF THE CURRENT STATE
! OF THE JOURNAL SYSTEM INCLUDING DETAILS OF ALL INDICES IN USE,
! DETAILS OF THE TAPE CYCLE AND THE CURRENT MASTER TAPE ETC.
! LIST JOURNAL INDEX: THIS ROUTINE WILL DUMP A FULL LIST OF THE
! CONTENTS OF AN INDEX INTO THE FILE "JLIST". JLIST CAN
! THEN BE LISTED OR VIEWED BY THE USER.
! NEW JOURNAL INDEX: THIS ROUTINE WILL CREATE A NEW INDEX (UNLESS
! IT ALREADY EXISTS) FOR THE KEYWORD SPECIFIED BY THE REPLY
! TO THE GIVEN PROMPT. EACH INDEX IS 90 PAGES LONG AND CAN HOLD A
! MAXIMUM OF 10, 000 ENTRIES. AN ENTRY(BY ROUTINE "CREATE JOURNAL
! SYSTEM" ONLY) WITH PARAMETER "SYSTEM" WILL CREATE ALL THE "SYSTEM"
! INDICES AND IF IT FAILS AT ALL WILL DESTROY ALL THE SYSTEM FILES
! ALREADY CREATED, INCLUDING JJMASTER, FOR A CLEAN RETRY.
! THE FIRST 10 INDICES ARE RESERVED FOR SYSTEM INDICES, THE
! REMAINDER BEING AVAILABLE TO THE INSTALLATION.
! NEW JOURNAL TAPE: THIS IS USED WHEN A NEW TAPE IS TO BE ADDED TO
! THE JOURNAL TAPE CYCLE. THE TAPE WILL BE REJECTED IF IT IS ALREADY
! IN THE CYCLE OTHERWISE AN ACCEPTANCE MESSAGE WILL BE GIVEN
! TOGETHER WITH A COUNT OF THE TAPES IN THE CYCLE.
! REMOVE JOURNAL INDEX: THIS ROUTINE IS USED TO DESTROY AN INDEX AND
! IN DOING SO REMOVING ALL ACCESS TO THE FILES STORED UNDER THAT
! INDEX.
! ************************************************************************
! ************************************************************************
! ************************************************************************
externalroutine abort journal files(string (255) s)
integer flag
destroy(pdstore, flag)
if flag#0 start
printstring(jtxt."Cannot destroy partition ".pdstore.", flag: ")
write(flag, 3); newline
finish else start
printstring(jtxt."All pending files destroyed")
newline
finish
newpdfile(pdstore)
cherish(pdstore)
end ; !OF ABORT JOURNAL FILES
! ***************************************************************
! ***************************************************************
! ***************************************************************
externalroutine abort journal tape(string (255) s)
record (f tape cycle)arrayformat af tape cycle(1:100)
record (f index list)arrayformat af index list(0:total indices)
record (f index entry)arrayformat af index entry(0:index top)
record (rf)r
integername master entry, total chapters, total epages, tape count
record (f tape cycle)arrayname tape cycle
record (f index list)arrayname index list
record (f index entry)arrayname index entry
integer i, j, k, files lost, flag, new master, max
string (15) ss, index
string (6) tsn
byteinteger id
connect(control, 3, 0, 0, r, flag)
if flag#0 then master file failure(control, flag)
master entry==integer(r_conad+x'708')
total epages==integer(r_conad+x'714')
total chapters==integer(r_conad+x'710')
tape cycle==array(r_conad+x'720', af tape cycle)
tape count==integer(r_conad+x'700')
index list==array(r_conad+x'30', af index list)
cycle
prompt("JOURNAL TAPE:")
read prompt reply(ss)
exit if length(ss)=6
printstring("??"); newline
repeat
for k=1, 1, tape count cycle
exit if tape cycle(k)_tsn=ss
if k=tape count start
printstring(ss." not a Journal cycle tape!")
newline
return
finish
repeat
files lost=0; !COUNT OF FILES ON THE BAD TAPE.
for i=0, 1, total indices cycle
if index list(i)_identity#"" start
id=index list(i)_id char
index="JJ#".intostr(id)."DEX"
connect(index, 3, 0, 0, r, flag)
if flag#0 then master file failure(index, flag)
index entry==array(r_conad+x'40', af index entry)
for j=0, 1, index top cycle
if index entry(j)_tape=ss start
if 1<=index entry(j)_status<9 then index entry(j)_status=9 c
and files lost=files lost+1
finish
repeat
disconnect(index, flag)
finish
repeat
printstring("There were ".intostr(files lost)." files on the tape.")
newline
unless k=master entry start
printstring("Bad tape marked unused, please replace with")
printstring(" a new tape with the same label.")
newline
tape cycle(k)_age=0
disconnect(control, flag)
printstring("Abort succeeds."); newline
return
finish
!OTHERWISE WE KNOW THE TAPE WAS THE MASTER TAPE.
new master=-1
for i=1, 1, tape count cycle
if tape cycle(i)_age=0 then new master=i and exit
repeat
if new master=-1 start
!WE MUST USE A FULL TAPE(THE OLDEST.)
max=10000
for i=1, 1, tape count cycle
if tape cycle(i)_age<max and tape cycle(i)_age#-1 start
max=tape cycle(i)_age
new master=i
finish
repeat
tsn=tape cycle(new master)_tsn
printstring("Reusing ".tsn." as replacement master tape")
newline
for i=0, 1, total indices cycle
if index list(i)_identity#"" start
id=index list(i)_id char
index="JJ#".intostr(id)."DEX"
connect(index, 3, 0, 0, r, flag)
if flag#0 then master file failure(index, flag)
index entry==array(r_conad+x'40', af index entry)
for j=0, 1, index top cycle
if index entry(j)_tape=tsn start
if index entry(j)_status>1 start
index entry(j)_status=9
integer(r_conad+x'2C')=j
finish
finish
repeat
disconnect(index, flag)
finish
repeat
finish else start
printstring("New master tape ".tape cycle(new master)_tsn)
newline
finish
printstring("Bad tape marked unused, please replace with a new tape")
newline
printstring("with the same label."); newline
tape cycle(k)_age=0
tape cycle(new master)_age=-1
master entry=newmaster
total chapters=0
total epages=0
disconnect(control, flag)
printstring("Abort succeeds."); newline
return
end ; !OF ABORT JOURNAL TAPE
! *******************************************************************
! *******************************************************************
! *******************************************************************
externalroutine abort main analysis(string (255) s)
record (rf)r; integer flag
connect("JJ#0DEX", 3, 0, 0, r, flag)
if flag#0 start
printstring(jtxt."Problems..cannot connect Mainlog index, ")
printstring("flag:".intostr(flag))
newline
return
finish
integer(r_conad+x'28')=integer(r_conad+x'20')
printstring(jtxt."Current analysis aborted.")
newline
end
! *******************************************************************
! *******************************************************************
! *******************************************************************
externalroutine abort volums analysis(string (255) s)
record (rf)r; integer flag
connect("JJ#1DEX", 3, 0, 0, r, flag)
if flag#0 start
printstring(jtxt."Problems..cannot connect Volums log index, ")
printstring("flag:".intostr(flag))
newline
return
finish
integer(r_conad+x'28')=integer(r_conad+x'20')
printstring(jtxt."Current analysis aborted.")
newline
end
! *******************************************************************
! *******************************************************************
! *******************************************************************
externalroutine abort spoolr analysis(string (255) s)
record (rf)r; integer flag
connect("JJ#2DEX", 3, 0, 0, r, flag)
if flag#0 start
printstring(jtxt."Problems..cannot connect Spoolr log index, ")
printstring("flag:".intostr(flag))
newline
return
finish
integer(r_conad+x'28')=integer(r_conad+x'20')
printstring(jtxt."Current analysis aborted.")
newline
end
! *******************************************************************
! *******************************************************************
! *******************************************************************
externalroutine abort direct analysis(string (255) s)
record (rf)r; integer flag
connect("JJ#4DEX", 3, 0, 0, r, flag)
if flag#0 start
printstring(jtxt."Problems..cannot connect Direct log index, ")
printstring("flag:".intostr(flag))
newline
return
finish
integer(r_conad+x'28')=integer(r_conad+x'20')
printstring(jtxt."Current analysis aborted.")
newline
end
! ************************************************************************
! ************************************************************************
! ************************************************************************
externalroutine create journal system(string (255) s)
record (f index list)arrayformat af index list(0:total indices)
record (f tape cycle)arrayformat af tape cycle(1:100)
record (f index list)arrayname index list
record (f tape cycle)arrayname tape cycle
string (7) arrayformat af pending files(1:250)
stringarrayname pending files
record (rf)r
integer i, flag, conad
connect(control, 0, 0, 0, r, flag)
if flag=0 start
printstring(jtxt.control." already exists??")
newlines(2)
return
finish
!WE NOW KNOW THAT JJMASTER DOES NOT EXIST AND THAT THE SYSTEM HAS
!NOT ALREADY BEEN SET UP. PROCEED WITH SET UP.
outfile(control, 3*4096, 0, 0, conad, flag)
if flag#0 start
printstring(jtxt."Failed to create JJMASTER, flag ")
write(flag, 2)
newlines(2)
return
finish
!NOW SET THE INITIAL VALUES TO JJMASTER.
integer(conad) = integer(conad+8); ! Set data length = physical length
integer(conad+x'20') = current packed dt
integer(conad+x'24')=0; !THE JOURNAL STATE SETTING.
integer(conad+x'28')=0; !THE ICL ERROR ENTRY CYCLIC COUNT(LAST TWO BYTES)
integer(conad+x'6D8')=0; !THE FAILURE DESCRIPTOR.
integer(conad+x'6DC')=0; !AUTO CONTROL FLAG
index list==array(conad+x'30', af index list)
!NOW INITIALISE THE INDEX DESCRIPTORS.
for i=0, 1, total indices cycle
index list(i)_id char=i
index list(i)_data type=0
!IE 0: TEXT(TEXT DATA). 1: MAPPED DATA.
index list(i)_identity=""
repeat
!NOW CREATE THE TAPE CYCLE CONTROL.
string(conad+x'6F2')=""; !IDENTIFIES LAST FAILING FILE.
integer(conad+x'700')=0; !TAPES IN CYCLE
integer(conad+x'704')=1; !AGE OF NEXT TAPE
integer(conad+x'708')=-1; !INITIAL MASTER TAPE ENTRY
integer(conad+x'70C')=7000; !Max epages per dump tape.
integer(conad+x'710')=0; !TOTAL CHAPTERS ON MASTER TAPE.
integer(conad+x'714')=0; !TOTAL EPAGES ON MASTER TAPE.
tape cycle==array(conad+x'720', af tape cycle)
for i=1, 1, 100 cycle
tape cycle(i)_tsn=""
tape cycle(i)_age=-2
repeat
integer(conad+x'1FFC')=0; !COUNT OF THE FILES IN THE PENDING FILES ARRAY.
pending files==array(conad+x'2000', af pending files)
!THIS ARRAY POINTS TO THE FILES IN JOURNL TAKEN FROM SPOOLER TO BE PROCESSED.
string(conad+x'6EA')=""; !THIS IS THE BAD FILE POINTER.
string(conad+x'27D0') = ""; ! Null background password.
journal backpass("")
byteinteger(conad+x'27DC') = 0; ! Count for next autojob logfile.
disconnect(control, flag)
printstring(jtxt."JJMASTER initialised.")
newlines(2)
cherish(control)
!NOW SET UP THE SYSTEM INDICES.
new journal index("SYSTEM")
printstring("The Journal system requires at least two tapes")
newline
printstring("for operation. Add these two tapes through the ")
newline
printstring("following prompts. Any further tapes can be added using")
newline
printstring("the command 'NEW JOURNAL TAPE'.")
newline
new journal tape(s)
new journal tape(s)
printstring("The Journal system is now initialised."); newline
printstring("The first run of the housekeeping command: JOURNAL")
printstring(" will initiate (on its"); newline
printstring("successful completion) the automatic housekeeping.")
newline
return
end ; !OF CREATE JOURNAL SYSTEM.
! ********************************************************************
! ********************************************************************
! ********************************************************************
! ROUTINES THAT GIVE DIRECT CALLED ACCESS TO THE HOUSEKEEPING.
externalroutine journal override(string (255) s)
journal("OVERRIDE")
end
externalroutine journal recovery(string (255) s)
journal("")
end
externalroutine update journal(string (255) s)
journal("TAPESKIP,ANALSKIP,EXTERNAL")
end
! ************************************************************************
! ************************************************************************
! ************************************************************************
externalroutine journal(string (255) s)
owninteger run tape
! Stops tape dump run if no files
owninteger tapeskip
owninteger analskip
owninteger auto call
owninteger decks
owninteger killfile
owninteger closetape
owninteger external; !USED WHEN 'JOURNAL' CALLED BY 'FULL JOURNAL ANALYSIS'.
owninteger call state; !ALSO USED IN ABOVE CASE.
owninteger write unit=1
!THE TAPE CONTROL UNIT IDENTITIES.
owninteger abandon tape retries = 2
!IE LEVEL OF RETRY THAT WILL RESULT IN AUTO JOURNAL JOBS BEING
!STOPPED IF UNSUCCESSFUL.
owninteger on = 1
owninteger off = 0
owninteger tape retry level= -1
!THE RETRY COUNTER.
owninteger override
!THE OVERRIDE FLAG.
recordformat f finf(integer nkb, rup, eep, apf, use,
arch, fsys, conseg, cct, codes, codes2, ssbyte, string (6) offer)
record (f finf)finf
recordformat f req(integer dest, srce, flag,
string (6) user, file, integer p6)
recordformat f rep a(integer dest, srce, flag,
string (6) file, string (11) output q)
recordformat f rep b(integer dest, srce, byteinteger flag,
string (6) file, string (15) output q)
recordformat f file list(integer files, integerarray dts(1:100),
string (7) array names(1:100))
record (f file list)array file list(0:total indices)
record (f file list)name fli
record (f index entry)arrayformat af index entry(0:index top)
record (f index list)arrayformat af index list(0:total indices)
record (f tape cycle)arrayformat af tape cycle(1:100)
record (f index entry)arrayname index entry
record (f index list)arrayname index list
record (f tape cycle)arrayname tape cycle
record (f chapter header)name chapter header
record (f parameters)name parameters
record (f req)req
record (f rep a)name repa
record (frep b)name repb
record (f repb)poff rep
record (rf)r
record (f parm)p
record (f queue)name queue
string (7) arrayformat af pending files(1:250)
stringarrayname pending files
string (11) backpass
byteintegername nextjjlog
externalintegerfnspec dpon2(string (6) user, record (f req)name p,
integer msgtype, outno)
externalintegerfnspec dfinfo(string (6) user, string (11) file,
integer fsys, addr)
recordformat f parm(integer dest, srce, p1, p2, p3, p4, p5, p6)
externalintegerfnspec dpon3(string (6) user, record (f parm)name p,
integer invoc, msgtype, outno)
routinespec remove failing file
routinespec bulk change index status(string (12) keyword,
byteinteger old status, new status)
routinespec collect journal files
routinespec connect control file
routinespec connect index(string (15) index, integer mode,
integername addr)
routinespec date and time(integer index slot)
routinespec dump to tape
routinespec check file(string (*)name file, byteintegername c
data type, integername flag)
routinespec file list from spooler
integerfnspec autojob(string (15) name, string (*)name ident)
routinespec respool journal(string (15) name)
routinespec remove queued file(string (6) file)
routinespec requeue file(string (6) file)
routinespec start up
byteintegerarrayformat af buff(1:10000000)
byteintegerarrayname buff
switch journal state(0:5)
integername relative age, master entry, p file count
integername system state, run date, total chapters, tape count
integername autoflag, fail type, total epages, max epages
string (*)name fail file, bad file
string (140) array atoms(1:68)
string (16) index, new file name, start date, start time, identj
string (16) finish date, finish time, poff file; poff file=""
string (64) s1, ss
integer i, flag, index addr, free slot, sequence number, entry
integer queues, prime start, prime end
prime start=packdateandtime(date, prime start time)
prime end=packdateandtime(date, prime end time)
string (255) pstring
byteinteger id char, datatype
!THE MAIN CONTROL CODE BEGINS HERE.
connect control file
!CONNECT THE CONTROL FILE.
respool journal("MONITOR") if autojob("MONITOR", identj)=no
disconnect("JJINF", flag); destroy("JJINF", flag)
destroy("JLIST", flag)
destroy("JJANL", flag)
destroy("JWORKFILE", flag)
!THIS IS A GENERAL WORK FILE THAT EXISTS ONLY FOR RUNS OF CERTAIN ANALYSES.
!DESTROY IT IF IT IS FOUND HANGING AROUND!!
if s#"" start
!THE CALL HAD A PARAMETER LIST.
!POSSIBLE PARAMETER COMBINATIONS:-
!
!'OVERRIDE, EXTERNAL':
!CALL FROM ENGINEERS(PACKAGE C) TO UPDATE
!JEF. REQUIRES A FULL COLLECTION, NO TAPE DUMP AND AN AUTO MAINLOG
!ANALYSIS. IT IS LEFT IN THE 'TAPE DUMP SKIPPED' STATE
!WHICH WILL TRIGGER THE NEXT AUTO HOUSEKEEPING TO TIDY UP.
!
!'TAPESKIP, ANALSKIP, EXTERNAL':
!A CALL FROM THE COMMAND 'UPDATE JOURNAL' TO UPDATE THE
!JOURNAL SYSTEM WITH THE FILES QUEUED BY SPOOLR.. LEFT IN STATE
!AS ABOVE.
!
!'AUTOCALL':
!THIS IS THE ENTRY MADE BY THE AUTOMATIC HOUSEKEEPING HOURLY BATCH JOB.
!IF IT DECIDES THAT A FULL RUN IS REQUIRED IT WILL DETACH
!A SECOND BATCH JOB TO RUN AS SOON AS POSSIBLE WITH ENTRY AS BELOW.
!
!'AUTOCALL+DECK':
!THIS ENTRY IS MADE BY THE ABOVE ENTRY BEING CALLED EARLIER AND
!DECIDING THAT A FULL RUN IS REQUIRED. THIS JOB ENTRY WILL
!REQUEST AN MTU FOR THE RUN.
!
!'OVERRIDE':
!THIS IS THE CALL TO OVERRIDE THE LOCK IMPOSED ON RUNNING THE
!HOUSEKEEPING WHEN THE AUTOMATIC HOUSEKEEPING IS IN AN UNFAILED STATE
!OR THE OPERATORS MAY RUN THIS TO INSTITUE A RECOVERY FROM ANY
!SUSPECTED ERRORS.
!
printstring("Parameter list: ".s)
newlines(2)
flag=0
for i=1, 1, 4 cycle
if s->s1.(",").s start
if s1="TAPESKIP" then tapeskip=1
if s1="ANALSKIP" then analskip=1
if s1="KILLFILE" then killfile=1
if s1="EXTERNAL" then external=1
if tapeskip+analskip+killfile+external#i then flag=1 and exit
finish else exit
repeat
if s="TAPESKIP" then tapeskip=1
if s="ANALSKIP" then analskip=1
if s="KILLFILE" then killfile=1
if s="EXTERNAL" then external=1
if s="AUTOCALL" then autocall=1
if s="AUTOCALL+DECK" then decks = on and autocall=on
if s="OVERRIDE" then override=1
if s="CLOSETAPE" then closetape=1
if tapeskip+analskip+killfile+external+autocall+override+closetape#i c
then flag=1
if (autocall=on) and i#1 then flag=1
if override=on start
if external#on start
if i#1 then flag=1
finish
finish
if flag=1 start
printstring(jtxt."Parameter list faulty!".snl)
return
finish
if killfile=1 then remove failing file
if closetape=1 then max epages = 0
! Reset (to 7000) by next call of START NEWTAPE.
finish
connect(spool.".CFILE", 9, 0, 0, r, flag)
if flag#0 start
!WE CANNOT CONNECT THE SPOOLR INFO FILE.
printstring("Spoolr descriptor file (CFILE) connect fails:")
write(flag, 3) and newline
printstring("Log off and try again.".snl)
stop
finish
queues=integer(r_conad+x'18')
if queues=0 start
printstring("No queues defined in SPOOLR descriptor file".snl)
stop
finish
for i=1, 1, queues cycle
queue==record(r_conad+x'20'+148*(i-1))
if queue_name="JOURNAL" then exit
if i=queues start
printstring("Journal queue not in SPOOLR descriptor file".snl)
stop
finish
repeat
if autoflag=on and autocall=off and override=off start
!IE A MANUAL RUN OF JOURNAL IS NOT ALLOWED WHEN THE AUTO
!JOURNAL SYSTEM IS IN AN UNFAILED STATE.
unless external=on start
printstring(jtxt."Manual run not permitted whilst auto".snl)
printstring(" Journal is in unfailed state.".snl)
stop
finish
!ALTHOUGH ALLOW CALL FROM UPDATE JOURNAL.
finish
if override=on and external=off start
!We have a manual run interrupting the auto run sequence.
autoflag=off
fail type=0
finish
if override=on and external=on start
!IE A CALL FROM THE ENGINEERS COMMAND 'UPDATE JEF'.
if autoflag=off or (system state#0 and system state#2) c
start
printstring("Journal system in failed state, please log")
printstring(" off and inform ops."); newline
return
finish
autoflag=off; tapeskip=on
printstring("Updating JEF")
newline
finish
start up; !FIND OUT HOW TO START UP THIS RUN OF JOURNAL HOUSEKEEPING
!NOW CLOSE THE CURRENT MAINLOG.
p=0
p_dest=x'FFFF0000'!27
i=dpon3("DIRECT", p, 0, 1, 7)
-> journal state(system state)
journal state(0):
!IF THE SET TESTS ARE POSITIVE (IE THE PD IS FILLING UP) THEN
!DESTROY THE PARTITION AMENDING THE STATUS SETTINGS IN THE
!INDICES FROM "ON PD AND TAPE" TO "ON TAPE ONLY". THEN CREATE
!A NEW 24 HOUR PARTITION.
i=dfinfo(me, "JJ#PD", -1, addr(finf))
if i#0 start
printstring("Journal DFINFO fails, max assumed".snl)
finf_nkb=3001
finish
if (finf_nkb>1000 and (finf_nkb*1024+queue_amount)>1024*3500) c
or (finf_nkb*1024+queue_amount)>1024*4000 start
bulk change index status("ALL", 1, 2)
!ALL STATUS AMENDMENTS MADE.
destroy(pdstore, flag)
newpdfile(pdstore)
cherish(pdstore)
finish
journal state(2):
journal state(3):
!RESTART WITH EXISTING PD FILE OR DROP THROUGH FROM ABOVE.
!STATE 3 CAN ONLY BE REACHED BY EXTERNAL CALL FROM 'UPDATE
!JOURNAL' WHEN A TAPE DUMP HAS PREVIOUSLY FAILED AND
!WE WISH TO ALLOW A FILE COLLECTION TO TAKE PLACE WHILST
!RETAINING THE TAPE DUMP FAILURE CONTINGENCY( THE CALL WILL
!BE ACCOMPANIED BY 'TAPESKIP' AND 'ANALSKIP')
if system state=3 then call state=3
!IE REMOTE CALL OF JOURNAL AFTER A PREVIOUS TAPE CONTINGENCY.
system state=1
!SETTING THE SYSTEM STATUS TO DEFAULT COLLECTION FAILURE.
collect journal files
journal state(4):
!FORCED DUMP TO TAPE OR FALL THROUGH FROM ABOVE.
if tape skip=0 start
cycle
system state = 3; ! Default state during tape dump.
dump to tape
exit if system state=0; ! Tape dump successful.
tape retry level=tape retry level+1
if tape retry level=abandon tape retries start
printstring("Multiple tape failure, auto Journal runs suspended.".snl)
printstring("See Journal documentation, failure no: 1.".snl)
auto flag=off
ss=" JOURNAL SYSTEM FAILS FAILURE NO: 1."
byteinteger(addr(ss)+1)=17
!MAKE THE OPER MESSAGE FLASH.
fail type=1
oper(0, ss)
return
!I.e. we have failed in the tape dump consistently, so stop auto runs
! and inform the operators of failure. The System management will
! then have to sort out the tape problem (fail type 1).
finish
printstring(jtxt."Dump to tape failed, retry level:")
printstring(intostr(tape retry level).snl)
oper(0, "JOURNAL:TRY A NEW DECK")
repeat
finishelsestart
if call state=3 then system state=3 else system state=2
! I.e. if remote call from 'UPDATE JOURNAL' then any tape
!contingency is retained through the call, else assign 'SKIP' state.
printstring(jtxt."Tape dump omitted as requested.".snl)
finish
if analskip=1 start
printstring(jtxt."Ended without auto analyses as requested".snl)
if autoflag=off then autoflag=on
!WE CAN ALLOW AUTO SYSTEM TO RUN SINCE COLLECTION IS OK.
disconnect(control, flag)
return
finish
autoflag=off; fail type=4
!SET THE FAIL TYPE FOR AUTO ANALYSIS FAILURE.
!NOW PERFORM THE MAIN LOG ANALYSIS FOR ''TODAY''
parameters==record(addr(pstring)+1)
parameters_keyword="MAINLOG"
parameters_analysis="AUTOMATIC"
index="MAINLOG"
identify index(index, id char, data type, entry)
index="JJ#".intostr(id char)."DEX"
connect index(index, 3, index addr)
parameters_lower file<-intostr(integer(index addr+x'28'))
if integer(index addr+x'28')=integer(index addr+x'20') start
printstring(jtxt."No files for automatic analysis (MAINLOG)".snl)
finish else start
parameters_upper file<-intostr(cyclic(integer(index addr+x'20'), -1))
byteinteger(addr(pstring))=x'30'
printstring(jtxt."Running automatic analysis (MAINLOG)".snl)
journal analysis(pstring)
!THE ANALYSIS HAS NOW BEEN DEFINED AND RUN.
!NOW RESET THE RUNNING PARAMETERS IN THE INDEX.
integer(index addr+x'28')=integer(index addr+x'20')
finish
disconnect(index, flag)
!AUTO MAINLOG ANALYSIS NOW COMPLETED AND POINTERS RESET.
if override=on and external=on start
printstring("JEF updated.")
autoflag=on; failtype=0
return
finish
!NOW PERFORM THE SPOOLR ANALYSIS FOR ''TODAY''
fail type=5; !SET FAIL TYPE FOR SPOOLR ANALYSIS.
parameters==record(addr(pstring)+1)
parameters_keyword="SPOOLR"
parameters_analysis="AUTOMATIC"
index="SPOOLR"
identify index(index, id char, data type, entry)
index="JJ#".intostr(id char)."DEX"
connect index(index, 3, index addr)
parameters_lower file<-intostr(integer(index addr+x'28'))
if integer(index addr+x'28')=integer(index addr+x'20') start
printstring(jtxt."No files for automatic analysis (SPOOLR)".snl)
finish else start
parameters_upper file<-intostr(cyclic(integer(index addr+x'20'), -1))
byteinteger(addr(pstring))=x'30'
printstring(jtxt."Running automatic analysis (SPOOLR)".snl)
journal analysis(pstring)
!THE ANALYSIS HAS NOW BEEN DEFINED AND RUN.
!NOW RESET THE RUNNING PARAMETERS IN THE INDEX.
integer(index addr+x'28')=integer(index addr+x'20')
finish
disconnect(index, flag)
!AUTO SPOOLR ANALYSIS NOW COMPLETED AND POINTERS RESET.
!NOW PERFORM THE VOLUMS ANALYSIS FOR 'TODAY'
fail type=6; !SET FAIL TYPE FOR VOLUMS ANALYSIS.
parameters==record(addr(pstring)+1)
parameters_keyword="VOLUMS"
parameters_analysis="AUTOMATIC"
index="VOLUMS"
identify index(index, id char, data type, entry)
index="JJ#".intostr(id char)."DEX"
connect index(index, 3, index addr)
parameters_lower file<-intostr(integer(index addr+x'28'))
if integer(index addr+x'28')=integer(index addr+x'20') start
printstring(jtxt."No files for automatic analysis (VOLUMS)".snl)
finish else start
parameters_upper file<-intostr(cyclic(integer(index addr+x'20'), -1))
byteinteger(addr(pstring))=x'30'
printstring(jtxt."Running automatic analysis (VOLUMS)".snl)
journal analysis(pstring)
!THE ANALYSIS HAS NOW BEEN DEFINED AND RUN.
!NOW RESET THE RUNNING PARAMETERS IN THE INDEX.
integer(index addr+x'28')=integer(index addr+x'20')
finish
disconnect(index, flag)
!AUTO VOLUMS ANALYSIS NOW COMPLETED AND POINTERS RESET.
!NOW PERFORM THE DIRECT ANALYSIS FOR 'TODAY'
fail type=7; !SET FAIL TYPE FOR DIRECT ANALYSIS.
parameters==record(addr(pstring)+1)
parameters_keyword="DIRECT"
parameters_analysis="AUTOMATIC"
index="DIRECT"
identify index(index, id char, data type, entry)
index="JJ#".intostr(id char)."DEX"
connect index(index, 3, index addr)
parameters_lower file<-intostr(integer(index addr+x'28'))
if integer(index addr+x'28')=integer(index addr+x'20') start
printstring(jtxt."No files for automatic analysis (DIRECT)".snl)
finish else start
parameters_upper file<-intostr(cyclic(integer(index addr+x'20'), -1))
byteinteger(addr(pstring))=x'30'
printstring(jtxt."Running automatic analysis (DIRECT)".snl)
journal analysis(pstring)
!THE ANALYSIS HAS NOW BEEN DEFINED AND RUN.
!NOW RESET THE RUNNING PARAMETERS IN THE INDEX.
integer(index addr+x'28')=integer(index addr+x'20')
finish
disconnect(index, flag)
!Auto Direct analysis now completed and pointers reset.
printstring(jtxt."Requested run of Journal completed.".snl)
fail type=0; autoflag=on
disconnect(control, flag)
return
routine remove failing file
!HERE WE REMOVE THE QUEUED FILE THAT IS CAUSING REPEATED FAILURES
integer i
string (16) s, ns1
if fail file="" start
printstring(jtxt."No record of a failing file!".snl)
stop
finish
if fail file->ns1.(spool.".").s and ns1="" start
printstring(jtxt."Marking ".fail file." for deletion.".snl)
bad file=s
disconnect(control, flag)
stop
finish else start
for i=1, 1, p file count cycle
if pending files(i)=fail file then pending files(i)=""
repeat
destroy(fail file, flag)
printstring(jtxt."File ".fail file." destroyed.".snl)
fail file=""
disconnect(control, flag)
stop
finish
end ; !OF REMOVE FAILING FILE.
routine bulk change index status(string (12) keyword,
byteinteger old, new)
!THIS ROUTINE WILL CONNECT THE DEFINED INDEX (ALL INDICES IF KEYWORD
!= "ALL" ) AND WILL CHANGE ALL STATUS VALUES THAT ARE AT PRESENT "OLD"
!TO "NEW"
!JJMASTER MUST BE CONNECTED AND INDEX LIST MAPPED ON ENTRY TO THIS
!ROUTINE.
byteinteger status
integer i, k, top file
for i=0, 1, total indices cycle
!LOOK UP THE LIST OF INDICES.
if (keyword="ALL" or keyword=index list(i)_identity) and c
index list(i)_identity#"" start
index="JJ#".intostr(index list(i)_id char)."DEX"
connect index(index, 3, index addr)
top file=integer(index addr+x'20'); !THE TOP FILE(+1)OF THE INDEX
if integer(index addr+x'24')#0 start
!THERE ARE FILES ON THE INDEX.
k = top file
cycle
k = cyclic(k,-1)
! Backwards to save cpu.
status=index entry(k)_status
exit if status=2 or status=8
!IE IF FILES ON TAPE ARE FOUND OR ENTRY UNUSED, THEN WE HAVE
! Gone far enough back through the index.
if status=old then index entry(k)_status=new
repeat until k=top file
finish
disconnect(index, flag)
finish
repeat
end ; !OF BULK CHANGE INDEX STATUS.
routine collect journal files
!THIS ROUTINE TAKES ALL THE FILES OFF THE INPUT QUEUE AND PUTS THEM
!ON THE 24 HOUR PARTITION AT THE SAME TIME MAKING AN ENTRY FOR EACH
!FILE IN THE RELEVANT INDEX. THE CONTROL OF THE SYSTEM IS MAINTAINED
!BY UPDATING THE CONTROL AREAS OF THE CONTROL FILE AND INDICES.
integer flag, i, ind, fls
byteinteger data type
!DATA TYPE: DEFINES THE FILE INFORMATION TYPE IE TEXT(TEXT DATA) OR MAPPED DATA.
string (31) file, seq
file list from spooler
for ind=0, 1, total indices cycle
fli == file list(ind)
continue unless fli_files>0
data type=index list(ind)_data type
! There are files to be taken of this type.
!ID CHAR IS DEFINED BY IND.
index="JJ#".intostr(ind)."DEX"
connect index(index, 3, index addr)
for fls=1, 1, fli_files cycle
file=fli_names(fls)
check file(file, data type, flag)
continue unless flag=0
free slot=integer(index addr+x'20')
sequence number=integer(index addr+x'24')
seq=intostr(sequence number); !THE STRING VERSION OF THE SEQUENCE
!WE NOW HAVE THE INDEX POSITION AND NEW IDENTITY NUMBER OF
!THE NEW FILE.
new file name="J".intostr(ind)."I".seq
!THE NEW FILE NAME.
index entry(free slot)_file id = sequence number
rename(pdstore."_".file.",".pdstore."_".newfilename)
connect(pdstore."_".newfilename, 0, 0, 0, r, flag)
monitor and stop if flag#0; !SHOULD NOT HAPPEN.
date and time(free slot)
index entry(freeslot)_status=0
integer(index addr+x'20') = cyclic(freeslot, 1)
integer(index addr+x'24') = cyclic(sequence number, 1)
for i=1, 1, p file count cycle
if pending files(i)=file then pending files(i)="" c
and exit
repeat
run tape=1
repeat
disconnect(index, flag)
repeat
p file count=0
!IE THERE ARE NO FILES ON THE PENDING FILE LIST NOW(ALL
!ENTRIES SHOULD BE "")
printstring(jtxt."File collection completed.".snl)
end ; !OF COLLECT JOURNAL FILES.
routine connect control file
!THIS ROUTINE WILL CONNECT THE MASTER CONTROL FILE JJMASTER AND
!ALL THE NAMES LINKED TO IT .
integer flag
connect(control, 3, 0, 0, r, flag)
if flag#0 then master file failure(control, flag)
system state==integer(r_conad+x'24')
run date==integer(r_conad+x'20')
master entry==integer(r_conad+x'708')
!THE POINTER FOR THE ENTRY TO THE CURRENT MASTER TAPE.
max epages==integer(r_conad+x'70C')
total epages==integer(r_conad+x'714')
total chapters==integer(r_conad+x'710')
tape cycle==array(r_conad+x'720', af tape cycle)
tape count==integer(r_conad+x'700')
relative age==integer(r_conad+x'704')
fail type==integer(r_conad+x'6D8')
autoflag==integer(r_conad+x'6DC')
!THE AUTO RUN PERMISSION FLAG.
fail file==string(r_conad+x'6F2')
index list==array(r_conad+x'30', af index list)
p file count==integer(r_conad+x'1FFC')
pending files==array(r_conad+x'2000', af pending files)
bad file==string(r_conad+x'6EA')
back pass <- string(r_conad+x'27D0')
nextjjlog == byteinteger(r_conad+x'27DC')
end ; !OF CONNECT CONTROL FILE.
routine connect index(string (15) index, integer mode,
integername addr)
!THIS ROUTINE WILL CONNECT THE REQUIRED INDEX IN THE MODE
!DEFINED AND WILL MAP THE "INDEX ENTRY" ARRAY ONTO IT. THE
!CONNECT ADDRESS IS PASSED BACK IN ADDR.
integer flag
connect(index, mode, 0, 0, r, flag)
if flag#0 then master file failure(index, flag)
addr=r_conad
index entry==array(r_conad+x'40', af index entry)
end ; !OF CONNECT INDEX.
routine date and time(integer index slot)
!THIS ROUTINE IS USED TO ENTER THE RELEVANT DATES AND TIMES
!FOR THE FILE IN THE INDEX CONNECTED. THIS WILL BE THE
!MEANS OF SEARCH IDENTITY FOR ANY RETRIEVAL FROM THE SYSTEM.
if start date#"*" start
if start date="" start
!IE NO DATES FOUND.
if index entry(cyclic(index slot, -1))_status#8 start
!IE NOT THE FIRST INDEX ENTRY.
index entry(index slot)_starting c
=index entry(cyclic(index slot, -1))_finishing
index entry(index slot)_finish ing c
=index entry(index slot)_starting
finish
! Leave index creation date in. This should not happen often.
finishelsestart
index entry(index slot)_starting c
=packdateandtime(start date, start time)
index entry(index slot)_finishing c
= packdateandtime(finish date, finish time)
finish
finish else start
!IN THIS CASE
!MAINTAIN A CONTINUOUS DATE INDEX WE USE THIS AS THE FINISHING
!DATE FOR THE FILE AND THE STARTING DATE AS THE FINISHING DATE
!OF THE LAST FILE ON THE INDEX.
index entry(index slot)_finishing= c
pack date and time(finish date, finish time)
if index entry(cyclic(index slot, -1))_status#8 start
!IE THIS IS NOT THE FIRST ENTRY IN THE INDEX
index entry(index slot)_starting= c
index entry(cyclic(index slot, -1))_finishing
finish else index entry(index slot)_starting= c
index entry(index slot)_finishing
finish
end ; !OF DATE AND TIME.
routine dump to tape
!THIS ROUTINE WILL DUMP ALL THE INDEXED FILES FROM THE PD FILE
!TO MAGNETIC TAPE CONTROLLED BY THE TAPE CYCLE INFORMATION IN
!THE CONTROL FILE JJMASTER.
integer epages, chapters, file epages, displ, wkaddr
integer i, j, k, curraddr, len, file length, existing chapters
integer last bytes, count
integer tape change; tape change=0
byteintegerarray buffer(0:4095)
!THE TAPE IO BUFFER
string (6) write tape, full tape
string (31) file name
connect control file
routine tape error(string (64) s)
!THIS ROUTINE DEALS WITH MOST OF THE 'EVERYDAY' TYPE OF TAPE ERRORS
!OCCURING DURING THE RUN OF THE TAPE DUMP.
printstring(jtxt."Tape error detected.".snl)
printstring(s.snl)
return
end ; !OF TAPE ERROR.
routine read verify(integername flag)
!THIS ROUTINE READS THROUGH THE THE LAST WRITE TAPE
!TO ENSURE THAT THERE ARE NO PROBLEMS
integer pages, j
printstring(jtxt."Verifying ".write tape.snl)
len=block
skip tm mag(write unit, 1); !GET BEYOND THE LABEL.
if chapters>0 start
printstring(jtxt."Verify: skipping ".intostr(chapters-1))
printstring(" chapters.".snl)
flag=0
f skip tm mag(write unit, chapters-1, flag) if chapters>1
!SKIP TO LAST CHAPTER
if flag#0 start
printstring(jtxt."Verify: skip fails flag: ".intostr(flag).snl)
flag=1
return
finish
len=block
read mag(write unit, wkaddr, len, flag)
if flag=1 start
printstring(jtxt."Verify: tape mark where header should be!!".snl)
flag=1; return
finish
if flag>1 start
printstring(jtxt."Verify: failure on header read , flag: ")
write(flag, 3); printstring("Chapter: ")
write(chapters, 4) and newline
flag=1; return
finish
if chapter header_type#"JOURNAL" or c
chapter header_tape name#write tape or c
chapter header_chapter#chapters start
printstring(jtxt."Verify: chapter header failure: ".snl)
printstring(" should be: ")
printstring("Journal ".write tape." ")
write(chapters, 4) and newline
printstring(" actual: ")
printstring(chapter header_type." ".chapter header_tapename)
write(chapter header_chapter, 5) and newline
flag=1; return
finish
pages=chapter header_epages
for j=1, 1, pages cycle
len=block
read mag(write unit, wkaddr, len, flag)
if flag=1 start
printstring(jtxt."Verify: tape mark in middle of file.".snl)
printstring(" chapter: ")
write(chapters, 4) and newline
flag=1; return
finish
if flag>1 start
printstring(jtxt."Verify: failure reading tape, flag: ")
write(flag, 3) and newline
printstring(" chapter: "); write(chapters, 4) and newline
flag=1; return
finish
repeat
read mag(write unit, wkaddr, len, flag)
if flag#1 start
printstring(jtxt."Verify: no tape mark, chapter: ")
write(chapters, 4) and newline
flag=1; return
finish
finish
printstring(jtxt."Verify: last existing chapter verified.".snl)
flag=0
return
end
routine verify new chapters(integer existing chapters, chapters,
integername flag)
!THIS ROUTINE JUST READ VERIFIES THE NEW CHAPTERS ON THE MASTER TAPE.
integer pages, i, j, ch count
ch count=0
printstring(jtxt."Verifying ".write tape.snl)
if chapters-existing chapters>0 start
f skip tm mag(write unit, -(chapters-existing chapters+2), flag)
if flag#0 start
printstring(jtxt."Verify: skip fails flag: ".intostr(flag).snl)
return
finish
!NOW SHOULD BE BEFORE TM OF LAST OLD CHAPTER.
skip tm mag(write unit, 1)
ch count=0
!NOW AT THE HEADER OF THE FIRST NEW CHAPTER(I HOPE)
for i=existing chapters+1, 1, chapters cycle
len=block
read mag(write unit, wkaddr, len, flag)
if flag=1 start
printstring(jtxt."Verify: tape mark where header should be!!".snl)
flag=1; return
finish
if flag>1 start
printstring(jtxt."Verify: failure on header read , flag: ")
write(flag, 3); printstring("Chapter: ")
write(i, 4) and newline
flag=1; return
finish
if chapter header_type#"JOURNAL" or c
chapter header_tape name#write tape or c
chapter header_chapter#i start
printstring(jtxt."Verify: chapter header failure: ".snl)
printstring(" should be: ")
printstring("Journal ".write tape." ")
write(i, 4) and newline
printstring(" actual: ")
printstring(chapter header_type." ".chapter header_tapename)
write(chapter header_chapter, 5) and newline
if i-chapter header_chapter=1 and c
i=existing chapters+1 start
!WE HAVE THE SITUATION WHERE THE TAPE MARK OF THE FINAL EXISTING
!CHAPTER HAS BEEN OVERWRITTEN BY THE NEW CHAPTERS, WE MUST
!RESTORE THE DOUBLE TM AT THE END OF THIS CHPTER BEFORE FAILING.
printstring(jtxt."Verify: special last chapter recovery ")
printstring("proceeding".snl)
pages=chapter header_epages
for j=1, 1, pages cycle
len=block
read mag(write unit, wkaddr, len, flag)
if flag=1 then c
printstring(" Fails with TM.".snl) and return
if flag>1 start
printstring(" Fails, flag: ")
write(flag, 1) and newline
flag=1
return
finish
repeat
!OK WE ARE AT THE END OF THE LAST EXISTING CHAPTER, WRITE TWO TMS.
write tmmag(write unit, flag)
write tmmag(write unit, flag)
printstring(" Recovery OK.".snl)
finish
flag=1; return
finish
pages=chapter header_epages
ch count=ch count+1
for j=1, 1, pages cycle
len=block
read mag(write unit, wkaddr, len, flag)
if flag=1 start
printstring(jtxt."Verify: tape mark in middle of file.".snl)
printstring(" chapter: ")
write(i, 4) and newline
flag=1; return
finish
if flag>1 start
printstring(jtxt."Verify: failure reading tape, flag: ")
write(flag, 3) and newline
printstring(" chapter: "); write(i, 4) and newline
flag=1; return
finish
repeat
read mag(write unit, wkaddr, len, flag)
if flag#1 start
printstring(jtxt."Verify: no tape mark, chapter: ")
write(i, 4) and newline
flag=1; return
finish
repeat
finish
printstring(jtxt.intostr(chcount)." new chapters verified.".snl)
flag=0
return
end
routine start new tape(integername flag)
!THIS ROUTINE IS CALLED WHEN THE CURRENT MASTER TAPE
!IS FULL AND NEEDS TO BE REPLACED WITH A FRESH TAPE FROM THE CYCLE.
integer i, max
record (rf) r
max epages = 7000; ! Could have been set to 0 (by JOURNAL(CLOSETAPE) ).
printstring(jtxt."Tape dump: ".write tape." full, starting new tape".snl)
write tmmag(write unit, flag)
if flag#0 start
printstring(jtxt."Tape dump: failed to write tape mark.".snl)
flag=1; return
finish
verify new chapters(existing chapters, chapters, flag)
if flag=1 then return
!IE VERIFY FAILED.
unload mag(write unit)
full tape=write tape
write tape=""
for i=1, 1, tape count cycle
if tape cycle(i)_age=0 then c
write tape=tape cycle(i)_tsn and exit
repeat
if write tape="" start
connect("JENGPD_JENGHD",0,0,0,r,flag)
if flag=0 and integer(r_conad+x'100')=5 start
! 2972 - temp frig.
oper(0,"LOG INTO JOURNL AND CALL")
oper(0,"COMMAND 'NEW JOURNAL TAPE'")
stop
finish
!WE WILL HAVE TO REUSE THE OLDEST TAPE
max=10000
for i=1, 1, tape count cycle
if tape cycle(i)_age<max and tape cycle(i)_age#-1 start
max=tape cycle(i)_age
write tape=tape cycle(i)_tsn
finish
repeat
printstring(" reusing ".write tape.snl)
finish
epages=0
chapters=0
existing chapters=0
!ZEROISE THE CHAPTER COUNT.
printstring(jtxt."Tape dump: new write tape: ".write tape.snl)
open mag(write unit, write tape."*")
skip mag(write unit, 1); !GET BEYOND THE LABEL.
write tm mag(write unit, flag)
flag=0
len=block
return
end ; !OF START NEW TAPE.
if run tape=0 start
printstring(jtxt."No files to dump to tape.".snl)
system state=0
return
finish
wkaddr=addr(buffer(0))
for i=0, 1, block-1 cycle
buffer(i)=0
repeat
!IE CLEAR DOWN THE IO BUFFER
if tape count<2 start
printstring(jtxt."Tape dump: only "); write(tape count, 1)
printstring(" tapes in the cycle, there must be at least 2.".snl)
return
finish
!WE KNOW THAT THERE ARE SUFFICIENT TAPES IN THE CYCLE.
if master entry=-1 start
!THIS MUST BE THE FIRST RUN OF THE SYSTEM!
master entry=1
tape cycle(1)_age=-1
finish
write tape=tape cycle(master entry)_tsn
chapter header==record(wkaddr)
!MAP THE CHAPTER HEADER RECORD ONTO THE I/O AREA.
chapters = total chapters; !THE NUMBER OF CHAPTERS ALREADY ON THE MASTER TAPE.
epages = total epages; !THE COUNT OF THE EPAGES ON THIS TAPE.
existing chapters=total chapters
printstring(jtxt."Tape dump: requesting tape ".writetape." for dumping files.".snl)
open mag(write unit, write tape."*")
if chapters>0 start
!THERE ARE FILES ALREADY ON THE TAPE, AS A CHECK READ VERIFY
!THE TAPE UP TO THE END
read verify(flag)
if flag=1 start
printstring("Verify: fails!".snl)
->unload
finish
finish else start
!OTHERWISE WE ARE STARTING A NEW TAPE.
skip mag(write unit, 1); !GET BEYOND THE LABEL
write tm mag(write unit, flag)
finish
!WE ARE NOW POSITIONED READY TO WRITE THE NEW FILES.
len = block
for i=0, 1, block-1 cycle
buffer(i)=0
repeat
for i=0, 1, total indices cycle
continue if index list(i)_identity=""
!THIS IS A 'USED' INDEX.
id char=index list(i)_id char
index="JJ#".intostr(id char)."DEX"
connect index(index, 3, index addr)
for j=0, 1, index top cycle
if index entry(j)_status=8 then disconnect(index, flag) c
and exit
!REACHED THE CURRENT TOP OF THE INDEX
continue if index entry(j)_status#0
!THE FILE NEEDS TO BE WRITTEN OUT TO TAPE.
filename="J".intostr(id char)."I" c
.intostr(indexentry(j)_file id)
connect(pdstore."_".file name, 0, 0, 0, r, flag)
if flag#0 start
printstring("Tape dump: ".filename." lost!!".snl)
index entry(j)_status=9
!MARK THE FILE AS LOST.
finish else start
if epages>max epages start
start new tape(flag)
->unload if flag=1
tape change=1
finish
!THE MASTER TAPE IS FULL START NEW TAPE(OR OLD FULL ONE.)
file length=integer(r_conad)
file epages=file length>>12
if file epages<<12 # file length start
last bytes=file length-file epages<<12
file epages=file epages+1
finish else last bytes=0
displ=0
chapters=chapters+1
chapter header_tape name<-write tape
chapter header_username="JOURNL"
chapter header_file name<-filename
chapter header_date=date
chapter header_time=time
chapter header_type="JOURNAL"
chapter header_chapter=chapters
chapter header_epages=file epages
chapter header_fsys=-1
chapter header_perms=0
write mag(write unit, wkaddr, len, flag)
if flag#0 then c
tape error("On writing file header in new chapter ".c
intostr(chapters)." Fails:".intostr(flag)) c
and ->unload
!THE HEADER FOR THE FILE IS NOW WRITTEN.
printstring(chapter header_tapename)
printstring(" ".chapter header_file name)
spaces(1); write(chapter header_chapter, 3)
write(chapter header_epages, 4)
newline
epages=epages+1
!INCREMENT THE TOTAL EPAGE COUNT.
for k=1, 1, file epages cycle
if k=file epages and lastbytes>0 then c
count=last bytes else count=block
!NOW COPY OVER EACH PAGE OF THE FILE
curraddr=r_conad+displ
move(count, curraddr, wkaddr)
write mag(write unit, wkaddr, len, flag)
!ONE PAGE FROM THE FILE.
displ = displ+block
if flag#0 then tape error("On writing page ". c
intostr(k)." of new chapter ".intostr(chapters). c
" Fails:".intostr(flag)) and ->unload
epages = epages+1
repeat
write tmmag(write unit, flag)
if flag#0 start
printstring("Tape dump: failed to write tape mark at ")
printstring("End of new chapter ")
write(chapters, 4) and newline
->unload
finish
!FILE IS NOW ON THE TAPE OK, FILL IN INDEX FOR TAPE POSN.
index entry(j)_tape<-write tape
index entry(j)_chapter=chapters
finish
repeat
disconnect(index, flag)
repeat
write tmmag(write unit, flag)
if flag#0 start
printstring("Tape dump: failed to write double tape mark.".snl)
->unload
finish
verify new chapters(existing chapters, chapters, flag)
if flag=1 then ->unload
!IE THE READ VERIFICATION FAILED.
unload:
unload mag(write unit)
return if flag#0; ! Error at some stage in tape handling.
!WE HAVE NOW CHECKED THAT THE NEW TAPE INFO CAN BE READ ALL THE WAY THROUGH.
!UPDATE THE INDICES TO IDENTIFY THE POSITION OF THE FILE
for i=0, 1, total indices cycle
if index list(i)_identity#"" start
id char=index list(i)_id char
index="JJ#".intostr(id char)."DEX"
connect index(index, 3, index addr)
for j=0, 1, index top cycle
if index entry(j)_status=0 then index entry(j)_status=1
!THE FILE IS NOW ON TAPE
if tape change=1 start
!THERE HAS BEEN AN ADDITION OF A NEW TAPE DURING THIS DUMP.
if index entry(j)_tape=write tape and c
index entry(j)_status>1 then index entry(j)_status=9 c
and integer(index addr+x'2C')=cyclic(j, 1)
!THE FILE WAS ON THE REUSED TAPE SO IT IS NOW LOST. ALSO
!THE OLDEST FILE POINTER IS UPDATED.
finish
exit if index entry(j)_status=8
repeat
disconnect(index, flag)
finish
repeat
total epages=epages
total chapters = chapters
!AND AMEND THE CHAPTER COUNT AND PAGE COUNT.
if tape change = 1 start
!THERE WAS A CHANGE OF TAPE IN THIS DUMP.
for i=1, 1, tape count cycle
if tape cycle(i)_tsn=write tape then tape cycle(i)_age=-1 c
and master entry=i
if tape cycle(i)_tsn=full tape c
then tape cycle(i)_age=relative age +1
repeat
relative age=relative age+1
!INCREMENT THE BASE AGE COUNTER FOR TAPES.
finish
!WE HAVE COMPLETED THE TAPE DUMP SUCCESSFULLY
system state=0; !IE TAPE DUMP COMPLETED OK.
end ; !OF DUMP TO TAPE.
routine file list from spooler
integer id, dt, count, fsys
string (16) name, s
integer ld, hd, i, j, k, flag, dat, min, low, pass, pfcount
ld=pack date and time("06/01/70", "01.01.01")
hd=pack date and time("01/01/99", "01.01.01")
string (16) file, spoolr file
for count=0, 1, total indices cycle
file list(count)_files=0
repeat
!FIRST COLLECT ALL THE FILES FROM SPOOLER AND THROW OUT ANY
!UNRECOGNISED FILES OR A MARKED BAD FILE.
pf count=0
pass=0
if p file count>0 then pass=1
!If the last run failed then there may be files in Journal
!that are waiting to be processed (pending files).
!In the following section we deal with these files first followed
!by files from Spooler (pass 1 and pass 0).
cycle
if pass=1 and pf count=p file count then pass=0
!WE HAVE LOOKED AT ALL THE PENDING FILES.
if pass=1 start
pf count=pf count+1
file=pending files(pf count)
connect(pdstore, 3, 0, 0, r, flag)
if flag #0 start
printstring("Journal file 'JJ#PD' lost !!!")
newline
stop
finish
connect(pdstore."_".file, 0, 0, 0, r, flag)
if flag#0 start
printstring(jtxt."File ".file." lost!!!".snl)
pending files(pf count)=""
->next
finish
finish else start
req_dest=x'FFFF003C'
req_flag=1
req_user="JOURNL"
i=dpon2(spool, req, 1, 7)
if poff file#"" start
poff rep=0
dpoff(poff rep)
if poff rep_flag#0 start
printstring(jtxt."Warning, ".poff file)
printstring(" still on queue, flag:")
write(poff rep_flag, 3) and newline
finish
poff file=""
finish
if i#0 start
printstring(jtxt."DPON2(3C) error..SPOOLR missing??".snl)
stop
finish
repa==req; repb==req
flag=0
if rep b_flag#0 then flag=rep b_flag else start
if length(repb_file)=6 then spoolr file=rep b_file c
else start
flag=rep a_flag
spoolr file=rep a_file if flag=0
finish
finish
file=spoolr file if flag=0
exit if flag=207
if flag#0 start
printstring(jtxt."Failed, Spooler flag: ")
write(flag, 3) and newline
printstring(" whilst accessing JOURNL queue.".snl)
stop
finish
fail file=spool.".".file
if file=bad file start
!THIS FILE HAS BEEN MARKED AS BAD AND IS TO BE IGNORED AND REMOVED.
disconnect(spool.".".file, flag)
remove queued file(file)
printstring(jtxt."File ".bad file." removed!".snl)
bad file=""
->next
finish
!FIND THE FILE SYSTEM FOR THIS SPOOLR.
s=file; length(s)=2
fsys = s to i(s)
unless 0<=fsys<=nsys start
printstring(jtxt."Invalid fsys for file: ".fail file)
printstring(" , removing queue entry".snl)
remove queued file(file)
->next
finish
i=(fsys<<8)!x'80'
connect(spool.".".file, 0, 0, i, r, flag)
if flag#0 start
printstring(jtxt."Cannot connect ".fail file." flag")
write(flag, 3) and newline
remove queued file(file)
->next
finish
if integer(r_conad+8)&x'0FFF'#0 or integer(r_conad) c
>x'100000' start
printstring(jtxt."File SPOOLR.".file." has a corrupt")
printstring(" Header or is too big(>1024k), file discarded.".snl)
sdisconnect(spool.".".file, fsys, flag)
remove queued file(file)
->next
finish
if r_datastart=r_dataend or r_dataend>integer(r_conad+8) c
or r_dataend<r_datastart start
!THE FILE IS EMPTY OR HAS A BAD HEADER.
sdisconnect(spool.".".file, fsys, flag)
remove queued file(file)
printstring(jtxt."Throwing out empty/bad file ".file.snl)
->next
finish
flen=r_dataend
!IT IS WORTH NOTING HERE THAT THE PD FILE CAN HOLD UP TO
!4 MEG. SINCE SPOOLER ONLY HOLDS 100 FILES IT WILL BE UNLIKELY
!THAT THE AVERAGE FILE SIZE WILL EXCEED 40K SO A SINGLE RUN
!IS EXTREMELY UNLIKELY TO FILL THE PARTITION ESPECIALLY
!SINCE RUNS WILL CATCH THE QUEUE WELL BEFORE THE UPPER FILE
!LIMIT IS REACHED.
printstring(jtxt."Taking ".file." from ".spool)
newline
file="J".file
copy(spool.".".spoolr file.",".pdstore."_".file)
connect(pdstore, 3, 0, 0, r, flag)
monitor if flag # 0
connect(pdstore."_".file, 0, 0, 0, r, flag)
if flag#0 start
printstring(jtxt."Fails taking file from queue.".snl)
printstring(" see documentation, failure number 2.".snl)
ss=" JOURNAL SYSTEM FAILS FAILURE NO: 2."
byteinteger(addr(ss)+1)=17
oper(0, ss)
autoflag=off; fail type=2
sdisconnect(spool.".".spoolr file, fsys, flag)
requeue file(spoolr file)
stop
finish
!THE FILE HAS BEEN SUCCESSFULLY COPIED INTO JOURNL.
sdisconnect(spool.".".spoolr file, fsys, flag)
remove queued file(spoolr file)
fail file=""
finish
id=integer(r_conad+x'18')
dt = dtword(integer(r_conad+x'14'))
! Note that date in logfile header is STILL in old format (put there by Director).
if id&x'FF' = 0 then integer(r_conad+4)=x'20'
!TO GET ROUND PETES FAULT IN SUPERV.
flag=0
if (id>>8)=x'FFFFFF' start
id=x'FF'&id
if 0<=id<=total indices start
flag=1
if ld<=dt<=hd then flag=2
!IE IS THE DATE AND TIME OK FOR RANGE?
finish
finish
if flag=2 start
if index list(id)_identity#"" start
!WE RECOGNISE THE FILE
file list(id)_files=file list(id)_files+1
count=file list(id)_files
file list(id)_names(count)<-file
file list(id)_dts(count)=dt
if pass=0 start
!ONLY ADD FILE TO PENDING LIST IF NEWLY OFF SPOOLER.
p file count=p file count+1
pending files(p file count)=file
finish
if count=100 start
printstring(jtxt."Filled file space, ")
printstring("Commencing processing!!".snl)
printstring(" Some files will be unordered!!!!".snl)
exit
finish
finish else start
printstring(jtxt.file." not recognised !!".snl)
printstring(" type ".intostr(id)." invalid.".snl)
finish
finish else start
if flag=0 then c
printstring(jtxt.file." not a 'JOURNAL' file!!".snl)
if flag=1 start
printstring(jtxt.file." has bad date/time entry!!".snl)
spaces(10)
printstring(unpackdate(dt)." ".unpacktime(dt).snl)
finish
newlines(2)
send(file.",.LP"); !SEND TO PRINTER IF INVALID FILE.
finish
next:
repeat
!Now sort each queue of pending files into chronological order.
for i=0, 1, total indices cycle
fli == file list(i)
count=fli_files
continue if count=0
for j=1, 1, count-1 cycle
low=j; min=fli_dts(j)
for k=j+1, 1, count cycle
if fli_dts(k)<min start
min=fli_dts(k)
low=k
finish
repeat
if low#j start
name=fli_names(low)
dat=fli_dts(low)
fli_names(low) = fli_names(j)
fli_dts(low)=fli_dts(j)
fli_names(j) = name
fli_dts(j) = dat
finish
repeat
printstring("Index: ".intostr(i));newline
for j=1, 1, count cycle
printstring(fli_names(j)." ". c
unpackdate(fli_dts(j))." ". c
unpacktime(fli_dts(j)))
newline
repeat
repeat
end ; !OF FILE LIST FROM SPOOLR.
routine check file(string (*)name file, byteintegername c
data type, integername flag)
!THE ROUTINE LOOKS FOR DATE AND TIME INFORMATION IN THE FILE
integer word count, i
!
routine reverse line to atoms(integername word count,
stringarrayname atoms, byteintegerarrayname buff)
!HERE WE READ A LINE OF THE FILE INTO AN ARRAY OF "ATOMS" PASSING
!BACK THE RESULTING WORDS(WORD COUNT DEFINING THE NUMBER OF WORDS)
!IN THE ARRAY ATOM.
integer adn
byteinteger ch, i
word count=0; endflag=0; i=0
cycle
chpointer=chpointer-1
if chpointer<flen then endflag=1 and return
ch=buff(chpointer)
exit if ch>32
repeat
cycle
if ch=32 or ch=10 start
if i>0 then byteinteger(adn)=i and i=0
return if ch=10
finish else start
if 32<ch<128 start
if i=0 start
word count=word count+1 unless word count=68
adn=addr(atoms(word count))
finish
i=i&x'7F'+1
!LENGTH OF ATOM SHOULD NOT EXCEED 127, SET TO 1 IF OCCURS!!
byteinteger(adn+i)=ch
finish
finish
chpointer=chpointer-1
if chpointer<flen then endflag=1 and ch=10 c
else ch=buff(chpointer)
repeat
end ; !OF REVERSE LINE TO ATOMS.
start date=""
fail file=file
connect(pdstore."_".file, 0, 0, 0, r, flag)
if flag#0 start
printstring(jtxt."Cannot connect ".file." for date search!".snl)
stop
finish
if datatype=1 or integer(r_conad+x'18')&x'FF'=5 start
!IE WITH A MAPPED DATE FILE OR BACKUP/ARCHIVE REPORT FILE WE KNOW THAT
!THE DATE INFORMATION IS THAT CONTAINED IN WORD 6 OF THE HEADER.
start date="*"
finish date=unpack date(integer(r_conad+x'14'))
finish time=unpack time(integer(r_conad+x'14'))
disconnect(pdstore."_".file, flag)
flag=0
fail file=""
return
finish
buff==array(r_conad+r_datastart, af buff)
flen=r_dataend-r_datastart
chpointer=0
cycle
line to atoms(word count, atoms, buff)
exit if endflag=1
if word count>=3 start
if atoms(1)="DT:" start
start date=atoms(2)
start time=atoms(3)
exit
finish
if atoms(1)="SDT:" start
finish date=atoms(2)
finish time=atoms(3)
start date="*"
exit
finish
finish
repeat
unless start date="*" start
finish date=start date
finish time=start time
chpointer=flen
flen=1
cycle
reverse line to atoms(word count , atoms, buff)
exit if endflag=1
if word count>=3 and atoms(word count)=":TD" start
if length(atoms(word count-1))=length(atoms(word count-2))=8 c
start
for i=8, -1, 1 cycle
byteinteger(addr(finish date)+9-i) c
=byteinteger(addr(atoms(word count-1))+i)
byteinteger(addr(finish time)+9-i)= c
byteinteger(addr(atoms(word count-2))+i)
repeat
length(finish time)=8
length(finish date)=8
exit
finish
finish
repeat
finish
disconnect(pdstore."_".file, flag)
fail file=""
flag=0
end ; !OF CHECK FILE.
routine remove queued file(string (6) file)
!HERE WE TELL SPOOLER TO REMOVE THE SPECIFIED FILE, IE DELETE IT, FROM
!ITHE JOURNAL QUEUE.
integer i
req_dest=x'FFFF003D'
req_flag=0
req_user="JOURNL"
req_file<-file
i=dpon2(spool, req, 1, 6)
if i#0 start
printstring(jtxt."DPON2(3D) error..SPOOLR missing??".snl)
stop
finish
poff file=file
end ; !OF REMOVE QUEUED FILE.
routine requeue file(string (6) file)
!HERE WE REQUEUE A FILE AFTER A PROBLEM.
integer i
req_dest=x'FFFF003D'
req_flag=1
req_file<-file
req_user="JOURNL"
i=dpon2(spool, req, 1, 7)
if i#0 start
printstring(jtxt."DPON(3D) error, SPOOLR missing??".snl)
stop
finish
repa==req; repb==req
flag=repb_flag
if flag #0 start
printstring(jtxt."File: ".file." cannot requeue!".snl)
finish
return
end ; !OF REQUEUE FILE
integerfn autojob(string (15) name, string (*)name ident)
!THIS ROUTINE INTERROGATES SPOOLR TO SEE IF THERE IS A BATCH JOB
!'NAME' IN THE QUEUE AND PASSES BACK ITS IDENTITY.
recordformat fhf(integer end, start, size, type, spare0, datetime,
spare1, spare2)
recordformat infof(integer vsn, state, string (7) ident, user,
string (15) dest, srce, output, string (31) name)
string (63) message
record (infof)name info
record (fhf)name fh
record (f parm)p
integer i, entries, flag
destroy("JJINF", flag)
message="COMMAND QUEUE BATCH,JJINF"
p=0
flag=dspool(p, length(message), addr(message)+1)
if flag#0 start
printstring("SPOOLR fault: no access!!".snl)
respool journal("MONITOR")
stop
finish
connect("JJINF", 0, 0, 0, r, flag)
if flag#0 start
printstring("Cannot connect SPOOLR info file for 'AUTOJOB'".snl)
respool journal("MONITOR")
stop
finish
fh==record(r_conad)
ident=""
entries=(fh_end-fh_start)//256
result =no if entries=0
for i=1, 1, entries cycle
info==record(r_conad+32+(i-1)*256)
if info_name=name and info_state=1 then ident = info_ident and result =yes
repeat
result =no
end ; !OF AUTOJOB.
routine respool journal(string (15) name)
!This routine is used to detach the auto command file that controls
!the Journal system in background mode. The detached files start Journal
!automatically every hour.
string (255) msg
integer flag
string (8) tt, th, timereq; integer hours, j, ocptype
connect("JENGPD_JENGHD", 0, 0, 0, r, flag)
ocptype=16
if flag=0 start
if 0<=integer(r_conad+x'100')<=15 then c
ocptype=integer(r_conad+x'100')
finish
if name = "HOUSEKEEP" then timereq=ocptimereq(ocptype) else timereq = "10"
define("STREAM12,JCMDFILE")
select output(12)
msg = "JOURNAL(AUTOCALL"
if name = "HOUSEKEEP" then msg = msg."+DECK)" else msg = msg.")"
if uinfi(16)=0 start ; ! NOBRACKETS option in force.
charno(msg,8) = ' '
length(msg) = length(msg)-1
finish
printstring(msg)
newline
select output(0)
close stream(12)
disconnect("JCMDFILE", flag)
msg="DOCUMENT DEST=BATCH,USER=JOURNL, PASS=".back pass.", "
msg=msg."SRCE=JCMDFILE,TIME=".timereq.",PRTY=VHIGH,NAME=".name.","
tt=time
tt->th.(".").tt
hours = s to i(th)
hours=hours+1
if hours=24 then tt="23.59.59" else start
th=intostr(hours)
if length(th)=1 then th="0".th
tt=th.".".tt
finish
if name = "HOUSEKEEP" then msg=msg."DECKS=1" else c
msg=msg."AFTER=".date." ".tt
msg = msg.",OUT=FILE,OUTNAME=JJLOG".tostring('0'+nextjjlog)
msg = msg.",RERUN=NO
"
p=0
j=0
j=dspool(p, length(msg), addr(msg)+1)
if j#0 start
printstring("Cannot spool auto command file(".name.") flag:")
write(j, 3) and newline
ss=" JOURNAL SYSTEM FAILS FAILURE NO: 3."
byteinteger(addr(ss)+1)=17; ! Flashing.
fail type=3
autoflag=off
oper(0, ss)
finishelse nextjjlog = (nextjjlog+1)&7; ! Thus 0<=nextjjlog<=7.
end ; !OF RESPOOL JOURNAL
routine start up
!The system state setting from the last run of Journal is looked at
!and based on this a decision is made on the route for the startup of
!this run.
integer i, j
conststring (7)array fail anal(4:7) = "MAINLOG","SPOOLR","VOLUMS","DIRECT"
switch sw(0:4)
if autocall = on and autoflag = off start
!THIS IS AN AUTOMATIC CALL OF JOURNAL BUT IT CANNOT
!PROCEED BECAUSE THE AUTO FLAG HAS BEEN SET TO INDICATE AN ERROR
!CONDITION IS PRESENT FROM THE LAST RUN.
ss=" JOURNAL IN FAIL STATE"
ss=ss." FAILURE NO: ".intostr(fail type)
byteinteger(addr(ss)+1)=17
oper(0, ss)
printstring(jtxt."Fail state ".intostr(fail type))
printstring(" recorded on oper!".snl)
stop
finish
if autocall=on start
!OK TO PROCEED WITH AUTOMATIC RUN OF JOURNAL.
printstring("Automatic Journal run.".snl)
j=minutes between(run date, packdateandtime(date, time))
flag=0
!TEST A: >=24 HRS SINCE LAST RUN AND >16K BYTES IN QUEUE.
if j>=24*60 and queue_amount>16*1024 then flag=1
!TEST B: >=25 FILES IN QUEUE OR >0.8 MEG OF FILES IN QUEUE.
if queue_amount>(800*1025) or queue_length>=25 c
then flag=1
!TEST C:(FOR PRIME TIME ONLY)>=45 FILES OR >2 MEG OF FILES
if queue_amount>(2000*1024) or queue_length>=45 c
then flag=2
printstring("SPOOLR parameters:".snl)
printstring("Files:"); write(queue_length, 3) and newline
printstring("Total size:"); write(queue_amount, 6) and newline
printstring("Minutes since last run:"); write(j, 5) and newline
if prime start<packdate and time(date, time)<prime end start
printstring("We are in prime period.".snl); newline
flag=0 if flag=1
finish
if system state#0 start
printstring(jtxt."Last run incomplete, or failed")
printstring(" (system crash?).".snl)
printstring("Running again to clear problem.".snl)
flag=1
finish
if flag>=1 start
!WE WANT A FULL RUN.
if decks = on then printstring("**Commencing auto run**".snl) C
else start
!DETACH THE JOB TO DO THE FULL RUN.
respool journal("HOUSEKEEP") if autojob("HOUSEKEEP", identj)=off
printstring("Full run detached or already there.".snl)
if identj = "" then flag = autojob("HOUSEKEEP", identj)
!FIND OUT THE IDENTITY IF JUST QUEUED.
flag = 0
ss=" JOURNAL RUN REQUIRED "
ss=ss." RUN ".identj." SOON!"
byteinteger(addr(ss)+1)=17
oper(0, ss)
finish
finish else printstring("**Full run not required**".snl)
stop if flag=0
finish
run date=pack date and time(date, time)
->sw(system state)
sw(0):
!ALL OK IN THE LAST RUN.
if fail type<4 start
printstring(jtxt."Last run of Journal ended normally ".snl)
finish else start
printstring(jtxt."Last run completed housekeeping but the".snl)
printstring("auto ".fail anal(failtype)." analysis failed!!".snl)
finish
return
sw(1):
printstring(jtxt."Restarting from Spooler unloading")
printstring(" failure during previous run".snl)
if fail file#"" start
printstring(jtxt."File: ".fail file." error warning!".snl)
finish else start
printstring(jtxt."No file in error, probably system crash?".snl)
finish
!TRIM DOWN THE PENDING FILE LIST(IE THOSE FILES LEFT OVER FROM FAILURE
!OF THE LAST RUN.)
if p file count>0 start
i=0
cycle
i=i+1; exit if i=p file count+1
if pending files(i)="" start
if i=p file count then p file count=p file count-1 c
and exit
for j=i+1, 1, p file count cycle
pending files(j-1)=pending files(j)
repeat
p file count=p file count-1
i=i-1
finish
repeat
finish
system state=2
!ALLOW RESTART
run tape=1
return
sw(2):
printstring(jtxt."Last run skipped tape dump.".snl)
run tape=1
return
sw(3):
if tapeskip=1 start
if external=off start
printstring(jtxt."The tape dump failed last run.".snl)
printstring(" Skip option not valid after failure!".snl)
stop
finish else start
!IE CALL FROM 'FULL JOURNAL ANALYSIS' ALLOWED TO RUN
!FILE COLLECTION EVEN THOUGH THERE WAS A TAPE CONTINGENCY
!ON THE LAST RUN. THE CONTINGENCY WILL BE RETAINED(UNLESS OF
!COURSE THE FILE COLLECTION FAILS AND THIS HIGHER PRIORITY
!CONTINGENCY IS THEN REMEMBERED)
printstring(jtxt."Last run failed in tape dump".snl)
printstring(" Allowing file collection run for 'FULL")
printstring(" Journal analysis'".snl)
system state=3
return
finish
finish
run tape=1
printstring(jtxt."The tape dumping failed last run.".snl)
if autocall=on start
printstring(" Must have been system crash, proceeding ")
printstring("with file collection.".snl)
system state=2
finish else start
printstring(" Retrying the tape dump.".snl)
system state=4
finish
return
sw(4):
!SHOULD NOT RETURN HERE EXCEPT IN FLUKE "SYSTEM DOWN" SITUATION.
!SHOULD TREAT THIS AS SW(3) TYPE ASSUMING TAPE DUMP TO BE RETRIED.
printstring(jtxt."Retrying tape dump.".snl)
run tape=1
return
end ; !OF START UP.
end ; !OF JOURNAL
! ************************************************************************
! ************************************************************************
! ************************************************************************
externalroutine journal state(string (255) s)
record (f queue)name queue
record (f tape cycle)arrayformat af tape cycle(1:100)
record (f tape cycle)arrayname tape cycle
record (rf)r
integer j, i, status, flag, autoflag, fail type, queues, k, latedate
string (8) tdate, ttime
newpage
printstring("Journal status report ".date." ".time)
newline
connect(control, 0, 0, 0, r, flag)
if flag#0 then master file failure(control, flag)
status=integer(r_conad+x'24')
autoflag=integer(r_conad+x'6DC')
fail type=integer(r_conad+x'6D8')
tdate=unpack date(integer(r_conad+x'20'))
ttime=unpack time(integer(r_conad+x'20'))
printstring("Last run on ".tdate." at ".ttime);newline
j = -1; latedate = 0
for i=0,1,7 cycle
connect("JJLOG".tostring('0'+i), 0, 0, 0, r, flag)
continue if flag#0
k = integer(r_conad+20)&x'7FFFFFFF'; ! Time last changed.
j = i and latedate=k if k>latedate
repeat
if j=-1 then printstring("No autojob logfiles found") else c
printstring("Last autojob logfile: JJLOG".tostring('0'+j))
newlines(2)
printstring("Status details: ")
if autoflag=1 start
if status=0 start
printstring("In automatic housekeeping mode.");newline
printstring("Action required: none.");newlines(2)
finish else start
printstring("Last auto housekeeping failed, recovery will ")
newline; printstring(" be attempted automatically.")
newline; spaces(16);printstring("[")
printstring(journal status(status)."]");newline
printstring("Action required: none.");newlines(2)
finish
finish else start
if fail type=0 start
printstring("In manual mode with an unexplained error or after")
newline;printstring(" a System crash.");newline
spaces(16);printstring("[")
printstring(journal status(status)."]")
newline
printstring("Action required: JOURNAL OVERRIDE in JOURNL process.")
newlines(2)
finish else start
printstring("In manual mode due to failure, doc ref: ")
write(failtype, 2);newline; printstring("Action required: ")
printstring("see Journal documentation.");newlines(2)
finish
finish
connect(spool.".CFILE", 9, 0, 0, r, flag)
if flag#0 start
!WE CANNOT CONNECT THE SPOOLR INFO FILE.
printstring("Spoolr descriptor file (CFILE) connect fails:")
write(flag, 3); newline
printstring("Log off and try again.")
newline
stop
finish
queues=integer(r_conad+x'18')
if queues=0 start
printstring("No queues defined in SPOOLR descriptor file")
newline
finish
for i=1, 1, queues cycle
queue==record(r_conad+x'20'+148*(i-1))
if queue_name="JOURNAL" then exit
if i=queues start
printstring("Journal queue not in SPOOLR descriptor file")
newline
finish
repeat
printstring("Current state of the 'JOURNAL' queue:");newline
printstring("Files:"); write(queue_length, 3)
printstring(" Total bytes:"); write(queue_amount, 6)
newline
connect(control, 0, 0, 0, r, flag)
if flag#0 then master file failure(control, flag)
!NOW ADD THE DETAILS FROM THE TAPE CONTROL .
j=0
newline
printstring("Tape cycle: there are ");write(integer(r_conad+x'700'), 3)
printstring(" tapes in the cycle.")
newline
if integer(r_conad+x'700')>0 start
!THERE ARE TAPES IN THE CYCLE TO DESCRIBE.
tape cycle==array(r_conad+x'720', af tape cycle)
if integer(r_conad+x'708')>0 start
!THERE IS AN ASSIGNED MASTER , IE. SYSTEM IN USE.
printstring("Master tape: ")
printstring(tape cycle(integer(r_conad+x'708'))_tsn)
printstring(" with a total of "); write(integer(r_conad+x'710'), 4)
printstring(" chapters, "); write(integer(r_conad+x'714'), 4)
printstring(" epages.")
newline
finish
newline; printstring("Full tape cycle list:")
newline
for i=1, 1, integer(r_conad+x'700') cycle
j=j+1
printstring("TSN:".tape cycle(i)_tsn." ")
if tape cycle(i)_age=-1 then printstring("master tape")
if tape cycle(i)_age=0 then printstring("unused tape")
if tape cycle(i)_age>0 then printstring("full tape ")
if j=3 then newline and j=0 else spaces(3)
repeat
finish
newlines(2)
printstring("End of system summary.")
newline
disconnect(control, flag)
end ; !OF JOURNAL STATE.
! ************************************************************************
! ************************************************************************
externalroutine list journal index(string (255) s)
! Parameter can be "dd/mm/yy,dd/mm/yy" (either or both optional), to
! specify the range of files of interest.
record (f index entry)arrayformat af index entry(0:index top)
record (f index list)arrayformat af index list(0:total indices)
record (f index entry)arrayname index entry
record (f index entry)name ie
record (f index list)arrayname index list
record (rf)r
conststring (40) array status description(0:9)= c
"ON LINE",
"ON LINE AND ON TAPE: ",
" ON TAPE: ",
"", "", "", "", "", "",
"LOST!!!!!!!!!"
string (8) index, tdate, ttime
string (16) reply
byteinteger id, data type
integer i, flag, status, entry, lost flag, early, late
connect(control, 0, 0, 0, r, flag)
if flag#0 then master file failure(control, flag)
index list==array(r_conad+x'30', af index list)
early = pack date and time("01/01/72","00.00.00")
late = current packed dt
if s#"" start ; ! Date range specified.
if s -> s.(",").reply start
if length(reply)=8 and charno(reply,3)='/' and charno(reply,6)='/' c
then late = pack date and time(reply,"23.59.59")
finish
if length(s)=8 and charno(s,3)='/' and charno(s,6)='/' then c
early = pack date and time(s,"00.00.00")
finish
if early>late start
printstring(jtxt."Early date is after late date??")
newline
return
finish
cycle
!Find out which file is to be listed.
prompt("INDEX KEYWORD:")
read prompt reply(reply)
if reply="HELP" start
printstring(jtxt."Current index keywords:"); newlines(2)
for i=0, 1, total indices cycle
!LIST OUT THE INDEX KEYWORDS.
if index list(i)_identity#"" then c
printstring(index list(i)_identity) and newline
repeat
return
finish
identify index(reply, id, data type, entry)
!FIND THE IDENTITY CHARACTER OF THIS INDEX.
exit if id#100
printstring(jtxt."Reply help for a list of keywords")
newline
repeat
index="JJ#".intostr(id)."DEX"
!THE INDEX FILE
connect(index, 0, 0, 0, r, flag)
if flag#0 then master file failure(index, flag)
define("STREAM10,JLIST,1024")
select output(10)
printstring(jtxt."List of index ".index.". ".date." ".time)
newline
printstring("===================================================")
newlines(2)
printstring("Date range: ".unpackdate(early)." - ".unpackdate(late))
newlines(2)
printstring("Index keyword: ".reply)
newlines(3)
lost flag = 0; ! Used to prevent repeated "file lost" output.
index entry==array(r_conad+x'40', af index entry)
for i=0, 1, index top cycle
ie == index entry(i)
exit if ie_file id=-1
! IE THE CURRENT TOP OF THE INDEX.
continue if ie_finishing<early or ie_starting>late; ! File not in requested range.
if ie_status=9 start
if lost flag=1 start
printstring(" ..... all lost up to .....")
newline
finish
lost flag = lost flag+1
continue if lost flag>1
finish else lost flag = 0
printstring("File: ")
write(ie_file id, 5)
tdate=unpack date(ie_starting)
ttime=unpack time(ie_starting)
printstring(" ".tdate." ".ttime." to ")
tdate=unpack date(ie_finishing)
ttime=unpack time(ie_finishing)
printstring(tdate." ".ttime." status: ")
status=ie_status
printstring(status description(status))
if 1<=status<=2 then printstring(ie_tape) c
and printstring("(".intostr(ie_chapter).")")
newline
repeat
newlines(2)
printstring(jtxt."End of list of index: ".index)
newlines(3)
select output(0)
close stream(10)
printstring(jtxt."List prepared in JLIST.")
newlines(2)
disconnect(index, flag)
disconnect(control, flag)
end ; !OF LIST JOURNAL INDEX
! ************************************************************************
! ************************************************************************
! *************************************************************************
externalroutine new journal index(string (255) s)
!STRING S WILL ONLY BE SET WHEN THE ROUTINE IS CALLED FROM
!"CREATE JOURNAL SYSTEM" WITH S='SYSTEM'. IN THIS CASE ALL THE SYSTEM
!INDICES ARE INITIALISED. ON A NORMAL CALL S IS NOT SET AND A SET
!OF PROMPTS ARE USED TO DEFINE THE INDEX TO BE SET UP.
record (f index list)arrayformat af index list(0:total indices)
record (f index entry)arrayformat af index entry(0:index top)
record (f index list)arrayname index list
record (f index entry)arrayname index entry
record (rf)r
integer i, j, k, flag, entry, data
string (16) reply, dtype
byteinteger id char, data type
integerfn empty slot(integer type)
!FIND THE NEXT EMPTY INDEX SLOT IN JJMASTER THAT WILL
!DEFINE THE IDENTITY OF THE NEW INDEX.
integer i, j
if type=0 then j=0 else j=system indices+1
for i=j, 1, total indices cycle
if index list(i)_identity="" then result =i
repeat
result =-1
end ; !OF EMPTY SLOT.
routine new index(byteinteger id char, integername flag)
!CREATE AND INITIALISE A NEW INDEX DEFINED BY ID CHAR
!FLAG=0: SUCCESS, FLAG=1: FAILURE.
record (f index entry)name ie0
string (8) file
integer i, conad, cflag
file="JJ#".intostr(id char)."DEX"
flag=1; !DEFAULT FAILURE.
connect(file, 0, 0, 0, r, cflag)
if cflag=0 start
printstring(jtxt.file." already exists")
newlines(2)
return
finish
create jfile(file, index top+1 {cells}, 24 {cell size}, x'40' {header},
conad, cflag)
if cflag#0 start
printstring(jtxt."Cannot create ".file." flag:")
write(cflag, 3)
newlines(2)
return
finish
integer(conad+x'20')=0; !NEXT FREE INDEX ENTRY, ALSO USED AS POINTER TO LAST(+1) FILE FOR AUTO ANALYSIS.
integer(conad+x'24')=0; !NEXT FREE SEQUENCE NO.
integer(conad+x'28')=0; !NEXT FILE ENTRY TO BE PROCESSED BY AUTO ANAL.
integer(conad+x'2C')=0; !The oldest file on the index pointer.
index entry==array(conad+x'40', af index entry)
ie0 == index entry(0)
ie0_file id=-1
ie0_starting = current packed dt
ie0_finishing=ie0_starting
ie0_status=8
ie0_chapter=-1
ie0_tape=""
index entry(i) = ie0 for i=1,1,index top
disconnect(file, flag)
cherish(file)
printstring(jtxt."File recognition number for ".file." is: ")
write(id char, 3)
newline
flag=0; !SUCCESSFUL.
end ; !OF NEW INDEX
connect(control, 3, 0, 0, r, flag)
if flag#0 then master file failure(control, flag)
index list==array(r_conad+x'30', af index list)
!THE INDEX CONTROL LIST.
if s="SYSTEM" start
!A CALL FROM 'CREATE JOURNAL SYSTEM' TO INITIALISE SYSTEM INDICES.
for i=0, 1, used system indices cycle
!CREATE EACH OF THE SYSTEM INDICES.
j=empty slot(0)
!THE NEXT EMPTY INDEX SLOT.
if j#i start
!NO INDICES SHOULD ALREADY EXIST.
printstring(jtxt."Severe warning, do not attempt ")
printstring("to recreate system indices!!!")
newlines(2)
disconnect(control, flag)
return
finish
id char=index list(j)_id char
!THE IDENTITY CHARACTER OF THE NEW INDEX.
new index(id char, flag)
if flag#0 start
printstring(jtxt."Failed to create system index!")
newline
for k=1, 1, i cycle
exit if k=i
destroy("JJ#".intostr(index list(k)_id char)."DEX", flag)
!DESTROY ALL THE ALREADY CREATED SYSTEM INDICES.
index list(k)_identity=""
repeat
disconnect(control, flag)
destroy(control, flag)
!DESTROY JJMASTER AS WELL TO GIVE CLEAN RETRY.
printstring(jtxt."Try running create again after checking")
printstring(" over the process")
newlines(3)
stop
finish
index list(j)_identity<-system keyword(i)
index list(i)_data type=0; !DEFAULT VALUE OF 'TEXT'.
if system keyword(i)="ACCOUNTS" then index list(i)_data type=1
!IE THIS IS A MAPPED DATA TYPE FILE.
printstring(jtxt.system keyword(i)." index initialised")
newlines(2)
repeat
printstring(jtxt."All system indices created.")
newlines(3)
disconnect(control, flag)
return
finish ; !OF "SYSTEM" JOURNAL INDICES CREATION.
!BELOW CODE WILL ADD INSTALLATIONS OWN INDEX.
!WHICH WILL BE INDICES 10-19, OR IT WILL BE USED
!TO ADD A NEW SYSTEM INDEX (RANGE 0-9)
cycle
prompt("SYS OR OWN:")
read prompt reply(reply)
exit if reply="SYS" or reply="OWN"
repeat
if reply="SYS" then j=empty slot(0) else j=empty slot(1)
cycle
prompt("INDEX KEYWORD:")
read prompt reply(reply)
exit if 0<length(reply)<=12
printstring(jtxt.reply." too long??")
newlines(2)
repeat
data=-1
cycle
prompt("TEXT OR MAPPED:")
read prompt reply(dtype)
data=0 if dtype="TEXT"
data=1 if dtype="MAPPED"
exit if data#-1
repeat
if j=-1 start
printstring(jtxt."System full, no further indices.")
newlines(2)
return
finish
identify index(reply, id char, data type, entry)
if id char<100 start
printstring(jtxt."Keyword already used!!")
newlines(2)
return
finish
id char = index list(j)_id char
new index(id char, flag)
!CREATE THE NEW INDEX DEFINED BY ID CHAR.
if flag#0 start
printstring(jtxt."Failed to create ".reply." index!")
newlines(2)
return
finish
index list(j)_identity<-reply
index list(j)_data type<-data
!FILL IN THE KEYWORD NOW INDEX CREATED.
printstring(jtxt.reply." index initialised.")
newlines(3)
disconnect(control, flag)
end ; !OF NEW JOURNAL INDEX.
! ************************************************************************
! ************************************************************************
! ************************************************************************
externalroutine new journal tape(string (255) s)
record (f tape cycle)arrayformat af tape cycle(1:100)
record (f tape cycle)arrayname tape cycle
record (rf)r
integer i, flag
integername tape count
string (16) reply
!THE CONTROL MASTER FILE.
connect(control, 3, 0, 0, r, flag)
!WE WANT TO WRITE TO IT.
if flag#0 then master file failure(control, flag)
tape count==integer(r_conad+x'700')
!THE TOTAL TAPES IN THE CYCLE.
cycle
!GET THE TAPE IDENTITY TO BE ADDED TO THE CYCLE.
prompt("JOURNAL TAPE:")
read prompt reply(reply)
if length(reply)=6 then exit
!CORRECT LENGTH TSN.
repeat
tape cycle==array(r_conad+x'720', af tape cycle)
if tape count=0 start
!THERE ARE NO TAPES ON CYCLE AT THE MOMENT.
tape cycle(1)_tsn<-reply
tape cycle(1)_age=0
tape count=1
finish else start
!THERE ARE TAPES ALREADY IN THE CYCLE.
for i=1, 1, tape count cycle
!CHECK TAPE NOT ALREADY THERE.
if tape cycle(i)_tsn=reply start
printstring(jtxt.reply." already in cycle")
newlines(2)
return
finish
repeat
for i=1, 1, 100 cycle
!NOW SLOT IN THE NEW TAPE.
if tape cycle (i)_tsn="" start
!WE HAVE FOUND EMPTY SLOT.
tape cycle(i)_tsn<-reply
tape cycle(i)_age=0; !UNUSED.
tape count=tape count+1
exit
finish
repeat
finish
printstring(jtxt.reply." added to cycle with new total of ")
write(tape count, 2)
printstring(" tapes.")
newlines(2)
disconnect(control, flag)
end ; !OF NEW JOURNAL TAPE.
! ************************************************************************
! ************************************************************************
! ************************************************************************
externalroutine remove journal index(string (255) s)
record (f index list)arrayformat af index list(0:total indices)
record (f index list)arrayname index list
record (rf)r
string (16) reply
byteinteger id char, data type
integer flag, entry
cycle
!FIND THE IDENTITY OF THE INDEX TO BE REMOVED.
prompt("INDEX KEYWORD:")
read prompt reply(reply)
exit if 0<length(reply)<=12
printstring(jtxt.reply." too long??")
newlines(2)
repeat
identify index(reply, id char, data type, entry)
if id char=100 start
printstring(jtxt.reply." not valid keyword")
newlines(2)
return
finish
connect(control, 3, 0, 0, r, flag)
if flag#0 then master file failure(control, flag)
index list==array(r_conad+x'30', af index list)
index list(entry)_identity=""
!THE INDEX ENTRY IS REMOVED.
destroy("JJ#".intostr(id char)."DEX", flag)
disconnect(control, flag)
printstring(jtxt."Index removed.")
newlines(2)
end ; !OF REMOVE JOURNAL INDEX
! *****************************************************************************
! *****************************************************************************
! *****************************************************************************
externalroutine journal backpass(string (255) s)
externalintegerfnspec dsetpassword(string (6) user, integer fsys, which,
string (63) old, new)
string (63) forepass, backpass
record (rf) r
integer i, flag
connect(control, 3, 0, 0, r, flag)
if flag#0 start
printstring("Unable to connect ".control)
newline
return
finish
printstring("Background password currently stored by Journal: ".c
string(r_conad+x'27D0'))
newline
printstring("If this is satisfactory, exit by replying '*' to the first prompt.")
newlines(2)
printstring("Give current foreground password, then new background password.")
newline
for i = 1,1,3 cycle
prompt("Foreground:")
read prompt reply(fore pass)
flag = 1 and exit if fore pass="*"
prompt("New back:")
read prompt reply(back pass)
if length(back pass)>11 start
printstring("**Warning: reduced to first 11 characters.")
newline
length(back pass) = 11
finish
flag = dsetpassword("JOURNL",-1,1,fore pass, back pass)
exit if flag=0
printstring("Failed!! You get 3 tries. That was try no.")
write(i,1); newline
repeat
if flag#0 start
printstring("Background password unchanged.")
finishelsestart
string(r_conad+x'27D0') = back pass
printstring("New background password now in use.")
finish
newline
end ; ! Of %external %routine journal backpass.
!**************************************************************************
! ROUTINES AND FUNCTIONS COMMON TO THE SYSTEM.
!**************************************************************************
routine identify index(string (*)name keyword, byteintegername c
id char, data type, integername entry)
!HERE WE ARE GIVEN AN INDEX IDENTITY KEYWORD IE 'ERRORLOG' AND
!WE SEARCH TO SEE IF IT IS VALID, IF IT IS WE PASS BACK THE
!IDENTITY OF THE INDEX IN THE RANGE '0' TO '99' WHICH DEFINES THE
!INDEX IE JJ'8'DEX ELSE WE PASS BACK A DEFAULT FAIL VALUE OF -1.
record (f index list)arrayformat af index list(0:total indices)
record (f index list)arrayname index list
record (rf)r
string (16) file
integer i, flag
file="JJMASTER"
connect(file, 0, 0, 0, r, flag)
if flag#0 then master file failure(file, flag)
index list==array(r_conad+x'30', af index list)
for i=0, 1, total indices cycle
if index list(i)_identity=keyword start
id char=index list(i)_id char
data type=index list(i)_data type
entry=i
return
finish
repeat
id char=100; !IE FAILED TO FIND MATCHING KEYWORD.
end ; !OF IDENTIFY INDEX.
routine line to atoms(integername word count,
stringarrayname atoms, byteintegerarrayname buff)
!HERE WE READ A LINE OF THE FILE INTO AN ARRAY OF "ATOMS" PASSING
!BACK THE RESULTING WORDS(WORD COUNT DEFINING THE NUMBER OF WORDS)
!IN THE ARRAY ATOM.
integer adn
byteinteger ch, i
word count=0; endflag=0; i=0
cycle
chpointer=chpointer+1
if chpointer>flen then endflag=1 and return
ch=buff(chpointer)
exit if ch>32
repeat
cycle
if ch=32 or ch=10 start
if i>0 then byteinteger(adn)=i and i=0
return if ch=10
finish else start
if 32<ch<128 start
if i=0 start
word count=word count+1 unless word count=68
adn=addr(atoms(word count))
finish
i=i&x'7F'+1
!LENGTH OF ATOM SHOULD NOT EXCEED 127, SET TO 1 IF OCCURS!!
byteinteger(adn+i)=ch
finish
finish
chpointer=chpointer+1
if chpointer>flen then endflag=1 and ch=10 c
else ch=buff(chpointer)
repeat
end ; !OF LINE TO ATOMS.
routine master file failure(string (*)name file, integer flag)
!HERE WE PRINT THE WARNING OF A FAILURE(MISSING) MASTER FILE
!AND STOP THE SYSTEM.
printstring(jtxt.file." lost, major fault. Flag: ")
write(flag, 2)
newlines(2)
stop
end ; !OF JJMASTER FAILURE.
endoffile