Google
 

Trailing-Edge - PDP-10 Archives - k20v7b - decnet-sources/nft.mac
There are 24 other files named nft.mac in the archive. Click here to see a list.
TITLE	NFT	Network file transfer utility for TOPS20 DECNET
SUBTTL	D. Oran	- P.J. Taylor	16-May-80

;
;
;
;	    COPYRIGHT (c) 1978,1979,1980,1985 BY
;           DIGITAL EQUIPMENT CORPORATION, MAYNARD, MA.
;
;     THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY  BE  USED
;     AND COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE
;     AND WITH THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE.   THIS
;     SOFTWARE  OR ANY OTHER COPIES THEREOF MAY NOT BE PROVIDED OR
;     OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON.  NO  TITLE  TO
;     AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED.
;
;     THE INFORMATION  IN  THIS  SOFTWARE  IS  SUBJECT  TO  CHANGE
;     WITHOUT  NOTICE  AND SHOULD NOT BE CONSTRUED AS A COMMITMENT
;     BY DIGITAL EQUIPMENT CORPORATION.
;
;     DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY
;     OF  ITS  SOFTWARE  ON  EQUIPMENT  WHICH  IS  NOT SUPPLIED BY
;     DIGITAL.




	SEARCH	GLXMAC			;Get Galaxy symbols
	PROLOG	(NFT)

	SEARCH	DAPSYM			;Get DAPLIB symbols

;Version Information

	NFTVER==2			;MAJOR VERSION OF NFT
	NFTMIN==0			;MINOR VERSION OF NFT
	NFTEDT==105			;EDIT LEVEL
	NFTWHO==0			;WHO LAST EDITED (0=DEC DEVELOPMENT)

	GLOB	DAPEDT

	VNFT==<VRSN.(NFT)>+DAPEDT	;Get the version level
SUBTTL	Table of contents

;               TABLE OF CONTENTS FOR NFT
;
;
;                        SECTION                                   PAGE
;    1. D. Oran - P.J. Taylor   9-May-79..........................   1
;    2. Table of contents.........................................   2
;    3. Revision History..........................................   3
;    4. Constants and assembly parameters.........................   4
;    5. LOCAL MACROS..............................................   5
;    6. Job version and entry vector..............................   6
;    7. Initialization blocks.....................................   6
;    8. MAIN ENTRY POINT AND INITIALIZATION.......................   7
;    9. Parser and Command dispatch...............................   8
;   10. DELETE DIRECTORY SUBMIT and TYPE commands.................  13
;   11. REMFIL  Common parsing routine for remote filespec........  14
;   12. REMRTN  Common Co-routine for DELETE SUBMIT and TYPE commands  15
;   13. DIRRTN  Co-routine for Directory command..................  16
;   14. OUTDEF Routine to default output file name................  17
;   15. HELP and EXIT commands....................................  18
;   16. INFORMATION command dispatch..............................  19
;   17. Information about DECNET..................................  20
;   18. Information about DEFAULTS................................  21
;   19. SET defaults command......................................  22
;   20. PARFIL  Routine to parse a network file specification.....  24
;   21. PARNOD  Routine to parse NODE::...........................  25
;   22. PARSWS  Routine to parse switches.........................  26
;   23. Switch processors.........................................  27
;   24. OSTYPE Switch processor...................................  28
;   25. GETUSR routine to ensure we have a user,account and password  29
;   26. HLPUSR  Routine to display access information for a node..  30
;   28. TAKE command..............................................  31
;   29. OUTNAM  Routine to generate output file spec..............  32
;   30. OUTFLG  Routine to set flags per what user typed..........  33
;   31. Routine to build destination string from wild information.  34
;   32. CHKWLD  Routine to validate wild construction.............  35
;   33. FILDEF  Routine to setup GTJFN file defaults..............  36
;   34. CPYFLD  ROUTINE TO COPY A STRING UNTIL BREAK CHARACTER....  37
;   35. CHKPTR  Routine to fix -1 type pointers...................  39
;   36. DAPOPN  Routine to Open logical link......................  40
;   37. DAPFNC  Routine to perform one DAP function...............  41
;   38. COMMAND ERROR SUBROUTINES.................................  42
;   39. CMDINI  Command parsing initialization routine............  44
;   40. Command field parsing routines............................  4
;   41. Command parsing error and reparse routines................  46
;   42. GENERAL SUBROUTINES.......................................  47
;   43. NODGET  Routine to build node recognition table...........  48
;   44. NODADD  Routine to add an entry to node table.............  49
;   45. PSIINI  Software interrupt system initialization..........  50
;   46. Interrupt service routines................................  50
;   47. Interrupt tables..........................................  51
;   48. Pure Data storage.........................................  52
;   49. Impure storage............................................  53
SUBTTL	Revision History

COMMENT \

Edit	Comment

0020	First field test of NFT version 2(20)
0021	Don't allow wild cards in remote retrieval
0022	MOVE QUOTED STRING TO FIRST CHOICE FOR REMOTE FILE SPEC.
	THIS DISABLES RECOGNITION FOR ONE CHARCTER AFTER THE NODE.
	Include DAPLIB version with NFT's version.
0023	FIX FILE BREAK TO ACCEPT <>; IN CASE GTJFN FAILS FOR BUMB
	DEVICE NOT KNOWN TO THIS NODE DURING REMOTE FILE PARSING.
0024	ADD FILDEF ROUTINE TO SETUP GTJFN BLOCK DEFAULTS FROM
	AN ASCIZ STRING.
0025	Fix a bug in OUTFLG that caused copy to fail when only
	output device was specified.
0026	Fix a bug in switch parsing on copy to proceed to output
	filespec if a space is typed after input filespec.
0027	Add directory code to display protection, filesize and
	last update time
0030	Add interrupt cause to calls to D$INTR so it doesn't have
	to interrogate link status for each interrupt
0031	Don't set GJ%OLD for file parsing in COPY (FROM)
0032	Add TYPE command.
0033	Remove GETUSR call from SET DEFAULT command
0034	Copy name on co-routine call from DAPLIB
0035	Impliment wild card remote file access and fix various bugs
0036	Fix connected directory structure bug so typing the local
	node is transparent
0037	Change record format calling arguments to allow all DAP
	record and file attributes to be passed.
0040	Remove reference to D$ERRS and use G1%SLN to suppress logical
	name expansion for parsing remote filespeces
0041	Make Account, User and Password valid switches for all commands
	which access remote files.
0042	Fix bug to allow actual remote filespec to be displayed for directory
	and copy commands if it is known
0043	Fix bug to allow directory file names greater than 39 characters.
0044	Clear valid bits on password, user-id and account if connect to remote
	node fails because of invalid password or invalid user-id.
0045	Fix bug in wild logic which cause *.%36 (TO) *.%36.-1 to fail.

*** Changes for DECnet-20 V3.0 begin here ***

0046	Add code to support PRINT command.

0047	Fix a bug in calls to D$CLOS which produced an invalid disconnect
	reason code to be sent.

0050	Change all interrupt processing to use level 1 and make LEV1PC
	global so it may be accessed in D$INTR.

0051	Add ^O trapping to type command to abort current file
	being typed.

0052	Make node table dynamic to prevent illegal instruction traps.

0053	Save DSTFIL across call to DAPOPN so we don't loose track
	of device and directory on wild card storage.

0054	Don't loose track of destination directory and device when
	doing wild retrieves.

*** Engineering responsibility changes hands here ***

0055	Don't loose the destination file spec when calling CHKPTR.
	This solves a class of problems in which the file is copied
	to the wrong structure or directory.

0056	Don't leave out fields in the destination file spec.
	Also, always generate file name and file type for
	destination file. Again this solves problems concerning
	files being copied to the wrong structure, directory, or
	with a bad file name.

0057	Print error message when a bad switch is typed.

0060	Allow underscore, and dollar sign in user identification,
	account field, and password. Some remotes allow such characters.

0061	Implement wildcards for tops-10, rsts, ias, amd 11m when
	ppn or ; before generation is specified.

0062	Treat a file spec with the local node name as remote if both
	files are local.
	This resolves the problem of local node file access using NFT.
	Without this change a user who had valid accounting info
	to access a local directory was refused access because his
	job didn't have local access privleges.

0063	Error messages for many things are very unclear.
	Error messages for bad node name, file name or accounting
	switches improved.

0064	The default for account and userid should be null. A null
	password should be allowed. The help text should
	be available for account userid and password.

0065	Allow all file names to be greater than 6 characters in length.

0066	When doing a DIR command, give a new node, volume, and
	directory heading whenever either volume or directory
	change.

0067	If the last written date is not provided print the
	creation date.

0070	Add support for poor man's routing.

0071	The code which reads NFT.INIT uses code from the TAKE
	command. Any error within this code can produce bad
	error messages or a fatal NFT error.

0072	The code which displays INFO DECNET never marks nodes
	offline if their status changes.

0073	The INFO DECNET code used the stack for the NODE temp
	storage. If the number of available nodes is high, this
	is too small. Listing should be alphabetical and neat.

0074	The Default file name routine FILGET parsed a device field
	and stopped on $-_. These characters are valid logical name
	characters on TOPS-20 and on remote systems. Allow them.

0075	Add status message when ^A is typed.

0076	In an effort to make security better, print a warning message
	whenever a password is found in a command file which allows
	read access to the world.

0077	Warn the user if NFT makes assumptions about the nodes
	in file specifications.

0100	If the comnd JSYS gets a very unexpected error, NFT can
	loop forever repeating the JSYS.

0101	Add DI%PGM field to DAPLIB initialization block

*** Changes for TOPS-20 V. 6.1 start here ***

0102	Release 6 GTJFN will parse file specs with node names in them.
	So, change PARFIL to set up GTJFN block for local file specs only.
	Also, alter a GTJFN in CPYRCV that assumes that GTJFN will
	fail on filename with node name in it.

0103	Change debugging object type to conform with updated standard

0104	In routine WILD change branch at WILD6 to skip over the
	decrementing of the source string pointer at WILD7.  This
	unnecessary operation was causing the stuttering wildcard
	problem, where copying files in the form of *<stuff>*
	resulted in the repetition of the last character of <stuff>.
	For example, *ABC* would become *ABCC*.

0105	Make the number of pages in the node table for the INFORMATION
	DECNET command a symbolic parameter.  Increase it to accomodate
	the number of in-house nodes.

\ ;end revision history
SUBTTL	Constants and assembly parameters


;[0075] Externals

	EXTERNAL PMRFLG,.DNINI,MESIN,MESOUT,LOCJFN,PAGFLG,PAGNUM
	EXTERNAL LLSTAT

	GLOB	DATEND			;End of impure data

;Constants

	XP	DAPLNK,1		;Request 1 logical link
	XP	DEBUGW,135		;DEBUGW
	XP	MAXNOD,^D128		;Starting size of node table
	XP	NODPGS,4		;[0105]Pages for node table
	ND	PDLEN,400		;Size of our stack
	XP	GJFSIZ,20		;Size of the GTJFN block
	XP	FILSIZ,40		;Maximum size of a file name
	XP	NAMSIZ,20		;Size of name string storage
	XP	FFSPEC,111110B17+JS%PAF	;Full file spec expansion

;Interrupt channel assignments

	XP	.ICCNO,0		;Control-O channel
	XP	.ICCDN,1		;Connect/Disconnect
	XP	.ICDAV,2		;Data available
	XP	.ICIMA,3		;Interrupt message

;Node data offsets

	PHASE 0
ND$NAM:	BLOCK 2				;NODE NAME STRING
ND$STA:	BLOCK 1				;NODE STATUS
ND$OST:	BLOCK 1				;NODE OPERATING SYSTEM TYPE
ND$DEV:	BLOCK	NAMSIZ			;DEFAULT DEVICE FOR NODE
ND$USR:	BLOCK	NAMSIZ			;NODE USER STRING
ND$ACT:	BLOCK	NAMSIZ			;NODE ACCOUNT STRING
ND$PSW:	BLOCK	NAMSIZ			;NODE PASSWORD STRING
	ND$LEN==.			;ALLOCATION PER NODE
	DEPHASE
;Daplib function block definitions

	MSKSTR	DPFNC,FNCBLK+.DFFLG,DF%ACC	;Dap function
	MSKSTR	DPLNK,FNCBLK+.DFFLG,DF%LNK	;Dap link
	MSKSTR	DPLFA,FNCBLK+.DFLFA,-1		;Dap local file attribs
	MSKSTR	DPLFS,FNCBLK+.DFLFS,-1		;Dap local filespec
	MSKSTR	DPRTN,FNCBLK+.DFRTN,-1		;Dap called co-routine
	MSKSTR	DPRFA,FNCBLK+.DFRFA,-1		;Dap remote file attribs
	MSKSTR	DPRFS,FNCBLK+.DFRFS,-1		;Pointer to remote file
SUBTTL LOCAL MACROS


DEFINE TXT(TEXT) <POINT 7,[ASCIZ\TEXT\]>

DEFINE	$FD(NAME) <
	XWD 10,0
	ASCIZ\NAME\>

;REPARS PARSE ERROR MACRO

DEFINE	REPARS	(MESSAGE) <
	 JRST	[MOVX	S1,TXT(MESSAGE)
		 JRST	.REPAR]>

;MACRO TO PROMPT FOR COMMAND

DEFINE PROMPT (MESSAGE) <
	$CALL	[MOVX S1,TXT(MESSAGE)
		 PJRST DPROMPT]
> ;END OF PROMPT DEFINITION


;MACRO TO PRINT GUIDEWORDS

DEFINE NOISE (SHT) <
	$CALL	[MOVEI S1,[EXP FLD(.CMNOI,CM%FNC),TXT(SHT)]
		 PJRST RFIELD]
> ;END OF NOISE DEFINITION

;MACRO TO REQUIRE CONFIRMATION

DEFINE CONFRM <
	$CALL	[MOVEI	S1,[FLD(.CMCFM,CM%FNC)]
		 PJRST RFIELD]
> ;END OF CONFRM DEFINITION

;MACRO TO MAKE TABLE ENTRY

DEFINE T (WORD,ADDRES) <

IFB <ADDRES>,<[ASCIZ /WORD/],,.'WORD>
IFNB <ADDRES>,<[ASCIZ /WORD/],,ADDRES>>

;MACRO TO MAKE SWITCH TABLE ENTRY

DEFINE SW (TXT) <[ASCIZ/TXT/],,.SW'TXT>
DEFINE SV (TXT) <[ASCIZ/TXT:/],,.SW'TXT>
SUBTTL	Job version and entry vector

	LOC	137			;SET THE VERSION
.JBVER:	EXP	VNFT
	RELOC	0

; ENTRY VECTOR DEFINITION

ENTVEC:	JRST NFT			;MAIN ENTRY POINT
	JRST REE			;REENTER ENTRY POINT
	EXP VNFT			;VERSION OF NFT PROGRAM

SUBTTL	Initialization blocks

IB:	$BUILD	(IB.SZ)
	  $SET	(IB.PRG,,'NFT   ')	;Set program name
	  $SET	(IB.OUT,,LOGCHR)	;DEFAULT TEXT OUTPUT ROUTINE
	  $SET	(IB.INT,,<LEVTAB,,CHNTAB>)
	$EOB

DAPIB:	$BUILD	(.DISIZ)		;Dap initialization block
	  $SET	(.DIFLG,DI%CNT,1)	;Request 1 link
	  $SET	(.DIFLG,DI%PGM,%PGNFT)	;[0101]We are NFT
	$EOB
SUBTTL	MAIN ENTRY POINT AND INITIALIZATION

NFT:	RESET
	MOVE P,[IOWD PDLEN,PDL]		;SET UP STACK
	SETZM	DATORG			;Clear impure storage
	MOVE	S1,[DATORG,,DATORG+1]	; Our first location thru
	BLT	S1,DATEND-1		; Last location of DAP storage
       	MOVEI	S1,IB.SZ
	MOVEI	S2,IB
	$CALL	I%INIT			;GET THE LIBRARY
	$CALL	PSIINI			;INITIALIZE PSI SYSTEM
	SKIPN	PMRFLG			;[70]
	JRST	NOPMR			;[70]
	MOVEI	S1,CONBLK		;[70]
	$CALL	.DNINI			;[70]INITIALIZE PMR TABLES
	 $FATAL (Error during initialization of PMR tables) ;[70]
NOPMR:	MOVX	S1,TXT(FAL)
	SKIPE	DEBUGW
	MOVX	S1,TXT(TASK-FALDEBUG)	;[0103]Talk to debugging FAL
	$TEXT	(<-1,,OBJNAM>,<^Q/S1/^0>)	;BECOME FAL
	MOVEI	S1,.DISIZ
	MOVEI	S2,DAPIB
	$CALL	D$INIT			;Init DAPLIB
	$CALL	NODGET			;BUILD NODE TABLE
	JRST	DOCMD			;Start processing commands
SUBTTL	Parser and Command dispatch

REE:	MOVE	P,[IOWD PDLEN,PDL]	;REENTER ADDRESS
	SKIPN	TAKFLG			;DOING A TAKE?
	JRST	PARSER			;NO..JUST PROCESS COMMANDS
	JRST	CMDEOF			;YES..FORCE TERMINATION

DOCMD:	$CALL	CMDINI			;DISPLAY AND INITIALIZE
	JUMPF	PARSER
	$CALL	CLRGJF			;CLEAR JFN BLOCK
	MOVX	S1,GJ%OLD		;File must exist
	MOVEM	S1,GJFBLK		;SAVE FOR GTJFN
	MOVE	S1,LOCNOD
	HRROI	S1,ND$USR(S1)		;Point to logged in directory
	MOVEM	S1,.GJDIR+GJFBLK	;Save in GTFJN block
	MOVEI	S1,GJFBLK		;Point to block
	MOVX	S2,TXT(PS:NFT.INIT)	;Get initialization file name
	GTJFN
	 ERJMP	PARSER
	MOVEM	S1,CMDJFN		;Save JFN
	SETZ	T4,			;Clear display flag
	$CALL	TAKINI			;[0071]Take the file
	SETZM	INIFLG			;[0071]Clear the NFT.INIT flag

PARSER:	$CALL	CNODIS			;TURN OF ^O PROCESSING
	HRROI	S1,PRMPT		;YES..SET THE PROMPT
	$CALL	DPROMPT			;INITIAL SBK
	$CALL	RELJFN			;RELEASE UNOPEN JFN'S
	$CALL	RELNOD			;Release temporary nodes
	MOVEI	S1,KEYFDB		;POINT TO COMMAND WORDS
	$CALL	RFIELD			;PARSE COMMAND WORD
	HRRZ	T1,(S2)			;Save routine address
	MOVEI	S1,FNCSIZ		;Get size of function area
	MOVEI	S2,FNCBEG		;Point to it
	$CALL	.ZCHNK			;Clear it
	$CALL	TAKTST			;Display command if doing take
	$CALL	0(T1)			;Call proper processor
	JRST	PARSER

KEYFDB:	FLD(.CMKEY,CM%FNC+CM%BRK)		;KEYWORD FUNCTION
	CMDTBL				;FROM COMMAND TABLE
	0
	0
	CMDBRK

CMDBRK:	777777,,777760			;Break on all control
	777773,,777760			;Allow /
	400000,,000760			;Allow A-Z
	400000,,000760			;Allow Lower case a-z

CMDTBL:	CMDSIZ-1,, CMDSIZ		;CURRENT,,MAX SIZE OF COMMAND TABLE
	T (COPY)			;COPY (FROM) (TO)
	T (DELETE)			;DELETE (REMOTE FILES)
	T (DIRECTORY)			;DIRECTORY (OF REMOTE FILES)
	T (EXIT)			;EXIT TO MONITOR
	T (HELP)			;OUTPUT HELP MESSAGE
	T (INFORMATION)
	T (PRINT)			;PRINT REMOTE FILE
	T (SET)				;SET MODES COMMAND
	T (SUBMIT)			;SUBMIT (REMOTE FILES)
	T (TAKE)			;TAKE (COMMAND FROM) FILESPEC
	[CM%FW+CM%INV
	ASCIZ /TRACE/],,.TRACE		;TRACE (MESSAGES) invisible command
	T (TYPE)			;TYPE (REMOTE FILES)

	CMDSIZ== .-CMDTBL
