NEW AUTO 3,1 .LIST OFF .OP 65C02 .OR $2000 .TF bin/useradd *-------------------------------------- USER.MAX .EQ 16 PASS.MAX .EQ 64 *-------------------------------------- .INB inc/macros.i .INB inc/a2osx.i *-------------------------------------- * Zero Page Segment, up to 32 bytes *-------------------------------------- .DUMMY .OR ZPBIN ZS.START ZPPWPtr .BS 2 ZPhPW .BS 1 ZPhStr .BS 1 ZPbStrSecret .BS 1 ZPStrLen .BS 1 ZPStrMax .BS 1 ArgIndex .BS 1 ArgUsername .BS 1 ZPStrPtr .BS 2 ZPTmpPtr .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 #0 S.PS.F.EVENT .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.USAGE .DA MSG.USAGE L.MSG.ROOTPWD1 .DA MSG.ROOTPWD1 L.MSG.ROOTPWD2 .DA MSG.ROOTPWD2 L.MSG.MISMATCH .DA MSG.MISMATCH L.MSG.CRLF .DA MSG.CRLF L.MSG.BS .DA MSG.BS J.CS.RUN.CheckArg .DA CS.RUN.CheckArg.C .DA CS.RUN.CheckArg.D .DA CS.RUN.CheckArg.P .DA CS.RUN.CheckArg.S .DA 0 *-------------------------------------- * Called once at process creation * Put code for loading LIB here *-------------------------------------- CS.INIT clc rts *-------------------------------------- * Called until exit with CS * if RUN exits with CC, RN entered again *-------------------------------------- CS.RUN >LDYAI S.PW >SYSCALL GetMem bcs .99 >STYA ZPPWPtr stx ZPhPW >LDYAI 256 >SYSCALL GetMem bcs .99 >STYA ZPStrPtr stx ZPhStr lda #0 >PUSHA >PUSHW ZPPWPtr >SYSCALL GetPWUID bcc .1 jmp CS.RUN.ROOT .1 ldy #S.PW .2 dey lda PW.DEFAULT,y sta (pData),y tya bne .2 jsr CS.RUN.CheckArg bcs .9 jsr CS.RUN.MkDir * bcs .99 >PUSHW pData >SYSCALL PutPW bcs .99 lda #0 sec rts .9 >LDYA L.MSG.USAGE >SYSCALL PutS lda #E.SYN sec .99 rts *-------------------------------------- CS.RUN.ROOT ldy #0 .1 lda PW.ROOT,y sta (pData),y PW iny cpy #S.PW bne .1 sec ror ZPbStrSecret lda #127 sta ZPStrMax >PUSHW L.MSG.ROOTPWD1 >PUSHBI 0 >SYSCALL PrintF bcs .90 jsr CS.RUN.GetStr bcs .90 >PUSHW ZPStrPtr >PUSHEA.G PW+S.PW.PASSWD >SYSCALL MD5 >PUSHW L.MSG.ROOTPWD2 >PUSHBI 0 >SYSCALL PrintF bcs .9 jsr CS.RUN.GetStr .90 bcs .9 >PUSHW ZPStrPtr >PUSHW ZPStrPtr >SYSCALL MD5 >PUSHW ZPStrPtr >PUSHEA.G PW+S.PW.PASSWD >SYSCALL StrCmp bcs .99 >PUSHW pData >SYSCALL PutPW bcs .9 lda #0 sec .9 rts .99 >LDYA L.MSG.MISMATCH >SYSCALL PutS lda #E.SYN sec rts *-------------------------------------- CS.RUN.GetStr stz ZPStrLen .1 >SYSCALL GetChar bcs .9 cmp #C.SPACE bcc .2 ldy ZPStrLen cpy ZPStrMax beq .1 bit ZPbStrSecret bmi .10 jsr CS.RUN.IsValidChar bcs .1 .10 sta (ZPStrPtr),y iny sty ZPStrLen bit ZPbStrSecret bmi .1 >SYSCALL PutChar bra .1 .2 cmp #3 Ctrl-C beq .9 cmp #C.CR beq .8 cmp #C.BS bne .1 ldy ZPStrLen beq .1 dec ZPStrLen bit ZPbStrSecret bmi .1 >PUSHW L.MSG.BS >PUSHBI 0 >SYSCALL PrintF bra .1 .8 ldy ZPStrLen lda #0 sta (ZPStrPtr),y >PUSHW L.MSG.CRLF >PUSHBI 0 >SYSCALL PrintF .9 rts *-------------------------------------- CS.RUN.CheckArg inc ArgIndex lda ArgIndex >SYSCALL ArgV bcs .8 >STYA ZPStrPtr lda (ZPStrPtr) cmp #'-' bne .4 ldy #1 lda (ZPStrPtr),y ldx #OptionCnt-1 .2 cmp OptionList,x beq .3 dex bpl .2 lda #E.SYN sec rts .3 txa and #$fe tax jmp (J.CS.RUN.CheckArg,x) *-------------------------------------- .4 lda ArgUsername bne CS.RUN.CheckArg.9 lda pData clc adc #S.PW.DIR+11 sta ZPTmpPtr lda pData+1 adc /S.PW.DIR+11 sta ZPTmpPtr+1 stz ZPbStrSecret ldy #0 .5 lda (ZPStrPtr),y sta (pData),y sta (ZPTmpPtr),y beq .6 jsr CS.RUN.IsValidChar bcs CS.RUN.CheckArg.9 iny cpy #16 bne .5 bra CS.RUN.CheckArg.9 .6 lda #'/' sta (ZPTmpPtr),y lda ArgIndex sta ArgUsername >SYSCALL ArgV >PUSHYA >PUSHW ZPPWPtr >SYSCALL GetPWName bcc .9 jmp CS.RUN.CheckArg .8 lda ArgUsername beq CS.RUN.CheckArg.9 clc rts .9 lda #E.DUPUSR sec rts CS.RUN.CheckArg.9 lda #E.SYN sec rts *-------------------------------------- CS.RUN.CheckArg.P inc ArgIndex lda ArgIndex >SYSCALL ArgV bcs CS.RUN.CheckArg.9 >PUSHYA >PUSHEA.G S.PW.PASSWD >SYSCALL MD5 jmp CS.RUN.CheckArg *-------------------------------------- CS.RUN.CheckArg.C inc ArgIndex lda ArgIndex >SYSCALL ArgV bcs CS.RUN.CheckArg.9 ldx #S.PW.GECOS bra CS.RUN.CheckArg.Next *-------------------------------------- CS.RUN.CheckArg.D inc ArgIndex lda ArgIndex >SYSCALL ArgV bcs CS.RUN.CheckArg.9 ldx #S.PW.DIR bra CS.RUN.CheckArg.Next *-------------------------------------- CS.RUN.CheckArg.S inc ArgIndex lda ArgIndex >SYSCALL ArgV bcs CS.RUN.CheckArg.9 ldx #S.PW.SHELL CS.RUN.CheckArg.Next >STYA ZPStrPtr * clc txa adc pData sta ZPTmpPtr lda pData+1 adc #0 sta ZPTmpPtr+1 ldy #$ff .1 iny lda (ZPStrPtr),y sta (ZPTmpPtr),y beq .8 cpy #64 bne .1 lda #0 sta (ZPTmpPtr),y .8 jmp CS.RUN.CheckArg *-------------------------------------- CS.RUN.IsValidChar cmp #'z'+1 bcs .99 cmp #'a' bcs .8 cmp #'Z'+1 bcs .99 cmp #'A' bcs .8 cpy #0 bcs .99 cmp #'0' bcc .9 cmp #'9'+1 rts .9 sec .99 rts .8 clc rts *-------------------------------------- CS.RUN.MkDir >PUSHEA.G S.PW.DIR >PUSHWI S.STAT.MODE.RO+S.STAT.MODE.RG+S.STAT.MODE.FU >SYSCALL MKDir rts *-------------------------------------- * Called if option S.PS.F.EVENT enabled in Header * Timer Event : every 10th seconds *-------------------------------------- CS.DOEVENT sec rts *-------------------------------------- * Called once, when RUN exited with CS * Put code for unloading LIB here *-------------------------------------- CS.QUIT lda ZPhStr beq .1 >SYSCALL FreeMem .1 lda ZPhPW beq .2 >SYSCALL FreeMem .2 clc rts *-------------------------------------- CS.END *-------------------------------------- OptionList .AS "CcDdPpSs" OptionCnt .EQ *-OptionList *-------------------------------------- * Initialized DATA *-------------------------------------- MSG.USAGE .CS "Usage : USERADD username\r\n" .CS " -c : Comment (GECOS)\r\n" .CS " -d : Home Directory\r\n" .CS " -p : Password\r\n" .CS " -s : Shell" MSG.CRLF .CZ "\r\n" MSG.BS .CZ "\b \b" MSG.ROOTPWD1 .CZ "\r\nPlease enter ROOT password : " MSG.ROOTPWD2 .CZ "\r\nPlease retype ROOT password : " MSG.MISMATCH .CZ "\r\nPasswords mismatch...\r\n" *-------------------------------------- PW.ROOT .AS "root" .BS 17-4 .AZ "d41d8cd98f00b204e9800998ecf8427e" .DA #0 UID .DA #0 GID .AS "Root User" .BS 65-9 .AS "${ROOT}root/" .BS 65-12 .AS "${ROOT}bin/sh" .BS 65-13 *-------------------------------------- PW.DEFAULT .BS 17 NAME .AZ "d41d8cd98f00b204e9800998ecf8427e" .DA #0 UID .DA #1 GID .BS 65 GECOS .AS "${ROOT}usr/" .BS 65-11 .AS "${ROOT}bin/sh" .BS 65-13 *-------------------------------------- *ROOT .AZ "ROOT" *-------------------------------------- * Per Process DATA segment *-------------------------------------- .DUMMY .OR 0 DS.START PW .BS S.PW DS.END .ED *-------------------------------------- MAN SAVE usr/src/bin/useradd.s ASM