summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@ubuntu.com>2014-08-20 14:22:07 -0400
committerLibravatarUnit 193 <unit193@ubuntu.com>2014-08-20 14:22:07 -0400
commit5a20092c0bfeba0fdbb4b7c6a11aed32432022a6 (patch)
treeef3083a577113e42e77ccdae541aadb25fd7e840
parente06e4e09c4c22c28cf4173437b76449ebfff31c0 (diff)
downloadinxi-5a20092c0bfeba0fdbb4b7c6a11aed32432022a6.tar.bz2
inxi-5a20092c0bfeba0fdbb4b7c6a11aed32432022a6.tar.xz
inxi-5a20092c0bfeba0fdbb4b7c6a11aed32432022a6.tar.zst
Imported Upstream version 2.2.00upstream/2.2.00
-rwxr-xr-xinxi1365
-rwxr-xr-xinxi.140
-rwxr-xr-xinxi.1.gzbin8777 -> 9783 bytes
-rwxr-xr-xinxi.changelog359
4 files changed, 1493 insertions, 271 deletions
diff --git a/inxi b/inxi
index a1bfb11..56ae949 100755
--- a/inxi
+++ b/inxi
@@ -1,8 +1,8 @@
#!/usr/bin/env bash
########################################################################
#### Script Name: inxi
-#### Version: 2.1.28
-#### Date: 2014-05-05
+#### Version: 2.2.0
+#### Date: 2014-08-18
#### Patch Number: 00
########################################################################
#### SPECIAL THANKS
@@ -1672,6 +1672,8 @@ debug_data_collector()
ls /usr/bin/gcc* &> $debug_data_dir/gcc-sys-versions.txt
gcc --version &> $debug_data_dir/gcc-version.txt
clang --version &> $debug_data_dir/clang-version.txt
+ cat /etc/src.conf &> $debug_data_dir/bsd-etc-src-conf.txt
+ cat /etc/make.conf &> $debug_data_dir/bsd-etc-make-conf.txt
cat /etc/issue &> $debug_data_dir/etc-issue.txt
cat $FILE_LSB_RELEASE &> $debug_data_dir/lsb-release.txt
cat $FILE_OS_RELEASE &> $debug_data_dir/os-release.txt
@@ -1830,7 +1832,7 @@ debug_data_collector()
echo 'Creating inxi output file now. This can take a few seconds...'
echo "Starting $SCRIPT_NAME from: $start_directory"
cd $start_directory
- $SCRIPT_PATH/$SCRIPT_NAME -FRfrploudxxx -c 0 -@ 8 -y 120 > $SCRIPT_DATA_DIR/$debug_data_dir/inxi-FRfrploudxxxy120.txt
+ $SCRIPT_PATH/$SCRIPT_NAME -FRfrploudmxxx -c 0 -@ 8 -y 120 > $SCRIPT_DATA_DIR/$debug_data_dir/inxi-FRfrploudmxxxy120.txt
cp $LOG_FILE $SCRIPT_DATA_DIR/$debug_data_dir
if [[ -f $SCRIPT_DATA_DIR/$debug_data_dir.tar.gz ]];then
echo "Found and removing previous tar.gz data file: $debug_data_dir.tar.gz"
@@ -2408,6 +2410,7 @@ get_parameters()
if [[ $OPTARG -ge 5 ]];then
B_SHOW_AUDIO='true'
B_SHOW_BASIC_OPTICAL='true'
+ B_SHOW_MEMORY='true'
B_SHOW_SENSORS='true'
B_SHOW_LABELS='true'
B_SHOW_UUIDS='true'
@@ -2632,7 +2635,7 @@ show_options()
# print_screen_output " "
print_lines_basic "0" "" "$SCRIPT_NAME supports the following options. You can combine them, or list them one by one. Examples: $SCRIPT_NAME^-v4^-c6 OR $SCRIPT_NAME^-bDc^6. If you start $SCRIPT_NAME with no arguments, it will show the short form."
print_screen_output " "
- print_lines_basic "0" "" "The following options if used without -F, -b, or -v will show just option line(s): A, C, D, G, I, M, N, P, R, S, f, i, n, o, p, l, u, r, s, t - you can use these alone or together to show just the line(s) you want to see. If you use them with -v^[level], -b or -F, it will show the full output for that line along with the output for the chosen verbosity level."
+ print_lines_basic "0" "" "The following options if used without -F, -b, or -v will show just option line(s): A, C, D, G, I, M, N, P, R, S, f, i, m, n, o, p, l, u, r, s, t - you can use these alone or together to show just the line(s) you want to see. If you use them with -v^[level], -b or -F, it will show the full output for that line along with the output for the chosen verbosity level."
print_screen_output "- - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
print_screen_output "Output Control Options:"
print_lines_basic "1" "-A" "Audio/sound card information."
@@ -2652,12 +2655,13 @@ show_options()
print_lines_basic "1" "-d" "Optical drive data. Same as -Dd. See also -x and -xx."
print_lines_basic "1" "-D" "Full hard Disk info, not only model, ie: /dev/sda ST380817AS 80.0GB. See also -x and -xx. Disk total used percentage includes swap partition size(s)."
print_lines_basic "1" "-f" "All cpu flags, triggers -C. Not shown with -F to avoid spamming. ARM cpus show 'features'."
- print_lines_basic "1" "-F" "Full output for $SCRIPT_NAME. Includes all Upper Case line letters, plus -s and -n. Does not show extra verbose options like -x -d -f -u -l -o -p -t -r"
+ print_lines_basic "1" "-F" "Full output for $SCRIPT_NAME. Includes all Upper Case line letters, plus -s and -n. Does not show extra verbose options like -d -f -l -m -o -p -r -t -u -x"
print_lines_basic "1" "-G" "Graphic card information (card, display server type/version, resolution, glx renderer, version)."
print_lines_basic "1" "-i" "Wan IP address, and shows local interfaces (requires ifconfig
network tool). Same as -Nni. Not shown with -F for user security reasons, you shouldn't paste your local/wan IP."
print_lines_basic "1" "-I" "Information: processes, uptime, memory, irc client (or shell type), $SCRIPT_NAME version."
print_lines_basic "1" "-l" "$partition_string_u labels. Default: short $partition_string -P. For full -p output, use: -pl (or -plu)."
+ print_lines_basic "1" "-m" "Memory (RAM) data. Physical system memory array(s), capacity, how many devices (slots) supported, and individual memory devices (sticks of memory etc). For devices, shows device locator, size, speed, type (like: DDR3). Also see -x, -xx, -xxx"
print_lines_basic "1" "-M" "Machine data. Motherboard, Bios, and if present, System Builder (Like Lenovo). Older systems/kernels without the required /sys data can use dmidecode instead, run as root. Dmidecode can be forced with -! 33"
print_lines_basic "1" "-n" "Advanced Network card information. Same as -Nn. Shows interface, speed, mac id, state, etc."
print_lines_basic "1" "-N" "Network card information. With -x, shows PCI BusID, Port number."
@@ -2678,7 +2682,7 @@ show_options()
print_lines_basic "2" "2" "Networking card (-N), Machine (-M) data, shows basic hard disk data (names only), and, if present, basic raid (devices only, and if inactive, notes that). similar to: $SCRIPT_NAME^-b"
print_lines_basic "2" "3" "Advanced CPU (-C), network (-n) data, and switches on -x advanced data option."
print_lines_basic "2" "4" "$partition_string_u size/filled data (-P) for (if present): /, /home, /var/, /boot. Shows full disk data (-D)."
- print_lines_basic "2" "5" "Audio card (-A); sensors^(-s), $partition_string label^(-l) and UUID^(-u), short form of optical drives, standard raid data (-R)."
+ print_lines_basic "2" "5" "Audio card (-A); sensors^(-s), memory/ram^(-m), $partition_string label^(-l) and UUID^(-u), short form of optical drives, standard raid data (-R)."
print_lines_basic "2" "6" "Full $partition_string (-p), unmounted $partition_string (-o), optical drive (-d), full raid; triggers -xx."
print_lines_basic "2" "7" "Network IP data (-i); triggers -xxx."
@@ -2695,6 +2699,7 @@ show_options()
print_lines_basic "2" "-G" "(for single gpu, nvidia driver) screen number gpu is running on."
print_lines_basic "2" "-i" "IPv6 as well for LAN interface (IF) devices."
print_lines_basic "2" "-I" "System GCC, default. With -xx, also show other installed GCC versions. If running in console, not in IRC client, shows shell version number, if detected. Init/RC Type and runlevel (if available)."
+ print_lines_basic "2" "-m" "Part number; Max memory module size (if available)."
print_lines_basic "2" "-N -A" "Version/port(s)/driver version (if available) for Network/Audio;"
print_lines_basic "2" "-N -A -G" "Network, audio, graphics, shows PCI Bus ID/Usb ID number of card."
print_lines_basic "2" "-R" "md-raid: Shows component raid id. Adds second RAID Info line: raid level; report on drives (like 5/5); blocks; chunk size; bitmap (if present). Resync line, shows blocks synced/total blocks. zfs-raid: Shows raid array full size; available size; portion allocated to RAID"
@@ -2708,6 +2713,7 @@ show_options()
print_lines_basic "2" "-D" "Disk serial number."
print_lines_basic "2" "-G" "Chip vendor:product ID for each video card."
print_lines_basic "2" "-I" "Other detected installed gcc versions (if present). System default runlevel. Adds parent program (or tty) for shell info if not in IRC (like Konsole or Gterm). Adds Init/RC (if found) version number."
+ print_lines_basic "2" "-m" "Manufacturer, Serial Number, single/double bank (if found)."
print_lines_basic "2" "-M" "Chassis information, bios rom size (dmidecode only), if data for either is available."
print_lines_basic "2" "-N" "Chip vendor:product ID for each nic."
print_lines_basic "2" "-R" "md-raid: Superblock (if present); algorythm, U data. Adds system info line (kernel support,read ahead, raid events). If present, adds unused device line. Resync line, shows progress bar."
@@ -2717,6 +2723,7 @@ show_options()
fi
print_lines_basic "2" "-@ 11-14" "Automatically uploads debugger data tar.gz file to ftp.techpatterns.com. EG: $SCRIPT_NAME^-xx@14"
print_lines_basic "1" "-xxx" "Show extra, extra, extra data (only works with verbose or line output, not short form):"
+ print_lines_basic "2" "-m" "Width of memory bus, data and total (if present and greater than data); Detail, if present, for Type; module voltage, if available."
print_lines_basic "2" "-S" "Panel/shell information in desktop output, if in X (like gnome-shell, cinnamon, mate-panel)."
if [[ $B_ALLOW_WEATHER == 'true' ]];then
print_lines_basic "2" "-w -W" "Location (uses -z/irc filter), weather observation time, wind chill, heat index, dew point (shows extra lines for data where relevant)."
@@ -3465,7 +3472,7 @@ get_audio_data()
else if (/kernel modules:/) {
modules[audioCard] = modules[audioCard] gensub( /(.*): (.*)/ ,"\\2" ,"g" ,$0 ) ""
}
- else if (/I\/O/) {
+ else if (/^[[:space:]]*I\/O/) {
portsTemp = gensub(/\t*I\/O ports at (.*) \[.*\]/,"\\1","g",$0)
ports[audioCard] = ports[audioCard] portsTemp " "
}
@@ -3874,7 +3881,6 @@ get_cpu_speed_hack()
echo $speed
}
-
get_cpu_data_bsd()
{
eval $LOGFS
@@ -4254,7 +4260,7 @@ get_desktop_environment()
desktop_environment="MATE"
# note, GNOME_DESKTOP_SESSION_ID is deprecated so we'll see how that works out
# https://bugzilla.gnome.org/show_bug.cgi?id=542880
- elif [[ -n $GNOME_DESKTOP_SESSION_ID ]]; then
+ elif [[ -n $GNOME_DESKTOP_SESSION_ID || $XDG_CURRENT_DESKTOP == 'GNOME' ]]; then
if type -p gnome-shell &>/dev/null;then
version=$( get_program_version 'gnome-shell' 'gnome' '3' )
elif type -p gnome-about &>/dev/null;then
@@ -4882,17 +4888,24 @@ get_dmidecode_data()
{
eval $LOGFS
- local dmidecodePath=''
+ local dmiData="" b_debugger='false'
if [[ $B_DMIDECODE_SET != 'true' ]];then
dmidecodePath=$( type -p dmidecode 2>/dev/null )
- if [[ -n $dmidecodePath ]];then
+ if [[ -z $dmidecodePath ]];then
+ DMIDECODE_DATA='dmidecode-error-not-installed'
+ else
# note stripping out these lines: Handle 0x0016, DMI type 17, 27 bytes
# but NOT deleting them, in case the dmidecode data is missing empty lines which will be
# used to separate results. Then we remove the doubled empty lines to keep it clean and
- # strip out all the stuff we don't want to see in the results.
- DMIDECODE_DATA="$( $dmidecodePath 2>/dev/null \
- | gawk -F ':' '
+ # strip out all the stuff we don't want to see in the results. We want the error data in
+ # stdout for error handling
+ if [[ $b_debugger == 'true' && $HOSTNAME == 'yawn' ]];then
+ dmiData="$( cat ~/bin/scripts/inxi/svn/misc/data/dmidecode/dmidecode-memory-variants-2.txt )"
+ else
+ dmiData="$( $dmidecodePath 2>&1 )"
+ fi
+ DMIDECODE_DATA="$( echo "$dmiData" | gawk -F ':' '
BEGIN {
IGNORECASE=1
cutExtraTab="false"
@@ -4913,11 +4926,12 @@ get_dmidecode_data()
sub(/^\tDMI type.*/, "", $0)
cutExtraTab="true"
}
+
gsub(/'"$BAN_LIST_NORMAL"'/, "", twoData)
- gsub(/,/, " ", $0)
+ gsub(/,/, " ", twoData)
# clean out Handle line
# sub(/^Handle.*/,"", $0)
- sub(/^[[:space:]]*Inactive.*/,"",$0)
+ sub(/^[[:space:]]*Inactive.*/,"",twoData)
# yes, there is a typo in a user data set, unknow
# Base Board Version|Base Board Serial Number
# Chassis Manufacturer|Chassis Version|Chassis Serial Number
@@ -4925,8 +4939,8 @@ get_dmidecode_data()
# To Be Filled By O.E.M.
# strip out starting white space so that the following stuff will clear properly
sub(/^[[:space:]]+/, "", twoData)
- sub(/^Base Board .*|^Chassis .*|.*O\.E\.M\..*|.*OEM.*|^Not .*|^System .*|.*unknow.*|.*N\/A.*|none|^To be filled.*/, "", twoData)
- sub(/(AssetTagNum|Manufacturer| Or Motherboard|PartNum|SerNum).*/, "", twoData)
+ sub(/^Base Board .*|^Chassis .*|.*O\.E\.M\..*|.*OEM.*|^Not .*|^System .*|.*unknow.*|.*N\/A.*|none|^To be filled.*|^0x[0]+$|\[Empty\]|<Bad Index>|^\.\.$/, "", twoData)
+ sub(/.*(AssetTagNum|Manufacturer| Or Motherboard|PartNum.*|SerNum).*/, "", twoData)
gsub(/bios|acpi/, "", twoData)
sub(/http:\/\/www.abit.com.tw\//, "Abit", twoData)
@@ -4939,15 +4953,17 @@ get_dmidecode_data()
else {
sub(/^\t\t+/, "~", oneData)
}
-
+ gsub(/ [ \t]+/, " ", twoData)
gsub(/^[[:space:]]+|[[:space:]]+$/, "", twoData)
gsub(/^[[:space:]]+|[[:space:]]+$/, "", oneData)
- gsub(/ [ \t]+/, " ", twoData)
+
# reconstructing the line for processing so gawk can use -F : again
if ( oneData != "" && twoHolder == "true" ) {
print oneData ":" twoData
}
else {
+ # make sure all null lines have no spaces in them!
+ gsub(/^[[:space:]]+|[[:space:]]+$/,"",$0)
print $0
}
}' \
@@ -4956,9 +4972,23 @@ N
/^\n$/D
}' \
)"
+ # echo ":${DMIDECODE_DATA}:"
+ log_function_data "DMIDECODE_DATA (PRE): $DMIDECODE_DATA"
+ if [[ ${#DMIDECODE_DATA} -lt 100 ]];then
+ if [[ -z ${DMIDECODE_DATA/*Permission denied*/} ]];then
+ # if [[ -n $( grep -i 'Permission denied' <<< "$DMIDECODE_DATA" ) ]];then
+ DMIDECODE_DATA='dmidecode-error-requires-root'
+ # this handles very old systems, like Lenny 2.6.26, with dmidecode, but no data
+ elif [[ -n $( grep -i 'no smbios ' <<< "$DMIDECODE_DATA" ) ]];then
+ DMIDECODE_DATA='dmidecode-error-no-smbios-dmi-data'
+ else
+ echo $DMIDECODE_DATA
+ DMIDECODE_DATA='dmidecode-error-unknown-error'
+ fi
+ fi
fi
B_DMIDECODE_SET='true'
- log_function_data "DMIDECODE_DATA: $DMIDECODE_DATA"
+ log_function_data "DMIDECODE_DATA (POST): $DMIDECODE_DATA"
fi
eval $LOGFE
@@ -4994,8 +5024,7 @@ get_gcc_system_version()
/^gcc/ {
print $2
exit
- }' )
-
+ }' )
# can't use xargs -L basename because not all systems support thats
if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
gcc_others=$( ls /usr/bin/gcc-* 2>/dev/null )
@@ -5904,11 +5933,6 @@ get_init_data()
init_type='launchd'
# / launchd/ version.plist /etc/launchd.conf
# init_version=$( get_program_version 'Launchd' '^Launchd' '4' )
- # missing data:
- # http://smarden.org/runit/sv.8.html
- elif [[ -e /sbin/runit-init || -e /etc/runit || -n $( type -p sv ) ]];then
- init_type='runit' # lower case
- # no data on version yet
elif [[ -f /etc/inittab ]];then
init_type='SysVinit'
if type -p strings &>/dev/null;then
@@ -5917,6 +5941,11 @@ get_init_data()
if [[ -n $strings_init_version ]];then
init_version=$( gawk '{print $2}' <<< "$strings_init_version" )
fi
+ # missing data:
+ # http://smarden.org/runit/sv.8.html
+ elif [[ -e /sbin/runit-init || -e /etc/runit || -n $( type -p sv ) ]];then
+ init_type='runit' # lower case
+ # no data on version yet
# freebsd at least
elif [[ -f /etc/ttys ]];then
init_type='init (bsd)'
@@ -6072,7 +6101,6 @@ get_machine_data()
board_vendor board_name board_version board_serial
bios_vendor bios_version bios_date
"
-
if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
machine_files="$machine_files
chassis_vendor chassis_type chassis_version chassis_serial
@@ -6109,120 +6137,120 @@ get_machine_data()
else
get_dmidecode_data
if [[ -n $DMIDECODE_DATA ]];then
- if [[ $B_ROOT == 'true' ]];then
- # this handles very old systems, like Lenny 2.6.26, with dmidecode, but no data
- if [[ -n $( grep -i 'no smbios ' <<< "$DMIDECODE_DATA" ) ]];then
- array_string='dmidecode-no-smbios-dmi-data'
- # please note: only dmidecode version 2.11 or newer supports consistently the -s flag
- else
- array_string=$( gawk -F ':' '
- BEGIN {
- IGNORECASE=1
- baseboardManufacturer=""
- baseboardProductName=""
- baseboardSerialNumber=""
- baseboardVersion=""
- biosReleaseDate=""
- biosRevision="" # only available from dmidecode
- biosRomSize="" # only available from dmidecode
- biosVendor=""
- biosVersion=""
- chassisManufacturer=""
- chassisSerialNumber=""
- chassisType=""
- chassisVersion=""
- systemManufacturer=""
- systemProductName=""
- systemVersion=""
- systemSerialNumber=""
- systemUuid=""
- bItemFound="" # we will only output if at least one item was found
- fullString=""
- testString=""
- bSys=""
- bCha=""
- bBio=""
- bBas=""
+ if [[ $DMIDECODE_DATA == 'dmidecode-error-'* ]];then
+ array_string=$DMIDECODE_DATA
+ # please note: only dmidecode version 2.11 or newer supports consistently the -s flag
+ else
+ array_string=$( gawk -F ':' '
+ BEGIN {
+ IGNORECASE=1
+ baseboardManufacturer=""
+ baseboardProductName=""
+ baseboardSerialNumber=""
+ baseboardVersion=""
+ biosReleaseDate=""
+ biosRevision="" # only available from dmidecode
+ biosRomSize="" # only available from dmidecode
+ biosVendor=""
+ biosVersion=""
+ chassisManufacturer=""
+ chassisSerialNumber=""
+ chassisType=""
+ chassisVersion=""
+ systemManufacturer=""
+ systemProductName=""
+ systemVersion=""
+ systemSerialNumber=""
+ systemUuid=""
+ bItemFound="" # we will only output if at least one item was found
+ fullString=""
+ testString=""
+ bSys=""
+ bCha=""
+ bBio=""
+ bBas=""
+ }
+ /^Bios Information/ {
+ while ( getline && !/^$/ ) {
+ if ( $1 ~ /^Release Date/ ) { biosReleaseDate=$2 }
+ if ( $1 ~ /^BIOS Revision/ ) { biosRevision=$2 }
+ if ( $1 ~ /^ROM Size/ ) { biosRomSize=$2 }
+ if ( $1 ~ /^Vendor/ ) { biosVendor=$2 }
+ if ( $1 ~ /^Version/ ) { biosVersion=$2 }
}
- /^Bios Information/ {
- while ( getline && !/^$/ ) {
- if ( $1 ~ /^Release Date/ ) { biosReleaseDate=$2 }
- if ( $1 ~ /^BIOS Revision/ ) { biosRevision=$2 }
- if ( $1 ~ /^ROM Size/ ) { biosRomSize=$2 }
- if ( $1 ~ /^Vendor/ ) { biosVendor=$2 }
- if ( $1 ~ /^Version/ ) { biosVersion=$2 }
- }
- testString=biosReleaseDate biosRevision biosRomSize biosVendor biosVersion
- if ( testString != "" ) {
- bItemFound="true"
- }
- bBio="true"
+ testString=biosReleaseDate biosRevision biosRomSize biosVendor biosVersion
+ if ( testString != "" ) {
+ bItemFound="true"
}
- /^Base Board Information/ {
- while ( getline && !/^$/ ) {
- if ( $1 ~ /^Manufacturer/ ) { baseboardManufacturer=$2 }
- if ( $1 ~ /^Product Name/ ) { baseboardProductName=$2 }
- if ( $1 ~ /^Serial Number/ ) { baseboardSerialNumber=$2 }
- }
- testString=baseboardManufacturer baseboardProductName baseboardSerialNumber
- if ( testString != "" ) {
- bItemFound="true"
- }
- bBas="true"
+ bBio="true"
+ }
+ /^Base Board Information/ {
+ while ( getline && !/^$/ ) {
+ if ( $1 ~ /^Manufacturer/ ) { baseboardManufacturer=$2 }
+ if ( $1 ~ /^Product Name/ ) { baseboardProductName=$2 }
+ if ( $1 ~ /^Serial Number/ ) { baseboardSerialNumber=$2 }
}
- /^Chassis Information/ {
- while ( getline && !/^$/ ) {
- if ( $1 ~ /^Manufacturer/ ) { chassisManufacturer=$2 }
- if ( $1 ~ /^Serial Number/ ) { chassisSerialNumber=$2 }
- if ( $1 ~ /^Type/ ) { chassisType=$2 }
- if ( $1 ~ /^Version/ ) { chassisVersion=$2 }
- }
- testString=chassisManufacturer chassisSerialNumber chassisType chassisVersion
- if ( testString != "" ) {
- bItemFound="true"
- }
- bCha="true"
+ testString=baseboardManufacturer baseboardProductName baseboardSerialNumber
+ if ( testString != "" ) {
+ bItemFound="true"
}
- /^System Information/ {
- while ( getline && !/^$/ ) {
- if ( $1 ~ /^Manufacturer/ ) { systemManufacturer=$2 }
- if ( $1 ~ /^Product Name/ ) { systemProductName=$2 }
- if ( $1 ~ /^Version/ ) { systemVersion=$2 }
- if ( $1 ~ /^Serial Number/ ) { systemSerialNumber=$2 }
- if ( $1 ~ /^UUID/ ) { systemUuid=$2 }
- }
- testString=systemManufacturer systemProductName systemVersion systemSerialNumber systemUuid
- if ( testString != "" ) {
- bItemFound="true"
- }
- bSys="true"
+ bBas="true"
+ }
+ /^Chassis Information/ {
+ while ( getline && !/^$/ ) {
+ if ( $1 ~ /^Manufacturer/ ) { chassisManufacturer=$2 }
+ if ( $1 ~ /^Serial Number/ ) { chassisSerialNumber=$2 }
+ if ( $1 ~ /^Type/ ) { chassisType=$2 }
+ if ( $1 ~ /^Version/ ) { chassisVersion=$2 }
}
- ( bSys == "true" && bCha="true" && bBio == "true" && bBas == "true" ) {
- exit # stop the loop
+ testString=chassisManufacturer chassisSerialNumber chassisType chassisVersion
+ if ( testString != "" ) {
+ bItemFound="true"
}
- END {
- if ( bItemFound == "true" ) {
- fullString = systemManufacturer "," systemProductName "," systemVersion "," systemSerialNumber
- fullString = fullString "," systemUuid "," baseboardManufacturer "," baseboardProductName
- fullString = fullString "," baseboardVersion "," baseboardSerialNumber "," biosVendor
- fullString = fullString "," biosVersion "," biosReleaseDate "," chassisManufacturer
- fullString = fullString "," chassisType "," chassisVersion "," chassisSerialNumber
- fullString = fullString "," biosRevision "," biosRomSize
-
- print fullString
- }
- }' <<< "$DMIDECODE_DATA" )
- fi
- else
- array_string='dmidecode-non-root-user'
+ bCha="true"
+ }
+ /^System Information/ {
+ while ( getline && !/^$/ ) {
+ if ( $1 ~ /^Manufacturer/ ) { systemManufacturer=$2 }
+ if ( $1 ~ /^Product Name/ ) { systemProductName=$2 }
+ if ( $1 ~ /^Version/ ) { systemVersion=$2 }
+ if ( $1 ~ /^Serial Number/ ) { systemSerialNumber=$2 }
+ if ( $1 ~ /^UUID/ ) { systemUuid=$2 }
+ }
+ testString=systemManufacturer systemProductName systemVersion systemSerialNumber systemUuid
+ if ( testString != "" ) {
+ bItemFound="true"
+ }
+ bSys="true"
+ }
+ ( bSys == "true" && bCha="true" && bBio == "true" && bBas == "true" ) {
+ exit # stop the loop
+ }
+ END {
+ # sys_vendor product_name product_version product_serial product_uuid
+ # board_vendor board_name board_version board_serial
+ # bios_vendor bios_version bios_date
+ if ( bItemFound == "true" ) {
+ fullString = systemManufacturer "," systemProductName "," systemVersion "," systemSerialNumber
+ fullString = fullString "," systemUuid "," baseboardManufacturer "," baseboardProductName
+ fullString = fullString "," baseboardVersion "," baseboardSerialNumber "," biosVendor
+ fullString = fullString "," biosVersion "," biosReleaseDate "," chassisManufacturer
+ fullString = fullString "," chassisType "," chassisVersion "," chassisSerialNumber
+ fullString = fullString "," biosRevision "," biosRomSize
+
+ print fullString
+ }
+ }' <<< "$DMIDECODE_DATA" )
fi
fi
fi
+ # echo $array_string
IFS=','
A_MACHINE_DATA=( $array_string )
IFS="$ORIGINAL_IFS"
- a_temp=${A_MACHINE_DATA[@]}
-# echo ${a_temp[@]}
+ # echo ${A_MACHINE_DATA[5]}
+ a_temp=( ${A_MACHINE_DATA[@]} )
+ # echo ${#a_temp[@]}
log_function_data "A_MACHINE_DATA: $a_temp"
eval $LOGFE
}
@@ -6319,6 +6347,7 @@ get_module_version_number()
eval $LOGFE
}
+
## create array of network cards
get_networking_data()
{
@@ -6329,72 +6358,64 @@ get_networking_data()
IFS=$'\n'
A_NETWORK_DATA=( $(
echo "$Lspci_v_Data" | gawk '
+ # NOTE: see version 2.1.28 or earlier for old logic if for some reason it is needed again
+ # that used a modified string made from nic name for index, why, I have no idea, makes no sense and leads
+ # to wrong ordered output as well. get_audio_data uses the old logic for now too.
BEGIN {
IGNORECASE=1
- counter=0 # required to handle cases of > 1 instance of the same chipset
+ counter=0
}
- /^[0-9a-f:\.]+ (ethernet|network) (controller|bridge)/ || /^[0-9a-f:\.]+ [^:]+: .*(ethernet|network).*$/ {
- nic=gensub(/^[0-9a-f:\.]+ [^:]+: (.+)$/,"\\1","g",$0)
- #gsub(/realtek semiconductor/, "Realtek", nic)
- #gsub(/davicom semiconductor/, "Davicom", nic)
+ /^[0-9a-f:\.]+ ((ethernet|network) (controller|bridge)|infiniband)/ || /^[0-9a-f:\.]+ [^:]+: .*(ethernet|infiniband|network).*$/ {
+ aNic[counter]=gensub(/^[0-9a-f:\.]+ [^:]+: (.+)$/,"\\1","g",$0)
+ #gsub(/realtek semiconductor/, "Realtek", aNic[counter])
+ #gsub(/davicom semiconductor/, "Davicom", aNic[counter])
# The doublequotes are necessary because of the pipes in the variable.
- gsub(/'"$BAN_LIST_NORMAL"'/, "", nic)
- gsub(/,/, " ", nic)
- gsub(/^ +| +$/, "", nic)
- gsub(/ [ \t]+/, " ", nic)
- # construct a unique string ending for each chipset detected, this allows for
- # multiple instances of the same exact chipsets, ie, dual gigabit
- nic = nic "~~" counter++
- aPciBusId[nic] = gensub(/(^[0-9a-f:\.]+) [^:]+: .+$/,"\\1","g",$0)
- # I do not understand why incrementing a string index makes sense?
- eth[nic]++
+ gsub(/'"$BAN_LIST_NORMAL"'/, "", aNic[counter])
+ gsub(/,/, " ", aNic[counter])
+ gsub(/^ +| +$/, "", aNic[counter])
+ gsub(/ [ \t]+/, " ", aNic[counter])
+ aPciBusId[counter] = gensub(/(^[0-9a-f:\.]+) [^:]+: .+$/,"\\1","g",$0)
while ( getline && !/^$/ ) {
gsub(/,/, "", $0)
- if ( /I\/O/ ) {
- ports[nic] = ports[nic] $4 " "
+ if ( /^[[:space:]]*I\/O/ ) {
+ aPorts[counter] = aPorts[counter] $4 " "
}
if ( /driver in use/ ) {
- drivers[nic] = drivers[nic] gensub( /(.*): (.*)/ ,"\\2" ,"g" ,$0 ) ""
+ aDrivers[counter] = aDrivers[counter] gensub( /(.*): (.*)/ ,"\\2" ,"g" ,$0 ) ""
}
else if ( /kernel modules/ ) {
- modules[nic] = modules[nic] gensub( /(.*): (.*)/ ,"\\2" ,"g" ,$0 ) ""
+ aModules[counter] = aModules[counter] gensub( /(.*): (.*)/ ,"\\2" ,"g" ,$0 ) ""
}
}
+ counter++
}
-
END {
- j=0
- for (i in eth) {
+ for (i=0;i<counter;i++) {
useDrivers=""
usePorts=""
useModules=""
+ useNic=""
usePciBusId=""
- if ( eth[i] > 1 ) {
- a[j] = eth[i] "x " i
- }
- else {
- a[j] = i
- }
## note: this loses the plural ports case, is it needed anyway?
- if ( ports[i] != "" ) {
- usePorts = ports[i]
+ if ( aPorts[i] != "" ) {
+ usePorts = aPorts[i]
}
- if ( drivers[i] != "" ) {
- useDrivers = drivers[i]
+ if ( aDrivers[i] != "" ) {
+ useDrivers = aDrivers[i]
}
- if ( modules[i] != "" ) {
- useModules = modules[i]
+ if ( aModules[i] != "" ) {
+ useModules = aModules[i]
+ }
+ if ( aNic[i] != "" ) {
+ useNic=aNic[i]
}
if ( aPciBusId[i] != "" ) {
usePciBusId = aPciBusId[i]
}
# create array primary item for master array
- # and strip out the counter again, this handled dual cards with same chipset
- sub( /~~[0-9]+$/, "", a[j] )
sub( / $/, "", usePorts ) # clean off trailing whitespace
- print a[j] "," useDrivers "," usePorts "," useModules, "," usePciBusId
- j++
+ print useNic "," useDrivers "," usePorts "," useModules, "," usePciBusId
}
}' ) )
IFS="$ORIGINAL_IFS"
@@ -6411,42 +6432,59 @@ get_networking_data()
get_network_advanced_data()
{
eval $LOGFS
- local a_network_adv_working='' if_path='' working_path='' working_uevent_path='' dir_path=''
- local if_id='' speed='' duplex='' mac_id='' oper_state='' chip_id=''
- local usb_data='' usb_vendor='' usb_product='' product_path='' driver_test=''
+ local a_network_adv_working='' if_data='' working_path='' working_uevent_path='' dir_path=''
+ local if_id='' speed='' duplex='' mac_id='' oper_state='' chip_id='' b_path_made='true'
+ local usb_data='' usb_vendor='' usb_product='' product_path='' driver_test='' array_counter=0
+ local full_path=''
+ # we need to change to holder since we are updating the main array
+ IFS=$'\n'
+ local a_main_working=(${A_NETWORK_DATA[@]})
+ IFS="$ORIGINAL_IFS"
- for (( i=0; i < ${#A_NETWORK_DATA[@]}; i++ ))
+ for (( i=0; i < ${#a_main_working[@]}; i++ ))
do
IFS=","
- a_network_adv_working=( ${A_NETWORK_DATA[i]} )
+ a_network_adv_working=( ${a_main_working[i]} )
+ IFS="$ORIGINAL_IFS"
# reset these every go round
driver_test=''
- if_id=''
- speed=''
- duplex=''
- mac_id=''
- oper_state=''
+ if_data=''
+ product_path=''
usb_data=''
- chip_id=''
+ usb_product=''
+ usb_vendor=''
+ working_path=''
+ working_uevent_path=''
if [[ -z $( grep '^usb-' <<< ${a_network_adv_working[4]} ) ]];then
# note although this may exist technically don't use it, it's a virtual path
# and causes weird cat errors when there's a missing file as well as a virtual path
# /sys/bus/pci/devices/0000:02:02.0/net/eth1
# real paths are: /sys/devices/pci0000:00/0000:00:1e/0/0000:02:02.0/net/eth1/uevent
# and on older debian kernels: /sys/devices/pci0000:00/0000:02:02.0/net:eth1/uevent
- # but broadcom shows this sometimes:
+ # but broadcom shows this sometimes, and older kernels maybe:
+ # /sys/devices/pci0000:00/0000:00:01.0/0000:05:00.0/net/eth0/
# /sys/devices/pci0000:00/0000:00:03.0/0000:03:00.0/ssb0:0/uevent:['DRIVER=b43', 'MODALIAS=ssb:v4243id0812rev0D']:
- working_path="/sys/bus/pci/devices/0000:${a_network_adv_working[4]}"
+ # echo a ${a_network_adv_working[4]}
+ if [[ -d /sys/bus/pci/devices/ ]];then
+ working_path="/sys/bus/pci/devices/0000:${a_network_adv_working[4]}"
+ elif [[ -d /sys/devices/pci0000:00/ ]];then
+ working_path="/sys/devices/pci0000:00/0000:00:01.0/0000:${a_network_adv_working[4]}"
+ fi
+ #echo wp ${a_network_adv_working[4]} $i
# now we want the real one, that xiin also displays, without symbolic links.
- if [[ -e $working_path ]];then
+ if [[ -n $working_path && -e $working_path ]];then
working_path=$( readlink -f $working_path 2>/dev/null )
- # sometimes there is another directory between the path and /net
- if [[ ! -e $working_path/net ]];then
- # using find here, probably will need to also use it in usb part since the grep
- # method seems to not be working now. Slice off the rest, which leaves the basic path
- working_path=$( find $working_path/*/net/*/uevent 2>/dev/null | \
- sed 's|/net.*||' )
- fi
+ else
+ working_path=$( find -P /sys/ -type d -name "*:${a_network_adv_working[4]}" 2>/dev/null )
+ # just on off chance we get two returns, just one one
+ working_path=${working_path%% *}
+ fi
+ # sometimes there is another directory between the path and /net
+ if [[ -n $working_path && ! -e $working_path/net ]];then
+ # using find here, probably will need to also use it in usb part since the grep
+ # method seems to not be working now. Slice off the rest, which leaves the basic path
+ working_path=$( find $working_path/*/net/*/uevent 2>/dev/null | \
+ sed 's|/net.*||' )
fi
# working_path=$( ls /sys/devices/pci*/*/0000:${a_network_adv_working[4]}/net/*/uevent )
else
@@ -6469,7 +6507,6 @@ get_network_advanced_data()
product_path=$( grep -s "$usb_product" /sys/devices/pci*/*/usb*/*/*/idProduct | \
sed -e "s/idProduct:$usb_product//" -e '/driver/d' )
fi
-
# make sure it's the right product/vendor match here, it will almost always be but let's be sure
if [[ -n $working_path && -n $product_path ]] && [[ $working_path == $product_path ]];then
#if [[ -n $working_path ]];then
@@ -6487,50 +6524,90 @@ get_network_advanced_data()
a_network_adv_working[1]=$driver_test
fi
fi
+ #echo wp: $working_path
log_function_data "PRE: working_path: $working_path\nworking_uevent_path: $working_uevent_path"
-
# this applies in two different cases, one, default, standard, two, for usb, this is actually
# the short path, minus the last longer numeric directory name, ie:
# from debian squeeze 2.6.32-5-686:
# /sys/devices/pci0000:00/0000:00:0b.1/usb1/1-1/net/wlan0/address
if [[ -e $working_path/net ]];then
- if_path=$( ls $working_path/net 2>/dev/null )
- if_id=$if_path
- working_path=$working_path/net/$if_path
+ # in cases like infiniband dual port devices, there can be two ids, like ib0 ib1,
+ # with line break in output
+ if_data=$( ls $working_path/net 2>/dev/null )
+ b_path_made='false'
# this is the normal usb detection if the first one didn't work
elif [[ -n $usb_data && -e $working_uevent_path/net ]];then
- if_path=$( ls $working_uevent_path/net 2>/dev/null )
- if_id=$if_path
- working_path=$working_uevent_path/net/$if_path
+ if_data=$( ls $working_uevent_path/net 2>/dev/null )
+ working_path=$working_uevent_path/net/$if_data
# 2.6.32 debian lenny kernel shows not: /net/eth0 but /net:eth0
- else
- if_path=$( ls $working_path 2>/dev/null | grep 'net:' )
- if_id=$( cut -d ':' -f 2 <<< "$if_path" )
- working_path=$working_path/$if_path
- fi
- log_function_data "POST: working_path: $working_path\nif_path: $if_path - if_id: $if_id"
-
- if [[ -n $if_path ]];then
- if [[ -r $working_path/speed ]];then
- speed=$( cat $working_path/speed 2>/dev/null )
- fi
- if [[ -r $working_path/duplex ]];then
- duplex=$( cat $working_path/duplex 2>/dev/null )
- fi
- if [[ -r $working_path/address ]];then
- mac_id=$( cat $working_path/address 2>/dev/null )
- fi
- if [[ -r $working_path/operstate ]];then
- oper_state=$( cat $working_path/operstate 2>/dev/null )
+ elif [[ -n ${working_path/\/sys*/} ]];then
+ if_data=$( ls $working_path 2>/dev/null | grep 'net:' )
+ if [[ -n $if_data ]];then
+ working_path=$working_path/$if_data
+ # we won't be using this for path any more, just the actual if id output
+ # so prep it for the loop below
+ if_data=$( cut -d ':' -f 2 <<< "$if_data" )
+ fi
+ fi
+ # just in case we got a failed path, like /net or /, clear it out for tests below
+ if [[ -n ${working_path/\/sys*/} ]];then
+ working_path=''
+ fi
+ #echo id: $if_data
+ log_function_data "POST: working_path: $working_path\nif_data: $if_data - if_id: $if_id"
+ # there are virtual devices that will have no if data but which we still want in the array
+ # as it loops. These will also have null working_path as well since no **/net is found
+ # echo if_data: $if_data
+ if [[ -z $if_data ]];then
+ if_data='null-if-id'
+ fi
+ ## note: in cases of dual ports with different ids, this loop will create extra array items
+ for if_item in $if_data
+ do
+ chip_id=
+ duplex=''
+ full_path=''
+ if_id=''
+ mac_id=''
+ oper_state=''
+ speed=''
+ # strip out trailing spaces
+ if_item=${if_item%% }
+ #echo wp1: $working_path
+ if [[ $working_path != '' ]];then
+ if_id=$if_item
+ if [[ $b_path_made == 'false' ]];then
+ full_path=$working_path/net/$if_item
+ else
+ full_path=$working_path
+ fi
+ if [[ -r $full_path/speed ]];then
+ speed=$( cat $full_path/speed 2>/dev/null )
+ fi
+ if [[ -r $full_path/duplex ]];then
+ duplex=$( cat $full_path/duplex 2>/dev/null )
+ fi
+ if [[ -r $full_path/address ]];then
+ mac_id=$( cat $full_path/address 2>/dev/null )
+ fi
+ if [[ -r $full_path/operstate ]];then
+ oper_state=$( cat $full_path/operstate 2>/dev/null )
+ fi
+ if [[ -n ${a_network_adv_working[10]} ]];then
+ chip_id=${a_network_adv_working[10]}
+ fi
fi
- fi
-
- if [[ -n ${a_network_adv_working[10]} ]];then
- chip_id=${a_network_adv_working[10]}
- fi
- A_NETWORK_DATA[i]=${a_network_adv_working[0]}","${a_network_adv_working[1]}","${a_network_adv_working[2]}","${a_network_adv_working[3]}","${a_network_adv_working[4]}","$if_id","$oper_state","$speed","$duplex","$mac_id","$chip_id
- IFS="$ORIGINAL_IFS"
+
+ #echo fp: $full_path
+ #echo id: $if_id
+ # echo "$if_data ii: $if_item $array_counter i: $i"
+ A_NETWORK_DATA[$array_counter]=${a_network_adv_working[0]}","${a_network_adv_working[1]}","${a_network_adv_working[2]}","${a_network_adv_working[3]}","${a_network_adv_working[4]}","$if_id","$oper_state","$speed","$duplex","$mac_id","$chip_id
+
+ ((array_counter++))
+ done
done
+ a_temp=${A_NETWORK_DATA[@]}
+ log_function_data "A_NETWORK_DATA (advanced): $a_temp"
eval $LOGFE
}
@@ -6607,7 +6684,7 @@ get_networking_wan_ip_data()
# awk has bad regex handling so checking it with grep -E instead
# ip=$( echo 2001:0db8:85a3:0000:0000:8a2e:0370:7334 | gawk --re-interval '
# ip=$( wget -q -O - $WAN_IP_URL | gawk --re-interval '
- ip=$( wget -t 1 -T $WGET_TIMEOUT -q -O - $WAN_IP_URL | gawk --re-interval '
+ ip=$( wget -t 4 -T $WGET_TIMEOUT -q -O - $WAN_IP_URL | gawk --re-interval '
{
#gsub("\n","",$2")
print $NF
@@ -8033,6 +8110,534 @@ get_raid_component_data_bsd()
}
# get_raid_data_bsd;exit
+get_ram_data()
+{
+ eval $LOGFS
+
+ local a_temp='' array_string=''
+
+ get_dmidecode_data
+
+ if [[ -n $DMIDECODE_DATA ]];then
+ if [[ $DMIDECODE_DATA == 'dmidecode-error-'* ]];then
+ A_MEMORY_DATA[0]=$DMIDECODE_DATA
+ # please note: only dmidecode version 2.11 or newer supports consistently the -s flag
+ else
+ IFS=$'\n'
+ A_MEMORY_DATA=( $(
+ gawk -F ':' '
+ BEGIN {
+ IGNORECASE=1
+ arrayHandle=""
+ bankLocator=""
+ clockSpeed=""
+ configuredClockSpeed=""
+ dataWidth=""
+ deviceManufacturer=""
+ devicePartNumber=""
+ deviceSerialNumber=""
+ deviceSpeed=""
+ deviceType=""
+ deviceTypeDetail=""
+ deviceSize=""
+ errorCorrection=""
+ formFactor=""
+ handle=""
+ location=""
+ locator=""
+ aArrayData[0,"maxCapacity5"]=0
+ aArrayData[0,"maxCapacity16"]=0
+ aArrayData[0,"usedCapacity"]=0
+ aArrayData[0,"maxModuleSize"]=0
+ aArrayData[0,"derivedModuleSize"]=0
+ aArrayData[0,"deviceCount5"]=0
+ aArrayData[0,"deviceCount16"]=0
+ aArrayData[0,"deviceCountFound"]=0
+ aArrayData[0,"moduleVoltage5"]=""
+ moduleVoltage=""
+ numberOfDevices=""
+ primaryType=""
+ totalWidth=""
+ use=""
+ i=0
+ j=0
+ k=0
+ bDebugger1="false"
+ dDebugger2="false"
+ bType5="false"
+ }
+ function calculateSize(data,size) {
+ if ( data ~ /^[0-9]+[[:space:]]*[GMTP]B/) {
+ if ( data ~ /GB/ ) {
+ data=gensub(/([0-9]+)[[:space:]]*GB/,"\\1",1,data) * 1024
+ }
+ else if ( data ~ /MB/ ) {
+ data=gensub(/([0-9]+)[[:space:]]*MB/,"\\1",1,data)
+ }
+ else if ( data ~ /TB/ ) {
+ data=gensub(/([0-9]+)[[:space:]]*TB/,"\\1",1,data) * 1024 * 1000
+ }
+ else if ( data ~ /PB/ ) {
+ data=gensub(/([0-9]+)[[:space:]]*TB/,"\\1",1,data) * 1024 * 1000 * 1000
+ }
+ if (data ~ /^[0-9][0-9]+$/ && data > size ) {
+ size=data
+ }
+ }
+ return size
+ }
+ /^Table[[:space:]]+at[[:space:]]/ {
+ bType5="false"
+ # we need to start count here because for testing > 1 array, and we want always to have
+ # the actual module data assigned to the right primary array, even when it is out of
+ # position in dmidecode output
+ i=0
+ j=0
+ k++
+ }
+ # {print k ":k:" $0}
+ /^Handle .* DMI[[:space:]]+type[[:space:]]+5(,|[[:space:]])/ {
+ while ( getline && !/^$/ ) {
+ if ( $1 == "Maximum Memory Module Size" ) {
+ aArrayData[k,"maxModuleSize"]=calculateSize($2,aArrayData[k,"maxModuleSize"])
+ # print "mms:" aArrayData[k,"maxModuleSize"] ":" $2
+ }
+ if ($1 == "Maximum Total Memory Size") {
+ aArrayData[k,"maxCapacity5"]=calculateSize($2,aArrayData[k,"maxCapacity5"])
+ }
+ if ( $1 == "Memory Module Voltage" ) {
+ aArrayData[k,"moduleVoltage5"]=$2
+ }
+ }
+ aArrayData[k,"data-type"]="memory-array"
+ # print k ":data5:"aArrayData[k,"data-type"]
+ bType5="true"
+ }
+ /^Handle .* DMI[[:space:]]+type[[:space:]]+6(,|[[:space:]])/ {
+ while ( getline && !/^$/ ) {
+ if ( $1 == "Installed Size" ) {
+ # get module size
+ aMemory[k,j,18]=calculateSize($2,0)
+ # get data after module size
+ sub(/ Connection/,"",$2)
+ sub(/^[0-9]+[[:space:]]*[MGTP]B[[:space:]]*/,"",$2)
+ aMemory[k,j,16]=$2
+ }
+ if ( $1 == "Current Speed" ) {
+ aMemory[k,j,17]=$2
+ }
+ }
+ j++
+ }
+
+ /^Handle .* DMI[[:space:]]+type[[:space:]]+16/ {
+ arrayHandle=gensub(/Handle[[:space:]]([0-9a-zA-Z]+)([[:space:]]|,).*/,"\\1",$0)
+ while ( getline && !/^$/ ) {
+ # print $0
+ if ( $1 == "Maximum Capacity") {
+ aArrayData[k,"maxCapacity16"]=calculateSize($2,aArrayData[k,"maxCapacity16"])
+ #print "mc:" aArrayData[k,"maxCapacity16"] ":" $2
+ }
+ # note: these 3 have cleaned data in get_dmidecode_data, so replace stuff manually
+ if ( $1 == "Location") {
+ sub(/[[:space:]]Or[[:space:]]Motherboard/,"",$2)
+ location=$2
+ if ( location == "" ){
+ location="System Board"
+ }
+ }
+ if ( $1 == "Use") {
+ use=$2
+ if ( use == "" ){
+ use="System Memory"
+ }
+ }
+ if ( $1 == "Error Correction Type") {
+ errorCorrection=$2
+ if ( errorCorrection == "" ){
+ errorCorrection="None"
+ }
+ }
+ if ( $1 == "Number of Devices") {
+ numberOfDevices=$2
+ }
+ }
+ aArrayData[k,"data-type"]="memory-array"
+ # print k ":data16:"aArrayData[k,"data-type"]
+ aArrayData[k,"handle"]=arrayHandle
+ aArrayData[k,"location"]=location
+ aArrayData[k,"deviceCount16"]=numberOfDevices
+ aArrayData[k,"use"]=use
+ aArrayData[k,"errorCorrection"]=errorCorrection
+
+ # reset
+ primaryType=""
+ arrayHandle=""
+ location=""
+ numberOfDevices=""
+ use=""
+ errorCorrection=""
+ moduleVoltage=""
+
+ aDerivedModuleSize[k+1]=0
+ aArrayData[k+1,"deviceCountFound"]=0
+ aArrayData[k+1,"maxCapacity5"]=0
+ aArrayData[k+1,"maxCapacity16"]=0
+ aArrayData[k+1,"maxModuleSize"]=0
+ }
+ /^Handle .* DMI[[:space:]]+type[[:space:]]+17/ {
+ while ( getline && !/^$/ ) {
+ if ( $1 == "Array Handle") {
+ arrayHandle=$2
+ }
+ if ( $1 == "Data Width") {
+ dataWidth=$2
+ }
+ if ( $1 == "Total Width") {
+ totalWidth=$2
+ }
+ if ( $1 == "Size") {
+ # do not try to guess from installed modules, only use this to correct type 5 data
+ aArrayData[k,"derivedModuleSize"]=calculateSize($2,aArrayData[k,"derivedModuleSize"])
+ workingSize=calculateSize($2,0)
+ if ( workingSize ~ /^[0-9][0-9]+$/ ){
+ aArrayData[k,"deviceCountFound"]++
+ # build up actual capacity found for override tests
+ aArrayData[k,"usedCapacity"]=workingSize + aArrayData[k,"usedCapacity"]
+ }
+ # print aArrayData[k,"derivedModuleSize"] " dm:" k ":mm " aMaxModuleSize[k] " uc:" aArrayData[k,"usedCapacity"]
+ # we want any non real size data to be preserved
+ if ( $2 ~ /^[0-9]+[[:space:]]*[MTPG]B/ ) {
+ deviceSize=workingSize
+ }
+ else {
+ deviceSize=$2
+ }
+ }
+ if ( $1 == "Locator") {
+ # sub(/.*_/,"",$2)
+ #sub(/RAM slot #|^DIMM/, "Slot",$2)
+ sub(/RAM slot #/, "Slot",$2)
+
+ #locator=toupper($2)
+ locator=$2
+ }
+ if ( $1 == "Bank Locator") {
+ #sub(/_.*/,"",$2)
+ #sub(/RAM slot #|Channel|Chan/,"bank",$2)
+ #sub(/RAM slot #|Channel|Chan/,"bank",$2)
+ #bankLocator=toupper($2)
+ bankLocator=$2
+ }
+ if ( $1 == "Form Factor") {
+ formFactor=$2
+ }
+ if ( $1 == "Type") {
+ deviceType=$2
+ }
+ if ( $1 == "Type Detail") {
+ deviceTypeDetail=$2
+ }
+ if ( $1 == "Speed") {
+ deviceSpeed=$2
+ }
+ if ( $1 == "Configured Clock Speed") {
+ configuredClockSpeed=$2
+ }
+ if ( $1 == "Manufacturer") {
+ gsub(/(^[0]+$|Undefined.*|.*Manufacturer.*)/,"",$2)
+ deviceManufacturer=$2
+ }
+ if ( $1 == "Part Number") {
+ sub(/(^[0]+$||.*Module.*|Undefined.*)/,"",$2)
+ devicePartNumber=$2
+ }
+ if ( $1 == "Serial Number") {
+ gsub(/(^[0]+$|Undefined.*)/,"",$2)
+ deviceSerialNumber=$2
+ }
+ }
+ # because of the wide range of bank/slot type data, we will just use
+ # the one that seems most likely to be right. Some have: Bank: SO DIMM 0 slot: J6A
+ # so we dump the useless data and use the one most likely to be visibly correct
+ if ( bankLocator ~ /DIMM/ ) {
+ mainLocator=bankLocator
+ }
+ else {
+ mainLocator=locator
+ }
+ # sometimes the data is just wrong, they reverse total/data. data I believe is
+ # used for the actual memory bus width, total is some synthetic thing, sometimes missing.
+ # note that we do not want a regular string comparison, because 128 bit memory buses are
+ # in our future, and 128 bits < 64 bits with string compare
+ intData=gensub(/(^[0-9]+).*/,"\\1",1,dataWidth)
+ intTotal=gensub(/(^[0-9]+).*/,"\\1",1,totalWidth)
+ if (intData != "" && intTotal != "" && intData > intTotal ) {
+ tempWidth=dataWidth
+ dataWidth=totalWidth
+ totalWidth=tempWidth
+ }
+
+ aMemory[k,i,0]="memory-device"
+ aMemory[k,i,1]=arrayHandle
+ aMemory[k,i,2]=deviceSize
+ aMemory[k,i,3]=bankLocator
+ aMemory[k,i,4]=locator
+ aMemory[k,i,5]=formFactor
+ aMemory[k,i,6]=deviceType
+ aMemory[k,i,7]=deviceTypeDetail
+ aMemory[k,i,8]=deviceSpeed
+ aMemory[k,i,9]=configuredClockSpeed
+ aMemory[k,i,10]=dataWidth
+ aMemory[k,i,11]=totalWidth
+ aMemory[k,i,12]=deviceManufacturer
+ aMemory[k,i,13]=devicePartNumber
+ aMemory[k,i,14]=deviceSerialNumber
+ aMemory[k,i,15]=mainLocator
+
+ primaryType=""
+ arrayHandle=""
+ deviceSize=""
+ bankLocator=""
+ locator=""
+ mainLocator=""
+ mainLocator=""
+ formFactor=""
+ deviceType=""
+ deviceTypeDetail=""
+ deviceSpeed=""
+ configuredClockSpeed=""
+ dataWidth=""
+ totalWidth=""
+ deviceManufacturer=""
+ devicePartNumber=""
+ deviceSerialNumber=""
+ i++
+ }
+ END {
+ ## CRITICAL: gawk keeps changing integers to strings, so be explicit with int() in math
+ # print primaryType "," arrayHandle "," location "," maxCapacity "," numberOfDevices "," use "," errorCorrection "," maxModuleSize "," moduleVoltage
+
+ # print primaryType "," arrayHandle "," deviceSize "," bankLocator "," locator "," formFactor "," deviceType "," deviceTypeDetail "," deviceSpeed "," configuredClockSpeed "," dataWidth "," totalWidth "," deviceManufacturer "," devicePartNumber "," deviceSerialNumber "," mainLocator
+
+ for ( m=1;m<=k;m++ ) {
+ estCap=""
+ estMod=""
+ unit=""
+ altCap=0
+ workingMaxCap=int(aArrayData[m,"maxCapacity16"])
+
+ if ( bDebugger1 == "true" ){
+ print ""
+ print "count: " m
+ print "1: mmods: " aArrayData[m,"maxModuleSize"] " :dmmods: " aArrayData[m,"derivedModuleSize"] " :mcap: " workingMaxCap " :ucap: " aArrayData[m,"usedCapacity"]
+ }
+ # 1: if max cap 1 is null, and max cap 2 not null, use 2
+ if ( workingMaxCap == 0 ) {
+ if ( aArrayData[m,"maxCapacity5"] != 0 ) {
+ workingMaxCap=aArrayData[m,"maxCapacity5"]
+ }
+ }
+ if ( aArrayData[m,"deviceCount16"] == "" ) {
+ aArrayData[m,"deviceCount16"] = 0
+ }
+ if ( bDebugger1 == "true" ){
+ print "2: mmods: " aArrayData[m,"maxModuleSize"] " :dmmods: " aArrayData[m,"derivedModuleSize"] " :mcap: " workingMaxCap " :ucap: " aArrayData[m,"usedCapacity"]
+ }
+ # 2: now check to see if actually found module sizes are > than listed max module, replace if >
+ if (aArrayData[m,"maxModuleSize"] != 0 && aArrayData[m,"derivedModuleSize"] != 0 && int(aArrayData[m,"derivedModuleSize"]) > int(aArrayData[m,"maxModuleSize"]) ) {
+ aArrayData[m,"maxModuleSize"]=aArrayData[m,"derivedModuleSize"]
+ estMod=" (est)"
+ }
+ aArrayData[m,"maxModuleSize"]=int(aArrayData[m,"maxModuleSize"])
+ aArrayData[m,"derivedModuleSize"]=int(aArrayData[m,"derivedModuleSize"])
+ aArrayData[m,"usedCapacity"]=int(aArrayData[m,"usedCapacity"])
+ workingMaxCap=int(workingMaxCap)
+
+ # note: some cases memory capacity == max module size, so one stick will fill it
+ # but I think only with cases of 2 slots does this happen, so if > 2, use the count of slots.
+ if ( bDebugger1 == "true" ){
+ print "3: fmod: " aArrayData[m,"deviceCountFound"] " :modc: " aArrayData[m,"deviceCount16"] " :maxc1: " aArrayData[m,"maxCapacity5"] " :maxc2: " aArrayData[m,"maxCapacity16"]
+ }
+ if (workingMaxCap != 0 && ( aArrayData[m,"deviceCountFound"] != 0 || aArrayData[m,"deviceCount16"] != 0 ) ) {
+ aArrayData[m,"deviceCount16"]=int(aArrayData[m,"deviceCount16"])
+ ## first check that actual memory found is not greater than listed max cap, or
+ ## checking to see module count * max mod size is not > used capacity
+ if ( aArrayData[m,"usedCapacity"] != 0 && aArrayData[m,"maxCapacity16"] != 0 ) {
+ if ( aArrayData[m,"usedCapacity"] > workingMaxCap ) {
+ if ( aArrayData[m,"maxModuleSize"] != 0 &&
+ aArrayData[m,"usedCapacity"] < aArrayData[m,"deviceCount16"] * aArrayData[m,"maxModuleSize"] ) {
+ workingMaxCap=aArrayData[m,"deviceCount16"] * aArrayData[m,"maxModuleSize"]
+ estCap=" (est)"
+ if ( bDebugger1 == "true" ){
+ print "A"
+ }
+ }
+ else if ( aArrayData[m,"derivedModuleSize"] != 0 &&
+ aArrayData[m,"usedCapacity"] < aArrayData[m,"deviceCount16"] * aArrayData[m,"derivedModuleSize"] ) {
+ workingMaxCap=aArrayData[m,"deviceCount16"] * aArrayData[m,"derivedModuleSize"]
+ estCap=" (est)"
+ if ( bDebugger1 == "true" ){
+ print "B"
+ }
+ }
+ else {
+ workingMaxCap=aArrayData[m,"usedCapacity"]
+ estCap=" (est)"
+ if ( bDebugger1 == "true" ){
+ print "C"
+ }
+ }
+ }
+ }
+ # note that second case will never really activate except on virtual machines and maybe
+ # mobile devices
+ if ( estCap == "" ) {
+ # do not do this for only single modules found, max mod size can be equal to the array size
+ if ( ( aArrayData[m,"deviceCount16"] > 1 && aArrayData[m,"deviceCountFound"] > 1 ) &&
+ ( workingMaxCap < aArrayData[m,"derivedModuleSize"] * aArrayData[m,"deviceCount16"] ) ) {
+ workingMaxCap = aArrayData[m,"derivedModuleSize"] * aArrayData[m,"deviceCount16"]
+ estCap=" (est)"
+ if ( bDebugger1 == "true" ){
+ print "D"
+ }
+ }
+ else if ( ( aArrayData[m,"deviceCountFound"] > 0 ) &&
+ ( workingMaxCap < aArrayData[m,"derivedModuleSize"] * aArrayData[m,"deviceCountFound"] ) ) {
+ workingMaxCap = aArrayData[m,"derivedModuleSize"] * aArrayData[m,"deviceCountFound"]
+ estCap=" (est)"
+ if ( bDebugger1 == "true" ){
+ print "E"
+ }
+ }
+ ## handle cases where we have type 5 data: mms x device count equals type 5 max cap
+ # however do not use it if cap / devices equals the derived module size
+ else if ( aArrayData[m,"maxModuleSize"] > 0 &&
+ ( aArrayData[m,"maxModuleSize"] * aArrayData[m,"deviceCount16"] == aArrayData[m,"maxCapacity5"] ) &&
+ aArrayData[m,"maxCapacity5"] != aArrayData[m,"maxCapacity16"] &&
+ aArrayData[m,"maxCapacity16"] / aArrayData[m,"deviceCount16"] != aArrayData[m,"derivedModuleSize"] ) {
+ workingMaxCap = aArrayData[m,"maxCapacity5"]
+ altCap=aArrayData[m,"maxCapacity5"] # not used
+ estCap=" (check)"
+ if ( bDebugger1 == "true" ){
+ print "F"
+ }
+ }
+ }
+ }
+ altCap=int(altCap)
+ workingMaxCap=int(workingMaxCap)
+ if ( bDebugger1 == "true" ){
+ print "4: mmods: " aArrayData[m,"maxModuleSize"] " :dmmods: " aArrayData[m,"derivedModuleSize"] " :mcap: " workingMaxCap " :ucap: " aArrayData[m,"usedCapacity"]
+ }
+ # some cases of type 5 have too big module max size, just dump the data then since
+ # we cannot know if it is valid or not, and a guess can be wrong easily
+ if ( aArrayData[m,"maxModuleSize"] != 0 && workingMaxCap != "" &&
+ ( aArrayData[m,"maxModuleSize"] > workingMaxCap ) ){
+ aArrayData[m,"maxModuleSize"] = 0
+ # print "yes"
+ }
+ if ( bDebugger1 == "true" ){
+ print "5: dms: " aArrayData[m,"derivedModuleSize"] " :dc: " aArrayData[m,"deviceCount16"] " :wmc: " workingMaxCap
+ }
+ ## prep for output ##
+ if (aArrayData[m,"maxModuleSize"] == 0 ){
+ aArrayData[m,"maxModuleSize"]=""
+ # ie: 2x4gB
+ if ( estCap == "" && int(aArrayData[m,"derivedModuleSize"]) > 0 &&
+ workingMaxCap > ( int(aArrayData[m,"derivedModuleSize"]) * int(aArrayData[m,"deviceCount16"]) * 4 ) ) {
+ estCap=" (check)"
+ if ( bDebugger1 == "true" ){
+ print "G"
+ }
+ }
+ }
+ else {
+ # case where listed max cap is too big for actual slots x max cap, eg:
+ # listed max cap, 8gb, max mod 2gb, slots 2
+ if ( estCap == "" && aArrayData[m,"maxModuleSize"] > 0 ) {
+ if ( int(workingMaxCap) > int(aArrayData[m,"maxModuleSize"]) * aArrayData[m,"deviceCount16"] ) {
+ estCap=" (check)"
+ if ( bDebugger1 == "true" ){
+ print "H"
+ }
+ }
+ }
+ if (aArrayData[m,"maxModuleSize"] > 1023 ) {
+ aArrayData[m,"maxModuleSize"]=aArrayData[m,"maxModuleSize"] / 1024 " GB"
+ }
+ else {
+ aArrayData[m,"maxModuleSize"]=aArrayData[m,"maxModuleSize"] " MB"
+ }
+ }
+ if ( aArrayData[m,"deviceCount16"] == 0 ) {
+ aArrayData[m,"deviceCount16"] = ""
+ }
+ if (workingMaxCap != 0 ) {
+ if ( workingMaxCap < 1024 ) {
+ workingMaxCap = workingMaxCap
+ unit=" MB"
+ }
+ else if ( workingMaxCap < 1024000 ) {
+ workingMaxCap = workingMaxCap / 1024
+ unit=" GB"
+ }
+ else if ( workingMaxCap < 1024000000 ) {
+ workingMaxCap = workingMaxCap / 1024000
+ unit=" TB"
+ }
+ # we only want a max 2 decimal places, this trick gives 0 to 2
+ workingMaxCap=gensub(/([0-9]+\.[0-9][0-9]).*/,"\\1",1,workingMaxCap)
+ workingMaxCap = workingMaxCap unit estCap
+
+ }
+ else {
+ workingMaxCap == ""
+ }
+
+ print aArrayData[m,"data-type"] "," aArrayData[m,"handle"] "," aArrayData[m,"location"] "," workingMaxCap "," aArrayData[m,"deviceCount16"] "," aArrayData[m,"use"] "," aArrayData[m,"errorCorrection"] "," aArrayData[m,"maxModuleSize"] estMod "," aArrayData[m,"voltage5"]
+ # print device rows next
+ for ( j=0;j<=100;j++ ) {
+ if (aMemory[m,j,0] != "" ) {
+ unit=""
+ workingSize=aMemory[m,j,2]
+ if ( workingSize ~ /^[0-9]+$/ ) {
+ workingSize=int(workingSize)
+ if ( workingSize < 1024 ) {
+ workingSize = workingSize
+ unit=" MB"
+ }
+ else if ( workingSize < 1024000 ) {
+ workingSize = workingSize / 1024
+ unit=" GB"
+ }
+ else if ( workingSize < 1024000000 ) {
+ workingSize = workingSize / 1024000
+ unit=" TB"
+ }
+ # we only want a max 2 decimal places, this trick gives 0 to 2
+ workingSize=gensub(/([0-9]+\.[0-9][0-9]).*/,"\\1",1,workingSize)
+ workingSize = workingSize unit
+ }
+ print aMemory[m,j,0] "," aMemory[m,j,1] "," workingSize "," aMemory[m,j,3] "," aMemory[m,j,4] "," aMemory[m,j,5] "," aMemory[m,j,6] "," aMemory[m,j,7] "," aMemory[m,j,8] "," aMemory[m,j,9] "," aMemory[m,j,10] "," aMemory[m,j,11] "," aMemory[m,j,12] "," aMemory[m,j,13] "," aMemory[m,j,14] "," aMemory[m,j,15] "," aMemory[m,j,16] "," aMemory[m,j,17]
+ }
+ else {
+ break
+ }
+ }
+ }
+ }' <<< "$DMIDECODE_DATA" ) )
+ fi
+ fi
+ IFS="$ORIGINAL_IFS"
+ a_temp=${A_MEMORY_DATA[@]}
+
+ # echo "${a_temp[@]}"
+ log_function_data "A_MEMORY_DATA: $a_temp"
+
+ eval $LOGFE
+}
+
# Repos will be added as we get distro package manager data to create the repo data.
# This method will output the file name also, which is useful to create output that's
# neat and readable. Each line of the total number contains the following sections,
@@ -9385,7 +9990,7 @@ print_it_out()
print_cpu_data
fi
if [[ $B_SHOW_MEMORY == 'true' ]];then
- print_memory_data
+ print_ram_data
fi
if [[ $B_SHOW_GRAPHICS == 'true' ]];then
print_graphics_data
@@ -9915,6 +10520,32 @@ print_cpu_flags_full()
eval $LOGFE
}
+# args: $1 - type [sys/default]; $2 - get_dmidecode_data error return
+print_dmidecode_error()
+{
+ eval $LOGFS
+ local error_message='Unknown dmidecode error.'
+ local sysDmiError='Using '
+
+ if [[ $1 == 'sys' ]];then
+ sysDmiError='No /sys/class/dmi; using '
+ fi
+ if [[ $B_FORCE_DMIDECODE == 'true' && $1 == 'sys' ]];then
+ sysDmiError='Forcing '
+ fi
+ if [[ $2 == 'dmidecode-error-requires-root' ]];then
+ error_message="${sysDmiError}dmidecode: you must be root to run dmidecode"
+ elif [[ $2 == 'dmidecode-error-not-installed' ]];then
+ error_message="${sysDmiError}dmidecode: dmidecode is not installed."
+ elif [[ $2 == 'dmidecode-error-no-smbios-dmi-data' ]];then
+ error_message="${sysDmiError}dmidecode: no smbios data available. Old system?"
+ elif [[ $2 == 'dmidecode-error-unknown-error' ]];then
+ error_message="${sysDmiError}dmidecode: unknown error occured"
+ fi
+ echo $error_message
+ eval $LOGFE
+}
+
print_graphics_data()
{
eval $LOGFS
@@ -10330,7 +10961,7 @@ print_info_data()
if [[ $shell_parent == 'login' ]];then
shell_parent=''
elif [[ -n $shell_parent ]];then
- shell_parent=" running in $shell_parent"
+ shell_parent=" running in ${shell_parent##*/}"
fi
fi
IRC_CLIENT="$IRC_CLIENT ($shell_data$shell_parent)"
@@ -10432,20 +11063,14 @@ print_machine_data()
local system_line='' mobo_line='' bios_line='' chassis_line=''
local mobo_vendor='' mobo_model='' mobo_version='' mobo_serial=''
- local bios_vendor='' bios_version='' bios_date='' bios_rom=''
+ local bios_vendor='' bios_version='' bios_date='' bios_rom='' error_string=''
local system_vendor='' product_name='' product_version='' product_serial='' product_uuid=''
local chassis_vendor='' chassis_type='' chassis_version='' chassis_serial=''
local b_skip_system='false' b_skip_chassis='false'
- local sysDmiError='No /sys/class/dmi, using '
local sysDmiNull='No /sys/class/dmi machine data: try newer kernel, or install dmidecode'
# set A_MACHINE_DATA
get_machine_data
- if [[ -n $BSD_TYPE || $B_FORCE_DMIDECODE == 'true' ]];then
- sysDmiError=''
- sysDmiNull='No machine data available. Is dmidecode installed?'
- fi
-
IFS=','
## keys for machine data are:
# 0-sys_vendor 1-product_name 2-product_version 3-product_serial 4-product_uuid
@@ -10453,8 +11078,8 @@ print_machine_data()
# 9-bios_vendor 10-bios_version 11-bios_date
## with extra data:
# 12-chassis_vendor 13-chassis_type 14-chassis_version 15-chassis_serial
-
- if [[ ${#A_MACHINE_DATA[@]} -gt 0 ]];then
+ # a null array always has a count of 1
+ if [[ ${#A_MACHINE_DATA[@]} -gt 1 ]];then
# note: in some case a mobo/version will match a product name/version, do not print those
# but for laptops, or even falsely id'ed desktops with batteries, let's print it all if it matches
# there can be false id laptops if battery appears so need to make sure system is filled
@@ -10566,18 +11191,14 @@ print_machine_data()
chassis_line=''
fi
fi
- IFS="$ORIGINAL_IFS"
else
system_line="${C2}$sysDmiNull"
fi
- # patch to dump all of above if dmidecode was data source and non root user
- if [[ ${A_MACHINE_DATA[0]} == 'dmidecode-non-root-user' || \
- ${A_MACHINE_DATA[0]} == 'dmidecode-no-smbios-dmi-data' ]];then
- if [[ ${A_MACHINE_DATA[0]} == 'dmidecode-non-root-user' ]];then
- system_line="${C2}${sysDmiError}dmidecode: you must be root to run dmidecode"
- elif [[ ${A_MACHINE_DATA[0]} == 'dmidecode-no-smbios-dmi-data' ]];then
- system_line="${C2}${sysDmiError}dmidecode: no machine data available"
- fi
+ IFS="$ORIGINAL_IFS"
+ # patch to dump all of above if dmidecode was data source and a dmidecode error is present
+ if [[ ${A_MACHINE_DATA[0]} == 'dmidecode-error-'* ]];then
+ error_string=$( print_dmidecode_error 'sys' "${A_MACHINE_DATA[0]}" )
+ system_line=${C2}$error_string
mobo_line=''
bios_line=''
chassis_line=''
@@ -10600,26 +11221,6 @@ print_machine_data()
eval $LOGFE
}
-print_memory_data()
-{
- eval $LOGFS
- local memory_line="${C1}Placeholder$SEP3${C2} Feature not yet developed"
-
- memory_line=$( create_print_line "Memory:" "$memory_line${CN}" )
- print_screen_output "$memory_line"
-
- if [[ ${A_MEMORY_DATA[0]} == 'dmidecode-non-root-user' || \
- ${A_MEMORY_DATA[0]} == 'dmidecode-no-smbios-dmi-data' ]];then
- if [[ ${A_MEMORY_DATA[0]} == 'dmidecode-non-root-user' ]];then
- memory_line="${C2}${sysDmiError}dmidecode: you must be root to run dmidecode"
- elif [[ ${A_MEMORY_DATA[0]} == 'dmidecode-no-smbios-dmi-data' ]];then
- memory_line="${C2}${sysDmiError}dmidecode: no machine data available"
- fi
- fi
-
- eval $LOGFE
-}
-
# args: $1 - module name (could be > 1, so loop it ); $2 - audio (optional)
print_module_version()
{
@@ -11632,6 +12233,240 @@ print_raid_data()
eval $LOGFE
}
+print_ram_data()
+{
+ eval $LOGFS
+ local memory_line='' line_2='' line_3='' b_module_present='true'
+ local error_string='' a_memory_item='' line_starter='Memory:' array_counter=1 device_counter=1
+ local dmidecodeNull='No dmidecode memory data: try newer kernel.'
+
+ local manufacturer='' part_nu='' serial_nu='' device_speed='' configured_speed='' bus_width=
+ local data_width='' total_width='' device_type='' device_type_detail='' bank='' slot='' form_factor=''
+ local device_size='' array_use='' location='' error_correction='' max_capacity='' nu_of_devices=''
+ local max_module_size='' module_voltage='' bank_connection=''
+
+ get_ram_data
+ #echo ${#A_MEMORY_DATA[@]}
+ #echo ${A_MEMORY_DATA[0]}
+ if [[ ${#A_MEMORY_DATA[@]} -gt 0 ]];then
+ if [[ ${A_MEMORY_DATA[0]} == 'dmidecode-error-'* ]];then
+ error_string=$( print_dmidecode_error 'default' "${A_MEMORY_DATA[0]}" )
+ memory_line="${C2}$error_string"
+ else
+ for (( i=0;i<${#A_MEMORY_DATA[@]};i++ ))
+ do
+ IFS=','
+ a_memory_item=(${A_MEMORY_DATA[i]})
+ IFS="$ORIGINAL_IFS"
+ memory_line=''
+ line_2=''
+ line_3=''
+ bus_width=''
+ data_width=
+ total_width=
+ part_nu=''
+ serial_nu=''
+ manufacturer=''
+ max_module_size=''
+ module_voltage=''
+ bank_connection=''
+ # memory-array,0x0012,System Board,8 GB,4,System Memory,None,max size,moudule voltage
+ if [[ ${a_memory_item[0]} == 'memory-array' ]];then
+ if [[ -n ${a_memory_item[4]} ]];then
+ nu_of_devices=${a_memory_item[4]}
+ else
+ nu_of_devices='N/A'
+ fi
+ if [[ -n ${a_memory_item[3]} ]];then
+ max_capacity=${a_memory_item[3]}
+ else
+ max_capacity='N/A'
+ fi
+ if [[ -n ${a_memory_item[6]} ]];then
+ error_correction=${a_memory_item[6]}
+ else
+ error_correction='N/A'
+ fi
+ if [[ $B_EXTRA_DATA == 'true' ]];then
+ if [[ -n ${a_memory_item[7]} ]];then
+ max_module_size="${C1}max module size${SEP3}${C2} ${a_memory_item[7]} "
+ fi
+ fi
+ if [[ $B_EXTRA_EXTRA_EXTRA_DATA == 'true' ]];then
+ if [[ -n ${a_memory_item[8]} ]];then
+ module_voltage="${C1}module voltage$SEP3${C2} ${a_memory_item[8]}"
+ fi
+ fi
+ memory_line="${C1}Array-$array_counter capacity$SEP3${C2} $max_capacity ${C1}devices$SEP3${C2} $nu_of_devices ${C1}EC$SEP3${C2} $error_correction "
+ line_2="$max_module_size$module_voltage"
+ if [[ -n $line_2 && $( calculate_line_length "$memory_line$line_2" ) -gt $COLS_INNER ]];then
+ memory_line=$( create_print_line "$line_starter" "$memory_line${CN}" )
+ print_screen_output "$memory_line"
+ memory_line="$line_2"
+ line_starter=' '
+ line_2=''
+ else
+ memory_line="$memory_line$line_2"
+ line_2=''
+ fi
+ (( array_counter++ ))
+ device_counter=1 # reset so device matches device count per array
+ else
+ # not used for now
+# if [[ -n ${a_memory_item[3333]} ]];then
+# if [[ -z ${a_memory_item[3]/BANK*/} ]];then
+# #bank=${a_memory_item[3]#BANK}
+# bank=${a_memory_item[3]}
+# bank=${bank## }
+# else
+# bank=${a_memory_item[3]}
+# fi
+# else
+# bank='N/A'
+# fi
+# # not used for now
+# if [[ -n ${a_memory_item[44444]} ]];then
+# if [[ -z ${a_memory_item[4]/SLOT*/} ]];then
+# #slot=${a_memory_item[4]#SLOT}
+# slot=${a_memory_item[4]}
+# slot=${slot## }
+# else
+# slot=${a_memory_item[4]}
+# fi
+# else
+# slot='N/A'
+# fi
+ if [[ -n ${a_memory_item[15]} ]];then
+ locator=${a_memory_item[15]}
+ locator=${locator## }
+ else
+ locator='N/A'
+ fi
+ if [[ -n ${a_memory_item[2]} ]];then
+ device_size=${a_memory_item[2]}
+ if [[ $device_size == 'No Module Installed' ]];then
+ b_module_present='false'
+ else
+ b_module_present='true'
+ fi
+ else
+ device_size='N/A'
+ fi
+ if [[ -n ${a_memory_item[6]} ]];then
+ device_type=${a_memory_item[6]}
+ if [[ $B_EXTRA_EXTRA_EXTRA_DATA == 'true' && -n ${a_memory_item[7]} \
+ && ${a_memory_item[7]} != 'Other' ]];then
+ device_type="$device_type (${a_memory_item[7]})"
+ fi
+ else
+ device_type='N/A'
+ fi
+ device_type="${C1}type$SEP3${C2} $device_type "
+ if [[ -n ${a_memory_item[8]} ]];then
+ if [[ -n ${a_memory_item[9]} ]];then
+ device_speed=${a_memory_item[9]}
+ else
+ device_speed=${a_memory_item[8]}
+ fi
+ else
+ device_speed='N/A'
+ fi
+ if [[ $b_module_present == 'true' ]];then
+ device_speed="${C1}speed$SEP3${C2} $device_speed "
+ else
+ device_speed=''
+ fi
+ # memory-device,0x002C,8192 MB,ChannelD,ChannelD_Dimm2,DIMM,DDR3,Synchronous,2400 MHz,2400 MHz,64 bits,64 bits,Undefined,F3-19200C10-8GBZH,00000000
+ if [[ $b_module_present == 'true' ]];then
+ if [[ $B_EXTRA_DATA == 'true' ]];then
+ if [[ -n ${a_memory_item[13]} ]];then
+ part_nu=${a_memory_item[13]}
+ else
+ part_nu='N/A'
+ fi
+ part_nu="${C1}part$SEP3${C2} $part_nu "
+ fi
+ if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
+ if [[ -n ${a_memory_item[12]} ]];then
+ manufacturer=${a_memory_item[12]}
+ else
+ manufacturer='N/A'
+ fi
+ manufacturer="${C1}manufacturer$SEP3${C2} $manufacturer "
+ if [[ -n ${a_memory_item[14]} ]];then
+ serial_nu=${a_memory_item[14]}
+ else
+ serial_nu='N/A'
+ fi
+ serial_nu="${C1}serial$SEP3${C2} $serial_nu "
+
+ if [[ $device_size != 'N/A' && -n ${a_memory_item[16]} ]];then
+ bank_connection=" ${a_memory_item[16]}"
+ fi
+ fi
+ fi
+ if [[ $B_EXTRA_EXTRA_EXTRA_DATA == 'true' ]];then
+ if [[ $b_module_present == 'true' ]] || \
+ [[ -n ${a_memory_item[11]} || -n ${a_memory_item[10]} ]];then
+ # only create this if the total exists and is > data width
+ if [[ -n ${a_memory_item[10]/ bits/} && -n ${a_memory_item[11]/ bits} && \
+ ${a_memory_item[11]/ bits/} -gt ${a_memory_item[10]/ bits/} ]];then
+ total_width=" (total$SEP3 ${a_memory_item[11]})"
+ fi
+ if [[ -n ${a_memory_item[10]} ]];then
+ data_width=${a_memory_item[10]}
+ else
+ data_width='N/A'
+ fi
+ bus_width="${C1}bus width$SEP3${C2} $data_width$total_width "
+ fi
+ fi
+ memory_line="${C1}Device-$device_counter$SEP3${C2} $locator ${C1}size$SEP3${C2} $device_size$bank_connection $device_speed"
+ if [[ $( calculate_line_length "$memory_line$device_type" ) -le $COLS_INNER ]];then
+ memory_line="$memory_line$device_type"
+ device_type=''
+ fi
+ line_3="$manufacturer$part_nu$serial_nu"
+ line_2="$device_type$bus_width"
+ # echo $( calculate_line_length "$memory_line" )
+ # echo $( calculate_line_length "$memory_line$line_2" )
+ if [[ $( calculate_line_length "$memory_line$line_2$line_3" ) -gt $COLS_INNER ]];then
+ memory_line=$( create_print_line "$line_starter" "$memory_line${CN}" )
+ print_screen_output "$memory_line"
+ memory_line="$line_2"
+ line_starter=' '
+ if [[ -n $memory_line && -n $line_3 && $( calculate_line_length "$memory_line$line_3" ) -gt $COLS_INNER ]];then
+ memory_line=$( create_print_line "$line_starter" "$memory_line${CN}" )
+ print_screen_output "$memory_line"
+ memory_line="$line_3"
+ else
+ memory_line="$memory_line$line_3"
+ fi
+ else
+ memory_line="$memory_line$line_2$line_3"
+ fi
+ (( device_counter++ ))
+ fi
+ memory_line=$( create_print_line "$line_starter" "$memory_line${CN}" )
+ print_screen_output "$memory_line"
+ line_starter=' '
+ done
+ memory_line=' '
+ fi
+ else
+ memory_line="${C2}$dmidecodeNull"
+ fi
+ IFS="$ORIGINAL_IFS"
+ memory_line=${memory_line## }
+ if [[ -n $memory_line ]];then
+ memory_line=$( create_print_line "$line_starter" "$memory_line${CN}" )
+ print_screen_output "$memory_line"
+ fi
+
+ eval $LOGFE
+}
+
+
# currently only apt using distros support this feature, but over time we can add others
print_repo_data()
{
diff --git a/inxi.1 b/inxi.1
index 1789874..7476fdf 100755
--- a/inxi.1
+++ b/inxi.1
@@ -1,10 +1,10 @@
-.TH INXI 1 "2014\-05\-01" inxi "inxi manual"
+.TH INXI 1 "2014\-08\-16" inxi "inxi manual"
.SH NAME
inxi \- Command line system information script for console and IRC
.SH SYNOPSIS
.B inxi \fR \- Single line, short form. Very basic output.
-.B inxi \fR[\fB\-AbCdDfFGhHiIlMnNopPrRsSuw\fR] \fR[\fB\-c NUMBER\fR] \fR[\fB\-v NUMBER\fR]
+.B inxi \fR[\fB\-AbCdDfFGhHiIlmMnNopPrRsSuw\fR] \fR[\fB\-c NUMBER\fR] \fR[\fB\-v NUMBER\fR]
.B inxi \fR[\fB\-t \fR(\fBc\fR or\fB m\fR or\fB cm\fR or\fB mc NUMBER\fR)] \fR[\fB\-x \-OPTION\fR(\fBs\fR)] \fR[\fB\-xx \-OPTION\fR(\fBs\fR)] \fR[\fB\-xxx \-OPTION\fR(\fBs\fR)]
@@ -93,8 +93,8 @@ spamming. ARM cpus: show \fBfeatures\fR items.
.TP
.B \-F
Show Full output for inxi. Includes all Upper Case line letters, plus \fB\-s\fR and \fB\-n\fR.
-Does not show extra verbose options like \fB\-x \-d \-f \-u \-l \-o \-p \-t \-r\fR unless you use
-that argument.
+Does not show extra verbose options like \fB\-d \-f \-l \-m \-o \-p \-r \-t \-u \-x\fR unless you use
+those arguments in the command, like: \fBinxi \-Frmxx\fR
.TP
.B \-G
Show Graphic card information. Card(s), Display Server (vendor and version number), for example:
@@ -125,6 +125,13 @@ See \fB\-x\fR and \fB\-xx\fR for extra information (init type/version, runlevel)
.B \-l
Show partition labels. Default: short partition \fB\-P\fR. For full \fB\-p\fR output, use: \fB\-pl\fR (or \fB\-plu\fR).
.TP
+.B \-m
+Memory (RAM) data. Does not show with \fB\-b\fR or \fB\-F\fR unless you use \fB\-m\fR explicitly. Ordered by system board physical system memory array(s) (\fBArray\-[number] capacity:\fR), and individual memory devices (\fBDevice\-[number]\fR). Physical memory array(s) data shows array capacity, and number of devices supported, and Error Correction information. Devices shows locator data (highly variable in syntax), size, speed, type (eg: \fBtype: DDR3\fR).
+
+Note that \fB\-m\fR uses \fBdmidecode\fR, which must be run as root (or start \fBinxi\fR with \fBsudo\fR), unless you figure out how to set up sudo to permit dmidecode to read \fB/dev/mem\fR as user. Note that speed will not show if \fBNo Module Installed\fR is found in size. This will also turn off Bus Width data output if it is null.
+
+Because dmidecode data is extremely unreliable, inxi will try to make best guesses. If you see \fB(check)\fR after capacity number, you should check it for sure with specifications. \fB(est)\fR is slightly more reliable, but you should still check the real specifications before buying ram. Unfortunately there is nothing \fBinxi can do to get truly reliable data about the system ram, maybe one day the kernel devs will put this data into \fB/sys\fR, and make it real data, taken from the actual system, not dmi data. For most people, the data will be right, but a significant percentage of users will have either wron max module size, if present, or max capacity.
+.TP
.B \-M
Show machine data. Motherboard, Bios, and if present, System Builder (Like Lenovo).
Older systems/kernels without the required \fB/sys\fR data can use dmidecode instead, run as root. If using dmidecode,
@@ -241,7 +248,7 @@ Supported levels: \fB0\-7\fR Examples :\fB inxi \-v 4 \fR or \fB inxi \-v4\fR
Shows full disk data (\fB\-D\fR)
.TP
.B \-v 5
-\- Adds audio card (\fB\-A\fR); sensors (\fB\-s\fR), partition label (\fB\-l\fR) and UUID (\fB\-u\fR), short form of
+\- Adds audio card (\fB\-A\fR); memory/ram (\fB\-m\fR);sensors (\fB\-s\fR), partition label (\fB\-l\fR) and UUID (\fB\-u\fR), short form of
optical drives.
.TP
.B \-v 6
@@ -326,6 +333,12 @@ version number, if available.
.B \-x \-I
\- If in shell (not in IRC client, that is), show shell version number (if available).
.TP
+.B \-x \-m
+\- Shows memory device Part Number (\fBpart:\fR). Useful to order new or replacement memory sticks etc. Usually part numbers are unique, particularly if you use the word \fBmemory\fR in the search as well. With \fB\-xx\fR, shows Serial Number and Manufactorer as well.
+.TP
+.B \-x \-m
+\- If present, shows maximum memory module/device size in the Array line. Only some systems will have this data available.
+.TP
.B \-x \-N
\- Adds version/port(s)/driver version (if available) for each Network card;
.TP
@@ -345,7 +358,7 @@ version number, if available.
\- Adds memory use output to cpu (\fB\-xt c\fR), and cpu use to memory (\fB\-xt m\fR).
.TP
.B \-x \-w / \-W
-\- Adds wind speed and time zone (\-w only), and makes output go to two lines.
+\- Adds wind speed and time zone (\fB\-w\fR only), and makes output go to two lines.
.TP
.B \-xx \-A
\- Adds vendor:product ID of each Audio device.
@@ -370,6 +383,12 @@ not all systemd systems have the default value set, in that case, if present, it
.B \-xx \-I
\- Adds parent program (or tty) that started shell, if not IRC client, to shell information.
.TP
+.B \-xx \-m
+\- Shows memory device Manufacturer and Serial Number.
+.TP
+.B \-xx \-m
+\- Single/double bank memory, if data is found. Note, this may not be 100% right all of the time since it depends on the order that data is found in \fBdmidecode\fR output for \fBtype 6\fR and \fBtype 17\fR.
+.TP
.B \-xx \-M
\- Adds chassis information, if any data for that is available. Also shows BIOS rom size if using dmidecode.
.TP
@@ -391,6 +410,15 @@ Supports most known display managers, like xdm, gdm, kdm, slim, lightdm, or mdm.
.B \-xx \-@ <11\-14>
\- Automatically uploads debugger data tar.gz file to \fIftp.techpatterns.com\fR.
.TP
+.B \-xxx \-m
+\- Memory bus width: primary bus width, and if present, total width. eg: bus width: 64 bit (total: 72 bits). Note that total / data widths are mixed up sometimes in dmidecode output, so inxi will take the larger value as total if present. If no total width data is found, then inxi will not show that item.
+.TP
+.B \-xxx \-m
+\- Adds device Type Detail, eg: DDR3 (Synchronous).
+.TP
+.B \-xxx \-m
+\- If present, will add memory module voltage. Only some systems will have this data available.
+.TP
.B \-xxx \-S
\- Adds, if run in X, shell/panel type info to Desktop information, if present. If none, shows nothing.
Supports some current desktop extras like gnome\-panel, lxde\-panel, and others. Added mainly for Mint support.
diff --git a/inxi.1.gz b/inxi.1.gz
index 7341b15..fe6b6cd 100755
--- a/inxi.1.gz
+++ b/inxi.1.gz
Binary files differ
diff --git a/inxi.changelog b/inxi.changelog
index c55328c..522a713 100755
--- a/inxi.changelog
+++ b/inxi.changelog
@@ -1,4 +1,363 @@
=====================================================================================
+Version: 2.2.00
+Patch Version: 00
+Script Date: 2014-08-18
+-----------------------------------
+Changes:
+-----------------------------------
+New version, tarball, man page. Maintainers, this is the official release of -m feature.
+
+I have collected enough datasamples to allow for reasonably fine grained corrections, estimates,
+warnings about unreliable capacity now, and have fixed all major failures.
+
+Also, because this stuff is filled out by people somewhere, or not, some fields often are just
+empty, or contain the default values, ie, they are worthless. inxi shows N/A for those situations,
+it means there is really no actual data to show you.
+
+This feature, sadly, well never be totally reliable, because dmi data is frankly junk, especially
+dmi type 5 and 16, which is what is supposed to tell you total capacity of memory array, and the
+maximum module size (type 5). However, this data is totally random, often it is right, sometimes
+it is wrong. Sometimes type 5 is right and type 16 is wrong, sometimes the other way. And since
+type 5 is only present in some systems, it's not reliable anyway.
+
+What is reliable and always right is the actually installed memory per device, ie, sticks. I have
+not seen any errors in that, so that seems to be actually coming from the system itself. type 5 / 16
+sadly are clearly entered in manually by some poorly paid engineers out there in the world, and are
+often total fictions, either far too small, or far too big, or whatever.
+
+inxi will attempt to correct all clear logic errors, and whenever it changes the listed data from
+type 5/16, it notes either (est) or (check). (est) means it is a good guess, one I am comfortable making,
+(check) means it is either an unreliable guess, or that what the system is reporting is so unlikely that
+even though inxi is showing it, it doubts it could actually be true, or at least, it thinks you
+should check this yourself.
+
+-m has 3 extra data options, -x prints the part number, if found, and the max module size, if type 5
+is present. inxi does NOT attempt to guess at max module size based on what is installed, it only will
+correct a listed max module size if installed modules are > than listed max size. Usually part numbers,
+if present, are all you need to order a new stick.
+
+-xx shows serial number, manufacturer (often empty, or just random alphanumeric identifiers, but sometimes
+they list the actual company name, which is helpful. It also shows, if type 5 data is present, single/double
+bank.
+
+-xxx as usual shows largely useless data that may be of interest to soemone, like if ram type is synchronous,
+memory bus width data, and module voltage (type 5 data).
+
+This feature will never be reliable I am sad to say because the source data itself is random and much
+has been filled out, or not filled out, by engineering drones somewhere out there in the underpaid
+world. The ranges of errors are so wide that inxi just has to check what is possible, reasonable, unlikely,
+etc, to generate its numbers. In other words, this is NOT just parsing dmidecode output, that is the raw
+material only, sad to say.
+
+So this is it, for better or worse. All bug / issue reports with this MUST come with a full:
+inxi -xx@14
+hardware data upload, run as root.
+
+Also, much to my annoyance, this feature requires root, since /dev/mem needs root to be read, and I assume
+the dmi table, so that is a departure from normal inxi standards, as is the low quality input, and thus,
+output, data, though I can guarantee that what inxi tells you is in most cases on average more accurate than
+what dmidecode tells you, since dmidecode simply prints out what it finds in the dmi table, and nothing else,
+in whatever order it finds it, from what I can see, ie, you also cannot trust the order of dmidecode output.
+
+I had been hoping that /sys would start to contain memory data like it does mobo/system data, but it never
+happened so I finally decided to just do the ram thing, require dmidecode, require root/sudo, and that's
+that.
+
+There will be issue reports, you can help them by looking up the mobo stats/specs yourself and listing them
+in the issue, so I don't have to do it. I use the tool at crucial.com which is very accurate and also very
+complete in terms of all possible hardware out there.
+
+I would trust that tool before trusting the companies that have the least reliable data, like ASUS.
+
+Much thanks to everyone who is contributing datasets, and the distros, particularly siduction, that really
+were very helpful in this process, by finding more and more failure cases that helped me start to tighten
+the logic, and make it more and more robust. Special thanks to Mikaela, of #smxi irc.oftc.net, who came up
+with two systems that both required a full redo of the logic, and thus who helped a lot in this process.
+
+-----------------------------------
+-- Harald Hope - Mon, 18 Aug 2014 15:07:36 -0700
+
+=====================================================================================
+Version: 2.1.98
+Patch Version: 01
+Script Date: 2014-08-17
+-----------------------------------
+Changes:
+-----------------------------------
+New patch version, new tarball. Another error case dataset, wrong cap, wrong max mod
+size, derived mod size 2gb, listed cap 8, but 2 slots, ie, 2gb x 2 == 4. Made this
+retain the listed size, but adds (check) to it because either max mod size is wrong
+or cap is wrong.
+
+-----------------------------------
+-- Harald Hope - Sun, 17 Aug 2014 19:40:46 -0700
+
+=====================================================================================
+Version: 2.1.98
+Patch Version: 00
+Script Date: 2014-08-17
+-----------------------------------
+Changes:
+-----------------------------------
+New version, new tarball. Fixed bad assumption, DMI type 0 is not always before other
+types, in at least one case, it is last, so can't use that as trigger to start loop.
+
+Now using: Table at .. which is always at start of dmi output.
+
+Also, changed size output per module to be in MB GB TB instead of all mB, since modules
+are sold by GB or MB, the data should show that as well. Also shortens output.
+
+-----------------------------------
+-- Harald Hope - Sun, 17 Aug 2014 12:01:38 -0700
+
+=====================================================================================
+Version: 2.1.97
+Patch Version: 00
+Script Date: 2014-08-16
+-----------------------------------
+Changes:
+-----------------------------------
+New version, new tarball. Another logic redo to handle a fringe case (dmidecode places
+type 17 in front of type 16), now each array is created as a multidimenstional, 2x array,
+and each device is a 3 dimensional array. This seems to clean up the problems with bad
+ordering of dmidecode data.
+
+-----------------------------------
+-- Harald Hope - Sat, 16 Aug 2014 16:22:17 -0700
+
+=====================================================================================
+Version: 2.1.96
+Patch Version: 02
+Script Date: 2014-08-15
+-----------------------------------
+Changes:
+-----------------------------------
+forgot to remove debugger on switch
+-----------------------------------
+-- Harald Hope - Fri, 15 Aug 2014 16:55:04 -0700
+
+=====================================================================================
+Version: 2.1.96
+Patch Version: 01
+Script Date: 2014-08-15
+-----------------------------------
+Changes:
+-----------------------------------
+Small change, forgot to add -m to the debugger inxi output.
+
+-----------------------------------
+-- Harald Hope - Fri, 15 Aug 2014 16:43:47 -0700
+
+=====================================================================================
+Version: 2.1.96
+Patch Version: 00
+Script Date: 2014-08-14
+-----------------------------------
+Changes:
+-----------------------------------
+New version, new tarball, new man page. This version hopefully brings inxi closer to
+at least making good guesses when the data is bad for ram, and hopefully will not break
+too many cases where it was actually right but seemed wrong.
+
+Unfortunately, dmidecode data simply cannot be relied on, and is FAR inferior to the type
+of data inxi tries in general to present users, ie, taken directly from the system, and,
+ideally, more accurate than most other tools. But in this case, there is just no way to get
+the data truly accurate no matter how many hacks I add.
+
+But if you have bad data, then submit: inxi -xx@ 14 so I can take a look at the system,
+and see if I can modify the hacks to improve that data.
+
+-----------------------------------
+-- Harald Hope - Thu, 14 Aug 2014 17:41:42 -0700
+
+=====================================================================================
+Version: 2.1.95
+Patch Version: 04
+Script Date: 2014-08-14
+-----------------------------------
+Changes:
+-----------------------------------
+New patch version, tarball. Fixed a few small oversights, more debugging added.
+
+Will next try to handle the remaining corner cases if possible.
+-----------------------------------
+-- Harald Hope - Thu, 14 Aug 2014 12:23:38 -0700
+
+=====================================================================================
+Version: 2.1.95
+Patch Version: 01
+Script Date: 2014-08-13
+-----------------------------------
+Changes:
+-----------------------------------
+patch version, trying to fix a small glitch with gawk wanting to change integers to strings.
+
+forcing int() on relevant items.
+
+-----------------------------------
+-- Harald Hope - Wed, 13 Aug 2014 21:28:46 -0700
+
+=====================================================================================
+Version: 2.1.95
+Patch Version: 00
+Script Date: 2014-08-13
+-----------------------------------
+Changes:
+-----------------------------------
+New version, new tarball. Attempting to handle bad extra data for max module size, sometimes
+it is too big, and sometimes too small. Changed data gathering to use arrays, then print/process
+the arrays once they are assembled.
+
+Now it will get rid of any max module size if it's greater than the calculated capacity, and it
+will generate an estimated capacity/max module size if they are clearly wrong because actual
+module sizes are greater than listed max size, or capacity is less than greatest module sizes times
+number of devices.
+
+Not perfect, but it never is, this covers more cases now correctly than before.
+
+-----------------------------------
+-- Harald Hope - Wed, 13 Aug 2014 20:42:00 -0700
+
+=====================================================================================
+Version: 2.1.94
+Patch Version: 00
+Script Date: 2014-08-13
+-----------------------------------
+Changes:
+-----------------------------------
+New version, new man page, new tarball. Realized that I can on some systems also add
+maximum supported module size, and module voltage. Most systems do not have this data,
+but some do. It's Type 5 item in dmidecode.
+
+Getting the type 6 data however is too hard, and even using type 5 assumes that the
+system only has one physical memory array, but that's fine given how few systems
+probably will have this information in the first place.
+
+-----------------------------------
+-- Harald Hope - Wed, 13 Aug 2014 14:03:03 -0700
+
+=====================================================================================
+Version: 2.1.93
+Patch Version: 00
+Script Date: 2014-08-13
+-----------------------------------
+Changes:
+-----------------------------------
+New version, new man page. Fixed man page errors, improved man page explanations of -m
+features. Changed output syntax to be more consistent, now each main array line starts with:
+
+Array-X capacity: (where X is an integer, counting from 1)
+
+and each device line starts with:
+Device-X: (where X is an integer incremented by 1 for each device, and starting at 1
+for each array. I have no data sets that contain > 1 physical memory array, if one appears,
+I may need to patch the output to link the array handles with the device handles explicitly.
+
+Made memory bus width output more clear, and added in a hack to correct dmidecode output errors,
+sometimes total width > data width, and sometimes data width is > total width, so using always
+greatest value for total if not equal to other width.
+
+I think this will be close to it barring any user feedback or bugs, if nothing comes to
+mind within a few days, I'll move the number to the new major version, 2.2.0
+
+-----------------------------------
+-- Harald Hope - Wed, 13 Aug 2014 12:12:23 -0700
+
+=====================================================================================
+Version: 2.1.92
+Patch Version: 00
+Script Date: 2014-08-12
+-----------------------------------
+Changes:
+-----------------------------------
+New version, new tarball. This is closer to final release. Removed Bank/Slot separate
+items and am now just generating one: Locator item, usually from Slot/DIMM locator info,
+but sometimes from Bank Locator info when it is more reliable based on my data samples.
+
+Updated help menu, updated man page, now shows working -x -xx -xxx extra data. This may
+change slightly over time.
+
+Also removed speed output when No Module Installed is returned for device size. This
+also wills switch off width if both total/data are empty.
+
+This is much closer now to live 2.2.0, but I'll leave a few more tests before putting
+it at 2.2.0.
+
+-----------------------------------
+-- Harald Hope - Tue, 12 Aug 2014 20:16:04 -0700
+
+=====================================================================================
+Version: 2.1.91
+Patch Version: 00
+Script Date: 2014-08-12
+-----------------------------------
+Changes:
+-----------------------------------
+New version, new tarball. This is a transitional version, most -x/-xx/-xxx data is now
+working, but help/man does not have that yet, until I finalize the order.
+
+Fixed dmidecode issues, showing extra data types for -m, added line length handling
+so -m is properly integrated with rest of inxi re max line lengths.
+
+-----------------------------------
+-- Harald Hope - Tue, 12 Aug 2014 18:11:29 -0700
+
+=====================================================================================
+Version: 2.1.90
+Patch Version: 00
+Script Date: 2014-08-11
+-----------------------------------
+Changes:
+-----------------------------------
+New version, new tarball, new man page. Finally, after all these years, initial memory/ram
+support. This feature requires dmidecode, and usually that needs to be run as root.
+
+Significantly improved dmidecode error handling and output, and have as 2.1.90 testing/initial
+release basic ram data.
+
+In subsequent releases, extra info for -x and -xx and -xxx will be added as well to the output.
+
+For those who want to jump on board early for ram data, update your repos, for those who want to
+wait for the full featured version, with -x type data, wait for 2.2.0
+
+And that's that.
+
+-----------------------------------
+-- Harald Hope - Mon, 11 Aug 2014 22:23:18 -0700
+
+=====================================================================================
+Version: 2.1.29
+Patch Version: 00
+Script Date: 2014-08-08
+-----------------------------------
+Changes:
+-----------------------------------
+No version change, this only will impact ancient systems, cleans up a data error message
+and restores N/A to IF id in networking. No functional change, and won't be seen on any
+non ancient systems.
+
+-----------------------------------
+-- Harald Hope - Mon, 11 Aug 2014 16:10:03 -0700
+
+=====================================================================================
+Version: 2.1.29
+Patch Version: 00
+Script Date: 2014-08-08
+-----------------------------------
+Changes:
+-----------------------------------
+New version, tarball. Big update/fix to -n/-i/-N. Now supports infiniband devices, which
+have the odd feature in our test data of having > 1 IF id, like ib0 ib1 per pcibusid.
+
+Added support for virtual nics as well. This required refactoring the networking functions
+significantly, so hopefully nothing breaks for existing systems. It should in theory be more
+robust now than it was before, with more accurate output, particularly with multiple port
+devices, like two port nics etc.
+
+-----------------------------------
+-- Harald Hope - Fri, 08 Aug 2014 10:17:52 -0700
+
+=====================================================================================
Version: 2.1.28
Patch Version: 00
Script Date: 2014-05-05