sysiddr5 1.0.1-beta-2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sysiddr5 might be problematic. Click here for more details.

package/lib/usb.js ADDED
@@ -0,0 +1,274 @@
1
+ 'use strict';
2
+ // @ts-check
3
+ // ==================================================================================
4
+ // usb.js
5
+ // ----------------------------------------------------------------------------------
6
+ // Description: System Information - library
7
+ // for Node.js
8
+ // Copyright: (c) 2014 - 2023
9
+ // Author: Sebastian Hildebrandt
10
+ // ----------------------------------------------------------------------------------
11
+ // License: MIT
12
+ // ==================================================================================
13
+ // 16. usb
14
+ // ----------------------------------------------------------------------------------
15
+
16
+ const exec = require('child_process').exec;
17
+ const util = require('./util');
18
+
19
+ let _platform = process.platform;
20
+
21
+ const _linux = (_platform === 'linux' || _platform === 'android');
22
+ const _darwin = (_platform === 'darwin');
23
+ const _windows = (_platform === 'win32');
24
+ const _freebsd = (_platform === 'freebsd');
25
+ const _openbsd = (_platform === 'openbsd');
26
+ const _netbsd = (_platform === 'netbsd');
27
+ const _sunos = (_platform === 'sunos');
28
+
29
+ function getLinuxUsbType(type, name) {
30
+ let result = type;
31
+ const str = (name + ' ' + type).toLowerCase();
32
+ if (str.indexOf('camera') >= 0) { result = 'Camera'; }
33
+ else if (str.indexOf('hub') >= 0) { result = 'Hub'; }
34
+ else if (str.indexOf('keybrd') >= 0) { result = 'Keyboard'; }
35
+ else if (str.indexOf('keyboard') >= 0) { result = 'Keyboard'; }
36
+ else if (str.indexOf('mouse') >= 0) { result = 'Mouse'; }
37
+ else if (str.indexOf('stora') >= 0) { result = 'Storage'; }
38
+ else if (str.indexOf('mic') >= 0) { result = 'Microphone'; }
39
+ else if (str.indexOf('headset') >= 0) { result = 'Audio'; }
40
+ else if (str.indexOf('audio') >= 0) { result = 'Audio'; }
41
+
42
+ return result;
43
+ }
44
+
45
+ function parseLinuxUsb(usb) {
46
+ const result = {};
47
+ const lines = usb.split('\n');
48
+ if (lines && lines.length && lines[0].indexOf('Device') >= 0) {
49
+ const parts = lines[0].split(' ');
50
+ result.bus = parseInt(parts[0], 10);
51
+ if (parts[2]) {
52
+ result.deviceId = parseInt(parts[2], 10);
53
+ } else {
54
+ result.deviceId = null;
55
+ }
56
+ } else {
57
+ result.bus = null;
58
+ result.deviceId = null;
59
+ }
60
+ const idVendor = util.getValue(lines, 'idVendor', ' ', true).trim();
61
+ let vendorParts = idVendor.split(' ');
62
+ vendorParts.shift();
63
+ const vendor = vendorParts.join(' ');
64
+
65
+ const idProduct = util.getValue(lines, 'idProduct', ' ', true).trim();
66
+ let productParts = idProduct.split(' ');
67
+ productParts.shift();
68
+ const product = productParts.join(' ');
69
+
70
+ const interfaceClass = util.getValue(lines, 'bInterfaceClass', ' ', true).trim();
71
+ let interfaceClassParts = interfaceClass.split(' ');
72
+ interfaceClassParts.shift();
73
+ const usbType = interfaceClassParts.join(' ');
74
+
75
+ const iManufacturer = util.getValue(lines, 'iManufacturer', ' ', true).trim();
76
+ let iManufacturerParts = iManufacturer.split(' ');
77
+ iManufacturerParts.shift();
78
+ const manufacturer = iManufacturerParts.join(' ');
79
+
80
+ result.id = (idVendor.startsWith('0x') ? idVendor.split(' ')[0].substr(2, 10) : '') + ':' + (idProduct.startsWith('0x') ? idProduct.split(' ')[0].substr(2, 10) : '');
81
+ result.name = product;
82
+ result.type = getLinuxUsbType(usbType, product);
83
+ result.removable = null;
84
+ result.vendor = vendor;
85
+ result.manufacturer = manufacturer;
86
+ result.maxPower = util.getValue(lines, 'MaxPower', ' ', true);
87
+ result.serialNumber = null;
88
+
89
+ return result;
90
+ }
91
+
92
+ function getDarwinUsbType(name) {
93
+ let result = '';
94
+ if (name.indexOf('camera') >= 0) { result = 'Camera'; }
95
+ else if (name.indexOf('touch bar') >= 0) { result = 'Touch Bar'; }
96
+ else if (name.indexOf('controller') >= 0) { result = 'Controller'; }
97
+ else if (name.indexOf('headset') >= 0) { result = 'Audio'; }
98
+ else if (name.indexOf('keyboard') >= 0) { result = 'Keyboard'; }
99
+ else if (name.indexOf('trackpad') >= 0) { result = 'Trackpad'; }
100
+ else if (name.indexOf('sensor') >= 0) { result = 'Sensor'; }
101
+ else if (name.indexOf('bthusb') >= 0) { result = 'Bluetooth'; }
102
+ else if (name.indexOf('bth') >= 0) { result = 'Bluetooth'; }
103
+ else if (name.indexOf('rfcomm') >= 0) { result = 'Bluetooth'; }
104
+ else if (name.indexOf('usbhub') >= 0) { result = 'Hub'; }
105
+ else if (name.indexOf(' hub') >= 0) { result = 'Hub'; }
106
+ else if (name.indexOf('mouse') >= 0) { result = 'Mouse'; }
107
+ else if (name.indexOf('mic') >= 0) { result = 'Microphone'; }
108
+ else if (name.indexOf('removable') >= 0) { result = 'Storage'; }
109
+ return result;
110
+ }
111
+
112
+
113
+ function parseDarwinUsb(usb, id) {
114
+ const result = {};
115
+ result.id = id;
116
+
117
+ usb = usb.replace(/ \|/g, '');
118
+ usb = usb.trim();
119
+ let lines = usb.split('\n');
120
+ lines.shift();
121
+ try {
122
+ for (let i = 0; i < lines.length; i++) {
123
+ lines[i] = lines[i].trim();
124
+ lines[i] = lines[i].replace(/=/g, ':');
125
+ if (lines[i] !== '{' && lines[i] !== '}' && lines[i + 1] && lines[i + 1].trim() !== '}') {
126
+ lines[i] = lines[i] + ',';
127
+ }
128
+
129
+ lines[i] = lines[i].replace(':Yes,', ':"Yes",');
130
+ lines[i] = lines[i].replace(': Yes,', ': "Yes",');
131
+ lines[i] = lines[i].replace(': Yes', ': "Yes"');
132
+ lines[i] = lines[i].replace(':No,', ':"No",');
133
+ lines[i] = lines[i].replace(': No,', ': "No",');
134
+ lines[i] = lines[i].replace(': No', ': "No"');
135
+
136
+ // In this case (("com.apple.developer.driverkit.transport.usb"))
137
+ lines[i] = lines[i].replace('((', '').replace('))', '');
138
+
139
+ // In case we have <923c11> we need make it "<923c11>" for correct JSON parse
140
+ const match = /<(\w+)>/.exec(lines[i]);
141
+ if (match) {
142
+ const number = match[0];
143
+ lines[i] = lines[i].replace(number, `"${number}"`);
144
+ }
145
+ }
146
+ const usbObj = JSON.parse(lines.join('\n'));
147
+ const removableDrive = (usbObj['Built-In'] ? usbObj['Built-In'].toLowerCase() !== 'yes' : true) && (usbObj['non-removable'] ? usbObj['non-removable'].toLowerCase() === 'no' : true);
148
+
149
+ result.bus = null;
150
+ result.deviceId = null;
151
+ result.id = usbObj['USB Address'] || null;
152
+ result.name = usbObj['kUSBProductString'] || usbObj['USB Product Name'] || null;
153
+ result.type = getDarwinUsbType((usbObj['kUSBProductString'] || usbObj['USB Product Name'] || '').toLowerCase() + (removableDrive ? ' removable' : ''));
154
+ result.removable = usbObj['non-removable'] ? usbObj['non-removable'].toLowerCase() || '' === 'no' : true;
155
+ result.vendor = usbObj['kUSBVendorString'] || usbObj['USB Vendor Name'] || null;
156
+ result.manufacturer = usbObj['kUSBVendorString'] || usbObj['USB Vendor Name'] || null;
157
+
158
+ result.maxPower = null;
159
+ result.serialNumber = usbObj['kUSBSerialNumberString'] || null;
160
+
161
+ if (result.name) {
162
+ return result;
163
+ } else {
164
+ return null;
165
+ }
166
+ } catch (e) {
167
+ return null;
168
+ }
169
+ }
170
+
171
+ function getWindowsUsbTypeCreation(creationclass, name) {
172
+ let result = '';
173
+ if (name.indexOf('storage') >= 0) { result = 'Storage'; }
174
+ else if (name.indexOf('speicher') >= 0) { result = 'Storage'; }
175
+ else if (creationclass.indexOf('usbhub') >= 0) { result = 'Hub'; }
176
+ else if (creationclass.indexOf('storage') >= 0) { result = 'Storage'; }
177
+ else if (creationclass.indexOf('usbcontroller') >= 0) { result = 'Controller'; }
178
+ else if (creationclass.indexOf('keyboard') >= 0) { result = 'Keyboard'; }
179
+ else if (creationclass.indexOf('pointing') >= 0) { result = 'Mouse'; }
180
+ else if (creationclass.indexOf('disk') >= 0) { result = 'Storage'; }
181
+ return result;
182
+ }
183
+
184
+ function parseWindowsUsb(lines, id) {
185
+ const usbType = getWindowsUsbTypeCreation(util.getValue(lines, 'CreationClassName', ':').toLowerCase(), util.getValue(lines, 'name', ':').toLowerCase());
186
+
187
+ if (usbType) {
188
+ const result = {};
189
+ result.bus = null;
190
+ result.deviceId = util.getValue(lines, 'deviceid', ':');
191
+ result.id = id;
192
+ result.name = util.getValue(lines, 'name', ':');
193
+ result.type = usbType;
194
+ result.removable = null;
195
+ result.vendor = null;
196
+ result.manufacturer = util.getValue(lines, 'Manufacturer', ':');
197
+ result.maxPower = null;
198
+ result.serialNumber = null;
199
+
200
+ return result;
201
+ } else {
202
+ return null;
203
+ }
204
+ }
205
+
206
+ function usb(callback) {
207
+
208
+ return new Promise((resolve) => {
209
+ process.nextTick(() => {
210
+ let result = [];
211
+ if (_linux) {
212
+ const cmd = 'export LC_ALL=C; lsusb -v 2>/dev/null; unset LC_ALL';
213
+ exec(cmd, { maxBuffer: 1024 * 1024 * 128 }, function (error, stdout) {
214
+ if (!error) {
215
+ const parts = ('\n\n' + stdout.toString()).split('\n\nBus ');
216
+ for (let i = 1; i < parts.length; i++) {
217
+ const usb = parseLinuxUsb(parts[i]);
218
+ result.push(usb);
219
+ }
220
+ }
221
+ if (callback) {
222
+ callback(result);
223
+ }
224
+ resolve(result);
225
+ });
226
+ }
227
+ if (_darwin) {
228
+ let cmd = 'ioreg -p IOUSB -c AppleUSBRootHubDevice -w0 -l';
229
+ exec(cmd, { maxBuffer: 1024 * 1024 * 128 }, function (error, stdout) {
230
+ if (!error) {
231
+ const parts = (stdout.toString()).split(' +-o ');
232
+ for (let i = 1; i < parts.length; i++) {
233
+ const usb = parseDarwinUsb(parts[i]);
234
+ if (usb) {
235
+ result.push(usb);
236
+ }
237
+ }
238
+ if (callback) {
239
+ callback(result);
240
+ }
241
+ resolve(result);
242
+ }
243
+ if (callback) {
244
+ callback(result);
245
+ }
246
+ resolve(result);
247
+ });
248
+ }
249
+ if (_windows) {
250
+ util.powerShell('Get-CimInstance CIM_LogicalDevice | where { $_.Description -match "USB"} | select Name,CreationClassName,DeviceId,Manufacturer | fl').then((stdout, error) => {
251
+ if (!error) {
252
+ const parts = stdout.toString().split(/\n\s*\n/);
253
+ for (let i = 0; i < parts.length; i++) {
254
+ const usb = parseWindowsUsb(parts[i].split('\n'), i);
255
+ if (usb) {
256
+ result.push(usb);
257
+ }
258
+ }
259
+ }
260
+ if (callback) {
261
+ callback(result);
262
+ }
263
+ resolve(result);
264
+ });
265
+ }
266
+ if (_sunos || _freebsd || _openbsd || _netbsd) {
267
+ resolve(null);
268
+ }
269
+ });
270
+ });
271
+ }
272
+
273
+ exports.usb = usb;
274
+
package/lib/users.js ADDED
@@ -0,0 +1,363 @@
1
+ 'use strict';
2
+ // @ts-check
3
+ // ==================================================================================
4
+ // users.js
5
+ // ----------------------------------------------------------------------------------
6
+ // Description: System Information - library
7
+ // for Node.js
8
+ // Copyright: (c) 2014 - 2023
9
+ // Author: Sebastian Hildebrandt
10
+ // ----------------------------------------------------------------------------------
11
+ // License: MIT
12
+ // ==================================================================================
13
+ // 11. Users/Sessions
14
+ // ----------------------------------------------------------------------------------
15
+
16
+ const exec = require('child_process').exec;
17
+ const util = require('./util');
18
+
19
+ let _platform = process.platform;
20
+
21
+ const _linux = (_platform === 'linux' || _platform === 'android');
22
+ const _darwin = (_platform === 'darwin');
23
+ const _windows = (_platform === 'win32');
24
+ const _freebsd = (_platform === 'freebsd');
25
+ const _openbsd = (_platform === 'openbsd');
26
+ const _netbsd = (_platform === 'netbsd');
27
+ const _sunos = (_platform === 'sunos');
28
+
29
+ function parseUsersLinux(lines, phase) {
30
+ let result = [];
31
+ let result_who = [];
32
+ let result_w = {};
33
+ let w_first = true;
34
+ let w_header = [];
35
+ let w_pos = [];
36
+ let who_line = {};
37
+
38
+ let is_whopart = true;
39
+ lines.forEach(function (line) {
40
+ if (line === '---') {
41
+ is_whopart = false;
42
+ } else {
43
+ let l = line.replace(/ +/g, ' ').split(' ');
44
+
45
+ // who part
46
+ if (is_whopart) {
47
+ result_who.push({
48
+ user: l[0],
49
+ tty: l[1],
50
+ date: l[2],
51
+ time: l[3],
52
+ ip: (l && l.length > 4) ? l[4].replace(/\(/g, '').replace(/\)/g, '') : ''
53
+ });
54
+ } else {
55
+ // w part
56
+ if (w_first) { // header
57
+ w_header = l;
58
+ w_header.forEach(function (item) {
59
+ w_pos.push(line.indexOf(item));
60
+ });
61
+ w_first = false;
62
+ } else {
63
+ // split by w_pos
64
+ result_w.user = line.substring(w_pos[0], w_pos[1] - 1).trim();
65
+ result_w.tty = line.substring(w_pos[1], w_pos[2] - 1).trim();
66
+ result_w.ip = line.substring(w_pos[2], w_pos[3] - 1).replace(/\(/g, '').replace(/\)/g, '').trim();
67
+ result_w.command = line.substring(w_pos[7], 1000).trim();
68
+ // find corresponding 'who' line
69
+ who_line = result_who.filter(function (obj) {
70
+ return (obj.user.substring(0, 8).trim() === result_w.user && obj.tty === result_w.tty);
71
+ });
72
+ if (who_line.length === 1) {
73
+ result.push({
74
+ user: who_line[0].user,
75
+ tty: who_line[0].tty,
76
+ date: who_line[0].date,
77
+ time: who_line[0].time,
78
+ ip: who_line[0].ip,
79
+ command: result_w.command
80
+ });
81
+ }
82
+ }
83
+ }
84
+ }
85
+ });
86
+ if (result.length === 0 && phase === 2) {
87
+ return result_who;
88
+ } else {
89
+ return result;
90
+ }
91
+ }
92
+
93
+ function parseUsersDarwin(lines) {
94
+ let result = [];
95
+ let result_who = [];
96
+ let result_w = {};
97
+ let who_line = {};
98
+
99
+ let is_whopart = true;
100
+ lines.forEach(function (line) {
101
+ if (line === '---') {
102
+ is_whopart = false;
103
+ } else {
104
+ let l = line.replace(/ +/g, ' ').split(' ');
105
+
106
+ // who part
107
+ if (is_whopart) {
108
+ result_who.push({
109
+ user: l[0],
110
+ tty: l[1],
111
+ date: ('' + new Date().getFullYear()) + '-' + ('0' + ('JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC'.indexOf(l[2].toUpperCase()) / 3 + 1)).slice(-2) + '-' + ('0' + l[3]).slice(-2),
112
+ time: l[4],
113
+ });
114
+ } else {
115
+ // w part
116
+ // split by w_pos
117
+ result_w.user = l[0];
118
+ result_w.tty = l[1];
119
+ result_w.ip = (l[2] !== '-') ? l[2] : '';
120
+ result_w.command = l.slice(5, 1000).join(' ');
121
+ // find corresponding 'who' line
122
+ who_line = result_who.filter(function (obj) {
123
+ return (obj.user === result_w.user && (obj.tty.substring(3, 1000) === result_w.tty || obj.tty === result_w.tty));
124
+ });
125
+ if (who_line.length === 1) {
126
+ result.push({
127
+ user: who_line[0].user,
128
+ tty: who_line[0].tty,
129
+ date: who_line[0].date,
130
+ time: who_line[0].time,
131
+ ip: result_w.ip,
132
+ command: result_w.command
133
+ });
134
+ }
135
+ }
136
+ }
137
+ });
138
+ return result;
139
+ }
140
+
141
+ function users(callback) {
142
+
143
+ return new Promise((resolve) => {
144
+ process.nextTick(() => {
145
+ let result = [];
146
+
147
+ // linux
148
+ if (_linux) {
149
+ exec('who --ips; echo "---"; w | tail -n +2', function (error, stdout) {
150
+ if (!error) {
151
+ // lines / split
152
+ let lines = stdout.toString().split('\n');
153
+ result = parseUsersLinux(lines, 1);
154
+ if (result.length === 0) {
155
+ exec('who; echo "---"; w | tail -n +2', function (error, stdout) {
156
+ if (!error) {
157
+ // lines / split
158
+ lines = stdout.toString().split('\n');
159
+ result = parseUsersLinux(lines, 2);
160
+ }
161
+ if (callback) { callback(result); }
162
+ resolve(result);
163
+ });
164
+ } else {
165
+ if (callback) { callback(result); }
166
+ resolve(result);
167
+ }
168
+ } else {
169
+ if (callback) { callback(result); }
170
+ resolve(result);
171
+ }
172
+ });
173
+ }
174
+ if (_freebsd || _openbsd || _netbsd) {
175
+ exec('who; echo "---"; w -ih', function (error, stdout) {
176
+ if (!error) {
177
+ // lines / split
178
+ let lines = stdout.toString().split('\n');
179
+ result = parseUsersDarwin(lines);
180
+ }
181
+ if (callback) { callback(result); }
182
+ resolve(result);
183
+ });
184
+ }
185
+ if (_sunos) {
186
+ exec('who; echo "---"; w -h', function (error, stdout) {
187
+ if (!error) {
188
+ // lines / split
189
+ let lines = stdout.toString().split('\n');
190
+ result = parseUsersDarwin(lines);
191
+ }
192
+ if (callback) { callback(result); }
193
+ resolve(result);
194
+ });
195
+ }
196
+
197
+ if (_darwin) {
198
+ exec('who; echo "---"; w -ih', function (error, stdout) {
199
+ if (!error) {
200
+ // lines / split
201
+ let lines = stdout.toString().split('\n');
202
+ result = parseUsersDarwin(lines);
203
+ }
204
+ if (callback) { callback(result); }
205
+ resolve(result);
206
+ });
207
+ }
208
+ if (_windows) {
209
+ try {
210
+ let cmd = 'Get-CimInstance Win32_LogonSession | select LogonId,@{n="StartTime";e={$_.StartTime.ToString("yyyy-MM-dd HH:mm:ss")}} | fl' + '; echo \'#-#-#-#\';';
211
+ cmd += 'Get-CimInstance Win32_LoggedOnUser | select antecedent,dependent | fl ' + '; echo \'#-#-#-#\';';
212
+ cmd += '$process = (Get-CimInstance Win32_Process -Filter "name = \'explorer.exe\'"); Invoke-CimMethod -InputObject $process[0] -MethodName GetOwner | select user, domain | fl; get-process -name explorer | select-object sessionid | fl; echo \'#-#-#-#\';';
213
+ cmd += 'query user';
214
+ util.powerShell(cmd).then((data) => {
215
+ if (data) {
216
+ data = data.split('#-#-#-#');
217
+ let sessions = parseWinSessions((data[0] || '').split(/\n\s*\n/));
218
+ let loggedons = parseWinLoggedOn((data[1] || '').split(/\n\s*\n/));
219
+ let queryUser = parseWinUsersQuery((data[3] || '').split('\r\n'));
220
+ let users = parseWinUsers((data[2] || '').split(/\n\s*\n/), queryUser);
221
+ for (let id in loggedons) {
222
+ if ({}.hasOwnProperty.call(loggedons, id)) {
223
+ loggedons[id].dateTime = {}.hasOwnProperty.call(sessions, id) ? sessions[id] : '';
224
+ }
225
+ }
226
+ users.forEach(user => {
227
+ let dateTime = '';
228
+ for (let id in loggedons) {
229
+ if ({}.hasOwnProperty.call(loggedons, id)) {
230
+ if (loggedons[id].user === user.user && (!dateTime || dateTime < loggedons[id].dateTime)) {
231
+ dateTime = loggedons[id].dateTime;
232
+ }
233
+ }
234
+ }
235
+
236
+ result.push({
237
+ user: user.user,
238
+ tty: user.tty,
239
+ date: `${dateTime.substring(0, 10)}`,
240
+ time: `${dateTime.substring(11, 19)}`,
241
+ ip: '',
242
+ command: ''
243
+ });
244
+ });
245
+ }
246
+ if (callback) { callback(result); }
247
+ resolve(result);
248
+
249
+ });
250
+ } catch (e) {
251
+ if (callback) { callback(result); }
252
+ resolve(result);
253
+ }
254
+ }
255
+ });
256
+ });
257
+ }
258
+
259
+ function parseWinSessions(sessionParts) {
260
+ const sessions = {};
261
+ sessionParts.forEach(session => {
262
+ const lines = session.split('\r\n');
263
+ const id = util.getValue(lines, 'LogonId');
264
+ const starttime = util.getValue(lines, 'starttime');
265
+ if (id) {
266
+ sessions[id] = starttime;
267
+ }
268
+ });
269
+ return sessions;
270
+ }
271
+
272
+ function fuzzyMatch(name1, name2) {
273
+ name1 = name1.toLowerCase();
274
+ name2 = name2.toLowerCase();
275
+ let eq = 0;
276
+ let len = name1.length;
277
+ if (name2.length > len) { len = name2.length; }
278
+
279
+ for (let i = 0; i < len; i++) {
280
+ const c1 = name1[i] || '';
281
+ const c2 = name2[i] || '';
282
+ if (c1 === c2) { eq++; }
283
+ }
284
+ return (len > 10 ? eq / len > 0.9 : (len > 0 ? eq / len > 0.8 : false));
285
+ }
286
+
287
+ function parseWinUsers(userParts, userQuery) {
288
+ const users = [];
289
+ userParts.forEach(user => {
290
+ const lines = user.split('\r\n');
291
+
292
+ const domain = util.getValue(lines, 'domain', ':', true);
293
+ const username = util.getValue(lines, 'user', ':', true);
294
+ const sessionid = util.getValue(lines, 'sessionid', ':', true);
295
+
296
+ if (username) {
297
+ const quser = userQuery.filter(item => fuzzyMatch(item.user, username));
298
+ users.push({
299
+ domain,
300
+ user: username,
301
+ tty: quser && quser[0] && quser[0].tty ? quser[0].tty : sessionid
302
+ });
303
+ }
304
+ });
305
+ return users;
306
+ }
307
+
308
+ function parseWinLoggedOn(loggedonParts) {
309
+ const loggedons = {};
310
+ loggedonParts.forEach(loggedon => {
311
+ const lines = loggedon.split('\r\n');
312
+
313
+ const antecendent = util.getValue(lines, 'antecedent', ':', true);
314
+ let parts = antecendent.split('=');
315
+ const name = parts.length > 2 ? parts[1].split(',')[0].replace(/"/g, '').trim() : '';
316
+ const domain = parts.length > 2 ? parts[2].replace(/"/g, '').replace(/\)/g, '').trim() : '';
317
+ const dependent = util.getValue(lines, 'dependent', ':', true);
318
+ parts = dependent.split('=');
319
+ const id = parts.length > 1 ? parts[1].replace(/"/g, '').replace(/\)/g, '').trim() : '';
320
+ if (id) {
321
+ loggedons[id] = {
322
+ domain,
323
+ user: name
324
+ };
325
+ }
326
+ });
327
+ return loggedons;
328
+ }
329
+
330
+ function parseWinUsersQuery(lines) {
331
+ lines = lines.filter(item => item);
332
+ let result = [];
333
+ const header = lines[0];
334
+ const headerDelimiter = [];
335
+ if (header) {
336
+ const start = (header[0] === ' ') ? 1 : 0;
337
+ headerDelimiter.push(start - 1);
338
+ let nextSpace = 0;
339
+ for (let i = start + 1; i < header.length; i++) {
340
+ if (header[i] === ' ' && ((header[i - 1] === ' ') || (header[i - 1] === '.'))) {
341
+ nextSpace = i;
342
+ } else {
343
+ if (nextSpace) {
344
+ headerDelimiter.push(nextSpace);
345
+ nextSpace = 0;
346
+ }
347
+ }
348
+ }
349
+ for (let i = 1; i < lines.length; i++) {
350
+ if (lines[i].trim()) {
351
+ const user = lines[i].substring(headerDelimiter[0] + 1, headerDelimiter[1]).trim() || '';
352
+ const tty = lines[i].substring(headerDelimiter[1] + 1, headerDelimiter[2] - 2).trim() || '';
353
+ result.push({
354
+ user: user,
355
+ tty: tty,
356
+ });
357
+ }
358
+ }
359
+ }
360
+ return result;
361
+ }
362
+
363
+ exports.users = users;