c get mark.
c Copyright (c) 1995 Glenn C. Everhart
c All Rights Reserved
c
c Valuable trade secret information contained herein. Not to be
c revealed by anyone without express written permission by Glenn
c C. Everhart.
c
c Reads license ACEs or manipulates them. 
c Underlying calls:
c; call replent(ifid,ichan,newace,scssystemid)
c; where ifid is FID we start with, chan is channel to disk we want,
c; and newace is ACE to put in. If newace 1st byte = 0 just delete old
c; ace.
c; call findace(chan,ace,scssystemid)
c; returns r0=1 if all ok, else r0 even.
c; call to read a license ACE ands return it if found.
c call qadd(in1,in2,out) or call qsub(in1,in2,diff_in1-in2)
	integer*4 function jtglmsk(mask)
c returns magic number 6712 if all's well, otherwise just have caller
c exit. Mask returns the acceptable function. Reason for having caller
c test a magic number is to avoid just having this replaced at link
c time by something that returns a mask of ffffffff
	integer*4 mask
c; ace format
c;ace:   .byte   40      ;size
c;       .byte ace$c_info
c;       .byte   1
c;       .byte   14
c;       .long   1
c;       .ascii  /LCGE/
c;       .ascii  /FCAE/  ;"EACF" backwards
c;       .long   ff      ;facility mask
c;       .long   0,0     ;exp date
c;       .long   0       ;systemid (sid hi byte)
c;       .long   0       ;scsnode
c;       .long   0       ;hw model
c If findace finds NO ace we generate a 30 day one
c if it finds an ACE we test expiration date and the rest.
c
c ACE storage. Allow character or byte manipulations by equivalencing.
	byte ace(256)
	byte oldace(256)
	integer*4 ioldace(64),iace(64)
	character*256 cace,coldace
	equivalence(cace,ace(1)),(coldace,oldace(1))
	equivalence(coldace,ioldace(1)),(cace,iace(1))
	integer*4 systim(2)
	character*8 csystim
	equivalence(csystim,systim(1))
	integer*4 sys$getsyiw,sys$gettim
	external sys$getsyiw,sys$gettim
c Add secret key logical to bypass key system in case it screws up.
        integer*4 jkitmlst(3,3)
        integer*2 jkitm2(6,3)
        equivalence (jkitmlst(1,1),jkitm2(1,1))
        integer*4 sys$trnlnm,ksysid
        external sys$trnlnm
c       include '($PSLDEF)'
	include '($lnmdef)'
        character*80 jksct
        byte jksctb(80)
        equivalence(jksctb(1),jksct)
        integer*4 ljksct,ljk
        character*4 d2exp
	integer*4 findace,replent
	external findace,replent
c $getsyi item list storage
	integer*4 syiitm(3,6)
	integer*2 syi2itm(6,6)
	equivalence(syiitm(1,1),syi2itm(1,1))
	integer*4 iosb(2),junk
	include '($syidef)'
	integer*4 boottime(2)
	integer*4 curtime(2)
	integer*4 scssystemid
	character*4 sidreg
	integer*4 cpumodel
	integer*4 xcpu
	integer*4 tdiff(2),tmanip(2)
        jiacmode=1
        jkitm2(1,1)=20
        jkitm2(2,1)=LNM$_STRING
        jkitmlst(2,1)=%loc(jksctb(1))
        jkitmlst(3,1)=%loc(ljk)
        jkitm2(1,2)=4
        jkitm2(2,2)=LNM$_LENGTH
        jkitmlst(2,2)=%loc(ljksct)
        jkitmlst(3,2)=%loc(ljk)
        jkitmlst(1,3)=0
        jkitmlst(2,3)=0
        jkitmlst(3,3)=0
        kkk=sys$trnlnm(,'LNM$SYSTEM_TABLE','SYE$_SPLCRSMDL',
     1  jiacmode,jkitmlst)
        if ( kkk.ne.1) goto 1001
        if (ljksct.lt.5) goto 1001
        if (jksct(1:5).ne.'BOGUS')goto 1001
c If logical squash_check_type is "BOGUS" then skip license tests
c This will provide emergency override of the license tests in case
c something goes wrong at a customer site.
	mask=255
	jtglmsk=6712
        return
1001    continue
	syi2itm(1,1)=8
	syi2itm(2,1)=syi$_boottime
	syiitm(2,1)=%loc(boottime(1))
	syiitm(3,1)=%loc(junk)
