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_CONNECTION_CLOSED EQU $8A
|
||||||
NB65_ERROR_FILE_ACCESS_FAILURE EQU $90
|
NB65_ERROR_FILE_ACCESS_FAILURE EQU $90
|
||||||
NB65_MALFORMED_URL EQU $A0
|
NB65_MALFORMED_URL EQU $A0
|
||||||
|
NB65_DNS_LOOKUP_FAILED EQU $A1
|
||||||
NB65_ERROR_OPTION_NOT_SUPPORTED EQU $FE
|
NB65_ERROR_OPTION_NOT_SUPPORTED EQU $FE
|
||||||
NB65_ERROR_FUNCTION_NOT_SUPPORTED EQU $FF
|
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
|
;outputs: AX set to a pseudo-random 16 bit number
|
||||||
ip65_random_word:
|
ip65_random_word:
|
||||||
jsr timer_read ;sets AX
|
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
|
pha
|
||||||
adc ip65_ctr_arp
|
adc ip65_ctr_arp
|
||||||
ora #$08 ;make sure we grab at least 8 bytes from eth_inp
|
ora #$08 ;make sure we grab at least 8 bytes from eth_inp
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
;text file parsing routines
|
;text file parsing routines
|
||||||
; first call parser_init
|
|
||||||
; then call parser_skip_next
|
|
||||||
|
|
||||||
.export parse_integer
|
.export parse_integer
|
||||||
.importzp copy_dest
|
.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_connect_ip
|
||||||
.export tcp_send_data_len
|
.export tcp_send_data_len
|
||||||
.export tcp_send
|
.export tcp_send
|
||||||
|
.export tcp_send_string
|
||||||
.export tcp_close
|
.export tcp_close
|
||||||
.export tcp_listen
|
.export tcp_listen
|
||||||
|
|
||||||
@ -368,6 +369,33 @@ tcp_close:
|
|||||||
rts
|
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:
|
tcp_send:
|
||||||
;send tcp data
|
;send tcp data
|
||||||
;inputs:
|
;inputs:
|
||||||
@ -378,6 +406,7 @@ tcp_send:
|
|||||||
; carry flag is set if an error occured, clear otherwise
|
; carry flag is set if an error occured, clear otherwise
|
||||||
|
|
||||||
stax tcp_send_data_ptr
|
stax tcp_send_data_ptr
|
||||||
|
|
||||||
lda tcp_state
|
lda tcp_state
|
||||||
cmp #tcp_cxn_state_established
|
cmp #tcp_cxn_state_established
|
||||||
beq @connection_established
|
beq @connection_established
|
||||||
@ -646,8 +675,19 @@ tcp_process:
|
|||||||
bit tcp_inp+tcp_flags_field
|
bit tcp_inp+tcp_flags_field
|
||||||
beq @not_reset
|
beq @not_reset
|
||||||
jsr check_current_connection
|
jsr check_current_connection
|
||||||
bcs @not_current_connection_on_rst
|
bcs @not_current_connection_on_rst
|
||||||
;connection has been reset so mark it as closed
|
;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
|
lda #tcp_cxn_state_closed
|
||||||
sta tcp_state
|
sta tcp_state
|
||||||
lda #NB65_ERROR_CONNECTION_RESET_BY_PEER
|
lda #NB65_ERROR_CONNECTION_RESET_BY_PEER
|
||||||
|
@ -11,18 +11,34 @@
|
|||||||
.import output_buffer
|
.import output_buffer
|
||||||
.importzp copy_src
|
.importzp copy_src
|
||||||
.importzp copy_dest
|
.importzp copy_dest
|
||||||
|
.import copymem
|
||||||
|
|
||||||
.import ip65_error
|
.import ip65_error
|
||||||
|
.import ip65_process
|
||||||
.import parser_init
|
.import parser_init
|
||||||
.import parser_skip_next
|
.import parser_skip_next
|
||||||
.import dns_set_hostname
|
.import dns_set_hostname
|
||||||
.import dns_resolve
|
.import dns_resolve
|
||||||
.import parse_integer
|
.import parse_integer
|
||||||
.import dns_ip
|
.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_ip
|
||||||
.export url_port
|
.export url_port
|
||||||
.export url_selector
|
.export url_selector
|
||||||
.export url_resource_type
|
.export url_resource_type
|
||||||
.export url_parse
|
.export url_parse
|
||||||
|
.export url_download
|
||||||
|
.export url_download_buffer
|
||||||
|
.export url_download_buffer_length
|
||||||
|
|
||||||
target_string=copy_src
|
target_string=copy_src
|
||||||
search_string=copy_dest
|
search_string=copy_dest
|
||||||
@ -41,6 +57,16 @@ selector_buffer=output_buffer
|
|||||||
|
|
||||||
src_ptr: .res 1
|
src_ptr: .res 1
|
||||||
dest_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
|
.code
|
||||||
|
|
||||||
|
|
||||||
@ -102,7 +128,11 @@ lda #url_type_gopher
|
|||||||
jsr dns_set_hostname
|
jsr dns_set_hostname
|
||||||
bcs @exit_with_sec
|
bcs @exit_with_sec
|
||||||
jsr dns_resolve
|
jsr dns_resolve
|
||||||
bcs @exit_with_sec
|
bcc :+
|
||||||
|
lda #NB65_DNS_LOOKUP_FAILED
|
||||||
|
sta ip65_error
|
||||||
|
jmp @exit_with_sec
|
||||||
|
:
|
||||||
;copy IP address
|
;copy IP address
|
||||||
ldx #3
|
ldx #3
|
||||||
:
|
:
|
||||||
@ -138,19 +168,23 @@ lda #url_type_gopher
|
|||||||
;first byte after / in a gopher url is the resource type
|
;first byte after / in a gopher url is the resource type
|
||||||
ldy src_ptr
|
ldy src_ptr
|
||||||
lda (copy_src),y
|
lda (copy_src),y
|
||||||
|
beq @start_of_selector
|
||||||
sta url_resource_type
|
sta url_resource_type
|
||||||
inc src_ptr
|
inc src_ptr
|
||||||
jmp @start_of_selector
|
jmp @start_of_selector
|
||||||
@not_gopher:
|
@not_gopher:
|
||||||
cmp #url_type_http
|
cmp #url_type_http
|
||||||
bne @done ; if it's not gopher or http, we don't know how to build a selector
|
beq @build_http_request
|
||||||
ldy #3
|
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
|
sty dest_ptr
|
||||||
:
|
:
|
||||||
lda get,y
|
lda get,y
|
||||||
sta (copy_dest),y
|
sta (copy_dest),y
|
||||||
dey
|
dey
|
||||||
bpl :-
|
bpl :-
|
||||||
|
|
||||||
@start_of_selector:
|
@start_of_selector:
|
||||||
lda #'/'
|
lda #'/'
|
||||||
inc dest_ptr
|
inc dest_ptr
|
||||||
@ -166,6 +200,55 @@ lda #url_type_gopher
|
|||||||
inc dest_ptr
|
inc dest_ptr
|
||||||
bne @copy_one_byte
|
bne @copy_one_byte
|
||||||
@end_of_selector:
|
@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
|
ldy dest_ptr
|
||||||
lda #$0d
|
lda #$0d
|
||||||
sta (copy_dest),y
|
sta (copy_dest),y
|
||||||
@ -173,11 +256,16 @@ lda #url_type_gopher
|
|||||||
lda #$0a
|
lda #$0a
|
||||||
sta (copy_dest),y
|
sta (copy_dest),y
|
||||||
iny
|
iny
|
||||||
|
dex
|
||||||
|
bne @final_crlf
|
||||||
|
|
||||||
@done:
|
@done:
|
||||||
lda #$00
|
lda #$00
|
||||||
sta (copy_dest),y
|
sta (copy_dest),y
|
||||||
ldax #selector_buffer
|
ldax #selector_buffer
|
||||||
|
stax url_selector
|
||||||
clc
|
clc
|
||||||
|
|
||||||
rts
|
rts
|
||||||
|
|
||||||
skip_to_hostname:
|
skip_to_hostname:
|
||||||
@ -186,7 +274,135 @@ skip_to_hostname:
|
|||||||
ldax #colon_slash_slash
|
ldax #colon_slash_slash
|
||||||
jmp parser_skip_next
|
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: .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 ":/"
|
colon_slash_slash: .byte ":/"
|
||||||
slash: .byte "/",0
|
slash: .byte "/",0
|
||||||
colon: .byte ":",0
|
colon: .byte ":",0
|
||||||
|
|
||||||
|
|
@ -31,6 +31,7 @@ all: \
|
|||||||
testdottedquad.prg\
|
testdottedquad.prg\
|
||||||
test_tcp.prg \
|
test_tcp.prg \
|
||||||
test_parser.prg \
|
test_parser.prg \
|
||||||
|
test_get_url.prg \
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(CC) -c $(CFLAGS) $<
|
$(CC) -c $(CFLAGS) $<
|
||||||
@ -44,6 +45,11 @@ all: \
|
|||||||
test_tcp.prg: test_tcp.o $(IP65TCPLIB) $(C64PROGLIB) $(INCFILES) ../cfg/c64prg.cfg
|
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)
|
$(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
|
%.pg2: %.o $(IP65LIB) $(APPLE2PROGLIB) $(INCFILES) ../cfg/a2bin.cfg
|
||||||
$(LD) -C ../cfg/a2bin.cfg -o $*.pg2 $(AFLAGS) $< $(IP65LIB) $(APPLE2PROGLIB)
|
$(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
|
press_a_key: .byte "PRESS ANY KEY TO CONTINUE",13,0
|
||||||
|
|
||||||
atom_file:
|
atom_file:
|
||||||
.incbin "atom_test.xml"
|
;.incbin "atom_test.xml"
|
||||||
|
|
||||||
|
|
||||||
.byte 0
|
.byte 0
|
Loading…
Reference in New Issue
Block a user