mirror of
https://github.com/bobbimanners/emailler.git
synced 2024-09-08 21:54:28 +00:00
git-svn-id: http://svn.code.sf.net/p/netboot65/code@177 93682198-c243-4bdb-bd91-e943c89aac3b
This commit is contained in:
parent
2760650688
commit
0a2982105b
@ -124,5 +124,6 @@ NB65_ERROR_CONNECTION_RESET_BY_PEER EQU $89
|
||||
NB65_ERROR_CONNECTION_CLOSED EQU $8A
|
||||
NB65_ERROR_FILE_ACCESS_FAILURE EQU $90
|
||||
NB65_MALFORMED_URL EQU $A0
|
||||
NB65_DNS_LOOKUP_FAILED EQU $A1
|
||||
NB65_ERROR_OPTION_NOT_SUPPORTED EQU $FE
|
||||
NB65_ERROR_FUNCTION_NOT_SUPPORTED EQU $FF
|
||||
|
@ -52,7 +52,8 @@ ip65_error: .res 1 ;last error code
|
||||
;outputs: AX set to a pseudo-random 16 bit number
|
||||
ip65_random_word:
|
||||
jsr timer_read ;sets AX
|
||||
adc $d018 ;on a c64, this is the raster register
|
||||
; adc $d018 ;on a c64, this is the raster register
|
||||
adc $d41b; on a c64, this is a 'random' number from the SID
|
||||
pha
|
||||
adc ip65_ctr_arp
|
||||
ora #$08 ;make sure we grab at least 8 bytes from eth_inp
|
||||
|
@ -1,6 +1,4 @@
|
||||
;text file parsing routines
|
||||
; first call parser_init
|
||||
; then call parser_skip_next
|
||||
|
||||
.export parse_integer
|
||||
.importzp copy_dest
|
||||
|
@ -23,6 +23,7 @@ MAX_TCP_PACKETS_SENT=8 ;timeout after sending 8 messages will be about 7 sec
|
||||
.export tcp_connect_ip
|
||||
.export tcp_send_data_len
|
||||
.export tcp_send
|
||||
.export tcp_send_string
|
||||
.export tcp_close
|
||||
.export tcp_listen
|
||||
|
||||
@ -368,6 +369,33 @@ tcp_close:
|
||||
rts
|
||||
|
||||
|
||||
tcp_send_string:
|
||||
;send a string over the current tcp connection
|
||||
;inputs:
|
||||
; tcp connection should already be opened
|
||||
; AX: pointer to buffer - data up to (but not including)
|
||||
; the first nul byte will be sent. max of 255 bytes will be sent.
|
||||
;outputs:
|
||||
; carry flag is set if an error occured, clear otherwise
|
||||
|
||||
stax tcp_send_data_ptr
|
||||
stax copy_src
|
||||
lda #0
|
||||
tay
|
||||
sta tcp_send_data_len
|
||||
sta tcp_send_data_len+1
|
||||
lda (copy_src),y
|
||||
bne @find_end_of_string
|
||||
rts ; if the string is empty, don't send anything!
|
||||
@find_end_of_string:
|
||||
lda (copy_src),y
|
||||
beq @done
|
||||
inc tcp_send_data_len
|
||||
iny
|
||||
bne @find_end_of_string
|
||||
@done:
|
||||
ldax tcp_send_data_ptr
|
||||
;now we can fall through into tcp_send
|
||||
tcp_send:
|
||||
;send tcp data
|
||||
;inputs:
|
||||
@ -378,6 +406,7 @@ tcp_send:
|
||||
; carry flag is set if an error occured, clear otherwise
|
||||
|
||||
stax tcp_send_data_ptr
|
||||
|
||||
lda tcp_state
|
||||
cmp #tcp_cxn_state_established
|
||||
beq @connection_established
|
||||
@ -647,6 +676,17 @@ tcp_process:
|
||||
beq @not_reset
|
||||
jsr check_current_connection
|
||||
bcs @not_current_connection_on_rst
|
||||
;for some reason, search.twitter.com is sending RSTs with ID=$1234 (i.e. echoing the inbound ID)
|
||||
;but then keeps the connection open and ends up sending the file.
|
||||
;so lets ignore a reset with ID=$1234
|
||||
lda ip_inp+ip_id
|
||||
cmp #$34
|
||||
bne @not_invalid_reset
|
||||
lda ip_inp+ip_id+1
|
||||
cmp #$12
|
||||
bne @not_invalid_reset
|
||||
jmp @send_ack
|
||||
@not_invalid_reset:
|
||||
;connection has been reset so mark it as closed
|
||||
lda #tcp_cxn_state_closed
|
||||
sta tcp_state
|
||||
|
@ -11,18 +11,34 @@
|
||||
.import output_buffer
|
||||
.importzp copy_src
|
||||
.importzp copy_dest
|
||||
.import copymem
|
||||
|
||||
.import ip65_error
|
||||
.import ip65_process
|
||||
.import parser_init
|
||||
.import parser_skip_next
|
||||
.import dns_set_hostname
|
||||
.import dns_resolve
|
||||
.import parse_integer
|
||||
.import dns_ip
|
||||
.import tcp_connect
|
||||
.import tcp_send_string
|
||||
.import tcp_send_data_len
|
||||
.import tcp_callback
|
||||
.import tcp_close
|
||||
.import tcp_connect_ip
|
||||
.import tcp_inbound_data_length
|
||||
.import tcp_inbound_data_ptr
|
||||
|
||||
|
||||
.export url_ip
|
||||
.export url_port
|
||||
.export url_selector
|
||||
.export url_resource_type
|
||||
.export url_parse
|
||||
.export url_download
|
||||
.export url_download_buffer
|
||||
.export url_download_buffer_length
|
||||
|
||||
target_string=copy_src
|
||||
search_string=copy_dest
|
||||
@ -41,6 +57,16 @@ selector_buffer=output_buffer
|
||||
|
||||
src_ptr: .res 1
|
||||
dest_ptr: .res 1
|
||||
|
||||
url_download_buffer: .res 2 ; points to a buffer that url will be downloaded into
|
||||
url_download_buffer_length: .res 2 ;length of buffer that url will be downloaded into
|
||||
|
||||
temp_buffer: .res 2
|
||||
temp_buffer_length: .res 2
|
||||
|
||||
download_flag: .res 1
|
||||
|
||||
|
||||
.code
|
||||
|
||||
|
||||
@ -102,7 +128,11 @@ lda #url_type_gopher
|
||||
jsr dns_set_hostname
|
||||
bcs @exit_with_sec
|
||||
jsr dns_resolve
|
||||
bcs @exit_with_sec
|
||||
bcc :+
|
||||
lda #NB65_DNS_LOOKUP_FAILED
|
||||
sta ip65_error
|
||||
jmp @exit_with_sec
|
||||
:
|
||||
;copy IP address
|
||||
ldx #3
|
||||
:
|
||||
@ -138,19 +168,23 @@ lda #url_type_gopher
|
||||
;first byte after / in a gopher url is the resource type
|
||||
ldy src_ptr
|
||||
lda (copy_src),y
|
||||
beq @start_of_selector
|
||||
sta url_resource_type
|
||||
inc src_ptr
|
||||
jmp @start_of_selector
|
||||
@not_gopher:
|
||||
cmp #url_type_http
|
||||
bne @done ; if it's not gopher or http, we don't know how to build a selector
|
||||
ldy #3
|
||||
beq @build_http_request
|
||||
jmp @done ; if it's not gopher or http, we don't know how to build a selector
|
||||
@build_http_request:
|
||||
ldy #get_length-1
|
||||
sty dest_ptr
|
||||
:
|
||||
lda get,y
|
||||
sta (copy_dest),y
|
||||
dey
|
||||
bpl :-
|
||||
|
||||
@start_of_selector:
|
||||
lda #'/'
|
||||
inc dest_ptr
|
||||
@ -166,6 +200,55 @@ lda #url_type_gopher
|
||||
inc dest_ptr
|
||||
bne @copy_one_byte
|
||||
@end_of_selector:
|
||||
|
||||
|
||||
ldx #1 ;number of CRLF at end of gopher request
|
||||
lda url_type
|
||||
|
||||
cmp #url_type_http
|
||||
bne @final_crlf
|
||||
|
||||
;now the HTTP version number & Host: field
|
||||
ldx #0
|
||||
:
|
||||
lda http_version_and_host,x
|
||||
beq :+
|
||||
ldy dest_ptr
|
||||
inc dest_ptr
|
||||
sta (copy_dest),y
|
||||
inx
|
||||
bne :-
|
||||
:
|
||||
|
||||
|
||||
;now copy the host field
|
||||
jsr skip_to_hostname
|
||||
;AX now pointing at hostname
|
||||
stax copy_src
|
||||
ldax #selector_buffer
|
||||
stax copy_dest
|
||||
|
||||
lda #0
|
||||
sta src_ptr
|
||||
|
||||
@copy_one_byte_of_hostname:
|
||||
ldy src_ptr
|
||||
lda (copy_src),y
|
||||
beq @end_of_hostname
|
||||
cmp #':'
|
||||
beq @end_of_hostname
|
||||
cmp #'/'
|
||||
beq @end_of_hostname
|
||||
inc src_ptr
|
||||
ldy dest_ptr
|
||||
sta (copy_dest),y
|
||||
inc dest_ptr
|
||||
bne @copy_one_byte_of_hostname
|
||||
@end_of_hostname:
|
||||
|
||||
ldx #2 ;number of CRLF at end of HTTP request
|
||||
|
||||
@final_crlf:
|
||||
ldy dest_ptr
|
||||
lda #$0d
|
||||
sta (copy_dest),y
|
||||
@ -173,11 +256,16 @@ lda #url_type_gopher
|
||||
lda #$0a
|
||||
sta (copy_dest),y
|
||||
iny
|
||||
dex
|
||||
bne @final_crlf
|
||||
|
||||
@done:
|
||||
lda #$00
|
||||
sta (copy_dest),y
|
||||
ldax #selector_buffer
|
||||
stax url_selector
|
||||
clc
|
||||
|
||||
rts
|
||||
|
||||
skip_to_hostname:
|
||||
@ -186,7 +274,135 @@ skip_to_hostname:
|
||||
ldax #colon_slash_slash
|
||||
jmp parser_skip_next
|
||||
|
||||
.code
|
||||
|
||||
|
||||
;download a resource specified by an URL
|
||||
;inputs:
|
||||
;AX = address of URL string
|
||||
; url_download_buffer - points to a buffer that url will be downloaded into
|
||||
; url_download_buffer_length - length of buffer
|
||||
;outputs:
|
||||
; sec if an error occured, else buffer pointed at by url_download_buffer is filled with contents
|
||||
; of specified resource (with an extra 2 null bytes at the end),
|
||||
; AX = length of resource downloaded.
|
||||
url_download:
|
||||
jsr url_parse
|
||||
bcc @url_parsed_ok
|
||||
rts
|
||||
@url_parsed_ok:
|
||||
ldax url_download_buffer
|
||||
stax temp_buffer
|
||||
ldax url_download_buffer_length
|
||||
stax temp_buffer_length
|
||||
|
||||
ldx #3 ; save IP address just retrieved
|
||||
: lda url_ip,x
|
||||
sta tcp_connect_ip,x
|
||||
dex
|
||||
bpl :-
|
||||
ldax #url_download_callback
|
||||
stax tcp_callback
|
||||
|
||||
ldax url_port
|
||||
jsr tcp_connect
|
||||
bcs @error
|
||||
|
||||
;connected, now send the selector
|
||||
ldx #0
|
||||
stx download_flag
|
||||
ldax url_selector
|
||||
|
||||
jsr tcp_send_string
|
||||
;now loop until we're done
|
||||
@download_loop:
|
||||
jsr ip65_process
|
||||
lda download_flag
|
||||
beq @download_loop
|
||||
jsr tcp_close
|
||||
clc
|
||||
@error:
|
||||
rts
|
||||
|
||||
|
||||
lda #NB65_ERROR_FILE_ACCESS_FAILURE
|
||||
sta ip65_error
|
||||
sec
|
||||
rts
|
||||
|
||||
|
||||
url_download_callback:
|
||||
|
||||
lda tcp_inbound_data_length+1
|
||||
cmp #$ff
|
||||
bne @not_end_of_file
|
||||
@end_of_file:
|
||||
lda #1
|
||||
sta download_flag
|
||||
|
||||
;put a zero byte at the end of the file (in case it was a text file)
|
||||
ldax temp_buffer
|
||||
stax copy_dest
|
||||
lda #0
|
||||
tay
|
||||
sta (copy_dest),y
|
||||
rts
|
||||
@not_end_of_file:
|
||||
|
||||
;copy this chunk to our input buffer
|
||||
ldax temp_buffer
|
||||
stax copy_dest
|
||||
ldax tcp_inbound_data_ptr
|
||||
stax copy_src
|
||||
sec
|
||||
lda temp_buffer_length
|
||||
sbc tcp_inbound_data_length
|
||||
pha
|
||||
lda temp_buffer_length+1
|
||||
sbc tcp_inbound_data_length+1
|
||||
bcc @would_overflow_buffer
|
||||
sta temp_buffer_length+1
|
||||
pla
|
||||
sta temp_buffer_length
|
||||
ldax tcp_inbound_data_length
|
||||
jsr copymem
|
||||
;increment the pointer into the input buffer
|
||||
clc
|
||||
lda temp_buffer
|
||||
adc tcp_inbound_data_length
|
||||
sta temp_buffer
|
||||
lda temp_buffer+1
|
||||
adc tcp_inbound_data_length+1
|
||||
sta temp_buffer+1
|
||||
; lda #'*'
|
||||
; jsr print_a
|
||||
|
||||
rts
|
||||
@would_overflow_buffer:
|
||||
pla ;clean up the stack
|
||||
ldax temp_buffer_length
|
||||
jsr copymem
|
||||
lda temp_buffer
|
||||
adc temp_buffer_length
|
||||
sta temp_buffer
|
||||
lda temp_buffer+1
|
||||
adc temp_buffer_length+1
|
||||
sta temp_buffer+1
|
||||
lda #0
|
||||
sta temp_buffer_length
|
||||
sta temp_buffer_length+1
|
||||
rts
|
||||
|
||||
.rodata
|
||||
get: .byte "GET "
|
||||
get_length=4
|
||||
http_version_and_host: .byte " HTTP/1.1",$0d,$0a, "Host: ",0
|
||||
; http_trailer: .byte " HTTP/1.1",$0a,$0a
|
||||
; http_trailer_end:
|
||||
; http_trailer_length=http_trailer_end-http_trailer
|
||||
|
||||
colon_slash_slash: .byte ":/"
|
||||
slash: .byte "/",0
|
||||
colon: .byte ":",0
|
||||
|
||||
|
@ -31,6 +31,7 @@ all: \
|
||||
testdottedquad.prg\
|
||||
test_tcp.prg \
|
||||
test_parser.prg \
|
||||
test_get_url.prg \
|
||||
|
||||
%.o: %.c
|
||||
$(CC) -c $(CFLAGS) $<
|
||||
@ -44,6 +45,11 @@ all: \
|
||||
test_tcp.prg: test_tcp.o $(IP65TCPLIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64prg.cfg
|
||||
$(LD) -m test_tcp.map -vm -C ../cfg/c64prg.cfg -o test_tcp.prg $(AFLAGS) $< $(IP65TCPLIB) $(C64PROGLIB)
|
||||
|
||||
test_parser.prg: test_parser.o $(IP65TCPLIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64prg.cfg
|
||||
$(LD) -m test_parser.map -vm -C ../cfg/c64prg.cfg -o test_parser.prg $(AFLAGS) $< $(IP65TCPLIB) $(C64PROGLIB)
|
||||
|
||||
test_get_url.prg: test_get_url.o $(IP65TCPLIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64prg.cfg
|
||||
$(LD) -m test_get_url.map -vm -C ../cfg/c64prg.cfg -o test_get_url.prg $(AFLAGS) $< $(IP65TCPLIB) $(C64PROGLIB)
|
||||
|
||||
%.pg2: %.o $(IP65LIB) $(APPLE2PROGLIB) $(INCFILES) ../cfg/a2bin.cfg
|
||||
$(LD) -C ../cfg/a2bin.cfg -o $*.pg2 $(AFLAGS) $< $(IP65LIB) $(APPLE2PROGLIB)
|
||||
|
@ -209,7 +209,7 @@ selector: .asciiz "SELECTOR: "
|
||||
press_a_key: .byte "PRESS ANY KEY TO CONTINUE",13,0
|
||||
|
||||
atom_file:
|
||||
.incbin "atom_test.xml"
|
||||
;.incbin "atom_test.xml"
|
||||
|
||||
|
||||
.byte 0
|
Loading…
Reference in New Issue
Block a user