You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

163 lines
4.0 KiB
Ruby

require 'socket'
include Socket::Constants
# A PipeSocket is an object that
def error(msg)
puts "PipeSocket: #{msg}"
exit 1
end
class PipeSocket
def initialize(name, addr, port)
@path = name
@port = port
@addr = addr
if File.exist?(name)
error("File #{name} already exists.")
end
end
def connect
puts "Opening #{@path} for read/write"
File.mkfifo(@path)
File.open(@path, "r+") { |pipe|
loop do
socket = Socket.tcp(@addr, @port)
msg = pipe.gets
socket.puts msg
resp = socket.gets
unless resp.nil?
puts resp.chomp
break if resp.chomp == "shutdown"
end
break if msg.chomp == "shutdown"
socket.close
end
}
puts "Closing #{@path}"
File.delete(@path)
end
end
#not useful?
class SocketPipe
def initialize(name, addr, port)
@path, @addr, @port = name, addr, port
if File.exist?(name)
error("File #{name} already exists.")
end
end
def listen
puts "Opening #{@path} for reading"
File.mkfifo(@path)
Socket.tcp_server_loop(@port) { |sock|
msg = sock.gets
File.open(@path, "r+") { |pipe| pipe.puts msg }
sock.close
break if msg.chomp == "shutdown"
}
puts "Closing #{@path}"
File.delete(@path)
end
end
# BackShot should be a server listening for
# a PipeSocket connection, which receives a
# ruby file containing an instance of the
# BackShot class
class BackShot
attr_accessor :send_back
attr_accessor :command
@@inst = 0
def initialize(addr, port)
@name = "backshot#{@@inst}"
@@inst += 1
@addr = addr
@port = port
@return = nil
@execute = nil
#a channel to send back the result
end
def BackShot.message(msg)
puts "BackShot: #{msg}"
end
def listen
BackShot.message "listening on port #{@port}"
loop do
#hello
Socket.tcp_server_loop(@port) { |sock|
msg = sock.gets
if msg.chomp == "hello"
sock.puts "hello"
break
else
sock.puts "goodbye"
end
sock.close
}
def recv_file(filename, expected_size)
Socket.tcp_server_loop(@port) { |sock|
data = sock.recv(expected_size)
File.open(filename, "w+") { |file| file.write data }
sock.puts "ok"
}
end
#recv files
Socket.tcp_server_loop(@port) { |sock|
msg = sock.gets
if msg.start_with? "file"
puts "file info recv"
# file name size
file, name, size = msg.split(" ")
size = size.chomp
sock.puts "ok"
recv_file(name, size)
elsif msg.start_with? "run"
puts "run recv"
# execute file
exec, name = msg.split(" ")
@execute = name
sock.puts "ok"
#sock.close
elsif msg.start_with? "return"
puts "return recv"
ret, name = msg.split(" ")
@return = name
if @execute == nil
sock.puts "error"
# sock.close
break
end
`./#{@execute}`
sock.write File.read(@return)
msg = sock.gets
if msg.chomp == "thanks"
@execute = nil
#sock.close
break
end
else
sock.puts "what"
#sock.close
end
}
end
end
end
bs = BackShot.new "127.0.0.1", 8081
bs.listen