	TITLE	CZ -- UN*X LIKE CONNECT COMMAND
	SUBTTL	PHIL BUDNE @ BU/DSG

	SEARCH	MONSYM, MACSYM, JOBDAT
	.REQUIRE SYS:MACREL

A==1
B==2
C==3
D==4

P==17

TABMAX==^D500			;MAXIMUM TABLE ENTRIES
DIRSIZ==^D85			;MAXIMUM CHARS IN A DIR NAME

PSDIR==540000,,0		;TEMPLATE FOR PS: DIRECTORY NUMBER
ROOTD==1			;DIRECTORY NUMBER FOR <ROOT-DIRECTORY>


PDLL==1K			;1 K WORDS FOR PDL
ATMLEN==^D100			;LENGTH FOR ATOM BUFFER
CMDLEN==^D200			;LENGTH FOR COMMAND BUFFER

ATMBUF:	BLOCK	<ATMLEN+4>/5	;ATOM BUFFER
CMDBUF:	BLOCK	<CMDLEN+5>/5	;COMMAND PARSE BUFFER
CSB:	BLOCK	20		;COMMAND STATE BLOCK
CMDGTJ:	BLOCK	20		;COMMAND GTJFN BLOCK

TABLE:	BLOCK	TABMAX+1	;ROOM FOR TABMAX ENTRIES PLUS HEADER WORD
PDL:	BLOCK	PDLL		;PUSH DOWN LIST

CURR:	BLOCK	1		;CONNECTED DIRECTORY AT START
HOME:	BLOCK	1		;'HOME' DIRECTORY
PREV:	BLOCK	1		;PREVIOUSLY CONNECTED DIR
SAVSTK:	BLOCK	1		;STACK FOR REPARSE
CAPS:	BLOCK	1		;POSSIBLE CAPS
ENABLD:	BLOCK	1		;ENABLED CAPS
TARGET:	BLOCK	1		;DIRECTORY TO CONNECT TO

DOTBP==<-1,,[ASCIZ '.']>
DDOTBP==<-1,,[ASCIZ '..']>
SLASH==<-1,,[ASCIZ '/']>

OPDEF	PJRST	[JUMPA	17,]

START:	JFCL
	RESET
	MOVE	P, [-PDLL,,PDL-1]

	MOVEI	A, .FHSLF
	RPCAP
	MOVEM	B, CAPS
	MOVEM	C, ENABLD
	SETO	C,
	EPCAP

	GJINF			;GET JOB INFO
	HRLI	A, (PSDIR)	;GET MAKE USER NUMBER INTO PS: DIR
	MOVEM	A, HOME		;SAVE AS POSSIBLE HOME
	MOVEM	B, CURR		;SAVE CURRENT

	HRROI	1, [ASCIZ 'HOME:']
	CALL	CNVDIR
	 TRNA
	  MOVEM	A, HOME		;SAVE NEW HOME

	HRROI	A, [ASCIZ 'PREV:']
	CALL	CNVDIR
	 SETZ	A,
	MOVEM	A, PREV

	MOVEI	A, .RSINI
	RSCAN
	 ERJMP	DIE
	JUMPE	A, DIE

	MOVE	A, [CM%WKF+PARSE] ;FLAGS,,REPARSE
	HRROI	B, [0]		;PROMPT
	CALL	CMDINI		;INIT COMMAND STATE BLOCK
	MOVEM	P, SAVSTK
	JRST	FIRST

	JFCL			;REPARA GETS SOS'ED
PARSE:	SKIPG	CSB+.CMINC
	 JRST	DIE
	MOVE	P, SAVSTK

