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