summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@ubuntu.com>2018-06-04 23:20:59 -0400
committerLibravatarUnit 193 <unit193@ubuntu.com>2018-06-04 23:20:59 -0400
commitd04e6727be6cbf207739eb675f0cda4012a1274e (patch)
tree7b973830b51f5f9902dc9013013a1c7c123d5fbb
parent8e2439019187be5e6576b6a400d48aed4731354a (diff)
downloadinxi-d04e6727be6cbf207739eb675f0cda4012a1274e.tar.bz2
inxi-d04e6727be6cbf207739eb675f0cda4012a1274e.tar.xz
inxi-d04e6727be6cbf207739eb675f0cda4012a1274e.tar.zst
New upstream version 3.0.11-1upstream/3.0.11-1
-rw-r--r--README.txt13
-rwxr-xr-xinxi696
-rw-r--r--inxi.1110
-rw-r--r--inxi.changelog136
4 files changed, 754 insertions, 201 deletions
diff --git a/README.txt b/README.txt
index 1970c17..df66930 100644
--- a/README.txt
+++ b/README.txt
@@ -66,13 +66,9 @@ OR easy to remember shortcut (which redirects to github):
wget -Nc https://smxi.org/inxi
wget -Nc smxi.org/inxi
-'Tagging' is purely a formality that certain distros can't figure out how to
-do without, that's all. A tag is a pointer to a commit, and has no further
-meaning.
-
NOTE: Just because github calls tagged commits 'Releases' does not mean they
are releases! I can't change the words on the tag page. They are tagged
-commmits, period.
+commmits, period. A tag is a pointer to a commit, and has no further meaning.
-------------------------------------------------------------------------------
DEVELOPMENT BRANCH:
@@ -87,8 +83,11 @@ OR easy to remember shortcut (which redirects to github):
wget -Nc https://smxi.org/pinxi
wget -Nc smxi.org/pinxi
-Once new features have been debugged, tested, and are stable, they will move
-to the master branch.
+Once new features have been debugged, tested, and are reasonably stable, pinxi
+is copied to inxi in the master branch.
+
+It's a good idea to check with pinxi if you want to make sure your issue has
+not been corrected, since pinxi is always equal to or ahead of inxi.
-------------------------------------------------------------------------------
LEGACY BRANCH:
diff --git a/inxi b/inxi
index dc46bb0..5c9e4c7 100755
--- a/inxi
+++ b/inxi
@@ -31,8 +31,8 @@ use POSIX qw(uname strftime ttyname);
## INXI INFO ##
my $self_name='inxi';
-my $self_version='3.0.09';
-my $self_date='2018-05-11';
+my $self_version='3.0.11';
+my $self_date='2018-06-04';
my $self_patch='00';
## END INXI INFO ##
@@ -64,8 +64,8 @@ my (@dm_boot_disk,@dm_boot_optical,@glabel,@gpart,@labels,@lsblk,@partitions,
my @test = (0,0,0,0,0);
## Booleans
-my ($b_arm,$b_console_irc,$b_debug_gz,$b_display,$b_dmesg_boot_check,$b_dmi,
-$b_dmidecode_force,$b_fake_bsd,$b_fake_dboot,$b_fake_pciconf,$b_fake_sysctl,
+my ($b_admin,$b_arm,$b_console_irc,$b_debug_gz,$b_display,$b_dmesg_boot_check,
+$b_dmi,$b_dmidecode_force,$b_fake_bsd,$b_fake_dboot,$b_fake_pciconf,$b_fake_sysctl,
$b_fake_usbdevs,$b_force_display,$b_gpudata,$b_irc,$b_log,$b_log_colors,
$b_log_full,$b_man,$b_mem,$b_pci,$b_root,$b_running_in_display,$b_sudo,
$b_sysctl,$b_usb_check);
@@ -79,7 +79,7 @@ my ($bsd_type,$language,$os) = ('','','');
my ($bits_sys);
my ($cpu_sleep,$dl_timeout,$limit,$ps_count,$usb_level) = (0.35,4,10,5,0);
my $sensors_cpu_nu = 0;
-my $weather_unit='cf';
+my $weather_unit='mi';
## Tools
my ($display,$ftp_alt,$tty_session);
@@ -176,17 +176,32 @@ sub check_tools {
if ( $b_dmi ){
$action = 'use';
if ($program = check_program('dmidecode')) {
- my $result = system("$program -t chassis >/dev/null 2>&1");
- if (!$result){
+ @data = grabber("$program -t chassis -t baseboard -t processor 2>&1");
+ if (scalar @data < 15){
if ($b_root) {
- @data = grabber("$program --type chassis");
- if ( grep { $_ =~ /No SMBIOS/i } @data ){
- $action = 'smbios';
+ foreach (@data){
+ if ($_ =~ /No SMBIOS/i){
+ $action = 'smbios';
+ last;
+ }
+ elsif ($_ =~ /^\/dev\/mem: Operation/i){
+ $action = 'no-data';
+ last;
+ }
+ else {
+ $action = 'unknown-error';
+ last;
+ }
+ }
+ }
+ else {
+ if (grep { $_ =~ /^\/dev\/mem: Permission/i } @data){
+ $action = 'permissions';
+ }
+ else {
+ $action = 'unknown-error';
}
}
- }
- elsif ($result){
- $action = 'permissions';
}
}
else {
@@ -198,6 +213,8 @@ sub check_tools {
'missing' => 'Required program dmidecode not available',
'permissions' => 'Unable to run dmidecode. Are you root?',
'smbios' => 'No SMBIOS data for dmidecode to process',
+ 'no-data' => 'dmidecode is not allowed to read /dev/mem',
+ 'unknown-error' => 'dmidecode was unable to generate data',
},
);
%alerts = (%alerts, %hash);
@@ -457,6 +474,7 @@ sub set_user_paths {
# initialize function directly.
$self_path = $0;
$self_path =~ s/[^\/]+$//;
+ # print "0: $0 sp: $self_path\n";
if ( defined $ENV{'XDG_CONFIG_HOME'} && $ENV{'XDG_CONFIG_HOME'} ){
$user_config_dir=$ENV{'XDG_CONFIG_HOME'};
@@ -852,7 +870,7 @@ sub get_selection {
@data = ();
my $response = <STDIN>;
chomp $response;
- if ($response =~ /[^0-9]/ || $response > ($count + 3)){
+ if ($response =~ /([^0-9]|^$)/ || ( $response =~ /^[0-9]+$/ && $response > ($count + 3) )){
@data = (
[0, '', '', "Error - Invalid Selection. You entered this: $response. Hit <ENTER> to continue."],
[0, '', '', "$line1"],
@@ -1024,7 +1042,14 @@ sub get_config_item {
elsif ($key eq 'PS_COUNT') {$ps_count = int($val) }
elsif ($key eq 'SENSORS_CPU_NO') {$sensors_cpu_nu = int($val)}
elsif ($key eq 'SHOW_HOST' || $key eq 'B_SHOW_HOST') { $show{'host'} = int($val)}
- elsif ($key eq 'WEATHER_UNIT') { $weather_unit = lc($val) if $val =~ /^(c|f|cf|fc)$/i}
+ elsif ($key eq 'WEATHER_UNIT') {
+ $val = lc($val) if $val;
+ if ($val && $val =~ /^(c|f|cf|fc|i|m|im|mi)$/){
+ my %units = ('c'=>'m','f'=>'i','cf'=>'mi','fc'=>'im');
+ $val = $units{$val} if defined $units{$val};
+ $weather_unit = $val;
+ }
+ }
# layout
elsif ($key eq 'CONSOLE_COLOR_SCHEME') {$colors{'console'} = int($val)}
elsif ($key eq 'GLOBAL_COLOR_SCHEME') {$colors{'global'} = int($val)}
@@ -1211,10 +1236,7 @@ package SystemDebugger;
#use POSIX qw(strftime);
my $option = 'main';
-my $upload = '';
-my $data_dir = '';
-my $debug_dir = '';
-my $debug_gz = '';
+my ($data_dir,$debug_dir,$debug_gz,$parse_src,$upload) = ('','','','','');
my @content = ();
my $b_debug = 0;
my $b_delete_dir = 1;
@@ -1258,6 +1280,13 @@ sub run_debugger {
print "Skipping /sys data collection. /sys not present, or empty.\n";
}
print $line3;
+ if ( -d '/proc' && main::count_dir_files('/proc') ){
+ proc_traverse_data();
+ }
+ else {
+ print "Skipping /proc data collection. /proc not present, or empty.\n";
+ }
+ print $line3;
}
run_self();
print $line3;
@@ -1267,11 +1296,10 @@ sub run_debugger {
sub create_debug_directory {
my $host = main::get_hostname();
$host =~ s/ /-/g;
- $host ||= 'no-host';
+ $host = 'no-host' if !$host || $host eq 'N/A';
my ($arm_string,$bsd_string,$root_string) = ('','','');
# note: Time::Piece was introduced in perl 5.9.5
my ($sec,$min,$hour,$mday,$mon,$year) = localtime;
- my $version = substr($self_version,0,3);
$year = $year+1900;
$mon += 1;
if (length($sec) == 1) {$sec = "0$sec";}
@@ -1287,7 +1315,7 @@ sub create_debug_directory {
}
$bsd_string = "-BSD-$bsd_type" if $bsd_type;
$arm_string = '-ARM' if $b_arm;
- $debug_dir = "$self_name$arm_string$bsd_string-$host-$today$root_string-$version";
+ $debug_dir = "$self_name$arm_string$bsd_string-$host-$today$root_string-$self_version";
$debug_gz = "$debug_dir.tar.gz";
$data_dir = "$user_data_dir/$debug_dir";
if ( -d $data_dir ){
@@ -1639,7 +1667,10 @@ sub system_data {
['systemctl','list-units'],
['systemctl','list-units --type=target'],
['systemd-detect-virt',''],
+ ['upower','-e'],
['uptime',''],
+ ['vcgencmd','get_mem arm'],
+ ['vcgencmd','get_mem gpu'],
);
run_commands(\@cmds,'system');
@files = main::globber('/dev/bus/usb/*/*');
@@ -1681,19 +1712,22 @@ sub system_files {
}
sub copy_files {
- my ($files_ref, $type) = @_;
+ my ($files_ref,$type,$alt_dir) = @_;
my ($absent,$error,$good,$name,$unreadable);
+ my $directory = ($alt_dir) ? $alt_dir : $data_dir;
+ my $working = ($type ne 'proc') ? "$type-file-": '';
foreach (@$files_ref) {
$name = $_;
$name =~ s/^\///;
- $name =~ s/\//-/g;
- $name = "$data_dir/$type-file-$name";
+ $name =~ s/\//~/g;
+ $name = "$directory/$working$name";
$good = $name . '.txt';
$absent = $name . '-absent';
$error = $name . '-error';
$unreadable = $name . '-unreadable';
- if (-e $_ ) {
- if (-r $_){
+ # proc have already been tested for readable/exists
+ if ($type eq 'proc' || -e $_ ) {
+ if ($type eq 'proc' || -r $_){
copy($_,"$good") or main::toucher($error);
}
else {
@@ -1846,30 +1880,50 @@ sub sys_traverse_data {
print "Parsing /sys files...\n";
# get rid pointless error:Can't cd to (/sys/kernel/) debug: Permission denied
no warnings 'File::Find';
+ $parse_src = 'sys';
File::Find::find( \&wanted, "/sys");
- process_data();
+ process_sys_data();
+ @content = ();
+}
+sub proc_traverse_data {
+ print "Parsing /proc files...\n";
+ # get rid pointless error:Can't cd to (/sys/kernel/) debug: Permission denied
+ no warnings 'File::Find';
+ $parse_src = 'proc';
+ File::Find::find( \&wanted, "/proc");
+ process_proc_data();
+ @content = ();
}
sub wanted {
return if -d; # not directory
return unless -e; # Must exist
- return unless -r; # Must be readable
return unless -f; # Must be file
- # note: a new file in 4.11 /sys can hang this, it is /parameter/ then
- # a few variables. Since inxi does not need to see that file, we will
- # not use it. Also do not need . files or __ starting files
- # print $File::Find::name . "\n";
- # block maybe: cfgroup\/
- return if $File::Find::name =~ /\/(\.[a-z]|kernel\/|parameters\/|debug\/)/;
- # comment this one out if you experience hangs or if
- # we discover syntax of foreign language characters
- # Must be ascii like. This is questionable and might require further
- # investigation, it is removing some characters that we might want
- return unless -T;
+ return unless -r; # Must be readable
+ if ($parse_src eq 'sys'){
+ # note: a new file in 4.11 /sys can hang this, it is /parameter/ then
+ # a few variables. Since inxi does not need to see that file, we will
+ # not use it. Also do not need . files or __ starting files
+ # print $File::Find::name . "\n";
+ # block maybe: cfgroup\/
+ return if $File::Find::name =~ /\/(\.[a-z]|kernel\/|parameters\/|debug\/)/;
+ # comment this one out if you experience hangs or if
+ # we discover syntax of foreign language characters
+ # Must be ascii like. This is questionable and might require further
+ # investigation, it is removing some characters that we might want
+ return unless -T;
+ }
+ elsif ($parse_src eq 'proc') {
+ return if $File::Find::name =~ /^\/proc\/[0-9]+\//;
+ return if $File::Find::name =~ /^\/proc\/bus\/pci\//;
+ return if $File::Find::name =~ /^\/proc\/irq\//;
+ return if $File::Find::name =~ /(\/mb_groups|debug)$/;
+ return if $File::Find::name eq '/proc/kallsyms' || $File::Find::name eq '/proc/keys';
+ }
# print $File::Find::name . "\n";
push (@content, $File::Find::name);
return;
}
-sub process_data {
+sub process_sys_data {
my ($data,$fh,$result,$row,$sep);
my $filename = "sys-data-parse.txt";
# no sorts, we want the order it comes in
@@ -1892,6 +1946,16 @@ sub process_data {
close $fh;
# print $fh "$result";
}
+sub process_proc_data {
+ my ($data,$fh,$result,$row,$sep);
+ my $proc_dir = "$data_dir/proc";
+ mkdir $proc_dir or main::error_handler('mkdir', "$proc_dir", "$!");
+ # @content = sort @content;
+ copy_files(\@content,'proc',$proc_dir);
+# foreach (@content){
+# print "$_\n";
+# }
+}
# args: 1 - path to file to be uploaded
# args: 2 - optional: alternate ftp upload url
# NOTE: must be in format: ftp.site.com/incoming
@@ -2111,8 +2175,10 @@ sub set_perl_downloader {
#### -------------------------------------------------------------------
sub error_handler {
+ eval $start if $b_log;
my ( $err, $one, $two) = @_;
- my ($b_recommends,$b_help,$errno) = (0,0,0);
+ my ($b_help,$b_recommends);
+ my ($b_exit,$errno) = (1,0);
my $message = do {
if ( $err eq 'empty' ) { 'empty value' }
## Basic rules
@@ -2146,7 +2212,7 @@ sub error_handler {
elsif ( $err eq 'mkdir' ) {
$errno=44; "Error creating directory: $one \nError: $two" }
elsif ( $err eq 'open' ) {
- $errno=45; "Error opening file: $one \nError: $two" }
+ $errno=45; $b_exit=0; "Error opening file: $one \nError: $two" }
elsif ( $err eq 'open-dir' ) {
$errno=46; "Error opening directory: $one \nError: $two" }
elsif ( $err eq 'output-file-bad' ) {
@@ -2187,7 +2253,8 @@ sub error_handler {
if ($b_recommends){
print_line("See --recommends for more information.\n");
}
- exit 0;
+ eval $end if $b_log;
+ exit 0 if $b_exit;
}
sub error_defaults {
@@ -2281,12 +2348,12 @@ sub check_items {
elsif ($type eq 'recommended system programs'){
if ($bsd_type){
@data = qw(camcontrol dig dmidecode fdisk file glabel gpart ifconfig ipmi-sensors
- ipmitool lsusb sudo smartctl sysctl tree uptime usbdevs);
+ ipmitool lsusb sudo smartctl sysctl tree upower uptime usbdevs);
$info_os = 'info-bsd';
}
else {
@data = qw(dig dmidecode fdisk file hddtemp ifconfig ip ipmitool ipmi-sensors
- lsblk lsusb modinfo runlevel sensors strings sudo tree uptime);
+ lsblk lsusb modinfo runlevel sensors strings sudo tree upower uptime);
}
$b_program = 1;
$item = 'Program';
@@ -2659,6 +2726,13 @@ sub item_data {
'pacman' => 'tree',
'rpm' => 'tree',
}),
+ 'upower' => ({
+ 'info' => '-sx attached device battery info',
+ 'info-bsd' => '-sx attached device battery info',
+ 'apt' => 'upower',
+ 'pacman' => 'upower',
+ 'rpm' => 'upower',
+ }),
'uptime' => ({
'info' => '-I uptime',
'info-bsd' => '-I uptime',
@@ -3397,6 +3471,8 @@ sub get_options{
my ($b_downloader,$b_help,$b_no_man,$b_no_man_force,$b_recommends,$b_updater,$b_version,
$b_use_man,$self_download, $download_id);
GetOptions (
+ 'admin' => sub {
+ $b_admin = 1;},
'A|audio' => sub {
$show{'short'} = 0;
$show{'audio'} = 1;},
@@ -3652,8 +3728,11 @@ sub get_options{
my ($opt,$arg) = @_;
$arg ||= '';
$arg =~ s/\s//g;
- if ($arg && $arg =~ /^(cf|fc|f|c)$/i){
- $weather_unit = lc($arg);
+ $arg = lc($arg) if $arg;
+ if ($arg && $arg =~ /^(c|f|cf|fc|i|m|im|mi)$/){
+ my %units = ('c'=>'m','f'=>'i','cf'=>'mi','fc'=>'im');
+ $arg = $units{$arg} if defined $units{$arg};
+ $weather_unit = $arg;
}
else {
error_handler('bad-arg',$opt,$arg);
@@ -3961,7 +4040,7 @@ sub show_options {
['0', '', '', "Output Control Options:" ],
['1', '-A', '--audio', "Audio/sound card(s), driver, sound server." ],
['1', '-b', '--basic', "Basic output, short form. Same as $self_name^-v^2." ],
- ['1', '-B', '--battery', "Battery info, including charge and condition, plus
+ ['1', '-B', '--battery', "System battery info, including charge and condition, plus
extra info (if battery present)." ],
['1', '-c', '--color', "Set color scheme (0-42). Example:^$self_name^-c^11" ],
['1', '', '', "Color selectors let you set the config file value for the
@@ -4064,22 +4143,23 @@ sub show_options {
Only use if you 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"],
- ['1', '', '--weather-unit', "Set weather units to metric (m), imperial (f),
- metric/imperial (cf), or imperial/metric (fc)."],
+ ['1', '', '--weather-unit', "Set weather units to metric (m), imperial (i),
+ metric/imperial (mi), or imperial/metric (im)."],
);
push @data, @rows;
}
@rows = (
- ['1', '-x', '-extra', "Adds the following extra data (only works with
+ ['1', '-x', '--extra', "Adds the following extra data (only works with
verbose or line output, not short form):" ],
- ['2', '-B', '', "Vendor/model, status (if available)." ],
+ ['2', '-B', '', "Vendor/model, status (if available); attached devices
+ (e.g. wireless mouse, keyboard, if present)." ],
['2', '-C', '', "CPU $flags, Bogomips on CPU; CPU microarchitecture +
- revision (if found)." ],
+ revision (if found, or unless --admin, then shows as 'stepping')." ],
['2', '-d', '', "Extra optical drive features data; adds rev version to
optical drive." ],
- ['2', '-D', '', "HDD temp with disk data if you have hddtemp installed, if
- you are root, or if you have added to /etc/sudoers (sudo v. 1.7 or newer).
- Example:^<username>^ALL^=^NOPASSWD:^/usr/sbin/hddtemp" ],
+ ['2', '-D', '', "HDD temp with disk data if you have hddtemp installed,
+ if you are root, or if you have added to /etc/sudoers (sudo v. 1.7 or newer).
+ Example:^<username>^ALL^=^NOPASSWD:^/usr/sbin/hddtemp" ],
['2', '-G', '', "Direct rendering status (in X); Screen number GPU is
running on (Nvidia only)." ],
['2', '-i', '', "For IPv6, show additional scope addresses: Global, Site,
@@ -4112,7 +4192,7 @@ sub show_options {
['2', '-A', '', "Chip vendor:product ID for each audio device." ],
['2', '-B', '', "Serial number, voltage now/minimum (if available)." ],
['2', '-C', '', "Minimum CPU speed, if available." ],
- ['2', '-D', '', "Disk serial number." ],
+ ['2', '-D', '', "Disk transfer speed; NVMe lanes; Disk serial number." ],
['2', '-G', '', "Chip vendor:product ID for each video card; OpenGL
compatibility version, if free drivers and available; compositor (experimental)." ],
['2', '-I', '', "Other detected installed gcc versions (if present). System
@@ -4138,7 +4218,8 @@ sub show_options {
['1', '-xxx', '--extra 3', "Show extra, extra, extra data (only works
with verbose or line output, not short form):" ],
['2', '-B', '', "Chemistry, cycles, location (if available)." ],
- ['2', '-D', '', "Firmware rev. if available; partition scheme, in some cases." ],
+ ['2', '-D', '', "Firmware rev. if available; partition scheme, in some cases; disk
+ rotation speed (if detected)." ],
['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
@@ -4155,6 +4236,10 @@ sub show_options {
push @data, @rows;
}
@rows = (
+ ['1', '', '--admin', "Adds advanced sys admin data (only works with
+ verbose or line output, not short form):" ],
+ ['2', '-C', '', "If available: CPU errata (bugs); family, model-id, stepping - format:
+ hex (decimal) if greater than 9, otherwise hex; microcode - format: hex." ],
['1', '-y', '--width', "Output line width max (integer >= 80). Overrides IRC/Terminal
settings or actual widths. Example:^inxi^-y^130" ],
['1', '-z', '--filter', "Adds security filters for IP/MAC addresses, serial numbers,
@@ -4681,11 +4766,13 @@ sub clean_characters {
my ($data) = @_;
# newline, pipe, brackets, + sign, with space, then clear doubled
# spaces and then strip out trailing/leading spaces.
- $data =~ s/\n|\|\+|\[\s\]|\s\s+/ /g if $data;
- $data =~ s/^\s+|\s+$//g if $data;
+ # etc/issue often has junk stuff like (\l) \n \l
+ return if ! $data;
+ $data =~ s/[:\47]|\\[a-z]|\n|,|\"|\*|\||\+|\[\s\]|n\/a|\s\s+/ /g;
+ $data =~ s/\(\)//;
+ $data =~ s/^\s+|\s+$//g;
return $data;
}
-
sub cleaner {
my ($item) = @_;
return $item if !$item;# handle cases where it was 0 or ''
@@ -4700,6 +4787,7 @@ sub cleaner {
sub disk_cleaner {
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;
@@ -4839,7 +4927,7 @@ sub row_defaults {
my %unfound = (
'arm-cpu-f' => 'Use -f option to see features',
'arm-pci' => "PCI data type is not supported on ARM systems.",
- 'battery-data' => "No battery data found. Is one present?",
+ 'battery-data' => "No system battery data found. Is one present?",
'battery-data-sys' => "No /sys data found. Old system?",
'cpu-model-null' => "Model N/A",
'darwin-feature' => "Feature not supported iu Darwin/OSX.",
@@ -5597,10 +5685,10 @@ sub sound_server_data {
## BatteryData
{
package BatteryData;
-
+my (@upower_items,$b_upower,$upower);
sub get {
eval $start if $b_log;
- my (@rows,$key1,%battery,$val1);
+ my (@rows,%battery,$key1,$val1);
my $num = 0;
if ($bsd_type || $b_dmidecode_force){
my $ref = $alerts{'dmidecode'};
@@ -5644,6 +5732,7 @@ sub get {
@rows = ({main::key($num++,$key1) => $val1,});
}
}
+ (@upower_items,$b_upower,$upower) = undef;
eval $end if $b_log;
return @rows;
}
@@ -5670,20 +5759,22 @@ sub get {
# 17 location
sub create_output {
eval $start if $b_log;
- my (%battery,@data,@rows) = @_;
- my ($key);
+ my (%battery) = @_;
+ my ($key,@data,@rows);
my $num = 0;
my $j = 0;
+ # print Data::Dumper::Dumper \%battery;
foreach $key (sort keys %battery){
$num = 0;
my ($charge,$condition,$model,$serial,$status,$volts) = ('','','','','','');
my ($chemistry,$cycles,$location) = ('','','');
+ next if !$battery{$key}{'purpose'} || $battery{$key}{'purpose'} ne 'primary';
# $battery{$key}{''};
# we need to handle cases where charge or energy full is 0
- $charge = ($battery{$key}{'energy_now'} || $battery{$key}{'energy_now'} eq 0) ? "$battery{$key}{'energy_now'} Wh" : 'N/A';
+ $charge = (defined $battery{$key}{'energy_now'} && $battery{$key}{'energy_now'} ne '') ? "$battery{$key}{'energy_now'} Wh" : 'N/A';
if ($battery{$key}{'energy_full'} || $battery{$key}{'energy_full_design'}){
$battery{$key}{'energy_full_design'} ||= 'N/A';
- $battery{$key}{'energy_full'}= ($battery{$key}{'energy_full'} || $battery{$key}{'energy_full'} eq 0) ? $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'}%)";
@@ -5741,6 +5832,57 @@ sub create_output {
}
}
}
+ $battery{$key} = undef;
+ }
+ # print Data::Dumper::Dumper \%battery;
+ # now if there are any devices left, print them out, excluding Mains
+ if ($extra > 0){
+ $upower = main::check_program('upower');
+ foreach $key (sort keys %battery){
+ $num = 0;
+ next if !defined $battery{$key} || $battery{$key}{'purpose'} eq 'mains';
+ my ($charge,$model,$serial,$percent,$status,$vendor) = ('','','','','','');
+ my (%upower_data);
+ $j = scalar @rows;
+ %upower_data = upower_data($key) if $upower;
+ if ($upower_data{'percent'}){
+ $charge = $upower_data{'percent'};
+ }
+ 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' ;
+ $vendor = $battery{$key}{'manufacturer'} if $battery{$key}{'manufacturer'};
+ if ($vendor || $model){
+ if ($vendor && $model){
+ $model = "$vendor $model";
+ }
+ elsif ($vendor){
+ $model = $vendor;
+ }
+ }
+ else {
+ $model = 'N/A';
+ }
+ @data = ({
+ main::key($num++,'Device') => $key,
+ main::key($num++,'model') => $model,
+ },);
+ @rows = (@rows,@data);
+ if ($extra > 1){
+ $serial = main::apply_filter($battery{$key}{'serial_number'});
+ $rows[$j]{main::key($num++,'serial')} = $serial;
+ }
+ $rows[$j]{main::key($num++,'charge')} = $charge;
+ if ($extra > 2 && $upower_data{'rechargeable'}){
+ $rows[$j]{main::key($num++,'rechargeable')} = $upower_data{'rechargeable'};
+ }
+ $rows[$j]{main::key($num++,'status')} = $status;
+ }
}
eval $end if $b_log;
return @rows;
@@ -5751,10 +5893,9 @@ sub battery_data_sys {
eval $start if $b_log;
my ($b_ma,%battery,$file,$id,$item,$path,$value);
my $num = 0;
- # NOTE: known ids: BAT[0-9] CMB[0-9]
- my @batteries = main::globber("/sys/class/power_supply/[BC][AM][TB]*/");
+ my @batteries = main::globber("/sys/class/power_supply/*");
# note: there is no 'location' file, but dmidecode has it
- # 'type' is generic, like: Battery
+ # 'type' is generic, like: Battery, Mains
# capacity_level is a string, like: Normal
my @items = qw(alarm capacity capacity_level charge_full charge_full_design charge_now
cycle_count energy_full energy_full_design energy_now location manufacturer model_name
@@ -5762,11 +5903,20 @@ sub battery_data_sys {
foreach $item (@batteries){
$b_ma = 0;
$id = $item;
- $id =~ s%/sys/class/power_supply/|\/$%%g;
+ $id =~ s%/sys/class/power_supply/%%g;
+ my $purpose = ($id =~ /^(BAT|CMB).*$/) ? 'primary': 'device';
+ # don't create arrays of device data if it's not going to show
+ next if $extra == 0 && $purpose ne 'primary';
$battery{$id} = ({});
+ # NOTE: known ids: BAT[0-9] CMB[0-9]
+ $battery{$id}{'purpose'} = $purpose;
foreach $file (@items){
- $path = "$item$file";
+ $path = "$item/$file";
$value = (-f $path) ? (main::reader($path))[0]: '';
+ # mains
+ if ($file eq 'type' && $value && lc($value) ne 'battery' ){
+ $battery{$id}{'purpose'} = 'mains';
+ }
if ($value){
if ($file eq 'voltage_min_design'){
$value = sprintf("%.1f", $value/1000000);
@@ -5860,6 +6010,7 @@ sub battery_data_dmi {
$id = "BAT$i";
$i++;
$battery{$id} = ({});
+ $battery{$id}{'purpose'} = 'primary';
# skip first three row, we don't need that data
splice @ref, 0, 3 if @ref;
foreach my $item (@ref){
@@ -5873,7 +6024,6 @@ sub battery_data_dmi {
elsif ($value[0] eq 'Design Capacity') {
$value[1] =~ s/\s*mwh$//i;
$battery{$id}{'energy_full_design'} = sprintf( "%.1f", $value[1]/1000);
-
}
elsif ($value[0] eq 'Design Voltage') {
$value[1] =~ s/\s*mv$//i;
@@ -5897,6 +6047,35 @@ sub battery_data_dmi {
eval $end if $b_log;
return %battery;
}
+sub upower_data {
+ my ($id) = @_;
+ eval $start if $b_log;
+ my (%data);
+ if (!$b_upower && $upower){
+ @upower_items = main::grabber("$upower -e",'','strip');
+ $b_upower = 1;
+ }
+ if ($upower && @upower_items){
+ foreach (@upower_items){
+ if ($_ =~ /$id/){
+ my @working = main::grabber("$upower -i $_",'','strip');
+ foreach my $row (@working){
+ my @temp = split /\s*:\s*/, $row;
+ if ($temp[0] eq 'percentage'){
+ $data{'percent'} = $temp[1];
+ }
+ elsif ($temp[0] eq 'rechargeable'){
+ $data{'rechargeable'} = $temp[1];
+ }
+ }
+ last;
+ }
+ }
+ }
+ eval $end if $b_log;
+ return %data;
+}
+
}
## CpuData
@@ -5967,10 +6146,18 @@ sub create_output_full {
if ($extra > 0){
$cpu{'arch'} ||= 'N/A';
$rows[$j]{main::key($num++,'arch')} = $cpu{'arch'};
- if ( $cpu{'arch'} ne 'N/A' && $cpu{'rev'} ){
+ if ( !$b_admin && $cpu{'arch'} ne 'N/A' && $cpu{'rev'} ){
$rows[$j]{main::key($num++,'rev')} = $cpu{'rev'};
}
}
+ if ($b_admin){
+ $rows[$j]{main::key($num++,'family')} = hex_and_decimal($cpu{'family'});
+ $rows[$j]{main::key($num++,'model-id')} = hex_and_decimal($cpu{'model_id'});
+ $rows[$j]{main::key($num++,'stepping')} = hex_and_decimal($cpu{'rev'});
+ $cpu{'microcode'} ||= 'N/A';
+ $rows[$j]{main::key($num++,'microcode')} = $cpu{'microcode'};
+ }
+
$properties{'l2-cache'} ||= 'N/A';
$rows[$j]{main::key($num++,'L2 cache')} = $properties{'l2-cache'} if (!$b_arm || ($b_arm && $properties{'l2-cache'} ne 'N/A'));
if ($extra > 0 && !$show{'cpu-flag'}){
@@ -6030,6 +6217,15 @@ sub create_output_full {
},);
@rows = (@rows,@data);
}
+ if ($b_admin && $cpu{'bugs'}){
+ my @bugs = split /\s+/, $cpu{'bugs'};
+ @bugs = sort(@bugs);
+ my $bug = join ' ', @bugs;
+ @data = ({
+ main::key($num++,'Errata') => $bug,
+ },);
+ @rows = (@rows,@data);
+ }
eval $end if $b_log;
return @rows;
}
@@ -6230,7 +6426,7 @@ sub data_cpuinfo {
}
}
elsif (!$cpu{'rev'} && ($line[0] eq 'stepping' || $line[0] eq 'cpu revision' )){
- $cpu{'rev'} = $line[1];
+ $cpu{'rev'} = uc(sprintf("%x", $line[1]));
}
# this is hex so uc for cpu arch id
elsif (!$cpu{'model_id'} && $line[0] eq 'model' ){
@@ -6325,6 +6521,21 @@ sub data_cpuinfo {
$cpu{'bogomips'} += $line[1] if $line[1] > 50;
}
}
+ if ($b_admin ){
+ 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]));
+ }
+ }
+ }
}
$cpu{'phys'} = scalar @phys_cpus;
$cpu{'dies'} = $die_id++; # count starts at 0, all cpus have 1 die at least
@@ -7093,6 +7304,16 @@ sub cpu_cleaner {
$cpu =~ s/^\s+|\s+$//g;
return $cpu;
}
+sub hex_and_decimal {
+ my ($data) = @_;
+ if ($data){
+ $data .= ' (' . hex($data) . ')' if hex($data) ne $data;
+ }
+ else {
+ $data = 'N/A';
+ }
+ return $data;
+}
}
## DiskData
@@ -7226,8 +7447,12 @@ sub create_output {
}
$rows[$j]{main::key($num++,'model')} = $model;
$rows[$j]{main::key($num++,'size')} = $size;
- if ($extra > 0 && $row{'speed'}){
+ if ($extra > 1 && $row{'speed'}){
$rows[$j]{main::key($num++,'speed')} = $row{'speed'};
+ $rows[$j]{main::key($num++,'lanes')} = $row{'lanes'} if $row{'lanes'};
+ }
+ if ($extra > 2 && $row{'rotation'}){
+ $rows[$j]{main::key($num++,'rotation')} = $row{'rotation'};
}
if ($extra > 1){
my $serial = main::apply_filter($row{'serial'});
@@ -7380,9 +7605,10 @@ sub proc_data_advanced {
($block_type,$firmware,$model,$partition_scheme,
$serial,$vendor,$working_path) = ('','','','','','','');
if ($extra > 2){
- @data = partition_scheme($pt_cmd,$drives[$i]{'id'});
+ @data = advanced_disk_data($pt_cmd,$drives[$i]{'id'});
$pt_cmd = $data[0];
$drives[$i]{'partition-table'} = uc($data[1]) if $data[1];
+ $drives[$i]{'rotation'} = "$data[2] rpm" if $data[2];
}
#print "$drives[$i]{'id'}\n";
@disk_data = disk_data_by_id("/dev/$drives[$i]{'id'}");
@@ -7465,6 +7691,9 @@ sub proc_data_advanced {
if ($extra > 0){
$drives[$i]{'temp'} = hdd_temp("/dev/$drives[$i]{'id'}");
if ($extra > 1){
+ my @speed_data = device_speed($drives[$i]{'id'});
+ $drives[$i]{'speed'} = $speed_data[0] if $speed_data[0];
+ $drives[$i]{'lanes'} = $speed_data[1] if $speed_data[1];
if (@disk_data && $disk_data[2]){
$drives[$i]{'serial'} = $disk_data[2];
}
@@ -7624,7 +7853,7 @@ sub peripheral_data {
eval $end if $b_log;
return $type;
}
-sub partition_scheme {
+sub advanced_disk_data {
eval $start if $b_log;
my ($set_cmd,$id) = @_;
my ($cmd,$pt,$program,@data,@return);
@@ -7635,15 +7864,13 @@ sub partition_scheme {
# runs as user, but is SLOW: udisksctl info -b /dev/sda
# line: org.freedesktop.UDisks2.PartitionTable:
# Type: dos
- if (!$b_root){
- if ($program = main::check_program('udevadm')){
- $return[0] = "$program info -q property -n ";
- }
+ if ($program = main::check_program('udevadm')){
+ $return[0] = "$program info -q property -n ";
}
- if (!$return[0] && $b_root && -e "/lib/udev/udisks-part-id") {
+ elsif ($b_root && -e "/lib/udev/udisks-part-id") {
$return[0] = "/lib/udev/udisks-part-id /dev/";
}
- elsif (!$return[0] && $b_root && ($program = main::check_program('fdisk'))) {
+ elsif ($b_root && ($program = main::check_program('fdisk'))) {
$return[0] = "$program -l /dev/";
}
if (!$return[0]) {
@@ -7670,9 +7897,19 @@ sub partition_scheme {
$return[1] = 'dos' if !$return[1];
}
else {
- $return[1] = main::awk(\@data,'^(UDISKS_PARTITION_TABLE_SCHEME|ID_PART_TABLE_TYPE)',2,'=');
+ foreach (@data){
+ if ( /^(UDISKS_PARTITION_TABLE_SCHEME|ID_PART_TABLE_TYPE)/ ){
+ my @working = split /=/, $_;
+ $return[1] = $working[1];
+ }
+ elsif (/^ID_ATA_ROTATION_RATE_RPM/){
+ my @working = split /=/, $_;
+ $return[2] = $working[1];
+ }
+ last if $return[1] && $return[2];
+ }
}
- $return[1] = 'mbr' if $return[1] && $return[1] eq 'dos';
+ $return[1] = 'mbr' if $return[1] && lc($return[1]) eq 'dos';
}
eval $end if $b_log;
return @return;
@@ -7777,7 +8014,8 @@ sub device_vendor {
['^PNY','^PNY\s','PNY','','^PNY'],
['^(SanDisk|SDS[S]?[DQ]|SL([0-9]+)G|AFGCE)','^SanDisk','SanDisk',''],
# note: get rid of: M[DGK] becasue mushkin starts with MK
- ['^([S]?TOS|THN)','^[S]?TOSHIBA','Toshiba',''], # scsi-STOSHIBA_STOR.E_EDITION_
+ # note: seen: KXG50ZNV512G NVMe TOSHIBA 512GB | THNSN51T02DUK NVMe TOSHIBA 1024GB
+ ['(^[S]?TOS|^THN|TOSHIBA)','[S]?TOSHIBA','Toshiba',''], # scsi-STOSHIBA_STOR.E_EDITION_
## These go last because they are short and could lead to false ID, or are unlikely ##
['^Android','^Android','Android',''],
# must come before AP|Apacer
@@ -7785,6 +8023,7 @@ sub device_vendor {
['^(AP|Apacer)','^Apacer','Apacer',''],
['^BUFFALO','^BUFFALO','Buffalo',''],
['^EXCELSTOR','^EXCELSTOR( TECHNOLOGY)?','Excelstor',''],
+ ['^GALAX\b','^GALAX','GALAX',''],
['^Generic','^Generic','Generic',''],
['^GOODRAM','^GOODRAM','GOODRAM',''],
# supertalent also has FM: |FM
@@ -7840,6 +8079,7 @@ sub device_vendor {
$vendor = $row[2];
$model =~ s/$row[1]//i if $row[1] && lc($model) ne lc($row[1]);
$model =~ s/^[\s\-_]+|[\s\-_]+$//g;
+ $model =~ s/\s\s/ /g;
@data = ($vendor,$model);
last;
}
@@ -7889,6 +8129,69 @@ sub hdd_temp {
eval $end if $b_log;
return $hdd_temp;
}
+sub device_speed {
+ eval $start if $b_log;
+ my ($device) = @_;
+ my ($b_nvme,$lanes,$speed,@data);
+ my $working = Cwd::abs_path("/sys/class/block/$device");
+ #print "$working\n";
+ if ($working){
+ my ($id);
+ # slice out the ata id:
+ # /sys/devices/pci0000:00:11.0/ata1/host0/target0:
+ if ($working =~ /^.*\/ata([0-9]+)\/.*/){
+ $id = $1;
+ }
+ # /sys/devices/pci0000:00/0000:00:05.0/virtio1/block/vda
+ elsif ($working =~ /^.*\/virtio([0-9]+)\/.*/){
+ $id = $1;
+ }
+ # /sys/devices/pci0000:10/0000:10:01.2/0000:13:00.0/nvme/nvme0/nvme0n1
+ elsif ($working =~ /^.*\/(nvme[0-9]+)\/.*/){
+ $id = $1;
+ $b_nvme = 1;
+ }
+ # do host last because the strings above might have host as well as their search item
+ # 0000:00:1f.2/host3/target3: increment by 1 sine ata starts at 1, but host at 0
+ elsif ($working =~ /^.*\/host([0-9]+)\/.*/){
+ $id = $1 + 1 if defined $1;
+ }
+ # print "$working $id\n";
+ if (defined $id){
+ if ($b_nvme){
+ $working = "/sys/class/nvme/$id/device/max_link_speed";
+ $speed = (main::reader($working))[0] if -f $working;
+ if ($speed =~ /([0-9\.]+)\sGT\/s/){
+ $speed = $1;
+ # pcie1: 2.5 GT/s; pcie2: 5.0 GT/s; pci3: 8 GT/s
+ # NOTE: PCIe 3 stopped using the 8b/10b encoding but a sample pcie3 nvme has
+ # rated speed of GT/s * .8 anyway. GT/s * (128b/130b)
+ $speed = ($speed <= 5 ) ? $speed * .8 : $speed * 128/130;
+ $speed = sprintf("%.1f",$speed) if $speed;
+ $working = "/sys/class/nvme/$id/device/max_link_width";
+ $lanes = (main::reader($working))[0] if -f $working;
+ $lanes = 1 if !$lanes;
+ # https://www.edn.com/electronics-news/4380071/What-does-GT-s-mean-anyway-
+ # https://www.anandtech.com/show/2412/2
+ # http://www.tested.com/tech/457440-theoretical-vs-actual-bandwidth-pci-express-and-thunderbolt/
+ # PCIe 1,2 use “8b/10b” encoding: eight bits are encoded into a 10-bit symbol
+ # PCIe 3,4,5 use "128b/130b" encoding: 128 bits are encoded into a 130 bit symbol
+ $speed = ($speed * $lanes) . " Gb/s";
+ }
+ }
+ else {
+ $working = "/sys/class/ata_link/link$id/sata_spd";
+ $speed = (main::reader($working))[0] if -f $working;
+ $speed = main::disk_cleaner($speed) if $speed;
+ $speed =~ s/Gbps/Gb\/s/ if $speed;
+ }
+ }
+ }
+ @data = ($speed,$lanes);
+ #print "$working $speed\n";
+ eval $end if $b_log;
+ return @data;
+}
# gptid/c5e940f1-5ce2-11e6-9eeb-d05099ac4dc2 N/A ada0p1
sub match_glabel {
eval $start if $b_log;
@@ -8035,7 +8338,7 @@ sub display_data(){
# $id = $ENV{'XDG_SESSION_ID'}; # returns tty session in console
my @data = main::grabber("$program --no-pager --no-legend 2>/dev/null",'','strip');
foreach (@data){
- next if /tty[0-6]$/;
+ next if /tty[v]?[0-6]$/; # freebsd: ttyv3
$id = (split /\s+/, $_)[0];
last; # multiuser? too bad, we'll go for the first one
}
@@ -8443,6 +8746,9 @@ sub display_compositor {
if (main::check_program('mutter') && (grep {/mutter/} @ps_cmd ) ) {
$compositor = 'mutter';
}
+ elsif (main::check_program('kwin_wayland') && (grep {/\bkwin_wayland\b/} @ps_cmd ) ) {
+ $compositor = 'kwin_wayland';
+ }
elsif (main::check_program('kwin') && (grep {/\bkwin\b/} @ps_cmd ) ) {
$compositor = 'kwin';
}
@@ -8632,7 +8938,8 @@ sub create_output {
if ($data{'chassis_vendor'} ne $data{'sys_vendor'} ){
$chassis_vendor = $data{'chassis_vendor'};
}
- if ($data{'chassis_type'} ){
+ # dmidecode can have these be the same
+ if ($data{'chassis_type'} && $data{'device'} ne $data{'chassis_type'} ){
$chassis_type = $data{'chassis_type'};
}
if ($data{'chassis_version'}){
@@ -8704,11 +9011,18 @@ sub create_output_arm {
my $num = 0;
my $j = 0;
#print Data::Dumper::Dumper \%arm_machine;
- if ($arm_machine{'device'}){
- my $device = main::cleaner( $arm_machine{'device'} );
- $device ||= 'N/A';
+ # 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 ($arm_machine{'device'} || $arm_machine{'model'}){
$rows[$j]{main::key($num++,'Type')} = 'ARM Device';
- $rows[$j]{main::key($num++,'System')} = $device;
+ my $system = 'System';
+ if (defined $arm_machine{'model'}){
+ $rows[$j]{main::key($num++,'System')} = $arm_machine{'model'};
+ $system = 'v';
+ }
+ my $device = $arm_machine{'device'};
+ $device ||= 'N/A';
+ $rows[$j]{main::key($num++,$system)} = $device;
}
# we're going to print N/A for 0000 values sine the item was there.
if ($arm_machine{'firmware'}){
@@ -8799,7 +9113,7 @@ sub machine_data_arm {
foreach (@data){
if (/^Hardware/i){
@temp = split /\s*:\s*/, $_;
- $arm_machine{'device'} = $temp[1];
+ $arm_machine{'device'} = main::cleaner($temp[1]);
}
elsif (/^Revision/i){
@temp = split /\s*:\s*/, $_;
@@ -8811,6 +9125,19 @@ sub machine_data_arm {
}
}
}
+ if (-f '/proc/device-tree/model'){
+ 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);
+ my (@result) = ();
+ @result = split(/\s+/, $arm_machine{'device'}) if $arm_machine{'device'};
+ if ( !$arm_machine{'device'} ||
+ (scalar(@result) == 1 && $model !~ /$arm_machine{'device'}/) ){
+ $arm_machine{'model'} = $model;
+ }
+ }
+ }
#print Data::Dumper::Dumper \%arm_machine;
eval $end if $b_log;
return %arm_machine;
@@ -9165,8 +9492,10 @@ sub card_data {
foreach (@pci){
$num = 1;
my @row = @$_;
- #print "$row[0] $row[3]\n";
- if ($row[0] eq 'network' || $row[0] eq 'ethernet' ){
+ #print "$row[0] $row[3]\n";
+ # NOTE: class 06 subclass 80
+ # https://www-s.acm.illinois.edu/sigops/2007/roll_your_own/7.c.1.html
+ if ($row[0] eq 'network' || $row[0] eq 'ethernet' || $row[1] eq '0680' ){
#print "$row[0] $row[3]\n";
$j = scalar @rows;
my $driver = $row[9];
@@ -9184,12 +9513,10 @@ sub card_data {
$card = ($card) ? main::pci_cleaner($card,'output') : 'N/A';
#$card ||= 'N/A';
$driver ||= 'N/A';
- @data = (
- {
+ @data = ({
main::key($num++,'Card') => $card,
main::key($num++,'driver') => $driver,
- },
- );
+ },);
@rows = (@rows,@data);
if ($extra > 0){
if ($row[9] && !$bsd_type){
@@ -10123,14 +10450,14 @@ sub partition_data {
}
}
@partitions_working = grep {!/^rootfs/} @partitions_working if $roots > 1;
- my $filters = '^(aufs|cgroup.*|cgmfs|configfs|debugfs|\/dev|dev|\/dev/loop[0-9]*|devfs|devtmpfs|';
- $filters .= 'fdescfs|iso9660|linprocfs|none|procfs|\/run(\/.*)?|run|squashfs|sys|\/sys\/.*|sysfs|';
- $filters .= 'tmpfs|type|udev|unionfs|vartmp)$';
+ my $filters = '^(aufs|cgroup.*|cgmfs|configfs|debugfs|\/dev|dev|\/dev/loop[0-9]*|';
+ $filters .= 'devfs|devtmpfs|fdescfs|iso9660|linprocfs|none|procfs|\/run(\/.*)?|';
+ $filters .= 'run|shm|squashfs|sys|\/sys\/.*|sysfs|tmpfs|type|udev|unionfs|vartmp)$';
foreach (@partitions_working){
# stupid apple bullshit
$_ =~ s/^map\s+([\S]+)/map:\/$1/ if $b_fake_map;
my @row = split /\s+/, $_;
- if ($row[0] =~ /$filters/ || $row[0] =~ /^ROOT/i){
+ if ($row[0] =~ /$filters/ || $row[0] =~ /^ROOT/i || ($b_fs && $row[1] eq 'tmpfs')){
next;
}
$dev_base = '';
@@ -12778,9 +13105,14 @@ sub sensors_data {
# which is the maximum CPU temperature reported as critical temperature by coretemp"
# NOTE: I've seen an inexplicable case where: CPU:52.0°C fails to match with [\s°] but
# does match with: [\s°]*. I can't account for this, but that's why the * is there
- elsif (!$sensors{'cpu-temp'} && $_ =~ /^CPU.*:([0-9\.]+)[\s°]*(C|F)/i) {
- $sensors{'cpu-temp'} = $1;
- $working_unit = $2;
+ # Tdie is a new k10temp-pci syntax for cpu die temp
+ elsif ($_ =~ /^(CPU.*|Tdie.*):([0-9\.]+)[\s°]*(C|F)/i) {
+ $temp_working = $2;
+ $working_unit = $3;
+ if ( !$sensors{'cpu-temp'} ||
+ ( defined $temp_working && $temp_working > 0 && $temp_working > $sensors{'cpu-temp'} ) ) {
+ $sensors{'cpu-temp'} = $temp_working;
+ }
$sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
}
elsif ($_ =~ /^PECI\sAgent\s0.*:([0-9\.]+)[\s°]*(C|F)/i) {
@@ -12797,13 +13129,13 @@ sub sensors_data {
$sensors{'sodimm-temp'} = $1;
$working_unit = $2;
$sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
-
}
# for temp1/2 only use temp1/2 if they are null or greater than the last ones
elsif ($_ =~ /^temp1:([0-9\.]+)[\s°]*(C|F)/i) {
$temp_working = $1;
$working_unit = $2;
- if ( !$sensors{'temp1'} || ( defined $temp_working && $temp_working > 0 ) ) {
+ if ( !$sensors{'temp1'} ||
+ ( defined $temp_working && $temp_working > 0 && $temp_working > $sensors{'temp1'} ) ) {
$sensors{'temp1'} = $temp_working;
}
$sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
@@ -12811,7 +13143,8 @@ sub sensors_data {
elsif ($_ =~ /^temp2:([0-9\.]+)[\s°]*(C|F)/i) {
$temp_working = $1;
$working_unit = $2;
- if ( !$sensors{'temp2'} || ( defined $temp_working && $temp_working > 0 ) ) {
+ if ( !$sensors{'temp2'} ||
+ ( defined $temp_working && $temp_working > 0 && $temp_working > $sensors{'temp2'} ) ) {
$sensors{'temp2'} = $temp_working;
}
$sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
@@ -12820,7 +13153,8 @@ sub sensors_data {
elsif ($_ =~ /^temp3:([0-9\.]+)[\s°]*(C|F)/i) {
$temp_working = $1;
$working_unit = $2;
- if ( !$sensors{'temp3'} || ( defined $temp_working && $temp_working > 0 ) ) {
+ if ( !$sensors{'temp3'} ||
+ ( defined $temp_working && $temp_working > 0 && $temp_working > $sensors{'temp3'} ) ) {
$sensors{'temp3'} = $temp_working;
}
$sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
@@ -12830,7 +13164,8 @@ sub sensors_data {
elsif ($_ =~ /^(core0|core 0|Physical id 0)(.*):([0-9\.]+)[\s°]*(C|F)/i) {
$temp_working = $3;
$working_unit = $4;
- if ( !$sensors{'core-0-temp'} || ( defined $temp_working && $temp_working > 0 ) ) {
+ if ( !$sensors{'core-0-temp'} ||
+ ( defined $temp_working && $temp_working > 0 && $temp_working > $sensors{'core-0-temp'} ) ) {
$sensors{'core-0-temp'} = $temp_working;
}
$sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
@@ -13487,9 +13822,10 @@ sub unmounted_data {
# lvm might have dm-1 type syntax
# need to exclude loop type file systems, squashfs for example
# NOTE: nvme needs special treatment because the main device is: nvme0n1
- if ( $working[-1] !~ /^nvme[0-9]+n[0-9]+$/ &&
- $working[-1] =~ /[a-z][0-9]+$|dm-[0-9]+$/ && $working[2] != 1 &&
- $working[-1] !~ /loop/ && !(grep {$working[-1] =~ /$_/} @mounted)){
+ # note: $working[2] != 1 is wrong, it's not related
+ if ( $working[-1] !~ /^(nvme[0-9]+n|mmcblk)[0-9]+$/ &&
+ $working[-1] =~ /[a-z][0-9]+$|dm-[0-9]+$/ && $working[-1] !~ /loop/ &&
+ !(grep {$working[-1] =~ /$_/} @mounted)){
%part = PartitionData::check_lsblk($working[-1],0) if (@lsblk && $working[-1]);
if (%part){
$fs = $part{'fs'};
@@ -13846,16 +14182,16 @@ sub elevation_output {
$feet = sprintf("%.0f", 3.28 * $meters) if defined $meters && !$feet;
$meters = sprintf("%.1f", $feet / 3.28 ) if defined $feet && !$meters;
$meters = sprintf("%.0f", $meters) if $meters;
- if ( defined $meters && $weather_unit eq 'cf' ){
+ if ( defined $meters && $weather_unit eq 'mi' ){
$result = "$meters $m_unit ($feet $i_unit)";
}
- elsif (defined $meters && $weather_unit eq 'fc' ){
+ elsif (defined $meters && $weather_unit eq 'im' ){
$result = "$feet $i_unit ($meters $m_unit)";
}
- elsif (defined $meters && $weather_unit eq 'c' ){
+ elsif (defined $meters && $weather_unit eq 'm' ){
$result = "$meters $m_unit";
}
- elsif (defined $feet && $weather_unit eq 'f' ){
+ elsif (defined $feet && $weather_unit eq 'i' ){
$result = "$feet $i_unit";
}
else {
@@ -13868,16 +14204,16 @@ sub unit_output {
eval $start if $b_log;
my ($primary,$metric,$m_unit,$imperial,$i_unit) = @_;
my $result = '';
- if ($metric && $imperial && $weather_unit eq 'cf' ){
+ if ($metric && $imperial && $weather_unit eq 'mi' ){
$result = "$metric $m_unit ($imperial $i_unit)";
}
- elsif ($metric && $imperial && $weather_unit eq 'fc' ){
+ elsif ($metric && $imperial && $weather_unit eq 'im' ){
$result = "$imperial $i_unit ($metric $m_unit)";
}
- elsif ($metric && $weather_unit eq 'c' ){
+ elsif ($metric && $weather_unit eq 'm' ){
$result = "$metric $m_unit";
}
- elsif ($imperial && $weather_unit eq 'f' ){
+ elsif ($imperial && $weather_unit eq 'i' ){
$result = "$imperial $i_unit";
}
elsif ($primary){
@@ -13897,10 +14233,10 @@ sub wind_output {
$gust_mph = undef if $gust_mph && $mph && $mph eq $gust_mph;
$gust_ms = undef if $gust_ms && $ms && $ms eq $gust_ms;
# calculate and round, order matters so that rounding only happens after math done
- $ms = sprintf("%.1f", $ms ) if $ms; # very low mph speeds yield 0, which is wrong
+ $ms = 0.44704 * $mph if $mph && !$ms;
$mph = $ms * 2.23694 if $ms && !$mph;
$kmh = sprintf("%.0f", 18 * $ms / 5) if $ms;
- $ms = sprintf("%.0f", $ms ) if $ms;
+ $ms = sprintf("%.1f", $ms ) if $ms; # very low mph speeds yield 0, which is wrong
$mph = sprintf("%.0f", $mph) if $mph;
$gust_ms = 0.44704 * $gust_mph if $gust_mph && !$gust_ms;
$gust_kmh = 18 * $gust_ms / 5 if $gust_ms;
@@ -13912,29 +14248,29 @@ sub wind_output {
$result = $primary;
}
elsif ($mph && $direction ){
- if ( $weather_unit eq 'cf' ){
+ if ( $weather_unit eq 'mi' ){
$result = "from $direction at $ms $m_unit ($kmh $km_unit, $mph $i_unit)";
}
- elsif ( $weather_unit eq 'fc' ){
+ elsif ( $weather_unit eq 'im' ){
$result = "from $direction at $mph $i_unit ($ms $m_unit, $kmh $km_unit)";
}
- elsif ( $weather_unit eq 'c' ){
+ elsif ( $weather_unit eq 'm' ){
$result = "from $direction at $ms $m_unit ($kmh $km_unit)";
}
- elsif ( $weather_unit eq 'f' ){
+ elsif ( $weather_unit eq 'i' ){
$result = "from $direction at $mph $i_unit";
}
if ($gust_mph){
- if ( $weather_unit eq 'cf' ){
+ if ( $weather_unit eq 'mi' ){
$result .= ". Gusting to $ms $m_unit ($kmh $km_unit, $mph $i_unit)";
}
- elsif ( $weather_unit eq 'fc' ){
+ elsif ( $weather_unit eq 'im' ){
$result .= ". Gusting to $mph $i_unit ($ms $m_unit, $kmh $km_unit)";
}
- elsif ( $weather_unit eq 'c' ){
+ elsif ( $weather_unit eq 'm' ){
$result .= ". Gusting to $ms $m_unit ($kmh $km_unit)";
}
- elsif ( $weather_unit eq 'f' ){
+ elsif ( $weather_unit eq 'i' ){
$result .= ". Gusting to $mph $i_unit";
}
}
@@ -14809,28 +15145,38 @@ sub set_xprop {
sub get_display_manager {
eval $start if $b_log;
- my (@data,@found,$temp,$working);
+ my (@data,@found,$temp,$working,$b_run,$b_vrun,$b_vrunrc);
# ldm - LTSP display manager. Note that sddm does not appear to have a .pid
# extension in Arch note: to avoid positives with directories, test for -f
# explicitly, not -e
my @dms = qw(entranced.pid gdm.pid gdm3.pid kdm.pid ldm.pid
- lightdm.pid lxdm.pid mdm.pid nodm.pid sddm.pid sddm slim.lock
- tint2.pid wdm.pid xdm.pid xenodm.pid);
+ lightdm.pid lxdm.pid mdm.pid nodm.pid pcdm.pid
+ sddm.pid slim.lock tint2.pid wdm.pid xdm.pid xenodm.pid);
# this is the only one I know of so far that has --version
# lightdm outputs to stderr, so it has to be redirected
my @dms_version = qw(lightdm);
+ $b_run = 1 if -d "/run";
+ # in most linux, /var/run is a sym link to /run, so no need to check it twice
+ if ( -d "/var/run" ){
+ my $rdlink = readlink('/var/run');
+ $b_vrun = 1 if $rdlink && $rdlink ne '/run';
+ $b_vrunrc = 1 if -d "/var/run/rc.d";
+ }
foreach my $id (@dms){
- # note: ${dm_id%.*}/$dm_id will create a dir name out of the dm id, then
+ # note: $working will create a dir name out of the dm $id, then
# test if pid is in that note: sddm, in an effort to be unique and special,
# do not use a pid/lock file, but rather a random string inside a directory
# called /run/sddm/ so assuming the existence of the pid inside a directory named
# from the dm. Hopefully this change will not have negative results.
$working = $id;
$working =~ s/\.\S+$//;
- # note: there's always been an issue with duplicated dm's in inxi, this should now correct it
- if ( ( -f "/run/$id" || -d "/run/$working" || -f "/var/run/$id" ) && ! grep {/$working/} @found ){
- if ($extra > 2 && awk( \@dms_version, $working) ){
- @data = main::grabber("$working --version 2>&1");
+ # note: there were issues with duplicated dm's in inxi, checking @found corrects it
+ if ( ( ( $b_run && ( -f "/run/$id" || -d "/run/$working" ) ) ||
+ ( $b_vrun && ( -f "/var/run/$id" || -d "/var/run/$working" ) ) ||
+ ( $b_vrunrc && ( -f "/var/run/rc.d/$working" || -d "/var/run/rc.d/$id" ) ) ) &&
+ ! grep {/$working/} @found ){
+ if ($extra > 2 && awk( \@dms_version, $working) && (my $path = main::check_program($working)) ){
+ @data = main::grabber("$path --version 2>&1");
$temp = awk(\@data,'\S',2,'\s+');
$working .= ' ' . $temp if $temp;
}
@@ -14890,7 +15236,7 @@ sub get_bsd_os {
sub get_linux_distro {
eval $start if $b_log;
my ($distro_file) = ('');
- my ($b_osr,@working);
+ my ($b_antergos,$b_osr,@working);
my @derived = qw(antix-version aptosid-version kanotix-version knoppix-version
mandrake-release manjaro-release mx-version pardus-release porteus-version sabayon-release
siduction-version sidux-version slitaz-release solusos-release turbolinux-release
@@ -14908,18 +15254,29 @@ sub get_linux_distro {
# uses this method
my @distro_files = glob('/etc/*[-_]{[rR]elease,[vV]ersion}*');
my $lsb_release = '/etc/lsb-release';
- my $issue = '/etc/issue';
+ my ($etc_issue,$issue) = ('','/etc/issue');
my $os_release = '/etc/os-release';
- my $b_os_release = ( -f $os_release ) ? 1 : 0;
- my $b_lsb = ( -f $lsb_release ) ? 1 : 0;
+ my $b_issue = 1 if -f $issue;
+ my $b_os_release = 1 if -f $os_release;
+ my $b_lsb = 1 if -f $lsb_release;
+ # note: OpenSuse Tumbleweed 2018-05 has made /etc/issue created by sym link to /run/issue
+ # and then made that resulting file 700 permissions, which is obviously a mistake
+ $etc_issue = (main::reader($issue))[0] if $b_issue && -r $issue;
+ # debian issue can end with weird escapes like \n \l
+ # antergos: Antergos Linux \r (\l)
+ if ($etc_issue){
+ $etc_issue = main::clean_characters($etc_issue);
+ $b_antergos = 1 if $etc_issue =~ /antergos/i;
+ }
main::log_data('dump','@distro_files',\@distro_files) if $b_log;
if ( scalar @distro_files == 1 ){
$distro_file = $distro_files[0];
}
elsif (scalar @distro_files > 1) {
- # special case, to force manjaro which also has arch-release
+ # special case, to force manjaro/antergos which also have arch-release
# manjaro should use lsb, which has the full info, arch uses os release
- if (grep {/manjaro/} @distro_files){
+ # antergos should use /etc/issue
+ if ($b_antergos || grep {/manjaro/} @distro_files){
@distro_files = grep {!/arch-release/} @distro_files;
}
my $distro_files_s = join "|", @distro_files;
@@ -14973,29 +15330,26 @@ sub get_linux_distro {
# not use a variable type format
@working = main::reader($distro_file);
$distro = main::awk(\@working,'suse');
- $distro = main::clean_characters($distro) if $distro;
}
else {
$distro = (main::reader($distro_file))[0];
}
+ $distro = main::clean_characters($distro) if $distro;
}
# otherwise try the default debian/ubuntu /etc/issue file
- elsif (-f $issue){
- @working = main::reader($issue);
- my $b_mint = scalar (grep {/mint/i} @working);
+ elsif ($b_issue){
+ my $b_mint = ( $etc_issue && $etc_issue =~ /mint/i ) ? 1 : 0;
# os-release/lsb gives more manageable and accurate output than issue,
- # but mint should use issue for now.
- if ($b_os_release && !$b_mint){
+ # but mint should use issue for now. Antergos uses arch os-release, but issue shows them
+ if ($b_os_release && !$b_mint && !$b_antergos){
$distro = get_os_release();
$b_osr = 1;
}
- elsif ($b_lsb && !$b_mint){
+ elsif ($b_lsb && !$b_mint && !$b_antergos){
$distro = get_lsb_release();
}
- else {
- # debian issue can end with weird escapes like \n \l
- @working = main::reader($issue);
- $distro = (map {s/\\[a-z]|,|\*|\\||\"|[:\47]|^\s+|\s+$|n\/a//ig; $_} @working)[0] if @working;
+ elsif ($etc_issue) {
+ $distro = $etc_issue;
# this handles an arch bug where /etc/arch-release is empty and /etc/issue
# is corrupted only older arch installs that have not been updated should
# have this fallback required, new ones use os-release
@@ -15006,8 +15360,8 @@ sub get_linux_distro {
}
# a final check. If a long value, before assigning the debugger output, if os-release
# exists then let's use that if it wasn't tried already. Maybe that will be better.
- # not handling the corrupt data, maybe later if needed
- if ($distro && length($distro) > 50 ){
+ # not handling the corrupt data, maybe later if needed. 10 + distro: (8) + string
+ if ($distro && length($distro) > 60 ){
if (!$b_osr && $b_os_release){
$distro = get_os_release();
}
@@ -15029,7 +15383,8 @@ sub get_linux_distro {
# the file name itself to set the distro value. Why say unknown if we have
# a pretty good idea, after all?
if ($distro_file){
- $distro_file =~ s/[-_]|release|version//g;
+ $distro_file =~ s/\/etc\/|[-_]|release|version//g;
+ $distro = $distro_file;
}
}
## finally, if all else has failed, give up
@@ -15037,6 +15392,7 @@ sub get_linux_distro {
eval $end if $b_log;
return $distro;
}
+
sub get_lsb_release {
eval $start if $b_log;
my ($distro,$id,$release,$codename,$description) = ('','','','','');
@@ -15083,8 +15439,8 @@ sub get_lsb_release {
}
sub get_os_release {
eval $start if $b_log;
- my ($pretty_name,$name,$version_name,$version_id,
- $distro_name,$distro) = ('','','','','','');
+ my ($pretty_name,$lc_name,$name,$version_name,$version_id,
+ $distro_name,$distro) = ('','','','','','','');
my @content = main::reader('/etc/os-release');
main::log_data('dump','@content',\@content) if $b_log;
@content = map {s/\\||\"|[:\47]|^\s+|\s+$|n\/a//ig; $_} @content if @content;
@@ -15097,6 +15453,7 @@ sub get_os_release {
}
if ($working[0] eq 'NAME' && $working[1]){
$name = $working[1];
+ $lc_name = lc($name);
}
if ($working[0] eq 'VERSION' && $working[1]){
$version_name = $working[1];
@@ -15106,18 +15463,19 @@ sub get_os_release {
}
}
# NOTE: tumbleweed has pretty name but pretty name does not have version id
- if ($pretty_name && $pretty_name !~ /tumbleweed/i){
+ # arco shows only the release name, like kirk, in pretty name
+ if ($pretty_name && ($pretty_name !~ /tumbleweed/i && $lc_name ne 'arcolinux') ){
$distro = $pretty_name;
}
elsif ($name){
$distro = $name;
+ $distro = 'Arco Linux' if $lc_name eq 'arcolinux';
if ($version_name){
$distro .= ' ' . $version_name;
}
elsif ($version_id){
$distro .= ' ' . $version_id;
}
-
}
eval $end if $b_log;
return $distro;
@@ -15706,7 +16064,7 @@ sub get_uptime {
$uptime = trimmer($uptime);
#$uptime = '05:36:47 up 3 min, 4 users, load average: 1,88, 0,98, 0,62';
if ($uptime &&
- $uptime =~ /[\S]+\s+up\s+(([0-9]+)\s+day[s]?,\s+)?(([0-9]{1,2}):([0-9]{1,2})|([0-9]+)\smin),\s+[0-9]+\s+user/){
+ $uptime =~ /[\S]+\s+up\s+(([0-9]+)\s+day[s]?,\s+)?(([0-9]{1,2}):([0-9]{1,2})|([0-9]+)\smin[s]?),\s+[0-9]+\s+user/){
$days = $2 . 'd' if $2;
$days .= ' ' if ($days && ($4 || $6));
if ($4 && $5){
@@ -16136,6 +16494,8 @@ sub set_lspci_data {
my $path = check_program('lspci');
$content = qx($path -nnv 2>/dev/null) if $path;
@pcis = split /\n/, $content if $content;
+ #my $file = "$ENV{HOME}/bin/scripts/inxi/data/lspci/racermach-1-knnv.txt";
+ #@pcis = reader($file);
#print scalar @pcis;
@pcis = map {$_ =~ s/^\s+//; $_} @pcis if @pcis;
foreach (@pcis){
diff --git a/inxi.1 b/inxi.1
index eef1304..b7d6872 100644
--- a/inxi.1
+++ b/inxi.1
@@ -1,4 +1,4 @@
-.TH INXI 1 "2018\-05\-11" inxi "inxi manual"
+.TH INXI 1 "2018\-06\-04" inxi "inxi manual"
.SH NAME
inxi \- Command line system information script for console and IRC
.SH SYNOPSIS
@@ -8,11 +8,11 @@ inxi \- Command line system information script for console and IRC
\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 {\fBc\fR|\fBf\fR|\fBcf\fR|\fBfc\fR}] [\fB\-y WIDTH\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\fB \-x\fR|\fB\-xx\fR|\fB\-xxx\fR \fB\-OPTION(s) \fR
+\fBinxi\fB [\-x\fR|\fB\-xx\fR|\fB\-xxx\fR|\-\-admin] \fB\-OPTION(s) \fR
All options have long form variants \- see below for these and more advanced options.
@@ -62,10 +62,11 @@ Show Audio/sound card(s) information, including card driver.
Show basic output, short form. Same as: \fBinxi \-v 2\fR
.TP
.B \-B\fR,\fB \-\-battery\fR
-Show Battery data, charge, condition, plus extra information (if battery present).
-Uses \fB/sys\fR or, for BSDs without systctl battery data, \fBdmidecode\fR.
-\fBdmidecode\fR does not have very much information, and none about current battery
-state/charge/voltage. Supports multiple batteries when using \fB/sys\fR data.
+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,
+\fBdmidecode\fR. \fBdmidecode\fR does not have very much information, and none
+about current battery state/charge/voltage. Supports multiple batteries when
+using \fB/sys\fR data.
Note that for \fBcharge\fR, the output shows the current charge, as well as its
value as a percentage of the available capacity, which can be less than the original design
@@ -79,6 +80,9 @@ capacity, and then this figure as a percentage of original capacity available in
\fBcondition: 22.2/36.4 Wh (61%)\fR
+With \fB\-x\fR shows attached \fBDevice\-x\fR information (mouse, keyboard, etc.)
+if they are battery powered.
+
.TP
.B \-c\fR,\fB \-\-color\fR \fR[\fB0\fR\-\fB42\fR]
Set color scheme. If no scheme number is supplied, 0 is assumed.
@@ -428,10 +432,10 @@ Use only ASCII letters in city/state/country names, sorry.
Examples: \fB\-W 95623\fR OR \fB\-W Boston,MA\fR OR \fB\-W45.5234,\-122.6762\fR
OR \fB\-W new+york,ny\fR OR \fB\-W bodo,norway\fR.
.TP
-.B \-w\fR,\fB \-\-weather\-unit <unit>\fR
-[\fBc\fR|\fBf\fR|\fBcf\fR|\fBfc\fR] Sets weather units to metric (\fBc\fR), imperial (\fBf\fR),
-metric (imperial) (\fBcf\fR), imperial (metric) (\fBfc\fR). If metric or imperial not found,
-sets to default values, or \fBN/A\fR.
+.B \-\-weather\-unit <unit>\fR
+[\fBm\fR|\fBi\fR|\fBmi\fR|\fBim\fR] Sets weather units to metric (\fBm\fR), imperial (\fBi\fR),
+metric (imperial) (\fBmi\fR, default), imperial (metric) (\fBim\fR). If metric or imperial
+not found,sets to default value, or \fBN/A\fR.
.TP
.B \-y\fR,\fB \-\-width <integer>\fR
This is an absolute width override which sets the output line width max.
@@ -477,8 +481,15 @@ device.
.B \-x \-B\fR
\- Adds vendor/model, battery status (if battery present).
.TP
+.B \-x \-B\fR
+\- Adds attached battery powered peripherals (\fBDevice\-[number]:\fR) if
+detected (keyboard, mouse, etc.).
+.TP
.B \-x \-C\fR
-\- Adds bogomips on CPU (if available); CPU Flags (short list).
+\- Adds bogomips on CPU (if available)
+.TP
+.B \-x \-C\fR
+\- Adds CPU Flags (short list).
.TP
.B \-x \-C\fR
\- Adds CPU microarchitecture + revision (e.g. Sandy Bridge, K8, ARMv8, P6,
@@ -496,7 +507,6 @@ dds rev version to optical drive.
or if you have added to \fB/etc/sudoers\fR (sudo v. 1.7 or newer):
.B <username> ALL = NOPASSWD: /usr/sbin/hddtemp (sample)
-
.TP
.B \-x \-G\fR
\- Adds direct rendering status.
@@ -596,6 +606,24 @@ data (if available) as the voltage now / minimum design voltage.
.B \-xx \-D\fR
\- Adds disk serial number.
.TP
+.B \-xx \-D\fR
+\- Adds disk speed (if available). This is the theoretical top speed of the
+device as reported. This speed may be restricted by system board limits, eg.
+a SATA 3 drive on a SATA 2 board may report SATA 2 speeds, but this is not
+completely consistent, sometimes a SATA 3 device on a SATA 2 board reports
+its design speed.
+
+NVMe drives: adds lanes, and (per direction) speed is calculated with
+lane speed * lanes * PCIe overhead. PCIe 1 and 2 have data rates of
+GT/s * .8 = Gb/s (10 bits required to transfer 8 bits of data).
+PCIe 3 and greater transfer data at a rate of GT/s * 128/130 * lanes = Gb/s
+(130 bits required to transfer 128 bits of data).
+
+For a PCIe 3 NVMe drive, with speed of \fB8 GT/s\fR and \fB4\fR lanes
+(\fB8GT/s * 128/130 * 4 = 31.6 Gb/s\fR):
+
+\fBspeed: 31.6 Gb/s lanes: 4\fR
+.TP
.B \-xx \-G\fR
\- Adds vendor:product ID of each Graphics card.
.TP
@@ -671,11 +699,21 @@ always shows \fB0\fR. There's nothing that can be done about this glitch, the
data is simply not available as of 2018\-04\-03), location (only available from
\fBdmidecode\fR derived output).
.TP
+.B \-xxx \-B\fR
+\- Adds attached device \fBrechargeable: [yes|no]\fR information.
+.TP
.B \-xxx \-D\fR
\- Adds disk firmware revision number (if available).
.TP
.B \-xxx \-D\fR
-\- Adds disk partition scheme (in some but not all cases), e.g. \fBscheme: GPT\fR
+\- Adds disk partition scheme (in most cases), e.g. \fBscheme: GPT\fR. Currently not
+able to detect all schemes, but handles the most common, e.g. \fBGPT\fR or \fBMBR\fR.
+.TP
+.B \-xxx \-D\fR
+\- Adds disk rotation speed (in some but not all cases), e.g. \fBrotation: 7200 rpm\fR.
+Only appears if detected (SSD drives do not have rotation speeds, for example). If none
+found, nothing shows. Not all disks report this speed, so even if they are spinnning,
+no data will show.
.TP
.B \-xxx \-I\fR
\- For \fBShell:\fR adds \fB(su|sudo|login)\fR to shell name if present.
@@ -719,6 +757,22 @@ If none found, shows nothing.
.B \-xxx \-w\fR,\fB \-W\fR
\- Adds location (city state country), altitude, weather observation time.
+.SH ADMIN EXTRA DATA OPTIONS
+These options are triggered with \fB\-\-admin\fR. Admin options are advanced output options,
+and are more technical, and mostly of interest to system administrators or other machine admins.
+The \fB\-\-admin\fR option only has to be used once, and will trigger the following features.
+
+.TP
+.B \-\-admin \-C\fR
+\- 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.
+.TP
+.B \-\-admin \-C\fR
+\- Adds CPU microcode. Format is \fBhexadecimal\fR.
+.TP
+.B \-\-admin \-C\fR
+\- Adds CPU Errata (bugs) as known by your current kernel.
+
.SH ADVANCED OPTIONS
.TP
@@ -854,16 +908,12 @@ Overrides default internal value and user configuration value:
\- Full file/system info logging.
.TP
-.B \-\-debug [20\-22]\fR
-Debugger output generator.
-
-.TP
.B \-\-debug 20\fR
Creates a tar.gz file of system data and collects the inxi output
in a file.
-* tree traversal data file read from \fB/sys\fR, and other system
-data.
+* tree traversal data file(s) read from \fB/proc\fR and \fB/sys\fR, and
+other system data.
* xorg conf and log data, xrandr, xprop, xdpyinfo, glxinfo etc.
@@ -960,7 +1010,8 @@ See the documentation page for more complete information on how to set
these up, and for a complete list of options:
.I https://smxi.org/docs/inxi\-configuration.htm
-
+.TP
+.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.
@@ -996,6 +1047,8 @@ above configuration page on smxi.org for full info.
\fBWEATHER_UNIT\fR Values: [\fBc\fR|\fBf\fR|\fBcf\fR|\fBfc\fR]. Same as \fB\-\-weather\-unit\fR.
+.TP
+.B Color Options
It's best to use the \fB\-c [94\-99]\fR color selector tool to set the following values
because it will correctly update the configuration file and remove any invalid
or conflicting items, but if you prefer to create your own configuration files,
@@ -1017,19 +1070,24 @@ here are the options. All take the integer value from the options available in
.SH BUGS
Please report bugs using the following resources.
-You may be asked to run the inxi debugger tool which will upload a data dump of
-system files for use in debugging inxi. These data dumps are very important since
-they provide us with all the real system data inxi uses to parse out its report.
+You may be asked to run the inxi debugger tool (see \fB\-\-debug 21/22\fR), which will
+upload a data dump of system files for use in debugging inxi. These data dumps are
+very important since they provide us with all the real system data inxi uses to parse
+out its report.
.TP
-inxi main website/source/wiki, file an issue report:
+.B Issue Report
+File an issue report:
.I https://github.com/smxi/inxi/issues
.TP
-post on inxi developer forums:
+.B Developer Forums
+Post on inxi developer forums:
.I https://techpatterns.com/forums/forum\-32.html
.TP
+.B IRC irc.oftc.net#smxi
You can also visit
.I irc.oftc.net
\fRchannel:\fI #smxi\fR to post issues.
+
.SH HOMEPAGE
.I https://github.com/smxi/inxi
.I https://smxi.org/
diff --git a/inxi.changelog b/inxi.changelog
index ab70880..a953a24 100644
--- a/inxi.changelog
+++ b/inxi.changelog
@@ -1,4 +1,140 @@
=====================================================================================
+Version: 3.0.11
+Patch Version: 00
+Script Date: 2018-06-04
+-----------------------------------
+Changes:
+-----------------------------------
+New version, man page. Features, bugs, fixes!
+
+Bugs:
+1. Color selector accepted '' as a value, which it would then write to config
+file, creating errors since it's not an integer value.
+2. Corrected distro id error for last fallback case, making the distro ID out
+of the filename itself, that was missing the assignment to $distro.
+3. mmcblk0 was showing up as an unmounted partition, due to failing to filter
+mmcblk[0-9] in unmounted.
+
+Fixes:
+1. Added missing compositor kwin_wayland to compositor detections
+2. For -M, on laptops, sometimes Type: would duplicate in Chassis: type: which
+looks silly, so now it checks to make sure the two values are different before
+using the Chassis: type: data.
+3. -D disk vendor, added GALAX, fixed Toshiba, which sometimes occurs other than
+start of disk id string, so now it checks the whole string. This seems particularly
+common in nvme devices from Toshiba. This is the only vendor I have found that
+puts the vendor string later in the device id string.
+4. Added protection against unreadable but present /etc/issue. This was caused
+by a now fixed bug in OpenSuSe, which symbolically linked to create /etc/issue
+from /var/run/issue, but with 600 permissions, root read only, that is. Note that
+this bug has since been fixed (now has the correct 644 permissions), but I figured
+better safe than sorry in case anyone else decides that's a good idea in the future.
+Now only sends to reader if readable.
+5. Related to 4, made reader not exit on failure, now just prints error message and
+keeps going.
+6. Upped maximum distro string length to 60, from 50. AntiX for example was coming
+in at 48, so I decided to add some safe room now that inxi does dynamic sizing, it
+is not a big problem having very long distro id strings.
+
+Enhancements:
+1. Added basic /proc data parser to debugger. Can't get all the data or files because
+it's simply too big, but grabs the basics.
+2. Added vcgencmd for some ARM rasberry pi debugging.
+3. ARM: add model if not found in /proc/cpuinfo, or if different.
+4. Added Tdie cpu sensor type, this is coming soon in latest kernels, so catching
+it early. Tdie will replace k10-temp sensor item temp1.
+5. Added --admin extra data option, and first set of extra data, -C, which will
+show CPU Errata (bugs), family, model-id, stepping (as hex (decimal) or hex if less
+than or equal to 9), microcode (as hex).
+6. Battery: added with -x option, if found, attached battery driven devices, like
+wifi keyboard, mouse. If upower is present, will also try to show battery charge
+percent for those devices. Note that -B only shows the Device-X items if -x is used,
+and will not show anything in -F unless there is a system, not device, battery
+present, or if -Fx is used and there is a Device battery detected.
+Added upower to recommends.
+7. Basic -Dxxx disk rotation speeds added. Requires udevadm. Not all spinning disks
+show rotation speeds, and it depends on udevadm, so if no rotation found, it shows
+nothing.
+8. Added explicit Arco Linux and Antergos distro ID support. This requires more
+checks, but in theory, both should now show Arco Linux or Antergos instead of default
+'Arch Linux' as before, plus extra data if found, like version.
+
+-----------------------------------
+-- Harald Hope - Mon, 04 Jun 2018 16:48:53 -0700
+
+=====================================================================================
+Version: 3.0.10
+Patch Version: 00
+Script Date: 2018-05-21
+-----------------------------------
+Changes:
+-----------------------------------
+New version, new man page.
+
+This version is very peaceful, no big changes, just a few fixes and small new
+features added.
+
+This version corrects a few small glitches reported by users, and adds basic support
+for disk speed report. Note that this is not as accurate as I'd like, it tries, but
+there is not a lot of data to be had. Limits of disk speed seems to be, roughly:
+1. most speed is reported as max board can do, not max drive can support
+2. usually when speed is reported as lower than max board speed, it's correct, but,
+as usual, exceptions to this were found during testing.
+3. usually if drive is faster than board speed, it reports board speed, but, again,
+exceptions to this rule were found during testing.
+
+However, with this said, it's usually more or less right, at least right in terms
+of the fastest speed you can expect to get with your board. NVMe was also supported,
+that's much more complicated because NVMe has >= 1 lane, and each lane has up and
+down data. The reported speed is max in one direction, and is a function of the
+PCIe 1,2 20% overhead, and PCIe 3,4,5 ~1.5% overhead. inxi shows the actual usable
+data rate, not the GT/s rate, which is the total transfers per second the unit
+supports.
+
+So due to the unreliable nature of the data, this is only a -xx option. There is
+also in general no data for USB, and none for mmcblk (sd cards usually).
+
+This feature may be enhanced with a C Perl XS library in the future, we'll see how
+that goes.
+
+FIXES:
+1. corrected an issue where a networking card of type Bridge failed to be detected.
+This is now handled. This was a PCI type I'd never seen before, but it exists, and
+a user had it, so now it will work as expected for this type.
+2. changed the default units in weather to be m (metric) imperial (i). While this is
+not very intuitive for me, it's easier to explain I think. The previous c / f
+syntax is supported internally, and inxi will just translate c to m and f to i, so
+it doesn't matter which is or was used on a config file or with the --weather-unit
+option.
+3. BSD uptime had a parsing glitch, there was a spelling variant I'd never seen in
+GNU/Linux that broke the regex. This is corrected now.
+4. Fixed a few small man page glitches, some ordering stuff, nothing major.
+5. Fixed BSD hostname issues. There was a case where a setup could have no hostname,
+inxi did not handle that correctly. This fix would have applied to gnu/linux as
+well.
+6. Fixed a few bsd, openbsd mostly, dm detections, there is a secondary path in
+OpenBSD that was not checked. This also went along with refactoring the dm logic
+to be much more efficient and optimized.
+7. Fine tuned dmidecode error message.
+8. Fixed PCI ID issue, it was failing to catch a certain bridged network type.
+9. A more global fix for unhandled tmpfs types, in this case, shm, but added a
+global test that will handle all tmpfs from now on, and exclude that data from
+-p reports.
+
+NEW FEATURES:
+1. First attempt to add basic disk speed (Gb/s). Supported types: ATA, NVMe. No
+speed data so far handled or found: mmcblk; USB. Also possibly older /dev/hda
+type devices (IDE bus) may not get handled in all cases. This may get more work
+in the future, but that's a long ways off. This case oddly was one where BSDs had
+support for basic disk speed reports before GNU/Linux, but that was really just
+because it was part of a single data line that inxi parsed for disk data anyway
+with BSDs.
+2. Man items added for -Dxx disk speed options.
+
+-----------------------------------
+-- Harald Hope - Mon, 21 May 2018 14:25:53 -0700
+
+=====================================================================================
Version: 3.0.09
Patch Version: 00
Script Date: 2018-05-11