UNPKG

32.5 kBJavaScriptView Raw
1'use strict';
2// @ts-check
3// ==================================================================================
4// osinfo.js
5// ----------------------------------------------------------------------------------
6// Description: System Information - library
7// for Node.js
8// Copyright: (c) 2014 - 2020
9// Author: Sebastian Hildebrandt
10// ----------------------------------------------------------------------------------
11// License: MIT
12// ==================================================================================
13// 3. Operating System
14// ----------------------------------------------------------------------------------
15
16const os = require('os');
17const exec = require('child_process').exec;
18const util = require('./util');
19const fs = require('fs');
20
21let _platform = process.platform;
22
23const _linux = (_platform === 'linux');
24const _darwin = (_platform === 'darwin');
25const _windows = (_platform === 'win32');
26const _freebsd = (_platform === 'freebsd');
27const _openbsd = (_platform === 'openbsd');
28const _netbsd = (_platform === 'netbsd');
29const _sunos = (_platform === 'sunos');
30
31const NOT_SUPPORTED = 'not supported';
32
33// --------------------------
34// Get current time and OS uptime
35
36function time() {
37 let t = new Date().toString().split(' ');
38
39 return {
40 current: Date.now(),
41 uptime: os.uptime(),
42 timezone: (t.length >= 7) ? t[5] : '',
43 timezoneName: (t.length >= 7) ? t.slice(6).join(' ').replace(/\(/g, '').replace(/\)/g, '') : ''
44 };
45}
46
47exports.time = time;
48
49// --------------------------
50// Get logo filename of OS distribution
51
52function getLogoFile(distro) {
53 distro = distro || '';
54 distro = distro.toLowerCase();
55 let result = _platform;
56 if (_windows) {
57 result = 'windows';
58 }
59 else if (distro.indexOf('mac os') !== -1) {
60 result = 'apple';
61 }
62 else if (distro.indexOf('arch') !== -1) {
63 result = 'arch';
64 }
65 else if (distro.indexOf('centos') !== -1) {
66 result = 'centos';
67 }
68 else if (distro.indexOf('coreos') !== -1) {
69 result = 'coreos';
70 }
71 else if (distro.indexOf('debian') !== -1) {
72 result = 'debian';
73 }
74 else if (distro.indexOf('deepin') !== -1) {
75 result = 'deepin';
76 }
77 else if (distro.indexOf('elementary') !== -1) {
78 result = 'elementary';
79 }
80 else if (distro.indexOf('fedora') !== -1) {
81 result = 'fedora';
82 }
83 else if (distro.indexOf('gentoo') !== -1) {
84 result = 'gentoo';
85 }
86 else if (distro.indexOf('mageia') !== -1) {
87 result = 'mageia';
88 }
89 else if (distro.indexOf('mandriva') !== -1) {
90 result = 'mandriva';
91 }
92 else if (distro.indexOf('manjaro') !== -1) {
93 result = 'manjaro';
94 }
95 else if (distro.indexOf('mint') !== -1) {
96 result = 'mint';
97 }
98 else if (distro.indexOf('mx') !== -1) {
99 result = 'mx';
100 }
101 else if (distro.indexOf('openbsd') !== -1) {
102 result = 'openbsd';
103 }
104 else if (distro.indexOf('freebsd') !== -1) {
105 result = 'freebsd';
106 }
107 else if (distro.indexOf('opensuse') !== -1) {
108 result = 'opensuse';
109 }
110 else if (distro.indexOf('pclinuxos') !== -1) {
111 result = 'pclinuxos';
112 }
113 else if (distro.indexOf('puppy') !== -1) {
114 result = 'puppy';
115 }
116 else if (distro.indexOf('raspbian') !== -1) {
117 result = 'raspbian';
118 }
119 else if (distro.indexOf('reactos') !== -1) {
120 result = 'reactos';
121 }
122 else if (distro.indexOf('redhat') !== -1) {
123 result = 'redhat';
124 }
125 else if (distro.indexOf('slackware') !== -1) {
126 result = 'slackware';
127 }
128 else if (distro.indexOf('sugar') !== -1) {
129 result = 'sugar';
130 }
131 else if (distro.indexOf('steam') !== -1) {
132 result = 'steam';
133 }
134 else if (distro.indexOf('suse') !== -1) {
135 result = 'suse';
136 }
137 else if (distro.indexOf('mate') !== -1) {
138 result = 'ubuntu-mate';
139 }
140 else if (distro.indexOf('lubuntu') !== -1) {
141 result = 'lubuntu';
142 }
143 else if (distro.indexOf('xubuntu') !== -1) {
144 result = 'xubuntu';
145 }
146 else if (distro.indexOf('ubuntu') !== -1) {
147 result = 'ubuntu';
148 }
149 else if (distro.indexOf('solaris') !== -1) {
150 result = 'solaris';
151 }
152 else if (distro.indexOf('tails') !== -1) {
153 result = 'tails';
154 }
155 else if (distro.indexOf('robolinux') !== -1) {
156 result = 'robolinux';
157 } else if (_linux && distro) {
158 result = distro.toLowerCase().trim().replace(/\s+/g, '-');
159 }
160 return result;
161}
162
163// --------------------------
164// OS Information
165
166function osInfo(callback) {
167
168 return new Promise((resolve) => {
169 process.nextTick(() => {
170 let result = {
171
172 platform: (_platform === 'Windows_NT' ? 'Windows' : _platform),
173 distro: 'unknown',
174 release: 'unknown',
175 codename: '',
176 kernel: os.release(),
177 arch: os.arch(),
178 hostname: os.hostname(),
179 codepage: '',
180 logofile: '',
181 serial: '',
182 build: '',
183 servicepack: '',
184 uefi: false
185 };
186
187 if (_linux) {
188
189 exec('cat /etc/*-release; cat /usr/lib/os-release; cat /etc/openwrt_release', function (error, stdout) {
190 //if (!error) {
191 /**
192 * @namespace
193 * @property {string} DISTRIB_ID
194 * @property {string} NAME
195 * @property {string} DISTRIB_RELEASE
196 * @property {string} VERSION_ID
197 * @property {string} DISTRIB_CODENAME
198 */
199 let release = {};
200 let lines = stdout.toString().split('\n');
201 lines.forEach(function (line) {
202 if (line.indexOf('=') !== -1) {
203 release[line.split('=')[0].trim().toUpperCase()] = line.split('=')[1].trim();
204 }
205 });
206 let releaseVersion = (release.VERSION || '').replace(/"/g, '');
207 let codename = (release.DISTRIB_CODENAME || release.VERSION_CODENAME || '').replace(/"/g, '');
208 if (releaseVersion.indexOf('(') >= 0) {
209 codename = releaseVersion.split('(')[1].replace(/[()]/g, '').trim();
210 releaseVersion = releaseVersion.split('(')[0].trim();
211 }
212 result.distro = (release.DISTRIB_ID || release.NAME || 'unknown').replace(/"/g, '');
213 result.logofile = getLogoFile(result.distro);
214 result.release = (releaseVersion || release.DISTRIB_RELEASE || release.VERSION_ID || 'unknown').replace(/"/g, '');
215 result.codename = codename;
216 result.codepage = util.getCodepage();
217 result.build = (release.BUILD_ID || '').replace(/"/g, '').trim();
218 isUefiLinux().then(uefi => {
219 result.uefi = uefi;
220 uuid().then(data => {
221 result.serial = data.os;
222 if (callback) {
223 callback(result);
224 }
225 resolve(result);
226 });
227 });
228 //}
229 });
230 }
231 if (_freebsd || _openbsd || _netbsd) {
232
233 exec('sysctl kern.ostype kern.osrelease kern.osrevision kern.hostuuid machdep.bootmethod', function (error, stdout) {
234 if (!error) {
235 let lines = stdout.toString().split('\n');
236 result.distro = util.getValue(lines, 'kern.ostype');
237 result.logofile = getLogoFile(result.distro);
238 result.release = util.getValue(lines, 'kern.osrelease').split('-')[0];
239 result.serial = util.getValue(lines, 'kern.uuid');
240 result.codename = '';
241 result.codepage = util.getCodepage();
242 result.uefi = util.getValue(lines, 'machdep.bootmethod').toLowerCase().indexOf('uefi') >= 0;
243 }
244 if (callback) {
245 callback(result);
246 }
247 resolve(result);
248 });
249 }
250 if (_darwin) {
251 exec('sw_vers; sysctl kern.ostype kern.osrelease kern.osrevision kern.uuid', function (error, stdout) {
252 let lines = stdout.toString().split('\n');
253 result.serial = util.getValue(lines, 'kern.uuid');
254 result.distro = util.getValue(lines, 'ProductName');
255 result.release = util.getValue(lines, 'ProductVersion');
256 result.build = util.getValue(lines, 'BuildVersion');
257 result.logofile = getLogoFile(result.distro);
258 result.codename = 'macOS';
259 result.codename = (result.release.indexOf('10.4') > -1 ? 'Mac OS X Tiger' : result.codename);
260 result.codename = (result.release.indexOf('10.4') > -1 ? 'Mac OS X Tiger' : result.codename);
261 result.codename = (result.release.indexOf('10.4') > -1 ? 'Mac OS X Tiger' : result.codename);
262 result.codename = (result.release.indexOf('10.5') > -1 ? 'Mac OS X Leopard' : result.codename);
263 result.codename = (result.release.indexOf('10.6') > -1 ? 'Mac OS X Snow Leopard' : result.codename);
264 result.codename = (result.release.indexOf('10.7') > -1 ? 'Mac OS X Lion' : result.codename);
265 result.codename = (result.release.indexOf('10.8') > -1 ? 'OS X Mountain Lion' : result.codename);
266 result.codename = (result.release.indexOf('10.9') > -1 ? 'OS X Mavericks' : result.codename);
267 result.codename = (result.release.indexOf('10.10') > -1 ? 'OS X Yosemite' : result.codename);
268 result.codename = (result.release.indexOf('10.11') > -1 ? 'OS X El Capitan' : result.codename);
269 result.codename = (result.release.indexOf('10.12') > -1 ? 'macOS Sierra' : result.codename);
270 result.codename = (result.release.indexOf('10.13') > -1 ? 'macOS High Sierra' : result.codename);
271 result.codename = (result.release.indexOf('10.14') > -1 ? 'macOS Mojave' : result.codename);
272 result.codename = (result.release.indexOf('10.15') > -1 ? 'macOS Catalina' : result.codename);
273 result.uefi = true;
274 result.codepage = util.getCodepage();
275 if (callback) {
276 callback(result);
277 }
278 resolve(result);
279 });
280 }
281 if (_sunos) {
282 result.release = result.kernel;
283 exec('uname -o', function (error, stdout) {
284 let lines = stdout.toString().split('\n');
285 result.distro = lines[0];
286 result.logofile = getLogoFile(result.distro);
287 if (callback) { callback(result); }
288 resolve(result);
289 });
290 }
291 if (_windows) {
292 result.logofile = getLogoFile();
293 result.release = result.kernel;
294 try {
295 util.wmic('os get /value').then((stdout) => {
296 let lines = stdout.toString().split('\r\n');
297 result.distro = util.getValue(lines, 'Caption', '=').trim();
298 result.serial = util.getValue(lines, 'SerialNumber', '=').trim();
299 result.build = util.getValue(lines, 'BuildNumber', '=').trim();
300 result.servicepack = util.getValue(lines, 'ServicePackMajorVersion', '=').trim() + '.' + util.getValue(lines, 'ServicePackMinorVersion', '=').trim();
301 result.codepage = util.getCodepage();
302 isUefiWindows().then(uefi => {
303 result.uefi = uefi;
304 if (callback) {
305 callback(result);
306 }
307 resolve(result);
308 });
309 });
310 } catch (e) {
311 if (callback) { callback(result); }
312 resolve(result);
313 }
314 }
315 });
316 });
317}
318
319exports.osInfo = osInfo;
320
321function isUefiLinux() {
322 return new Promise((resolve) => {
323 process.nextTick(() => {
324 fs.stat('/sys/firmware/efi', function (err) {
325 if (!err) {
326 resolve(true);
327 } else {
328 resolve(false);
329 }
330 });
331 });
332 });
333}
334
335function isUefiWindows() {
336 return new Promise((resolve) => {
337 process.nextTick(() => {
338 try {
339 exec('findstr /C:"Detected boot environment" "%windir%\\Panther\\setupact.log"', util.execOptsWin, function (error, stdout) {
340 if (!error) {
341 const line = stdout.toString().split('\n\r')[0];
342 resolve(line.toLowerCase().indexOf('uefi') >= 0);
343 return;
344 }
345 resolve(false);
346 });
347 } catch (e) {
348 resolve(false);
349 }
350 });
351 });
352}
353
354function versions(apps, callback) {
355 let versionObject = {
356 kernel: os.release(),
357 openssl: '',
358 systemOpenssl: '',
359 systemOpensslLib: '',
360 node: process.versions.node,
361 v8: process.versions.v8,
362 npm: '',
363 yarn: '',
364 pm2: '',
365 gulp: '',
366 grunt: '',
367 git: '',
368 tsc: '',
369 mysql: '',
370 redis: '',
371 mongodb: '',
372 apache: '',
373 nginx: '',
374 php: '',
375 docker: '',
376 postfix: '',
377 postgresql: '',
378 perl: '',
379 python: '',
380 python3: '',
381 pip: '',
382 pip3: '',
383 java: '',
384 gcc: '',
385 virtualbox: '',
386 dotnet: ''
387 };
388
389 function checkVersionParam(apps) {
390 if (apps === '*') {
391 return {
392 versions: versionObject,
393 counter: 26
394 };
395 }
396 if (!Array.isArray(apps)) {
397 apps = apps.trim().toLowerCase().replace(/,+/g, '|').replace(/ /g, '|');
398 apps = apps.split('|');
399 const result = {
400 versions: {},
401 counter: 0
402 };
403 apps.forEach(el => {
404 if (el) {
405 for (let key in versionObject) {
406 if ({}.hasOwnProperty.call(versionObject, key)) {
407 if (key.toLowerCase() === el.toLowerCase() && !{}.hasOwnProperty.call(result.versions, key)) {
408 result.versions[key] = versionObject[key];
409 if (key === 'openssl') {
410 result.versions.systemOpenssl = '';
411 result.versions.systemOpensslLib = '';
412 }
413
414 if (!result.versions[key]) { result.counter++; }
415 }
416 }
417 }
418 }
419 });
420 return result;
421 }
422 }
423
424 return new Promise((resolve) => {
425 process.nextTick(() => {
426 if (util.isFunction(apps) && !callback) {
427 callback = apps;
428 apps = '*';
429 } else {
430 apps = apps || '*';
431 }
432 const appsObj = checkVersionParam(apps);
433 let totalFunctions = appsObj.counter;
434
435 let functionProcessed = (function () {
436 return function () {
437 if (--totalFunctions === 0) {
438 if (callback) {
439 callback(appsObj.versions);
440 }
441 resolve(appsObj.versions);
442 }
443 };
444 })();
445
446 let cmd = '';
447 try {
448 if ({}.hasOwnProperty.call(appsObj.versions, 'openssl')) {
449 appsObj.versions.openssl = process.versions.openssl;
450 exec('openssl version', function (error, stdout) {
451 if (!error) {
452 let openssl_string = stdout.toString().split('\n')[0].trim();
453 let openssl = openssl_string.split(' ');
454 appsObj.versions.systemOpenssl = openssl.length > 0 ? openssl[1] : openssl[0];
455 appsObj.versions.systemOpensslLib = openssl.length > 0 ? openssl[0] : 'openssl';
456 }
457 functionProcessed();
458 });
459 }
460 if ({}.hasOwnProperty.call(appsObj.versions, 'npm')) {
461 exec('npm -v', function (error, stdout) {
462 if (!error) {
463 appsObj.versions.npm = stdout.toString().split('\n')[0];
464 }
465 functionProcessed();
466 });
467 }
468 if ({}.hasOwnProperty.call(appsObj.versions, 'pm2')) {
469 cmd = 'pm2';
470 if (_windows) {
471 cmd += '.cmd';
472 }
473 exec(`${cmd} -v`, function (error, stdout) {
474 if (!error) {
475 let pm2 = stdout.toString().split('\n')[0].trim();
476 if (!pm2.startsWith('[PM2]')) {
477 appsObj.versions.pm2 = pm2;
478 }
479 }
480 functionProcessed();
481 });
482 }
483 if ({}.hasOwnProperty.call(appsObj.versions, 'yarn')) {
484 exec('yarn --version', function (error, stdout) {
485 if (!error) {
486 appsObj.versions.yarn = stdout.toString().split('\n')[0];
487 }
488 functionProcessed();
489 });
490 }
491 if ({}.hasOwnProperty.call(appsObj.versions, 'gulp')) {
492 cmd = 'gulp';
493 if (_windows) {
494 cmd += '.cmd';
495 }
496 exec(`${cmd} --version`, function (error, stdout) {
497 if (!error) {
498 const gulp = stdout.toString().split('\n')[0] || '';
499 appsObj.versions.gulp = (gulp.toLowerCase().split('version')[1] || '').trim();
500 }
501 functionProcessed();
502 });
503 }
504 if ({}.hasOwnProperty.call(appsObj.versions, 'tsc')) {
505 cmd = 'tsc';
506 if (_windows) {
507 cmd += '.cmd';
508 }
509 exec(`${cmd} --version`, function (error, stdout) {
510 if (!error) {
511 const tsc = stdout.toString().split('\n')[0] || '';
512 appsObj.versions.tsc = (tsc.toLowerCase().split('version')[1] || '').trim();
513 }
514 functionProcessed();
515 });
516 }
517 if ({}.hasOwnProperty.call(appsObj.versions, 'grunt')) {
518 cmd = 'grunt';
519 if (_windows) {
520 cmd += '.cmd';
521 }
522 exec(`${cmd} --version`, function (error, stdout) {
523 if (!error) {
524 const grunt = stdout.toString().split('\n')[0] || '';
525 appsObj.versions.grunt = (grunt.toLowerCase().split('cli v')[1] || '').trim();
526 }
527 functionProcessed();
528 });
529 }
530 if ({}.hasOwnProperty.call(appsObj.versions, 'git')) {
531 if (_darwin) {
532 const gitHomebrewExists = fs.existsSync('/usr/local/Cellar/git');
533 if (util.darwinXcodeExists() || gitHomebrewExists) {
534 exec('git --version', function (error, stdout) {
535 if (!error) {
536 let git = stdout.toString().split('\n')[0] || '';
537 git = (git.toLowerCase().split('version')[1] || '').trim();
538 appsObj.versions.git = (git.split(' ')[0] || '').trim();
539 }
540 functionProcessed();
541 });
542 } else {
543 functionProcessed();
544 }
545 } else {
546 exec('git --version', function (error, stdout) {
547 if (!error) {
548 let git = stdout.toString().split('\n')[0] || '';
549 git = (git.toLowerCase().split('version')[1] || '').trim();
550 appsObj.versions.git = (git.split(' ')[0] || '').trim();
551 }
552 functionProcessed();
553 });
554 }
555 }
556 if ({}.hasOwnProperty.call(appsObj.versions, 'apache')) {
557 exec('apachectl -v 2>&1', function (error, stdout) {
558 if (!error) {
559 const apache = (stdout.toString().split('\n')[0] || '').split(':');
560 appsObj.versions.apache = (apache.length > 1 ? apache[1].replace('Apache', '').replace('/', '').trim() : '');
561 }
562 functionProcessed();
563 });
564 }
565 if ({}.hasOwnProperty.call(appsObj.versions, 'nginx')) {
566 exec('nginx -v 2>&1', function (error, stdout) {
567 if (!error) {
568 const nginx = stdout.toString().split('\n')[0] || '';
569 appsObj.versions.nginx = (nginx.toLowerCase().split('/')[1] || '').trim();
570 }
571 functionProcessed();
572 });
573 }
574 if ({}.hasOwnProperty.call(appsObj.versions, 'mysql')) {
575 exec('mysql -V', function (error, stdout) {
576 if (!error) {
577 let mysql = stdout.toString().split('\n')[0] || '';
578 mysql = mysql.toLowerCase();
579 if (mysql.indexOf(',') > -1) {
580 mysql = (mysql.split(',')[0] || '').trim();
581 const parts = mysql.split(' ');
582 appsObj.versions.mysql = (parts[parts.length - 1] || '').trim();
583 } else {
584 if (mysql.indexOf(' ver ') > -1) {
585 mysql = mysql.split(' ver ')[1];
586 appsObj.versions.mysql = mysql.split(' ')[0];
587 }
588 }
589 }
590 functionProcessed();
591 });
592 }
593 if ({}.hasOwnProperty.call(appsObj.versions, 'php')) {
594 exec('php -v', function (error, stdout) {
595 if (!error) {
596 const php = stdout.toString().split('\n')[0] || '';
597 let parts = php.split('(');
598 if (parts[0].indexOf('-')) {
599 parts = parts[0].split('-');
600 }
601 appsObj.versions.php = parts[0].replace(/[^0-9.]/g, '');
602 }
603 functionProcessed();
604 });
605 }
606 if ({}.hasOwnProperty.call(appsObj.versions, 'redis')) {
607 exec('redis-server --version', function (error, stdout) {
608 if (!error) {
609 const redis = stdout.toString().split('\n')[0] || '';
610 const parts = redis.split(' ');
611 appsObj.versions.redis = util.getValue(parts, 'v', '=', true);
612 }
613 functionProcessed();
614 });
615 }
616 if ({}.hasOwnProperty.call(appsObj.versions, 'docker')) {
617 exec('docker --version', function (error, stdout) {
618 if (!error) {
619 const docker = stdout.toString().split('\n')[0] || '';
620 const parts = docker.split(' ');
621 appsObj.versions.docker = parts.length > 2 && parts[2].endsWith(',') ? parts[2].slice(0, -1) : '';
622 }
623 functionProcessed();
624 });
625 }
626 if ({}.hasOwnProperty.call(appsObj.versions, 'postfix')) {
627 exec('postconf -d | grep mail_version', function (error, stdout) {
628 if (!error) {
629 const postfix = stdout.toString().split('\n') || [];
630 appsObj.versions.postfix = util.getValue(postfix, 'mail_version', '=', true);
631 }
632 functionProcessed();
633 });
634 }
635 if ({}.hasOwnProperty.call(appsObj.versions, 'mongodb')) {
636 exec('mongod --version', function (error, stdout) {
637 if (!error) {
638 const mongodb = stdout.toString().split('\n')[0] || '';
639 appsObj.versions.mongodb = (mongodb.toLowerCase().split(',')[0] || '').replace(/[^0-9.]/g, '');
640 }
641 functionProcessed();
642 });
643 }
644 if ({}.hasOwnProperty.call(appsObj.versions, 'postgresql')) {
645 if (_linux) {
646 exec('locate bin/postgres', function (error, stdout) {
647 if (!error) {
648 const postgresqlBin = stdout.toString().split('\n').sort();
649 if (postgresqlBin.length) {
650 exec(postgresqlBin[postgresqlBin.length - 1] + ' -V', function (error, stdout) {
651 if (!error) {
652 const postgresql = stdout.toString().split('\n')[0].split(' ') || [];
653 appsObj.versions.postgresql = postgresql.length ? postgresql[postgresql.length - 1] : '';
654 }
655 functionProcessed();
656 });
657 } else {
658 functionProcessed();
659 }
660 } else {
661 exec('psql -V', function (error, stdout) {
662 if (!error) {
663 const postgresql = stdout.toString().split('\n')[0].split(' ') || [];
664 appsObj.versions.postgresql = postgresql.length ? postgresql[postgresql.length - 1] : '';
665 appsObj.versions.postgresql = appsObj.versions.postgresql.split('-')[0];
666 }
667 functionProcessed();
668 });
669 functionProcessed();
670 }
671 });
672 } else {
673 if (_windows) {
674 util.wmic('service get /value').then((stdout) => {
675 let serviceSections = stdout.split(/\n\s*\n/);
676 for (let i = 0; i < serviceSections.length; i++) {
677 if (serviceSections[i].trim() !== '') {
678 let lines = serviceSections[i].trim().split('\r\n');
679 let srvCaption = util.getValue(lines, 'caption', '=', true).toLowerCase();
680 if (srvCaption.indexOf('postgresql') > -1) {
681 const parts = srvCaption.split(' server ');
682 if (parts.length > 1) {
683 appsObj.versions.postgresql = parts[1];
684 }
685 }
686 }
687 }
688 functionProcessed();
689 });
690 } else {
691 exec('postgres -V', function (error, stdout) {
692 if (!error) {
693 const postgresql = stdout.toString().split('\n')[0].split(' ') || [];
694 appsObj.versions.postgresql = postgresql.length ? postgresql[postgresql.length - 1] : '';
695 }
696 functionProcessed();
697 });
698 }
699 }
700 }
701 if ({}.hasOwnProperty.call(appsObj.versions, 'perl')) {
702 exec('perl -v', function (error, stdout) {
703 if (!error) {
704 const perl = stdout.toString().split('\n') || '';
705 while (perl.length > 0 && perl[0].trim() === '') {
706 perl.shift();
707 }
708 if (perl.length > 0) {
709 appsObj.versions.perl = perl[0].split('(').pop().split(')')[0].replace('v', '');
710 }
711 }
712 functionProcessed();
713 });
714 }
715 if ({}.hasOwnProperty.call(appsObj.versions, 'python')) {
716 exec('python -V 2>&1', function (error, stdout) {
717 if (!error) {
718 const python = stdout.toString().split('\n')[0] || '';
719 appsObj.versions.python = python.toLowerCase().replace('python', '').trim();
720 }
721 functionProcessed();
722 });
723 }
724 if ({}.hasOwnProperty.call(appsObj.versions, 'python3')) {
725 exec('python3 -V 2>&1', function (error, stdout) {
726 if (!error) {
727 const python = stdout.toString().split('\n')[0] || '';
728 appsObj.versions.python3 = python.toLowerCase().replace('python', '').trim();
729 }
730 functionProcessed();
731 });
732 }
733 if ({}.hasOwnProperty.call(appsObj.versions, 'pip')) {
734 exec('pip -V 2>&1', function (error, stdout) {
735 if (!error) {
736 const pip = stdout.toString().split('\n')[0] || '';
737 const parts = pip.split(' ');
738 appsObj.versions.pip = parts.length >= 2 ? parts[1] : '';
739 }
740 functionProcessed();
741 });
742 }
743 if ({}.hasOwnProperty.call(appsObj.versions, 'pip3')) {
744 exec('pip3 -V 2>&1', function (error, stdout) {
745 if (!error) {
746 const pip = stdout.toString().split('\n')[0] || '';
747 const parts = pip.split(' ');
748 appsObj.versions.pip3 = parts.length >= 2 ? parts[1] : '';
749 }
750 functionProcessed();
751 });
752 }
753 if ({}.hasOwnProperty.call(appsObj.versions, 'java')) {
754 if (_darwin) {
755 // check if any JVM is installed but avoid dialog box that Java needs to be installed
756 exec('/usr/libexec/java_home -V 2>&1', function (error, stdout) {
757 if (!error && stdout.toString().toLowerCase().indexOf('no java runtime') === -1) {
758 // now this can be done savely
759 exec('java -version 2>&1', function (error, stdout) {
760 if (!error) {
761 const java = stdout.toString().split('\n')[0] || '';
762 const parts = java.split('"');
763 appsObj.versions.java = parts.length === 3 ? parts[1].trim() : '';
764 }
765 functionProcessed();
766 });
767 } else {
768 functionProcessed();
769 }
770 });
771 } else {
772 exec('java -version 2>&1', function (error, stdout) {
773 if (!error) {
774 const java = stdout.toString().split('\n')[0] || '';
775 const parts = java.split('"');
776 appsObj.versions.java = parts.length === 3 ? parts[1].trim() : '';
777 }
778 functionProcessed();
779 });
780 }
781 }
782 if ({}.hasOwnProperty.call(appsObj.versions, 'gcc')) {
783 if ((_darwin && util.darwinXcodeExists()) || !_darwin) {
784 exec('gcc -dumpversion', function (error, stdout) {
785 if (!error) {
786 appsObj.versions.gcc = stdout.toString().split('\n')[0].trim() || '';
787 }
788 if (appsObj.versions.gcc.indexOf('.') > -1) {
789 functionProcessed();
790 } else {
791 exec('gcc --version', function (error, stdout) {
792 if (!error) {
793 const gcc = stdout.toString().split('\n')[0].trim();
794 if (gcc.indexOf('gcc') > -1 && gcc.indexOf(')') > -1) {
795 const parts = gcc.split(')');
796 appsObj.versions.gcc = parts[1].trim() || appsObj.versions.gcc;
797 }
798 }
799 functionProcessed();
800 });
801 }
802 });
803 } else {
804 functionProcessed();
805 }
806 }
807 if ({}.hasOwnProperty.call(appsObj.versions, 'virtualbox')) {
808 exec(util.getVboxmanage() + ' -v 2>&1', function (error, stdout) {
809 if (!error) {
810 const vbox = stdout.toString().split('\n')[0] || '';
811 const parts = vbox.split('r');
812 appsObj.versions.virtualbox = parts[0];
813 }
814 functionProcessed();
815 });
816 }
817 if ({}.hasOwnProperty.call(appsObj.versions, 'dotnet')) {
818 exec('dotnet --version 2>&1', function (error, stdout) {
819 if (!error) {
820 const dotnet = stdout.toString().split('\n')[0] || '';
821 appsObj.versions.dotnet = dotnet.trim();
822 }
823 functionProcessed();
824 });
825 }
826 } catch (e) {
827 if (callback) { callback(appsObj.versions); }
828 resolve(appsObj.versions);
829 }
830 });
831 });
832}
833
834exports.versions = versions;
835
836function shell(callback) {
837 return new Promise((resolve, reject) => {
838 process.nextTick(() => {
839 if (_windows) {
840 let error = new Error(NOT_SUPPORTED);
841 if (callback) {
842 callback(NOT_SUPPORTED);
843 }
844 reject(error);
845 }
846
847 let result = '';
848 exec('echo $SHELL', function (error, stdout) {
849 if (!error) {
850 result = stdout.toString().split('\n')[0];
851 }
852 if (callback) {
853 callback(result);
854 }
855 resolve(result);
856 });
857 });
858 });
859}
860
861exports.shell = shell;
862
863function uuid(callback) {
864 return new Promise((resolve) => {
865 process.nextTick(() => {
866
867 let result = {
868 os: ''
869 };
870 let parts;
871
872 if (_darwin) {
873 exec('ioreg -rd1 -c IOPlatformExpertDevice | grep IOPlatformUUID', function (error, stdout) {
874 if (!error) {
875 parts = stdout.toString().split('\n')[0].replace(/"/g, '').split('=');
876 result.os = parts.length > 1 ? parts[1].trim().toLowerCase() : '';
877 }
878 if (callback) {
879 callback(result);
880 }
881 resolve(result);
882 });
883 }
884 if (_linux) {
885 exec('( cat /var/lib/dbus/machine-id /etc/machine-id 2> /dev/null || hostname ) | head -n 1 || :', function (error, stdout) {
886 if (!error) {
887 result.os = stdout.toString().split('\n')[0].trim().toLowerCase();
888 }
889 if (callback) {
890 callback(result);
891 }
892 resolve(result);
893 });
894 }
895 if (_freebsd || _openbsd || _netbsd) {
896 exec('kenv -q smbios.system.uuid', function (error, stdout) {
897 if (!error) {
898 result.os = stdout.toString().split('\n')[0].trim().toLowerCase();
899 }
900 if (callback) {
901 callback(result);
902 }
903 resolve(result);
904 });
905 }
906 if (_windows) {
907 exec('%windir%\\System32\\reg query "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography" /v MachineGuid', util.execOptsWin, function (error, stdout) {
908 if (!error) {
909 parts = stdout.toString().split('\n\r')[0].split('REG_SZ');
910 result.os = parts.length > 1 ? parts[1].replace(/\r+|\n+|\s+/ig, '').toLowerCase() : '';
911 }
912 if (callback) {
913 callback(result);
914 }
915 resolve(result);
916 });
917 }
918 });
919 });
920}
921
922exports.uuid = uuid;