SUBTTL	COPY command

.COPY:	STKVAR	<<SRCDEF,DEFSIZ>>	;TEMP AREA TO SAVE DEFAULTS
	NOISE	(FROM)
	MOVEI	S1,CPYRTN		;Get co-routine address
	STORE	S1,,DPRTN		;Save for D$FUNC
	$CALL	CLRGJF			;CLEAR JFN BLOCK
	MOVX	S1,GJ%IFG+GJ%OLD	;Allow wild cards
	MOVEM	S1,GJFBLK
	HRROI	S1,SRCNAM		;Place to store node stuff
	HRROI	S2,SRCFIL		;Place to store file string
	MOVX	T1,TXT(input filespec)
	SETZM SRCPFL			;[0061] ALLOW CONVERSION
	$CALL	PARFIL			;Get a file spec
	MOVEM	S1,SRCNOD		;Save source node
	MOVEM	S2,SRCJFN		;Save source JFN
	MOVX	S2,TXT(input file switches) ;Get help text
	$CALL	PARSWS			;Look for switches if any
	 JUMPF [MOVX S1,TXT(?Illegal switch:) ;[0057]Give error message...
		$CALL TSTCOL		;[0057]...for bad switches
		$CALL TYPATM		;[0057]
		$CALL RELJFN		;[0057]
		JRST CMDER1]		;[0057]
	MOVE	S1,FILATT		;Get file format switches
	MOVEM	S1,SRCSWS		;Save as source switches
	HRLI	S1,DEFBEG		;GET SOURCE ADDRESS
	HRRI	S1,SRCDEF		;GET DEST ADDRESS
	BLT	S1,DEFSIZ-1+SRCDEF	;SAVE THE DEFAUTLS
	NOISE	(TO)

	HRROI	S1,SRCFIL		;POINT TO SOURCE NAME
	MOVX	S2,GJ%OFG+GJ%FOU+GJ%IFG+GJ%MSG	;ALLOW WILD CARDS
	$CALL	FILDEF			;SET UP OUTPUT NAME DEFAULTS
	SETZM	GJFBLK+.GJDEV		;DON'T DEFAULT DEVICE
	SETZM	GJFBLK+.GJDIR		;OR DIRECTORY
	HRROI	S1,DSTNAM		;Place to store dest node name
	HRROI	S2,DSTFIL		;Place to store dest file name
	MOVX	T1,TXT(output filespec)
	SETZM DSTPFL			;[0061]ALLOW CONVERSION
	$CALL	PARFIL			;Get a filespec
	MOVEM	S1,DSTNOD		;Save destination node
	MOVEM	S2,DSTJFN		;Save destination JFN
	MOVX	S2,TXT(output file switches) ;Get help text
	$CALL	PARSWS			;LOOK FOR OPTIONAL SWITCHES
	 JUMPF [MOVX S1,TXT(?Illegal switch:) ;[0057]Give error messages...
		$CALL TSTCOL		;[0057]...for bad switches
		$CALL TYPATM		;[0057]
		$CALL RELJFN		;[0057]
		JRST CMDER1]		;[0057]
	MOVE	S1,FILATT		;Get file format switches
	MOVEM	S1,DSTSWS		;Save for destination file
	CONFRM

COPY40:	SETOM	NAMFLG			;Say name is not displayed
	SKIPN	SRCNOD			;[0062]IF BOTH SOURCE...
	SKIPE	DSTNOD			;[0062]...AND DEST ARE UNTYPED
	JRST	COPY45			;[0062]
	MOVE	S1,LOCNOD		;[0062]THEN MARK DEST AS REMOTE
	MOVEM	S1,DSTNOD		;[0062]
	$TEXT	(,<%No remote node specified, assuming destination file is remote>) ;[77]
COPY45:	SKIPN	SRCNOD			;Source node local
	 JRST	COPY60			;Yes..send the files
	SKIPN	DSTNOD			;Destination node local
	 JRST	COPY70			;Yes..recieve a file
	MOVE	S1,LOCNOD		;[0062]
	CAMN	S1,SRCNOD		;[0062]SOURCE REALLY LOCAL?
	JRST	[SETZM SRCNOD		;[0062]
		$TEXT (,<%No local node specified, assuming source file is local>) ;[77]
		JRST COPY40]		;[0062]
	CAMN	S1,DSTNOD		;[0062]DEST REALLY LOCAL?
	JRST	[SETZM DSTNOD		;[0062]
		$TEXT (,<%No local node specified, assuming destination file is local>) ;[77]
		JRST COPY40]		;[0062]
	REPARS	(Remote to Remote transfers not supported)
;COPY60	Routine to send files to remote node

COPY60:	SETOM	SNDFLG			;Remember we are sending
	MOVX	S1,AF$CRE		;Function is create remote file
	STORE	S1,,DPFNC
	MOVEI	S1,DAPLNK		;Get requested link
	STORE	S1,,DPLNK		;Save it
	MOVE	S1,SRCSWS		;Get source switches
	STORE	S1,,DPLFA		;Save local file attributes
	HRROI	S1,SRCFIL		;Point to local filespec
	STORE	S1,,DPLFS		;Save for D$FUNC
	MOVE	S1,DSTSWS		;Get destination file switches
	STORE	S1,,DPRFA		;Save remote file attributes
	HRROI	S1,DSTFIL		;Point to dest file name
	STORE	S1,,DPRFS		;Save for D$FUNC
	MOVE	S1,[POINT 7,DSTFIL]	;Check what user typed
	$CALL	OUTFLG
	DMOVEM	S1,DSTFLG		;Save for call to OUTNAM
	MOVE	S1,SRCJFN		;GET SOURCE JFN
	SKIPE	S2,DSTNOD		;Get destination node
	$CALL	NODOFF			;Mark node off-line
	MOVEM	S2,REMNOD		;Save for call to GETUSR
	MOVE	S1,SRCJFN		;Get source JFN
	TXNN	S1,GJ%DEV+GJ%DIR+GJ%NAM+GJ%EXT+GJ%VER ;Wild cards?
	JRST	COPY61			;No..Check for output wild cards
	SKIPE	S1,DSTJFN		;Must have Destination JFN
	TXNN	S1,GJ%DEV+GJ%DIR+GJ%NAM+GJ%EXT+GJ%VER ;and must be wild
	 JRST	WLDERR
COPY61:	MOVE	S1,[DSTFIL,,TMPFIL]	;HACK TO SAVE DST ACROSS
	BLT	S1,TMPFIL+FILSIZ-1	;CALLS TO DAP OPEN
COPY62:	HRROI	S1,SRCFIL		;Point to source file storage
	HRRZ	S2,SRCJFN		;Expand without wild cards
	MOVX	T1,FFSPEC
	JFNS				;Get current file name
	MOVE	S1,[TMPFIL,,DSTFIL]
	BLT	S1,DSTFIL+FILSIZ-1
COPY63:	DMOVE	S1,DSTFLG		;Get dest pointer and flags
	$CALL	OUTNAM			;Yes..Get output filename
	 JUMPF	WLDERR			;Bad wild cards
	SKIPE	DSTNOD			;Expand file name if local
	JRST	COPY64			;No..don't expand local name
	MOVX	S1,GJ%SHT+GJ%FOU
	HRROI	S2,DSTFIL
	$CALL	NAMEXT
COPY64:	$CALL	DAPOPN			;Make sure link is OPEN
	MOVEI S1,DSTFIL			;[0061]DEST STRING
	SKIPE DSTPFL			;[0061]NEED RECONVERSION?
	$CALL RESNAM			;YES
	$CALL	DAPFNC			;Do the function
	MOVE	S1,SRCJFN		;Get source JFN
	GNJFN				;Do the next file
	 JRST	DAPCLS			;Finish up
	MOVE	S1,REMNOD		;Get pointer to remote node
	HRRZ	S1,ND$OST(S1)		;Get system type
	CAIN	S1,.OSRXM		;RSX?
	$CALL	DAPCLS			;Yes..close link each time
	JRST	COPY62			;Do the next file
;COPY70	Routine to recieve files from remote node

COPY70:	SETZM	SNDFLG			;Remember we are recieving
	MOVX	S1,AF$OPN		;Function is read remote file
	STORE	S1,,DPFNC
	MOVEI	S1,DAPLNK		;Get requested link
	STORE	S1,,DPLNK		;Save it
	MOVE	S1,SRCSWS		;Get source file switches
	STORE	S1,,DPRFA		;Save remote file attributes
	HRROI	S1,SRCFIL		;Point to source file name
	STORE	S1,,DPRFS		;Save for D$FUNC
	SKIPE	SRCNOD			;Source node local?
	JRST	COPY72			;No..dont expand file name
	MOVX	S1,GJ%SHT+GJ%OLD+GJ%IFG	;Get JFN flags
	HRROI	S2,SRCFIL		;Point to destination
	$CALL	NAMEXT			;Expand the name
COPY72:	MOVE	S1,[POINT 7,DSTFIL]	;Point to user input
	$CALL	OUTFLG			;Find out what they typed
	DMOVEM	S1,DSTFLG		;Save for call to OUTNAM
	MOVE	S1,DSTSWS		;Get destination switches
	STORE	S1,,DPLFA		;Save local file attributes
	HRROI	S1,DSTFIL		;Point to destination file name
	STORE	S1,,DPLFS		;Save as local filespec
	SKIPE	S2,SRCNOD		;Get source node
	$CALL	NODOFF			;Mark node off-line
	MOVEM	S2,REMNOD		;Save for Call to GETUSR
	HRLI	S1,SRCDEF		;Reclaim source defaults
	HRRI	S1,DEFBEG
	BLT	S1,DEFSIZ-1+DEFBEG	;For GETUSR
	DMOVE	S1,DSTFLG		;Get destination flags
	MOVE	T1,DSTJFN		;GET DESTINATION JFN
	TXO	S2,GJ%DIR		;[0054]ALWAYS GET DIR TO MAKE
					;[0054]LOGICAL NAMES WORK
	$CALL	OUTNAM			;Yes..Generate output filename
	 JUMPF	WLDERR			;Bad wild cards
	MOVX	S1,GJ%SHT+GJ%FOU	;File for output
	HRROI	S2,DSTFIL
	$CALL	NAMEXT			;Expand output file name
	 JFCL				;Don't care if this fails
	$CALL	DAPOPN			;Make sure link is open
	MOVEI S1,SRCFIL			;[0061]ADDRESS OF SOURCE FILE STRING
	SKIPE SRCPFL			;[0061]NEED RECONVERSION?
	$CALL RESNAM			;[0061]YES
	$CALL	DAPFNC
	JRST	DAPCLS
CPYRTN:	CAIN	S1,.DMACK		;ACK FOR ACCESS?
	PJRST	CPYACK			;Yes..check for file display
	CAIN	S1,.DMACP		;ACCESS COMPLETE?
	JRST	CPYACP			;Yes..display [OK]
	SUBI	S1,.DMNAM		;Try for name message
	TRNE	S1,-1
	$RETT				;Return for all else
	$CALL	SAVNAM			;Store name
	SKIPT	SNDFLG			;Sending files?
	JRST	CPYRCV			;No..must be recieving
	JRST	CPYSND			;Yes..setup proper text

CPYACK:	AOSE	NAMFLG			;File text displayed?
	$RETT				;Yes..just return
	SKIPE	S1,SRCNOD		;Source node local?
	$TEXT	(,^T/@S1/::^A)		;no..display it
	$TEXT	(,^T/SRCFIL/^T/FROMTO/^A);Display source file
	SKIPE	S1,DSTNOD		;Destination node local?
	$TEXT	(,^T/@S1/::^A)		;no..display it
	$TEXT	(,^T/DSTFIL/^A)		;Display destination file
	$RETT

CPYACP:	$TEXT	(, [OK])		;Display OK
	SETOM	NAMFLG			;Say name is not displayed
	$RETT				;Return
CPYSND:	TLNE	S1,NA$FSP		;Actual remote filespec?
	$TEXT	(<-1,,DSTFIL>,<^Q/S2/^0>)	;Yes..save as destination file
	SKIPN	S1			;Expanded local filespec?
	$TEXT	(<-1,,SRCFIL>,<^Q/S2/^0>)	;Yes..save as source file
	$RETT

CPYRCV:	TLNE	S1,NA$FSP		;Actual remote filespec?
	$TEXT	(<-1,,SRCFIL>,<^Q/S2/^0>)	;Yes..save as source file
	SKIPN	S1			;Expaned local filespec?
	$TEXT	(<-1,,DSTFIL>,<^Q/S2/^0>)	;Yes..save as destination file
	TLNN	S1,NA$FNM		;Doing wild operation?
	$RETT				;No..just return
	$TEXT	(<-1,,SRCFIL>,^T/VOLNAM/^T/DIRNAM/^T/FILNAM/^0)
	SKIPL	NAMFLG			;Name displayed?
	$CALL	CPYACP			;Yes..display [ok]
	PUSH P,P2			;[0061]Convert names supplied...
	MOVE S1,[POINT 7,SRCFIL]	;[0061]...in a name message
	MOVEI P2,SRCFIL			;[0061]
	$CALL COVNAM			;[0061]
	POP P,P2			;[0061]
	MOVX	S1,GJ%SHT+GJ%OFG	;Get parse only JFN for name
	HRROI	S2,SRCFIL
	GTJFN
	 ERJMP	CPYNA1			;Try file name only
	TXNN 	S1,GJ%NOD		;[0102] Node in file spec ?
	JRST CPYNA2			;[0102] no. Generate output filename
	RLJFN				;[0102] yes. pretend GTJFN failed,
	 JFCL				;[0102] release JFN, ignore error
CPYNA1:	MOVX	S1,GJ%SHT+GJ%OFG
	HRROI	S2,FILNAM
	GTJFN
	 ERJMP	.RETF			;Fail if JFN not assigned
CPYNA2:	HRRZM	S1,REMJFN		;Save JFN for OUTNAM
	HRROI	S1,DSTFIL		;Generate destination name
	MOVX	S2,GJ%NAM+GJ%EXT+GJ%VER ;[0054]
	MOVE	T1,DSTFLG+1		;See what caller typed
	ANDX	T1,GJ%DEV+GJ%DIR
	IOR	S2,T1			;Generate required fields
	PUSH	P,S1			;[54]SAVE ACS
	PUSH	P,S2			;[54]
	PUSH	P,T1			;[54]
	PUSH	P,T2			;[54]
	MOVE	S2,DSTJFN		;[54]DOES THIS FILE SPEC...
	MOVX	T1,FLD(1,JS%DIR)	;[54]HAVE A DIR FIELD?
	SETZ	T2,			;[54]
	JFNS				;[54]
	POP	P,T2			;[54]
	POP	P,T1			;[54]
	POP	P,S2			;[54]
	CAME	S1,[-1,,DSTFIL]		;[54]
	TXO	S2,GJ%DIR		;[0054]ALWAYS GET DIR TO MAKE
					;[0054]LOGICAL NAMES WORK
	POP	P,S1			;[54]
	$CALL	OUTNAM			;Generate output name
	MOVX	S1,GJ%SHT+GJ%FOU	;File for output
	HRROI	S2,DSTFIL		;Store in DSTFIL
	$CALL	NAMEXT			;Expand the name
	MOVE	S1,REMJFN
	RLJFN				;Release the JFN
	 ERJMP	.+1
	SETZM	REMJFN			;Null the JFN
	MOVEI S1,SRCFIL			;[0061]
	SKIPE SRCPFL			;[0061]Need reconversion?
	$CALL RESNAM			;[0061]Yes, reconvert file name
	$RET				;Return True/false per OUTNAM
SUBTTL	DELETE DIRECTORY SUBMIT TRACE and TYPE commands

.DELET:	NOISE	(REMOTE FILES)
	MOVX	S1,AF$ERA		;Function is delete remote files
	MOVEI	S2,REMRTN		;General Co-routine
	MOVX	T1,TXT<>		;No default name or extenstion
	MOVX	T2,GJ%IFG+GJ%OLD	;Allow wild cards
	JRST	REMFIL			;Enter common Code

.DIREC:	NOISE	(OF REMOTE FILES)
	MOVX	S1,AF$DIR		;Function is directory
	MOVEI	S2,DIRRTN		;Directory Co-routine
	MOVX	T1,TXT(*.*)		;Default name and ext
	MOVX	T2,GJ%IFG+GJ%OLD+.GJALL	;Wild and * for version
	JRST	REMFIL			;Enter common code

.PRINT:	NOISE	(REMOTE FILES)		;Function is print remote files
	MOVX	S1,AF$PRN		;At remote node
	MOVEI	S2,REMRTN
	MOVX	T1,TXT()
	MOVX	T2,GJ%IFG+GJ%OLD
	JRST	REMFIL

.SUBMI:	NOISE	(REMOTE FILES)
	MOVX	S1,AF$EXE		;Function is submit remote files
	MOVEI	S2,REMRTN		;General Co-routine
	MOVX	T1,TXT(.CTL)		;Default extention is .CTL
	MOVX	T2,GJ%IFG+GJ%OLD	;Allow wild cards
	JRST	REMFIL			;Enter common code

.TRACE:	NOISE	(DAP MESSAGES)
	CONFRM
	MOVEI	S1,.PRIOU
	MOVEM	S1,DAPIB+.DIMSG		;Store for output
	MOVEI	S1,.DISIZ
	MOVEI	S2,DAPIB
	$CALL	D$INIT			;Re-initialize DAPLIB
	$RETT

.TYPE:	NOISE	(REMOTE FILES)
	MOVX	S1,AF$TYP		;Function is type remote files
	MOVEI	S2,TYPRTN		;General Co-routine
	MOVX	T1,TXT()		;No default name or extenstion
	MOVX	T2,GJ%IFG+GJ%OLD	;Allow wild cards
	SETOM	CNOFLG			;Request control O processing
	JRST	REMFIL			;Enter common code
SUBTTL	REMFIL	Common parsing routine for remote filespec

REMFSW:	FLD(.CMCFM,CM%FNC)+REMFS1

REMFS1:	FLD(.CMSWI,CM%FNC)
	REMSWS


REMSWS:	REMSIZ,,REMSIZ
	SV (ACCOUNT)
	SV (PASSWORD)
	SV (USER)
	REMSIZ==.-REMSWS-1

REMFIL:	STORE	S1,,DPFNC		;Save requested function
	STORE	S2,,DPRTN		;Save for D$FUNC
	MOVEI	S1,DAPLNK		;Get requested link
	STORE	S1,,DPLNK		;Save it
	DMOVE	S1,T1			;Get Defaults
	$CALL	FILDEF			;Set them up
	HRROI	S1,SRCNAM		;Point to destination for NODE
	HRROI	S2,SRCFIL		;Point to destination for file
	MOVX	T1,TXT(remote filespec)
	$CALL	PARFIL			;Parse a file spec
	MOVEM	S1,SRCNOD		;Save source node
	MOVEM	S2,SRCJFN		;Save JFN
	MOVEI S1,SRCFIL			;[0061]
	SKIPE SRCPFL			;[0061]WAS FILE NAME CHANGED?
	$CALL RESNAM			;[0061]RESTORE TRUE FILE NAME
REMF20:	MOVEI	S1,REMFSW		;Point to Delete switches
	$CALL	RFIELD
	CAIN	T2,.CMCFM		;Parse a confirm?
	JRST	REMF30			;Yes..go finish up
	HRRZ	S2,0(S2)		;No..must be a switch
	PUSHJ	P,0(S2)			;Call the processor
	JRST	REMF20			;Look for confirm

REMF30:	SETZM	NAMFLG			;Say name not yet displayed
	SETZM	VOLNAM			;Null volume name
	SETZM	DIRNAM			;Null directory name
	SETZM	FILNAM			;Null file name
	SETZM	FILSPC			;Null file spec
	SETZM	FILNAM			;Say file name is missing
	SKIPE	S2,SRCNOD		;Get source node
	$CALL	NODOFF			;Mark node off-line
	MOVEM	S2,REMNOD		;Save for Call to GETUSR
	HRROI	S1,SRCFIL		;Point to file name
	STORE	S1,,DPRFS		;Save for D$FUNC
	MOVE	S2,SRCJFN		;Get source JFN
	MOVX	T1,FFSPEC		;Do full name expansion if local
	SKIPN	SRCNOD
	JFNS

REMF40:	SKIPF	CNOFLG			;Want control O interrupts?
	$CALL	CNOENA			;Yes..enable them
	$CALL	DAPOPN			;Make sure link is open
	$CALL	DAPFNC			;Do the function
	 JRST	DAPCLS			;Finish up nicely
SUBTTL	DIRRTN	Co-routine for Directory command

;DIRRTN is called from DAPLIB durring function execution

;ACCEPTS	S1/ [Flags],,DAP message
;		S2/ [Arguments]


DIRRTN:	CAIE	S1,.DMATT		;Attributes?
	CAIN	S1,.DMACK		; Or ACK?
	JRST	DIRATT			;Yes..process it
	SUBI	S1,.DMNAM		;Try for name message
	TRNE	S1,-1			;Is it some type of name?
	$RETT				;No..just return
	$CALL	SAVNAM			;Yes..store the pointer
	TLNN	S1,NA$DIR		;[0066]DIRECTORY NAME?
	SKIPE	NAMFLG			;[0066]OR VOL NAME?
	JRST	DOHDR			;[0066]YES
	TLNE	S1,NA$VOL		;[0066]VOL NAME?
	SETOM	NAMFLG			;[0066]FLAG IT FOR NEXT TIME
	$RETT				;No..just return
DOHDR:	$TEXT	(,^M^J  ^T/@REMNOD/::^T/VOLNAM/^T/DIRNAM/)
	SETZM	NAMFLG			;[0066]CLEAR VOL NAME SEEN FLAG
	$RETT

;DIRATT is called with address of remote files FDB in S2
DIRATT:	SKIPN	FILNAM			;Was filename returned?
	$TEXT	(<-1,,FILNAM>,<^T/SRCFIL/^0>)
	$TEXT	(<-1,,DIRTXT>,<^T/FILNAM/;P^O6L/.FBPRT(S2)/^0>)
	$TEXT	(<-1,,DIRTX1>,<^D4R /.FBBYV(S2),FB%PGC/ ^D/.FBSIZ(S2)/(^D/.FBBYV(S2),FB%BSZ/)^0>)
	$TEXT	(,<^T30L /DIRTXT/^T15L /DIRTX1/^A>)
	SKIPN	.FBWRT(S2)			;[67]
	JRST	DIRAT1				;[67]
	$TEXT	(,< ^H/.FBWRT(S2)/^A>)		;Yes..display it
	$TEXT	(,)				;Do final crlf
	$RETT
DIRAT1:	SKIPE	.FBCRV(S2)			;[67]
	$TEXT	(,< ^H/.FBCRV(S2)/^A>)		;[67]
	$TEXT	(,)				;[67]
	$RETT					;[67]
SUBTTL	REMRTN	Common Co-routine for DELETE and SUBMIT commands

;ACCEPTS	S1/ [Flags],,msg type
;		S2/ [Argument pointer]

REMRTN:	CAIN	S1,.DMACP		;Access complete?
	PJRST	REMACP			;Yes..process it
	SUBI	S1,.DMNAM		;Check for name function
	TRNE	S1,-1			;Was it?
	 $RETT				;No..just return

REMNAM:	$CALL	SAVNAM			;Yes..store the pointers
	TLNE	S1,NA$FNM		;File name?
	JRST	REMFNM			;Yes..process it
	TLNN	S1,NA$FSP		;File spec?
	$RETT				;No..just return
	SKIPN	DIRNAM			;Wild operation?
	SKIPE	FILNAM
	$RETT				;Yes..ignore NA$FSP
	SKIPE	NAMFLG			;Been here before?
	$CALL	REMSOK			;Yes..display previous [OK]
	$TEXT	(,^T/@REMNOD/::^Q/S2/^A);No..type the filespec
	SETOM	NAMFLG			;Say weve been here before
	$RETT				;And return

REMFNM:	SKIPE	NAMFLG			;Been here before?
	$CALL	REMSOK			;Yes..display [OK]
	$TEXT	(,^T/@REMNOD/::^T/VOLNAM/^T/DIRNAM/^T/FILNAM/^A)
	SETOM	NAMFLG			;Say weve been here before
	$RETT

REMACP:	SKIPE	NAMFLG			;Has name been displayed?
	JRST	REMSOK			;Yes..display final OK
	$TEXT	(,^T/@REMNOD/::^T/SRCFIL/^A) ;No..display original name
REMSOK:	$TEXT	(, [OK])			;Display ok message
	SETZM	NAMFLG			;Ready for next name display
	$RETT
SUBTTL	TYPRTN	Co-routine for TYPE command

;ACCEPTS	S1/ [Flags],,msg type
;		S2/ [Argument pointer]

TYPRTN:	SUBI	S1,.DMNAM		;Check for name function
	TRNE	S1,-1			;Was it?
	 $RETT				;No..just return

TYPNAM:	$CALL	SAVNAM			;Yes..store the pointers
	TLNN	S1,NA$FNM		;File name?
	$RETT				;No..just return
	SKIPF	CNOFLG			;Trapping Control-O?
	$CALL	SUPOFF			;Yes..turn suppress bit off
	$CALL	TYPCRL			;Type CRLF if needed
	$TEXT	(, ^T/@REMNOD/::^T/VOLNAM/^T/DIRNAM/^T/FILNAM/^M^J)
	SETOM	NAMFLG			;Say name has been displayed
	$RETT

TYPCRL:	SKIPN	NAMFLG			;Has name been displayed?
	$RETT				;No..Just return
	$TEXT				;Yes..display CRLF
	$RETT

;SAVNAM is called with S1 containing flag indicating type of name msg
;		       S2 containing pointer to the asciz name string

SAVNAM:	DMOVE	T2,S1			;Save flags and pointer
	SETZ	S1,			;Clear destination pointer
	TLNE	T2,NA$VOL		;Is it structure?
	HRROI	S1,VOLNAM		;Yes..store in volume name
	TLNE	T2,NA$DIR		;Directory?
	HRROI	S1,DIRNAM		;Yes..store in directory name
	TLNE	T2,NA$FNM		;File name?
	HRROI	S1,FILNAM		;Yes..store in filename
	TLNE	T2,NA$FSP		;Full file spec?
	HRROI	S1,FILSPC		;Yes..store in filespec
	SKIPE	S1			;Destination specified?
	$CALL	STOSTR			;Yes..store the name
	DMOVE	S1,T2			;Restore flags and pointer
	$RETT				;Return
SUBTTL	OUTDEF Routine to default output file name

OUTDEF:	$CALL	CLRGJF			;Clear file parse block
	SKIPN	S1,SRCJFN		;Source JFN given?
	$RETT				;No..just return
	MOVE	T4,[-3,,1]		;Set up for <Dir>nam.ext
	TXNN	S1,GJ%DIR		;Directory have wild cards?
	AOBJN	T4,.+1			;No..skip it
	MOVX	S1,GJ%FOU+GJ%OFG	;Allow wild + file for output
	MOVEM	S1,GJFBLK+.GJGEN	;Store the flags
OUTD.1:	HLLZ	S1,FSTRT(T4)		;GET FIELD
	MOVE	T1,FFLDT(T4)		;Get the offset of bits
	HRRO	S1,FSTRT(T4)		;POINT TO DESTINATION FOR STRING
	MOVEM	S1,GJFBLK+.GJDEV(T4)	;STORE THE POINTER
	MOVE	S2,SRCJFN		;PICK UP SOURCE JFN
	JFNS				;Copy spec from souce
OUTD.4:	AOBJN	T4,OUTD.1		;NEXT FIELD
	$RETT


FSTRT:	GJ%DEV+DEFDEV			;DEVICE STRING STORAGE
	GJ%DIR+DEFDIR			;DIRECTORY STRING STORAGE
	GJ%NAM+DEFNAM			;FILENAME STRING STORAGE
	GJ%EXT+DEFEXT			;EXTENTION STRING STORAGE
	GJ%VER+DEFVER			;VERSION STRING STORAGE

FFLDT:	FLD(.JSAOF,JS%DEV)		;JFNS PRINT DEVICE
	FLD(.JSAOF,JS%DIR)		;JFNS PRNT DIR
	NIFLD==.-FFLDT			;NUMBER OF INPUT FIELDS

	FLD(.JSAOF,JS%NAM)		;JFNS PRINT NAME
	FLD(.JSAOF,JS%TYP)		;JFNS PRINT EXTENTION
	FLD(.JSAOF,JS%GEN)		;JFNS PRINT VERSION
	NFFLD=.-FFLDT			;NUMBER OF OUTPUT FIELDS
SUBTTL	HELP and EXIT commands

; EXIT COMMAND

.EXIT:	NOISE	(TO MONITOR)
	CONFRM
	HALTF				;Exit to monitor
	$RETT				;Return to parser if continued

; HELP COMMAND

HLPFOB:	$BUILD	(FOB.SZ)
	  $SET	(FOB.FD,,[$FD(HLP:NFT.HLP)])
	  $SET	(FOB.CW,FB.BSZ,7)
	  $SET	(FOB.CW,FB.LSN,1)
	$EOB

.HELP:	NOISE	(WITH NFT)
	CONFRM
	STKVAR	<HLPIFN>		;IFN FOR HELP FILE
	DMOVE	S1,[EXP FOB.SZ,HLPFOB]	;POINT TO FILE INFO
	$CALL	F%IOPN			;OPEN THE FILE
	 JUMPF	NOHELP
	MOVEM	S1,HLPIFN		;STORE THE IFN

HELP1:	MOVE	S1,HLPIFN
	$CALL	F%IBYT
	JUMPF	HELP2			;FINISHED ON EOF
	HRRZ	S1,SBK+.CMIOJ		;GET OUTPUT JFN
	BOUT
	JRST	HELP1			;FINISH THE FILE

HELP2:	MOVE	S1,HLPIFN		;GET THE IFN
	$CALL	F%REL			;CLOSE THE FILE
	$RETT				;And return

;HERE ON ERROR WITH HELP FILE
NOHELP:	MOVX	S1,TXT(No HELP available)
	$CALL	K%SOUT			;DUMP THE MESSAGE
	$RETF				;GO PARSE NEXT COMMAND
SUBTTL	INFORMATION command dispatch

.INFOR:	NOISE	(ABOUT)
	MOVEI	S1,INFFDB		;INFORMATION KEYTAB
	$CALL	CFIELD			;Get keyword and confirmation
	HRRZ	S2,(S2)			;GET DISPATCH ADDRESS
	PUSHJ	P,0(S2)			;CALL THE ROUTINE
	$RETT				;RETURN TO CALLER

INFFDB:	FLD(.CMKEY,CM%FNC)+CM%DPP	;DEFAULT POINTER
	INFTBL				;KEYWORD TABLE
	0				;HELP
	TXT (DECNET)			;Default is INF DECNET

INFTBL:	INFSIZ,,INFSIZ
	T (DECNET,INFDNT)		;Information about DECNET
	T (DEFAULTS,INFDEF)		;Information about DEFAUTLS
	INFSIZ==.-INFTBL-1
SUBTTL	Information about DECNET

INFDNT:	$SAVE	<P1,P2,P3>		;[0073]
	$CALL	NODGET			;GET CURRENT NODE INFO
	JUMPF	[$TEXT (,<?Error getting list of available nodes>)
		$RETF]
	MOVE	P2,NODTBL		;[0073]
	HLRZ	P1,0(P2)		;[0073]TABLE SIZE
	JUMPE	P1,INFDN2		;[0073]EMPTY TABLE
	ADDI	P2,1			;[0073]
INFDN1:	HRRZ	S2,0(P2)		;[0073]
	MOVE	S1,ND$STA(S2)		; AND IT'S STATUS
	CAIN	S1,.NDSON		;IS IT ONLINE?
	JRST	INFDN3			;YES..TELL THEM
	ADDI	P2,1			;[0073]
	SUBI	P1,1			;[0073]
	JUMPE	P1,INFDN2		;[0073]
	JRST	INFDN1			;[0073]
INFDN2:	$TEXT	(,< No DECNET nodes are accessible>)
	$RETF				;RETURN FAILURE

INFDN3:	$TEXT	(,< Accessible DECNET nodes are:	^A>)
	MOVEI	P3,5			;[0073]
	JRST	INFDN5

INFDN4:	MOVE	S1,ND$STA(S2)		;GET NODE STATUS
	CAIE	S1,.NDSON		;IS IT ON LINE?
	 JRST	INFDN6			;NO..CHECK THE NEXT
	$TEXT	(,<	^A>)		;YES..DISPLAY A COMMA
	SOSG	P3			;[0073]
	JRST	[$TEXT			;[0073]
		MOVEI P3,^D9		;[0073]
		JRST .+1]		;[0073]
INFDN5:	$TEXT	(,<^T/ND$NAM(S2)/^A>)	;DISPLAY THE NODE NAME
INFDN6:	ADDI	P2,1			;[0073]
	SUBI	P1,1			;[0073]
	JUMPE	P1,INFDN7		;[0073]END OF LIST
	HRRZ	S2,0(P2)		;[0073]
	JRST	INFDN4			;[0073]
	JUMPT	INFDN4			;PROCESS IT

INFDN7:	$TEXT				;DISPLAY A CRLF
	$RETT				;AND RETURN
SUBTTL	Information about DEFAULTS

INFDEF:	MOVE	S1,NODLST		;POINT TO NODE LIST
	$CALL	L%FIRST			;POINT TO FIRST ENTRY
INFDE1:	JUMPF	.RETT			;QUIT AT END OF LIST
	MOVE	S1,S2			;PUT ADDRESS IN S1
	$CALL	INFNOD			;DISPLAY THE DEFAULTS
	MOVE	S1,NODLST		;POINT TO NODE LIST
	$CALL	L%NEXT			;GET THE NEXT ENTRY
	JRST	INFDE1			;LOOP THRU THEM ALL


;INFNOD Routine to display node and user information

;ACCEPTS	S1/ Base of node data

;RETURNS TRUE	Information has been displayed


INFNOD:	MOVEI	S2,1B35			;Get String valid bit
	TDNN	S2,ND$USR(S1)		;User or account string valid?
	TDNE	S2,ND$ACT(S1)
	 JRST	INFNO1			;Yes..display the info
	SKIPN	ND$OST(S1)		;OSTYPE Specified?
	$RETT				;No..just return
INFNO1:	$TEXT	(,<Node ^T/ND$NAM(S1)/::^A>)	;DISPLAY THE NODE NAME
	TDNE	S2,ND$USR(S1)		;Display only valid defaults
	$TEXT	(,</USER:^T/ND$USR(S1)/^A>)	;YES..DISPLAY IT
	TDNE	S2,ND$ACT(S1)		;Display only valid defaults
	$TEXT	(,</ACCOUNT:^T/ND$ACT(S1)/^A>)	;YES..DISPLAY IT
	SKIPE	ND$OST(S1)			;OSTYPE KNOWN?
	$TEXT	(,</OSTYPE:^Q/ND$OST(S1),LHMASK/^A>) ;YES..DISPLAY IT
	$TEXT				;CRLF
	$RETT				;NO..JUST RETURN
SUBTTL	SET defaults command

.SET:	MOVEI	S1,SETFDB		;KEYWORD -- DEFAULT
	$CALL	PARSE			;PARSE THE KEYWORD
	SKIPT				;PARSE OK?
	 REPARS	(Invalid set command)	;NO..ERROR
	HRRZ	S2,(S2)			;GET DISPATCH ADDRESS
	PUSHJ	P,0(S2)			;DO THE ROUTINE
	$RETT

SEDEFA:	$SAVE	<P1,P2>
	NOISE	(FOR NODE)
	HRROI	S1,SRCNAM		;Point to node text
	MOVX	S2,TXT(NODE::)		;Get help text
	$CALL	PARNOD
	SKIPN	S1			;Node specified?
	MOVE	S1,LOCNOD		;No..use local node
	MOVEM	S1,SRCNOD		;Save as source node
	MOVE	P1,S1			;Save for OSTYPE switch
	SETZM	P2			;Clear count of switches specified
SEDEF1:	MOVEI	S1,DEFASW		;POINT TO OUR SWITCH FDB
	$CALL	RFIELD			;PARSE THE FIELD
	CAIN	T2,.CMCFM		;PARSE CONFIRMATION?
	JRST	SEDEF2			;YES..FINISH UP
	HRRZ	S2,(S2)			;NO..GET PROCESSOR ADDRESS
	PUSHJ	P,0(S2)			;CALL THE PROCESSOR
	AOJA	P2,SEDEF1			;LOOK FOR CONFIRM

SEDEF2:	JUMPE	P2,[MOVEI S2,1		;Any switches specified?
		    ANDCAM S2,REMUSR		;NO..CLEAR VALID BIT FOR USER
		    ANDCAM S2,REMACT		;CLEAR VALID BIT FOR ACCOUNT
		    ANDCAM S2,REMPSW		;CLEAR VALID BIT FOR PASSWORD
		    JRST .+1]
	MOVE	S1,SRCNOD		;Get address of source node
	MOVEI	S2,.NDSOF		;Get off-line status
	SKIPGE	ND$STA(S1)		;Status already known?
	MOVEM	S2,ND$STA(S1)		;No..assume off-line
	HRLI	S2,REMUSR		;Copy defaults obtained from switches
	HRRI	S2,ND$USR(S1)
	MOVE	S1,S2
	BLT	S1,DEFSIZ-1(S2)
	$RETT
DEFASW:	FLD(.CMCFM,CM%FNC)+DEFAS1	;CONFIRM OR SWITCH

DEFAS1:	FLD(.CMSWI,CM%FNC)		;PARSE SWITCHES
	DEFSWS				;FILE SWITCH TABLE

DEFSWS:	XWD DFSSIZ,DFSSIZ		;DEFAULT SWITCH TABLE SIZE
	SV (ACCOUNT)
	SV (OSTYPE)
	SV (PASSWORD)
	SV (USER)
	DFSSIZ==.-DEFSWS-1

SETFDB:	FLD(.CMKEY,CM%FNC)+CM%DPP	;DEFAULT POINTER PRESENT
	SETTBL				;SET KEYWORD TABLE
	0				;NO HELP
	TXT (DEFAULTS)			;DEFAULT IS "DEFAULT"

SETTBL:	SETSIZ,,SETSIZ
	T (DEFAULTS,SEDEFA)
	SETSIZ==.-SETTBL-1
SUBTTL	PARFIL	Routine to parse a network file specification

;ACCEPTS	S1/ Destination pointer for node string
;		S2/ Destination pointer for file spec string
;		T1/ Pointer to help text for this parse
;	    GJFBLK/ Flags and defaults established

;RETURNS TRUE	S1/ Address of node data if node exists
;		or  0 if node wasn't typed or local node was specified
;		or -1 if a new node was typed
;		S2/ JFN acquired on behalf of the filespec
;		or  0 if no JFN was obtained


	P%%PPN==1B1		;We saw [P,PN]
	P%%GEN==1B2		;We saw ;GEN


PARFIL:	$SAVE	<P1,P2,P3,P4>		;Save some Ac's
	DMOVE	P1,S1			;Save calling pointers
	MOVEM	T1,CMDFDB+.CMHLP	;Save help pointer
	MOVE	T1,FILFDB+.CMFLG	;Get our file function
	MOVEM	T1,CMDFDB+.CMFLG	;Save it for COMND
       	MOVEI	S1,CMDFDB		;Point to our FDB
	MOVX 	T1,GJ%XTN		;[0102] Make sure GTJFN block
	IORM 	T1,GJFBLK+.GJGEN	; is extended and
	MOVX 	T1,G1%LOC		;  local files
	IORM 	T1,GJFBLK+.GJF2		;   only.
	$CALL	RFLDE			;Try for a file
	JUMPT	PARFI5			;We found a local file
	JUMPE	P1,CMDERR		;The file must be remote
	MOVE	T1,SBK+.CMPTR		;Get pointer to characters
	MOVE	T2,SBK+.CMINC		;Get unparsed count
	MOVE	T3,[POINT 7,ATMBUF]	;Point to destination
	MOVEI	T4,^D6			;Allow six characters

PARFI2:	$CALL	PARFI9			;Get character
	CAIE	S1," "			;Ignore spaces and tabs
	CAIN	S1,.CHTAB
	 JRST	PARFI2			;Back for more
	SKIPA				;We have the character
PARFI3:	$CALL	PARFI9			;Get character
	CAIN	S1,":"			;Node terminator?
	JRST	PARFI4			;Yes..go check for next ":"
	IDPB	S1,T3			;No..store the character
	CAIL	S1,"0"			;Check proper node syntax
	CAILE	S1,"9"
	 SKIPA				;Not numeric..check alpha
	JRST	PARFIX			;[0063]Back for next character
	CAIL	S1,"a"			;Upper case?
	SUBI	S1,40			;Convert it to upper
	CAIL	S1,"A"			;has to be alpha
	CAILE	S1,"Z"
	 PJRST	BADNOD			;[0063]
PARFIX:	SOJGE	T4,PARFI3		;[0063]Back for rest of node
	PJRST	BADNOD			;[0063]

PARFI4:	$CALL	PARFI9			;Get next character
	CAIE	S1,":"			;Second delimiter for NODE::?
	PJRST	BADNOD			;[0063]
	SETZ	S1,			;Get a null
	IDPB	S1,T3			;Terminate atom
	MOVEM	T1,SBK+.CMPTR		;We've just parsed the node
	MOVEM	T2,SBK+.CMINC		;Save count of unparsed chars
	$CALL	PARNO1			;Get the node index
	MOVE	P1,S1			;[0062]Remember node index for return
	MOVE	S1,FILFDB		;[0062]GET REMOTE FILE SPEC
	MOVEM	S1,CMDFDB+.CMFLG	;Save for PARSE
	MOVE	S1,GJFBLK		;Get starting flags
	TXZ	S1,GJ%IFG+GJ%OLD+GJ%MSG	;Clear wild input flag
	TXO	S1,GJ%OFG		;Get parse only flag
	MOVEM	S1,GJFBLK		;Save for next parse
PARFI6:	MOVX	S1,G1%SLN		;Suppress logical name expansion
	IORM	S1,GJFBLK+.GJF2		;Set for GTJFN
	MOVE S1,SBK+.CMPTR		;[0061]
	$CALL COVNAM			;[0061]Convert non-20 style file names
	MOVEI S1,CMDFDB			;[0061]
	$CALL RFLDE			;[0061]Now parse it as a 20 filename
	 JUMPF [HRROI S1,[ASCIZ/
?Syntax error in remote file name - /]
		PSOUT			;[0063]
		MOVEI S1,.PRIOU		;[0063]
		MOVE  S2,[.FHSLF,,-1]	;[0063]
		SETZ T1,		;[0063]
		ERSTR			;[0063]PRINT LAST ERROR IN THIS PROCESS
		 JFCL			;[0063]
		 JFCL			;[0063]
		HRROI S1,[ASCIZ /
/]
		PSOUT			;[0063]
		JRST CMDER1]		;[0063]
	SKIPA				;Remember, we parsed a node!
PARFI5:	SETZ	P1,			;We parsed local node
	MOVE	S1,P2			;Get file destination pointer
	MOVE	P2,S2			;Save JFN for return
	$CALL	STOATM
	MOVE	S1,P1			;[0062]
	SKIPN	P1			;Parse a node?
	$CALL	PARNO2			;Yes..copy local defaults
	DMOVE	S1,P1			;Return node and JFN
	$RETT				;Hurray..we've got it

PARFI9:	ILDB	S1,T1			;Get next comnd byte
	SOS	T2			;Decr unparsed count
	$RET				;Return

BADNOD:	HRROI	S1,[ASCIZ /
?Syntax error in node name or error in local file specification
 (/]
	PSOUT				;[0063]
	MOVEI	S1,.PRIOU		;[0063]
	MOVE	S2,[.FHSLF,,-1]		;[0063]
	SETZ	T1,			;[0063]
	ERSTR				;[0063]LAST ERROR IN THIS PROCESS
	 JFCL				;[0063]
	 JFCL				;[0063]
	HRROI S1,[ASCIZ /)
/]
	PSOUT				;[0063]
	JRST CMDER1			;[0063]

FILFDB:	FLD(.CMFIL,CM%FNC)+CM%SDH+CM%HPP	;LOCAL FILESPEC
SUBTTL	COVNAM Routine to make a file spec TOPS-20 compatible

;	This entire routine is part of edit 0061

;ACCEPTS	S1/ Pointer to file spec string
;		P2/ ADDRESS OF DESTINATION STRING

;RETURN		S1/ SAME POINTER TO UPDATED FILE SPEC STRING
;		-1(P2)/ BITS SET TO SHOW ANY CHANGES MADE

COVNAM:	$SAVE <S2,T1>
	MOVE S2,S1			;STRING POINTER
	SETZ S1,			;FLAG WORD
CN.0:	ILDB T1,S2			;GET A BYTE
	CAIE T1,"/"
	SKIPN T1
	JRST [MOVEM S1,-1(P2)		;SAVE THE BITS
	      $RETT]			;RETURN
	CAIE T1,";"			;SEMI COLON?
	JRST CN.1			;NO
	TXO S1,P%%GEN			;SEMI SEEN
	MOVEI T1,"."			;CONVERT TO...
	DPB T1,S2			;A PERIOD
CN.1:	CAIE T1,","			;SEEN A COMMA?
	JRST CN.0			;NO
	TXO S1,P%%PPN			;SET THE FLAG
	MOVEI T1,"-"			;CONVERT TO A DASH
	DPB T1,S2
	JRST CN.0
SUBTTL RESNAM Routine to restore file spec to original condition

;	This entire routine is part of edit 0061

;ACCEPTS	S1/ ADDRESS OF STRING

;RETURNS	S1/ ADDRESS OF UPDATED STRING

RESNAM:	$SAVE <S2,T1>
	MOVE S2,-1(S1)			;GET FLAG BITS
	HLL S1,[POINT 7,0]		;MAKE A BYTE POINTER
RN.2:	ILDB T1,S1			;GET A BYTE
	CAIE T1,"/"
	SKIPN T1			;END OF STRING?
	$RETT				;YES
	CAIE T1,"["			;DIRECTORY?
	CAIN T1,"<"			;?
	JRST RN.0			;YES
	CAIE T1,"."			;PERIOD?
	JRST RN.2			;NO
RN.3:	ILDB T1,S1			;GET A BYTE
	CAIE T1,"/"
	SKIPN T1			;END OF STRING?
	$RETT				;YES, RETURN
	CAIE T1,"."			;YES, IT MUST BE THE VERSION
	JRST RN.3			;NOT VERSION, KEEP LOOKING
	MOVEI T1,";"			;TURN . INTO ;
	TXNE S2,P%%GEN			;WAS A ; TURNED INTO A DOT?
	DPB T1,S1			;YES, TURN IT BACK
	$RETT
