summaryrefslogtreecommitdiff
path: root/node_modules/systeminformation/lib/osinfo.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/systeminformation/lib/osinfo.js')
-rw-r--r--node_modules/systeminformation/lib/osinfo.js1167
1 files changed, 1167 insertions, 0 deletions
diff --git a/node_modules/systeminformation/lib/osinfo.js b/node_modules/systeminformation/lib/osinfo.js
new file mode 100644
index 0000000..39573ed
--- /dev/null
+++ b/node_modules/systeminformation/lib/osinfo.js
@@ -0,0 +1,1167 @@
+'use strict';
+// @ts-check
+// ==================================================================================
+// osinfo.js
+// ----------------------------------------------------------------------------------
+// Description: System Information - library
+// for Node.js
+// Copyright: (c) 2014 - 2023
+// Author: Sebastian Hildebrandt
+// ----------------------------------------------------------------------------------
+// License: MIT
+// ==================================================================================
+// 3. Operating System
+// ----------------------------------------------------------------------------------
+
+const os = require('os');
+const fs = require('fs');
+const util = require('./util');
+const exec = require('child_process').exec;
+const execSync = require('child_process').execSync;
+
+let _platform = process.platform;
+
+const _linux = (_platform === 'linux' || _platform === 'android');
+const _darwin = (_platform === 'darwin');
+const _windows = (_platform === 'win32');
+const _freebsd = (_platform === 'freebsd');
+const _openbsd = (_platform === 'openbsd');
+const _netbsd = (_platform === 'netbsd');
+const _sunos = (_platform === 'sunos');
+
+// --------------------------
+// Get current time and OS uptime
+
+function time() {
+ let t = new Date().toString().split(' ');
+ return {
+ current: Date.now(),
+ uptime: os.uptime(),
+ timezone: (t.length >= 7) ? t[5] : '',
+ timezoneName: Intl ? Intl.DateTimeFormat().resolvedOptions().timeZone : (t.length >= 7) ? t.slice(6).join(' ').replace(/\(/g, '').replace(/\)/g, '') : ''
+ };
+}
+
+exports.time = time;
+
+// --------------------------
+// Get logo filename of OS distribution
+
+function getLogoFile(distro) {
+ distro = distro || '';
+ distro = distro.toLowerCase();
+ let result = _platform;
+ if (_windows) {
+ result = 'windows';
+ }
+ else if (distro.indexOf('mac os') !== -1) {
+ result = 'apple';
+ }
+ else if (distro.indexOf('arch') !== -1) {
+ result = 'arch';
+ }
+ else if (distro.indexOf('centos') !== -1) {
+ result = 'centos';
+ }
+ else if (distro.indexOf('coreos') !== -1) {
+ result = 'coreos';
+ }
+ else if (distro.indexOf('debian') !== -1) {
+ result = 'debian';
+ }
+ else if (distro.indexOf('deepin') !== -1) {
+ result = 'deepin';
+ }
+ else if (distro.indexOf('elementary') !== -1) {
+ result = 'elementary';
+ }
+ else if (distro.indexOf('fedora') !== -1) {
+ result = 'fedora';
+ }
+ else if (distro.indexOf('gentoo') !== -1) {
+ result = 'gentoo';
+ }
+ else if (distro.indexOf('mageia') !== -1) {
+ result = 'mageia';
+ }
+ else if (distro.indexOf('mandriva') !== -1) {
+ result = 'mandriva';
+ }
+ else if (distro.indexOf('manjaro') !== -1) {
+ result = 'manjaro';
+ }
+ else if (distro.indexOf('mint') !== -1) {
+ result = 'mint';
+ }
+ else if (distro.indexOf('mx') !== -1) {
+ result = 'mx';
+ }
+ else if (distro.indexOf('openbsd') !== -1) {
+ result = 'openbsd';
+ }
+ else if (distro.indexOf('freebsd') !== -1) {
+ result = 'freebsd';
+ }
+ else if (distro.indexOf('opensuse') !== -1) {
+ result = 'opensuse';
+ }
+ else if (distro.indexOf('pclinuxos') !== -1) {
+ result = 'pclinuxos';
+ }
+ else if (distro.indexOf('puppy') !== -1) {
+ result = 'puppy';
+ }
+ else if (distro.indexOf('raspbian') !== -1) {
+ result = 'raspbian';
+ }
+ else if (distro.indexOf('reactos') !== -1) {
+ result = 'reactos';
+ }
+ else if (distro.indexOf('redhat') !== -1) {
+ result = 'redhat';
+ }
+ else if (distro.indexOf('slackware') !== -1) {
+ result = 'slackware';
+ }
+ else if (distro.indexOf('sugar') !== -1) {
+ result = 'sugar';
+ }
+ else if (distro.indexOf('steam') !== -1) {
+ result = 'steam';
+ }
+ else if (distro.indexOf('suse') !== -1) {
+ result = 'suse';
+ }
+ else if (distro.indexOf('mate') !== -1) {
+ result = 'ubuntu-mate';
+ }
+ else if (distro.indexOf('lubuntu') !== -1) {
+ result = 'lubuntu';
+ }
+ else if (distro.indexOf('xubuntu') !== -1) {
+ result = 'xubuntu';
+ }
+ else if (distro.indexOf('ubuntu') !== -1) {
+ result = 'ubuntu';
+ }
+ else if (distro.indexOf('solaris') !== -1) {
+ result = 'solaris';
+ }
+ else if (distro.indexOf('tails') !== -1) {
+ result = 'tails';
+ }
+ else if (distro.indexOf('feren') !== -1) {
+ result = 'ferenos';
+ }
+ else if (distro.indexOf('robolinux') !== -1) {
+ result = 'robolinux';
+ } else if (_linux && distro) {
+ result = distro.toLowerCase().trim().replace(/\s+/g, '-');
+ }
+ return result;
+}
+
+// --------------------------
+// FQDN
+
+function getFQDN() {
+ let fqdn = os.hostname;
+ if (_linux || _darwin) {
+ try {
+ const stdout = execSync('hostnamectl --json short 2>/dev/null');
+ const json = JSON.parse(stdout.toString());
+
+ fqdn = json['StaticHostname'];
+ } catch (e) {
+ try {
+ const stdout = execSync('hostname -f 2>/dev/null');
+ fqdn = stdout.toString().split(os.EOL)[0];
+ } catch (e) {
+ util.noop();
+ }
+ }
+ } if (_freebsd || _openbsd || _netbsd) {
+ try {
+ const stdout = execSync('hostname 2>/dev/null');
+ fqdn = stdout.toString().split(os.EOL)[0];
+ } catch (e) {
+ util.noop();
+ }
+ }
+ if (_windows) {
+ try {
+ const stdout = execSync('echo %COMPUTERNAME%.%USERDNSDOMAIN%', util.execOptsWin);
+ fqdn = stdout.toString().replace('.%USERDNSDOMAIN%', '').split(os.EOL)[0];
+ } catch (e) {
+ util.noop();
+ }
+ }
+ return fqdn;
+}
+
+// --------------------------
+// OS Information
+
+function osInfo(callback) {
+
+ return new Promise((resolve) => {
+ process.nextTick(() => {
+ let result = {
+
+ platform: (_platform === 'win32' ? 'Windows' : _platform),
+ distro: 'unknown',
+ release: 'unknown',
+ codename: '',
+ kernel: os.release(),
+ arch: os.arch(),
+ hostname: os.hostname(),
+ fqdn: getFQDN(),
+ codepage: '',
+ logofile: '',
+ serial: '',
+ build: '',
+ servicepack: '',
+ uefi: false
+ };
+
+ if (_linux) {
+
+ exec('cat /etc/*-release; cat /usr/lib/os-release; cat /etc/openwrt_release', function (error, stdout) {
+ /**
+ * @namespace
+ * @property {string} DISTRIB_ID
+ * @property {string} NAME
+ * @property {string} DISTRIB_RELEASE
+ * @property {string} VERSION_ID
+ * @property {string} DISTRIB_CODENAME
+ */
+ let release = {};
+ let lines = stdout.toString().split('\n');
+ lines.forEach(function (line) {
+ if (line.indexOf('=') !== -1) {
+ release[line.split('=')[0].trim().toUpperCase()] = line.split('=')[1].trim();
+ }
+ });
+ let releaseVersion = (release.VERSION || '').replace(/"/g, '');
+ let codename = (release.DISTRIB_CODENAME || release.VERSION_CODENAME || '').replace(/"/g, '');
+ if (releaseVersion.indexOf('(') >= 0) {
+ codename = releaseVersion.split('(')[1].replace(/[()]/g, '').trim();
+ releaseVersion = releaseVersion.split('(')[0].trim();
+ }
+ result.distro = (release.DISTRIB_ID || release.NAME || 'unknown').replace(/"/g, '');
+ result.logofile = getLogoFile(result.distro);
+ result.release = (releaseVersion || release.DISTRIB_RELEASE || release.VERSION_ID || 'unknown').replace(/"/g, '');
+ result.codename = codename;
+ result.codepage = util.getCodepage();
+ result.build = (release.BUILD_ID || '').replace(/"/g, '').trim();
+ isUefiLinux().then(uefi => {
+ result.uefi = uefi;
+ uuid().then((data) => {
+ result.serial = data.os;
+ if (callback) {
+ callback(result);
+ }
+ resolve(result);
+ });
+ });
+ });
+ }
+ if (_freebsd || _openbsd || _netbsd) {
+
+ exec('sysctl kern.ostype kern.osrelease kern.osrevision kern.hostuuid machdep.bootmethod kern.geom.confxml', function (error, stdout) {
+ let lines = stdout.toString().split('\n');
+ const distro = util.getValue(lines, 'kern.ostype');
+ const logofile = util.getValue(lines, 'kern.ostype');
+ const release = util.getValue(lines, 'kern.osrelease').split('-')[0];
+ const serial = util.getValue(lines, 'kern.uuid');
+ const bootmethod = util.getValue(lines, 'machdep.bootmethod');
+ const uefiConf = stdout.toString().indexOf('<type>efi</type>') >= 0;
+ const uefi = bootmethod ? bootmethod.toLowerCase().indexOf('uefi') >= 0 : (uefiConf ? uefiConf : null);
+ result.distro = distro || result.distro;
+ result.logofile = logofile || result.logofile;
+ result.release = release || result.release;
+ result.serial = serial || result.serial;
+ result.codename = '';
+ result.codepage = util.getCodepage();
+ result.uefi = uefi || null;
+ if (callback) {
+ callback(result);
+ }
+ resolve(result);
+ });
+ }
+ if (_darwin) {
+ exec('sw_vers; sysctl kern.ostype kern.osrelease kern.osrevision kern.uuid', function (error, stdout) {
+ let lines = stdout.toString().split('\n');
+ result.serial = util.getValue(lines, 'kern.uuid');
+ result.distro = util.getValue(lines, 'ProductName');
+ result.release = (util.getValue(lines, 'ProductVersion', ':', true, true) + ' ' + util.getValue(lines, 'ProductVersionExtra', ':', true, true)).trim();
+ result.build = util.getValue(lines, 'BuildVersion');
+ result.logofile = getLogoFile(result.distro);
+ result.codename = 'macOS';
+ result.codename = (result.release.indexOf('10.4') > -1 ? 'Mac OS X Tiger' : result.codename);
+ result.codename = (result.release.indexOf('10.5') > -1 ? 'Mac OS X Leopard' : result.codename);
+ result.codename = (result.release.indexOf('10.6') > -1 ? 'Mac OS X Snow Leopard' : result.codename);
+ result.codename = (result.release.indexOf('10.7') > -1 ? 'Mac OS X Lion' : result.codename);
+ result.codename = (result.release.indexOf('10.8') > -1 ? 'OS X Mountain Lion' : result.codename);
+ result.codename = (result.release.indexOf('10.9') > -1 ? 'OS X Mavericks' : result.codename);
+ result.codename = (result.release.indexOf('10.10') > -1 ? 'OS X Yosemite' : result.codename);
+ result.codename = (result.release.indexOf('10.11') > -1 ? 'OS X El Capitan' : result.codename);
+ result.codename = (result.release.indexOf('10.12') > -1 ? 'macOS Sierra' : result.codename);
+ result.codename = (result.release.indexOf('10.13') > -1 ? 'macOS High Sierra' : result.codename);
+ result.codename = (result.release.indexOf('10.14') > -1 ? 'macOS Mojave' : result.codename);
+ result.codename = (result.release.indexOf('10.15') > -1 ? 'macOS Catalina' : result.codename);
+ result.codename = (result.release.startsWith('11.') ? 'macOS Big Sur' : result.codename);
+ result.codename = (result.release.startsWith('12.') ? 'macOS Monterey' : result.codename);
+ result.codename = (result.release.startsWith('13.') ? 'macOS Ventura' : result.codename);
+ result.uefi = true;
+ result.codepage = util.getCodepage();
+ if (callback) {
+ callback(result);
+ }
+ resolve(result);
+ });
+ }
+ if (_sunos) {
+ result.release = result.kernel;
+ exec('uname -o', function (error, stdout) {
+ let lines = stdout.toString().split('\n');
+ result.distro = lines[0];
+ result.logofile = getLogoFile(result.distro);
+ if (callback) { callback(result); }
+ resolve(result);
+ });
+ }
+ if (_windows) {
+ result.logofile = getLogoFile();
+ result.release = result.kernel;
+ try {
+ const workload = [];
+ workload.push(util.powerShell('Get-CimInstance Win32_OperatingSystem | select Caption,SerialNumber,BuildNumber,ServicePackMajorVersion,ServicePackMinorVersion | fl'));
+ workload.push(util.powerShell('(Get-CimInstance Win32_ComputerSystem).HypervisorPresent'));
+ workload.push(util.powerShell('Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.SystemInformation]::TerminalServerSession'));
+ util.promiseAll(
+ workload
+ ).then((data) => {
+ let lines = data.results[0] ? data.results[0].toString().split('\r\n') : [''];
+ result.distro = util.getValue(lines, 'Caption', ':').trim();
+ result.serial = util.getValue(lines, 'SerialNumber', ':').trim();
+ result.build = util.getValue(lines, 'BuildNumber', ':').trim();
+ result.servicepack = util.getValue(lines, 'ServicePackMajorVersion', ':').trim() + '.' + util.getValue(lines, 'ServicePackMinorVersion', ':').trim();
+ result.codepage = util.getCodepage();
+ const hyperv = data.results[1] ? data.results[1].toString().toLowerCase() : '';
+ result.hypervisor = hyperv.indexOf('true') !== -1;
+ const term = data.results[2] ? data.results[2].toString() : '';
+ result.remoteSession = (term.toString().toLowerCase().indexOf('true') >= 0);
+ isUefiWindows().then(uefi => {
+ result.uefi = uefi;
+ if (callback) {
+ callback(result);
+ }
+ resolve(result);
+ });
+ });
+ } catch (e) {
+ if (callback) { callback(result); }
+ resolve(result);
+ }
+ }
+ });
+ });
+}
+
+exports.osInfo = osInfo;
+
+function isUefiLinux() {
+ return new Promise((resolve) => {
+ process.nextTick(() => {
+ fs.stat('/sys/firmware/efi', function (err) {
+ if (!err) {
+ return resolve(true);
+ } else {
+ exec('dmesg | grep -E "EFI v"', function (error, stdout) {
+ if (!error) {
+ const lines = stdout.toString().split('\n');
+ return resolve(lines.length > 0);
+ }
+ return resolve(false);
+ });
+ }
+ });
+ });
+ });
+}
+
+function isUefiWindows() {
+ return new Promise((resolve) => {
+ process.nextTick(() => {
+ try {
+ exec('findstr /C:"Detected boot environment" "%windir%\\Panther\\setupact.log"', util.execOptsWin, function (error, stdout) {
+ if (!error) {
+ const line = stdout.toString().split('\n\r')[0];
+ return resolve(line.toLowerCase().indexOf('efi') >= 0);
+ } else {
+ exec('echo %firmware_type%', util.execOptsWin, function (error, stdout) {
+ if (!error) {
+ const line = stdout.toString() || '';
+ return resolve(line.toLowerCase().indexOf('efi') >= 0);
+ } else {
+ return resolve(false);
+ }
+ });
+ }
+ });
+ } catch (e) {
+ return resolve(false);
+ }
+ });
+ });
+}
+
+function versions(apps, callback) {
+ let versionObject = {
+ kernel: os.release(),
+ openssl: '',
+ systemOpenssl: '',
+ systemOpensslLib: '',
+ node: process.versions.node,
+ v8: process.versions.v8,
+ npm: '',
+ yarn: '',
+ pm2: '',
+ gulp: '',
+ grunt: '',
+ git: '',
+ tsc: '',
+ mysql: '',
+ redis: '',
+ mongodb: '',
+ apache: '',
+ nginx: '',
+ php: '',
+ docker: '',
+ postfix: '',
+ postgresql: '',
+ perl: '',
+ python: '',
+ python3: '',
+ pip: '',
+ pip3: '',
+ java: '',
+ gcc: '',
+ virtualbox: '',
+ bash: '',
+ zsh: '',
+ fish: '',
+ powershell: '',
+ dotnet: ''
+ };
+
+ function checkVersionParam(apps) {
+ if (apps === '*') {
+ return {
+ versions: versionObject,
+ counter: 30
+ };
+ }
+ if (!Array.isArray(apps)) {
+ apps = apps.trim().toLowerCase().replace(/,+/g, '|').replace(/ /g, '|');
+ apps = apps.split('|');
+ const result = {
+ versions: {},
+ counter: 0
+ };
+ apps.forEach(el => {
+ if (el) {
+ for (let key in versionObject) {
+ if ({}.hasOwnProperty.call(versionObject, key)) {
+ if (key.toLowerCase() === el.toLowerCase() && !{}.hasOwnProperty.call(result.versions, key)) {
+ result.versions[key] = versionObject[key];
+ if (key === 'openssl') {
+ result.versions.systemOpenssl = '';
+ result.versions.systemOpensslLib = '';
+ }
+
+ if (!result.versions[key]) { result.counter++; }
+ }
+ }
+ }
+ }
+ });
+ return result;
+ }
+ }
+
+ return new Promise((resolve) => {
+ process.nextTick(() => {
+ if (util.isFunction(apps) && !callback) {
+ callback = apps;
+ apps = '*';
+ } else {
+ apps = apps || '*';
+ if (typeof apps !== 'string') {
+ if (callback) { callback({}); }
+ return resolve({});
+ }
+ }
+ const appsObj = checkVersionParam(apps);
+ let totalFunctions = appsObj.counter;
+
+ let functionProcessed = (function () {
+ return function () {
+ if (--totalFunctions === 0) {
+ if (callback) {
+ callback(appsObj.versions);
+ }
+ resolve(appsObj.versions);
+ }
+ };
+ })();
+
+ let cmd = '';
+ try {
+ if ({}.hasOwnProperty.call(appsObj.versions, 'openssl')) {
+ appsObj.versions.openssl = process.versions.openssl;
+ exec('openssl version', function (error, stdout) {
+ if (!error) {
+ let openssl_string = stdout.toString().split('\n')[0].trim();
+ let openssl = openssl_string.split(' ');
+ appsObj.versions.systemOpenssl = openssl.length > 0 ? openssl[1] : openssl[0];
+ appsObj.versions.systemOpensslLib = openssl.length > 0 ? openssl[0] : 'openssl';
+ }
+ functionProcessed();
+ });
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'npm')) {
+ exec('npm -v', function (error, stdout) {
+ if (!error) {
+ appsObj.versions.npm = stdout.toString().split('\n')[0];
+ }
+ functionProcessed();
+ });
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'pm2')) {
+ cmd = 'pm2';
+ if (_windows) {
+ cmd += '.cmd';
+ }
+ exec(`${cmd} -v`, function (error, stdout) {
+ if (!error) {
+ let pm2 = stdout.toString().split('\n')[0].trim();
+ if (!pm2.startsWith('[PM2]')) {
+ appsObj.versions.pm2 = pm2;
+ }
+ }
+ functionProcessed();
+ });
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'yarn')) {
+ exec('yarn --version', function (error, stdout) {
+ if (!error) {
+ appsObj.versions.yarn = stdout.toString().split('\n')[0];
+ }
+ functionProcessed();
+ });
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'gulp')) {
+ cmd = 'gulp';
+ if (_windows) {
+ cmd += '.cmd';
+ }
+ exec(`${cmd} --version`, function (error, stdout) {
+ if (!error) {
+ const gulp = stdout.toString().split('\n')[0] || '';
+ appsObj.versions.gulp = (gulp.toLowerCase().split('version')[1] || '').trim();
+ }
+ functionProcessed();
+ });
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'tsc')) {
+ cmd = 'tsc';
+ if (_windows) {
+ cmd += '.cmd';
+ }
+ exec(`${cmd} --version`, function (error, stdout) {
+ if (!error) {
+ const tsc = stdout.toString().split('\n')[0] || '';
+ appsObj.versions.tsc = (tsc.toLowerCase().split('version')[1] || '').trim();
+ }
+ functionProcessed();
+ });
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'grunt')) {
+ cmd = 'grunt';
+ if (_windows) {
+ cmd += '.cmd';
+ }
+ exec(`${cmd} --version`, function (error, stdout) {
+ if (!error) {
+ const grunt = stdout.toString().split('\n')[0] || '';
+ appsObj.versions.grunt = (grunt.toLowerCase().split('cli v')[1] || '').trim();
+ }
+ functionProcessed();
+ });
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'git')) {
+ if (_darwin) {
+ const gitHomebrewExists = fs.existsSync('/usr/local/Cellar/git') || fs.existsSync('/opt/homebrew/bin/git');
+ if (util.darwinXcodeExists() || gitHomebrewExists) {
+ exec('git --version', function (error, stdout) {
+ if (!error) {
+ let git = stdout.toString().split('\n')[0] || '';
+ git = (git.toLowerCase().split('version')[1] || '').trim();
+ appsObj.versions.git = (git.split(' ')[0] || '').trim();
+ }
+ functionProcessed();
+ });
+ } else {
+ functionProcessed();
+ }
+ } else {
+ exec('git --version', function (error, stdout) {
+ if (!error) {
+ let git = stdout.toString().split('\n')[0] || '';
+ git = (git.toLowerCase().split('version')[1] || '').trim();
+ appsObj.versions.git = (git.split(' ')[0] || '').trim();
+ }
+ functionProcessed();
+ });
+ }
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'apache')) {
+ exec('apachectl -v 2>&1', function (error, stdout) {
+ if (!error) {
+ const apache = (stdout.toString().split('\n')[0] || '').split(':');
+ appsObj.versions.apache = (apache.length > 1 ? apache[1].replace('Apache', '').replace('/', '').split('(')[0].trim() : '');
+ }
+ functionProcessed();
+ });
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'nginx')) {
+ exec('nginx -v 2>&1', function (error, stdout) {
+ if (!error) {
+ const nginx = stdout.toString().split('\n')[0] || '';
+ appsObj.versions.nginx = (nginx.toLowerCase().split('/')[1] || '').trim();
+ }
+ functionProcessed();
+ });
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'mysql')) {
+ exec('mysql -V', function (error, stdout) {
+ if (!error) {
+ let mysql = stdout.toString().split('\n')[0] || '';
+ mysql = mysql.toLowerCase();
+ if (mysql.indexOf(',') > -1) {
+ mysql = (mysql.split(',')[0] || '').trim();
+ const parts = mysql.split(' ');
+ appsObj.versions.mysql = (parts[parts.length - 1] || '').trim();
+ } else {
+ if (mysql.indexOf(' ver ') > -1) {
+ mysql = mysql.split(' ver ')[1];
+ appsObj.versions.mysql = mysql.split(' ')[0];
+ }
+ }
+ }
+ functionProcessed();
+ });
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'php')) {
+ exec('php -v', function (error, stdout) {
+ if (!error) {
+ const php = stdout.toString().split('\n')[0] || '';
+ let parts = php.split('(');
+ if (parts[0].indexOf('-')) {
+ parts = parts[0].split('-');
+ }
+ appsObj.versions.php = parts[0].replace(/[^0-9.]/g, '');
+ }
+ functionProcessed();
+ });
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'redis')) {
+ exec('redis-server --version', function (error, stdout) {
+ if (!error) {
+ const redis = stdout.toString().split('\n')[0] || '';
+ const parts = redis.split(' ');
+ appsObj.versions.redis = util.getValue(parts, 'v', '=', true);
+ }
+ functionProcessed();
+ });
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'docker')) {
+ exec('docker --version', function (error, stdout) {
+ if (!error) {
+ const docker = stdout.toString().split('\n')[0] || '';
+ const parts = docker.split(' ');
+ appsObj.versions.docker = parts.length > 2 && parts[2].endsWith(',') ? parts[2].slice(0, -1) : '';
+ }
+ functionProcessed();
+ });
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'postfix')) {
+ exec('postconf -d | grep mail_version', function (error, stdout) {
+ if (!error) {
+ const postfix = stdout.toString().split('\n') || [];
+ appsObj.versions.postfix = util.getValue(postfix, 'mail_version', '=', true);
+ }
+ functionProcessed();
+ });
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'mongodb')) {
+ exec('mongod --version', function (error, stdout) {
+ if (!error) {
+ const mongodb = stdout.toString().split('\n')[0] || '';
+ appsObj.versions.mongodb = (mongodb.toLowerCase().split(',')[0] || '').replace(/[^0-9.]/g, '');
+ }
+ functionProcessed();
+ });
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'postgresql')) {
+ if (_linux) {
+ exec('locate bin/postgres', function (error, stdout) {
+ if (!error) {
+ const postgresqlBin = stdout.toString().split('\n').sort();
+ if (postgresqlBin.length) {
+ exec(postgresqlBin[postgresqlBin.length - 1] + ' -V', function (error, stdout) {
+ if (!error) {
+ const postgresql = stdout.toString().split('\n')[0].split(' ') || [];
+ appsObj.versions.postgresql = postgresql.length ? postgresql[postgresql.length - 1] : '';
+ }
+ functionProcessed();
+ });
+ } else {
+ functionProcessed();
+ }
+ } else {
+ exec('psql -V', function (error, stdout) {
+ if (!error) {
+ const postgresql = stdout.toString().split('\n')[0].split(' ') || [];
+ appsObj.versions.postgresql = postgresql.length ? postgresql[postgresql.length - 1] : '';
+ appsObj.versions.postgresql = appsObj.versions.postgresql.split('-')[0];
+ }
+ functionProcessed();
+ });
+ }
+ });
+ } else {
+ if (_windows) {
+ util.powerShell('Get-CimInstance Win32_Service | select caption | fl').then((stdout) => {
+ let serviceSections = stdout.split(/\n\s*\n/);
+ serviceSections.forEach((item) => {
+ if (item.trim() !== '') {
+ let lines = item.trim().split('\r\n');
+ let srvCaption = util.getValue(lines, 'caption', ':', true).toLowerCase();
+ if (srvCaption.indexOf('postgresql') > -1) {
+ const parts = srvCaption.split(' server ');
+ if (parts.length > 1) {
+ appsObj.versions.postgresql = parts[1];
+ }
+ }
+ }
+ });
+ functionProcessed();
+ });
+ } else {
+ exec('postgres -V', function (error, stdout) {
+ if (!error) {
+ const postgresql = stdout.toString().split('\n')[0].split(' ') || [];
+ appsObj.versions.postgresql = postgresql.length ? postgresql[postgresql.length - 1] : '';
+ }
+ functionProcessed();
+ });
+ }
+ }
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'perl')) {
+ exec('perl -v', function (error, stdout) {
+ if (!error) {
+ const perl = stdout.toString().split('\n') || '';
+ while (perl.length > 0 && perl[0].trim() === '') {
+ perl.shift();
+ }
+ if (perl.length > 0) {
+ appsObj.versions.perl = perl[0].split('(').pop().split(')')[0].replace('v', '');
+ }
+ }
+ functionProcessed();
+ });
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'python')) {
+ if (_darwin) {
+ const stdout = execSync('sw_vers');
+ const lines = stdout.toString().split('\n');
+ const osVersion = util.getValue(lines, 'ProductVersion', ':');
+ const gitHomebrewExists1 = fs.existsSync('/usr/local/Cellar/python');
+ const gitHomebrewExists2 = fs.existsSync('/opt/homebrew/bin/python');
+ if ((util.darwinXcodeExists() && util.semverCompare('12.0.1', osVersion) < 0) || gitHomebrewExists1 || gitHomebrewExists2) {
+ const cmd = gitHomebrewExists1 ? '/usr/local/Cellar/python -V 2>&1' : (gitHomebrewExists2 ? '/opt/homebrew/bin/python -V 2>&1' : 'python -V 2>&1');
+ exec(cmd, function (error, stdout) {
+ if (!error) {
+ const python = stdout.toString().split('\n')[0] || '';
+ appsObj.versions.python = python.toLowerCase().replace('python', '').trim();
+ }
+ functionProcessed();
+ });
+ } else {
+ functionProcessed();
+ }
+ } else {
+ exec('python -V 2>&1', function (error, stdout) {
+ if (!error) {
+ const python = stdout.toString().split('\n')[0] || '';
+ appsObj.versions.python = python.toLowerCase().replace('python', '').trim();
+ }
+ functionProcessed();
+ });
+ }
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'python3')) {
+ if (_darwin) {
+ const gitHomebrewExists = fs.existsSync('/usr/local/Cellar/python3') || fs.existsSync('/opt/homebrew/bin/python3');
+ if (util.darwinXcodeExists() || gitHomebrewExists) {
+ exec('python3 -V 2>&1', function (error, stdout) {
+ if (!error) {
+ const python = stdout.toString().split('\n')[0] || '';
+ appsObj.versions.python3 = python.toLowerCase().replace('python', '').trim();
+ }
+ functionProcessed();
+ });
+ } else {
+ functionProcessed();
+ }
+ } else {
+ exec('python3 -V 2>&1', function (error, stdout) {
+ if (!error) {
+ const python = stdout.toString().split('\n')[0] || '';
+ appsObj.versions.python3 = python.toLowerCase().replace('python', '').trim();
+ }
+ functionProcessed();
+ });
+ }
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'pip')) {
+ if (_darwin) {
+ const gitHomebrewExists = fs.existsSync('/usr/local/Cellar/pip') || fs.existsSync('/opt/homebrew/bin/pip');
+ if (util.darwinXcodeExists() || gitHomebrewExists) {
+ exec('pip -V 2>&1', function (error, stdout) {
+ if (!error) {
+ const pip = stdout.toString().split('\n')[0] || '';
+ const parts = pip.split(' ');
+ appsObj.versions.pip = parts.length >= 2 ? parts[1] : '';
+ }
+ functionProcessed();
+ });
+ } else {
+ functionProcessed();
+ }
+ } else {
+ exec('pip -V 2>&1', function (error, stdout) {
+ if (!error) {
+ const pip = stdout.toString().split('\n')[0] || '';
+ const parts = pip.split(' ');
+ appsObj.versions.pip = parts.length >= 2 ? parts[1] : '';
+ }
+ functionProcessed();
+ });
+ }
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'pip3')) {
+ if (_darwin) {
+ const gitHomebrewExists = fs.existsSync('/usr/local/Cellar/pip3') || fs.existsSync('/opt/homebrew/bin/pip3');
+ if (util.darwinXcodeExists() || gitHomebrewExists) {
+ exec('pip3 -V 2>&1', function (error, stdout) {
+ if (!error) {
+ const pip = stdout.toString().split('\n')[0] || '';
+ const parts = pip.split(' ');
+ appsObj.versions.pip3 = parts.length >= 2 ? parts[1] : '';
+ }
+ functionProcessed();
+ });
+ } else {
+ functionProcessed();
+ }
+ } else {
+ exec('pip3 -V 2>&1', function (error, stdout) {
+ if (!error) {
+ const pip = stdout.toString().split('\n')[0] || '';
+ const parts = pip.split(' ');
+ appsObj.versions.pip3 = parts.length >= 2 ? parts[1] : '';
+ }
+ functionProcessed();
+ });
+ }
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'java')) {
+ if (_darwin) {
+ // check if any JVM is installed but avoid dialog box that Java needs to be installed
+ exec('/usr/libexec/java_home -V 2>&1', function (error, stdout) {
+ if (!error && stdout.toString().toLowerCase().indexOf('no java runtime') === -1) {
+ // now this can be done savely
+ exec('java -version 2>&1', function (error, stdout) {
+ if (!error) {
+ const java = stdout.toString().split('\n')[0] || '';
+ const parts = java.split('"');
+ appsObj.versions.java = parts.length === 3 ? parts[1].trim() : '';
+ }
+ functionProcessed();
+ });
+ } else {
+ functionProcessed();
+ }
+ });
+ } else {
+ exec('java -version 2>&1', function (error, stdout) {
+ if (!error) {
+ const java = stdout.toString().split('\n')[0] || '';
+ const parts = java.split('"');
+ appsObj.versions.java = parts.length === 3 ? parts[1].trim() : '';
+ }
+ functionProcessed();
+ });
+ }
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'gcc')) {
+ if ((_darwin && util.darwinXcodeExists()) || !_darwin) {
+ exec('gcc -dumpversion', function (error, stdout) {
+ if (!error) {
+ appsObj.versions.gcc = stdout.toString().split('\n')[0].trim() || '';
+ }
+ if (appsObj.versions.gcc.indexOf('.') > -1) {
+ functionProcessed();
+ } else {
+ exec('gcc --version', function (error, stdout) {
+ if (!error) {
+ const gcc = stdout.toString().split('\n')[0].trim();
+ if (gcc.indexOf('gcc') > -1 && gcc.indexOf(')') > -1) {
+ const parts = gcc.split(')');
+ appsObj.versions.gcc = parts[1].trim() || appsObj.versions.gcc;
+ }
+ }
+ functionProcessed();
+ });
+ }
+ });
+ } else {
+ functionProcessed();
+ }
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'virtualbox')) {
+ exec(util.getVboxmanage() + ' -v 2>&1', function (error, stdout) {
+ if (!error) {
+ const vbox = stdout.toString().split('\n')[0] || '';
+ const parts = vbox.split('r');
+ appsObj.versions.virtualbox = parts[0];
+ }
+ functionProcessed();
+ });
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'bash')) {
+ exec('bash --version', function (error, stdout) {
+ if (!error) {
+ const line = stdout.toString().split('\n')[0];
+ const parts = line.split(' version ');
+ if (parts.length > 1) {
+ appsObj.versions.bash = parts[1].split(' ')[0].split('(')[0];
+ }
+ }
+ functionProcessed();
+ });
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'zsh')) {
+ exec('zsh --version', function (error, stdout) {
+ if (!error) {
+ const line = stdout.toString().split('\n')[0];
+ const parts = line.split('zsh ');
+ if (parts.length > 1) {
+ appsObj.versions.zsh = parts[1].split(' ')[0];
+ }
+ }
+ functionProcessed();
+ });
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'fish')) {
+ exec('fish --version', function (error, stdout) {
+ if (!error) {
+ const line = stdout.toString().split('\n')[0];
+ const parts = line.split(' version ');
+ if (parts.length > 1) {
+ appsObj.versions.fish = parts[1].split(' ')[0];
+ }
+ }
+ functionProcessed();
+ });
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'powershell')) {
+ if (_windows) {
+ util.powerShell('$PSVersionTable').then(stdout => {
+ const lines = stdout.toString().split('\n').map(line => line.replace(/ +/g, ' ').replace(/ +/g, ':'));
+ appsObj.versions.powershell = util.getValue(lines, 'psversion');
+ functionProcessed();
+ });
+ } else {
+ functionProcessed();
+ }
+ }
+ if ({}.hasOwnProperty.call(appsObj.versions, 'dotnet')) {
+ if (_windows) {
+ 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 => {
+ const lines = stdout.toString().split('\r\n');
+ let dotnet = '';
+ lines.forEach(line => {
+ line = line.replace(/ +/g, ' ');
+ const parts = line.split(' ');
+ dotnet = dotnet || (parts[0].toLowerCase().startsWith('client') && parts.length > 2 ? parts[1].trim() : (parts[0].toLowerCase().startsWith('full') && parts.length > 2 ? parts[1].trim() : ''));
+ });
+ appsObj.versions.dotnet = dotnet.trim();
+ functionProcessed();
+ });
+ } else {
+ functionProcessed();
+ }
+ }
+ } catch (e) {
+ if (callback) { callback(appsObj.versions); }
+ resolve(appsObj.versions);
+ }
+ });
+ });
+}
+
+exports.versions = versions;
+
+function shell(callback) {
+ return new Promise((resolve) => {
+ process.nextTick(() => {
+ if (_windows) {
+ resolve('cmd');
+ } else {
+ let result = '';
+ exec('echo $SHELL', function (error, stdout) {
+ if (!error) {
+ result = stdout.toString().split('\n')[0];
+ }
+ if (callback) {
+ callback(result);
+ }
+ resolve(result);
+ });
+ }
+ });
+ });
+}
+
+exports.shell = shell;
+
+function getUniqueMacAdresses() {
+ let macs = [];
+ try {
+ const ifaces = os.networkInterfaces();
+ for (let dev in ifaces) {
+ if ({}.hasOwnProperty.call(ifaces, dev)) {
+ ifaces[dev].forEach(function (details) {
+ if (details && details.mac && details.mac !== '00:00:00:00:00:00') {
+ const mac = details.mac.toLowerCase();
+ if (macs.indexOf(mac) === -1) {
+ macs.push(mac);
+ }
+ }
+ });
+ }
+ }
+ macs = macs.sort(function (a, b) {
+ if (a < b) { return -1; }
+ if (a > b) { return 1; }
+ return 0;
+ });
+ } catch (e) {
+ macs.push('00:00:00:00:00:00');
+ }
+ return macs;
+}
+
+function uuid(callback) {
+ return new Promise((resolve) => {
+ process.nextTick(() => {
+
+ let result = {
+ os: '',
+ hardware: '',
+ macs: getUniqueMacAdresses()
+ };
+ let parts;
+
+ if (_darwin) {
+ exec('system_profiler SPHardwareDataType -json', function (error, stdout) {
+ if (!error) {
+ try {
+ const jsonObj = JSON.parse(stdout.toString());
+ if (jsonObj.SPHardwareDataType && jsonObj.SPHardwareDataType.length > 0) {
+ const spHardware = jsonObj.SPHardwareDataType[0];
+ result.os = spHardware.platform_UUID.toLowerCase();
+ result.hardware = spHardware.serial_number;
+ }
+ } catch (e) {
+ util.noop();
+ }
+ }
+ if (callback) {
+ callback(result);
+ }
+ resolve(result);
+ });
+ }
+ if (_linux) {
+ const cmd = `echo -n "os: "; cat /var/lib/dbus/machine-id 2> /dev/null; echo;
+echo -n "os: "; cat /etc/machine-id 2> /dev/null; echo;
+echo -n "hardware: "; cat /sys/class/dmi/id/product_uuid 2> /dev/null; echo;`;
+ exec(cmd, function (error, stdout) {
+ const lines = stdout.toString().split('\n');
+ result.os = util.getValue(lines, 'os').toLowerCase();
+ result.hardware = util.getValue(lines, 'hardware').toLowerCase();
+ if (!result.hardware) {
+ const lines = fs.readFileSync('/proc/cpuinfo', { encoding: 'utf8' }).toString().split('\n');
+ const serial = util.getValue(lines, 'serial');
+ result.hardware = serial || '';
+ }
+ if (callback) {
+ callback(result);
+ }
+ resolve(result);
+ });
+ }
+ if (_freebsd || _openbsd || _netbsd) {
+ exec('sysctl -i kern.hostid kern.hostuuid', function (error, stdout) {
+ const lines = stdout.toString().split('\n');
+ result.os = util.getValue(lines, 'kern.hostid', ':').toLowerCase();
+ result.hardware = util.getValue(lines, 'kern.hostuuid', ':').toLowerCase();
+ if (result.os.indexOf('unknown') >= 0) { result.os = ''; }
+ if (result.hardware.indexOf('unknown') >= 0) { result.hardware = ''; }
+ if (callback) {
+ callback(result);
+ }
+ resolve(result);
+ });
+ }
+ if (_windows) {
+ let sysdir = '%windir%\\System32';
+ if (process.arch === 'ia32' && Object.prototype.hasOwnProperty.call(process.env, 'PROCESSOR_ARCHITEW6432')) {
+ sysdir = '%windir%\\sysnative\\cmd.exe /c %windir%\\System32';
+ }
+ util.powerShell('Get-CimInstance Win32_ComputerSystemProduct | select UUID | fl').then((stdout) => {
+ let lines = stdout.split('\r\n');
+ result.hardware = util.getValue(lines, 'uuid', ':').toLowerCase();
+ exec(`${sysdir}\\reg query "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography" /v MachineGuid`, util.execOptsWin, function (error, stdout) {
+ parts = stdout.toString().split('\n\r')[0].split('REG_SZ');
+ result.os = parts.length > 1 ? parts[1].replace(/\r+|\n+|\s+/ig, '').toLowerCase() : '';
+ if (callback) {
+ callback(result);
+ }
+ resolve(result);
+ });
+ });
+ }
+ });
+ });
+}
+
+exports.uuid = uuid;