FIRST:	MOVX	A, GJ%OFG	;GET FLAGS
	MOVEM	A, CMDGTJ	;SET UP GTJFN BLOCK
	MOVEI	A, [FLDDB. .CMFIL] ;PARSE FILE (TO GET RID OF COMMAND NAME)
	CALL	RFIELD
	MOVE	A, B		;GET JFN
	RLJFN			;TOSS IT
	 JFCL

	CALL	DOTOP		;PARSE TOP LEVEL
	MOVEM	A, TARGET
	CAME	A, CURR		;SAME?
	 IFSKP.
	  TMSG	<[Curr: >	;]
	  MOVEI	A, .PRIOU
	  MOVE	B, CURR
	  DIRST
	   EJSHLT
	  CALL	BRCRLF

	  SKIPN	PREV		;HAVE PREV?
	   JRST	DIE		; NO, KILL ME NOW!
	  TMSG	<[Prev: >	;]
	  MOVEI	A, .PRIOU
	  MOVE	B, PREV
	  DIRST
	   EJSHLT
	  CALL	BRCRLF
	  JRST	DIE
	 ENDIF.
	TMSG	<[From: >	;]
	MOVEI	A, .PRIOU
	MOVE	B, CURR
	DIRST
	 EJSHLT
	CALL	BRCRLF

	TMSG	<[To:   >	;]
	MOVEI	A, .PRIOU
	MOVE	B, TARGET
	DIRST
	 EJSHLT
	CALL	BRCRLF

	MOVEI	A, .FHSLF
	MOVE	C, ENABLD	;REDUCE PRIVS
	EPCAP

	MOVE	A, TARGET
	SETZ	B,		;NO PASSWORD (FIRST TRY)
	CALL	CONNECT
	 TRNA
	  JRST	DONE		;ALL DONE

	MOVEI	A, .FHSLF
	GETER
	 EJSHLT
	HRRZ	B, B		;GET JUST ERROR CODE
	CAIE	B, ACESX3	;PASSWORD IS REQUIRED?
	 JSHLT

	MOVEI	A, REPASS
	HRROI	B, [ASCIZ 'Password: ']
	CALL	CMDINI
	MOVEM	P, SAVSTK
	TRNA

REPASS:	MOVE	P, SAVSTK
	MOVEI	A, [FLDDB. .CMINI]
	CALL	RFIELD

	CALL	NOECHO
	MOVEI	A, [FLDDB. .CMTXT,,,,,[
		    FLDDB. .CMCFM]]
	CALL	RFIELD
	TSZ	C, C		;GET TEXT?
	IFN.	C
	 CALL	ECHO
	 CALL	CRLF
	 TMSG	<[Aborted]>
	 CALL	CRLF
	 JRST	DIE
	ENDIF.
	CALL	CRLF
	CALL	ECHO

	MOVE	A, TARGET
	HRROI	B, ATMBUF
	CALL	CONNECT
	 JSHLT
	TMSG	<[OK]>
	CALL	CRLF

DONE:	HRROI	A, [ASCIZ 'PREV']
	MOVE	B, CURR
	CALL	LOGNAM
	 JSERR

	HRROI	A, [ASCIZ 'CURR']
	MOVE	B, TARGET
	CALL	LOGNAME
	 JSERR

DIE:	HALTF
	JRST	DIE

	SUBTTL	STRING SPACE ROUTINES
; CLEAR TBLUK TABLE
CLRTAB:	MOVEI	A, TABMAX	;GET MAX ENTRIES, CURRENT
	MOVEM	A, TABLE	;STORE

; CLEAR STRING AREA
CLRSTR:	HLRZ	A, .JBSA
	MOVEM	A, .JBFF
	JUMPN	A, R	
	TMSG	<
? LEFT HALF OF .JBSA EMPTY -- WAS NOT LOADED BY LINK?
>
	HALTF
	JRST	CLRSTR

; RETURN POINTER TO STRING SPACE
STRBEG:	MOVE	A, .JBFF
	RET

; END NEW STRING, RETURN POINTER TO IT
STREND:	EXCH	A, .JBFF
	RET

; A/	DIR NUMBER (0 FOR CURRENT)
;	CALL	GETSUB
;	<ALWAYS>
; TABLE FILLED WITH ALL SUBDIRS OF GIVEN DIR

GETSUB:	STKVAR	<DIRN,JFN,<STRBUF,40>>
	MOVEM	A, DIRN		;SAVE USER NUMBER

	IFN. A			;GIVEN A DIRECTORY?
	 HRRZ	C, A		;GET JUST DIR NUMBER
	 MOVE	D, CAPS		;GET POSSIBLE CAPS
