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
				.INB INC/LIBCRYPT.I
*--------------------------------------
				.DUMMY
				.OR ZPBIN
ZS.START
ZPUsrID			.BS 1

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

ZPhSID			.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 #64					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.LIBCRYPT		.DA LIBCRYPT
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.SESSION.ROOT	.DA SESSION.ROOT
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

				>PUSHWZ				Dry Run, no output
*				lda #0					ROOT user
				>SYSCALL GetPWUID
				bcc CS.RUN.AUTH			
*--------------------------------------
CS.RUN.NOAUTH	>PUSHBI 0
				>LDYA L.MSG.NOAUTH
				>SYSCALL printf
				bcs .9
				
				jsr CS.RUN.SetRootSession
				bcs .9
				
				jmp CS.RUN.EXEC
.9				rts				
*--------------------------------------
CS.RUN.AUTH		>LDYA L.LIBCRYPT
				>SYSCALL LoadLib
				bcs CS.INIT.RTS
				
				sta hLIBCRYPT

				lda #3
				sta ZPRetryCnt

.1				>PUSHBI 0
				>LDYA L.MSG.LOGIN
				>SYSCALL printf
				bcs .9
				
				lda #16
				clc
				jsr CS.RUN.GetLine
				bcs .9

				>PUSHWZ					Dry Run
				>LDYA ZPGetLinePtr
				>SYSCALL GetPWName
				ror ZPbValidUser
				sta ZPUID
				
				>PUSHBI 0
				>LDYA L.MSG.PASSWORD
				>SYSCALL printf
				bcs .9
				
				lda #32
				sec
				jsr CS.RUN.GetLine
				bcs .9

				>PUSHBI 0
				>LDYA L.MSG.CRLF
				>SYSCALL printf
				bcs .9

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

				jmp CS.RUN.EXEC
				
.8				>PUSHBI 0
				>LDYA L.MSG.BAD
				>SYSCALL printf
				bcs .9
				
				dec ZPRetryCnt
				beq .99
				
				jmp .1
				
.99				lda #E.IUSR
				sec				
.9				rts
*--------------------------------------
CS.RUN.SetRootSession
				>LDYA L.SESSION.ROOT
				>STYA ZPStrPtr
		
				>LDYAI SESSION.ROOT.Size			
				>SYSCALL getmem
				bcs .9
				>STYA pSession
				stx ZPhSID
				
				ldy #SESSION.ROOT.Size-1
				
.1				lda (ZPStrPtr),y
				sta (pSession),y
				dey
				bpl .1
				
*				clc
.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 pSession
				>STYA ZPStrPtr

				stx ZPhSID

*				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
				
				>PUSHYA
				lda ZPUID
				>SYSCALL GetPWUID
				bcs CS.RUN.CHECK.9

				>PUSHW ZPGetlinePtr
				>PUSHW ZPGetlinePtr
				>LIBCALL hLIBCRYPT,LIBCRYPT.MD5
				
				lda ZPPWPtr
				clc
				adc #S.PW.PASSWD
				tay
				lda ZPPWPtr+1
				adc /S.PW.PASSWD
				>PUSHYA
				
				>LDYA ZPGetlinePtr
				>SYSCALL strcmp

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 ZPUsrID
				txa
				
				ldy #S.PS.hSID
				sta (pPS),y
				
				lda ZPhSID
				ldx ZPUsrID
				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

				>PUSHBI S.PS.F.HOLD
				>LDYA L.SHELL
				>SYSCALL ExecL
				bcs .9
				
				>SLEEP
				
				ldx ZPUsrID
				lda S.Table.hSession-1,x
				stz S.Table.hSession-1,x
				stz S.Table.hFILE-1,x
				>SYSCALL freemem
				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
				
				>PUSHBI 0
				>LDYA L.MSG.BS
				>SYSCALL printf
				bra .1
				
.8				ldy ZPGetLineLen
				lda #0
				sta (ZPGetLinePtr),y
				
				clc
				
.9				rts	
*--------------------------------------
CS.RUN.DumpFile	pha

				>PUSHWZ				Aux type
				>PUSHBI S.FI.T.TXT
				>PUSHBI	O.RDONLY+O.TEXT
				
				pla
				>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
				
				>LDYA ZPBufPtr
				>SYSCALL ExpandStr
				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			lda hLIBCRYPT
				beq CS.CLEANUP
				
				>SYSCALL UnloadLib
				
CS.CLEANUP		lda ZPhGetLine
				beq .1
				stz ZPhGetLine
				>SYSCALL freemem
				
.1				lda ZPhPW
				beq .8
				stz ZPhPW
				>SYSCALL freemem
				
.8				clc
				rts
*--------------------------------------
CS.END
*--------------------------------------
LIBCRYPT		.AZ "libcrypt"
hLIBCRYPT		.BS 1
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\r\n"
MSG.BS			.DA #C.BS,#C.SPACE,#C.BS,#0
ETCISSUE		.AZ "${ROOT}ETC/ISSUE"
ETCMOTD			.AZ "${ROOT}ETC/MOTD"
SHELL			.AZ "${SHELL}"
*--------------------------------------
SESSION.ROOT	.DA #S.SESSION.P.ROOT
				.DA #0					UID
				.DA #0					GID
				.AZ "ROOT"				NAME
				.AZ "Root User"			GECOS
				.AZ "${ROOT}ROOT/"		DIR
				.AZ "${ROOT}BIN/SH"		SHELL
SESSION.ROOT.Size	.EQ	*-SESSION.ROOT
*--------------------------------------
				.DUMMY
				.OR 0
DS.START
DS.END
				.ED
*--------------------------------------
MAN
SAVE USR/SRC/SBIN/LOGIN.S
ASM