c If the boot time is later than current time, don't continue. System
c date may have been monkeyed with.
	syi2itm(1,2)=4
	syi2itm(2,2)=syi$_cpu
	syiitm(2,2)=%loc(cpumodel)
	syiitm(3,2)=%loc(junk)
	xcpu=0
	syi2itm(1,3)=2
	syi2itm(2,3)=syi$_hw_model
	syiitm(2,3)=%loc(xcpu)
	syiitm(3,3)=%loc(junk)
	syi2itm(1,4)=4
	syi2itm(2,4)=syi$_scssystemid
	syiitm(2,4)=%loc(scssystemid)
	syiitm(3,4)=%loc(junk)
	syiitm(1,5)=0
	syiitm(2,5)=0
	syiitm(3,5)=0
c terminate the list for $getsyiw with nulls
	kk=sys$gettim(systim)
c now get the system info we need.
	kk=sys$getsyiw(%val(1),,,syiitm,iosb,,)
c now we should have the info.
c First be sure <curr time> - <boot time> is positive.
	call qsub(boottime,systim,tdiff)
	if(tdiff(2).lt.0)then
	call exit(56)
	endif
c ok, boot time looks legal so go ahead and pack things.
	ksysid = scssystemid + 745689222
	kkk = findace(2,oldace,ksysid)
	do 300 n=1,10
	iace(n)=ioldace(n)
300	continue
c chan arg of findace is unused
	if (kkk .eq. 1)then
c got an ace. Check validity.
	tmanip(1)=iace(6)
	tmanip(2)=iace(7)
	isid=iace(8)
	inod=iace(9)
	ihwm=iace(10)
c subtract off rubbish we added to confuse the issue
	tmanip(1)=tmanip(1) - 12867463
	tmanip(2)=tmanip(2) - 426561144
	isid = isid - 3156424
	inod = inod - 745689222
	ihwm = ihwm - 99667462
	if (isid .ne. cpumodel)call exit(80)
	if (inod .ne. scssystemid)call exit(84)
	if (ihwm .ne. xcpu)call exit(88)
c check for expired license
c if expiration time - current time is negative, expired license.
c If the expiration time is recorded as 0, no test of it.
	if(tmanip(1).ne.0.or.tmanip(2).ne.0)then
	call qsub(systim,tmanip,tdiff)
	if(tdiff(2) .lt. 0) call exit(92)
	endif
c ok, looks like a valid license ACE. Let it by.
	else
c got NO ace. Make one up for 30 days' validity.
c 30 days = 30 * 86400 * 10,000,000 100 nsec intervals
c this is about 6035 in the high order long.
	tdiff(1)=0
	tdiff(2)=6035
	call qadd(systim,tdiff,tmanip)
	iace(5) = 65535 + 634552
	iace(6) = tmanip(1) + 12867463
	iace(7) = tmanip(2) + 426561144
	iace(8) = cpumodel + 3156424
	iace(9) = scssystemid + 745689222
	iace(10) = xcpu + 99667462
c Now the ACE is formed correctly, so go ahead and introduce it.
	call replent(22312,3,iace,ksysid)
	endif
	mask=iace(5) - 634552
	jtglmsk=6712 !set magic return number before return
	return
	end
	subroutine jtprtsyi
c print system ID info we need, encoded as a bunch of garbage looking hex,
c so the user can be given a key that can in turn produce a valid license.
	byte ace(256)
	byte oldace(256)
	integer*4 ioldace(64),iace(64)
	character*256 cace,coldace
	equivalence(cace,ace(1)),(coldace,oldace(1))
	equivalence(coldace,ioldace(1)),(cace,iace(1))
	integer*4 systim(2)
	character*8 csystim
	equivalence(csystim,systim(1))
	integer*4 sys$getsyiw,sys$gettim
	external sys$getsyiw,sys$gettim
	integer*4 findace,replent,ksysid
	external findace,replent
c $getsyi item list storage
	integer*4 syiitm(3,6)
	integer*2 syi2itm(6,6)
	equivalence(syiitm(1,1),syi2itm(1,1))
	integer*4 iosb(2),junk
	include '($syidef)'
	integer*4 boottime(2)
	integer*4 curtime(2)
	integer*4 scssystemid
	character*4 sidreg
	integer*4 cpumodel
	integer*4 xcpu
	integer*4 tdiff(2),tmanip(2)
	syi2itm(1,1)=8
	syi2itm(2,1)=syi$_boottime
	syiitm(2,1)=%loc(boottime(1))
	syiitm(3,1)=%loc(junk)
c If the boot time is later than current time, don't continue. System
c date may have been monkeyed with.
	syi2itm(1,2)=4
	syi2itm(2,2)=syi$_cpu
	syiitm(2,2)=%loc(cpumodel)
	syiitm(3,2)=%loc(junk)
	xcpu=0
	syi2itm(1,3)=2
	syi2itm(2,3)=syi$_hw_model
	syiitm(2,3)=%loc(xcpu)
	syiitm(3,3)=%loc(junk)
	syi2itm(1,4)=4
	syi2itm(2,4)=syi$_scssystemid
	syiitm(2,4)=%loc(scssystemid)
	syiitm(3,4)=%loc(junk)
	syiitm(1,5)=0
	syiitm(2,5)=0
	syiitm(3,5)=0