;;	 CAIN	C, ROOTD	;IS A ROOT-DIRECTORY?
;;	  TXNE	D, (SC%WHL!SC%OPR) ; ARE WE WOPR?
;;	   TRNA			;  BE MACHO
	    PJRST ROTSUB	;   GO GET TOP LEVELS WITH RCDIR FOR WIMPS

	 HRROI	A, STRBUF
	 MOVE	B, DIRN
	 DIRST			;NO, GET STRING
	  ERJMP	R		; ERROR!
	ELSE.			;GIVEN A DIRECTORY?
	 HRROI	A, STRBUF
	ENDIF.			;NOT GIVEN DIRECTORY

	HRROI	B, [ASCIZ '*.DIRECTORY'] ;GET WILDCARD STRING
	SETZ	C,
	SOUT			;COPY

	MOVSI	A, (GJ%SHT!GJ%IFG) ;SHORT, WILD
	HRROI	B, STRBUF
	GTJFN
	 RET
	MOVEM	A, JFN		;SAVE JFN
	JRST	CHKDIR		;JUMP INTO LOOP

	DO.
	 MOVE	A, JFN		;GET JFN WITH FLAGS
	 GNJFN			;STEP
	 ERJMP ENDLP.		; NO MORE

CHKDIR:	 HRRZ	A, JFN		;GET JUST JFN
	 MOVE	B, [1,,.FBCTL]	;GET FLAGS WORD
	 MOVEI C, D		;INTO D
	 GTFDB			;GET FROM FDB
	  ERJMP ENDLP.		; FAILED
	 TXNN	D, FB%DIR	;IS IT A DIR?
	  LOOP.			; NO, GET NEXT

	 CALL	STRBEG		;GET STRING FROM END OF CORE
	 HRLI	A, (POINT 7,)	;MAKE BP
	 HRRZ	B, JFN		;GET JUST JFN
	 MOVX	C, <FLD(.JSAOF,JS%NAM)>	;GET FILE NAME ONLY
	 MOVE	D, A		;SAVE BP
	 JFNS			;GET STRING
	  ERJMP ENDLP.		; SIGH
	 SETZ	B,		;GET NUL
	 IDPB	B, A		;TERMINATE STRING

	 DO.
	  ILDB	B, D		;GET CHAR
	  JUMPE	B, ENDLP.	;DONE
	  CAIG	B, "Z"		;IS UPPER?
	   CAIGE B, "A"
	    TRNA
	     ADDI B, "a"-"A"	;MAKE LOWER
	  DPB	B, D		;STORE BACK
	  LOOP.
	 OD.

	 MOVEI	A, 1(A)		;GET NEW END OF CORE
	 CALL	STREND		;SET IT
	 HRLZ	B, A		;MAKE TABLE ENTRY

	 MOVEI	A, TABLE	;GET TABLE
	 TBADD			;ADD TO TABLE
	  ERJMP ENDLP.
	 LOOP.
	OD.
	RET
	ENDSV.

; HERE TO GET SUBDIRS OF A <ROOT-DIRECTORY>.  USE RCDIR
; SO THAT NON-WHEELS CAN WIN WITH /PS/USER
ROTSUB:	STKVAR	<DIRN,<PATBUF,DIRSIZ/5>,<DIRBUF,DIRSIZ/5>,USER>
	MOVEM	A, DIRN
	HRRZ	A, A		;GET JUST DIR NUMBER
	CAIE	A, ROOTD	;IS ROOT?
	 IFSKP.
	  HLRZ	B, DIRN		;GET 0,,STR NUMBER
	  HRLI	B, .DVDES	;MAKE DEVICE DESCR
	  HRROI	A, PATBUF	;GET BP TO BUFFER
	  DEVST			;MAKE STRING
	   RET
	  HRROI	B, [ASCIZ ':<*>']
	  SETZ	C,
	  SOUT
	 ELSE.
	  HRROI	A, PATBUF	;GET DEST BUFFER
	  MOVE	B, DIRN		;GET BASE DIR
	  DIRST			;CONVERT TO STRING
	   EJSHLT
	  MOVEI	B, "."		;CRUSH CLOSE WIDGET WITH DOT
	  DPB	B, A
	  MOVEI	B, "*"		;ADD A STAR
	  IDPB	B, A		;<
	  MOVEI	B, ">"		;AND A NEW CLOSE WIDGET
	  IDPB	B, A
	  SETZ	B,		;TIE OFF WITH A NULL
	  IDPB	B, A
	 ENDIF.

	MOVSI	A, (RC%AWL)	;ALLOW WILDS
	HRROI	B, PATBUF	;GET TEMPLATE
	RCDIR			;GET FIRST DIR IN GROUP
	 ERJMP	R
	TLNN	A, (RC%NOM!RC%AMB!RC%NMD)
	 TLNN	A, (RC%WLD)
	  RET
	MOVEM	C, USER		;STORE INITIAL USER NUMBER

	TMSG	<ROTSUB: >
	HRROI	A, PATBUF
	PSOUT
	CALL	CRLF

	DO.			;LOOP FOR ALL MATCHING DIRS
	 HRROI	A, DIRBUF	;GET STR BUFF
	 MOVE	B, USER		;GET USER NUMBER
	 DIRST			;
	  EJSHLT

	 CALL	STRBEG
	 HRLI	A, (POINT 7,)	;MAKE DEST BP

