Trailing-Edge
-
PDP-10 Archives
-
bb-h138e-bm_tops20_v6_1_distr
-
6-1-sources/reaper.mac
There are 27 other files named reaper.mac in the archive. Click here to see a list.
TITLE REAPER
SEARCH MONSYM,MACSYM
.REQUIRE SYS:ARMAIL
EXTERN MLINIT,MLTOWN,MLTLST,MLDONE,.MLNFL,.MLOFL
.DIRECT FLBLST ;DON'T EXPAND TEXT
SALL ;KEEP LISTING READABLE
CPYRIG: ASCIZ +
REAPER - TOPS-20 Archival Utility
Copyright (C) 1984 by Digital Equipment Corporation, Maynard, Mass
THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
+
SUBTTL Version info and edit history
.MAJOR==6
.MINOR==0
.EDIT=^D302
.WHO=0 ;SM
COMMENT +
# who date Edit description, decreasing order
--- --- --------- ---------------------------------------------------
302 SM 24-Jul-85 Twofold bug in TRIM. FB%NOD should not be checked, as
it cannot prevent Migration, and make sure a file with
AR%NAR can be migrated if needed
301 SM 15-May-85 Have TAKE try connected directory first, then SYSTEM:
if it can't find the file.
300 SM 23-Jan-85 Add POLICY command, since TAKE<CR> no longer
takes SYSTEM:REAPER.CMD automatically. Fix
version number.
200 SM 14-Nov-84 Clean up code, fix SKIP to handle non-existant
directories, catch ill. inst. problems.
+
SUBTTL Definitions
; AC def's
F==0 ;FLAGS (F.????)
T1==1 ;THE USUAL SCRAP
T2==2
T3==3
T4==4
Q1==5
Q2==6
Q3==7
P1==10
P2==11
P3==12
P4==13
DIRPGS==14
ITMSTK==16 ;FOR DIRECTORY INFORMATION
P=17 ;STACK POINTER
; flags in AC F
F.PRIV==1B0 ;WHEEL
F.TRIM==1B1 ;TRIMMING OVER-ALLOCATION DIRECTORIES
F.TAPE==1B2 ;CHECK TAPES IN USE
F.FLSH==1B3 ;FLUSH OFFLINE FILES OLDER THAN (PERIOD)
F.PURG==1B5 ;PURGE EXPIRED FDBS
F.INVL==1B6 ;REQUIRE MIGRATION OF OLD FILES
F.SCAN==1B7 ;SCAN ONLY
F.NDIR==1B8 ;NEW DIRECTORY
F.TRES==1B9 ;TAKE RESISTED FILES
F.ORDR==1B11 ;HAVE A SYSTEM ORDER LIST
F.USOD==1B12 ;HAVE A USER ORDER LIST
F.CMMA==1B18 ;COMMA FOR OUTPUT FLAG
F.PEND==1B19 ;ARCHIVE PENDING ON THIS FILE
F.TMP==1B20 ;FOR TEMPORARY THINGS
F.GOTN==1B21
LS.TTY==1B0 ;FLAGS IN LSTFLG
LS.LST==1B1
;Useful symbols
FTONEX==0 ;-1 FOR ONLINE EXP. CODE
PERWRN==^D14 ;2 WEEKS WARNING
JFNSAL=1B2+1B5+1B8+1B11+1B14+JS%PAF+JS%TMP ;JFNS%, do all fields
JFNSNE=1B8+1B11+1B14+JS%PAF+JS%TMP ;JFNS%, name, ext, gen
JFNSNX=1B8+1B11+JS%PAF+JS%TMP ;JFNS%, name, ext
NFILMX==^D8000
NTAPES==500
NDIRS==400
NJFNS==150
TAKLEN==10
TMPLEN==100
PAGLIN=56
BFRSIZ==1300 ;PARSE BUFFER SIZE (LARGE FOR LONG SKIP CMDS)
ATMSIZ==70 ;ATOM BUFFER SIZE
BFRLEN=BFRSIZ*5-1 ;CHARS ALLOWED IN CMD BUFFER
ATMLEN=ATMSIZ*5-1 ;CHARS ALLOWED IN ATOM BUFFER
PAGSIZ=1000 ;For DDT, mostly
PTAP==0 ;FOR THE TAPE STORE ROUTINES
TNAM==1
TCNT==2
IFNDEF VI%DEC,<VI%DEC==0>
;words for variables
%WRDAT==70000 ;Start of word assignments
;Allocate word macro
DEFINE W$(name,num<1>),<
name=%WRDAT
%WRDAT==%WRDAT+num>
W$ STACK,250
W$ DONEFL,NFILMX
W$ MSGPTR
W$ MSGSPC,2000
W$ DIRCNT
W$ DIRPTR
W$ FILPTR
W$ DIRS,NDIRS+1
W$ JFNSTP
W$ JFNPTR
W$ JFNLST,NJFNS+1
W$ RPSSTK
W$ RPSSTR,400
W$ PEOCNT
W$ COLTMP
W$ TMP
W$ INTTMP,2
W$ AGEIS
W$ LSTFLG
W$ FLGTMP
W$ STKSAV
W$ LSTTMP
W$ IFCTMP
W$ INPTMP
W$ TAKSTK
W$ TAKSTR,TAKLEN+1
W$ OUTMST
W$ OUTMSX
W$ TABTMP,6
W$ STRING,TMPLEN
W$ TEMP2,100
W$ DEFDEV,20
W$ DEFDIR,15
W$ DEFNAM,15
W$ DEFEXT,15
W$ DIRWLD,15
W$ FILPTH,50
W$ GOTNAM,50
W$ FDB,.FBLEN
W$ TAPBLK,.ARPSZ+1
W$ FINDSP
W$ LOCJFN
W$ ARCJFN
W$ MAILFL
W$ MLBLK,3
W$ LSTIS,25
W$ ATOM,ATMSIZ
W$ BFFR,BFRSIZ
;Things that get zeroed at start time
W$ CLRDAT,0
W$ CURDIR
W$ TODAY
W$ PERIOD
W$ LVPC3
W$ PREHIT
W$ EXPHIT
W$ LSTJFN
W$ CURCMD
W$ LSTLIN
W$ LSTPOS
W$ LSTPGN
;Keep the following in order
W$ NFILES
W$ TOTPGS
W$ NFLFIL
W$ FLPGS
W$ NTMFIL
W$ TMPGS
W$ NPURGE
W$ ZERO
;things above here get zero'd at start time
W$ CLREND
W$ TAPCNT,NTAPES*3
;Writables
GUIINB: <.CMNOI>B8
BLOCK 1
LISINB: <.CMOFI>B8+CM%SDH+CM%HPP+CM%DPP
0
-1,,[ASCIZ/LIST file specification/]
0 ;filled in at runtime
CMDBLK: 0,,TRAPRP
.PRIIN,,.PRIOU ;< FOR BALANCE
-1,,[ASCIZ/REAPER>/]
-1,,BFFR
-1,,BFFR
BFRLEN
BFRLEN
-1,,ATOM
ATMLEN
GTJBLK
GTJBLK: BLOCK 16
;TYPE addr types the string at that address. Literals are acceptable.
DEFINE TYPE(locstr),<
CALL [PUSH P,T1
HRROI T1,locstr
JRST OUTMSA] >
;TYPCHR "chr" types the character out.
DEFINE TYPCHR(chr),<
CALL [PUSH P,T1
MOVEI T1,<chr>
JRST OUTMSC] >
;TYPEAT addr is just like TYPE, but the addr contains a byte pointer to
; the text
DEFINE TYPEAT(locptr),<
CALL [PUSH P,T1
MOVE T1,locptr
JRST OUTMSG] >
;SELECT sets the output flags as listed, return flagword in the AC
DEFINE SELECT(flags,ac<T1>),<
MOVX ac,flags
MOVEM ac,LSTFLG >
;JSERRD for jsys errors that just shouldn't happen
DEFINE JSERRD(text, where<BAKOUT>, entri<ERJMP>),<
entri [CALL ANNERR ;;ANNOUNCE COMMAND IF TAKING
HRROI T1,[ASCIZ\?text\]
CALL LSTERR ;;REPORT WHAT ERROR WAS
JRST where] > ;;GO WHEREVER REQUESTED
;ERROR for general errors that just shouldn't happen.
DEFINE ERROR(text, where<BAKOUT>),<
JRST [CALL ANNERR
TYPE [ASCIZ\?text\]
JRST where] >
;WARN types a message with the approprate leadin character.
DEFINE WARN(locstr),<
CALL [CALL IFCRLF
TYPE [ASCIZ ~%'locstr~]
RET] >
;Command table macro
DEFINE CTB (addr,txt,fla<0>),<
IF1, < %%C==0>
IF2, < IFDEF addr, < %%C=addr>
IFNDEF addr, < %%C=NOCMD
PRINTX ?txt not in
>
>
XWD [ IFN fla,<EXP CM%FW!fla>
ASCIZ \txt\],%%C
>
;GUIDES does the GUIDE call and dispatches to NOCMD if it fails. Don't
; call this in a literal.
DEFINE GUIDES(text,whr<NOCMD>),<
JRST [HRROI T1,[ASCIZ ~text~]
CALL GUIDE
JRST whr
JRST .+1] >
;CONFIRM does a confirm. Dispatches to NOCMD on error, hurts no AC's.
DEFINE CONFIRM(whr<NOCMD>),<
CALL CONFRM
JRST whr >
SUBTTL Startup and Branching code
ENTVEC: JRST START
JRST START
BYTE (3).WHO (9).MAJOR (6).MINOR (18) <VI%DEC+.EDIT> ;VERSION
START: MOVEI P,STACK-1 ;SET STACK UP
MOVX T1,LS.TTY
MOVEM T1,LSTFLG ;OUTPUT TO TTY: ONLY FOR NOW
RESET% ;CLEAR THE UNIVERSE
SETZB F,CLRDAT ;AND THE FLAGS
MOVE T1,[CLRDAT,,CLRDAT+1]
BLT T1,CLREND
SETZM DIRS ;NO DIRECTORIES STORED YET
SETZM JFNLST ;NO JFNS EITHER
MOVSI T1,-NDIRS
MOVEM T1,DIRPTR
MOVE T1,[-NJFNS,,JFNLST]
MOVEM T1,JFNPTR
MOVEI T1,TAKSTR
MOVEM T1,TAKSTK ;SET UP TAKE STACK
MOVEI T1,.FHSLF ;Set up interrupts
MOVE T2,[LEVTAB,,CHNTAB]
SIR% ;DECLARE INTERRUPT TABLES
EIR%
MOVE T2,CHNMSK ;TURN ON THE CHANNELS
AIC% ;ACTIVATE CHANNELS
MOVE T1,[.TICCA,,CFCHN]
ATI% ;SETUP ^A
MOVX T1,.FHSLF
RPCAP%
TXNN T3,SC%WHL+SC%OPR ;WHEEL OR OPR PRIVS ON?
TXOA F,F.SCAN ;NO, ONLY SCANNING BY DEFAULT
TXOA F,F.PRIV ;YES, PRIVS!
JRST PEON ;NO, PEON TIME
HRROI T1,[ASCIZ/REAPER>/] ;INSURE NONPEON PROMPT
MOVEM T1,CMDBLK+.CMRTY
;Here after cleaning up after a bad error.
PANIC: MOVEI P,STACK-1 ;GET A CLEAN STACK
CALL GCMD ;DO A COMMAND
JRST .-1 ;DO ANOTHER COMMAND
GCMD: SETZM CURCMD ;NO COMMAND IN PROGRESS
GCMDP: DMOVE T1,[EXP CMDBLK,INIINB] ;DO THE COMMAND INIT
CALL PARSE ;PROMPT
JFCL ;SNH
MOVEM F,FLGTMP
MOVEM P,STKSAV ;SAVE STACK IN CASE REPARSE
MOVEI T1,RPSSTR
MOVEM T1,RPSSTK ;SAY NO REPARSE OPS NEED DOING YET
RPRS: TXNN F,F.PRIV ;PEON?
JRST [CALL WHERE ;YES, WHERE IS INPUT FROM?
JRST .+1 ;FROM FILE, FINE
JRST PENPAR] ;FROM TERMINAL, DO PEON PARSE
DMOVE T1,[EXP CMDBLK,CMDINB]
CALL PARSE ;PARSE A COMMAND
JRST UKCERR ;UNKNOWN COMMAND
MOVEM T2,CURCMD ;STORE THE COMMAND INFO
HRRZ T1,(T2)
JRST (T1)
;Routine should RET (if all OK), BAKOUT (if failing or ABORTed),
; or NOCMD (if the parse didn't work alright).
UKCERR: CALL ANNERR ;SOME SORT OF ERROR COMING UP
TYPE [ASCIZ/?Not a defined command/]
NOCMD: CALL UNDO ;GET THINGS LEFT BY PARSING
CALL WHERE ;IF INPUT FROM PRIMARY..
CALL UNTAKE ;DON'T UNDO TAKE FILES ON HIM
MOVE F,FLGTMP
JRST GCMDP
;Here if ^U or rubout
TRAPRP: CALL UNDO ;UNDO THE EFFECTS OF THE PARTIAL PARSE
GRPRS: MOVE F,FLGTMP ;RECOVER FLAGS BEFORE PARSE
MOVE P,STKSAV ;RESTORE THE STACK
JRST RPRS ;AND GO REPARSE
;Here if a command fails midstream or gets an ABORT.
BAKOUT: CALL WHERE ;IF INPUT FROM PRIMARY, DON'T HURT TAKES
CALL UNTAKE ;TOSS ANY COMMAND FILES
CALL UNDO ;GET ANYTHING LEFT BY PARSING
JRST PANIC ;AND SET UP ANEW
;Peon code, done if not an enables wheel at startup time. This forces a take
; on SYSTEM:REAPER.CMD if available, then forces the commands hardcoded in at
; PARTAB.
PEON: MOVX T1,GJ%SHT+GJ%OLD
HRROI T2,[ASCIZ/SYSTEM:REAPER.CMD/]
GTJFN%
JSERRD <Policy file not available>,DIENOW
TYPE [ASCIZ/ REAPER, reading policy file...
/]
CALL TAKE1 ;IF IT'S THERE, TAKE IT
PEON1: CALL GCMD
JRST PEON1 ;RUN UNTIL PAREOF GETS AN EOF
PEON2: TYPE CRLF ;PAREOF BRANCHES HERE FOR PEONS
SETOM PEOCNT ;SET UP FOR LIST OF IN-YOUR-BEHALF COMMANDS
PEOSET: AOS T3,PEOCNT ;GET OPERATION INDEX
SKIPN T3,PARTAB(T3) ;ANY SUCH OPERATION?
JRST DIENOW ;NO, DONE
HLRO T1,T3 ;GET THE PROMPT
MOVEM T1,CMDBLK+.CMRTY ;SET UP PROMPT
JRST GCMD ;STEAL INIT CODE AT GCMD FOR THIS
PENPAR: MOVE T3,PEOCNT ;GCMD BRANCHES HERE FOR US. GET INDEX
HRRZ T1,PARTAB(T3) ;DETERMINE WHERE TO ENTER ROUTINE
CALL (T1) ;ENTER IT
JRST PEOSET ;DONE. GO GET NEXT COMMAND
PARTAB: [ASCIZ/ Output to: /],,LIST1
[ASCIZ/ Check files: /],,ARCH1
0
SUBTTL Interrupt stuff
CFINT: SKIPN CURDIR ; Processing a BEGIN command?
DEBRK%
DMOVEM T1,INTTMP
MOVEI T1,.PRIOU
DOBE%
RFPOS%
HRROI T1,CRLF
TRNE T2,-1
PSOUT%
CFINT2: HRROI T1,[ASCIZ/ Working on /]
PSOUT%
MOVX T1,.PRIOU
MOVE T2,CURDIR
DIRST%
ERJMP .+1 ;DOESN'T FAIL
HRROI T1,CRLF
PSOUT%
DMOVE T1,INTTMP
DEBRK%
LEVTAB: BLOCK 2
LVPC3
CFCHN==1
CHNTAB: 0 ;0 Free
3,,CFINT ;1 ^A
0 ;2-5 free
0
0
0
0 ;6 Arith overflow
0 ;7 Float overflow
0 ;8 Reserved
0 ;9 PDL overflow
0 ;10 EOF
0 ;11 File Data error .ICDAE
0 ;12 Disk full
0 ;13 Reserved
0 ;14 Reserved
0 ;15 Ill Inst
0 ;16 Ill mem read
0 ;17 Ill mem write
0 ;18 Reserved
0 ;19 Inferior stopped
0 ;20 Sys res exhausted
0 ;21 Reserved
0 ;22 Non existant page
BLOCK ^D35-^D23+1 ;23 Free, 23-35
CHNMSK: 1B<CFCHN>
SUBTTL Quick commands
.FLUSH: GUIDES <Of old offline files>
MOVX T1,F.FLSH
JRST ONFLAG
.INVOL: GUIDES <Old files to offline storage>
MOVX T1,F.INVL
JRST ONFLAG
.TAPE: GUIDES <Check of tapes in use>
MOVX T1,F.TAPE
JRST ONFLAG
.TRIM: GUIDES <Directories over allocation>
MOVX T1,F.TRIM
JRST ONFLAG
.PURGE: GUIDES <Expired FDBs from disk>
MOVX T1,F.PURG
JRST ONFLAG
.REAPE: GUIDES <Everything possible>
MOVX T1,F.PURG!F.TRIM!F.INVL!F.FLSH
JRST ONFLAG
.SCAN: GUIDES <Only>
MOVX T1,F.SCAN
ONFLAG: CONFIRM
IOR F,T1
RET
.PERIO: GUIDES <For migration>
DMOVE T1,[EXP CMDBLK,PERINB]
CALL PARSE
ERROR <Bad Period>
GUIDES <Days>
CONFIRM
CAIGE T2,0
WARN <Negative PERIOD values are usually meaningless>
MOVEM T2,PERIOD
RET
.EXIT: GUIDES <To Monitor>
CONFIRM
HLLZ T1,TAKSTK
CAIE T1,0
WARN <EXIT command encountered in TAKE file>
HALTF%
RET
.SKIP: GUIDES <Directories>
MOVE ITMSTK,DIRPTR
SKIP1: DMOVE T1,[EXP CMDBLK,SKPINB]
CALL PARSE
JRST [HLLZ T1,TAKSTK ;IN A TAKE FILE?
CAIN T1,0 ;NONZERO IF YES
ERROR <Bad directory name in SKIP list> ;NO, DIE
WARN <Bad directory name "> ;YES, LET'S TRY TO IGNORE IT
MOVEI T1,[EXP ",", 0]
CALL SKIPTR ;SKIP UNTIL COMMA
TYPE ATOM ;SKIPTR LEAVES SKIPPED TEXT HERE
TYPE [ASCIZ/" ignored/]
JUMPE T3,SKIP2 ;THIS WOULD IMPLY CONFIRMED
JRST SKIP1] ;OTHERWISE, HIT A COMMA, GO ON
MOVE T3,T2
SKIP3: MOVEM T3,DIRS(ITMSTK) ; Save #
AOBJP ITMSTK,[WARN <SKIP space full>
JRST SKIP2]
MOVX T1,RC%STP+RC%AWL
HRROI T2,ATOM
RCDIR%
ERJMP SKIP4
TXNN T1,RC%NOM+RC%AMB+RC%NMD
JRST SKIP3
SKIP4: DMOVE T1,[EXP CMDBLK,CMCINB]
CALL PARSE
ERROR <Bad syntax in SKIP command>
CAIE T3,.CMCFM ;Confirm?
JRST SKIP1
SKIP2: SETZM DIRS(ITMSTK)
MOVEM ITMSTK,DIRPTR
RET
.ORDER: GUIDES <For trimming>
MOVE ITMSTK,JFNPTR ; Free space
ORDER1: SETO T1, ; Parse only pls
CALL GETFIL
ERROR <Bad filespec in ORDER list>
MOVEM T2,(ITMSTK) ; Save JFN
CALL RPSJFN
AOBJP ITMSTK,[
WARN <ORDER space is full>
JRST ORDER2]
DMOVE T1,[EXP CMDBLK, CMCINB]
CALL PARSE
ERROR <Bad syntax in ORDER command> ; Garbage
CAIE T3,.CMCFM
JRST ORDER1
ORDER2: SETZM (ITMSTK)
MOVEM ITMSTK,JFNPTR ; Cover stack
TXO F,F.ORDR ;SYSTEM ORDER LIST IN
RET
.LIST: GUIDES <Output to file>
HRROI T1,[ASCIZ/REAPER.LIST/]
TXNN F,F.PRIV
LIST1: HRROI T1,[ASCIZ/TTY:/]
MOVEM T1,LISINB+.CMDEF
DMOVE T1,[EXP CMDBLK,LISINB]
CALL PARSE
ERROR <Bad filespec in LIST Command>
CALL RPSJFN
CONFIRM
HRRZ T1,T2
MOVX T2,<FLD(7,OF%BSZ)+OF%WR>
OPENF%
JSERRD <Can't open LIST file>
EXCH T1,LSTJFN
CAIE T1,0
CLOSF%
JFCL
RET
SUBTTL BEGIN command
.ARCHI: TXNN F,F.PRIV ; Allowed?
RET ; Not really, just ignore the command
GUIDES <Processing files>
SETZ T1, ; Real JFNs
ARCH1: CALL GETFIL ; Get a file spec
ERROR <Bad file specification>
CONFIRM
MOVEM T2,ARCJFN ; Path to check
GTAD%
HLRZM T1,TODAY
SETZM DIRCNT
TXNE F,F.PRIV
TXNE F,F.TRIM
JRST NOPERW
SKIPN PERIOD
WARN <No period specified, continuing...>
; Get a directory number so we can step with RCDIR
NOPERW: HRROI T1,DIRWLD ; Area for string with wildcards
MOVX T3,<FLD(.JSAOF,JS%DEV)+FLD(.JSAOF,JS%DIR)+JS%PAF>
JFNS% ; Get STR:<DIR>
MOVX T1,RC%AWL ; Allow wildcards
HRROI T2,DIRWLD ; Point to directory string
SETZ T3, ; No previous dir #
RCDIR% ; Get a dir #
TXNE T1,RC%NOM ; No match???
ERROR <Failed to translate string to directory number>
MOVEM T3,CURDIR ; Save the result
HRROI T1,FILPTH ; Area for complete filespec
MOVE T2,ARCJFN
MOVX T3,JFNSAL
JFNS%
; Set up default strings for name and extension
HRROI T1,DEFNAM ; Area for name string
MOVX T3,<FLD(.JSAOF,JS%NAM)>
JFNS% ; Get the name specified
HRROI T1,DEFEXT ; Area for extension string
MOVX T3,<FLD(.JSAOF,JS%TYP)>
JFNS% ; Get the extension
MOVE T1,T2 ; JFN to T1
RLJFN% ; No longer need this
JFCL
CALL MLINIT ; Init stuff for sending mail
; Put in the listing file to describe what we were told to do
SKIPN T1,LSTJFN ; Have a listing file?
JRST [ MOVX T1,GJ%FOU+GJ%SHT
HRROI T2,[ASCIZ /REAPER.LIST/]
GTJFN%
JSERRD <Can't create list file>
MOVE T2,T1
CALL RPSJFN
HRRZ T1,T2
MOVX T2,<FLD(7,OF%BSZ)+OF%WR>
OPENF%
JSERRD <Can't create list file>
MOVEM T1,LSTJFN ; Save it
JRST .+1]
SELECT LS.LST
TYPE [ASCIZ /
REAPER run started at /]
CALL TADOUT
TYPE CRLF2
TYPE [ASCIZ / Specified file path: /]
TYPE FILPTH
TXNN F,F.PRIV
JRST [TYPE [ASCIZ /
The following would happen if the OPERATOR ran REAPER now:
/]
JRST STAT9]
TYPE CRLF
SKIPN T2,PERIOD ; Any period given to us?
JRST STAT0 ; No
TYPE [ASCIZ / Period is: /]
CALL DECOUT
TYPE [ASCIZ / days
/]
STAT0: TXNE F,F.SCAN
TYPE [ASCIZ / SCAN ONLY
/]
TXNE F,F.FLSH
TYPE [ASCIZ / Deleting disk contents of old offline files
/]
TXNE F,F.PURG
TYPE [ASCIZ / Purging expired offline files
/]
TXNN F,F.TRIM ; Triming directories?
JRST STAT1 ; No, skip that
TYPE [ASCIZ / Trimming directories over permanent allocation
Order during TRIM for taking files is: /]
TXNN F,F.ORDR
JRST [TYPE [ASCIZ/Not specified
/]
JRST STAT1]
MOVE ITMSTK,[-NJFNS,,JFNLST] ;Where things needing printing live
MOVEI T4,TYJFNF ;Routine to call to output an element
MOVX T3,JFNSNX
CALL PRTORD ; Print it
STAT1: TYPE [ASCIZ / Skipping directories: /]
SKIPN DIRS ; Any spec'd?
JRST [ TYPE [ASCIZ / None specified
/]
JRST STAT9]
MOVE ITMSTK,[-NDIRS,,DIRS]
MOVEI T4,TYDIRS
CALL PRTORD ; Listing is started, now start processing
STAT9: TXZ F,F.NDIR ; New directory
DODIR: CALL CHKDIR ; Make sure of good directory
JRST ENDARC ; That's the last of them
SETZ DIRPGS, ; No pages collected yet
SETO T1,
CALL SETGTD ; Set up the block
MOVE T1,[.NULIO,,.NULIO]
MOVEM T1,GTJBLK+.GJSRC
HRROI T1,STRING ; Scratch area
MOVE T2,CURDIR ; Dir we are working on
DIRST% ; Get the string
JSERRD <DIRST failure>
MOVE T1,[POINT 7,STRING]
MOVE T2,[POINT 7,DEFDEV] ; Make structure name
MOVEM T2,GTJBLK+.GJDEV
DODIR1: ILDB T3,T1
CAIN T3,":"
SETZ T3,
IDPB T3,T2
JUMPN T3,DODIR1
DODIR2: IBP T1 ; Flush "<"
MOVE T2,[POINT 7,DEFDIR] ; Make directory name
MOVEM T2,GTJBLK+.GJDIR
DODIR3: ILDB T3,T1
CAIN T3,">"
SETZ T3,
IDPB T3,T2
JUMPN T3,DODIR3
TXNE F,F.TRIM ;GOING TO TRIM BACK THE DIRECTORY?
CALL GETORD ;YES, GET ANY USER ORDER
HRROI T1,DEFNAM
MOVEM T1,GTJBLK+.GJNAM
HRROI T1,DEFEXT
MOVEM T1,GTJBLK+.GJEXT
DOFIL: SETZM FILPTR ; Reset count of entries in DONEFL
CALL DOKEEP ; Touch files WE want around
CALL DOPERI ; Migrate old files
CALL DOFLSH ; Delete contents of old archive files
CALL DOMISC ; Delete old temp files, etc.
CALL DOTRIM ; Trim directory back to quota
CALL DOTAPE ; Check tapes reference by this directory
AOS T1,DIRCNT
TRNE T1,17 ;CHECKPOINT EVERY 16 DIRECTORIES
JRST NXTDIR ;NOT YET
MOVE T1,LSTJFN
TXO T1,CO%NRJ
CLOSF% ;CLOSE LISTING FILE, BUT KEEP JFN
ERJMP .+2
CALL OPNLST
JRST [SELECT LS.TTY
WARN <List file didn't reopen>
JRST NXTDIR]
NXTDIR: CALL INCDIR
JRST ENDARC
JRST DODIR ; Loop
INCDIR: MOVX T1,RC%STP+RC%AWL ; Gotta go to next directory
HRROI T2,DIRWLD ; Point to wildcard string
MOVE T3,CURDIR ; Current dir #
RCDIR% ; Find next one
ERJMP CPOPJ
TXNE T1,RC%NMD ; No more dirs?
RET
MOVEM T3,CURDIR ; Remember new dir #
TXZ F,F.NDIR ; New directory
MOVE ITMSTK,JFNPTR
CALL RLJFNS ; Release any user ORDER JFNs
JRST CPOPJ1
; Check CURDIR to see if SKIPping this directory; if so, advance
; to one we aren't SKIPping
CHKDIR: SKIPN DIRS ; Skipping anything?
JRST CPOPJ1
MOVE T3,CURDIR ; Get current dir #
MOVSI T1,-NDIRS ; Those to check
CHKDI1: CAME T3,DIRS(T1) ; Skip this guy?
AOBJN T1,CHKDI1 ; Loop
JUMPGE T1,CPOPJ1 ; Done, no match
CHKDI2: CALL INCDIR ; To next directory
RET ; No next
JRST CHKDIR ; Check this one too
ENDARC: TYPE CRLF2
SETZ Q2,
LSTTTL: HLRZ Q1,LSTTAB(Q2)
JUMPE Q1,ENDAR1
MOVE T2,(Q1)
TYPCHR " "
CALL DESOUT
HRRO T1,LSTTAB(Q2)
TYPEAT T1
MOVEI T2,^D40
CALL TABOUT
MOVE T2,1(Q1)
CALL DESOUT
TYPE [ASCIZ/ pages
/]
AOJA Q2,LSTTTL
ENDAR1: SKIPE EXPHIT ; Did any tapes get noted?
CALL DMPTAP ; Yes, dump out the info now
ENDAR2: MOVE T1,LSTJFN
CLOSF% ; Close the listing file
JFCL
SETZM LSTJFN ; No longer valid
CALL MLDONE ; Clean up mail stuff
MOVE ITMSTK,[-NJFNS,,JFNLST]
CALL RLJFNS
DIENOW: HALTF%
JRST START
DMPTAP: SETOM LSTLIN ; Start a new page
TYPE [ASCIZ/
Tape ID Count Tape ID Count Tape ID Count
/]
SETZM COLTMP ;Start in column 1, please
MOVEI T3,TAPCNT ; Beginning of the tree
CHASE: PUSH P,T1
CHASE1: MOVE T1,T3
HRRZ T3,PTAP(T3)
CAIE T3,0
CALL CHASE
CALL DOOP ;Do for each element in the tree
MOVE T3,T1
HLRZ T3,PTAP(T3)
CAIE T3,0
JRST CHASE1 ;TAIL RECURSION, JUST LIKE CALL CHASE
POP P,T1
RET
DOOP: PUSH P,T1
MOVE T2,TNAM(T1)
TLNE T2,-1 ;SIXBIT OT NUMERIC?
JRST [MOVE T3,T2
CALL SIXOUT
JRST DOOP1]
MOVE T3,[NO%OOV+NO%MAG+NO%LFL+7B17+^D10]
CALL NUMOUT
DOOP1: MOVE T2,COLTMP
MOVE T2,[DEC 10,34,58](T2)
CALL TABOUT ;..
MOVE T1,(P) ;POINTER TO BLOCK CONTAINING INFO
MOVE T2,TCNT(T1) ;GET THE COUNT
CALL DESOUT ;OUTPUT
AOS T2,COLTMP
SKIPN T2,[DEC 24,48,0]-1(T2)
JRST [SETZM COLTMP ;YES
TYPE CRLF
JRST DOOP2]
CALL TABOUT
DOOP2: POP P,T1 ;RESTORE T1
RET
;LH address of a pair of words, the first is typed before the RH text, the
; 2nd after it.
LSTTAB: NFILES,,[ASCIZ / files marked for migration/]
NFLFIL,,[ASCIZ / archive files deleted from disk/]
NTMFIL,,[ASCIZ / temporary files deleted/]
NPURGE,,[ASCIZ / expired files purged/]
0
; Period checker
DOPERI: TXNN F,F.INVL ; Switch for this turned on?
RET ; No
MOVX T1,GJ%IFG+GJ%XTN+.GJALL
MOVEM T1,GTJBLK+.GJGEN ; Fix up GTJFN bits
MOVEI T1,GTJBLK
SETZ T2, ; As if the user took default
GTJFN%
RET ; Done, none here
MOVEM T1,LOCJFN ; Save the JFN
DOPER1: CALL GTFDBF ;GET FDB INFORMATION
MOVE T1,FDB+.FBCTL
TXNE T1,FB%ARC!FB%OFF!FB%DIR!FB%NOD!FB%TMP!FB%PRM
JRST DOPER9 ; Go to next file
MOVE T1,FDB+.FBBBT
TXNE T1,AR%RAR!AR%RIV!AR%NAR!AR%EXM ; If requested or resist, skip it
JRST DOPER9
CALL HAVTAP ; See if we have tape ID's already
JRST DOPER9 ; We do, don't migrate the file again
; Check to see if online expiration has occured
IFN FTONEX,<
SKIPN T2,FDB+.FBNET ; Have on online expiration?
JRST DOPER3 ; No, file can't expire then
HLRZS T2 ; Want date portion of online exp
CAML T2,TODAY
JRST DOPER3 ; No (& does have exp. date)
JUMPN T2,DOPER5 ; Expired date if non-zero--take it
MOVE T1,FDB+.FBCRE ; Interval, find most recent date
CAMG T1,FDB+.FBCRV
MOVE T1,FDB+.FBCRV
CAMG T1,FDB+.FBWRT
MOVE T1,FDB+.FBWRT
CAMG T1,FDB+.FBREF
MOVE T1,FDB+.FBREF
HRRZ T2,FDB+.FBNET ; Get the interval
HLRZS T1
ADD T2,T1 ; Form expiration date
CAML T2,TODAY
JRST DOPER3 ; No, check for age
DOPER5: SETO T2, ; Flag file is expired
JRST DOPER2
> ; End IFN FTONEX
; Now check for too old a file
DOPER3: SKIPG PERIOD ; Have a real period?
JRST DOPER9 ; No, skip this then
CALL GTAGE ; Get age of file
CAMGE T2,PERIOD ; Old enough?
JRST DOPER9 ; No, skip it
DOPER2: CALL CKDNFL ; Has this one been done before?
JRST DOPER9 ; Yes, skip it this time
MOVEM T2,AGEIS
HRRZ T1,LOCJFN
MOVEI T2,.ARRIV ; Request file be migrated
MOVEI T3,.ARSET
TXNN F,F.SCAN ; Only a scan?
ARCF% ; No, real thing
ERJMP [HRROI T2,[ASCIZ / ARCF failed/]
CALL LSTFIL
JRST DOPER9]
HRRZ T1,FDB+.FBBYV
ADD DIRPGS,T1 ; Accum what we've taken
ADDM T1,TOTPGS ; Into running total
AOS NFILES ; Count files
HRROI T2,STRING
MOVE T1,AGEIS ;fetch age again
IFN FTONEX,<
JUMPL T1,[
HRROI T1,[ASCIZ /Online expiration reached/]
JRST DOPER4]
>; end IFN FTONEX
CALL NOUTB
HRROI T1,[ASCIZ / days old/]
DOPER4: CALL CSTR
HRROI T2,STRING
CALL LSTFIL ; Into listing
DOPER9: MOVE T1,LOCJFN
GNJFN%
JRST [ SETZM LOCJFN
RET]
JRST DOPER1
; Flush contents of OLD online files with tape backup
DOFLSH: TXNE F,F.FLSH
SKIPN PERIOD
RET
MOVX T1,GJ%IFG+GJ%XTN+.GJALL
MOVEM T1,GTJBLK+.GJGEN
MOVEI T1,GTJBLK
SETZ T2, ; Take default
GTJFN%
RET ; No files to do
MOVEM T1,LOCJFN ; Save the JFN
HRROI T1,[ASCIZ /Old file contents deleted from disk/]
MOVX T2,.MLOFL ; Use the offline msg file
CALL BEGUSR ; Start user message
DOFLS1: CALL GTFDBF
MOVE T1,FDB+.FBCTL
TXNE T1,FB%OFF ; Already off-line?
JRST DOFLS9 ; Yes, skip it
SKIPE TAPBLK+.ARTP1 ; First tape exist?
SKIPN TAPBLK+.ARTP2 ; AND 2nd? (HAVTAP is OR not AND)
JRST DOFLS9 ; Both tapes don't exist yet
CALL GTAGE ; Get its age
CAMGE T2,PERIOD ; Old enough?
JRST DOFLS9 ; No, skip the file
MOVEM T2,AGEIS ; Save the age
TXNE F,F.SCAN
JRST DOFLS2
MOVX T1,DF%CNO+DF%NRJ ; Disk contents only
HRR T1,LOCJFN
DELF% ; No, real thing
JRST [ HRROI T2,[ASCIZ / DELF failed/]
CALL LSTFIL
JRST DOFLS9]
DOFLS2: HRROI T1,[ASCIZ / - Disk contents deleted/]
CALL TOUSR ; Include in the message
AOS NFLFIL
HRRZ T1,FDB+.FBBYV ; Get # of pages
ADD DIRPGS,T1
ADDM T1,FLPGS ; To total
HRROI T1,[ASCIZ / Disk contents deleted, /]
HRROI T2,STRING
CALL CSTRB
MOVE T1,AGEIS
CALL NOUTB
HRROI T1,[ASCIZ / days old/]
CALL CSTR
HRROI T2,STRING
CALL LSTFIL
DOFLS9: MOVE T1,LOCJFN
GNJFN%
JRST [ SETZM LOCJFN ; Done JFN is garbage
JRST ENDUSR] ; End the message
JRST DOFLS1
; Here to touch various files that shouldn't get migrated...
DOKEEP: TXNE F,F.SCAN
RET ;SCANNING, IGNORE THIS
MOVX T1,GJ%OLD+GJ%XTN ; All files must exist
MOVEM T1,GTJBLK+.GJGEN
MOVX T1,G1%IIN
MOVEM T1,GTJBLK+.GJF2
HRROI T2,[ASCIZ /DIRECTORY.OWNER/]
CALL DOKEP1
HRROI T2,[ASCIZ /MAIL.TXT.1/]
CALL DOKEP1
HRROI T2,[ASCIZ /OFFLINE-FILE-MSGS.TXT/]
;JRST DOKEP1
DOKEP1: MOVE T1,[.NULIO,,.NULIO]
MOVEM T1,GTJBLK+.GJSRC
MOVEI T1,GTJBLK
GTJFN%
RET ; File doesn't exist
MOVEM T1,TMP ; Save the JFN
MOVE T2,[1,,.FBBBT] ;Get archival flags
MOVEI T3,T4 ;into T4
GTFDB%
TXNE T4,AR%EXM ;is it already migrate proof?
JRST DOKEP2 ;yes. It's safe. Go on.
MOVX T2,.AREXM ;Set prohibit migration
MOVX T3,.ARSET ; This disturbs the access date, but should
ARCF% ; only happen once.
ERJMP DOKEP2 ;shouldn't happen
DOKEP2: MOVE T1,TMP ;done, lose jfn
RLJFN%
JFCL
RET
; Trim directory back to size
DOTRIM: TXNN F,F.TRIM
RET ; We weren't told to do this
MOVX T1,GJ%IFG+GJ%XTN+.GJALL
MOVEM T1,GTJBLK+.GJGEN
MOVE T1,CURDIR ; Get current directory #
GTDAL%
SUB T2,T3 ; Pages they are over
SUB T2,DIRPGS ; And those already stolen
JUMPLE T2,CPOPJ ; Done if under allocation
TXON F,F.NDIR ; Need to print directory name?
CALL LSTDIR ; Yes, do that
MOVE DIRPGS,T2 ; Those required from user
TYPE [ASCIZ / Collecting /]
MOVE T2,DIRPGS
CALL DECOUT
TYPE [ASCIZ / pages
/]
MOVE ITMSTK,JFNSTP ; Get pointer to ORDER list
TXZ F,F.TRES ; Leave RESIST's (AR%NAR) if possible
DOTRI1: SKIPN T2,(ITMSTK) ; Anything?
JRST DOTRI2 ; No, go to next phase
CALL DOTRM ; Do the work
JRST DOTRIX ; Done
AOBJN ITMSTK,DOTRI1
DOTRI2: HRROI T2,[ASCIZ /*.*.*/]
CALL DOTRMS
JRST DOTRIX ; Done, enough collected
MOVE ITMSTK,JFNSTP ; Current ORDER list
TXO F,F.TRES ; Take RESIST's if necessary
DOTRI3: SKIPN T2,(ITMSTK) ; Any there?
JRST DOTRI4 ; No, done
CALL DOTRM
JRST DOTRIX ; Done, enough pages collected
AOBJN ITMSTK,DOTRI3
DOTRI4: HRROI T2,[ASCIZ /*.*.*/]
CALL DOTRMS
JRST DOTRIX ; Got all we needed
DOTRIX: JUMPLE DIRPGS,CPOPJ ; Leave
TXON F,F.NDIR ; Make sure we said what directory
CALL LSTDIR ; We didn't yet, do it now
TYPE [ASCIZ / Still over allocation by /]
MOVE T2,DIRPGS
CALL DECOUT
TYPE [ASCIZ / pages
/]
RET
; Do actual work; Expects T2 to have JFN of files to consider (ORDER)
DOTRM: HRROI T1,STRING
MOVX T3,<FLD(.JSAOF,JS%NAM)+FLD(.JSAOF,JS%TYP)+JS%PAF>
JFNS% ; Default name string
HRROI T2,STRING ; Point to default string
; Enter here with a string pointer in AC2 (also fallen into from DOTRM)
DOTRMS: MOVEI T1,GTJBLK ; Enter here with string
GTJFN%
JRST CPOPJ1 ; Done, none of correct flavor
MOVEM T1,LOCJFN ; Save the local JFN
DOTRM1: TXZ F,F.PEND ; No archive pending on this file
CALL GTFDBF ; Get FDB
TXNE F,F.TRES ; Interested in resisting files?
JRST DOTRM4 ; Yes - try to take it
MOVE T3,FDB+.FBBBT
TXNE T3,AR%NAR ; No. Is this a Resisting file?
JRST DOTRM9 ; Yes. Skip it this time
DOTRM4: CALL CKDNFL ; Check if file already done
JRST DOTRM9 ; Yes, don't do it again
MOVE T3,FDB+.FBBBT
TXNE T3,AR%RAR!AR%RIV ; Archive already pending?
JRST [ TXNE T3,AR%NDL ; Will we get any pages of it?
JRST DOTRM9 ; No, skip the file
TXO F,F.PEND ; Yes, flag archive already pending
JRST DOTRM8] ; And enter further down the line
MOVE T2,FDB+.FBCTL
TXNN T3,AR%EXM ; Not allowed to migrate it?
TXNE T2,FB%ARC!FB%OFF!FB%DIR!FB%TMP!FB%PRM
JRST DOTRM9 ; Skip it
CALL HAVTAP ; Already have tape backup?
JRST DOTRM9 ; Yes, skip the file
HRRZ T1,LOCJFN
MOVX T2,.ARRIV ; Migrate it
MOVEI T3,.ARSET
TXNN F,F.SCAN ; Only a scan?
ARCF% ; No, real
ERJMP [HRROI T2,[ASCIZ / ARCF failed/]
CALL LSTFIL
JRST DOTRM9]
DOTRM8: HRRZ T2,FDB+.FBBYV ; Get # of pages we got back
SUB DIRPGS,T2
TXNN F,F.PEND ; Actually mark it?
ADDM T2,TOTPGS ; Yes, add to total pages
AOS NFILES ; And count the files
MOVE T1,T2
HRROI T2,STRING
CALL NOUTB
HRROI T1,[ASCIZ / pages claimed/]
TXNE F,F.PEND ; Was archive already pending?
HRROI T1,[ASCIZ / migration already pending/]
CALL CSTR
HRROI T2,STRING
CALL LSTFIL ; Into listing
DOTRM9: JUMPLE DIRPGS,DOTRMD ; Done, end up things
MOVE T1,LOCJFN
GNJFN%
JRST CPOPJ1
JRST DOTRM1 ; Around for more
DOTRMD: HRRZ T1,LOCJFN
RLJFN%
JFCL
SETZM LOCJFN
RET ; Signal directory done
; Do miscellaneous operations -- delete old temp files,
; expunge FDBs which are past offline expiration.
DOMISC: TXNN F,F.PURG ;PURGING?
RET ;NO, NO MISC FUNCTIONS NEED DOING
MOVX T1,GJ%IFG+GJ%XTN+.GJALL
MOVEM T1,GTJBLK+.GJGEN
MOVEI T1,GTJBLK ; Get defaults
SETZ T2, ; Use them
GTJFN%
RET ; Nothing to do
MOVEM T1,LOCJFN ; Save local JFN
HRROI T1,[ASCIZ /Offline expired files/]
MOVX T2,.MLNFL ; Don't send to offline msg file
CALL BEGUSR ; Start a message
DOMSC1: CALL GTFDBF
MOVE T1,FDB+.FBCTL ; Get ctl bits
TXNE T1,FB%TMP ; Temp file?
JRST DOTMP ; Delete it if too old
JRST DOFET ; Yes, check offline expiration
DOADVA: MOVE T1,LOCJFN
GNJFN%
SETZM LOCJFN
ENDMSC: SKIPE LOCJFN
JRST DOMSC1
JRST ENDUSR ; Finish up and return
; Check offline file to see if it has reached offline expiration.
; If so, expunge it.
DOFET: TXNN F,F.PURG ; Purge expired FDBs?
JRST DOADVA ; No, done here
LDB T1,[POINT 7,FDB+.FBHDR,35]
CAIGE T1,.FBLXT ; Long enough?
JRST DOADVA ; No, skip this file
SKIPN FDB+.FBTP1 ; Have any tape info?
SKIPE FDB+.FBTP2
SKIPA T1,FDB+.FBFET
JRST DOADVA ; Has none, skip this file
TLNN T1,-1 ; Which is it?
JRST [ HRLZS T1 ; Make # days,,0
ADD T1,FDB+.FBTDT ; Date when will be expired
JRST .+1]
HLRZS T1
CAML T1,TODAY
JRST DOFET2
MOVE T1,FDB+.FBBBT
TXNN T1,AR%WRN ; User been warned about this?
JRST DOFET3 ; No, do so now
CALL JOJAR ; try to get (in T1) and advance jfn
MOVE T2,FDB+.FBCTL ;GET FLAGS ON THIS FILE
TXNN T2,FB%OFF ;OFFLINE?
JRST DOFETD ;YES. GO DISCARD TAPE BACKUP INFO
TXNE F,F.SCAN
JRST DOFETA
TXO T1,DF%EXP+DF%ARC
DELF%
JRST DELERR
DOFETA: AOS NPURGE
HRROI T2,[ASCIZ / Expunged, offline expiration reached/]
CALL LSTFIL
HRROI T1,[ASCIZ / - File deleted and expunged (expired)/]
CALL TOUSR
JRST ENDMSC
DOFET2: MOVE T3,FDB+.FBBBT
TXNE T3,AR%WRN ; Been warned?
JRST DOADVA ; Yes, don't do it again
SUBI T1,PERWRN ; Make it look later than it is
CAML T1,TODAY ; Now is it expired?
JRST DOADVA ; No, on to the next file
DOFET3: HRRZ T1,LOCJFN
HRLI T1,.FBBBT ; Set the warning flag
MOVX T2,AR%WRN
MOVE T3,T2
TXNN F,F.SCAN ; Don't if only a listing
CHFDB%
HRROI T1,[ASCIZ / - Offline expiration approaching/]
CALL TOUSR ; Put this in the msg
JRST DOADVA ; And go on
DOFETD: MOVX T2,.ARDIS ; Discard tape info
MOVX T3,AR%CR1+AR%CR2 ; Clear both sets of tape info
TXNN F,F.SCAN ; Don't if only a listing
ARCF%
ERJMP [HRROI T2,[ASCIZ/ ARCF discard failure/]
JRST OPERR]
HRROI T2,[ASCIZ / Tape backup information discarded/]
CALL LSTFIL
HRROI T1,[ASCIZ / - Tape backup information discarded (expired)/]
CALL TOUSR
MOVE T1,TMP
RLJFN% ; 2nd JFN no longer needed
JFCL
JRST ENDMSC
;JFN the file pointed to by LOCJFN, and advance LOCJFN. Returns GOTNAM
; containing the filename to operate on, T1/ jfn on that file, and
; F.GOTN on (for subsequent LSTFIL calls).
JOJAR: HRROI T1,GOTNAM
HRRZ T2,LOCJFN
MOVX T3,JFNSAL
JFNS%
TXO F,F.GOTN ;LSTFIL please use this name
MOVE T1,LOCJFN
GNJFN%
SETZM LOCJFN
MOVX T1,GJ%IFG+GJ%XTN+GJ%DEL
MOVEM T1,GTJBLK+.GJGEN
MOVEI T1,GTJBLK
HRROI T2,GOTNAM
GTJFN%
JSERRD <2nd JFN failure>,DIENOW
HRRZS T1
MOVEM T1,TMP
RET
;Release the JFN stored by JOJAR, and report a failed operation
DELERR: HRROI T2,[ASCIZ / DELF failed/]
OPERR: MOVE T1,TMP
RLJFN%
JFCL
CALL LSTFIL
JRST ENDMSC
BEGUSR: TXNE F,F.SCAN
RET ; Scan only, don't do message
MOVEM T2,MAILFL ; Save flag handed us
MOVEM T1,MLBLK+1 ; Remember the subject
MOVE T1,CURDIR
MOVEM T1,MLBLK+0 ; Save directory #
MOVE T1,[POINT 7,MSGSPC]
MOVEM T1,MSGPTR
MOVEM T1,MLBLK+2 ; Text field
RET ; All set up
ENDUSR: TXNE F,F.SCAN
RET ; Don't if scan only
MOVE T2,MSGPTR
CAMN T2,[POINT 7,MSGSPC] ; Have anything for the user?
RET ; No, don't bother sending then
HRROI T1,CRLF
CALL CSTR
MOVEI T1,MLBLK
MOVE T2,MAILFL ; Pick up flag type user wanted
JRST MLTOWN ; Mail to owner of the files
TOUSR: TXNE F,F.SCAN
RET ; Don't if scan only
PUSH P,T1 ; Save comment line
MOVE T1,MSGPTR
HRRZ T2,LOCJFN
MOVX T3,JFNSAL
JFNS%
MOVE T2,T1
POP P,T1 ; Comment line
TLNE T1,-1 ; Look like a string ptr?
CALL CSTRB
HRROI T1,CRLF
CALL CSTRB
MOVEM T2,MSGPTR
RET
; Delete temporary files PERIOD days old.
DOTMP: SKIPN PERIOD ; Period specified?
JRST DOADVA ; No, nothing to do
CALL GTAGE
CAMGE T2,PERIOD ; File old enough?
JRST DOADVA ; No, skip it
MOVEM T2,AGEIS
CALL JOJAR
TXNE F,F.SCAN ;just scanning?
JRST DOTMP1 ;yes, skip the DELF
TXO T1,DF%EXP
DELF% ; No, do it for real
JRST DELERR
DOTMP1: HRRZ T1,FDB+.FBBYV ; Get pages claimed
ADD DIRPGS,T1 ; Accumulate dir total
ADDM T1,TOTPGS ; Account total pages in this directory
ADDM T1,TMPGS ; Accumulate temp file total
AOS NTMFIL ; Count temp files deleted
HRROI T2,STRING
MOVE T1,AGEIS
CALL NOUTB
HRROI T1,[ASCIZ / days old, deleted and expunged/]
CALL CSTR
HRROI T2,STRING
CALL LSTFIL
JRST ENDMSC
DOTAPE: TXNN F,F.TAPE
RET ;DON'T BOTHER IF NOT WANTED
MOVX T1,GJ%IFG+GJ%XTN+.GJALL
MOVEM T1,GTJBLK+.GJGEN
MOVEI T1,GTJBLK
SETZ T2,
GTJFN%
RET ; None to do
MOVEM T1,LOCJFN
DOTAP1: HRRZ T1,LOCJFN
MOVX T2,.ARGST
MOVEI T3,TAPBLK
ARCF% ; Get the tape info
ERJMP DOTAP2 ; Isn't any for that file
CALL STOTAP
DOTAP2: MOVE T1,LOCJFN
GNJFN%
RET ; All done
JRST DOTAP1
;Here with TAPBLK set up to store both tape names
STOTAP: SKIPE T2,TAPBLK+.ARTP1
CALL FIND
SKIPN T2,TAPBLK+.ARTP2
RET
;Here with tape name to match in T2. This routine is written to expect
; lots of calls with T2 alternating between FOO1 and FOO2 on entry. Ie,
; before it searches the tree, it checks to see if it is looking for
; what it was looking for 2 calls ago.
FIND: SKIPN PREHIT ;FIRST CALL?
JRST FFIND ;YES. GO SET UP AND ADD 1ST ENTRY.
SKIPN T1,EXPHIT ;MIGHT IT BE THE ONE WE EXPECT?
JRST FIND2 ;WE DON'T EXPECT ANYTHING, GO FIND PLACE
CAMN T2,TNAM(T1) ;MATCH EXPECTED ENTRY?
AOSA TCNT(T1) ;YES - UP THE COUNT AND GO HOME
JRST FIND2 ;NO, HAVE TO GO FIND OR ADD
RET
FFIND: MOVE T1,[-NTAPES,,TAPCNT] ;HERE TO ADD FIRST ENTRY. SET UP THE
MOVEM T1,FINDSP ;"LAST USED" POINTER, AND ADD ENTRY
JRST ADDIN2 ;..
NXTINT: SKIPA T1,T3 ;COPY POINTER
FIND2: MOVEI T1,TAPCNT ;HERE TO START AT THE BEGINNING
CAMN T2,TNAM(T1) ;MATCH THIS ENTRY?
JRST FOUND ;GOTCHA
HLRZ T3,PTAP(T1) ;NO, GUESS NAME IS GREATERTHAN
CAMG T2,TNAM(T1) ;IS IT?
HRRZ T3,PTAP(T1) ;NO, USE LESSTHAN POINTER
JUMPN T3,NXTINT ;ANYTHING THERE?
SKIPL T3,FINDSP ;NO - HAVE TO ADD AN ENTRY
RET ;LOSING ENTIRES, & ALREADY WARNED
ADD T3,[3,,3] ;SKIP OVER LAST ADDED
MOVEM T3,FINDSP ;YES, STORE FREESPACE POINTER BACK
JUMPG T3,[
WARN <Increase the size of NTAPES, entries being lost>
RET] ;IS THERE ROOM?
CAMG T2,TNAM(T1) ;LESS THAN OR GREATER?
JRST [HRRM T3,PTAP(T1) ;MAKE LESS POINTER POINT TO NEW ENTRY
JRST ADDIN]
HRLM T3,PTAP(T1) ;MAKE GREATER POINTER POINT HERE
ADDIN: MOVE T1,T3
ADDIN2: SETZM PTAP(T1) ;NEW ENTRY. NO POINTERS,..
SETZM TCNT(T1) ;AND NO COUNT
FOUND: MOVEM T2,TNAM(T1) ;STORE NAME
AOS TCNT(T1) ;AND INCR COUNT
EXCH T1,PREHIT ;GET LAST HIT IF ANY
HRRZM T1,EXPHIT ;MAKE IT THE EXPECTED HIT
RET
;This returns in T2 the age of the file looked at by GTFDBF in days.
GTAGE: MOVX T1,1B0+1B17
MOVSI T4,-NDATES
GTAGE1: HLRZ T2,@DATES(T4)
SUB T2,TODAY
CAMLE T2,T1
MOVE T1,T2
AOBJN T4,GTAGE1
MOVN T2,T1
CAIL T2,0 ;Make sure the value is 0 or greater
CAILE T2,^D365*14
SETZ T2,
RET
DATES: FDB+.FBCRV
FDB+.FBWRT
FDB+.FBREF
FDB+.FBTDT ; Last archive d&t
NDATES==.-DATES
; Here to see if a file has already been done once, & record if not
; Ret +1 if already done, +2 if not
CKDNFL: MOVE T1,FDB+.FBADR ; Assume caller has obtained the FDB
SKIPN T4,FILPTR ; Get current count
JRST CKFLD1 ; None, make 1st entry
HRLZS T4 ; Make an AOBJN ptr
CKFLD2: CAMN T1,DONEFL(T4) ; This match?
RET ; Yes, note we've seen the file before
AOBJN T4,CKFLD2 ; No match yet
CKFLD1: MOVEM T1,DONEFL(T4) ; Record new guy
SOS T1,FILPTR ; Update the count
MOVNS T1 ; Make positive count
CAIGE T1,NFILMX ; Over running the buffer?
JRST CPOPJ1 ; No
AOS FILPTR ; Yes, keep using last cell
WARN <File buffer full in CKDNFL - increase NFILMX>
JRST CPOPJ1
;Call with ITMSTK containing an AOBJN pointer, and T4 contaning the address
; of a routine to call to do the output of whetever is in T2.
PRTORD: TXZ F,F.CMMA
PRTO2: SKIPN T2,(ITMSTK)
JRST PROT3 ; Done
TXOE F,F.CMMA
TYPE [ASCIZ/, /]
CALL (T4) ;MUSTN'T HURT T3,T4
AOBJP ITMSTK,PROT3
MOVE T1,LSTPOS
CAIGE T1,^D57
JRST PRTO2
TYPE [ASCIZ/
/]
JRST PRTORD
PROT3: TYPE CRLF
RET
;Read user's MIGRATION.ORDER and set up JFNSTK approprately.
GETORD: TXNN F,F.TRIM ; Will the order be useful?
JRST GETOR4 ; Flag no user order & return
TXO F,F.USOD ; Assume the user will have one
MOVE ITMSTK,JFNPTR ; Where free space starts
PUSH P,GTJBLK+.GJGEN ; Save this, it's set up for someone
MOVX T1,GJ%OLD
MOVEM T1,GTJBLK+.GJGEN ; Set what we need
MOVEI T1,GTJBLK
HRROI T2,[ASCIZ /MIGRATION.ORDER/]
GTJFN%
JRST GETOR3 ; No order list for us
HRRZS T1 ; Probably got flags back
MOVEM T1,TMP ; Save the JFN
MOVX T2,<FLD(7,OF%BSZ)+OF%RD>
OPENF%
JRST [ MOVE T1,TMP ; JFN
RLJFN%
JFCL
JRST GETOR3]
MOVEM ITMSTK,JFNSTP ; Set for user ORDER list
GETOR1: MOVX T1,GJ%OFG+GJ%SHT+GJ%FNS+.GJALL
HRL T2,TMP ; Read from file
HRRI T2,.NULIO ; No output
GTJFN%
JRST GETOR2 ; Abort on error of any kind
MOVEM T1,(ITMSTK) ; Save it
AOBJN ITMSTK,GETOR1 ; Loop until...
WARN <User's ORDER list caused JFN storage to fill up>
GETOR2: SETZM (ITMSTK)
MOVE T1,TMP
CLOSF%
JFCL
GETOR3: POP P,GTJBLK+.GJGEN ; Restore GTJFN block
CAME ITMSTK,JFNPTR ; Get anything?
RET
MOVE T1,[-NJFNS,,JFNLST]
MOVEM T1,JFNSTP
GETOR4: TXZ F,F.USOD ; User didn't have an order list
RET
SUBTTL TAKE command
;TAKE and friends
.POLIC: GUIDES <does a TAKE on SYSTEM:REAPER.CMD>
CONFIRM
MOVX T1,GJ%SHT+GJ%OLD
HRROI T2,[ASCIZ/SYSTEM:REAPER.CMD/]
GTJFN%
JSERRD <Policy file not available>
JRST TAKE1
.TAKE: HLRZ T1,TAKSTK ;GET THE TAKE STACK COUNT
CAIL T1,TAKLEN ;ALL FULL UP?
ERROR <TAKEs nested too deeply, aborting.>
GUIDES <Commands from file>
MOVX T1,GJ%OLD ;JUST AN OLD FILE, PLEASE
MOVEM T1,GTJBLK+.GJGEN
SETZM GTJBLK+.GJDIR
SETZM GTJBLK+.GJDEV
HRROI T1,[ASCIZ/REAPER/]
MOVEM T1,GTJBLK+.GJNAM
HRROI T1,[ASCIZ/CMD/]
MOVEM T1,GTJBLK+.GJEXT
DMOVE T1,[EXP CMDBLK,FICINB] ;INPUT FILE OR CONFRM
CALL PARSE
TRNA
JRST TAKEOK
HRROI T1,[ASCIZ/SYSTEM/]
MOVEM T1,GTJBLK+.GJDEV
DMOVE T1,[EXP CMDBLK,FICINB]
CALL PARSE
ERROR <Not a Confirm or a File Specification>,NOCMD
TAKEOK: CAIN T3,.CMCFM ;CONFIRM OR FILE?
JRST TAKEND
CALL RPSJFN ;SAVE JFN FOR REPARSE
CONFIRM
HRRZ T1,T2 ;GET JFN IN T1
TAKE1: MOVX T2,7B5+OF%RD ;TRY TO OPEN
OPENF%
JSERRD <Can't OPEN file>,NOCMD ;IF AN ERROR OCCURS, SAY WHY AND DIE
HRLZS T1 ;JFN IN LH
HRRI T1,.NULIO ;OUTPUT (NOWHERE) IN RH
;JRST PUSTAK
;HERE WITH T1/ INJFN,,OUTJFN TO PUSH TO NEW INPUT & OUTPUT
PUSTAK: MOVE Q1,TAKSTK ;GET THE TAKE STACK
EXCH T1,CMDBLK+.CMIOJ;WHERE COMND LOOKS NOW
PUSH Q1,T1 ;SAVE OLD SOURCE ON TAKE JFN STACK
MOVEM Q1,TAKSTK ;SAVE STACK POINTER
RET
TAKEND: CALL TAKEOS
ERROR <No TAKE files active>,CPOPJ
RET
TAKEOS: TXOA F,F.TMP ;DON'T WANT ENDING MESSAGE
TAKEOF: TXZ F,F.TMP ;ALLOW END MESSAGE
MOVE Q1,TAKSTK ;GET TAKE STACK
TAKEO2: TLNN Q1,-1
RET ;NO OPERATION IF EMPTY STACK
POP Q1,T1 ;RESTORE PREVIOUS JFNS
MOVEM Q1,TAKSTK
EXCH T1,CMDBLK+.CMIOJ;GIVE BACK LAST JFNS
HLRZ T2,T1 ;GET COMMAND INPUT JFN IN T2
CAIN T2,.PRIIN ;IS IT MAIN INPUT?
JRST CPOPJ1 ;YEAH, DON'T ANNOUNCE OR CLOSE
TXZE F,F.TMP
JRST TAKEO3 ;NO ENDING MESSAGE
CALL IFCRLF ;ANNOUNCE WHAT'S ENDING
TYPE <[ASCIZ/[Ending /]>
CALL TYJFNS
TYPE CBCR ;CLOSE BRACKET CRLF
TAKEO3: MOVE T1,T2
CLOSF% ;CLOSE THE FILE OUT
JSERRD <>,CPOPJ1 ;FAILURE SEEMS UNLIKELY
JRST CPOPJ1 ;+2 RET
;Here to blow away all take files
UNTAKE: CALL TAKEOF ;END THE CURRENT TAKE FILES
RET ;DONE
JRST UNTAKE ;GO UNTIL NONE LEFT
SUBTTL Parsing
;To parse a wild filespec
GETFIL: PUSH P,T1 ; Save parse only param
SETO T1, ; Say we want *'s
CALL SETGTD ; Set the defaults for GTJFN
MOVX T1,GJ%OLD+GJ%IFG+GJ%DEL
IORM T1,GTJBLK+.GJGEN
POP P,T1
JUMPGE T1,GETFL2
MOVX T1,GJ%IFG+GJ%OLD
ANDCAM T1,GTJBLK+.GJGEN
MOVX T1,GJ%OFG
IORM T1,GTJBLK+.GJGEN
GETFL2: DMOVE T1,[EXP CMDBLK, FILINB]
;JRST PARSE
; Sucessful parse returns usual flags in T1, usual stuff in T2, the
; type of block in T3. Bad parse returns +1, good +2.
PARSE: COMND%
HITME: ERJMP PAREOF
TXNE T1,CM%NOP
RET ;DIDN'T PARSE
LDB T3,[POINT 9,(T3),8]
CPOPJ1: AOS (P)
RET
PAREOF: MOVX T1,.FHSLF ;WHAT WENT WRONG?
GETER% ;..
HRRZ T1,T2 ;ISOLATE ERROR CODE
CAIN T1,DESX3 ;DID WE LOSE THE JFN?
JRST [MOVEI T1,TAKSTR ;YES, ASSUME ^C/START
MOVEM T1,TAKSTK ;BLOW AWAY COMMAND STACK
MOVE T1,[.PRIIN,,.PRIOU] ;AND TALK TO TERMINAL
MOVEM T1,CMDBLK+.CMIOJ
JRST PANIC]
CAIE T1,IOX4 ;EOF?
JSERRD <Can't parse command>,PANIC,JRST ;NO, COMPLAIN
CALL TAKEOF ;ASSUME EOF, DROP A COMMAND LEVEL
JSERRD <Parse error>,PANIC,JRST ;IF THERE ISN'T A TAKE FILE, WEIRD
TXNE F,F.PRIV ;IS THIS A PEON?
JRST PANIC ;NO, RESTART
JRST PEON2 ;YES, SECOND STAGE PEON CODE PLEASE
;CALL to confirm. Skip ret if all OK.
CONFRM: DMOVEM T1,1(P)
MOVEM T3,3(P)
DMOVE T1,[EXP CMDBLK,CONINB]
COMND%
ERJMP PAREOF
TXNE T1,CM%NOP
ERROR <Not confirmed>,CPOPJ
MOVE T3,3(P)
DMOVE T1,1(P)
JRST CPOPJ1
;Here with a word address of a string to guide with in T1. Skip if OK.
GUIDE: HRROM T1,GUIINB+.CMDAT
DMOVEM T2,1(P)
DMOVE T1,[EXP CMDBLK,GUIINB]
COMND%
ERJMP PAREOF
TXNE T1,CM%NOP
ERROR <Illegal guide word>,CPOPJ
DMOVE T2,1(P)
JRST CPOPJ1
;Call with T1 pointing to a 0 terminated list of characters to stop on.
; This copies characters out of the COMND% buffer into the atom buffer,
; stopping on null or one of the characters listed. T3 is returned as the
; character matched, or 0 if noting did.
SKIPTR: MOVEM T1,TMP
MOVE T4,[POINT 7,ATOM]
SETZ T3,
JRST SKIPT3
SKIPT1: CAIE T2,.CHCRT
CAIN T2,.CHLFD
TRNA ;DON'T COPY THESE TO ATOM BUFFER
IDPB T2,T4
SKIPT3: SOS CMDBLK+.CMINC
ILDB T2,CMDBLK+.CMPTR
JUMPE T2,NFIND
MOVE T1,TMP
SKIPT2: SKIPN T3,(T1)
JRST SKIPT1
CAIE T2,(T3)
AOJA T1,SKIPT2
SETZ T2,
NFIND: IDPB T2,T4
RET
SETGTD: MOVE T2,[GTJBLK,,GTJBLK+1]
SETZM -1(T2)
BLT T2,GTJBLK+.GJBFP ; Clear it to start
MOVE T2,[.PRIIN,,.PRIOU]
MOVEM T2,GTJBLK+.GJSRC
MOVX T2,GJ%XTN
IORM T2,GTJBLK+.GJGEN
MOVX T2,G1%IIN
MOVEM T2,GTJBLK+.GJF2 ; Into extended blk
JUMPE T1,CPOPJ ; Done if doesn't want stars
HRROI T2,[ASCIZ /*/]
MOVEM T2,GTJBLK+.GJDIR ; For directory name
MOVEM T2,GTJBLK+.GJNAM ; For file name
MOVEM T2,GTJBLK+.GJEXT ; For extention
MOVX T2,GJ%IFG+.GJALL
IORM T2,GTJBLK+.GJGEN
RET
SUBTTL Error support
;ERROR and special output routines.
;ANNERR is good to call when you hit an error. If you are in a TAKE file,
; it <CRLF>s at need and types the failing command back to the user. It
; makes sure the next output starts at the margin and clears the input
; buffer.
ANNERR: DMOVEM T1,IFCTMP
MOVX T1,.CTTRM
RFMOD%
TXZE T2,TT%OSP ;CLEAR ^O
SFMOD%
CFIBF%
CALL WHERE
JRST .+2 ;FROM FILE
JRST IFCRL2 ;FROM TERMINAL
MOVEM T1,INPTMP
CALL IFCRL2
TYPE [ASCIZ/?In command /]
TYPE BFFR ;TYPE COMMAND
CALL IFCRL2
TYPE [ASCIZ/?In file /]
MOVE T2,INPTMP
CALL TYJFNS
JRST IFCRL2 ;DO IFCRLF, RESTORING CALLER'S AC'S
IFCRLF: DMOVEM T1,IFCTMP
IFCRL2: MOVEI T1,.PRIOU
DOBE%
RFPOS%
TRNE T2,-1
YSCRLF: TYPE CRLF
NOCRLF: DMOVE T1,IFCTMP
CPOPJ: RET
;WHERE skips if the commands are coming in from .PRIIN
; The current input JFN is returned in T1
WHERE: HLRZ T1,CMDBLK+.CMIOJ ;GET THE INPUT SOURCE
CAIN T1,.PRIIN ;PRIMARY INPUT?
AOS (P) ;YES, SKIP RET
RET
LSTERR: TLCE T1,-1 ;ANY LEADER STRING BEYOND "?"
TLCN T1,-1
HRLI T1,(POINT 7)
MOVEI T2,2 ;POINT TO 2ND CHARACTER
ADJBP T2,T1
LDB T2,T2 ;FETCH
TYPEAT T1
CAIE T2,0 ;JUST ONE CHAR (IE, "?") ?
LSTERD: TYPE [ASCIZ/ - /] ;IF YES, DON'T TYPE THIS
LSTERO: HRLOI T2,.FHSLF
LSTERC: HRROI T1,STRING
SETZ T3,
ERSTR%
JFCL
JFCL
TYPE STRING
RET
SUBTTL Terminal and List file output
;Terminal and list file, etc I/O subroutines
;Get text to proper places (Terminal, list file, etc). OUTMSG if the pointer
; passed could be anything, including null. OUTMSS if the pointer certainly
; contains some sort of pointer. OUTMSA if the pointer is PSOUT% legal.
; OUTMTT if the string is in TEMP2.
; TYPE and TYPEAT come here. Enter with T1 on the stack.
OUTMSG: JUMPE T1,OUTMS3 ;NULL POINTER OR CHARACTER? NOOP IF SO.
OUTMSS: TLNE T1,-1 ;POINTER OR CHARACTER?
JRST OUTMSA ;POINTER, GO USE
OUTMSC: HRLZM T1,OUTMSX ;CHARACTER. TUCK INTO STORAGE..
SKIPA T1,[POINT 7,OUTMSX,10] ;AND FETCH A POINTER TO IT
OUTMTT: HRROI T1,TEMP2 ;WHERE CALLER WROTE STRING
OUTMSA: MOVEM T1,OUTMST ;STORE THE POINTER TO THIS TEXT
PUSH P,T4 ;SAVE T4
MOVE T4,LSTFLG ;ARE WE WRITING THIS ANYWHERE?
TXNE T4,LS.TTY ;OUT TO PRIMARY OUTPUT?
PSOUT% ;YES
TXNE T4,LS.LST
SKIPN T1,LSTJFN ;FETCH LIST JFN
JRST OUTMSD ;NOT AVAILABLE, FINE
PUSH P,T2
PUSH P,T3
SKIPGE LSTLIN ;NEED A HEADER FIRST?
CALL FSTPGN ;YES, DO THAT
MOVE T2,OUTMST ;POINTER TO TEXT
SETZ T3, ;GO UNTIL NULL SEEN
SOUT% ;WRITE TO LIST FILE
ERJMP NOLSTF
SKIPGE T3,LSTPOS ;DID CALLER ALREADY FIGURE LSTPOS FOR US?
JRST [MOVNS T3 ;YES, JUST SET IT RIGHT
JRST CNTSP2]
MOVE T1,OUTMST
TLC T1,-1 ;UPDATE LSTPOS
TLCN T1,-1
HRLI T1,(POINT 7)
CNTSPC: ILDB T2,T1
JUMPE T2,CNTSP2
CAIN T2,.CHCRT
JRST [SETZ T3,
JRST CNTSPC]
CAIN T2,.CHLFD
JRST PAGTST ;<LF> DONE BELOW
CAIN T2,.CHTAB
JRST [TRO T3,7
AOJA T3,CNTSPC]
CAIGE T2," "
ADDI T3,1 ;ASSUME CTRL CHARS ARE 2 WIDE (^x)
AOJA T3,CNTSPC
PAGTST: AOS T4,LSTLIN
CAIL T4,PAGLIN ;LINES/PAGE
CALL FSTPGN ;NEED A PAGE HEADER
JRST CNTSPC ;NOT A NEW PAGE YET, GO ON
FSTPGN: PUSH P,T1
MOVE T1,LSTJFN ;SET UP TO OUT A ^L
MOVEI T2,.CHFFD
BOUT%
ERJMP .+1
SETZM LSTLIN
POP P,T1
RET
CNTSP2: MOVEM T3,LSTPOS
POP P,T3
POP P,T2
OUTMSD: POP P,T4
OUTMS3: POP P,T1
RET
;Error while writing list file - end the list file
NOLSTF: SKIPE T1,LSTJFN ;LIST FILE HERE?
CLOSF% ;YES, CLOSE IT
ERJMP .+1
SETZM LSTJFN
MOVX T4,LS.LST ;SAY NO MORE LIST FILE
ANDCAM T4,LSTFLG
CALL ANNERR ;ANNOUNCE ERROR
TYPE [ASCIZ/?Error writing LIST file, list file ended
/] ;RECURSION!
SETZ T3,
JRST CNTSP2
;TABOUT only works for the list file (because OUTMSG only follows the line
; position of the list file)
; Give it the column to get to in T2. This always outputs at least 1 space.
TABOUT: PUSH P,T1 ;BECAUSE OUTMSA WANTS THAT
MOVE T1,[POINT 7,TABTMP] ;A PLACE TO WRITE TO
MOVE T3,LSTPOS ;FIND OUT WHERE WE ARE
MOVEM T3,LSTTMP ;SAVE IT
MOVEI T4,.CHTAB ;PREPARE TO WRITE SOME TABS
TRZ T3,7 ;FIGURE THE EFFECT OF THE FIRST TAB
ADDI T3,8 ;..
TABITH: IDPB T4,T1 ;IN GOES THE TAB
CAIL T3,(T2) ;FAR ENOUGH?
JRST TTOFAR ;YES, MAYBE TOO FAR
MOVEM T3,LSTTMP ;TAB WAS OK, REMEMBER WHERE WE ARE
ADDI T3,8 ;SIMULATE THE NEXT TAB
JRST TABITH ;AND GO DO IT
TTOFAR: CAIG T3,(T2) ;DID WE GO TOO FAR?
JRST TOKOUT ;NO, JUST RIGHT, FINISH UP
MOVEI T4," " ;TOO FAR, OVERWRITE LAST TAB WITH SPACE
DPB T4,T1 ;..
AOS T3,LSTTMP ;ACCOUNT FOR SPACE
TSPOUT: CAIL T3,(T2) ;ENOUGH SPACES?
JRST TOKOUT ;YES, FINISH UP
IDPB T4,T1 ;NO, SPACE GOES IN
AOJA T3,TSPOUT ;ADVANCE THE COUNT AND GO ON
TOKOUT: MOVNM T3,LSTPOS ;TELL OUTMSA WE FIGURED THE LENGTH FOR IT
SETZ T4, ;NULL TO END
IDPB T4,T1 ;..
HRROI T1,TABTMP ;THE STRING WE WROTE
JRST OUTMSA ;GETS WRITTEN NOW
; Listing routines
;LSTFIL types out the current filename, either from the JFN in LOCJFN (if
; F.GOTN is off) or directly from the text at GOTNAM (if F.GOTN is on). It
; also clears F.GOTN when called.
LSTFIL: TXON F,F.NDIR ; New directory?
CALL LSTDIR ; Yes, spit it out
PUSH P,T2 ; Save note
TXZE F,F.GOTN ; Got name already?
JRST [TYPE GOTNAM
JRST LSTFI1]
HRRZ T2,LOCJFN
MOVX T3,JFNSNE ;Filnam, type, gen, and punctuation
CALL TYJFNF
LSTFI1: MOVEI T2,^D40
CALL TABOUT
POP P,T2 ; Note
CAIE T2,0 ; Any?
TYPEAT T2
TYPE CRLF
RET
LSTDIR: PUSH P,T2
TYPE [ASCIZ/
/]
CALL TYDIRC ;Type current directory name
TYPE CRLF
TXNN F,F.USOD ;HAVE A USER ORDERING?
JRST LSTDI1
TYPE [ASCIZ/ user ordering: /]
MOVEM ITMSTK,TMP
MOVE ITMSTK,JFNSTP
MOVX T3,JFNSNX
MOVEI T4,TYJFNF
CALL PRTORD
MOVE ITMSTK,TMP
LSTDI1: POP P,T2
RET
OPNLST: HRRZS T1
MOVE T2,[7B5+OF%APP]
OPENF%
ERJMP NOLISF
JRST CPOPJ1
NOLISF: HRRZS T1
RLJFN%
ERJMP .+1
RET
;Here to output time and date
TADOUT: PUSH P,T1
SETO T2,
MOVX T3,OT%NSC+OT%NCO+OT%SCL+OT%DAY
HRROI T1,TEMP2
ODTIM%
ERJMP .+1
JRST OUTMTT
;Here with a number in T2 to output. DECOUT loses T3. DECOUT & NUMOUT
; act identically to TYPE (it calls OUTMSG). NUMOUT can be treated
; exactly like NOUT% in terms of radixs and flags.
DESOUT: SKIPA T3,[NO%LFL+NO%OOV+5B17+^D10]
DECOUT: MOVEI T3,^D10 ;RADIX 10
NUMOUT: PUSH P,T1 ;MOSTLY BECAUSE OUTMSA WANTS IT
HRROI T1,TEMP2
NOUT%
ERJMP .+1
JRST OUTMTT
;Type JFN in T2
TYJFNS: MOVE T3,[JFNSAL]
TYJFNF: HRROI T1,TEMP2
JFNS%
ERJMP CPOPJ
PUSH P,T1
JRST OUTMTT ;TYPE STRING
;Type the directory name referenced by T2
TYDIRC: MOVE T2,CURDIR
TYDIRS: PUSH P,T1
HRROI T1,TEMP2
DIRST%
ERJMP .+1
JRST OUTMTT
;Acts like CSTRB, except T1/ number to output (decimal)
NOUTB: EXCH T1,T2
MOVEI T3,^D10
NOUT%
ERJMP .+1
EXCH T1,T2
RET
;Copy string and back up T2 on exit. Return last character in T3.
CSTRB: CALL CSTR
SETO T3,
ADJBP T3,T2
MOVE T2,T3
RET
;More string copy stuff. Takes T1 and T2 as the from and to, and returns
; T3 as 0.
CSTR: TLCE T1,-1
TLCN T1,-1
HRLI T1,(POINT 7)
TLCE T2,-1
TLCN T2,-1
HRLI T2,(POINT 7)
CSTRA: ILDB T3,T1
IDPB T3,T2
JUMPN T3,CSTRA
RET
;Output sixbit string in T3. Hurts T2 and T3
SIXOUT: PUSH P,T1
SETZ T2, ;PREPARE TO CONVERT TO ASCIZ
JUMPE T3,SIXOU1 ;IF NONE, ALREADY CONVERTED, SO TO SPEAK
JRST V6TO7B
V6TO7: LSH T2,1 ;ROOM FOR ASCII BIT (OR, MAKE LEFT JUSTIFIED)
TLNE T2,774K ;DONE? (ANYTHING IN 1ST BYTE?)
JRST V6TO7D ;YES, GO STORE
V6TO7B: LSHC T2,6 ;FETCH NEXT 6BIT BYTE INTO T2
TRNE T2,77 ;IS IT REAL?
ADDI T2," " ;YES, CONVERT TO ASCII
JRST V6TO7
V6TO7D: JUMPE T3,SIXOU1 ;IS 6TH BYTE NONEXISTANT?
LSH T3,-1 ;NO, NEEDS CONVERTING
ADD T3,[BYTE(7) " ",0]
SIXOU1: DMOVEM T2,TEMP2
JRST OUTMTT
;Here to push the JFN in T2 and the address of the "delete jfn" routine
; on the reparse stack.
RPSJFN: MOVEI T1,RPSJFD
HRL T1,T2
EXCH T1,RPSSTK ;SAVE DATA, GET STACK POINTER
PUSH T1,RPSSTK ;PUT DATA ON REPARSE STACK
EXCH T1,RPSSTK ;GET T1 BACK, PUT STACK POINTER AWAY AGAIN
RET
;Here to get something off the reparse stack. +1 ret with something in T1,
; +2 with nothing on stack anymore.
RPSGET: EXCH T2,RPSSTK
TLNN T2,-1 ;EMPTY STACK?
AOSA (P) ;YES, SKIP RETURN
POP T2,T1
EXCH T2,RPSSTK
RET
UNDO: CALL RPSGET
JRST GOUNDO ;RH OF T1 HAS THE ADDR OF A ROUTINE TO CALL
RET ;NOTHING LEFT TO UNDO
GOUNDO: CALL (T1) ;GO DO ROUTINE
JRST UNDO ;GO UNTIL REPARSE STACK EMPTY
JRST UNDO ;IN CASE OF A SKIP RETURN
RLJFNS: SKIPE T1,(ITMSTK) ; Anything?
RLJFN% ; Yes, release it
JFCL
SETZM (ITMSTK)
AOBJN ITMSTK,RLJFNS
RET
RPSJFD: HLRZS T1 ;DROP THE JFN IN THE LF OF T1
;Here to drop the JFN in T1 as though we never touched it
DRPJFN: JUMPE T1,CPOPJ ;IF NO JFN, FINE
GTSTS% ;IS THE JFN OPEN AT ALL?
JUMPL T2,DRPOFN ;IF SO, CLOSF%
RLJFN%
ERJMP .+1 ;IF NOT, RLJFN%, IF FAILS, CLOSF%
RET
DRPOFN: HRLI T1,(CZ%ABT+CZ%NUD)
CLOSF% ;THIS JFN NEVER HAPPENED
ERJMP .+1
RET
SUBTTL File information subroutines
; Here to determine if file has ANY tape info associated with it
HAVTAP: SKIPN TAPBLK+.ARTP1 ; Tape 1 ID there?
SKIPE TAPBLK+.ARTP2 ; No, how about tape 2 ID?
RET ; At least one is there
JRST CPOPJ1 ; Neither are there
GTFDBF: HRRZ T1,LOCJFN
MOVSI T2,.FBLEN
MOVEI T3,FDB
GTFDB%
ERJMP [HRLI T2,.FBLN0 ; Probably a short FDB
GTFDB%
JRST .+1]
LDB T2,[POINT 7,(T3),35]
CAIGE T2,.FBLXT ; Long enough for tape info?
JRST [ SETZM .FBTDT(T3) ; No, date is not valid then
SETZM TAPBLK+.ARTP1 ; No tape info
SETZM TAPBLK+.ARTP2 ; ...
RET]
HRRZS T1 ; JFN only
MOVX T2,.ARGST ; Get tape info
MOVEI T3,TAPBLK
ARCF%
ERJMP .+1
RET
CRLF: ASCIZ/
/
CRLF2: ASCIZ/
/
CBCR: ASCIZ/]
/
;Some parsing tokens
CMDINB: <.CMKEY>B8
CMDLST
CMDLST: CMDLEN,,CMDLEN
CTB .ARCHI, <BEGIN>
CTB .FLUSH, <DELETE-CONTENTS>
CTB .EXIT, <EXIT>
CTB .LIST, <LIST>
CTB .INVOL, <MIGRATE>
CTB .ORDER, <ORDER>
CTB .PERIO, <PERIOD>
CTB .POLIC, <POLICY>
CTB .PURGE, <PURGE>
; CTB .REAPE, <REAP>
CTB .SCAN, <SCAN>
CTB .SKIP, <SKIP>
CTB .TAKE, <TAKE>
CTB .TAPE, <TAPE>
CTB .TRIM, <TRIM>
CMDLEN=.-CMDLST-1
FICINB: <.CMCFM>B8+FILINB
FILINB: <.CMFIL>B8
PERINB: <.CMNUM>B8+CM%SDH+CM%HPP
^D10
-1,,[ASCIZ/Number of days/]
SKPINB: <.CMDIR>B8+CM%SDH+CM%HPP
CM%DWC
-1,,[ASCIZ/Name of directory to SKIP/]
CMCINB: <.CMCMA>B8+CONINB
INIINB: <.CMINI>B8
CONINB: <.CMCFM>B8
END <3,,ENTVEC>