Skip to content
This repository was archived by the owner on Jan 4, 2022. It is now read-only.

Commit 294c932

Browse files
committed
Not First Commit
1 parent 13d62c2 commit 294c932

File tree

8 files changed

+819
-0
lines changed

8 files changed

+819
-0
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
# Only for Dan
2+
GetAll.js
3+
rootfs
4+
tizen-sdk
5+
tmp
6+
db.json
7+
18
# Logs
29
logs
310
*.log

1 - Bus Name Discovery.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
const { cfg, setData, runAsShell, runAsPkg } = require('./common');
2+
3+
const { join } = require('path'),
4+
{ readFileSync, statSync, readdirSync } = require('fs');
5+
6+
function getNamesFromRootfs(parentPath, result = []) {
7+
console.log(`getNamesFromRootfs: parent: ${parentPath}`);
8+
9+
readdirSync(parentPath).forEach(child => {
10+
const childPath = join(parentPath, child),
11+
stat = statSync(childPath);
12+
13+
if (stat.isDirectory()) {
14+
getNamesFromRootfs(childPath, result); // Recursive!
15+
return;
16+
}
17+
18+
if (!stat.isFile()) {
19+
return;
20+
}
21+
22+
console.log(`getNamesFromRootfs: child: ${childPath}`);
23+
24+
const content = readFileSync(childPath, {encoding: 'utf-8'});
25+
if (!/\[D-BUS Service\]/i.test(content)) {
26+
return;
27+
}
28+
29+
const [_, name] = content.match(/Name\s*=\s*([^\s]+)$/im) || [];
30+
if (name === undefined) {
31+
return;
32+
}
33+
34+
result.push(name);
35+
});
36+
37+
return result;
38+
}
39+
40+
function getNamesFromTarget() {
41+
const result = runAsShell('dbus-send --system --dest=org.freedesktop.DBus --type=method_call --print-reply /org/freedesktop/DBus org.freedesktop.DBus.ListNames');
42+
return result.match(/string "[^"]+"/g).map(v => v.split('"')[1]);
43+
}
44+
45+
function deduplicate(result = []) {
46+
const dict = {};
47+
result.forEach(v => dict[v] = true);
48+
return Object.keys(dict);
49+
}
50+
51+
async function main() {
52+
// Recursively grab the names from D-Bus service files
53+
let names = getNamesFromRootfs(join(cfg.rootfs, '/usr/share/dbus-1/'));
54+
55+
// Grab the names of the running bus names
56+
names.push(...getNamesFromTarget());
57+
58+
// Remove duplicates from an array
59+
names = deduplicate(names);
60+
61+
// Log
62+
console.log(`#${names.length}: ${names}`);
63+
64+
// Save names
65+
setData('names', names);
66+
}
67+
68+
main();

