.TITLE LNOTICE Send System Notices to User at Login .IDENT /1.03/ ;++ ; Title: ; LNOTICE Send System Notices to User at Login ; ; Facility: ; Utility for displaying relevant system notices to users. ; Invoked by SYS$LOGIN for each user's login ; ; Abstract: ; Program to send the system notices to the user, provided a ; notice file has been created since the user's last login. ; A file is maintained containing the time of last login for ; each UIC on the system. ; ; Environment: ; Native mode. No other special considerations. ; ; Author: ; Gary L. Grebus, Creation date: 07-Apr-1980 ; Battelle Columbus Labs ; ; Modified by: ; Gary L. Grebus, 09-Apr-1980 ; 1.01 - Added automatic printing of notice date and time. ; Changed location of notice files to SYS$MAIL. ; ; Gary L. Grebus, 11-Nov-1980 ; 1.02 - Changed location of notice files to BAT$MAIL ; ; Gary L. Grebus, 12-Oct-1983 14:20:31 ; Changed to use indexed USRLOGREC file to improve performance. ; ;-- .PAGE ;++ ; Functional Description: ; The user login record (ULR) file is scanned for a record containing the ; UIC of the user. If the UIC is not found, a new record is appended to ; the file. Each version of the system notice file is opened, starting ; with the most recent. Each notice file created after the user's last ; login is written to the user. No more files are processed once a file ; is found which is older than the user's login or when a version of ; the message file is missing (the end of the set of message files). ; All file manipulation is via RMS. The ULR is a sequential, fixed- ; record-length file. Records are 12 bytes long and have the form: ; ULR_L_ENTUIC) UIC identifying the record ; ULR_Q_ENTTIM) Time of last login for this UIC in system 64 bit format ; ;-- ; Define symbols $JPIDEF ;Symbols for $GETJPI call MSG_C_MAXREC=160 ;Max length (chars) of message record ULR_C_ENTSZ=12 ;Length (chars) of record in ULR file ULR_L_ENTUIC=0 ;Offset in ULR record of UIC ULR_Q_ENTTIM=4 ;Offset in ULR record of login time ; Local macros .MACRO MSG ADDR,LEN $RAB_STORE - RAB=OUT_RAB,- RBF='ADDR,- RSZ=#'LEN ;;Point RAB at message $PUT RAB=OUT_RAB ;;Issue the message .ENDM MSG .PSECT RWDATA RD,WRT,NOEXE,NOSHR,LONG ; Local data ; RMS blocks for files ; Note: the DNM string must be kept the same as that in VERS_CTL below. MSG_FAB: $FAB FAC=GET,- DNM=,- FNM=,- NAM=MSG_NAM,- ORG=SEQ,RFM=VAR,- SHR=GET,XAB=MSG_XAB ;Notice file FAB MSG_RAB: $RAB FAB=MSG_FAB,- UBF=MSG_LINE,- USZ=MSG_C_MAXREC ;Notice file RAB MSG_XAB: $XABDAT ;XAB for getting creation date MSG_NAM: $NAM RSA=MSG_FULLSPEC,- RSS=NAM$C_MAXRSS ;NAM to get version number OUT_FAB: $FAB FAC=PUT,- FNM=,- ORG=SEQ,RFM=VAR,RAT=CR ;FAB for writing to the user OUT_RAB: $RAB FAB=OUT_FAB ;SYS$OUTPUT RAB ULR_FAB: $FAB FAC=,- SHR=,- DNM=,- FNM=,- BKS=3,ALQ=50,- ORG=IDX,FOP=,- MRS=ULR_C_ENTSZ,- XAB=ULR_XAB,- RFM=FIX ;FAB for User Login Record file ULR_RAB: $RAB FAB=ULR_FAB,- UBF=ULR_BUF,- KBF=UIC_BUF,- KSZ=4,- RAC=KEY,MBF=4,- ROP=,- USZ=ULR_C_ENTSZ ;RAB for User Login Record file ULR_XAB: $XABKEY REF=0,- DFL=768,- DTP=BN4,- POS=0,SIZ=4,- ULR_BUF: .BLKB ULR_C_ENTSZ ;Buffer for ULR records MSG_LINE: .BLKB MSG_C_MAXREC ;Buffer for notice file records MSG_FULLSPEC: .BLKB NAM$C_MAXRSS ;Buffer to hold full notice file spec JPI_LIST: .WORD 4 .WORD JPI$_UIC ;Code for UIC .LONG UIC_BUF .LONG 0[2] ;Request block for $GETJPI UIC_BUF: .BLKL 1 ;Buffer to hold user's UIC CUR_TIME: .BLKQ 1 ;Buffer to hold current time REC_TIME: .BLKQ 1 ;Buffer to hold login time from ;ULR record WAIT_INC: .LONG -2500*1000,-1 ;Wait interval for busy file = .25 sec NXT_VERS: .BLKL 1 ;Next file version to open VERS_TEXT: .BLKB 19 ;Buffer for text of version number VERS_TEXT_D: .LONG 19 .ADDRESS VERS_TEXT ;Desc for above buffer VERS_L_TEXT: .BLKL 1 ;Length of version string in buffer VERS_CTL: .ASCID /BAT$MAIL:.TXT;!UL/ ;Control string for coding version nr. ; This string must be kept consistent ; with the DNM string in the $FAB ; macro above BLANK_LINE: .ASCII / / ;A blank TIME_BUF: .BLKB 20 ;Buffer to hold notice creation date ;and time string TIME_BUF_LEN=.-TIME_BUF TIME_BUF_D: .LONG TIME_BUF_LEN .ADDRESS TIME_BUF ;Descriptor for above buffer .PAGE .PSECT CODE NOWRT,EXE,SHR,LONG .ENTRY LNOTICE,0 ; Main program for LNOTICE ; No registers are used except R0-R1 (scratch) ; Get user's UIC and the current time $GETJPI_S ITMLST=JPI_LIST ;Get the UIC BLBS R0,30$ ;Branch if success BRW MSG_WRITE ;If error, force the notice 30$: $GETTIM_S TIMADR=CUR_TIME ;Get current time BLBS R0,OPN_ULR ;Branch if success BRW MSG_WRITE ;If error, force the notice ; Create or open the User Login Record file OPN_ULR: $CREATE FAB=ULR_FAB ;Create or open if it exists BLBS R0,20$ ;Branch if success CMPL R0,#RMS$_FLK ;Is file busy? BNEQ 10$ ;Branch if not $SCHDWK_S DAYTIM=WAIT_INC ;Wait for .25 secs $HIBER_S ;Sleep BRB OPN_ULR ;Try again for file ; Some other error on file. Force the notice to be issued. 10$: BRW MSG_WRITE 20$: $CONNECT RAB=ULR_RAB ;Connect the ULR record stream BLBS R0,READ_ULR ;Branch if success BRW MSG_WRITE ;Error - force the notice ; Try to read the record from the UAF READ_ULR: $GET RAB=ULR_RAB ;Try to read BLBS R0,20$ ;Branch if success CMPL R0,#RMS$_RNF ;No such user in file? BNEQ 10$ ;Branch if other error ; No record in file for this UIC. Append a new record MOVL UIC_BUF,- ULR_BUF+ULR_L_ENTUIC ;UIC into record MOVQ CUR_TIME,- ULR_BUF+ULR_Q_ENTTIM ;Time into record $RAB_STORE - RAB=ULR_RAB,- RBF=ULR_BUF,- RSZ=#ULR_C_ENTSZ ;Point RAB at record $PUT RAB=ULR_RAB ;Write the new record 10$: BRW MSG_WRITE ;Force the notice to be sent ; We have the matching record. Update it. 20$: MOVQ ULR_BUF+ULR_Q_ENTTIM,- REC_TIME ;Save the time from the record MOVQ CUR_TIME,- ULR_BUF+ULR_Q_ENTTIM ;Put current time into record $UPDATE RAB=ULR_RAB ;Update the record BRW ULR_DONE ;Done with ULR file ; Here to force the notice file to be written MSG_WRITE: CLRQ REC_TIME ;Make login time a long time ago ULR_DONE: $CLOSE FAB=ULR_FAB ;Done with ULR file. Close it ; Loop through all the versions of the notice file ; Stop when a version is not found or the user has seen a version $OPEN FAB=OUT_FAB ;Open SYS$OUTPUT $CONNECT RAB=OUT_RAB ;And connect it OPN_MSG: $OPEN FAB=MSG_FAB ;Open the message file BLBS R0,10$ ;Branch if success BRW FIN ;Give up if an error 10$: $CONNECT RAB=MSG_RAB ;Connect the file BLBS R0,20$ ;Branch if success BRW FIN ;Give up if an error ; Do we need to write the notice for this user? 20$: CMPL MSG_XAB+XAB$Q_CDT+4,- REC_TIME+4 ;Compare upper longword of times BEQL 25$ ;Uppers equal - need to compare lower BGTR 30$ ;Branch if notice is newer BRW FIN ;Done if notice is older 25$: CMPL MSG_XAB+XAB$Q_CDT,- REC_TIME ;Upper longwords equal - test lower BGEQU 30$ ;Branch if notice is newer or same age BRW FIN ;Done is notice is older ; Print the message creation date and time 30$: MSG BLANK_LINE,1 ;Skip a line $ASCTIM_S - TIMBUF=TIME_BUF_D,- TIMADR= ;Convert file creation date and ;time to ASCII BLBC R0,35$ ;Skip this junk if failure MSG TIME_BUF,TIME_BUF_LEN ;Print the time MSG BLANK_LINE,1 ;Skip a line ; Loop copying notice file to SYS$OUTPUT 35$: $GET RAB=MSG_RAB ;Get a line BLBC R0,40$ ;Stop on any error $RAB_STORE - RAB=OUT_RAB,- RBF=MSG_LINE,- RSZ= ;Point RAB at record $PUT RAB=OUT_RAB ;Put the line BRB 35$ ;Loop 40$: MSG BLANK_LINE,1 ;Skip a line $CLOSE FAB=MSG_FAB ;Close this notice file ; Compute version for next file and adjust FAB MOVZBL MSG_NAM+NAM$B_RSL,R0 ;Get length of full file spec LOCC #^A/;/,R0,MSG_FULLSPEC ;Find beginning of the version nr. PUSHAL NXT_VERS ;Arg 3 is dest of value ADDL3 #1,R1,-(SP) ;Arg 2 is string address+1 SUBL3 #1,R0,-(SP) ;Arg 1 is string length-1 CALLS #3,G^LIB$CVT_DTB ;Convert version nr to binary DECL NXT_VERS ;Next version to use is current-1 BNEQ 50$ ;Branch if version non_zero BRW FIN ;All versions checked ; Supply new version via default file spec field in FAB 50$: $FAO_S CTRSTR=VERS_CTL,- OUTLEN=VERS_L_TEXT,- OUTBUF=VERS_TEXT_D,- P1=NXT_VERS ;Convert version to text $FAB_STORE - FAB=MSG_FAB,- DNA=VERS_TEXT,- DNS=VERS_L_TEXT ;Supply this version via default BRW OPN_MSG ;Loop for this version FIN: $CLOSE FAB=OUT_FAB ;Done with SYS$OUTPUT MOVL #SS$_NORMAL,R0 ;Signal normal completion RET ;Go home .END LNOTICE