Skip to content

Instantly share code, notes, and snippets.

Created October 26, 2013 19:43
Show Gist options
  • Save anonymous/7173655 to your computer and use it in GitHub Desktop.
Save anonymous/7173655 to your computer and use it in GitHub Desktop.
Why is CLRF undefined from within the model?
module FTP
module Common
CRLF = "\r\n"
def initialize(port = 21)
@control_socket = TCPServer.new(port)
trap(:INT) { exit }
end
def respond(response)
@client.write(response)
@client.write(CLRF)
end
class CommandHandler
attr_reader :connection
def initalize(connection)
@connection = connection
end
def pwd
@pwd || Dir.pwd
end
def handle(data)
cmd = data[0..3].strip.upcase
options = data[4..-1].strip
case cmd
when "USER"
#accept any username anonymously
"230 Logged in anonymously"
when "SYST"
#what's your name?
"215 UNIX Working with FTP"
when "CWD"
if File.directory?(options)
@pwd = options
"250 directory changed to #{pwd}"
else
"550 directory not found"
end
when "PWD"
"257 \"#{pwd}\" is the current directory"
when "PORT"
parts = options.split(',')
ip_address = parts[0..3],join('.')
port = Integer(parts[4]) * 256 + Integer(parts(5))
@data_socket = TCPSocket.new(ip_address, port)
"200 Active connection established (#{port})"
when "RETR"
file = File.read(File.join(pwd, options), 'r')
connection.respond "125 Data transfer starting #{file.size} bytes"
bytes = IO.copy_stream(file, @data_socket)
@data_socket.close
"226 Closing data connection, sent #{bytes} bytes"
when "LIST"
connection.respond "125 Opening data connection for file list"
result = Dir.entries(pwd).join(CLRF)
@data_socket.write(result)
@data_socket.close
when "QUIT"
"221 Ciao"
else
"502 Don't know how to respond to #{cmd}"
end
end
end
end
end
➜ ftp git:(master) ✗ ruby bin/serial_server.rb
/home/richard/projects/pickaxe/mini-projects/ftp/lib/ftp/common.rb:12:in `respond': uninitialized constant FTP::Common::CLRF (NameError)
from /home/richard/projects/pickaxe/mini-projects/ftp/arch/serial.rb:11:in `block in run'
from /home/richard/projects/pickaxe/mini-projects/ftp/arch/serial.rb:9:in `loop'
from /home/richard/projects/pickaxe/mini-projects/ftp/arch/serial.rb:9:in `run'
from bin/serial_server.rb:4:in `<main>'
require 'socket'
require_relative "../lib/ftp/common"
module FTP
class Serial
include Common
def run
loop do
@client = @control_socket.accept
respond "220 OHAI"
handler = CommandHandler.new(self)
loop do
request = @client.gets(CRLF)
if request
respond handler.handle(request)
else
@client.close
break
end
end
end
end
end
end
require_relative "../arch/serial"
server = FTP::Serial.new(4481)
server.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment