Class: Sheepsafe::Controller

Inherits:
Object
  • Object
show all
Defined in:
lib/sheepsafe/controller.rb

Defined Under Namespace

Classes: TeeStdout

Constant Summary collapse

LOG_FILE =
Sheepsafe::Config::FILE.sub(/\.yml/, '.log')

Instance Method Summary collapse

Constructor Details

#initialize(config = nil, network = nil, logger = nil) ⇒ Controller

Returns a new instance of Controller.



28
29
30
31
32
33
# File 'lib/sheepsafe/controller.rb', line 28

def initialize(config = nil, network = nil, logger = nil)
  @config  = config  || Sheepsafe::Config.new
  @network = network || Sheepsafe::Network.new(@config)
  @logger  = logger
  $stdout  = TeeStdout.new(self)
end

Instance Method Details

#bring_socks_proxy(direction) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/sheepsafe/controller.rb', line 91

def bring_socks_proxy(direction)
  cmd = case direction
        when 'up'   then 'start'
        when 'down' then 'stop'
        when 'kick' then 'restart'
        else
          direction
        end
  Daemons.run_proc('.sheepsafe.proxy', :ARGV => [cmd], :dir_mode => :normal, :dir => ENV['HOME']) do
    pid = nil
    trap("TERM") do
      Process.kill("TERM", pid)
      exit 0
    end
    sleep 5                 # wait a bit before starting proxy
    exit_count = 0
    ssh_command = "ssh #{@config.ssh_args}"
    loop do
      pid = fork do
        exec(ssh_command)
      end
      Process.waitpid(pid)
      exit_count += 1
      if exit_count % 2 == 1 && exit_count < 10
        log "command '#{ssh_command}' exited #{exit_count} times:\nlast time with #{$?.exitstatus}"
      end
      sleep 1
    end
  end
end

#log(msg) ⇒ Object



140
141
142
143
144
145
146
# File 'lib/sheepsafe/controller.rb', line 140

def log(msg)
  if @logger
    @logger.info(msg)
  else
    with_log_file {|f| Logger.new(f).info(msg) }
  end
end

#network_changed?Boolean

Returns:

  • (Boolean)


79
80
81
# File 'lib/sheepsafe/controller.rb', line 79

def network_changed?
  @config.last_network.nil? || @network.ssid != @config.last_network.ssid || @network.bssid != @config.last_network.bssid
end

#network_up?Boolean

Returns:

  • (Boolean)


75
76
77
# File 'lib/sheepsafe/controller.rb', line 75

def network_up?
  @network.up?
end

#notify_ok(msg) ⇒ Object



126
127
128
129
# File 'lib/sheepsafe/controller.rb', line 126

def notify_ok(msg)
  when_growl_available { Growl.notify_ok(msg) }
  log(msg)
end

#notify_warning(msg) ⇒ Object



131
132
133
134
# File 'lib/sheepsafe/controller.rb', line 131

def notify_warning(msg)
  when_growl_available { Growl.notify_warning(msg) }
  log(msg)
end

#proxy_running?Boolean

Returns:

  • (Boolean)


122
123
124
# File 'lib/sheepsafe/controller.rb', line 122

def proxy_running?
  File.exist?("#{ENV['HOME']}/.sheepsafe.proxy.pid") && File.read("#{ENV['HOME']}/.sheepsafe.proxy.pid").to_i > 0
end

#runObject



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/sheepsafe/controller.rb', line 35

def run
  log("Sheepsafe starting")

  if ARGV.first == 'proxy'  # 'sheepsafe proxy up/down/kick'
    bring_socks_proxy ARGV[1]
    return
  end

  # Always recycle the proxy server on network changes
  bring_socks_proxy 'down'
  if network_up?
    if network_changed?
      if switch_to_trusted?
        notify_ok "Switching to #{@config.trusted_location} location"
        system "scselect #{@config.trusted_location}"
      elsif switch_to_untrusted?
        notified = false
        loop do
          require 'open-uri'
          is_example_com = open("http://example.com") {|f| f.read[/(RFC 2606)/] == "RFC 2606"} rescue nil
          break if is_example_com
          notify_warning("Waiting for internet connection before switching") unless notified
          notified = true
          sleep 5
        end
        notify_warning "Switching to #{@config.untrusted_location} location"
        system "scselect #{@config.untrusted_location}"
        bring_socks_proxy 'up'
      end
      @config.last_network = @network
      @config.write
    elsif !@network.trustworthy?
      bring_socks_proxy 'up'
    end
  else
    log("AirPort is off")
  end
  log("Sheepsafe finished")
end

#switch_to_trusted?Boolean

Returns:

  • (Boolean)


83
84
85
# File 'lib/sheepsafe/controller.rb', line 83

def switch_to_trusted?
  @network.trustworthy?
end

#switch_to_untrusted?Boolean

Returns:

  • (Boolean)


87
88
89
# File 'lib/sheepsafe/controller.rb', line 87

def switch_to_untrusted?
  !@network.trustworthy?
end

#when_growl_available(&block) ⇒ Object



136
137
138
# File 'lib/sheepsafe/controller.rb', line 136

def when_growl_available(&block)
  block.call if defined?(Growl)
end

#with_log_file(&block) ⇒ Object



148
149
150
# File 'lib/sheepsafe/controller.rb', line 148

def with_log_file(&block)
  File.open(LOG_FILE, (File::WRONLY | File::APPEND), &block)
end