sysiddr5 1.0.1-beta-3

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/osinfo.js ADDED
@@ -0,0 +1,1167 @@
1
+ 'use strict';
2
+ // @ts-check
3
+ // ==================================================================================
4
+ // osinfo.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
+ // 3. Operating System
14
+ // ----------------------------------------------------------------------------------
15
+
16
+ const os = require('os');
17
+ const fs = require('fs');
18
+ const util = require('./util');
19
+ const exec = require('child_process').exec;
20
+ const execSync = require('child_process').execSync;
21
+
22
+ let _platform = process.platform;
23
+
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
+
32
+ // --------------------------
33
+ // Get current time and OS uptime
34
+
35
+ function time() {
36
+ let t = new Date().toString().split(' ');
37
+ return {
38
+ current: Date.now(),
39
+ uptime: os.uptime(),
40
+ timezone: (t.length >= 7) ? t[5] : '',
41
+ timezoneName: Intl ? Intl.DateTimeFormat().resolvedOptions().timeZone : (t.length >= 7) ? t.slice(6).join(' ').replace(/\(/g, '').replace(/\)/g, '') : ''
42
+ };
43
+ }
44
+
45
+ exports.time = time;
46
+
47
+ // --------------------------
48
+ // Get logo filename of OS distribution
49
+
50
+ function getLogoFile(distro) {
51
+ distro = distro || '';
52
+ distro = distro.toLowerCase();
53
+ let result = _platform;
54
+ if (_windows) {
55
+ result = 'windows';
56
+ }
57
+ else if (distro.indexOf('mac os') !== -1) {
58
+ result = 'apple';
59
+ }
60
+ else if (distro.indexOf('arch') !== -1) {
61
+ result = 'arch';
62
+ }
63
+ else if (distro.indexOf('centos') !== -1) {
64
+ result = 'centos';
65
+ }
66
+ else if (distro.indexOf('coreos') !== -1) {
67
+ result = 'coreos';
68
+ }
69
+ else if (distro.indexOf('debian') !== -1) {
70
+ result = 'debian';
71
+ }
72
+ else if (distro.indexOf('deepin') !== -1) {
73
+ result = 'deepin';
74
+ }
75
+ else if (distro.indexOf('elementary') !== -1) {
76
+ result = 'elementary';
77
+ }
78
+ else if (distro.indexOf('fedora') !== -1) {
79
+ result = 'fedora';
80
+ }
81
+ else if (distro.indexOf('gentoo') !== -1) {
82
+ result = 'gentoo';
83
+ }
84
+ else if (distro.indexOf('mageia') !== -1) {
85
+ result = 'mageia';
86
+ }
87
+ else if (distro.indexOf('mandriva') !== -1) {
88
+ result = 'mandriva';
89
+ }
90
+ else if (distro.indexOf('manjaro') !== -1) {
91
+ result = 'manjaro';
92
+ }
93
+ else if (distro.indexOf('mint') !== -1) {
94
+ result = 'mint';
95
+ }
96
+ else if (distro.indexOf('mx') !== -1) {
97
+ result = 'mx';
98
+ }
99
+ else if (distro.indexOf('openbsd') !== -1) {
100
+ result = 'openbsd';
101
+ }
102
+ else if (distro.indexOf('freebsd') !== -1) {
103
+ result = 'freebsd';
104
+ }
105
+ else if (distro.indexOf('opensuse') !== -1) {
106
+ result = 'opensuse';
107
+ }
108
+ else if (distro.indexOf('pclinuxos') !== -1) {
109
+ result = 'pclinuxos';
110
+ }
111
+ else if (distro.indexOf('puppy') !== -1) {
112
+ result = 'puppy';
113
+ }
114
+ else if (distro.indexOf('raspbian') !== -1) {
115
+ result = 'raspbian';
116
+ }
117
+ else if (distro.indexOf('reactos') !== -1) {
118
+ result = 'reactos';
119
+ }
120
+ else if (distro.indexOf('redhat') !== -1) {
121
+ result = 'redhat';
122
+ }
123
+ else if (distro.indexOf('slackware') !== -1) {
124
+ result = 'slackware';
125
+ }
126
+ else if (distro.indexOf('sugar') !== -1) {
127
+ result = 'sugar';
128
+ }
129
+ else if (distro.indexOf('steam') !== -1) {
130
+ result = 'steam';
131
+ }
132
+ else if (distro.indexOf('suse') !== -1) {
133
+ result = 'suse';
134
+ }
135
+ else if (distro.indexOf('mate') !== -1) {
136
+ result = 'ubuntu-mate';
137
+ }
138
+ else if (distro.indexOf('lubuntu') !== -1) {
139
+ result = 'lubuntu';
140
+ }
141
+ else if (distro.indexOf('xubuntu') !== -1) {
142
+ result = 'xubuntu';
143
+ }
144
+ else if (distro.indexOf('ubuntu') !== -1) {
145
+ result = 'ubuntu';
146
+ }
147
+ else if (distro.indexOf('solaris') !== -1) {
148
+ result = 'solaris';
149
+ }
150
+ else if (distro.indexOf('tails') !== -1) {
151
+ result = 'tails';
152
+ }
153
+ else if (distro.indexOf('feren') !== -1) {
154
+ result = 'ferenos';
155
+ }
156
+ else if (distro.indexOf('robolinux') !== -1) {
157
+ result = 'robolinux';
158
+ } else if (_linux && distro) {
159
+ result = distro.toLowerCase().trim().replace(/\s+/g, '-');
160
+ }
161
+ return result;
162
+ }
163
+
164
+ // --------------------------
165
+ // FQDN
166
+
167
+ function getFQDN() {
168
+ let fqdn = os.hostname;
169
+ if (_linux || _darwin) {
170
+ try {
171
+ const stdout = execSync('hostnamectl --json short 2>/dev/null');
172
+ const json = JSON.parse(stdout.toString());
173
+
174
+ fqdn = json['StaticHostname'];
175
+ } catch (e) {
176
+ try {
177
+ const stdout = execSync('hostname -f 2>/dev/null');
178
+ fqdn = stdout.toString().split(os.EOL)[0];
179
+ } catch (e) {
180
+ util.noop();
181
+ }
182
+ }
183
+ } if (_freebsd || _openbsd || _netbsd) {
184
+ try {
185
+ const stdout = execSync('hostname 2>/dev/null');
186
+ fqdn = stdout.toString().split(os.EOL)[0];
187
+ } catch (e) {
188
+ util.noop();
189
+ }
190
+ }
191
+ if (_windows) {
192
+ try {
193
+ const stdout = execSync('echo %COMPUTERNAME%.%USERDNSDOMAIN%', util.execOptsWin);
194
+ fqdn = stdout.toString().replace('.%USERDNSDOMAIN%', '').split(os.EOL)[0];
195
+ } catch (e) {
196
+ util.noop();
197
+ }
198
+ }
199
+ return fqdn;
200
+ }
201
+
202
+ // --------------------------
203
+ // OS Information
204
+
205
+ function osInfo(callback) {
206
+
207
+ return new Promise((resolve) => {
208
+ process.nextTick(() => {
209
+ let result = {
210
+
211
+ platform: (_platform === 'win32' ? 'Windows' : _platform),
212
+ distro: 'unknown',
213
+ release: 'unknown',
214
+ codename: '',
215
+ kernel: os.release(),
216
+ arch: os.arch(),
217
+ hostname: os.hostname(),
218
+ fqdn: getFQDN(),
219
+ codepage: '',
220
+ logofile: '',
221
+ serial: '',
222
+ build: '',
223
+ servicepack: '',
224
+ uefi: false
225
+ };
226
+
227
+ if (_linux) {
228
+
229
+ exec('cat /etc/*-release; cat /usr/lib/os-release; cat /etc/openwrt_release', function (error, stdout) {
230
+ /**
231
+ * @namespace
232
+ * @property {string} DISTRIB_ID
233
+ * @property {string} NAME
234
+ * @property {string} DISTRIB_RELEASE
235
+ * @property {string} VERSION_ID
236
+ * @property {string} DISTRIB_CODENAME
237
+ */
238
+ let release = {};
239
+ let lines = stdout.toString().split('\n');
240
+ lines.forEach(function (line) {
241
+ if (line.indexOf('=') !== -1) {
242
+ release[line.split('=')[0].trim().toUpperCase()] = line.split('=')[1].trim();
243
+ }
244
+ });
245
+ let releaseVersion = (release.VERSION || '').replace(/"/g, '');
246
+ let codename = (release.DISTRIB_CODENAME || release.VERSION_CODENAME || '').replace(/"/g, '');
247
+ if (releaseVersion.indexOf('(') >= 0) {
248
+ codename = releaseVersion.split('(')[1].replace(/[()]/g, '').trim();
249
+ releaseVersion = releaseVersion.split('(')[0].trim();
250
+ }
251
+ result.distro = (release.DISTRIB_ID || release.NAME || 'unknown').replace(/"/g, '');
252
+ result.logofile = getLogoFile(result.distro);
253
+ result.release = (releaseVersion || release.DISTRIB_RELEASE || release.VERSION_ID || 'unknown').replace(/"/g, '');
254
+ result.codename = codename;
255
+ result.codepage = util.getCodepage();
256
+ result.build = (release.BUILD_ID || '').replace(/"/g, '').trim();
257
+ isUefiLinux().then(uefi => {
258
+ result.uefi = uefi;
259
+ uuid().then((data) => {
260
+ result.serial = data.os;
261
+ if (callback) {
262
+ callback(result);
263
+ }
264
+ resolve(result);
265
+ });
266
+ });
267
+ });
268
+ }
269
+ if (_freebsd || _openbsd || _netbsd) {
270
+
271
+ exec('sysctl kern.ostype kern.osrelease kern.osrevision kern.hostuuid machdep.bootmethod kern.geom.confxml', function (error, stdout) {
272
+ let lines = stdout.toString().split('\n');
273
+ const distro = util.getValue(lines, 'kern.ostype');
274
+ const logofile = util.getValue(lines, 'kern.ostype');
275
+ const release = util.getValue(lines, 'kern.osrelease').split('-')[0];
276
+ const serial = util.getValue(lines, 'kern.uuid');
277
+ const bootmethod = util.getValue(lines, 'machdep.bootmethod');
278
+ const uefiConf = stdout.toString().indexOf('<type>efi</type>') >= 0;
279
+ const uefi = bootmethod ? bootmethod.toLowerCase().indexOf('uefi') >= 0 : (uefiConf ? uefiConf : null);
280
+ result.distro = distro || result.distro;
281
+ result.logofile = logofile || result.logofile;
282
+ result.release = release || result.release;
283
+ result.serial = serial || result.serial;
284
+ result.codename = '';
285
+ result.codepage = util.getCodepage();
286
+ result.uefi = uefi || null;
287
+ if (callback) {
288
+ callback(result);
289
+ }
290
+ resolve(result);
291
+ });
292
+ }
293
+ if (_darwin) {
294
+ exec('sw_vers; sysctl kern.ostype kern.osrelease kern.osrevision kern.uuid', function (error, stdout) {
295
+ let lines = stdout.toString().split('\n');
296
+ result.serial = util.getValue(lines, 'kern.uuid');
297
+ result.distro = util.getValue(lines, 'ProductName');
298
+ result.release = (util.getValue(lines, 'ProductVersion', ':', true, true) + ' ' + util.getValue(lines, 'ProductVersionExtra', ':', true, true)).trim();
299
+ result.build = util.getValue(lines, 'BuildVersion');
300
+ result.logofile = getLogoFile(result.distro);
301
+ result.codename = 'macOS';
302
+ result.codename = (result.release.indexOf('10.4') > -1 ? 'Mac OS X Tiger' : result.codename);
303
+ result.codename = (result.release.indexOf('10.5') > -1 ? 'Mac OS X Leopard' : result.codename);
304
+ result.codename = (result.release.indexOf('10.6') > -1 ? 'Mac OS X Snow Leopard' : result.codename);
305
+ result.codename = (result.release.indexOf('10.7') > -1 ? 'Mac OS X Lion' : result.codename);
306
+ result.codename = (result.release.indexOf('10.8') > -1 ? 'OS X Mountain Lion' : result.codename);
307
+ result.codename = (result.release.indexOf('10.9') > -1 ? 'OS X Mavericks' : result.codename);
308
+ result.codename = (result.release.indexOf('10.10') > -1 ? 'OS X Yosemite' : result.codename);
309
+ result.codename = (result.release.indexOf('10.11') > -1 ? 'OS X El Capitan' : result.codename);
310
+ result.codename = (result.release.indexOf('10.12') > -1 ? 'macOS Sierra' : result.codename);
311
+ result.codename = (result.release.indexOf('10.13') > -1 ? 'macOS High Sierra' : result.codename);
312
+ result.codename = (result.release.indexOf('10.14') > -1 ? 'macOS Mojave' : result.codename);
313
+ result.codename = (result.release.indexOf('10.15') > -1 ? 'macOS Catalina' : result.codename);
314
+ result.codename = (result.release.startsWith('11.') ? 'macOS Big Sur' : result.codename);
315
+ result.codename = (result.release.startsWith('12.') ? 'macOS Monterey' : result.codename);
316
+ result.codename = (result.release.startsWith('13.') ? 'macOS Ventura' : result.codename);
317
+ result.uefi = true;
318
+ result.codepage = util.getCodepage();
319
+ if (callback) {
320
+ callback(result);
321
+ }
322
+ resolve(result);
323
+ });
324
+ }
325
+ if (_sunos) {
326
+ result.release = result.kernel;
327
+ exec('uname -o', function (error, stdout) {
328
+ let lines = stdout.toString().split('\n');
329
+ result.distro = lines[0];
330
+ result.logofile = getLogoFile(result.distro);
331
+ if (callback) { callback(result); }
332
+ resolve(result);
333
+ });
334
+ }
335
+ if (_windows) {
336
+ result.logofile = getLogoFile();
337
+ result.release = result.kernel;
338
+ try {
339
+ const workload = [];
340
+ workload.push(util.powerShell('Get-CimInstance Win32_OperatingSystem | select Caption,SerialNumber,BuildNumber,ServicePackMajorVersion,ServicePackMinorVersion | fl'));
341
+ workload.push(util.powerShell('(Get-CimInstance Win32_ComputerSystem).HypervisorPresent'));
342
+ workload.push(util.powerShell('Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.SystemInformation]::TerminalServerSession'));
343
+ util.promiseAll(
344
+ workload
345
+ ).then((data) => {
346
+ let lines = data.results[0] ? data.results[0].toString().split('\r\n') : [''];
347
+ result.distro = util.getValue(lines, 'Caption', ':').trim();
348
+ result.serial = util.getValue(lines, 'SerialNumber', ':').trim();
349
+ result.build = util.getValue(lines, 'BuildNumber', ':').trim();
350
+ result.servicepack = util.getValue(lines, 'ServicePackMajorVersion', ':').trim() + '.' + util.getValue(lines, 'ServicePackMinorVersion', ':').trim();
351
+ result.codepage = util.getCodepage();
352
+ const hyperv = data.results[1] ? data.results[1].toString().toLowerCase() : '';
353
+ result.hypervisor = hyperv.indexOf('true') !== -1;
354
+ const term = data.results[2] ? data.results[2].toString() : '';
355
+ result.remoteSession = (term.toString().toLowerCase().indexOf('true') >= 0);
356
+ isUefiWindows().then(uefi => {
357
+ result.uefi = uefi;
358
+ if (callback) {
359
+ callback(result);
360
+ }
361
+ resolve(result);
362
+ });
363
+ });
364
+ } catch (e) {
365
+ if (callback) { callback(result); }
366
+ resolve(result);
367
+ }
368
+ }
369
+ });
370
+ });
371
+ }
372
+
373
+ exports.osInfo = osInfo;
374
+
375
+ function isUefiLinux() {
376
+ return new Promise((resolve) => {
377
+ process.nextTick(() => {
378
+ fs.stat('/sys/firmware/efi', function (err) {
379
+ if (!err) {
380
+ return resolve(true);
381
+ } else {
382
+ exec('dmesg | grep -E "EFI v"', function (error, stdout) {
383
+ if (!error) {
384
+ const lines = stdout.toString().split('\n');
385
+ return resolve(lines.length > 0);
386
+ }
387
+ return resolve(false);
388
+ });
389
+ }
390
+ });
391
+ });
392
+ });
393
+ }
394
+
395
+ function isUefiWindows() {
396
+ return new Promise((resolve) => {
397
+ process.nextTick(() => {
398
+ try {
399
+ exec('findstr /C:"Detected boot environment" "%windir%\\Panther\\setupact.log"', util.execOptsWin, function (error, stdout) {
400
+ if (!error) {
401
+ const line = stdout.toString().split('\n\r')[0];
402
+ return resolve(line.toLowerCase().indexOf('efi') >= 0);
403
+ } else {
404
+ exec('echo %firmware_type%', util.execOptsWin, function (error, stdout) {
405
+ if (!error) {
406
+ const line = stdout.toString() || '';
407
+ return resolve(line.toLowerCase().indexOf('efi') >= 0);
408
+ } else {
409
+ return resolve(false);
410
+ }
411
+ });
412
+ }
413
+ });
414
+ } catch (e) {
415
+ return resolve(false);
416
+ }
417
+ });
418
+ });
419
+ }
420
+
421
+ function versions(apps, callback) {
422
+ let versionObject = {
423
+ kernel: os.release(),
424
+ openssl: '',
425
+ systemOpenssl: '',
426
+ systemOpensslLib: '',
427
+ node: process.versions.node,
428
+ v8: process.versions.v8,
429
+ npm: '',
430
+ yarn: '',
431
+ pm2: '',
432
+ gulp: '',
433
+ grunt: '',
434
+ git: '',
435
+ tsc: '',
436
+ mysql: '',
437
+ redis: '',
438
+ mongodb: '',
439
+ apache: '',
440
+ nginx: '',
441
+ php: '',
442
+ docker: '',
443
+ postfix: '',
444
+ postgresql: '',
445
+ perl: '',
446
+ python: '',
447
+ python3: '',
448
+ pip: '',
449
+ pip3: '',
450
+ java: '',
451
+ gcc: '',
452
+ virtualbox: '',
453
+ bash: '',
454
+ zsh: '',
455
+ fish: '',
456
+ powershell: '',
457
+ dotnet: ''
458
+ };
459
+
460
+ function checkVersionParam(apps) {
461
+ if (apps === '*') {
462
+ return {
463
+ versions: versionObject,
464
+ counter: 30
465
+ };
466
+ }
467
+ if (!Array.isArray(apps)) {
468
+ apps = apps.trim().toLowerCase().replace(/,+/g, '|').replace(/ /g, '|');
469
+ apps = apps.split('|');
470
+ const result = {
471
+ versions: {},
472
+ counter: 0
473
+ };
474
+ apps.forEach(el => {
475
+ if (el) {
476
+ for (let key in versionObject) {
477
+ if ({}.hasOwnProperty.call(versionObject, key)) {
478
+ if (key.toLowerCase() === el.toLowerCase() && !{}.hasOwnProperty.call(result.versions, key)) {
479
+ result.versions[key] = versionObject[key];
480
+ if (key === 'openssl') {
481
+ result.versions.systemOpenssl = '';
482
+ result.versions.systemOpensslLib = '';
483
+ }
484
+
485
+ if (!result.versions[key]) { result.counter++; }
486
+ }
487
+ }
488
+ }
489
+ }
490
+ });
491
+ return result;
492
+ }
493
+ }
494
+
495
+ return new Promise((resolve) => {
496
+ process.nextTick(() => {
497
+ if (util.isFunction(apps) && !callback) {
498
+ callback = apps;
499
+ apps = '*';
500
+ } else {
501
+ apps = apps || '*';
502
+ if (typeof apps !== 'string') {
503
+ if (callback) { callback({}); }
504
+ return resolve({});
505
+ }
506
+ }
507
+ const appsObj = checkVersionParam(apps);
508
+ let totalFunctions = appsObj.counter;
509
+
510
+ let functionProcessed = (function () {
511
+ return function () {
512
+ if (--totalFunctions === 0) {
513
+ if (callback) {
514
+ callback(appsObj.versions);
515
+ }
516
+ resolve(appsObj.versions);
517
+ }
518
+ };
519
+ })();
520
+
521
+ let cmd = '';
522
+ try {
523
+ if ({}.hasOwnProperty.call(appsObj.versions, 'openssl')) {
524
+ appsObj.versions.openssl = process.versions.openssl;
525
+ exec('openssl version', function (error, stdout) {
526
+ if (!error) {
527
+ let openssl_string = stdout.toString().split('\n')[0].trim();
528
+ let openssl = openssl_string.split(' ');
529
+ appsObj.versions.systemOpenssl = openssl.length > 0 ? openssl[1] : openssl[0];
530
+ appsObj.versions.systemOpensslLib = openssl.length > 0 ? openssl[0] : 'openssl';
531
+ }
532
+ functionProcessed();
533
+ });
534
+ }
535
+ if ({}.hasOwnProperty.call(appsObj.versions, 'npm')) {
536
+ exec('npm -v', function (error, stdout) {
537
+ if (!error) {
538
+ appsObj.versions.npm = stdout.toString().split('\n')[0];
539
+ }
540
+ functionProcessed();
541
+ });
542
+ }
543
+ if ({}.hasOwnProperty.call(appsObj.versions, 'pm2')) {
544
+ cmd = 'pm2';
545
+ if (_windows) {
546
+ cmd += '.cmd';
547
+ }
548
+ exec(`${cmd} -v`, function (error, stdout) {
549
+ if (!error) {
550
+ let pm2 = stdout.toString().split('\n')[0].trim();
551
+ if (!pm2.startsWith('[PM2]')) {
552
+ appsObj.versions.pm2 = pm2;
553
+ }
554
+ }
555
+ functionProcessed();
556
+ });
557
+ }
558
+ if ({}.hasOwnProperty.call(appsObj.versions, 'yarn')) {
559
+ exec('yarn --version', function (error, stdout) {
560
+ if (!error) {
561
+ appsObj.versions.yarn = stdout.toString().split('\n')[0];
562
+ }
563
+ functionProcessed();
564
+ });
565
+ }
566
+ if ({}.hasOwnProperty.call(appsObj.versions, 'gulp')) {
567
+ cmd = 'gulp';
568
+ if (_windows) {
569
+ cmd += '.cmd';
570
+ }
571
+ exec(`${cmd} --version`, function (error, stdout) {
572
+ if (!error) {
573
+ const gulp = stdout.toString().split('\n')[0] || '';
574
+ appsObj.versions.gulp = (gulp.toLowerCase().split('version')[1] || '').trim();
575
+ }
576
+ functionProcessed();
577
+ });
578
+ }
579
+ if ({}.hasOwnProperty.call(appsObj.versions, 'tsc')) {
580
+ cmd = 'tsc';
581
+ if (_windows) {
582
+ cmd += '.cmd';
583
+ }
584
+ exec(`${cmd} --version`, function (error, stdout) {
585
+ if (!error) {
586
+ const tsc = stdout.toString().split('\n')[0] || '';
587
+ appsObj.versions.tsc = (tsc.toLowerCase().split('version')[1] || '').trim();
588
+ }
589
+ functionProcessed();
590
+ });
591
+ }
592
+ if ({}.hasOwnProperty.call(appsObj.versions, 'grunt')) {
593
+ cmd = 'grunt';
594
+ if (_windows) {
595
+ cmd += '.cmd';
596
+ }
597
+ exec(`${cmd} --version`, function (error, stdout) {
598
+ if (!error) {
599
+ const grunt = stdout.toString().split('\n')[0] || '';
600
+ appsObj.versions.grunt = (grunt.toLowerCase().split('cli v')[1] || '').trim();
601
+ }
602
+ functionProcessed();
603
+ });
604
+ }
605
+ if ({}.hasOwnProperty.call(appsObj.versions, 'git')) {
606
+ if (_darwin) {
607
+ const gitHomebrewExists = fs.existsSync('/usr/local/Cellar/git') || fs.existsSync('/opt/homebrew/bin/git');
608
+ if (util.darwinXcodeExists() || gitHomebrewExists) {
609
+ exec('git --version', function (error, stdout) {
610
+ if (!error) {
611
+ let git = stdout.toString().split('\n')[0] || '';
612
+ git = (git.toLowerCase().split('version')[1] || '').trim();
613
+ appsObj.versions.git = (git.split(' ')[0] || '').trim();
614
+ }
615
+ functionProcessed();
616
+ });
617
+ } else {
618
+ functionProcessed();
619
+ }
620
+ } else {
621
+ exec('git --version', function (error, stdout) {
622
+ if (!error) {
623
+ let git = stdout.toString().split('\n')[0] || '';
624
+ git = (git.toLowerCase().split('version')[1] || '').trim();
625
+ appsObj.versions.git = (git.split(' ')[0] || '').trim();
626
+ }
627
+ functionProcessed();
628
+ });
629
+ }
630
+ }
631
+ if ({}.hasOwnProperty.call(appsObj.versions, 'apache')) {
632
+ exec('apachectl -v 2>&1', function (error, stdout) {
633
+ if (!error) {
634
+ const apache = (stdout.toString().split('\n')[0] || '').split(':');
635
+ appsObj.versions.apache = (apache.length > 1 ? apache[1].replace('Apache', '').replace('/', '').split('(')[0].trim() : '');
636
+ }
637
+ functionProcessed();
638
+ });
639
+ }
640
+ if ({}.hasOwnProperty.call(appsObj.versions, 'nginx')) {
641
+ exec('nginx -v 2>&1', function (error, stdout) {
642
+ if (!error) {
643
+ const nginx = stdout.toString().split('\n')[0] || '';
644
+ appsObj.versions.nginx = (nginx.toLowerCase().split('/')[1] || '').trim();
645
+ }
646
+ functionProcessed();
647
+ });
648
+ }
649
+ if ({}.hasOwnProperty.call(appsObj.versions, 'mysql')) {
650
+ exec('mysql -V', function (error, stdout) {
651
+ if (!error) {
652
+ let mysql = stdout.toString().split('\n')[0] || '';
653
+ mysql = mysql.toLowerCase();
654
+ if (mysql.indexOf(',') > -1) {
655
+ mysql = (mysql.split(',')[0] || '').trim();
656
+ const parts = mysql.split(' ');
657
+ appsObj.versions.mysql = (parts[parts.length - 1] || '').trim();
658
+ } else {
659
+ if (mysql.indexOf(' ver ') > -1) {
660
+ mysql = mysql.split(' ver ')[1];
661
+ appsObj.versions.mysql = mysql.split(' ')[0];
662
+ }
663
+ }
664
+ }
665
+ functionProcessed();
666
+ });
667
+ }
668
+ if ({}.hasOwnProperty.call(appsObj.versions, 'php')) {
669
+ exec('php -v', function (error, stdout) {
670
+ if (!error) {
671
+ const php = stdout.toString().split('\n')[0] || '';
672
+ let parts = php.split('(');
673
+ if (parts[0].indexOf('-')) {
674
+ parts = parts[0].split('-');
675
+ }
676
+ appsObj.versions.php = parts[0].replace(/[^0-9.]/g, '');
677
+ }
678
+ functionProcessed();
679
+ });
680
+ }
681
+ if ({}.hasOwnProperty.call(appsObj.versions, 'redis')) {
682
+ exec('redis-server --version', function (error, stdout) {
683
+ if (!error) {
684
+ const redis = stdout.toString().split('\n')[0] || '';
685
+ const parts = redis.split(' ');
686
+ appsObj.versions.redis = util.getValue(parts, 'v', '=', true);
687
+ }
688
+ functionProcessed();
689
+ });
690
+ }
691
+ if ({}.hasOwnProperty.call(appsObj.versions, 'docker')) {
692
+ exec('docker --version', function (error, stdout) {
693
+ if (!error) {
694
+ const docker = stdout.toString().split('\n')[0] || '';
695
+ const parts = docker.split(' ');
696
+ appsObj.versions.docker = parts.length > 2 && parts[2].endsWith(',') ? parts[2].slice(0, -1) : '';
697
+ }
698
+ functionProcessed();
699
+ });
700
+ }
701
+ if ({}.hasOwnProperty.call(appsObj.versions, 'postfix')) {
702
+ exec('postconf -d | grep mail_version', function (error, stdout) {
703
+ if (!error) {
704
+ const postfix = stdout.toString().split('\n') || [];
705
+ appsObj.versions.postfix = util.getValue(postfix, 'mail_version', '=', true);
706
+ }
707
+ functionProcessed();
708
+ });
709
+ }
710
+ if ({}.hasOwnProperty.call(appsObj.versions, 'mongodb')) {
711
+ exec('mongod --version', function (error, stdout) {
712
+ if (!error) {
713
+ const mongodb = stdout.toString().split('\n')[0] || '';
714
+ appsObj.versions.mongodb = (mongodb.toLowerCase().split(',')[0] || '').replace(/[^0-9.]/g, '');
715
+ }
716
+ functionProcessed();
717
+ });
718
+ }
719
+ if ({}.hasOwnProperty.call(appsObj.versions, 'postgresql')) {
720
+ if (_linux) {
721
+ exec('locate bin/postgres', function (error, stdout) {
722
+ if (!error) {
723
+ const postgresqlBin = stdout.toString().split('\n').sort();
724
+ if (postgresqlBin.length) {
725
+ exec(postgresqlBin[postgresqlBin.length - 1] + ' -V', function (error, stdout) {
726
+ if (!error) {
727
+ const postgresql = stdout.toString().split('\n')[0].split(' ') || [];
728
+ appsObj.versions.postgresql = postgresql.length ? postgresql[postgresql.length - 1] : '';
729
+ }
730
+ functionProcessed();
731
+ });
732
+ } else {
733
+ functionProcessed();
734
+ }
735
+ } else {
736
+ exec('psql -V', function (error, stdout) {
737
+ if (!error) {
738
+ const postgresql = stdout.toString().split('\n')[0].split(' ') || [];
739
+ appsObj.versions.postgresql = postgresql.length ? postgresql[postgresql.length - 1] : '';
740
+ appsObj.versions.postgresql = appsObj.versions.postgresql.split('-')[0];
741
+ }
742
+ functionProcessed();
743
+ });
744
+ }
745
+ });
746
+ } else {
747
+ if (_windows) {
748
+ util.powerShell('Get-CimInstance Win32_Service | select caption | fl').then((stdout) => {
749
+ let serviceSections = stdout.split(/\n\s*\n/);
750
+ serviceSections.forEach((item) => {
751
+ if (item.trim() !== '') {
752
+ let lines = item.trim().split('\r\n');
753
+ let srvCaption = util.getValue(lines, 'caption', ':', true).toLowerCase();
754
+ if (srvCaption.indexOf('postgresql') > -1) {
755
+ const parts = srvCaption.split(' server ');
756
+ if (parts.length > 1) {
757
+ appsObj.versions.postgresql = parts[1];
758
+ }
759
+ }
760
+ }
761
+ });
762
+ functionProcessed();
763
+ });
764
+ } else {
765
+ exec('postgres -V', function (error, stdout) {
766
+ if (!error) {
767
+ const postgresql = stdout.toString().split('\n')[0].split(' ') || [];
768
+ appsObj.versions.postgresql = postgresql.length ? postgresql[postgresql.length - 1] : '';
769
+ }
770
+ functionProcessed();
771
+ });
772
+ }
773
+ }
774
+ }
775
+ if ({}.hasOwnProperty.call(appsObj.versions, 'perl')) {
776
+ exec('perl -v', function (error, stdout) {
777
+ if (!error) {
778
+ const perl = stdout.toString().split('\n') || '';
779
+ while (perl.length > 0 && perl[0].trim() === '') {
780
+ perl.shift();
781
+ }
782
+ if (perl.length > 0) {
783
+ appsObj.versions.perl = perl[0].split('(').pop().split(')')[0].replace('v', '');
784
+ }
785
+ }
786
+ functionProcessed();
787
+ });
788
+ }
789
+ if ({}.hasOwnProperty.call(appsObj.versions, 'python')) {
790
+ if (_darwin) {
791
+ const stdout = execSync('sw_vers');
792
+ const lines = stdout.toString().split('\n');
793
+ const osVersion = util.getValue(lines, 'ProductVersion', ':');
794
+ const gitHomebrewExists1 = fs.existsSync('/usr/local/Cellar/python');
795
+ const gitHomebrewExists2 = fs.existsSync('/opt/homebrew/bin/python');
796
+ if ((util.darwinXcodeExists() && util.semverCompare('12.0.1', osVersion) < 0) || gitHomebrewExists1 || gitHomebrewExists2) {
797
+ const cmd = gitHomebrewExists1 ? '/usr/local/Cellar/python -V 2>&1' : (gitHomebrewExists2 ? '/opt/homebrew/bin/python -V 2>&1' : 'python -V 2>&1');
798
+ exec(cmd, function (error, stdout) {
799
+ if (!error) {
800
+ const python = stdout.toString().split('\n')[0] || '';
801
+ appsObj.versions.python = python.toLowerCase().replace('python', '').trim();
802
+ }
803
+ functionProcessed();
804
+ });
805
+ } else {
806
+ functionProcessed();
807
+ }
808
+ } else {
809
+ exec('python -V 2>&1', function (error, stdout) {
810
+ if (!error) {
811
+ const python = stdout.toString().split('\n')[0] || '';
812
+ appsObj.versions.python = python.toLowerCase().replace('python', '').trim();
813
+ }
814
+ functionProcessed();
815
+ });
816
+ }
817
+ }
818
+ if ({}.hasOwnProperty.call(appsObj.versions, 'python3')) {
819
+ if (_darwin) {
820
+ const gitHomebrewExists = fs.existsSync('/usr/local/Cellar/python3') || fs.existsSync('/opt/homebrew/bin/python3');
821
+ if (util.darwinXcodeExists() || gitHomebrewExists) {
822
+ exec('python3 -V 2>&1', function (error, stdout) {
823
+ if (!error) {
824
+ const python = stdout.toString().split('\n')[0] || '';
825
+ appsObj.versions.python3 = python.toLowerCase().replace('python', '').trim();
826
+ }
827
+ functionProcessed();
828
+ });
829
+ } else {
830
+ functionProcessed();
831
+ }
832
+ } else {
833
+ exec('python3 -V 2>&1', function (error, stdout) {
834
+ if (!error) {
835
+ const python = stdout.toString().split('\n')[0] || '';
836
+ appsObj.versions.python3 = python.toLowerCase().replace('python', '').trim();
837
+ }
838
+ functionProcessed();
839
+ });
840
+ }
841
+ }
842
+ if ({}.hasOwnProperty.call(appsObj.versions, 'pip')) {
843
+ if (_darwin) {
844
+ const gitHomebrewExists = fs.existsSync('/usr/local/Cellar/pip') || fs.existsSync('/opt/homebrew/bin/pip');
845
+ if (util.darwinXcodeExists() || gitHomebrewExists) {
846
+ exec('pip -V 2>&1', function (error, stdout) {
847
+ if (!error) {
848
+ const pip = stdout.toString().split('\n')[0] || '';
849
+ const parts = pip.split(' ');
850
+ appsObj.versions.pip = parts.length >= 2 ? parts[1] : '';
851
+ }
852
+ functionProcessed();
853
+ });
854
+ } else {
855
+ functionProcessed();
856
+ }
857
+ } else {
858
+ exec('pip -V 2>&1', function (error, stdout) {
859
+ if (!error) {
860
+ const pip = stdout.toString().split('\n')[0] || '';
861
+ const parts = pip.split(' ');
862
+ appsObj.versions.pip = parts.length >= 2 ? parts[1] : '';
863
+ }
864
+ functionProcessed();
865
+ });
866
+ }
867
+ }
868
+ if ({}.hasOwnProperty.call(appsObj.versions, 'pip3')) {
869
+ if (_darwin) {
870
+ const gitHomebrewExists = fs.existsSync('/usr/local/Cellar/pip3') || fs.existsSync('/opt/homebrew/bin/pip3');
871
+ if (util.darwinXcodeExists() || gitHomebrewExists) {
872
+ exec('pip3 -V 2>&1', function (error, stdout) {
873
+ if (!error) {
874
+ const pip = stdout.toString().split('\n')[0] || '';
875
+ const parts = pip.split(' ');
876
+ appsObj.versions.pip3 = parts.length >= 2 ? parts[1] : '';
877
+ }
878
+ functionProcessed();
879
+ });
880
+ } else {
881
+ functionProcessed();
882
+ }
883
+ } else {
884
+ exec('pip3 -V 2>&1', function (error, stdout) {
885
+ if (!error) {
886
+ const pip = stdout.toString().split('\n')[0] || '';
887
+ const parts = pip.split(' ');
888
+ appsObj.versions.pip3 = parts.length >= 2 ? parts[1] : '';
889
+ }
890
+ functionProcessed();
891
+ });
892
+ }
893
+ }
894
+ if ({}.hasOwnProperty.call(appsObj.versions, 'java')) {
895
+ if (_darwin) {
896
+ // check if any JVM is installed but avoid dialog box that Java needs to be installed
897
+ exec('/usr/libexec/java_home -V 2>&1', function (error, stdout) {
898
+ if (!error && stdout.toString().toLowerCase().indexOf('no java runtime') === -1) {
899
+ // now this can be done savely
900
+ exec('java -version 2>&1', function (error, stdout) {
901
+ if (!error) {
902
+ const java = stdout.toString().split('\n')[0] || '';
903
+ const parts = java.split('"');
904
+ appsObj.versions.java = parts.length === 3 ? parts[1].trim() : '';
905
+ }
906
+ functionProcessed();
907
+ });
908
+ } else {
909
+ functionProcessed();
910
+ }
911
+ });
912
+ } else {
913
+ exec('java -version 2>&1', function (error, stdout) {
914
+ if (!error) {
915
+ const java = stdout.toString().split('\n')[0] || '';
916
+ const parts = java.split('"');
917
+ appsObj.versions.java = parts.length === 3 ? parts[1].trim() : '';
918
+ }
919
+ functionProcessed();
920
+ });
921
+ }
922
+ }
923
+ if ({}.hasOwnProperty.call(appsObj.versions, 'gcc')) {
924
+ if ((_darwin && util.darwinXcodeExists()) || !_darwin) {
925
+ exec('gcc -dumpversion', function (error, stdout) {
926
+ if (!error) {
927
+ appsObj.versions.gcc = stdout.toString().split('\n')[0].trim() || '';
928
+ }
929
+ if (appsObj.versions.gcc.indexOf('.') > -1) {
930
+ functionProcessed();
931
+ } else {
932
+ exec('gcc --version', function (error, stdout) {
933
+ if (!error) {
934
+ const gcc = stdout.toString().split('\n')[0].trim();
935
+ if (gcc.indexOf('gcc') > -1 && gcc.indexOf(')') > -1) {
936
+ const parts = gcc.split(')');
937
+ appsObj.versions.gcc = parts[1].trim() || appsObj.versions.gcc;
938
+ }
939
+ }
940
+ functionProcessed();
941
+ });
942
+ }
943
+ });
944
+ } else {
945
+ functionProcessed();
946
+ }
947
+ }
948
+ if ({}.hasOwnProperty.call(appsObj.versions, 'virtualbox')) {
949
+ exec(util.getVboxmanage() + ' -v 2>&1', function (error, stdout) {
950
+ if (!error) {
951
+ const vbox = stdout.toString().split('\n')[0] || '';
952
+ const parts = vbox.split('r');
953
+ appsObj.versions.virtualbox = parts[0];
954
+ }
955
+ functionProcessed();
956
+ });
957
+ }
958
+ if ({}.hasOwnProperty.call(appsObj.versions, 'bash')) {
959
+ exec('bash --version', function (error, stdout) {
960
+ if (!error) {
961
+ const line = stdout.toString().split('\n')[0];
962
+ const parts = line.split(' version ');
963
+ if (parts.length > 1) {
964
+ appsObj.versions.bash = parts[1].split(' ')[0].split('(')[0];
965
+ }
966
+ }
967
+ functionProcessed();
968
+ });
969
+ }
970
+ if ({}.hasOwnProperty.call(appsObj.versions, 'zsh')) {
971
+ exec('zsh --version', function (error, stdout) {
972
+ if (!error) {
973
+ const line = stdout.toString().split('\n')[0];
974
+ const parts = line.split('zsh ');
975
+ if (parts.length > 1) {
976
+ appsObj.versions.zsh = parts[1].split(' ')[0];
977
+ }
978
+ }
979
+ functionProcessed();
980
+ });
981
+ }
982
+ if ({}.hasOwnProperty.call(appsObj.versions, 'fish')) {
983
+ exec('fish --version', function (error, stdout) {
984
+ if (!error) {
985
+ const line = stdout.toString().split('\n')[0];
986
+ const parts = line.split(' version ');
987
+ if (parts.length > 1) {
988
+ appsObj.versions.fish = parts[1].split(' ')[0];
989
+ }
990
+ }
991
+ functionProcessed();
992
+ });
993
+ }
994
+ if ({}.hasOwnProperty.call(appsObj.versions, 'powershell')) {
995
+ if (_windows) {
996
+ util.powerShell('$PSVersionTable').then(stdout => {
997
+ const lines = stdout.toString().split('\n').map(line => line.replace(/ +/g, ' ').replace(/ +/g, ':'));
998
+ appsObj.versions.powershell = util.getValue(lines, 'psversion');
999
+ functionProcessed();
1000
+ });
1001
+ } else {
1002
+ functionProcessed();
1003
+ }
1004
+ }
1005
+ if ({}.hasOwnProperty.call(appsObj.versions, 'dotnet')) {
1006
+ if (_windows) {
1007
+ util.powerShell('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').then(stdout => {
1008
+ const lines = stdout.toString().split('\r\n');
1009
+ let dotnet = '';
1010
+ lines.forEach(line => {
1011
+ line = line.replace(/ +/g, ' ');
1012
+ const parts = line.split(' ');
1013
+ dotnet = dotnet || (parts[0].toLowerCase().startsWith('client') && parts.length > 2 ? parts[1].trim() : (parts[0].toLowerCase().startsWith('full') && parts.length > 2 ? parts[1].trim() : ''));
1014
+ });
1015
+ appsObj.versions.dotnet = dotnet.trim();
1016
+ functionProcessed();
1017
+ });
1018
+ } else {
1019
+ functionProcessed();
1020
+ }
1021
+ }
1022
+ } catch (e) {
1023
+ if (callback) { callback(appsObj.versions); }
1024
+ resolve(appsObj.versions);
1025
+ }
1026
+ });
1027
+ });
1028
+ }
1029
+
1030
+ exports.versions = versions;
1031
+
1032
+ function shell(callback) {
1033
+ return new Promise((resolve) => {
1034
+ process.nextTick(() => {
1035
+ if (_windows) {
1036
+ resolve('cmd');
1037
+ } else {
1038
+ let result = '';
1039
+ exec('echo $SHELL', function (error, stdout) {
1040
+ if (!error) {
1041
+ result = stdout.toString().split('\n')[0];
1042
+ }
1043
+ if (callback) {
1044
+ callback(result);
1045
+ }
1046
+ resolve(result);
1047
+ });
1048
+ }
1049
+ });
1050
+ });
1051
+ }
1052
+
1053
+ exports.shell = shell;
1054
+
1055
+ function getUniqueMacAdresses() {
1056
+ let macs = [];
1057
+ try {
1058
+ const ifaces = os.networkInterfaces();
1059
+ for (let dev in ifaces) {
1060
+ if ({}.hasOwnProperty.call(ifaces, dev)) {
1061
+ ifaces[dev].forEach(function (details) {
1062
+ if (details && details.mac && details.mac !== '00:00:00:00:00:00') {
1063
+ const mac = details.mac.toLowerCase();
1064
+ if (macs.indexOf(mac) === -1) {
1065
+ macs.push(mac);
1066
+ }
1067
+ }
1068
+ });
1069
+ }
1070
+ }
1071
+ macs = macs.sort(function (a, b) {
1072
+ if (a < b) { return -1; }
1073
+ if (a > b) { return 1; }
1074
+ return 0;
1075
+ });
1076
+ } catch (e) {
1077
+ macs.push('00:00:00:00:00:00');
1078
+ }
1079
+ return macs;
1080
+ }
1081
+
1082
+ function uuid(callback) {
1083
+ return new Promise((resolve) => {
1084
+ process.nextTick(() => {
1085
+
1086
+ let result = {
1087
+ os: '',
1088
+ hardware: '',
1089
+ macs: getUniqueMacAdresses()
1090
+ };
1091
+ let parts;
1092
+
1093
+ if (_darwin) {
1094
+ exec('system_profiler SPHardwareDataType -json', function (error, stdout) {
1095
+ if (!error) {
1096
+ try {
1097
+ const jsonObj = JSON.parse(stdout.toString());
1098
+ if (jsonObj.SPHardwareDataType && jsonObj.SPHardwareDataType.length > 0) {
1099
+ const spHardware = jsonObj.SPHardwareDataType[0];
1100
+ result.os = spHardware.platform_UUID.toLowerCase();
1101
+ result.hardware = spHardware.serial_number;
1102
+ }
1103
+ } catch (e) {
1104
+ util.noop();
1105
+ }
1106
+ }
1107
+ if (callback) {
1108
+ callback(result);
1109
+ }
1110
+ resolve(result);
1111
+ });
1112
+ }
1113
+ if (_linux) {
1114
+ const cmd = `echo -n "os: "; cat /var/lib/dbus/machine-id 2> /dev/null; echo;
1115
+ echo -n "os: "; cat /etc/machine-id 2> /dev/null; echo;
1116
+ echo -n "hardware: "; cat /sys/class/dmi/id/product_uuid 2> /dev/null; echo;`;
1117
+ exec(cmd, function (error, stdout) {
1118
+ const lines = stdout.toString().split('\n');
1119
+ result.os = util.getValue(lines, 'os').toLowerCase();
1120
+ result.hardware = util.getValue(lines, 'hardware').toLowerCase();
1121
+ if (!result.hardware) {
1122
+ const lines = fs.readFileSync('/proc/cpuinfo', { encoding: 'utf8' }).toString().split('\n');
1123
+ const serial = util.getValue(lines, 'serial');
1124
+ result.hardware = serial || '';
1125
+ }
1126
+ if (callback) {
1127
+ callback(result);
1128
+ }
1129
+ resolve(result);
1130
+ });
1131
+ }
1132
+ if (_freebsd || _openbsd || _netbsd) {
1133
+ exec('sysctl -i kern.hostid kern.hostuuid', function (error, stdout) {
1134
+ const lines = stdout.toString().split('\n');
1135
+ result.os = util.getValue(lines, 'kern.hostid', ':').toLowerCase();
1136
+ result.hardware = util.getValue(lines, 'kern.hostuuid', ':').toLowerCase();
1137
+ if (result.os.indexOf('unknown') >= 0) { result.os = ''; }
1138
+ if (result.hardware.indexOf('unknown') >= 0) { result.hardware = ''; }
1139
+ if (callback) {
1140
+ callback(result);
1141
+ }
1142
+ resolve(result);
1143
+ });
1144
+ }
1145
+ if (_windows) {
1146
+ let sysdir = '%windir%\\System32';
1147
+ if (process.arch === 'ia32' && Object.prototype.hasOwnProperty.call(process.env, 'PROCESSOR_ARCHITEW6432')) {
1148
+ sysdir = '%windir%\\sysnative\\cmd.exe /c %windir%\\System32';
1149
+ }
1150
+ util.powerShell('Get-CimInstance Win32_ComputerSystemProduct | select UUID | fl').then((stdout) => {
1151
+ let lines = stdout.split('\r\n');
1152
+ result.hardware = util.getValue(lines, 'uuid', ':').toLowerCase();
1153
+ exec(`${sysdir}\\reg query "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography" /v MachineGuid`, util.execOptsWin, function (error, stdout) {
1154
+ parts = stdout.toString().split('\n\r')[0].split('REG_SZ');
1155
+ result.os = parts.length > 1 ? parts[1].replace(/\r+|\n+|\s+/ig, '').toLowerCase() : '';
1156
+ if (callback) {
1157
+ callback(result);
1158
+ }
1159
+ resolve(result);
1160
+ });
1161
+ });
1162
+ }
1163
+ });
1164
+ });
1165
+ }
1166
+
1167
+ exports.uuid = uuid;