RN.0:	MOVEI T1,"["			;ALWAYS USE SQUARE BRACKETS
	DPB T1,S1			;CHANGE < TO [
RN.1:	ILDB T1,S1			;GET A BYTE
	CAIE T1,"]"			;WAS IT END OF DIR NAME?
	CAIN T1,">"
	JRST [MOVEI T1,"]"		;YES, MAKE IT A SQUARE BRACKET
		DPB T1,S1
		JRST RN.2]
	CAIE T1,"-"			;WAS IT A DASH?
	JRST RN.1			;NO, KEEP LOOKING
	MOVEI T1,","			;TURN . INTO ,
	TXNE S2,P%%PPN			;WAS A , TURNED INTO A DOT?
	DPB T1,S1			;YES, RESTORE IT
	JRST RN.1
SUBTTL	PARNOD	Routine to parse NODE::

;ACCEPTS	S1/ Pointer to destination for parsed node string
;		S2/ Pointer to help text

;RETURNS TRUE	S1/ Address of node data
;		    or 0 if local node specified

;	FALSE	S1/ 0 (local node implied)

PARNOD:	$SAVE	<P1>			;Preserve an AC
	MOVE	P1,S1			;Save destination pointer
	MOVEM	S2,CMDFDB+.CMHLP	;Save help pointer
	MOVE	S2,NODFDB+.CMFLG	;Get Node function
	TXO	S2,CM%HPP+CM%SDH	;Say help is here
	MOVEM	S2,CMDFDB+.CMFLG	;Save the function word
	MOVEI	S1,CMDFDB		;Point to our FDB
	$CALL	RFLDE			;Parse the field
	 JUMPF	[SETZ S1,		;[0062]No node was parsed
		JRST PARNO2]		;[0062]
PARNO1:	MOVE	S1,P1			;Get destination pointer
	$CALL	STOATM			;Save the parsed node
	MOVE	S1,NODTBL		;Point to node table
	MOVE	S2,P1			;Get destination pointer
	$CALL	S%TBLK			;Look for it
	TXNN	S2,TL%EXM		;Is it there?
	 JRST	[MOVE	S1,P1		;Point to node name
		 $CALL	NODADD		;Add it to table
		 JRST	.+1]		;Continue
	HRRZ	S1,0(S1)		;Yes..return node data address
PARNO2:	SKIPN	S2,S1			;Local node?
	MOVE	S2,LOCNOD		;Yes..get local defaults
	HRLI	S2,ND$USR(S2)		;Point to node defaults
	HRRI	S2,DEFBEG		;Point to destination
	BLT	S2,DEFBEG+DEFSIZ-1	;Copy the defaults
	$RET				;Return True if node parsed

NODFDB:	FLD(.CMNOD,CM%FNC)+CM%SDH+CM%PO
SUBTTL	PARSWS	Routine to parse switches

PARSWS:	SETZM	FILATT			;CLEAR FILE FORMAT SWITCHES
	MOVE	S1,SWTFDB		;POINT TO SWITCH FDB
	MOVEM	S1,CMDFDB		;Store in private FDB
	MOVE	S1,SWTFDB+.CMDAT	;Get table address
	MOVEM	S1,CMDFDB+.CMDAT	;Save for parse
	MOVEM	S2,CMDFDB+.CMHLP	;Save help pointer
PARSW1:	MOVEI	S1,CMDFDB		;Point to our FDB
	MOVE	S2,SBK+.CMPTR		;Get pointer to next character
	ILDB	S2,S2			;Get it
	CAIE	S2,"/"			;Beginning of a switch?
	$RETT				;No..just return
PARSW2:	$CALL	RFLDE			;PARSE A FIELD
	 JUMPF	.RETF			;RETURN IF NO PARSE
	CAIE	T2,.CMSWI		;WAS IT A SWITCH?
	$RETT				;NO..RETURN
	HRRZ	S2,0(S2)		;YES..GET PROCESSOR ADDRESS
	PUSHJ	P,0(S2)			;CALL THE PROCESSOR
	JRST	PARSW1			;Back for more switches

SWTFDB:	FLD(.CMSWI,CM%FNC)+CM%HPP+REMFS1	;PARSE SWITCHES
	FILSWS					;FILE SWITCH TABLE
						;HELP SUPPLIED BY CALLER

FILSWS:	SWSSIZ,,SWSSIZ
	SW (ASCII)
	SV (FIXED)
	SW (IMAGE)
	SW (MACY11)
	SV (VARIABLE)
	SWSSIZ==.-FILSWS-1
SUBTTL	Switch processors

.SWACC:	MOVEI	S2,1			;Clear account valid bit
	ANDCAM	S2,REMACT
	TXNN	S1,CM%SWT		;TERMINATED BY A COLON?
	 $RETT				;No..return and prompt for it
	IORM	S2,REMACT		;Yes..whatever we parse is valid
	MOVEI	S1,ACT001		;PARSE ACCOUNT
	PUSH	P,SBK+.CMCNT		;[0063]
	$CALL	PARSE
	 JUMPF	[POP P,S1
		 REPARS	(Invalid account string)]
	POP	P,S1			;[0063]
	SUB	S1,SBK+.CMCNT		;[0063] SIZE OF STRING
	CAILE	S1,^D39			;[0063]TOO LONG?
	JRST	[REPARS (Length of account string exceeds 39 characters)]
	HRROI	S1,REMACT		;POINT TO DESTINATION
	$CALL	STOATM			;STORE THE ATOM
	$RETT				;AND RETURN


.SWPAS:	SETZM	REMPSW			;Clear password value
	TXNN	S1,CM%SWT		;Switch terminator?
	 $RETT				;No..return and prompt for it
	MOVEI	S1,PSW001		;[0064]Yes..point to password function
	PUSH	P,SBK+.CMCNT		;[0063]
	$CALL	PARSE
	 JUMPF	[POP P,S1
		 REPARS (Invalid password)]
	POP	P,S1			;[0063]
	SUB	S1,SBK+.CMCNT		;[0063]LENGTH OF STRING
	CAILE	S1,^D39			;[0063]TOO LONG?
	JRST	[REPARS (Length of password string exceeds 39 characters)]
	HRROI	S1,REMPSW		;Point to password storage
	$CALL	STOATM			;Save the string
	MOVEI	S1,1			;Get valid bit
	IORM	S1,REMPSW		;Yes..set the valid bit
	SKIPE	PASFLG			;[76]PASSWORD UNSECURE?
	$TEXT	(,<%Password found in command or NFT.INIT file which has world read access>) ;[76]
	$RETT				;Return

.SWUSE:	MOVEI	S2,1			;Clear user valid bit
	ANDCAM	S2,REMUSR
	andcam	s2,rempsw		;
	TXNN	S1,CM%SWT		;TERMINATED BY A COLON?
	 $RETT				;No..return and prompt for it
	IORM	S2,REMUSR		;Yes..user is valid
	MOVEI	S1,USR001		;[0064]
	PUSH	P,SBK+.CMCNT		;[0063]
	$CALL	PARSE
	 JUMPF	[POP P,S1
		 REPARS	(Invalid userid)]
	POP	P,S1			;[0063]
	SUB	S1,SBK+.CMCNT		;[0063]
	CAILE	S1,^D39			;[0063]TOO LONG?
	JRST	[REPARS (Length of userid string exceeds 39 characters)]
	HRROI	S1,REMUSR		;POINT TO DESTINATION
	$CALL	STOATM			;STORE THE ATOM
	$RETT
.SWASC:	MOVX	S2,DT$ASC		;ASCII MODE
	STORE	S2,FILATT,DF%DAT	;STORE THE MODE
	TXNE	S1,CM%SWT		;COLON?
	 REPARS	(Invalid switch terminator)
	$RETT


.SWFIX:	MOVX	S2,FB$FIX		;FIXED LENGTH RECORD FORMAT
	STORE	S2,FILATT,DF%RFM	;STORE THE FORMAT
	TXNN	S1,CM%SWT		;TERMINATED WITH A COLON?
	$RETT				;NO..USE THE DEFAULT
	MOVEI	S1,FRLFDB		;PARSE RECORD LENGTH
	$CALL	PARSE
	 JUMPF	[REPARS	(Invalid record length)]
	STORE	S2,FILATT,DF%MRS	;Store maximum record size
	$RETT

.SWIMA:	MOVX	S2,DT$IMA		;IMAGE MODE
	STORE	S2,FILATT,DF%DAT	;Store the mode
	TXNE	S1,CM%SWT		;COLON?
	 REPARS	(Invalid switch terminator)
	$RETT

.SWMAC:	MOVX	S2,FB$MCY		;MACY11 MODE
	STORE	S2,FILATT,DF%RAT	;STORE THE RECORD ATTRIBUTE
	TXNE	S1,CM%SWT		;COLON?
	 REPARS	(Invalid switch terminator)
	$RETT


.SWVAR:	MOVX	S2,FB$VAR		;VARIABLE LENGTH RECORD FORMAT
	STORE	S2,FILATT,DF%RFM	;Store the record format
	TXNN	S1,CM%SWT		;TERMINATED BY A COLON?
	$RETT				;NO..USE DEFAULT
	MOVEI	S1,VRLFDB		;PARSE VARIABLE RECORD LENGTH
	$CALL	PARSE
	 JUMPF	[REPARS	(Invalid record length)]
	STORE	S2,FILATT,DF%MRS	;Store maximum record size
	$RETT

	CONT.	(SWITCH)


ACTFDB:	FLD(.CMCFM,CM%FNC)+CM%SDH+ACT001
	0
	0
	0				;[0064]

ACT001:	FLD(.CMFLD,CM%FNC)+CM%BRK+CM%HPP
	USRBRK				;For .CMUQS (if REL3A)
	TXT(Account designator for remote system)
	0
	USRBRK

USRFDB:	FLD(.CMCFM,CM%FNC)+CM%SDH+USR001
	0
	0
	0

USR001:	FLD(.CMFLD,CM%FNC)+CM%HPP+CM%BRK
	USRBRK				;For .CMUQS (if REL3A)
	TXT(User name or identification for remote system)
	0
	USRBRK

PSWFDB:	FLD(.CMCFM,CM%FNC)+CM%SDH+PSW001
	0
	0
	0

PSW001:	FLD(.CMFLD,CM%FNC)+CM%HPP+CM%BRK
	USRBRK				;For .CMUQS (if REL3A)
	TXT(Password required to access remote system)
	0
	USRBRK

USRBRK:	777777,,777760			;BREAK ON ALL CONTROL
	745504,,001760			;[0060] allow dollar sign
	400000,,000240			;[0060] allow underscore
	400000,,000760

FRLFDB:	FLD(.CMNUM,CM%FNC)+CM%SDH+CM%HPP+CM%DPP
	^D10				;RADIX
	TXT (Record length)
	TXT (512)			;DEFAULT

VRLFDB:	FLD(.CMNUM,CM%FNC)+CM%SDH+CM%HPP+CM%DPP
	^D10				;RADIX
	TXT (Maximum record length)	;HELP
	TXT (512)			;DEFAULT
SUBTTL	OSTYPE Switch processor

.SWOST:	SETZM	ND$OST(P1)		;CLEAR OSTYPE
	TXNN	S1,CM%SWT		;SWITCH TERMINATOR?
	$RETT				;NO..JUST RETURN
	MOVEI	S1,OSTFDB		;POINT TO OSTYPE FUNCTION BLOCK
	$CALL	RFIELD
	MOVE	S2,0(S2)		;GET OSTYPE
	MOVEM	S2,ND$OST(P1)		;SAVE IT
	$RETT

OSTFDB:	FLD(.CMKEY,CM%FNC)+CM%DPP+CM%HPP
	OSTTBL				;POINT TO TYPE TABLE
	TXT(System type)		;HELP TEXT
	TXT(TOPS20)			;DEFAULT TO TOPS20

OSTTBL:	XWD OSTSIZ,OSTSIZ		;ARGUMENTS FOR /OSTYPE
	T (IAS,.OSIAS)			;Operating system type
;	T (OS-8,.OSOS8)
	T (RSTS,.OSRST)
	T (RSX11,.OSRXM)
	T (RT11,.OSRT)
	T (TOPS10,.OSTP10)
	T (TOPS20,.OSTP20)
	T (VMS,.OSVAX)
	OSTSIZ==.-OSTTBL-1
SUBTTL	GETUSR routine to ensure we have a user,account and password

GETUSR:	$SAVE	<P1,SBK+.CMIOJ>		;Preserve an AC and JFNs
	MOVE	S1,LOCNOD
	SKIPG	REMNOD			;Remote node given?
	MOVEM	S1,REMNOD
	MOVEI	P1,1			;Get string valid bit
	AND	P1,REMUSR		;Test all strings for valid bit
	AND	P1,REMACT
	AND	P1,REMPSW
	JUMPN	P1,.RETT		;All strings valid?
GETUS1:	$CALL	HLPUSR			;No..display access info prompt
	MOVE	S1,[.PRIIN,,.PRIOU]	;Must come from TTY
	MOVEM	S1,SBK+.CMIOJ		;Tell comnd
	$CALL	CMDINI			;Init cmd for this level
	 JUMPF	.RETF			;False return on EOF
	MOVEI	P1,1			;Get string valid bit
	TDNE	P1,REMUSR		;Is user specified?
	JRST	GETUS2			;Yes..check account
	PROMPT	(User: )
	MOVEI	S1,USRFDB
	SETZM   ATMBUF			;[0064]
	PUSH	P,SBK+.CMCNT		;[0063]
	$CALL	PARSE
	 JUMPF	[POP P,S1		;[0063]
		REPARS (Invalid userid)]
	POP	P,S1			;[0063]
	SUB	S1,SBK+.CMCNT		;[0063]Length of string
	PUSH	P,S1			;[0063]
	CAIE	T2,.CMCFM		;[0064]CONFIRMED?
	CONFRM
	POP	P,S1			;[0063]
	CAILE	S1,^D39			;[0063]is string too long?
	JRST	[REPARS (Length of userid string exceeds 39 characters)]
	HRROI	S1,REMUSR		;Point to destination
	$CALL	STOATM			;Store the userid
	IORM	P1,REMUSR		;Set valid bit
	ANDCAM	P1,REMPSW		;Clear password valid bit
GETUS2:	TDNE	P1,REMACT		;Is account specified?
	JRST	GETUS3			;Yes..check password
	PROMPT	(Account: )		;YES..GET ACCOUNT STRING
	MOVEI	S1,ACTFDB
	SETZM	ATMBUF			;Clear account string
	PUSH	P,SBK+.CMCNT		;[0063]
	$CALL	PARSE
	 JUMPF	[POP P,S1		;[0063]
		REPARS (Invalid account string)]
	POP	P,S1			;[0063]
	SUB	S1,SBK+.CMCNT		;[0063]Length of string
	PUSH	P,S1			;[0063]
	CAIE	T2,.CMCFM		;Confirmed?
	CONFRM				;No..get confirmation
	POP	P,S1			;[0063]
	CAILE	S1,^D39			;[0063]Is string too long?
	JRST	[REPARS (Length of account string exceeds 39 characters)]
	HRROI	S1,REMACT		;Point to destination
	$CALL	STOATM			;Store the account
	IORM	P1,REMACT		;Set the valid bit
GETUS3:	TDNE	P1,REMPSW		;Is password specified?
	JRST	GETUS4			;Yes..exit
	$CALL	TSTCOL
	PROMPT	(Password: )
	$CALL	ECHOOF
	MOVEI	S1,PSWFDB
	SETZM	ATMBUF			;[0064]
	PUSH	P,SBK+.CMCNT		;[0063]
	$CALL	PARSE
	 JUMPF	[POP P,S1		;[0063]
		$CALL	ECHOON		;BAD PARSE..RESTORE ECHOS
		 REPARS (Invalid password)]
	POP	P,S1			;[0063]
	SUB	S1,SBK+.CMCNT		;[0063]Length of string
	PUSH	P,S1			;[0063]
	CAIE	T2,.CMCFM		;[0064]CONFIRMED?
	CONFRM
	$CALL	ECHOON
	$CALL	TSTCOL
	POP	P,S1			;[0063]
	CAILE	S1,^D39			;[0063]Is string too long?
	JRST	[REPARS (Length of password string exceeds 39 characters)]
	HRROI	S1,REMPSW		;Point to destination
	$CALL	STOATM			;Copy the string
	IORM	P1,REMPSW		;Set the valid bit
GETUS4:	MOVE	S1,REMNOD		;Point to remote node data
	HRLI	S2,REMUSR		;Copy defaults obtained from prompt
	HRRI	S2,ND$USR(S1)
	BLT	S2,DEFSIZ-1+ND$USR(S1)
	$RETT
SUBTTL	HLPUSR	Routine to display access information for a node

HLPUSR:	$TEXT	(T%TTY,<Access information for node ^T/@REMNOD/::^A>)
	MOVEI	S1,1B35			;Get string valid bit
	TDNE	S1,REMUSR		;Display only valid strings
	$TEXT	(T%TTY,</USER:^T/REMUSR/^A>)
	TDNE	S1,REMACT
	$TEXT	(T%TTY,</ACCOUNT:^T/REMACT/^A>)
	$TEXT	(T%TTY,<>)		;Send a CRLF
	$RETT
SUBTTL	TAKE command

.TAKE:	NOISE	(COMMANDS FROM)
	SETZ	T4,			;SET DEFAULT TO NOECHO
	$CALL CLRGJF			;GO CLEAR GTJFN BLOCK
	MOVX	S1,GJ%OLD		;GET EXISTING FILE FLAG
	MOVEM	S1,GJFBLK+.GJGEN	;STORE GTJFN FLAGS
	HRROI	S1,[ASCIZ/CMD/]		;GET DEFAULT FILE TYPE FIELD
	MOVEM	S1,GJFBLK+.GJEXT	;STORE DEFAULT EXTENSION
	MOVEI	S1,TAK010		;PARSE FILE SPEC
	$CALL	RFIELD
	CAIN	T2,.CMFIL		;PARSE A FILE SPEC?
	JRST	TAKE10			;Yes..Save input JFN
	JRST	CMDEOF			;NO..TERMINATE THIS COMMAND FILE

; HERE ON A GOOD INPUT FILE SPEC

TAKE10:	MOVEM	S2,CMDJFN		;SAVE INPUT JFN FOR COMMANDS
	NOISE	(LOGGING OUTPUT ON)
	$CALL CLRGJF			;GO CLEAR GTJFN BLOCK USED BY COMND JSYS
	MOVX	S1,GJ%FOU		;GET FLAG SAYING FILEIS FOR OUTPUT USE
	MOVEM	S1,GJFBLK+.GJGEN	;SAVE GTJFN FLAGS
	SETZM SRCFIL			;INITIALIZE FILENAME BUFFER
	HRROI	S1,SRCFIL		;GET POINTER TO WHERE FILENAME IS TO GO
	MOVE	S2,CMDJFN		;GET INPUT JFN
	MOVX	T1,<FLD(.JSAOF,JS%NAM)> ;GET FLAG BITS SAYING OUTPUT NAME ONLY
	JFNS				;GET FILE NAME OF INPUT FILE
	HRROI	S1,SRCFIL		;GET A POINTER TO FILE NAME FOR INPUT
	MOVEM	S1,GJFBLK+.GJNAM	;STORE DEFAULT NAME OF OUTPUT FILE
	HRROI	S1,[ASCIZ/LOG/]		;GET DEFAULT FILE TYPE OF OUTPUT FILE
	MOVEM	S1,GJFBLK+.GJEXT	;STORE DEFAULT EXTENSION
	SETZM	LOGJFN			;CLEAR LOG JFN
	MOVEI	S1,TAK020		;PARSE FILE SPEC OR CONFIRM
	$CALL	RFIELD
	CAIN	T2,.CMCFM		;PARSE CONFIRM?
	JRST	TAKE25			;YES..FINISH UP
	CAIN	T2,.CMSWI		;PARSE A SWITCH
	JRST	TAKE22			;YES..GO PROCESS IT
	MOVEM	S2,LOGJFN		;SAVE LOGGIN FILE JFN

TAKE20:	MOVEI	S1,TAK040		;PARSE CONFIRM OR SWITCHES
	$CALL	RFIELD
	CAIN	T2,.CMCFM		;PARSE CONFIRM?
	JRST	TAKE25			;YES..FINISH UP

TAKE22:	HRRZ	S2,0(S2)		;NO..MUST BE SWITCH
	PUSHJ	P,0(S2)			;CALL THE PROCESSOR
	JRST	TAKE20			;GET CONFIRMATION

	CONT.	(Take command)

; OPEN INPUT AND OUTPUT FILES

TAKINI:	SETOM	INIFLG			;[0071]Now taking NFT.INIT
TAKE25:	MOVE	S1,CMDJFN		;GET INPUT JFN
	MOVE	S2,[7B5+OF%RD]		;7 BIT BYTES, READ ACCESS
	OPENF				;OPEN INPUT FILE
	 JRST [SKIPN INIFLG		;[0071]
		REPARS	(Cannot OPEN command file)
		$TEXT (,<?Cannot OPEN PS:NFT.INIT>)
		$TEXT (,)
		$RETF]			;RETURN FAIL
	SKIPE	S1,LOGJFN		;GET OUTPUT JFN
	CAIN	S1,.PRIOU		;STILL PRIMARY OUTPUT JFN ?
	JRST TAKE30			;NO OUTPUT JFN, GO ON

	DVCHR				;Get log device characteristics
	LOAD	S1,S2,DV%TYP		;Extract device type
	CAIE	S1,.DVDSK		;Device DSK:?
	SETZ	T4,			;No..clear display flag
	MOVE	S1,LOGJFN		;Get logfile JFN
	MOVE	S2,[7B5+OF%APP]		;7 BIT BYTES, WRITE ACCESS
	OPENF				;OPEN OUTPUT FILE
	 REPARS	(Cannot OPEN logging file)

; NOW SAVE NEW JFN'S AND RETURN TO PARSER

TAKE30:	$SAVE	<SBK+.CMIOJ,LOGJFN,DSPFLG,PASFLG> ;[76]STACK CURRENT STUFF
	SETZB	S1,T1			;[76]
	MOVE	S2,CMDJFN		;[76]JFN OF COMMAND FILE
	RCDIR				;[76]DIR NUM THAT CMD FILE IS IN
	 ERJMP	PASOK			;[76]IGNORE ERRORS
	MOVEI	S1,^D9			;[76]
	MOVEM	S1,TMPFIL+.CDLEN	;[76]
	SETZM	TMPFIL+.CDPSW		;[76]
	MOVE	S1,T1			;[76]
	MOVEI	S2,TMPFIL		;[76]
	SETZ	T1,			;[76]
	GTDIR				;[76]PROT OF THAT DIR
	 ERJMP	PASOK			;[76]IGNORE ERRORS
	MOVE	S1,TMPFIL+.CDDPT	;[76]
	TRNN	S1,40			;[76]WORLD ACCESS TO DIR?
	JRST	PASOK			;[76]NO, NO PROBLEM
	MOVE	S1,CMDJFN		;[76]
	MOVE	S2,[1,,.FBPRT]		;[76]
	MOVEI	T1,T2			;[76]
	GTFDB				;[76]
	 ERJMP	PASOK			;[76]IGNORE ERRORS
	SETOM	PASFLG			;[76]ASSUME WORLD HAS READ ACCESS
					;[76]TO DIR AND FILE
	TRNN	T2,40			;[76]DOES WORLD HAVE READ ACCESS?
PASOK:	SETZM	PASFLG			;[76]NO
	MOVEM	T4,DSPFLG		;SAVE ECHO/NOECHO VALUE
	HRRZ	S1,SBK+.CMIOJ		;GET CURRENT OUTPUT JFN
	SKIPN	LOGJFN			;GET OUTPUT JFN IF ANY
	MOVEM	S1,LOGJFN		;SAVE CURRENT JFN FOR OUTPUT
	HRR	S1,LOGJFN		;GET OUTPUT JFN
	HRL	S1,CMDJFN		;GET INPUT JFN
	EXCH	S1,SBK+.CMIOJ		;SAVE NEW JFN'S AND GET OLD
	HRRZM	S1,LOGJFN		;SAVE OLD OUTPUT JFN
	AOS	TAKFLG			;BUMP TAKE LEVEL
	$CALL	CMDINI			;STACK THIS LEVEL
	 JUMPF	TAKE40			;CLOSE FILES AND RETURN ON EOF
	JRST	PARSER			;BACK FOR SOME MORE COMMANDS

TAKE40:	HLRZ	S1,SBK+.CMIOJ		;GET INPUT JFN
	CLOSF
	 JFCL
	HRRZ	S1,SBK+.CMIOJ		;GET OUTPUT JFN
	CAME	S1,LOGJFN		;SAME AS BEFORE?
	CLOSF				;NO..CLOSE THE FILE
	 JFCL				;YES..DON'T CLOSE IT
	SOS	TAKFLG			;DECR TAKE LEVEL
	$RETT

	CONT.	(Take command)

TAK010:	FLD(.CMFIL,CM%FNC)+TAK015	;CMD FILE FDB
TAK015:	FLD(.CMCFM,CM%FNC)+CM%HPP+CM%SDH
	0
	TXT(Carriage return to terminate current command file)

TAK020:	FLD(.CMCFM,CM%FNC)+TAK030	;CONFIRM, FILE OR SWITCH
TAK030:	FLD(.CMFIL,CM%FNC)+TAK050
TAK040:	FLD(.CMCFM,CM%FNC)+TAK050	;CONFIRM OR SWITCHES
TAK050:	FLD(.CMSWI,CM%FNC)
	TAKSWS


TAKSWS:	TAKSIZ,,TAKSIZ
	SW (DISPLAY)
	SW (NODISPLAY)
	TAKSIZ==.-TAKSWS-1

.SWDIS:	SETOM	T4			;SET DISPLAY FLAG
	$RETT

.SWNOD:	SETZM	T4			;CLEAR DISPLAY FLAG
	$RETT
SUBTTL	OUTNAM	Routine to generate output file spec

;ACCEPTS	S1/ Pointer to destination string
;		S2/ Requested field flags (GJ%DIR etc)

;RETURNS TRUE	Output file name stored
;	 FALSE	Illegal wild card syntax

OUTNAM:	$SAVE	<P1>			;Preserve an ac
	STKVAR <DSTPTR,DSTFLD,<SRCWLD,8>,<SRCFLD,8>,<DSTWLD,8>>
	MOVE	P1,S1			;Copy destination pointer
	MOVEI	S1,[EXP P1,0]		;Make sure it's a valid pointer
	$CALL	CHKPTR
	MOVEM	P1,DSTPTR		;Save destination pointer
	TXNN	S2,GJ%DIR+GJ%EXT+GJ%VER	;Any flags set?
	OR	S2,[GJ%NAM]		;[0056]Request name
	OR	S2,[GJ%EXT]		;[0056]Always request extension
	MOVEM	S2,DSTFLD		;Save requested fields
	SKIPE	S1,SRCJFN		;Must have source JFN
	SKIPN	S2,DSTJFN		;And destination JFN
	 $RETF				;Else fail
	MOVE	S1,DSTJFN		;Get destination JFN
	TDZ	S1,DSTFLD		;Clear common flags
	TXNE	S1,GJ%DIR+GJ%NAM+GJ%EXT+GJ%VER
	 $RETF				;Too many wild destination flags
	MOVE	S1,SRCJFN		;Get wild source flags
	TDZ	S1,DSTFLD		;Clear common flags
	TXNE	S1,GJ%DIR+GJ%NAM+GJ%EXT+GJ%VER
	 $RETF				;Too many wild source fields
	MOVSI	P1,-NFFLD		;Get count of requested fields
OUTN1:	HLLZ	T2,FSTRT(P1)		;Get bit for field
	TDNN	T2,DSTFLD		;This field requested?
	 JRST	OUTN4			;No..on to next field
	HLRZ	S2,PNCTAB(P1)		;Yes..get prefix punctuation
	SKIPE	S2			;Don't store null
	IDPB	S2,DSTPTR		;Store it
	TDNN	T2,DSTJFN		;Is this field wild?
	 JRST	OUTN2			;No..just store dest field
	HRROI	S1,SRCWLD		;Point to wild source field
	MOVE	S2,SRCJFN		;Get wild source JFN
	MOVE	T1,FFLDT(P1)		;Get bits for this field
	JFNS				;Store the field
	HRROI	S1,SRCFLD		;Point to source field
	SKIPN	S2,REMJFN		;Get remote JFN (via Name msg)
	HRRZ	S2,SRCJFN		;Else use non-wild source JFN
	JFNS
	HRROI	S1,DSTWLD		;Point to wild dest field
	MOVE	S2,DSTJFN
	JFNS
	CONT.	(OUTNAM)
	HRROI	S1,SRCWLD		;Setup for wild call
	HRROI	S2,SRCFLD
	HRROI	T1,DSTWLD
	MOVE	T2,DSTPTR
	$CALL	WILD
	 JUMPF	.RETF			;Return if false
	MOVEM	T2,DSTPTR		;Save updated pointer
	JRST	OUTN3			;Store suffix punctuation

OUTN2:	MOVE	S1,DSTPTR		;Get output pointer
	MOVE	S2,DSTJFN
	HLLZ	T1,FFLDT(P1)		;Get bits for this field
	JFNS
	MOVEM	S1,DSTPTR		;Save updated pointer
OUTN3:	LDB	S1,DSTPTR		;[0056]GET THE LAST SAVED BYTE
	CAIE	S1,"<"			;[0056]WAS IT BEGINNING OF DIRECTORY?
	JRST	OUTN25			;[0056]NO, GO ON
	HRREI	S1,-1			;[0056]-1
	ADJBP	S1,DSTPTR		;[0056]MOVE BACK ONE BYTE
	MOVEM	S1,DSTPTR		;[0056]RESTORE THE NEW POINTER
	JRST	OUTN4			;[0056]
OUTN25:	HRRZ	S2,PNCTAB(P1)		;Get suffix punctuation
	SKIPE	S2			;Don't store null
	IDPB	S2,DSTPTR		;Store it
OUTN4:	AOBJN	P1,OUTN1		;On to next field
	MOVE	T1,DSTPTR		;Return updated pointer
	$RETT

PNCTAB:	BYTE(18) 0,":"			;Device prefix,suffix
	BYTE(18) "<",">"		;Directory prefix suffix
	BYTE(18) 0,0			;Name prefix,suffix
	BYTE(18) "."			;Extension prefix
	BYTE(18) "."			;Generation prefix


SUBTTL	NAMEXT	Routine to expand full file name

;Accepts	S1/	GTJFN flags
;		S2/	Pointer to name string storage

;Returns	Expanded local file name stored per S2

NAMEXT:	MOVE	T4,S2			;Save pointer to destination
	GTJFN				;Get full JFN for name
	 ERJMP	.RETF
	MOVE	S2,S1			;JFN to S2
	MOVE	S1,T4			;Destination to S1
	MOVX	T1,FFSPEC		;Get full expansion flags
	JFNS				;Expand the name
	MOVE	S1,S2			;JFN to S1
	RLJFN				;Release it
	 ERJMP	.RETF
	$RETT
SUBTTL	OUTFLG	Routine to set flags per what user typed

;ACCEPTS	S1/ Pointer to file string

;RETURNS	S1/ Updated pointer
;		S2/ Flags set per user input


OUTFLG:	MOVE	T2,S1			;Copy original pointer
	MOVX	S2,GJ%NAM+GJ%EXT	;Require name and extension
	ILDB	T1,T2			;Get character
	JUMPE	T1,.RETT		;Return on null
	TXZA	S2,GJ%EXT		;Clear extention flag
OUTFL1:	ILDB	T1,T2			;Get next byte
	JUMPE	T1,.RETT		;Return on null
	CAIN	T1,":"			;Was it a device terminator?
	JRST	[TXO	S2,GJ%DEV		;Yes..set the flag
		 JRST	OUTFL1]			;Get next character
	CAIE	T1,"<"			;Was it a directory
	CAIN	T1,"["
	 JRST	OUTFL3			;Yes..get the field
	CAIE	T1,"."			;Was it extension or generation?
	JRST	OUTFL1			;No..get next character
	TXO	S2,GJ%EXT		;Set extension flag
OUTFL2:	ILDB	T1,T2			;Get next byte
	JUMPE	T1,.RETT		;Return
	CAIN	T1,"."			;Generation?
	TXO	S2,GJ%VER		;Yes..set the flag
	JRST	OUTFL2			;Back for next character

OUTFL3:	ILDB	T1,T2			;Get next character of directory
	JUMPE	T1,.RETF		;Fail on null
	CAIE	T1,">"			;Terminator?
	CAIN	T1,"]"
	TXOA	S2,GJ%DIR		;Yes..Say they typed directory
	JRST	OUTFL3			;No..finish directory
	JRST	OUTFL1			;Back for rest of name
SUBTTL	Routine to build destination string from wild information

;WILD	Build destination string

;CALL		S1/ Wild source string pointer
;		S2/ Source string pointer
;		T1/ Wild destination string pointer
;		T2/ Destination string pointer

WILD::	$SAVE	<P1,P2,P3,P4>		;PRESERVE SOME ACS
	TRVAR	<DSTSIZ,DSTTRM,<SRCTRM,8>>	;TEMP VARIABLES
	DMOVE	P1,S1			;SAVE SOURCE STUFF
	DMOVE	P3,T1			;SAVE DEST STUFF
	MOVEI	S1,[EXP P1,P2,P3,P4,0]	;Get list of pointers
	$CALL	CHKPTR			;Make real pointers
	MOVE	S1,P1			;Get wild source pointer
	MOVE	S2,P3			;Get wild dest pointer
	$CALL	CHKWLD			;Check construction
	JUMPF	.RETF			;Fail now if bad construction
	JUMPN	T2,WILD1		;Was dst-msk = "*"
	MOVE	S1,P2			;Yes..point to src-str
	MOVE	S2,P4			;     point to dst-str
	$CALL	CPYSTR			;Copy the field
	MOVE	T2,S2			;Return updated pointers
	MOVE	S2,S1
	MOVE	S1,P1
	MOVE	T1,P3
	$RETT				;Return

WILD1:	MOVE	S1,P3			;Point to dst-msk
	MOVE	S2,P4			;Point to dst-str
	$CALL	CPYSTR			;Copy the field
	MOVE	P4,S2			;Save the dst-str pointer
	$CALL	MSKSIZ			;Get mask size
	MOVE	P3,S1			;Save the dst-msk pointer
	MOVEM	S2,DSTSIZ		;Save it
	MOVEM	T1,DSTTRM		;Save terminating character
WILD2:	ILDB	T1,P1			;Get src-msk byte
	ILDB	T2,P2			;Get src-str byte
	CAMN	T1,T2			;Match?
	 JUMPN	T1,WILD2		;Yes..find first non-match
	MOVE	S1,P2			;Get src-str pointer
	$CALL	DPB			;Decrement it
	MOVE	P2,S1			;Put it back
	MOVE	S1,P1			;Get src-mask pointer
	$CALL	DPB			;Decrement the pointer
	$CALL	MSKSIZ			;Get src-msk size
	CAMLE	S2,DSTSIZ		;Fit into dst-msk?
	 $RETF				;No..give up
	MOVE	P1,S1			;Save src-msk pointer
	MOVE	S1,P2			;Get src-str pointer
	SETZ	T2,			;Clear count
	CONT.	(WILD)

WILD3:	ILDB	S2,S1			;Get byte from src-str
	CAMN	S2,T1			;Terminator?
	 JRST	WILD4			;Yes..copy src-msk terminator
	IDPB	S2,P4			;No..put it in dst-str
	AOJA	T2,WILD3		;Find terminator
WILD4:	$CALL	DPB			;Decrement src-str pointer
	MOVE	P2,S1			;Put it back
	MOVE	S1,P1			;Get src-msk pointer
	MOVE	S2,[POINT 7,SRCTRM]	;Yes..copy the terminator string
	$CALL	CPYSTR			;Copy termination string
	MOVE	P1,S1			;Save src-msk pointer
WILD5:	MOVE	S1,[POINT 7,SRCTRM]	;Point to src-msk terminator
	MOVE	S2,P2			;Point to src-str
	STCMP				;Look for terminator string
	SKIPE	S1			;Exact match
	TXNE	S1,SC%SUB		; or subset?
	JRST	WILD6			;Yes..we found it
	ILDB	T1,P2			;No..copy src-str byte
	JUMPE	T1,WILD7		;Exit on null src-str byte
	IDPB	T1,P4			;    to dst-str
	AOJA	T2,WILD5		;Try again for a match
WILD6:	MOVE	P2,S2			;Save src-str pointer
	JRST	WILD8			;[0104]Skip unnecessary decrementation
WILD7:	MOVE	S1,P2			;Decrement source string pointer
	$CALL	DPB
	MOVE	P2,S1			;Put it back
WILD8:	HRRZ	S1,DSTSIZ		;[0104]Get min dst-msk size
	HLRZ	S2,DSTSIZ		;Get max dst-msk size
	CAML	T2,S1			;Check range
	CAMLE	T2,S2
	 $RETF				;Bad..fail
	MOVE	T2,P4			;Get pointer to dest
	SETZ	T1,			;Get a null
	IDPB	T1,T2			;Ensure a null
	SKIPE	DSTTRM			;At end of destination?
	JRST	WILD1			;No..process next field
	DMOVE	S1,P1			;Yes..Return updated pointers
	DMOVE	T1,P3
	$RETT
SUBTTL	CHKWLD	Routine to validate wild construction

;CALL		S1/ Source wild pointer
;		S2/ Destination wild pointer

;RETURN	TRUE	Valid construction
;	FALSE	Invalid construction

CHKWLD:	$SAVE	<P1,P2,P3,P4>
	DMOVE	P1,S1			;Save the pointers
	SETZ	T2,
CHKW1:	ILDB	T1,P2			;Get destination byte
	JUMPE	T1,CHKW2		;Onward on null
	CAIE	T1,"*"
	CAIN	T1,"%"
	 JRST	CHKW2			;Onward on wild
	AOJA	T2,CHKW1		;Look for wild card or null

CHKW2:	MOVE	S1,P2			;Get destination pointer
	$CALL	DPB			;Decrement it
	$CALL	MSKSIZ			;Get mask size
	MOVE	P2,S1			;Save updated pointer
	DMOVE	P3,S2			;Save size and terminator
	JUMPN	T2,CHKW3		;Onward if any characters seen
	CAMN	S2,[377,,0]		;Was wild card "*"
	JUMPE	T1,.RETT		; and terminator null?

CHKW3:	ILDB	T1,P1			;Get source byte
	JUMPE	T1,CHKW4		;Onward on null
	CAIE	T1,"*"
	CAIN	T1,"%"
	 JRST	CHKW4			;Onward on wild card
	AOJA	T2,CHKW3

CHKW4:	MOVE	S1,P1			;Get source pointer
	$CALL	DPB			;Decrement it
	$CALL	MSKSIZ			;Get the size
	CAMLE	S2,P3			;Will source always fit dest?
	 $RETF				;No..fail now
	MOVE	P1,S1			;Save updated pointer

	SKIPE	T1			;Src term null
	 JRST	[JUMPN P4,CHKW1		;Look for the end
		 $RETF]			;Not the same number of wilds
	SKIPE	P4			;Dest term null
	 $RETF				;Not the same number of wilds
	$RETT
SUBTTL	FILDEF	Routine to setup GTJFN file defaults

;CALL		S1/ POINTER TO SOURCE STRING
;		S2/ FLAGS TO STORE IN GTJFN BLOCK

;RETURNS	S1/ UPDATED POINTER
;		S2/ FLAGS INDICATING WHAT WAS PARSED

FILDEF:	$SAVE	<P1,P2>			;PRESERVE SOME AC'S
	TLC	S1,-1			;FIX -1 TYPE POINTERS
	TLCN	S1,-1
	 HRLI	S1,(POINT 7)
	DMOVE	P1,S1			;PRESERVE CALLING ARGS
	$CALL	CLRGJF			;CLEAR GTJFN BLOCK
	EXCH	P2,GJFBLK+.GJGEN	;STORE CALLING FLAGS
	MOVE	S1,P1			;GET CALLING POINTER
	HRROI	S2,DEFDEV		;POINT TO DEVICE STORAGE
	MOVEI	T1,DEVBRK		;POINT TO BREAK SET
	$CALL	CPYFLD			;COPY THE DEVICE
	CAIE	T1,":"			;PROPER TERMIEATION?
	JRST	FILDE1			;NO..TRY DIRECTORY
	TXO	P2,GJ%DEV		;YES..SET DEVICE FLAG
	HRROI	S2,DEFDEV		;POINT TO STRING
	MOVEM	S2,GJFBLK+.GJDEV	;STORE FOR GTJFN
	SKIPA	P1,S1			;SAVE UPDATED POINTER
FILDE1:	MOVE	S1,P1			;GET CALLING POINTER
	ILDB	S2,S1			;GET FIRST BYTE
	SETZ	T1,			;CLEAR BREAK ADDRESS
	CAIE	S2,"<"			;LOOK LIKE DIRECTORY?
	CAIN	S2,"["			;OR UIC?
	MOVEI	T1,DIRBRK		;YES..POINT TO DIR BREAK SET
	JUMPE	T1,FILDE2		;NO..ON TO CHECK FILENAME
	HRROI	S2,DEFDIR		;POINT TO DIRECTORY STORAGE
	$CALL	CPYFLD			;YES..PARSE IT
	CAIE	T1,">"			;UIC OR DIRECTORY TERMINATOR?
	CAIN	T1,"]"
	SKIPA				;YES..SAY WE PARSED DIRECTORY
	 $RETF				;WE TRIED, BUT LOST
	TXO	P2,GJ%DIR		;SET DIRECTORY FLAG
	HRROI	S2,DEFDIR		;POINT TO DIRECTORY STORAGE
	MOVEM	S2,GJFBLK+.GJDIR	;SAVE FOR GTJFN
	SKIPA	P1,S1			;SAVE UPDATED POINTER
FILDE2:	MOVE	S1,P1			;GET UPDATED POINTER
	HRROI	S2,DEFNAM		;POINT TO DEFAULT NAME STORAGE
	MOVEI	T1,NAMBRK		;POINT TO NAME BREAK SET
	$CALL	CPYFLD			;COPY THE FIELD
	SKIPN	DEFNAM			;ANYTHING STORED?
	JRST	FILDE3			;NO..CHECK EXTENTION
	TXO	P2,GJ%NAM		;SET NAME FLAG
	HRROI	S2,DEFNAM		;POINT TO STORAGE
	MOVEM	S2,GJFBLK+.GJNAM	;SAVE FOR GTJFN

	CONT.	(FILDEF routine)
FILDE3:	CAIE	T1,"."			;EXTENTION PREFIX?
	JRST	FILDE4			;NO..CHECK GENERATION
	HRROI	S2,DEFEXT		;POINT TO DEFAULT EXT STORAGE
	MOVEI	T1,NAMBRK		;SAME AS NAME
	$CALL	CPYFLD			;STORE IT
	TXO	P2,GJ%EXT		;SAY WE PARSED EXTENTION
	HRROI	S2,DEFEXT		;POINT TO IT
	MOVEM	S2,GJFBLK+.GJEXT	;SAVE FOR GTJFN
FILDE4:	CAIE	T1,"."			;VERSION PREFIX?
	CAIN	T1,";"			;(FOR VAX)
	SKIPA				;YES..
	JRST	FILDE5			;NO..CHECK PROPER TERMINATION
	HRROI	S2,DEFVER		;POINT TO DEFAULT VER STORAGE
	MOVEI	T1,NUMBRK		;POINT TO NUMBER BREAK SET
	$CALL	CPYFLD			;COPY THE FIELD
	SKIPN	DEFVER			;ANYTHING PARSED?
	JRST	FILDE5			;NO..CHECK TERMINATION
	TXO	P2,GJ%VER		;SAY WE PARSED IT
FILDE5:	MOVE S2,P2			;RETURN PARSED FLAGS
	CAIE	T1,0			;NULL TERMINATOR
	CAIN	T1,";"			;OR ATTRIBUTES?
	$RETT				;YES..RETURN SUCCESS
	$RETF				;NO..FAIL

DEVBRK:	777777,,777760		;BREAK ON ALL CONTROL
	757754,,001760		;[0074]ALLOW 0-9 $-
	400000,,000740		;[0074]ALLOW A-Z _
	400000,,000760		;ALLOW LC A-Z

DIRBRK:	777777,,777760		;BREAK ON ALL CONTROL
	747504,,001760		;ALLOW $%*,-. 0-9
	400000,,000740		;ALLOW A-Z _
	400000,,000760		;ALLOW LC A-Z

NAMBRK:	777777,,777760		;BREAK ON ALL CONTROL
	747554,,001760		;ALLOW $%*- 0-9
	400000,,000740		;ALLOW A-Z _
	400000,,000760		;ALLOW LC A-Z

NUMBRK:	777777,,777760		;BREAK ON ALL CONTROL
	777774,,001760		;ALLOW 0-9
	0
	0
SUBTTL	CPYFLD	ROUTINE TO COPY A STRING UNTIL BREAK CHARACTER

;CALL		S1/ SOURCE POINTER
;		S2/ DESTINATION POINTER
;		T1/ ADDRESS OF BREAK TABLE

;RETURNS	S1/ UPDATED POINTER
;		S2/ UPDATED POINTER
;		T1/ BREAK CHARACTER

CPYFLD:	TLC	S1,-1			;FIX -1 TYPE POINTERS
	TLCN	S1,-1
	 HRLI	S1,(POINT 7)
	TLC	S2,-1
	TLCN	S2,-1
	 HRLI	S2,(POINT 7)
	HRR	T4,T1			;GET ADDRESS OF BREAK SET
	HRLI	T4,T2			;MAKE IT INDEXED BY T2
CPYFL1:	ILDB	T1,S1			;GET A SOURCE BYTE
	MOVE	T2,T1			;GET A COPY OF IT
	IDIVI	T2,40			;GET BREAK WORD,,BIT
	MOVE	T3,BITS(T3)		;GET PROPER BIT MASK
	TDNE	T3,@T4			;BREAK CHARACTER?
	JRST	CPYFL2			;YES..RETURN NOW
	IDPB	T1,S2			;NO..STORE THE CHARACTER
	JRST	CPYFL1			;BACK FOR NEXT CHARACTER
CPYFL2:	MOVE	T2,S2			;COPY DEST POINTER
	SETZ	T3,			;GET A NULL
	IDPB	T3,T2			;TERMINATE WITH A NULL
	$RETT				;RETURN TO CALLER

;BIT TABLE FOR CPYFLD BREAK CHARACTER CHECKING

	XX==0
BITS:	LSTOF.
	REPEAT ^D36,<
	EXP 1B<XX>
	XX==XX+1>
	LSTON.
;CPYSTR	Routine to copy a string until mask character

;CALL		S1/ Source pointer
;		S2/ Destination pointer

;RETURN		S1/ Updated pointer
;		S2/ Updated pointer
;		T1/ String terminator character

CPYSTR:	ILDB	T1,S1			;GET THE CHARACTER
	JUMPE	T1,CPYS1		;TERMINATE ON NULL
	CAIE	T1,"*"			;MASK CHARACTER?
	CAIN	T1,"%"
	 JRST	CPYS1			;YES..RETURN CORRECT POINTER
	IDPB	T1,S2			;NO..STORE CHARACTER
	JRST	CPYSTR			;LOOP UNTIL MASK FOUND

CPYS1:	$SAVE	<T1,T2>			;Save terminator and T2
	$CALL	DPB			;BACK UP SOURCE POINTER
	MOVE	T2,S2			;GET DESTINATION POINTER
	SETZ	T1,			;GET A NULL
	IDPB	T1,T2			;TERMINATE DEST STRING
	JRST	.RETT			;RETURN TO CALLER


;MSKSIZ	Return the mask limits

;CALL		S1/ Pointer to mask

;RETURN		S1/ Updated pointer
;		S2/ max length,,min length
;		T1/ Mask terminator character

MSKSIZ:	SETZ	S2,			;CLEAR THE COUNT
MSKS1:	ILDB	T1,S1			;GET A BYTE FROM STRING
	JUMPE	T1,MSKS2			;EXIT IF NULL FOUND
	CAIN	T1,"*"			;IS IT A WILD MASK CHARACTER?
	HRLI	S2,377			;YES..MAKE SIZE MAXIMUM
	CAIN	T1,"%"			;IS IT CHARACTER MASK?
	AOJA	S2,MSKS1		;YES..ADJ MIN LENGTH
	CAIN	T1,"*"			;WAS IT A WILD MASK CHARACTER?
	JRST	MSKS1			;YES..GET NEXT CHARACTER
MSKS2:	TLNN	S2,377			;WAS "*" SEEN?
	HRL	S2,S2			;NO.. MAX==MIN
DPB:	SOS	S1			;DECREMENT BYTE POINTER
	IBP	S1
	IBP	S1
	IBP	S1
	IBP	S1
	JRST	.RETT			;RETURN TO CALLER
SUBTTL	CHKPTR	Routine to fix -1 type pointers

;ACCEPTS	S1/ Address of list of pointer address

;RETURNS TRUE	Pointers are valid pointers

CHKPTR:	$SAVE <S2>			;[0055]
	SKIPN	S2,(S1)			;Get pointer address
	$RETT				;Return on 0 address
	MOVE	T1,@S2			;Get the pointer
	TLC	T1,-1			;Is LH = 0
	TLCN	T1,-1			;  or -1 ?
	 HRLI	T1,(POINT 7,0)		;Yes..make full word pointer
	HRRI	T1,@T1			;Remove indexing and indirect
	TLZ	T1,37			;Clear the bits
	MOVEM	T1,@S2			;Store the pointer
	AOJA	S1,CHKPTR		;Do next pointer
SUBTTL	DAPOPN	Routine to Open logical link

DAPIOB:	$BUILD	(.DOSIZ)		;Dap link open block
	  $SET	(.DOFLG,DO%LNK,DAPLNK)	;Request first link
	  $SET	(.DOFLG,DO%PSI,1)	;Use PSI
	  $SET	(.DOFLG,DO%WCN,1)	;Wait for connection
	  $SET	(.DOPSI,DO%CDN,.ICCDN)	;Connect/Disconnect channel
	  $SET	(.DOPSI,DO%DAV,.ICDAV)	;Data available
	  $SET	(.DOPSI,DO%INA,.ICIMA)	;Interrupt message
	  $SET	(.DOOBJ,,<POINT 7,OBJNAM>)	;Requested object
	  $SET	(.DOUSR,,<POINT 7,REMUSR>)	;User string
	  $SET	(.DOPSW,,<POINT 7,REMPSW>)	;Password string
	  $SET	(.DOACT,,<POINT 7,REMACT>)	;Account string
	$EOB

DAPOPN:	MOVEI	S1,DAPLNK		;Get proper index
	$CALL	D$STAT			;Get the status
	JUMPF	DAPO20			;Go open it
	$RETT				;All is well

DAPO10:	MOVEI	S1,DAPLNK		;Get link index
	MOVEI	S2,[EXP .DCX42]		;Confirm DI request
	$CALL	D$CLOS

DAPO20:	$CALL	GETUSR			;Get missing info
	MOVE	S1,[DAPIOB,,DAPOB]	;Move initial parameters
	BLT	S1,DAPOB+.DOSIZ-1	; to Dap open block
	HRRO	S1,REMNOD		;Get pointer to remote node
	MOVEM	S1,DAPOB+.DONOD		;Store in open block
	MOVEI	S1,.DOSIZ		;Get size of open block
	MOVEI	S2,DAPOB
	$CALL	D$OPEN			;Open the link
	JUMPF	DAPERR			;Display failure
	MOVE	S1,REMNOD		;Point to node data
	MOVX	S2,.NDSON		;Indicate node is accessible
	MOVEM	S2,ND$STA(S1)
	$RETT				;Return sucess

DAPERR:	MOVEI	S1,DAPLNK		;Get link status
	$CALL	D$STAT
	ANDX	S1,777777		;Get disconnect reason
	MOVE	S2,REMNOD		;Point to remote node data
	MOVEI	T1,1			;Get string valid bit
	CAIN	S1,.DCX34		;Was it bad user or password?
	 JRST	[ANDCAM T1,ND$USR(S2)		;Yes..clear user valid
		 ANDCAM T1,ND$PSW(S2)		;Clear password valid
		 JRST	DAPER1]
	CAIN	S1,.DCX36		;Was it bad account?
	ANDCAM	T1,ND$ACT(S2)		;Yes..clear account valid.
DAPER1:	JRST	CMDER1			;FORCE REPARSE
SUBTTL	DAPFNC	Routine to perform one DAP function

;ACCEPTS	S1/ address of initial function block

;RETURNS TRUE	Function accomplished
;RETURNS FALSE	Error during function


DAPFNC:	MOVEI	S1,.DFSIZ		;Get size of function block
	MOVEI	S2,FNCBLK		;Point to it
	$CALL	D$FUNC			;PERFORM FUNCTION
	 JUMPF	DAPERR			;Report DAP error
	$RETT				;Return success

WLDERR:	REPARS	(Invalid use of wild cards)

DAPCLS:	MOVEI	S1,DAPLNK		;Get the link index
	MOVEI	S2,[EXP .DCX0]		;Normal close
	$CALL	D$CLOS
	$RETT				;GIVE GOOD RETURN
SUBTTL	COMMAND ERROR SUBROUTINES


; SUBROUTINE TO TEST COLUMN POSITION AND OUTPUT CRLF IF NEEDED

TSTCOL:	$SAVE	<S1,S2>			;PRESERVE ACS ACROSS CALL
	HRRZ	S1,SBK+.CMIOJ		;GET OUTPUT JFN
	RFPOS				;READ FILE POSITION
	HRRZ	S2,S2			;KEEP JUST THE COLUMN POSITION
	JUMPE	S2,.RETF		;IF AT COLUMN 1 DO NOT OUTPUT CRLF
	MOVEI	S2,.CHCRT		;Get crlf
	BOUT				;Out put it
	MOVEI	S2,.CHLFD		;Get line feed
	BOUT				;Out put it
	$RETT				;RETURN TO WHENCE WE CAME ...


; ROUTINE TO OUTPUT THE JSYS MESSAGE ON AN ERROR FROM A GTJFN OR OPENF
;
; CALL:		CALL PUTERR
;RETURNS	 TRUE ALWAYS

PUTERR:	$TEXT	(,<^E/[-2]/>)		;Display last error
	$RETF				;RETURN TO WHENCE WE CAME ...

; ROUTINE TO OUTPUT PROPER STUFF WHILE DOING A TAKE

; CALL:		CALL TAKTST
;RETURNS	 TRUE ALWAYS


TAKTST:	SKIPE	TAKFLG			;Doing a TAKE?
	SKIPN	DSPFLG			; and displaying output?
	$RETT				;No..just return
	$TEXT	(,<^Q/DPRMPT/^T/CMDBUF/^A>) ;Yes..Log command
	$RETT

LOGCHR:	CAIE	S1,"?"			;Error character?
	CAIN	S1,"%"			;  or warning character?
	$CALL	[$SAVE	<S1,S2,T1>
		 $CALL	SUPOFF		;Yes..clear output suppression
		 $CALL	CHKPOS		;do <CRLF> if needed
		 $RETT]			;Continue
LOGCH1:	AOS	LOGPOS			;Increment position
	CAIN	S1,.CHCRT		;Carriage return?
	SETOM	LOGPOS			;Yes..reset position
	MOVE	S2,S1			;Put character in S2
	HRRZ	S1,SBK+.CMIOJ		;Get output JFN
	BOUT				;Write the character
	CAIE	S1,.PRIOU		;Primary output?
	SKIPN	DSPFLG			; not displaying take stuff?
	$RETT				;Yes..just return
	MOVEI	S1,.PRIOU		;Display on terminal for take
	BOUT
	$RETT


CHKPOS:	SKIPG	LOGPOS			;At column 0?
	$RETT				;Yes..just return
	$SAVE	<S1>			;No..save calling character
	MOVEI	S1,.CHCRT		;Send a carriage return
	$CALL	LOGCH1
	MOVEI	S1,.CHLFD		;Send a line feed
	$CALL	LOGCH1
	$RETT				;RETTurn original character
;TYPATM - ROUTINE TO TYPE THE CONTENTS OF THE ATOM BUFFER
;
;ACCEPTS IN S1/	POINTER TO ASCIZ PREFIX STRING TO BE TYPED
;		CALL TYPATM
;RETURNS	 TRUE ALWAYS

TYPATM:	$TEXT	(T%TTY,<^Q/S1/ "^T/ATMBUF/">)
	$RETT

;STOATM - ROUTINE TO COPY ATOM
;STOSTR - ROUTINE TO COPY AN ASCIZ STRING

;ACCEPTS	S1/ DESTINATION DESIGNATOR
;		S2/ SOURCE DESIGNATOR (STOSTR ONLY)

;RETURNS TRUE

STOATM:	HRROI	S2,ATMBUF		;POINT TO ATOM
STOSTR:	SETZ	T1,			;TERMINATE ON NULL
	SOUT
	$RETT
SUBTTL	CMDINI	Command parsing initialization routine

;ALWAYS CALL THIS ROUTINE AT A LESS-THAN-OR-EQUALLY NESTED LOCATION
;WITHIN THE PROGRAM IN COMPARISON WITH ANY SUBSEQUENT CALL TO THE COMND
;JSYS EXECUTION ROUTINES

CMDINI:	POP	P,T1			;REMEMBER EOF ADDRESS
	CAMG	P,CMDFRM		;NEED TO SAVE CONTEXT?
	JRST	CMDIN1			;NO..JUST SAVE EOF STUFF
	$SAVE	<CMDFRM,CMDPDL,SBK+.CMRTY,REPADR,EOFADR,NOPRMT>
	STKVAR	<<SAVACS,20>>		;SAVE THE CONTEXT AC'S
	HRLI	S1,CMDACS
	HRRI	S1,SAVACS
	BLT	S1,17+SAVACS
	HLRZ	S1,CMDPDL		;GET SAVED STACK SIZE
	ADD	S1,CMDPDL		;OFFSET SAVED WORDS
	HRRZM	S1,CMDPDL		;SET SAVE STACK SIZE TO ZERO
	HLRZ	S2,S1
	PUSH	P,[CMDIN2]		;SAVE FIXUP ADDRESS
CMDIN1:	MOVEM	T1,EOFADR		;SAVE EOF ADDRESS
	MOVEM	P,CMDFRM		;REMEMBER BEGINNING OF STACK
	MOVEI	S1,REPAR		;REPARSE ADDRESS
	MOVEM	S1,SBK+.CMFLG
	MOVEI	S1,CMDPDL+1
	SKIPN	CMDPDL			;FIRST PASS
	MOVEM	S1,CMDPDL		;YES..INIT CMD STACK STORAGE
	MOVE	S1,[.PRIIN,,.PRIOU]
	SKIPN	SBK+.CMIOJ
	MOVEM	S1,SBK+.CMIOJ		;STORE THE JFN'S
	HLRZ	S1,SBK+.CMIOJ		;GET INPUT JFN
	DVCHR				;FIND OUT WHAT IT IS
	LOAD	S2,S2,DV%TYP		;GET DEVICE TYPE
	SETOM	NOPRMT			;ASSUME NULL PROMPT
	CAIE	S2,.DVTTY		;IS IT TTY?
	CAIN	S2,.DVPTY		; OR PTY?
	SETZM	NOPRMT			;YES..WE NEED THE PROMPT
	PUSH	P,EOFADR		;RETURN TO CALLER
	JRST	CMDIN3			;INIT SBK AND RETURN

;HERE TO RESTORE PREVIOUS CONTEXT
CMDIN2:	HRLI	S1,SAVACS
	HRRI	S1,CMDACS
	BLT	S1,CMDACS+17		;RESTORE THEM ALL
CMDIN3:	MOVX	S1,<POINT 7,CMDBUF>	;POINTER TO COMMAND BUFFER
	MOVEM	S1,SBK+.CMBFP
	MOVEM	S1,SBK+.CMPTR		;POINTER TO NEXT FIELD
	MOVEI	S1,CMDBLN*5		;ROOM FOR TYPIN
	MOVEM	S1,SBK+.CMCNT
	SETZM	SBK+.CMINC		;NO UNPARSED CHARACTERS YET
	MOVX	S1,<POINT 7,ATMBUF>	;POINTER TO ATOM BUFFER
	MOVEM	S1,SBK+.CMABP
	MOVEI	S1,ATMBLN*5
	MOVEM	S1,SBK+.CMABC		;ROOM IN ATOM BUFFER
	MOVEI	S1,GJFBLK		;POINTER TO JFN BLOCK
	MOVEM	S1,SBK+.CMGJB
	$RETT
SUBTTL	Command field parsing routines

;COME HERE TO PROMPT FOR NEW COMMAND OR NEW PROMPT LINE OF COMMAND.
;CALL THIS ROUTINE WITH POINTER TO PROMPT IN S1, OR 0 IF NO PROMPT.

DPROMP:	MOVEM	S1,DPRMPT		;SAVE PROMPT POINTER FOR TAKTST
	SKIPN	NOPRMT			;WANT ANY PROMPT?
	CAIN	S1,0			;YES..ANY PROMPT SPECIFIED?
	HRROI	S1,[0]			;NO, POINT TO A NULL STRING
	MOVEM	S1,SBK+.CMRTY		;SAVE POINTER TO PROMPT
	POP	P,REPADR		;REMEMBER REPARSE ADDRESS
	DMOVEM	0,CMDACS+0		;SAVE AC'S
	MOVE	1,[2,,CMDACS+2]
	BLT	1,CMDACS+17
	HRL	S1,CMDFRM		;SAVE FROM BOTTOM OF STACK
	HRR	S1,CMDPDL		;MOVE DATA TO COMND PDL AREA
	HRRZ	S2,P			;SEE WHERE TOP OF STACK IS NOW
	SUB	S2,CMDFRM		;CALCULATE NUMBER OF WORDS
	HRLM	S2,CMDPDL		;SAVE SIZE OF SAVED STACK
	BLT	S1,CMDPDL(S2)		;SAVE THE STACK
	PUSH	P,REPADR		;MAKE STACK LIKE IT WAS
	MOVEI	S1,[FLD(.CMINI,CM%FNC)]	;TYPE PROMPT
	$CALL	RFIELD			;YES..DO IT
	$RETT				;RETURN TO CALLER

;READ A FIELD ROUTINE.  GIVE IT ADDRESS OF FUNCTION BLOCK IN A.
;JRSTS TO CMDERR IF ERROR.  S1 AND S2 WILL HAVE
;RESULT OF COMND JSYS IN THEM.

RFIELD:	$CALL	RFLDE			;READ FIELT2, SKIP IF SUCCESS
	 JUMPF	CMDERR			;FAILED, GO PROCESS ERROR
	$RETT				;SUCCESS

;ROUTINE TO READ A FIELD AND SKIP IFF SUCCESSFUL.  S1,S2, AND C WILL HAVE
;RESULT OF COMND JSYS IN THEM UPON RETURN.

PARSE:
RFLDE:	MOVE	S2,S1			;PUT FUNCTION BLOCK POINTER IN B
	MOVEI	S1,SBK			;POINTER TO STATE BLOCK IN A
	COMND				;READ FIELD OF COMND
	 ERJMP [HLRZ S1,SBK+.CMIOJ	;[100]
		GTSTS			;[100]
		TXNE S2,GS%EOF		;[100]
		JRST CMDEOF		;[100]EOF
		$TEXT (,<?Command JSYS failed, type CONTINUE to try again>)
					;[100]
		HALTF			;[100]
		JRST CMDEOF]		;[100]
	TXNE	S1,CM%NOP		;DID COMMAND PARSE CORRECTLY?
	 $RETF	 			;NO SINGLE RETURN
	LOAD	T2,.CMFNP(T1),CM%FNC	;GET THE PARSED FUNCTION
	$RETT				;YES, SKIP RETURN
CMDEOF:	HLRZ	S1,SBK+.CMIOJ		;GET COMND INPUT JFN
	GTSTS				;READ THE STATUS
	MOVE	P,CMDFRM		;RESTORE FRAME
	PUSH	P,EOFADR		;RETURN FALSE AFTER CMDINI
	SETZ	S1,			;CLEAR ERROR REASON
	TXNN	S2,GS%EOF		;WAS ERROR EOF?
	$RETF				;NO..JUST RETURN ERROR
	$RETE	(EOF)			;YES..RETURN EOF

;READ A FIELD AND REQUIRE CARRIAGE RETURN AFTER IT FOR CONFIRMATION

CFIELD:	STKVAR	<<VALUES,2>>
	$CALL	RFIELD			;READ THE FIELD
	DMOVEM	S1,VALUES		;SAVE DATA FROM FIELD
	CONFRM				;GET CONFIRMATION
	DMOVE	S1,VALUES		;GET VALUES OF FIELD
	$RETT				;RETURN TO CALLER
SUBTTL	Command parsing error and reparse routines

.REPAR:	$CALL	TSTCOL			;CRLF IF NEEDED
	$TEXT	(T%TTY,<?^T/0(S1)/>)	;DISPLAY MESSAGE
	$CALL	RELJFN
	JRST	CMDER1			;BACK TO THE BEGINNING

;GET HERE ON COMND JSYS ERROR.  LET USER TRY AGAIN.

MESLN==30
CMDERR:	STKVAR	<<ERMES,MESLN>>
	HRROI	S1,ERMES		;POINT TO MESSAGE AREA
	MOVE	S2,[.FHSLF,,-1]		;OURSELF, MOST RECENT ERROR
	MOVSI	T1,-MESLN*5		;MAXIMUM STRING WE'VE ROOM FOR
	ERSTR				;GET ERROR STRING
	 JFCL
	 JFCL				;UNEXPECTED ERRORS
	HRROI	S1,ERMES		;POINT AT STRING
	ESOUT				;PRINT IT IN STANDARD MANNER
	 ;...

;COME HERE TO LET USER FIX HIS ERROR (BY TYPING ^H) OR ISSUE ANOTHER
;COMMAND
;PRINT ERROR MESSAGE BEFORE TRANSFERRING HERE

	 ;...
CMDER1:	SKIPN	TAKFLG		;ARE WE IN A TAKE
	JRST	CMDER2		;NO..JUST REPARSE
	HLRZ	S1,SBK+.CMIOJ	;GET INPUT JFN
	CAIN	S1,.PRIIN	;READING FROM TERMINAL?
	JRST	CMDER2		;YES..JUST REPARS
	$CALL	TSTCOL			;BACK TO FIRST COLUMN
	SKIPN	INIFLG		;[0071]
	$TEXT	(T%TTY,<?Error during take file, aborting TAKE command>)
	SKIPE	INIFLG		;[0071]
	$TEXT	(T%TTY,<?Error processing PS:NFT.INIT, aborting processing>)
	JRST	CMDEOF			;Force exit from take

CMDER2:	SOS	REPADR			;MODIFY REPARSE ADDRESS SO REPROMPT HAPPENS
	JRST	REPAR

;PLACE TO TRANSFER IF USER EDITS PREVIOUSLY PARSED FIELDS

REPAR:	MOVE	P,CMDACS+P		;RESTORE P FOR SIZE CALCULATION
	HRL	S1,CMDPDL		;RESTORE STACK FROM SAVED STACK
	HRR	S1,CMDFRM		;COPY TO BOTTOM OF STACK
	BLT	S1,(P)			;RESTORE THE STACK
	MOVSI	16,CMDACS		;MAKE BLT POINTER
	BLT	16,16			;RESTORE REST OF AC'S
	JRSTF	@REPADR			;BACK TO END OF PROMPT CALL
SUBTTL	GENERAL SUBROUTINES

; ROUTINE TO CLEAR GTJFN BLOCK USED BY COMND JSYS
;
; CALL:		CALL CLRGJF

CLRGJF:	MOVE	S1,[GJFBLK,,GJFBLK+1] ;SET UP TO CLEAR GTJFN BLOCK
	SETZM GJFBLK			;CLEAR FIRST WORD OF BLOCK
	BLT	S1,GJFBLK+GJFLEN-1	;CLEAR GTJFN BLOCK
	MOVE	S1,[.NULIO,,.NULIO]	;GET NULL IO DEVICE
	MOVEM	S1,.GJSRC+GJFBLK	;SAVE IT
	$RETT				;RETURN TO WHENCE WE CAME ...

;RELJFN		QUICKY ROUTINE TO RELEASE ALL NON-OPEN JFNS
;ACCEPTS	NO ARGUMENTS
;RETURNS	TRUE ALWAYS

RELJFN::MOVX	S1,CZ%NCL!.FHSLF	;RELEASE ALL NON-OPEN JFNS
	CLZFF
	$RETT				;RETURN

;ECHOON AND ECHOOF - ROUTINES TO TURN ECHOING ON AND OFF
;ACCEPTS	NO ARGUMENTS
;RETURNS	TRUE ALWAYS

ECHOON:	SKIPA	T1,[TXO S2,TT%ECO]	;GET INSTRUCTION
ECHOOF:	MOVE	T1,[TXZ S2,TT%ECO]	;OR OTHER ONE
	MOVEI	S1,.PRIIN		;PRIMARY INPUT
	RFMOD				;READ STATUS OF TERMINAL
	XCT	T1			;TURN ON OR OFF ECHO BIT
	SFMOD				;SET TERMINAL TO NEW STATUS
	$RETT				;RETURN
SUBTTL	NODGET	Routine to build node recognition table

NODGET:	$SAVE	<P1,P2>			;PRESERVE SOME AC'S
	MOVEI	S1,NODPGS		;[0105]
	$CALL	M%AQNP			;[0073]GET PAGES
	LSH	S1,11			;[0073]
	MOVE	T2,S1			;[0073]SAVE ADDRESS OF PAGE
	SKIPE	NODTBL			;FIRST TIME HERE?
	 JRST	NODGE1			;NO..SKIP CREATION STUFF
	SETZM	0(T2)			;[0073]
	HRLI	S1,0(T2)		;[0073]CLEAR NODE DATA BASE
	HRRI	S1,1(T2)		;[0073]
	BLT	S1,NODPGS*1000-1(T2)	;[0105]
	$CALL	L%CLST			;YES..CREATE THE NODE LIST
	MOVEM	S1,NODLST		;SAVE THE INDEX
	MOVEI	S1,.NDGLN		;GET LOCAL HOST NAME
	MOVEI	S2,0(T2)		;[0073]POINT TO ARG BLOCK
	HRROI	T1,DEFNOD
	MOVEM	T1,.NDNOD(S2)		;STORE POINTER IN BLOCK
	NODE
	 ERJMP	[MOVEI S1,NODPGS	;[0105]
		MOVE S2,T2		;[0073]
		LSH S2,-11		;[0073]
		$CALL M%RLNP		;[0073]
		$RETF]
	HRROI	S1,DEFNOD		;Point to the name
	PUSH	P,T2			;[0073]
	$CALL	NODADD			;Add local node to table
	POP	P,T2			;[0073]
	MOVEM	S2,LOCNOD		;SAVE THE ENTRY ADDRESS

NODGE1:	MOVE	S2,NODTBL		;[0072]NODE TABLE
	HLRZ	S1,0(S2)		;[0072]COUNT OF ENTRIES
	JUMPE	S1,NODGE3		;[0072]NONE THERE?
NODGE2:	AOS	S2			;[0072]POINT AT NEXT ENTRY
	HLRZ	T1,0(S2)		;[0072]POINT TO ENTRY
	PUSH	P,T2			;[0072]
	MOVEI	T2,.NDSOF		;[0072]GET OFFLINE STATUS
	MOVEM	T2,ND$STA(T1)		;[0072]SET IT OFFLINE
	POP	P,T2			;[0072]
	SOSE	S1			;[0072] ANY MORE?
	JRST	NODGE2			;[0072] YES, KEEP GOING
NODGE3:	MOVEI	S1,NODPGS*1000-1	;[0105]GET ARGBLK LENGTH
	MOVEM	S1,0(T2)		;[0073]SAVE FOR NODE JSYS
	MOVEI	S1,.NDGNT		;GET THE FUNCTION
	MOVEI	S2,0(T2)		;[0073]AND ADDR OF ARG BLOCK
	NODE				;READ THE NAMES
	 ERJMP	[MOVEI S1,NODPGS	;[0105]
		MOVE S2,T2		;[0073]
		LSH S2,-11		;[0073]
		$CALL M%RLNP		;[0073]
		$RETF]
	HLLZ	P1,.NDNND(T2)		;[0073]GET COUNT OF NODES
	MOVN	P1,P1			;NEGATE IT
	HRRI	P1,.NDBK1(T2)		;[0073]GET ADDRESS OF FIRST BLOCK
NODGE4:	MOVE	P2,(P1)			;GET CURRENT BLOCK ADDRESS IN P2
	MOVE	S1,NODTBL		;POINT TO NODE TABLE
	MOVE	S2,.NDNAM(P2)		;GET POINTER TO NAME STRING
	TBLUK				;FIND THE NODE
	TXNE	S2,TL%NOM+TL%AMB	;AMBIGUOUS OR NO MATCH?
	 JRST	[MOVE S1,.NDNAM(P2)	;YES..ADD IT TO THE TABLE
		PUSH P,T2		;[0073]
	         $CALL NODADD
		POP P,T2		;[0073]
		 JRST .+1]		;FINISH ALL THE REST
	MOVE	S1,(S1)			;YES -- GET NODE INFO ADDRESS
	MOVE	S2,.NDSTA(P2)		;Get on or off-line status
	MOVEM	S2,ND$STA(S1)		;Store it
	AOBJN	P1,NODGE4		;DO ALL NODES
	MOVEI	S1,NODPGS		;[0105]
	MOVE	S2,T2			;[0073]
	LSH	S2,-11			;[0073]
	$CALL	M%RLNP			;[0073]
	$RETT				;RETURN
SUBTTL	NODADD	Routine to add an entry to node table

;ACCEPTS	S1/ pointer to node name string to be added

;RETURNS	S1/ address of table entry
;		S2/ address of node data

NODADD:	$SAVE	<P1>			;REMEMBER CALLING ARG
	MOVE	P1,S1
	MOVE	S1,NODLST		;GET NODE LIST INDEX
	MOVEI	S2,ND$LEN		;GET REQUIRED SIZE FOR ENTRY
	$CALL	L%CENT			;CREATE AN ENTRY
	MOVE	T4,S2			;REMEMBER ENTRY ADDRESS
	HRROI	S1,ND$NAM(S2)		;POINT TO STORAGE FOR STRING
	MOVE	S2,P1			;GET POINTER TO NAME
	$CALL	STOSTR			;COPY THE NAME
	$CALL	NODEXP			;CHECK TABLE SIZE
	MOVE	S2,T4			;GET ENTRY ADDRESS
	HRLI	S2,ND$NAM(S2)		;POINT TO NAME STRING
	MOVE	S1,NODTBL
	TBADD				;ADD IT TO TABLE
	MOVE	P1,S1			;REMEMBER WHERE IT WENT
	SKIPN	T3,LOCNOD		;Is this the local node?
	JRST	NODAD1			;Yes..get local defaults
	SETOM	ND$STA(T4)		;No..Mark temporary status
	HRROI	S1,ND$USR(T4)		;Copy local default USER
	HRROI	S2,ND$USR(T3)		;...
	$CALL	STOSTR
	HRROI	S1,ND$ACT(T4)		;Copy local default ACCOUNT
	HRROI	S2,ND$ACT(T3)		;...
	$CALL	STOSTR
	JRST	NODAD2			;Return Node entry address
NODAD1:	MOVE	S1,[[ASCIZ/TOPS20/],,.OSTP20]	;Get local defaults
	MOVEM	S1,ND$OST(T4)		;Set TOPS10 ostype
	GJINF				;Get user number
	MOVE	S2,S1			;Store user name
	HRROI	S1,ND$USR(T4)		;...
	DIRST				;...
	 ERJMP	.+2
	AOS	ND$USR(T4)		;Set user valid
	SETO	S1,			;Get account string
	HRROI	S2,ND$ACT(T4)		;Store account string
	GACCT				;...
	 ERJMP	.+2
	AOS	ND$ACT(T4)		;Set account valid
NODAD2:	MOVE	S1,P1			;Return Node entry address
	HRRZ	S2,0(S1)		;Return Node data address
	$RETT

NODEXP:	SKIPN	S1,NODTBL		;Have a node table yet?
	JRST	NODEX1			;No..go create one
	HRRZ	S1,@NODTBL		;Get maximum entry count
	HLRZ	S2,@NODTBL		;Get actual entry count
	CAME	S1,S2			;Is table full?
	$RETT				;No..just return
NODEX1:	ADDI	S1,MAXNOD+1		;Yes..get more room
	$CALL	M%GMEM
	MOVE	TF,NODTBL		;Save source address
	SUBI	S1,1			;Say MAXNOD entries allowed
	MOVEM	S1,0(S2)		;Store in table header
	MOVEM	S2,NODTBL		;Save new pointer
	JUMPF	TF,NODEX2		;Return if no previous table
	HLRZ	S1,@TF			;Get current entry count
	HRLM	S1,@NODTBL		;Save in new table
	HRL	S2,TF			;Get source,,dest
	AOBJP	S2,.+1			;Point past header
	ADD	S1,S2			;Get final destination address
	BLT	S2,0(S1)		;Copy the table
	HRRZ	S1,@TF			;Get old table size
	ADDI	S1,1			;Plus header word
	MOVE	S2,TF			;Get old table address
	$CALL	M%RMEM			;Release the memory
NODEX2:	$RETT
SUBTTL	RELNOD	Routine to delete temporary node info

;Accepts	No arguments

RELNOD:	MOVE	S1,NODLST		;Position to first list entry
	$CALL	L%FIRST
	JUMPT	RELNO2
	$RETT

RELNO1:	MOVE	S1,NODLST		;Position to next list entry
	$CALL	L%NEXT
	JUMPF	.RETT			;Return on last entry
RELNO2:	SKIPGE	ND$STA(S2)		;Node data termporary?
	$CALL	DELNOD			;Yes..delete the entry
	JRST	RELNO1			;Check all list entries


SUBTTL	DELNOD	Routine to delete node entry

;Accepts	S2/	Address of node data

DELNOD:	MOVE	S1,NODTBL		;Get table entry address
	HRROI	S2,ND$NAM(S2)
	TBLUK
	TXNN	S2,TL%EXM		;Find it?
	$RETF				;No..return failure
	MOVE	S2,S1			;Delete table entry
	MOVE	S1,NODTBL
	TBDEL
	MOVE	S1,NODLST		;Delete list entry
	$CALL	L%DENT
	$RETT

SUBTTL	NODOFF	Put node in off-line status

;Accepts	S2/	Address of node data

NODOFF:	MOVEI	S1,.NDSOF		;Get off-line status
	MOVEM	S1,ND$STA(S2)
	$RETT
SUBTTL	PSIINI	Software interrupt system initialization

PSIINI:	MOVEI	S1,.FHSLF		;Initialize for me
	MOVE	S2,[LEVTAB,,CHNTAB]	;Point to tables
	SIR
	MOVE	S1,[.TICCA,,4]		;[0075]
	ATI				;[0075]
	MOVEI	S1,.FHSLF		;[0075]
	MOVX	S2,1B<.ICCDN>!1B<.ICDAV>!1B<.ICIMA>!1B<.ICCNO>!1B4 ;[0075]
	AIC				;Turn on selected channels
	EIR				;Enable requests
	$RETT

CNOENA:	SETOM	CNOFLG			;We are processing control O
	MOVE	S1,[.CHCNO,,.ICCNO]	;Get control O channel
	ATI				;Attatch it
	$RETT

CNODIS:	SETZM	CNOFLG			;No control O processing
	MOVEI	S1,.CHCNO		;Get control O character
	DTI				;Detatch it
SUPOFF:	HRRZ	S1,SBK+.CMIOJ		;Clear suppress output flag
	RFMOD
	TXZ	S2,TT%OSP
	SFMOD
	$RETT

SUBTTL	Interrupt service routines

INTCTA:	$BGINT	2			;[0075]
	MOVE	T1,LLSTAT		;[0075]
	TXNN	T1,MO%CON		;[0075]LINK CONNECTED?
	JRST	[$TEXT (,<[No logical link established]>) ;[0075]
		$DEBRK]			;[0075]
	$TEXT	(,<[^D/MESIN/ messages received, ^D/MESOUT/ messages sent^A>)
	HRRZ	S1,LOCJFN		;[0075]
	GTSTS				;[0075]
	TXNE	S2,GS%OPN		;[0075]FILE OPEN?
	SKIPN	PAGFLG		;[0075]DISK FILE USING PMAPS
	JRST	[$TEXT (,<]>)		;[0075]NO
		$DEBRK]			;[0075]
	$TEXT	(,<, local file open at page ^D/PAGNUM/]>) ;[0075]
	$DEBRK

