New version, many small fixes. And a hall of shame, LOL.

Bugs:
1. Issue #188 exposed a situation in glxinfo where the required opengl fields are
present but contain null data. This happens when a system does not have the required
opengl drivers, which was the case here. inxi failed to handle that. Thanks
LinuxMonger for posting the required data to figure this corner case out.

2. Fixed a long time bug in Disk vendor ID, there was an eq (string equals)
where it was supposed to use regex pattern match. Oops. Would have led to
disk vendor id failures in several cases.

Fixes:
1. help, man updates for RAM/Memory data, more clarifications.

2. Refactored RepoData class/package, to make it easier to handle repo string
data, and make it all overall cleaner internally, and enable future extensions
to certain features in inxi that may or may not one day become active.

3. Added to some regex compares \Q$VAR\E to disable regex characters in strings.
I should have used that a long time ago, oh well, better late than never!

4. Found a horrible case were xdpyinfo uses 'preferred' instead of the actual
pixel dimensions, shame on whoever allowed that output!!! shame! Had to add
a workaround to make sure numeric values are present, if not, then use the
fallback, which means, 2x more data parsing to get data that should not
require that, but in this example, it did (an Arch derivative, but it could
be xdpyinfo itself, don't know)>

Enhancements:
1. More fixes on issue #185. Thanks tubecleaner for finding and provding required
data to really solve a set of RAM issues that apply particularly in production
systems. This issue report led to 2 new options: --memory-short, which only
shows a basic RAM report.

Memory:    RAM: total: 31.43 GiB used: 14.98 GiB (47.7%)
           Report: arrays: 1 slots: 4 modules: 2 type: DDR4

And a 2nd, --memory-modules, only shows the occupied slots. This can be
useful in situations where it's a server or vm with a lot of slots, most empty:

Memory:    RAM: total: 31.43 GiB used: 15.44 GiB (49.1%)
           Array-1: capacity: 256 GiB slots: 4 EC: None
           Device-1: DIMM 1 size: 16 GiB speed: 2400 MT/s
           Device-2: DIMM 1 size: 16 GiB speed: 2400 MT/s

Note that both of these options trigger -m, so -m itself is not required.

2. More disk vendors!! The list never ends! Thanks linux-lite hardware database
and users for supplying, and buying/obtaining, apparently every disk known to
mankind.

3. Added fallback XFCE detection, in cases were the system does not have xprop
installed, it's still possible to do a full detection of xfce, including toolkit,
so now inxi does that, one less dependency to detect one more desktop.

4. Added vmwgfx driver to xorg drivers list. Note, I've never actually seen this
in the wild, but I did see it as the kernel reported driver from lspci, so it
may exist.

Unfixed:
1. Issue #187 EnochTheWise (?) did not supply the required debugger data so there
is a RAID ZFS issue that will not get fixed until the required debugger data is
supplied. Please do not waste all our time filing an issue if you have no
intention of actually following through so we can get it fixed.

Note that a key way we get issues here is from Perl errors on the screen, which are
a frequent cause of someone realizing something is wrong. This is why I'm not going
to do a hack fix for the RAID ZFS issue, then the error messages will go away, and
it will likely never get handled. For examples of good, useful, productive issue
reports, and how to do them right: #188 and #185, both of which led to good
improvements in how inxi handles corner cases in those areas.
This commit is contained in:
Harald Hope 2019-08-14 11:14:13 -07:00
parent 0757b3a816
commit 92df6e1ae0
3 changed files with 341 additions and 150 deletions

380
inxi
View file

@ -31,8 +31,8 @@ use POSIX qw(uname strftime ttyname);
## INXI INFO ##
my $self_name='inxi';
my $self_version='3.0.35';
my $self_date='2019-07-15';
my $self_version='3.0.36';
my $self_date='2019-08-14';
my $self_patch='00';
## END INXI INFO ##
@ -3907,6 +3907,14 @@ sub get_options{
'm|memory' => sub {
$show{'short'} = 0;
$show{'ram'} = 1; },
'memory-modules' => sub {
$show{'short'} = 0;
$show{'ram'} = 1;
$show{'ram-modules'} = 1;},
'memory-short' => sub {
$show{'short'} = 0;
$show{'ram'} = 1;
$show{'ram-short'} = 1;},
'M|machine' => sub {
$show{'short'} = 0;
$show{'machine'} = 1; },
@ -4502,6 +4510,9 @@ sub show_options {
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." ],
['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
@ -4600,7 +4611,7 @@ sub show_options {
['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)." ],
['2', '-m', '', "Max memory module size (if available), device type." ],
['2', '-m,--memory-modules', '', "Max memory module size (if available), device type." ],
['2', '-N', '', "Specific vendor/product information (if relevant);
PCI Bus ID/USB ID number of card; Version/port(s)/driver version (if available)." ],
['2', '-R', '', "md-raid: second RAID Info line with extra data:
@ -4633,7 +4644,7 @@ sub show_options {
['2', '-I', '', "Other detected installed gcc versions (if present). System
default runlevel. Adds parent program (or tty) for shell info if not in
IRC. Adds Init version number, RC (if found)." ],
['2', '-m', '', "Manufacturer, part number; single/double bank (if found)." ],
['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', '', "md-raid: Superblock (if present), algorithm. If resync,
@ -4662,7 +4673,7 @@ sub show_options {
['2', '-G', '', "Compositor version (if detectable)." ],
['2', '-I', '', "For 'Shell:' adds ([su|sudo|login]) to shell name if present;
for 'running in:' adds (SSH) if SSH session." ],
['2', '-m', '', "Width of memory bus, data and total (if present and greater
['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." ],
@ -5402,6 +5413,8 @@ sub pci_long_filter {
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 {
@ -5434,6 +5447,7 @@ sub row_defaults {
'display-root-x' => 'Advanced graphics data unavailable for root.',
'display-server' => "No display server data found. Headless machine?",
'glxinfo-missing' => "Unable to show advanced data. Required tool glxinfo missing.",
'gl-empty' => 'Unset. Missing GL driver?',
'display-try' => 'Advanced graphics data unavailable in console. Try -G --display',
'dev' => 'Feature under development',
'dmesg-boot-permissions' => 'dmesg.boot permissions',
@ -8746,24 +8760,25 @@ sub device_vendor {
# HM320II HM320II
['(SAMSUNG|^MCG[0-9]+GC|^MCC|^[GS]2 Portable|^DUO\b|^P3|^(HM|SP)[0-9]{2}|^MZMPC|^HD[0-9]{3}[A-Z]{2}$)','SAMSUNG','Samsung',''], # maybe ^SM, ^HM
# Android UMS Composite?
['(SanDisk|^SDS[S]?[DQ]|^SL([0-9]+)G|^AFGCE|ULTRA\sFIT|Clip Sport|Cruzer|^Extreme)','SanDisk','SanDisk',''],
['(SanDisk|^SDS[S]?[DQ]|^SL([0-9]+)G|^AFGCE|^U3\b|ULTRA\sFIT|Clip Sport|Cruzer|^Extreme)','SanDisk','SanDisk',''],
['^STEC\b','^STEC\b','STEC',''], # ssd drive, must come before seagate ST test
# real, SSEAGATE Backup+; XP1600HE30002 | 024 HN (spinpoint)
['(^ST[^T]|[S]?SEAGATE|^X[AFP]|^5AS|^BUP|Expansion Desk|FreeAgent|GoFlex|Backup(\+|\s?Plus)\s?(Hub)?|OneTouch)','[S]?SEAGATE','Seagate',''],
['^(WD|WL[0]9]|Western Digital|My (Book|Passport)|\d*LPCX|Elements|M000|EARX|EFRX|\d*EAVS|0JD|JPVX|[0-9]+(BEV|(00)?AAK|AAV|AZL|EA[CD]S))','(^WDC|Western\s?Digital)','Western Digital',''],
['^(WD|WL[0]9]|Western Digital|My (Book|Passport)|\d*LPCX|Elements|easystore|MD0|M000|EARX|EFRX|\d*EAVS|0JD|JPVX|[0-9]+(BEV|(00)?AAK|AAV|AZL|EA[CD]S))','(^WDC|Western\s?Digital)','Western Digital',''],
## Then better known ones ##
['^(A-DATA|ADATA|AXN|CH11|HV[1-9])','^(A-DATA|ADATA)','A-Data',''],
['^(A-DATA|ADATA|AXN|CH11|HV[1-9]|IM2)','^(A-DATA|ADATA)','A-Data',''],
['^ADTRON','^(ADTRON)','Adtron',''],
['^ASUS','^ASUS','ASUS',''],
# ATCS05 can be hitachi travelstar but not sure
['^ATP','^ATP[\s\-]','ATP',''],
# Force MP500
['^(Corsair|Force\s|(Flash\s*)?Voyager)','^Corsair','Corsair',''],
['^(FUJITSU|MH[TVWYZ][0-9]|MP|MAP[0-9])','^FUJITSU','Fujitsu',''],
['^(FUJITSU|MJA|MH[TVWYZ][0-9]|MP|MAP[0-9])','^FUJITSU','Fujitsu',''],
# note: 2012: wdc bought hgst
['^(HGST|Touro|5450)','^HGST','HGST (Hitachi)',''], # HGST HUA
['^(Hitachi|HD[ST]|DK[0-9]|IC|HT|HU)','^Hitachi','Hitachi',''],
# vb: VB0250EAVER but clashes with vbox; HP_SSD_S700_120G ;GB0500EAFYL GB starter too generic?
['^(HP\b|MB0|G[BJ]0|v[0-9]{3}[bgorw]$|x[0-9]{3}[w]$)','^HP','HP',''],
['^(HP\b|MB[0-6]|G[BJ]0|v[0-9]{3}[bgorw]$|x[0-9]{3}[w]$)','^HP','HP',''],
['^(LSD|Lexar|JumpDrive|JD\s?Firefly)','^Lexar','Lexar',''], # mmc-LEXAR_0xb016546c; JD Firefly;
# OCZSSD2-2VTXE120G is OCZ-VERTEX2_3.5
['^(OCZ|APOC|D2|DEN|DEN|DRSAK|EC188|FTNC|GFGC|MANG|MMOC|NIMC|NIMR|PSIR|RALLY2|TALOS2|TMSC|TRSAK)','^OCZ[\s\-]','OCZ',''],
@ -8787,14 +8802,16 @@ sub device_vendor {
['^(APPLE|iPod)','^APPLE','Apple',''],
['^(AP|Apacer)','^Apacer','Apacer',''],
['^(A-?RAM|ARSSD)','^A-?RAM','A-RAM',''],
['^Asgard','^Asgard','Asgard',''],
['^(ASM|2115)','^ASM','ASMedia',''],#asm1153e
['^Bell\b','^Bell','Packard Bell',''],
['^BHT','^BHT','BHT',''],
['^BIOSTAR','^BIOSTAR','Biostar',''],
['^BIWIN','^BIWIN','BIWIN',''],
['^BUFFALO','^BUFFALO','Buffalo',''],
['^Bulldozer','^Bulldozer','Bulldozer',''],
['^Centerm','^Centerm','Centerm',''],
['^Centon','^Centon','Centonm',''],
['^Centon','^Centon','Centon',''],
['^CHN\b','','Zheino',''],
['^Clover','^Clover','Clover',''],
['^Colorful\b','^Colorful','Colorful',''],
@ -8808,9 +8825,10 @@ sub device_vendor {
['^Dogfish','^Dogfish','Dogfish',''],
['^DragonDiamond','^DragonDiamond','DragonDiamond',''],
['^DREVO\b','^DREVO','Drevo',''],
# DX1100 is probably sandisk, but could be HP, or it could be hp branded sandisk
['^(Eaget|V8$)','^Eaget','Eaget',''],
['^EDGE','^EDGE','EDGE',''],
['^Elecom','^ElecomE','Elecom',''],
['^Elecom','^Elecom','Elecom',''],
['^EXCELSTOR','^EXCELSTOR( TECHNO(LOGY)?)?','ExcelStor',''],
['^EZLINK','^EZLINK','EZLINK',''],
['^Fantom','^Fantom( Drive[s]?)?','Fantom Drives',''],
@ -8818,7 +8836,7 @@ sub device_vendor {
['^FASTDISK','^FASTDISK','FASTDISK',''],
# FK0032CAAZP/FB160C4081 FK or FV can be HP but can be other things
['^FORESEE','^FORESEE','Foresee',''],
['^GALAX\b','^GALAX','GALAX',''],
['^(GALAX\b|Gamer\s?L)','^GALAX','GALAX',''],
['^Galaxy\b','^Galaxy','Galaxy',''],
['^(Garmin|Fenix)','^Garmin','Garmin',''],
['^Geil','^Geil','Geil',''],
@ -8845,7 +8863,7 @@ sub device_vendor {
['^(Iomega|ZIP\b)','^Iomega','Iomega',''],
['^JingX','^JingX','JingX',''], #JingX 120G SSD - not confirmed, but guessing
# NOTE: ITY2 120GB hard to find
['^JMicron','^JMicron','JMicron',''], #JMicron H/W raid
['^JMicron','^JMicron(\s?Tech(nology)?)?','JMicron Tech',''], #JMicron H/W raid
['^KingDian','^KingDian','KingDian',''],
['^Kingfast','^Kingfast','Kingfast',''],
['^KingMAX','^KingMAX','KingMAX',''],
@ -8856,14 +8874,16 @@ sub device_vendor {
['^KLEVV','^KLEVV','KLEVV',''],
['^(Lacie|P92)','^Lacie','Lacie',''],
['^LDLC','^LDLC','LDLC',''],
['^Lenovo','^Lenovo','Lenovo',''],
# LENSE30512GMSP34MEAT3TA
['^LEN','^Lenovo','Lenovo',''],
['^RPFT','','Lenovo O.E.M.',''],
['^LG\b','^LG','LG',''],
['^(LITE[\-\s]?ON[\s\-]?IT)','^LITE[\-]?ON[\s\-]?IT','LITE-ON IT',''], # LITEONIT_LSS-24L6G
['^(LITE[\-\s]?ON|PH[1-9])','^LITE[\-]?ON','LITE-ON',''], # PH6-CE240-L
['^M-Systems','^M-Systems','M-Systems',''],
['^(Mach\s*Xtreme|MXSSD)','^Mach\s*Xtreme','Mach Xtreme',''],
['^(MAXTOR|Atlas|TM[0-9]{4})','^MAXTOR','Maxtor',''], # note M2 M3 is usually maxtor, but can be samsung
['^(Memorex|TravelDrive)','^Memorex','Memorex',''],
['^(Memorex|TravelDrive|TD\s?Classic)','^Memorex','Memorex',''],
# note: C300/400 can be either micron or crucial, but C400 is M4 from crucial
['(^MT|^M5|^Micron|00-MT|C[34]00)','^Micron','Micron',''],# C400-MTFDDAK128MAM
['^MARSHAL\b','^MARSHAL','Marshal',''],
@ -8871,10 +8891,10 @@ sub device_vendor {
['^MDT\b','^MDT','MDT (rebuilt WD/Seagate)',''], # mdt rebuilds wd/seagate hdd
['^Medion','^Medion','Medion',''],
['^(MEDIAMAX|WL[0-9]{2})','^MEDIAMAX','MediaMax',''],
['^Monster\s?Digital','^Monster\s?Digital','Monster Digital',''],
['^Morebeck','^Morebeck','Morebeck',''],
['^Motorola','^Motorola','Motorola',''],
['^MTRON','^MTRON','MTRON',''],
['^MXSSD','^Mach\s*Xtreme','Mach Xtreme',''],
['^Netac','^Netac','Netac',''],
['^OOS[1-9]','','Utania',''],
['^OWC','^OWC\b','OWC',''],
@ -8943,7 +8963,15 @@ sub device_vendor {
foreach my $row (@vendors){
if ($model =~ /$row->[0]/i || ($row->[3] && $serial && $serial =~ /$row->[3]/)){
$vendor = $row->[2];
$model =~ s/$row->[1]//i if $row->[1] && lc($model) ne lc($row->[1]);
# Usually we want to assign N/A at output phase, maybe do this logic there?
if ($row->[1]){
if ($model !~ m/$row->[1]$/i){
$model =~ s/$row->[1]//i;
}
else {
$model = 'N/A';
}
}
$model =~ s/^[\s\-_]+|[\s\-_]+$//g;
$model =~ s/\s\s/ /g;
@data = ($vendor,$model);
@ -8954,6 +8982,7 @@ sub device_vendor {
return @data;
}
# Normally hddtemp requires root, but you can set user rights in /etc/sudoers.
# args: $1 - /dev/<disk> to be tested for
sub hdd_temp {
eval $start if $b_log;
@ -9215,6 +9244,8 @@ sub display_data(){
# note: these may not always be set, they won't be out of X, for example
$protocol = $ENV{'XDG_SESSION_TYPE'} if $ENV{'XDG_SESSION_TYPE'};
$protocol = $ENV{'WAYLAND_DISPLAY'} if (!$protocol && $ENV{'WAYLAND_DISPLAY'});
# yes, I've seen this in 2019 distros, sigh
$protocol = '' if $protocol eq 'tty';
# need to confirm that there's a point to this test, I believe no, fails out of x
# loginctl also results in the session id
if (!$protocol && $b_display && $b_force_display){
@ -9293,16 +9324,24 @@ sub display_data(){
my $ref = $graphics{'dimensions'};
if (defined $ref){
my @screens = @$ref;
my $resolution;
if (scalar @screens == 1){
if (my $program = main::check_program('xrandr')){
my $counter = 0;
my @xrandr = main::grabber("$program $display_opt 2>/dev/null",'','strip');
foreach (@xrandr){
$counter++;
if (/^[^\s]+\sconnected\s(primary\s)?([0-9]+)\s*x\s*([0-9]+)\+/){
$resolution = $2 . 'x' . $3 if $2 && $3;
}
my @working = split /\s+/,$_;
# print join "$_\n";
if ($working[1] =~ /\*/){
$working[1] =~ s/\*|\+//g;
$working[1] = sprintf("%.0f",$working[1]);
$working[1] = ($working[1]) ? "$working[1]Hz" : 'N/A';
# case where 0 is 'preferred, sigh.
$working[0] = ($working[0] !~ /[0-9]\s*x\s*[0-9]/ && $resolution) ? $resolution : $working[0];
my $screen = "$working[0]~$working[1]";
if ($graphics{'screens'}){
$graphics{'screens'} = ([@{$graphics{'screens'}},$screen]);
@ -9411,8 +9450,10 @@ sub gl_data(){
#print ("$b_display : $b_root\n");
if ( $b_display){
if (my $program = main::check_program('glxinfo')){
# NOTE: glxinfo -B is not always available, unforunately
# NOTE: glxinfo -B is not always available, unfortunately
my @glxinfo = main::grabber("$program $display_opt 2>/dev/null");
#my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/graphics/glxinfo/glxinfo-ssh-centos.txt";
#my @glxinfo = main::reader($file);
if (!@glxinfo){
my $type = 'display-console';
if ($b_root){
@ -9428,41 +9469,60 @@ sub gl_data(){
}
#print join "\n",@glxinfo,"\n";
my $compat_version = '';
my ($b_compat,@core_profile_version,@direct_render,@renderer,@opengl_version,@working);
my ($b_compat,$b_nogl,@core_profile_version,@direct_render,@renderer,
@opengl_version,@working);
foreach (@glxinfo){
next if /^\s/;
if (/^opengl renderer/i){
@working = split /:\s*/, $_;
$working[1] = main::cleaner($working[1]);
# Allow all mesas
#if ($working[1] =~ /mesa/i){
#
#}
if ($working[1]){
$working[1] = main::cleaner($working[1]);
# Allow all mesas
#if ($working[1] =~ /mesa/i){
#
#}
}
# note: there are cases where gl drivers are missing and empty
# field value occurs.
else {
$b_nogl = 1;
$working[1] = main::row_defaults('gl-empty');
}
push @renderer, $working[1];
}
# dropping all conditions from this test to just show full mesa information
# there is a user case where not f and mesa apply, atom mobo
# /opengl version/ && ( f || $2 !~ /mesa/ ) {
elsif (/^opengl version/i){
# fglrx started appearing with this extra string, does not appear
# to communicate anything of value
@working = split /:\s*/, $_;
$working[1] =~ s/(Compatibility Profile Context|\(Compatibility Profile\))//;
$working[1] =~ s/\s\s/ /g;
$working[1] =~ s/^\s+|\s+$//;
push @opengl_version, $working[1];
# note: this is going to be off if ever multi opengl versions appear, never seen one
@working = split /\s+/, $working[1];
$compat_version = $working[0];
if ($working[1]){
# fglrx started appearing with this extra string, does not appear
# to communicate anything of value
$working[1] =~ s/(Compatibility Profile Context|\(Compatibility Profile\))//;
$working[1] =~ s/\s\s/ /g;
$working[1] =~ s/^\s+|\s+$//;
push @opengl_version, $working[1];
# note: this is going to be off if ever multi opengl versions appear,
# never seen one
@working = split /\s+/, $working[1];
$compat_version = $working[0];
}
elsif (!$b_nogl) {
push @opengl_version, main::row_defaults('gl-empty');
}
}
elsif (/^opengl core profile version/i){
# fglrx started appearing with this extra string, does not appear
# to communicate anything of value
@working = split /:\s*/, $_;
$working[1] =~ s/(Compatibility Profile Context|\((Compatibility|Core) Profile\))//;
$working[1] =~ s/\s\s/ /g;
$working[1] =~ s/^\s+|\s+$//;
push @core_profile_version, $working[1];
# note: no need to apply empty message here since we don't have the data
# anyway
if ($working[1]){
# fglrx started appearing with this extra string, does not appear
# to communicate anything of value
$working[1] =~ s/(Compatibility Profile Context|\((Compatibility|Core) Profile\))//;
$working[1] =~ s/\s\s/ /g;
$working[1] =~ s/^\s+|\s+$//;
push @core_profile_version, $working[1];
}
}
elsif (/direct rendering/){
@working = split /:\s*/, $_;
@ -9487,10 +9547,9 @@ sub gl_data(){
$renderer = join ', ', @renderer if @renderer;
@row = ({
main::key($num++,'OpenGL') => '',
main::key($num++,'renderer') => $renderer,
main::key($num++,'v') => $version,
main::key($num++,'renderer') => ($renderer) ? $renderer : 'N/A',
main::key($num++,'v') => ($version) ? $version : 'N/A',
});
if ($b_compat && $extra > 1 && $compat_version){
$row[0]{main::key($num++,'compat-v')} = $compat_version;
}
@ -9562,7 +9621,8 @@ sub x_drivers {
neomagic newport nouveau nsc nvidia nv openchrome r128 radeonhd radeon
rendition s3virge s3 savage siliconmotion sisimedia sisusb sis
sunbw2 suncg14 suncg3 suncg6 sunffb sunleo suntcx
tdfx tga trident tseng unichrome v4l vboxvideo vesa vga via vmware voodoo);
tdfx tga trident tseng unichrome v4l vboxvideo vesa vga via vmware vmwgfx
voodoo);
# it's much cheaper to grab the simple pattern match then do the expensive one
# in the main loop.
#@xorg = grep {/Failed|Unload|Loading/} @xorg;
@ -10071,7 +10131,7 @@ sub machine_data_soc {
$model = main::dmi_cleaner($model);
$model = (split /\x01|\x02|\x03|\x00/, $model)[0] if $model;
my $device_temp = main::regex_cleaner($soc_machine{'device'});
if ( !$soc_machine{'device'} || ($model && $model !~ /$device_temp/i) ){
if ( !$soc_machine{'device'} || ($model && $model !~ /\Q$device_temp\E/i) ){
$model = main::arm_cleaner($model);
$soc_machine{'model'} = $model;
}
@ -12783,29 +12843,36 @@ sub create_output {
my $num = 0;
my $j = 0;
my (@data,@rows,$b_non_system);
my ($arrays,$modules,$slots,$type_holder) = (0,0,0,'');
foreach (@ram){
$j = scalar @rows;
my %ref = %$_;
$b_non_system = ($ref{'use'} && lc($ref{'use'}) ne 'system memory') ? 1:0 ;
$num = 1;
@data = ({
main::key($num++,'Array') => '',
main::key($num++,'capacity') => process_size($ref{'capacity'}),
});
@rows = (@rows,@data);
if ($ref{'cap-qualifier'}){
$rows[$j]{main::key($num++,'note')} = $ref{'cap-qualifier'};
}
$rows[$j]{main::key($num++,'use')} = $ref{'use'} if $b_non_system;
$rows[$j]{main::key($num++,'slots')} = $ref{'slots'};
$ref{'eec'} ||= 'N/A';
$rows[$j]{main::key($num++,'EC')} = $ref{'eec'};
if ($extra > 0 && (!$b_non_system ||
( main::is_numeric($ref{'max-module-size'}) && $ref{'max-module-size'} > 10 ) ) ){
$rows[$j]{main::key($num++,'max module size')} = process_size($ref{'max-module-size'});
if ($ref{'mod-qualifier'}){
$rows[$j]{main::key($num++,'note')} = $ref{'mod-qualifier'};
if (!$show{'ram-short'}){
$b_non_system = ($ref{'use'} && lc($ref{'use'}) ne 'system memory') ? 1:0 ;
$num = 1;
@data = ({
main::key($num++,'Array') => '',
main::key($num++,'capacity') => process_size($ref{'capacity'}),
});
@rows = (@rows,@data);
if ($ref{'cap-qualifier'}){
$rows[$j]{main::key($num++,'note')} = $ref{'cap-qualifier'};
}
$rows[$j]{main::key($num++,'use')} = $ref{'use'} if $b_non_system;
$rows[$j]{main::key($num++,'slots')} = $ref{'slots'};
$ref{'eec'} ||= 'N/A';
$rows[$j]{main::key($num++,'EC')} = $ref{'eec'};
if ($extra > 0 && (!$b_non_system ||
( main::is_numeric($ref{'max-module-size'}) && $ref{'max-module-size'} > 10 ) ) ){
$rows[$j]{main::key($num++,'max module size')} = process_size($ref{'max-module-size'});
if ($ref{'mod-qualifier'}){
$rows[$j]{main::key($num++,'note')} = $ref{'mod-qualifier'};
}
}
}
else {
$slots += $ref{'slots'} if $ref{'slots'};
$arrays++;
}
foreach my $ref2 ($ref{'modules'}){
next if ref $ref2 ne 'ARRAY';
@ -12817,6 +12884,12 @@ sub create_output {
# multi array setups will start index at next from previous array
next if ref $ref3 ne 'HASH';
my %mod = %$ref3;
if ($show{'ram-short'}){
$modules++ if ($mod{'size'} =~ /^\d/);
$type_holder = $mod{'device-type'} if $mod{'device-type'};
next;
}
next if ($show{'ram-modules'} && $mod{'size'} =~ /\D/);
$mod{'locator'} ||= 'N/A';
@data = ({
main::key($num++,'Device') => $mod{'locator'},
@ -12855,6 +12928,18 @@ sub create_output {
}
}
}
if ($show{'ram-short'}){
$num = 1;
$type_holder ||= 'N/A';
@data = ({
main::key($num++,'Report') => '',
main::key($num++,'arrays') => $arrays,
main::key($num++,'slots') => $slots,
main::key($num++,'modules') => $modules,
main::key($num++,'type') => $type_holder,
});
@rows = (@rows,@data);
}
eval $end if $b_log;
return @rows;
}
@ -13445,11 +13530,11 @@ sub get_repos_linux {
}
}
if (@apt_urls){
$key = repo_builder('active','apt');
$key = repo_data('active','apt');
@apt_urls = url_cleaner(@apt_urls);
}
else {
$key = repo_builder('missing','apt');
$key = repo_data('missing','apt');
}
@data = (
{main::key($num++,$key) => $file},
@ -13497,7 +13582,7 @@ sub get_repos_linux {
}
if (!@rows){
@data = (
{main::key($num++,repo_builder('missing','no-files')) => $pacman },
{main::key($num++,repo_data('missing','files')) => $pacman },
);
@rows = (@rows,@data);
}
@ -13540,11 +13625,11 @@ sub get_repos_linux {
}
}
if (! @content){
$key = repo_builder('missing','slackpkg+');
$key = repo_data('missing','slackpkg+');
}
else {
@content = url_cleaner(@content);
$key = repo_builder('active','slackpkg+');
$key = repo_data('active','slackpkg+');
}
@data = (
{main::key($num++,$key) => $slackpkg_plus},
@ -13612,11 +13697,11 @@ sub get_repos_linux {
push @content, "$title ~ $url";
}
if (! @content){
$key = repo_builder('missing',$repo);
$key = repo_data('missing',$repo);
}
else {
@content = url_cleaner(@content);
$key = repo_builder('active',$repo);
$key = repo_data('active',$repo);
}
@data = (
{main::key($num++,$key) => $_},
@ -13676,11 +13761,11 @@ sub get_repos_linux {
push @content, "$title ~ $url";
}
if (! @content){
$key = repo_builder('missing','portage');
$key = repo_data('missing','portage');
}
else {
@content = url_cleaner(@content);
$key = repo_builder('active','portage');
$key = repo_data('active','portage');
}
@data = (
{main::key($num++,$key) => $_},
@ -13707,11 +13792,11 @@ sub get_repos_linux {
}
}
if (! @content){
$key = repo_builder('missing','cards');
$key = repo_data('missing','cards');
}
else {
@content = url_cleaner(@content);
$key = repo_builder('active','cards');
$key = repo_data('active','cards');
}
@data = (
{main::key($num++,$key) => $cards},
@ -13810,7 +13895,7 @@ sub get_repos_linux {
}
if ($repo && @content){
@content = url_cleaner(@content);
$key = repo_builder('active',$which);
$key = repo_data('active',$which);
@data = (
{main::key($num++,$key) => $repo},
[@content],
@ -13823,7 +13908,7 @@ sub get_repos_linux {
# last one if present
if ($repo && @content){
@content = url_cleaner(@content);
$key = repo_builder('active',$which);
$key = repo_data('active',$which);
@data = (
{main::key($num++,$key) => $repo},
[@content],
@ -13891,11 +13976,11 @@ sub get_repos_bsd {
}
}
if (! @data3){
$key = repo_builder('missing','bsd-package');
$key = repo_data('missing','bsd-package');
}
else {
@data3 = url_cleaner(@data3);
$key = repo_builder('active','bsd-package');
$key = repo_data('active','bsd-package');
}
@data = (
{main::key($num++,$key) => $_},
@ -13926,16 +14011,16 @@ sub get_repos_bsd {
# mesage in that case
if (!@rows){
if ($bsd_type eq 'freebsd'){
$key = repo_builder('missing','freebsd-nf');
$key = repo_data('missing','freebsd-files');
}
elsif ($bsd_type eq 'openbsd'){
$key = repo_builder('missing','openbsd-nf');
$key = repo_data('missing','openbsd-files');
}
elsif ($bsd_type eq 'netbsd'){
$key = repo_builder('missing','netbsd-nf');
$key = repo_data('missing','netbsd-files');
}
else {
$key = repo_builder('missing','bsd-nf');
$key = repo_data('missing','bsd-files');
}
@data = (
{main::key($num++,'Message') => $key},
@ -13946,65 +14031,65 @@ sub get_repos_bsd {
eval $start if $b_log;
return @rows;
}
sub repo_data {
eval $start if $b_log;
my ($status,$type) = @_;
my %keys = (
'apk-active' => 'APK repo',
'apk-missing' => 'No active APK repos in',
'apt-active' => 'Active apt repos in',
'apt-missing' => 'No active apt repos in',
'bsd-files-missing' => 'No BSD pkg server files found',
'bsd-package-active' => 'BSD enabled pkg servers in',
'bsd-package-missing' => 'No enabled BSD pkg servers in',
'cards-active' => 'Active CARDS collections in',
'cards-missing' => 'No active CARDS collections in',
'eopkg-active' => 'Active eopkg repo',
'eopkg-missing' => 'No active eopkg repos found',
'files-missing' => 'No repo files found in',
'freebsd-active' => 'FreeBSD update server',
'freebsd-files-missing' => 'No FreeBSD update server files found',
'freebsd-missing' => 'No FreeBSD update servers in',
'freebsd-pkg-active' => 'FreeBSD default pkg server',
'freebsd-pkg-missing' => 'No FreeBSD default pkg server in',
'netbsd-active' => 'NetBSD pkg servers',
'netbsd-files-missing' => 'No NetBSD pkg server files found',
'netbsd-missing' => 'No NetBSD pkg servers in',
'openbsd-active' => 'OpenBSD pkg mirror',
'openbsd-files-missing' => 'No OpenBSD pkg mirror files found',
'openbsd-missing' => 'No OpenBSD pkg mirrors in',
'pacman-active' => 'Active pacman repo servers in',
'pacman-missing' => 'No active pacman repos in',
'pacman-g2-active' => 'Active pacman-g2 repo servers in',
'pacman-g2-missing' => 'No active pacman-g2 repos in',
'pisi-active' => 'Active pisi repo',
'pisi-missing' => 'No active pisi repos found',
'portage-active' => 'Enabled portage sources in',
'portage-missing' => 'No enabled portage sources in',
'portsnap-active' => 'BSD ports server',
'portsnap-missing' => 'No ports servers in',
'slackpkg-active' => 'slackpkg repos in',
'slackpkg-missing' => 'No active slackpkg repos in',
'slackpkg+-active' => 'slackpkg+ repos in',
'slackpkg+-missing' => 'No active slackpkg+ repos in',
'slaptget-active' => 'slapt-get repos in',
'slaptget-missing' => 'No active slapt-get repos in',
'tce-active' => 'tce mirrors in',
'tce-missing' => 'No tce mirrors in',
'xbps-active' => 'Active xbps repos in',
'xbps-missing' => 'No active xbps repos in',
'yum-active' => 'Active yum repos in',
'yum-missing' => 'No active yum repos in',
'zypp-active' => 'Active zypp repos in',
'zypp-missing' => 'No active zypp repos in',
);
eval $end if $b_log;
return $keys{$type . '-' . $status};
}
sub repo_builder {
eval $start if $b_log;
my ($file,$type,$search,$split,$count) = @_;
my (@content,@data,$missing,$key);
my %unfound = (
'apk' => 'No active APK repos in',
'apt' => 'No active apt repos in',
'bsd-package' => 'No enabled BSD pkg servers in',
'bsd-nf' => 'No BSD pkg server files found',
'cards' => 'No active CARDS collections in',
'eopkg' => 'No active eopkg repos found',
'pacman' => 'No active pacman repos in',
'pacman-g2' => 'No active pacman-g2 repos in',
'pisi' => 'No active pisi repos found',
'portage' => 'No enabled portage sources in',
'portsnap' => 'No ports servers in',
'freebsd' => 'No FreeBSD update servers in',
'freebsd-nf' => 'No FreeBSD update server files found',
'freebsd-pkg' => 'No FreeBSD default pkg server in',
'openbsd' => 'No OpenBSD pkg mirrors in',
'openbsd-nf' => 'No OpenBSD pkg mirror files found',
'netbsd' => 'No NetBSD pkg servers in',
'netbsd-nf' => 'No NetBSD pkg server files found',
'no-files' => 'No repo files found in',
'slackpkg' => 'No active slackpkg repos in',
'slackpkg+' => 'No active slackpkg+ repos in',
'slaptget' => 'No active slapt-get repos in',
'tce' => 'No tce mirrors in',
'xbps' => 'No active xbps repos in',
'yum' => 'No active yum repos in',
'zypp' => 'No active zypp repos in',
);
$missing = $unfound{$type};
return $missing if $file eq 'missing';
my %keys = (
'apk' => 'APK repo',
'apt' => 'Active apt repos in',
'bsd-package' => 'BSD enabled pkg servers in',
'cards' => 'Active CARDS collections in',
'eopkg' => 'Active eopkg repo',
'freebsd' => 'FreeBSD update server',
'freebsd-pkg' => 'FreeBSD default pkg server',
'pacman' => 'Active pacman repo servers in',
'pacman-g2' => 'Active pacman-g2 repo servers in',
'pisi' => 'Active pisi repo',
'portage' => 'Enabled portage sources in',
'portsnap' => 'BSD ports server',
'openbsd' => 'OpenBSD pkg mirror',
'netbsd' => 'NetBSD pkg servers',
'slackpkg' => 'slackpkg repos in',
'slackpkg+' => 'slackpkg+ repos in',
'slaptget' => 'slapt-get repos in',
'tce' => 'tce mirrors in',
'xbps' => 'Active xbps repos in',
'yum' => 'Active yum repos in',
'zypp' => 'Active zypp repos in',
);
$key = $keys{$type};
return $key if $file eq 'active';
my (@content,@data,$key);
push @dbg_files, $file if $debugger_dir;
if (-r $file){
@content = main::reader($file);
@ -14018,9 +14103,10 @@ sub repo_builder {
} @content;
}
if (!@content){
$key = $missing;
$key = repo_data('missing',$type);
}
else {
$key = repo_data('active',$type);
@content = url_cleaner(@content);
}
@data = (
@ -16477,6 +16563,8 @@ sub get_ps_de_data {
['windowlab','windowlab','windowlab','windowlab'],
['wmx','wmx','wmx','wmx'],
['xmonad','xmonad','xmonad','xmonad'],
## fallback for xfce in case no xprop
['xfdesktop','xfdesktop','xfdesktop','xfdesktop'],
);
foreach my $item (@desktops){
# no need to use check program with short list of ps_gui
@ -16485,6 +16573,11 @@ sub get_ps_de_data {
@data = main::program_data($item->[2],$item->[3],0);
$desktop[0] = $data[0];
$desktop[1] = $data[1];
if ($extra > 1 && $item->[0] eq 'xfdesktop'){
@version_data = main::program_data('xfdesktop-toolkit',$item->[0],1);
$desktop[2] = $version_data[0] if $version_data[0];
$desktop[3] = $version_data[1] if $version_data[1];
}
last;
}
}
@ -17692,6 +17785,7 @@ sub get_pci_vendor {
return if !$subsystem;
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);
my @data = split /\s+/, $subsystem;
# when using strings in patterns for regex have to escape them
@ -18133,9 +18227,10 @@ sub pciconf_data {
$vendor = main::cleaner($vendor);
$device = main::cleaner($device);
# handle possible regex in device name, like [ConnectX-3]
# and which could make matches fail
my $device_temp = main::regex_cleaner($device);
if ($vendor && $device){
if (main::regex_cleaner($vendor) !~ /$device_temp/i){
if (main::regex_cleaner($vendor) !~ /\Q$device_temp\E/i){
$device = "$vendor $device";
}
}
@ -18864,7 +18959,8 @@ sub set_ps_gui {
dwm fluxbox flwm flwm_topside fvwm.*-crystal fvwm2 fvwm i3 ion jwm lwm
matchbox-window-manager mwm nawm openbox notion orbital pekwm perceptia
qtile ratpoison sawfish scrotwm spectrwm sway tvtwm twm
waycooler way-cooler windowlab WindowMaker wm2 wmii2 wmii wmx xmonad);
waycooler way-cooler windowlab WindowMaker wm2 wmii2 wmii wmx
xfdesktop xmonad);
@match = (@match,@temp);
}
# wm:

28
inxi.1
View file

@ -1,4 +1,4 @@
.TH INXI 1 "2019\-07\-15" inxi "inxi manual"
.TH INXI 1 "2019\-08\-14" inxi "inxi manual"
.SH NAME
inxi \- Command line system information script for console and IRC
.SH SYNOPSIS
@ -6,11 +6,12 @@ inxi \- Command line system information script for console and IRC
\fBinxi\fR [\fB\-AbBCdDfFGhiIlmMnNopPrRsSuUVwzZ\fR]
\fBinxi\fR [\fB\-c NUMBER\fR] [\fB\-t\fR [\fBc\fR|\fBm\fR|\fBcm\fR|\fBmc\fR]
[\fBNUMBER\fR]] [\fB\-v NUMBER\fR] [\fB\-W LOCATION\fR]
\fBinxi\fR [\fB\-c NUMBER\fR] [\fB\-t\fR
[\fBc\fR|\fBm\fR|\fBcm\fR|\fBmc\fR][\fBNUMBER\fR]]
[\fB\-v NUMBER\fR] [\fB\-W LOCATION\fR]
[\fB\-\-weather\-unit\fR {\fBm\fR|\fBi\fR|\fBmi\fR|\fBim\fR}] [\fB\-y WIDTH\fR]
\fBinxi\fR [\fB\-\-recommends\fR] \fR[\fB\-\-slots\fR] \fR[\fB\-\-usb\fR]
\fBinxi\fR [\fB\-\-memory\-modules\fR] [\fB\-\-memory\-short\fR]
[\fB\-\-recommends\fR] [\fB\-\-slots\fR] [\fB\-\-usb\fR]
\fBinxi\fB [\fB\-x\fR|\fB\-xx\fR|\fB\-xxx\fR|\fB\-a\fR|\fB\-\-admin\fR] \fB\-OPTION(s)\fR
@ -238,6 +239,17 @@ can do to get truly reliable data about the system RAM; maybe one day the kernel
will put this data into \fB/sys\fR, and make it real data, taken from the actual system,
not dmi data. For most people, the data will be right, but a significant percentage of
users will have either a wrong max module size, if present, or max capacity.
See \fB\-\-memory\-modules\fR and \fB\-\-memory\-short\fR if you want a shorter report.
.TP
.B \-\-memory\-modules\fR
Memory (RAM) data. Show only RAM arrays and modules in Memory report.
Skip empty slots. See \fB\-m\fR.
.TP
.B \-\-memory\-short\fR
Memory (RAM) data. Show a one line RAM report in Memory, e.g.
\fBReport: arrays: 1 slots: 4 modules: 2 type: DDR4\fR
See \fB\-m\fR.
.TP
.B \-M\fR,\fB \-\-machine\fR
Show machine data. Device, Motherboard, BIOS, and if present, System Builder (Like Lenovo).
@ -622,7 +634,7 @@ versions.
\- If in shell (i.e. not in IRC client), adds shell version number, if available.
.TP
.B \-x \-m\fR
.B \-x \-m\fR, \fB\-\-memory\-modules\fR
\- If present, adds maximum memory module/device size in the Array line.
Only some systems will have this data available. Shows estimate if it can
generate one.
@ -729,7 +741,7 @@ type defaults.
\- Adds parent program (or tty) that started shell, if not IRC client.
.TP
.B \-xx \-m\fR
.B \-xx \-m\fR, \fB\-\-memory\-modules\fR
\- Adds memory device Manufacturer.
\- Adds memory device Part Number (\fBpart\-no:\fR). Useful for ordering new or
@ -818,7 +830,7 @@ no data will show.
\- For \fBrunning in:\fR adds \fB(SSH)\fR to parent, if present. SSH detection
uses the \fBwho am i\fR test.
.TP
.B \-xxx \-m\fR
.B \-xxx \-m\fR, \fB\-\-memory\-modules\fR
\- Adds memory bus width: primary bus width, and if present, total width. e.g.
\fBbus width: 64 bit (total: 72 bits)\fR. Note that total / data widths are mixed up
sometimes in dmidecode output, so inxi will take the larger value as the total if

View file

@ -1,3 +1,86 @@
=====================================================================================
Version: 3.0.36
Patch: 00
Date: 2019-08-14
-----------------------------------
Changes:
-----------------------------------
New version, many small fixes. And a hall of shame, LOL.
Bugs:
1. Issue #188 exposed a situation in glxinfo where the required opengl fields are
present but contain null data. This happens when a system does not have the required
opengl drivers, which was the case here. inxi failed to handle that. Thanks
LinuxMonger for posting the required data to figure this corner case out.
2. Fixed a long time bug in Disk vendor ID, there was an eq (string equals)
where it was supposed to use regex pattern match. Oops. Would have led to
disk vendor id failures in several cases.
Fixes:
1. help, man updates for RAM/Memory data, more clarifications.
2. Refactored RepoData class/package, to make it easier to handle repo string
data, and make it all overall cleaner internally, and enable future extensions
to certain features in inxi that may or may not one day become active.
3. Added to some regex compares \Q$VAR\E to disable regex characters in strings.
I should have used that a long time ago, oh well, better late than never!
4. Found a horrible case were xdpyinfo uses 'preferred' instead of the actual
pixel dimensions, shame on whoever allowed that output!!! shame! Had to add
a workaround to make sure numeric values are present, if not, then use the
fallback, which means, 2x more data parsing to get data that should not
require that, but in this example, it did (an Arch derivative, but it could
be xdpyinfo itself, don't know)>
Enhancements:
1. More fixes on issue #185. Thanks tubecleaner for finding and provding required
data to really solve a set of RAM issues that apply particularly in production
systems. This issue report led to 2 new options: --memory-short, which only
shows a basic RAM report.
Memory: RAM: total: 31.43 GiB used: 14.98 GiB (47.7%)
Report: arrays: 1 slots: 4 modules: 2 type: DDR4
And a 2nd, --memory-modules, only shows the occupied slots. This can be
useful in situations where it's a server or vm with a lot of slots, most empty:
Memory: RAM: total: 31.43 GiB used: 15.44 GiB (49.1%)
Array-1: capacity: 256 GiB slots: 4 EC: None
Device-1: DIMM 1 size: 16 GiB speed: 2400 MT/s
Device-2: DIMM 1 size: 16 GiB speed: 2400 MT/s
Note that both of these options trigger -m, so -m itself is not required.
2. More disk vendors!! The list never ends! Thanks linux-lite hardware database
and users for supplying, and buying/obtaining, apparently every disk known to
mankind.
3. Added fallback XFCE detection, in cases were the system does not have xprop
installed, it's still possible to do a full detection of xfce, including toolkit,
so now inxi does that, one less dependency to detect one more desktop.
4. Added vmwgfx driver to xorg drivers list. Note, I've never actually seen this
in the wild, but I did see it as the kernel reported driver from lspci, so it
may exist.
Unfixed:
1. Issue #187 EnochTheWise (?) did not supply the required debugger data so there
is a RAID ZFS issue that will not get fixed until the required debugger data is
supplied. Please do not waste all our time filing an issue if you have no
intention of actually following through so we can get it fixed.
Note that a key way we get issues here is from Perl errors on the screen, which are
a frequent cause of someone realizing something is wrong. This is why I'm not going
to do a hack fix for the RAID ZFS issue, then the error messages will go away, and
it will likely never get handled. For examples of good, useful, productive issue
reports, and how to do them right: #188 and #185, both of which led to good
improvements in how inxi handles corner cases in those areas.
-----------------------------------
-- Harald Hope - Wed, 14 Aug 2019 10:47:47 -0700
=====================================================================================
Version: 3.0.35
Patch: 00