Google
 

Trailing-Edge - PDP-10 Archives - bb-x130a-sb - nik.mac
There is 1 other file named nik.mac in the archive. Click here to see a list.
	TITLE	NIK %1(15) NETWORK INTERCHANGE KLUDGE
	SUBTTL

	SALL

	SEARCH	JOBDAT,UUOSYM,MACTEN,SCNMAC

	.REQUE	NIKLIB,ACCSCN,ACCWLD,REL:HELPER

	.TEXT	'/SYMSEG:HIGH/LOCALS'	;KEEP WEM HAPPY
	SUBTTL	REVISION HISTORY

;INITIAL VERSION CREATED FROM SC + XMIT FILES  30-NOV-78

;1	RDH	4-DEC-78
;	REWORK DATA FILE I/O TO KEEP RUNNING CHECKSUM OF USER DATA,
;	VERIFY CHECKSUM AT END OF TRANSFER. /PERCENT GOT LOST.
;	ADD FIRST SUPPORT CODE FOR /ANYPPN.

;2	RDH	30-DEC-78
;	REVAMP TO SUPPORT BI-DIRECTIONAL FILE TRANSFER, ADD FOUNDA-
;	TION FOR /COPY, /DELETE, /DIRECT, AND /RENAME.

;3	RDH	21-JAN-79
;	USE NON-BLOCKING TSK: I/O TO AVOID PERMANENT EW WAIT STATE
;	UNDER 7.01 LOAD 332

;4	RDH	25-JAN-79
;	NXTFIL TRASHED FILE I/O CHANNEL IN OBSCURE CONDITIONS

;5	RDH	30-JAN-79
;	PUSH/CLEAR/RESTORE .RBNCA IN TELFIL (ACCSCN TREATS IT AS THE
;	SECOND 6 CHARACTERS IN FILE NAME)

;6	RDH	23-MAR-79
;	ADD "NIK" COMMAND ENTRY (CCL COMMAND FROM MONITOR). ZERO .RBNCA
;	FOR THE TIME BEING. ADD /TOTALS TO PRINT FILE/BLOCKS TOTALS.

;7	RDH	16-MAY-79
;	USE NAME "ANYNIK" IF /ANYPPN SINCE 7.01 TREATS [777777,777777]
;	AS [*,*]. CHANGE NAME (/PERCENT) LESS OFTEN. ADD BAUD TO
;	I/O SUMMARY MESSAGE. FIX /OKERROR. USE DIFFERENT TASK NAME IF
;	USING IMAGE MODE.

;10	RDH	23-AUG-79
;	ADD /WAIT TO WAIT INDEFINITELY FOR REMOTE NIK TO APPEAR (ONLY
;	IF NODE IS PRESENT). OTHER MINOR EDITS.

;11	RDH	9-SEP-79
;	EDIT IN ACCSCN TO PICK UP SCAN EDIT 573 (CCL FILE FROM AN SFD).
;	ALSO FORCE WILD TO USE OUTPUT SCAN BLOCK DEVICE NAME, NEVER
;	.RBDEV SINCE IT IS USUALLY WRONG (SUPPLIED BY LOOKUP DONE BY NIK
;	ON OTHER SYSTEM).

;12	RDH	22-OCT-79
;	PROMPT "#" RATHER THAN "-" ON CONTINUATION LINES

;13	RDH	20-DEC-79
;	(IN WILD) MAKE ERROR ROUTINE E.LKEN (LOOKUP/ENTER ERROR) NOT
;	DESTROY WILD'S DATABASE SUCH THAT FUTURE CALLS TO .LKWLD FIND
;	LAST CALL TO E.LKEN'S FILE (PRIMARILY A PROBLEM WHEN CALLED
;	FOR ENTER ERROR FROM .SCWLD, BUT EFFECTS ARE FAR RANGING).

;14	RDH	24-JAN-80
;	SHRINK PROTOCOL BLOCK BY A WORD (WHICH TURNED OUT TO BE EXTRANEOUS
;	ANYWAY) TO KEEP BUFFERSIZE WITHIN 100 OCTAL WORDS IN ORDER TO BE
;	ABLE TO TALK BETWEEN 6.03 AND 7.00.

;15	RDH	5-FEB-80
;	14 DIDN'T QUITE MAKE IT - A BLT WAS OFF BY ONE.

;VERSION NUMBER

MAJVER==1		;MAJOR VERSION LEVEL
MINVER==0		;MAINTENANCE LEVEL
CSTVER==0		;CUSTOMER VERSION
EDTVER==15		;EDIT LEVEL

	LOC	.JBVER
	<%%NIK==:<BYTE (3)CSTVER(9)MAJVER(6)MINVER(18)EDTVER>>
	RELOC


	TWOSEG	400000
	SUBTTL	SYMBOL DEFINITIONS

;THE ACS

	T1=1
	T2=2
	T3=3
	T4=4
	P1=5
	P2=6
	P3=7
	P4=10

	P=17	;THE GOOD OLE PUSHDOWN POINTER

;OTHER STUFF

	PDLEN==^D50
	FLPLEN==.FOPPN+1;LENGTH OF FILOP. BLOCKS
	FILLEN==.RBAC8	;LENGTH OF LOOKUP/ENTER BLOCKS
	PTHLEN==.PTMAX-1;LENGTH OF PATH BLOCK
	DSKLEN==.DCSNM+1;LENGTH OF DSKCHR BLOCK

;I/O CHANNELS OF INTEREST

	$TSK==1		;TASK I/O CHANNEL
	$DSK==2		;DISK READING CHANNEL
	SUBTTL	MACRO DEFINITIONS

;ERROR - PRINT ERROR MESSAGE AND ABORT
;CALL IS:
;
;	ERROR	PFX,TXT,RTN,ADR,DIE
;
;WHERE PFX IS THE 3-LETTER ERROR MNEMONIC; TXT IS ERROR TEXT TO
;BE TYPED OUT; ADR IS OPTIONAL AND IF SPECIFIED IS ADDRESS
;FROM WHICH TO LOAD T1 FOR RTN (USING T1-T4 OR P IS ILLEGAL);
;RTN IS OPTIONAL AND IF SPECIFIED IS SPECIAL ROUTINE TO CALL
;AFTER TXT PRINTED (ONLY CALLED IF /MESS:FIRST) AND WITH T1 LOADED
;FROM ADR; AND DIE IS OPTIONAL RESUME ADDRESS (DEFAULT IS PC+1
;FOR ALL BUT ERROR, WHOSE DEFAULT IS A POPJ P,).