INTCNO:	$BGINT	1
	SKIPT	CNOFLG			;Processing control-O?
	JRST	INTCN1			;No..just debrk
	HRRZ	S1,SBK+.CMIOJ		;Get output JFN
	RFMOD
	TXCE	S2,TT%OSP		;Already suppressing?
	 JRST	[SFMOD			;Yes..compliment the state
		 JRST	INTCN1]		;And proceed
	CFOBF				;No..clear output buffer
	$TEXT	(,< ^^O...>)		;Say we did it
	SFMOD				;Suppress output
	MOVEI	S1,DAPLNK		;Get link index
	MOVEI	S2,.DIACP		;Force access complete
	$CALL	D$INTR
INTCN1:	$DEBRK

INTCDN:	$BGINT	1
	MOVEI	S1,DAPLNK		;Get link index
	MOVEI	S2,.DICDN		;Get interrupt cause
	$CALL	D$INTR
	$DEBRK

INTDAV:	$BGINT	1
	MOVEI	S1,DAPLNK		;Get link index
	MOVEI	S2,.DIDAV		;Get interrupt cause
	$CALL	D$INTR
	$DEBRK

INTINA:	$BGINT	1
	MOVEI	S1,DAPLNK		;Get the link index
	MOVEI	S2,.DIINA		;Get interrupt cause
	$CALL	D$INTR
	$DEBRK
