co 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +108 -0
- data/Rakefile +2 -0
- data/bin/co +150 -0
- data/co.gemspec +25 -0
- data/lib/co/version.rb +3 -0
- data/lib/co.rb +5 -0
- metadata +96 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 33b0f645332faffdf5d106d4e4b3ae69a88d055d
|
4
|
+
data.tar.gz: 12835f2e27c9f554f6b56aa71bc430e146e58024
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 68942169a3e85d54ea386c571b47db755642d054df2f7ddf03d0af34e6b3ec90e6ea6546fa042491df47f175bb3263cdf826b1ac181dce09b4d64eba085d1a00
|
7
|
+
data.tar.gz: db9d7346e7b5504c5df2058786a2e789f336216c387429c0d6e1ffe5269e69409c0c01f6fc9e21204a3316ba635951b7948c084aff1cf09234891d8bea6ca48e
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 0catac0
|
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,108 @@
|
|
1
|
+
# Co
|
2
|
+
|
3
|
+
Co stands for Command Organizer.
|
4
|
+
|
5
|
+
You may use co to remember and organize shell commands.
|
6
|
+
|
7
|
+
Imagine you have successfully figured out the command to do a firewall scan for MAC address spoofing, say:
|
8
|
+
|
9
|
+
nmap -v -sT -PN --spoof-mac 0 192.168.1.1
|
10
|
+
|
11
|
+
Chances are that the next time you want to do a firewall scan, you have forgotten the arguments. If you are lucky you may find the command with a combination of 'grep' and 'history'.
|
12
|
+
|
13
|
+
For these situations you can use co.
|
14
|
+
|
15
|
+
After you have executed a command that you might want to reuse later;
|
16
|
+
|
17
|
+
$ co save
|
18
|
+
|
19
|
+
This will save the command for reuse. By default co will tag this command with the current directory.
|
20
|
+
|
21
|
+
At a later stage just;
|
22
|
+
|
23
|
+
$ co
|
24
|
+
|
25
|
+
And use the arrow keys to cycle the commands that are tagged with the directory that you are currently in. If you wish change some arguments and then press enter to execute the (modified) command.
|
26
|
+
|
27
|
+
Besides the automatic pwd tags, you may also define your own tags. And specify a message that helps you remember the exact use for the command.
|
28
|
+
For the nmap example you could use:
|
29
|
+
|
30
|
+
$ co save @scan @nmap -m "perform firewall scan with random mac"
|
31
|
+
|
32
|
+
At a later stage, when you need to do a scan, you can;
|
33
|
+
|
34
|
+
$ co list @scan
|
35
|
+
|
36
|
+
And co will print a list of commands that tagged with @scan, with an id and the message you provided:
|
37
|
+
|
38
|
+
3 | nmap -v -sT -PN --spoof-mac 0 192.168.1.1 | perform firewall scan with random mac
|
39
|
+
|
40
|
+
To execute the command you can;
|
41
|
+
|
42
|
+
$ co 3
|
43
|
+
|
44
|
+
## Installation
|
45
|
+
|
46
|
+
Install co with:
|
47
|
+
|
48
|
+
$ gem install co
|
49
|
+
|
50
|
+
|
51
|
+
IMPORTANT:
|
52
|
+
|
53
|
+
You need to include the following export into your bash profile.
|
54
|
+
|
55
|
+
`export PROMPT_COMMAND="history -a;"$PROMPT_COMMAND`
|
56
|
+
|
57
|
+
After this bash will sync your history file on every command.
|
58
|
+
Without it, co will save the last command of your previous session every time.
|
59
|
+
|
60
|
+
## Usage
|
61
|
+
|
62
|
+
- co save [@tag] [@tag] [-m message]
|
63
|
+
|
64
|
+
Save last command from history to the database.
|
65
|
+
Co automatically tags the saved command with @[pwd].
|
66
|
+
Tags should start with the @ character to be recognized as such.
|
67
|
+
The -m message should be provided within quotes "".
|
68
|
+
|
69
|
+
- co
|
70
|
+
|
71
|
+
Cycles through commands tagged with [@pwd].
|
72
|
+
If there are no commands found in the database, the command falls through.
|
73
|
+
|
74
|
+
- co @tag
|
75
|
+
|
76
|
+
Cycles through commands tagged with @tag
|
77
|
+
If there are no commands found in the database, the command falls through.
|
78
|
+
|
79
|
+
- co list [all] [@tag]
|
80
|
+
|
81
|
+
without optional arguments: lists commands for @[pwd]
|
82
|
+
all: lists all commands in the database
|
83
|
+
@tag: lists commands for @tag
|
84
|
+
|
85
|
+
- co id
|
86
|
+
|
87
|
+
execute command identified by id (integer)
|
88
|
+
|
89
|
+
- co delete id
|
90
|
+
|
91
|
+
delete command identified by id
|
92
|
+
|
93
|
+
## Configuration
|
94
|
+
|
95
|
+
By default the database is created as ~/.co/co.db.
|
96
|
+
|
97
|
+
Co looks for a .coconfig file in your home directory.
|
98
|
+
In this config file, you may specify a custom location for a database as a key value pair, with 'db' as the key;
|
99
|
+
|
100
|
+
db=/home/0catac0/dropbox/co.db
|
101
|
+
|
102
|
+
## Contributing
|
103
|
+
|
104
|
+
1. Fork it ( https://github.com/[my-github-username]/co/fork )
|
105
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
106
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
107
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
108
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/bin/co
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "optparse"
|
4
|
+
require "sqlite3"
|
5
|
+
require "readline"
|
6
|
+
|
7
|
+
#use default_path
|
8
|
+
default_path = "#{ENV['HOME']}/.co/co.db"
|
9
|
+
path = default_path
|
10
|
+
|
11
|
+
#check for coniguration
|
12
|
+
if File.exists? "#{ENV['HOME']}/.coconfig"
|
13
|
+
#read config file
|
14
|
+
config = Hash[*File.read("#{ENV['HOME']}/.coconfig").split(/[= \n]+/)]
|
15
|
+
if(config['db'])
|
16
|
+
#set path from config
|
17
|
+
path = config['db']
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
#create default directory if necessary
|
22
|
+
if path == default_path
|
23
|
+
Dir.mkdir "#{ENV['HOME']}/.co" unless Dir.exists? "#{ENV['HOME']}/.co"
|
24
|
+
end
|
25
|
+
|
26
|
+
db = SQLite3::Database.new path
|
27
|
+
db.execute "CREATE TABLE IF NOT EXISTS commands(id INTEGER PRIMARY KEY, cmd TEXT UNIQUE, description TEXT)"
|
28
|
+
db.execute "CREATE TABLE IF NOT EXISTS tags(id INTEGER PRIMARY KEY, tag TEXT UNIQUE)"
|
29
|
+
db.execute "CREATE TABLE IF NOT EXISTS command_tags(cmd_id INTEGER, tag_id INTEGER, UNIQUE (cmd_id,tag_id) ON CONFLICT REPLACE)"
|
30
|
+
|
31
|
+
pwd = `pwd`
|
32
|
+
pwd.strip!
|
33
|
+
|
34
|
+
options = {}
|
35
|
+
optparse = OptionParser.new do |opts|
|
36
|
+
opts.on('-m STR','Provide a description for the command') do | desc |
|
37
|
+
options[:description] = desc
|
38
|
+
end
|
39
|
+
end
|
40
|
+
optparse.parse!
|
41
|
+
|
42
|
+
#Save the last command in the command history to the database
|
43
|
+
#NB. for this to work, EXPORT PROMPT_COMMAND="history -a;"
|
44
|
+
if(ARGV[0] == 'save')
|
45
|
+
|
46
|
+
cmd = `tail -n 1 ${HOME}/.bash_history`
|
47
|
+
cmd.strip!
|
48
|
+
|
49
|
+
description = options[:description]
|
50
|
+
|
51
|
+
#treat any tokens that start with @ as tags
|
52
|
+
tags = []
|
53
|
+
tags << "@#{pwd}"
|
54
|
+
ARGV.each do | token |
|
55
|
+
if(token.start_with? "@")
|
56
|
+
tags << token
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
#insert stuff into the database
|
61
|
+
begin
|
62
|
+
#find or insert command
|
63
|
+
db.execute "INSERT OR IGNORE INTO commands(cmd,description) VALUES ('#{cmd}','#{description}');"
|
64
|
+
cmd_id = db.get_first_value "SELECT id from commands WHERE cmd = '#{cmd}';"
|
65
|
+
|
66
|
+
tags.each do |tag|
|
67
|
+
#find or insert tag
|
68
|
+
db.execute "INSERT OR IGNORE INTO tags(tag) VALUES ('#{tag}')"
|
69
|
+
tag_id = db.get_first_value "SELECT id from tags WHERE tag = '#{tag}';"
|
70
|
+
|
71
|
+
#insert connection
|
72
|
+
db.execute "INSERT INTO command_tags(cmd_id,tag_id) VALUES (#{cmd_id},#{tag_id})"
|
73
|
+
|
74
|
+
end
|
75
|
+
rescue SQLite3::Exception => e
|
76
|
+
puts e
|
77
|
+
end
|
78
|
+
db.close if db
|
79
|
+
exit #quit
|
80
|
+
end
|
81
|
+
|
82
|
+
#select all commands in current pwd
|
83
|
+
if(ARGV[0] == 'list')
|
84
|
+
tag = "@#{pwd}"
|
85
|
+
if(ARGV[1] != nil && ARGV[1].start_with?("@"))
|
86
|
+
tag = ARGV[1]
|
87
|
+
end
|
88
|
+
tag_id = db.get_first_value "SELECT id from tags WHERE tag = '#{tag}'"
|
89
|
+
if(tag_id)
|
90
|
+
rows = db.execute "SELECT * from commands WHERE id in (SELECT cmd_id from command_tags where tag_id = '#{tag_id}')"
|
91
|
+
for row in rows do
|
92
|
+
puts row.join "\s | \s"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
#delete the command
|
98
|
+
if(ARGV[0] == 'delete' && Integer(ARGV[1]) rescue false )
|
99
|
+
cmd_id = ARGV[1].to_i
|
100
|
+
db.execute "DELETE FROM commands WHERE id = #{cmd_id}"
|
101
|
+
db.execute "DELETE FROM command_tags where cmd_id = #{cmd_id}"
|
102
|
+
db.close
|
103
|
+
exit
|
104
|
+
end
|
105
|
+
|
106
|
+
if(ARGV[0] == 'tags')
|
107
|
+
rows = db.execute "SELECT tag from tags"
|
108
|
+
for row in rows do
|
109
|
+
puts row
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
#execute the provided id
|
114
|
+
if(Integer(ARGV[0]) rescue false)
|
115
|
+
cmd_id = ARGV[0].to_i
|
116
|
+
cmd = db.get_first_value "SELECT cmd from commands where id = #{cmd_id};"
|
117
|
+
if(cmd)
|
118
|
+
exec cmd
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
#Default behaviour
|
123
|
+
#Cycle through commands saved for pwd
|
124
|
+
if(ARGV.length == 0 || (ARGV[0] != nil && ARGV[0].start_with?("@")))
|
125
|
+
|
126
|
+
tag = "@#{pwd}"
|
127
|
+
if(ARGV[0] != nil && ARGV[0].start_with?("@"))
|
128
|
+
tag = ARGV[0]
|
129
|
+
end
|
130
|
+
tag_id = db.get_first_value "SELECT id from tags WHERE tag = '#{tag}'"
|
131
|
+
|
132
|
+
if(tag_id)
|
133
|
+
rows = db.execute "SELECT * from commands WHERE id in (SELECT cmd_id from command_tags where tag_id = '#{tag_id}')"
|
134
|
+
LIST = []
|
135
|
+
rows.each do | row |
|
136
|
+
Readline::HISTORY << row[1]
|
137
|
+
#LIST << row[1]
|
138
|
+
end
|
139
|
+
|
140
|
+
#comp = proc {|s| LIST.grep(/^#{Regexp.escape(s)}/)}
|
141
|
+
#Readline.completion_proc = comp
|
142
|
+
|
143
|
+
while line = Readline.readline('co> ', true)
|
144
|
+
if(line != "")
|
145
|
+
system line
|
146
|
+
end
|
147
|
+
break
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
data/co.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 'co/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "co"
|
8
|
+
spec.version = Co::VERSION
|
9
|
+
spec.authors = ["0catac0"]
|
10
|
+
spec.email = ["taco@yavin4.nl"]
|
11
|
+
spec.summary = %q{Command organizer}
|
12
|
+
spec.description = %q{Use co to remember and organize shell commands.}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
|
24
|
+
spec.add_runtime_dependency "sqlite3"
|
25
|
+
end
|
data/lib/co/version.rb
ADDED
data/lib/co.rb
ADDED
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: co
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- 0catac0
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-06-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sqlite3
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Use co to remember and organize shell commands.
|
56
|
+
email:
|
57
|
+
- taco@yavin4.nl
|
58
|
+
executables:
|
59
|
+
- co
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- .gitignore
|
64
|
+
- Gemfile
|
65
|
+
- LICENSE.txt
|
66
|
+
- README.md
|
67
|
+
- Rakefile
|
68
|
+
- bin/co
|
69
|
+
- co.gemspec
|
70
|
+
- lib/co.rb
|
71
|
+
- lib/co/version.rb
|
72
|
+
homepage: ''
|
73
|
+
licenses:
|
74
|
+
- MIT
|
75
|
+
metadata: {}
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - '>='
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
requirements: []
|
91
|
+
rubyforge_project:
|
92
|
+
rubygems_version: 2.0.14
|
93
|
+
signing_key:
|
94
|
+
specification_version: 4
|
95
|
+
summary: Command organizer
|
96
|
+
test_files: []
|