git-svn-id: http://svn.code.sf.net/p/netboot65/code@136 93682198-c243-4bdb-bd91-e943c89aac3b

This commit is contained in:
jonnosan 2009-05-15 12:11:04 +00:00
parent eade2778dd
commit 1f536b8c7c
3 changed files with 52 additions and 28 deletions

View File

@ -102,12 +102,14 @@ exit_cart:
sta $0001 ;turns off ordinary cartridge by modifying HIRAM/LORAM (this will also bank out BASIC)
.endif
get_value_of_axy: ;some more self-modifying code
lda $ffff,y
rts
call_downloaded_prg:
jsr $0000 ;overwritten when we load a file
jmp init
.bss
.segment "CARTRIDGE_HEADER"
@ -378,18 +380,22 @@ cmp #KEYCODE_F7
@tftp_boot:
ldax #tftp_dir_filemask
@get_tftp_directory_listing:
stax nb65_param_buffer+NB65_TFTP_FILENAME
ldax #tftp_dir_buffer
stax nb65_param_buffer+NB65_TFTP_POINTER
ldax #getting_dir_listing_msg
jsr print
ldax #tftp_dir_filemask
stax nb65_param_buffer+NB65_TFTP_FILENAME
ldax #nb65_param_buffer
nb65call #NB65_TFTP_DOWNLOAD
bcs @dir_failed
lda tftp_dir_buffer ;get the first byte that was downloaded
@ -408,6 +414,33 @@ cmp #KEYCODE_F7
bcc @tftp_filename_set
jmp main_menu
@tftp_filename_set:
stax copy_dest
stax get_value_of_axy+1
ldy #0
jsr get_value_of_axy ;A now == first char in string we just downloaded
cmp #'$'
bne @not_directory_name
;it's a directory name, so we need to append the file mask to end of it
;this will fail if the file path is more than 255 characters long
@look_for_trailing_zero:
iny
inc copy_dest
bne :+
inc copy_dest+1
:
jsr get_value_of_axy ;A now == next char in string we just downloaded
bne @look_for_trailing_zero
; got trailing zero
ldax #tftp_dir_filemask+1 ;skip the leading '$'
stax copy_src
ldax #$07
jsr copymem
ldax get_value_of_axy+1
jmp @get_tftp_directory_listing
@not_directory_name:
ldax get_value_of_axy+1
jsr download
bcc @file_downloaded_ok
@tftp_boot_failed:
@ -567,7 +600,7 @@ new:
.byte"NEW ",0
tftp_dir_filemask:
.asciiz "$*.prg"
.asciiz "$/*.prg"
tftp_file:
.asciiz "BOOTC64.PRG"

View File

@ -20,6 +20,7 @@
@progname=File.basename($0)
def show_options
puts "valid options are: #{@cartridge_offsets.keys.join(", ")}"
puts "mac auto will automagically generate a pseudorandom MAC"
end
def usage
puts "#{@progname} <image> <option> <value> [<option> <value> ..]"

View File

@ -8,6 +8,7 @@
# TFTP spec : http://www.ietf.org/rfc/rfc1350.txt
require 'socket'
require 'file_list'
class Netboot65TFTPServer
@ -33,7 +34,7 @@ class Netboot65TFTPServer
attr_reader :bootfile_dir,:port,:server_thread
def initialize(bootfile_dir,port=69)
@bootfile_dir=bootfile_dir
@file_list=FileList.new(bootfile_dir)
@port=port
@server_thread=nil
@current_connection={}
@ -165,27 +166,16 @@ class Netboot65TFTPServer
opcode,filename_and_mode=data.unpack("nA*")
filename,mode=filename_and_mode.split(0.chr)
log_msg "RRQ for #{filename} (#{mode})"
if filename=~/^\./ || filename=~/\.\./ then #looks like something dodgy - either a dotfile or a directory traversal attempt
send_error(client_ip,client_port,1,"'#{filename}' invalid filename")
elsif filename=~/^\$(.*)/ then #it's a directory request
filemask="/#{$1}"
filemask="#{filemask}/*.*" unless filemask=~/\*/
log_msg "DIR for #{filemask}"
data_to_send=""
Dir.glob("#{bootfile_dir}#{filemask}").each do |full_filename|
filename=full_filename.sub(/^#{bootfile_dir}\/*/,'')
data_to_send<<"#{filename}\000"
if filename=~/^\./ || filename=~/\.\./ #looks like something dodgy - either a dotfile or a directory traversal attempt
send_error(client_ip,client_port,1,"'#{filename}' invalid filename")
else
begin
data_to_send=@file_list[filename]
Thread.new {send_data(client_ip,client_port,filename,data_to_send)}
rescue Exception=>e
send_error(client_ip,client_port,1,"error retrieving '#{filename}':#{e.to_s}")
log_msg(e.backtrace.join("\n"))
end
data_to_send<<0.chr
Thread.new {send_data(client_ip,client_port,"DIR of #{filemask}",data_to_send)}
else
full_filename="#{bootfile_dir}/#{filename}"
if File.file?(full_filename) then
data_to_send=File.open(full_filename,"rb").read
Thread.new {send_data(client_ip,client_port,full_filename,data_to_send)}
else
send_error(client_ip,client_port,1,"'#{filename}' not found")
end
end
when 2 : #WRITE REQUEST
opcode,filename_and_mode=data.unpack("nA*")