require "ipc" require "hexa" # TODO: Write documentation for `IPCd` module IPCd VERSION = "0.1.0" @@proxy_name = "ipcd" @@proxied_service = "pong" def self.start @@proxied_service = ARGV[0] if ARGV.size >= 1 @@proxy_name = ARGV[1] if ARGV.size >= 2 puts "proxy named #{@@proxy_name} for service #{@@proxied_service}" ipcd = IPC.new() ipcd.service_init @@proxy_name ipcd.timer 10_000 timer = 0 ipcd.loop do |event| begin case event.type when LibIPC::EventType::Timer STDOUT.write "Timer #{timer}.\r".to_slice STDOUT.flush timer += 1 when LibIPC::EventType::Connection fd = ipcd.connect @@proxied_service ipcd.add_switch event.newfd, fd input = -> fn_input( LibC::Int, LibC::Char*, LibC::UInt64T*) output = -> fn_output(LibC::Int, LibC::Char*, LibC::UInt64T ) ipcd.switch_callbacks event.newfd, input, output puts "New connection (#{event.newfd}) now automatically switched to '#{@@proxied_service}' (#{fd})!" when LibIPC::EventType::Disconnection puts "Disconnection from #{event.fd}." when LibIPC::EventType::MessageTx puts "Message sent to #{event.fd}." when LibIPC::EventType::MessageRx puts "Message received from #{event.fd}." when LibIPC::EventType::SwitchRx #puts "Switch message received from #{event.fd}." when LibIPC::EventType::SwitchTx #puts "Switch message sent to #{event.fd}." when LibIPC::EventType::Error puts "And error occured on fd #{event.fd}." else puts "Unhandled IPC event: #{event.class}." if event.responds_to?(:fd) puts "closing #{event.fd}" ipcd.close event.fd end end rescue exception puts "exception: #{typeof(exception)} - #{exception.message}" end end end end def fn_input(fd : LibC::Int, buffer : LibC::Char*, buflen : LibC::UInt64T*) : LibC::Char io = IO::FileDescriptor.new fd, close_on_finalize: false slice = Bytes.new buffer, buflen.value len = io.read slice buflen.value = len.to_u64 return 2_u8 if (len == 0) hexa = Hexa.new 50_000 bytes = Bytes.new buffer, buflen.value puts hexa.dump "message received from #{fd}", bytes 0_u8 rescue e puts "fn_input exception! #{e}" 1_u8 end def fn_output(fd : LibC::Int, buffer : LibC::Char*, buflen : LibC::UInt64T) : LibC::Char hexa = Hexa.new 50_000 bytes = Bytes.new buffer, buflen puts hexa.dump "message to send to #{fd}", bytes slice = Bytes.new buffer, buflen io = IO::FileDescriptor.new fd, close_on_finalize: false io.write slice io.flush 0_u8 rescue e puts "fn_output exception! #{e}" 1_u8 end IPCd.start