; -*-MACRO-*- .=0 for EMACS use only ; CHKBBD.MAC.95, 27-Jan-86 22:10:19, Edit by GERGELY ; TITLE CHKBBD SUBTTL Copyright (C) by D.N.D, Canada and Peter J. Gergely COMMENT ` This program cleans up the bulletin boards. It zeroes any invalid entry (files only, or never logged in). A list of .IDX files may be given or a wildcarded file list. The program makes use of the macros available in the files CMD.UNV, SYS:CMD.REL, PJGSYM.UNV, SYS:PJGSYM.REL. This computer program is the property of THE CANADIAN DEPARTMENT OF NATIONAL DEFENCE. It shall be used only for purposes authorized by the department. It shall not be disclosed to a third party without the Department's written permission. Queries and comments should be sent to: Peter J. Gergely Defence Research Establishment Atlantic P.O. Box 1012 Dartmouth, N.S. Canada B2Y 3Z7 Phone: 1(902) 426-3100 Copyright (C) by the authors. This software is the sole property of the author and may not be copied by any means without the expressed written consent of the author. There is no expressed or implied warranty that this software is suitable for its intended or any other use, or that it will perform any function whatsoever. ` ; Necessary External Files and Symbols SEARCH MONSYM,MACSYM,CMD,PJGSYM .REQUIRE SYS:MACREL,SYS:CMD,SYS:PJGSYM .TEXT \CHKBBD/SAVE\ SALL ; Template definitions and program version parameters ; ; ; +-----Who edited (0--DEC, 1--DEC SWS, 6--DREA) ; | +-----Program Version ; | | +-----Minor Version (a letter) ; | | | +-----The edit number ; | | | | +-----The length of the Push down stack (PDLST) ; | | | | | +-----The start address ; | | | | | | +-----The Re-entry address ; | | | | | | | +-----Your name ; V V V V V V V V PJGSTG(6,4,102,1,200,START,REENT,< Peter J. Gergely Defence Research Establishment Atlantic P.O. Box 1012 Dartmouth, N.S. Canada B2Y 3Z7 Phone: 1(902) 426-3100 >) ; Storage variables PJGACS ; Get the standard AC's K==7 X==11 ; Used to find device and directory .JBSA==120 ;[57] Here is the word set by loader DIR: BLOCK 30 ; Storage for directory information DIRBEG: Z ; The first directory to check DIREND: .INFIN ; The last directory to check ; ; File JFN related storage ; MAXJFN==^D100 ; The maximum allowable JFNS JFNPNT==10 ; Accumulator to point into JFN tables HANDLE: BLOCK MAXJFN+1 ; The Indexable file handle table SJFN: BLOCK 1 ; The current JFN we are on OUTJFN: .PRIOU ; The output JFN CURJFN: BLOCK 1 ; The current JFN JFNBLK: ; GTJFN argument block GJ%OLD!GJ%DEL!GJ%IFG!GJ%FLG!GJ%XTN!.GJDEF ; Flags Z ; Input,,Output Specs. POINT 7,DEVICE ; Device POINT 7,DIRECTORY ; Directory POINT 7,[ASCIZ \MAIL\] ; Default Filename POINT 7,[ASCIZ \IDX\] ; Default Extension Z ; Default Protection Z ; Default Account Z ; Associated JFN G1%IIN!1 ; Extended argument block Z ; Exact Copy of Typescript Z ; # of bytes in destination string Z ; CTRL/R text byte pointe Z ; Beginning of dest. block (obsolete) Z ; Pointer to file spec. attribute blk. ; ; Other storage ; MMRPAG==20 ; Must correspond to MM's .IDX files MMWPAG==40 MMPDIF== ; Difference in the pages NRMFLG: -1 ; Zero if USER format FULLFL: -1 ; Zero if summary only FIRSTF: Z ; Nonzero if something was found RSTCNT: Z ; Number of entries reset FILFLG: Z ; Nonzero if flag name given MAXDIR: Z ; The absolute highest directory number MAXLEN: MMPDIF ; The maximum allowable pages to pmap MAXPAG: 100 ; The absolute maximum allowable pages NPAGES: Z ; The length of the file in pages SIZE: Z ; The number of bytes in the mail file DATPG0: BLOCK 1 ; [PJG] Read date's DATPG1: BLOCK 1 ; [PJG] Write dates PG0ADD: Z ; The true address of the pmap space PG1ADD: Z ; The true address of the pmap space TEMP: BLOCK 10 ; Temporary storage for things TIME: Z ; The time of last read (internal) USER: BLOCK 20 ; The directory associated with time CURDAY: BLOCK 1 ; The current day OLDDAT: BLOCK 1 ; The current day a year ago AGEFLG: BLOCK 1 ; Nonzero, if current dir is too old DEVICE: BLOCK 2 ; Default device DIRECT: BLOCK 10 ; Default directory BUFFER: BLOCK 100 ; Some buffer space ZERALL: BLOCK 1 ; Nonzero if we are to empty file MALJFN: BLOCK 1 ; The mail file JFN ; Storage for COMND Jsys and valid commands CMDSTG ; Storage for the COMND JSYS SUBLST: SUBLEN,,SUBLEN ; The subcommands KWD DATE,.DATE KWD DAYS,.DAYS KWD EXIT,.ENDIT KWD FORMAT,.FORM KWD OUTPUT,.OUTPT KWD RANGE,.RANGE KWI ABORT,.ENDIT KWI PAGES,.PAGE KWI START,.BEGIN SUBLEN==.-SUBLST-1 SWILST: SWILEN,,SWILEN KWD DATE:,.DATE0 KWD DAYS:,.DAYS0 KWD FORMAT:,.FORM0 KWD OUTPUT:,.OUTP0 SWILEN==.-SWILST-1 FRMLST: FRMLEN,,FRMLEN KWD BRIEF,.FBRF KWD FULL,.FFULL KWD NORMAL,.FNORM KWD USER,.FUSER FRMLEN==.-FRMLST-1 ; PROGRAM STARTS HERE REENT: JRST START ; Reentry point START: STPROG ; default program start ; .RSCNF is returned non-zero if there ; is something in the rescan buffer ; Command JSYS activation starts here CMDSTA: PROMPT (CHKBBD> ) ; The prompt for the COMND JSYS SETZB J,HANDLE ; Zero both the index count and the ; storage location for number of JFN's CMDST0: MOVE A,[JFNBLK,,CJFNBK] BLT A,CJFNBK+11 MOVEI A,[FLDDB. .CMCFM,,,,,[ FLDDB. .CMFIL,,,,,[ FLDDB. .CMSWI,,SWILST]]] ; Get a filename CALL RFIELD FNTYP. D ; Get the argument type CAIN D,.CMCFM ; Was it a return JRST ENDIT ; Yes then done CAIE D,.CMSWI IFSKP. MOVE A,(B) ; Get address of command ROUTINE CALL (A) ; Execute the command JRST CMDST0 ENDIF. AOS J ; Add one to the JFN count MOVEM J,HANDLE ; Save it MOVEM B,HANDLE(J) ; Save the indexable handle CMALOP: MOVE A,OUTJFN CAIN A,.PRIOU IFSKP. MOVEI A,[FLDDB. .CMCMA,,, ,,[ FLDDB. .CMCFM,]] ; Read either a comma or carriage ELSE. MOVEI A,[FLDDB. .CMSWI,,SWILST,,,[ FLDDB. .CMCMA,,, ,,[ FLDDB. .CMCFM,]]] ; Read either a comma or carriage or switch ENDIF. CALL RFIELD ; return FNTYP. D CAIN D,.CMCFM JRST STPROC ; If a CR then done reading commands, CAIE D,.CMSWI IFSKP. MOVE A,(B) ; Get address of command ROUTINE CALL (A) ; Execute the command JRST CMALOP ENDIF. ; Otherwise we might have more files ; or may want to enter subcommands MOVE A,[JFNBLK,,CJFNBK] BLT A,CJFNBK+11 MOVEI A,[FLDDB. .CMCFM,,, ,,[ FLDDB. .CMFIL,CM%SDH]] ; Read either a file or CR CALL RFIELD FNTYP. D CAIN D,.CMCFM JRST SUBCOM ; IF CR then want to enter ; subcommands, othewise we have ; another filespec CAIL J,MAXJFN ; Are we at the maximum number of JFNs? JRST CMALOP ; Yes then accept no more AOS J ; Increment the JFN count MOVEM J,HANDLE ; Save it MOVEM B,HANDLE(J) ; Save the indexable handle JRST CMALOP ; Continue with this loop ; ; STPROC -- Start processing the files STPROC: MOVN JFNPNT,HANDLE ; Make a counter out of the number of HRLZ JFNPNT,JFNPNT ; JFN's AOS JFNPNT ; Increment right half, which is the ; position in the handle table SKIPL JFNPNT ; Check if a valid counter exists JRST ENDIT ; Go to the end of the program SETZM FILFLG ; Say no files jet CALL PRCLOP ; Process loop JRST ENDIT ; Go to the end of the program ; SUBCOM -- Subcommand processing is performed here SUBCOM: PROMPT(SUBCMD> ) ; Subcommand prompt MOVEI A,[FLDDB. .CMKEY,,SUBLST,,,[ FLDDB. .CMCFM,CM%SDH]] ; Get the subcommands CALL RFIELD ; Read in a keyword FNTYP. D CAIN D,.CMCFM ; default of start processing JRST .BEG1 MOVE A,(B) ; Get address of command ROUTINE CALL (A) ; Execute the command JRST SUBCOM ; Go get next command .FORM: NOISE (of output) MOVEI A,[FLDDB. .CMKEY,,FRMLST,,NORMAL] CALL CFIELD MOVE A,(B) CALL (A) JRST SUBCOM .FORM0: MOVEI A,[FLDDB. .CMKEY,,FRMLST,,NORMAL] CALL RFIELD MOVE A,(B) CALL (A) RET .FFULL: SETOM FULLFL SETOM NRMFLG RET .FBRF: SETZM FULLFL SETZM NRMFLG RET .FUSER: SETZM NRMFLG RET .FNORM: SETOM NRMFLG RET .OUTPT: NOISE (information to) ; Change the output file MOVEI A,[FLDDB. .CMOFI,CM%DPP,,,TTY:] ; The default is the TTY CALL CFIELD JRST .OUTP1 .OUTP0: MOVEI A,[FLDDB. .CMOFI,CM%DPP,,,TTY:] ; The default is the TTY CALL RFIELD .OUTP1: MOVE E,B PUSH P,B HRRZ A,OUTJFN ; Get the old jfn CAIN A,E ; See if they are the same JRST [ POP P,B RET] CAIN A,.PRIOU ; Check if the output terminal JRST .OUTP2 CLOSF% ; Otherwise close the output jfn ERCAL NOTBAD .OUTP2: POP P,B MOVEM B,OUTJFN ; Save this JFN MOVE A,B ; Open it in seven bit write MOVX B, OPENF% ERJMP .OUERR RET .OUERR: TMSG <% Could not open > ; Output the error message MOVEI A,.PRIOU HRRZ B,OUTJFN ; and the file name MOVE C,[XWD 111110,1] SETZ D, JFNS% ERCAL NOTBAD TMSG < for output. > RET .RANGE: NOISE (of directories from) ; Set range of directories to scan SETZM DIRBEG ; Set lower to zero MOVEI A,[FLDDB. .CMNUM,,^D8,,0] ; Read in the number CALL RFIELD ; and confirm it JUMPL B,[TMSG <% Negative numbers are illegal. Value set to 0. > ; Error message for negatives JRST RNGHGH] ; and continue with command MOVEM B,DIRBEG ; Stuff it away RNGHGH: MOVE A,[.INFIN] ; Upper bound to infinity MOVEM A,DIREND NOISE (to) ; Here to set end MOVEI A,[FLDDB. .CMNUM,,^D8,,377777777777] ; Def infin. CALL CFIELD ; Confirm it JUMPL B,[TMSG <% Negative numbers are illegal. Value set to infinity. > ; Error message if negative RET] MOVEM B,DIREND ; Stuff it away MOVE A,DIRBEG ; Check for DIRBEG > DIREND CAMLE A,DIREND JRST [ TMSG<% Negative range given. Resetting it to all directories. > SETZM DIRBEG ; Zero beginning MOVX A,.INFIN ; Set end to infinity MOVEM A,DIREND RET] RET .DAYS: NOISE (for declaring entry extinct) MOVEI A,[FLDDB. .CMNUM,,^D10,,366] ; A decimal number CALL CFIELD ; Confirm the field as well JUMPL B,[TMSG <% Negative numbers are illegal. No action taken. > ; Error message if negative RET] MOVE A,CURDAY SUB A,B MOVEM A,OLDDAT RET .DAYS0: MOVEI A,[FLDDB. .CMNUM,,^D10,,366] ; A decimal number CALL RFIELD ; Confirm the field as well JUMPL B,[TMSG <% Negative numbers are illegal. No action taken. > ; Error message if negative RET] MOVE A,CURDAY SUB A,B MOVEM A,OLDDAT RET .DATE: NOISE (for declaring entries extinct) MOVEI A,[FLDDB. .CMTAD,,CM%IDA] CALL CFIELD HLRZM B,OLDDAT RET .DATE0: MOVEI A,[FLDDB. .CMTAD,,CM%IDA] CALL RFIELD HLRZM B,OLDDAT RET .PAGE: NOISE (of available memory to use) ; Allow expansion of input MOVEI A,[FLDDB. .CMNUM,,^D10,,100] ; A decimal number CALL CFIELD ; Confirm the field as well JUMPL B,[TMSG <% Negative numbers are illegal. No action taken. > ; Error message if negative RET] CAILE B,MAXPAG ; Cannot exceed absolut maximum JRST [ TMSG <% Number given exceeds allowable maximum > RET] MOVEM B,MAXLEN ; Stuff it away RET .ENDIT: NOISE (the program) ; Here on the abort or exit command CONFRM POP P,A ; Won't return so pop JRST ENDIT .BEGIN: NOISE (the directory listing) ; Start processing CONFRM POP P,A ; Wont return so stop .BEG1: JRST STPROC ; Start up processing PRCLOP: SKIPE A,HANDLE(JFNPNT) ; Get the JFN and skip if invalid CALL PRCGRP AOBJN JFNPNT,PRCLOP ; Increment the counter and continue RET PRCGRP: MOVE A,HANDLE(JFNPNT) MOVEM A,SJFN PRCGR0: HRRZ A,SJFN CALL PRCFIL ; PRCFIL Get's AC1 with current JFN MOVE A,SJFN ; Get the indexable file handle that GNJFN% ; was saved, and get the next file ERJMP [RET] ; Done this one if it failed ;Any other processing when changing file JRST PRCGR0 PRCFIL: MOVEM A,CURJFN SETZM ZERALL SETZ E, MOVE A,CURJFN MOVE B,[1,,.FBSIZ] MOVEI C,E GTFDB% ERJMP [RET] SETZ J, MOVE A,CURJFN MOVE B,[1,,.FBBYV] MOVEI C,J GTFDB% ERJMP [RET] HRRZ J,J SKIPN E SKIPE J CAIA JRST [RET] SETZ E, HRRZ A,CURJFN MOVE B,[1,,.FBCTL] MOVEI C,E GTFDB% ERJMP [RET] TXNE E,FB%DEL RET HRROI A,BUFFER HRRZ B,CURJFN MOVX C,FLD(1,JS%DEV)!FLD(1,JS%DIR)!FLD(1,JS%NAM)!JS%PAF JFNS% ERJMP PRCFL0 FMSG <.TXT> MOVX A,GJ%OLD!GJ%DEL!1 HRROI B,BUFFER GTJFN% ERJMP PRCFL0 HRRZM A,MALJFN SETZ E, MOVE A,MALJFN MOVE B,[1,,.FBCTL] MOVEI C,E GTFDB% ERJMP [MOVE A,MALJFN RLJFN% ERCAL NOTBAD JRST PRCFL1] MOVE A,MALJFN RLJFN% ERCAL NOTBAD JUMPE E,PRCFL1 TXNN E,FB%DEL JRST PRCFL1 PRCFL0: TMSG MOVEI A,.PRIOU HRRZ B,CURJFN MOVX C,JS%SPC JFNS% ERCAL NOTBAD TMSG < % Nonexistent, deleted or empty mail file. Deleting all entries > HRRZ A,CURJFN MOVX B, ; access OPENF% ERCAL NOTBAD DO. HRLZ A,CURJFN FFUFP% ERJMP [TMSG <[OK] > JRST ENDLP.] MOVE B,A SETO A, SETZ C, PMAP% ERJMP [TMSG <[FAILED] > JRST ENDLP.] LOOP. ENDDO. MOVX A,FLD(.FBSIZ,CF%DSP) ; Set byte length to 0 HRR A,CURJFN SETO B, SETZ C, CHFDB% ERCAL NOTBAD MOVX A,FLD(.FBBYV,CF%DSP) ; Set byte size 36 , page length 0 HRR A,CURJFN MOVX B,FLD(77,FB%BSZ)!FLD(777777,FB%PGC) MOVX C,FLD(44,FB%BSZ)!FLD(0,FB%PGC) CHFDB% ERCAL NOTBAD MOVX A,CO%NRJ ; CLOSE THE FILE HRR A,CURJFN CLOSF% ERCAL NOTBAD RET PRCFL1: HRRZ A,CURJFN MOVX B, ; access OPENF% ERJMP [RET] SETZM FIRSTF SETZM RSTCNT GETSIZ: HRRZ A,CURJFN ; Get the size of the DAT file HRLI A,MMRPAG FFFFP% ERJMP [TMSG <% File has never been used. > JRST ENDIT] ; Error condition CAME A,[-1] IFSKP. MOVE A,CURJFN ; Get the size of the DAT file SIZEF% ERJMP [TMSG <% File has never been used. > JRST ENDIT] ; Error condition SOS C ; [PJG] One for the index page. MOVE D,C CAILE D,MMPDIF MOVEI D,MMPDIF ELSE. HRRZ D,A SUBI D,MMRPAG CAILE D,MMPDIF MOVEI D,MMPDIF ENDIF. CAMLE D,MAXLEN ; See if it is not too big JRST [ TMSG <% File is too large to read into memory > JRST ENDIT] MOVEM D,NPAGES ; Save the page length IMULI D,1000 ; Multiply by 1000 and subtract 1 SOS D ; because directory go from 0 MOVEM D,MAXDIR ; Save the number of max. directory HRLZ A,CURJFN ; JFN,,starting page = 0 HRRI A,MMRPAG HRLZI B,.FHSLF ; Handle,,Page in memory HRR B,DATPG0 MOVX C, ; and flags=count,read acc,write HRR C,NPAGES ; Count of pages to read PMAP% ; PMAP into memory ERCAL BAD HRLZ A,CURJFN ; JFN,,starting page = 0 HRRI A,MMWPAG HRLZI B,.FHSLF ; Handle,,Page in memory HRR B,DATPG1 MOVX C, ; and flags=count,read acc,write HRR C,NPAGES ; Count of pages to read PMAP% ; PMAP into memory ERCAL BAD MOVE A,DIREND ; Set up the counter into E CAMLE A,MAXDIR ; If DIREND>MAXDIR reset the value MOVE A,MAXDIR SUB A,DIRBEG ; Subtract directory begin SKIPGE A ; If range negative then quit JRST [ TMSG<% Negative number of directories requested > JRST ENDIT] AOS A ; Add one to get a true count MOVN A,A ; Multiply it by -1 HRLZ E,A ; Create the count index ADD E,DIRBEG ; Get the first directory to do HRRZ A,DATPG0 ; Set count word to A,,Start add IMULI A,1000 ; where start = startpage*1000 MOVEM A,PG0ADD ; Save the start address MOVE A,DATPG1 ; Save the address of the byte counter IMULI A,1000 ; page MOVEM A,PG1ADD SETZM FIRSTF ; No directories found yet SETZM RSTCNT LOOP: HRRZ J,E ADD J,PG0ADD ; [PJG] Add it back in SKIPN (J) JRST INCLP ; If nothing then go to the next one SKIPE FIRSTF ; Skip if no header printed yet JRST LOOP1 MOVE A,OUTJFN CAIN A,.PRIOU IFSKP. TMSG MOVEI A,.PRIOU HRRZ B,CURJFN MOVX C,JS%SPC JFNS% ERCAL NOTBAD TMSG < > ENDIF. SKIPN NRMFLG JRST LOOP1 SKIPN FILFLG IFSKP. MOVE A,OUTJFN FMSG < > ELSE. SETOM FILFLG ENDIF. MOVE A,OUTJFN FMSG < Processing > MOVE A,OUTJFN HRRZ B,CURJFN MOVX C,JS%SPC JFNS% ERCAL NOTBAD MOVE A,OUTJFN FMSG < > SKIPN FULLFL IFSKP. MOVE A,OUTJFN ; Output the header FMSG < Date and Time Dir # User Name Last Read Message File Last Written > ENDIF. LOOP1: AOS FIRSTF ; Increment the directory count SKIPN FULLFL ; Just count if brief mode JRST INCLP HRROI A,USER ; Write directory to USER SKIPN NRMFLG IFSKP. HRRZ B,E ; Get the directory number which is ; the relative word address in MOVX C, ; Output NOUT% ; the octal directory number ERCAL [HRROI A,USER RET] FMSG <. > ; A separator ENDIF. SETZM AGEFLG ; If we go to NODIR then it is because ; that the directory does not exist or ; it is files only or because ZERALL ; is set HRRZ B,E ; restore the user number HRLI B,500000 ; The left have contains the dev. DIRST% ; Translate the user number ERJMP NODIR HRRZ A,E ; Get the directory HRLI A,540000 ; Make it a directory MOVEI B,DIR ; Store it here SETZ C, GTDIR% ; Get the directory information ERJMP OUTTXT ; An error implies unprivileged so ; just output the info MOVE B,DIR+.CDMOD ; Get the mode word TXNE B,CD%DIR ; Check if files-only JRST NODIR ; Yes, then reset directory MOVE B,DIR+.CDLLD ; GET DATE OF LAST LOGIN JUMPE B,NODIR ; Reset the directory if never logged SETOM AGEFLG ; Say we are testing age HLRZ B,(J) ; Check for system date and time incorr CAMGE B,OLDDAT ; If older than a year ago, reset also JRST NODIR OUTTXT: MOVE A,OUTJFN ; Write it out to output device HRROI B,USER ; Stored in USER MOVEI C,0 ; All the text should go MOVEI D,0 ; End on a null SOUT% ERCAL BAD MOVE A,[POINT 7,USER] ; Calculate the terminal column CALL TERCOL ; it is in MOVEM B,TEMP ; Save it temporarily MOVE C,B ; If longer than 4 tabs = 32 col SUBI C,^D32 ; Then put in a carriage return SKIPL C ; and go to the proper column JRST [ MOVE A,OUTJFN FMSG < > SETZ C, ; Make sure all are output JRST DTWRIT] MOVEI C,^D31 ; Calculate how many we need SUB C,TEMP IDIVI C,10 ADDI C,1 DTWRIT: MOVE A,OUTJFN ; Write out the column justification HRROI B,[ASCIZ \ \] ; 3 tabs MOVEI D,0 ; End on a null SOUT% ERCAL BAD HLRZ B,(J) ; Check for system date and time incorr CAMLE B,CURDAY ; IFSKP. MOVE A,OUTJFN FMSG < > ELSE. MOVE A,CURDAY HRLM A,(J) MOVE A,OUTJFN FMSG <*> ENDIF. MOVE A,OUTJFN ; Output the time of the last message MOVE B,(J) ; read MOVEI C,0 ; Get the brief format ODTIM% ; Translate the internal format ERCAL BAD GETVTM: SKIPN NRMFLG JRST EOL MOVE A,OUTJFN ; Output a separator FMSG < > HRRZ J,E ADD J,PG1ADD SKIPN B,(J) ; 0 means never read IFNSK. MOVE A,OUTJFN FMSG < Never> JRST EOL ENDIF. HLRZ B,(J) ; Check for system date and time incorr CAMLE B,CURDAY IFSKP. MOVE A,OUTJFN FMSG < > ELSE. MOVE A,CURDAY HRLM A,(J) MOVE A,OUTJFN FMSG <*> ENDIF. MOVE A,OUTJFN SUB B,(J) ; Subtract the time of the last ; message read MOVM B,B ; Take the absolute value of it CAIG B,1 ; Ignore if it differs by one JRST EOL MOVE A,OUTJFN MOVE B,(J) ; Output this time if not the same MOVEI C,0 ; Get the brief format ODTIM% ; Translate the internal format ERCAL BAD EOL: SKIPE NRMFLG IFSKP. MOVE A,OUTJFN FMSG < > MOVE A,OUTJFN HRRZ B,CURJFN MOVX C,JS%DEV!JS%DIR!JS%NAM!JS%PAF JFNS% ERCAL NOTBAD ENDIF. MOVE A,OUTJFN ; Output a CRLF at the end of the line FMSG < > ; Terminate the line JRST INCLP ; [PJG] Finished then continue ; ; NODIR -- Nonexistant directory. Reset the internal values NODIR: MOVEI A,.PRIOU ; Output the directory number HRROI B,USER SETZB C,D SOUT% ERCAL NOTBAD SKIPN AGEFLG IFSKP. TMSG < [Resetting this entry line (too old)] > ELSE. TMSG < [Resetting this entry line] > ENDIF. HRRZ J,E HRRZ K,E ADD J,PG0ADD ADD K,PG1ADD SETZM (J) SETZM (K) AOS RSTCNT ; Increment number reset ; RET INCLP: AOBJN E,LOOP ; Repeat until done what we want MOVE A,FIRSTF SUB A,RSTCNT ; Remove number reset MOVEM A,FIRSTF CAIE A,1 IFSKP. MOVE A,OUTJFN FMSG < 1 Reader found> ELSE. MOVE A,OUTJFN FMSG < > MOVE A,OUTJFN MOVE B,FIRSTF MOVX C, ; Output NOUT% ERCAL NOTBAD FMSG < Readers found> ENDIF. MOVE A,OUTJFN ; Output the time of the last message FMSG < > MOVE A,OUTJFN SETO B, MOVEI C,0 ; Get the brief format ODTIM% ; Translate the internal format ERCAL BAD SKIPE NRMFLG IFSKP. MOVE A,OUTJFN FMSG < > MOVE A,OUTJFN HRRZ B,CURJFN MOVX C,JS%DEV!JS%DIR!JS%NAM!JS%PAF JFNS% ERCAL NOTBAD ENDIF. MOVE A,OUTJFN FMSG < > MOVE A,FIRSTF ; Get the number of directories done CAIG A,10 ; More than ten then output a bottom IFSKP. SKIPN NRMFLG IFSKP. SKIPN FULLFL IFSKP. MOVE A,OUTJFN FMSG < Dir # User Name Last Read Message File Last Written Date and Time > ENDIF. ENDIF. ENDIF. UNMAP: HRROI A,-1 ; Required to unmap process pages HRLZI B,.FHSLF ; Process handle,,and page HRR B,DATPG0 ; Get the page HRRZ C,NPAGES ; The number of pages to unmap PMAP% ERCAL NOTBAD HRROI A,-1 ; Required to unmap process pages HRLZI B,.FHSLF ; Process handle,,and page HRR B,DATPG1 ; Get the page HRRZ C,NPAGES ; The number of pages to unmap PMAP% ERCAL NOTBAD MOVX A,CO%NRJ ; CLOSE THE FILE HRR A,CURJFN CLOSF% ERCAL NOTBAD RET ; PRGINI -- Program initialization ; PRGINI: HRROI A,[ASCIZ \BBD:\] ;See if BBD: exists STDEV% TDZA X,X ;Use X as a flag saying "bbd: exists or not" SETO X, ;Zero means doesn't exist. This routine only JUMPE X,PRGIN0 ;If it doesn't exist, go around MOVX A,GJ%SHT!GJ%OFG ;Get parse only JFN HRROI B,[ASCIZ \BBD:\] GTJFN% ERJMP PRGIN0 HRRZ B,A ;Get JFN in right place HRROI A,DEVICE ;Store device name for GTJFN% later MOVX C,FLD(.JSAOF,JS%DEV) JFNS% ERCAL NOTBAD HRROI A,DIRECT ; Store the directory MOVX C,FLD(.JSAOF,JS%DIR) JFNS% ERCAL NOTBAD PRGIN0: MOVEI A,.PRIOU ; Default output is to TTY: MOVEM A,OUTJFN SETOM NRMFLG ; Default is NORMAL Format SETOM FULLFL ; Default is FULL Format GTAD% ERCAL BAD HLRZM A,CURDAY MOVE A,CURDAY SUBI A,^D366 MOVEM A,OLDDAT ; Keep this value for other things SETZM DIRBEG ; Directory begin is zero MOVE A,[.INFIN] MOVEM A,DIREND ; Directory end is infinity HLRZ A, .JBSA ;[57] Find end of file ADDI A, 777 ;[57] Find first free page after everything LSH A, -9 MOVEM A, DATPG0 ;[57] Here it is ADDI A,MMPDIF MOVEM A, DATPG1 ; [PJG] Data page for write access is ; [PJG] next RET ; Program termination ENDIT: MOVX A,.FHSLF ; Current file handle CLZFF% ; Close anything we can ERCAL NOTBAD HRROI A,-1 ; -1 for all JFNS RLJFN% ; Release anything we can ERCAL NOTBAD RESET% ; Reset HALTF% ; Here is where we stop the program JRST START ; In case of a restart END -------