NEW
  AUTO 3,1
				.LIST OFF
				.OP	65C02
				.OR	$2000
				.TF SBIN/TELNETD
*--------------------------------------
				.INB INC/MACROS.I
				.INB INC/A2OSX.I
				.INB INC/ETH.I
				.INB INC/LIBTCPIP.I
				.INB INC/NET.TELNET.I
*--------------------------------------
CONN.MAX		.EQ 16
TIMEOUT.MAX		.EQ 200					20 sec.
*--------------------------------------
				.DUMMY
				.OR ZPBIN
ZS.START
ZPIPCfgPtr		.BS 2
ZPSktPtr		.BS 2
TimeOut			.BS 1
ZS.END
				.ED
*--------------------------------------
*			File Header (16 Bytes)
*--------------------------------------
CS.START		cld
				jmp (.1,x)
				.DA #$61				6502,Level 1 (65c02)
				.DA #1					BIN Layout Version 1
				.DA #S.PS.F.EVENT		S.PS.F
				.DA #0
				.DA CS.END-CS.START		CS
				.DA DS.END-DS.START		DS
				.DA #64					SS
				.DA #4					ZP				SS
				.DA 0
*--------------------------------------
* Relocation Table
*--------------------------------------				
.1				.DA CS.INIT
				.DA CS.RUN
				.DA CS.DOEVENT
				.DA	CS.QUIT
L.LIBTCPIP		.DA LIBTCPIP
L.SA.LOCAL		.DA SA.LOCAL
L.MSG.TCPWAIT	.DA MSG.TCPWAIT
L.MSG.INITOK	.DA MSG.INITOK
L.MSG.TCPIPERR	.DA MSG.TCPIPERR
L.MSG.SKTERR	.DA MSG.SKTERR
L.MSG.ABORT		.DA MSG.ABORT
L.MSG.INCOMING	.DA MSG.INCOMING
L.MSG.EXECERR	.DA MSG.EXECERR
L.NOD.Template	.DA NOD.Template
L.CMD.Template	.DA CMD.Template
				.DA 0				
*--------------------------------------
CS.INIT			>LDYA L.LIBTCPIP
				>SYSCALL LoadLib
				bcs .9
				sta hLIBTCPIP

.9				rts
*--------------------------------------
CS.RUN			lda #TIMEOUT.MAX
				sta TimeOut
				
				>LDYA L.MSG.TCPWAIT
				>SYSCALL puts
				
.1				>SLEEP
				
				>LIBCALL hLIBTCPIP,LIBTCPIP.GETCFG	is TCPIP loaded ?
				bcs .99
				>STYA ZPIPCfgPtr
				
				lda (ZPIPCfgPtr)		Configured ?
				bmi CS.RUN.INIT
				
				lda Timeout
				beq .99
				
				ldy #S.PS.hStdIn
				lda (pPs),y
				>SYSCALL feof
				bcs .9					I/O err
				
				tay
				bne .1
				
				>SYSCALL GetChar
				bcs .9
				
				cmp #$03
				bne .1
				jmp CS.RUN.ABORT
				
.99				pha
				>LDYA L.MSG.TCPIPERR
				>SYSCALL puts
				pla
				sec	
.9				rts
				
CS.RUN.INIT		ldx #3
				ldy #S.IPCFG.IP+3

.1				lda (ZPIPCfgPtr),y
				sta SA.LOCAL+S.SOCKADDR.ADDR,x
				dey
				dex
				bpl .1
				
				lda #1
				>SYSCALL ArgV
				bcs CS.RUN.PORTOK
				
				>SYSCALL atoi
				>STYA SA.LOCAL+S.SOCKADDR.PORT
				
CS.RUN.PORTOK	>PUSHBI 0				no protocol
				lda #S.SOCKET.T.STREAM
				>LIBCALL hLIBTCPIP,LIBTCPIP.Socket
				bcs .9

				>STA.G hSrvSocket
				pha
				>PUSHW L.SA.LOCAL
				pla
				>LIBCALL hLIBTCPIP,LIBTCPIP.Bind
				bcs .9
				
				>LDA.G hSrvSocket
				>LIBCALL hLIBTCPIP,LIBTCPIP.Listen
				bcs .9
				
				>LDYA L.MSG.INITOK
				>SYSCALL puts

.2				>SLEEP

				>LDA.G hSrvSocket
				>LIBCALL hLIBTCPIP,LIBTCPIP.Accept
				bcs .2
				
				jsr CS.RUN.SERVER
				bcc .2
				rts
				
