aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@ubuntu.com>2018-05-12 16:25:51 -0400
committerLibravatarUnit 193 <unit193@ubuntu.com>2018-05-12 16:25:51 -0400
commit8e2439019187be5e6576b6a400d48aed4731354a (patch)
tree1130528b92e83e1d33a5717d54fcc0582f2609e2
parent2f191c302fed4463b1192d2595184a65411adf25 (diff)
downloadinxi-8e2439019187be5e6576b6a400d48aed4731354a.tar.bz2
inxi-8e2439019187be5e6576b6a400d48aed4731354a.tar.xz
inxi-8e2439019187be5e6576b6a400d48aed4731354a.tar.zst
New upstream version 3.0.09-1upstream/3.0.09-1
-rw-r--r--README.txt574
-rwxr-xr-xinxi1153
-rw-r--r--inxi.142
-rw-r--r--inxi.changelog145
4 files changed, 1316 insertions, 598 deletions
diff --git a/README.txt b/README.txt
index 5443b0b..1970c17 100644
--- a/README.txt
+++ b/README.txt
@@ -1,32 +1,61 @@
README for inxi - a command line system information tool
-The new Perl inxi is now here! File all issue reports with the master
-branch. All support for versions prior to 3.0 is now ended, sorry.
+The new faster, more powerful Perl inxi is here! File all issue reports
+with the master branch. All support for versions prior to 3.0 is now ended,
+sorry.
-Make sure to update to the current inxi from the master branch before
-filing any issue reports. The code in pre 2.9 versions literally no
-longer exists in inxi 3. Bugs from earlier versions cannot be solved
-in the new version since the pre 2.9 and the 2.9 and later versions
-are completely different internally.
+Make sure to update to the current inxi from the master branch before filing
+any issue reports. The code in pre 2.9 versions literally no longer exists in
+inxi 3. Bugs from earlier versions cannot usually be solved in the new version
+since the pre 2.9 and the 2.9 and later versions are completely different
+internally.
-inxi strives to support the widest range of operating systems and
-hardware, from the most simple consumer desktops, to the most advanced
-professional hardware and servers.
+===============================================================================
+Help inxi development! Submit a user debugger dataset.
-The issues you post help maintain or expand that support, and are
-always appreciated since user data and feedback is what keeps inxi
-working and supporting the latest or not so latest hardware and
-operating systems.
+This is easy to do, and only takes a few seconds. These datasets really help
+the project add and debug features. You will generally also be asked to provide
+this data for non trivial issue reports.
-See the BSD section below for qualifications re BSDs, and OSX in
-particular.
+Note that the following options are present:
-=====================================================================
+1. Generate local gz'ed debugger dataset. Leaves gz on your system:
+ inxi version 3: inxi --debug 20
+ inxi version <= 2.3: inxi -@14
+2. Generate, upload gz'ed debugger dataset. Leaves gz on your system:
+ inxi version 3: inxi --debug 21
+ inxi version <= 2.3: inxi -xx@14
+3. Generate, upload, delete gz'ed debugger dataset:
+ inxi version 3 only: inxi --debug 22
+
+You can run these as regular user, or root/sudo, which will gather a bit more
+data, like from dmidecode, and other tools that need superuser permissions
+to run.
+
+ARM and BSD datasets are particularly appreciated because we simply do not
+have enough of those.
+
+===============================================================================
+Make inxi better! Get more support, fix broken items!
+
+inxi strives to support the widest range of operating systems and hardware,
+from the most simple consumer desktops, to the most advanced professional
+hardware and servers.
+
+The issues you post help maintain or expand that support, and are always
+appreciated since user data and feedback is what keeps inxi working and
+supporting the latest (or not so latest) hardware and operating systems.
+
+See the BSD section below for qualifications re BSDs, and OSX in particular.
+
+===============================================================================
+BRANCHES
+-------------------------------------------------------------------------------
MASTER BRANCH:
-This is the only supported branch, and the current latest commit is
-the only supported 'release'. There are no 'releases' of inxi beyond
-the current commit to master. All past commits are not supported.
+This is the only supported branch, and the current latest commit/version is
+the only supported 'release'. There are no 'releases' of inxi beyond the
+current commit/version in master. All past versions are not supported.
git clone https://github.com/smxi/inxi --branch master --single-branch
@@ -37,18 +66,15 @@ 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.
+'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. I did not want to use tags precisely
-to avoid the idea that inxi has any release that exists that is other
-than it's current master version, but I decided that it was less pain
-to add tags than to argue this point any further.
+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.
-=====================================================================
+-------------------------------------------------------------------------------
DEVELOPMENT BRANCH:
All active development is now done on the inxi-perl branch (pinxi):
@@ -61,13 +87,13 @@ 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 stable, they will move
+to the master branch.
-=====================================================================
+-------------------------------------------------------------------------------
LEGACY BRANCH:
-If you'd like to look at or check out the Gawk/Bash version of inxi,
-you can find it here, at the inxi-legacy branch (binxi):
+If you'd like to look at or check out the Gawk/Bash version of inxi, you can
+find it here, at the inxi-legacy branch (binxi):
git clone https://github.com/smxi/inxi --branch inxi-legacy --single-branch
@@ -77,42 +103,40 @@ wget -Nc https://github.com/smxi/inxi/raw/inxi-legacy/binxi
OR easy to remember shortcut (which redirects to github):
wget -Nc https://smxi.org/binxi
-This version will not be maintained, and it's unlikely that any time
-will be spent on it in the future, but it is there in case it's of
-use or interest to anyone.
+This version will not be maintained, and it's unlikely that any time will be
+spent on it in the future, but it is there in case it's of use or interest to
+anyone.
-=====================================================================
+===============================================================================
SUPPORT INFO:
-Do not ask for basic help that reading the inxi -h / --help menus, or
-man page would show you, and do not ask for features to be added that
-inxi already has. Also do not ask for support if your distro won't
-update its inxi version, some are bad about that.
+Do not ask for basic help that reading the inxi -h / --help menus, or man page
+would show you, and do not ask for features to be added that inxi already has.
+Also do not ask for support if your distro won't update its inxi version, some
+are bad about that.
DOCUMENTATION: https://smxi.org/docs/inxi.htm
-(smxi.org/docs/ is easier to remember, and is one click away from
-inxi.htm). The one page wiki on github is only a pointer to the real
-resources.
+(smxi.org/docs/ is easier to remember, and is one click away from inxi.htm).
+The one page wiki on github is only a pointer to the real resources.
https://github.com/smxi/inxi/tree/inxi-perl/docs
-Contains specific Perl inxi documentation, of interest mostly to
-developers. Includes internal inxi tools, values, configuration items.
-Also has useful information about Perl version support, including the
-list of Core modules that _should_ be included in a distribution's
-core modules, but which are unfortunately sometimes removed.
+Contains specific Perl inxi documentation, of interest mostly to developers.
+Includes internal inxi tools, values, configuration items. Also has useful
+information about Perl version support, including the list of Core modules that
+_should_ be included in a distribution's core modules, but which are
+unfortunately sometimes removed.
HTML MAN PAGE: https://smxi.org/docs/inxi-man.htm
INXI OPTIONS PAGE: http://smxi.org/docs/inxi-options.htm
-NOTE: These may not always be up to date, but generally track the most
-recent inxi commits.
+NOTE: These may not always be up to date, but generally track the most recent
+inxi commits.
ISSUES: https://github.com/smxi/inxi/issues
-No issues accepted for non current inxi releases. See below for more on
-that. Unfortunately as of 2.9, no support or issues can be accepted for
-older inxi's because inxi 2.9 (Perl) and newer is a full rewrite, and
-legacy inxi is not being supported since our time here on earth is
-finite (plus of course, one reason for the rewrite was to never have
-to work with Gawk->Bash again!).
+No issues accepted for non current inxi versions. See below for more on that.
+Unfortunately as of 2.9, no support or issues can be accepted for older inxi's
+because inxi 2.9 (Perl) and newer is a full rewrite, and legacy inxi is not
+being supported since our time here on earth is finite (plus of course, one
+reason for the rewrite was to never have to work with Gawk->Bash again!).
SUPPORT FORUMS: https://techpatterns.com/forums/forum-33.html
This is the best place to place support issues that may be complicated.
@@ -123,254 +147,230 @@ DEVELOPER FORUMS: https://techpatterns.com/forums/forum-32.html
SOURCE VERSION CONTROL: https://github.com/smxi/inxi
MAIN BRANCH: master
DEVELOPMENT BRANCHES: inxi-perl, one, two
-inxi-perl is the dev branch, the others are rarely if ever used. inxi
-itself has the built in feature to be able to update itself from
-anywhere, including these branches, which is very useful for development
-and debugging on various user systems.
-
-PULL REQUESTS: Please talk to me before starting to work on patches of
-any reasonable complexity. inxi is hard to work on, and you have to
-understand how it works before submitting patches, unless it's a trivial
-bug fix. Please: NEVER even think about looking at or using previous
-inxi commits, previous to the current master version, as a base for a
-patch. If you do, your patch / pull request will probably be rejected.
-Developers, get your version from the inxi-perl branch, pinxi, otherwise
-you may not be current to actual development versions. inxi-perl pinxi
-is always equal to or ahead of master branch inxi.
-
-Man page updates, doc page updates, etc, of course, are easy and will
-probably be accepted, as long as they are properly formatted and
-logically coherent.
-
-inxi releases early, and releases often, when under development.
+inxi-perl is the dev branch, the others are rarely if ever used. inxi itself
+has the built in feature to be able to update itself from anywhere, including
+these branches, which is very useful for development and debugging on various
+user systems.
+
+PULL REQUESTS: Please talk to me before starting to work on patches of any
+reasonable complexity. inxi is hard to work on, and you have to understand how
+it works before submitting patches, unless it's a trivial bug fix. Please:
+NEVER even think about looking at or using previous inxi commits, previous to
+the current master version, as a base for a patch. If you do, your patch / pull
+request will probably be rejected. Developers, get your version from the
+inxi-perl branch, pinxi, otherwise you may not be current to actual development
+versions. inxi-perl pinxi is always equal to or ahead of master branch inxi.
+
+Man page updates, doc page updates, etc, of course, are easy and will probably
+be accepted, as long as they are properly formatted and logically coherent.
+
+When under active development, inxi releases early, and releases often.
PACKAGERS: inxi has one and only one 'release', and that is the current
-commit to master branch (plus pinxi inxi-perl branch, of course, but
-those should never be packaged).
+commit/version in the master branch (plus pinxi inxi-perl branch, of course,
+but those should never be packaged).
-=====================================================================
+===============================================================================
ABOUT INXI - CORE COMMITMENT TO LONG TERM STABILITY
-inxi is a command line system information tool. It was forked from the
-ancient and mindbendingly perverse yet ingenius infobash, by locsmif.
-
-That was a buggy, impossible to update or maintain piece of software,
-so the fork fixed those core issues, and made it flexible enough to
-expand the utility of the original ideas. Locmsif has given his thumbs
-up to inxi, so don't be fooled by legacy infobash stuff you may see
-out there.
-
-inxi is lower case, except when I create a text header here in a file
-like this, but it's always lower case. Sometimes to follow convention
-I will use upper case inxi to start a sentence, but i find it a bad
-idea since invariably, someone will repeat that and type it in as the
-command name, then someone will copy that, and complain that the
-command: Inxi doesn't exist...
-
-The primary purpose of inxi is for support, and sys admin use. inxi
-is used widely for forum and IRC support, which is I believe it's most
-common function.
-
-If you are piping output to paste or post (or writing to file), inxi
-now automatically turns off color codes, so the old suggestion to
-use -c 0 to turn off colors is no longer required.
-
-inxi should always show you your current system state, as far as
-possible, and should be more reliable than your own beliefs about
-what is in your system, ideally. In other words, the goal in inxi
-is to have it be right more than it is wrong about any system that
-it runs on. And not to rely on non current system state data if at
-all possible. Some things, like memory/ram data, rely on radically
-unreliable system self reporting based on OEM filling out data
-correctly, which doesn't often happen, so in those cases, you want to
-confirm things like ram capacity with a reputable hardware source,
-like crucial.com, which has the best ram hardware tool I know of.
-
-The core mission of inxi is to always work on all systems all the
-time. Well, all systems with the core tools inxi requires to operate
-installed. Ie, not Android, yet. What this means is this: you can
-have a 10 year old box, or probably 15, not sure, and you can install
-today's inxi on it, and it will run. It won't run fast, but it will
-run. I test inxi on a 200 MHz laptop from about 1998 to keep it
-honest. That's also what was used to optimize the code at some
-points, since differences appear as seconds, not 10ths or 100ths
-of seconds on old systems like that.
-
-inxi is being written, and tested, on Perl as old as 5.08, and will
-work on any system that runs Perl 5.08 or later. Pre 2.9.0 Gawk/Bash
-inxi will also run on any system no matter how old, within reason,
-so there should be no difference.
-
-=====================================================================
+inxi is a command line system information tool. It was forked from the ancient
+and mindbendingly perverse yet ingenius infobash, by locsmif.
+
+That was a buggy, impossible to update or maintain piece of software, so the
+fork fixed those core issues, and made it flexible enough to expand the utility
+of the original ideas. Locmsif has given his thumbs up to inxi, so don't be
+fooled by legacy infobash stuff you may see out there.
+
+inxi is lower case, except when I create a text header here in a file like
+this, but it's always lower case. Sometimes to follow convention I will use
+upper case inxi to start a sentence, but i find it a bad idea since invariably,
+someone will repeat that and type it in as the command name, then someone will
+copy that, and complain that the command: Inxi doesn't exist...
+
+The primary purpose of inxi is for support, and sys admin use. inxi is used
+widely for forum and IRC support, which is I believe it's most common function.
+
+If you are piping output to paste or post (or writing to file), inxi now
+automatically turns off color codes, so the old suggestion to use -c 0 to turn
+off colors is no longer required.
+
+inxi should always show you your current system state, as far as possible, and
+should be more reliable than your own beliefs about what is in your system,
+ideally. In other words, the goal in inxi is to have it be right more than it
+is wrong about any system that it runs on. And not to rely on non current
+system state data if at all possible. Some things, like memory/ram data, rely
+on radically unreliable system self reporting based on OEM filling out data
+correctly, which doesn't often happen, so in those cases, you want to confirm
+things like ram capacity with a reputable hardware source, like crucial.com,
+which has the best ram hardware tool I know of.
+
+The core mission of inxi is to always work on all systems all the time. Well,
+all systems with the core tools inxi requires to operate installed. Ie, not
+Android, yet. What this means is this: you can have a 10 year old box, or
+probably 15, not sure, and you can install today's inxi on it, and it will run.
+It won't run fast, but it will run. I test inxi on a 200 MHz laptop from about
+1998 to keep it honest. That's also what was used to optimize the code at some
+points, since differences appear as seconds, not 10ths or 100ths of seconds on
+old systems like that.
+
+inxi is being written, and tested, on Perl as old as 5.08, and will work on any
+system that runs Perl 5.08 or later. Pre 2.9.0 Gawk/Bash inxi will also run on
+any system no matter how old, within reason, so there should be no difference.
+
+===============================================================================
BSD SUPPORT
Real BSDs:
-BSD support is not as complete as GNU/Linux support due to the fact
-some of the data simply is not available, or is structured in a way
-that makes it unique to each BSD. This fragmentation makes supporting
-BSDs far more difficult than it should be in the 21st century. The
-BSD support in inxi is an ongoing process, with more features being
-added as new data sources and types are discovered.
-
-All BSD issue reports unless trivial and obvious will require 1 of
-two things:
-
-1. a full --debug 21 data dump so I don't have to spend days trying
-to get the information I need to resolve the issue file by painful
-file from the issue poster. This is only the start of the process,
-and realistically requires 2. to complete it.
-
-2. direct SSH access to at least a comparable live BSD version/system,
-that is, if the issue is on a laptop, access has to be granted to the
-laptop, or a similar one.
-
-Option 2 is far preferred because in terms of my finite time on this
-planet of ours, the fact is, if I don't have direct (or SSH) access,
-I can't get much done, and the little I can get done will take 10 to
-1000x longer than it should. That's my time spent (and sadly, with
-BSDs, largely lost), not yours.
-
-I decided I have to adopt this much more strict policy with BSDs
-after wasting untold hours on trying to get good BSD support, only
-to see that support break a few years down the road as the data inxi
-relied in changed structure or syntax, or the tools changed, or
-whatever else makes the BSDs such a challenge to support. In the end,
-I realized, the only BSDs that are well supported are ones that I have
-had direct access to for debugging and testing.
+BSD support is not as complete as GNU/Linux support due to the fact some of the
+data simply is not available, or is structured in a way that makes it unique to
+each BSD. This fragmentation makes supporting BSDs far more difficult than it
+should be in the 21st century. The BSD support in inxi is an ongoing process,
+with more features being added as new data sources and types are discovered.
+
+All BSD issue reports unless trivial and obvious will require 1 of two things:
+
+1. a full --debug 21 data dump so I don't have to spend days trying to get the
+information I need to resolve the issue file by painful file from the issue
+poster. This is only the start of the process, and realistically requires 2. to
+complete it.
+
+2. direct SSH access to at least a comparable live BSD version/system, that is,
+if the issue is on a laptop, access has to be granted to the laptop, or a
+similar one.
+
+Option 2 is far preferred because in terms of my finite time on this planet of
+ours, the fact is, if I don't have direct (or SSH) access, I can't get much
+done, and the little I can get done will take 10 to 1000x longer than it
+should. That's my time spent (and sadly, with BSDs, largely lost), not yours.
+
+I decided I have to adopt this much more strict policy with BSDs after wasting
+untold hours on trying to get good BSD support, only to see that support break
+a few years down the road as the data inxi relied in changed structure or
+syntax, or the tools changed, or whatever else makes the BSDs such a challenge
+to support. In the end, I realized, the only BSDs that are well supported are
+ones that I have had direct access to for debugging and testing.
I will always accept patches that are well done, if they do not break
-GNU/Linux, and extend BSD support, or add new BSD features, and follow
-the internal inxi logic, and aren't too long. inxi sets initial internal
-flags to identify that it is a BSD system vs a GNU/Linux system, and
-preloads some data structures for BSD use, so make sure you understand
-what inxi is doing before you get into it.
+GNU/Linux, and extend BSD support, or add new BSD features, and follow the
+internal inxi logic, and aren't too long. inxi sets initial internal flags to
+identify that it is a BSD system vs a GNU/Linux system, and preloads some data
+structures for BSD use, so make sure you understand what inxi is doing before
+you get into it.
OSX:
-Do not insult real BSDs by calling OSX a BSD. OSX is the least
-Unix-like operating system I've ever seen that claims to be a Unix,
-its tools are mutated, it's data randomly and non-standardly organized,
-and it totally fails to respect the 'spirit' of Unix, even though it
-might pass some random tests that certify a system as a 'Unix'.
-
-If you want me to use my time on OSX features or issues, you have to
-pay me, because Apple is all about money, not freedom (that's what
-the 'free' in 'free software' is referring to, not cost), and I'm not
-donating my finite time in support of non-free operating systems.
-
-=====================================================================
+Do not insult real BSDs by calling OSX a BSD. OSX is the least Unix-like
+operating system I've ever seen that claims to be a Unix, its tools are
+mutated, it's data randomly and non-standardly organized, and it totally fails
+to respect the 'spirit' of Unix, even though it might pass some random tests
+that certify a system as a 'Unix'.
+
+If you want me to use my time on OSX features or issues, you have to pay me,
+because Apple is all about money, not freedom (that's what the 'free' in 'free
+software' is referring to, not cost), and I'm not donating my finite time in
+support of non-free operating systems.
+
+===============================================================================
INXI FEATURES AND FUNCTIONALITY
-inxi's functionality continues to grow over time, but it's also
-important to understand that each core new feature usually requires
-about 30 days work to get it stable. So new features are not trivial
-things, nor is it acceptable to submit a patch that works only on your
-personal system. One inxi feature (-s, sensors data), took about
-2 hours to get working in the alpha test on the local dev system, but
-then to handle the massive chaos that is actual user sensors output
-and system variations, it took several rewrites and about 30 days to
-get somewhat reliable for about 98% or so of inxi users. So if your
-patch is rejected, it's likely because you have not thought it through
-adequately, have not done adequate testing cross system and
-platform, etc.
-
-=====================================================================
-INXI RELEASE/SUPPORT/ISSUES/BUGS INFORMATION:
-
-Important: the only version of inxi that is supported is the latest
-current master branch release. No issue reports or bug reports will be
-accepted for anything other than current master branch. No merges,
-attempts to patch old code from old releases, will be considered or
-accepted. If you are not updated to the latest inxi, do not file a
-bug report since it's probably been fixed ages ago. If your distro
-isn't packaging a current inxi, then file a bug report with them, not
-here. The only valid working code base for inxi is the current
-release of inxi.
-
-Distributions should never feel any advantage comes from using old
-inxi releases because inxi has as a core promise to you, the end user,
-that it will NEVER require new tools to run. New tools may be required
-for a new feature, but that will always be handled internally by inxi,
-and will not cause any operational failures. This is a promise, and I
-will never as long as I run this project violate that core inxi
-requirement. Old inxi is NOT more stable than current inxi, it's just
-old, and lacking in bug fixes and features. For pre 2.9 releases, it's
-also significantly slower, and with fewer features.
-
-inxi is a rolling release codebase, just like Debian Sid, Gentoo, or
-Arch Linux are rolling release GNU/Linux distributions, with no
-'release points'.
-
-Your distro not updating inxi ever, then failing to show something
-that is fixed in current inxi is not a bug, and please do not post it
-here. File the issue with your distro, not here. Updating inxi in a
-package pool will NEVER make anything break or fail, period. It has no
-version based dependencies, just software, like Perl 5.xx, lspci, etc.
-There is never a valid reason to not update inxi in a package pool of
-any distro in the world (with one single known exception, the Slackware
-based Puppy Linux release, which ships without the full Perl language.
-The Debian based one works fine).
-
-Sys Admin type inxi users always get the first level of support. ie,
-convince us you run real systems and networks, and your issue shoots
-to the top of the line. As do any real bugs. Failure to supply
-requested debugger data will lead to a distinct lack of interest on
-our part to help you with a bug. ie, saying, oh, x doesn't work,
-doesn't cut it, unless it's obvious why.
-
-=====================================================================
+inxi's functionality continues to grow over time, but it's also important to
+understand that each core new feature usually requires about 30 days work to
+get it stable. So new features are not trivial things, nor is it acceptable to
+submit a patch that works only on your personal system. One inxi feature (-s,
+sensors data), took about 2 hours to get working in the alpha test on the local
+dev system, but then to handle the massive chaos that is actual user sensors
+output and system variations, it took several rewrites and about 30 days to
+get somewhat reliable for about 98% or so of inxi users. So if your patch is
+rejected, it's likely because you have not thought it through adequately, have
+not done adequate testing cross system and platform, etc.
+
+===============================================================================
+INXI VERSION/SUPPORT/ISSUES/BUGS INFORMATION:
+
+Important: the only version of inxi that is supported is the latest current
+master branch version/commit. No issue reports or bug reports will be accepted
+for anything other than current master branch. No merges, attempts to patch old
+code from old versions, will be considered or accepted. If you are not updated
+to the latest inxi, do not file a bug report since it's probably been fixed
+ages ago. If your distro isn't packaging a current inxi, then file a bug report
+with them, not here.
+
+Distributions should never feel any advantage comes from using old inxi
+versions because inxi has as a core promise to you, the end user, that it will
+never require new tools to run. New tools may be required for a new feature,
+but that will always be handled internally by inxi, and will not cause any
+operational failures. This is a promise, and I will never as long as I run this
+project violate that core inxi requirement. Old inxi is NOT more stable than
+current inxi, it's just old, and lacking in bug fixes and features. For pre 2.9
+versions, it's also significantly slower, and with fewer features.
+
+inxi is 'rolling release' software, just like Debian Sid, Gentoo, or Arch Linux
+are rolling release GNU/Linux distributions, with no 'release points'.
+
+Your distro not updating inxi ever, then failing to show something that is
+fixed in current inxi is not a bug, and please do not post it here. File the
+issue with your distro, not here. Updating inxi in a package pool will NEVER
+make anything break or fail, period. It has no version based dependencies, just
+software, like Perl 5.xx, lspci, etc. There is never a valid reason to not
+update inxi in a package pool of any distro in the world (with one single known
+exception, the Slackware based Puppy Linux release, which ships without the
+full Perl language. The Debian based one works fine).
+
+Sys Admin type inxi users always get the first level of support. ie, convince
+us you run real systems and networks, and your issue shoots to the top of the
+line. As do any real bugs. Failure to supply requested debugger data will lead
+to a distinct lack of interest on our part to help you with a bug. ie, saying,
+oh, it doesn't work, doesn't cut it, unless it's obvious why.
+
+===============================================================================
INXI VERSION NUMBERING:
-inxi uses 'semantic' version numbering, where the version numbers
-actually mean something.
+inxi uses 'semantic' version numbering, where the version numbers actually mean
+something.
The version number follows these guidelines:
Using example 3.2.28-6
-The first digit(s), "3", is a major version, and almost never changes.
-Only a huge milestone, or if inxi reaches 3.9.xx, when it will simply
-move up to 4.0.0 just to keep it clean, would cause a change.
-
-The second digit(s), "2", means a new real feature has been added.
-Not a tweaked existing feature, an actual new feature, which usually
-also has a new argument option letter attached. The second number goes
-from 0 to 9, and then rolls over the first after 9. It could also be
-adding a very complicated expansion of existing features, like Wayland.
-It depends.
-
-The third, "28", is for everything small, can cover bug fixes, tweaks
-to existing features to add support for something, pretty much anything
-where you want the end user to know that they are not up to date. The
-third goes from 0 to 99, then rolls over the second.
-
-The fourth, "6", is extra information about certain types of inxi
-updates. I don't usually use this last one in master branch, but you
-will see it in branches one,two, inxi-perl, inxi-legacy since that is
-used to confirm remote test system patch version updates.
-
-The fourth number, when used, will be alpha-numeric, a common version
-would be, in say, branch one: 2.2.28-b1-02, in other words, a branch 1
-release, version 2.
-
-In the past, now and then the 4th, or 'patch', number, was used in
-trunk/master branches of inxi, but I've pretty much stopped doing that
-because it's confusing.
-
-inxi does not use the fiction of date based versioning because that
-imparts no useful information to the end user, when you look at say,
-2.2.28, and you last had 2.2.11, you can know with some certainty that
-inxi has no major new features, just fine tunings and bug fixes. And
-if you see one with 2.3.2, you will know that there is a new feature,
-almost, but not always, linked to one or more new line output items.
-Sometimes a fine tuning can be quite significant, sometimes it's a
-one line code fix.
-
-A move to a new full version number, like the rewrite of inxi to Perl,
-would reflect in first version say, 2.9.01, then after a period of
-testing, where most little glitches are fixed, a move to 3.0.0. These
-almost never happen. I do not expect for example version 4.0 to ever
-happen after the 3.0 release of early 2018, unless so many new
-features are added that it actually hits 3.9, then it would roll
-over to 4.
+The first digit(s), "3", is a major version, and almost never changes. Only a
+huge milestone, or if inxi reaches 3.9.xx, when it will simply move up to 4.0.0
+just to keep it clean, would cause a change.
+
+The second digit(s), "2", means a new real feature has been added. Not a
+tweaked existing feature, an actual new feature, which usually also has a new
+argument option letter attached. The second number goes from 0 to 9, and then
+rolls over the first after 9. It could also be adding a very complicated
+expansion of existing features, like Wayland. It depends.
+
+The third, "28", is for everything small, can cover bug fixes, tweaks to
+existing features to add support for something, pretty much anything where you
+want the end user to know that they are not up to date. The third goes from 0
+to 99, then rolls over the second.
+
+The fourth, "6", is extra information about certain types of inxi updates. I
+don't usually use this last one in master branch, but you will see it in
+branches one,two, inxi-perl, inxi-legacy since that is used to confirm remote
+test system patch version updates.
+
+The fourth number, when used, will be alpha-numeric, a common version would be,
+in say, branch one: 2.2.28-b1-02, in other words: branch 1 patch version 2.
+
+In the past, now and then the 4th, or 'patch', number, was used in trunk/master
+branches of inxi, but I've pretty much stopped doing that because it's
+confusing.
+
+inxi does not use the fiction of date based versioning because that imparts no
+useful information to the end user, when you look at say, 2.2.28, and you last
+had 2.2.11, you can know with some certainty that inxi has no major new
+features, just fine tunings and bug fixes. And if you see one with 2.3.2, you
+will know that there is a new feature, almost, but not always, linked to one or
+more new line output items. Sometimes a fine tuning can be quite significant,
+sometimes it's a one line code fix.
+
+A move to a new full version number, like the rewrite of inxi to Perl, would
+reflect in first version say, 2.9.01, then after a period of testing, where
+most little glitches are fixed, a move to 3.0.0. These almost never happen. I
+do not expect for example version 4.0 to ever happen after 3.0 (early 2018),
+unless so many new features are added that it actually hits 3.9, then it would
+roll over to 4.
### EOF ###
diff --git a/inxi b/inxi
index 92926b5..dc46bb0 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.07';
-my $self_date='2018-04-17';
+my $self_version='3.0.09';
+my $self_date='2018-05-11';
my $self_patch='00';
## END INXI INFO ##
@@ -52,7 +52,7 @@ if (eval {require Time::HiRes}){
}
@t0 = eval 'Time::HiRes::gettimeofday()' if $b_hires; # let's start it right away
## Hashes
-my ( %alerts, %client, %colors, %dl, %files, %rows, %system_files, %use );
+my ( %alerts,%client,%colors,%dl,%files,%rows,%system_files,%use );
## Arrays
# ps_aux is full output, ps_cmd is only the last 10 to last
@@ -65,22 +65,25 @@ 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_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_sysctl,$b_usb_check);
+$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);
## Disk checks
-my ($b_dm_boot_disk,$b_dm_boot_optical,$b_glabel,$b_lsblk,$b_partitions,
-$b_partition_extra,$b_raid);
+my ($b_dm_boot_disk,$b_dm_boot_optical,$b_glabel,$b_label_uuid,$b_lsblk,
+$b_partitions,$b_raid);
my ($b_sysctl_disk,$b_update,$b_weather) = (1,1,1);
## System
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 ($bits_sys);
+my $weather_unit='cf';
## Tools
my ($display,$ftp_alt,$tty_session);
-my $display_opt = '';
+my ($display_opt,$sudo) = ('','');
## Output
my $extra = 0;# supported values: 0-3
@@ -279,7 +282,23 @@ sub check_tools {
%alerts = (%alerts, %hash);
}
# print Dumper \%alerts;
+ # only use sudo if not root, -n option requires sudo -V 1.7 or greater.
+ # for some reason sudo -n with < 1.7 in Perl does not print to stderr
+ # sudo will just error out which is the safest course here for now,
+ # otherwise that interactive sudo password thing is too annoying
+ # important: -n makes it non interactive, no prompt for password
+ if (!$b_root && $b_sudo && (my $path = main::check_program('sudo') )) {
+ my @data = program_values('sudo');
+ my $version = program_version($path,$data[0],$data[1],$data[2],$data[5]);
+ $version =~ s/^([0-9]+\.[0-9]+).*/$1/;
+ $sudo = "$path -n " if $version >= 1.7;
+ }
+ set_fake_tools() if $b_fake_bsd;
}
+
+# args: 1 - desktop/app command for --version; 2 - search string;
+# 3 - space print number; 4 - [optional] version arg: -v, version, etc
+# 5 - [optional] exit first find 0/1; 6 - [optional] 0/1 stderr output
sub set_basics {
### LOCALIZATION - DO NOT CHANGE! ###
# set to default LANG to avoid locales errors with , or .
@@ -353,6 +372,21 @@ sub set_display_width {
}
# print "tc: $size{'term'} cmc: $size{'console'} cm: $size{'max'}\n";
}
+
+# only for dev/debugging BSD
+sub set_fake_tools {
+ $system_files{'dmesg-boot'} = '/var/run/dmesg.boot' if $b_fake_dboot;
+ $alerts{'pciconf'} = ({'action' => 'use'}) if $b_fake_pciconf;
+ $alerts{'sysctl'} = ({'action' => 'use'}) if $b_fake_sysctl;
+ if ($b_fake_usbdevs ){
+ $alerts{'usbdevs'} = ({'action' => 'use'});
+ $alerts{'lsusb'} = ({
+ 'action' => 'missing',
+ 'missing' => 'Required program lsusb not available',
+ });
+ }
+}
+
# NOTE: most tests internally are against !$bsd_type
sub set_os {
@uname = uname();
@@ -380,6 +414,7 @@ sub set_os {
}
}
}
+
# This data is hard set top of program but due to a specific project's
# foolish idea that ignoring the FSH totally is somehow a positive step
# forwards for free software, we also have to padd the results with PATH.
@@ -464,6 +499,7 @@ sub set_user_paths {
#system 'echo', "$ENV{'HOME'}/.$self_name/* $user_data_dir";
# print "scd: $user_config_dir sdd: $user_data_dir \n";
}
+
# args: 1: set|hash key to return either null or path
sub system_files {
my ($file) = @_;
@@ -502,6 +538,7 @@ sub system_files {
return $system_files{$file};
}
}
+
########################################################################
#### UTILITIES
########################################################################
@@ -987,6 +1024,7 @@ 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}
# layout
elsif ($key eq 'CONSOLE_COLOR_SCHEME') {$colors{'console'} = int($val)}
elsif ($key eq 'GLOBAL_COLOR_SCHEME') {$colors{'global'} = int($val)}
@@ -1051,6 +1089,7 @@ sub begin_logging {
print $fh_l $data;
}
+
# NOTE: no logging available until get_parameters is run, since that's what
# sets logging # in order to trigger earlier logging manually set $b_log
# to true in top variables.
@@ -1348,7 +1387,8 @@ sub disk_data {
['lsblk', '-r'],
['lsblk', '-r --output NAME,PKNAME,TYPE,RM,FSTYPE,SIZE,LABEL,UUID,MOUNTPOINT'],
['lsblk', '-rb --output NAME,PKNAME,TYPE,RM,FSTYPE,SIZE,LABEL,UUID,MOUNTPOINT'],
- ['lsblk', '-Pb --output NAME,PKNAME,TYPE,RM,FSTYPE,SIZE,LABEL,UUID,MOUNTPOINT'],
+ ['lsblk', '-Pb --output NAME,PKNAME,TYPE,RM,FSTYPE,SIZE'],
+ ['lsblk', '-Pb --output NAME,TYPE,RM,FSTYPE,SIZE,LABEL,UUID,SERIAL,MOUNTPOINT'],
['gpart', 'list'],
['gpart', 'show'],
['gpart', 'status'],
@@ -1513,7 +1553,7 @@ sub system_data {
my %data = (
'cc' => $ENV{'CC'},
# @(#)MIRBSD KSH R56 2018/03/09: ksh and mksh
- 'ksh-version' => $ENV{'KSH_VERSION'},
+ 'ksh-version' => system('echo -n $KSH_VERSION'), # shell, not env, variable
'manpath' => $ENV{'MANPATH'},
'path' => $ENV{'PATH'},
'xdg-config-home' => $ENV{'XDG_CONFIG_HOME'},
@@ -2149,6 +2189,7 @@ sub error_handler {
}
exit 0;
}
+
sub error_defaults {
my ($type,$one) = @_;
$one ||= '';
@@ -2789,6 +2830,7 @@ sub awk {
eval $end if $b_log;
return $result;
}
+
# $1 - Perl module to check
sub check_module {
my ($module) = @_;
@@ -2797,6 +2839,7 @@ sub check_module {
$b_present = 1 if !$@;
return $b_present;
}
+
# arg: 1 - string or path to search gneerated @paths data for.
# note: a few nano seconds are saved by using raw $_[0] for program
sub check_program {
@@ -2861,6 +2904,7 @@ sub globber {
eval $end if $b_log;
return @files;
}
+
# gets array ref, which may be undefined, plus join string
# this helps avoid debugger print errors when we are printing arrays
# which we don't know are defined or not null.
@@ -2973,7 +3017,7 @@ sub program_values {
'clang' => ['clang',3,'--version','Clang',1,0,0],
'gcc' => ['^gcc',3,'--version','GCC',1,0,0],
'gcc-apple' => ['Apple[[:space:]]LLVM',2,'--version','LLVM',1,0,0],
- 'sudo' => ['^Sudo',3,'--version','Sudo',1,0,0],
+ 'sudo' => ['^Sudo',3,'-V','Sudo',1,1,0], # sudo pre 1.7 does not have --version
);
if ( defined $data{$app} ){
my $ref = $data{$app};
@@ -2983,6 +3027,7 @@ sub program_values {
main::log_data('dump',"Client Data",\@client_data) if $b_log;
return @client_data;
}
+
# args: 1 - desktop/app command for --version; 2 - search string;
# 3 - space print number; 4 - [optional] version arg: -v, version, etc
# 5 - [optional] exit first find 0/1; 6 - [optional] 0/1 stderr output
@@ -3000,10 +3045,11 @@ sub program_version {
# mksh: @(#)MIRBSD KSH R56 2018/03/09
# loksh: @(#)PD KSH v5.2.14 99/07/13.2
# --version opens a new ksh, sigh... This so far does not work
- # because the ENV variable is not visible internally
+ # because the ENV/Shell variable is not visible in subshells
if ($search eq 'ksh'){
- if ( $ENV{'KSH_VERSION'} ){
- my @temp = split /\s+/, $ENV{'KSH_VERSION'};
+ my $ksh = system('echo -n $KSH_VERSION');
+ if ( $ksh ){
+ my @temp = split /\s+/, $ksh;
if ($temp[2]){
$temp[2] =~ s/^v//i; # trim off leading v
log_data('data',"Program *ksh array: @temp version: $temp[2]") if $b_log;
@@ -3057,7 +3103,9 @@ sub program_version {
# breaks version detection. A quick fix attempt is to just add 1 to $num
# to get the next value.
$version_nu = $data[$num+1] if $data[$num+1] && $version_nu =~ /version/i;
- $version_nu =~ s/(\([^)]+\)|,|dwm-|wmii2-|wmii-|v|V|\||\(|\))//g if $version_nu;
+ $version_nu =~ s/(\([^)]+\)|,|dwm-|wmii2-|wmii-|\||\(|\))//g if $version_nu;
+ # trim off leading v but only when followed by a number
+ $version_nu =~ s/^v([0-9])/$1/i if $version_nu;
# print "$version_nu\n";
last;
}
@@ -3087,6 +3135,7 @@ sub reader {
eval $end if $b_log;
return @rows;
}
+
# args: 1 - the file to create if not exists
sub toucher {
my $file = shift;
@@ -3105,12 +3154,14 @@ sub trimmer {
#eval $end if $b_log;
return $str;
}
+
# args: 1 - hash
# send array, assign to hash, return array, uniq values only.
sub uniq {
my %seen;
grep !$seen{$_}++, @_;
}
+
# arg: 1 file full path to write to; 2 - arrayof data to write.
# note: turning off strict refs so we can pass it a scalar or an array reference.
sub writer {
@@ -3124,7 +3175,7 @@ sub writer {
else {
$content = scalar $ref_content;
}
- open(my $fh, '>', $path) or error_handler('open',"$path", "$!");
+ open(my $fh, ">", $path) or error_handler('open',"$path", "$!");
print $fh $content;
close $fh;
}
@@ -3155,6 +3206,7 @@ sub get_defaults {
error_handler('bad-arg-int', $type);
}
}
+
# args: 1 - download url, not including file name; 2 - string to print out
# 3 - update type option
# note that 1 must end in / to properly construct the url path
@@ -3596,6 +3648,16 @@ sub get_options{
else {
error_handler('distro-block', $opt);
} },
+ 'weather-unit:s' => sub {
+ my ($opt,$arg) = @_;
+ $arg ||= '';
+ $arg =~ s/\s//g;
+ if ($arg && $arg =~ /^(cf|fc|f|c)$/i){
+ $weather_unit = lc($arg);
+ }
+ else {
+ error_handler('bad-arg',$opt,$arg);
+ } },
'x|extra:i' => sub {
my ($opt,$arg) = @_;
if ($arg > 0){
@@ -3646,6 +3708,19 @@ sub get_options{
my ($opt,$arg) = @_;
if ($arg =~ /^(darwin|dragonfly|freebsd|openbsd|netbsd)$/i){
$bsd_type = lc($arg);
+ $b_fake_bsd = 1;
+ }
+ else {
+ error_handler('bad-arg', $opt, $arg);
+ }
+ },
+ 'bsd-data:s' => sub {
+ my ($opt,$arg) = @_;
+ if ($arg =~ /^(dboot|pciconf|sysctl|usbdevs)$/i){
+ $b_fake_dboot = 1 if $arg eq 'dboot';
+ $b_fake_pciconf = 1 if $arg eq 'pciconf';
+ $b_fake_sysctl = 1 if $arg eq 'sysctl';
+ $b_fake_usbdevs = 1 if $arg eq 'usbdevs';
}
else {
error_handler('bad-arg', $opt, $arg);
@@ -3830,13 +3905,14 @@ sub get_options{
# to detect wan/lan, we have to use long form to get as much data as possible
$usb_level = ($show{'usb'} || $show{'network'}) ? 2 : 1;
}
- if ($bsd_type && ($show{'short'} || $show{'cpu'} || $show{'cpu-basic'} || $show{'machine'} ||
- $show{'info'} || $show{'process'} || $show{'ram'} ) ){
+ if ($bsd_type && ($show{'short'} || $show{'battery'} || $show{'cpu'} || $show{'cpu-basic'} ||
+ $show{'info'} || $show{'machine'} || $show{'process'} || $show{'ram'} || $show{'sensor'} ) ){
$b_sysctl = 1;
}
if ($show{'filter-override'}){
$show{'filter'} = 0;
}
+ $b_sudo = 1 if ( $show{'unmounted'} || ($extra > 0 && $show{'disk'}) );
# override for things like -b or -v2 to -v3
$show{'cpu-basic'} = 0 if $show{'cpu'};
$show{'optical-basic'} = 0 if $show{'optical'};
@@ -3987,7 +4063,9 @@ sub show_options {
<location>: postal code; city, state/country; latitude, longitude.
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"]
+ 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)."],
);
push @data, @rows;
}
@@ -4015,7 +4093,7 @@ sub show_options {
['2', '-R', '', "md-raid: second RAID Info line with extra data:
blocks, chunk size, bitmap (if present). Resync line, shows blocks
synced/total blocks." ],
- ['2', '-s', '', "Basic voltages (ipmi only): 12v, 5v, 3.3v, vbat." ],
+ ['2', '-s', '', "Basic voltages (ipmi, lm-sensors if present): 12v, 5v, 3.3v, vbat." ],
['2', '-S', '', "Desktop toolkit, if available (GNOME/Xfce/KDE only);
Kernel gcc version" ],
['2', '-t', '', "Adds memory use output to CPU (-xt c), and CPU use to
@@ -4611,13 +4689,23 @@ sub clean_characters {
sub cleaner {
my ($item) = @_;
return $item if !$item;# handle cases where it was 0 or ''
- $item =~ s/chipset|components|computing|computer|corporation|communications|electronics|electrical|electric|gmbh|group|incorporation|industrial|international|nee|revision|semiconductor|software|technologies|technology|ltd\.|<ltd>|\bltd\b|inc\.|<inc>|\binc\b|intl\.|co\.|<co>|corp\.|<corp>|\(tm\)|\(r\)|®|\(rev ..\)|\'|\"|\sinc\s*$|\?//gi;
+ # note: |nee trips engineering, but I don't know why nee was filtered
+ $item =~ s/chipset|company|components|computing|computer|corporation|communications|electronics|electrical|electric|gmbh|group|incorporation|industrial|international|\bnee\b|revision|semiconductor|software|technologies|technology|ltd\.|<ltd>|\bltd\b|inc\.|<inc>|\binc\b|intl\.|co\.|<co>|corp\.|<corp>|\(tm\)|\(r\)|®|\(rev ..\)|\'|\"|\sinc\s*$|\?//gi;
$item =~ s/,|\*/ /g;
$item =~ s/\s\s+/ /g;
$item =~ s/^\s+|\s+$//g;
return $item;
}
+sub disk_cleaner {
+ my ($item) = @_;
+ return $item if !$item;
+ $item =~ s/vendor.*|product.*|O\.?E\.?M\.?//gi;
+ $item =~ s/\s\s+/ /g;
+ $item =~ s/^\s+|\s+$//g;
+ return $item;
+}
+
sub dmi_cleaner {
my ($string) = @_;
my $cleaner = '^Base Board .*|^Chassis .*|empty|Undefined.*|.*O\.E\.M\..*|.*OEM.*|^Not .*';
@@ -4632,6 +4720,7 @@ sub dmi_cleaner {
$string = remove_duplicates($string) if $string;
return $string;
}
+
sub remove_duplicates {
my ($string) = @_;
return if ! $string;
@@ -4695,6 +4784,7 @@ sub increment_starters {
}
return $result;
}
+
sub memory_data_full {
eval $start if $b_log;
my ($source) = @_;
@@ -4768,8 +4858,9 @@ sub row_defaults {
'dmesg-boot-missing' => 'dmesg.boot not found',
'IP' => "No $id data found. Connected to the web? SSL issues?",
'machine-data' => "No machine data: try newer kernel.",
- 'machine-data-alt-33' => "No machine data: try newer kernel. Is dmidecode installed? Try -M --dmidecode.",
- 'machine-data-dmidecode' => "No machine data: try newer kernel, or install dmidecoce.",
+ 'machine-data-bsd' => "No machine data: Is dmidecode installed? Try -M --dmidecode.",
+ 'machine-data-dmidecode' => "No machine data: try newer kernel. Is dmidecode installed? Try -M --dmidecode.",
+ 'machine-data-force-dmidecode' => "No machine data: try newer kernel. Is dmidecode installed? Try -M --dmidecode.",
'optical-data' => "No Optical or Floppy data was found.",
'optical-data-bsd' => "No floppy or optical data found for this BSD system.",
'output-limit' => "Output throttled. IPs: $id; Limit: $limit; Override: --limit [1-x;-1 all]",
@@ -4795,6 +4886,7 @@ sub row_defaults {
);
return $unfound{$type};
}
+
# convert string passed to KB, based on GB/MB/TB id
# NOTE: K 1024 KB 1000
sub translate_size {
@@ -4853,6 +4945,7 @@ sub output_handler {
generate_xml(%data);
}
}
+
# NOTE: file has already been set and directory verified
sub generate_json {
eval $start if $b_log;
@@ -4889,6 +4982,7 @@ sub generate_json {
}
eval $end if $b_log;
}
+
# NOTE: So far xml is substantially more difficult than json, so
# using a crude dumper rather than making a nice xml file, but at
# least xml has some output now.
@@ -5006,6 +5100,7 @@ sub print_basic {
}
}
}
+
# this has to get a hash of hashes, at least for now.
# because perl does not retain insertion order, I use a prefix for each
# hash key to force sorts.
@@ -5711,6 +5806,9 @@ sub battery_data_sys {
$value = main::dmi_cleaner($value);
}
}
+ elsif ($b_root && -e $path && ! -r $path ){
+ $value = main::row_defaults('root-required');
+ }
$battery{$id}{$file} = $value;
# print "$battery{$id}{$file}\n";
}
@@ -6276,7 +6374,7 @@ sub data_sysctl {
$line[1] = main::cleaner($line[1]);
$line[1] = cpu_cleaner($line[1]);
if ( $line[1] =~ /([0-9]+)[\-[:space:]]*([KM]B)\s+L2 cache/) {
- my $multiplier = ($2 eq 'KB') ? 1024: 1;
+ my $multiplier = ($2 eq 'MB') ? 1024: 1;
$cpu{'l2-cache'} = $1 * $multiplier;
}
if ( $line[1] =~ /([^0-9\.][0-9\.]+)[\-[:space:]]*[MG]Hz/) {
@@ -6752,10 +6850,7 @@ sub cpu_flags_bsd {
my ($flags,$sep) = ('','');
# this will be null if it was not readable
my $file = main::system_files('dmesg-boot');
- if ( $file && ! -r $file ){
- $flags = main::row_defaults('dmesg-boot-permissions');
- }
- else {
+ if ( @dmesg_boot){
foreach (@dmesg_boot){
if ( /Features/ || ( $bsd_type eq "openbsd" && /^cpu0:\s*[a-z0-9]{2,3}(\s|,)[a-z0-9]{2,3}(\s|,)/i ) ) {
my @line = split /:\s*/, lc($_);
@@ -6778,6 +6873,11 @@ sub cpu_flags_bsd {
$flags =~ s/^\s+|\s+$//g;
}
}
+ else {
+ if ( $file && ! -r $file ){
+ $flags = main::row_defaults('dmesg-boot-permissions');
+ }
+ }
eval $end if $b_log;
return $flags;
}
@@ -6998,8 +7098,8 @@ sub cpu_cleaner {
## DiskData
{
package DiskData;
-my ($b_hddtemp,$b_nvme,$b_sudo);
-my ($hddtemp,$nvme,$sudo) = ('','','');
+my ($b_hddtemp,$b_nvme);
+my ($hddtemp,$nvme) = ('','');
my (@by_id,@by_path);
sub get {
@@ -7017,10 +7117,10 @@ sub get {
if ( $bsd_type && !@dm_boot_disk && $type eq 'standard' && $show{'disk'} ){
$key1 = 'Drive Report';
my $file = main::system_files('dmesg-boot');
- if ( $file && ! -r $file ){
+ if ( $file && ! -r $file){
$val1 = main::row_defaults('dmesg-boot-permissions');
}
- elsif (! -e $file){
+ elsif (!$file){
$val1 = main::row_defaults('dmesg-boot-missing');
}
else {
@@ -7051,7 +7151,7 @@ sub get {
@data = OpticalData::get();
@rows = (@rows,@data);
}
- ($b_hddtemp,$b_nvme,$b_sudo,$hddtemp,$nvme,$sudo) = (undef,undef,undef,undef,undef,undef);
+ ($b_hddtemp,$b_nvme,$hddtemp,$nvme) = (undef,undef,undef,undef);
(@by_id,@by_path) = (undef,undef);
eval $end if $b_log;
return @rows;
@@ -7121,6 +7221,9 @@ sub create_output {
if ($row{'type'}){
$rows[$j]{main::key($num++,'type')} = $row{'type'},
}
+ if ($row{'vendor'}){
+ $rows[$j]{main::key($num++,'vendor')} = $row{'vendor'},
+ }
$rows[$j]{main::key($num++,'model')} = $model;
$rows[$j]{main::key($num++,'size')} = $size;
if ($extra > 0 && $row{'speed'}){
@@ -7214,9 +7317,9 @@ sub proc_data {
# }
# special case from this data: 8 0 156290904 sda
# 43 0 48828124 nbd0
- # note: known starters: vm: 252/253/254; grsec: 202; nvme: 259
- if ( $row[0] =~ /^(3|8|22|33|43|202|252|253|254|259)$/ &&
- $row[-1] =~ /(n[b]?d[0-9]+|nvme[0-9]+n[0-9]+|[hsv]d[a-z]+)$/ &&
+ # note: known starters: vm: 252/253/254; grsec: 202; nvme: 259 mmcblk: 179
+ if ( $row[0] =~ /^(3|8|22|33|43|179|202|252|253|254|259)$/ &&
+ $row[-1] =~ /(mmcblk[0-9]+|n[b]?d[0-9]+|nvme[0-9]+n[0-9]+|[hsv]d[a-z]+)$/ &&
( $row[1] % 16 == 0 || $row[1] % 16 == 8 ) ) {
$size += $row[2];
}
@@ -7242,11 +7345,18 @@ sub proc_data_advanced {
eval $start if $b_log;
my ($b_hdx,@drives) = @_;
my ($i) = (0);
- my (@data,@rows,@scsi,@temp,@working);
+ my (@data,@disk_data,@rows,@scsi,@temp,@working);
my ($pt_cmd) = ('unset');
my ($block_type,$file,$firmware,$model,$path,$partition_scheme,
$serial,$vendor,$working_path);
@by_id = main::globber('/dev/disk/by-id/*');
+ # these do not contain any useful data, no serial or model name
+ # wwn-0x50014ee25fb50fc1 and nvme-eui.0025385b71b07e2e
+ # scsi-SATA_ST980815A_ simply repeats ata-ST980815A_; same with scsi-0ATA_WDC_WD5000L31X
+ # we also don't need the partition items
+ my $pattern = '^\/dev\/disk\/by-id\/(md-|lvm-|dm-|wwn-|nvme-eui|raid-|scsi-([0-9]ATA|SATA))|-part[0-9]+$';
+ @by_id = grep {!/$pattern/} @by_id if @by_id;
+ # print join "\n", @by_id, "\n";
@by_path = main::globber('/dev/disk/by-path/*');
## check for all ide type drives, non libata, only do it if hdx is in array
## this is now being updated for new /sys type paths, this may handle that ok too
@@ -7264,7 +7374,7 @@ sub proc_data_advanced {
if ($file = main::system_files('scsi')){
@scsi = scsi_data($file);
}
- #print 'drives:', Data::Dumper::Dumper \@drives;
+ # print 'drives:', Data::Dumper::Dumper \@drives;
for ($i = 1; $i < scalar @drives; $i++){
#next if $drives[$i]{'id'} =~ /^hd[a-z]/;
($block_type,$firmware,$model,$partition_scheme,
@@ -7275,6 +7385,8 @@ sub proc_data_advanced {
$drives[$i]{'partition-table'} = uc($data[1]) if $data[1];
}
#print "$drives[$i]{'id'}\n";
+ @disk_data = disk_data_by_id("/dev/$drives[$i]{'id'}");
+ main::log_data('dump','@disk_data', \@disk_data) if $b_log;
if ($drives[$i]{'id'} =~ /[sv]d[a-z]/){
$block_type = 'sdx';
$working_path = "/sys/block/$drives[$i]{'id'}/device/";
@@ -7292,55 +7404,59 @@ sub proc_data_advanced {
$working_path =~ s/nvme[^\/]*$//;
}
main::log_data('data',"working path: $working_path") if $b_log;
- if ($block_type){
+ if ($block_type && @scsi && @by_id && ! -e "${working_path}model" && ! -e "${working_path}name"){
+ ## ok, ok, it's incomprehensible, search /dev/disk/by-id for a line that contains the
+ # discovered disk name AND ends with the correct identifier, sdx
+ # get rid of whitespace for some drive names and ids, and extra data after - in name
+ SCSI:
+ foreach my $ref (@scsi){
+ my %row = %$ref;
+ if ($row{'model'}){
+ $row{'model'} = (split /\s*-\s*/,$row{'model'})[0];
+ foreach my $id (@by_id){
+ if ($id =~ /$row{'model'}/ && "/dev/$drives[$i]{'id'}" eq Cwd::abs_path($id)){
+ $drives[$i]{'firmware'} = $row{'firmware'};
+ $drives[$i]{'model'} = $row{'model'};
+ $drives[$i]{'vendor'} = $row{'vendor'};
+ last SCSI;
+ }
+ }
+ }
+ }
+ }
+ # note: an entire class of model names gets truncated by /sys so that should be the last
+ # in priority re tests.
+ elsif ( (!@disk_data || !$disk_data[0] ) && $block_type){
# NOTE: while path ${working_path}vendor exists, it contains junk value, like: ATA
$path = "${working_path}model";
if ( -e $path){
$model = (main::reader($path,'strip'))[0];
if ($model){
- $model =~ s/\s/_/g;
- #@temp = split /-/, $model;
- #$drives[$i]{'model'} = $temp[0];
$drives[$i]{'model'} = $model;
}
}
elsif ($block_type eq 'mmc' && -e "${working_path}name"){
$path = "${working_path}name";
- if ( -e $path){
- $model = (main::reader($path,'strip'))[0];
- if ($model){
- $model =~ s/\s/_/g;
- #@temp = split /-/, $model;
- #$drives[$i]{'model'} = $temp[0];
- $drives[$i]{'model'} = $model;
- }
- }
- }
- elsif (@scsi && @by_id){
- ## ok, ok, it's incomprehensible, search /dev/disk/by-id for a line that contains the
- # discovered disk name AND ends with the correct identifier, sdx
- # get rid of whitespace for some drive names and ids, and extra data after - in name
- foreach my $ref (@scsi){
- my %row = %$ref;
- if ($row{'model'}){
- $row{'model'} =~ s/\s/_/g;
- $row{'model'} = (split /-/,$row{'model'})[0];
- foreach my $id (@by_id){
- if ($id =~ /$row{'model'}/ && "/dev/$drives[$i]{'id'}" eq Cwd::abs_path($id)){
- $drives[$i]{'firmware'} = $row{'firmware'};
- $drives[$i]{'model'} = $row{'model'};
- $drives[$i]{'vendor'} = $row{'vendor'};
- last;
- }
- }
- }
+ $model = (main::reader($path,'strip'))[0];
+ if ($model){
+ $drives[$i]{'model'} = $model;
}
}
+ }
+ if (!$drives[$i]{'model'} && @disk_data){
+ $drives[$i]{'model'} = $disk_data[0] if $disk_data[0];
+ $drives[$i]{'vendor'} = $disk_data[1] if $disk_data[1];
+ }
+ # maybe rework logic if find good scsi data example, but for now use this
+ elsif ($drives[$i]{'model'} && !$drives[$i]{'vendor'}) {
+ $drives[$i]{'model'} = main::disk_cleaner($drives[$i]{'model'});
+ my @device_data = device_vendor($drives[$i]{'model'},'');
+ $drives[$i]{'model'} = $device_data[1] if $device_data[1];
+ $drives[$i]{'vendor'} = $device_data[0] if $device_data[0];
+ }
+ if ($working_path){
$path = "${working_path}removable";
- if (-e $path){
- my $b_removable = (main::reader($path,'strip'))[0]; # 0/1 value
- $drives[$i]{'type'} = 'Removable' if $b_removable;
- }
+ $drives[$i]{'type'} = 'Removable' if -e $path && (main::reader($path,'strip'))[0]; # 0/1 value
}
my $peripheral = peripheral_data($drives[$i]{'id'});
# note: we only want to update type if we found a peripheral, otherwise preserve value
@@ -7349,24 +7465,24 @@ sub proc_data_advanced {
if ($extra > 0){
$drives[$i]{'temp'} = hdd_temp("/dev/$drives[$i]{'id'}");
if ($extra > 1){
- $path = "${working_path}serial";
- if ( -e $path){
- $serial = (main::reader($path,'strip'))[0];
- if ($serial){
- $drives[$i]{'serial'} = $serial;
- }
+ if (@disk_data && $disk_data[2]){
+ $drives[$i]{'serial'} = $disk_data[2];
}
else {
- $drives[$i]{'serial'} = disk_serial_by_id("/dev/$drives[$i]{'id'}");
- }
- if ($extra > 2){
- $path = "${working_path}rev";
+ $path = "${working_path}serial";
if ( -e $path){
- $drives[$i]{'firmware'} = (main::reader($path,'strip'))[0];
+ $serial = (main::reader($path,'strip'))[0];
+ $drives[$i]{'serial'} = $serial if $serial;
}
- $path = "${working_path}fwrev";
- if ( !$drives[$i]{'firmware'} && -e $path){
- $drives[$i]{'firmware'} = (main::reader($path,'strip'))[0];
+ }
+ if ($extra > 2 && !$drives[$i]{'firmware'} ){
+ my @fm = ('rev','fmrev','firmware_rev'); # 0 ~ default; 1 ~ mmc; 2 ~ nvme
+ foreach my $firmware (@fm){
+ $path = "${working_path}$firmware";
+ if ( -e $path){
+ $drives[$i]{'firmware'} = (main::reader($path,'strip'))[0];
+ last;
+ }
}
}
}
@@ -7442,6 +7558,10 @@ sub dmesg_boot_data {
$drives[$i]{'speed'} =~ s/\.[0-9]+// if $drives[$i]{'speed'};
}
}
+ $drives[$i]{'model'} = main::disk_cleaner($drives[$i]{'model'});
+ my @device_data = device_vendor($drives[$i]{'model'},'');
+ $drives[$i]{'vendor'} = $device_data[0] if $device_data[0];
+ $drives[$i]{'model'} = $device_data[1] if $device_data[1];
}
if (!$size){
$size = main::row_defaults('data-bsd');
@@ -7450,7 +7570,7 @@ sub dmesg_boot_data {
elsif ( $file && ! -r $file ){
$size = main::row_defaults('dmesg-boot-permissions');
}
- elsif (! -f $file ){
+ elsif (!$file ){
$size = main::row_defaults('dmesg-boot-missing');
}
@data = ({
@@ -7552,7 +7672,7 @@ sub partition_scheme {
else {
$return[1] = main::awk(\@data,'^(UDISKS_PARTITION_TABLE_SCHEME|ID_PART_TABLE_TYPE)',2,'=');
}
- $return[1] = 'mbr' if $return[1] eq 'dos';
+ $return[1] = 'mbr' if $return[1] && $return[1] eq 'dos';
}
eval $end if $b_log;
return @return;
@@ -7587,22 +7707,145 @@ sub scsi_data {
eval $end if $b_log;
return @scsi;
}
-
-sub disk_serial_by_id {
+# @b_id has already been cleaned of partitions, wwn-, nvme-eui
+sub disk_data_by_id {
eval $start if $b_log;
my ($device) = @_;
- my ($serial) = ('');
+ my ($model,$serial,$vendor) = ('','','');
+ my (@disk_data);
foreach (@by_id){
if ($device eq Cwd::abs_path($_)){
my @data = split /_/, $_;
- $serial = $data[-1];
+ my @device_data = ();
+ last if scalar @data < 2; # scsi-3600508e000000000876995df43efa500
+ $serial = pop @data if @data;
+ # usb-PNY_USB_3.0_FD_3715202280-0:0
$serial =~ s/-[0-9]+:[0-9]+$//;
- # print $device, ' ', Cwd::abs_path($_),' ', $serial,"\n";
+ $model = join ' ', @data;
+ # get rid of the ata-|nvme-|mmc- etc
+ $model =~ s/^\/dev\/disk\/by-id\/([^-]+-)?//;
+ $model = main::disk_cleaner($model);
+ @device_data = device_vendor($model,$serial);
+ $vendor = $device_data[0] if $device_data[0];
+ $model = $device_data[1] if $device_data[1];
+ # print $device, '::', Cwd::abs_path($_),'::', $model, '::', $vendor, '::', $serial, "\n";
+ (@disk_data) = ($model,$vendor,$serial);
last;
}
}
eval $end if $b_log;
- return $serial;
+ return @disk_data;
+}
+# receives space separated string that may or may not contain vendor data
+sub device_vendor {
+ eval $start if $b_log;
+ my ($model,$serial) = @_;
+ my ($vendor) = ('');
+ my (@data);
+ return if !$model;
+ # 0 - match pattern; 1 - replace pattern; 2 - vendor print; 3 - serial pattern
+ # https://elinux.org/RPi_SD_cards
+ # https://sd2snes.de/blog/card-list
+ # https://www.superbiiz.com # lists by real part numbers
+ my @vendors = (
+ ## These go first because they are the most likely and common ##
+ ['^INTEL','^INTEL','Intel',''],
+ # must come before samsung MU. NOTE: toshiba can have: TOSHIBA_MK6475GSX: mush: MKNSSDCR120GB_
+ ['^(MKN|Mushkin)','^Mushkin','Mushkin',''], # MKNS
+ # MU = Multiple_Flash_Reader too risky: |M[UZ][^L]
+ ['^(SAMSUNG|MCG[0-9]+GC)','^SAMSUNG','Samsung',''], # maybe ^SM
+ ['^(ST[^T]|[S]?SEAGATE|X[AFP])','^[S]?SEAGATE','Seagate',''], # real, SSEAGATE Backup+; XP1600HE30002
+ ['^WD','^(WDC|WD\s)','Western Digital',''],
+ ## Then better known ones ##
+ ['^(A-DATA|ADATA)','^(A-DATA|ADATA)','A-Data',''],
+ ['^ADTRON','^(ADTRON)','Adtron',''],
+ ['^ASUS','^ASUS','ASUS',''],
+ ['^ATP','^ATP[\s\-]','ATP',''],
+ ['^Corsair','^Corsair','Corsair',''],
+ ['(^Crucial|^CT|-CT|^M4-)','^Crucial','Crucial',''],
+ ['^(FUJITSU|MP)','^FUJITSU','Fujitsu',''],
+ # note: 2012: wdc bought hgst
+ ['^(Hitachi|HGST|IC|HT|HU)','^Hitachi','Hitachi',''], # HGST HUA
+ ['^(HP[\s\-])','^HP[\s\-]','HP',''], # vb: VB0250EAVER but clashes with vbox
+ ['^(KINGSTON|DataTraveler|SMS|SHS|SUV)','^KINGSTON','Kingston',''], # maybe SHS: SHSS37A SKC SUV
+ ['^(LSD|Lexar)','^Lexar','Lexar',''], # mmc-LEXAR_0xb016546c
+ # OCZSSD2-2VTXE120G is OCZ-VERTEX2_3.5
+ ['^(OCZ|APOC|D2|DEN|DEN|DRSAK|EC188|FTNC|GFGC|MANG|MMOC|NIMC|NIMR|PSIR|TALOS2|TMSC|TRSAK)','^OCZ[\s\-]','OCZ',''],
+ ['^OWC','^OWC[\s\-]','OWC',''],
+ ['^Philips','^Philips','Philips',''],
+ ['^PIONEER','^PIONEER','Pioneer',''],
+ ['^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_
+ ## These go last because they are short and could lead to false ID, or are unlikely ##
+ ['^Android','^Android','Android',''],
+ # must come before AP|Apacer
+ ['^APPLE','','^APPLE','Apple'],
+ ['^(AP|Apacer)','^Apacer','Apacer',''],
+ ['^BUFFALO','^BUFFALO','Buffalo',''],
+ ['^EXCELSTOR','^EXCELSTOR( TECHNOLOGY)?','Excelstor',''],
+ ['^Generic','^Generic','Generic',''],
+ ['^GOODRAM','^GOODRAM','GOODRAM',''],
+ # supertalent also has FM: |FM
+ ['^(G[\.]?SKILL)','^G[\.]?SKILL','G.SKILL',''],
+ ['^HUAWEI','^HUAWEI','Huawei',''],
+ ['^(IBM|DT)','^IBM','IBM',''],
+ ['^Imation','^Imation(\sImation)?','Imation',''], # Imation_ImationFlashDrive
+ ['^(InnoDisk|Innolite)','^InnoDisk( Corp.)?','InnoDisk',''],
+ ['^Innostor','^Innostor','Innostor',''],
+ ['^Intenso','^Intenso','Intenso',''],
+ ['^(LITE[\-]?ON[\s\-]?IT)','^LITE[\-]?ON[\s\-]?IT','LITE-ON IT',''], # LITEONIT_LSS-24L6G
+ ['^(LITE[\-]?ON|PH6)','^LITE[\-]?ON','LITE-ON',''], # PH6-CE240-L
+ ['^M-Systems','^M-Systems','M-Systems',''],
+ ['^MAXTOR','^MAXTOR','Maxtor',''],
+ ['^(MT|M5|Micron)','^Micron','Micron',''],
+ ['^MARVELL','^MARVELL','Marvell',''],
+ ['^Medion','^Medion','Medion',''],
+ ['^Motorola','^Motorola','Motorola',''],
+ ['^(PS[8F]|Patriot)','^Patriot','Patriot',''],
+ ['^PIX[\s]?JR','^PIX[\s]?JR','Disney',''],
+ ['^(PLEXTOR|PX-)','^PLEXTOR','Plextor',''],
+ ['(^Quantum|Fireball)','^Quantum','Quantum',''],
+ ['^R3','','AMD Radeon',''], # ssd
+ ['^RENICE','^RENICE','Renice',''],
+ ['^RIM[\s]','^RIM','RIM',''],
+ ['^SigmaTel','^SigmaTel','SigmaTel',''],
+ ['^SPPC','','Silicon Power',''],
+ ['^(SK HYNIX|SKHYNIX|HFS)','^(SK HYNIX|SKHYNIX)','SK Hynix',''], # HFS128G39TND-N210A
+ ['^SH','','Smart Modular Tech.',''],
+ ['^(SMART( Storage Systems)?|TX)','^(SMART( Storage Systems)?)','Smart Storage Systems',''],
+ ['^(S[FR]-|Sony)','^Sony','Sony',''],
+ ['^STE[CK]','^STE[CK]','sTec',''], # wd bought this one
+ ['^STORFLY','^STORFLY','StorFly',''],
+ # NOTE: F[MNETU] not reliable, g.skill starts with FM too:
+ # Seagate ST skips STT.
+ ['^(STT)','','Super Talent',''],
+ ['^(SF|Swissbit)','^Swissbit','Swissbit',''],
+ # ['^(SUPERSPEED)','^SUPERSPEED','SuperSpeed',''], # superspeed is a generic term
+ ['^TANDBERG','^TANDBERG','Tanberg',''],
+ ['^TEAC','^TEAC','TEAC',''],
+ ['^(TS|Transcend|JetFlash)','^Transcend','Transcend',''],
+ ['^TrekStor','^TrekStor','TrekStor',''],
+ ['^(UG|Unigen)','^Unigen','Unigen',''],
+ ['^VBOX','','VirtualBox',''],
+ ['^Verbatim','^Verbatim','Verbatim',''],
+ ['^VISIONTEK','^VISIONTEK','VisionTek',''],
+ ['^VMware','^VMware','VMware',''],
+ ['^(Vseky|Vaseky)','^Vaseky','Vaseky',''], # ata-Vseky_V880_350G_
+ );
+ foreach my $ref (@vendors){
+ my @row = @$ref;
+ 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]);
+ $model =~ s/^[\s\-_]+|[\s\-_]+$//g;
+ @data = ($vendor,$model);
+ last;
+ }
+ }
+ eval $end if $b_log;
+ return @data;
}
# Normally hddtemp requires root, but you can set user rights in /etc/sudoers.
# args: $1 - /dev/<disk> to be tested for
@@ -7611,12 +7854,6 @@ sub hdd_temp {
my ($device) = @_;
my ($path) = ('');
my (@data,$hdd_temp);
- if (!$b_sudo){
- $b_sudo = 1;
- if (!$b_root && ($path = main::check_program('sudo') )) {
- $sudo = "$path -n ";
- }
- }
if ($device =~ /nvme/i){
if (!$b_nvme){
$b_nvme = 1;
@@ -7869,11 +8106,12 @@ sub display_data(){
my @xrandr = main::grabber("$program $display_opt 2>/dev/null",'','strip');
foreach (@xrandr){
my @working = split /\s+/,$_;
- print join "$_\n";
+ # print join "$_\n";
if ($working[1] =~ /\*/){
$working[1] =~ s/\*|\+//g;
- $working[1] = sprintf("%0.0f",$working[1]);
- my $screen = "$working[0]~$working[1]Hz";
+ $working[1] = sprintf("%.0f",$working[1]);
+ $working[1] = ($working[1]) ? "$working[1]Hz" : 'N/A';
+ my $screen = "$working[0]~$working[1]";
if ($graphics{'screens'}){
$graphics{'screens'} = ([@{$graphics{'screens'}},$screen]);
}
@@ -8280,7 +8518,14 @@ sub get {
eval $start if $b_log;
my (%arm_machine,@data,@rows,$key1,$val1,$which);
my $num = 0;
- if ($bsd_type || $b_dmidecode_force){
+ if ($bsd_type && @sysctl_machine && !$b_dmidecode_force ){
+ @data = machine_data_sysctl();
+ if (!@data && !$key1){
+ $key1 = 'Message';
+ $val1 = main::row_defaults('machine-data-force-dmidecode','');
+ }
+ }
+ elsif ($bsd_type || $b_dmidecode_force){
my $ref = $alerts{'dmidecode'};
if ( $$ref{'action'} ne 'use'){
$key1 = $$ref{'action'};
@@ -8312,7 +8557,7 @@ sub get {
}
if (!@data){
$key1 = 'Message';
- $val1 = main::row_defaults('machine-data-alt-33','');
+ $val1 = main::row_defaults('machine-data-force-dmidecode','');
}
}
# if error case, null data, whatever
@@ -8391,7 +8636,8 @@ sub create_output {
$chassis_type = $data{'chassis_type'};
}
if ($data{'chassis_version'}){
- $chassis_version = $data{'chassis_version'}
+ $chassis_version = $data{'chassis_version'};
+ $chassis_version =~ s/^v([0-9])/$1/i;
}
$chassis_serial = main::apply_filter($data{'chassis_serial'});
$chassis_vendor ||= '';
@@ -8418,14 +8664,16 @@ sub create_output {
$bios_vendor = ($data{'bios_vendor'}) ? main::cleaner($data{'bios_vendor'}) : 'N/A';
if ($data{'bios_version'}){
$bios_version = $data{'bios_version'};
+ $bios_version =~ s/^v([0-9])/$1/i;
if ($data{'bios_rev'}){
$bios_rev = $data{'bios_rev'};
}
- $bios_version ||= 'N/A';
}
+ $bios_version ||= 'N/A';
if ($data{'bios_date'}){
$bios_date = $data{'bios_date'};
}
+ $bios_date ||= 'N/A';
if ($extra > 1 && $data{'bios_romsize'}){
$bios_romsize = $data{'bios_romsize'};
}
@@ -8435,6 +8683,9 @@ sub create_output {
$rows[$j]{main::key($num++,'v')} = $mobo_version;
}
$rows[$j]{main::key($num++,'serial')} = $mobo_serial;
+ if ($extra > 2 && $data{'board_uuid'}){
+ $rows[$j]{main::key($num++,'uuid')} = $data{'board_uuid'};
+ }
$rows[$j]{main::key($num++,$firmware)} = $bios_vendor;
$rows[$j]{main::key($num++,'v')} = $bios_version;
if ($bios_rev){
@@ -8510,6 +8761,9 @@ sub machine_data_sys {
$data{$_} = (main::reader($path))[0];
$data{$_} = ($data{$_}) ? main::dmi_cleaner($data{$_}) : '';
}
+ elsif (!$b_root && -e $path && !-r $path ){
+ $data{$_} = main::row_defaults('root-required');
+ }
else {
$data{$_} = '';
}
@@ -8580,7 +8834,7 @@ sub machine_data_arm {
# product_serial:
# product_uuid:
# product_version:
-# sys_uuid: dmi only
+# sys_uuid: dmi/sysctl only
# sys_vendor:
sub machine_data_dmi {
eval $start if $b_log;
@@ -8686,6 +8940,53 @@ sub machine_data_dmi {
eval $end if $b_log;
return @rows;
}
+# As far as I know, only OpenBSD supports this method.
+# it uses hw. info from sysctl -a and bios info from dmesg.boot
+sub machine_data_sysctl {
+ eval $start if $b_log;
+ my (%data,$vm);
+ # ^hw\.(vendor|product|version|serialno|uuid)
+ foreach (@sysctl_machine){
+ next if ! $_;
+ my @item = split /:/, $_;
+ next if ! $item[1];
+ if ($item[0] eq 'hw.vendor'){
+ $data{'board_vendor'} = main::dmi_cleaner($item[1]);
+ }
+ elsif ($item[0] eq 'hw.product'){
+ $data{'board_name'} = main::dmi_cleaner($item[1]);
+ }
+ elsif ($item[0] eq 'hw.version'){
+ $data{'board_version'} = $item[1];
+ }
+ elsif ($item[0] eq 'hw.serialno'){
+ $data{'board_serial'} = $item[1];
+ }
+ elsif ($item[0] eq 'hw.serial'){
+ $data{'board_serial'} = $item[1];
+ }
+ elsif ($item[0] eq 'hw.uuid'){
+ $data{'board_uuid'} = $item[1];
+ }
+ # bios0:at mainbus0: AT/286+ BIOS, date 06/30/06, BIOS32 rev. 0 @ 0xf2030, SMBIOS rev. 2.4 @ 0xf0000 (47 entries)
+ # bios0:vendor Phoenix Technologies, LTD version "3.00" date 06/30/2006
+ elsif ($item[0] =~ /^bios[0-9]/){
+ if ($_ =~ /^^bios[0-9]:at\s.*\srev\.\s([\S]+)\s@.*/){
+ $data{'bios_rev'} = $1;
+ $data{'firmware'} = 'BIOS' if $_ =~ /BIOS/;
+ }
+ elsif ($item[1] =~ /^vendor\s(.*)\sversion\s"?([\S]+)"?\sdate\s([\S]+)/ ){
+ $data{'bios_vendor'} = $1;
+ $data{'bios_version'} = $2;
+ $data{'bios_date'} = $3;
+ $data{'bios_version'} =~ s/^v//i if $data{'bios_version'} && $data{'bios_version'} !~ /vi/i;
+ }
+ }
+ }
+ my @rows = create_output(\%data);
+ eval $end if $b_log;
+ return @rows;
+}
sub get_device_sys {
eval $start if $b_log;
@@ -9373,7 +9674,7 @@ sub get {
if ( $file && ! -r $file ){
$val1 = main::row_defaults('dmesg-boot-permissions');
}
- elsif (! -e $file){
+ elsif (!$file){
$val1 = main::row_defaults('dmesg-boot-missing');
}
else {
@@ -9750,16 +10051,7 @@ sub create_output {
else {
$dev_type = 'dev';
}
- %part = check_lsblk($row{'dev-base'},0) if (@lsblk && $row{'dev-base'} && $dev_type eq 'dev');
- if (%part && $part{'fs'}){
- $fs = lc($part{'fs'});
- }
- elsif ($row{'fs'}){
- $fs = lc($row{'fs'});
- }
- else {
- $fs = 'N/A';
- }
+ $fs = ($row{'fs'}) ? lc($row{'fs'}): 'N/A';
$dev ||= 'N/A';
$j = scalar @rows;
@data = ({
@@ -9784,14 +10076,14 @@ sub create_output {
sub partition_data {
eval $start if $b_log;
#return if $bsd_type && $bsd_type eq 'darwin'; # darwin has muated output, of course
- my (@data,@rows,@mapper,@mount,@partitions_working);
+ my (@data,@rows,@mapper,@mount,@partitions_working,%part);
my ($b_fake_map,$b_fs,$b_load,$cols,$roots) = (0,1,0,6,0);
my ($back_size,$back_used) = (4,3);
my ($dev_base,$fs,$id,$label,$percent_used,$size,$type,$uuid,$used);
$b_partitions = 1;
set_lsblk() if !$bsd_type && !$b_lsblk;
# set labels, uuid, gpart
- main::get_partition_extra_data() if !$b_partition_extra;
+ set_label_uuid() if !$b_label_uuid;
# most current OS support -T and -k, but -P means different things
# in freebsd. However since most use is from linux, we make that default
if (!$bsd_type){
@@ -9847,6 +10139,7 @@ sub partition_data {
$label = '';
$size = 0;
$used = 0;
+ %part = ();
$percent_used = 0;
$type = '';
$uuid = '';
@@ -9867,6 +10160,7 @@ sub partition_data {
}
$dev_base = $row[0];
$dev_base =~ s/^\/dev\///;
+ %part = check_lsblk($dev_base,0) if @lsblk;
}
# this handles zfs type devices/partitions, which do not start with / but contain /
# note: Main/jails/transmission_1 path can be > 1 deep
@@ -9886,20 +10180,35 @@ sub partition_data {
$type = 'secondary';
}
if ($b_load){
- if ($show{'label'} && @labels){
- $label = get_label($row[0]);
- }
- if ($show{'uuid'} && @uuids){
- $uuid = get_uuid($row[0]);
+ if (!$bsd_type){
+ $fs = (%part && $part{'fs'}) ? $part{'fs'} : $row[1];
+ if ($show{'label'}) {
+ if (%part && $part{'label'}) {
+ $label = $part{'label'};
+ }
+ elsif ( @labels){
+ $label = get_label($row[0]);
+ }
+ }
+ if ($show{'uuid'}) {
+ if (%part && $part{'uuid'}) {
+ $uuid = $part{'uuid'};
+ }
+ elsif ( @uuids){
+ $uuid = get_uuid($row[0]);
+ }
+ }
}
- if ($bsd_type && @gpart && ($show{'label'} || $show{'uuid'} ) ){
- my @extra = get_bsd_label_uuid("$dev_base");
- if (@extra){
- $label = $extra[0];
- $uuid = $extra[1];
+ else {
+ $fs = ($b_fs) ? $row[1]: get_bsd_fs($row[0],@mount);
+ if (@gpart && ($show{'label'} || $show{'uuid'} ) ){
+ my @extra = get_bsd_label_uuid("$dev_base");
+ if (@extra){
+ $label = $extra[0];
+ $uuid = $extra[1];
+ }
}
}
- $fs = ($b_fs) ? $row[1]: get_bsd_fs($row[0],@mount);
$id = join ' ', @row[$cols .. $#row];
$id =~ s/\/home\/[^\/]+\/(.*)/\/home\/$filter_string\/$1/ if $show{'filter'};
$size = $row[$cols - $back_size];
@@ -9998,7 +10307,7 @@ sub get_bsd_fs {
# linux: /dev/sdb6 on /var/www/m type ext4 (rw,relatime,data=ordered)
# bsd: /dev/ada0s1a on / (ufs, local, soft-updates)
foreach (@mount){
- if ($_ =~ /^$item\son.*\(([^,\s]+)[,\s].*/){
+ if ($_ =~ /^$item\son.*\(([^,\s\)]+)[,\s]*.*\)/){
$fs = $1;
last;
}
@@ -10038,21 +10347,46 @@ sub get_bsd_label_uuid {
eval $end if $b_log;
return @data;
}
+sub set_label_uuid {
+ eval $start if $b_log;
+ $b_label_uuid = 1;
+ if ( $show{'unmounted'} || $show{'label'} || $show{'uuid'} ){
+ if (!$bsd_type){
+ if (-d '/dev/disk/by-label'){
+ @labels = main::globber('/dev/disk/by-label/*');
+ }
+ if (-d '/dev/disk/by-uuid'){
+ @uuids = main::globber('/dev/disk/by-uuid/*');
+ }
+ }
+ else {
+ if ( my $path = main::check_program('gpart')){
+ @gpart = main::grabber("$path list 2>/dev/null",'strip');
+ }
+ }
+ }
+ eval $end if $b_log;
+}
sub set_lsblk {
eval $start if $b_log;
$b_lsblk = 1;
my (@temp,@working);
if (my $program = main::check_program('lsblk')){
- @working = main::grabber("$program -bP --output NAME,TYPE,RM,FSTYPE,SIZE,LABEL,UUID,MOUNTPOINT 2>/dev/null");
+ @working = main::grabber("$program -bP --output NAME,TYPE,RM,FSTYPE,SIZE,LABEL,UUID,SERIAL,MOUNTPOINT 2>/dev/null");
foreach (@working){
- my ($name,$type,$rm,$fstype,$size) = ('','','','','');
- if (/NAME="([^"]*)"\s+TYPE="([^"]*)"\s+RM="([^"]*)"\s+FSTYPE="([^"]*)"\s+SIZE="([^"]*)"/){
+ if (/NAME="([^"]*)"\s+TYPE="([^"]*)"\s+RM="([^"]*)"\s+FSTYPE="([^"]*)"\s+SIZE="([^"]*)"\s+LABEL="([^"]*)"\s+UUID="([^"]*)"\s+SERIAL="([^"]*)"\s+MOUNTPOINT="([^"]*)"/){
+ my $size = ($5) ? $5/1024: 0;
+ # some versions of lsblk do not return serial, fs, uuid, or label
my @temp = ({
'name' => $1,
'type' => $2,
'rm' => $3,
'fs' => $4,
- 'size' => $5
+ 'size' => $size,
+ 'label' => $6,
+ 'uuid' => $7,
+ 'serial' => $8,
+ 'mount' => $9,
});
@lsblk = (@lsblk,@temp);
}
@@ -10070,12 +10404,11 @@ sub check_lsblk {
my %row = %$ref;
next if ! $row{'name'};
if ($name eq $row{'name'}){
- $part{'fs'} = $row{'fs'};
- $part{'size'} = $row{'size'}/ 1024 if $b_size && $row{'size'};
- $part{'rm'} = $row{'rm'} if $row{'rm'};
+ %part = %row;
last;
}
}
+ # print Data::Dumper::Dumper \%part;
main::log_data('dump','%part',\%part) if $b_log;
eval $end if $b_log;
return %part;
@@ -11866,6 +12199,7 @@ sub get_repos_bsd {
my $freebsd_pkg = '/etc/pkg/FreeBSD.conf';
my $netbsd = '/usr/pkg/etc/pkgin/repositories.conf';
my $openbsd = '/etc/pkg.conf';
+ my $openbsd2 = '/etc/installurl';
my $portsnap = '/etc/portsnap.conf';
if ( -f $portsnap || -f $freebsd || -d $bsd_pkg){
if ( -f $portsnap ) {
@@ -11928,9 +12262,15 @@ sub get_repos_bsd {
}
}
}
- elsif (-f $openbsd) {
- @data = repo_builder($openbsd,'openbsd','^installpath','\s*=\s*',1);
- @rows = (@rows,@data);
+ elsif (-f $openbsd || -f $openbsd2) {
+ if (-f $openbsd){
+ @data = repo_builder($openbsd,'openbsd','^installpath','\s*=\s*',1);
+ @rows = (@rows,@data);
+ }
+ if (-f $openbsd2){
+ @data = repo_builder($openbsd2,'openbsd','^(http|ftp)','',1);
+ @rows = (@rows,@data);
+ }
}
elsif (-f $netbsd){
# not an empty row, and not a row starting with #
@@ -12191,8 +12531,8 @@ sub create_output {
$rows[$j]{main::key($num++,'sodimm')} = $fan_main[$i];
}
elsif ($i > 4){
- $fan_number = $i - 3;
- $rows[$j]{main::key($num++,"sys-$fan_number")} = $fan_main[$i];
+ $fan_number = $i - 4;
+ $rows[$j]{main::key($num++,"case-$fan_number")} = $fan_main[$i];
}
}
}
@@ -12229,20 +12569,21 @@ sub create_output {
}
}
}
- if ($extra > 0 && $source eq 'ipmi'){
+ if ($extra > 0 && ($source eq 'ipmi' ||
+ ($sensors{'volts-12'} || $sensors{'volts-5'} || $sensors{'volts-3.3'} || $sensors{'volts-vbat'}))){
$j = scalar @rows;
$sensors{'volts-12'} ||= 'N/A';
$sensors{'volts-5'} ||= 'N/A';
$sensors{'volts-3.3'} ||= 'N/A';
- $sensors{'volts-dimm-p1'} ||= 'N/A';
- $sensors{'volts-dimm-p2'} ||= 'N/A';
$sensors{'volts-vbat'} ||= 'N/A';
$rows[$j]{main::key($num++,'Voltages')} = $data_source;
$rows[$j]{main::key($num++,'12v')} = $sensors{'volts-12'};
$rows[$j]{main::key($num++,'5v')} = $sensors{'volts-5'};
$rows[$j]{main::key($num++,'3.3v')} = $sensors{'volts-3.3'};
$rows[$j]{main::key($num++,'vbat')} = $sensors{'volts-vbat'};
- if ($extra > 1){
+ if ($extra > 1 && $source eq 'ipmi' ){
+ $sensors{'volts-dimm-p1'} ||= 'N/A';
+ $sensors{'volts-dimm-p2'} ||= 'N/A';
$rows[$j]{main::key($num++,'dimm-p1')} = $sensors{'volts-dimm-p1'} if $sensors{'volts-dimm-p1'};
$rows[$j]{main::key($num++,'dimm-p2')} = $sensors{'volts-dimm-p2'} if $sensors{'volts-dimm-p2'};
$rows[$j]{main::key($num++,'soc-p1')} = $sensors{'volts-soc-p1'} if $sensors{'volts-soc-p1'};
@@ -12299,7 +12640,7 @@ sub ipmi_data {
$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
- if ($row[$i_key] =~ /^Temp 1$/i) {
+ elsif ($row[$i_key] =~ /^Temp 1$/i) {
$temp_working = int($row[$i_value]);
$working_unit = $row[$i_unit];
$working_unit =~ s/degrees\s// if $b_ipmitool;
@@ -12308,7 +12649,7 @@ sub ipmi_data {
}
$sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
}
- if ($row[$i_key] =~ /^Temp 2$/i) {
+ elsif ($row[$i_key] =~ /^Temp 2$/i) {
$temp_working = int($row[$i_value]);
$working_unit = $row[$i_unit];
$working_unit =~ s/degrees\s// if $b_ipmitool;
@@ -12318,7 +12659,7 @@ sub ipmi_data {
$sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
}
# temp3 is only used as an absolute override for systems with all 3 present
- if ($row[$i_key] =~ /^Temp 3$/i) {
+ elsif ($row[$i_key] =~ /^Temp 3$/i) {
$temp_working = int($row[$i_value]);
$working_unit = $row[$i_unit];
$working_unit =~ s/degrees\s// if $b_ipmitool;
@@ -12328,14 +12669,14 @@ sub ipmi_data {
$sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
}
# note: can be cpu fan:, cpu fan speed:, etc.
- if ($row[$i_key] =~ /^(CPU|Processor)\sFan/i) {
+ elsif ($row[$i_key] =~ /^(CPU|Processor)\sFan/i) {
$sensors{'fan-main'} = () if !$sensors{'fan-main'};
$sensors{'fan-main'}[1] = int($row[$i_value]);
}
# note that the counters are dynamically set for fan numbers here
# otherwise you could overwrite eg aux fan2 with case fan2 in theory
# note: cpu/mobo/ps are 1/2/3
- if ($row[$i_key] =~ /^FAN([0-9A-F]+)/i) {
+ elsif ($row[$i_key] =~ /^FAN([0-9A-F]+)/i) {
$sys_fan_nu = hex($1);
next if $row[$i_value] !~ /^[0-9\.]+$/;
$fan_working = int($row[$i_value]);
@@ -12396,6 +12737,7 @@ sub sensors_data {
#my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sensors/amdgpu-w-fan-speed-stretch-k10.txt";
#my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sensors/peci-tin-geggo.txt";
#my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sensors/sensors-w-other-biker.txt";
+ #my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sensors/sensors-asus-chassis-1.txt";
#@sensors_data = main::reader($file);
@sensors_data = main::grabber(main::check_program('sensors') . " 2>/dev/null");
#print @sensors_data;
@@ -12424,7 +12766,7 @@ sub sensors_data {
# note that because of charset issues, no "°" degree sign used, but it is required
# in testing regex to avoid error. It might be because I got that data from a forum post,
# note directly via debugger.
- if (/^(AMBIENT|M\/B|MB|SIO|SYS).*:([0-9\.]+)[\s°]*(C|F)/i) {
+ if ($_ =~ /^(AMBIENT|M\/B|MB|SIO|SYS).*:([0-9\.]+)[\s°]*(C|F)/i) {
$sensors{'mobo-temp'} = $2;
$working_unit = $3;
$sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
@@ -12436,29 +12778,29 @@ 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
- if (/^CPU.*:([0-9\.]+)[\s°]*(C|F)/i) {
+ elsif (!$sensors{'cpu-temp'} && $_ =~ /^CPU.*:([0-9\.]+)[\s°]*(C|F)/i) {
$sensors{'cpu-temp'} = $1;
$working_unit = $2;
$sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
}
- if (/^PECI\sAgent\s0.*:([0-9\.]+)[\s°]*(C|F)/i) {
+ elsif ($_ =~ /^PECI\sAgent\s0.*:([0-9\.]+)[\s°]*(C|F)/i) {
$sensors{'cpu-peci-temp'} = $1;
$working_unit = $2;
$sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
}
- if (/^(P\/S|Power).*:([0-9\.]+)[\s°]*(C|F)/i) {
+ elsif ($_ =~ /^(P\/S|Power).*:([0-9\.]+)[\s°]*(C|F)/i) {
$sensors{'psu-temp'} = $2;
$working_unit = $3;
$sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
}
- if (/^SODIMM.*:([0-9\.]+)[\s°]*(C|F)/i) {
+ elsif ($_ =~ /^SODIMM.*:([0-9\.]+)[\s°]*(C|F)/i) {
$sensors{'sodimm-temp'} = $1;
$working_unit = $2;
$sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
}
# for temp1/2 only use temp1/2 if they are null or greater than the last ones
- if (/^temp1:([0-9\.]+)[\s°]*(C|F)/i) {
+ elsif ($_ =~ /^temp1:([0-9\.]+)[\s°]*(C|F)/i) {
$temp_working = $1;
$working_unit = $2;
if ( !$sensors{'temp1'} || ( defined $temp_working && $temp_working > 0 ) ) {
@@ -12466,7 +12808,7 @@ sub sensors_data {
}
$sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
}
- if (/^temp2:([0-9\.]+)[\s°]*(C|F)/i) {
+ elsif ($_ =~ /^temp2:([0-9\.]+)[\s°]*(C|F)/i) {
$temp_working = $1;
$working_unit = $2;
if ( !$sensors{'temp2'} || ( defined $temp_working && $temp_working > 0 ) ) {
@@ -12475,7 +12817,7 @@ sub sensors_data {
$sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
}
# temp3 is only used as an absolute override for systems with all 3 present
- if (/^temp3:([0-9\.]+)[\s°]*(C|F)/i) {
+ elsif ($_ =~ /^temp3:([0-9\.]+)[\s°]*(C|F)/i) {
$temp_working = $1;
$working_unit = $2;
if ( !$sensors{'temp3'} || ( defined $temp_working && $temp_working > 0 ) ) {
@@ -12485,7 +12827,7 @@ sub sensors_data {
}
# final fallback if all else fails, funtoo user showed sensors putting
# temp on wrapped second line, not handled
- if (/^(core0|core 0|Physical id 0)(.*):([0-9\.]+)[\s°]*(C|F)/i) {
+ 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 ) ) {
@@ -12494,54 +12836,42 @@ sub sensors_data {
$sensors{'temp-unit'} = set_temp_unit($sensors{'temp-unit'},$working_unit) if $working_unit;
}
# note: can be cpu fan:, cpu fan speed:, etc.
- if (/^(CPU|Processor).*:([0-9]+)[\s]RPM/i) {
+ elsif (!$sensors{'fan-main'}[1] && $_ =~ /^(CPU|Processor).*:([0-9]+)[\s]RPM/i) {
$sensors{'fan-main'} = () if !$sensors{'fan-main'};
$sensors{'fan-main'}[1] = $2;
}
- if (/^(M\/B|MB|SYS).*:([0-9]+)[\s]RPM/i) {
+ elsif (!$sensors{'fan-main'}[2] && $_ =~ /^(M\/B|MB|SYS).*:([0-9]+)[\s]RPM/i) {
$sensors{'fan-main'} = () if !$sensors{'fan-main'};
$sensors{'fan-main'}[2] = $2;
}
- if (/(Power|P\/S|POWER).*:([0-9]+)[\s]RPM/i) {
+ elsif (!$sensors{'fan-main'}[3] && $_ =~ /(Power|P\/S|POWER).*:([0-9]+)[\s]RPM/i) {
$sensors{'fan-main'} = () if !$sensors{'fan-main'};
$sensors{'fan-main'}[3] = $2;
}
- if (/(SODIMM).*:([0-9]+)[\s]RPM/i) {
+ elsif (!$sensors{'fan-main'}[4] && $_ =~ /(SODIMM).*:([0-9]+)[\s]RPM/i) {
$sensors{'fan-main'} = () if !$sensors{'fan-main'};
$sensors{'fan-main'}[4] = $2;
}
# note that the counters are dynamically set for fan numbers here
# otherwise you could overwrite eg aux fan2 with case fan2 in theory
- # note: cpu/mobo/ps are 1/2/3
- if (/^(AUX[1]? |CASE[1]? |CHASSIS[1]? ).*:([0-9]+)[\s]RPM/i) {
- $temp_working = $2;
- $sensors{'fan-main'} = () if !$sensors{'fan-main'};
- for ( my $i = 5; $i < 7; $i++ ){
- next if defined $sensors{'fan-main'}[$i];
- if ( !defined $sensors{'fan-main'}[$i] ){
- $sensors{'fan-main'}[$i] = $temp_working;
- last;
- }
- }
- }
- if (/^(AUX[2-9] |CASE[2-9] |CHASSIS[2-9] ).*:([0-9]+)[\s]RPM/i) {
+ # note: cpu/mobo/ps/sodimm are 1/2/3/4
+ elsif ($_ =~ /^(AUX|CASE|CHASSIS).*:([0-9]+)[\s]RPM/i) {
$temp_working = $2;
$sensors{'fan-main'} = () if !$sensors{'fan-main'};
for ( my $i = 5; $i < 30; $i++ ){
next if defined $sensors{'fan-main'}[$i];
if ( !defined $sensors{'fan-main'}[$i] ){
- $sys_fan_nu = $i;
$sensors{'fan-main'}[$i] = $temp_working;
last;
}
}
}
# in rare cases syntax is like: fan1: xxx RPM
- if (/^FAN(1)?:([0-9]+)[\s]RPM/i) {
+ elsif ($_ =~ /^FAN(1)?:([0-9]+)[\s]RPM/i) {
$sensors{'fan-default'} = () if !$sensors{'fan-default'};
$sensors{'fan-default'}[1] = $2;
}
- if (/^FAN([2-9]|1[0-9]).*:([0-9]+)[\s]RPM/i) {
+ elsif ($_ =~ /^FAN([2-9]|1[0-9]).*:([0-9]+)[\s]RPM/i) {
$fan_working = $2;
$sys_fan_nu = $1;
$sensors{'fan-default'} = () if !$sensors{'fan-default'};
@@ -12557,6 +12887,21 @@ sub sensors_data {
}
}
}
+ if ($extra > 0){
+ if ($_ =~ /^[+]?(12 Volt|12V).*:([0-9\.]+)\sV/i) {
+ $sensors{'volts-12'} = $2;
+ }
+ # note: 5VSB is a field name
+ elsif ($_ =~ /^[+]?(5 Volt|5V):([0-9\.]+)\sV/i) {
+ $sensors{'volts-5'} = $2;
+ }
+ elsif ($_ =~ /^[+]?(3\.3 Volt|3\.3V).*:([0-9\.]+)\sV/i) {
+ $sensors{'volts-3.3'} = $2;
+ }
+ elsif ($_ =~ /^(Vbat).*:([0-9\.]+)\sV/i) {
+ $sensors{'volts-vbat'} = $2;
+ }
+ }
}
# print Data::Dumper::Dumper \%sensors;
%sensors = data_processor(%sensors) if %sensors;
@@ -12794,7 +13139,8 @@ sub data_processor {
$cpu3_temp = $sensors{'cpu3-temp'} if $sensors{'cpu3-temp'};
$cpu4_temp = $sensors{'cpu4-temp'} if $sensors{'cpu4-temp'};
# so far only for ipmi, sensors data is junk for volts
- if ($extra > 0 && $sensors{'volts-12'} ){
+ if ($extra > 0 &&
+ ($sensors{'volts-12'} || $sensors{'volts-5'} || $sensors{'volts-3.3'} || $sensors{'volts-vbat'}) ){
$v_12 = $sensors{'volts-12'} if $sensors{'volts-12'};
$v_5 = $sensors{'volts-5'} if $sensors{'volts-5'};
$v_3_3 = $sensors{'volts-3.3'} if $sensors{'volts-3.3'};
@@ -12821,7 +13167,7 @@ sub data_processor {
if ($sodimm_temp){
$sensors{'sodimm-temp'} = $sodimm_temp;
}
- if ($extra > 0 && ($v_12 || $v_5 || $v_3_3) ){
+ if ($extra > 0 && ($v_12 || $v_5 || $v_3_3 || $v_vbat) ){
$sensors{'volts-12'} = $v_12;
$sensors{'volts-5'} = $v_5;
$sensors{'volts-3.3'} = $v_3_3;
@@ -13123,7 +13469,7 @@ sub create_output {
sub unmounted_data {
eval $start if $b_log;
my ($file) = @_;
- my ($fs,$size,@data,%part,@unmounted);
+ my ($fs,$label,$size,$uuid,@data,%part,@unmounted);
my @mounted = ('scd[0-9]+','sr[0-9]+','cdrom[0-9]*','cdrw[0-9]*',
'dvd[0-9]*','dvdrw[0-9]*','fd[0-9]','ram[0-9]*');
my @mounts = main::reader($file,'strip');
@@ -13131,12 +13477,12 @@ sub unmounted_data {
PartitionData::set_lsblk() if !$bsd_type && !$b_lsblk;
# set labels, uuid, gpart
PartitionData::partition_data() if !$b_partitions;
- main::get_partition_extra_data() if !$b_partition_extra;
+ PartitionData::set_label_uuid() if !$b_label_uuid;
RaidData::raid_data() if !$b_raid;
@mounted = get_mounted(@mounted);
foreach (@mounts){
my @working = split /\s+/, $_;
- ($fs,$size) = ('','');
+ ($fs,$label,$uuid,$size) = ('','','','');
# note that size 1 means it is a logical extended partition container
# lvm might have dm-1 type syntax
# need to exclude loop type file systems, squashfs for example
@@ -13144,15 +13490,17 @@ sub unmounted_data {
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)){
- my $label = PartitionData::get_label("/dev/$working[-1]");
- my $uuid = PartitionData::get_uuid("/dev/$working[-1]");
- %part = PartitionData::check_lsblk($working[-1],0) if (@lsblk && $working[-1]);
+ %part = PartitionData::check_lsblk($working[-1],0) if (@lsblk && $working[-1]);
if (%part){
$fs = $part{'fs'};
+ $label = $part{'label'};
+ $uuid = $part{'uuid'};
$size = $part{'size'} if $part{'size'} && !$working[2];
}
$size ||= $working[2];
- $fs = unmounted_filesystem($working[-1]) if ! $fs;
+ $fs = unmounted_filesystem($working[-1]) if !$fs;
+ $label = PartitionData::get_label("/dev/$working[-1]") if !$label;
+ $uuid = PartitionData::get_uuid("/dev/$working[-1]") if !$uuid;
@data = ({
'dev-base' => $working[-1],
'fs' => $fs,
@@ -13178,6 +13526,8 @@ sub get_mounted {
foreach my $ref (@raid){
my %row = %$ref;
my $ref2 = $row{'arrays'};
+ # we want to not show md0 etc in unmounted report
+ push @mounted, $row{'id'} if $row{'id'};
my @arrays = (ref $ref2 eq 'ARRAY' ) ? @$ref2 : ();
@arrays = grep {defined $_} @arrays;
foreach my $array (@arrays){
@@ -13197,7 +13547,7 @@ sub unmounted_filesystem {
eval $start if $b_log;
my ($item) = @_;
my ($data,%part);
- my ($file,$fs,$path,$sudo) = ('','','','');
+ my ($file,$fs,$path) = ('','','');
if ($path = main::check_program('file')) {
$file = $path;
}
@@ -13207,13 +13557,6 @@ sub unmounted_filesystem {
'ffs','hammer','hfs\+','hfs\splus','hfs\sextended\sversion\s[1-9]','hfsj',
'hfs','jfs','nss','reiserfs','reiser4','ufs2','ufs','xfs','zfs');
if ($file){
- # only use sudo if not root, -n option requires sudo -V 1.7 or greater.
- # sudo will just error out which is the safest course here for now,
- # otherwise that interactive sudo password thing is too annoying
- # important: -n makes it non interactive, no prompt for password
- if (!$b_root && ($path = main::check_program('sudo') )) {
- $sudo = "$path -n ";
- }
# this will fail if regular user and no sudo present, but that's fine, it will just return null
# note the hack that simply slices out the first line if > 1 items found in string
# also, if grub/lilo is on partition boot sector, no file system data is available
@@ -13454,48 +13797,157 @@ sub create_output {
main::key($num++,'Message') => main::row_defaults('weather-null','weather data'),
});
}
- if ($weather{'temp'} && $weather{'weather'} ){
- $conditions = "$weather{'temp'} - $weather{'weather'}";
- }
- elsif ($weather{'temp'}){
- $conditions = $weather{'temp'};
- }
- elsif ($weather{'weather'}) {
- $conditions = $weather{'weather'};
- }
+ $conditions = "$weather{'weather'}";
+ my $temp = unit_output($weather{'temp'},$weather{'temp-c'},'C',$weather{'temp-f'},'F');
@data = ({
+ main::key($num++,'Temperature') => $temp,
main::key($num++,'Conditions') => $conditions,
},);
@rows = (@rows,@data);
if ($extra > 0){
- $rows[0]{main::key($num++,'Wind')} = $weather{'wind'};
+ my $pressure = unit_output($weather{'pressure'},$weather{'pressure-mb'},'mb',$weather{'pressure-in'},'in');
+ my $wind = wind_output($weather{'wind'},$weather{'wind-direction'},$weather{'wind-mph'},$weather{'wind-ms'},
+ $weather{'wind-gust-mph'},$weather{'wind-gust-ms'});
+ $rows[0]{main::key($num++,'Wind')} = $wind;
$rows[0]{main::key($num++,'Humidity')} = $weather{'humidity'};
- $rows[0]{main::key($num++,'Pressure')} = $weather{'pressure'};
+ $rows[0]{main::key($num++,'Pressure')} = $pressure;
}
if ($extra > 1){
if ($weather{'heat-index'}){
- $rows[0]{main::key($num++,'Heat Index')} = $weather{'heat-index'};
+ my $heat = unit_output($weather{'heat-index'},$weather{'heat-index-c'},'C',$weather{'heat-index-f'},'F');
+ $rows[0]{main::key($num++,'Heat Index')} = $heat;
}
if ($weather{'windchill'}){
- $rows[0]{main::key($num++,'Wind Chill')} = $weather{'windchill'};
+ my $chill = unit_output($weather{'windchill'},$weather{'windchill-c'},'C',$weather{'windchill-f'},'F');
+ $rows[0]{main::key($num++,'Wind Chill')} = $chill ;
}
if ($weather{'dewpoint'}){
- $rows[0]{main::key($num++,'Dew Point')} = $weather{'dewpoint'};
+ my $dew = unit_output($weather{'dewpoint'},$weather{'dewpoint-c'},'C',$weather{'dewpoint-f'},'F');
+ $rows[0]{main::key($num++,'Dew Point')} = $dew;
}
}
if ($extra > 2){
if (!$show{'filter'}){
$rows[0]{main::key($num++,'Location')} = $location[1];
- $rows[0]{main::key($num++,'altitude')} = $weather{'elevation'};
+ $rows[0]{main::key($num++,'altitude')} = elevation_output($weather{'elevation-m'},$weather{'elevation-ft'});
}
}
- $rows[0]{main::key($num++,'Time')} = $weather{'date-time'};
+ $rows[0]{main::key($num++,'Current Time')} = $weather{'date-time'};
if ($extra > 2){
$rows[0]{main::key($num++,'Observation Time')} = $weather{'observation-time-local'};
}
eval $end if $b_log;
return @rows;
}
+sub elevation_output {
+ eval $start if $b_log;
+ my ($meters,$feet) = @_;
+ my ($result,$i_unit,$m_unit) = ('','ft','m');
+ $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' ){
+ $result = "$meters $m_unit ($feet $i_unit)";
+ }
+ elsif (defined $meters && $weather_unit eq 'fc' ){
+ $result = "$feet $i_unit ($meters $m_unit)";
+ }
+ elsif (defined $meters && $weather_unit eq 'c' ){
+ $result = "$meters $m_unit";
+ }
+ elsif (defined $feet && $weather_unit eq 'f' ){
+ $result = "$feet $i_unit";
+ }
+ else {
+ $result = 'N/A';
+ }
+ eval $end if $b_log;
+ return $result;
+}
+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' ){
+ $result = "$metric $m_unit ($imperial $i_unit)";
+ }
+ elsif ($metric && $imperial && $weather_unit eq 'fc' ){
+ $result = "$imperial $i_unit ($metric $m_unit)";
+ }
+ elsif ($metric && $weather_unit eq 'c' ){
+ $result = "$metric $m_unit";
+ }
+ elsif ($imperial && $weather_unit eq 'f' ){
+ $result = "$imperial $i_unit";
+ }
+ elsif ($primary){
+ $result = $primary;
+ }
+ else {
+ $result = 'N/A';
+ }
+ eval $end if $b_log;
+ return $result;
+}
+sub wind_output {
+ eval $start if $b_log;
+ my ($primary,$direction,$mph,$ms,$gust_mph,$gust_ms) = @_;
+ my ($result,$gust_kmh,$kmh,$i_unit,$m_unit,$km_unit) = ('','','','mph','m/s','km/h');
+ # get rid of possible gust values if they are the same as wind values
+ $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
+ $mph = $ms * 2.23694 if $ms && !$mph;
+ $kmh = sprintf("%.0f", 18 * $ms / 5) if $ms;
+ $ms = sprintf("%.0f", $ms ) if $ms;
+ $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;
+ $gust_mph = $gust_ms * 2.23694 if $gust_ms && !$gust_mph;
+ $gust_mph = sprintf("%.0f", $gust_mph) if $gust_mph;
+ $gust_kmh = sprintf("%.0f", $gust_kmh) if $gust_kmh;
+ $gust_ms = sprintf("%.0f", $gust_ms ) if $gust_ms;
+ if (!$mph && $primary){
+ $result = $primary;
+ }
+ elsif ($mph && $direction ){
+ if ( $weather_unit eq 'cf' ){
+ $result = "from $direction at $ms $m_unit ($kmh $km_unit, $mph $i_unit)";
+ }
+ elsif ( $weather_unit eq 'fc' ){
+ $result = "from $direction at $mph $i_unit ($ms $m_unit, $kmh $km_unit)";
+ }
+ elsif ( $weather_unit eq 'c' ){
+ $result = "from $direction at $ms $m_unit ($kmh $km_unit)";
+ }
+ elsif ( $weather_unit eq 'f' ){
+ $result = "from $direction at $mph $i_unit";
+ }
+ if ($gust_mph){
+ if ( $weather_unit eq 'cf' ){
+ $result .= ". Gusting to $ms $m_unit ($kmh $km_unit, $mph $i_unit)";
+ }
+ elsif ( $weather_unit eq 'fc' ){
+ $result .= ". Gusting to $mph $i_unit ($ms $m_unit, $kmh $km_unit)";
+ }
+ elsif ( $weather_unit eq 'c' ){
+ $result .= ". Gusting to $ms $m_unit ($kmh $km_unit)";
+ }
+ elsif ( $weather_unit eq 'f' ){
+ $result .= ". Gusting to $mph $i_unit";
+ }
+ }
+ }
+ elsif ($primary){
+ $result = $primary;
+ }
+ else {
+ $result = 'N/A';
+ }
+ eval $end if $b_log;
+ return $result;
+}
sub get_weather {
eval $start if $b_log;
my (@location) = @_;
@@ -13510,7 +13962,8 @@ sub get_weather {
$freshness = (split /\^\^/, $weather_data[0])[1];
#print "$now:$freshness\n";
}
- if (!$freshness || $freshness < $now - 90) {
+ if (!$freshness || $freshness < ($now - 90) ) {
+ @weather_data = (); # reset so we don't write the previous data to file!!
my $url = "http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query=$location[0]";
my $temp;
# {
@@ -13540,53 +13993,127 @@ sub get_weather {
#print "$file_cached: download/cleaned\n";
}
#print join "\n", @weather_data, "\n";
-
+ # NOTE: because temps can be 0, we can't do if value tests
foreach (@weather_data){
my @working = split /\s*\^\^\s*/,$_;
- if ( $working[0] eq 'local_time' ){
+ next if ! defined $working[1] || $working[1] eq '';
+ if ( $working[0] eq 'dewpoint_string' ){
+ $weather{'dewpoint'} = $working[1];
+ $working[1] =~ /^([0-9\.]+)\sF\s\(([0-9\.]+)\sC\)/;
+ $weather{'dewpoint-c'} = $2;;
+ $weather{'dewpoint-f'} = $1;;
+ }
+ elsif ( $working[0] eq 'dewpoint_c' ){
+ $weather{'dewpoint-c'} = $working[1];
+ }
+ elsif ( $working[0] eq 'dewpoint_f' ){
+ $weather{'dewpoint-f'} = $working[1];
+ }
+ # there are two elevations, we want the first one
+ elsif (!$weather{'elevation-m'} && $working[0] eq 'elevation'){
+ # note: bug in source data uses ft for meters, not 100% of time, but usually
+ $weather{'elevation-m'} = $working[1];
+ $weather{'elevation-m'} =~ s/\s*(ft|m).*$//;
+ }
+ elsif ( $working[0] eq 'heat_index_string' ){
+ $weather{'heat-index'} = $working[1];
+ $working[1] =~ /^([0-9\.]+)\sF\s\(([0-9\.]+)\sC\)/;
+ $weather{'heat-index-c'} = $2;;
+ $weather{'heat-index-f'} = $1;
+ }
+ elsif ( $working[0] eq 'heat_index_c' ){
+ $weather{'heat-index-c'} = $working[1];
+ }
+ elsif ( $working[0] eq 'heat_index_f' ){
+ $weather{'heat-index-f'} = $working[1];
+ }
+ elsif ( $working[0] eq 'relative_humidity' ){
+ $weather{'humidity'} = $working[1];
+ }
+ elsif ( $working[0] eq 'local_time' ){
$weather{'local-time'} = $working[1];
}
- elsif ( $working[0] eq 'weather' ){
- $weather{'weather'} = $working[1];
+ elsif ( $working[0] eq 'local_epoch' ){
+ $weather{'local-epoch'} = $working[1];
+ }
+ elsif ( $working[0] eq 'observation_time_rfc822' ){
+ $weather{'observation-time-gmt'} = $working[1];
+ }
+ elsif ( $working[0] eq 'observation_epoch' ){
+ $weather{'observation-epoch'} = $working[1];
+ }
+ elsif ( $working[0] eq 'observation_time' ){
+ $weather{'observation-time-local'} = $working[1];
+ $weather{'observation-time-local'} =~ s/Last Updated on //;
+ }
+ elsif ( $working[0] eq 'pressure_string' ){
+ $weather{'pressure'} = $working[1];
+ }
+ elsif ( $working[0] eq 'pressure_mb' ){
+ $weather{'pressure-mb'} = $working[1];
+ }
+ elsif ( $working[0] eq 'pressure_in' ){
+ $weather{'pressure-in'} = $working[1];
}
elsif ( $working[0] eq 'temperature_string' ){
$weather{'temp'} = $working[1];
+ $working[1] =~ /^([0-9\.]+)\sF\s\(([0-9\.]+)\sC\)/;
+ $weather{'temp-c'} = $2;;
+ $weather{'temp-f'} = $1;
# $weather{'temp'} =~ s/\sF/\xB0 F/; # B0
# $weather{'temp'} =~ s/\sF/\x{2109}/;
# $weather{'temp'} =~ s/\sC/\x{2103}/;
}
- elsif ( $working[0] eq 'relative_humidity' ){
- $weather{'humidity'} = $working[1];
+ elsif ( $working[0] eq 'temp_f' ){
+ $weather{'temp-f'} = $working[1];
}
- elsif ( $working[0] eq 'wind_string' ){
- $weather{'wind'} = $working[1];
+ elsif ( $working[0] eq 'temp_c' ){
+ $weather{'temp-c'} = $working[1];
}
- elsif ( $working[0] eq 'pressure_string' ){
- $weather{'pressure'} = $working[1];
+ elsif ( $working[0] eq 'visibility' ){
+ $weather{'visibility'} = $working[1];
}
- elsif ( $working[0] eq 'heat_index_string' ){
- $weather{'heat-index'} = $working[1];
+ elsif ( $working[0] eq 'visibility_km' ){
+ $weather{'visibility-km'} = $working[1];
}
- elsif ( $working[0] eq 'windchill_string' ){
- $weather{'windchill'} = $working[1];
+ elsif ( $working[0] eq 'visibility_mi' ){
+ $weather{'visibility-mi'} = $working[1];
}
- elsif ( $working[0] eq 'dewpoint_string' ){
- $weather{'dewpoint'} = $working[1];
+ elsif ( $working[0] eq 'weather' ){
+ $weather{'weather'} = $working[1];
}
- elsif ( $working[0] eq 'observation_time_rfc822' ){
- $weather{'observation-time-gmt'} = $working[1];
+ elsif ( $working[0] eq 'wind_degrees' ){
+ $weather{'wind-degrees'} = $working[1];
}
- elsif ( $working[0] eq 'observation_time_rfc822' ){
- $weather{'observation-time-gmt'} = $working[1];
+ elsif ( $working[0] eq 'wind_dir' ){
+ $weather{'wind-direction'} = $working[1];
}
- elsif ( $working[0] eq 'observation_time' ){
- $weather{'observation-time-local'} = $working[1];
- $weather{'observation-time-local'} =~ s/Last Updated on //;
+ elsif ( $working[0] eq 'wind_mph' ){
+ $weather{'wind-mph'} = $working[1];
}
- elsif (!$weather{'elevation'} && $working[0] eq 'elevation'){
- # note: bug in source data uses ft for meters, not 100% of time, but usually
- $weather{'elevation'} = $working[1];
- $weather{'elevation'} =~ s/ft/m/;
+ elsif ( $working[0] eq 'wind_gust_mph' ){
+ $weather{'wind-gust-mph'} = $working[1];
+ }
+ elsif ( $working[0] eq 'wind_gust_ms' ){
+ $weather{'wind-gust-ms'} = $working[1];
+ }
+ elsif ( $working[0] eq 'wind_ms' ){
+ $weather{'wind-ms'} = $working[1];
+ }
+ elsif ( $working[0] eq 'wind_string' ){
+ $weather{'wind'} = $working[1];
+ }
+ elsif ( $working[0] eq 'windchill_string' ){
+ $weather{'windchill'} = $working[1];
+ $working[1] =~ /^([0-9\.]+)\sF\s\(([0-9\.]+)\sC\)/;
+ $weather{'windchill-c'} = $2;
+ $weather{'windchill-f'} = $1;
+ }
+ elsif ( $working[0] eq 'windchill_c' ){
+ $weather{'windchill-c'} = $working[1];
+ }
+ elsif ( $working[0] eq 'windchill_f' ){
+ $weather{'windchill_f'} = $working[1];
}
}
if ($show{'weather-location'}){
@@ -13603,6 +14130,10 @@ sub get_weather {
$tz = ( $location[2] ) ? " ($location[2])" : '';
$weather{'date-time'} = $date_time . $tz;
}
+ # we get the wrong time using epoch for remote -W location
+ if ( !$show{'weather-location'} && $weather{'observation-epoch'}){
+ $weather{'observation-time-local'} = POSIX::strftime "%c", localtime($weather{'observation-epoch'});
+ }
return %weather;
eval $end if $b_log;
}
@@ -13713,6 +14244,7 @@ sub get_compiler_version {
eval $end if $b_log;
return @compiler;
}
+
sub get_compiler_version_bsd {
eval $start if $b_log;
my (@compiler,@working);
@@ -13739,6 +14271,7 @@ sub get_compiler_version_bsd {
eval $end if $b_log;
return @compiler;
}
+
sub get_compiler_version_linux {
eval $start if $b_log;
my ($file) = @_;
@@ -14318,6 +14851,7 @@ sub get_display_manager {
eval $end if $b_log;
return join ',', @found if @found;
}
+
## Get DistroData
{
package DistroData;
@@ -14589,6 +15123,7 @@ sub get_os_release {
return $distro;
}
}
+
sub get_gcc_data {
eval $start if $b_log;
my ($gcc,@data,@gccs,@temp);
@@ -14618,6 +15153,7 @@ sub get_gcc_data {
eval $end if $b_log;
return @gccs;
}
+
sub get_hostname {
eval $start if $b_log;
my $hostname = '';
@@ -14640,6 +15176,7 @@ sub get_hostname {
eval $end if $b_log;
return $hostname;
}
+
sub get_init_data {
eval $start if $b_log;
my $runlevel = get_runlevel_data();
@@ -14725,6 +15262,7 @@ sub get_init_data {
eval $end if $b_log;
return %init;
}
+
sub get_kernel_data {
eval $start if $b_log;
my ($kernel,$ksplice) = ('','');
@@ -14745,6 +15283,7 @@ sub get_kernel_data {
eval $end if $b_log;
return $kernel;
}
+
sub get_kernel_bits {
eval $start if $b_log;
my $bits = '';
@@ -14756,6 +15295,7 @@ sub get_kernel_bits {
eval $end if $b_log;
return $bits;
}
+
sub get_memory_data {
eval $start if $b_log;
my ($type) = @_;
@@ -14769,6 +15309,7 @@ sub get_memory_data {
eval $end if $b_log;
return $memory;
}
+
sub get_memory_data_linux {
eval $start if $b_log;
my ($type,$file) = @_;
@@ -14797,6 +15338,7 @@ sub get_memory_data_linux {
eval $end if $b_log;
return $memory;
}
+
# openbsd/linux
# procs memory page disks traps cpu
# r b w avm fre flt re pi po fr sr wd0 wd1 int sys cs us sy id
@@ -14916,26 +15458,7 @@ sub get_module_version {
eval $end if $b_log;
return $version;
}
-sub get_partition_extra_data {
- eval $start if $b_log;
- $b_partition_extra = 1;
- if ( $show{'unmounted'} || $show{'label'} || $show{'uuid'} ){
- if (!$bsd_type){
- if (-d '/dev/disk/by-label'){
- @labels = main::globber('/dev/disk/by-label/*');
- }
- if (-d '/dev/disk/by-uuid'){
- @uuids = main::globber('/dev/disk/by-uuid/*');
- }
- }
- else {
- if ( my $path = main::check_program('gpart')){
- @gpart = main::grabber("$path list 2>/dev/null",'strip');
- }
- }
- }
- eval $end if $b_log;
-}
+
# # check? /var/run/nologin for bsds?
sub get_runlevel_data {
eval $start if $b_log;
@@ -14948,6 +15471,7 @@ sub get_runlevel_data {
eval $end if $b_log;
return $runlevel;
}
+
# note: it appears that at least as of 2014-01-13, /etc/inittab is going
# to be used for default runlevel in upstart/sysvinit. systemd default is
# not always set so check to see if it's linked.
@@ -14981,6 +15505,7 @@ sub get_runlevel_default {
eval $end if $b_log;
return $default;
}
+
sub get_self_version {
eval $start if $b_log;
my $patch = $self_patch;
@@ -14992,6 +15517,7 @@ sub get_self_version {
eval $end if $b_log;
return $self_version . $patch;
}
+
sub get_shell_data {
eval $start if $b_log;
my ($ppid) = @_;
@@ -15042,6 +15568,7 @@ sub get_shell_data {
$client{'su-start'} = 'sudo' if (!$client{'su-start'} && $ENV{'SUDO_USER'});
eval $end if $b_log;
}
+
sub get_shell_source {
eval $start if $b_log;
my (@data);
@@ -15096,6 +15623,7 @@ sub get_shell_source {
eval $end if $b_log;
return $shell_parent;
}
+
# utilities for get_shell_source
# arg: 1 - parent id
sub get_start_parent {
@@ -15110,6 +15638,7 @@ sub get_start_parent {
eval $end if $b_log;
return $self_parent;
}
+
# arg: 1 - parent id
sub get_shell_parent {
eval $start if $b_log;
@@ -15122,6 +15651,7 @@ sub get_shell_parent {
eval $end if $b_log;
return $shell_parent;
}
+
# this will test against default IP like: (:0) vs full IP to determine
# ssh status. Surprisingly easy test? Cross platform
sub get_ssh_status {
@@ -15151,6 +15681,7 @@ sub get_tty_console_irc {
eval $end if $b_log;
return $tty_session;
}
+
sub get_tty_number {
eval $start if $b_log;
my $tty = POSIX::ttyname(1);
@@ -15161,6 +15692,7 @@ sub get_tty_number {
eval $end if $b_log;
return $tty;
}
+
# 2:58PM up 437 days, 8:18, 3 users, load averages: 2.03, 1.72, 1.77
# 04:29:08 up 3:18, 3 users, load average: 0,00, 0,00, 0,00
# 10:23PM up 5 days, 16:17, 1 user, load averages: 0.85, 0.90, 1.00
@@ -15192,6 +15724,7 @@ sub get_uptime {
eval $end if $b_log;
return $uptime;
}
+
# NOTE: annoyingly, /sys does NOT actually use the id, it uses
# the count of physical devices, starting at 0 for hub, on the bus.
# args: $1 - $bus number; $2 - vendor:chip id
@@ -15244,6 +15777,7 @@ sub get_usb_drivers {
eval $end if $b_log;
return @temp;
}
+
sub get_usb_path {
eval $start if $b_log;
my ($vendor,$chip,$glob) = @_;
@@ -15276,12 +15810,18 @@ sub set_dmesg_boot_data {
my ($file,@temp);
my ($counter) = (0);
$b_dmesg_boot_check = 1;
- $file = system_files('dmesg-boot');
- #$file = "$ENV{'HOME'}/bin/scripts/inxi/data/dmesg-boot/bsd-disks-diabolus.txt";
- #$file = "$ENV{'HOME'}/bin/scripts/inxi/data/dmesg-boot/freebsd-disks-solestar.txt";
- #$file = "$ENV{'HOME'}/bin/scripts/inxi/data/dmesg-boot/freebsd-enceladus-1.txt";
- #$file = "$ENV{'HOME'}/bin/scripts/inxi/data/dmesg-boot/openbsd-5.6-dmesg.boot-1.txt";
- #$file = "$ENV{'HOME'}/bin/scripts/inxi/data/dmesg-boot/openbsd-dmesg.boot-1.txt";
+ if (!$b_fake_dboot){
+ $file = system_files('dmesg-boot');
+ }
+ else {
+ #$file = "$ENV{'HOME'}/bin/scripts/inxi/data/dmesg-boot/bsd-disks-diabolus.txt";
+ #$file = "$ENV{'HOME'}/bin/scripts/inxi/data/dmesg-boot/freebsd-disks-solestar.txt";
+ #$file = "$ENV{'HOME'}/bin/scripts/inxi/data/dmesg-boot/freebsd-enceladus-1.txt";
+ ## matches: toshiba: openbsd-5.6-sysctl-2.txt
+ #$file = "$ENV{'HOME'}/bin/scripts/inxi/data/dmesg-boot/openbsd-5.6-dmesg.boot-1.txt";
+ ## matches: compaq: openbsd-5.6-sysctl-1.txt"
+ $file = "$ENV{'HOME'}/bin/scripts/inxi/data/dmesg-boot/openbsd-dmesg.boot-1.txt";
+ }
if ($file){
return if ! -r $file;
@dmesg_boot = reader($file);
@@ -15299,6 +15839,9 @@ sub set_dmesg_boot_data {
$_ =~ s/\s\s/ /g;
$_ =~ s/^(\S+)\sat\s/$1:at /; # ada0 at ahcich0
push @temp, $_;
+ if (/^bios[0-9]:(at|vendor)/){
+ push @sysctl_machine, $_;
+ }
}
@dmesg_boot = @temp;
# FreeBSD: 'da*' is a USB device 'ada*' is a SATA device 'mmcsd*' is an SD card
@@ -15317,6 +15860,7 @@ sub set_dmesg_boot_data {
#print Dumper \@dmesg_boot if $test[9];
eval $end if $b_log;
}
+
# note, all actual tests have already been run in check_tools so if we
# got here, we're good.
sub set_dmi_data {
@@ -15399,6 +15943,7 @@ sub set_ip_data {
}
eval $end if $b_log;
}
+
sub set_ip_addr {
eval $start if $b_log;
my $program = check_program('ip');
@@ -15451,6 +15996,7 @@ sub set_ip_addr {
print Dumper \@ifs if $test[3];
eval $end if $b_log;
}
+
sub set_ifconfig {
eval $start if $b_log;
my $program = check_program('ifconfig'); # not in user path, sbin
@@ -15484,19 +16030,27 @@ sub set_ifconfig {
}
$b_skip = 0;
}
- elsif (!$b_skip && $bsd_type && /^\s+(ether|media|status)/){
+ # lladdr openbsd
+ elsif (!$b_skip && $bsd_type && /^\s+(ether|media|status|lladdr)/){
$_ =~ s/^\s+//;
# media: Ethernet 100baseTX <full-duplex> freebsd 7.3
# media: Ethernet autoselect (1000baseT <full-duplex>) Freebsd 8.2
#
if (/^media/){
- $_ =~ /<([^>]+)>/;
- $duplex = $1;
- $_ =~ /[\s\(]([1-9][\S]+\s)/;
+ # openbsd: media: Ethernet autoselect (1000baseT full-duplex)
+ if ($bsd_type && $bsd_type eq 'openbsd'){
+ $_ =~ /\s\([\S]+\s([\S]+)\)/;
+ $duplex = $1;
+ }
+ else {
+ $_ =~ /<([^>]+)>/;
+ $duplex = $1;
+ }
+ $_ =~ /\s\(([1-9][\S]+\s)/;
$speed = $1;
$speed =~ s/\s+$// if $speed;
}
- elsif (/^ether/){
+ elsif (!$mac && /^ether|lladdr/){
$mac = (split /\s+/, $_)[1];
}
elsif (/^status/){
@@ -15561,6 +16115,7 @@ sub set_pci_data {
}
eval $end if $b_log;
}
+
# 0 type
# 1 type_id
# 2 bus_id
@@ -15634,6 +16189,7 @@ sub set_lspci_data {
main::log_data('dump','@pci',\@pci) if $b_log;
eval $end if $b_log;
}
+
# em0@pci0:6:0:0: class=0x020000 card=0x10d315d9 chip=0x10d38086 rev=0x00 hdr=0x00
# vendor = 'Intel Corporation'
# device = 'Intel 82574L Gigabit Ethernet Controller (82574L)'
@@ -15716,6 +16272,7 @@ sub set_pciconf_data {
main::log_data('dump','@pci',\@pci) if $b_log;
eval $end if $b_log;
}
+
sub set_ps_aux {
eval $start if $b_log;
@ps_aux = split "\n",qx(ps aux);;
@@ -15738,9 +16295,21 @@ sub set_ps_aux {
sub set_sysctl_data {
eval $start if $b_log;
return if $alerts{'sysctl'}{'action'} ne 'use';
+ my (@temp);
# darwin sysctl has BOTH = and : separators, and repeats data. Why?
- my $program = check_program('sysctl');
- my @temp = grabber("$program -a 2>/dev/null");
+ if (!$b_fake_sysctl){
+ my $program = check_program('sysctl');
+ @temp = grabber("$program -a 2>/dev/null");
+ }
+ else {
+ #my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sysctl/obsd_6.1_sysctl_soekris6501_root.txt";
+ #my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sysctl/obsd_6.1sysctl_lenovot500_user.txt";
+ ## matches: compaq: openbsd-dmesg.boot-1.txt
+ my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sysctl/openbsd-5.6-sysctl-1.txt";
+ ## matches: toshiba: openbsd-5.6-dmesg.boot-1.txt
+ #my $file = "$ENV{'HOME'}/bin/scripts/inxi/data/sysctl/openbsd-5.6-sysctl-2.txt";
+ @temp = reader($file);
+ }
foreach (@temp){
$_ =~ s/\s*=\s*|:\s+/:/;
$_ =~ s/\"//g;
@@ -15764,6 +16333,7 @@ sub set_sysctl_data {
}
eval $end if $b_log;
}
+
# http://www.usb.org/developers/defined_class
sub set_usb_data {
eval $start if $b_log;
@@ -15815,6 +16385,7 @@ sub set_lsusb_data_short {
main::log_data('dump','@usb: short',\@usb) if $b_log;
eval $end if $b_log;
}
+
sub set_lsusb_data_long {
eval $start if $b_log;
my ($content,@data,@working,$bus_id,$device_id,$id,$b_skip);
@@ -15895,6 +16466,7 @@ sub set_lsusb_data_long {
main::log_data('dump','@usb: long',\@usb) if $b_log;
eval $end if $b_log;
}
+
# Controller /dev/usb2:
# addr 1: full speed, self powered, config 1, UHCI root hub(0x0000), Intel(0x8086), rev 1.00
# port 1 addr 2: full speed, power 98 mA, config 1, USB Receiver(0xc52b), Logitech(0x046d), rev 12.01
@@ -15902,10 +16474,9 @@ sub set_lsusb_data_long {
sub set_usbdevs_data {
eval $start if $b_log;
my (@data,@working,$class,$bus_id,$addr_id,$id,$speed,$protocol);
- my $b_live = 1;
my $j = 0;
my $ports = 0;
- if ($b_live){
+ if (!$b_fake_usbdevs){
my $program = check_program('usbdevs');
my $content = qx($program -v 2>/dev/null);
@data = split /\n/, $content;
@@ -15986,6 +16557,7 @@ sub assign_data {
%rows = (%rows,%row);
}
}
+
sub generate_lines {
eval $start if $b_log;
my (%row,$b_pci_check,$b_dmi_check);
@@ -15998,9 +16570,7 @@ sub generate_lines {
main::log_data('dump','@ps_cmd',\@ps_cmd);
}
if ( $show{'short'} ){
- if ($bsd_type && !$b_dmesg_boot_check){
- set_dmesg_boot_data();
- }
+ set_dmesg_boot_data() if ($bsd_type && !$b_dmesg_boot_check);
%row = generate_short_data();
assign_data(%row);
}
@@ -16014,9 +16584,7 @@ sub generate_lines {
set_dmi_data() ;
$b_dmi_check = 1;
}
- if ($bsd_type && !$b_dmesg_boot_check){
- set_dmesg_boot_data();
- }
+ set_dmesg_boot_data() if ($bsd_type && !$b_dmesg_boot_check);
%row = line_handler('Machine','machine');
assign_data(%row);
}
@@ -16041,9 +16609,7 @@ sub generate_lines {
assign_data(%row);
}
if ( $show{'cpu'} || $show{'cpu-basic'} ){
- if ($bsd_type && !$b_dmesg_boot_check){
- set_dmesg_boot_data();
- }
+ set_dmesg_boot_data() if ($bsd_type && !$b_dmesg_boot_check);
my $arg = ($show{'cpu-basic'}) ? 'basic' : 'full' ;
%row = line_handler('CPU','cpu',$arg);
assign_data(%row);
@@ -16070,9 +16636,7 @@ sub generate_lines {
assign_data(%row);
}
if ( $show{'disk'} || $show{'disk-basic'} || $show{'disk-total'} || $show{'optical'} ){
- if ($bsd_type && !$b_dmesg_boot_check){
- set_dmesg_boot_data();
- }
+ set_dmesg_boot_data() if ($bsd_type && !$b_dmesg_boot_check);
%row = line_handler('Drives','disk');
assign_data(%row);
}
@@ -16120,6 +16684,7 @@ sub generate_lines {
}
eval $end if $b_log;
}
+
sub line_handler {
eval $start if $b_log;
my ($key,$sub,$arg) = @_;
diff --git a/inxi.1 b/inxi.1
index f475a1d..eef1304 100644
--- a/inxi.1
+++ b/inxi.1
@@ -1,4 +1,4 @@
-.TH INXI 1 "2018\-04\-18" inxi "inxi manual"
+.TH INXI 1 "2018\-05\-11" inxi "inxi manual"
.SH NAME
inxi \- Command line system information script for console and IRC
.SH SYNOPSIS
@@ -7,7 +7,8 @@ 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] [\fB\-y WIDTH\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]
\fBinxi\fR [\fB\-\-recommends\fR] \fR[\fB\-\-slots\fR] \fR[\fB\-\-usb\fR]
@@ -141,13 +142,16 @@ so it will simply show the floppy ID without any extra data. \fB\-xx\fR adds a
few more features.
.TP
.B \-D\fR,\fB \-\-disk\fR
-Show Hard Disk info. Shows total disk space, used percentage, and details for
-each disk. The disk used percentage includes space used by swap partition(s),
-since those are not usable for data storage. Note that
-with RAID disks, the percentage will be wrong since the total is computed from the
-disk sizes, but used is computed from mounted partition used percentages. This
-small defect may get corrected in the future. Also, unmounted partitions are not
-counted in disk use percentages since inxi has no access to that data.
+Show Hard Disk info. Shows total disk space and used percentage. The disk used
+percentage includes space used by swap partition(s), since those are not usable
+for data storage. Note that with RAID disks, the percentage will be wrong since
+the total is computed from the disk sizes, but used is computed from mounted
+partition used percentages. This small defect may get corrected in the future.
+Also, unmounted partitions are not counted in disk use percentages since inxi
+has no access to the used amount.
+
+Also shows per disk information: Disk ID, type (if present), vendor (if detected),
+model, and size. See \fBExtra Data Options\fR for more features.
.TP
.B \-f\fR,\fB \-\-flags\fR
Show all CPU flags used, not just the short list. Not shown with \fB\-F\fR in order
@@ -172,10 +176,7 @@ If protocol is not detected, shows:
Also shows screen resolution(s), OpenGL renderer, OpenGL core profile version/OpenGL
version.
-If detected (currently only available if on a desktop), it will attempt to show the
-server type, i.e., X11, Wayland, Mir. When Xorg is present, its version information
-will show after the server type in parentheses. Compositor information will show if
-detected using \fB\-xx\fR option.
+Compositor information will show if detected using \fB\-xx\fR option.
.TP
.B \-h\fR,\fB \-\-help\fR
The help menu. Features dynamic sizing to fit into terminal window. Set script
@@ -427,6 +428,11 @@ 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.
+.TP
.B \-y\fR,\fB \-\-width <integer>\fR
This is an absolute width override which sets the output line width max.
Overrides \fBCOLS_MAX_IRC\fR / \fBCOLS_MAX_CONSOLE\fR globals, or the
@@ -558,8 +564,8 @@ generate one.
\- md\-raid: Adds second RAID Info line with extra data: blocks, chunk size,
bitmap (if present). Resync line, shows blocks synced/total blocks.
.TP
-.B \-xx \-s\fR
-\- Adds basic voltages: 12v, 5v, 3.3v, vbat (\fBipmi\fR only).
+.B \-x \-s\fR
+\- Adds basic voltages: 12v, 5v, 3.3v, vbat (\fBipmi\fR, \fBlm-sensors\fR if present).
.TP
.B \-x \-S\fR
\- Adds desktop toolkit (\fBtk\fR), if available (GNOME/Xfce/KDE only).
@@ -666,10 +672,10 @@ data is simply not available as of 2018\-04\-03), location (only available from
\fBdmidecode\fR derived output).
.TP
.B \-xxx \-D\fR
-\- Adds disk firmware revision number, if available (nvme and possibly other types).
+\- Adds disk firmware revision number (if available).
.TP
.B \-xxx \-D\fR
-\- Adds disk partition scheme (in some but not all cases), e.g. scheme: \fBGPT\fR
+\- Adds disk partition scheme (in some but not all cases), e.g. \fBscheme: GPT\fR
.TP
.B \-xxx \-I\fR
\- For \fBShell:\fR adds \fB(su|sudo|login)\fR to shell name if present.
@@ -988,6 +994,8 @@ above configuration page on smxi.org for full info.
\fBSEP2_CONSOLE\fR Replaces default key / value separator of '\fB:\fR'.
+\fBWEATHER_UNIT\fR Values: [\fBc\fR|\fBf\fR|\fBcf\fR|\fBfc\fR]. Same as \fB\-\-weather\-unit\fR.
+
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,
diff --git a/inxi.changelog b/inxi.changelog
index 82c3aec..ab70880 100644
--- a/inxi.changelog
+++ b/inxi.changelog
@@ -1,4 +1,149 @@
=====================================================================================
+Version: 3.0.09
+Patch Version: 00
+Script Date: 2018-05-11
+-----------------------------------
+Changes:
+-----------------------------------
+
+New version, new man. Bug fixes, feature updates.
+
+The main reason to release this earlier than I had hoped was because of the /sys
+permission change for serial/uuid file data. The earlier we can get this fix out,
+the better for end users, otherwise they will think they have no serial data when
+they really do.
+
+FIXES:
+1. this bug just came to my attention, apparently the (I assume) kernel people
+decided for us that we don't need to see our serial numbers in /sys unless we are
+root. This is an unfortunate but sadly predictable event. To work around this
+recent change (somewhere between 4.14 and 4.15 as far as I can tell), inxi -M and
+-B now check for root read-only and show <root required> if the file exists but
+is not user readable. I wish, I really wish, that people could stop changing stuff
+for no good reason, but that's out of my control, all I can do is adjust inxi to
+this reality. But shame on whoever decided that was a good idea.
+
+This is not technically an inxi bug, but rather a regression, since it's caused
+by a change in /sys permissions, but users would see it as a bug so I consider
+this an important fix.
+
+Note that the new /sys/class/dmi/id permissions result in various possible things:
+1. serial/uuid file is empty but exists and is not readable by user
+2. serial/uuid file is not empty and exists and is not readable by user
+3. serial/uuid file does not exist
+4. serial/uuid file exists, is not empty, and is readable by root
+
+Does this change make your life better? It doesn't make mine better, it makes
+it worse. Consider filing a bug report against whoever allowed this regression
+is my suggestion.
+
+BUGS:
+1. A weather bug could result in odd or wrong data showing in weather output, this
+was due to a mistake in how the weather data was assembled internally. This error
+could lead to large datastore files, and odd output that is not all correct.
+
+2. More of an enhancement, but due to the way 'v' is used in version numbers,
+the program_version tool in some cases could have sliced out a 'v' in the wrong
+place in the version string, and also could have sliced out legitimate v values.
+
+This v issue also appeared in bios version, so now the new rule for program_version
+and certain other version results is to trim off starting v if and only if it is
+followed by a number.
+
+FEATURES:
+1. Added in OpenBSD support for showing machine data without having to use dmidecode.
+This is a combination of systcl -a and dmesg.boot data, not very good quality data
+sources, but it is available as user, and it does work. Note that BIOS systems
+are the only ones tested, I don't know what the syntax for UEFI is for the field
+names and strings. Coming soon is Battery and Sensors data, from the same sources.
+
+Sadly as far as I know, OpenBSD is the only BSD that has such nice, usable (well,
+ok, dmesg.boot data is low quality strings, not really machine safe) data. I
+have no new datasets from the other BSDs so I don't know if they have decided to
+copy/emulate this method.
+
+2. By request, and this was listed in issue #134, item no. 1, added in weather
+switchable metric/imperial output. Also added an option, --weather-unit and
+configuration item: WEATHER_UNIT with possible values: cf|fc|c|f. The 2nd of
+two in cf/fc goes in () in the output. Note that windspeed is m/s or km/h as metric,
+inxi shows m/s as default for metric and (km/h as secondary). Also fixed -w
+observation date to use local time formatting. That does not work in -W so it shows
+the default value.
+
+3. Updated man to show new WEATHER_UNIT config option, and new --weather-unit
+option. Also fixed some other small man glitches that I had missed.
+
+-----------------------------------
+-- Harald Hope - Fri, 11 May 2018 13:29:06 -0700
+
+=====================================================================================
+Version: 3.0.08
+Patch Version: 00
+Script Date: 2018-05-06
+-----------------------------------
+Changes:
+-----------------------------------
+
+New version, new tarball. New features, bug fixes.
+
+This is a big one.
+
+NEW FEATURES:
+
+1. By Request: Disk vendor is now generally going to be shown. Since this uses
+empirical data to grab the vendor name, from the model string, it will not always
+find anything. When it fails to find vendor data, no vendor: item will show.
+
+Note that some MMC devices will probably not show vendor data, but that's due to
+there being no data that reveals that.
+
+2. Extended -sx volts to also show voltage from lm-sensors if present. Many
+systems show no voltage data with lm-sensors, but now if any is found, it
+will show, same as impi.
+
+3. Moved to lsblk as primary source for partition/unmounted filesystem, uuid, and
+label data.
+
+Falls back to previous methods if lsblk does not return data. Some lsblk do not
+show complete data unless super user as well.
+
+4. Refactored code to be more logical and clear.
+
+5. Added for OpenBSD -r: /etc/installurl file.
+
+BUG FIXES:
+
+1. CRITICAL: /sys/block/xxx/device/model is in some cases truncating the disk
+model name to 16 characters. This is not an inxi bug, it's a bug with /sys itself.
+
+To fix this, inxi now uses for GNU/Linux /dev/disk/by-id data which does not
+ever do this truncation. It's also faster I believe to read that directory
+once, filter the results, then use the data for vendor/model/serial.
+
+this was also part of the disk vendor data feature.
+
+2. Openbsd networking fix. Was not showing IF data, now it does.
+
+3. Fixed bug with unmounted where sometimes md0 type partitions would show
+even though they are in a raid array.
+
+4. Fixed disk rev, now it searches for 3 different files in /sys to get that data.
+
+5. Fixed bug with very old systems, with sudo 1.6 or older, for some reason that
+error did not get redirected to /dev/null, so now only using sudo -n after explicit
+version test, only if 1.7 or newer.
+
+6. Fixed a few null results in fringe cases for graphics. Resolution now shows
+NA for Hz if no hz data found. This was only present on a fringe user case
+which is unlikely to ever impact normal X installations.
+
+7. Fixed BSD L2 cache, was showing MiB instead of KiB, wrong math.
+
+
+-----------------------------------
+-- Harald Hope - Sun, 06 May 2018 20:23:30 -0700
+
+=====================================================================================
Version: 3.0.07
Patch Version: 00
Script Date: 2018-04-17