;; ELIMINATE PREFIX
	 MOVE	B, [POINT 7, DIRBUF]
	 MOVE	D, [POINT 7, PATBUF]
	 DO.
	  ILDB	C, D		;GET CHAR FROM WILD SPEC
	  JUMPE	C, NXTDIR	;NEVER SAW STAR????
	  CAIN	C, "*"		;STAR?
	   EXIT.		; YES, NOW POSITIONED AT START
	  ILDB	C, B		;GET A CHAR FROM SANE SPEC
	  JUMPE	C, NXTDIR	;NEVER SAW OPEN WIDGET?
	  LOOP.
	 OD.

	 TMSG	<	>
	 MOVE	A, B
	 PSOUT
	 CALL	CRLF

	 DO.			;COPY WIDGET CONTENTS
	  ILDB	C, B		;GET NEXT
	  JUMPE	C, NXTDIR	;NO CLOSE WIDGET?
	  CAIN	C, "."		;DREADED DOT?
	   JRST NXTDIR		; YES, TOSS THIS ONE <
	  CAIN	C, ">"
	   EXIT.
	  IDPB	C, A		;STORE CHAR
	  LOOP.
	 OD.			;COPY WIDGET CONTENTS
	 SETZ	C,
	 IDPB	C, A		;TIE OFF STRING

	 MOVEI	A, 1(A)		;GET END OF STRING
	 CALL	STREND		;STORE IT

	 MOVE	D, A		;GET STRING START
	 HRLI	D, (POINT 7,)	;MAKE BP
	 DO.
	  ILDB	B, D		;GET CHAR
	  JUMPE	B, ENDLP.	;DONE
	  CAIG	B, "Z"		;IS UPPER?
	   CAIGE B, "A"
	    TRNA
	     ADDI B, "a"-"A"	;MAKE LOWER
	  DPB	B, D		;STORE BACK
	  LOOP.
	 OD.

	 HRLZ	B, A		;GET TABLE ENTRY
	 MOVEI	A, TABLE	;GET TABLE
	 TBADD
	  ERJMP	R		;DID NOT FIT?

NXTDIR:  MOVSI	A, (RC%AWL!RC%STP) ;STEP TO THE NEXT DIRECTORY
	 HRROI	B, PATBUF
	 MOVE	C, USER
	 RCDIR
	  ERJMP	R
	 MOVEM	C, USER
	 TLNN	A, (RC%NOM!RC%AMB!RC%NMD)
	  TLNN	A, (RC%WLD)
	   EXIT.
	 LOOP.			;DO NEXT ONE
	OD.			;LOOP FOR ALL MATCHING DIRS
	RET
	ENDSV.
	SUBTTL	TOP LEVEL PARSING

	CALL	TOPSLASH
TOPFDB:	FLDDB.	.CMTOK,,SLASH,,,TOPFD2

	CALL	TOPDDOT
TOPFD2:	FLDDB.	.CMTOK,,DDOTBP,,,TOPFD3

	CALL	TOPDOT
TOPFD3:	FLDDB.	.CMTOK,,DOTBP,,,TOPFD4

	CALL	TOPSUB
TOPFD4:	FLDDB.	.CMKEY,,TABLE,,,TOPFD5

	CALL	TOPUSR
TOPFD5:	FLDDB. .CMTOK,,<-1,,[ASCIZ '~']>,,,TOPFD6

	CALL	TOPDIR
TOPFD6:	FLDDB.	.CMDIR,,,,,TOPFD7

	CALL	TOPREV
TOPFD7:	FLDDB.	.CMTOK,,<-1,,[ASCIZ '^']>,,,TOPFD8

	CALL	TOPCFM
TOPFD8:	FLDDB.	.CMCFM

DOTOP:	CALL	CLRTAB

	SETZ	A,		;CURRENT DIR
	CALL	GETSUB		;FILL TABLE WITH SUBDIRS

	MOVEI	A, TOPFDB
	CALL	RFIELD
	XCT	-1(C)		;EXECUTE ACTION
	RET

;PARSED TOPS-20 DIR -- GET NUMBER IN A
TOPDIR:	MOVE	A, B
	CALL	DOLOOP
	RET

; PARSED TWIDDLE, GET USER NAME (OR NOT!)

	JFCL
USRFDB:	FLDDB.	.CMUSR,,,,,USRFD2

	PJRST	XDLOOP
USRFD2:	FLDDB.	.CMTOK,,<-1,,[ASCIZ '/']>,,,USRFD3

	RET
USRFD3:	FLDDB.	.CMCFM

TOPUSR:	STKVAR	<USERNO,<BUFFER,DIRSIZ/5>>
	MOVEI	A, USRFDB
	CALL	RFIELD		;PARSE USER
	MOVE	A, HOME		;GET HOME
	XCT	-1(C)		;DO ACTION

	MOVEM	B, USERNO	;SAVE NUMBER
	HRROI	A, BUFFER
	HLRZ	B, HOME		;GET STRUCURE OF OUR HOME
	HRLI	B, .DVDES	;MAKE DEVICE DESCR
	DEVST			;GET STRING
	 ERJMP	PSHOME
	MOVEI	B,":"
	IDPB	B, A
	MOVEI	B, "<"		;>
	IDPB	B, A
	MOVE	B, USERNO
	DIRST			;< TAKE DIR NAME FROM USER NUMBER
	 ERJMP	PSHOME
	MOVEI	B, ">"
	IDPB	B, A
	SETZ	B,
	IDPB	B, A
	HRROI	A, BUFFER
	CALL	CNVDIR		;CONVERT TO NUMBER
	 JRST	PSHOME
	PJRST	DOLOOP

PSHOME:	MOVE	A, USERNO	;GET USER NUMBER IN A
	HRLI	A, (PSDIR)	;MAKE INTO PS DIR
	PJRST	DOLOOP		;ENTER LOOP

; PARSED DOT
TOPDOT:	MOVE	A, CURR
	PJRST	DOLOOP

; PARSED DOUBLE DOT
TOPDDOT:
	MOVE	A, CURR		;GET CURRENT (CONNECTED DIR)
	CALL	GETPARENT	;GET ITS PARENT
	 JSHLT			; SIGH
	PJRST	DOLOOP		;PARSE MORE

; PARSED SUBDIR NAME
TOPSUB:	MOVE	A, CURR
	CALL	DOSUB
	PJRST	DOLOOP

; GOT '\' CONNECT TO PREV:
TOPREV:	SKIPN	A, PREV
	 MOVE	A, CURR
	PJRST	DOLOOP

;GOT CONFIRM... GO HOME
TOPCFM:	MOVE	A, HOME
	RET

