NEW AUTO 3,1 .LIST OFF .OP 65C02 .OR $2000 .TF sbin/httpd *-------------------------------------- .INB inc/macros.i .INB inc/a2osx.i .INB inc/mli.i .INB inc/mli.e.i .INB inc/eth.i .INB inc/libtcpip.i .INB inc/net.http.i *-------------------------------------- TIMEOUT.MAX .EQ 30 30 sec. CONN.MAX .EQ 16 *-------------------------------------- .DUMMY .OR ZPBIN ZS.START ZPPtr1 .BS 2 ZPPtr2 .BS 2 ZPSktPtr .BS 2 hFile .BS 1 hLineBuf .BS 1 hSrvSocket .BS 1 TimeOut .BS 1 hSrvName .BS 1 ZPSrvNamePtr .BS 2 hRootdir .BS 1 ZPRootDirPtr .BS 2 ZPRequestPtr .BS 2 ZPnRequestLen .BS 2 ZPLinePtr .BS 2 ZPRepPtr .BS 2 CLN.hSocket .BS 1 REP.hBuf .BS 1 REQ.hFile .BS 1 REQ.KeepAlive .BS 1 REQ.MimeType .BS 1 REQ.hReq .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 .DA #0 .DA CS.END-CS.START CS .DA DS.END-DS.START DS .DA #64 SS .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.LIBTCPIP .DA LIBTCPIP L.ETCHTTPDCONF .DA ETCHTTPDCONF L.KEYWORDS.CONF .DA KEYWORDS.CONF J.KEYWORDS.CONF .DA CS.RUN.CONF.SERVERNAME .DA CS.RUN.CONF.LISTEN .DA CS.RUN.CONF.DOCUMENTROOT L.SA.LOCAL .DA SA.LOCAL L.MSG.TCPWAIT .DA MSG.TCPWAIT L.MSG.TCPIPERR .DA MSG.TCPIPERR L.MSG.INITCONF .DA MSG.INITCONF L.MSG.INITOK .DA MSG.INITOK L.MSG.SKTERR .DA MSG.SKTERR L.MSG.INCOMING .DA MSG.INCOMING L.MSG.REQ .DA MSG.REQ L.MSG.FILE .DA MSG.FILE L.MSG.SKTCLOSE .DA MSG.SKTCLOSE L.KEYWORDS.REQ .DA KEYWORDS.REQ J.KEYWORDS.REQ .DA CS.RUN.REQ.GET L.INDEX.HTML .DA INDEX.HTML L.MIME.TYPES .DA MIME.TYPES T.MIME .DA MIME.HTML .DA MIME.TXT .DA MIME.TTF .DA MIME.ICO .DA MIME.PNG .DA MIME.JPG L.MIME.DEFAULT .DA MIME.DEFAULT L.HTTP.200 .DA HTTP.200 L.HTTP.404 .DA HTTP.404 .DA 0 *-------------------------------------- CS.INIT >LDYA L.LIBTCPIP >SYSCALL LoadLib bcs .9 sta hLIBTCPIP .9 rts *-------------------------------------- CS.RUN >LDYA L.MSG.TCPWAIT >SYSCALL PutS lda #TIMEOUT.MAX sta TimeOut .1 >SLEEP >LIBCALL hLIBTCPIP,LIBTCPIP.GETCFG is TCPIP loaded ? bcs .99 >STYA ZPPtr1 lda (ZPPtr1) Configured ? bmi CS.RUN.INIT lda TimeOut bcs .99 ldy #S.PS.hStdIn lda (pPS),y >SYSCALL FEOF bcs CS.RUN.RTS I/O err tay bne .1 >SYSCALL GetChar bcs CS.RUN.RTS cmp #3 Ctrl-C bne .1 sec rts .99 >LDYA L.MSG.TCPIPERR >SYSCALL PutS CS.RUN.SYN lda #E.SYN sec CS.RUN.RTS rts *-------------------------------------- CS.RUN.INIT ldx #3 ldy #S.IPCFG.IP+3 .1 lda (ZPPtr1),y sta SA.LOCAL+S.SOCKADDR.ADDR,x dey dex bpl .1 >LDYAI 256 >SYSCALL GetMem bcs CS.RUN.RTS >STYA ZPLinePtr stx hLineBuf >PUSHW L.MSG.INITCONF >PUSHW L.ETCHTTPDCONF >PUSHBI 2 >SYSCALL PrintF bcs CS.RUN.RTS jsr CS.RUN.CONF bcs CS.RUN.RTS >PUSHBI S.SOCKET.T.SEQPKT >PUSHBI 0 no protocol >LIBCALL hLIBTCPIP,LIBTCPIP.Socket bcs CS.RUN.RTS sta hSrvSocket >PUSHB hSrvSocket >PUSHW L.SA.LOCAL >LIBCALL hLIBTCPIP,LIBTCPIP.Bind bcs CS.RUN.ERR lda hSrvSocket >LIBCALL hLIBTCPIP,LIBTCPIP.Listen bcs CS.RUN.ERR >PUSHW L.MSG.INITOK >PUSHW SA.LOCAL+S.SOCKADDR.PORT >PUSHW ZPRootDirPtr >PUSHBI 4 >SYSCALL PrintF *-------------------------------------- CS.RUN.LOOP >SLEEP jsr CS.RUN.SERVER bcs CS.RUN.ERR bra CS.RUN.LOOP CS.RUN.ERR >LDYA L.MSG.SKTERR >SYSCALL PutS lda #E.SYN sec rts *-------------------------------------- CS.RUN.CONF >PUSHW L.ETCHTTPDCONF >PUSHBI O.RDONLY+O.TEXT >PUSHBI S.FI.T.TXT >PUSHWZ >SYSCALL FOpen bcs .99 sta hFile .1 >PUSHB hFile >PUSHW ZPLinePtr >PUSHWI 256 >SYSCALL FGetS bcs .8 tya beq .1 lda (ZPLinePtr) cmp #'#' beq .1 >LDYA L.KEYWORDS.CONF >STYA ZPPtr1 ldx #0 .2 ldy #0 .3 lda (ZPPtr1),y cmp (ZPLinePtr),y bne .4 iny cmp #C.SPACE bne .3 jsr CS.RUN.CONF.JMP bcc .1 bra .97 .4 inx inx ldy #0 .5 iny lda (ZPPtr1),y cmp #C.SPACE bne .5 tya sec adc ZPPtr1 sta ZPPtr1 bcc .6 inc ZPPtr1+1 .6 lda (ZPPtr1) bne .2 .97 lda #E.SYN .98 pha jsr .8 pla sec .99 rts .8 lda hFile >SYSCALL FClose rts *-------------------------------------- CS.RUN.CONF.JMP tya clc adc ZPLinePtr sta ZPPtr1 tay lda #0 adc ZPLinePtr+1 sta ZPPtr1+1 jmp (J.KEYWORDS.CONF,x) CS.RUN.CONF.SERVERNAME >SYSCALL StrDup bcs .9 >STYA ZPSrvNamePtr stx hSrvName .9 rts CS.RUN.CONF.LISTEN >SYSCALL AToI bcs .9 >STYA SA.LOCAL+S.SOCKADDR.PORT .9 rts CS.RUN.CONF.DOCUMENTROOT >PUSHYA >PUSHWZ Allocate >SYSCALL RealPath bcs .9 >STYA ZPRootDirPtr stx hRootdir .9 rts *-------------------------------------- CS.RUN.SERVER lda hSrvSocket >LIBCALL hLIBTCPIP,LIBTCPIP.Accept bcs .8 sta CLN.hSocket >SYSCALL GetMemPtr >STYA ZPSktPtr >PUSHW L.MSG.INCOMING >PUSHB CLN.hSocket ldx #3 ldy #S.SOCKET.REM.ADDR .1 >PUSHB (ZPSktPtr),y iny dex bpl .1 >PUSHBI 5 >SYSCALL PrintF jsr CS.RUN.CLIENT >PUSHW L.MSG.SKTCLOSE >PUSHB CLN.hSocket >PUSHBI 1 >SYSCALL PrintF lda CLN.hSocket >LIBCALL hLIBTCPIP,LIBTCPIP.Shutdown .8 clc .9 CS.RUN.SERVER.RTS rts *-------------------------------------- CS.RUN.CLIENT >LDYAI 1024 >SYSCALL GetMem bcs CS.RUN.SERVER.RTS >STYA ZPRepPtr stx REP.hBuf .10 >STZ.G REQ.FullPath stz REQ.hReq stz REQ.KeepAlive stz REQ.hFile .1 >SLEEP lda CLN.hSocket >LIBCALL hLIBTCPIP,LIBTCPIP.Recv bcc .2 cmp #E.NODATA beq .1 jmp .99 .2 jsr CS.RUN.REQ.GetReq .3 jsr CS.RUN.REQ.GetLine bcs .4 >LDYA ZPLinePtr >STYA ZPPtr2 >LDYA L.KEYWORDS.REQ jsr CS.RUN.GET.KW bcs .3 jsr CS.RUN.REQ.JMP bcc .3 bcs .98 .4 lda REQ.hReq >SYSCALL FreeMem stz REQ.hReq >LDA.G REQ.FullPath beq .9 jsr CS.RUN.OpenFile bcs .9 jsr CS.RUN.SendFile bcs .99 bra .8 .9 >PUSHB CLN.hSocket >PUSHW L.HTTP.404 >PUSHWI HTTP.404.len >LIBCALL hLIBTCPIP,LIBTCPIP.Send .8 bit REQ.KeepAlive bpl .99 jmp .10 .98 lda REQ.hReq beq .99 >SYSCALL FreeMem .99 lda REP.hBuf >SYSCALL FreeMem rts *-------------------------------------- CS.RUN.REQ.GetReq sta REQ.hReq >SYSCALL GetMemPtr >STYA ZPRequestPtr >PUSHW L.MSG.REQ >PUSHB REQ.hReq >PUSHB CLN.hSocket >PUSHBI 2 >SYSCALL PrintF ldy #S.IP.TOTAL.LENGTH+1 lda (ZPRequestPtr),y sec sbc #S.TCP-S.IP eor #$ff sta ZPnRequestLen dey lda (ZPRequestPtr),y sbc /S.TCP-S.IP eor #$ff sta ZPnRequestLen+1 lda ZPRequestPtr clc adc #S.TCP sta ZPRequestPtr bcc .8 inc ZPRequestPtr+1 .8 rts *-------------------------------------- CS.RUN.REQ.GetLine ldy #0 .1 inc ZPnRequestLen bne .2 inc ZPnRequestLen+1 beq .9 .2 lda (ZPRequestPtr) inc ZPRequestPtr bne .21 inc ZPRequestPtr+1 .21 cmp #C.CR bne .4 inc ZPnRequestLen bne .3 inc ZPnRequestLen+1 beq .9 .3 lda (ZPRequestPtr) inc ZPRequestPtr bne .31 inc ZPRequestPtr+1 .31 eor #C.LF bne .9 sta (ZPLinePtr),y Y,A = StrLen clc rts .4 sta (ZPLinePtr),y iny bra .1 .9 sec rts *-------------------------------------- CS.RUN.OpenFile >PUSHW L.MSG.FILE >PUSHB CLN.hSocket >PUSHEA.G REQ.FullPath >PUSHBI 3 >SYSCALL PrintF >PUSHEA.G REQ.FullPath >PUSHBI O.RDONLY >PUSHBI 0 type >PUSHWZ Aux type >SYSCALL FOpen bcs .9 stx REQ.hFile >PUSHA >PUSHEA.G REQ.Stat >SYSCALL FStat >LEA.G REQ.FullPath >STYA ZPPtr2 ldx #$ff ldy #$ff .1 iny lda (ZPPtr2),y beq .2 cmp #'.' bne .1 tya tax bra .1 .2 txa bpl .3 lda #MIME.DEFAULT.ID bra .8 .3 sec adc ZPPtr2 sta ZPPtr2 bcc .4 inc ZPPtr2+1 .4 >LDYA L.MIME.TYPES jsr CS.RUN.GET.KW txa .8 sta REQ.MimeType clc .9 rts *-------------------------------------- CS.RUN.SendFile >PUSHW ZPRepPtr >PUSHW L.HTTP.200 ldx REQ.MimeType >PUSHW T.MIME,x >PUSHL.G REQ.Stat+S.STAT.SIZE >PUSHBI 6 >SYSCALL SPrintF bcs .9 jsr CS.RUN.SendBuf Y,A = car count .1 >PUSHB REQ.hFile >PUSHW ZPRepPtr >PUSHWI 1024 >SYSCALL FRead bcs .8 jsr CS.RUN.SendBuf bcs .9 bra .1 .8 cmp #MLI.E.EOF bne .9 clc .9 php pha lda REQ.hFile >SYSCALL FClose pla plp rts *-------------------------------------- CS.RUN.SendBuf pha >PUSHB CLN.hSocket >PUSHW ZPRepPtr pla >PUSHYA >LIBCALL hLIBTCPIP,LIBTCPIP.Send rts *-------------------------------------- CS.RUN.REQ.JMP jmp (J.KEYWORDS.REQ,x) *-------------------------------------- CS.RUN.REQ.GET ldy #0 .1 iny lda (ZPPtr2),y eor #C.SPACE bne .1 sta (ZPPtr2),y lda (ZPPtr2) cmp #'/' bne .4 >PUSHEA.G REQ.FullPath >PUSHW ZPRootDirPtr >SYSCALL StrCpy >PUSHEA.G REQ.FullPath ldy #1 lda (ZPPtr2),y bne .2 >LDYA L.INDEX.HTML bra .3 .2 >LDYA ZPPtr2 .3 >PUSHYA >SYSCALL StrCat rts .4 >PUSHW ZPPtr2 >PUSHEA.G REQ.FullPath >SYSCALL RealPath .9 rts *-------------------------------------- CS.RUN.REQ.Connection lda (ZPPtr2) eor #'k' beq .1 lda #$ff .1 sta REQ.KeepAlive clc rts *-------------------------------------- CS.RUN.GET.KW >STYA ZPPtr1 ldx #0 .2 ldy #$ff .3 iny lda (ZPPtr1),y cmp (ZPPtr2),y bne .4 cmp #0 beq .33 cmp #C.SPACE bne .3 .33 tya sec adc ZPPtr2 sta ZPPtr2 bcc .8 inc ZPPtr2+1 .8 clc rts .4 inx inx ldy #0 .5 iny lda (ZPPtr1),y bne .5 tya sec adc ZPPtr1 sta ZPPtr1 bcc .6 inc ZPPtr1+1 .6 lda (ZPPtr1) bne .2 sec 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 lda hSrvSocket beq .1 >LIBCALL hLIBTCPIP,LIBTCPIP.Shutdown .1 lda hLineBuf beq .2 >SYSCALL FreeMem .2 lda hLIBTCPIP beq .8 >SYSCALL UnloadLib .8 clc rts *-------------------------------------- CS.END *-------------------------------------- hLIBTCPIP .BS 1 LIBTCPIP .AZ "libtcpip" ETCHTTPDCONF .AZ "${BOOT}etc/httpd.conf" *-------------------------------------- KEYWORDS.CONF .AS "ServerName " .AS "Listen " .AS "DocumentRoot " .DA #0 *-------------------------------------- MSG.TCPWAIT .AZ "HTTPD:Waiting for TCP/IP initializing..." MSG.TCPIPERR .AZ "HTTPD:TCP/IP Not initialized properly." MSG.INITCONF .AZ "HTTPD:Reading %s file...\r\n" MSG.INITOK .AZ "HTTPD:Listening on port %D, root dir: %s.\r\n" MSG.SKTERR .AZ "HTTPD:Skt Bind Error." MSG.INCOMING .AZ "HTTPD:Skt $%h Opened From %d.%d.%d.%d\r\n" MSG.REQ .AZ "HTTPD:Req $%h From Skt $%h\r\n" MSG.FILE .AZ "HTTPD:Skt $%h File %s\r\n" MSG.SKTCLOSE .AZ "HTTPD:Skt $%h Close\r\n" *-------------------------------------- KEYWORDS.REQ .AS "GET " .AS "Connection: " .DA #0 *-------------------------------------- INDEX.HTML .AS "/index." html *-------------------------------------- MIME.TYPES .AZ "html" .AZ "txt" .AZ "ttf" .AZ "ico" .AZ "png" .AZ "jpg" .DA #0 MIME.HTML .AZ "text/html" MIME.TXT .AZ "text/plain" MIME.TTF .AZ "font/truetype" MIME.ICO .AZ "image/vnd.microsoft.icon" "image/x-icon" MIME.PNG .AZ "image/png" MIME.JPG .AZ "image/jpeg" MIME.DEFAULT .AZ "application/octet-stream" MIME.DEFAULT.ID .EQ 12 *-------------------------------------- HTTP.200 .AS "HTTP/1.1 200 OK" .DA #C.CR,#C.LF .AS "Server: A2osX-HTTPD 0.94" .DA #C.CR,#C.LF .AS "Content-Type: %s" .DA #C.CR,#C.LF .AS "Content-Length: %u" .DA #C.CR,#C.LF .DA #C.CR,#C.LF .DA #0 *-------------------------------------- HTTP.404 .AS "HTTP/1.1 404 Not Found" .DA #C.CR,#C.LF .AS "Server: A2osX-HTTPD 0.94" .DA #C.CR,#C.LF .AS "Content-Type: text/html" .DA #C.CR,#C.LF .AS "Content-Length: 47" .DA #C.CR,#C.LF .AS "Connection: Close" .DA #C.CR,#C.LF .DA #C.CR,#C.LF .AS "404:NOT FOUND" .DA #C.CR,#C.LF HTTP.404.len .EQ *-HTTP.404 *-------------------------------------- SA.LOCAL .DA #AF.INET S.SOCKADDR.AF .BS 1 .BS 4 S.SOCKADDR.ADDR .DA TCP.PORT.HTTP *-------------------------------------- .DUMMY .OR 0 DS.START REQ.FullPath .BS MLI.MAXPATH+1 REQ.Stat .BS S.STAT DS.END .ED *-------------------------------------- MAN SAVE usr/src/sbin/httpd.s ASM