! SECURE.BAS
!
! Function: Individual account security.
!       To change passwords, you need to modify the DATA statment (at the end
!       of the program).
!
!       Will store any attempt in output file filex (PAS.PAS).  Use program
!       DSTATE to create data statements  (included at end of this program).
!       Will allow access, will NOT inform user that information (including
!       job #) was loaded into output file, will chain INCORRECT signons to
!       LOGOFF.LIT
!
! Normally run from a start command as follows:
!       ; Start file for Michaels Libarary Account
!       :R
!       XY=0
!       :<Michael's Libarary Account -- 300,0
!
!       >
!       SET NOCTRLC
!       RUN SECURE
!       ; End start command file
!

Mapped'Vars:

       MAP1 Copyright,S,35,"Copyright @ 1984 by M.E. Clark"

       MAP1 sysdate,B,4                ! System date in binary(4)
       MAP1 datesys,@sysdate
        MAP2 sysm,B,1                  ! date month
        MAP2 sysd,B,1                  ! date day
        MAP2 sysy,B,1                  ! date year
        MAP2 sday,B,1                  ! day of week

       MAP1 chnout,S,200               ! chainout command file
       MAP1 message,S,100              ! output message (if approved)
       MAP1 passin,S,10                ! password entered
       MAP1 today,S,9                  ! today (M-S)
       MAP1 ddate,S,8                  ! system date in MM/DD/YY format
       MAP1 filex,S,7,"PAS.PAS"        ! output reporting file
       MAP1 ctime,S,5                  ! system time in HH:MM
       MAP1 crto,S,1                   ! individual character

       MAP1 counter,F,6                ! internal counter
       MAP1 blocks,F,6                 ! filesize
       MAP1 hours,F,6                  ! system time (hours)
       MAP1 mns,F,6                    ! system time (mins)
       MAP1 chv,F,6                    ! character check value
       MAP1 chvi,F,6                   ! character value in

       MAP1 jobno,B,2                  ! accessing job number

       MAP1 srtn,B,1                   ! security return code (-1=approved 0=not approved)

       XCALL NOECHO                    ! for ONECHR processing

Begin:
! (1) load the current date and time, (2) Write the access try to file,
! (3) process the security signon, (4) complete with LOGOFF if security
! signon is incorrect, with a notice if it is correct.
!

       CALL Fetch'Date'n'Time : CALL Write'File
       ?:?"Password: "; : counter=0 : CALL Security

Exit:
       IF srtn CHAIN chnout
       CHAIN "DSK0:LOGOFF.LIT[1,4]"


! ============================= SUBROUTINES =========================

Fetch'Date'n'Time:
! This routine load the system date into a MM/DD/YY format (stored in
! ddate and the current system time into the HH:MM format (using the
! 24 hour clock.

! First, we will setup the current date ...

       sysdate=DATE : ddate[1;2]=sysm USING "#Z"
       ddate[3;1]="/" : ddate[4;2]=sysd USING "#Z"
       ddate[6;1]="/" : ddate[7;2]=sysy USING "#Z"

! and then grab the day of the week ...

       ON sday CALL MO,TU,WE,TH,FR,SA,SU

! next figure the system time in HH:MM format

       hours=INT(TIME/(60^2))
       mns=TIME-(hours*(60^2))
       mns=INT(mns/60)
Fd1:    IF hours>24 THEN hours=hours-24 : GOTO Fd1
       ctime[1;2]=hours USING "#Z"
       ctime[3;1]=":"
       ctime[4;2]=mns USING "#Z"

! Always nice to make it personal.

       chnout="DSK0:SET.LIT[1,4] CTRLC"+CHR(13)+CHR(10)
       IF hours<12 message="Good Morning. "
       IF hours<18 and hours>12 message="Good Afternoon. "
       IF hours>18 message="Good Evening. "
       message=message+"Today is "+today+", "+ddate+"."
       chnout=chnout+":<"+message+CHR(13)+CHR(10)
       chnout=chnout+">"
       RETURN

MO:     today="Monday" : RETURN
TU:     today="Tuesday" : RETURN
WE:     today="Wednesday" : RETURN
TH:     today="Thursday" : RETURN
FR:     today="Friday" : RETURN
SA:     today="Saturday" : RETURN
SU:     today="Sunday" : RETURN


Write'File:
! Here we will write the file 'filex' what's going on.  We check to see
! if the file RJOBNO exists - if it does, we will also write just WHAT
! terminal this person is setting at ...

       LOOKUP filex,blocks
       IF blocks # 0 OPEN #1,filex,APPEND ELSE OPEN #1,filex,OUTPUT
       LOOKUP "DSK0:RJOBNO.SBR[7,6]",blocks
       IF blocks # 0 XCALL RJOBNO,jobno : ?#1,"Job #";jobno;" ";
       ?#1,"access try on ";today;" (";ddate;") at ";ctime;".  ";
       RETURN

Security:
! Process the password section.  Allow the user to input a password.  Exit is
! a simple RETURN. Note:  we only process the FIRST 10 CHARACTERS.

! Have the user hit a key ...

       XCALL ONECHR,crto : crto=UCS(crto)
       counter=counter+1

! Load the key hit.  If a RETURN (13), exit to S'2.  If a CONTROL W (23),
! we should start the entire process over.

       IF ASC(crto)=13 GOTO S'2
       IF ASC(crto)=23 counter=0 : passin="" : &
         ?TAB(-1,2);TAB(-1,9);"Password: "; : GOTO Security
       ?"*";
       IF counter<11 passin[counter;1]=crto
       GOTO Security

S'2:
! Read to process the entered password.  Write to out output file just what
! password was tried IF NOT APPROVED.  If approved, simply write out APPROVED.

       ?:?
       FOR counter=1 TO LEN(passin)
        crto=MID(passin,counter,1)
        chvi=ASC(crto)
        READ chv : IF chv # chvi ?#1,"pw: ";passin : CLOSE #1 : RETURN
       NEXT counter
       srtn=-1 : ?#1,"pw: *** APPROVED ***" : CLOSE #1 : RETURN

! Data statement.  Use program DSTATE to load this little gem.

       DATA 66,79,79,84,83,0           ! Current password is BOOTS


! ======================================================================
!       ! Program DSTATE.BAS
!       !   Secondary program for SECURE
!       !
!       Map'Area:
!
!               MAP1 wordin,S,10
!               MAP1 sm,S,35
!               MAP1 value$,S,3
!               MAP1 char,S,1
!
!               MAP1 counter,F,6
!               MAP1 value,F,6
!
!               MAP1 first,B,1
!
!       Begin:
!               ?:INPUT "keyword in (10 characters max): ",wordin
!               wordin=UCS(wordin)
!               first=1
!               FOR counter=1 TO LEN(wordin)
!                char=MID(wordin,counter,1)
!                value=ASC(char)
!                IF first # 1 sm=sm+","
!                IF first = 1 first = 0
!                value$=value : sm=sm+value$
!               NEXT counter
!               sm=sm+",0"
!               ?:?"DATA ";sm
!               ?:END
!
!       ! End program DSTATE.BAS
! =========================================================================

! END program SECURE.BAS