; PARSED SLASH AT TOP LEVEL.. GO LOOK FOR STRUCTURES
TOPSLASH:
	ACVAR	<X>
	STKVAR	<TEMP,<BUFFER,DIRSIZ/5>>

	CALL	CLRTAB

	MOVE	A, [SIXBIT 'DEVCHR']
	SYSGT
	HLLZ	X, B		;GET AOBJN

	DO.
	 MOVSI	A, (X)		;GET TABLE INDEX
	 HRRI	A, .DEVCHR	;GET TABLE NUMBER
	 GETAB
	  RET
	 LDB	A, [POINTR A, DV%TYP] ;GET DEVICE TYPE
	 CAIE	A, .DVDSK	;STILL A DISK?
	  EXIT.			;DISKS COME FIRST

	 MOVSI	A, (X)		;GET INDEX AGAIN
	 HRRI	A, .DEVNAM	;GET NAME THIS TIME
	 GETAB			;FETCH!
	  RET
	 MOVEM	A, TEMP		;SAVE DEVICE NAME

	 CALL	STRBEG		;GET A STRING
	 HRLI	A, (POINT 7,)	;MAKE DEST BP
	 MOVE	B, [POINT 6,TEMP] ;GET SOURCE BP
	 MOVEI	D, 6		;MAXIMUM
	 DO.
	  ILDB	C, B		;GET A BYTE
	  JUMPE	C, ENDLP.	;TERMINATE ON SPACE
	  ADDI	C, 40		;MAKE ASCII
	  CAIG	C, "Z"		;IS UPPER?
	   CAIGE C, "A"
	    TRNA
	     ADDI C, "a"-"A"	;MAKE LOWER
	  IDPB	C, A		;STORE
	  SOJG	D, TOP.		;LOOP
	 OD.
	 SETZ	C,
	 IDPB	C, A		;TIE OFF
	 MOVEI	A, 1(A)		;ROUND
	 MOVEM	A, TEMP		;SAVE BP TO END

	 CALL	STRBEG		;GET STRING TOP AGAIN
	 HRROI	A, (A)		;MAKE BP
	 STDEV			;GET DEV DESCR
	  IFSKP.
	   MOVE	A, TEMP		;GET END OF STRING
	   CALL	STREND		;SAVE NEW STRING
	   HRLZ	B, A		;MAKE TABLE ENTRY
	   MOVEI A, TABLE	;GET TABLE ADDRESS
	   TBADD
	    ERJMP ENDLP.
	  ENDIF.
	 AOBJN	X, TOP.
	OD.

	MOVEI	A, TABLE
	MOVSI	B, [ASCIZ 'PS']	;ADD PS FOR SYSTEMS WITH
	TBADD			;OTHER PRIMARY STRUCTURE NAMES
	 ERJMP	.+1		;OK TO FAIL

;		*** PERHAPS ADD ALL LOGICALS??? ***

	MOVEI	A, [FLDDB. .CMKEY,,TABLE]
	CALL	RFIELD
	HRROI	A, BUFFER	;BP TO BUFFER
	HLRO	B, (B)		;BP TO DEVICE NAME
	SETZ	C,
	SOUT
	HRROI	B, [ASCIZ ':<ROOT-DIRECTORY>']
	SOUT

	HRROI	A, BUFFER
	CALL	CNVDIR
	 JSHLT

	CALL	DOLOOP
	RET
	ENDAV.
	ENDSV.

; GET NUMBER OF SUBDIR FROM NAME AND PARENT
; A/	DIR NUMBER OF PARENT
; B/	ADDRESS OF TBLUK TABLE ENTRY
;	CALL	DOSUB
;	<ALWAYS (OR JSHLT)>
; A/	SUBDIR NUMBER

DOSUB:	STKVAR	<DIRN,TABENT,<BUFFER,DIRSIZ/5>>
	MOVEM	A, DIRN		;SAVE DIRECTORY
	MOVEM	B, TABENT	;SAVE POINTER INTO TABLE

	HRROI	A, BUFFER	;GET BUFFER
	MOVE	B, DIRN		;GET SPECIFIED DIRECTORY
	DIRST			;CONVERT TO STRING
	 EJSHLT
	MOVEI	B, "."		;SMASH CLOSE WIDGET WITH DOT
	DPB	B, A		;STORE

	HLRO	B, @TABENT	;GET BP TO SUBDIR NAME
	SETZ	C,		;TERMINATOR
	SOUT			;COPY STRING INTO BUFFER <

	MOVEI	B, ">"		;CLOSE OFF DIR NAME
	IDPB	B, A
	SETZ	B,		;TIE OFF STRING
	IDPB	B, A

	HRROI	A, BUFFER	;GET FULL STRING
	CALL	CNVDIR		;GET DIR NUMBER
	 JSHLT
	RET
	ENDSV.

