summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@unit193.net>2021-12-14 22:01:01 -0500
committerLibravatarUnit 193 <unit193@unit193.net>2021-12-14 22:01:01 -0500
commitad23217950d54d653851fd37f4b924e883acee1d (patch)
tree048596a83c6f26466c784f8090648957ede539f5
parent19c5b6157eba9a68ae9e5fc37ae40892404c7d54 (diff)
downloadinxi-ad23217950d54d653851fd37f4b924e883acee1d.tar.bz2
inxi-ad23217950d54d653851fd37f4b924e883acee1d.tar.xz
inxi-ad23217950d54d653851fd37f4b924e883acee1d.tar.zst
New upstream version 3.3.10-1.upstream/3.3.10-1
-rwxr-xr-xinxi5033
-rw-r--r--inxi.1838
-rw-r--r--inxi.changelog689
3 files changed, 4335 insertions, 2225 deletions
diff --git a/inxi b/inxi
index 7b8fe62..c7d6299 100755
--- a/inxi
+++ b/inxi
@@ -30,6 +30,7 @@ use 5.008;
use Cwd qw(abs_path); # #abs_path realpath getcwd
use Data::Dumper qw(Dumper); # print_r
+$Data::Dumper::Sortkeys = 1;
# NOTE: load in SystemDebugger unless encounter issues with require/import
# use File::Find;
use File::stat; # needed for Xorg.0.log file mtime comparisons
@@ -46,11 +47,10 @@ use POSIX qw(ceil uname strftime ttyname);
## INXI INFO ##
my $self_name='inxi';
-my $self_version='3.3.07';
-my $self_date='2021-10-11';
+my $self_version='3.3.10';
+my $self_date='2021-12-13';
my $self_patch='00';
## END INXI INFO ##
-
my ($b_pledge,@pledges);
if (eval {require OpenBSD::Pledge}){
OpenBSD::Pledge->import();
@@ -70,12 +70,12 @@ if (eval {require OpenBSD::Pledge}){
my ($self_path,$user_config_dir,$user_config_file,$user_data_dir);
## Hashes
-my (%alerts,%build_prop,%client,%colors,%disks_bsd,%dboot,%devices,%dl,
-%dmmapper,%force,%loaded,%mapper,%program_values,%rows,%sensors_raw,
-%service_tool,%show,%sysctl,%system_files,%usb);
+my (%alerts,%build_prop,%client,%colors,,%cpuinfo_machine,%disks_bsd,
+%dboot,%devices,%dl,%dmmapper,%force,%loaded,%mapper,%program_values,%risc,
+%rows,%sensors_raw,%service_tool,%show,%sysctl,%system_files,%usb);
## System Arrays
-my (@app,@dmi,@gpudata,@ifs,@ifs_bsd,@paths,@ps_aux,@ps_cmd,@ps_gui,
+my (@app,@cpuinfo,@dmi,@gpudata,@ifs,@ifs_bsd,@paths,@ps_aux,@ps_cmd,@ps_gui,
@sensors_exclude,@sensors_use,@uname);
## Disk/Logical/Partition/RAID arrays
@@ -100,8 +100,7 @@ if (eval {require Time::HiRes}){
@t0 = eval 'Time::HiRes::gettimeofday()' if $b_hires; # let's start it right away
## Booleans [busybox_ps not used actively]
-my ($b_admin,$b_android,$b_arm,$b_busybox_ps,$b_cygwin,$b_display,$b_irc,
-$b_mips,$b_ppc,$b_root,$b_running_in_display,$b_sparc);
+my ($b_admin,$b_android,$b_busybox_ps,$b_cygwin,$b_display,$b_irc,$b_root);
## System
my ($bsd_type,$device_vm,$language,$os,$pci_tool,$wan_url) = ('','','','','','');
@@ -135,17 +134,20 @@ my %sep = (
);
#$show{'host'} = 1;
my %size = (
-'console' => 115,
+'console' => 80, # In display, orig: 115
# Default indentation level. NOTE: actual indent is 1 greater to allow for
# spacing
'indent' => 11,
-'wrap-max' => 90,
+'indents' => 2,
'irc' => 100, # shorter because IRC clients have nick lists etc
-'max' => 0,
-'no-display' => 130,
-# these will be set dynamically in set_display_width()
-'term' => 80,
-'term-lines' => 100,
+'lines' => 1, # for active output line counter for -Y
+'max-cols' => 0,
+'max-lines' => 0,
+'max-wrap' => 110,
+'no-display' => 100, # No Display, orig: 130
+# this will be set dynamically in set_display_size()
+'term-cols' => 80, # orig: 80
+'term-lines' => 40, # orig: 100
);
my %use = (
'update' => 1, # switched off/on with maintainer config ALLOW_UPDATE
@@ -198,7 +200,7 @@ sub initialize {
set_system_files();
Configs::set();
# set_downloader();
- set_display_width('live');
+ set_display_size();
}
## CheckTools
@@ -211,7 +213,7 @@ sub set {
my ($action,$program,$message,@data);
foreach my $test (keys %commands){
($action,$program) = ('use','');
- $message = main::row_defaults('tool-present');
+ $message = main::message('tool-present');
if ($commands{$test}->[1] && (
($commands{$test}->[1] eq 'linux' && $os ne 'linux') ||
($commands{$test}->[1] eq 'bsd' && $os eq 'linux'))){
@@ -222,6 +224,8 @@ sub set {
# my $cmd = "$program $commands{$test} >/dev/null";
# print "$cmd\n";
$pci_tool = $test if $test =~ /pci/;
+ # this test is not ideal because other errors can make program fail, but
+ # we can't test for root since could be say, wheel permissions needed
if ($commands{$test}->[0] eq 'exec-sys'){
$action = 'permissions' if system("$program $commands{$test}->[2] >/dev/null 2>&1");
}
@@ -243,13 +247,13 @@ sub set {
$alerts{$test}->{'action'} = $action;
$alerts{$test}->{'path'} = $program;
if ($action eq 'missing'){
- $alerts{$test}->{'message'} = main::row_defaults('tool-missing-recommends',"$test");
+ $alerts{$test}->{'message'} = main::message('tool-missing-recommends',"$test");
}
elsif ($action eq 'permissions'){
- $alerts{$test}->{'message'} = main::row_defaults('tool-permissions',"$test");
+ $alerts{$test}->{'message'} = main::message('tool-permissions',"$test");
}
elsif ($action eq 'platform'){
- $alerts{$test}->{'message'} = main::row_defaults('tool-missing-os', $uname[0] . " $test");
+ $alerts{$test}->{'message'} = main::message('tool-missing-os', $uname[0] . " $test");
}
}
print Data::Dumper::Dumper \%alerts if $dbg[25];
@@ -290,13 +294,13 @@ sub set_dmidecode {
}
if ($action ne 'use' && $action ne 'permissions'){
if ($action eq 'smbios'){
- $alerts{'dmidecode'}->{'message'} = main::row_defaults('dmidecode-smbios');
+ $alerts{'dmidecode'}->{'message'} = main::message('dmidecode-smbios');
}
elsif ($action eq 'no-data'){
- $alerts{'dmidecode'}->{'message'} = main::row_defaults('dmidecode-dev-mem');
+ $alerts{'dmidecode'}->{'message'} = main::message('dmidecode-dev-mem');
}
elsif ($action eq 'unknown-error'){
- $alerts{'dmidecode'}->{'message'} = main::row_defaults('tool-unknown-error','dmidecode');
+ $alerts{'dmidecode'}->{'message'} = main::message('tool-unknown-error','dmidecode');
}
}
return $action;
@@ -444,63 +448,56 @@ sub set_basics {
$ppid = getppid();
}
-# args: $1 - default OR override default cols max integer count. $_[0]
-# is the display width override.
-sub set_display_width {
- my ($width) = @_;
- if ($width eq 'live'){
- ## sometimes tput will trigger an error (mageia) if irc client
- if (!$b_irc){
- if (my $program = check_program('tput')){
- # Arch urxvt: 'tput: unknown terminal "rxvt-unicode-256color"'
- # trips error if use qx(); in FreeBSD, if you use 2>/dev/null
- # it makes default value 80x24, who knows why?
- chomp($size{'term'} = qx{$program cols});
- chomp($size{'term-lines'} = qx{$program lines});
- $size{'term-cols'} = $size{'term'};
- }
- # print "tc: $size{'term'} cmc: $size{'console'}\n";
- # double check, just in case it's missing functionality or whatever
- if (!is_int($size{'term'} || $size{'term'} == 0)){
- $size{'term'}=80;
- # we'll be using this for terminal dimensions later so don't set default.
- # $size{'term-lines'}=100;
- }
- }
- # this lets you set different size for in or out of display server
- if (!$b_running_in_display && $size{'no-display'}){
- $size{'console'} = $size{'no-display'};
- }
- # term_cols is set in top globals, using tput cols
- # print "tc: $size{'term'} cmc: $size{'console'}\n";
- if ($size{'term'} < $size{'console'}){
- $size{'console'} = $size{'term'};
- }
- # adjust, some terminals will wrap if output cols == term cols
- $size{'console'} = ($size{'console'} - 2);
- # echo cmc: $size{'console'}
- # comes after source for user set stuff
- if (!$b_irc){
- $size{'max'} = $size{'console'};
- }
- else {
- $size{'max'} = $size{'irc'};
- }
+sub set_display_size {
+ ## sometimes tput will trigger an error (mageia) if irc client
+ if (!$b_irc){
+ if (my $program = check_program('tput')){
+ # Arch urxvt: 'tput: unknown terminal "rxvt-unicode-256color"'
+ # trips error if use qx(); in FreeBSD, if you use 2>/dev/null
+ # it makes default value 80x24, who knows why?
+ chomp($size{'term-cols'} = qx{$program cols});
+ chomp($size{'term-lines'} = qx{$program lines});
+ }
+ # print "tc: $size{'term-cols'} cmc: $size{'console'}\n";
+ # double check, just in case it's missing functionality or whatever
+ if (!is_int($size{'term-cols'} || $size{'term-cols'} == 0)){
+ $size{'term-cols'} = 80;
+ }
+ if (!is_int($size{'term-lines'} || $size{'term-lines'} == 0)){
+ $size{'term-lines'} = 24;
+ }
+ }
+ # this lets you set different size for in or out of display server
+ if (!$b_display && $size{'no-display'}){
+ $size{'console'} = $size{'no-display'};
+ }
+ # term_cols is set in top globals, using tput cols
+ # print "tc: $size{'term-cols'} cmc: $size{'console'}\n";
+ if ($size{'term-cols'} < $size{'console'}){
+ $size{'console'} = $size{'term-cols'};
+ }
+ # adjust, some terminals will wrap if output cols == term cols
+ $size{'console'} = ($size{'console'} - 1);
+ # echo cmc: $size{'console'}
+ # comes after source for user set stuff
+ if (!$b_irc){
+ $size{'max-cols'} = $size{'console'};
}
else {
- $size{'max'} = $width;
+ $size{'max-cols'} = $size{'irc'};
}
- # print "tc: $size{'term'} cmc: $size{'console'} cm: $size{'max'}\n";
+ # print "tc: $size{'term-cols'} cmc: $size{'console'} cm: $size{'max-cols'}\n";
}
sub set_os {
@uname = uname();
$os = lc($uname[0]);
$cpu_arch = lc($uname[-1]);
- if ($cpu_arch =~ /arm|aarch/){$b_arm = 1;}
- elsif ($cpu_arch =~ /mips/){$b_mips = 1}
- elsif ($cpu_arch =~ /power|ppc/){$b_ppc = 1}
- elsif ($cpu_arch =~ /sparc/){$b_sparc = 1}
+ if ($cpu_arch =~ /arm|aarch/){$risc{'arm'} = 1;$risc{'id'} = 'arm';}
+ elsif ($cpu_arch =~ /mips/){$risc{'mips'} = 1;$risc{'id'} = 'mips';}
+ elsif ($cpu_arch =~ /power|ppc/){$risc{'ppc'} = 1;$risc{'id'} = 'ppc';}
+ elsif ($cpu_arch =~ /riscv/){$risc{'riscv'} = 1;$risc{'id'} = 'riscv';}
+ elsif ($cpu_arch =~ /sparc/){$risc{'sparc'} = 1;$risc{'id'} = 'sparc';}
# aarch32 mips32 intel/amd handled in cpu
if ($cpu_arch =~ /(armv[1-7]|32|sparc_v9)/){
$bits_sys = 32;
@@ -856,7 +853,7 @@ sub set_colors {
}
}
# force 0 for | or > output, all others prints to irc or screen
- if (!$b_irc && ! -t STDOUT){
+ if (!$b_irc && !$force{'colors'} && ! -t STDOUT){
$color_scheme = 0;
}
set_color_scheme($color_scheme);
@@ -1003,8 +1000,7 @@ sub get_selection {
);
main::print_basic(\@data);
@data = ();
- my $response = <STDIN>;
- chomp($response);
+ chomp(my $response = <STDIN>);
if (!main::is_int($response) || $response > ($count + 3)){
@data = (
[0, '', '', "Error - Invalid Selection. You entered this: $response. Hit <ENTER> to continue."],
@@ -1178,6 +1174,7 @@ sub set {
# args: 0: key; 1: value
sub process_item {
my ($key,$val) = @_;
+ ## UTILITIES ##
if ($key eq 'ALLOW_UPDATE' || $key eq 'B_ALLOW_UPDATE'){
$use{'update'} = $val if main::is_int($val)}
elsif ($key eq 'ALLOW_WEATHER' || $key eq 'B_ALLOW_WEATHER'){
@@ -1245,7 +1242,7 @@ sub process_item {
$weather_unit = $val;
}
}
- # layout
+ ## COLORS/SEP ##
elsif ($key eq 'CONSOLE_COLOR_SCHEME'){
$colors{'console'} = $val if main::is_int($val)}
elsif ($key eq 'GLOBAL_COLOR_SCHEME'){
@@ -1267,7 +1264,7 @@ sub process_item {
$sep{'s2-irc'} = $val}
elsif ($key eq 'SEP2_CONSOLE'){
$sep{'s2-console'} = $val}
- # size
+ ## SIZES ##
elsif ($key eq 'COLS_MAX_CONSOLE'){
$size{'console'} = $val if main::is_int($val)}
elsif ($key eq 'COLS_MAX_IRC'){
@@ -1276,8 +1273,19 @@ sub process_item {
$size{'no-display'} = $val if main::is_int($val)}
elsif ($key eq 'INDENT'){
$size{'indent'} = $val if main::is_int($val)}
- elsif ($key eq 'WRAP_MAX' || $key eq 'INDENT_MIN'){
- $size{'wrap-max'} = $val if main::is_int($val)}
+ elsif ($key eq 'INDENTS'){
+ $filter_string = $val if main::is_int($val)}
+ elsif ($key eq 'LINES_MAX'){
+ if ($val =~ /^-?\d+$/ && $val >= -1){
+ if ($val == 0){
+ $size{'max-lines'} = $size{'term-lines'};}
+ elsif ($val == -1){
+ $size{'output-block'} = 1;}
+ else {
+ $size{'max-lines'} = $val;}
+ }}
+ elsif ($key eq 'MAX_WRAP' || $key eq 'WRAP_MAX' || $key eq 'INDENT_MIN'){
+ $size{'max-wrap'} = $val if main::is_int($val)}
# print "mc: key: $key val: $val\n";
# print Dumper (keys %size) . "\n";
}
@@ -1525,7 +1533,9 @@ sub run_debugger {
if ($debugger{'sys'} && main::count_dir_files('/sys')){
build_tree('sys');
# kernel crash, not sure what creates it, for ppc, as root
- sys_traverse_data() if ($debugger{'sys'} && ($debugger{'sys-force'} || !$b_root || !$b_ppc)) ;
+ if ($debugger{'sys'} && ($debugger{'sys-force'} || !$b_root || !$risc{'ppc'})){
+ sys_traverse_data();
+ }
}
else {
print "Skipping /sys data collection.\n";
@@ -1567,10 +1577,7 @@ sub create_debug_directory {
$root_string = '-root';
}
my $id = ($debugger{'id'}) ? '-' . $debugger{'id'}: '';
- if ($b_arm){$alt_string = '-ARM'}
- elsif ($b_mips){$alt_string = '-MIPS'}
- elsif ($b_ppc){$alt_string = '-PPC'}
- elsif ($b_sparc){$alt_string = '-SPARC'}
+ $alt_string = '-' . uc($risc{'id'}) if %risc;
$alt_string .= "-BSD-$bsd_type" if $bsd_type;
$alt_string .= '-ANDROID' if $b_android;
$alt_string .= '-CYGWIN' if $b_cygwin; # could be windows arm?
@@ -1846,9 +1853,10 @@ sub display_data {
'clutter-backend' => $ENV{'CLUTTER_BACKEND'},
'sdl-videodriver' => $ENV{'SDL_VIDEODRIVER'},
# program display values
- 'size-cols-max' => $size{'max'},
+ 'size-cols-max' => $size{'max-cols'},
'size-indent' => $size{'indent'},
- 'size-wrap-width' => $size{'wrap-max'},
+ 'size-lines-max' => $size{'max-lines'},
+ 'size-wrap-width' => $size{'max-wrap'},
);
write_data(\%data,'display');
my @cmds = (
@@ -2011,6 +2019,7 @@ sub system_data {
['dmidecode',''],
['dmesg',''],
['gcc','--version'],
+ ['getconf','-a'],
['initctl','list'],
['ipmi-sensors','-V'], # version
['ipmi-sensors',''],
@@ -2064,9 +2073,14 @@ sub system_data {
['vcgencmd','get_mem gpu'],
);
run_commands(\@cmds,'system');
+ my $glob = '/sys/devices/system/cpu/';
+ $glob .= '{cpufreq,cpu*/topology,cpu*/cpufreq,cpu*/cache/index*,smt,';
+ $glob .= 'vulnerabilities}/*';
+ get_glob('sys','cpu',$glob);
@files = main::globber('/dev/bus/usb/*/*');
copy_files(\@files, 'system');
}
+
sub system_files {
print "Collecting system files data...\n";
my (%data,@files,@files2);
@@ -2187,6 +2201,25 @@ sub run_commands {
}
}
}
+sub get_glob {
+ my ($type,$id,$glob) = @_;
+ my @files = main::globber($glob);
+ return if !@files;
+ my ($item,@result);
+ foreach (sort @files){
+ next if -d $_;
+ if (-r $_) {
+ $item = main::reader($_,'strip',0);
+ }
+ else {
+ $item = main::message('root-required');
+ }
+ $item = main::message('undefined') if ! defined $item;
+ push(@result,$_ . '::' . $item);
+ }
+ # print Data::Dumper::Dumper \@result;
+ main::writer("$data_dir/$type-data-$id-glob.txt",\@result);
+}
sub write_data {
my ($data_ref, $type) = @_;
my ($empty,$error,$fh,$good,$name,$undefined,$value);
@@ -2394,7 +2427,7 @@ sub wanted {
# block maybe: cfgroup\/
# picdec\/|, wait_for_fb_sleep/wake is an odroid thing caused hang
# wakeup_count also fails for android, but works fine on regular systems
- return if $b_arm && $File::Find::name =~ m!^/sys/power/(wait_for_fb_|wakeup_count$)!;
+ return if $risc{'arm'} && $File::Find::name =~ m!^/sys/power/(wait_for_fb_|wakeup_count$)!;
# do not need . files or __ starting files
return if $File::Find::name =~ m!/\.[a-z]!;
# pp_num_states: amdgpu driver bug; android: wakeup_count
@@ -3303,7 +3336,7 @@ sub item_data {
'rpm' => '?',
},
'sudo' => {
- 'info' => '-Dx hddtemp-user; -o file-user',
+ 'info' => '-Dx hddtemp-user; -o file-user (try doas!)',
'info-bsd' => '-Dx hddtemp-user; -o file-user (alt for doas)',
'apt' => 'sudo',
'pacman' => 'sudo',
@@ -3502,7 +3535,7 @@ sub get_pm {
sub make_row {
my ($start,$middle,$end) = @_;
my ($dots,$line,$sep) = ('','',': ');
- foreach (0 .. ($size{'max'} - 16 - length("$start$middle"))){
+ foreach (0 .. ($size{'max-cols'} - 16 - length("$start$middle"))){
$dots .= '.';
}
$line = "$start$sep$middle$dots $end";
@@ -3510,7 +3543,7 @@ sub make_row {
}
sub make_line {
my $line = '';
- foreach (0 .. $size{'max'} - 2){
+ foreach (0 .. $size{'max-cols'} - 2){
$line .= '-';
}
return $line;
@@ -3665,13 +3698,14 @@ sub is_hex {
## NOTE: for perl pre 5.012 length(undef) returns warning
# receives string, returns boolean 1 if integer
sub is_int {
- return 1 if (defined $_[0] && length($_[0]) && length($_[0]) == ($_[0] =~ tr/0123456789//));
+ return 1 if (defined $_[0] && length($_[0]) &&
+ length($_[0]) == ($_[0] =~ tr/0123456789//));
}
-# receives string, returns boolean 1 if numeric. tr/// is 4x faster than regex
+# receives string, returns true/1 if >= 0 numeric. tr/// 4x faster than regex
sub is_numeric {
return 1 if (defined $_[0] && ($_[0] =~ tr/0123456789//) >= 1 &&
- length($_[0]) == ($_[0] =~ tr/0123456789.//) && ($_[0] =~ tr/.//) <= 1);
+ length($_[0]) == ($_[0] =~ tr/0123456789.//) && ($_[0] =~ tr/.//) <= 1);
}
# gets array ref, which may be undefined, plus join string
@@ -4461,7 +4495,7 @@ sub get {
'B|battery' => sub {
$show{'short'} = 0;
$show{'battery'} = 1;
- $show{'battery-forced'} = 1; },
+ $show{'battery-forced'} = 1;},
'c|color:i' => sub {
my ($opt,$arg) = @_;
if ($arg >= 0 && $arg < main::get_color_scheme('count')){
@@ -4475,14 +4509,14 @@ sub get {
} },
'C|cpu' => sub {
$show{'short'} = 0;
- $show{'cpu'} = 1; },
+ $show{'cpu'} = 1;},
'd|disk-full|optical' => sub {
$show{'short'} = 0;
$show{'disk'} = 1;
- $show{'optical'} = 1; },
+ $show{'optical'} = 1;},
'D|disk' => sub {
$show{'short'} = 0;
- $show{'disk'} = 1; },
+ $show{'disk'} = 1;},
'E|bluetooth' => sub {
$show{'short'} = 0;
$show{'bluetooth'} = 1;
@@ -4490,7 +4524,7 @@ sub get {
'f|flags|flag' => sub {
$show{'short'} = 0;
$show{'cpu'} = 1;
- $show{'cpu-flag'} = 1; },
+ $show{'cpu-flag'} = 1;},
'F|full' => sub {
$show{'short'} = 0;
$show{'audio'} = 1;
@@ -4508,13 +4542,13 @@ sub get {
$show{'raid'} = 1;
$show{'sensor'} = 1;
$show{'swap'} = 1;
- $show{'system'} = 1; },
+ $show{'system'} = 1;},
'G|graphics|graphic' => sub {
$show{'short'} = 0;
$show{'graphic'} = 1;
- $show{'graphic-basic'} = 1; },
+ $show{'graphic-basic'} = 1;},
'h|help|?' => sub {
- $show{'help'} = 1; },
+ $show{'help'} = 1;},
'i|ip' => sub {
$show{'short'} = 0;
$show{'ip'} = 1;
@@ -4523,13 +4557,13 @@ sub get {
$use{'downloader'} = 1 if ! main::check_program('dig');},
'I|info' => sub {
$show{'short'} = 0;
- $show{'info'} = 1; },
+ $show{'info'} = 1;},
'j|swap|swaps' => sub {
$show{'short'} = 0;
$show{'swap'} = 1;},
'J|usb' => sub {
$show{'short'} = 0;
- $show{'usb'} = 1; },
+ $show{'usb'} = 1;},
'l|labels|label' => sub {
$show{'label'} = 1;},
'limit:i' => sub {
@@ -4542,10 +4576,10 @@ sub get {
} },
'L|logical|lvm' => sub {
$show{'short'} = 0;
- $show{'logical'} = 1; },
+ $show{'logical'} = 1;},
'm|memory' => sub {
$show{'short'} = 0;
- $show{'ram'} = 1; },
+ $show{'ram'} = 1;},
'memory-modules' => sub {
$show{'short'} = 0;
$show{'ram'} = 1;
@@ -4556,24 +4590,24 @@ sub get {
$show{'ram-short'} = 1;},
'M|machine' => sub {
$show{'short'} = 0;
- $show{'machine'} = 1; },
+ $show{'machine'} = 1;},
'n|network-advanced' => sub {
$show{'short'} = 0;
$show{'network'} = 1;
- $show{'network-advanced'} = 1; },
+ $show{'network-advanced'} = 1;},
'N|network' => sub {
$show{'short'} = 0;
- $show{'network'} = 1; },
+ $show{'network'} = 1;},
'o|unmounted' => sub {
$show{'short'} = 0;
- $show{'unmounted'} = 1; },
+ $show{'unmounted'} = 1;},
'p|partition-full|partitions-full' => sub {
$show{'short'} = 0;
$show{'partition'} = 0;
- $show{'partition-full'} = 1; },
+ $show{'partition-full'} = 1;},
'P|partitions|partition' => sub {
$show{'short'} = 0;
- $show{'partition'} = 1; },
+ $show{'partition'} = 1;},
'partition-sort:s' => sub {
my ($opt,$arg) = @_;
if ($arg =~ /^(dev-base|fs|id|label|percent-used|size|uuid|used)$/){
@@ -4584,14 +4618,14 @@ sub get {
} },
'r|repos|repo' => sub {
$show{'short'} = 0;
- $show{'repo'} = 1; },
+ $show{'repo'} = 1;},
'R|raid' => sub {
$show{'short'} = 0;
$show{'raid'} = 1;
- $show{'raid-forced'} = 1; },
+ $show{'raid-forced'} = 1;},
's|sensors|sensor' => sub {
$show{'short'} = 0;
- $show{'sensor'} = 1; },
+ $show{'sensor'} = 1;},
'sleep:s' => sub {
my ($opt,$arg) = @_;
$arg ||= 0;
@@ -4603,10 +4637,10 @@ sub get {
} },
'slots|slot' => sub {
$show{'short'} = 0;
- $show{'slot'} = 1; },
+ $show{'slot'} = 1;},
'S|system' => sub {
$show{'short'} = 0;
- $show{'system'} = 1; },
+ $show{'system'} = 1;},
't|processes|process:s' => sub {
my ($opt,$arg) = @_;
$show{'short'} = 0;
@@ -4773,19 +4807,42 @@ sub get {
$arg = 80;
}
if ($arg =~ /\d/ && ($arg == 1 || $arg >= 80)){
- main::set_display_width($arg);
+ $size{'max-cols'} = $arg;
}
else {
main::error_handler('bad-arg', $opt, $arg);
- } },
+ }},
+ 'Y|height|less:i' => sub {
+ my ($opt, $arg) = @_;
+ main::error_handler('not-in-irc', '-Y/--height') if $b_irc;
+ if ($arg >= -3){
+ if ($arg >= 0){
+ $size{'max-lines'} = ($arg) ? $arg: $size{'term-lines'};
+ }
+ elsif ($arg == -1) {
+ $use{'output-block'} = 1;
+ }
+ elsif ($arg == -2) {
+ $force{'colors'} = 1;
+ }
+ # unset conifiguration set max height
+ else {
+ $size{'max-lines'} = 0;
+ }
+ }
+ else {
+ main::error_handler('bad-arg', $opt, $arg);
+ }},
'z|filter' => sub {
- $use{'filter'} = 1; },
- 'filter-label' => sub {
- $use{'filter-label'} = 1; },
- 'Z|filter-override' => sub {
- $use{'filter-override'} = 1; },
- 'filter-uuid' => sub {
- $use{'filter-uuid'} = 1; },
+ $use{'filter'} = 1;},
+ 'filter-label|zl' => sub {
+ $use{'filter-label'} = 1;},
+ 'Z|filter-override|no-filter' => sub {
+ $use{'filter-override'} = 1;},
+ 'filter-uuid|zu' => sub {
+ $use{'filter-uuid'} = 1;},
+ 'filter-v|filter-vulnerabilities|zv' => sub {
+ $use{'filter-vulnerabilities'} = 1;},
## Start non data options
'alt:i' => sub {
my ($opt,$arg) = @_;
@@ -4810,7 +4867,9 @@ sub get {
main::error_handler('bad-arg', $opt, $arg);
}},
'arm' => sub {
- $b_arm = 1 },
+ undef %risc;
+ $risc{'id'} = 'arm';
+ $risc{'arm'} = 1;},
'bsd:s' => sub {
my ($opt,$arg) = @_;
if ($arg =~ /^(darwin|dragonfly|freebsd|openbsd|netbsd)$/i){
@@ -4864,17 +4923,17 @@ sub get {
'debug-no-exit' => sub {
$debugger{'no-exit'} = 1 },
'debug-no-proc' => sub {
- $debugger{'no-proc'} = 1; },
+ $debugger{'no-proc'} = 1;},
'debug-no-sys' => sub {
- $debugger{'sys'} = 0; },
+ $debugger{'sys'} = 0;},
'debug-proc' => sub {
- $debugger{'proc'} = 1; },
+ $debugger{'proc'} = 1;},
'debug-proc-print' => sub {
$debugger{'proc-print'} = 1;},
'debug-sys-print' => sub {
- $debugger{'sys-print'} = 1; },
+ $debugger{'sys-print'} = 1;},
'debug-test-1' => sub {
- $debugger{'test-1'} = 1; },
+ $debugger{'test-1'} = 1;},
'debug-width|debug-y|debug-zy:i' => sub {
my ($opt,$arg) = @_;
$arg ||= 80;
@@ -4885,7 +4944,7 @@ sub get {
main::error_handler('bad-arg', $opt, $arg);
} },
'dig' => sub {
- $force{'no-dig'} = 0; },
+ $force{'no-dig'} = 0;},
'display:s' => sub {
my ($opt,$arg) = @_;
if ($arg =~ /^:?([0-9\.]+)?$/){
@@ -4945,8 +5004,8 @@ sub get {
'force:s' => sub {
my ($opt,$arg) = @_;
if ($arg){
- my $wl = 'display|dmidecode|hddtemp|lsusb|man|meminfo|no-dig|';
- $wl .= 'no-doas|no-html-wan|no-sudo|pkg|usb-sys|vmstat|wmctrl';
+ my $wl = 'colors|cpuinfo|display|dmidecode|hddtemp|lsusb|man|meminfo|';
+ $wl .= 'no-dig|no-doas|no-html-wan|no-sudo|pkg|usb-sys|vmstat|wmctrl';
for (split(',',$arg)){
if ($_ =~ /\b($wl)\b/){
$force{lc($1)} = 1;
@@ -4974,13 +5033,39 @@ sub get {
$show{'host'} = 1;
$show{'no-host'} = 0},
'html-wan' => sub {
- $force{'no-html-wan'} = 0; },
+ $force{'no-html-wan'} = 0;},
+ 'indent:i' => sub {
+ my ($opt,$arg) = @_;
+ if ($arg >= 11){
+ $size{'indent'} = $arg;
+ }
+ else {
+ main::error_handler('bad-arg', $opt, $arg);
+ }},
+ 'indents:i' => sub {
+ my ($opt,$arg) = @_;
+ if ($arg >= 0 && $arg < 11){
+ $size{'indents'} = $arg;
+ }
+ else {
+ main::error_handler('bad-arg', $opt, $arg);
+ }},
'irc' => sub {
- $b_irc = 1; },
+ $b_irc = 1;},
'man' => sub {
- $use{'yes-man'} = 1; },
+ $use{'yes-man'} = 1;},
+ 'max-wrap|wrap-max|indent-min:i' => sub {
+ my ($opt,$arg) = @_;
+ if ($arg >= 0){
+ $size{'max-wrap'} = $arg;
+ }
+ else {
+ main::error_handler('bad-arg', $opt, $arg);
+ }},
'mips' => sub {
- $b_mips = 1 },
+ undef %risc;
+ $risc{'id'} = 'mips';
+ $risc{'mips'} = 1;},
'output:s' => sub {
my ($opt,$arg) = @_;
if ($arg =~ /^(json|screen|xml)$/){
@@ -4990,20 +5075,20 @@ sub get {
main::error_handler('bad-arg', $opt, $arg);
}},
'no-dig' => sub {
- $force{'no-dig'} = 1; },
+ $force{'no-dig'} = 1;},
'no-doas' => sub {
- $force{'no-doas'} = 1; },
+ $force{'no-doas'} = 1;},
'no-host|no-hostname' => sub {
$show{'host'} = 0 ;
$show{'no-host'} = 1},
'no-html-wan' => sub {
$force{'no-html-wan'}= 1;},
'no-man' => sub {
- $use{'no-man'} = 0; },
+ $use{'no-man'} = 0;},
'no-ssl' => sub {
$dl{'no-ssl-opt'}=1 },
'no-sudo' => sub {
- $force{'no-sudo'} = 1; },
+ $force{'no-sudo'} = 1;},
'output-file:s' => sub {
my ($opt,$arg) = @_;
if ($arg){
@@ -5020,11 +5105,17 @@ sub get {
'pkg' => sub {
$force{'pkg'} = 1 },
'ppc' => sub {
- $b_ppc = 1 },
+ undef %risc;
+ $risc{'id'} = 'ppc';
+ $risc{'ppc'} = 1;},
'recommends' => sub {
$show{'recommends'} = 1;},
+ 'riscv' => sub {
+ undef %risc;
+ $risc{'id'} = 'riscv';
+ $risc{'riscv'} = 1;},
'sensors-default' => sub {
- $use{'sensors-default'} = 1; },
+ $use{'sensors-default'} = 1;},
'sensors-exclude:s' => sub {
my ($opt,$arg) = @_;
if ($arg){
@@ -5042,11 +5133,13 @@ sub get {
main::error_handler('bad-arg',$opt,$arg);
}},
'sparc' => sub {
- $b_sparc = 1; },
+ undef %risc;
+ $risc{'id'} = 'sparc';
+ $risc{'sparc'} = 1;},
'sys-debug' => sub {
- $debugger{'sys-force'} = 1; },
+ $debugger{'sys-force'} = 1;},
'tty' => sub { # workaround for ansible running this
- $b_irc = 0; },
+ $b_irc = 0;},
'U|update:s' => sub { # 1,2,3 OR http://myserver/path/inxi
my ($opt,$arg) = @_;
process_updater($opt,$arg);},
@@ -5065,14 +5158,6 @@ sub get {
}},
'wm' => sub {
$force{'wmctrl'} = 1 },
- 'wrap-max|indent-min:i' => sub {
- my ($opt,$arg) = @_;
- if ($arg =~ /^\d+$/){
- $size{'wrap-max'} = $arg;
- }
- else {
- main::error_handler('bad-arg', $opt, $arg);
- }},
'<>' => sub {
my ($opt) = @_;
main::error_handler('unknown-option', "$opt", "");}
@@ -5250,133 +5335,131 @@ sub show_options {
my $color_scheme_count = get_color_scheme('count') - 1;
my $partition_string='partition';
my $partition_string_u='Partition';
- my $flags = ($b_arm) ? 'features' : 'flags' ;
+ my $flags = (%risc || $bsd_type) ? 'features' : 'flags' ;
if ($bsd_type){
$partition_string='slice';
$partition_string_u='Slice';
}
# fit the line to the screen!
- for my $i (0 .. (($size{'max'} / 2) - 2)){
+ for my $i (0 .. (($size{'max-cols'} / 2) - 2)){
$line = $line . '- ';
}
push(@data,
['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', '', '', '' ],
+ it will display a short system summary."],
+ ['0', '', '', ''],
['0', '', '', "You can use these options alone or together,
to show or add the item(s) you want to see: A, B, C, D, E, G, I, J, L, 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." ],
+ lines to the output."],
['0', '', '', '' ],
['0', '', '', "Examples:^$self_name^-v4^-c6 OR $self_name^-bDc^6 OR
- $self_name^-FzjJxy^80" ],
+ $self_name^-FzjJxy^80"],
['0', '', '', $line ],
- ['0', '', '', "Output Control Options (see Extra Data Options to extend output):" ],
- ['1', '-A', '--audio', "Audio/sound devices(s), driver, running sound servers." ],
- ['1', '-b', '--basic', "Basic output, short form. Same as $self_name^-v^2." ],
+ ['0', '', '', "See Filter Options for output filtering, Output Control Options
+ for colors, sizing, output changes, Extra Data Options to extend Main output,
+ Additional Options and Advanced Options for less common situations."],
+ ['0', '', '', $line ],
+ ['0', '', '', "Main Feature Options:"],
+ ['1', '-A', '--audio', "Audio/sound devices(s), driver, running sound
+ servers."],
+ ['1', '-b', '--basic', "Basic output, short form. Same as $self_name^-v^2."],
['1', '-B', '--battery', "System battery info, including charge, condition
- voltage (if critical), plus extra info (if battery present/detected)." ],
- ['1', '-c', '--color', "Set color scheme (0-42). For piped or redirected output,
- you must use an explicit color selector. Example:^$self_name^-c^11" ],
- ['1', '', '', "Color selectors let you set the config file value for the
- selection (NOTE: IRC and global only show safe color set)" ],
- ['2', '94', '', "Console, out of X" ],
- ['2', '95', '', "Terminal, running in X - like xTerm" ],
- ['2', '96', '', "Gui IRC, running in X - like Xchat, Quassel, Konversation etc." ],
- ['2', '97', '', "Console IRC running in X - like irssi in xTerm" ],
- ['2', '98', '', "Console IRC not in X" ],
- ['2', '99', '', "Global - Overrides/removes all settings. Setting specific
- removes global." ],
- ['1', '-C', '--cpu', "CPU output, including per CPU clock speed and max
- CPU speed (if available)." ],
+ voltage (if critical), plus extra info (if battery present/detected)."],
+ ['1', '-C', '--cpu', "CPU output (if each item available): basic topology,
+ model, type (see man for types), cache, average CPU speed, min/max speeds,
+ per core clock speeds."],
['1', '-d', '--disk-full, --optical', "Optical drive data (and floppy disks,
- if present). Triggers -D." ],
+ 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_string}
- size(s)." ],
- ['1', '-E', '--bluetooth', "Show bluetooth device data and report, if available.
- Shows state, address, IDs, version info." ],
+ size(s)."],
+ ['1', '-E', '--bluetooth', "Show bluetooth device data and report, if
+ available. Shows state, address, IDs, version info."],
['1', '-f', '--flags', "All CPU $flags. Triggers -C. Not shown with -F to
- avoid spamming." ],
+ avoid spamming."],
['1', '-F', '--full', "Full output. Includes all Upper Case line letters
- (except -J, -W) plus --swap, -s and -n. Does not show extra verbose options such
- as -d -f -i -J -l -m -o -p -r -t -u -x, unless specified." ],
- ['1', '-G', '--graphics', "Graphics info (devices(s), drivers, display protocol
- (if available), display server/Wayland compositor, resolution, renderer,
- OpenGL version)." ],
+ (except -J, -W) plus --swap, -s and -n. Does not show extra verbose options
+ such as -d -f -i -J -l -m -o -p -r -t -u -x, unless specified."],
+ ['1', '-G', '--graphics', "Graphics info (devices(s), drivers, display
+ protocol (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." ],
+ 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. Use with -j, -o, -p, -P." ],
+ 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. Use with -j, -o, -p, -P."],
['1', '-L', '--logical', "Logical devices, LVM (VG, LV),
- LUKS, Crypto, bcache, etc. Shows components/devices, sizes, etc." ],
+ LUKS, Crypto, bcache, etc. Shows components/devices, sizes, etc."],
['1', '-m', '--memory', "Memory (RAM) data. Requires root. Numbers of
devices (slots) supported and individual memory devices (sticks of memory etc).
For devices, shows device locator, size, speed, type (e.g. DDR3).
- If neither -I nor -tm are selected, also shows RAM used/total." ],
- ['1', '', '--memory-modules', "Memory (RAM) data. Exclude empty module slots." ],
- ['1', '', '--memory-short', "Memory (RAM) data. Show only short Memory RAM report,
- number of arrays, slots, modules, and RAM type." ],
+ If neither -I nor -tm are selected, also shows RAM used/total."],
+ ['1', '', '--memory-modules', "Memory (RAM) data. Exclude empty module slots."],
+ ['1', '', '--memory-short', "Memory (RAM) data. Show only short Memory RAM
+ report, number of arrays, slots, modules, and RAM type."],
['1', '-M', '--machine', "Machine data. Device type (desktop, server, laptop,
VM etc.), motherboard, BIOS and, if present, system builder (e.g. Lenovo).
Shows UEFI/BIOS/UEFI [Legacy]. Older systems/kernels without the required /sys
- data can use dmidecode instead, run as root. Dmidecode can be forced with --dmidecode" ],
- ['1', '-n', '--network-advanced', "Advanced Network device info. Triggers -N. Shows
- interface, speed, MAC id, state, etc. " ],
- ['1', '-N', '--network', "Network device(s), driver." ],
+ data can use dmidecode instead, run as root. Dmidecode can be forced with
+ --dmidecode"],
+ ['1', '-n', '--network-advanced', "Advanced Network device info. Triggers -N.
+ Shows interface, speed, MAC id, state, etc. "],
+ ['1', '-N', '--network', "Network device(s), driver."],
['1', '-o', '--unmounted', "Unmounted $partition_string info (includes UUID
and Label if available). Shows file system type if you have lsblk installed
(Linux) or, for BSD/GNU Linux, if 'file' installed and you are root or if
- you have added to /etc/sudoers (sudo v. 1.7 or newer)(BSDs: see doas)." ],
- ['1', '', '', "Example: ^<username>^ALL^=^NOPASSWD:^/usr/bin/file^" ],
- ['1', '-p', '--partitions-full', "Full $partition_string information (-P plus all other
- detected ${partition_string}s)." ],
+ you have added to /etc/sudoers (sudo v. 1.7 or newer)(or try doas)."],
+ ['1', '', '', "Example: ^<username>^ALL^=^NOPASSWD:^/usr/bin/file^"],
+ ['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. Swap
${partition_string}s show if --swap is not used. Use -p to see all
- mounted ${partition_string}s." ],
+ mounted ${partition_string}s."],
['1', '-r', '--repos', "Distro repository data. Supported repo types: APK,
APT, CARDS, EOPKG, NIX, PACMAN, PACMAN-G2, PISI, PKG (BSDs), PORTAGE, PORTS
- (BSDs), SCRATCHPKG, SLACKPKG, TCE, URPMQ, XBPS, YUM/ZYPP." ],
- ['1', '-R', '--raid', "RAID data. Shows RAID devices, states, levels, array sizes,
- and components. md-raid: If device is resyncing, also shows resync progress line." ],
+ (BSDs), SCRATCHPKG, SLACKPKG, TCE, URPMQ, XBPS, YUM/ZYPP."],
+ ['1', '-R', '--raid', "RAID data. Shows RAID devices, states, levels, array
+ sizes, and components. md-raid: If device is resyncing, also shows resync
+ progress line."],
['1', '-s', '--sensors', "Sensors output (if sensors installed/configured):
mobo/CPU/GPU temp; detected fan speeds. GPU temp only for Fglrx/Nvidia drivers.
- Nvidia shows screen number for > 1 screen. IPMI sensors if present." ],
- ['1', '', '--slots', "PCI slots: type, speed, status. Requires root." ],
+ Nvidia shows screen number for > 1 screen. IPMI sensors if present."],
+ ['1', '', '--slots', "PCI slots: type, speed, status. Requires root."],
['1', '-S', '--system', "System info: host name, kernel, desktop environment
- (if in X/Wayland), distro." ],
+ (if in X/Wayland), distro."],
['1', '-t', '--processes', "Processes. Requires extra options: c (CPU), m
(memory), cm (CPU+memory). If followed by numbers 1-x, shows that number
- of processes for each type (default: 5; if in IRC, max: 5). " ],
+ 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', '-u', '--uuid', "$partition_string_u UUIDs. Use with -j, -o, -p, -P." ],
+ numbers (e.g.^-t^cm10)."],
+ ['1', '-u', '--uuid', "$partition_string_u UUIDs. Use with -j, -o, -p, -P."],
['1', '-v', '--verbosity', "Set $self_name verbosity level (0-8).
- Should not be used with -b or -F. Example: $self_name^-v^4" ],
- ['2', '0', '', "Same as: $self_name" ],
- ['2', '1', '', "Basic verbose, -S + basic CPU + -G + basic Disk + -I." ],
- ['2', '2', '', "Networking device (-N), Machine (-M), Battery (-B; if present),
- and, if present, basic RAID (devices only; notes if inactive).
- Same as $self_name^-b" ],
+ Should not be used with -b or -F. Example: $self_name^-v^4"],
+ ['2', '0', '', "Same as: $self_name"],
+ ['2', '1', '', "Basic verbose, -S + basic CPU + -G + basic Disk + -I."],
+ ['2', '2', '', "Networking device (-N), Machine (-M), Battery (-B; if
+ present), and, if present, basic RAID (devices only; notes if inactive). Same
+ as $self_name^-b"],
['2', '3', '', "Advanced CPU (-C), battery (-B), network (-n);
- triggers -x. " ],
+ triggers -x. "],
['2', '4', '', "$partition_string_u size/used data (-P) for
- (if present) /, /home, /var/, /boot. Shows full disk data (-D). " ],
+ (if present) /, /home, /var/, /boot. Shows full disk data (-D). "],
['2', '5', '', "Audio device (-A), sensors (-s), memory/RAM (-m),
bluetooth (if present), $partition_string label^(-l), full swap (-j),
- UUID^(-u), short form of optical drives, RAID data (if present)." ],
+ UUID^(-u), short form of optical drives, RAID data (if present)."],
['2', '6', '', "Full $partition_string (-p),
unmounted $partition_string (-o), optical drive (-d), USB (-J),
- full RAID; triggers -xx." ],
+ full RAID; triggers -xx."],
['2', '7', '', "Network IP data (-i), bluetooth, logical (-L),
- RAID forced; triggers -xxx."],
+ RAID forced, full CPU $flags; triggers -xxx."],
['2', '8', '', "Everything available, including repos (-r),
processes (-tcm), PCI slots (--slots); triggers admin (-a)."],
);
@@ -5391,316 +5474,364 @@ sub show_options {
want the weather somewhere other than the machine running $self_name. Use
only ASCII characters, replace spaces in city/state/country names with '+'.
Example:^$self_name^-W^[new+york,ny^london,gb^madrid,es]"],
- ['1', '', '--weather-source', "[1-9] Change weather data source. 1-4 generally
- active, 5-9 check. See man."],
+ ['1', '', '--weather-source', "[1-9] Change weather data source. 1-4
+ generally active, 5-9 check. See man."],
['1', '', '--weather-unit', "Set weather units to metric (m), imperial (i),
metric/imperial (mi), or imperial/metric (im)."],
);
}
push(@data,
- ['1', '-y', '--width', "Output line width max (integer >= 80). Overrides IRC/Terminal
- 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, host name. 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', '', '', "Extra Data Options:" ],
+ [0, '', '', "$line"],
+ ['0', '', '', "Filter Options:"],
+ ['1', '', '--host', "Turn on hostname for -S. Overrides -z."],
+ ['1', '', '--no-host', "Turn off hostname for -S. Useful if showing output
+ from servers etc. Activated by -z as well."],
+ ['1', '-z', '--filter', "Adds security filters for IP/MAC addresses, serial
+ numbers, location (-w), user home directory name, host name. Default on for
+ IRC clients."],
+ ['1', '', '--zl,--filter-label', "Filters out ${partition_string} labels in
+ -j, -o, -p, -P, -Sa."],
+ ['1', '', '--zu,--filter-uuid', "Filters out ${partition_string} UUIDs in -j,
+ -o, -p, -P, -Sa."],
+ ['1', '', '--zv,--filter-vulnerabilities', "Filters out Vulnerabilities
+ report in -Ca."],
+ ['1', '-Z', '--no-filter', "Disable output filters. Useful for debugging
+ networking issues in IRC, or you needed to use --tty, for example."],
+ [0, '', '', "$line"],
+ ['0', '', '', "Output Control Options:"],
+ ['1', '-c', '--color', "Set color scheme (0-42). For piped or redirected
+ output, you must use an explicit color selector. Example:^$self_name^-c^11"],
+ ['1', '', '', "Color selectors let you set the config file value for the
+ selection (NOTE: IRC and global only show safe color set)"],
+ ['2', '94', '', "Console, out of X"],
+ ['2', '95', '', "Terminal, running in X - like xTerm"],
+ ['2', '96', '', "Gui IRC, running in X - like Xchat, Quassel, Konversation
+ etc."],
+ ['2', '97', '', "Console IRC running in X - like irssi in xTerm"],
+ ['2', '98', '', "Console IRC not in X"],
+ ['2', '99', '', "Global - Overrides/removes all settings. Setting specific
+ removes global."],
+ ['1', '', '--indent', "[11-20] Change default wide mode primary indentation
+ width."],
+ ['1', '', '--indents', "[0-10] Change wrapped mode primary indentation width,
+ and secondary / -y1 indent widths."],
+ ['1', '', '--limit', "[-1; 1-x] Set max output limit of IP addresses for -i
+ (default 10; -1 removes limit)."],
+ ['1', '', '--max-wrap,--wrap-max', "[70-xxx] Set maximum width where
+ $self_name autowraps line starters. Current: $size{'max-wrap'}"],
+ ['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_string} output. See man page for specifics."],
+ ['1', '-y', '--width', "[empty|-1|1|80-xxx] Output line width max. Overrides
+ IRC/Terminal 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', '-Y', '--height', "[empty|-3-xxx] Output height control. Similar to
+ 'less' command except colors preserved, defaults to console/terminal height.
+ -1 shows 1 primary Item: at a time; -2 retains color on redirect/piping (to
+ less -R); -3 removes configuration value; 0 or -Y sets to detected terminal
+ height. Greater than 0 shows x lines at a time."],
+ ['0', '', '', "$line"],
+ ['0', '', '', "Extra Data Options:"],
['1', '-a', '--admin', "Adds advanced sys admin data (only works with
verbose or line output, not short form); check man page for explanations!;
- also sets --extra=3:" ],
+ also sets --extra=3:"],
['2', '-A', '', "If available: list of alternate kernel modules/drivers
- for device(s)." ],
+ for device(s)."],
['2', '-C', '', "If available: CPU socket type, base/boost speeds
- (dmidecode+root/sudo/doas[BSDs] 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;
- maj:min, USB drive specifics; SMART report." ],
+ (dmidecode+root/sudo/doas required); Full topology line, with cores, threads,
+ threads per core, granular cache data, smt status; CPU vulnerabilities (bugs);
+ family, model-id, stepping - format: hex (decimal) if greater than 9;
+ microcode format: hex."],
+ ['2', '-d,-D', '', "If available: logical and physical block sizes; drive
+ family; maj:min, USB drive specifics; SMART report."],
['2', '-E', '', "If available: in Report:, adds Info: line: acl-mtu,
- sco-mtu, link-policy, link-mode, service-classes." ],
+ sco-mtu, link-policy, link-mode, service-classes."],
['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)." ],
+ 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; adds init
- service tool." ],
+ service tool."],
['2', '-j,-p,-P', '', "For swap (if available): swappiness and vfs cache
- pressure, and if values are default or not." ],
+ pressure, and if values are default or not."],
['2', '-L', '', "LV, Crypto, devices, components: add maj:min; show
- full device/components report (speed, mapped names)." ],
+ full device/components report (speed, mapped names)."],
['2', '-n,-N', '', "If available: list of alternate kernel modules/drivers
- for device(s)." ],
- ['2', '-o', '', "If available: maj:min of device." ],
+ for device(s)."],
+ ['2', '-o', '', "If available: maj:min of device."],
['2', '-p,-P', '', "If available: raw size of ${partition_string}s, maj:min,
- percent available for user, block size of file system (root required)." ],
- ['2', '-r', '', "Packages, see -Ia." ],
- ['2', '-R', '', "mdraid: device maj:min; per component: size, maj:min, state." ],
- ['2', '-S', '', "If available: kernel boot parameters." ],
+ percent available for user, block size of file system (root required)."],
+ ['2', '-r', '', "Packages, see -Ia."],
+ ['2', '-R', '', "mdraid: device maj:min; per component: size, maj:min, state."],
+ ['2', '-S', '', "If available: kernel boot parameters."],
['0', '', '', ''],
['1', '-x', '--extra', "Adds the following extra data (only works with
- verbose or line output, not short form):" ],
+ verbose or line output, not short form):"],
['2', '-A', '', "Specific vendor/product information (if relevant);
PCI/USB ID of device; Version/port(s)/driver version (if available);
- non-running sound servers." ],
+ non-running sound servers."],
['2', '-B', '', "Current/minimum voltage, vendor/model, status (if available);
- attached devices (e.g. wireless mouse, keyboard, if present)." ],
- ['2', '-C', '', "CPU $flags (short list, use -f to see full list);
- CPU boost (turbo) enabled/disabled, if present;
- Bogomips on CPU; CPU microarchitecture + revision (if found, or
- unless --admin, then shows as 'stepping')." ],
+ attached devices (e.g. wireless mouse, keyboard, if present)."],
+ ['2', '-C', '', "L1/L3 cache (if most Linux, or if root and dmidecode
+ installed); smt if disabled, CPU $flags (short list, use -f to see full list);
+ Highest core speed (if > 1 core); CPU boost (turbo) enabled/disabled, if
+ present; Bogomips on CPU; CPU microarchitecture + revision (if found, or
+ unless --admin, then shows as 'stepping')."],
['2', '-d', '', "Extra optical drive features data; adds rev version to
- optical drive." ],
+ optical drive."],
['2', '-D', '', "HDD temp with disk data. Kernels >= 5.6: enable module
drivetemp if not enabled. Older systems require hddtemp, run as
as superuser, or as user if you have added hddtemp to /etc/sudoers
- (sudo v. 1.7 or newer)(BSDs see doas).
- Example:^<username>^ALL^=^NOPASSWD:^/usr/sbin/hddtemp" ],
+ (sudo v. 1.7 or newer)(or try doas).
+ Example:^<username>^ALL^=^NOPASSWD:^/usr/sbin/hddtemp"],
['2', '-E', '', "PCI/USB Bus ID of device, driver version,
- LMP version." ],
+ LMP version."],
['2', '-G', '', "Specific vendor/product information (if relevant);
PCI/USB ID of device; Direct rendering status (in X); Screen
- number GPU is running on (Nvidia only)." ],
+ number GPU is running on (Nvidia only)."],
['2', '-i', '', "For IPv6, show additional scope addresses: Global, Site,
- Temporary, Unknown. See --limit for large counts of IP addresses." ],
+ 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). Total
- count of all packages discovered in system and not -r." ],
- ['2', '-j', '', "Add mapped: name if partition mapped." ],
- ['2', '-J', '', "For Device: driver." ],
- ['2', '-L', '', "For VG > LV, and other Devices, dm:" ],
- ['2', '-m,--memory-modules', '', "Max memory module size (if available), device type." ],
+ count of all packages discovered in system and not -r."],
+ ['2', '-j', '', "Add mapped: name if partition mapped."],
+ ['2', '-J', '', "For Device: driver."],
+ ['2', '-L', '', "For VG > LV, and other Devices, dm:"],
+ ['2', '-m,--memory-modules', '', "Max memory module size (if available),
+ device type."],
['2', '-N', '', "Specific vendor/product information (if relevant);
- PCI/USB ID of device; Version/port(s)/driver version (if available)." ],
- ['2', '-o,-p,-P', '', "Add mapped: name if partition mapped." ],
- ['2', '-r', '', "Packages, see -Ix." ],
+ PCI/USB ID of device; Version/port(s)/driver version (if available)."],
+ ['2', '-o,-p,-P', '', "Add mapped: name if partition mapped."],
+ ['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." ],
- ['2', '-s', '', "Basic voltages (ipmi, lm-sensors if present): 12v, 5v, 3.3v, vbat." ],
+ synced/total blocks. Hardware RAID driver version, bus-ID."],
+ ['2', '-s', '', "Basic voltages (ipmi, lm-sensors if present): 12v, 5v, 3.3v,
+ vbat."],
['2', '-S', '', "Kernel gcc version; system base of distro (if relevant
- and detected)" ],
+ and detected)"],
['2', '-t', '', "Adds memory use output to CPU (-xt c), and CPU use to
- memory (-xt m)." ],
+ memory (-xt m)."],
);
if ($use{'weather'}){
push(@data,
['2', '-w,-W', '', "Wind speed and direction, humidity, pressure,
- and time zone, if available." ]);
+ and time zone, if available."]);
}
push(@data,
['0', '', '', ''],
['1', '-xx', '--extra 2', "Show extra, extra data (only works with verbose
- or line output, not short form):" ],
- ['2', '-A', '', "Chip vendor:product ID for each audio device." ],
- ['2', '-B', '', "Serial number." ],
- ['2', '-C', '', "L1/L3 cache (if root and dmidecode installed)." ],
+ or line output, not short form):"],
+ ['2', '-A', '', "Chip vendor:product ID for each audio device."],
+ ['2', '-B', '', "Serial number."],
['2', '-D', '', "Disk transfer speed; NVMe lanes; Disk serial number; LVM
- volume group free space (if available); disk duid (some BSDs)." ],
- ['2', '-E', '', "Chip vendor:product ID, LMP subversion." ],
+ volume group free space (if available); disk duid (some BSDs)."],
+ ['2', '-E', '', "Chip vendor:product ID, LMP subversion."],
['2', '-G', '', "Chip vendor:product ID for each video device; OpenGL
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 device vendor, but is not installed on system;
- Xorg dpi." ],
+ driver check list of Xorg for the device 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 pty/tty) for shell info if not in
IRC. Adds Init version number, RC (if found). Adds per package manager
- installed package counts if not -r." ],
- ['2', '-j,-p,-P', '', "Swap priority." ],
- ['2', '-J', '', "Vendor:chip-ID." ],
+ installed package counts if not -r."],
+ ['2', '-j,-p,-P', '', "Swap priority."],
+ ['2', '-J', '', "Vendor:chip-ID."],
['2', '-L', '', "Show internal LVM volumes, like raid image/meta volumes;
for LVM RAID, adds RAID report line (if not -R); show all components >
- devices, number of 'c' or 'p' indicate depth of device." ],
- ['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." ],
+ devices, number of 'c' or 'p' indicate depth of device."],
+ ['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)." ],
+ shows progress bar. Hardware RAID Chip vendor:product ID."],
+ ['2', '-s', '', "DIMM/SOC voltages (ipmi only)."],
['2', '-S', '', "Display manager (dm) in desktop output (e.g. kdm,
gdm3, lightdm); active window manager if detected; desktop toolkit,
- if available (Xfce/KDE/Trinity only)." ],
- ['2', '--slots', '', "Slot length." ],
+ if available (Xfce/KDE/Trinity only)."],
+ ['2', '--slots', '', "Slot length."],
);
if ($use{'weather'}){
push(@data,
['2', '-w,-W', '', "Snow, rain, precipitation, (last observed hour),
- cloud cover, wind chill, dew point, heat index, if available." ]
+ cloud cover, wind chill, dew point, heat index, if available."]
);
}
push(@data,
['0', '', '', ''],
['1', '-xxx', '--extra 3', "Show extra, extra, extra data (only works
- with verbose or line output, not short form):" ],
- ['2', '-A', '', "Serial number, class ID." ],
- ['2', '-B', '', "Chemistry, cycles, location (if available)." ],
- ['2', '-C', '', "CPU voltage, external clock speed (if root and dmidecode installed)." ],
- ['2', '-D', '', "Firmware rev. if available; partition scheme, in some cases; disk
- type, rotation rpm (if available)." ],
- ['2', '-E', '', "Serial number, class ID, HCI version and revision." ],
- ['2', '-G', '', "Serial number, class ID." ],
- ['2', '-I', '', "For 'Shell:' adds ([doas|su|sudo|login]) to shell name if present;
- adds default shell+version if different; for 'running in:' adds (SSH) if SSH session;
- adds wakeups: (from suspend) to Uptime." ],
- ['2', '-J', '', "If present: Devices: serial number, interface count; USB speed; max power." ],
- ['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." ],
- ['2', '-N', '', "Serial number, class ID." ],
+ with verbose or line output, not short form):"],
+ ['2', '-A', '', "Serial number, class ID."],
+ ['2', '-B', '', "Chemistry, cycles, location (if available)."],
+ ['2', '-C', '', "CPU voltage, external clock speed (if root and dmidecode
+ installed); smt status, if available."],
+ ['2', '-D', '', "Firmware rev. if available; partition scheme, in some cases;
+ disk type, rotation rpm (if available)."],
+ ['2', '-E', '', "Serial number, class ID, HCI version and revision."],
+ ['2', '-G', '', "Serial number, class ID."],
+ ['2', '-I', '', "For 'Shell:' adds ([doas|su|sudo|login]) to shell name if
+ present; adds default shell+version if different; for 'running in:' adds (SSH)
+ if SSH session; adds wakeups: (from suspend) to Uptime."],
+ ['2', '-J', '', "If present: Devices: serial number, interface count; USB
+ speed; max power."],
+ ['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."],
+ ['2', '-N', '', "Serial number, class ID."],
['2', '-R', '', "zfs-raid: portion allocated (used) by RAID devices/arrays.
- md-raid: system md-raid support types (kernel support, read ahead, RAID events).
- Hardware RAID rev, ports, specific vendor/product information." ],
- ['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, virtual terminal number."],
+ md-raid: system md-raid support types (kernel support, read ahead, RAID
+ events). Hardware RAID rev, ports, specific vendor/product information."],
+ ['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, virtual terminal number."],
);
if ($use{'weather'}){
push(@data,
['2', '-w,-W', '', "Location (uses -z/irc filter), weather observation
- time, altitude, sunrise/sunset, if available." ]
+ time, altitude, sunrise/sunset, if available."]
);
}
push(@data,
- [0, '', '', "$line" ],
- [0, '', '', "Additional Options:" ],
- ['1', '-h', '--help', "This help menu." ],
- ['1', '', '--recommends', "Checks $self_name application dependencies + recommends,
- and directories, then shows what package(s) you need to install to add support
- for that feature." ],
+ [0, '', '', "$line"],
+ [0, '', '', "Additional Options:"],
+ ['1', '-h', '--help', "This help menu."],
+ ['1', '', '--recommends', "Checks $self_name application dependencies +
+ recommends, and directories, then shows what package(s) you need to install
+ to add support for that feature."],
);
if ($use{'update'}){
push(@data,
- ['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
- user is fine. Man page installs require root. No arguments downloads from
- main $self_name git repo." ],
- ['1', '', '', "Use alternate sources for updating $self_name" ],
- ['2', '1', '', "Get the git branch one version." ],
- ['2', '2', '', "Get the git branch two version." ],
- ['3', '3', '', "Get the dev server (smxi.org) version." ],
+ ['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 user is fine. Man page installs require root. No arguments
+ downloads from main $self_name git repo."],
+ ['1', '', '', "Use alternate sources for updating $self_name"],
+ ['2', '1', '', "Get the git branch one version."],
+ ['2', '2', '', "Get the git branch two version."],
+ ['3', '3', '', "Get the dev server (smxi.org) version."],
['2', '<http>', '', "Get a version of $self_name from your own server.
- Use the full download path, e.g.^$self_name^-U^https://myserver.com/inxi" ],
+ Use the full download path, e.g.^$self_name^-U^https://myserver.com/inxi"],
);
}
push(@data,
- ['1', '-V', '--version', "Prints $self_name version info then exits." ],
- ['0', '', '', "$line" ],
- ['0', '', '', "Advanced Options:" ],
- ['1', '', '--alt', "Trigger for various advanced options:" ],
- ['2', '40', '', "Bypass Perl as a downloader option." ],
- ['2', '41', '', "Bypass Curl as a downloader option." ],
- ['2', '42', '', "Bypass Fetch as a downloader option." ],
- ['2', '43', '', "Bypass Wget as a downloader option." ],
+ ['1', '-V', '--version', "Prints $self_name version info then exits."],
+ ['0', '', '', "$line"],
+ ['0', '', '', "Advanced Options:"],
+ ['1', '', '--alt', "Trigger for various advanced options:"],
+ ['2', '40', '', "Bypass Perl as a downloader option."],
+ ['2', '41', '', "Bypass Curl as a downloader option."],
+ ['2', '42', '', "Bypass Fetch as a downloader option."],
+ ['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', '', '--bt-tool', "[bt-adapter|hciconfig|rfkill] Force use of given tool for
- bluetooth report." ],
- ['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', '', '--force', "[dmidecode|hddtemp|lsusb|meminfo|usb-sys|vmstat|wmctl]. 1 or more
- in comma separated list. Force use of item(s).
- See --hddtemp, --dmidecode, --wm, --usb-tool, --usb-sys." ],
- ['1', '', '--hddtemp', "Force use of hddtemp for disk temps." ],
- ['1', '', '--host', "Turn on hostname for -S." ],
- ['1', '', '--html-wan', "Overrides configuration item NO_HTML_WAN (resets to default)." ],
- ['1', '', '--limit', "[-1; 1-x] Set max output limit of IP addresses for -i
- (default 10; -1 removes limit)." ],
+ Perl if HTTP::Tiny present."],
+ ['1', '', '--bt-tool', "[bt-adapter|hciconfig|rfkill] Force use of given tool
+ for bluetooth report."],
+ ['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', '', '--force', "[dmidecode|hddtemp|lsusb|meminfo|usb-sys|vmstat|wmctrl].
+ 1 or more in comma separated list. Force use of item(s).
+ See --hddtemp, --dmidecode, --wm, --usb-tool, --usb-sys."],
+ ['1', '', '--hddtemp', "Force use of hddtemp for disk temps."],
+ ['1', '', '--html-wan', "Overrides configuration item NO_HTML_WAN (resets to
+ default)."],
);
if ($use{'update'}){
push(@data,
- ['1', '', '--man', "Install correct man version for dev branch (-U 3) or pinxi using -U." ],
+ ['1', '', '--man', "Install correct man version for dev branch (-U 3) or
+ pinxi using -U."],
);
}
push(@data,
- ['1', '', '--no-dig', "Skip dig for WAN IP checks, use downloader program." ],
- ['1', '', '--no-doas', "Skip internal program use of doas features (not related
- to starting $self_name with doas)." ],
- ['1', '', '--no-host', "Turn off hostname for -S. Useful if showing output from servers etc.
- -z triggers --no-host." ],
- ['1', '', '--no-html-wan', "Skip HTML IP sources for WAN IP checks, use dig only,
- or nothing if --no-dig." ],
+ ['1', '', '--no-dig', "Skip dig for WAN IP checks, use downloader program."],
+ ['1', '', '--no-doas', "Skip internal program use of doas features (not
+ related to starting $self_name with doas)."],
+ ['1', '', '--no-html-wan', "Skip HTML IP sources for WAN IP checks, use dig
+ only, or nothing if --no-dig."],
);
if ($use{'update'}){
push(@data,
- ['1', '', '--no-man', "Disable man install for all -U update actions." ],
+ ['1', '', '--no-man', "Disable man install for all -U update actions."],
);
}
push(@data,
['1', '', '--no-ssl', "Skip SSL certificate checks for all downloader actions
- (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_string} output. See man page for specifics." ],
- ['1', '', '--pkg', "Force use of disabled package manager counts for packages feature.
- RPM disabled by default due to possible massive rpm package query times." ],
- ['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)." ],
+ (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', '', '--pkg', "Force use of disabled package manager counts for packages
+ feature. RPM disabled by default due to possible massive rpm package query
+ times."],
+ ['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" ],
- ['1', '', '--tty', "Forces irc flag to false. Generally useful if $self_name is running
- inside of another tool like Chef or MOTD and returns corrupted color codes. Please see
- man page or file an issue if you need to use this flag. Must use -y [width] option if
- you want a specific output width. Always put this option first in an option list."],
- ['1', '', '--usb-sys', "Force USB data to use only /sys as data source (Linux only)." ],
+ use. Example:^$self_name^-Cxxx^--sleep^0.15"],
+ ['1', '', '--tty', "Forces irc flag to false. Generally useful if $self_name
+ is running inside of another tool like Chef or MOTD and returns corrupted
+ color codes. Please see man page or file an issue if you need to use this
+ flag. Must use -y [width] option if you want a specific output width. Always
+ put this option first in an option list. See -Z for disabling output filters
+ as well."],
+ ['1', '', '--usb-sys', "Force USB data to use only /sys as data source (Linux
+ only)."],
['1', '', '--usb-tool', "Force USB data to use lsusb as data source [default]
- (Linux only)." ],
+ (Linux only)."],
['1', '', '--wan-ip-url', "[URL] Skips dig, uses supplied URL for WAN IP (-i).
URL output must end in the IP address. See man.
- Example:^$self_name^-i^--wan-ip-url^https://yoursite.com/ip.php" ],
- ['1', '', '--wm', "Force wm: to use wmctrl as data source. Default uses ps." ],
- ['1', '', '--wrap-max', "Set maximum width where $self_name autowraps line starters
- (previously --indent-min). Current: $size{'wrap-max'}" ],
+ Example:^$self_name^-i^--wan-ip-url^https://yoursite.com/ip.php"],
+ ['1', '', '--wm', "Force wm: to use wmctrl as data source. Default uses ps."],
['0', '', '', $line ],
- ['0', '', '', "Debugging Options:" ],
- ['1', '', '--dbg', "Specific debuggers, change often. Only 1 is constant:" ],
- ['2', '1', '', "Show downloader output. Turns off quiet mode." ],
- ['1', '', '--debug', "Triggers debugging modes." ],
- ['2', '1-3', '', "On screen debugger output." ],
- ['2', '10', '', "Basic logging." ],
- ['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.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." ],
+ ['0', '', '', "Debugging Options:"],
+ ['1', '', '--dbg', "[1-xx] Specific debuggers, change often. See man page."],
+ ['2', '1', '', "Show downloader output. Turns off quiet mode."],
+ ['1', '', '--debug', "[1-3|10|11|20-22] Triggers debugging modes."],
+ ['2', '1-3', '', "On screen debugger output."],
+ ['2', '10', '', "Basic logging."],
+ ['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.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."],
['2', '21', '', "Upload debugger dataset to $self_name debugger server
- automatically, removes debugger data directory, leaves tar.gz debugger file." ],
+ automatically, removes debugger data directory, leaves tar.gz debugger file."],
['2', '22', '', "Upload debugger dataset to $self_name debugger server
- automatically, removes debugger data directory and debugger tar.gz file." ],
- # ['1', '', '--debug-filter', "Add -z flag to debugger $self_name optiions." ],
- ['1', '', '--debug-proc', "Force debugger parsing of /proc as sudo/doas/root." ],
- ['1', '', '--debug-proc-print', "To locate file that /proc debugger hangs on." ],
- ['1', '', '--debug-no-exit', "Skip exit on error to allow completion." ],
- ['1', '', '--debug-no-proc', "Skip /proc debugging in case of a hang." ],
- ['1', '', '--debug-no-sys', "Skip /sys debugging in case of a hang." ],
- ['1', '', '--debug-sys', "Force PowerPC debugger parsing of /sys as sudo/doas/root." ],
- ['1', '', '--debug-sys-print', "To locate file that /sys debugger hangs on." ],
- ['1', '', '--ftp', "Use with --debugger 21 to trigger an alternate FTP server for upload.
- Format:^[ftp.xx.xx/yy]. Must include a remote directory to upload to.
- Example:^$self_name^--debug^21^--ftp^ftp.myserver.com/incoming" ],
- ['0', '', '', "$line" ],
+ automatically, removes debugger data directory and debugger tar.gz file."],
+ # ['1', '', '--debug-filter', "Add -z flag to debugger $self_name optiions."],
+ ['1', '', '--debug-id', "[short-string] Add given string to debugger file
+ name. Helps identify source of debugger dataset. Use with --debug 20-22."],
+ ['1', '', '--debug-proc', "Force debugger parsing of /proc as sudo/doas/root."],
+ ['1', '', '--debug-proc-print', "To locate file that /proc debugger hangs on."],
+ ['1', '', '--debug-no-exit', "Skip exit on error to allow completion."],
+ ['1', '', '--debug-no-proc', "Skip /proc debugging in case of a hang."],
+ ['1', '', '--debug-no-sys', "Skip /sys debugging in case of a hang."],
+ ['1', '', '--debug-sys', "Force PowerPC debugger parsing of /sys as
+ sudo/doas/root."],
+ ['1', '', '--debug-sys-print', "To locate file that /sys debugger hangs on."],
+ ['1', '', '--ftp', "Use with --debugger 21 to trigger an alternate FTP server
+ for upload. Format:^[ftp.xx.xx/yy]. Must include a remote directory to upload
+ to. Example:^$self_name^--debug^21^--ftp^ftp.myserver.com/incoming"],
+ ['0', '', '', "$line"],
);
print_basic(\@data);
exit 0; # shell true
@@ -5782,7 +5913,7 @@ sub set {
eval $start if $b_log;
main::set_ps_aux() if !$loaded{'ps-aux'};
if (!$b_irc){
- # we'll run get_shell_data for -I, but only then
+ # we'll run ShellData::set() for -I, but only then
}
else {
$use{'filter'} = 1;
@@ -5953,6 +6084,7 @@ sub get_client_version {
$client{'name-print'} = $client{'name'};
}
$b_irc = 0;
+ $use{'filter'} = 0;
}
else {
$client{'name-print'} = 'Unknown Client: ' . $client{'name'};
@@ -6081,7 +6213,6 @@ sub check_modern_konvi {
eval $end if $b_log;
return $b_modern_konvi;
}
-
sub set_konvi_data {
eval $start if $b_log;
my $config_tool = '';
@@ -6124,39 +6255,25 @@ sub set_konvi_data {
########################################################################
#### -------------------------------------------------------------------
-#### FILTERS AND TOOLS
+#### CLEANERS, FILTERS, AND TOOLS
#### -------------------------------------------------------------------
-sub apply_filter {
- my ($string) = @_;
- if ($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 clean {
+ my ($item) = @_;
+ return $item if !$item;# handle cases where it was 0 or ''
+ # note: |nee trips engineering, but I don't know why nee was filtered
+ $item =~ s/chipset|company|components|computing|computer|corporation|communications|electronics|electrical|electric|gmbh|group|incorporation|industrial|international|\bnee\b|no\sstring|revision|semiconductor|software|technologies|technology|ltd\.|<ltd>|\bltd\b|inc\.|<inc>|\binc\b|intl\.|co\.|<co>|corp\.|<corp>|\(tm\)|\(r\)|®|\(rev ..\)|\'|\"|\sinc\s*$|\?//gi;
+ $item =~ s/,|\*/ /g;
+ $item =~ s/^\s+|\s+$//g;
+ $item =~ s/\s\s+/ /g;
+ return $item;
}
-sub arm_cleaner {
+sub clean_arm {
my ($item) = @_;
$item =~ s/(\([^\(]*Device Tree[^\)]*\))//gi;
- $item =~ s/\s\s+/ /g;
$item =~ s/^\s+|\s+$//g;
+ $item =~ s/\s\s+/ /g;
return $item;
}
@@ -6172,49 +6289,122 @@ sub clean_characters {
return $data;
}
-sub cleaner {
- my ($item) = @_;
- return $item if !$item;# handle cases where it was 0 or ''
- # note: |nee trips engineering, but I don't know why nee was filtered
- $item =~ s/chipset|company|components|computing|computer|corporation|communications|electronics|electrical|electric|gmbh|group|incorporation|industrial|international|\bnee\b|no\sstring|revision|semiconductor|software|technologies|technology|ltd\.|<ltd>|\bltd\b|inc\.|<inc>|\binc\b|intl\.|co\.|<co>|corp\.|<corp>|\(tm\)|\(r\)|®|\(rev ..\)|\'|\"|\sinc\s*$|\?//gi;
- $item =~ s/,|\*/ /g;
- $item =~ s/\s\s+/ /g;
- $item =~ s/^\s+|\s+$//g;
- return $item;
-}
-
-sub disk_cleaner {
+sub clean_disk {
my ($item) = @_;
return $item if !$item;
# <?unknown>?|
$item =~ s/vendor.*|product.*|O\.?E\.?M\.?//gi;
- $item =~ s/\s\s+/ /g;
$item =~ s/^\s+|\s+$//g;
+ $item =~ s/\s\s+/ /g;
return $item;
}
-sub dmi_cleaner {
+sub clean_dmi {
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>|<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 = clean_unset($string,'AssetTagNum|^Base Board .*|^Chassis .*|' .
+ 'Manufacturer.*| Or Motherboard|\bOther\b.*|PartNum.*|SerNum|' .
+ '^System .*|^0x[0]+$');
+ $string =~ s/\bbios\b|\bacpi\b//gi;
$string =~ s/http:\/\/www.abit.com.tw\//Abit/i;
+ $string =~ s/^[\s'"]+|[\s'"]+$//g;
$string =~ s/\s\s+/ /g;
- $string =~ s/^\s+|\s+$//g;
$string = remove_duplicates($string) if $string;
return $string;
}
-sub general_cleaner {
+sub clean_pci {
+ my ($string,$type) = @_;
+ # print "st1 $type:$string\n";
+ my $filter = 'and\ssubsidiaries|compatible\scontroller|';
+ $filter .= '\b(device|controller|connection|multimedia)\b|\([^)]+\)';
+ # \[[^\]]+\]$| not trimming off ending [...] initial type filters removes end
+ $filter = '\[[^\]]+\]$|' . $filter if $type eq 'pci';
+ $string =~ s/($filter)//ig;
+ $string =~ s/^[\s'"]+|[\s'"]+$//g;
+ $string =~ s/\s\s+/ /g;
+ # print "st2 $type:$string\n";
+ $string = remove_duplicates($string) if $string;
+ return $string;
+}
+
+sub clean_pci_subsystem {
my ($string) = @_;
- my $cleaner = '\b(defauult string|empty|none|undefined.*|unknown|unspecified)\b';
- $string =~ s/$cleaner//i;
+ # we only need filters for features that might use vendor, -AGN
+ my $filter = 'and\ssubsidiaries|adapter|(hd\s)?audio|definition|desktop|ethernet|';
+ $filter .= 'gigabit|graphics|hdmi(\/[\S]+)?|high|integrated|motherboard|network|onboard|';
+ $filter .= 'raid|pci\s?express';
+ $string =~ s/\b($filter)\b//ig;
+ $string =~ s/^[\s'"]+|[\s'"]+$//g;
+ $string =~ s/\s\s+/ /g;
return $string;
}
+# Use sparingly, but when we need regex type stuff
+# stripped out for reliable string compares, it's better.
+# sometimes the pattern comes from unknown strings
+# which can contain regex characters, get rid of those
+sub clean_regex {
+ my ($string) = @_;
+ return if !$string;
+ $string =~ s/(\{|\}|\(|\)|\[|\]|\|)/ /g;
+ $string =~ s/^\s+|\s+$//g;
+ $string =~ s/\s\s+/ /g;
+ return $string;
+}
+
+# $extra optional, if you want to add custom filter to defaults
+sub clean_unset {
+ my ($string,$extra) = @_;
+ my $cleaner = '^(\.)+$|Bad Index|default string|\[?empty\]?|\bnone\b|N\/A|^not |';
+ $cleaner .= 'not set|OUT OF SPEC|To be filled|O\.?E\.?M|undefine|unknow|unspecif';
+ $cleaner .= '|' . $extra if $extra;
+ $string =~ s/.*($cleaner).*//i;
+ return $string;
+}
+
+sub filter {
+ my ($string) = @_;
+ if ($string){
+ if ($use{'filter'} && $string ne message('root-required')){
+ $string = $filter_string;
+ }
+ }
+ else {
+ $string = 'N/A';
+ }
+ return $string;
+}
+
+# note, let the print logic handle N/A cases
+sub filter_partition {
+ 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 filter_pci_long {
+ my ($string) = @_;
+ if ($string =~ /\[AMD(\/ATI)?\]/){
+ $string =~ s/Advanced\sMicro\sDevices\s\[AMD(\/ATI)?\]/AMD/;
+ }
+ return $string;
+}
+
+# args: list of values, return the first one that is defined
+sub get_defined {
+ for (@_){
+ return $_ if defined $_;
+ }
+ return; # don't return undef explicitly, only implicitly!
+}
+
# args: $1 - vendor id; $2 - product id
# returns print ready vendor:chip id string, or na variants
sub get_chip_id {
@@ -6290,75 +6480,11 @@ sub increment_starters {
return $result;
}
-sub pci_cleaner {
- my ($string,$type) = @_;
- # print "st1 $type:$string\n";
- my $filter = 'and\ssubsidiaries|compatible\scontroller|';
- $filter .= '\b(device|controller|connection|multimedia)\b|\([^)]+\)';
- # \[[^\]]+\]$| not trimming off ending [...] initial type filters removes end
- $filter = '\[[^\]]+\]$|' . $filter if $type eq 'pci';
- $string =~ s/($filter)//ig;
- $string =~ s/\s\s+/ /g;
- $string =~ s/^\s+|\s+$//g;
- # print "st2 $type:$string\n";
- $string = remove_duplicates($string) if $string;
- return $string;
-}
-
-sub pci_cleaner_subsystem {
- my ($string) = @_;
- # we only need filters for features that might use vendor, -AGN
- my $filter = 'and\ssubsidiaries|adapter|(hd\s)?audio|definition|desktop|ethernet|';
- $filter .= 'gigabit|graphics|hdmi(\/[\S]+)?|high|integrated|motherboard|network|onboard|';
- $filter .= 'raid|pci\s?express';
- $string =~ s/\b($filter)\b//ig;
- $string =~ s/\s\s+/ /g;
- $string =~ s/^\s+|\s+$//g;
- return $string;
-}
-
-sub pci_long_filter {
- my ($string) = @_;
- if ($string =~ /\[AMD(\/ATI)?\]/){
- $string =~ s/Advanced\sMicro\sDevices\s\[AMD(\/ATI)?\]/AMD/;
- }
- return $string;
-}
-
-# Use sparingly, but when we need regex type stuff
-# stripped out for reliable string compares, it's better.
-# sometimes the pattern comes from unknown strings
-# which can contain regex characters, get rid of those
-sub regex_cleaner {
- my ($string) = @_;
- return if !$string;
- $string =~ s/(\{|\}|\(|\)|\[|\]|\|)/ /g;
- $string =~ s/\s\s+/ /g;
- $string =~ s/^\s+|\s+$//g;
- return $string;
-}
-
-sub remove_duplicates {
- my ($string) = @_;
- return if !$string;
- my $holder = '';
- my (@temp);
- foreach (split(/\s+/, $string)){
- if ($holder ne $_){
- push(@temp, $_);
- }
- $holder = $_;
- }
- $string = join(' ', @temp);
- return $string;
-}
-
-sub row_defaults {
+sub message {
my ($type,$id) = @_;
$id ||= '';
my %unfound = (
'arm-cpu-f' => 'Use -f option to see features',
- 'arm-pci' => 'No ARM data found for this feature.',
'battery-data' => 'No system battery data found. Is one present?',
'battery-data-bsd' => 'No battery data found. Try with --dmidecode',
'battery-data-sys' => 'No /sys data found.',
@@ -6367,6 +6493,7 @@ sub row_defaults {
'cpu-bugs-null' => 'No CPU vulnerability/bugs data available.',
'cpu-model-null' => 'Model N/A',
'cpu-speeds' => 'No per core speed data found.',
+ 'cpu-speeds-bsd' => 'No OS support for core speeds.',
'darwin-feature' => 'Feature not supported iu Darwin/OSX.',
'disk-data' => 'No disk data found.',
'disk-data-bsd' => 'No disk data found.',
@@ -6394,11 +6521,12 @@ sub row_defaults {
'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.',
'machine-data-force-dmidecode' => 'No machine data: try newer kernel. Is dmidecode installed? Try -M --dmidecode.',
- 'mips-pci' => 'No MIPS data found for this feature.',
'note-check' => 'check',
'note-est' => 'est.',
'optical-data' => 'No optical or floppy data found.',
'optical-data-bsd' => 'No optical or floppy data found.',
+ 'output-control' => "-:: 'Enter' to continue to next block. Any key + 'Enter' to exit:",
+ 'output-control-exit' => 'Exiting output. Have a nice day.',
'output-limit' => "Output throttled. IPs: $id; Limit: $limit; Override: --limit [1-x;-1 all]",
'package-data' => 'No packages detected. Unsupported package manager?',
'partition-data' => 'No partition data found.',
@@ -6416,6 +6544,7 @@ sub row_defaults {
'recommends' => 'see --recommends',
'repo-data', "No repo data detected. Does $self_name support your package manager?",
'repo-data-bsd', "No repo data detected. Does $self_name support $id?",
+ 'risc-pci' => 'No ' . uc($id) . ' data found for this feature.',
'root-feature' => 'Feature requires superuser permissions.',
'root-item-incomplete' => "Full $id report requires superuser permissions.",
'root-required' => '<superuser required>',
@@ -6441,10 +6570,13 @@ sub row_defaults {
'tool-unknown-error' => "Unknown $id error. Unable to generate data.",
'tools-missing' => "This feature requires one of these tools: $id",
'tools-missing-bsd' => "This feature requires one of these tools: $id",
+ 'undefined' => '<undefined>',
'unmounted-data' => 'No unmounted partitions found.',
'unmounted-data-bsd' => "Unmounted partition feature unsupported in $id.",
'unmounted-file' => 'No /proc/partitions file found.',
+ 'unsupported' => '<unsupported>',
'usb-data' => 'No USB data found. Server?',
+ 'unknown-cpu-topology' => 'ERR-103',
'unknown-desktop-version' => 'ERR-101',
'unknown-dev' => 'ERR-102',
'unknown-shell' => 'ERR-100',
@@ -6454,6 +6586,34 @@ sub row_defaults {
return $unfound{$type};
}
+# string of range types (2-5; 3 4; 3,4,2-12) to generate single regex string for
+sub regex_range {
+ return if ! defined $_[0];
+ my @processed;
+ foreach my $item (split(/[,\s]+/,$_[0])){
+ if ($item =~ /(\d+)-(\d+)/){
+ $item = join('|',($1..$2));
+ }
+ push(@processed,$item);
+ }
+ return join('|',@processed);
+}
+
+sub remove_duplicates {
+ my ($string) = @_;
+ return if !$string;
+ my $holder = '';
+ my (@temp);
+ foreach (split(/\s+/, $string)){
+ if ($holder ne $_){
+ push(@temp, $_);
+ }
+ $holder = $_;
+ }
+ $string = join(' ', @temp);
+ return $string;
+}
+
# convert string passed to KB, based on GB/MB/TB id
# NOTE: K 1024 KB 1000 KiB 1024
# The logic will turn false MB to M for this tool
@@ -6593,6 +6753,18 @@ sub key {
return sprintf("%03d#%s#%s#%s", $_[0],$_[1],$_[2],$_[3]);
}
+sub output_control {
+ print message('output-control');
+ chomp(my $response = <STDIN>);
+ if (!$response){
+ $size{'lines'} = 1;
+ }
+ else {
+ print message('output-control-exit'), "\n";
+ exit 0;
+ }
+}
+
sub print_basic {
my ($data) = @_;
my $indent = 18;
@@ -6603,11 +6775,10 @@ sub print_basic {
my $indent2 = 8;
my $length = @$data;
my ($start,$i,$j,$line);
-
- if ($size{'max'} > 110){
+ if ($size{'max-cols'} > 110){
$indent_static = 22;
}
- elsif ($size{'max'} < 90){
+ elsif ($size{'max-cols'} < 90){
$indent_static = 15;
}
# print $length . "\n";
@@ -6640,7 +6811,7 @@ sub print_basic {
$start = '';
# print "1-print.\n";
}
- if (($indent + length($data->[$i][3])) < $size{'max'}){
+ if (($indent + length($data->[$i][3])) < $size{'max-cols'}){
$data->[$i][3] =~ s/\^/ /g;
$line = sprintf("%-${indent}s%s\n", "$start", $data->[$i][3]);
print_line($line);
@@ -6653,12 +6824,12 @@ sub print_basic {
# then splits like awk, on one or more white spaces.
foreach my $word (split(' ', $data->[$i][3])){
# print "$word\n";
- if (($indent + length($holder) + length($word)) < $size{'max'}){
+ if (($indent + length($holder) + length($word)) < $size{'max-cols'}){
$word =~ s/\^/ /g;
$holder .= $word . $sep;
# print "3-hold.\n";
}
- # elsif (($indent + length($holder) + length($word)) >= $size{'max'}){
+ # elsif (($indent + length($holder) + length($word)) >= $size{'max-cols'}){
else {
$line = sprintf("%-${indent}s%s\n", "$start", $holder);
print_line($line);
@@ -6682,26 +6853,31 @@ sub print_basic {
# hash key to force sorts.
sub print_data {
my ($data) = @_;
- my ($array,$counter,$length,$split_count) = (0,0,0,0);
+ my ($counter,$length,$split_count) = (0,0,0);
my ($hash_id,$holder,$start,$start2,$start_holder) = ('','','','','');
my $indent = $size{'indent'};
- my (@temp,@working,@values,%ids,%row);
- my ($holder2,$key,$line,$val2,$val3);
+ my (%ids);
+ my ($b_container,$b_ni2,$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;
+ my $b_single = ($size{'max-cols'} == 1) ? 1: 0;
+ my ($b_row1,$indent_2,$indent_use,$indentx) = (1,0,0,0);
+ # $size{'max-cols'} = 88;
# NOTE: indent < 11 would break the output badly in some cases
- if ($size{'max'} < $size{'wrap-max'} || $size{'indent'} < 11){
- $indent = 2;
+ if ($size{'max-cols'} < $size{'max-wrap'} || $size{'indent'} < 11){
+ $indent = $size{'indents'};
}
- # 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))[3];
+ $b_row1 = 1;
if ($key ne 'SHORT'){
$start = sprintf("$colors{'c1'}%-${indent}s$colors{'cn'}","$key$sep{'s1'}");
+ if ($use{'output-block'}){
+ output_control() if $use{'output-block'} > 1;
+ $use{'output-block'}++;
+ }
$start_holder = $key;
+ $indent_2 = $indent + $size{'indents'};
+ $b_ni2 = ($start_holder eq 'Info') ? 1 : 0;
if ($indent < 10){
$line = "$start\n";
print_line($line);
@@ -6713,7 +6889,6 @@ sub print_data {
$indent = 0;
}
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 = (
@@ -6734,13 +6909,16 @@ sub print_data {
'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 (sor ({ (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){
+ if (!$b_single){
+ $indent_use = $length = ($b_row1) ? $indent : $indent_2;
+ }
+ ($counter,$b_row1,$split_count) = (0,1,0);
+ foreach my $key2 (sort {substr($a,0,3) <=> substr($b,0,3)} keys %$val1){
+ if (!$b_single){
+ $indent_use = ($b_row1 || $b_ni2) ? $indent: $indent_2;
+ }
+ # print "m-1: r1: $b_row1 iu: $indent_use\n";
($hash_id,$b_container,$indentx,$key) = (split('#', $key2));
if ($start_holder eq 'Graphics' && $key eq 'Screen'){
$ids{'Monitor'} = 1;
@@ -6765,39 +6943,52 @@ sub print_data {
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);
+ # see: Use of implicit split to @_ is deprecated. Only get this
+ # warning in Perl 5.08 oddly enough. ie, no: scalar (split(...));
+ my @temp = split(/\s+/, $val2);
$split_count = scalar @temp;
- if (!$b_single && (length("$key$sep{'s2'} $val2") + $length) < $size{'max'}){
- # print "one\n";
+ if (!$b_single &&
+ (length("$key$sep{'s2'} $val2") + $length) < $size{'max-cols'}){
+ # print "h-1: r1: $b_row1 iu: $indent_use\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);
+ # handle case where the 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_use) > $size{'max-cols'} &&
+ !defined $ids{$key} && $split_count > 2){
+ # print "m-2 r1: $b_row1 iu: $indent_use\n";
+ my @values = split(/\s+/, $val2);
$val3 = shift @values;
- # $length += length("$key$sep{'s2'} $val3 ") + $indent;
$start2 = "$colors{'c1'}$key$sep{'s2'}$colors{'c2'} $val3 ";
$holder2 = '';
+ # case where not first item in line, but when key+first word added,
+ # is wider than max width.
+ if ($holder &&
+ ($length + length("$key$sep{'s2'} $val3")) > $size{'max-cols'}){
+ # print "p-1a r1: $b_row1 iu: $indent_use\n";
+ $holder =~ s/\s+$//;
+ $line = sprintf("%-${indent_use}s%s$colors{'cn'}\n","$start","$holder");
+ print_line($line);
+ $b_row1 = 0;
+ $start = '';
+ $holder = '';
+ $length = $indent_use;
+ }
$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";
+ $indent_use = ($b_row1) ? $indent : $indent_2;
+ if ((length("$_ ") + $length) < $size{'max-cols'}){
+ # print "h-2: r1: $b_row1 iu: $indent_use\n";
# print "a\n";
if ($start2){
$holder2 .= "$start2$_ ";
$start2 = '';
- #$length += $length2;
- #$length2 = 0;
}
else {
$holder2 .= "$_ ";
@@ -6805,7 +6996,7 @@ sub print_data {
$length += length("$_ ");
}
else {
- # print "three.2\n";
+ # print "p-1b: r1: $b_row1 iu: $indent_use\n";
if ($start2){
$holder2 = "$start2$holder2";
}
@@ -6814,57 +7005,63 @@ sub print_data {
}
# print "xx:$holder";
$holder2 =~ s/\s+$//;
- $line = sprintf("%-${indent}s%s$colors{'cn'}\n","$start","$holder$holder2");
+ $line = sprintf("%-${indent_use}s%s$colors{'cn'}\n","$start","$holder$holder2");
print_line($line);
+ $b_row1 = 0;
$holder = '';
$holder2 = "$_ ";
# print "h2: $holder2\n";
- $length = length($holder2) + $indent;
+ $length = length($holder2) + $indent_use;
$start2 = '';
$start = '';
- #$length2 = 0;
}
}
if ($holder2 !~ /^\s*$/){
- # print "four\n";
+ # print "p-2: r1: $b_row1 iu: $indent_use\n";
$holder2 =~ s/\s+$//;
$holder2 = "$colors{'c2'}$holder2";
- $line = sprintf("%-${indent}s%s$colors{'cn'}\n","$start","$holder$holder2");
+ $line = sprintf("%-${indent_use}s%s$colors{'cn'}\n","$start","$holder$holder2");
print_line($line);
+ $b_row1 = 0;
$holder = '';
$holder2 = '';
- $length = $indent;
+ $length = $indent_use;
$start2 = '';
$start = '';
- #$length2 = 0;
}
}
# 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";
+ # print "p-3: r1: $b_row1 iu: $indent_use\n";
$holder =~ s/\s+$//;
$line = sprintf("%-${indent_use}s%s$colors{'cn'}\n",$start,"$holder");
$length = length("$key$sep{'s2'} $val2") + $indent_use;
print_line($line);
+ $b_row1 = 0;
$start = '';
}
else {
- # print "six\n";
+ # print "h-3a: r1: $b_row1 iu: $indent_use\n";
$length = $indent_use;
- #$holder = '';
+ }
+ if ($b_single){
+ $indent_use = ($indent * $indentx);
+ }
+ else {
+ $indent_use = ($b_row1 || $b_ni2) ? $indent: $indent_2;
}
$holder = "$colors{'c1'}$key$sep{'s2'}$colors{'c2'} $val2";
+ # print "h-3b: r1: $b_row1 iu: $indent_use\n";
}
$counter++;
- $indent_use = ($indent * $indentx) if $b_single;
}
if ($holder !~ /^\s*$/){
- # print "seven\n";
+ # print "p-4: r1: $b_row1 iu: $indent_use\n";
$holder =~ s/\s+$//;
$line = sprintf("%-${indent_use}s%s$colors{'cn'}\n",$start,"$start2$holder");
print_line($line);
+ $b_row1 = 0;
$holder = '';
$length = 0;
$start = '';
@@ -6872,11 +7069,19 @@ sub print_data {
}
# only for repos currently
elsif (ref($val1) eq 'ARRAY'){
- # print "eight\n";
- $array=0;
+ # print "p-5: r1: $b_row1 iu: $indent_use\n";
+ my $array=0;
+ $indent_use = $indent_2;
foreach my $item (@$val1){
$array++;
- $indent_use = ($b_single) ? $indent + 2: $indent;
+ if ($size{'max-lines'}){
+ my $l1 = length("$array$sep{'s2'} $item") + $indent_use;
+ if ($l1 > $size{'term-cols'}){
+ my $l2 = length("$array$sep{'s2'} ") + $indent_use + 6;
+ # print "$l1 $size{'term-cols'} $l2 $array $indent_use\n";
+ $item = substr($item,0,$size{'term-cols'} - $l2) . '[...]';
+ }
+ }
$line = "$colors{'c1'}$array$sep{'s2'} $colors{'c2'}$item$colors{'cn'}";
$line = sprintf("%-${indent_use}s%s\n","","$line");
print_line($line);
@@ -6907,7 +7112,19 @@ sub print_line {
system('qdbus', 'org.kde.konversation', '/irc', 'say', $client{'dserver'}, $client{'dtarget'}, $line);
}
else {
+ # print "tl: $size{'term-lines'} ml: $size{'max-lines'} l:$size{'lines'}\n";
+ if ($size{'max-lines'}){
+ # -y1 + -Y can result in start of output scrolling off screen if terminal
+ # wrapped lines happen.
+ if ((($size{'max-lines'} >= $size{'term-lines'}) &&
+ $size{'max-lines'} == $size{'lines'}) ||
+ ($size{'max-lines'} < $size{'term-lines'} &&
+ $size{'max-lines'} + 1 == $size{'lines'})){
+ output_control();
+ }
+ }
print $line;
+ $size{'lines'}++ if $size{'max-lines'};
}
}
@@ -6927,17 +7144,16 @@ sub get {
eval $start if $b_log;
my (@rows);
my $num = 0;
- if (($b_arm || $b_mips) && !$use{'soc-audio'} && !$use{'pci-tool'}){
- my $type = ($b_arm) ? 'arm' : 'mips';
+ if (%risc && !$use{'soc-audio'} && !$use{'pci-tool'}){
my $key = 'Message';
push(@rows,{
- main::key($num++,0,1,$key) => main::row_defaults($type . '-pci',''),
+ main::key($num++,0,1,$key) => main::message('risc-pci',$risc{'id'}),
},);
}
else {
push(@rows,device_output());
}
- if (((($b_arm || $b_mips) && !$use{'soc-audio'} && !$use{'pci-tool'}) || !@rows) &&
+ if (((%risc && !$use{'soc-audio'} && !$use{'pci-tool'}) || !@rows) &&
(my $file = $system_files{'asound-cards'})){
push(@rows,asound_output($file));
}
@@ -6949,7 +7165,7 @@ sub get {
$type = 'pci-card-data-root';
}
push(@rows,{
- main::key($num++,0,1,$key) => main::row_defaults($type,''),
+ main::key($num++,0,1,$key) => main::message($type,''),
},);
}
push(@rows,sound_server_output());
@@ -6968,10 +7184,10 @@ sub device_output {
my $driver = $row->[9];
$driver ||= 'N/A';
my $device = $row->[4];
- $device = ($device) ? main::pci_cleaner($device,'output') : 'N/A';
+ $device = ($device) ? main::clean_pci($device,'output') : 'N/A';
# have seen absurdly verbose card descriptions, with non related data etc
- if (length($device) > 85 || $size{'max'} < 110){
- $device = main::pci_long_filter($device);
+ if (length($device) > 85 || $size{'max-cols'} < 110){
+ $device = main::filter_pci_long($device);
}
push(@rows, {
main::key($num++,1,1,'Device') => $device,
@@ -7035,7 +7251,7 @@ sub asound_output {
if ($extra > 0){
my $version = main::get_module_version($driver);
$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','');
+ $rows[$j]->{main::key($num++,0,2,'message')} = main::message('pci-advanced-data','');
}
}
}
@@ -7054,7 +7270,7 @@ sub usb_output {
$num = 1;
# make sure to reset, or second device trips last flag
($path_id,$product) = ('','');
- $product = main::cleaner($row->[13]) if $row->[13];
+ $product = main::clean($row->[13]) if $row->[13];
$path_id = $row->[2] if $row->[2];
$product ||= 'N/A';
$row->[15] ||= 'N/A';
@@ -7074,7 +7290,7 @@ sub usb_output {
$rows[$j]->{main::key($num++,0,2,'class-ID')} = "$row->[4]$row->[5]";
}
if ($extra > 2 && $row->[16]){
- $rows[$j]->{main::key($num++,0,2,'serial')} = main::apply_filter($row->[16]);
+ $rows[$j]->{main::key($num++,0,2,'serial')} = main::filter($row->[16]);
}
$j = scalar @rows;
}
@@ -7188,7 +7404,7 @@ sub get {
if (!%battery){
if ($show{'battery-forced'}){
$key1 = 'Message';
- $val1 = main::row_defaults('battery-data','');
+ $val1 = main::message('battery-data','');
@rows = ({main::key($num++,0,1,$key1) => $val1,});
}
}
@@ -7202,7 +7418,7 @@ sub get {
if (!%battery){
if ($show{'battery-forced'}){
$key1 = 'Message';
- $val1 = main::row_defaults('battery-data-bsd','');
+ $val1 = main::message('battery-data-bsd','');
@rows = ({main::key($num++,0,1,$key1) => $val1,});
}
}
@@ -7215,7 +7431,7 @@ sub get {
if (!%battery){
if ($show{'battery-forced'}){
$key1 = 'Message';
- $val1 = main::row_defaults('battery-data','');
+ $val1 = main::message('battery-data','');
@rows = ({main::key($num++,0,1,$key1) => $val1,});
}
}
@@ -7226,7 +7442,7 @@ sub get {
else {
if ($show{'battery-forced'}){
$key1 = 'Message';
- $val1 = (!$bsd_type) ? main::row_defaults('battery-data-sys'): main::row_defaults('battery-data-bsd');
+ $val1 = (!$bsd_type) ? main::message('battery-data-sys'): main::message('battery-data-bsd');
@rows = ({main::key($num++,0,1,$key1) => $val1,});
}
}
@@ -7271,7 +7487,8 @@ sub battery_output {
# we need to handle cases where charge or energy full is 0
if (defined $battery->{$key}{'energy_now'} && $battery->{$key}{'energy_now'} ne ''){
$charge = "$battery->{$key}{'energy_now'} Wh";
- if ($battery->{$key}{'energy_full'} && main::is_numeric($battery->{$key}{'energy_full'})){
+ if ($battery->{$key}{'energy_full'} &&
+ main::is_numeric($battery->{$key}{'energy_full'})){
my $percent = sprintf("%.1f", $battery->{$key}{'energy_now'}/$battery->{$key}{'energy_full'}*100);
$charge .= ' (' . $percent . '%)';
}
@@ -7285,7 +7502,8 @@ sub battery_output {
}
if ($battery->{$key}{'energy_full'} || $battery->{$key}{'energy_full_design'}){
$battery->{$key}{'energy_full_design'} ||= 'N/A';
- $battery->{$key}{'energy_full'}= (defined $battery->{$key}{'energy_full'} && $battery->{$key}{'energy_full'} ne '') ? $battery->{$key}{'energy_full'} : 'N/A';
+ $battery->{$key}{'energy_full'} = (defined $battery->{$key}{'energy_full'} &&
+ $battery->{$key}{'energy_full'} ne '') ? $battery->{$key}{'energy_full'} : 'N/A';
$condition = "$battery->{$key}{'energy_full'}/$battery->{$key}{'energy_full_design'} Wh";
if ($battery->{$key}{'of_orig'}){
$condition .= " ($battery->{$key}{'of_orig'}%)";
@@ -7298,7 +7516,8 @@ sub battery_output {
main::key($num++,0,2,'charge') => $charge,
main::key($num++,0,2,'condition') => $condition,
},);
- if ($extra > 0 || ($battery->{$key}{'voltage_now'} && $battery->{$key}{'voltage_min_design'} &&
+ if ($extra > 0 || ($battery->{$key}{'voltage_now'} &&
+ $battery->{$key}{'voltage_min_design'} &&
($battery->{$key}{'voltage_now'} - $battery->{$key}{'voltage_min_design'}) < 0.5)){
$battery->{$key}{'voltage_now'} ||= 'N/A';
$rows[$j]->{main::key($num++,1,2,'volts')} = $battery->{$key}{'voltage_now'};
@@ -7328,7 +7547,7 @@ sub battery_output {
$rows[$j]->{main::key($num++,0,2,'type')} = $chemistry;
}
if ($extra > 1){
- $serial = main::apply_filter($battery->{$key}{'serial_number'});
+ $serial = main::filter($battery->{$key}{'serial_number'});
$rows[$j]->{main::key($num++,0,2,'serial')} = $serial;
}
$status = ($battery->{$key}{'status'}) ? $battery->{$key}{'status'}: 'N/A';
@@ -7358,14 +7577,15 @@ sub battery_output {
if ($upower_data{'percent'}){
$charge = $upower_data{'percent'};
}
- elsif ($battery->{$key}{'capacity_level'} && lc($battery->{$key}{'capacity_level'}) ne 'unknown'){
+ elsif ($battery->{$key}{'capacity_level'} &&
+ lc($battery->{$key}{'capacity_level'}) ne 'unknown'){
$charge = $battery->{$key}{'capacity_level'};
}
else {
$charge = 'N/A';
}
$model = $battery->{$key}{'model_name'} if $battery->{$key}{'model_name'};
- $status = ($battery->{$key}{'status'} && lc($battery->{$key}{'status'}) ne 'unknown') ? $battery->{$key}{'status'}: 'N/A' ;
+ $status = ($battery->{$key}{'status'}) ? $battery->{$key}{'staus'}: 'N/A' ;
$vendor = $battery->{$key}{'manufacturer'} if $battery->{$key}{'manufacturer'};
if ($vendor || $model){
if ($vendor && $model){
@@ -7383,7 +7603,7 @@ sub battery_output {
main::key($num++,0,2,'model') => $model,
},);
if ($extra > 1){
- $serial = main::apply_filter($battery->{$key}{'serial_number'});
+ $serial = main::filter($battery->{$key}{'serial_number'});
$rows[$j]->{main::key($num++,0,2,'serial')} = $serial;
}
$rows[$j]->{main::key($num++,0,2,'charge')} = $charge;
@@ -7409,7 +7629,8 @@ sub battery_data_sys {
my @items = qw(alarm capacity capacity_level charge_full charge_full_design
charge_now constant_charge_current constant_charge_current_max cycle_count
energy_full energy_full_design energy_now location manufacturer model_name
- power_now present scope serial_number status technology type voltage_min_design voltage_now);
+ power_now present scope serial_number status technology type voltage_min_design
+ voltage_now);
foreach $item (@batteries){
$b_ma = 0;
$id = $item;
@@ -7457,14 +7678,19 @@ sub battery_data_sys {
$b_ma = 1;
}
elsif ($file eq 'manufacturer'){
- $value = main::dmi_cleaner($value);
+ $value = main::clean_dmi($value);
}
elsif ($file eq 'model_name'){
- $value = main::dmi_cleaner($value);
+ $value = main::clean_dmi($value);
+ }
+ # Valid values: Unknown,Charging,Discharging,Not charging,Full
+ # don't use clean_unset because Not charging is a valid value.
+ elsif ($file eq 'status'){
+ $value =~ s/unknown//i;
}
}
elsif ($b_root && -e $path && ! -r $path){
- $value = main::row_defaults('root-required');
+ $value = main::message('root-required');
}
$battery{$id}->{$file} = $value;
# print "$battery{$id}->{$file}\n";
@@ -7557,11 +7783,19 @@ sub battery_data_sysctl {
elsif (/raw[^:]+:[0-9\.]+\s+\((battery) ([^\)]+)\)/){
$battery{$id}->{'status'} = $2;
}
- elsif (/^acpi[\S]+:at [^:]+:\s*$id\s+model\s+(.*?)\s*serial\s+([\S]*?)\s*type\s+(.*?)\s*oem\s+(.*)/i){
- $battery{$id}->{'model_name'} = main::dmi_cleaner($1);
- $battery{$id}->{'serial_number'} = $2;
- $battery{$id}->{'technology'} = $3;
- $battery{$id}->{'manufacturer'} = main::dmi_cleaner($4);
+ elsif (/^acpi[\S]+:at [^:]+:\s*$id\s+/i){
+ if (/\s+model\s+(.*?)\s*/){
+ $battery{$id}->{'model_name'} = main::clean_dmi($1);
+ }
+ if (/\s*serial\s+([\S]*?)\s*/){
+ $battery{$id}->{'serial_number'} = main::clean_unset($1,'^(0x)0+$');
+ }
+ if (/\s*type\s+(.*?)\s*/){
+ $battery{$id}->{'technology'} = $1;
+ }
+ if (/\s*oem\s+(.*)/){
+ $battery{$id}->{'manufacturer'} = main::clean_dmi($1);
+ }
}
}
# then do the condition/charge percent math
@@ -7617,11 +7851,16 @@ sub battery_data_dmi {
foreach my $item (@$row[3 .. $#$row]){
my @value = split(/:\s+/, $item);
next if !$value[0];
- if ($value[0] eq 'Location'){$battery{$id}->{'location'} = $value[1] }
- elsif ($value[0] eq 'Manufacturer'){$battery{$id}->{'manufacturer'} = main::dmi_cleaner($value[1]) }
- elsif ($value[0] =~ /Chemistry/){$battery{$id}->{'technology'} = $value[1] }
- elsif ($value[0] =~ /Serial Number/){$battery{$id}->{'serial_number'} = $value[1] }
- elsif ($value[0] =~ /^Name/){$battery{$id}->{'model_name'} = main::dmi_cleaner($value[1]) }
+ if ($value[0] eq 'Location'){
+ $battery{$id}->{'location'} = $value[1]}
+ elsif ($value[0] eq 'Manufacturer'){
+ $battery{$id}->{'manufacturer'} = main::clean_dmi($value[1])}
+ elsif ($value[0] =~ /Chemistry/){
+ $battery{$id}->{'technology'} = $value[1]}
+ elsif ($value[0] =~ /Serial Number/){
+ $battery{$id}->{'serial_number'} = $value[1]}
+ elsif ($value[0] =~ /^Name/){
+ $battery{$id}->{'model_name'} = main::clean_dmi($value[1])}
elsif ($value[0] eq 'Design Capacity'){
$value[1] =~ s/\s*mwh$//i;
$battery{$id}->{'energy_full_design'} = sprintf("%.1f", $value[1]/1000);
@@ -7693,13 +7932,12 @@ sub get {
my $num = 0;
$b_bluetooth = 1 if @ps_cmd && (grep {m|/bluetoothd\b|} @ps_cmd);
# note: rapi 4 has pci bus
- if (($b_arm || $b_mips) && !$use{'soc-bluetooth'} && !$use{'pci-tool'}){
+ if (%risc && !$use{'soc-bluetooth'} && !$use{'pci-tool'}){
# do nothing, but keep the test conditions to force
- # the non arm case to always run
- # my $type = ($b_arm) ? 'arm' : 'mips';
+ # the non risc case to always run
# my $key = 'Message';
# push(@rows,{
- # main::key($num++,0,1,$key) => main::row_defaults($type . '-pci',''),
+ # main::key($num++,0,1,$key) => main::message('risc-pci',$risc{'id'}),
# },);
}
else {
@@ -7710,7 +7948,7 @@ sub get {
if ($show{'bluetooth-forced'}){
my $key = 'Message';
push(@rows,{
- main::key($num++,0,1,$key) => main::row_defaults('bluetooth-data'),
+ main::key($num++,0,1,$key) => main::message('bluetooth-data'),
},);
}
}
@@ -7733,10 +7971,10 @@ sub device_output {
$j = scalar @rows;
my $driver = ($row->[9]) ? $row->[9] : 'N/A';
my $device = $row->[4];
- $device = ($device) ? main::pci_cleaner($device,'output') : 'N/A';
+ $device = ($device) ? main::clean_pci($device,'output') : 'N/A';
# have seen absurdly verbose card descriptions, with non related data etc
- if (length($device) > 85 || $size{'max'} < 110){
- $device = main::pci_long_filter($device);
+ if (length($device) > 85 || $size{'max-cols'} < 110){
+ $device = main::filter_pci_long($device);
}
push(@rows, {
main::key($num++,1,1,'Device') => $device,
@@ -7790,7 +8028,7 @@ sub usb_output {
$j = scalar @rows;
# makre sure to reset, or second device trips last flag
($path_id,$product) = ('','');
- $product = main::cleaner($row->[13]) if $row->[13];
+ $product = main::clean($row->[13]) if $row->[13];
$product ||= 'N/A';
$row->[15] ||= 'N/A';
$path_id = $row->[2] if $row->[2];
@@ -7814,7 +8052,7 @@ sub usb_output {
$rows[$j]->{main::key($num++,0,2,'class-ID')} = "$row->[4]$row->[5]";
}
if ($extra > 2 && $row->[16]){
- $rows[$j]->{main::key($num++,0,2,'serial')} = main::apply_filter($row->[16]);
+ $rows[$j]->{main::key($num++,0,2,'serial')} = main::filter($row->[16]);
}
push(@rows,advanced_output('usb',$path_id)) if $path_id;
}
@@ -7898,10 +8136,10 @@ sub advanced_output {
}
}
if (!$hci{$item}->{'address'} && $tool eq 'rfkill'){
- $address = main::row_defaults('recommends');
+ $address = main::message('recommends');
}
else {
- $address = main::apply_filter($hci{$item}->{'address'});
+ $address = main::filter($hci{$item}->{'address'});
}
$rows[$j]->{main::key($num++,0,$l,'address')} = $address;
# lmp/hci version only hciconfig sadly
@@ -7964,10 +8202,10 @@ sub advanced_output {
my $value = '';
if ($alerts{'hciconfig'}->{'action'} eq 'platform' ||
$alerts{'bt-adapter'}->{'action'} eq 'platform'){
- $value = main::row_defaults('tool-missing-os','bluetooth');
+ $value = main::message('tool-missing-os','bluetooth');
}
else {
- $value = main::row_defaults('tools-missing','hciconfig/bt-adapter');
+ $value = main::message('tools-missing','hciconfig/bt-adapter');
}
push(@rows,{
main::key($num++,0,1,$key) => $value,
@@ -8019,7 +8257,7 @@ sub bt_tool_data {
}
}
if (!@data && !$b_bluetooth){
- $hci{'alert'} = main::row_defaults('bluetooth-down');
+ $hci{'alert'} = main::message('bluetooth-down');
}
print Data::Dumper::Dumper \%hci if $dbg[27];
main::log_data('dump','%hci', \%hci) if $b_log;
@@ -8071,7 +8309,7 @@ sub hciconfig_data {
$hci{$id}->{'link-mode'} = lc($1);
}
elsif (/^Service Classes?:\s+(.+)/){
- $hci{$id}->{'service-classes'} = main::general_cleaner(lc($1));
+ $hci{$id}->{'service-classes'} = main::clean_unset(lc($1));
}
}
print Data::Dumper::Dumper \%hci if $dbg[27];
@@ -8138,14 +8376,14 @@ sub bluetooth_version {
## CpuItem
{
package CpuItem;
-
+my ($type);
sub get {
eval $start if $b_log;
- my ($type) = @_;
+ ($type) = @_;
my (@rows);
if ($type eq 'short' || $type eq 'basic'){
# note, for short form, just return the raw data, not the processed output
- @rows = short_data($type);
+ @rows = short_data();
if ($type eq 'basic'){
@rows = short_output(\@rows);
}
@@ -8156,28 +8394,24 @@ sub get {
eval $end if $b_log;
return @rows;
}
+
+## OUTPUT HANDLERS ##
sub full_output {
eval $start if $b_log;
my $num = 0;
- my ($b_flags,$b_speeds,$core_speeds_value,$flag_key,@flags,%cpu,@rows);
+ my ($b_speeds,$core_speeds_value,$cpu);
+ my (@rows);
my $sleep = $cpu_sleep * 1000000;
if (my $file = $system_files{'proc-cpuinfo'}){
- # bsd sleep is set before sysctl runs, same idea
- if ($b_hires){
- eval 'Time::HiRes::usleep($sleep)';
- }
- else {
- select(undef, undef, undef, $cpu_sleep);
- }
- %cpu = cpuinfo_data($file,'full');
+ $cpu = cpuinfo_data($file);
}
elsif ($bsd_type){
my ($key1,$val1) = ('','');
if ($alerts{'sysctl'}){
if ($alerts{'sysctl'}->{'action'} eq 'use'){
# $key1 = 'Status';
-# $val1 = main::row_defaults('dev');
- %cpu = sysctl_data('full');
+# $val1 = main::message('dev');
+ $cpu = sysctl_data();
}
else {
$key1 = ucfirst($alerts{'sysctl'}->{'action'});
@@ -8187,18 +8421,17 @@ sub full_output {
}
}
}
- my %properties = cpu_properties(\%cpu);
- my $type = ($properties{'cpu-type'}) ? $properties{'cpu-type'}: '';
- my @processors = @{$cpu{'processors'}};
- my @speeds = cpu_speeds(\@processors);
+ my $properties = cpu_properties($cpu);
+ my $type = ($properties->{'cpu-type'}) ? $properties->{'cpu-type'}: '';
my $j = scalar @rows;
- $cpu{'model_name'} ||= 'N/A';
+ $j = scalar @rows;
+ $cpu->{'model_name'} ||= 'N/A';
push(@rows, {
- main::key($num++,1,1,'Info') => $properties{'cpu-layout'},
- main::key($num++,0,2,'model') => $cpu{'model_name'},
+ main::key($num++,1,1,'Info') => $properties->{'topology-string'},
+ main::key($num++,0,2,'model') => $cpu->{'model_name'},
},);
- if ($cpu{'system-cpus'}){
- my %system_cpus = %{$cpu{'system-cpus'}};
+ if ($cpu->{'system-cpus'}){
+ my %system_cpus = %{$cpu->{'system-cpus'}};
my $i = 1;
my $counter = (%system_cpus && scalar keys %system_cpus > 1) ? '-' : '';
foreach my $key (keys %system_cpus){
@@ -8206,160 +8439,229 @@ sub full_output {
$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')} = main::row_defaults('note-check');
+ 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')} = main::message('note-check');
}
else {
- $rows[$j]->{main::key($num++,0,2,'socket')} = $properties{'socket'};
+ $rows[$j]->{main::key($num++,0,2,'socket')} = $properties->{'socket'};
}
}
- $properties{'bits-sys'} ||= 'N/A';
- $rows[$j]->{main::key($num++,0,2,'bits')} = $properties{'bits-sys'};
+ $properties->{'bits-sys'} ||= 'N/A';
+ $rows[$j]->{main::key($num++,0,2,'bits')} = $properties->{'bits-sys'};
if ($type){
$rows[$j]->{main::key($num++,0,2,'type')} = $type;
+ if (!$properties->{'topology-full'} && $cpu->{'smt'} && ($extra > 2 ||
+ ($extra > 0 && $cpu->{'smt'} eq 'disabled'))){
+ $rows[$j]->{main::key($num++,0,2,'smt')} = $cpu->{'smt'};
+ }
}
if ($extra > 0){
- $cpu{'arch'} ||= 'N/A';
- $rows[$j]->{main::key($num++,1,2,'arch')} = $cpu{'arch'};
- if ($cpu{'arch-note'}){
- $rows[$j]->{main::key($num++,0,3,'note')} = $cpu{'arch-note'};
+ $cpu->{'arch'} ||= 'N/A';
+ $rows[$j]->{main::key($num++,1,2,'arch')} = $cpu->{'arch'};
+ if ($cpu->{'arch-note'}){
+ $rows[$j]->{main::key($num++,0,3,'note')} = $cpu->{'arch-note'};
}
# ntoe: had if arch, but stepping can be defined where arch failed, stepping can be 0
- if (!$b_admin && defined $cpu{'stepping'}){
- $rows[$j]->{main::key($num++,0,2,'rev')} = $cpu{'stepping'};
+ if (!$b_admin && (defined $cpu->{'stepping'} || defined $cpu->{'revision'})){
+ my $rev = main::get_defined($cpu->{'stepping'},$cpu->{'revision'});
+ $rows[$j]->{main::key($num++,0,2,'rev')} = $rev;
}
}
if ($b_admin){
- $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{'stepping'});
- if (!$b_arm && !$b_mips && !$b_ppc && $cpu{'type'} ne 'elbrus'){
- $cpu{'microcode'} ||= 'N/A';
- $rows[$j]->{main::key($num++,0,2,'microcode')} = $cpu{'microcode'};
+ $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'});
+ if (defined $cpu->{'stepping'}){
+ $rows[$j]->{main::key($num++,0,2,'stepping')} = hex_and_decimal($cpu->{'stepping'});
}
- }
- if (($extra > 1 && ($properties{'l1-cache'} || $properties{'l3-cache'})) ||
- ((!$b_arm && !$b_mips && !$b_ppc) || $properties{'l2-cache'})){
- $rows[$j]->{main::key($num++,1,2,'cache')} = '';
- if ($extra > 1 && $properties{'l1-cache'}){
- $rows[$j]->{main::key($num++,0,3,'L1')} = main::get_size($properties{'l1-cache'},'string');
- }
- # the arm + l2 will never be true since arm cpus don't have l2 cache
- $properties{'l2-cache'} = ($properties{'l2-cache'}) ? main::get_size($properties{'l2-cache'},'string') : 'N/A';
- $rows[$j]->{main::key($num++,0,3,'L2')} = $properties{'l2-cache'};
- if ($extra > 1 && $properties{'l3-cache'}){
- $rows[$j]->{main::key($num++,0,3,'L3')} = main::get_size($properties{'l3-cache'},'string');
+ elsif (defined $cpu->{'revision'}){
+ $rows[$j]->{main::key($num++,0,2,'rev')} = $cpu->{'revision'};
}
- if ($properties{'cache-check'}){
- $rows[$j]->{main::key($num++,0,3,'note')} = $properties{'cache-check'};
+
+ if (!%risc && $cpu->{'type'} ne 'elbrus'){
+ $cpu->{'microcode'} = ($cpu->{'microcode'}) ? '0x' . $cpu->{'microcode'} : 'N/A';
+ $rows[$j]->{main::key($num++,0,2,'microcode')} = $cpu->{'microcode'};
}
}
- if ($extra > 0 && !$show{'cpu-flag'}){
+ # note, risc cpus are using l1, L2, L3 more often, but if risc and no L2, skip
+ if ($properties->{'topology-string'} && (($extra > 1 &&
+ ($properties->{'l1-cache'} || $properties->{'l3-cache'})) ||
+ (!%risc || $properties->{'l2-cache'}) || $properties->{'cache'})){
+ full_output_caches($j,$properties,\$num,\@rows);
+ }
+ # all tests already done to load this, admin, etc
+ if ($properties->{'topology-full'}){
$j = scalar @rows;
- @flags = split(/\s+/, $cpu{'flags'}) if $cpu{'flags'};
- $flag_key = ($b_arm || $bsd_type) ? 'features': 'flags';
- my $flag = 'N/A';
- if (@flags){
- # failure to read dmesg.boot: dmesg.boot permissions; then short -Cx list flags
- @flags = grep {/^(dmesg.boot|permissions|avx[2-9]?|lm|nx|pae|pni|(sss|ss)e([2-9])?([a-z])?(_[0-9])?|svm|vmx)$/} @flags;
- @flags = map {s/pni/sse3/; $_} @flags;
- @flags = sort @flags;
- $flag = join(' ', @flags) if @flags;
- }
- if ($b_arm && $flag eq 'N/A'){
- $flag = main::row_defaults('arm-cpu-f');
- }
push(@rows, {
- main::key($num++,0,2,$flag_key) => $flag,
- });
- $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++,0,2,'bogomips')} = $bogomips;
+ main::key($num++,1,1,'Topology') => '',
+ },);
+ my ($id,$var) = (2,'');
+ if (scalar @{$properties->{'topology-full'}} > 1){
+ $var = 'variant';
+ $id = 3;
+ }
+ foreach my $topo (@{$properties->{'topology-full'}}){
+ if ($var){
+ $rows[$j]->{main::key($num++,1,2,'variant')} = '';
+ }
+ my $x = ($size{'max-cols'} == 1 || $output_type ne 'screen') ? '' : 'x';
+ $rows[$j]->{main::key($num++,0,$id,'cpus')} = $topo->{'cpus'} . $x;
+ $rows[$j]->{main::key($num++,1,$id+1,'cores')} = $topo->{'cores'};
+ if ($topo->{'cores-mt'} && $topo->{'cores-st'}){
+ $rows[$j]->{main::key($num++,1,$id+2,'mt')} = $topo->{'cores-mt'};
+ $rows[$j]->{main::key($num++,0,$id+3,'tpc')} = $topo->{'tpc'};
+ $rows[$j]->{main::key($num++,0,$id+2,'st')} = $topo->{'cores-st'};
+ }
+ if ($topo->{'cores-mt'}){
+ $rows[$j]->{main::key($num++,0,$id+2,'tpc')} = $topo->{'tpc'};
+ }
+ if ($topo->{'max'} || $topo->{'min'}){
+ my ($freq,$key) = ('','');
+ if ($topo->{'max'} && $topo->{'min'}){
+ $key = 'min/max';
+ $freq = $topo->{'min'} . '/' . $topo->{'max'};
+ }
+ elsif ($topo->{'max'}){
+ $key = 'max';
+ $freq = $topo->{'max'};
+ }
+ else {
+ $key = 'min';
+ $freq = $topo->{'min'};
+ }
+ $rows[$j]->{main::key($num++,0,$id+1,$key)} = $freq;
+ }
+ if ($topo->{'threads'}){
+ $rows[$j]->{main::key($num++,0,$id+1,'threads')} = $topo->{'threads'};
+ }
+ if ($topo->{'dies'}){
+ $rows[$j]->{main::key($num++,0,$id+1,'dies')} = $topo->{'dies'};
+ }
+ }
+ $cpu->{'smt'} ||= 'N/A';
+ $rows[$j]->{main::key($num++,0,2,'smt')} = $cpu->{'smt'};
+ full_output_caches($j,$properties,\$num,\@rows);
}
$j = scalar @rows;
- my $core_key = (scalar @speeds > 1) ? 'Core speeds (MHz)' : 'Core speed (MHz)';
- my $speed_key = ($properties{'speed-key'}) ? $properties{'speed-key'}: 'Speed';
- my $min_max = ($properties{'min-max'}) ? $properties{'min-max'}: 'N/A';
- my $min_max_key = ($properties{'min-max-key'}) ? $properties{'min-max-key'}: 'min/max';
- my $speed = (defined $properties{'speed'}) ? $properties{'speed'}: 'N/A';
- # aren't able to get per core speeds in bsds yet
- if (@speeds){
- if (grep {$_ ne '0'} @speeds){
+ my $speeds = $cpu->{'processors'};
+ my $core_key = (defined $speeds && scalar @{$speeds} > 1) ? 'cores' : 'core';
+ my $speed_key = ($properties->{'speed-key'}) ? $properties->{'speed-key'}: 'Speed';
+ my $min_max = ($properties->{'min-max'}) ? $properties->{'min-max'}: 'N/A';
+ my $min_max_key = ($properties->{'min-max-key'}) ? $properties->{'min-max-key'}: 'min/max';
+ my $speed = '';
+ if (!$properties->{'avg-speed-key'}){
+ $speed = (defined $properties->{'speed'}) ? $properties->{'speed'}: 'N/A';
+ }
+ # Aren't able to get per core speeds in BSDs. Why don't they support this?
+ if (defined $speeds && @$speeds){
+ # only if defined and not 0
+ if (grep {$_} @{$speeds}){
$core_speeds_value = '';
$b_speeds = 1;
}
else {
- $core_speeds_value = main::row_defaults('cpu-speeds');
+ my $id = ($bsd_type) ? 'cpu-speeds-bsd' : 'cpu-speeds';
+ $core_speeds_value = main::message($id);
}
}
else {
- $core_speeds_value = 'N/A';
+ $core_speeds_value = main::message('cpu-speeds');
}
$j = scalar @rows;
push(@rows, {
main::key($num++,1,1,$speed_key) => $speed,
- main::key($num++,0,2,$min_max_key) => $min_max,
});
- 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 ($properties->{'avg-speed-key'}){
+ $rows[$j]->{main::key($num++,0,2,$properties->{'avg-speed-key'})} = $properties->{'speed'};
+ if ($extra > 0 && $properties->{'high-speed-key'}){
+ $rows[$j]->{main::key($num++,0,2,$properties->{'high-speed-key'})} = $cpu->{'high-freq'};
+ }
}
- if ($extra > 0){
- my $boost = get_boost_status();
- $rows[$j]->{main::key($num++,0,2,'boost')} = $boost if $boost;
+ $rows[$j]->{main::key($num++,0,2,$min_max_key)} = $min_max;
+ if ($extra > 0 && defined $cpu->{'boost'}){
+ $rows[$j]->{main::key($num++,0,2,'boost')} = $cpu->{'boost'};
+ }
+ 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 ($b_admin && ($cpu->{'governor'} || $cpu->{'scaling-driver'})){
+ $rows[$j]->{main::key($num++,1,2,'scaling')} = '';
+ $cpu->{'driver'} ||= 'N/A';
+ $rows[$j]->{main::key($num++,0,3,'driver')} = $cpu->{'scaling-driver'};
+ $cpu->{'governor'} ||= 'N/A';
+ $rows[$j]->{main::key($num++,0,3,'governor')} = $cpu->{'governor'};
}
if ($extra > 2){
- if ($properties{'volts'}){
- $rows[$j]->{main::key($num++,0,2,'volts')} = $properties{'volts'} . ' V';
+ 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'};
+ if ($properties->{'ext-clock'}){
+ $rows[$j]->{main::key($num++,0,2,'ext-clock')} = $properties->{'ext-clock'};
}
}
$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){
+ foreach (@{$speeds}){
$rows[$j]->{main::key($num++,0,3,$i++)} = $_;
}
}
- if ($show{'cpu-flag'} && !$b_flags){
- $flag_key = ($b_arm || $bsd_type) ? 'Features': 'Flags';
- @flags = split(/\s+/, $cpu{'flags'}) if $cpu{'flags'};
+ if ($extra > 0 && !$bsd_type){
+ my $bogomips = ($cpu->{'bogomips'} &&
+ main::is_numeric($cpu->{'bogomips'})) ? int($cpu->{'bogomips'}) : 'N/A';
+ $rows[$j]->{main::key($num++,0,2,'bogomips')} = $bogomips;
+ }
+ if (($extra > 0 && !$show{'cpu-flag'}) || $show{'cpu-flag'}){
+ my @flags = ($cpu->{'flags'}) ? split(/\s+/, $cpu->{'flags'}) : ();
+ my $flag_key = (%risc || $bsd_type) ? 'Features': 'Flags';
my $flag = 'N/A';
+ if (!$show{'cpu-flag'}){
+ if (@flags){
+ # failure to read dmesg.boot: dmesg.boot permissions; then short -Cx list flags
+ @flags = grep {/^(dmesg.boot|permissions|avx[2-9]?|ht|lm|nx|pae|pni|(sss|ss)e([2-9])?([a-z])?(_[0-9])?|svm|vmx)$/} @flags;
+ @flags = map {s/pni/sse3/; $_} @flags if @flags;
+ @flags = sort @flags;
+ }
+ # only ARM has Features, never seen them for MIPS/PPC/SPARC/RISCV, but check
+ if ($risc{'arm'} && $flag eq 'N/A'){
+ $flag = main::message('arm-cpu-f');
+ }
+ }
if (@flags){
@flags = sort @flags;
- $flag = join(' ', @flags) if @flags;
+ $flag = join(' ', @flags);
}
push(@rows, {
main::key($num++,0,1,$flag_key) => $flag,
},);
}
if ($b_admin){
- my @bugs = cpu_bugs_sys();
my $value = '';
- if (!@bugs){
- if ($cpu{'bugs'}){
- my @proc_bugs = split(/\s+/, $cpu{'bugs'});
+ if (!defined $cpu->{'bugs-hash'}){
+ if ($cpu->{'bugs-string'}){
+ my @proc_bugs = split(/\s+/, $cpu->{'bugs-string'});
@proc_bugs = sort @proc_bugs;
$value = join(' ', @proc_bugs);
}
else {
- $value = main::row_defaults('cpu-bugs-null');
+ $value = main::message('cpu-bugs-null');
}
}
+ if ($use{'filter-vulnerabilities'} &&
+ (defined $cpu->{'bugs-hash'} || $cpu->{'bugs-string'})){
+ $value = $filter_string;
+ undef $cpu->{'bugs-hash'};
+ }
push(@rows, {
main::key($num++,1,1,'Vulnerabilities') => $value,
},);
- if (@bugs){
- $j = $#rows;
- foreach my $bug (@bugs){
- $rows[$j]->{main::key($num++,1,2,'Type')} = $bug->[0];
- $rows[$j]->{main::key($num++,0,3,$bug->[1])} = $bug->[2];
+ if (defined $cpu->{'bugs-hash'}){
+ $j = scalar @rows;
+ foreach my $key (sort keys %{$cpu->{'bugs-hash'}}){
+ $rows[$j]->{main::key($num++,1,2,'Type')} = $key;
+ $rows[$j]->{main::key($num++,0,3,$cpu->{'bugs-hash'}->{$key}[0])} = $cpu->{'bugs-hash'}->{$key}[1];
$j++;
}
}
@@ -8367,55 +8669,96 @@ sub full_output {
eval $end if $b_log;
return @rows;
}
+# $num, $rows passed by reference
+sub full_output_caches {
+ eval $start if $b_log;
+ my ($j,$properties,$num,$rows) = @_;
+ my $value = '';
+ if (!$properties->{'l1-cache'} && !$properties->{'l2-cache'} &&
+ !$properties->{'l3-cache'}){
+ $value = ($properties->{'cache'}) ? $properties->{'cache'} : 'N/A';
+ }
+ $$rows[$j]->{main::key($$num++,1,2,'cache')} = $value;
+ if ($extra > 0 && $properties->{'l1-cache'}){
+ $$rows[$j]->{main::key($$num++,2,3,'L1')} = $properties->{'l1-cache'};
+ if ($b_admin && ($properties->{'l1d-desc'} || $properties->{'l1i-desc'})){
+ my $desc = '';
+ if ($properties->{'l1d-desc'}){
+ $desc .= 'd-' . $properties->{'l1d-desc'};
+ }
+ if ($properties->{'l1i-desc'}){
+ $desc .= '; ' if $desc;
+ $desc .= 'i-' . $properties->{'l1i-desc'};
+ }
+ $$rows[$j]->{main::key($$num++,0,4,'desc')} = $desc;
+ }
+ }
+ # $$rows[$j]->{main::key($$num++,1,$l,$key)} = $support;
+ if (!$value){
+ $properties->{'l2-cache'} = ($properties->{'l2-cache'}) ? $properties->{'l2-cache'} : 'N/A';
+ $$rows[$j]->{main::key($$num++,1,3,'L2')} = $properties->{'l2-cache'};
+ if ($b_admin && $properties->{'l2-desc'}){
+ $$rows[$j]->{main::key($$num++,0,4,'desc')} = $properties->{'l2-desc'};
+ }
+ }
+ if ($extra > 0 && $properties->{'l3-cache'}){
+ $$rows[$j]->{main::key($$num++,1,3,'L3')} = $properties->{'l3-cache'};
+ if ($b_admin && $properties->{'l3-desc'}){
+ $$rows[$j]->{main::key($$num++,0,4,'desc')} = $properties->{'l3-desc'};
+ }
+ }
+ if ($properties->{'cache-check'}){
+ $$rows[$j]->{main::key($$num++,0,3,'note')} = $properties->{'cache-check'};
+ }
+ eval $end if $b_log;
+}
sub short_output {
eval $start if $b_log;
my ($cpu) = @_;
my @data;
my $num = 0;
- $cpu->[1] ||= main::row_defaults('cpu-model-null');
+ $cpu->[1] ||= main::message('cpu-model-null');
$cpu->[2] ||= 'N/A';
@data = ({
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++,1,2,'arch')} = $cpu->[7];
- if ($cpu->[8]){
- $data[0]->{main::key($num++,0,3,'note')} = $cpu->[8];
+ $data[0]->{main::key($num++,1,2,'arch')} = $cpu->[8];
+ if ($cpu->[9]){
+ $data[0]->{main::key($num++,0,3,'note')} = $cpu->[9];
}
}
- $data[0]->{main::key($num++,0,2,$cpu->[3])} = $cpu->[4];
+ my $value = ($cpu->[7]) ? '' : $cpu->[4];
+ $data[0]->{main::key($num++,1,2,$cpu->[3])} = $value;
+ if ($cpu->[7]){
+ $data[0]->{main::key($num++,0,3,$cpu->[7])} = $cpu->[4];
+ }
if ($cpu->[6]){
- $data[0]->{main::key($num++,0,2,$cpu->[5])} = $cpu->[6];
+ $data[0]->{main::key($num++,0,3,$cpu->[5])} = $cpu->[6];
}
eval $end if $b_log;
return @data;
}
+
+## SHORT OUTPUT DATA ##
sub short_data {
eval $start if $b_log;
- my ($type) = @_;
my $num = 0;
- my (%cpu,@data,%speeds);
+ my ($cpu,@data,%speeds);
my $sys = '/sys/devices/system/cpu/cpufreq/policy0';
# NOTE: : Permission denied, ie, this is not always readable
# /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq
if (my $file = $system_files{'proc-cpuinfo'}){
- my $sleep = $cpu_sleep * 1000000;
- if ($b_hires){
- eval 'Time::HiRes::usleep($sleep)';
- }
- else {
- select(undef, undef, undef, $cpu_sleep);
- }
- %cpu = cpuinfo_data($file,$type);
+ $cpu = cpuinfo_data($file);
}
elsif ($bsd_type){
my ($key1,$val1) = ('','');
if ($alerts{'sysctl'}){
if ($alerts{'sysctl'}->{'action'} eq 'use'){
# $key1 = 'Status';
-# $val1 = main::row_defaults('dev');
- %cpu = sysctl_data($type);
+# $val1 = main::message('dev');
+ $cpu = sysctl_data($type);
}
else {
$key1 = ucfirst($alerts{'sysctl'}->{'action'});
@@ -8426,52 +8769,310 @@ sub short_data {
}
}
# $cpu{'cur-freq'} = $cpu[0]->{'core-id'}[0]{'speed'};
- @data = prep_short_data(\%cpu);
+ @data = prep_short_data($cpu);
eval $end if $b_log;
return @data;
}
-
sub prep_short_data {
eval $start if $b_log;
my ($cpu_data) = @_;
- my %properties = cpu_properties($cpu_data);
+ my $properties = cpu_properties($cpu_data);
my ($cpu,$speed_key,$speed,$type) = ('','speed',0,'');
$cpu = $cpu_data->{'model_name'} if $cpu_data->{'model_name'};
- $type = $properties{'cpu-type'} if $properties{'cpu-type'};
- $speed_key = $properties{'speed-key'} if $properties{'speed-key'};
- $speed = $properties{'speed'} if $properties{'speed'};
+ $type = $properties->{'cpu-type'} if $properties->{'cpu-type'};
+ $speed_key = $properties->{'speed-key'} if $properties->{'speed-key'};
+ $speed = $properties->{'speed'} if $properties->{'speed'};
my @result = (
- $properties{'cpu-layout'},
+ $properties->{'topology-string'},
$cpu,
$type,
$speed_key,
$speed,
- $properties{'min-max-key'},
- $properties{'min-max'},
+ $properties->{'min-max-key'},
+ $properties->{'min-max'},
+ $properties->{'avg-speed-key'},
);
if ($extra > 0){
$cpu_data->{'arch'} ||= 'N/A';
- $result[7] = $cpu_data->{'arch'};
- $result[8] = $cpu_data->{'arch-note'};
+ $result[8] = $cpu_data->{'arch'};
+ $result[9] = $cpu_data->{'arch-note'};
}
eval $end if $b_log;
return @result;
}
+## PRIMARY DATA GENERATORS ##
sub cpuinfo_data {
eval $start if $b_log;
- my ($file,$type)= @_;
- my ($arch,@ids,@line,$b_first,$b_proc_int,$note,$starter);
+ my ($file)= @_;
+ my ($arch,$note,$temp);
# has to be set above fake cpu section
my %cpu = set_cpu_data();
+ # sleep is also set in front of sysctl_data for BSDs, same idea
+ my $sleep = $cpu_sleep * 1000000;
+ if ($b_hires){
+ eval 'Time::HiRes::usleep($sleep)';
+ }
+ else {
+ select(undef, undef, undef, $cpu_sleep);
+ }
+ # Run this logic first to make sure we get the speeds as raw as possible.
+ # Not in function to avoid unnecessary cpu use, we have slept right before.
+ # ARM and legacy systems etc do not always have cpufreq.
+ # note that there can be a definite cost to reading scaling_cur_freq, which
+ # must be generated on the fly based on some time snippet sample.
+ if (-e '/sys/devices/system/cpu/'){
+ my $glob = '/sys/devices/system/cpu/cpu*/cpufreq/{affected_cpus,';
+ # reading cpuinfo WAY faster than scaling, but root only
+ if (-r '/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq'){
+ $glob .= 'cpuinfo_cur_freq}';
+ }
+ else {
+ $glob .= 'scaling_cur_freq}';
+ }
+ my ($error,$file,$key,%working,%freq,@value);
+ foreach (main::globber($glob)){
+ next if ! -r $_;
+ undef $error;
+ # $fh always non null, even on error
+ open(my $fh, '<', $_) or $error = $!;
+ if (!$error){
+ m%/sys/devices/system/cpu/cpu(\d+)/cpufreq/(affected_cpus|(cpuinfo|scaling)_cur_freq)%;
+ $key = $1;
+ $file = $2;
+ chomp(@value = <$fh>);
+ close $fh;
+ if ($file eq 'affected_cpus'){
+ # chomp seems to turn undefined into '', not sure why
+ $working{$key}->[0] = $value[0] if $value[0] ne '';
+ }
+ else {
+ $working{$key}->[1] = clean_speed($value[0],'khz');
+ }
+ }
+ }
+ if (%working){
+ foreach (keys %working){
+ $freq{sprintf("%04d",$_)} = $working{$_}->[1] if defined $working{$_}->[0];
+ }
+ $cpu{'sys-freq'} = \%freq if %freq;
+ }
+ }
+ cpuinfo_data_grabber($file) if !$loaded{'cpuinfo'};
$cpu{'type'} = cpu_vendor($cpu_arch) if $cpu_arch =~ /e2k/; # already set to lower
+ my ($core_count,$proc_count,$speed) = (0,0,0);
+ my ($b_block_1) = (1);
+ # need to prime for arm cpus, which do not have physical/core ids usually
+ # level 0 is phys id, level 1 is die id, level 2 is core id
+ # note, there con be a lot of processors, 32 core HT would have 64, for example.
+ foreach my $block (@cpuinfo){
+ # get the repeated data for CPUs, after assign the dynamic per core data
+ next if !$block;
+ if ($b_block_1){
+ $b_block_1 = 0;
+ if (!$cpu{'type'} && $block->{'vendor_id'}){
+ $cpu{'type'} = cpu_vendor($block->{'vendor_id'});
+ }
+ # PPC can use 'cpu', MIPS 'cpu model'
+ $temp = main::get_defined($block->{'model name'},$block->{'cpu'},
+ $block->{'cpu model'});
+ if ($temp){
+ $cpu{'model_name'} = $temp;
+ $cpu{'model_name'} = main::clean($cpu{'model_name'});
+ $cpu{'model_name'} = clean_cpu($cpu{'model_name'});
+ if ($risc{'arm'} || $cpu{'model_name'} =~ /ARM|AArch/i){
+ $cpu{'type'} = 'arm';
+ if ($cpu{'model_name'} =~ /(.*)\srev\s([\S]+)\s(\(([\S]+)\))?/){
+ $cpu{'model_name'} = $1;
+ $cpu{'stepping'} = $2;
+ if ($4){
+ $cpu{'arch'} = $4;
+ if ($cpu{'model_name'} !~ /\Q$cpu{'arch'}\E/i){
+ $cpu{'model_name'} .= ' ' . $cpu{'arch'};
+ }
+ }
+ # print "p0:\n";
+ }
+ }
+ elsif ($risc{'mips'} || $cpu{'model_name'} =~ /mips/i){
+ $cpu{'type'} = 'mips';
+ }
+ }
+ $temp = main::get_defined($block->{'architecture'},
+ $block->{'cpu family'},$block->{'cpu architecture'});
+ if ($temp){
+ if ($temp =~ /^\d+$/){
+ # translate integers to hex
+ $cpu{'family'} = uc(sprintf("%x",$temp));
+ }
+ elsif ($risc{'arm'}){
+ $cpu{'arch'} = $temp;
+ }
+ }
+ # note: stepping and ARM cpu revision are integers
+ $temp = main::get_defined($block->{'stepping'},$block->{'cpu revision'});
+ # can be 0, but can be 'unknown'
+ if (defined $temp){
+ if ($temp =~ /^\d+$/){
+ $cpu{'stepping'} = uc(sprintf("%x",$temp));
+ }
+ }
+ # PPC revision is a string
+ elsif (defined $block->{'revision'}){
+ $cpu{'revision'} = $block->{'revision'};
+ }
+ # this is hex so uc for cpu arch id. raspi 4 has Model rather than Hardware
+ if (defined $block->{'model'}){
+ # can be 0, but can be 'unknown'
+ if ($temp =~ /^\d+$/){
+ $cpu{'model-id'} = uc(sprintf("%x",$block->{'model'}));
+ }
+ }
+ if ($block->{'cpu variant'}){
+ $cpu{'model-id'} = uc($block->{'cpu variant'});
+ $cpu{'model-id'} =~ s/^0X//;
+ }
+ # this is per cpu, not total if > 1 pys cpus
+ if (!$cpu{'cores'} && $block->{'cpu cores'}){
+ $cpu{'cores'} = $block->{'cpu cores'};
+ }
+ ## this is only for -C full cpu output
+ if ($type eq 'full'){
+ # note: in cases where only cache is there, don't guess, it can be L1,
+ # L2, or L3, but never all of them added togehter, so give up.
+ if ($block->{'cache size'} &&
+ $block->{'cache size'} =~ /(\d+\s*[KMG])i?B?$/){
+ $cpu{'cache'} = main::translate_size($1);
+ }
+ if ($block->{'l1 cache size'} &&
+ $block->{'l1 cache size'} =~ /(\d+\s*[KMG])i?B?$/){
+ $cpu{'l1-cache'} = main::translate_size($1);
+ }
+ if ($block->{'l2 cache size'} &&
+ $block->{'l2 cache size'} =~ /(\d+\s*[KMG])i?B?$/){
+ $cpu{'l2-cache'} = main::translate_size($1);
+ }
+ if ($block->{'l3 cache size'} &&
+ $block->{'l3 cache size'} =~ /(\d+\s*[KMG])i?B?$/){
+ $cpu{'l3-cache'} = main::translate_size($1);
+ }
+ if ($cpu{'type'} eq 'elbrus'){
+ # note: cache0 is L1i and cache1 L1d. cp_caches_fallback handles
+ if (!$cpu{'l1i-cache'} && $block->{'cache0'} &&
+ $block->{'cache0'} =~ /size\s*=\s*(\d+)K\s/){
+ $cpu{'l1i-cache'} = $1;
+ }
+ if (!$cpu{'l1d-cache'} && $block->{'cache1'} &&
+ $block->{'cache1'} =~ /size\s*=\s*(\d+)K\s/){
+ $cpu{'l1d-cache'} = $1;
+ }
+ if (!$cpu{'l2-cache'} && $block->{'cache2'} &&
+ $block->{'cache2'} =~ /size\s*=\s*(\d+)(K|M)\s/){
+ $cpu{'l2-cache'} = ($2 eq 'M') ? ($1*1024) : $1;
+ }
+ if (!$cpu{'l3-cache'} && $block->{'cache3'} &&
+ $block->{'cache3'} =~ /size\s*=\s*(\d+)(K|M)\s/){
+ $cpu{'l3-cache'} = ($2 eq 'M') ? ($1*1024) : $1;
+ }
+ }
+ $temp = main::get_defined($block->{'flags'} || $block->{'features'});
+ if ($temp){
+ $cpu{'flags'} = $temp;
+ }
+ if ($b_admin){
+ # note: not used unless maybe /sys data missing?
+ if ($block->{'bugs'}){
+ $cpu{'bugs-string'} = $block->{'bugs'};
+ }
+ # unlike family and model id, microcode appears to be hex already
+ if ($block->{'microcode'}){
+ if ($block->{'microcode'} =~ /0x/){
+ $cpu{'microcode'} = uc($block->{'microcode'});
+ $cpu{'microcode'} =~ s/^0X//;
+ }
+ else {
+ $cpu{'microcode'} = uc(sprintf("%x",$block->{'microcode'}));
+ }
+ }
+ }
+ }
+ }
+ ## Start incrementers
+ $temp = main::get_defined($block->{'cpu mhz'},$block->{'clock'});
+ if ($temp){
+ $speed = clean_speed($temp);
+ push(@{$cpu{'processors'}},$speed);
+ }
+ # new arm shows bad bogomip value, so don't use it, however, ancient
+ # cpus, intel 486, can have super low bogomips, like 33.17
+ if ($extra > 0 && $block->{'bogomips'} && ((%risc &&
+ $block->{'bogomips'} > 50) || !%risc)){
+ $cpu{'bogomips'} += $block->{'bogomips'};
+ }
+ # just to get core counts for ARM/MIPS/PPC systems
+ if (defined $block->{'processor'} && !$temp){
+ if ($block->{'processor'} =~ /^\d+$/){
+ push(@{$cpu{'processors'}},0);
+ }
+ }
+ # note: for alder lake, could vary, depending on if e or p core but we
+ # only care aobut the highest value for crude logic here
+ if ($block->{'siblings'} &&
+ (!$cpu{'siblings'} || $block->{'siblings'} > $cpu{'siblings'})){
+ $cpu{'siblings'} = $block->{'siblings'};
+ }
+ # Ignoring trying to catch dies with $block->{'physical id'},
+ # that's too buggy for cpuinfo
+ if (defined $block->{'core id'}){
+ # https://www.pcworld.com/article/3214635/components-processors/ryzen-threadripper-review-we-test-amds-monster-cpu.html
+ my $phys = (defined $block->{'physical id'}) ? $block->{'physical id'}: 0;
+ my $die_id = 0;
+ if (!grep {$_ eq $block->{'core id'}} @{$cpu{'ids'}->[$phys][$die_id]}){
+ push(@{$cpu{'ids'}->[$phys][$die_id]},$block->{'core id'});
+ }
+ }
+ }
+ undef @cpuinfo; # we're done with it, dump it
+ undef %cpuinfo_machine;
+ if (%risc){
+ if (!$cpu{'type'}){
+ $cpu{'type'} = $risc{'id'};
+ }
+ if (!$bsd_type){
+ my $system_cpus = system_cpu_name();
+ $cpu{'system-cpus'} = $system_cpus if %$system_cpus;
+ }
+ }
+ main::log_data('dump','%cpu',\%cpu) if $b_log;
+ print Data::Dumper::Dumper \%cpu if $dbg[8];
+ eval $end if $b_log;
+ return \%cpu;
+}
+sub cpuinfo_data_grabber {
+ eval $start if $b_log;
+ my ($file) = @_;
+ $loaded{'cpuinfo'} = 1;
# use --arm flag when testing arm cpus, and --fake-cpu to trigger fake data
if ($fake{'cpu'}){
+ ## CPU sys/cpuinfo pairs:
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/sys-ci-pairs/android-pocom3-fake-cpuinfo.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/sys-ci-pairs/arm-pine64-cpuinfo-1.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/sys-ci-pairs/arm-riscyslack2-cpuinfo-1.txt";
+ $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/sys-ci-pairs/ppc-stuntkidz~cpuinfo.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/sys-ci-pairs/riscv-unmatched-2021~cpuinfo-1.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/sys-ci-pairs/x86-brickwizard-atom-n270~cpuinfo-1.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/sys-ci-pairs/x86-amd-phenom-chrisretusn-cpuinfo-1.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/sys-ci-pairs/x86-drgibbon-intel-i7-cpuinfo.txt";
+ ## ARM/MIPS
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/arm/arm-4-core-pinebook-1.txt";
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/arm/armv6-single-core-1.txt";
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/arm/armv7-dual-core-1.txt";
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/arm/armv7-new-format-model-name-single-core.txt";
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/arm/arm-2-die-96-core-rk01.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/arm/arm-shevaplug-1.2ghz.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/mips/mips-mainusg-cpuinfo.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/ppc/ppc-debian-ppc64-cpuinfo.txt";
+ ## x86
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/amd/16-core-32-mt-ryzen.txt";
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/amd/2-16-core-epyc-abucodonosor.txt";
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/amd/2-core-probook-antix.txt";
@@ -8479,6 +9080,7 @@ sub cpuinfo_data {
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/amd/4-core-althlon-mjro.txt";
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/amd/4-core-apu-vc-box.txt";
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/amd/4-core-a10-5800k-1.txt";
+ $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/intel/1-core-486-fourtysixandtwo.txt";
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/intel/2-core-ht-atom-bruh.txt";
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/intel/core-2-i3.txt";
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/intel/8-core-i7-damentz64.txt";
@@ -8488,8 +9090,7 @@ sub cpuinfo_data {
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/intel/2-1-core-xeon-vm-vs2017.txt";
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/intel/4-1-core-xeon-vps-frodo1.txt";
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/intel/4-6-core-xeon-no-mt-lathander.txt";
- # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/mips/mips-mainusg-cpuinfo.txt";
- # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/ppc/ppc-debian-ppc64-cpuinfo.txt";
+ ## Elbrus
# $cpu{'type'} = 'elbrus'; # uncomment to test elbrus
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/elbrus/elbrus-2c3/cpuinfo.txt";
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/elbrus/1xE1C-8.txt";
@@ -8501,274 +9102,340 @@ sub cpuinfo_data {
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/elbrus/4xE2CDSP-4.txt";
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/elbrus/cpuinfo.e8c2.txt";
}
- my @cpuinfo = main::reader($file);
- my %speeds = set_cpu_speeds_sys();
- my @phys_cpus = (0);# start with 1 always
- my ($core_count,$die_holder,$die_id,$phys_id,$proc_count,$speed) = (0,0,0,0,0,0,0);
- my ($phys_holder) = (undef);
- # need to prime for arm cpus, which do not have physical/core ids usually
- # level 0 is phys id, level 1 is die id, level 2 is core id
- # note, there con be a lot of processors, 32 core HT would have 64, for example.
- foreach (@cpuinfo){
- next if /^\s*$/;
- @line = split(/\s*:\s*/, $_, 2);
- next if !$line[0];
- $starter = $line[0]; # preserve case for one specific ARM issue
- $line[0] = lc($line[0]);
- if ($b_arm && !$b_first && $starter eq 'Processor' && $line[1] !~ /^\d+$/){
- # print "l1:$line[1]\n";
- $cpu{'model_name'} = main::cleaner($line[1]);
- $cpu{'model_name'} = cpu_cleaner($cpu{'model_name'});
- $cpu{'type'} = 'arm';
- # Processor : AArch64 Processor rev 4 (aarch64)
- # Processor : Feroceon 88FR131 rev 1 (v5l)
- if ($cpu{'model_name'} && $cpu{'model_name'} =~ /(.*)\srev\s([\S]+)\s(\(([\S]+)\))?/){
- $cpu{'model_name'} = $1;
- $cpu{'stepping'} = $2;
- if ($4){
- $cpu{'arch'} = $4;
- $cpu{'model_name'} .= ' ' . $cpu{'arch'} if $cpu{'model_name'} !~ /$cpu{'arch'}/i;
- }
- $cpu{'processors'}->[$proc_count] = 0;
- $b_proc_int = 0;
- $b_first = 1;
- # print "p0:\n";
- }
- }
- elsif ($line[0] eq 'processor'){
- # this protects against double processor lines, one int, one string
- if ($line[1] =~ /^\d+$/){
- $b_proc_int = 1;
- $b_first = 1;
- $cpu{'processors'}->[$proc_count] = 0;
- $proc_count++;
- # print "p1: $proc_count\n";
- }
- else {
- if (!$b_proc_int){
- $cpu{'processors'}->[$proc_count] = 0;
- $proc_count++;
- # print "p2a: $proc_count\n";
- }
- if (!$b_first){
- # note: alternate:
- # Processor : AArch64 Processor rev 4 (aarch64)
- # but no model name type
- if ($b_arm || $line[1] =~ /ARM|AArch/i){
- $b_arm = 1;
- $cpu{'type'} = 'arm';
- }
- $cpu{'model_name'} = main::cleaner($line[1]);
- $cpu{'model_name'} = cpu_cleaner($cpu{'model'});
- # print "p2b:\n";
- }
- $b_first = 1;
- }
- }
- elsif (!$cpu{'family'} &&
- ($line[0] eq 'architecture' || $line[0] eq 'cpu family' ||
- $line[0] eq 'cpu architecture')){
- if ($line[1] =~ /^\d+$/){
- # translate integers to hex
- $cpu{'family'} = uc(sprintf("%x", $line[1]));
- }
- elsif ($b_arm){
- $cpu{'arch'} = $line[1];
- }
- }
- elsif (!defined $cpu{'stepping'} && ($line[0] eq 'stepping' ||
- $line[0] eq 'cpu revision')){
- $cpu{'stepping'} = uc(sprintf("%x", $line[1]));
- }
- # ppc
- elsif (!defined $cpu{'stepping'} && $line[0] eq 'revision'){
- $cpu{'stepping'} = $line[1];
- }
- # this is hex so uc for cpu arch id. raspi 4 has Model rather than Hard
- elsif (!$cpu{'model_id'} && (!$b_ppc && !$b_arm && $line[0] eq 'model')){
- $cpu{'model_id'} = uc(sprintf("%x", $line[1]));
- }
- elsif (!$cpu{'model_id'} && $line[0] eq 'cpu variant'){
- $cpu{'model_id'} = uc($line[1]);
- $cpu{'model_id'} =~ s/^0X//;
- }
- # cpu can show in arm
- elsif (!$cpu{'model_name'} && ($line[0] eq 'model name' ||
- $line[0] eq 'cpu' || $line[0] eq 'cpu model')){
- $cpu{'model_name'} = main::cleaner($line[1]);
- $cpu{'model_name'} = cpu_cleaner($cpu{'model_name'});
- if ($b_arm || $line[1] =~ /ARM|AArch/i){
- $b_arm = 1;
- $cpu{'type'} = 'arm';
- if ($cpu{'model_name'} &&
- $cpu{'model_name'} =~ /(.*)\srev\s([\S]+)\s(\(([\S]+)\))?/){
- $cpu{'model_name'} = $1;
- $cpu{'stepping'} = $2;
- if ($4){
- $cpu{'arch'} = $4;
- $cpu{'model_name'} .= ' ' . $cpu{'arch'} if $cpu{'model_name'} !~ /$cpu{'arch'}/i;
- }
- #$cpu{'processors'}->[$proc_count] = 0;
- }
- }
- elsif ($b_mips || $line[1] =~ /mips/i){
- $b_mips = 1;
- $cpu{'type'} = 'mips';
- }
- }
- elsif ($line[0] eq 'cpu mhz' || $line[0] eq 'clock'){
- $speed = speed_cleaner($line[1]);
- $cpu{'processors'}->[$proc_count-1] = $speed;
- #$ids[$phys_id]->[$die_id] = [$speed];
- }
- elsif (!$cpu{'siblings'} && $line[0] eq 'siblings'){
- $cpu{'siblings'} = $line[1];
+ my @raw = main::reader($file);
+ @raw = map {$_ =~ s/^\s*$/~~~/;$_;} @raw;
+ push(@raw,'~~~') if @raw;
+ my ($b_processor,$key,$value);
+ my ($i) = (0);
+ my @key_tests = ('firmware','hardware','mmu','model','motherboard',
+ 'platform','system type','timebase');
+ foreach my $row (@raw){
+ ($key,$value) = split(/\s*:\s*/,$row,2);
+ next if !defined $key;
+ # ARM: 'Hardware' can appear in processor block; system type (mips)
+ # ARM: CPU revision; machine: Revision/PPC: revision (CPU implied)
+ # orangepi3 has Hardware/Processor embedded in processor block
+ if (%risc && ((grep {lc($key) eq $_} @key_tests) ||
+ (!$risc{'ppc'} && lc($key) eq 'revision'))){
+ $b_processor = 0;
}
- elsif (!$cpu{'cores'} && $line[0] eq 'cpu cores'){
- $cpu{'cores'} = $line[1];
+ else {
+ $b_processor = 1;
}
- # increment by 1 for every new physical id we see. These are in almost all cases
- # separate cpus, not separate dies within a single cpu body.
- elsif ($line[0] eq 'physical id'){
- if (!defined $phys_holder || $phys_holder != $line[1]){
- # only increment if not in array counter
- push(@phys_cpus, $line[1]) if ! grep {/$line[1]/} @phys_cpus;
- $phys_holder = $line[1];
- # print "pid: $line[1] ph: $phys_holder did: $die_id\n";
- $die_id = 0;
- #$die_holder = 0;
+ if ($b_processor){
+ if ($key eq '~~~'){
+ $i++;
+ next;
}
+ # A small handful of ARM devices use Processor instead of 'model name'
+ # Processor : AArch64 Processor rev 4 (aarch64)
+ # Processor : Feroceon 88FR131 rev 1 (v5l)
+ $key = ($key eq 'Processor') ? 'model name' : lc($key);
+ $cpuinfo[$i]->{$key} = $value;
}
- elsif ($line[0] eq 'core id'){
- # print "ph: $phys_holder did: $die_id l1: $line[1] s: $speed\n";
- # https://www.pcworld.com/article/3214635/components-processors/ryzen-threadripper-review-we-test-amds-monster-cpu.html
- if ($line[1] > 0){
- $die_holder = $line[1];
- $core_count++;
- }
- # NOTE: this logic won't work for die detections, unforutnately.
- # ARM uses a different /sys based method, and ryzen relies on math on the cores
- # in process_data
- elsif ($line[1] == 0 && $die_holder > 0){
- $die_holder = $line[1];
- $core_count = 0;
- $die_id++ if ($cpu{'type'} ne 'intel' && $cpu{'type'} ne 'amd');
- }
- $phys_holder = 0 if ! defined $phys_holder;
- $ids[$phys_holder]->[$die_id][$line[1]] = $speed;
- # print "ph: $phys_holder did: $die_id l1: $line[1] s: $speed\n";
- }
- if (!$cpu{'type'} && $line[0] eq 'vendor_id'){
- $cpu{'type'} = cpu_vendor($line[1]);
+ else {
+ next if $cpuinfo_machine{lc($key)};
+ $cpuinfo_machine{lc($key)} = $value;
}
- ## this is only for -C full cpu output
- if ($type eq 'full'){
- if (!$cpu{'l2-cache'} && ($line[0] eq 'cache size' || $line[0] eq 'l2 cache size')){
- if ($line[1] =~ /(\d+\s*[KMG])i?B?$/){
- $cpu{'l2-cache'} = main::translate_size($1);
+ }
+ if ($b_log){
+ main::log_data('dump','@cpuinfo',\@cpuinfo);
+ main::log_data('dump','%cpuinfo_machine',\%cpuinfo_machine);
+ }
+ if ($dbg[41]){
+ print Data::Dumper::Dumper \@cpuinfo;
+ print Data::Dumper::Dumper \%cpuinfo_machine;
+ }
+ eval $end if $b_log;
+}
+sub cpu_sys_data {
+ eval $start if $b_log;
+ my $sys_freq = $_[0];
+ my (%cpu_sys);
+ my $working = sys_data_grabber();
+ return \%cpu_sys if !%{$working};
+ $cpu_sys{'data'} = $working->{'data'} if $working->{'data'};
+ my ($core_id,$fake_core_id,$phys_id,) = (0,0,-1);
+ my (%cache_ids,@freq_max,@freq_min);
+ foreach my $key (sort keys %{$working->{'cpus'}}){
+ ($core_id,$phys_id) = (0,0);
+ my $cpu_id = $key + 0;
+ my $speed;
+ my $cpu = $working->{'cpus'}{$key};
+ if (defined $cpu->{'topology'}{'physical_package_id'}){
+ $phys_id = sprintf("%04d",$cpu->{'topology'}{'physical_package_id'});
+ }
+ if (defined $cpu->{'topology'}{'core_id'}){
+ # id is not consistent, seen 5 digit id
+ $core_id = sprintf("%08d",$cpu->{'topology'}{'core_id'});
+ if ($fake{'cpu'}){
+ if (defined $cpu->{'cpufreq'}{'scaling_cur_freq'} &&
+ $cpu->{'cpufreq'}{'affected_cpus'} &&
+ $cpu->{'cpufreq'}{'affected_cpus'} ne 'UNDEFINED'){
+ $speed = clean_speed($cpu->{'cpufreq'}{'scaling_cur_freq'},'khz');
}
}
- elsif (!$cpu{'l1-cache'} && $line[0] eq 'l1 cache size'){
- if ($line[1] =~ /(\d+\s*[KMG])i?B?$/){
- $cpu{'l1-cache'} = main::translate_size($1);
- }
+ elsif (defined $sys_freq && defined $sys_freq->{$key}){
+ $speed = $sys_freq->{$key};
}
- elsif (!$cpu{'l3-cache'} && $line[0] eq 'l3 cache size'){
- if ($line[1] =~ /(\d+\s*[KMG])i?B?$/){
- $cpu{'l3-cache'} = main::translate_size($1);
- }
+ if (defined $speed){
+ push(@{$cpu_sys{'cpus'}->{$phys_id}{'cores'}{$core_id}},$speed);
+ push(@{$cpu_sys{'data'}->{'speeds'}{'all'}},$speed);
}
- if ($cpu{'type'} eq 'elbrus'){
- # note: cache0 is L1i and cache1 L1d, but add both for L1
- if (!$cpu{'l0-cache'} && $line[0] eq 'cache0'){
- if ($line[1] =~ /size\s*=\s*(\d+)K\s/){
- $cpu{'l0-cache'} = $1;
- }
- }
- elsif (!$cpu{'l1-cache'} && $line[0] eq 'cache1'){
- if ($line[1] =~ /size\s*=\s*(\d+)K\s/){
- $cpu{'l1-cache'} = $1;
- $cpu{'l1-cache'} += $cpu{'l0-cache'} if $cpu{'l0-cache'};
- }
- }
- elsif (!$cpu{'l2-cache'} && $line[0] eq 'cache2'){
- if ($line[1] =~ /size\s*=\s*(\d+)(K|M)\s/){
- $cpu{'l2-cache'} = ($2 eq 'M') ? ($1*1024) : $1;
- }
- }
- elsif (!$cpu{'l3-cache'} && $line[0] eq 'cache3'){
- if ($line[1] =~ /size\s*=\s*(\d+)(K|M)\s/){
- $cpu{'l3-cache'} = ($2 eq 'M') ? ($1*1024) : $1;
+ else {
+ push(@{$cpu_sys{'data'}->{'speeds'}{'all'}},0);
+ # seen cases, riscv, where core id, phys id, are all -1
+ my $id = ($core_id != -1) ? $core_id: $fake_core_id++;
+ push(@{$cpu_sys{'cpus'}->{$phys_id}{'cores'}{$id}},0);
+ }
+ # Only use if topology core-id exists, some virtualized cpus can list
+ # frequency data for the non available cores, but those do not show
+ # topology data.
+ # For max / min, we want to prep for the day 1 pys cpu has > 1 min/max freq
+ if (defined $cpu->{'cpufreq'}{'cpuinfo_max_freq'}){
+ $cpu->{'cpufreq'}{'cpuinfo_max_freq'} = clean_speed($cpu->{'cpufreq'}{'cpuinfo_max_freq'},'khz');
+ if (!grep {$_ eq $cpu->{'cpufreq'}{'cpuinfo_max_freq'}} @freq_max){
+ push(@freq_max,$cpu->{'cpufreq'}{'cpuinfo_max_freq'});
+ }
+ if (!grep {$_ eq $cpu->{'cpufreq'}{'cpuinfo_max_freq'}} @{$cpu_sys{'cpus'}->{$phys_id}{'max-freq'}}){
+ push(@{$cpu_sys{'cpus'}->{$phys_id}{'max-freq'}},$cpu->{'cpufreq'}{'cpuinfo_max_freq'});
+ }
+ }
+ if (defined $cpu->{'cpufreq'}{'cpuinfo_min_freq'}){
+ $cpu->{'cpufreq'}{'cpuinfo_min_freq'} = clean_speed($cpu->{'cpufreq'}{'cpuinfo_min_freq'},'khz');
+ if (!grep {$_ eq $cpu->{'cpufreq'}{'cpuinfo_min_freq'}} @freq_min){
+ push(@freq_min,$cpu->{'cpufreq'}{'cpuinfo_min_freq'});
+ }
+ if (!grep {$_ eq $cpu->{'cpufreq'}{'cpuinfo_min_freq'}} @{$cpu_sys{'cpus'}->{$phys_id}{'min-freq'}}){
+ push(@{$cpu_sys{'cpus'}->{$phys_id}{'min-freq'}},$cpu->{'cpufreq'}{'cpuinfo_min_freq'});
+ }
+ }
+ if (defined $cpu->{'cpufreq'}{'scaling_governor'}){
+ if (!grep {$_ eq $cpu->{'cpufreq'}{'scaling_governor'}} @{$cpu_sys{'cpus'}->{$phys_id}{'governor'}}){
+ push(@{$cpu_sys{'cpus'}->{$phys_id}{'governor'}},$cpu->{'cpufreq'}{'scaling_governor'});
+ }
+ }
+ if (defined $cpu->{'cpufreq'}{'scaling_driver'}){
+ $cpu_sys{'cpus'}->{$phys_id}{'scaling-driver'} = $cpu->{'cpufreq'}{'scaling_driver'};
+ }
+ }
+ if (!defined $cpu_sys{'data'}->{'cpufreq-boost'} && defined $cpu->{'cpufreq'}{'cpb'}){
+ $cpu_sys{'data'}->{'cpufreq-boost'} = $cpu->{'cpufreq'}{'cpb'};
+ }
+ if (defined $cpu->{'topology'}{'core_cpus_list'}){
+ $cpu->{'topology'}{'thread_siblings_list'} = $cpu->{'topology'}{'core_cpus_list'};
+ }
+ if (defined $cpu->{'cache'} && keys %{$cpu->{'cache'}} > 0){
+ foreach my $key2 (sort keys %{$cpu->{'cache'}}){
+ my $cache = $cpu->{'cache'}{$key2};
+ my $type = ($cache->{'type'} =~ /^([DI])/i) ? lc($1): '';
+ my $level = 'l' . $cache->{'level'} . $type;
+ # Very old systems, 2.6.xx do not have shared_cpu_list
+ if (!defined $cache->{'shared_cpu_list'} && defined $cache->{'shared_cpu_map'}){
+ $cache->{'shared_cpu_list'} = $cache->{'shared_cpu_map'};
+ }
+ # print Data::Dumper::Dumper $cache;
+ if (defined $cache->{'shared_cpu_list'}){
+ # not needed, the cpu is always in the range
+ # my $range = main::regex_range($cache->{'shared_cpu_list'});
+ my $size = main::translate_size($cache->{'size'});
+ # print "cpuid: $cpu_id phys-core: $phys_id-$core_id level: $level range: $range shared: $cache->{'shared_cpu_list'}\n";
+ if (!(grep {$_ eq $cache->{'shared_cpu_list'}} @{$cache_ids{$phys_id}->{$level}})){
+ push(@{$cache_ids{$phys_id}->{$level}},$cache->{'shared_cpu_list'});
+ push(@{$cpu_sys{'cpus'}->{$phys_id}{'caches'}{$level}},$size);
}
}
}
- if (!$cpu{'flags'} && ($line[0] eq 'flags' || $line[0] eq 'features')){
- $cpu{'flags'} = $line[1];
- }
- if ($extra > 0 && $line[0] eq 'bogomips'){
- # new arm shows bad bogomip value, so don't use it
- $cpu{'bogomips'} += $line[1] if $line[1] > 50;
- }
}
- if ($b_admin){
- # note: not used unless maybe /sys data missing?
- if (!$cpu{'bugs'} && $line[0] eq 'bugs'){
- $cpu{'bugs'} = $line[1];
- }
- # unlike family and model id, microcode appears to be hex already
- if (!$cpu{'microcode'} && $line[0] eq 'microcode'){
- if ($line[1] =~ /0x/){
- $cpu{'microcode'} = uc($line[1]);
- $cpu{'microcode'} =~ s/^0X//;
- }
- else {
- $cpu{'microcode'} = uc(sprintf("%x", $line[1]));
- }
+ # die_id is relatively new, core_siblings_list has been around longer
+ if (defined $cpu->{'topology'}{'die_id'} ||
+ defined $cpu->{'topology'}{'core_siblings_list'}){
+ my $die = $cpu->{'topology'}{'die_id'};
+ $die = $cpu->{'topology'}{'core_siblings_list'} if !defined $die;
+ if (!grep {$_ eq $die} @{$cpu_sys{'cpus'}->{$phys_id}{'dies'}}){
+ push(@{$cpu_sys{'cpus'}->{$phys_id}{'dies'}},$die);
}
}
}
- $cpu{'phys'} = scalar @phys_cpus;
- $cpu{'dies'} = $die_id++; # count starts at 0, all cpus have 1 die at least
- if ($b_arm || $b_mips){
- if ($cpu{'dies'} <= 1){
- my $arm_dies = cpu_dies_sys();
- # case were 4 core arm returned 4 sibling lists, obviously wrong
- $cpu{'dies'} = $arm_dies if $arm_dies && $proc_count != $arm_dies;
+ if (defined $cpu_sys{'data'}->{'cpufreq-boost'} &&
+ $cpu_sys{'data'}->{'cpufreq-boost'} =~ /^[01]$/){
+ if ($cpu_sys{'data'}->{'cpufreq-boost'}){
+ $cpu_sys{'data'}->{'cpufreq-boost'} = 'enabled';
}
- $cpu{'type'} = ($b_arm) ? 'arm' : 'mips' if !$cpu{'type'};
- if (!$bsd_type){
- my %system_cpus = system_cpu_name();
- $cpu{'system-cpus'} = \%system_cpus if %system_cpus;
+ else {
+ $cpu_sys{'data'}->{'cpufreq-boost'} = 'disabled';
}
}
- $cpu{'ids'} = (\@ids);
- if ($extra > 0 && !$cpu{'arch'} && $type ne 'short'){
- ($cpu{'arch'},$cpu{'arch-note'}) = cpu_arch($cpu{'type'},$cpu{'family'},$cpu{'model_id'},$cpu{'stepping'});
- # cpu_arch comes from set_os()
- $cpu{'arch'} = $cpu_arch if (!$cpu{'arch'} && $cpu_arch && ($b_mips || $b_arm || $b_ppc));
- # print "$cpu{'type'},$cpu{'family'},$cpu{'model_id'},$cpu{'arch'}\n";
+ # cpuinfo_max_freq:["2000000"] cpuinfo_max_freq:["1500000"]
+ # cpuinfo_min_freq:["200000"]
+ if (@freq_max){
+ $cpu_sys{'data'}->{'speeds'}{'max-freq'} = join(':',@freq_max);
+ }
+ if (@freq_min){
+ $cpu_sys{'data'}->{'speeds'}{'min-freq'} = join(':',@freq_min);
}
- if (!$speeds{'cur-freq'}){
- $cpu{'cur-freq'} = $cpu{'processors'}->[0];
- $speeds{'min-freq'} = 0;
- $speeds{'max-freq'} = 0;
+ if ((scalar @freq_max < 2 && scalar @freq_min < 2) &&
+ (defined $cpu_sys{'data'}->{'speeds'}{'min-freq'} &&
+ defined $cpu_sys{'data'}->{'speeds'}{'max-freq'}) &&
+ ($cpu_sys{'data'}->{'speeds'}{'min-freq'} > $cpu_sys{'data'}->{'speeds'}{'max-freq'} ||
+ $cpu_sys{'data'}->{'speeds'}{'min-freq'} == $cpu_sys{'data'}->{'speeds'}{'max-freq'})){
+ $cpu_sys{'data'}->{'speeds'}{'min-freq'} = 0;
}
+ main::log_data('dump','%cpu_sys',\%cpu_sys) if $b_log;
+ print Data::Dumper::Dumper \%cpu_sys if $dbg[8];
+ eval $end if $b_log;
+ return \%cpu_sys;
+}
+sub sys_data_grabber {
+ eval $start if $b_log;
+ my (@files);
+ # this data has to match the data in cpuinfo grabber fake cpu, and remember
+ # to use --arm flag if arm tests
+ if ($fake{'cpu'}){
+ my $file;
+ ## CPU sys/cpuinfo pairs:
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/sys-ci-pairs/android-pocom3-fake-sys.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/sys-ci-pairs/arm-pine64-sys-1.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/sys-ci-pairs/arm-riscyslack2-sys-1.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/sys-ci-pairs/ppc-stuntkidz~sys.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/sys-ci-pairs/riscv-unmatched-2021~sys-1.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/sys-ci-pairs/x86-brickwizard-atom-n270~sys-1.txt";
+ $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/sys-ci-pairs/x86-amd-phenom-chrisretusn-sys-1.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/sys-ci-pairs/x86-drgibbon-intel-i7-sys.txt";
+ @files = main::reader($file);
+ }
+ # There's a massive time hit reading full globbed set of files, so grab and
+ # read only what we need.
else {
- $cpu{'cur-freq'} = $speeds{'cur-freq'};
- $cpu{'min-freq'} = $speeds{'min-freq'};
- $cpu{'max-freq'} = $speeds{'max-freq'};
+ my $glob = '/sys/devices/system/cpu/{';
+ if ($dbg[43]){
+ $glob .= 'cpufreq,cpu*/topology,cpu*/cpufreq,cpu*/cache/index*,smt,vulnerabilities}/*';
+ }
+ else {
+ $glob .= 'cpu*/topology/{core_cpus_list,core_id,core_siblings_list,die_id,';
+ $glob .= 'physical_package_id,thread_siblings_list}';
+ $glob .= ',cpufreq/{boost,ondemand}';
+ $glob .= ',cpu*/cpufreq/{cpb,cpuinfo_max_freq,cpuinfo_min_freq';
+ $glob .= ($type eq 'full' && $b_admin) ? ',scaling_driver,scaling_governor}':'}';
+ if ($type eq 'full'){
+ $glob .= ',cpu*/cache/index*/{level,shared_cpu_list,shared_cpu_map,size,type}';
+ }
+ $glob .= ',smt/{active,control}';
+ if ($b_admin){
+ $glob .= ',vulnerabilities/*';
+ }
+ $glob .= '}';
+ }
+ @files = main::globber($glob);
}
- main::log_data('dump','%cpu',\%cpu) if $b_log;
- print Data::Dumper::Dumper \%cpu if $dbg[8];
+ main::log_data('dump','@files',\@files) if $b_log;
+ print Data::Dumper::Dumper \@files if $dbg[40];
+ my ($b_bug,$b_cache,$b_freq,$b_topo,$b_main,%working);
+ my ($main_id,$main_key,$holder,$id,$item,$key) = ('','','','','','');
+ # need to return hash reference on failure or old systems complain
+ return \%working if !@files;
+ foreach (sort @files){
+ if ($fake{'cpu'}){
+ ($_,$item) = split(/::/,$_,2);
+ }
+ else {
+ next if -d $_ || ! -e $_;
+ undef $item;
+ }
+ $key = $_;
+ $key =~ m|/([^/]+)/([^/]+)$|;
+ my ($key_1,$key_2) = ($1,$2);
+ if (m|/cpu(\d+)/|){
+ if (!$holder || $1 ne $holder){
+ $id = sprintf("%04d",$1);
+ $holder = $1;
+ }
+ $b_bug = 0;
+ $b_cache = 0;
+ $b_freq = 0;
+ $b_main = 0;
+ $b_topo = 0;
+ if ($key_1 eq 'cpufreq'){
+ $b_freq = 1;
+ $main_key = $key_2;
+ $key = $key_1;
+ }
+ elsif ($key_1 eq 'topology'){
+ $b_topo = 1;
+ $main_key = $key_2;
+ $key = $key_1;
+ }
+ elsif ($key_1 =~ /^index(\d+)$/){
+ $b_cache = 1;
+ $main_key = $key_2;
+ $main_id = sprintf("%02d",$1);
+ $key = 'cache';
+ }
+ }
+ elsif ($key_1 eq 'vulnerabilities'){
+ $id = $key_1;
+ $key = $key_2;
+ $b_bug = 1;
+ $b_cache = 0;
+ $b_main = 0;
+ $b_freq = 0;
+ $b_topo = 0;
+ $main_key = '';
+ $main_id = '';
+ }
+ else {
+ $id = $key_1 . '-' . $key_2;
+ $b_bug = 0;
+ $b_cache = 0;
+ $b_main = 1;
+ $b_freq = 0;
+ $b_topo = 0;
+ $main_key = '';
+ $main_id = '';
+ }
+ if (!$fake{'cpu'}){
+ if (-r $_) {
+ my $error;
+ # significantly faster to skip reader() and do it directly
+ # $fh always non null, even on error
+ open(my $fh, '<', $_) or $error = $!;
+ if (!$error){
+ chomp(my @value = <$fh>);
+ close $fh;
+ $item = $value[0];
+ }
+ # $item = main::reader($_,'strip',0);
+ }
+ else {
+ $item = main::message('root-required');
+ }
+ $item = main::message('undefined') if !defined $item;
+ }
+ # print "$key_1 :: $key_2 :: $item\n";
+ if ($b_main){
+ $working{'data'}->{$id} = $item;
+ }
+ elsif ($b_bug){
+ my $type = ($item =~ /^Mitigation:/) ? 'mitigation': 'status';
+ $item =~ s/Mitigation: //;
+ $working{'data'}->{$id}{$key} = [$type,$item];
+ }
+ elsif ($b_cache){
+ $working{'cpus'}->{$id}{$key}{$main_id}{$main_key} = $item;
+ }
+ elsif ($b_freq || $b_topo){
+ $working{'cpus'}->{$id}{$key}{$main_key} = $item;
+ }
+ }
+ main::log_data('dump','%working',\%working) if $b_log;
+ print Data::Dumper::Dumper \%working if $dbg[39];
eval $end if $b_log;
- return %cpu;
+ return \%working;
}
-
sub sysctl_data {
eval $start if $b_log;
- my ($type) = @_;
my %cpu = set_cpu_data();
- my (@ids,@line,%speeds,@working);
+ my (@line,%speeds,@working);
my ($sep) = ('');
my ($die_holder,$die_id,$phys_holder,$phys_id,$proc_count,$speed) = (0,0,0,0,0,0,0);
@{$sysctl{'cpu'}} = () if !$sysctl{'cpu'}; # don't want error next!
@@ -8783,8 +9450,8 @@ sub sysctl_data {
# openbsd 5.6: AMD Sempron(tm) Processor 3400+ ("AuthenticAMD" 686-class, 256KB L2 cache)
# openbsd 6.x has Lx cache data in dmesg.boot
# freebsd 10: hw.model: AMD Athlon(tm) II X2 245 Processor
- $line[1] = main::cleaner($line[1]);
- $line[1] = cpu_cleaner($line[1]);
+ $line[1] = main::clean($line[1]);
+ $line[1] = clean_cpu($line[1]);
if ($line[1] =~ /([0-9]+)[\s-]*([KM]B)\s+L2 cache/i){
my $multiplier = ($2 eq 'MB') ? 1024: 1;
$cpu{'l2-cache'} = $1 * $multiplier;
@@ -8793,12 +9460,12 @@ sub sysctl_data {
$cpu{'max-freq'} = $1;
if ($cpu{'max-freq'} =~ /MHz/i){
$cpu{'max-freq'} =~ s/[\s-]*MHz//;
- $cpu{'max-freq'} = speed_cleaner($cpu{'max-freq'},'mhz');
+ $cpu{'max-freq'} = clean_speed($cpu{'max-freq'},'mhz');
}
elsif ($cpu{'max-freq'} =~ /GHz/){
$cpu{'max-freq'} =~ s/[\s-]*GHz//i;
$cpu{'max-freq'} = $cpu{'max-freq'} / 1000;
- $cpu{'max-freq'} = speed_cleaner($cpu{'max-freq'},'mhz');
+ $cpu{'max-freq'} = clean_speed($cpu{'max-freq'},'mhz');
}
}
if ($line[1] =~ /\)$/){
@@ -8808,8 +9475,11 @@ sub sysctl_data {
$cpu{'type'} = cpu_vendor($line[1]);
}
# NOTE: hw.l1icachesize: hw.l1dcachesize: ; in bytes, apparently
+ elsif ($line[0] eq 'hw.l1dcachesize'){
+ $cpu{'l1d-cache'} = $line[1]/1024;
+ }
elsif ($line[0] eq 'hw.l1icachesize'){
- $cpu{'l1-cache'} = $line[1]/1024;
+ $cpu{'l1i-cache'} = $line[1]/1024;
}
elsif ($line[0] eq 'hw.l2cachesize'){
$cpu{'l2-cache'} = $line[1]/1024;
@@ -8817,6 +9487,14 @@ sub sysctl_data {
elsif ($line[0] eq 'hw.l3cachesize'){
$cpu{'l3-cache'} = $line[1]/1024;
}
+ # hw.smt: openbsd
+ elsif ($line[0] eq 'hw.smt'){
+ $cpu{'smt'} = ($line[1]) ? 'enabled' : 'disabled';
+ }
+ # htl: maybe freebsd, never seen, 1 is disabled, sigh...
+ elsif ($line[0] eq 'machdep.hlt_logical_cpus'){
+ $cpu{'smt'} = ($line[1]) ? 'disabled' : 'enabled';
+ }
# this is in mghz in samples
elsif (!$cpu{'cur-freq'} &&
($line[0] eq 'hw.clockrate' || $line[0] eq 'hw.cpuspeed')){
@@ -8835,7 +9513,7 @@ sub sysctl_data {
# FB seems to call freq something other than clock speed, unreliable
# eg: 1500 Mhz real shows as 2400 freq, which is wrong
# elsif ($line[0] =~ /^dev\.cpu\.([0-9]+)\.freq$/){
- # $speed = speed_cleaner($line[1]);
+ # $speed = clean_speed($line[1]);
# $cpu{'processors'}->[$1] = $speed;
# }
# weird FB thing, freq can be wrong, so just count the cores and call it
@@ -8851,6 +9529,7 @@ sub sysctl_data {
elsif ($line[0] eq 'machdep.cpu.features'){
$cpu{'flags'} = lc($line[1]);
}
+ # is this per phys or total?
elsif ($line[0] eq 'hw.ncpu'){
$cpu{'cores'} = $line[1];
}
@@ -8878,7 +9557,6 @@ sub sysctl_data {
my @temp = split(/\s+/, $line[1]);
my $count = scalar @temp;
$count-- if $count > 0;
- $cpu{'processors'}->[$count] = 0;
# no way to get per processor speeds yet, so assign 0 to each
foreach (0 .. $count){
$cpu{'processors'}->[$_] = 0;
@@ -8889,63 +9567,52 @@ sub sysctl_data {
my @temp = split(/\s+/, $line[1]);
$cpu{'siblings'} = scalar @temp;
}
- # increment by 1 for every new physical id we see. These are in almost all cases
- # separate cpus, not separate dies within a single cpu body.
+ # increment by 1 for every new physical id we see. These are in almost all
+ # cases separate cpus, not separate dies within a single cpu body.
+ # This needs DATA!! Almost certainly wrong!!
elsif ($line[0] eq 'hw.cpu_topology.cpu0.physical_id'){
if ($phys_holder != $line[1]){
$phys_id++;
$phys_holder = $line[1];
- $ids[$phys_id] = [0];
- $ids[$phys_id]->[$die_id] = [0];
+ push(@{$cpu{'ids'}->[$phys_id][$die_id]},0);
}
}
elsif ($line[0] eq 'hw.cpu_topology.cpu0.core_id'){
- if ($line[1] > 0){
- $die_holder = $line[1];
- }
- # this handles multi die cpus like 16 core ryzen
- elsif ($line[1] == 0 && $die_holder > 0){
- $die_id++ ;
- $die_holder = $line[1];
- }
- $ids[$phys_id]->[$die_id][$line[1]] = $speed;
- $cpu{'dies'} = $die_id;
+ $cpu{'ids'}->[$phys_id][$line[1]] = $speed;
}
}
if (!$cpu{'flags'} || !$cpu{'family'}){
- my %dmesg_boot = dboot_data();
+ my $dmesg_boot = dboot_data();
# this core count may fix failed MT detection.
- $cpu{'cores'} = $dmesg_boot{'cores'} if $dmesg_boot{'cores'};
- $cpu{'flags'} = $dmesg_boot{'flags'} if !$cpu{'flags'};
- $cpu{'family'} = $dmesg_boot{'family'} if !$cpu{'family'};
- $cpu{'l1-cache'} = $dmesg_boot{'l1-cache'} if !$cpu{'l1-cache'};
- $cpu{'l2-cache'} = $dmesg_boot{'l2-cache'} if !$cpu{'l2-cache'};
- $cpu{'l3-cache'} = $dmesg_boot{'l3-cache'} if !$cpu{'l3-cache'};
- $cpu{'microcode'} = $dmesg_boot{'microcode'} if !$cpu{'microcode'};
- $cpu{'model_id'} = $dmesg_boot{'model_id'} if !$cpu{'model_id'};
- $cpu{'max-freq'} = $dmesg_boot{'max-freq'} if !$cpu{'max-freq'};
- $cpu{'min-freq'} = $dmesg_boot{'min-freq'} if !$cpu{'min-freq'};
- $cpu{'scalings'} = $dmesg_boot{'scalings'} if !$cpu{'scalings'};
- $cpu{'siblings'} = $dmesg_boot{'siblings'} if !$cpu{'siblings'};
- $cpu{'stepping'} = $dmesg_boot{'stepping'} if !$cpu{'stepping'};
- $cpu{'type'} = $dmesg_boot{'type'} if !$cpu{'type'};
- }
- if ($extra > 0 && !$cpu{'arch'} && $type ne 'short'){
- ($cpu{'arch'},$cpu{'arch-note'}) = cpu_arch($cpu{'type'},$cpu{'family'},$cpu{'model_id'},$cpu{'stepping'});
- # print "$cpu{'type'},$cpu{'family'},$cpu{'model_id'},$cpu{'arch'}\n";
+ $cpu{'cores'} = $dmesg_boot->{'cores'} if $dmesg_boot->{'cores'};
+ $cpu{'flags'} = $dmesg_boot->{'flags'} if !$cpu{'flags'};
+ $cpu{'family'} = $dmesg_boot->{'family'} if !$cpu{'family'};
+ $cpu{'l1d-cache'} = $dmesg_boot->{'l1d-cache'} if !$cpu{'l1d-cache'};
+ $cpu{'l1i-cache'} = $dmesg_boot->{'l1i-cache'} if !$cpu{'l1i-cache'};
+ $cpu{'l2-cache'} = $dmesg_boot->{'l2-cache'} if !$cpu{'l2-cache'};
+ $cpu{'l3-cache'} = $dmesg_boot->{'l3-cache'} if !$cpu{'l3-cache'};
+ $cpu{'microcode'} = $dmesg_boot->{'microcode'} if !$cpu{'microcode'};
+ $cpu{'model-id'} = $dmesg_boot->{'model-id'} if !$cpu{'model-id'};
+ $cpu{'max-freq'} = $dmesg_boot->{'max-freq'} if !$cpu{'max-freq'};
+ $cpu{'min-freq'} = $dmesg_boot->{'min-freq'} if !$cpu{'min-freq'};
+ $cpu{'scalings'} = $dmesg_boot->{'scalings'} if !$cpu{'scalings'};
+ $cpu{'siblings'} = $dmesg_boot->{'siblings'} if !$cpu{'siblings'};
+ $cpu{'stepping'} = $dmesg_boot->{'stepping'} if !$cpu{'stepping'};
+ $cpu{'type'} = $dmesg_boot->{'type'} if !$cpu{'type'};
}
main::log_data('dump','%cpu',\%cpu) if $b_log;
print Data::Dumper::Dumper \%cpu if $dbg[8];
eval $end if $b_log;
- return %cpu;
+ return \%cpu;
}
+## DATA GENERATOR DATA SOURCES ##
sub dboot_data {
eval $start if $b_log;
my ($max_freq,$min_freq,@scalings,%values);
my ($family,$flags,$microcode,$model,$sep,$stepping,$type) = ('','','','','','','');
my ($cores,$siblings) = (0,0);
- my ($l1,$l2,$l3) = (0,0,0);
+ my ($l1d,$l1i,$l2,$l3) = (0,0,0,0);
# this will be null if it was not readable
my $file = $system_files{'dmesg-boot'};
if ($dboot{'cpu'}){
@@ -8982,11 +9649,11 @@ sub dboot_data {
elsif (/^cpu0:\s*[0-9\.]+[KMG]B\s/){
# cpu0: 32KB 64b/line 4-way L1 VIPT I-cache, 32KB 64b/line 4-way L1 D-cache
# cpu0:48KB 64b/line 3-way L1 PIPT I-cache, 32KB 64b/line 2-way L1 D-cache
- if (/\b([0-9\.]+[KMG])i?B\s\S+\s([0-9]+)-way\s(L1 \S+\s)?I[\s-]?cache/){
- $l1 = main::translate_size($1);
- }
if (/\b([0-9\.]+[KMG])i?B\s\S+\s([0-9]+)-way\sD[\s-]?cache/){
- # do nothing, we aren't going to use the D cache
+ $l1d = main::translate_size($1);
+ }
+ if (/\b([0-9\.]+[KMG])i?B\s\S+\s([0-9]+)-way\s(L1 \S+\s)?I[\s-]?cache/){
+ $l1i = main::translate_size($1);
}
if (/\b([0-9\.]+[KMG])i?B\s\S+\s([0-9]+)-way\sL2[\s-]?cache/){
$l2 = main::translate_size($1);
@@ -9008,7 +9675,7 @@ sub dboot_data {
}
# they don't seem to use hex for steppings, so convert it
if (/\bStepping\s*=\s*(0x)?([0-9a-f]+)\b/){
- $stepping = (!$1) ? uc(sprintf("%X", $2)) : $2;
+ $stepping = (!$1) ? uc(sprintf("%X",$2)) : $2;
}
}
elsif (/^cpu0:.*?[0-9\.]+\s?MHz:\sspeeds:\s(.*?)\s?MHz/){
@@ -9034,20 +9701,21 @@ sub dboot_data {
}
else {
if ($file && ! -r $file){
- $flags = main::row_defaults('dmesg-boot-permissions');
+ $flags = main::message('dmesg-boot-permissions');
}
}
%values = (
'cores' => $cores,
'family' => $family,
'flags' => $flags,
- 'l1-cache' => $l1,
+ 'l1d-cache' => $l1d,
+ 'l1i-cache' => $l1i,
'l2-cache' => $l2,
'l3-cache' => $l3,
'max-freq' => $max_freq,
'microcode' => $microcode,
'min-freq' => $min_freq,
- 'model_id' => $model,
+ 'model-id' => $model,
'scalings' => \@scalings,
'siblings' => $siblings,
'stepping' => $stepping,
@@ -9055,13 +9723,14 @@ sub dboot_data {
);
print Data::Dumper::Dumper \%values if $dbg[27];
eval $end if $b_log;
- return %values;
+ return \%values;
}
sub dmidecode_data {
eval $start if $b_log;
return if !@dmi;
- my %dmi_data = ('L1' => 0, 'L2' => 0,'L3' => 0, 'ext-clock' => undef, 'socket' => undef,
- 'speed' => undef, 'max-speed' => undef, 'upgrade' => undef, 'volts' => undef);
+ my %dmi_data = ('L1' => 0, 'L2' => 0,'L3' => 0, 'phys-cnt' => 0,
+ 'ext-clock' => undef, 'socket' => undef, 'speed' => undef,
+ 'max-speed' => undef, 'upgrade' => undef, 'volts' => undef);
my ($id,$amount,$socket,$upgrade);
foreach my $item (@dmi){
next if ref $item ne 'ARRAY';
@@ -9069,63 +9738,74 @@ sub dmidecode_data {
last if $item->[0] > 7;
if ($item->[0] == 7){
# skip first three rows, we don't need that data
+ # seen very bad data, L2 labeled L3, and random phantom type 7 caches
($id,$amount) = ('',0);
+ # Configuration: Disabled, Not Socketed, Level 2
+ next if $item->[4] =~ /^Configuration:.*Disabled/i;
+ # labels have to be right before the block, otherwise exiting sub errors
+ DMI:
foreach my $value (@$item[3 .. $#$item]){
- next if $value =~ /~/;
+ next if $value =~ /^~/;
# variants: L3 - Cache; L3 Cache; L3-cache; L2 CACHE; CPU Internal L1
if ($value =~ /^Socket Designation:.*? (L[1-3])\b/){
- $id = $1;
+ $id = lc($1);
}
# some cpus only show Socket Designation: Internal cache
elsif (!$id && $value =~ /^Configuration:.* Level.*?([1-3])\b/){
- $id = "L$1";
+ if ($value !~ /Disabled/i){
+ $id = "l$1";
+ }
}
# NOTE: cache is in KiB or MiB but they call it kB or MB
# so we send translate_size k or M which trips KiB/MiB mode
+ # if disabled can be 0.
elsif ($id && $value =~ /^Installed Size:\s+(.*?[kKM])i?B$/){
+ # Config..Disabled test should have gotten this, but just in case 0 size
+ next DMI if !$1;
$amount = main::translate_size($1);
- }
+ }
if ($id && $amount){
- $dmi_data{$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.
+ # and most 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,s we don't need that data
- ($socket,$upgrade) = (undef);
+ ($socket,$upgrade) = (undef,undef);
+ $dmi_data{'phys-cnt'}++; # try to catch bsds without physical cpu count
foreach my $value (@$item[3 .. $#$item]){
- next if $value =~ /~/;
+ 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;
+ $upgrade = main::clean_dmi($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;
+ $socket = main::clean_dmi($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);
+ $dmi_data{'volts'} = main::clean_dmi($1);
}
elsif ($value =~ /^Current Speed:\s*([0-9\.]+)\s*([MGK]Hz)?\b/i){
- $dmi_data{'speed'} = main::dmi_cleaner($1);
+ $dmi_data{'speed'} = main::clean_dmi($1);
}
elsif ($value =~ /^Max Speed:\s*([0-9\.]+)\s*([MGK]Hz)?\b/i){
- $dmi_data{'max-speed'} = main::dmi_cleaner($1);
+ $dmi_data{'max-speed'} = main::clean_dmi($1);
}
elsif ($value =~ /^External Clock:\s*([0-9\.]+\s*[MGK]Hz)\b/){
- $dmi_data{'ext-clock'} = main::dmi_cleaner($1);
+ $dmi_data{'ext-clock'} = main::clean_dmi($1);
}
}
}
@@ -9143,148 +9823,355 @@ sub dmidecode_data {
$dmi_data{'upgrade'} = $upgrade;
}
main::log_data('dump','%dmi_data',\%dmi_data) if $b_log;
- # print Data::Dumper::Dumper \%dmi_data;
+ print Data::Dumper::Dumper \%dmi_data if $dbg[27];
eval $end if $b_log;
- return %dmi_data;
+ return \%dmi_data;
}
+## CPU PROPERTIES MAIN ##
sub cpu_properties {
my ($cpu) = @_;
- my ($b_amd_zen,$b_epyc,$b_ht,$b_elbrus,$b_intel,$b_ryzen,$b_xeon);
- my ($cores_x,$cache_check) = (1,'');
- if ($cpu->{'type'}){
- if ($cpu->{'type'} eq 'intel'){
- $b_intel = 1;
- $b_xeon = 1 if $cpu->{'model_name'} =~ /Xeon/i;
- }
- elsif ($cpu->{'type'} eq 'amd'){
- if ($cpu->{'family'} && $cpu->{'family'} eq '17'){
- $b_amd_zen = 1;
- if ($cpu->{'model_name'}){
- if ($cpu->{'model_name'} =~ /Ryzen/i){
- $b_ryzen = 1;
- }
- elsif ($cpu->{'model_name'} =~ /EPYC/i){
- $b_epyc = 1;
- }
- }
- }
+ my ($cpu_sys,%dmi_data,%tests);
+ my %caches = (
+ 'cache' => 0, # general, non id'ed from cpuinfo generic cache
+ 'l1' => 0,
+ 'l1d' => 0,
+ 'l1i' => 0,
+ 'l2' => 0,
+ 'l3' => 0,
+ );
+ my %counts = (
+ 'dies' => 0,
+ 'cpu-cores' => 0,
+ 'cores' => 0,
+ 'cores-multiplier' => 0,
+ 'physical' => 0,
+ 'processors' => 0,
+ );
+ my ($cache_check) = ('');
+ if (!$bsd_type && -d '/sys/devices' && !$force{'cpuinfo'}){
+ $cpu_sys = cpu_sys_data($cpu->{'sys-freq'});
+ }
+ cp_test_types($cpu,\%tests) if $cpu->{'type'};
+ undef $cpu_sys if $dbg[42];
+ ## START CPU DATA HANDLERS ##
+ if (defined $cpu_sys->{'cpus'}){
+ cp_data_sys(
+ $cpu,
+ $cpu_sys,
+ \%caches,
+ \%counts
+ );
+ }
+ if (!defined $cpu_sys->{'cpus'} || !$counts{'physical'} ||
+ !$counts{'cpu-cores'}){
+ cp_data_fallback(
+ $cpu,
+ \%caches,
+ \$cache_check,
+ \%counts,
+ \%tests,
+ );
+ }
+ # some arm cpus report each core as its own die, but that's wrong
+ if (%risc && $counts{'dies'} > 1 && $counts{'cpu-cores'} == $counts{'dies'}){
+ $counts{'dies'} = 1;
+ $cpu->{'dies'} = 1;
+ }
+ if ($type eq 'full' && ($extra > 1 || ($bsd_type && !$cpu->{'l2-cache'}))){
+ cp_data_dmi(
+ $cpu,
+ \%dmi_data,
+ \%caches,
+ \%counts, # only to set BSD phys cpu counts if not found
+ \$cache_check,
+ );
+ }
+ ## END CPU DATA HANDLERS ##
+
+ # print "pc: $counts{'processors'} s: $cpu->{'siblings'} cpuc: $counts{'cpu-cores'} corec: $counts{'cores'}\n";
+
+ ## START CACHE PROCESSING ##
+ # Get BSD and legacy linux caches if not already from dmidecode or cpu_sys.
+ if ($type eq 'full' && !$caches{'l1'} && !$caches{'l2'} && !$caches{'l2'}){
+ cp_caches_fallback(
+ \%counts,
+ $cpu,
+ \%caches,
+ \$cache_check,
+ );
+ }
+ # nothing to check!
+ if ($type eq 'full'){
+ if (!$caches{'l1'} && !$caches{'l2'} && !$caches{'l3'} && !$caches{'cache'}){
+ $cache_check = '';
+ }
+ if ($caches{'cache'}){
+ # we don't want any math done on this one, who knows what it is
+ $caches{'cache'} = cp_cache_processor($caches{'cache'},1);
+ }
+ if ($caches{'l1'}){
+ $caches{'l1'} = cp_cache_processor($caches{'l1'},$counts{'physical'});
}
- elsif ($cpu->{'type'} eq 'elbrus'){
- $b_elbrus = 1;
+ if ($caches{'l2'}){
+ $caches{'l2'} = cp_cache_processor($caches{'l2'},$counts{'physical'});
}
+ if ($caches{'l3'}){
+ $caches{'l3'} = cp_cache_processor($caches{'l3'},$counts{'physical'});
+ }
+ }
+ ## END CACHE PROCESSING ##
+
+ ## START TYPE/LAYOUT/ARCH/BUGS ##
+ my ($cpu_type) = ('');
+ $cpu_type = cp_cpu_type(
+ \%counts,
+ $cpu,
+ \%tests
+ );
+ my %topology;
+ cp_cpu_topology(\%counts,\%topology);
+ my $arch = cp_cpu_arch(
+ $cpu->{'type'},
+ $cpu->{'family'},
+ $cpu->{'model-id'},
+ $cpu->{'stepping'}
+ );
+ # arm cpuinfo case only; confirm on bsds, not sure all get family/ids
+ if ($arch->[0] && !$cpu->{'arch'}){
+ ($cpu->{'arch'},$cpu->{'arch-note'}) = @{$arch};
+ }
+ # cpu_arch comes from set_os()
+ if (!$cpu->{'arch'} && $cpu_arch && %risc){
+ $cpu->{'arch'} = $cpu_arch;
+ }
+ if ($b_admin && defined $cpu_sys->{'data'}{'vulnerabilities'}){
+ $cpu->{'bugs-hash'} = $cpu_sys->{'data'}{'vulnerabilities'};
+ }
+ ## END TYPE/LAYOUT/ARCH/BUGS ##
+
+ ## START SPEED/BITS ##
+ my $speed_info = cp_speed_data($cpu,$cpu_sys);
+ if (!$bits_sys && !%risc && $cpu->{'flags'}){
+ $bits_sys = ($cpu->{'flags'} =~ /\blm\b/) ? 64 : 32;
+ }
+ ## END SPEED/BITS ##
+
+ ## LOAD %cpu_properties
+ my %cpu_properties = (
+ 'avg-speed-key' => $speed_info->{'avg-speed-key'},
+ 'bits-sys' => $bits_sys,
+ 'cache' => $caches{'cache'},
+ 'cache-check' => $cache_check,
+ 'cpu-type' => $cpu_type,
+ 'dmi-max-speed' => $dmi_data{'max-speed'},
+ 'dmi-speed' => $dmi_data{'speed'},
+ 'ext-clock' => $dmi_data{'ext-clock'},
+ 'high-speed-key' => $speed_info->{'high-speed-key'},
+ 'l1-cache' => $caches{'l1'},
+ 'l1d-desc' => $caches{'l1d-desc'},
+ 'l1i-desc' => $caches{'l1i-desc'},
+ 'l2-cache' => $caches{'l2'},
+ 'l2-desc' => $caches{'l2-desc'},
+ 'l3-cache' => $caches{'l3'},
+ 'l3-desc' => $caches{'l3-desc'},
+ 'min-max-key' => $speed_info->{'min-max-key'},
+ 'min-max' => $speed_info->{'min-max'},
+ 'socket' => $dmi_data{'socket'},
+ 'speed-key' => $speed_info->{'speed-key'},
+ 'speed' => $speed_info->{'speed'},
+ 'topology-full' => $topology{'full'},
+ 'topology-string' => $topology{'string'},
+ 'upgrade' => $dmi_data{'upgrade'},
+ 'volts' => $dmi_data{'volts'},
+ );
+ if ($b_log){
+ main::log_data('dump','%cpu_properties',\%cpu_properties);
+ main::log_data('dump','%topology',\%topology);
}
- # my @dies = $phys[0]->[0];
- my @phys = @{$cpu->{'ids'}};
- my $physical_count = 0;
- # my $physical_count = scalar @phys;
- my @processors;
- my ($speed,$speed_key);
- # handle case where cpu reports say, phys id 0, 2, 4, 6 [yes, seen it]
- foreach (@phys){
- $physical_count++ if $_;
+ # print Data::Dumper::Dumper $cpu;
+ if ($dbg[38]){
+ print Data::Dumper::Dumper \%cpu_properties;
+ print Data::Dumper::Dumper \%topology;
+ }
+ # my $dc = scalar @dies;
+ # print 'phys: ' . $pc . ' dies: ' . $dc, "\n";
+ eval $end if $b_log;
+ return \%cpu_properties;
+}
+
+## CPU DATA ENGINES ##
+# everything is passed by reference so no need to return anything
+sub cp_data_dmi {
+ eval $start if $b_log;
+ my ($cpu,$dmi_data,$caches,$counts,$cache_check) = @_;
+ my $cpu_dmi = dmidecode_data();
+ # fix for bsds that do not show physical cpus, like openbsd
+ if ($cpu_dmi->{'phys-cnt'} && $counts->{'physical'} == 1 &&
+ $cpu_dmi->{'phys-cnt'} > 1){
+ $counts->{'physical'} = $cpu_dmi->{'phys-cnt'};
+ }
+ # We have to undef all the sys stuff to get back to the true dmidecode results
+ # Too many variants to treat one by one, just clear it out if forced.
+ undef %$caches if $force{'dmidecode'};
+ # We don't want to use dmi L1/L2/L3 at all for non BSD systems unless forced
+ # because have seen totally gibberish dmidecode data for caches. /sys cache
+ # data preferred, more granular and basically consistently right.
+ # Only run for linux if no cache data found, but BSD use to fill in missing
+ # (we don't care about legacy errors for BSD since the data isn't adequate).
+ # legacy dmidecode cache data used the per cache value, NOT the per CPU total
+ # value like it does today. Which makes it impossible to know for sure if the
+ # given value is right (new, or if cache matched cpu total) or inadequate.
+ if ((!$bsd_type && !$caches->{'l1'} && !$caches->{'l2'} && !$caches->{'l3'}) ||
+ ($bsd_type && (!$caches->{'l1'} || !$caches->{'l2'} || !$caches->{'l3'}))){
+ # Newer dmi: cache type total per phys cpu; Legacy: raw cache size only
+ if ($cpu_dmi->{'l1'} && !$caches->{'l1'}){
+ $caches->{'l1'} = $cpu_dmi->{'l1'};
+ $$cache_check = main::message('note-check');
+ }
+ # note: bsds often won't have L2 catch data found yet, but bsd sysctl can
+ # have these values so let's check just in case. OpenBSD does have it often.
+ if ($cpu_dmi->{'l2'} && !$caches->{'l2'}){
+ $caches->{'l2'} = $cpu_dmi->{'l2'};
+ $$cache_check = main::message('note-check');
+ }
+ if ($cpu_dmi->{'l3'} && !$caches->{'l3'}){
+ $caches->{'l3'} = $cpu_dmi->{'l3'};
+ $$cache_check = main::message('note-check');
+ }
+ }
+ $dmi_data->{'max-speed'} = $cpu_dmi->{'max-speed'};
+ $dmi_data->{'socket'} = $cpu_dmi->{'socket'} if $cpu_dmi->{'socket'};
+ $dmi_data->{'upgrade'} = $cpu_dmi->{'upgrade'} if $cpu_dmi->{'upgrade'};
+ $dmi_data->{'speed'} = $cpu_dmi->{'speed'} if $cpu_dmi->{'speed'};
+ $dmi_data->{'ext-clock'} = $cpu_dmi->{'ext-clock'} if $cpu_dmi->{'ext-clock'};
+ $dmi_data->{'volts'} = $cpu_dmi->{'volts'} if $cpu_dmi->{'volts'};
+ eval $end if $b_log;
+}
+sub cp_data_fallback {
+ eval $start if $b_log;
+ my ($cpu,$caches,$cache_check,$counts,$tests) = @_;
+ if (!$counts->{'physical'}){
+ # handle case where cpu reports say, phys id 0, 2, 4, 6
+ foreach (@{$cpu->{'ids'}}){
+ $counts->{'physical'}++ if $_;
+ }
}
# count unique processors ##
# note, this fails for intel cpus at times
- @processors = @{$cpu->{'processors'}};
# print ref $cpu->{'processors'}, "\n";
- my $processors_count = scalar @processors;
- # print "p count:$processors_count\n";
- # 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){
- my @elbrus = elbrus_data($cpu->{'family'},$cpu->{'model_id'},$processors_count,$cpu->{'arch'});
- $cpu_cores = $elbrus[0];
- $physical_count = $elbrus[1];
+ if (!$counts->{'processors'}){
+ $counts->{'processors'} = scalar @{$cpu->{'processors'}};
+ }
+ # print "p count:$counts->{'processors'}\n";
+ # print Data::Dumper::Dumper $cpu->{'processors'};
+ # $counts->{'cpu-cores'} is per physical cpu
+ # note: elbrus supports turning off cores, so we need to add one for cases
+ # where rounds to 0 or 1 less
+ # print "$cpu{'type'},$cpu{'family'},$cpu{'model-id'},$cpu{'arch'}\n";
+ if ($tests->{'elbrus'} && $counts->{'processors'}){
+ my @elbrus = cp_elbrus_data($cpu->{'family'},$cpu->{'model-id'},
+ $counts->{'processors'},$cpu->{'arch'});
+ $counts->{'cpu-cores'} = $elbrus[0];
+ $counts->{'physical'} = $elbrus[1];
$cpu->{'arch'} = $elbrus[2];
- # print 'model id: ' . $cpu->{'model_id'} . ' arch: ' . $cpu->{'arch'} . " cpc: $cpu_cores phyc: $physical_count proc: $processors_count \n";
+ # print 'model id: ' . $cpu->{'model-id'} . ' arch: ' . $cpu->{'arch'} . " cpc: $counts->{'cpu-cores'} phyc: $counts->{'physical'} proc: $counts->{'processors'} \n";
}
- $physical_count ||= 1; # assume 1 if no id found, as with ARM
- foreach my $die_ref (@phys){
+ $counts->{'physical'} ||= 1; # assume 1 if no id found, as with ARM
+ foreach my $die_ref (@{$cpu->{'ids'}}){
next if ref $die_ref ne 'ARRAY';
- $core_count = 0;
- $die_count = scalar @$die_ref;
- #$cpu->{'dies'} = $die_count;
+ $counts->{'cores'} = 0;
+ $counts->{'dies'} = scalar @$die_ref;
+ #$cpu->{'dies'} = $counts->{'dies'};
foreach my $core_ref (@$die_ref){
next if ref $core_ref ne 'ARRAY';
- $core_count = 0;# reset for each die!!
+ $counts->{'cores'} = 0;# reset for each die!!
# NOTE: the counters can be undefined because the index comes from
# core id: which can be 0 skip 1 then 2, which leaves index 1 undefined
- # arm cpus do not actually show core id so ignore that counter
+ # risc cpus do not actually show core id so ignore that counter
foreach my $id (@$core_ref){
- $core_count++ if defined $id && !$b_arm;
+ $counts->{'cores'}++ if defined $id && !%risc;
}
- # print 'cores: ' . $core_count, "\n";
+ # print 'cores: ' . $counts->{'cores'}, "\n";
}
}
# this covers potentially cases where ARM cpus have > 1 die
- $cpu->{'dies'} = ($b_arm && $die_count <= 1 && $cpu->{'dies'} > 1) ? $cpu->{'dies'}: $die_count;
+ # maybe applies to all risc, not sure, but dies is broken anyway for cpuinfo
+ if (!$cpu->{'dies'}){
+ if ($risc{'arm'} && $counts->{'dies'} <= 1 && $cpu->{'dies'} > 1){
+ $counts->{'dies'} = $cpu->{'dies'};
+ }
+ else {
+ $cpu->{'dies'} = $counts->{'dies'};
+ }
+ }
# this is an attempt to fix the amd family 15 bug with reported cores vs actual cores
# NOTE: amd A6-4400M APU 2 core reports: cores: 1 siblings: 2
# NOTE: AMD A10-5800K APU 4 core reports: cores: 2 siblings: 4
- if (!$cpu_cores){
- if ($cpu->{'cores'} && !$core_count || $cpu->{'cores'} >= $core_count){
- $cpu_cores = $cpu->{'cores'};
+ if (!$counts->{'cpu-cores'}){
+ if ($cpu->{'cores'} && !$counts->{'cores'} ||
+ $cpu->{'cores'} >= $counts->{'cores'}){
+ $counts->{'cpu-cores'} = $cpu->{'cores'};
}
- elsif ($core_count > $cpu->{'cores'}){
- $cpu_cores = $core_count;
+ elsif ($counts->{'cores'} > $cpu->{'cores'}){
+ $counts->{'cpu-cores'} = $counts->{'cores'};
}
}
- # print "cpu-c:$cpu_cores\n";
- #$cpu_cores = $cpu->{'cores'};
+ # print "cpu-c:$counts->{'cpu-cores'}\n";
+ # $counts->{'cpu-cores'} = $cpu->{'cores'};
# like, intel core duo
# NOTE: sadly, not all core intel are HT/MT, oh well...
# xeon may show wrong core / physical id count, if it does, fix it. A xeon
# may show a repeated core id : 0 which gives a fake num_of_cores=1
- if ($b_intel){
- if ($cpu->{'siblings'} && $cpu->{'siblings'} > 1 && $cpu->{'cores'} && $cpu->{'cores'} > 1){
+ if ($tests->{'intel'}){
+ if ($cpu->{'siblings'} && $cpu->{'siblings'} > 1 &&
+ $cpu->{'cores'} && $cpu->{'cores'} > 1){
if ($cpu->{'siblings'}/$cpu->{'cores'} == 1){
- $b_intel = 0;
- $b_ht = 0;
+ $tests->{'intel'} = 0;
+ $tests->{'ht'} = 0;
}
else {
- $cpu_cores = ($cpu->{'siblings'}/2);
- $b_ht = 1;
+ $counts->{'cpu-cores'} = ($cpu->{'siblings'}/2);
+ $tests->{'ht'} = 1;
}
}
}
- # ryzen is made out of blocks of 8 core dies
- elsif ($b_ryzen){
- $cpu_cores = $cpu->{'cores'};
+ # ryzen is made out of blocks of 2, 4, or 8 core dies...
+ if ($tests->{'ryzen'}){
+ $counts->{'cpu-cores'} = $cpu->{'cores'};
# note: posix ceil isn't present in Perl for some reason, deprecated?
- my $working = $cpu_cores / 8;
+ my $working = $counts->{'cpu-cores'} / 8;
my @temp = split('\.', $working);
$cpu->{'dies'} = ($temp[1] && $temp[1] > 0) ? $temp[0]++ : $temp[0];
+ $counts->{'dies'} = $cpu->{'dies'};
}
# these always have 4 dies
- elsif ($b_epyc){
- $cpu_cores = $cpu->{'cores'};
- $cpu->{'dies'} = 4;
+ elsif ($tests->{'epyc'}){
+ $counts->{'cpu-cores'} = $cpu->{'cores'};
+ $counts->{'dies'} = $cpu->{'dies'} = 4;
}
-# elsif ($b_elbrus){
-# $cpu_cores =
-# }
+ # elsif ($tests->{'elbrus'}){
+ # $counts->{'cpu-cores'} =
+ # }
# final check, override the num of cores value if it clearly is wrong
# and use the raw core count and synthesize the total instead of real count
- if ($cpu_cores == 0 && ($cpu->{'cores'} * $physical_count > 1)){
- $cpu_cores = ($cpu->{'cores'} * $physical_count);
+ if ($counts->{'cpu-cores'} == 0 &&
+ $cpu->{'cores'} * $counts->{'physical'} > 1){
+ $counts->{'cpu-cores'} = ($cpu->{'cores'} * $counts->{'physical'});
}
# last check, seeing some intel cpus and vms with intel cpus that do not show any
# core id data at all, or siblings.
- if ($cpu_cores == 0 && $processors_count > 0){
- $cpu_cores = $processors_count;
+ if ($counts->{'cpu-cores'} == 0 && $counts->{'processors'} > 0){
+ $counts->{'cpu-cores'} = $counts->{'processors'};
}
# this happens with BSDs which have very little cpu data available
- if ($processors_count == 0 && $cpu_cores > 0){
- $processors_count = $cpu_cores;
- if ($bsd_type && ($b_ht || $b_amd_zen) && $cpu_cores > 2){
- $cpu_cores = $cpu_cores/2;;
+ if ($counts->{'processors'} == 0 && $counts->{'cpu-cores'} > 0){
+ $counts->{'processors'} = $counts->{'cpu-cores'};
+ if ($bsd_type && ($tests->{'ht'} || $tests->{'amd-zen'}) &&
+ $counts->{'cpu-cores'} > 2){
+ $counts->{'cpu-cores'} = $counts->{'cpu-cores'}/2;;
}
- my $count = $processors_count;
+ my $count = $counts->{'processors'};
$count-- if $count > 0;
$cpu->{'processors'}[$count] = 0;
# no way to get per processor speeds yet, so assign 0 to each
@@ -9294,421 +10181,258 @@ sub cpu_properties {
$cpu->{'processors'}[$_] = 0;
}
}
- # so far only OpenBSD has a way to detect MT cpus
+ # so far only OpenBSD has a way to detect MT cpus, but Openbsd has disabled MT
if ($bsd_type){
- if ($cpu->{'siblings'}){
- $cores_x = $cpu_cores if $cpu_cores && $cpu_cores > 1;
+ if ($cpu->{'siblings'} &&
+ $counts->{'cpu-cores'} && $counts->{'cpu-cores'} > 1){
+ $counts->{'cores-multiplier'} = $counts->{'cpu-cores'};
}
# if no siblings we couldn't get MT status of cpu so can't trust cache
else {
- $cache_check = main::row_defaults('note-check');
+ $$cache_check = main::message('note-check');
}
}
- # only elbrus shows L1 / L3 cache data in cpuinfo
- else {
- $cores_x = $cpu_cores if $cpu_cores && $cpu_cores > 1;
+ # only elbrus shows L1 / L3 cache data in cpuinfo, cpu_sys data should show
+ # for newer full linux.
+ elsif ($counts->{'cpu-cores'} && $counts->{'cpu-cores'} > 1) {
+ $counts->{'cores-multiplier'} = $counts->{'cpu-cores'};
}
# last test to catch some corner cases
# seen a case where a xeon vm in a dual xeon system actually had 2 cores, no MT
# so it reported 4 siblings, 2 cores, but actually only had 1 core per virtual cpu
- # print "prc: $processors_count phc: $physical_count coc: $core_count cpc: $cpu_cores\n";
- if (!$b_arm && $processors_count == $physical_count*$core_count && $cpu_cores > $core_count){
- $b_ht = 0;
- #$b_xeon = 0;
- $b_intel = 0;
- $cpu_cores = 1;
- $core_count = 1;
+ # print "prc: $counts->{'processors'} phc: $counts->{'physical'} coc: $counts->{'cores'} cpc: $counts->{'cpu-cores'}\n";
+ # this test was for arm but I think it applies to all risc, but risc will be sys
+ if (!%risc &&
+ $counts->{'processors'} == $counts->{'physical'} * $counts->{'cores'} &&
+ $counts->{'cpu-cores'} > $counts->{'cores'}){
+ $tests->{'ht'} = 0;
+ # $tests->{'xeon'} = 0;
+ $tests->{'intel'} = 0;
+ $counts->{'cpu-cores'} = 1;
+ $counts->{'cores'} = 1;
$cpu->{'siblings'} = 1;
}
- if ($extra > 1 || ($bsd_type && !$cpu->{'l2-cache'})){
- # 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 %cpu_dmi = dmidecode_data();
- my $multi = ($bsd_type) ? $cpu_cores: 1;
- $l1_cache = $cpu_dmi{'L1'} * $physical_count if $cpu_dmi{'L1'};
- # note: bsds often won't have L2 catch data found yet
- $cpu->{'l2-cache'} = $cpu_dmi{'L2'} if !$cpu->{'l2-cache'} && $cpu_dmi{'L2'};
- $l3_cache = $cpu_dmi{'L3'} * $physical_count if $cpu_dmi{'L3'};
- # bsd sysctl can have these values so let's check just in case
- $l1_cache = $cpu->{'l1-cache'} * $cores_x * $physical_count if !$l1_cache && $cpu->{'l1-cache'};
- # L3 is almost always per physical cpu, not per core
- $l3_cache = $cpu->{'l3-cache'} * $physical_count if !$l3_cache && $cpu->{'l3-cache'};
- $cache_check = '' if !$l1_cache && !$cpu->{'l2-cache'} && !$l3_cache; # nothing to check!
- $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'};
- }
- # print "pc: $processors_count s: $cpu->{'siblings'} cpuc: $cpu_cores corec: $core_count\n";
- # Algorithm:
- # if > 1 processor && processor id (physical id) == core id then Multi threaded (MT)
- # if siblings > 1 && siblings == 2 * num_of_cores ($cpu->{'cores'}) then Multi threaded (MT)
- # if > 1 processor && processor id (physical id) != core id then Multi-Core Processors (MCP)
- # if > 1 processor && processor ids (physical id) > 1 then Symmetric Multi Processing (SMP)
- # if = 1 processor then single core/processor Uni-Processor (UP)
- if ($processors_count > 1 || ($b_intel && $cpu->{'siblings'} > 0)){
- # non-multicore MT
- if ($processors_count == ($physical_count * $cpu_cores * 2)){
- # print "mt:1\n";
- $cpu_type .= 'MT';
- }
-# elsif ($b_xeon && $cpu->{'siblings'} > 1){
-# # print "mt:2\n";
-# $cpu_type .= 'MT';
-# }
- elsif ($cpu->{'siblings'} > 1 && ($cpu->{'siblings'} == 2 * $cpu_cores)){
- # print "mt:3\n";
- $cpu_type .= 'MT';
- }
- # non-MT multi-core or MT multi-core
- if (($processors_count == $cpu_cores) || ($physical_count < $cpu_cores)){
- my $sep = ($cpu_type) ? ' ' : '' ;
- $cpu_type .= $sep . 'MCP';
- }
- # only solidly known > 1 die cpus will use this, ryzen and arm for now
- if ($cpu->{'dies'} > 1){
- my $sep = ($cpu_type) ? ' ' : '' ;
- $cpu_type .= $sep . 'MCM';
- }
- # >1 cpu sockets active: Symetric Multi Processing
- if ($physical_count > 1){
- my $sep = ($cpu_type) ? ' ' : '' ;
- $cpu_type .= $sep . 'SMP';
- }
- }
- else {
- $cpu_type = 'UP';
- }
- if ($physical_count > 1){
- $cpu_layout = $physical_count . 'x ';
- }
- $cpu_layout .= count_alpha($cpu_cores) . 'Core';
- $cpu_layout .= ' (' . $cpu->{'dies'}. '-Die)' if !$bsd_type && $cpu->{'dies'} > 1;
- if (!$cpu->{'l2-cache'}){
- # do nothing
- }
- # the only possible change for bsds is if we can get phys counts in the future
- # Looks like Intel on bsd shows L2 per core, not total. Note: Pentium N3540
- # uses 2(not 4)xL2 cache size for 4 cores, sigh... you just can't win...
- elsif ($bsd_type){
- $l2_cache = $cpu->{'l2-cache'} * $cores_x * $physical_count;
- }
- # AMD SOS chips appear to report full L2 cache per core
- elsif ($cpu->{'type'} eq 'amd' && ($cpu->{'family'} eq '14' || $cpu->{'family'} eq '15' || $cpu->{'family'} eq '16')){
- $l2_cache = $cpu->{'l2-cache'} * $physical_count;
- }
- elsif ($cpu->{'type'} ne 'intel'){
- $l2_cache = $cpu->{'l2-cache'} * $cpu_cores * $physical_count;
- }
- ## note: this handles how intel reports L2, total instead of per core like AMD does
- # note that we need to multiply by number of actual cpus here to get true cache size
- else {
- $l2_cache = $cpu->{'l2-cache'} * $physical_count;
- }
- if ($cpu->{'cur-freq'} && $cpu->{'min-freq'} && $cpu->{'max-freq'}){
- $min_max = "$cpu->{'min-freq'}/$cpu->{'max-freq'} MHz";
- $min_max_key = "min/max";
- $speed_key = ($show{'short'} || $show{'cpu-basic'}) ? 'speed' : 'Speed';
- $speed = "$cpu->{'cur-freq'} MHz";
- }
- elsif ($cpu->{'cur-freq'} && $cpu->{'max-freq'}){
- $min_max = "$cpu->{'max-freq'} MHz";
- $min_max_key = "max";
- $speed_key = ($show{'short'} || $show{'cpu-basic'}) ? 'speed' : 'Speed';
- $speed = "$cpu->{'cur-freq'} MHz";
- }
-# elsif ($cpu->{'cur-freq'} && $cpu->{'max-freq'} && $cpu->{'cur-freq'} == $cpu->{'max-freq'}){
-# $speed_key = ($show{'short'} || $show{'cpu-basic'}) ? 'speed' : 'Speed';
-# $speed = "$cpu->{'cur-freq'} MHz (max)";
-# }
- elsif ($cpu->{'cur-freq'} && $cpu->{'min-freq'}){
- $min_max = "$cpu->{'min-freq'} MHz";
- $min_max_key = "min";
- $speed_key = ($show{'short'} || $show{'cpu-basic'}) ? 'speed' : 'Speed';
- $speed = "$cpu->{'cur-freq'} MHz";
- }
- elsif ($cpu->{'cur-freq'} && !$cpu->{'max-freq'}){
- $speed_key = ($show{'short'} || $show{'cpu-basic'}) ? 'speed' : 'Speed';
- $speed = "$cpu->{'cur-freq'} MHz";
- }
-
- if (!$bits_sys && !$b_arm && $cpu->{'flags'}){
- $bits_sys = ($cpu->{'flags'} =~ /\blm\b/) ? 64 : 32;
- }
- my %cpu_properties = (
- 'bits-sys' => $bits_sys,
- 'cache-check' => $cache_check,
- '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,
- );
- main::log_data('dump','%cpu_properties',\%cpu_properties) if $b_log;
- # print Data::Dumper::Dumper $cpu;
- # print Data::Dumper::Dumper \%cpu_properties;
- # my $dc = scalar @dies;
- # print 'phys: ' . $pc . ' dies: ' . $dc, "\n";
eval $end if $b_log;
- return %cpu_properties;
}
-
-sub cpu_bugs_sys {
+# all values passed by reference so no need for returns
+sub cp_data_sys {
eval $start if $b_log;
- my (@bugs,$type,$value);
- return if ! -d '/sys/devices/system/cpu/vulnerabilities/';
- my @items = main::globber('/sys/devices/system/cpu/vulnerabilities/*');
- if (@items){
- foreach (@items){
- $value = (-r $_) ? main::reader($_,'',0) : main::row_defaults('root-required');
- $type = ($value =~ /^Mitigation:/) ? 'mitigation': 'status';
- $_ =~ s/.*\/([^\/]+)$/$1/;
- $value =~ s/Mitigation: //;
- push(@bugs,[($_,$type,$value)]);
- }
+ my ($cpu,$cpu_sys,$caches,$counts) = @_;
+ my (@keys) = (sort keys %{$cpu_sys->{'cpus'}});
+ return if !@keys;
+ $counts->{'physical'} = scalar @keys;
+ if ($type eq 'full' && $cpu_sys->{'cpus'}{$keys[0]}{'caches'}){
+ cp_sys_caches($cpu_sys->{'cpus'}{$keys[0]}{'caches'},$caches,'l1','l1d');
+ cp_sys_caches($cpu_sys->{'cpus'}{$keys[0]}{'caches'},$caches,'l1','l1i');
+ cp_sys_caches($cpu_sys->{'cpus'}{$keys[0]}{'caches'},$caches,'l2','');
+ cp_sys_caches($cpu_sys->{'cpus'}{$keys[0]}{'caches'},$caches,'l3','');
}
- main::log_data('dump','@bugs',\@bugs) if $b_log;
- # print Data::Dumper::Dumper \@bugs;
- eval $end if $b_log;
- return @bugs;
-}
-
-sub cpu_speeds {
- eval $start if $b_log;
- my ($processors) = @_;
- my (@speeds);
- my @files = main::globber('/sys/devices/system/cpu/cpu*/cpufreq/scaling_cur_freq');
- foreach (@files){
- my $speed = main::reader($_,'',0);
- if (defined $speed){
- $speed = sprintf("%.0f", $speed/1000);
- push(@speeds, $speed);
- }
+ if ($cpu_sys->{'data'}{'speeds'}{'all'}){
+ $counts->{'processors'} = scalar @{$cpu_sys->{'data'}{'speeds'}{'all'}};
}
- if (!@speeds){
- # handle special case, FB, where we use undef for no processor speed found
- foreach (@$processors){
- if ($_ || (defined $_ && $_ eq '0')){
- $_ = sprintf("%.0f", $_);
- push(@speeds, $_);
- }
+ if (defined $cpu_sys->{'data'}{'smt-active'}){
+ if ($cpu_sys->{'data'}{'smt-active'}){
+ $cpu->{'smt'} = 'enabled';
+ }
+ # values: on/off/notsupported/notimplemented
+ elsif (defined $cpu_sys->{'data'}{'smt-control'} &&
+ $cpu_sys->{'data'}{'smt-control'} =~ /^not/){
+ $cpu->{'smt'} = main::message('unsupported');
+ }
+ else {
+ $cpu->{'smt'} = 'disabled';
}
}
- # print join('; ', @speeds), "\n";
- eval $end if $b_log;
- return @speeds;
-}
-sub set_cpu_speeds_sys {
- eval $start if $b_log;
- my (@max_freq,@min_freq,@policies,%speeds);
- my $sys = '/sys/devices/system/cpu/cpufreq/policy0';
- my $sys2 = '/sys/devices/system/cpu/cpu0/cpufreq/';
- my ($cur,$min,$max) = ('scaling_cur_freq','scaling_min_freq','scaling_max_freq');
- if (!-d $sys && -d $sys2){
- $sys = $sys2;
- ($cur,$min,$max) = ('scaling_cur_freq','cpuinfo_min_freq','cpuinfo_max_freq');
- }
- if (-d $sys){
- # corner cases, android, will have the files but they may be unreadable
- if (-r "$sys/$cur"){
- $speeds{'cur-freq'} = main::reader("$sys/$cur",'',0);
- $speeds{'cur-freq'} = speed_cleaner($speeds{'cur-freq'},'khz');
- }
- if (-r "$sys/$min"){
- $speeds{'min-freq'} = main::reader("$sys/$min",'',0);
- $speeds{'min-freq'} = speed_cleaner($speeds{'min-freq'},'khz');
- }
- if (-r "$sys/$max"){
- $speeds{'max-freq'} = main::reader("$sys/$max",'',0);
- $speeds{'max-freq'} = speed_cleaner($speeds{'max-freq'},'khz');
- }
- if ($b_arm || $b_mips){
- @policies = main::globber('/sys/devices/system/cpu/cpufreq/policy*/');
- # there are arm chips with two dies, that run at different min max speeds!!
- # see: https://github.com/smxi/inxi/issues/128
- # it would be slick to show both die min/max/cur speeds, but this is
- # ok for now.
- if (scalar @policies > 1){
- my ($current,$cur_temp,$max,$max_temp,$min,$min_temp) = (0,0,0,0,0,0);
- foreach (@policies){
- $_ =~ s/\/$//; # strip off last slash in case globs have them
- $max_temp = (-r "$_/cpuinfo_max_freq") ? main::reader("$_/cpuinfo_max_freq",'',0) : 0;
- if ($max_temp){
- $max_temp = speed_cleaner($max_temp,'khz');
- push(@max_freq, $max_temp);
- }
- $max = $max_temp if ($max_temp > $max);
- $min_temp = (-r "$_/cpuinfo_min_freq") ? main::reader("$_/cpuinfo_min_freq",'',0) : 0;
- if ($min_temp){
- $min_temp = speed_cleaner($min_temp,'khz');
- push(@min_freq, $min_temp);
- }
- $min = $min_temp if ($min_temp < $min || $min == 0);
- $cur_temp = (-r "$_/scaling_cur_freq") ? main::reader("$_/scaling_cur_freq",'',0) : 0;
- $cur_temp = speed_cleaner($cur_temp,'khz') if $cur_temp;
- if ($cur_temp > $current){
- $current = $cur_temp;
+ my $i = 0;
+ my (@governor,@max,@min,@phys_cores);
+ foreach my $phys_id (@keys){
+ if ($cpu_sys->{'cpus'}{$phys_id}{'cores'}){
+ my ($mt,$st) = (0,0);
+ my (@core_keys) = keys %{$cpu_sys->{'cpus'}{$phys_id}{'cores'}};
+ $cpu->{'cores'} = $counts->{'cpu-cores'} = scalar @core_keys;
+ $counts->{'cpu-topo'}[$i]{'cores'} = $cpu->{'cores'};
+ if ($cpu_sys->{'cpus'}{$phys_id}{'dies'}){
+ $counts->{'cpu-topo'}[$i]{'dies'} = scalar @{$cpu_sys->{'cpus'}{$phys_id}{'dies'}};
+ $cpu->{'dies'} = $counts->{'cpu-topo'}[$i]{'dies'};
+ }
+ # If we ever get > 1 min/max speed per phy cpu, we'll need to fix the [0]
+ if ($cpu_sys->{'cpus'}{$phys_id}{'max-freq'}[0]){
+ if (!grep {$cpu_sys->{'cpus'}{$phys_id}{'max-freq'}[0] eq $_} @max){
+ push(@max,$cpu_sys->{'cpus'}{$phys_id}{'max-freq'}[0]);
+ }
+ $counts->{'cpu-topo'}[$i]{'max'} = $cpu_sys->{'cpus'}{$phys_id}{'max-freq'}[0];
+ }
+ if ($cpu_sys->{'cpus'}{$phys_id}{'min-freq'}[0]){
+ if (!grep {$cpu_sys->{'cpus'}{$phys_id}{'min-freq'}[0] eq $_} @min){
+ push(@min,$cpu_sys->{'cpus'}{$phys_id}{'min-freq'}[0]);
+ }
+ $counts->{'cpu-topo'}[$i]{'min'} = $cpu_sys->{'cpus'}{$phys_id}{'min-freq'}[0];
+ }
+ # cheating, this is not a count, but we need the data for topology, must
+ # sort since governors can be in different order if > 1
+ if ($cpu_sys->{'cpus'}{$phys_id}{'governor'}){
+ foreach my $gov (@{$cpu_sys->{'cpus'}{$phys_id}{'governor'}}){
+ push(@governor,$gov) if !grep {$_ eq $gov} @governor;
+ }
+ $cpu->{'governor'} = join(',',@governor);
+ }
+ if ($cpu_sys->{'cpus'}{$phys_id}{'scaling-driver'}){
+ $cpu->{'scaling-driver'} = $cpu_sys->{'cpus'}{$phys_id}{'scaling-driver'};
+ }
+ if ($cpu_sys->{'cpus'}{$phys_id}{'scaling-driver'}){
+ $cpu->{'scaling-driver'} = $cpu_sys->{'cpus'}{$phys_id}{'scaling-driver'};
+ }
+ if (!grep {$counts->{'cpu-cores'} eq $_} @phys_cores){
+ push(@phys_cores,$counts->{'cpu-cores'});
+ }
+ if ($counts->{'processors'}){
+ if ($counts->{'processors'} > $counts->{'cpu-cores'}){
+ for my $key (@core_keys){
+ if ((my $threads = scalar @{$cpu_sys->{'cpus'}{$phys_id}{'cores'}{$key}}) > 1){
+ $counts->{'cpu-topo'}[$i]{'cores-mt'}++;
+ $counts->{'cpu-topo'}[$i]{'threads'} += $threads;
+ $counts->{'cpu-topo'}[$i]{'tpc'} = $threads;
+ $counts->{'struct-mt'} = 1;
+ }
+ else {
+ $counts->{'cpu-topo'}[$i]{'cores-st'}++;
+ $counts->{'cpu-topo'}[$i]{'threads'}++;
+ $counts->{'struct-st'} = 1;
+ }
}
}
- if (@max_freq){
- main::uniq(\@max_freq);
- $max = join(':', @max_freq);
- }
- if (@min_freq){
- main::uniq(\@min_freq);
- $min = join(':', @min_freq);
- }
- $speeds{'cur-freq'} = $current if $current;
- $speeds{'max-freq'} = $max if $max;
- $speeds{'min-freq'} = $min if $min;
}
- }
- # policy4/cpuinfo_max_freq:["2000000"] policy0/cpuinfo_max_freq:["1500000"]
- # policy4/cpuinfo_min_freq:["200000"]
- if ((scalar @max_freq < 2 && scalar @min_freq < 2) &&
- (defined $speeds{'min-freq'} && defined $speeds{'max-freq'}) &&
- ($speeds{'min-freq'} > $speeds{'max-freq'} ||
- $speeds{'min-freq'} == $speeds{'max-freq'})){
- $speeds{'min-freq'} = 0;
+ $i++;
}
}
- main::log_data('dump','%speeds',\%speeds) if $b_log;
- eval $end if $b_log;
- return %speeds;
-}
-
-# right now only using this for ARM cpus, this is not the same in intel/amd
-sub cpu_dies_sys {
- eval $start if $b_log;
- my @data = main::globber('/sys/devices/system/cpu/cpu*/topology/core_siblings_list');
- my (@dies);
- foreach (@data){
- my $siblings = main::reader($_,'',0);
- if (! grep {/$siblings/} @dies){
- push(@dies, $siblings);
- }
+ $counts->{'struct-max'} = 1 if scalar @max > 1;
+ $counts->{'struct-min'} = 1 if scalar @min > 1;
+ $counts->{'struct-cores'} = 1 if scalar @phys_cores > 1;
+ if ($b_log){
+ main::log_data('dump','%cpu_properties',$caches);
+ main::log_data('dump','%cpu_properties',$counts);
}
- my $die_count = scalar @dies;
+ # print Data::Dumper::Dumper $caches;
+ # print Data::Dumper::Dumper $counts;
eval $end if $b_log;
- return $die_count;
}
-# needed because no physical_id in cpuinfo, but > 1 cpu systems exist
-# returns: 0 - per cpu cores; 1 - phys cpu count; 2 - override model defaul names
-sub elbrus_data {
+sub cp_sys_caches {
eval $start if $b_log;
- my ($family_id,$model_id,$count,$arch) = @_;
- # 0: cores
- my @return = (0,1,$arch);
- my %cores = (
- # key=family id + model id
- '41' => 1,
- '42' => 1,
- '43' => 4,
- '44' => 2,
- '46' => 1,
- '47' => 8,
- '48' => 1,
- '49' => 8,
- '59' => 8,
- '4A' => 12,
- '4B' => 16,
- '4C' => 2,
- '6A' => 12,
- '6B' => 16,
- '6C' => 2,
- );
- $return[0] = $cores{$family_id . $model_id} if $cores{$family_id . $model_id};
- if ($return[0]){
- $return[1] = ($count % $return[0]) ? int($count/$return[0]) + 1 : $count/$return[0];
+ my ($sys_caches,$caches,$id,$id_di) = @_;
+ my $cache_id = ($id_di) ? $id_di: $id;
+ my %cache_desc;
+ if ($sys_caches->{$cache_id}){
+ # print Data::Dumper::Dumper $cpu_sys->{'cpus'};
+ foreach (@{$sys_caches->{$cache_id}}){
+ # android seen to have cache data without size item
+ next if !defined $_;
+ $caches->{$cache_id} += $_;
+ $cache_desc{$_}++ if $b_admin;
+ }
+ $caches->{$id} += $caches->{$id_di} if $id_di;
+ $caches->{$cache_id . '-desc'} = cp_cache_desc(\%cache_desc) if $b_admin;
}
eval $end if $b_log;
- return @return;
}
-# only elbrus ID is actually used live
-sub cpu_vendor {
- eval $start if $b_log;
- my ($string) = @_;
- my ($vendor) = ('');
- $string = lc($string);
- if ($string =~ /intel/){
- $vendor = "intel"
+## CPU PROPERTIES TOOLS ##
+sub cp_cache_desc {
+ my ($cache_desc) = @_;
+ my ($desc,$sep) = ('','');
+ foreach (sort keys %{$cache_desc}){
+ $desc .= $sep . $cache_desc->{$_} . 'x' . main::get_size($_,'string');
+ $sep = ', ';
}
- elsif ($string =~ /amd/){
- $vendor = "amd"
- }
- # via
- elsif ($string =~ /centaur/){
- $vendor = "centaur"
+ undef %{$cache_desc};
+ return $desc;
+}
+# $caches passed by reference
+sub cp_cache_processor {
+ my ($cache,$count) = @_;
+ my $output;
+ if ($count > 1){
+ $output = $count . 'x ' . main::get_size($cache,'string');
+ $output .= ' (' . main::get_size($cache * $count,'string') . ')';
}
- elsif ($string =~ /e2k/){
- $vendor = "elbrus"
+ else {
+ $output = main::get_size($cache,'string');
}
- eval $end if $b_log;
- return $vendor;
+ # print "$cache :: $count :: $output\n";
+ return $output;
}
-sub get_boost_status {
+sub cp_caches_fallback {
eval $start if $b_log;
- my ($boost);
- my $path = '/sys/devices/system/cpu/cpufreq/boost';
- if (-r $path){
- $boost = main::reader($path,'',0);
- if (defined $boost && $boost =~ /^[01]$/){
- $boost = ($boost) ? 'enabled' : 'disabled';
- }
+ my ($counts,$cpu,$caches,$cache_check) = @_;
+ # L1 Cache
+ if ($cpu->{'l1-cache'}){
+ $caches->{'l1'} = $cpu->{'l1-cache'} * $counts->{'cores-multiplier'};
}
- eval $end if $b_log;
- return $boost;
-}
-sub system_cpu_name {
- eval $start if $b_log;
- my (%cpus,$compat,@working);
- if (@working = main::globber('/sys/firmware/devicetree/base/cpus/cpu@*/compatible')){
- foreach my $file (@working){
- $compat = main::reader($file,'',0);
- next if $compat =~ /timer/; # seen on android
- # these can have non printing ascii... why? As long as we only have the
- # splits for: null 00/start header 01/start text 02/end text 03
- $compat = (split(/\x01|\x02|\x03|\x00/, $compat))[0] if $compat;
- $compat = (split(/,\s*/, $compat))[-1] if $compat;
- $cpus{$compat} = ($cpus{$compat}) ? ++$cpus{$compat}: 1;
+ else {
+ if ($cpu->{'l1d-cache'}){
+ $caches->{'l1d-desc'} = $counts->{'cores-multiplier'} . 'x';
+ $caches->{'l1d-desc'} .= main::get_size($cpu->{'l1d-cache'},'string');
+ $caches->{'l1'} += $cpu->{'l1d-cache'} * $counts->{'cores-multiplier'};
+
+ }
+ if ($cpu->{'l1i-cache'}){
+ $caches->{'l1i-desc'} = $counts->{'cores-multiplier'} . 'x';
+ $caches->{'l1i-desc'} .= main::get_size($cpu->{'l1i-cache'},'string');
+ $caches->{'l1'} += $cpu->{'l1i-cache'} * $counts->{'cores-multiplier'};
+ }
+ }
+ # L2 Cache
+ # If summed by dmidecode or from cpu_sys don't use this
+ if ($cpu->{'l2-cache'}){
+ # the only possible change for bsds is if dmidecode method gives phy counts
+ # Looks like Intel on bsd shows L2 per core, not total. Note: Pentium N3540
+ # uses 2(not 4)xL2 cache size for 4 cores, sigh... you just can't win...
+ if ($bsd_type){
+ $caches->{'l2'} = $cpu->{'l2-cache'} * $counts->{'cores-multiplier'};
}
- }
- # synthesize it, [4] will be like: cortex-a15-timer; sunxi-timer
- # so far all with this directory show soc name, not cpu name for timer
- elsif (! -d '/sys/firmware/devicetree/base' && $devices{'timer'}){
- foreach my $working (@{$devices{'timer'}}){
- next if $working->[0] ne 'timer' || !$working->[4] || $working->[4] =~ /timer-mem$/;
- $working->[4] =~ s/(-system)?-timer$//;
- $compat = $working->[4];
- $cpus{$compat} = ($cpus{$compat}) ? ++$cpus{$compat}: 1;
+ # AMD SOS chips appear to report full L2 cache per cpu
+ elsif ($cpu->{'type'} eq 'amd' && ($cpu->{'family'} eq '14' ||
+ $cpu->{'family'} eq '15' || $cpu->{'family'} eq '16')){
+ $caches->{'l2'} = $cpu->{'l2-cache'};
+ }
+ elsif ($cpu->{'type'} ne 'intel'){
+ $caches->{'l2'} = $cpu->{'l2-cache'} * $counts->{'cpu-cores'};
+ }
+ # note: this handles how intel reports L2, total instead of per core like
+ # AMD does when cpuinfo sourced, when caches sourced, is per core as expected
+ else {
+ $caches->{'l2'} = $cpu->{'l2-cache'};
}
}
- main::log_data('dump','%cpus',\%cpus) if $b_log;
+ # l3 Cache - usually per physical cpu, but some rzyen will have per ccx.
+ if ($cpu->{'l3-cache'}){
+ $caches->{'l3'} = $cpu->{'l3-cache'};
+ }
+ # don't do anything with it, we have no ideaw if it's L1, L2, or L3, generic
+ # cpuinfo fallback, it's junk data essentially, and will show as cache:
+ # only use this fallback if no cache data was found
+ if ($cpu->{'cache'} && !$caches->{'l1'} && !$caches->{'l2'} &&
+ !$caches->{'l3'}){
+ $caches->{'cache'} = $cpu->{'cache'};
+ $$cache_check = main::message('note-check');
+ }
eval $end if $b_log;
- return %cpus;
}
-
-sub cpu_arch {
+sub cp_cpu_arch {
eval $start if $b_log;
my ($type,$family,$model,$stepping) = @_;
- $stepping = 0 if !main::is_numeric($stepping);
+ # we can get various random strings for rev/stepping, particularly for arm,ppc
+ # but we want stepping to be integer for math comparisons, so convert, or set
+ # to 0 so it won't break anything.
+ if (defined $stepping && $stepping =~ /^[A-F0-9]{1,3}$/i){
+ $stepping = hex($stepping);
+ }
+ else {
+ $stepping = 0
+ }
$family ||= '';
- $model ||= '';
+ $model = '' if !defined $model; # model can be 0
my ($arch,$note) = ('','');
- my $check = main::row_defaults('note-check');
+ my $check = main::message('note-check');
# See: docs/inxi-resources.txt
# print "type:$type fam:$family model:$model step:$stepping\n";
if ($type eq 'amd'){
@@ -9775,12 +10499,16 @@ sub cpu_arch {
$arch = 'Bobcat'}
}
elsif ($family eq '15'){
- if ($model =~ /^(0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F)$/){
+ # note: only model 1 confirmd
+ if ($model =~ /^(0|1|3|4|5|6|7|8|9|A|B|C|D|E|F)$/){
$arch = 'Bulldozer'}
- elsif ($model =~ /^(10|11|12|13|14|15|16|17|18|19|1A|1B|1C|1D|1E|1F)$/){
+ # note: only 2,11,13 confirmed
+ elsif ($model =~ /^(2|10|11|12|13|14|15|16|17|18|19|1A|1B|1C|1D|1E|1F)$/){
$arch = 'Piledriver'}
+ # note: only 30,38 confirmed
elsif ($model =~ /^(30|31|32|33|34|35|36|37|38|39|3A|3B|3C|3D|3E|3F)$/){
$arch = 'Steamroller'}
+ # note; only 60,65,70 confirmed
elsif ($model =~ /^(60|61|62|63|64|65|66|67|68|69|6A|6B|6C|6D|6E|6F|70|71|72|73|74|75|76|77|78|79|7A|7B|7C|7D|7E|7F)$/){
$arch = 'Excavator'}
else {
@@ -9796,9 +10524,12 @@ sub cpu_arch {
$arch = 'Jaguar'}
}
elsif ($family eq '17'){
- if ($model =~ /^(1|11|18|20)$/){
- $arch = 'Zen'}
+ # can't find stepping/model for no ht 2x2 core/die models, only first ones
+ if ($model =~ /^(1|11|20)$/){
+ $arch = 'Zen';
+ }
# Seen: stepping 1 is Zen+ Ryzen 7 3750H. But stepping 1 Zen is: Ryzen 3 3200U
+ # AMD Ryzen 3 3200G is stepping 1, Zen+
# Unknown if stepping 0 is Zen or either.
elsif ($model =~ /^(18)$/){
$arch = 'Zen/Zen+';
@@ -9806,14 +10537,17 @@ sub cpu_arch {
}
# shares model 8 with zen, stepping unknown
elsif ($model =~ /^(8)$/){
- $arch = 'Zen+'}
+ $arch = 'Zen+';
+ }
# used this but it didn't age well: ^(2[0123456789ABCDEF]|
elsif ($model =~ /^(31|47|60|68|71|90)$/){
- $arch = 'Zen 2'}
+ $arch = 'Zen 2';
+ }
else {
$arch = 'Zen';
$note = $check;}
}
+ # Joint venture between AMD and Chinese companies. Type amd? or hygon?
elsif ($family eq '18'){
# model 0
$arch = 'Zen (Hygon Dhyana)';
@@ -9822,10 +10556,10 @@ sub cpu_arch {
# model: 0 1 21 40 50
$arch = 'Zen 3';
}
- # note: family 20 may be Zen 4 but not known for sure yet
+ # note: family 20 may be Zen 4 but not known for sure yet, zen 5 also in pipeline
# elsif ($family eq '20'){
- # model: unknown
- # $arch = 'Zen 4';
+ # # model: unknown
+ # $arch = 'Zen 4';
# }
}
elsif ($type eq 'arm'){
@@ -9960,13 +10694,15 @@ sub cpu_arch {
elsif ($model =~ /^(15)$/){
$arch = 'M Tolapai'} # pentium M system on chip
elsif ($model =~ /^(17|1D)$/){
- $arch = 'Penryn'}
- elsif ($model =~ /^(1A|1E|1F|25|2C|2E|2F)$/){
+ $arch = 'Core Penryn'}
+ # had 25 also, but that's westmere, at least for stepping 2
+ elsif ($model =~ /^(1A|1E|1F|2C|2E|2F)$/){
$arch = 'Nehalem'}
elsif ($model =~ /^(1C|26)$/){
$arch = 'Bonnell'} # atom Bonnell? 27?
elsif ($model =~ /^(27|35|36)$/){
$arch = 'Saltwell'}
+ # 25 may be nahelem in a stepping, check. Stepping 2 is westmere
elsif ($model =~ /^(25|2C|2F)$/){
$arch = 'Westmere'}
elsif ($model =~ /^(2A|2D)$/){
@@ -10066,7 +10802,11 @@ sub cpu_arch {
elsif ($model =~ /^(3)$/){
$arch = 'Netburst Prescott'} # 6? Nocona
elsif ($model =~ /^(4)$/){
- $arch = 'Netburst Smithfield'} # 6? Nocona
+ if ($stepping == 1){
+ $arch = 'Netburst Prescott'}
+ else {
+ $arch = 'Netburst Smithfield'} # 6? Nocona
+ }
elsif ($model =~ /^(6)$/){
$arch = 'Netburst Presler'}
else {
@@ -10084,27 +10824,344 @@ sub cpu_arch {
}
}
eval $end if $b_log;
- return ($arch,$note);
+ return [$arch,$note];
}
-
-sub count_alpha {
- my ($count) = @_;
- # print "$count\n";
+sub cp_cpu_topology {
+ my ($counts,$topology) = @_;
my @alpha = qw(Single Dual Triple Quad);
- if ($count > 4){
- $count .= '-';
+ my ($sep) = ('');
+ my (%keys,%done);
+ my @tests = ('x'); # prefill [0] because iterator runs before 'next' test.
+ if ($counts->{'cpu-topo'}){
+ # first we want to find out how many of each physical variant there are
+ foreach my $topo (@{$counts->{'cpu-topo'}}){
+ # turn sorted hash into string
+ my $test = join('::', map{$_ . ':' . $topo->{$_}} sort keys %$topo);
+ if ($keys{$test}){
+ $keys{$test}++;
+ }
+ else {
+ $keys{$test} = 1;
+ }
+ push(@tests,$test);
+ }
+ my ($i,$j) = (0,0);
+ # then we build up the topology data per variant
+ foreach my $topo (@{$counts->{'cpu-topo'}}){
+ my $key = '';
+ $i++;
+ next if $done{$tests[$i]};
+ $done{$tests[$i]} = 1;
+ if ($b_admin && $type eq 'full'){
+ $topology->{'full'}[$j]{'cpus'} = $keys{$tests[$i]};
+ $topology->{'full'}[$j]{'cores'} = $topo->{'cores'};
+ if ($topo->{'threads'} && $topo->{'cores'} != $topo->{'threads'}){
+ $topology->{'full'}[$j]{'threads'} = $topo->{'threads'};
+ }
+ if ($topo->{'dies'} && $topo->{'dies'} > 1){
+ $topology->{'full'}[$j]{'dies'} = $topo->{'dies'};
+ }
+ if ($counts->{'struct-mt'}){
+ $topology->{'full'}[$j]{'cores-mt'} = $topo->{'cores-mt'};
+ }
+ if ($counts->{'struct-st'}){
+ $topology->{'full'}[$j]{'cores-st'} = $topo->{'cores-st'};
+ }
+ if ($counts->{'struct-max'} || $counts->{'struct-min'}){
+ $topology->{'full'}[$j]{'max'} = $topo->{'max'};
+ $topology->{'full'}[$j]{'min'} = $topo->{'min'};
+ }
+ if ($topo->{'smt'}){
+ $topology->{'full'}[$j]{'smt'} = $topo->{'smt'};
+ }
+ if ($topo->{'tpc'}){
+ $topology->{'full'}[$j]{'tpc'} = $topo->{'tpc'};
+ }
+ $j++;
+ }
+ else {
+ # start building string
+ $topology->{'string'} .= $sep;
+ $sep = ',';
+ if ($counts->{'physical'} > 1) {
+ my $phys = ($topology->{'struct-cores'}) ? $keys{$tests[$i]} : $counts->{'physical'};
+ $topology->{'string'} .= $phys . 'x ';
+ $topology->{'string'} .= $topo->{'cores'} . '-core';
+ }
+ else {
+ $topology->{'string'} .= cp_cpu_alpha($topo->{'cores'});
+ }
+ # alder lake type cpu
+ if ($topo->{'cores-st'} && $topo->{'cores-mt'}){
+ $topology->{'string'} .= ' (' . $topo->{'cores-mt'} . '-mt/';
+ $topology->{'string'} .= $topo->{'cores-st'} . '-st)';
+ }
+ # we only want to show > 1 phys short form basic if cpus have different
+ # core counts, not different min/max frequencies
+ last if !$topology->{'struct-cores'};
+ }
+ }
}
else {
- $count = $alpha[$count-1] . ' ' if $count > 0;
+ if ($counts->{'physical'} > 1) {
+ $topology->{'string'} = $counts->{'physical'} . 'x ';
+ $topology->{'string'} .= $counts->{'cpu-cores'} . '-core';
+ }
+ else {
+ $topology->{'string'} = cp_cpu_alpha($counts->{'cpu-cores'});
+ }
}
- return $count;
+ $topology->{'string'} ||= '';
+}
+sub cp_cpu_alpha {
+ my $cores = $_[0];
+ my $string = '';
+ if ($cores > 4){
+ $string = $cores . '-core';
+ }
+ elsif ($cores == 0){
+ $string = main::message('unknown-cpu-topology');
+ }
+ else {
+ my @alpha = qw(single dual triple quad);
+ $string = $alpha[$cores-1] . ' core';
+ }
+ return $string;
}
+# Logic:
+# if > 1 processor && processor id (physical id) == core id then Multi threaded (MT)
+# if siblings > 1 && siblings == 2 * num_of_cores ($cpu->{'cores'}) then Multi threaded (MT)
+# if > 1 processor && processor id (physical id) != core id then Multi-Core Processors (MCP)
+# if > 1 processor && processor ids (physical id) > 1 then Symmetric Multi Processing (SMP)
+# if = 1 processor then single core/processor Uni-Processor (UP)
+sub cp_cpu_type {
+ eval $start if $b_log;
+ my ($counts,$cpu,$tests) = @_;
+ my $cpu_type = '';
+ if ($counts->{'processors'} > 1 ||
+ (defined $tests->{'intel'} && $tests->{'intel'} && $cpu->{'siblings'} > 0)){
+ # cpu_sys detected MT
+ if ($counts->{'struct-mt'}){
+ if ($counts->{'struct-mt'} && $counts->{'struct-st'}){
+ $cpu_type .= 'MST';
+ }
+ else {
+ $cpu_type .= 'MT';
+ }
+ }
+ # handle case of OpenBSD that has hw.smt but no other meaningful topology
+ elsif ($cpu->{'smt'}){
+ $cpu_type .= 'MT' if $cpu->{'smt'} eq 'enabled';
+ }
+ # non-multicore MT, with 2 or more threads per core
+ elsif ($counts->{'processors'} && $counts->{'physical'} &&
+ $counts->{'cpu-cores'} &&
+ $counts->{'processors'}/($counts->{'physical'} * $counts->{'cpu-cores'}) >= 2){
+ # print "mt:1\n";
+ $cpu_type .= 'MT';
+ }
+ # 2 or more siblings per cpu real core
+ elsif ($cpu->{'siblings'} > 1 && $cpu->{'siblings'}/$counts->{'cpu-cores'} >= 2){
+ # print "mt:3\n";
+ $cpu_type .= 'MT';
+ }
+ # non-MT multi-core or MT multi-core
+ if ($counts->{'cpu-cores'} > 1){
+ if ($counts->{'struct-mt'} && $counts->{'struct-st'}){
+ $cpu_type .= ' AMCP';
+ }
+ else {
+ $cpu_type .= ' MCP';
+ }
+ }
+ # only solidly known > 1 die cpus will use this
+ if ($cpu->{'dies'} > 1){
+ $cpu_type .= ' MCM';
+ }
+ # >1 cpu sockets active: Symetric Multi Processing
+ if ($counts->{'physical'} > 1){
+ if ($counts->{'struct-cores'} || $counts->{'struct-max'} ||
+ $counts->{'struct-min'}){
+ $cpu_type .= ' AMP';
+ }
+ else {
+ $cpu_type .= ' SMP';
+ }
+ }
+ $cpu_type =~ s/^\s+//;
+ }
+ else {
+ $cpu_type = 'UP';
+ }
+ eval $end if $b_log;
+ return $cpu_type;
+}
+# needed because no physical_id in cpuinfo, but > 1 cpu systems exist
+# returns: 0 - per cpu cores; 1 - phys cpu count; 2 - override model defaul names
+sub cp_elbrus_data {
+ eval $start if $b_log;
+ my ($family_id,$model_id,$count,$arch) = @_;
+ # 0: cores
+ my @return = (0,1,$arch);
+ my %cores = (
+ # key=family id + model id
+ '41' => 1,
+ '42' => 1,
+ '43' => 4,
+ '44' => 2,
+ '46' => 1,
+ '47' => 8,
+ '48' => 1,
+ '49' => 8,
+ '59' => 8,
+ '4A' => 12,
+ '4B' => 16,
+ '4C' => 2,
+ '6A' => 12,
+ '6B' => 16,
+ '6C' => 2,
+ );
+ $return[0] = $cores{$family_id . $model_id} if $cores{$family_id . $model_id};
+ if ($return[0]){
+ $return[1] = ($count % $return[0]) ? int($count/$return[0]) + 1 : $count/$return[0];
+ }
+ eval $end if $b_log;
+ return @return;
+}
+sub cp_speed_data {
+ eval $start if $b_log;
+ my ($cpu,$cpu_sys) = @_;
+ my %info;
+ if (defined $cpu_sys->{'data'}){
+ if (defined $cpu_sys->{'data'}{'speeds'}{'min-freq'}){
+ $cpu->{'min-freq'} = $cpu_sys->{'data'}{'speeds'}{'min-freq'};
+ }
+ if (defined $cpu_sys->{'data'}{'speeds'}{'max-freq'}){
+ $cpu->{'max-freq'} = $cpu_sys->{'data'}{'speeds'}{'max-freq'};
+ }
+ if (defined $cpu_sys->{'data'}{'speeds'}{'all'}){
+ # only replace if we got actual speed values from cpufreq, or if no legacy
+ # sourced processors data. Handles fake syz core speeds for counts.
+ if ((grep {$_} @{$cpu_sys->{'data'}{'speeds'}{'all'}}) ||
+ !@{$cpu->{'processors'}}){
+ $cpu->{'processors'} = $cpu_sys->{'data'}{'speeds'}{'all'};
+ }
+ }
+ if (defined $cpu_sys->{'data'}{'cpufreq-boost'}){
+ $cpu->{'boost'} = $cpu_sys->{'data'}{'cpufreq-boost'};
+ }
+ }
+ if (defined $cpu->{'processors'}){
+ if (scalar @{$cpu->{'processors'}} > 1){
+ my ($agg,$high) = (0,0);
+ for (@{$cpu->{'processors'}}){
+ next if !$_; # bsds might have 0 or undef value, that's junk
+ $agg += $_;
+ $high = $_ if $_ > $high;
+ }
+ if ($agg){
+ $cpu->{'avg-freq'} = int($agg/scalar @{$cpu->{'processors'}});
+ $cpu->{'cur-freq'} = $high;
+ $info{'avg-speed-key'} = 'avg';
+ $info{'speed'} = $cpu->{'avg-freq'};
+ if ($high > $cpu->{'avg-freq'}){
+ $cpu->{'high-freq'} = $high;
+ $info{'high-speed-key'} = 'high';
+ }
+ }
+ }
+ elsif ($cpu->{'processors'}[0]) {
+ $cpu->{'cur-freq'} = $cpu->{'processors'}[0];
+ $info{'speed'} = $cpu->{'cur-freq'};
+ }
+ }
+ # BSDs generally will have processors count, but not per core speeds
+ if ($cpu->{'cur-freq'} && !$info{'speed'}){
+ $info{'speed'} = $cpu->{'cur-freq'};
+ }
+ # BSDs generally will have processors count, but not per core speeds
+ if ($cpu->{'min-freq'} && $cpu->{'max-freq'}){
+ $info{'min-max'} = "$cpu->{'min-freq'}/$cpu->{'max-freq'}";
+ $info{'min-max-key'} = "min/max";
+ }
+ elsif ($cpu->{'max-freq'}){
+ $info{'min-max'} = $cpu->{'max-freq'};
+ $info{'min-max-key'} = "max";
+ }
+ elsif ($cpu->{'min-freq'}){
+ $info{'min-max'} = $cpu->{'min-freq'};
+ $info{'min-max-key'} = "min";
+ }
+ if ($cpu->{'cur-freq'}){
+ if ($show{'short'}){
+ $info{'speed-key'} = 'speed';
+ }
+ elsif ($show{'cpu-basic'}){
+ $info{'speed-key'} = 'speed (MHz)';
+ }
+ else {
+ $info{'speed-key'} = 'Speed (MHz)';
+ }
+ }
+ eval $end if $b_log;
+ return \%info;
+}
+# update $tests by reference
+sub cp_test_types {
+ my ($cpu,$tests) = @_;
+ if ($cpu->{'type'} eq 'intel'){
+ $$tests{'intel'} = 1;
+ $$tests{'xeon'} = 1 if $cpu->{'model_name'} =~ /Xeon/i;
+ }
+ elsif ($cpu->{'type'} eq 'amd'){
+ if ($cpu->{'family'} && $cpu->{'family'} eq '17'){
+ $$tests{'amd-zen'} = 1;
+ if ($cpu->{'model_name'}){
+ if ($cpu->{'model_name'} =~ /Ryzen/i){
+ $$tests{'ryzen'} = 1;
+ }
+ elsif ($cpu->{'model_name'} =~ /EPYC/i){
+ $$tests{'epyc'} = 1;
+ }
+ }
+ }
+ }
+ elsif ($cpu->{'type'} eq 'elbrus'){
+ $$tests{'elbrus'} = 1;
+ }
+}
+
+## CPU UTILITIES ##
+# only elbrus ID is actually used live
+sub cpu_vendor {
+ eval $start if $b_log;
+ my ($string) = @_;
+ my ($vendor) = ('');
+ $string = lc($string);
+ if ($string =~ /intel/){
+ $vendor = "intel"
+ }
+ elsif ($string =~ /amd/){
+ $vendor = "amd"
+ }
+ # via
+ elsif ($string =~ /centaur/){
+ $vendor = "centaur"
+ }
+ elsif ($string =~ /(e2k|elbrus)/){
+ $vendor = "elbrus"
+ }
+ eval $end if $b_log;
+ return $vendor;
+}
+# do not define model-id, stepping, or revision, those can be 0 valid value
sub set_cpu_data {
my %cpu = (
'arch' => '',
+ 'avg-freq' => 0, # MHz
'bogomips' => 0,
'cores' => 0,
- 'cur-freq' => 0,
+ 'cur-freq' => 0, # MHz
'dies' => 0,
'family' => '',
'flags' => '',
@@ -10112,20 +11169,48 @@ sub set_cpu_data {
'l1-cache' => 0, # store in KB
'l2-cache' => 0, # store in KB
'l3-cache' => 0, # store in KB
- 'max-freq' => 0,
- 'min-freq' => 0,
- 'model_id' => undef,
+ 'max-freq' => 0, # MHz
+ 'min-freq' => 0, # MHz
'model_name' => '',
'processors' => [],
- 'rev' => '',
'scalings' => [],
'siblings' => 0,
'type' => '',
);
return %cpu;
}
+sub system_cpu_name {
+ eval $start if $b_log;
+ my (%cpus,$compat,@working);
+ if (@working = main::globber('/sys/firmware/devicetree/base/cpus/cpu@*/compatible')){
+ foreach my $file (@working){
+ $compat = main::reader($file,'',0);
+ next if $compat =~ /timer/; # seen on android
+ # these can have non printing ascii... why? As long as we only have the
+ # splits for: null 00/start header 01/start text 02/end text 03
+ $compat = (split(/\x01|\x02|\x03|\x00/, $compat))[0] if $compat;
+ $compat = (split(/,\s*/, $compat))[-1] if $compat;
+ $cpus{$compat} = ($cpus{$compat}) ? ++$cpus{$compat}: 1;
+ }
+ }
+ # synthesize it, [4] will be like: cortex-a15-timer; sunxi-timer
+ # so far all with this directory show soc name, not cpu name for timer
+ elsif (! -d '/sys/firmware/devicetree/base' && $devices{'timer'}){
+ foreach my $working (@{$devices{'timer'}}){
+ next if $working->[0] ne 'timer' || !$working->[4] || $working->[4] =~ /timer-mem$/;
+ $working->[4] =~ s/(-system)?-timer$//;
+ $compat = $working->[4];
+ $cpus{$compat} = ($cpus{$compat}) ? ++$cpus{$compat}: 1;
+ }
+ }
+ main::log_data('dump','%cpus',\%cpus) if $b_log;
+ eval $end if $b_log;
+ return \%cpus;
+}
+
+## CLEANERS/OUTPUT HANDLERS ##
# MHZ - cell cpus
-sub speed_cleaner {
+sub clean_speed {
my ($speed,$opt) = @_;
return if !$speed || $speed eq '0';
$speed =~ s/[GMK]HZ$//gi;
@@ -10133,7 +11218,7 @@ sub speed_cleaner {
$speed = sprintf("%.0f", $speed);
return $speed;
}
-sub cpu_cleaner {
+sub clean_cpu {
my ($cpu) = @_;
return if !$cpu;
my $filters = '@|cpu |cpu deca|([0-9]+|single|dual|two|triple|three|tri|quad|four|';
@@ -10148,7 +11233,11 @@ sub hex_and_decimal {
my ($data) = @_;
$data = '' if !defined $data;
if ($data =~ /\S/){
- $data .= ' (' . hex($data) . ')' if hex($data) ne $data;
+ # only handle if a short hex number!! No need to prepend 0x to 0-9
+ if ($data =~ /^[0-9a-f]{1,3}$/i && hex($data) ne $data){
+ $data .= ' (' . hex($data) . ')';
+ $data = '0x' . $data;
+ }
}
else {
$data = 'N/A';
@@ -10181,13 +11270,13 @@ sub get {
$key1 = 'Drive Report';
my $file = $system_files{'dmesg-boot'};
if ($file && ! -r $file){
- $val1 = main::row_defaults('dmesg-boot-permissions');
+ $val1 = main::message('dmesg-boot-permissions');
}
elsif (!$file){
- $val1 = main::row_defaults('dmesg-boot-missing');
+ $val1 = main::message('dmesg-boot-missing');
}
else {
- $val1 = main::row_defaults('disk-data-bsd');
+ $val1 = main::message('disk-data-bsd');
}
push(@rows,{main::key($num++,0,1,$key1) => $val1,});
}
@@ -10200,12 +11289,12 @@ sub get {
}
else {
$key1 = 'Message';
- $val1 = main::row_defaults('disk-data');
+ $val1 = main::message('disk-data');
@rows = ({main::key($num++,0,1,$key1) => $val1,});
}
if (!@rows){
$key1 = 'Message';
- $val1 = main::row_defaults('disk-data');
+ $val1 = main::message('disk-data');
@rows = ({main::key($num++,0,1,$key1) => $val1,});
}
# push(@rows,@data);
@@ -10327,14 +11416,14 @@ sub drive_output {
if ($extra > 1){
if (!$row->{'serial'} && $alerts{'bioctl'} &&
$alerts{'bioctl'}->{'action'} eq 'permissions'){
- $row->{'serial'} = main::row_defaults('root-required');
+ $row->{'serial'} = main::message('root-required');
}
else {
- $row->{'serial'} = main::apply_filter($row->{'serial'});
+ $row->{'serial'} = main::filter($row->{'serial'});
}
$rows[$j]->{main::key($num++,0,2,'serial')} = $row->{'serial'};
if ($row->{'drive-serial'}){
- $rows[$j]->{main::key($num++,0,2,'drive serial')} = main::apply_filter($row->{'drive-serial'});
+ $rows[$j]->{main::key($num++,0,2,'drive serial')} = main::filter($row->{'drive-serial'});
}
if ($row->{'firmware'}){
$rows[$j]->{main::key($num++,0,2,'rev')} = $row->{'firmware'};
@@ -10348,10 +11437,10 @@ sub drive_output {
}
if ($extra > 1 && $alerts{'bioctl'}){
if (!$row->{'duid'} && $alerts{'bioctl'}->{'action'} eq 'permissions'){
- $rows[$j]->{main::key($num++,0,2,'duid')} = main::row_defaults('root-required');
+ $rows[$j]->{main::key($num++,0,2,'duid')} = main::message('root-required');
}
elsif ($row->{'duid'}){
- $rows[$j]->{main::key($num++,0,2,'duid')} = main::apply_filter($row->{'duid'});
+ $rows[$j]->{main::key($num++,0,2,'duid')} = main::filter($row->{'duid'});
}
}
# extra level tests already done
@@ -10626,7 +11715,7 @@ sub proc_data_advanced {
}
# maybe rework logic if find good scsi data example, but for now use this
elsif ($drives->[$i]{'model'} && !$drives->[$i]{'vendor'}){
- $drives->[$i]{'model'} = main::disk_cleaner($drives->[$i]{'model'});
+ $drives->[$i]{'model'} = main::clean_disk($drives->[$i]{'model'});
my @device_data = device_vendor($drives->[$i]{'model'},'');
$drives->[$i]{'model'} = $device_data[1] if $device_data[1];
$drives->[$i]{'vendor'} = $device_data[0] if $device_data[0];
@@ -10701,10 +11790,10 @@ sub bsd_data {
DiskDataBSD::set() if !$loaded{'disk-data-bsd'};
# we don't want non dboot disk data from gpart or disklabel
if ($file && ! -r $file){
- $size = main::row_defaults('dmesg-boot-permissions');
+ $size = main::message('dmesg-boot-permissions');
}
elsif (!$file){
- $size = main::row_defaults('dmesg-boot-missing');
+ $size = main::message('dmesg-boot-missing');
}
elsif (%disks_bsd){
if ($sysctl{'softraid'}){
@@ -10752,7 +11841,7 @@ sub bsd_data {
$logical_size = ($size - $raw_logical[1] + $raw_logical[0]);
}
if (!$size){
- $size = main::row_defaults('data-bsd');
+ $size = main::message('data-bsd');
}
}
@data = ({
@@ -10884,20 +11973,20 @@ sub smartctl_data {
print 'Drive:/dev/' . $id . ":\n", Data::Dumper::Dumper\@result if $dbg[12];
if (scalar @result < 5){
if (grep {/failed: permission denied/i} @result){
- $data->[$i]{'smart-permissions'} = main::row_defaults('tool-permissions','smartctl');
+ $data->[$i]{'smart-permissions'} = main::message('tool-permissions','smartctl');
}
elsif (grep {/unknown usb bridge/i} @result){
- $data->[$i]{'smart-error'} = main::row_defaults('smartctl-usb');
+ $data->[$i]{'smart-error'} = main::message('smartctl-usb');
}
# can come later in output too
elsif (grep {/A mandatory SMART command failed/i} @result){
- $data->[$i]{'smart-error'} = main::row_defaults('smartctl-command');
+ $data->[$i]{'smart-error'} = main::message('smartctl-command');
}
elsif (grep {/open device.*Operation not supported by device/i} @result){
- $data->[$i]{'smart-error'} = main::row_defaults('smartctl-open');
+ $data->[$i]{'smart-error'} = main::message('smartctl-open');
}
else {
- $data->[$i]{'smart-error'} = main::row_defaults('tool-unknown-error','smartctl');
+ $data->[$i]{'smart-error'} = main::message('tool-unknown-error','smartctl');
}
next;
}
@@ -10921,7 +12010,7 @@ sub smartctl_data {
}
# can occur later in output so retest it here
if ($split[$a] =~ /A mandatory SMART command failed/i){
- $data->[$i]{'smart-error'} = main::row_defaults('smartctl-command');
+ $data->[$i]{'smart-error'} = main::message('smartctl-command');
}
## DEVICE INFO ##
if ($split[$a] eq 'Device Model'){
@@ -11137,7 +12226,7 @@ sub smartctl_data {
elsif ($split[$a] eq 'UDMA_CRC_Error_Count'){
if (main::is_numeric($split[$r]) && $split[$r] > 50){
$data->[$i]{'smart-udma-crc-errors-ar'} = $split[$r];
- $data->[$i]{'smart-udma-crc-errors-f'} = main::row_defaults('smartctl-udma-crc') if $split[$r] > 500;
+ $data->[$i]{'smart-udma-crc-errors-f'} = main::message('smartctl-udma-crc') if $split[$r] > 500;
}
}
@@ -11401,7 +12490,7 @@ sub disk_data_by_id {
$model = join(' ', @data);
# get rid of the ata-|nvme-|mmc- etc
$model =~ s/^\/dev\/disk\/by-id\/([^-]+-)?//;
- $model = main::disk_cleaner($model);
+ $model = main::clean_disk($model);
@device_data = device_vendor($model,$serial);
$vendor = $device_data[0] if $device_data[0];
$model = $device_data[1] if $device_data[1];
@@ -11422,14 +12511,14 @@ sub set_vendors {
# H10 HBRPEKNX0202A NVMe INTEL 512GB
['(\bINTEL\b|^SSD(PAM|SA2))','\bINTEL\b','Intel',''],
# note: S[AV][1-9][0-9] can trigger false positives
- ['(KINGSTON|DataTraveler|DT\s?(DUO|Microduo|101)|^RBU|^SMS|^SHS|^SS0|^SUV|^T52|^T[AB]29|^Ultimate CF|HyperX|^S[AV][1234]00|^SKYMEDI|13fe\b)','KINGSTON','Kingston',''], # maybe SHS: SHSS37A SKC SUV
+ ['(K(ING)?STON|DataTraveler|DT\s?(DUO|Microduo|101)|^RBU|^SMS|^SHS|^SS0|^SUV|^T52|^T[AB]29|^Ultimate CF|HyperX|^S[AV][1234]00|^SKYMEDI|13fe\b)','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|^MCBOE|\bEVO\b|^[GS]2 Portable|^DS20|^[DG]3 Station|^DUO\b|^P3|^[BC]GN|^[CD]JN|^BJ[NT]|^[BC]WB|^(HM|SP)[0-9]{2}|^MZMPC|^HD[0-9]{3}[A-Z]{2}$|^G[CD][1-9][QS]|^M[AB]G[0-9][FG]|SV[0-9]|[BE][A-Z][1-9]QT|YP\b)','SAMSUNG','Samsung',''], # maybe ^SM, ^HM
+ ['(SAMSUNG|^MCG[0-9]+GC|^CKT|^DUT|^MCC|^MCBOE|\bEVO\b|^[GS]2 Portable|^DS20|^[DG]3 Station|^DUO\b|^P3|^[BC]GN|^[CD]JN|^BJ[NT]|^[BC]WB|^(HM|SP)[0-9]{2}|^MZMPC|^HD[0-9]{3}[A-Z]{2}$|^G[CD][1-9][QS]|^M[AB]G[0-9][FG]|SV[0-9]|[BE][A-Z][1-9]QT|YP\b)','SAMSUNG','Samsung',''], # maybe ^SM, ^HM
# Android UMS Composite?
- ['(SanDisk|^SDS[S]?[DQ]|^D[AB]4|^SL([0-9]+)G|^AFGCE|^ABLCD|^SDW[1-9]|^SEM[1-9]|^U3\b|^SU[0-9]|^DX[1-9]|^S[CD][0-9]{2}G|ULTRA\s(FIT|trek)|Clip Sport|Cruzer|^Extreme|iXpand|SSD (Plus|U100) [1-9])','SanDisk','SanDisk',''],
+ ['(SanDisk|^SDS[S]?[DQ]|^D[AB]4|^SL([0-9]+)G|^AFGCE|^ABLCD|^SDW[1-9]|^SEM[1-9]|^U3\b|^SU[0-9]|^DX[1-9]|^S[CD][0-9]{2}G|ULTRA\s(FIT|trek)|Clip Sport|Cruzer|^Extreme|iXpand|SSD (Plus|U100) [1-9]|0781)','(SanDisk|0781)','SanDisk',''],
# these are HP/Sandisk cobranded. DX110064A5xnNMRI ids as HP and Sandisc
['(^DX[1-9])','^(HP\b|SANDDISK)','Sandisk/HP',''], # ssd drive, must come before seagate ST test
# real, SSEAGATE Backup+; XP1600HE30002 | 024 HN (spinpoint) ; possible usb: 24AS
@@ -11439,6 +12528,7 @@ sub set_vendors {
# rare cases WDC is in middle of string
['(\bWDC\b|1002FAEX)','','Western Digital',''],
## THEN BETTER KNOWN ONESs ##
+ ['^Acer','^Acer','Acer',''],
# A-Data can be in middle of string
['^(.*\bA-?DATA|ASP[0-9]|AX[MN]|CH11|HV[1-9]|IM2|HD[1-9]|HDD\s?CH|IUM)','A-?DATA','A-Data',''],
['^(ASUS|ROG)','^ASUS','ASUS',''], # ROG ESD-S1C
@@ -11463,10 +12553,11 @@ sub set_vendors {
['^(PNY|Hook\s?Attache|SSD2SC|(SSD7?)?EP7)','^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[GKQ][0-9]|KBG4|^HDW|^SA[0-9]{2}G$|^(008|016|032|064|128)G[379E][0-9A]$)','[S]?TOSHIBA','Toshiba',''], # scsi-STOSHIBA_STOR.E_EDITION_
+ ['(^[S]?TOS|^THN|TOSHIBA|TransMemory|^M[GKQ][0-9]|KBG4|^HDW|^SA[0-9]{2}G$|^(008|016|032|064|128)G[379E][0-9A]$|0930)','[S]?(TOSHIBA|0930)','Toshiba',''], # scsi-STOSHIBA_STOR.E_EDITION_
## LAST: 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
+ ['^(Alcor(\s?Micro)?|058F)','^(Alcor(\s?Micro)?|058F)','Alcor Micro',''],
['^2[\s-]?Power','^2[\s-]?Power','2-Power',''],
['^(3ware|9650SE)','^3ware','3ware (controller)',''],
['^5ACE','^5ACE','5ACE',''], # could be seagate: ST316021 5ACE
@@ -11474,7 +12565,7 @@ sub set_vendors {
['^(AbonMax|ASU[0-9])','^AbonMax','AbonMax',''],
['^Acasis','^Acasis','Acasis (hub)',''],
['^Acclamator','^Acclamator','Acclamator',''],
- ['^(Actions|HS USB Flash)','^Actions','Actions',''],
+ ['^(Actions|HS USB Flash|10d6)','^(Actions|10d6)','Actions',''],
['^Addlink','^Addlink','Addlink',''],
['^(ADplus|SuperVer\b)','^ADplus','ADplus',''],
['^ADTRON','^ADTRON','Adtron',''],
@@ -11507,6 +12598,7 @@ sub set_vendors {
['^BIOSTAR','^BIOSTAR','Biostar',''],
['^BIWIN','^BIWIN','BIWIN',''],
['^Blackpcs','^Blackpcs','Blackpcs',''],
+ ['^(BlueRay|SDM[0-9])','^BlueRay','BlueRay',''],
['^Bory','^Bory','Bory',''],
['^Braveeagle','^Braveeagle','BraveEagle',''],
['^(BUFFALO|BSC)','^BUFFALO','Buffalo',''], # usb: BSCR05TU2
@@ -11531,6 +12623,7 @@ sub set_vendors {
['^DATABAR','^DATABAR','DataBar',''],
# Daplink vfs is an ARM software thing
['^Dataram','^Dataram','Dataram',''],
+ ['^DELAIHE','^DELAIHE','DELAIHE',''],
# DataStation can be Trekstore or I/O gear
['^Dell\b','^Dell','Dell',''],
['^DeLOCK','^Delock(\s?products)?','Delock',''],
@@ -11546,7 +12639,7 @@ sub set_vendors {
['^(Dogfish|Shark)','^Dogfish(\s*Technology)?','Dogfish Technology',''],
['^DragonDiamond','^DragonDiamond','DragonDiamond',''],
['^DREVO\b','^DREVO','Drevo',''],
- ['^DREVO\b','^DREVO','Drevo',''],
+ ['^DSS','^DSS DAHUA','DSS DAHUA',''],
['^(Dynabook|AE[1-3]00)','^Dynabook','Dynabook',''],
# DX1100 is probably sandisk, but could be HP, or it could be hp branded sandisk
['^(Eaget|V8$)','^Eaget','Eaget',''],
@@ -11563,8 +12656,10 @@ sub set_vendors {
['^EURS','^EURS','EURS',''],
# NOTE: ESA3... may be IBM PCIe SAD card/drives
['^(EXCELSTOR|r technology)','^EXCELSTOR( TECHNO(LOGY)?)?','ExcelStor',''],
+ ['^EYOTA','^EYOTA','EYOTA',''],
['^EZLINK','^EZLINK','EZLINK',''],
['^Fantom','^Fantom( Drive[s]?)?','Fantom Drives',''],
+ ['^Fanxiang','^Fanxiang','Fanxiang',''],
['^Faspeed','^Faspeed','Faspeed',''],
['^FASTDISK','^FASTDISK','FASTDISK',''],
['^Festtive','^Festtive','Festtive',''],
@@ -11580,12 +12675,14 @@ sub set_vendors {
['^Geil','^Geil','Geil',''],
['^GelL','^GelL','GelL',''], # typo for Geil? GelL ZENITH R3 120GB
['^(Generic|UY[67])','^Generic','Generic',''],
+ ['^(Genesis(\s?Logic)?|05e3)','(Genesis(\s?Logic)?|05e3)','Genesis Logic',''],
['^Geonix','^Geonix','Geonix',''],
['^Getrich','^Getrich','Getrich',''],
['^Gigabyte','^Gigabyte','Gigabyte',''], # SSD
['^Gigastone','^Gigastone','Gigastone',''],
['^Gigaware','^Gigaware','Gigaware',''],
['^Gloway','^Gloway','Gloway',''],
+ ['^GLOWY','^GLOWY','Glowy',''],
['^Goldendisk','^Goldendisk','Goldendisk',''],
['^Goldenfir','^Goldenfir','Goldenfir',''],
# Wilk Elektronik SA, poland
@@ -11617,7 +12714,7 @@ sub set_vendors {
['^(Initio)','^Initio','Initio',''],
['^Inland','^Inland','Inland',''],
['^(InnoDisk|Innolite|SATA\s?Slim)','^InnoDisk( Corp.)?','InnoDisk',''],
- ['Innostor','Innostor','Innostor',''],
+ ['(Innostor|1f75)','(Innostor|1f75)','Innostor',''],
['(^Innovation|Innovation\s?IT)','Innovation(\s*IT)?','Innovation IT',''],
['^Innovera','^Innovera','Innovera',''],
['^Intaiel','^Intaiel','Intaiel',''],
@@ -11659,12 +12756,13 @@ sub set_vendors {
# LENSE30512GMSP34MEAT3TA / UMIS RPITJ256PED2MWX
['^(LEN|UMIS)','^Lenovo','Lenovo',''],
['^RPFT','','Lenovo O.E.M.',''],
- # JAJS300M120C JAJM600M256C JAJS600M1024C JAJS600M256C
- ['^(Leven|JAJ[MS][1-9])','^Leven','Leven',''],
+ # JAJS300M120C JAJM600M256C JAJS600M1024C JAJS600M256C JAJMS600M128G
+ ['^(Leven|JAJ[MS])','^Leven','Leven',''],
['^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; CL1-3D256-Q11 NVMe LITEON 256GB
['^LONDISK','^LONDISK','LONDISK',''],
+ ['^Longline','^Longline','Longline',''],
['^(LSI|MegaRAID)','^LSI\b','LSI',''],
['^(M-Systems|DiskOnKey)','^M-Systems','M-Systems',''],
['^(Mach\s*Xtreme|MXSSD|MXU|MX[\s-])','^Mach\s*Xtreme','Mach Xtreme',''],
@@ -11686,9 +12784,11 @@ sub set_vendors {
['^MGTEC','^MGTEC','MGTEC',''],
['^(Microsoft|S31)','^Microsoft','Microsoft',''],
['^MidasForce','^MidasForce','MidasForce',''],
+ ['^Milan','^Milan','Milan',''],
['^(Mimoco|Mimobot)','^Mimoco','Mimoco',''],
['^MINIX','^MINIX','MINIX',''],
['^Miracle','^Miracle','Miracle',''],
+ ['^MLLSE','^MLLSE','MLLSE',''],
['^Moba','^Moba','Moba',''],
# Monster MONSTER DIGITAL
['^(Monster\s)+(Digital)?|OD[\s-]?ADVANCE','^(Monster\s)+(Digital)?','Monster Digital',''],
@@ -11750,7 +12850,7 @@ sub set_vendors {
['^(Sea\s?Tech|Transformer)','^Sea\s?Tech','Sea Tech',''],
['^SigmaTel','^SigmaTel','SigmaTel',''],
# DIAMOND_040_GB
- ['^(SILICON\s?MOTION|SM[0-9])','^SILICON\s?MOTION','Silicon Motion',''],
+ ['^(SILICON\s?MOTION|SM[0-9]|090c)','^(SILICON\s?MOTION|090c)','Silicon Motion',''],
['(Silicon[\s-]?Power|^SP[CP]C|^Silicon|^Diamond|^HasTopSunlightpeed)','Silicon[\s-]?Power','Silicon Power',''],
['^SINTECHI?','^SINTECHI?','SinTech (adapter)',''],
['^SiS\b','^SiS','SiS',''],
@@ -11795,11 +12895,13 @@ sub set_vendors {
['^TopSunligt','^TopSunligt','TopSunligt',''], # is this a typo? hard to know
['^TopSunlight','^TopSunlight','TopSunlight',''],
['^TOROSUS','^TOROSUS','Torosus',''],
- ['^([F]?TS|Transcend|JetDrive|JetFlash|USDU|EZEX)','^Transcend','Transcend',''],
+ ['^([F]?TS|Transcend|JetDrive|JetFlash|USDU|EZEX|1307)','^(Transcend|1307)','Transcend',''],
['^(TrekStor|DS (maxi|pocket)|DataStation)','^TrekStor','TrekStor',''],
+ ['^Turbox','^Turbox','Turbox',''],
['^(TwinMOS|TW[0-9])','^TwinMOS','TwinMOS',''],
# note: udisk means usb disk, it's not a vendor ID
['^UDinfo','^UDinfo','UDinfo',''],
+ ['^UMAX','^UMAX','UMAX',''],
['^USBTech','^USBTech','USBTech',''],
['^(UNIC2)','^UNIC2','UNIC2',''],
['^(UG|Unigen)','^Unigen','Unigen',''],
@@ -12072,7 +13174,7 @@ sub device_speed {
else {
$working = "/sys/class/ata_link/link$id/sata_spd";
$speed = main::reader($working,'',0) if -r $working;
- $speed = main::disk_cleaner($speed) if $speed;
+ $speed = main::clean_disk($speed) if $speed;
$speed =~ s/Gbps/Gb\/s/ if $speed;
}
}
@@ -12093,11 +13195,10 @@ sub get {
eval $start if $b_log;
my (@rows);
my $num = 0;
- if (($b_arm || $b_mips) && !$use{'soc-gfx'} && !$use{'pci-tool'}){
- my $type = ($b_arm) ? 'arm' : 'mips';
+ if (%risc && !$use{'soc-gfx'} && !$use{'pci-tool'}){
my $key = 'Message';
push(@rows, {
- main::key($num++,0,1,$key) => main::row_defaults($type . '-pci',''),
+ main::key($num++,0,1,$key) => main::message('risc-pci',$risc{'id'}),
},);
}
else {
@@ -12109,7 +13210,7 @@ sub get {
$type = 'pci-card-data-root';
}
push(@rows, {
- main::key($num++,0,1,$key) => main::row_defaults($type,''),
+ main::key($num++,0,1,$key) => main::message($type,''),
},);
}
}
@@ -12140,10 +13241,10 @@ sub device_output {
$driver = $row->[9];
$driver ||= 'N/A';
my $device = main::trimmer($row->[4]);
- $device = ($device) ? main::pci_cleaner($device,'output') : 'N/A';
+ $device = ($device) ? main::clean_pci($device,'output') : 'N/A';
# have seen absurdly verbose card descriptions, with non related data etc
- if (length($device) > 85 || $size{'max'} < 110){
- $device = main::pci_long_filter($device);
+ if (length($device) > 85 || $size{'max-cols'} < 110){
+ $device = main::filter_pci_long($device);
}
push(@rows, {
main::key($num++,1,1,'Device') => $device,
@@ -12188,7 +13289,7 @@ sub usb_output {
$j = scalar @rows;
# make sure to reset, or second device trips last flag
($driver,$path_id,$product) = ('','','');
- $product = main::cleaner($row->[13]) if $row->[13];
+ $product = main::clean($row->[13]) if $row->[13];
$driver = $row->[15] if $row->[15];
$path_id = $row->[2] if $row->[2];
$product ||= 'N/A';
@@ -12217,7 +13318,7 @@ sub usb_output {
$rows[$j]->{main::key($num++,0,2,'class-ID')} = "$row->[4]$row->[5]";
}
if ($extra > 2 && $row->[16]){
- $rows[$j]->{main::key($num++,0,2,'serial')} = main::apply_filter($row->[16]);
+ $rows[$j]->{main::key($num++,0,2,'serial')} = main::filter($row->[16]);
}
}
eval $end if $b_log;
@@ -12270,7 +13371,7 @@ sub display_output(){
}
my @drivers = x_drivers();
if (!$protocol && !$server_string && !$graphics{'x-vendor'} && !@drivers){
- $server_string = main::row_defaults('display-server');
+ $server_string = main::message('display-server');
@row = ({
main::key($num++,1,1,'Display') => '',
main::key($num++,0,2,'server') => $server_string,
@@ -12298,14 +13399,14 @@ sub display_output(){
# $driver comes from the Device lines, and is just last fallback.
if ($driver && $driver ne 'N/A'){
if (-e '/var/lib/gdm' && !$b_root){
- $driver_missing = main::row_defaults('display-driver-na') . ' - ' . main::row_defaults('root-suggested');
+ $driver_missing = main::message('display-driver-na') . ' - ' . main::message('root-suggested');
}
else {
- $driver_missing = main::row_defaults('display-driver-na');
+ $driver_missing = main::message('display-driver-na');
}
}
else {
- $driver_missing = main::row_defaults('root-suggested') if -e '/var/lib/gdm' && !$b_root;
+ $driver_missing = main::message('root-suggested') if -e '/var/lib/gdm' && !$b_root;
}
}
else {
@@ -12610,7 +13711,7 @@ sub display_data_x {
}
}
else {
- $graphics{'no-xdpyinfo'} = main::row_defaults('tool-missing-basic','xdpyinfo');
+ $graphics{'no-xdpyinfo'} = main::message('tool-missing-basic','xdpyinfo');
}
print 'last: ', Data::Dumper::Dumper $graphics{'screens'} if $dbg[17];
main::log_data('dump','$graphics{screens}',$graphics{'screens'}) if $b_log;
@@ -12692,7 +13793,7 @@ sub gl_output(){
$type = 'display-null';
}
@row = ({
- main::key($num++,0,1,'Message') => main::row_defaults($type),
+ main::key($num++,0,1,'Message') => main::message($type),
});
return @row;
}
@@ -12705,7 +13806,7 @@ sub gl_output(){
if (/^opengl renderer/i){
@working = split(/:\s*/, $_, 2);
if ($working[1]){
- $working[1] = main::cleaner($working[1]);
+ $working[1] = main::clean($working[1]);
# Allow all mesas
# if ($working[1] =~ /mesa/i){
#
@@ -12715,7 +13816,7 @@ sub gl_output(){
# field value occurs.
else {
$b_nogl = 1;
- $working[1] = main::row_defaults('gl-empty');
+ $working[1] = main::message('gl-empty');
}
push(@renderer, $working[1]);
}
@@ -12737,7 +13838,7 @@ sub gl_output(){
$compat_version = $working[0];
}
elsif (!$b_nogl){
- push(@opengl_version, main::row_defaults('gl-empty'));
+ push(@opengl_version, main::message('gl-empty'));
}
}
elsif (/^opengl core profile version/i){
@@ -12788,7 +13889,7 @@ sub gl_output(){
}
else {
@row = ({
- main::key($num++,0,1,'Message') => main::row_defaults('glxinfo-missing'),
+ main::key($num++,0,1,'Message') => main::message('glxinfo-missing'),
});
}
}
@@ -12806,7 +13907,7 @@ sub gl_output(){
}
}
@row = ({
- main::key($num++,0,1,'Message') => main::row_defaults($type),
+ main::key($num++,0,1,'Message') => main::message($type),
});
}
eval $end if $b_log;
@@ -13058,7 +14159,7 @@ sub get {
my $num = 0;
if ($bsd_type){
$key1 = 'Message';
- $val1 = main::row_defaults('logical-data-bsd',$uname[0]);
+ $val1 = main::message('logical-data-bsd',$uname[0]);
@rows = ({main::key($num++,0,1,$key1) => $val1,});
}
else {
@@ -13068,7 +14169,7 @@ sub get {
if (!@lvm){
my $key = 'Message';
# note: arch linux has a bug where lvs returns 0 if non root start
- my $message = ($use{'logical-lvm'}) ? main::row_defaults('tool-permissions','lvs') : main::row_defaults('logical-data','');
+ my $message = ($use{'logical-lvm'}) ? main::message('tool-permissions','lvs') : main::message('logical-data','');
push(@rows, {
main::key($num++,0,1,$key) => $message,
},);
@@ -13088,7 +14189,7 @@ sub get {
$alerts{'lvs'}->{'action'} eq 'missing')){
my $key = 'Message';
push(@rows, {
- main::key($num++,0,1,$key) => main::row_defaults('logical-data',''),
+ main::key($num++,0,1,$key) => main::message('logical-data',''),
},);
}
elsif ($alerts{'lvs'}->{'action'} ne 'use'){
@@ -13425,7 +14526,7 @@ sub get {
}
elsif (!$key1){
$key1 = 'Message';
- $val1 = main::row_defaults('machine-data-force-dmidecode','');
+ $val1 = main::message('machine-data-force-dmidecode','');
}
}
elsif ($bsd_type || $force{'dmidecode'}){
@@ -13441,7 +14542,7 @@ sub get {
}
elsif (!$key1){
$key1 = 'Message';
- $val1 = main::row_defaults('machine-data');
+ $val1 = main::message('machine-data');
}
}
}
@@ -13453,22 +14554,22 @@ sub get {
else {
$key1 = 'Message';
if ($alerts{'dmidecode'}->{'action'} eq 'missing'){
- $val1 = main::row_defaults('machine-data-dmidecode');
+ $val1 = main::message('machine-data-dmidecode');
}
else {
- $val1 = main::row_defaults('machine-data');
+ $val1 = main::message('machine-data');
}
}
}
elsif (!$bsd_type){
# this uses /proc/cpuinfo so only GNU/Linux
- if ($b_arm || $b_mips || $b_ppc){
+ if (%risc){
%data = machine_data_soc();
@rows = machine_soc_output(\%data) if %data;
}
if (!%data){
$key1 = 'Message';
- $val1 = main::row_defaults('machine-data-force-dmidecode','');
+ $val1 = main::message('machine-data-force-dmidecode','');
}
}
# if error case, null data, whatever
@@ -13527,14 +14628,14 @@ sub machine_output {
},);
if (!$b_skip_system){
# this has already been tested for above so we know it's not null
- $system_vendor = main::cleaner($data->{'sys_vendor'});
+ $system_vendor = main::clean($data->{'sys_vendor'});
$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'});
+ $product_serial = main::filter($data->{'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;
+ $rows[$j]->{main::key($num++,1,2,'product')} = $product_name;
+ $rows[$j]->{main::key($num++,0,3,'v')} = $product_version;
+ $rows[$j]->{main::key($num++,0,3,'serial')} = $product_serial;
# no point in showing chassis if system isn't there, it's very unlikely that
# would be correct
if ($extra > 1){
@@ -13554,7 +14655,7 @@ sub machine_output {
$chassis_version = $data->{'chassis_version'};
$chassis_version =~ s/^v([0-9])/$1/i;
}
- $chassis_serial = main::apply_filter($data->{'chassis_serial'});
+ $chassis_serial = main::filter($data->{'chassis_serial'});
$chassis_vendor ||= '';
$chassis_type ||= '';
$rows[$j]->{main::key($num++,1,1,'Chassis')} = $chassis_vendor;
@@ -13572,11 +14673,11 @@ sub machine_output {
if ($data->{'firmware'}){
$firmware = $data->{'firmware'};
}
- $mobo_vendor = ($data->{'board_vendor'}) ? main::cleaner($data->{'board_vendor'}) : 'N/A';
+ $mobo_vendor = ($data->{'board_vendor'}) ? main::clean($data->{'board_vendor'}) : 'N/A';
$mobo_model = ($data->{'board_name'}) ? $data->{'board_name'}: 'N/A';
$mobo_version = ($data->{'board_version'})? $data->{'board_version'} : '';
- $mobo_serial = main::apply_filter($data->{'board_serial'});
- $bios_vendor = ($data->{'bios_vendor'}) ? main::cleaner($data->{'bios_vendor'}) : 'N/A';
+ $mobo_serial = main::filter($data->{'board_serial'});
+ $bios_vendor = ($data->{'bios_vendor'}) ? main::clean($data->{'bios_vendor'}) : 'N/A';
if ($data->{'bios_version'}){
$bios_version = $data->{'bios_version'};
$bios_version =~ s/^v([0-9])/$1/i;
@@ -13593,13 +14694,13 @@ sub machine_output {
$bios_romsize = $data->{'bios_romsize'};
}
$rows[$j]->{main::key($num++,1,1,'Mobo')} = $mobo_vendor;
- $rows[$j]->{main::key($num++,0,2,'model')} = $mobo_model;
+ $rows[$j]->{main::key($num++,1,2,'model')} = $mobo_model;
if ($mobo_version){
- $rows[$j]->{main::key($num++,0,2,'v')} = $mobo_version;
+ $rows[$j]->{main::key($num++,0,3,'v')} = $mobo_version;
}
- $rows[$j]->{main::key($num++,0,2,'serial')} = $mobo_serial;
+ $rows[$j]->{main::key($num++,0,3,'serial')} = $mobo_serial;
if ($extra > 2 && $data->{'board_uuid'}){
- $rows[$j]->{main::key($num++,0,2,'uuid')} = $data->{'board_uuid'};
+ $rows[$j]->{main::key($num++,0,3,'uuid')} = $data->{'board_uuid'};
}
$rows[$j]->{main::key($num++,1,1,$firmware)} = $bios_vendor;
$rows[$j]->{main::key($num++,0,2,'v')} = $bios_version;
@@ -13621,10 +14722,7 @@ sub machine_soc_output {
# 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
if ($soc_machine->{'device'} || $soc_machine->{'model'}){
- if ($b_arm){$key = 'ARM Device'}
- elsif ($b_mips){$key = 'MIPS Device'}
- elsif ($b_ppc){$key = 'PowerPC Device'}
- $rows[$j]->{main::key($num++,0,1,'Type')} = $key;
+ $rows[$j]->{main::key($num++,0,1,'Type')} = uc($risc{'id'});
my $system = 'System';
if (defined $soc_machine->{'model'}){
$rows[$j]->{main::key($num++,1,1,'System')} = $soc_machine->{'model'};
@@ -13634,6 +14732,9 @@ sub machine_soc_output {
$soc_machine->{'device'} ||= 'N/A';
$rows[$j]->{main::key($num++,$cont_sys,$ind_sys,$system)} = $soc_machine->{'device'};
}
+ if ($soc_machine->{'mobo'}){
+ $rows[$j]->{main::key($num++,1,1,'mobo')} = $soc_machine->{'mobo'};
+ }
# 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
@@ -13645,7 +14746,7 @@ sub machine_soc_output {
if (defined $soc_machine->{'serial'}){
# most samples I've seen are like: 0000
$soc_machine->{'serial'} =~ s/^[0]+$//;
- $rows[$j]->{main::key($num++,0,2,'serial')} = main::apply_filter($soc_machine->{'serial'});
+ $rows[$j]->{main::key($num++,0,2,'serial')} = main::filter($soc_machine->{'serial'});
}
eval $end if $b_log;
return @rows;
@@ -13683,10 +14784,10 @@ sub machine_data_sys {
$path = "$sys_dir$_";
if (-r $path){
$data{$_} = main::reader($path,'',0);
- $data{$_} = ($data{$_}) ? main::dmi_cleaner($data{$_}) : '';
+ $data{$_} = ($data{$_}) ? main::clean_dmi($data{$_}) : '';
}
elsif (!$b_root && -e $path && !-r $path){
- $data{$_} = main::row_defaults('root-required');
+ $data{$_} = main::message('root-required');
}
else {
$data{$_} = '';
@@ -13701,10 +14802,10 @@ sub machine_data_sys {
$data{'device'} = get_device_sys($data{'chassis_type'});
}
}
-# print "sys:\n";
-# foreach (keys %data){
-# print "$_: $data{$_}\n";
-# }
+ # print "sys:\n";
+ # foreach (keys %data){
+ # print "$_: $data{$_}\n";
+ # }
print Data::Dumper::Dumper \%data if $dbg[28];
main::log_data('dump','%data',\%data) if $b_log;
eval $end if $b_log;
@@ -13716,31 +14817,34 @@ sub machine_data_sys {
# certain actions for arm only.
sub machine_data_soc {
eval $end if $b_log;
- my (%data,@temp);
+ my (%data);
if (my $file = $system_files{'proc-cpuinfo'}){
- # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/cpu/arm/arm-shevaplug-1.2ghz.txt";
- my @data = main::reader($file);
- foreach (@data){
- if (/^(Hardware|machine)\s*:/i){
- @temp = split(/\s*:\s*/, $_, 2);
- $temp[1] = main::arm_cleaner($temp[1]);
- $temp[1] = main::dmi_cleaner($temp[1]);
- $data{'device'} = main::cleaner($temp[1]);
- }
- elsif (/^(system type|model)\s*:/i){
- @temp = split(/\s*:\s*/, $_, 2);
- $temp[1] = main::dmi_cleaner($temp[1]);
- $data{'model'} = main::cleaner($temp[1]);
- }
- elsif (/^Revision/i){
- @temp = split(/\s*:\s*/, $_, 2);
- $data{'firmware'} = $temp[1];
- }
- elsif (/^Serial/i){
- @temp = split(/\s*:\s*/, $_, 2);
- $data{'serial'} = $temp[1];
- }
+ CpuItem::cpuinfo_data_grabber($file) if !$loaded{'cpuinfo'};
+ # grabber sets keys to lower case to avoid error here
+ if ($cpuinfo_machine{'hardware'} || $cpuinfo_machine{'machine'}){
+ $data{'device'} = main::get_defined($cpuinfo_machine{'hardware'},
+ $cpuinfo_machine{'machine'});
+ $data{'device'} = main::clean_arm($data{'device'});
+ $data{'device'} = main::clean_dmi($data{'device'});
+ $data{'device'} = main::clean($data{'device'});
+ }
+ if (defined $cpuinfo_machine{'system type'} || $cpuinfo_machine{'model'}){
+ $data{'model'} = main::get_defined($cpuinfo_machine{'system type'},
+ $cpuinfo_machine{'model'});
+ $data{'model'} = main::clean_dmi($data{'model'});
+ $data{'model'} = main::clean($data{'model'});
+ }
+ # seen with PowerMac PPC
+ if (defined $cpuinfo_machine{'motherboard'}){
+ $data{'mobo'} = $cpuinfo_machine{'motherboard'};
+ }
+ if (defined $cpuinfo_machine{'revision'}){
+ $data{'firmware'} = $cpuinfo_machine{'revision'};
}
+ if (defined $cpuinfo_machine{'serial'}){
+ $data{'serial'} = $cpuinfo_machine{'serial'};
+ }
+ undef %cpuinfo_machine; # we're done with it, don't need it anymore
}
if (!$data{'model'} && $b_android){
main::set_build_prop() if !$loaded{'build-prop'};
@@ -13763,11 +14867,11 @@ sub machine_data_soc {
my $model = main::reader('/proc/device-tree/model','',0);
main::log_data('data',"device-tree-model: $model") if $b_log;
if ($model){
- $model = main::dmi_cleaner($model);
+ $model = main::clean_dmi($model);
$model = (split(/\x01|\x02|\x03|\x00/, $model))[0] if $model;
- my $device_temp = main::regex_cleaner($data{'device'});
+ my $device_temp = main::clean_regex($data{'device'});
if (!$data{'device'} || ($model && $model !~ /\Q$device_temp\E/i)){
- $model = main::arm_cleaner($model);
+ $model = main::clean_arm($model);
$data{'model'} = $model;
}
}
@@ -13820,15 +14924,15 @@ sub machine_data_dmi {
if ($item !~ /^~/){ # skip the indented rows
my @value = split(/:\s+/, $item);
if ($value[0] eq 'Release Date'){
- $data{'bios_date'} = main::dmi_cleaner($value[1]) }
+ $data{'bios_date'} = main::clean_dmi($value[1]) }
elsif ($value[0] eq 'Vendor'){
- $data{'bios_vendor'} = main::dmi_cleaner($value[1]) }
+ $data{'bios_vendor'} = main::clean_dmi($value[1]) }
elsif ($value[0] eq 'Version'){
- $data{'bios_version'} = main::dmi_cleaner($value[1]) }
+ $data{'bios_version'} = main::clean_dmi($value[1]) }
elsif ($value[0] eq 'ROM Size'){
- $data{'bios_romsize'} = main::dmi_cleaner($value[1]) }
+ $data{'bios_romsize'} = main::clean_dmi($value[1]) }
elsif ($value[0] eq 'BIOS Revision'){
- $data{'bios_rev'} = main::dmi_cleaner($value[1]) }
+ $data{'bios_rev'} = main::clean_dmi($value[1]) }
}
else {
if ($item eq '~UEFI is supported'){
@@ -13844,15 +14948,15 @@ sub machine_data_dmi {
if ($item !~ /^~/){ # skip the indented rows
my @value = split(/:\s+/, $item);
if ($value[0] eq 'Product Name'){
- $data{'product_name'} = main::dmi_cleaner($value[1]) }
+ $data{'product_name'} = main::clean_dmi($value[1]) }
elsif ($value[0] eq 'Version'){
- $data{'product_version'} = main::dmi_cleaner($value[1]) }
+ $data{'product_version'} = main::clean_dmi($value[1]) }
elsif ($value[0] eq 'Serial Number'){
- $data{'product_serial'} = main::dmi_cleaner($value[1]) }
+ $data{'product_serial'} = main::clean_dmi($value[1]) }
elsif ($value[0] eq 'Manufacturer'){
- $data{'sys_vendor'} = main::dmi_cleaner($value[1]) }
+ $data{'sys_vendor'} = main::clean_dmi($value[1]) }
elsif ($value[0] eq 'UUID'){
- $data{'sys_uuid'} = main::dmi_cleaner($value[1]) }
+ $data{'sys_uuid'} = main::clean_dmi($value[1]) }
}
}
next;
@@ -13864,13 +14968,13 @@ sub machine_data_dmi {
if ($item !~ /^~/){ # skip the indented rows
my @value = split(/:\s+/, $item);
if ($value[0] eq 'Product Name'){
- $data{'board_name'} = main::dmi_cleaner($value[1]) }
+ $data{'board_name'} = main::clean_dmi($value[1]) }
elsif ($value[0] eq 'Serial Number'){
- $data{'board_serial'} = main::dmi_cleaner($value[1]) }
+ $data{'board_serial'} = main::clean_dmi($value[1]) }
elsif ($value[0] eq 'Manufacturer'){
- $data{'board_vendor'} = main::dmi_cleaner($value[1]) }
+ $data{'board_vendor'} = main::clean_dmi($value[1]) }
elsif ($value[0] eq 'Version'){
- $data{'board_version'} = main::dmi_cleaner($value[1]) }
+ $data{'board_version'} = main::clean_dmi($value[1]) }
}
}
next;
@@ -13882,13 +14986,13 @@ sub machine_data_dmi {
if ($item !~ /^~/){ # skip the indented rows
my @value = split(/:\s+/, $item);
if ($value[0] eq 'Serial Number'){
- $data{'chassis_serial'} = main::dmi_cleaner($value[1]) }
+ $data{'chassis_serial'} = main::clean_dmi($value[1]) }
elsif ($value[0] eq 'Type'){
- $data{'chassis_type'} = main::dmi_cleaner($value[1]) }
+ $data{'chassis_type'} = main::clean_dmi($value[1]) }
elsif ($value[0] eq 'Manufacturer'){
- $data{'chassis_vendor'} = main::dmi_cleaner($value[1]) }
+ $data{'chassis_vendor'} = main::clean_dmi($value[1]) }
elsif ($value[0] eq 'Version'){
- $data{'chassis_version'} = main::dmi_cleaner($value[1]) }
+ $data{'chassis_version'} = main::clean_dmi($value[1]) }
}
}
if ($data{'chassis_type'} && $data{'chassis_type'} ne 'Other'){
@@ -13935,37 +15039,37 @@ sub machine_data_sysctl {
my @item = split(':', $_);
next if !$item[1];
if ($item[0] eq 'hw.vendor' || $item[0] eq 'machdep.dmi.board-vendor'){
- $data{'board_vendor'} = main::dmi_cleaner($item[1]);
+ $data{'board_vendor'} = main::clean_dmi($item[1]);
}
elsif ($item[0] eq 'hw.product' || $item[0] eq 'machdep.dmi.board-product'){
- $data{'board_name'} = main::dmi_cleaner($item[1]);
+ $data{'board_name'} = main::clean_dmi($item[1]);
}
elsif ($item[0] eq 'hw.version' || $item[0] eq 'machdep.dmi.board-version'){
- $data{'board_version'} = main::dmi_cleaner($item[1]);
+ $data{'board_version'} = main::clean_dmi($item[1]);
}
elsif ($item[0] eq 'hw.serialno' || $item[0] eq 'machdep.dmi.board-serial'){
- $data{'board_serial'} = main::dmi_cleaner($item[1]);
+ $data{'board_serial'} = main::clean_dmi($item[1]);
}
elsif ($item[0] eq 'hw.serial'){
- $data{'board_serial'} = main::dmi_cleaner($item[1]);
+ $data{'board_serial'} = main::clean_dmi($item[1]);
}
elsif ($item[0] eq 'hw.uuid'){
- $data{'board_uuid'} = main::dmi_cleaner($item[1]);
+ $data{'board_uuid'} = main::clean_dmi($item[1]);
}
elsif ($item[0] eq 'machdep.dmi.system-vendor'){
- $data{'sys_vendor'} = main::dmi_cleaner($item[1]);
+ $data{'sys_vendor'} = main::clean_dmi($item[1]);
}
elsif ($item[0] eq 'machdep.dmi.system-product'){
- $data{'product_name'} = main::dmi_cleaner($item[1]);
+ $data{'product_name'} = main::clean_dmi($item[1]);
}
elsif ($item[0] eq 'machdep.dmi.system-version'){
- $data{'product_version'} = main::dmi_cleaner($item[1]);
+ $data{'product_version'} = main::clean_dmi($item[1]);
}
elsif ($item[0] eq 'machdep.dmi.system-serial'){
- $data{'product_serial'} = main::dmi_cleaner($item[1]);
+ $data{'product_serial'} = main::clean_dmi($item[1]);
}
elsif ($item[0] eq 'machdep.dmi.system-uuid'){
- $data{'sys_uuid'} = main::dmi_cleaner($item[1]);
+ $data{'sys_uuid'} = main::clean_dmi($item[1]);
}
# bios0:at mainbus0: AT/286+ BIOS, date 06/30/06, BIOS32 rev. 0 @ 0xf2030, SMBIOS rev. 2.4 @ 0xf0000 (47 entries)
# bios0:vendor Phoenix Technologies, LTD version "3.00" date 06/30/2006
@@ -13982,13 +15086,13 @@ sub machine_data_sysctl {
}
}
elsif ($item[0] eq 'machdep.dmi.bios-vendor'){
- $data{'bios_vendor'} = main::dmi_cleaner($item[1]);
+ $data{'bios_vendor'} = main::clean_dmi($item[1]);
}
elsif ($item[0] eq 'machdep.dmi.bios-version'){
- $data{'bios_version'} = main::dmi_cleaner($item[1]);
+ $data{'bios_version'} = main::clean_dmi($item[1]);
}
elsif ($item[0] eq 'machdep.dmi.bios-date'){
- $data{'bios_date'} = main::dmi_cleaner($item[1]);
+ $data{'bios_date'} = main::clean_dmi($item[1]);
}
}
if ($data{'board_vendor'} || $data{'sys_vendor'} || $data{'board_name'} || $data{'product_name'}){
@@ -14157,7 +15261,7 @@ sub get {
eval $start if $b_log;
my (@rows);
my $num = 0;
- if (($b_arm || $b_mips) && !$use{'soc-network'} && !$use{'pci-tool'}){
+ if (%risc && !$use{'soc-network'} && !$use{'pci-tool'}){
# do nothing, but keep the test conditions to force
# the non arm case to always run
}
@@ -14167,11 +15271,10 @@ sub get {
push(@rows,usb_output());
# note: raspberry pi uses usb networking only
if (!@rows){
- if ($b_arm || $b_mips){
- my $type = ($b_arm) ? 'arm' : 'mips';
+ if (%risc){
my $key = 'Message';
push(@rows, {
- main::key($num++,0,1,$key) => main::row_defaults($type . '-pci',''),
+ main::key($num++,0,1,$key) => main::message('risc-pci',$risc{'id'}),
},);
}
else {
@@ -14181,7 +15284,7 @@ sub get {
$type = 'pci-card-data-root';
}
push(@rows,{
- main::key($num++,0,1,$key) => main::row_defaults($type,''),
+ main::key($num++,0,1,$key) => main::message($type,''),
},);
}
}
@@ -14225,7 +15328,7 @@ sub device_output {
# first check if it's a known wifi id'ed card, if so, no print of duplex/speed
$b_wifi = check_wifi($row->[4]);
my $device = $row->[4];
- $device = ($device) ? main::pci_cleaner($device,'output') : 'N/A';
+ $device = ($device) ? main::clean_pci($device,'output') : 'N/A';
#$device ||= 'N/A';
$driver ||= 'N/A';
push(@rows, {
@@ -14280,14 +15383,14 @@ sub device_output {
}
# @rows = ();
# we want to handle ARM errors in main get
- if (!@rows && !$b_arm && !$b_mips){
+ if (!@rows && !%risc){
my $key = 'Message';
my $type = 'pci-card-data';
if ($pci_tool && $alerts{$pci_tool}->{'action'} eq 'permissions'){
$type = 'pci-card-data-root';
}
push(@rows, {
- main::key($num++,0,1,$key) => main::row_defaults($type,''),
+ main::key($num++,0,1,$key) => main::message($type,''),
},);
}
eval $end if $b_log;
@@ -14301,7 +15404,7 @@ sub usb_output {
foreach my $row (@{$usb{'network'}}){
$num = 1;
($driver,$path,$path_id,$product,$type) = ('','','','','');
- $product = main::cleaner($row->[13]) if $row->[13];
+ $product = main::clean($row->[13]) if $row->[13];
$driver = $row->[15] if $row->[15];
$path = $row->[3] if $row->[3];
$path_id = $row->[2] if $row->[2];
@@ -14324,7 +15427,7 @@ sub usb_output {
$rows[$j]->{main::key($num++,0,2,'class-ID')} = "$row->[4]$row->[5]";
}
if ($extra > 2 && $row->[16]){
- $rows[$j]->{main::key($num++,0,2,'serial')} = main::apply_filter($row->[16]);
+ $rows[$j]->{main::key($num++,0,2,'serial')} = main::filter($row->[16]);
}
if ($show{'network-advanced'}){
my @data;
@@ -14378,7 +15481,7 @@ sub advanced_data_sys {
# for usb, we already know where we are
if (!$b_usb){
# pi mmcnr has pcitool and also these vendor/device paths.
- if ((!$b_arm && !$b_ppc) || $use{'pci-tool'}){
+ if (!%risc || $use{'pci-tool'}){
$path = "$_/device/vendor";
$data1 = main::reader($path,'',0) if -r $path;
$data1 =~ s/^0x// if $data1;
@@ -14391,7 +15494,7 @@ sub advanced_data_sys {
# there are cases where arm devices have a small pci bus
# or, with mmcnr devices, will show device/vendor info in data1/2
# which won't match with the path IDs
- if (($b_arm || $b_ppc || $b_mips || $b_sparc) && $chip && Cwd::abs_path($_) =~ /\b$chip\b/){
+ if (%risc && $chip && Cwd::abs_path($_) =~ /\b$chip\b/){
$data1 = $vendor;
$data2 = $chip;
}
@@ -14399,7 +15502,7 @@ sub advanced_data_sys {
# print "d1:$data1 v:$vendor d2:$data2 c:$chip bus_id: $bus_id\n";
# print Cwd::abs_path($_), "\n" if $bus_id;
if ($b_usb || $b_check || ($data1 && $data2 && $data1 eq $vendor && $data2 eq $chip &&
- (($b_arm || $b_mips || $b_ppc || $b_sparc) || check_bus_id($_,$bus_id)))){
+ (%risc || check_bus_id($_,$bus_id)))){
$if = $_;
$if =~ s/^\/.+\///;
# print "top: if: $if ifs: @ifs_found\n";
@@ -14409,7 +15512,7 @@ sub advanced_data_sys {
$duplex ||= 'N/A';
$path = "$_/address";
$mac = main::reader($path,'',0) if -r $path;
- $mac = main::apply_filter($mac);
+ $mac = main::filter($mac);
$path = "$_/speed";
$speed = main::reader($path,'',0) if -r $path;
$speed ||= 'N/A';
@@ -14484,7 +15587,7 @@ sub advanced_data_bsd {
# ($state,$speed,$duplex,$mac)
$duplex = $data[2];
$duplex ||= 'N/A';
- $mac = main::apply_filter($data[3]);
+ $mac = main::filter($data[3]);
$speed = $data[1];
$speed ||= 'N/A';
$state = $data[0];
@@ -14551,14 +15654,14 @@ sub if_ip {
$num = 1;
if ($limit > 0 && $j >= $limit){
push(@rows, {
- main::key($num++,0,$cont_ip,'Message') => main::row_defaults('output-limit',scalar @data),
+ main::key($num++,0,$cont_ip,'Message') => main::message('output-limit',scalar @data),
},);
last OUTER;
}
# print "$data2->[0] $data2->[1]\n";
my ($ipv,$ip,$broadcast,$scope,$scope_id);
$ipv = ($data2->[0])? $data2->[0]: 'N/A';
- $ip = main::apply_filter($data2->[1]);
+ $ip = main::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'){
@@ -14596,7 +15699,7 @@ sub if_ip {
},);
}
if ($extra > 1 && $data2->[2]){
- $broadcast = main::apply_filter($data2->[2]);
+ $broadcast = main::filter($data2->[2]);
$rows[$j]->{main::key($num++,0,$ind_ip,'broadcast')} = $broadcast;
}
}
@@ -14659,13 +15762,13 @@ sub wan_ip {
if (!$ip){
# true case trips
if (!$b_dig){
- $ip = main::row_defaults('IP-no-dig', 'WAN IP');
+ $ip = main::message('IP-no-dig', 'WAN IP');
}
elsif ($b_dig && !$b_html){
- $ip = main::row_defaults('IP-dig', 'WAN IP');
+ $ip = main::message('IP-dig', 'WAN IP');
}
else {
- $ip = main::row_defaults('IP', 'WAN IP');
+ $ip = main::message('IP', 'WAN IP');
}
}
@data = ({
@@ -14706,7 +15809,7 @@ sub get {
my $num = 0;
if ($bsd_type){
$key1 = 'Optical Report';
- $val1 = main::row_defaults('optical-data-bsd');
+ $val1 = main::message('optical-data-bsd');
@rows = ({main::key($num++,0,1,$key1) => $val1,});
if ($dboot{'optical'}){
%data = drive_data_bsd();
@@ -14715,13 +15818,13 @@ sub get {
else{
my $file = $system_files{'dmesg-boot'};
if ($file && ! -r $file){
- $val1 = main::row_defaults('dmesg-boot-permissions');
+ $val1 = main::message('dmesg-boot-permissions');
}
elsif (!$file){
- $val1 = main::row_defaults('dmesg-boot-missing');
+ $val1 = main::message('dmesg-boot-missing');
}
else {
- $val1 = main::row_defaults('optical-data-bsd');
+ $val1 = main::message('optical-data-bsd');
}
$key1 = 'Optical Report';
@rows = ({main::key($num++,0,1,$key1) => $val1,});
@@ -14733,7 +15836,7 @@ sub get {
}
if (!@rows){
$key1 = 'Message';
- $val1 = main::row_defaults('optical-data');
+ $val1 = main::message('optical-data');
@rows = ({main::key($num++,0,1,$key1) => $val1,});
}
eval $end if $b_log;
@@ -14772,7 +15875,7 @@ sub drive_output {
$rows[$j]->{ main::key($num++,0,2,'rev')} = $rev;
}
if ($extra > 1 && $drives->{$key}{'serial'}){
- $rows[$j]->{ main::key($num++,0,2,'serial')} = main::apply_filter($drives->{$key}{'serial'});
+ $rows[$j]->{ main::key($num++,0,2,'serial')} = main::filter($drives->{$key}{'serial'});
}
my $links = (@{$drives->{$key}{'links'}}) ? join(',', sort @{$drives->{$key}{'links'}}) : 'N/A' ;
$rows[$j]->{ main::key($num++,0,2,'dev-links')} = $links;
@@ -14964,16 +16067,16 @@ sub drive_data_linux {
if (-d $device){
if (-r "$device/vendor"){
$drives{$key}->{'vendor'} = main::reader("$device/vendor",'',0);
- $drives{$key}->{'vendor'} = main::cleaner($drives{$key}->{'vendor'});
+ $drives{$key}->{'vendor'} = main::clean($drives{$key}->{'vendor'});
$drives{$key}->{'state'} = main::reader("$device/state",'',0);
$drives{$key}->{'model'} = main::reader("$device/model",'',0);
- $drives{$key}->{'model'} = main::cleaner($drives{$key}->{'model'});
+ $drives{$key}->{'model'} = main::clean($drives{$key}->{'model'});
$drives{$key}->{'rev'} = main::reader("$device/rev",'',0);
}
}
elsif (-r "/proc/ide/$key/model"){
$drives{$key}->{'vendor'} = main::reader("/proc/ide/$key/model",'',0);
- $drives{$key}->{'vendor'} = main::cleaner($drives{$key}->{'vendor'});
+ $drives{$key}->{'vendor'} = main::clean($drives{$key}->{'vendor'});
}
if ($show{'optical'} && @info){
my $index = 0;
@@ -15037,8 +16140,8 @@ sub get {
if (!@partitions){
$key1 = 'Message';
#$val1 = ($bsd_type && $bsd_type eq 'darwin') ?
- # main::row_defaults('darwin-feature') : main::row_defaults('partition-data');
- $val1 = main::row_defaults('partition-data');
+ # main::message('darwin-feature') : main::message('partition-data');
+ $val1 = main::message('partition-data');
@rows = ({main::key($num++,0,1,$key1) => $val1,});
}
else {
@@ -15072,7 +16175,7 @@ sub create_output {
}
else {
$percent = '';
- $used = $size = (!$b_root) ? main::row_defaults('root-required') : main::row_defaults('partition-hidden');
+ $used = $size = (!$b_root) ? main::message('root-required') : main::message('partition-hidden');
}
$fs = ($row->{'fs'}) ? lc($row->{'fs'}): 'N/A';
$dev_type = ($row->{'dev-type'}) ? $row->{'dev-type'} : 'dev';
@@ -15120,14 +16223,14 @@ sub create_output {
$fs !~ /^$fs_skip$/){
if ($show{'label'}){
if ($use{'filter-label'}){
- $row->{'label'} = main::apply_partition_filter('part', $row->{'label'}, '');
+ $row->{'label'} = main::filter_partition('part', $row->{'label'}, '');
}
$row->{'label'} ||= 'N/A';
$rows[$j]->{main::key($num++,0,2,'label')} = $row->{'label'};
}
if ($show{'uuid'}){
if ($use{'filter-uuid'}){
- $row->{'uuid'} = main::apply_partition_filter('part', $row->{'uuid'}, '');
+ $row->{'uuid'} = main::filter_partition('part', $row->{'uuid'}, '');
}
$row->{'uuid'} ||= 'N/A';
$rows[$j]->{main::key($num++,0,2,'uuid')} = $row->{'uuid'};
@@ -15351,7 +16454,7 @@ sub set_partitions {
# an error has occurred almost for sure
elsif (!$dev_base){
$dev_type = 'source';
- $dev_base = main::row_defaults('unknown-dev');
+ $dev_base = main::message('unknown-dev');
}
else {
$dev_type = 'dev';
@@ -15775,7 +16878,7 @@ sub get {
else {
my $key = 'Message';
push(@rows, ({
- main::key($num++,0,1,$key) => main::row_defaults('ps-data-null',''),
+ main::key($num++,0,1,$key) => main::message('ps-data-null',''),
},));
}
eval $end if $b_log;
@@ -15949,7 +17052,7 @@ sub get {
!@hardware_raid){
if ($show{'raid-forced'}){
$key1 = 'Message';
- $val1 = main::row_defaults('raid-data');
+ $val1 = main::message('raid-data');
}
}
else {
@@ -16004,7 +17107,7 @@ sub hw_output {
$rows[$j]->{main::key($num++,0,2,'bus-ID')} = $bus_id;
}
if ($extra > 1){
- my $chip_id = main::get_chip_id($row->[5],$row->[6]);
+ my $chip_id = main::get_chip_id($row->{'vendor-id'},$row->{'chip-id'});
$rows[$j]->{main::key($num++,0,2,'chip-ID')} = $chip_id;
}
if ($extra > 2){
@@ -16129,7 +17232,7 @@ sub md_output {
$size = main::get_size($row->{'size'},'string');
}
else {
- $size = (!$b_root && !@lsblk) ? main::row_defaults('root-required'): 'N/A';
+ $size = (!$b_root && !@lsblk) ? main::message('root-required'): 'N/A';
}
$rows[$j]->{main::key($num++,0,2,'size')} = $size;
$report = ($row->{'report'}) ? $row->{'report'}: '';
@@ -16221,7 +17324,7 @@ sub soft_output {
my ($j,$num) = (0,0);
if (@soft_raid && $alerts{'bioctl'}->{'action'} eq 'permissions'){
push(@rows,{
- main::key($num++,1,1,'Message') => main::row_defaults('root-item-incomplete','softraid'),
+ main::key($num++,1,1,'Message') => main::message('root-item-incomplete','softraid'),
});
}
# print Data::Dumper::Dumper \@soft_raid;
@@ -16539,7 +17642,6 @@ sub btrfs_data {
}
print Data::Dumper::Dumper \@working if $dbg[37];
-
print Data::Dumper::Dumper \@btraid if $dbg[37];
main::log_data('dump','@lvraid',\@btraid) if $b_log;
eval $end if $b_log;
@@ -16579,7 +17681,7 @@ sub lvm_data {
}
if ($item->{'segtype'}){
if ($item->{'segtype'} eq 'raid1'){$item->{'segtype'} = 'mirror';}
- else {$item->{'segtype'} =~ s/^raid([0-9]+)/raid-$1/; }
+ else {$item->{'segtype'} =~ s/^raid([0-9]+)/raid-$1/;}
}
push(@lvraid, {
'components' => \@components,
@@ -16902,6 +18004,7 @@ sub zfs_data {
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/raid/zpool-list-2-mirror-main-solestar.txt";
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/raid/zpool-list-v-tank-1.txt";
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/raid/zpool-list-v-gojev-1.txt";
+ # $file = "$ENV{'HOME'}/bin/scripts/inxi/data/raid/zpool-list-v-w-spares-1.txt";
#@working = main::reader($file);$zpool = '';
}
else {
@@ -16981,20 +18084,22 @@ sub zfs_data {
$zfs[$j]->{'arrays'}[$k]{'raw-size'} = $size;
}
# https://blogs.oracle.com/eschrock/entry/zfs_hot_spares
- elsif ($row[1] =~ /spares/){
+ elsif ($row[1] =~ /spares?/){
next;
}
- # the first is a member of a raid array
- # ada2 - - - - - -
- # this second is a single device not in an array
+ # A member of a raid array:
+ # ada2 - - - - - -
+ # A single device not in an array:
# ada0s2 25.9G 14.6G 11.3G - 0% 56%
# gptid/3838f796-5c46-11e6-a931-d05099ac4dc2 - - - - - -
- # third is using /dev/disk/by-id
- # ata-VBOX_HARDDISK_VB5b6350cd-06618d58 - - - - - - - - ONLINE
+ # Using /dev/disk/by-id:
+ # ata-VBOX_HARDDISK_VB5b6350cd-06618d58 - - - - - - - - ONLINE
+ # Spare in use:
+ # /home/fred/zvol/hdd-2-3 - - - - - - - - INUSE
elsif ($row[1] =~ /^(sd[a-z]+|[a-z0-9]+[0-9]+|([\S]+)\/.*|(ata|mmc|nvme|pci|scsi|wwn)-\S+)$/ &&
($row[2] eq '-' || $row[2] =~ /^[0-9\.]+[MGTPE]$/)){
#print "r1:$row[1]",' :: ', Cwd::abs_path('/dev/disk/by-id/'.$row[1]), "\n";
- $row[1] =~ /^(sd[a-z]+|[a-z0-9]+[0-9]+|([\S]+)\/.*|(ata|mmc|nvme|pci|scsi|wwn)-\S+)\s.*?(DEGRADED|FAULTED|OFFLINE)?$/;
+ $row[1] =~ /^(sd[a-z]+|[a-z0-9]+[0-9]+|([\S]+)\/.*|(ata|mmc|nvme|pci|scsi|wwn)-\S+)\s.*?(DEGRADED|FAULTED|INUSE|OFFLINE)?$/;
#my $working = '';
my $working = ($1) ? $1 : ''; # note: the negative case can never happen
my $state = ($4) ? $4 : '';
@@ -17069,14 +18174,23 @@ sub zfs_data {
sub zfs_fs_sizes {
my ($path,$id) = @_;
eval $start if $b_log;
+ my @data;
my @result = main::grabber("$path list -pH $id 2>/dev/null",'','strip');
main::log_data('dump','zfs list @result',\@result) if $b_log;
print Data::Dumper::Dumper \@result if $dbg[37];
- my @working = split(/\s+/,$result[0]);
+ # some zfs devices do not have zfs data, lake spare storage devices
+ if (@result){
+ my @working = split(/\s+/,$result[0]);
+ $data[0] = $working[1]/1024 if $working[1];
+ $data[1] = $working[2]/1024 if $working[2];
+ }
+ elsif ($b_log || $dbg[37]) {
+ @result = main::grabber("$path list -pH $id 2>&1",'','strip');
+ main::log_data('dump','zfs list w/error @result',\@result) if $b_log;
+ print '@result w/error: ', Data::Dumper::Dumper \@result if $dbg[37];
+ }
eval $end if $b_log;
- $working[1] = $working[1]/1024 if $working[1];
- $working[2] = $working[2]/1024 if $working[2];
- return ($working[1],$working[2]);
+ return @data;
}
sub zfs_status {
eval $start if $b_log;
@@ -17162,7 +18276,7 @@ sub get {
}
else {
$key1 = 'message';
- $val1 = main::row_defaults('ram-data-dmidecode');
+ $val1 = main::message('ram-data-dmidecode');
@data = ({
main::key($num++,1,1,'RAM Report') => '',
main::key($num++,0,2,$key1) => $val1,
@@ -17176,7 +18290,7 @@ sub get {
}
else {
$key1 = 'message';
- $val1 = main::row_defaults('ram-data');
+ $val1 = main::message('ram-data');
@data = ({
main::key($num++,1,1,'RAM Report') => '',
main::key($num++,0,2,$key1) => $val1,
@@ -17206,7 +18320,7 @@ sub ram_output {
my ($arrays,$modules,$slots,$type_holder) = (0,0,0,'');
if ($source eq 'dboot'){
push(@rows, {
- main::key($num++,0,1,'Message') => main::row_defaults('ram-data-complete'),
+ main::key($num++,0,1,'Message') => main::message('ram-data-complete'),
});
}
foreach my $item (@$ram){
@@ -17307,7 +18421,7 @@ sub ram_output {
$rows[$j]->{main::key($num++,0,3,'part-no')} = $mod->{'part-number'};
}
if ($source ne 'dboot' && $extra > 2){
- $mod->{'serial'} = main::apply_filter($mod->{'serial'});
+ $mod->{'serial'} = main::filter($mod->{'serial'});
$rows[$j]->{main::key($num++,0,3,'serial')} = $mod->{'serial'};
}
}
@@ -17333,7 +18447,7 @@ sub dmidecode_data {
my ($b_5,$handle,@ram,@temp);
my ($derived_module_size,$max_cap_5,$max_cap_16,$max_module_size) = (0,0,0,0);
my ($i,$j,$k) = (0,0,0);
- my $check = main::row_defaults('note-check');
+ my $check = main::message('note-check');
# print Data::Dumper::Dumper \@dmi;
foreach my $entry (@dmi){
## NOTE: do NOT reset these values, that causes failures
@@ -17386,7 +18500,7 @@ sub dmidecode_data {
$type = lc($temp[1]);
}
elsif ($temp[0] eq 'Current Speed'){
- $speed = main::dmi_cleaner($temp[1]);
+ $speed = main::clean_dmi($temp[1]);
}
elsif ($temp[0] eq 'Locator' || $temp[0] eq 'Socket Designation'){
$temp[1] =~ s/D?RAM slot #?/Slot/i; # can be with or without #
@@ -17511,16 +18625,14 @@ sub dmidecode_data {
($configured_speed,$configured_note) = process_speed($temp[1],$device_type,$check);
}
elsif ($temp[0] eq 'Manufacturer'){
- $temp[1] = main::dmi_cleaner($temp[1]);
+ $temp[1] = main::clean_dmi($temp[1]);
$manufacturer = $temp[1];
}
elsif ($temp[0] eq 'Part Number'){
- $temp[1] =~ s/(^[0]+$||.*Module.*|Undefined.*|PartNum.*|\[Empty\]|^To be filled.*)//g;
- $part_number = $temp[1];
+ $part_number = main::clean_unset($temp[1],'^[0]+$|.*Module.*|PartNum.*');
}
elsif ($temp[0] eq 'Serial Number'){
- $temp[1] =~ s/(^[0]+$|Undefined.*|SerNum.*|\[Empty\]|^To be filled.*)//g;
- $serial = $temp[1];
+ $serial = main::clean_unset($temp[1],'^[0]+$|SerNum.*');
}
}
# because of the wide range of bank/slot type data, we will just use
@@ -17600,7 +18712,7 @@ sub dmidecode_data {
sub dboot_data {
eval $start if $b_log;
my (@ram);
- my $est = main::row_defaults('note-est');
+ my $est = main::message('note-est');
my ($arr,$derived_module_size,$subtract) = (0,0,0);
my ($holder);
foreach (@{$dboot{'ram'}}){
@@ -17686,8 +18798,8 @@ sub process_data {
my ($ram) = @_;
my $b_debug = 0;
my (@return);
- my $check = main::row_defaults('note-check');
- my $est = main::row_defaults('note-est');
+ my $check = main::message('note-check');
+ my $est = main::message('note-est');
foreach my $item (@$ram){
# because we use the actual array handle as the index,
# there will be many undefined keys
@@ -17859,7 +18971,7 @@ sub process_data {
sub process_speed {
my ($speed,$device_type,$check) = @_;
my $speed_note;
- $speed = main::dmi_cleaner($speed) if $speed;
+ $speed = main::clean_dmi($speed) if $speed;
if ($device_type && $device_type =~ /ddr/i && $speed && $speed =~ /^([0-9]+)\s*MHz/){
$speed = ($1 * 2) . " MT/s ($speed)";
}
@@ -18091,10 +19203,10 @@ sub get {
if (!@rows_r){
my $pm_missing;
if ($bsd_type){
- $pm_missing = main::row_defaults('repo-data-bsd',$uname[0]);
+ $pm_missing = main::message('repo-data-bsd',$uname[0]);
}
else {
- $pm_missing = main::row_defaults('repo-data');
+ $pm_missing = main::message('repo-data');
}
@data = ({main::key($num++,0,1,'Alert') => $pm_missing});
}
@@ -18222,7 +19334,7 @@ sub get_repos_linux {
}
if (@apt_urls){
$key = repo_data('active','apt');
- url_cleaner(\@apt_urls);
+ clean_url(\@apt_urls);
}
else {
$key = repo_data('missing','apt');
@@ -18316,14 +19428,14 @@ sub get_repos_linux {
$key = repo_data('missing','slackpkg+');
}
else {
- url_cleaner(\@content);
+ clean_url(\@content);
$key = repo_data('active','slackpkg+');
}
@data = (
{main::key($num++,1,1,$key) => $slackpkg_plus},
[@content],
);
- url_cleaner(\@data);
+ clean_url(\@data);
push(@rows,@data);
@content = ();
}
@@ -18399,7 +19511,7 @@ sub get_repos_linux {
$key = repo_data('missing',$repo);
}
else {
- url_cleaner(\@content);
+ clean_url(\@content);
$key = repo_data('active',$repo);
}
push(@rows,
@@ -18462,7 +19574,7 @@ sub get_repos_linux {
$key = repo_data('missing','portage');
}
else {
- url_cleaner(\@content);
+ clean_url(\@content);
$key = repo_data('active','portage');
}
push(@rows,
@@ -18497,7 +19609,7 @@ sub get_repos_linux {
$key = repo_data('missing','cards');
}
else {
- url_cleaner(\@content);
+ clean_url(\@content);
$key = repo_data('active','cards');
}
push(@rows,
@@ -18548,7 +19660,7 @@ sub get_repos_linux {
if (/(.+)\s([\S]+:\/\/.+)/){
# pack the repo url
push(@content, $1);
- url_cleaner(\@content);
+ clean_url(\@content);
# get the repo
$repo = $2;
push(@rows,
@@ -18594,7 +19706,7 @@ sub get_repos_linux {
$repo = ($2 =~ /^activ/i) ? $repo : '';
}
if ($repo && @content){
- url_cleaner(\@content);
+ clean_url(\@content);
$key = repo_data('active',$which);
push(@rows,
{main::key($num++,1,1,$key) => $repo},
@@ -18606,7 +19718,7 @@ sub get_repos_linux {
}
# last one if present
if ($repo && @content){
- url_cleaner(\@content);
+ clean_url(\@content);
$key = repo_data('active',$which);
push(@rows,
{main::key($num++,1,1,$key) => $repo},
@@ -18621,7 +19733,7 @@ sub get_repos_linux {
$key = repo_data('missing','nix');
}
else {
- url_cleaner(\@content);
+ clean_url(\@content);
$key = repo_data('active','nix');
}
my $user = ($ENV{'USER'}) ? $ENV{'USER'}: 'N/A';
@@ -18673,13 +19785,13 @@ sub get_repos_bsd {
# first dump all lines that start with #
@content = main::reader($_,'strip');
# then do some clean up on the lines
- @content = map { $_ =~ s/{|}|,|\*//g; $_; } @content if @content;
+ @content = map { $_ =~ s/{|}|,|\*//g; $_;} @content if @content;
# get all rows not starting with a # and starting with a non space character
my $url = '';
foreach my $line (@content){
if ($line !~ /^\s*$/){
my @data2 = split(/\s*:\s*/, $line);
- @data2 = map { $_ =~ s/^\s+|\s+$//g; $_; } @data2;
+ @data2 = map { $_ =~ s/^\s+|\s+$//g; $_;} @data2;
if ($data2[0] eq 'url'){
$url = "$data2[1]:$data2[2]";
$url =~ s/"|,//g;
@@ -18697,7 +19809,7 @@ sub get_repos_bsd {
$key = repo_data('missing','bsd-package');
}
else {
- url_cleaner(\@data3);
+ clean_url(\@data3);
$key = repo_data('active','bsd-package');
}
push(@rows,
@@ -18741,7 +19853,7 @@ sub get_repos_bsd {
# $key = repo_data('missing','mports');
# }
# else {
-# url_cleaner(\@data3);
+# clean_url(\@data3);
# $key = repo_data('active','mports');
# }
# push(@rows,
@@ -18844,7 +19956,7 @@ sub repo_builder {
if (-r $file){
@content = main::reader($file);
@content = grep {/$search/i && !/^\s*$/} @content if @content;
- data_cleaner(\@content) if @content;
+ clean_data(\@content) if @content;
}
if ($split && @content){
@content = map {
@@ -18857,7 +19969,7 @@ sub repo_builder {
}
else {
$key = repo_data('active',$type);
- url_cleaner(\@content);
+ clean_url(\@content);
}
@data = (
{main::key($num++,1,1,$key) => $file},
@@ -18866,13 +19978,20 @@ sub repo_builder {
eval $end if $b_log;
return @data;
}
-sub data_cleaner {
- # basics: trim white space, get rid of double spaces
- @{$_[0]} = map {$_ =~ s/^\s+|\s+$//g; $_ =~ s/\s\s+/ /g; $_} @{$_[0]};
+sub clean_data {
+ # basics: trim white space, get rid of double spaces; trim comments at
+ # ends of repo values
+ @{$_[0]} = map {
+ $_ =~ s/\s\s+/ /g;
+ $_ =~ s/^\s+|\s+$//g;
+ $_ =~ s/^(.*\/.*) #.*/$1/;
+ $_;} @{$_[0]};
}
# clean if irc
-sub url_cleaner {
+sub clean_url {
@{$_[0]} = map {$_ =~ s/:\//: \//; $_} @{$_[0]} if $b_irc;
+ # trim comments at ends of repo values
+ @{$_[0]} = map {$_ =~ s/^(.*\/.*) #.*/$1/; $_} @{$_[0]};
}
sub file_path {
my ($filename,$dir) = @_;
@@ -18903,8 +20022,8 @@ sub get {
@data = sensors_output('ipmi',\%sensors);
if (!@data){
$key1 = 'Message';
- $val1 = main::row_defaults('sensors-data-ipmi');
- # $val1 = main::row_defaults('dev');
+ $val1 = main::message('sensors-data-ipmi');
+ # $val1 = main::message('dev');
@data = ({main::key($num++,0,1,$key1) => $val1,});
}
push(@rows,@data);
@@ -18912,7 +20031,7 @@ sub get {
}
else {
$key1 = 'Permissions';
- $val1 = main::row_defaults('sensors-ipmi-root');
+ $val1 = main::message('sensors-ipmi-root');
@data = ({main::key($num++,0,1,$key1) => $val1,});
push(@rows,@data);
}
@@ -18922,7 +20041,7 @@ sub get {
@data = sensors_output('sysctl-sensors',\%sensors);
if (!@data){
$key1 = 'Message';
- $val1 = main::row_defaults('sensors-data-bsd',$uname[0]);
+ $val1 = main::message('sensors-data-bsd',$uname[0]);
@data = ({main::key($num++,0,1,$key1) => $val1,});
}
push(@rows,@data);
@@ -18932,7 +20051,7 @@ sub get {
# print "here 1\n";
if ($bsd_type && $bsd_type =~ /^(free|open)bsd/){
$key1 = 'Message';
- $val1 = main::row_defaults('sensors-data-bsd-ok');
+ $val1 = main::message('sensors-data-bsd-ok');
}
else {
$key1 = $alerts{'sensors'}->{'action'};
@@ -18948,7 +20067,7 @@ sub get {
# print "here 2\n";
if (!@data){
$key1 = 'Message';
- $val1 = main::row_defaults('sensors-data-linux');
+ $val1 = main::message('sensors-data-linux');
@data = ({main::key($num++,0,1,$key1) => $val1,});
}
push(@rows,@data);
@@ -18960,14 +20079,14 @@ sub get {
sub sensors_output {
eval $start if $b_log;
my ($source,$sensors) = @_;
- # note: might revisit this, since gpu sensors data might be present
- return if ! %$sensors;
my (@gpu,@rows,@fan_default,@fan_main);
my ($data_source) = ('');
my $fan_number = 0;
my $num = 0;
my $j = 0;
@gpu = gpu_data() if ($source eq 'sensors' || $source eq 'lm-sensors');
+ # gpu sensors data might be present even if standard sensors data wasn't
+ return if !%$sensors && !@gpu;
my $temp_unit = (defined $sensors->{'temp-unit'}) ? " $sensors->{'temp-unit'}": '';
my $cpu_temp = (defined $sensors->{'cpu-temp'}) ? $sensors->{'cpu-temp'} . $temp_unit: 'N/A';
my $mobo_temp = (defined $sensors->{'mobo-temp'}) ? $sensors->{'mobo-temp'} . $temp_unit: 'N/A';
@@ -18986,6 +20105,10 @@ sub sensors_output {
if ($sensors->{'cpu4-temp'}){
$rows[$j]->{main::key($num++,0,2,'cpu-4')} = $sensors->{'cpu4-temp'} . $temp_unit;
}
+ if (defined $sensors->{'pch-temp'}){
+ my $pch_temp = $sensors->{'pch-temp'} . $temp_unit;
+ $rows[$j]->{main::key($num++,0,2,'pch')} = $pch_temp;
+ }
$rows[$j]->{main::key($num++,0,2,'mobo')} = $mobo_temp;
if (defined $sensors->{'sodimm-temp'}){
my $sodimm_temp = $sensors->{'sodimm-temp'} . $temp_unit;
@@ -19010,8 +20133,8 @@ sub sensors_output {
}
}
$j = scalar @rows;
- @fan_main = @{$sensors->{'fan-main'}} if @{$sensors->{'fan-main'}};
- @fan_default = @{$sensors->{'fan-default'}} if @{$sensors->{'fan-default'}};
+ @fan_main = @{$sensors->{'fan-main'}} if $sensors->{'fan-main'};
+ @fan_default = @{$sensors->{'fan-default'}} if $sensors->{'fan-default'};
my $fan_def = ($data_source) ? $data_source : '';
if (!@fan_main && !@fan_default){
$fan_def = ($fan_def) ? "$data_source N/A" : 'N/A';
@@ -19129,8 +20252,8 @@ sub ipmi_data {
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/ipmitool/ipmi-sensors-zwerg.txt";
# $file = "$ENV{'HOME'}/bin/scripts/inxi/data/ipmitool/ipmi-sensors-arm-server-1.txt";
# @data = main::reader($file);
- #($b_ipmitool,$i_key,$i_value,$i_unit) = (0,1,3,4); # ipmi-sensors
- #($b_ipmitool,$i_key,$i_value,$i_unit) = (1,0,1,2); # ipmitool sensors
+ # ($b_ipmitool,$i_key,$i_value,$i_unit) = (0,1,3,4); # ipmi-sensors
+ # ($b_ipmitool,$i_key,$i_value,$i_unit) = (1,0,1,2); # ipmitool sensors
}
else {
if ($program =~ /ipmi-sensors$/){
@@ -19327,7 +20450,7 @@ sub lm_sensors_data {
# 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 ($_ =~ /^(T?CPU.*|Tdie.*):([0-9\.]+)[\s°]*(C|F)/i){
+ elsif ($_ =~ /^(Chip 0.*?|T?CPU.*|Tdie.*):([0-9\.]+)[\s°]*(C|F)/i){
$temp_working = $2;
$working_unit = $3;
if (!$sensors{'cpu-temp'} ||
@@ -19346,7 +20469,7 @@ sub lm_sensors_data {
$working_unit = $3;
$sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
}
- elsif ($_ =~ /^T?(dimm|mem|sodimm).*:([0-9\.]+)[\s°]*(C|F)/i){
+ elsif ($_ =~ /^T?(dimm|mem|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;
@@ -19456,6 +20579,27 @@ sub lm_sensors_data {
}
}
}
+ foreach $adapter (keys %{$sensors_raw{'pch'}}){
+ next if !$adapter || ref $sensors_raw{'pch'}->{$adapter} ne 'ARRAY';
+ if ((@sensors_use && !(grep {/$adapter/} @sensors_use)) ||
+ (@sensors_exclude && (grep {/$adapter/} @sensors_exclude))){
+ next;
+ }
+ $temp_working = '';
+ foreach (@{$sensors_raw{'pch'}->{$adapter}}){
+ if ($_ =~ /^[^:]+:([0-9\.]+)[\s°]*(C|F)/i){
+ $temp_working = $1;
+ $working_unit = $2;
+ if (!$sensors{'pch-temp'} ||
+ (defined $temp_working && $temp_working > 0 && $temp_working > $sensors{'pch-temp'})){
+ $sensors{'pch-temp'} = $temp_working;
+ }
+ if (!$sensors{'temp-unit'} && $working_unit){
+ $sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit);
+ }
+ }
+ }
+ }
print Data::Dumper::Dumper \%sensors if $dbg[31];
%sensors = process_data(%sensors) if %sensors;
main::log_data('dump','lm-sensors: %sensors',\%sensors) if $b_log;
@@ -19478,7 +20622,9 @@ sub process_lm_sensors {
# 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);
+ # my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sensors/sensors-pch-intel-1.txt";
+ # my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sensors/sensors-ppc-sr71.txt";
+ # @sensors_data = main::reader($file);
}
else {
# only way to get sensor array data? Unless using sensors -j, but can't assume json
@@ -19499,15 +20645,20 @@ sub process_lm_sensors {
if ($adapter =~ /^(drive|nvme)/){
$type = 'disk';
}
- elsif ($adapter =~ /^(amdgpu|intel|nouveau|radeon)-/){
- $type = 'gpu';
+ # intel on die io controller, like southbridge/northbridge used to be
+ elsif ($adapter =~ /^(pch[_-])/){
+ $type = 'pch';
+ }
+ elsif ($adapter =~ /^(.*hwmon)-/){
+ $type = 'hwmon';
}
# 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';
+ # put last just in case some other sensor type above had intel in name
+ elsif ($adapter =~ /^(amdgpu|intel|nouveau|radeon)-/){
+ $type = 'gpu';
}
else {
$type = 'main';
@@ -19624,7 +20775,7 @@ sub set_temp_unit {
sub process_data {
eval $start if $b_log;
my (%sensors) = @_;
- my ($cpu_temp,$cpu2_temp,$cpu3_temp,$cpu4_temp,$mobo_temp,$psu_temp);
+ my ($cpu_temp,$cpu2_temp,$cpu3_temp,$cpu4_temp,$mobo_temp,$pch_temp,$psu_temp);
my ($fan_type,$i,$j,$index_count_fan_default,$index_count_fan_main) = (0,0,0,0,0);
my $temp_diff = 20; # for C, handled for F after that is determined
my (@fan_main,@fan_default);
@@ -19823,12 +20974,13 @@ sub process_data {
$cpu3_temp = $sensors{'cpu3-temp'} if $sensors{'cpu3-temp'};
$cpu4_temp = $sensors{'cpu4-temp'} if $sensors{'cpu4-temp'};
$ambient_temp = $sensors{'ambient-temp'} if $sensors{'ambient-temp'};
+ $pch_temp = $sensors{'pch-temp'} if $sensors{'pch-temp'};
$psu_fan = $sensors{'fan-psu'} if $sensors{'fan-psu'};
$psu1_fan = $sensors{'fan-psu-1'} if $sensors{'fan-psu-1'};
$psu2_fan = $sensors{'fan-psu-2'} if $sensors{'fan-psu-2'};
# so far only for ipmi, sensors data is junk for volts
- if ($extra > 0 &&
- ($sensors{'volts-12'} || $sensors{'volts-5'} || $sensors{'volts-3.3'} || $sensors{'volts-vbat'})){
+ if ($extra > 0 && ($sensors{'volts-12'} || $sensors{'volts-5'} ||
+ $sensors{'volts-3.3'} || $sensors{'volts-vbat'})){
$v_12 = $sensors{'volts-12'} if $sensors{'volts-12'};
$v_5 = $sensors{'volts-5'} if $sensors{'volts-5'};
$v_3_3 = $sensors{'volts-3.3'} if $sensors{'volts-3.3'};
@@ -19845,6 +20997,7 @@ sub process_data {
'cpu3-temp' => $cpu3_temp,
'cpu4-temp' => $cpu4_temp,
'mobo-temp' => $mobo_temp,
+ 'pch-temp' => $pch_temp,
'psu-temp' => $psu_temp,
'temp-unit' => $sensors{'temp-unit'},
'fan-main' => \@fan_main,
@@ -19979,7 +21132,7 @@ sub gpu_data {
# print "temp: $_\n";
}
# speeds can be in percents or rpms, so need the 'fan' in regex
- elsif (/^.*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'} = '';
@@ -20010,12 +21163,12 @@ sub get {
my (@rows,$key1,$val1);
my $num = 0;
if ($fake{'dmidecode'} || ($alerts{'dmidecode'}->{'action'} eq 'use' &&
- (!$b_arm || $use{'slot-tool'}))){
+ (!%risc || $use{'slot-tool'}))){
@rows = slot_output();
}
- elsif ($b_arm && !$use{'slot-tool'}){
- $key1 = 'ARM';
- $val1 = main::row_defaults('arm-pci','');
+ elsif (%risc && !$use{'slot-tool'}){
+ $key1 = 'Message';
+ $val1 = main::message('risc-pci',$risc{'id'});
@rows = ({main::key($num++,0,1,$key1) => $val1,});
}
elsif ($alerts{'dmidecode'}->{'action'} ne 'use'){
@@ -20080,7 +21233,7 @@ sub slot_output {
if (!@rows){
my $key = 'Message';
push(@rows, {
- main::key($num++,0,1,$key) => main::row_defaults('pci-slot-data',''),
+ main::key($num++,0,1,$key) => main::message('pci-slot-data',''),
},);
}
eval $end if $b_log;
@@ -20099,7 +21252,7 @@ sub get {
@rows = create_output();
if (!@rows){
push(@rows,
- {main::key($num++,0,1,'Alert') => main::row_defaults('swap-data')},
+ {main::key($num++,0,1,'Alert') => main::message('swap-data')},
);
}
eval $end if $b_log;
@@ -20133,7 +21286,7 @@ sub create_output {
}
}
else {
- $rows[$j]->{main::key($num++,0,1,'Message')} = main::row_defaults('swap-admin');
+ $rows[$j]->{main::key($num++,0,1,'Message')} = main::message('swap-admin');
}
}
$j = scalar @rows;
@@ -20172,14 +21325,14 @@ sub create_output {
}
if ($show{'label'} && ($row->{'label'} || $row->{'swap-type'} eq 'partition')){
if ($use{'filter-label'}){
- $row->{'label'} = main::apply_partition_filter('part', $row->{'label'}, '');
+ $row->{'label'} = main::filter_partition('part', $row->{'label'}, '');
}
$row->{'label'} ||= 'N/A';
$rows[$j]->{main::key($num++,0,2,'label')} = $row->{'label'};
}
if ($show{'uuid'} && ($row->{'uuid'} || $row->{'swap-type'} eq 'partition')){
if ($use{'filter-uuid'}){
- $row->{'uuid'} = main::apply_partition_filter('part', $row->{'uuid'}, '');
+ $row->{'uuid'} = main::filter_partition('part', $row->{'uuid'}, '');
}
$row->{'uuid'} ||= 'N/A';
$rows[$j]->{main::key($num++,0,2,'uuid')} = $row->{'uuid'};
@@ -20206,7 +21359,7 @@ sub get {
@data = bsd_data();
if (!@data){
$key1 = 'Message';
- $val1 = main::row_defaults('unmounted-data');
+ $val1 = main::message('unmounted-data');
}
else {
@rows = create_output(\@data);
@@ -20219,7 +21372,7 @@ sub get {
}
else {
$key1 = 'Message';
- $val1 = main::row_defaults('unmounted-data-bsd',$uname[0]);
+ $val1 = main::message('unmounted-data-bsd',$uname[0]);
}
}
}
@@ -20228,7 +21381,7 @@ sub get {
@data = proc_data();
if (!@data){
$key1 = 'Message';
- $val1 = main::row_defaults('unmounted-data');
+ $val1 = main::message('unmounted-data');
}
else {
@rows = create_output(\@data);
@@ -20236,7 +21389,7 @@ sub get {
}
else {
$key1 = 'Message';
- $val1 = main::row_defaults('unmounted-file');
+ $val1 = main::message('unmounted-file');
}
}
if (!@rows && $key1){
@@ -20263,10 +21416,10 @@ sub create_output {
$fs = 'N/A';
}
elsif (main::check_program('file')){
- $fs = ($b_root) ? 'N/A' : main::row_defaults('root-required');
+ $fs = ($b_root) ? 'N/A' : main::message('root-required');
}
else {
- $fs = main::row_defaults('tool-missing-basic','file');
+ $fs = main::message('tool-missing-basic','file');
}
}
$j = scalar @rows;
@@ -20287,14 +21440,14 @@ sub create_output {
if (($show{'label'} || $show{'uuid'}) && $fs !~ /^$fs_skip$/){
if ($show{'label'}){
if ($use{'filter-label'}){
- $row->{'label'} = main::apply_partition_filter('part', $row->{'label'}, '');
+ $row->{'label'} = main::filter_partition('part', $row->{'label'}, '');
}
$row->{'label'} ||= 'N/A';
$rows[$j]->{main::key($num++,0,2,'label')} = $row->{'label'};
}
if ($show{'uuid'}){
if ($use{'filter-uuid'}){
- $row->{'uuid'} = main::apply_partition_filter('part', $row->{'uuid'}, '');
+ $row->{'uuid'} = main::filter_partition('part', $row->{'uuid'}, '');
}
$row->{'uuid'} ||= 'N/A';
$rows[$j]->{main::key($num++,0,2,'uuid')} = $row->{'uuid'};
@@ -20505,7 +21658,7 @@ sub get {
if ($alerts{'usbdevs'}->{'action'} eq 'missing' &&
$alerts{'usbconfig'}->{'action'} eq 'missing'){
$key1 = $alerts{'usbdevs'}->{'action'};
- $val1 = main::row_defaults('tools-missing-bsd','usbdevs/usbconfig');
+ $val1 = main::message('tools-missing-bsd','usbdevs/usbconfig');
}
elsif ($alerts{'usbconfig'}->{'action'} eq 'permissions'){
$key1 = $alerts{'usbconfig'}->{'action'};
@@ -20524,7 +21677,7 @@ sub get {
if (!@rows){
my $key = 'Message';
push(@rows, {
- main::key($num++,0,1,$key) => main::row_defaults('usb-data',''),
+ main::key($num++,0,1,$key) => main::message('usb-data',''),
},);
}
}
@@ -20546,8 +21699,8 @@ sub usb_output {
($driver,$path_id,$ports,$product,
$serial,$speed,$type) = ('','','','','','','');
$speed = (main::is_numeric($id->[8])) ? sprintf("%1.1f",$id->[8]) : $id->[8] if $id->[8];
- $product = main::cleaner($id->[13]) if $id->[13];
- $serial = main::apply_filter($id->[16]) if $id->[16];
+ $product = main::clean($id->[13]) if $id->[13];
+ $serial = main::filter($id->[16]) if $id->[16];
$product ||= 'N/A';
$speed ||= 'N/A';
$path_id = $id->[2] if $id->[2];
@@ -20605,7 +21758,7 @@ sub usb_output {
}
if (!$b_hub && $extra > 2){
if ($serial){
- $rows[$j]->{main::key($num++,0,$ind_sc,'serial')} = main::apply_filter($serial);
+ $rows[$j]->{main::key($num++,0,$ind_sc,'serial')} = main::filter($serial);
}
}
}
@@ -20647,26 +21800,26 @@ sub weather_output {
}
$location_string = $string;
}
- $location_string = main::apply_filter($location_string);
+ $location_string = main::filter($location_string);
@location = ($show{'weather-location'},$location_string,'');
}
else {
@location = get_location();
if (!$location[0]){
return @rows = ({
- main::key($num++,0,1,'Message') => main::row_defaults('weather-null','current location'),
+ main::key($num++,0,1,'Message') => main::message('weather-null','current location'),
});
}
}
%weather = get_weather(\@location);
if ($weather{'error'}){
return @rows = ({
- main::key($num++,0,1,'Message') => main::row_defaults('weather-error',$weather{'error'}),
+ main::key($num++,0,1,'Message') => main::message('weather-error',$weather{'error'}),
});
}
if (!$weather{'weather'}){
return @rows = ({
- main::key($num++,0,1,'Message') => main::row_defaults('weather-null','weather data'),
+ main::key($num++,0,1,'Message') => main::message('weather-null','weather data'),
});
}
$conditions = "$weather{'weather'}";
@@ -21240,7 +22393,7 @@ sub get_location {
$country = ($loc{'country3'}) ? $loc{'country3'} : $loc{'country'};
$city = ($loc{'city'}) ? $loc{'city'} : 'City N/A';
$state = ($loc{'region-id'}) ? $loc{'region-id'} : 'Region N/A';
- $loc_string = main::apply_filter("$city, $state, $country");
+ $loc_string = main::filter("$city, $state, $country");
my @location = ($loc_arg,$loc_string,$loc{'tz'});
# print ($loc_arg,"\n", join("\n", @loc_data), "\n",scalar @loc_data, "\n");
eval $end if $b_log;
@@ -21701,7 +22854,7 @@ sub get_kde_trinity_data {
$desktop[0] = 'KDE Plasma';
}
if (!$desktop[1]){
- $desktop[1] = ($kde_session_version) ? $kde_session_version: main::row_defaults('unknown-desktop-version');
+ $desktop[1] = ($kde_session_version) ? $kde_session_version: main::message('unknown-desktop-version');
}
# print Data::Dumper::Dumper \@version_data;
if ($extra > 1){
@@ -22294,7 +23447,7 @@ sub set {
# ! -d '/proc/bus/pci'
# this is sketchy, a sbc won't have pci, but a non sbc arm may have it, so
# build up both and see what happens
- if ($b_arm || $b_mips || $b_ppc || $b_sparc){
+ if (%risc){
soc_data();
}
}
@@ -22351,9 +23504,9 @@ sub lspci_data {
$subsystem_id = $1;
$subsystem = (split(/^Subsystem:\s*/, $_))[1];
$subsystem =~ s/(\s?\[[^\]]+\])+$//g;
- $subsystem = main::cleaner($subsystem);
- $subsystem = main::pci_cleaner($subsystem,'pci');
- $subsystem = main::pci_cleaner_subsystem($subsystem);
+ $subsystem = main::clean($subsystem);
+ $subsystem = main::clean_pci($subsystem,'pci');
+ $subsystem = main::clean_pci_subsystem($subsystem);
# print "ss:$subsystem\n";
}
elsif ($_ =~ /^I\/O\sports/){
@@ -22384,7 +23537,7 @@ sub lspci_data {
$type_id = $3;
$_ =~ s/^\Q$1\E//;
$type = lc($type);
- $type = main::pci_cleaner($type,'pci');
+ $type = main::clean_pci($type,'pci');
$type =~ s/\s+$//;
}
# trim off end prog-if and rev items
@@ -22411,7 +23564,7 @@ sub lspci_data {
}
$device = $_;
# cases of corrupted string set to ''
- $device = main::cleaner($device);
+ $device = main::clean($device);
# corrupted lspci truncation bug; and ancient lspci, 2.4 kernels
if (!$vendor_id){
my @temp = lspci_n_data($busid_full);
@@ -22441,6 +23594,7 @@ sub lspci_n_data {
my (@data);
if ($fake{'lspci'}){
# my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/lspci/steve-mint-topaz-lspci-n.txt";
+ # my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/lspci/ben81-hwraid-lspci-n.txt";
# @data = main::reader($file,'strip');
}
else {
@@ -22473,13 +23627,13 @@ sub pciconf_data {
foreach (@data){
if ($driver){
if ($_ =~ /^~$/){
- $vendor = main::cleaner($vendor);
- $device = main::cleaner($device);
+ $vendor = main::clean($vendor);
+ $device = main::clean($device);
# handle possible regex in device name, like [ConnectX-3]
# and which could make matches fail
- my $device_temp = main::regex_cleaner($device);
+ my $device_temp = main::clean_regex($device);
if ($vendor && $device){
- if (main::regex_cleaner($vendor) !~ /\Q$device_temp\E/i){
+ if (main::clean_regex($vendor) !~ /\Q$device_temp\E/i){
$device = "$vendor $device";
}
}
@@ -22557,7 +23711,7 @@ sub pcidump_data {
$busid = $1;
$busid_nu = $2;
($driver,$driver_nu) = pcidump_driver("$busid:$busid_nu") if $dboot{'pci'};
- $device = main::cleaner($3);
+ $device = main::clean($3);
}
elsif ($_ =~ /^0x[\S]{4}:\s+Vendor ID:\s+([0-9a-f]{4}),?\s+Product ID:\s+([0-9a-f]{4})/){
$vendor_id = $1;
@@ -22615,7 +23769,7 @@ sub pcictl_data {
if ($_ =~ /^([0-9a-f:]+):([0-9]+):\s+([^.]+?)$/i){
$busid = $1;
$busid_nu = $2;
- $device = main::cleaner($3);
+ $device = main::clean($3);
my $working = (grep {/^${busid}:${busid_nu}:\s/} @data2)[0];
if ($working &&
$working =~ /^${busid}:${busid_nu}:\s+0x([0-9a-f]{4})([0-9a-f]{4})\s+\(0x([0-9a-f]{2})([0-9a-f]{2})[0-9a-f]+\)/){
@@ -22669,6 +23823,7 @@ sub pci_grabber {
# my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/lspci/rk016013-knnv.txt";
# my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/lspci/kot--book-lspci-nnv.txt";
# my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/lspci/steve-mint-topaz-lspci-nnkv.txt";
+ # my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/lspci/ben81-hwraid-lspci-nnv.txt";
# @data = main::reader($file,'strip');
}
else {
@@ -22886,7 +24041,7 @@ sub assign_data {
$use{'soc-timer'} = 1 if $tool eq 'soc';
}
# not used at this point, -M comes before ANG
- # $device_vm = check_vm($data[4]) if ((!$b_ppc && !$b_mips) && !$device_vm);
+ # $device_vm = check_vm($data[4]) if ((!$risc{'ppc'} && !$risc{'mips'}) && !$device_vm);
push(@devices,[@$data]);
}
# note: for soc, these have been converted in soc_type()
@@ -23123,7 +24278,7 @@ sub set_dboot_disks {
$disks_bsd{$id}->{'speed'} = $1;
$disks_bsd{$id}->{'speed'} =~ s/\.[0-9]+// if $disks_bsd{$id}->{'speed'};
}
- $disks_bsd{$id}->{'model'} = main::disk_cleaner($disks_bsd{$id}->{'model'});
+ $disks_bsd{$id}->{'model'} = main::clean_disk($disks_bsd{$id}->{'model'});
if (!$disks_bsd{$id}->{'serial'} && $show{'disk'} && $extra > 1 &&
$alerts{'bioctl'}->{'action'} eq 'use'){
$disks_bsd{$id}->{'serial'} = bioctl_data($id);
@@ -23164,7 +24319,7 @@ sub set_disklabel_data {
main::log_data('dump','disklabel @data', \@data) if $b_log;
if (scalar @data < 4 && (grep {/permission/i} @data)){
$alerts{'disklabel'}->{'action'} = 'permissions';
- $alerts{'disklabel'}->{'message'} = main::row_defaults('root-feature');
+ $alerts{'disklabel'}->{'message'} = main::message('root-feature');
last;
}
else {
@@ -23406,7 +24561,7 @@ sub get_bsd_os {
@working = main::reader($distro_file);
@working = grep {/(ProductName|ProductVersion)/} @working if @working;
@working = grep {/<string>/} @working if @working;
- @working = map {s/<[\/]?string>//g; } @working if @working;
+ @working = map {s/<[\/]?string>//g;} @working if @working;
$distro = join(' ', @working);
}
}
@@ -24253,7 +25408,7 @@ sub get_init_data {
# output: /sbin/init --version: init (upstart 1.1)
# init (upstart 0.6.3)
# openwrt /sbin/init hangs on --version command, I think
- if ((!$b_mips && !$b_sparc && !$b_arm) &&
+ if (!%risc &&
($init_version = program_version('init', 'upstart', '3','--version'))){
$init = 'Upstart';
}
@@ -24501,9 +25656,8 @@ sub get_kernel_bits {
$bits = (grabber("$program LONG_BIT 2>/dev/null"))[0];
}
# fallback test
- if (!$bits && @uname){
- $bits = $uname[-1];
- $bits = ($bits =~ /64/) ? 64 : 32;
+ if (!$bits && $bits_sys){
+ $bits = $bits_sys;
}
$bits ||= 'N/A';
eval $end if $b_log;
@@ -24530,6 +25684,7 @@ sub parameters_linux {
my ($file) = @_;
# unrooted android may have file only root readable
my $line = main::reader($file,'',0) if -r $file;
+ $line =~ s/\s\s+/ /g;
eval $end if $b_log;
return $line;
}
@@ -24699,7 +25854,7 @@ sub meminfo_data {
$available = main::get_piece($_,2);
}
}
- $gpu = gpu_ram_arm() if $b_arm;
+ $gpu = gpu_ram_arm() if $risc{'arm'};
#$gpu = main::translate_size('128M');
$total += $gpu;
if ($available){
@@ -24921,7 +26076,7 @@ sub create_output {
$total = 'N/A';
}
else {
- $total = main::row_defaults('package-data');
+ $total = main::message('package-data');
}
}
if ($counts{'total'} && $extra > 1){
@@ -25027,7 +26182,7 @@ sub package_counts {
}
else {
@list = undef;
- $error = main::row_defaults('pm-disabled');
+ $error = main::message('pm-disabled');
}
$libs = undef;
# print Data::Dumper::Dumper \@list;
@@ -25125,7 +26280,7 @@ sub get_pci_vendor {
my ($vendor,$sep,$temp) = ('','','');
# get rid of any [({ type characters that will make regex fail
# and similar matches show as non-match
- $subsystem = regex_cleaner($subsystem);
+ $subsystem = clean_regex($subsystem);
my @data = split(/\s+/, $subsystem);
# when using strings in patterns for regex have to escape them
foreach (@data){
@@ -25172,6 +26327,9 @@ sub set_ps_aux {
my $final = $#split;
# some stuff has a lot of data, chrome for example
$final = ($final > ($ps_cols + 2)) ? $ps_cols + 2 : $final;
+ # handle case of ps wrapping lines despite ww unlimited width, which
+ # should NOT be happening, but is.
+ next if !defined $split[$ps_cols];
if ($split[$ps_cols] !~ /^\[/){
push(@ps_cmd,join(' ', @split[$ps_cols .. $final]));
}
@@ -25578,7 +26736,7 @@ sub set {
}
}
else {
- $client{'version'} = main::row_defaults('unknown-shell');
+ $client{'version'} = main::message('unknown-shell');
}
print "6: shell not app version: $client{'version'}\n" if $b_debug;
}
@@ -25836,8 +26994,8 @@ sub set_sysctl_data {
}
# Must go AFTER sensor because sometimes freebsd puts sensors in dev.cpu
# hw.l1dcachesize hw.l2cachesize
- elsif ($use{'bsd-cpu'} && (/^hw\.(busfreq|clock|n?cpu|l[123].?cach|model)/ ||
- /^dev\.cpu/ || /^machdep\.cpu/)){
+ elsif ($use{'bsd-cpu'} && (/^hw\.(busfreq|clock|n?cpu|l[123].?cach|model|smt)/ ||
+ /^dev\.cpu/ || /^machdep\.(cpu|hlt_logical_cpus)/)){
push(@{$sysctl{'cpu'}}, $_);
}
# only activate if using the diskname feature in dboot!!
@@ -26151,17 +27309,17 @@ sub usbconfig_data {
$product_id = $1;
}
elsif (/^iManufacturer\s*=\s*0x([a-f0-9]{4})\s*(<([^>]+)>)?/){
- $vendor = main::cleaner($3);
+ $vendor = main::clean($3);
$vendor =~ s/^0x.*//; # seen case where vendor string was ID
$working[11] = $vendor;
}
elsif (/^iProduct\s*=\s*0x([a-f0-9]{4})\s*(<([^>]+)>)?/){
- $product = main::cleaner($3);
+ $product = main::clean($3);
$product =~ s/^0x.*//; # in case they put product ID in, sigh
$working[12] = $product;
}
elsif (/^iSerialNumber\s*=\s*0x([a-f0-9]{4})\s*(<([^>]+)>)?/){
- $working[16] = main::cleaner($3);
+ $working[16] = main::clean($3);
}
}
main::log_data('dump','$usb{main}: usbconfig',$usb{'main'}) if $b_log;
@@ -26266,7 +27424,7 @@ sub usbdevs_data {
elsif (/^addr\s*([0-9a-f]+):\s+([a-f0-9]{4}:[a-f0-9]{4})\s*([^,]+)?(,\s[^,]+?)?,\s+([^,]+)$/){
$addr_id = $1;
$chip_id = $2;
- $vendor = main::cleaner($3) if $3;
+ $vendor = main::clean($3) if $3;
$vendor ||= '';
$name = main::remove_duplicates("$vendor $5");
$type = check_type($name,'','');
@@ -26415,7 +27573,11 @@ sub sys_data {
# this will be a hex number
$class_id = sys_item("$_/bDeviceClass");
# $subclass_id = sys_item("$_/bDeviceSubClass");
+ # $protocol_id = sys_item("$_/bDeviceProtocol");
$class_id = hex($class_id) if $class_id;
+ # $subclass_id = hex($subclass_id) if $subclass_id;
+ # $protocol_id = hex($protocol_id) if $protocol_id;
+ # print "$path_id $class_id/$subclass_id/$protocol_id\n";
$power = sys_item("$_/bMaxPower");
process_power(\$power) if $power;
# this populates class, subclass, and protocol id with decimal numbers
@@ -26474,9 +27636,9 @@ sub sys_data {
# we don't want the device, it's probably a bad path in /sys/bus/usb/devices
next if !$vendor_id && !$chip_id;
$product = sys_item("$_/product");
- $product = main::cleaner($product) if $product;
+ $product = main::clean($product) if $product;
$vendor = sys_item("$_/manufacturer");
- $vendor = main::cleaner($vendor) if $vendor;
+ $vendor = main::clean($vendor) if $vendor;
if (!$b_hub && ($product || $vendor)){
if ($vendor && $product && $product !~ /$vendor/){
$name = "$vendor $product";
@@ -26545,8 +27707,14 @@ sub uevent_data {
# print join("\n",@working), "\n";
if (@working){
$driver = main::awk(\@working,'^DRIVER',2,'=');
- $interface = main::awk(\@working,'^INTERFACE',2,'=');
+ $interface = main::awk(\@working,'^INTERFACE',2,'=');
if ($interface){
+ # for hubs, we need the specific protocol, which is in TYPE
+ if ($interface eq '9/0/0' &&
+ (my $temp = main::awk(\@working,'^TYPE',2,'='))){
+ $interface = $temp;
+ }
+ # print "$interface\n";
$interface = device_type($interface);
if ($interface){
if ($interface ne '<vendor specific>'){
@@ -26661,10 +27829,15 @@ sub device_type {
elsif ($types[0] eq '6'){$type = 'Still Imaging';}
elsif ($types[0] eq '7'){$type = 'Printer';}
elsif ($types[0] eq '8'){$type = 'Mass Storage';}
+ # note: there is a bug in linux kernel that always makes hubs 9/0/0
elsif ($types[0] eq '9'){
- if ($types[2] eq '0'){$type = 'Full speed (or root) Hub';}
+ if ($types[2] eq '0'){$type = 'Full speed or root hub';}
elsif ($types[2] eq '1'){$type = 'Hi-speed hub with single TT';}
elsif ($types[2] eq '2'){$type = 'Hi-speed hub with multiple TTs';}
+ # seen protocol 3, usb3 type hub, but not documented on usb.org
+ elsif ($types[2] eq '3'){$type = 'Super-speed hub';}
+ # this is a guess, never seen it
+ elsif ($types[2] eq '4'){$type = 'Super-speed+ hub';}
}
elsif ($types[0] eq '10'){$type = 'CDC-Data';}
elsif ($types[0] eq '11'){$type = 'Smart Card';}
@@ -26779,6 +27952,12 @@ sub prep_speed {
elsif ($_[0] =~ /^([0-9\.]+)+\s*Gb/){
$speed = $1 * 1000;
}
+ elsif ($_[0] =~ /usb\s?40/i){
+ $speed = 40000;# 4 40gbps
+ }
+ elsif ($_[0] =~ /usb\s?20/i){
+ $speed = 20000;# 4 20gbps
+ }
# could be 3.2, 20000 too, also superspeed+
elsif ($_[0] =~ /super[\s-]?speed\s?(\+|plus)/i){
$speed = 10000;# 3.1; # can't trust bsds to use superspeed+ but we'll hope
@@ -26814,7 +27993,7 @@ sub bus_id_alpha {
# note: seen instance in android where reading file hangs endlessly!!!
sub get_wakeups {
eval $start if $b_log;
- return if $b_arm || $b_mips || $b_ppc;
+ return if %risc;
my ($wakeups);
my $path = '/sys/power/wakeup_count';
$wakeups = reader($path,'strip',0) if -r $path;
@@ -26875,7 +28054,7 @@ sub generate {
assign_data(\%row);
}
if ($show{'cpu'} || $show{'cpu-basic'}){
- DeviceData::set(\$checks{'device'}) if $b_arm && !$checks{'device'};
+ DeviceData::set(\$checks{'device'}) if %risc && !$checks{'device'};
DmidecodeData::set(\$checks{'dmi'}) if $use{'dmidecode'} && !$checks{'dmi'};
my $arg = ($show{'cpu-basic'}) ? 'basic' : 'full' ;
%row = item_handler('CPU','cpu',$arg);
@@ -26975,14 +28154,13 @@ sub short_output {
($speed,$speed_key) = ('','');
if ($cpu[6]){
$speed_key = "$cpu[3]/$cpu[5]";
- $cpu[4] =~ s/ MHz//;
- $speed = "$cpu[4]/$cpu[6]";
+ $speed = "$cpu[4]/$cpu[6] MHz";
}
else {
$speed_key = $cpu[3];
- $speed = $cpu[4];
+ $speed = "$cpu[4] MHz";
}
- $cpu[1] ||= main::row_defaults('cpu-model-null');
+ $cpu[1] ||= main::message('cpu-model-null');
$cpu_string = $cpu[0] . ' ' . $cpu[1] . $type;
}
elsif ($bsd_type){
@@ -26997,6 +28175,7 @@ sub short_output {
}
}
}
+ $speed ||= 'N/A'; # totally unexpected situation, what happened?
my @disk = DriveItem::get('short');
# print Dumper \@disk;
my $disk_string = 'N/A';
@@ -27020,7 +28199,7 @@ sub short_output {
$disk_string = "$size$percent";
}
else {
- $size ||= main::row_defaults('disk-size-0');
+ $size ||= main::message('disk-size-0');
$disk_string = "$used/$size";
}
}
@@ -27231,13 +28410,13 @@ sub system_item {
}
}
if ($b_admin && (my $params = KernelParameters::get())){
- $index = scalar(@{$data{$data_name}});
+ # $index = scalar(@{$data{$data_name}}); # not on own line for now
# print "$params\n";
if ($use{'filter-label'}){
- $params = main::apply_partition_filter('system', $params, 'label');
+ $params = main::filter_partition('system', $params, 'label');
}
if ($use{'filter-uuid'}){
- $params = main::apply_partition_filter('system', $params, 'uuid');
+ $params = main::filter_partition('system', $params, 'uuid');
}
$data{$data_name}->[$index]{main::key($num++,0,2,'parameters')} = $params;
$index = scalar(@{$data{$data_name}});
diff --git a/inxi.1 b/inxi.1
index b2b7351..b0f5385 100644
--- a/inxi.1
+++ b/inxi.1
@@ -15,7 +15,7 @@
.\" with this program; if not, write to the Free Software Foundation, Inc.,
.\" 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
.\"
-.TH INXI 1 "2021\-10\-11" "inxi" "inxi manual"
+.TH INXI 1 "2021\-12\-13" "inxi" "inxi manual"
.SH NAME
inxi \- Command line system information script for console and IRC
@@ -23,7 +23,7 @@ inxi \- Command line system information script for console and IRC
.SH SYNOPSIS
\fBinxi\fR
-\fBinxi\fR [\fB\-AbBCdDEfFGhiIjJlLmMnNopPrRsSuUVwzZ\fR]
+\fBinxi\fR [\fB\-AbBCdDEfFGhiIjJlLmMnNopPrRsSuUVwyYzZ\fR]
\fBinxi\fR [\fB\-c NUMBER\fR]
[\fB\-\-sensors\-exclude SENSORS\fR] [\fB\-\-sensors\-use SENSORS\fR]
@@ -78,19 +78,37 @@ 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.
+These are avalable options sections:
+
+* \fBSTANDARD OPTIONS\fR Primary data types trigger items.
+
+* \fBFILTER OPTIONS\fR Apply a variety of output filters.
+
+* \fBOUTPUT CONTROL OPTIONS\fR Change default colors, widths, heights, output
+types, etc.
+
+* \fBEXTRA DATA OPTIONS\fR What \fB\-x\fR, \fB\-xx\fR, \fB\-xxx\fR, and \fB\-a\fR
+add to the output.
+
+* \fBADVANCED OPTIONS\fR Modify behavior or choice of data sources, and other
+advanced switches.
+
+* \fBDEBUGGING OPTIONS\fR For development use mainly, or contributing datasets to
+the project.
+
.SH STANDARD OPTIONS
.TP
-.B \-A\fR,\fB \-\-audio\fR
+.B \-A \fR, \fB\-\-audio\fR
Show Audio/sound device(s) information, including device driver. Show running
sound server(s). See \fB\-xxA\fR to show all sound servers detected.
.TP
-.B \-b\fR,\fB \-\-basic\fR
+.B \-b \fR, \fB\-\-basic\fR
Show basic output, short form. Same as: \fBinxi \-v 2\fR
.TP
-.B \-B\fR,\fB \-\-battery\fR
+.B \-B \fR, \fB\-\-battery\fR
Show system battery (\fBID\-x\fR) data, charge, condition, plus extra
information (if battery present). Uses \fB/sys\fR or, for BSDs without systctl
battery data, use \fB\-\-dmidecode\fR to force its use. \fBdmidecode\fR does
@@ -122,67 +140,35 @@ With \fB\-x\fR shows attached \fBDevice\-x\fR information (mouse, keyboard,
etc.) if they are battery powered.
.TP
-.B \-\-bluetooth\fR \- See \fB\-E\fR
+.B \-\-bluetooth\fR
+.br
+See \fB\-E\fR.
.TP
-.B \-c\fR,\fB \-\-color\fR \fR[\fB0\fR\-\fB42\fR]
-Set color scheme. If no scheme number is supplied, 0 is assumed.
+.B \-c \fR, \fB\-\-color\fR
+.br
+See \fBOUTPUT CONTROL OPTIONS\fR.
.TP
-.B \-c \fR[\fB94\fR\-\fB99\fR]
-
-These color selectors run a color selector option prior to inxi starting
-which lets you set the config file value for the selection.
-
-NOTE: All configuration file set color values are removed when output is
-piped or redirected. You must use the explicit runtime \fB\-c <color number>\fR
-option 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):
+.B \-C \fR, \fB\-\-cpu\fR
+Show full CPU output (if each item available): basic CPU topology, model, type,
+L2 cache, average speed of all cores (if > 1 core, otherwise speed of the core),
+min/max speeds for CPU, and per CPU clock speed. More data available with
+\fB\-x\fR, \fB\-xxx\fR, and \fB\-a\fR options.
-.TP
-.B \-c 94\fR
-\- Console, out of X.
+Explanation of CPU type (\fBtype: MT MCP\fR) abbreviations:
-.TP
-.B \-c 95\fR
-\- Terminal, running in X \- like xTerm.
+* \fBAMCP\fR \- Asymmetric Multi Core Processor. More than 1 core per CPU, and
+more than one core type (single and multithreaded cores in the same CPU).
-.TP
-.B \-c 96\fR
-\- GUI IRC, running in X \- like XChat, Quassel,
-Konversation etc.
+* \fBAMP\fR \- Asymmetric Multi Processing (more than 1 physical CPU, but not
+identical in terms of core counts or min/max speeds).
-.TP
-.B \-c 97\fR
-\- Console IRC running in X \- like irssi in xTerm.
+* \fBMT\fR \- Multi/Hyper Threaded CPU (more than 1 thread per core, previously
+\fBHT\fR).
-.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). If max speed data present, shows \fB(max)\fR in short output
-formats (\fBinxi\fR, \fBinxi \-b\fR) if actual CPU speed matches max CPU
-speed. If max CPU speed does not match actual CPU speed, shows both actual
-and max speed information. See \fB\-x\fR for more options.
-
-For certain CPUs (some ARM, and AMD Zen family) shows CPU die count.
-
-The details for each CPU include a technical description e.g. \fBtype: MT
-MCP\fR
-
-* \fBMT\fR \- Multi/Hyper Threaded CPU, more than 1 thread per core
-(previously \fBHT\fR).
+* \fBMST\fR \- Multi and Single Threaded CPU (a CPU with both Single and Multi
+Threaded cores).
* \fBMCM\fR \- Multi Chip Model (more than 1 die per CPU).
@@ -194,10 +180,19 @@ MCP\fR
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.
+\fBbase/boost:\fR speed data, more granular cache data, and more.
+
+Sample:
+.nf
+\fBCPU:
+ Info: 2x 8\-core model: Intel Xeon E5\-2620 v4 bits: 64 type: MT MCP SMP
+ cache: L2: 2x 2 MiB (4 MiB)
+ Speed (MHz): avg: 1601 min/max: 1200/3000 cores: 1: 1280 2: 1595 3: 1416
+ ... 32: 1634\fR
+.fi
.TP
-.B \-d\fR,\fB \-\-disk\-full\fR,\fB\-\-optical\fR
+.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
@@ -205,7 +200,7 @@ 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
+.B \-D \fR, \fB\-\-disk\fR
Show Hard Disk info. Shows total disk space and used percentage. The disk used
percentage includes space used by swap partition(s), since those are not usable
for data storage. Also, unmounted partitions are not counted in disk use
@@ -237,7 +232,7 @@ address per device (requires \fBbt\-adapter\fR or \fBhciconfig\fR),
and if available (hciconfig only) bluetooth version (\fBbt\-v\fR).
See \fBExtra Data Options\fR for more.
-If bluetooth shows as \fBstatus: down\fR, shows \fBbt-service:\fR\fB state
+If bluetooth shows as \fBstatus: down\fR, shows \fBbt\-service:\fR\fB state
and rfkill\fR software and hardware blocked states, and rfkill ID.
Note that \fBReport\-ID:\fR indicates that the HCI item was not able to be
@@ -259,27 +254,17 @@ or
\fBrfkill unblock bluetooth\fR
.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.
+.B \-\-filter\fR, \fB\-z\fR
+.br
+See \fBFILTER OPTIONS\fR.
.TP
-.B \-f\fR,\fB \-\-flags\fR
+.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
+.B \-F \fR, \fB\-\-full\fR
Show Full output for inxi. Includes all Upper Case line letters (except
\fB\-J\fR and \fB\-W\fR) plus \fB\-\-swap\fR, \fB\-s\fR and \fB\-n\fR. Does
not show extra verbose options such as \fB\-d \-f \-i -J \-l \-m \-o \-p \-r
@@ -287,7 +272,7 @@ not show extra verbose options such as \fB\-d \-f \-i -J \-l \-m \-o \-p \-r
\fBinxi \-Frmxx\fR
.TP
-.B \-G\fR,\fB \-\-graphics\fR
+.B \-G \fR, \fB\-\-graphics\fR
Show Graphic device(s) information, including details of device and display
drivers (\fBloaded:\fR, and, if applicable: \fBunloaded:\fR, \fBfailed:\fR),
display protocol (if available), display server (and/or Wayland compositor),
@@ -306,21 +291,21 @@ Compositor information will show if detected using \fB\-xx\fR option
or always if detected and Wayland.
.TP
-.B \-h\fR,\fB \-\-help\fR
+.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
+.B \-i \fR, \fB\-\-ip\fR
Show WAN IP address and local interfaces (latter requires \fBifconfig\fR or
\fBip\fR network tool), as well as network output from \fB\-n\fR.
Not shown with \fB\-F\fR for user security reasons. You shouldn't paste your
local/WAN IP. Shows both IPv4 and IPv6 link IP addresses.
.TP
-.B \-I\fR,\fB \-\-info\fR
+.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\-Ix\fR, \fB\-Ixx\fR, and \fB\-Ia\fR
for extra information (init type/version, runlevel, packages).
@@ -341,7 +326,7 @@ To show partition labels or UUIDs (when available and relevant), use with
\fB\-l\fR or\fB \-u\fR.
.TP
-.B \-J\fR,\fB \-\-usb\fR
+.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
@@ -362,7 +347,7 @@ 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
+.B \-l \fR, \fB\-\-label\fR
Show partition labels. Use with \fB\-j\fR, \fB\-o\fR, \fB\-p\fR, and \fB\-P\fR
to show partition labels. Does nothing without one of those options.
@@ -375,7 +360,7 @@ size, free space (for LVM VG). For LVM, shows \fBDevice\-[xx]: VG:\fR
(Volume Group) size/free, \fBLV\-[xx]\fR (Logical Volume). LV shows type,
size, and components. Note that components are made up of either containers
(aka, logical devices), or physical devices. The full report requires
-doas[BSDs]/sudo/root.
+doas/sudo/root.
Logical block devices can be thought of as devices that are made up out
of either other logical devices, or physical devices. inxi does its best
@@ -398,14 +383,13 @@ component belongs to which.
Sample:
-\fBDevice\-10: mybackup type: LUKS dm: dm\-28 size: 6.36 GiB Components:
-c\-1: md1 cc\-1: dm\-26 ppp\-1: sdj2 cc\-2: dm\-27 ppp\-1: sdk2\fR
-
.nf
-\fBLV\-5: lvm_raid1 type: raid1 dm: dm\-16 size: 4.88 GiB
-RAID: stripes: 2 sync: idle copied: 100% mismatches: 0
-Components: c\-1: dm\-10 pp\-1: sdd1 c\-2: dm\-11 pp\-1: sdd1 c\-3: dm\-13
-pp\-1: sde1 c\-4: dm\-15 pp\-1: sde1\fR
+\fB Device\-10: mybackup type: LUKS dm: dm\-28 size: 6.36 GiB Components:
+ c\-1: md1 cc\-1: dm\-26 ppp\-1: sdj2 cc\-2: dm\-27 ppp\-1: sdk2\fR
+ \fBLV\-5: lvm_raid1 type: raid1 dm: dm\-16 size: 4.88 GiB
+ RAID: stripes: 2 sync: idle copied: 100% mismatches: 0
+ Components: c\-1: dm\-10 pp\-1: sdd1 c\-2: dm\-11 pp\-1: sdd1 c\-3: dm\-13
+ pp\-1: sde1 c\-4: dm\-15 pp\-1: sde1\fR
.fi
It is easier to follow the flow of components and devices using \fB\-y1\fR. In
@@ -444,7 +428,7 @@ Other types of logical block handling like LUKS, bcache show as:
\fBDevice\-[xx] [name/id] type: [LUKS|Crypto|bcache]:\fR
.TP
-.B \-m\fR,\fB \-\-memory\fR
+.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 explicitly. Ordered by system board physical system memory
array(s) (\fBArray\-[number]\fR), and individual memory devices
@@ -453,11 +437,11 @@ number of devices supported, and Error Correction information. Devices shows
locator data (highly variable in syntax), size, speed, type
(eg: \fBtype: DDR3\fR).
-Note: \fB\-m\fR uses \fBdmidecode\fR, which must be run as root (or start
-\fBinxi\fR with \fBsudo\fR), unless you figure out how to set up
-doas[BSDs]/sudo to permit dmidecode to read \fB/dev/mem\fR as user.
-\fBspeed\fR and \fBbus\-width\fR will not show if \fBNo Module Installed\fR
-is found in \fBsize\fR.
+Note: \fB\-m\fR uses \fBdmidecode\fR, which must be run as root (or start
+\fBinxi\fR with \fBdoas/sudo\fR), unless you figure out how to set up doas/sudo
+to permit dmidecode to read \fB/dev/mem\fR as user. \fBspeed\fR and
+\fBbus\-width\fR will not show if \fBNo Module Installed\fR is found in
+\fBsize\fR.
Note: If \fB\-m\fR is triggered RAM total/used report will appear in this
section, not in \fB\-I\fR or \fB\-tm\fR items.
@@ -491,10 +475,10 @@ If the detected speed is logically absurd, like 1 MT/s or 69910 MT/s, adds:
Array\-1: capacity: N/A slots: 4 note: check EC: N/A
Device\-1: DIMM_A1 size: 8 GiB speed: 1600 MT/s (800 MHz)
Device\-2: DIMM_A2 size: 8 GiB speed: spec: 1600 MT/s (800 MHz)
- actual: 61910 MT/s (30955 MHz) note: check
+ actual: 61910 MT/s (30955 MHz) note: check
Device\-3: DIMM_B1 size: 8 GiB speed: 1600 MT/s (800 MHz)
Device\-4: DIMM_B2 size: 8 GiB speed: spec: 1600 MT/s (800 MHz)
- actual: 2 MT/s (1 MHz) note: check\fR
+ actual: 2 MT/s (1 MHz) note: check\fR
.fi
See \fB\-\-memory\-modules\fR and \fB\-\-memory\-short\fR if you want a
@@ -512,7 +496,7 @@ 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
+.B \-M \fR, \fB\-\-machine\fR
Show machine data. Device, Motherboard, BIOS, and if present, System Builder
(Like Lenovo). Older systems/kernels without the required \fB/sys\fR data can
use \fBdmidecode\fR instead, run as root. If using \fBdmidecode\fR, may also
@@ -534,17 +518,17 @@ notebook, server, blade, plus some obscure stuff that inxi is unlikely to
ever run on.
.TP
-.B \-n\fR,\fB \-\-network\-advanced\fR
+.B \-n \fR, \fB\-\-network\-advanced\fR
Show Advanced Network device information in addition to that produced by
\fB\-N\fR. Shows interface, speed, MAC ID, state, etc.
.TP
-.B \-N\fR,\fB \-\-network\fR
+.B \-N \fR, \fB\-\-network\fR
Show Network device(s) information, including device driver. With \fB\-x\fR,
shows Bus ID, Port number.
.TP
-.B \-o\fR,\fB \-\-unmounted\fR
+.B \-o \fR, \fB\-\-unmounted\fR
Show unmounted partition information (includes UUID and LABEL if available).
Shows file system type if you have \fBlsblk\fR installed (Linux only). For
BSD/GNU Linux: shows file system type if \fBfile\fR is installed, and if you
@@ -552,7 +536,7 @@ are root or if you have added to \fB/etc/sudoers\fR (sudo v. 1.7 or newer):
.B <username> ALL = NOPASSWD: /usr/bin/file (sample)
-BSD users: see \fBman doas.conf\fR for setup.
+doas users: see \fBman doas.conf\fR for setup.
Does not show components (partitions that create the md\-raid array) of
md\-raid arrays.
@@ -561,7 +545,7 @@ To show partition labels or UUIDs (when available and relevant), use with
\fB\-l\fR or\fB \-u\fR.
.TP
-.B \-p\fR,\fB \-\-partitions\-full\fR
+.B \-p \fR, \fB\-\-partitions\-full\fR
Show full Partition information (\fB\-P\fR plus all other detected mounted
partitions).
@@ -569,7 +553,7 @@ To show partition labels or UUIDs (when available and relevant), use with
\fB\-l\fR or\fB \-u\fR.
.TP
-.B \-P\fR,\fB \-\-partitions\fR
+.B \-P \fR, \fB\-\-partitions\fR
Show basic Partition information.
Shows, if detected: \fB/ /boot /boot/efi /home /opt /tmp /usr /usr/home /var
/var/tmp /var/log\fR (for android, shows \fB/cache /data /firmware /system\fR).
@@ -580,10 +564,12 @@ To show partition labels or UUIDs (when available and relevant), use with
\fB\-l\fR or\fB \-u\fR.
.TP
-.B \-\-processes\fR \- See \fB\-t\fR
+.B \-\-processes\fR
+.br
+See \fB\-t\fR.
.TP
-.B \-r\fR,\fB \-\-repos\fR
+.B \-r \fR, \fB\-\-repos\fR
Show distro repository data. Currently supported repo types:
\fBAPK\fR (Alpine Linux + derived versions)
@@ -628,7 +614,7 @@ See \fB\-rx\fR, \fB\-rxx\fR, and \fB\-ra\fR for installed package count
information.
.TP
-.B \-R\fR,\fB \-\-raid\fR
+.B \-R \fR, \fB\-\-raid\fR
Show RAID data. Shows RAID devices, states, levels, device/array size,
and components. See extra data with \fB\-x\fR / \fB\-xx\fR.
@@ -652,7 +638,7 @@ 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
+.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)
@@ -665,17 +651,19 @@ exclude one.
Show PCI slots with type, speed, and status information.
.TP
-.B \-\-swap\fR \- See \fB\-j\fR
+.B \-\-swap\fR
+.br
+See \fB\-j\fR
.TP
-.B \-S\fR,\fB \-\-system\fR
+.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
+.B \-t \fR, \fB\-\-processes\fR
[\fBc\fR|\fBm\fR|\fBcm\fR|\fBmc NUMBER\fR] Show processes. If no arguments,
defaults to \fBcm\fR. If followed by a number, shows that number of processes
for each type (default: \fB5\fR; if in IRC, max: \fB5\fR)
@@ -699,14 +687,14 @@ system RAM used/total information.
same line.
.TP
-.B \-u\fR,\fB \-\-uuid\fR
+.B \-u \fR, \fB\-\-uuid\fR
Show partition UUIDs. Use with \fB\-j\fR, \fB\-o\fR, \fB\-p\fR, and \fB\-P\fR
to show partition labels. Does nothing without one of those options.
Sample: \fB\-opju\fR.
.TP
-.B \-U\fR,\fB \-\-update\fR
+.B \-U \fR, \fB\-\-update\fR
Note \- Maintainer may have disabled this function.
If inxi \fB\-h\fR has no listing for \fB\-U\fR then it's disabled.
@@ -720,14 +708,16 @@ to that directory. See \fB\-\-man\fR or \fB\-\-no\-man\fR to force or disable
man install.
.TP
-.B \-\-usb\fR \- See \fB\-J\fR
+.B \-\-usb\fR
+.br
+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
+.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.
@@ -739,8 +729,8 @@ Supported levels: \fB0\-8\fR Examples :\fB inxi \-v 4 \fR or \fB inxi \-v4\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.
+\- Basic verbose, \fB\-S\fR + basic CPU (cores, type, average clock speed, and
+min/max speeds, if available) + \fB\-G\fR + basic Disk + \fB\-I\fR.
.TP
.B \-v 2
@@ -754,40 +744,39 @@ speeds, if available) + \fB\-G\fR + basic Disk + \fB\-I\fR.
.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)
+\- 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 device (\fB\-A\fR), memory/RAM (\fB\-m\fR),
-bluetooth data (\fB\-E\fR) (if present), sensors (\fB\-s\fR),
-RAID data (if present), partition label (\fB\-l\fR),
-UUID (\fB\-u\fR), full swap data (\fB\-j\fR), and short form of
-optical drives.
+\- Adds audio device (\fB\-A\fR), memory/RAM (\fB\-m\fR), bluetooth data
+(\fB\-E\fR) (if present), sensors (\fB\-s\fR), RAID data (if present), 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\-J\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), forced bluetooth (\fB\-E\fR),
-Logical (\fB\-L\fR), RAID (\fB\-R\fR); triggers \fB\-xxx\fR
+\- Adds network IP data (\fB\-i\fR), forced bluetooth (\fB\-E\fR), Logical
+(\fB\-L\fR), RAID (\fB\-R\fR), full CPU flags/features (\fB\-f\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.
+\- 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
-\fB\-W [location]\fR. See also \fB\-x\fR, \fB\-xx\fR, \fB\-xxx\fR options.
-Please note that your distribution's maintainer may chose to disable this
-feature.
+.B \-w \fR, \fB\-\-weather\fR
+Adds weather line. To get weather for an alternate location, use \fB\-W
+[location]\fR. See also \fB\-x\fR, \fB\-xx\fR, \fB\-xxx\fR options. Please note
+that your distribution's maintainer may chose to disable this feature.
DO NOT USE THIS FEATURE FOR AUTOMATED WEATHER UPDATES! Automated or excessive
use will lead to your being blocked from any further access. This feature is not
@@ -840,30 +829,239 @@ source message, it means that number has not been implemented.
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.
+.SH FILTER OPTIONS
+The following options allow for applying various types of filtering to the
+output.
+
.TP
-.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. 1 switches to a single indented key/value
-pair per line, and removes all long line wrapping (similar to
-\fBdmidecode\fR output).
+.B \-\-filter \fR, \fB\-\-filter\-override\fR
+.br
+See \fB\-z\fR, \fB\-Z\fR.
-If no integer value is given, sets width to default of 80.
+.TP
+.B \-\-filter\-label\fR, \fB\-\-filter\-uuid\fR, \fB\-\-filter\-vulnerabilities\fR
+.br
+See \fB\-\-zl\fR, \fB\-\-zu\fR, \fB\-\-zv\fR.
-Examples: \fBinxi \-Fxx\ \-y 130\fR or \fBinxi \-Fxxy\fR or \fBinxi \-bay1\fR
+.TP
+.B \-\-host\fR
+Turns on hostname in System line. Overrides inxi config file value (if set):
+
+\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 \-z\fR,\fB \-\-filter\fR
-Adds security filters for IP addresses, serial numbers, MAC,
-location (\fB\-w\fR), and user home directory name. Removes Host:.
-On by default for IRC clients.
+.B \-\-no\-host\fR
+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
+
+This is an absolute override, the host will not show no matter what other
+switches you use.
+
+.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. Removes Host:. On by default for IRC
+clients.
+
+.TP
+.B \-\-zl\fR, \fB\-\-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 \-\-zu\fR, \fB\-\-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 \-Z\fR,\fB \-\-filter\-override\fR
+.B \-\-zv\fR, \fB\-\-filter\-v\fR, \fB\-\-filter\-vulnerabilities\fR
+Filter Vulnerabilities report from \fB\-Ca\fR. Generally only useful in very
+specialized cases.
+
+.TP
+.B \-Z \fR, \fB\-\-filter\-override \fR, \fB\-\-no\-filter\fR
Absolute override for output filters. Useful for debugging networking
issues in IRC for example.
+.SH OUTPUT CONTROL OPTIONS
+The following options allow for modifying the output in various ways.
+
+.TP
+.B \-c \fR, \fB\-\-color\fR \fR[\fB0\fR\-\fB42\fR]
+Set color scheme. If no scheme number is supplied, 0 is assumed.
+
+.TP
+.B \-c \fR[\fB94\fR\-\fB99\fR]
+These color selectors run a color selector option prior to inxi starting
+which lets you set the config file value for the selection.
+
+NOTE: All configuration file set color values are removed when output is
+piped or redirected. You must use the explicit runtime \fB\-c <color number>\fR
+option 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 \-\-indent [11\-xx]\fR
+Change primary wide indent width. Generally useless. Only applied if output
+width is greater than max wrap width (see \fB\-\-max\-wrap\fR). Use
+configuration item \fBINDENT\fR to make permanent.
+
+.TP
+.B \-\-indents [0\-10]\fR
+Change primary wrap mode, second, and -y1 level indents. First indent level only
+applied if output width is less than max wrap width (see \fB\-\-max\-wrap\fR). 0
+disables all wrapped indents and all second level indents. Use configuration
+item \fBINDENTS\fR to make permanent.
+
+.TP
+.B \-\-limit [\-1 \- x]\fR
+Raise or lower max output limit of IP addresses for \fB\-i\fR. \fB\-1\fR
+removes limit.
+
+.TP
+.B \-\-max\-wrap\fR, \fB\-\-wrap\-max [integer]\fR
+Overrides default or configuration set line starter wrap width value. Wrap max
+is the maximum width that inxi will wrap line starters (e.g. \fBInfo:\fR) to
+their own lines, with data lines indented default 2 columns (use
+\fB\-\-indents\fR to change).
+
+If terminal/console width or \fB\-\-width\fR is less than wrap width, wrapping
+of line starter occurs. If \fB80\fR or less, no wrapping will occur. Overrides
+internal default value (110) and user configuration value \fBMAX_WRAP\fR.
+
+.TP
+.B \-\-output [json|screen|xml]\fR
+Change data output type. Requires \-\-output\-file if not \fBscreen\fR.
+
+.TP
+.B \-\-output\-file [full path to output file|print]\fR
+The given directory path must exist. The directory path given must exist,
+The \fBprint\fR options prints to stdout.
+Required for non\-screen \fB\-\-output\fR formats (json|xml).
+
+.TP
+.B \-\-partition\-sort [dev\-base|fs|id|label|percent\-used|size|uuid|used]\fR
+Change default sort order of partition output. Corresponds to
+\fBPARTITION_SORT\fR 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 filesystems are the same.
+
+\fBid\fR \- Mount point of partition (default).
+
+\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.
+
+\fBuuid\fR \- UUID of the partition.
+
+\fBused\fR \- KiB used of partition.
+
+.TP
+.B \-\-wrap\-max [integer]\fR
+.br
+See \fB\-\-max-wrap\fR.
+
+.TP
+.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_NO_DISPLAY\fR, \fBCOLS_MAX_CONSOLE\fR
+configuration items, or the actual widths of the terminal.
+
+* \fB\-y\fR \- sets default width of 80 columns.
+.br
+* \fB\-y [80-xxx]\fR \- sets width to given number. Must be 80 or more.
+.br
+* \fB\-y 1\fR \- switches to a single indented key/value pair per line, and
+removes all long line wrapping (similar to \fBdmidecode\fR output). Not
+recommended for use with \fB\-Y\fR;
+.br
+* \fB\-y \-1\fR \- removes width limits (if assigned by configuration items).
+
+Examples:
+.br
+\fBinxi \-Fxx \-y 130\fR
+.br
+\fBinxi \-Fxxy\fR
+.br
+\fBinxi \-bay1\fR
+
+.TP
+.B \-Y\fR, \fB\-\-height\fR, \fB\-\-less [\-3\-[integer]\fR
+Control output height. Useful when in console, and scrollback not available.
+Breaks output flow based on values provided.
+
+* \fB\-Y 0\fR or \fB\-Y\fR \- Set default max height to terminal height.
+.br
+* \fB\-Y [1\-xxx]\fR \- set max output block height height in lines.
+.br
+* \fB\-Y \-1\fR \- Print out one primary data item block (like \fBCPU:\fR,
+\fBSystem:\fR) at a time. Useful for very long outputs like \fB\-Fa\fR,
+\fB\-v8\fR, etc. Not available for \fB\-h\fR.
+.br
+* \fB\-Y \-2\fR \- Do not disable output colors when redirected or piped to
+another program. Useful if piping output to \fBless \-R\fR for example. This
+does not limit the height otherwise since the expectation it is being piped to
+another program like \fBless\fR which will handle that.
+.br
+* \fB\-Y \-3\fR \- Restore default unlimited output lines if \fBLINES_MAX\fR
+configuration item set.
+
+Recommended to use the following for very clean up and down scrollable output
+out of display, while retaining the color schemes, which are normally removed
+with piping or redirect:
+
+\fBpinxi \-v8Y \-2 | less \-R\fR
+
+Note: since it's not possible for inxi to know how many actual terminal lines
+are being used by terminal wrapped output, with \fB\-y 1\fR , it may be better
+in general to use a fixed height like:
+
+\fB\-y 1 \-Y 20\fR instead of: \fB\-y 1 \-Y\fR
+
.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
@@ -875,11 +1073,11 @@ data on various options. They can be added to any long form option list,
e.g.: \fB\-bxx\fR or \fB\-Sxxx\fR
There are 3 extra data levels:
-
+.br
\fB\-x\fR, \fB\-xx\fR, \fB\-xxx\fR
-
+.br
OR
-
+.br
\fB\-\-extra 1\fR, \fB\-\-extra 2\fR, \fB\-\-extra 3\fR
The following details show which lines / items display extra information for
@@ -909,23 +1107,38 @@ without \fB\-x\fR.
.TP
.B \-x \-C\fR
-\- Adds bogomips on CPU (if available)
+\- Adds bogomips to CPU speed report (if available).
+
+\- Adds \fBL1:\fR and \fBL3:\fR cache types if either are present/available. For
+BSD or legacy Linux, uses dmidecode + doas/sudo/root. Force use of dmidecode
+cache values by adding \fB\-\-dmidecode\fR. This will override /sys based cache
+data, which tends to be better, so in general don't do that.
\- Adds \fBboost: [enabled|disabled]\fR if detected, aka \fBturbo\fR. Not all
CPUs have this feature.
\- Adds CPU Flags (short list). Use \fB\-f\fR to see full flag/feature list.
-\- Adds CPU microarchitecture + revision (e.g. Sandy Bridge, K8, ARMv8, P6,
-etc.). Only shows data if detected. Newer microarchitectures will have
-to be added as they appear, and require the CPU family ID, model ID,
-and stepping.
+\- Adds CPU microarchitecture + revision (e.g. Sandy Bridge, K8, ARMv8, P6,
+etc.). Only shows data if detected. Newer microarchitectures will have to be
+added as they appear, and require the CPU family ID, model ID, and stepping.
-Examples: \fBarch: Sandy Bridge rev: 2\fR, \fBarch: K8 rev.F+ rev: 2\fR
+\- Adds, if smt (Simultaneous MultiThreading) is available but disabled, after
+\fBtype:\fR data \fBsmt: disabled\fR. \fBtype: MT\fR means it's enabled. See
+\fB\-Cxxx\fR.
+
+Examples:
+.br
+\fBarch: Sandy Bridge rev: 2\fR
+.br
+\fBarch: K8 rev.F+ rev: 2\fR
If unable to non\-ambiguosly determine architecture, will show something like:
\fBarch: Amber Lake note: check rev: 9\fR
+\- Adds CPU highest speed after \fBavg: [speed] high: [speed]\fR if greater than
+1 core and cores have different speeds. Linux only.
+
.TP
.B \-x \-d\fR
\- Adds more items to \fBFeatures\fR line of optical drive;
@@ -948,18 +1161,18 @@ If your \fBdrivetemp\fR module is not enabled, enable it:
Once enabled, add \fBdrivetemp\fR to \fB/etc/modules\fR or
\fB/etc/modules\-load.d/***.conf\fR so it starts automatically.
-If you see drive temps running as regular user and you did not configure
-system to use doas[BSDs]/sudo hddtemp, then your system supports this feature.
-If no /sys data is found, inxi will try to use hddtemp methods instead for
-that drive. Hint: if temp is /sys sourced, the temp will be to 1 decimal,
-like 34.8, if hddtemp sourced, they will be integers.
+If you see drive temps running as regular user and you did not configure system
+to use doas/sudo hddtemp, then your system supports this feature. If no /sys
+data is found, inxi will try to use hddtemp methods instead for that drive.
+Hint: if temp is /sys sourced, the temp will be to 1 decimal, like 34.8, if
+hddtemp sourced, they will be integers.
Method 2: 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)
-BSD users: see \fBman doas.conf\fR for setup.
+doas users: see \fBman doas.conf\fR for setup.
You can force use of \fBhddtemp\fR for all drives using \fB\-\-hddtemp\fR.
@@ -1107,7 +1320,7 @@ found for each distribution system base detection.
(\fB\-xt m\fR).
.TP
-.B \-x \-w\fR,\fB \-W\fR
+.B \-x \-w \fR, \fB\-W\fR
\- Adds humidity and barometric pressure.
\- Adds wind speed and direction.
@@ -1121,11 +1334,6 @@ found for each distribution system base detection.
\- Adds serial number.
.TP
-.B \-xx \-C\fR
-\- Adds \fBL1\-cache:\fR and \fBL3\-cache:\fR if either are available.
-Requires dmidecode and doas[BSDs]/sudo/root.
-
-.TP
.B \-xx \-D\fR
\- Adds disk serial number.
@@ -1270,7 +1478,7 @@ running. If none found, shows nothing. Uses a less accurate fallback tool
\- Adds slot length.
.TP
-.B \-xx \-w\fR,\fB \-W\fR
+.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
@@ -1295,7 +1503,16 @@ data is simply not available as of 2018\-04\-03), location (only available from
.TP
.B \-xxx \-C\fR
\- Adds CPU voltage and external clock speed (this is the motherboard speed).
-Requires doas[BSDs]/sudo/root and \fBdmidecode\fR.
+Requires doas/sudo/root and \fBdmidecode\fR.
+
+\- Adds, if smt (Simultaneous MultiThreading) data is available, after
+\fBtype:\fR data \fBsmt: [status]\fR.
+.br
+\fBsmt: [status]\fR
+.br
+\fBMT\fR in \fBtype:\fR will show if smt is enabled in general. 3 values are
+possible: [\fBenabled|disabled|<unsupported>\fR]. \fB<unsupported>\fR means the
+CPU does not support SMT.
.TP
.B \-xxx \-D\fR
@@ -1394,7 +1611,7 @@ These are the same as \fBctrl+alt+F[x]\fR numbers usually. Some systems
have this, some don't, it varies.
.TP
-.B \-xxx \-w\fR,\fB \-W\fR
+.B \-xxx \-w \fR, \fB\-W\fR
\- Adds location (city state country), observation altitude (if available),
weather observation time (if available), sunset/sunrise (if available).
@@ -1419,34 +1636,51 @@ knows could possibly be used instead.
\- Adds CPU family, model\-id, and stepping (replaces \fBrev\fR of \fB\-Cx\fR).
Format is \fBhexadecimal (decimal)\fR if greater than 9, otherwise
\fBhexadecimal\fR.
+
\- 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
-doas[BSDs]/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
+doas/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.
+
Sample: \fBsocket: 775 (478) note: check\fR
+.br
Sample: \fBsocket: AM4\fR
-.fi
-\- Adds DMI CPU base and boost/turbo speeds. Requires doas[BSDs]/sudo/root and
+\- Adds DMI CPU base and boost/turbo speeds. Requires doas/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.
+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
+.br
CPU not overclocked, with boost, like Ryzen:
-\fBSpeed: 2861 MHz min/max: 1550/3400 MHz boost: enabled base/boost: 3400/3900\fR
-
+.nf
+\fBSpeed (MHz):
+ avg: 2861
+ high: 3250
+ min/max: 1550/3400
+ boost: enabled
+ base/boost: 3400/3900\fR
+.fi
Overclocked 2900 MHz CPU, with no boost available:
-\fBSpeed: 2900 MHz min/max: 800/2900 MHz base/boost: 3350/3000\fR
-
+.nf
+\fBSpeed (MHz):
+ avg: 2345
+ high: 2900
+ min/max: 800/2900
+ base/boost: 3350/3000\fR
+.fi
Overclocked 3000 MHz CPU, with boosted max speed:
-\fBSpeed: 4190 MHz min/max: 1200/3001 MHz base/boost: 3000/4000\fR
+.nf
+\fBSpeed (MHz):
+ avg: 3260
+ high: 4190
+ min/max: 1200/3001
+ base/boost: 3000/4000\fR
.fi
Note that these numbers can be confusing, but basically, the \fBbase\fR
@@ -1463,6 +1697,65 @@ 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 frequency \fBscaling: governor:.. driver:..\fR if found/available.
+
+\- Adds description of cache topology per cpu. Linux only.
+
+\- Creates new \fBTopology:\fR line after the \fBInfo:\fR line. Moves cache data
+to this line from \fBInfo:\fR line.
+
+Topology line contains, if available and/or relevant: physical CPU count
+(\fBcpus:\fR); per physical cpu core count (cores:\fR); threads per core, if > 1
+(\fBtpc:\fR); how many \fBthreads:\fR (if more threads than cores); \fBdies:\fR
+(rarely detected, but if so, if > 1); smt status (if no smt status found, shows
+\fBN/A\fR).
+
+If complex CPU type, like Alder lake, cores; will have a more granular breakdown
+of how many mt (multi\-threaded) and how many st (single\-threaded) cores there
+in the physical cpu ( \fBmt\-cores:\fR, \fBst\-cores:\fR); For complex CPU
+types like ARM SoC devices with 2 CPU types, with different core counts and/or
+\fBmin/max:\fR) frequencies, \fBvariant:\fR per type found, with relevant
+differences shown, like \fBcores:, \fBmin/max:\fR, etc.
+
+.nf
+\fBCPU:
+ Info:
+ model: AMD EPYC 7281
+ bits: 64
+ type: MT MCP MCM SMP
+ arch: Zen
+ family:0x17 (23)
+ model\-id:1
+ stepping: 2
+ microcode: 0x8001250
+ Topology:
+ cpus: 2
+ cores: 16
+ tpc: 2
+ threads: 32
+ dies: 4
+ cache:
+ L1: 2x 1.5 MiB (3 MiB)
+ desc: d\-16x32 KiB; i\-16x64 KiB
+ L2: 2x 8 MiB (16 MiB)
+ desc: 16x512 KiB
+ L3: 2x 32 MiB (64 MiB)
+ desc: 8x4 MiB
+ Speed (MHz):
+ avg: 1195
+ high: 1197
+ min/max: 1200/2100
+ boost: enabled
+ scaling:
+ driver: acpi\-cpufreq
+ governor: ondemand
+ cores:
+ 1: 1195
+ 2: 1196
+ ....
+ bogomips: 267823
+.fi
+
\- 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).
@@ -1471,7 +1764,7 @@ values. The \fBbase/boost:\fR values are sometimes real, and sometimes not.
.B \-a \-d\fR,\fB\-a \-D\fR
\- Adds logical and physical block size in bytes.
-Using \fBsmartctl\fR (requires doas[BSDs]/sudo/root privileges).
+Using \fBsmartctl\fR (requires doas/sudo/root privileges).
\- Adds device model family, like \fBCaviar Black\fR, if available.
@@ -1558,15 +1851,15 @@ Sample (with both \fBxdpyinfo\fR and \fBxrandr\fR data available):
.nf
\fBinxi \-aG
Graphics:
- ....
-Display: x11 server: X.Org 1.20.6 driver: loaded: 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")
+ ....
+ Display: x11 server: X.Org 1.20.6 driver: loaded: 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
@@ -1584,15 +1877,15 @@ 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\fR
+ ....
+ 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\fR
.fi
\- Adds service control tool, tested for in the following order: \fBsystemctl
-rc-service rcctl service sv /etc/rc.d /etc/init.d\fR - useful to know which
-you need when using an unfamiliar machine.
+rc\-service rcctl service sv /etc/rc.d /etc/init.d\fR. Can be useful to know
+which you need when using an unfamiliar machine.
.TP
.B \-a \-j\fR, \fB\-a \-P\fR [swap], \fB\-a \-P\fR [swap]
@@ -1728,12 +2021,15 @@ Shortcut, legacy. See \fB\-\-force dmidecode\fR.
Force inxi to use Curl, Fetch, Perl, or Wget for downloads.
.TP
-.B \-\-force [dmidecode|hddtemp|lsusb|pkg|usb-sys|vmstat|wmctl]\fR
+.B \-\-force [colors|dmidecode|hddtemp|lsusb|pkg|usb-sys|vmstat|wmctrl]\fR
Various force options to allow users to override defaults. Values be given
as a comma separated list:
\fBinxi \-MJ --force dmidecode,lsusb\fR
+\- \fBcolors\fR \- Same as \fB\-Y \-2\fR . Do not remove colors from piped or
+redirected output.
+
\- \fBdmidecode\fR \- Force use of \fBdmidecode\fR. This will override
\fB/sys\fR data in some lines, e.g. \fB\-M\fR or \fB\-B\fR.
@@ -1758,7 +2054,7 @@ data source instead of \fBlsusb\fR (Linux only).
\- \fBvmstat\fR \- Forces use of vmstat for memory data.
-\- \fBwmctl\fR \- Force \fBSystem\fR item \fBwm\fR to use \fBwmctrl\fR
+\- \fBwmctrl\fR \- Force \fBSystem\fR item \fBwm\fR to use \fBwmctrl\fR
as data source, override default \fBps\fR source.
.TP
@@ -1766,26 +2062,12 @@ as data source, override default \fBps\fR source.
Shortcut, legacy. See \fB\-\-force hddtemp\fR.
.TP
-.B \-\-host\fR
-Turns on hostname in System line. Overrides inxi config file value (if set):
-
-\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 \-\-limit [\-1 \- x]\fR
-Raise or lower max output limit of IP addresses for \fB\-i\fR. \fB\-1\fR
-removes limit.
-
-.TP
.B \-\-man\fR
Updates / installs man page with \fB\-U\fR if \fBpinxi\fR or using \fB\-U 3\fR
dev branch. (Only active if \fB\-U\fR is is not disabled by maintainers).
@@ -1795,6 +2077,7 @@ dev branch. (Only active if \fB\-U\fR is is not disabled by maintainers).
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\-doas\fR
Skips the use of doas to run certain internal features (like \fBhddtemp\fR,
@@ -1806,18 +2089,6 @@ this option, or \fBNO_DOAS\fR configuration item. See \fB\-\-no\-sudo\fR if
you need to disable both types.
.TP
-.B \-\-no\-host\fR
-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):
-indent\-min
-
-\fBSHOW_HOST='true'\fR \- Same as: \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
@@ -1852,40 +2123,6 @@ requires configuration to setup anyway for these options) just use this option,
or \fBNO_SUDO\fR configuration item.
.TP
-.B \-\-output [json|screen|xml]\fR
-Change data output type. Requires \-\-output\-file if not \fBscreen\fR.
-
-.TP
-.B \-\-output\-file [full path to output file|print]\fR
-The given directory path must exist. The directory path given must exist,
-The \fBprint\fR options prints to stdout.
-Required for non\-screen \fB\-\-output\fR formats (json|xml).
-
-.TP
-.B \-\-partition\-sort [dev\-base|fs|id|label|percent\-used|size|uuid|used]\fR
-Change default sort order of partition output. Corresponds to
-\fBPARTITION_SORT\fR 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 filesystems are the same.
-
-\fBid\fR \- Mount point of partition (default).
-
-\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.
-
-\fBuuid\fR \- UUID of the partition.
-
-\fBused\fR \- KiB used of partition.
-
-.TP
.B \-\-pkg\fR
Shortcut. See \fB\-\-force pkg\fR.
@@ -1965,6 +2202,10 @@ You can see what inxi believed started it in the \fB\-Ixxx\fR line,
\fBShell:\fR or \fBClient:\fR item. Please let us know what that result was
so we can add it to the parent start program whitelist.
+In some cases, you may want to also use \fB\-\-no\-filter\fR/\fB\-Z\fR option if
+you want to see filtered values. Filtering is turned on by default if \fBinxi\fR
+believes it is running in an IRC client.
+
.TP
.B \-\-usb\-sys\fR
Shortcut, legacy. See \fB\-\-force usb\-sys\fR
@@ -1989,21 +2230,7 @@ Same as configuration value (example):
.B \-\-wm\fR
Shortcut, legacy. See \fB\-\-force wmctl\fR.
-.TP
-.B \-\-wrap\-max [integer]\fR
-Overrides default or configuration set line starter wrap width value. Wrap
-max is the maximum width that inxi will wrap line starters (e.g. \fBInfo:\fR)
-to their own lines, with data lines indented only 2 columns. If
-terminal/console width or \fB\-\-width\fR is less than wrap width, wrapping
-of line starter occurs. If \fB80\fR or less, no wrapping will occur. Overrides
-internal default value (90) and user configuration value:
-
-\fBWRAP_MAX=85\fR (previously \fBINDENT_MIN\fR)
-
-Previously called: \fB\-\-indent\-min\fR.
-
.SH DEBUGGING OPTIONS
-
.TP
.B \-\-dbg 1\fR
\- Debug downloader failures. Turns off silent/quiet mode for curl, wget, and
@@ -2059,7 +2286,6 @@ For alternate ftp upload locations: Example:
\fBinxi \-\-ftp \fIftp.yourserver.com/incoming\fB \-\-debug 21\fR
.SH DEBUGGING OPTIONS TO DEBUG DEBUGGER FAILURES
-
Only use the following in conjunction with \fB\-\-debug 2[012]\fR, and only
use if you experienced a failure or hang, or were instructed to do so.
@@ -2086,7 +2312,7 @@ Skip /sys debugging in case of a hang.
.TP
.B \-\-debug\-sys\fR
-Force PowerPC debugger parsing of /sys as doas[BSDs]/sudo/root.
+Force PowerPC debugger parsing of /sys as doas/sudo/root.
.TP
.B \-\-debug\-sys\-print\fR
@@ -2178,13 +2404,14 @@ these up, and for a complete list of options:
.B Basic Options
Here's a brief overview of the basic options you are likely to want to use:
-\fBCOLS_MAX_CONSOLE\fR The max display column width on terminal.
-If terminal/console width or \fB\-\-width\fR is less than wrap width,
-wrapping of line starter occurs
+\fBCOLS_MAX_CONSOLE\fR The max display column width on terminal. If
+terminal/console width or \fB\-\-width\fR is less than wrap width, wrapping of
+line starter occurs
+
\fBCOLS_MAX_IRC\fR The max display column width on IRC clients.
-\fBCOLS_MAX_NO_DISPLAY\fR The max display column width in console, out of GUI
-desktop.
+\fBCOLS_MAX_NO_DISPLAY\fR The max display column width in out of X / Wayland /
+desktop / window manager.
\fBCPU_SLEEP\fR Decimal value \fB0\fR or more. Default is usually around
\fB0.35\fR seconds. Time that inxi will 'sleep' before getting CPU speed data,
@@ -2197,9 +2424,25 @@ downloaders.
\fBFILTER_STRING\fR Default \fB<filter>\fR. Any string you prefer to see
instead for filtered values.
+\fBINDENT\fR Change primary indent width of wide mode output. See
+\fB\-\-indent\fR.
+
+\fBINDENTS\fR Change primary indents of narrow wrapped mode output, and second
+level indents. See \fB\-\-indents\fR.
+
\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.
+\fBLINES_MAX\fR Values: [\-2\-xxx]. See \fB\-Y\fR for explanation and values.
+Use \fB\-Y \-3\fR to restore default unlimited output lines. Avoid using this in
+general unless the machine is a headless system and you want the output to be
+always controlled.
+
+\fBMAX_WRAP\fR (or \fBWRAP_MAX\fR) The maximum width where the line starter
+wraps to its own line. If terminal/console width or \fB\-\-width\fR is less than
+wrap width, wrapping of line starter occurs. Overrides default. See
+\fB\-\-max\-wrap\fR. If \fB80\fR or less, wrap will never happen.
+
\fBNO_DIG\fR Set to \fB1\fR or \fBtrue\fR to disable WAN IP use of \fBdig\fR
and force use of alternate downloaders.
@@ -2250,11 +2493,6 @@ Values 4\-9 are not currently supported, but this can change at any time.
\fBWEATHER_UNIT\fR Values: [\fBm\fR|\fBi\fR|\fBmi\fR|\fBim\fR]. Same as
\fB\-\-weather\-unit\fR.
-\fBWRAP_MAX\fR (previously \fBINDENT_MIN\fR) The maximum width where the line
-starter wraps to its own line. If terminal/console width or \fB\-\-width\fR is
-less than wrap width, wrapping of line starter occurs. Overrides default.
-See \fB\-\-wrap\-max\fR. If \fB80\fR or less, wrap will never happen.
-
.TP
.B Color Options
It's best to use the \fB\-c [94\-99]\fR color selector tool to set the
@@ -2337,10 +2575,14 @@ Jarett.Stevens \- \fBdmidecode \-M\fR patch for older systems with no
.SH SPECIAL THANKS TO THE FOLLOWING
-The nice people at irc.oftc.net channels #linux\-smokers\-club and #smxi,
-who all really have to be considered to be co\-developers because of their
-non\-stop enthusiasm and willingness to provide real\-time testing and
-debugging of inxi development.
+The nice people at irc.oftc.net channels #linux\-smokers\-club and #smxi, who
+all really have to be considered to be co\-developers because of their non\-stop
+enthusiasm and willingness to provide real\-time testing and debugging of inxi
+development over the years.
+
+LinuxQuestions.org Slackware forum members, for major help with development and
+debugging new or refactored features, particularly the redone CPU logic of
+2021\-12.
Siduction forum members, who have helped get some features working by providing
a large number of datasets that have revealed possible variations, particularly
diff --git a/inxi.changelog b/inxi.changelog
index 46360eb..f4f8f5b 100644
--- a/inxi.changelog
+++ b/inxi.changelog
@@ -1,4 +1,693 @@
================================================================================
+Version: 3.3.10
+Patch: 01
+Date: 2021-12-13
+--------------------------------------------------------------------------------
+RELEASE NOTES:
+--------------------------------------------------------------------------------
+
+Huge refactor of CPU physical/core/cache logic. That was some very old logic
+with a lot of hacks and patches, but it had never been actually rewritten to
+take advantage of Perl's far more powerful and robust data structures and logic.
+This caused a continuous stream of error cases in subtle ways, or not so subtle,
+and fixes were just changing how the errors manifested.
+
+Tnanks very much to linuxquestions.org Slackware forum people for massive help,
+and also to linux.org forum members for ongoing help and data and debugging.
+
+Note Changes 5, change of default widths in display to 80 columns, and out (aka,
+console, or ssh into remote system), 100. You can still use other widths if you
+like something wider using the configuration options shown. Also upped max
+columns wrapping line starters to own rows to 110 columns from 90, again the
+idea being to make output more readable to other users when posted in public.
+
+I've been thinking of this change for a long time, but was hoping -y would
+register with users, but it hasn't gained enough traction, so the result is way
+too many super hard to read issue reports, forum posts, linux kernel issues,
+etc, it's honestly gotten sort of embarrassing because they make it look like
+inxi has bad output. Sidescrolling code blocks in forums in particular are
+absurdly hard to read and scan rapidly for data.
+
+Going along with the width and indentation changes, for most main row types, if
+they wrap to a second row, they are further indented 2 column2, to make it
+easier to see what they belong to. The two levels of indentation contain more
+useful visual cues as to what belongs to what.
+
+There was a temptation to release this as either 3.4.00 or 4.0.00 but in the
+end, I decided to follow the numbering rules, and to just roll it to 3.3.10
+since there aren't really any primary new features even though CPU was basically
+rewritten in large part, and big parts of inxi were also changed, upgraded, and
+enhanced. But no truly new features, just some display control items like -Y,
+--indent, --indents.
+
+I hope this refactor meets its primary goals, and that the new defaults for
+display help resolve public posting issues which have grown increasingly
+annoying for anyone trying to read those pasted in too long outputs.
+
+--------------------------------------------------------------------------------
+KNOWN ISSUES:
+
+1. Android seems to have CPU cache data, but does not show any 'size' item. But
+it does have the other data for each cache type internally, which is odd.
+
+2. In some instances, the parent key:value pairs with '' as value, those are
+parents of children key:value pairs, are left hanging at end of line, with the
+children on the following line. This can look awkward, but in other cases,
+actually looks very good, it depends if it's at the start or end of the line.
+
+I won't say this is not correctable, but it would be very difficult, and outside
+the scope of this release, but that is something that I may look at for a future
+release now that the output generator logic was reworked slightly for Change 5b.
+
+It's tricky though, because in cases where it's the first item on the line, you
+want that behavior, but when it's last, you don't. But this may be worth
+revisiting in the future.
+
+3. In some cases, -Y + -y1 may lead to the start of the block scrolling off the
+top of the visible screen. This isn't really correctable, so if that's an issue
+for you, just don't use -y1 with -Y and all the output will wrap nicely.
+
+4. There is an unaccountable ~10-20ms delay reading cpufreq/scaling_cur_freq,
+per thread/core, which really adds up on high thread count CPUs. There is a
+workaround in inxi to use cpufreq_cur_freq if it is readable, ie, if you are
+root or use sudo, but to fallback to scaling_cur_freq if can't read cpuinfo_...
+
+This is a drag, and really looks like a kernel bug, or a frequency driver bug.
+
+--------------------------------------------------------------------------------
+BUGS:
+
+1. 3.3.09 and 3.3.10 CPU bug fixes:
+* Failed to filter out certain virtual machine CPU core speeds, and showed more
+speeds than the instance actually has. Noticed this with KVM running on Xeon
+CPUs.
+* For many cases, L2 cache, particularly for Intel, was completely wrong, it was
+showing L3 caches, or L3+L2. Failed to handle cases where L2 cache belongs to
+more than 1 core, except for using a crude hack for AMD Bulldozer microarch.
+Older Intel Core 4 core CPUs would sometimes be 1 L2 per die, and the 4 cores
+were actually 2 core duo cpu dies, with one L2 cache per die.
+* Shows wrong core count for complex core complexes like those found in Intel
+Alder Lake, now shows correct count of actual cores, regardless of the MT or ST
+state of each core.
+* Showed invalid L3 cache values in some legacy cpus that had no L3 cache, that
+is due to a bug in the dmidecode data itself. Solution is to never use dmidecode
+cache data if any other valid L1, L2, or L3 cache data found for Linux, and to
+only use dmidecode data for bsds if no L1, or L2, or L3 data found. Or if forced
+with --dmidecode.
+
+2. An unfortunately long standing bug found and fixed, thanks slackware users!
+cp_cpu_arch was, and has been for a while, failing to convert hex stepping to
+decimal, or test if the string it gets is even a possible hex value, this
+resulted in all Intel CPUs with stepping > 9 failing to ID correctly for cpu
+arch.
+
+3. In a related bug, hex to decimal tool used to create --admin hex/decimal
+output for family/model/stepping was also not testing if the string was an
+actual valid hex number. Case in particular, power pc with revision field
+contained a long string, which was of course not a valid hex number, and that
+tripped a Perl error when it was asked to convert a non hex string to decimal.
+
+4. Long standing bug found while doing Change 5: inxi actually never applied
+separate in/out of dispay to widths because using a legacy boolean that was not
+updated, so it was always using out of display widths.
+
+--------------------------------------------------------------------------------
+FIXES:
+
+1. Incorrectly calling PowerPC 'revision' 'stepping' for -Ca, that is now stored
+as $cpu{'revision'} to avoid mixing up the logics there. For PowerPC shows as
+rev: [string].
+
+2. Microarch:
+* AMD family 15, model 2 as bulldozer, actually piledriver.
+* AMD family 17, model 18, was supposed to be zen/zen+, since I can't tell those
+apart, seen stepping 1 is zen+, but had incorrect match.
+* Intel family 6, model 25, stepping 2 as nehalem, should have been westmere.
+* Changed Penryn to Core Penryn, intel family 6, model 17
+* misc other micro arch fine tunings.
+
+3. Code fix 8, switched to global %risc for arm, mips, ppc, riscv, sparc. This
+corrects many sloppy handlers, and makes all risc processing the same, and calls
+device tree readers for all risc systems, not just arm or arm and mips.
+
+4. In cases where bogomips were 0 due to false values in risc results, show N/A.
+
+5. Removed all attempts to guess at what /proc/cpuinfo cache size: refers to,
+it can literally be anything, a per core L1, a per core or cpu L2, or an L3.
+So applying any math to it is just a random guess at that point. If any L1,2,3
+cache data is found, don't use the cache: value at all, but that will only be
+present if no /sys data was found anyway, and if cpuinfo had no specific cache
+type fields, only generic cache.
+
+6. Added failsafe tests for stepping and model id before doing conversion to
+hex. Make sure integer!
+
+7. Added L1 D cache, was only using I cache for BSDs. Output will show total for
+L1 A + L1 D. No idea why I didn't use L1 D, makes little sense, but that's how
+it goes.
+
+8. Made bogomips tests more granular, now only rejects low sub 50 bogomips
+values if %risc cpu type. Legacy ancient cpus like 486 could and did have
+bogomip counts below 50.
+https://tldp.org/HOWTO/BogoMips/bogo-list.html
+
+9. See Enhancement 12 as well. If OpenBSD, which has no per core data or
+physical cpu data, is running on MT capable cpu, but for security OpenBSD has
+disabled MT, will now force MT to be not shown via the hw.smt value. This
+removes a small glitch that would have bothered OpenBSD users who know that
+OpenBSD has disabled MT for security purposes.
+
+10. Changed BSD hack to use L2 cache totals to deduce > 1 physical cpus, that
+was flat out dumb, since we can just use dmidecode type 4 to iterate physical
+cpu counts and skip the pointless logic. Thus, if dmidecode, and if > 1
+dmidecode type 4 found, and if physical cpu counts equal 1, then replace the
+found counts with the dmidecode physical cpu counts.
+
+11. Corrected bad assumption that threads would always be 2 per core for MT
+tests. Still no way to reliably determine threads per core for non x86 cpus like
+powerpc however, but those are very fringe and should rarely be an issue since
+that data is only missing on very old linux now I think.
+
+12. Fixed 'parameters:' going to its own line with -Sa, that wasn't supposed to.
+-S is two lines, the kernel / host stuff, and the desktop/console/distro stuff.
+
+13. Fixed case when key: value first word plus other parts of line longer than
+max width, failed to wrap as expected.
+
+14. Added start/end ' and " start / end \s to main filters.
+
+--------------------------------------------------------------------------------
+ENHANCEMENTS:
+
+1. CPU: most Linux will now show L1 and L3 cache with -Cx without needing
+sudo/root, and it will be more accurate than ever before.
+
+2. CPU: shows per CPU L1/L2/L3 totals, and shows actual full system physical
+processor count * L1/L2/L3 total in parentheses, like: L2: 1.5 MiB (3 MiB).
+
+3. CPU: A long standing annoyance, previously for main CPU 'Speed:' item, showed
+the fastest core speed found, now shows avg: [speed] and with -Cx, shows the
+'high:' as well if > 1 cores, and if 1 or more cores have a higher speed than
+the other(s).
+
+4. CPU: Handles advanced cases of new architectures, like Alder Lake with
+Performance and Efficiency cores, future Zen, and existing ARM CPUs with 2 or
+more different core sets, with different max/min frequencies. Previously a hack
+was used to handle only ARM CPUs with this type of architecture. Will show
+correct CPU core counts, which previous inxi versions would fail to do for Alder
+Lake type scenarios of 8 single threaded CPUs and 4-8 multithreaded )MT)
+perforance cores.
+
+This should also in theory show different the different min/max speeds if they
+were detected. Those did not seem to be set correctly in Alder Lake sample data
+I saw however, P and E cores were set to the same min/max speeds.
+
+5. Added CPU types MST (Multi+Single Thread), AMP (Asymmetric Multi Processing),
+and AMCP (Asymmetrical Multi Core Processor). This will be applied to any CPU
+that has this type of complex topology that has been dynamically detected, like
+Alder Lake or different core count or min/max speed RISC CPUs.
+
+6. CPU: shows with -Ca for cases where different L1/L2/L3 caches found per
+physical CPU, as with Alder Lake, but also many other variants that were poorly
+or not at all handled before, how many of each cache type (L1 Data, instruction)
+were found, otherwise will show how many of each cache were found.
+
+7. CPU: shows with -Ca in Topology: report, for cases like Alder Lake with
+different core types in one physical CPU (type: MST AMCP), the number that are
+single threaded (st) and number that are multi-threaded (mt).
+
+8. Basic support for rsyc-v systems, going along with code fix 8, fix 3, now
+it's easy to add this type of support.
+
+9. Added shortcut options for --filter-label (--zl), --filter-uuid (--zu), and
+andded new filter option, --filter-vulnerabilities (--zv). The latter is added
+by request, a decent idea to have option to not show cpu vulnerabilities.
+
+10. Going with fix 7, switched to a sort of pseudo L1 d/i with desc report for
+any BSD with L1 I/D cache found, or elbrus cache0 (icache) / cache1 (d cache).
+Elbrus should hopefully be handled by the /sys tool. Guesses on the L1 are ok,
+since those are almost always per core, so it's fine. Didn't expect to enhance
+any BSD cpu data this time around, but there you go!! If they have the data,
+then it will be used. Not going to go overboard though in that, quite useless
+overall since usually can't see how many CPUs are present, at least not usually.
+
+11. For -Ca, full CPU topology report if any complex topogy is detected,
+otherwise shows the same basic Info: 2x 6-core or Info: dual core as before, no
+point in wasting a line for something with no more data than the short string.
+Complex types include MT CPUs since they will have different thread counts etc,
+and will have 2 or more threads per core, which will also be listed.
+
+12. If smt status is defined (0/1), shows smt: enabled|disabled in Topology
+section, can be useful for systems with disabled MT, but supporting it. If no
+topology data found (OpenBSD for example), for -C shows 'smt: disabled' after
+'type:' section, and enabled if -Cxxx (since MT really already tells you that).
+
+13. For -Ca Speed: report, added 'governor:' item, if found. Can show 1 or more
+active governors.
+
+14. Output height (in lines) control: -Y [-2|-1|0|1-xxx]]. This lets you break
+up any of the output into whatever number of lines you want. Also useful out of
+DISPLAY for reading -h options menu items etc.
+
+It came tp my attention that the long standing shift+pgup/pgdown (aka
+'softscrollback) behavior had stopped working, and in fact has been removed from
+the current Linux kernel, at least until it is rewritten to be more clean and
+understandable. Read more about it in these kernel post/commit messages:
+
+https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=50145474f6ef4a9c19205b173da6264a644c7489
+https://lwn.net/ml/linux-kernel/CAHk-=whe4ZdTdCebneWqC4gSQZwsVJ5-Emg0BucOGCwPhOAJpw@mail.gmail.com/
+
+Options for -Y are:
+* -Y 0 or -Y: Set maximum block height to terminal line height.
+* -Y [1-xxx]: Set maximum block line height to given integer.
+* -Y -1: Print out one primary data block item at a time, with -F for example.
+* -Y -2: Restore default unlimited height if LINES_MAX configuration item used.
+
+15. And finally, more disk vendors/vendor ids. As usual. As expected.
+
+--------------------------------------------------------------------------------
+CHANGES:
+
+1. If /sys or /proc/cpuinfo speed data available:
+* For -b CPU item:
+ speed: [speed MHz] min/max: [min]/[max] MHz
+ becomes:
+ speed (MHz): avg: [speed] min/max: [min]/[max]
+* For -C, Speed item
+ Speed: [speed MHz] min/max: [min]/[max] MHz Cores (MHz): ...
+ becomes:
+ Speed (MHz): avg: [speed] min/max: [min]/[max] cores: ...
+* For short form, shows speed/min/max but uses average speed if available.
+
+For -b and -C, only shows one MHz in Speed line starter, which slightly shortens
+the line even with the added 'avg:' item since 3 MHz are replaced with 1.
+
+2. Going with change 1, now the 'avg:' item shows not the fastest cpu speed
+found, which was the case before, but shows an average of all cpu speeds found.
+Showing the fastest made some sense back in the days of single core, or even
+dual core CPUs, but makes little sense today with many core/threaded cpus.
+
+With -x, it will show the high: [speed] item as well, after 'avg:'.
+
+3. By suggestion, wrapped first Type item in Vulnerabilities to its own line,
+that's a verbose --admin option after all, no need to save lines!
+
+4. Going along with Fix 5, give up on trying to pretend we can guess at L2
+cache, now if only 'cache' data was available from cpuinfo, will just say:
+cache: [cache size]
+ note: check
+
+and call it a day.
+
+5a. Change default width to 80 columns, in and out of display. Too many users
+are posting horribly wrapping inxi output in forums, issue trackers, etc, and it
+frankly makes inxi look really bad, creates awful side scrolling code boxes,
+etc. So now default widths in and out of console are 80 (since often data is
+generated in SSH or out of X/Wayland) for issues.
+
+This essentially makes -y 80/-y the default width. This is what I've been using
+for a few years now, and after seeing far too many side scrolling or badly
+wrapping inxi outputs online, I think it's probably time to just force 80 column
+widths as default and call it a day.
+
+You can change these new defaults using configuration options (these are the
+previous options, though due to a bug, COLS_MAX_CONSOLE was never being used):
+
+ COLS_MAX_CONSOLE=115 # in display, terminal client max width
+ COLS_MAX_IRC=100
+ COLS_MAX_NO_DISPLAY=130 # not in display, no X/Wayland running
+
+5b. Changed output wrapped indent to 1 column from 2, and make second and
+greater rows of a line indent +1 to make it more clear that it is a child row of
+its parent row. Note that because no arg short form, -S, and -I are special
+types of rows, this behavior is not used, they just print out as usual. This 1
+column indent also applies to -y1, making for a little more data per line but
+more readable and easy to follow.
+
+6. If > 1 physical cpu detected, no longer uses single/dual/triple/quad core
+strings, rather uses: 2x 2-core. Also uses lower case -core, not -Core.
+
+7. Only show die counts for CPU (on rare occasions > 1 found) with -xx. Not
+particularly important bit of data afterall.
+
+8. Make L1, L3 cache data show with -Cx, not -Cxx, now that it's working well.
+
+9. Removed CPU die for -Cxx, that's only going to show with -Ca now.
+
+10. If -Ca, and if certain complexity conditions are met, shows a separate
+Topology line rather than the Info: 6-core type item. For -b, short, -Cx, -Cxxx
+shows the Info: topology short form.
+
+11. Bogomips always shows before flags data, whether -f or just -Cx trips flag
+output.
+
+12. Flags/Features now shows in the same place, under Speeds: always, whether
+-Cx shortlist, or -Cf full list. Makes more sense that way, and code is much
+cleaner too.
+
+13. Bogomips, being essentially bogus units of speed for cpu, are moved into
+Speed: report.
+
+--------------------------------------------------------------------------------
+DOCUMENTATION:
+
+1. Updated man/help for new CPU extra data options and output changes.
+
+2. Cleaned up and added sample outputs for man CPU items.
+
+3. Now that doas is getting into Linux distros, removed all mentions of doas as
+a BSD option, and made it a general doas/sudo item. Glad to see doas making it
+into linux distros, it's a good tool, much easier to configure and use than
+sudo. Good job OpenBSD guys. Note that inxi already has had full doas support
+for a while now, but this finalizes it, and makes it fully agnostic. Internally
+doas is actually preferred over sudo, by the way.
+
+4. Added documention items for INDENT (--indent), INDENT_MIN (--inident-min).
+
+5. Re-ordered help menu and man page, created new Filters and Output Controls
+sections to make stuff easier to find. In man page, also added on top a list of
+OPTIONS sections to make finding stuff easier.
+
+--------------------------------------------------------------------------------
+CODE:
+
+1. Removed legacy /sys cpu functions: cpu_bugs_sys(); get_boost_status();
+set_cpu_speeds_sys(). cpu_speeds() is deprecated and now will only be used for
+legacy Linux and BSDs if they had any per core speeds found; get_caches() was
+only a placeholder for the full featured cpu_sys data source, and was removed;
+cpu_speeds() no longer needed, integrated into other logic; cpu_dies_sys()
+removed, integrated into other logic.
+
+This logic is now integrated into cpu_data_sys() data generator.
+
+2. Changed the main CpuItems functions to use array/hash references, not passing
+full hashes or arrays in most cases now.
+
+3. For machine_data_soc(), switched to CpuItem::cpuinfo_grabber() which then
+sets the global @cpuinfo and %cpuinfo_machine items, which will be used again
+in Cpu if cpu data is requested. This gets rid of a full parsing of cpuinfo
+just to get the machine data section, and also makes it so cpuinfo in cpu does
+not need to worry about the machine data block, which is not related to the
+processor blocks anyway, that was always a hack done by the kernel guys to toss
+that SOC data somewhere as far as I can tell.
+
+4. New tools:
+* either_or() - takes a list, and returns the first defined element of list.
+* regex_range() - generate ranges from comma, space, or ranges like 2-29, or any
+combination of those, like 3,6,12-29
+
+5. Added --force cpuinfo to bypass all /sys based cpu logic, useful for testing
+to see what would have happened using old logic.
+
+6. Added --dbg switches 39, 40, 41, for the new cpu sys data features, also made
+more consistent --dbg 8 and --dbg 38 switches.
+
+7. Added sys/cpuinfo pair debugger to support debugging complex sys/cpuinfo
+issues.
+
+8. Got rid of $b_arm,$b_mips,$b_ppc,$b_sparc, replaced with global %risc, also
+added $risc{'riscv'} type. this makes general risc type feature testing a lot
+easier since inxi can either test for %risc defined, or for a specific type of
+risc cpu. This is much cleaner, and use $risc{'id'} for print purposes, which
+got rid of a lot of tests. Also made all risc tests consistent, some were ARM
+only, or arm/mips, but were supposed to be for all risc cpus.
+
+9. Set help menu code to roughly 80 columns width assuming 2 space tab
+indentation.
+
+10. Changed all xxx_cleaner subs to clean_xxx, all filter subs to filter_xxx,
+and row_defaults() to message().
+
+11. Dumped redundant fallback logic in get_kernel_bits, if first getconf method
+fails, use $sys_bits, and call it good, it was repeating the 32/64 bit tests
+pointlessly.
+
+12. Cleaned up print_data() to allow for more fine tuned indentation for the new
+2 indent levels.
+
+13. Made help menu code more or less wrap to 80 columns, or close. Ongoing to
+bring to 80 columns where practical, but never at expense of clarity or logic.
+
+--------------------------------------------------------------------------------
+-- Harald Hope - Tue, 13 Dec 2021 10:25:49 -0800
+
+================================================================================
+Version: 3.3.09
+Patch: 01
+Date: 2021-11-22
+--------------------------------------------------------------------------------
+RELEASE NOTES:
+--------------------------------------------------------------------------------
+
+Thanks manjaro user alven for finding a bunch of corner and not so corner case
+errors, glitches, documentation oversights, etc.
+
+This is a point release between the coming full CPU refactor and the current
+set of bug fixes and issue handlings.
+
+This release also contains the debuggers for the new CPU data logic, which are
+important to get this CPU refactor stable and reliable across old/new systems,
+different operating systems and platforms.
+
+Wanted to do this intermediate releaase to get the current fixes out, which
+make inxi overall better for CPU issues, but do not handle the core requirement
+to do a full refactor.
+
+--------------------------------------------------------------------------------
+
+CORRECTION:
+
+1. On release notes for 3.3.08: due to a long delay to get real debugger data
+from the person who had the issue, but finally getting it after the release of
+3.3.08, there was NO bug in ps wwaux output. Something else was creating the
+linewraps, maybe the subshell, it's basically impossible to know since we never
+got a real debugger data set, which is the only real way to get the actual same
+data inxi will see.
+
+Was it a subshell wrapping the output? We just can't know, nor are we likely to
+ever find out.
+
+This highlights very well however why some issues are essentially impossible to
+ever fully resolve without the --debug 22 dataset. This bug/fix is definitely in
+that class of issues.
+
+It's never good to accuse another program of having a bug when it doesn't, so
+sorry to ps authors, no bug or issue exists for ps in this area.
+
+--------------------------------------------------------------------------------
+KNOWN ISSUES:
+
+1. wiryonolau issue #259 points out that if --tty is used, default IRC filter
+rule is still active and on. Because his case appears to be from an autostart
+using Bash, which then gives up to find the parent at dash, which then makes
+inxi believe it's in an IRC shell client, that issue doesn't appear to be
+resolvable.
+
+--------------------------------------------------------------------------------
+BUGS:
+
+1. Documentation, help menu and man page showed wmctl instead of wmctrl,
+which for someone who reads the help man, leads to command --fake wmctl failing.
+Thanks manjaro user alven for finding this typo.
+
+2. For dmidecode cpu data, had global total values for cache that could result
+in wrong output values, 2x or more wrong for L1 / L3 cache on linux. Difficulty
+is preserving that data for bsd, which in general do not show phys cpu counts,
+and thus make showing totals off. Created new '-total' item for each L cache
+type, which will handle > 1 cpus, and also can be used to determine if > 1 cpus
+present!.
+
+3. Manjaro user pointed out that hub types were wrong, this is because inxi was
+using the INTERFACE ID values for hubs instead of the TYPE values. For all other
+device types, INTERFACE is correct, but for hubs, we needed TYPE, so fix is to
+detect INTERFACE 9/0/0 and if TYPE present for that, swap.
+
+--------------------------------------------------------------------------------
+FIXES:
+
+1. For > 1 cpu systems, with dmidecode sourced cpu cache data, can now determine
+physical cpu count based on comparing L2 and L2-total values. This means that
+when dmidecode is used on BSD for CPU data, inxi may now be able to deduce that
+it is a > 1 cpu system.
+
+2. Forgot to set $run{'filter'} to 0 for whitelist start client detection.
+
+3. Going along with bug 3, changed 'Full speed (or root) hub' to:
+Full speed or root hub, to make more clear that it's one or the other, or both.
+
+4. For apply_filter(), added test if <superuser required> just return the
+string.
+
+--------------------------------------------------------------------------------
+ENHANCEMENTS:
+
+1. Going with bug 1, and fix 1, for > 1 cpu systems, will now show for all
+cache: items L1: 2x 1.5 MiB (3 MiB), same for L2 and L3. This is far less
+confusing than showing the totals without explaining what they are.
+
+2. Going along with 1, now root is not required to show L1 and L3 -Cxx on Linux
+as long as the system is reasonably new, about after 2008, and has getconf -a
+supported. That support is came in somewhere around 2.10, not sure exactly when.
+Debian Etch had it, Sarge did not, Ubuntu 9.10 had it. Tinycore does not have
+getconf at all. This will probably be replaced by a more robust full cpu /sys
+data tool.
+
+3. Added ht to default short -Cx flag list, that should show, and it's short.
+
+4. Added --no-filter to activate -Z, --filter-override isn't consistent with
+other --no-xxx options, even I forgot it. No changes, just another way to use
+-Z.
+
+5. For issue #260 added pch as a new sensor output type, it's kind of a builtin
+southbridge / northbridge in the CPU die, but it's not a core, and has a
+different temp. Will anyone even know what pch is? probably not, but who cares.
+
+--------------------------------------------------------------------------------
+CHANGES:
+
+1. No longer showing for > 1 physical cpu systems the sum total of L1/2/3 cache
+data. Now shows per cpu L1/L2/L3, and if > 1 cpu, shows for example:
+
+cache: L1: 2x 512 KiB (1024 KiB) L2: 2x 2 MiB (4 MiB) L3: 2x 20 MiB (40 MiB)
+
+For single physical cpu output remains the same:
+
+cache: L1: 576 KiB L2: 3 MiB L3: 16 MiB
+
+--------------------------------------------------------------------------------
+DOCUMENTATION:
+
+1. Updated help/man for L1/L3 cache -Cxx changes.
+
+2. Updated man and help to suggest -Z for --tty.
+
+3. Forgot to note -v 7 adds -f, added to man/help.
+
+--------------------------------------------------------------------------------
+CODE:
+
+* Added 'getconf -a' to debugger, that may be usable for cpu cache data, need to
+gather data on that to confirm. that's regading issue #257 cache glitches.
+
+2. Removed all * $physical_count for cache data in cpu_properties, that is now
+handled by creating string with cpu count, per cpu caches, and total in parens.
+
+3. Added in fallback failure case for the ZFS file system issue exposed by
+accident in issue #258 - will now log in debugger the error, so we can try to
+find what is going on there, impossible to reproduce until we find what zfs or
+more likely, freebsd, changed there. Could be hyper specific, some weird thing
+like a person making a zfs device name with space, impossible to guess. Note
+that since the freebsd user declined to supply any data to help resolve this
+issue, then closed it, we're back where we usually end up with FreeBSD issues,
+either a Linux user (or worse, me) willing and able to find the issue and supply
+the debugger data required shows up, OR the issue is ignored as valid but
+impossible to resolve.
+
+RANT: Note that this also confirmed to me that in order to preserve my own
+sanity and not waste endless hours trying to get data, from now on, unless
+utterly trivial, if a FreeBSD user refuses to promptly supply the required data,
+the issue will be closed with a freebsd-closed-no-data-supplied label, which
+means, valid but not possible to solve due to user refusing to help me help
+them.
+
+Come on FreeBSD users!! If you want help, and inxi to support your distro, help
+me help you!! If not, then why are you even filing an issue in the first place?
+Do you expect faeries to spread magic bug / issue fixing faerie dust over inxi
+and then activate it with their little wands? This is growing tiresome to be
+honest because it's so utterly predictable.
+
+4. Shuffled order of sensor type detections, there was a slim chance that a non
+gpu sensor type could have string intel in it, so put the gpu sensors second
+to last, before 'main'.
+
+5. Started refactor of cpu core/cache logic. Added feature to cpu_arch, and
+changed it to cpu_info since now it gives by vendor/family/model/stepping both
+micorarch and cache/core math array returns. Also started refactor to make more
+predictable, with increased comments, about what is going on in cpu_properties
+to avoid breaking existing correct results.
+
+6. Added to --debug /sys cpu data globber tool, that will help debugging the new
+/sys cpu data feature, will let me insert the file data directly into the logic.
+
+7. Added CpuItem::cpu_data_sys() with debuggers, that will now start collecting
+user cpu data whenever the debugger is run, though it's not active yet.
+
+8. Set $Data::Dumper::SortKeys = 1; dugh, could have saved big headaches if had
+found this before. Makes all keys sorted cleanly, gets rid of random hash sorts.
+
+--------------------------------------------------------------------------------
+-- Harald Hope - Mon, 22 Nov 2021 12:45:00 -0700
+
+================================================================================
+Version: 3.3.08
+Patch: 00
+Date: 2021-10-21
+--------------------------------------------------------------------------------
+RELEASE NOTES:
+--------------------------------------------------------------------------------
+
+Bug fix release. 2 bugs that can impact all users under the right circumstances
+were detected and fixed. Thanks manjaro users there for finding and reporting
+those. No other changes.
+
+--------------------------------------------------------------------------------
+KNOWN ISSUES:
+
+None.
+
+--------------------------------------------------------------------------------
+BUGS:
+
+1. Manjaro user ben81 located a critical bug in hardware raid output, this bug
+impacts ALL users of hwraid that run inxi with -xx option. Bug was a bad copy
+paste, the classic, had updated all the pci type data blocks at once, and hw
+raid unfortunately had a slightly different logic due to being part of the more
+complex RAID block of logic. Was trying to use an array, not a hash, reference.
+
+Thanks ben81, I would never have spotted this one, and it would impact 100% of
+all inxi users with hwraid on their machine who ran inxi with -xx option.
+
+2. Also, ps wwaux parser was spitting out an undefined index error. This is
+caused by one of two things:
+
+* ps has an issue, and is apparently at times failing to respect ww, unlimited
+line length, and wrapping anyway. This is the likely cause.
+* the user terminal for some inexpicable reason has decided to hard wrap long
+lines. This is very unlikely, but has to be considered as a possible cause.
+Since these commands run in a subshell, this is VERY unlikely.
+
+Workaround this failure by double checking that line split item is defined, if
+not, next row. Thanks Carpenter for finding that one.
+
+--------------------------------------------------------------------------------
+FIXES:
+
+None.
+
+--------------------------------------------------------------------------------
+ENHANCEMENTS:
+
+None.
+
+--------------------------------------------------------------------------------
+CHANGES:
+
+None.
+
+--------------------------------------------------------------------------------
+DOCUMENTATION:
+
+None.
+
+--------------------------------------------------------------------------------
+CODE:
+
+1. Added workarounds for bug 2. Corrected silly copy/paste error for bug 1.
+
+--------------------------------------------------------------------------------
+-- Harald Hope - Thu, 21 Oct 2021 12:28:15 -0700
+
+================================================================================
Version: 3.3.07
Patch: 00
Date: 2021-10-11