NEW
  AUTO 3,1
				.LIST OFF
				.OP	65C02
				.OR	$2000
				.TF sbin/login
*--------------------------------------
				.INB INC/MACROS.I
				.INB INC/A2OSX.I
				.INB INC/KERNEL.I
				.INB INC/MLI.I
*--------------------------------------
				.DUMMY
				.OR ZPBIN
ZS.START
ZPhBuf			.BS 1
ZPBufPtr		.BS 2

ZPRetryCnt		.BS 1
ZPbValidUser	.BS 1
ZPUID			.BS 1

ZPhGetLine		.BS 1
ZPGetLinePtr	.BS 2
ZPbGetLineSecret	.BS 1
ZPbEsc			.BS 1
ZPGetLineLen	.BS 1
ZPGetLineMax	.BS 1

ZPhPW			.BS 1
ZPPWPtr			.BS 2

hSession		.BS 1
ZPNewSID		.BS 1
ZPOldSID		.BS 1

ZPhFile			.BS 1
ZPStrPtr		.BS 2
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		Code Size (without Constants)
				.DA DS.END-DS.START		Data Segment Size
				.DA #32					Stack Size
				.DA #ZS.END-ZS.START	Zero Page Size
				.DA 0
*--------------------------------------
* Relocation Table
*--------------------------------------
.1				.DA CS.INIT
				.DA CS.RUN
				.DA CS.DOEVENT
				.DA	CS.QUIT
L.MSG.NOAUTH	.DA MSG.NOAUTH
L.MSG.LOGIN		.DA MSG.LOGIN
L.MSG.PASSWORD	.DA MSG.PASSWORD
L.MSG.BAD		.DA MSG.BAD
L.MSG.CRLF		.DA MSG.CRLF
L.MSG.BS		.DA MSG.BS
L.ETCISSUE		.DA ETCISSUE
L.ETCMOTD		.DA ETCMOTD
L.SHELL			.DA SHELL
				.DA 0
*--------------------------------------
CS.INIT			clc
CS.INIT.RTS		rts
*--------------------------------------
CS.RUN			>LDYAI 33				Enough for HASH
				>SYSCALL getmem
				bcs CS.INIT.RTS

				>STYA ZPGetLinePtr
				stx ZPhGetLine

				>LDYA L.ETCISSUE
				jsr CS.RUN.DUMPFILE

				lda #0
				>PUSHA					ROOT user
				>PUSHWZ					Dry Run, no output
				>SYSCALL GetPWUID
				bcc CS.RUN.AUTH			

				>LDYA L.MSG.NOAUTH
				jsr CS.RUN.StrOut
				bcs .9
				
				ldy #S.PS.hSID
				lda (pPS),y
				tax
				
				lda S.Table.hSession-1,x
				sta hSession

				jmp CS.RUN.EXEC
.9				rts
*--------------------------------------
CS.RUN.AUTH		lda #3
				sta ZPRetryCnt

.1				>LDYA L.MSG.LOGIN
				jsr CS.RUN.StrOut
				bcs .9

				lda #16
				clc
				jsr CS.RUN.GetLine
				bcs .9

				>PUSHWZ					Dry Run
				>LDYA ZPGetLinePtr
				>SYSCALL GetPWName
				ror ZPbValidUser
				sta ZPUID

				>LDYA L.MSG.PASSWORD
				jsr CS.RUN.StrOut
				bcs .9
				lda #32
				sec
				jsr CS.RUN.GetLine
				bcs .9

				>LDYA L.MSG.CRLF
				jsr CS.RUN.StrOut
				bcs .9

				jsr CS.RUN.CHECKPWD
				bcs .8
				jsr CS.RUN.SetUserSession
				bcs .9

				jmp CS.RUN.EXEC

.8				>LDYA L.MSG.BAD
				>SYSCALL puts
				bcs .9

				dec ZPRetryCnt
				beq .99

				jmp .1

.99				lda #E.IUSR
				sec
