NEW AUTO 3,1 .LIST OFF .OP 65C02 .OR $2000 .TF bin/httpget *-------------------------------------- .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.tcpip.i .INB inc/net.http.i *-------------------------------------- TIMEOUT.MAX .EQ 250 25 sec. *-------------------------------------- .DUMMY .OR ZPBIN ZS.START ZPIPCfgPtr .BS 2 ZPHostPtr .BS 2 ZPPtr .BS 2 ArgIndex .BS 1 hSocket .BS 1 hReqBuf .BS 1 ZPReqBufPtr .BS 2 ZPReqBufLen .BS 2 bHeader .BS 1 TimeOut .BS 1 hEncodedBuf .BS 1 ZPEncodedBufPtr .BS 2 ZPEncodedBufLen .BS 2 hSendBuf .BS 1 ZPSendBufPtr .BS 2 hRespBuf .BS 1 ZPRespBufPtr .BS 2 ZPRespBufLen .BS 2 hFile .BS 1 ZPFileName .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 Length To Relocate .DA DS.END-DS.START Data Segment to Allocate .DA #64 SS .DA #ZS.END-ZS.START Zero Page Size .DA 0 *-------------------------------------- .1 .DA CS.INIT .DA CS.RUN .DA CS.DOEVENT .DA CS.QUIT L.LIBTCPIP .DA LIBTCPIP L.SA.LOCAL .DA SA.LOCAL L.SA.REMOTE .DA SA.REMOTE L.SA.REMOTE.AD .DA SA.REMOTE+S.SOCKADDR.ADDR L.MSG.IPKO .DA MSG.IPKO L.MSG.USAGE .DA MSG.USAGE L.MSG.CRLF .DA MSG.CRLF L.MSG.NULL .DA MSG.NULL L.MSG.UNKNOWN .DA MSG.UNKNOWN L.MSG.CONNECT .DA MSG.CONNECT L.MSG.SKTKO .DA MSG.SKTKO L.MSG.CONNECTED .DA MSG.CONNECTED L.MSG.SKTERR .DA MSG.SKTERR L.MSG.IOERR .DA MSG.IOERR L.MSG.FileLength .DA MSG.FileLength L.MSG.Progress .DA MSG.Progress L.HTTP.GET .DA HTTP.GET .DA 0 *-------------------------------------- CS.INIT >LDYA L.LIBTCPIP >SYSCALL LoadLib bcs .9 sta hLIBTCPIP .9 rts *-------------------------------------- CS.RUN >LIBCALL hLIBTCPIP,LIBTCPIP.GETCFG is TCPIP loaded ? >STYA ZPIPCfgPtr lda (ZPIPCfgPtr) Configured ? bmi CS.RUN.IPOK >LDYA L.MSG.IPKO >SYSCALL PutS lda #E.SYN sec rts CS.RUN.IPOK ldy #S.IPCFG.IP+3 ldx #3 .1 lda (ZPIPCfgPtr),y sta SA.LOCAL+S.SOCKADDR.ADDR,x dey dex bpl .1 jsr CS.RUN.GETNEXTARG bcs .9 >STYA ZPHostPtr jsr Init.TimeOut .2 >PUSHW L.SA.REMOTE.AD >PUSHW ZPHostPtr >LIBCALL hLIBTCPIP,LIBTCPIP.HST.GetByName bcc CS.RUN.HOSTOK >SLEEP lda TimeOut bne .2 >PUSHW L.MSG.UNKNOWN >PUSHW ZPHostPtr >PUSHBI 2 >SYSCALL PrintF bra CS.RUN.ESYN .9 >PUSHW L.MSG.USAGE >PUSHBI 0 >SYSCALL PrintF CS.RUN.ESYN lda #E.SYN sec CS.RUN.RTS rts *-------------------------------------- CS.RUN.HOSTOK jsr CS.RUN.GETNEXTARG bcc .10 .8 jmp CS.RUN.ARGSOK .10 >STYA ZPPtr lda (ZPPtr) cmp #'-' beq .1 >LDYA ZPPtr >SYSCALL AToI bcs CS.RUN.RTS >STYA SA.REMOTE+S.SOCKADDR.PORT jsr CS.RUN.GETNEXTARG bcs .8 >STYA ZPPtr lda (ZPPtr) cmp #'-' bne CS.RUN.ESYN .1 ldy #1 lda (ZPPtr),y cmp #'a' bcc .11 cmp #'z'+1 bcs .11 eor #$20 .11 cmp #'U' bne .2 lda ZPReqBufPtr+1 bne CS.RUN.ESYN jsr CS.RUN.GETNEXTARG .9 bcs CS.RUN.ESYN >STYA ZPReqBufPtr >SYSCALL StrLen >STYA ZPReqBufLen bra CS.RUN.HOSTOK .2 cmp #'F' bne .3 lda ZPReqBufPtr+1 bne CS.RUN.ESYN jsr CS.RUN.GETNEXTARG bcs CS.RUN.ESYN2 >SYSCALL LoadTxtFile bcs CS.RUN.RTS >STYA ZPReqBufLen stx hReqBuf >SYSCALL GetMemPtr >STYA ZPReqBufPtr jmp CS.RUN.HOSTOK .3 cmp #'O' bne CS.RUN.ESYN2 lda ZPFileName+1 bne CS.RUN.ESYN2 jsr CS.RUN.GETNEXTARG bcs CS.RUN.ESYN2 >STYA ZPFileName jmp CS.RUN.HOSTOK *-------------------------------------- CS.RUN.ESYN2 lda #E.SYN sec rts *-------------------------------------- CS.RUN.ARGSOK >PUSHW L.MSG.CONNECT ldx #0 .1 >PUSHB SA.REMOTE+S.SOCKADDR.ADDR,x inx cpx #4 bne .1 >PUSHW SA.REMOTE+S.SOCKADDR.PORT >PUSHW ZPHostPtr >PUSHBI 8 >SYSCALL PrintF CS.RUN.OPENSKT >PUSHBI S.SOCKET.T.SEQPKT >PUSHBI 0 no protocol >LIBCALL hLIBTCPIP,LIBTCPIP.Socket bcs .9 sta hSocket >PUSHB hSocket >PUSHW L.SA.LOCAL >LIBCALL hLIBTCPIP,LIBTCPIP.Bind bcc .1 .9 pha >LDYA L.MSG.SKTKO >SYSCALL PutS pla sec .99 rts .1 jsr Init.TimeOut .2 >SLEEP >PUSHB hSocket >PUSHW L.SA.REMOTE >LIBCALL hLIBTCPIP,LIBTCPIP.Connect bcc .3 cmp #ERR.SKT.NOCONN bne .9 lda TimeOut bne .2 lda #ERR.SKT.NOCONN bra .9 .3 >SLEEP lda hSocket >LIBCALL hLIBTCPIP,LIBTCPIP.Recv bcc .7 cmp #E.NODATA beq .8 ldx TimeOut bne .3 lda #ERR.SKT.NOCONN bra .9 .7 >SYSCALL Freemem .8 >LDYA L.MSG.CONNECTED >SYSCALL PutS >SLEEP CS.RUN.GET jsr CS.RUN.ENCODE bcs .99 jsr CS.RUN.REQUEST bcs .99 >LDYA ZPFileName beq .1 >PUSHYA >PUSHBI O.CREATE+O.WRONLY+O.TRUNC >PUSHBI 0 TYPE >PUSHWZ AUXTYPE >SYSCALL FOpen bcs .99 sta hFile .1 jsr CS.RUN.RESPONSE bcs .99 .9 lda #0 sec .99 rts *-------------------------------------- CS.RUN.SKTERR pha >PUSHW L.MSG.SKTERR bra CS.RUN.ERR *-------------------------------------- CS.RUN.IOERR pha >PUSHW L.MSG.IOERR CS.RUN.ERR pla pha >PUSHA >PUSHBI 1 >SYSCALL PrintF pla sec rts *-------------------------------------- CS.RUN.GETNEXTARG inc ArgIndex lda ArgIndex >SYSCALL ArgV rts *-------------------------------------- CS.RUN.ENCODE ldy ZPReqBufPtr lda ZPReqBufPtr+1 bne .10 >LDYA L.MSG.NULL >STYA ZPReqBufPtr .10 >STYA ZPPtr inc ZPEncodedBufLen for ending \0 .1 lda (ZPPtr) beq .4 inc ZPPtr bne .2 inc ZPPtr+1 .2 jsr CS.RUN.TOENCODE if CS 3 bytes, if CC 1 byte lda #1 bcc .3 inc .3 adc ZPEncodedBufLen sta ZPEncodedBufLen bcc .1 inc ZPEncodedBufLen+1 bra .1 *-------------------------------------- .4 >LDYA ZPEncodedBufLen >SYSCALL GetMem bcs .9 >STYA ZPEncodedBufPtr >STYA ZPPtr stx hEncodedBuf .5 lda (ZPReqBufPtr) beq .8 inc ZPReqBufPtr bne .6 inc ZPReqBufPtr+1 .6 jsr CS.RUN.TOENCODE bcc .7 jsr CS.RUN.ADDBYTETOBUF bra .5 .7 jsr CS.RUN.ADDTOBUF bra .5 .8 sta (ZPPtr) ending \0 clc .9 rts *-------------------------------------- CS.RUN.TOENCODE ldx #URI.ToEncode.Cnt-1 .1 cmp URI.ToEncode,x beq .9 CS dex bpl .1 clc .9 rts *-------------------------------------- CS.RUN.ADDBYTETOBUF pha lda #'%' jsr CS.RUN.ADDTOBUF pla pha lsr lsr lsr lsr ora #$30 cmp #$3A bcc .1 adc #6 .1 jsr CS.RUN.ADDTOBUF pla and #$0F ora #$30 cmp #$3A bcc CS.RUN.ADDTOBUF adc #6 *-------------------------------------- CS.RUN.ADDTOBUF sta (ZPPtr) inc ZPPtr bne .8 inc ZPPtr+1 .8 rts *-------------------------------------- CS.RUN.REQUEST jsr Init.TimeOut >LDYAI 1024 >SYSCALL GetMem bcs .9 >STYA ZPSendBufPtr stx hSendBuf >PUSHYA >PUSHW L.HTTP.GET >PUSHW ZPEncodedBufPtr >PUSHW ZPHostPtr >PUSHBI 4 >SYSCALL SPrintF bcs .90 pha >PUSHB hSocket >PUSHW ZPSendBufPtr pla >PUSHYA Byte count >LIBCALL hLIBTCPIP,LIBTCPIP.Send .90 php pha lda hSendBuf >SYSCALL FreeMem pla plp .9 CS.RUN.REQUEST.RTS rts *-------------------------------------- CS.RUN.RESPONSE jsr Init.TimeOut .1 >SLEEP lda hSocket >LIBCALL hLIBTCPIP,LIBTCPIP.Recv bcc .2 cmp #E.NODATA bne .80 jsr CS.RUN.CtrlC bcs CS.RUN.REQUEST.RTS lda TimeOut bne .1 bit bHeader bmi .1 .80 jmp .8 .2 jsr CS.RUN.GETRESPONSE bit bHeader bmi .6 jsr CS.RUN.GETHEADER sec ror bHeader .6 lda hFile bne .7 ldy #S.PS.hStdOut lda (pPS),y .7 >PUSHA >PUSHW ZPRespBufPtr >PUSHW ZPRespBufLen >SYSCALL FWrite bcs .9 lda hRespBuf stz hRespBuf >SYSCALL FreeMem lda ZPRespBufLen clc adc Received sta Received lda ZPRespBufLen+1 adc Received+1 sta Received+1 bcc .70 inc Received+2 bne .70 inc Received+3 .70 lda hFile beq .71 >PUSHW L.MSG.Progress >PUSHL Received >PUSHBI 4 >SYSCALL PrintF bcs .9 .71 jmp CS.RUN.RESPONSE .8 bit bHeader bpl .99 >PUSHW L.MSG.CRLF >PUSHBI 0 >SYSCALL PrintF jsr CS.RUN.CHECKLEN bcc .9 .99 lda #MLI.E.IO sec .9 rts *-------------------------------------- CS.RUN.GETRESPONSE sta hRespBuf >SYSCALL GetMemPtr >STYA ZPRespBufPtr ldy #S.IP.TOTAL.LENGTH+1 lda (ZPRespBufPtr),y sec sbc #S.TCP-S.ETH.EII sta ZPRespBufLen dey lda (ZPRespBufPtr),y sbc /S.TCP-S.ETH.EII sta ZPRespBufLen+1 lda ZPRespBufPtr clc adc #S.TCP sta ZPRespBufPtr bcc .8 inc ZPRespBufPtr+1 .8 rts *-------------------------------------- CS.RUN.GETHEADER .1 ldy #$ff .2 iny lda (ZPRespBufPtr),y eor #C.CR bne .2 sta (ZPRespBufPtr),y iny skip CR iny skip LF sty ArgIndex >LDYA ZPRespBufPtr >STYA ZPPtr lda ZPRespBufLen sec sbc ArgIndex sta ZPRespBufLen bcs .3 dec ZPRespBufLen+1 .3 lda ArgIndex tay clc adc ZPRespBufPtr sta ZPRespBufPtr bcc .4 inc ZPRespBufPtr+1 .4 dey dey beq .8 ldy #$ff .5 iny lda (ZPPtr),y cmp HEAD.ContentLength,y bne .1 cmp #C.SPACE bne .5 tya sec skip SPACE adc ZPPtr tay lda ZPPtr+1 adc #0 >SYSCALL AToL >PULLL Length >PUSHW L.MSG.FileLength >PUSHL Length >PUSHBI 4 >SYSCALL PrintF jmp .1 .8 clc .9 rts *-------------------------------------- CS.RUN.CHECKLEN ldx #3 sec .1 lda Received,x eor Length,x bne .9 dex bpl .1 clc .9 rts *-------------------------------------- CS.RUN.CtrlC ldy #S.PS.hStdIn lda (pPS),y >SYSCALL FEOF bcs .8 tay bne .8 CC >SYSCALL GetChar bcs .9 cmp #$03 Ctrl-C beq .9 CS .8 clc .9 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 hSocket beq .1 >LIBCALL hLIBTCPIP,LIBTCPIP.Shutdown .1 lda hReqBuf beq .2 >SYSCALL FreeMem .2 lda hEncodedBuf beq .3 >SYSCALL FreeMem .3 lda hRespBuf beq .4 >SYSCALL FreeMem .4 lda hFile beq .5 >SYSCALL FClose .5 lda hLIBTCPIP beq .8 >SYSCALL UnloadLib .8 clc rts *-------------------------------------- Init.TimeOut lda #TIMEOUT.MAX sta TimeOut rts *-------------------------------------- CS.END LIBTCPIP .AZ "libtcpip" hLIBTCPIP .BS 1 MSG.IPKO .CZ "TCP/IP Not Loaded/Configured." MSG.USAGE .CS "Usage : HTTPGET [port]\r\n" .CS " -U : Url\r\n" .CS " -F : UrlFile\r\n" .CS " -O : OutputFile" MSG.CRLF .CS "\r\n" MSG.NULL .DA #0 MSG.UNKNOWN .CZ "%s: Unknown host\r\n" MSG.CONNECT .CZ "Connecting to %d.%d.%d.%d:%D (%s)..." MSG.SKTKO .CZ "Failed to Open Socket." MSG.CONNECTED .CZ "Connected." MSG.SKTERR .CZ "Socket Error : $%h\r\n" MSG.IOERR .CZ "I/O Error : $%h\r\n" MSG.FileLength .CZ "File Length : %10u Bytes\r\n" MSG.Progress .CZ "\rReceived : %10u" *-------------------------------------- SA.LOCAL .DA #AF.INET S.SOCKADDR.AF .BS 1 .BS 4 S.SOCKADDR.ADDR .BS 2 S.SOCKADDR.PORT *-------------------------------------- SA.REMOTE .DA #AF.INET S.SOCKADDR.AF .BS 1 .BS 4 S.SOCKADDR.ADDR .DA TCP.PORT.HTTP *-------------------------------------- URI.ToEncode .DA #C.LF,#C.CR,#C.SPACE,#'"' .AS "%-.\^_`{|}~" URI.ToEncode.Cnt .EQ *-URI.ToEncode *-------------------------------------- HEAD.ContentLength .AZ "Content-Length: " *-------------------------------------- HTTP.GET .AS "GET /%s HTTP/1.1" .DA #C.CR,#C.LF .AS "User-Agent: A2osX.HTTPGET" .DA #C.CR,#C.LF .AS "Host: %s" .DA #C.CR,#C.LF .AS "Connection: close" .DA #C.CR,#C.LF .DA #C.CR,#C.LF .DA #0 *-------------------------------------- Received .BS 4 Length .BS 4 *-------------------------------------- .DUMMY .OR 0 DS.START DS.END .ED *-------------------------------------- MAN SAVE usr/src/bin/httpget.s ASM