Better CLI.

dev
Philippe PITTOLI 2019-10-10 03:35:21 +02:00
parent 91b99de473
commit 3b6073a949
1 changed files with 113 additions and 29 deletions

View File

@ -10,9 +10,11 @@ prefered_network_configuration_program = nil
prefered_wireless_configuration_program = nil
prefered_dhcp_client = nil
root = "/"
print_autodetect = false
command = "list"
args = Array(String).new
OptionParser.parse! do |parser|
parser.on "-s", "--simulation", "Export the network configuration." do
@ -35,6 +37,10 @@ OptionParser.parse! do |parser|
prefered_dhcp_client = prog
end
parser.on "-r root", "--root root", "Root where to search for <root>/etc/hostname.* files." do |optsn|
root = optsn
end
parser.on "-f file", "--file file", "Parse a configuration file." do |optsn|
file = optsn
end
@ -57,22 +63,22 @@ OptionParser.parse! do |parser|
parser.unknown_args do |arg|
command = arg.shift
args = arg
case command
when /^(list)/
STDERR.puts "TODO: list" unless arg.empty?
when /^(up)/
STDERR.puts "TODO: up" unless arg.empty?
when /^(down)/
STDERR.puts "TODO: down" unless arg.empty?
when /^(scan)/
else
STDERR.puts "Command #{command} not understood"
end
unless arg.empty?
STDERR.puts "unknown arg: #{arg}"
exit 1
end
# unless arg.empty?
# STDERR.puts "unknown arg: #{arg}"
# exit 1
# end
end
parser.on "-h", "--help", "Show this help" do
@ -92,6 +98,15 @@ class Do < Process
Process.run cmd, params
end
end
def self.run(cmd : String, params : Array(String) = nil, &block : Process -> _)
if @@simulation
puts "simulation, do: #{cmd} #{params.join(" ")}"
Process::Status.new 0
else
Process.run cmd, params, &block
end
end
end
class NotSetup
@ -109,14 +124,29 @@ end
class NetworkCommands
class_property cmd_network_configuration : IfconfigCommand.class | IPCommand.class = IfconfigCommand
class_property cmd_wireless_configuration : IWCommand.class | NotSetup.class = NotSetup
class_property cmd_wireless_configuration : IfconfigCommand.class | IWCommand.class | NotSetup.class = NotSetup
class_property cmd_dhcp_client : UDHCPCCommand.class | DHClientCommand.class | NotSetup.class = NotSetup
class IWCommand
def self.get_ssid(ifname : String, ssid)
unless Do.run(cmd, [ ifname ]).success?
raise "(#{cmd}) dhcp failed on #{ifname}"
# get the available SSID
def self.scan(ifname : String) : Array(String)
ssids = Array(String).new
Do.run("iw", [ ifname, "scan" ]) do |p|
p.output.each_line do |line|
ssid = /SSID: (?<ssid>[a-zA-Z0-9_-]+)/.match(line).try &.["ssid"]
unless ssid.nil?
ssids << ssid
end
end
end
if ssids.empty?
raise "(iw) cannot get ssid list from #{ifname}"
end
ssids
end
end
@ -190,6 +220,11 @@ class NetworkCommands
raise "(ifconfig) Cannot set down #{name}"
end
end
# ifconfig also performs wireless configuration on some OSs
def self.scan(name : String)
puts "TODO: (ifconfig) ifconfig ifname scan | grep SSID"
end
end
class IPCommand
@ -293,13 +328,13 @@ class NetworkCommands
@@cmd_network_configuration.down name
end
def self.wireless_list_ssid(ifname : String)
def self.scan(ifname : String)
cmd = @@cmd_wireless_configuration
case cmd
when NotSetup.class
puts "no wireless configuration program: cannot list ssid"
when IWCommand.class
cmd.list_ssid ifname
else
cmd.scan ifname
end
end
@ -308,7 +343,7 @@ class NetworkCommands
case cmd
when NotSetup.class
puts "no wireless configuration program: cannot connect to ssid #{ssid}"
when IWCommand.class
else
cmd.list_ssid ifname
end
end
@ -566,6 +601,15 @@ class InterfaceConfiguration
NetworkCommands.flush name
NetworkCommands.down name
end
def scan
unless NetworkCommands.interface_exists(@name)
raise "The interface #{@name} doesn't exists or is already down."
end
ssid_list = NetworkCommands.scan name
pp! ssid_list
end
end
class NetworkConfigurationParser
@ -819,7 +863,8 @@ possible_dhcp_clients = {
# iw = linux
possible_wireless_configuration_cmds = {
"iw" => NetworkCommands::IWCommand
"iw" => NetworkCommands::IWCommand,
"ifconfig" => NetworkCommands::IfconfigCommand
}
key = prefered_network_configuration_program
@ -838,20 +883,59 @@ key = possible_wireless_configuration_cmds.keys.find { |key| Autodetect.which(ke
NetworkCommands.cmd_wireless_configuration = possible_wireless_configuration_cmds[key.not_nil!]
if file.nil?
raise "Cannot search for files yet"
files = Array(String).new
Dir.children("#{root}/etc/").each do |f|
if /^hostname\./.match(f)
files << f
end
end
case command
when "list"
interface_files = Array(String).new
if ! file.nil?
# file passed via the '-f' option
# TODO: why having to force "not_nil!" ? Seems like a compiler bug
puts NetworkConfigurationParser.parse_file(file.not_nil!)
when "up"
# TODO: why having to force "not_nil!" ? Seems like a compiler bug
network_configuration = NetworkConfigurationParser.parse_file(file.not_nil!)
network_configuration.execute
when "down"
# TODO: why having to force "not_nil!" ? Seems like a compiler bug
network_configuration = NetworkConfigurationParser.parse_file(file.not_nil!)
network_configuration.down
interface_files << file.not_nil!
elsif args.empty?
# every configured interface
files.each do |f|
interface_files << "#{root}/etc/#{f}"
end
else
# only interfaces in arguments
args.each do |interface|
interface_files << "#{root}/etc/hostname.#{interface}"
end
end
begin
case command
when "list"
interface_files.each do |f|
puts NetworkConfigurationParser.parse_file(f.not_nil!)
end
when "up"
# TODO: why having to force "not_nil!" ? Seems like a compiler bug
interface_files.each do |f|
network_configuration = NetworkConfigurationParser.parse_file(f.not_nil!)
network_configuration.execute
end
when "down"
# TODO: why having to force "not_nil!" ? Seems like a compiler bug
interface_files.each do |f|
network_configuration = NetworkConfigurationParser.parse_file(f.not_nil!)
network_configuration.down
end
when "scan"
# TODO: why having to force "not_nil!" ? Seems like a compiler bug
interface_files.each do |f|
network_configuration = NetworkConfigurationParser.parse_file(f.not_nil!)
network_configuration.scan
end
end
rescue e
STDERR.puts "#{CRED}Exception: #{CRESET}#{e}"
end