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 hStr .BS 1 hSrvSocket .BS 1 TimeOut .BS 1 hSrvName .BS 1 ZPSrvNamePtr .BS 2 hRootdir .BS 1 ZPRootDirPtr .BS 2 hClntSocket .BS 1 ZPRequestPtr .BS 2 ZPnRequestLen .BS 2 ZPLinePtr .BS 2 ZPRepPtr .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 .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.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.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 hStr >PUSHW L.MSG.INITCONF >PUSHW L.ETCHTTPDCONF >PUSHBI 2 >SYSCALL PrintF bcs CS.RUN.RTS jsr CS.RUN.CONF bcs CS.RUN.RTS >PUSHBI 0 no protocol lda #S.SOCKET.T.SEQPACKET >LIBCALL hLIBTCPIP,LIBTCPIP.Socket bcs CS.RUN.RTS sta hSrvSocket >PUSHW L.SA.LOCAL lda hSrvSocket >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 .9 >LDYA L.MSG.SKTERR >SYSCALL PutS lda #E.SYN sec CS.RUN.ERR 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 >PUSHWI 256 >PUSHW ZPLinePtr lda hFile >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 >PUSHWI 0 Allocate >SYSCALL RealPath bcs .9 >STYA ZPRootDirPtr stx hRootdir .9 rts *-------------------------------------- CS.RUN.SERVER lda hSrvSocket >LIBCALL hLIBTCPIP,LIBTCPIP.accept bcs .8 sta hClntSocket >SYSCALL GetMemPtr >STYA ZPSktPtr >PUSHW L.MSG.INCOMING ldx #3 ldy #S.SOCKET.REM.ADDR >PUSHB hClntSocket .1 >PUSHB (ZPSktPtr),y iny dex bpl .1 >PUSHBI 5 >SYSCALL PrintF jsr CS.RUN.CLIENT .8 clc .9 rts *-------------------------------------- CS.RUN.CLIENT >STZ.G REQ.KeepAlive >STA.G REQ.FullPath >STA.G REQ.hFile >STA.G REQ.hBuf .1 >SLEEP lda hClntSocket >LIBCALL hLIBTCPIP,LIBTCPIP.Recv bcc .2 tay beq .1 jmp .80 .2 jsr CS.RUN.REQ.GetFrame .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 .9 .4 >LDA.G REQ.FullPath beq .9 >LDYAI 1024 >SYSCALL GetMem bcs .9 >STYA ZPRepPtr txa >STA.G REQ.hBuf jsr CS.RUN.OpenFile bcs .9 jsr CS.RUN.GetMime bcs .9 jsr CS.RUN.SendFile bcc .5 .9 >PUSHWI HTTP.404.len >PUSHW L.HTTP.404 lda hClntSocket >LIBCALL hLIBTCPIP,LIBTCPIP.Send bcs .80 * >STZ.G REQ.KeepAlive .5 >LDA.G REQ.hFile beq .6 >SYSCALL FClose .6 >LDA.G REQ.hBuf beq .7 >SYSCALL freemem .7 >LDA.G REQ.hFrame beq .8 >SYSCALL FreeMem .8 >LDA.G REQ.KeepAlive beq .80 jmp CS.RUN.CLIENT .80 lda hClntSocket >LIBCALL hLIBTCPIP,LIBTCPIP.Shutdown .99 rts *-------------------------------------- CS.RUN.REQ.GetFrame >STA.G REQ.hFrame >SYSCALL GetMemPtr >STYA ZPRequestPtr 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 >LEA.G REQ.FullPath >SYSCALL puts >PUSHEA.G REQ.FullPath >PUSHBI O.RDONLY >PUSHBI 0 type >PUSHWZ Aux type >SYSCALL FOpen bcs .9 txa >STA.G REQ.hFile >PUSHA >PUSHEA.G REQ.Stat >SYSCALL FStat .9 rts *-------------------------------------- CS.RUN.GetMime >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.G REQ.MimeType clc rts *-------------------------------------- CS.RUN.SendFile >PUSHW ZPRepPtr >PUSHW L.HTTP.200 >LDA.G REQ.MimeType tax >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 >PUSHWI 1024 >PUSHW ZPRepPtr >LDA.G REQ.hFile >SYSCALL fread bcs .8 jsr CS.RUN.SendBuf bcc .1 rts .8 cmp #MLI.E.EOF bne .9 clc .9 rts *-------------------------------------- CS.RUN.SendBuf >PUSHYA >PUSHW ZPRepPtr lda hClntSocket >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 >PUSHW ZPRootDirPtr >LEA.G REQ.FullPath >SYSCALL StrCpy ldy #1 lda (ZPPtr2),y bne .2 >LDYA L.INDEX.HTML bra .3 .2 >LDYA ZPPtr2 .3 >PUSHYA >LEA.G REQ.FullPath >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.G 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 hStr 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:Listen Error." MSG.INCOMING .AZ "HTTPD:Incoming Connection [SKT=%h] From : %d.%d.%d.%d\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 REQ.hFrame .BS 1 REQ.hFile .BS 1 REQ.hBuf .BS 1 REQ.MimeType .BS 1 REQ.KeepAlive .BS 1 DS.END .ED *-------------------------------------- MAN SAVE usr/src/sbin/httpd.s ASM