Bump inxi version to 2.1.1
[quassel.git] / data / scripts / inxi
1 #!/usr/bin/env bash
2 ########################################################################
3 ####  Script Name: inxi
4 ####  Version: 2.1.1
5 ####  Date: 2014-03-14
6 ####  Patch Number: 00
7 ########################################################################
8 ####  SPECIAL THANKS
9 ########################################################################
10 ####  Special thanks to all those in #lsc and #smxi for their tireless 
11 ####  dedication helping test inxi modules.
12 ########################################################################
13 ####  ABOUT INXI
14 ########################################################################
15 ####  inxi is a fork of infobash 3.02, the original bash sys info tool by locsmif
16 ####  As time permits functionality improvements and recoding will occur.
17 ####
18 ####  inxi, the universal, portable, system information tool for irc.
19 ####  Tested with Irssi, Xchat, Konversation, BitchX, KSirc, ircII,
20 ####  Gaim/Pidgin, Weechat, KVIrc and Kopete.
21 ####  Original infobash author and copyright holder:
22 ####  Copyright (C) 2005-2007  Michiel de Boer a.k.a. locsmif
23 ####  inxi version: Copyright (C) 2008-2014 Scott Rogers & Harald Hope
24 ####  Further fixes (listed as known): Horst Tritremmel <hjt at sidux.com>
25 ####  Steven Barrett (aka: damentz) - usb audio patch; swap percent used patch
26 ####  Jarett.Stevens - dmidecde -M patch for older systems with the /sys 
27 ####
28 ####  Current script home page/wiki/svn: http://inxi.googlecode.com
29 ####  Script forums: http://techpatterns.com/forums/forum-33.html
30 ####  IRC support: irc.oftc.net channel #smxi
31 ####
32 ####  This program is free software; you can redistribute it and/or modify
33 ####  it under the terms of the GNU General Public License as published by
34 ####  the Free Software Foundation; either version 3 of the License, or
35 ####  (at your option) any later version.
36 ####
37 ####  This program is distributed in the hope that it will be useful,
38 ####  but WITHOUT ANY WARRANTY; without even the implied warranty of
39 ####  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
40 ####  GNU General Public License for more details.
41 ####
42 ####  You should have received a copy of the GNU General Public License
43 ####  along with this program.  If not, see <http://www.gnu.org/licenses/>.
44 ####
45 ####  If you don't understand what Free Software is, please read (or reread)
46 ####  this page: http://www.gnu.org/philosophy/free-sw.html
47 ########################################################################
48 ####  * Package names in (...) are the Debian Squeeze package name. Check your 
49 ####    distro for proper package name by doing this: which <application> 
50 ####    then find what package owns that application file. Or run --recommends
51 ####    which shows package names for Debian/Ubuntu, Arch, and Fedora/Redhat/Suse
52 ####
53 ####  DEPENDENCIES
54 ####  * bash >=3.0 (bash); df, readlink, stty, tr, uname, wc (coreutils);
55 ####    gawk (gawk); grep (grep); lspci (pciutils);
56 ####    ps, uptime (procps); find (findutils)
57 ####  * Also the proc filesystem should be present and mounted
58 ####  * Some features, like -M and -d will not work, or will work incompletely,
59 ####    if /sys is missing
60 ####
61 ####    Apparently unpatched bash 3.0 has arrays broken; bug reports:
62 ####    http://ftp.gnu.org/gnu/bash/bash-3.0-patches/bash30-008
63 ####    http://lists.gnu.org/archive/html/bug-bash/2004-08/msg00144.html
64 ####  Bash 3.1 for proper array use
65 ####
66 ####    Arrays work in bash 2.05b, but "grep -Em" does not
67 ####
68 ####  RECOMMENDS (Needed to run certain features, listed by option)
69 ####  -A - for output of usb audio information: lsusb (usbutils)
70 ####  -Ax -Nx - for audio/network module version: modinfo (module-init-tools)
71 ####  -Dx - for hdd temp output (root only default): hddtemp (hddtemp)
72 ####       For user level hdd temp output: sudo (sudo)
73 ####       Note: requires user action for this feature to run as user (edit /etc/sudoers file)
74 ####  -G - full graphics output requires:  glxinfo (mesa-utils); xdpyinfo (X11-utils);
75 ####       xrandr (x11-xserver-utils)
76 ####  -i - IP information, local/wan - ip (iproute) legacy, not used if ip present: ifconfig (net-tools)
77 ####  -Ix - view current runlevel while not in X window system (or with -x): runlevel (sysvinit)
78 ####  -M - for older systems whose kernel does not have /sys data for machine, dmidecode (dmidecode)
79 ####  -o - for unmounted file system information in unmounted drives (root only default): file (file)
80 ####       Note: requires user action for this feature to run as user (edit /etc/sudoers file)
81 ####       For user level unmounted file system type output: sudo (sudo)
82 ####  -s   For any sensors output, fan, temp, etc: sensors (lm-sensors)
83 ####       Note: requires setup of lm-sensors (sensors-detect and adding modules/modprobe/reboot,
84 ####       and ideally, pwmconfig) prior to full output being available. 
85 ####  -S   For desktop environment, user must be in X and have xprop installed (in X11-utils)
86 ########################################################################
87 ####  BSD Adjustments
88 ####  * sed -i '' form supported by using SED_I="-i ''".
89 ####  * Note: New BSD sed supports using -r instead of -E for compatibility with gnu sed
90 ####    However, older, like FreeBSD 7.x, does not have -r so using SED_RX='-E' for this.
91 ####  * Gnu grep options can be used if the function component is only run in linux
92 ####    These are the options that bsd grep does not support that inxi uses: -m <number> -o 
93 ####    so make sure if you use those to have them in gnu/linux only sections.
94 ####    It appears that freebsd uses gnu grep but openbsd uses bsd grep, however.
95 ####  * BSD ps does not support --without-headers option, and also does not support --sort <option>
96 ####    Tests show that -m fails to sort memory as expected, but -r does sort cpu percentage.
97 ####  * BSD_TYPE is set with values null, debian-bsd (debian gnu/kfreebsd), bsd (all other bsds)
98 ####  * Subshell and array closing ) must not be on their own line unless you use an explicit \ 
99 ####    to indicate that logic continues to next line where closing ) or )) are located.
100 ########################################################################
101 ####  CONVENTIONS:
102 ####  * Character Encoding: UTF-8 - this file contains special characters that must be opened and saved as UTF8
103 ####  * Indentation: TABS
104 ####  * Do not use `....` (back quotes), those are totally non-reabable, use $(....).
105 ####  * Do not use one liner flow controls. 
106 ####    The ONLY time you should use ';' (semi-colon) is in this single case: if [[ condition ]];then.
107 ####    Never use compound 'if': ie, if [[ condition ]] && statement.
108 ####  * Note: [[ -n $something ]] - double brackets does not require quotes for variables: ie, "$something".
109 ####  * Always use quotes, double or single, for all string values.
110 ####  * All new code/methods must be in a function.
111 ####  * For all boolean tests, use 'true' / 'false'.
112 ####    !! Do NOT use 0 or 1 unless it's a function return. 
113 ####  * Avoid complicated tests in the if condition itself.
114 ####  * To 'return' a value in a function, use 'echo <var>'.
115 ####  * For gawk: use always if ( num_of_cores > 1 ) { hanging { starter for all blocks
116 ####    This lets us use one method for all gawk structures, including BEGIN/END, if, for, etc
117 ####
118 ####  VARIABLE/FUNCTION NAMING:
119 ####  * All functions should follow standard naming--verb adjective noun. 
120 ####      ie, get_cpu_data
121 ####  * All variables MUST be initialized / declared explicitly, either top of file, for Globals, or using local
122 ####  * All variables should clearly explain what they are, except counters like i, j.
123 ####  * Each word of Bash variable must be separated by '_' (underscore) (camel form), like: cpu_data
124 ####  * Each word of Gawk variable must be like this (first word lower, following start with upper): cpuData
125 ####  * Global variables are 'UPPER CASE', at top of this file.
126 ####      ie, SOME_VARIABLE=''
127 ####  * Local variables are 'lower case' and declared at the top of the function using local, always.
128 ####      ie: local some_variable=''
129 ####  * Locals that will be inherited by child functions have first char capitalized (so you know they are inherited).
130 ####      ie, Some_Variable 
131 ####  * Booleans should start with b_ (local) or B_ (global) and state clearly what is being tested.
132 ####  * Arrays should start with a_ (local) or A_ (global).
133 ####
134 ####  SPECIAL NOTES:
135 ####  * The color variable ${C2} must always be followed by a space unless you know what
136 ####    character is going to be next for certain. Otherwise irc color codes can be accidentally
137 ####    activated or altered.
138 ####  * For native script konversation support (check distro for correct konvi scripts path):
139 ####    ln -s <path to inxi> /usr/share/apps/konversation/scripts/inxi
140 ####    DCOP doesn't like \n, so avoid using it for most output unless required, as in error messages.
141 ####  * print_screen_output " " # requires space, not null, to avoid error in for example in irssi
142 ####  * For logging of array data, array must be placed into the temp_array, otherwise only the first key logs
143 ####  * In gawk search patterns, . is a wildcard EXCEPT in [0-9.] type containers, then it's a literal
144 ####    So outside of bracketed items, it must be escaped, \. but inside, no need. Outside of gawk it should 
145 ####    be escaped in search patterns if you are using it as a literal.
146 ####  
147 ####  PACKAGE MANAGER DATA (note, while inxi tries to avoid using package managers to get data, sometimes 
148 ####  it's the only way to get some data):
149 ####  * dpkg options: http://www.cyberciti.biz/howto/question/linux/dpkg-cheat-sheet.php
150 ####  * pacman options: https://wiki.archlinux.org/index.php/Pacman_Rosetta
151 ####
152 ####  As with all 'rules' there are acceptions, these are noted where used.
153 ###################################################################################
154 ####    KDE Konversation information.  Moving from dcop(qt3/KDE3) to dbus(qt4/KDE4)
155 ###################################################################################
156 ####  * dcop and dbus   -- these talk back to Konversation from this program
157 ####  * Scripting info  -- http://konversation.berlios.de/docs/scripting.html
158 ####    -- http://www.kde.org.uk/apps/konversation/
159 ####  * dbus info       -- http://dbus.freedesktop.org/doc/dbus-tutorial.html
160 ####    view dbus info  -- https://fedorahosted.org/d-feet/
161 ####    -- or run qdbus
162 ####  * Konvi dbus/usage-- qdbus org.kde.konversation /irc say <server> <target-channel> <output>
163 ####  * Python usage    -- http://wiki.python.org/moin/DbusExamples  (just in case)
164 ####
165 ####    Because webpages come and go, the above information needs to be moved to inxi's wiki
166 ########################################################################
167 ####  Valuable Resources
168 ####  CPU flags: http://unix.stackexchange.com/questions/43539/what-do-the-flags-in-proc-cpuinfo-mean
169 ####  Advanced Bash: http://wiki.bash-hackers.org/syntax/pe
170 ####  gawk arrays: http://www.math.utah.edu/docs/info/gawk_12.html
171 ####  raid mdstat: http://www-01.ibm.com/support/docview.wss?uid=isg3T1011259
172 ####               http://www.howtoforge.com/replacing_hard_disks_in_a_raid1_array
173 ####               https://raid.wiki.kernel.org/index.php/Mdstat
174 ########################################################################
175 ####  TESTING FLAGS
176 ####  inxi supports advanced testing triggers to do various things, using -! <arg>
177 ####  -! 1  - triggers default B_TESTING_1='true' to trigger some test or other
178 ####  -! 2  - triggers default B_TESTING_2='true' to trigger some test or other
179 ####  -! 3  - triggers B_TESTING_1='true' and B_TESTING_2='true'
180 ####  -! 10 - triggers an update from the primary dev download server instead of svn
181 ####  -! 11 - triggers an update from svn branch one - if present, of course
182 ####  -! 12 - triggers an update from svn branch two - if present, of course
183 ####  -! 13 - triggers an update from svn branch three - if present, of course
184 ####  -! 14 - triggers an update from svn branch four - if present, of course
185 ####  -! <http://......> - Triggers an update from whatever server you list.
186 ####  LOG FLAGS (logs to $HOME/.inxi/inxi.log with rotate 3 total)
187 ####  -@ 8  - Basic data logging of generated data / array values
188 ####  -@ 9  - Full logging of all data used, including cat of files and system data
189 ####  -@ 10 - Basic data logging plus color code logging
190 ########################################################################
191 #### VARIABLES
192 ########################################################################
193
194 ## NOTE: we can use hwinfo if it's available in all systems, or most, to get
195 ## a lot more data and verbosity levels going
196
197 ### DISTRO MAINTAINER FLAGS ###
198 # flag to allow distro maintainers to turn off update features. If false, turns off
199 # -U and -! testing/advanced update options, as well as removing the -U help menu item
200 # NOTE: Usually you want to create these in /etc/inxi.conf to avoid having to update each time
201 B_ALLOW_UPDATE='true'
202 B_ALLOW_WEATHER='true'
203
204 ### USER CONFIGS: SET IN inxi.conf file see wiki for directions ###
205 # http://code.google.com/p/inxi/wiki/script_configuration_files
206 # override in user config if desired, seems like less than .3 doesn't work as reliably
207 CPU_SLEEP='0.3' 
208 FILTER_STRING='<filter>'
209
210 # for features like help/version will fit to terminal / console screen width. Console
211 # widths will be dynamically set in main() based on cols in term/console
212 COLS_MAX_CONSOLE='115'
213 COLS_MAX_IRC='105'
214 PS_COUNT=5
215 # change to less, or more if you have very slow connection
216 WGET_TIMEOUT=8
217 ### END USER CONFIGS ###
218
219 ### LOCALIZATION - DO NOT CHANGE! ###
220 # set to default LANG to avoid locales errors with , or .
221 LANG=C
222 # Make sure every program speaks English.
223 LC_ALL="C"
224 export LC_ALL
225
226 ### ARRAYS ###
227 ## Prep
228 # Clear nullglob, because it creates unpredictable situations with IFS=$'\n' ARR=($VAR) IFS="$ORIGINAL_IFS"
229 # type constructs. Stuff like [rev a1] is now seen as a glob expansion pattern, and fails, and
230 # therefore results in nothing.
231 shopt -u nullglob
232 ## info on bash built in: $IFS - http://tldp.org/LDP/abs/html/internalvariables.html
233 # Backup the current Internal Field Separator
234 ORIGINAL_IFS="$IFS"
235
236 ## Initialize
237 A_ALSA_DATA=''
238 A_AUDIO_DATA=''
239 A_CMDL=''
240 A_CPU_CORE_DATA=''
241 A_CPU_DATA=''
242 A_CPU_TYPE_PCNT_CCNT=''
243 A_DEBUG_BUFFER=''
244 A_GCC_VERSIONS=''
245 A_GLX_DATA=''
246 A_GRAPHICS_CARD_DATA=''
247 A_GRAPHIC_DRIVERS=''
248 A_HDD_DATA=''
249 A_INIT_DATA=''
250 A_INTERFACES_DATA=''
251 A_MACHINE_DATA=''
252 A_NETWORK_DATA=''
253 A_OPTICAL_DRIVE_DATA=''
254 A_PARTITION_DATA=''
255 A_PCICONF_DATA=''
256 A_PS_DATA=''
257 A_RAID_DATA=''
258 A_SENSORS_DATA=''
259 A_UNMOUNTED_PARTITION_DATA=''
260 A_WEATHER_DATA=''
261 A_DISPLAY_SERVER_DATA=''
262
263 ### BOOLEANS ###
264 ## standard boolean flags ##
265 B_BSD_RAID='false'
266 B_COLOR_SCHEME_SET='false'
267 B_CONSOLE_IRC='false'
268 # triggers full display of cpu flags
269 B_CPU_FLAGS_FULL='false'
270 # test for dbus irc client
271 B_DBUS_CLIENT='false'
272 # kde dcop
273 B_DCOP='false'
274 # Debug flood override: make 'true' to allow long debug output
275 B_DEBUG_FLOOD='false'
276 B_DMIDECODE_SET='false'
277 # show extra output data
278 B_EXTRA_DATA='false'
279 # triggered by -xx
280 B_EXTRA_EXTRA_DATA='false'
281 B_ID_SET='false'
282 # override certain errors due to currupted data
283 B_HANDLE_CORRUPT_DATA='false'
284 B_LABEL_SET='false'
285 B_LSPCI='false'
286 B_LOG_COLORS='false'
287 B_LOG_FULL_DATA='false'
288 B_MAPPER_SET='false'
289 B_OUTPUT_FILTER='false'
290 B_OVERRIDE_FILTER='false'
291 B_PCICONF='false'
292 B_PCICONF_SET='false'
293 # kde qdbus
294 B_QDBUS='false'
295 B_PORTABLE='false'
296 B_RAID_SET='false'
297 B_ROOT='false'
298 B_RUN_COLOR_SELECTOR='false'
299 B_RUNNING_IN_DISPLAY='false' # in x type display server
300 if tty >/dev/null;then
301         B_RUNNING_IN_SHELL='true'
302 else
303         B_RUNNING_IN_SHELL='false'
304 fi
305 # this sets the debug buffer
306 B_SCRIPT_UP='false'
307 B_SHOW_ADVANCED_NETWORK='false'
308 # Show sound card data
309 B_SHOW_AUDIO='false'
310 B_SHOW_BASIC_RAID='false'
311 B_SHOW_BASIC_CPU='false'
312 B_SHOW_BASIC_DISK='false'
313 B_SHOW_BASIC_OPTICAL='false'
314 B_SHOW_CPU='false'
315 B_SHOW_DISPLAY_DATA='false'
316 B_SHOW_DISK_TOTAL='false'
317 B_SHOW_DISK='false'
318 # Show full hard disk output
319 B_SHOW_FULL_HDD='false'
320 B_SHOW_FULL_OPTICAL='false'
321 B_SHOW_GRAPHICS='false'
322 # Set this to 'false' to avoid printing the hostname, can be set false now
323 B_SHOW_HOST='true'
324 B_SHOW_INFO='false'
325 B_SHOW_IP='false'
326 B_SHOW_LABELS='false'
327 B_SHOW_MACHINE='false'
328 B_SHOW_NETWORK='false'
329 # either -v > 3 or -P will show partitions
330 B_SHOW_PARTITIONS='false'
331 B_SHOW_PARTITIONS_FULL='false'
332 B_SHOW_PS_CPU_DATA='false'
333 B_SHOW_PS_MEM_DATA='false'
334 B_SHOW_RAID='false'
335 # because many systems have no mdstat file, -b/-F should not show error if no raid file found
336 B_SHOW_RAID_R='false' 
337 B_SHOW_REPOS='false'
338 B_SHOW_SENSORS='false'
339 # triggers only short inxi output
340 B_SHOW_SHORT_OUTPUT='false'
341 B_SHOW_SYSTEM='false'
342 B_SHOW_UNMOUNTED_PARTITIONS='false'
343 B_SHOW_UUIDS='false'
344 B_SHOW_WEATHER='false'
345 B_SYSCTL='false'
346 # triggers various debugging and new option testing
347 B_TESTING_1='false'
348 B_TESTING_2='false'
349 B_UPLOAD_DEBUG_DATA='false'
350 B_USB_NETWORKING='false'
351 # set to true here for debug logging from script start
352 B_USE_LOGGING='false'
353 B_UUID_SET='false'
354 B_XORG_LOG='false'
355
356 ## Directory/file exist flags; test as [[ $(boolean) ]] not [[ $boolean ]]
357 B_ASOUND_DEVICE_FILE='false'
358 B_ASOUND_VERSION_FILE='false'
359 B_BASH_ARRAY='false'
360 B_CPUINFO_FILE='false'
361 B_DMESG_BOOT_FILE='false' # bsd only
362 B_LSB_FILE='false'
363 B_MDSTAT_FILE='false'
364 B_MEMINFO_FILE='false'
365 B_MODULES_FILE='false' #
366 B_MOUNTS_FILE='false'
367 B_OS_RELEASE_FILE='false' # new default distro id file? will this one work where lsb-release didn't?
368 B_PARTITIONS_FILE='false' #
369 B_PROC_DIR='false'
370 B_SCSI_FILE='false'
371
372 ## app tested for and present, to avoid repeat tests
373 B_FILE_TESTED='false'
374 B_HDDTEMP_TESTED='false'
375 B_MODINFO_TESTED='false'
376 B_SUDO_TESTED='false'
377
378 ### CONSTANTS/INITIALIZE - SOME MAY BE RESET LATER ###
379 DCOPOBJ="default"
380 DEBUG=0 # Set debug levels from 1-10 (8-10 trigger logging levels)
381 # Debug Buffer Index, index into a debug buffer storing debug messages until inxi is 'all up'
382 DEBUG_BUFFER_INDEX=0
383 ## note: the debugger rerouting to /dev/null has been moved to the end of the get_parameters function
384 ## so -@[number] debug levels can be set if there is a failure, otherwise you can't even see the errors
385 SED_I='-i' # for gnu sed, will be set to -i '' for bsd sed
386 SED_RX='-r' # for gnu sed, will be set to -E for bsd sed for backward compatibility
387
388 # default to false, no konversation found, 1 is native konvi (qt3/KDE3) script mode, 2 is /cmd inxi start,
389 ##      3 is Konversation > 1.2 (qt4/KDE4) 
390 KONVI=0
391 # NO_CPU_COUNT=0        # Wether or not the string "dual" or similar is found in cpuinfo output. If so, avoid dups.
392 # This is a variable that controls how many parameters inxi will parse in a /proc/<pid>/cmdline file before stopping.
393 PARAMETER_LIMIT=30
394 SCHEME=0 # set default scheme - do not change this, it's set dynamically
395 # this is set in user prefs file, to override dynamic temp1/temp2 determination of sensors output in case
396 # cpu runs colder than mobo
397 SENSORS_CPU_NO=''
398 # SHOW_IRC=1 to avoid showing the irc client version number, or SHOW_IRC=0 to disable client information completely.
399 SHOW_IRC=2
400 # Verbosity level defaults to 0, this can also be set with -v0, -v2, -v3, etc as a parameter.
401 VERBOSITY_LEVEL=0
402 # Supported number of verbosity levels, including 0
403 VERBOSITY_LEVELS=7
404
405 ### LOGGING ###
406 ## logging eval variables, start and end function: Insert to LOGFS LOGFE when debug level >= 8
407 LOGFS_STRING='log_function_data fs $FUNCNAME "$( echo $@ )"'
408 LOGFE_STRING='log_function_data fe $FUNCNAME'
409 LOGFS=''
410 LOGFE=''
411 # uncomment for debugging from script start
412 # LOGFS=$LOGFS_STRING
413 # LOGFE=$LOGFE_STRING
414
415 ### FILE NAMES/PATHS/URLS - must be non root writable ###
416 # File's used when present
417 FILE_ASOUND_DEVICE='/proc/asound/cards'
418 FILE_ASOUND_MODULES='/proc/asound/modules' # not used but maybe for -A?
419 FILE_ASOUND_VERSION='/proc/asound/version'
420 FILE_CPUINFO='/proc/cpuinfo'
421 FILE_DMESG_BOOT='/var/run/dmesg.boot'
422 FILE_LSB_RELEASE='/etc/lsb-release'
423 FILE_MDSTAT='/proc/mdstat'
424 FILE_MEMINFO='/proc/meminfo'
425 FILE_MODULES='/proc/modules'
426 FILE_MOUNTS='/proc/mounts'
427 FILE_OS_RELEASE='/etc/os-release'
428 FILE_PARTITIONS='/proc/partitions'
429 FILE_SCSI='/proc/scsi/scsi'
430 FILE_XORG_LOG='/var/log/Xorg.0.log' # if not found, search and replace with actual location
431
432 FILE_PATH=''
433 HDDTEMP_PATH=''
434 MODINFO_PATH=''
435 SUDO_PATH=''
436
437 SCRIPT_DATA_DIR="$HOME/.inxi"
438 ALTERNATE_FTP='' # for data uploads
439 ALTERNATE_WEATHER_LOCATION='' # weather alternate location
440 LOG_FILE="$SCRIPT_DATA_DIR/inxi.log"
441 LOG_FILE_1="$SCRIPT_DATA_DIR/inxi.1.log"
442 LOG_FILE_2="$SCRIPT_DATA_DIR/inxi.2.log"
443 MAN_FILE_DOWNLOAD='http://inxi.googlecode.com/svn/trunk/inxi.1.gz'
444 MAN_FILE_LOCATION='/usr/share/man/man1'
445 SCRIPT_NAME='inxi'
446 SCRIPT_PATCH_NUMBER=''
447 SCRIPT_PATH='' #filled-in in Main
448 SCRIPT_VERSION_NUMBER=""        #filled-in in Main
449 SCRIPT_DOWNLOAD='http://inxi.googlecode.com/svn/trunk/'
450 SCRIPT_DOWNLOAD_BRANCH_1='http://inxi.googlecode.com/svn/branches/one/'
451 SCRIPT_DOWNLOAD_BRANCH_2='http://inxi.googlecode.com/svn/branches/two/'
452 SCRIPT_DOWNLOAD_BRANCH_3='http://inxi.googlecode.com/svn/branches/three/'
453 SCRIPT_DOWNLOAD_BRANCH_4='http://inxi.googlecode.com/svn/branches/four/'
454 SCRIPT_DOWNLOAD_BRANCH_BSD='http://inxi.googlecode.com/svn/branches/bsd/'
455 SCRIPT_DOWNLOAD_BRANCH_GNUBSD='http://inxi.googlecode.com/svn/branches/gnubsd/'
456 SCRIPT_DOWNLOAD_DEV='http://smxi.org/test/'
457 # note, you can use any ip url here as long as it's the only line on the output page.
458 # Also the ip address must be the last thing on that line.
459 WAN_IP_URL='http://smxi.org/opt/ip.php'
460 KONVI_CFG="konversation/scripts/$SCRIPT_NAME.conf" # relative path to $(kde-config --path data)
461
462 ### INITIALIZE VARIABLES NULL ###
463 BSD_TYPE=''
464 BSD_VERSION=
465 CMDL_MAX=''
466
467 DEV_DISK_ID=''
468 DEV_DISK_LABEL=''
469 DEV_DISK_MAPPER=''
470 DEV_DISK_UUID=''
471 DMIDECODE_DATA=''
472 IRC_CLIENT=''
473 IRC_CLIENT_VERSION=''
474 PS_THROTTLED=''
475 REPO_DATA=''
476
477 ### LAYOUT ###
478 # These two determine separators in single line output, to force irc clients not to break off sections
479 SEP1='~'
480 SEP2=' '
481 # these will assign a separator to non irc states. Important! Using ':' can trigger stupid emoticon
482 # behaviors in output on IRC, so do not use those.
483 SEP3_IRC=''
484 SEP3_CONSOLE=':'
485 SEP3='' # do not set, will be set dynamically
486
487 # Default indentation level. NOTE: actual indent is 1 greater to allow for spacing
488 INDENT=10
489
490 ### COLUMN WIDTHS ###
491 COLS_INNER='' ## for width minus INDENT
492 COLS_MAX=''
493
494 TERM_COLUMNS=80
495 TERM_LINES=100
496
497 # http://stackoverflow.com/questions/1780483/lines-and-columns-environmental-variables-lost-in-a-script
498 if [[ -n $( type -p tput ) ]];then
499         TERM_COLUMNS=$(tput cols)
500         TERM_LINES=$(tput lines)
501 fi
502 # double check, just in case it's missing functionality or whatever
503 if [[ -n ${TERM_COLUMNS##[0-9]*} ]];then
504         TERM_COLUMNS=80
505         TERM_LINES=100
506 fi
507
508 # Only for legacy user config files se we can test and convert the var name
509 LINE_MAX_CONSOLE=''
510 LINE_MAX_IRC=''
511
512 ### COLORS ###
513 # Defaults to 2, make this 1 for normal, 0 for no colorcodes at all. Use following variables in config 
514 # files to change defaults for each type, or global
515 # Same as runtime parameter.
516 DEFAULT_COLOR_SCHEME=2
517 ## color variables - set dynamically
518 COLOR_SCHEME=''
519 C1=''
520 C2=''
521 CN=''
522 ## Always leave these blank, these are only going to be set in inxi.conf files, that makes testing
523 ## for user changes easier after sourcing the files
524 GLOBAL_COLOR_SCHEME=''
525 IRC_COLOR_SCHEME=''
526 IRC_CONS_COLOR_SCHEME=''
527 IRC_X_TERM_COLOR_SCHEME=''
528 CONSOLE_COLOR_SCHEME=''
529 VIRT_TERM_COLOR_SCHEME=''
530
531 ## Output colors
532 # A more elegant way to have a scheme that doesn't print color codes (neither ANSI nor mIRC) at all. See below.
533 unset EMPTY
534 #             DGREY   BLACK   RED     DRED    GREEN   DGREEN  YELLOW  DYELLOW
535 ANSI_COLORS="\e[1;30m \e[0;30m \e[1;31m \e[0;31m \e[1;32m \e[0;32m \e[1;33m \e[0;33m"
536 IRC_COLORS="  \x0314  \x0301  \x0304  \x0305  \x0309  \x0303  \x0308  \x0307"
537 #                          BLUE    DBLUE   MAGENTA DMAGENTA CYAN   DCYAN   WHITE   GREY    NORMAL
538 ANSI_COLORS="$ANSI_COLORS \e[1;34m \e[0;34m \e[1;35m \e[0;35m \e[1;36m \e[0;36m \e[1;37m \e[0;37m \e[0;37m"
539 IRC_COLORS=" $IRC_COLORS    \x0312 \x0302  \x0313  \x0306  \x0311  \x0310  \x0300  \x0315  \x03"
540
541 #ANSI_COLORS=($ANSI_COLORS); IRC_COLORS=($IRC_COLORS)
542 A_COLORS_AVAILABLE=( DGREY BLACK RED DRED GREEN DGREEN YELLOW DYELLOW BLUE DBLUE MAGENTA DMAGENTA CYAN DCYAN WHITE GREY NORMAL )
543
544 # See above for notes on EMPTY
545 ## note: group 1: 0, 1 are null/normal
546 ## Following: group 2: generic, light/dark or dark/light; group 3: dark on light; group 4 light on dark; 
547 # this is the count of the first two groups, starting at zero
548 SAFE_COLOR_COUNT=12
549 A_COLOR_SCHEMES=( 
550 EMPTY,EMPTY,EMPTY 
551 NORMAL,NORMAL,NORMAL 
552
553 BLUE,NORMAL,NORMAL
554 BLUE,RED,NORMAL 
555 CYAN,BLUE,NORMAL 
556 DCYAN,NORMAL,NORMAL
557 DCYAN,BLUE,NORMAL 
558 DGREEN,NORMAL,NORMAL 
559 DYELLOW,NORMAL,NORMAL 
560 GREEN,DGREEN,NORMAL 
561 GREEN,NORMAL,NORMAL 
562 MAGENTA,NORMAL,NORMAL
563 RED,NORMAL,NORMAL
564
565 BLACK,DGREY,NORMAL
566 DBLUE,DGREY,NORMAL 
567 DBLUE,DMAGENTA,NORMAL
568 DBLUE,DRED,NORMAL 
569 DBLUE,BLACK,NORMAL
570 DGREEN,DYELLOW,NORMAL 
571 DYELLOW,BLACK,NORMAL
572 DMAGENTA,BLACK,NORMAL
573 DCYAN,DBLUE,NORMAL
574
575 WHITE,GREY,NORMAL
576 GREY,WHITE,NORMAL
577 CYAN,GREY,NORMAL 
578 GREEN,WHITE,NORMAL 
579 GREEN,YELLOW,NORMAL 
580 YELLOW,WHITE,NORMAL 
581 MAGENTA,CYAN,NORMAL 
582 MAGENTA,YELLOW,NORMAL
583 RED,CYAN,NORMAL
584 RED,WHITE,NORMAL 
585 BLUE,WHITE,NORMAL
586 )
587
588 # WARNING: In the main part below (search for 'KONVI')
589 # there's a check for Konversation-specific config files.
590 # Any one of these can override the above if inxi is run
591 # from Konversation!
592
593 ## DISTRO DATA/ID ##
594 # In cases of derived distros where the version file of the base distro can also be found under /etc,
595 # the derived distro's version file should go first. (Such as with Sabayon / Gentoo)
596 DISTROS_DERIVED="antix-version aptosid-version kanotix-version knoppix-version mandrake-release pardus-release sabayon-release siduction-version sidux-version solusos-release turbolinux-release zenwalk-version"
597 # debian_version excluded from DISTROS_PRIMARY so Debian can fall through to /etc/issue detection. Same goes for Ubuntu.
598 DISTROS_EXCLUDE_LIST="debian_version ubuntu_version"
599 DISTROS_PRIMARY="arch-release gentoo-release redhat-release slackware-version SuSE-release"
600 DISTROS_LSB_GOOD="mandrake-release mandriva-release mandrakelinux-release"
601 # this is being used both by core distros and derived distros now, eg, solusos 1 uses it for solusos id, while
602 # debian, solusos base, uses it as well, so we have to know which it is.
603 DISTROS_OS_RELEASE_GOOD="arch-release SuSE-release"
604 ## Distros with known problems
605 # DSL (Bash 2.05b: grep -m doesn't work; arrays won't work) --> unusable output
606 # Puppy Linux 4.1.2 (Bash 3.0: arrays won't work) --> works partially
607
608 ## OUTPUT FILTERS/SEARCH ##
609 # Note that \<ltd\> bans only words, not parts of strings; in \<corp\> you can't use punctuation characters like . or ,
610 # we're saving about 10+% of the total script exec time by hand building the ban lists here, using hard quotes.
611 BAN_LIST_NORMAL='chipset|components|computing|computer|corporation|communications|electronics|electrical|electric|gmbh|group|industrial|international|revision|semiconductor|software|technologies|technology|ltd\.|\<ltd\>|inc\.|\<inc\>|intl\.|co\.|\<co\>|corp\.|\<corp\>|\(tm\)|\(r\)|®|\(rev ..\)'
612 BAN_LIST_CPU='@|cpu deca|dual core|dual-core|tri core|tri-core|quad core|quad-core|ennea|genuine|hepta|hexa|multi|octa|penta|processor|single|triple|[0-9\.]+ *[MmGg][Hh][Zz]'
613
614 SENSORS_GPU_SEARCH='intel|radeon|nouveau'
615
616 ### USB networking search string data, because some brands can have other products than
617 ### wifi/nic cards, they need further identifiers, with wildcards.
618 ### putting the most common and likely first, then the less common, then some specifics
619 USB_NETWORK_SEARCH="Wi-Fi.*Adapter|Wireless.*Adapter|Ethernet.*Adapter|WLAN.*Adapter|Network.*Adapter|802\.11|Atheros|Atmel|D-Link.*Adapter|D-Link.*Wireless|Linksys|Netgea|Ralink|Realtek.*Network|Realtek.*Wireless|Realtek.*WLAN|Belkin.*Wireless|Belkin.*WLAN|Belkin.*Network"
620 USB_NETWORK_SEARCH="$USB_NETWORK_SEARCH|Actiontec.*Wireless|Actiontec.*Network|AirLink.*Wireless|Asus.*Network|Asus.*Wireless|Buffalo.*Wireless|Davicom|DWA-.*RangeBooster|DWA-.*Wireless|ENUWI-.*Wireless|LG.*Wi-Fi|Rosewill.*Wireless|RNX-.*Wireless|Samsung.*LinkStick|Samsung.*Wireless|Sony.*Wireless|TEW-.*Wireless|TP-Link.*Wireless|WG[0-9][0-9][0-9].*Wireless|WNA[0-9][0-9][0-9]|WNDA[0-9][0-9][0-9]|Zonet.*ZEW.*Wireless|54 Mbps" 
621 # then a few known hard to ID ones added 
622 # belkin=050d; d-link=07d1; netgear=0846; ralink=148f; realtek=0bda; 
623 USB_NETWORK_SEARCH="$USB_NETWORK_SEARCH|050d:935b|0bda:8189|0bda:8197"
624
625 ########################################################################
626 #### MAIN: Where it all begins
627 ########################################################################
628 main()
629 {
630         eval $LOGFS
631         
632         local color_scheme=''
633         # this will be used by all functions following
634         local Ps_aux_Data="$( ps aux )"
635
636         # This function just initializes variables
637         initialize_data
638         
639         # Source global config overrides, needs to be here because some things
640         # can be reset that were set in initialize, but check_required_apps needs
641         if [[ -s /etc/$SCRIPT_NAME.conf ]];then
642                 source /etc/$SCRIPT_NAME.conf
643         fi
644         # Source user config variables override /etc/inxi.conf variables
645         if [[ -s $HOME/.$SCRIPT_NAME/$SCRIPT_NAME.conf ]];then
646                 source $HOME/.$SCRIPT_NAME/$SCRIPT_NAME.conf
647         fi
648         # Convert to new variable names if set in config files, legacy test
649         if [[ -n $LINE_MAX_CONSOLE ]];then
650                 COLS_MAX_CONSOLE=$LINE_MAX_CONSOLE
651         fi
652         if [[ -n $LINE_MAX_IRC ]];then
653                 COLS_MAX_IRC=$LINE_MAX_IRC
654         fi
655         # TERM_COLUMNS is set in top globals, using tput cols
656         if [[ $TERM_COLUMNS -lt $COLS_MAX_CONSOLE ]];then
657                 COLS_MAX_CONSOLE=$TERM_COLUMNS
658         fi
659         # adjust, some terminals will wrap if output cols == term cols
660         COLS_MAX_CONSOLE=$(( $COLS_MAX_CONSOLE - 2 ))
661         
662         # comes after source for user set stuff
663         if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
664                 COLS_MAX=$COLS_MAX_CONSOLE
665                 SEP3=$SEP3_CONSOLE
666         else
667                 # too hard to read if no colors, so force that for users on irc
668                 if [[ $SCHEME == 0 ]];then
669                         SEP3=$SEP3_CONSOLE
670                 else
671                         SEP3=$SEP3_IRC
672                 fi
673                 COLS_MAX=$COLS_MAX_IRC
674         fi
675         COLS_INNER=$(( $COLS_MAX - $INDENT - 4 ))
676
677         # Check for dependencies BEFORE running ANYTHING else except above functions
678         # Not all distro's have these depends installed by default. Don't want to run
679         # this if the user is requesting to see this information in the first place
680         # Only continue if required apps tests ok
681         if [[ $1 != '--recommends' ]];then
682                 check_required_apps
683                 check_recommended_apps
684         fi
685
686         SCRIPT_VERSION_NUMBER=$( parse_version_data 'main' )
687         SCRIPT_PATCH_NUMBER=$( parse_version_data 'patch' )
688         
689         # previous source location, check for bugs
690
691         ## this needs to run before the KONVI stuff is set below
692         ## Konversation 1.2 apparently does not like the $PPID test in get_start_client
693         ## So far there is no known way to detect if qt4_konvi is the parent process
694         ## this method will infer qt4_konvi as parent
695         get_start_client
696
697         # note: this only works if it's run from inside konversation as a script builtin or something
698         # only do this if inxi has been started as a konversation script, otherwise bypass this 
699 #       KONVI=3 ## for testing puroses
700         if [[ $KONVI -eq 1 || $KONVI -eq 3 ]];then
701                 if [[ $KONVI -eq 1 ]]; then ## dcop Konversation (ie 1.x < 1.2(qt3))    
702                         DCPORT="$1"
703                         DCSERVER="$2"
704                         DCTARGET="$3"
705                         shift 3
706                 elif [[ $KONVI -eq 3 ]]; then ## dbus Konversation (> 1.2 (qt4))
707                         DCSERVER="$1" ##dbus testing
708                         DCTARGET="$2" ##dbus testing
709                         shift 2
710                 fi
711
712                 # The section below is on request of Argonel from the Konversation developer team:
713                 # it sources config files like $HOME/.kde/share/apps/konversation/scripts/inxi.conf
714                 IFS=":"
715                 for kde_config in $( kde-config --path data )
716                 do
717                         if [[ -r ${kde_config}${KONVI_CFG} ]];then
718                                 source "${kde_config}${KONVI_CFG}"
719                                 break
720                         fi
721                 done
722                 IFS="$ORIGINAL_IFS"
723         fi
724
725         ## leave this for debugging dcop stuff if we get that working
726         #       print_screen_output "DCPORT: $DCPORT"
727         #       print_screen_output "DCSERVER: $DCSERVER"
728         #       print_screen_output "DCTARGET: $DCTARGET"
729         
730         # first init function must be set first for colors etc. Remember, no debugger
731         # stuff works on this function unless you set the debugging flag manually.
732         # Debugging flag -@ [number] will not work until get_parameters runs.
733         
734         # "$@" passes every parameter separately quoted, "$*" passes all parameters as one quoted parameter.
735         # must be here to allow debugger and other flags to be set.
736         get_parameters "$@"
737
738         # If no colorscheme was set in the parameter handling routine, then set the default scheme
739         if [[ $B_COLOR_SCHEME_SET != 'true' ]];then
740                 # This let's user pick their color scheme. For IRC, only shows the color schemes, no interactive
741                 # The override value only will be placed in user config files. /etc/inxi.conf can also override
742                 if [[ $B_RUN_COLOR_SELECTOR == 'true' ]];then 
743                         select_default_color_scheme
744                 else
745                         # set the default, then override as required
746                         color_scheme=$DEFAULT_COLOR_SCHEME
747                         if [[ -n $GLOBAL_COLOR_SCHEME ]];then
748                                 color_scheme=$GLOBAL_COLOR_SCHEME
749                         else
750                                 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
751                                         if [[ -n $CONSOLE_COLOR_SCHEME && -z $DISPLAY ]];then
752                                                 color_scheme=$CONSOLE_COLOR_SCHEME
753                                         elif [[ -n $VIRT_TERM_COLOR_SCHEME ]];then
754                                                 color_scheme=$VIRT_TERM_COLOR_SCHEME
755                                         fi
756                                 else
757                                         if [[ -n $IRC_X_TERM_COLOR_SCHEME && $B_CONSOLE_IRC == 'true' && -n $B_RUNNING_IN_DISPLAY ]];then
758                                                 color_scheme=$IRC_X_TERM_COLOR_SCHEME
759                                         elif [[ -n $IRC_CONS_COLOR_SCHEME && -z $DISPLAY ]];then
760                                                 color_scheme=$IRC_CONS_COLOR_SCHEME
761                                         elif [[ -n $IRC_COLOR_SCHEME ]];then
762                                                 color_scheme=$IRC_COLOR_SCHEME
763                                         fi
764                                 fi
765                         fi
766                         set_color_scheme $color_scheme
767                 fi
768         fi
769         
770         # all the pre-start stuff is in place now
771         B_SCRIPT_UP='true'
772         script_debugger "Debugger: $SCRIPT_NAME is up and running..."
773         
774         # then create the output
775         print_it_out
776
777         ## last steps
778         if [[ $B_RUNNING_IN_SHELL == 'true' && $SCHEME -gt 0 ]];then
779                 echo -n "\e[0m"
780         fi
781         eval $LOGFE
782         # weechat's executor plugin forced me to do this, and rightfully so, because else the exit code
783         # from the last command is taken..
784         exit 0
785 }
786
787 #### -------------------------------------------------------------------
788 #### basic tests: set script data, booleans, PATH, version numbers
789 #### -------------------------------------------------------------------
790
791 # Set PATH data so we can access all programs as user. Set BAN lists.
792 # initialize some boleans, these directories are used throughout the script
793 # some apps are used for extended functions any directory used, should be
794 # checked here first.
795 # No args taken.
796 initialize_data()
797 {
798         eval $LOGFS
799         BSD_VERSION=$( uname -s 2>/dev/null | tr '[A-Z]' '[a-z]' )
800         
801         # note: archbsd says they are a freebsd distro, so assuming it's the same as freebsd
802         if [[ -n $( grep 'bsd' <<< "$BSD_VERSION" ) ]];then
803                 # GNU/kfreebsd will by definition have GNU tools like sed/grep
804                 if [[ -n $( grep 'kfreebsd' <<< "$BSD_VERSION" ) ]];then
805                         BSD_TYPE='debian-bsd' # debian gnu bsd
806                 else
807                         BSD_TYPE='bsd' # all other bsds
808                         SED_I="-i ''"
809                         SED_RX='-E'
810                 fi
811         fi
812         # now set the script BOOLEANS for files required to run features
813         # note that freebsd has /proc but it's empty
814         if [[ -d "/proc/" && -z $BSD_TYPE ]];then
815                 B_PROC_DIR='true'
816         elif [[ -n $BSD_TYPE ]];then
817                 B_PROC_DIR='false'
818         else
819                 error_handler 6
820         fi
821         
822         initialize_paths
823         
824         if [[ -n $BSD_TYPE ]];then
825                 if [[ -e $FILE_DMESG_BOOT ]];then
826                         B_DMESG_BOOT_FILE='true'
827                 fi
828         else
829                 # found a case of battery existing but having nothing in it on desktop mobo
830                 # not all laptops show the first, 
831                 if [[ -n $( ls /proc/acpi/battery 2>/dev/null ) ]];then
832                         B_PORTABLE='true'
833                 fi
834         fi
835         
836         
837         if [[ -e $FILE_CPUINFO ]]; then
838                 B_CPUINFO_FILE='true'
839         fi
840
841         if [[ -e $FILE_MEMINFO ]];then
842                 B_MEMINFO_FILE='true'
843         fi
844
845         if [[ -e $FILE_ASOUND_DEVICE ]];then
846                 B_ASOUND_DEVICE_FILE='true'
847         fi
848
849         if [[ -e $FILE_ASOUND_VERSION ]];then
850                 B_ASOUND_VERSION_FILE='true'
851         fi
852
853         if [[ -f $FILE_LSB_RELEASE ]];then
854                 B_LSB_FILE='true'
855         fi
856         
857         if [[ -f $FILE_OS_RELEASE ]];then
858                 B_OS_RELEASE_FILE='true'
859         fi
860
861         if [[ -e $FILE_SCSI ]];then
862                 B_SCSI_FILE='true'
863         fi
864
865         if [[ -n $DISPLAY ]];then
866                 B_SHOW_DISPLAY_DATA='true'
867                 B_RUNNING_IN_DISPLAY='true'
868         fi
869         
870         if [[ -e $FILE_MDSTAT ]];then
871                 B_MDSTAT_FILE='true'
872         fi
873
874         if [[ -e $FILE_MODULES ]];then
875                 B_MODULES_FILE='true'
876         fi
877
878         if [[ -e $FILE_MOUNTS ]];then
879                 B_MOUNTS_FILE='true'
880         fi
881
882         if [[ -e $FILE_PARTITIONS ]];then
883                 B_PARTITIONS_FILE='true'
884         fi
885         # default to the normal location, then search for it
886         if [[ -e $FILE_XORG_LOG ]];then
887                 B_XORG_LOG='true'
888         else
889                 # Detect location of the Xorg log file
890                 if [[ -n $( type -p xset ) ]]; then
891                         FILE_XORG_LOG=$( xset q 2>/dev/null | grep -i 'Log file' | gawk '{print $3}')
892                         if [[ -e $FILE_XORG_LOG ]];then
893                                 B_XORG_LOG='true'
894                         fi
895                 fi
896         fi
897         # gfx output will require this flag
898         if [[ $( whoami ) == 'root' ]];then
899                 B_ROOT='true'
900         fi
901         eval $LOGFE
902 }
903
904 # arg: $1 - version number: main/patch/date
905 parse_version_data()
906 {
907         local version_data=''
908
909         # note, using ####[[:space:]]+ to avoid having this function also trip the version datas
910         case $1 in
911                 date)
912                         version_data="$( gawk -F ': ' '
913                         /####[[:space:]]+Date:/ {
914                                 print $NF
915                         }' $SCRIPT_PATH/$SCRIPT_NAME )"
916                         ;;
917                 main)
918                         version_data="$( gawk '
919                         /####[[:space:]]+Version:/ {
920                                 print $3
921                         }' $SCRIPT_PATH/$SCRIPT_NAME )"
922                         ;;
923                 patch)
924                         version_data="$( gawk '
925                         /####[[:space:]]+Patch Number:/ {
926                                 print $4
927                         }' $SCRIPT_PATH/$SCRIPT_NAME )"
928                         ;;
929         esac
930         echo $version_data
931 }
932
933 initialize_paths()
934 {
935         local path='' added_path='' b_path_found='' sys_path=''
936         # Extra path variable to make execute failures less likely, merged below
937         local extra_paths="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
938         
939         # this needs to be set here because various options call the parent initialize function directly.
940         SCRIPT_PATH=$( dirname $0 )
941
942         # Fallback paths put into $extra_paths; This might, among others, help on gentoo.
943         # Now, create a difference of $PATH and $extra_paths and add that to $PATH:
944         IFS=":"
945         for path in $extra_paths
946         do
947                 b_path_found='false'
948                 for sys_path in $PATH
949                 do
950                         if [[ $path == $sys_path ]];then
951                                 b_path_found='true'
952                         fi
953                 done
954                 if [[ $b_path_found == 'false' ]];then
955                         added_path="$added_path:$path"
956                 fi
957         done
958
959         IFS="$ORIGINAL_IFS"
960         PATH="${PATH}${added_path}"
961         ##echo "PATH='$PATH'"
962         ##/bin/sh -c 'echo "PATH in subshell=\"$PATH\""'
963 }
964
965 # No args taken.
966 check_recommended_apps()
967 {
968         eval $LOGFS
969         local bash_array_test=( "one" "two" )
970
971         # check for array ability of bash, this is only good for the warning at this time
972         # the boolean could be used later
973         # bash version 2.05b is used in DSL
974         # bash version 3.0 is used in Puppy Linux; it has a known array bug <reference to be placed here>
975         # versions older than 3.1 don't handle arrays
976         # distro's using below 2.05b are unknown, released in 2002
977         if [[ ${bash_array_test[1]} -eq "two" ]];then
978                 B_BASH_ARRAY='true'
979         else
980                 script_debugger "Suggestion: update to Bash v3.1 for optimal inxi output"
981         fi
982         # test for a few apps that bsds may not have after initial tests
983         if [[ -n $( type -p lspci ) ]];then
984                 B_LSPCI='true'
985         fi
986         if [[ -n $BSD_TYPE ]];then
987                 if [[ -n $( type -p sysctl ) ]];then
988                         B_SYSCTL='true'
989                 fi
990                 if [[ -n $( type -p pciconf ) ]];then
991                         B_PCICONF='true'
992                 fi
993         fi
994         # now setting qdbus/dcop for first run, some systems can have both by the way
995         if [[ -n $( type -p qdbus ) ]];then
996                 B_QDBUS='true'
997         fi
998         if [[ -n $( type -p dcop ) ]];then
999                 B_DCOP='true'
1000         fi
1001         eval $LOGFE
1002 }
1003
1004 # Determine if any of the absolutely necessary tools are absent
1005 # No args taken.
1006 check_required_apps()
1007 {
1008         eval $LOGFS
1009         local app_name='' app_path=''
1010         # bc removed from deps for now
1011         local depends="df gawk grep ps readlink tr uname uptime wc"
1012         
1013         if [[ -z $BSD_TYPE  ]];then
1014                 depends="$depends lspci"
1015         elif [[ $BSD_TYPE == 'bsd' ]];then
1016                 depends="$depends sysctl"
1017                 # debian-bsd has lspci but you must be root to run it
1018         elif [[ $BSD_TYPE == 'debian-bsd' ]];then
1019                 depends="$depends sysctl lspci"
1020         fi
1021         # no need to add xprop because it will just give N/A if not there, but if we expand use of xprop,
1022         # should add that here as a test, then use the B_SHOW_DISPLAY_DATA flag to trigger the tests in de function
1023         local x_apps="xrandr xdpyinfo glxinfo" 
1024
1025         if [[ $B_RUNNING_IN_DISPLAY == 'true' ]];then
1026                 for app_name in $x_apps
1027                 do
1028                         app_path=$( type -p $app_name )
1029                         if [[ -z $app_path ]];then
1030                                 script_debugger "Resuming in non X mode: $app_name not found. For package install advice run: $SCRIPT_NAME --recommends"
1031                                 B_SHOW_DISPLAY_DATA='false'
1032                                 break
1033                         fi
1034                 done
1035         fi
1036
1037         app_name=''
1038
1039         for app_name in $depends
1040         do
1041                 app_path=$( type -p $app_name )
1042                 if [[ -z $app_path ]];then
1043                         error_handler 5 "$app_name"
1044                 fi
1045         done
1046         eval $LOGFE
1047 }
1048
1049 ## note: this is now running inside each gawk sequence directly to avoid exiting gawk
1050 ## looping in bash through arrays, then re-entering gawk to clean up, then writing back to array
1051 ## in bash. For now I'll leave this here because there's still some interesting stuff to get re methods
1052 # Enforce boilerplate and buzzword filters
1053 # args: $1 - BAN_LIST_NORMAL/BAN_LIST_CPU; $2 - string to sanitize
1054 sanitize_characters()
1055 {
1056         eval $LOGFS
1057         # Cannot use strong quotes to unquote a string with pipes in it!
1058         # bash will interpret the |'s as usual and try to run a subshell!
1059         # Using weak quotes instead, or use '"..."'
1060         echo "$2" | gawk "
1061         BEGIN {
1062                 IGNORECASE=1
1063         }
1064         {
1065                 gsub(/${!1}/,\"\")
1066                 gsub(/ [ ]+/,\" \")    ## ([ ]+) with (space)
1067                 gsub(/^ +| +$/,\"\")   ## (pipe char) with (nothing)
1068                 print                  ## prints (returns) cleaned input
1069         }"
1070         eval $LOGFE
1071 }
1072
1073 # Set the colorscheme
1074 # args: $1 = <scheme number>|<"none">
1075 set_color_scheme()
1076 {
1077         eval $LOGFS
1078         local i='' a_output_colors='' a_color_codes=''
1079
1080         if [[ $1 -ge ${#A_COLOR_SCHEMES[@]} ]];then
1081                 set -- 1
1082         fi
1083         # Set a global variable to allow checking for chosen scheme later
1084         SCHEME="$1"
1085         if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
1086                 a_color_codes=( $ANSI_COLORS )
1087         else
1088                 a_color_codes=( $IRC_COLORS )
1089         fi
1090         for (( i=0; i < ${#A_COLORS_AVAILABLE[@]}; i++ ))
1091         do
1092                 eval "${A_COLORS_AVAILABLE[i]}=\"${a_color_codes[i]}\""
1093         done
1094         IFS=","
1095         a_output_colors=( ${A_COLOR_SCHEMES[$1]} )
1096         IFS="$ORIGINAL_IFS"
1097         # then assign the colors globally
1098         C1="${!a_output_colors[0]}"
1099         C2="${!a_output_colors[1]}"
1100         CN="${!a_output_colors[2]}"
1101         # ((COLOR_SCHEME++)) ## note: why is this? ##
1102         eval $LOGFE
1103 }
1104
1105 select_default_color_scheme()
1106 {
1107         eval $LOGFS
1108         local spacer='  ' options='' user_selection='' config_variable=''
1109         local config_file="$HOME/.$SCRIPT_NAME/$SCRIPT_NAME.conf"
1110         local irc_clear="\e[0m" 
1111         local irc_gui='Unset' irc_console='Unset' irc_x_term='Unset'
1112         local console='Unset' virt_term='Unset' global='Unset' 
1113         
1114         if [[ -n $IRC_COLOR_SCHEME ]];then
1115                 irc_gui="Set: $IRC_COLOR_SCHEME"
1116         fi
1117         if [[ -n $IRC_CONS_COLOR_SCHEME ]];then
1118                 irc_console="Set: $IRC_CONS_COLOR_SCHEME"
1119         fi
1120         if [[ -n $IRC_X_TERM_COLOR_SCHEME ]];then
1121                 irc_x_term="Set: $IRC_X_TERM_COLOR_SCHEME"
1122         fi
1123         if [[ -n $VIRT_TERM_COLOR_SCHEME ]];then
1124                 virt_term="Set: $VIRT_TERM_COLOR_SCHEME"
1125         fi
1126         if [[ -n $CONSOLE_COLOR_SCHEME ]];then
1127                 console="Set: $CONSOLE_COLOR_SCHEME"
1128         fi
1129         if [[ -n $GLOBAL_COLOR_SCHEME ]];then
1130                 global="Set: $GLOBAL_COLOR_SCHEME"
1131         fi
1132         
1133         # don't want these printing in irc since they show literally
1134         if [[ $B_RUNNING_IN_SHELL != 'true' ]];then
1135                 irc_clear=''
1136         fi
1137         # first make output neutral so it's just plain default for console client
1138         set_color_scheme "0"
1139         if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
1140                 print_screen_output "Welcome to $SCRIPT_NAME! Please select the default $COLOR_SELECTION color scheme."
1141                 # print_screen_output "You will see this message only one time per user account, unless you set preferences in: /etc/$SCRIPT_NAME.conf"
1142                 print_screen_output " "
1143         fi
1144         print_screen_output "Because there is no way to know your $COLOR_SELECTION foreground/background colors, you can"
1145         print_screen_output "set your color preferences from color scheme option list below. 0 is no colors, 1 neutral."
1146         print_screen_output "After these, there are 3 sets: 1-dark or light backgrounds; 2-light backgrounds; 3-dark backgrounds."
1147         if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
1148                 print_screen_output "Please note that this will set the $COLOR_SELECTION preferences only for user: $(whoami)"
1149         fi
1150         print_screen_output "------------------------------------------------------------------------------"
1151         for (( i=0; i < ${#A_COLOR_SCHEMES[@]}; i++ ))
1152         do
1153                 if [[ $i -gt 9 ]];then
1154                         spacer=' '
1155                 fi
1156                 # only offer the safe universal defaults
1157                 case $COLOR_SELECTION in
1158                         global|irc|irc-console|irc-virtual-terminal)
1159                                 if [[ $i -gt $SAFE_COLOR_COUNT ]];then
1160                                         break
1161                                 fi
1162                                 ;;
1163                 esac
1164                 set_color_scheme $i
1165                 print_screen_output "$irc_clear $i)$spacer${C1}Card:${C2} nVidia G86 [GeForce 8400 GS] ${C1}X.Org${C2} 1.7.7"
1166         done
1167         set_color_scheme 0
1168         
1169         if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
1170                 echo -n "\e[0m"
1171                 print_screen_output "$irc_clear $i)${spacer}Remove all color settings. Restore $SCRIPT_NAME default."
1172                 print_screen_output "$irc_clear $(($i+1)))${spacer}Continue, no changes or config file setting."
1173                 print_screen_output "$irc_clear $(($i+2)))${spacer}Exit, use another terminal, or set manually."
1174                 print_screen_output "------------------------------------------------------------------------------"
1175                 print_screen_output "Simply type the number for the color scheme that looks best to your eyes for your $COLOR_SELECTION settings"
1176                 print_screen_output "and hit ENTER. NOTE: You can bring this option list up by starting $SCRIPT_NAME with option: -c plus one of these numbers:"
1177                 print_screen_output "94 (console, no X - $console); 95 (terminal, X - $virt_term); 96 (irc, gui, X - $irc_gui);"
1178                 print_screen_output "97 (irc, X, in terminal - $irc_x_term); 98 (irc, no X - $irc_console); 99 (global - $global)"
1179                 print_screen_output "Your selection(s) will be stored here: $config_file"
1180                 print_screen_output "Global overrides all individual color schemes. Individual schemes remove the global setting."
1181                 print_screen_output "------------------------------------------------------------------------------"
1182                 read user_selection
1183                 if [[ -n $( grep -Es '^([0-9]+)$' <<< "$user_selection" ) && $user_selection -lt $i ]];then
1184                         case $COLOR_SELECTION in
1185                                 irc)
1186                                         config_variable='IRC_COLOR_SCHEME'
1187                                         ;;
1188                                 irc-console)
1189                                         config_variable='IRC_CONS_COLOR_SCHEME'
1190                                         ;;
1191                                 irc-virtual-terminal)
1192                                         config_variable='IRC_X_TERM_COLOR_SCHEME'
1193                                         ;;
1194                                 console)
1195                                         config_variable='CONSOLE_COLOR_SCHEME'
1196                                         ;;
1197                                 virtual-terminal)
1198                                         config_variable='VIRT_TERM_COLOR_SCHEME'
1199                                         ;;
1200                                 global)
1201                                         config_variable='GLOBAL_COLOR_SCHEME'
1202                                         ;;
1203                         esac
1204                         set_color_scheme $user_selection
1205                         # make file/directory first if missing
1206                         if [[ ! -f $config_file ]];then
1207                                 if [[ ! -d $HOME/.$SCRIPT_NAME ]];then
1208                                         mkdir $HOME/.$SCRIPT_NAME
1209                                 fi
1210                                 touch $config_file
1211                         fi
1212                         if [[ -z $( grep -s "$config_variable=" $config_file ) ]];then
1213                                 print_screen_output "Creating and updating config file for $COLOR_SELECTION color scheme now..."
1214                                 echo "$config_variable=$user_selection" >> $config_file
1215                         else
1216                                 print_screen_output "Updating config file for $COLOR_SELECTION color scheme now..."
1217                                 sed $SED_I "s/$config_variable=.*/$config_variable=$user_selection/" $config_file
1218                         fi
1219                         # file exists now so we can go on to cleanup
1220                         case $COLOR_SELECTION in
1221                                 irc|irc-console|irc-virtual-terminal|console|virtual-terminal)
1222                                         sed $SED_I '/GLOBAL_COLOR_SCHEME=/d' $config_file
1223                                         ;;
1224                                 global)
1225                                         sed $SED_I -e '/VIRT_TERM_COLOR_SCHEME=/d' -e '/CONSOLE_COLOR_SCHEME=/d' -e '/IRC_COLOR_SCHEME=/d' \
1226                                         -e '/IRC_CONS_COLOR_SCHEME=/d' -e '/IRC_X_TERM_COLOR_SCHEME=/d' $config_file
1227                                         ;;
1228                         esac
1229                 elif [[ $user_selection == $i ]];then
1230                         print_screen_output "Removing all color settings from config file now..."
1231                         sed $SED_I -e '/VIRT_TERM_COLOR_SCHEME=/d' -e '/GLOBAL_COLOR_SCHEME=/d' -e '/CONSOLE_COLOR_SCHEME=/d' \
1232                         -e '/IRC_COLOR_SCHEME=/d' -e '/IRC_CONS_COLOR_SCHEME=/d' -e '/IRC_X_TERM_COLOR_SCHEME=/d' $config_file
1233                         set_color_scheme $DEFAULT_COLOR_SCHEME
1234                 elif [[ $user_selection == $(( $i+1 )) ]];then
1235                         print_screen_output "Ok, continuing $SCRIPT_NAME unchanged. You can set the colors anytime by starting with: -c 95 to 99"
1236                         if [[ -n $CONSOLE_COLOR_SCHEME && -z $DISPLAY ]];then
1237                                 set_color_scheme $CONSOLE_COLOR_SCHEME
1238                         elif [[ -n $VIRT_TERM_COLOR_SCHEME ]];then
1239                                 set_color_scheme $VIRT_TERM_COLOR_SCHEME
1240                         else
1241                                 set_color_scheme $DEFAULT_COLOR_SCHEME
1242                         fi
1243                 elif [[ $user_selection == $(( $i+2 )) ]];then
1244                         set_color_scheme $DEFAULT_COLOR_SCHEME
1245                         print_screen_output "Ok, exiting $SCRIPT_NAME now. You can set the colors later."
1246                         exit 0
1247                 else
1248                         print_screen_output "Error - Invalid Selection. You entered this: $user_selection"
1249                         print_screen_output " "
1250                         select_default_color_scheme
1251                 fi
1252         else
1253                 print_screen_output "------------------------------------------------------------------------------"
1254                 print_screen_output "After finding the scheme number you like, simply run this again in a terminal to set the configuration"
1255                 print_screen_output "data file for your irc client. You can set color schemes for the following: start inxi with -c plus:"
1256                 print_screen_output "94 (console, no X - $console); 95 (terminal, X - $virt_term); 96 (irc, gui, X - $irc_gui);"
1257                 print_screen_output "97 (irc, X, in terminal - $irc_x_term); 98 (irc, no X - $irc_console); 99 (global - $global)"
1258                 exit 0
1259         fi
1260
1261         eval $LOGFE
1262 }
1263
1264 ########################################################################
1265 #### UTILITY FUNCTIONS
1266 ########################################################################
1267
1268 #### -------------------------------------------------------------------
1269 #### error handler, debugger, script updater
1270 #### -------------------------------------------------------------------
1271
1272 # Error handling
1273 # args: $1 - error number; $2 - optional, extra information; $3 - optional extra info
1274 error_handler()
1275 {
1276         eval $LOGFS
1277         local error_message=''
1278
1279         # assemble the error message
1280         case $1 in
1281                 2)      error_message="large flood danger, debug buffer full!"
1282                         ;;
1283                 3)      error_message="unsupported color scheme number: $2"
1284                         ;;
1285                 4)      error_message="unsupported verbosity level: $2"
1286                         ;;
1287                 5)      error_message="dependency not met: $2 not found in path.\nFor distribution installation package names and missing apps information, run: $SCRIPT_NAME --recommends"
1288                         ;;
1289                 6)      error_message="/proc not found! Quitting..."
1290                         ;;
1291                 7)      error_message="One of the options you entered in your script parameters: $2\nis not supported.The option may require extra arguments to work.\nFor supported options (and their arguments), check the help menu: $SCRIPT_NAME -h"
1292                         ;;
1293                 8)      error_message="the self-updater failed, wget exited with error: $2.\nYou probably need to be root.\nHint, to make for easy updates without being root, do: chown <user name> $SCRIPT_PATH/$SCRIPT_NAME"
1294                         ;;
1295                 9)      error_message="unsupported debugging level: $2"
1296                         ;;
1297                 10)
1298                         error_message="the alt download url you provided: $2\nappears to be wrong, download aborted. Please note, the url\nneeds to end in /, without $SCRIPT_NAME, like: http://yoursite.com/downloads/"
1299                         ;;
1300                 11)
1301                         error_message="unsupported testing option argument: -! $2"
1302                         ;;
1303                 12)
1304                         error_message="the svn branch download url: $2\nappears to be empty currently. Make sure there is an actual svn branch version\nactive before you try this again. Check http://code.google.com/p/inxi\nto verify the branch status."
1305                         ;;
1306                 13)
1307                         error_message="The -t option requires the following extra arguments (no spaces between letters/numbers):\nc m cm [required], for example: -t cm8 OR -t cm OR -t c9\n(numbers: 1-20, > 5 throttled to 5 in irc clients) You entered: $2"
1308                         ;;
1309                 14)
1310                         error_message="failed to write correctly downloaded $SCRIPT_NAME to location $SCRIPT_PATH.\nThis usually means you don't have permission to write to that location, maybe you need to be root?\nThe operation failed with error: $2"
1311                         ;;
1312                 15)
1313                         error_message="failed set execute permissions on $SCRIPT_NAME at location $SCRIPT_PATH.\nThis usually means you don't have permission to set permissions on files there, maybe you need to be root?\nThe operation failed with error: $2"
1314                         ;;
1315                 16)
1316                         error_message="$SCRIPT_NAME downloaded but the file data is corrupted. Purged data and using current version."
1317                         ;;
1318                 17)
1319                         error_message="All $SCRIPT_NAME self updater features have been disabled by the distribution\npackage maintainer. This includes the option you used: $2"
1320                         ;;
1321                 18)
1322                         error_message="The argument you provided for $2 does not have supported syntax.\nPlease use the following formatting:\n$3"
1323                         ;;
1324                 19)
1325                         error_message="The option $2 has been deprecated. Please use $3 instead.\nSee -h for instructions and syntax."
1326                         ;;
1327                 20)
1328                         error_message="The option you selected has been deprecated. $2\nSee the -h (help) menu for currently supported options."
1329                         ;;
1330                 *)      error_message="error unknown: $@"
1331                         set -- 99
1332                         ;;
1333         esac
1334         # then print it and exit
1335         print_screen_output "Error $1: $error_message"
1336         eval $LOGFE
1337         exit $1
1338 }
1339
1340 # prior to script up set, pack the data into an array
1341 # then we'll print it out later.
1342 # args: $1 - $@ debugging string text
1343 script_debugger()
1344 {
1345         eval $LOGFS
1346         if [[ $B_SCRIPT_UP == 'true' ]];then
1347                 # only return if debugger is off and no pre start up errors have occured
1348                 if [[ $DEBUG -eq 0 && $DEBUG_BUFFER_INDEX -eq 0 ]];then
1349                         return 0
1350                 # print out the stored debugging information if errors occured
1351                 elif [[ $DEBUG_BUFFER_INDEX -gt 0 ]];then
1352                         for (( DEBUG_BUFFER_INDEX=0; DEBUG_BUFFER_INDEX < ${#A_DEBUG_BUFFER[@]}; DEBUG_BUFFER_INDEX++ ))
1353                         do
1354                                 print_screen_output "${A_DEBUG_BUFFER[$DEBUG_BUFFER_INDEX]}"
1355                         done
1356                         DEBUG_BUFFER_INDEX=0
1357                 fi
1358                 # or print out normal debugger messages if debugger is on
1359                 if [[ $DEBUG -gt 0 ]];then
1360                         print_screen_output "$1"
1361                 fi
1362         else
1363                 if [[ $B_DEBUG_FLOOD == 'true' && $DEBUG_BUFFER_INDEX -gt 10 ]];then
1364                         error_handler 2
1365                 # this case stores the data for later printout, will print out only
1366                 # at B_SCRIPT_UP == 'true' if array index > 0
1367                 else
1368                         A_DEBUG_BUFFER[$DEBUG_BUFFER_INDEX]="$1"
1369                         # increment count for next pre script up debugging error
1370                         (( DEBUG_BUFFER_INDEX++ ))
1371                 fi
1372         fi
1373         eval $LOGFE
1374 }
1375
1376 # NOTE: no logging available until get_parameters is run, since that's what sets logging
1377 # in order to trigger earlier logging manually set B_USE_LOGGING to true in top variables.
1378 # $1 alone: logs data; $2 with or without $3 logs func start/end.
1379 # $1 type (fs/fe/cat/raw) or logged data; [$2 is $FUNCNAME; [$3 - function args]]
1380 log_function_data()
1381 {
1382         if [ "$B_USE_LOGGING" == 'true' ];then
1383                 local logged_data='' spacer='   ' line='----------------------------------------'
1384                 case $1 in
1385                         fs)
1386                                 logged_data="Function: $2 - Primary: Start"
1387                                 if [ -n "$3" ];then
1388                                         logged_data="$logged_data\n${spacer}Args: $3"
1389                                 fi
1390                                 spacer=''
1391                                 ;;
1392                         fe)
1393                                 logged_data="Function: $2 - Primary: End"
1394                                 spacer=''
1395                                 ;;
1396                         cat)
1397                                 if [[ $B_LOG_FULL_DATA == 'true' ]];then
1398                                         logged_data="\n$line\nFull file data: cat $2\n\n$( cat $2 )\n$line\n"
1399                                         spacer=''
1400                                 fi
1401                                 ;;
1402                         raw)
1403                                 if [[ $B_LOG_FULL_DATA == 'true' ]];then
1404                                         logged_data="\n$line\nRaw system data:\n\n$2\n$line\n"
1405                                         spacer=''
1406                                 fi
1407                                 ;;
1408                         *)
1409                                 logged_data="$1"
1410                                 ;;
1411                 esac
1412                 # Create any required line breaks and strip out escape color code, either ansi (case 1)or irc (case 2).
1413                 # This pattern doesn't work for irc colors, if we need that someone can figure it out
1414                 if [[ -n $logged_data ]];then
1415                         if [[ $B_LOG_COLORS != 'true' ]];then
1416                                 echo -e "${spacer}$logged_data" | sed $SED_RX 's/\x1b\[[0-9]{1,2}(;[0-9]{1,2}){0,2}m//g' >> $LOG_FILE
1417                         else
1418                                 echo -e "${spacer}$logged_data" >> $LOG_FILE
1419                         fi
1420                 fi
1421         fi
1422 }
1423
1424 # called in the initial -@ 10 script args setting so we can get logging as soon as possible
1425 # will have max 3 files, inxi.log, inxi.1.log, inxi.2.log
1426 create_rotate_logfiles()
1427 {
1428         if [[ ! -d $SCRIPT_DATA_DIR ]];then
1429                 mkdir $SCRIPT_DATA_DIR
1430         fi
1431         # do the rotation if logfile exists
1432         if [[ -f $LOG_FILE ]];then
1433                 # copy if present second to third
1434                 if [[ -f $LOG_FILE_1 ]];then
1435                         mv -f $LOG_FILE_1 $LOG_FILE_2
1436                 fi
1437                 # then copy initial to second
1438                 mv -f $LOG_FILE $LOG_FILE_1
1439         fi
1440         # now create the logfile
1441         touch $LOG_FILE
1442         # and echo the start data
1443         echo "=========================================================" >> $LOG_FILE
1444         echo "START $SCRIPT_NAME LOGGING:"                               >> $LOG_FILE
1445         echo "Script started: $( date +%Y-%m-%d-%H:%M:%S )"              >> $LOG_FILE
1446         echo "=========================================================" >> $LOG_FILE
1447 }
1448
1449 # args: $1 - download url, not including file name; $2 - string to print out
1450 # $3 - update type option
1451 # note that $1 must end in / to properly construct the url path
1452 script_self_updater()
1453 {
1454         eval $LOGFS
1455         local wget_error=0 file_contents='' wget_man_error=0 
1456         local man_file_path="$MAN_FILE_LOCATION/inxi.1.gz"
1457         
1458         if [[ $B_RUNNING_IN_SHELL != 'true' ]];then
1459                 print_screen_output "Sorry, you can't run the $SCRIPT_NAME self updater option (-$3) in an IRC client."
1460                 exit 1
1461         fi
1462
1463         print_screen_output "Starting $SCRIPT_NAME self updater."
1464         print_screen_output "Currently running $SCRIPT_NAME version number: $SCRIPT_VERSION_NUMBER"
1465         print_screen_output "Current version patch number: $SCRIPT_PATCH_NUMBER"
1466         print_screen_output "Updating $SCRIPT_NAME in $SCRIPT_PATH using $2 as download source..."
1467
1468         file_contents="$( wget -q -O - $1$SCRIPT_NAME )" || wget_error=$?
1469         # then do the actual download
1470         if [[  $wget_error -eq 0 ]];then
1471                 # make sure the whole file got downloaded and is in the variable
1472                 if [[ -n $( grep '###\*\*EOF\*\*###' <<< "$file_contents" ) ]];then
1473                         echo "$file_contents" > $SCRIPT_PATH/$SCRIPT_NAME || error_handler 14 "$?"
1474                         chmod +x $SCRIPT_PATH/$SCRIPT_NAME || error_handler 15 "$?"
1475                         SCRIPT_VERSION_NUMBER=$( parse_version_data 'main' )
1476                         SCRIPT_PATCH_NUMBER=$( parse_version_data 'patch' )
1477                         print_screen_output "Successfully updated to $2 version: $SCRIPT_VERSION_NUMBER"
1478                         print_screen_output "New $2 version patch number: $SCRIPT_PATCH_NUMBER"
1479                         print_screen_output "To run the new version, just start $SCRIPT_NAME again."
1480                         print_screen_output "----------------------------------------"
1481                         print_screen_output "Starting download of man page file now."
1482                         if [[ ! -d $MAN_FILE_LOCATION ]];then
1483                                 print_screen_output "The required man directory was not detected on your system, unable to continue: $MAN_FILE_LOCATION"
1484                         else
1485                                 if [[ $B_ROOT == 'true' ]];then
1486                                         print_screen_output "Checking Man page download URL..."
1487                                         if [[ -f /usr/share/man/man8/inxi.8.gz ]];then
1488                                                 print_screen_output "Updating man page location to man1."
1489                                                 mv -f /usr/share/man/man8/inxi.8.gz /usr/share/man/man1/inxi.1.gz 
1490                                                 if [[ -n $( type -p mandb ) ]];then
1491                                                         exec $( type -p mandb ) -q 
1492                                                 fi
1493                                         fi
1494                                         wget -q --spider $MAN_FILE_DOWNLOAD || wget_man_error=$?
1495                                         if [[ $wget_man_error -eq 0 ]];then
1496                                                 print_screen_output "Man file download URL verified: $MAN_FILE_DOWNLOAD"
1497                                                 print_screen_output "Downloading Man page file now."
1498                                                 wget -q -O $man_file_path $MAN_FILE_DOWNLOAD || wget_man_error=$?
1499                                                 if [[ $wget_man_error -gt 0 ]];then
1500                                                         print_screen_output "Oh no! Something went wrong downloading the Man gz file at: $MAN_FILE_DOWNLOAD"
1501                                                         print_screen_output "Check the error messages for what happened. Error: $wget_man_error"
1502                                                 else
1503                                                         print_screen_output "Download/install of man page successful. Check to make sure it works: man inxi"
1504                                                 fi
1505                                         else
1506                                                 print_screen_output "Man file download URL failed, unable to continue: $MAN_FILE_DOWNLOAD"
1507                                         fi
1508                                 else
1509                                         print_screen_output "Updating / Installing the Man page requires root user, writing to: $MAN_FILE_LOCATION"
1510                                         print_screen_output "If you want the man page, you'll have to run $SCRIPT_NAME -$3 as root."
1511                                 fi
1512                         fi
1513                         exit 0
1514                 else
1515                         error_handler 16
1516                 fi
1517         # now run the error handlers on any wget failure
1518         else
1519                 if [[ $2 == 'svn server' ]];then
1520                         error_handler 8 "$wget_error"
1521                 elif [[ $2 == 'alt server' ]];then
1522                         error_handler 10 "$1"
1523                 else
1524                         error_handler 12 "$1"
1525                 fi
1526         fi
1527         eval $LOGFS
1528 }
1529
1530 # args: $1 - debug data type: sys|xorg|disk
1531 debug_data_collector()
1532 {
1533         local xiin_app='' xiin_data_file='' xiin_download='' error='' b_run_xiin='false'
1534         local debug_data_dir='' bsd_string=''
1535         local completed_gz_file='' xiin_file='xiin.py' ftp_upload='ftp.techpatterns.com/incoming'
1536         local Line='-------------------------'
1537         local start_directory=$( pwd )
1538         
1539         if [[ -n $BSD_TYPE ]];then
1540                 bsd_string="$BSD_TYPE-"
1541         fi
1542         
1543         debug_data_dir="inxi-$bsd_string$(tr ' ' '-' <<< $HOSTNAME | tr '[A-Z]' '[a-z]' )-$1-$(date +%Y%m%d)" 
1544         
1545         if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
1546                 if [[ -n $ALTERNATE_FTP ]];then
1547                         ftp_upload=$ALTERNATE_FTP
1548                 fi
1549                 echo "Starting debugging data collection type: $1"
1550                 echo -n "Checking/creating required directories... "
1551                 if [[ ! -d $SCRIPT_DATA_DIR ]];then
1552                         mkdir $SCRIPT_DATA_DIR
1553                 fi
1554                 echo 'completed'
1555                 cd $SCRIPT_DATA_DIR
1556                 if [[ -d $SCRIPT_DATA_DIR/$debug_data_dir ]];then
1557                         echo 'Deleting previous xiin data directory...'
1558                         rm -rf $SCRIPT_DATA_DIR/$debug_data_dir
1559                 fi
1560                 mkdir $SCRIPT_DATA_DIR/$debug_data_dir
1561                 if [[ -f $SCRIPT_DATA_DIR/$debug_data_dir.tar.gz ]];then
1562                         echo 'Deleting previous tar.gz file...'
1563                         rm -f $SCRIPT_DATA_DIR/$debug_data_dir.tar.gz
1564                 fi
1565                 
1566                 echo 'Collecting system info: sensors, lsusb, lspci, lspci -v data, plus /proc data'
1567                 echo 'also checking for dmidecode data: note, you must be root to have dmidecode work.'
1568                 echo "Data going into: $SCRIPT_DATA_DIR/$debug_data_dir"
1569                 # bsd tools
1570                 pciconf -vl &> $debug_data_dir/bsd-pciconf-vl.txt
1571                 sysctl -a &> $debug_data_dir/bsd-sysctl-a.txt
1572                 
1573                 dmidecode &> $debug_data_dir/dmidecode.txt
1574                 
1575                 lscpu &> $debug_data_dir/lscpu.txt
1576                 lspci &> $debug_data_dir/lspci.txt
1577                 lspci -n &> $debug_data_dir/lspci-n.txt
1578                 lspci -v &> $debug_data_dir/lspci-v.txt
1579                 lsusb &> $debug_data_dir/lsusb.txt
1580                 ps aux &> $debug_data_dir/ps-aux.txt
1581                 runlevel &> $debug_data_dir/runlevel.txt
1582                 systemctl list-units &> $debug_data_dir/systemctl-list-units.txt
1583                 systemctl list-units --type=target &> $debug_data_dir/systemctl-list-units-target.txt
1584                 initctl list &> $debug_data_dir/initctl-list.txt
1585                 sensors &> $debug_data_dir/sensors.txt
1586                 strings --version  &> $debug_data_dir/strings.txt
1587                 nvidia-smi -q &> $debug_data_dir/nvidia-smi-q.txt
1588                 nvidia-smi -q -x &> $debug_data_dir/nvidia-smi-xq.txt
1589                 
1590                 ls /usr/bin/gcc* &> $debug_data_dir/gcc-sys-versions.txt
1591                 gcc --version &> $debug_data_dir/gcc-version.txt
1592                 cat /etc/issue &> $debug_data_dir/etc-issue.txt
1593                 cat $FILE_LSB_RELEASE &> $debug_data_dir/lsb-release.txt
1594                 cat $FILE_OS_RELEASE &> $debug_data_dir/os-release.txt
1595                 cat $FILE_ASOUND_DEVICE &> $debug_data_dir/proc-asound-device.txt
1596                 cat $FILE_ASOUND_VERSION &> $debug_data_dir/proc-asound-version.txt
1597                 cat $FILE_CPUINFO &> $debug_data_dir/proc-cpu-info.txt
1598                 cat $FILE_MEMINFO &> $debug_data_dir/proc-meminfo.txt
1599                 cat $FILE_MODULES &> $debug_data_dir/proc-modules.txt
1600                 cat /proc/net/arp &> $debug_data_dir/proc-net-arp.txt 
1601                 # bsd data
1602                 cat /var/run/dmesg.boot &> $debug_data_dir/bsd-var-run-dmesg.boot.txt 
1603                 
1604                 check_recommends_user_output &> $debug_data_dir/check-recommends-user-output.txt
1605                 # first download and verify xiin
1606                 if [[ $B_UPLOAD_DEBUG_DATA == 'true' || $1 == 'disk' || $1 == 'sys' || $1 == 'all' ]];then
1607                         touch $SCRIPT_DATA_DIR/$debug_data_dir/xiin-error.txt
1608                         echo "Downloading required tree traverse tool $xiin_file..."
1609                         if [[ -f xiin && ! -f $xiin_file ]];then
1610                                 mv -f xiin $xiin_file
1611                         fi
1612                         # -Nc is creating really weird download anomolies, so using -O instead
1613                         xiin_download="$( wget -q -O - http://inxi.googlecode.com/svn/branches/xiin/$xiin_file )"
1614                         # if nothing got downloaded kick out error, otherwise we'll use an older version
1615                         if [[ $? -gt 0 && ! -f $xiin_file ]];then
1616                                 echo -e "ERROR: Failed to download required file: $xiin_file\nMaybe the remote site is down or your networking is broken?"
1617                                 echo "Continuing with incomplete data collection."
1618                                 echo "$xiin_file download failed and no existing $xiin_file" >> $debug_data_dir/xiin-error.txt
1619                         elif [[ -n $( grep -s '# EOF' <<< "$xiin_download" ) || -f $xiin_file ]];then
1620                                 if [[ -n $( grep -s '# EOF' <<< "$xiin_download" ) ]];then
1621                                         echo "Updating $xiin_file from remote location"
1622                                         echo "$xiin_download" > $xiin_file
1623                                 else
1624                                         echo "Using local $xiin_file due to download failure"
1625                                 fi
1626                                 b_run_xiin='true'
1627                         else
1628                                 echo -e "ERROR: $xiin_file downloaded but the program file data is corrupted.\nContinuing with incomplete data collection."
1629                                 echo "$xiin_file downloaded but the program file data is corrupted." >> $debug_data_dir/xiin-error.txt
1630                         fi
1631                 fi
1632                 # note, only bash 4> supports ;;& for case, so using if/then here
1633                 if [[ $1 == 'disk' || $1 == 'sys' || $1 == 'all' ]];then
1634                         xiin_data_file=$SCRIPT_DATA_DIR/$debug_data_dir/xiin-sys.txt
1635                         echo 'Collecting networking data...'
1636                         ifconfig &> $debug_data_dir/ifconfig.txt
1637                         ip addr &> $debug_data_dir/ip-addr.txt
1638                         if [[ $b_run_xiin == 'true' && -z $BSD_TYPE ]];then
1639                                 echo $Line
1640                                 echo "Running $xiin_file tool now on /sys..."
1641                                 echo "Using Python version:" && python --version
1642                                 python --version &> $debug_data_dir/python-version.txt
1643                                 python ./$xiin_file -d /sys -f $xiin_data_file
1644                                 if [[ $? -ne 0 ]];then
1645                                         error=$?
1646                                         echo -e "ERROR: $xiin_file exited with error $error - removing data file.\nContinuing with incomplete data collection."
1647                                         echo "Continuing with incomplete data collection."
1648                                         rm -f $xiin_data_file
1649                                         echo "$xiin_file data generation failed with python error $error" >> $debug_data_dir/xiin-error.txt
1650                                 fi
1651                                 echo $Line
1652                         fi
1653                 fi
1654                 if [[ $1 == 'xorg' || $1 == 'all' ]];then
1655                         if [[ $B_RUNNING_IN_DISPLAY != 'true' ]];then
1656                                 echo 'Warning: only some of the data collection can occur if you are not in X'
1657                                 touch $debug_data_dir/warning-user-not-in-x
1658                         fi
1659                         if [[ $B_ROOT == 'true' ]];then
1660                                 echo 'Warning: only some of the data collection can occur if you are running as Root user'
1661                                 touch $debug_data_dir/warning-root-user
1662                         fi
1663                         echo 'Collecting Xorg log and xorg.conf files'
1664                         if [[ -e $FILE_XORG_LOG ]];then
1665                                 cat $FILE_XORG_LOG &> $debug_data_dir/xorg-log-file.txt
1666                         else
1667                                 touch $debug_data_dir/no-xorg-log-file
1668                         fi
1669                         if [[ -e /etc/X11/xorg.conf ]];then
1670                                 cp /etc/X11/xorg.conf $SCRIPT_DATA_DIR/$debug_data_dir
1671                         else
1672                                 touch $debug_data_dir/no-xorg-conf-file
1673                         fi
1674                         if [[ -n $( ls /etc/X11/xorg.conf.d/ 2>/dev/null ) ]];then
1675                                 ls /etc/X11/xorg.conf.d &> $debug_data_dir/ls-etc-x11-xorg-conf-d.txt
1676                                 cp /etc/X11/xorg.conf.d $SCRIPT_DATA_DIR/$debug_data_dir
1677                         else
1678                                 touch $debug_data_dir/no-xorg-conf-d-files
1679                         fi
1680                         echo 'Collecting X, xprop, glxinfo, xrandr, xdpyinfo data...'
1681                         xprop -root &> $debug_data_dir/xprop_root.txt
1682                         glxinfo &> $debug_data_dir/glxinfo.txt
1683                         xdpyinfo &> $debug_data_dir/xdpyinfo.txt
1684                         xrandr &> $debug_data_dir/xrandr.txt
1685                         X -version &> $debug_data_dir/x-version.txt
1686                         Xorg -version &> $debug_data_dir/xorg-version.txt
1687                         echo $GNOME_DESKTOP_SESSION_ID &> $debug_data_dir/gnome-desktop-session-id.txt
1688                         # kde 3 id
1689                         echo $KDE_FULL_SESSION &> $debug_data_dir/kde3-ful-session.txt
1690                         echo $KDE_SESSION_VERSION &> $debug_data_dir/kde456-session-version.txt
1691                         echo "$(kded$KDE_SESSION_VERSION --version )" &> $debug_data_dir/kde-version-data.txt
1692                         echo $XDG_CURRENT_DESKTOP &> $debug_data_dir/xdg-current-desktop.txt
1693                 fi
1694                 if [[ $1 == 'disk' || $1 == 'all' ]];then
1695                         echo 'Collecting dev, label, disk, uuid data, df...'
1696                         ls -l /dev &> $debug_data_dir/dev-data.txt
1697                         ls -l /dev/disk &> $debug_data_dir/dev-disk-data.txt
1698                         ls -l /dev/disk/by-id &> $debug_data_dir/dev-disk-id-data.txt
1699                         ls -l /dev/disk/by-label &> $debug_data_dir/dev-disk-label-data.txt
1700                         ls -l /dev/disk/by-uuid &> $debug_data_dir/dev-disk-uuid-data.txt
1701                         ls -l /dev/disk/by-path &> $debug_data_dir/dev-disk-path-data.txt
1702                         ls -l /dev/mapper &> $debug_data_dir/dev-disk-mapper-data.txt
1703                         readlink /dev/root &> $debug_data_dir/dev-root.txt
1704                         df -h -T -P --exclude-type=aufs --exclude-type=squashfs --exclude-type=unionfs --exclude-type=devtmpfs --exclude-type=tmpfs --exclude-type=iso9660 --exclude-type=devfs --exclude-type=linprocfs --exclude-type=sysfs --exclude-type=fdescfs &> $debug_data_dir/df-h-T-P-excludes.txt
1705                         df -T -P --exclude-type=aufs --exclude-type=squashfs --exclude-type=unionfs --exclude-type=devtmpfs --exclude-type=tmpfs --exclude-type=iso9660 --exclude-type=devfs --exclude-type=linprocfs --exclude-type=sysfs --exclude-type=fdescfs &> $debug_data_dir/df-T-P-excludes.txt
1706                         df -H -T &> $debug_data_dir/bsd-df-H-T-no-excludes.txt
1707                         df -H &> $debug_data_dir/bsd-df-H-no-excludes.txt
1708                         # bsd tool
1709                         mount &> $debug_data_dir/mount.txt
1710                         gpart list &> $debug_data_dir/bsd-gpart-list.txt
1711                         gpart show &> $debug_data_dir/bsd-gpart-show.txt
1712                         gpart status &> $debug_data_dir/bsd-gpart-status.txt
1713                         swapctl -l &> $debug_data_dir/bsd-swapctl-l.txt
1714                         swapon -s &> $debug_data_dir/swapon-s.txt
1715                         sysctl -b kern.geom.conftxt  &> $debug_data_dir/bsd-sysctl-b-kern.geom.conftxt.txt
1716                         sysctl -b kern.geom.confxml &> $debug_data_dir/bsd-sysctl-b-kern.geom.confxml.txt
1717                         zfs list &> $debug_data_dir/bsd-zfs-list.txt
1718                         zpool list &> $debug_data_dir/bsd-zpool-list.txt
1719                         zpool list -v &> $debug_data_dir/bsd-zpool-list-v.txt
1720                         df -P --exclude-type=aufs --exclude-type=squashfs --exclude-type=unionfs --exclude-type=devtmpfs --exclude-type=tmpfs --exclude-type=iso9660 &> $debug_data_dir/df-P-excludes.txt
1721                         df -P &> $debug_data_dir/bsd-df-P-no-excludes.txt
1722                         cat /proc/mdstat &> $debug_data_dir/proc-mdstat.txt
1723                         cat $FILE_PARTITIONS &> $debug_data_dir/proc-partitions.txt
1724                         cat $FILE_SCSI &> $debug_data_dir/proc-scsi.txt
1725                         cat $FILE_MOUNTS &> $debug_data_dir/proc-mounts.txt
1726                         cat /proc/sys/dev/cdrom/info &> $debug_data_dir/proc-cdrom-info.txt
1727                         ls /proc/ide/ &> $debug_data_dir/proc-ide.txt
1728                         cat /proc/ide/*/* &> $debug_data_dir/proc-ide-hdx-cat.txt
1729                         cat /etc/fstab &> $debug_data_dir/etc-fstab.txt
1730                         cat /etc/mtab &> $debug_data_dir/etc-mtab.txt
1731                 fi
1732                 echo 'Creating inxi output file now. This can take a few seconds...'
1733                 echo "Starting $SCRIPT_NAME from: $start_directory"
1734                 cd $start_directory
1735                 $SCRIPT_PATH/$SCRIPT_NAME -FRploudxxx -c 0 -@ 8 > $SCRIPT_DATA_DIR/$debug_data_dir/inxi-FRploudxxx.txt
1736                 cp $LOG_FILE $SCRIPT_DATA_DIR/$debug_data_dir
1737                 if [[ -f $SCRIPT_DATA_DIR/$debug_data_dir.tar.gz ]];then
1738                         echo "Found and removing previous tar.gz data file: $debug_data_dir.tar.gz"
1739                         rm -f $SCRIPT_DATA_DIR/$debug_data_dir.tar.gz
1740                 fi
1741                 cd $SCRIPT_DATA_DIR
1742                 echo 'Creating tar.gz compressed file of this material now. Contents:'
1743                 echo $Line
1744                 tar -cvzf $debug_data_dir.tar.gz $debug_data_dir
1745                 echo $Line
1746                 echo 'Cleaning up leftovers...'
1747                 rm -rf $debug_data_dir
1748                 echo 'Testing gzip file integrity...'
1749                 gzip -t $debug_data_dir.tar.gz
1750                 if [[ $? -gt 0 ]];then
1751                         echo 'Data in gz is corrupted, removing gzip file, try running data collector again.'
1752                         rm -f $debug_data_dir.tar.gz
1753                         echo "Data in gz is corrupted, removed gzip file" >> $debug_data_dir/gzip-error.txt
1754                 else
1755                         echo 'All done, you can find your data gzipped directory here:'
1756                         completed_gz_file=$SCRIPT_DATA_DIR/$debug_data_dir.tar.gz
1757                         echo $completed_gz_file
1758                         if [[ $B_UPLOAD_DEBUG_DATA == 'true' ]];then
1759                                 echo $Line
1760                                 if [[ $b_run_xiin == 'true' ]];then
1761                                         echo "Running automatic upload of data to remote server $ftp_upload now..."
1762                                         python ./$xiin_file --version
1763                                         python ./$xiin_file -u $completed_gz_file $ftp_upload
1764                                         if [[ $? -gt 0 ]];then
1765                                                 echo $Line
1766                                                 echo "Error: looks like the ftp upload failed. Error number: $?"
1767                                                 echo "The ftp upload failed. Error number: $?" >> $debug_data_dir/xiin-error.txt
1768                                         fi
1769                                 else
1770                                         echo 'Unable to run the automoatic ftp upload because of an error with the xiin download.'
1771                                         echo "Unable to run the automoatic ftp upload because of an error with the xiin download" >> $debug_data_dir/xiin-error.txt
1772                                 fi
1773                         else
1774                                 echo 'You can upload this here using most file managers: ftp.techpatterns.com/incoming'
1775                                 echo 'then let a maintainer know it is uploaded.'
1776                         fi
1777                 fi
1778         else
1779                 echo 'This feature only available in console or shell client! Exiting now.'
1780         fi
1781         exit 0
1782 }
1783
1784 check_recommends_user_output()
1785 {
1786         local Line='-----------------------------------------------------------------------------------------'
1787         local gawk_version='N/A' sed_version='N/A' sudo_version='N/A' python_version='N/A'
1788         
1789         if [[ $B_RUNNING_IN_SHELL != 'true' ]];then
1790                 print_screen_output "Sorry, you can't run this option in an IRC client."
1791                 exit 1
1792         fi
1793         
1794         initialize_paths
1795         
1796         echo "$SCRIPT_NAME will now begin checking for the programs it needs to operate. First a check of"
1797         echo "the main languages and tools $SCRIPT_NAME uses. Python is only for debugging data collection."
1798         echo $Line
1799         echo "Bash version: $( bash --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^GNU bash/ {print $4}' )"
1800         if [[ -n $( type -p gawk ) ]];then
1801                 gawk_version=$( gawk --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^GNU Awk/ {print $3}' )
1802         fi
1803         if [[ -n $( type -p sed ) ]];then
1804                 sed_version=$( sed --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^GNU sed version/ {print $4}' )
1805                 if [[ -z $sed_version ]];then
1806                         # note: bsd sed shows error with --version flag
1807                         sed_version=$( sed --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^sed: illegal option/ {print "BSD sed"}' )
1808                 fi
1809         fi
1810         if [[ -n $( type -p sudo ) ]];then
1811                 sudo_version=$( sudo -V 2>&1 | awk 'BEGIN {IGNORECASE=1} /^Sudo version/ {print $3}' )
1812         fi
1813         if [[ -n $( type -p python ) ]];then
1814                 python_version=$( python --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^Python/ {print $2}' )
1815         fi
1816         echo "Gawk version: $gawk_version"
1817         echo "Sed version: $sed_version"
1818         echo "Sudo version: $sudo_version"
1819         echo "Python version: $python_version"
1820         echo $Line
1821         echo "Test One: Required System Directories."
1822         echo "If one of these system directories is missing, $SCRIPT_NAME cannot operate:"
1823         echo 
1824         check_recommends_items 'required-dirs'
1825         echo "Test Two: Required Core Applications."
1826         echo "If one of these applications is missing, $SCRIPT_NAME cannot operate:"
1827         echo 
1828         check_recommends_items 'required-apps'
1829         echo 'Test Three: Script Recommends for Graphics Features. If you do not use X these do not matter.'
1830         echo "If one of these applications is missing, $SCRIPT_NAME will have incomplete output:"
1831         echo 
1832         check_recommends_items 'recommended-x-apps'
1833         echo 'Test Four: Script Recommends for Remaining Features.' 
1834         echo "If one of these applications is missing, $SCRIPT_NAME will have incomplete output:"
1835         echo 
1836         check_recommends_items 'recommended-apps'
1837         echo 'Test Five: System Directories for Various Information.' 
1838         echo "If one of these directories is missing, $SCRIPT_NAME will have incomplete output:"
1839         echo 
1840         check_recommends_items 'system-dirs'
1841         echo 'All tests completed.' 
1842 }
1843 # args: $1 - check item
1844 check_recommends_items()
1845 {
1846         local item='' item_list='' item_string='' missing_items='' missing_string=''
1847         local package='' application='' feature='' type='' starter='' finisher=''
1848         local package_deb='' package_pacman='' package_rpm='' 
1849         local print_string='' separator=''
1850         local required_dirs='/proc /sys'
1851         # package-owner: 1 - debian/ubuntu; 2 - arch; 3 - yum/rpm
1852         # pardus: pisi sf -q /usr/bin/package
1853         local required_apps='
1854         df:coreutils~coreutils~coreutils~:partition_data 
1855         gawk:gawk~gawk~gawk~:core_tool
1856         grep:grep~grep~grep~:string_search 
1857         lspci:pciutils~pciutils~pciutils~:hardware_data 
1858         ps:procps~procps~procps~:process_data 
1859         readlink:coreutils~coreutils~coreutils~: 
1860         sed:sed~sed~sed~:string_replace 
1861         tr:coreutils~coreutils~coreutils~:character_replace 
1862         uname:uname~coreutils~coreutils~:kernel_data 
1863         uptime:procps~procps~procps~: 
1864         wc:coreutils~coreutils~coreutils~:word_character_count
1865         '
1866         local x_recommends='
1867         glxinfo:mesa-utils~mesa-demos~glx-utils_(openSUSE_12.3_and_later_Mesa-demo-x)~:-G_glx_info 
1868         xdpyinfo:X11-utils~xorg-xdpyinfo~xorg-x11-utils~:-G_multi_screen_resolution 
1869         xprop:X11-utils~xorg-xprop~x11-utils~:-S_desktop_data 
1870         xrandr:x11-xserver-utils~xrandr~x11-server-utils~:-G_single_screen_resolution
1871         '
1872         local recommended_apps='
1873         dmidecode:dmidecode~dmidecode~dmidecode~:-M_if_no_sys_machine_data 
1874         file:file~file~file~:-o_unmounted_file_system
1875         hddtemp:hddtemp~hddtemp~hddtemp~:-Dx_show_hdd_temp 
1876         ifconfig:net-tools~net-tools~net-tools~:-i_ip_lan-deprecated
1877         ip:iproute~iproute2~iproute~:-i_ip_lan
1878         sensors:lm-sensors~lm_sensors~lm-sensors~:-s_sensors_output
1879         strings:binutils~~~:-I_sysvinit_version
1880         lsusb:usbutils~usbutils~usbutils~:-A_usb_audio;-N_usb_networking 
1881         modinfo:module-init-tools~module-init-tools~module-init-tools~:-Ax,-Nx_module_version 
1882         runlevel:sysvinit~sysvinit~systemd~:-I_runlevel
1883         sudo:sudo~sudo~sudo~:-Dx_hddtemp-user;-o_file-user
1884         '
1885         local recommended_dirs='
1886         /sys/class/dmi/id:-M_system,_motherboard,_bios
1887         /dev:-l,-u,-o,-p,-P,-D_disk_partition_data
1888         /dev/disk/by-label:-l,-o,-p,-P_partition_labels
1889         /dev/disk/by-uuid:-u,-o,-p,-P_partition_uuid
1890         /var/run/dmesg.boot:-C,-f_(BSD_only)
1891         '
1892         
1893         case $1 in
1894                 required-dirs)
1895                         item_list=$required_dirs
1896                         item_string='Required file system'
1897                         missing_string='system directories'
1898                         type='directories'
1899                         ;;
1900                 required-apps)
1901                         item_list=$required_apps
1902                         item_string='Required application'
1903                         missing_string='applications, and their corresponding packages,'
1904                         type='applications'
1905                         ;;
1906                 recommended-x-apps)
1907                         item_list=$x_recommends
1908                         item_string='Recommended X application'
1909                         missing_string='applications, and their corresponding packages,'
1910                         type='applications'
1911                         ;;
1912                 recommended-apps)
1913                         item_list=$recommended_apps
1914                         item_string='Recommended application'
1915                         missing_string='applications, and their corresponding packages,'
1916                         type='applications'
1917                         ;;
1918                 system-dirs)
1919                         item_list=$recommended_dirs
1920                         item_string='System directory'
1921                         missing_string='system directories'
1922                         type='directories'
1923                         ;;
1924         esac
1925         # great trick from: http://ideatrash.net/2011/01/bash-string-padding-with-sed.html
1926         # left pad: sed -e :a -e 's/^.\{1,80\}$/& /;ta'
1927         # right pad: sed -e :a -e 's/^.\{1,80\}$/ &/;ta'
1928         # center pad: sed -e :a -e 's/^.\{1,80\}$/ & /;ta'
1929         
1930         for item in $item_list
1931         do
1932                 if [[ $( awk -F ":" '{print NF-1}' <<< $item ) -eq 0 ]];then
1933                         application=$item
1934                         package=''
1935                         feature=''
1936                         location=''
1937                 elif [[ $( awk -F ":" '{print NF-1}' <<< $item ) -eq 1 ]];then
1938                         application=$( cut -d ':' -f 1 <<< $item )
1939                         package=''
1940                         feature=$( cut -d ':' -f 2 <<< $item )
1941                         location=''
1942                 else
1943                         application=$( cut -d ':' -f 1 <<< $item )
1944                         package=$( cut -d ':' -f 2 <<< $item )
1945                         location=$( type -p $application )
1946                         if [[ $( awk -F ":" '{print NF-1}' <<< $item ) -eq 2 ]];then
1947                                 feature=$( cut -d ':' -f 3 <<< $item )
1948                         else
1949                                 feature=''
1950                         fi
1951                 fi
1952                 if [[ -n $feature ]];then
1953                         print_string="$item_string: $application (info: $( sed 's/_/ /g' <<< $feature ))"
1954                 else
1955                         print_string="$item_string: $application"
1956                 fi
1957                 
1958                 starter="$( sed -e :a -e 's/^.\{1,75\}$/&./;ta' <<< $print_string )"
1959                 if [[ -z $( grep '^/' <<< $application ) && -n $location ]] || [[ -d $application ]];then
1960                         if [[ -n $location ]];then
1961                                 finisher=" $location"
1962                         else
1963                                 finisher=" Present"
1964                         fi
1965                 else
1966                         finisher=" Missing"
1967                         missing_items="$missing_items$separator$application:$package"
1968                         separator=' '
1969                 fi
1970                 
1971                 echo "$starter$finisher"
1972         done
1973         echo 
1974         if [[ -n $missing_items ]];then
1975                 echo "The following $type are missing from your system:"
1976                 for item in $missing_items
1977                 do
1978                         application=$( cut -d ':' -f 1 <<< $item )
1979                         if [[ $type == 'applications' ]];then
1980                                 # echo '--------------------------------------------------------'
1981                                 echo
1982                                 package=$( cut -d ':' -f 2 <<< $item )
1983                                 package_deb=$( cut -d '~' -f 1 <<< $package )
1984                                 package_pacman=$( cut -d '~' -f 2 <<< $package )
1985                                 package_rpm=$( cut -d '~' -f 3 <<< $package )
1986                                 echo "Application: $application"
1987                                 echo "To add to your system, install the proper distribution package for your system:"
1988                                 echo "Debian/Ubuntu: $package_deb :: Arch Linux: $package_pacman :: Redhat/Fedora/Suse: $package_rpm"
1989                         else
1990                                 echo "Directory: $application"
1991                         fi
1992                 done
1993                 if [[ $item_string == 'System directory' ]];then
1994                         echo "These directories are created by the kernel, so don't worry if they are not present."
1995                 fi
1996         else
1997                 echo "All the $( cut -d ' ' -f 1 <<< $item_string | sed -e 's/Re/re/' -e 's/Sy/sy/' ) $type are present."
1998         fi
1999         echo $Line
2000 }
2001
2002 #### -------------------------------------------------------------------
2003 #### print / output cleaners
2004 #### -------------------------------------------------------------------
2005
2006 # inxi speaks through here. When run by Konversation script alias mode, uses DCOP
2007 # for dcop to work, must use 'say' operator, AND colors must be evaluated by echo -e
2008 # note: dcop does not seem able to handle \n so that's being stripped out and replaced with space.
2009 print_screen_output()
2010 {
2011         eval $LOGFS
2012         # the double quotes are needed to avoid losing whitespace in data when certain output types are used
2013         local print_data="$( echo -e "$1" )"
2014
2015         # just using basic debugger stuff so you can tell which thing is printing out the data. This
2016         # should help debug kde 4 konvi issues when that is released into sid, we'll see. Turning off
2017         # the redundant debugger output which as far as I can tell does exactly nothing to help debugging.
2018         if [[ $DEBUG -gt 5 ]];then
2019                 if [[ $KONVI -eq 1 ]];then
2020                         # konvi doesn't seem to like \n characters, it just prints them literally
2021                         # print_data="$( tr '\n' ' ' <<< "$print_data" )"
2022                         # dcop "$DCPORT" "$DCOPOBJ" say "$DCSERVER" "$DCTARGET" "konvi='$KONVI' saying : '$print_data'"
2023                         print_data="KP-$KONVI: $print_data"
2024                 elif [[ $KONVI -eq 2 ]];then
2025                         # echo "konvi='$KONVI' saying : '$print_data'"
2026                         print_data="KP-$KONVI: $print_data"
2027                 else
2028                         # echo "printing out: '$print_data'"
2029                         print_data="P: $print_data"
2030                 fi
2031         fi
2032
2033         if [[ $KONVI -eq 1 && $B_DCOP == 'true' ]]; then ## dcop Konversation (<= 1.1 (qt3))
2034                 # konvi doesn't seem to like \n characters, it just prints them literally
2035                 $print_data="$( tr '\n' ' ' <<< "$print_data" )"
2036                 dcop "$DCPORT" "$DCOPOBJ" say "$DCSERVER" "$DCTARGET" "$print_data"
2037
2038         elif [[ $KONVI -eq 3 && $B_QDBUS == 'true' ]]; then ## dbus Konversation (> 1.2 (qt4))
2039                 qdbus org.kde.konversation /irc say "$DCSERVER" "$DCTARGET" "$print_data"
2040
2041 #       elif [[ $IRC_CLIENT == 'X-Chat' ]]; then
2042 #               qdbus org.xchat.service print "$print_data\n"
2043
2044         else
2045                 # the -n is needed to avoid double spacing of output in terminal
2046                 echo -ne "$print_data\n"
2047         fi
2048         eval $LOGFE
2049 }
2050
2051 ## this handles all verbose line construction with indentation/line starter
2052 ## args: $1 - null (, actually: " ") or line starter; $2 - line content
2053 create_print_line()
2054 {
2055         eval $LOGFS
2056         printf "${C1}%-${INDENT}s${C2} %s" "$1" "$2"
2057         eval $LOGFE
2058 }
2059
2060 # this removes newline and pipes.
2061 # args: $1 - string to clean
2062 remove_erroneous_chars()
2063 {
2064         eval $LOGFS
2065         ## RS is input record separator
2066         ## gsub is substitute;
2067         gawk '
2068         BEGIN {
2069                 RS=""
2070         }
2071         {
2072                 gsub(/\n$/,"")         ## (newline; end of string) with (nothing)
2073                 gsub(/\n/," ");        ## (newline) with (space)
2074                 gsub(/^ *| *$/, "")    ## (pipe char) with (nothing)
2075                 gsub(/  +/, " ")       ## ( +) with (space)
2076                 gsub(/ [ ]+/, " ")     ## ([ ]+) with (space)
2077                 gsub(/^ +| +$/, "")    ## (pipe char) with (nothing)
2078                 printf $0
2079         }' "$1"      ## prints (returns) cleaned input
2080         eval $LOGFE
2081 }
2082
2083 #### -------------------------------------------------------------------
2084 #### parameter handling, print usage functions.
2085 #### -------------------------------------------------------------------
2086
2087 # Get the parameters. Note: standard options should be lower case, advanced or testing, upper
2088 # args: $1 - full script startup args: $@
2089 get_parameters()
2090 {
2091         eval $LOGFS
2092         local opt='' wget_test='' debug_data_type='' weather_flag='wW:' 
2093         local use_short='true' # this is needed to trigger short output, every v/d/F/line trigger sets this false
2094
2095         # if distro maintainers don't want the weather feature disable it
2096         if [[ $B_ALLOW_WEATHER == 'false' ]];then
2097                 weather_flag=''
2098                 
2099         fi
2100         if [[ $1 == '--version' ]];then
2101                 print_version_info
2102                 exit 0
2103         elif [[ $1 == '--help' ]];then
2104                 show_options
2105                 exit 0
2106         elif [[ $1 == '--recommends' ]];then
2107                 check_recommends_user_output
2108                 exit 0
2109         # the short form only runs if no args output args are used
2110         # no need to run through these if there are no args
2111         # reserved for future use: -g for extra Graphics; -m for extra Machine; -d for extra Disk
2112         elif [[ -n $1 ]];then
2113                 while getopts Abc:CdDfFGhHiIlMnNopPrRsSt:uUv:V${weather_flag}xzZ%@:!: opt
2114                 do
2115                         case $opt in
2116                         A)      B_SHOW_AUDIO='true'
2117                                 use_short='false'
2118                                 ;;
2119                         b)      use_short='false'
2120                                 B_SHOW_BASIC_CPU='true'
2121                                 B_SHOW_BASIC_RAID='true'
2122                                 B_SHOW_DISK_TOTAL='true'
2123                                 B_SHOW_GRAPHICS='true'
2124                                 B_SHOW_INFO='true'
2125                                 B_SHOW_MACHINE='true'
2126                                 B_SHOW_NETWORK='true'
2127                                 B_SHOW_SYSTEM='true'
2128                                 ;;
2129                         c)      if [[ -n $( grep -E '^[0-9][0-9]?$' <<< $OPTARG ) ]];then
2130                                         case $OPTARG in
2131                                                 99)
2132                                                         B_RUN_COLOR_SELECTOR='true'
2133                                                         COLOR_SELECTION='global'
2134                                                         ;;
2135                                                 98)
2136                                                         B_RUN_COLOR_SELECTOR='true'
2137                                                         COLOR_SELECTION='irc-console'
2138                                                         ;;
2139                                                 97)
2140                                                         B_RUN_COLOR_SELECTOR='true'
2141                                                         COLOR_SELECTION='irc-virtual-terminal'
2142                                                         ;;
2143                                                 96)
2144                                                         B_RUN_COLOR_SELECTOR='true'
2145                                                         COLOR_SELECTION='irc'
2146                                                         ;;
2147                                                 95)
2148                                                         B_RUN_COLOR_SELECTOR='true'
2149                                                         COLOR_SELECTION='virtual-terminal'
2150                                                         ;;
2151                                                 94)
2152                                                         B_RUN_COLOR_SELECTOR='true'
2153                                                         COLOR_SELECTION='console'
2154                                                         ;;
2155                                                 *)      
2156                                                         B_COLOR_SCHEME_SET='true'
2157                                                         ## note: not sure about this, you'd think user values should be overridden, but
2158                                                         ## we'll leave this for now
2159                                                         if [[ -z $COLOR_SCHEME ]];then
2160                                                                 set_color_scheme "$OPTARG"
2161                                                         fi
2162                                                         ;;
2163                                         esac
2164                                 else
2165                                         error_handler 3 "$OPTARG"
2166                                 fi
2167                                 ;;
2168                         C)      B_SHOW_CPU='true'
2169                                 use_short='false'
2170                                 ;;
2171                         d)      B_SHOW_DISK='true'
2172                                 B_SHOW_FULL_OPTICAL='true'
2173                                 use_short='false'
2174                                 # error_handler 20 "-d has been replaced by -b"
2175                                 ;;
2176                         D)      B_SHOW_DISK='true'
2177                                 use_short='false'
2178                                 ;;
2179                         f)      B_SHOW_CPU='true'
2180                                 B_CPU_FLAGS_FULL='true'
2181                                 use_short='false'
2182                                 ;;
2183                         F)      # B_EXTRA_DATA='true'
2184                                 B_SHOW_ADVANCED_NETWORK='true'
2185                                 B_SHOW_AUDIO='true'
2186                                 # B_SHOW_BASIC_OPTICAL='true'
2187                                 B_SHOW_CPU='true'
2188                                 B_SHOW_DISK='true'
2189                                 B_SHOW_GRAPHICS='true'
2190                                 B_SHOW_INFO='true'
2191                                 B_SHOW_MACHINE='true'
2192                                 B_SHOW_NETWORK='true'
2193                                 B_SHOW_PARTITIONS='true'
2194                                 B_SHOW_RAID='true'
2195                                 B_SHOW_SENSORS='true'
2196                                 B_SHOW_SYSTEM='true'
2197                                 use_short='false'
2198                                 ;;
2199                         G)      B_SHOW_GRAPHICS='true'
2200                                 use_short='false'
2201                                 ;;
2202                         i)      B_SHOW_IP='true'
2203                                 B_SHOW_NETWORK='true'
2204                                 B_SHOW_ADVANCED_NETWORK='true'
2205                                 use_short='false'
2206                                 ;;
2207                         I)      B_SHOW_INFO='true'
2208                                 use_short='false'
2209                                 ;;
2210                         l)      B_SHOW_LABELS='true'
2211                                 B_SHOW_PARTITIONS='true'
2212                                 use_short='false'
2213                                 ;;
2214                         M)      B_SHOW_MACHINE='true'
2215                                 use_short='false'
2216                                 ;;
2217                         n)      B_SHOW_ADVANCED_NETWORK='true'
2218                                 B_SHOW_NETWORK='true'
2219                                 use_short='false'
2220                                 ;;
2221                         N)      B_SHOW_NETWORK='true'
2222                                 use_short='false'
2223                                 ;;
2224                         o)      B_SHOW_UNMOUNTED_PARTITIONS='true'
2225                                 use_short='false'
2226                                 ;;
2227                         p)      B_SHOW_PARTITIONS_FULL='true'
2228                                 B_SHOW_PARTITIONS='true'
2229                                 use_short='false'
2230                                 ;;
2231                         P)      B_SHOW_PARTITIONS='true'
2232                                 use_short='false'
2233                                 ;;
2234                         r)      B_SHOW_REPOS='true'
2235                                 use_short='false'
2236                                 ;;
2237                         R)      B_SHOW_RAID='true'
2238                                 # it turns out only users with mdraid software installed will have raid,
2239                                 # so unless -R is explicitly called, blank -b/-F/-v6 and less output will not show
2240                                 # error if file is missing.
2241                                 B_SHOW_RAID_R='true'
2242                                 use_short='false'
2243                                 ;;
2244                         s)      B_SHOW_SENSORS='true'
2245                                 use_short='false'
2246                                 ;;
2247                         S)      B_SHOW_SYSTEM='true'
2248                                 use_short='false'
2249                                 ;;
2250                         t)      if [[ -n $( grep -E '^(c|m|cm|mc)([1-9]|1[0-9]|20)?$' <<< $OPTARG ) ]];then
2251                                         use_short='false'
2252                                         if [[ -n $( grep -E '[0-9]+' <<< $OPTARG ) ]];then
2253                                                 PS_COUNT=$( sed 's/[^0-9]//g' <<< $OPTARG )
2254                                         fi
2255                                         if [[ -n $( grep 'c' <<< $OPTARG ) ]];then
2256                                                 B_SHOW_PS_CPU_DATA='true'
2257                                         fi
2258                                         if [[ -n $( grep 'm' <<< $OPTARG ) ]];then
2259                                                 B_SHOW_PS_MEM_DATA='true'
2260                                         fi
2261                                 else
2262                                         error_handler 13 "$OPTARG"
2263                                 fi
2264                                 ;;
2265                         u)      B_SHOW_UUIDS='true'
2266                                 B_SHOW_PARTITIONS='true'
2267                                 use_short='false'
2268                                 ;;
2269                         v)      if [[ -n $( grep -E "^[0-9][0-9]?$" <<< $OPTARG ) && $OPTARG -le $VERBOSITY_LEVELS ]];then
2270                                         if [[ $OPTARG -ge 1 ]];then
2271                                                 use_short='false'
2272                                                 B_SHOW_BASIC_CPU='true'
2273                                                 B_SHOW_DISK_TOTAL='true'
2274                                                 B_SHOW_GRAPHICS='true'
2275                                                 B_SHOW_INFO='true'
2276                                                 B_SHOW_SYSTEM='true'
2277                                         fi
2278                                         if [[ $OPTARG -ge 2 ]];then
2279                                                 B_SHOW_BASIC_DISK='true'
2280                                                 B_SHOW_BASIC_RAID='true'
2281                                                 B_SHOW_MACHINE='true'
2282                                                 B_SHOW_NETWORK='true'
2283                                         fi
2284                                         if [[ $OPTARG -ge 3 ]];then
2285                                                 B_SHOW_ADVANCED_NETWORK='true'
2286                                                 B_SHOW_CPU='true'
2287                                                 B_EXTRA_DATA='true'
2288                                         fi
2289                                         if [[ $OPTARG -ge 4 ]];then
2290                                                 B_SHOW_DISK='true'
2291                                                 B_SHOW_PARTITIONS='true'
2292                                         fi
2293                                         if [[ $OPTARG -ge 5 ]];then
2294                                                 B_SHOW_AUDIO='true'
2295                                                 B_SHOW_BASIC_OPTICAL='true'
2296                                                 B_SHOW_SENSORS='true'
2297                                                 B_SHOW_LABELS='true'
2298                                                 B_SHOW_UUIDS='true'
2299                                                 B_SHOW_RAID='true'
2300                                         fi
2301                                         if [[ $OPTARG -ge 6 ]];then
2302                                                 B_SHOW_FULL_OPTICAL='true'
2303                                                 B_SHOW_PARTITIONS_FULL='true'
2304                                                 B_SHOW_UNMOUNTED_PARTITIONS='true'
2305                                                 B_EXTRA_EXTRA_DATA='true'
2306                                         fi
2307                                         if [[ $OPTARG -ge 7 ]];then
2308                                                 B_EXTRA_EXTRA_EXTRA_DATA='true'
2309                                                 B_SHOW_IP='true'
2310                                                 B_SHOW_RAID_R='true'
2311                                         fi
2312                                 else
2313                                         error_handler 4 "$OPTARG"
2314                                 fi
2315                                 ;;
2316                         U)      if [[ $B_ALLOW_UPDATE == 'true' ]];then
2317                                         script_self_updater "$SCRIPT_DOWNLOAD" 'svn server' "$opt"
2318                                 else
2319                                         error_handler 17 "-$opt"
2320                                 fi
2321                                 ;;
2322                         V)      print_version_info
2323                                 exit 0
2324                                 ;;
2325                         w)      B_SHOW_WEATHER=true
2326                                 use_short='false'
2327                                 ;;
2328                         W)      ALTERNATE_WEATHER_LOCATION=$( sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'  <<< $OPTARG )
2329                                 if [[ -n $( grep -Esi '([^,]+,.+|[0-9-]+)' <<< $ALTERNATE_WEATHER_LOCATION ) ]];then
2330                                         B_SHOW_WEATHER=true
2331                                         use_short='false'
2332                                 else
2333                                         error_handler 18 "-$opt: '$OPTARG'" "city,state OR latitude,longitude OR postal/zip code."
2334                                 fi
2335                                 ;;
2336                         # this will trigger either with x, xx, xxx or with Fx but not with xF
2337                         x)      if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
2338                                         B_EXTRA_EXTRA_EXTRA_DATA='true'
2339                                 elif [[ $B_EXTRA_DATA == 'true' ]];then
2340                                         B_EXTRA_EXTRA_DATA='true'
2341                                 else
2342                                         B_EXTRA_DATA='true'
2343                                 fi
2344                                 ;;
2345                         z)      B_OUTPUT_FILTER='true'
2346                                 ;;
2347                         Z)      B_OVERRIDE_FILTER='true'
2348                                 ;;
2349                         h)      show_options
2350                                 exit 0
2351                                 ;;
2352                         H)      show_options 'full'
2353                                 exit 0
2354                                 ;;
2355                         ## debuggers and testing tools
2356                         %)      B_HANDLE_CORRUPT_DATA='true'
2357                                 ;;
2358                         @)      if [[ -n $( grep -E "^([1-9]|1[0-4])$" <<< $OPTARG ) ]];then
2359                                         DEBUG=$OPTARG
2360                                         if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
2361                                                 B_UPLOAD_DEBUG_DATA='true'
2362                                         fi
2363                                         exec 2>&1
2364                                         # switch on logging only for -@ 8-10
2365                                         case $OPTARG in
2366                                                 8|9|10)
2367                                                         if [[ $OPTARG -eq 10 ]];then
2368                                                                 B_LOG_COLORS='true'
2369                                                         elif [[ $OPTARG -eq 9 ]];then           
2370                                                                 B_LOG_FULL_DATA='true'
2371                                                         fi
2372                                                         B_USE_LOGGING='true'
2373                                                         # pack the logging data for evals function start/end
2374                                                         LOGFS=$LOGFS_STRING
2375                                                         LOGFE=$LOGFE_STRING
2376                                                         create_rotate_logfiles # create/rotate logfiles before we do anything else
2377                                                         ;;
2378                                                 11|12|13|14)
2379                                                         case $OPTARG in
2380                                                                 11)
2381                                                                         debug_data_type='sys'
2382                                                                         ;;
2383                                                                 12)
2384                                                                         debug_data_type='xorg'
2385                                                                         ;;
2386                                                                 13)
2387                                                                         debug_data_type='disk'
2388                                                                         ;;
2389                                                                 14)
2390                                                                         debug_data_type='all'
2391                                                                         ;;
2392                                                         esac
2393                                                         initialize_data
2394                                                         debug_data_collector $debug_data_type
2395                                                         ;;
2396                                         esac
2397                                 else
2398                                         error_handler 9 "$OPTARG"
2399                                 fi
2400                                 ;;
2401                         !)      # test for various supported methods
2402                                 case $OPTARG in
2403                                         1)      B_TESTING_1='true'
2404                                                 ;;
2405                                         2)      B_TESTING_2='true'
2406                                                 ;;
2407                                         3)      B_TESTING_1='true'
2408                                                 B_TESTING_2='true'
2409                                                 ;;
2410                                         1[0-6]|http*)
2411                                                 if [[ $B_ALLOW_UPDATE == 'true' ]];then
2412                                                         case $OPTARG in
2413                                                                 10)
2414                                                                         script_self_updater "$SCRIPT_DOWNLOAD_DEV" 'dev server' "$opt $OPTARG"
2415                                                                         ;;
2416                                                                 11)
2417                                                                         script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_1" 'svn: branch one server' "$opt $OPTARG"
2418                                                                         ;;
2419                                                                 12)
2420                                                                         script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_2" 'svn: branch two server' "$opt $OPTARG"
2421                                                                         ;;
2422                                                                 13)
2423                                                                         script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_3" 'svn: branch three server' "$opt $OPTARG"
2424                                                                         ;;
2425                                                                 14)
2426                                                                         script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_4" 'svn: branch four server' "$opt $OPTARG"
2427                                                                         ;;
2428                                                                 15)
2429                                                                         script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_BSD" 'svn: branch bsd server' "$opt $OPTARG"
2430                                                                         ;;
2431                                                                 16)
2432                                                                         script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_GNUBSD" 'svn: branch gnubsd server' "$opt $OPTARG"
2433                                                                         ;;
2434                                                                 http*)
2435                                                                         script_self_updater "$OPTARG" 'alt server' "$opt <http...>"
2436                                                                         ;;
2437                                                         esac
2438                                                 else
2439                                                         error_handler 17 "-$opt $OPTARG"
2440                                                 fi
2441                                                 ;;
2442                                         30)
2443                                                 B_RUNNING_IN_SHELL='true'
2444                                                 ;;
2445                                         31)
2446                                                 B_SHOW_HOST='false'
2447                                                 ;;
2448                                         32)
2449                                                 B_SHOW_HOST='true'
2450                                                 ;;
2451                                         ftp*)
2452                                                 ALTERNATE_FTP="$OPTARG"
2453                                                 ;;
2454                                         # for weather function, allows user to set an alternate weather location
2455                                         location=*)
2456                                                 error_handler 19 "-$opt location=" "-W"
2457                                                 ;;
2458                                         *)      error_handler 11 "$OPTARG"
2459                                                 ;;
2460                                 esac
2461                                 ;;
2462                         *)      error_handler 7 "$1"
2463                                 ;;
2464                         esac
2465                 done
2466         fi
2467         ## this must occur here so you can use the debugging flag to show errors
2468         ## Reroute all error messages to the bitbucket (if not debugging)
2469         if [[ $DEBUG -eq 0 ]];then
2470                 exec 2>/dev/null
2471         fi
2472         #((DEBUG)) && exec 2>&1 # This is for debugging konversation
2473
2474         # after all the args have been processed, if no long output args used, run short output
2475         if [[ $use_short == 'true' ]];then
2476                 B_SHOW_SHORT_OUTPUT='true'
2477         fi
2478         # just in case someone insists on using -zZ
2479         if [[ $B_OVERRIDE_FILTER == 'true' ]];then
2480                 B_OUTPUT_FILTER='false'
2481         fi
2482         # change basic to full if user requested it or if arg overrides it
2483         if [[ $B_SHOW_RAID == 'true' && $B_SHOW_BASIC_RAID == 'true' ]];then
2484                 B_SHOW_BASIC_RAID='false'
2485         fi
2486         
2487         
2488         eval $LOGFE
2489 }
2490
2491 ## print out help menu, not including Testing or Debugger stuff because it's not needed
2492 show_options()
2493 {
2494         local color_scheme_count=$(( ${#A_COLOR_SCHEMES[@]} - 1 ))
2495         local partition_string='partition' partition_string_u='Partition'
2496         
2497         if [[ $B_RUNNING_IN_SHELL != 'true' ]];then
2498                 print_screen_output "Sorry, you can't run the help option in an IRC client."
2499                 exit 1
2500         fi
2501         if [[ -n $BSD_TYPE ]];then
2502                 partition_string='slice'
2503                 partition_string_u='Slice'
2504         fi
2505         # print_lines_basic "0" "" ""
2506         # print_lines_basic "1" "" ""
2507         # print_lines_basic "2" "" ""
2508         # print_screen_output " "
2509         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."
2510         print_screen_output " "
2511         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."
2512         
2513         print_screen_output "- - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
2514         print_screen_output "Output Control Options:"
2515         print_lines_basic "1" "-A" "Audio/sound card information."
2516         print_lines_basic "1" "-b" "Basic output, short form. Like $SCRIPT_NAME^-v^2, only minus hard disk names."
2517         print_lines_basic "1" "-c" "Color schemes. Scheme number is required. Color selectors run a color selector option prior to $SCRIPT_NAME starting which lets you set the config file value for the selection."
2518         print_lines_basic "1" "" "Supported color schemes: 0-$color_scheme_count Example: $SCRIPT_NAME^-c^11"
2519         print_lines_basic "1" "" "Color selectors for each type display (NOTE: irc and global only show safe color set):"
2520 #       print_screen_output "    Supported color schemes: 0-$color_scheme_count Example: $SCRIPT_NAME -c 11"
2521 #       print_screen_output "    Color selectors for each type display (NOTE: irc and global only show safe color set):"
2522         print_lines_basic "2" "94" "Console, out of X"
2523         print_lines_basic "2" "95" "Terminal, running in X - like xTerm"
2524         print_lines_basic "2" "96" "Gui IRC, running in X - like Xchat, Quassel, Konversation etc."
2525         print_lines_basic "2" "97" "Console IRC running in X - like irssi in xTerm"
2526         print_lines_basic "2" "98" "Console IRC not in  X"
2527         print_lines_basic "2" "99" "Global - Overrides/removes all settings. Setting specific removes global."
2528         print_lines_basic "1" "-C" "CPU output, including per CPU clockspeed (if available)."
2529         print_lines_basic "1" "-d" "Optical drive data. Same as -Dd. See also -x and -xx."
2530         print_lines_basic "1" "-D" "Full hard Disk info, not only model, ie: /dev/sda ST380817AS 80.0GB. See also -x and -xx."
2531         print_lines_basic "1" "-f" "All cpu flags, triggers -C. Not shown with -F to avoid spamming. ARM cpus show 'features'."
2532         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"
2533         print_lines_basic "1" "-G" "Graphic card information (card, display server type/version, resolution, glx renderer, version)."
2534         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."
2535         print_lines_basic "1" "-I" "Information: processes, uptime, memory, irc client (or shell type), $SCRIPT_NAME version."
2536         print_lines_basic "1" "-l" "${partition_string_u} labels. Default: short ${partition_string} -P. For full -p output, use: -pl (or -plu)."
2537         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."
2538         print_lines_basic "1" "-n" "Advanced Network card information. Same as -Nn. Shows interface, speed, mac id, state, etc."
2539         print_lines_basic "1" "-N" "Network card information. With -x, shows PCI BusID, Port number."
2540         print_lines_basic "1" "-o" "Unmounted ${partition_string} information (includes UUID and LABEL if available). Shows file system type if you have file installed, if you are root OR if you have added to /etc/sudoers (sudo v. 1.7 or newer) Example:^<username>^ALL^=^NOPASSWD:^/usr/bin/file^"
2541         print_lines_basic "1" "-p" "Full ${partition_string} information (-P plus all other detected ${partition_string}s)."
2542         print_lines_basic "1" "-P" "Basic ${partition_string} information (shows what -v 4 would show, but without extra data). Shows, if detected: / /boot /home /tmp /usr /var. Use -p to see all mounted ${partition_string}s."
2543         print_lines_basic "1" "-r" "Distro repository data. Supported repo types: APT; PACMAN; PISI; YUM; URPMQ; Ports."
2544         print_lines_basic "1" "-R" "RAID data. Shows RAID devices, states, levels, and components, and extra data with -x/-xx. md-raid: If device is resyncing, shows resync progress line as well."
2545         print_lines_basic "1" "-s" "Sensors output (if sensors installed/configured): mobo/cpu/gpu temp; detected fan speeds. Gpu temp only for Fglrx/Nvidia drivers. Nvidia shows screen number for > 1 screens."
2546         print_lines_basic "1" "-S" "System information: host name, kernel, desktop environment (if in X), distro"
2547         print_lines_basic "1" "-t" "Processes. Requires extra options: c (cpu) m (memory) cm (cpu+memory). If followed by numbers 1-20, shows that number of processes for each type (default:^$PS_COUNT; if in irc, max:^5): -t^cm10"
2548         print_lines_basic "1" "" "Make sure to have no space between letters and numbers (-t^cm10 - right, -t^cm^10 - wrong)."
2549         print_lines_basic "1" "-u" "${partition_string_u} UUIDs. Default: short ${partition_string} -P. For full -p output, use: -pu (or -plu)."
2550         print_lines_basic "1" "-v" "Script verbosity levels. Verbosity level number is required. Should not be used with -b or -F"
2551         print_lines_basic "1" "" "Supported levels: 0-${VERBOSITY_LEVELS} Example: $SCRIPT_NAME^-v^4"
2552         print_lines_basic "2" "0" "Short output, same as: $SCRIPT_NAME"
2553         print_lines_basic "2" "1" "Basic verbose, -S + basic CPU + -G + basic Disk + -I."
2554         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"
2555         print_lines_basic "2" "3" "Advanced CPU (-C), network (-n) data, and switches on -x advanced data option."
2556         print_lines_basic "2" "4" "${partition_string_u} size/filled data (-P) for (if present):/, /home, /var/, /boot. Shows full disk data (-D)."
2557         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)."
2558         print_lines_basic "2" "6" "Full ${partition_string} (-p), unmounted ${partition_string} (-o), optical drive (-d), full raid; triggers -xx."
2559         print_lines_basic "2" "7" "Network IP data (-i); triggers -xxx."
2560         
2561         # if distro maintainers don't want the weather feature disable it
2562         if [[ $B_ALLOW_WEATHER == 'true' ]];then
2563                 print_lines_basic "1" "-w" "Local weather data/time. To check an alternate location, see: -W^<location>. For extra weather data options see -x, -xx, and -xxx."
2564                 print_lines_basic "1" "-W" "<location> Supported options for <location>: postal code; city, state/country; latitude/longitude. Only use if you want the weather somewhere other than the machine running $SCRIPT_NAME. Use only ascii characters, replace spaces in city/state/country names with '+'. Example:^$SCRIPT_NAME^-W^new+york,ny"
2565         fi
2566         print_lines_basic "1" "-x" "Adds the following extra data (only works with verbose or line output, not short form):"
2567         print_lines_basic "2" "-C" "CPU Flags, Bogomips on Cpu;"
2568         print_lines_basic "2" "-d" "Extra optical drive data; adds rev version to optical drive."
2569         print_lines_basic "2" "-D" "Hdd temp with disk data if you have hddtemp installed, if you are root OR if you have added to /etc/sudoers (sudo v. 1.7 or newer) Example:^<username>^ALL^=^NOPASSWD:^/usr/sbin/hddtemp"
2570         print_lines_basic "2" "-G" "Direct rendering status for Graphics (in X)."
2571         print_lines_basic "2" "-G" "(for single gpu, nvidia driver) screen number gpu is running on."
2572         print_lines_basic "2" "-i" "IPv6 as well for LAN interface (IF) devices."
2573         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)."
2574         print_lines_basic "2" "-N -A" "Version/port(s)/driver version (if available) for Network/Audio;"
2575         print_lines_basic "2" "-N -A -G" "Network, audio, graphics, shows PCI Bus ID/Usb ID number of card."
2576         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"
2577         print_lines_basic "2" "-S" "Desktop toolkit if avaliable (GNOME/XFCE/KDE only); Kernel gcc version"
2578         print_lines_basic "2" "-t" "Memory use output to cpu (-xt c), and cpu use to memory (-xt m)."
2579         if [[ $B_ALLOW_WEATHER == 'true' ]];then
2580                 print_lines_basic "2" "-w -W" "Wind speed and time zone (-w only)."
2581         fi
2582         print_lines_basic "1" "-xx" "Show extra, extra data (only works with verbose or line output, not short form):"
2583         print_lines_basic "2" "-A" "Chip vendor:product ID for each audio device."
2584         print_lines_basic "2" "-D" "Disk serial number."
2585         print_lines_basic "2" "-G" "Chip vendor:product ID for each video card."
2586         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."
2587         print_lines_basic "2" "-M" "Chassis information, bios rom size (dmidecode only), if data for either is available."
2588         print_lines_basic "2" "-N" "Chip vendor:product ID for each nic."
2589         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."
2590         print_lines_basic "2" "-S" "Display manager (dm) in desktop output, if in X (like kdm, gdm3, lightdm)."
2591         if [[ $B_ALLOW_WEATHER == 'true' ]];then
2592                 print_lines_basic "2" "-w -W" "Humidity, barometric pressure."
2593         fi
2594         print_lines_basic "2" "-@ 11-14" "Automatically uploads debugger data tar.gz file to ftp.techpatterns.com. EG: $SCRIPT_NAME^-xx@14"
2595         print_lines_basic "1" "-xxx" "Show extra, extra, extra data (only works with verbose or line output, not short form):"
2596         print_lines_basic "2" "-S" "Panel/shell information in desktop output, if in X (like gnome-shell, cinnamon, mate-panel)."
2597         if [[ $B_ALLOW_WEATHER == 'true' ]];then
2598                 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)."
2599         fi
2600         print_lines_basic "1" "-z" "Security filters for IP/Mac addresses, location, user home directory name. Default on for irc clients."
2601         print_lines_basic "1" "-Z" "Absolute override for output filters. Useful for debugging networking issues in irc for example."
2602         print_screen_output " "
2603         print_screen_output "Additional Options:"
2604         print_lines_basic "4" "-h --help" "This help menu."
2605         print_lines_basic "4" "-H" "This help menu, plus developer options. Do not use dev options in normal operation!"
2606         print_lines_basic "4" "--recommends" "Checks $SCRIPT_NAME application dependencies + recommends, and directories, then shows what package(s) you need to install to add support for that feature. "
2607         if [[ $B_ALLOW_UPDATE == 'true' ]];then
2608                 print_lines_basic "4" "-U" "Auto-update script. Will also install/update man page. Note: if you installed as root, you must be root to update, otherwise user is fine. Man page installs require root user mode."
2609         fi
2610         print_lines_basic "4" "-V --version" "$SCRIPT_NAME version information. Prints information then exits."
2611         print_screen_output " "
2612         print_screen_output "Debugging Options:"
2613         print_lines_basic "1" "-%" "Overrides defective or corrupted data."
2614         print_lines_basic "1" "-@" "Triggers debugger output. Requires debugging level 1-14 (8-10 - logging of data). Less than 8 just triggers $SCRIPT_NAME debugger output on screen."
2615         print_lines_basic "2" "1-7" "On screen debugger output"
2616         print_lines_basic "2" "8" "Basic logging"
2617         print_lines_basic "2" "9" "Full file/sys info logging"
2618         print_lines_basic "2" "10" "Color logging."
2619         print_lines_basic "1" "" "The following create a tar.gz file of system data, plus collecting the inxi output to file. To automatically upload debugger data tar.gz file to ftp.techpatterns.com: inxi^-xx@^<11-14>"
2620         print_lines_basic "1" "" "For alternate ftp upload locations: Example: inxi^-!^ftp.yourserver.com/incoming^-xx@^14"
2621         print_lines_basic "2" "11" "With data file of xiin read of /sys."
2622         print_lines_basic "2" "12" "With xorg conf and log data, xrandr, xprop, xdpyinfo, glxinfo etc."
2623         print_lines_basic "2" "13" "With data from dev, disks, ${partition_string}s, etc., plus xiin data file."
2624         print_lines_basic "2" "14" "Everything, full data collection."
2625         print_screen_output " "
2626         print_screen_output "Advanced Options:"
2627         print_lines_basic "1" "-! 31" "Turns off hostname in output. Useful if showing output from servers etc."
2628         print_lines_basic "1" "-! 32" "Turns on hostname in output. Overrides global B_SHOW_HOST='false'"
2629         
2630         if [[ $1 == 'full' ]];then
2631                 print_screen_output " "
2632                 print_screen_output "Developer and Testing Options (Advanced):"
2633                 print_lines_basic "1" "-! 1" "Sets testing flag B_TESTING_1='true' to trigger testing condition 1."
2634                 print_lines_basic "1" "-! 2" "Sets testing flag B_TESTING_2='true' to trigger testing condition 2."
2635                 print_lines_basic "1" "-! 3" "Sets flags B_TESTING_1='true' and B_TESTING_2='true'."
2636                 if [[ $B_ALLOW_UPDATE == 'true' ]];then
2637                         print_lines_basic "1" "-! 10" "Triggers an update from the primary dev download server instead of svn."
2638                         print_lines_basic "1" "-! 11" "Triggers an update from svn branch one - if present, of course."
2639                         print_lines_basic "1" "-! 12" "Triggers an update from svn branch two - if present, of course."
2640                         print_lines_basic "1" "-! 13" "Triggers an update from svn branch three - if present, of course."
2641                         print_lines_basic "1" "-! 14" "Triggers an update from svn branch four - if present, of course."
2642                         print_lines_basic "1" "-! 15" "Triggers an update from svn branch BSD - if present, of course."
2643                         print_lines_basic "1" "-! 16" "Triggers an update from svn branch GNUBSD - if present, of course."
2644                         print_lines_basic "1" "-! <http://......>" "Triggers an update from whatever server you list."
2645                 fi
2646                 print_lines_basic "1" "-! <ftp.......>" "Changes debugging data ftp upload location to whatever you enter here. Only used together with -xx@^11-14, and must be used in front of that. "
2647                 print_lines_basic "1" "" "Example: inxi^-!^ftp.yourserver.com/incoming^-xx@^14"
2648         fi
2649         print_screen_output " "
2650 }
2651
2652 # uses $TERM_COLUMNS to set width using $COLS_MAX as max width
2653 # IMPORTANT: minimize use of subshells here or the output is too slow
2654 # args: $1 - 0 1 2 3 4 for indentation level; $2 -line starter, like -m; $3 - content of block.
2655 print_lines_basic()
2656 {
2657         local line_width=$COLS_MAX
2658         local print_string='' indent_inner='' indent_full='' indent_x='' 
2659         local indent_working='' indent_working_full=''
2660         local line_starter='' line_1_starter='' line_x_starter='' 
2661         # note: to create a padded string below
2662         local fake_string=' ' temp_count='' line_count='' spacer=''
2663         local indent_main=6 indent_x='' b_indent_x='true' 
2664         
2665         case $1 in
2666                 # for no options, start at left edge
2667                 0)      indent_full=0
2668                         line_1_starter=''
2669                         line_x_starter=''
2670                         b_indent_x='false'
2671                         ;;
2672                 1)      indent_full=$indent_main
2673                         temp_count=${#2}
2674                         if [[ $temp_count -le $indent_full ]];then
2675                                 indent_working=$indent_full
2676                         else
2677                                 indent_working=$temp_count #$(( $temp_count + 1 ))
2678                         fi
2679                         line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_working\}$/& /;ta" <<< $2 )"
2680                         ;;
2681                 # first left pad 2 and 3, then right pad them
2682                 2)      indent_full=$(( $indent_main + 6 ))
2683                         indent_inner=3
2684                         temp_count=${#2}
2685                         if [[ $temp_count -le $indent_inner ]];then
2686                                 indent_working=$indent_inner
2687                                 #indent_working_full=$indent_full
2688                         else
2689                                 indent_working=$(( $temp_count + 1 ))
2690                                 #indent_working_full=$(( $indent_full - $indent_inner - 1 ))
2691                         fi
2692                         line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_working\}$/& /;ta" <<< $2 )"
2693                         line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_full\}$/ &/;ta" <<< "$line_1_starter" )"
2694                         ;;
2695                 3)      indent_full=$(( $indent_main + 8 ))
2696                         indent_inner=3
2697                         temp_count=${#2}
2698                         if [[ $temp_count -le $indent_inner ]];then
2699                                 indent_working=$indent_inner
2700                         else
2701                                 indent_working=$(( $temp_count + 1 ))
2702                         fi
2703                         line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_working\}$/& /;ta" <<< $2 )"
2704                         line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_full\}$/ &/;ta" <<< "$line_1_starter" )"
2705                         ;;
2706                 # for long options
2707                 4)      indent_full=$(( $indent_main + 8 ))
2708                         temp_count=${#2}
2709                         if [[ $temp_count -lt $indent_full ]];then
2710                                 indent_working=$indent_full
2711                         else
2712                                 indent_working=$temp_count #$(( $temp_count + 1 ))
2713                         fi
2714                         line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_working\}$/& /;ta" <<< $2 )"
2715                         ;;
2716         esac
2717         
2718         if [[ $b_indent_x == 'true' ]];then
2719                 indent_x=$(( $indent_full + 1 ))
2720                 line_x_starter="$(printf "%${indent_x}s" '')"
2721         fi
2722         
2723         line_count=$(( $line_width - $indent_full ))
2724         
2725         # bash loop is slow, only run this if required
2726         if [[ ${#3} -gt $line_count ]];then
2727                 for word in $3
2728                 do
2729                         temp_string="$print_string$spacer$word"
2730                         spacer=' '
2731                         if [[ ${#temp_string} -lt $line_count ]];then
2732                                 print_string=$temp_string # lose any white space start/end
2733                                 # echo -n $(( $line_width - $indent_full ))
2734                         else
2735                                 if [[ -n $line_1_starter ]];then
2736                                         line_starter="$line_1_starter"
2737                                         line_1_starter=''
2738                                 else
2739                                         line_starter="$line_x_starter"
2740                                 fi
2741                                 # clean up forced connections, ie, stuff we don't want wrapping
2742                                 print_string=${print_string//\^/ }
2743                                 print_screen_output "$line_starter$print_string"
2744                                 print_string="$word$spacer" # needed to handle second word on new line
2745                                 temp_string=''
2746                                 spacer=''
2747                         fi
2748                 done
2749         else
2750                 # echo no loop
2751                 print_string=$3
2752         fi
2753         # print anything left over
2754         if [[ -n $print_string ]];then
2755                 if [[ -n $line_1_starter ]];then
2756                         line_starter="$line_1_starter"
2757                         line_1_starter=''
2758                 else
2759                         line_starter="$line_x_starter"
2760                 fi
2761                 print_string=${print_string//\^/ }
2762                 print_screen_output "$line_starter$print_string"
2763         fi
2764 }
2765 # print_lines_basic '1' '-m' 'let us teest this string and lots more and stuff and more stuff and x is wy and z is x and fred is dead and gus is alive an yes we have to go now'
2766 # print_lines_basic '2' '7' 'and its substring this string and lots more and stuff and more stuff and x is wy and z is x and fred is dead and gus is alive an yes we have to go now'
2767 # print_lines_basic '2' '12' 'and its sss substring'
2768 # print_lines_basic '3' '12' 'and its sss substring this string and lots more and stuff and more stuff and x is wy and z is x and fred is dead and gus is alive an yes we have to go now'
2769 # exit
2770
2771 ## print out version information for -V/--version
2772 print_version_info()
2773 {
2774         # if not in PATH could be either . or directory name, no slash starting
2775         local script_path=$SCRIPT_PATH script_symbolic_start=''
2776         if [[ $script_path == '.' ]];then
2777                 script_path=$( pwd )
2778         elif [[ -z $( grep '^/' <<< "$script_path" ) ]];then
2779                 script_path="$( pwd )/$script_path"
2780         fi
2781         # handle if it's a symbolic link, rare, but can happen with script directories in irc clients
2782         # which would only matter if user starts inxi with -! 30 override in irc client
2783         if [[ -L $script_path/$SCRIPT_NAME ]];then
2784                 script_symbolic_start=$script_path/$SCRIPT_NAME
2785                 script_path=$( readlink $script_path/$SCRIPT_NAME )
2786                 script_path=$( dirname $script_path )
2787         fi
2788         local last_modified=$( parse_version_data 'date' ) 
2789         local year_modified=$( gawk '{print $NF}' <<< "$last_modified" )
2790         
2791         print_screen_output "$SCRIPT_NAME $SCRIPT_VERSION_NUMBER-$SCRIPT_PATCH_NUMBER ($last_modified)"
2792         if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
2793                 print_screen_output "Program Location: $script_path"
2794                 if [[ -n $script_symbolic_start ]];then
2795                         print_screen_output "Started via symbolic link: $script_symbolic_start"
2796                 fi
2797                 print_lines_basic "0" "" "Website:^http://inxi.goooglecode.com"
2798                 print_lines_basic "0" "" "IRC:^irc.oftc.net channel:^#smxi"
2799                 print_lines_basic "0" "" "Forums:^http://techpatterns.com/forums/forum-33.html"
2800                 print_screen_output " "
2801                 print_lines_basic "0" "" "$SCRIPT_NAME - the universal, portable, system information tool for console and irc."
2802                 print_screen_output " "
2803                 print_lines_basic "0" "" "This program started life as a fork of Infobash 3.02: Copyright (C) 2005-2007  Michiel de Boer a.k.a. locsmif."
2804                 print_lines_basic "0" "" "Subsequent changes and modifications (after Infobash 3.02): Copyright (C) 2008-$year_modified Scott Rogers, Harald Hope, aka trash80 & h2"
2805                 print_screen_output " "
2806                 print_lines_basic "0" "" "This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. (http://www.gnu.org/licenses/gpl.html)"
2807         fi
2808 }
2809
2810 ########################################################################
2811 #### MAIN FUNCTIONS
2812 ########################################################################
2813
2814 #### -------------------------------------------------------------------
2815 #### initial startup stuff
2816 #### -------------------------------------------------------------------
2817
2818 # Determine where inxi was run from, set IRC_CLIENT and IRC_CLIENT_VERSION
2819 get_start_client()
2820 {
2821         eval $LOGFS
2822         local Irc_Client_Path='' irc_client_path_lower='' non_native_konvi='' i=''
2823         local B_Non_Native_App='false' pppid='' App_Working_Name=''
2824         local b_qt4_konvi='false' ps_parent=''
2825
2826         if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
2827                 IRC_CLIENT='Shell'
2828                 unset IRC_CLIENT_VERSION
2829         # elif [[ -n $PPID ]];then
2830         elif [[ -n $PPID && -f /proc/$PPID/exe ]];then
2831                 if [[ $B_OVERRIDE_FILTER != 'true' ]];then
2832                         B_OUTPUT_FILTER='true'
2833                 fi
2834                 Irc_Client_Path=$( readlink /proc/$PPID/exe )
2835                 # Irc_Client_Path=$( ps -p $PPID | gawk '!/[[:space:]]*PID/ {print $5}'  )
2836                 # echo $( ps -p $PPID )
2837                 irc_client_path_lower=$( tr '[:upper:]' '[:lower:]' <<< $Irc_Client_Path )
2838                 App_Working_Name=$( basename $irc_client_path_lower )
2839                 # handles the xchat/sh/bash/dash cases, and the konversation/perl cases, where clients
2840                 # report themselves as perl or unknown shell. IE:  when konversation starts inxi
2841                 # from inside itself, as a script, the parent is konversation/xchat, not perl/bash etc
2842                 # note: perl can report as: perl5.10.0, so it needs wildcard handling
2843                 case $App_Working_Name in
2844                         # bsd will never use this section
2845                         bash|dash|sh|python*|perl*)     # We want to know who wrapped it into the shell or perl.
2846                                 pppid="$( ps -p $PPID -o ppid --no-headers | sed 's/[[:space:]]//g' )"
2847                                 if [[ -n $pppid && -f /proc/$pppid/exe ]];then
2848                                         Irc_Client_Path="$( readlink /proc/$pppid/exe )"
2849                                         irc_client_path_lower="$( tr '[:upper:]' '[:lower:]' <<< $Irc_Client_Path )"
2850                                         App_Working_Name=$( basename $irc_client_path_lower )
2851                                         B_Non_Native_App='true'
2852                                 fi
2853                                 ;;
2854                 esac
2855                 # sets version number if it can find it
2856                 get_irc_client_version
2857         else
2858                 ## lets look to see if qt4_konvi is the parent.  There is no direct way to tell, so lets infer it.
2859                 ## because $PPID does not work with qt4_konvi, the above case does not work
2860                 if [[ $B_OVERRIDE_FILTER != 'true' ]];then
2861                         B_OUTPUT_FILTER='true'
2862                 fi
2863                 b_qt4_konvi=$( is_this_qt4_konvi )
2864                 if [[ $b_qt4_konvi == 'true' ]];then
2865                         KONVI=3
2866                         IRC_CLIENT='Konversation'
2867                         IRC_CLIENT_VERSION=" $( konversation -v | gawk '
2868                                 /Konversation:/ {
2869                                         for ( i=2; i<=NF; i++ ) {
2870                                                 if (i == NF) {
2871                                                         print $i
2872                                                 }
2873                                                 else {
2874                                                         printf $i" "
2875                                                 }
2876                                         }
2877                                         exit
2878                                 }' )"
2879                 else
2880                         # this should handle certain cases where it's ssh or some other startup tool
2881                         # that falls through all the other tests
2882                         if [[ $BSD_TYPE != 'bsd' ]];then
2883                                 App_Working_Name=$(ps -p $PPID --no-headers 2>/dev/null | gawk '{print $NF}' )
2884                         else
2885                                 # without --no-headers we need the second line
2886                                 App_Working_Name=$(ps -p&