DEFINE	ERROR(PFX,TXT,RTN<0>,ADR<0>,DIE<.POPJ##>),<
E..'PFX::PUSHJ	P,[PUSHJ P,ERRMSG	;;CALL ERROR MESSAGE PROCESSOR
	 SIXBIT\NIK'PFX\		;;PREFIX
	 "?",,[ASCIZ\TXT\]		;;CHAR AND TEXT BODY
	 Z	RTN			;;ADDITIONAL ROUTINE
	 Z	ADR			;;ADDITIONAL ADDRESS
	 Z	DIE]			;;RESUME ADDRESS
> ;END ERROR MACRO


DEFINE	WARN(PFX,TXT,RTN<0>,ADR<0>,DIE<.+1>),<
E..'PFX::PUSHJ	P,[PUSHJ P,ERRMSG	;;CALL ERROR MESSAGE PROCESSOR
	 SIXBIT\NIK'PFX\		;;PREFIX
	 "%",,[ASCIZ\TXT\]		;;CHAR AND TEXT BODY
	 Z	RTN			;;ADDITIONAL ROUTINE
	 Z	ADR			;;ADDITIONAL ADDRESS
	 Z	DIE]			;;RESUME ADDRESS
> ;END WARN MACRO


DEFINE	INFORM(PFX,TXT,RTN<0>,ADR<0>,DIE<.+1>),<
E..'PFX::PUSHJ	P,[PUSHJ P,ERRMSG	;;CALL ERROR MESSAGE PROCESSOR
	 SIXBIT\NIK'PFX\		;;PREFIX
	 "[",,[ASCIZ\TXT\]		;;CHAR AND TEXT BODY
	 Z	RTN			;;ADDITIONAL ROUTINE
	 Z	ADR			;;ADDITIONAL ADDRESS
	 Z	DIE]			;;RESUME ADDRESS
> ;END INFORM MACRO
	SUBTTL	INITIALIZATION

