-
Notifications
You must be signed in to change notification settings - Fork 1
/
ssh-search-provider.js
executable file
·186 lines (145 loc) · 4.81 KB
/
ssh-search-provider.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#!/usr/bin/gjs
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const Lang = imports.lang;
const shellSearchProvider2 = (function () {
var file,
xml;
file = Gio.file_new_for_path(
'/usr/share/dbus-1/interfaces/org.gnome.ShellSearchProvider2.xml'
);
xml = file.load_contents(null)[1];
file = null;
return xml.toString();
}());
let knownHosts,
results,
sshSearcher,
// Functions
findKnownHosts,
makeRegexes,
parseKnownHosts,
searchHosts;
findKnownHosts = function findKnownHosts() {
var home = GLib.getenv('HOME'),
file,
contents;
if (knownHosts) {
return;
}
file = home + '/.ssh/known_hosts';
file = Gio.file_new_for_path(file);
contents = file.load_contents(null);
if (! contents[0]) {
return;
}
knownHosts = parseKnownHosts(contents[1].toString());
};
makeRegexes = function makeRegexes(terms) {
var regexes = [];
terms.forEach(function (term) {
regexes.push(
new GLib.Regex(term, GLib.RegexCompileFlags.JAVASCRIPT_COMPAT, 0)
);
});
return regexes;
};
parseKnownHosts = function parseKnownHosts(string) {
var hosts = {};
// Split the string into lines
string.split("\n").forEach(function (line) {
/* Each line contains three tokens: host, algorithm, key. We're only
interested in the host. The host may be a comma-separated list, in
which case we'll want all the hosts in the list. It may also be
hashed, in which case we'll ignore it. */
var tokens = line.split(' ');
/* Hashed hosts begin with a pipe character followed by a magic number,
which indicates the hashing algorithm used. So, we can ignore any hosts
that begin with a pipe character. */
if ('|' !== tokens[0][0]) {
tokens[0].split(',').forEach(function (host) {
// Strip square brackets that may be wrapping the hostname.
var h = host.replace('[', '').replace(']', '');
h = h.replace(/(?:|:.+)$/, '');
hosts[h] = true;
});
}
});
// We used an object so that we can return a distinct set of hosts thus:
return Object.keys(hosts);
};
searchHosts = function searchHosts(hosts, terms) {
var regexes = makeRegexes(terms),
results = [];
hosts.forEach(function (host) {
var matched = true;
regexes.forEach(function (regex) {
matched = matched && regex.match(host, 0)[0];
});
if (matched) {
results.push(host);
}
});
return results;
};
sshSearcher = Gio.DBusExportedObject.wrapJSObject(
shellSearchProvider2,
{
LaunchSearch: function LaunchSearch(terms, timestamp) {
// Not supported.
},
GetInitialResultSet: function GetInitialResultSet(terms) {
var toReturn;
findKnownHosts();
toReturn = searchHosts(knownHosts, terms);
return toReturn;
},
GetSubsearchResultSet: function GetSubsearchResultSet(previousResults, terms) {
return searchHosts(previousResults, terms);
},
GetResultMetas: function GetResultMetas(ids) {
var metas = [];
ids.forEach(function (id) {
var variant = new GLib.Variant('s', id);
metas.push({id: variant, name: variant});
});
return metas;
},
ActivateResult: function ActivateResult(id, terms, timestamp) {
// Terminal app must support the -e option, like GNOME Terminal.
var settings,
exec,
appInfo,
command;
settings = Gio.Settings.new(
'org.gnome.desktop.default-applications.terminal'
);
exec = settings.get_string('exec');
command = exec + ' -e "ssh ' + id + '"';
appInfo = Gio.app_info_create_from_commandline(
command,
null,
Gio.AppInfoCreateFlags.SUPPORTS_STARTUP_NOTIFICATION & Gio.AppInfoCreateFlags.SUPPORTS_URIS
);
appInfo.launch_uris([''], new Gio.AppLaunchContext({}));
}
}
);
const App = new Lang.Class({
Name: 'SshSearcher',
Extends: Gio.Application,
_init: function init() {
this.parent({
application_id: 'uk.co.zygous.sshsearcher',
flags: Gio.ApplicationFlags.IS_SERVICE
});
},
startup: function startup() {},
activate: function activate() {},
vfunc_dbus_register: function vfunc_dbus_register(connection, path) {
this.parent(connection, path);
sshSearcher.export(connection, '/uk/co/zygous/sshsearcher');
return true;
}
});
(new App()).run(ARGV);