;;	FDBs FOR FIRST HALF OF LOOP

	JFCL
LOPFDB:	FLDDB.	.CMTOK,,SLASH,,,LOPFD2

	RET
LOPFD2:	FLDDB.	.CMCFM


;;	FDBs FOR SECOND HALF OF LOOP

	JRST	LOPDDOT
LP2FDB:	FLDDB.	.CMTOK,,DDOTBP,,,LP2FD2

	JRST	LOOP1
LP2FD2:	FLDDB.	.CMTOK,,DOTBP,,,LP2FD3

	JRST	LOPSUB
LP2FD3:	FLDDB.	.CMKEY,,TABLE,,,LP2FD4

	RET
LP2FD4:	FLDDB.	.CMCFM,CM%SDH

; JUST PARSED DIR NAME
; A/	DIR NUMBER

DOLOOP:	TDZA	B, B		;ENTER HERE FOR FIRST PART
XDLOOP:	 SETO	B,		;ENTER HERE FOR SECOND PART FIRST
	STKVAR	<DIRN,FLAG>
	MOVEM	B, FLAG
LOOP0:	MOVEM	A, DIRN
	AOSG	FLAG
	 JRST	LOOP2
LOOP1:	MOVEI	A, LOPFDB
	CALL	RFIELD
	MOVE	A, DIRN		;GET PASSED DIR
	XCT	-1(C)		;EXECUTE ACTION

; SECOND HALF OF LOOP
LOOP2:	CALL	CLRTAB		;CLEAR TABLE AND STRING SPACE
	MOVE	A, DIRN		;GET DIR NUMBER
	CALL	GETSUB		;FILL TABLE WITH SUBDIR NAMES

	MOVEI	A, LP2FDB	;GET SECOND HALF FDB CHAIN
	CALL	RFIELD		;READ A FIELD
	MOVE	A, DIRN		;GET CURRENT
	XCT	-1(C)		;DO ACTION
	HALT	.		;SHOULD NEVER HAPPEN

; SAW DOUBLE DOR
LOPDDOT:
	CALL	GETPARENT
	 JSHLT
	JRST	LOOP0

; SAW SUBDIR NAME
LOPSUB:	CALL	DOSUB		;PROCESS SUBDIR
	JRST	LOOP0
	ENDSV.

; GET PARENT DIR NUMBER GIVEN A DIR NUMBER
;
; IF CURRENT NOT A SUBDIR RETURNS <ROOT-DIRECTORY>
; (TRUE FOR <ROOT-DIRECTORY> ALSO)
;
; A/	DIR NUMBER
;	CALL	GETPARENT
;	 <ERROR>
;	<OK>
; A/	DIR NUMBER

GETPARENT:
	STKVAR	<DIRN,<BUFFER,DIRSIZ/5>>
	MOVEM	A, DIRN
	MOVE	B, A
	HRROI	A, BUFFER
	DIRST
	 ERJMP	R

	MOVEI	B, BUFFER
	HRLI	B, (POINT 7,)

	DO.
	 ILDB	A, B		;GET A CHAR
	 JUMPE	A, R		;EOS??
	 CAIE	A, "<"		;> START OF DIR?
	  LOOP.			;NO, KEEP LOOKING
	OD.

	SETZ	C,		;BP TO AFTER LAST DOT
	DO.
	 ILDB	A, B		;GET NEXT
	 JUMPE	A, ENDLP.	;GOT TO END
	 CAIN	A, "."		;DOT?
	  MOVE	C, B		; YES, SAVE BP
	 LOOP.
	OD.

	IFN.	C		;SAW A DOT?
	 SETO	B,		;BACK UP BY ONE
	 ADJBP	B, C		;GET NEW BP IN B <
	 MOVEI	A, ">"		;TERMINATE DIR HERE
	 IDPB	A, B		;STORE
	 SETZ	A,		;GET NUL
	 IDPB	A, B		;TIE OFF STRING

	 HRROI	A, BUFFER	;GET BUFFER
	 CALL	CNVDIR		;CONVERT TO NUMBER
	  RET			; ERROR
	ELSE.			;SAW NO DOTS...
	 MOVE	A, DIRN		;GET DIR BACK
	 HRRI	A, ROOTD	;RETURN ROOT-DIRECTORY ON THAT STR
	ENDIF.

	RETSKP
	ENDSV.

