#!/usr/bin/ruby

require 'celluloid'
require 'socket'

# More complex port Scanner using Celluloid
# By Daniel González Lopes

class ScanPort

  include Celluloid

  def initialize(startPort, endPort, host)        # => ASIGNATION and INIT
    @startPort = startPort                        #
    @endPort = endPort                            # Creation of an ..
    @host = host                                  # with ..
  end                                             #

  def run                                         # =>
    until @startPortPort == @endPort do           #
      scan @startPort                             #
      @startPort += 1                             #
    end                                           #
  end                                             #

  def scan(port)
      begin
        sock = Socket.new(:INET, :STREAM)        #build the socket
        raw = Socket.sockaddr_in(port, @host)

        puts "#{port} open." if sock.connect(raw)
      rescue
        if sock != nil
          sock.close
        end
      end
    end
end

def main
  host = ARGV[0]              #Host Input
  startPort = ARGV[1].to_i    #Start Port Input
  endPort = ARGV[2].to_i      #End Port Input

  segment_size = 100

  until startPort >= endPort do
    sp = ScanPort.new startPort, startPort + segment_size, host
    sp.async.run

    startPort += segment_size
  end
end

main