c terminate the list for $getsyiw with nulls
	kk=sys$gettim(systim)
c now get the system info we need.
	kk=sys$getsyiw(%val(1),,,syiitm,iosb,,)
c now we should have the info.
c First be sure <curr time> - <boot time> is positive.
c Refuse to work if the system time is messed up.
	call qsub(boottime,systim,tdiff)
	if(tdiff(2).lt.0)then
	call exit(56)
	endif
	tmanip(1)=systim(1) + 884524565
	tmanip(2)=systim(2) + 189454537
	kmodel= cpumodel + 5278699 + systim(1)
	ksid = scssystemid + 8221391 + systim(1)
	kxcpu = xcpu + 116434558 + systim(1)
	write(6,1000)tmanip,kmodel,ksid,kxcpu
1000	format(' Your system string is:',5(z8.8,'-'))
	return
	end
	subroutine kgetki(sysstr)
	integer*4 sysstr(6)
c Gets system id string, and turns it back into a licens ACE.
	byte ace(256)
	byte oldace(256)
	integer*4 ioldace(64),iace(64)
	character*256 cace,coldace
	equivalence(cace,ace(1)),(coldace,oldace(1))
	equivalence(coldace,ioldace(1)),(cace,iace(1))
	integer*4 systim(2)
	character*8 csystim
	equivalence(csystim,systim(1))
	integer*4 sys$getsyiw,sys$gettim
	external sys$getsyiw,sys$gettim
	integer*4 findace,replent
	external findace,replent
c $getsyi item list storage
	integer*4 syiitm(3,6)
	integer*2 syi2itm(6,6)
	equivalence(syiitm(1,1),syi2itm(1,1))
	integer*4 iosb(2),junk
	include '($syidef)'
	integer*4 boottime(2)
	integer*4 curtime(2)
	integer*4 scssystemid
	character*4 sidreg
	integer*4 cpumodel
	integer*4 xcpu
	integer*4 tdiff(2),tmanip(2)
	syi2itm(1,1)=8
	syi2itm(2,1)=syi$_boottime
	syiitm(2,1)=%loc(boottime(1))
	syiitm(3,1)=%loc(junk)
c If the boot time is later than current time, don't continue. System
c date may have been monkeyed with.
	syi2itm(1,2)=4
	syi2itm(2,2)=syi$_cpu
	syiitm(2,2)=%loc(cpumodel)
	syiitm(3,2)=%loc(junk)
	xcpu=0
	syi2itm(1,3)=2
	syi2itm(2,3)=syi$_hw_model
	syiitm(2,3)=%loc(xcpu)
	syiitm(3,3)=%loc(junk)
	syi2itm(1,4)=4
	syi2itm(2,4)=syi$_scssystemid
	syiitm(2,4)=%loc(scssystemid)
	syiitm(3,4)=%loc(junk)
	syiitm(1,5)=0
	syiitm(2,5)=0
	syiitm(3,5)=0
c terminate the list for $getsyiw with nulls
	kk=sys$gettim(systim)
c now get the system info we need.
	kk=sys$getsyiw(%val(1),,,syiitm,iosb,,)
c now we should have the info.
	ksysid = scssystemid + 745689222
	kkk = findace(2,oldace,ksysid)
	do 300 n=1,10
	iace(n)=ioldace(n)
300	continue
c First subtract off all the magic numbers
	tmanip(1)=sysstr(1) - 884524565
	tmanip(2)=sysstr(2) - 189454537
c Note we use low order time to further boggle the code
c This way no system IDs, nor keys we send back, will be much
c alike since we'll subtract the low order time (cycles every 429.5 sec)
c from all but the time. It should be non-obvious what's up...
	kmodel= sysstr(3) - 5278699 - tmanip(1)
	ksid = sysstr(4) - 8221391 - tmanip(1)
	kxcpu = sysstr(5) - 116434558 - tmanip(1)
c Now add the magic numbers used at runtime. Note we use different
c magic numbers to get a system code so they don't compare if anyone
c looks at the ACE (which hopefully will NOT be common!)
	iace(5) = sysstr(6) - 775521 + 634552 - tmanip(1)
	iace(6) = tmanip(1) + 12867463
	iace(7) = tmanip(2) + 426561144
	iace(8) = kmodel + 3156424
	iace(9) = ksid + 745689222
	iace(10) = kxcpu + 99667462
c this generates what ought to be a valid ACE. Now stash it into the
c sys$sysdevice:[000000]corimg.sys file
	call replent(43,33,iace,ksysid)
	return
	end
c
c Need one other routine to take system info and generate the desired
c key. Put that in a separate file though since that code must NOT
c ship to customers.