; CONVERT DIRECTORY STRING TO NUMBER
;
; A/	BP
;	CALL	CNVDIR
;	 <SOME ERROR>
;	<OK>
; A/	NUMBER

CNVDIR:	MOVE	B, A
	MOVSI	A, (RC%EMO)	;MUST BE EXACT
	RCDIR			;TRANSLATE BACK TO NUMBER
	 ERJMP	R		; SIGH
	TLNE	A, (RC%NOM!RC%AMB) ;NO MATCH OR AMBIGUOUS
	 RET			; ERROR
	MOVE	A, C		;GET NUMBER IN A
	RETSKP

; A/	DIRNUM
; B/	BP TO PASSWORD (OR 0)
;	CALL	CONNECT
;	 <ERROR>
;	<OK>

CONNECT:
	STKVAR	<<BLK,3>>
	DMOVEM	A, BLK
	SETOM	.ACJOB+BLK
	MOVE	A, [AC%CON!3]
	MOVEI	B, BLK
	ACCES			;TRY TO CONNECT
	 ERJMP	R
	RETSKP

				;[
BRCRLF:	MOVEI	A, "]"
	PBOUT
CRLF:	TMSG	<
>
	RET

NOECHO:	MOVEI	A, .PRIOU
	RFMOD
	TRZ	B, TT%ECO
	SFMOD
	RET

ECHO:	MOVEI	A, .PRIOU
	RFMOD
	TRO	B, TT%ECO
	SFMOD
	RET

; A/	BP TO NAME
; B/	DIR NUMBER FOR DEFN
LOGNAM:	STKVAR	<NAME,<BUFFER,DIRSIZ/5>>
	MOVEM	A, NAME		;SAVE NAME
	HRROI	A, BUFFER
	DIRST			;XLATE DIR NUMBER TO STRING
	 ERJMP	R

	MOVEI	A, .CLNJB
	MOVE	B, NAME		;GET NAME BACK
	HRROI	C, BUFFER
	CRLNM			;CREATE LOGICAL FOR JOB
	 RET			;FAILED
	RETSKP			;SUCCESS!
	SUBTTL	COMND ROUTINES

; A/	REPARSE ADDRESS / FLAGS
; B/	PROMPT BP
CMDINI:	MOVEM	A, CSB+.CMFLG
	MOVEM	B, CSB+.CMRTY

	MOVE	A, [.PRIIN,,.PRIOU]
	MOVEM	A, CSB+.CMIOJ	;JFNS

	HRROI	A, CMDBUF
	MOVEM	A, CSB+.CMBFP	;COMMAND BUFFER
	MOVEM	A, CSB+.CMPTR	;POINTER TO NEXT FIELD

	MOVEI	A, CMDLEN	;ROOM LEFT
	MOVEM	A, CSB+.CMCNT
	SETZM	CSB+.CMINC	;CHARS TO BE PARSED

	MOVEI	A, CMDGTJ	;GETJFN BLOCK
	MOVEM	A, CSB+.CMGJB

	HRROI	A, ATMBUF	;ATOM BUFFER
	MOVEM	A, CSB+.CMABP
	MOVEI 	A, ATMLEN
	MOVEM	A, CSB+.CMABC
	RET

RFIELD:	CALL	RFLDE		;PARSE WITH ERROR RETURN
	 PJRST	CMDERR
	RET

ERRLEN==^D10
CMDERR:	STKVAR	<<BUF,ERRLEN>>
	HRROI	A, BUF		;GET BUFFER
	HRLOI	B, .FHSLF	;SELF,,LAST ERROR
	MOVSI	C, ERRLEN*5-1
	ERSTR
	 TRNA
	  JFCL
	HRROI	A, BUF
	ESOUT
	JRST	DIE
	ENDSV.

RFLDE:	MOVE	B, A		;GET FDB IN B
	MOVEI	A, CSB		;CSB IN A
	COMND
	 ERJMP	R
	TLNE	A, (CM%NOP)	;NO PARSE?
	 RET
	RETSKP

LITTER:	END	START