SUBTTL	Literals


FROMTO:	ASCIZ / => /			;LITERAL TO SHOW FILE FROM, TO
PRMPT:	ASCIZ /NFT>/			;PROMPT FOR COMMANDS


	LSTOF.				;Expand the literals
	LIT
	LSTON.
SUBTTL	Interrupt tables

	.PSECT	DATA			;Load into impure storage

LEVTAB:	LEV1PC
	LEV2PC				;[0075]
	EXP  0

;INTERRUPT CHANNELS

RADIX 5+5

CHNTAB:
ICHESC:	1,,INTCNO			;Control-O channel
ICHCDN:	1,,INTCDN			;Connect/Disconnect
ICHDAV:	1,,INTDAV			;Data available
ICHINA:	1,,INTINA			;Interrupt message
ICH004:	2,,INTCTA			;[0075]^A
ICH005:	BLOCK 1				;ASSIGNABLE CHANNEL 5
ICHAOV:	BLOCK 1				;ARITHMETIC OVERFLOW
ICHFOV:	BLOCK 1				;FLOATING OVERFLOW
ICH008:	BLOCK 1				;RESERVED
ICHPOV:	BLOCK 1				;PDL OVERFLOW
ICHEOF:	BLOCK 1				;END OF FILE
ICHDAE:	BLOCK 1				;DATA ERROR
ICHQTA:	BLOCK 1				;QUOTA EXCEEDED
ICH013:	BLOCK 1				;RESERVED
ICHTOD:	BLOCK 1				;TIME OF DAY (RESERVED)
ICHILI:	BLOCK 1				;ILLEG INSTRUCTION
ICHIRD:	BLOCK 1				;ILLEGAL READ
ICHIWR:	BLOCK 1				;ILLEGAL WRITE
ICHIEX:	BLOCK 1				;ILLEGAL EXECUTE (RESERVED)
ICHIFT:	BLOCK 1				;INFERIOR FORK TERMINATION
ICHMSE:	BLOCK 1				;MACHINE SIZE EXCEEDED
ICHTRU:	BLOCK 1				;TRAP TO USER (RESERVED)
ICHNXP:	BLOCK 1				;NONEXISTENT PAGE REFERENCED
ICH023:	BLOCK 1				;ASSIGNABLE CHANNEL 23
ICH024:	BLOCK 1				;ASSIGNABLE CHANNEL 24
ICH025:	BLOCK 1				;ASSIGNABLE CHANNEL 25
ICH026:	BLOCK 1				;ASSIGNABLE CHANNEL 26
ICH027:	BLOCK 1				;ASSIGNABLE CHANNEL 27
ICH028:	BLOCK 1				;ASSIGNABLE CHANNEL 28
ICH029:	BLOCK 1				;ASSIGNABLE CHANNEL 29
ICH030:	BLOCK 1				;ASSIGNABLE CHANNEL 30
ICH031:	BLOCK 1				;ASSIGNABLE CHANNEL 31
ICH032:	BLOCK 1				;ASSIGNABLE CHANNEL 32
ICH033:	BLOCK 1				;ASSIGNABLE CHANNEL 33
ICH034:	BLOCK 1				;ASSIGNABLE CHANNEL 34
ICH035:	BLOCK 1				;ASSIGNABLE CHANNEL 35

