d $	!		C H R O N O S
 $	!						Version V3.0
,$
$ 	verify = 'F$Verify(0)'
$	Set NoOn
X$	Set Process /Priority=5				   ! <<<<<<<<<<
$	On Control_Y	THEN GOTO cleanup
 $
$ !	This command file looks up the file CHRONICLE.DAT
$ !	and starts all commands for the current day. It
L$ !	leaves a record of what it has done in CHRON.LOG
$ !	Try     @CHRONOS HELP   for help
$ !	or read CHRONOS:chronos.doc
x$
$ !	The lines that you may wnat to change are marked   ! <<<<<<<<<<
@$
$ !						CHRONOS.COM
$ !		Change the name of this file at your peril !
l$
$
4$
$ !	Copyright (c)1982 ,	INMOS Corp.,
.	$ !
`	$ !	  Date		Programmer	 Description
	$ !
(
$ !	 1 Oct 82	B. Lee Jones	Version 3.0
$ !
$
$
$	! Define chronos' default directory
H$
$	Assign disk$system:[chronos]  CHRONOS_DIR:	! <<<<<<<<<<
$	chron_queue := "CONTROL"			! <<<<<<<<<<
t$
$
<$	! The following four assignments are used to check
$	! that the person running  this file is also the 
$	! nominated owner of the CHRONOS system.
h$
$	! (In this case the owner is PRODUCTION who has a UIC of [4,0]
0$
$	! The UIC of [10,40] is the 'user' that runs SYSTARTUP at
$	! boot time.
\$
$	! All this is done not only for security, but to reduce the
$$	! problems of file ownership to a minimum.
$
$
P$	sysexe := [10,40]
$	owner := [4,0]					! <<<<<<<<<<
$	ownername := PRODUCTION				! <<<<<<<<<<
|$
$	user := 'F$User()'
D$
$				! SYSTARTUP thinks it's a batch job
$
p$	interactive = "''F$Mode()'" .EQS. "INTERACTIVE" .OR. 	-
			user .EQS. sysexe
8$	batch = .NOT. interactive
$
 $	here := 'F$Logical("SYS$DISK")''F$Directory()'
d$ 
$	IF user .EQS. sysexe	THEN Set UIC 'user'
,$
$
$	Set Default CHRONOS_DIR:
X$
$	lenp1 = 'F$Length(P1)'
 $
$	IF P1 .EQS. "S"		THEN GOTO  notuniq
$
L$	IF P1  .EQS.  "''F$Extract(0,lenp1,"SHOW")'"	THEN  GOTO  show
$	IF P1  .EQS.  "''F$Extract(0,lenp1,"ALL")'"	THEN  GOTO  startall
$	IF P1  .EQS.  "''F$Extract(0,lenp1,"CHRONOS")'"	THEN  GOTO  startchronos
x$	IF P1  .EQS.  "''F$Extract(0,lenp1,"START")'"	THEN  GOTO  startlater
$	IF P1  .EQS.  "''F$Extract(0,lenp1,"HELP")'"	THEN  GOTO  help
@$	IF P1  .EQS.  "''F$Extract(0,lenp1,"LIST")'"	THEN  GOTO  list
$
 $	Write SYS$OUTPUT "%%CHRONOS-F-INVPAR, parameter error"
l $	Write SYS$OUTPUT "  \''P1'\"
 $ GOTO end
4!$
!$ notuniq:
!$	Write SYS$OUTPUT "%%CHRONOS-F-AMBIGKEYW, parameter not unique"
`"$	Write SYS$OUTPUT "  \''P1'\"
"$ GOTO end
(#$
#$
#$ help:
T$$	@CHRONOS_DIR:chronos.hlp  'P2'
$$ GOTO end
%$
%$
%$ list:			! Can be improved and formatted as required
H&$	Print /Header  CHRONOS_DIR:chronicle.dat
&$ GOTO end
'$
t'$
'$ show:
<($	action := "show"
($ GOTO main
)$
h)$ startchronos:
)$	! IF user .NES. owner 	THEN  GOTO end
0*$
*$	Submit /Priority=5 /After=23:59 /Queue='chron_queue' /Parameter=all  CHRONOS_DIR:chronos
*$
\+$	Write SYS$OUTPUT "%%CHRONOS-I-CRES, will run again tonight"
+$ GOTO end
$,$
,$
,$ startall:
P-$	IF user .NES. owner	THEN GOTO end
-$
.$	IF batch 	THEN wait 0:1:10	! usually run at
|.$						! midnight but the
.$						! closest we can get is
D/$						! 23:59 so wait a bit
/$	action := "startall"
0$ GOTO startgen
p0$
0$
81$ startlater:
1$	IF user .NES. owner 	.AND. user .NES. sysexe  -
 2	THEN  GOTO end