.9				pha
				>LDYA L.MSG.SKTERR
				>SYSCALL puts
				pla
				sec	
				rts
				
CS.RUN.ABORT	>LDYA L.MSG.ABORT
				>SYSCALL puts
				lda #3
				
				sec	
				rts
*--------------------------------------
CS.RUN.SERVER	pha
				ldy #hSockets
				ldx #CONN.MAX
				
.1				lda (pData),y
				bne .2
				pla
				sta (pData),y
				
				bra CS.RUN.CLIENT
				
.2				iny
				dex
				bne .1
				
				pla
				>LIBCALL hLIBTCPIP,LIBTCPIP.Shutdown
.8				clc
				rts
*--------------------------------------
CS.RUN.CLIENT	>SLEEP					give some time for TCPIP SYN/ACK

				>STA.G hClientSocket
				>SYSCALL GetMemPtr
				>STYA ZPSktPtr

				ldx #3
				ldy #S.SOCKET.REM.ADDR+3
				
.3				>PUSHB (ZPSktPtr),y
				dey
				dex
				bpl .3
				
				>PUSHB.G hClientSocket

				>PUSHBI 5
				>LDYA L.MSG.INCOMING
				>SYSCALL printf
				
				>PUSHB.G hClientSocket
				>PUSHBI 1
				>PUSHW L.NOD.Template
				>LEA.G NodBuf
				>SYSCALL sprintf
				
				>PUSHB.G hClientSocket
				>PUSHW 0
				>LEA.G NodBuf
				>SYSCALL mknod
				bcs .9
				>STA.G hClientFile
				
				>PUSHEA.G NodBuf
				>PUSHBI 2
				>PUSHW L.CMD.Template
				>LEA.G CmdBuf
				>SYSCALL sprintf
				
				>PUSHBI 0
				>LEA.G CmdBuf
				>SYSCALL execl
				bcc .8

				>PUSHA
				>PUSHBI 1
				>LDYA L.MSG.EXECERR
				>SYSCALL printf

.8				clc
.9				rts
*--------------------------------------
CS.DOEVENT		lda (pEvent)
				bpl .9					is it a TIMER event?
				
				lda TimeOut
				beq .9
				
				dec TimeOut
				
.9				sec						do not discard TIMER event
				rts
*--------------------------------------
CS.QUIT			ldx #CONN.MAX
				ldy #hSockets
				
.1				lda (pData),y
				beq .2
				
				phx
				phy
				>LIBCALL hLIBTCPIP,LIBTCPIP.Shutdown
				ply
				plx
				
.2				iny
				dex
				bne .1
				
				>LDA.G hSrvSocket
				beq .3
				>LIBCALL hLIBTCPIP,LIBTCPIP.Shutdown
				
.3				lda hLIBTCPIP
				beq .8
				>SYSCALL UnloadLib

.8				clc
				rts
*--------------------------------------
CS.END
*--------------------------------------
hLIBTCPIP		.BS 1
LIBTCPIP		.AZ "libtcpip"
MSG.TCPWAIT		.AZ "TELNETD:Waiting for TCP/IP initializing..."
MSG.INITOK		.AZ "TELNETD:Init Ok, Listening."
MSG.TCPIPERR	.AZ "TELNETD:TCP/IP Not initialized properly."
MSG.SKTERR		.AZ "TELNETD:Listen Error."
MSG.ABORT		.AZ "TELNETD:User Aborted."
MSG.INCOMING	.AZ "TELNETD:Incoming Connection [SKT=%h] From : %d.%d.%d.%d\r\n"
MSG.EXECERR		.AZ "TELNETD:ExecL failed $%h."
*--------------------------------------
NOD.Template	.AZ "/DEV/TTY%h"
CMD.Template	.AZ "${ROOT}SBIN/GETTY -E %s ${ROOT}SBIN/LOGIN"
*--------------------------------------
SA.LOCAL		.DA #AF.INET			S.SOCKADDR.AF
				.BS 1
				.BS 4					S.SOCKADDR.ADDR
				.DA TCP.PORT.TELNET
*--------------------------------------
				.DUMMY
				.OR 0
DS.START
hSockets		.BS	CONN.MAX			pData
SktIndex		.BS 1
hSrvSocket		.BS 1
hClientSocket	.BS 1
hClientFile		.BS 1
NodBuf			.BS 11
CmdBuf			.BS 65
DS.END
				.ED
*--------------------------------------
MAN
SAVE USR/SRC/SBIN/TELNETD.S
ASM