.9				rts
*--------------------------------------
CS.RUN.SetUserSession
				ldx #S.SESSION.NAME		P+UID+GID
				ldy #S.PW.NAME-1
				jsr CS.RUN.AddStrLen	NAME len
				inx
				ldy #S.PW.GECOS-1
				jsr CS.RUN.AddStrLen	GECOS len
				inx
				ldy #S.PW.DIR-1
				jsr CS.RUN.AddStrLen	DIR len
				inx

				ldy #S.PW.SHELL-1
				jsr CS.RUN.AddStrLen	SHELL len

				txa
				tay
				lda #0
				>SYSCALL getmem
				bcs .9

				>STYA ZPStrPtr
				stx hSession

*				clc

				ldy #S.PW.GID
				lda (ZPPWPtr),y
				tax
				bne .5
				sec
.5				ldy #S.PW.UID
				lda (ZPPWPtr),y
				bne .6
				sec
.6				lda #0
				ror
				jsr CS.RUN.AddByte			PRIV
				lda (ZPPWPtr),y
				jsr CS.RUN.AddByte			UID
				txa
				jsr CS.RUN.AddByte			GID
				ldy #S.PW.NAME
				jsr CS.RUN.AddStr
				ldy #S.PW.GECOS
				jsr CS.RUN.AddStr
				ldy #S.PW.DIR
				jsr CS.RUN.AddStr
				ldy #S.PW.SHELL
				jsr CS.RUN.AddStr
				lda #0
				jsr CS.RUN.AddByte

				clc
.9				rts
*--------------------------------------
CS.RUN.CHECKPWD	rol ZPbValidUser
				bcs CS.RUN.CHECK.9

				>LDYAI S.PW
				>SYSCALL getmem
				bcs CS.RUN.CHECK.9

				>STYA ZPPWPtr
				stx ZPhPW

				pha
				>PUSHB ZPUID
				pla
				>PUSHYA
				>SYSCALL GetPWUID
				bcs CS.RUN.CHECK.9

				>PUSHW ZPGetlinePtr
				>PUSHW ZPGetlinePtr
				>SYSCALL MD5
				
				lda ZPPWPtr
				clc
				adc #S.PW.PASSWD
				tay
				lda ZPPWPtr+1
				adc /S.PW.PASSWD
				
				>PUSHYA
				>LDYA ZPGetlinePtr
				>SYSCALL strcmp
				bcc CS.RUN.CHECK.9
				
				jsr CS.CLEANUP.hPW
				
				sec

CS.RUN.CHECK.9	rts
*--------------------------------------
CS.RUN.EXEC		ldx #1

.1				lda S.Table.hSession-1,x
				beq .2

				inx
				cpx #K.USR.MAX+1
				bne .1

				lda #E.OOH
*				sec
				rts	

.2				stx ZPNewSID
				ldy #S.PS.hSID
				lda (pPS),y
				sta ZPOldSID
				
				txa
				sta (pPS),y

				lda hSession
				sta S.Table.hSession-1,x

				ldy #S.PS.hStdIn
				lda (pPS),y
				sta S.Table.hFILE-1,x

				>LDYA L.ETCMOTD
				jsr CS.RUN.DumpFile
				jsr CS.CLEANUP

				>PUSHW L.SHELL
				>PUSHBI S.PS.F.HOLD
				>SYSCALL ExecL
				bcs .9

				>SLEEP
				ldx ZPNewSID
				lda S.Table.hSession-1,x
				stz S.Table.hSession-1,x
				stz S.Table.hFILE-1,x
				>SYSCALL freemem
				
				ldy #S.PS.hSID
				lda ZPOldSID
				sta (pPS),y
				
				sec
.9				rts
*--------------------------------------
CS.RUN.AddStrLen
.1				inx
				iny
				lda (ZPPWPtr),y
				bne .1
				rts
*--------------------------------------
CS.RUN.AddStr	lda (ZPPWPtr),y
				jsr CS.RUN.AddByte
				iny
				tax
				bne CS.RUN.AddStr
				rts
