Class: Net::TFTP
- Inherits:
-
Object
- Object
- Net::TFTP
- Defined in:
- lib/net/tftp.rb
Constant Summary collapse
- VERSION =
"0.1.0"
- DEFAULTS =
{ :port => (Socket.getservbyname("tftp", "udp") rescue 69), :timeout => 5, }
- MINSIZE =
4
- MAXSIZE =
516
- DATABLOCK =
512
- ERROR_DESCRIPTION =
Errors
[ "Custom error", "File not found", "Access violation", "Disk full", "Illegal TFP operation", "Unknown transfer ID", "File already exists", "No such user", ]
- ERROR_UNDEF =
0
- ERROR_FILE_NOT_FOUND =
1
- ERROR_ACCESS_VIOLATION =
2
- ERROR_DISK_FULL =
3
- ERROR_ILLEGAL_OPERATION =
4
- ERROR_UNKNOWN_TRANSFER_ID =
5
- ERROR_FILE_ALREADY_EXISTS =
6
- ERROR_NO_SUCH_USER =
7
- OP_RRQ =
Opcodes
1
- OP_WRQ =
2
- OP_DATA =
3
- OP_ACK =
4
- OP_ERROR =
5
Instance Attribute Summary collapse
-
#host ⇒ Object
Returns the value of attribute host.
-
#timeout ⇒ Object
Returns the value of attribute timeout.
Class Method Summary collapse
-
.open(host) ⇒ Object
Alias for new.
-
.size_in_blocks(size) ⇒ Object
Return the number of blocks to send size bytes.
Instance Method Summary collapse
-
#getbinary(remotefile, io, &block) ⇒ Object
Retrieve a file using binary mode and send content to an io object The optional block receives the data in the block and the sequence number of the block starting at 1.
-
#getbinaryfile(remotefile, localfile = nil, &block) ⇒ Object
Retrieve a file using binary mode.
-
#initialize(host, params = {}) ⇒ TFTP
constructor
Create a TFTP connection object to a host.
-
#putbinary(remotefile, io, &block) ⇒ Object
Send the content read from io to the remotefile.
-
#putbinaryfile(localfile, remotefile = nil, &block) ⇒ Object
Send a file in binary mode.
Constructor Details
#initialize(host, params = {}) ⇒ TFTP
Create a TFTP connection object to a host. Note that no actual network connection is made. This methods never fails. Parameters:
- :port
-
The UDP port. See DEFAULTS
- :timeout
-
Timeout in second for each ack packet. See DEFAULTS
113 114 115 116 117 |
# File 'lib/net/tftp.rb', line 113 def initialize(host, params = {}) @host = host @port = params[:port] || DEFAULTS[:port] @timeout = params[:timeout] || DEFAULTS[:timeout] end |
Instance Attribute Details
#host ⇒ Object
Returns the value of attribute host.
106 107 108 |
# File 'lib/net/tftp.rb', line 106 def host @host end |
#timeout ⇒ Object
Returns the value of attribute timeout.
106 107 108 |
# File 'lib/net/tftp.rb', line 106 def timeout @timeout end |
Class Method Details
.open(host) ⇒ Object
Alias for new
94 95 96 |
# File 'lib/net/tftp.rb', line 94 def open(host) new(host) end |
Instance Method Details
#getbinary(remotefile, io, &block) ⇒ Object
Retrieve a file using binary mode and send content to an io object The optional block receives the data in the block and the sequence number of the block starting at 1.
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/net/tftp.rb', line 133 def getbinary(remotefile, io, &block) # :yields: data, seq s = UDPSocket.new begin peer_ip = IPSocket.getaddress(@host) rescue raise TFTPError, "Cannot find host '#{@host}'" end peer_tid = nil seq = 1 from = nil data = nil # Initialize request s.send(rrq_packet(remotefile, "octet"), 0, peer_ip, @port) Timeout::timeout(@timeout, TFTPTimeout) do loop do packet, from = s.recvfrom(MAXSIZE, 0) next unless peer_ip == from[3] type, block, data = scan_packet(packet) break if (type == OP_DATA) && (block == seq) end end peer_tid = from[1] # Get and write data to io loop do io.write(data) s.send(ack_packet(seq), 0, peer_ip, peer_tid) yield(data, seq) if block_given? break if data.size < DATABLOCK seq += 1 Timeout::timeout(@timeout, TFTPTimeout) do loop do packet, from = s.recvfrom(MAXSIZE, 0) next unless peer_ip == from[3] if peer_tid != from[1] s.send(error_packet(ERROR_UNKNOWN_TRANSFER_ID), 0, from[3], from[1]) next end type, block, data = scan_packet(packet) break if (type == OP_DATA) && (block == seq) end end end return true end |
#getbinaryfile(remotefile, localfile = nil, &block) ⇒ Object
Retrieve a file using binary mode. If the localfile name is omitted, it is set to the remotefile. The optional block receives the data in the block and the sequence number of the block starting at 1.
123 124 125 126 127 128 |
# File 'lib/net/tftp.rb', line 123 def getbinaryfile(remotefile, localfile = nil, &block) # :yields: data, seq localfile ||= File.basename(remotefile) open(localfile, "w") do |f| getbinary(remotefile, f, &block) end end |
#putbinary(remotefile, io, &block) ⇒ Object
Send the content read from io to the remotefile. The optional block receives the data in the block and the sequence number of the block starting at 1.
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
# File 'lib/net/tftp.rb', line 198 def putbinary(remotefile, io, &block) # :yields: data, seq s = UDPSocket.new peer_ip = IPSocket.getaddress(@host) peer_tid = nil seq = 0 from = nil data = nil # Initialize request s.send(wrq_packet(remotefile, "octet"), 0, peer_ip, @port) Timeout::timeout(@timeout, TFTPTimeout) do loop do packet, from = s.recvfrom(MAXSIZE, 0) next unless peer_ip == from[3] type, block, data = scan_packet(packet) break if (type == OP_ACK) && (block == seq) end end peer_tid = from[1] loop do data = io.read(DATABLOCK) || "" seq += 1 s.send(data_packet(seq, data), 0, peer_ip, peer_tid) Timeout::timeout(@timeout, TFTPTimeout) do loop do packet, from = s.recvfrom(MAXSIZE, 0) next unless peer_ip == from[3] if peer_tid != from[1] s.send(error_packet(ERROR_UNKNOWN_TRANSFER_ID), 0, from[3], from[1]) next end type, block, void = scan_packet(packet) break if (type == OP_ACK) && (block == seq) end end yield(data, seq) if block_given? break if data.size < DATABLOCK end return true end |
#putbinaryfile(localfile, remotefile = nil, &block) ⇒ Object
Send a file in binary mode. The name of the remotefile is set to the name of the local file if omitted. The optional block receives the data in the block and the sequence number of the block starting at 1.
188 189 190 191 192 193 |
# File 'lib/net/tftp.rb', line 188 def putbinaryfile(localfile, remotefile = nil, &block) # :yields: data, seq remotefile ||= File.basename(localfile) open(localfile) do |f| putbinary(remotefile, f, &block) end end |