2 - Object Introspection.js

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
const { cfg, getData, setData, runAsShell, runAsPkg } = require('./common'),
2+
{ randomFillSync } = require('crypto'),
3+
{ parseString } = require('xml2js'),
4+
{ parse: parseGetAll } = require('./GetAll');
5+
6+
const cnames = ['INVALID', 'BYTE', 'BOOLEAN', 'INT16', 'UINT16', 'INT32', 'UINT32', 'INT64', 'UINT64', 'DOUBLE', 'STRING', 'OBJECT_PATH', 'SIGNATURE', 'ARRAY', 'STRUCT', 'VARIANT', 'DICT ENTRY', 'UNIX FD'];
7+
8+
async function parseXML(xml) {
9+
return new Promise((resolve, reject) => {
10+
parseString(xml, {
11+
mergeAttrs: true,
12+
// explicitArray: false
13+
}, (err, result) => {
14+
if (err) {
15+
return reject(err);
16+
} else {
17+
return resolve(result);
18+
}
19+
});
20+
});
21+
}
22+
23+
async function introspect(runner) {
24+
/*
25+
_root = {
26+
bus.na.me: { // Level 1: Destination
27+
/obj/ect: { // Level 2: Object
28+
in.ter.face: { // Level 3: Interface
29+
'method': { // Level 4: 'method'
30+
MethodName: [
31+
{name: "argument_name", type: "a{type}", direction: "in/out"},
32+
...
33+
],
34+
...
35+
},
36+
'signal': { // Level 4: 'signal'
37+
SignalName: [
38+
{name: "argument_name", type: "a{type}"},
39+
...
40+
],
41+
...
42+
},
43+
'property': { // Level 4: 'property'
44+
PropertyName1: "property_value",
45+
PropertyName2: null,
46+
...
47+
}
48+
}
49+
},
50+
...
51+
},
52+
...
53+
}
54+
*/
55+
const _root = {};
56+
57+
/*
58+
shelf = [
59+
{dest: "bus.na.me", object: "/", interface: null},
60+
{dest: "bus.na.me", object: "/", interface: "in.ter.face"},
61+
]
62+
63+
Temporary shelf for a batch of commands
64+
- If interface is null, call Introspectable.Introspect
65+
- If interface is not null, call Properties.GetAll
66+
*/
67+
68+
// let shelf = getData('names').map(name => ({ dest: name, object: '/', interface: null }));
69+
let shelf = [
70+
{ dest: 'fi.w1.wpa_supplicant1', object: '/fi/w1/wpa_supplicant1', interface: null },
71+
];//debug
72+
73+
while (shelf.length) {
74+
console.log(JSON.stringify(shelf));
75+
76+
// A random delimiter for this iteration
77+
const delimiter = `[:${randomFillSync(Buffer.alloc(20)).toString('base64')}:]`;
78+
79+
const cmd = shelf.reduce((cmd, v) => {
80+
const { dest, object, interface } = v;
81+
82+
// Delimiter
83+
cmd += `\necho '${delimiter}';\n`;
84+
85+
// Metadata
86+
cmd += `echo '${JSON.stringify(v)}';\n`;
87+
88+
// If interface is null, call Introspectable.Introspect
89+
if (interface == null) {
90+
return cmd + `dbus-send --system --type=method_call --print-reply --dest=${dest} ${object} org.freedesktop.DBus.Introspectable.Introspect;\n`;
91+
}
92+
93+
// If interface is not null, call Properties.GetAll
94+
else {
95+
return cmd + `dbus-send --system --type=method_call --print-reply --dest=${dest} ${object} org.freedesktop.DBus.Properties.GetAll string:${interface};\n`;
96+
}
97+
}, '');
98+
99+
// Run the command
100+
const res = await runner(cmd);
101+
102+
// Flush shelf
103+
shelf = [];
104+
105+
// Split by delimiter
106+
for (const block of res.split(delimiter)) {
107+
// Parse metadata
108+
const [, metadata] = /^({.+})$/m.exec(block) || [, '{}'],
109+
{ dest, object, interface } = JSON.parseXML(metadata);
110+
if (!dest) {
111+
continue;
112+
}
113+
114+
// Initialize _root[dest] (Level 1)
115+
if (!_root[dest]) {
116+
_root[dest] = {};
117+
}
118+
119+
// Initialize _root[dest][object] (Level 2)
120+
if (!_root[dest][object]) {
121+
_root[dest][object] = {};
122+
}
123+
124+
// Parse the message
125+
const [, string] = /\n\s+string "(.+)"[\n\s]*$/s.exec(block) || [], // Introspect
126+
[, array] = /\n\s+array \[(.+)\][\n\s]*$/s.exec(block) || []; // GetAll
127+
128+
// If interface is null, Introspect is expected
129+
if (interface == null && string) {
130+
// Parse XML, grab interfaces and children
131+
const {
132+
node: {
133+
interface: interfaces,
134+
node: children
135+
} = {}
136+
} = await parseXML(string) || {};
137+
138+
// interfaces: Enumerate and register
139+
(interfaces || []).forEach(v => {
140+
const {
141+
name: [ interface ],
142+
method: methods,
143+
signal: signals,
144+
property
145+
} = v;
146+
147+
// Initialize _root[dest][object][interface] (Level 3)
148+
_root[dest][object][interface] = {};
149+
150+
// Found methods,
151+
if (methods) {
152+
// Initialize _root[dest][object][interface]['method'] (Level 4)
153+
_root[dest][object][interface]['method'] = {};
154+
155+
// methods: Enumerate and register
156+
methods.forEach(v => {
157+
const {
158+
name: [ method ],
159+
arg
160+
} = v;
161+
162+
_root[dest][object][interface]['method'][method] = arg;
163+
});
164+
}
165+
166+
// Found signals,
167+
if (signals) {
168+
// Initialize _root[dest][object][interface]['signal'] (Level 4)
169+
_root[dest][object][interface]['signal'] = {};
170+
171+
// signals: Enumerate and register
172+
signals.forEach(v => {
173+
const {
174+
name: [ signal ],
175+
arg
176+
} = v;
177+
178+
_root[dest][object][interface]['signal'][signal] = arg;
179+
});
180+
}
181+
182+
// Found property,
183+
if (property) {
184+
// Initialize _root[dest][object][interface]['property'] (Level 4)
185+
_root[dest][object][interface]['property'] = {};
186+
187+
// Put it on shelf for later GetAll
188+
shelf.push({dest: dest, object: object, interface: interface});
189+
}
190+
});
191+
192+
// children: Enumerate and register
193+
(children || []).forEach(v => {
194+
const {
195+
name: [ child ]
196+
} = v;
197+
198+
// Put it on shelf for later Introspect
199+
shelf.push({
200+
dest: dest,
201+
object: `${object}${object == '/' ? '' : '/'}${child}`,
202+
interface: null
203+
});
204+
});
205+
}
206+
// If interface is not null, GetAll is expected
207+
else if (array) {
208+
// FIXME: Use GetAll.jison
209+
}
210+
// Else: Invalid
211+
else {
212+
console.log(`Invalid: ${block}`);
213+
}
214+
}
215+
}
216+
217+
return _root;
218+
}
219+
220+
async function main() {
221+
// Introspect and acquire root objects
222+
const shell = await introspect(runAsShell),
223+
pkg = await introspect(runAsPkg);
224+
225+
// Save root
226+
setData('root.shell', shell);
227+
setData('root.pkg', pkg);
228+
}
229+
230+
main();

0 commit comments

Comments
 (0)