RADIX 8

	.ENDPS DATA
SUBTTL	Impure storage


	.PSECT	DATA

DEFINE	$DATA (NAME,SIZE<1>) <
 NAME:	BLOCK SIZE
	 ..LOC==.>

;Command parsing storage


CMDBLN==:<^D80*6>/5+1		;ROOM FOR SIX LINE COMMAND
ATMBLN==:CMDBLN


DATORG:				;Start of impure storage to be cleared

$DATA	CONBLK,14		;[70]
$DATA	CMDBUF,CMDBLN
$DATA	CMDACS,20		;SAVED AC'S FROM BEGINNING OF COMMAND LINE
$DATA	EOFADR,1		;EOF DISPATCH ADDRESS
$DATA	ATMBUF,ATMBLN		;HOLDS LAST PARSED FIELD
$DATA	SBK,20			;COMND JSYS STATE BLOCK
$DATA	REPADR,1		;Reparse address for comnd
$DATA	CMDFRM,1		;Frame pointer for parse routines
$DATA	CMDPDL,PDLEN		;ROOM TO SAVE PDL

$DATA	CMDFDB,5		;Temporary FDB used by PARFIL

;Interrupt PC locations

$GDATA	LEV1PC,1		;RETURN PC FOR INTERRUPT LEVEL 1
$GDATA	LEV2PC,1		;[0075]RETURN PC FOR LEV 2 INT

$DATA	LOCNOD,1		;LOCAL NODE TABLE ENTRY
$DATA	DEFNOD,2		;Default node name

$DATA	OBJNAM,NAMSIZ		;Object name text

$DATA	FNCBEG,0		;Start of parsing area

$DATA	FNCBLK,.DFSIZ		;Dap function block

$DATA	SRCNOD,1		;SOURCE NODE TABLE ENTRY
$DATA	SRCNAM,2		;Source node name
$DATA	SRCJFN,1		;SOURCE FILE JFN
$DATA	SRCPFL,1		;NON TOPS-20 FILE SPEC FLAG
$DATA	SRCFIL,FILSIZ		;SOURCE FILE NAME STRING
$DATA	SRCSWS,1		;SOURCE FILE SWITCHES

$DATA	DSTFLG,2		;DESTINATION BLOCK POINTER
$DATA	DSTNOD,1		;DESTINATION NODE TABLE ENTRY
$DATA	DSTNAM,2		;Destination node name
$DATA	DSTJFN,1		;DESTINATION FILE JFN
$DATA	DSTPFL,1		;NON TOPS-20 FILE SPEC FLAG
$DATA	DSTFIL,FILSIZ		;DESTINATION FILE NAME STRING
$DATA	TMPFIL,FILSIZ		;TEMPORARY SAVE FOR DESTINATION FILE
$DATA	DSTSWS,1		;DESTINATION FILE SWITCHES

$DATA	REMNOD,1		;Remote node data address
$DATA	REMJFN,1		;Remote JFN from Name message

$DATA	NODHLP,5		;Node help string

$DATA	DEFBEG,0		;* Order must agree with mode *
$DATA	REMUSR,NAMSIZ		;Remote user name
$DATA	REMACT,NAMSIZ		;Remote account string
$DATA	REMPSW,NAMSIZ		;Remote password string
	DEFSIZ==.-DEFBEG	;Size of default save area

$DATA	REMOPD,NAMSIZ		;Remote optional data
$DATA	FILATT,1		;File attribute switches

$DATA	GJFBLK,GJFSIZ		;GTJFN BLOCK FOR COMND JSYS

$DATA	DEFDEV,NAMSIZ		;DEFAULT OUTPUT DEVICE STORAGE
$DATA	DEFDIR,NAMSIZ		;DEFAULT DIRECTORY STRING
$DATA	DEFNAM,NAMSIZ		;DEFAULT FILENAME STORAGE
$DATA	DEFEXT,NAMSIZ		;DEFAULT EXTENSION STORAGE
$DATA	DEFVER,NAMSIZ		;DEFAULT VERSION STORAGE
	GJFLEN==.-GJFBLK	;LENGTH TO CLEAR FOR CLRGJF

$DATA	CNOFLG,1		;-1 if Control-O being trapped
$DATA	NAMFLG,1		;-1 If file name displayed
$DATA	SNDFLG,1		;-1 if sending files to remote node
$DATA	VOLNAM,8		;Pointer to current volume name
$DATA	DIRNAM,8		;Pointer to current direct name
$DATA	FILNAM,8		;Pointer to current file name
$DATA	FILSPC,^D20		;Pointer to current filespec
	FNCSIZ==.-FNCBEG	;SIZE OF COPY AREA

$DATA	DIRTXT,^D40		;Storage for NAME;PROTECTION
$DATA	DIRTX1,^D20		;Storage for n nnnn(n)

$DATA	PDL,PDLEN		;PUSH DOWN POINTER
$DATA	CMDJFN,1		;INPUT JFN FOR TAKE COMMAND
$DATA	LOGJFN,1		;OUTPUT JFN FOR TAKE COMMAND
$DATA	LOGPOS,1		;Current logfile (or terminal) position
$DATA	INIFLG,1		;[0071]NON-ZERO IF READING NFT.INIT
$DATA	TAKFLG,1		;NON-ZERO IF PROCESSING INDIRECT FILE
$DATA	DSPFLG,1		;NON-ZERO IF DISPLAYING TAKE
$DATA	PASFLG,1		;[76]-1 IF COMMAND FILE HAS WORLD READ ACCESS
$DATA	NOPRMT,1		;NON-ZERO IF NULL PROMPT WANTED
$DATA	DPRMPT,1		;PROMPT POINTER


$DATA	DAPOB,.DOSIZ		;Dap Open block

;Node data base storage

$DATA	NODLST,1		;NODE LIST INDEX
$DATA	NODTBL,1		;Address of node recognition table
$DATA	NFTEND,0		;End of impure storage

	.ENDPS	DATA		;Back to normal storage

	END <3,,ENTVEC>