xscreen_usb_unlocker 0.90.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +62 -0
- data/Rakefile +2 -0
- data/bin/xscreen_usb_unlocker +106 -0
- data/lib/xscreen_usb_unlocker/app.rb +75 -0
- data/lib/xscreen_usb_unlocker/config.rb +40 -0
- data/lib/xscreen_usb_unlocker/log.rb +96 -0
- data/lib/xscreen_usb_unlocker/optparser.rb +59 -0
- data/lib/xscreen_usb_unlocker/version.rb +3 -0
- data/lib/xscreen_usb_unlocker.rb +14 -0
- data/xscreen_usb_unlocker.gemspec +22 -0
- metadata +143 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Ernie Brodeur
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# XscreenUsb
|
2
|
+
|
3
|
+
This gem provides a command line application that will control xscreensaver's lock/unlock features via connecting/disconnecting a given USB device.
|
4
|
+
|
5
|
+
This will work best with a device that presents a unique serial number, and you have with you all the time . . . like your smart phone. In fact I designed this to be used with an android phone in usb debugging mode (so it will register with the system). I don't have to mount the disk, simply plugging it in is enough.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
$ gem install xscreen_usb_unlocker
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
To make sure it's not any device plugged or unpluged, you have to supply either a serial or a device id to scan for.
|
14
|
+
|
15
|
+
For now, the serial can be found with:
|
16
|
+
|
17
|
+
$ lsusb -v |grep Serial
|
18
|
+
|
19
|
+
Once you find the device (if it has a serial, most phone's do.)
|
20
|
+
|
21
|
+
$ xscreen_usb_unlocker -s SERIAL
|
22
|
+
|
23
|
+
If it doesn't provide a serial, you can also use a device id. Either the vendor, device or both can be supplied in a `vendor:device` format.
|
24
|
+
|
25
|
+
To find these just run `lsusb` and look for the `1234:ABCD` piece, that is your device id.
|
26
|
+
|
27
|
+
$ xscreen_usb_unlocker -d 1234:ABCD
|
28
|
+
|
29
|
+
You can also save these so you don't have to retype them, or have them in your history:
|
30
|
+
|
31
|
+
$ xscreen_usb_unlocker -s SERIAL -d 1234:ABCD --save-config
|
32
|
+
|
33
|
+
Last, it can be daemonized, if this happens it will write a log to your homedirectory in: `~/.logs/xscreen_usb_unlocker.log`. After you've saved your config, this is the simplest way to enable/disable it.
|
34
|
+
|
35
|
+
$ xscreen_usb_unlocker -D
|
36
|
+
|
37
|
+
You can control logging and the logfile as well, likely I will disable the log for the 1.0 release.
|
38
|
+
|
39
|
+
If you unlock xscreensaver by hand, you are not disabling this, the next time you plug/unplug your usb device, it will lock again. This is useful if for some reason your usb device isn't available, you can still use your system as normal.
|
40
|
+
|
41
|
+
## SECURITY
|
42
|
+
|
43
|
+
This is incredibly important to understand, their isn't any. This isn't a tool designed to secure your workstation, I can think of half a dozen ways to get past this easily.
|
44
|
+
|
45
|
+
Instead, this tool is for convience, to help facilitate simple locking/unlocking in a casual business/home environment.
|
46
|
+
|
47
|
+
All it does is start/kill (safely) xscreensaver based on scanning for usb devices.
|
48
|
+
|
49
|
+
## TODO:
|
50
|
+
|
51
|
+
* Add a --kill option to remove the other daemonizes.
|
52
|
+
* Add a --name to trap for the device name (regex? substring?)
|
53
|
+
* Add basic device detection to print out a pretty table to help configure it (offer options and save automatically?)
|
54
|
+
|
55
|
+
|
56
|
+
## Contributing
|
57
|
+
|
58
|
+
1. Fork it
|
59
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
60
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
61
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
62
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
require 'xscreen_usb_unlocker'
|
3
|
+
include XscreenUsbUnlocker
|
4
|
+
Options.banner = "Usage: Used to lock/unlock xscreensaver based on usb device id and serial."
|
5
|
+
Options.on("-s", "--serial SERIAL", "make sure the device matches this serial.") { |s| Options[:serial] = s}
|
6
|
+
Options.on("-d", "--device DEVICE", "make sure it is this specific device.") { |d| Options[:device] = d}
|
7
|
+
Options.on("-D", "--daemonize", "Daemonize this process in the background.") { |d| Options[:daemonize] = true}
|
8
|
+
Options.on("--save-config", "Save the device and serial to a config file and exit.") { |d| Options[:save_config] = true}
|
9
|
+
Options.parse!
|
10
|
+
|
11
|
+
if !Options[:device] && !Options[:serial]
|
12
|
+
puts 'Must supply a device or serial to look for.'
|
13
|
+
exit
|
14
|
+
end
|
15
|
+
|
16
|
+
def lock_screen
|
17
|
+
Log.info 'locking'
|
18
|
+
p = spawn "xscreensaver -no-splash"
|
19
|
+
Process.detach p
|
20
|
+
%x[xscreensaver-command -lock]
|
21
|
+
end
|
22
|
+
|
23
|
+
def unlock_screen
|
24
|
+
Log.info 'unlocking'
|
25
|
+
|
26
|
+
if xscreensaver_pids
|
27
|
+
xscreensaver_pids.each do |p|
|
28
|
+
Log.info "Appears to be pid: #{p.pid}"
|
29
|
+
Process.kill "QUIT", p.pid
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def xscreensaver_running?
|
35
|
+
xscreensaver_pids.any?
|
36
|
+
end
|
37
|
+
|
38
|
+
def xscreensaver_pids
|
39
|
+
Sys::ProcTable.ps.select{|x| x.cmdline.include?("xscreensaver") && !x.cmdline.include?("ruby")}
|
40
|
+
end
|
41
|
+
|
42
|
+
def plugged_in?
|
43
|
+
usb = LIBUSB::Context.new
|
44
|
+
options_hash = {}
|
45
|
+
|
46
|
+
if Options[:device]
|
47
|
+
v, p = Options[:device].split(":")
|
48
|
+
options_hash[:idVendor] = v.hex if v && !v.empty?
|
49
|
+
options_hash[:idProduct] = p.hex if p && !p.empty?
|
50
|
+
end
|
51
|
+
|
52
|
+
devices = usb.devices(options_hash)
|
53
|
+
return true if devices.select { |d| d.serial_number == Options[:serial]}.any?
|
54
|
+
false
|
55
|
+
end
|
56
|
+
|
57
|
+
def toggle_lock
|
58
|
+
if plugged_in?
|
59
|
+
Log.info 'unlock requested'
|
60
|
+
unlock_screen
|
61
|
+
else
|
62
|
+
Log.info 'lock request'
|
63
|
+
lock_screen
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
if __FILE__ == $0
|
68
|
+
# did we pry?
|
69
|
+
Options.on_pry
|
70
|
+
|
71
|
+
# should we save our config and bail?
|
72
|
+
if Options[:save_config]
|
73
|
+
Config["serial"] = Options[:serial] if Options[:serial]
|
74
|
+
Config["device"] = Options[:device] if Options[:device]
|
75
|
+
Config.save!
|
76
|
+
puts "Saved configuration to #{Config.file}"
|
77
|
+
exit
|
78
|
+
end
|
79
|
+
|
80
|
+
# kill a running copy of xscreensaver
|
81
|
+
if xscreensaver_running?
|
82
|
+
Log.info "xscreensaver appears to be running, killing so we can trap it."
|
83
|
+
%x[killall -QUIT xscreensaver]
|
84
|
+
end
|
85
|
+
|
86
|
+
# grab our notifications
|
87
|
+
Notifier = INotify::Notifier.new
|
88
|
+
Dir.glob("/dev/bus/usb/*").each do |d|
|
89
|
+
Notifier.watch(d, :delete, :create) do
|
90
|
+
toggle_lock
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# fire off the lock cycle once.
|
95
|
+
toggle_lock
|
96
|
+
|
97
|
+
# start the notifier, which will fire off callbacks as needed.
|
98
|
+
if Options[:daemonize] || File.file?(Config.file)
|
99
|
+
Log.debug "Opening logfile."
|
100
|
+
Log.filename "/home/ebrodeur/.logs/xscreensaver_unlocker.log"
|
101
|
+
Log.debug "Daemonizing."
|
102
|
+
App.daemonize(:mulitple_pids => false) { Notifier.run }
|
103
|
+
else
|
104
|
+
Notifier.run
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# Some requires, they don't fit elsewhere.
|
2
|
+
module XscreenUsbUnlocker
|
3
|
+
|
4
|
+
class Application
|
5
|
+
attr_accessor :version
|
6
|
+
attr_accessor :banner
|
7
|
+
attr_accessor :long_description
|
8
|
+
attr_accessor :plugins
|
9
|
+
|
10
|
+
# return the name of the app, for now this is just the cmd ran, later it will be
|
11
|
+
# something generated but more unique.
|
12
|
+
def name
|
13
|
+
$0.split("/").last
|
14
|
+
end
|
15
|
+
|
16
|
+
def cache_dir
|
17
|
+
"#{Dir.home}/.cache/erniebrodeur/#{App.name}/"
|
18
|
+
end
|
19
|
+
|
20
|
+
def config_dir
|
21
|
+
"#{Dir.home}/.config/erniebrodeur/#{App.name}/"
|
22
|
+
end
|
23
|
+
|
24
|
+
def pids
|
25
|
+
a = Sys::ProcTable.ps.select{|x| x.cmdline =~ /.*#{App.name}.*-[dD].*/}.map {|x| x.pid}
|
26
|
+
a.delete $$
|
27
|
+
return a if a.any?
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize
|
32
|
+
@version = '0.0.0'
|
33
|
+
@banner = 'A bin snippet by Ernie Brodeur that does . . . something.'
|
34
|
+
@long_description = ''
|
35
|
+
@plugins = []
|
36
|
+
end
|
37
|
+
|
38
|
+
def daemonize(*params, &block)
|
39
|
+
if params[0] && !params[0][:multiple_pids] && pids
|
40
|
+
puts_or_log :info, "#{App.name} appears to be running (#{pids}), only one allowed, exiting."
|
41
|
+
exit
|
42
|
+
end
|
43
|
+
puts_or_log :info, "Forking to background."
|
44
|
+
|
45
|
+
Process.daemon
|
46
|
+
block.call
|
47
|
+
end
|
48
|
+
|
49
|
+
def kill_daemon
|
50
|
+
if !pids
|
51
|
+
puts_or_log :fatal, "No pids found, exiting."
|
52
|
+
end
|
53
|
+
|
54
|
+
pids.each do |p|
|
55
|
+
puts_or_log :info, "Killing #{p}"
|
56
|
+
`kill -TERM #{p}`
|
57
|
+
end
|
58
|
+
end
|
59
|
+
private
|
60
|
+
def puts_or_log(l, s)
|
61
|
+
if App.plugins.include? 'logging'
|
62
|
+
Log.send l, s
|
63
|
+
else
|
64
|
+
puts s
|
65
|
+
exit if l.to_sym == :fatal
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
App = Application.new
|
71
|
+
|
72
|
+
# This will load a helper, if it exists.
|
73
|
+
f = "#{$:.last}/helpers/#{App.name}.rb"
|
74
|
+
require f if File.exist? f
|
75
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module XscreenUsbUnlocker
|
4
|
+
class ConfigBlob < Hash
|
5
|
+
BaseDir = "/home/ebrodeur/.config/erniebrodeur"
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
FileUtils.mkdir_p BaseDir if !Dir.exist? BaseDir
|
9
|
+
load
|
10
|
+
end
|
11
|
+
|
12
|
+
def file
|
13
|
+
"#{BaseDir}/#{App.name}.json"
|
14
|
+
end
|
15
|
+
|
16
|
+
def save
|
17
|
+
if any?
|
18
|
+
# I do this the long way because I want an immediate sync.
|
19
|
+
f = open(file, 'w')
|
20
|
+
f.write Yajl.dump self
|
21
|
+
f.sync
|
22
|
+
f.close
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def save!
|
27
|
+
FileUtils.rm file if File.file? file
|
28
|
+
save
|
29
|
+
end
|
30
|
+
|
31
|
+
def load
|
32
|
+
if File.exist? self.file
|
33
|
+
h = Yajl.load open(file, 'r').read
|
34
|
+
h.each { |k,v| self[k.to_sym] = v}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
App.plugins.push 'config'
|
39
|
+
Config = ConfigBlob.new
|
40
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# it should override puts and print to 'capture' output as debug output.
|
2
|
+
# It should have a semi easy to read standard format
|
3
|
+
# it will have multiple formats available.
|
4
|
+
# it should produce colorized output (either parsed or part of the file format)
|
5
|
+
require 'logger'
|
6
|
+
|
7
|
+
module XscreenUsbUnlocker
|
8
|
+
class Logger
|
9
|
+
def initialize
|
10
|
+
@options = {}
|
11
|
+
|
12
|
+
@options[:utc] = true
|
13
|
+
@options[:level] = ::Logger::DEBUG
|
14
|
+
@options[:override_puts] = false
|
15
|
+
@options[:filename] = STDOUT
|
16
|
+
|
17
|
+
create_logger
|
18
|
+
end
|
19
|
+
|
20
|
+
def method_missing(sym, *args, &block)
|
21
|
+
@l.send sym, *args, &block
|
22
|
+
exit if sym == :fatal
|
23
|
+
end
|
24
|
+
|
25
|
+
def enable(sym)
|
26
|
+
raise 'NoSuchOption' if @options[sym] == nil
|
27
|
+
@options[sym] = true
|
28
|
+
|
29
|
+
if sym == :override_puts
|
30
|
+
level ::Logger::DEBUG
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def disable(sym)
|
35
|
+
raise 'NoSuchOption' if @options[sym] == nil
|
36
|
+
@options[sym] = false
|
37
|
+
end
|
38
|
+
|
39
|
+
def level(s)
|
40
|
+
level = case s.to_sym
|
41
|
+
when :fatal then ::Logger::FATAL
|
42
|
+
when :error then ::Logger::ERROR
|
43
|
+
when :warn then ::Logger::WARN
|
44
|
+
when :info then ::Logger::INFO
|
45
|
+
when :debug then ::Logger::DEBUG
|
46
|
+
else ::Logger::UNKNOWN
|
47
|
+
end
|
48
|
+
|
49
|
+
@options[:level] = level
|
50
|
+
@l.level = level
|
51
|
+
end
|
52
|
+
|
53
|
+
def override_puts?
|
54
|
+
return true if @options[:override_puts]
|
55
|
+
false
|
56
|
+
end
|
57
|
+
|
58
|
+
def filename(file)
|
59
|
+
@options[:filename] = file
|
60
|
+
create_logger
|
61
|
+
end
|
62
|
+
private
|
63
|
+
def fmt_time
|
64
|
+
if @options[:utc]
|
65
|
+
Time.now.getutc
|
66
|
+
else
|
67
|
+
Time.now
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def create_logger
|
72
|
+
FileUtils.mkdir_p File.dirname @options[:filename] if File.file? @options[:filename]
|
73
|
+
@l = ::Logger.new(@options[:filename])
|
74
|
+
@l.level = @options[:level]
|
75
|
+
|
76
|
+
@l.formatter = proc do |severity, datetime, progname, msg|
|
77
|
+
"[#{fmt_time.asctime}] [#{severity}]: #{msg}\n"
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
App.plugins.push 'logging'
|
84
|
+
Log = Logger.new
|
85
|
+
end
|
86
|
+
|
87
|
+
# better way to do this with: Kernel.module_eval def puts ...
|
88
|
+
module Kernel
|
89
|
+
def puts (s)
|
90
|
+
if Log.override_puts?
|
91
|
+
Log.info s
|
92
|
+
else
|
93
|
+
Kernel::puts s
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
module XscreenUsbUnlocker
|
4
|
+
class OptionParser < ::OptionParser
|
5
|
+
def initialize
|
6
|
+
super
|
7
|
+
@options = {}
|
8
|
+
on("-V", "--version", "Print version") { |version| @options[:version] = true}
|
9
|
+
on("-p", "--pry", "open a pry shell.") { |pry| @options[:pry] = true}
|
10
|
+
if App.plugins.include? 'logging'
|
11
|
+
on("-l", "--log-level LEVEL", "Change the log level, default is debug.") { |level| Log.level level }
|
12
|
+
on("--log-file FILE", "What file to output to, default is STDOUT") { |file| Log.filename file }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# This will build an on/off option with a default value set to false.
|
17
|
+
def bool_on(word, description = "")
|
18
|
+
Options[word.to_sym] = false
|
19
|
+
on "-#{word.chars.first}", "--[no]#{word}", description do |o|
|
20
|
+
Options[word.to_sym] == o
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def parse!
|
25
|
+
super
|
26
|
+
|
27
|
+
if @options[:version]
|
28
|
+
puts XscreenUsbUnlocker::Version
|
29
|
+
exit 0
|
30
|
+
end
|
31
|
+
|
32
|
+
# we need to mash in our config array. To do this we want to make config
|
33
|
+
# options that don't overwrite cli options.
|
34
|
+
if App.plugins.include? 'config'
|
35
|
+
Config.each do |k,v|
|
36
|
+
@options[k] = v if !@options[k]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def on_pry
|
42
|
+
if @options[:pry]
|
43
|
+
require 'pry'
|
44
|
+
binding.pry
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def [](k)
|
49
|
+
@options[k]
|
50
|
+
end
|
51
|
+
|
52
|
+
def []=(k,v)
|
53
|
+
@options[k] = v
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
App.plugins.push "optparser"
|
58
|
+
Options = OptionParser.new
|
59
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rb-inotify'
|
2
|
+
require 'libusb'
|
3
|
+
require 'yajl'
|
4
|
+
require 'sys/proctable'
|
5
|
+
|
6
|
+
require 'xscreen_usb_unlocker/app'
|
7
|
+
require 'xscreen_usb_unlocker/log'
|
8
|
+
require 'xscreen_usb_unlocker/config'
|
9
|
+
require 'xscreen_usb_unlocker/optparser'
|
10
|
+
require "xscreen_usb_unlocker/version"
|
11
|
+
|
12
|
+
module XscreenUsbUnlocker
|
13
|
+
# Your code goes here...
|
14
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/xscreen_usb_unlocker/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Ernie Brodeur"]
|
6
|
+
gem.email = ["ebrodeur@ujami.net"]
|
7
|
+
gem.description = "A CLI tool that scans your usb ports for a device, then locks/unlocks xscreensaver."
|
8
|
+
gem.summary = "This tool is used to control xscreensaver via a USB device being plugged in and removed. It provides minor methods to scan for unique device, like serial and device id. This is rather useful with a smart phone."
|
9
|
+
gem.homepage = "https://github.com/erniebrodeur/xscreen_usb_unlocker"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "xscreen_usb_unlocker"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.add_runtime_dependency "rb-inotify"
|
17
|
+
gem.add_runtime_dependency "libusb"
|
18
|
+
gem.add_runtime_dependency "yajl-ruby"
|
19
|
+
gem.add_runtime_dependency "sys-proctable"
|
20
|
+
gem.add_development_dependency "pry"
|
21
|
+
gem.version = XscreenUsbUnlocker::VERSION
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: xscreen_usb_unlocker
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.90.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Ernie Brodeur
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-14 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rb-inotify
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: libusb
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: yajl-ruby
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: sys-proctable
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: pry
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
description: A CLI tool that scans your usb ports for a device, then locks/unlocks
|
95
|
+
xscreensaver.
|
96
|
+
email:
|
97
|
+
- ebrodeur@ujami.net
|
98
|
+
executables:
|
99
|
+
- xscreen_usb_unlocker
|
100
|
+
extensions: []
|
101
|
+
extra_rdoc_files: []
|
102
|
+
files:
|
103
|
+
- .gitignore
|
104
|
+
- Gemfile
|
105
|
+
- LICENSE
|
106
|
+
- README.md
|
107
|
+
- Rakefile
|
108
|
+
- bin/xscreen_usb_unlocker
|
109
|
+
- lib/xscreen_usb_unlocker.rb
|
110
|
+
- lib/xscreen_usb_unlocker/app.rb
|
111
|
+
- lib/xscreen_usb_unlocker/config.rb
|
112
|
+
- lib/xscreen_usb_unlocker/log.rb
|
113
|
+
- lib/xscreen_usb_unlocker/optparser.rb
|
114
|
+
- lib/xscreen_usb_unlocker/version.rb
|
115
|
+
- xscreen_usb_unlocker.gemspec
|
116
|
+
homepage: https://github.com/erniebrodeur/xscreen_usb_unlocker
|
117
|
+
licenses: []
|
118
|
+
post_install_message:
|
119
|
+
rdoc_options: []
|
120
|
+
require_paths:
|
121
|
+
- lib
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
+
none: false
|
124
|
+
requirements:
|
125
|
+
- - ! '>='
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
requirements: []
|
135
|
+
rubyforge_project:
|
136
|
+
rubygems_version: 1.8.21
|
137
|
+
signing_key:
|
138
|
+
specification_version: 3
|
139
|
+
summary: This tool is used to control xscreensaver via a USB device being plugged
|
140
|
+
in and removed. It provides minor methods to scan for unique device, like serial
|
141
|
+
and device id. This is rather useful with a smart phone.
|
142
|
+
test_files: []
|
143
|
+
has_rdoc:
|