d2$
2$	action := "startlater"
,3$ GOTO startgen
3$
3$
X4$
4$ startgen:		! general start procedure
 5$
5$
5$	!	First check if CHRONOS is still in a queue
L6$
6$	Open  /Write /Error=bq_error bq showq.tmp
7$	Assign /User  bq  SYS$OUTPUT
x7$	Show Queue /All /Batch
7$	Close bq
@8$
8$	Open /Error=bq_error /Read bq  showq.tmp
9$
l9$			! Check for a non-current job owned by 'owner'
9$			! with a name of CHRONOS in the batch queues
4:$	ccloop:
:$		Read /end=ccend  bq  rec
:$
`;$		IF 'F$Locate("CHRONOS",rec)' .EQ. 'F$Length(rec)'  -
;		.OR. 'F$Locate(ownername,rec)' .EQ. 'F$Length(rec)'  -
(<		.OR. 'F$Locate("CURR",rec)' .NE. 'F$Length(rec)'  -
<		THEN GOTO ccloop
<$
T=$			Close bq
=$			Delete /NoLog showq.tmp.*
>$			Write SYS$OUTPUT "%%CHRONOS-I-CSIQ, chronos still in queue"
>$
>$		GOTO end
H?$
?$	ccend:
@$
t@$	Close bq
@$	Delete /NoLog showq.tmp.*
<A$
A$		!	Now set the log file
B$
hB$	Open /Write  /Error=log_error log  CHRONOS_DIR:chronday.log
B$	Assign  log  sys$output
0C$
C$	Write  log  "CHRONOS V3: run at ''F$Time()'   User = ''user'"
C$
\D$ GOTO main
D$
$E$
E$
E$
PF$
F$ main:			!  Where it all happens
G$
|G$	!	First get todays date and set up the variables
G$
DH$	date := "''F$Time()'"
H$
I$	dom  = 'F$Extract(0, 2, date)'
pI$	mth := "''F$Extract(3, 3, date)'"
I$	year = 'F$Extract(7, 4, date)'
8J$	cent = 'F$Extract(7, 2, date)'
J$	yr   = 'F$Extract(9, 2, date)'
 K$	hr   = 'F$Extract(12, 2, date)'
dK$	min  = 'F$Extract(15, 2, date)'
K$
,L$	!	Set the numeric value of mth
L$
L$	!	First set up the month values
XM$
M$
 N$	mthnjan =  1
N$	mthnfeb =  2
N$	mthnmar =  3
LO$	mthnapr =  4
O$	mthnmay =  5
P$	mthnjun =  6
xP$	mthnjul =  7
P$	mthnaug =  8
@Q$	mthnsep =  9
Q$	mthnoct = 10
R$	mthnnov = 11
lR$	mthndec = 12
R$
4S$	mthn = mthn'mth'
S$
S$	!	Show parameters can change this so....
`T$
T$	IF action .NES. "show" 	THEN GOTO notshow
(U$
U$		IF P2 .NES. "" 	THEN dom = 'P2'
U$		IF P3 .NES. "" 	THEN mthn = 'P3'
TV$	notshow:
V$
W$	!	Calculate the last day of the month
W$
W$
HX$	days_in_1  = 31
X$	days_in_2  = 28
Y$	days_in_3  = 31
tY$	days_in_4  = 30
Y$	days_in_5  = 31
<Z$	days_in_6  = 30
Z$	days_in_7  = 31
[$	days_in_8  = 31
h[$	days_in_9  = 30
[$	days_in_10 = 31
0\$	days_in_11 = 30
\$	days_in_12 = 31
\$
\]$	days_in_mth = days_in_'mthn'
]$
$^$	IF "''mth'" .NES. "FEB"	THEN GOTO not_feb
^$		leap_year = ( (year / 4)*4) .EQ. year
^$		IF leap_year	THEN days_in_mth = 29
P_$	not_feb:
_$
`$	!	Calculate day-of-week
|`$
`$	!	The formula used is :-
Da$	!    dow = ( [2.6M - 0.2]  + D + Y + [Y/4] + [C/4] - 2C) mod 7
a$
b$	!	Where :-	D = day of month
pb$	!			M = month taking March = 1 and Jan & Feb
b$	!			    11 & 12 of the previous year
8c$	!			C = century (first 2 digits of year)
c$	!			Y = year (The second 2)
 d$
dd$	!	and [ brackets ] meaning truncation of fraction
d$
,e$
e$
e$
Xf$	dcent = cent
f$	dyr = yr
 g$
g$	dmthn = mthn - 2
g$
Lh$	IF dmthn .GT. 0 	THEN GOTO dmthnok
h$
i$		!	Jan & Feb = 11 & 12 of last year 
xi$
i$		dmthn = dmthn + 12
@j$		dyr = dyr - 1
j$
k$		IF dyr .GT. 0 	THEN GOTO dyrok
lk$			dcent = dcent - 1
k$			dyr = dyr + 100
4l$		dyrok:
l$
l$	dmthnok:
`m$
m$
(n$	t1 = ( 26 * dmthn - 2 ) / 10
n$	t2 =  dyr / 4
n$	t3 = dcent / 4
To$	t4 = t1 + t2 + t3 + dom + dyr - ( 2 * dcent )
o$
p$	IF t4 .LT. 0	THEN t4 = t4 + 196	! The rules say so
p$
p$	t5 = t4 / 7
Hq$
q$	down = t4 - ( t5 * 7 )
r$
tr$	dow0 := SUN
r$	dow1 := MON
<s$	dow2 := TUE
s$	dow3 := WED
t$	dow4 := THU
ht$	dow5 := FRI
t$	dow6 := SAT
0u$
u$	dowvar := "'dow''down'"
u$	dow := 'dowvar'
\v$
v$
$w$	IF action .EQS. "show"	-
w	THEN Write SYS$OUTPUT "Chronicled for ''dow' ''dom'/''mthn'/''yr'"
w$
Px$	!	Now set up the things for fields to match
x$
y$	match1  =  'down'
|y$	match2  =  'dom'
y$	match3  =  'mthn'
Dz$
z$
{$	!	Now open the chronicle and see whats to do
p{$
{$	max_field = 8
8|$
|$	Open /Read /Error=chrontaberror chrontab  CHRONOS_DIR:chronicle.dat
 }$	Read  chrontab  ignoreheading
d}$
}$	chrecloop:
,~$		Read /End_of_File=chrecend  chrontab  chrec
~$
~$	!	Extract the fields and put them in field1 .. field'max_field'
X$
$		N = 0
 $		reclen = 'F$Length(chrec)'
$		IF reclen .EQ. 0	THEN GOTO chrecloop
$
L$		extractloop:
$			N = N + 1
$			IF N .GE. 'max_field'	THEN GOTO extractend
x$
܂$			field'N' := ""
@$
$			IF chrec .EQS. ""	THEN GOTO extractloop
$
l$			!	Skip leading spaces ( and tabs )
Є$
4$			skiploop:
$				ch := 'F$Extract(0,1,chrec)'
$
`$				IF ch .NES. " "   .AND.	-
Ć				   ch .NES. "	" 	-
(				THEN  GOTO  skipend
$
$				reclen = reclen - 1
T$				chrec := 'F$Extract(1,reclen,chrec)'
$			GOTO skiploop
$			skipend:
$
$			sp = 'F$Locate(" ",chrec)'
H$			tab = 'F$Locate("	",chrec)'
$
$			IF tab .LT. sp	THEN  sp = tab
t$
؋$			field'N' := 'F$Extract(0,sp,chrec)'
<$
$			reclen = reclen - sp + 1
$			sp = sp + 1
h$			chrec := 'F$Extract(sp,reclen,chrec)'
̍$		GOTO extractloop
0$		extractend:
$
$		field'max_field' := 'chrec'		! the rest of the line
\$
$	!	Now we have the fields, see what matches
$$
$		
$		IF field7 .EQS. ""	THEN GOTO chrecloop		!	No command file?
P$
$ !	<field> ::= * | <field-list> | <value>:<value> | <value>
$
|$ !	See CHRONOS_DIR:chronos.doc
$
D$		N = 0
$
$		fieldloop:		! <field> ::= 
p$			N = N + 1
Ԕ$			IF N .GT. 3	THEN GOTO fieldend
8$
$			f := "'field''N'"
 $			m := "'match''N'"
d$
Ȗ$			field := 'f'
,$			match := 'm'
$
$			flen = 'F$Length(field)'
X$
$						!    * |
 $
$			IF 'F$Locate("*",field)' .NE. flen	-
			THEN GOTO fieldloop
L$
$			listloop:
$
x$				IF field .EQS. "" 	-	! No match
ܛ				THEN GOTO  chrecloop
@$
$						! <field-list> |
$
l$				itemend = 'F$Locate(",",field)'
Н$				item := 'F$Extract(0,itemend,field)'
4$				flen  = flen - itemend - 1
$				eoffset = itemend + 1
$
`$				field := 'F$Extract(eoffset,flen,field)'
ğ$
($					!  <value>:<value> |
$
$				startval := 'item'
T$
$				endval   := 'item'
$				colon = 'F$Locate(":",item)'
$
$				IF colon .EQ. itemend	-
H				THEN GOTO nocolon
$
$				startval = 'F$Extract(0,colon,item)'
t$
ؤ$				eve = itemend - colon - 1
<$				eoffset = colon + 1
$
$				endval = 'F$Extract(eoffset,eve,item)'
h$
̦$			nocolon:
0$						! <value>
$				!	Check for negative values (for mth)
$
\$				IF startval .LE. 0 .AND N .EQ. 2	-
				THEN startval = days_in_mth + startval + 1
$$
$				IF endval .LE. 0 .AND N .EQ. 2	-
				THEN endval = days_in_mth + endval + 1
P$
				IF (match .GE. startval)  .AND.	-
				   (match .LE. endval  )	-
|				THEN GOTO fieldloop
$
D$			GOTO listloop
$			listend:
$
p$		GOTO fieldloop
ԭ$		fieldend:
8$
$
 $		IF action .EQS. "show"	THEN GOTO display
d$		IF action .EQS. "startall"	THEN GOTO submit
ȯ$		IF ACTION .EQS. "startlater"	THEN GOTO checksubmit
,$
$		Write SYS$OUTPUT "%%CHRONOS-F-CHRONIC, error in main"
$		Exit
X$
$	display:
 $		Write SYS$OUTPUT "For user ''field6' 	:  Submit /After=''field4':''field5' 	''field7' 	''field8'"
$	GOTO chrecloop
$
L$
$	checksubmit:
$		IF field4 .GT. hr  .OR.	-
x		   field4 .EQ. hr .AND.field5 .GT. min	-
ܴ		THEN GOTO submit
@$
$	GOTO chrecloop
$
l$	submit:
ж$		Write log "For user ''field6' 	:  Submit /After=''field4':''field5' 	''field7' 	''field8'"
4$	Goto 'Field6'_Name
$	Goto Clean_Up			! Error in name - must create new image
$Sysacct_Name:
`$	Run Ssexe:Sysacct
ĸ$	Goto After_Name
($Operations_Name:
$	Run Ssexe:Operation
$	Goto After_Name
T$Production_Name:
$	Run Ssexe:Product
$	Goto After_Name
$Sysprog_Name:
$	Run Ssexe:Sysprog
H$	Goto After_Name
$Matl_Name:
$	Run Ssexe:Matl
t$	Goto After_Name
ؽ$Manu_Name:
<$	Run Ssexe:Manu
$	Goto After_Name
$Mrkt_Name:
h$	Run Ssexe:Mrkt
̿$	Goto After_Name
0$Post_Name:
$	Run Ssexe:Post
$	Goto After_Name
\$Admin_Name:
$	Run Ssexe:Admin
$$	Goto After_Name
$	!
$After_Name:
P$	!
$		Submit /Priority=5 /After='field4':'field5'   'field7'   'field8'
$		Run Ssexe:Admin		! Reset ADMIN Username
|$
$	GOTO chrecloop
D$
$ chrecend:
$	IF action .EQS. "show"	THEN GOTO showend
p$	IF action .EQS. "startall" .OR.	-
	   action .EQS. "startlater"	-
8	THEN GOTO startend
$
 $	Write SYS$OUTPUT "%%CHRONOS-F-CHRONIC, error in chrecend"
d$ 	Exit
$
,$ showend:
$	Write SYS$OUTPUT ""
$	Close chrontab
X$ GOTO end
$
 $
$ startend:
$	Write log "CHRONOS: end at ''F$Time()'"
L$	Write log ""
$	Close log
$	Close chrontab
x$	Deassign SYS$OUTPUT
$
@$	IF batch 	THEN Type CHRONOS_DIR:chronday.log
$
$	IF dom .NE. 1	THEN GOTO oldlog
l$
$		Copy CHRONOS_DIR:chronday.log CHRONOS_DIR:chron.log
4$	!	Purge /Keep:12 CHRONOS_DIR:chronlog
$
$ GOTO end
`$
$
($ oldlog:
$	Append /New  CHRONOS_DIR:chronday.log  CHRONOS_DIR:chron.log
$	Delete /NoLog CHRONOS_DIR:chronday.log.*
T$
$ GOTO end
$
$
$ end:
H$	!	Normal exit point
$	IF interactive	THEN GOTO interact
$
t$	!	Don't print the log file - but keep a copy
$	!			       ( - just in case )
<$
$
$	Rename SYS$LOGIN:chronos.log  CHRONOS_DIR:
h$	Assign NLA0: SYS$PRINT		! NLA0: is a null device
$	Purge /Keep:2 CHRONOS_DIR:chronos.log
0$
$
$ interact:
\$	Deassign CHRONOS_DIR:
$	Set UIC 'user'
$$	Set Default 'here'
$	Set Process /Priority=4
$	IF verify	THEN Set Verify
P$ Exit
$
$
|$ chrontaberror:
$	Write SYS$OUTPUT "''F$Message($STATUS)'"
D$	Write SYS$OUTPUT "%%CHRONOS-F-CHRONIC, error with chronicle"
$
$ Exit
p$
$ bq_error:
8$	Write SYS$OUTPUT "%%CHRONOS-F-BATQER, error opening batch queue file"
$ Exit
 $
d$ log_error:
$	Write SYS$OUTPUT "%%CHRONOS-F-LOGERR, error opening log file"
,$ Exit
$
$ cleanup:
X$	Write SYS$OUTPUT "%%CHRONOS-I-ABORT, aborted by control_Y"
$	Set NoOn
 $	Close bq
$	Close log
$	Close chrontab
L$	Deassign CHRONOS_DIR
$	Set UIC 'user'
$	Set Default 'here'
x$	Set Process /Priority=4
$	IF verify	THEN Set Verify
@$ Exit
$
$
l$
$	!	END OF THE CHRONOS COMMAND FILE
4$
