systeminformation 5.28.1 → 5.28.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -10
- package/lib/index.js +35 -30
- package/lib/network.js +68 -58
- package/lib/osinfo.js +128 -144
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -185,7 +185,7 @@ si.cpu()
|
|
|
185
185
|
|
|
186
186
|
(last 7 major and minor version releases)
|
|
187
187
|
|
|
188
|
-
- Version 5.28.0: `
|
|
188
|
+
- Version 5.28.0: `cpuTemperature()` added suppurt for macos-temperature-sensor (macOS)
|
|
189
189
|
- Version 5.27.0: `mem()` added reclaimable memory
|
|
190
190
|
- Version 5.26.0: `getStatic()`, `getAll()` added usb, audio, bluetooth, printer
|
|
191
191
|
- Version 5.25.0: `versions()` added homebrew
|
|
@@ -235,10 +235,10 @@ and above.
|
|
|
235
235
|
|
|
236
236
|
I was able to test it on several Debian, Raspbian, Ubuntu distributions as well
|
|
237
237
|
as macOS (Mavericks, Yosemite, El Captain, Sierra, High Sierra, Mojave,
|
|
238
|
-
Catalina, Big Sur
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
details.
|
|
238
|
+
Catalina, Big Sur, Monterey, Ventura, Sonoma, Sequoia, Tahoe) and some Windows 7,
|
|
239
|
+
Windows 8, Windows 10, Windows 11, FreeBSD, OpenBSD, NetBSD and SunOS machines.
|
|
240
|
+
Not all functions are supported on all operating systems. Have a look at the
|
|
241
|
+
function reference in the docs to get further details.
|
|
242
242
|
|
|
243
243
|
If you have comments, suggestions & reports, please feel free to contact me!
|
|
244
244
|
|
|
@@ -1018,21 +1018,27 @@ async function cpuData() {
|
|
|
1018
1018
|
|
|
1019
1019
|
#### macOS - Temperature Sensor
|
|
1020
1020
|
|
|
1021
|
-
To be able to measure temperature on macOS I created
|
|
1022
|
-
|
|
1021
|
+
To be able to measure temperature on macOS I created two little additional
|
|
1022
|
+
packages. Due to some difficulties in NPM with `optionalDependencies` I
|
|
1023
1023
|
unfortunately was getting unexpected warnings on other platforms. So I decided
|
|
1024
1024
|
to drop this optional dependency for macOS - so by default, you will not get
|
|
1025
1025
|
correct values.
|
|
1026
1026
|
|
|
1027
|
-
This additional package is now also supporting Apple Silicon M1/M2/M3 machines.
|
|
1028
|
-
|
|
1029
1027
|
But if you need to detect macOS temperature just run the following additional
|
|
1030
1028
|
installation command:
|
|
1031
1029
|
|
|
1030
|
+
For Intel based machines (deprecated lib) install
|
|
1031
|
+
|
|
1032
1032
|
```bash
|
|
1033
1033
|
$ npm install osx-temperature-sensor --save
|
|
1034
1034
|
```
|
|
1035
1035
|
|
|
1036
|
+
For Apple Silicon (ARM) based machines install
|
|
1037
|
+
|
|
1038
|
+
```bash
|
|
1039
|
+
$ npm install macos-temperature-sensor --save
|
|
1040
|
+
```
|
|
1041
|
+
|
|
1036
1042
|
`systeminformation` will then detect this additional library and return the
|
|
1037
1043
|
temperature when calling systeminformations standard function `cpuTemperature()`
|
|
1038
1044
|
|
|
@@ -1163,7 +1169,7 @@ trademark of Fabrice Bellard, bochs is a trademark of The Bochs Project, USB and
|
|
|
1163
1169
|
USB Logo are trademarks of USB Implementation Forum, Bluetooth and Bluetooth
|
|
1164
1170
|
Logo are trademarks of Bluetooth SIG, Android is a trademark of Google LLC,
|
|
1165
1171
|
Parallels is a trademarks of Parallels International GmbH. Bun is a trademark of
|
|
1166
|
-
Codeblog Corp. Deno is a trademark of Deno Land Inc.
|
|
1172
|
+
Codeblog Corp. Deno is a trademark of Deno Land Inc. Arm is a trademark of Arm Limited.
|
|
1167
1173
|
|
|
1168
1174
|
All other trademarks are the property of their respective owners.
|
|
1169
1175
|
|
package/lib/index.js
CHANGED
|
@@ -42,12 +42,12 @@ const usb = require('./usb');
|
|
|
42
42
|
const audio = require('./audio');
|
|
43
43
|
const bluetooth = require('./bluetooth');
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
const _windows =
|
|
47
|
-
const _freebsd =
|
|
48
|
-
const _openbsd =
|
|
49
|
-
const _netbsd =
|
|
50
|
-
const _sunos =
|
|
45
|
+
const _platform = process.platform;
|
|
46
|
+
const _windows = _platform === 'win32';
|
|
47
|
+
const _freebsd = _platform === 'freebsd';
|
|
48
|
+
const _openbsd = _platform === 'openbsd';
|
|
49
|
+
const _netbsd = _platform === 'netbsd';
|
|
50
|
+
const _sunos = _platform === 'sunos';
|
|
51
51
|
|
|
52
52
|
// ----------------------------------------------------------------------------------
|
|
53
53
|
// init
|
|
@@ -74,11 +74,9 @@ function version() {
|
|
|
74
74
|
// get static data - they should not change until restarted
|
|
75
75
|
|
|
76
76
|
function getStaticData(callback) {
|
|
77
|
-
|
|
78
77
|
return new Promise((resolve) => {
|
|
79
78
|
process.nextTick(() => {
|
|
80
|
-
|
|
81
|
-
let data = {};
|
|
79
|
+
const data = {};
|
|
82
80
|
|
|
83
81
|
data.version = version();
|
|
84
82
|
|
|
@@ -99,7 +97,7 @@ function getStaticData(callback) {
|
|
|
99
97
|
audio.audio(),
|
|
100
98
|
bluetooth.bluetoothDevices(),
|
|
101
99
|
usb.usb(),
|
|
102
|
-
printer.printer()
|
|
100
|
+
printer.printer()
|
|
103
101
|
]).then((res) => {
|
|
104
102
|
data.system = res[0];
|
|
105
103
|
data.bios = res[1];
|
|
@@ -118,14 +116,15 @@ function getStaticData(callback) {
|
|
|
118
116
|
data.bluetooth = res[14];
|
|
119
117
|
data.usb = res[15];
|
|
120
118
|
data.printer = res[16];
|
|
121
|
-
if (callback) {
|
|
119
|
+
if (callback) {
|
|
120
|
+
callback(data);
|
|
121
|
+
}
|
|
122
122
|
resolve(data);
|
|
123
123
|
});
|
|
124
124
|
});
|
|
125
125
|
});
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
|
|
129
128
|
// --------------------------
|
|
130
129
|
// get all dynamic data - e.g. for monitoring agents
|
|
131
130
|
// may take some seconds to get all data
|
|
@@ -135,7 +134,6 @@ function getStaticData(callback) {
|
|
|
135
134
|
// - iface: define network interface for which you like to monitor network speed e.g. "eth0"
|
|
136
135
|
|
|
137
136
|
function getDynamicData(srv, iface, callback) {
|
|
138
|
-
|
|
139
137
|
if (util.isFunction(iface)) {
|
|
140
138
|
callback = iface;
|
|
141
139
|
iface = '';
|
|
@@ -147,16 +145,21 @@ function getDynamicData(srv, iface, callback) {
|
|
|
147
145
|
|
|
148
146
|
return new Promise((resolve) => {
|
|
149
147
|
process.nextTick(() => {
|
|
150
|
-
|
|
151
148
|
iface = iface || network.getDefaultNetworkInterface();
|
|
152
149
|
srv = srv || '';
|
|
153
150
|
|
|
154
151
|
// use closure to track ƒ completion
|
|
155
|
-
let functionProcessed = (
|
|
152
|
+
let functionProcessed = (() => {
|
|
156
153
|
let totalFunctions = 15;
|
|
157
|
-
if (_windows) {
|
|
158
|
-
|
|
159
|
-
|
|
154
|
+
if (_windows) {
|
|
155
|
+
totalFunctions = 13;
|
|
156
|
+
}
|
|
157
|
+
if (_freebsd || _openbsd || _netbsd) {
|
|
158
|
+
totalFunctions = 11;
|
|
159
|
+
}
|
|
160
|
+
if (_sunos) {
|
|
161
|
+
totalFunctions = 6;
|
|
162
|
+
}
|
|
160
163
|
|
|
161
164
|
return function () {
|
|
162
165
|
if (--totalFunctions === 0) {
|
|
@@ -168,7 +171,7 @@ function getDynamicData(srv, iface, callback) {
|
|
|
168
171
|
};
|
|
169
172
|
})();
|
|
170
173
|
|
|
171
|
-
|
|
174
|
+
const data = {};
|
|
172
175
|
|
|
173
176
|
// get time
|
|
174
177
|
data.time = osInfo.time();
|
|
@@ -286,7 +289,6 @@ function getDynamicData(srv, iface, callback) {
|
|
|
286
289
|
// - iface: define network interface for which you like to monitor network speed e.g. "eth0"
|
|
287
290
|
|
|
288
291
|
function getAllData(srv, iface, callback) {
|
|
289
|
-
|
|
290
292
|
return new Promise((resolve) => {
|
|
291
293
|
process.nextTick(() => {
|
|
292
294
|
let data = {};
|
|
@@ -310,7 +312,9 @@ function getAllData(srv, iface, callback) {
|
|
|
310
312
|
data[key] = res[key];
|
|
311
313
|
}
|
|
312
314
|
}
|
|
313
|
-
if (callback) {
|
|
315
|
+
if (callback) {
|
|
316
|
+
callback(data);
|
|
317
|
+
}
|
|
314
318
|
resolve(data);
|
|
315
319
|
});
|
|
316
320
|
});
|
|
@@ -322,8 +326,8 @@ function get(valueObject, callback) {
|
|
|
322
326
|
return new Promise((resolve) => {
|
|
323
327
|
process.nextTick(() => {
|
|
324
328
|
const allPromises = Object.keys(valueObject)
|
|
325
|
-
.filter(func => ({}.hasOwnProperty.call(exports, func))
|
|
326
|
-
.map(func => {
|
|
329
|
+
.filter((func) => ({}).hasOwnProperty.call(exports, func))
|
|
330
|
+
.map((func) => {
|
|
327
331
|
const params = valueObject[func].substring(valueObject[func].lastIndexOf('(') + 1, valueObject[func].lastIndexOf(')'));
|
|
328
332
|
let funcWithoutParams = func.indexOf(')') >= 0 ? func.split(')')[1].trim() : func;
|
|
329
333
|
funcWithoutParams = func.indexOf('|') >= 0 ? func.split('|')[0].trim() : funcWithoutParams;
|
|
@@ -361,12 +365,12 @@ function get(valueObject, callback) {
|
|
|
361
365
|
if (Array.isArray(data[i])) {
|
|
362
366
|
// result is in an array, go through all elements of array and pick only the right ones
|
|
363
367
|
const partialArray = [];
|
|
364
|
-
data[i].forEach(element => {
|
|
368
|
+
data[i].forEach((element) => {
|
|
365
369
|
let partialRes = {};
|
|
366
370
|
if (keys.length === 1 && (keys[0] === '*' || keys[0] === 'all')) {
|
|
367
371
|
partialRes = element;
|
|
368
372
|
} else {
|
|
369
|
-
keys.forEach(k => {
|
|
373
|
+
keys.forEach((k) => {
|
|
370
374
|
if ({}.hasOwnProperty.call(element, k)) {
|
|
371
375
|
partialRes[k] = element[k];
|
|
372
376
|
}
|
|
@@ -376,11 +380,11 @@ function get(valueObject, callback) {
|
|
|
376
380
|
if (filter && filterParts.length === 2) {
|
|
377
381
|
if ({}.hasOwnProperty.call(partialRes, filterParts[0].trim())) {
|
|
378
382
|
const val = partialRes[filterParts[0].trim()];
|
|
379
|
-
if (typeof val
|
|
383
|
+
if (typeof val === 'number') {
|
|
380
384
|
if (val === parseFloat(filterParts[1].trim())) {
|
|
381
385
|
partialArray.push(partialRes);
|
|
382
386
|
}
|
|
383
|
-
} else if (typeof val
|
|
387
|
+
} else if (typeof val === 'string') {
|
|
384
388
|
if (val.toLowerCase() === filterParts[1].trim().toLowerCase()) {
|
|
385
389
|
partialArray.push(partialRes);
|
|
386
390
|
}
|
|
@@ -389,12 +393,11 @@ function get(valueObject, callback) {
|
|
|
389
393
|
} else {
|
|
390
394
|
partialArray.push(partialRes);
|
|
391
395
|
}
|
|
392
|
-
|
|
393
396
|
});
|
|
394
397
|
result[key] = partialArray;
|
|
395
398
|
} else {
|
|
396
399
|
const partialRes = {};
|
|
397
|
-
keys.forEach(k => {
|
|
400
|
+
keys.forEach((k) => {
|
|
398
401
|
if ({}.hasOwnProperty.call(data[i], k)) {
|
|
399
402
|
partialRes[k] = data[i][k];
|
|
400
403
|
}
|
|
@@ -408,7 +411,9 @@ function get(valueObject, callback) {
|
|
|
408
411
|
i++;
|
|
409
412
|
}
|
|
410
413
|
}
|
|
411
|
-
if (callback) {
|
|
414
|
+
if (callback) {
|
|
415
|
+
callback(result);
|
|
416
|
+
}
|
|
412
417
|
resolve(result);
|
|
413
418
|
});
|
|
414
419
|
});
|
package/lib/network.js
CHANGED
|
@@ -19,7 +19,7 @@ const execSync = require('child_process').execSync;
|
|
|
19
19
|
const fs = require('fs');
|
|
20
20
|
const util = require('./util');
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
const _platform = process.platform;
|
|
23
23
|
|
|
24
24
|
const _linux = _platform === 'linux' || _platform === 'android';
|
|
25
25
|
const _darwin = _platform === 'darwin';
|
|
@@ -29,7 +29,7 @@ const _openbsd = _platform === 'openbsd';
|
|
|
29
29
|
const _netbsd = _platform === 'netbsd';
|
|
30
30
|
const _sunos = _platform === 'sunos';
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
const _network = {};
|
|
33
33
|
let _default_iface = '';
|
|
34
34
|
let _ifaces = {};
|
|
35
35
|
let _dhcpNics = [];
|
|
@@ -41,14 +41,14 @@ function getDefaultNetworkInterface() {
|
|
|
41
41
|
let ifacename = '';
|
|
42
42
|
let ifacenameFirst = '';
|
|
43
43
|
try {
|
|
44
|
-
|
|
44
|
+
const ifaces = os.networkInterfaces();
|
|
45
45
|
|
|
46
46
|
let scopeid = 9999;
|
|
47
47
|
|
|
48
48
|
// fallback - "first" external interface (sorted by scopeid)
|
|
49
49
|
for (let dev in ifaces) {
|
|
50
50
|
if ({}.hasOwnProperty.call(ifaces, dev)) {
|
|
51
|
-
ifaces[dev].forEach(
|
|
51
|
+
ifaces[dev].forEach((details) => {
|
|
52
52
|
if (details && details.internal === false) {
|
|
53
53
|
ifacenameFirst = ifacenameFirst || dev; // fallback if no scopeid
|
|
54
54
|
if (details.scopeid && details.scopeid < scopeid) {
|
|
@@ -79,7 +79,7 @@ function getDefaultNetworkInterface() {
|
|
|
79
79
|
if (defaultIp) {
|
|
80
80
|
for (let dev in ifaces) {
|
|
81
81
|
if ({}.hasOwnProperty.call(ifaces, dev)) {
|
|
82
|
-
ifaces[dev].forEach(
|
|
82
|
+
ifaces[dev].forEach((details) => {
|
|
83
83
|
if (details && details.address && details.address === defaultIp) {
|
|
84
84
|
ifacename = dev;
|
|
85
85
|
}
|
|
@@ -89,9 +89,9 @@ function getDefaultNetworkInterface() {
|
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
if (_linux) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
const cmd = 'ip route 2> /dev/null | grep default';
|
|
93
|
+
const result = execSync(cmd, util.execOptsLinux);
|
|
94
|
+
const parts = result.toString().split('\n')[0].split(/\s+/);
|
|
95
95
|
if (parts[0] === 'none' && parts[5]) {
|
|
96
96
|
ifacename = parts[5];
|
|
97
97
|
} else if (parts[4]) {
|
|
@@ -113,7 +113,7 @@ function getDefaultNetworkInterface() {
|
|
|
113
113
|
if (_freebsd || _openbsd || _netbsd || _sunos) {
|
|
114
114
|
cmd = 'route get 0.0.0.0 | grep interface:';
|
|
115
115
|
}
|
|
116
|
-
|
|
116
|
+
const result = execSync(cmd);
|
|
117
117
|
ifacename = result.toString().split('\n')[0];
|
|
118
118
|
if (ifacename.indexOf(':') > -1) {
|
|
119
119
|
ifacename = ifacename.split(':')[1].trim();
|
|
@@ -133,7 +133,7 @@ exports.getDefaultNetworkInterface = getDefaultNetworkInterface;
|
|
|
133
133
|
function getMacAddresses() {
|
|
134
134
|
let iface = '';
|
|
135
135
|
let mac = '';
|
|
136
|
-
|
|
136
|
+
const result = {};
|
|
137
137
|
if (_linux || _freebsd || _openbsd || _netbsd) {
|
|
138
138
|
if (typeof pathToIp === 'undefined') {
|
|
139
139
|
try {
|
|
@@ -149,12 +149,12 @@ function getMacAddresses() {
|
|
|
149
149
|
}
|
|
150
150
|
try {
|
|
151
151
|
const cmd = 'export LC_ALL=C; ' + (pathToIp ? pathToIp + ' link show up' : '/sbin/ifconfig') + '; unset LC_ALL';
|
|
152
|
-
|
|
152
|
+
const res = execSync(cmd, util.execOptsLinux);
|
|
153
153
|
const lines = res.toString().split('\n');
|
|
154
154
|
for (let i = 0; i < lines.length; i++) {
|
|
155
155
|
if (lines[i] && lines[i][0] !== ' ') {
|
|
156
156
|
if (pathToIp) {
|
|
157
|
-
|
|
157
|
+
const nextline = lines[i + 1].trim().split(' ');
|
|
158
158
|
if (nextline[0] === 'link/ether') {
|
|
159
159
|
iface = lines[i].split(' ')[1];
|
|
160
160
|
iface = iface.slice(0, iface.length - 1);
|
|
@@ -203,7 +203,7 @@ function getMacAddresses() {
|
|
|
203
203
|
function networkInterfaceDefault(callback) {
|
|
204
204
|
return new Promise((resolve) => {
|
|
205
205
|
process.nextTick(() => {
|
|
206
|
-
|
|
206
|
+
const result = getDefaultNetworkInterface();
|
|
207
207
|
if (callback) {
|
|
208
208
|
callback(result);
|
|
209
209
|
}
|
|
@@ -218,7 +218,7 @@ exports.networkInterfaceDefault = networkInterfaceDefault;
|
|
|
218
218
|
// NET - interfaces
|
|
219
219
|
|
|
220
220
|
function parseLinesWindowsNics(sections, nconfigsections) {
|
|
221
|
-
|
|
221
|
+
const nics = [];
|
|
222
222
|
for (let i in sections) {
|
|
223
223
|
try {
|
|
224
224
|
if ({}.hasOwnProperty.call(sections, i)) {
|
|
@@ -230,10 +230,10 @@ function parseLinesWindowsNics(sections, nconfigsections) {
|
|
|
230
230
|
} catch (e) {
|
|
231
231
|
util.noop();
|
|
232
232
|
}
|
|
233
|
-
|
|
233
|
+
const netEnabled = util.getValue(lines, 'NetEnabled', ':');
|
|
234
234
|
let adapterType = util.getValue(lines, 'AdapterTypeID', ':') === '9' ? 'wireless' : 'wired';
|
|
235
|
-
|
|
236
|
-
|
|
235
|
+
const ifacename = util.getValue(lines, 'Name', ':').replace(/\]/g, ')').replace(/\[/g, '(');
|
|
236
|
+
const iface = util.getValue(lines, 'NetConnectionID', ':').replace(/\]/g, ')').replace(/\[/g, '(');
|
|
237
237
|
if (ifacename.toLowerCase().indexOf('wi-fi') >= 0 || ifacename.toLowerCase().indexOf('wireless') >= 0) {
|
|
238
238
|
adapterType = 'wireless';
|
|
239
239
|
}
|
|
@@ -448,7 +448,7 @@ function getWindowsIEEE8021x(connectionType, iface, ifaces) {
|
|
|
448
448
|
function splitSectionsNics(lines) {
|
|
449
449
|
const result = [];
|
|
450
450
|
let section = [];
|
|
451
|
-
lines.forEach(
|
|
451
|
+
lines.forEach((line) => {
|
|
452
452
|
if (!line.startsWith('\t') && !line.startsWith(' ')) {
|
|
453
453
|
if (section.length) {
|
|
454
454
|
result.push(section);
|
|
@@ -480,7 +480,7 @@ function parseLinesDarwinNics(sections) {
|
|
|
480
480
|
};
|
|
481
481
|
const first = section[0];
|
|
482
482
|
nic.iface = first.split(':')[0].trim();
|
|
483
|
-
|
|
483
|
+
const parts = first.split('> mtu');
|
|
484
484
|
nic.mtu = parts.length > 1 ? parseInt(parts[1], 10) : null;
|
|
485
485
|
if (isNaN(nic.mtu)) {
|
|
486
486
|
nic.mtu = null;
|
|
@@ -562,7 +562,7 @@ function checkLinuxDCHPInterfaces(file) {
|
|
|
562
562
|
}
|
|
563
563
|
}
|
|
564
564
|
if (line.toLowerCase().includes('source')) {
|
|
565
|
-
|
|
565
|
+
const file = line.split(' ')[1];
|
|
566
566
|
result = result.concat(checkLinuxDCHPInterfaces(file));
|
|
567
567
|
}
|
|
568
568
|
});
|
|
@@ -574,7 +574,7 @@ function checkLinuxDCHPInterfaces(file) {
|
|
|
574
574
|
|
|
575
575
|
function getLinuxDHCPNics() {
|
|
576
576
|
// alternate methods getting interfaces using DHCP
|
|
577
|
-
|
|
577
|
+
const cmd = 'ip a 2> /dev/null';
|
|
578
578
|
let result = [];
|
|
579
579
|
try {
|
|
580
580
|
const lines = execSync(cmd, util.execOptsLinux).toString().split('\n');
|
|
@@ -621,7 +621,7 @@ function getLinuxIfaceDHCPstatus(iface, connectionName, DHCPNics) {
|
|
|
621
621
|
const lines = execSync(cmd, util.execOptsLinux).toString();
|
|
622
622
|
const resultFormat = lines.replace(/\s+/g, ' ').trim();
|
|
623
623
|
|
|
624
|
-
|
|
624
|
+
const dhcStatus = resultFormat.split(' ').slice(1).toString();
|
|
625
625
|
switch (dhcStatus) {
|
|
626
626
|
case 'auto':
|
|
627
627
|
result = true;
|
|
@@ -762,7 +762,7 @@ function networkInterfaces(callback, rescan, defaultString) {
|
|
|
762
762
|
|
|
763
763
|
return new Promise((resolve) => {
|
|
764
764
|
process.nextTick(() => {
|
|
765
|
-
|
|
765
|
+
const ifaces = os.networkInterfaces();
|
|
766
766
|
|
|
767
767
|
let result = [];
|
|
768
768
|
let nics = [];
|
|
@@ -1066,7 +1066,7 @@ function networkInterfaces(callback, rescan, defaultString) {
|
|
|
1066
1066
|
_ifaces = JSON.parse(JSON.stringify(ifaces));
|
|
1067
1067
|
const defaultInterface = getDefaultNetworkInterface();
|
|
1068
1068
|
|
|
1069
|
-
getWindowsNics().then(
|
|
1069
|
+
getWindowsNics().then((nics) => {
|
|
1070
1070
|
nics.forEach((nic) => {
|
|
1071
1071
|
let found = false;
|
|
1072
1072
|
Object.keys(ifaces).forEach((key) => {
|
|
@@ -1114,7 +1114,7 @@ function networkInterfaces(callback, rescan, defaultString) {
|
|
|
1114
1114
|
|
|
1115
1115
|
if ({}.hasOwnProperty.call(ifaces, dev)) {
|
|
1116
1116
|
let ifaceName = dev;
|
|
1117
|
-
ifaces[dev].forEach(
|
|
1117
|
+
ifaces[dev].forEach((details) => {
|
|
1118
1118
|
if (details.family === 'IPv4' || details.family === 4) {
|
|
1119
1119
|
ip4 = details.address;
|
|
1120
1120
|
ip4subnet = details.netmask;
|
|
@@ -1219,7 +1219,7 @@ exports.networkInterfaces = networkInterfaces;
|
|
|
1219
1219
|
// NET - Speed
|
|
1220
1220
|
|
|
1221
1221
|
function calcNetworkSpeed(iface, rx_bytes, tx_bytes, operstate, rx_dropped, rx_errors, tx_dropped, tx_errors) {
|
|
1222
|
-
|
|
1222
|
+
const result = {
|
|
1223
1223
|
iface,
|
|
1224
1224
|
operstate,
|
|
1225
1225
|
rx_bytes,
|
|
@@ -1420,7 +1420,7 @@ function networkStatsSingle(iface) {
|
|
|
1420
1420
|
'cat /sys/class/net/' +
|
|
1421
1421
|
ifaceSanitized +
|
|
1422
1422
|
'/statistics/tx_errors; ';
|
|
1423
|
-
exec(cmd,
|
|
1423
|
+
exec(cmd, (error, stdout) => {
|
|
1424
1424
|
if (!error) {
|
|
1425
1425
|
lines = stdout.toString().split('\n');
|
|
1426
1426
|
operstate = lines[0].trim();
|
|
@@ -1441,7 +1441,7 @@ function networkStatsSingle(iface) {
|
|
|
1441
1441
|
}
|
|
1442
1442
|
if (_freebsd || _openbsd || _netbsd) {
|
|
1443
1443
|
cmd = 'netstat -ibndI ' + ifaceSanitized; // lgtm [js/shell-command-constructed-from-input]
|
|
1444
|
-
exec(cmd,
|
|
1444
|
+
exec(cmd, (error, stdout) => {
|
|
1445
1445
|
if (!error) {
|
|
1446
1446
|
lines = stdout.toString().split('\n');
|
|
1447
1447
|
for (let i = 1; i < lines.length; i++) {
|
|
@@ -1471,7 +1471,7 @@ function networkStatsSingle(iface) {
|
|
|
1471
1471
|
}
|
|
1472
1472
|
if (_darwin) {
|
|
1473
1473
|
cmd = 'ifconfig ' + ifaceSanitized + ' | grep "status"'; // lgtm [js/shell-command-constructed-from-input]
|
|
1474
|
-
exec(cmd,
|
|
1474
|
+
exec(cmd, (error, stdout) => {
|
|
1475
1475
|
result.operstate = (stdout.toString().split(':')[1] || '').trim();
|
|
1476
1476
|
result.operstate = (result.operstate || '').toLowerCase();
|
|
1477
1477
|
result.operstate = result.operstate === 'active' ? 'up' : result.operstate === 'inactive' ? 'down' : 'unknown';
|
|
@@ -1602,15 +1602,15 @@ function networkConnections(callback) {
|
|
|
1602
1602
|
cmd =
|
|
1603
1603
|
'export LC_ALL=C; netstat -na | grep "ESTABLISHED\\|SYN_SENT\\|SYN_RECV\\|FIN_WAIT1\\|FIN_WAIT2\\|TIME_WAIT\\|CLOSE\\|CLOSE_WAIT\\|LAST_ACK\\|LISTEN\\|CLOSING\\|UNKNOWN"; unset LC_ALL';
|
|
1604
1604
|
}
|
|
1605
|
-
exec(cmd, { maxBuffer: 1024 * 102400 },
|
|
1605
|
+
exec(cmd, { maxBuffer: 1024 * 102400 }, (error, stdout) => {
|
|
1606
1606
|
let lines = stdout.toString().split('\n');
|
|
1607
1607
|
if (!error && (lines.length > 1 || lines[0] !== '')) {
|
|
1608
|
-
lines.forEach(
|
|
1608
|
+
lines.forEach((line) => {
|
|
1609
1609
|
line = line.replace(/ +/g, ' ').split(' ');
|
|
1610
1610
|
if (line.length >= 7) {
|
|
1611
1611
|
let localip = line[3];
|
|
1612
1612
|
let localport = '';
|
|
1613
|
-
|
|
1613
|
+
const localaddress = line[3].split(':');
|
|
1614
1614
|
if (localaddress.length > 1) {
|
|
1615
1615
|
localport = localaddress[localaddress.length - 1];
|
|
1616
1616
|
localaddress.pop();
|
|
@@ -1618,14 +1618,14 @@ function networkConnections(callback) {
|
|
|
1618
1618
|
}
|
|
1619
1619
|
let peerip = line[4];
|
|
1620
1620
|
let peerport = '';
|
|
1621
|
-
|
|
1621
|
+
const peeraddress = line[4].split(':');
|
|
1622
1622
|
if (peeraddress.length > 1) {
|
|
1623
1623
|
peerport = peeraddress[peeraddress.length - 1];
|
|
1624
1624
|
peeraddress.pop();
|
|
1625
1625
|
peerip = peeraddress.join(':');
|
|
1626
1626
|
}
|
|
1627
|
-
|
|
1628
|
-
|
|
1627
|
+
const connstate = line[5];
|
|
1628
|
+
const proc = line[6].split('/');
|
|
1629
1629
|
|
|
1630
1630
|
if (connstate) {
|
|
1631
1631
|
result.push({
|
|
@@ -1647,15 +1647,15 @@ function networkConnections(callback) {
|
|
|
1647
1647
|
resolve(result);
|
|
1648
1648
|
} else {
|
|
1649
1649
|
cmd = 'ss -tunap | grep "ESTAB\\|SYN-SENT\\|SYN-RECV\\|FIN-WAIT1\\|FIN-WAIT2\\|TIME-WAIT\\|CLOSE\\|CLOSE-WAIT\\|LAST-ACK\\|LISTEN\\|CLOSING"';
|
|
1650
|
-
exec(cmd, { maxBuffer: 1024 * 102400 },
|
|
1650
|
+
exec(cmd, { maxBuffer: 1024 * 102400 }, (error, stdout) => {
|
|
1651
1651
|
if (!error) {
|
|
1652
|
-
|
|
1653
|
-
lines.forEach(
|
|
1652
|
+
const lines = stdout.toString().split('\n');
|
|
1653
|
+
lines.forEach((line) => {
|
|
1654
1654
|
line = line.replace(/ +/g, ' ').split(' ');
|
|
1655
1655
|
if (line.length >= 6) {
|
|
1656
1656
|
let localip = line[4];
|
|
1657
1657
|
let localport = '';
|
|
1658
|
-
|
|
1658
|
+
const localaddress = line[4].split(':');
|
|
1659
1659
|
if (localaddress.length > 1) {
|
|
1660
1660
|
localport = localaddress[localaddress.length - 1];
|
|
1661
1661
|
localaddress.pop();
|
|
@@ -1663,7 +1663,7 @@ function networkConnections(callback) {
|
|
|
1663
1663
|
}
|
|
1664
1664
|
let peerip = line[5];
|
|
1665
1665
|
let peerport = '';
|
|
1666
|
-
|
|
1666
|
+
const peeraddress = line[5].split(':');
|
|
1667
1667
|
if (peeraddress.length > 1) {
|
|
1668
1668
|
peerport = peeraddress[peeraddress.length - 1];
|
|
1669
1669
|
peeraddress.pop();
|
|
@@ -1679,12 +1679,22 @@ function networkConnections(callback) {
|
|
|
1679
1679
|
let pid = null;
|
|
1680
1680
|
let process = '';
|
|
1681
1681
|
if (line.length >= 7 && line[6].indexOf('users:') > -1) {
|
|
1682
|
-
|
|
1682
|
+
const proc = line[6].replace('users:(("', '').replace(/"/g, '').replace('pid=', '').split(',');
|
|
1683
1683
|
if (proc.length > 2) {
|
|
1684
|
-
process = proc[0]
|
|
1685
|
-
|
|
1684
|
+
process = proc[0];
|
|
1685
|
+
const pidValue = parseInt(proc[1], 10);
|
|
1686
|
+
if (pidValue > 0) {
|
|
1687
|
+
pid = pidValue;
|
|
1688
|
+
}
|
|
1686
1689
|
}
|
|
1687
1690
|
}
|
|
1691
|
+
// if (line.length >= 7 && line[6].indexOf('users:') > -1) {
|
|
1692
|
+
// const proc = line[6].replace('users:(("', '').replace(/"/g, '').split(',');
|
|
1693
|
+
// if (proc.length > 2) {
|
|
1694
|
+
// process = proc[0].split(' ')[0].split(':')[0];
|
|
1695
|
+
// pid = parseInt(proc[1], 10);
|
|
1696
|
+
// }
|
|
1697
|
+
// }
|
|
1688
1698
|
if (connstate) {
|
|
1689
1699
|
result.push({
|
|
1690
1700
|
protocol: line[0],
|
|
@@ -1709,16 +1719,16 @@ function networkConnections(callback) {
|
|
|
1709
1719
|
});
|
|
1710
1720
|
}
|
|
1711
1721
|
if (_darwin) {
|
|
1712
|
-
|
|
1722
|
+
const cmd = 'netstat -natvln | head -n2; netstat -natvln | grep "tcp4\\|tcp6\\|udp4\\|udp6"';
|
|
1713
1723
|
const states = 'ESTABLISHED|SYN_SENT|SYN_RECV|FIN_WAIT1|FIN_WAIT_1|FIN_WAIT2|FIN_WAIT_2|TIME_WAIT|CLOSE|CLOSE_WAIT|LAST_ACK|LISTEN|CLOSING|UNKNOWN'.split('|');
|
|
1714
|
-
exec(cmd, { maxBuffer: 1024 * 102400 },
|
|
1724
|
+
exec(cmd, { maxBuffer: 1024 * 102400 }, (error, stdout) => {
|
|
1715
1725
|
if (!error) {
|
|
1716
|
-
exec('ps -axo pid,command', { maxBuffer: 1024 * 102400 },
|
|
1726
|
+
exec('ps -axo pid,command', { maxBuffer: 1024 * 102400 }, (err2, stdout2) => {
|
|
1717
1727
|
let processes = stdout2.toString().split('\n');
|
|
1718
1728
|
processes = processes.map((line) => {
|
|
1719
1729
|
return line.trim().replace(/ +/g, ' ');
|
|
1720
1730
|
});
|
|
1721
|
-
|
|
1731
|
+
const lines = stdout.toString().split('\n');
|
|
1722
1732
|
lines.shift();
|
|
1723
1733
|
let pidPos = 8;
|
|
1724
1734
|
if (lines.length > 1 && lines[0].indexOf('pid') > 0) {
|
|
@@ -1729,12 +1739,12 @@ function networkConnections(callback) {
|
|
|
1729
1739
|
.split(' ');
|
|
1730
1740
|
pidPos = header.indexOf('pid');
|
|
1731
1741
|
}
|
|
1732
|
-
lines.forEach(
|
|
1742
|
+
lines.forEach((line) => {
|
|
1733
1743
|
line = line.replace(/ +/g, ' ').split(' ');
|
|
1734
1744
|
if (line.length >= 8) {
|
|
1735
1745
|
let localip = line[3];
|
|
1736
1746
|
let localport = '';
|
|
1737
|
-
|
|
1747
|
+
const localaddress = line[3].split('.');
|
|
1738
1748
|
if (localaddress.length > 1) {
|
|
1739
1749
|
localport = localaddress[localaddress.length - 1];
|
|
1740
1750
|
localaddress.pop();
|
|
@@ -1742,14 +1752,14 @@ function networkConnections(callback) {
|
|
|
1742
1752
|
}
|
|
1743
1753
|
let peerip = line[4];
|
|
1744
1754
|
let peerport = '';
|
|
1745
|
-
|
|
1755
|
+
const peeraddress = line[4].split('.');
|
|
1746
1756
|
if (peeraddress.length > 1) {
|
|
1747
1757
|
peerport = peeraddress[peeraddress.length - 1];
|
|
1748
1758
|
peeraddress.pop();
|
|
1749
1759
|
peerip = peeraddress.join('.');
|
|
1750
1760
|
}
|
|
1751
1761
|
const hasState = states.indexOf(line[5]) >= 0;
|
|
1752
|
-
|
|
1762
|
+
const connstate = hasState ? line[5] : 'UNKNOWN';
|
|
1753
1763
|
let pidField = '';
|
|
1754
1764
|
if (line[line.length - 9].indexOf(':') >= 0) {
|
|
1755
1765
|
pidField = line[line.length - 9].split(':')[1];
|
|
@@ -1760,7 +1770,7 @@ function networkConnections(callback) {
|
|
|
1760
1770
|
pidField = pidField.split(':')[1];
|
|
1761
1771
|
}
|
|
1762
1772
|
}
|
|
1763
|
-
|
|
1773
|
+
const pid = parseInt(pidField, 10);
|
|
1764
1774
|
if (connstate) {
|
|
1765
1775
|
result.push({
|
|
1766
1776
|
protocol: line[0],
|
|
@@ -1786,11 +1796,11 @@ function networkConnections(callback) {
|
|
|
1786
1796
|
if (_windows) {
|
|
1787
1797
|
let cmd = 'netstat -nao';
|
|
1788
1798
|
try {
|
|
1789
|
-
exec(cmd, util.execOptsWin,
|
|
1799
|
+
exec(cmd, util.execOptsWin, (error, stdout) => {
|
|
1790
1800
|
if (!error) {
|
|
1791
1801
|
let lines = stdout.toString().split('\r\n');
|
|
1792
1802
|
|
|
1793
|
-
lines.forEach(
|
|
1803
|
+
lines.forEach((line) => {
|
|
1794
1804
|
line = line.trim().replace(/ +/g, ' ').split(' ');
|
|
1795
1805
|
if (line.length >= 4) {
|
|
1796
1806
|
let localip = line[1];
|
|
@@ -1892,7 +1902,7 @@ function networkGatewayDefault(callback) {
|
|
|
1892
1902
|
if (_linux || _freebsd || _openbsd || _netbsd) {
|
|
1893
1903
|
let cmd = 'ip route get 1';
|
|
1894
1904
|
try {
|
|
1895
|
-
exec(cmd, { maxBuffer: 1024 * 102400 },
|
|
1905
|
+
exec(cmd, { maxBuffer: 1024 * 102400 }, (error, stdout) => {
|
|
1896
1906
|
if (!error) {
|
|
1897
1907
|
let lines = stdout.toString().split('\n');
|
|
1898
1908
|
const line = lines && lines[0] ? lines[0] : '';
|
|
@@ -1922,7 +1932,7 @@ function networkGatewayDefault(callback) {
|
|
|
1922
1932
|
if (_darwin) {
|
|
1923
1933
|
let cmd = 'route -n get default';
|
|
1924
1934
|
try {
|
|
1925
|
-
exec(cmd, { maxBuffer: 1024 * 102400 },
|
|
1935
|
+
exec(cmd, { maxBuffer: 1024 * 102400 }, (error, stdout) => {
|
|
1926
1936
|
if (!error) {
|
|
1927
1937
|
const lines = stdout
|
|
1928
1938
|
.toString()
|
|
@@ -1932,7 +1942,7 @@ function networkGatewayDefault(callback) {
|
|
|
1932
1942
|
}
|
|
1933
1943
|
if (!result) {
|
|
1934
1944
|
cmd = "netstat -rn | awk '/default/ {print $2}'";
|
|
1935
|
-
exec(cmd, { maxBuffer: 1024 * 102400 },
|
|
1945
|
+
exec(cmd, { maxBuffer: 1024 * 102400 }, (error, stdout) => {
|
|
1936
1946
|
const lines = stdout
|
|
1937
1947
|
.toString()
|
|
1938
1948
|
.split('\n')
|
|
@@ -1961,7 +1971,7 @@ function networkGatewayDefault(callback) {
|
|
|
1961
1971
|
}
|
|
1962
1972
|
if (_windows) {
|
|
1963
1973
|
try {
|
|
1964
|
-
exec('netstat -r', util.execOptsWin,
|
|
1974
|
+
exec('netstat -r', util.execOptsWin, (error, stdout) => {
|
|
1965
1975
|
const lines = stdout.toString().split(os.EOL);
|
|
1966
1976
|
lines.forEach((line) => {
|
|
1967
1977
|
line = line.replace(/\s+/g, ' ').trim();
|
package/lib/osinfo.js
CHANGED
|
@@ -21,13 +21,13 @@ const execSync = require('child_process').execSync;
|
|
|
21
21
|
|
|
22
22
|
let _platform = process.platform;
|
|
23
23
|
|
|
24
|
-
const _linux =
|
|
25
|
-
const _darwin =
|
|
26
|
-
const _windows =
|
|
27
|
-
const _freebsd =
|
|
28
|
-
const _openbsd =
|
|
29
|
-
const _netbsd =
|
|
30
|
-
const _sunos =
|
|
24
|
+
const _linux = _platform === 'linux' || _platform === 'android';
|
|
25
|
+
const _darwin = _platform === 'darwin';
|
|
26
|
+
const _windows = _platform === 'win32';
|
|
27
|
+
const _freebsd = _platform === 'freebsd';
|
|
28
|
+
const _openbsd = _platform === 'openbsd';
|
|
29
|
+
const _netbsd = _platform === 'netbsd';
|
|
30
|
+
const _sunos = _platform === 'sunos';
|
|
31
31
|
|
|
32
32
|
// --------------------------
|
|
33
33
|
// Get current time and OS uptime
|
|
@@ -38,12 +38,12 @@ function time() {
|
|
|
38
38
|
try {
|
|
39
39
|
timezoneName = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
40
40
|
} catch {
|
|
41
|
-
timezoneName =
|
|
41
|
+
timezoneName = t.length >= 7 ? t.slice(6).join(' ').replace(/\(/g, '').replace(/\)/g, '') : '';
|
|
42
42
|
}
|
|
43
43
|
const result = {
|
|
44
44
|
current: Date.now(),
|
|
45
45
|
uptime: os.uptime(),
|
|
46
|
-
timezone:
|
|
46
|
+
timezone: t.length >= 7 ? t[5] : '',
|
|
47
47
|
timezoneName
|
|
48
48
|
};
|
|
49
49
|
if (_darwin || _linux) {
|
|
@@ -61,7 +61,7 @@ function time() {
|
|
|
61
61
|
current: Date.now(),
|
|
62
62
|
uptime: os.uptime(),
|
|
63
63
|
timezone: lines[1] ? timezone + lines[1] : timezone,
|
|
64
|
-
timezoneName: lines[2] && lines[2].indexOf('/zoneinfo/') > 0 ?
|
|
64
|
+
timezoneName: lines[2] && lines[2].indexOf('/zoneinfo/') > 0 ? lines[2].split('/zoneinfo/')[1] || '' : ''
|
|
65
65
|
};
|
|
66
66
|
} catch (e) {
|
|
67
67
|
util.noop();
|
|
@@ -81,116 +81,79 @@ function getLogoFile(distro) {
|
|
|
81
81
|
let result = _platform;
|
|
82
82
|
if (_windows) {
|
|
83
83
|
result = 'windows';
|
|
84
|
-
}
|
|
85
|
-
else if (distro.indexOf('mac os') !== -1 || distro.indexOf('macos') !== -1) {
|
|
84
|
+
} else if (distro.indexOf('mac os') !== -1 || distro.indexOf('macos') !== -1) {
|
|
86
85
|
result = 'apple';
|
|
87
|
-
}
|
|
88
|
-
else if (distro.indexOf('arch') !== -1) {
|
|
86
|
+
} else if (distro.indexOf('arch') !== -1) {
|
|
89
87
|
result = 'arch';
|
|
90
|
-
}
|
|
91
|
-
else if (distro.indexOf('cachy') !== -1) {
|
|
88
|
+
} else if (distro.indexOf('cachy') !== -1) {
|
|
92
89
|
result = 'cachy';
|
|
93
|
-
}
|
|
94
|
-
else if (distro.indexOf('centos') !== -1) {
|
|
90
|
+
} else if (distro.indexOf('centos') !== -1) {
|
|
95
91
|
result = 'centos';
|
|
96
|
-
}
|
|
97
|
-
else if (distro.indexOf('coreos') !== -1) {
|
|
92
|
+
} else if (distro.indexOf('coreos') !== -1) {
|
|
98
93
|
result = 'coreos';
|
|
99
|
-
}
|
|
100
|
-
else if (distro.indexOf('debian') !== -1) {
|
|
94
|
+
} else if (distro.indexOf('debian') !== -1) {
|
|
101
95
|
result = 'debian';
|
|
102
|
-
}
|
|
103
|
-
else if (distro.indexOf('deepin') !== -1) {
|
|
96
|
+
} else if (distro.indexOf('deepin') !== -1) {
|
|
104
97
|
result = 'deepin';
|
|
105
|
-
}
|
|
106
|
-
else if (distro.indexOf('elementary') !== -1) {
|
|
98
|
+
} else if (distro.indexOf('elementary') !== -1) {
|
|
107
99
|
result = 'elementary';
|
|
108
|
-
}
|
|
109
|
-
else if (distro.indexOf('endeavour') !== -1) {
|
|
100
|
+
} else if (distro.indexOf('endeavour') !== -1) {
|
|
110
101
|
result = 'endeavour';
|
|
111
|
-
}
|
|
112
|
-
else if (distro.indexOf('fedora') !== -1) {
|
|
102
|
+
} else if (distro.indexOf('fedora') !== -1) {
|
|
113
103
|
result = 'fedora';
|
|
114
|
-
}
|
|
115
|
-
else if (distro.indexOf('gentoo') !== -1) {
|
|
104
|
+
} else if (distro.indexOf('gentoo') !== -1) {
|
|
116
105
|
result = 'gentoo';
|
|
117
|
-
}
|
|
118
|
-
else if (distro.indexOf('mageia') !== -1) {
|
|
106
|
+
} else if (distro.indexOf('mageia') !== -1) {
|
|
119
107
|
result = 'mageia';
|
|
120
|
-
}
|
|
121
|
-
else if (distro.indexOf('mandriva') !== -1) {
|
|
108
|
+
} else if (distro.indexOf('mandriva') !== -1) {
|
|
122
109
|
result = 'mandriva';
|
|
123
|
-
}
|
|
124
|
-
else if (distro.indexOf('manjaro') !== -1) {
|
|
110
|
+
} else if (distro.indexOf('manjaro') !== -1) {
|
|
125
111
|
result = 'manjaro';
|
|
126
|
-
}
|
|
127
|
-
else if (distro.indexOf('mint') !== -1) {
|
|
112
|
+
} else if (distro.indexOf('mint') !== -1) {
|
|
128
113
|
result = 'mint';
|
|
129
|
-
}
|
|
130
|
-
else if (distro.indexOf('mx') !== -1) {
|
|
114
|
+
} else if (distro.indexOf('mx') !== -1) {
|
|
131
115
|
result = 'mx';
|
|
132
|
-
}
|
|
133
|
-
else if (distro.indexOf('openbsd') !== -1) {
|
|
116
|
+
} else if (distro.indexOf('openbsd') !== -1) {
|
|
134
117
|
result = 'openbsd';
|
|
135
|
-
}
|
|
136
|
-
else if (distro.indexOf('freebsd') !== -1) {
|
|
118
|
+
} else if (distro.indexOf('freebsd') !== -1) {
|
|
137
119
|
result = 'freebsd';
|
|
138
|
-
}
|
|
139
|
-
else if (distro.indexOf('opensuse') !== -1) {
|
|
120
|
+
} else if (distro.indexOf('opensuse') !== -1) {
|
|
140
121
|
result = 'opensuse';
|
|
141
|
-
}
|
|
142
|
-
else if (distro.indexOf('pclinuxos') !== -1) {
|
|
122
|
+
} else if (distro.indexOf('pclinuxos') !== -1) {
|
|
143
123
|
result = 'pclinuxos';
|
|
144
|
-
}
|
|
145
|
-
else if (distro.indexOf('puppy') !== -1) {
|
|
124
|
+
} else if (distro.indexOf('puppy') !== -1) {
|
|
146
125
|
result = 'puppy';
|
|
147
|
-
}
|
|
148
|
-
else if (distro.indexOf('popos') !== -1) {
|
|
126
|
+
} else if (distro.indexOf('popos') !== -1) {
|
|
149
127
|
result = 'popos';
|
|
150
|
-
}
|
|
151
|
-
else if (distro.indexOf('raspbian') !== -1) {
|
|
128
|
+
} else if (distro.indexOf('raspbian') !== -1) {
|
|
152
129
|
result = 'raspbian';
|
|
153
|
-
}
|
|
154
|
-
else if (distro.indexOf('reactos') !== -1) {
|
|
130
|
+
} else if (distro.indexOf('reactos') !== -1) {
|
|
155
131
|
result = 'reactos';
|
|
156
|
-
}
|
|
157
|
-
else if (distro.indexOf('redhat') !== -1) {
|
|
132
|
+
} else if (distro.indexOf('redhat') !== -1) {
|
|
158
133
|
result = 'redhat';
|
|
159
|
-
}
|
|
160
|
-
else if (distro.indexOf('slackware') !== -1) {
|
|
134
|
+
} else if (distro.indexOf('slackware') !== -1) {
|
|
161
135
|
result = 'slackware';
|
|
162
|
-
}
|
|
163
|
-
else if (distro.indexOf('sugar') !== -1) {
|
|
136
|
+
} else if (distro.indexOf('sugar') !== -1) {
|
|
164
137
|
result = 'sugar';
|
|
165
|
-
}
|
|
166
|
-
else if (distro.indexOf('steam') !== -1) {
|
|
138
|
+
} else if (distro.indexOf('steam') !== -1) {
|
|
167
139
|
result = 'steam';
|
|
168
|
-
}
|
|
169
|
-
else if (distro.indexOf('suse') !== -1) {
|
|
140
|
+
} else if (distro.indexOf('suse') !== -1) {
|
|
170
141
|
result = 'suse';
|
|
171
|
-
}
|
|
172
|
-
else if (distro.indexOf('mate') !== -1) {
|
|
142
|
+
} else if (distro.indexOf('mate') !== -1) {
|
|
173
143
|
result = 'ubuntu-mate';
|
|
174
|
-
}
|
|
175
|
-
else if (distro.indexOf('lubuntu') !== -1) {
|
|
144
|
+
} else if (distro.indexOf('lubuntu') !== -1) {
|
|
176
145
|
result = 'lubuntu';
|
|
177
|
-
}
|
|
178
|
-
else if (distro.indexOf('xubuntu') !== -1) {
|
|
146
|
+
} else if (distro.indexOf('xubuntu') !== -1) {
|
|
179
147
|
result = 'xubuntu';
|
|
180
|
-
}
|
|
181
|
-
else if (distro.indexOf('ubuntu') !== -1) {
|
|
148
|
+
} else if (distro.indexOf('ubuntu') !== -1) {
|
|
182
149
|
result = 'ubuntu';
|
|
183
|
-
}
|
|
184
|
-
else if (distro.indexOf('solaris') !== -1) {
|
|
150
|
+
} else if (distro.indexOf('solaris') !== -1) {
|
|
185
151
|
result = 'solaris';
|
|
186
|
-
}
|
|
187
|
-
else if (distro.indexOf('tails') !== -1) {
|
|
152
|
+
} else if (distro.indexOf('tails') !== -1) {
|
|
188
153
|
result = 'tails';
|
|
189
|
-
}
|
|
190
|
-
else if (distro.indexOf('feren') !== -1) {
|
|
154
|
+
} else if (distro.indexOf('feren') !== -1) {
|
|
191
155
|
result = 'ferenos';
|
|
192
|
-
}
|
|
193
|
-
else if (distro.indexOf('robolinux') !== -1) {
|
|
156
|
+
} else if (distro.indexOf('robolinux') !== -1) {
|
|
194
157
|
result = 'robolinux';
|
|
195
158
|
} else if (_linux && distro) {
|
|
196
159
|
result = distro.toLowerCase().trim().replace(/\s+/g, '-');
|
|
@@ -234,12 +197,10 @@ function getFQDN() {
|
|
|
234
197
|
// OS Information
|
|
235
198
|
|
|
236
199
|
function osInfo(callback) {
|
|
237
|
-
|
|
238
200
|
return new Promise((resolve) => {
|
|
239
201
|
process.nextTick(() => {
|
|
240
202
|
let result = {
|
|
241
|
-
|
|
242
|
-
platform: (_platform === 'win32' ? 'Windows' : _platform),
|
|
203
|
+
platform: _platform === 'win32' ? 'Windows' : _platform,
|
|
243
204
|
distro: 'unknown',
|
|
244
205
|
release: 'unknown',
|
|
245
206
|
codename: '',
|
|
@@ -256,7 +217,6 @@ function osInfo(callback) {
|
|
|
256
217
|
};
|
|
257
218
|
|
|
258
219
|
if (_linux) {
|
|
259
|
-
|
|
260
220
|
exec('cat /etc/*-release; cat /usr/lib/os-release; cat /etc/openwrt_release', function (error, stdout) {
|
|
261
221
|
/**
|
|
262
222
|
* @namespace
|
|
@@ -289,7 +249,7 @@ function osInfo(callback) {
|
|
|
289
249
|
result.codename = codename;
|
|
290
250
|
result.codepage = util.getCodepage();
|
|
291
251
|
result.build = (release.BUILD_ID || '').replace(/"/g, '').trim();
|
|
292
|
-
isUefiLinux().then(uefi => {
|
|
252
|
+
isUefiLinux().then((uefi) => {
|
|
293
253
|
result.uefi = uefi;
|
|
294
254
|
uuid().then((data) => {
|
|
295
255
|
result.serial = data.os;
|
|
@@ -302,7 +262,6 @@ function osInfo(callback) {
|
|
|
302
262
|
});
|
|
303
263
|
}
|
|
304
264
|
if (_freebsd || _openbsd || _netbsd) {
|
|
305
|
-
|
|
306
265
|
exec('sysctl kern.ostype kern.osrelease kern.osrevision kern.hostuuid machdep.bootmethod kern.geom.confxml', function (error, stdout) {
|
|
307
266
|
let lines = stdout.toString().split('\n');
|
|
308
267
|
const distro = util.getValue(lines, 'kern.ostype');
|
|
@@ -311,7 +270,7 @@ function osInfo(callback) {
|
|
|
311
270
|
const serial = util.getValue(lines, 'kern.uuid');
|
|
312
271
|
const bootmethod = util.getValue(lines, 'machdep.bootmethod');
|
|
313
272
|
const uefiConf = stdout.toString().indexOf('<type>efi</type>') >= 0;
|
|
314
|
-
const uefi = bootmethod ? bootmethod.toLowerCase().indexOf('uefi') >= 0 :
|
|
273
|
+
const uefi = bootmethod ? bootmethod.toLowerCase().indexOf('uefi') >= 0 : uefiConf ? uefiConf : null;
|
|
315
274
|
result.distro = distro || result.distro;
|
|
316
275
|
result.logofile = logofile || result.logofile;
|
|
317
276
|
result.release = release || result.release;
|
|
@@ -334,25 +293,24 @@ function osInfo(callback) {
|
|
|
334
293
|
result.build = util.getValue(lines, 'BuildVersion');
|
|
335
294
|
result.logofile = getLogoFile(result.distro);
|
|
336
295
|
result.codename = 'macOS';
|
|
337
|
-
result.codename =
|
|
338
|
-
result.codename =
|
|
339
|
-
result.codename =
|
|
340
|
-
result.codename =
|
|
341
|
-
result.codename =
|
|
342
|
-
result.codename =
|
|
343
|
-
result.codename =
|
|
344
|
-
result.codename =
|
|
345
|
-
result.codename =
|
|
346
|
-
result.codename =
|
|
347
|
-
result.codename =
|
|
348
|
-
result.codename =
|
|
349
|
-
result.codename =
|
|
350
|
-
result.codename =
|
|
351
|
-
result.codename =
|
|
352
|
-
result.codename =
|
|
353
|
-
result.codename =
|
|
354
|
-
result.codename =
|
|
355
|
-
result.codename = (result.release.startsWith('26.') ? 'Tahoe' : result.codename);
|
|
296
|
+
result.codename = result.release.indexOf('10.4') > -1 ? 'OS X Tiger' : result.codename;
|
|
297
|
+
result.codename = result.release.indexOf('10.5') > -1 ? 'OS X Leopard' : result.codename;
|
|
298
|
+
result.codename = result.release.indexOf('10.6') > -1 ? 'OS X Snow Leopard' : result.codename;
|
|
299
|
+
result.codename = result.release.indexOf('10.7') > -1 ? 'OS X Lion' : result.codename;
|
|
300
|
+
result.codename = result.release.indexOf('10.8') > -1 ? 'OS X Mountain Lion' : result.codename;
|
|
301
|
+
result.codename = result.release.indexOf('10.9') > -1 ? 'OS X Mavericks' : result.codename;
|
|
302
|
+
result.codename = result.release.indexOf('10.10') > -1 ? 'OS X Yosemite' : result.codename;
|
|
303
|
+
result.codename = result.release.indexOf('10.11') > -1 ? 'OS X El Capitan' : result.codename;
|
|
304
|
+
result.codename = result.release.indexOf('10.12') > -1 ? 'Sierra' : result.codename;
|
|
305
|
+
result.codename = result.release.indexOf('10.13') > -1 ? 'High Sierra' : result.codename;
|
|
306
|
+
result.codename = result.release.indexOf('10.14') > -1 ? 'Mojave' : result.codename;
|
|
307
|
+
result.codename = result.release.indexOf('10.15') > -1 ? 'Catalina' : result.codename;
|
|
308
|
+
result.codename = result.release.startsWith('11.') ? 'Big Sur' : result.codename;
|
|
309
|
+
result.codename = result.release.startsWith('12.') ? 'Monterey' : result.codename;
|
|
310
|
+
result.codename = result.release.startsWith('13.') ? 'Ventura' : result.codename;
|
|
311
|
+
result.codename = result.release.startsWith('14.') ? 'Sonoma' : result.codename;
|
|
312
|
+
result.codename = result.release.startsWith('15.') ? 'Sequoia' : result.codename;
|
|
313
|
+
result.codename = result.release.startsWith('26.') ? 'Tahoe' : result.codename;
|
|
356
314
|
result.uefi = true;
|
|
357
315
|
result.codepage = util.getCodepage();
|
|
358
316
|
if (callback) {
|
|
@@ -367,7 +325,9 @@ function osInfo(callback) {
|
|
|
367
325
|
let lines = stdout.toString().split('\n');
|
|
368
326
|
result.distro = lines[0];
|
|
369
327
|
result.logofile = getLogoFile(result.distro);
|
|
370
|
-
if (callback) {
|
|
328
|
+
if (callback) {
|
|
329
|
+
callback(result);
|
|
330
|
+
}
|
|
371
331
|
resolve(result);
|
|
372
332
|
});
|
|
373
333
|
}
|
|
@@ -379,9 +339,7 @@ function osInfo(callback) {
|
|
|
379
339
|
workload.push(util.powerShell('Get-CimInstance Win32_OperatingSystem | select Caption,SerialNumber,BuildNumber,ServicePackMajorVersion,ServicePackMinorVersion | fl'));
|
|
380
340
|
workload.push(util.powerShell('(Get-CimInstance Win32_ComputerSystem).HypervisorPresent'));
|
|
381
341
|
workload.push(util.powerShell('Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.SystemInformation]::TerminalServerSession'));
|
|
382
|
-
util.promiseAll(
|
|
383
|
-
workload
|
|
384
|
-
).then((data) => {
|
|
342
|
+
util.promiseAll(workload).then((data) => {
|
|
385
343
|
let lines = data.results[0] ? data.results[0].toString().split('\r\n') : [''];
|
|
386
344
|
result.distro = util.getValue(lines, 'Caption', ':').trim();
|
|
387
345
|
result.serial = util.getValue(lines, 'SerialNumber', ':').trim();
|
|
@@ -391,8 +349,8 @@ function osInfo(callback) {
|
|
|
391
349
|
const hyperv = data.results[1] ? data.results[1].toString().toLowerCase() : '';
|
|
392
350
|
result.hypervisor = hyperv.indexOf('true') !== -1;
|
|
393
351
|
const term = data.results[2] ? data.results[2].toString() : '';
|
|
394
|
-
result.remoteSession =
|
|
395
|
-
isUefiWindows().then(uefi => {
|
|
352
|
+
result.remoteSession = term.toString().toLowerCase().indexOf('true') >= 0;
|
|
353
|
+
isUefiWindows().then((uefi) => {
|
|
396
354
|
result.uefi = uefi;
|
|
397
355
|
if (callback) {
|
|
398
356
|
callback(result);
|
|
@@ -401,7 +359,9 @@ function osInfo(callback) {
|
|
|
401
359
|
});
|
|
402
360
|
});
|
|
403
361
|
} catch (e) {
|
|
404
|
-
if (callback) {
|
|
362
|
+
if (callback) {
|
|
363
|
+
callback(result);
|
|
364
|
+
}
|
|
405
365
|
resolve(result);
|
|
406
366
|
}
|
|
407
367
|
}
|
|
@@ -513,7 +473,7 @@ function versions(apps, callback) {
|
|
|
513
473
|
versions: {},
|
|
514
474
|
counter: 0
|
|
515
475
|
};
|
|
516
|
-
apps.forEach(el => {
|
|
476
|
+
apps.forEach((el) => {
|
|
517
477
|
if (el) {
|
|
518
478
|
for (let key in versionObject) {
|
|
519
479
|
if ({}.hasOwnProperty.call(versionObject, key)) {
|
|
@@ -524,7 +484,9 @@ function versions(apps, callback) {
|
|
|
524
484
|
result.versions.systemOpensslLib = '';
|
|
525
485
|
}
|
|
526
486
|
|
|
527
|
-
if (!result.versions[key]) {
|
|
487
|
+
if (!result.versions[key]) {
|
|
488
|
+
result.counter++;
|
|
489
|
+
}
|
|
528
490
|
}
|
|
529
491
|
}
|
|
530
492
|
}
|
|
@@ -542,7 +504,9 @@ function versions(apps, callback) {
|
|
|
542
504
|
} else {
|
|
543
505
|
apps = apps || '*';
|
|
544
506
|
if (typeof apps !== 'string') {
|
|
545
|
-
if (callback) {
|
|
507
|
+
if (callback) {
|
|
508
|
+
callback({});
|
|
509
|
+
}
|
|
546
510
|
return resolve({});
|
|
547
511
|
}
|
|
548
512
|
}
|
|
@@ -684,7 +648,7 @@ function versions(apps, callback) {
|
|
|
684
648
|
exec('apachectl -v 2>&1', function (error, stdout) {
|
|
685
649
|
if (!error) {
|
|
686
650
|
const apache = (stdout.toString().split('\n')[0] || '').split(':');
|
|
687
|
-
appsObj.versions.apache =
|
|
651
|
+
appsObj.versions.apache = apache.length > 1 ? apache[1].replace('Apache', '').replace('/', '').split('(')[0].trim() : '';
|
|
688
652
|
}
|
|
689
653
|
functionProcessed();
|
|
690
654
|
});
|
|
@@ -854,7 +818,7 @@ function versions(apps, callback) {
|
|
|
854
818
|
const gitHomebrewExists1 = fs.existsSync('/usr/local/Cellar/python');
|
|
855
819
|
const gitHomebrewExists2 = fs.existsSync('/opt/homebrew/bin/python');
|
|
856
820
|
if ((util.darwinXcodeExists() && util.semverCompare('12.0.1', osVersion) < 0) || gitHomebrewExists1 || gitHomebrewExists2) {
|
|
857
|
-
const cmd = gitHomebrewExists1 ? '/usr/local/Cellar/python -V 2>&1' :
|
|
821
|
+
const cmd = gitHomebrewExists1 ? '/usr/local/Cellar/python -V 2>&1' : gitHomebrewExists2 ? '/opt/homebrew/bin/python -V 2>&1' : 'python -V 2>&1';
|
|
858
822
|
exec(cmd, function (error, stdout) {
|
|
859
823
|
if (!error) {
|
|
860
824
|
const python = stdout.toString().split('\n')[0] || '';
|
|
@@ -868,7 +832,6 @@ function versions(apps, callback) {
|
|
|
868
832
|
} catch (e) {
|
|
869
833
|
functionProcessed();
|
|
870
834
|
}
|
|
871
|
-
|
|
872
835
|
} else {
|
|
873
836
|
exec('python -V 2>&1', function (error, stdout) {
|
|
874
837
|
if (!error) {
|
|
@@ -1080,7 +1043,9 @@ function versions(apps, callback) {
|
|
|
1080
1043
|
exec('node -v', function (error, stdout) {
|
|
1081
1044
|
if (!error) {
|
|
1082
1045
|
let line = stdout.toString().split('\n')[0].trim();
|
|
1083
|
-
if (line.startsWith('v')) {
|
|
1046
|
+
if (line.startsWith('v')) {
|
|
1047
|
+
line = line.slice(1);
|
|
1048
|
+
}
|
|
1084
1049
|
appsObj.versions.node = line;
|
|
1085
1050
|
}
|
|
1086
1051
|
functionProcessed();
|
|
@@ -1088,8 +1053,12 @@ function versions(apps, callback) {
|
|
|
1088
1053
|
}
|
|
1089
1054
|
if ({}.hasOwnProperty.call(appsObj.versions, 'powershell')) {
|
|
1090
1055
|
if (_windows) {
|
|
1091
|
-
util.powerShell('$PSVersionTable').then(stdout => {
|
|
1092
|
-
const lines = stdout
|
|
1056
|
+
util.powerShell('$PSVersionTable').then((stdout) => {
|
|
1057
|
+
const lines = stdout
|
|
1058
|
+
.toString()
|
|
1059
|
+
.toLowerCase()
|
|
1060
|
+
.split('\n')
|
|
1061
|
+
.map((line) => line.replace(/ +/g, ' ').replace(/ +/g, ':'));
|
|
1093
1062
|
appsObj.versions.powershell = util.getValue(lines, 'psversion');
|
|
1094
1063
|
functionProcessed();
|
|
1095
1064
|
});
|
|
@@ -1099,23 +1068,31 @@ function versions(apps, callback) {
|
|
|
1099
1068
|
}
|
|
1100
1069
|
if ({}.hasOwnProperty.call(appsObj.versions, 'dotnet')) {
|
|
1101
1070
|
if (_windows) {
|
|
1102
|
-
util
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
const
|
|
1108
|
-
dotnet =
|
|
1071
|
+
util
|
|
1072
|
+
.powerShell(
|
|
1073
|
+
'gci "HKLM:\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP" -recurse | gp -name Version,Release -EA 0 | where { $_.PSChildName -match "^(?!S)\\p{L}"} | select PSChildName, Version, Release'
|
|
1074
|
+
)
|
|
1075
|
+
.then((stdout) => {
|
|
1076
|
+
const lines = stdout.toString().split('\r\n');
|
|
1077
|
+
let dotnet = '';
|
|
1078
|
+
lines.forEach((line) => {
|
|
1079
|
+
line = line.replace(/ +/g, ' ');
|
|
1080
|
+
const parts = line.split(' ');
|
|
1081
|
+
dotnet =
|
|
1082
|
+
dotnet ||
|
|
1083
|
+
(parts[0].toLowerCase().startsWith('client') && parts.length > 2 ? parts[1].trim() : parts[0].toLowerCase().startsWith('full') && parts.length > 2 ? parts[1].trim() : '');
|
|
1084
|
+
});
|
|
1085
|
+
appsObj.versions.dotnet = dotnet.trim();
|
|
1086
|
+
functionProcessed();
|
|
1109
1087
|
});
|
|
1110
|
-
appsObj.versions.dotnet = dotnet.trim();
|
|
1111
|
-
functionProcessed();
|
|
1112
|
-
});
|
|
1113
1088
|
} else {
|
|
1114
1089
|
functionProcessed();
|
|
1115
1090
|
}
|
|
1116
1091
|
}
|
|
1117
1092
|
} catch (e) {
|
|
1118
|
-
if (callback) {
|
|
1093
|
+
if (callback) {
|
|
1094
|
+
callback(appsObj.versions);
|
|
1095
|
+
}
|
|
1119
1096
|
resolve(appsObj.versions);
|
|
1120
1097
|
}
|
|
1121
1098
|
});
|
|
@@ -1130,7 +1107,7 @@ function shell(callback) {
|
|
|
1130
1107
|
if (_windows) {
|
|
1131
1108
|
try {
|
|
1132
1109
|
const result = 'CMD';
|
|
1133
|
-
util.powerShell(`Get-CimInstance -className win32_process | where-object {$_.ProcessId -eq ${process.ppid} } | select Name`).then(stdout => {
|
|
1110
|
+
util.powerShell(`Get-CimInstance -className win32_process | where-object {$_.ProcessId -eq ${process.ppid} } | select Name`).then((stdout) => {
|
|
1134
1111
|
let result = 'CMD';
|
|
1135
1112
|
if (stdout) {
|
|
1136
1113
|
if (stdout.toString().toLowerCase().indexOf('powershell') >= 0) {
|
|
@@ -1183,8 +1160,12 @@ function getUniqueMacAdresses() {
|
|
|
1183
1160
|
}
|
|
1184
1161
|
}
|
|
1185
1162
|
macs = macs.sort(function (a, b) {
|
|
1186
|
-
if (a < b) {
|
|
1187
|
-
|
|
1163
|
+
if (a < b) {
|
|
1164
|
+
return -1;
|
|
1165
|
+
}
|
|
1166
|
+
if (a > b) {
|
|
1167
|
+
return 1;
|
|
1168
|
+
}
|
|
1188
1169
|
return 0;
|
|
1189
1170
|
});
|
|
1190
1171
|
} catch (e) {
|
|
@@ -1196,7 +1177,6 @@ function getUniqueMacAdresses() {
|
|
|
1196
1177
|
function uuid(callback) {
|
|
1197
1178
|
return new Promise((resolve) => {
|
|
1198
1179
|
process.nextTick(() => {
|
|
1199
|
-
|
|
1200
1180
|
let result = {
|
|
1201
1181
|
os: '',
|
|
1202
1182
|
hardware: '',
|
|
@@ -1248,8 +1228,12 @@ echo -n "hardware: "; cat /sys/class/dmi/id/product_uuid 2> /dev/null; echo;`;
|
|
|
1248
1228
|
const lines = stdout.toString().split('\n');
|
|
1249
1229
|
result.hardware = util.getValue(lines, 'kern.hostid', ':').toLowerCase();
|
|
1250
1230
|
result.os = util.getValue(lines, 'kern.hostuuid', ':').toLowerCase();
|
|
1251
|
-
if (result.os.indexOf('unknown') >= 0) {
|
|
1252
|
-
|
|
1231
|
+
if (result.os.indexOf('unknown') >= 0) {
|
|
1232
|
+
result.os = '';
|
|
1233
|
+
}
|
|
1234
|
+
if (result.hardware.indexOf('unknown') >= 0) {
|
|
1235
|
+
result.hardware = '';
|
|
1236
|
+
}
|
|
1253
1237
|
if (callback) {
|
|
1254
1238
|
callback(result);
|
|
1255
1239
|
}
|
|
@@ -1266,7 +1250,7 @@ echo -n "hardware: "; cat /sys/class/dmi/id/product_uuid 2> /dev/null; echo;`;
|
|
|
1266
1250
|
result.hardware = util.getValue(lines, 'uuid', ':').toLowerCase();
|
|
1267
1251
|
exec(`${sysdir}\\reg query "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography" /v MachineGuid`, util.execOptsWin, function (error, stdout) {
|
|
1268
1252
|
parts = stdout.toString().split('\n\r')[0].split('REG_SZ');
|
|
1269
|
-
result.os = parts.length > 1 ? parts[1].replace(/\r+|\n+|\s+/
|
|
1253
|
+
result.os = parts.length > 1 ? parts[1].replace(/\r+|\n+|\s+/gi, '').toLowerCase() : '';
|
|
1270
1254
|
if (callback) {
|
|
1271
1255
|
callback(result);
|
|
1272
1256
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "systeminformation",
|
|
3
|
-
"version": "5.28.
|
|
3
|
+
"version": "5.28.2",
|
|
4
4
|
"description": "Advanced, lightweight system and OS information library",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Sebastian Hildebrandt <hildebrandt@plus-innovations.com> (https://plus-innovations.com)",
|