0c55bb8e20d25aba2be92d53808ab2718efb2f7f
[quassel.git] / data / scripts / inxi
1 #!/usr/bin/env bash
2 ########################################################################
3 ####  Script Name: inxi
4 ####  Version: 2.1.2
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 ## sometimes will trigger an error (mageia) if not in shell
498 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
499         if [[ -n $( type -p tput ) ]];then
500                 TERM_COLUMNS=$(tput cols)
501                 TERM_LINES=$(tput lines)
502         fi
503         # double check, just in case it's missing functionality or whatever
504         if [[ -n ${TERM_COLUMNS##[0-9]*} ]];then
505                 TERM_COLUMNS=80
506                 TERM_LINES=100
507         fi
508 fi
509
510 # Only for legacy user config files se we can test and convert the var name
511 LINE_MAX_CONSOLE=''
512 LINE_MAX_IRC=''
513
514 ### COLORS ###
515 # Defaults to 2, make this 1 for normal, 0 for no colorcodes at all. Use following variables in config 
516 # files to change defaults for each type, or global
517 # Same as runtime parameter.
518 DEFAULT_COLOR_SCHEME=2
519 ## color variables - set dynamically
520 COLOR_SCHEME=''
521 C1=''
522 C2=''
523 CN=''
524 ## Always leave these blank, these are only going to be set in inxi.conf files, that makes testing
525 ## for user changes easier after sourcing the files
526 GLOBAL_COLOR_SCHEME=''
527 IRC_COLOR_SCHEME=''
528 IRC_CONS_COLOR_SCHEME=''
529 IRC_X_TERM_COLOR_SCHEME=''
530 CONSOLE_COLOR_SCHEME=''
531 VIRT_TERM_COLOR_SCHEME=''
532
533 ## Output colors
534 # A more elegant way to have a scheme that doesn't print color codes (neither ANSI nor mIRC) at all. See below.
535 unset EMPTY
536 #             DGREY   BLACK   RED     DRED    GREEN   DGREEN  YELLOW  DYELLOW
537 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"
538 IRC_COLORS="  \x0314  \x0301  \x0304  \x0305  \x0309  \x0303  \x0308  \x0307"
539 #                          BLUE    DBLUE   MAGENTA DMAGENTA CYAN   DCYAN   WHITE   GREY    NORMAL
540 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"
541 IRC_COLORS=" $IRC_COLORS    \x0312 \x0302  \x0313  \x0306  \x0311  \x0310  \x0300  \x0315  \x03"
542
543 #ANSI_COLORS=($ANSI_COLORS); IRC_COLORS=($IRC_COLORS)
544 A_COLORS_AVAILABLE=( DGREY BLACK RED DRED GREEN DGREEN YELLOW DYELLOW BLUE DBLUE MAGENTA DMAGENTA CYAN DCYAN WHITE GREY NORMAL )
545
546 # See above for notes on EMPTY
547 ## note: group 1: 0, 1 are null/normal
548 ## Following: group 2: generic, light/dark or dark/light; group 3: dark on light; group 4 light on dark; 
549 # this is the count of the first two groups, starting at zero
550 SAFE_COLOR_COUNT=12
551 A_COLOR_SCHEMES=( 
552 EMPTY,EMPTY,EMPTY 
553 NORMAL,NORMAL,NORMAL 
554
555 BLUE,NORMAL,NORMAL
556 BLUE,RED,NORMAL 
557 CYAN,BLUE,NORMAL 
558 DCYAN,NORMAL,NORMAL
559 DCYAN,BLUE,NORMAL 
560 DGREEN,NORMAL,NORMAL 
561 DYELLOW,NORMAL,NORMAL 
562 GREEN,DGREEN,NORMAL 
563 GREEN,NORMAL,NORMAL 
564 MAGENTA,NORMAL,NORMAL
565 RED,NORMAL,NORMAL
566
567 BLACK,DGREY,NORMAL
568 DBLUE,DGREY,NORMAL 
569 DBLUE,DMAGENTA,NORMAL
570 DBLUE,DRED,NORMAL 
571 DBLUE,BLACK,NORMAL
572 DGREEN,DYELLOW,NORMAL 
573 DYELLOW,BLACK,NORMAL
574 DMAGENTA,BLACK,NORMAL
575 DCYAN,DBLUE,NORMAL
576
577 WHITE,GREY,NORMAL
578 GREY,WHITE,NORMAL
579 CYAN,GREY,NORMAL 
580 GREEN,WHITE,NORMAL 
581 GREEN,YELLOW,NORMAL 
582 YELLOW,WHITE,NORMAL 
583 MAGENTA,CYAN,NORMAL 
584 MAGENTA,YELLOW,NORMAL
585 RED,CYAN,NORMAL
586 RED,WHITE,NORMAL 
587 BLUE,WHITE,NORMAL
588 )
589
590 # WARNING: In the main part below (search for 'KONVI')
591 # there's a check for Konversation-specific config files.
592 # Any one of these can override the above if inxi is run
593 # from Konversation!
594
595 ## DISTRO DATA/ID ##
596 # In cases of derived distros where the version file of the base distro can also be found under /etc,
597 # the derived distro's version file should go first. (Such as with Sabayon / Gentoo)
598 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"
599 # debian_version excluded from DISTROS_PRIMARY so Debian can fall through to /etc/issue detection. Same goes for Ubuntu.
600 DISTROS_EXCLUDE_LIST="debian_version ubuntu_version"
601 DISTROS_PRIMARY="arch-release gentoo-release redhat-release slackware-version SuSE-release"
602 DISTROS_LSB_GOOD="mandrake-release mandriva-release mandrakelinux-release"
603 # this is being used both by core distros and derived distros now, eg, solusos 1 uses it for solusos id, while
604 # debian, solusos base, uses it as well, so we have to know which it is.
605 DISTROS_OS_RELEASE_GOOD="arch-release SuSE-release"
606 ## Distros with known problems
607 # DSL (Bash 2.05b: grep -m doesn't work; arrays won't work) --> unusable output
608 # Puppy Linux 4.1.2 (Bash 3.0: arrays won't work) --> works partially
609
610 ## OUTPUT FILTERS/SEARCH ##
611 # Note that \<ltd\> bans only words, not parts of strings; in \<corp\> you can't use punctuation characters like . or ,
612 # we're saving about 10+% of the total script exec time by hand building the ban lists here, using hard quotes.
613 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 ..\)'
614 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]'
615
616 SENSORS_GPU_SEARCH='intel|radeon|nouveau'
617
618 ### USB networking search string data, because some brands can have other products than
619 ### wifi/nic cards, they need further identifiers, with wildcards.
620 ### putting the most common and likely first, then the less common, then some specifics
621 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"
622 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" 
623 # then a few known hard to ID ones added 
624 # belkin=050d; d-link=07d1; netgear=0846; ralink=148f; realtek=0bda; 
625 USB_NETWORK_SEARCH="$USB_NETWORK_SEARCH|050d:935b|0bda:8189|0bda:8197"
626
627 ########################################################################
628 #### MAIN: Where it all begins
629 ########################################################################
630 main()
631 {
632         eval $LOGFS
633         
634         local color_scheme=''
635         # this will be used by all functions following
636         local Ps_aux_Data="$( ps aux )"
637
638         # This function just initializes variables
639         initialize_data
640         
641         # Source global config overrides, needs to be here because some things
642         # can be reset that were set in initialize, but check_required_apps needs
643         if [[ -s /etc/$SCRIPT_NAME.conf ]];then
644                 source /etc/$SCRIPT_NAME.conf
645         fi
646         # Source user config variables override /etc/inxi.conf variables
647         if [[ -s $HOME/.$SCRIPT_NAME/$SCRIPT_NAME.conf ]];then
648                 source $HOME/.$SCRIPT_NAME/$SCRIPT_NAME.conf
649         fi
650         # Convert to new variable names if set in config files, legacy test
651         if [[ -n $LINE_MAX_CONSOLE ]];then
652                 COLS_MAX_CONSOLE=$LINE_MAX_CONSOLE
653         fi
654         if [[ -n $LINE_MAX_IRC ]];then
655                 COLS_MAX_IRC=$LINE_MAX_IRC
656         fi
657         # TERM_COLUMNS is set in top globals, using tput cols
658         if [[ $TERM_COLUMNS -lt $COLS_MAX_CONSOLE ]];then
659                 COLS_MAX_CONSOLE=$TERM_COLUMNS
660         fi
661         # adjust, some terminals will wrap if output cols == term cols
662         COLS_MAX_CONSOLE=$(( $COLS_MAX_CONSOLE - 2 ))
663         
664         # comes after source for user set stuff
665         if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
666                 COLS_MAX=$COLS_MAX_CONSOLE
667                 SEP3=$SEP3_CONSOLE
668         else
669                 # too hard to read if no colors, so force that for users on irc
670                 if [[ $SCHEME == 0 ]];then
671                         SEP3=$SEP3_CONSOLE
672                 else
673                         SEP3=$SEP3_IRC
674                 fi
675                 COLS_MAX=$COLS_MAX_IRC
676         fi
677         
678         COLS_INNER=$(( $COLS_MAX - $INDENT - 1 ))
679         # Check for dependencies BEFORE running ANYTHING else except above functions
680         # Not all distro's have these depends installed by default. Don't want to run
681         # this if the user is requesting to see this information in the first place
682         # Only continue if required apps tests ok
683         if [[ $1 != '--recommends' ]];then
684                 check_required_apps
685                 check_recommended_apps
686         fi
687
688         SCRIPT_VERSION_NUMBER=$( parse_version_data 'main' )
689         SCRIPT_PATCH_NUMBER=$( parse_version_data 'patch' )
690         
691         # previous source location, check for bugs
692
693         ## this needs to run before the KONVI stuff is set below
694         ## Konversation 1.2 apparently does not like the $PPID test in get_start_client
695         ## So far there is no known way to detect if qt4_konvi is the parent process
696         ## this method will infer qt4_konvi as parent
697         get_start_client
698
699         # note: this only works if it's run from inside konversation as a script builtin or something
700         # only do this if inxi has been started as a konversation script, otherwise bypass this 
701 #       KONVI=3 ## for testing puroses
702         if [[ $KONVI -eq 1 || $KONVI -eq 3 ]];then
703                 if [[ $KONVI -eq 1 ]]; then ## dcop Konversation (ie 1.x < 1.2(qt3))    
704                         DCPORT="$1"
705                         DCSERVER="$2"
706                         DCTARGET="$3"
707                         shift 3
708                 elif [[ $KONVI -eq 3 ]]; then ## dbus Konversation (> 1.2 (qt4))
709                         DCSERVER="$1" ##dbus testing
710                         DCTARGET="$2" ##dbus testing
711                         shift 2
712                 fi
713
714                 # The section below is on request of Argonel from the Konversation developer team:
715                 # it sources config files like $HOME/.kde/share/apps/konversation/scripts/inxi.conf
716                 IFS=":"
717                 for kde_config in $( kde-config --path data )
718                 do
719                         if [[ -r ${kde_config}${KONVI_CFG} ]];then
720                                 source "${kde_config}${KONVI_CFG}"
721                                 break
722                         fi
723                 done
724                 IFS="$ORIGINAL_IFS"
725         fi
726
727         ## leave this for debugging dcop stuff if we get that working
728         #       print_screen_output "DCPORT: $DCPORT"
729         #       print_screen_output "DCSERVER: $DCSERVER"
730         #       print_screen_output "DCTARGET: $DCTARGET"
731         
732         # first init function must be set first for colors etc. Remember, no debugger
733         # stuff works on this function unless you set the debugging flag manually.
734         # Debugging flag -@ [number] will not work until get_parameters runs.
735         
736         # "$@" passes every parameter separately quoted, "$*" passes all parameters as one quoted parameter.
737         # must be here to allow debugger and other flags to be set.
738         get_parameters "$@"
739
740         # If no colorscheme was set in the parameter handling routine, then set the default scheme
741         if [[ $B_COLOR_SCHEME_SET != 'true' ]];then
742                 # This let's user pick their color scheme. For IRC, only shows the color schemes, no interactive
743                 # The override value only will be placed in user config files. /etc/inxi.conf can also override
744                 if [[ $B_RUN_COLOR_SELECTOR == 'true' ]];then 
745                         select_default_color_scheme
746                 else
747                         # set the default, then override as required
748                         color_scheme=$DEFAULT_COLOR_SCHEME
749                         if [[ -n $GLOBAL_COLOR_SCHEME ]];then
750                                 color_scheme=$GLOBAL_COLOR_SCHEME
751                         else
752                                 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
753                                         if [[ -n $CONSOLE_COLOR_SCHEME && -z $DISPLAY ]];then
754                                                 color_scheme=$CONSOLE_COLOR_SCHEME
755                                         elif [[ -n $VIRT_TERM_COLOR_SCHEME ]];then
756                                                 color_scheme=$VIRT_TERM_COLOR_SCHEME
757                                         fi
758                                 else
759                                         if [[ -n $IRC_X_TERM_COLOR_SCHEME && $B_CONSOLE_IRC == 'true' && -n $B_RUNNING_IN_DISPLAY ]];then
760                                                 color_scheme=$IRC_X_TERM_COLOR_SCHEME
761                                         elif [[ -n $IRC_CONS_COLOR_SCHEME && -z $DISPLAY ]];then
762                                                 color_scheme=$IRC_CONS_COLOR_SCHEME
763                                         elif [[ -n $IRC_COLOR_SCHEME ]];then
764                                                 color_scheme=$IRC_COLOR_SCHEME
765                                         fi
766                                 fi
767                         fi
768                         set_color_scheme $color_scheme
769                 fi
770         fi
771         
772         # all the pre-start stuff is in place now
773         B_SCRIPT_UP='true'
774         script_debugger "Debugger: $SCRIPT_NAME is up and running..."
775         
776         # then create the output
777         print_it_out
778
779         ## last steps
780         if [[ $B_RUNNING_IN_SHELL == 'true' && $SCHEME -gt 0 ]];then
781                 echo -n "\e[0m"
782         fi
783         eval $LOGFE
784         # weechat's executor plugin forced me to do this, and rightfully so, because else the exit code
785         # from the last command is taken..
786         exit 0
787 }
788
789 #### -------------------------------------------------------------------
790 #### basic tests: set script data, booleans, PATH, version numbers
791 #### -------------------------------------------------------------------
792
793 # Set PATH data so we can access all programs as user. Set BAN lists.
794 # initialize some boleans, these directories are used throughout the script
795 # some apps are used for extended functions any directory used, should be
796 # checked here first.
797 # No args taken.
798 initialize_data()
799 {
800         eval $LOGFS
801         BSD_VERSION=$( uname -s 2>/dev/null | tr '[A-Z]' '[a-z]' )
802         
803         # note: archbsd says they are a freebsd distro, so assuming it's the same as freebsd
804         if [[ -n $( grep 'bsd' <<< "$BSD_VERSION" ) ]];then
805                 # GNU/kfreebsd will by definition have GNU tools like sed/grep
806                 if [[ -n $( grep 'kfreebsd' <<< "$BSD_VERSION" ) ]];then
807                         BSD_TYPE='debian-bsd' # debian gnu bsd
808                 else
809                         BSD_TYPE='bsd' # all other bsds
810                         SED_I="-i ''"
811                         SED_RX='-E'
812                 fi
813         fi
814         # now set the script BOOLEANS for files required to run features
815         # note that freebsd has /proc but it's empty
816         if [[ -d "/proc/" && -z $BSD_TYPE ]];then
817                 B_PROC_DIR='true'
818         elif [[ -n $BSD_TYPE ]];then
819                 B_PROC_DIR='false'
820         else
821                 error_handler 6
822         fi
823         
824         initialize_paths
825         
826         if [[ -n $BSD_TYPE ]];then
827                 if [[ -e $FILE_DMESG_BOOT ]];then
828                         B_DMESG_BOOT_FILE='true'
829                 fi
830         else
831                 # found a case of battery existing but having nothing in it on desktop mobo
832                 # not all laptops show the first, 
833                 if [[ -n $( ls /proc/acpi/battery 2>/dev/null ) ]];then
834                         B_PORTABLE='true'
835                 fi
836         fi
837         
838         
839         if [[ -e $FILE_CPUINFO ]]; then
840                 B_CPUINFO_FILE='true'
841         fi
842
843         if [[ -e $FILE_MEMINFO ]];then
844                 B_MEMINFO_FILE='true'
845         fi
846
847         if [[ -e $FILE_ASOUND_DEVICE ]];then
848                 B_ASOUND_DEVICE_FILE='true'
849         fi
850
851         if [[ -e $FILE_ASOUND_VERSION ]];then
852                 B_ASOUND_VERSION_FILE='true'
853         fi
854
855         if [[ -f $FILE_LSB_RELEASE ]];then
856                 B_LSB_FILE='true'
857         fi
858         
859         if [[ -f $FILE_OS_RELEASE ]];then
860                 B_OS_RELEASE_FILE='true'
861         fi
862
863         if [[ -e $FILE_SCSI ]];then
864                 B_SCSI_FILE='true'
865         fi
866
867         if [[ -n $DISPLAY ]];then
868                 B_SHOW_DISPLAY_DATA='true'
869                 B_RUNNING_IN_DISPLAY='true'
870         fi
871         
872         if [[ -e $FILE_MDSTAT ]];then
873                 B_MDSTAT_FILE='true'
874         fi
875
876         if [[ -e $FILE_MODULES ]];then
877                 B_MODULES_FILE='true'
878         fi
879
880         if [[ -e $FILE_MOUNTS ]];then
881                 B_MOUNTS_FILE='true'
882         fi
883
884         if [[ -e $FILE_PARTITIONS ]];then
885                 B_PARTITIONS_FILE='true'
886         fi
887         # default to the normal location, then search for it
888         if [[ -e $FILE_XORG_LOG ]];then
889                 B_XORG_LOG='true'
890         else
891                 # Detect location of the Xorg log file
892                 if [[ -n $( type -p xset ) ]]; then
893                         FILE_XORG_LOG=$( xset q 2>/dev/null | grep -i 'Log file' | gawk '{print $3}')
894                         if [[ -e $FILE_XORG_LOG ]];then
895                                 B_XORG_LOG='true'
896                         fi
897                 fi
898         fi
899         # gfx output will require this flag
900         if [[ $( whoami ) == 'root' ]];then
901                 B_ROOT='true'
902         fi
903         eval $LOGFE
904 }
905
906 # arg: $1 - version number: main/patch/date
907 parse_version_data()
908 {
909         local version_data=''
910
911         # note, using ####[[:space:]]+ to avoid having this function also trip the version datas
912         case $1 in
913                 date)
914                         version_data="$( gawk -F ': ' '
915                         /####[[:space:]]+Date:/ {
916                                 print $NF
917                         }' $SCRIPT_PATH/$SCRIPT_NAME )"
918                         ;;
919                 main)
920                         version_data="$( gawk '
921                         /####[[:space:]]+Version:/ {
922                                 print $3
923                         }' $SCRIPT_PATH/$SCRIPT_NAME )"
924                         ;;
925                 patch)
926                         version_data="$( gawk '
927                         /####[[:space:]]+Patch Number:/ {
928                                 print $4
929                         }' $SCRIPT_PATH/$SCRIPT_NAME )"
930                         ;;
931         esac
932         echo $version_data
933 }
934
935 initialize_paths()
936 {
937         local path='' added_path='' b_path_found='' sys_path=''
938         # Extra path variable to make execute failures less likely, merged below
939         local extra_paths="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
940         
941         # this needs to be set here because various options call the parent initialize function directly.
942         SCRIPT_PATH=$( dirname $0 )
943
944         # Fallback paths put into $extra_paths; This might, among others, help on gentoo.
945         # Now, create a difference of $PATH and $extra_paths and add that to $PATH:
946         IFS=":"
947         for path in $extra_paths
948         do
949                 b_path_found='false'
950                 for sys_path in $PATH
951                 do
952                         if [[ $path == $sys_path ]];then
953                                 b_path_found='true'
954                         fi
955                 done
956                 if [[ $b_path_found == 'false' ]];then
957                         added_path="$added_path:$path"
958                 fi
959         done
960
961         IFS="$ORIGINAL_IFS"
962         PATH="${PATH}${added_path}"
963         ##echo "PATH='$PATH'"
964         ##/bin/sh -c 'echo "PATH in subshell=\"$PATH\""'
965 }
966
967 # No args taken.
968 check_recommended_apps()
969 {
970         eval $LOGFS
971         local bash_array_test=( "one" "two" )
972
973         # check for array ability of bash, this is only good for the warning at this time
974         # the boolean could be used later
975         # bash version 2.05b is used in DSL
976         # bash version 3.0 is used in Puppy Linux; it has a known array bug <reference to be placed here>
977         # versions older than 3.1 don't handle arrays
978         # distro's using below 2.05b are unknown, released in 2002
979         if [[ ${bash_array_test[1]} -eq "two" ]];then
980                 B_BASH_ARRAY='true'
981         else
982                 script_debugger "Suggestion: update to Bash v3.1 for optimal inxi output"
983         fi
984         # test for a few apps that bsds may not have after initial tests
985         if [[ -n $( type -p lspci ) ]];then
986                 B_LSPCI='true'
987         fi
988         if [[ -n $BSD_TYPE ]];then
989                 if [[ -n $( type -p sysctl ) ]];then
990                         B_SYSCTL='true'
991                 fi
992                 if [[ -n $( type -p pciconf ) ]];then
993                         B_PCICONF='true'
994                 fi
995         fi
996         # now setting qdbus/dcop for first run, some systems can have both by the way
997         if [[ -n $( type -p qdbus ) ]];then
998                 B_QDBUS='true'
999         fi
1000         if [[ -n $( type -p dcop ) ]];then
1001                 B_DCOP='true'
1002         fi
1003         eval $LOGFE
1004 }
1005
1006 # Determine if any of the absolutely necessary tools are absent
1007 # No args taken.
1008 check_required_apps()
1009 {
1010         eval $LOGFS
1011         local app_name='' app_path=''
1012         # bc removed from deps for now
1013         local depends="df gawk grep ps readlink tr uname uptime wc"
1014         
1015         if [[ -z $BSD_TYPE  ]];then
1016                 depends="$depends lspci"
1017         elif [[ $BSD_TYPE == 'bsd' ]];then
1018                 depends="$depends sysctl"
1019                 # debian-bsd has lspci but you must be root to run it
1020         elif [[ $BSD_TYPE == 'debian-bsd' ]];then
1021                 depends="$depends sysctl lspci"
1022         fi
1023         # no need to add xprop because it will just give N/A if not there, but if we expand use of xprop,
1024         # should add that here as a test, then use the B_SHOW_DISPLAY_DATA flag to trigger the tests in de function
1025         local x_apps="xrandr xdpyinfo glxinfo" 
1026
1027         if [[ $B_RUNNING_IN_DISPLAY == 'true' ]];then
1028                 for app_name in $x_apps
1029                 do
1030                         app_path=$( type -p $app_name )
1031                         if [[ -z $app_path ]];then
1032                                 script_debugger "Resuming in non X mode: $app_name not found. For package install advice run: $SCRIPT_NAME --recommends"
1033                                 B_SHOW_DISPLAY_DATA='false'
1034                                 break
1035                         fi
1036                 done
1037         fi
1038
1039         app_name=''
1040
1041         for app_name in $depends
1042         do
1043                 app_path=$( type -p $app_name )
1044                 if [[ -z $app_path ]];then
1045                         error_handler 5 "$app_name"
1046                 fi
1047         done
1048         eval $LOGFE
1049 }
1050
1051 ## note: this is now running inside each gawk sequence directly to avoid exiting gawk
1052 ## looping in bash through arrays, then re-entering gawk to clean up, then writing back to array
1053 ## in bash. For now I'll leave this here because there's still some interesting stuff to get re methods
1054 # Enforce boilerplate and buzzword filters
1055 # args: $1 - BAN_LIST_NORMAL/BAN_LIST_CPU; $2 - string to sanitize
1056 sanitize_characters()
1057 {
1058         eval $LOGFS
1059         # Cannot use strong quotes to unquote a string with pipes in it!
1060         # bash will interpret the |'s as usual and try to run a subshell!
1061         # Using weak quotes instead, or use '"..."'
1062         echo "$2" | gawk "
1063         BEGIN {
1064                 IGNORECASE=1
1065         }
1066         {
1067                 gsub(/${!1}/,\"\")
1068                 gsub(/ [ ]+/,\" \")    ## ([ ]+) with (space)
1069                 gsub(/^ +| +$/,\"\")   ## (pipe char) with (nothing)
1070                 print                  ## prints (returns) cleaned input
1071         }"
1072         eval $LOGFE
1073 }
1074
1075 # Set the colorscheme
1076 # args: $1 = <scheme number>|<"none">
1077 set_color_scheme()
1078 {
1079         eval $LOGFS
1080         local i='' a_output_colors='' a_color_codes=''
1081
1082         if [[ $1 -ge ${#A_COLOR_SCHEMES[@]} ]];then
1083                 set -- 1
1084         fi
1085         # Set a global variable to allow checking for chosen scheme later
1086         SCHEME="$1"
1087         if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
1088                 a_color_codes=( $ANSI_COLORS )
1089         else
1090                 a_color_codes=( $IRC_COLORS )
1091         fi
1092         for (( i=0; i < ${#A_COLORS_AVAILABLE[@]}; i++ ))
1093         do
1094                 eval "${A_COLORS_AVAILABLE[i]}=\"${a_color_codes[i]}\""
1095         done
1096         IFS=","
1097         a_output_colors=( ${A_COLOR_SCHEMES[$1]} )
1098         IFS="$ORIGINAL_IFS"
1099         # then assign the colors globally
1100         C1="${!a_output_colors[0]}"
1101         C2="${!a_output_colors[1]}"
1102         CN="${!a_output_colors[2]}"
1103         # ((COLOR_SCHEME++)) ## note: why is this? ##
1104         eval $LOGFE
1105 }
1106
1107 select_default_color_scheme()
1108 {
1109         eval $LOGFS
1110         local spacer='  ' options='' user_selection='' config_variable=''
1111         local config_file="$HOME/.$SCRIPT_NAME/$SCRIPT_NAME.conf"
1112         local irc_clear="\e[0m" 
1113         local irc_gui='Unset' irc_console='Unset' irc_x_term='Unset'
1114         local console='Unset' virt_term='Unset' global='Unset' 
1115         
1116         if [[ -n $IRC_COLOR_SCHEME ]];then
1117                 irc_gui="Set: $IRC_COLOR_SCHEME"
1118         fi
1119         if [[ -n $IRC_CONS_COLOR_SCHEME ]];then
1120                 irc_console="Set: $IRC_CONS_COLOR_SCHEME"
1121         fi
1122         if [[ -n $IRC_X_TERM_COLOR_SCHEME ]];then
1123                 irc_x_term="Set: $IRC_X_TERM_COLOR_SCHEME"
1124         fi
1125         if [[ -n $VIRT_TERM_COLOR_SCHEME ]];then
1126                 virt_term="Set: $VIRT_TERM_COLOR_SCHEME"
1127         fi
1128         if [[ -n $CONSOLE_COLOR_SCHEME ]];then
1129                 console="Set: $CONSOLE_COLOR_SCHEME"
1130         fi
1131         if [[ -n $GLOBAL_COLOR_SCHEME ]];then
1132                 global="Set: $GLOBAL_COLOR_SCHEME"
1133         fi
1134         
1135         # don't want these printing in irc since they show literally
1136         if [[ $B_RUNNING_IN_SHELL != 'true' ]];then
1137                 irc_clear=''
1138         fi
1139         # first make output neutral so it's just plain default for console client
1140         set_color_scheme "0"
1141         if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
1142                 print_screen_output "Welcome to $SCRIPT_NAME! Please select the default $COLOR_SELECTION color scheme."
1143                 # print_screen_output "You will see this message only one time per user account, unless you set preferences in: /etc/$SCRIPT_NAME.conf"
1144                 print_screen_output " "
1145         fi
1146         print_screen_output "Because there is no way to know your $COLOR_SELECTION foreground/background colors, you can"
1147         print_screen_output "set your color preferences from color scheme option list below. 0 is no colors, 1 neutral."
1148         print_screen_output "After these, there are 3 sets: 1-dark or light backgrounds; 2-light backgrounds; 3-dark backgrounds."
1149         if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
1150                 print_screen_output "Please note that this will set the $COLOR_SELECTION preferences only for user: $(whoami)"
1151         fi
1152         print_screen_output "------------------------------------------------------------------------------"
1153         for (( i=0; i < ${#A_COLOR_SCHEMES[@]}; i++ ))
1154         do
1155                 if [[ $i -gt 9 ]];then
1156                         spacer=' '
1157                 fi
1158                 # only offer the safe universal defaults
1159                 case $COLOR_SELECTION in
1160                         global|irc|irc-console|irc-virtual-terminal)
1161                                 if [[ $i -gt $SAFE_COLOR_COUNT ]];then
1162                                         break
1163                                 fi
1164                                 ;;
1165                 esac
1166                 set_color_scheme $i
1167                 print_screen_output "$irc_clear $i)$spacer${C1}Card:${C2} nVidia G86 [GeForce 8400 GS] ${C1}X.Org${C2} 1.7.7"
1168         done
1169         set_color_scheme 0
1170         
1171         if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
1172                 echo -n "\e[0m"
1173                 print_screen_output "$irc_clear $i)${spacer}Remove all color settings. Restore $SCRIPT_NAME default."
1174                 print_screen_output "$irc_clear $(($i+1)))${spacer}Continue, no changes or config file setting."
1175                 print_screen_output "$irc_clear $(($i+2)))${spacer}Exit, use another terminal, or set manually."
1176                 print_screen_output "------------------------------------------------------------------------------"
1177                 print_screen_output "Simply type the number for the color scheme that looks best to your eyes for your $COLOR_SELECTION settings"
1178                 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:"
1179                 print_screen_output "94 (console, no X - $console); 95 (terminal, X - $virt_term); 96 (irc, gui, X - $irc_gui);"
1180                 print_screen_output "97 (irc, X, in terminal - $irc_x_term); 98 (irc, no X - $irc_console); 99 (global - $global)"
1181                 print_screen_output "Your selection(s) will be stored here: $config_file"
1182                 print_screen_output "Global overrides all individual color schemes. Individual schemes remove the global setting."
1183                 print_screen_output "------------------------------------------------------------------------------"
1184                 read user_selection
1185                 if [[ -n $( grep -Es '^([0-9]+)$' <<< "$user_selection" ) && $user_selection -lt $i ]];then
1186                         case $COLOR_SELECTION in
1187                                 irc)
1188                                         config_variable='IRC_COLOR_SCHEME'
1189                                         ;;
1190                                 irc-console)
1191                                         config_variable='IRC_CONS_COLOR_SCHEME'
1192                                         ;;
1193                                 irc-virtual-terminal)
1194                                         config_variable='IRC_X_TERM_COLOR_SCHEME'
1195                                         ;;
1196                                 console)
1197                                         config_variable='CONSOLE_COLOR_SCHEME'
1198                                         ;;
1199                                 virtual-terminal)
1200                                         config_variable='VIRT_TERM_COLOR_SCHEME'
1201                                         ;;
1202                                 global)
1203                                         config_variable='GLOBAL_COLOR_SCHEME'
1204                                         ;;
1205                         esac
1206                         set_color_scheme $user_selection
1207                         # make file/directory first if missing
1208                         if [[ ! -f $config_file ]];then
1209                                 if [[ ! -d $HOME/.$SCRIPT_NAME ]];then
1210                                         mkdir $HOME/.$SCRIPT_NAME
1211                                 fi
1212                                 touch $config_file
1213                         fi
1214                         if [[ -z $( grep -s "$config_variable=" $config_file ) ]];then
1215                                 print_screen_output "Creating and updating config file for $COLOR_SELECTION color scheme now..."
1216                                 echo "$config_variable=$user_selection" >> $config_file
1217                         else
1218                                 print_screen_output "Updating config file for $COLOR_SELECTION color scheme now..."
1219                                 sed $SED_I "s/$config_variable=.*/$config_variable=$user_selection/" $config_file
1220                         fi
1221                         # file exists now so we can go on to cleanup
1222                         case $COLOR_SELECTION in
1223                                 irc|irc-console|irc-virtual-terminal|console|virtual-terminal)
1224                                         sed $SED_I '/GLOBAL_COLOR_SCHEME=/d' $config_file
1225                                         ;;
1226                                 global)
1227                                         sed $SED_I -e '/VIRT_TERM_COLOR_SCHEME=/d' -e '/CONSOLE_COLOR_SCHEME=/d' -e '/IRC_COLOR_SCHEME=/d' \
1228                                         -e '/IRC_CONS_COLOR_SCHEME=/d' -e '/IRC_X_TERM_COLOR_SCHEME=/d' $config_file
1229                                         ;;
1230                         esac
1231                 elif [[ $user_selection == $i ]];then
1232                         print_screen_output "Removing all color settings from config file now..."
1233                         sed $SED_I -e '/VIRT_TERM_COLOR_SCHEME=/d' -e '/GLOBAL_COLOR_SCHEME=/d' -e '/CONSOLE_COLOR_SCHEME=/d' \
1234                         -e '/IRC_COLOR_SCHEME=/d' -e '/IRC_CONS_COLOR_SCHEME=/d' -e '/IRC_X_TERM_COLOR_SCHEME=/d' $config_file
1235                         set_color_scheme $DEFAULT_COLOR_SCHEME
1236                 elif [[ $user_selection == $(( $i+1 )) ]];then
1237                         print_screen_output "Ok, continuing $SCRIPT_NAME unchanged. You can set the colors anytime by starting with: -c 95 to 99"
1238                         if [[ -n $CONSOLE_COLOR_SCHEME && -z $DISPLAY ]];then
1239                                 set_color_scheme $CONSOLE_COLOR_SCHEME
1240                         elif [[ -n $VIRT_TERM_COLOR_SCHEME ]];then
1241                                 set_color_scheme $VIRT_TERM_COLOR_SCHEME
1242                         else
1243                                 set_color_scheme $DEFAULT_COLOR_SCHEME
1244                         fi
1245                 elif [[ $user_selection == $(( $i+2 )) ]];then
1246                         set_color_scheme $DEFAULT_COLOR_SCHEME
1247                         print_screen_output "Ok, exiting $SCRIPT_NAME now. You can set the colors later."
1248                         exit 0
1249                 else
1250                         print_screen_output "Error - Invalid Selection. You entered this: $user_selection"
1251                         print_screen_output " "
1252                         select_default_color_scheme
1253                 fi
1254         else
1255                 print_screen_output "------------------------------------------------------------------------------"
1256                 print_screen_output "After finding the scheme number you like, simply run this again in a terminal to set the configuration"
1257                 print_screen_output "data file for your irc client. You can set color schemes for the following: start inxi with -c plus:"
1258                 print_screen_output "94 (console, no X - $console); 95 (terminal, X - $virt_term); 96 (irc, gui, X - $irc_gui);"
1259                 print_screen_output "97 (irc, X, in terminal - $irc_x_term); 98 (irc, no X - $irc_console); 99 (global - $global)"
1260                 exit 0
1261         fi
1262
1263         eval $LOGFE
1264 }
1265
1266 ########################################################################
1267 #### UTILITY FUNCTIONS
1268 ########################################################################
1269
1270 #### -------------------------------------------------------------------
1271 #### error handler, debugger, script updater
1272 #### -------------------------------------------------------------------
1273
1274 # Error handling
1275 # args: $1 - error number; $2 - optional, extra information; $3 - optional extra info
1276 error_handler()
1277 {
1278         eval $LOGFS
1279         local error_message=''
1280
1281         # assemble the error message
1282         case $1 in
1283                 2)      error_message="large flood danger, debug buffer full!"
1284                         ;;
1285                 3)      error_message="unsupported color scheme number: $2"
1286                         ;;
1287                 4)      error_message="unsupported verbosity level: $2"
1288                         ;;
1289                 5)      error_message="dependency not met: $2 not found in path.\nFor distribution installation package names and missing apps information, run: $SCRIPT_NAME --recommends"
1290                         ;;
1291                 6)      error_message="/proc not found! Quitting..."
1292                         ;;
1293                 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"
1294                         ;;
1295                 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"
1296                         ;;
1297                 9)      error_message="unsupported debugging level: $2"
1298                         ;;
1299                 10)
1300                         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/"
1301                         ;;
1302                 11)
1303                         error_message="unsupported testing option argument: -! $2"
1304                         ;;
1305                 12)
1306                         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."
1307                         ;;
1308                 13)
1309                         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"
1310                         ;;
1311                 14)
1312                         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"
1313                         ;;
1314                 15)
1315                         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"
1316                         ;;
1317                 16)
1318                         error_message="$SCRIPT_NAME downloaded but the file data is corrupted. Purged data and using current version."
1319                         ;;
1320                 17)
1321                         error_message="All $SCRIPT_NAME self updater features have been disabled by the distribution\npackage maintainer. This includes the option you used: $2"
1322                         ;;
1323                 18)
1324                         error_message="The argument you provided for $2 does not have supported syntax.\nPlease use the following formatting:\n$3"
1325                         ;;
1326                 19)
1327                         error_message="The option $2 has been deprecated. Please use $3 instead.\nSee -h for instructions and syntax."
1328                         ;;
1329                 20)
1330                         error_message="The option you selected has been deprecated. $2\nSee the -h (help) menu for currently supported options."
1331                         ;;
1332                 *)      error_message="error unknown: $@"
1333                         set -- 99
1334                         ;;
1335         esac
1336         # then print it and exit
1337         print_screen_output "Error $1: $error_message"
1338         eval $LOGFE
1339         exit $1
1340 }
1341
1342 # prior to script up set, pack the data into an array
1343 # then we'll print it out later.
1344 # args: $1 - $@ debugging string text
1345 script_debugger()
1346 {
1347         eval $LOGFS
1348         if [[ $B_SCRIPT_UP == 'true' ]];then
1349                 # only return if debugger is off and no pre start up errors have occured
1350                 if [[ $DEBUG -eq 0 && $DEBUG_BUFFER_INDEX -eq 0 ]];then
1351                         return 0
1352                 # print out the stored debugging information if errors occured
1353                 elif [[ $DEBUG_BUFFER_INDEX -gt 0 ]];then
1354                         for (( DEBUG_BUFFER_INDEX=0; DEBUG_BUFFER_INDEX < ${#A_DEBUG_BUFFER[@]}; DEBUG_BUFFER_INDEX++ ))
1355                         do
1356                                 print_screen_output "${A_DEBUG_BUFFER[$DEBUG_BUFFER_INDEX]}"
1357                         done
1358                         DEBUG_BUFFER_INDEX=0
1359                 fi
1360                 # or print out normal debugger messages if debugger is on
1361                 if [[ $DEBUG -gt 0 ]];then
1362                         print_screen_output "$1"
1363                 fi
1364         else
1365                 if [[ $B_DEBUG_FLOOD == 'true' && $DEBUG_BUFFER_INDEX -gt 10 ]];then
1366                         error_handler 2
1367                 # this case stores the data for later printout, will print out only
1368                 # at B_SCRIPT_UP == 'true' if array index > 0
1369                 else
1370                         A_DEBUG_BUFFER[$DEBUG_BUFFER_INDEX]="$1"
1371                         # increment count for next pre script up debugging error
1372                         (( DEBUG_BUFFER_INDEX++ ))
1373                 fi
1374         fi
1375         eval $LOGFE
1376 }
1377
1378 # NOTE: no logging available until get_parameters is run, since that's what sets logging
1379 # in order to trigger earlier logging manually set B_USE_LOGGING to true in top variables.
1380 # $1 alone: logs data; $2 with or without $3 logs func start/end.
1381 # $1 type (fs/fe/cat/raw) or logged data; [$2 is $FUNCNAME; [$3 - function args]]
1382 log_function_data()
1383 {
1384         if [ "$B_USE_LOGGING" == 'true' ];then
1385                 local logged_data='' spacer='   ' line='----------------------------------------'
1386                 case $1 in
1387                         fs)
1388                                 logged_data="Function: $2 - Primary: Start"
1389                                 if [ -n "$3" ];then
1390                                         logged_data="$logged_data\n${spacer}Args: $3"
1391                                 fi
1392                                 spacer=''
1393                                 ;;
1394                         fe)
1395                                 logged_data="Function: $2 - Primary: End"
1396                                 spacer=''
1397                                 ;;
1398                         cat)
1399                                 if [[ $B_LOG_FULL_DATA == 'true' ]];then
1400                                         logged_data="\n$line\nFull file data: cat $2\n\n$( cat $2 )\n$line\n"
1401                                         spacer=''
1402                                 fi
1403                                 ;;
1404                         raw)
1405                                 if [[ $B_LOG_FULL_DATA == 'true' ]];then
1406                                         logged_data="\n$line\nRaw system data:\n\n$2\n$line\n"
1407                                         spacer=''
1408                                 fi
1409                                 ;;
1410                         *)
1411                                 logged_data="$1"
1412                                 ;;
1413                 esac
1414                 # Create any required line breaks and strip out escape color code, either ansi (case 1)or irc (case 2).
1415                 # This pattern doesn't work for irc colors, if we need that someone can figure it out
1416                 if [[ -n $logged_data ]];then
1417                         if [[ $B_LOG_COLORS != 'true' ]];then
1418                                 echo -e "${spacer}$logged_data" | sed $SED_RX 's/\x1b\[[0-9]{1,2}(;[0-9]{1,2}){0,2}m//g' >> $LOG_FILE
1419                         else
1420                                 echo -e "${spacer}$logged_data" >> $LOG_FILE
1421                         fi
1422                 fi
1423         fi
1424 }
1425
1426 # called in the initial -@ 10 script args setting so we can get logging as soon as possible
1427 # will have max 3 files, inxi.log, inxi.1.log, inxi.2.log
1428 create_rotate_logfiles()
1429 {
1430         if [[ ! -d $SCRIPT_DATA_DIR ]];then
1431                 mkdir $SCRIPT_DATA_DIR
1432         fi
1433         # do the rotation if logfile exists
1434         if [[ -f $LOG_FILE ]];then
1435                 # copy if present second to third
1436                 if [[ -f $LOG_FILE_1 ]];then
1437                         mv -f $LOG_FILE_1 $LOG_FILE_2
1438                 fi
1439                 # then copy initial to second
1440                 mv -f $LOG_FILE $LOG_FILE_1
1441         fi
1442         # now create the logfile
1443         touch $LOG_FILE
1444         # and echo the start data
1445         echo "=========================================================" >> $LOG_FILE
1446         echo "START $SCRIPT_NAME LOGGING:"                               >> $LOG_FILE
1447         echo "Script started: $( date +%Y-%m-%d-%H:%M:%S )"              >> $LOG_FILE
1448         echo "=========================================================" >> $LOG_FILE
1449 }
1450
1451 # args: $1 - download url, not including file name; $2 - string to print out
1452 # $3 - update type option
1453 # note that $1 must end in / to properly construct the url path
1454 script_self_updater()
1455 {
1456         eval $LOGFS
1457         local wget_error=0 file_contents='' wget_man_error=0 
1458         local man_file_path="$MAN_FILE_LOCATION/inxi.1.gz"
1459         
1460         if [[ $B_RUNNING_IN_SHELL != 'true' ]];then
1461                 print_screen_output "Sorry, you can't run the $SCRIPT_NAME self updater option (-$3) in an IRC client."
1462                 exit 1
1463         fi
1464
1465         print_screen_output "Starting $SCRIPT_NAME self updater."
1466         print_screen_output "Currently running $SCRIPT_NAME version number: $SCRIPT_VERSION_NUMBER"
1467         print_screen_output "Current version patch number: $SCRIPT_PATCH_NUMBER"
1468         print_screen_output "Updating $SCRIPT_NAME in $SCRIPT_PATH using $2 as download source..."
1469
1470         file_contents="$( wget -q -O - $1$SCRIPT_NAME )" || wget_error=$?
1471         # then do the actual download
1472         if [[  $wget_error -eq 0 ]];then
1473                 # make sure the whole file got downloaded and is in the variable
1474                 if [[ -n $( grep '###\*\*EOF\*\*###' <<< "$file_contents" ) ]];then
1475                         echo "$file_contents" > $SCRIPT_PATH/$SCRIPT_NAME || error_handler 14 "$?"
1476                         chmod +x $SCRIPT_PATH/$SCRIPT_NAME || error_handler 15 "$?"
1477                         SCRIPT_VERSION_NUMBER=$( parse_version_data 'main' )
1478                         SCRIPT_PATCH_NUMBER=$( parse_version_data 'patch' )
1479                         print_screen_output "Successfully updated to $2 version: $SCRIPT_VERSION_NUMBER"
1480                         print_screen_output "New $2 version patch number: $SCRIPT_PATCH_NUMBER"
1481                         print_screen_output "To run the new version, just start $SCRIPT_NAME again."
1482                         print_screen_output "----------------------------------------"
1483                         print_screen_output "Starting download of man page file now."
1484                         if [[ ! -d $MAN_FILE_LOCATION ]];then
1485                                 print_screen_output "The required man directory was not detected on your system, unable to continue: $MAN_FILE_LOCATION"
1486                         else
1487                                 if [[ $B_ROOT == 'true' ]];then
1488                                         print_screen_output "Checking Man page download URL..."
1489                                         if [[ -f /usr/share/man/man8/inxi.8.gz ]];then
1490                                                 print_screen_output "Updating man page location to man1."
1491                                                 mv -f /usr/share/man/man8/inxi.8.gz /usr/share/man/man1/inxi.1.gz 
1492                                                 if [[ -n $( type -p mandb ) ]];then
1493                                                         exec $( type -p mandb ) -q 
1494                                                 fi
1495                                         fi
1496                                         wget -q --spider $MAN_FILE_DOWNLOAD || wget_man_error=$?
1497                                         if [[ $wget_man_error -eq 0 ]];then
1498                                                 print_screen_output "Man file download URL verified: $MAN_FILE_DOWNLOAD"
1499                                                 print_screen_output "Downloading Man page file now."
1500                                                 wget -q -O $man_file_path $MAN_FILE_DOWNLOAD || wget_man_error=$?
1501                                                 if [[ $wget_man_error -gt 0 ]];then
1502                                                         print_screen_output "Oh no! Something went wrong downloading the Man gz file at: $MAN_FILE_DOWNLOAD"
1503                                                         print_screen_output "Check the error messages for what happened. Error: $wget_man_error"
1504                                                 else
1505                                                         print_screen_output "Download/install of man page successful. Check to make sure it works: man inxi"
1506                                                 fi
1507                                         else
1508                                                 print_screen_output "Man file download URL failed, unable to continue: $MAN_FILE_DOWNLOAD"
1509                                         fi
1510                                 else
1511                                         print_screen_output "Updating / Installing the Man page requires root user, writing to: $MAN_FILE_LOCATION"
1512                                         print_screen_output "If you want the man page, you'll have to run $SCRIPT_NAME -$3 as root."
1513                                 fi
1514                         fi
1515                         exit 0
1516                 else
1517                         error_handler 16
1518                 fi
1519         # now run the error handlers on any wget failure
1520         else
1521                 if [[ $2 == 'svn server' ]];then
1522                         error_handler 8 "$wget_error"
1523                 elif [[ $2 == 'alt server' ]];then
1524                         error_handler 10 "$1"
1525                 else
1526                         error_handler 12 "$1"
1527                 fi
1528         fi
1529         eval $LOGFS
1530 }
1531
1532 # args: $1 - debug data type: sys|xorg|disk
1533 debug_data_collector()
1534 {
1535         local xiin_app='' xiin_data_file='' xiin_download='' error='' b_run_xiin='false'
1536         local debug_data_dir='' bsd_string=''
1537         local completed_gz_file='' xiin_file='xiin.py' ftp_upload='ftp.techpatterns.com/incoming'
1538         local Line='-------------------------'
1539         local start_directory=$( pwd )
1540         
1541         if [[ -n $BSD_TYPE ]];then
1542                 bsd_string="$BSD_TYPE-"
1543         fi
1544         
1545         debug_data_dir="inxi-$bsd_string$(tr ' ' '-' <<< $HOSTNAME | tr '[A-Z]' '[a-z]' )-$1-$(date +%Y%m%d)" 
1546         
1547         if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
1548                 if [[ -n $ALTERNATE_FTP ]];then
1549                         ftp_upload=$ALTERNATE_FTP
1550                 fi
1551                 echo "Starting debugging data collection type: $1"
1552                 echo -n "Checking/creating required directories... "
1553                 if [[ ! -d $SCRIPT_DATA_DIR ]];then
1554                         mkdir $SCRIPT_DATA_DIR
1555                 fi
1556                 echo 'completed'
1557                 cd $SCRIPT_DATA_DIR
1558                 if [[ -d $SCRIPT_DATA_DIR/$debug_data_dir ]];then
1559                         echo 'Deleting previous xiin data directory...'
1560                         rm -rf $SCRIPT_DATA_DIR/$debug_data_dir
1561                 fi
1562                 mkdir $SCRIPT_DATA_DIR/$debug_data_dir
1563                 if [[ -f $SCRIPT_DATA_DIR/$debug_data_dir.tar.gz ]];then
1564                         echo 'Deleting previous tar.gz file...'
1565                         rm -f $SCRIPT_DATA_DIR/$debug_data_dir.tar.gz
1566                 fi
1567                 
1568                 echo 'Collecting system info: sensors, lsusb, lspci, lspci -v data, plus /proc data'
1569                 echo 'also checking for dmidecode data: note, you must be root to have dmidecode work.'
1570                 echo "Data going into: $SCRIPT_DATA_DIR/$debug_data_dir"
1571                 # bsd tools
1572                 pciconf -vl &> $debug_data_dir/bsd-pciconf-vl.txt
1573                 sysctl -a &> $debug_data_dir/bsd-sysctl-a.txt
1574                 
1575                 dmidecode &> $debug_data_dir/dmidecode.txt
1576                 
1577                 lscpu &> $debug_data_dir/lscpu.txt
1578                 lspci &> $debug_data_dir/lspci.txt
1579                 lspci -n &> $debug_data_dir/lspci-n.txt
1580                 lspci -v &> $debug_data_dir/lspci-v.txt
1581                 lsusb &> $debug_data_dir/lsusb.txt
1582                 ps aux &> $debug_data_dir/ps-aux.txt
1583                 runlevel &> $debug_data_dir/runlevel.txt
1584                 systemctl list-units &> $debug_data_dir/systemctl-list-units.txt
1585                 systemctl list-units --type=target &> $debug_data_dir/systemctl-list-units-target.txt
1586                 initctl list &> $debug_data_dir/initctl-list.txt
1587                 sensors &> $debug_data_dir/sensors.txt
1588                 strings --version  &> $debug_data_dir/strings.txt
1589                 nvidia-smi -q &> $debug_data_dir/nvidia-smi-q.txt
1590                 nvidia-smi -q -x &> $debug_data_dir/nvidia-smi-xq.txt
1591                 
1592                 ls /usr/bin/gcc* &> $debug_data_dir/gcc-sys-versions.txt
1593                 gcc --version &> $debug_data_dir/gcc-version.txt
1594                 cat /etc/issue &> $debug_data_dir/etc-issue.txt
1595                 cat $FILE_LSB_RELEASE &> $debug_data_dir/lsb-release.txt
1596                 cat $FILE_OS_RELEASE &> $debug_data_dir/os-release.txt
1597                 cat $FILE_ASOUND_DEVICE &> $debug_data_dir/proc-asound-device.txt
1598                 cat $FILE_ASOUND_VERSION &> $debug_data_dir/proc-asound-version.txt
1599                 cat $FILE_CPUINFO &> $debug_data_dir/proc-cpu-info.txt
1600                 cat $FILE_MEMINFO &> $debug_data_dir/proc-meminfo.txt
1601                 cat $FILE_MODULES &> $debug_data_dir/proc-modules.txt
1602                 cat /proc/net/arp &> $debug_data_dir/proc-net-arp.txt 
1603                 # bsd data
1604                 cat /var/run/dmesg.boot &> $debug_data_dir/bsd-var-run-dmesg.boot.txt 
1605                 
1606                 check_recommends_user_output &> $debug_data_dir/check-recommends-user-output.txt
1607                 # first download and verify xiin
1608                 if [[ $B_UPLOAD_DEBUG_DATA == 'true' || $1 == 'disk' || $1 == 'sys' || $1 == 'all' ]];then
1609                         touch $SCRIPT_DATA_DIR/$debug_data_dir/xiin-error.txt
1610                         echo "Downloading required tree traverse tool $xiin_file..."
1611                         if [[ -f xiin && ! -f $xiin_file ]];then
1612                                 mv -f xiin $xiin_file
1613                         fi
1614                         # -Nc is creating really weird download anomolies, so using -O instead
1615                         xiin_download="$( wget -q -O - http://inxi.googlecode.com/svn/branches/xiin/$xiin_file )"
1616                         # if nothing got downloaded kick out error, otherwise we'll use an older version
1617                         if [[ $? -gt 0 && ! -f $xiin_file ]];then
1618                                 echo -e "ERROR: Failed to download required file: $xiin_file\nMaybe the remote site is down or your networking is broken?"
1619                                 echo "Continuing with incomplete data collection."
1620                                 echo "$xiin_file download failed and no existing $xiin_file" >> $debug_data_dir/xiin-error.txt
1621                         elif [[ -n $( grep -s '# EOF' <<< "$xiin_download" ) || -f $xiin_file ]];then
1622                                 if [[ -n $( grep -s '# EOF' <<< "$xiin_download" ) ]];then
1623                                         echo "Updating $xiin_file from remote location"
1624                                         echo "$xiin_download" > $xiin_file
1625                                 else
1626                                         echo "Using local $xiin_file due to download failure"
1627                                 fi
1628                                 b_run_xiin='true'
1629                         else
1630                                 echo -e "ERROR: $xiin_file downloaded but the program file data is corrupted.\nContinuing with incomplete data collection."
1631                                 echo "$xiin_file downloaded but the program file data is corrupted." >> $debug_data_dir/xiin-error.txt
1632                         fi
1633                 fi
1634                 # note, only bash 4> supports ;;& for case, so using if/then here
1635                 if [[ $1 == 'disk' || $1 == 'sys' || $1 == 'all' ]];then
1636                         xiin_data_file=$SCRIPT_DATA_DIR/$debug_data_dir/xiin-sys.txt
1637                         echo 'Collecting networking data...'
1638                         ifconfig &> $debug_data_dir/ifconfig.txt
1639                         ip addr &> $debug_data_dir/ip-addr.txt
1640                         if [[ $b_run_xiin == 'true' && -z $BSD_TYPE ]];then
1641                                 echo $Line
1642                                 echo "Running $xiin_file tool now on /sys..."
1643                                 echo "Using Python version:" && python --version
1644                                 python --version &> $debug_data_dir/python-version.txt
1645                                 python ./$xiin_file -d /sys -f $xiin_data_file
1646                                 if [[ $? -ne 0 ]];then
1647                                         error=$?
1648                                         echo -e "ERROR: $xiin_file exited with error $error - removing data file.\nContinuing with incomplete data collection."
1649                                         echo "Continuing with incomplete data collection."
1650                                         rm -f $xiin_data_file
1651                                         echo "$xiin_file data generation failed with python error $error" >> $debug_data_dir/xiin-error.txt
1652                                 fi
1653                                 echo $Line
1654                         fi
1655                 fi
1656                 if [[ $1 == 'xorg' || $1 == 'all' ]];then
1657                         if [[ $B_RUNNING_IN_DISPLAY != 'true' ]];then
1658                                 echo 'Warning: only some of the data collection can occur if you are not in X'
1659                                 touch $debug_data_dir/warning-user-not-in-x
1660                         fi
1661                         if [[ $B_ROOT == 'true' ]];then
1662                                 echo 'Warning: only some of the data collection can occur if you are running as Root user'
1663                                 touch $debug_data_dir/warning-root-user
1664                         fi
1665                         echo 'Collecting Xorg log and xorg.conf files'
1666                         if [[ -e $FILE_XORG_LOG ]];then
1667                                 cat $FILE_XORG_LOG &> $debug_data_dir/xorg-log-file.txt
1668                         else
1669                                 touch $debug_data_dir/no-xorg-log-file
1670                         fi
1671                         if [[ -e /etc/X11/xorg.conf ]];then
1672                                 cp /etc/X11/xorg.conf $SCRIPT_DATA_DIR/$debug_data_dir
1673                         else
1674                                 touch $debug_data_dir/no-xorg-conf-file
1675                         fi
1676                         if [[ -n $( ls /etc/X11/xorg.conf.d/ 2>/dev/null ) ]];then
1677                                 ls /etc/X11/xorg.conf.d &> $debug_data_dir/ls-etc-x11-xorg-conf-d.txt
1678                                 cp /etc/X11/xorg.conf.d $SCRIPT_DATA_DIR/$debug_data_dir
1679                         else
1680                                 touch $debug_data_dir/no-xorg-conf-d-files
1681                         fi
1682                         echo 'Collecting X, xprop, glxinfo, xrandr, xdpyinfo data...'
1683                         xprop -root &> $debug_data_dir/xprop_root.txt
1684                         glxinfo &> $debug_data_dir/glxinfo.txt
1685                         xdpyinfo &> $debug_data_dir/xdpyinfo.txt
1686                         xrandr &> $debug_data_dir/xrandr.txt
1687                         X -version &> $debug_data_dir/x-version.txt
1688                         Xorg -version &> $debug_data_dir/xorg-version.txt
1689                         echo $GNOME_DESKTOP_SESSION_ID &> $debug_data_dir/gnome-desktop-session-id.txt
1690                         # kde 3 id
1691                         echo $KDE_FULL_SESSION &> $debug_data_dir/kde3-ful-session.txt
1692                         echo $KDE_SESSION_VERSION &> $debug_data_dir/kde456-session-version.txt
1693                         echo "$(kded$KDE_SESSION_VERSION --version )" &> $debug_data_dir/kde-version-data.txt
1694                         echo $XDG_CURRENT_DESKTOP &> $debug_data_dir/xdg-current-desktop.txt
1695                 fi
1696                 if [[ $1 == 'disk' || $1 == 'all' ]];then
1697                         echo 'Collecting dev, label, disk, uuid data, df...'
1698                         ls -l /dev &> $debug_data_dir/dev-data.txt
1699                         ls -l /dev/disk &> $debug_data_dir/dev-disk-data.txt
1700                         ls -l /dev/disk/by-id &> $debug_data_dir/dev-disk-id-data.txt
1701                         ls -l /dev/disk/by-label &> $debug_data_dir/dev-disk-label-data.txt
1702                         ls -l /dev/disk/by-uuid &> $debug_data_dir/dev-disk-uuid-data.txt
1703                         ls -l /dev/disk/by-path &> $debug_data_dir/dev-disk-path-data.txt
1704                         ls -l /dev/mapper &> $debug_data_dir/dev-disk-mapper-data.txt
1705                         readlink /dev/root &> $debug_data_dir/dev-root.txt
1706                         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
1707                         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
1708                         df -H -T &> $debug_data_dir/bsd-df-H-T-no-excludes.txt
1709                         df -H &> $debug_data_dir/bsd-df-H-no-excludes.txt
1710                         # bsd tool
1711                         mount &> $debug_data_dir/mount.txt
1712                         gpart list &> $debug_data_dir/bsd-gpart-list.txt
1713                         gpart show &> $debug_data_dir/bsd-gpart-show.txt
1714                         gpart status &> $debug_data_dir/bsd-gpart-status.txt
1715                         swapctl -l &> $debug_data_dir/bsd-swapctl-l.txt
1716                         swapon -s &> $debug_data_dir/swapon-s.txt
1717                         sysctl -b kern.geom.conftxt  &> $debug_data_dir/bsd-sysctl-b-kern.geom.conftxt.txt
1718                         sysctl -b kern.geom.confxml &> $debug_data_dir/bsd-sysctl-b-kern.geom.confxml.txt
1719                         zfs list &> $debug_data_dir/bsd-zfs-list.txt
1720                         zpool list &> $debug_data_dir/bsd-zpool-list.txt
1721                         zpool list -v &> $debug_data_dir/bsd-zpool-list-v.txt
1722                         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
1723                         df -P &> $debug_data_dir/bsd-df-P-no-excludes.txt
1724                         cat /proc/mdstat &> $debug_data_dir/proc-mdstat.txt
1725                         cat $FILE_PARTITIONS &> $debug_data_dir/proc-partitions.txt
1726                         cat $FILE_SCSI &> $debug_data_dir/proc-scsi.txt
1727                         cat $FILE_MOUNTS &> $debug_data_dir/proc-mounts.txt
1728                         cat /proc/sys/dev/cdrom/info &> $debug_data_dir/proc-cdrom-info.txt
1729                         ls /proc/ide/ &> $debug_data_dir/proc-ide.txt
1730                         cat /proc/ide/*/* &> $debug_data_dir/proc-ide-hdx-cat.txt
1731                         cat /etc/fstab &> $debug_data_dir/etc-fstab.txt
1732                         cat /etc/mtab &> $debug_data_dir/etc-mtab.txt
1733                 fi
1734                 echo 'Creating inxi output file now. This can take a few seconds...'
1735                 echo "Starting $SCRIPT_NAME from: $start_directory"
1736                 cd $start_directory
1737                 $SCRIPT_PATH/$SCRIPT_NAME -FRploudxxx -c 0 -@ 8 > $SCRIPT_DATA_DIR/$debug_data_dir/inxi-FRploudxxx.txt
1738                 cp $LOG_FILE $SCRIPT_DATA_DIR/$debug_data_dir
1739                 if [[ -f $SCRIPT_DATA_DIR/$debug_data_dir.tar.gz ]];then
1740                         echo "Found and removing previous tar.gz data file: $debug_data_dir.tar.gz"
1741                         rm -f $SCRIPT_DATA_DIR/$debug_data_dir.tar.gz
1742                 fi
1743                 cd $SCRIPT_DATA_DIR
1744                 echo 'Creating tar.gz compressed file of this material now. Contents:'
1745                 echo $Line
1746                 tar -cvzf $debug_data_dir.tar.gz $debug_data_dir
1747                 echo $Line
1748                 echo 'Cleaning up leftovers...'
1749                 rm -rf $debug_data_dir
1750                 echo 'Testing gzip file integrity...'
1751                 gzip -t $debug_data_dir.tar.gz
1752                 if [[ $? -gt 0 ]];then
1753                         echo 'Data in gz is corrupted, removing gzip file, try running data collector again.'
1754                         rm -f $debug_data_dir.tar.gz
1755                         echo "Data in gz is corrupted, removed gzip file" >> $debug_data_dir/gzip-error.txt
1756                 else
1757                         echo 'All done, you can find your data gzipped directory here:'
1758                         completed_gz_file=$SCRIPT_DATA_DIR/$debug_data_dir.tar.gz
1759                         echo $completed_gz_file
1760                         if [[ $B_UPLOAD_DEBUG_DATA == 'true' ]];then
1761                                 echo $Line
1762                                 if [[ $b_run_xiin == 'true' ]];then
1763                                         echo "Running automatic upload of data to remote server $ftp_upload now..."
1764                                         python ./$xiin_file --version
1765                                         python ./$xiin_file -u $completed_gz_file $ftp_upload
1766                                         if [[ $? -gt 0 ]];then
1767                                                 echo $Line
1768                                                 echo "Error: looks like the ftp upload failed. Error number: $?"
1769                                                 echo "The ftp upload failed. Error number: $?" >> $debug_data_dir/xiin-error.txt
1770                                         fi
1771                                 else
1772                                         echo 'Unable to run the automoatic ftp upload because of an error with the xiin download.'
1773                                         echo "Unable to run the automoatic ftp upload because of an error with the xiin download" >> $debug_data_dir/xiin-error.txt
1774                                 fi
1775                         else
1776                                 echo 'You can upload this here using most file managers: ftp.techpatterns.com/incoming'
1777                                 echo 'then let a maintainer know it is uploaded.'
1778                         fi
1779                 fi
1780         else
1781                 echo 'This feature only available in console or shell client! Exiting now.'
1782         fi
1783         exit 0
1784 }
1785
1786 check_recommends_user_output()
1787 {
1788         local Line='-----------------------------------------------------------------------------------------'
1789         local gawk_version='N/A' sed_version='N/A' sudo_version='N/A' python_version='N/A'
1790         
1791         if [[ $B_RUNNING_IN_SHELL != 'true' ]];then
1792                 print_screen_output "Sorry, you can't run this option in an IRC client."
1793                 exit 1
1794         fi
1795         
1796         initialize_paths
1797         
1798         echo "$SCRIPT_NAME will now begin checking for the programs it needs to operate. First a check of"
1799         echo "the main languages and tools $SCRIPT_NAME uses. Python is only for debugging data collection."
1800         echo $Line
1801         echo "Bash version: $( bash --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^GNU bash/ {print $4}' )"
1802         if [[ -n $( type -p gawk ) ]];then
1803                 gawk_version=$( gawk --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^GNU Awk/ {print $3}' )
1804         fi
1805         if [[ -n $( type -p sed ) ]];then
1806                 sed_version=$( sed --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^GNU sed version/ {print $4}' )
1807                 if [[ -z $sed_version ]];then
1808                         # note: bsd sed shows error with --version flag
1809                         sed_version=$( sed --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^sed: illegal option/ {print "BSD sed"}' )
1810                 fi
1811         fi
1812         if [[ -n $( type -p sudo ) ]];then
1813                 sudo_version=$( sudo -V 2>&1 | awk 'BEGIN {IGNORECASE=1} /^Sudo version/ {print $3}' )
1814         fi
1815         if [[ -n $( type -p python ) ]];then
1816                 python_version=$( python --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^Python/ {print $2}' )
1817         fi
1818         echo "Gawk version: $gawk_version"
1819         echo "Sed version: $sed_version"
1820         echo "Sudo version: $sudo_version"
1821         echo "Python version: $python_version"
1822         echo $Line
1823         echo "Test One: Required System Directories."
1824         echo "If one of these system directories is missing, $SCRIPT_NAME cannot operate:"
1825         echo 
1826         check_recommends_items 'required-dirs'
1827         echo "Test Two: Required Core Applications."
1828         echo "If one of these applications is missing, $SCRIPT_NAME cannot operate:"
1829         echo 
1830         check_recommends_items 'required-apps'
1831         echo 'Test Three: Script Recommends for Graphics Features. If you do not use X these do not matter.'
1832         echo "If one of these applications is missing, $SCRIPT_NAME will have incomplete output:"
1833         echo 
1834         check_recommends_items 'recommended-x-apps'
1835         echo 'Test Four: Script Recommends for Remaining Features.' 
1836         echo "If one of these applications is missing, $SCRIPT_NAME will have incomplete output:"
1837         echo 
1838         check_recommends_items 'recommended-apps'
1839         echo 'Test Five: System Directories for Various Information.' 
1840         echo "If one of these directories is missing, $SCRIPT_NAME will have incomplete output:"
1841         echo 
1842         check_recommends_items 'system-dirs'
1843         echo 'All tests completed.' 
1844 }
1845 # args: $1 - check item
1846 check_recommends_items()
1847 {
1848         local item='' item_list='' item_string='' missing_items='' missing_string=''
1849         local package='' application='' feature='' type='' starter='' finisher=''
1850         local package_deb='' package_pacman='' package_rpm='' 
1851         local print_string='' separator=''
1852         local required_dirs='/proc /sys'
1853         # package-owner: 1 - debian/ubuntu; 2 - arch; 3 - yum/rpm
1854         # pardus: pisi sf -q /usr/bin/package
1855         local required_apps='
1856         df:coreutils~coreutils~coreutils~:partition_data 
1857         gawk:gawk~gawk~gawk~:core_tool
1858         grep:grep~grep~grep~:string_search 
1859         lspci:pciutils~pciutils~pciutils~:hardware_data 
1860         ps:procps~procps~procps~:process_data 
1861         readlink:coreutils~coreutils~coreutils~: 
1862         sed:sed~sed~sed~:string_replace 
1863         tr:coreutils~coreutils~coreutils~:character_replace 
1864         uname:uname~coreutils~coreutils~:kernel_data 
1865         uptime:procps~procps~procps~: 
1866         wc:coreutils~coreutils~coreutils~:word_character_count
1867         '
1868         local x_recommends='
1869         glxinfo:mesa-utils~mesa-demos~glx-utils_(openSUSE_12.3_and_later_Mesa-demo-x)~:-G_glx_info 
1870         xdpyinfo:X11-utils~xorg-xdpyinfo~xorg-x11-utils~:-G_multi_screen_resolution 
1871         xprop:X11-utils~xorg-xprop~x11-utils~:-S_desktop_data 
1872         xrandr:x11-xserver-utils~xrandr~x11-server-utils~:-G_single_screen_resolution
1873         '
1874         local recommended_apps='
1875         dmidecode:dmidecode~dmidecode~dmidecode~:-M_if_no_sys_machine_data 
1876         file:file~file~file~:-o_unmounted_file_system
1877         hddtemp:hddtemp~hddtemp~hddtemp~:-Dx_show_hdd_temp 
1878         ifconfig:net-tools~net-tools~net-tools~:-i_ip_lan-deprecated
1879         ip:iproute~iproute2~iproute~:-i_ip_lan
1880         sensors:lm-sensors~lm_sensors~lm-sensors~:-s_sensors_output
1881         strings:binutils~~~:-I_sysvinit_version
1882         lsusb:usbutils~usbutils~usbutils~:-A_usb_audio;-N_usb_networking 
1883         modinfo:module-init-tools~module-init-tools~module-init-tools~:-Ax,-Nx_module_version 
1884         runlevel:sysvinit~sysvinit~systemd~:-I_runlevel
1885         sudo:sudo~sudo~sudo~:-Dx_hddtemp-user;-o_file-user
1886         '
1887         local recommended_dirs='
1888         /sys/class/dmi/id:-M_system,_motherboard,_bios
1889         /dev:-l,-u,-o,-p,-P,-D_disk_partition_data
1890         /dev/disk/by-label:-l,-o,-p,-P_partition_labels
1891         /dev/disk/by-uuid:-u,-o,-p,-P_partition_uuid
1892         /var/run/dmesg.boot:-C,-f_(BSD_only)
1893         '
1894         
1895         case $1 in
1896                 required-dirs)
1897                         item_list=$required_dirs
1898                         item_string='Required file system'
1899                         missing_string='system directories'
1900                         type='directories'
1901                         ;;
1902                 required-apps)
1903                         item_list=$required_apps
1904                         item_string='Required application'
1905                         missing_string='applications, and their corresponding packages,'
1906                         type='applications'
1907                         ;;
1908                 recommended-x-apps)
1909                         item_list=$x_recommends
1910                         item_string='Recommended X application'
1911                         missing_string='applications, and their corresponding packages,'
1912                         type='applications'
1913                         ;;
1914                 recommended-apps)
1915                         item_list=$recommended_apps
1916                         item_string='Recommended application'
1917                         missing_string='applications, and their corresponding packages,'
1918                         type='applications'
1919                         ;;
1920                 system-dirs)
1921                         item_list=$recommended_dirs
1922                         item_string='System directory'
1923                         missing_string='system directories'
1924                         type='directories'
1925                         ;;
1926         esac
1927         # great trick from: http://ideatrash.net/2011/01/bash-string-padding-with-sed.html
1928         # left pad: sed -e :a -e 's/^.\{1,80\}$/& /;ta'
1929         # right pad: sed -e :a -e 's/^.\{1,80\}$/ &/;ta'
1930         # center pad: sed -e :a -e 's/^.\{1,80\}$/ & /;ta'
1931         
1932         for item in $item_list
1933         do
1934                 if [[ $( awk -F ":" '{print NF-1}' <<< $item ) -eq 0 ]];then
1935                         application=$item
1936                         package=''
1937                         feature=''
1938                         location=''
1939                 elif [[ $( awk -F ":" '{print NF-1}' <<< $item ) -eq 1 ]];then
1940                         application=$( cut -d ':' -f 1 <<< $item )
1941                         package=''
1942                         feature=$( cut -d ':' -f 2 <<< $item )
1943                         location=''
1944                 else
1945                         application=$( cut -d ':' -f 1 <<< $item )
1946                         package=$( cut -d ':' -f 2 <<< $item )
1947                         location=$( type -p $application )
1948                         if [[ $( awk -F ":" '{print NF-1}' <<< $item ) -eq 2 ]];then
1949                                 feature=$( cut -d ':' -f 3 <<< $item )
1950                         else
1951                                 feature=''
1952                         fi
1953                 fi
1954                 if [[ -n $feature ]];then
1955                         print_string="$item_string: $application (info: $( sed 's/_/ /g' <<< $feature ))"
1956                 else
1957                         print_string="$item_string: $application"
1958                 fi
1959                 
1960                 starter="$( sed -e :a -e 's/^.\{1,75\}$/&./;ta' <<< $print_string )"
1961                 if [[ -z $( grep '^/' <<< $application ) && -n $location ]] || [[ -d $application ]];then
1962                         if [[ -n $location ]];then
1963                                 finisher=" $location"
1964                         else
1965                                 finisher=" Present"
1966                         fi
1967                 else
1968                         finisher=" Missing"
1969                         missing_items="$missing_items$separator$application:$package"
1970                         separator=' '
1971                 fi
1972                 
1973                 echo "$starter$finisher"
1974         done
1975         echo 
1976         if [[ -n $missing_items ]];then
1977                 echo "The following $type are missing from your system:"
1978                 for item in $missing_items
1979                 do
1980                         application=$( cut -d ':' -f 1 <<< $item )
1981                         if [[ $type == 'applications' ]];then
1982                                 # echo '--------------------------------------------------------'
1983                                 echo
1984                                 package=$( cut -d ':' -f 2 <<< $item )
1985                                 package_deb=$( cut -d '~' -f 1 <<< $package )
1986                                 package_pacman=$( cut -d '~' -f 2 <<< $package )
1987                                 package_rpm=$( cut -d '~' -f 3 <<< $package )
1988                                 echo "Application: $application"
1989                                 echo "To add to your system, install the proper distribution package for your system:"
1990                                 echo "Debian/Ubuntu: $package_deb :: Arch Linux: $package_pacman :: Redhat/Fedora/Suse: $package_rpm"
1991                         else
1992                                 echo "Directory: $application"
1993                         fi
1994                 done
1995                 if [[ $item_string == 'System directory' ]];then
1996                         echo "These directories are created by the kernel, so don't worry if they are not present."
1997                 fi
1998         else
1999                 echo "All the $( cut -d ' ' -f 1 <<< $item_string | sed -e 's/Re/re/' -e 's/Sy/sy/' ) $type are present."
2000         fi
2001         echo $Line
2002 }
2003
2004 #### -------------------------------------------------------------------
2005 #### print / output cleaners
2006 #### -------------------------------------------------------------------
2007
2008 # inxi speaks through here. When run by Konversation script alias mode, uses DCOP
2009 # for dcop to work, must use 'say' operator, AND colors must be evaluated by echo -e
2010 # note: dcop does not seem able to handle \n so that's being stripped out and replaced with space.
2011 print_screen_output()
2012 {
2013         eval $LOGFS
2014         # the double quotes are needed to avoid losing whitespace in data when certain output types are used
2015         # trim off whitespace at end
2016         local print_data="$( echo -e "$1" )" 
2017
2018         # just using basic debugger stuff so you can tell which thing is printing out the data. This
2019         # should help debug kde 4 konvi issues when that is released into sid, we'll see. Turning off
2020         # the redundant debugger output which as far as I can tell does exactly nothing to help debugging.
2021         if [[ $DEBUG -gt 5 ]];then
2022                 if [[ $KONVI -eq 1 ]];then
2023                         # konvi doesn't seem to like \n characters, it just prints them literally
2024                         # print_data="$( tr '\n' ' ' <<< "$print_data" )"
2025                         # dcop "$DCPORT" "$DCOPOBJ" say "$DCSERVER" "$DCTARGET" "konvi='$KONVI' saying : '$print_data'"
2026                         print_data="KP-$KONVI: $print_data"
2027                 elif [[ $KONVI -eq 2 ]];then
2028                         # echo "konvi='$KONVI' saying : '$print_data'"
2029                         print_data="KP-$KONVI: $print_data"
2030                 else
2031                         # echo "printing out: '$print_data'"
2032                         print_data="P: $print_data"
2033                 fi
2034         fi
2035
2036         if [[ $KONVI -eq 1 && $B_DCOP == 'true' ]]; then ## dcop Konversation (<= 1.1 (qt3))
2037                 # konvi doesn't seem to like \n characters, it just prints them literally
2038                 $print_data="$( tr '\n' ' ' <<< "$print_data" )"
2039                 dcop "$DCPORT" "$DCOPOBJ" say "$DCSERVER" "$DCTARGET" "$print_data"
2040
2041         elif [[ $KONVI -eq 3 && $B_QDBUS == 'true' ]]; then ## dbus Konversation (> 1.2 (qt4))
2042                 qdbus org.kde.konversation /irc say "$DCSERVER" "$DCTARGET" "$print_data"
2043
2044 #       elif [[ $IRC_CLIENT == 'X-Chat' ]]; then
2045 #               qdbus org.xchat.service print "$print_data\n"
2046
2047         else
2048                 # the -n is needed to avoid double spacing of output in terminal
2049                 echo -ne "$print_data\n"
2050         fi
2051         eval $LOGFE
2052 }
2053
2054 ## this handles all verbose line construction with indentation/line starter
2055 ## args: $1 - null (, actually: " ") or line starter; $2 - line content
2056 create_print_line()
2057 {
2058         eval $LOGFS
2059         local line=$2
2060         printf "${C1}%-${INDENT}s${C2} %s" "$1" "$line"
2061         eval $LOGFE
2062 }
2063
2064 # this removes newline and pipes.
2065 # args: $1 - string to clean
2066 remove_erroneous_chars()
2067 {
2068         eval $LOGFS
2069         ## RS is input record separator
2070         ## gsub is substitute;
2071         gawk '
2072         BEGIN {
2073                 RS=""
2074         }
2075         {
2076                 gsub(/\n$/,"")         ## (newline; end of string) with (nothing)
2077                 gsub(/\n/," ");        ## (newline) with (space)
2078                 gsub(/^ *| *$/, "")    ## (pipe char) with (nothing)
2079                 gsub(/  +/, " ")       ## ( +) with (space)
2080                 gsub(/ [ ]+/, " ")     ## ([ ]+) with (space)
2081                 gsub(/^ +| +$/, "")    ## (pipe char) with (nothing)
2082                 printf $0
2083         }' "$1"      ## prints (returns) cleaned input
2084         eval $LOGFE
2085 }
2086
2087 #### -------------------------------------------------------------------
2088 #### parameter handling, print usage functions.
2089 #### -------------------------------------------------------------------
2090
2091 # Get the parameters. Note: standard options should be lower case, advanced or testing, upper
2092 # args: $1 - full script startup args: $@
2093 get_parameters()
2094 {
2095         eval $LOGFS
2096         local opt='' wget_test='' debug_data_type='' weather_flag='wW:' 
2097         local use_short='true' # this is needed to trigger short output, every v/d/F/line trigger sets this false
2098
2099         # if distro maintainers don't want the weather feature disable it
2100         if [[ $B_ALLOW_WEATHER == 'false' ]];then
2101                 weather_flag=''
2102                 
2103         fi
2104         if [[ $1 == '--version' ]];then
2105                 print_version_info
2106                 exit 0
2107         elif [[ $1 == '--help' ]];then
2108                 show_options
2109                 exit 0
2110         elif [[ $1 == '--recommends' ]];then
2111                 check_recommends_user_output
2112                 exit 0
2113         # the short form only runs if no args output args are used
2114         # no need to run through these if there are no args
2115         # reserved for future use: -g for extra Graphics; -m for extra Machine; -d for extra Disk
2116         elif [[ -n $1 ]];then
2117                 while getopts Abc:CdDfFGhHiIlMnNopPrRsSt:uUv:V${weather_flag}xzZ%@:!: opt
2118                 do
2119                         case $opt in
2120                         A)      B_SHOW_AUDIO='true'
2121                                 use_short='false'
2122                                 ;;
2123                         b)      use_short='false'
2124                                 B_SHOW_BASIC_CPU='true'
2125                                 B_SHOW_BASIC_RAID='true'
2126                                 B_SHOW_DISK_TOTAL='true'
2127                                 B_SHOW_GRAPHICS='true'
2128                                 B_SHOW_INFO='true'
2129                                 B_SHOW_MACHINE='true'
2130                                 B_SHOW_NETWORK='true'
2131                                 B_SHOW_SYSTEM='true'
2132                                 ;;
2133                         c)      if [[ -n $( grep -E '^[0-9][0-9]?$' <<< $OPTARG ) ]];then
2134                                         case $OPTARG in
2135                                                 99)
2136                                                         B_RUN_COLOR_SELECTOR='true'
2137                                                         COLOR_SELECTION='global'
2138                                                         ;;
2139                                                 98)
2140                                                         B_RUN_COLOR_SELECTOR='true'
2141                                                         COLOR_SELECTION='irc-console'
2142                                                         ;;
2143                                                 97)
2144                                                         B_RUN_COLOR_SELECTOR='true'
2145                                                         COLOR_SELECTION='irc-virtual-terminal'
2146                                                         ;;
2147                                                 96)
2148                                                         B_RUN_COLOR_SELECTOR='true'
2149                                                         COLOR_SELECTION='irc'
2150                                                         ;;
2151                                                 95)
2152                                                         B_RUN_COLOR_SELECTOR='true'
2153                                                         COLOR_SELECTION='virtual-terminal'
2154                                                         ;;
2155                                                 94)
2156                                                         B_RUN_COLOR_SELECTOR='true'
2157                                                         COLOR_SELECTION='console'
2158                                                         ;;
2159                                                 *)      
2160                                                         B_COLOR_SCHEME_SET='true'
2161                                                         ## note: not sure about this, you'd think user values should be overridden, but
2162                                                         ## we'll leave this for now
2163                                                         if [[ -z $COLOR_SCHEME ]];then
2164                                                                 set_color_scheme "$OPTARG"
2165                                                         fi
2166                                                         ;;
2167                                         esac
2168                                 else
2169                                         error_handler 3 "$OPTARG"
2170                                 fi
2171                                 ;;
2172                         C)      B_SHOW_CPU='true'
2173                                 use_short='false'
2174                                 ;;
2175                         d)      B_SHOW_DISK='true'
2176                                 B_SHOW_FULL_OPTICAL='true'
2177                                 use_short='false'
2178                                 # error_handler 20 "-d has been replaced by -b"
2179                                 ;;
2180                         D)      B_SHOW_DISK='true'
2181                                 use_short='false'
2182                                 ;;
2183                         f)      B_SHOW_CPU='true'
2184                                 B_CPU_FLAGS_FULL='true'
2185                                 use_short='false'
2186                                 ;;
2187                         F)      # B_EXTRA_DATA='true'
2188                                 B_SHOW_ADVANCED_NETWORK='true'
2189                                 B_SHOW_AUDIO='true'
2190                                 # B_SHOW_BASIC_OPTICAL='true'
2191                                 B_SHOW_CPU='true'
2192                                 B_SHOW_DISK='true'
2193                                 B_SHOW_GRAPHICS='true'
2194                                 B_SHOW_INFO='true'
2195                                 B_SHOW_MACHINE='true'
2196                                 B_SHOW_NETWORK='true'
2197                                 B_SHOW_PARTITIONS='true'
2198                                 B_SHOW_RAID='true'
2199                                 B_SHOW_SENSORS='true'
2200                                 B_SHOW_SYSTEM='true'
2201                                 use_short='false'
2202                                 ;;
2203                         G)      B_SHOW_GRAPHICS='true'
2204                                 use_short='false'
2205                                 ;;
2206                         i)      B_SHOW_IP='true'
2207                                 B_SHOW_NETWORK='true'
2208                                 B_SHOW_ADVANCED_NETWORK='true'
2209                                 use_short='false'
2210                                 ;;
2211                         I)      B_SHOW_INFO='true'
2212                                 use_short='false'
2213                                 ;;
2214                         l)      B_SHOW_LABELS='true'
2215                                 B_SHOW_PARTITIONS='true'
2216                                 use_short='false'
2217                                 ;;
2218                         M)      B_SHOW_MACHINE='true'
2219                                 use_short='false'
2220                                 ;;
2221                         n)      B_SHOW_ADVANCED_NETWORK='true'
2222                                 B_SHOW_NETWORK='true'
2223                                 use_short='false'
2224                                 ;;
2225                         N)      B_SHOW_NETWORK='true'
2226                                 use_short='false'
2227                                 ;;
2228                         o)      B_SHOW_UNMOUNTED_PARTITIONS='true'
2229                                 use_short='false'
2230                                 ;;
2231                         p)      B_SHOW_PARTITIONS_FULL='true'
2232                                 B_SHOW_PARTITIONS='true'
2233                                 use_short='false'
2234                                 ;;
2235                         P)      B_SHOW_PARTITIONS='true'
2236                                 use_short='false'
2237                                 ;;
2238                         r)      B_SHOW_REPOS='true'
2239                                 use_short='false'
2240                                 ;;
2241                         R)      B_SHOW_RAID='true'
2242                                 # it turns out only users with mdraid software installed will have raid,
2243                                 # so unless -R is explicitly called, blank -b/-F/-v6 and less output will not show
2244                                 # error if file is missing.
2245                                 B_SHOW_RAID_R='true'
2246                                 use_short='false'
2247                                 ;;
2248                         s)      B_SHOW_SENSORS='true'
2249                                 use_short='false'
2250                                 ;;
2251                         S)      B_SHOW_SYSTEM='true'
2252                                 use_short='false'
2253                                 ;;
2254                         t)      if [[ -n $( grep -E '^(c|m|cm|mc)([1-9]|1[0-9]|20)?$' <<< $OPTARG ) ]];then
2255                                         use_short='false'
2256                                         if [[ -n $( grep -E '[0-9]+' <<< $OPTARG ) ]];then
2257                                                 PS_COUNT=$( sed 's/[^0-9]//g' <<< $OPTARG )
2258                                         fi
2259                                         if [[ -n $( grep 'c' <<< $OPTARG ) ]];then
2260                                                 B_SHOW_PS_CPU_DATA='true'
2261                                         fi
2262                                         if [[ -n $( grep 'm' <<< $OPTARG ) ]];then
2263                                                 B_SHOW_PS_MEM_DATA='true'
2264                                         fi
2265                                 else
2266                                         error_handler 13 "$OPTARG"
2267                                 fi
2268                                 ;;
2269                         u)      B_SHOW_UUIDS='true'
2270                                 B_SHOW_PARTITIONS='true'
2271                                 use_short='false'
2272                                 ;;
2273                         v)      if [[ -n $( grep -E "^[0-9][0-9]?$" <<< $OPTARG ) && $OPTARG -le $VERBOSITY_LEVELS ]];then
2274                                         if [[ $OPTARG -ge 1 ]];then
2275                                                 use_short='false'
2276                                                 B_SHOW_BASIC_CPU='true'
2277                                                 B_SHOW_DISK_TOTAL='true'
2278                                                 B_SHOW_GRAPHICS='true'
2279                                                 B_SHOW_INFO='true'
2280                                                 B_SHOW_SYSTEM='true'
2281                                         fi
2282                                         if [[ $OPTARG -ge 2 ]];then
2283                                                 B_SHOW_BASIC_DISK='true'
2284                                                 B_SHOW_BASIC_RAID='true'
2285                                                 B_SHOW_MACHINE='true'
2286                                                 B_SHOW_NETWORK='true'
2287                                         fi
2288                                         if [[ $OPTARG -ge 3 ]];then
2289                                                 B_SHOW_ADVANCED_NETWORK='true'
2290                                                 B_SHOW_CPU='true'
2291                                                 B_EXTRA_DATA='true'
2292                                         fi
2293                                         if [[ $OPTARG -ge 4 ]];then
2294                                                 B_SHOW_DISK='true'
2295                                                 B_SHOW_PARTITIONS='true'
2296                                         fi
2297                                         if [[ $OPTARG -ge 5 ]];then
2298                                                 B_SHOW_AUDIO='true'
2299                                                 B_SHOW_BASIC_OPTICAL='true'
2300                                                 B_SHOW_SENSORS='true'
2301                                                 B_SHOW_LABELS='true'
2302                                                 B_SHOW_UUIDS='true'
2303                                                 B_SHOW_RAID='true'
2304                                         fi
2305                                         if [[ $OPTARG -ge 6 ]];then
2306                                                 B_SHOW_FULL_OPTICAL='true'
2307                                                 B_SHOW_PARTITIONS_FULL='true'
2308                                                 B_SHOW_UNMOUNTED_PARTITIONS='true'
2309                                                 B_EXTRA_EXTRA_DATA='true'
2310                                         fi
2311                                         if [[ $OPTARG -ge 7 ]];then
2312                                                 B_EXTRA_EXTRA_EXTRA_DATA='true'
2313                                                 B_SHOW_IP='true'
2314                                                 B_SHOW_RAID_R='true'
2315                                         fi
2316                                 else
2317                                         error_handler 4 "$OPTARG"
2318                                 fi
2319                                 ;;
2320                         U)      if [[ $B_ALLOW_UPDATE == 'true' ]];then
2321                                         script_self_updater "$SCRIPT_DOWNLOAD" 'svn server' "$opt"
2322                                 else
2323                                         error_handler 17 "-$opt"
2324                                 fi
2325                                 ;;
2326                         V)      print_version_info
2327                                 exit 0
2328                                 ;;
2329                         w)      B_SHOW_WEATHER=true
2330                                 use_short='false'
2331                                 ;;
2332                         W)      ALTERNATE_WEATHER_LOCATION=$( sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'  <<< $OPTARG )
2333                                 if [[ -n $( grep -Esi '([^,]+,.+|[0-9-]+)' <<< $ALTERNATE_WEATHER_LOCATION ) ]];then
2334                                         B_SHOW_WEATHER=true
2335                                         use_short='false'
2336                                 else
2337                                         error_handler 18 "-$opt: '$OPTARG'" "city,state OR latitude,longitude OR postal/zip code."
2338                                 fi
2339                                 ;;
2340                         # this will trigger either with x, xx, xxx or with Fx but not with xF
2341                         x)      if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
2342                                         B_EXTRA_EXTRA_EXTRA_DATA='true'
2343                                 elif [[ $B_EXTRA_DATA == 'true' ]];then
2344                                         B_EXTRA_EXTRA_DATA='true'
2345                                 else
2346                                         B_EXTRA_DATA='true'
2347                                 fi
2348                                 ;;
2349                         z)      B_OUTPUT_FILTER='true'
2350                                 ;;
2351                         Z)      B_OVERRIDE_FILTER='true'
2352                                 ;;
2353                         h)      show_options
2354                                 exit 0
2355                                 ;;
2356                         H)      show_options 'full'
2357                                 exit 0
2358                                 ;;
2359                         ## debuggers and testing tools
2360                         %)      B_HANDLE_CORRUPT_DATA='true'
2361                                 ;;
2362                         @)      if [[ -n $( grep -E "^([1-9]|1[0-4])$" <<< $OPTARG ) ]];then
2363                                         DEBUG=$OPTARG
2364                                         if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
2365                                                 B_UPLOAD_DEBUG_DATA='true'
2366                                         fi
2367                                         exec 2>&1
2368                                         # switch on logging only for -@ 8-10
2369                                         case $OPTARG in
2370                                                 8|9|10)
2371                                                         if [[ $OPTARG -eq 10 ]];then
2372                                                                 B_LOG_COLORS='true'
2373                                                         elif [[ $OPTARG -eq 9 ]];then           
2374                                                                 B_LOG_FULL_DATA='true'
2375                                                         fi
2376                                                         B_USE_LOGGING='true'
2377                                                         # pack the logging data for evals function start/end
2378                                                         LOGFS=$LOGFS_STRING
2379                                                         LOGFE=$LOGFE_STRING
2380                                                         create_rotate_logfiles # create/rotate logfiles before we do anything else
2381                                                         ;;
2382                                                 11|12|13|14)
2383                                                         case $OPTARG in
2384                                                                 11)
2385                                                                         debug_data_type='sys'
2386                                                                         ;;
2387                                                                 12)
2388                                                                         debug_data_type='xorg'
2389                                                                         ;;
2390                                                                 13)
2391                                                                         debug_data_type='disk'
2392                                                                         ;;
2393                                                                 14)
2394                                                                         debug_data_type='all'
2395                                                                         ;;
2396                                                         esac
2397                                                         initialize_data
2398                                                         debug_data_collector $debug_data_type
2399                                                         ;;
2400                                         esac
2401                                 else
2402                                         error_handler 9 "$OPTARG"
2403                                 fi
2404                                 ;;
2405                         !)      # test for various supported methods
2406                                 case $OPTARG in
2407                                         1)      B_TESTING_1='true'
2408                                                 ;;
2409                                         2)      B_TESTING_2='true'
2410                                                 ;;
2411                                         3)      B_TESTING_1='true'
2412                                                 B_TESTING_2='true'
2413                                                 ;;
2414                                         1[0-6]|http*)
2415                                                 if [[ $B_ALLOW_UPDATE == 'true' ]];then
2416                                                         case $OPTARG in
2417                                                                 10)
2418                                                                         script_self_updater "$SCRIPT_DOWNLOAD_DEV" 'dev server' "$opt $OPTARG"
2419                                                                         ;;
2420                                                                 11)
2421                                                                         script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_1" 'svn: branch one server' "$opt $OPTARG"
2422                                                                         ;;
2423                                                                 12)
2424                                                                         script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_2" 'svn: branch two server' "$opt $OPTARG"
2425                                                                         ;;
2426                                                                 13)
2427                                                                         script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_3" 'svn: branch three server' "$opt $OPTARG"
2428                                                                         ;;
2429                                                                 14)
2430                                                                         script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_4" 'svn: branch four server' "$opt $OPTARG"
2431                                                                         ;;
2432                                                                 15)
2433                                                                         script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_BSD" 'svn: branch bsd server' "$opt $OPTARG"
2434                                                                         ;;
2435                                                                 16)
2436                                                                         script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_GNUBSD" 'svn: branch gnubsd server' "$opt $OPTARG"
2437                                                                         ;;
2438                                                                 http*)
2439                                                                         script_self_updater "$OPTARG" 'alt server' "$opt <http...>"
2440                                                                         ;;
2441                                                         esac
2442                                                 else
2443                                                         error_handler 17 "-$opt $OPTARG"
2444                                                 fi
2445                                                 ;;
2446                                         30)
2447                                                 B_RUNNING_IN_SHELL='true'
2448                                                 ;;
2449                                         31)
2450                                                 B_SHOW_HOST='false'
2451                                                 ;;
2452                                         32)
2453                                                 B_SHOW_HOST='true'
2454                                                 ;;
2455                                         ftp*)
2456                                                 ALTERNATE_FTP="$OPTARG"
2457                                                 ;;
2458                                         # for weather function, allows user to set an alternate weather location
2459                                         location=*)
2460                                                 error_handler 19 "-$opt location=" "-W"
2461                                                 ;;
2462                                         *)      error_handler 11 "$OPTARG"
2463                                                 ;;
2464                                 esac
2465                                 ;;
2466                         *)      error_handler 7 "$1"
2467                                 ;;
2468                         esac
2469                 done
2470         fi
2471         ## this must occur here so you can use the debugging flag to show errors
2472         ## Reroute all error messages to the bitbucket (if not debugging)
2473         if [[ $DEBUG -eq 0 ]];then
2474                 exec 2>/dev/null
2475         fi
2476         #((DEBUG)) && exec 2>&1 # This is for debugging konversation
2477
2478         # after all the args have been processed, if no long output args used, run short output
2479         if [[ $use_short == 'true' ]];then
2480                 B_SHOW_SHORT_OUTPUT='true'
2481         fi
2482         # just in case someone insists on using -zZ
2483         if [[ $B_OVERRIDE_FILTER == 'true' ]];then
2484                 B_OUTPUT_FILTER='false'
2485         fi
2486         # change basic to full if user requested it or if arg overrides it
2487         if [[ $B_SHOW_RAID == 'true' && $B_SHOW_BASIC_RAID == 'true' ]];then
2488                 B_SHOW_BASIC_RAID='false'
2489         fi
2490         
2491         
2492         eval $LOGFE
2493 }
2494
2495 ## print out help menu, not including Testing or Debugger stuff because it's not needed
2496 show_options()
2497 {
2498         local color_scheme_count=$(( ${#A_COLOR_SCHEMES[@]} - 1 ))
2499         local partition_string='partition' partition_string_u='Partition'
2500         
2501         if [[ $B_RUNNING_IN_SHELL != 'true' ]];then
2502                 print_screen_output "Sorry, you can't run the help option in an IRC client."
2503                 exit 1
2504         fi
2505         if [[ -n $BSD_TYPE ]];then
2506                 partition_string='slice'
2507                 partition_string_u='Slice'
2508         fi
2509         # print_lines_basic "0" "" ""
2510         # print_lines_basic "1" "" ""
2511         # print_lines_basic "2" "" ""
2512         # print_screen_output " "
2513         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."
2514         print_screen_output " "
2515         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."
2516         
2517         print_screen_output "- - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
2518         print_screen_output "Output Control Options:"
2519         print_lines_basic "1" "-A" "Audio/sound card information."
2520         print_lines_basic "1" "-b" "Basic output, short form. Like $SCRIPT_NAME^-v^2, only minus hard disk names."
2521         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."
2522         print_lines_basic "1" "" "Supported color schemes: 0-$color_scheme_count Example: $SCRIPT_NAME^-c^11"
2523         print_lines_basic "1" "" "Color selectors for each type display (NOTE: irc and global only show safe color set):"
2524 #       print_screen_output "    Supported color schemes: 0-$color_scheme_count Example: $SCRIPT_NAME -c 11"
2525 #       print_screen_output "    Color selectors for each type display (NOTE: irc and global only show safe color set):"
2526         print_lines_basic "2" "94" "Console, out of X"
2527         print_lines_basic "2" "95" "Terminal, running in X - like xTerm"
2528         print_lines_basic "2" "96" "Gui IRC, running in X - like Xchat, Quassel, Konversation etc."
2529         print_lines_basic "2" "97" "Console IRC running in X - like irssi in xTerm"
2530         print_lines_basic "2" "98" "Console IRC not in  X"
2531         print_lines_basic "2" "99" "Global - Overrides/removes all settings. Setting specific removes global."
2532         print_lines_basic "1" "-C" "CPU output, including per CPU clockspeed (if available)."
2533         print_lines_basic "1" "-d" "Optical drive data. Same as -Dd. See also -x and -xx."
2534         print_lines_basic "1" "-D" "Full hard Disk info, not only model, ie: /dev/sda ST380817AS 80.0GB. See also -x and -xx."
2535         print_lines_basic "1" "-f" "All cpu flags, triggers -C. Not shown with -F to avoid spamming. ARM cpus show 'features'."
2536         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"
2537         print_lines_basic "1" "-G" "Graphic card information (card, display server type/version, resolution, glx renderer, version)."
2538         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."
2539         print_lines_basic "1" "-I" "Information: processes, uptime, memory, irc client (or shell type), $SCRIPT_NAME version."
2540         print_lines_basic "1" "-l" "${partition_string_u} labels. Default: short ${partition_string} -P. For full -p output, use: -pl (or -plu)."
2541         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."
2542         print_lines_basic "1" "-n" "Advanced Network card information. Same as -Nn. Shows interface, speed, mac id, state, etc."
2543         print_lines_basic "1" "-N" "Network card information. With -x, shows PCI BusID, Port number."
2544         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^"
2545         print_lines_basic "1" "-p" "Full ${partition_string} information (-P plus all other detected ${partition_string}s)."
2546         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."
2547         print_lines_basic "1" "-r" "Distro repository data. Supported repo types: APT; PACMAN; PISI; YUM; URPMQ; Ports."
2548         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."
2549         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."
2550         print_lines_basic "1" "-S" "System information: host name, kernel, desktop environment (if in X), distro"
2551         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"
2552         print_lines_basic "1" "" "Make sure to have no space between letters and numbers (-t^cm10 - right, -t^cm^10 - wrong)."
2553         print_lines_basic "1" "-u" "${partition_string_u} UUIDs. Default: short ${partition_string} -P. For full -p output, use: -pu (or -plu)."
2554         print_lines_basic "1" "-v" "Script verbosity levels. Verbosity level number is required. Should not be used with -b or -F"
2555         print_lines_basic "1" "" "Supported levels: 0-${VERBOSITY_LEVELS} Example: $SCRIPT_NAME^-v^4"
2556         print_lines_basic "2" "0" "Short output, same as: $SCRIPT_NAME"
2557         print_lines_basic "2" "1" "Basic verbose, -S + basic CPU + -G + basic Disk + -I."
2558         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"
2559         print_lines_basic "2" "3" "Advanced CPU (-C), network (-n) data, and switches on -x advanced data option."
2560         print_lines_basic "2" "4" "${partition_string_u} size/filled data (-P) for (if present):/, /home, /var/, /boot. Shows full disk data (-D)."
2561         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)."
2562         print_lines_basic "2" "6" "Full ${partition_string} (-p), unmounted ${partition_string} (-o), optical drive (-d), full raid; triggers -xx."
2563         print_lines_basic "2" "7" "Network IP data (-i); triggers -xxx."
2564         
2565         # if distro maintainers don't want the weather feature disable it
2566         if [[ $B_ALLOW_WEATHER == 'true' ]];then
2567                 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."
2568                 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"
2569         fi
2570         print_lines_basic "1" "-x" "Adds the following extra data (only works with verbose or line output, not short form):"
2571         print_lines_basic "2" "-C" "CPU Flags, Bogomips on Cpu;"
2572         print_lines_basic "2" "-d" "Extra optical drive data; adds rev version to optical drive."
2573         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"
2574         print_lines_basic "2" "-G" "Direct rendering status for Graphics (in X)."
2575         print_lines_basic "2" "-G" "(for single gpu, nvidia driver) screen number gpu is running on."
2576         print_lines_basic "2" "-i" "IPv6 as well for LAN interface (IF) devices."
2577         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)."
2578         print_lines_basic "2" "-N -A" "Version/port(s)/driver version (if available) for Network/Audio;"
2579         print_lines_basic "2" "-N -A -G" "Network, audio, graphics, shows PCI Bus ID/Usb ID number of card."
2580         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"
2581         print_lines_basic "2" "-S" "Desktop toolkit if avaliable (GNOME/XFCE/KDE only); Kernel gcc version"
2582         print_lines_basic "2" "-t" "Memory use output to cpu (-xt c), and cpu use to memory (-xt m)."
2583         if [[ $B_ALLOW_WEATHER == 'true' ]];then
2584                 print_lines_basic "2" "-w -W" "Wind speed and time zone (-w only)."
2585         fi
2586         print_lines_basic "1" "-xx" "Show extra, extra data (only works with verbose or line output, not short form):"
2587         print_lines_basic "2" "-A" "Chip vendor:product ID for each audio device."
2588         print_lines_basic "2" "-D" "Disk serial number."
2589         print_lines_basic "2" "-G" "Chip vendor:product ID for each video card."
2590         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."
2591         print_lines_basic "2" "-M" "Chassis information, bios rom size (dmidecode only), if data for either is available."
2592         print_lines_basic "2" "-N" "Chip vendor:product ID for each nic."
2593         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."
2594         print_lines_basic "2" "-S" "Display manager (dm) in desktop output, if in X (like kdm, gdm3, lightdm)."
2595         if [[ $B_ALLOW_WEATHER == 'true' ]];then
2596                 print_lines_basic "2" "-w -W" "Humidity, barometric pressure."
2597         fi
2598         print_lines_basic "2" "-@ 11-14" "Automatically uploads debugger data tar.gz file to ftp.techpatterns.com. EG: $SCRIPT_NAME^-xx@14"
2599         print_lines_basic "1" "-xxx" "Show extra, extra, extra data (only works with verbose or line output, not short form):"
2600         print_lines_basic "2" "-S" "Panel/shell information in desktop output, if in X (like gnome-shell, cinnamon, mate-panel)."
2601         if [[ $B_ALLOW_WEATHER == 'true' ]];then
2602                 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)."
2603         fi
2604         print_lines_basic "1" "-z" "Security filters for IP/Mac addresses, location, user home directory name. Default on for irc clients."
2605         print_lines_basic "1" "-Z" "Absolute override for output filters. Useful for debugging networking issues in irc for example."
2606         print_screen_output " "
2607         print_screen_output "Additional Options:"
2608         print_lines_basic "4" "-h --help" "This help menu."
2609         print_lines_basic "4" "-H" "This help menu, plus developer options. Do not use dev options in normal operation!"
2610         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. "
2611         if [[ $B_ALLOW_UPDATE == 'true' ]];then
2612                 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."
2613         fi
2614         print_lines_basic "4" "-V --version" "$SCRIPT_NAME version information. Prints information then exits."
2615         print_screen_output " "
2616         print_screen_output "Debugging Options:"
2617         print_lines_basic "1" "-%" "Overrides defective or corrupted data."
2618         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."
2619         print_lines_basic "2" "1-7" "On screen debugger output"
2620         print_lines_basic "2" "8" "Basic logging"
2621         print_lines_basic "2" "9" "Full file/sys info logging"
2622         print_lines_basic "2" "10" "Color logging."
2623         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>"
2624         print_lines_basic "1" "" "For alternate ftp upload locations: Example: inxi^-!^ftp.yourserver.com/incoming^-xx@^14"
2625         print_lines_basic "2" "11" "With data file of xiin read of /sys."
2626         print_lines_basic "2" "12" "With xorg conf and log data, xrandr, xprop, xdpyinfo, glxinfo etc."
2627         print_lines_basic "2" "13" "With data from dev, disks, ${partition_string}s, etc., plus xiin data file."
2628         print_lines_basic "2" "14" "Everything, full data collection."
2629         print_screen_output " "
2630         print_screen_output "Advanced Options:"
2631         print_lines_basic "1" "-! 31" "Turns off hostname in output. Useful if showing output from servers etc."
2632         print_lines_basic "1" "-! 32" "Turns on hostname in output. Overrides global B_SHOW_HOST='false'"
2633         
2634         if [[ $1 == 'full' ]];then
2635                 print_screen_output " "
2636                 print_screen_output "Developer and Testing Options (Advanced):"
2637                 print_lines_basic "1" "-! 1" "Sets testing flag B_TESTING_1='true' to trigger testing condition 1."
2638                 print_lines_basic "1" "-! 2" "Sets testing flag B_TESTING_2='true' to trigger testing condition 2."
2639                 print_lines_basic "1" "-! 3" "Sets flags B_TESTING_1='true' and B_TESTING_2='true'."
2640                 if [[ $B_ALLOW_UPDATE == 'true' ]];then
2641                         print_lines_basic "1" "-! 10" "Triggers an update from the primary dev download server instead of svn."
2642                         print_lines_basic "1" "-! 11" "Triggers an update from svn branch one - if present, of course."
2643                         print_lines_basic "1" "-! 12" "Triggers an update from svn branch two - if present, of course."
2644                         print_lines_basic "1" "-! 13" "Triggers an update from svn branch three - if present, of course."
2645                         print_lines_basic "1" "-! 14" "Triggers an update from svn branch four - if present, of course."
2646                         print_lines_basic "1" "-! 15" "Triggers an update from svn branch BSD - if present, of course."
2647                         print_lines_basic "1" "-! 16" "Triggers an update from svn branch GNUBSD - if present, of course."
2648                         print_lines_basic "1" "-! <http://......>" "Triggers an update from whatever server you list."
2649                 fi
2650                 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. "
2651                 print_lines_basic "1" "" "Example: inxi^-!^ftp.yourserver.com/incoming^-xx@^14"
2652         fi
2653         print_screen_output " "
2654 }
2655
2656 # uses $TERM_COLUMNS to set width using $COLS_MAX as max width
2657 # IMPORTANT: minimize use of subshells here or the output is too slow
2658 # args: $1 - 0 1 2 3 4 for indentation level; $2 -line starter, like -m; $3 - content of block.
2659 print_lines_basic()
2660 {
2661         local line_width=$COLS_MAX
2662         local print_string='' indent_inner='' indent_full='' indent_x='' 
2663         local indent_working='' indent_working_full=''
2664         local line_starter='' line_1_starter='' line_x_starter='' 
2665         # note: to create a padded string below
2666         local fake_string=' ' temp_count='' line_count='' spacer=''
2667         local indent_main=6 indent_x='' b_indent_x='true' 
2668         
2669         case $1 in
2670                 # for no options, start at left edge
2671                 0)      indent_full=0
2672                         line_1_starter=''
2673                         line_x_starter=''
2674                         b_indent_x='false'
2675                         ;;
2676                 1)      indent_full=$indent_main
2677                         temp_count=${#2}
2678                         if [[ $temp_count -le $indent_full ]];then
2679                                 indent_working=$indent_full
2680                         else
2681                                 indent_working=$temp_count #$(( $temp_count + 1 ))
2682                         fi
2683                         line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_working\}$/& /;ta" <<< $2 )"
2684                         ;;
2685                 # first left pad 2 and 3, then right pad them
2686                 2)      indent_full=$(( $indent_main + 6 ))
2687                         indent_inner=3
2688                         temp_count=${#2}
2689                         if [[ $temp_count -le $indent_inner ]];then
2690                                 indent_working=$indent_inner
2691                                 #indent_working_full=$indent_full
2692                         else
2693                                 indent_working=$(( $temp_count + 1 ))
2694                                 #indent_working_full=$(( $indent_full - $indent_inner - 1 ))
2695                         fi
2696                         line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_working\}$/& /;ta" <<< $2 )"
2697                         line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_full\}$/ &/;ta" <<< "$line_1_starter" )"
2698                         ;;
2699                 3)      indent_full=$(( $indent_main + 8 ))
2700                         indent_inner=3
2701                         temp_count=${#2}
2702                         if [[ $temp_count -le $indent_inner ]];then
2703                                 indent_working=$indent_inner
2704                         else
2705                                 indent_working=$(( $temp_count + 1 ))
2706                         fi
2707                         line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_working\}$/& /;ta" <<< $2 )"
2708                         line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_full\}$/ &/;ta" <<< "$line_1_starter" )"
2709                         ;;
2710                 # for long options
2711                 4)      indent_full=$(( $indent_main + 8 ))
2712                         temp_count=${#2}
2713                         if [[ $temp_count -lt $indent_full ]];then
2714                                 indent_working=$indent_full
2715                         else
2716                                 indent_working=$temp_count #$(( $temp_count + 1 ))
2717                         fi
2718                         line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_working\}$/& /;ta" <<< $2 )"
2719                         ;;
2720         esac
2721         
2722         if [[ $b_indent_x == 'true' ]];then
2723                 indent_x=$(( $indent_full + 1 ))
2724                 line_x_starter="$(printf "%${indent_x}s" '')"
2725         fi
2726         
2727         line_count=$(( $line_width - $indent_full ))
2728         
2729         # bash loop is slow, only run this if required
2730         if [[ ${#3} -gt $line_count ]];then
2731                 for word in $3
2732                 do
2733                         temp_string="$print_string$spacer$word"
2734                         spacer=' '
2735                         if [[ ${#temp_string} -lt $line_count ]];then
2736                                 print_string=$temp_string # lose any white space start/end
2737                                 # echo -n $(( $line_width - $indent_full ))
2738                         else
2739                                 if [[ -n $line_1_starter ]];then
2740                                         line_starter="$line_1_starter"
2741                                         line_1_starter=''
2742                                 else
2743                                         line_starter="$line_x_starter"
2744                                 fi
2745                                 # clean up forced connections, ie, stuff we don't want wrapping
2746                                 print_string=${print_string//\^/ }
2747                                 print_screen_output "$line_starter$print_string"
2748                                 print_string="$word$spacer" # needed to handle second word on new line
2749                                 temp_string=''
2750                                 spacer=''
2751                         fi
2752                 done
2753         else
2754                 # echo no loop
2755                 print_string=$3
2756         fi
2757         # print anything left over
2758         if [[ -n $print_string ]];then
2759                 if [[ -n $line_1_starter ]];then
2760                         line_starter="$line_1_starter"
2761                         line_1_starter=''
2762                 else
2763                         line_starter="$line_x_starter"
2764                 fi
2765                 print_string=${print_string//\^/ }
2766                 print_screen_output "$line_starter$print_string"
2767         fi
2768 }
2769 # 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'
2770 # 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'
2771 # print_lines_basic '2' '12' 'and its sss substring'
2772 # 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'
2773 # exit
2774
2775 ## print out version information for -V/--version
2776 print_version_info()
2777 {
2778         # if not in PATH could be either . or directory name, no slash starting
2779         local script_path=$SCRIPT_PATH script_symbolic_start=''
2780         if [[ $script_path == '.' ]];then
2781                 script_path=$( pwd )
2782         elif [[ -z $( grep '^/' <<< "$script_path" ) ]];then
2783                 script_path="$( pwd )/$script_path"
2784         fi
2785         # handle if it's a symbolic link, rare, but can happen with script directories in irc clients
2786         # which would only matter if user starts inxi with -! 30 override in irc client
2787         if [[ -L $script_path/$SCRIPT_NAME ]];then
2788                 script_symbolic_start=$script_path/$SCRIPT_NAME
2789                 script_path=$( readlink $script_path/$SCRIPT_NAME )
2790                 script_path=$( dirname $script_path )
2791         fi
2792         local last_modified=$( parse_version_data 'date' ) 
2793         local year_modified=$( gawk '{print $NF}' <<< "$last_modified" )
2794         
2795         print_screen_output "$SCRIPT_NAME $SCRIPT_VERSION_NUMBER-$SCRIPT_PATCH_NUMBER ($last_modified)"
2796         if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
2797                 print_screen_output "Program Location: $script_path"
2798                 if [[ -n $script_symbolic_start ]];then
2799                         print_screen_output "Started via symbolic link: $script_symbolic_start"
2800                 fi
2801                 print_lines_basic "0" "" "Website:^http://inxi.goooglecode.com"
2802                 print_lines_basic "0" "" "IRC:^irc.oftc.net channel:^#smxi"
2803                 print_lines_basic "0" "" "Forums:^http://techpatterns.com/forums/forum-33.html"
2804                 print_screen_output " "
2805                 print_lines_basic "0" "" "$SCRIPT_NAME - the universal, portable, system information tool for console and irc."
2806                 print_screen_output " "
2807                 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."
2808                 print_lines_basic "0" "" "Subsequent changes and modifications (after Infobash 3.02): Copyright (C) 2008-$year_modified Scott Rogers, Harald Hope, aka trash80 & h2"
2809                 print_screen_output " "
2810                 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)"
2811         fi
2812 }
2813
2814 ########################################################################
2815 #### MAIN FUNCTIONS
2816 ########################################################################
2817
2818 #### -------------------------------------------------------------------
2819 #### initial startup stuff
2820 #### -------------------------------------------------------------------
2821
2822 # Determine where inxi was run from, set IRC_CLIENT and IRC_CLIENT_VERSION
2823 get_start_client()
2824 {
2825         eval $LOGFS
2826         local Irc_Client_Path='' irc_client_path_lower='' non_native_konvi='' i=''
2827         local B_Non_Native_App='false' pppid='' App_Working_Name=''
2828         local b_qt4_konvi='false' ps_parent=''
2829
2830         if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
2831                 IRC_CLIENT='Shell'
2832                 unset IRC_CLIENT_VERSION
2833         # elif [[ -n $PPID ]];then
2834         elif [[ -n $PPID && -f /proc/$PPID/exe ]];then
2835                 if [[ $B_OVERRIDE_FILTER != 'true' ]];then
2836                         B_OUTPUT_FILTER='true'
2837                 fi
2838                 Irc_Client_Path=$( readlink /proc/$PPID/exe )
2839                 # Irc_Client_Path=$( ps -p $PPID | gawk '!/[[:space:]]*PID/ {print $5}'  )
2840                 # echo $( ps -p $PPID )
2841                 irc_client_path_lower=$( tr '[:upper:]' '[:lower:]' <<< $Irc_Client_Path )
2842                 App_Working_Name=$( basename $irc_client_path_lower )
2843                 # handles the xchat/sh/bash/dash cases, and the konversation/perl cases, where clients
2844                 # report themselves as perl or unknown shell. IE:  when konversation starts inxi
2845                 # from inside itself, as a script, the parent is konversation/xchat, not perl/bash etc
2846                 # note: perl can report as: perl5.10.0, so it needs wildcard handling
2847                 case $App_Working_Name in
2848                         # bsd will never use this section
2849                         bash|dash|sh|python*|perl*)     # We want to know who wrapped it into the shell or perl.
2850                                 pppid="$( ps -p $PPID -o ppid --no-headers | sed 's/[[:space:]]//g' )"
2851                                 if [[ -n $pppid && -f /proc/$pppid/exe ]];then
2852                                         Irc_Client_Path="$( readlink /proc/$pppid/exe )"
2853                                         irc_client_path_lower="$( tr '[:upper:]' '[:lower:]' <<< $Irc_Client_Path )"
2854                                         App_Working_Name=$( basename $irc_client_path_lower )
2855                                         B_Non_Native_App='true'
2856                                 fi
2857                                 ;;
2858                 esac
2859                 # sets version number if it can find it
2860                 get_irc_client_version
2861         else
2862                 ## lets look to see if qt4_konvi is the parent.  There is no direct way to tell, so lets infer it.
2863                 ## because $PPID does not work with qt4_konvi, the above case does not work
2864                 if [[ $B_OVERRIDE_FILTER != 'true' ]];then
2865                         B_OUTPUT_FILTER='true'
2866                 fi
2867                 b_qt4_konvi=$( is_this_qt4_konvi )
2868                 if [[ $b_qt4_konvi == 'true' ]];then
2869                         KONVI=3
2870                         IRC_CLIENT='Konversation'
2871                         IRC_CLIENT_VERSION=" $( konversation -v | gawk '
2872                                 /Konversation:/ {
2873                                         for ( i=2; i<=NF; i++ ) {
2874                                                 if (i == NF) {
2875                                                         print $i
2876                                                 }
2877                                                 else {
2878                                                         printf $i" "
2879                                                 }
2880                                         }
2881                                         exit
2882                                 }' )"
2883                 else
2884                         # this should handle certain cases where it's ssh or some other startup tool
2885                         # that falls through all the other tests
2886                         if [[ $BSD_TYPE != 'bsd' ]];then
2887                                 App_Working_Name=$(ps -p $PPID --no-headers 2>/dev/null | gawk '{print $NF}' )
2888                         else
2889                                 # without --no-headers we need the second line
2890                                 App_Working_Name=$(ps -p $PPID 2>/dev/null | gawk '/^[0-9]+/ {print $5}' )
2891                         fi
2892                         
2893                         if [[ -n $App_Working_Name ]];then
2894                                 Irc_Client_Path=$App_Working_Name
2895                                 B_Non_Native_App='false'
2896                                 get_irc_client_version
2897                                 if [[ -z $IRC_CLIENT ]];then
2898                                         IRC_CLIENT=$App_Working_Name
2899                                 fi
2900                         else
2901                                 IRC_CLIENT="PPID=\"$PPID\" - empty?"
2902                                 unset IRC_CLIENT_VERSION
2903                         fi
2904                 fi
2905         fi
2906
2907         log_function_data "IRC_CLIENT: $IRC_CLIENT :: IRC_CLIENT_VERSION: $IRC_CLIENT_VERSION :: PPID: $PPID"
2908         eval $LOGFE
2909 }
2910 # note: all variables set in caller so no need to pass
2911 get_irc_client_version()
2912 {
2913         local file_data=''
2914         # replacing loose detection with tight detection, bugs will be handled with app names
2915         # as they appear.
2916         case $App_Working_Name in
2917                 # check for shell first
2918                 bash|dash|sh)
2919                         unset IRC_CLIENT_VERSION
2920                         IRC_CLIENT="Shell wrapper"
2921                         ;;
2922                 # now start on irc clients, alphabetically
2923                 bitchx)
2924                         IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk '
2925                         /Version/ {
2926                                 a=tolower($2)
2927                                 gsub(/[()]|bitchx-/,"",a)
2928                                 print a
2929                                 exit
2930                         }
2931                         $2 == "version" {
2932                                 a=tolower($3)
2933                                 sub(/bitchx-/,"",a)
2934                                 print a
2935                                 exit
2936                         }' )"
2937                         B_CONSOLE_IRC='true'
2938                         IRC_CLIENT="BitchX"
2939                         ;;
2940                 finch)
2941                         IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
2942                                 print $2
2943                         }' )"
2944                         B_CONSOLE_IRC='true'
2945                         IRC_CLIENT="Finch"
2946                         ;;
2947                 gaim)
2948                         IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
2949                                 print $2
2950                         }' )"
2951                         IRC_CLIENT="Gaim"
2952                         ;;
2953                 hexchat)
2954                         # the hexchat author decided to make --version/-v return a gtk dialogue box, lol...
2955                         # so we need to read the actual config file for hexchat. Note that older hexchats
2956                         # used xchat config file, so test first for default, then legacy. Because it's possible
2957                         # for this file to be use edited, doing some extra checks here.
2958                         if [[ -f ~/.config/hexchat/hexchat.conf ]];then
2959                                 file_data="$( cat ~/.config/hexchat/hexchat.conf )"
2960                         elif [[ -f  ~/.config/hexchat/xchat.conf ]];then
2961                                 file_data="$( cat ~/.config/hexchat/xchat.conf )"
2962                         fi
2963                         if [[ -n $file_data ]];then
2964                                 IRC_CLIENT_VERSION=$( gawk '
2965                                 BEGIN {
2966                                         IGNORECASE=1
2967                                         FS="="
2968                                 }
2969                                 /^[[:space:]]*version/ {
2970                                         # get rid of the space if present
2971                                         gsub(/[[:space:]]*/, "", $2 )
2972                                         print $2
2973                                         exit # usually this is the first line, no point in continuing
2974                                 }' <<< "$file_data" )
2975                                 
2976                                 IRC_CLIENT_VERSION=" $IRC_CLIENT_VERSION"
2977                         else
2978                                 IRC_CLIENT_VERSION=' N/A'
2979                         fi
2980                         IRC_CLIENT="HexChat"
2981                         ;;
2982                 ircii)
2983                         IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
2984                                 print $3
2985                         }' )"
2986                         B_CONSOLE_IRC='true'
2987                         IRC_CLIENT="ircII"
2988                         ;;
2989                 irssi-text|irssi)
2990                         IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
2991                                 print $2
2992                         }' )"
2993                         B_CONSOLE_IRC='true'
2994                         IRC_CLIENT="Irssi"
2995                         ;;
2996                 konversation) ## konvi < 1.2 (qt4)
2997                         # this is necessary to avoid the dcop errors from starting inxi as a /cmd started script
2998                         if [[ $B_Non_Native_App == 'true' ]];then  ## true negative is confusing
2999                                 KONVI=2
3000                         else # if native app
3001                                 KONVI=1
3002                         fi
3003                         IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk '
3004                         /Konversation:/ {
3005                                 for ( i=2; i<=NF; i++ ) {
3006                                         if (i == NF) {
3007                                                 print $i
3008                                         }
3009                                         else {
3010                                                 printf $i" "
3011                                         }
3012                                 }
3013                                 exit
3014                         }' )"
3015
3016                         T=($IRC_CLIENT_VERSION)
3017                         if [[ ${T[0]} == *+* ]];then
3018                                 # < Sho_> locsmif: The version numbers of SVN versions look like this:
3019                                 #         "<version number of last release>+ #<build number", i.e. "1.0+ #3177" ...
3020                                 #         for releases we remove the + and build number, i.e. "1.0" or soon "1.0.1"
3021                                 IRC_CLIENT_VERSION=" CVS $IRC_CLIENT_VERSION"
3022                                 T2="${T[0]/+/}"
3023                         else
3024                                 IRC_CLIENT_VERSION=" ${T[0]}"
3025                                 T2="${T[0]}"
3026                         fi
3027                         # Remove any dots except the first, and make sure there are no trailing zeroes,
3028                         T2=$( echo "$T2" | gawk '{
3029                                 sub(/\./, " ")
3030                                 gsub(/\./, "")
3031                                 sub(/ /, ".")
3032                                 printf("%g\n", $0)
3033                         }' )
3034                         # Since Konversation 1.0, the DCOP interface has changed a bit: dcop "$DCPORT" Konversation ..etc
3035                         # becomes : dcop "$DCPORT" default ... or dcop "$DCPORT" irc ..etc. So we check for versions smaller
3036                         # than 1 and change the DCOP parameter/object accordingly.
3037                         if [[ ${T2} -lt 1 ]];then
3038                                 DCOPOBJ="Konversation"
3039                         fi
3040                         IRC_CLIENT="Konversation"
3041                         ;;
3042                 kopete)
3043                         IRC_CLIENT_VERSION=" $( kopete -v | gawk '
3044                         /Kopete:/ {
3045                                 print $2
3046                                 exit
3047                         }' )"
3048                         IRC_CLIENT="Kopete"
3049                         ;;
3050                 kvirc)
3051                         IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v 2>&1 | gawk '{
3052                                 for ( i=2; i<=NF; i++) {
3053                                         if ( i == NF ) {
3054                                                 print $i
3055                                         }
3056                                         else {
3057                                                 printf $i" "
3058                                         }
3059                                 }
3060                                 exit
3061                                 }' )"
3062                         IRC_CLIENT="KVIrc"
3063                         ;;
3064                 pidgin)
3065                         IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
3066                                 print $2
3067                         }' )"
3068                         IRC_CLIENT="Pidgin"
3069                         ;;
3070                 quassel*)
3071                         # sample: quassel -v
3072                         # Qt: 4.5.0
3073                         # KDE: 4.2.65 (KDE 4.2.65 (KDE 4.3 >= 20090226))
3074                         # Quassel IRC: v0.4.0 [+60] (git-22effe5)
3075                         # note: early < 0.4.1 quassels do not have -v
3076                         IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v 2>/dev/null | gawk -F ': ' '
3077                         BEGIN {
3078                                 IGNORECASE=1
3079                                 clientVersion=""
3080                         }
3081                         /Quassel IRC/ {
3082                                 clientVersion = $2
3083                         }
3084                         END {
3085                                 # this handles pre 0.4.1 cases with no -v
3086                                 if ( clientVersion == "" ) {
3087                                         clientVersion = "(pre v0.4.1)"
3088                                 }
3089                                 print clientVersion
3090                         }' )"
3091                         # now handle primary, client, and core. quasselcore doesn't actually
3092                         # handle scripts with exec, but it's here just to be complete
3093                         case $App_Working_Name in
3094                                 quassel)
3095                                         IRC_CLIENT="Quassel [M]"
3096                                         ;;
3097                                 quasselclient)
3098                                         IRC_CLIENT="Quassel"
3099                                         ;;
3100                                 quasselcore)
3101                                         IRC_CLIENT="Quassel (core)"
3102                                         ;;
3103                         esac
3104                         ;;
3105                 weechat-curses)
3106                         IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v ) "
3107                         B_CONSOLE_IRC='true'
3108                         IRC_CLIENT="Weechat"
3109                         ;;
3110                 xchat-gnome)
3111                         IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
3112                                 print $2
3113                         }' )"
3114                         IRC_CLIENT="X-Chat-Gnome"
3115                         ;;
3116                 xchat)
3117                         IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
3118                                 print $2
3119                         }' )"
3120                         IRC_CLIENT="X-Chat"
3121                         ;;
3122                 # then do some perl type searches, do this last since it's a wildcard search
3123                 perl*|ksirc|dsirc)
3124                         unset IRC_CLIENT_VERSION
3125                         # KSirc is one of the possibilities now. KSirc is a wrapper around dsirc, a perl client
3126                         get_cmdline $PPID
3127                         for (( i=0; i <= $CMDL_MAX; i++ ))
3128                         do
3129                                 case ${A_CMDL[i]} in
3130                                         *dsirc*)
3131                                         IRC_CLIENT="KSirc"
3132                                         # Dynamic runpath detection is too complex with KSirc, because KSirc is started from
3133                                         # kdeinit. /proc/<pid of the grandparent of this process>/exe is a link to /usr/bin/kdeinit
3134                                         # with one parameter which contains parameters separated by spaces(??), first param being KSirc.
3135                                         # Then, KSirc runs dsirc as the perl irc script and wraps around it. When /exec is executed,
3136                                         # dsirc is the program that runs inxi, therefore that is the parent process that we see.
3137                                         # You can imagine how hosed I am if I try to make inxi find out dynamically with which path
3138                                         # KSirc was run by browsing up the process tree in /proc. That alone is straightjacket material.
3139                                         # (KSirc sucks anyway ;)
3140                                         IRC_CLIENT_VERSION=" $( ksirc -v | gawk '
3141                                         /KSirc:/ {
3142                                                 print $2
3143                                                 exit
3144                                         }' )"
3145                                         break
3146                                         ;;
3147                                 esac
3148                         done
3149                         B_CONSOLE_IRC='true'
3150                         set_perl_python_konvi "$App_Working_Name"
3151                         ;;
3152                 python*)
3153                         # B_CONSOLE_IRC='true' # are there even any python type console irc clients? check.
3154                         set_perl_python_konvi "$App_Working_Name"
3155                         ;;
3156                 # then unset, set unknown data
3157                 *)      
3158                         IRC_CLIENT="Unknown : ${Irc_Client_Path##*/}"
3159                         unset IRC_CLIENT_VERSION
3160                         ;;
3161         esac
3162         if [[ $SHOW_IRC -lt 2 ]];then
3163                 unset IRC_CLIENT_VERSION
3164         fi
3165 }
3166
3167 # args: $1 - App_Working_Name
3168 set_perl_python_konvi()
3169 {
3170         if [[ -z $IRC_CLIENT_VERSION ]];then
3171                 # this is a hack to try to show konversation if inxi is running but started via /cmd
3172                 if [[ -n $( grep -i 'konversation' <<< "$Ps_aux_Data" | grep -v 'grep' ) && $B_RUNNING_IN_DISPLAY == 'true' ]];then
3173                         IRC_CLIENT='Konversation'
3174                         IRC_CLIENT_VERSION=" $( konversation --version 2>/dev/null | gawk '/^Konversation/ {print $2}' )"
3175                         B_CONSOLE_IRC='false'
3176                 else
3177                         IRC_CLIENT="Unknown $1 client"
3178                 fi
3179         fi
3180 }
3181
3182 ## try to infer the use of Konversation >= 1.2, which shows $PPID improperly
3183 ## no known method of finding Kovni >= 1.2 as parent process, so we look to see if it is running,
3184 ## and all other irc clients are not running.  
3185 is_this_qt4_konvi()
3186 {
3187         local konvi_qt4_client='' konvi_dbus_exist='' konvi_pid='' konvi_home_dir='' 
3188         local konvi='' konvi_qt4_ver='' b_is_qt4=''
3189         
3190         # fringe cases can throw error, always if untested app, use 2>/dev/null after testing if present
3191         if [[ $B_QDBUS == 'true' ]];then
3192                 konvi_dbus_exist=$( qdbus 2>/dev/null | grep "org.kde.konversation" )
3193         fi
3194         # sabayon uses /usr/share/apps/konversation as path
3195         if [[ -n $konvi_dbus_exist ]] && [[ -e /usr/share/kde4/apps/konversation || -e  /usr/share/apps/konversation ]]; then
3196                 konvi_pid=$( ps -A | gawk 'BEGIN{IGNORECASE=1} /konversation/ { print $1 }' ) 
3197                 konvi_home_dir=$( readlink /proc/$konvi_pid/exe )
3198                 konvi=$( echo $konvi_home_dir | sed "s/\// /g" )
3199                 konvi=($konvi)
3200
3201                 if [[ ${konvi[2]} == 'konversation' ]];then     
3202                         konvi_qt4_ver=$( konversation -v | grep -i 'konversation' )
3203                         # note: we need to change this back to a single dot number, like 1.3, not 1.3.2
3204                         konvi_qt4_client=$( echo "$konvi_qt4_ver" | gawk '{ print $2 }' | cut -d '.' -f 1,2 )
3205
3206                         if [[ $konvi_qt4_client > 1.1 ]]; then
3207                                 b_is_qt4='true'
3208                         fi
3209                 fi
3210         else
3211                 konvi_qt4="qt3"
3212                 b_is_qt4='false'
3213         fi
3214         log_function_data "b_is_qt4: $b_is_qt4"
3215         echo $b_is_qt4
3216         ## for testing this module
3217         #qdbus org.kde.konversation /irc say $1 $2 "getpid_dir: $konvi_qt4  qt4_konvi: $konvi_qt4_ver   verNum: $konvi_qt4_ver_num  pid: $konvi_pid ppid: $PPID  konvi_home_dir: ${konvi[2]}"
3218 }
3219
3220 # This needs some cleanup and comments, not quite understanding what is happening, although generally output is known
3221 # Parse the null separated commandline under /proc/<pid passed in $1>/cmdline
3222 # args: $1 - $PPID
3223 get_cmdline()
3224 {
3225         eval $LOGFS
3226         local i=0 ppid=$1
3227
3228         if [[ ! -e /proc/$ppid/cmdline ]];then
3229                 echo 0
3230                 return
3231         fi
3232         ##print_screen_output "Marker"
3233         ##print_screen_output "\$ppid='$ppid' -=- $(< /proc/$ppid/cmdline)"
3234         unset A_CMDL
3235         ## note: need to figure this one out, and ideally clean it up and make it readable
3236         while read -d $'\0' L && [[ $i -lt 32 ]]
3237         do
3238                 A_CMDL[i++]="$L" ## note: make sure this is valid - What does L mean? ##
3239         done < /proc/$ppid/cmdline
3240         ##print_screen_output "\$i='$i'"
3241         if [[ $i -eq 0 ]];then
3242                 A_CMDL[0]=$(< /proc/$ppid/cmdline)
3243                 if [[ -n ${A_CMDL[0]} ]];then
3244                         i=1
3245                 fi
3246         fi
3247         CMDL_MAX=$i
3248         log_function_data "CMDL_MAX: $CMDL_MAX"
3249         eval $LOGFE
3250 }
3251
3252 #### -------------------------------------------------------------------
3253 #### get data types
3254 #### -------------------------------------------------------------------
3255 ## create array of sound cards installed on system, and if found, use asound data as well
3256 get_audio_data()
3257 {
3258         eval $LOGFS
3259         local i='' alsa_data='' audio_driver='' device_count='' temp_array=''
3260
3261         IFS=$'\n'
3262         # this first step handles the drivers for cases where the second step fails to find one
3263         device_count=$( echo "$Lspci_v_Data" | grep -iEc '(multimedia audio controller|audio device)' )