*--------------------------------------
CS.RUN.AddByte	sta (ZPStrPtr)
				inc ZPStrPtr
				bne .8
				inc ZPStrPtr+1
.8				rts
*--------------------------------------
CS.RUN.GetLine	sta ZPGetLineMax
				ror ZPbGetLineSecret
				stz ZPGetLineLen
				stz ZPbEsc

.1				>SYSCALL getchar
				bcs .9

				bit ZPbEsc
				bpl .11

*				clc
				ror ZPbEsc
				cmp #'D'
				bne .1

				bra .3

.11				cmp #C.DEL
				beq .3

				cmp #C.SPACE
				bcc .2

				ldy ZPGetLineLen
				cpy ZPGetLineMax
				beq .1

				sta (ZPGetLinePtr),y
				inc ZPGetLineLen
				bit ZPbGetLineSecret
				bmi .1

				>SYSCALL putchar
				bra .1

.2				cmp #3					Ctrl-C
				beq .9

				cmp #C.CR
				beq .8

				cmp #C.ESC
				bne .1

*				sec
				ror ZPbEsc
				bra .1

.3				ldy ZPGetLineLen
				beq .1

				dec ZPGetLineLen
				bit ZPbGetLineSecret
				bmi .1

				>LDYA L.MSG.BS
				jsr CS.RUN.StrOut
				bra .1

.8				ldy ZPGetLineLen
				lda #0
				sta (ZPGetLinePtr),y
				clc
.9				rts	
*--------------------------------------
CS.RUN.StrOut	>PUSHYA
				>PUSHBI 0
				>SYSCALL printf
				rts
*--------------------------------------
CS.RUN.DumpFile	>PUSHYA
				>PUSHBI	O.RDONLY+O.TEXT
				>PUSHBI S.FI.T.TXT
				>PUSHWZ				Aux type
				>SYSCALL FOpen
				bcs .9

				stx ZPhFile		
				>LDYAI 256
				>SYSCALL getmem
				bcs .99

				>STYA ZPBufPtr
				stx ZPhBuf

.1				>PUSHWI	256
				>PUSHW ZPBufPtr
				lda ZPhFile
				>SYSCALL fgets
				bcs .7

				>PUSHW ZPBufPtr
				>PUSHWI 0
				>SYSCALL Expand
				bcc .2

.99				php
				pha
				jsr .8
				pla
				plp
.9				rts

.2				phx
				>SYSCALL puts
				pla
				>SYSCALL freemem
				bra .1

.7 				lda ZPhBuf
				>SYSCALL freemem

.8				lda ZPhFile
				>SYSCALL fclose
				rts
*--------------------------------------
CS.DOEVENT		
				sec
				rts		
*--------------------------------------
CS.QUIT			
CS.CLEANUP		lda ZPhGetLine
				beq CS.CLEANUP.hPW

				stz ZPhGetLine
				>SYSCALL freemem

CS.CLEANUP.hPW	lda ZPhPW
				beq .8
				
				stz ZPhPW
				>SYSCALL freemem

.8				clc
				rts
*--------------------------------------
CS.END
*--------------------------------------
MSG.NOAUTH		.AS "\r\n\r\nA2osX-Login:No ETC/PASSWD file present, Logged as ROOT.\r\n"
				.AS "Consider adding ROOT password with USERADD command.\r\n"
MSG.CRLF		.AZ "\r\n"
MSG.LOGIN		.AZ "\r\nlogin:"
MSG.PASSWORD	.AZ "\r\npassword:"
MSG.BAD			.AZ "Bad user or password"
MSG.BS			.DA #C.BS,#C.SPACE,#C.BS,#0
ETCISSUE		.AZ "${ROOT}etc/issue"
ETCMOTD			.AZ "${ROOT}etc/motd"
SHELL			.AZ "${SHELL}"
*--------------------------------------
				.DUMMY
				.OR 0
DS.START
DS.END			.ED
*--------------------------------------
MAN
SAVE USR/SRC/SBIN/LOGIN.S
ASM
