aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--debian/changelog64
-rw-r--r--debian/compat1
-rw-r--r--debian/control6
-rw-r--r--debian/copyright4
-rw-r--r--debian/patches/001-Fix-shebang.patch12
-rwxr-xr-xinxi5413
-rw-r--r--inxi.1650
-rw-r--r--inxi.changelog1044
8 files changed, 5323 insertions, 1871 deletions
diff --git a/debian/changelog b/debian/changelog
index 1b4cee9..98bf8f4 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,67 @@
+inxi (3.1.06-1-1) unstable; urgency=medium
+
+ * New upstream version 3.1.06-1.
+
+ -- Unit 193 <unit193@debian.org> Sat, 22 Aug 2020 19:41:34 -0400
+
+inxi (3.1.05-2-1) unstable; urgency=medium
+
+ * New upstream version 3.1.05-2.
+ - Remove excess closing bracket. (Closes: #966424)
+
+ -- Unit 193 <unit193@debian.org> Tue, 28 Jul 2020 18:37:38 -0400
+
+inxi (3.1.05-1-1) unstable; urgency=medium
+
+ * New upstream version 3.1.05-1.
+
+ -- Unit 193 <unit193@debian.org> Tue, 28 Jul 2020 00:28:22 -0400
+
+inxi (3.1.04-1-1) unstable; urgency=medium
+
+ * New upstream version 3.1.04-1.
+
+ -- Unit 193 <unit193@debian.org> Wed, 01 Jul 2020 02:46:47 -0400
+
+inxi (3.1.03-1-1) unstable; urgency=medium
+
+ * New upstream version 3.1.03-1.
+
+ -- Unit 193 <unit193@debian.org> Mon, 15 Jun 2020 19:31:16 -0400
+
+inxi (3.1.01-1-1) unstable; urgency=medium
+
+ * New upstream version 3.1.01-1.
+ - Refresh patch.
+
+ -- Unit 193 <unit193@debian.org> Mon, 01 Jun 2020 19:14:31 -0400
+
+inxi (3.1.00-1-1) unstable; urgency=medium
+
+ * New upstream version 3.1.00-1
+ - Verify TLS certificates. (Closes: #954042)
+ * d/compat, d/control:
+ - Drop d/compat in favor of debhelper-compat, bump to 13.
+ * d/control, d/copyright: Update email address.
+
+ -- Unit 193 <unit193@debian.org> Wed, 29 Apr 2020 18:15:37 -0400
+
+inxi (3.0.38-1-1) unstable; urgency=medium
+
+ * New upstream version 3.0.38-1
+ * d/copyright: Update years.
+ * Update Standards-Version to 4.5.0.
+
+ -- Unit 193 <unit193@ubuntu.com> Tue, 17 Mar 2020 23:51:29 -0400
+
+inxi (3.0.37-1-1) unstable; urgency=medium
+
+ * New upstream version 3.0.37-1
+ - Add an option to disable use of 'sudo'. (Closes: #942194)
+ * Update Standards-Version to 4.4.1.
+
+ -- Unit 193 <unit193@ubuntu.com> Wed, 20 Nov 2019 19:52:15 -0500
+
inxi (3.0.36-1-1) unstable; urgency=medium
* New upstream version 3.0.36-1
diff --git a/debian/compat b/debian/compat
deleted file mode 100644
index ec63514..0000000
--- a/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-9
diff --git a/debian/control b/debian/control
index fd55827..5591ff0 100644
--- a/debian/control
+++ b/debian/control
@@ -1,10 +1,10 @@
Source: inxi
Section: misc
Priority: optional
-Maintainer: Unit 193 <unit193@ubuntu.com>
-Build-Depends: debhelper (>= 9)
+Maintainer: Unit 193 <unit193@debian.org>
+Build-Depends: debhelper-compat (= 13)
Rules-Requires-Root: no
-Standards-Version: 4.4.1
+Standards-Version: 4.5.0
Homepage: https://smxi.org/docs/inxi.htm
Vcs-Browser: https://git.unit193.net/cgit/users/unit193/inxi.git
Vcs-Git: https://git.unit193.net/cgit/users/unit193/inxi.git
diff --git a/debian/copyright b/debian/copyright
index 28b2d78..896ff36 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -5,7 +5,7 @@ Source: https://github.com/smxi/inxi/
Files: *
Copyright: 2005-2007, Michiel de Boer <infobash@rebelhomicide.demon.nl>
2008-2017, Scott Rogers <trash80.v2.0@gmail.com>
- 2008-2019, Harold Hope <inxi-svn@techpatterns.com>
+ 2008-2020, Harold Hope <inxi-svn@techpatterns.com>
License: GPL-3+
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -25,7 +25,7 @@ License: GPL-3+
Files: debian/*
-Copyright: 2013-2019, Unit 193 <unit193@ubuntu.com>
+Copyright: 2013-2020, Unit 193 <unit193@debian.org>
License: BSD-3-clause
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
diff --git a/debian/patches/001-Fix-shebang.patch b/debian/patches/001-Fix-shebang.patch
index 8dc0e36..eea1daf 100644
--- a/debian/patches/001-Fix-shebang.patch
+++ b/debian/patches/001-Fix-shebang.patch
@@ -1,11 +1,15 @@
Description: Fix shebang to comply with Debian Policy 10.4
-Author: Unit 193 <unit193@ubuntu.com>
+Author: Unit 193 <unit193@debian.org>
---- inxi-3.0.20-1.orig/inxi
-+++ inxi-3.0.20-1/inxi
+---
+ inxi | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/inxi 2020-06-01 19:13:23.534785060 -0400
++++ b/inxi 2020-06-01 19:13:23.526785130 -0400
@@ -1,4 +1,4 @@
-#!/usr/bin/env perl
+#!/usr/bin/perl
## infobash: Copyright (C) 2005-2007 Michiel de Boer aka locsmif
- ## inxi: Copyright (C) 2008-2019 Harald Hope
+ ## inxi: Copyright (C) 2008-2020 Harald Hope
## Additional features (C) Scott Rogers - kde, cpu info
diff --git a/inxi b/inxi
index e65a29f..0ce2026 100755
--- a/inxi
+++ b/inxi
@@ -1,6 +1,6 @@
#!/usr/bin/env perl
## infobash: Copyright (C) 2005-2007 Michiel de Boer aka locsmif
-## inxi: Copyright (C) 2008-2019 Harald Hope
+## inxi: Copyright (C) 2008-2020 Harald Hope
## Additional features (C) Scott Rogers - kde, cpu info
## Further fixes (listed as known): Horst Tritremmel <hjt at sidux.com>
## Steven Barrett (aka: damentz) - usb audio patch; swap percent used patch
@@ -19,9 +19,17 @@ use warnings;
# use diagnostics;
use 5.008;
+## Perl 7 things for testing: depend on Perl 5.032
+# use 5.032
+# use compat::perl5; # act like Perl 5's defaults
+# no feature qw(indirect);
+# no multidimensional;
+# no bareword::filehandle;
+
use Cwd qw(abs_path); # qw(abs_path);#abs_path realpath getcwd
use Data::Dumper qw(Dumper); # print_r
use File::Find;
+use File::stat; # needed for Xorg.0.log file mtime comparisons
use Getopt::Long qw(GetOptions);
# Note: default auto_abbrev is enabled, that's fine
Getopt::Long::Configure ('bundling', 'no_ignore_case',
@@ -31,8 +39,8 @@ use POSIX qw(uname strftime ttyname);
## INXI INFO ##
my $self_name='inxi';
-my $self_version='3.0.37';
-my $self_date='2019-11-19';
+my $self_version='3.1.06';
+my $self_date='2020-08-17';
my $self_patch='00';
## END INXI INFO ##
@@ -52,41 +60,46 @@ if (eval {require Time::HiRes}){
}
@t0 = eval 'Time::HiRes::gettimeofday()' if $b_hires; # let's start it right away
## Hashes
-my ( %alerts,%client,%colors,%debugger,%dl,%files,%rows,%system_files,%use );
+my (%alerts,%client,%colors,%debugger,%dl,%files,%program_values,%rows,
+%sensors_raw,%system_files);
## Arrays
# ps_aux is full output, ps_cmd is only the last 10 columns to last
my (@app,@dmesg_boot,@devices_audio,@devices_graphics,@devices_network,
@devices_hwraid,@devices_timer,@dmi,@gpudata,@ifs,@ifs_bsd,
-@paths,@proc_partitions,@ps_aux,@ps_cmd,@ps_gui,
+@paths,@proc_partitions,@ps_aux,@ps_cmd,@ps_gui,@sensors_exclude,@sensors_use,
@sysctl,@sysctl_battery,@sysctl_sensors,@sysctl_machine,@uname,@usb);
## Disk arrays
my (@dm_boot_disk,@dm_boot_optical,@glabel,@gpart,@hardware_raid,@labels,
-@lsblk,@partitions,@raid,@sysctl_disks,@uuids);
+@lsblk,@partitions,@raid,@sysctl_disks,@swaps,@uuids);
my @test = (0,0,0,0,0);
## Booleans
-my ($b_admin,$b_arm,$b_bb_ps,$b_block_tool,$b_console_irc,
+my ($b_admin,$b_arm,$b_bb_ps,$b_block_tool,
$b_display,$b_dmesg_boot_check,$b_dmi,$b_dmidecode_force,
$b_fake_bsd,$b_fake_dboot,$b_fake_dmidecode,$b_fake_pciconf,$b_fake_sysctl,
$b_fake_usbdevs,$b_force_display,$b_gpudata,$b_irc,
-$b_log,$b_log_colors,$b_log_full,$b_man,$b_mem,$b_mips,$b_no_sudo,
-$b_pci,$b_pci_tool,$b_ppc,$b_proc_partitions,$b_ps_gui,
-$b_root,$b_running_in_display,$b_skip_dig,
+$b_log,$b_log_colors,$b_log_full,$b_man,$b_mem,$b_no_html_wan,$b_mips,$b_no_sudo,
+$b_pci,$b_pci_tool,$b_pkg,$b_ppc,$b_proc_partitions,$b_ps_gui,
+$b_root,$b_running_in_display,$b_sensors,$b_skip_dig,
$b_slot_tool,$b_soc_audio,$b_soc_gfx,$b_soc_net,$b_soc_timer,$b_sparc,
-$b_sudo,$b_sysctl,$b_usb,$b_usb_check,$b_usb_sys,$b_usb_tool,$b_wmctrl);
+$b_swaps,$b_sysctl,$b_usb,$b_usb_check,$b_usb_sys,$b_usb_tool,
+$b_wmctrl);
## Disk checks
my ($b_dm_boot_disk,$b_dm_boot_optical,$b_glabel,$b_hardware_raid,
-$b_label_uuid,$b_lsblk,$b_partitions,$b_raid);
-my ($b_sysctl_disk,$b_update,$b_weather) = (1,1,1);
-
+$b_label_uuid,$b_lsblk,$b_partitions,$b_raid,$b_smartctl);
+# initialize basic use features
+my %use = (
+'sysctl_disk' => 1, # unused currently
+'update' => 1, # switched off/on with maintainer config ALLOW_UPDATE
+'weather' => 1, # switched off/on with maintainer config ALLOW_WEATHER
+);
## System
my ($bsd_type,$device_vm,$language,$os,$pci_tool,$wan_url) = ('','','','','','');
my ($bits_sys,$cpu_arch);
my ($cpu_sleep,$dl_timeout,$limit,$ps_cols,$ps_count) = (0.35,4,10,0,5);
my $sensors_cpu_nu = 0;
my ($dl_ua,$weather_source,$weather_unit) = ('s-tools/' . $self_name . '-',100,'mi');
-
## Tools
my ($display,$ftp_alt,$tty_session);
my ($display_opt,$sudo) = ('','');
@@ -109,9 +122,8 @@ my %sep = (
's2-irc' => '',
's2-console' => ':',
);
-
-my %show = ('host' => 1);
-
+my %show;
+#$show{'host'} = 1;
my %size = (
'console' => 115,
# Default indentation level. NOTE: actual indent is 1 greater to allow for
@@ -143,7 +155,7 @@ sub main {
eval $start if $b_log;
initialize();
## Uncomment these two values for start client debugging
- # $debug = 10; # 3 prints timers
+ # $debug = 3; # 3 prints timers / 10 prints to log file
# set_debugger(); # for debugging of konvi and other start client issues
## legacy method
#my $ob_start = StartClient->new();
@@ -287,7 +299,7 @@ sub check_tools {
);
%commands = (%commands,%hash);
}
- # can't check permissions since we need to know the partition
+ # can't check permissions since we need to know the partition/disc
if ($b_block_tool){
%hash = (
'blockdev' => 'linux',
@@ -295,6 +307,12 @@ sub check_tools {
);
%commands = (%commands,%hash);
}
+ if ($b_smartctl){
+ %hash = (
+ 'smartctl' => 'all',
+ );
+ %commands = (%commands,%hash);
+ }
foreach ( keys %commands ){
$action = 'use';
$message = 'Present and working';
@@ -316,17 +334,7 @@ sub check_tools {
%alerts = (%alerts, %hash);
}
# print Dumper \%alerts;
- # only use sudo if not root, -n option requires sudo -V 1.7 or greater.
- # for some reason sudo -n with < 1.7 in Perl does not print to stderr
- # sudo will just error out which is the safest course here for now,
- # otherwise that interactive sudo password thing is too annoying
- # important: -n makes it non interactive, no prompt for password
- if (!$b_root && $b_sudo && (my $path = main::check_program('sudo') )) {
- my @data = program_values('sudo');
- my $version = program_version($path,$data[0],$data[1],$data[2],$data[5]);
- $version =~ s/^([0-9]+\.[0-9]+).*/$1/;
- $sudo = "$path -n " if !$b_no_sudo && is_numeric($version) && $version >= 1.7;
- }
+
set_fake_tools() if $b_fake_bsd;
}
# args: 1 - desktop/app command for --version; 2 - search string;
@@ -492,6 +500,20 @@ sub set_sep {
}
}
+# Important: -n makes it non interactive, no prompt for password
+# only use sudo if not root, -n option requires sudo -V 1.7 or greater.
+# for some reason sudo -n with < 1.7 in Perl does not print to stderr
+# sudo will just error out which is the safest course here for now,
+# otherwise that interactive sudo password thing is too annoying
+sub set_sudo {
+ if (!$b_root && !$b_no_sudo && (my $path = check_program('sudo'))) {
+ my @data = program_data('sudo');
+ $data[1] =~ s/^([0-9]+\.[0-9]+).*/$1/;
+ #print "sudo v: $data[1]\n";
+ $sudo = "$path -n " if is_numeric($data[1]) && $data[1] >= 1.7;
+ }
+}
+
sub set_user_paths {
my ( $b_conf, $b_data );
# this needs to be set here because various options call the parent
@@ -562,24 +584,62 @@ sub system_files {
'partitions' => '/proc/partitions',
'scsi' => '/proc/scsi/scsi',
'version' => '/proc/version',
- 'xorg-log' => '/var/log/Xorg.0.log'
+ # note: 'xorg-log' is set only if -G is triggered
);
foreach ( keys %files ){
$system_files{$_} = ( -e $files{$_} ) ? $files{$_} : '';
}
- if ( ! $system_files{'xorg-log'} && check_program('xset') ){
- my $data = qx(xset q 2>/dev/null);
- foreach ( split /\n/, $data){
- if ($_ =~ /Log file/i){
- $system_files{'xorg-log'} = get_piece($_,3);
- last;
+ }
+ else {
+ return $system_files{$file};
+ }
+}
+sub set_xorg_log {
+ eval $start if $b_log;
+ my (@temp,@x_logs);
+ my ($file_holder,$time_holder,$x_mtime) = ('',0,0);
+ # NOTE: other variations may be /var/run/gdm3/... but not confirmed
+ # we are just going to get all the Xorg logs we can find, and not worry about
+ # which is 'right'.
+ @temp = globber('/var/log/Xorg.*.log');
+ push @x_logs, @temp if @temp;
+ @temp = globber('/var/lib/gdm/.local/share/xorg/Xorg.*.log');
+ push @x_logs, @temp if @temp;
+ @temp = globber($ENV{'HOME'} . '/.local/share/xorg/Xorg.*.log',);
+ push @x_logs, @temp if @temp;
+ # root will not have a /root/.local/share/xorg directory so need to use a
+ # user one if we can find one.
+ if ($b_root){
+ @temp = globber('/home/*/.local/share/xorg/Xorg.*.log');
+ push @x_logs, @temp if @temp;
+ }
+ foreach (@x_logs){
+ if (-r $_){
+ my $src_info = File::stat::stat("$_");
+ #print "$_\n";
+ if ($src_info){
+ $x_mtime = $src_info->mtime;
+ # print $_ . ": $x_time" . "\n";
+ if ($x_mtime > $time_holder ){
+ $time_holder = $x_mtime;
+ $file_holder = $_;
}
}
}
}
- else {
- return $system_files{$file};
+ if ( !$file_holder && check_program('xset') ){
+ my $data = qx(xset q 2>/dev/null);
+ foreach ( split /\n/, $data){
+ if ($_ =~ /Log file/i){
+ $file_holder = get_piece($_,3);
+ last;
+ }
+ }
}
+ print "Xorg log file: $file_holder\nLast modified: $time_holder\n" if $test[14];
+ log_data('data',"Xorg log file: $file_holder") if $b_log;
+ $system_files{'xorg-log'} = $file_holder;
+ eval $end if $b_log;
}
########################################################################
@@ -643,6 +703,7 @@ sub get_color_scheme {
[qw(MAGENTA BLUE NORMAL)],
[qw(MAGENTA DBLUE NORMAL)],
);
+ eval $end if $b_log;
if ($type eq 'count' ){
return scalar @color_schemes;
}
@@ -653,7 +714,6 @@ sub get_color_scheme {
return @{$color_schemes[$type]};
# print Dumper $color_schemes[$scheme_nu];
}
- eval $end if $b_log;
}
sub set_color_scheme {
@@ -960,7 +1020,7 @@ sub process_selection {
}
sub delete_all_colors {
my @file_lines = main::reader( $user_config_file );
- open( $w_fh, '>', $user_config_file ) or error_handler('open', $user_config_file, $!);
+ open( $w_fh, '>', $user_config_file ) or main::error_handler('open', $user_config_file, $!);
foreach ( @file_lines ) {
if ( $_ !~ /^(CONSOLE_COLOR_SCHEME|GLOBAL_COLOR_SCHEME|IRC_COLOR_SCHEME|IRC_CONS_COLOR_SCHEME|IRC_X_TERM_COLOR_SCHEME|VIRT_TERM_COLOR_SCHEME)/){
print {$w_fh} "$_";
@@ -970,7 +1030,7 @@ sub delete_all_colors {
}
sub delete_global_color {
my @file_lines = main::reader( $user_config_file );
- open( $w_fh, '>', $user_config_file ) or error_handler('open', $user_config_file, $!);
+ open( $w_fh, '>', $user_config_file ) or main::error_handler('open', $user_config_file, $!);
foreach ( @file_lines ) {
if ( $_ !~ /^GLOBAL_COLOR_SCHEME/){
print {$w_fh} "$_";
@@ -982,7 +1042,7 @@ sub set_config_color_scheme {
my $value = shift;
my @file_lines = main::reader( $user_config_file );
my $b_found = 0;
- open( $w_fh, '>', $user_config_file ) or error_handler('open', $user_config_file, $!);
+ open( $w_fh, '>', $user_config_file ) or main::error_handler('open', $user_config_file, $!);
foreach ( @file_lines ) {
if ( $_ =~ /^$configs{'variable'}/ ){
$_ = "$configs{'variable'}=$value";
@@ -1065,8 +1125,8 @@ sub get_configs {
# args: 0: key; 1: value
sub get_config_item {
my ($key,$val) = @_;
- if ($key eq 'ALLOW_UPDATE' || $key eq 'B_ALLOW_UPDATE') {$b_update = $val if is_int($val)}
- elsif ($key eq 'ALLOW_WEATHER' || $key eq 'B_ALLOW_WEATHER') {$b_weather = $val if is_int($val)}
+ if ($key eq 'ALLOW_UPDATE' || $key eq 'B_ALLOW_UPDATE') {$use{'update'} = $val if is_int($val)}
+ elsif ($key eq 'ALLOW_WEATHER' || $key eq 'B_ALLOW_WEATHER') {$use{'weather'} = $val if is_int($val)}
elsif ($key eq 'CPU_SLEEP') {$cpu_sleep = $val if is_numeric($val)}
elsif ($key eq 'DL_TIMEOUT') {$dl_timeout = $val if is_int($val)}
elsif ($key eq 'DOWNLOADER') {
@@ -1080,11 +1140,20 @@ sub get_config_item {
elsif ($key eq 'LANGUAGE') {$language = $val if $val =~ /^(en)$/}
elsif ($key eq 'LIMIT') {$limit = $val if is_int($val)}
elsif ($key eq 'OUTPUT_TYPE') {$output_type = $val if $val =~ /^(json|screen|xml)$/}
+ elsif ($key eq 'NO_DIG') {$b_skip_dig = $val if is_int($val)}
+ elsif ($key eq 'NO_HTML_WAN') {$b_no_html_wan = $val if is_int($val)}
elsif ($key eq 'NO_SUDO') {$b_no_sudo = $val if is_int($val)}
elsif ($key eq 'PARTITION_SORT') {$show{'partition-sort'} = $val if ($val =~ /^(dev-base|fs|id|label|percent-used|size|uuid|used)$/) }
elsif ($key eq 'PS_COUNT') {$ps_count = $val if is_int($val) }
elsif ($key eq 'SENSORS_CPU_NO') {$sensors_cpu_nu = $val if is_int($val)}
- elsif ($key eq 'SHOW_HOST' || $key eq 'B_SHOW_HOST') { $show{'host'} = $val if is_int($val)}
+ elsif ($key eq 'SENSORS_EXCLUDE') {@sensors_exclude = split /\s*,\s*/, $val if $val}
+ elsif ($key eq 'SENSORS_USE') {@sensors_use = split /\s*,\s*/, $val if $val}
+ elsif ($key eq 'SHOW_HOST' || $key eq 'B_SHOW_HOST') {
+ if (is_int($val)){
+ $show{'host'} = $val;
+ $show{'no-host'} = 1 if !$show{'host'};
+ }
+ }
elsif ($key eq 'USB_SYS') {$b_usb_sys = $val if is_int($val)}
elsif ($key eq 'WAN_IP_URL') {
if ($val =~ /^(ht|f)tp[s]?:\//i){
@@ -1182,7 +1251,7 @@ sub log_data {
# print "1: $one 2: $two 3: $three\n";
if ($one eq 'fs') {
if (ref $three eq 'ARRAY'){
- my @temp = @$three;
+ # my @temp = @$three;
# print Data::Dumper::Dumper \@$three;
$args = "\n${spacer}Args: " . joiner($three, '; ', 'unset');
}
@@ -1435,7 +1504,6 @@ sub audio_data {
else {
$data{'proc-asound-codecs'} = undef;
}
-
write_data(\%data,'audio');
@files = (
'/proc/asound/cards',
@@ -1555,7 +1623,13 @@ sub display_data {
else {
@files = ('/xorg-conf-d');
}
- push (@files, $files{'xorg-log'});
+ # keep this updated to handle all possible locations we know about for Xorg.0.log
+ # not using $system_files{'xorg-log'} for now though it would be best to know what file is used
+ main::set_xorg_log();
+ push (@files, '/var/log/Xorg.0.log');
+ push (@files, '/var/lib/gdm/.local/share/xorg/Xorg.0.log');
+ push (@files, $ENV{'HOME'} . '/.local/share/xorg/Xorg.0.log');
+ push (@files, $system_files{'xorg-log'}) if $system_files{'xorg-log'};
push (@files, '/etc/X11/xorg.conf');
copy_files(\@files,'display-xorg');
print "Collecting X, xprop, glxinfo, xrandr, xdpyinfo data, wayland, weston...\n";
@@ -1608,6 +1682,7 @@ sub display_data {
['plasmashell','--version'],
['vainfo',''],
['vdpauinfo',''],
+ ['vulkaninfo',''],
['weston-info',''],
['wmctrl','-m'],
['weston','--version'],
@@ -1675,7 +1750,7 @@ sub system_data {
my %data = (
'cc' => $ENV{'CC'},
# @(#)MIRBSD KSH R56 2018/03/09: ksh and mksh
- 'ksh-version' => system('echo -n $KSH_VERSION'), # shell, not env, variable
+ 'ksh-version' => system('ksh -c \'printf %s "$KSH_VERSION"\''), # shell, not env, variable
'manpath' => $ENV{'MANPATH'},
'path' => $ENV{'PATH'},
'xdg-config-home' => $ENV{'XDG_CONFIG_HOME'},
@@ -1721,6 +1796,8 @@ sub system_data {
# fdisk <disk>
@cmds = (
['clang','--version'],
+ # only for prospective ram feature data collection: requires i2c-tools and module eeprom loaded
+ ['decode-dimms',''],
['dmidecode',''],
['dmesg',''],
['gcc','--version'],
@@ -1754,6 +1831,8 @@ sub system_data {
['rc-status','-l'],
['rc-status','-r'],
['sensors',''],
+ ['sensors','-j'],
+ ['sensors','-u'],
# leaving this commented out to remind that some systems do not
# support strings --version, but will just simply hang at that command
# which you can duplicate by simply typing: strings then hitting enter.
@@ -1820,8 +1899,8 @@ sub run_self {
my $i = ($option eq 'main-full')? ' -i' : '';
my $z = ($debugger{'z'}) ? ' -z' : '';
my $iz = "$i$z";
- $iz =~ s/[\s\-]//g;
- my $cmd = "$self_path/$self_name -FRfrploudmaxxx$i$z --usb --slots --debug 10 -y 120 > $data_dir/$self_name-FRfrploudmaxxx$iz-usb-slots-y120.txt 2>&1";
+ $iz =~ s/[\s-]//g;
+ my $cmd = "$self_path/$self_name -FRfJrploudmaxxx$i$z --slots --debug 10 -y 120 > $data_dir/$self_name-FRfJrploudmaxxx$iz-slots-y120.txt 2>&1";
system($cmd);
copy($log_file, "$data_dir") or main::error_handler('copy-failed', "$log_file", "$!");
system("$self_path/$self_name --recommends -y 120 > $data_dir/$self_name-recommends-120.txt 2>&1");
@@ -2216,7 +2295,10 @@ sub download_file {
sub get_file {
my ($type, $url, $file) = @_;
- my $response = HTTP::Tiny->new->get($url);
+ my $tiny = HTTP::Tiny->new;
+ # note: default is no verify, so default here actually is to verify unless overridden
+ $tiny->verify_SSL => 1 if !$dl{'no-ssl-opt'};
+ my $response = $tiny->get($url);
my $return = 1;
my $debug = 0;
my $fh;
@@ -2841,8 +2923,8 @@ sub item_data {
'rpm' => 'util-linux-ng',
}),
'lsusb' => ({
- 'info' => '-A usb audio; -N usb networking; --usb (optional)',
- 'info-bsd' => '-A; -N; --usb. Alternate to usbdevs',
+ 'info' => '-A usb audio; -J (optional); -N usb networking',
+ 'info-bsd' => '-A; -J; -N. Alternate to usbdevs',
'apt' => 'usbutils',
'pacman' => 'usbutils',
'rpm' => 'usbutils',
@@ -2869,11 +2951,11 @@ sub item_data {
'rpm' => 'lm-sensors',
}),
'smartctl' => ({
- 'info' => '-Dxx rotation (alt), type, smart',
- 'info-bsd' => '-Dx rotation (alt), type, smart',
- 'apt' => '',
- 'pacman' => '',
- 'rpm' => '',
+ 'info' => '-Da advanced data',
+ 'info-bsd' => '-Da advanced data',
+ 'apt' => 'smartmontools',
+ 'pacman' => 'smartmontools',
+ 'rpm' => 'smartmontools',
}),
'strings' => ({
'info' => '-I sysvinit version',
@@ -2919,7 +3001,7 @@ sub item_data {
}),
'usbdevs' => ({
'info' => '',
- 'info-bsd' => '-A; -N; --usb;',
+ 'info-bsd' => '-A; -J; -N;',
'apt' => 'usbutils',
'pacman' => 'usbutils',
'rpm' => 'usbutils',
@@ -3124,8 +3206,8 @@ sub compare_versions {
elsif ($two && !$one){return $two;}
elsif (!$one && !$two){return}
my ($pad1,$pad2) = ('','');
- my (@temp1) = split /[\.\-_]/, $one;
- my (@temp2) = split /[\.\-_]/, $two;
+ my (@temp1) = split /[._-]/, $one;
+ my (@temp2) = split /[._-]/, $two;
@temp1 = map {$_ = sprintf("%04s", $_);$_ } @temp1;
@temp2 = map {$_ = sprintf("%04s", $_);$_ } @temp2;
$pad1 = join '', @temp1;
@@ -3218,10 +3300,8 @@ sub joiner {
# returns array of: 0: program print name 1: program version
# args: 1: program values id 2: program version string
-# 3: extra level. Note that StartClient runs BEFORE -x levels are set!
+# 3: $extra level. Note that StartClient runs BEFORE -x levels are set!
# Only use this function when you only need the name/version data returned
-# Important: all tests that use this must explicitly have program_values
-# set for each item tested for!!
sub program_data {
eval $start if $b_log;
my ($values_id,$version_id,$level) = @_;
@@ -3229,287 +3309,328 @@ sub program_data {
$level = 0 if ! $level;
#print "val_id: $values_id ver_id:$version_id lev:$level ex:$extra\n";
$version_id = $values_id if ! $version_id;
- @data = main::program_values($values_id);
- $program_data[0] = $data[3];
- # programs that have no version method return 0 0 for index 1 and 2
- if ( $extra >= $level && $data[1] && $data[2]){
- $program_data[1] = main::program_version($version_id,$data[0],$data[1],$data[2],$data[5],$data[6]);
+ @data = program_values($values_id);
+ if ($data[3]){
+ $program_data[0] = $data[3];
+ # programs that have no version method return 0 0 for index 1 and 2
+ if ( $extra >= $level && $data[1] && $data[2]){
+ $program_data[1] = program_version($version_id,$data[0],
+ $data[1],$data[2],$data[5],$data[6],$data[7],$data[8]);
+ }
}
- $program_data[1] = '' if ! defined $program_data[1];
+ $program_data[0] ||= '';
+ $program_data[1] ||= '';
eval $end if $b_log;
return @program_data;
}
+# it's almost 1000 times slower to load these each time program_values is called!!
+sub set_program_values {
+ %program_values = (
+ ## Clients ##
+ 'bitchx' => ['bitchx',2,'','BitchX',1,0,0,'',''],# special
+ 'finch' => ['finch',2,'-v','Finch',1,1,0,'',''],
+ 'gaim' => ['[0-9.]+',2,'-v','Gaim',0,1,0,'',''],
+ 'ircii' => ['[0-9.]+',3,'-v','ircII',1,1,0,'',''],
+ 'irssi' => ['irssi',2,'-v','Irssi',1,1,0,'',''],
+ 'irssi-text' => ['irssi',2,'-v','Irssi',1,1,0,'',''],
+ 'konversation' => ['konversation',2,'-v','Konversation',0,0,0,'',''],
+ 'kopete' => ['Kopete',2,'-v','Kopete',0,0,0,'',''],
+ 'kvirc' => ['[0-9.]+',2,'-v','KVIrc',0,0,1,'',''], # special
+ 'pidgin' => ['[0-9.]+',2,'-v','Pidgin',0,1,0,'',''],
+ 'quassel' => ['',1,'-v','Quassel [M]',0,0,0,'',''], # special
+ 'quasselclient' => ['',1,'-v','Quassel',0,0,0,'',''],# special
+ 'quasselcore' => ['',1,'-v','Quassel (core)',0,0,0,'',''],# special
+ 'gribble' => ['^Supybot',2,'--version','Gribble',1,0,0,'',''],# special
+ 'limnoria' => ['^Supybot',2,'--version','Limnoria',1,0,0,'',''],# special
+ 'supybot' => ['^Supybot',2,'--version','Supybot',1,0,0,'',''],# special
+ 'weechat' => ['[0-9.]+',1,'-v','WeeChat',1,0,0,'',''],
+ 'weechat-curses' => ['[0-9.]+',1,'-v','WeeChat',1,0,0,'',''],
+ 'xchat-gnome' => ['[0-9.]+',2,'-v','X-Chat-Gnome',1,1,0,'',''],
+ 'xchat' => ['[0-9.]+',2,'-v','X-Chat',1,1,0,'',''],
+ ## Desktops / wm / compositors ##
+ '3dwm' => ['^3dwm',0,'0','3Dwm',0,1,0,'',''], # unverified
+ '9wm' => ['^9wm',3,'-version','9wm',0,1,0,'',''],
+ 'aewm' => ['^aewm',3,'--version','aewm',0,1,0,'',''],
+ 'aewm++' => ['^Version:',2,'-version','aewm++',0,1,0,'',''],
+ 'afterstep' => ['^afterstep',3,'--version','AfterStep',0,1,0,'',''],
+ 'amiwm' => ['^amiwm',0,'0','AmiWM',0,1,0,'',''], # no version
+ 'antiwm' => ['^antiwm',0,'0','AntiWM',0,1,0,'',''], # no version known
+ 'asc' => ['^asc',0,'0','asc',0,1,0,'',''],
+ 'awesome' => ['^awesome',2,'--version','awesome',0,1,0,'',''],
+ 'beryl' => ['^beryl',0,'0','Beryl',0,1,0,'',''], # unverified; legacy
+ 'blackbox' => ['^Blackbox',2,'--version','Blackbox',0,1,0,'',''],
+ 'bspwm' => ['^\S',1,'-v','bspwm',0,1,0,'',''],
+ 'budgie-desktop' => ['^budgie-desktop',2,'--version','Budgie',0,1,0,'',''],
+ 'budgie-wm' => ['^budgie',0,'0','budgie-wm',0,1,0,'',''],
+ 'cagebreak' => ['^Cagebreak',3,'-v','Cagebreak',0,1,0,'',''],
+ 'calmwm' => ['^calmwm',0,'0','CalmWM',0,1,0,'',''], # unverified
+ 'cinnamon' => ['^cinnamon',2,'--version','Cinnamon',0,1,0,'',''],
+ 'clfswm' => ['^clsfwm',0,'0','clfswm',0,1,0,'',''], # no version
+ 'compiz' => ['^compiz',2,'--version','Compiz',0,1,0,'',''],
+ 'compton' => ['^\d',1,'--version','Compton',0,1,0,'',''],
+ 'cwm' => ['^cwm',0,'0','CWM',0,1,0,'',''], # no version
+ 'dcompmgr' => ['^dcompmgr',0,'0','dcompmgr',0,1,0,'',''], # unverified
+ 'deepin' => ['^Version',2,'file','Deepin',0,100,'=','','/etc/deepin-version'], # special
+ 'deepin-metacity' => ['^metacity',2,'--version','Deepin-Metacity',0,1,0,'',''],
+ 'deepin-mutter' => ['^mutter',2,'--version','Deepin-Mutter',0,1,0,'',''],
+ 'deepin-wm' => ['^gala',0,'0','DeepinWM',0,1,0,'',''], # no version
+ 'dwc' => ['^dwc',0,'0','dwc',0,1,0,'',''], # unverified
+ 'dwm' => ['^dwm',1,'-v','dwm',0,1,1,'^dwm-',''],
+ 'echinus' => ['^echinus',1,'-v','echinus',0,1,1,'',''], # echinus-0.4.9 (c)...
+ # only listed here for compositor values, version data comes from xprop
+ 'enlightenment' => ['^enlightenment',0,'0','enlightenment',0,1,0,'',''], # no version, yet?
+ 'evilwm' => ['evilwm',3,'-V','evilwm',0,1,0,'',''],# might use full path in match
+ 'fireplace' => ['^fireplace',0,'0','fireplace',0,1,0,'',''], # unverified
+ 'fluxbox' => ['^fluxbox',2,'-v','Fluxbox',0,1,0,'',''],
+ 'flwm' => ['^flwm',0,'0','FLWM',0,0,1,'',''], # no version
+ 'fvwm' => ['^fvwm',2,'-version','FVWM',0,1,0,'',''],
+ 'fvwm1' => ['^Fvwm',3,'-version','FVWM1',0,1,1,'',''],
+ 'fvwm2' => ['^fvwm',2,'--version','fVWM2',0,1,0,'',''],
+ 'fvwm3' => ['^fvwm',2,'--version','fVWM3',0,1,0,'',''],
+ 'fvwm95' => ['^fvwm',2,'--version','FVWM95',0,1,1,'',''],
+ 'fvwm-crystal' => ['^fvwm',2,'--version','FVWM-Crystal',0,0,0,'',''], # for print name fvwm
+ 'gala' => ['^gala',0,'0','gala',0,1,0,'',''], # pantheon wm: super slow result, 2, '--version' works?
+ 'glass' => ['^glass',3,'-v','Glass',0,1,0,'',''],
+ 'gnome' => ['^gnome',3,'--version','GNOME',0,1,0,'',''], # no version, print name
+ 'gnome-about' => ['^gnome',3,'--version','GNOME',0,1,0,'',''],
+ 'gnome-shell' => ['^gnome',3,'--version','gnome-shell',0,1,0,'',''],
+ 'grefson' => ['^grefson',0,'0','grefson',0,1,0,'',''], # unverified
+ 'hackedbox' => ['^hackedbox',2,'-version','HackedBox',0,1,0,'',''], # unverified, assume blackbox
+ # note, herbstluftwm when launched with full path returns full path in version string
+ 'herbstluftwm' => ['herbstluftwm',2,'--version','herbstluftwm',0,1,0,'',''],
+ 'i3' => ['^i3',3,'--version','i3',0,1,0,'',''],
+ 'icewm' => ['^icewm',2,'--version','IceWM',0,1,0,'',''],
+ 'instantwm' => ['^instantwm',1,'-v','instantWM',0,1,1,'^instantwm-?(instantos-?)?',''],
+ 'ion3' => ['^ion3',0,'--version','Ion3',0,1,0,'',''], # unverified; also shell called ion
+ 'jbwm' => ['jbwm',3,'-v','JBWM',0,1,0,'',''], # might use full path in match
+ 'jwm' => ['^jwm',2,'--version','JWM',0,1,0,'',''],
+ 'kded' => ['^KDE Development Platform:',4,'--version','KDE',0,1,0,'',''],
+ 'kded1' => ['^KDE Development Platform:',4,'--version','KDE',0,1,0,'',''],
+ 'kded2' => ['^KDE Development Platform:',4,'--version','KDE',0,1,0,'',''],
+ 'kded3' => ['^KDE Development Platform:',4,'--version','KDE',0,1,0,'',''],
+ 'kded4' => ['^KDE Development Platform:',4,'--version','KDE',0,1,0,'',''],
+ 'ksmcon' => ['^ksmcon',0,'0','ksmcon',0,1,0,'',''],# no version
+ 'kwin' => ['^kwin',0,'0','kwin',0,1,0,'',''],# no version
+ 'kwin_wayland' => ['^kwin_wayland',0,'0','kwin_wayland',0,1,0,'',''],# no version
+ 'kwin_x11' => ['^kwin_x11',0,'0','kwin_x11',0,1,0,'',''],# no version
+ 'larswm' => ['^larswm',2,'-v','larswm',0,1,1,'',''],
+ 'liri' => ['^liri',0,'0','liri',0,1,0,'',''],
+ 'lumina' => ['^\S',1,'--version','Lumina',0,1,1,'',''],
+ 'lwm' => ['^lwm',0,'0','lwm',0,1,0,'',''], # no version
+ 'lxpanel' => ['^lxpanel',2,'--version','LXDE',0,1,0,'',''],
+ # command: lxqt-panel
+ 'lxqt-panel' => ['^lxqt-panel',2,'--version','LXQt',0,1,0,'',''],
+ 'lxqt-variant' => ['^lxqt-panel',0,'0','LXQt-Variant',0,1,0,'',''],
+ 'lxsession' => ['^lxsession',0,'0','lxsession',0,1,0,'',''],
+ 'manokwari' => ['^manokwari',0,'0','Manokwari',0,1,0,'',''],
+ 'marco' => ['^marco',2,'--version','marco',0,1,0,'',''],
+ 'matchbox' => ['^matchbox',0,'0','Matchbox',0,1,0,'',''],
+ 'matchbox-window-manager' => ['^matchbox',2,'--help','Matchbox',0,0,0,'',''],
+ 'mate-about' => ['^MATE[[:space:]]DESKTOP',-1,'--version','MATE',0,1,0,'',''],
+ # note, mate-session when launched with full path returns full path in version string
+ 'mate-session' => ['mate-session',-1,'--version','MATE',0,1,0,'',''],
+ 'metacity' => ['^metacity',2,'--version','Metacity',0,1,0,'',''],
+ 'metisse' => ['^metisse',0,'0','metisse',0,1,0,'',''],
+ 'mini' => ['^Mini',5,'--version','Mini',0,1,0,'',''],
+ 'mir' => ['^mir',0,'0','mir',0,1,0,'',''],# unverified
+ 'moblin' => ['^moblin',0,'0','moblin',0,1,0,'',''],# unverified
+ 'motorcar' => ['^motorcar',0,'0','motorcar',0,1,0,'',''],# unverified
+ 'muffin' => ['^muffin',2,'--version','Muffin',0,1,0,'',''],
+ 'musca' => ['^musca',0,'-v','Musca',0,1,0,'',''], # unverified
+ 'mutter' => ['^mutter',2,'--version','Mutter',0,1,0,'',''],
+ 'mwm' => ['^mwm',0,'0','MWM',0,1,0,'',''],# no version
+ 'nawm' => ['^nawm',0,'0','nawm',0,1,0,'',''],# unverified
+ 'notion' => ['^.',1,'--version','Notion',0,1,0,'',''],
+ 'openbox' => ['^openbox',2,'--version','Openbox',0,1,0,'',''],
+ 'orbital' => ['^orbital',0,'0','orbital',0,1,0,'',''],# unverified
+ 'pantheon' => ['^pantheon',0,'0','Pantheon',0,1,0,'',''],# no version
+ 'papyros' => ['^papyros',0,'0','papyros',0,1,0,'',''],# no version
+ 'pekwm' => ['^pekwm',3,'--version','PekWM',0,1,0,'',''],
+ 'perceptia' => ['^perceptia',0,'0','perceptia',0,1,0,'',''],
+ 'picom' => ['^\S',1,'--version','Picom',0,1,0,'^v',''],
+ 'plasmashell' => ['^plasmashell',2,'--version','KDE Plasma',0,1,0,'',''],
+ 'qtile' => ['^',1,'--version','Qtile',0,1,0,'',''],
+ 'qvwm' => ['^qvwm',0,'0','qvwm',0,1,0,'',''], # unverified
+ 'razor-session' => ['^razor',0,'0','Razor-Qt',0,1,0,'',''],
+ 'ratpoison' => ['^ratpoison',2,'--version','Ratpoison',0,1,0,'',''],
+ 'rustland' => ['^rustland',0,'0','rustland',0,1,0,'',''], # unverified
+ 'sawfish' => ['^sawfish',3,'--version','Sawfish',0,1,0,'',''],
+ 'scrotwm' => ['^scrotwm.*welcome.*',5,'-v','scrotwm',0,1,1,'',''],
+ 'sommelier' => ['^sommelier',0,'0','sommelier',0,1,0,'',''], # unverified
+ 'spectrwm' => ['^spectrwm.*welcome.*wm',5,'-v','spectrwm',0,1,1,'',''],
+ # out of stump, 2 --version, but in tries to start new wm instance endless hang
+ 'stumpwm' => ['^SBCL',0,'--version','StumpWM',0,1,0,'',''], # hangs when run in wm
+ 'sway' => ['^sway',3,'-v','sway',0,1,0,'',''],
+ 'swc' => ['^swc',0,'0','swc',0,1,0,'',''], # unverified
+ 'tinywm' => ['^tinywm',0,'0','TinyWM',0,1,0,'',''], # no version
+ 'tvtwm' => ['^tvtwm',0,'0','tvtwm',0,1,0,'',''], # unverified
+ 'twin' => ['^Twin:',2,'--version','Twin',0,0,0,'',''],
+ 'twm' => ['^twm',0,'0','TWM',0,1,0,'',''], # no version
+ 'ukui' => ['^ukui-session',2,'--version','UKUI',0,1,0,'',''],
+ 'ukwm' => ['^ukwm',2,'--version','ukwm',0,1,0,'',''],
+ 'unagi' => ['^\S',1,'--version','unagi',0,1,0,'',''],
+ 'unity' => ['^unity',2,'--version','Unity',0,1,0,'',''],
+ 'unity-system-compositor' => ['^unity-system-compositor',2,'--version',
+ 'unity-system-compositor (mir)',0,0,0,'',''],
+ 'wavy' => ['^wavy',0,'0','wavy',0,1,0,'',''], # unverified
+ 'waycooler' => ['^way',3,'--version','way-cooler',0,1,0,'',''],
+ 'way-cooler' => ['^way',3,'--version','way-cooler',0,1,0,'',''],
+ 'wayfire' => ['^way',0,'0','wayfire',0,1,0,'',''], # unverified
+ 'wayhouse' => ['^wayhouse',0,'0','wayhouse',0,1,0,'',''], # unverified
+ 'westford' => ['^westford',0,'0','westford',0,1,0,'',''], # unverified
+ 'weston' => ['^weston',0,'0','weston',0,1,0,'',''], # unverified
+ 'windowlab' => ['^windowlab',2,'-about','WindowLab',0,1,0,'',''],
+ 'wm2' => ['^wm2',0,'0','wm2',0,1,0,'',''], # no version
+ 'wmaker' => ['^Window[[:space:]]*Maker',-1,'--version','WindowMaker',0,1,0,'',''],
+ 'wmii' => ['^wmii',1,'-v','wmii',0,1,0,'^wmii[234]?-',''], # wmii is wmii3
+ 'wmii2' => ['^wmii2',1,'--version','wmii2',0,1,0,'^wmii[234]?-',''],
+ 'wmx' => ['^wmx',0,'0','wmx',0,1,0,'',''], # no version
+ 'xcompmgr' => ['^xcompmgr',0,'0','xcompmgr',0,1,0,'',''], # no version
+ 'xfce4-panel' => ['^xfce4-panel',2,'--version','Xfce',0,1,0,'',''],
+ 'xfce5-panel' => ['^xfce5-panel',2,'--version','Xfce',0,1,0,'',''],
+ 'xfdesktop' => ['xfdesktop[[:space:]]version',5,'--version','Xfce',0,1,0,'',''],
+ # command: xfdesktop
+ 'xfdesktop-toolkit' => ['Built[[:space:]]with[[:space:]]GTK',4,'--version','Gtk',0,1,0,'',''],
+ 'xmonad' => ['^xmonad',2,'--version','XMonad',0,1,0,'',''],
+ 'yeahwm' => ['^yeahwm',0,'--version','YeahWM',0,1,0,'',''], # unverified
+ ## Toolkits ##
+ 'gtk-launch' => ['^\S',1,'--version','GTK',0,1,0,'',''],
+ 'qmake' => ['^^Using Qt version',4,'--version','Qt',0,0,0,'',''],
+ 'qtdiag' => ['^qt',2,'--version','Qt',0,1,0,'',''],
+ ## Display Managers (dm) ##
+ 'cdm' => ['^cdm',0,'0','CDM',0,1,0,'',''],
+ 'entrance' => ['^entrance',0,'0','Entrance',0,1,0,'',''],
+ 'gdm' => ['^gdm',2,'--version','GDM',0,1,0,'',''],
+ 'gdm3' => ['^gdm',2,'--version','GDM3',0,1,0,'',''],
+ 'kdm' => ['^kdm',0,'0','KDM',0,1,0,'',''],
+ 'ldm' => ['^ldm',0,'0','LDM',0,1,0,'',''],
+ 'lightdm' => ['^lightdm',2,'--version','LightDM',0,1,1,'',''],
+ 'lxdm' => ['^lxdm',0,'0','LXDM',0,1,0,'',''],
+ 'ly' => ['^ly',3,'--version','Ly',0,1,0,'',''],
+ 'mdm' => ['^mdm',0,'0','MDM',0,1,0,'',''],
+ 'nodm' => ['^nodm',0,'0','nodm',0,1,0,'',''],
+ 'pcdm' => ['^pcdm',0,'0','PCDM',0,1,0,'',''],
+ 'sddm' => ['^sddm',0,'0','SDDM',0,1,0,'',''],
+ 'slim' => ['slim version',3,'-v','SLiM',0,1,0,'',''],
+ 'tdm' => ['^tdm',0,'0','TDM',0,1,0,'',''],
+ 'udm' => ['^udm',0,'0','udm',0,1,0,'',''],
+ 'wdm' => ['^wdm',0,'0','WINGs DM',0,1,0,'',''],
+ 'xdm' => ['^xdm',0,'0','XDM',0,1,0,'',''],
+ 'xenodm' => ['^xenodm',0,'0','xenodm',0,1,0,'',''],
+ ## Shells - not checked: ion, eshell ##
+ ## See test_shell() for unhandled but known shells
+ 'ash' => ['',3,'pkg','ash',1,0,0,'',''], # special; dash precursor
+ 'bash' => ['^GNU[[:space:]]bash',4,'--version','Bash',1,1,0,'',''],
+ 'busybox' => ['^busybox',0,'0','BusyBox',1,0,0,'',''], # unverified, hush/ash likely
+ 'cicada' => ['^\s*version',2,'cmd','cicada',1,1,0,'',''], # special
+ 'csh' => ['^tcsh',2,'--version','csh',1,1,0,'',''], # mapped to tcsh often
+ 'dash' => ['',3,'pkg','DASH',1,0,0,'',''], # no version, pkg query
+ 'elvish' => ['^\S',1,'--version','Elvish',1,0,0,'',''],
+ 'fish' => ['^fish',3,'--version','fish',1,0,0,'',''],
+ 'fizsh' => ['^fizsh',3,'--version','FIZSH',1,0,0,'',''],
+ # ksh/lksh/loksh/mksh/posh//pdksh need to print their own $VERSION info
+ 'ksh' => ['^\S',1,'cmd','ksh',1,0,0,'^(Version|.*KSH)\s*',''], # special
+ 'ksh93' => ['^\S',1,'cmd','ksh93',1,0,0,'^(Version|.*KSH)\s*',''], # special
+ 'lksh' => ['^\S',1,'cmd','lksh',1,0,0,'^.*KSH\s*',''], # special
+ 'loksh' => ['^\S',1,'cmd','loksh',1,0,0,'^.*KSH\s*',''], # special
+ 'mksh' => ['^\S',1,'cmd','mksh',1,0,0,'^.*KSH\s*',''], # special
+ 'nash' => ['^nash',0,'0','Nash',1,0,0,'',''], # unverified; rc based [no version]
+ 'oh' => ['^oh',0,'0','Oh',1,0,0,'',''], # no version yet
+ 'oil' => ['^Oil',3,'--version','Oil',1,1,0,'',''], # could use cmd $OIL_SHELL
+ 'osh' => ['^osh',3,'--version','OSH',1,1,0,'',''], # precursor of oil
+ 'pdksh' => ['^\S',1,'cmd','pdksh',1,0,0,'^.*KSH\s*',''], # special, in ksh family
+ 'posh' => ['^\S',1,'cmd','posh',1,0,0,'',''], # special, in ksh family
+ 'tcsh' => ['^tcsh',2,'--version','tcsh',1,1,0,'',''], # enhanced csh
+ 'xonsh' => ['^xonsh',1,'--version','xonsh',1,0,0,'^xonsh[\/-]',''],
+ 'yash' => ['^Y',5,'--version','yash',1,0,0,'',''],
+ 'zsh' => ['^zsh',2,'--version','Zsh',1,0,0,'',''],
+ ## Tools ##
+ 'clang' => ['clang',3,'--version','Clang',1,0,0,'',''],
+ 'gcc' => ['^gcc',3,'--version','GCC',1,0,0,'',''],
+ 'gcc-apple' => ['Apple[[:space:]]LLVM',2,'--version','LLVM',1,0,0,'',''],
+ 'sudo' => ['^Sudo',3,'-V','Sudo',1,1,0,'',''], # sudo pre 1.7 does not have --version
+ );
+}
+
# returns array of:
# 0 - match string; 1 - search number; 2 - version string [alt: file];
# 3 - Print name; 4 - console 0/1;
# 5 - 0/1 exit version loop at 1 [alt: if version=file replace value with \s];
# 6 - 0/1 write to stderr [alt: if version=file, path for file]
+# 7 - replace regex for further cleanup; 8 - extra data
+# note: setting index 1 or 2 to 0 will trip flags to not do version
# arg: 1 - program lower case name
sub program_values {
my ($app) = @_;
my (@program_data);
- # note: setting index 1 and 2 to 0 will trip flags to not do version
- my %data = (
- ## Clients
- 'bitchx' => ['bitchx',2,'','BitchX',1,0,0],# special
- 'finch' => ['finch',2,'-v','Finch',1,1,0],
- 'gaim' => ['[0-9.]+',2,'-v','Gaim',0,1,0],
- 'ircii' => ['[0-9.]+',3,'-v','ircII',1,1,0],
- 'irssi' => ['irssi',2,'-v','Irssi',1,1,0],
- 'irssi-text' => ['irssi',2,'-v','Irssi',1,1,0],
- 'konversation' => ['konversation',2,'-v','Konversation',0,0,0],
- 'kopete' => ['Kopete',2,'-v','Kopete',0,0,0],
- 'kvirc' => ['[0-9.]+',2,'-v','KVIrc',0,0,1], # special
- 'pidgin' => ['[0-9.]+',2,'-v','Pidgin',0,1,0],
- 'quassel' => ['',1,'-v','Quassel [M]',0,0,0], # special
- 'quasselclient' => ['',1,'-v','Quassel',0,0,0],# special
- 'quasselcore' => ['',1,'-v','Quassel (core)',0,0,0],# special
- 'gribble' => ['^Supybot',2,'--version','Gribble',1,0,0],# special
- 'limnoria' => ['^Supybot',2,'--version','Limnoria',1,0,0],# special
- 'supybot' => ['^Supybot',2,'--version','Supybot',1,0,0],# special
- 'weechat' => ['[0-9.]+',1,'-v','WeeChat',1,0,0],
- 'weechat-curses' => ['[0-9.]+',1,'-v','WeeChat',1,0,0],
- 'xchat-gnome' => ['[0-9.]+',2,'-v','X-Chat-Gnome',1,1,0],
- 'xchat' => ['[0-9.]+',2,'-v','X-Chat',1,1,0],
- ## Desktops / wm / compositors
- '3dwm' => ['^3dwm',0,'0','3dwm',0,1,0], # unknown syntax
- '9wm' => ['^9wm',3,'-version','9wm',0,1,0],
- 'afterstep' => ['^afterstep',3,'--version','AfterStep',0,1,0],
- 'amiwm' => ['^amiwm',0,'0','AmiWM',0,1,0],
- 'asc' => ['^asc',0,'0','asc',0,1,0],
- 'awesome' => ['^awesome',2,'--version','Awesome',0,1,0],
- 'blackbox' => ['^Blackbox',2,'--version','Blackbox',0,1,0],
- 'bspwm' => ['^\S',1,'-v','bspwm',0,1,0],
- 'budgie' => ['^budgie-desktop',2,'--version','Budgie',0,1,0],
- 'budgie-wm' => ['^budgie',0,'0','budgie-wm',0,1,0],
- 'cinnamon' => ['^cinnamon',2,'--version','Cinnamon',0,1,0],
- 'compiz' => ['^compiz',2,'--version','Compiz',0,1,0],
- 'compton' => ['^\d',1,'--version','Compton',0,1,0],
- 'dcompmgr' => ['^dcompmgr',0,'0','dcompmgr',0,1,0],
- 'deepin' => ['^Version',2,'file','Deepin',0,'=','/etc/deepin-version'],
- 'deepin-metacity' => ['^metacity',2,'--version','Deepin-Metacity',0,1,0],
- 'deepin-mutter' => ['^mutter',2,'--version','Deepin-Mutter',0,1,0],
- 'deepin-wm' => ['^gala',0,'0','DeepinWM',0,1,0],
- 'dwc' => ['^dwc',0,'0','dwc',0,1,0],
- 'dwm' => ['^dwm',1,'-v','dwm',0,1,1],
- # only listed here for compositor values, version data comes from xprop
- 'enlightenment' => ['^enlightenment',0,'0','enlightenment',0,1,0],
- 'fireplace' => ['^fireplace',0,'0','fireplace',0,1,0],
- 'fluxbox' => ['^fluxbox',2,'-v','Fluxbox',0,1,0],
- 'flwm' => ['^flwm',0,'0','FLWM',0,0,1],
- 'fvwm' => ['^fvwm',2,'--version','FVWM',0,0,1],
- 'fvwm2' => ['^fvwm',2,'--version','FVWM2',0,0,1],
- # command: fvwm
- 'fvwm-crystal' => ['^fvwm',2,'--version','FVWM-Crystal',0,0,0],
- 'gala' => ['^gala',0,'0','gala',0,1,0], # super slow result, but 2, '--version' works?
- 'gnome-about' => ['gnome',3,'--version','Gnome',0,1,0],
- 'gnome-shell' => ['gnome',3,'--version','Gnome',0,1,0],
- 'grefson' => ['^grefson',0,'0','grefson',0,1,0],
- # note, herbstluftwm when launched with full path returns full path in version string
- 'herbstluftwm' => ['herbstluftwm',2,'--version','herbstluftwm',0,1,0],
- 'jwm' => ['^jwm',2,'--version','JWM',0,1,0],
- # i3 version 4.13 (2016-11-08) © 2009 Michael Stapelberg and contributors
- 'i3' => ['^i3',3,'--version','i3',0,1,0],
- 'icewm' => ['^icewm',2,'--version','IceWM',0,1,0],
- 'ion' => ['^ion',0,'0','Ion',0,1,0],
- 'kded' => ['^KDE Development Platform:',4,'--version','KDE',0,1,0],
- 'kded1' => ['^KDE Development Platform:',4,'--version','KDE',0,1,0],
- 'kded2' => ['^KDE Development Platform:',4,'--version','KDE',0,1,0],
- 'kded3' => ['^KDE Development Platform:',4,'--version','KDE',0,1,0],
- 'kded4' => ['^KDE Development Platform:',4,'--version','KDE',0,1,0],
- 'ksmcon' => ['^ksmcon',0,'0','ksmcon',0,1,0],
- 'kwin' => ['^kwin',0,'0','kwin',0,1,0],
- 'kwin_wayland' => ['^kwin_wayland',0,'0','kwin_wayland',0,1,0],
- 'kwin_x11' => ['^kwin_x11',0,'0','kwin_x11',0,1,0],
- 'liri' => ['^liri',0,'0','liri',0,1,0],
- 'lumina' => ['^\S',1,'--version','Lumina',0,1,1],
- 'lwm' => ['^lwm',0,'0','lwm',0,1,0],
- 'lxde' => ['^lxpanel',2,'--version','LXDE',0,1,0],
- # command: lxqt-panel
- 'lxqt' => ['^lxqt-panel',2,'--version','LXQt',0,1,0],
- 'lxqt-variant' => ['^lxqt-panel',0,'0','LXQt-Variant',0,1,0],
- 'lxsession' => ['^lxsession',0,'0','lxsession',0,1,0],
- 'ly' => ['^ly',3,'--version','Ly',0,1,0],
- 'manokwari' => ['^manokwari',0,'0','Manokwari',0,1,0],
- 'marco' => ['^marco',2,'--version','marco',0,1,0],
- 'matchbox' => ['^matchbox',0,'0','Matchbox',0,1,0],
- 'matchbox-window-manager' => ['^matchbox',2,'--help','Matchbox',0,0,0],
- 'mate-about' => ['^MATE[[:space:]]DESKTOP',-1,'--version','MATE',0,1,0],
- # note, mate-session when launched with full path returns full path in version string
- 'mate-session' => ['mate-session',-1,'--version','MATE',0,1,0],
- 'metacity' => ['^metacity',2,'--version','Metacity',0,1,0],
- 'metisse' => ['^metisse',0,'0','metisse',0,1,0],
- 'mir' => ['^mir',0,'0','mir',0,1,0],
- 'motorcar' => ['^motorcar',0,'0','motorcar',0,1,0],
- 'muffin' => ['^muffin',2,'--version','muffin',0,1,0],
- 'moblin' => ['^moblin',0,'0','moblin',0,1,0],
- 'mutter' => ['^mutter',2,'--version','mutter',0,1,0],
- 'mwm' => ['^mwm',0,'0','mwm',0,1,0],
- 'nawm' => ['^nawm',0,'0','nawm',0,1,0],
- 'notion' => ['^.',1,'--version','notion',0,1,0],
- 'openbox' => ['^openbox',2,'--version','Openbox',0,1,0],
- 'orbital' => ['^orbital',0,'0','orbital',0,1,0],
- 'pantheon' => ['^pantheon',0,'0','Pantheon',0,1,0],
- 'papyros' => ['^papyros',0,'0','papyros',0,1,0],
- 'pekwm' => ['^pekwm',3,'--version','PekWM',0,1,0],
- 'perceptia' => ['^perceptia',0,'0','perceptia',0,1,0],
- 'plasmashell' => ['^plasmashell',2,'--version','KDE Plasma',0,1,0],
- 'qtdiag' => ['^qt',2,'--version','Qt',0,1,0],
- 'qtile' => ['^qtile',0,'0','Qtile',0,0,1],
- 'razor' => ['^razor',0,'0','Razor-Qt',0,1,0],
- 'ratpoison' => ['^ratpoison',2,'--version','Ratpoison',0,1,0],
- 'rustland' => ['^rustland',0,'0','rustland',0,1,0],
- 'sawfish' => ['^sawfish',3,'--version','Sawfish',0,1,0],
- 'scrotwm' => ['^scrotwm.*welcome.*',5,'-v','Scrotwm',0,1,1],
- 'sommelier' => ['^sommelier',0,'0','sommelier',0,1,0],
- 'spectrwm' => ['^spectrwm.*welcome.*wm',5,'-v','Spectrwm',0,1,1],
- 'sway' => ['^sway',3,'-v','sway',0,1,0],
- 'swc' => ['^swc',0,'0','swc',0,1,0],
- 'tvtwm' => ['^tvtwm',0,'0','tvtwm',0,1,0],
- 'twin' => ['^Twin:',2,'--version','Twin',0,0,0],
- 'twm' => ['^twm',0,'0','twm',0,1,0],
- 'ukui' => ['^ukui-session',2,'--version','UKUI',0,1,0],
- 'ukwm' => ['^ukwm',2,'--version','ukwm',0,1,0],
- 'unagi' => ['^unagi',0,'0','unagi',0,1,0],
- 'unity' => ['^unity',2,'--version','Unity',0,1,0],
- 'unity-system-compositor' => ['^unity-system-compositor',2,'--version','unity-system-compositor (mir)',0,0,0],
- 'wavy' => ['^wavy',0,'0','wavy',0,1,0],
- 'waycooler' => ['^way',3,'--version','way-cooler',0,1,0],
- 'way-cooler' => ['^way',3,'--version','way-cooler',0,1,0],
- 'wayhouse' => ['^wayhouse',0,'0','wayhouse',0,1,0],
- 'westford' => ['^westford',0,'0','westford',0,1,0],
- 'weston' => ['^weston',0,'0','weston',0,1,0],
- 'windowlab' => ['^windowlab',2,'-about','WindowLab',0,1,0],
- 'wm2' => ['^wm2',0,'0','wm2',0,1,0],
- 'wmaker' => ['^Window[[:space:]]*Maker',-1,'--version','WindowMaker',0,1,0],
- 'wmii' => ['^wmii',0,'0','wmii',0,1,0], # note: in debian, wmii is wmii3
- 'wmii2' => ['^wmii2',1,'--version','wmii2',0,1,0],
- 'wmx' => ['^wmx',0,'0','wmx',0,1,0],
- 'xcompmgr' => ['^xcompmgr',0,'0','xcompmgr',0,1,0],
- 'xfce4-panel' => ['^xfce4-panel',2,'--version','Xfce',0,1,0],
- 'xfce5-panel' => ['^xfce5-panel',2,'--version','Xfce',0,1,0],
- 'xfdesktop' => ['xfdesktop[[:space:]]version',5,'--version','Xfce',0,1,0],
- # command: xfdesktop
- 'xfdesktop-toolkit' => ['Built[[:space:]]with[[:space:]]GTK',4,'--version','Gtk',0,1,0],
- 'xmonad' => ['^xmonad',2,'--version','XMonad',0,1,0],
- ## display managers (dm)
- 'cdm' => ['^cdm',0,'0','CDM',0,1,0],
- 'entrance' => ['^entrance',0,'0','Entrance',0,1,0],
- 'gdm' => ['^gdm',2,'--version','GDM',0,1,0],
- 'gdm3' => ['^gdm',2,'--version','GDM3',0,1,0],
- 'kdm' => ['^kdm',0,'0','KDM',0,1,0],
- 'ldm' => ['^ldm',0,'0','LDM',0,1,0],
- 'lightdm' => ['^lightdm',2,'--version','LightDM',0,1,1],
- 'lxdm' => ['^lxdm',0,'0','LXDM',0,1,0],
- 'mdm' => ['^mdm',0,'0','MDM',0,1,0],
- 'nodm' => ['^nodm',0,'0','nodm',0,1,0],
- 'pcdm' => ['^pcdm',0,'0','PCDM',0,1,0],
- 'sddm' => ['^sddm',0,'0','SDDM',0,1,0],
- 'slim' => ['slim version',3,'-v','SLiM',0,1,0],
- 'tdm' => ['^tdm',0,'0','TDM',0,1,0],
- 'wdm' => ['^wdm',0,'0','WINGs DM',0,1,0],
- 'xdm' => ['^xdm',0,'0','XDM',0,1,0],
- 'xenodm' => ['^xenodm',0,'0','xenodm',0,1,0],
- ## Shells
- 'ash' => ['^ash',0,'0','ash',1,0,0],
- 'bash' => ['^GNU[[:space:]]bash,[[:space:]]version',4,'--version','Bash',1,0,0],
- 'csh' => ['^tcsh',2,'--version','csh',1,0,0],
- 'dash' => ['dash',3,'--version','Dash',1,0,0], # no version, uses dpkg query, sigh
- # ksh/lksh/mksh/pdksh can't be handled with version but we'll use the search string to
- # trigger version return and tests
- 'ksh' => ['ksh',5,'-v','ksh',1,0,0],
- 'lksh' => ['ksh',5,'-v','lksh',1,0,0],
- 'loksh' => ['ksh',5,'-v','lksh',1,0,0],
- 'mksh' => ['ksh',5,'-v','mksh',1,0,0],
- 'pdksh' => ['ksh',5,'-v','pdksh',1,0,0],
- 'tcsh' => ['^tcsh',2,'--version','tcsh',1,0,0],
- 'zsh' => ['^zsh',2,'--version','zsh',1,0,0],
- ## Tools
- 'clang' => ['clang',3,'--version','Clang',1,0,0],
- 'gcc' => ['^gcc',3,'--version','GCC',1,0,0],
- 'gcc-apple' => ['Apple[[:space:]]LLVM',2,'--version','LLVM',1,0,0],
- 'sudo' => ['^Sudo',3,'-V','Sudo',1,1,0], # sudo pre 1.7 does not have --version
- );
- if ( defined $data{$app} ){
- my $ref = $data{$app};
- @program_data = @$ref;
+ set_program_values() if !%program_values;
+ if ( defined $program_values{$app} ){
+ @program_data = @{$program_values{$app}};
}
- #my $debug = main::Dumper \@program_data;
- main::log_data('dump',"Program Data",\@program_data) if $b_log;
+ #my $debug = Dumper \@program_data;
+ log_data('dump',"Program Data",\@program_data) if $b_log;
return @program_data;
}
# args: 1 - desktop/app command for --version; 2 - search string;
# 3 - space print number; 4 - [optional] version arg: -v, version, etc
# 5 - [optional] exit first find 0/1; 6 - [optional] 0/1 stderr output
+# 7 - replace regex; 8 - extra data
sub program_version {
eval $start if $b_log;
- my ($app, $search, $num,$version,$exit,$stderr) = @_;
- my ($cmd,$line,$output);
+ my ($app,$search,$num,$version,$exit,$stderr,$replace,$extra) = @_;
+ my ($b_no_space,$cmd,$line,$output);
my $version_nu = '';
my $count = 0;
- #print "app:$app\n";
+ my $app_name = $app;
+ $app_name =~ s%^.*/%%;
+ # print "app: $app :: appname: $app_name\n";
$exit ||= 100; # basically don't exit ever
$version ||= '--version';
# adjust to array index, not human readable
$num-- if (defined $num && $num > 0);
- # ksh: Version JM 93t+ 2010--03-05
- # mksh: @(#)MIRBSD KSH R56 2018/03/09
- # loksh: @(#)PD KSH v5.2.14 99/07/13.2
- # --version opens a new ksh, sigh... This so far does not work
- # because the ENV/Shell variable is not visible in subshells
- if ($search eq 'ksh'){
- my $ksh = system('echo -n $KSH_VERSION');
- if ( $ksh ){
- my @temp = split /\s+/, $ksh;
- if ($temp[2]){
- $temp[2] =~ s/^v//i; # trim off leading v
- log_data('data',"Program *ksh array: @temp version: $temp[2]") if $b_log;
- return $temp[2];
- }
- }
- return 0;
- }
# konvi in particular doesn't like using $ENV{'PATH'} as set, so we need
# to always assign the full path if it hasn't already been done
- if ( $app !~ /^\// ){
+ if ( $version ne 'file' && $app !~ /^\// ){
if (my $program = check_program($app) ){
$app = $program;
}
else {
- log_data('data',"$app not found in path.");
+ log_data('data',"$app not found in path.") if $b_log;
return 0;
}
}
+ if ($version eq 'file'){
+ return 0 unless $extra && -r $extra;
+ my @data = reader($extra,'strip');
+ @data = map {s/$stderr/ /;$_} @data if $stderr; # $stderr is the splitter
+ $output = join "\n",@data;
+ }
+ # These will mostly be shells that require running the shell command -c to get info data
+ elsif ($version eq 'cmd'){
+ ($cmd,$b_no_space) = program_version_cmd($app,$app_name,$extra);
+ return 0 if !$cmd;
+ }
+ # slow: use pkg manager to get version, avoid unless you really want version
+ elsif ($version eq 'pkg'){
+ ($cmd,$search) = program_version_pkg($app_name);
+ return 0 if !$cmd;
+ }
# note, some wm/apps send version info to stderr instead of stdout
- if ( $stderr && $stderr ne 'file' ) {
+ elsif ($stderr) {
$cmd = "$app $version 2>&1";
}
-# elsif ( $app eq 'csh' ){
-# $app = 'tcsh';
-# }
- # quick debian/buntu hack until I find a universal way to get version for these
- elsif ( $app =~ /dash$/ ){
- $app =~ s/^.*\///;
- $cmd = "dpkg -l $app 2>/dev/null";
- }
else {
$cmd = "$app $version 2>/dev/null";
}
log_data('data',"version: $version num: $num search: $search command: $cmd") if $b_log;
# special case, in rare instances version comes from file
- if ($version eq 'file' && $stderr){
- return 0 unless -r $stderr;
- my @data = reader($stderr,'strip');
- @data = map {s/$exit/ /;$_} @data if $exit;
- $output = join "\n",@data;
- $exit = 100;
- }
- else {
+ if ($version ne 'file'){
$output = qx($cmd);
+ log_data('data',"output: $output") if $b_log;
}
- # print "$cmd : $output\n";
+ # print "cmd: $cmd\noutput:\n$output\n";
# sample: dwm-5.8.2, ©.. etc, why no space? who knows. Also get rid of v in number string
# xfce, and other, output has , in it, so dump all commas and parentheses
if ($output){
@@ -3519,7 +3640,9 @@ sub program_version {
last if $count > $exit;
if ( $_ =~ /$search/i ) {
$_ = trimmer($_);
- # print "$_ ::$num\n";
+ # print "loop: $_ :: num: $num\n";
+ $_ =~ s/$replace//i if $replace;
+ $_ =~ s/\s/_/g if $b_no_space; # needed for some items with version > 1 word
my @data = split /\s+/, $_;
$version_nu = $data[$num];
last if ! defined $version_nu;
@@ -3527,7 +3650,7 @@ sub program_version {
# breaks version detection. A quick fix attempt is to just add 1 to $num
# to get the next value.
$version_nu = $data[$num+1] if $data[$num+1] && $version_nu =~ /version/i;
- $version_nu =~ s/(\([^)]+\)|,|"|dwm-|wmii2-|wmii-|\||\(|\))//g if $version_nu;
+ $version_nu =~ s/(\([^)]+\)|,|"|\||\(|\))//g if $version_nu;
# trim off leading v but only when followed by a number
$version_nu =~ s/^v([0-9])/$1/i if $version_nu;
# print "$version_nu\n";
@@ -3543,6 +3666,48 @@ sub program_version {
}
# print program_version('bash', 'bash', 4) . "\n";
+# returns ($cmdd, $b_no_space)
+# ksh: Version JM 93t+ 2010-03-05 [OR] Version A 2020.0.0
+# mksh: @(#)MIRBSD KSH R56 2018/03/09; lksh/pdksh: @(#)LEGACY KSH R56 2018/03/09
+# loksh: @(#)PD KSH v5.2.14 99/07/13.2; posh: 0.13.2
+sub program_version_cmd {
+ eval $start if $b_log;
+ my ($app,$app_name,$extra) = @_;
+ my @data = ('',0);
+ if ($app_name eq 'cicada') {
+ $data[0] = $app . ' -c "' . $extra . '" 2>/dev/null';}
+ elsif ($app_name =~ /^(|l|lo|m|pd)ksh(93)?$/){
+ $data[0] = $app . ' -c \'printf %s "$KSH_VERSION"\' 2>/dev/null';
+ $data[1] = 1;}
+ elsif ($app_name eq 'posh'){
+ $data[0] = $app . ' -c \'printf %s "$POSH_VERSION"\' 2>/dev/null'}
+ # print "$data[0] :: $data[1]\n";
+ eval $end if $b_log;
+ return @data;
+}
+# returns $cmd, $search
+sub program_version_pkg {
+ eval $start if $b_log;
+ my ($app) = @_;
+ my ($program,@data);
+ # note: version $num is 3 in dpkg-query/pacman/rpm, which is convenient
+ if ($program = check_program('dpkg-query') ){
+ $data[0] = "$program -W -f='\${Package}\tversion\t\${Version}\n' $app 2>/dev/null";
+ $data[1] = "^$app\\b";
+ }
+ elsif ($program = check_program('pacman') ){
+ $data[0] = "$program -Q --info $app 2>/dev/null";
+ $data[1] = '^Version';
+ }
+ elsif ($program = check_program('rpm') ){
+ $data[0] = "$program -qi --nodigest --nosignature $app 2>/dev/null";
+ $data[1] = '^Version';
+ }
+ # print "$data[0] :: $data[1]\n";
+ eval $end if $b_log;
+ return @data;
+}
+
# arg: 1 - full file path, returns array of file lines.
# 2 - optionsl, strip and clean data
# note: chomp has to chomp the entire action, not just <$fh>
@@ -3612,7 +3777,7 @@ sub writer {
sub get_defaults {
my ($type) = @_;
my %defaults = (
- 'ftp-upload' => 'ftp.techpatterns.com/incoming',
+ 'ftp-upload' => 'ftp.smxi.org/incoming',
'inxi-branch-1' => 'https://github.com/smxi/inxi/raw/one/',
'inxi-branch-2' => 'https://github.com/smxi/inxi/raw/two/',
'inxi-dev' => 'https://smxi.org/in/',
@@ -3818,8 +3983,8 @@ sub get_options{
eval $start if $b_log;
my (@args) = @_;
$show{'short'} = 1;
- my ($b_downloader,$b_help,$b_no_man,$b_no_man_force,$b_recommends,$b_updater,$b_version,
- $b_use_man,$self_download, $download_id);
+ my ($b_downloader,$b_help,$b_no_man,$b_no_man_force,$b_sensors_default,
+ $b_recommends,$b_updater,$b_version,$b_use_man,$self_download, $download_id);
GetOptions (
'a|admin' => sub {
$b_admin = 1;},
@@ -3833,6 +3998,7 @@ sub get_options{
$show{'raid-basic'} = 1;
$show{'disk-total'} = 1;
$show{'graphic'} = 1;
+ $show{'graphic-basic'} = 1;
$show{'info'} = 1;
$show{'machine'} = 1;
$show{'network'} = 1;
@@ -3873,6 +4039,7 @@ sub get_options{
$show{'cpu'} = 1;
$show{'disk'} = 1;
$show{'graphic'} = 1;
+ $show{'graphic-basic'} = 1;
$show{'info'} = 1;
$show{'machine'} = 1;
$show{'network'} = 1;
@@ -3880,10 +4047,14 @@ sub get_options{
$show{'partition'} = 1;
$show{'raid'} = 1;
$show{'sensor'} = 1;
+ $show{'swap'} = 1;
$show{'system'} = 1; },
'G|graphics|graphic' => sub {
$show{'short'} = 0;
- $show{'graphic'} = 1; },
+ $show{'graphic'} = 1;
+ $show{'graphic-basic'} = 1; },
+ 'h|help|?' => sub {
+ $b_help = 1; },
'i|ip' => sub {
$show{'short'} = 0;
$show{'ip'} = 1;
@@ -3893,6 +4064,12 @@ sub get_options{
'I|info' => sub {
$show{'short'} = 0;
$show{'info'} = 1; },
+ 'j|swap|swaps' => sub {
+ $show{'short'} = 0;
+ $show{'swap'} = 1; },
+ 'J|usb' => sub {
+ $show{'short'} = 0;
+ $show{'usb'} = 1; },
'l|labels|label' => sub {
$show{'short'} = 0;
$show{'label'} = 1;
@@ -3988,9 +4165,6 @@ sub get_options{
else {
error_handler('bad-arg',$opt,$arg);
} },
- 'usb' => sub {
- $show{'short'} = 0;
- $show{'usb'} = 1; },
'u|uuid' => sub {
$show{'short'} = 0;
$show{'partition'} = 1;
@@ -4006,6 +4180,7 @@ sub get_options{
$show{'cpu-basic'} = 1;
$show{'disk-total'} = 1;
$show{'graphic'} = 1;
+ $show{'graphic-basic'} = 1;
$show{'info'} = 1;
$show{'system'} = 1;
}
@@ -4033,6 +4208,7 @@ sub get_options{
$show{'ram'} = 1;
$show{'raid'} = 1;
$show{'sensor'} = 1;
+ $show{'swap'} = 1;
$show{'uuid'} = 1;
}
if ($arg >= 6 ){
@@ -4063,11 +4239,13 @@ sub get_options{
else {
error_handler('bad-arg',$opt,$arg);
} },
+ 'V|version' => sub {
+ $b_version = 1 },
'w|weather' => sub {
my ($opt) = @_;
$show{'short'} = 0;
$b_downloader = 1;
- if ( $b_weather ){
+ if ( $use{'weather'} ){
$show{'weather'} = 1;
}
else {
@@ -4079,7 +4257,7 @@ sub get_options{
$arg =~ s/\s//g;
$show{'short'} = 0;
$b_downloader = 1;
- if ( $b_weather ){
+ if ( $use{'weather'} ){
if ($arg){
$show{'weather'} = 1;
$show{'weather-location'} = $arg;
@@ -4124,17 +4302,27 @@ sub get_options{
} },
'y|width:i' => sub {
my ($opt, $arg) = @_;
- $arg = 2000 if defined $arg && $arg == -1;
- if ( $arg =~ /\d/ && $arg >= 80 ){
+ if( defined $arg && $arg == -1){
+ $arg = 2000;
+ }
+ # note: :i creates 0 value if not supplied even though means optional
+ elsif (!$arg){
+ $arg = 80;
+ }
+ if ( $arg =~ /\d/ && ($arg == 1 || $arg >= 80) ){
set_display_width($arg);
}
else {
error_handler('bad-arg', $opt, $arg);
} },
'z|filter' => sub {
- $show{'filter'} = 1; },
+ $use{'filter'} = 1; },
+ 'filter-label' => sub {
+ $use{'filter-label'} = 1; },
'Z|filter-override' => sub {
- $show{'filter-override'} = 1; },
+ $use{'filter-override'} = 1; },
+ 'filter-uuid' => sub {
+ $use{'filter-uuid'} = 1; },
## Start non data options
'alt:i' => sub {
my ($opt,$arg) = @_;
@@ -4219,6 +4407,8 @@ sub get_options{
$debugger{'test-1'} = 1; },
'debug-z' => sub {
$debugger{'z'} = 1 },
+ 'dig' => sub {
+ $b_skip_dig = 0; },
'display:s' => sub {
my ($opt,$arg) = @_;
if ($arg =~ /^:?([0-9]+)?$/){
@@ -4266,10 +4456,11 @@ sub get_options{
else {
error_handler('bad-arg', $opt, $arg);
}},
- 'h|help|?' => sub {
- $b_help = 1; },
'host|hostname' => sub {
- $show{'host'} = 1 },
+ $show{'host'} = 1;
+ $show{'no-host'} = 0},
+ 'html-wan' => sub {
+ $b_no_html_wan = 0; },
'indent-min:i' => sub {
my ($opt,$arg) = @_;
if ($arg =~ /^\d+$/){
@@ -4297,8 +4488,13 @@ sub get_options{
else {
error_handler('bad-arg', $opt, $arg);
}},
+ 'no-dig' => sub {
+ $b_skip_dig = 1; },
'no-host|no-hostname' => sub {
- $show{'host'} = 0 },
+ $show{'host'} = 0 ;
+ $show{'no-host'} = 1},
+ 'no-html-wan' => sub {
+ $b_no_html_wan= 1;},
'no-man' => sub {
$b_no_man_force = 0; },
'no-ssl' => sub {
@@ -4322,6 +4518,24 @@ sub get_options{
$b_ppc = 1 },
'recommends' => sub {
$b_recommends = 1; },
+ 'sensors-default' => sub {
+ $b_sensors_default = 1; },
+ 'sensors-exclude:s' => sub {
+ my ($opt,$arg) = @_;
+ if ($arg){
+ @sensors_exclude = split /\s*,\s*/, $arg;
+ }
+ else {
+ error_handler('bad-arg',$opt,$arg);
+ }},
+ 'sensors-use:s' => sub {
+ my ($opt,$arg) = @_;
+ if ($arg){
+ @sensors_use = split /\s*,\s*/, $arg;
+ }
+ else {
+ error_handler('bad-arg',$opt,$arg);
+ }},
'sparc' => sub {
$b_sparc = 1; },
'sys-debug' => sub {
@@ -4331,7 +4545,7 @@ sub get_options{
'U|update:s' => sub { # 1,2,3 OR http://myserver/path/inxi
my ($opt,$arg) = @_;
$b_downloader = 1;
- if ( $b_update ){
+ if ( $use{'update'} ){
$b_updater = 1;
if (!$arg && $self_name eq 'pinxi'){
$b_man = 1;
@@ -4370,8 +4584,6 @@ sub get_options{
$b_usb_sys = 1 },
'usb-tool' => sub {
$b_usb_tool = 1 },
- 'V|version' => sub {
- $b_version = 1 },
'wan-ip-url:s' => sub {
my ($opt,$arg) = @_;
if ($arg && $arg =~ /^(f|ht)tp[s]?:\/\//){
@@ -4390,7 +4602,8 @@ sub get_options{
## run all these after so that we can change widths, downloaders, etc
eval $end if $b_log;
CheckRecommends::run() if $b_recommends;
- set_downloader() if $b_downloader || $wan_url; # sets for either config or arg here
+ set_downloader() if $b_downloader || $wan_url || ($b_skip_dig && $show{'ip'}); # sets for either config or arg here
+ set_xorg_log() if $show{'graphic'};
show_version() if $b_version;
show_options() if $b_help;
$b_man = 0 if (!$b_use_man || $b_no_man_force);
@@ -4400,12 +4613,21 @@ sub get_options{
error_handler('bad-arg', '--output', '--output-file not provided');
}
}
+ $show{'graphic-basic'} = 0 if $b_admin;
+ if ($b_sensors_default){
+ @sensors_exclude = ();
+ @sensors_use = ();
+ }
$b_block_tool = 1 if ( $b_admin && ($show{'partition'} || $show{'partition-full'} ));
- $b_sudo = 1 if ( $show{'unmounted'} || ($extra > 0 && $show{'disk'}) );
+ set_sudo() if ( $show{'unmounted'} || ($extra > 0 && $show{'disk'}) );
+ $extra = 3 if $b_admin;
+ $use{'filter'} = 0 if $use{'filter-override'};
# override for things like -b or -v2 to -v3
$show{'cpu-basic'} = 0 if $show{'cpu'};
$show{'optical-basic'} = 0 if $show{'optical'};
$show{'partition'} = 0 if $show{'partition-full'};
+ $show{'host'} = 0 if $show{'no-host'};
+ $show{'host'} = 1 if ($show{'host'} || (!$use{'filter'} && !$show{'no-host'}));
if ($show{'disk'} || $show{'optical'} ){
$show{'disk-basic'} = 0;
$show{'disk-total'} = 0;
@@ -4417,22 +4639,22 @@ sub get_options{
if ($show{'audio'} || $show{'graphic'} || $show{'network'} || $show{'raid'} || $show{'raid-forced'} ){
$b_pci = 1;
}
- if ($show{'usb'} || $show{'audio'} || $show{'network'} ){
+ if ($show{'usb'} || $show{'audio'} || $show{'graphic'} || $show{'network'} ){
$b_usb = 1;
}
if ($bsd_type && ($show{'short'} || $show{'system'} || $show{'battery'} || $show{'cpu'} || $show{'cpu-basic'} ||
$show{'info'} || $show{'machine'} || $show{'process'} || $show{'ram'} || $show{'sensor'} ) ){
$b_sysctl = 1;
}
- if ($show{'filter-override'}){
- $show{'filter'} = 0;
- }
if ($bsd_type && ($show{'short'} || $show{'disk-basic'} || $show{'disk-total'} || $show{'disk'})){
$b_dm_boot_disk = 1;
}
if ($bsd_type && ($show{'optical-basic'} || $show{'optical'})){
$b_dm_boot_optical = 1
}
+ if ($b_admin && $show{'disk'}){
+ $b_smartctl = 1;
+ }
}
sub show_options {
@@ -4452,27 +4674,44 @@ sub show_options {
$line = $line . '- ';
}
@rows = (
- ['0', '', '', "$self_name supports the following options. You can combine
- these or list them one by one. For more detailed information, see man^$self_name.
- Examples:^$self_name^-v4^-c6 OR
- $self_name^-bDc^6. If you start $self_name with no arguments, it will display
- a short system summary." ],
+ ['0', '', '', "$self_name supports the following options. For more detailed
+ information, see man^$self_name. If you start $self_name with no arguments,
+ it will display a short system summary." ],
['0', '', '', '' ],
- ['0', '', '', "The following options, if used without -F, -b, or -v, will
- show option line(s): A, B, C, D, G, I, M, N, P, R, S, W, d, f, i, l, m, n,
- o, p, r, s, t, u, w, --slots, --usb - you can use these alone or together
- to show just the line(s) you want to see. If you use them with -v [level],
- -b or -F, $self_name will combine the outputs." ],
+ ['0', '', '', "You can use these options alone or together,
+ to show or add the item(s) you want to see: A, B, C, D, G, I, J, M, N, P,
+ R, S, W, d, f, i, j, l, m, n, o, p, r, s, t, u, w, --slots.
+ If you use them with -v [level], -b or -F, $self_name will add the requested
+ lines to the output." ],
+ ['0', '', '', '' ],
+ ['0', '', '', "Examples:^$self_name^-v4^-c6 OR $self_name^-bDc^6 OR
+ $self_name^-FzjJxy^80" ],
['0', '', '', $line ],
['0', '', '', "Output Control Options:" ],
['1', '-a', '--admin', "Adds advanced sys admin data (only works with
- verbose or line output, not short form):" ],
- ['2', '-C', '', "If available: CPU vulnerabilities (bugs); family, model-id, stepping - format:
- hex (decimal) if greater than 9, otherwise hex; microcode - format: hex." ],
- ['2', '-d,-D', '', "If available: logical and physical block sizes." ],
- ['2', '-p,-P', '', "If available: raw size of partition, percent available for user,
- block size of file system (root required); for swap, shows swapiness and vfs cache
+ verbose or line output, not short form); check man page for explanations!;
+ also sets --extra=3:" ],
+ ['2', '-A', '', "If available: list of alternate kernel modules/drivers
+ for device(s)." ],
+ ['2', '-C', '', "If available: CPU socket type, base/boost speeds
+ (dmidecode+root/sudo required); CPU vulnerabilities (bugs);
+ family, model-id, stepping - format: hex (decimal) if greater
+ than 9, otherwise hex; microcode - format: hex." ],
+ ['2', '-d,-D', '', "If available: logical and physical block sizes; drive family;
+ USB drive specifics; SMART report." ],
+ ['2', '-G', '', "If available: Xorg Display ID, Screens total, default Screen,
+ current Screen; per X Screen: resolution, dpi, size, diagonal; per Monitor:
+ resolution; hz; dpi; size; diagonal; list of alternate kernel modules/drivers
+ for device(s)." ],
+ ['2', '-I', '', "As well as per package manager counts, also adds total
+ number of lib files found for each package manager if not -r." ],
+ ['2', '-j,-p,-P', '', "For swap (if available): swappiness and vfs cache
pressure, and if values are default or not." ],
+ ['2', '-n,-N', '', "If available: list of alternate kernel modules/drivers
+ for device(s)." ],
+ ['2', '-p,-P', '', "If available: raw size of ${partition_string}s,
+ percent available for user, block size of file system (root required)." ],
+ ['2', '-r', '', "Packages, see -Ia." ],
['2', '-S', '', "If available: kernel boot parameters." ],
['1', '-A', '--audio', "Audio/sound card(s), driver, sound server." ],
['1', '-b', '--basic', "Basic output, short form. Same as $self_name^-v^2." ],
@@ -4494,19 +4733,23 @@ sub show_options {
['1', '-d', '--disk-full, --optical', "Optical drive data (and floppy disks,
if present). Triggers -D." ],
['1', '-D', '--disk', "Hard Disk info, including total storage and details
- for each disk. Disk total used percentage includes swap partition size(s)." ],
+ for each disk. Disk total used percentage includes swap ${partition_string}
+ size(s)." ],
['1', '-f', '--flags', "All CPU $flags. Triggers -C. Not shown with -F to
avoid spamming." ],
['1', '-F', '--full', "Full output. Includes all Upper Case line letters
- except -W, plus -s and -n. Does not show extra verbose options such
+ except -W, plus --swap, -s and -n. Does not show extra verbose options such
as -d -f -i -l -m -o -p -r -t -u -x, unless specified." ],
['1', '-G', '--graphics', "Graphics info (card(s), driver, display protocol
- (if available), display server, resolution, renderer, OpenGL version)." ],
+ (if available), display server/Wayland compositor, resolution, renderer,
+ OpenGL version)." ],
['1', '-i', '--ip', "WAN IP address and local interfaces (requires ifconfig
or ip network tool). Triggers -n. Not shown with -F for user security reasons.
You shouldn't paste your local/WAN IP." ],
['1', '-I', '--info', "General info, including processes, uptime, memory,
IRC client or shell type, $self_name version." ],
+ ['1', '-j', '--swap', "Swap in use. Includes ${partition_string}s, zram, file." ],
+ ['1', '-J', '--usb', "Show USB data: Hubs and Devices." ],
['1', '-l', '--label', "$partition_string_u labels. Triggers -P.
For full -p output, use -pl." ],
['1', '-m', '--memory', "Memory (RAM) data. Requires root. Numbers of
@@ -4531,7 +4774,8 @@ sub show_options {
['1', '-p', '--partitions-full', "Full $partition_string information (-P plus all other
detected ${partition_string}s)." ],
['1', '-P', '--partitions', "Basic $partition_string info. Shows, if detected:
- / /boot /home /opt /tmp /usr /usr/home /var /var/log /var/tmp. Use -p to see all
+ / /boot /home /opt /tmp /usr /usr/home /var /var/log /var/tmp. Swap
+ ${partition_string}s show if --swap is not used. Use -p to see all
mounted ${partition_string}s." ],
['1', '-r', '--repos', "Distro repository data. Supported repo types: APK,
APT, CARDS, EOPKG, PACMAN, PACMAN-G2, PISI, PORTAGE, PORTS (BSDs), SLACKPKG,
@@ -4549,7 +4793,6 @@ sub show_options {
of processes for each type (default: 5; if in IRC, max: 5). " ],
['1', '', '', "Make sure that there is no space between letters and
numbers (e.g.^-t^cm10)." ],
- ['1', '', '--usb', "Show USB data: Hubs and Devices." ],
['1', '-u', '--uuid', "$partition_string_u UUIDs. Triggers -P. For full -p
output, use -pu." ],
['1', '-v', '--verbosity', "Set $self_name verbosity level (0-8).
@@ -4564,17 +4807,18 @@ sub show_options {
['2', '4', '', "$partition_string_u size/used data (-P) for
(if present) /, /home, /var/, /boot. Shows full disk data (-D). " ],
['2', '5', '', "Audio card (-A), sensors (-s), memory/RAM (-m),
- $partition_string label^(-l), UUID^(-u), short form of optical drives,
- standard RAID data (-R). " ],
- ['2', '6', '', "Full $partition_string (-p), unmounted $partition_string (-o),
- optical drive (-d), USB (--usb), full RAID; triggers -xx." ],
+ $partition_string label^(-l), full swap (-j), UUID^(-u), short form
+ of optical drives, standard RAID data (-R). " ],
+ ['2', '6', '', "Full $partition_string (-p),
+ unmounted $partition_string (-o), optical drive (-d), USB (-J),
+ full RAID; triggers -xx." ],
['2', '7', '', "Network IP data (-i); triggers -xxx."],
['2', '8', '', "Everything available, including repos (-r), processes
(-tcm), PCI slots (--slots)."],
);
push @data, @rows;
# if distro maintainers don't want the weather feature disable it
- if ( $b_weather ){
+ if ( $use{'weather'} ){
@rows = (
['1', '-w', '--weather', "Local weather data/time. To check an alternate
location, see -W. NO AUTOMATED QUERIES ALLOWED!"],
@@ -4613,10 +4857,13 @@ sub show_options {
Temporary, Unknown. See --limit for large counts of IP addresses." ],
['2', '-I', '', "Default system GCC. With -xx, also shows other installed
GCC versions. If running in shell, not in IRC client, shows shell version
- number, if detected. Init/RC type and runlevel (if available)." ],
+ number, if detected. Init/RC type and runlevel (if available). Total
+ count of all packages discovered in system and not -r." ],
+ ['2', '-J', '', "For Device: driver." ],
['2', '-m,--memory-modules', '', "Max memory module size (if available), device type." ],
['2', '-N', '', "Specific vendor/product information (if relevant);
PCI Bus ID/USB ID number of card; Version/port(s)/driver version (if available)." ],
+ ['2', '-r', '', "Packages, see -Ix." ],
['2', '-R', '', "md-raid: second RAID Info line with extra data:
blocks, chunk size, bitmap (if present). Resync line, shows blocks
synced/total blocks. Hardware RAID driver version, bus ID." ],
@@ -4625,10 +4872,9 @@ sub show_options {
and detected)" ],
['2', '-t', '', "Adds memory use output to CPU (-xt c), and CPU use to
memory (-xt m)." ],
- ['2', '--usb', '', "For Device: driver." ],
);
push @data, @rows;
- if ( $b_weather ){
+ if ( $use{'weather'} ){
@rows = (['2', '-w -W', '', "Wind speed and direction, humidity, pressure,
and time zone, if available." ]);
push @data, @rows;
@@ -4641,15 +4887,20 @@ sub show_options {
['2', '-C', '', "L1/L3 cache (if root and dmidecode installed)." ],
['2', '-D', '', "Disk transfer speed; NVMe lanes; Disk serial number." ],
['2', '-G', '', "Chip vendor:product ID for each video card; OpenGL
- compatibility version, if free drivers and available; compositor (experimental);
+ compatibility version, if free drivers and available; Xorg compositor;
alternate Xorg drivers (if available). Alternate means driver is on automatic
- driver check list of Xorg for the card vendor, but is not installed on system." ],
+ driver check list of Xorg for the card vendor, but is not installed on system;
+ Xorg dpi." ],
['2', '-I', '', "Other detected installed gcc versions (if present). System
default runlevel. Adds parent program (or tty) for shell info if not in
- IRC. Adds Init version number, RC (if found)." ],
+ IRC. Adds Init version number, RC (if found). Adds per package manager
+ package counts if not -r." ],
+ ['2', '-j,-p,-P', '', "Swap priority." ],
+ ['2', '-J', '', "Vendor:chip ID." ],
['2', '-m,--memory-modules', '', "Manufacturer, part number; single/double bank (if found)." ],
['2', '-M', '', "Chassis info, BIOS ROM size (dmidecode only), if available." ],
['2', '-N', '', "Chip vendor:product ID." ],
+ ['2', '-r', '', "Packages, see -Ixx." ],
['2', '-R', '', "md-raid: Superblock (if present), algorithm. If resync,
shows progress bar. Hardware RAID Chip vendor:product ID." ],
['2', '-s', '', "DIMM/SOC voltages (ipmi only)." ],
@@ -4657,10 +4908,9 @@ sub show_options {
gdm3, lightdm); active window manager if detected; desktop toolkit,
if available (Xfce/KDE/Trinity only)." ],
['2', '--slots', '', "Slot length." ],
- ['2', '--usb', '', "Vendor:chip ID." ],
);
push @data, @rows;
- if ( $b_weather ){
+ if ( $use{'weather'} ){
@rows = (['2', '-w -W', '', "Snow, rain, precipitation, (last observed hour),
cloud cover, wind chill, dew point, heat index, if available." ]);
push @data, @rows;
@@ -4670,12 +4920,13 @@ sub show_options {
with verbose or line output, not short form):" ],
['2', '-A', '', "Serial number." ],
['2', '-B', '', "Chemistry, cycles, location (if available)." ],
- ['2', '-C', '', "CPU boost (turbo) enabled/disabled, if present." ],
+ ['2', '-C', '', "CPU boost (turbo) enabled/disabled, if present;
+ CPU voltage, external clock speed (if root and dmidecode installed)." ],
['2', '-D', '', "Firmware rev. if available; partition scheme, in some cases; disk
rotation speed (if detected)." ],
- ['2', '-G', '', "Compositor version (if detectable)." ],
['2', '-I', '', "For 'Shell:' adds ([su|sudo|login]) to shell name if present;
- for 'running in:' adds (SSH) if SSH session." ],
+ adds default shell+version if different; for 'running in:' adds (SSH) if SSH session." ],
+ ['2', '-J', '', "For Device: serial number (if present), interface count; USB speed." ],
['2', '-m,--memory-modules', '', "Width of memory bus, data and total (if present and greater
than data); Detail for Type, if present; module voltage, if available; serial
number." ],
@@ -4686,21 +4937,25 @@ sub show_options {
['2', '-S', '', "Panel/tray/bar/dock info in desktop output, if in X (like lxpanel,
xfce4-panel, mate-panel); (if available) dm version number, window manager
version number." ],
- ['2', '--usb', '', "For Device: serial number (if present), interface count; USB speed." ],
);
push @data, @rows;
- if ( $b_weather ){
+ if ( $use{'weather'} ){
@rows = (['2', '-w -W', '', "Location (uses -z/irc filter), weather observation
time, altitude, sunrise/sunset, if available." ] );
push @data, @rows;
}
@rows = (
['1', '-y', '--width', "Output line width max (integer >= 80). Overrides IRC/Terminal
- settings or actual widths. Example:^inxi^-y^130" ],
+ settings or actual widths. If no integer give, defaults to 80. -1 removes line lengths.
+ 1 switches output to 1 key/value pair per line. Example:^inxi^-y^130" ],
['1', '-z', '--filter', "Adds security filters for IP/MAC addresses, serial numbers,
- location (-w), user home directory name. Default on for IRC clients." ],
- ['1', '-Z', '--filter-override', "Absolute override for output filters. Useful for
+ location (-w), user home directory name, host item. Default on for IRC clients." ],
+ ['1', '', '--filter-label', "Filters out ${partition_string} labels in -j,
+ -o, -p, -P, -Sa." ],
+ ['1', '-Z', '--filter-override', "Override for output filters. Useful for
debugging networking issues in IRC, for example." ],
+ ['1', '', '--filter-uuid', "Filters out ${partition_string} UUIDs in -j,
+ -o, -p, -P, -Sa." ],
[0, '', '', "$line" ],
[0, '', '', "Additional Options:" ],
['1', '-h', '--help', "This help menu." ],
@@ -4709,7 +4964,7 @@ sub show_options {
for that feature." ]
);
push @data, @rows;
- if ( $b_update ){
+ if ( $use{'update'} ){
@rows = (
['1', '-U', '--update', "Auto-update $self_name. Will also install/update man
page. Note: if you installed as root, you must be root to update, otherwise
@@ -4735,27 +4990,32 @@ sub show_options {
['2', '43', '', "Bypass Wget as a downloader option." ],
['2', '44', '', "Bypass Curl, Fetch, and Wget as downloader options. Forces
Perl if HTTP::Tiny present." ],
+ ['1', '', '--dig', "Overrides configuration item NO_DIG (resets to default)." ],
['1', '', '--display', "[:[0-9]] Try to get display data out of X (default: display 0)." ],
['1', '', '--dmidecode', "Force use of dmidecode data instead of /sys where relevant
(e.g. -M, -B)." ],
['1', '', '--downloader', "Force $self_name to use [curl|fetch|perl|wget] for downloads." ],
['1', '', '--host', "Turn on hostname for -S." ],
+ ['1', '', '--html-wan', "Overrides configuration item NO_HTML_WAN (resets to default)." ],
['1', '', '--indent-min', "Set point where $self_name autowraps line starters." ],
['1', '', '--limit', "[-1; 1-x] Set max output limit of IP addresses for -i
(default 10; -1 removes limit)." ],
);
push @data, @rows;
- if ( $b_update ){
+ if ( $use{'update'} ){
@rows = (
['1', '', '--man', "Install correct man version for dev branch (-U 3) or pinxi using -U." ],
);
push @data, @rows;
}
@rows = (
+ ['1', '', '--no-dig', "Skip dig for WAN IP checks, use downloader program." ],
['1', '', '--no-host', "Turn off hostname for -S. Useful if showing output from servers etc." ],
+ ['1', '', '--no-html-wan', "Skip HTML IP sources for WAN IP checks, use dig only,
+ or nothing if --no-dig." ],
);
push @data, @rows;
- if ( $b_update ){
+ if ( $use{'update'} ){
@rows = (
['1', '', '--no-man', "Disable man install for all -U update actions." ],
);
@@ -4763,14 +5023,20 @@ sub show_options {
}
@rows = (
['1', '', '--no-ssl', "Skip SSL certificate checks for all downloader actions
- (Wget/Fetch/Curl only)." ],
+ (Wget/Fetch/Curl/Perl-HTTP::Tiny)." ],
['1', '', '--no-sudo', "Skip internal program use of sudo features (not related
to starting $self_name with sudo)." ],
['1', '', '--output', "[json|screen|xml] Change data output type. Requires --output-file
if not screen." ],
['1', '', '--output-file', "[Full filepath|print] Output file to be used for --output." ],
['1', '', '--partition-sort', "[dev-base|fs|id|label|percent-used|size|uuid|used]
- Change sort order of partition output. See man page for specifics." ],
+ Change sort order of ${partition_string} output. See man page for specifics." ],
+ ['1', '', '--sensors-default', "Removes configuration item SENSORS_USE and SENSORS_EXCLUDE.
+ Same as default behavior." ],
+ ['1', '', '--sensors-exclude', "[sensor[s] name, comma separated] Exclude supplied sensor
+ array[s] for -s output (lm-sensors, Linux only)." ],
+ ['1', '', '--sensors-use', "[sensor[s] name, comma separated] Use only supplied sensor
+ array[s] for -s output (lm-sensors, Linux only)." ],
['1', '', '--sleep', "[0-x.x] Change CPU sleep time, in seconds, for -C
(default:^$cpu_sleep). Allows system to catch up and show a more accurate CPU
use. Example:^$self_name^-Cxxx^--sleep^0.15" ],
@@ -4794,7 +5060,7 @@ sub show_options {
['2', '11', '', "Full file/system info logging." ],
['1', '', ,'', "The following create a tar.gz file of system data, plus $self_name
output. To automatically upload debugger data tar.gz file
- to ftp.techpatterns.com: $self_name^--debug^21" ],
+ to ftp.smxi.org: $self_name^--debug^21" ],
['2', '20', '', "Full system data collection: /sys; xorg conf and log data, xrandr,
xprop, xdpyinfo, glxinfo etc.; data from dev, disks,
${partition_string}s, etc." ],
@@ -4831,6 +5097,7 @@ sub show_version {
elsif ( $working_path !~ /^\// ){
$working_path = getcwd() . "/$working_path";
}
+ $working_path =~ s%/$%%;
# handle if it's a symbolic link, rare, but can happen with directories
# in irc clients which would only matter if user starts inxi with -! 30 override
# in irc client
@@ -4841,33 +5108,31 @@ sub show_version {
}
# strange output /./ ending, but just trim it off, I don't know how it happens
$working_path =~ s%/\./%/%;
- @row = ([ 0, '', '', "$self_name $self_version-$self_patch ($self_date)"],);
+ @row = (
+ [ 0, '', '', "$self_name $self_version-$self_patch ($self_date)"],
+ );
push @data, @row;
if ( ! $b_irc ){
- @row = ([ 0, '', '', ""],);
+ @row = ([ 0, '', '', ''],);
push @data, @row;
my $year = (split/-/, $self_date)[0];
- @row = [ 0, '', '', "Program Location: $working_path" ];
+ @row = (
+ [ 0, '', '', "Copyright^(C)^2008-$year^Harald^Hope^aka^h2"],
+ [ 0, '', '', "Forked from Infobash 3.02: Copyright^(C)^2005-2007^Michiel^de^Boer^aka^locsmif." ],
+ [ 0, '', '', "Using Perl version: $]"],
+ [ 0, '', '', "Program Location: $working_path" ],
+ );
push @data, @row;
if ( $link ){
@row = [ 0, '', '', "Started via symbolic link: $link" ];
push @data, @row;
}
@rows = (
+ [ 0, '', '', '' ],
[ 0, '', '', "Website:^https://github.com/smxi/inxi^or^https://smxi.org/" ],
[ 0, '', '', "IRC:^irc.oftc.net channel:^#smxi" ],
[ 0, '', '', "Forums:^https://techpatterns.com/forums/forum-33.html" ],
- [ 0, '', '', " " ],
- [ 0, '', '', "$self_name - the universal, portable, system information tool
- for console and irc." ],
- [ 0, '', '', "Using Perl version: $]"],
- [ 0, '', '', " " ],
- [ 0, '', '', "This program started life as a fork of Infobash 3.02:
- Copyright^(C)^2005-2007^Michiel^de^Boer^aka^locsmif." ],
- [ 0, '', '', "Subsequent changes and modifications (after Infobash 3.02):
- Copyright^(C)^2008-$year^Harald^Hope^aka^h2.
- CPU/Konversation^fixes:^Scott^Rogers^aka^trash80.
- USB^audio^fixes:^Steven^Barrett^aka^damentz." ],
+
[ 0, '', '', '' ],
[ 0, '', '', "This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by the Free Software
@@ -4887,10 +5152,8 @@ sub show_version {
# StartClient
{
package StartClient;
-
# use warnings;
# use strict;
-
my $ppid = '';
my $pppid = '';
@@ -4910,10 +5173,11 @@ sub get_client_data {
$ppid = getppid();
main::set_ps_aux() if ! @ps_aux;
if (!$b_irc){
- main::get_shell_data($ppid);
+ # we'll run get_shell_data for -I, but only then
+ $client{'ppid'} = $ppid;
}
else {
- $show{'filter'} = 1;
+ $use{'filter'} = 1;
get_client_name();
if ($client{'konvi'} == 1 || $client{'konvi'} == 3){
set_konvi_data();
@@ -5041,7 +5305,7 @@ sub get_client_version {
$client{'version'} ||= '(pre v0.4.1)?';
}
# then do some perl type searches, do this last since it's a wildcard search
- elsif ($client{'name'} =~ /^perl.*|ksirc|dsirc$/ ) {
+ elsif ($client{'name'} =~ /^(perl.*|ksirc|dsirc)$/ ) {
my @cmdline = main::get_cmdline();
# Dynamic runpath detection is too complex with KSirc, because KSirc is started from
# kdeinit. /proc/<pid of the grandparent of this process>/exe is a link to /usr/bin/kdeinit
@@ -5068,7 +5332,7 @@ sub get_client_version {
# NOTE: these must be empirically determined, not all events that
# show no tty are actually IRC.
my $wl_terms = 'alacritty|evilvte|germinal|guake|hyper|kate|kitty|kmscon|';
- $wl_terms .= 'konsole|putty|rxvt|sakura|shellinabox|^st$|sudo|term|tilda|';
+ $wl_terms .= 'konsole|minicom|putty|rxvt|sakura|shellinabox|^st$|sudo|term|tilda|';
$wl_terms .= 'tilix|urvxt|yaft|yakuake';
my $wl_clients = 'ansible|chef|run-parts';
my $whitelist = "$wl_terms|$wl_clients";
@@ -5101,7 +5365,6 @@ sub get_cmdline {
print_line("Open /proc/$ppid/cmdline failed: $!");
my @rows = <$fh>;
close $fh;
-
foreach (@rows){
push @cmdline, $_;
$i++;
@@ -5121,7 +5384,8 @@ sub perl_python_client {
# this is a hack to try to show konversation if inxi is running but started via /cmd
# OR via program shortcuts, both cases in fact now
# main::print_line("konvi: " . scalar grep { $_ =~ /konversation/ } @ps_cmd);
- if ( $b_display && main::check_program('konversation') && ( grep { $_ =~ /konversation/ } @ps_cmd )){
+ if ( $b_display && main::check_program('konversation') &&
+ ( grep { $_ =~ /konversation/ } @ps_cmd )){
@app = main::program_values('konversation');
$client{'version'} = main::program_version('konversation',$app[0],$app[1],$app[2],$app[5],$app[6]);
$client{'name'} = 'konversation';
@@ -5131,7 +5395,8 @@ sub perl_python_client {
## NOTE: supybot only appears in ps aux using 'SHELL' command; the 'CALL' command
## gives the user system irc priority, and you don't see supybot listed, so use SHELL
elsif ( !$b_display &&
- (main::check_program('supybot') || main::check_program('gribble') || main::check_program('limnoria')) &&
+ (main::check_program('supybot') ||
+ main::check_program('gribble') || main::check_program('limnoria')) &&
( grep { $_ =~ /supybot/ } @ps_cmd ) ){
@app = main::program_values('supybot');
$client{'version'} = main::program_version('supybot',$app[0],$app[1],$app[2],$app[5],$app[6]);
@@ -5258,13 +5523,26 @@ sub set_konvi_data {
sub apply_filter {
my ($string) = @_;
if ($string){
- $string = ( $show{'filter'} ) ? $filter_string : $string;
+ $string = ( $use{'filter'} ) ? $filter_string : $string;
}
else {
$string = 'N/A';
}
return $string;
}
+# note, let the print logic handle N/A cases
+sub apply_partition_filter {
+ my ($source,$string,$type) = @_;
+ return $string if !$string || $string eq 'N/A';
+ if ($source eq 'system') {
+ my $test = ($type eq 'label') ? '=LABEL=': '=UUID=';
+ $string =~ s/$test[^\s]+/$test$filter_string/g;
+ }
+ else {
+ $string = $filter_string;
+ }
+ return $string;
+}
sub arm_cleaner {
my ($item) = @_;
$item =~ s/(\([^\(]*Device Tree[^\)]*\))//gi;
@@ -5310,8 +5588,8 @@ sub dmi_cleaner {
my ($string) = @_;
my $cleaner = '^Base Board .*|^Chassis .*|empty|Undefined.*|.*O\.E\.M\..*|.*OEM.*|^Not .*';
$cleaner .= '|^System .*|.*unknow.*|.*N\/A.*|none|^To be filled.*|^0x[0]+$';
- $cleaner .= '|\[Empty\]|<Bad Index>|Default string|^\.\.$|Manufacturer.*';
- $cleaner .= '|AssetTagNum|Manufacturer| Or Motherboard|PartNum.*|SerNum';
+ $cleaner .= '|\[Empty\]|<Bad Index>|<OUT OF SPEC>|Default string|^\.\.$|Manufacturer.*';
+ $cleaner .= '|AssetTagNum|Manufacturer| Or Motherboard|PartNum.*|\bOther\b.*|SerNum';
$string =~ s/$cleaner//i;
$string =~ s/^\s+|\bbios\b|\bacpi\b|\s+$//gi;
$string =~ s/http:\/\/www.abit.com.tw\//Abit/i;
@@ -5447,6 +5725,7 @@ sub row_defaults {
'disk-data' => "No Disk data was found.",
'disk-size-0' => "Total N/A",
'display-console' => 'No advanced graphics data found on this system in console.',
+ 'display-driver-na' => "display driver n/a",
'display-null' => 'No advanced graphics data found on this system.',
'display-root' => 'Advanced graphics data unavailable in console for root.',
'display-root-x' => 'Advanced graphics data unavailable for root.',
@@ -5457,7 +5736,9 @@ sub row_defaults {
'dev' => 'Feature under development',
'dmesg-boot-permissions' => 'dmesg.boot permissions',
'dmesg-boot-missing' => 'dmesg.boot not found',
- 'IP' => "No $id data found. Connected to the web? SSL issues?",
+ 'IP' => "No $id found. Connected to web? SSL issues?",
+ 'IP-dig' => "No $id found. Connected to web? SSL issues? Try --no-dig",
+ 'IP-no-dig' => "No $id found. Connected to web? SSL issues? Try enabling dig",
'machine-data' => "No machine data: try newer kernel.",
'machine-data-bsd' => "No machine data: Is dmidecode installed? Try -M --dmidecode.",
'machine-data-dmidecode' => "No machine data: try newer kernel. Is dmidecode installed? Try -M --dmidecode.",
@@ -5466,6 +5747,7 @@ sub row_defaults {
'optical-data' => "No Optical or Floppy data was found.",
'optical-data-bsd' => "No floppy or optical data found for this BSD system.",
'output-limit' => "Output throttled. IPs: $id; Limit: $limit; Override: --limit [1-x;-1 all]",
+ 'packages' => 'No packages detected. Unsupported package manager?',
'partition-data' => "No Partition data was found.",
'partition-hidden' => "N/A (hidden?)",
'pci-advanced-data' => 'bus/chip ids unavailable',
@@ -5475,10 +5757,18 @@ sub row_defaults {
'ps-data-null' => "No Process data available.",
'raid-data' => "No RAID data was found.",
'ram-data' => "No RAM data was found.",
- 'root-required' => "<root required>",
+ 'root-required' => "<superuser/root required>",
+ 'root-suggested' => "try sudo/root",
'sensors-data-ipmi' => "No ipmi sensors data was found.",
'sensors-data-linux' => "No sensors data was found. Is sensors configured?",
- 'sensors-ipmi-root' => "Unable to run ipmi sensors. Root privileges required.",
+ 'sensors-ipmi-root' => "Unable to run ipmi sensors. Root privileges required.",
+ 'smartctl-command-failed' => "A mandatory SMART command failed. Various possible causes.",
+ 'smartctl-root' => "Unable to run smartctl. Root privileges required.",
+ 'smartctl-udma-crc' => "Bad cable/connection?",
+ 'smartctl-usb' => "Unknown USB bridge. Flash drive/Unsupported enclosure?",
+ 'smartctl-unknown' => "Unknown smartctl error. Unable to get data.",
+ 'swap-admin' => "No admin swap data available.",
+ 'swap-data' => "No Swap data was found.",
'tool-missing' => "<missing $id>",
'unmounted-data' => "No unmounted partitions found.",
'unmounted-data-bsd' => "No unmounted partition data found for this BSD system.",
@@ -5622,7 +5912,7 @@ sub generate_xml {
}
sub key {
- return sprintf("%03d#%s", $_[0],$_[1]);
+ return sprintf("%03d#%s#%s#%s", $_[0],$_[1],$_[2],$_[3]);
}
sub print_basic {
@@ -5713,19 +6003,14 @@ sub print_basic {
# hash key to force sorts.
sub print_data {
my (%data) = @_;
- my $array = 0;
- my $array_holder = 1;
- my $counter=0;
- my $split_count = 0;
- my $hash = 0;
- my $holder = '';
- my $id_holder = 0;
- my $start = '';
- my $start2 = '';
- my $length = 0;
+ my ($array,$counter,$length,$split_count) = (0,0,0,0);
+ my ($hash_id,$holder,$start,$start2,$start_holder) = ('','','','','');
my $indent = $size{'indent'};
- my (@temp,@working,@values,%ids,$holder2,%row);
- my ($key,$line,$val2,$val3);
+ my (@temp,@working,@values,%ids,%row);
+ my ($holder2,$key,$line,$val2,$val3);
+ # these 2 sets are single logic items
+ my $b_single = ($size{'max'} == 1) ? 1: 0;
+ my ($b_container,$indent_use,$indentx) = (0,0,0);
# $size{'max'} = 88;
# NOTE: indent < 11 would break the output badly in some cases
if ($size{'max'} < $size{'indent-min'} || $size{'indent'} < 11 ){
@@ -5734,9 +6019,10 @@ sub print_data {
#foreach my $key1 (sort { (split/#/, $a)[0] <=> (split/#/, $b)[0] } keys %data) {
foreach my $key1 (sort { substr($a,0,3) <=> substr($b,0,3) } keys %data) {
#foreach my $key1 (sort { $a cmp $b } keys %data) {
- $key = (split/#/, $key1)[1];
+ $key = (split/#/, $key1)[3];
if ($key ne 'SHORT' ) {
$start = sprintf("$colors{'c1'}%-${indent}s$colors{'cn'}","$key$sep{'s1'}");
+ $start_holder = $key;
if ($indent < 10){
$line = "$start\n";
print_line($line);
@@ -5747,167 +6033,169 @@ sub print_data {
else {
$indent = 0;
}
- if (ref($data{$key1}) eq 'ARRAY'){
- # @working = @{$data{$key1}};
- %ids = (
- 'Array' => 1,
- 'array' => 1,
- 'Battery' => 1,
- 'Card' => 1,
- 'Device' => 1,
- 'Floppy' => 1,
- 'Hardware' => 1, # hardware raid report
- 'ID' => 1,
- 'IF-ID' => 1,
- 'Optical' => 1,
- 'variant' => 1, # arm > 1 cpu type
- );
- $array_holder = 1;
- foreach my $val1 (@{$data{$key1}}){
- $length = $indent;
- if (ref($val1) eq 'HASH'){
- #%row = %$val1;
- $counter=0;
- $split_count = 0;
- $hash = scalar %$val1;
- #foreach my $key2 (sort { (split/#/, $a)[0] <=> (split/#/, $b)[0] } keys %$val1){
- foreach my $key2 (sort { substr($a,0,3) <=> substr($b,0,3) } keys %$val1){
- #foreach my $key2 (sort { $a cmp $b } keys %$val1){
- $key = (split/#/, $key2)[1];
- # for ram with > 1 system array, we want to reset device count to 1 for each
- # new array
- if ($key eq 'Array' && $array_holder != $ids{$key} ){
- $array_holder = $ids{$key};
- $ids{'Device'} = 1 if ($ids{'Device'} > 1);
- }
- if ($key eq 'Device' && $ids{'array'} > 1 && $id_holder != $ids{$key} ){
- $id_holder = $ids{$key};
- $ids{'array'} = 1 if ($ids{'array'} > 1);
- }
- if ($counter == 0 && defined $ids{$key}){
- $key .= '-' . $ids{$key}++;
- }
- $val2 = $$val1{$key2};
- # we have to handle cases where $val2 is 0
- if ($val2 || $val2 eq '0'){
- $val2 .= " ";
- }
- # see: Use of implicit split to @_ is deprecated. Only get this warning
- # in Perl 5.08 oddly enough.
- @temp = split/\s+/, $val2;
- $split_count = scalar @temp;
- if ( ( length( "$key$sep{'s2'} $val2" ) + $length ) < $size{'max'} ) {
- $length += length("$key$sep{'s2'} $val2");
- $holder .= "$colors{'c1'}$key$sep{'s2'}$colors{'c2'} $val2";
- #print "one\n";
- }
- # handle case where the opening key/value pair is > max, and where
- # there are a lot of terms, like cpu flags, raid types supported. Raid
- # can have the last row have a lot of devices, or many raid types
- elsif ( ( length( "$key$sep{'s2'} $val2" ) + $indent ) > $size{'max'} &&
- !defined $ids{$key} && $split_count > 2 ) {
- @values = split/\s+/, $val2;
- $val3 = shift @values;
- # $length += length("$key$sep{'s2'} $val3 ") + $indent;
- $start2 = "$colors{'c1'}$key$sep{'s2'}$colors{'c2'} $val3 ";
- $holder2 = '';
- $length += length("$key$sep{'s2'} $val3 ");
- # print scalar @values,"\n";
- foreach (@values){
- # my $l = (length("$_ ") + $length);
- #print "$l\n";
- if ( (length("$_ ") + $length) < $size{'max'} ){
- #print "a\n";
- if ($start2){
- $holder2 .= "$start2$_ ";
- $start2 = '';
- #$length += $length2;
- #$length2 = 0;
- }
- else {
- $holder2 .= "$_ ";
- }
- $length += length("$_ ");
- }
- else {
- #print "three\n";
- if ($start2){
- $holder2 = "$start2$holder2";
- }
- else {
- $holder2 = "$colors{'c2'}$holder2";
- }
- #print "xx:$holder";
- $line = sprintf("%-${indent}s%s$colors{'cn'}\n","$start","$holder$holder2");
- print_line($line);
- $holder = '';
-
- $holder2 = "$_ ";
- #print "h2: $holder2\n";
- $length = length($holder2) + $indent;
+ next if ref($data{$key1}) ne 'ARRAY';
+ # @working = @{$data{$key1}};
+ # Line starters that will be -x incremented always
+ # It's a tiny bit faster manually resetting rather than using for loop
+ %ids = (
+ 'Array' => 1, # RAM or RAID
+ 'Battery' => 1,
+ 'Card' => 1,
+ 'Device' => 1,
+ 'Floppy' => 1,
+ 'Hardware' => 1, # hardware raid report
+ 'ID' => 1,
+ 'IF-ID' => 1,
+ 'Monitor' => 1,
+ 'Optical' => 1,
+ 'Screen' => 1,
+ 'variant' => 1, # arm > 1 cpu type
+ );
+ foreach my $val1 (@{$data{$key1}}){
+ $indent_use = $length = $indent;
+ if (ref($val1) eq 'HASH'){
+ #%row = %$val1;
+ ($counter,$split_count) = (0,0);
+ #foreach my $key2 (sort { (split/#/, $a)[0] <=> (split/#/, $b)[0] } keys %$val1){
+ foreach my $key2 (sort { substr($a,0,3) <=> substr($b,0,3) } keys %$val1){
+ #foreach my $key2 (sort { $a cmp $b } keys %$val1){
+ ($hash_id,$b_container,$indentx,$key) = (split/#/, $key2);
+ if ($start_holder eq 'Graphics' && $key eq 'Screen'){
+ $ids{'Monitor'} = 1;
+ }
+ elsif ($start_holder eq 'Memory' && $key eq 'Array'){
+ $ids{'Device'} = 1;
+ }
+ elsif ($start_holder eq 'RAID' && $key eq 'Device'){
+ $ids{'Array'} = 1;
+ }
+ elsif ($start_holder eq 'USB' && $key eq 'Hub'){
+ $ids{'Device'} = 1;
+ }
+ if ($counter == 0 && defined $ids{$key}){
+ $key .= '-' . $ids{$key}++;
+ }
+ $val2 = $$val1{$key2};
+ # we have to handle cases where $val2 is 0
+ if (!$b_single && $val2 || $val2 eq '0'){
+ $val2 .= " ";
+ }
+ # see: Use of implicit split to @_ is deprecated. Only get this warning
+ # in Perl 5.08 oddly enough.
+ @temp = split/\s+/, $val2;
+ $split_count = scalar @temp;
+ if ( !$b_single && ( length( "$key$sep{'s2'} $val2" ) + $length ) < $size{'max'} ) {
+ #print "one\n";
+ $length += length("$key$sep{'s2'} $val2");
+ $holder .= "$colors{'c1'}$key$sep{'s2'}$colors{'c2'} $val2";
+ }
+ # handle case where the opening key/value pair is > max, and where
+ # there are a lot of terms, like cpu flags, raid types supported. Raid
+ # can have the last row have a lot of devices, or many raid types
+ elsif ( !$b_single && ( length( "$key$sep{'s2'} $val2" ) + $indent ) > $size{'max'} &&
+ !defined $ids{$key} && $split_count > 2 ) {
+ #print "two\n";
+ @values = split/\s+/, $val2;
+ $val3 = shift @values;
+ # $length += length("$key$sep{'s2'} $val3 ") + $indent;
+ $start2 = "$colors{'c1'}$key$sep{'s2'}$colors{'c2'} $val3 ";
+ $holder2 = '';
+ $length += length("$key$sep{'s2'} $val3 ");
+ # print scalar @values,"\n";
+ foreach (@values){
+ # my $l = (length("$_ ") + $length);
+ #print "$l\n";
+ if ( (length("$_ ") + $length) < $size{'max'} ){
+ #print "three.1\n";
+ #print "a\n";
+ if ($start2){
+ $holder2 .= "$start2$_ ";
$start2 = '';
- $start = '';
+ #$length += $length2;
#$length2 = 0;
}
+ else {
+ $holder2 .= "$_ ";
+ }
+ $length += length("$_ ");
}
- if ($holder2 !~ /^\s*$/){
- #print "four\n";
- $holder2 = "$colors{'c2'}$holder2";
+ else {
+ #print "three.2\n";
+ if ($start2){
+ $holder2 = "$start2$holder2";
+ }
+ else {
+ $holder2 = "$colors{'c2'}$holder2";
+ }
+ #print "xx:$holder";
$line = sprintf("%-${indent}s%s$colors{'cn'}\n","$start","$holder$holder2");
print_line($line);
$holder = '';
- $holder2 = '';
- $length = $indent;
+ $holder2 = "$_ ";
+ #print "h2: $holder2\n";
+ $length = length($holder2) + $indent;
$start2 = '';
$start = '';
#$length2 = 0;
}
}
- else {
- #print "H: $counter $hash\n";
- if ($holder){
- #print "five\n";
- $line = sprintf("%-${indent}s%s$colors{'cn'}\n",$start,"$holder");
- $holder = "$colors{'c1'}$key$sep{'s2'}$colors{'c2'} $val2";
- $length = length("$key$sep{'s2'} $val2") + $indent;
- print_line($line);
- $start = '';
- }
- else {
- #print "six\n";
- $holder = "$colors{'c1'}$key$sep{'s2'}$colors{'c2'} $val2";
- #$line = sprintf("%-${indent}s%s$colors{'cn'}\n",$start,"$holder");
- $length = $indent;
- #$holder = '';
- }
+ if ($holder2 !~ /^\s*$/){
+ #print "four\n";
+ $holder2 = "$colors{'c2'}$holder2";
+ $line = sprintf("%-${indent}s%s$colors{'cn'}\n","$start","$holder$holder2");
+ print_line($line);
+ $holder = '';
+ $holder2 = '';
+ $length = $indent;
+ $start2 = '';
+ $start = '';
+ #$length2 = 0;
}
- $counter++;
}
- if ($holder !~ /^\s*$/){
- #print "seven\n";
- $line = sprintf("%-${indent}s%s$colors{'cn'}\n",$start,"$start2$holder");
- print_line($line);
- $holder = '';
- $length = 0;
- $start = '';
+ # NOTE: only these and the last fallback are used for b_single output
+ else {
+ #print "H: $counter " . scalar %$val1 . " $indent3 $indent2\n";
+ if ($holder){
+ #print "five\n";
+ $line = sprintf("%-${indent_use}s%s$colors{'cn'}\n",$start,"$holder");
+ $length = length("$key$sep{'s2'} $val2") + $indent_use;
+ print_line($line);
+ $start = '';
+ }
+ else {
+ #print "six\n";
+ $length = $indent_use;
+ #$holder = '';
+ }
+ $holder = "$colors{'c1'}$key$sep{'s2'}$colors{'c2'} $val2";
}
+ $counter++;
+ $indent_use = ($indent * $indentx) if $b_single;
}
- # only for repos?
- elsif (ref($val1) eq 'ARRAY'){
- #print "eight\n";
- $array=0;
- foreach my $item (@$val1){
- $array++;
- $line = "$colors{'c1'}$array$sep{'s2'} $colors{'c2'}$item$colors{'cn'}";
- $line = sprintf("%-${indent}s%s\n","","$line");
- print_line($line);
- }
+ if ($holder !~ /^\s*$/){
+ #print "seven\n";
+ $line = sprintf("%-${indent_use}s%s$colors{'cn'}\n",$start,"$start2$holder");
+ print_line($line);
+ $holder = '';
+ $length = 0;
+ $start = '';
}
- else {
-
+ }
+ # only for repos currently
+ elsif (ref($val1) eq 'ARRAY'){
+ #print "eight\n";
+ $array=0;
+ foreach my $item (@$val1){
+ $array++;
+ $indent_use = ($b_single) ? $indent + 2: $indent;
+ $line = "$colors{'c1'}$array$sep{'s2'} $colors{'c2'}$item$colors{'cn'}";
+ $line = sprintf("%-${indent_use}s%s\n","","$line");
+ print_line($line);
}
}
}
+ # we want a space between data blocks for single
+ print_line("\n") if $b_single;
}
}
@@ -5954,7 +6242,7 @@ sub get {
my $type = ($b_arm) ? 'arm' : 'mips';
my $key = 'Message';
@data = ({
- main::key($num++,$key) => main::row_defaults($type . '-pci',''),
+ main::key($num++,0,1,$key) => main::row_defaults($type . '-pci',''),
},);
@rows = (@rows,@data);
}
@@ -5976,7 +6264,7 @@ sub get {
$type = 'pci-card-data-root';
}
@data = ({
- main::key($num++,$key) => main::row_defaults($type,''),
+ main::key($num++,0,1,$key) => main::row_defaults($type,''),
},);
@rows = (@rows,@data);
}
@@ -6003,22 +6291,26 @@ sub card_data {
$card = main::pci_long_filter($card);
}
@data = ({
- main::key($num++,'Device') => $card,
+ main::key($num++,1,1,'Device') => $card,
},);
@rows = (@rows,@data);
if ($extra > 0 && $b_pci_tool && $row[12]){
my $item = main::get_pci_vendor($row[4],$row[12]);
- $rows[$j]{main::key($num++,'vendor')} = $item if $item;
+ $rows[$j]{main::key($num++,0,2,'vendor')} = $item if $item;
}
- $rows[$j]{main::key($num++,'driver')} = $driver;
+ $rows[$j]{main::key($num++,1,2,'driver')} = $driver;
if ($extra > 0 && !$bsd_type){
if ($row[9] ){
my $version = main::get_module_version($row[9]);
- $rows[$j]{main::key($num++,'v')} = $version if $version;
+ $rows[$j]{main::key($num++,0,3,'v')} = $version if $version;
}
}
+ if ($b_admin && $row[10]){
+ $row[10] = main::get_driver_modules($row[9],$row[10]);
+ $rows[$j]{main::key($num++,0,3,'alternate')} = $row[10] if $row[10];
+ }
if ($extra > 0){
- $rows[$j]{main::key($num++,'bus ID')} = (!$row[2] && !$row[3]) ? 'N/A' : "$row[2].$row[3]";
+ $rows[$j]{main::key($num++,0,2,'bus ID')} = (!$row[2] && !$row[3]) ? 'N/A' : "$row[2].$row[3]";
}
if ($extra > 1){
my $chip_id = 'N/A';
@@ -6028,7 +6320,7 @@ sub card_data {
elsif ($row[6]){
$chip_id = $row[6];
}
- $rows[$j]{main::key($num++,'chip ID')} = $chip_id;
+ $rows[$j]{main::key($num++,0,2,'chip ID')} = $chip_id;
}
#print "$row[0]\n";
}
@@ -6060,14 +6352,14 @@ sub asound_data {
$j = scalar @rows;
$driver ||= 'N/A';
@data = ({
- main::key($num++,'Device') => $card,
- main::key($num++,'driver') => $driver,
+ main::key($num++,1,1,'Device') => $card,
+ main::key($num++,1,2,'driver') => $driver,
},);
@rows = (@rows,@data);
if ($extra > 0){
my $version = main::get_module_version($driver);
- $rows[$j]{main::key($num++,'v')} = $version if $version;
- $rows[$j]{main::key($num++,'message')} = main::row_defaults('pci-advanced-data','');
+ $rows[$j]{main::key($num++,0,3,'v')} = $version if $version;
+ $rows[$j]{main::key($num++,0,2,'message')} = main::row_defaults('pci-advanced-data','');
}
}
}
@@ -6111,20 +6403,20 @@ sub usb_data {
$product ||= 'N/A';
$driver ||= 'snd-usb-audio';
@data = ({
- main::key($num++,'Device') => $product,
- main::key($num++,'type') => 'USB',
- main::key($num++,'driver') => $driver,
+ main::key($num++,1,1,'Device') => $product,
+ main::key($num++,0,2,'type') => 'USB',
+ main::key($num++,0,2,'driver') => $driver,
},);
@rows = (@rows,@data);
if ($extra > 0){
- $rows[$j]{main::key($num++,'bus ID')} = "$path_id:$row[1]";
+ $rows[$j]{main::key($num++,0,2,'bus ID')} = "$path_id:$row[1]";
}
if ($extra > 1){
$row[7] ||= 'N/A';
- $rows[$j]{main::key($num++,'chip ID')} = $row[7];
+ $rows[$j]{main::key($num++,0,2,'chip ID')} = $row[7];
}
if ($extra > 2 && $row[16]){
- $rows[$j]{main::key($num++,'serial')} = main::apply_filter($row[16]);
+ $rows[$j]{main::key($num++,0,2,'serial')} = main::apply_filter($row[16]);
}
}
}
@@ -6158,8 +6450,8 @@ sub sound_server_data {
}
if ($server){
@data = ({
- main::key($num++,'Sound Server') => $server,
- main::key($num++,'v') => $version,
+ main::key($num++,1,1,'Sound Server') => $server,
+ main::key($num++,0,2,'v') => $version,
},);
}
eval $end if $b_log;
@@ -6181,7 +6473,7 @@ sub get {
$key1 = $$ref{'action'};
$val1 = $$ref{$key1};
$key1 = ucfirst($key1);
- @rows = ({main::key($num++,$key1) => $val1,});
+ @rows = ({main::key($num++,0,1,$key1) => $val1,});
}
else {
%battery = battery_data_dmi();
@@ -6189,7 +6481,7 @@ sub get {
if ($show{'battery-forced'}){
$key1 = 'Message';
$val1 = main::row_defaults('battery-data','');
- @rows = ({main::key($num++,$key1) => $val1,});
+ @rows = ({main::key($num++,0,1,$key1) => $val1,});
}
}
else {
@@ -6203,7 +6495,7 @@ sub get {
if ($show{'battery-forced'}){
$key1 = 'Message';
$val1 = main::row_defaults('battery-data','');
- @rows = ({main::key($num++,$key1) => $val1,});
+ @rows = ({main::key($num++,0,1,$key1) => $val1,});
}
}
else {
@@ -6214,7 +6506,7 @@ sub get {
if ($show{'battery-forced'}){
$key1 = 'Message';
$val1 = main::row_defaults('battery-data-sys','');
- @rows = ({main::key($num++,$key1) => $val1,});
+ @rows = ({main::key($num++,0,1,$key1) => $val1,});
}
}
(@upower_items,$b_upower,$upower) = undef;
@@ -6277,9 +6569,9 @@ sub create_output {
$condition ||= 'N/A';
$j = scalar @rows;
@data = ({
- main::key($num++,'ID') => $key,
- main::key($num++,'charge') => $charge,
- main::key($num++,'condition') => $condition,
+ main::key($num++,1,1,'ID') => $key,
+ main::key($num++,0,2,'charge') => $charge,
+ main::key($num++,0,2,'condition') => $condition,
},);
@rows = (@rows,@data);
if ($extra > 0){
@@ -6290,7 +6582,7 @@ sub create_output {
$volts = "$battery{$key}{'voltage_now'}/$battery{$key}{'voltage_min_design'}";
}
$volts ||= 'N/A';
- $rows[$j]{main::key($num++,'volts')} = $volts;
+ $rows[$j]{main::key($num++,0,2,'volts')} = $volts;
}
if ($battery{$key}{'manufacturer'} || $battery{$key}{'model_name'}) {
if ($battery{$key}{'manufacturer'} && $battery{$key}{'model_name'}){
@@ -6306,23 +6598,23 @@ sub create_output {
else {
$model = 'N/A';
}
- $rows[$j]{main::key($num++,'model')} = $model;
+ $rows[$j]{main::key($num++,0,2,'model')} = $model;
if ($extra > 2){
$chemistry = ( $battery{$key}{'technology'} ) ? $battery{$key}{'technology'}: 'N/A';
- $rows[$j]{main::key($num++,'type')} = $chemistry;
+ $rows[$j]{main::key($num++,0,2,'type')} = $chemistry;
}
if ($extra > 1){
$serial = main::apply_filter($battery{$key}{'serial_number'});
- $rows[$j]{main::key($num++,'serial')} = $serial;
+ $rows[$j]{main::key($num++,0,2,'serial')} = $serial;
}
$status = ($battery{$key}{'status'}) ? $battery{$key}{'status'}: 'N/A';
- $rows[$j]{main::key($num++,'status')} = $status;
+ $rows[$j]{main::key($num++,0,2,'status')} = $status;
if ($extra > 2){
if ($battery{$key}{'cycle_count'}){
- $rows[$j]{main::key($num++,'cycles')} = $battery{$key}{'cycle_count'};
+ $rows[$j]{main::key($num++,0,2,'cycles')} = $battery{$key}{'cycle_count'};
}
if ($battery{$key}{'location'}){
- $rows[$j]{main::key($num++,'location')} = $battery{$key}{'location'};
+ $rows[$j]{main::key($num++,0,2,'location')} = $battery{$key}{'location'};
}
}
}
@@ -6363,19 +6655,19 @@ sub create_output {
$model = 'N/A';
}
@data = ({
- main::key($num++,'Device') => $key,
- main::key($num++,'model') => $model,
+ main::key($num++,1,1,'Device') => $key,
+ main::key($num++,0,2,'model') => $model,
},);
@rows = (@rows,@data);
if ($extra > 1){
$serial = main::apply_filter($battery{$key}{'serial_number'});
- $rows[$j]{main::key($num++,'serial')} = $serial;
+ $rows[$j]{main::key($num++,0,2,'serial')} = $serial;
}
- $rows[$j]{main::key($num++,'charge')} = $charge;
+ $rows[$j]{main::key($num++,0,2,'charge')} = $charge;
if ($extra > 2 && $upower_data{'rechargeable'}){
- $rows[$j]{main::key($num++,'rechargeable')} = $upower_data{'rechargeable'};
+ $rows[$j]{main::key($num++,0,2,'rechargeable')} = $upower_data{'rechargeable'};
}
- $rows[$j]{main::key($num++,'status')} = $status;
+ $rows[$j]{main::key($num++,0,2,'status')} = $status;
}
}
eval $end if $b_log;
@@ -6408,6 +6700,7 @@ sub battery_data_sys {
$battery{$id}{'purpose'} = 'mains';
}
if ($value){
+ $value = main::trimmer($value);
if ($file eq 'voltage_min_design'){
$value = sprintf("%.1f", $value/1000000);
}
@@ -6631,7 +6924,7 @@ sub create_output_full {
else {
$key1 = ucfirst($alerts{'sysctl'}{'action'});
$val1 = $alerts{'sysctl'}{$alerts{'sysctl'}{'action'}};
- @data = ({main::key($num++,$key1) => $val1,});
+ @data = ({main::key($num++,0,1,$key1) => $val1,});
return @data;
}
}
@@ -6644,8 +6937,8 @@ sub create_output_full {
my $j = scalar @rows;
$cpu{'model_name'} ||= 'N/A';
@data = ({
- main::key($num++,'Topology') => $properties{'cpu-layout'},
- main::key($num++,'model') => $cpu{'model_name'},
+ main::key($num++,1,1,'Info') => $properties{'cpu-layout'},
+ main::key($num++,0,2,'model') => $cpu{'model_name'},
},);
@rows = (@rows,@data);
if ($cpu{'system-cpus'}){
@@ -6655,38 +6948,48 @@ sub create_output_full {
my $counter = ( %system_cpus && scalar keys %system_cpus > 1 ) ? '-' : '';
foreach my $key (keys %system_cpus){
$counter = '-' . $i++ if $counter;
- $rows[$j]{main::key($num++,'variant'.$counter)} = $key;
+ $rows[$j]{main::key($num++,0,2,'variant'.$counter)} = $key;
+ }
+ }
+ if ($b_admin && $properties{'socket'}){
+ if ($properties{'upgrade'}){
+ $rows[$j]{main::key($num++,1,2,'socket')} = $properties{'socket'} . ' (' . $properties{'upgrade'} . ')';
+ $rows[$j]{main::key($num++,0,3,'note')} = 'check';
+ }
+ else {
+ $rows[$j]{main::key($num++,0,2,'socket')} = $properties{'socket'};
}
}
$properties{'bits-sys'} ||= 'N/A';
- $rows[$j]{main::key($num++,'bits')} = $properties{'bits-sys'};
+ $rows[$j]{main::key($num++,0,2,'bits')} = $properties{'bits-sys'};
if ($type){
- $rows[$j]{main::key($num++,'type')} = $type;
+ $rows[$j]{main::key($num++,0,2,'type')} = $type;
}
if ($extra > 0){
$cpu{'arch'} ||= 'N/A';
- $rows[$j]{main::key($num++,'arch')} = $cpu{'arch'};
+ $rows[$j]{main::key($num++,0,2,'arch')} = $cpu{'arch'};
if ( !$b_admin && $cpu{'arch'} ne 'N/A' && $cpu{'rev'} ){
- $rows[$j]{main::key($num++,'rev')} = $cpu{'rev'};
+ $rows[$j]{main::key($num++,0,2,'rev')} = $cpu{'rev'};
}
}
if ($b_admin){
- $rows[$j]{main::key($num++,'family')} = hex_and_decimal($cpu{'family'});
- $rows[$j]{main::key($num++,'model-id')} = hex_and_decimal($cpu{'model_id'});
- $rows[$j]{main::key($num++,'stepping')} = hex_and_decimal($cpu{'rev'});
+ $rows[$j]{main::key($num++,0,2,'family')} = hex_and_decimal($cpu{'family'});
+ $rows[$j]{main::key($num++,0,2,'model-id')} = hex_and_decimal($cpu{'model_id'});
+ $rows[$j]{main::key($num++,0,2,'stepping')} = hex_and_decimal($cpu{'rev'});
$cpu{'microcode'} ||= 'N/A';
- $rows[$j]{main::key($num++,'microcode')} = $cpu{'microcode'};
+ $rows[$j]{main::key($num++,0,2,'microcode')} = $cpu{'microcode'};
}
if ($extra > 1 && $properties{'l1-cache'}){
- $rows[$j]{main::key($num++,'L1 cache')} = $properties{'l1-cache'};
+ $rows[$j]{main::key($num++,0,2,'L1 cache')} = $properties{'l1-cache'};
}
$properties{'l2-cache'} ||= 'N/A';
if (!$b_arm || ($b_arm && $properties{'l2-cache'} ne 'N/A')){
- $rows[$j]{main::key($num++,'L2 cache')} = $properties{'l2-cache'};
+ $rows[$j]{main::key($num++,0,2,'L2 cache')} = $properties{'l2-cache'};
}
if ($extra > 1 && $properties{'l3-cache'}){
- $rows[$j]{main::key($num++,'L3 cache')} = $properties{'l3-cache'};
+ $rows[$j]{main::key($num++,0,2,'L3 cache')} = $properties{'l3-cache'};
}
+
if ($extra > 0 && !$show{'cpu-flag'}){
$j = scalar @rows;
@flags = split /\s+/, $cpu{'flags'} if $cpu{'flags'};
@@ -6703,14 +7006,14 @@ sub create_output_full {
$flag = main::row_defaults('arm-cpu-f');
}
@data = ({
- main::key($num++,$flag_key) => $flag,
+ main::key($num++,0,2,$flag_key) => $flag,
},);
@rows = (@rows,@data);
$b_flags = 1;
}
if ($extra > 0 && !$bsd_type){
my $bogomips = (main::is_numeric($cpu{'bogomips'})) ? int($cpu{'bogomips'}) : 'N/A';
- $rows[$j]{main::key($num++,'bogomips')} = $bogomips;
+ $rows[$j]{main::key($num++,0,2,'bogomips')} = $bogomips;
}
$j = scalar @rows;
my $core_key = (scalar @speeds > 1) ? 'Core speeds (MHz)' : 'Core speed (MHz)';
@@ -6733,20 +7036,29 @@ sub create_output_full {
}
$j = scalar @rows;
@data = ({
- main::key($num++,$speed_key) => $speed,
- main::key($num++,$min_max_key) => $min_max,
+ main::key($num++,1,1,$speed_key) => $speed,
+ main::key($num++,0,2,$min_max_key) => $min_max,
});
@rows = (@rows,@data);
+ if ($b_admin && $properties{'dmi-speed'} && $properties{'dmi-max-speed'}){
+ $rows[$j]{main::key($num++,0,2,'base/boost')} = $properties{'dmi-speed'} . '/' . $properties{'dmi-max-speed'};
+ }
if ($extra > 2){
my $boost = get_boost_status();
- $rows[$j]{main::key($num++,'boost')} = $boost if $boost;
+ $rows[$j]{main::key($num++,0,2,'boost')} = $boost if $boost;
+ if ($properties{'volts'}){
+ $rows[$j]{main::key($num++,0,2,'volts')} = $properties{'volts'} . ' V';
+ }
+ if ($properties{'ext-clock'}){
+ $rows[$j]{main::key($num++,0,2,'ext-clock')} = $properties{'ext-clock'};
+ }
}
- $rows[$j]{main::key($num++,$core_key)} = $core_speeds_value;
+ $rows[$j]{main::key($num++,1,2,$core_key)} = $core_speeds_value;
my $i = 1;
# if say 96 0 speed cores, no need to print all those 0s
if ($b_speeds){
foreach (@speeds){
- $rows[$j]{main::key($num++,$i++)} = $_;
+ $rows[$j]{main::key($num++,0,3,$i++)} = $_;
}
}
if ($show{'cpu-flag'} && !$b_flags){
@@ -6758,7 +7070,7 @@ sub create_output_full {
$flag = join ' ', @flags if @flags;
}
@data = ({
- main::key($num++,$flag_key) => $flag,
+ main::key($num++,0,1,$flag_key) => $flag,
},);
@rows = (@rows,@data);
}
@@ -6769,22 +7081,22 @@ sub create_output_full {
if ( $cpu{'bugs'}){
my @proc_bugs = split /\s+/, $cpu{'bugs'};
@proc_bugs = sort(@proc_bugs);
- $value = join ' ', @bugs;
+ $value = join ' ', @proc_bugs;
}
else {
$value = main::row_defaults('cpu-bugs-null');
}
}
@data = ({
- main::key($num++,'Vulnerabilities') => $value,
+ main::key($num++,1,1,'Vulnerabilities') => $value,
},);
@rows = (@rows,@data);
if (@bugs){
$j = $#rows;
foreach my $ref (@bugs){
my @bug = @$ref;
- $rows[$j]{main::key($num++,'Type')} = $bug[0];
- $rows[$j]{main::key($num++,$bug[1])} = $bug[2];
+ $rows[$j]{main::key($num++,1,2,'Type')} = $bug[0];
+ $rows[$j]{main::key($num++,0,3,$bug[1])} = $bug[2];
$j++;
}
}
@@ -6800,15 +7112,15 @@ sub create_output_short {
$cpu[1] ||= main::row_defaults('cpu-model-null');
$cpu[2] ||= 'N/A';
@data = ({
- main::key($num++,$cpu[0]) => $cpu[1],
- main::key($num++,'type') => $cpu[2],
+ main::key($num++,1,1,'Info') => $cpu[0] . ' ' . $cpu[1] . ' [' . $cpu[2] . ']',
+ #main::key($num++,0,2,'type') => $cpu[2],
},);
if ($extra > 0){
- $data[0]{main::key($num++,'arch')} = $cpu[7];
+ $data[0]{main::key($num++,0,2,'arch')} = $cpu[7];
}
- $data[0]{main::key($num++,$cpu[3])} = $cpu[4];
+ $data[0]{main::key($num++,0,2,$cpu[3])} = $cpu[4];
if ($cpu[6]){
- $data[0]{main::key($num++,$cpu[5])} = $cpu[6];
+ $data[0]{main::key($num++,0,2,$cpu[5])} = $cpu[6];
}
eval $end if $b_log;
return @data;
@@ -6842,7 +7154,7 @@ sub data_short {
else {
$key1 = ucfirst($alerts{'sysctl'}{'action'});
$val1 = $alerts{'sysctl'}{$alerts{'sysctl'}{'action'}};
- @data = ({main::key($num++,$key1) => $val1,});
+ @data = ({main::key($num++,0,1,$key1) => $val1,});
return @data;
}
}
@@ -7188,18 +7500,18 @@ sub data_sysctl {
# freebsd 10: hw.model: AMD Athlon(tm) II X2 245 Processor
$line[1] = main::cleaner($line[1]);
$line[1] = cpu_cleaner($line[1]);
- if ( $line[1] =~ /([0-9]+)[\-[:space:]]*([KM]B)\s+L2 cache/) {
+ if ( $line[1] =~ /([0-9]+)[-[:space:]]*([KM]B)\s+L2 cache/) {
my $multiplier = ($2 eq 'MB') ? 1024: 1;
$cpu{'l2-cache'} = $1 * $multiplier;
}
- if ( $line[1] =~ /([^0-9\.][0-9\.]+)[\-[:space:]]*[MG]Hz/) {
+ if ( $line[1] =~ /([^0-9\.][0-9\.]+)[-[:space:]]*[MG]Hz/) {
$cpu{'max-freq'} = $1;
if ($cpu{'max-freq'} =~ /MHz/i) {
- $cpu{'max-freq'} =~ s/[\-[:space:]]*MHz//;
+ $cpu{'max-freq'} =~ s/[-[:space:]]*MHz//;
$cpu{'max-freq'} = speed_cleaner($cpu{'max-freq'},'mhz');
}
elsif ($cpu{'max-freq'} =~ /GHz/) {
- $cpu{'max-freq'} =~ s/[\-[:space:]]*GHz//i;
+ $cpu{'max-freq'} =~ s/[-[:space:]]*GHz//i;
$cpu{'max-freq'} = $cpu{'max-freq'} / 1000;
$cpu{'max-freq'} = speed_cleaner($cpu{'max-freq'},'mhz');
}
@@ -7352,6 +7664,7 @@ sub cpu_properties {
#print Data::Dumper::Dumper \@processors;
# $cpu_cores is per physical cpu
my ($cpu_layout,$cpu_type,$min_max,$min_max_key) = ('','','','');
+ my ($dmi_max_speed,$dmi_speed,$ext_clock,$socket,$upgrade,$volts) = (undef);
my ($l1_cache,$l2_cache,$l3_cache,$core_count,$cpu_cores,$die_count) = (0,0,0,0,0,0);
# note: elbrus supports turning off cores, so we need to add one for cases where rounds to 0 or 1 less
if ($b_elbrus && $processors_count){
@@ -7365,12 +7678,18 @@ sub cpu_properties {
if ($extra > 1){
# note: dmidecode has one entry per cpu per cache type, so this already
# has done the arithmetic on > 1 cpus for L1 and L3.
- my %caches = cpu_cache_dmi();
- $l1_cache = $caches{'L1'} if $caches{'L1'};
- $l3_cache = $caches{'L3'} if $caches{'L3'};
+ my %cpu_dmi = cpu_dmi_data();
+ $l1_cache = $cpu_dmi{'L1'} if $cpu_dmi{'L1'};
+ $l3_cache = $cpu_dmi{'L3'} if $cpu_dmi{'L3'};
# bsd sysctl can have these values so let's check just in case
$l1_cache = $cpu{'l1-cache'} * $phyical_count if !$l1_cache && $cpu{'l1-cache'};
$l3_cache = $cpu{'l3-cache'} * $phyical_count if !$l3_cache && $cpu{'l3-cache'};
+ $dmi_max_speed = $cpu_dmi{'max-speed'} if $cpu_dmi{'max-speed'};
+ $socket = $cpu_dmi{'socket'} if $cpu_dmi{'socket'};
+ $upgrade = $cpu_dmi{'upgrade'} if $cpu_dmi{'upgrade'};
+ $dmi_speed = $cpu_dmi{'speed'} if $cpu_dmi{'speed'};
+ $ext_clock = $cpu_dmi{'ext-clock'} if $cpu_dmi{'ext-clock'};
+ $volts = $cpu_dmi{'volts'} if $cpu_dmi{'volts'};
}
foreach my $die_ref ( @phys ){
next if ! $die_ref;
@@ -7587,10 +7906,16 @@ sub cpu_properties {
'bits-sys' => $bits_sys,
'cpu-layout' => $cpu_layout,
'cpu-type' => $cpu_type,
+ 'dmi-max-speed' => $dmi_max_speed,
+ 'dmi-speed' => $dmi_speed,
+ 'ext-clock' => $ext_clock,
'min-max-key' => $min_max_key,
'min-max' => $min_max,
+ 'socket' => $socket,
'speed-key' => $speed_key,
'speed' => $speed,
+ 'upgrade' => $upgrade,
+ 'volts' => $volts,
'l1-cache' => $l1_cache,
'l2-cache' => $l2_cache,
'l3-cache' => $l3_cache,
@@ -7603,41 +7928,96 @@ sub cpu_properties {
eval $end if $b_log;
return %cpu_properties;
}
-sub cpu_cache_dmi {
+sub cpu_dmi_data {
eval $start if $b_log;
return if !@dmi;
- my %caches = ('L1' => 0, 'L2' => 0,'L3' => 0);
- my ($id,$amount);
+ my %dmi_data = ('L1' => 0, 'L2' => 0,'L3' => 0, 'ext-clock' => undef, 'socket' => undef,
+ 'speed' => undef, 'max-speed' => undef, 'upgrade' => undef, 'volts' => undef);
+ my ($id,$amount,$socket,$upgrade);
foreach my $ref (@dmi){
next if ref $ref ne 'ARRAY';
my @item = @$ref;
- next if $item[0] != 7;
+ next if ($item[0] < 4 || $item[0] == 5 || $item[0] == 6);
last if $item[0] > 7;
- # skip first three row, we don't need that data
- splice @item, 0, 3;
- ($id,$amount) = ('',0);
- foreach my $value (@item){
- # variants: L3 - Cache; L3 Cache; L3-cache; CPU Internal L1
- if ($value =~ /^Socket Designation:.* (L[1-3])\b/){
- $id = $1;
- }
- # some cpus only show Socket Designation: Internal cache
- elsif (!$id && $value =~ /^Configuration:.* Level.*([1-3])\b/){
- $id = "L$1";
- }
- elsif ($id && $value =~ /^Installed Size:\s+(.*B)$/){
- $amount = main::translate_size($1);
- }
- if ($id && $amount){
- $caches{$id} += $amount;
- last;
+ if ($item[0] == 7){
+ # skip first three row, we don't need that data
+ splice @item, 0, 3;
+ ($id,$amount) = ('',0);
+ foreach my $value (@item){
+ next if $value =~ /~/;
+ # variants: L3 - Cache; L3 Cache; L3-cache; CPU Internal L1
+ if ($value =~ /^Socket Designation:.* (L[1-3])\b/){
+ $id = $1;
+ }
+ # some cpus only show Socket Designation: Internal cache
+ elsif (!$id && $value =~ /^Configuration:.* Level.*([1-3])\b/){
+ $id = "L$1";
+ }
+ elsif ($id && $value =~ /^Installed Size:\s+(.*B)$/){
+ $amount = main::translate_size($1);
+ }
+ if ($id && $amount){
+ $dmi_data{$id} += $amount;
+ last;
+ }
+ }
+ }
+ # note: for multi cpu systems, we're hoping that these values are
+ # the same for each cpu, which in most pc situations they will be,
+ # and ARM etc won't be using dmi data here anyway.
+ # Older dmidecode appear to have unreliable Upgrade outputs
+ elsif ($item[0] == 4){
+ # skip first three row, we don't need that data
+ splice @item, 0, 3;
+ ($socket,$upgrade) = (undef);
+ foreach my $value (@item){
+ next if $value =~ /~/;
+ # note: on single cpu systems, Socket Designation shows socket type,
+ # but on multi, shows like, CPU1; CPU Socket #2; Socket 0; so check values a bit.
+ # Socket Designation: Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz
+ # Sometimes shows as CPU Socket...
+ if ($value =~ /^Socket Designation:\s*(CPU\s*Socket|Socket)?[\s-]*(.*)$/i){
+ $upgrade = main::dmi_cleaner($2) if $2 !~ /(cpu|[mg]hz|onboard|socket|@|^#?[0-9]$)/i;
+ #print "$socket_temp\n";
+ }
+ # normally we prefer this value, but sometimes it's garbage
+ # older systems often show: Upgrade: ZIF Socket which is a generic term, legacy
+ elsif ($value =~ /^Upgrade:\s*(CPU\s*Socket|Socket)?[\s-]*(.*)$/i){
+ #print "$2\n";
+ $socket = main::dmi_cleaner($2) if $2 !~ /(ZIF|\bslot\b)/i;
+ }
+ # seen: Voltage: 5.0 V 2.9 V
+ elsif ($value =~ /^Voltage:\s*([0-9\.]+)\s*(V|Volts)?\b/i){
+ $dmi_data{'volts'} = main::dmi_cleaner($1);
+ }
+ elsif ($value =~ /^Current Speed:\s*([0-9\.]+)\s*([MGK]Hz)?\b/i){
+ $dmi_data{'speed'} = main::dmi_cleaner($1);
+ }
+ elsif ($value =~ /^Max Speed:\s*([0-9\.]+)\s*([MGK]Hz)?\b/i){
+ $dmi_data{'max-speed'} = main::dmi_cleaner($1);
+ }
+ elsif ($value =~ /^External Clock:\s*([0-9\.]+\s*[MGK]Hz)\b/){
+ $dmi_data{'ext-clock'} = main::dmi_cleaner($1);
+ }
}
}
}
- main::log_data('dump','%caches',\%caches) if $b_log;
- #print Data::Dumper::Dumper \%caches;
+ # Seen older cases where Upgrade: Other value exists
+ if ($socket || $upgrade){
+ if ($socket && $upgrade){
+ $upgrade = undef if $socket eq $upgrade;
+ }
+ elsif ($upgrade){
+ $socket = $upgrade;
+ $upgrade = undef;
+ }
+ $dmi_data{'socket'} = $socket;
+ $dmi_data{'upgrade'} = $upgrade;
+ }
+ main::log_data('dump','%dmi_data',\%dmi_data) if $b_log;
+ # print Data::Dumper::Dumper \%dmi_data;
eval $end if $b_log;
- return %caches;
+ return %dmi_data;
}
sub cpu_bugs_sys {
eval $start if $b_log;
@@ -7968,7 +8348,11 @@ sub cpu_arch {
elsif ($family eq '17'){
if ( $model =~ /^(1|11)$/ ) {$arch = 'Zen'}
elsif ( $model =~ /^(8|18)$/ ) {$arch = 'Zen+'}
- elsif ( $model =~ /^2[0123456789ABCDEF]$/ ) {$arch = 'Zen 2'}
+ # not positive about 2x, main resource shows only 31 and 71 hex
+ elsif ( $model =~ /^(2[0123456789ABCDEF]|31|71)$/ ) {$arch = 'Zen 2'}
+ # no info on these yet, but they are coming and are scheduled
+ # elsif ( $model =~ /^()$/ ) {$arch = 'Zen 3'}
+ # elsif ( $model =~ /^()$/ ) {$arch = 'Zen 4'}
else {$arch = 'Zen'}
}
elsif ($family eq '18'){
@@ -8015,7 +8399,7 @@ sub cpu_arch {
else {$arch = 'Elbrus-8C';}
} # note: stepping > 1 may be 8C1
elsif ( $model eq '8' ) {$arch = 'Elbrus-1C+'}
- elsif ( $model eq '9' ) {$arch = 'Elbrus-8CB'}
+ elsif ( $model eq '9' ) {$arch = 'Elbrus-8CV'}
elsif ( $model eq '10' ) {$arch = 'Elbrus-12C'}
elsif ( $model eq '11' ) {$arch = 'Elbrus-16C'}
elsif ( $model eq '12' ) {$arch = 'Elbrus-2C3'}
@@ -8072,7 +8456,8 @@ sub cpu_arch {
elsif ($model eq '8E' && ($stepping == 11 || $stepping == 12)){$arch = 'Whiskey Lake'}
elsif ($model eq '8E' && $stepping == 9){$arch = 'Amber Lake'}
elsif ($stepping > 13){$arch = 'Comet Lake'} # guess, have not seen docs yet
- elsif ($stepping > 9){$arch = 'Coffee Lake'}
+ # elsif ($stepping > 9 && $stepping < 14){$arch = 'Coffee Lake'}
+ # NOTE: kaby lake is 8E 9 but so is Amber Lake
else {$arch = 'Kaby Lake'} }
#elsif ( $model =~ /^(9E)$/ ) {$arch = 'Coffee Lake'}
elsif ( $model =~ /^(57)$/ ) {$arch = 'Knights Landing'}
@@ -8172,10 +8557,11 @@ sub hex_and_decimal {
## DiskData
{
package DiskData;
-my ($b_hddtemp,$b_nvme);
+my ($b_hddtemp,$b_nvme,$smartctl_missing);
my ($hddtemp,$nvme) = ('','');
-my (@by_id,@by_path);
-
+my (@by_id,@by_path,@vendors);
+my ($debugger_dir);
+# main::writer("$debugger_dir/system-repo-data-urpmq.txt",@data2) if $debugger_dir;
sub get {
eval $start if $b_log;
my (@data,@rows,$key1,$val1);
@@ -8200,7 +8586,7 @@ sub get {
else {
$val1 = main::row_defaults('disk-data-bsd');
}
- @data = ({main::key($num++,$key1) => $val1,});
+ @data = ({main::key($num++,0,1,$key1) => $val1,});
@rows = (@rows,@data);
}
}
@@ -8212,12 +8598,12 @@ sub get {
else {
$key1 = 'Message';
$val1 = main::row_defaults('disk-data');
- @rows = ({main::key($num++,$key1) => $val1,});
+ @rows = ({main::key($num++,0,1,$key1) => $val1,});
}
if (!@rows){
$key1 = 'Message';
$val1 = main::row_defaults('disk-data');
- @data = ({main::key($num++,$key1) => $val1,});
+ @data = ({main::key($num++,0,1,$key1) => $val1,});
}
#@rows = (@rows,@data);
@data = ();
@@ -8234,9 +8620,84 @@ sub create_output {
eval $start if $b_log;
my (@disks) = @_;
#print Data::Dumper::Dumper \@disks;
- my (@data,@rows);
+ my ($b_oldage,$b_prefail,$b_smart,$b_smart_permissions,@data,@rows);
my ($num,$j) = (0,0);
- my ($id,$model,$size,$used,$percent,$size_holder,$used_holder) = ('','','','','','','');
+ my ($id,$model,$size,$used,$percent,$size_holder,
+ $used_holder) = ('','','','','','','');
+ my @smart_basic =(
+ ['smart','SMART'],
+ ['smart-error','SMART Message'],
+ ['smart-support','state'],
+ ['smart-status','health'],
+ ['smart-power-on-hours','on'],
+ ['smart-cycles','cycles'],
+ ['smart-units-read','read-units'],
+ ['smart-units-written','written-units'],
+ ['smart-read','read'],
+ ['smart-written','written'],
+ );
+ my @smart_age =(
+ ['smart-gsense-error-rate-r','g-sense error rate'],
+ ['smart-media-wearout-v','media wearout'],
+ ['smart-media-wearout-t','threshold'],
+ ['smart-media-wearout-f','alert'],
+ ['smart-multizone-errors-v','write error rate'],
+ ['smart-multizone-errors-t','threshold'],
+ ['smart-udma-crc-errors-r','UDMA CRC errors'],
+ ['smart-udma-crc-errors-f','alert'],
+ );
+ my @smart_fail =(
+ ['smart-end-to-end-v','end-to-end'],
+ ['smart-end-to-end-t','threshold'],
+ ['smart-end-to-end-f','alert'],
+ ['smart-raw-read-error-rate-v','read error rate'],
+ ['smart-raw-read-error-rate-t','threshold'],
+ ['smart-raw-read-error-rate-f','alert'],
+ ['smart-reallocated-sectors-v','reallocated sector'],
+ ['smart-reallocated-sectors-t','threshold'],
+ ['smart-reallocated-sectors-f','alert'],
+ ['smart-retired-blocks-v','retired block'],
+ ['smart-retired-blocks-t','threshold'],
+ ['smart-retired-blocks-f','alert'],
+ ['smart-runtime-bad-block-v','runtime bad block'],
+ ['smart-runtime-bad-block-t','threshold'],
+ ['smart-runtime-bad-block-f','alert'],
+ ['smart-seek-error-rate-v', 'seek error rate'],
+ ['smart-seek-error-rate-t', 'threshold'],
+ ['smart-seek-error-rate-f', 'alert'],
+ ['smart-spinup-time-v','spin-up time'],
+ ['smart-spinup-time-t','threshold'],
+ ['smart-spinup-time-f','alert'],
+ ['smart-ssd-life-left-v','life left'],
+ ['smart-ssd-life-left-t','threshold'],
+ ['smart-ssd-life-left-f','alert'],
+ ['smart-unused-reserve-block-v','unused reserve block'],
+ ['smart-unused-reserve-block-t','threshold'],
+ ['smart-unused-reserve-blockf','alert'],
+ ['smart-used-reserve-block-v','used reserve block'],
+ ['smart-used-reserve-block-t','threshold'],
+ ['smart-used-reserve-block-f','alert'],
+ ['smart-unknown-1-a','attribute'],
+ ['smart-unknown-1-v','value'],
+ ['smart-unknown-1-w','worst'],
+ ['smart-unknown-1-t','threshold'],
+ ['smart-unknown-1-f','alert'],
+ ['smart-unknown-2-a','attribute'],
+ ['smart-unknown-2-v','value'],
+ ['smart-unknown-2-w','worst'],
+ ['smart-unknown-2-t','threshold'],
+ ['smart-unknown-2-f','alert'],
+ ['smart-unknown-3-a','attribute'],
+ ['smart-unknown-3-v','value'],
+ ['smart-unknown-3-w','worst'],
+ ['smart-unknown-3-t','threshold'],
+ ['smart-unknown-4-f','alert'],
+ ['smart-unknown-4-a','attribute'],
+ ['smart-unknown-4-v','value'],
+ ['smart-unknown-4-w','worst'],
+ ['smart-unknown-4-t','threshold'],
+ ['smart-unknown-4-f','alert'],
+ );
my @sizing = main::get_size($disks[0]{'size'}) if $disks[0]{'size'};
#print Data::Dumper::Dumper \@disks;
if (@sizing){
@@ -8261,16 +8722,20 @@ sub create_output {
}
$used ||= 'N/A';
@data = ({
- main::key($num++,'Local Storage') => '',
- main::key($num++,'total') => $size,
- main::key($num++,'used') => $used,
+ main::key($num++,1,1,'Local Storage') => '',
+ main::key($num++,0,2,'total') => $size,
+ main::key($num++,0,2,'used') => $used,
});
@rows = (@rows,@data);
shift @disks;
+ if ($smartctl_missing){
+ $j = scalar @rows;
+ $rows[$j]{main::key($num++,0,1,'SMART Message')} = $smartctl_missing;
+ }
if ( $show{'disk'} && @disks){
@disks = sort { $a->{'id'} cmp $b->{'id'} } @disks;
foreach my $ref (@disks){
- ($id,$model,$size) = ('','','');
+ ($b_oldage,$b_prefail,$b_smart,$id,$model,$size) = (0,0,0,'','','');
my %row = %$ref;
$num = 1;
$model = ($row{'model'}) ? $row{'model'}: 'N/A';
@@ -8290,47 +8755,104 @@ sub create_output {
$size = 'N/A';
}
$j = scalar @rows;
+ if (!$b_smart_permissions && $row{'smart-permissions'}){
+ $b_smart_permissions = 1;
+ $rows[$j]{main::key($num++,0,1,'SMART Message')} = $row{'smart-permissions'};
+ $j = scalar @rows;
+ }
@data = ({
- main::key($num++,'ID') => $id,
+ main::key($num++,1,1,'ID') => $id,
});
@rows = (@rows,@data);
if ($row{'type'}){
- $rows[$j]{main::key($num++,'type')} = $row{'type'},
+ $rows[$j]{main::key($num++,0,2,'type')} = $row{'type'};
}
if ($row{'vendor'}){
- $rows[$j]{main::key($num++,'vendor')} = $row{'vendor'},
+ $rows[$j]{main::key($num++,0,2,'vendor')} = $row{'vendor'};
}
- $rows[$j]{main::key($num++,'model')} = $model;
- $rows[$j]{main::key($num++,'size')} = $size;
+ $rows[$j]{main::key($num++,0,2,'model')} = $model;
+ if ($row{'drive-vendor'}){
+ $rows[$j]{main::key($num++,0,2,'drive vendor')} = $row{'drive-vendor'};
+ }
+ if ($row{'drive-model'}){
+ $rows[$j]{main::key($num++,0,2,'drive model')} = $row{'drive-model'};
+ }
+ if ($row{'family'}){
+ $rows[$j]{main::key($num++,0,2,'family')} = $row{'family'};
+ }
+ $rows[$j]{main::key($num++,0,2,'size')} = $size;
if ($b_admin && $row{'block-physical'}){
- $rows[$j]{main::key($num++,'block size')} = '';
- $rows[$j]{main::key($num++,'physical')} = $row{'block-physical'} . ' B';
- $rows[$j]{main::key($num++,'logical')} = ($row{'block-logical'}) ? $row{'block-logical'} . ' B' : 'N/A';
+ $rows[$j]{main::key($num++,1,2,'block size')} = '';
+ $rows[$j]{main::key($num++,0,3,'physical')} = $row{'block-physical'} . ' B';
+ $rows[$j]{main::key($num++,0,3,'logical')} = ($row{'block-logical'}) ? $row{'block-logical'} . ' B' : 'N/A';
}
if ($extra > 1 && $row{'speed'}){
- $rows[$j]{main::key($num++,'speed')} = $row{'speed'};
- $rows[$j]{main::key($num++,'lanes')} = $row{'lanes'} if $row{'lanes'};
+ if ($row{'sata'}){
+ $rows[$j]{main::key($num++,0,2,'sata')} = $row{'sata'};
+ }
+ $rows[$j]{main::key($num++,0,2,'speed')} = $row{'speed'};
+ $rows[$j]{main::key($num++,0,2,'lanes')} = $row{'lanes'} if $row{'lanes'};
}
if ($extra > 2 && $row{'rotation'}){
- $rows[$j]{main::key($num++,'rotation')} = $row{'rotation'};
+ $rows[$j]{main::key($num++,0,2,'rotation')} = $row{'rotation'};
}
if ($extra > 1){
my $serial = main::apply_filter($row{'serial'});
- $rows[$j]{main::key($num++,'serial')} = $serial;
+ $rows[$j]{main::key($num++,0,2,'serial')} = $serial;
+ if ($row{'drive-serial'}){
+ $rows[$j]{main::key($num++,0,2,'drive serial')} = main::apply_filter($row{'drive-serial'});
+ }
if ($row{'firmware'}){
- $rows[$j]{main::key($num++,'rev')} = $row{'firmware'};
+ $rows[$j]{main::key($num++,0,2,'rev')} = $row{'firmware'};
+ }
+ if ($row{'drive-firmware'}){
+ $rows[$j]{main::key($num++,0,2,'drive rev')} = $row{'drive-firmware'};
}
}
if ($extra > 0 && $row{'temp'}){
- $rows[$j]{main::key($num++,'temp')} = $row{'temp'} . ' C';
+ $rows[$j]{main::key($num++,0,2,'temp')} = $row{'temp'} . ' C';
}
# extra level tests already done
if (defined $row{'partition-table'}){
- $rows[$j]{main::key($num++,'scheme')} = $row{'partition-table'};
+ $rows[$j]{main::key($num++,0,2,'scheme')} = $row{'partition-table'};
+ }
+ if ($row{'smart'} || $row{'smart-error'}){
+ $j = scalar @rows;
+ ## Basic SMART and drive info ##
+ for (my $i = 0; $i < scalar @smart_basic;$i++){
+ if ($row{$smart_basic[$i][0]}){
+ if (!$b_smart){
+ my $support = ($row{'smart'}) ? $row{'smart'}: $row{'smart-error'};
+ $rows[$j]{main::key($num++,1,2,$smart_basic[$i][1])} = $support;
+ $b_smart = 1;
+ next;
+ }
+ $rows[$j]{main::key($num++,0,3,$smart_basic[$i][1])} = $row{$smart_basic[$i][0]};
+ }
+ }
+ ## Old-Age errors ##
+ for (my $i = 0; $i < scalar @smart_age;$i++){
+ if ($row{$smart_age[$i][0]}){
+ if (!$b_oldage){
+ $rows[$j]{main::key($num++,1,3,'Old-Age')} = '';
+ $b_oldage = 1;
+ }
+ $rows[$j]{main::key($num++,0,4,$smart_age[$i][1])} = $row{$smart_age[$i][0]};
+ }
+ }
+ ## Pre-Fail errors ##
+ for (my $i = 0; $i < scalar @smart_fail;$i++){
+ if ($row{$smart_fail[$i][0]}){
+ if (!$b_prefail){
+ $rows[$j]{main::key($num++,1,3,'Pre-Fail')} = '';
+ $b_prefail = 1;
+ }
+ $rows[$j]{main::key($num++,0,4,$smart_fail[$i][1])} = $row{$smart_fail[$i][0]};
+ }
+ }
}
}
}
-
eval $end if $b_log;
return @rows;
}
@@ -8346,13 +8868,15 @@ sub disk_data {
# don't count remote used, also, some cases mount
# panfs is parallel NAS volume manager, need more data
next if ($row{'fs'} && $row{'fs'} =~ /cifs|iso9660|nfs|panfs|sshfs|smbfs|unionfs/);
+ # don't count zfs or file type swap
+ next if ($row{'swap-type'} && $row{'swap-type'} ne 'partition');
# in some cases, like redhat, mounted cdrom/dvds show up in partition data
next if ($row{'dev-base'} && $row{'dev-base'} =~ /^sr[0-9]+$/);
# this is used for specific cases where bind, or incorrect multiple mounts
# to same partitions, or btrfs sub volume mounts, is present. The value is
# searched for an earlier appearance of that partition and if it is present,
# the data is not added into the partition used size.
- if ( $row{'dev-base'} !~ /^\/\/|:\// && ! (grep {/$row{'dev-base'}/} @devs) ){
+ if ( $row{'dev-base'} !~ /^(\/\/|:\/)/ && ! (grep {/$row{'dev-base'}/} @devs) ){
$used += $row{'used'} if $row{'used'};
push @devs, $row{'dev-base'};
}
@@ -8363,7 +8887,16 @@ sub disk_data {
else {
@data = dmesg_boot_data($used);
}
- #print Data::Dumper::Dumper \@data;
+ if ($b_admin){
+ my $ref = $alerts{'smartctl'};
+ if ( $ref && $$ref{'action'} eq 'use'){
+ @data = smartctl_data(@data);
+ }
+ else {
+ $smartctl_missing = $$ref{'missing'};
+ }
+ }
+ print Data::Dumper::Dumper \@data if $test[13];;
main::log_data('data',"used: $used") if $b_log;
eval $end if $b_log;
return @data;
@@ -8402,9 +8935,12 @@ sub proc_data {
# special case from this data: 8 0 156290904 sda
# 43 0 48828124 nbd0
# note: known starters: vm: 252/253/254; grsec: 202; nvme: 259 mmcblk: 179
+ # Note: with > 1 nvme drives, the minor number no longer passes the modulus tests,
+ # It appears to just increase randomly from the first 0 minor of the first nvme to
+ # nvme partitions to next nvme, so it only passes the test for the first nvme drive.
if ( $row[0] =~ /^(3|8|22|33|43|179|202|252|253|254|259)$/ &&
$row[-1] =~ /(mmcblk[0-9]+|n[b]?d[0-9]+|nvme[0-9]+n[0-9]+|[hsv]d[a-z]+)$/ &&
- ( $row[1] % 16 == 0 || $row[1] % 16 == 8 ) ) {
+ ( $row[1] % 16 == 0 || $row[1] % 16 == 8 || $row[-1] =~ /(nvme[0-9]+n[0-9]+)$/) ) {
$size += $row[2];
}
}
@@ -8499,10 +9035,10 @@ sub proc_data_advanced {
}
main::log_data('data',"working path: $working_path") if $b_log;
if ($b_admin && -e "/sys/block/"){
- my @working = admin_data($drives[$i]{'id'});
- $drives[$i]{'block-logical'} = $working[0];
- $drives[$i]{'block-physical'} = $working[1];
- }
+ my @working = block_data($drives[$i]{'id'});
+ $drives[$i]{'block-logical'} = $working[0];
+ $drives[$i]{'block-physical'} = $working[1];
+ }
if ($block_type && @scsi && @by_id && ! -e "${working_path}model" && ! -e "${working_path}name"){
## ok, ok, it's incomprehensible, search /dev/disk/by-id for a line that contains the
# discovered disk name AND ends with the correct identifier, sdx
@@ -8689,6 +9225,370 @@ sub dmesg_boot_data {
return @data;
}
+sub smartctl_data {
+ eval $start if $b_log;
+ my (@data) = @_;
+ my ($b_attributes,$b_intel,$b_kingston,$cmd,%holder,$id,@working,@result,@split);
+ my ($splitter,$num,$a,$f,$r,$t,$v,$w,$y) = (':\s*',0,0,8,1,5,3,4,6); # $y is type, $t threashold, etc
+ my $smartctl = main::check_program('smartctl');
+ for (my $i = 0; $i < scalar @data; $i++){
+ next if !$data[$i]{'id'};
+ ($b_attributes,$b_intel,$b_kingston,$splitter,$num,$a,$r) = (0,0,0,':\s*',0,0,1);
+ %holder = ();
+ #print $data[$i]{'id'},"\n";
+ # m2 nvme failed on nvme0n1 drive id:
+ $id = $data[$i]{'id'};
+ $id =~ s/n[0-9]+$// if $id =~ /^nvme/;
+ $cmd = "$smartctl -AHi /dev/" . $id . ' 2>/dev/null';
+ @result = main::grabber("$cmd", '', 'strip');
+ main::log_data('dump','@result', \@result) if $b_log; # log before cleanup
+ @result = grep {!/^(smartctl|Copyright|==)/} @result;
+ print 'Drive:/dev/' . $id . ":\n", Data::Dumper::Dumper\@result if $test[12];
+ if (scalar @result < 4 ){
+ if (grep {/failed: permission denied/i} @result){
+ $data[$i]{'smart-permissions'} = main::row_defaults('smartctl-root');
+ }
+ elsif (grep {/unknown usb bridge/i} @result){
+ $data[$i]{'smart-error'} = main::row_defaults('smartctl-usb');
+ }
+ elsif (grep {/A mandatory SMART command failed/i} @result){
+ $data[$i]{'smart-error'} = main::row_defaults('smartctl-command-failed');
+ }
+ else {
+ $data[$i]{'smart-error'} = main::row_defaults('smartctl-unknown');
+ }
+ next;
+ }
+ else {
+ foreach my $row (@result){
+ if ($row =~ /^ID#/){
+ $splitter = '\s+';
+ $b_attributes = 1;
+ $a = 1;
+ $r = 9;
+ next;
+ }
+ @split = split /$splitter/, $row;
+ next if !$b_attributes && ! defined $split[$r];
+ # some cases where drive not in db threshhold will be: ---
+ # value is usually 0 padded which confuses perl. However this will
+ # make subsequent tests easier, and will strip off leading 0s
+ if ($b_attributes){
+ $split[$t] = (main::is_numeric($split[$t])) ? int($split[$t]) : 0;
+ $split[$v] = (main::is_numeric($split[$v])) ? int($split[$v]) : 0;
+ }
+ ## DEVICE INFO ##
+ if ($split[$a] eq 'Device Model'){
+ $b_intel = 1 if $split[$r] =~/\bintel\b/i;
+ $b_kingston = 1 if $split[$r] =~/kingston/i;
+ # usb/firewire/thunderbolt
+ if ($data[$i]{'type'}){
+ @working = device_vendor("$split[$r]");
+ $data[$i]{'drive-model'} = $working[1] if $data[$i]{'model'} && $data[$i]{'model'} ne $working[1];
+ $data[$i]{'drive-vendor'} = $working[0] if $data[$i]{'vendor'} && $data[$i]{'vendor'} ne $working[0];
+ }
+ }
+ elsif ($split[$a] eq 'Model Family'){
+ @working = device_vendor("$split[$r]");
+ $data[$i]{'family'} = $working[1];
+ # $data[$i]{'family'} =~ s/$data[$i]{'vendor'}\s*// if $data[$i]{'vendor'};
+ }
+ elsif ($split[$a] eq 'Firmware Version'){
+ # 01.01A01 vs 1A01
+ if ($data[$i]{'firmware'} && $split[$r] !~ /$data[$i]{'firmware'}/){
+ $data[$i]{'drive-firmware'} = $split[$r];
+ }
+ elsif (!$data[$i]{'firmware'}){
+ $data[$i]{'firmware'} = $split[$r];
+ }
+ }
+ elsif ($split[$a] eq 'Rotation Rate'){
+ $data[$i]{'rotation'} = $split[$r] if $split[$r] !~ /^Solid/;
+ }
+ elsif ($split[$a] eq 'Serial Number'){
+ if ( !$data[$i]{'serial'}){
+ $data[$i]{'serial'} = $split[$r];
+ }
+ elsif ($data[$i]{'type'} && $split[$r] ne $data[$i]{'serial'}){
+ $data[$i]{'drive-serial'} = $split[$r];
+ }
+ }
+ elsif ($split[$a] eq 'SATA Version is'){
+ if ( $split[$r] =~ /SATA ([0-9.]+), ([0-9.]+ [^\s]+)( \(current: ([1-9.]+ [^\s]+)\))?/){
+ $data[$i]{'sata'} = $1;
+ $data[$i]{'speed'} = $2 if !$data[$i]{'speed'};
+ }
+ }
+ elsif ($split[$a] eq 'Sector Sizes'){
+ if( $data[$i]{'type'} || !$data[$i]{'block-logical'} || !$data[$i]{'block-physical'} ){
+ if ($split[$r] =~ m|^([0-9]+) bytes logical/physical| ){
+ $data[$i]{'block-logical'} = $1;
+ $data[$i]{'block-physical'} = $1;
+ }
+ # 512 bytes logical, 4096 bytes physical
+ elsif ($split[$r] =~ m|^([0-9]+) bytes logical, ([0-9]+) bytes physical|){
+ $data[$i]{'block-logical'} = $1;
+ $data[$i]{'block-physical'} = $2;
+ }
+ }
+ }
+ ## SMART STATUS/HEALTH ##
+ elsif ($split[$a] eq 'SMART support is'){
+ if ($split[$r] =~ /^(Available|Unavailable) /){
+ $data[$i]{'smart'} = $1;
+ $data[$i]{'smart'} = ($data[$i]{'smart'} eq 'Unavailable') ? 'no' : 'yes';
+ }
+ elsif ($split[$r] =~ /^(Enabled|Disabled)/ ){
+ $data[$i]{'smart-support'} = lc($1);
+ }
+ }
+ elsif ($split[$a] eq 'SMART overall-health self-assessment test result' ){
+ $data[$i]{'smart-status'} = $split[$r];
+ # seen nvme that only report smart health, not smart support
+ $data[$i]{'smart'} = 'yes' if !$data[$i]{'smart'};
+ }
+
+ ## DEVICE CONDITION: temp/read/write/power on/cycles ##
+ # Attributes data fields, sometimes are same syntax as info block:...
+ elsif ( $split[$a] eq 'Power_Cycle_Count' || $split[$a] eq 'Power Cycles' ){
+ $data[$i]{'smart-cycles'} = $split[$r] if $split[$r];
+ }
+ elsif ($split[$a] eq 'Power_On_Hours' || $split[$a] eq 'Power On Hours' ||
+ $split[$a] eq 'Power_On_Hours_and_Msec'){
+ if ($split[$r]){
+ $split[$r] =~ s/,//;
+ # trim off: h+0m+00.000s which is useless and at times empty anyway
+ $split[$r] =~ s/h\+.*$// if $split[$a] eq 'Power_On_Hours_and_Msec';
+ # $split[$r] = 43;
+ if ($split[$r] =~ /^([0-9]+)$/){
+ if ($1 > 9000){
+ $data[$i]{'smart-power-on-hours'} = int($1/(24*365)) . 'y ' . int($1/24)%365 . 'd ' . $1%24 . 'h';
+ }
+ elsif ($1 > 100){
+ $data[$i]{'smart-power-on-hours'} = int($1/24) . 'd ' . $1%24 . 'h';
+ }
+ else {
+ $data[$i]{'smart-power-on-hours'} = $split[$r] . ' hrs';
+ }
+ }
+ else {
+ $data[$i]{'smart-power-on-hours'} = $split[$r];
+ }
+ }
+ }
+ # 'Airflow_Temperature_Cel' like: 29 (Min/Max 14/43) so can't use -1 index
+ # Temperature like 29 Celsisu
+ elsif ( $split[$a] eq 'Temperature_Celsius' || $split[$a] eq 'Temperature' ||
+ $split[$a] eq 'Airflow_Temperature_Cel' ) {
+ if (!$data[$i]{'temp'} && $split[$r]){
+ $data[$i]{'temp'} = $split[$r];
+ }
+ }
+ ## DEVICE USE: Reads/Writes ##
+ elsif ($split[$a] eq 'Data Units Read'){
+ $data[$i]{'smart-units-read'} = $split[$r];
+ }
+ elsif ($split[$a] eq 'Data Units Written'){
+ $data[$i]{'smart-units-written'} = $split[$r];
+ }
+ elsif ($split[$a] eq 'Host_Reads_32MiB'){
+ $split[$r] = $split[$r] * 32 * 1024;
+ $data[$i]{'smart-read'} = join ' ', main::get_size($split[$r]);
+ }
+ elsif ($split[$a] eq 'Host_Writes_32MiB'){
+ $split[$r] = $split[$r] * 32 * 1024;
+ $data[$i]{'smart-written'} = join ' ', main::get_size($split[$r]);
+ }
+ elsif ($split[$a] eq 'Lifetime_Reads_GiB'){
+ $data[$i]{'smart-read'} = $split[$r] . ' GiB';
+ }
+ elsif ($split[$a] eq 'Lifetime_Writes_GiB'){
+ $data[$i]{'smart-written'} = $split[$r] . ' GiB';
+ }
+ elsif ($split[$a] eq 'Total_LBAs_Read'){
+ if (main::is_numeric($split[$r])){
+ # blocks in bytes, so convert to KiB, the internal unit here
+ # reports in 32MiB units, sigh
+ if ($b_intel){
+ $split[$r] = $split[$r] * 32 * 1024;
+ }
+ # reports in 1 GiB units, sigh
+ elsif ($b_kingston){
+ $split[$r] = $split[$r] * 1024 * 1024;
+ }
+ # this is what it's supposed to refer to
+ else {
+ $split[$r] = int($data[$i]{'block-logical'} * $split[$r] / 1024);
+ }
+ $data[$i]{'smart-read'} = join ' ', main::get_size($split[$r]);
+ }
+ }
+ elsif ($split[$a] eq 'Total_LBAs_Written'){
+ if (main::is_numeric($split[$r])){
+ # blocks in bytes, so convert to KiB, the internal unit here
+ # reports in 32MoB units, sigh
+ if ($b_intel){
+ $split[$r] = $split[$r] * 32 * 1024;
+ }
+ # reports in 1 GiB units, sigh
+ elsif ($b_kingston){
+ $split[$r] = $split[$r] * 1024 * 1024;
+ }
+ # this is what it's supposed to refer to, in byte blocks
+ else {
+ $split[$r] = int($data[$i]{'block-logical'} * $split[$r] / 1024);
+ }
+ $data[$i]{'smart-written'} = join ' ', main::get_size($split[$r]);
+ }
+ }
+
+ ## DEVICE OLD AGE ##
+ # 191 G-Sense_Error_Rate 0x0032 001 001 000 Old_age Always - 291
+ elsif ($split[$a] eq 'G-Sense_Error_Rate'){
+ # $data[$i]{'smart-media-wearout'} = $split[$r];
+ if ($b_attributes && $split[$r] > 100){
+ $data[$i]{'smart-gsense-error-rate-r'} = $split[$r];
+ }
+ }
+ elsif ($split[$a] eq 'Media_Wearout_Indicator'){
+ # $data[$i]{'smart-media-wearout'} = $split[$r];
+ if ($b_attributes && $split[$r] > 0){
+ $data[$i]{'smart-media-wearout-v'} = $split[$v];
+ $data[$i]{'smart-media-wearout-t'} = $split[$t];
+ $data[$i]{'smart-media-wearout-f'} = $split[$f] if $split[$f] ne '-';
+ }
+ }
+ elsif ($split[$a] eq 'Multi_Zone_Error_Rate'){
+ # note: all t values are 0 that I have seen
+ if ( ($split[$v] - $split[$t]) < 50){
+ $data[$i]{'smart-multizone-errors-v'} = $split[$v];
+ $data[$i]{'smart-multizone-errors-t'} = $split[$v];
+ }
+
+ }
+ elsif ($split[$a] eq 'UDMA_CRC_Error_Count'){
+ if (main::is_numeric($split[$r]) && $split[$r] > 50){
+ $data[$i]{'smart-udma-crc-errors-r'} = $split[$r];
+ $data[$i]{'smart-udma-crc-errors-f'} = main::row_defaults('smartctl-udma-crc') if $split[$r] > 500;
+ }
+ }
+
+ ## DEVICE PRE-FAIL ##
+ elsif ($split[$a] eq 'Available_Reservd_Space'){
+ # $data[$i]{'smart-available-reserved-space'} = $split[$r];
+ if ($b_attributes && $split[$v] && $split[$t] && $split[$t]/$split[$v] > 0.92){
+ $data[$i]{'smart-available-reserved-space-v'} = $split[$v];
+ $data[$i]{'smart-available-reserved-space-t'} = $split[$t];
+ $data[$i]{'smart-available-reserved-space-f'} = $split[$f] if $split[$f] ne '-';
+ }
+ }
+ ## nvme splits these into two field/value sets
+ elsif ($split[$a] eq 'Available Spare'){
+ $split[$r] =~ s/%$//;
+ $holder{'spare'} = int($split[$r]) if main::is_numeric($split[$r]);
+ }
+ elsif ($split[$a] eq 'Available Spare Threshold'){
+ $split[$r] =~ s/%$//;
+ if ($holder{'spare'} && main::is_numeric($split[$r]) && $split[$r]/$holder{'spare'} > 0.92 ){
+ $data[$i]{'smart-available-reserved-space-v'} = $holder{'spare'};
+ $data[$i]{'smart-available-reserved-space-t'} = int($split[$r]);
+ }
+ }
+ elsif ($split[$a] eq 'End-to-End_Error'){
+ if ($b_attributes && int($split[$r]) > 0 && $split[$t]){
+ $data[$i]{'smart-end-to-end-v'} = $split[$v];
+ $data[$i]{'smart-end-to-end-t'} = $split[$t];
+ $data[$i]{'smart-end-to-end-f'} = $split[$f] if $split[$f] ne '-';
+ }
+ }
+ # seen raw value: 0/8415644
+ elsif ($split[$a] eq 'Raw_Read_Error_Rate'){
+ if ($b_attributes && $split[$v] && $split[$t] && $split[$t]/$split[$v] > 0.92){
+ $data[$i]{'smart-raw-read-error-rate-v'} = $split[$v];
+ $data[$i]{'smart-raw-read-error-rate-t'} = $split[$t];
+ $data[$i]{'smart-raw-read-error-rate-f'} = $split[$f] if $split[$f] ne '-';
+ }
+ }
+ elsif ($split[$a] eq 'Reallocated_Sector_Ct'){
+ if ($b_attributes && int($split[$r]) > 0 && $split[$t]){
+ $data[$i]{'smart-reallocated-sectors-v'} = $split[$v];
+ $data[$i]{'smart-reallocated-sectors-t'} = $split[$t];
+ $data[$i]{'smart-reallocated-sectors-f'} = $split[$f] if $split[$f] ne '-';
+ }
+ }
+ elsif ($split[$a] eq 'Retired_Block_Count'){
+ if ($b_attributes && int($split[$r]) > 0 && $split[$t]){
+ $data[$i]{'smart-retired-blocks-v'} = $split[$v];
+ $data[$i]{'smart-retired-blocks-t'} = $split[$t];
+ $data[$i]{'smart-retired-blocks-f'} = $split[$f] if $split[$f] ne '-';
+ }
+ }
+ elsif ($split[$a] eq 'Runtime_Bad_Block'){
+ if ($b_attributes && $split[$v] && $split[$t] && $split[$t]/$split[$v] > 0.92 ){
+ $data[$i]{'smart-runtime-bad-block-v'} = $split[$v];
+ $data[$i]{'smart-runtime-bad-block-t'} = $split[$t];
+ $data[$i]{'smart-runtime-bad-block-f'} = $split[$f] if $split[$f] ne '-';
+ }
+ }
+ elsif ($split[$a] eq 'Seek_Error_Rate'){
+ # value 72; threshold either 000 or 30
+ if ($b_attributes && $split[$v] && $split[$t] && $split[$t]/$split[$v] > 0.92 ){
+ $data[$i]{'smart-seek-error-rate-v'} = $split[$v];
+ $data[$i]{'smart-seek-error-rate-t'} = $split[$t];
+ $data[$i]{'smart-seek-error-rate-f'} = $split[$f] if $split[$f] ne '-';
+ }
+ }
+ elsif ($split[$a] eq 'Spin_Up_Time'){
+ # raw will always be > 0 on spinning disks
+ if ($b_attributes && $split[$v] && $split[$t] && $split[$t]/$split[$v] > 0.92 ){
+ $data[$i]{'smart-spinup-time-v'} = $split[$v];
+ $data[$i]{'smart-spinup-time-t'} = $split[$t];
+ $data[$i]{'smart-spinup-time-f'} = $split[$f] if $split[$f] ne '-';
+ }
+ }
+ elsif ($split[$a] eq 'SSD_Life_Left'){
+ # raw will always be > 0 on spinning disks
+ if ($b_attributes && $split[$v] && $split[$t] && $split[$t]/$split[$v] > 0.92 ){
+ $data[$i]{'smart-ssd-life-left-v'} = $split[$v];
+ $data[$i]{'smart-ssd-life-left-t'} = $split[$t];
+ $data[$i]{'smart-ssd-life-left-f'} = $split[$f] if $split[$f] ne '-';
+ }
+ }
+ elsif ($split[$a] eq 'Unused_Rsvd_Blk_Cnt_Tot'){
+ # raw will always be > 0 on spinning disks
+ if ($b_attributes && $split[$v] && $split[$t] && $split[$t]/$split[$v] > 0.92 ){
+ $data[$i]{'smart-unused-reserve-block-v'} = $split[$v];
+ $data[$i]{'smart-unused-reserve-block-t'} = $split[$t];
+ $data[$i]{'smart-unused-reserve-block-f'} = $split[$f] if $split[$f] ne '-';
+ }
+ }
+ elsif ($split[$a] eq 'Used_Rsvd_Blk_Cnt_Tot'){
+ # raw will always be > 0 on spinning disks
+ if ($b_attributes && $split[$v] && $split[$t] && $split[$t]/$split[$v] > 0.92 ){
+ $data[$i]{'smart-used-reserve-block-v'} = $split[$v];
+ $data[$i]{'smart-used-reserve-block-t'} = $split[$t];
+ $data[$i]{'smart-used-reserve-block-f'} = $split[$f] if $split[$f] ne '-';
+ }
+ }
+ elsif ($b_attributes ){
+ if ( $split[$y] eq 'Pre-fail' && ($split[$f] ne '-' ||
+ ($split[$t] && $split[$v] && $split[$t]/$split[$v] > 0.92 ))) {
+ $num++;
+ $data[$i]{'smart-unknown-' . $num . '-a'} = $split[$a];
+ $data[$i]{'smart-unknown-' . $num . '-v'} = $split[$v];
+ $data[$i]{'smart-unknown-' . $num . '-w'} = $split[$v];
+ $data[$i]{'smart-unknown-' . $num . '-t'} = $split[$t];
+ $data[$i]{'smart-unknown-' . $num . '-f'} = $split[$f] if $split[$f] ne '-';
+ }
+ }
+ }
+ }
+ }
+ #print Data::Dumper::Dumper\@data;
+ eval $end if $b_log;
+ return @data;
+}
+
# check for usb/firewire/[and thunderwire when data found]
sub peripheral_data {
eval $start if $b_log;
@@ -8702,7 +9602,7 @@ sub peripheral_data {
if (/usb-/i){
$type = 'USB';
}
- elsif (/ieee1394--/i){
+ elsif (/ieee1394-/i){
$type = 'FireWire';
}
last;
@@ -8846,137 +9746,164 @@ sub disk_data_by_id {
eval $end if $b_log;
return @disk_data;
}
-# receives space separated string that may or may not contain vendor data
-sub device_vendor {
+# 0 - match pattern; 1 - replace pattern; 2 - vendor print; 3 - serial pattern
+sub set_vendors {
eval $start if $b_log;
- my ($model,$serial) = @_;
- my ($vendor) = ('');
- my (@data);
- return if !$model;
- # 0 - match pattern; 1 - replace pattern; 2 - vendor print; 3 - serial pattern
- # Data URLs: inxi-resources.txt Section: DiskData device_vendor()
- # $model = 'MEDIAMAX ';
- # $model = 'Patriot Memory';
- my @vendors = (
+ @vendors = (
## These go first because they are the most likely and common ##
- ['(Crucial|^(FC)?CT|-CT|^M4\b)','Crucial','Crucial',''],
- ['^(INTEL|SSD(PAM|SA2))','^INTEL','Intel',''],
- ['(KINGSTON|DataTraveler|DT\s?(DUO|Microduo|101)|^SMS|^SHS|^SUV|^Ultimate CF|HyperX|^S[AV][34]00)','KINGSTON','Kingston',''], # maybe SHS: SHSS37A SKC SUV
+ ['(Crucial|^(FC)?CT|-CT|^M4\b|Gizmo!)','Crucial','Crucial',''],
+ ['^(INTEL|SSD(PAM|SA2))','^INTEL','Intel',''],
+ # note: S[AV][1-9][0-9] can trigger false positives
+ ['(KINGSTON|DataTraveler|DT\s?(DUO|Microduo|101)|^SMS|^SHS|^SS0|^SUV|^Ultimate CF|HyperX|^S[AV][1234]00|^SKYMEDI)','KINGSTON','Kingston',''], # maybe SHS: SHSS37A SKC SUV
# must come before samsung MU. NOTE: toshiba can have: TOSHIBA_MK6475GSX: mush: MKNSSDCR120GB_
['(^MKN|Mushkin)','Mushkin','Mushkin',''], # MKNS
# MU = Multiple_Flash_Reader too risky: |M[UZ][^L] HD103SI HD start risky
# HM320II HM320II
- ['(SAMSUNG|^MCG[0-9]+GC|^MCC|^MCB0E|^[GS]2 Portable|^DUO\b|^P3|^(HM|SP)[0-9]{2}|^MZMPC|^HD[0-9]{3}[A-Z]{2}$)','SAMSUNG','Samsung',''], # maybe ^SM, ^HM
+ ['(SAMSUNG|^MCG[0-9]+GC|^MCC|^MCBOE|\bEVO\b|^[GS]2 Portable|^[DG]3 Station|^DUO\b|^P3|^BGN|^BJ[NT]|^BWB|^(HM|SP)[0-9]{2}|^MZMPC|^HD[0-9]{3}[A-Z]{2}$)','SAMSUNG','Samsung',''], # maybe ^SM, ^HM
# Android UMS Composite?
- ['(SanDisk|^SDS[S]?[DQ]|^SL([0-9]+)G|^AFGCE|^U3\b|ULTRA\sFIT|Clip Sport|Cruzer|^Extreme)','SanDisk','SanDisk',''],
+ ['(SanDisk|^SDS[S]?[DQ]|^SL([0-9]+)G|^AFGCE|^ABLCD|^SDW[1-9]|^U3\b|ULTRA\sFIT|Clip Sport|Cruzer|^Extreme)','SanDisk','SanDisk',''],
['^STEC\b','^STEC\b','STEC',''], # ssd drive, must come before seagate ST test
# real, SSEAGATE Backup+; XP1600HE30002 | 024 HN (spinpoint)
- ['(^ST[^T]|[S]?SEAGATE|^X[AFP]|^5AS|^BUP|Expansion Desk|FreeAgent|GoFlex|Backup(\+|\s?Plus)\s?(Hub)?|OneTouch)','[S]?SEAGATE','Seagate',''],
- ['^(WD|WL[0]9]|Western Digital|My (Book|Passport)|\d*LPCX|Elements|easystore|MD0|M000|EARX|EFRX|\d*EAVS|0JD|JPVX|[0-9]+(BEV|(00)?AAK|AAV|AZL|EA[CD]S))','(^WDC|Western\s?Digital)','Western Digital',''],
+ ['(^ST[^T]|[S]?SEAGATE|^X[AFP]|^5AS|^BUP|Expansion Desk|^Expansion|FreeAgent|GoFlex|Backup(\+|\s?Plus)\s?(Hub)?|OneTouch)','[S]?SEAGATE','Seagate',''],
+ ['^(WD|WL[0]9]|Western Digital|My (Book|Passport)|\d*LPCX|Elements|easystore|MD0|M000|EARX|EFRX|\d*EAVS|0JD|JPVX|[0-9]+(BEV|(00)?AAK|AAV|AZL|EA[CD]S)|3200[AB]|2500[BJ]|5000[AB]|6400[AB]|7500[AB]|i HTS)','(^WDC|Western\s?Digital)','Western Digital',''],
## Then better known ones ##
- ['^(A-DATA|ADATA|AXN|CH11|HV[1-9]|IM2)','^(A-DATA|ADATA)','A-Data',''],
+ ['^(A-DATA|ADATA|AX[MN]|CH11|HV[1-9]|IM2)','^(A-DATA|ADATA)','A-Data',''],
['^ADTRON','^(ADTRON)','Adtron',''],
['^ASUS','^ASUS','ASUS',''],
# ATCS05 can be hitachi travelstar but not sure
- ['^ATP','^ATP[\s\-]','ATP',''],
+ ['^ATP','^ATP[\s-]','ATP',''],
# Force MP500
- ['^(Corsair|Force\s|(Flash\s*)?Voyager)','^Corsair','Corsair',''],
+ ['^(Corsair|Force\s|(Flash\s*)?(Survivor|Voyager))','^Corsair','Corsair',''],
['^(FUJITSU|MJA|MH[TVWYZ][0-9]|MP|MAP[0-9])','^FUJITSU','Fujitsu',''],
# note: 2012: wdc bought hgst
- ['^(HGST|Touro|5450)','^HGST','HGST (Hitachi)',''], # HGST HUA
- ['^(Hitachi|HD[PST]|DK[0-9]|IC|HT|HU)','^Hitachi','Hitachi',''],
+ ['^(HGST|Touro|54[15]0|7250)','^HGST','HGST (Hitachi)',''], # HGST HUA
+ ['^(Hitachi|HCS|HD[PST]|DK[0-9]|IC|HT|HU|HMS)','^Hitachi','Hitachi',''],
# vb: VB0250EAVER but clashes with vbox; HP_SSD_S700_120G ;GB0500EAFYL GB starter too generic?
# DX110064A5xnNMRI ids as HP and Sandisc, same ID, made by sandisc for hp? not sure
- ['^(HP\b|MB[0-6]|G[BJ][01]|v[0-9]{3}[bgorw]$|x[0-9]{3}[w]$)','^HP','HP',''],
- ['^(LSD|Lexar|JumpDrive|JD\s?Firefly)','^Lexar','Lexar',''], # mmc-LEXAR_0xb016546c; JD Firefly;
+ ['^(HP\b|[MV]B[0-6]|G[BJ][01]|DF|0-9]|FK|0-9]|PSS|v[0-9]{3}[bgorw]$|x[0-9]{3}[w]$)','^HP','HP',''],
+ ['^(LSD|Lexar|JumpDrive|JD\s?Firefly|WorkFlow)','^Lexar','Lexar',''], # mmc-LEXAR_0xb016546c; JD Firefly;
# OCZSSD2-2VTXE120G is OCZ-VERTEX2_3.5
- ['^(OCZ|APOC|D2|DEN|DEN|DRSAK|EC188|FTNC|GFGC|MANG|MMOC|NIMC|NIMR|PSIR|RALLY2|TALOS2|TMSC|TRSAK)','^OCZ[\s\-]','OCZ',''],
- ['^OWC','^OWC[\s\-]','OWC',''],
- ['^Philips','^Philips','Philips',''],
+ ['^(OCZ|APOC|D2|DEN|DEN|DRSAK|EC188|FTNC|GFGC|MANG|MMOC|NIMC|NIMR|PSIR|RALLY2|TALOS2|TMSC|TRSAK)','^OCZ[\s-]','OCZ',''],
+ ['^OWC','^OWC[\s-]','OWC',''],
+ ['^(Philips|GoGear)','^Philips','Philips',''],
['^PIONEER','^PIONEER','Pioneer',''],
- ['^PNY','^PNY\s','PNY','','^PNY'],
+ ['^(PNY|Hook\s?Attache|SSD2SC)','^PNY\s','PNY','','^PNY'],
# note: get rid of: M[DGK] becasue mushkin starts with MK
# note: seen: KXG50ZNV512G NVMe TOSHIBA 512GB | THNSN51T02DUK NVMe TOSHIBA 1024GB
- ['(^[S]?TOS|^THN|TOSHIBA|TransMemory|^M[KQ][0-9])','[S]?TOSHIBA','Toshiba',''], # scsi-STOSHIBA_STOR.E_EDITION_
+ ['(^[S]?TOS|^THN|TOSHIBA|TransMemory|^M[GKQ][0-9]|KBG4)','[S]?TOSHIBA','Toshiba',''], # scsi-STOSHIBA_STOR.E_EDITION_
## These go last because they are short and could lead to false ID, or are unlikely ##
# unknown: AL25744_12345678; ADP may be usb 2.5" adapter; udisk unknown: Z1E6FTKJ 00AAKS
# SSD2SC240G726A10 MRS020A128GTS25C EHSAJM0016GB
['^5ACE','^5ACE','5ACE',''], # could be seagate: ST316021 5ACE
+ ['^(AbonMax|ASU[0-9])','^AbonMax','AbonMax',''],
['^Addlink','^Addlink','Addlink',''],
['^Aireye','^Aireye','Aireye',''],
['^Alfawise','^Alfawise','Alfawise',''],
['^Android','^Android','Android',''],
+ ['^ANACOMDA','^ANACOMDA','ANACOMDA',''],
['^Apotop','^Apotop','Apotop',''],
# must come before AP|Apacer
['^(APPLE|iPod)','^APPLE','Apple',''],
['^(AP|Apacer)','^Apacer','Apacer',''],
['^(A-?RAM|ARSSD)','^A-?RAM','A-RAM',''],
+ ['^Arch','^Arch(\s*Memory)?','Arch Memory',''],
['^Asgard','^Asgard','Asgard',''],
['^(ASM|2115)','^ASM','ASMedia',''],#asm1153e
['^(AVEXIR|AVSSD)','^AVEXIR','Avexir',''],
+ ['^Axiom','^Axiom','Axiom',''],
['^Bell\b','^Bell','Packard Bell',''],
+ ['^(BelovedkaiAE|GhostPen)','^BelovedkaiAE','BelovedkaiAE',''],
['^BHT','^BHT','BHT',''],
['^BIOSTAR','^BIOSTAR','Biostar',''],
['^BIWIN','^BIWIN','BIWIN',''],
+ ['^Blackpcs','^Blackpcs','Blackpcs',''],
+ ['^Braveeagle','^Braveeagle','BraveEagle',''],
['^(BUFFALO|BSC)','^BUFFALO','Buffalo',''], # usb: BSCR05TU2
['^Bulldozer','^Bulldozer','Bulldozer',''],
+ ['^BUSlink','^BUSlink','BUSlink',''],
['^Centerm','^Centerm','Centerm',''],
['^Centon','^Centon','Centon',''],
['^CHN\b','','Zheino',''],
['^Clover','^Clover','Clover',''],
['^Colorful\b','^Colorful','Colorful',''],
+ # note: www.cornbuy.com is both a brand and also sells other brands, like newegg
+ # addlink; colorful; goldenfir; kodkak; maxson; netac; teclast; vaseky
+ ['^Corn','^Corn','Corn',''],
+ ['^CnMemory|Spaceloop','^CnMemory','CnMemory',''],
['^CSD','^CSD','CSD',''],
['^(Dane-?Elec|Z Mate)','^Dane-?Elec','DaneElec',''],
+ ['^DATABAR','^DATABAR','DataBar',''],
# Daplink vfs is an ARM software thing
+ ['^Dataram','^Dataram','Dataram',''],
+ # DataStation can be Trekstore or I/O gear
['^Dell\b','^Dell','Dell',''],
['^DeLOCK','^Delock(\s?products)?','Delock',''],
+ ['^Derler','^Derler','Derler',''],
+ ['^detech','^detech','DETech',''],
['^DGM','^DGM\b','DGM',''],
+ ['^Digifast','^Digifast','Digifast',''],
['^DIGITAL\s?FILM','DIGITAL\s?FILM','Digital Film',''],
- ['^Dogfish','^Dogfish','Dogfish',''],
+ ['^(Dogfish|Shark)','^Dogfish(\s*Technology)?','Dogfish Technolgy',''],
['^DragonDiamond','^DragonDiamond','DragonDiamond',''],
['^DREVO\b','^DREVO','Drevo',''],
# DX1100 is probably sandisk, but could be HP, or it could be hp branded sandisk
['^(Eaget|V8$)','^Eaget','Eaget',''],
- ['^EDGE','^EDGE','EDGE',''],
+ ['^EDGE','^EDGE','EDGE Tech',''],
['^Elecom','^Elecom','Elecom',''],
+ ['^Eluktro','^Eluktronics','Eluktronics',''],
+ ['^Emperor','^Emperor','Emperor',''],
+ ['^Emtec','^Emtec','Emtec',''],
['^EXCELSTOR','^EXCELSTOR( TECHNO(LOGY)?)?','ExcelStor',''],
['^EZLINK','^EZLINK','EZLINK',''],
['^Fantom','^Fantom( Drive[s]?)?','Fantom Drives',''],
['^Faspeed','^Faspeed','Faspeed',''],
['^FASTDISK','^FASTDISK','FASTDISK',''],
+ ['^Fordisk','^Fordisk','Fordisk',''],
# FK0032CAAZP/FB160C4081 FK or FV can be HP but can be other things
['^FORESEE','^FORESEE','Foresee',''],
- ['^FOXLINE','^FOXLINE','Foxline',''], # russian vendor?
+ ['^(FOXLINE|FLD)','^FOXLINE','Foxline',''], # russian vendor?
['^(GALAX\b|Gamer\s?L)','^GALAX','GALAX',''],
['^Galaxy\b','^Galaxy','Galaxy',''],
- ['^(Garmin|Fenix)','^Garmin','Garmin',''],
+ ['^(Garmin|Fenix|Nuvi|Zumo)','^Garmin','Garmin',''],
['^Geil','^Geil','Geil',''],
['^Generic','^Generic','Generic',''],
['^Gigabyte','^Gigabyte','Gigabyte',''], # SSD
['^Gigastone','^Gigastone','Gigastone',''],
['^Gloway','^Gloway','Gloway',''],
- ['^(GOODRAM|GOODDRIVE|IR SSD)','^GOODRAM','GOODRAM',''],
+ ['^Goldendisk','^Goldendisk','Goldendisk',''],
+ ['^Goldenfir','^Goldenfir','Goldenfir',''],
+ # Wilk Elektronik SA, poland
+ ['^(Wilk\s*)?(GOODRAM|GOODDRIVE|IR[\s-]?SSD|IRP|SSDPR)','^GOODRAM','GOODRAM',''],
# supertalent also has FM: |FM
['^(G[\.]?SKILL)','^G[\.]?SKILL','G.SKILL',''],
+ ['^G[\s-]*Tech','^G[\s-]*Technology','G-Technology',''],
['^HDC','^HDC\b','HDC',''],
['^Hectron','^Hectron','Hectron',''],
['^(Hikvision|HKVSN)','^Hikvision','Hikvision',''],
['^Hoodisk','^Hoodisk','Hoodisk',''],
['^HUAWEI','^HUAWEI','Huawei',''],
+ ['^HyperX','^HyperX','HyperX',''],
['^Hyundai','^Hyundai','Hyundai',''],
['^(IBM|DT)','^IBM','IBM',''],
['^IEI Tech','^IEI Tech(\.|nology)?( Corp(\.|oration)?)?','IEI Technology',''],
['^(Imation|Nano\s?Pro|HQT)','^Imation(\sImation)?','Imation',''], # Imation_ImationFlashDrive; TF20 is imation/tdk
+ ['^(Inca\b|Npenterprise)','^Inca','Inca',''],
+ ['^INDMEM','^INDMEM','INDMEM',''],
+ ['^Inland','^Inland','Inland',''],
['^(InnoDisk|Innolite)','^InnoDisk( Corp.)?','InnoDisk',''],
['^Innostor','^Innostor','Innostor',''],
['^Innovation','^Innovation','Innovation',''],
['^Innovera','^Innovera','Innovera',''],
+ ['^Intaiel','^Intaiel','Intaiel',''],
['^(INM|Integral|V\s?Series)','^Integral(\s?Memory)?','Integral Memory',''],
- ['^(Intenso|(Alu|Basic|Business|Micro|Mobile|Rainbow|Speed|Twister) Line|Rainbow)','^Intenso','Intenso',''],
- ['^(Iomega|ZIP\b)','^Iomega','Iomega',''],
+ ['^(lntenso|Intenso|(Alu|Basic|Business|Micro|Mobile|Rainbow|Speed|Twister) Line|Rainbow)','^Intenso','Intenso',''],
+ ['^(Iomega|ZIP\b|Clik!)','^Iomega','Iomega',''],
['^JingX','^JingX','JingX',''], #JingX 120G SSD - not confirmed, but guessing
+ ['^Jingyi','^Jingyi','Jingyi',''],
# NOTE: ITY2 120GB hard to find
['^JMicron','^JMicron(\s?Tech(nology)?)?','JMicron Tech',''], #JMicron H/W raid
+ ['^KimMIDI','^KimMIDI','KimMIDI',''],
+ ['^Kingchux[\s-]?ing','^Kingchux[\s-]?ing','Kingchuxing',''],
['^KingDian','^KingDian','KingDian',''],
['^Kingfast','^Kingfast','Kingfast',''],
['^KingMAX','^KingMAX','KingMAX',''],
@@ -8985,99 +9912,154 @@ sub device_vendor {
# kingwin docking, not actual drive
['^(EZD|EZ-Dock)','','Kingwin Docking Station',''],
['^KLEVV','^KLEVV','KLEVV',''],
- ['^(Lacie|P92)','^Lacie','Lacie',''],
+ ['^Kodak','^Kodak','Kodak',''],
+ ['^(Lacie|P92|itsaKey|iamaKey)','^Lacie','LaCie',''],
+ ['^LANBO','^LANBO','LANBO',''],
['^LDLC','^LDLC','LDLC',''],
- # LENSE30512GMSP34MEAT3TA
- ['^LEN','^Lenovo','Lenovo',''],
+ # LENSE30512GMSP34MEAT3TA / UMIS RPITJ256PED2MWX
+ ['^(LEN|UMIS)','^Lenovo','Lenovo',''],
['^RPFT','','Lenovo O.E.M.',''],
['^LG\b','^LG','LG',''],
- ['^(LITE[\-\s]?ON[\s\-]?IT)','^LITE[\-]?ON[\s\-]?IT','LITE-ON IT',''], # LITEONIT_LSS-24L6G
- ['^(LITE[\-\s]?ON|PH[1-9])','^LITE[\-]?ON','LITE-ON',''], # PH6-CE240-L
+ ['^(LITE[-\s]?ON[\s-]?IT)','^LITE[-]?ON[\s-]?IT','LITE-ON IT',''], # LITEONIT_LSS-24L6G
+ ['^(LITE[-\s]?ON|PH[1-9])','^LITE[-]?ON','LITE-ON',''], # PH6-CE240-L
['^LONDISK','^LONDISK','LONDISK',''],
['^M-Systems','^M-Systems','M-Systems',''],
- ['^(Mach\s*Xtreme|MXSSD)','^Mach\s*Xtreme','Mach Xtreme',''],
+ ['^(Mach\s*Xtreme|MXSSD|MXU)','^Mach\s*Xtreme','Mach Xtreme',''],
+ ['^Maximus','^Maximus','Maximus',''],
['^(MAXTOR|Atlas|TM[0-9]{4})','^MAXTOR','Maxtor',''], # note M2 M3 is usually maxtor, but can be samsung
['^(Memorex|TravelDrive|TD\s?Classic)','^Memorex','Memorex',''],
# note: C300/400 can be either micron or crucial, but C400 is M4 from crucial
['(^MT|^M5|^Micron|00-MT|C[34]00)','^Micron','Micron',''],# C400-MTFDDAK128MAM
- ['^MARSHAL\b','^MARSHAL','Marshal',''],
+ ['^(MARSHAL\b|MAL[0-9])','^MARSHAL','Marshal',''],
['^MARVELL','^MARVELL','Marvell',''],
+ ['^Maxsun','^Maxsun','Maxsun',''],
['^MDT\b','^MDT','MDT (rebuilt WD/Seagate)',''], # mdt rebuilds wd/seagate hdd
# MD1TBLSSHD, careful with this MD starter!!
['^MD[1-9]','^Max\s*Digital','MaxDigital',''],
['^Medion','^Medion','Medion',''],
['^(MEDIAMAX|WL[0-9]{2})','^MEDIAMAX','MediaMax',''],
- ['^Monster\s?Digital','^Monster\s?Digital','Monster Digital',''],
+ ['^Mengmi','^Mengmi','Mengmi',''],
+ ['^MINIX','^MINIX','MINIX',''],
+ ['^Miracle','^Miracle','Miracle',''],
+ # Monster MONSTER DIGITAL
+ ['^(Monster\s)+Digital','^(Monster\s)+Digital','Monster Digital',''],
['^Morebeck','^Morebeck','Morebeck',''],
['^Motorola','^Motorola','Motorola',''],
+ ['^Moweek','^Moweek','Moweek',''],
+ #MRMAD4B128GC9M2C
+ ['^(MRMA|Memoright)','^Memoright','Memoright',''],
+ ['^MTASE','^MTASE','MTASE',''],
['^MTRON','^MTRON','MTRON',''],
+ ['^Neo\s*Forza','^Neo\s*Forza','Neo Forza',''],
['^Netac','^Netac','Netac',''],
- ['^OOS[1-9]','','Utania',''],
+ ['^Nik','^Nikimi','Nikimi',''],
+ ['^Orico','^Orico','Orico',''],
['^OWC','^OWC\b','OWC',''],
+ ['^oyunkey','^oyunkey','Oyunkey',''],
['^PALIT','PALIT','Palit',''], # ssd
['^PERC\b','','Dell PowerEdge RAID Card',''], # ssd
['^(PS[8F]|Patriot)','^Patriot([-\s]?Memory)?','Patriot',''],
+ ['PHISON[\s-]?','PHISON[\s-]?','Phison',''],# E12-256G-PHISON-SSD-B3-BB1
['^Pioneer','Pioneer','Pioneer',''],
['^PIX[\s]?JR','^PIX[\s]?JR','Disney',''],
['^(PLEXTOR|PX-)','^PLEXTOR','Plextor',''],
['^(PQI|Intelligent\s?Stick)','^PQI','PQI',''],
+ ['^Pretec','Pretec','Pretec',''],
['QEMU','^[0-9]*QEMU( QEMU)?','QEMU',''], # 0QUEMU QEMU HARDDISK
['(^Quantum|Fireball)','^Quantum','Quantum',''],
['^QUMO','^QUMO','Qumo',''],
['^(R3|AMD\s?(RADEON)?)','AMD\s?(RADEON)?','AMD Radeon',''], # ssd
+ ['^(Ramaxel|RT|RM|RPF)','^Ramaxel','Ramaxel',''],
['^RENICE','^RENICE','Renice',''],
['^(Ricoh|R5)','^Ricoh','Ricoh',''],
['^RIM[\s]','^RIM','RIM',''],
+ #RTDMA008RAV2BWL comes with lenovo but don't know brand
['^Runcore','^Runcore','Runcore',''],
+ ['^Sabrent','^Sabrent','Sabrent',''],
['^Sage','^Sage(\s?Micro)?','Sage Micro',''],
+ ['^SandForce','^SandForce','SandForce',''],
+ ['^Sannobel','^Sannobel','Sannobel',''],
['^SigmaTel','^SigmaTel','SigmaTel',''],
# DIAMOND_040_GB
['^(SILICON\s?MOTION|SM[0-9])','^SILICON\s?MOTION','Silicon Motion',''],
- ['^(Silicon\s?Power|SP[CP]C|Silicon|Diamond|Haspeed)','Silicon\s?Power','Silicon Power',''],
+ ['(Silicon[\s-]?Power|^SP[CP]C|^Silicon|^Diamond|^Haspeed)','Silicon[\s-]?Power','Silicon Power',''],
['^SINTECHI?','^SINTECHI?','SinTech (adapter)',''],
['Smartbuy','\s?Smartbuy','Smartbuy',''], # SSD Smartbuy 60GB; mSata Smartbuy 3
# HFS128G39TND-N210A; seen nvme with name in middle
- ['(SK\s?HYNIX|^HF[MS])','\s?SK\s?HYNIX','SK Hynix',''],
+ ['(SK\s?HYNIX|^HF[MS]|^H[BC]G)','\s?SK\s?HYNIX','SK Hynix',''],
['hynix','hynix','Hynix',''],# nvme middle of string, must be after sk hynix
['^SH','','Smart Modular Tech.',''],
['^Skill','^Skill','Skill',''],
['^(SMART( Storage Systems)?|TX)','^(SMART( Storage Systems)?)','Smart Storage Systems',''],
['^(S[FR]-|Sony)','^Sony','Sony',''],
['^STE[CK]','^STE[CK]','sTec',''], # wd bought this one
+ ['^STmagic','^STmagic','STmagic',''],
['^STORFLY','^STORFLY','StorFly',''],
['^SUNEAST','^SUNEAST','SunEast',''],
+ ['^SuperSSpeed','^SuperSSpeed','SuperSSpeed',''],
# NOTE: F[MNETU] not reliable, g.skill starts with FM too:
# Seagate ST skips STT.
- ['^(STT|F[HT]M[0-9])','','Super Talent',''],
+ ['^(Super\s*Talent|STT|F[HT]M[0-9]|PicoDrive|Teranova)','','Super Talent',''],
['^(SF|Swissbit)','^Swissbit','Swissbit',''],
# ['^(SUPERSPEED)','^SUPERSPEED','SuperSpeed',''], # superspeed is a generic term
+ ['^(TakeMS|ColorLine)','^TakeMS','TakeMS',''],
+ ['^Tammuz','^Tammuz','Tammuz',''],
['^TANDBERG','^TANDBERG','Tanberg',''],
- ['^TCSUNBOW','^TCSUNBOW','TCSunBow',''],
+ ['^TC[\s-]*SUNBOW','^TC[\s-]*SUNBOW','TCSunBow',''],
['^(TDK|TF[1-9][0-9])','^TDK','TDK',''],
['^TEAC','^TEAC','TEAC',''],
- ['^TEAM','^TEAM( Group)?','Team',''],
- ['^Teclast','^Teclast','Teclast',''],
+ ['^TEAM','^TEAM(\s*Group)?','TeamGroup',''],
+ ['^(Teclast|CoolFlash)','^Teclast','Teclast',''],
['^Teleplan','^Teleplan','Teleplan',''],
+ ['^TEUTONS','^TEUTONS','TEUTONS',''],
['^Tigo','^Tigo','Tigo',''],
+ ['^Timetec','^Timetec','Timetec',''],
+ ['^TKD','^TKD','TKD',''],
['^TopSunligt','^TopSunligt','TopSunligt',''], # is this a typo? hard to know
['^TopSunlight','^TopSunlight','TopSunlight',''],
- ['^(TS|Transcend|JetFlash)','^Transcend','Transcend',''],
+ ['^([F]?TS|Transcend|JetDrive|JetFlash|USDU)','^Transcend','Transcend',''],
['^(TrekStor|DS maxi)','^TrekStor','TrekStor',''],
['^UDinfo','^UDinfo','UDinfo',''],
['^USBTech','^USBTech','USBTech',''],
['^(UG|Unigen)','^Unigen','Unigen',''],
+ ['^(OOS[1-9]|Utania)','Utania','Utania',''],
+ ['^U-TECH','U-TECH','U-Tech',''],
['^VBOX','','VirtualBox',''],
- ['^(Verbatim|STORE N GO)','^Verbatim','Verbatim',''],
+ ['^(Verbatim|STORE N GO|Vi[1-9])','^Verbatim','Verbatim',''],
+ ['^V-GEN','^V-GEN','V-Gen',''],
['^(Victorinox|Swissflash)','^Victorinox','Victorinox',''],
+ ['^(Visipro|SDVP)','^Visipro','Visipro',''],
['^VISIONTEK','^VISIONTEK','VisionTek',''],
['^VMware','^VMware','VMware',''],
['^(Vseky|Vaseky)','^Vaseky','Vaseky',''], # ata-Vseky_V880_350G_
+ ['^Wilk','^Wilk','Wilk',''],
+ ['^Xintor','^Xintor','Xintor',''],
+ ['^XPG','^XPG','XPG',''],
+ ['^XUNZHE','^XUNZHE','XUNZHE',''],
['^(YUCUN|R880)','^YUCUN','YUCUN',''],
- ['^(Zheino|CHN[0-9])','^Zheino','Zheino',''],
+ ['^ZALMAN','^ZALMAN','Zalman',''],
+ ['^ZEUSLAP','^ZEUSLAP','ZEUSLAP',''],
+ ['^(Zheino|CHN[0-9]|CNM)','^Zheino','Zheino',''],
+ ['^(Zotac|ZTSSD)','^Zotac','Zotac',''],
['^ZSPEED','^ZSPEED','ZSpeed',''],
['^ZTC','^ZTC','ZTC',''],
['^(ASMT|2115)','^ASMT','ASMT (case)',''],
);
+ eval $end if $b_log;
+}
+
+# receives space separated string that may or may not contain vendor data
+sub device_vendor {
+ eval $start if $b_log;
+ my ($model,$serial) = @_;
+ my ($vendor) = ('');
+ my (@data);
+ return if !$model;
+ set_vendors() if !@vendors;
+ # 0 - match pattern; 1 - replace pattern; 2 - vendor print; 3 - serial pattern
+ # Data URLs: inxi-resources.txt Section: DiskData device_vendor()
+ # $model = 'MEDIAMAX ';
+ # $model = 'Patriot Memory';
foreach my $row (@vendors){
if ($model =~ /$row->[0]/i || ($row->[3] && $serial && $serial =~ /$row->[3]/)){
$vendor = $row->[2];
@@ -9090,7 +10072,7 @@ sub device_vendor {
$model = 'N/A';
}
}
- $model =~ s/^[\s\-_]+|[\s\-_]+$//g;
+ $model =~ s/^[\/\[\s_-]+|[\/\s_-]+$//g;
$model =~ s/\s\s/ /g;
@data = ($vendor,$model);
last;
@@ -9119,6 +10101,7 @@ sub hdd_temp {
@data = main::grabber("$sudo$nvme smart-log $device 2>/dev/null");
foreach (@data){
my @row = split /\s*:\s*/, $_;
+ next if !$row[0];
# other rows may have: Temperature sensor 1 :
if ( $row[0] eq 'temperature') {
$row[1] =~ s/\s*C//;
@@ -9143,7 +10126,7 @@ sub hdd_temp {
return $hdd_temp;
}
# args: 1: block id
-sub admin_data {
+sub block_data {
eval $start if $b_log;
my ($id) = @_;
# 0: logical block size 1: disk physical block size/partition block size;
@@ -9266,7 +10249,8 @@ sub set_glabel {
## GraphicData
{
package GraphicData;
-my $driver = ''; # we need this as a fallback in case no xorg.0.log
+my $driver = ''; # we need this as a fallback in case no xorg log found
+my %graphics;
sub get {
eval $start if $b_log;
my (@data,@rows);
@@ -9275,7 +10259,7 @@ sub get {
my $type = ($b_arm) ? 'arm' : 'mips';
my $key = 'Message';
@data = ({
- main::key($num++,$key) => main::row_defaults($type . '-pci',''),
+ main::key($num++,0,1,$key) => main::row_defaults($type . '-pci',''),
},);
@rows = (@rows,@data);
}
@@ -9289,11 +10273,14 @@ sub get {
$type = 'pci-card-data-root';
}
@data = ({
- main::key($num++,$key) => main::row_defaults($type,''),
+ main::key($num++,0,1,$key) => main::row_defaults($type,''),
},);
@rows = (@rows,@data);
}
}
+ # note: not perfect, but we need usb gfx to show for all types, soc, pci, etc
+ @data = usb_data();
+ @rows = (@rows,@data);
@data = display_data();
@rows = (@rows,@data);
@data = gl_data();
@@ -9327,24 +10314,28 @@ sub card_data {
$card = main::pci_long_filter($card);
}
@data = ({
- main::key($num++,'Device') => $card,
+ main::key($num++,1,1,'Device') => $card,
},);
@rows = (@rows,@data);
if ($extra > 0 && $b_pci_tool && $row[12]){
my $item = main::get_pci_vendor($row[4],$row[12]);
- $rows[$j]{main::key($num++,'vendor')} = $item if $item;
+ $rows[$j]{main::key($num++,0,2,'vendor')} = $item if $item;
}
- $rows[$j]{main::key($num++,'driver')} = $driver;
+ $rows[$j]{main::key($num++,1,2,'driver')} = $driver;
if ($row[9] && !$bsd_type){
my $version = main::get_module_version($row[9]);
$version ||= 'N/A';
- $rows[$j]{main::key($num++,'v')} = $version;
+ $rows[$j]{main::key($num++,0,3,'v')} = $version;
+ }
+ if ($b_admin && $row[10]){
+ $row[10] = main::get_driver_modules($row[9],$row[10]);
+ $rows[$j]{main::key($num++,0,3,'alternate')} = $row[10] if $row[10];
}
if ($extra > 0){
- $rows[$j]{main::key($num++,'bus ID')} = (!$row[2] && !$row[3]) ? 'N/A' : "$row[2].$row[3]";
+ $rows[$j]{main::key($num++,0,2,'bus ID')} = (!$row[2] && !$row[3]) ? 'N/A' : "$row[2].$row[3]";
}
if ($extra > 1){
- $rows[$j]{main::key($num++,'chip ID')} = ($row[5]) ? "$row[5]:$row[6]" : $row[6];
+ $rows[$j]{main::key($num++,0,2,'chip ID')} = ($row[5]) ? "$row[5]:$row[6]" : $row[6];
}
#print "$row[0]\n";
}
@@ -9353,131 +10344,70 @@ sub card_data {
eval $end if $b_log;
return @rows;
}
-sub display_data(){
+sub usb_data {
eval $start if $b_log;
- my (%graphics,@row);
- my @xdpyinfo;
- my $num = 0;
- my ($protocol,$server) = ('','');
- # note: these may not always be set, they won't be out of X, for example
- $protocol = $ENV{'XDG_SESSION_TYPE'} if $ENV{'XDG_SESSION_TYPE'};
- $protocol = $ENV{'WAYLAND_DISPLAY'} if (!$protocol && $ENV{'WAYLAND_DISPLAY'});
- # yes, I've seen this in 2019 distros, sigh
- $protocol = '' if $protocol eq 'tty';
- # need to confirm that there's a point to this test, I believe no, fails out of x
- # loginctl also results in the session id
- if (!$protocol && $b_display && $b_force_display){
- if (my $program = main::check_program('loginctl')){
- my $id = '';
- # $id = $ENV{'XDG_SESSION_ID'}; # returns tty session in console
- my @data = main::grabber("$program --no-pager --no-legend 2>/dev/null",'','strip');
- foreach (@data){
- next if /tty[v]?[0-6]$/; # freebsd: ttyv3
- $id = (split /\s+/, $_)[0];
- last; # multiuser? too bad, we'll go for the first one
- }
- if ($id ){
- my $temp = (main::grabber("$program show-session $id -p Type --no-pager --no-legend 2>/dev/null"))[0];
- $temp =~ s/Type=// if $temp;
- # ssh will not show /dev/ttyx so would have passed the first test
- $protocol = $temp if $temp && $temp ne 'tty';
- }
- }
- }
- if ($extra > 1){
- # initial tests, if wayland, it is certainly a compositor
- $protocol = lc($protocol) if $protocol;
- $graphics{'compositor'} = display_compositor($protocol);
- # gnome-shell is incredibly slow to return version
- if ($extra > 2 && $graphics{'compositor'} && (!$show{'system'} || $graphics{'compositor'} ne 'gnome-shell' ) ){
- $graphics{'compositor-version'} = (main::program_data($graphics{'compositor'},$graphics{'compositor'},3))[1];
- }
- }
- if ( $b_display){
- # X vendor and version detection.
- # new method added since radeon and X.org and the disappearance of
- # <X server name> version : ...etc. Later on, the normal textual version string
- # returned, e.g. like: X.Org version: 6.8.2
- # A failover mechanism is in place: if $version empty, release number parsed instead
- if (my $program = main::check_program('xdpyinfo')){
- my @xdpyinfo = main::grabber("$program $display_opt 2>/dev/null","\n",'strip');
- #@xdpyinfo = map {s/^\s+//;$_} @xdpyinfo if @xdpyinfo;
- #print join "\n",@xdpyinfo, "\n";
- foreach (@xdpyinfo){
- my @working = split /:\s+/, $_;
- next if ( ($graphics{'dimensions'} && $working[0] ne 'dimensions' ) || !$working[0] );
- #print "$_\n";
- if ($working[0] eq 'vendor string'){
- $working[1] =~ s/The\s|\sFoundation//g;
- # some distros, like fedora, report themselves as the xorg vendor,
- # so quick check here to make sure the vendor string includes Xorg in string
- if ($working[1] !~ /x/i){
- $working[1] .= ' X.org';
- }
- $graphics{'vendor'} = $working[1];
- }
- elsif ($working[0] eq 'version number'){
- $graphics{'version-id'} = $working[1];
- }
- elsif ($working[0] eq 'vendor release number'){
- $graphics{'vendor-release'} = $working[1];
- }
- elsif ($working[0] eq 'X.Org version'){
- $graphics{'xorg-version'} = $working[1];
+ my (@rows,@data,@ids,$driver,$path_id,$product,@temp2);
+ my ($j,$num) = (0,1);
+ return if !@usb;
+ foreach my $ref (@usb){
+ my @row = @$ref;
+ # these tests only work for /sys based usb data for now
+ if ($row[14] && ($row[14] eq 'Audio-Video' || $row[14] eq 'Video' ) ){
+ $num = 1;
+ $j = scalar @rows;
+ # makre sure to reset, or second device trips last flag
+ ($driver,$path_id,$product) = ('','','');
+ $product = main::cleaner($row[13]) if $row[13];
+ $driver = $row[15] if $row[15];
+ $path_id = $row[2] if $row[2];
+ $product ||= 'N/A';
+ # note: for real usb video out, no generic drivers? webcams may have one though
+ if (!$driver){
+ if ($row[14] eq 'Audio-Video'){
+ $driver = 'N/A';
}
- elsif ($working[0] eq 'dimensions'){
- $working[1] =~ s/\spixels//;
- $working[1] =~ s/\smillimeters/ mm/;
- if ($graphics{'dimensions'}){
- $graphics{'dimensions'} = ([@{$graphics{'dimensions'}},$working[1]]);
- }
- else {
- $graphics{'dimensions'} = ([$working[1]]);
- }
+ else {
+ $driver = 'N/A';
}
}
- #$graphics{'dimensions'} = (\@dimensions);
- # we get a bit more info from xrandr than xdpyinfo, but xrandr fails to handle
- # multiple screens from different video cards
- my $ref = $graphics{'dimensions'};
- if (defined $ref){
- my @screens = @$ref;
- my $resolution;
- if (scalar @screens == 1){
- if (my $program = main::check_program('xrandr')){
- my $counter = 0;
- my @xrandr = main::grabber("$program $display_opt 2>/dev/null",'','strip');
- foreach (@xrandr){
- $counter++;
- if (/^[^\s]+\sconnected\s(primary\s)?([0-9]+)\s*x\s*([0-9]+)\+/){
- $resolution = $2 . 'x' . $3 if $2 && $3;
- }
- my @working = split /\s+/,$_;
- # print join "$_\n";
- if ($working[1] =~ /\*/){
- $working[1] =~ s/\*|\+//g;
- $working[1] = sprintf("%.0f",$working[1]);
- $working[1] = ($working[1]) ? "$working[1]Hz" : 'N/A';
- # case where 0 is 'preferred, sigh.
- $working[0] = ($working[0] !~ /[0-9]\s*x\s*[0-9]/ && $resolution) ? $resolution : $working[0];
- my $screen = "$working[0]~$working[1]";
- if ($graphics{'screens'}){
- $graphics{'screens'} = ([@{$graphics{'screens'}},$screen]);
- }
- else {
- $graphics{'screens'} = ([$screen]);
- }
- }
- }
- }
- }
+ @data = ({
+ main::key($num++,1,1,'Device') => $product,
+ main::key($num++,0,2,'type') => 'USB',
+ main::key($num++,0,2,'driver') => $driver,
+ },);
+ @rows = (@rows,@data);
+ if ($extra > 0){
+ $rows[$j]{main::key($num++,0,2,'bus ID')} = "$path_id:$row[1]";
}
- else {
- $graphics{'tty'} = tty_data();
+ if ($extra > 1){
+ $row[7] ||= 'N/A';
+ $rows[$j]{main::key($num++,0,2,'chip ID')} = $row[7];
+ }
+ if ($extra > 2 && $row[16]){
+ $rows[$j]{main::key($num++,0,2,'serial')} = main::apply_filter($row[16]);
}
}
- else {
- $graphics{'screens'} = ([main::row_defaults('xdpyinfo-missing')]);
+ }
+ eval $end if $b_log;
+ return @rows;
+}
+sub display_data(){
+ eval $start if $b_log;
+ my (@row);
+ my ($num,$protocol) = (0,'');
+ # note: these may not always be set, they won't be out of X, for example
+ $protocol = get_protocol();
+ # note, since the compositor is the server with wayland, always show it
+ if ($extra > 1 || $protocol eq 'wayland'){
+ set_compositor($protocol);
+ }
+ if ( $b_display){
+ x_display_data();
+ # currently barebones, wayland needs a lot more work
+ if ($protocol && $protocol eq 'wayland' && !$graphics{'screens'}){
+ wayland_display_data();
+ # it worked! we got screen data
+ $graphics{'no-xdpyinfo'} = undef if $graphics{'screens'};
}
}
else {
@@ -9485,82 +10415,436 @@ sub display_data(){
}
# this gives better output than the failure last case, which would only show:
# for example: X.org: 1.9 instead of: X.org: 1.9.0
- $graphics{'version'} = $graphics{'xorg-version'} if $graphics{'xorg-version'};;
- $graphics{'version'} = x_version() if !$graphics{'version'};
- $graphics{'version'} = $graphics{'version-id'} if !$graphics{'version'};
-
- undef @xdpyinfo;
+ $graphics{'x-version'} = $graphics{'xorg-version'} if $graphics{'xorg-version'};;
+ $graphics{'x-version'} = x_version() if !$graphics{'x-version'};
+ $graphics{'x-version'} = $graphics{'x-version-id'} if !$graphics{'x-version'};
#print Data::Dumper::Dumper \%graphics;
if (%graphics){
- my $resolution = '';
- my $server_string = '';
- if ($graphics{'vendor'}){
- my $version = ($graphics{'version'}) ? " $graphics{'version'}" : '';
- $server_string = "$graphics{'vendor'}$version";
- }
- elsif ($graphics{'version'}) {
- if ($graphics{'version'} =~ /^Xvesa/){
- $server_string = $graphics{'version'};
+ my ($driver_missing,$resolution,$server_string) = ('','','');
+ # print "$graphics{'x-vendor'} $graphics{'x-version'} $graphics{'x-vendor-release'}","\n";
+ if ($graphics{'x-vendor'}){
+ my $version = ($graphics{'x-version'}) ? " $graphics{'x-version'}" : '';
+ #$version = (!$version && $graphics{'x-vendor-release'}) ? " $graphics{'x-vendor-release'}" : '';
+ $server_string = "$graphics{'x-vendor'}$version";
+ #print "$server_string\n";
+ }
+ elsif ($graphics{'x-version'}) {
+ if ($graphics{'x-version'} =~ /^Xvesa/){
+ $server_string = $graphics{'x-version'};
}
else {
- $server_string = "X.org $graphics{'version'}";
- }
- }
- if ($graphics{'screens'}){
- my $ref = $graphics{'screens'};
- my @screens = @$ref;
- my $sep = '';
- foreach (@screens){
- $resolution .= $sep . $_;
- $sep = ', ';
+ $server_string = "X.org $graphics{'x-version'}";
}
}
my @drivers = x_drivers();
- if (!$protocol && !$server_string && !$graphics{'vendor'} && !@drivers){
+ if (!$protocol && !$server_string && !$graphics{'x-vendor'} && !@drivers){
$server_string = main::row_defaults('display-server');
@row = ({
- main::key($num++,'Display') => '',
- main::key($num++,'server') => $server_string,
+ main::key($num++,1,1,'Display') => '',
+ main::key($num++,0,2,'server') => $server_string,
});
}
else {
$server_string ||= 'N/A';
+ @row = ({
+ main::key($num++,1,1,'Display') => $protocol,
+ main::key($num++,0,2,'server') => $server_string,
+ });
+ if ($graphics{'compositor'}){
+ $row[0]{main::key($num++,0,2,'compositor')} = $graphics{'compositor'};
+ if ($graphics{'compositor-version'}){
+ $row[0]{main::key($num++,0,3,'v')} = $graphics{'compositor-version'};
+ }
+ }
# note: if no xorg log, and if wayland, there will be no xorg drivers,
# obviously, so we use the last driver found on the card section in that case.
# those come from lscpi kernel drivers so there should be no xorg/wayland issues.
- $driver = ($drivers[0]) ? $drivers[0]: $driver;
- @row = ({
- main::key($num++,'Display') => $protocol,
- main::key($num++,'server') => $server_string,
- main::key($num++,'driver') => $driver,
- });
+ if (!$drivers[0]){
+ # Fallback: specific case: in Arch/Manjaro gdm run systems, their Xorg.0.log is
+ # located inside this directory, which is not readable unless you are root
+ # Normally Arch gdm log is here: ~/.local/share/xorg/Xorg.1.log
+ # $driver comes from the Device lines, and is just last fallback.
+ if ($driver){
+ if (-e '/var/lib/gdm' && !$b_root ){
+ $driver_missing = main::row_defaults('display-driver-na') . ' - ' . main::row_defaults('root-suggested');
+ }
+ else {
+ $driver_missing = main::row_defaults('display-driver-na');
+ }
+ }
+ else {
+ $driver_missing = main::row_defaults('root-suggested') if -e '/var/lib/gdm' && !$b_root;
+ }
+ }
+ else {
+ $driver = $drivers[0];
+ }
+ $driver ||= 'N/A';
+ $row[0]{main::key($num++,0,2,'driver')} = $driver;
+ if ($driver_missing){
+ $row[0]{main::key($num++,0,3,'note')} = $driver_missing;
+ }
if ($drivers[2]){
- $row[0]{main::key($num++,'FAILED')} = $drivers[2];
+ $row[0]{main::key($num++,0,3,'FAILED')} = $drivers[2];
}
if ($drivers[1]){
- $row[0]{main::key($num++,'unloaded')} = $drivers[1];
+ $row[0]{main::key($num++,0,3,'unloaded')} = $drivers[1];
}
if ($extra > 1 && $drivers[3]){
- $row[0]{main::key($num++,'alternate')} = $drivers[3];
+ $row[0]{main::key($num++,0,3,'alternate')} = $drivers[3];
}
- if ($graphics{'compositor'}){
- $row[0]{main::key($num++,'compositor')} = $graphics{'compositor'};
- if ($graphics{'compositor-version'}){
- $row[0]{main::key($num++,'v')} = $graphics{'compositor-version'};
+ }
+ if ($b_admin ){
+ if (defined $graphics{'display-id'}){
+ $row[0]{main::key($num++,0,2,'display ID')} = $graphics{'display-id'};
+ }
+ if (defined $graphics{'display-screens'}){
+ $row[0]{main::key($num++,0,2,'screens')} = $graphics{'display-screens'};
+ }
+ if (defined $graphics{'display-default-screen'} &&
+ $graphics{'display-screens'} && $graphics{'display-screens'} > 1){
+ $row[0]{main::key($num++,0,2,'default screen')} = $graphics{'display-default-screen'};
+ }
+ }
+ if ($graphics{'no-xdpyinfo'}){
+ $row[0]{main::key($num++,0,2,'resolution')} = $graphics{'no-xdpyinfo'};
+ }
+ elsif ($graphics{'screens'}){
+ my ($diag,$dpi,$hz,$size);
+ my ($m_count,$basic_count,$row_key,$screen_count) = (0,0,0,0);
+ my $s_count = ($graphics{'screens'}) ? scalar @{$graphics{'screens'}}: 0;
+ foreach (@{$graphics{'screens'}}){
+ my %main = %$_;
+ $m_count = scalar @{$main{'monitors'}} if $main{'monitors'};
+ $screen_count++;
+ ($diag,$dpi,$hz,$resolution,$size) = (undef);
+ $row_key++ if !$show{'graphic-basic'};
+ if ( !$show{'graphic-basic'} || $m_count == 0 ){
+ if ( !$show{'graphic-basic'} && defined $main{'screen'} ){
+ $row[$row_key]{main::key($num++,1,2,'Screen')} = $main{'screen'};
+ }
+ $resolution = $main{'res-x'} . 'x' . $main{'res-y'} if $main{'res-x'} && $main{'res-y'};
+ $resolution .= '~' . $main{'hz'} . 'Hz' if $show{'graphic-basic'} && $main{'hz'} && $resolution;
+ $resolution ||= 'N/A';
+ if ($s_count == 1 || !$show{'graphic-basic'}){
+ $row[$row_key]{main::key($num++,0,3,'s-res')} = $resolution;
+ }
+ elsif ($show{'graphic-basic'}) {
+ $row[$row_key]{main::key($num++,0,3,'s-res')} = '' if $screen_count == 1;
+ $row[$row_key]{main::key($num++,0,3,$screen_count)} = $resolution;
+ }
+ $resolution = '';
+ if ($main{'s-dpi'} && (!$show{'graphic-basic'} || $extra > 1)){
+ $row[$row_key]{main::key($num++,0,3,'s-dpi')} = $main{'s-dpi'};
+ }
+ if ( !$show{'graphic-basic'} ){
+ if ($main{'size-x'} && $main{'size-y'}){
+ $size = $main{'size-x'} . 'x' . $main{'size-y'} .
+ 'mm ('. $main{'size-x-i'} . 'x' . $main{'size-y-i'} . '")';
+ }
+ $size ||= '';
+ $row[$row_key]{main::key($num++,0,3,'s-size')} = $size if $size;
+ if ($main{'diagonal'}){
+ $diag = $main{'diagonal-m'} . 'mm ('. $main{'diagonal'} . '")';
+ }
+ $diag ||= '';
+ $row[$row_key]{main::key($num++,0,3,'s-diag')} = $diag if $diag;
+ }
+ }
+ if ($main{'monitors'}){
+ #print $basic_count . '::' . $m_count, "\n";
+ foreach my $ref2 (@{$main{'monitors'}}){
+ my %monitor = %$ref2;
+ ($diag,$dpi,$hz,$resolution,$size) = (undef);
+ if ($show{'graphic-basic'}){
+ $basic_count++;
+ if ($monitor{'res-x'} && $monitor{'res-y'}){
+ $resolution = $monitor{'res-x'} . 'x' . $monitor{'res-y'};
+ }
+ # using main, noit monitor, dpi because we want xorg dpi, not physical screen dpi
+ $dpi = $main{'s-dpi'} if $resolution && $extra > 1 && $main{'s-dpi'};
+ $resolution .= '~' . $monitor{'hz'} . 'Hz' if $monitor{'hz'} && $resolution;
+ $resolution ||= 'N/A';
+ if ($basic_count == 1 && $m_count == 1){
+ $row[$row_key]{main::key($num++,0,2,'resolution')} = $resolution;
+ }
+ else {
+ $row[$row_key]{main::key($num++,1,2,'resolution')} = '' if $basic_count == 1;
+ $row[$row_key]{main::key($num++,0,3,$basic_count)} = $resolution;
+ }
+ if ($m_count == $basic_count){
+ $row[$row_key]{main::key($num++,0,2,'s-dpi')} = $dpi if $dpi;
+ }
+ next;
+ }
+ $row_key++;
+ $row[$row_key]{main::key($num++,0,3,'Monitor')} = $monitor{'monitor'};
+ if ($monitor{'res-x'} && $monitor{'res-y'}){
+ $resolution = $monitor{'res-x'} . 'x' . $monitor{'res-y'};
+ }
+ $resolution ||= 'N/A';
+ $row[$row_key]{main::key($num++,0,4,'res')} = $resolution;
+ $hz = ($monitor{'hz'}) ? $monitor{'hz'} : '';
+ $row[$row_key]{main::key($num++,0,4,'hz')} = $hz if $hz;
+ $dpi = ($monitor{'dpi'}) ? $monitor{'dpi'} : '';
+ $row[$row_key]{main::key($num++,0,4,'dpi')} = $dpi if $dpi;
+ #print "$dpi :: $main{'s-dpi'}\n";
+ if ($monitor{'size-x'} && $monitor{'size-y'}){
+ $size = $monitor{'size-x'} . 'x' . $monitor{'size-y'} .
+ 'mm ('. $monitor{'size-x-i'} . 'x' . $monitor{'size-y-i'} . '")';
+ }
+ $size ||= '';
+ $row[$row_key]{main::key($num++,0,4,'size')} = $size if $size;
+ if ($monitor{'diagonal'}){
+ $diag = $monitor{'diagonal-m'} . 'mm ('. $monitor{'diagonal'} . '")';
+ }
+ $diag ||= '';
+ $row[$row_key]{main::key($num++,0,4,'diag')} = $diag if $diag;
+ }
}
}
}
- if ($resolution){
- $row[0]{main::key($num++,'resolution')} = $resolution;
- }
else {
$graphics{'tty'} ||= 'N/A';
- $row[0]{main::key($num++,'tty')} = $graphics{'tty'};
+ $row[0]{main::key($num++,0,2,'tty')} = $graphics{'tty'};
}
}
eval $end if $b_log;
return @row;
}
+
+sub x_display_data {
+ eval $start if $b_log;
+ # X vendor and version detection.
+ # new method added since radeon and X.org and the disappearance of
+ # <X server name> version : ...etc. Later on, the normal textual version string
+ # returned, e.g. like: X.Org version: 6.8.2
+ # A failover mechanism is in place: if $version empty, release number parsed instead
+ if (my $program = main::check_program('xdpyinfo')){
+ my ($diagonal,$diagonal_m,$dpi) = ('','','');
+ my ($screen_id,$screen,@working);
+ my ($res_x,$res_x_i,$res_y,$res_y_i,$size_x,$size_x_i,$size_y,$size_y_i);
+ my @xdpyinfo = main::grabber("$program $display_opt 2>/dev/null","\n",'strip');
+ #@xdpyinfo = map {s/^\s+//;$_} @xdpyinfo if @xdpyinfo;
+ #print join "\n",@xdpyinfo, "\n";
+ foreach (@xdpyinfo){
+ @working = split /:\s+/, $_;
+ next if ( ($graphics{'screens'} && $working[0] !~ /^(dimensions$|screen\s#)/ ) || !$working[0] );
+ #print "$_\n";
+ if ($working[0] eq 'vendor string'){
+ $working[1] =~ s/The\s|\sFoundation//g;
+ # some distros, like fedora, report themselves as the xorg vendor,
+ # so quick check here to make sure the vendor string includes Xorg in string
+ if ($working[1] !~ /x/i){
+ $working[1] .= ' X.org';
+ }
+ $graphics{'x-vendor'} = $working[1];
+ }
+ elsif ($working[0] eq 'name of display'){
+ $graphics{'display-id'} = $working[1];
+ }
+ elsif ($working[0] eq 'version number'){
+ $graphics{'x-version-id'} = $working[1];
+ }
+ # note used, fix that
+ elsif ($working[0] eq 'vendor release number'){
+ $graphics{'x-vendor-release'} = $working[1];
+ }
+ elsif ($working[0] eq 'X.Org version'){
+ $graphics{'xorg-version'} = $working[1];
+ }
+ elsif ($working[0] eq 'default screen number'){
+ $graphics{'display-default-screen'} = $working[1];
+ }
+ elsif ($working[0] eq 'number of screens'){
+ $graphics{'display-screens'} = $working[1];
+ }
+ elsif ($working[0] =~ /^screen #([0-9]+):/){
+ $screen_id = $1;
+ $graphics{'screens'} = () if !$graphics{'screens'};
+ }
+ elsif ($working[0] eq 'resolution'){
+ $working[1] =~ s/^([0-9]+)x/$1/;
+ $graphics{'s-dpi'} = $working[1];
+ }
+ elsif ($working[0] eq 'dimensions'){
+ ($dpi,$res_x,$res_y,$size_x,$size_y) = (undef,undef,undef,undef,undef);
+ if ($working[1] =~ /([0-9]+)\s*x\s*([0-9]+)\s+pixels\s+\(([0-9]+)\s*x\s*([0-9]+)\s*millimeters\)/){
+ $res_x = $1;
+ $res_y = $2;
+ $size_x = $3;
+ $size_y = $4;
+ $res_x_i = ($1) ? sprintf("%.1f", ($1/25.4)) : 0;
+ $res_y_i = ($2) ? sprintf("%.1f", ($2/25.4)) : 0;
+ $size_x_i = ($3) ? sprintf("%.1f", ($3/25.4)) : 0;
+ $size_y_i = ($4) ? sprintf("%.1f", ($4/25.4)) : 0;
+ $dpi = ($res_x && $size_x) ? sprintf("%.0f", ($res_x*25.4/$size_x)) : '';
+ $diagonal = ($res_x && $size_x) ? sprintf("%.1f", (sqrt($size_x**2 + $size_y**2)/25.4 )) : '';
+ $diagonal += 0 if $diagonal;# trick to get rid of decimal 0
+ $diagonal_m = ($res_x && $size_x) ? sprintf("%.0f", (sqrt($size_x**2 + $size_y**2))) : '';
+ }
+ $screen = {
+ 'screen' => $screen_id,
+ 'res-x' => $res_x,
+ 'res-x-i' => $res_x_i,
+ 'res-y' => $res_y,
+ 'res-y-i' => $res_y_i,
+ 'size-x' => $size_x,
+ 'size-x-i' => $size_x_i,
+ 'size-y' => $size_y,
+ 'size-y-i' => $size_y_i,
+ 's-dpi' => $dpi,
+ 'diagonal' => $diagonal,
+ 'diagonal-m' => $diagonal_m,
+ };
+ push @{$graphics{'screens'}}, $screen;
+ }
+ }
+ #print Data::Dumper::Dumper $graphics{'screens'};
+ if (my $program = main::check_program('xrandr')){
+ ($diagonal,$diagonal_m,$dpi) = (undef);
+ ($screen_id,$screen,@working) = (undef);
+ ($res_x,$res_x_i,$res_y,$res_y_i,$size_x,$size_x_i,$size_y,$size_y_i) = (undef);
+ my ($monitor,@monitors,$monitor_id,$screen,$screen_id,@xrandr_screens);
+ my @xrandr = main::grabber("$program $display_opt 2>/dev/null",'','strip');
+ #$graphics{'dimensions'} = (\@dimensions);
+ # we get a bit more info from xrandr than xdpyinfo, but xrandr fails to handle
+ # multiple screens from different video cards
+ foreach (@xrandr){
+ if (/^Screen ([0-9]+):/){
+ $screen_id = $1;
+ push @xrandr_screens, \@monitors if @monitors;
+ @monitors = ();
+ }
+ if (/^([^\s]+)\s+connected\s(primary\s)?([0-9]+)\s*x\s*([0-9]+)\+[0-9+]+(\s\([^)]+\))?(\s([0-9]+)mm\sx\s([0-9]+)mm)?/){
+ $monitor_id = $1;
+ $res_x = $3;
+ $res_y = $4;
+ $size_x = $7;
+ $size_y = $8;
+ $res_x_i = ($3) ? sprintf("%.1f", ($3/25.4)) : 0;
+ $res_y_i = ($4) ? sprintf("%.1f", ($4/25.4)) : 0;
+ $size_x_i = ($7) ? sprintf("%.1f", ($7/25.4)) : 0;
+ $size_y_i = ($8) ? sprintf("%.1f", ($8/25.4)) : 0;
+ $dpi = ($res_x && $size_x) ? sprintf("%.0f", $res_x * 25.4 / $size_x) : '';
+ $diagonal = ($res_x && $size_x) ? sprintf("%.1f", (sqrt($size_x**2 + $size_y**2)/25.4 )) : '';
+ $diagonal += 0 if $diagonal; # trick to get rid of decimal 0
+ $diagonal_m = ($res_x && $size_x) ? sprintf("%.0f", (sqrt($size_x**2 + $size_y**2))) : '';
+ $monitor = {
+ 'screen' => $screen_id,
+ 'monitor' => $monitor_id,
+ 'res-x' => $res_x,
+ 'res-x-i' => $res_x_i,
+ 'res-y' => $res_y,
+ 'res-y-i' => $res_y_i,
+ 'size-x' => $size_x,
+ 'size-x-i' => $size_x_i,
+ 'size-y' => $size_y,
+ 'size-y-i' => $size_y_i,
+ 'dpi' => $dpi,
+ 'diagonal' => $diagonal,
+ 'diagonal-m' => $diagonal_m,
+ };
+ push @monitors, $monitor;
+ # print "x:$size_x y:$size_y rx:$res_x ry:$res_y dpi:$dpi\n";
+ ($res_x,$res_x_i,$res_y,$res_y_i,$size_x,$size_x_i,$size_y,$size_y_i) = (0,0,0,0,0,0,0,0);
+
+ }
+ my @working = split /\s+/,$_;
+ # print join "$_\n";
+ if ($working[1] =~ /\*/){
+ $working[1] =~ s/\*|\+//g;
+ $working[1] = sprintf("%.0f",$working[1]);
+ $monitors[scalar @monitors - 1]{'hz'} = $working[1] if @monitors;
+ ($diagonal,$dpi) = ('','');
+ # print Data::Dumper::Dumper \@monitors;
+ }
+ }
+ push @xrandr_screens, \@monitors if @monitors;
+ #print "xrand: " . Data::Dumper::Dumper \@xrandr_screens;
+ my ($i) = (0);
+ foreach (@{$graphics{'screens'}}){
+ my %main = %$_;
+ # print "h: " . Data::Dumper::Dumper \%main;
+ #print $main{'screen'}, "\n";
+ foreach my $ref2 (@xrandr_screens){
+ my @screens = @$ref2;
+ # print "d: " . Data::Dumper::Dumper \@screens;
+ if ($screens[0]{'screen'} eq $main{'screen'}){
+ ${$graphics{'screens'}}[$i]{'monitors'} = \@screens;
+ last;
+ }
+ }
+ $i++;
+ }
+ if (!$graphics{'screens'}) {
+ $graphics{'tty'} = tty_data();
+ }
+ }
+ }
+ else {
+ $graphics{'no-xdpyinfo'} = main::row_defaults('xdpyinfo-missing');
+ }
+ print 'last: ', Data::Dumper::Dumper $graphics{'screens'} if $test[17];
+ main::log_data('dump','$graphics{screens}',$graphics{'screens'}) if $b_log;
+ eval $end if $b_log;
+}
+sub wayland_display_data {
+ eval $start if $b_log;
+ if ($ENV{'WAYLAND_DISPLAY'}){
+ $graphics{'display-id'} = $ENV{'WAYLAND_DISPLAY'};
+ # return as wayland-0 or 0?
+ $graphics{'display-id'} =~ s/wayland-?//i;
+ }
+ #print 'last: ', Data::Dumper::Dumper $graphics{'screens'} if $test[17];
+ #main::log_data('dump','@graphics{screens}',$graphics{'screens'}) if $b_log;
+ eval $end if $b_log;
+}
+sub set_compositor {
+ eval $start if $b_log;
+ my ($protocol) = @_;
+ # initial tests, if wayland, it is certainly a compositor
+ $protocol = lc($protocol) if $protocol;
+ $graphics{'compositor'} = display_compositor($protocol);
+ # gnome-shell is incredibly slow to return version
+ if (($extra > 2 || $protocol eq 'wayland') && $graphics{'compositor'} &&
+ ( !$show{'system'} || $graphics{'compositor'} ne 'gnome-shell' ) ){
+ $graphics{'compositor-version'} = (main::program_data($graphics{'compositor'},$graphics{'compositor'},3))[1];
+ }
+ eval $end if $b_log;
+}
+sub get_protocol {
+ eval $start if $b_log;
+ my ($protocol) = ('');
+ $protocol = $ENV{'XDG_SESSION_TYPE'} if $ENV{'XDG_SESSION_TYPE'};
+ $protocol = $ENV{'WAYLAND_DISPLAY'} if (!$protocol && $ENV{'WAYLAND_DISPLAY'});
+ # can show as wayland-0
+ $protocol = 'wayland' if $protocol && $protocol =~ /wayland/i;
+ # yes, I've seen this in 2019 distros, sigh
+ $protocol = '' if $protocol eq 'tty';
+ # need to confirm that there's a point to this test, I believe no, fails out of x
+ # loginctl also results in the session id
+ if (!$protocol && $b_display && $b_force_display){
+ if (my $program = main::check_program('loginctl')){
+ my $id = '';
+ # $id = $ENV{'XDG_SESSION_ID'}; # returns tty session in console
+ my @data = main::grabber("$program --no-pager --no-legend 2>/dev/null",'','strip');
+ foreach (@data){
+ next if /tty[v]?[0-6]$/; # freebsd: ttyv3
+ $id = (split /\s+/, $_)[0];
+ last; # multiuser? too bad, we'll go for the first one
+ }
+ if ($id ){
+ my $temp = (main::grabber("$program show-session $id -p Type --no-pager --no-legend 2>/dev/null"))[0];
+ $temp =~ s/Type=// if $temp;
+ # ssh will not show /dev/ttyx so would have passed the first test
+ $protocol = $temp if $temp && $temp ne 'tty';
+ }
+ }
+ }
+ eval $end if $b_log;
+ return $protocol;
+}
sub gl_data(){
eval $start if $b_log;
my $num = 0;
@@ -9581,7 +10865,7 @@ sub gl_data(){
$type = 'display-null';
}
@row = ({
- main::key($num++,'Message') => main::row_defaults($type),
+ main::key($num++,0,1,'Message') => main::row_defaults($type),
});
return @row;
}
@@ -9664,20 +10948,20 @@ sub gl_data(){
$version = join ', ', @opengl_version if @opengl_version;
$renderer = join ', ', @renderer if @renderer;
@row = ({
- main::key($num++,'OpenGL') => '',
- main::key($num++,'renderer') => ($renderer) ? $renderer : 'N/A',
- main::key($num++,'v') => ($version) ? $version : 'N/A',
+ main::key($num++,1,1,'OpenGL') => '',
+ main::key($num++,1,2,'renderer') => ($renderer) ? $renderer : 'N/A',
+ main::key($num++,0,2,'v') => ($version) ? $version : 'N/A',
});
if ($b_compat && $extra > 1 && $compat_version){
- $row[0]{main::key($num++,'compat-v')} = $compat_version;
+ $row[0]{main::key($num++,0,2,'compat-v')} = $compat_version;
}
if ($extra > 0){
- $row[0]{main::key($num++,'direct render')} = $direct_render;
+ $row[0]{main::key($num++,0,2,'direct render')} = $direct_render;
}
}
else {
@row = ({
- main::key($num++,'Message') => main::row_defaults('glxinfo-missing'),
+ main::key($num++,0,1,'Message') => main::row_defaults('glxinfo-missing'),
});
}
}
@@ -9695,7 +10979,7 @@ sub gl_data(){
}
}
@row = ({
- main::key($num++,'Message') => main::row_defaults($type),
+ main::key($num++,0,1,'Message') => main::row_defaults($type),
});
}
eval $end if $b_log;
@@ -9730,6 +11014,7 @@ sub x_drivers {
# $log = "$ENV{HOME}/bin/scripts/inxi/data/xorg-logs/loading-unload-failed-all41-mint.txt";
# $log = "$ENV{HOME}/bin/scripts/inxi/data/xorg-logs/loading-unload-failed-phd21-mint.txt";
# $log = "$ENV{HOME}/bin/scripts/inxi/data/xorg-logs/Xorg.0-gm10.log";
+ # $log = "$ENV{HOME}/bin/scripts/inxi/data/xorg-logs/xorg-multi-driver-1.log";
my @xorg = main::reader($log);
# list is from sgfxi plus non-free drivers, plus ARM drivers
my $list = join '|',qw(amdgpu apm ark armsoc atimisc ati
@@ -9810,7 +11095,6 @@ sub x_drivers {
$alternate .= $sep . $_;
}
}
- $loaded ||= 'none';
@driver_data = ($loaded,$unloaded,$failed,$alternate);
}
eval $end if $b_log;
@@ -9863,7 +11147,7 @@ sub display_compositor {
eval $start if $b_log;
my ($protocol) = @_;
my ($compositor) = ('');
- main::set_ps_gui() if ! $b_ps_gui;
+ main::set_ps_gui() if !$b_ps_gui;
if (@ps_gui){
# 1 check program; 2 search; 3 unused version; 4 print
my @compositors = (
@@ -9897,6 +11181,7 @@ sub display_compositor {
['orbital','orbital','','orbital'],
['papyros','papyros','','papyros'],
['perceptia','perceptia','','perceptia'],
+ ['picom','picom','','picom'],
['rustland','rustland','','rustland'],
['sommelier','sommelier','','sommelier'],
['sway','sway','','sway'],
@@ -9906,6 +11191,7 @@ sub display_compositor {
['unity-system-compositor','unity-system-compositor','','unity-system-compositor'],
['way-cooler','way-cooler','','way-cooler'],
['wavy','wavy','','wavy'],
+ ['wayfire','wayfire','','wayfire'],
['wayhouse','wayhouse','','wayhouse'],
['westford','westford','','westford'],
['xcompmgr','xcompmgr','','xcompmgr'],
@@ -9975,7 +11261,7 @@ sub get {
}
# if error case, null data, whatever
if ($key1) {
- @data = ({main::key($num++,$key1) => $val1,});
+ @data = ({main::key($num++,0,1,$key1) => $val1,});
}
eval $end if $b_log;
return @data;
@@ -10023,7 +11309,7 @@ sub create_output {
$data{'device'} ||= 'N/A';
$j = scalar @rows;
@row = ({
- main::key($num++,'Type') => ucfirst($data{'device'}),
+ main::key($num++,0,1,'Type') => ucfirst($data{'device'}),
},);
@rows = (@rows,@row);
if (!$b_skip_system){
@@ -10032,10 +11318,10 @@ sub create_output {
$product_name = ($data{'product_name'}) ? $data{'product_name'}:'N/A';
$product_version = ($data{'product_version'}) ? $data{'product_version'}:'N/A';
$product_serial = main::apply_filter($data{'product_serial'});
- $rows[$j]{main::key($num++,'System')} = $system_vendor;
- $rows[$j]{main::key($num++,'product')} = $product_name;
- $rows[$j]{main::key($num++,'v')} = $product_version;
- $rows[$j]{main::key($num++,'serial')} = $product_serial;
+ $rows[$j]{main::key($num++,1,1,'System')} = $system_vendor;
+ $rows[$j]{main::key($num++,0,2,'product')} = $product_name;
+ $rows[$j]{main::key($num++,0,2,'v')} = $product_version;
+ $rows[$j]{main::key($num++,0,2,'serial')} = $product_serial;
# no point in showing chassis if system isn't there, it's very unlikely that
# would be correct
if ($extra > 1){
@@ -10057,14 +11343,14 @@ sub create_output {
$chassis_serial = main::apply_filter($data{'chassis_serial'});
$chassis_vendor ||= '';
$chassis_type ||= '';
- $rows[$j]{main::key($num++,'Chassis')} = $chassis_vendor;
+ $rows[$j]{main::key($num++,1,1,'Chassis')} = $chassis_vendor;
if ($chassis_type){
- $rows[$j]{main::key($num++,'type')} = $chassis_type;
+ $rows[$j]{main::key($num++,0,2,'type')} = $chassis_type;
}
if ($chassis_version){
- $rows[$j]{main::key($num++,'v')} = $chassis_version;
+ $rows[$j]{main::key($num++,0,2,'v')} = $chassis_version;
}
- $rows[$j]{main::key($num++,'serial')} = $chassis_serial;
+ $rows[$j]{main::key($num++,0,2,'serial')} = $chassis_serial;
}
}
$j++; # start new row
@@ -10092,23 +11378,23 @@ sub create_output {
if ($extra > 1 && $data{'bios_romsize'}){
$bios_romsize = $data{'bios_romsize'};
}
- $rows[$j]{main::key($num++,'Mobo')} = $mobo_vendor;
- $rows[$j]{main::key($num++,'model')} = $mobo_model;
+ $rows[$j]{main::key($num++,1,1,'Mobo')} = $mobo_vendor;
+ $rows[$j]{main::key($num++,0,2,'model')} = $mobo_model;
if ($mobo_version){
- $rows[$j]{main::key($num++,'v')} = $mobo_version;
+ $rows[$j]{main::key($num++,0,2,'v')} = $mobo_version;
}
- $rows[$j]{main::key($num++,'serial')} = $mobo_serial;
+ $rows[$j]{main::key($num++,0,2,'serial')} = $mobo_serial;
if ($extra > 2 && $data{'board_uuid'}){
- $rows[$j]{main::key($num++,'uuid')} = $data{'board_uuid'};
+ $rows[$j]{main::key($num++,0,2,'uuid')} = $data{'board_uuid'};
}
- $rows[$j]{main::key($num++,$firmware)} = $bios_vendor;
- $rows[$j]{main::key($num++,'v')} = $bios_version;
+ $rows[$j]{main::key($num++,1,1,$firmware)} = $bios_vendor;
+ $rows[$j]{main::key($num++,0,2,'v')} = $bios_version;
if ($bios_rev){
- $rows[$j]{main::key($num++,'rev')} = $bios_rev;
+ $rows[$j]{main::key($num++,0,2,'rev')} = $bios_rev;
}
- $rows[$j]{main::key($num++,'date')} = $bios_date;
+ $rows[$j]{main::key($num++,0,2,'date')} = $bios_date;
if ($bios_romsize){
- $rows[$j]{main::key($num++,'rom size')} = $bios_romsize;
+ $rows[$j]{main::key($num++,0,2,'rom size')} = $bios_romsize;
}
eval $end if $b_log;
return @rows;
@@ -10116,8 +11402,7 @@ sub create_output {
sub create_output_soc {
my (%soc_machine) = @_;
my ($key,%data,@row,@rows);
- my $num = 0;
- my $j = 0;
+ my ($cont_sys,$ind_sys,$j,$num) = (1,1,0,0);
#print Data::Dumper::Dumper \%soc_machine;
# this is sketchy, /proc/device-tree/model may be similar to Hardware value from /proc/cpuinfo
# raspi: Hardware : BCM2835 model: Raspberry Pi Model B Rev 2
@@ -10125,27 +11410,28 @@ sub create_output_soc {
if ($b_arm){$key = 'ARM Device'}
elsif ($b_mips){$key = 'MIPS Device'}
elsif ($b_ppc){$key = 'PowerPC Device'}
- $rows[$j]{main::key($num++,'Type')} = $key;
+ $rows[$j]{main::key($num++,0,1,'Type')} = $key;
my $system = 'System';
if (defined $soc_machine{'model'}){
- $rows[$j]{main::key($num++,'System')} = $soc_machine{'model'};
+ $rows[$j]{main::key($num++,1,1,'System')} = $soc_machine{'model'};
$system = 'details';
+ ($cont_sys,$ind_sys) = (0,2);
}
$soc_machine{'device'} ||= 'N/A';
- $rows[$j]{main::key($num++,$system)} = $soc_machine{'device'};
+ $rows[$j]{main::key($num++,$cont_sys,$ind_sys,$system)} = $soc_machine{'device'};
}
# we're going to print N/A for 0000 values sine the item was there.
if ($soc_machine{'firmware'}){
# most samples I've seen are like: 0000
$soc_machine{'firmware'} =~ s/^[0]+$//;
$soc_machine{'firmware'} ||= 'N/A';
- $rows[$j]{main::key($num++,'rev')} = $soc_machine{'firmware'};
+ $rows[$j]{main::key($num++,0,2,'rev')} = $soc_machine{'firmware'};
}
# sometimes has value like: 0000
if (defined $soc_machine{'serial'}){
# most samples I've seen are like: 0000
$soc_machine{'serial'} =~ s/^[0]+$//;
- $rows[$j]{main::key($num++,'serial')} = main::apply_filter($soc_machine{'serial'});
+ $rows[$j]{main::key($num++,0,2,'serial')} = main::apply_filter($soc_machine{'serial'});
}
eval $end if $b_log;
return @rows;
@@ -10587,7 +11873,7 @@ sub get {
my $type = ($b_arm) ? 'arm' : 'mips';
my $key = 'Message';
@data = ({
- main::key($num++,$key) => main::row_defaults($type . '-pci',''),
+ main::key($num++,0,1,$key) => main::row_defaults($type . '-pci',''),
},);
@rows = (@rows,@data);
}
@@ -10638,17 +11924,17 @@ sub card_data {
#$card ||= 'N/A';
$driver ||= 'N/A';
@data = ({
- main::key($num++,'Device') => $card,
+ main::key($num++,1,1,'Device') => $card,
},);
@rows = (@rows,@data);
if ($extra > 0 && $b_pci_tool && $row[12]){
my $item = main::get_pci_vendor($row[4],$row[12]);
- $rows[$j]{main::key($num++,'vendor')} = $item if $item;
+ $rows[$j]{main::key($num++,0,2,'vendor')} = $item if $item;
}
if ($row[1] eq '0680'){
- $rows[$j]{main::key($num++,'type')} = 'network bridge';
+ $rows[$j]{main::key($num++,0,2,'type')} = 'network bridge';
}
- $rows[$j]{main::key($num++,'driver')} = $driver;
+ $rows[$j]{main::key($num++,1,2,'driver')} = $driver;
my $bus_id = 'N/A';
# note: for arm/mips we want to see the single item bus id, why not?
# note: we can have bus id: 0002 / 0 which is valid, but 0 / 0 is invalid
@@ -10659,15 +11945,19 @@ sub card_data {
if ($row[9] && !$bsd_type){
my $version = main::get_module_version($row[9]);
$version ||= 'N/A';
- $rows[$j]{main::key($num++,'v')} = $version;
+ $rows[$j]{main::key($num++,0,3,'v')} = $version;
+ }
+ if ($b_admin && $row[10]){
+ $row[10] = main::get_driver_modules($row[9],$row[10]);
+ $rows[$j]{main::key($num++,0,3,'modules')} = $row[10] if $row[10];
}
$row[8] ||= 'N/A';
# as far as I know, wifi has no port, but in case it does in future, use it
- $rows[$j]{main::key($num++,'port')} = $row[8] if (!$b_wifi || ( $b_wifi && $row[8] ne 'N/A') );
- $rows[$j]{main::key($num++,'bus ID')} = $bus_id;
+ $rows[$j]{main::key($num++,0,2,'port')} = $row[8] if (!$b_wifi || ( $b_wifi && $row[8] ne 'N/A') );
+ $rows[$j]{main::key($num++,0,2,'bus ID')} = $bus_id;
}
if ($extra > 1){
- $rows[$j]{main::key($num++,'chip ID')} = $chip_id;
+ $rows[$j]{main::key($num++,0,2,'chip ID')} = $chip_id;
}
if ($show{'network-advanced'}){
@data = ();
@@ -10690,7 +11980,7 @@ sub card_data {
$type = 'pci-card-data-root';
}
@data = ({
- main::key($num++,$key) => main::row_defaults($type,''),
+ main::key($num++,0,1,$key) => main::row_defaults($type,''),
},);
@rows = (@rows,@data);
@@ -10722,20 +12012,20 @@ sub usb_data {
if ($product && network_device($test)){
$driver ||= 'usb-network';
@data = ({
- main::key($num++,'Device') => $product,
- main::key($num++,'type') => 'USB',
- main::key($num++,'driver') => $driver,
+ main::key($num++,1,1,'Device') => $product,
+ main::key($num++,0,2,'type') => 'USB',
+ main::key($num++,0,2,'driver') => $driver,
},);
$b_wifi = check_wifi($product);
@rows = (@rows,@data);
if ($extra > 0){
- $rows[$j]{main::key($num++,'bus ID')} = "$path_id:$row[1]";
+ $rows[$j]{main::key($num++,0,2,'bus ID')} = "$path_id:$row[1]";
}
if ($extra > 1){
- $rows[$j]{main::key($num++,'chip ID')} = $row[7];
+ $rows[$j]{main::key($num++,0,2,'chip ID')} = $row[7];
}
if ($extra > 2 && $row[16]){
- $rows[$j]{main::key($num++,'serial')} = main::apply_filter($row[16]);
+ $rows[$j]{main::key($num++,0,2,'serial')} = main::apply_filter($row[16]);
}
if ($show{'network-advanced'}){
@data = ();
@@ -10764,7 +12054,7 @@ sub advanced_data_sys {
eval $start if $b_log;
return if ! -d '/sys/class/net';
my ($vendor,$chip,$count,$b_wifi,$path_usb,$bus_id) = @_;
- my $num = 0;
+ my ($cont_if,$ind_if,$num) = (2,3,0);
my $key = 'IF';
my ($b_check,$b_usb,$if,$path,@paths,@row,@rows);
# ntoe: we've already gotten the base path, now we
@@ -10784,6 +12074,7 @@ sub advanced_data_sys {
if ($vendor eq 'check'){
$b_check = 1;
$key = 'IF-ID';
+ ($cont_if,$ind_if) = (1,2);
}
#print join '; ', @paths, $count, "\n";
foreach (@paths){
@@ -10831,8 +12122,8 @@ sub advanced_data_sys {
$state ||= 'N/A';
#print "$speed \n";
@row = ({
- main::key($num++,$key) => $if,
- main::key($num++,'state') => $state,
+ main::key($num++,1,$cont_if,$key) => $if,
+ main::key($num++,0,$ind_if,'state') => $state,
},);
#my $j = scalar @row - 1;
push (@ifs_found, $if) if (!$b_check && (! grep {/$if/} @ifs_found));
@@ -10845,10 +12136,10 @@ sub advanced_data_sys {
if (!$b_wifi && $state ne 'down' && $state ne 'no'){
# make sure the value is strictly numeric before appending Mbps
$speed = ( main::is_int($speed) ) ? "$speed Mbps" : $speed;
- $row[0]{main::key($num++,'speed')} = $speed;
- $row[0]{main::key($num++,'duplex')} = $duplex;
+ $row[0]{main::key($num++,0,$ind_if,'speed')} = $speed;
+ $row[0]{main::key($num++,0,$ind_if,'duplex')} = $duplex;
}
- $row[0]{main::key($num++,'mac')} = $mac;
+ $row[0]{main::key($num++,0,$ind_if,'mac')} = $mac;
if ($b_check){
@rows = (@rows,@row);
}
@@ -10856,7 +12147,7 @@ sub advanced_data_sys {
@rows = @row;
}
if ($show{'ip'}){
- @row = if_ip($if);
+ @row = if_ip($key,$if);
@rows = (@rows,@row);
}
last if !$b_check;
@@ -10872,12 +12163,13 @@ sub advanced_data_bsd {
my ($if,$b_wifi) = @_;
my (@data,@row,@rows,$working_if);
my ($b_check,$state,$speed,$duplex,$mac);
- my $num = 0;
+ my ($cont_if,$ind_if,$num) = (2,3,0);
my $key = 'IF';
my $j = 0;
if ($if eq 'check'){
$b_check = 1;
$key = 'IF-ID';
+ ($cont_if,$ind_if) = (1,2);
}
foreach my $ref (@ifs_bsd){
if (ref $ref ne 'ARRAY'){
@@ -10903,8 +12195,8 @@ sub advanced_data_bsd {
$state ||= 'N/A';
#print "$speed \n";
@row = ({
- main::key($num++,$key) => $if,
- main::key($num++,'state') => $state,
+ main::key($num++,1,$cont_if,$key) => $if,
+ main::key($num++,0,$ind_if,'state') => $state,
},);
push (@ifs_found, $if) if (!$b_check && (! grep {/$if/} @ifs_found ));
# print "push: if: $if ifs: @ifs_found\n";
@@ -10914,14 +12206,14 @@ sub advanced_data_bsd {
if (!$b_wifi && $state ne 'down' && $state ne 'no'){
# make sure the value is strictly numeric before appending Mbps
$speed = ( main::is_int($speed) ) ? "$speed Mbps" : $speed;
- $row[0]{main::key($num++,'speed')} = $speed;
- $row[0]{main::key($num++,'duplex')} = $duplex;
+ $row[0]{main::key($num++,0,$ind_if,'speed')} = $speed;
+ $row[0]{main::key($num++,0,$ind_if,'duplex')} = $duplex;
}
- $row[0]{main::key($num++,'mac')} = $mac;
+ $row[0]{main::key($num++,0,$ind_if,'mac')} = $mac;
}
@rows = (@rows,@row);
if ($show{'ip'}){
- @row = if_ip($if) if $if;
+ @row = if_ip($key,$if) if $if;
@rows = (@rows,@row) if @row;
}
}
@@ -10937,11 +12229,15 @@ sub advanced_data_bsd {
# 4 - scope if, if different from if
sub if_ip {
eval $start if $b_log;
- my ($if) = @_;
+ my ($type,$if) = @_;
my (@data,@row,@rows,$working_if);
+ my ($cont_ip,$ind_ip) = (3,4);
my $num = 0;
my $j = 0;
$b_ip_run = 1;
+ if ($type eq 'IF-ID'){
+ ($cont_ip,$ind_ip) = (2,3);
+ }
OUTER:
foreach my $ref (@ifs){
if (ref $ref ne 'ARRAY'){
@@ -10959,7 +12255,7 @@ sub if_ip {
$num = 1;
if ($limit > 0 && $j >= $limit){
@row = ({
- main::key($num++,'Message') => main::row_defaults('output-limit',scalar @data),
+ main::key($num++,0,$cont_ip,'Message') => main::row_defaults('output-limit',scalar @data),
},);
@rows = (@rows,@row);
last OUTER;
@@ -10970,6 +12266,7 @@ sub if_ip {
$ipv = ($data2[0])? $data2[0]: 'N/A';
$ip = main::apply_filter($data2[1]);
$scope = ($data2[3])? $data2[3]: 'N/A';
+ # note: where is this ever set to 'all'? Old test condition?
if ($if ne 'all'){
if (defined $data2[4] && $working_if ne $data2[4]){
# scope global temporary deprecated dynamic
@@ -10985,29 +12282,29 @@ sub if_ip {
$data2[4] =~ s/\s$if$// if $data2[4] =~ /[^\s]+\s$if$/;
my $key = ($data2[4] =~ /deprecated|dynamic|temporary|noprefixroute/ ) ? 'type':'virtual' ;
@row = ({
- main::key($num++,"IP v$ipv") => $ip,
- main::key($num++,$key) => $data2[4],
- main::key($num++,'scope') => $scope,
+ main::key($num++,1,$cont_ip,"IP v$ipv") => $ip,
+ main::key($num++,0,$ind_ip,$key) => $data2[4],
+ main::key($num++,0,$ind_ip,'scope') => $scope,
},);
}
else {
@row = ({
- main::key($num++,"IP v$ipv") => $ip,
- main::key($num++,'scope') => $scope,
+ main::key($num++,1,$cont_ip,"IP v$ipv") => $ip,
+ main::key($num++,0,$ind_ip,'scope') => $scope,
},);
}
}
else {
@row = ({
- main::key($num++,'IF') => $if,
- main::key($num++,"IP v$ipv") => $ip,
- main::key($num++,'scope') => $scope,
+ main::key($num++,1,($cont_ip - 1 ),'IF') => $if,
+ main::key($num++,1,$cont_ip,"IP v$ipv") => $ip,
+ main::key($num++,0,$ind_ip,'scope') => $scope,
},);
}
@rows = (@rows,@row);
if ($extra > 1 && $data2[2]){
$broadcast = main::apply_filter($data2[2]);
- $rows[$j]{main::key($num++,'broadcast')} = $broadcast;
+ $rows[$j]{main::key($num++,0,$ind_ip,'broadcast')} = $broadcast;
}
}
}
@@ -11026,13 +12323,21 @@ sub if_ip {
# dig +short +time=1 +tries=1 myip.opendns.com. A @208.67.222.222
sub wan_ip {
eval $start if $b_log;
- my (@data,$ip,$ua);
+ my (@data,$b_dig,$b_html,$ip,$ua);
my $num = 0;
# time: 0.06 - 0.07 seconds
+ # cisco opendns.com may be terminating supporting this one, sometimes works, sometimes not:
+ # use -4/6 to force ipv 4 or 6, but generally we want the 'natural' native
+ # ip returned.
+ # dig +short +time=1 +tries=1 myip.opendns.com @resolver1.opendns.com
+ # dig +short @ns1-1.akamaitech.net ANY whoami.akamai.net
+ # this one can take forever, and sometimes requires explicit -4 or -6
+ # dig -4 TXT +short o-o.myaddr.l.google.com @ns1.google.com
if (!$b_skip_dig && (my $program = main::check_program('dig') )){
- $ip = (main::grabber("$program +short +time=1 +tries=1 myip.opendns.com \@resolver1.opendns.com 2>/dev/null"))[0];
+ $ip = (main::grabber("$program +short +time=1 +tries=1 \@ns1-1.akamaitech.net ANY whoami.akamai.net 2>/dev/null"))[0];
+ $b_dig = 1;
}
- else {
+ if (!$ip && !$b_no_html_wan) {
# note: tests: akamai: 0.055 - 0.065 icanhazip.com: 0.177 0.164
# smxi: 0.525, so almost 10x slower. Dig is fast too
# leaving smxi as last test because I know it will always be up.
@@ -11049,13 +12354,25 @@ sub wan_ip {
last;
}
}
+ $b_html = 1;
}
- if ($ip && $show{'filter'}){
+ if ($ip && $use{'filter'}){
$ip = $filter_string;
}
- $ip ||= main::row_defaults('IP', 'WAN IP');
+ if (!$ip){
+ # true case trips
+ if (!$b_dig){
+ $ip = main::row_defaults('IP-no-dig', 'WAN IP');
+ }
+ elsif ($b_dig && !$b_html){
+ $ip = main::row_defaults('IP-dig', 'WAN IP');
+ }
+ else {
+ $ip = main::row_defaults('IP', 'WAN IP');
+ }
+ }
@data = ({
- main::key($num++,'WAN IP') => $ip,
+ main::key($num++,0,1,'WAN IP') => $ip,
},);
eval $end if $b_log;
return @data;
@@ -11134,7 +12451,7 @@ sub get {
#@data = optical_data_bsd();
$key1 = 'Optical Report';
$val1 = main::row_defaults('optical-data-bsd');
- @data = ({main::key($num++,$key1) => $val1,});
+ @data = ({main::key($num++,0,1,$key1) => $val1,});
if ( @dm_boot_optical){
@data = optical_data_bsd();
}
@@ -11150,7 +12467,7 @@ sub get {
$val1 = main::row_defaults('optical-data-bsd');
}
$key1 = 'Optical Report';
- @data = ({main::key($num++,$key1) => $val1,});
+ @data = ({main::key($num++,0,1,$key1) => $val1,});
}
}
else {
@@ -11159,7 +12476,7 @@ sub get {
if (!@data){
$key1 = 'Message';
$val1 = main::row_defaults('optical-data');
- @data = ({main::key($num++,$key1) => $val1,});
+ @data = ({main::key($num++,0,1,$key1) => $val1,});
}
@rows = (@rows,@data);
eval $end if $b_log;
@@ -11174,7 +12491,7 @@ sub create_output {
# build floppy if any
foreach my $key (sort keys %devices){
if ($devices{$key}{'type'} eq 'floppy'){
- @data = ({ main::key($num++,ucfirst($devices{$key}{'type'})) => "/dev/$key"});
+ @data = ({ main::key($num++,0,1,ucfirst($devices{$key}{'type'})) => "/dev/$key"});
@rows = (@rows,@data);
delete $devices{$key};
}
@@ -11187,22 +12504,22 @@ sub create_output {
my $model = $devices{$key}{'model'};
$model ||= 'N/A';
@data = ({
- main::key($num++,ucfirst($devices{$key}{'type'})) => "/dev/$key",
- main::key($num++,'vendor') => $vendor,
- main::key($num++,'model') => $model,
+ main::key($num++,1,1,ucfirst($devices{$key}{'type'})) => "/dev/$key",
+ main::key($num++,0,2,'vendor') => $vendor,
+ main::key($num++,0,2,'model') => $model,
});
@rows = (@rows,@data);
if ($extra > 0){
my $rev = $devices{$key}{'rev'};
$rev ||= 'N/A';
- $rows[$j]{ main::key($num++,'rev')} = $rev;
+ $rows[$j]{ main::key($num++,0,2,'rev')} = $rev;
}
if ($extra > 1 && $devices{$key}{'serial'}){
- $rows[$j]{ main::key($num++,'serial')} = main::apply_filter($devices{$key}{'serial'});
+ $rows[$j]{ main::key($num++,0,2,'serial')} = main::apply_filter($devices{$key}{'serial'});
}
my $ref = $devices{$key}{'links'};
my $links = (@$ref) ? join ',', sort @$ref: 'N/A' ;
- $rows[$j]{ main::key($num++,'dev-links')} = $links;
+ $rows[$j]{ main::key($num++,0,2,'dev-links')} = $links;
if ($show{'optical'}){
$j = scalar @rows;
my $speed = $devices{$key}{'speed'};
@@ -11235,19 +12552,18 @@ sub create_output {
}
$rws = (@rw) ? join ',', @rw: 'none' ;
@data = ({
- main::key($num++,'Features') => '',
- main::key($num++,'speed') => $speed,
- main::key($num++,'multisession') => $multisession,
- main::key($num++,'audio') => $audio,
- main::key($num++,'dvd') => $dvd,
- main::key($num++,'rw') => $rws,
+ main::key($num++,1,2,'Features') => '',
+ main::key($num++,0,3,'speed') => $speed,
+ main::key($num++,0,3,'multisession') => $multisession,
+ main::key($num++,0,3,'audio') => $audio,
+ main::key($num++,0,3,'dvd') => $dvd,
+ main::key($num++,0,3,'rw') => $rws,
});
@rows = (@rows,@data);
-
if ($extra > 0 ){
my $state = $devices{$key}{'state'};
$state ||= 'N/A';
- $rows[$j]{ main::key($num++,'state')} = $state;
+ $rows[$j]{ main::key($num++,0,3,'state')} = $state;
}
}
}
@@ -11472,7 +12788,7 @@ sub get {
#$val1 = ($bsd_type && $bsd_type eq 'darwin') ?
# main::row_defaults('darwin-feature') : main::row_defaults('partition-data');
$val1 = main::row_defaults('partition-data');
- @rows = ({main::key($num++,$key1) => $val1,});
+ @rows = ({main::key($num++,0,1,$key1) => $val1,});
}
else {
@rows = create_output();
@@ -11496,6 +12812,8 @@ sub create_output {
my %row = %$ref;
$num = 1;
next if $row{'type'} eq 'secondary' && $show{'partition'};
+ next if $show{'swap'} && $row{'fs'} && $row{'fs'} eq 'swap';
+ next if $row{'swap-type'} && $row{'swap-type'} ne 'partition';
if (!$row{'hidden'}){
@data2 = main::get_size($row{'size'}) if (defined $row{'size'});
$size = (@data2) ? $data2[0] . ' ' . $data2[1]: 'N/A';
@@ -11512,9 +12830,10 @@ sub create_output {
$dev_type = ($row{'dev-type'}) ? $row{'dev-type'} : 'dev';
$row{'dev-base'} = '/dev/' . $row{'dev-base'} if $dev_type eq 'dev' && $row{'dev-base'};
$dev = ($row{'dev-base'}) ? $row{'dev-base'} : 'N/A';
+ $row{'id'} =~ s|/home/[^/]+/(.*)|/home/$filter_string/$1| if $use{'filter'};
$j = scalar @rows;
@data = ({
- main::key($num++,'ID') => $row{'id'},
+ main::key($num++,1,1,'ID') => $row{'id'},
});
@rows = (@rows,@data);
if (($b_admin || $row{'hidden'}) && $row{'raw-size'} ){
@@ -11526,31 +12845,36 @@ sub create_output {
@data2 = main::get_size($row{'raw-size'});
$raw_size = (@data2) ? $data2[0] . ' ' . $data2[1]: 'N/A';
}
- $rows[$j]{main::key($num++,'raw size')} = $raw_size;
+ $rows[$j]{main::key($num++,0,2,'raw size')} = $raw_size;
}
if ($b_admin && $row{'raw-available'} && $size ne 'N/A'){
$size .= ' (' . $row{'raw-available'} . '%)';
}
- $rows[$j]{main::key($num++,'size')} = $size;
- $rows[$j]{main::key($num++,'used')} = $used . $percent;
- $rows[$j]{main::key($num++,'fs')} = $fs;
- if ($b_admin && $fs eq 'swap' && $row{'swappiness'}){
- $rows[$j]{main::key($num++,'swappiness')} = $row{'swappiness'};
+ $rows[$j]{main::key($num++,0,2,'size')} = $size;
+ $rows[$j]{main::key($num++,0,2,'used')} = $used . $percent;
+ $rows[$j]{main::key($num++,0,2,'fs')} = $fs;
+ if ($b_admin && $fs eq 'swap' && defined $row{'swappiness'}){
+ $rows[$j]{main::key($num++,0,2,'swappiness')} = $row{'swappiness'};
+ }
+ if ($b_admin && $fs eq 'swap' && defined $row{'cache-pressure'}){
+ $rows[$j]{main::key($num++,0,2,'cache pressure')} = $row{'cache-pressure'};
}
- if ($b_admin && $fs eq 'swap' && $row{'cache-pressure'}){
- $rows[$j]{main::key($num++,'cache pressure')} = $row{'cache-pressure'};
+ if ($extra > 1 && $fs eq 'swap' && defined $row{'priority'}){
+ $rows[$j]{main::key($num++,0,2,'priority')} = $row{'priority'};
}
if ($b_admin && $row{'block-size'}){
- $rows[$j]{main::key($num++,'block size')} = $row{'block-size'} . ' B';;
- #$rows[$j]{main::key($num++,'physical')} = $row{'block-size'} . ' B';
- #$rows[$j]{main::key($num++,'logical')} = $row{'block-logical'} . ' B';
+ $rows[$j]{main::key($num++,0,2,'block size')} = $row{'block-size'} . ' B';;
+ #$rows[$j]{main::key($num++,0,2,'physical')} = $row{'block-size'} . ' B';
+ #$rows[$j]{main::key($num++,0,2,'logical')} = $row{'block-logical'} . ' B';
}
- $rows[$j]{main::key($num++,$dev_type)} = $dev;
+ $rows[$j]{main::key($num++,0,2,$dev_type)} = $dev;
if ($show{'label'}){
- $rows[$j]{main::key($num++,'label')} = ($row{'label'}) ? $row{'label'}: 'N/A';
+ $row{'label'} = main::apply_partition_filter('part', $row{'label'}, '') if $use{'filter-label'};
+ $rows[$j]{main::key($num++,0,2,'label')} = ($row{'label'}) ? $row{'label'}: 'N/A';
}
if ($show{'uuid'}){
- $rows[$j]{main::key($num++,'uuid')} = ($row{'uuid'}) ? $row{'uuid'}: 'N/A';
+ $row{'uuid'} = main::apply_partition_filter('part', $row{'uuid'}, '') if $use{'filter-uuid'};
+ $rows[$j]{main::key($num++,0,2,'uuid')} = ($row{'uuid'}) ? $row{'uuid'}: 'N/A';
}
}
eval $end if $b_log;
@@ -11614,9 +12938,11 @@ sub partition_data {
$roots++ if /\s\/$/;
}
@partitions_working = grep {!/^rootfs/} @partitions_working if $roots > 1;
- my $filters = '^(aufs|cgroup.*|cgmfs|configfs|debugfs|\/dev|dev|\/dev/loop[0-9]*|';
+ # IMPORTANT: check the lsblk completer tool check_partition_data() for matching lsblck
+ # filters.
+ my $filters = 'aufs|cgroup.*|cgmfs|configfs|debugfs|\/dev|dev|\/dev\/loop[0-9]*|';
$filters .= 'devfs|devtmpfs|fdescfs|iso9660|linprocfs|none|procfs|\/run(\/.*)?|';
- $filters .= 'run|shm|squashfs|sys|\/sys\/.*|sysfs|tmpfs|type|udev|unionfs|vartmp)$';
+ $filters .= 'run|shm|squashfs|sys|\/sys\/.*|sysfs|tmpfs|type|udev|unionfs|vartmp';
#push @partitions_working, '//mafreebox.freebox.fr/Disque dur cifs 239216096 206434016 20607496 91% /freebox/Disque dur';
#push @partitions_working, '//mafreebox.freebox.fr/AllPG cifs 436616192 316339304 120276888 73% /freebox/AllPG';
foreach (@partitions_working){
@@ -11635,9 +12961,10 @@ sub partition_data {
#print "$_\n";
}
}
+
my @row = split /\s+/, $_;
# autofs is a bsd thing, has size 0
- if ($row[0] =~ /$filters/ || $row[0] =~ /^ROOT/i ||
+ if ($row[0] =~ /^($filters)$/ || $row[0] =~ /^ROOT/i ||
($b_fs && ($row[2] == 0 || $row[1] =~ /^(autofs|iso9660|tmpfs)$/ ) )){
next;
}
@@ -11717,7 +13044,6 @@ sub partition_data {
}
}
$id = join ' ', @row[$cols .. $#row];
- $id =~ s/\/home\/[^\/]+\/(.*)/\/home\/$filter_string\/$1/ if $show{'filter'};
$size = $row[$cols - $back_size];
if ($b_admin && -e "/sys/block/"){
@working = admin_data($blockdev,$dev_base,$size);
@@ -11766,18 +13092,24 @@ sub partition_data {
}
@data = swap_data();
@partitions = (@partitions,@data);
+ # print Data::Dumper::Dumper \@partitions if $test[16];
if (!$bsd_type && @lsblk){
@data = check_partition_data();
@partitions = (@partitions,@data) if @data;
}
main::log_data('dump','@partitions',\@partitions) if $b_log;
- # print Data::Dumper::Dumper \@partitions;
+ print Data::Dumper::Dumper \@partitions if $test[16];
eval $end if $b_log;
}
sub swap_data {
eval $start if $b_log;
- my (@swap,@working,$cache_pressure,$path,$label,$swappiness,$uuid);
+ return @swaps if $b_swaps;
+ $b_swaps = 1;
+ my (@data,@working);
+ my ($cache_pressure,$dev_base,$dev_type,$label,$mount,$path,
+ $pattern1,$pattern2,$percent_used,$priority,$size,$swap_type,
+ $swappiness,$used,$uuid);
my ($s,$j,$size_id,$used_id) = (1,0,2,3);
if (!$bsd_type){
# faster, avoid subshell, same as swapon -s
@@ -11790,10 +13122,12 @@ sub swap_data {
@working = main::grabber("$path -s 2>/dev/null");
}
if ($b_admin){
- my @data = swap_advanced_data();
+ @data = swap_advanced_data();
$swappiness = $data[0];
$cache_pressure = $data[1];
}
+ $pattern1 = 'partition|file|ram';
+ $pattern2 = '[^\s].*[^\s]';
}
else {
if ( $path = main::check_program('swapctl') ){
@@ -11801,32 +13135,57 @@ sub swap_data {
@working = main::grabber("$path -l -k 2>/dev/null");
}
($size_id,$used_id) = (1,2);
+ $pattern1 = '[0-9]+';
+ $pattern2 = '[^\s]+';
}
# now add the swap partition data, don't want to show swap files, just partitions,
# though this can include /dev/ramzswap0. Note: you can also use /proc/swaps for this
# data, it's the same exact output as swapon -s
foreach (@working){
- next if ! /^\/dev/ || /^\/dev\/(ramzwap|zram)/;
- my @data = split /\s+/, $_;
- my $dev_base = $data[0];
- $dev_base =~ s/^\/dev\///;
- my $dev_type = 'dev';
- my $size = $data[$size_id];
- my $used = $data[$used_id];
- my $percent_used = sprintf( "%.1f", ( $used/$size )*100 );
- if ($show{'label'} && @labels){
- $label = get_label($data[0]);
- }
- if ($show{'uuid'} && @uuids){
- $uuid = get_uuid($data[0]);
- }
- if ($bsd_type && @gpart && ($show{'label'} || $show{'uuid'} ) ){
- my @extra = get_bsd_label_uuid("$dev_base");
- if (@extra){
- $label = $extra[0];
- $uuid = $extra[1];
+ #next if ! /^\/dev/ || /^\/dev\/(ramzwap|zram)/;
+ next if /^(Device|Filename)/;
+ ($dev_base,$dev_type,$label,$mount,$priority,
+ $swap_type,$uuid) = ('','','','',undef,'partition','');
+ @data = split /\s+/, $_;
+ if (/^\/dev\/(compcache|ramzwap|zram)/i){
+ $swap_type = 'zram';
+ $dev_type = 'dev';
+ }
+ elsif ($data[1] && $data[1] eq 'ram'){
+ $swap_type = 'ram';
+ }
+ elsif (m|^/dev|){
+ $swap_type = 'partition';
+ $dev_base = $data[0];
+ $dev_base =~ s|^/dev/||;
+ if ($show{'label'} && @labels){
+ $label = get_label($data[0]);
+ }
+ if ($show{'uuid'} && @uuids){
+ $uuid = get_uuid($data[0]);
+ }
+ if ($bsd_type && @gpart && ($show{'label'} || $show{'uuid'} ) ){
+ my @extra = get_bsd_label_uuid("$dev_base");
+ if (@extra){
+ $label = $extra[0];
+ $uuid = $extra[1];
+ }
}
+ $dev_type = 'dev';
+ }
+ elsif ($data[1] && $data[1] eq 'file' || m|^/|){
+ $swap_type = 'file';
}
+ $priority = $data[-1] if !$bsd_type;
+ # swpaon -s: /dev/sdb1 partition 16383996 109608 -2
+ # swapctl -l -k: /dev/label/swap0.eli 524284 154092
+ # users could have space in swapfile name
+ if (/^($pattern2)\s+($pattern1)\s+/){
+ $mount = main::trimmer($1);
+ }
+ $size = $data[$size_id];
+ $used = $data[$used_id];
+ $percent_used = sprintf( "%.1f", ( $used/$size )*100 );
@data = ({
'cache-pressure' => $cache_pressure,
'dev-base' => $dev_base,
@@ -11834,22 +13193,27 @@ sub swap_data {
'fs' => 'swap',
'id' => "swap-$s",
'label' => $label,
+ 'mount' => $mount,
+ 'priority' => $priority,
'size' => $size,
'swappiness' => $swappiness,
'type' => 'main',
+ 'swap-type' => $swap_type,
'used' => $used,
'uuid' => $uuid,
'percent-used' => $percent_used,
});
- @swap = (@swap,@data);
+ @swaps = (@swaps,@data);
$s++;
}
+ main::log_data('dump','@swaps',\@swaps) if $b_log;
+ print Data::Dumper::Dumper \@swaps if $test[15];;
eval $end if $b_log;
- return @swap;
+ return @swaps;
}
sub swap_advanced_data {
eval $start if $b_log;
- my ($swappiness,$cache_pressure) = ('','');
+ my ($swappiness,$cache_pressure) = (undef,undef);
if (-r "/proc/sys/vm/swappiness"){
$swappiness = (main::reader("/proc/sys/vm/swappiness"))[0];
if (defined $swappiness){
@@ -11991,12 +13355,16 @@ sub check_lsblk {
sub check_partition_data {
eval $start if $b_log;
my ($b_found,@data,@temp);
+ # NOTE: these filters must match the fs filters in the main partition data sub!!
+ my $fs_filters = 'aufs|cgmfs|configfs|devfs|devtmpfs|';
+ $fs_filters .= 'fdescfs|linprocfs|procfs|squashfs|swap|';
+ $fs_filters .= 'sysfs|tmpfs|unionfs';
foreach my $ref (@lsblk){
my %row = %$ref;
$b_found = 0;
- if (!$row{'name'} || !$row{'mount'} ||
- (!$row{'type'} || $row{'type'} eq 'disk' || $row{'type'} eq 'rom' ) ||
- ($row{'fs'} && $row{'fs'} eq 'swap') ){
+ if (!$row{'name'} || !$row{'mount'} || !$row{'type'} ||
+ ($row{'fs'} && $row{'fs'} =~ /^($fs_filters)$/) ||
+ ($row{'type'} =~ /^(disk|loop|rom)$/)){
next;
}
#print "$row{'name'} $row{'mount'}\n";
@@ -12143,6 +13511,7 @@ package ProcessData;
sub get {
eval $start if $b_log;
+ my $num = 0;
my (@processes,@rows);
if (@ps_aux){
if ($show{'ps-cpu'}){
@@ -12157,12 +13526,12 @@ sub get {
else {
my $key = 'Message';
@rows = ({
- main::key(1,$key) => main::row_defaults('ps-data-null',''),
+ main::key($num++,0,1,$key) => main::row_defaults('ps-data-null',''),
},);
@processes = (@processes,@rows);
}
- return @processes;
eval $end if $b_log;
+ return @processes;
}
sub cpu_processes {
eval $start if $b_log;
@@ -12189,7 +13558,7 @@ sub cpu_processes {
#my $header = "CPU % used - Command - pid$cpu_mem - top";
#my $header = "Top $count by CPU";
my @data = ({
- main::key($num++,'CPU top') => "$count$throttled",
+ main::key($num++,1,1,'CPU top') => "$count$throttled" . ' of ' . scalar @ps_aux,
},);
@processes = (@processes,@data);
my $i = 1;
@@ -12200,21 +13569,21 @@ sub cpu_processes {
my @command = process_starter(scalar @row, $row[$ps_cols],$row[$ps_cols + 1]);
$cpu = ($ps_cols >= 10 ) ? $row[2] . '%': 'N/A';
@data = ({
- main::key($num++,$i++) => '',
- main::key($num++,'cpu') => $cpu,
- main::key($num++,'command') => $command[0],
+ main::key($num++,1,2,$i++) => '',
+ main::key($num++,0,3,'cpu') => $cpu,
+ main::key($num++,1,3,'command') => $command[0],
},);
@processes = (@processes,@data);
if ($command[1]) {
- $processes[$j]{main::key($num++,'started by')} = $command[1];
+ $processes[$j]{main::key($num++,0,4,'started by')} = $command[1];
}
$pid = (defined $pid_col)? $row[$pid_col] : 'N/A';
- $processes[$j]{main::key($num++,'pid')} = $pid;
+ $processes[$j]{main::key($num++,0,3,'pid')} = $pid;
if ($extra > 0 && $ps_cols >= 10){
my $decimals = ($row[5]/1024 > 10 ) ? 1 : 2;
$mem = (defined $row[5]) ? sprintf( "%.${decimals}f", $row[5]/1024 ) . ' MiB' : 'N/A';
$mem .= ' (' . $row[3] . '%)';
- $processes[$j]{main::key($num++,'mem')} = $mem;
+ $processes[$j]{main::key($num++,0,3,'mem')} = $mem;
}
#print Data::Dumper::Dumper \@processes, "i: $i; j: $j ";
}
@@ -12247,7 +13616,7 @@ sub mem_processes {
#my $header = "Memory MiB/% used - Command - pid$cpu_mem - top";
#my $header = "Top $count by Memory";
@data = ({
- main::key($num++,'Memory top') => "$count$throttled",
+ main::key($num++,1,1,'Memory top') => "$count$throttled" . ' of ' . scalar @ps_aux,
},);
@processes = (@processes,@data);
my $i = 1;
@@ -12265,19 +13634,19 @@ sub mem_processes {
}
my @command = process_starter(scalar @row, $row[$ps_cols],$row[$ps_cols + 1]);
@data = ({
- main::key($num++,$i++) => '',
- main::key($num++,'mem') => $mem,
- main::key($num++,'command') => $command[0],
+ main::key($num++,1,2,$i++) => '',
+ main::key($num++,0,3,'mem') => $mem,
+ main::key($num++,1,3,'command') => $command[0],
},);
@processes = (@processes,@data);
if ($command[1]) {
- $processes[$j]{main::key($num++,'started by')} = $command[1];
+ $processes[$j]{main::key($num++,0,4,'started by')} = $command[1];
}
$pid = (defined $pid_col)? $row[$pid_col] : 'N/A';
- $processes[$j]{main::key($num++,'pid')} = $pid;
+ $processes[$j]{main::key($num++,0,3,'pid')} = $pid;
if ($extra > 0 && $ps_cols >= 10){
$cpu = $row[2] . '%';
- $processes[$j]{main::key($num++,'cpu')} = $cpu;
+ $processes[$j]{main::key($num++,0,3,'cpu')} = $cpu;
}
#print Data::Dumper::Dumper \@processes, "i: $i; j: $j ";
}
@@ -12305,7 +13674,7 @@ sub throttled {
my ($ps_count,$count,$j) = @_;
my $throttled = '';
if ($count > $j){
- $throttled = " ( $j processes)";
+ $throttled = " ( $j processes)"; # space to avoid emoji in irc
}
elsif ($count < $ps_count){
$throttled = " (throttled from $ps_count)";
@@ -12337,7 +13706,7 @@ sub get {
@rows = create_output();
}
if (!@rows && $key1){
- @rows = ({main::key($num++,$key1) => $val1,});
+ @rows = ({main::key($num++,0,1,$key1) => $val1,});
}
eval $end if $b_log;
($b_md,$b_zfs,@hardware_raid) = undef;
@@ -12350,7 +13719,7 @@ sub create_output {
my ($allocated,$available,$blocks_avail,$chunk_raid,$component_string,$raid,
$ref2,$ref3,$report_size,$size,$status);
my ($b_row_1_sizes);
- my ($i,$j,$num,$status_id) = (0,0,0,0);
+ my ($cont_arr,$i,$ind_arr,$j,$num,$status_id) = (2,0,3,0,0,0);
#print Data::Dumper::Dumper \@raid;
if (@hardware_raid){
foreach my $ref (@hardware_raid){
@@ -12359,35 +13728,35 @@ sub create_output {
my $device = ($row{'device'}) ? $row{'device'}: 'N/A';
my $driver = ($row{'driver'}) ? $row{'driver'}: 'N/A';
@data = ({
- main::key($num++,'Hardware') => $device,
+ main::key($num++,1,1,'Hardware') => $device,
});
@rows = (@rows,@data);
$j = scalar @rows - 1;
- $rows[$j]{main::key($num++,'vendor')} = $row{'vendor'} if $row{'vendor'};
- $rows[$j]{main::key($num++,'driver')} = $driver;
+ $rows[$j]{main::key($num++,0,2,'vendor')} = $row{'vendor'} if $row{'vendor'};
+ $rows[$j]{main::key($num++,1,2,'driver')} = $driver;
if ($extra > 0){
my $driver_version = ($row{'driver-version'}) ? $row{'driver-version'}: 'N/A' ;
- $rows[$j]{main::key($num++,'v')} = $driver_version;
+ $rows[$j]{main::key($num++,0,3,'v')} = $driver_version;
if ($extra > 2){
my $port= ($row{'port'}) ? $row{'port'}: 'N/A' ;
- $rows[$j]{main::key($num++,'port')} = $port;
+ $rows[$j]{main::key($num++,0,2,'port')} = $port;
}
my $bus_id = (defined $row{'bus-id'} && defined $row{'sub-id'}) ? "$row{'bus-id'}.$row{'sub-id'}": 'N/A' ;
- $rows[$j]{main::key($num++,'bus ID')} = $bus_id;
+ $rows[$j]{main::key($num++,0,2,'bus ID')} = $bus_id;
}
if ($extra > 1){
my $chip_id = (defined $row{'vendor-id'} && defined $row{'chip-id'}) ? "$row{'vendor-id'}.$row{'chip-id'}": 'N/A' ;
- $rows[$j]{main::key($num++,'chip ID')} = $chip_id;
+ $rows[$j]{main::key($num++,0,2,'chip ID')} = $chip_id;
}
if ($extra > 2){
my $rev= (defined $row{'rev'} && $row{'rev'}) ? $row{'rev'}: 'N/A' ;
- $rows[$j]{main::key($num++,'rev')} = $rev;
+ $rows[$j]{main::key($num++,0,2,'rev')} = $rev;
}
}
}
if ($extra > 2 && $raid[0]{'system-supported'}){
@data = ({
- main::key($num++,'Supported md-raid types') => $raid[0]{'system-supported'},
+ main::key($num++,0,1,'Supported md-raid types') => $raid[0]{'system-supported'},
});
@rows = (@rows,@data);
}
@@ -12398,9 +13767,9 @@ sub create_output {
next if !%row;
$num = 1;
@data = ({
- main::key($num++,'Device') => $row{'id'},
- main::key($num++,'type') => $row{'type'},
- main::key($num++,'status') => $row{'status'},
+ main::key($num++,1,1,'Device') => $row{'id'},
+ main::key($num++,0,2,'type') => $row{'type'},
+ main::key($num++,0,2,'status') => $row{'status'},
});
@rows = (@rows,@data);
if ($row{'type'} eq 'mdraid'){
@@ -12435,28 +13804,30 @@ sub create_output {
@arrays_holder = @arrays;
if (($row{'type'} eq 'mdraid' && $extra == 0 ) || !defined $arrays[0]{'raid'} ){
$raid = (defined $arrays[0]{'raid'}) ? $arrays[0]{'raid'}: 'no-raid';
- $rows[$j]{main::key($num++,'raid')} = $raid;
+ $rows[$j]{main::key($num++,0,2,'raid')} = $raid;
}
if ( ( $row{'type'} eq 'zfs' || ($row{'type'} eq 'mdraid' && $extra == 0 ) ) && $size){
#print "here 0\n";
- $rows[$j]{main::key($num++,$report_size)} = $size;
+ $rows[$j]{main::key($num++,0,2,$report_size)} = $size;
$size = '';
$b_row_1_sizes = 1;
}
if ( $row{'type'} eq 'zfs' && $available){
- $rows[$j]{main::key($num++,$blocks_avail)} = $available;
+ $rows[$j]{main::key($num++,0,2,$blocks_avail)} = $available;
$available = '';
$b_row_1_sizes = 1;
}
if ( $row{'type'} eq 'zfs' && $allocated){
- $rows[$j]{main::key($num++,$chunk_raid)} = $allocated;
+ $rows[$j]{main::key($num++,0,2,$chunk_raid)} = $allocated;
$allocated = '';
}
$i = 0;
my $count = scalar @arrays;
foreach $ref3 (@arrays){
my %row2 = %$ref3;
+ ($cont_arr,$ind_arr) = (2,3);
if ($count > 1){
+ ($cont_arr,$ind_arr) = (3,4);
$j = scalar @rows;
$num = 1;
@sizes = ($row2{'size'}) ? main::get_size($row2{'size'}) : ();
@@ -12466,10 +13837,10 @@ sub create_output {
$raid = (defined $row2{'raid'}) ? $row2{'raid'}: 'no-raid';
$status = ($row2{'status'}) ? $row2{'status'}: 'N/A';
@data = ({
- main::key($num++,'array') => $raid,
- main::key($num++,'status') => $status,
- main::key($num++,'size') => $size,
- main::key($num++,'free') => $available,
+ main::key($num++,1,2,'Array') => $raid,
+ main::key($num++,0,3,'status') => $status,
+ main::key($num++,0,3,'size') => $size,
+ main::key($num++,0,3,'free') => $available,
});
@rows = (@rows,@data);
}
@@ -12480,13 +13851,13 @@ sub create_output {
$size = (@sizes) ? "$sizes[0] $sizes[1]" : '';
@sizes = ($row2{'free'}) ? main::get_size($row2{'free'}) : ();
$available = (@sizes) ? "$sizes[0] $sizes[1]" : '';
- $rows[$j]{main::key($num++,'size')} = $size;
- $rows[$j]{main::key($num++,'free')} = $available;
+ $rows[$j]{main::key($num++,0,2,'size')} = $size;
+ $rows[$j]{main::key($num++,0,2,'free')} = $available;
if ($extra > 2){
@sizes = ($row{'allocated'}) ? main::get_size($row2{'allocated'}) : ();
$allocated = (@sizes) ? "$sizes[0] $sizes[1]" : '';
if ($allocated){
- $rows[$j]{main::key($num++,$chunk_raid)} = $allocated;
+ $rows[$j]{main::key($num++,0,2,$chunk_raid)} = $allocated;
}
}
}
@@ -12512,36 +13883,36 @@ sub create_output {
}
}
$component_string = (@components_good) ? join ' ', @components_good : 'N/A';
- $rows[$j]{main::key($num++,'Components')} = '';
- $rows[$j]{main::key($num++,'online')} = $component_string;
+ $rows[$j]{main::key($num++,1,$cont_arr,'Components')} = '';
+ $rows[$j]{main::key($num++,0,$ind_arr,'online')} = $component_string;
if (@failed){
- $rows[$j]{main::key($num++,'FAILED')} = join ' ', @failed;
+ $rows[$j]{main::key($num++,0,$ind_arr,'FAILED')} = join ' ', @failed;
}
if (@spare){
- $rows[$j]{main::key($num++,'spare')} = join ' ', @spare;
+ $rows[$j]{main::key($num++,0,$ind_arr,'spare')} = join ' ', @spare;
}
if ($row{'type'} eq 'mdraid' && $extra > 0 ){
$j = scalar @rows;
$num = 1;
#print Data::Dumper::Dumper \@arrays_holder;
- $rows[$j]{main::key($num++,'Info')} = '';
+ $rows[$j]{main::key($num++,1,$cont_arr,'Info')} = '';
$raid = (defined $arrays_holder[0]{'raid'}) ? $arrays_holder[0]{'raid'}: 'no-raid';
- $rows[$j]{main::key($num++,'raid')} = $raid;
- $rows[$j]{main::key($num++,$blocks_avail)} = $available;
+ $rows[$j]{main::key($num++,0,$ind_arr,'raid')} = $raid;
+ $rows[$j]{main::key($num++,0,$ind_arr,$blocks_avail)} = $available;
if ($size){
- $rows[$j]{main::key($num++,$report_size)} = $size;
+ $rows[$j]{main::key($num++,0,$ind_arr,$report_size)} = $size;
}
my $chunk = ($row{'chunk-size'}) ? $row{'chunk-size'}: 'N/A';
- $rows[$j]{main::key($num++,$chunk_raid)} = $chunk;
+ $rows[$j]{main::key($num++,0,$ind_arr,$chunk_raid)} = $chunk;
if ($extra > 1){
if ($row{'bitmap'}){
- $rows[$j]{main::key($num++,'bitmap')} = $row{'bitmap'};
+ $rows[$j]{main::key($num++,0,$ind_arr,'bitmap')} = $row{'bitmap'};
}
if ($row{'super-block'}){
- $rows[$j]{main::key($num++,'super blocks')} = $row{'super-block'};
+ $rows[$j]{main::key($num++,0,$ind_arr,'super blocks')} = $row{'super-block'};
}
if ($row{'algorithm'}){
- $rows[$j]{main::key($num++,'algorithm')} = $row{'algorithm'};
+ $rows[$j]{main::key($num++,0,$ind_arr,'algorithm')} = $row{'algorithm'};
}
}
}
@@ -12554,16 +13925,16 @@ sub create_output {
if ($extra > 1 && $row{'progress-bar'}){
$percent .= " $row{'progress-bar'}"
}
- $rows[$j]{main::key($num++,'Recovering')} = $percent;
+ $rows[$j]{main::key($num++,1,$cont_arr,'Recovering')} = $percent;
my $finish = ($row{'recovery-finish'})?$row{'recovery-finish'} : 'N/A';
- $rows[$j]{main::key($num++,'time remaining')} = $finish;
+ $rows[$j]{main::key($num++,0,$ind_arr,'time remaining')} = $finish;
if ($extra > 0){
if ($row{'sectors-recovered'}){
- $rows[$j]{main::key($num++,'sectors')} = $row{'sectors-recovered'};
+ $rows[$j]{main::key($num++,0,$ind_arr,'sectors')} = $row{'sectors-recovered'};
}
}
if ($extra > 1 && $row{'recovery-speed'}){
- $rows[$j]{main::key($num++,'speed')} = $row{'recovery-speed'};
+ $rows[$j]{main::key($num++,0,$ind_arr,'speed')} = $row{'recovery-speed'};
}
}
}
@@ -12638,7 +14009,7 @@ sub mdraid_data {
#$mdstat = "$ENV{'HOME'}/bin/scripts/inxi/data/raid/md-rebuild-1.txt";
#$mdstat = "$ENV{'HOME'}/bin/scripts/inxi/data/raid/md-2-mirror-fserver2-1.txt";
#$mdstat = "$ENV{'HOME'}/bin/scripts/inxi/data/raid/md-2-raid10-abucodonosor.txt";
- # $mdstat = "$ENV{'HOME'}/bin/scripts/inxi/data/raid/md-2-raid10-ant.txt";
+ #$mdstat = "$ENV{'HOME'}/bin/scripts/inxi/data/raid/md-2-raid10-ant.txt";
my @working = main::reader($mdstat,'strip');
#print Data::Dumper::Dumper \@working;
my (@data,@mdraid,@temp,$b_found,$system,$unused);
@@ -12932,8 +14303,8 @@ sub get {
$key1 = $$ref{'action'};
$val1 = $$ref{$key1};
@data = ({
- main::key($num++,'RAM Report') => '',
- main::key($num++,$key1) => $val1,
+ main::key($num++,1,1,'RAM Report') => '',
+ main::key($num++,0,2,$key1) => $val1,
});
@rows = (@rows,@data);
}
@@ -12946,8 +14317,8 @@ sub get {
$key1 = 'message';
$val1 = main::row_defaults('ram-data');
@data = ({
- main::key($num++,'RAM Report') => '',
- main::key($num++,$key1) => $val1,
+ main::key($num++,1,1,'RAM Report') => '',
+ main::key($num++,0,2,$key1) => $val1,
});
}
@rows = (@rows,@data);
@@ -12971,22 +14342,22 @@ sub create_output {
$b_non_system = ($ref{'use'} && lc($ref{'use'}) ne 'system memory') ? 1:0 ;
$num = 1;
@data = ({
- main::key($num++,'Array') => '',
- main::key($num++,'capacity') => process_size($ref{'capacity'}),
+ main::key($num++,1,1,'Array') => '',
+ main::key($num++,1,2,'capacity') => process_size($ref{'capacity'}),
});
@rows = (@rows,@data);
if ($ref{'cap-qualifier'}){
- $rows[$j]{main::key($num++,'note')} = $ref{'cap-qualifier'};
+ $rows[$j]{main::key($num++,0,3,'note')} = $ref{'cap-qualifier'};
}
- $rows[$j]{main::key($num++,'use')} = $ref{'use'} if $b_non_system;
- $rows[$j]{main::key($num++,'slots')} = $ref{'slots'};
+ $rows[$j]{main::key($num++,0,2,'use')} = $ref{'use'} if $b_non_system;
+ $rows[$j]{main::key($num++,0,2,'slots')} = $ref{'slots'};
$ref{'eec'} ||= 'N/A';
- $rows[$j]{main::key($num++,'EC')} = $ref{'eec'};
+ $rows[$j]{main::key($num++,0,2,'EC')} = $ref{'eec'};
if ($extra > 0 && (!$b_non_system ||
( main::is_numeric($ref{'max-module-size'}) && $ref{'max-module-size'} > 10 ) ) ){
- $rows[$j]{main::key($num++,'max module size')} = process_size($ref{'max-module-size'});
+ $rows[$j]{main::key($num++,1,2,'max module size')} = process_size($ref{'max-module-size'});
if ($ref{'mod-qualifier'}){
- $rows[$j]{main::key($num++,'note')} = $ref{'mod-qualifier'};
+ $rows[$j]{main::key($num++,0,3,'note')} = $ref{'mod-qualifier'};
}
}
}
@@ -13012,38 +14383,38 @@ sub create_output {
next if ($show{'ram-modules'} && $mod{'size'} =~ /\D/);
$mod{'locator'} ||= 'N/A';
@data = ({
- main::key($num++,'Device') => $mod{'locator'},
- main::key($num++,'size') => process_size($mod{'size'}),
+ main::key($num++,1,2,'Device') => $mod{'locator'},
+ main::key($num++,0,3,'size') => process_size($mod{'size'}),
});
@rows = (@rows,@data);
next if ($mod{'size'} =~ /\D/);
if ($extra > 1 && $mod{'type'} ){
- $rows[$j]{main::key($num++,'info')} = $mod{'type'};
+ $rows[$j]{main::key($num++,0,3,'info')} = $mod{'type'};
}
- $rows[$j]{main::key($num++,'speed')} = $mod{'speed'};
+ $rows[$j]{main::key($num++,0,3,'speed')} = $mod{'speed'};
if ($extra > 0 ){
$mod{'device-type'} ||= 'N/A';
- $rows[$j]{main::key($num++,'type')} = $mod{'device-type'};
+ $rows[$j]{main::key($num++,0,3,'type')} = $mod{'device-type'};
if ($extra > 2 && $mod{'device-type'} ne 'N/A'){
$mod{'device-type-detail'} ||= 'N/A';
- $rows[$j]{main::key($num++,'detail')} = $mod{'device-type-detail'};
+ $rows[$j]{main::key($num++,0,3,'detail')} = $mod{'device-type-detail'};
}
}
if ($extra > 2 ){
$mod{'data-width'} ||= 'N/A';
- $rows[$j]{main::key($num++,'bus width')} = $mod{'data-width'};
+ $rows[$j]{main::key($num++,0,3,'bus width')} = $mod{'data-width'};
$mod{'total-width'} ||= 'N/A';
- $rows[$j]{main::key($num++,'total')} = $mod{'total-width'};
+ $rows[$j]{main::key($num++,0,3,'total')} = $mod{'total-width'};
}
if ($extra > 1 ){
$mod{'manufacturer'} ||= 'N/A';
- $rows[$j]{main::key($num++,'manufacturer')} = $mod{'manufacturer'};
+ $rows[$j]{main::key($num++,0,3,'manufacturer')} = $mod{'manufacturer'};
$mod{'part-number'} ||= 'N/A';
- $rows[$j]{main::key($num++,'part-no')} = $mod{'part-number'};
+ $rows[$j]{main::key($num++,0,3,'part-no')} = $mod{'part-number'};
}
if ($extra > 2 ){
$mod{'serial'} = main::apply_filter($mod{'serial'});
- $rows[$j]{main::key($num++,'serial')} = $mod{'serial'};
+ $rows[$j]{main::key($num++,0,3,'serial')} = $mod{'serial'};
}
}
}
@@ -13052,11 +14423,11 @@ sub create_output {
$num = 1;
$type_holder ||= 'N/A';
@data = ({
- main::key($num++,'Report') => '',
- main::key($num++,'arrays') => $arrays,
- main::key($num++,'slots') => $slots,
- main::key($num++,'modules') => $modules,
- main::key($num++,'type') => $type_holder,
+ main::key($num++,1,1,'Report') => '',
+ main::key($num++,0,2,'arrays') => $arrays,
+ main::key($num++,0,2,'slots') => $slots,
+ main::key($num++,0,2,'modules') => $modules,
+ main::key($num++,0,2,'type') => $type_holder,
});
@rows = (@rows,@data);
}
@@ -13514,12 +14885,21 @@ my $num = 0;
sub get {
eval $start if $b_log;
($debugger_dir) = @_;
- my (@data,@rows);
+ my (@data,@rows,@rows_p,@rows_r);
+ if ($extra > 0 && !$b_pkg){
+ my %packages = PackageData::get('main',\$num);
+ my @data;
+ for (keys %packages){
+ $rows_p[0]{$_} = $packages{$_};
+ }
+ $b_pkg = 1;
+ }
+ $num = 0;
if ($bsd_type){
- @rows = get_repos_bsd();
+ @rows_r = get_repos_bsd();
}
else {
- @rows = get_repos_linux();
+ @rows_r = get_repos_linux();
}
if ($debugger_dir){
@rows = @dbg_files;
@@ -13527,13 +14907,13 @@ sub get {
undef $debugger_dir;
}
else {
- if (!@rows){
+ if (!@rows_r){
my $pm = (!$bsd_type) ? 'package manager': 'OS type';
@data = (
- {main::key($num++,'Alert') => "No repo data detected. Does $self_name support your $pm?"},
+ {main::key($num++,0,1,'Alert') => "No repo data detected. Does $self_name support your $pm?"},
);
- @rows = (@data);
}
+ @rows = (@rows_p,@rows_r,@data);
}
eval $end if $b_log;
return @rows;
@@ -13657,7 +15037,7 @@ sub get_repos_linux {
$key = repo_data('missing','apt');
}
@data = (
- {main::key($num++,$key) => $file},
+ {main::key($num++,1,1,$key) => $file},
[@apt_urls],
);
@rows = (@rows,@data);
@@ -13694,7 +15074,7 @@ sub get_repos_linux {
# set it so the debugger knows the file wasn't there
push @dbg_files, $_ if $debugger_dir;
@data = (
- {main::key($num++,'File listed in') => $pacman},
+ {main::key($num++,1,1,'File listed in') => $pacman},
[("$_ does not seem to exist.")],
);
@rows = (@rows,@data);
@@ -13702,7 +15082,7 @@ sub get_repos_linux {
}
if (!@rows){
@data = (
- {main::key($num++,repo_data('missing','files')) => $pacman },
+ {main::key($num++,0,1,repo_data('missing','files')) => $pacman },
);
@rows = (@rows,@data);
}
@@ -13752,7 +15132,7 @@ sub get_repos_linux {
$key = repo_data('active','slackpkg+');
}
@data = (
- {main::key($num++,$key) => $slackpkg_plus},
+ {main::key($num++,1,1,$key) => $slackpkg_plus},
[@content],
);
@data = url_cleaner(@data);
@@ -13800,8 +15180,10 @@ sub get_repos_linux {
$url = $2;
}
# note: enabled = 1. enabled = 0 means disabled
- elsif ($line =~ /^enabled\s*=\s*([01])/i){
+ elsif ($line =~ /^enabled\s*=\s*(0|1|No|Yes|True|False)/i){
$enabled = $1;
+ $enabled =~ s/(No|False)/0/i;
+ $enabled =~ s/(Yes|True)/1/i;
}
# print out the line if all 3 values are found, otherwise if a new
# repoTitle is hit above, it will print out the line there instead
@@ -13824,7 +15206,7 @@ sub get_repos_linux {
$key = repo_data('active',$repo);
}
@data = (
- {main::key($num++,$key) => $_},
+ {main::key($num++,1,1,$key) => $_},
[@content],
);
@rows = (@rows,@data);
@@ -13862,10 +15244,10 @@ sub get_repos_linux {
$url = $2;
}
# note: enabled = 1. enabled = 0 means disabled
- elsif ($line =~ /^auto-sync\s*=\s*(0|1|No|Yes)/i){
+ elsif ($line =~ /^auto-sync\s*=\s*(0|1|No|Yes|True|False)/i){
$enabled = $1;
- $enabled =~ s/No/0/;
- $enabled =~ s/Yes/1/;
+ $enabled =~ s/(No|False)/0/i;
+ $enabled =~ s/(Yes|True)/1/i;
}
# print out the line if all 3 values are found, otherwise if a new
# repoTitle is hit above, it will print out the line there instead
@@ -13888,7 +15270,7 @@ sub get_repos_linux {
$key = repo_data('active','portage');
}
@data = (
- {main::key($num++,$key) => $_},
+ {main::key($num++,1,1,$key) => $_},
[@content],
);
@rows = (@rows,@data);
@@ -13919,7 +15301,7 @@ sub get_repos_linux {
$key = repo_data('active','cards');
}
@data = (
- {main::key($num++,$key) => $cards},
+ {main::key($num++,1,1,$key) => $cards},
[@content],
);
@rows = (@rows,@data);
@@ -13971,7 +15353,7 @@ sub get_repos_linux {
# get the repo
$repo = $2;
@data = (
- {main::key($num++,'urpmq repo') => $repo},
+ {main::key($num++,1,1,'urpmq repo') => $repo},
[@content],
);
@rows = (@rows,@data);
@@ -14017,7 +15399,7 @@ sub get_repos_linux {
@content = url_cleaner(@content);
$key = repo_data('active',$which);
@data = (
- {main::key($num++,$key) => $repo},
+ {main::key($num++,1,1,$key) => $repo},
[@content],
);
@rows = (@rows,@data);
@@ -14030,7 +15412,7 @@ sub get_repos_linux {
@content = url_cleaner(@content);
$key = repo_data('active',$which);
@data = (
- {main::key($num++,$key) => $repo},
+ {main::key($num++,1,1,$key) => $repo},
[@content],
);
@rows = (@rows,@data);
@@ -14103,7 +15485,7 @@ sub get_repos_bsd {
$key = repo_data('active','bsd-package');
}
@data = (
- {main::key($num++,$key) => $_},
+ {main::key($num++,1,1,$key) => $_},
[@data3],
);
@rows = (@rows,@data);
@@ -14143,7 +15525,7 @@ sub get_repos_bsd {
$key = repo_data('missing','bsd-files');
}
@data = (
- {main::key($num++,'Message') => $key},
+ {main::key($num++,0,1,'Message') => $key},
[()],
);
@rows = (@rows,@data);
@@ -14230,7 +15612,7 @@ sub repo_builder {
@content = url_cleaner(@content);
}
@data = (
- {main::key($num++,$key) => $file},
+ {main::key($num++,1,1,$key) => $file},
[@content],
);
eval $end if $b_log;
@@ -14262,7 +15644,6 @@ sub file_path {
## SensorData
{
package SensorData;
-my (@sensors_data);
my ($b_ipmi) = (0);
sub get {
eval $start if $b_log;
@@ -14282,7 +15663,7 @@ sub get {
$key1 = 'Message';
$val1 = main::row_defaults('sensors-data-ipmi');
#$val1 = main::row_defaults('dev');
- @data = ({main::key($num++,$key1) => $val1,});
+ @data = ({main::key($num++,0,1,$key1) => $val1,});
}
@rows = (@rows,@data);
$source = 'lm-sensors'; # trips per sensor type output
@@ -14290,7 +15671,7 @@ sub get {
else {
$key1 = 'Permissions';
$val1 = main::row_defaults('sensors-ipmi-root');
- @data = ({main::key($num++,$key1) => $val1,});
+ @data = ({main::key($num++,0,1,$key1) => $val1,});
@rows = (@rows,@data);
}
}
@@ -14300,7 +15681,7 @@ sub get {
$key1 = $$ref{'action'};
$val1 = $$ref{$key1};
$key1 = ucfirst($key1);
- @data = ({main::key($num++,$key1) => $val1,});
+ @data = ({main::key($num++,0,1,$key1) => $val1,});
@rows = (@rows,@data);
}
else {
@@ -14310,11 +15691,10 @@ sub get {
if (!@data) {
$key1 = 'Message';
$val1 = main::row_defaults('sensors-data-linux');
- @data = ({main::key($num++,$key1) => $val1,});
+ @data = ({main::key($num++,0,1,$key1) => $val1,});
}
@rows = (@rows,@data);
}
- undef @sensors_data;
eval $end if $b_log;
return @rows;
}
@@ -14335,38 +15715,41 @@ sub create_output {
my $cpu1_key = ($sensors{'cpu2-temp'}) ? 'cpu-1': 'cpu' ;
$data_source = $source if ($source eq 'ipmi' || $source eq 'lm-sensors');
@data = ({
- main::key($num++,'System Temperatures') => $data_source,
- main::key($num++,$cpu1_key) => $cpu_temp,
+ main::key($num++,1,1,'System Temperatures') => $data_source,
+ main::key($num++,0,2,$cpu1_key) => $cpu_temp,
});
@rows = (@rows,@data);
if ($sensors{'cpu2-temp'}){
- $rows[$j]{main::key($num++,'cpu-2')} = $sensors{'cpu2-temp'} . $temp_unit;
+ $rows[$j]{main::key($num++,0,2,'cpu-2')} = $sensors{'cpu2-temp'} . $temp_unit;
}
if ($sensors{'cpu3-temp'}){
- $rows[$j]{main::key($num++,'cpu-3')} = $sensors{'cpu3-temp'} . $temp_unit;
+ $rows[$j]{main::key($num++,0,2,'cpu-3')} = $sensors{'cpu3-temp'} . $temp_unit;
}
if ($sensors{'cpu4-temp'}){
- $rows[$j]{main::key($num++,'cpu-4')} = $sensors{'cpu4-temp'} . $temp_unit;
+ $rows[$j]{main::key($num++,0,2,'cpu-4')} = $sensors{'cpu4-temp'} . $temp_unit;
}
- $rows[$j]{main::key($num++,'mobo')} = $mobo_temp;
+ $rows[$j]{main::key($num++,0,2,'mobo')} = $mobo_temp;
if (defined $sensors{'sodimm-temp'}){
my $sodimm_temp = $sensors{'sodimm-temp'} . $temp_unit;
- $rows[$j]{main::key($num++,'sodimm')} = $sodimm_temp;
+ $rows[$j]{main::key($num++,0,2,'sodimm')} = $sodimm_temp;
}
if (defined $sensors{'psu-temp'}){
my $psu_temp = $sensors{'psu-temp'} . $temp_unit;
- $rows[$j]{main::key($num++,'psu')} = $psu_temp;
+ $rows[$j]{main::key($num++,0,2,'psu')} = $psu_temp;
}
if (defined $sensors{'ambient-temp'}){
my $ambient_temp = $sensors{'ambient-temp'} . $temp_unit;
- $rows[$j]{main::key($num++,'ambient')} = $ambient_temp;
+ $rows[$j]{main::key($num++,0,2,'ambient')} = $ambient_temp;
}
if (scalar @gpu == 1 && defined $gpu[0]{'temp'}){
my $gpu_temp = $gpu[0]{'temp'};
my $gpu_type = $gpu[0]{'type'};
my $gpu_unit = (defined $gpu[0]{'temp-unit'} && $gpu_temp ) ? " $gpu[0]{'temp-unit'}" : ' C';
- $rows[$j]{main::key($num++,'gpu')} = $gpu_type;
- $rows[$j]{main::key($num++,'temp')} = $gpu_temp . $gpu_unit;
+ $rows[$j]{main::key($num++,1,2,'gpu')} = $gpu_type;
+ $rows[$j]{main::key($num++,0,3,'temp')} = $gpu_temp . $gpu_unit;
+ if ($extra > 1 && $gpu[0]{'temp-mem'}){
+ $rows[$j]{main::key($num++,0,3,'mem')} = $gpu[0]{'temp-mem'} . $gpu_unit;
+ }
}
$j = scalar @rows;
my $ref_main = $sensors{'fan-main'};
@@ -14377,49 +15760,49 @@ sub create_output {
if (!@fan_main && !@fan_default){
$fan_def = ($fan_def) ? "$data_source N/A" : 'N/A';
}
- $rows[$j]{main::key($num++,'Fan Speeds (RPM)')} = $fan_def;
+ $rows[$j]{main::key($num++,1,1,'Fan Speeds (RPM)')} = $fan_def;
my $b_cpu = 0;
for (my $i = 0; $i < scalar @fan_main; $i++){
next if $i == 0;# starts at 1, not 0
if (defined $fan_main[$i]){
if ($i == 1 || ($i == 2 && !$b_cpu )){
- $rows[$j]{main::key($num++,'cpu')} = $fan_main[$i];
+ $rows[$j]{main::key($num++,0,2,'cpu')} = $fan_main[$i];
$b_cpu = 1;
}
elsif ($i == 2 && $b_cpu){
- $rows[$j]{main::key($num++,'mobo')} = $fan_main[$i];
+ $rows[$j]{main::key($num++,0,2,'mobo')} = $fan_main[$i];
}
elsif ($i == 3){
- $rows[$j]{main::key($num++,'psu')} = $fan_main[$i];
+ $rows[$j]{main::key($num++,0,2,'psu')} = $fan_main[$i];
}
elsif ($i == 4){
- $rows[$j]{main::key($num++,'sodimm')} = $fan_main[$i];
+ $rows[$j]{main::key($num++,0,2,'sodimm')} = $fan_main[$i];
}
elsif ($i > 4){
$fan_number = $i - 4;
- $rows[$j]{main::key($num++,"case-$fan_number")} = $fan_main[$i];
+ $rows[$j]{main::key($num++,0,2,"case-$fan_number")} = $fan_main[$i];
}
}
}
for (my $i = 0; $i < scalar @fan_default; $i++){
next if $i == 0;# starts at 1, not 0
if (defined $fan_default[$i]){
- $rows[$j]{main::key($num++,"fan-$i")} = $fan_default[$i];
+ $rows[$j]{main::key($num++,0,2,"fan-$i")} = $fan_default[$i];
}
}
- $rows[$j]{main::key($num++,'psu')} = $sensors{'fan-psu'} if defined $sensors{'fan-psu'};
- $rows[$j]{main::key($num++,'psu-1')} = $sensors{'fan-psu1'} if defined $sensors{'fan-psu1'};
- $rows[$j]{main::key($num++,'psu-2')} = $sensors{'fan-psu2'} if defined $sensors{'fan-psu2'};
+ $rows[$j]{main::key($num++,0,2,'psu')} = $sensors{'fan-psu'} if defined $sensors{'fan-psu'};
+ $rows[$j]{main::key($num++,0,2,'psu-1')} = $sensors{'fan-psu1'} if defined $sensors{'fan-psu1'};
+ $rows[$j]{main::key($num++,0,2,'psu-2')} = $sensors{'fan-psu2'} if defined $sensors{'fan-psu2'};
# note: so far, only nvidia-settings returns speed, and that's in percent
if (scalar @gpu == 1 && defined $gpu[0]{'fan-speed'}){
my $gpu_fan = $gpu[0]{'fan-speed'} . $gpu[0]{'speed-unit'};
my $gpu_type = $gpu[0]{'type'};
- $rows[$j]{main::key($num++,'gpu')} = $gpu_type;
- $rows[$j]{main::key($num++,'fan')} = $gpu_fan;
+ $rows[$j]{main::key($num++,1,2,'gpu')} = $gpu_type;
+ $rows[$j]{main::key($num++,0,3,'fan')} = $gpu_fan;
}
if (scalar @gpu > 1){
$j = scalar @rows;
- $rows[$j]{main::key($num++,'GPU')} = '';
+ $rows[$j]{main::key($num++,1,1,'GPU')} = '';
my $gpu_unit = (defined $gpu[0]{'temp-unit'} ) ? " $gpu[0]{'temp-unit'}" : ' C';
foreach my $ref (@gpu){
my %info = %$ref;
@@ -14427,13 +15810,22 @@ sub create_output {
my $gpu_fan = (defined $info{'fan-speed'}) ? $info{'fan-speed'} . $info{'speed-unit'}: undef ;
my $gpu_type = $info{'type'};
my $gpu_temp = (defined $info{'temp'} ) ? $info{'temp'} . $gpu_unit: 'N/A';
- $rows[$j]{main::key($num++,'device')} = $gpu_type;
+ $rows[$j]{main::key($num++,1,2,'device')} = $gpu_type;
if (defined $info{'screen'} ){
- $rows[$j]{main::key($num++,'screen')} = $info{'screen'};
+ $rows[$j]{main::key($num++,0,3,'screen')} = $info{'screen'};
+ }
+ $rows[$j]{main::key($num++,0,3,'temp')} = $gpu_temp;
+ if ($extra > 1 && $info{'temp-mem'}){
+ $rows[$j]{main::key($num++,0,3,'mem')} = $info{'temp-mem'} . $gpu_unit;
}
- $rows[$j]{main::key($num++,'temp')} = $gpu_temp;
if (defined $gpu_fan){
- $rows[$j]{main::key($num++,'fan')} = $gpu_fan;
+ $rows[$j]{main::key($num++,0,3,'fan')} = $gpu_fan;
+ }
+ if ($extra > 2 && $info{'watts'}){
+ $rows[$j]{main::key($num++,0,3,'watts')} = $info{'watts'};
+ }
+ if ($extra > 2 && $info{'mvolts'}){
+ $rows[$j]{main::key($num++,0,3,'mV')} = $info{'mvolts'};
}
}
}
@@ -14444,18 +15836,23 @@ sub create_output {
$sensors{'volts-5'} ||= 'N/A';
$sensors{'volts-3.3'} ||= 'N/A';
$sensors{'volts-vbat'} ||= 'N/A';
- $rows[$j]{main::key($num++,'Voltages')} = $data_source;
- $rows[$j]{main::key($num++,'12v')} = $sensors{'volts-12'};
- $rows[$j]{main::key($num++,'5v')} = $sensors{'volts-5'};
- $rows[$j]{main::key($num++,'3.3v')} = $sensors{'volts-3.3'};
- $rows[$j]{main::key($num++,'vbat')} = $sensors{'volts-vbat'};
+ $rows[$j]{main::key($num++,1,1,'Power')} = $data_source;
+ $rows[$j]{main::key($num++,0,2,'12v')} = $sensors{'volts-12'};
+ $rows[$j]{main::key($num++,0,2,'5v')} = $sensors{'volts-5'};
+ $rows[$j]{main::key($num++,0,2,'3.3v')} = $sensors{'volts-3.3'};
+ $rows[$j]{main::key($num++,0,2,'vbat')} = $sensors{'volts-vbat'};
if ($extra > 1 && $source eq 'ipmi' ){
$sensors{'volts-dimm-p1'} ||= 'N/A';
$sensors{'volts-dimm-p2'} ||= 'N/A';
- $rows[$j]{main::key($num++,'dimm-p1')} = $sensors{'volts-dimm-p1'} if $sensors{'volts-dimm-p1'};
- $rows[$j]{main::key($num++,'dimm-p2')} = $sensors{'volts-dimm-p2'} if $sensors{'volts-dimm-p2'};
- $rows[$j]{main::key($num++,'soc-p1')} = $sensors{'volts-soc-p1'} if $sensors{'volts-soc-p1'};
- $rows[$j]{main::key($num++,'soc-p2')} = $sensors{'volts-soc-p2'} if $sensors{'volts-soc-p2'};
+ $rows[$j]{main::key($num++,0,2,'dimm-p1')} = $sensors{'volts-dimm-p1'} if $sensors{'volts-dimm-p1'};
+ $rows[$j]{main::key($num++,0,2,'dimm-p2')} = $sensors{'volts-dimm-p2'} if $sensors{'volts-dimm-p2'};
+ $rows[$j]{main::key($num++,0,2,'soc-p1')} = $sensors{'volts-soc-p1'} if $sensors{'volts-soc-p1'};
+ $rows[$j]{main::key($num++,0,2,'soc-p2')} = $sensors{'volts-soc-p2'} if $sensors{'volts-soc-p2'};
+ }
+ if (scalar @gpu == 1 && $extra > 2 && ($gpu[0]{'watts'} || $gpu[0]{'mvolts'})){
+ $rows[$j]{main::key($num++,1,2,'gpu')} = $gpu[0]{'type'};
+ $rows[$j]{main::key($num++,0,3,'watts')} = $gpu[0]{'watts'} if $gpu[0]{'watts'} ;
+ $rows[$j]{main::key($num++,0,3,'mV')} = $gpu[0]{'mvolts'} if $gpu[0]{'mvolts'};
}
}
eval $end if $b_log;
@@ -14629,188 +16026,174 @@ sub ipmi_data {
sub lm_sensors_data {
eval $start if $b_log;
my (%sensors);
- my ($b_valid,$sys_fan_nu) = (0,0);
- my ($adapter,$fan_working,$temp_working,$working_unit) = ('','','','');
- @sensors_data = main::grabber(main::check_program('sensors') . " 2>/dev/null");
- #my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sensors/amdgpu-w-fan-speed-stretch-k10.txt";
- #my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sensors/peci-tin-geggo.txt";
- #my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sensors/sensors-w-other-biker.txt";
- #my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sensors/sensors-asus-chassis-1.txt";
- #my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sensors/sensors-devnull-1.txt";
- #my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sensors/sensors-jammin1.txt";
- # my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sensors/sensors-maximus-arch-1.txt";
- # @sensors_data = main::reader($file);
- # print join ("\n", @sensors_data), "\n";
- @sensors_data = map {$_ =~ s/\s*:\s*\+?/:/;$_} @sensors_data;
- foreach (@sensors_data){
- # we get this from gpu_data()
- if (/^(amdgpu|intel|nouveau|radeon|.*hwmon)-pci/){
- $b_valid = 0;
- $adapter = '';
- next;
- }
- if (/^(?:(?!amdgpu|intel|nouveau|radeon|.*hwmon).)*-(isa|pci|virtual)-/){
- $b_valid = 1;
- $adapter = $1;
+ my ($sys_fan_nu) = (0);
+ my ($adapter,$fan_working,$temp_working,$working_unit) = ('','','','','');
+ lm_sensors_processor() if !$b_sensors;
+ foreach $adapter (keys %{$sensors_raw{'main'}}){
+ next if !$adapter || ref $sensors_raw{'main'}->{$adapter} ne 'ARRAY';
+ # not sure why hwmon is excluded, forgot to add info in comments
+ if ((@sensors_use && !(grep {/$adapter/} @sensors_use)) ||
+ (@sensors_exclude && (grep {/$adapter/} @sensors_exclude))){
next;
}
- next if !$b_valid;
- my @working = split /:/, $_;
- next if !$working[0] || /^Adapter/;
- #print "$working[0]:$working[1]\n";
- # There are some guesses here, but with more sensors samples it will get closer.
- # note: using arrays starting at 1 for all fan arrays to make it easier overall
- # we have to be sure we are working with the actual real string before assigning
- # data to real variables and arrays. Extracting C/F degree unit as well to use
- # when constructing temp items for array.
- # note that because of charset issues, no "°" degree sign used, but it is required
- # in testing regex to avoid error. It might be because I got that data from a forum post,
- # note directly via debugger.
- if ($_ =~ /^(AMBIENT|M\/B|MB|Motherboard|SIO|SYS).*:([0-9\.]+)[\s°]*(C|F)/i) {
- # avoid SYSTIN: 118 C
- if (main::is_numeric($2) && $2 < 90 ){
- $sensors{'mobo-temp'} = $2;
+ foreach (@{$sensors_raw{'main'}->{$adapter}}){
+ my @working = split /:/, $_;
+ next if !$working[0];
+ #print "$working[0]:$working[1]\n";
+ # There are some guesses here, but with more sensors samples it will get closer.
+ # note: using arrays starting at 1 for all fan arrays to make it easier overall
+ # we have to be sure we are working with the actual real string before assigning
+ # data to real variables and arrays. Extracting C/F degree unit as well to use
+ # when constructing temp items for array.
+ # note that because of charset issues, no "°" degree sign used, but it is required
+ # in testing regex to avoid error. It might be because I got that data from a forum post,
+ # note directly via debugger.
+ if ($_ =~ /^(AMBIENT|M\/B|MB|Motherboard|SIO|SYS).*:([0-9\.]+)[\s°]*(C|F)/i) {
+ # avoid SYSTIN: 118 C
+ if (main::is_numeric($2) && $2 < 90 ){
+ $sensors{'mobo-temp'} = $2;
+ $working_unit = $3;
+ $sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
+ }
+ }
+ # issue 58 msi/asus show wrong for CPUTIN so overwrite it if PECI 0 is present
+ # http://www.spinics.net/lists/lm-sensors/msg37308.html
+ # NOTE: had: ^CPU.*\+([0-9]+): but that misses: CPUTIN and anything not with + in starter
+ # However, "CPUTIN is not a reliable measurement because it measures difference to Tjmax,
+ # which is the maximum CPU temperature reported as critical temperature by coretemp"
+ # NOTE: I've seen an inexplicable case where: CPU:52.0°C fails to match with [\s°] but
+ # does match with: [\s°]*. I can't account for this, but that's why the * is there
+ # Tdie is a new k10temp-pci syntax for cpu die temp
+ elsif ($_ =~ /^(CPU.*|Tdie.*):([0-9\.]+)[\s°]*(C|F)/i) {
+ $temp_working = $2;
$working_unit = $3;
+ if ( !$sensors{'cpu-temp'} ||
+ ( defined $temp_working && $temp_working > 0 && $temp_working > $sensors{'cpu-temp'} ) ) {
+ $sensors{'cpu-temp'} = $temp_working;
+ }
$sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
}
- }
- # issue 58 msi/asus show wrong for CPUTIN so overwrite it if PECI 0 is present
- # http://www.spinics.net/lists/lm-sensors/msg37308.html
- # NOTE: had: ^CPU.*\+([0-9]+): but that misses: CPUTIN and anything not with + in starter
- # However, "CPUTIN is not a reliable measurement because it measures difference to Tjmax,
- # which is the maximum CPU temperature reported as critical temperature by coretemp"
- # NOTE: I've seen an inexplicable case where: CPU:52.0°C fails to match with [\s°] but
- # does match with: [\s°]*. I can't account for this, but that's why the * is there
- # Tdie is a new k10temp-pci syntax for cpu die temp
- elsif ($_ =~ /^(CPU.*|Tdie.*):([0-9\.]+)[\s°]*(C|F)/i) {
- $temp_working = $2;
- $working_unit = $3;
- if ( !$sensors{'cpu-temp'} ||
- ( defined $temp_working && $temp_working > 0 && $temp_working > $sensors{'cpu-temp'} ) ) {
- $sensors{'cpu-temp'} = $temp_working;
- }
- $sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
- }
- elsif ($_ =~ /^PECI\sAgent\s0.*:([0-9\.]+)[\s°]*(C|F)/i) {
- $sensors{'cpu-peci-temp'} = $1;
- $working_unit = $2;
- $sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
- }
- elsif ($_ =~ /^(P\/S|Power).*:([0-9\.]+)[\s°]*(C|F)/i) {
- $sensors{'psu-temp'} = $2;
- $working_unit = $3;
- $sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
- }
- elsif ($_ =~ /^SODIMM.*:([0-9\.]+)[\s°]*(C|F)/i) {
- $sensors{'sodimm-temp'} = $1;
- $working_unit = $2;
- $sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
- }
- # for temp1/2 only use temp1/2 if they are null or greater than the last ones
- elsif ($_ =~ /^temp1:([0-9\.]+)[\s°]*(C|F)/i) {
- $temp_working = $1;
- $working_unit = $2;
- if ( !$sensors{'temp1'} ||
- ( defined $temp_working && $temp_working > 0 && $temp_working > $sensors{'temp1'} ) ) {
- $sensors{'temp1'} = $temp_working;
- }
- $sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
- }
- elsif ($_ =~ /^temp2:([0-9\.]+)[\s°]*(C|F)/i) {
- $temp_working = $1;
- $working_unit = $2;
- if ( !$sensors{'temp2'} ||
- ( defined $temp_working && $temp_working > 0 && $temp_working > $sensors{'temp2'} ) ) {
- $sensors{'temp2'} = $temp_working;
+ elsif ($_ =~ /^PECI\sAgent\s0.*:([0-9\.]+)[\s°]*(C|F)/i) {
+ $sensors{'cpu-peci-temp'} = $1;
+ $working_unit = $2;
+ $sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
}
- $sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
- }
- # temp3 is only used as an absolute override for systems with all 3 present
- elsif ($_ =~ /^temp3:([0-9\.]+)[\s°]*(C|F)/i) {
- $temp_working = $1;
- $working_unit = $2;
- if ( !$sensors{'temp3'} ||
- ( defined $temp_working && $temp_working > 0 && $temp_working > $sensors{'temp3'} ) ) {
- $sensors{'temp3'} = $temp_working;
+ elsif ($_ =~ /^(P\/S|Power).*:([0-9\.]+)[\s°]*(C|F)/i) {
+ $sensors{'psu-temp'} = $2;
+ $working_unit = $3;
+ $sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
}
- $sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
- }
- # final fallback if all else fails, funtoo user showed sensors putting
- # temp on wrapped second line, not handled
- elsif ($_ =~ /^(core0|core 0|Physical id 0)(.*):([0-9\.]+)[\s°]*(C|F)/i) {
- $temp_working = $3;
- $working_unit = $4;
- if ( !$sensors{'core-0-temp'} ||
- ( defined $temp_working && $temp_working > 0 && $temp_working > $sensors{'core-0-temp'} ) ) {
- $sensors{'core-0-temp'} = $temp_working;
+ elsif ($_ =~ /^SODIMM.*:([0-9\.]+)[\s°]*(C|F)/i) {
+ $sensors{'sodimm-temp'} = $1;
+ $working_unit = $2;
+ $sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
}
- $sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
- }
- # note: can be cpu fan:, cpu fan speed:, etc.
- elsif (!$sensors{'fan-main'}[1] && $_ =~ /^(CPU|Processor).*:([0-9]+)[\s]RPM/i) {
- $sensors{'fan-main'} = () if !$sensors{'fan-main'};
- $sensors{'fan-main'}[1] = $2;
- }
- elsif (!$sensors{'fan-main'}[2] && $_ =~ /^(M\/B|MB|SYS|Motherboard).*:([0-9]+)[\s]RPM/i) {
- $sensors{'fan-main'} = () if !$sensors{'fan-main'};
- $sensors{'fan-main'}[2] = $2;
- }
- elsif (!$sensors{'fan-main'}[3] && $_ =~ /(Power|P\/S|POWER).*:([0-9]+)[\s]RPM/i) {
- $sensors{'fan-main'} = () if !$sensors{'fan-main'};
- $sensors{'fan-main'}[3] = $2;
- }
- elsif (!$sensors{'fan-main'}[4] && $_ =~ /(SODIMM).*:([0-9]+)[\s]RPM/i) {
- $sensors{'fan-main'} = () if !$sensors{'fan-main'};
- $sensors{'fan-main'}[4] = $2;
- }
- # note that the counters are dynamically set for fan numbers here
- # otherwise you could overwrite eg aux fan2 with case fan2 in theory
- # note: cpu/mobo/ps/sodimm are 1/2/3/4
- elsif ($_ =~ /^(AUX|CASE|CHASSIS).*:([0-9]+)[\s]RPM/i) {
- $temp_working = $2;
- $sensors{'fan-main'} = () if !$sensors{'fan-main'};
- for ( my $i = 5; $i < 30; $i++ ){
- next if defined $sensors{'fan-main'}[$i];
- if ( !defined $sensors{'fan-main'}[$i] ){
- $sensors{'fan-main'}[$i] = $temp_working;
- last;
+ # for temp1/2 only use temp1/2 if they are null or greater than the last ones
+ elsif ($_ =~ /^temp1:([0-9\.]+)[\s°]*(C|F)/i) {
+ $temp_working = $1;
+ $working_unit = $2;
+ if ( !$sensors{'temp1'} ||
+ ( defined $temp_working && $temp_working > 0 && $temp_working > $sensors{'temp1'} ) ) {
+ $sensors{'temp1'} = $temp_working;
}
+ $sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
}
- }
- # in rare cases syntax is like: fan1: xxx RPM
- elsif ($_ =~ /^FAN(1)?:([0-9]+)[\s]RPM/i) {
- $sensors{'fan-default'} = () if !$sensors{'fan-default'};
- $sensors{'fan-default'}[1] = $2;
- }
- elsif ($_ =~ /^FAN([2-9]|1[0-9]).*:([0-9]+)[\s]RPM/i) {
- $fan_working = $2;
- $sys_fan_nu = $1;
- $sensors{'fan-default'} = () if !$sensors{'fan-default'};
- if ( $sys_fan_nu =~ /^([0-9]+)$/ ) {
- # add to array if array index does not exist OR if number is > existing number
- if ( defined $sensors{'fan-default'}[$sys_fan_nu] ) {
- if ( $fan_working >= $sensors{'fan-default'}[$sys_fan_nu] ) {
- $sensors{'fan-default'}[$sys_fan_nu] = $fan_working;
- }
+ elsif ($_ =~ /^temp2:([0-9\.]+)[\s°]*(C|F)/i) {
+ $temp_working = $1;
+ $working_unit = $2;
+ if ( !$sensors{'temp2'} ||
+ ( defined $temp_working && $temp_working > 0 && $temp_working > $sensors{'temp2'} ) ) {
+ $sensors{'temp2'} = $temp_working;
}
- else {
- $sensors{'fan-default'}[$sys_fan_nu] = $fan_working;
+ $sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
+ }
+ # temp3 is only used as an absolute override for systems with all 3 present
+ elsif ($_ =~ /^temp3:([0-9\.]+)[\s°]*(C|F)/i) {
+ $temp_working = $1;
+ $working_unit = $2;
+ if ( !$sensors{'temp3'} ||
+ ( defined $temp_working && $temp_working > 0 && $temp_working > $sensors{'temp3'} ) ) {
+ $sensors{'temp3'} = $temp_working;
}
+ $sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
}
- }
- if ($extra > 0){
- if ($_ =~ /^[+]?(12 Volt|12V).*:([0-9\.]+)\sV/i) {
- $sensors{'volts-12'} = $2;
+ # final fallback if all else fails, funtoo user showed sensors putting
+ # temp on wrapped second line, not handled
+ elsif ($_ =~ /^(core0|core 0|Physical id 0)(.*):([0-9\.]+)[\s°]*(C|F)/i) {
+ $temp_working = $3;
+ $working_unit = $4;
+ if ( !$sensors{'core-0-temp'} ||
+ ( defined $temp_working && $temp_working > 0 && $temp_working > $sensors{'core-0-temp'} ) ) {
+ $sensors{'core-0-temp'} = $temp_working;
+ }
+ $sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
}
- # note: 5VSB is a field name
- elsif ($_ =~ /^[+]?(5 Volt|5V):([0-9\.]+)\sV/i) {
- $sensors{'volts-5'} = $2;
+ # note: can be cpu fan:, cpu fan speed:, etc.
+ elsif (!$sensors{'fan-main'}[1] && $_ =~ /^(CPU|Processor).*:([0-9]+)[\s]RPM/i) {
+ $sensors{'fan-main'} = () if !$sensors{'fan-main'};
+ $sensors{'fan-main'}[1] = $2;
+ }
+ elsif (!$sensors{'fan-main'}[2] && $_ =~ /^(M\/B|MB|SYS|Motherboard).*:([0-9]+)[\s]RPM/i) {
+ $sensors{'fan-main'} = () if !$sensors{'fan-main'};
+ $sensors{'fan-main'}[2] = $2;
+ }
+ elsif (!$sensors{'fan-main'}[3] && $_ =~ /(Power|P\/S|POWER).*:([0-9]+)[\s]RPM/i) {
+ $sensors{'fan-main'} = () if !$sensors{'fan-main'};
+ $sensors{'fan-main'}[3] = $2;
+ }
+ elsif (!$sensors{'fan-main'}[4] && $_ =~ /(SODIMM).*:([0-9]+)[\s]RPM/i) {
+ $sensors{'fan-main'} = () if !$sensors{'fan-main'};
+ $sensors{'fan-main'}[4] = $2;
+ }
+ # note that the counters are dynamically set for fan numbers here
+ # otherwise you could overwrite eg aux fan2 with case fan2 in theory
+ # note: cpu/mobo/ps/sodimm are 1/2/3/4
+ elsif ($_ =~ /^(AUX|CASE|CHASSIS).*:([0-9]+)[\s]RPM/i) {
+ $temp_working = $2;
+ $sensors{'fan-main'} = () if !$sensors{'fan-main'};
+ for ( my $i = 5; $i < 30; $i++ ){
+ next if defined $sensors{'fan-main'}[$i];
+ if ( !defined $sensors{'fan-main'}[$i] ){
+ $sensors{'fan-main'}[$i] = $temp_working;
+ last;
+ }
+ }
}
- elsif ($_ =~ /^[+]?(3\.3 Volt|3\.3V).*:([0-9\.]+)\sV/i) {
- $sensors{'volts-3.3'} = $2;
+ # in rare cases syntax is like: fan1: xxx RPM
+ elsif ($_ =~ /^FAN(1)?:([0-9]+)[\s]RPM/i) {
+ $sensors{'fan-default'} = () if !$sensors{'fan-default'};
+ $sensors{'fan-default'}[1] = $2;
+ }
+ elsif ($_ =~ /^FAN([2-9]|1[0-9]).*:([0-9]+)[\s]RPM/i) {
+ $fan_working = $2;
+ $sys_fan_nu = $1;
+ $sensors{'fan-default'} = () if !$sensors{'fan-default'};
+ if ( $sys_fan_nu =~ /^([0-9]+)$/ ) {
+ # add to array if array index does not exist OR if number is > existing number
+ if ( defined $sensors{'fan-default'}[$sys_fan_nu] ) {
+ if ( $fan_working >= $sensors{'fan-default'}[$sys_fan_nu] ) {
+ $sensors{'fan-default'}[$sys_fan_nu] = $fan_working;
+ }
+ }
+ else {
+ $sensors{'fan-default'}[$sys_fan_nu] = $fan_working;
+ }
+ }
}
- elsif ($_ =~ /^(Vbat).*:([0-9\.]+)\sV/i) {
- $sensors{'volts-vbat'} = $2;
+ if ($extra > 0){
+ if ($_ =~ /^[+]?(12 Volt|12V).*:([0-9\.]+)\sV/i) {
+ $sensors{'volts-12'} = $2;
+ }
+ # note: 5VSB is a field name
+ elsif ($_ =~ /^[+]?(5 Volt|5V):([0-9\.]+)\sV/i) {
+ $sensors{'volts-5'} = $2;
+ }
+ elsif ($_ =~ /^[+]?(3\.3 Volt|3\.3V).*:([0-9\.]+)\sV/i) {
+ $sensors{'volts-3.3'} = $2;
+ }
+ elsif ($_ =~ /^(Vbat).*:([0-9\.]+)\sV/i) {
+ $sensors{'volts-vbat'} = $2;
+ }
}
}
}
@@ -14821,6 +16204,74 @@ sub lm_sensors_data {
eval $end if $b_log;
return %sensors;
}
+sub lm_sensors_processor {
+ eval $start if $b_log;
+ my (@data,@sensors_data,@values);
+ my ($adapter,$holder,$type) = ('','','');
+ @sensors_data = main::grabber(main::check_program('sensors') . " 2>/dev/null");
+ #my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sensors/amdgpu-w-fan-speed-stretch-k10.txt";
+ #my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sensors/peci-tin-geggo.txt";
+ #my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sensors/sensors-w-other-biker.txt";
+ #my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sensors/sensors-asus-chassis-1.txt";
+ #my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sensors/sensors-devnull-1.txt";
+ #my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sensors/sensors-jammin1.txt";
+ #my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sensors/sensors-mx-incorrect-1.txt";
+ # my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sensors/sensors-maximus-arch-1.txt";
+ # my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sensors/kernel-58-sensors-ant-1.txt";
+ # my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sensors/sensors-zenpower-nvme-2.txt";
+ # @sensors_data = main::reader($file); # only way to get sensor array data? Unless using sensors -j, but can't assume json
+ # print join ("\n", @sensors_data), "\n";
+ if (@sensors_data){
+ @sensors_data = map {$_ =~ s/\s*:\s*\+?/:/;$_} @sensors_data;
+ push @sensors_data, 'END';
+ }
+ #print Data::Dumper::Dumper \@sensors_data;
+ foreach (@sensors_data){
+ #print 'st:', $_, "\n";
+ next if /^\s*$/;
+ $_ = main::trimmer($_);
+ if (@values && $adapter && (/^Adapter/ || $_ eq 'END')){
+ # note: drivetemp: known, but many others could exist
+ if ($adapter =~ /^(drive|nvme)/){
+ $type = 'disk';
+ }
+ elsif ($adapter =~ /^(amdgpu|intel|nouveau|radeon)-/){
+ $type = 'gpu';
+ }
+ # ath/iwl: wifi; enp/eno/eth: lan nic
+ elsif ($adapter =~ /^(ath|iwl|en[op][0-9]|eth)[\S]+-/){
+ $type = 'network';
+ }
+ elsif ($adapter =~ /^(.*hwmon)-/){
+ $type = 'hwmon';
+ }
+ else {
+ $type = 'main';
+ }
+ $sensors_raw{$type}->{$adapter} = [@values];
+ @values = ();
+ $adapter = '';
+ }
+ if (/^Adapter/){
+ $adapter = $holder;
+ }
+ elsif (/\S:\S/){
+ push @values, $_;
+ }
+ else {
+ $holder = $_;
+ }
+ }
+ $b_sensors = 1;
+ if ($test[18]){
+ print 'lm sensors: ' , Data::Dumper::Dumper \%sensors_raw;
+ }
+ if ($b_log){
+ main::log_data('dump','lm-sensors data: %sensors_raw',\%sensors_raw);
+ }
+ eval $end if $b_log;
+ return @data;
+}
# oddly, openbsd sysctl actually has hw.sensors data!
sub sysctl_data {
@@ -14844,7 +16295,6 @@ sub sysctl_data {
sub set_temp_unit {
my ($sensors,$working) = @_;
my $return_unit = '';
-
if ( !$sensors && $working ){
$return_unit = $working;
}
@@ -15188,39 +16638,44 @@ sub gpu_data {
}
}
}
- if (@sensors_data){
- my ($b_found,$holder) = (0,'');
- foreach (@sensors_data){
- next if (/^Adapter:/ || /^\s*$/);
- if (/^(amdgpu|intel|nouveau|radeon)-pci-(.*)/){
- $b_found = 1;
- $holder = $1;
- $j = scalar @gpudata;
- }
- if (/^(?:(?!amdgpu|.*hwmon|intel|nouveau|radeon).)*-(pci|virtual|isa)-(.*)/){
- $b_found = 0;
- $holder = '';
- }
- if ($b_found){
- $gpudata[$j]{'type'} = $holder;
- if (/^[^:]*:([0-9]+).*\b(C|F)\s/i){
+ if ($sensors_raw{'gpu'}){
+ #my ($b_found,$holder) = (0,'');
+ foreach my $adapter (keys %{$sensors_raw{'gpu'}}){
+ $j = scalar @gpudata;
+ $gpudata[$j]{'type'} = $adapter;
+ $gpudata[$j]{'type'} =~ s/^(amdgpu|intel|nouveau|radeon)-.*/$1/;
+ # print "ad: $adapter\n";
+ foreach (@{$sensors_raw{'gpu'}->{$adapter}}){
+ # print "val: $_\n";
+ if (/^[^:]*mem[^:]*:([0-9\.]+).*\b(C|F)\b/i){
+ $gpudata[$j]{'temp-mem'} = $1;
+ $gpudata[$j]{'unit'} = $2;
+ # print "temp: $_\n";
+ }
+ elsif (/^[^:]+:([0-9\.]+).*\b(C|F)\b/i){
$gpudata[$j]{'temp'} = $1;
$gpudata[$j]{'unit'} = $2;
- # print "$_\n";
+ # print "temp: $_\n";
}
# speeds can be in percents or rpms, so need the 'fan' in regex
- if (/^.*fan.*:([0-9]+).*(RPM)?/i){
+ elsif (/^.*fan.*:([0-9\.]+).*(RPM)?/i){
$gpudata[$j]{'fan-speed'} = $1;
# NOTE: we test for nvidia %, everything else stays with nothing
$gpudata[$j]{'speed-unit'} = '';
}
- main::log_data('dump','sensors output: video: @gpudata',\@gpudata);
+ elsif (/^[^:]+:([0-9\.]+)\s+W\s/i){
+ $gpudata[$j]{'watts'} = $1;
+ }
+ elsif (/^[^:]+:([0-9\.]+)\s+mV\s/i){
+ $gpudata[$j]{'mvolts'} = $1;
+ }
}
}
}
+ main::log_data('dump','sensors output: video: @gpudata',\@gpudata);
# we'll probably use this data elsewhere so make it a one time call
$b_gpudata = 1;
- # print Data::Dumper::Dumper \@gpudata;
+ print 'gpudata: ', Data::Dumper::Dumper \@gpudata if $test[18];
eval $end if $b_log;
return @gpudata;
}
@@ -15241,13 +16696,13 @@ sub get {
elsif ($b_arm && !$b_slot_tool){
$key1 = 'ARM';
$val1 = main::row_defaults('arm-pci','');
- @rows = ({main::key($num++,$key1) => $val1,});
+ @rows = ({main::key($num++,0,1,$key1) => $val1,});
}
elsif ( $$ref{'action'} ne 'use'){
$key1 = $$ref{'action'};
$val1 = $$ref{$key1};
$key1 = ucfirst($key1);
- @rows = ({main::key($num++,$key1) => $val1,});
+ @rows = ({main::key($num++,0,1,$key1) => $val1,});
}
eval $end if $b_log;
return @rows;
@@ -15295,14 +16750,14 @@ sub slot_data {
}
@data = (
{
- main::key($num++,'Slot') => $id,
- main::key($num++,'type') => $type,
- main::key($num++,'status') => $usage,
+ main::key($num++,1,1,'Slot') => $id,
+ main::key($num++,0,2,'type') => $type,
+ main::key($num++,0,2,'status') => $usage,
},
);
@rows = (@rows,@data);
if ($extra > 1 ){
- $rows[$j]{main::key($num++,'length')} = $length;
+ $rows[$j]{main::key($num++,0,2,'length')} = $length;
}
}
}
@@ -15310,7 +16765,7 @@ sub slot_data {
if (!@rows){
my $key = 'Message';
@data = ({
- main::key($num++,$key) => main::row_defaults('pci-slot-data',''),
+ main::key($num++,0,1,$key) => main::row_defaults('pci-slot-data',''),
},);
@rows = (@rows,@data);
}
@@ -15319,6 +16774,106 @@ sub slot_data {
}
}
+## SwapData
+{
+package SwapData;
+
+sub get {
+ eval $start if $b_log;
+ my (@data,@rows,$key1,$val1);
+ my $num = 0;
+ @rows =create_output();
+ if (!@rows){
+ @data = (
+ {main::key($num++,0,1,'Alert') => main::row_defaults('swap-data')},
+ );
+ @rows = (@data);
+ }
+ eval $end if $b_log;
+ return @rows;
+}
+sub create_output {
+ eval $start if $b_log;
+ my $num = 0;
+ my $j = 0;
+ my (@data,@data2,%part,@rows,$dev,$percent,$raw_size,$size,$used);
+ my @swap_data = PartitionData::swap_data();
+ foreach my $ref (@swap_data){
+ my %row = %$ref;
+ $num = 1;
+ @data2 = main::get_size($row{'size'}) if (defined $row{'size'});
+ $size = (@data2) ? $data2[0] . ' ' . $data2[1]: 'N/A';
+ @data2 = main::get_size($row{'used'}) if (defined $row{'used'});
+ $used = (@data2) ? $data2[0] . ' ' . $data2[1]: 'N/A';
+ $percent = (defined $row{'percent-used'}) ? ' (' . $row{'percent-used'} . '%)' : '';
+ %part = ();
+ $dev = ($row{'swap-type'} eq 'file') ? 'file' : 'dev';
+ $row{'swap-type'} = ($row{'swap-type'}) ? $row{'swap-type'} : 'N/A';
+ if ($b_admin && !$bsd_type && $j == 0){
+ $j = scalar @rows;
+ if (defined $row{'swappiness'} || defined $row{'cache-pressure'}){
+ $rows[$j]{main::key($num++,1,1,'Kernel')} = '';
+ if (defined $row{'swappiness'}){
+ $rows[$j]{main::key($num++,0,2,'swappiness')} = $row{'swappiness'};
+ }
+ if (defined $row{'cache-pressure'}){
+ $rows[$j]{main::key($num++,0,2,'cache pressure')} = $row{'cache-pressure'};
+ }
+ }
+ else {
+ $rows[$j]{main::key($num++,0,1,'Message')} = main::row_defaults('swap-admin');
+ }
+ }
+ $j = scalar @rows;
+ @data = ({
+ main::key($num++,1,1,'ID') => $row{'id'},
+ main::key($num++,0,2,'type') => $row{'swap-type'},
+ });
+ @rows = (@rows,@data);
+ # not used for swap as far as I know
+ if ($b_admin && $row{'raw-size'} ){
+ # It's an error! permissions or missing tool
+ if (!main::is_numeric($row{'raw-size'})){
+ $raw_size = $row{'raw-size'};
+ }
+ else {
+ @data2 = main::get_size($row{'raw-size'});
+ $raw_size = (@data2) ? $data2[0] . ' ' . $data2[1]: 'N/A';
+ }
+ $rows[$j]{main::key($num++,0,2,'raw size')} = $raw_size;
+ }
+ # not used for swap as far as I know
+ if ($b_admin && $row{'raw-available'} && $size ne 'N/A'){
+ $size .= ' (' . $row{'raw-available'} . '%)';
+ }
+ $rows[$j]{main::key($num++,0,2,'size')} = $size;
+ $rows[$j]{main::key($num++,0,2,'used')} = $used . $percent;
+ # not used for swap as far as I know
+ if ($b_admin && $row{'block-size'}){
+ $rows[$j]{main::key($num++,0,2,'block size')} = $row{'block-size'} . ' B';;
+ #$rows[$j]{main::key($num++,0,2,'physical')} = $row{'block-size'} . ' B';
+ #$rows[$j]{main::key($num++,0,2,'logical')} = $row{'block-logical'} . ' B';
+ }
+ if ($extra > 1 && defined $row{'priority'}){
+ $rows[$j]{main::key($num++,0,2,'priority')} = $row{'priority'};
+ }
+ $row{'mount'} =~ s|/home/[^/]+/(.*)|/home/$filter_string/$1| if $row{'mount'} && $use{'filter'};
+ $rows[$j]{main::key($num++,0,2,$dev)} = ($row{'mount'}) ? $row{'mount'} : 'N/A';
+ if ($show{'label'} && ($row{'label'} || $row{'swap-type'} eq 'partition') ){
+ $row{'label'} = main::apply_partition_filter('part', $row{'label'}, '') if $use{'filter-label'};
+ $rows[$j]{main::key($num++,0,2,'label')} = ($row{'label'}) ? $row{'label'}: 'N/A';
+ }
+ if ($show{'uuid'} && ($row{'uuid'} || $row{'swap-type'} eq 'partition' )){
+ $row{'uuid'} = main::apply_partition_filter('part', $row{'uuid'}, '') if $use{'filter-uuid'};
+ $rows[$j]{main::key($num++,0,2,'uuid')} = ($row{'uuid'}) ? $row{'uuid'}: 'N/A';
+ }
+ }
+ eval $end if $b_log;
+ return @rows;
+}
+
+}
+
## UnmountedData
{
package UnmountedData;
@@ -15348,7 +16903,7 @@ sub get {
}
}
if (!@rows && $key1){
- @rows = ({main::key($num++,$key1) => $val1,});
+ @rows = ({main::key($num++,0,1,$key1) => $val1,});
}
eval $end if $b_log;
return @rows;
@@ -15375,12 +16930,14 @@ sub create_output {
$fs = 'requires file';
}
}
+ $row{'label'} = main::apply_partition_filter('part', $row{'label'}, '') if $use{'filter-label'};
+ $row{'uuid'} = main::apply_partition_filter('part', $row{'uuid'}, '') if $use{'filter-uuid'};
@data = ({
- main::key($num++,'ID') => , "/dev/$row{'dev-base'}",
- main::key($num++,'size') => , $size,
- main::key($num++,'fs') => , $fs,
- main::key($num++,'label') => , $row{'label'},
- main::key($num++,'uuid') => , $row{'uuid'},
+ main::key($num++,1,1,'ID') => "/dev/$row{'dev-base'}",
+ main::key($num++,0,2,'size') => $size,
+ main::key($num++,0,2,'fs') => $fs,
+ main::key($num++,0,2,'label') => $row{'label'},
+ main::key($num++,0,2,'uuid') => $row{'uuid'},
});
@rows = (@rows,@data);
}
@@ -15521,14 +17078,14 @@ sub get {
$val1 = $$ref2{$key1};
}
$key1 = ucfirst($key1);
- @rows = ({main::key($num++,$key1) => $val1,});
+ @rows = ({main::key($num++,0,1,$key1) => $val1,});
}
else {
@rows = usb_data();
if (!@rows){
my $key = 'Message';
@data = ({
- main::key($num++,$key) => main::row_defaults('usb-data',''),
+ main::key($num++,0,1,$key) => main::row_defaults('usb-data',''),
},);
@rows = (@rows,@data);
}
@@ -15540,7 +17097,7 @@ sub usb_data {
eval $start if $b_log;
return if ! @usb;
my (@data,@rows);
- my ($b_hub,$bus_id,$chip_id,$driver,$path_id,$ports,$product,$serial,$speed,$type);
+ my ($b_hub,$bus_id,$chip_id,$driver,$ind_sc,$path_id,$ports,$product,$serial,$speed,$type);
my $num = 0;
my $j = 0;
# note: the data has been presorted in set_lsusb_data by:
@@ -15548,9 +17105,8 @@ sub usb_data {
foreach my $ref (@usb){
my @id = @$ref;
$j = scalar @rows;
- $num = 1;
+ ($b_hub,$ind_sc,$num) = (0,3,1);
$chip_id = $id[7];
- $b_hub = 0;
($driver,$path_id,$ports,$product,
$serial,$speed,$type) = ('','','','','','','');
$speed = ( main::is_numeric($id[8]) ) ? sprintf("%1.1f",$id[8]) : $id[8] if $id[8];
@@ -15566,13 +17122,14 @@ sub usb_data {
$ports ||= 'N/A';
#print "pt0:$protocol\n";
@data = ({
- main::key($num++,'Hub') => $bus_id,
- main::key($num++,'info') => $product,
- main::key($num++,'ports') => $ports,
- main::key($num++,'rev') => $speed,
+ main::key($num++,1,1,'Hub') => $bus_id,
+ main::key($num++,0,2,'info') => $product,
+ main::key($num++,0,2,'ports') => $ports,
+ main::key($num++,0,2,'rev') => $speed,
},);
@rows = (@rows,@data);
$b_hub = 1;
+ $ind_sc =2;
}
# it's a device
else {
@@ -15581,29 +17138,30 @@ sub usb_data {
$type ||= 'N/A';
$driver ||= 'N/A';
#print "pt3:$class:$product\n";
- $rows[$j]{main::key($num++,'Device')} = $bus_id;
- $rows[$j]{main::key($num++,'info')} = $product;
- $rows[$j]{main::key($num++,'type')} = $type;
+ $rows[$j]{main::key($num++,1,2,'Device')} = $bus_id;
+ $rows[$j]{main::key($num++,0,3,'info')} = $product;
+ $rows[$j]{main::key($num++,0,3,'type')} = $type;
if ($extra > 0){
- $rows[$j]{main::key($num++,'driver')} = $driver;
+ $rows[$j]{main::key($num++,0,3,'driver')} = $driver;
}
if ($extra > 2 && $id[9]){
- $rows[$j]{main::key($num++,'interfaces')} = $id[9];
+ $rows[$j]{main::key($num++,0,3,'interfaces')} = $id[9];
}
- $rows[$j]{main::key($num++,'rev')} = $speed;
+ $rows[$j]{main::key($num++,0,3,'rev')} = $speed;
}
+ # for either hub or device
if ($extra > 2 && main::is_numeric($id[17])){
my $speed = $id[17];
if ($speed >= 1000) {$speed = ($id[17] / 1000 ) . " Gb/s"}
else {$speed = $id[17] . " Mb/s"}
- $rows[$j]{main::key($num++,'speed')} = $speed;
+ $rows[$j]{main::key($num++,0,$ind_sc,'speed')} = $speed;
}
if ($extra > 1){
- $rows[$j]{main::key($num++,'chip ID')} = $chip_id;
+ $rows[$j]{main::key($num++,0,$ind_sc,'chip ID')} = $chip_id;
}
if (!$b_hub && $extra > 2){
if ($serial){
- $rows[$j]{main::key($num++,'serial')} = main::apply_filter($serial);
+ $rows[$j]{main::key($num++,0,$ind_sc,'serial')} = main::apply_filter($serial);
}
}
}
@@ -15628,7 +17186,7 @@ sub get {
}
sub create_output {
eval $start if $b_log;
- my $num = 0;
+ my ($j,$num) = (0,0);
my (@data,@location,@rows,$value,%weather,);
my ($conditions) = ('NA');
if ($show{'weather-location'}){
@@ -15653,99 +17211,110 @@ sub create_output {
@location = get_location();
if (!$location[0]) {
return @rows = ({
- main::key($num++,'Message') => main::row_defaults('weather-null','current location'),
+ main::key($num++,0,1,'Message') => main::row_defaults('weather-null','current location'),
});
}
}
%weather = get_weather(@location);
if ($weather{'error'}) {
return @rows = ({
- main::key($num++,'Message') => main::row_defaults('weather-error',$weather{'error'}),
+ main::key($num++,0,1,'Message') => main::row_defaults('weather-error',$weather{'error'}),
});
}
if (!$weather{'weather'}) {
return @rows = ({
- main::key($num++,'Message') => main::row_defaults('weather-null','weather data'),
+ main::key($num++,0,1,'Message') => main::row_defaults('weather-null','weather data'),
});
}
$conditions = "$weather{'weather'}";
my $temp = unit_output($weather{'temp'},$weather{'temp-c'},'C',$weather{'temp-f'},'F');
+ $j = scalar @rows;
@data = ({
- main::key($num++,'Temperature') => $temp,
- main::key($num++,'Conditions') => $conditions,
+ main::key($num++,1,1,'Report') => '',
+ main::key($num++,0,2,'temperature') => $temp,
+ main::key($num++,0,2,'conditions') => $conditions,
},);
@rows = (@rows,@data);
if ($extra > 0){
my $pressure = unit_output($weather{'pressure'},$weather{'pressure-mb'},'mb',$weather{'pressure-in'},'in');
my $wind = wind_output($weather{'wind'},$weather{'wind-direction'},$weather{'wind-mph'},$weather{'wind-ms'},
$weather{'wind-gust-mph'},$weather{'wind-gust-ms'});
- $rows[0]{main::key($num++,'Wind')} = $wind;
+ $rows[$j]{main::key($num++,0,2,'wind')} = $wind;
if ($extra > 1){
if (defined $weather{'cloud-cover'}){
- $rows[0]{main::key($num++,'Cloud Cover')} = $weather{'cloud-cover'} . '%';
+ $rows[$j]{main::key($num++,0,2,'cloud cover')} = $weather{'cloud-cover'} . '%';
}
if ($weather{'precip-1h-mm'} && defined $weather{'precip-1h-in'} ){
$value = unit_output('',$weather{'precip-1h-mm'},'mm',$weather{'precip-1h-in'},'in');
- $rows[0]{main::key($num++,'Precipitation')} = $value;
+ $rows[$j]{main::key($num++,0,2,'precipitation')} = $value;
}
if ($weather{'rain-1h-mm'} && defined $weather{'rain-1h-in'} ){
$value = unit_output('',$weather{'rain-1h-mm'},'mm',$weather{'rain-1h-in'},'in');
- $rows[0]{main::key($num++,'Rain')} = $value;
+ $rows[$j]{main::key($num++,0,2,'rain')} = $value;
}
if ($weather{'snow-1h-mm'} && defined $weather{'snow-1h-in'} ){
$value = unit_output('',$weather{'snow-1h-mm'},'mm',$weather{'snow-1h-in'},'in');
- $rows[0]{main::key($num++,'Snow')} = $value;
+ $rows[$j]{main::key($num++,0,2,'snow')} = $value;
}
}
- $rows[0]{main::key($num++,'Humidity')} = $weather{'humidity'} . '%';
+ $rows[$j]{main::key($num++,0,2,'humidity')} = $weather{'humidity'} . '%';
if ($extra > 1){
if ($weather{'dewpoint'} || (defined $weather{'dewpoint-c'} && defined $weather{'dewpoint-f'})){
$value = unit_output($weather{'dewpoint'},$weather{'dewpoint-c'},'C',$weather{'dewpoint-f'},'F');
- $rows[0]{main::key($num++,'Dew Point')} = $value;
+ $rows[$j]{main::key($num++,0,2,'dew point')} = $value;
}
}
- $rows[0]{main::key($num++,'Pressure')} = $pressure;
+ $rows[$j]{main::key($num++,0,2,'pressure')} = $pressure;
}
if ($extra > 1){
if ($weather{'heat-index'} || (defined $weather{'heat-index-c'} && defined $weather{'heat-index-f'})){
$value = unit_output($weather{'heat-index'},$weather{'heat-index-c'},'C',$weather{'heat-index-f'},'F');
- $rows[0]{main::key($num++,'Heat Index')} = $value;
+ $rows[$j]{main::key($num++,0,2,'heat index')} = $value;
}
if ($weather{'windchill'} || (defined $weather{'windchill-c'} && defined $weather{'windchill-f'})){
$value = unit_output($weather{'windchill'},$weather{'windchill-c'},'C',$weather{'windchill-f'},'F');
- $rows[0]{main::key($num++,'Wind Chill')} = $value;
+ $rows[$j]{main::key($num++,0,2,'wind chill')} = $value;
}
- }
- if ($extra > 2){
- if (!$show{'filter'}){
- $rows[0]{main::key($num++,'Location')} = complete_location($location[1],$weather{'city'},$weather{'state'},$weather{'country'});
- if ($weather{'elevation-m'} || $weather{'elevation-ft'}){
- $rows[0]{main::key($num++,'altitude')} = elevation_output($weather{'elevation-m'},$weather{'elevation-ft'});
+ if ($extra > 2){
+ if ($weather{'forecast'}){
+ $j = scalar @rows;
+ @data = ({
+ main::key($num++,1,1,'Forecast') => $weather{'forecast'},
+ },);
+ @rows = (@rows,@data);
}
}
}
- $rows[0]{main::key($num++,'Current Time')} = $weather{'date-time'};
+ $j = scalar @rows;
+ my $location = '';
+ if ($extra > 2 && !$use{'filter'}){
+ $location = complete_location($location[1],$weather{'city'},$weather{'state'},$weather{'country'});
+ }
+ @data = ({
+ main::key($num++,1,1,'Locale') => $location,
+ },);
+ @rows = (@rows,@data);
+ if ($extra > 2 && !$use{'filter'} && ($weather{'elevation-m'} || $weather{'elevation-ft'} )){
+ $rows[$j]{main::key($num++,0,2,'altitude')} = elevation_output($weather{'elevation-m'},$weather{'elevation-ft'});
+ }
+ $rows[$j]{main::key($num++,0,2,'current time')} = $weather{'date-time'},;
if ($extra > 2){
$weather{'observation-time-local'} = 'N/A' if !$weather{'observation-time-local'};
- $rows[0]{main::key($num++,'Observation Time')} = $weather{'observation-time-local'};
+ $rows[$j]{main::key($num++,0,2,'observation time')} = $weather{'observation-time-local'};
if ($weather{'sunrise'}){
- $rows[0]{main::key($num++,'Sunrise')} = $weather{'sunrise'};
+ $rows[$j]{main::key($num++,0,2,'sunrise')} = $weather{'sunrise'};
}
if ($weather{'sunset'}){
- $rows[0]{main::key($num++,'Sunset')} = $weather{'sunset'};
+ $rows[$j]{main::key($num++,0,2,'sunset')} = $weather{'sunset'};
}
if ($weather{'moonphase'}){
$value = $weather{'moonphase'} . '%';
$value .= ($weather{'moonphase-graphic'}) ? ' ' . $weather{'moonphase-graphic'} :'';
- $rows[0]{main::key($num++,'Moonphase')} = $value;
- }
- if ($weather{'forecast'}){
- $rows[0]{main::key($num++,'Forecast')} = $weather{'forecast'};
+ $rows[$j]{main::key($num++,0,2,'moonphase')} = $value;
}
}
-
if ($weather{'api-source'}){
- $rows[0]{main::key($num++,'Source')} = $weather{'api-source'};
+ $rows[$j]{main::key($num++,0,1,'Source')} = $weather{'api-source'};
}
eval $end if $b_log;
return @rows;
@@ -16105,8 +17674,8 @@ sub get_weather {
$date_time = test_locale_date($date_time,$show{'weather-location'},$weather{'observation-epoch'});
$weather{'observation-time-local'} = $date_time;
}
- return %weather;
eval $end if $b_log;
+ return %weather;
}
sub download_weather {
eval $start if $b_log;
@@ -16240,7 +17809,7 @@ sub get_location {
sub complete_location {
eval $start if $b_log;
my ($location,$city,$state,$country) = @_;
- if ($location && $location =~ /[\+\-0-9]/ && $city){
+ if ($location && $location =~ /[0-9+-]/ && $city){
$location = $country . ', ' . $location if $country && $location !~ m|$country|i;
$location = $state . ', ' . $location if $state && $location !~ m|$state|i;
$location = $city . ', ' . $location if $city && $location !~ m|$city|i;
@@ -16294,16 +17863,21 @@ sub get_compiler_version_bsd {
sub get_compiler_version_linux {
eval $start if $b_log;
my ($file) = @_;
- my (@compiler,$type);
+ my (@compiler,$version);
my @data = reader($file);
my $result = $data[0] if @data;
if ($result){
- $result =~ /(gcc|clang).*version\s([\S]+)/;
# $result = $result =~ /\*(gcc|clang)\*eval\*/;
- if ($1){
- $type = $2;
- $type ||= 'N/A'; # we don't really know what linux clang looks like!
- @compiler = ($1,$type);
+ # $result='Linux version 5.4.0-rc1 (sourav@archlinux-pc) (clang version 9.0.0 (tags/RELEASE_900/final)) #1 SMP PREEMPT Sun Oct 6 18:02:41 IST 2019';
+ if ($result =~ /(gcc|clang).*version\s([\S]+)/){
+ $version = $2;
+ $version ||= 'N/A'; # we don't really know what linux clang looks like!
+ @compiler = ($1,$version);
+ }
+ elsif ($result =~ /\((gcc|clang)[^\(]*\([^\)]+\)\s+([0-9\.]+)\s.*,\s*/){
+ $version = $2;
+ $version ||= 'N/A'; # we don't really know what linux clang looks like!
+ @compiler = ($1,$version);
}
}
log_data('dump','@compiler',\@compiler) if $b_log;
@@ -16322,24 +17896,26 @@ sub get_compiler_version_linux {
# 6 - wm version
{
package DesktopEnvironment;
-my ($b_gtk,$b_qt,$b_xprop,$desktop_session,$kde_session_version,$xdg_desktop,
-@desktop,@data,@xprop);
+my ($b_gtk,$b_qt,$b_xprop,$desktop_session,$gdmsession,$kde_session_version,
+$xdg_desktop,@desktop,@data,@xprop);
sub get {
# NOTE $XDG_CURRENT_DESKTOP envvar is not reliable, but it shows certain desktops better.
# most desktops are not using it as of 2014-01-13 (KDE, UNITY, LXDE. Not Gnome)
$desktop_session = ( $ENV{'DESKTOP_SESSION'} ) ? lc($ENV{'DESKTOP_SESSION'}) : '';
$xdg_desktop = ( $ENV{'XDG_CURRENT_DESKTOP'} ) ? lc($ENV{'XDG_CURRENT_DESKTOP'}) : '';
$kde_session_version = ($ENV{'KDE_SESSION_VERSION'}) ? $ENV{'KDE_SESSION_VERSION'} : '';
+ # for fallback to fallback protections re false gnome id
+ $gdmsession = ( $ENV{'GDMSESSION'} ) ? lc($ENV{'GDMSESSION'}) : '';
main::set_ps_gui() if ! $b_ps_gui;
get_kde_trinity_data();
if (!@desktop){
get_env_de_data();
}
if (!@desktop){
- get_env_xprop_de_data();
+ get_env_xprop_gnome_based_data();
}
if (!@desktop && $b_xprop ){
- get_xprop_de_data();
+ get_env_xprop_non_gnome_based_data();
}
if (!@desktop){
get_ps_de_data();
@@ -16350,7 +17926,7 @@ sub get {
if ($b_display && !$b_force_display && $extra > 1){
get_wm();
}
- # set_gtk_data if $b_gtk && $extra > 1;
+ set_gtk_data() if $b_gtk && $extra > 1;
set_qt_data() if $b_qt && $extra > 1;
main::log_data('dump','@desktop', \@desktop) if $b_log;
# ($b_xprop,$kde_session_version,$xdg_desktop,@data,@xprop) = undef;
@@ -16360,7 +17936,6 @@ sub get_kde_trinity_data {
eval $start if $b_log;
my ($program,@version_data,@version_data2);
my $kde_full_session = ($ENV{'KDE_FULL_SESSION'}) ? $ENV{'KDE_FULL_SESSION'} : '';
-
if ($desktop_session eq 'trinity' || $xdg_desktop eq 'trinity' || (grep {/^tde/} @ps_gui) ){
$desktop[0] = 'Trinity';
if ($program = main::check_program('kdesktop')){
@@ -16418,14 +17993,13 @@ sub get_kde_trinity_data {
$desktop[3] = main::awk(\@version_data,'^Qt:', 2,'\s+');
}
# qmake can have variants, qt4-qmake, qt5-qmake, also qt5-default but not tested
- if (!$desktop[3] && ($program = main::check_program("qmake"))){
+ if (!$desktop[3] && main::check_program("qmake")){
# note: this program has issues, it may appear to be in /usr/bin, but it
# often fails to execute, so the below will have null output, but use as a
# fall back test anyway.
- @version_data = main::grabber("$program --version 2>/dev/null");
- $desktop[3] = main::awk(\@version_data,'^Using Qt version',4) if @version_data;
+ ($desktop[2],$desktop[3]) = main::program_data('qmake');
}
- $desktop[2] = 'Qt';
+ $desktop[2] ||= 'Qt';
}
}
# KDE_FULL_SESSION property is only available since KDE 3.5.5.
@@ -16447,65 +18021,63 @@ sub get_env_de_data {
eval $start if $b_log;
my ($program,@version_data);
if (!$desktop[0]){
- # 1 equals 1/0; 2 env var search; 3 values; 4 version; 5 - gtk tk; 6 - qt tk
+ # 0: 1/0; 1: env var search; 2: data; 3: gtk tk; 4: qt tk; 5: ps_gui search
my @desktops =(
- [1,'unity','unity','cinnamon',0,0],
- [0,'budgie','budgie','budgie-desktop',0,0],
+ [1,'unity','unity',0,0],
+ [0,'budgie','budgie-desktop',0,0],
# debian package: lxde-core.
# NOTE: some distros fail to set XDG data for root
- [1,'lxde','lxde','lxpanel',0,0,'^lxsession$'],
- [1,'razor','razor','razor-session',0,1,'^razor-session$'],
+ [1,'lxde','lxpanel',0,0,',^lxsession$'],
+ [1,'razor','razor-session',0,1,'^razor-session$'],
# BAD: lxqt-about opens dialogue, sigh.
# Checked, lxqt-panel does show same version as lxqt-about
- [1,'lxqt','lxqt','lxqt-panel',0,1,'^lxqt-session$'],
- [0,'^(razor|lxqt)$','lxqt-variant','lxqt-panel',0,1,'^(razor-session|lxqt-session)$'],
+ [1,'lxqt','lxqt-panel',0,1,'^lxqt-session$'],
+ [0,'^(razor|lxqt)$','lxqt-variant',0,1,'^(razor-session|lxqt-session)$'],
# note, X-Cinnamon value strikes me as highly likely to change, so just
# search for the last part
- [0,'cinnamon','cinnamon','cinnamon',0,0],
+ [0,'cinnamon','cinnamon',1,0],
# these so far have no cli version data
- [1,'deepin','deepin','dde-desktop',0,1], # version comes from file read
- [1,'pantheon','pantheon','pantheon',0,0],
- [1,'lumina','lumina','lumina-desktop',0,1],
- [0,'manokwari','manokwari','manokwari',1,0],
- [1,'ukui','ukui','ukui-session',0,1],
+ [1,'deepin','deepin',0,1], # version comes from file read
+ [1,'pantheon','pantheon',0,0],
+ [1,'lumina','lumina-desktop',0,1],
+ [0,'manokwari','manokwari',1,0],
+ [1,'ukui','ukui-session',0,1],
);
foreach my $item (@desktops){
# Check if in xdg_desktop OR desktop_session OR if in $item->[6] and in ps_gui
if ( (($item->[0] && ($xdg_desktop eq $item->[1] || $desktop_session eq $item->[1] )) ||
(!$item->[0] && ($xdg_desktop =~ /$item->[1]/ || $desktop_session =~ /$item->[1]/ )) ) ||
- ($item->[6] && @ps_gui && (grep {/$item->[6]/} @ps_gui) ) ){
- @data = main::program_values($item->[2]);
- $desktop[0] = $data[3];
- $b_gtk = $item->[4];
- $b_qt = $item->[5];
- if ($data[1] && $data[2]){
- $desktop[1] = main::program_version($item->[3],$data[0],$data[1],$data[2],$data[5],$data[6]);
- }
+ ($item->[5] && @ps_gui && (grep {/$item->[5]/} @ps_gui) ) ){
+ ($desktop[0],$desktop[1]) = main::program_data($item->[2]);
+ $b_gtk = $item->[3];
+ $b_qt = $item->[4];
last;
}
}
}
eval $end if $b_log;
}
-sub get_env_xprop_de_data {
+sub get_env_xprop_gnome_based_data {
eval $start if $b_log;
my ($program,$value,@version_data);
# NOTE: Always add to set_prop the search term if you add an item!!
set_xprop();
+ # add more as discovered
+ return if $xdg_desktop eq 'xfce' || $gdmsession eq 'xfce';
# note that cinnamon split from gnome, and and can now be id'ed via xprop,
# but it will still trigger the next gnome true case, so this needs to go
# before gnome test eventually this needs to be better organized so all the
# xprop tests are in the same section, but this is good enough for now.
# NOTE: was checking for 'muffin' but that's not part of cinnamon
- if ( (main::check_program('muffin') || main::check_program('cinnamon-session') ) &&
+ if ( $xdg_desktop eq 'cinnamon' || $gdmsession eq 'cinnamon' ||
+ (main::check_program('muffin') || main::check_program('cinnamon-session') ) &&
($b_xprop && main::awk(\@xprop,'_muffin') )){
- @data = main::program_data('cinnamon','cinnamon',0);
- $desktop[0] = $data[0];
- $desktop[1] = $data[1];
- # $b_gtk = 1;
+ ($desktop[0],$desktop[1]) = main::program_data('cinnamon','cinnamon',0);
+ $b_gtk = 1;
$desktop[0] ||= 'Cinnamon';
}
- elsif ($xdg_desktop eq 'mate' || ( $b_xprop && main::awk(\@xprop,'_marco') )){
+ elsif ($xdg_desktop eq 'mate' || $gdmsession eq 'mate' ||
+ ( $b_xprop && main::awk(\@xprop,'_marco') )){
# NOTE: mate-about and mate-sesssion vary which has the higher number, neither
# consistently corresponds to the actual MATE version, so check both.
my %versions = ('mate-about' => '','mate-session' => '');
@@ -16521,25 +18093,62 @@ sub get_env_xprop_de_data {
# $b_gtk = 1;
$desktop[0] ||= 'MATE';
}
- # note, GNOME_DESKTOP_SESSION_ID is deprecated so we'll see how that works out
- # https://bugzilla.gnome.org/show_bug.cgi?id=542880.
- # NOTE: manjaro is leaving XDG data null, which forces the manual check for gnome, sigh...
- elsif ($xdg_desktop eq 'gnome' || $ENV{'GNOME_DESKTOP_SESSION_ID'} ||
- (main::check_program('gnome-shell') && $b_xprop && main::awk(\@xprop,'^_gnome') ) ){
- if ($program = main::check_program('gnome-about') ) {
- @data = main::program_values('gnome-about');
- $desktop[1] = main::program_version('gnome-about',$data[0],$data[1],$data[2],$data[5],$data[6]);
+ # See sub for logic and comments
+ elsif (check_gnome() ){
+ if (main::check_program('gnome-about') ) {
+ ($desktop[0],$desktop[1]) = main::program_data('gnome-about');
}
- elsif ($program = main::check_program('gnome-shell') ) {
- @data = main::program_values('gnome-shell');
- $desktop[1] = main::program_version('gnome-shell',$data[0],$data[1],$data[2],$data[5],$data[6]);
+ elsif (main::check_program('gnome-shell') ) {
+ ($desktop[0],$desktop[1]) = main::program_data('gnome','gnome-shell');
}
- # $b_gtk = 1;
- $desktop[0] = ( $data[3] ) ? $data[3] : 'Gnome';
+ $b_gtk = 1;
+ $desktop[0] ||= 'GNOME';
}
eval $end if $b_log;
}
-sub get_xprop_de_data {
+# note, GNOME_DESKTOP_SESSION_ID is deprecated so we'll see how that works out
+# https://bugzilla.gnome.org/show_bug.cgi?id=542880.
+# NOTE: manjaro is leaving XDG data null, which forces the manual check for gnome, sigh...
+# some gnome programs can trigger a false xprop gnome ID
+# _GNOME_BACKGROUND_REPRESENTATIVE_COLORS(STRING) = "rgb(23,31,35)"
+sub check_gnome {
+ eval $start if $b_log;
+ my ($b_gnome,$detection) = (0,'');
+ if ($xdg_desktop && $xdg_desktop eq 'gnome'){
+ $detection = 'xdg_current_desktop';
+ $b_gnome = 1;
+ }
+ elsif ($xdg_desktop && $xdg_desktop ne 'gnome'){
+ $detection = 'xdg_current_desktop';
+ }
+ # possible values: lightdm-xsession, only positive match tests will work
+ elsif ($gdmsession && $gdmsession eq 'gnome'){
+ $detection = 'gdmsession';
+ $b_gnome = 1;
+ }
+ # risky: Debian: $DESKTOP_SESSION = lightdm-xsession; Manjaro/Arch = xfce
+ # note that mate/cinnamon would already have been caught so no need to add
+ # explicit tests for them
+ elsif ($desktop_session && $desktop_session eq 'gnome'){
+ $detection = 'desktop_session';
+ $b_gnome = 1;
+ }
+ # possible value: this-is-deprecated, but I believe only gnome based desktops
+ # set this variable, so it doesn't matter what it contains
+ elsif ($ENV{'GNOME_DESKTOP_SESSION_ID'}){
+ $detection = 'gnome_destkop_session_id';
+ $b_gnome = 1;
+ }
+ # maybe use ^_gnome_session instead? try it for a while
+ elsif ($b_xprop && main::check_program('gnome-shell') && main::awk(\@xprop,'^_gnome_session')){
+ $detection = 'xprop-root';
+ $b_gnome = 1;
+ }
+ main::log_data('data','$detection:$b_gnome',$detection . ":$b_gnome") if $b_log;
+ eval $end if $b_log;
+ return $b_gnome;
+}
+sub get_env_xprop_non_gnome_based_data {
eval $start if $b_log;
my ($program,@version_data,$version);
#print join "\n", @xprop, "\n";
@@ -16547,7 +18156,8 @@ sub get_xprop_de_data {
# alternate: xfce4-about --version > xfce4-about 4.10.0 (Xfce 4.10)
# note: some distros/wm (e.g. bunsen) set xdg to xfce to solve some other
# issues so don't test for that. $xdg_desktop eq 'xfce'
- if ((main::check_program('xfdesktop')) && main::awk(\@xprop,'^(xfdesktop|xfce)' )){
+ if ($xdg_desktop eq 'xfce' || $gdmsession eq 'xfce' ||
+ (main::check_program('xfdesktop')) && main::awk(\@xprop,'^(xfdesktop|xfce)' )){
# this is a very expensive test that doesn't usually result in a find
# talk to xfce to see what id they will be using for xfce 5
# if (main::awk(\@xprop, 'xfce4')){
@@ -16584,15 +18194,16 @@ sub get_xprop_de_data {
$desktop[2] = $data[3];
}
}
- elsif ( (main::check_program('enlightenment') || main::check_program('moksha') ) &&
- main::awk(\@xprop,'moksha') ){
+ elsif ( $xdg_desktop eq 'moksha' || $gdmsession eq 'moksha' ||
+ (main::check_program('enlightenment') || main::check_program('moksha') ) && main::awk(\@xprop,'moksha') ){
# no -v or --version but version is in xprop -root
# ENLIGHTENMENT_VERSION(STRING) = "Moksha 0.2.0.15989"
$desktop[0] = 'Moksha';
$desktop[1] = main::awk(\@xprop,'(enlightenment|moksha)_version',2,'\s+=\s+' );
$desktop[1] =~ s/"?(Moksha|Enlightenment)\s([^"]+)"?/$2/i if $desktop[1];
}
- elsif ( main::check_program('enlightenment') && main::awk(\@xprop,'enlightenment' ) ){
+ elsif ( $xdg_desktop eq 'enlightenment' || $gdmsession eq 'enlightenment' ||
+ (main::check_program('enlightenment') && main::awk(\@xprop,'enlightenment' ) ) ){
# no -v or --version but version is in xprop -root
# ENLIGHTENMENT_VERSION(STRING) = "Enlightenment 0.16.999.49898"
$desktop[0] = 'Enlightenment';
@@ -16603,27 +18214,25 @@ sub get_xprop_de_data {
# wm, so we want to get the main controlling desktop first, then fall back to the wm
# detections. get_ps_de_data() and get_wm() will handle alternate wm detections.
if (!$desktop[0]){
- # 1 check program; 2 xprop search; 3 values; 4 version; 5 - optional: ps_gui search
+ # 0 check program; 1 xprop search; 2: data; 3 - optional: ps_gui search
my @desktops =(
- ['icewm','icewm','icewm','icewm'],
+ ['icewm','icewm','icewm'],
# debian package: i3-wm
- ['i3','i3','i3','i3'],
- ['mwm','^_motif','mwm','mwm'],
+ ['i3','i3','i3'],
+ ['mwm','^_motif','mwm'],
# debian package name: wmaker
- ['WindowMaker','^_?windowmaker','wmaker','wmaker'],
- ['wm2','^_wm2','wm2','wm2'],
- ['herbstluftwm','herbstluftwm','herbstluftwm','herbstluftwm'],
- ['fluxbox','blackbox_pid','fluxbox','fluxbox','^fluxbox$'],
- ['blackbox','blackbox_pid','blackbox','blackbox'],
- ['openbox','openbox_pid','openbox','openbox'],
- ['amiwm','amiwm','amiwm','amiwm'],
+ ['WindowMaker','^_?windowmaker','wmaker'],
+ ['wm2','^_wm2','wm2'],
+ ['herbstluftwm','herbstluftwm','herbstluftwm'],
+ ['fluxbox','blackbox_pid','fluxbox','^fluxbox$'],
+ ['blackbox','blackbox_pid','blackbox'],
+ ['openbox','openbox_pid','openbox'],
+ ['amiwm','amiwm','amiwm'],
);
foreach my $item (@desktops){
if (main::check_program($item->[0]) && main::awk(\@xprop,$item->[1]) &&
(!$item->[4] || (@ps_gui && (grep {/$item->[4]/} @ps_gui ))) ){
- @data = main::program_data($item->[2],$item->[3],0);
- $desktop[0] = $data[0];
- $desktop[1] = $data[1];
+ ($desktop[0],$desktop[1]) = main::program_data($item->[2]);
last;
}
}
@@ -16636,67 +18245,83 @@ sub get_ps_de_data {
my ($program,@version_data);
main::set_ps_gui() if !$b_ps_gui;
if (@ps_gui){
- # 1 check program; 2 ps_gui search; 3 values; 4 version
+ # 1 check program; 2 ps_gui search; 3 data; 4: trigger alternate values/version
my @desktops =(
- ['fluxbox','fluxbox','fluxbox','fluxbox'],
+ ['9wm','9wm','9wm',''],
+ ['afterstep','afterstep','afterstep',''],
+ ['aewm++','aewm\+\+','aewm++',''],
+ ['aewm','aewm','aewm',''],
+ ['amiwm','amiwm','amiwm',''],
+ ['antiwm','antiwm','antiwm',''],
+ ['awesome','awesome','awesome',''],
+ ['blackbox','blackbox','blackbox',''],
+ ['bspwm','bspwm','bspwm',''],
+ ['cagebreak','cagebreak','cagebreak',''],
+ ['calmwm','calmwm','calmwm',''],
+ ['clfswm','.*(sh|c?lisp)?.*clfswm','clfswm',''],
+ ['cwm','(openbsd-)?cwm','cwm',''],
+ ['dwm','dwm','dwm',''],
+ ['echinus','echinus','echinus',''],
+ ['evilwm','evilwm','evilwm',''],
+ ['fireplace','fireplace','fireplace',''],
+ ['fluxbox','fluxbox','fluxbox',''],
+ ['flwm','flwm','flwm',''],
+ ['flwm','flwm_topside','flwm',''],
['fvwm-crystal','fvwm.*-crystal','fvwm-crystal','fvwm'],
- ['fvwm2','fvwm2','fvwm2','fvwm2'],
- ['fvwm','fvwm','fvwm','fvwm'],
- ['pekwm','pekwm','pekwm','pekwm'],
- ['awesome','awesome','awesome','awesome'],
- ['blackbox','blackbox','blackbox','blackbox'],
- ['openbox','openbox','openbox','openbox'],
- # not in debian apt
- ['scrotwm','scrotwm','scrotwm','scrotwm'],
- ['spectrwm','spectrwm','spectrwm','spectrwm'],
- ['twm','twm','twm','twm'],
- # note: built from source, but I assume it will show: /usr/bin/dwm
- ['dwm','dwm','dwm','dwm'],
+ ['fvwm1','fvwm1','fvwm1',''],
+ ['fvwm2','fvwm2','fvwm2',''],
+ ['fvwm3','fvwm3','fvwm3',''],
+ ['fvwm95','fvwm95','fvwm95',''],
+ ['fvwm','fvwm','fvwm',''],
+ ['glass','glass','glass',''],
+ ['hackedbox','hackedbox','hackedbox',''],
+ ['instantwm','instantwm','instantwm',''],
+ ['ion3','ion3','ion3',''],
+ ['jbwm','jbwm','jbwm',''],
+ ['jwm','jwm','jwm',''],
+ ['larswm','larswm','larswm',''],
+ ['lwm','lwm','lwm',''],
+ ['mini','mini','mini',''],
+ ['musca','musca','musca',''],
+ ['mvwm','mvwm','mvwm',''],
+ ['mwm','mwm','mwm',''],
+ ['nawm','nawm','nawm',''],
+ ['notion','notion','notion',''],
+ ['openbox','openbox','openbox',''],
+ ['orbital','orbital','orbital',''],
+ ['pekwm','pekwm','pekwm',''],
+ ['perceptia','perceptia','perceptia',''],
+ ['qtile','.*(python.*)?qtile','qtile',''],
+ ['qvwm','qvwm','qvwm',''],
+ ['ratpoison','ratpoison','ratpoison',''],
+ ['sawfish','sawfish','sawfish',''],
+ ['scrotwm','scrotwm','scrotwm',''],
+ ['spectrwm','spectrwm','spectrwm',''],
+ ['stumpwm','(sh|c?lisp)?.*stumpwm','stumpwm',''],
+ ['sway','sway','sway',''],
+ ['matchbox-window-manager','matchbox-window-manager','matchbox-window-manager',''],
+ ['tinywm','tinywm','tinywm',''],
+ ['tvtwm','tvtwm','tvtwm',''],
+ ['twm','twm','twm',''],
+ ['waycooler','waycooler','way-cooler',''],
+ ['way-cooler','way-cooler','way-cooler',''],
+ ['WindowMaker','WindowMaker','wmaker',''],
+ ['windowlab','windowlab','windowlab',''],
# not in debian apt, current is wmii, version 3
- ['wmii2','wmii2','wmii2','wmii2'],
- ['wmii','wmii','wmii','wmii'],
- ['9wm','9wm','9wm','9wm'],
- ['amiwm','amiwm','amiwm','amiwm'],
- ['fireplace','fireplace','fireplace','fireplace'],
- ['flwm','flwm','flwm','flwm'],
- ['flwm','flwm_topside','flwm','flwm'],
- ['ion','ion','ion','ion'],
- ['jwm','jwm','jwm','jwm'],
- ['lwm','lwm','lwm','lwm'],
- ['mwm','mwm','mwm','mwm'],
- ['nawm','nawm','nawm','nawm'],
- ['notion','notion','notion','notion'],
- ['orbital','orbital','orbital','orbital'],
- ['perceptia','perceptia','perceptia','perceptia'],
- ['qtile','qtile','qtile','qtile'],
- ['ratpoison','ratpoison','ratpoison','ratpoison'],
- ['sawfish','sawfish','sawfish','sawfish'],
- ['sway','sway','sway','sway'],
- ['matchbox-window-manager','matchbox-window-manager',
- 'matchbox-window-manager','matchbox-window-manager'],
- ['afterstep','afterstep','afterstep','afterstep'],
- ['bspwm','bspwm','bspwm','bspwm'],
- ['tvtwm','tvtwm','tvtwm','tvtwm'],
- ['waycooler','waycooler','way-cooler','way-cooler'],
- ['way-cooler','way-cooler','way-cooler','way-cooler'],
- ['WindowMaker','WindowMaker','wmaker','wmaker'],
- ['windowlab','windowlab','windowlab','windowlab'],
- ['wmx','wmx','wmx','wmx'],
- ['xmonad','xmonad','xmonad','xmonad'],
+ ['wmii2','wmii2','wmii2',''],
+ ['wmii','wmii','wmii',''],
+ ['wmx','wmx','wmx',''],
+ ['xmonad','xmonad','xmonad',''],
## fallback for xfce in case no xprop
- ['xfdesktop','xfdesktop','xfdesktop','xfdesktop'],
+ ['xfdesktop','xfdesktop','xfdesktop',''],
+ ['yeahwm','yeahwm','yeahwm',''],
);
foreach my $item (@desktops){
# no need to use check program with short list of ps_gui
- # if ( main::check_program($item[0]) && (grep {/^$item[1]$/} @ps_gui)){
if (grep {/^$item->[1]$/} @ps_gui){
- @data = main::program_data($item->[2],$item->[3],0);
- $desktop[0] = $data[0];
- $desktop[1] = $data[1];
+ ($desktop[0],$desktop[1]) = main::program_data($item->[2],$item->[3]);
if ($extra > 1 && $item->[0] eq 'xfdesktop'){
- @version_data = main::program_data('xfdesktop-toolkit',$item->[0],1);
- $desktop[2] = $version_data[0] if $version_data[0];
- $desktop[3] = $version_data[1] if $version_data[1];
+ ($desktop[2],$desktop[3]) = main::program_data('xfdesktop-toolkit',$item->[0],1);
}
last;
}
@@ -16704,7 +18329,15 @@ sub get_ps_de_data {
}
eval $end if $b_log;
}
-
+# NOTE: used to use a super slow method here, but gtk-launch returns
+# the gtk version I believe
+sub set_gtk_data {
+ eval $start if $b_log;
+ if (main::check_program('gtk-launch')){
+ ($desktop[2],$desktop[3]) = main::program_data('gtk-launch');
+ }
+ eval $end if $b_log;
+}
sub set_qt_data {
eval $start if $b_log;
my ($program,@data,@version_data);
@@ -16718,15 +18351,11 @@ sub set_qt_data {
}
# alternate: qt4-default, qt4-qmake or qt5-default, qt5-qmake
# often this exists, is executable, but actually is nothing, shows error
- if (!$desktop[3] && ($program = main::check_program("qmake"))){
- @version_data = main::grabber("$program --version 2>/dev/null");
- $desktop[2] = 'Qt';
- $desktop[3] = main::awk(\@version_data,'^Using Qt version',4) if @version_data;
+ if (!$desktop[3] && main::check_program('qmake')){
+ ($desktop[2],$desktop[3]) = main::program_data('qmake');
}
- if (!$desktop[3] && ($program = main::check_program("qtdiag") )){
- @data = main::program_values('qtdiag');
- $desktop[3] = main::program_version($program,$data[0],$data[1],$data[2],$data[5],$data[6]);
- $desktop[2] = $data[3];
+ if (!$desktop[3] && main::check_program('qtdiag')){
+ ($desktop[2],$desktop[3]) = main::program_data('qtdiag');
}
if (!$desktop[3] && ($program = main::check_program("kf$kde_version-config") )){
@version_data = main::grabber("$program --version 2>/dev/null");
@@ -16772,13 +18401,20 @@ sub get_wm_main {
if (!$desktop[5]){
main::set_ps_gui() if ! $b_ps_gui;
# order matters, see above logic
- $wms = '9wm|afterstep|amiwm|awesome|bspwm|budgie-wm|compiz|fluxbox|blackbox|';
- $wms .= 'deepin-wm|dwm|fireplace|flwm|fvwm-crystal|fvwm2|fvwm|gala|gnome-shell|i3|ion|jwm|';
- $wms .= 'twin|kwin_wayland|kwin_x11|kwin|lwm|matchbox-window-manager|marco|';
- $wms .= 'muffin|deepin-mutter|mutter|deepin-metacity|metacity|mwm|';
- $wms .= 'nawm|notion|openbox|orbital|perceptia|qtile|ratpoison|sawfish|scrotwm|spectrwm|';
- $wms .= 'sway|tvtwm|twm|ukwm|way-?cooler|windowlab|WindowMaker|wm2|wmii2|wmii|wmx|';
- $wms .= 'xfwm4|xfwm5|xmonad';
+ # due to lisp/python starters, clfswm/stumpwm/qtile will not detect here
+ $wms = '9wm|aewm\+\+|aewm|afterstep|amiwm|antiwm|awesome|blackbox|bspwm|budgie-wm|';
+ $wms .= 'cagebreak|calmwm|clfswm|compiz|(openbsd-)?cwm|fluxbox|';
+ $wms .= 'deepin-wm|dwm|echinus|evilwm|';
+ $wms .= 'fireplace|flwm|fvwm-crystal|fvwm1|fvwm2|fvwm3|fvwm95|fvwm|';
+ $wms .= 'gala|glass|gnome-shell|hackedbox|i3|instantwm|ion3|jbwm|jwm|';
+ $wms .= 'twin|kwin_wayland|kwin_x11|kwin|larswm|lwm|';
+ $wms .= 'matchbox-window-manager|marco|mini|muffin|';
+ $wms .= 'musca|deepin-mutter|mutter|deepin-metacity|metacity|mvwm|mwm|';
+ $wms .= 'nawm|notion|openbox|orbital|perceptia|qtile|qvwm|';
+ $wms .= 'ratpoison|sawfish|scrotwm|spectrwm|';
+ $wms .= 'stumpwm|sway|tinywm|tvtwm|twm|ukwm|';
+ $wms .= 'way-?cooler|windowlab|WindowMaker|wm2|wmii2|wmii|wmx|';
+ $wms .= 'xfwm4|xfwm5|xmonad|yeahwm';
foreach (@ps_gui){
if (/^($wms)$/){
$working = $1;
@@ -16831,16 +18467,14 @@ sub get_wm_version {
}
eval $end if $b_log;
}
-# see: inxi-fragments.txt for legacy code
-# sub set_gtk_data {
-# }
+
sub set_info_data {
eval $start if $b_log;
main::set_ps_gui() if ! $b_ps_gui;
my (@data,@info,$item);
my $pattern = 'alltray|awn|bar|bmpanel|bmpanel2|budgie-panel|cairo-dock|';
$pattern .= 'dde-dock|dmenu|dockbarx|docker|docky|dzen|dzen2|';
- $pattern .= 'fancybar|fbpanel|fspanel|glx-dock|gnome-panel|hpanel|i3bar|icewmtray|';
+ $pattern .= 'fancybar|fbpanel|fspanel|glx-dock|gnome-panel|hpanel|i3bar|i3status|icewmtray|';
$pattern .= 'kdocker|kicker|';
$pattern .= 'latte|latte-dock|lemonbar|ltpanel|lxpanel|lxqt-panel|';
$pattern .= 'matchbox-panel|mate-panel|ourico|';
@@ -16895,7 +18529,7 @@ sub get_display_manager {
# explicitly, not -e. Guessing on cdm.pid
my @dms = qw(cdm.pid entranced.pid gdm.pid gdm3.pid kdm.pid ldm.pid
lightdm.pid lxdm.pid mdm.pid nodm.pid pcdm.pid sddm.pid slim.lock
- tdm.pid wdm.pid xdm.pid xenodm.pid);
+ tdm.pid udm.pid wdm.pid xdm.pid xenodm.pid);
# these are the only one I know of so far that have version info
my @dms_version = qw(gdm gdm3 lightdm slim);
$b_run = 1 if -d "/run";
@@ -16918,10 +18552,10 @@ sub get_display_manager {
( $b_vrun && ( -f "/var/run/$id" || -d "/var/run/$working" ) ) ||
( $b_vrunrc && ( -f "/var/run/rc.d/$working" || -d "/var/run/rc.d/$id" ) ) ) &&
! grep {/$working/} @found ){
- if ($extra > 2 && awk( \@dms_version, $working) && ($path = main::check_program($working)) ){}
+ if ($extra > 2 && awk( \@dms_version, $working) && ($path = check_program($working)) ){}
else {$path = $working;}
# print "$path $extra\n";
- @data = main::program_data($working,$path,3);
+ @data = program_data($working,$path,3);
$working = $data[0];
$working .= ' ' . $data[1] if $data[1];
push @found, $working;
@@ -16930,7 +18564,7 @@ sub get_display_manager {
if (!@found){
# ly does not have a run/pid file
if (grep {$_ eq 'ly'} @ps_gui) {
- @data = main::program_data('ly','ly',3);
+ @data = program_data('ly','ly',3);
$found[0] = $data[0];
$found[0] .= ' ' . $data[1] if $data[1];
}
@@ -17437,6 +19071,8 @@ sub ubuntu_id {
$codename = lc($codename);
my ($id) = ('');
my %codenames = (
+ 'groovy' => '20.10',
+ 'focal' => '20.04 LTS',
'eoan' => '19.10',
'disco' => '19.04',
'cosmic' => '18.10',
@@ -17459,7 +19095,23 @@ sub ubuntu_id {
return $id;
}
}
-
+# return all device modules not including driver
+sub get_driver_modules {
+ eval $start if $b_log;
+ my ($driver,$modules) = @_;
+ return if ! $modules;
+ my @mods = split /,\s+/, $modules;
+ if ($driver){
+ @mods = grep {!/^$driver$/} @mods;
+ $modules = join ',', @mods;
+ }
+ log_data('data','$modules',$modules) if $b_log;
+ eval $end if $b_log;
+ return $modules;
+}
+# 1: driver; 2: modules, comma separated, return only modules
+# which do not equal the driver string itself. Sometimes the module
+# name is different from the driver name, even though it's the same thing.
sub get_gcc_data {
eval $start if $b_log;
my ($gcc,@data,@gccs,@temp);
@@ -17711,10 +19363,10 @@ sub get_memory_data_full {
}
}
my $key = ($source eq 'process') ? 'System RAM': 'RAM';
- $rows[0]{main::key($num++,$key)} = '';
- $rows[0]{main::key($num++,'total')} = $total;
- $rows[0]{main::key($num++,'used')} = $used;
- $rows[0]{main::key($num++,'gpu')} = $gpu_ram if $gpu_ram;
+ $rows[0]{main::key($num++,1,1,$key)} = '';
+ $rows[0]{main::key($num++,0,2,'total')} = $total;
+ $rows[0]{main::key($num++,0,2,'used')} = $used;
+ $rows[0]{main::key($num++,0,2,'gpu')} = $gpu_ram if $gpu_ram;
$b_mem = 1;
}
eval $end if $b_log;
@@ -17901,6 +19553,146 @@ sub get_module_version {
eval $end if $b_log;
return $version;
}
+# Note: this outputs the key/value pairs ready to go and is
+# called from either -r or -Ix, -r precedes.
+## Get PackageData
+{
+package PackageData;
+my ($count,%counts,@list,$num,%output,$program,$type);
+$counts{'total'} = 0;
+sub get {
+ eval $start if $b_log;
+ # $num passed by reference to maintain incrementing where requested
+ ($type,$num) = @_;
+ package_counts();
+ appimage_counts();
+ create_output();
+ eval $end if $b_log;
+ return %output;
+}
+sub create_output {
+ eval $start if $b_log;
+ my $total;
+ if ($counts{'total'}){
+ $total = $counts{'total'};
+ }
+ else {
+ if ($type eq 'inner'){$total = 'N/A';}
+ else {$total = main::row_defaults('packages','');}
+ }
+ if ($counts{'total'} && $extra > 1){
+ delete $counts{'total'};
+ my $b_mismatch;
+ foreach (keys %counts){
+ if ($counts{$_}->[0] && $counts{$_}->[0] != $total){
+ $b_mismatch = 1;
+ last;
+ }
+ }
+ $total = '' if !$b_mismatch;
+ }
+ $output{main::key($$num++,1,1,'Packages')} = $total;
+ if ($extra > 1 && %counts){
+ foreach (sort keys %counts){
+ my ($cont,$ind) = (1,2);
+ # if package mgr command returns error, this will not be an array
+ next if ref $counts{$_} ne 'ARRAY';
+ if ($counts{$_}->[0] || $b_admin){
+ my $key = $_;
+ $key =~ s/^zzz-//; # get rid of the special sorters for items to show last
+ $output{main::key($$num++,$cont,$ind,$key)} = $counts{$_}->[0];
+ if ($b_admin && $counts{$_}->[1]){
+ ($cont,$ind) = (0,3);
+ $output{main::key($$num++,$cont,$ind,'lib')} = $counts{$_}->[1];
+ }
+ }
+ }
+ }
+ # print Data::Dumper::Dumper \%output;
+ eval $end if $b_log;
+}
+sub package_counts {
+ eval $start if $b_log;
+ my ($type) = @_;
+ # 0: key; 1: program; 2: p/d; 3: arg/path; 4: 0/1 use lib;
+ # 5: lib slice; 6: lib splitter; 7 - optional eval test
+ # needed: cards [nutyx], urpmq [mageia]
+ my @pkg_managers = (
+ ['alps','alps','p','showinstalled',1,0,''],
+ ['apk','apk','p','info',1,0,''],
+ # older dpkg-query do not support -f values consistently: eg ${binary:Package}
+ ['apt','dpkg-query','p','-W -f=\'${Package}\n\'',1,0,''],
+ # ['aptd','dpkg-query','d','/usr/lib/*',1,3,'\\/'],
+ # mutyx. do cards test because there is a very slow pkginfo python pkg mgr
+ ['cards','pkginfo','p','-i',1,1,'','main::check_program(\'cards\')'],
+ ['emerge','emerge','d','/var/db/pkg/*/*/',1,5,'\\/'],
+ ['eopkg','eopkg','d','/var/lib/eopkg/package/*',1,5,'\\/'],
+ ['guix-sys','guix','p','package -p "/run/current-system/profile" -I',1,0,''],
+ ['guix-usr','guix','p','package package -I',1,0,''],
+ ['pacman','pacman','p','-Qq --color never',1,0,''],
+ ['pacman-g2','pacman-g2','p','-Q',1,0,''],
+ ['pkg','pkg','d','/var/db/pkg/*',1,0,''], # 'pkg list' returns non programs
+ ['pkg_info','pkg_info','p','',1,0,''],
+ ['pkgtool','pkgtool','d','/var/log/packages/*',1,4,'\\/'],
+ # way too slow without nodigest/sig!! confirms packages exist
+ ['rpm','rpm','p','-qa --nodigest --nosignature',1,0,''],
+ # note',' slapt-get, spkg, and pkgtool all return the same count
+ #['slapt-get','slapt-get','p','--installed',1,0,''],
+ #['spkg','spkg','p','--installed',1,0,''],
+ ['tce','tce-status','p','-i',1,0,''],
+ # note: I believe mageia uses rpm internally but confirm
+ # ['urpmi','urpmq','p','??',1,0,''],
+ ['xbps','xbps-query','p','-l',1,1,''],
+ ['zzz-flatpak','flatpak','p','list',0,0,''],
+ ['zzz-snap','snap','p','list',0,0,'','@ps_cmd && (grep {/\bsnapd\b/} @ps_cmd)'],
+ );
+ my $libs;
+ foreach (@pkg_managers){
+ if ($program = main::check_program($_->[1])){
+ next if $_->[7] && !eval $_->[7];
+ if ($_->[2] eq 'p'){
+ chomp(@list = qx($program $_->[3] 2>/dev/null));
+ }
+ else {
+ @list = main::globber($_->[3]);
+ }
+ $libs = undef;
+ $count = scalar @list;
+ #print Data::Dumper::Dumper \@list;
+ if ($b_admin && $count && $_->[4]){
+ $libs = count_libs(\@list,$_->[5],$_->[6]);
+ }
+ $counts{$_->[0]} = ([$count,$libs]);
+ $counts{'total'} += $count;
+ #print Data::Dumper::Dumper \%counts;
+ }
+ }
+ # print Data::Dumper::Dumper \%counts;
+ main::log_data('dump','Packaage managers: %counts',\%counts) if $b_log;
+ eval $end if $b_log;
+}
+sub appimage_counts {
+ if (@ps_cmd && (grep {/\bappimaged\b/} @ps_cmd)){
+ @list = main::globber($ENV{'HOME'} . '/.local/bin/*.appimage');
+ $count = scalar @list;
+ $counts{'zzz-appimage'} = ([$$count,undef]) if $count;
+ $counts{'total'} += $count;
+ }
+}
+sub count_libs {
+ my ($ref,$pos,$split) = @_;
+ my (@data);
+ my $i = 0;
+ $split ||= '\\s+';
+ #print scalar @$ref, '::', $split, '::', $pos, "\n";
+ foreach (@$ref){
+ @data = split /$split/, $_;
+ #print scalar @data, '::', $data[$pos], "\n";
+ $i++ if $data[$pos] && $data[$pos] =~ m%^lib%;
+ }
+ return $i;
+}
+}
# args: 1 - pci device string; 2 - pci cleaned subsystem string
sub get_pci_vendor {
@@ -18002,33 +19794,78 @@ sub get_shell_data {
# but at least one user dataset suggests otherwise so just do it for all.
$shell =~ s/^.*\///;
my $working = $ENV{'SHELL'};
- $working =~ s/^.*\///;
# NOTE: su -c "inxi -F" results in shell being su
- if (($shell eq 'sh' || $shell eq 'sudo' || $shell eq 'su' ) && $shell ne $working){
- $client{'su-start'} = $shell if ($shell eq 'sudo' || $shell eq 'su');
- $shell = $working;
- }
- #print "shell post: $shell\n";
- # sh because -v/--version doesn't work on it
- if ( $shell ne 'sh' ) {
- @app = main::program_values(lc($shell));
- if ($app[0]){
- $client{'version'} = main::program_version($shell,$app[0],$app[1],$app[2],$app[5],$app[6]);
- }
- # guess that it's two and --version
- else {
- # we're just guessing at the search phrase and position
- if ($shell){
- $client{'version'} = main::program_version($shell,$shell,2,'');
- }
- else {
- $client{'version'} = row_defaults('unknown-shell');
+ if ($shell eq 'sudo' || $shell eq 'su' ){
+ $client{'su-start'} = $shell;
+ $shell = get_shell_parent(get_start_parent($ppid));
+ }
+ if ($working){
+ $working =~ s/^.*\///;
+# if (($shell eq 'sh' || $shell eq 'sudo' || $shell eq 'su' ) && $shell ne $working){
+# $client{'su-start'} = $shell if ($shell eq 'sudo' || $shell eq 'su');
+# $shell = $working;
+# }
+ # a few manual changes for known
+ # Note: parent when fizsh shows as zsh but SHELL is fizsh, but other times
+ # SHELL is default shell, but in zsh, SHELL is default shell, not zfs
+ if ($shell eq 'zsh' && $working eq 'fizsh' ){
+ $shell = $working;
+ }
+ }
+ # print "shell post: $shell working: $working\n";
+ # since there are endless shells, we'll keep a list of non program value
+ # set shells since there is little point in adding those to program values
+ if (test_shell($shell)){
+ # do nothing, just leave $shell as is
+ }
+ # note: not all programs return version data. This may miss unhandled shells!
+ elsif ((@app = program_data(lc($shell),lc($shell),1)) && $app[0]){
+ $shell = $app[0];
+ $client{'version'} = $app[1] if $app[1];
+ #print "app test $shell v: $client{'version'}\n";
+ }
+ else {
+ # NOTE: we used to guess here with position 2 --version but this cuold lead
+ # to infinite loops when inxi called from a script 'infos' that is in PATH and
+ # script does not have any start arg handlers or bad arg handlers:
+ # eg: shell -> infos -> inxi -> sh -> infos --version -> infos -> inxi...
+ # Basically here we are hoping that the grandparent is a shell, or at least
+ # recognized as a known possible program
+ #print "app not shell?: $shell\n";
+ if ($shell){
+ # print 'shell: ' . $shell .' Start client version type: ', get_shell_parent(get_start_parent(getppid())), "\n";
+ my $parent = get_shell_parent(get_start_parent($ppid));
+ if ($parent){
+ if (test_shell($parent)){
+ $shell = $parent;
+ }
+ elsif ((@app = program_data(lc($parent),lc($parent),0)) && $app[0]){
+ $shell = $app[0];
+ $client{'version'} = $app[1] if $app[1];
+ }
+ #print "shell3: $shell version: $client{'version'}\n";
}
}
- $client{'version'} =~ s/(\(.*|-release|-version)//;
+ else {
+ $client{'version'} = row_defaults('unknown-shell');
+ }
+ #print "shell not app version: $client{'version'}\n";
}
+ $client{'version'} ||= '';
+ $client{'version'} =~ s/(\(.*|-release|-version)// if $client{'version'};
$client{'name'} = lc($shell);
$client{'name-print'} = $shell;
+ #print "shell4: $client{'name-print'} version: $client{'version'}\n";
+ if ($extra > 2 && $working && lc($shell) ne lc($working)){
+ if (@app = program_data(lc($working))){
+ $client{'default-shell'} = $app[0];
+ $client{'default-shell-v'} = $app[1];
+ $client{'default-shell-v'} =~ s/(\(.*|-release|-version)// if $client{'default-shell-v'};
+ }
+ else {
+ $client{'default-shell'} = $working;
+ }
+ }
}
else {
$client{'name'} = 'shell';
@@ -18037,6 +19874,19 @@ sub get_shell_data {
$client{'su-start'} = 'sudo' if (!$client{'su-start'} && $ENV{'SUDO_USER'});
eval $end if $b_log;
}
+# list of program_values non-handled shells, or known to have no version
+# Move shell to set_program_values for print name, or version if available
+sub test_shell {
+ my ($test) = @_;
+ # not verified or tested
+ my $shells = 'apush|ccsh|ch|esh|eshell|heirloom|hush|';
+ $shells .= 'ion|imrsh|larryshell|mrsh|msh(ell)?|murex|nsh|nu(shell)?|';
+ $shells .= 'psh|pwsh|pysh(ell)?|rush|sash|';
+ # tested shells with no version info discovered
+ $shells .= 'es|rc|scsh|sh';
+ return '|' . $shells if $test eq 'return';
+ return ($test =~ /^($shells)$/) ? $test : '';
+}
sub get_shell_source {
eval $start if $b_log;
@@ -18059,13 +19909,16 @@ sub get_shell_source {
}
# in case sudo starts inxi, parent is shell (or perl inxi if run by debugger)
# so: perl (2) started pinxi with sudo (3) in sh (4) in terminal
+ my $shells = 'ash|bash|busybox|cicada|csh|dash|elvish|fish|fizsh|ksh|ksh93|';
+ $shells .= 'lksh|loksh|mksh|nash|oh|oil|osh|pdksh|perl|posh|';
+ $shells .= 'su|sudo|tcsh|xonsh|yash|zsh';
+ $shells .= test_shell('return');
for my $i (2..4){
- if ( $shell_parent &&
- $shell_parent =~ /^(ash|bash|csh|dash|ksh|lksh|loksh|mksh|pdksh|perl|sh|su|sudo|tcsh|zsh)$/ ){
+ if ( $shell_parent && $shell_parent =~ /^($shells)$/ ){
# no idea why have to do script_parent action twice in su case, but you do.
$self_parent = get_start_parent($self_parent);
$shell_parent = get_shell_parent($self_parent);
- #print "shell parent 2: $shell_parent\n";
+ #print "self::shell parent 2-${i}: $self_parent :: $shell_parent\n";
if ($b_log){
$msg = ($shell_parent) ? "shell parent $i: $shell_parent": "shell parent $i: undefined";
log_data('data',$msg);
@@ -18093,6 +19946,7 @@ sub get_shell_source {
sub get_start_parent {
eval $start if $b_log;
my ($parent) = @_;
+ return 0 if !$parent;
# ps -j -fp : bsds ps do not have -f for PPID, so we can't get the ppid
my $cmd = "ps -j -fp $parent 2>/dev/null";
log_data('cmd',$cmd) if $b_log;
@@ -18107,6 +19961,7 @@ sub get_start_parent {
sub get_shell_parent {
eval $start if $b_log;
my ($parent) = @_;
+ return '' if !$parent;
my $cmd = "ps -j -p $parent 2>/dev/null";
log_data('cmd',$cmd) if $b_log;
my @data = grabber($cmd,'','strip');
@@ -18640,8 +20495,9 @@ sub check_audio {
else {return 0}
}
sub check_graphics {
- if ( ( $_[1] && length($_[1]) == 4 && $_[1] =~/^03/ ) ||
- ( $_[0] && $_[0] =~ /^(vga|display|hdmi|3d)$/)){
+ # note: multimedia class 04 is viddeo if 0400. 'tv' is risky I think
+ if ( ( $_[1] && length($_[1]) == 4 && ($_[1] =~/^03/ || $_[1] eq '0400' ) ) ||
+ ( $_[0] && $_[0] =~ /^(vga|display|hdmi|3d|video|tv|television)$/)){
return 1;
}
else {return 0}
@@ -18672,7 +20528,7 @@ sub soc_type {
my ($type,$info,$driver) = @_;
# I2S or i2s. I2C is i2 controller |[iI]2[Ss]. note: odroid hdmi item is sound only
# snd_soc_dummy. simple-audio-amplifier driver: speaker_amp
- if ($type =~ /^(daudio|.*hifi.*|.*sound[\-_]card|.*dac[0-9]?)$/ ||
+ if ($type =~ /^(daudio|.*hifi.*|.*sound[_-]card|.*dac[0-9]?)$/ ||
($info && $info !~ /amp|codec|dummy/ && $info =~ /(sound|audio)/) ||
($driver && $driver !~ /(codec|dummy)/ && $driver =~ /(audio|snd|sound)/) ){
$type = 'audio';
@@ -18863,7 +20719,7 @@ sub set_dmidecode_data {
# about random dmi type ordering in the data, which happens. Also sort
# by handle, as secondary sort.
@dmi = sort { $a->[0] <=> $b->[0] || $a->[1] <=> $b->[1] } @dmi;
- main::log_data('dump','@dmi',\@dmi) if $b_log;
+ log_data('dump','@dmi',\@dmi) if $b_log;
print Dumper \@dmi if $test[2];
eval $end if $b_log;
}
@@ -18929,7 +20785,7 @@ sub set_ip_addr {
@temp = ($if,[@ips]);
@ifs = (@ifs,@temp);
}
- main::log_data('dump','@ifs',\@ifs) if $b_log;
+ log_data('dump','@ifs',\@ifs) if $b_log;
print Dumper \@ifs if $test[3];
eval $end if $b_log;
}
@@ -19030,8 +20886,8 @@ sub set_ifconfig {
}
print Dumper \@ifs if $test[3];
print Dumper \@ifs_bsd if $test[3];
- main::log_data('dump','@ifs',\@ifs) if $b_log;
- main::log_data('dump','@ifs_bsd',\@ifs_bsd) if $b_log;
+ log_data('dump','@ifs',\@ifs) if $b_log;
+ log_data('dump','@ifs_bsd',\@ifs_bsd) if $b_log;
eval $end if $b_log;
}
@@ -19070,21 +20926,27 @@ sub set_ps_aux {
print Dumper \@ps_cmd if $test[5];
eval $end if $b_log;
}
+
sub set_ps_gui {
eval $start if $b_log;
$b_ps_gui = 1;
my ($working,@match,@temp);
- # desktops / wm
+ # desktops / wm (some wm also compositors)
if ($show{'system'}){
@temp=qw(razor-desktop razor-session lxsession lxqt-session
tdelauncher tdeinit_phase1);
@match = (@match,@temp);
- @temp=qw(3dwm 9wm afterstep amiwm awesome blackbox bspwm
- dwm fluxbox flwm flwm_topside fvwm.*-crystal fvwm2 fvwm i3 ion jwm lwm
- matchbox-window-manager mwm nawm openbox notion orbital pekwm perceptia
- qtile ratpoison sawfish scrotwm spectrwm sway tvtwm twm
+ @temp=qw(3dwm 9wm afterstep aewm aewm\+\+ amiwm antiwm awesome
+ blackbox bspwm
+ cagebreak calmwm (sh|c?lisp).*clfswm (openbsd-)?cwm dwm evilwm
+ fluxbox flwm flwm_topside fvwm.*-crystal fvwm1 fvwm2 fvwm3 fvwm95 fvwm
+ i3 instantwm ion3 jbwm jwm larswm lwm
+ matchbox-window-manager mini musca mwm nawm notion
+ openbox orbital pekwm perceptia python.*qtile qtile qvwm ratpoison
+ sawfish scrotwm spectrwm (sh|c?lisp).*stumpwm sway
+ tinywm tvtwm twm
waycooler way-cooler windowlab WindowMaker wm2 wmii2 wmii wmx
- xfdesktop xmonad);
+ xfdesktop xmonad yeahwm);
@match = (@match,@temp);
}
# wm:
@@ -19111,14 +20973,15 @@ sub set_ps_gui {
xfce4-panel xfce5-panel xmobar yabar);
@match = (@match,@temp);
}
- # compositors (for wayland these are also the server, note
- if ($show{'graphic'} && $extra > 1){
+ # compositors (for wayland these are also the server, note.
+ # for wayland always show, so always load these
+ if ($show{'graphic'} && $extra > 0){
@temp=qw(3dwm asc budgie-wm compiz compton deepin-wm dwc dcompmgr
enlightenment fireplace gnome-shell grefson kmscon kwin_wayland kwin_x11
liri marco metisse mir moblin motorcar muffin mutter
- orbital papyros perceptia rustland sommelier sway swc
+ orbital papyros perceptia picom rustland sommelier sway swc
ukwm unagi unity-system-compositor
- wavy waycooler way-cooler wayhouse westford weston xcompmgr);
+ wavy waycooler way-cooler wayfire wayhouse westford weston xcompmgr);
@match = (@match,@temp);
}
@match = uniq(@match);
@@ -19134,7 +20997,6 @@ sub set_ps_gui {
log_data('dump','@ps_gui',\@ps_gui) if $b_log;
eval $end if $b_log;
}
-
sub set_sysctl_data {
eval $start if $b_log;
return if $alerts{'sysctl'}{'action'} ne 'use';
@@ -19661,7 +21523,7 @@ sub generate_lines {
if ($b_log){
# I don't think we need to see this, it's long, but leave in case we do
#main::log_data('dump','@ps_aux',\@ps_aux);
- main::log_data('dump','@ps_cmd',\@ps_cmd);
+ log_data('dump','@ps_cmd',\@ps_cmd);
}
if ( $show{'short'} ){
set_dmesg_boot_data() if ($bsd_type && !$b_dmesg_boot_check);
@@ -19705,11 +21567,13 @@ sub generate_lines {
assign_data(%row);
}
if ( $show{'graphic'} ){
+ USBData::set() if !$b_usb_check;
DeviceData::set($b_pci_check) if !$b_pci_check;
%row = line_handler('Graphics','graphic');
assign_data(%row);
}
if ( $show{'audio'} ){
+ # Note: USBData is set internally in AudioData because it's only run in one case
DeviceData::set($b_pci_check) if !$b_pci_check;
%row = line_handler('Audio','audio');
assign_data(%row);
@@ -19735,6 +21599,10 @@ sub generate_lines {
%row = line_handler('Partition','partition');
assign_data(%row);
}
+ if ( $show{'swap'} ){
+ %row = line_handler('Swap','swap');
+ assign_data(%row);
+ }
if ( $show{'unmounted'} ){
%row = line_handler('Unmounted','unmounted');
assign_data(%row);
@@ -19789,12 +21657,13 @@ sub line_handler {
'process' => \&ProcessData::get,
'sensor' => \&SensorData::get,
'slot' => \&SlotData::get,
+ 'swap' => \&SwapData::get,
'unmounted' => \&UnmountedData::get,
'usb' => \&UsbData::get,
'weather' => \&WeatherData::get,
);
my (%data);
- my $data_name = main::key($prefix++,$key);
+ my $data_name = main::key($prefix++,1,0,$key);
my @rows = $subs{$sub}->($arg);
if (@rows){
%data = ($data_name => \@rows,);
@@ -19811,6 +21680,7 @@ sub generate_short_data {
eval $start if $b_log;
my $num = 0;
my $kernel_os = ($bsd_type) ? 'OS' : 'Kernel';
+ get_shell_data($client{'ppid'}) if $client{'ppid'};
my $client = $client{'name-print'};
my $client_shell = ($b_irc) ? 'Client' : 'Shell';
if ($client{'version'}){
@@ -19854,14 +21724,14 @@ sub generate_short_data {
if (@disk){
$size = $disk[0]{'size'};
# must be > 0
- if ($disk[0]{'size'} && main::is_numeric($disk[0]{'size'}) ){
+ if ($disk[0]{'size'} && is_numeric($disk[0]{'size'}) ){
$size_holder = $disk[0]{'size'};
@temp = get_size($size);
$size = $temp[0];
$size_type = " $temp[1]";
}
$used = $disk[0]{'used'};
- if (main::is_numeric($disk[0]{'used'}) ){
+ if (is_numeric($disk[0]{'used'}) ){
$used_holder = $disk[0]{'used'};
@temp = get_size($used);
$used = $temp[0];
@@ -19880,19 +21750,19 @@ sub generate_short_data {
#print join '; ', @cpu, " sleep: $cpu_sleep\n";
$memory ||= 'N/A';
my @data = ({
- main::key($num++,'CPU') => $cpu_string,
- main::key($num++,$speed_key) => $speed,
- main::key($num++,$kernel_os) => &get_kernel_data(),
- main::key($num++,'Up') => &get_uptime(),
- main::key($num++,'Mem') => $memory,
- main::key($num++,'Storage') => $disk_string,
+ main::key($num++,0,0,'CPU') => $cpu_string,
+ main::key($num++,0,0,$speed_key) => $speed,
+ main::key($num++,0,0,$kernel_os) => &get_kernel_data(),
+ main::key($num++,0,0,'Up') => &get_uptime(),
+ main::key($num++,0,0,'Mem') => $memory,
+ main::key($num++,0,0,'Storage') => $disk_string,
# could make -1 for ps aux itself, -2 for ps aux and self
- main::key($num++,'Procs') => scalar @ps_aux,
- main::key($num++,$client_shell) => $client,
- main::key($num++,$self_name) => &get_self_version(),
+ main::key($num++,0,0,'Procs') => scalar @ps_aux,
+ main::key($num++,0,0,$client_shell) => $client,
+ main::key($num++,0,0,$self_name) => &get_self_version(),
},);
my %row = (
- main::key($prefix,'SHORT') => [(@data),],
+ main::key($prefix,1,0,'SHORT') => [(@data),],
);
eval $end if $b_log;
return %row;
@@ -19907,11 +21777,9 @@ sub generate_info_data {
my $num = 0;
my $gcc_alt = '';
my $running_in = '';
- my $data_name = main::key($prefix++,'Info');
+ my $data_name = main::key($prefix++,1,0,'Info');
my ($b_gcc,$gcc,$index,$ref,%row);
my ($gpu_ram,$parent,$percent,$total,$used) = (0,'','','','');
- my $client_shell = ($b_irc) ? 'Client' : 'Shell';
- my $client = $client{'name-print'};
my @gccs = get_gcc_data();
if (@gccs){
$gcc = shift @gccs;
@@ -19921,31 +21789,14 @@ sub generate_info_data {
$b_gcc = 1;
}
$gcc ||= 'N/A';
- if (!$b_irc && $extra > 1 ){
- # bsds don't support -f option to get PPID
- if (($b_display && !$b_force_display) && !$bsd_type){
- $parent = get_shell_source();
- }
- else {
- $parent = get_tty_number();
- $parent = "tty $parent" if $parent ne '';
- }
- if ($parent eq 'login'){
- $client{'su-start'} = $parent if !$client{'su-start'};
- $parent = undef;
- }
- # can be tty 0 so test for defined
- $running_in = $parent if defined $parent;
- if ($extra > 2 && $running_in && get_ssh_status() ){
- $running_in .= ' (SSH)';
- }
- }
+ get_shell_data($client{'ppid'}) if $client{'ppid'};
+ my $client_shell = ($b_irc) ? 'Client' : 'Shell';
+ my $client = $client{'name-print'};
my %data = (
$data_name => [{
- main::key($num++,'Processes') => scalar @ps_aux,
- main::key($num++,'Uptime') => &get_uptime(),
-
- },],
+ main::key($num++,0,1,'Processes') => scalar @ps_aux,
+ main::key($num++,0,1,'Uptime') => &get_uptime(),
+ },],
);
$index = scalar(@{ $data{$data_name} } ) - 1;
if (!$b_mem){
@@ -19963,33 +21814,33 @@ sub generate_info_data {
$gpu_ram = $temp2[0] . ' ' . $temp2[1] if $temp2[1];
}
}
- $data{$data_name}[$index]{main::key($num++,'Memory')} = $total;
- $data{$data_name}[$index]{main::key($num++,'used')} = $used;
+ $data{$data_name}[$index]{main::key($num++,1,1,'Memory')} = $total;
+ $data{$data_name}[$index]{main::key($num++,0,2,'used')} = $used;
}
if ($gpu_ram){
- $data{$data_name}[$index]{main::key($num++,'gpu')} = $gpu_ram;
+ $data{$data_name}[$index]{main::key($num++,0,2,'gpu')} = $gpu_ram;
}
if ( (!$b_display || $b_force_display) || $extra > 0 ){
my %init = get_init_data();
my $init_type = ($init{'init-type'}) ? $init{'init-type'}: 'N/A';
- $data{$data_name}[$index]{main::key($num++,'Init')} = $init_type;
+ $data{$data_name}[$index]{main::key($num++,1,1,'Init')} = $init_type;
if ($extra > 1 ){
my $init_version = ($init{'init-version'}) ? $init{'init-version'}: 'N/A';
- $data{$data_name}[$index]{main::key($num++,'v')} = $init_version;
+ $data{$data_name}[$index]{main::key($num++,0,2,'v')} = $init_version;
}
if ($init{'rc-type'}){
- $data{$data_name}[$index]{main::key($num++,'rc')} = $init{'rc-type'};
+ $data{$data_name}[$index]{main::key($num++,1,2,'rc')} = $init{'rc-type'};
if ($init{'rc-version'}){
- $data{$data_name}[$index]{main::key($num++,'v')} = $init{'rc-version'};
+ $data{$data_name}[$index]{main::key($num++,0,3,'v')} = $init{'rc-version'};
}
}
if ($init{'runlevel'}){
- $data{$data_name}[$index]{main::key($num++,'runlevel')} = $init{'runlevel'};
+ $data{$data_name}[$index]{main::key($num++,0,2,'runlevel')} = $init{'runlevel'};
}
if ($extra > 1 ){
if ($init{'default'}){
my $default = ($init{'init-type'} eq 'systemd' && $init{'default'} =~ /[^0-9]$/ ) ? 'target' : 'default';
- $data{$data_name}[$index]{main::key($num++,$default)} = $init{'default'};
+ $data{$data_name}[$index]{main::key($num++,0,2,$default)} = $init{'default'};
}
}
}
@@ -20002,28 +21853,58 @@ sub generate_info_data {
$b_clang = 1;
}
my $compiler = ($b_gcc || $b_clang) ? '': 'N/A';
- $data{$data_name}[$index]{main::key($num++,'Compilers')} = $compiler;
+ $data{$data_name}[$index]{main::key($num++,1,1,'Compilers')} = $compiler;
if ($b_gcc){
- $data{$data_name}[$index]{main::key($num++,'gcc')} = $gcc;
+ $data{$data_name}[$index]{main::key($num++,1,2,'gcc')} = $gcc;
if ( $extra > 1 && $gcc_alt){
- $data{$data_name}[$index]{main::key($num++,'alt')} = $gcc_alt;
+ $data{$data_name}[$index]{main::key($num++,0,3,'alt')} = $gcc_alt;
}
}
if ($b_clang){
- $data{$data_name}[$index]{main::key($num++,'clang')} = $clang_version;
+ $data{$data_name}[$index]{main::key($num++,0,2,'clang')} = $clang_version;
+ }
+ }
+ if ($extra > 0 && !$b_pkg){
+ my %packages = PackageData::get('inner',\$num);
+ for (keys %packages){
+ $data{$data_name}[$index]{$_} = $packages{$_};
+ }
+ $b_pkg = 1;
+ }
+ if (!$b_irc && $extra > 1 ){
+ # bsds don't support -f option to get PPID
+ if (($b_display && !$b_force_display) && !$bsd_type){
+ $parent = get_shell_source();
+ }
+ else {
+ $parent = get_tty_number();
+ $parent = "tty $parent" if $parent ne '';
+ }
+ if ($parent eq 'login'){
+ $client{'su-start'} = $parent if !$client{'su-start'};
+ $parent = undef;
+ }
+ # can be tty 0 so test for defined
+ $running_in = $parent if defined $parent;
+ if ($extra > 2 && $running_in && get_ssh_status() ){
+ $running_in .= ' (SSH)';
}
}
if ($extra > 2 && $client{'su-start'}){
$client .= " ($client{'su-start'})";
}
- $data{$data_name}[$index]{main::key($num++,$client_shell)} = $client;
+ $data{$data_name}[$index]{main::key($num++,1,1,$client_shell)} = $client;
if ($extra > 0 && $client{'version'}){
- $data{$data_name}[$index]{main::key($num++,'v')} = $client{'version'};
+ $data{$data_name}[$index]{main::key($num++,0,2,'v')} = $client{'version'};
+ }
+ if ($extra > 2 && $client{'default-shell'}){
+ $data{$data_name}[$index]{main::key($num++,1,2,'default')} = $client{'default-shell'};
+ $data{$data_name}[$index]{main::key($num++,0,3,'v')} = $client{'default-shell-v'} if $client{'default-shell-v'};
}
if ( $running_in ){
- $data{$data_name}[$index]{main::key($num++,'running in')} = $running_in;
+ $data{$data_name}[$index]{main::key($num++,0,2,'running in')} = $running_in;
}
- $data{$data_name}[$index]{main::key($num++,$self_name)} = &get_self_version();
+ $data{$data_name}[$index]{main::key($num++,0,1,$self_name)} = &get_self_version();
eval $end if $b_log;
return %data;
@@ -20031,10 +21912,10 @@ sub generate_info_data {
sub generate_system_data {
eval $start if $b_log;
- my $num = 0;
+ my ($cont_desk,$ind_dm,$num) = (1,2,0);
my (%row,$ref,$index,$val1);
- my $data_name = main::key($prefix++,'System');
- my ($desktop,$desktop_info,$desktop_key,$toolkit,$wm) = ('','','Desktop','','');
+ my $data_name = main::key($prefix++,1,0,'System');
+ my ($desktop,$desktop_info,$desktop_key,$dm_key,$toolkit,$wm) = ('','','Desktop','dm','','');
my (@desktop_data,$desktop_version);
my %data = (
@@ -20042,25 +21923,28 @@ sub generate_system_data {
);
$index = scalar(@{ $data{$data_name} } ) - 1;
if ($show{'host'}){
- $data{$data_name}[$index]{main::key($num++,'Host')} = get_hostname();
+ $data{$data_name}[$index]{main::key($num++,0,1,'Host')} = get_hostname();
}
- $data{$data_name}[$index]{main::key($num++,'Kernel')} = get_kernel_data();
- $data{$data_name}[$index]{main::key($num++,'bits')} = get_kernel_bits();
+ $data{$data_name}[$index]{main::key($num++,1,1,'Kernel')} = get_kernel_data();
+ $data{$data_name}[$index]{main::key($num++,0,2,'bits')} = get_kernel_bits();
if ($extra > 0){
my @compiler = get_compiler_version(); # get compiler data
if (scalar @compiler != 2){
@compiler = ('N/A', '');
}
- $data{$data_name}[$index]{main::key($num++,'compiler')} = $compiler[0];
+ $data{$data_name}[$index]{main::key($num++,1,2,'compiler')} = $compiler[0];
# if no compiler, obviously no version, so don't waste space showing.
if ($compiler[0] ne 'N/A'){
$compiler[1] ||= 'N/A';
- $data{$data_name}[$index]{main::key($num++,'v')} = $compiler[1];
+ $data{$data_name}[$index]{main::key($num++,0,3,'v')} = $compiler[1];
}
}
if ($b_admin && (my $params = get_kernel_parameters())){
$index = scalar(@{ $data{$data_name} } );
- $data{$data_name}[$index]{main::key($num++,'parameters')} = $params;
+ #print "$params\n";
+ $params = apply_partition_filter('system', $params, 'label') if $use{'filter-label'};
+ $params = apply_partition_filter('system', $params, 'uuid') if $use{'filter-uuid'};
+ $data{$data_name}[$index]{main::key($num++,0,2,'parameters')} = $params;
$index = scalar(@{ $data{$data_name} } );
}
# note: tty can have the value of 0 but the two tools
@@ -20080,7 +21964,7 @@ sub generate_system_data {
}
# don't print the desktop if it's a wm and the same
if ($extra > 1 && $desktop_data[5] &&
- (!$desktop_data[0] || $desktop_data[5] =~ /^(deepin.+|gnome[\s\-_]shell|budgie.+)$/i ||
+ (!$desktop_data[0] || $desktop_data[5] =~ /^(deepin.+|gnome[\s_-]shell|budgie.+)$/i ||
index(lc($desktop_data[5]),lc($desktop_data[0])) == -1 )){
$wm = $desktop_data[5];
$wm .= ' ' . $desktop_data[6] if $extra > 2 && $desktop_data[6];
@@ -20097,34 +21981,39 @@ sub generate_system_data {
}
$desktop = "tty $tty" if $tty ne '';
$desktop_key = 'Console';
+ $dm_key = 'DM';
+ $ind_dm = 1;
+ $cont_desk = 0;
}
$desktop ||= 'N/A';
- $data{$data_name}[$index]{main::key($num++,$desktop_key)} = $desktop;
+ $data{$data_name}[$index]{main::key($num++,$cont_desk,1,$desktop_key)} = $desktop;
if ($toolkit){
- $data{$data_name}[$index]{main::key($num++,'tk')} = $toolkit;
+ $data{$data_name}[$index]{main::key($num++,0,2,'tk')} = $toolkit;
}
if ($extra > 2){
if ($desktop_info){
- $data{$data_name}[$index]{main::key($num++,'info')} = $desktop_info;
+ $data{$data_name}[$index]{main::key($num++,0,2,'info')} = $desktop_info;
}
}
if ($extra > 1){
- $data{$data_name}[$index]{main::key($num++,'wm')} = $wm if $wm;
+ $data{$data_name}[$index]{main::key($num++,0,2,'wm')} = $wm if $wm;
my $dms = get_display_manager();
- $dms ||= 'N/A';
- $data{$data_name}[$index]{main::key($num++,'dm')} = $dms;
+ if ($dms || $desktop_key ne 'Console'){
+ $dms ||= 'N/A';
+ $data{$data_name}[$index]{main::key($num++,0,$ind_dm,$dm_key)} = $dms;
+ }
}
#if ($extra > 2 && $desktop_key ne 'Console'){
# my $tty = get_tty_number();
- # $data{$data_name}[$index]{main::key($num++,'vc')} = $tty if $tty ne '';
+ # $data{$data_name}[$index]{main::key($num++,0,1,'vc')} = $tty if $tty ne '';
#}
my $distro_key = ($bsd_type) ? 'OS': 'Distro';
my @distro_data = DistroData::get();
my $distro = $distro_data[0];
$distro ||= 'N/A';
- $data{$data_name}[$index]{main::key($num++,$distro_key)} = $distro;
+ $data{$data_name}[$index]{main::key($num++,1,1,$distro_key)} = $distro;
if ($extra > 0 && $distro_data[1]){
- $data{$data_name}[$index]{main::key($num++,'base')} = $distro_data[1];
+ $data{$data_name}[$index]{main::key($num++,0,2,'base')} = $distro_data[1];
}
eval $end if $b_log;
return %data;
diff --git a/inxi.1 b/inxi.1
index 22b3677..8ae052f 100644
--- a/inxi.1
+++ b/inxi.1
@@ -1,21 +1,25 @@
-.TH INXI 1 "2019\-11\-19" inxi "inxi manual"
+.TH INXI 1 "2020\-08\-17" inxi "inxi manual"
+
.SH NAME
inxi \- Command line system information script for console and IRC
+
.SH SYNOPSIS
\fBinxi\fR
-\fBinxi\fR [\fB\-AbBCdDfFGhiIlmMnNopPrRsSuUVwzZ\fR]
+\fBinxi\fR [\fB\-AbBCdDfFGhijJIlmMnNopPrRsSuUVwzZ\fR]
\fBinxi\fR [\fB\-c NUMBER\fR] [\fB\-t\fR
+[\fB\-\-sensors\-exclude SENSORS\fR] [\fB\-\-sensors\-use SENSORS\fR]
[\fBc\fR|\fBm\fR|\fBcm\fR|\fBmc\fR][\fBNUMBER\fR]]
[\fB\-v NUMBER\fR] [\fB\-W LOCATION\fR]
[\fB\-\-weather\-unit\fR {\fBm\fR|\fBi\fR|\fBmi\fR|\fBim\fR}] [\fB\-y WIDTH\fR]
+
\fBinxi\fR [\fB\-\-memory\-modules\fR] [\fB\-\-memory\-short\fR]
-[\fB\-\-recommends\fR] [\fB\-\-slots\fR] [\fB\-\-usb\fR]
+[\fB\-\-recommends\fR] [\fB\-\-sensors\-default\fR] [\fB\-\-slots\fR]
-\fBinxi\fB [\fB\-x\fR|\fB\-xx\fR|\fB\-xxx\fR|\fB\-a\fR|\fB\-\-admin\fR] \fB\-OPTION(s)\fR
+\fBinxi\fB [\fB\-x\fR|\fB\-xx\fR|\fB\-xxx\fR|\fB\-a\fR] \fB\-OPTION(s)\fR
-All options have long form variants \- see below for these and more advanced options.
+All short form options have long form variants \- see below for these and more advanced options.
.SH DESCRIPTION
\fBinxi\fR is a command line system information script built for console
@@ -44,23 +48,28 @@ Options can be combined if they do not conflict. You can either group the letter
together or separate them.
Letters with numbers can have no gap or a gap at your discretion, except when
-using \fB \-t\fR.
+using \fB \-t\fR. Note that if you use an option that requires an additional
+argument, that must be last in the short form group of options. Otherwise
+you can use those separately as well.
For example:
-.B inxi
-\fB\-AG\fR or \fBinxi \-A \-G\fR or \fBinxi \-c10\fR
+\fBinxi \-AG\fR | \fBinxi \-A \-G\fR | \fBinxi \-b\fR | \fBinxi \-c10\fR
+| \fBinxi \-FxxzJy90\fR | \fBinxi \-bay\fR
Note that all the short form options have long form equivalents, which are
listed below. However, usually the short form is used in examples in order to
keep things simple.
.SH STANDARD OPTIONS
+
.TP
.B \-A\fR,\fB \-\-audio\fR
Show Audio/sound card(s) information, including card driver.
+
.TP
.B \-b\fR,\fB \-\-basic\fR
Show basic output, short form. Same as: \fBinxi \-v 2\fR
+
.TP
.B \-B\fR,\fB \-\-battery\fR
Show system battery (\fBID\-x\fR) data, charge, condition, plus extra information
@@ -99,27 +108,34 @@ piped or redirected. You must use the explicit runtime \fB\-c <color number>\fR
if you want color codes to be present in the piped/redirected output.
Color selectors for each type display (NOTE: IRC and global only show safe color set):
+
.TP
.B \-c 94\fR
\- Console, out of X.
+
.TP
.B \-c 95\fR
\- Terminal, running in X \- like xTerm.
+
.TP
.B \-c 96\fR
\- GUI IRC, running in X \- like XChat, Quassel,
Konversation etc.
+
.TP
.B \-c 97\fR
\- Console IRC running in X \- like irssi in xTerm.
+
.TP
.B \-c 98\fR
\- Console IRC not in X.
+
.TP
.B \-c 99\fR
\- Global \- Overrides/removes all settings.
Setting a specific color type removes the global color selection.
+
.TP
.B \-C\fR,\fB \-\-cpu\fR
Show full CPU output, including per CPU clock speed and CPU max speed (if available).
@@ -142,13 +158,17 @@ The details for each CPU include a technical description e.g. \fBtype: MT MCP\fR
* \fBUP\fR \- Uni (single core) Processor.
+Note that \fBmin/max:\fR speeds are not necessarily true in cases of overclocked CPUs
+or CPUs in turbo/boost mode. See \fB\-Ca\fR for alternate \fBbase/boost:\fR speed data.
+
.TP
.B \-d\fR,\fB \-\-disk\-full\fR,\fB\-\-optical\fR
Show optical drive data as well as \fB\-D\fR hard drive data. With \fB\-x\fR, adds a
feature line to the output. Also shows floppy disks if present. Note that there is
-no current way to get any information about the floppy device that I am aware of,
+no current way to get any information about the floppy device that we are aware of,
so it will simply show the floppy ID without any extra data. \fB\-xx\fR adds a
few more features.
+
.TP
.B \-D\fR,\fB \-\-disk\fR
Show Hard Disk info. Shows total disk space and used percentage. The disk used
@@ -160,21 +180,41 @@ Also, unmounted partitions are not counted in disk use percentages since inxi
has no access to the used amount.
Also shows per disk information: Disk ID, type (if present), vendor (if detected),
-model, and size. See \fBExtra Data Options\fR for more features.
+model, and size. See \fBExtra Data Options\fR (\fB\-x\fR options) and
+\fBAdmin Extra Data Options\fR (\fB\-\-admin\fR options) for many more features.
+
+.TP
+.B \-\-filter\fR,\fB \-\-filter\-override\fR \- See \fB\-z\fR, \fB\-Z\fR.
+
+.TP
+.B \-\-filter\-label\fR
+Filter partition label names from \fB\-j\fR, \fB\-o\fR, \fB\-p\fR,
+\fB\-P\fR, and \fB\-Sa\fR (root=LABEL=...). Generally only useful in
+very specialized cases.
+
+.TP
+.B \-\-filter\-uuid\fR
+Filter partition UUIDs from \fB\-j\fR, \fB\-o\fR, \fB\-p\fR,
+\fB\-P\fR, and \fB\-Sa\fR (root=UUID=...). Generally only useful in
+very specialized cases.
+
.TP
.B \-f\fR,\fB \-\-flags\fR
Show all CPU flags used, not just the short list. Not shown with \fB\-F\fR in order
to avoid spamming. ARM CPUs: show \fBfeatures\fR items.
+
.TP
.B \-F\fR,\fB \-\-full\fR
Show Full output for inxi. Includes all Upper Case line letters except \fB\-W\fR,
-plus \fB\-s\fR and \fB\-n\fR. Does not show extra verbose options such as
+plus \fB\-\-swap\fR, \fB\-s\fR and \fB\-n\fR. Does not show extra verbose options such as
\fB\-d \-f \-i \-l \-m \-o \-p \-r \-t \-u \-x\fR unless you use those arguments in
the command, e.g.: \fBinxi \-Frmxx\fR
+
.TP
.B \-G\fR,\fB \-\-graphics\fR
Show Graphic card(s) information, including details of card and card driver,
-display protocol (if available), display server (vendor and version number), e.g.:
+display protocol (if available), display server (and/or Wayland compositor),
+vendor and version number, e.g.:
\fBDisplay: x11 server: Xorg 1.15.1\fR
@@ -182,15 +222,18 @@ If protocol is not detected, shows:
\fBDisplay: server: Xorg 1.15.1\fR
-Also shows screen resolution(s), OpenGL renderer, OpenGL core profile version/OpenGL
-version.
+Also shows screen resolution(s) (per monitor/X screen), OpenGL renderer,
+OpenGL core profile version/OpenGL version.
+
+Compositor information will show if detected using \fB\-xx\fR option
+or always if detected and Wayland.
-Compositor information will show if detected using \fB\-xx\fR option.
.TP
.B \-h\fR,\fB \-\-help\fR
The help menu. Features dynamic sizing to fit into terminal window. Set script
global \fBCOLS_MAX_CONSOLE\fR if you want a different default value, or
use \fB\-y <width>\fR to temporarily override the defaults or actual window width.
+
.TP
.B \-i\fR,\fB \-\-ip\fR
Show WAN IP address and local interfaces (latter requires \fBifconfig\fR or
@@ -201,8 +244,8 @@ local/WAN IP. Shows both IPv4 and IPv6 link IP addresses.
.TP
.B \-I\fR,\fB \-\-info\fR
Show Information: processes, uptime, memory, IRC client (or shell type if run in
-shell, not IRC), inxi version. See \fB\-x\fR and \fB\-xx\fR for extra information
-(init type/version, runlevel).
+shell, not IRC), inxi version. See \fB\-Ix\fR, \fB\-Ixx\fR, and \fB\-Ia\fR
+for extra information (init type/version, runlevel, packages).
Note: if \fB\-m\fR is used or triggered, the memory item will show in the main
Memory: report of \fB\-m\fR, not in \fB\Info:\fR.
@@ -210,10 +253,37 @@ Memory: report of \fB\-m\fR, not in \fB\Info:\fR.
Rasberry Pi only: uses \fBvcgencmd get_mem gpu\fR to get gpu RAM amount,
if user is in video group and \fBvcgencmd\fR is installed. Uses
this result to increase the \fBMemory:\fR amount and \fBused:\fR amounts.
+
+.TP
+.B \-j\fR, \fB\-\-swap\fR
+Shows all active swap types (partition, file, zram). When this option is used,
+swap partition(s) will not show on the \fB\-P\fR line to avoid redundancy.
+
+.TP
+.B \-J\fR,\fB \-\-usb\fR
+Show USB data for attached Hubs and Devices. Hubs also show number of ports.
+Be aware that a port is not always external, some may be internal, and either
+used or unused (for example, a motherboard USB header connector that is not used).
+
+Hubs and Devices are listed in order of BusID.
+
+BusID is generally in this format: BusID\-port[.port][.port]:DeviceID
+
+Device ID is a number created by the kernel, and has no necessary ordering
+or sequence connection, but can be used to match this output to lsusb
+values, which generally shows BusID / DeviceID (except for tree view, which
+shows ports).
+
+Examples: \fBDevice\-3: 4\-3.2.1:2\fR or \fBHub: 4\-0:1\fR
+
+The \fBrev: 2.0\fR item refers to the USB revision number, like \fB1.0\fR or
+\fB3.1\fR.
+
.TP
.B \-l\fR,\fB \-\-label\fR
Show partition labels. Default: main partitions \fB\-P\fR. For full \fB\-p\fR output,
use: \fB\-pl\fR.
+
.TP
.B \-m\fR,\fB \-\-memory\fR
Memory (RAM) data. Does not display with \fB\-b\fR or \fB\-F\fR unless you use \fB\-m\fR
@@ -241,15 +311,18 @@ not dmi data. For most people, the data will be right, but a significant percent
users will have either a wrong max module size, if present, or max capacity.
See \fB\-\-memory\-modules\fR and \fB\-\-memory\-short\fR if you want a shorter report.
+
.TP
.B \-\-memory\-modules\fR
Memory (RAM) data. Show only RAM arrays and modules in Memory report.
Skip empty slots. See \fB\-m\fR.
+
.TP
.B \-\-memory\-short\fR
-Memory (RAM) data. Show a one line RAM report in Memory, e.g.
-\fBReport: arrays: 1 slots: 4 modules: 2 type: DDR4\fR
-See \fB\-m\fR.
+Memory (RAM) data. Show a one line RAM report in Memory. See \fB\-m\fR.
+
+Sample: \fBReport: arrays: 1 slots: 4 modules: 2 type: DDR4\fR
+
.TP
.B \-M\fR,\fB \-\-machine\fR
Show machine data. Device, Motherboard, BIOS, and if present, System Builder (Like Lenovo).
@@ -268,14 +341,17 @@ post an issue and we'll get it fixed if possible.
Due to unreliable vendor data, device type will show: desktop, laptop, notebook, server,
blade, plus some obscure stuff that inxi is unlikely to ever run on.
+
.TP
.B \-n\fR,\fB \-\-network\-advanced\fR
Show Advanced Network card information in addition to that produced by \fB\-N\fR.
Shows interface, speed, MAC ID, state, etc.
+
.TP
.B \-N\fR,\fB \-\-network\fR
Show Network card(s) information, including card driver. With \fB\-x\fR, shows PCI BusID,
Port number.
+
.TP
.B \-o\fR,\fB \-\-unmounted\fR
Show unmounted partition information (includes UUID and LABEL if available).
@@ -286,14 +362,22 @@ if you have added to \fB/etc/sudoers\fR (sudo v. 1.7 or newer):
.B <username> ALL = NOPASSWD: /usr/bin/file (sample)
Does not show components (partitions that create the md\-raid array) of md\-raid arrays.
+
.TP
.B \-p\fR,\fB \-\-partitions\-full\fR
Show full Partition information (\fB\-P\fR plus all other detected mounted partitions).
+
.TP
.B \-P\fR,\fB \-\-partitions\fR
Show basic Partition information.
Shows, if detected: \fB/ /boot /home /opt /tmp /usr /usr/home /var /var/tmp /var/log\fR.
+If \fB\-\-swap\fR is not used, shows active swap partitions (never shows file or
+zram type swap).
Use \fB\-p\fR to see all mounted partitions.
+
+.TP
+.B \-\-processes\fR \- See \fB\-t\fR
+
.TP
.B \-r\fR,\fB \-\-repos\fR
Show distro repository data. Currently supported repo types:
@@ -301,7 +385,7 @@ Show distro repository data. Currently supported repo types:
\fBAPK\fR (Alpine Linux + derived versions)
\fBAPT\fR (Debian, Ubuntu + derived versions, as well as RPM based
-APT distros like PCLinuxOS or Alt-Linux)
+APT distros like PCLinuxOS or Alt\-Linux)
\fBCARDS\fR (NuTyX + derived versions)
@@ -321,7 +405,7 @@ APT distros like PCLinuxOS or Alt-Linux)
\fBTCE\fR (TinyCore)
-\fBURPMQ\fR (Mandriva, Mageia + derived versions)
+\fBURPMI\fR (Mandriva, Mageia + derived versions)
\fBXBPS\fR (Void)
@@ -329,6 +413,9 @@ APT distros like PCLinuxOS or Alt-Linux)
More will be added as distro data is collected. If yours is missing please
show us how to get this information and we'll try to add it.
+
+See \fB\-rx\fR, \fB\-rxx\fR, and \fB\-ra\fR for installed package count information.
+
.TP
.B \-R\fR,\fB \-\-raid\fR
Show RAID data. Shows RAID devices, states, levels and components, and
@@ -348,22 +435,30 @@ if there is demand, and reasonable reporting tools.
.B \-\-recommends\fR
Checks inxi application dependencies and recommends, as well as directories,
then shows what package(s) you need to install to add support for each feature.
+
.TP
.B \-s\fR,\fB \-\-sensors\fR
Show output from sensors if sensors installed/configured: Motherboard/CPU/GPU
temperatures; detected fan speeds. GPU temperature when available. Nvidia shows
screen number for multiple screens. IPMI sensors are also used (root required)
-if present.
+if present. See Advanced options \fB\-\-sensors\-use\fR or
+\fB\-\-sensors\-exclude\fR if you want to use only a subset of all sensors, or
+exclude one.
.
.TP
.B \-\-slots\fR
Show PCI slots with type, speed, and status information.
+
+.TP
+.B \-\-swap\fR \- See \fB\-j\fR
+
.TP
.B \-S\fR,\fB \-\-system\fR
Show System information: host name, kernel, desktop environment (if in X),
distro. With \fB\-xx\fR show dm \- or startx \- (only shows if present and
running if out of X), and if in X, with \fB\-xxx\fR show more desktop info,
e.g. taskbar or panel.
+
.TP
.B \-t\fR,\fB \-\-processes\fR
[\fBc\fR|\fBm\fR|\fBcm\fR|\fBmc NUMBER\fR] Show processes. If no arguments, defaults to \fBcm\fR.
@@ -371,43 +466,27 @@ If followed by a number, shows that number of processes for each type
(default: \fB5\fR; if in IRC, max: \fB5\fR)
Make sure that there is no space between letters and numbers (e.g. write as \fB\-t cm10\fR).
+
.TP
.B \-t c\fR
\- CPU only. With \fB\-x\fR, also shows memory for that process on same line.
+
.TP
.B \-t m\fR
\- memory only. With \fB\-x\fR, also shows CPU for that process on same line.
If the \-I line is not triggered, will also show the system RAM used/total
information.
+
.TP
.B \-t cm\fR
\- CPU+memory. With \fB\-x\fR, shows also CPU or memory for that process on
same line.
.TP
-.B \-\-usb\fR
-Show USB data for attached Hubs and Devices. Hubs also show number of ports.
-Be aware that a port is not always external, some may be internal, and either
-used or unused (for example, a motherboard USB header connector that is not used).
-
-Hubs and Devices are listed in order of BusID.
-
-BusID is generally in this format: BusID-port[.port][.port]:DeviceID
-
-Device ID is a number created by the kernel, and has no necessary ordering
-or sequence connection, but can be used to match this output to lsusb
-values, which generally shows BusID / DeviceID (except for tree view, which
-shows ports).
-
-Examples: \fBDevice-3: 4-3.2.1:2\fR or \fBHub: 4-0:1\fR
-
-The \fBrev: 2.0\fR item refers to the USB revision number, like \fB1.0\fR or
-\fB3.1\fR.
-
-.TP
.B \-u\fR,\fB \-\-uuid\fR
Show partition UUIDs. Default: main partitions \fB\-P\fR. For full \fB\-p\fR
output, use: \fB\-pu\fR.
+
.TP
.B \-U\fR,\fB \-\-update\fR
Note \- Maintainer may have disabled this function.
@@ -423,51 +502,65 @@ to that directory. See \fB\-\-man\fR or \fB\-\-no\-man\fR to force or disable
man install.
.TP
-.B \-V\fR,\fB \-\-version\fR
+.B \-\-usb\fR \- See \fB\-J\fR
+
+.TP
+.B \-V\fR, \fB\-\-version\fR
inxi version information. Prints information then exits.
+
.TP
.B \-v\fR,\fB \-\-verbosity\fR
Script verbosity levels. If no verbosity level number is given, 0 is assumed.
Should not be used with \fB\-b\fR or \fB\-F\fR.
Supported levels: \fB0\-8\fR Examples :\fB inxi \-v 4 \fR or \fB inxi \-v4\fR
+
.TP
.B \-v 0
\- Short output, same as: \fBinxi\fR
+
.TP
.B \-v 1
\- Basic verbose, \fB\-S\fR + basic CPU (cores, type, clock speed, and min/max
speeds, if available) + \fB\-G\fR + basic Disk + \fB\-I\fR.
+
.TP
.B \-v 2
\- Adds networking card (\fB\-N\fR), Machine (\fB\-M\fR) data, Battery (\fB\-B\fR)
(if available). Same as: \fBinxi \-b\fR
+
.TP
.B \-v 3
\- Adds advanced CPU (\fB\-C\fR) and network (\fB\-n\fR) data; triggers \fB\-x\fR
advanced data option.
+
.TP
.B \-v 4
\- Adds partition size/used data (\fB\-P\fR) for (if present):
\fB/ /home /var/ /boot\fR. Shows full disk data (\fB\-D\fR)
+
.TP
.B \-v 5
\- Adds audio card (\fB\-A\fR), memory/RAM (\fB\-m\fR), sensors (\fB\-s\fR),
-partition label (\fB\-l\fR), UUID (\fB\-u\fR), and short form of
-optical drives.
+partition label (\fB\-l\fR), UUID (\fB\-u\fR), full swap data (\fB\-j\fR),
+and short form of optical drives.
+
.TP
.B \-v 6
-\- Adds full mounted partition data (\fB\-p\fR), unmounted partition data (\fB\-o\fR),
-optical drive data (\fB\-d\fR), USB (\fB\-\-usb\fR); triggers \fB\-xx\fR extra data
-option.
+\- Adds full mounted partition data (\fB\-p\fR),
+unmounted partition data (\fB\-o\fR), optical drive data (\fB\-d\fR),
+USB (\fB\-J\fR); triggers \fB\-xx\fR extra data option.
+
.TP
.B \-v 7
\- Adds network IP data (\fB\-i\fR); triggers \fB\-xxx\fR
+
.TP
.B \-v 8
\- All system data available. Adds Repos (\fB\-r\fR), PCI slots (\fB\-\-slots\fR),
processes (\fB\-tcm\fR), admin (\fB\-\-admin\fR). Useful for testing output and to
see what data you can get from your system.
+
.TP
.B \-w\fR,\fB \-\-weather\fR
Adds weather line. To get weather for an alternate location, use
@@ -478,6 +571,7 @@ DO NOT USE THIS FEATURE FOR AUTOMATED WEATHER UPDATES! You will be blocked
from any further access. This feature is not meant for widget type
weather monitoring, or Conky type use. It is meant to get weather when you need to
see it, for example, on a remote server.
+
.TP
.B \-W\fR, \fB\-\-weather\-location <location_string>\fR
Get weather/time for an alternate location. Accepts postal/zip code[, country],
@@ -488,7 +582,7 @@ Try postal codes with and without country code added. Note that City,State appli
only to USA, otherwise it's City,Country. If country name (english) does not work,
try 2 character country code (e.g. Spain: es; Great Britain: gb).
-See \fIhttps://en.wikipedia.org/wiki/ISO_3166-1_alpha-2\fR for current 2 letter
+See \fIhttps://en.wikipedia.org/wiki/ISO_3166\-1_alpha\-2\fR for current 2 letter
country codes.
Use only ASCII letters in city/state/country names.
@@ -499,6 +593,7 @@ Examples: \fB\-W 95623,us\fR OR \fB\-W Boston,MA\fR OR
DO NOT USE THIS FEATURE FOR AUTOMATED WEATHER UPDATES! Use of automated queries,
will result in your access being blocked. If you try to work around the ban, you
will be permanently banned from this service.
+
.TP
.B \-\-weather\-source\fR, \fB\-\-ws <unit>\fR
[\fB1\-9\fR] Switches weather data source. Possible values are \fB1\-9\fR. \fB1\-4\fR
@@ -512,25 +607,37 @@ or be removed, so always test to verify which source is being used for each valu
if that is important to you. Data sources may be added or removed on occasions, so
try each one and see which you prefer. If you get unsupported source message, it means
that number has not been implemented.
+
.TP
.B \-\-weather\-unit <unit>\fR
[\fBm\fR|\fBi\fR|\fBmi\fR|\fBim\fR] Sets weather units to metric (\fBm\fR), imperial (\fBi\fR),
metric (imperial) (\fBmi\fR, default), imperial (metric) (\fBim\fR). If metric or imperial
not found,sets to default value, or \fBN/A\fR.
+
.TP
-.B \-y\fR,\fB \-\-width <integer>\fR
+.B \-y\fR,\fB \-\-width [integer]\fR
This is an absolute width override which sets the output line width max.
Overrides \fBCOLS_MAX_IRC\fR / \fBCOLS_MAX_CONSOLE\fR globals, or the
actual widths of the terminal. \fB80\fR is the minimum width supported.
-\fB\-1\fR removes width limits. Example: \fBinxi \-Fxx\ \-y 130\fR
+\fB\-1\fR removes width limits. 1 switches to a single indented key/value
+pair per line, and removes all long line wrapping (similar to
+\fBdmidecode\fR output).
+
+If no integer value is given, sets width to default of 80.
+
+Examples: \fBinxi \-Fxx\ \-y 130\fR or \fBinxi \-Fxxy\fR or \fBinxi \-bay1\fR
+
.TP
.B \-z\fR,\fB \-\-filter\fR
Adds security filters for IP addresses, serial numbers, MAC,
-location (\fB\-w\fR), and user home directory name. On by default for IRC clients.
+location (\fB\-w\fR), and user home directory name. Removes Host:.
+On by default for IRC clients.
+
.TP
.B \-Z\fR,\fB \-\-filter\-override\fR
Absolute override for output filters. Useful for debugging networking
issues in IRC for example.
+
.SH EXTRA DATA OPTIONS
These options can be triggered by one or more \fB\-x\fR.
Alternatively, the \fB\-v\fR options trigger them in the following
@@ -551,6 +658,7 @@ OR
The following details show which lines / items display extra information for each
extra data level.
+
.TP
.B \-x \-A\fR
\- Adds (if available and/or relevant) \fBvendor:\fR item, which shows
@@ -560,12 +668,14 @@ specific vendor [product] information.
device.
\- Adds PCI Bus ID/USB ID number of each Audio device.
+
.TP
.B \-x \-B\fR
\- Adds vendor/model, battery status (if battery present).
\- Adds attached battery powered peripherals (\fBDevice\-[number]:\fR) if
detected (keyboard, mouse, etc.).
+
.TP
.B \-x \-C\fR
\- Adds bogomips on CPU (if available)
@@ -577,16 +687,19 @@ etc.). Only shows data if detected. Newer microarchitectures will have
to be added as they appear, and require the CPU family ID and model ID.
Examples: \fBarch: Sandy Bridge rev: 2\fR, \fBarch: K8 rev.F+ rev: 2\fR
+
.TP
.B \-x \-d\fR
\- Adds more items to \fBFeatures\fR line of optical drive;
dds rev version to optical drive.
+
.TP
.B \-x \-D\fR
\- Adds HDD temperature with disk data if you have hddtemp installed, if you are root
or if you have added to \fB/etc/sudoers\fR (sudo v. 1.7 or newer):
.B <username> ALL = NOPASSWD: /usr/sbin/hddtemp (sample)
+
.TP
.B \-x \-G\fR
\- Adds (if available and/or relevant) \fBvendor:\fR item, which shows
@@ -597,12 +710,13 @@ specific vendor [product] information.
\- Adds (for single GPU, nvidia driver) screen number that GPU is running on.
\- Adds PCI Bus ID/USB ID number of each Graphics card.
+
.TP
.B \-x \-i\fR
\- Adds IP v6 additional scope data, like Global, Site, Temporary for
each interface.
-Note that there is no way I am aware of to filter out the deprecated
+Note that there is no way we are aware of to filter out the deprecated
IP v6 scope site/global temporary addresses from the output of
\fBifconfig\fR. The \fBip\fR tool shows that clearly.
@@ -632,7 +746,20 @@ versions.
\- Adds current runlevel (not available with all init systems).
+\- Adds total packages discovered in system. See \fB\-xx\fR and \fB\-a\fR
+for per package manager types output. Moves to \fBRepos\fR if \fB\-rx\fR.
+
+If your package manager is not supported, please file an issue and we'll add it.
+That requires the full output of the query or method to discover all installed
+packages on your system, as well of course as the command or method used to
+discover those.
+
\- If in shell (i.e. not in IRC client), adds shell version number, if available.
+
+.TP
+.B \-x \-J\fR (\fB\-\-usb\fR)
+\- For Devices, adds driver(s).
+
.TP
.B \-x \-m\fR, \fB\-\-memory\-modules\fR
\- If present, adds maximum memory module/device size in the Array line.
@@ -640,6 +767,7 @@ Only some systems will have this data available. Shows estimate if it can
generate one.
\- Adds device type in the Device line.
+
.TP
.B \-x \-N\fR
\- Adds (if available and/or relevant) \fBvendor:\fR item, which shows
@@ -648,15 +776,22 @@ specific vendor [product] information.
\- Adds version/port(s)/driver version (if available) for each Network card;
\- Adds PCI Bus ID/USB ID number of each Network card.
+
+.TP
+.B \-x \-r\fR
+\- Adds Package info. See \fB\-Ix\fR
+
.TP
.B \-x \-R\fR
\- md\-raid: Adds second RAID Info line with extra data: blocks, chunk size,
bitmap (if present). Resync line, shows blocks synced/total blocks.
\- Hardware RAID: Adds driver version, bus ID.
+
.TP
.B \-x \-s\fR
\- Adds basic voltages: 12v, 5v, 3.3v, vbat (\fBipmi\fR, \fBlm-sensors\fR if present).
+
.TP
.B \-x \-S\fR
\- Adds Kernel gcc version.
@@ -666,29 +801,32 @@ a subset of distributions. The distro must be both derived from a parent distro
Ubuntu), and explicitly added to the supported distributions for this feature. Due to
the complexity of distribution identification, these will only be added as relatively solid
methods are found for each distribution system base detection.
+
.TP
-.B \-x \-t\fR
+.B \-x \-t\fR (\fB\-\-processes\fR)
\- Adds memory use output to CPU (\fB\-xt c\fR), and CPU use to memory
(\fB\-xt m\fR).
-.TP
-.B \-x \-\-usb\fR
-\- For Devices, adds driver(s).
+
.TP
.B \-x \-w\fR,\fB \-W\fR
\- Adds humidity and barometric pressure.
\- Adds wind speed and direction.
+
.TP
.B \-xx \-A\fR
\- Adds vendor:product ID for each Audio device.
+
.TP
.B \-xx \-B\fR
\- Adds serial number, voltage (if available). Note that \fBvolts\fR shows the
data (if available) as the voltage now / minimum design voltage.
+
.TP
.B \-xx \-C\fR
\- Adds \fBL1 cache:\fR and \fBL3 cache:\fR if either are available. Requires
dmidecode and sudo/root.
+
.TP
.B \-xx \-D\fR
\- Adds disk serial number.
@@ -709,11 +847,12 @@ For a PCIe 3 NVMe drive, with speed of \fB8 GT/s\fR and \fB4\fR lanes
(\fB8GT/s * 128/130 * 4 = 31.6 Gb/s\fR):
\fBspeed: 31.6 Gb/s lanes: 4\fR
+
.TP
.B \-xx \-G\fR
\- Adds vendor:product ID of each Graphics card.
-\- Adds compositor, if found (experimental).
+\- Adds Xorg compositor, if found (always shows for Wayland systems).
\- For free drivers, adds OpenGL compatibility version number if available.
For nonfree drivers, the core version and compatibility versions are usually
@@ -730,6 +869,10 @@ and loaded when checking the card. This can let you know there are other driver
Note that if you have explicitly set the driver in \fBxorg.conf\fR, Xorg will not
create this automatic check driver list.
+\- If available, shows Xorg dpi (\fBs-dpi:\fR) for the active Xorg \fBScreen\fR
+(not physical monitor). Note that the physical monitor dpi and the Xorg
+dpi are not necessarily the same thing, and can vary widely.
+
.TP
.B \-xx \-I\fR
\- Adds init type version number (and rc if present).
@@ -739,7 +882,22 @@ create this automatic check driver list.
\- Adds system default runlevel, if detected. Supports Systemd/Upstart/SysVinit
type defaults.
+\- Shows \fBPackages:\fR counts by discovered package manager types. In cases where
+only 1 type had results, does not show total after \fBPackages:\fR. Does not
+show installed package managers wtih 0 packages. See \fB\-a\fR for full output.
+Moves to \fBRepos\fR if \fB\-rxx\fR.
+
\- Adds parent program (or tty) that started shell, if not IRC client.
+
+.TP
+.B \-xx \-j\fR (\fB\-\-swap\fR), \fB\-xx \-p\fR, \fB\-xx \-P\fR
+\- Adds swap priority to each swap partition (for \fB\-P\fR) used, and for all
+swap types (for \fB\-j\fR).
+
+.TP
+.B \-xx \-J\fR (\fB\-\-usb\fR)
+\- Adds vendor:chip id.
+
.TP
.B \-xx \-m\fR, \fB\-\-memory\-modules\fR
\- Adds memory device Manufacturer.
@@ -752,22 +910,31 @@ also shows serial number.
\- Adds single/double bank memory, if data is found. Note, this may not be 100% right
all of the time since it depends on the order that data is found in \fBdmidecode\fR
output for \fBtype 6\fR and \fBtype 17\fR.
+
.TP
.B \-xx \-M\fR
\- Adds chassis information, if data is available. Also shows BIOS
ROM size if using \fBdmidecode\fR.
+
.TP
.B \-xx \-N\fR
\- Adds vendor:product ID for each Network card.
+
+.TP
+.B \-xx \-r\fR
+\- Adds Packages info. See \fB\-Ixx\fR
+
.TP
.B \-xx \-R\fR
\- md\-raid: Adds superblock (if present) and algorithm. If resync,
shows progress bar.
\- Hardware RAID: Adds Chip vendor:product ID.
+
.TP
.B \-xx \-s\fR
\- Adds DIMM/SOC voltages, if present (\fBipmi\fR only).
+
.TP
.B \-xx \-S\fR
\- Adds display manager (\fBdm\fR) type, if present. If none, shows N/A.
@@ -781,21 +948,22 @@ If none found, shows nothing. Uses a less accurate fallback tool \fBwmctrl\fR
if \fBps\fR tests fail to find data.
\- Adds desktop toolkit (\fBtk\fR), if available (Xfce/KDE/Trinity).
+
.TP
.B \-xx \-\-slots\fR
\- Adds slot length.
-.TP
-.B \-xx \-\-usb\fR
-\- Adds vendor:chip id.
+
.TP
.B \-xx \-w\fR,\fB \-W\fR
\- Adds wind chill, heat index, and dew point, if available.
\- Adds cloud cover, rain, snow, or precipitation (amount in previous hour
to observation time), if available.
+
.TP
.B \-xxx \-A\fR
\- Adds, if present, serial number.
+
.TP
.B \-xxx \-B\fR
\- Adds battery chemistry (e.g. \fBLi\-ion\fR), cycles (NOTE: there appears to
@@ -805,10 +973,15 @@ data is simply not available as of 2018\-04\-03), location (only available from
\fBdmidecode\fR derived output).
\- Adds attached device \fBrechargeable: [yes|no]\fR information.
+
.TP
.B \-xxx \-C\fR
\- Adds \fBboost: [enabled|disabled]\fR if detected, aka \fBturbo\fR. Not all CPUs
have this feature.
+
+\- Adds CPU voltage and external clock speed (this is the motherboard speed).
+Requires sudo/root and \fBdmidecode\fR.
+
.TP
.B \-xxx \-D\fR
\- Adds disk firmware revision number (if available).
@@ -820,15 +993,25 @@ able to detect all schemes, but handles the most common, e.g. \fBGPT\fR or \fBMB
Only appears if detected (SSD drives do not have rotation speeds, for example). If none
found, nothing shows. Not all disks report this speed, so even if they are spinnning,
no data will show.
-.TP
-.B \-xxx \-G\fR
-\- Adds (if available) \fBcompositor:\fR version \fBv:\fR.
+
.TP
.B \-xxx \-I\fR
\- For \fBShell:\fR adds \fB(su|sudo|login)\fR to shell name if present.
+\- For \fBShell:\fR adds \fBdefault:\fR shell if different from
+running shell, and default shell \fBv:\fR, if available.
+
\- For \fBrunning in:\fR adds \fB(SSH)\fR to parent, if present. SSH detection
uses the \fBwho am i\fR test.
+
+.TP
+.B \-xxx \-J\fR (\fB\-\-usb\fR)
+\- Adds, if present, serial number for non hub devices.
+
+\- Adds \fBinterfaces:\fR for non hub devices.
+
+\- Adds, if available, USB speed in \fBMbits/s\fR or \fBGbits/s\fR.
+
.TP
.B \-xxx \-m\fR, \fB\-\-memory\-modules\fR
\- Adds memory bus width: primary bus width, and if present, total width. e.g.
@@ -842,9 +1025,11 @@ present. If no total width data is found, then inxi will not show that item.
data available.
\- Adds device serial number.
+
.TP
.B \-xxx \-N\fR
\- Adds, if present, serial number.
+
.TP
.B \-xxx \-R\fR
\- md\-raid: Adds system mdraid support types (kernel support, read ahead, RAID events)
@@ -853,6 +1038,7 @@ data available.
\- Hardware RAID: Adds rev, ports, and (if available and/or relevant)
\fBvendor:\fR item, which shows specific vendor [product] information.
+
.TP
.B \-xxx \-S\fR
\- Adds, if in X, or with \fB--display\fR, bar/dock/panel/tray items
@@ -862,13 +1048,7 @@ lxpanel, xfce4\-panel, lxqt\-panel, tint2, cairo-dock, trayer, and many others.
\- Adds (if present), window manager (\fBwm\fR) version number.
\- Adds (if present), display manager (\fBdm\fR) version number.
-.TP
-.B \-xxx \-\-usb\fR
-\- Adds, if present, serial number for non hub devices.
-
-\- Adds \fBinterfaces:\fR for non hub devices.
-\- Adds, if available, USB speed in \fBMbits/s\fR or \fBGbits/s\fR.
.TP
.B \-xxx \-w\fR,\fB \-W\fR
\- Adds location (city state country), observation altitude (if available),
@@ -878,7 +1058,18 @@ weather observation time (if available), sunset/sunrise (if available).
These options are triggered with \fB\-\-admin\fR or \fB\-a\fR. Admin options are
advanced output options, and are more technical, and mostly of interest to system
administrators or other machine admins.
-The \fB\-\-admin\fR option only has to be used once, and will trigger the following features.
+
+The \fB\-\-admin\fR option sets \fB\-xxx\fR, and only has to be used once.
+It will trigger the following features:
+
+.TP
+.B \-a \-A\fR
+\- Adds, if present, possible \fBalternate:\fR kernel modules capable of driving
+each \fBDevice\-x\fR (not including the current \fBdriver:\fR). If no non\-driver
+modules found, shows nothing. NOTE: just because it lists a module does NOT mean it is
+available in the system, it's just something the kernel knows could possibly be used
+instead.
+
.TP
.B \-a \-C\fR
\- Adds CPU family, model\-id, and stepping (replaces \fBrev\fR of \fB\-Cx\fR).
@@ -886,6 +1077,48 @@ Format is \fBhexadecimal (decimal)\fR if greater than 9, otherwise \fBhexadecima
\- Adds CPU microcode. Format is \fBhexadecimal\fR.
+\- Adds socket type (for motherboard CPU socket, if available). If results doubtful
+will list two socket types and \fBnote: check\fR. Requires sudo/root and \fBdmidecode\fR.
+The item in parentheses may simply be a different syntax for the same socket,
+but in general, check this before trusting it.
+.nf
+Sample: \fBsocket: 775 (478) note: check\fR
+Sample: \fBsocket: AM4\fR
+.fi
+
+\- Adds DMI CPU base and boost/turbo speeds. Requires sudo/root and \fBdmidecode\fR.
+In some cases, like with overclocking or 'turbo' or 'boost' modes, voltage and
+external clock speeds may be increased, or short term limits raised on max CPU speeds.
+These are often not reflected in /sys based CPU \fBmin/max:\fR speed results,
+but often are using this source.
+
+Samples:
+.nf
+CPU not overclocked, with boost, like Ryzen:
+\fBSpeed: 2861 MHz min/max: 1550/3400 MHz boost: enabled base/boost: 3400/3900\fR
+
+Overclocked 2900 MHz CPU, with no boost available:
+\fBSpeed: 2900 MHz min/max: 800/2900 MHz base/boost: 3350/3000\fR
+
+Overclocked 3000 MHz CPU, with boosted max speed:
+\fBSpeed: 4190 MHz min/max: 1200/3001 MHz base/boost: 3000/4000\fR
+.fi
+
+Note that these numbers can be confusing, but basically, the \fBbase\fR
+number is the actual normal top speed the CPU runs at without boost mode, and the
+\fBboost\fR number is the max speed the CPU reports itself able to run at.
+The actual max speed may be higher than either value, or lower.
+The \fBboost\fR number appears to be hard\-coded into the CPU DMI data,
+and does not seem to reflect actual max speeds that overclocking or
+other combinations of speed boosters can enable, as you can see from the
+example where the CPU is running at a speed faster than
+the min/max or base/boost values.
+
+Note that the normal \fBmin/max:\fR speeds do NOT show actual overclocked OR
+boost/turbo mode speeds, and appear to be hard\-coded values, not dynamic real
+values. The \fBbase/boost:\fR values are sometimes real, and sometimes not.
+\fBbase\fR appears in general to be real.
+
\- Adds CPU Vulnerabilities (bugs) as known by your current kernel. Lists by
\fBType: ... (status|mitigation): ....\fR for systems that support this feature
(Linux kernel 4.14 or newer, or patched older kernels).
@@ -894,6 +1127,137 @@ Format is \fBhexadecimal (decimal)\fR if greater than 9, otherwise \fBhexadecima
.B \-a \-d\fR,\fB\-a \-D\fR
\- Adds logical and physical block size in bytes.
+Using \fBsmartctl\fR (requires sudo/root privileges).
+
+\- Adds device model family, like \fBCaviar Black\fR, if available.
+
+\- Adds SATA type (eg 1.0, 2.6, 3.0) if a SATA device.
+
+\- Adds SMART report line: status, enabled/disabled, health, powered on,
+cycles, and some error cases if out of range values. Note that for Pre\-fail items,
+it will show the VALUE and THRESHOLD numbers. It will also fall back for unknown
+attributes that are or have been failing and print out the Attribute name, value,
+threshold, and failing message. This way even for unhandled Attribute names,
+you should get a solid report for full failure cases. Other cases may show
+if inxi believes that the item may be approaching failure. This is a guess so
+make sure to check the drive and smartctl full output to verify before
+taking any further action.
+
+\- Adds, for USB or other external drives, actual model name/serial if
+available, and different from enclosure model/serial, and corrects block
+sizes if necessary. Adds in drive temperature for some drives as well,
+and other useful data.
+
+.TP
+.B \-a \-G\fR
+Triggers a much more complete Screen/Monitor output on the
+\fBDisplay:\fR line of \fB\-G\fR. Note that the
+basic feature requires \fBxdpyinfo\fR, and the advanced per monitor
+feature requires \fBxrandr\fR.
+
+No support currently exists for \fBWayland\fR since we so far can find
+no documentation or easy methods to extract this information from \fBWayland\fR
+compositors. This unfortunate situation may change in the future, hopefully.
+However, most \fBWayland\fR systems also come with \fBxwayland\fR,
+which should supply the tools necessary for the time being.
+
+Further note that all references to \fBDisplays\fR, \fBScreens\fR,
+and \fBMonitors\fR are referring to the \fBX\fR technical terms,
+not normal consumer usage. 1 \fBDisplay\fR runs 1 or more
+\fBScreens\fR, and a \fBScreen\fR runs 1 or more \fBMonitors\fR.
+
+\- Adds \fBDisplay\fR ID, for the Display running the Screen that runs the Monitors.
+
+\- Adds total number of \fBScreens\fR listed for the current \fBDisplay\fR.
+
+\- Adds default \fBScreen\fR ID if Screen (not monitor!) total is greater than 1.
+
+\- Adds \fBScreen\fR line, which includes the ID (\fBScreen: 0\fR) then \fBs-res\fR
+(Screen resolution), \fBs\-dpi\fR, \fBs\-size\fR and \fBs\-diag\fR. Remember, this is an
+Xorg \fBScreen\fR, NOT a monitor screen, and the information listed is about
+the Xorg Screen! It may at times be the same as a single monitor system,
+but usually it's different in some ways.
+
+\- Adds \fBMonitor\fR ID(s). Monitors are a subset of a Screen, each of which
+can have one or more monitors. Normally a dual monitor setup is 2 monitors
+run by one Xorg Screen. Each monitor has the following data, if available:
+
+\- \fBres:\fR resolution in pixels. This is the individual monitor's
+reported pixel dimensions.
+
+\- \fBhz:\fR frequency in Herz, as reported to Xorg. Note that there have been
+and may continue to be bugs with how Xorg treats > 1 monitor frequencies.
+
+\- \fBdpi:\fR dpi (dots per inch), aka, ppi (pixels per inch). This is the
+physical screen dpi, which is calculated using the screen dimensions and its
+resolution.
+
+\- \fBsize:\fR size in mm (inches). Note that this is the real monitor size,
+not the Xorg Screen size, which can be quite different (1 Xorg Screen can
+for instance contain two or more monitors).
+
+\- \fBdiag:\fR monitor screen diagonal in mm (inches). Note that this is
+the real monitor size, not the Xorg full Screen diagonal size, which
+can be quite different.
+
+Sample (with both \fBxdpyinfo\fR and \fBxrandr\fR data available):
+.nf
+\fBinxi \-aG
+Graphics:
+ ....
+Display: x11 server: X.Org 1.20.6 driver: modesetting
+display ID: :0.0 screens: 1
+Screen\-1: 0 s\-res: 2560x1024 s\-dpi: 96 s\-size: 677x271mm (26.7x10.7")
+s\-diag: 729mm (28.7")
+Monitor\-1: DVI\-I\-0 res: 1280x1024 hz: 60 dpi: 96
+size: 338x270mm (13.3x10.6") diag: 433mm (17")
+Monitor\-2: VGA\-0 res: 1280x1024 hz: 60 dpi: 86
+size: 376x301mm (14.8x11.9") diag: 482mm (19")
+ ....\fR
+.fi
+\- Adds, if present, possible \fBalternate:\fR kernel modules capable of driving
+each \fBDevice\-x\fR (not including the current \fBdriver:\fR). If no non\-driver
+modules found, shows nothing. NOTE: just because it lists a module does NOT mean it is
+available in the system, it's just something the kernel knows could possibly be used
+instead.
+
+.TP
+.B \-a \-I\fR
+Adds Packages, totals, per package manager totals, and number of lib
+packages detected per package manager. Also adds detected package managers
+with 0 packages listed. Moves to \fBRepos\fR if \fB\-ra\fR.
+
+.nf
+\fBinxi \-aI
+Info:
+ ....
+ Init: systemd v: 245 runlevel: 5 Compilers: gcc: 9.3.0 alt: 5/6/7/8/9
+ Packages: apt: 3681 lib: 2096 rpm: 0 Shell: ksh v: A_2020.0.0 default: Bash
+ v: 5.0.16 running in: kate inxi: 3.1.04
+.fi
+
+.TP
+.B \-a \-j\fR, \fB\-a \-P\fR , \fB\-a \-P\fR
+\- Adds swappiness and vfs cache pressure, and a message to indicate
+if the value is the default value or not (Linux only, and only if available).
+If not the default value, shows default value as well, e.g.
+
+For \fB\-P\fR per swap physical partition:
+
+\fBswappiness: 60 (default) cache pressure: 90 (default 100)\fR
+
+For \fB\-j\fR row 1 output:
+
+\fBKernel: swappiness: 60 (default) cache pressure: 90 (default 100)\fR
+
+.TP
+.B \-a \-n\fR, \fB\-a \-N\fR, \fB\-a \-i\fR
+\- Adds, if present, possible \fBalternate:\fR kernel modules capable of driving
+each \fBDevice\-x\fR (not including the current \fBdriver:\fR). If no non\-driver
+modules found, shows nothing. NOTE: just because it lists a module does NOT mean it is
+available in the system, it's just something the kernel knows could possibly be used
+instead.
+
.TP
.B \-a \-p\fR,\fB\-a \-P\fR
\- Adds raw partition size, including file system overhead, partition table, e.g.
@@ -909,11 +1273,9 @@ not the raw size.
\- Adds partition filesystem block size if found (requires root and blockdev).
-\- For swap, adds swappiness and vfs cache pressure, and a message to indicate
-if it is the default value or not (Linux only, and only if available). If not,
-shows default value as well, e.g.
-
-\fBswappiness: 60 (default) cache pressure: 90 (default 100)\fR.
+.TP
+.B \-a \-r\fR
+\- Adds Packages. See \fB\-Ia\fR
.TP
.B \-a \-S\fR
@@ -950,6 +1312,11 @@ which is generally slower than \fBCurl\fR or \fBWget\fR but it may help bypass
issues with downloading.
.TP
+.B \-\-dig\fR
+Temporary override of \fBNO_DIG\fR configuration item. Only use to test w/wo dig.
+Restores default behavior for WAN IP, which is use dig if present.
+
+.TP
.B \-\-display [:<integer>]\fR
Will try to get display data out of X (does not usually work as root user).
Default gets display info from display \fB:0\fR. If you use the format
@@ -979,7 +1346,16 @@ Force inxi to use Curl, Fetch, Perl, or Wget for downloads.
.B \-\-host\fR
Turns on hostname in System line. Overrides inxi config file value (if set):
-\fBSHOW_HOST='false'\fR
+\fBSHOW_HOST='false'\fR \- Same as: \fBSHOW_HOST='true'\fR
+
+This is an absolute override, the host will always show no matter what
+other switches you use.
+
+.TP
+.B \-\-html\-wan\fR
+Temporary override of \fBNO_HTML_WAN\fR configuration item. Only use to test w/wo
+HTML downloaders for WAN IP. Restores default behavior for WAN IP, which is use HTML
+downloader if present and if dig failed.
.TP
.B \-\-indent\-min [integer]\fR
@@ -999,12 +1375,28 @@ Updates / installs man page with \fB\-U\fR if \fBpinxi\fR or using \fB\-U 3\fR d
(Only active if \fB\-U\fR is is not disabled by maintainers).
.TP
+.B \-\-no\-dig\fR
+Overrides default use of \fBdig\fR to get WAN IP address. Allows use of normal
+downloader tool to get IP addresses. Only use if dig is failing, since dig is much
+faster and more reliable in general than other methods.
+
+.TP
.B \-\-no\-host\fR
-Turns off hostname in System line. Useful, in combination with \fB\-z\fR,
-for anonymizing inxi output for posting on forums or IRC. Same as
-configuration value:
+Turns off hostname in System line. This is default when using \fB\-z\fR,
+for anonymizing inxi output for posting on forums or IRC. Overrides
+configuration value (if set):
+
+\fBSHOW_HOST='true'\fR \- Same as: \fBSHOW_HOST='false'\fR
-\fBSHOW_HOST='false'\fR
+This is an absolute override, the host will not show no matter what other
+switches you use.
+
+.TP
+.B \-\-no\-html-wan\fR
+Overrides use of HTML downloaders to get WAN IP address. Use either only dig, or
+do not get wan IP. Only use if dig is failing, and the HTML downloaders are taking
+too long, or are hanging or failing.
+Make permanent with \fBNO_HTML_WAN='true'\fR
.TP
.B \-\-no\-man\fR
@@ -1012,11 +1404,15 @@ Disables man page install with \fB\-U\fR for master and active development branc
(Only active if \fB\-U\fR is is not disabled by maintainers).
.TP
+.B \-\-no\-sensor\-force\fR
+Overrides user set \fBSENSOR_FORCE\fR configuration value. Restores default behavior.
+
+.TP
.B \-\-no\-ssl\fR
Skip SSL certificate checks for all downloader actions (\fB\-U\fR, \fB\-w\fR,
\fB\-W\fR, \fB\-i\fR). Use if your system does not have current SSL certificate
lists, or if you have problems making a connection for any reason. Works with
-\fBWget\fR, \fBCurl\fR, and \fBFetch\fR only.
+\fBWget\fR, \fBCurl\fR, \fBPerl HTTP::Tiny\fRand \fBFetch\fR.
.TP
.B \-\-no\-sudo\fR
@@ -1044,21 +1440,21 @@ configuration item. These are the available sort options:
\fBdev\-base\fR - \fB/dev\fR partition identifier, like \fB/dev/sda1\fR.
Note that it's an alphabetic sort, so \fBsda12\fR is before \fBsda2\fR.
-\fBfs\fR - Partition filesystem. Note that sorts will be somewhat random if all
+\fBfs\fR \- Partition filesystem. Note that sorts will be somewhat random if all
filesystems are the same.
-\fBid\fR - Mount point of partition (default).
+\fBid\fR \- Mount point of partition (default).
-\fBlabel\fR - Label of partition. If partitions have no labels,
+\fBlabel\fR \- Label of partition. If partitions have no labels,
sort will be random.
\fBpercent\-used\fR - Percentage of partition size used.
-\fBsize\fR - KiB size of partition.
+\fBsize\fR \- KiB size of partition.
-\fBuuid\fR - UUID of the partition.
+\fBuuid\fR \- UUID of the partition.
-\fBused\fR - KiB used of partition.
+\fBused\fR \- KiB used of partition.
.TP
.B \-\-pm\-type [package manager name]\fR
@@ -1066,6 +1462,43 @@ For distro package maintainers only, and only for non apt, rpm, or pacman based
To be used to test replacement package lists for recommends for that package manager.
.TP
+.B \-\-sensors\-default\fR
+Overrides configuration values \fBSENSORS_USE\fR or \fBSENSORS_EXCLUDE\fR
+on a one time basis.
+
+.TP
+.B \-\-sensors\-exclude\fR
+Similar to \fB\-\-sensors\-use\fR except removes listed sensors from sensor data.
+Make permanent with \fBSENSORS_EXCLUDE\fR configuration item. Note that gpu, network,
+disk, and other specific device monitor chips are excluded by default.
+
+Example: \fBinxi \-sxx \-\-sensors\-exclude k10temp-pci-00c3\fR
+
+.TP
+.B \-\-sensors\-use\fR
+Use only the (comma separated) sensor arrays for \fB\-s\fR output. Make permanent
+with \fBSENSORS_USE\fR configuration item. Sensor array ID value must be the exact
+value shown in lm-sensors sensors output (Linux/lm-sensors only). If you only want
+to exclude one (or more) sensors from the output, use \fB\-\-sensors\-exlude\fR.
+
+Can be useful if the default sensor data used by inxi is not from the right sensor
+array. Note that all other sensor data will be removed, which may lead to undesired
+consequences. Please be aware that this can lead to many undesirable side-effects,
+since default behavior is to use all the sensors arrays and select which values
+to use from them following a set sequence of rules. So if you force one to be used,
+you may lose data that was used from another one.
+
+Most likely best use is when one (or two) of the sensor arrays has all the sensor data
+you want, and you just want to make sure inxi doesn't use data from another array that
+has inacurate or misleading data.
+
+Note that gpu, network, disk, and other specific device monitor chips are excluded by
+default, and should not be added since they do not provide cpu, board, system, etc,
+sensor data.
+
+Example: \fBinxi \-sxx \-\-sensors\-use nct6791-isa-0290,k10temp-pci-00c3\fR
+
+.TP
.B \-\-sleep [0\-x.x]\fR
Usually in decimals. Change CPU sleep time for \fB\-C\fR (current: \fB\0.35\fR).
Sleep is used to let the system catch up and show a more accurate CPU use. Example:
@@ -1109,7 +1542,7 @@ Forces the USB data generator to use \fBlsusb\fR as data source. Overrides
Force \fB\-i\fR to use supplied URL as WAN IP source. Overrides dig or
default IP source urls. URL must start with http[s] or ftp.
-The IP address from the URL must be the last item on the last (non-empty) line
+The IP address from the URL must be the last item on the last (non\-empty) line
of the page content source code.
Same as configuration value (example):
@@ -1130,6 +1563,12 @@ fetch. Shows more downloader action information. Shows some more information
for Perl downloader.
.TP
+.B \-\-dbg [2\-xx]\fR
+\- See github \fBinxi-perl/docs/inxi-values.txt\fR for specific specialized debugging
+options. These can vary but tend to not change much, though they are added as
+needed.
+
+.TP
.B \-\-debug [1\-3]\fR
\- On screen debugger output. Output varies depending on current needs
Usually nothing changes.
@@ -1157,13 +1596,13 @@ other system data.
.TP
.B \-\-debug 21\fR
-Automatically uploads debugger data tar.gz file to \fIftp.techpatterns.com\fR,
+Automatically uploads debugger data tar.gz file to \fIftp.smxi.org\fR,
then removes the debug data directory, but leaves the debug tar.gz file.
See \fB\-\-ftp\fR for uploading to alternate locations.
.TP
.B \-\-debug 22\fR
-Automatically uploads debugger data tar.gz file to \fIftp.techpatterns.com\fR, then
+Automatically uploads debugger data tar.gz file to \fIftp.smxi.org\fR, then
removes the debug data directory and the tar.gz file.
See \fB\-\-ftp\fR for uploading to alternate locations.
@@ -1306,6 +1745,13 @@ Overrides default. See \fB\-\-indent\-min\fR. If \fB80\fR or less, wrap will nev
\fBLIMIT\fR Overrides default of \fB10\fR IP addresses per IF. This is only of interest
to sys admins running servers with many IP addresses.
+\fBNO_DIG\fR Set to \fB1\fR or \fBtrue\fR to disable WAN IP use of \fBdig\fR and force
+use of alternate downloaders.
+
+\fBNO_HTML_WAN\fR Set to \fB1\fR or \fBtrue\fR to disable WAN IP use of \fBHTML Downloaders\fR and force
+use of dig only, or nothing if dig disabled as well. Same as \fB\-\-no\-html\-wan\fR. Only use if
+dig is failing, and HTML downloaders are hanging.
+
\fBNO_SUDO\fR Set to \fB1\fR or \fBtrue\fR to disable internal use of \fBsudo\fR.
\fBPARTITION_SORT\fR Overrides default partition output sort. See
@@ -1318,6 +1764,12 @@ to sys admins running servers with many IP addresses.
is the CPU), forces sensors to use either value 1 or 2 as CPU temperature. See the
above configuration page on smxi.org for full info.
+\fBSENSORS_EXCLUDE\fR Exclude supplied sensor array[s] from sensor output. Override with
+\fB\-\-sensors\-default\fR. See \fB\-\-sensors\-exclude\fR.
+
+\fBSENSORS_USE\fR Use only supplied sensor array[s]. Override with
+\fB\-\-sensors\-default\fR. See \fB\-\-sensors\-use\fR.
+
\fBSEP2_CONSOLE\fR Replaces default key / value separator of '\fB:\fR'.
\fBUSB_SYS\fR Forces all USB data to use \fB/sys\fR instead of \fBlsusb\fR.
@@ -1327,15 +1779,15 @@ generally much faster). URL must begin with http or ftp. Note that if you use th
the downloader set tests will run each time you start inxi whether a downloader feature
is going to be used or not.
-The IP address from the URL must be the last item on the last (non-empty) line of
+The IP address from the URL must be the last item on the last (non\-empty) line of
the URL's page content source code.
Same as \fB\-\-wan\-ip\-url [URL]\fR
\fBWEATHER_SOURCE\fR Values: [\fB0-9\fR]. Same as \fB\-\-weather\-source\fR. Values
-4-9 are not currently supported, but this can change at any time.
+4\-9 are not currently supported, but this can change at any time.
-\fBWEATHER_UNIT\fR Values: [\fBc\fR|\fBf\fR|\fBcf\fR|\fBfc\fR]. Same as \fB\-\-weather\-unit\fR.
+\fBWEATHER_UNIT\fR Values: [\fBm\fR|\fBi\fR|\fBmi\fR|\fBim\fR]. Same as \fB\-\-weather\-unit\fR.
.TP
.B Color Options
@@ -1374,9 +1826,9 @@ out its report.
File an issue report:
.I https://github.com/smxi/inxi/issues
.TP
-.B Developer Forums
-Post on inxi developer forums:
-.I https://techpatterns.com/forums/forum\-32.html
+.B Forums
+Post on inxi forums:
+.I https://techpatterns.com/forums/forum\-33.html
.TP
.B IRC irc.oftc.net#smxi
You can also visit
@@ -1396,7 +1848,7 @@ is a fork of \fBlocsmif\fR's very clever \fBinfobash\fR script.
Original infobash author and copyright holder:
Copyright (C) 2005\-2007 Michiel de Boer aka locsmif
-inxi version: Copyright (C) 2008\-18 Harald Hope
+inxi version: Copyright (C) 2008\-20 Harald Hope
This man page was originally created by Gordon Spencer (aka aus9) and is
maintained by Harald Hope (aka h2 or TechAdmin).
diff --git a/inxi.changelog b/inxi.changelog
index e6efbde..33fd5d8 100644
--- a/inxi.changelog
+++ b/inxi.changelog
@@ -1,4 +1,1048 @@
=====================================================================================
+Version: 3.1.06
+Patch: 00
+Date: 2020-08-16
+-----------------------------------
+Changes:
+-----------------------------------
+
+New features, new changes, new bug fixes!!! Excitement!!! Thrills!!!
+
+Bugs:
+1. Forgot to set get Shell logic in inxi short form, oops, so Shell remained blank,
+only inxi short, which I rarely use so I didn't notice.
+
+2. Failed to test pacman-g2 for packages, had wrong query argument, so it failed.
+Also failed to test for null data, so showed errors for packages as well. Both
+fixed.
+
+3. A big bug, subtle, and also at the same time, an enhancement, it turns out NVME
+drives do NOT follow the age old /proc/partitions logic where if the minor number is
+divisible by 16 or has remainder 8 when divided by 16, it's a primary drive, not
+a partition. nvme drives use a random numbering when > 1 nvme drives are present, and
+the old tests would fail for all nvme drivers more than the first one, which led
+to wrong disk size totals. Thanks gardotd426 who took the time to help figure this
+out in issue #223 - fix is to not do that test for nvme drives, or rather, to add
+a last fail test for nvme primary nvme[0-9]n[0-9] drive detections, not the minor
+number.
+
+Fixes:
+1. Corrected indentation for block sizes, children were not indented.
+
+2. Updated some older inxi-perl/docs pages, why not, once in a while?
+
+3. Kernel 5.8 introduces a changed syntax to gcc string location, this has been
+corrected, and the kernel gcc version now shows correctly for the previous
+syntax and the new one. Hopefully they do not change it again, sigh...
+
+4. Removed string 'hwmon' sensors from gpu, those are not gpu sensors, and
+are also usually not board/cpu sensors, but things like ath10, iwl, etc,
+network, or disk sensors, etc. In some cases hwmon sensor data would appear
+
+Enhancements:
+1. Big sensors refactor, now inxi supports two new sensors options:
+--sensors-exclude - which allows you to exclude any primary sensor type[s]. Note that
+in the refactored logic, and in the old logic, gpu sensors were already excluded.
+Now other hardware specific sensors like network are excluded as well.
+
+--sensors-use - use ONLY list of supplied sensor IDs, which have to match the
+syntax you see in lm-sensors sensors output.
+
+Both accept comma separated list of sensors, 1 or more, no spaces.
+
+The refactor however is more far reaching, now inxi stores and structures data
+not as a long line of sensors and data without differentiation, but by sensor array/chip
+ID, which is how the exclude and use features can work, and how granular default
+hardware sensor exclusions and uses can happen. This is now working in the gpu
+sensors, and will in the future be extended to the newer 5.7/5.8 kernel disk
+temperature sensors values, which will lead in some cases to being able to get
+sensors data for disks without root or hddtemp. This is a complicated bit of logic,
+and I don't have time to do it right now, but the data is now there and stored
+and possible to use in the future.
+
+To see sensors structures, use: inxi -s --dbg 18 and that will show the sensors data
+and its structures, which makes debugger a lot easier for new features.
+
+This issue was originally generated by what was in my view an invalid complaint
+about some inxi sensors defaults, which led me to look more closely at sensors
+logic, which is severely lacking. More work on sensors will happen in the future,
+time, health, and energy permitting.
+
+2. Added Watts, mem temp, for amdgpu sensors, as -sxxx option. More gpu sensor
+data will be added as new data samples show what will be available for the
+free modules like amdgpu, nouvean, and the intel graphics modules.
+
+3. More disk vendors and IDs, as noted, the list never ends, and it hasn't ended,
+so statement remains true. Thanks linux-lite hardware database.
+
+Changes:
+
+1. This has always bugged me since it was introduced, the primary cpu line starter
+Topology: which was only technically accurate for its direct value, not its children,
+and also, in -b, cpu short form was using the value as the key, which is a no-no,
+I'd been meaning to fix that too, but finally realized if I just make the primary
+CPU line key be 'Info:', which is short, yet non-ambiguous, it would solve both
+problems.
+To keep the -b cpu line as short as before, I removed the 'type:' and integraged
+that value into the primary Info: string:
+CPU:
+ Info: 6-Core AMD Ryzen 5 2600 [MT MCP] speed: 2750 MHz min/max: 1550/3400 MHz
+
+-b 3.1.05 and earlier:
+CPU:
+ 6-Core: AMD Ryzen 5 2600 type: MT MCP speed: 1515 MHz min/max: 1550/3400 MHz
+
+These resolve something that has irked me for quite a while, 'Topology:' didn't
+fit, it was too geeky, and worst, it only applied to the value directly following
+it, NOT to the rest of the CPU information. It also could not be shortened or
+abbreviated since then it would have made no actual sense, like topo:, and the
+same issue with value being used for key in -b, and wrong word for line starter
+in -C would have existed. Besides, someone might think I was trying to make a
+subtle reference to the great Jodorowsky film 'El Topo', which would be silly,
+because that's art, and this is just some system specs that are reasonably
+readable...
+
+2. Was using opendns for WAN dig IP address, but apparently cysco bought that
+company, and now I've noticed the old opendns dig queries were failing more and
+more, so replaced that with akamai dig requests.
+Also made the WAN IP fallback to HTTP IP method if dig failed. New option:
+--no-http-wan and config item NO_HTTP_WAN with override --http-wan added to
+let you switch off http wan IP requests if you want. Note that if dig fails,
+you will get no wan ip address.
+Updated/improved error messages to handle this more complex set of wan ip
+options, so hopefully the error alert message will in most cases be right.
+
+3. To future proof inxi, switched debugger upload location to ftp.smxi.org/incoming
+from the old techpatterns.com/incoming. Updated man/help to remove those urls too.
+
+
+-----------------------------------
+-- Harald Hope - Sun, 16 Aug 2020 14:28:58 -0700
+
+=====================================================================================
+Version: 3.1.05
+Patch: 00
+Date: 2020-07-26
+-----------------------------------
+Changes:
+-----------------------------------
+
+Bug fixes!!! New Features!! Why wait!!!
+
+Bugs:
+1. Issue #220 on github: inxi misidentified XFCE as Gnome. This was a kind of core
+issue, and pointed to some logic that needed updating, and some inadequate
+assumptions made, and some too loose cascade of tests. Hopefully now xfce will
+almost never get misidentified, and the other primary desktops ID'ed either from
+$ENV or from xrop -root will be slightly more accurately identified as well.
+
+Note that this fix creates a possibility for obscure misconfigured desktops to
+be ID'ed wrong, but in this case, that will be technically a bug for them, but
+with the new fixes, that situation will be cleaner to handle internally in the
+desktop ID logic.
+
+Also tightened the final Gnome fallback detection to not trigger a possible
+false positive, it was testing for ^_GNOME but that is not adequate, because
+some gnome programs will trigger these values in xprop -root even if GNOME
+is not running. Should be safer now, hopefully no new bugs will be triggered
+by these changes.
+
+Fixes:
+1. Missed an indentation level for -y1, gcc alt should have been indented in
+one more level, now it is.
+
+2. In disk vendors/family, didn't clean items starting with '/', this is
+now corrected. Yes, some do, don't ask me why. Might be cases like:
+Crucial/Micron maybe, where the first ID is grabbed, not sure.
+
+
+Enhancements:
+1. New Disk vendors, vendor IDs!!! The list never ends!!! We've finally found
+infinity, and it is the unceasing wave of tiny and not so tiny disks and their
+Ids.
+
+2. New feature: for -Aa, -Na/-na/-ia, -Ga, now will add the modules the kernel
+could support if they were available on the Device-x lines of those items.
+This was made an -a option because it really makes no sense, if it's a regular
+option, users might think that for example an nvidia card had a nouveua driver
+when it didn't, when in fact, all the kernel is saying is that it knows those
+listed modules 'couid' be used or present. This corresponds to the Display:
+item in -Ga, that lists 'alternate:' drivers that Xorg knows about that could
+likewise be used, if they were on the system.
+
+In other words these are --admin options because otherwise users might get confused,
+so this is one where you want to know the man explanation before you ask for it.
+
+It is useful however if you're not sure what your choices are for kernel modules.
+
+When the alternate driver is the same as the active driver, or if none is found,
+it does not show the alternate: item to avoid spamming.
+
+
+-----------------------------------
+-- Harald Hope - Sun, 26 Jul 2020 19:10:21 -0700
+
+=====================================================================================
+Version: 3.1.04
+Patch: 00
+Date: 2020-06-28
+-----------------------------------
+Changes:
+-----------------------------------
+
+New version, new man, huge update, bug fixes, cleanups, updates!!
+
+What started as a relatively minor issue report ended up with a refactor of big
+chunks of some of the oldest code and logic in inxi.
+
+So many bugs and fixes, updates, and enhancements, that I will probably miss some
+when I try to list them.
+
+Bugs:
+1. In the process of fixing an issue about sudo use triggering server admin
+emails on failure, when --sudo/--no-sudo and their respective configuration
+items were added, sudo was inadvertently disabled because the test ran before
+the options were processed, which meant the condition to set sudo data was
+always false, so sudo for internal use was never set. The solution was to
+set a flag in the option handler and set sudo after options or configs run.
+
+2. Issue #219 reported gentoo and one other repo type would fail to show
+enabled repos, and would show an error as well, this was due to forgetting
+to make the match test case insensitive. If only all bugs were this easy
+to fix!!
+
+3. I'd seen this bug before, and couldn't figure out why it existed.
+It turned out that the partition blacklist filters were running fine
+in the main partition data tool, but I had forgotten to add in corresponding
+lsblk partition data filters, lol, so when the logic went back and double
+checked for missing partitions. This feature had been, if i remember right,
+to be able to show hidden partitions, which the standard method didn't see,
+but lsblk did, anyway, when the double check and add missing partitions
+logic ran, inxi was putting back in the blacklisted partitions every time,
+despite the original blacklists working well and as intended.
+This was fixed by adding in all the required fs type blacklists, then
+adding in comments above each black list reminding coders that if they
+add or remove from one blacklist, they have to do the same on the other.
+
+4. Found while testing something unrelated on older vm, the fallback
+case for cpu bugs, which was supposed to show the basic /proc/cpuinfo
+cpu bugs, was failing inexplicably because the data was simply being
+put into the wrong variable name, sigh.
+
+Fixes:
+1. While not technically an inxi bug, it would certainly appear that way to
+anyone who triggered it. We'd gotten issue reports before on this, but they
+were never complete, so couldn't figure it out. Basically, if someone puts
+inxi into a simple script that is in $PATH [this was the missing fact needed to
+actually trigger this bug in order to fix it], the script [not inxi], will
+then enter into an endless loop as inxi queries it for its version number using
+<script name> --version. This issue didn't happen if the script calling inxi
+was not in PATH, which is why I'd never been able to figure it out before.
+
+Only simple scripts with no argument handlers could trigger this scenario,
+and only if they were in PATH.
+
+Fixing this required refactoring the entire start get_shell_data logic, which
+ended up with a full refactor of the program_version logic as well. The fix
+was to expand the list of shells known by inxi so it would be able to recognize
+when it was in a shell running a script running inxi.
+
+This resulted in several real improvements, for instance, inxi will now almost
+always be able to determine the actual shell running inxi, even when started
+by something else. It will also never use --version attempts on programs it does
+not know about in a whitelist.
+
+So we lose slightly the abilty to get version data on unknown shells, but we
+gain inxi never being able to trigger such an infinite loop situation.
+
+2. As part of the program_version refactor, a long standing failure to get ksh,
+lksh, loksh, pdksh, and the related posh shells, all of which ID their version
+numbers only if they are running the command in themselves. The mistake had
+been having the default shell run that command. These all now correctly identify
+themselves.
+
+3. As part of the wm upgrades, many small failures to ID version numbers, or
+even wm's, in some cases, were discovered when testing, and corrected. Some
+I had not tested, like qtile, and the lisp variants, were not being detected
+correctly by the tests due to the way python or lisp items are listed in ps aux.
+
+4. As part of the wm update and program_version refactor, updated and simplified
+many desktop and wm detections and logic blocks. Ideally this makes them more
+predictable and easy to work on for the future.
+
+5. As some last tunings for the new -y1 key: value pair per line output option,
+fixed some small glitches in -b indentation. Also improved RAID indenting,
+and Weather, and made it all very clean and predictable in terms of indentations.
+
+6. Something I'd slightly noticed but never done anything about, while testing
+desktop fixes, I realized that for Desktop: item, dm: is a secondary data type,
+but if it's Console:, then DM: is a primary data type, not a secondary one. So
+now if Console: it becomes DM: which makes sense, previously it implied a dm:
+was used to start the console, which was silly. Also, since often the reason
+it's Console: with no dm in the first place is that it's a server with no dm.
+So now if console, and no dm detected, rather than showing DM: N/A it just
+doesn't show dm at all. Note that the -y1 display feature now makes catching
+and correcting such logic and level assignments much easier since you can
+see the error in the indentations directly.
+
+7. As part of the overall core refactor, the print_data logic was also refactored
+and simplified, by making -y1 a first class citizen, it led to significantly
+different way of being able to present inxi data on your screen, and now
+print_data logic is cleaner and reflects these changes more natively, all the
+initial hacks to get this working were removed, and the logic was made to be
+core, not tacked on.
+
+8. A small thing also revealed in issue #219, battery data was not being
+trimmed, not sure how I missed that, but in some cases, space padding was in the
+values and was not removed, which leads to silly looking inxi output.
+
+9. Several massive internal optimizations, which were tested heavily, led to
+in one case, 8-900x faster execution the second time a data structure is used,
+previously in program_values the entire list was loaded each time program_values
+was called, now it's loaded into a variable on first load and the variable is
+used for the tests after that. This was also done for the vendor_version for
+disk vendors, which also features a very long data structure which can be
+loaded > 1 times for instances where a system has > 1 disk.
+
+I also tested while I was at it, to see if loading these types of data structures,
+arrays of arrays, or hashes of arrays, by reference, or by dereferencing their
+arrays, was faster, and it proved that it's about 20% faster to not
+dereference them, but to use them directly. So I've switched a number of the
+fixed data structures internally do use that method.
+
+Another tiny optimization was hard resetting the print_data iterator hash,
+while this would never matter in the real world, it showed that resetting
+the iterator hash manually was slightly more efficient than resetting it
+with a for loop.
+
+10. While not seen inside inxi, I updated and improved a number of the vm's
+used to test inxi and various software detections, so now I have a good selection,
+going back to 2008 or so, up to current. This is helpful because things like
+shells and window managers and desktops come and go, so it is hard to test
+old detections on new stuff when you can't install those anymore. You'll see
+these fixes in many of the less well known window managers, and in a few of
+the better known ones, where in some cases the detections were damaged.
+
+11. As part of the program_version refactor, updated and fixed file based
+version detections, those, ideally, will almost never be used. Hopefully
+programmers of things like window managers, shells, and desktops, can
+learn how to handle --version requests, even though I realize that's a lot
+harder than copying someone's code and then rebranding as your own project, or
+whatever excuse people have for not including a --version item in their software.
+
+Enhancements:
+1. As a result of the shell, start shell, shell parent refactors, inxi was able
+to correctly in most cases determine also the user default shell and its version,
+so that was added as an -Ixxx option:
+Shell: ksh v: A_2020.0.0 default: Bash v: 5.0.16
+
+2. As part of the program_version refactor, a more robust version number
+cleaner was made, which now allows for much more manipulation of the version
+number string, which sometimes contains, without spaces, non version number '
+info right before the actual version.
+
+3. Many more wm IDs were created and tested, and some old virtual machines
+that were used years ago were used again to test old window managers and
+their IDs, as well as new vms created to test newer ones. Many version
+IDs and WM ids were fixed in this process as well. All kinds of new ones
+added, though the list is basiclaly endless so ideally inxi would only use
+its internal data tables for window managers that have actual users, or did.
+
+4. First wayland datatype, now it may show Display ID: with -Ga, so far that's
+the only wayland screen/display data I can get reliably.
+
+5. As part of the shell parent/started in: updates and fixes, added every shell
+I could find, and installed and tested as many of them as possible to verify
+that either they have no version method, or that their version method works.
+This shell logic also is used to determine start parent. Obviously using
+whitelists of things that can change over time isn't ideal, but there was no
+way to actually do it otherwise. The best part of the fixes is that it's now
+remarkably difficult to trick inxi into reporting the wrong shell, and it
+generally will also get the default shell right, though I found cases in
+testing where a shell when started replaces the value in $SHELL with itself.
+
+6. I found a much faster and reasonably reliable way to determine toolkits
+used by gtk desktops, like cinnamon, gnome, and a few others. Test is to
+get version from gtk-launcher, which is MUCH faster than doing a package
+version query on the random libgtk toolkit that might be tested, and actually
+was tested for pacman, apt, and rpm in the old days, but that was removed
+because it was a silly hack. It's possible that now and then gtk desktops
+will be 0.0.1 versions off, but in most cases, the version matched, so I decided
+to restore the tk: item for a selection of gtk or gnome based desktops.
+
+So now gtk desktops, except mate, which of course will be using gtk 2 for a
+while longer, toolkit version should be working again, and the new method
+works on everything, unlike the old nasty hack that was used, which required
+package queries and guessing at which gtk lib was actually running the desktop,
+it was such a slow nasty hack that it was dumped a while ago, but this new
+method works reliably in most cases and solves most of the issues.
+
+7. As part of the overall program_versions refactor, the package version
+tester tool was extended to support pacman, dpkg, and rpm, which in practical
+terms covers most gnu/linux users and systems. Since this feature is literally
+only used for ASH and DASH shell version detections, it was really just added
+as a proof of concept, and because it fit in well with the new Package counts
+feature of -I/-r.
+
+8. Updated for version info a few other programs, added compositors as well.
+
+9. Last but not least!! More disk vendor IDs, more disk vendors!! And found
+another source to double check vendor IDs, that's good.
+
+New Features:
+1. For -Ix/-rx, -Ixx/-rxx, -Ia/-ra, now inxi shows package counts for most
+package managers plus snap, flatpak, and appimage. I didn't test appimage so
+I'm not 100% sure that works, but the others are all tested and work.
+
+If -r, Packages shows in the Repos item as first row, which makes sense, packages,
+repos, fits. Note that in some systems getting full package counts takes some
+time so it's an -x option not default.
+If -rx, -rxx, -ra, package info moved to -r section, and if -Ix, -Ixx, or -Ia,
+the following data shows:
+ * -Ix or -rx: show total package counts: Packages: 2429
+ * -Ixx or -rxx: shows Packages then counts by package manager located. If there
+ was only one package manager with packages, the total moves from right after
+ Packages: to the package manager, like: Packages: apt: 3241 but if there were
+ for example 2 or more found, it would show the total then:
+ Packages 3245 apt:3241 snap: 4
+ * -Ia or -ra: adds package managers with 0 packages managed, those are not
+ shown with -xx, and also shows how many of those packages per package manager
+ is a library type lib file.
+ Sample:
+ inxi -Iay1
+Info:
+ Processes: 470
+ Uptime: 8d 10h 42m
+ Memory: 31.38 GiB
+ used: 14.43 GiB (46.0%)
+ Init: systemd
+ v: 245
+ runlevel: 5
+ Compilers:
+ gcc: 9.3.0
+ alt: 5/6/7/8/9
+ Packages:
+ apt: 3685
+ lib: 2098
+ rpm: 0
+ Shell: Elvish
+ v: 0.13.1+ds1-1
+ default: Bash
+ v: 5.0.16
+ running in: kate
+ pinxi: 3.1.04-1
+
+-----------------------------------
+-- Harald Hope - Sun, 28 Jun 2020 21:07:42 -0700
+
+=====================================================================================
+Version: 3.1.03
+Patch: 00
+Date: 2020-06-12
+-----------------------------------
+Changes:
+-----------------------------------
+
+Big internal refactor!! Fully adjustable indentation logic, built in, native!
+
+NOTE: none of these changes have any impact on normal inxi -y -1, -y, or -y xx
+operation, everything will remain exactly the same, this only changes and
+makes robust -y 1 single key: value pair per line output.
+
+3.1.03 finishes the -y1 introduced in 3.1.02, but makes it a core part of the inxi
+logic for line printing, not a tacked on afterthought.
+
+Because the first draft of this in 3.1.02 was really a hack tacked onto the existing
+logic, which was not very flexible or robust, and required way too much literal test
+logic in the black box print_data() subroutine, which is supposed to be a 'dumb'
+logic, that just does what you give it automatically, I added in key changes that
+hard code the indentations per key, like so:
+
+Now: 34#0#3#key-name
+Before: 34#key-name
+
+Note that anyone using the json or XML output option may need to redo their code
+a bit to handle these extra 2 values that preface the actual key names.
+
+Fixes:
+1. In order to make this work, changed a few small things internally, a few
+key names were slightly altered to make them more clear.
+
+Changes:
+1. Redo of all internal full key strings, added two new # separated items:
+ xx#x#y#key-name:
+ * xx remains the main 0 padded 2 digit sorter per row/block.
+ * x is a new 0/1 boolean, that shows if the value is a container or not. As
+ currently implemented probably not hugely useful since it won't say when
+ the following items it is a container of ends.
+ Note that the following y value will always be 1 for the item contained by
+ the container, so you can check that way if you want. the next item can
+ also be a container, but it would have either the same indentation level
+ as the previous container or be different.
+ Thus, if a key is a container, it can contain either non containers, or
+ other containers, but that primary container does not end until the indent
+ value equals or is less than the indent value of the first container.
+ If you are a programmer you should be able to figure this out.
+ * y is the indentation level, 0-xx is supported, but in practical terms, only
+ 4 levels are used. For single line output, these set the indentation for that
+ key.
+ * key-name remains the key string ID name.
+
+2. For -y 1 -G will show drivers then indented one more level unloaded, FAILED,
+and alternate: to make it clear those are a subset of drivers. driver: itself
+will contain the actual driver. In cases where no driver is loaded, a note
+will show indented after driver:
+
+3. For -y 1, driver v: versions will be indented 1, and driver will be a container
+that contains that version key: value pair.
+
+Samples:
+-----------------------------------
+inxi -Razy1
+RAID:
+ Device-1: g23-home
+ type: zfs
+ status: ONLINE
+ size: 2.69 TiB
+ free: 1.26 TiB
+ allocated: 1.43 TiB
+ Array-1: mirror
+ status: ONLINE
+ size: 1.82 TiB
+ free: 602.00 GiB
+ Components:
+ online: sdb sdc
+ Array-2: mirror
+ status: ONLINE
+ size: 888.00 GiB
+ free: 688.00 GiB
+ Components:
+ online: sdd sde
+
+-----------------------------------
+sudo inxi -dazy1
+Drives:
+ Local Storage:
+ total: 1.98 TiB
+ used: 1.43 TiB (72.2%)
+ ID-1: /dev/sda
+ vendor: Intel
+ model: SSDSC2BW180A4
+ family: 53x and Pro 1500/2500 Series SSDs
+ size: 167.68 GiB
+ block size:
+ physical: 512 B
+ logical: 512 B
+ sata: 3.0
+ speed: 6.0 Gb/s
+ serial: <filter>
+ rev: DC32
+ temp: 37 C
+ scheme: MBR
+ SMART: yes
+ state: enabled
+ health: PASSED
+ on: 291d 17h
+ cycles: 1346
+ read: 431.94 GiB
+ written: 666.16 GiB
+ Optical-1: /dev/sr0
+ vendor: HL-DT-ST
+ model: DVDRAM GH20LS10
+ rev: FL00
+ dev-links: cdrom,cdrw,dvd,dvdrw
+ Features:
+ speed: 48
+ multisession: yes
+ audio: yes
+ dvd: yes
+ rw: cd-r,cd-rw,dvd-r,dvd-ram
+ state: running
+
+-----------------------------------
+inxi -Aazy1
+Audio:
+ Device-1: NVIDIA High Definition Audio
+ vendor: Gigabyte
+ driver: snd_hda_intel
+ v: kernel
+ bus ID: 09:00.1
+ chip ID: 10de:0be3
+ Device-2: AMD Family 17h HD Audio
+ vendor: Gigabyte
+ driver: snd_hda_intel
+ v: kernel
+ bus ID: 0b:00.3
+ chip ID: 1022:1457
+ Device-3: N/A
+ type: USB
+ driver: hid-generic,snd-usb-audio,usbhid
+ bus ID: 5-1.3.4:5
+ chip ID: 21b4:0083
+ serial: <filter>
+ Sound Server: ALSA
+ v: k5.4.0-11.2-liquorix-amd64
+
+-----------------------------------
+-- Harald Hope - Fri, 12 Jun 2020 19:02:08 -0700
+
+=====================================================================================
+Version: 3.1.02
+Patch: 00
+Date: 2020-06-12
+-----------------------------------
+Changes:
+-----------------------------------
+
+Big change, cleanup, small bug fixes. Hot, grab it now!!
+
+The new -y 1 feature exposed several small and larger glitches with how sets
+of data were constructed in inxi output. See Changes: for list of changes made
+to improve or fix these glitches.
+
+These errors and minor output inconsistencies became very obvious when I was
+doing heavy testing of -y 1, so I decided to just fix all of them at the same
+time, plus it was very hard to make the -y 1 indenter work as expected when the
+key values were not being treated consistently.
+
+Note that this completes the set of all possible -y results:
+
+Full -y Options:
+1. -y [no integer given] :: set width to a default of 80. this is what you usually
+want for forum posts, or for online issue reports, because it won't wrap and be
+hard to read. Help us help your users and others!! Teach them to use for example
+-Fxzy or -bay for their bug reports. Just add y to whatever collection of arguments
+you generally ask for in support forums or issue reports. Highly recommended,
+easy to type, and joins cleanly with other letters.
+
+2. -y -1 :: removes line width limits, this can lead to very long lines in some
+cases, and removes all auto-wrapping of line widths.
+
+3. -y 1 :: Switch to stacked key: value pairs, with primary data blocks separated
+by a blank line. Think dmidecode type output, or other command line sys info tools.
+By request, a forum support guy noted it was hard for newbies to understand the
+-G values, particularly -Ga when in lines, so this is another way to request
+data. WARNING: for lots of data, this gets really long!!! But if you are curious
+how inxi actually constructs its data internally, this sort of shows it.
+
+4. -y 80-xx :: set width to 80 or greater. Note you can also set these in
+your configurations if you want using the various options supported.
+
+-----------------------------------
+
+Bugs:
+1. Once again, no real bugs found beyond a few trivial things I can't remember.
+
+Fixes:
+1. When out of X, dm: showed after Console: and often said dm: N/A particularly
+on headless servers, which was silly. Now DM: only shows after Console: if
+a DM: was actually found. If regular Desktop output, either in X, or via
+--display out of X, no changes.
+
+2. There was a pointless sudo test when sudo values are set initially, they
+were still running even if --no-sudo was used. Now they don't run in that case.
+
+Enhancements:
+1. The biggie, now inxi can output in a similar indented way as something like
+dmidecode if you use the -y 1 option. This feature was originally by request,
+though the initial request actually just wanted to see it stacked simply,
+but that was almost impossible to read for any output reasonably long, so
+I made the indentations very dynamic and deep, they go up to 4 levels in,
+which is roughly how deep in the inxi sub Categories go. This output format
+makes it very easy to see how inxi 'thinks' about its data, how it views
+sets, subsets, subsubsets, and subsubsubsets of data.
+
+Note that each data block, as with dmidecode data, is separated by a blank
+line. You know what this means!!! Yes, that's right!!! You can parse inxi
+output with awk!!, same way legacy bash+gawk inxi used to parse its data!!
+Or if your brain just does not like lines of data, you can make it appear in
+indented single key: value pairs.
+
+Here you can see for example that 1 Xorg Display has 1 or more Screens,
+and each Screen has one or more Monitors. Note that this -Ga data first
+appeared in inxi 3.1.00.
+
+Sample [with bug in OpenGL output!, and showing -Ga newer values as well
+for dual monitor setup, with one Xorg Screen]:
+
+inxi -aGy1
+Graphics:
+ Device-1: NVIDIA GT218 [GeForce 210]
+ vendor: Gigabyte
+ driver: nouveau
+ v: kernel
+ bus ID: 09:00.0
+ chip ID: 10de:0a65
+ Display: x11
+ server: X.Org 1.20.8
+ driver: nouveau
+ unloaded: fbdev,modesetting,vesa
+ display ID: :0.0
+ screens: 1
+ Screen-1: 0
+ s-res: 2560x1024
+ s-dpi: 96
+ s-size: 677x271mm (26.7x10.7")
+ s-diag: 729mm (28.7")
+ Monitor-1: DVI-I-0
+ res: 1280x1024
+ hz: 60
+ dpi: 96
+ size: 338x270mm (13.3x10.6")
+ diag: 433mm (17")
+ Monitor-2: VGA-0
+ res: 1280x1024
+ hz: 60
+ dpi: 86
+ size: 376x301mm (14.8x11.9")
+ diag: 482mm (19")
+ OpenGL:
+ renderer: N/A
+ v: N/A
+ direct render: N/A
+
+2. Refactored and cleaned up print_data(), got rid of some early testing code,
+dumped some unnecessary tests, simplified old tests, and optimized the new
+indentation logic reasonably well. Hopefully the print_data() will not be
+quite as much of a black box now as it was.
+
+3. Even more drive vendors and ID matches!!! The list never ends!! An endless
+series of new vendors and IDs of existing vendors sprout up, then float away.
+And inxi follows them to the best of its ability. Thanks again to Linux-Lite
+hardware database, which help make this ever expanding list possible, since
+their users appear to use every disk known to humankind.
+
+Changes:
+1. When out of Display, and Console: shows, -S will not show dm: if no
+display manager is detected, and if it is detected, it shows DM: since it's
+not part of the Console: set of data. If out of X and --display is used to
+get Xorg data out of X, it will show Desktop: set of data as normal, at least
+it will show the stuff it can find. This resolves the issue where dm: appeared
+to be a member of the set of Console: data, instead of either its own thing,
+DM:, or a member of the set of Desktop: data.
+
+2. For RAID Devices with sub Array-x: values, Array-x: is capitalized, it used
+to be array-x: That was silly.
+
+3. In USB, now Device-x: resets inside each Hub: so that the Device-x: are
+numbered starting at 1 within each Hub:. This makes the counter behavior act
+the same as it does in for example RAM Array-x: / Device-y:, where each Array-x:
+resets Device-y: count to 1. This changes the old default of having Device-x:
+not reset, to let you see the total number of devices plugged in or attached
+no matter which hub they were plugged into, but the output actually gets
+sort of confusing in single key: value pair mode per line.
+
+4. The key: value syntax for weather was changed completely, now it works
+like the rest of the features, with Report:... [Forecast:...] Locale:...
+and Source:. Locale makes the source of the times and other date related
+features, and the location if shown or available, much more obvious. Before
+it was never clear if Current Time referred to your local or the remote
+time, now it's clearly from the Locale: you specified with -W, or
+the default -w local info. Also made Report 1 line if unwrapped, Forecast 1
+line if not wrapped, and Locale: 1 line if not wrapped, which makes the output
+easier to read.
+
+NOTE: automated weather queries are NOT allowed, if you do it, you will be
+banned!! inxi is NOT a desktop weather app!! Don't confuse it with one!!
+Weather is just a small service to users who might for example want to check
+the weather on a remote system, or something like that, and is not intended
+to be used on a routine basis.
+
+5. Cleaned up and re-ordered the --version output. It had some pretty old
+contexts in the language, which were removed or cleaned up and brought up to
+date. If you're wondering, I roughly use rsync and nano --version as guides
+for what to show or not show there.
+
+-----------------------------------
+-- Harald Hope - Thu, 11 Jun 2020 23:53:30 -0700
+
+=====================================================================================
+Version: 3.1.01
+Patch: 00
+Date: 2020-05-31
+-----------------------------------
+Changes:
+-----------------------------------
+
+New inxi, man. New information types, fixes, man updates.
+
+Bugs:
+No bugs of any importance fixed or found!!
+
+Fixes:
+1. Tiny fix, didn't use partition/slice assignment in help menu. BSD
+interest only since default partition is standard for Linux.
+
+Enhancements:
+1. Disc Vendors: added a large number of possible disk vendors, without having
+actual detection data available for all of them, using a different source.
+Also added, as usual, more disc vendor IDs from linux-lite hardware database,
+always ready with more vendors!
+2. Added groovy gorilla ID for ubuntu
+3. Very nice usability change, mostly for support people, now if -y without
+an integer is supplied, it will assign default column width of 80, which
+is what you usually want for forums or issue reports, otherwise the output
+can wrap outside the post or issue report, which is hard to read. Hopefully
+support people will catch onto this one.
+4. This closes issue #217 - Adds dmidecode based extra data:
+ -xxx - shows CPU voltage and external clock speeds
+ -a - shows CPU socket type and base/boost: speed items. These are --admin
+ options because neither is particularly reliable, sometimes they are right,
+ sometimes they aren't, as usual with dmi data. As far as tests show, base
+ speed, what dmidecode misleadingly calls 'Current Speed', which it isn't,
+ is the actual normal non throttled speed of the CPU / motherboard setup.
+ boost is what dmidecode calls 'Max Speed', which it also isn't, though
+ sometimes it is, as with AMD cpus with boost, and no overclocking. With
+ overclocking, sometimes base will be higher, sometimes the actual real
+ current cpu speeds will be higher than all the max/boost values.
+ Motherboard CPU socket type is likewise randomly correct, incorrect, empty,
+ misleading, depending on the age and type of the system, and the CPU
+ vendor. It appears that in general, AMD CPUs will be more or less right
+ if they have this data, and Intel CPUs will sometimes be right, sometimes
+ not, or empty. For > 1 CPU systems, the data is much less reliable.
+
+-----------------------------------
+-- Harald Hope - Sun, 31 May 2020 14:26:37 -0700
+
+=====================================================================================
+Version: 3.1.00
+Patch: 00
+Date: 2020-04-22
+-----------------------------------
+Changes:
+-----------------------------------
+New inxi, new man. Huge update, new line types, huge graphics upgrade, new
+switches, bug fixes, glitch fixes, enhancements, you name it, this has got it!!
+
+Note that since this features a new primary line item (-j / --swap Swap:),
+the version number has been bumped to 3.1.0, making this a major version
+upgrade, the first since the new Perl inxi rewrite was launched, though of
+course 3.0.0 contained many new line items as well, but this is the first
+actually new line item since then.
+
+Bugs:
+1. Big bug fix: if -z used, and -p, and user had partitions mounted in $HOME
+directory, the partitions would buggily duplicate in the output.
+
+2. See Fix 1, inxi was reporting the wrong (or no in some cases) Xorg driver
+because it was using the wrong Xorg log, it was only searcing in the original
+/var/log/Xorg.0.log file, not the newer alternative path locations.
+
+Fixes:
+1. Both an enhancement and a fix, users reported Xorg log file location changes.
+Fix is that now inxi uses wildcard searches of all readable locations that can
+contain the log files, then collects a list of them, and uses the last modified
+one. This ensures that the best possible guess is made about which actual
+log file is current, which should lead to significantly more reliable Xorg
+driver reports overall.
+
+Note that this fix works for user level and root level, it will always use the
+most recent readable file no matter what. For root, that should translate to
+the most recent on an absolute level Xorg log file. This issue was caused by
+gdm moving from Xorg.0.log to Xorg.1.log on some systems, but not all, and
+also, the location is often but not always now:
+~/.local/share/xorg/Xorg.[01234..].log [except for root, which is why
+root has to search for all user Xorg log files to find the most recent one.
+
+There were many red-herrings in this issue report, so it took some research to
+dig through those to the real data sources.
+
+2. Now that the compositor detection is out of early testing mode, enabled
+always on compositor detection for Wayland systems. Since the compositor
+is the Wayland display server, it makes sense to always show it if Wayland.
+Note that there is still no known way to actually reliably get Wayland data
+beyond simple environmental variables that let inxi detect Wayland is running
+the desktop. Lack of reliable logs or debugging tools across Wayland compositors
+makes this entire process about 10-50x more difficult than it should have been.
+
+3. In keeping with 2., also moved compositor: item to be right after server:
+item.
+
+4. Debian bug:
+https://bugs.debian.org/cgi-bin/pkgreport.cgi?dist=unstable;package=inxi
+requested that HTTP::Tiny be set to default always check SSL certificates.
+Now inxi does that, and --no-ssl flag disables this, which makes the Perl
+http downloader now work roughly the same as wget, curl, etc.
+
+5. Man page fixes, added pointer placeholders for out of alphabetical order
+options, so you can find anything by looking down the alpha sorted lists, like:
+--swap - See -j. Since inxi is running out of single letters that match new
+features, it's easier to point man readers to the right item without them
+having to already know it to find it. Also added --dbg [2-xx] pointer to
+github inxi-perl/docs/inxi-values.txt so people interested can learn how to
+trip the various per feature screen debuggers.
+
+Enhancements:
+1. updated ubuntu ids, added 'focal LTS'.
+
+2. USB Graphic devices added. This will add support for USB graphics adapters,
+an uncommon but existing category, often used in SOC boards, for example, but
+also on desktops, and things like USB webcams. Leaving these off was really
+just an oversight, the programming internally had the data, it just wasn't
+using it.
+
+3. Support added for TV card type multimedia devices in Graphics. That was
+actually a long term oversight, I'd simply missed that in the device ID
+documentation, one of the multimedia device subtypes is Video device.
+
+4. Huge, massive, internal upgrade to allow for -Ga output, which gives a
+technically accurate Xorg > Display > Screen > Monitor breakdown. Note that
+Display and Screen data come from xdpyinfo, and Monitor info comes from xrandr,
+but if xrandr is missing, the Screen information shows.
+
+Technically for -G, -Gxx, end users see very little difference except the per
+Screen / per Monitor resolutions are listed with a 1: type counter per item.
+
+Note that Xorg Screens are NOT Monitors, they are a virtual space Xorg constructs
+out of the pieces of hardware that make up the Screen space. In many cases,
+1 Xorg Screen contains only 1 Monitor, but the dimensions or dpi are frequenty
+different.
+
+New output items:
+Display: ... display ID: [Xorg Screen identifier, like :0.0]; screens: [Total Xorg
+Screens in current Display]; [s-default: [if > 1 Screens, default Screen number]]
+
+Screen-x: [Screen number]; s-res: [Xorg Screen resolution];
+s-dpi: [Xorg Screen dpi]; s-size: [Xorg Screen mm (inch) size;
+s-diag: [diagonal of Xorg Screen size]
+
+Monitor-x: [Monitor Xorg ID]; res: [Actual monitor pixel dimensions];
+hz: [actual monitor reported frequency]; dpi: [actual monitor dpi as calculated
+from actual monitor resolution/size; size: [actual monitor size in mm (inch);
+diag: [actual diagonal size in mm (inch).
+
+4a. -Gxx now shows Xorg s-dpi: for the Screen as well, after the main resolution
+section for -G.
+
+5. Big improvement in error messages and logging for Xorg driver detections,
+this logic is much more robust now, but after the main driver fix, also much less
+likely to ever be seen.
+
+6. Almost not visible to users, but major internal graphics refactor allows now
+for more modular treatment, and eventual Wayland data sourcing. Currently
+most Wayland data sourcing is in stub form, or only logically possible, but
+as it grows possible (if ever, since Wayland protocal appears to have totally
+neglected enforcing single location logging, and single tool debugging for
+the entire Wayland protocol of compositors, a massive oversight in my view).
+The -Ga refactors internally made this much more possible, and I integrated
+switches and tests, and fallbacks, and stubs in some locations, so it was
+clear where current Xorg specific logic is, and where future Wayland logic
+will fit in, sort of anyway.
+
+7. Debugger tools added for new features, or most of them.
+
+8. New primary line item: --swap / -j. This moves all swap data to a dedicated
+Swap: line, which looks roughly the same as Partition: lines, but when -j/--swap
+is used, all swap types, not only physical partition swaps, show. This should
+make some users happy.
+
+9. Added more cpu family IDs for Zen 2 series of cpu, tweaked some later
+Intel cpu family ids in terms of cpu arch name tool.
+
+10. By request, added ability filter out all UUID or Partition Label
+strings in -j, -o, -Sa, -p, -P. Those are tripped by --filter-label and
+--filter-uuid. Mostly useful in fringe cases, for example, replacing
+label or UUID from -Sa kernel boot parameters with root=LABEL=<filter>,
+or in cases you want to show full -v8 output without showing UUID or Labels,
+whatever.
+
+11. Added --no-dig/--dig plus configuration option NO_DIG=true. This disables
+dig in cases where dig is installed but failed due to maybe network firewall
+rules or something, and WAN IP detection fails. Normally you always want
+to use dig, it's faster, more reliable, and safer, than all the other regular
+downloader based methods, but we have seen server setups where for some reason
+those types of dig requests were blocked, thus disabling WAN IP detection.
+
+12. Added in WAN IP failure case, if dig was used, suggestion to try
+again with --no-dig, since most users are unlikely to learn about this issue,
+or the solution to it.
+
+13. Added single letter shortcut -J for --usb, maybe this will help people
+discover usb component of inxi, now you can request for instance: inxi -FJaz
+
+14. Added xonsh to supported shells, that had tripped a perl undefined value
+for start client bug since xonsh uses single word for version, xonsh/234
+so the default value, 2nd word, was undefined.
+
+15. More SSD and USB drive vendors from the endless fountain over at
+Linux Hardware Database (linuxliteos.com).
+
+Changes:
+1. Small change in how screen resolutions are output in -G non -a mode,
+now each Screen / Monitor will increment by 1 the 1: [resolution~hz] key.
+This helps make it more readable. Note that in non -a mode, the increments
+are just based on Screen, then Monitor, Monitor, Screen, and so on, counts.
+Most users will only have one Screen systems, but more advanced setups may use
+the Xorg > 1 Screen, each screen able to run > 1 monitors.
+
+The counts in say, a 2 Screen system, with 3 monitors, would be:
+1: res1 [from screen 0, monitor 1] 2: res2 [from screen 0, monitor 2]
+3: res3 [from screen 1, monitor 1.
+
+If xrandr is not installed, it would show:
+1: res1 [from screen 0] 2: res2 [from screen 1]
+
+-----------------------------------
+-- Harald Hope - Wed, 22 Apr 2020 19:33:56 -0700
+
+=====================================================================================
+Version: 3.0.38
+Patch: 00
+Date: 2020-03-14
+-----------------------------------
+Changes:
+-----------------------------------
+
+New version, man page, exciting changes!!
+
+Bugs:
+1. Fixed undefined error that could happen, in rare cases, in hdd_temp logic.
+
+Fixes:
+1. Fixed Elbrus cpu nazming, model 9 is 8CV, not 8CB (Cyrillic error)
+2. Preventitive, was not using '-' quite correctly in all regex ranges.
+3. Had wrong desktop string listed in Unity
+4. Reordered Family/Drive model in usb drive reports, it's to make it
+more obvious what is what.
+5. Adjusted indexing of splits to get better results in corner cases.
+6. Fixed some numbering issues.
+7. Added trimming n1 from nvme0 type names for nvme, this corrects some
+issues users were having.
+8. Fixed a division by 0 error in smartctl data grabber.
+9. Fixed a Perl issue, didn't realize perl treats 000 as a string, not 0.
+10. Another Perl fix, int() only wants to get numeric values sent to it,
+I'd assumed a different behavior, non numerics get converted to 0, but that's
+not how Perl sees things. Things like this, by the way, are why Perl is so
+absurdly fast.
+
+Enhancements:
+1. More disk vendors. The list will never be complete!! We have found eternal
+churn!! Thanks to linux lite hardware database as always.
+2. Big one!!! Now inxi uses smartctl data, if installed, for getting advanced
+drive information (with -a). See man and help for details. Will show failing drives,
+etc. Lots of info can be available, but sometimes data is not in smartctl db,
+so inxi can't find it, that's not an inxi bug, it's just how it is.
+3. Made hours on more human readable, into days/hours, for -a smartctl disk
+report.
+4. Added $test[12] for smartctl data printout, and $test[13] for disk array print out.
+Note that advanced debugger outputs can change or vary depending on what is being
+worked on so don't in general rely on these always being around. But they do
+tend to say stuck in place once I add them.
+5. Added some nvme stuff, spare reserve, if you need it, you'll appreciate it,
+if not, you'll never know it's there.
+6. By request from some forum issue thread: made --host only be shown onif not
+--filter or not --host. This makes -z remove hostname, but retains ability to
+do absolute overrides. Hostname should have always been filtered out like that,
+it was an oversight. I think that was Manjaro who asked that, but I forget.
+Note that this change, as usual, will not alter expected behaviors if users
+have config item for hostname set.
+7. Added support for picom compositor, thanks user codebling for that, I think
+that's compiz fork, the real branch that is that is being developed.
+
+-----------------------------------
+-- Harald Hope - Sat, 14 Mar 2020 22:56:32 -0700
+
+=====================================================================================
Version: 3.0.37
Patch: 00
Date: 2019-11-19