NIK:	TDZA	P,P		;REGULAR ENTRY POINT
	MOVEI	P,1		;CCL ENTRY (OFFSET OF 1)
	MOVEM	P,CCLFLG	;SET IT FOR .ISCAN
	MOVE	P,[IOWD PDLEN,PDLST] ;SETUP STACK
	MOVE	T1,[PUSHJ P,ERR##]
	MOVEM	T1,.JB41##
	RESET			;"STOP THE WORLD" - FAILSA
	MOVE	P1,[PTHLEN,,PTHBLK]  ;POINTER TO READ
	SETOM	PTHBLK		;DEFAULT (-1) PATH BLOCK
	PATH.	P1,		;ASK MONITOR
	 ERROR	PTH,<PATH to read default path failed>,,,ERRDIE
	SETZM	PTHBLK		;CLEAR EXTRANEOUS BITS
	SETZM	PTHBLK+1	;DITTO
	MOVE	P1,[.NDRNN,,P2]	;SET TO READ HOST NODE NAME
	MOVEI	P2,2		;LENGTH FOR NODE.
	MOVSI	P3,'CTY'	;IDENTIFY HOST
	WHERE	P3,UU.PHY	;BY TRADITIONAL MEANS
	 ERROR	WHR,<WHERE for host failed>,,,ERRDIE
	ANDI	P3,-1		;JUST HOST NODE NUMBER
	MOVEM	P3,MYNNM	;REMEMBER THE NUMBER
	NODE.	P1,		;ASK FOR NODE NAME
	 ERROR	NOD,<NODE. for host failed, code >,.TOCTW##,P1,ERRDIE
	MOVEM	P1,MYNOD	;REMEMBER THE NAME AS WELL
	MOVE	T1,[ISLEN,,ISBLK] ;.ISCAN BLOCK
	PUSHJ	P,.ISCAN##	;INITIALIZE SCAN

;FALL INTO MAIN COMMAND LOOP ON NEXT PAGE
	SUBTTL	MAIN CONTROL LOOP

SCAN:	SETZM	SIFIR		;CLEAR OUT THE OLD DATA BASE
	MOVE	T1,[TSLEN,,TSBLK] ;.TSCAN BLOCK
	PUSHJ	P,.TSCAN##	;READ A COMMAND LINE
	MOVE	T1,[OSLEN,,OSBLK]  ;.OSCAN BLOCK
	PUSHJ	P,.OSCAN##	;CHECK SWITCH.INI
	SKIPLE	S.RECV		;/RECEIVE GIVEN?
	JRST	RECV##		;YES, BECOME A PASSIVE RECEIVER THEN
	SKIPN	P1,SIFIR	;ADDRESS OF FIRST INPUT SPEC
	JRST	SCAN		;NONE?????
	SKIPN	P2,.FXNOD(P1)	;GET FIRST INPUT NODE FOR DEFAULTING
	MOVE	P2,MYNOD	;DEFAULT DEFAULT NODE TO ME
	SETZM	FILES		;INITIALLY NO FILES PROCESSED
	SETZM	BLOCKS		; . . .
	SETZM	WORDS		; . . .
	SETZM	MSECS		; . . .
	SETZM	ERRORS		; . . .
SCAN02:	MOVE	T1,P1		;ADDRESS OF CURRENT INPUT SPEC
	MOVEI	T2,.FXLEN	;AND ITS LENGTH
	PUSHJ	P,.OSDFS##	;APPLY SWITCH.INI DEFAULTS
	SKIPN	T3,.FXNOD(P1)	;GET USER SPECIFIED NODE
	MOVE	T3,P2		;NONE, USE LAST SPECIFIED (OR US)
	MOVE	P2,T3		;SET NEW LAST SPECIFIED
	PUSHJ	P,NDNAM		;TRY TO FORCE NODE NAME TO FULL SET
	MOVEM	T1,.FXNOD(P1)	;SET NODE NAME
	MOVX	T1,FX.PRT	;THE /OKPROT SWITCH BIT
	TDNN	T1,.FXMOM(P1)	;EXPLICIT /OKPROT/ERPROT?
	ANDCAM	T1,.FXMOD(P1)	;NO, DEFAULT TO /ERPROT
				; CONSIDER "26_NUL:=ACCT.SYS[1,4]"
	IORM	T1,.FXMOM(P1)	;MAKE SURE NOBODY ELSE UNDEFAULTS US!
	ADDI	P1,.FXLEN	;STEP TO NEXT SPEC
	CAMG	P1,SILAS	;REACHED LAST ONE YET?
	JRST	SCAN02		;NOPE, LOOP BACK FOR MORE DEFAULTS
	SKIPN	T3,OUSCN+.FXNOD	;SPECIFIED DESTINATION NODE
	MOVE	T3,MYNOD	;NONE GIVEN, SEND TO US THEN
	PUSHJ	P,NDNAM		;TRY TO MAKE SYMBOLIC NAME
	MOVEM	T1,OUSCN+.FXNOD	;SET DESTINATION NAME
	MOVSI	T2,'*  '	;DEFAULT FULL WILD NAME
	SKIPE	OUSCN+.FXNAM	;OUTPUT FILE NAME GIVEN?
	JRST	SCAN04		;YES
	MOVEM	T2,OUSCN+.FXNAM	;NO, DEFAULT FULL WILD
	SETZM	OUSCN+.FXNMM	;AND FULL WILD MASK
SCAN04:	SKIPN	OUSCN+.FXEXT	;OUTPUT EXTENSION GIVEN?
	HLLZM	T2,OUSCN+.FXEXT	;NO, DEFAULT TO FULL WILD
	MOVX	T1,FX.PRT	;THE /OKPROT BIT
	ANDCAM	T1,OUSCN+.FXMOD	;FORCE /ERPROT FOR OUTPUT FILE
	IORM	T1,OUSCN+.FXMOM	;AND MAKE IT STICKY
				; THIS IS DONE FOR REASONS TO OBSCURE TO
				; DETAIL HERE, BU BASICALLY BECAUSE E.LKEN
				; IS CALLED BY BOTH E.DFL AND E.SCL.
	HLLOS	SCFLG		;SET OK TOO MANY INPUT WILDCARDS

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;NOW LOOP OVER SPECS DOING REQUESTED ACTION, GROUPED BY NODE

SCAN10:	MOVE	P1,MYNOD	;OUR (LOCAL) NODE NAME
	MOVE	T1,SIFIR	;FIRST (OR NEXT SET) INPUT SPEC
	CAMLE	T1,SILAS	;HAVE WE DONE THEM ALL YET?
	JRST	SCAN90		;YES, GO BACK FOR MORE COMMANDS
	MOVE	T2,T1		;NO, PRESET END OF THIS SET
SCAN12:	MOVE	T3,.FXNOD(T2)	;GET LATEST NODE NAME
	CAME	T3,.FXNOD(T1)	;SAME AS FIRST IN SET?
	JRST	SCAN16		;NO, END OF THIS SET THEN
;	LDB	T3,[POINTR .FXMOD(T2),FX.TRM]  ;SPEC TERMINATOR
;	JUMPE	T3,SCAN17	;"," ALSO ENDS THIS SET
	ADDI	T2,.FXLEN	;TRY TO ADD ANOTHER SPEC TO THIS SET
	CAMG	T2,SILAS	;HAVE WE RUN OUT YET?
	JRST	SCAN12		;NO, CHECK THIS SPEC OUT
SCAN16:	SUBI	T2,.FXLEN	;YES, BACK UP TO REAL LAST SPEC
SCAN17:	MOVEM	T1,WIFIR	;SET FIRST (.LKWLD) INPUT SPEC
	MOVEM	T2,WILAS	;SET LAST (.LKWLD) INPUT SPEC
	SETZM	WICUR		;SET CURRENT (.LKWLD) INPUT SPEC
	ADDI	T2,.FXLEN	;ADVANCE TO NEXT FIRST SPEC
	MOVEM	T2,SIFIR	;REMEMBER FOR NEXT TIME AROUND

;PERFORM REQUESTED ACTION ON APPROPRIATE FILES

	PUSHJ	P,MAIN		;GO DO IT
	 JRST	SCAN90		;ABORT ON ERROR
	JRST	SCAN10		;LOOK FOR MORE FILES TO DO
;OUTPUT TOTALS IF APPROPRIATE

SCAN90:	SKIPN	S.TOTA		;/TOTALS GIVEN?
	JRST	SCAN		;/NOTOTALS, SUPPRESS SUMMARY
	SKIPN	FILES		;/TOTALS, ANY FILES
	SKIPE	ERRORS		;OR ANY ERRORS?
	CAIA			;YES, SOMETHING HAPPENED
	JRST	SCAN		;NO, DUD COMMAND LINE
	MOVEI	T1,[ASCIZ\Total of \]  ;START UP THE MESSAGE
	PUSHJ	P,.TSTRG##	;OUTPUT IT
	SKIPN	FILES		;DID ANY FILES GET THROUGH?
	JRST	SCAN94		;NO, CHECK FOR ERRORS
	MOVE	T1,WORDS	;GET COUNT OF WORDS
	PUSHJ	P,.TDECW##	;AND TELL USER
	MOVEI	T1,[ASCIZ\ word\]  ;IDENTIFY COUNT
	PUSHJ	P,.TSTRG##	;AS WORDS
	MOVEI	T1,"s"		;IN CASE PLURAL
	SOSE	WORDS		;EXACTLY ONE WORD?
	PUSHJ	P,.TCHAR##	;NO
	MOVEI	T1,[ASCIZ\ (in \]  ;PREPARE FOR BLOCK COUNT
	PUSHJ	P,.TSTRG##	; . . .
	MOVE	T1,BLOCKS	;GET BLOCK COUNT
	PUSHJ	P,.TDECW##	;PRINT DECIMAL BLOCKS (OF DATA)
	MOVEI	T1,[ASCIZ\ block\]  ;IDENTIFY NUMBER
	PUSHJ	P,.TSTRG##	;AS BLOCK COUNT
	MOVEI	T1,"s"		;IN CASE PLURAL
	SOSE	BLOCKS		;EXACTLY ONE BLOCK?
	PUSHJ	P,.TCHAR##	;NO, APPEND THE "S"
	MOVEI	T1,[ASCIZ\) in \]  ;MORE TEXT
	PUSHJ	P,.TSTRG##	; . . .
	MOVE	T1,FILES	;COUNT OF FILES
	PUSHJ	P,.TDECW##	;TELL USER HOW MANY FILES
	MOVEI	T1,[ASCIZ\ file\]  ;IDENTIFY NUMBER AS FILES
	PUSHJ	P,.TSTRG##	; . . .
	MOVEI	T1,"s"		;IN CASE PLURAL
	SOSE	FILES		;EXACTLY ONE FILE?
	PUSHJ	P,.TCHAR##	;NO, MORE THAN ONE FILE
	SKIPN	WORDS		;ANYTHING TRANSFERRED?
	JRST	SCAN93		;NO, NO BAUD RATE THEN
	MOVEI	T1,[ASCIZ\ at \];TEXT
	PUSHJ	P,.TSTRG##	;TELL USER
	MOVE	T1,WORDS	;GET WORDS TRANSFERRED
	MULI	T1,^D36*^D1000	;READY FOR BAUD RATE
	DIV	T1,MSECS	;T1 := BITS PER SECOND
	PUSHJ	P,.TDECW##	;TYPE OUT BITS PER SECOND
	MOVEI	T1,[ASCIZ\ baud\]  ;AND IDENTIFY AS SUCH
	PUSHJ	P,.TSTRG##	;TO THE USER

;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE

;CHECK FOR ERRORS

SCAN93:	SKIPN	ERRORS		;ANY ERRORS?
	JRST	SCAN95		;NO
	MOVEI	T1,[ASCIZ\ and \]  ;YES
	PUSHJ	P,.TSTRG##	;SO TELL USER THAT TOO
SCAN94:	MOVE	T1,ERRORS	;COUNT OF ERRORS
	PUSHJ	P,.TDECW##	;PRINT THE COUNT
	MOVEI	T1,[ASCIZ\ error\]  ;IDENTIFY ERRORS
	PUSHJ	P,.TSTRG##	;TO USER
	MOVEI	T1,"s"		;IN CASE PLURAL
	SOSE	ERRORS		;EXACTLY ONE ERROR?
	PUSHJ	P,.TCHAR##	;NO
SCAN95:	PUSHJ	P,.TCRLF##	;CAP OFF TOTALS WITH A <CR><LF>
	JRST	SCAN		;GO FOR MORE COMMANDS
	SUBTTL	MAIN FUNCTION SETUP AND DISPATCH

MAIN:	MOVE	T1,.JBFF##	;START ADDRESS FOR BUFFER ALLOCATION
	MOVEM	T1,SAVJBF	;REMEMBER IT
	MOVE	T1,OUSCN+.FXNOD	;DISPATCH WITH OUTPUT NODE NAME
	MOVE	T2,WIFIR	;ADDRESS OF FIRST INPUT SPEC
	MOVE	T2,.FXNOD(T2)	;INPUT NODE NAME
	MOVEM	T1,LNODE	;REMEMBER LEFT NODE NAME AND
	MOVEM	T2,RNODE	;RIGHT NODE NAME FOR TELFIL
	SKIPGE	T4,S.FUNC	;PICK UP FUNCTION CODE
	SETZB	T4,S.FUNC	;NONE GIVEN, USE COPY
	PJRST	@FUNTBL(T4)	;DISPATCH ON FUNCTION

;FUNCTION DISPATCH TABLE, INDEX BY FUNCTION CODE

FUNTBL:	CPY			;/COPY
	DEL			;/DELETE
	LIS			;/DIRECT
	REN			;/RENAME
	SUBTTL	COPY ROUTINE(S)

CPY:	CAME	T2,MYNOD	;COPY FROM LOCAL (US)?
	JRST	CPYR		;NO, FROM REMOTE

;COPY FROM LOCAL (US) TO REMOTE

CPYL:	MOVEI	T1,$DSK		;READ FROM LOCAL INPUT CHANNEL
	PUSHJ	P,NXTFIL	;GET NEXT FILE
	 JRST	.POPJ1		;ALL DONE
	MOVEI	T1,PTHBLK	;OUR DEFAULT PATH
	SKIPN	OUFIL+.RBPPN	;DO WE HAVE EXPLICIT DESTINATION PATH?
	MOVEM	T1,OUFIL+.RBPPN	;NO, USE OUR DEFAULT PATH
	MOVE	T1,SAVJBF	;START ADDRESS FOR BUFFERS ETC.
	MOVEM	T1,.JBFF##	;RESET IN CASE NOT FIRST TIME HERE

	SETZM	TELCNT		;NOTE TELFIL NEVER CALLED YET
	SKIPE	S.FILE		;EXPLICIT /NOFILE?
	PUSHJ	P,TELFIL	;NO, LIST OUT=IN

	MSTIME	T1,		;GET TIME OF DAY
	MOVEM	T1,TIME		;AND REMEMBER IT FOR LATER
	MOVE	T1,OUSCN+.FXNOD	;GET NODE NAME
	PUSHJ	P,TSKXMT##	;SEND THIS FILE ACCROSS
	 JRST	CPYLE		;ERROR SOMEWHERE!
	MSTIME	T1,		;GET NEW TIME OF DAY
	SUB	T1,TIME		;GET INCREMENTAL TIME OF DAY
	CAIGE	T1,0		;WRAP AROUND? (OR REALLY FAST)
	ADDX	T1,^D24*^D60*^D60*^D1000  ;WRAPPED PAST MIDNIGHT
	CAIG	T1,0		;IF CAME BACK THE SAME TICK
	MOVEI	T1,1		;DON'T DIVIDE BY ZERO
	ADDM	T1,MSECS	;COUNT UP TIME
	MOVE	T1,INFIL+.RBSIZ	;WORD COUNT OF INPUT FILE
	ADDM	T1,WORDS	;COUNT UP THE WORDS TRANSFERRED
	ADDI	T1,177		;ROUND UP
	LSH	T1,-7		;AND CHOP DOWN TO BLOCKS
	ADDM	T1,BLOCKS	;COUNT UP BLOCKS
	AOS	FILES		;COUNT UP FILES
	JRST	CPYL		;GO BACK FOR NEXT FILE
;I/O ERROR COPYING FILE

CPYLE:	MOVEI	T1,$TSK		;TASK I/O CHANNEL
	RESDV.	T1,		;JUNK IT
	 JFCL			;SO?
	MOVEI	T1,$DSK		;DISK I/O CHANNEL
	RESDV.	T1,		;JUNK IT ALSO
	 JFCL			;SO ALSO?
	SKIPG	S.OKER		;/OKERROR?
	ERROR	CRE,<Copy to remote failed - aborting>,,,CPYLE2
	WARN	CRW,<Copy to remote failed - continuing>

CPYLE2:	MOVSI	T1,'NIK'	;IN CASE NAME LEFT PERCENTED BY ERROR
	SKIPLE	S.PERC		;ARE WE DOING PERCENT STUFF?
	SETNAM	T1,		;YES, MAKE SURE OUR NAME IS CORRECT
	AOS	ERRORS		;COUNT UP ERRORS TOO
	PUSHJ	P,ONERCK	;ABORT ON ERROR?
	 POPJ	P,		;YES, ABORT ON ERROR
	JRST	CPYL		;NO, KEEP TRYING WITH SUBSEQUENT FILES
;HERE TO COPY FROM REMOTE TO LOCAL (US)

CPYR:	ERROR	CNI,<COPY from remote not yet implemented>
SUBTTL	DELETE ROUTINE

DEL:	ERROR	DNI,<DELETE function not implemented>
	SUBTTL	DIRECT ROUTINE TO RETURN WITH DIRECTORY LISTING

LIS:	ERROR	LNI,<LIST (directory) function not yet implemented>
	SUBTTL	RENAME ROUTINE

REN:	ERROR	RNI,<RENAME function not yet implemented>
	SUBTTL	NXTFIL ADVANCE TO NEXT FILE FROM WILDCARDS

NXTFIL:	HRLZM	T1,INFLP+.FOFNC	;REMEMBER I/O CHANNEL TO USE
NXTFI0:	MOVE	T1,[LKLEN,,LKBLK] ;.LKWLD BLOCK
	PUSHJ	P,.LKWLD##	;CALL WILD SEARCH
	 PJRST	NXTDON		;SEE WHY FAILED
	MOVE	T1,[1B0+.FORED]	;READ A FILE
	IORM	T1,INFLP+.FOFNC	;SET FUNCTION IN FILOP. BLOCK
	SETZM	INFLP+.FOBRH	;NO RING HEADERS YET
	SETZM	INFLP+.FONBF	;NOR ANY BUFFERS YET
	MOVEI	T1,INFIL	;INPUT FILE LOOKUP BLOCK
	MOVEM	T1,INFLP+.FOLEB	;SET IN FILOP. BLOCK
	MOVE	T1,[PTHLEN,,INPTH]  ;WHERE TO RETURN INPUT PATH
	MOVEM	T1,INFLP+.FOPAT	;AFTER DOING "LOOKUP"
	SETZM	INFLP+.FOPPN	;LOOKUP IS FOR US
	MOVE	T1,[FLPLEN,,INFLP]  ;FILOP. POINTER TO
	FILOP.	T1,		;READ THE FILE
	CAIA			;ERROR
	JRST	NXTFI4		;GOT IT,CHECK TIME ETC.
	PUSHJ	P,E.DFL##	;TYPE LOOKUP ERROR
	AOJE	T1,NXTFI0	;IF -1 THEN CONTINUE (E.G., /OKPROT)
	PUSHJ	P,ONERCK	;SEE IF SHOULD ABORT
	 POPJ	P,		;YES, ABORT ON ERROR
	JRST	NXTFI0		;NO, TRY FOR ANOTHER FILE

NXTFI4:	PUSHJ	P,.CHKTM##	;CHECK TIME CONSTRAINTS
	 JRST	NXTFI0		;NO GO FOR THIS FILE
	MOVE	T1,INFIL+.RBDEV	;FILE LOGICAL UNIT NAME
	MOVEM	T1,DSKBLK	;SET IN DSKCHR BLOCK
	MOVE	T1,[DSKLEN,,DSKBLK]  ;ARG BLOCK FOR DSKCHR. TO
	DSKCHR	T1,		;FIND TRUE STRUCTURE NAME
	 ERROR	DUF,<DSKCHR UUO failed for input file>
	MOVE	T1,DSKBLK+.DCSNM;INPUT DISK FILE STRUCTURE
	MOVEM	T1,INOPN+.OPDEV	;SET TRUE DEVICE NAME
	MOVEI	T1,INPTH	;ADDRESS OF ALLEGED TRUE PATH
	MOVEM	T1,INFIL+.RBPPN	;SET IN LOOKUP BLOCK

;WE FOUND A GOOD INPUT FILE, NOW GENERATE OUTPUT FILE FROM IT

	MOVE	T1,[SCLEN,,SCBLK] ;.SCWLD BLOCK
	PUSHJ	P,.SCWLD##	;GENERATE OUTPUT FILE STUFF
	  ERROR	OGE,<Output file specification generation error in .SCWLD>
	PJRST	.POPJ1##	;RETURN WITH INPUT AND OUTPUT FILES
NXTDON:	AOSN	T1		;IF -1 NO MORE FILES
	POPJ	P,		;NO MORE FROM NXTFIL
	MOVE	T1,WICUR	;POINTER TO CURRENT SCAN BLOCK
	MOVE	T1,.FXDEV(T1)	;DEVICE THAT FAILED US
	MOVEM	T1,INOPN+.OPDEV	;SAVE IT FOR ERROR PROCESSOR
	ERROR	IND,<Input device not a disk>,.TSIXN,<INOPN+.OPDEV>

ONERCK:	SKIPLE	S.OKER		;/OKERROR?
	 AOS	(P)		;YES, TRY TO DO MORE
	POPJ	P,		;NO,ABORT
	SUBTTL	TELFIL LIST OUTPUT AND INPUT FILES

TELERR::SKIPE	TELCNT		;THIS FILE ALREADY BEEN LISTED?
	POPJ	P,		;YES, WE NEED DO NOTHING THEN

TELFIL:	PUSHJ	P,.TSPAC##	;PRESERVE COLUMN ONE (BATCH ETC.)
	MOVE	T1,LNODE	;LEFT (DESTINATION) NODE NAME
	PUSHJ	P,.TSIXN##	;IT COMES FIRST
	MOVEI	T1,"_"		;END OF NODE NAME
	PUSHJ	P,.TCHAR##	;AND TYPE IT TOO
	MOVEI	T1,OUOPN	;OUTPUT DEVICE OPEN BLOCK
	MOVEI	T2,OUFIL	;OUTPUT FILE ENTER BLOCK
	PUSH	P,OUFIL+.RBVER	;SAVE VERSION WORD
	SETZM	OUFIL+.RBVER	;SO ACCSCN'S .TOLEB DOESN'T TYPE ";VER"
;[6]	PUSH	P,OUFIL+.RBNCA	;SAVE NON-PRIVILEGED CUSTOMER WORD
	SETZM	OUFIL+.RBNCA	;SO ACCSCN'S .TOLEB DOESN'T TYPE 12-CHAR NAME
	PUSHJ	P,.TOLEB##	;TYPE 'EM OUT
;[6]	POP	P,OUFIL+.RBNCA	;RESTORE TRUE .RBNCA
	POP	P,OUFIL+.RBVER	;RESTORE TRUE .RBVER
	MOVEI	T1,[ASCIZ/ <=/]	;SEPARATE OUTPUT FROM INPUT
				; (NOTE THAT ANGLE BRACKETS MATCHED
				;  AT PRMPT)
	PUSHJ	P,.TSTRG##	;LIST THE SEPARATOR

;TELL INPUT SPEC

TELIIL:	PUSHJ	P,.TSPAC##	;SEPARATE WITH A SPACE
	MOVE	T1,RNODE	;RIGHT (SOURCE) NODE NAME
	PUSHJ	P,.TSIXN##	;TYPE IT OUT
	MOVEI	T1,"_"		;END OF NODE NAME
	PUSHJ	P,.TCHAR##	;TYPE IT OUT TOO
	MOVEI	T1,INOPN	;INPUT DEVICE OPEN BLOCK
	MOVEI	T2,INFIL	;INPUT FILE LOOKUP BLOCK
	PUSH	P,INFIL+.RBVER	;SAVE VERSION WORD HERE TOO
	SETZM	INFIL+.RBVER	;AGAIN . . .
;[6]	PUSH	P,INFIL+.RBNCA	;SAVE CUSTOMER WORD HERE TOO
	SETZM	INFIL+.RBNCA	;AGAIN . . .
	PUSHJ	P,.TOLEB##	;TYPE 'EM OUT AS WELL
;[6]	POP	P,INFIL+.RBNCA	;TRUTH IN ADVERTISING
	POP	P,INFIL+.RBVER	;TRUTH IN ADVERTISING
	AOS	TELCNT		;NOTE WE TYPED OUT A FILE SPEC
	PJRST	.TCRLF##	;CAP OFF THIS LINE
	SUBTTL	NDNAM TURN A NODE SPEC INTO A NODE NAME

;NDNAM  --  TRY TO MAKE A NAME OUT OF A NODE SPECIFIER
;CALL IS:
;
;	MOVX	T3,<NODE>
;	PUSHJ	P,NDNAM
;	RETURN
;
;WHERE <NODE> IS SIXBIT NODE NAME, SIXBIT NODE NUMBER, OR OCTAL NODE NUMBER.
;
;ON RETURN T1 WILL HAVE THE NODE NAME IF <NODE> IS MEANINGFUL, OTHERWISE
;T1 WILL HAVE <NODE>, ASSUMING WHOEVER WANTS TO USE IT WILL BE BETTER
;SITUATED TO COMPLAIN ABOUT NO SUCH NODE.

NDNAM:	PUSH	P,T3		;SAVE INPUT
	TLNN	T3,770000	;SIXBIT OF SOME SORT?
	JRST	NDNAM3		;NO, MUST BE OCTAL NODE NUMBER
	MOVE	T1,[.NDRNN,,T2]	;YES, MAY BE SIXBIT NODE NUMBER
	MOVEI	T2,2		;SO ASK MONITOR FOR OCTAL NODE NUMBER
	NODE.	T1,		;SINCE WE CAN'T TELL THE DIFFERENCE
	 JRST	NDNAM8		;JUNK, PRESERVE INPUT
	MOVE	T3,T1		;SET UP NODE NUMBER
NDNAM3:	MOVE	T1,[.NDRNN,,T2]	;ARG POINTER
	MOVEI	T2,2		;AND ARG BLOCK LENGTH
	NODE.	T1,		;TO READ NODE NAME GIVEN NODE NUMBER
NDNAM8:	 MOVE	T1,0(P)		;NO SUCH NODE, RETURN INPUT SPECIFIER
	POP	P,(P)		;ADJUST STACK
	POPJ	P,		;AND RETURN
	SUBTTL	ERROR PROCESSOR

;ALL ERROR/WARN/INFORM CALLS COME HERE TO BE HANDLED

ERRMSG:	PUSHJ	P,.PSH4T##	;SAVE T1-T4 FOR MOMENT
	MOVE	T4,-4(P)	;CALLER PC
	MOVE	T1,0(T4)	;PREFIX
	MOVE	T2,1(T4)	;CHAR AND TEXT
	MOVE	T3,-5(P)	;AND THE ERROR PC
	PUSHJ	P,.ERMSA##	;TYPE ERROR STUFF
	MOVE	T4,-4(P)	;ARG BLOCK PC AGAIN
	SKIPE	T2,2(T4)	;DID USER REQUEST A ROUTINE?
	TXNN	T1,JWW.FL	;AND IS FIRST SET?
	JRST	ERRMS4		;NO, DON'T EVEN BOTHER
	SKIPE	T1,3(T4)	;DID USER GIVE AN ADDRESS?
	MOVE	T1,@T1		;YES, LOAD UP T1
	PUSHJ	P,@T2		;CALL USER SPECIAL ROUTINE
ERRMS4:	MOVE	T4,-4(P)	;GET ARG BLOCK PC YET AGAIN
	HLRZ	T1,1(T4)	;GET ERROR CHARACTER
	CAIN	T1,"["		;INFORMATIONAL?
	PUSHJ	P,.TRBRK##	;YES, CAP IT OFF
	PUSHJ	P,.TCRLF##	;END THE LINE OF TEXT
	MOVEI	T1,@4(T4)	;GET RESUME ADDRESS
	MOVEM	T1,-5(P)	;FAKE OUT THE POPJ P,
	PUSHJ	P,.POP4T##	;RESTORE THE T REGS
	POP	P,(P)		;DISCARD JUNK PC
	POPJ	P,		;AND "RESUME" PROCESSING


ERRDIE:	EXIT			;AND THAT IS THAT!
	SUBTTL	VARIOUS SUBROUTINES

CLRALL:	SETOM	BZSWIT		;START OF SWITCHES
	MOVE	T1,[BZSWIT,,BZSWIT+1]  ;POINTER TO SWITCH TABLE
	BLT	T1,EZSWIT	;"CLEAR" ALL SWITCHES
	POPJ	P,		;THAT'S THAT

PRMPT:	JUMPL	T1,PRMPT4	;SKIP IF CONTINUATION
	OUTSTR	[ASCIZ/NIK>/]	;ELSE NORMAL PROMPT
				; (NOTE THAT THIS MATCHES THE OPEN
				;  ANGLE BRACKET AT TELFIL)
	POPJ	P,		;AND CONTINUE IN SCAN

PRMPT4:	OUTCHR	["#"]		;OUTPUT THE "#" PROMPT
	POPJ	P,		;AND CONTINUE IN SCAN

;ALLOCATE FILE-SPEC AREAS (SCAN BLOCKS)

OUX:	MOVEI	T1,OUSCN	;OUTPUT SCAN BLOCK
	MOVEI	T2,.FXLEN	;AND LENGTH
	POPJ	P,

INX:	MOVEI	T1,.FXLEN	;LENGTH OF A SCAN BLOCK
	ADDB	T1,.JBFF	;ALLOCATE US SOME CORE FOR IT
	SOJ	T1,		;DEC BY ONE FOR NEATNESS
	CAMLE	T1,.JBREL	;DO WE HAVE THE PHYSICAL CORE?
	 PUSHJ	P,GTCOR		;NO - ASK MONITOR FOR IT
	SUBI	T1,.FXLEN-1	;SCAN WANTS START ADDRESS IN T1
	MOVEI	T2,.FXLEN	;AND LENGTH IN T2
	SKIPN	SIFIR		;IS THIS THE VERY FIRST SCAN BLOCK?
	MOVEM	T1,SIFIR	;YES - REMEMBER IT
	MOVEM	T1,SILAS	;ALSO REMEMBER LAST SCAN BLOCK
	POPJ	P,		;GIVE STUFF TO SCAN


;GTCOR  --  GET CORE FROM MONITOR

GTCOR:	PUSH	P,T1		;PRESERVE T1
	CORE	T1,		;ASK MONITOR FOR SOME CORE
	 JRST	GTCOR9		;NO CORE - DIE BIG
	POP	P,T1		;RESTORE T1
	POPJ	P,		;GOT IT.

GTCOR9:	OUTSTR	[ASCIZ/? Not enough free core available/]
	EXIT			;AND THAT'S THAT!
;TNEWL  --  MAKE SURE TTY AT BEGINING OF LINE
;CALL IS:
;
;	PUSHJ	P,TNEWL
;	RETURN
;
;ON RETURN TTY IS AT LEFT MARGIN (POSITION 0)

.TNEWL::PUSHJ	P,.SAVE4##	;SAVE THE T ACS
TNEWL0:	MOVE	P1,[2,,P2]	;TRMOP. ARG POINTER
	MOVEI	P2,.TOSOP	;SKIP IF STILL HAVE OUTPUT
	SETO	P3,		;-1 = US
	TRMOP.	P1,		;ASK MONITOR ABOUT TTY OUTPUT
	 JRST	TNEWL5		;NO OUTPUT PENDING
	MOVEI	P1,0		;OUTPUT PENDING
	SLEEP	P1,		;SLEEP A BIT
	JRST	TNEWL0		;AND CHECK AGAIN

TNEWL5:	MOVE	P1,[2,,P2]	;TRMOP. ARG POINTER
	MOVEI	P2,.TOHPS	;FOR READING HORIZONTAL POSITION
	SETO	P3,-1		;-1 = US
	TRMOP.	P1,		;ASK MONITOR ABOUT "CURSOR" POSITION
	 CAIA			;ASSUME NEED <CR><LF>
	JUMPE	P1,.POPJ##	;IF 0 THEN AT LEFT MARGIN, NO <CR><LF> NEEDED
	PJRST	.TCRLF##	;NOT AT LEFT MARGIN, GET A <CR><LF> OUT
	SUBTTL	SWITCH DEFINITIONS

DEFINE	SWTCHS,<
SN	ALLOCA,S.ALLO,FS.NFS
SN	ANYPPN,S.ANYP,FS.NFS
SN	BITCH,S.BITC,FS.NFS
SN	DETACH,S.DETA,FS.NFS
SN	FILES,S.FILE,FS.NFS
SN	NBIO,S.NBIO,FS.NFS
SN	OKERROR,S.OKER,FS.NFS
SN	PERCENT,S.PERC,FS.NFS
SS	RECEIV,S.RECV,1,FS.NFS
SN	TOTALS,S.TOTA,FS.NFS
SN	WAIT,S.WAIT,FS.NFS
>

DOSCAN(NIKSW)
	SUBTTL	DATA BLOCKS

;FOR SCAN

;MONITOR COMMAND TABLE

CCMDT:	'NIK   '		;USEFUL MONITOR COMMAND
	'COPY  '		;SOMEDAY, OVER THE RAINBOW

	CCMDL==.-CCMDT

;ISCAN PARAMETER BLOCK

ISBLK:	IOWD	CCMDL,CCMDT	;IOWD OF LEGAL MONITOR COMMANDS
	CCLFLG,,'NIK'		;ADR OF STARTING OFFSET,,CCL NAME
	Z			;CHAR INPUT RTN,,CHAR OUTPUT RTN
	Z			;INDIRECT FILE BLOCK POINTER (XWD)
	XWD	PRMPT,0		;PROMPT RTN,,MONRET RTN
	Z			;FLAGS,,<FUTURE>

	ISLEN==.-ISBLK

;TSCAN PARAMETER BLOCK

TSBLK:	IOWD	NIKSWL,NIKSWN	;IOWD POINTER FOR SWITCH NAMES
	XWD	NIKSWD,NIKSWM	;DEFAULT TABLE,,PROCESSOR TABLE
	XWD	0,NIKSWP	;<FUTURE>,,STORAGE POINTERS
	SIXBIT	/NIK/		;HELP
	XWD	CLRALL,0	;CLEAR ALL,,CLEAR FILE
	XWD	INX,OUX		;ALLOC INPUT AREA,,ALLOC OUTPUT AREA
	Z			;MEMORIZE STICKY,,APPLY STICKY
	Z			;CLEAR STICKY,,FLAGS
	Z			;<FUTURE>,,SWITCH VALUE STORAGE RTN

	TSLEN==.-TSBLK

;OSCAN BLOCK

OSBLK:	IOWD	NIKSWL,NIKSWN	;IOWD POINTER FOR SWITCH NAMES
	XWD	NIKSWD,NIKSWM	;DEFAULT TABLE,,PROCESSOR TABLE
	XWD	0,NIKSWP	;<FUTURE>,,STORAGE POINTERS
	SIXBIT	/NIK/		;HELP
	SIXBIT	/NIK/		;OPTIONS NAME

	OSLEN==.-OSBLK
;FOR WILD

LKBLK:	WIFIR,,WILAS		;<FIRST,,LAST> SCAN BLOCK POINTER ADR
	INOPN,,INFIL		;<OPEN,,LOOKUP> BLOCK ADDRESS
	.FXLEN,,FILLEN		;SCAN BLOCK LENGTH,,LOOKUP LENGTH
	0,,WICUR		;FLAGS!CHANNEL,,CUR SCNBLK PTR ADR
	Z			;END OF DIRECTORY RTN

	LKLEN==.-LKBLK


SCBLK:	WICUR,,[OUSCN]		;<CUR INPUT,,OUTPUT> SCNBLK PTR ADR
	INOPN,,OUOPN		;<INPUT,,OUTPUT> OPEN BLK ADR
	INFIL,,OUFIL		;<INPUT,,OUTPUT> FILE BLK ADR
	[0,,-1],,FILLEN		;DEFAULT EXT ADR,,FILE BLK LEN
	0,,SCFLG		;<FUTURE>,,SCWILD PROCESSING FLAGS

	SCLEN==.-SCBLK
	XLIST			;THE LITERALS GO IN THE HIGH SEG
	LIT
	LIST

	RELOC	0

PDLST:	BLOCK	PDLEN		;THE STACK

;OTHER (FOR WILD) BLOCKS

WIFIR:	BLOCK	1		;POINTER TO FIRST SCAN BLOCK
WILAS:	BLOCK	1		;POINTER TO LAST SCAN BLOCK
WICUR:	BLOCK	1		;POINTER TO CURRENT SCAN BLOCK
				;(INITIALLY 0, UPDATED BY WILD)
SCFLG:	BLOCK	1		;SCWILD MODE,,MASK CONSTRAINTS

;OTHER (FOR SCAN) BLOCKS

SIFIR:	BLOCK	1		;FIRST INPUT SCAN BLOCK ADDRESS
SILAS:	BLOCK	1		;LAST INPUT SCAN BLOCK ADDRESS

;SCAN SWITCHES

BZSWIT:				;START OF SWITCHES
S.ALLO::BLOCK	1		;.GT. 0 THEN BELIEVE .RBALC
S.ANYP::BLOCK	1		;.GT. 0 THEN RECEIVE FROM ANYBODY
S.BITC::BLOCK	1		;.GT. 0 THEN BITCH ABOUT TSKSER
S.DETA::BLOCK	1		;.GT. 0 THEN DETACH (RECV ONLY)
S.FILE::BLOCK	1		;.GT. 0 THEN LIST FILES (XMIT ONLY)
S.FUNC:	BLOCK	1		;FUNCTION TO BE PERFORMED
S.NBIO::BLOCK	1		;.NE. 0 THEN USE TSK: NON-BLOCKING I/O
S.OKER::BLOCK	1		;.EQ. 0 THEN ABORT ON TRANSFER FAILURE
S.PERC::BLOCK	1		;.GT. 0 THEN SETNAM TO PERCENTAGES
S.RECV::BLOCK	1		;.GT. 0 IF /RECEIVE
S.TOTA:	BLOCK	1		;.NE. 0 THEN SUMMARY AT END
S.WAIT::BLOCK	1		;.GT. 0 THEN WAIT FOR RECEIVER FOREVER
EZSWIT==.-1
CCLFLG:	BLOCK	1		;STARTING OFFSET
				;   0 = NORMAL (".RUN PROG")
				;   1 = CCL (LOOK IN TMPCOR)
PTHBLK:	BLOCK	PTHLEN+1	;TO HOLD OUR DEFAULT PATH
DSKBLK:	BLOCK	DSKLEN		;FOR DSKCHR UUO

MYNNM:	BLOCK	1		;HOST NODE NUMBER
MYNOD:	BLOCK	1		;HOST NODE NAME
SAVJBF:	BLOCK	1		;TO HOLD .JBFF
LNODE:	BLOCK	1		;HOLD LEFT (DESTINATION) NODE FOR TELFIL
RNODE:	BLOCK	1		;HOLD RIGHT (SOURCE) NODE FOR TELFIL

WORDS:	BLOCK	1		;COUNT OF WORDS TRANSFERRED
BLOCKS:	BLOCK	1		;COUNT OF BLOCKS TRANSFERRED
FILES:	BLOCK	1		;COUNT OF FILES TRANSFERRED
MSECS:	BLOCK	1		;COUNT OF MILLISECONDS FOR TRANSFERS
ERRORS:	BLOCK	1		;COUNT OF FILES ABORTED
TIME:	BLOCK	1		;SCRATCH TIMER FOR CURRENT FILE
TELCNT:	BLOCK	1		;COUNT OF TELFIL'S FOR CURRENT FILE


;FILE BLOCKS

;INSCN:	BLOCK	.FXLEN		;INPUT SCAN BLOCK
OUSCN:	BLOCK	.FXLEN		;OUTPUT SCAN BLOCK

INFLP::	BLOCK	1		;INPUT FILOP. BLOCK
INOPN::	BLOCK	3		;INPUT OPEN BLOCK
	BLOCK	FLPLEN-.FONBF	;REST OF INPUT FILOP. BLOCK

OUFLP::	BLOCK	1		;OUTPUT FILOP. BLOCK
OUOPN::	BLOCK	3		;OUTPUT OPEN BLOCK
	BLOCK	FLPLEN-.FONBF	;REST OF OUTPUT FILOP. BLOCK

INFIL::	BLOCK	FILLEN+1	;INPUT FILE LOOKUP BLOCK
OUFIL::	BLOCK	FILLEN+1	;OUTPUT FILE ENTER BLOCK

INPTH:	BLOCK	PTHLEN		;INPUT FILE PATH BLOCK
OUPTH:	BLOCK	PTHLEN		;OUTPUT FILE PATH BLOCK
	END	NIK