file_option : String? = nil OptionParser.parse do |parser| parser.on "-s", "--simulation", "Export the network configuration." do Context.simulation = true end parser.on "-k keydir", "--keydir keydir", "Key storing directory for wireless access point connection." do |keydir| Context.keydir = keydir end parser.on "-a", "--print-autodetect", "Print autodetection of the installed programs." do Context.print_autodetect = true end parser.on "-w wireless-configuration-program", "--wireless wireless-configuration-program", "iw" do |prog| Context.prefered_wireless_configuration_program = prog end parser.on "-n network-configuration-program", "--net-conf network-configuration-program", "ifconfig | ip" do |prog| Context.prefered_network_configuration_program = prog end parser.on "-d dhcp-client-program", "--dhcp-client dhcp-client-program", "udhcpc | dhclient" do |prog| Context.prefered_dhcp_client = prog end parser.on "-r root", "--root root", "Root where to search for /etc/hostname.* files." do |optsn| Context.root = optsn end parser.on "-f file", "--file file", "Parse a configuration file." do |optsn| file_option = optsn end # 0: nothing is printed, 1: only events, 2: events and messages parser.on "-v verbosity", "--verbosity verbosity", "Verbosity (0-2). Default: 1" do |optsn| Context.verbosity = optsn.to_i end parser.missing_option do |opt| STDERR.puts "You missed the argument for option #{opt}" # TODO: explain the different arguments exit 1 end parser.invalid_option do |flag| STDERR.puts "Error: #{flag} not a valid option" exit 1 end parser.unknown_args do |arg| Context.command = arg.shift Context.args = arg case Context.command when /^(list)/ when /^(up)/ when /^(down)/ when /^(scan)/ when /^(store-keys)/ when /^(context)/ else STDERR.puts "Command #{Context.command} not understood" exit 1 end # unless arg.empty? # STDERR.puts "unknown arg: #{arg}" # exit 1 # end end parser.on "-h", "--help", "Show this help" do puts parser exit 0 end end Do.simulation = Context.simulation Autodetect.print_autodetect = Context.print_autodetect # # discover available configuration commands # # ifconfig = *bsd and some linux # ip = linux possible_network_configuration_cmds = { "ifconfig" => NetworkCommands::IfconfigCommand, "ip" => NetworkCommands::IPCommand } # udhcpc = busybox dhcp client possible_dhcp_clients = { "udhcpc" => NetworkCommands::UDHCPCCommand, "dhclient" => NetworkCommands::DHClientCommand } # iw = linux possible_wireless_configuration_cmds = { "iw" => NetworkCommands::IWCommand, "ifconfig" => NetworkCommands::IfconfigCommand } # first, check if we are on OpenBSD Context.os = Autodetect.uname case Context.os when "Linux" key = Context.prefered_network_configuration_program key = possible_network_configuration_cmds.keys.find { |key| Autodetect.which(key) } if key.nil? # should crash if there is no network command installed NetworkCommands.cmd_network_configuration = possible_network_configuration_cmds[key.not_nil!] key = Context.prefered_wireless_configuration_program key = possible_wireless_configuration_cmds.keys.find { |key| Autodetect.which(key) } if key.nil? # should crash if there is no wireless command installed NetworkCommands.cmd_wireless_configuration = possible_wireless_configuration_cmds[key.not_nil!] key = Context.prefered_dhcp_client key = possible_dhcp_clients.keys.find { |key| Autodetect.which(key) } if key.nil? # should not crash if there is no dhcp client on the system NetworkCommands.cmd_dhcp_client = possible_dhcp_clients[key] unless key.nil? NetworkCommands.cmd_sysctl = NetworkCommands::SysctlCommand when "OpenBSD" NetworkCommands.cmd_network_configuration = NetworkCommands::OpenBSDIfconfigCommand NetworkCommands.cmd_wireless_configuration = NetworkCommands::OpenBSDIfconfigCommand NetworkCommands.cmd_dhcp_client = NetworkCommands::OpenBSDDHClientCommand NetworkCommands.cmd_sysctl = NetworkCommands::OpenBSDSysctlCommand end files = Array(String).new Dir.children("#{Context.root}/etc/").each do |f| if /^hostname\./.match(f) files << f end end interface_files = Array(String).new if ! file_option.nil? # file passed via the '-f' option # TODO: why having to force "not_nil!" ? Seems like a compiler bug interface_files << file_option.not_nil! elsif Context.args.empty? # every configured interface files.each do |f| interface_files << "#{Context.root}/etc/#{f}" end else # only interfaces in arguments Context.args.each do |interface| interface_files << "#{Context.root}/etc/hostname.#{interface}" end end begin case Context.command when "list" interface_files.each do |f| puts NetworkConfigurationParser.parse_file(f) end when "up" interface_files.each do |f| network_configuration = NetworkConfigurationParser.parse_file(f) network_configuration.execute end when "down" interface_files.each do |f| network_configuration = NetworkConfigurationParser.parse_file(f) network_configuration.down end when "scan" interface_files.each do |f| network_configuration = NetworkConfigurationParser.parse_file(f) network_configuration.scan end when "store-keys" interface_files.each do |f| network_configuration = NetworkConfigurationParser.parse_file(f) network_configuration.store_access_point_keys end when "context" pp! Context.root pp! Context.keydir pp! Context.simulation pp! Context.verbosity pp! Context.prefered_network_configuration_program pp! Context.prefered_wireless_configuration_program pp! Context.prefered_dhcp_client pp! Context.print_autodetect pp! Context.command pp! Context.args end rescue e STDERR.puts "#{CRED}Exception: #{CRESET}#{e}" end