tojour 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c160c80eded75c02c4244a52105371b859788377
4
+ data.tar.gz: 87136a5b12e33f1e0ffd766b5073edad4d449e32
5
+ SHA512:
6
+ metadata.gz: 31b0db7f147a705e01fa108e8ea056d0458f54fd6afdf24f8b5fe01ebb0cb430b7e4b5129cdf6aa877c47b7bec08a222e60f9e83b7525ca3048c69756a07a025
7
+ data.tar.gz: 0e010491320fbc3a6a16ad8f93dd25793fd6cddc5fe7a706d39ef5e43e94010da11cc9bdcc1b6175de28b31363ae2f39ac307e328fd6eb143a1083c193436ca3
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ .DS_Store
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.5
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in tojour.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Roger Jungemann
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # Tojour
2
+
3
+ Like AirDrop for the command line.
4
+
5
+ Make your computer available over Bonjour for someone to send you a file. Uses
6
+ SSL sockets.
7
+
8
+ ## Installation
9
+
10
+ Install it yourself as:
11
+
12
+ $ gem install tojour
13
+
14
+ ## Usage
15
+
16
+ ### Let Someone Send you a File
17
+
18
+ On your machine, run the following to wait for a file. Assuming your username is
19
+ `jbiebz`.
20
+
21
+ ```bash
22
+ tojour -r jbiebz
23
+ ```
24
+
25
+ Have your friend run the following to send you a file. Assuming the file you
26
+ want to send is located at `some_file.txt`.
27
+
28
+ ```bash
29
+ tojour -s some_file.txt jbiebz
30
+ ```
31
+
32
+ ### Let Someone Pipe you a Log
33
+
34
+ Your friend wants to send you pipe you some data. On your machine, make your
35
+ machine available over Bonjour.
36
+
37
+ ```bash
38
+ tojour -i jbiebz
39
+ ```
40
+
41
+ On their machine, run a command, and pipe the output to `tojour`.
42
+
43
+ ```bash
44
+ ruby -e 'loop { puts 'Wow!'; sleep 1 }' | tojour -o jbiebz
45
+ ```
46
+
47
+ ### Get Help
48
+
49
+ List arguments you can pass to `tojour`.
50
+
51
+ ```bash
52
+ tojour
53
+ ```
54
+
55
+ ### List People Waiting for Files
56
+
57
+ List all the people on your network waiting for files or logs.
58
+
59
+ ```bash
60
+ tojour -l
61
+ ```
62
+
63
+ ## Development
64
+
65
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run
66
+ `bin/console` for an interactive prompt that will allow you to experiment.
67
+
68
+ To install this gem onto your local machine, run `bundle exec rake install`. To
69
+ release a new version, update the version number in `version.rb`, and then run
70
+ `bundle exec rake release` to create a git tag for the version, push git commits
71
+ and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
72
+
73
+ ## Contributing
74
+
75
+ 1. Fork it ( https://github.com/[my-github-username]/tojour/fork )
76
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
77
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
78
+ 4. Push to the branch (`git push origin my-new-feature`)
79
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/tojour ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative '../lib/tojour/opt_parser'
4
+ require_relative '../lib/tojour/cli'
5
+
6
+ optparser = Tojour::OptParser.new(ARGV.dup)
7
+ Tojour::Cli.new(optparser.options).send(optparser.method, *optparser.argv)
8
+
data/keys/server.crt ADDED
@@ -0,0 +1,13 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIICATCCAWoCCQDjuYV1G+F6zjANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB
3
+ VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
4
+ cyBQdHkgTHRkMB4XDTE1MDcyNTIwMTk1MVoXDTE2MDcyNDIwMTk1MVowRTELMAkG
5
+ A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
6
+ IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArjnQ
7
+ HXwjU7gD/PRVk/NOTstxRolSUJlQGaybM+6PM4nOUi1BLx58TtxSfAQxgzVNbpXM
8
+ EElrpvuJHsTMj2ZinSS3rJitOAJ1qJfqE6VOJ88+/sijfv3aMB5YUyCjajYKCjrB
9
+ ead73bPQUhMcewDJtZgUycSOa2V2YgrgCjf0xuECAwEAATANBgkqhkiG9w0BAQsF
10
+ AAOBgQChmiuZMlFvYApshntbafZiALABf9WYPOm2E/m9iQ+5g6BGf5/imXTehdmB
11
+ DMSnIZtCQqWiIypzlCpAeoUoO6jOigs4i1F9xunbZuIVNX3valBPNeX+nNmHS2NW
12
+ SyW7UjpN4bfKSoFkeFsst+bKK6vaQgkyHFZSlUVK1bHfcDioDA==
13
+ -----END CERTIFICATE-----
data/keys/server.csr ADDED
@@ -0,0 +1,11 @@
1
+ -----BEGIN CERTIFICATE REQUEST-----
2
+ MIIBhDCB7gIBADBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEh
3
+ MB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEB
4
+ AQUAA4GNADCBiQKBgQCuOdAdfCNTuAP89FWT805Oy3FGiVJQmVAZrJsz7o8zic5S
5
+ LUEvHnxO3FJ8BDGDNU1ulcwQSWum+4kexMyPZmKdJLesmK04AnWol+oTpU4nzz7+
6
+ yKN+/dowHlhTIKNqNgoKOsF5p3vds9BSExx7AMm1mBTJxI5rZXZiCuAKN/TG4QID
7
+ AQABoAAwDQYJKoZIhvcNAQELBQADgYEAYMmfsP+vLknDkL8uCwXJo2kepnOV86j2
8
+ P6tCRep7nA/zfblcabBM03WxL33vST2Cbe/pXU1kMBxdQgCelIb0Himf7YnABuW0
9
+ 2w6tWh6WROpuS2ezzRFX9ZUPdepIRW33xi0p8EtZa/9kJs1qUScRoWtwCtTOrfNd
10
+ LeZNo2Ef0Ww=
11
+ -----END CERTIFICATE REQUEST-----
data/keys/server.key ADDED
@@ -0,0 +1,15 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIICWwIBAAKBgQCuOdAdfCNTuAP89FWT805Oy3FGiVJQmVAZrJsz7o8zic5SLUEv
3
+ HnxO3FJ8BDGDNU1ulcwQSWum+4kexMyPZmKdJLesmK04AnWol+oTpU4nzz7+yKN+
4
+ /dowHlhTIKNqNgoKOsF5p3vds9BSExx7AMm1mBTJxI5rZXZiCuAKN/TG4QIDAQAB
5
+ AoGAaiYNFzm/6EzwGRjgXvDZIAaxcDFQNo0CEXJpaP2Kv/LRAp5R3ZxsTjvMAYUo
6
+ iXFbSOn5V170ONt90oJCw4e0wlmpI5VeKMB3T4hJhCyai6nkJPR6R0yvLQFtNrwe
7
+ ky6eVanQAugreU0UyYAlvFoKv2fLfEhpwZndKRYTk9WmpbECQQDd4G+hY0SqNzfL
8
+ /pGA7ucA/MojrLHdHlo3s9q5hrTldt81iGtuhu5eF5ByrGOINy1YyE9ySlC6+9KP
9
+ Fxd0Bbw9AkEAyQVNZsjP0LNVOUqXs+lvl9ixzal5nQwe737DkvbIc5PkBrgD+DML
10
+ mwCkt90QDfALtYnB3dkSjtdACD3AW42rdQJAcoBpe3L8M4+NdvPn6Q7hHcxXEPQF
11
+ UiRg0JA7lzTiU+z1oe3F62MszlgAzn0SXHCFMWUmQsgBQ43Dit6S1uhCzQJAbwq4
12
+ yPBgq56Ek1M7HazzcePHxB28Ch6p8A4MJuCftgiZy4RW3QIFhSgD1XUN60UQksV4
13
+ C/5fG/yXaHYEDg7iCQJAM0QMxX96sgZ/dwO7lqOKYP47xmRz+3FNaX1X5u6rMBhF
14
+ WhLzUKAbNAJ+tAGHNR7AtaT8wAir/JG7xDVtc457Nw==
15
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1,18 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ Proc-Type: 4,ENCRYPTED
3
+ DEK-Info: DES-EDE3-CBC,A269AEC7F8083E02
4
+
5
+ ry/7s32zECM61hAol2jhS1UyUNRDjZgjIOq2C4VPUBNVHae2SmEUNrH8hthljGPS
6
+ pj03eEBw3THc+bgKNmeZ8AQPcrf8sOZdpLCg8MDpg9kmFOz/EFfzL2tDZExG80TE
7
+ 3mBuYcr1zcXEaWu7ml/MtQJ1Kn9P3jhvBm/ljKsLm3CgxZnd18hy+gZtjeG8rt3m
8
+ IaikO2cbq9fJgSLGpRFRSFVuYObW9oJNYVaGwRm/SYHE+2MPzAJL2Hom16lkOvM3
9
+ 4bcz9JRmetdezoTVWMglyfqucNNf23QRr9Ptyf5EdC236FrJOxyiMxMF/ExQeCvX
10
+ uDtwmjjsC/wuTNDEQRW7G+WlfMKg31XZNo9uJgSgXD2LyyYBIj3NOLGXRYu0ARtL
11
+ 8/d/+5Zr6YPGTWKWKapuE4ffwObRkwotH1mM9qMDuvbX5E00ZVvJjWTTb9kZMWkH
12
+ gengy2GmphSe+HZWbK4EEXzDaXj97PRptCFEdbuPk5wmS0L7JQSFSoID5IUMxT21
13
+ mN6Z8ByQTQsRphsOBSexFG3Srq5ZE02LZqKIzEoFzqOkssnci6/KvRUPO+ail782
14
+ +xQoB+l5M7Z4Y7E4g0bcqomPx+yLoC/Tg0suWpowI47II8/2xxkcXBPo5QSY6Khb
15
+ X6NmjhZu30szmcdVFlK7GCWzWNTeFJ2byYAcsCaJuOSO3o4hP94GsDBMZRPXDd9A
16
+ eDfaeqGOeoLZODE6rtg2KWvsNRg7q9YATHroBMcsbBBXW4vi1TGm+iTbwsef7q5N
17
+ Z5uAEUncWwsI6vuLb/Tj2TTqM4YmV2ZymX0Z49Jhxss=
18
+ -----END RSA PRIVATE KEY-----
data/lib/tojour/cli.rb ADDED
@@ -0,0 +1,89 @@
1
+ require 'base64'
2
+ require_relative 'utils'
3
+ require_relative 'sock'
4
+ require_relative 'jour'
5
+
6
+ module Tojour
7
+ class Cli
8
+ def initialize(options)
9
+ @options = options
10
+ end
11
+
12
+ def send_file(name)
13
+ Jour.new(name, 'file').resolve do |r|
14
+ Utils.log "Found #{name} running at #{r.target}:#{r.port}"
15
+ File.open(@options[:send_filename]) do |f|
16
+ Utils.log "Sending \"#{@options[:send_filename]}\"."
17
+ Sock.new(@options).client(r.target, r.port) do |client|
18
+ client.puts('### ' + @options[:send_filename])
19
+ loop do
20
+ begin
21
+ client.puts(Base64.strict_encode64(f.readpartial(1024)))
22
+ rescue EOFError
23
+ client.puts '### done'
24
+ break
25
+ end
26
+ end
27
+ Utils.log "Done!"
28
+ exit
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ def receive_file(name)
35
+ Jour.new(name, 'file').register(@options[:port]) do |r|
36
+ Utils.log "Registered as #{name}."
37
+ Sock.new(@options).server do |server|
38
+ connection = server.accept
39
+ file_name = connection.gets.chomp.gsub(/^### /, '')
40
+ Utils.log "Receiving file \"#{file_name}\"."
41
+ File.open(file_name, 'w') do |f|
42
+ while line = connection.gets
43
+ line = line.chomp
44
+ break if line === '### done'
45
+ f.write Base64.strict_decode64(line)
46
+ end
47
+ end
48
+ Utils.log "Done!"
49
+ exit
50
+ end
51
+ end
52
+ end
53
+
54
+ def output(name)
55
+ Jour.new(name, 'file').resolve do |r|
56
+ Utils.log "Found #{name} running at #{r.target}:#{r.port}"
57
+ Sock.new(@options).client(r.target, r.port) do |client|
58
+ Utils.log "Sending log data from STDIN."
59
+ $stdin.each do |line|
60
+ puts line
61
+ client.puts(Base64.strict_encode64(line))
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ def input(name)
68
+ Jour.new(name, 'file').register(@options[:port]) do |r|
69
+ Utils.log "Registered as #{name}."
70
+ Sock.new(@options).server do |server|
71
+ connection = server.accept
72
+ Utils.log "Receiving log data."
73
+ while line = connection.gets
74
+ # next unless line
75
+ line = line.chomp
76
+ $stdout.puts Base64.strict_decode64(line)
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ def list
83
+ Jour.list do |kind, name|
84
+ Utils.log("#{name} (#{kind})")
85
+ end
86
+ end
87
+ end
88
+ end
89
+
@@ -0,0 +1,38 @@
1
+ require 'dnssd'
2
+
3
+ module Tojour
4
+ class Jour
5
+ def initialize(name, kind)
6
+ @name = name
7
+ @protocol = "_tojour_#{kind}._tcp"
8
+ end
9
+
10
+ def register(port, &block)
11
+ DNSSD::register(@name, @protocol, nil, port) do |r|
12
+ block.call(r)
13
+ end
14
+ loop do
15
+ sleep 1
16
+ end
17
+ end
18
+
19
+ def resolve(&block)
20
+ DNSSD.resolve(@name, @protocol, 'local') do |r|
21
+ block.call(r)
22
+ end
23
+ loop do
24
+ sleep 1
25
+ end
26
+ end
27
+
28
+ def self.list(&block)
29
+ %w[file io].each do |kind|
30
+ DNSSD.browse("_tojour_#{kind}._tcp") do |r|
31
+ block.call(kind, r.name)
32
+ end
33
+ end
34
+ sleep 5
35
+ end
36
+ end
37
+ end
38
+
@@ -0,0 +1,75 @@
1
+ require 'optparse'
2
+
3
+ module Tojour
4
+ class OptParser
5
+ attr_accessor :options, :argv, :method
6
+
7
+ def initialize(argv)
8
+ options = {
9
+ is_send_file: false,
10
+ is_receive_file: false,
11
+ is_input: false,
12
+ is_output: false,
13
+ is_list_file_clients: false,
14
+ is_list: false,
15
+ send_filename: nil,
16
+ port: 9876,
17
+
18
+ key_path: ENV['KEY_PATH'] || %[#{File.dirname(__FILE__)}/../../keys/server.key],
19
+ csr_path: ENV['CSR_PATH'] || %[#{File.dirname(__FILE__)}/../../keys/server.csr],
20
+ crt_path: ENV['CRT_PATH'] || %[#{File.dirname(__FILE__)}/../../keys/server.crt]
21
+ }
22
+ methods = [
23
+ :send_file,
24
+ :receive_file,
25
+ :input,
26
+ :output,
27
+ :list
28
+ ]
29
+ optparse = OptionParser.new do |opts|
30
+ opts.banner = 'USAGE: tojour [options] name'
31
+
32
+ opts.on('-s FILE', '--send FILE', 'Transmit a FILE.') do |filename|
33
+ options[:is_send_file] = true
34
+ options[:send_filename] = filename
35
+ end
36
+
37
+ opts.on('-r', '--receive', 'Receive a file.') do |filename|
38
+ options[:is_receive_file] = true
39
+ options[:receive_filename] = filename
40
+ end
41
+
42
+ opts.on('-i', '--input', 'Receive input and output to STOUT.') do
43
+ options[:is_input] = true
44
+ end
45
+
46
+ opts.on('-o', '--output', 'Transmit output from STDIN.') do
47
+ options[:is_output] = true
48
+ end
49
+
50
+ opts.on('-l', '--list-clients', 'List clients.') do
51
+ options[:is_list] = true
52
+ end
53
+
54
+ opts.on('-p PORT', '--port PORT', 'Port to wait on.') do |port|
55
+ options[:port] = port
56
+ end
57
+
58
+ opts.on_tail('-h', '--help', 'Show this message.') do
59
+ STDERR.puts optparse.help
60
+ exit
61
+ end
62
+ end
63
+
64
+ @options = options
65
+ @argv = optparse.parse(argv)
66
+ true_values = methods.select { |name| options[:"is_#{name}"] == true }
67
+ @method = true_values.first.to_s.gsub(/^is_/, '').to_sym
68
+ if true_values.count != 1
69
+ STDERR.puts optparse.help
70
+ exit
71
+ end
72
+ end
73
+ end
74
+ end
75
+
@@ -0,0 +1,48 @@
1
+ require 'socket'
2
+ require 'openssl'
3
+ require_relative 'utils'
4
+
5
+ Thread.abort_on_exception = true
6
+
7
+ module Tojour
8
+ class Sock
9
+ attr_accessor :options, :key_path, :crt_path, :port
10
+
11
+ def initialize(options)
12
+ @options = options
13
+ @key_path = @options[:key_path]
14
+ @crt_path = @options[:crt_path]
15
+ @port = @options[:port]
16
+ end
17
+
18
+ def server(&block)
19
+ Utils.log("Listening on port #{@port}.")
20
+ block.call(ssl_server)
21
+ end
22
+
23
+ def client(host, port, &block)
24
+ block.call(ssl_client)
25
+ end
26
+
27
+ def ssl_server
28
+ server = TCPServer.new(@port)
29
+ ssl_context = OpenSSL::SSL::SSLContext.new
30
+ ssl_context.cert = OpenSSL::X509::Certificate.new(File.open(@crt_path))
31
+ ssl_context.key = OpenSSL::PKey::RSA.new(File.open(@key_path))
32
+ OpenSSL::SSL::SSLServer.new(server, ssl_context)
33
+ end
34
+
35
+ def ssl_client
36
+ socket = TCPSocket.new(host, port)
37
+ expected_cert = OpenSSL::X509::Certificate.new(File.open(@crt_path))
38
+ ssl_client = OpenSSL::SSL::SSLSocket.new(socket)
39
+ ssl_client.sync_close = true
40
+ ssl_client.connect
41
+ if ssl_client.peer_cert.to_s != expected_cert.to_s
42
+ $stderr.puts 'Unexpected certificate.'
43
+ exit(1)
44
+ end
45
+ end
46
+ end
47
+ end
48
+
@@ -0,0 +1,15 @@
1
+ require 'colorize'
2
+
3
+ module Tojour
4
+ class Utils
5
+ def self.log(msg)
6
+ $stderr.puts(msg.colorize(:light_blue))
7
+ end
8
+
9
+ def self.sh(cmd)
10
+ $stderr.puts(cmd.colorize(:yellow))
11
+ Kernel.system(cmd)
12
+ end
13
+ end
14
+ end
15
+
@@ -0,0 +1,3 @@
1
+ module Tojour
2
+ VERSION = "0.1.0"
3
+ end
data/lib/tojour.rb ADDED
@@ -0,0 +1,10 @@
1
+ require_relative 'tojour/version'
2
+ require_relative 'tojour/cli'
3
+ require_relative 'tojour/jour'
4
+ require_relative 'tojour/opt_parser'
5
+ require_relative 'tojour/sock'
6
+ require_relative 'tojour/utils'
7
+
8
+ module Tojour
9
+ # Your code goes here...
10
+ end
data/tojour.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'tojour/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'tojour'
8
+ spec.version = Tojour::VERSION
9
+ spec.authors = ['Roger Jungemann']
10
+ spec.email = ['roger@thefifthcircuit.com']
11
+
12
+ spec.summary = %q{Like AirDrop for the command line.}
13
+ spec.homepage = 'https://github.com/rjungemann/tojour'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ spec.bindir = 'bin'
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_dependency 'dnssd', '~> 3.0.1'
22
+ spec.add_dependency 'colorize', '~> 0.7.7'
23
+ spec.add_development_dependency 'bundler', '~> 1.8'
24
+ spec.add_development_dependency 'rake', '~> 10.0'
25
+ end
metadata ADDED
@@ -0,0 +1,122 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tojour
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Roger Jungemann
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: dnssd
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 3.0.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 3.0.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: colorize
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.7.7
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.7.7
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.8'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.8'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ description:
70
+ email:
71
+ - roger@thefifthcircuit.com
72
+ executables:
73
+ - tojour
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - ".rspec"
79
+ - ".travis.yml"
80
+ - CODE_OF_CONDUCT.md
81
+ - Gemfile
82
+ - LICENSE.txt
83
+ - README.md
84
+ - Rakefile
85
+ - bin/tojour
86
+ - keys/server.crt
87
+ - keys/server.csr
88
+ - keys/server.key
89
+ - keys/server.key.org
90
+ - lib/tojour.rb
91
+ - lib/tojour/cli.rb
92
+ - lib/tojour/jour.rb
93
+ - lib/tojour/opt_parser.rb
94
+ - lib/tojour/sock.rb
95
+ - lib/tojour/utils.rb
96
+ - lib/tojour/version.rb
97
+ - tojour.gemspec
98
+ homepage: https://github.com/rjungemann/tojour
99
+ licenses:
100
+ - MIT
101
+ metadata: {}
102
+ post_install_message:
103
+ rdoc_options: []
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ required_rubygems_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ requirements: []
117
+ rubyforge_project:
118
+ rubygems_version: 2.2.2
119
+ signing_key:
120
+ specification_version: 4
121
+ summary: Like AirDrop for the command line.
122
+ test_files: []