Merge ~sylvain-pineau/plainbox-provider-checkbox:inxi_2021_07_21 into plainbox-provider-checkbox:master

Proposed by Sylvain Pineau
Status: Merged
Approved by: Sylvain Pineau
Approved revision: 24af188e19afb22898301d5a30e498b0daf980c3
Merged at revision: 5d9b74b71d0e883bce1b1300e580f79ada78a7e7
Proposed branch: ~sylvain-pineau/plainbox-provider-checkbox:inxi_2021_07_21
Merge into: plainbox-provider-checkbox:master
Diff against target: 45453 lines (+26072/-18358)
1 file modified
bin/inxi_snapshot (+26072/-18358)
Reviewer Review Type Date Requested Status
Maciej Kisielewski (community) Approve
Review via email: mp+408945@code.launchpad.net

Description of the change

Version refresh of the INXI system information tool

The previous snapshot was from 2018 and was missing some CPU IDs

Tested on AMD64

To post a comment you must log in.
Revision history for this message
Maciej Kisielewski (kissiel) wrote :

+1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/bin/inxi_snapshot b/bin/inxi_snapshot
index 5928ca5..6c4d37b 100755
--- a/bin/inxi_snapshot
+++ b/bin/inxi_snapshot
@@ -1,11 +1,11 @@
1#!/usr/bin/env perl1#!/usr/bin/env perl
2## infobash: Copyright (C) 2005-2007 Michiel de Boer aka locsmif2## infobash: Copyright (C) 2005-2007 Michiel de Boer aka locsmif
3## inxi: Copyright (C) 2008-2018 Harald Hope3## inxi: Copyright (C) 2008-2021 Harald Hope
4## Additional features (C) Scott Rogers - kde, cpu info4## Additional features (C) Scott Rogers - kde, cpu info
5## Further fixes (listed as known): Horst Tritremmel <hjt at sidux.com>5## Further fixes (listed as known): Horst Tritremmel <hjt at sidux.com>
6## Steven Barrett (aka: damentz) - usb audio patch; swap percent used patch6## Steven Barrett (aka: damentz) - usb audio patch; swap percent used patch
7## Jarett.Stevens - dmidecode -M patch for older systems with the /sys7## Jarett.Stevens - dmidecode -M patch for older systems without /sys machine
8##8##
9## License: GNU GPL v3 or greater9## License: GNU GPL v3 or greater
10##10##
11## You should have received a copy of the GNU General Public License11## You should have received a copy of the GNU General Public License
@@ -13,83 +13,106 @@
13##13##
14## If you don't understand what Free Software is, please read (or reread)14## If you don't understand what Free Software is, please read (or reread)
15## this page: http://www.gnu.org/philosophy/free-sw.html15## this page: http://www.gnu.org/philosophy/free-sw.html
16##
17## DEVS: NOTE: geany/scite folding is picky. Leave 1 space after # or it breaks!
1618
17use strict;19use strict;
18use warnings;20use warnings;
19# use diagnostics;21# use diagnostics;
20use 5.008;22use 5.008;
2123
22use Cwd qw(abs_path); # qw(abs_path);#abs_path realpath getcwd24## Perl 7 things for testing: depend on Perl 5.032
25# use 5.032;
26# use compat::perl5; # act like Perl 5's defaults
27# no feature qw(indirect);
28# no multidimensional;
29# no bareword::filehandles;
30
31use Cwd qw(abs_path); # #abs_path realpath getcwd
23use Data::Dumper qw(Dumper); # print_r32use Data::Dumper qw(Dumper); # print_r
24use File::Find;33# NOTE: load in SystemDebugger unless encounter issues with require/import
34# use File::Find;
35use File::stat; # needed for Xorg.0.log file mtime comparisons
25use Getopt::Long qw(GetOptions);36use Getopt::Long qw(GetOptions);
26# Note: default auto_abbrev is enabled, that's fine37# Note: default auto_abbrev is enabled
27Getopt::Long::Configure ('bundling', 'no_ignore_case', 38Getopt::Long::Configure ('bundling', 'no_ignore_case',
28'no_getopt_compat', 'no_auto_abbrev','pass_through');39'no_getopt_compat', 'no_auto_abbrev','pass_through');
29use POSIX qw(uname strftime ttyname);40use POSIX qw(ceil uname strftime ttyname);
30# use feature qw(state);41# use Benchmark qw(:all);_
42# use Devel::Size qw(size total_size);
43# use feature qw(say state); # 5.10 or newer Perl
44
45### INITIALIZE VARIABLES ###
3146
32## INXI INFO ##47## INXI INFO ##
33my $self_name='inxi';48my $self_name='inxi';
34my $self_version='3.0.27';49my $self_version='3.3.06';
35my $self_date='2018-10-14';50my $self_date='2021-07-21';
36my $self_patch='00';51my $self_patch='00';
37## END INXI INFO ##52## END INXI INFO ##
3853
39### INITIALIZE VARIABLES ###54my ($b_pledge,@pledges);
55if (eval {require OpenBSD::Pledge}){
56 OpenBSD::Pledge->import();
57 $b_pledge = 1;
58 # cpath/wpath: dir/files .inxi, --debug > 9, -c 9x, -w/W;
59 # dns/inet: ftp upload --debug > 20; exec/proc/rpath: critical;
60 # prot_exec: Perl import; getpw: perl getpwuid() -c 9x, Net::FTP --debug > 20;
61 # stdio: default; error: debugging pledge/perl
62 # tested. not required: mcast pf ps recvfd sendfd tmppath tty unix vminfo;
63 # Pledge removal: OptionsHandler::post_process() [dns,inet,cpath,getpw,wpath];
64 # SelectColors::set_selection() [getpw]
65 @pledges = qw(cpath dns exec getpw inet proc prot_exec rpath wpath);
66 pledge(@pledges);
67}
4068
41## Self data69## Self data
42my ($self_path, $user_config_dir, $user_config_file,$user_data_dir);70my ($self_path,$user_config_dir,$user_config_file,$user_data_dir);
71
72## Hashes
73my (%alerts,%build_prop,%client,%colors,%disks_bsd,%dboot,%devices,%dl,
74%dmmapper,%force,%loaded,%mapper,%program_values,%rows,%sensors_raw,
75%service_tool,%show,%sysctl,%system_files,%usb);
76
77## System Arrays
78my (@app,@dmi,@gpudata,@ifs,@ifs_bsd,@paths,@ps_aux,@ps_cmd,@ps_gui,
79@sensors_exclude,@sensors_use,@uname);
80
81## Disk/Logical/Partition/RAID arrays
82my (@btrfs_raid,@glabel,@labels,@lsblk,@lvm,@lvm_raid,@md_raid,@partitions,
83@proc_partitions,@raw_logical,@soft_raid,@swaps,@uuids,@zfs_raid);
4384
44## Debuggers85## Debuggers
45my $debug=0;86my %debugger = ('level' => 0);
46my (@t0,$end,$start,$fh_l,$log_file); # log file handle, file87my (@dbg,%fake,@t0);
47my ($b_hires,$t1,$t2,$t3) = (0,0,0,0);88my ($b_hires,$b_log,$b_log_colors,$b_log_full);
89my ($end,$start,$fh_l,$log_file); # log file handle, file
90my ($t1,$t2,$t3) = (0,0,0); # timers
91## debug / temp tools
92$debugger{'sys'} = 1;
93$client{'test-konvi'} = 0;
94
48# NOTE: redhat removed HiRes from Perl Core Modules. 95# NOTE: redhat removed HiRes from Perl Core Modules.
49if (eval {require Time::HiRes}){96if (eval {require Time::HiRes}){
50 Time::HiRes->import('gettimeofday','tv_interval','usleep');97 Time::HiRes->import('gettimeofday','tv_interval','usleep');
51 $b_hires = 1;98 $b_hires = 1;
52}99}
53@t0 = eval 'Time::HiRes::gettimeofday()' if $b_hires; # let's start it right away100@t0 = eval 'Time::HiRes::gettimeofday()' if $b_hires; # let's start it right away
54## Hashes101
55my ( %alerts,%client,%colors,%debugger,%dl,%files,%rows,%system_files,%use );102## Booleans [busybox_ps not used actively]
56103my ($b_admin,$b_android,$b_arm,$b_busybox_ps,$b_display,$b_irc,
57## Arrays104$b_mips,$b_ppc,$b_root,$b_running_in_display,$b_sparc);
58# ps_aux is full output, ps_cmd is only the last 10 columns to last
59my (@app,@dmesg_boot,@devices_audio,@devices_graphics,@devices_network,
60@devices_hwraid,@devices_timer,@dmi,@gpudata,@ifs,@ifs_bsd,
61@paths,@proc_partitions,@ps_aux,@ps_cmd,@ps_gui,
62@sysctl,@sysctl_battery,@sysctl_sensors,@sysctl_machine,@uname,@usb);
63## Disk arrays
64my (@dm_boot_disk,@dm_boot_optical,@glabel,@gpart,@hardware_raid,@labels,
65@lsblk,@partitions,@raid,@sysctl_disks,@uuids);
66my @test = (0,0,0,0,0);
67
68## Booleans
69my ($b_admin,$b_arm,$b_bb_ps,$b_block_tool,$b_console_irc,
70$b_display,$b_dmesg_boot_check,$b_dmi,$b_dmidecode_force,
71$b_fake_bsd,$b_fake_dboot,$b_fake_dmidecode,$b_fake_pciconf,$b_fake_sysctl,
72$b_fake_usbdevs,$b_force_display,$b_gpudata,$b_irc,
73$b_log,$b_log_colors,$b_log_full,$b_man,$b_mem,$b_mips,
74$b_pci,$b_pci_tool,$b_ppc,$b_proc_partitions,$b_ps_gui,
75$b_root,$b_running_in_display,
76$b_slot_tool,$b_soc_audio,$b_soc_gfx,$b_soc_net,$b_soc_timer,$b_sparc,
77$b_sudo,$b_sysctl,$b_usb,$b_usb_check,$b_usb_sys,$b_usb_tool,$b_wmctrl);
78## Disk checks
79my ($b_dm_boot_disk,$b_dm_boot_optical,$b_glabel,$b_hardware_raid,
80$b_label_uuid,$b_lsblk,$b_partitions,$b_raid);
81my ($b_sysctl_disk,$b_update,$b_weather) = (1,1,1);
82105
83## System106## System
84my ($bsd_type,$language,$os,$pci_tool,$device_vm) = ('','','','','');107my ($bsd_type,$device_vm,$language,$os,$pci_tool,$wan_url) = ('','','','','','');
85my ($bits_sys,$cpu_arch);108my ($bits_sys,$cpu_arch,$ppid);
86my ($cpu_sleep,$dl_timeout,$limit,$ps_cols,$ps_count) = (0.35,4,10,0,5);109my ($cpu_sleep,$dl_timeout,$limit,$ps_cols,$ps_count) = (0.35,4,10,0,5);
87my $sensors_cpu_nu = 0;110my $sensors_cpu_nu = 0;
88my $weather_unit='mi';111my ($dl_ua,$weather_source,$weather_unit) = ('s-tools/' . $self_name . '-',100,'mi');
89112
90## Tools113## Tools
91my ($display,$ftp_alt,$tty_session);114my ($bt_tool,$display,$ftp_alt);
92my ($display_opt,$sudo) = ('','');115my ($display_opt,$sudoas) = ('','');
93116
94## Output117## Output
95my $extra = 0;# supported values: 0-3118my $extra = 0;# supported values: 0-3
@@ -98,26 +121,25 @@ my $line1 = "-------------------------------------------------------------------
98my $line2 = "======================================================================\n";121my $line2 = "======================================================================\n";
99my $line3 = "----------------------------------------\n";122my $line3 = "----------------------------------------\n";
100my ($output_file,$output_type) = ('','screen');123my ($output_file,$output_type) = ('','screen');
101my $prefix = 0; # for the primiary row hash key prefix124my $prefix = 0; # for the primary row hash key prefix
102125
103# these will assign a separator to non irc states. Important! Using ':' can 126## Initialize internal hashes
127# these assign a separator to non irc states. Important! Using ':' can
104# trigger stupid emoticon. Note: SEP1/SEP2 from short form not used anymore.128# trigger stupid emoticon. Note: SEP1/SEP2 from short form not used anymore.
105# behaviors in output on IRC, so do not use those.129# behaviors in output on IRC, so do not use those.
106my %sep = ( 130my %sep = (
107's1-irc' => ':',131's1-irc' => ':',
108's1-console' => ':',132's1-console' => ':',
109's2-irc' => '',133's2-irc' => '',
110's2-console' => ':',134's2-console' => ':',
111);135);
112136#$show{'host'} = 1;
113my %show = ('host' => 1);
114
115my %size = (137my %size = (
116'console' => 115,138'console' => 115,
117# Default indentation level. NOTE: actual indent is 1 greater to allow for 139# Default indentation level. NOTE: actual indent is 1 greater to allow for
118# spacing140# spacing
119'indent' => 11,141'indent' => 11,
120'indent-min' => 90,142'wrap-max' => 90,
121'irc' => 100, # shorter because IRC clients have nick lists etc143'irc' => 100, # shorter because IRC clients have nick lists etc
122'max' => 0,144'max' => 0,
123'no-display' => 130,145'no-display' => 130,
@@ -125,10 +147,10 @@ my %size = (
125'term' => 80,147'term' => 80,
126'term-lines' => 100,148'term-lines' => 100,
127);149);
128150my %use = (
129## debug / temp tools151'update' => 1, # switched off/on with maintainer config ALLOW_UPDATE
130$debugger{'sys'} = 1;152'weather' => 1, # switched off/on with maintainer config ALLOW_WEATHER
131$client{'test-konvi'} = 0;153);
132154
133########################################################################155########################################################################
134#### STARTUP156#### STARTUP
@@ -139,28 +161,29 @@ $client{'test-konvi'} = 0;
139#### -------------------------------------------------------------------161#### -------------------------------------------------------------------
140162
141sub main {163sub main {
142# print Dumper \@ARGV;164# print Dumper \@ARGV;
143 eval $start if $b_log;165 eval $start if $b_log;
144 initialize();166 initialize();
145 ## use for start client debugging167 ## Uncomment these two values for start client debugging
146 # $debug = 10; # 3 prints timers168 # $debugger{'level'} = 3; # 3 prints timers / 10 prints to log file
147 # set_debugger(); # for debugging of konvi issues169 # set_debugger(); # for debugging of konvi and other start client issues
148 #my $ob_start = StartClient->new();170 ## legacy method
149 #$ob_start->get_client_data();171 # my $ob_start = StartClient->new();
150 StartClient::get_client_data();172 #$ob_start->get_client_data();
151 # print_line( Dumper \%client);173 StartClient::set();
152 get_options();174 # print_line(Dumper \%client);
153 set_debugger(); # right after so it's set175 OptionsHandler::get();
154 check_tools();176 set_debugger(); # right after so it's set
155 set_colors();177 CheckTools::set();
156 set_sep();178 set_colors();
157 # print download_file('stdout','https://') . "\n";179 set_sep();
158 generate_lines();180 # print download_file('stdout','https://') . "\n";
159 eval $end if $b_log;181 OutputGenerator::generate();
160 cleanup();182 eval $end if $b_log;
161 # weechat's executor plugin forced me to do this, and rightfully so, 183 cleanup();
162 # because else the exit code from the last command is taken..184 # weechat's executor plugin forced me to do this, and rightfully so,
163 exit 0;185 # because else the exit code from the last command is taken..
186 exit 0;
164}187}
165188
166#### -------------------------------------------------------------------189#### -------------------------------------------------------------------
@@ -168,417 +191,515 @@ sub main {
168#### -------------------------------------------------------------------191#### -------------------------------------------------------------------
169192
170sub initialize {193sub initialize {
171 set_os();194 set_os();
172 set_path();195 set_path();
173 set_user_paths();196 set_user_paths();
174 set_basics();197 set_basics();
175 system_files('set');198 set_system_files();
176 get_configs();199 Configs::set();
177 # set_downloader();200 # set_downloader();
178 set_display_width('live');201 set_display_width('live');
179}202}
180203
181sub check_tools {204## CheckTools
182 my ($action,$program,$message,@data,%commands,%hash);205{
183 if ( $b_dmi ){206package CheckTools;
184 $action = 'use';207my (%commands);
185 if ($program = check_program('dmidecode')) {208sub set {
186 @data = grabber("$program -t chassis -t baseboard -t processor 2>&1");209 eval $start if $b_log;
187 if (scalar @data < 15){210 set_commands();
188 if ($b_root) {211 my ($action,$program,$message,@data);
189 foreach (@data){212 foreach my $test (keys %commands){
190 if ($_ =~ /No SMBIOS/i){213 ($action,$program) = ('use','');
191 $action = 'smbios';214 $message = main::row_defaults('tool-present');
192 last;215 if ($commands{$test}->[1] && (
193 }216 ($commands{$test}->[1] eq 'linux' && $os ne 'linux') ||
194 elsif ($_ =~ /^\/dev\/mem: Operation/i){217 ($commands{$test}->[1] eq 'bsd' && $os eq 'linux'))){
195 $action = 'no-data';218 $action = 'platform';
196 last;219 }
197 }220 elsif ($program = main::check_program($test)){
198 else {221 # > 0 means error in shell
199 $action = 'unknown-error';222 # my $cmd = "$program $commands{$test} >/dev/null";
200 last;223 # print "$cmd\n";
201 }224 $pci_tool = $test if $test =~ /pci/;
202 }225 if ($commands{$test}->[0] eq 'exec-sys'){
203 }226 $action = 'permissions' if system("$program $commands{$test}->[2] >/dev/null 2>&1");
204 else {227 }
205 if (grep { $_ =~ /^\/dev\/mem: Permission/i } @data){228 elsif ($commands{$test}->[0] eq 'exec-string'){
206 $action = 'permissions';229 @data = main::grabber("$program $commands{$test}->[2] 2>&1");
207 }230 # dmidecode errors are so specific it gets its own section
208 else {231 # also sets custom dmidecode error messages
209 $action = 'unknown-error';232 if ($test eq 'dmidecode'){
210 }233 $action = set_dmidecode(\@data) if scalar @data < 15;
211 }234 }
212 }235 elsif (grep { $_ =~ /$commands{$test}->[3]/i } @data){
213 }236 $action = 'permissions';
214 else {237 }
215 $action = 'missing';238 }
216 }239 }
217 %hash = (240 else {
218 'dmidecode' => {241 $action = 'missing';
219 'action' => $action,242 }
220 'missing' => 'Required program dmidecode not available',243 $alerts{$test}->{'action'} = $action;
221 'permissions' => 'Unable to run dmidecode. Are you root?',244 $alerts{$test}->{'path'} = $program;
222 'smbios' => 'No SMBIOS data for dmidecode to process',245 if ($action eq 'missing'){
223 'no-data' => 'dmidecode is not allowed to read /dev/mem',246 $alerts{$test}->{'message'} = main::row_defaults('tool-missing-recommends',"$test");
224 'unknown-error' => 'dmidecode was unable to generate data',247 }
225 },248 elsif ($action eq 'permissions'){
226 );249 $alerts{$test}->{'message'} = main::row_defaults('tool-permissions',"$test");
227 %alerts = (%alerts, %hash);250 }
228 }251 elsif ($action eq 'platform'){
229 # note: gnu/linux has sysctl so it may be used that for something if present252 $alerts{$test}->{'message'} = main::row_defaults('tool-missing-os', $uname[0] . " $test");
230 # there is lspci for bsds so doesn't hurt to check it253 }
231 if ($b_pci || $b_sysctl){254 }
232 if (!$bsd_type){255 print Data::Dumper::Dumper \%alerts if $dbg[25];
233 if ($b_pci ){256 set_fake_bsd_tools() if $fake{'bsd'};
234 %hash = ('lspci' => '-n',);257 set_forced_tools();
235 %commands = (%commands,%hash);258 eval $end if $b_log;
236 }259}
237 }260sub set_dmidecode {
238 else {261 my ($data) = @_;
239 if ($b_pci ){262 my $action = 'use';
240 %hash = ('pciconf' => '-l','pcictl' => 'list', 'pcidump' => '');263 if ($b_root){
241 %commands = (%commands,%hash);264 foreach (@$data){
242 }265 # don't need first line or scanning /dev/mem lines
243 if ($b_sysctl ){266 if (/^(# dmi|Scanning)/){
244 # note: there is a case of kernel.osrelease but it's a linux distro267 next;
245 %hash = ('sysctl' => 'kern.osrelease',);268 }
246 %commands = (%commands,%hash);269 elsif ($_ =~ /No SMBIOS/i){
247 }270 $action = 'smbios';
248 }271 last;
249 foreach ( keys %commands ){272 }
250 $action = 'use';273 elsif ($_ =~ /^\/dev\/mem: Operation/i){
251 if ($program = check_program($_)) {274 $action = 'no-data';
252 # > 0 means error in shell275 last;
253 #my $cmd = "$program $commands{$_} >/dev/null";276 }
254 #print "$cmd\n";277 else {
255 $pci_tool = $_ if $_ =~ /pci/;278 $action = 'unknown-error';
256 $action = 'permissions' if system("$program $commands{$_} >/dev/null 2>&1");279 last;
257 }280 }
258 else {281 }
259 $action = 'missing';282 }
260 }283 else {
261 %hash = (284 if (grep { $_ =~ /^\/dev\/mem: Permission/i } @$data){
262 $_ => {285 $action = 'permissions';
263 'action' => $action,286 }
264 'missing' => "Missing system tool: $_. Output will be incomplete",287 else {
265 'permissions' => "Unable to run $_. Root required?",288 $action = 'unknown-error';
266 },289 }
267 );290 }
268 %alerts = (%alerts, %hash);291 if ($action ne 'use' && $action ne 'permissions'){
269 }292 if ($action eq 'smbios'){
270 }293 $alerts{'dmidecode'}->{'message'} = main::row_defaults('dmidecode-smbios');
271 %commands = ();294 }
272 if ( $show{'sensor'} ){295 elsif ($action eq 'no-data'){
273 %commands = ('sensors' => 'linux',);296 $alerts{'dmidecode'}->{'message'} = main::row_defaults('dmidecode-dev-mem');
274 }297 }
275 # note: lsusb ships in FreeBSD ports sysutils/usbutils298 elsif ($action eq 'unknown-error'){
276 if ( $b_usb ){299 $alerts{'dmidecode'}->{'message'} = main::row_defaults('tool-unknown-error','dmidecode');
277 %hash = ('lsusb' => 'all',);300 }
278 %commands = (%commands,%hash);301 }
279 %hash = ('usbdevs' => 'bsd',);302 return $action;
280 %commands = (%commands,%hash);303}
281 }304sub set_commands {
282 if ($show{'ip'} || ($bsd_type && $show{'network-advanced'})){305 # note: gnu/linux has sysctl so it may be used that for something if present
283 %hash = (306 # there is lspci for bsds so doesn't hurt to check it
284 'ip' => 'linux',307 if (!$bsd_type){
285 'ifconfig' => 'all',308 if ($use{'pci'}){
286 );309 $commands{'lspci'} = ['exec-sys','','-n'];
287 %commands = (%commands,%hash);310 }
288 }311 if ($use{'logical'}){
289 # can't check permissions since we need to know the partition312 $commands{'lvs'} = ['exec-sys','',''];
290 if ($b_block_tool){313 }
291 %hash = (314 }
292 'blockdev' => 'linux',315 else {
293 'lsblk' => 'linux',316 if ($use{'pci'}){
294 );317 $commands{'pciconf'} = ['exec-sys','','-l'];
295 %commands = (%commands,%hash);318 $commands{'pcictl'} = ['exec-sys','',' pci0 list'];
296 }319 $commands{'pcidump'} = ['exec-sys','',''];
297 foreach ( keys %commands ){320 }
298 $action = 'use';321 if ($use{'sysctl'}){
299 $message = 'Present and working';322 # note: there is a case of kernel.osrelease but it's a linux distro
300 if ( ($commands{$_} eq 'linux' && $os ne 'linux' ) || ($commands{$_} eq 'bsd' && $os eq 'linux' ) ){323 $commands{'sysctl'} = ['exec-sys','','kern.osrelease'];
301 $message = "No " . ucfirst($os) . " support. Is a comparable $_ tool available?";324 }
302 $action = 'platform';325 if ($use{'bsd-partition'}){
303 }326 $commands{'bioctl'} = ['missing','',''];
304 elsif (!check_program($_)){327 $commands{'disklabel'} = ['missing','',''];
305 $message = "Required tool $_ not installed. Check --recommends";328 $commands{'fdisk'} = ['missing','',''];
306 $action = 'missing';329 $commands{'gpart'} = ['missing','',''];
307 }330 }
308 %hash = (331 }
309 $_ => {332 if ($use{'dmidecode'}){
310 'action' => $action,333 $commands{'dmidecode'} = ['exec-string','','-t chassis -t baseboard -t processor',''];
311 'missing' => $message,334 }
312 'platform' => $message,335 if ($use{'usb'}){
313 },336 # note: lsusb ships in FreeBSD ports sysutils/usbutils
314 );337 $commands{'lsusb'} = ['missing','','',''];
315 %alerts = (%alerts, %hash);338 # we want these set for various null bsd data tests
316 }339 $commands{'usbconfig'} = ['exec-string','bsd','list','permissions'];
317 # print Dumper \%alerts;340 $commands{'usbdevs'} = ['missing','bsd','',''];
318 # only use sudo if not root, -n option requires sudo -V 1.7 or greater. 341 }
319 # for some reason sudo -n with < 1.7 in Perl does not print to stderr342 if ($show{'bluetooth'}){
320 # sudo will just error out which is the safest course here for now,343 $commands{'bluetoothctl'} = ['missing','linux','',''];
321 # otherwise that interactive sudo password thing is too annoying344 # bt-adapter hangs when bluetooth service is disabled
322 # important: -n makes it non interactive, no prompt for password345 $commands{'bt-adapter'} = ['missing','linux','',''];
323 if (!$b_root && $b_sudo && (my $path = main::check_program('sudo') )) {346 $commands{'hciconfig'} = ['missing','linux','',''];
324 my @data = program_values('sudo');347 }
325 my $version = program_version($path,$data[0],$data[1],$data[2],$data[5]);348 if ($show{'sensor'}){
326 $version =~ s/^([0-9]+\.[0-9]+).*/$1/;349 $commands{'sensors'} = ['missing','linux','',''];
327 $sudo = "$path -n " if $version >= 1.7;350 }
328 }351 if ($show{'ip'} || ($bsd_type && $show{'network-advanced'})){
329 set_fake_tools() if $b_fake_bsd;352 $commands{'ip'} = ['missing','linux','',''];
353 $commands{'ifconfig'} = ['missing','','',''];
354 }
355 # can't check permissions since we need to know the partition/disc
356 if ($use{'block-tool'}){
357 $commands{'blockdev'} = ['missing','linux','',''];
358 $commands{'lsblk'} = ['missing','linux','',''];
359 }
360 if ($use{'btrfs'}){
361 $commands{'btrfs'} = ['missing','linux','',''];
362 }
363 if ($use{'mdadm'}){
364 $commands{'mdadm'} = ['missing','linux','',''];
365 }
366 if ($use{'smartctl'}){
367 $commands{'smartctl'} = ['missing','','',''];
368 }
369 if ($show{'unmounted'}){
370 $commands{'disklabel'} = ['missing','bsd','xx'];
371 }
372}
373sub set_forced_tools {
374 if ($bt_tool){
375 if ($bt_tool ne 'bluetootctl' && $alerts{'bluetoothctl'}->{'action'} eq 'use'){
376 $alerts{'bluetoothctl'}->{'action'} = 'missing';
377 }
378 if ($bt_tool ne 'bt-adapter' && $alerts{'bt-adapter'}->{'action'} eq 'use'){
379 $alerts{'bt-adapter'}->{'action'} = 'missing';
380 }
381 if ($bt_tool ne 'hciconfig' && $alerts{'hciconfig'}->{'action'} eq 'use'){
382 $alerts{'hciconfig'}->{'action'} = 'missing';
383 }
384 }
385}
386# only for dev/debugging BSD
387sub set_fake_bsd_tools {
388 $system_files{'dmesg-boot'} = '/var/run/dmesg.boot' if $fake{'dboot'};
389 $alerts{'sysctl'}->{'action'} = 'use' if $fake{'sysctl'};
390 if ($fake{'pciconf'} || $fake{'pcictl'} || $fake{'pcidump'}){
391 $alerts{'pciconf'}->{'action'} = 'use' if $fake{'pciconf'};
392 $alerts{'pcictl'}->{'action'} = 'use' if $fake{'pcictl'};
393 $alerts{'pcidump'}->{'action'} = 'use' if $fake{'pcidump'};
394 $alerts{'lspci'} = {
395 'action' => 'missing',
396 'message' => 'Required program lspci not available',
397 };
398 }
399 if ($fake{'usbconfig'} || $fake{'usbdevs'}){
400 $alerts{'usbconfig'}->{'action'} = 'use' if $fake{'usbconfig'};
401 $alerts{'usbdevs'}->{'action'} = 'use' if $fake{'usbdevs'};
402 $alerts{'lsusb'} = {
403 'action' => 'missing',
404 'message' => 'Required program lsusb not available',
405 };
406 }
407 if ($fake{'disklabel'}){
408 $alerts{'disklabel'}->{'action'} = 'use';
409 }
410}
330}411}
331412
332# args: 1 - desktop/app command for --version; 2 - search string; 413# args: 1 - desktop/app command for --version; 2 - search string;
333# 3 - space print number; 4 - [optional] version arg: -v, version, etc414# 3 - space print number; 4 - [optional] version arg: -v, version, etc
334# 5 - [optional] exit first find 0/1; 6 - [optional] 0/1 stderr output415# 5 - [optional] exit first find 0/1; 6 - [optional] 0/1 stderr output
335sub set_basics {416sub set_basics {
336 ### LOCALIZATION - DO NOT CHANGE! ###417 ### LOCALIZATION - DO NOT CHANGE! ###
337 # set to default LANG to avoid locales errors with , or .418 # set to default LANG to avoid locales errors with , or .
338 # Make sure every program speaks English.419 # Make sure every program speaks English.
339 $ENV{'LANG'}='C';420 $ENV{'LANG'}='C';
340 $ENV{'LC_ALL'}='C';421 $ENV{'LC_ALL'}='C';
341 # remember, perl uses the opposite t/f return as shell!!!422 # remember, perl uses the opposite t/f return as shell!!!
342 # some versions of busybox do not have tty, like openwrt423 # some versions of busybox do not have tty, like openwrt
343 $b_irc = ( check_program('tty') && system('tty >/dev/null') ) ? 1 : 0;424 $b_irc = (check_program('tty') && system('tty >/dev/null')) ? 1 : 0;
344 # print "birc: $b_irc\n";425 # print "birc: $b_irc\n";
345 $b_display = ( $ENV{'DISPLAY'} ) ? 1 : 0;426 $b_display = ($ENV{'DISPLAY'}) ? 1 : 0;
346 $b_root = ( $ENV{'HOME'} eq '/root' ) ? 1 : 0;427 $b_root = $< == 0; # root UID 0, all others > 0
347 $dl{'dl'} = 'curl';428 $dl{'dl'} = 'curl';
348 $dl{'curl'} = 1;429 $dl{'curl'} = 1;
349 $dl{'tiny'} = 1; # note: two modules needed, tested for in set_downloader430 $dl{'tiny'} = 1; # note: two modules needed, tested for in set_downloader
350 $dl{'wget'} = 1;431 $dl{'wget'} = 1;
351 $dl{'fetch'} = 1;432 $dl{'fetch'} = 1;
352 $client{'console-irc'} = 0;433 $client{'console-irc'} = 0;
353 $client{'dcop'} = (check_program('dcop')) ? 1 : 0;434 $client{'dcop'} = (check_program('dcop')) ? 1 : 0;
354 $client{'qdbus'} = (check_program('qdbus')) ? 1 : 0;435 $client{'qdbus'} = (check_program('qdbus')) ? 1 : 0;
355 $client{'konvi'} = 0;436 $client{'konvi'} = 0;
356 $client{'name'} = '';437 $client{'name'} = '';
357 $client{'name-print'} = '';438 $client{'name-print'} = '';
358 $client{'su-start'} = ''; # shows sudo/su439 $client{'su-start'} = ''; # shows sudo/su
359 $client{'version'} = '';440 $client{'version'} = '';
360 $colors{'default'} = 2;441 $colors{'default'} = 2;
361 $show{'partition-sort'} = 'id'; # sort order for partitions442 $show{'partition-sort'} = 'id'; # sort order for partitions
443 @raw_logical = (0,0,0);
444 $ppid = getppid();
362}445}
363446
364# args: $1 - default OR override default cols max integer count. $_[0]447# args: $1 - default OR override default cols max integer count. $_[0]
365# is the display width override.448# is the display width override.
366sub set_display_width {449sub set_display_width {
367 my ($width) = @_;450 my ($width) = @_;
368 if ( $width eq 'live' ){451 if ($width eq 'live'){
369 ## sometimes tput will trigger an error (mageia) if irc client452 ## sometimes tput will trigger an error (mageia) if irc client
370 if ( ! $b_irc ){453 if (!$b_irc){
371 if ( check_program('tput') ) {454 if (my $program = check_program('tput')){
372 # trips error if use qx()...455 # Arch urxvt: 'tput: unknown terminal "rxvt-unicode-256color"'
373 chomp($size{'term'}=qx{tput cols});456 # trips error if use qx(); in FreeBSD, if you use 2>/dev/null
374 chomp($size{'term-lines'}=qx{tput lines});457 # it makes default value 80x24, who knows why?
375 $size{'term-cols'} = $size{'term'};458 chomp($size{'term'} = qx{$program cols});
376 }459 chomp($size{'term-lines'} = qx{$program lines});
377 # print "tc: $size{'term'} cmc: $size{'console'}\n";460 $size{'term-cols'} = $size{'term'};
378 # double check, just in case it's missing functionality or whatever461 }
379 if ( $size{'term'} == 0 || $size{'term'} !~ /\d/ ){ 462 # print "tc: $size{'term'} cmc: $size{'console'}\n";
380 $size{'term'}=80;463 # double check, just in case it's missing functionality or whatever
381 # we'll be using this for terminal dimensions later so don't set default.464 if (!is_int($size{'term'} || $size{'term'} == 0)){
382 # $size{'term-lines'}=100;465 $size{'term'}=80;
383 }466 # we'll be using this for terminal dimensions later so don't set default.
384 }467 # $size{'term-lines'}=100;
385 # this lets you set different size for in or out of display server468 }
386 if ( ! $b_running_in_display && $size{'no-display'} ){469 }
387 $size{'console'}=$size{'no-display'};470 # this lets you set different size for in or out of display server
388 }471 if (!$b_running_in_display && $size{'no-display'}){
389 # term_cols is set in top globals, using tput cols472 $size{'console'} = $size{'no-display'};
390 # print "tc: $size{'term'} cmc: $size{'console'}\n";473 }
391 if ( $size{'term'} < $size{'console'} ){474 # term_cols is set in top globals, using tput cols
392 $size{'console'}=$size{'term'};475 # print "tc: $size{'term'} cmc: $size{'console'}\n";
393 }476 if ($size{'term'} < $size{'console'}){
394 # adjust, some terminals will wrap if output cols == term cols477 $size{'console'} = $size{'term'};
395 $size{'console'}=( $size{'console'} - 2 );478 }
396 # echo cmc: $size{'console'}479 # adjust, some terminals will wrap if output cols == term cols
397 # comes after source for user set stuff480 $size{'console'} = ($size{'console'} - 2);
398 if ( ! $b_irc ){481 # echo cmc: $size{'console'}
399 $size{'max'}=$size{'console'};482 # comes after source for user set stuff
400 }483 if (!$b_irc){
401 else {484 $size{'max'} = $size{'console'};
402 $size{'max'}=$size{'irc'};485 }
403 }486 else {
404 }487 $size{'max'} = $size{'irc'};
405 else {488 }
406 $size{'max'}=$width;489 }
407 }490 else {
408 # print "tc: $size{'term'} cmc: $size{'console'} cm: $size{'max'}\n";491 $size{'max'} = $width;
409}492 }
410493 # print "tc: $size{'term'} cmc: $size{'console'} cm: $size{'max'}\n";
411# only for dev/debugging BSD
412sub set_fake_tools {
413 $system_files{'dmesg-boot'} = '/var/run/dmesg.boot' if $b_fake_dboot;
414 $alerts{'pciconf'} = ({'action' => 'use'}) if $b_fake_pciconf;
415 $alerts{'sysctl'} = ({'action' => 'use'}) if $b_fake_sysctl;
416 if ($b_fake_usbdevs ){
417 $alerts{'usbdevs'} = ({'action' => 'use'});
418 $alerts{'lsusb'} = ({
419 'action' => 'missing',
420 'missing' => 'Required program lsusb not available',
421 });
422 }
423}494}
424495
425# NOTE: most tests internally are against !$bsd_type496# NOTE: most tests internally are against !$bsd_type
426sub set_os {497sub set_os {
427 @uname = uname();498 @uname = uname();
428 $os = lc($uname[0]);499 $os = lc($uname[0]);
429 $cpu_arch = lc($uname[-1]);500 $cpu_arch = lc($uname[-1]);
430 if ($cpu_arch =~ /arm|aarch/){$b_arm = 1}501 if ($cpu_arch =~ /arm|aarch/){$b_arm = 1;}
431 elsif ($cpu_arch =~ /mips/) {$b_mips = 1}502 elsif ($cpu_arch =~ /mips/){$b_mips = 1}
432 elsif ($cpu_arch =~ /power|ppc/) {$b_ppc = 1}503 elsif ($cpu_arch =~ /power|ppc/){$b_ppc = 1}
433 elsif ($cpu_arch =~ /sparc/) {$b_sparc = 1}504 elsif ($cpu_arch =~ /sparc/){$b_sparc = 1}
434 # aarch32 mips32 intel/amd handled in cpu505 # aarch32 mips32 intel/amd handled in cpu
435 if ($cpu_arch =~ /(armv[1-7]|32|sparc_v9)/){506 if ($cpu_arch =~ /(armv[1-7]|32|sparc_v9)/){
436 $bits_sys = 32;507 $bits_sys = 32;
437 }508 }
438 elsif ($cpu_arch =~ /(alpha|64)/){509 elsif ($cpu_arch =~ /(alpha|64|e2k)/){
439 $bits_sys = 64;510 $bits_sys = 64;
440 }511 }
441 if ( $os =~ /(aix|bsd|cosix|dragonfly|darwin|hp-?ux|indiana|irix|sunos|solaris|ultrix|unix)/ ){512 $b_android = 1 if -e '/system/build.prop';
442 if ( $os =~ /openbsd/ ){513 if ($os =~ /(aix|bsd|cosix|dragonfly|darwin|hp-?ux|indiana|irix|sunos|solaris|ultrix|unix)/){
443 $os = 'openbsd';514 if ($os =~ /openbsd/){
444 }515 $os = 'openbsd';
445 elsif ($os =~ /darwin/){516 }
446 $os = 'darwin';517 elsif ($os =~ /darwin/){
447 }518 $os = 'darwin';
448 if ($os =~ /kfreebsd/){519 }
449 $bsd_type = 'debian-bsd';520 if ($os =~ /kfreebsd/){
450 }521 $bsd_type = 'debian-bsd';
451 else {522 }
452 $bsd_type = $os;523 else {
453 }524 $bsd_type = $os;
454 }525 }
455}526 }
456527}
457# This data is hard set top of program but due to a specific project's528
458# foolish idea that ignoring the FSH totally is somehow a positive step529# Sometimes users will have more PATHs local to their setup, so we want those
459# forwards for free software, we also have to padd the results with PATH.530# too.
460sub set_path {531sub set_path {
461 # Extra path variable to make execute failures less likely, merged below532 # Extra path variable to make execute failures less likely, merged below
462 my (@path);533 my (@path);
463 # NOTE: recent Xorg's show error if you try /usr/bin/Xorg -version but work 534 # NOTE: recent Xorg's show error if you try /usr/bin/Xorg -version but work
464 # if you use the /usr/lib/xorg-server/Xorg path.535 # if you use the /usr/lib/xorg-server/Xorg path.
465 @paths = qw(/sbin /bin /usr/sbin /usr/bin /usr/local/sbin /usr/local/bin);536 @paths = qw(/sbin /bin /usr/sbin /usr/bin /usr/local/sbin /usr/local/bin);
466 @path = split /:/, $ENV{'PATH'} if $ENV{'PATH'};537 @path = split(':', $ENV{'PATH'}) if $ENV{'PATH'};
467 # print "paths: @paths\nPATH: $ENV{'PATH'}\n";538 # print "paths: @paths\nPATH: $ENV{'PATH'}\n";
468 # Create a difference of $PATH and $extra_paths and add that to $PATH:539 # Create a difference of $PATH and $extra_paths and add that to $PATH:
469 foreach my $id (@path) {540 foreach my $id (@path){
470 if ( !(grep { /^$id$/ } @paths) && $id !~ /(game)/ ){541 if (!(grep { /^$id$/ } @paths) && $id !~ /(game)/){
471 push @paths, $id;542 push(@paths, $id);
472 }543 }
473 }544 }
474 # print "paths: @paths\n";545 # print "paths: @paths\n";
475}546}
476547
477sub set_sep {548sub set_sep {
478 if ( $b_irc ){549 if ($b_irc){
479 # too hard to read if no colors, so force that for users on irc550 # too hard to read if no colors, so force that for users on irc
480 if ($colors{'scheme'} == 0 ){551 if ($colors{'scheme'} == 0){
481 $sep{'s1'} = $sep{'s1-console'};552 $sep{'s1'} = $sep{'s1-console'};
482 $sep{'s2'} = $sep{'s2-console'};553 $sep{'s2'} = $sep{'s2-console'};
483 }554 }
484 else {555 else {
485 $sep{'s1'} = $sep{'s1-irc'};556 $sep{'s1'} = $sep{'s1-irc'};
486 $sep{'s2'} = $sep{'s2-irc'};557 $sep{'s2'} = $sep{'s2-irc'};
487 }558 }
488 }559 }
489 else {560 else {
490 $sep{'s1'} = $sep{'s1-console'};561 $sep{'s1'} = $sep{'s1-console'};
491 $sep{'s2'} = $sep{'s2-console'};562 $sep{'s2'} = $sep{'s2-console'};
492 }563 }
564}
565
566# Important: -n makes it non interactive, no prompt for password
567# only use doas/sudo if not root, -n option requires sudo -V 1.7 or greater.
568# for some reason sudo -n with < 1.7 in Perl does not print to stderr
569# sudo will just error out which is the safest course here for now,
570# otherwise that interactive sudo password thing is too annoying
571sub set_sudo {
572 if (!$b_root){
573 my ($path);
574 if (!$force{'no-doas'} && ($path = check_program('doas'))){
575 $sudoas = "$path -n ";
576 }
577 elsif (!$force{'no-sudo'} && ($path = check_program('sudo'))){
578 my @data = program_data('sudo');
579 $data[1] =~ s/^([0-9]+\.[0-9]+).*/$1/;
580 # print "sudo v: $data[1]\n";
581 $sudoas = "$path -n " if is_numeric($data[1]) && $data[1] >= 1.7;
582 }
583 }
584}
585
586sub set_system_files {
587 my %files = (
588 'asound-cards' => '/proc/asound/cards',
589 'asound-modules' => '/proc/asound/modules',
590 'asound-version' => '/proc/asound/version',
591 'dmesg-boot' => '/var/run/dmesg.boot',
592 'proc-cmdline' => '/proc/cmdline',
593 'proc-cpuinfo' => '/proc/cpuinfo',
594 'proc-mdstat' => '/proc/mdstat',
595 'proc-meminfo' => '/proc/meminfo',
596 'proc-modules' => '/proc/modules', # not used
597 'proc-mounts' => '/proc/mounts',# not used
598 'proc-partitions' => '/proc/partitions',
599 'proc-scsi' => '/proc/scsi/scsi',
600 'proc-version' => '/proc/version',
601 # note: 'xorg-log' is set in set_xorg_log() only if -G is triggered
602 );
603 foreach (keys %files){
604 $system_files{$_} = (-e $files{$_}) ? $files{$_} : '';
605 }
493}606}
494607
495sub set_user_paths {608sub set_user_paths {
496 my ( $b_conf, $b_data );609 my ($b_conf,$b_data);
497 # this needs to be set here because various options call the parent 610 # this needs to be set here because various options call the parent
498 # initialize function directly.611 # initialize function directly.
499 $self_path = $0;612 $self_path = $0;
500 $self_path =~ s/[^\/]+$//;613 $self_path =~ s/[^\/]+$//;
501 # print "0: $0 sp: $self_path\n";614 # print "0: $0 sp: $self_path\n";
502 615 if (defined $ENV{'XDG_CONFIG_HOME'} && $ENV{'XDG_CONFIG_HOME'}){
503 if ( defined $ENV{'XDG_CONFIG_HOME'} && $ENV{'XDG_CONFIG_HOME'} ){616 $user_config_dir=$ENV{'XDG_CONFIG_HOME'};
504 $user_config_dir=$ENV{'XDG_CONFIG_HOME'};617 $b_conf=1;
505 $b_conf=1;618 }
506 }619 elsif (-d "$ENV{'HOME'}/.config"){
507 elsif ( -d "$ENV{'HOME'}/.config" ){620 $user_config_dir="$ENV{'HOME'}/.config";
508 $user_config_dir="$ENV{'HOME'}/.config";621 $b_conf=1;
509 $b_conf=1;622 }
510 }623 else {
511 else {624 $user_config_dir="$ENV{'HOME'}/.$self_name";
512 $user_config_dir="$ENV{'HOME'}/.$self_name";625 }
513 }626 if (defined $ENV{'XDG_DATA_HOME'} && $ENV{'XDG_DATA_HOME'}){
514 if ( defined $ENV{'XDG_DATA_HOME'} && $ENV{'XDG_DATA_HOME'} ){627 $user_data_dir="$ENV{'XDG_DATA_HOME'}/$self_name";
515 $user_data_dir="$ENV{'XDG_DATA_HOME'}/$self_name";628 $b_data=1;
516 $b_data=1;629 }
517 }630 elsif (-d "$ENV{'HOME'}/.local/share"){
518 elsif ( -d "$ENV{'HOME'}/.local/share" ){631 $user_data_dir="$ENV{'HOME'}/.local/share/$self_name";
519 $user_data_dir="$ENV{'HOME'}/.local/share/$self_name";632 $b_data=1;
520 $b_data=1;633 }
521 }634 else {
522 else {635 $user_data_dir="$ENV{'HOME'}/.$self_name";
523 $user_data_dir="$ENV{'HOME'}/.$self_name";636 }
524 }637 # note, this used to be created/checked in specific instance, but we'll just
525 # note, this used to be created/checked in specific instance, but we'll just do it638 # do it universally so it's done at script start.
526 # universally so it's done at script start.639 if (! -d $user_data_dir){
527 if ( ! -d $user_data_dir ){640 mkdir $user_data_dir;
528 mkdir $user_data_dir;641 # system "echo", "Made: $user_data_dir";
529 # system "echo", "Made: $user_data_dir";642 }
530 }643 if ($b_conf && -f "$ENV{'HOME'}/.$self_name/$self_name.conf"){
531 if ( $b_conf && -f "$ENV{'HOME'}/.$self_name/$self_name.conf" ){644 # system 'mv', "-f $ENV{'HOME'}/.$self_name/$self_name.conf", $user_config_dir;
532 #system 'mv', "-f $ENV{'HOME'}/.$self_name/$self_name.conf", $user_config_dir;645 # print "WOULD: Moved $self_name.conf from $ENV{'HOME'}/.$self_name to $user_config_dir\n";
533 # print "WOULD: Moved $self_name.conf from $ENV{'HOME'}/.$self_name to $user_config_dir\n";646 }
534 }647 if ($b_data && -d "$ENV{'HOME'}/.$self_name"){
535 if ( $b_data && -d "$ENV{'HOME'}/.$self_name" ){648 # system 'mv', '-f', "$ENV{'HOME'}/.$self_name/*", $user_data_dir;
536 #system 'mv', '-f', "$ENV{'HOME'}/.$self_name/*", $user_data_dir;649 # system 'rm', '-Rf', "$ENV{'HOME'}/.$self_name";
537 #system 'rm', '-Rf', "$ENV{'HOME'}/.$self_name";650 # print "WOULD: Moved data dir $ENV{'HOME'}/.$self_name to $user_data_dir\n";
538 # print "WOULD: Moved data dir $ENV{'HOME'}/.$self_name to $user_data_dir\n";651 }
539 }652 $log_file="$user_data_dir/$self_name.log";
540 $log_file="$user_data_dir/$self_name.log";653 # system 'echo', "$ENV{'HOME'}/.$self_name/* $user_data_dir";
541 #system 'echo', "$ENV{'HOME'}/.$self_name/* $user_data_dir";654 # print "scd: $user_config_dir sdd: $user_data_dir \n";
542 # print "scd: $user_config_dir sdd: $user_data_dir \n";655}
543}656
544657sub set_xorg_log {
545# args: 1: set|hash key to return either null or path658 eval $start if $b_log;
546sub system_files {659 my (@temp,@x_logs);
547 my ($file) = @_;660 my ($file_holder,$time_holder,$x_mtime) = ('',0,0);
548 if ( $file eq 'set'){661 # NOTE: other variations may be /var/run/gdm3/... but not confirmed
549 %files = (662 # worry about we are just going to get all the Xorg logs we can find,
550 'asound-cards' => '/proc/asound/cards',663 # and not which is 'right'.
551 'asound-modules' => '/proc/asound/modules',664 @temp = globber('/var/log/Xorg.*.log');
552 'asound-version' => '/proc/asound/version',665 push(@x_logs, @temp) if @temp;
553 'cpuinfo' => '/proc/cpuinfo',666 @temp = globber('/var/lib/gdm/.local/share/xorg/Xorg.*.log');
554 'dmesg-boot' => '/var/run/dmesg.boot',667 push(@x_logs, @temp) if @temp;
555 'lsb-release' => '/etc/lsb-release',668 @temp = globber($ENV{'HOME'} . '/.local/share/xorg/Xorg.*.log',);
556 'mdstat' => '/proc/mdstat',669 push(@x_logs, @temp) if @temp;
557 'meminfo' => '/proc/meminfo',670 # root will not have a /root/.local/share/xorg directory so need to use a
558 'modules' => '/proc/modules',671 # user one if we can find one.
559 'mounts' => '/proc/mounts',672 if ($b_root){
560 'os-release' => '/etc/os-release',673 @temp = globber('/home/*/.local/share/xorg/Xorg.*.log');
561 'partitions' => '/proc/partitions',674 push(@x_logs, @temp) if @temp;
562 'scsi' => '/proc/scsi/scsi',675 }
563 'version' => '/proc/version',676 foreach (@x_logs){
564 'xorg-log' => '/var/log/Xorg.0.log'677 if (-r $_){
565 );678 my $src_info = File::stat::stat("$_");
566 foreach ( keys %files ){679 # print "$_\n";
567 $system_files{$_} = ( -e $files{$_} ) ? $files{$_} : '';680 if ($src_info){
568 }681 $x_mtime = $src_info->mtime;
569 if ( ! $system_files{'xorg-log'} && check_program('xset') ){682 # print $_ . ": $x_time" . "\n";
570 my $data = qx(xset q 2>/dev/null);683 if ($x_mtime > $time_holder){
571 foreach ( split /\n/, $data){684 $time_holder = $x_mtime;
572 if ($_ =~ /Log file/i){685 $file_holder = $_;
573 $system_files{'xorg-log'} = get_piece($_,3);686 }
574 last;687 }
575 }688 }
576 }689 }
577 }690 if (!$file_holder && check_program('xset')){
578 }691 my $data = qx(xset q 2>/dev/null);
579 else {692 foreach (split('\n', $data)){
580 return $system_files{$file};693 if ($_ =~ /Log file/i){
581 }694 $file_holder = get_piece($_,3);
695 last;
696 }
697 }
698 }
699 print "Xorg log file: $file_holder\nLast modified: $time_holder\n" if $dbg[14];
700 log_data('data',"Xorg log file: $file_holder") if $b_log;
701 $system_files{'xorg-log'} = $file_holder;
702 eval $end if $b_log;
582}703}
583704
584########################################################################705########################################################################
@@ -591,425 +712,420 @@ sub system_files {
591712
592## arg: 1 - the type of action, either integer, count, or full713## arg: 1 - the type of action, either integer, count, or full
593sub get_color_scheme {714sub get_color_scheme {
594 my ($type) = @_;715 my ($type) = @_;
595 eval $start if $b_log;716 eval $start if $b_log;
596 my @color_schemes = (717 my @color_schemes = (
597 [qw(EMPTY EMPTY EMPTY )],718 [qw(EMPTY EMPTY EMPTY)],
598 [qw(NORMAL NORMAL NORMAL )],719 [qw(NORMAL NORMAL NORMAL)],
599 # for dark OR light backgrounds720 # for dark OR light backgrounds
600 [qw(BLUE NORMAL NORMAL)],721 [qw(BLUE NORMAL NORMAL)],
601 [qw(BLUE RED NORMAL )],722 [qw(BLUE RED NORMAL)],
602 [qw(CYAN BLUE NORMAL )],723 [qw(CYAN BLUE NORMAL)],
603 [qw(DCYAN NORMAL NORMAL)],724 [qw(DCYAN NORMAL NORMAL)],
604 [qw(DCYAN BLUE NORMAL )],725 [qw(DCYAN BLUE NORMAL)],
605 [qw(DGREEN NORMAL NORMAL )],726 [qw(DGREEN NORMAL NORMAL)],
606 [qw(DYELLOW NORMAL NORMAL )],727 [qw(DYELLOW NORMAL NORMAL)],
607 [qw(GREEN DGREEN NORMAL )],728 [qw(GREEN DGREEN NORMAL)],
608 [qw(GREEN NORMAL NORMAL )],729 [qw(GREEN NORMAL NORMAL)],
609 [qw(MAGENTA NORMAL NORMAL)],730 [qw(MAGENTA NORMAL NORMAL)],
610 [qw(RED NORMAL NORMAL)],731 [qw(RED NORMAL NORMAL)],
611 # for light backgrounds732 # for light backgrounds
612 [qw(BLACK DGREY NORMAL)],733 [qw(BLACK DGREY NORMAL)],
613 [qw(DBLUE DGREY NORMAL )],734 [qw(DBLUE DGREY NORMAL)],
614 [qw(DBLUE DMAGENTA NORMAL)],735 [qw(DBLUE DMAGENTA NORMAL)],
615 [qw(DBLUE DRED NORMAL )],736 [qw(DBLUE DRED NORMAL)],
616 [qw(DBLUE BLACK NORMAL)],737 [qw(DBLUE BLACK NORMAL)],
617 [qw(DGREEN DYELLOW NORMAL )],738 [qw(DGREEN DYELLOW NORMAL)],
618 [qw(DYELLOW BLACK NORMAL)],739 [qw(DYELLOW BLACK NORMAL)],
619 [qw(DMAGENTA BLACK NORMAL)],740 [qw(DMAGENTA BLACK NORMAL)],
620 [qw(DCYAN DBLUE NORMAL)],741 [qw(DCYAN DBLUE NORMAL)],
621 # for dark backgrounds742 # for dark backgrounds
622 [qw(WHITE GREY NORMAL)],743 [qw(WHITE GREY NORMAL)],
623 [qw(GREY WHITE NORMAL)],744 [qw(GREY WHITE NORMAL)],
624 [qw(CYAN GREY NORMAL )],745 [qw(CYAN GREY NORMAL)],
625 [qw(GREEN WHITE NORMAL )],746 [qw(GREEN WHITE NORMAL)],
626 [qw(GREEN YELLOW NORMAL )],747 [qw(GREEN YELLOW NORMAL)],
627 [qw(YELLOW WHITE NORMAL )],748 [qw(YELLOW WHITE NORMAL)],
628 [qw(MAGENTA CYAN NORMAL )],749 [qw(MAGENTA CYAN NORMAL)],
629 [qw(MAGENTA YELLOW NORMAL)],750 [qw(MAGENTA YELLOW NORMAL)],
630 [qw(RED CYAN NORMAL)],751 [qw(RED CYAN NORMAL)],
631 [qw(RED WHITE NORMAL )],752 [qw(RED WHITE NORMAL)],
632 [qw(BLUE WHITE NORMAL)],753 [qw(BLUE WHITE NORMAL)],
633 # miscellaneous754 # miscellaneous
634 [qw(RED BLUE NORMAL )],755 [qw(RED BLUE NORMAL)],
635 [qw(RED DBLUE NORMAL)],756 [qw(RED DBLUE NORMAL)],
636 [qw(BLACK BLUE NORMAL)],757 [qw(BLACK BLUE NORMAL)],
637 [qw(BLACK DBLUE NORMAL)],758 [qw(BLACK DBLUE NORMAL)],
638 [qw(NORMAL BLUE NORMAL)],759 [qw(NORMAL BLUE NORMAL)],
639 [qw(BLUE MAGENTA NORMAL)],760 [qw(BLUE MAGENTA NORMAL)],
640 [qw(DBLUE MAGENTA NORMAL)],761 [qw(DBLUE MAGENTA NORMAL)],
641 [qw(BLACK MAGENTA NORMAL)],762 [qw(BLACK MAGENTA NORMAL)],
642 [qw(MAGENTA BLUE NORMAL)],763 [qw(MAGENTA BLUE NORMAL)],
643 [qw(MAGENTA DBLUE NORMAL)],764 [qw(MAGENTA DBLUE NORMAL)],
644 );765 );
645 if ($type eq 'count' ){766 eval $end if $b_log;
646 return scalar @color_schemes;767 if ($type eq 'count'){
647 }768 return scalar @color_schemes;
648 if ($type eq 'full' ){769 }
649 return @color_schemes;770 if ($type eq 'full'){
650 }771 return @color_schemes;
651 else {772 }
652 return @{$color_schemes[$type]};773 else {
653 # print Dumper $color_schemes[$scheme_nu];774 return @{$color_schemes[$type]};
654 }775 # print Dumper $color_schemes[$scheme_nu];
655 eval $end if $b_log;776 }
656}777}
657778
658sub set_color_scheme {779sub set_color_scheme {
659 eval $start if $b_log;780 eval $start if $b_log;
660 my ($scheme) = @_;781 my ($scheme) = @_;
661 $colors{'scheme'} = $scheme;782 $colors{'scheme'} = $scheme;
662 my $index = ( $b_irc ) ? 1 : 0; # defaults to non irc783 my $index = ($b_irc) ? 1 : 0; # defaults to non irc
663 784
664 # NOTE: qw(...) kills the escape, it is NOT the same as using 785 # NOTE: qw(...) kills the escape, it is NOT the same as using
665 # Literal "..", ".." despite docs saying it is.786 # Literal "..", ".." despite docs saying it is.
666 my %color_palette = (787 my %color_palette = (
667 'EMPTY' => [ '', '' ],788 'EMPTY' => [ '', '' ],
668 'DGREY' => [ "\e[1;30m", "\x0314" ],789 'DGREY' => [ "\e[1;30m", "\x0314" ],
669 'BLACK' => [ "\e[0;30m", "\x0301" ],790 'BLACK' => [ "\e[0;30m", "\x0301" ],
670 'RED' => [ "\e[1;31m", "\x0304" ],791 'RED' => [ "\e[1;31m", "\x0304" ],
671 'DRED' => [ "\e[0;31m", "\x0305" ],792 'DRED' => [ "\e[0;31m", "\x0305" ],
672 'GREEN' => [ "\e[1;32m", "\x0309" ],793 'GREEN' => [ "\e[1;32m", "\x0309" ],
673 'DGREEN' => [ "\e[0;32m", "\x0303" ],794 'DGREEN' => [ "\e[0;32m", "\x0303" ],
674 'YELLOW' => [ "\e[1;33m", "\x0308" ],795 'YELLOW' => [ "\e[1;33m", "\x0308" ],
675 'DYELLOW' => [ "\e[0;33m", "\x0307" ],796 'DYELLOW' => [ "\e[0;33m", "\x0307" ],
676 'BLUE' => [ "\e[1;34m", "\x0312" ],797 'BLUE' => [ "\e[1;34m", "\x0312" ],
677 'DBLUE' => [ "\e[0;34m", "\x0302" ],798 'DBLUE' => [ "\e[0;34m", "\x0302" ],
678 'MAGENTA' => [ "\e[1;35m", "\x0313" ],799 'MAGENTA' => [ "\e[1;35m", "\x0313" ],
679 'DMAGENTA' => [ "\e[0;35m", "\x0306" ],800 'DMAGENTA' => [ "\e[0;35m", "\x0306" ],
680 'CYAN' => [ "\e[1;36m", "\x0311" ],801 'CYAN' => [ "\e[1;36m", "\x0311" ],
681 'DCYAN' => [ "\e[0;36m", "\x0310" ],802 'DCYAN' => [ "\e[0;36m", "\x0310" ],
682 'WHITE' => [ "\e[1;37m", "\x0300" ],803 'WHITE' => [ "\e[1;37m", "\x0300" ],
683 'GREY' => [ "\e[0;37m", "\x0315" ],804 'GREY' => [ "\e[0;37m", "\x0315" ],
684 'NORMAL' => [ "\e[0m", "\x03" ],805 'NORMAL' => [ "\e[0m", "\x03" ],
685 );806 );
686 my @scheme = get_color_scheme($colors{'scheme'});807 my @scheme = get_color_scheme($colors{'scheme'});
687 $colors{'c1'} = $color_palette{$scheme[0]}[$index];808 $colors{'c1'} = $color_palette{$scheme[0]}->[$index];
688 $colors{'c2'} = $color_palette{$scheme[1]}[$index];809 $colors{'c2'} = $color_palette{$scheme[1]}->[$index];
689 $colors{'cn'} = $color_palette{$scheme[2]}[$index];810 $colors{'cn'} = $color_palette{$scheme[2]}->[$index];
690 # print Dumper \@scheme;811 # print Dumper \@scheme;
691 # print "$colors{'c1'}here$colors{'c2'} we are!$colors{'cn'}\n";812 # print "$colors{'c1'}here$colors{'c2'} we are!$colors{'cn'}\n";
692 eval $end if $b_log;813 eval $end if $b_log;
693}814}
694815
695sub set_colors {816sub set_colors {
696 eval $start if $b_log;817 eval $start if $b_log;
697 # it's already been set with -c 0-43818 # it's already been set with -c 0-43
698 if ( exists $colors{'c1'} ){819 if (exists $colors{'c1'}){
699 return 1;820 return 1;
700 }821 }
701 # This let's user pick their color scheme. For IRC, only shows the color schemes, 822 # This let's user pick their color scheme. For IRC, only shows the color
702 # no interactive. The override value only will be placed in user config files. 823 # schemes, no interactive. The override value only will be placed in user
703 # /etc/inxi.conf can also override824 # config files. /etc/inxi.conf can also override
704 if (exists $colors{'selector'}){825 if (exists $colors{'selector'}){
705 my $ob_selector = SelectColors->new($colors{'selector'});826 my $ob_selector = SelectColors->new($colors{'selector'});
706 $ob_selector->select_schema();827 $ob_selector->select_schema();
707 return 1;828 return 1;
708 }829 }
709 # set the default, then override as required830 # set the default, then override as required
710 my $color_scheme = $colors{'default'};831 my $color_scheme = $colors{'default'};
711 # these are set in user configs832 # these are set in user configs
712 if (defined $colors{'global'}){833 if (defined $colors{'global'}){
713 $color_scheme = $colors{'global'};834 $color_scheme = $colors{'global'};
714 }835 }
715 else {836 else {
716 if ( $b_irc ){837 if ($b_irc){
717 if (defined $colors{'irc-virt-term'} && $b_display && $client{'console-irc'}){838 if (defined $colors{'irc-virt-term'} && $b_display && $client{'console-irc'}){
718 $color_scheme = $colors{'irc-virt-term'};839 $color_scheme = $colors{'irc-virt-term'};
719 }840 }
720 elsif (defined $colors{'irc-console'} && !$b_display){841 elsif (defined $colors{'irc-console'} && !$b_display){
721 $color_scheme = $colors{'irc-console'};842 $color_scheme = $colors{'irc-console'};
722 }843 }
723 elsif ( defined $colors{'irc-gui'}) {844 elsif (defined $colors{'irc-gui'}){
724 $color_scheme = $colors{'irc-gui'};845 $color_scheme = $colors{'irc-gui'};
725 }846 }
726 }847 }
727 else {848 else {
728 if (defined $colors{'console'} && !$b_display){849 if (defined $colors{'console'} && !$b_display){
729 $color_scheme = $colors{'console'};850 $color_scheme = $colors{'console'};
730 }851 }
731 elsif (defined $colors{'virt-term'}){852 elsif (defined $colors{'virt-term'}){
732 $color_scheme = $colors{'virt-term'};853 $color_scheme = $colors{'virt-term'};
733 }854 }
734 }855 }
735 }856 }
736 # force 0 for | or > output, all others prints to irc or screen857 # force 0 for | or > output, all others prints to irc or screen
737 if (!$b_irc && ! -t STDOUT ){858 if (!$b_irc && ! -t STDOUT){
738 $color_scheme = 0;859 $color_scheme = 0;
739 }860 }
740 set_color_scheme($color_scheme);861 set_color_scheme($color_scheme);
741 eval $end if $b_log;862 eval $end if $b_log;
742}863}
743864
744## SelectColors865## SelectColors
745{866{
746package SelectColors;867package SelectColors;
747868my (@data,%configs,%status);
748# use warnings;
749# use strict;
750# use diagnostics;
751# use 5.008;
752
753my (@data,@rows,%configs,%status);
754my ($type,$w_fh);869my ($type,$w_fh);
755my $safe_color_count = 12; # null/normal + default color group870my $safe_color_count = 12; # null/normal + default color group
756my $count = 0;871my $count = 0;
757
758# args: 1 - type872# args: 1 - type
759sub new {873sub new {
760 my $class = shift;874 my $class = shift;
761 ($type) = @_;875 ($type) = @_;
762 my $self = {};876 my $self = {};
763 return bless $self, $class;877 return bless $self, $class;
764}878}
765sub select_schema {879sub select_schema {
766 eval $start if $b_log;880 eval $start if $b_log;
767 assign_selectors();881 assign_selectors();
768 main::set_color_scheme(0);882 main::set_color_scheme(0);
769 set_status();883 set_status();
770 start_selector();884 start_selector();
771 create_color_selections();885 create_color_selections();
772 if (! $b_irc ){886 if (!$b_irc){
773 main::check_config_file();887 Configs::check_file();
774 get_selection();888 get_selection();
775 }889 }
776 else {890 else {
777 print_irc_message();891 print_irc_message();
778 }892 }
779 eval $end if $b_log;893 eval $end if $b_log;
780}894}
781895
782sub set_status {896sub set_status {
783 $status{'console'} = (defined $colors{'console'}) ? "Set: $colors{'console'}" : 'Not Set';897 $status{'console'} = (defined $colors{'console'}) ? "Set: $colors{'console'}" : 'Not Set';
784 $status{'virt-term'} = (defined $colors{'virt-term'}) ? "Set: $colors{'virt-term'}" : 'Not Set';898 $status{'virt-term'} = (defined $colors{'virt-term'}) ? "Set: $colors{'virt-term'}" : 'Not Set';
785 $status{'irc-console'} = (defined $colors{'irc-console'}) ? "Set: $colors{'irc-console'}" : 'Not Set';899 $status{'irc-console'} = (defined $colors{'irc-console'}) ? "Set: $colors{'irc-console'}" : 'Not Set';
786 $status{'irc-gui'} = (defined $colors{'irc-gui'}) ? "Set: $colors{'irc-gui'}" : 'Not Set';900 $status{'irc-gui'} = (defined $colors{'irc-gui'}) ? "Set: $colors{'irc-gui'}" : 'Not Set';
787 $status{'irc-virt-term'} = (defined $colors{'irc-virt-term'}) ? "Set: $colors{'irc-virt-term'}" : 'Not Set';901 $status{'irc-virt-term'} = (defined $colors{'irc-virt-term'}) ? "Set: $colors{'irc-virt-term'}" : 'Not Set';
788 $status{'global'} = (defined $colors{'global'}) ? "Set: $colors{'global'}" : 'Not Set';902 $status{'global'} = (defined $colors{'global'}) ? "Set: $colors{'global'}" : 'Not Set';
789}903}
790904
791sub assign_selectors {905sub assign_selectors {
792 if ($type == 94){906 if ($type == 94){
793 $configs{'variable'} = 'CONSOLE_COLOR_SCHEME';907 $configs{'variable'} = 'CONSOLE_COLOR_SCHEME';
794 $configs{'selection'} = 'console';908 $configs{'selection'} = 'console';
795 }909 }
796 elsif ($type == 95){910 elsif ($type == 95){
797 $configs{'variable'} = 'VIRT_TERM_COLOR_SCHEME';911 $configs{'variable'} = 'VIRT_TERM_COLOR_SCHEME';
798 $configs{'selection'} = 'virt-term';912 $configs{'selection'} = 'virt-term';
799 }913 }
800 elsif ($type == 96){914 elsif ($type == 96){
801 $configs{'variable'} = 'IRC_COLOR_SCHEME';915 $configs{'variable'} = 'IRC_COLOR_SCHEME';
802 $configs{'selection'} = 'irc-gui';916 $configs{'selection'} = 'irc-gui';
803 }917 }
804 elsif ($type == 97){918 elsif ($type == 97){
805 $configs{'variable'} = 'IRC_X_TERM_COLOR_SCHEME';919 $configs{'variable'} = 'IRC_X_TERM_COLOR_SCHEME';
806 $configs{'selection'} = 'irc-virt-term';920 $configs{'selection'} = 'irc-virt-term';
807 }921 }
808 elsif ($type == 98){922 elsif ($type == 98){
809 $configs{'variable'} = 'IRC_CONS_COLOR_SCHEME';923 $configs{'variable'} = 'IRC_CONS_COLOR_SCHEME';
810 $configs{'selection'} = 'irc-console';924 $configs{'selection'} = 'irc-console';
811 }925 }
812 elsif ($type == 99){926 elsif ($type == 99){
813 $configs{'variable'} = 'GLOBAL_COLOR_SCHEME';927 $configs{'variable'} = 'GLOBAL_COLOR_SCHEME';
814 $configs{'selection'} = 'global';928 $configs{'selection'} = 'global';
815 }929 }
816}930}
817sub start_selector {931sub start_selector {
818 my $whoami = getpwuid($<) || "unknown???";932 my $whoami = getpwuid($<) || "unknown???";
819 if ( ! $b_irc ){933 if (!$b_irc){
820 @data = (934 @data = (
821 [ 0, '', '', "Welcome to $self_name! Please select the default 935 [ 0, '', '', "Welcome to $self_name! Please select the default
822 $configs{'selection'} color scheme."],936 $configs{'selection'} color scheme."],
823 );937 );
824 }938 }
825 @rows = (939 push(@data,
826 [ 0, '', '', "Because there is no way to know your $configs{'selection'}940 [ 0, '', '', "Because there is no way to know your $configs{'selection'}
827 foreground/background colors, you can set your color preferences from 941 foreground/background colors, you can set your color preferences from
828 color scheme option list below:"],942 color scheme option list below:"],
829 [ 0, '', '', "0 is no colors; 1 is neutral."],943 [ 0, '', '', "0 is no colors; 1 is neutral."],
830 [ 0, '', '', "After these, there are 4 sets:"],944 [ 0, '', '', "After these, there are 4 sets:"],
831 [ 0, '', '', "1-dark^or^light^backgrounds; 2-light^backgrounds; 945 [ 0, '', '', "1-dark^or^light^backgrounds; 2-light^backgrounds;
832 3-dark^backgrounds; 4-miscellaneous"],946 3-dark^backgrounds; 4-miscellaneous"],
833 [ 0, '', '', ""],947 [ 0, '', '', ""],
834 );948 );
835 push @data, @rows;949 if (!$b_irc){
836 if ( ! $b_irc ){950 push(@data,
837 @rows = (951 [ 0, '', '', "Please note that this will set the $configs{'selection'}
838 [ 0, '', '', "Please note that this will set the $configs{'selection'} 952 preferences only for user: $whoami"],
839 preferences only for user: $whoami"],953 );
840 );954 }
841 push @data, @rows;955 push(@data,
842 }956 [ 0, '', '', "$line1"],
843 @rows = (957 );
844 [ 0, '', '', "$line1"],958 main::print_basic(\@data);
845 );959 @data = ();
846 push @data, @rows;
847 main::print_basic(@data);
848 @data = ();
849}960}
850sub create_color_selections {961sub create_color_selections {
851 my $spacer = '^^'; # printer removes double spaces, but replaces ^ with ' '962 my $spacer = '^^'; # printer removes double spaces, but replaces ^ with ' '
852 $count = ( main::get_color_scheme('count') - 1 );963 $count = (main::get_color_scheme('count') - 1);
853 for my $i (0 .. $count){964 foreach my $i (0 .. $count){
854 if ($i > 9){965 if ($i > 9){
855 $spacer = '^';966 $spacer = '^';
856 }967 }
857 if ($configs{'selection'} =~ /^(global|irc-gui|irc-console|irc-virt-term)$/ && $i > $safe_color_count ){968 if ($configs{'selection'} =~ /^(global|irc-gui|irc-console|irc-virt-term)$/ && $i > $safe_color_count){
858 last;969 last;
859 }970 }
860 main::set_color_scheme($i);971 main::set_color_scheme($i);
861 @rows = (972 push(@data,
862 [0, '', '', "$i)$spacer$colors{'c1'}Card:$colors{'c2'}^nVidia^GT218 973 [0, '', '', "$i)$spacer$colors{'c1'}Card:$colors{'c2'}^nVidia^GT218
863 $colors{'c1'}Display^Server$colors{'c2'}^x11^(X.Org^1.7.7)$colors{'cn'}"],974 $colors{'c1'}Display^Server$colors{'c2'}^x11^(X.Org^1.7.7)$colors{'cn'}"],
864 );975 );
865 push @data, @rows;976 }
866 }977 main::print_basic(\@data);
867 main::print_basic(@data); 978 @data = ();
868 @data = ();979 main::set_color_scheme(0);
869 main::set_color_scheme(0);
870}980}
871sub get_selection {981sub get_selection {
872 my $number = $count + 1;982 my $number = $count + 1;
873 @data = (983 @data = (
874 [0, '', '', ($number++) . ")^Remove all color settings. Restore $self_name default."],984 [0, '', '', ($number++) . ")^Remove all color settings. Restore $self_name default."],
875 [0, '', '', ($number++) . ")^Continue, no changes or config file setting."],985 [0, '', '', ($number++) . ")^Continue, no changes or config file setting."],
876 [0, '', '', ($number++) . ")^Exit, use another terminal, or set manually."],986 [0, '', '', ($number++) . ")^Exit, use another terminal, or set manually."],
877 [0, '', '', "$line1"],987 [0, '', '', "$line1"],
878 [0, '', '', "Simply type the number for the color scheme that looks best to your 988 [0, '', '', "Simply type the number for the color scheme that looks best to your
879 eyes for your $configs{'selection'} settings and hit <ENTER>. NOTE: You can bring this 989 eyes for your $configs{'selection'} settings and hit <ENTER>. NOTE: You can bring this
880 option list up by starting $self_name with option: -c plus one of these numbers:"],990 option list up by starting $self_name with option: -c plus one of these numbers:"],
881 [0, '', '', "94^-^console,^not^in^desktop^-^$status{'console'}"],991 [0, '', '', "94^-^console,^not^in^desktop^-^$status{'console'}"],
882 [0, '', '', "95^-^terminal,^desktop^-^$status{'virt-term'}"],992 [0, '', '', "95^-^terminal,^desktop^-^$status{'virt-term'}"],
883 [0, '', '', "96^-^irc,^gui,^desktop^-^$status{'irc-gui'}"],993 [0, '', '', "96^-^irc,^gui,^desktop^-^$status{'irc-gui'}"],
884 [0, '', '', "97^-^irc,^desktop,^in^terminal^-^$status{'irc-virt-term'}"],994 [0, '', '', "97^-^irc,^desktop,^in^terminal^-^$status{'irc-virt-term'}"],
885 [0, '', '', "98^-^irc,^not^in^desktop^-^$status{'irc-console'}"],995 [0, '', '', "98^-^irc,^not^in^desktop^-^$status{'irc-console'}"],
886 [0, '', '', "99^-^global^-^$status{'global'}"],996 [0, '', '', "99^-^global^-^$status{'global'}"],
887 [0, '', '', ""],997 [0, '', '', ""],
888 [0, '', '', "Your selection(s) will be stored here: $user_config_file"],998 [0, '', '', "Your selection(s) will be stored here: $user_config_file"],
889 [0, '', '', "Global overrides all individual color schemes. Individual 999 [0, '', '', "Global overrides all individual color schemes. Individual
890 schemes remove the global setting."],1000 schemes remove the global setting."],
891 [0, '', '', "$line1"],1001 [0, '', '', "$line1"],
892 );1002 );
893 main::print_basic(@data); 1003 main::print_basic(\@data);
894 @data = ();1004 @data = ();
895 my $response = <STDIN>;1005 my $response = <STDIN>;
896 chomp $response;1006 chomp($response);
897 if (!main::is_int($response) || $response > ($count + 3) ){1007 if (!main::is_int($response) || $response > ($count + 3)){
898 @data = (1008 @data = (
899 [0, '', '', "Error - Invalid Selection. You entered this: $response. Hit <ENTER> to continue."],1009 [0, '', '', "Error - Invalid Selection. You entered this: $response. Hit <ENTER> to continue."],
900 [0, '', '', "$line1"],1010 [0, '', '', "$line1"],
901 );1011 );
902 main::print_basic(@data); 1012 main::print_basic(\@data);
903 my $response = <STDIN>;1013 my $response = <STDIN>;
904 start_selector();1014 start_selector();
905 create_color_selections();1015 create_color_selections();
906 get_selection();1016 get_selection();
907 }1017 }
908 else {1018 else {
909 process_selection($response);1019 process_selection($response);
910 }1020 }
1021 if ($b_pledge){
1022 @pledges = grep {$_ ne 'getpw'} @pledges;
1023 OpenBSD::Pledge::pledge(@pledges);
1024 }
911}1025}
912sub process_selection {1026sub process_selection {
913 my $response = shift;1027 my $response = shift;
914 if ($response == ($count + 3) ){1028 if ($response == ($count + 3)){
915 @data = ([0, '', '', "Ok, exiting $self_name now. You can set the colors later."],);1029 @data = (
916 main::print_basic(@data); 1030 [0, '', '', "Ok, exiting $self_name now. You can set the colors later."],
917 exit 0;1031 );
918 }1032 main::print_basic(\@data);
919 elsif ($response == ($count + 2)){1033 exit 0;
920 @data = (1034 }
921 [0, '', '', "Ok, continuing $self_name unchanged."],1035 elsif ($response == ($count + 2)){
922 [0, '', '', "$line1"],1036 @data = (
923 );1037 [0, '', '', "Ok, continuing $self_name unchanged."],
924 main::print_basic(@data); 1038 [0, '', '', "$line1"],
925 if ( defined $colors{'console'} && !$b_display ){1039 );
926 main::set_color_scheme($colors{'console'});1040 main::print_basic(\@data);
927 }1041 if (defined $colors{'console'} && !$b_display){
928 if ( defined $colors{'virt-term'} ){1042 main::set_color_scheme($colors{'console'});
929 main::set_color_scheme($colors{'virt-term'});1043 }
930 }1044 if (defined $colors{'virt-term'}){
931 else {1045 main::set_color_scheme($colors{'virt-term'});
932 main::set_color_scheme($colors{'default'});1046 }
933 }1047 else {
934 }1048 main::set_color_scheme($colors{'default'});
935 elsif ($response == ($count + 1)){1049 }
936 @data = (1050 }
937 [0, '', '', "Removing all color settings from config file now..."],1051 elsif ($response == ($count + 1)){
938 [0, '', '', "$line1"],1052 @data = (
939 );1053 [0, '', '', "Removing all color settings from config file now..."],
940 main::print_basic(@data); 1054 [0, '', '', "$line1"],
941 delete_all_config_colors();1055 );
942 main::set_color_scheme($colors{'default'});1056 main::print_basic(\@data);
943 }1057 delete_all_config_colors();
944 else {1058 main::set_color_scheme($colors{'default'});
945 main::set_color_scheme($response);1059 }
946 @data = (1060 else {
947 [0, '', '', "Updating config file for $configs{'selection'} color scheme now..."],1061 main::set_color_scheme($response);
948 [0, '', '', "$line1"],1062 @data = (
949 );1063 [0, '', '', "Updating config file for $configs{'selection'} color scheme now..."],
950 main::print_basic(@data); 1064 [0, '', '', "$line1"],
951 if ($configs{'selection'} eq 'global'){1065 );
952 delete_all_colors();1066 main::print_basic(\@data);
953 }1067 if ($configs{'selection'} eq 'global'){
954 else {1068 delete_all_colors();
955 delete_global_color();1069 }
956 }1070 else {
957 set_config_color_scheme($response);1071 delete_global_color();
958 }1072 }
1073 set_config_color_scheme($response);
1074 }
959}1075}
960sub delete_all_colors {1076sub delete_all_colors {
961 my @file_lines = main::reader( $user_config_file );1077 my @file_lines = main::reader($user_config_file);
962 open( $w_fh, '>', $user_config_file ) or error_handler('open', $user_config_file, $!);1078 open($w_fh, '>', $user_config_file) or main::error_handler('open', $user_config_file, $!);
963 foreach ( @file_lines ) { 1079 foreach (@file_lines){
964 if ( $_ !~ /^(CONSOLE_COLOR_SCHEME|GLOBAL_COLOR_SCHEME|IRC_COLOR_SCHEME|IRC_CONS_COLOR_SCHEME|IRC_X_TERM_COLOR_SCHEME|VIRT_TERM_COLOR_SCHEME)/){1080 if ($_ !~ /^(CONSOLE_COLOR_SCHEME|GLOBAL_COLOR_SCHEME|IRC_COLOR_SCHEME|IRC_CONS_COLOR_SCHEME|IRC_X_TERM_COLOR_SCHEME|VIRT_TERM_COLOR_SCHEME)/){
965 print {$w_fh} "$_"; 1081 print {$w_fh} "$_";
966 }1082 }
967 } 1083 }
968 close $w_fh;1084 close $w_fh;
969}1085}
970sub delete_global_color {1086sub delete_global_color {
971 my @file_lines = main::reader( $user_config_file );1087 my @file_lines = main::reader($user_config_file);
972 open( $w_fh, '>', $user_config_file ) or error_handler('open', $user_config_file, $!);1088 open($w_fh, '>', $user_config_file) or main::error_handler('open', $user_config_file, $!);
973 foreach ( @file_lines ) { 1089 foreach (@file_lines){
974 if ( $_ !~ /^GLOBAL_COLOR_SCHEME/){1090 if ($_ !~ /^GLOBAL_COLOR_SCHEME/){
975 print {$w_fh} "$_"; 1091 print {$w_fh} "$_";
976 }1092 }
977 } 1093 }
978 close $w_fh;1094 close $w_fh;
979}1095}
980sub set_config_color_scheme {1096sub set_config_color_scheme {
981 my $value = shift;1097 my $value = shift;
982 my @file_lines = main::reader( $user_config_file );1098 my @file_lines = main::reader($user_config_file);
983 my $b_found = 0;1099 my $b_found = 0;
984 open( $w_fh, '>', $user_config_file ) or error_handler('open', $user_config_file, $!);1100 open($w_fh, '>', $user_config_file) or main::error_handler('open', $user_config_file, $!);
985 foreach ( @file_lines ) { 1101 foreach (@file_lines){
986 if ( $_ =~ /^$configs{'variable'}/ ){1102 if ($_ =~ /^$configs{'variable'}/){
987 $_ = "$configs{'variable'}=$value";1103 $_ = "$configs{'variable'}=$value";
988 $b_found = 1;1104 $b_found = 1;
989 }1105 }
990 print $w_fh "$_\n";1106 print $w_fh "$_\n";
991 }1107 }
992 if (! $b_found ){1108 if (!$b_found){
993 print $w_fh "$configs{'variable'}=$value\n";1109 print $w_fh "$configs{'variable'}=$value\n";
994 }1110 }
995 close $w_fh;1111 close $w_fh;
996}1112}
9971113
998sub print_irc_message {1114sub print_irc_message {
999 @data = (1115 @data = (
1000 [ 0, '', '', "$line1"],1116 [ 0, '', '', "$line1"],
1001 [ 0, '', '', "After finding the scheme number you like, simply run this again1117 [ 0, '', '', "After finding the scheme number you like, simply run this again
1002 in a terminal to set the configuration data file for your irc client. You can 1118 in a terminal to set the configuration data file for your irc client. You can
1003 set color schemes for the following: start inxi with -c plus:"],1119 set color schemes for the following: start inxi with -c plus:"],
1004 [ 0, '', '', "94 (console,^not^in^desktop^-^$status{'console'})"],1120 [ 0, '', '', "94 (console,^not^in^desktop^-^$status{'console'})"],
1005 [ 0, '', '', "95 (terminal, desktop^-^$status{'virt-term'})"],1121 [ 0, '', '', "95 (terminal, desktop^-^$status{'virt-term'})"],
1006 [ 0, '', '', "96 (irc,^gui,^desktop^-^$status{'irc-gui'})"],1122 [ 0, '', '', "96 (irc,^gui,^desktop^-^$status{'irc-gui'})"],
1007 [ 0, '', '', "97 (irc,^desktop,^in terminal^-^$status{'irc-virt-term'})"],1123 [ 0, '', '', "97 (irc,^desktop,^in terminal^-^$status{'irc-virt-term'})"],
1008 [ 0, '', '', "98 (irc,^not^in^desktop^-^$status{'irc-console'})"],1124 [ 0, '', '', "98 (irc,^not^in^desktop^-^$status{'irc-console'})"],
1009 [ 0, '', '', "99 (global^-^$status{'global'})"]1125 [ 0, '', '', "99 (global^-^$status{'global'})"]
1010 );1126 );
1011 main::print_basic(@data); 1127 main::print_basic(\@data);
1012 exit 0;1128 exit 0;
1013}1129}
10141130
1015}1131}
@@ -1018,100 +1134,158 @@ sub print_irc_message {
1018#### CONFIGS1134#### CONFIGS
1019#### -------------------------------------------------------------------1135#### -------------------------------------------------------------------
10201136
1021sub check_config_file {1137## Configs
1022 $user_config_file = "$user_config_dir/$self_name.conf";1138# public: set() check_file()
1023 if ( ! -f $user_config_file ){1139{
1024 open( my $fh, '>', $user_config_file ) or error_handler('create', $user_config_file, $!);1140package Configs;
1025 }1141sub set {
1026}1142 my ($configs) = @_;
10271143 my ($key, $val,@config_files);
1028sub get_configs {1144 if (!$configs){
1029 my (@configs) = @_;1145 @config_files = (
1030 my ($key, $val,@config_files);1146 qq(/etc/$self_name.conf),
1031 if (!@configs){1147 qq($user_config_dir/$self_name.conf)
1032 @config_files = (1148 );
1033 qq(/etc/$self_name.conf), 1149 }
1034 qq($user_config_dir/$self_name.conf)1150 else {
1035 );1151 @config_files = @$configs;
1036 }1152 }
1037 else {1153 # Config files should be passed in an array as a param to this function.
1038 @config_files = (@configs);1154 # Default intended use: global @CONFIGS;
1039 }1155 foreach (@config_files){
1040 # Config files should be passed in an array as a param to this function.1156 next unless open(my $fh, '<', "$_");
1041 # Default intended use: global @CONFIGS;1157 while (<$fh>){
1042 foreach (@config_files) {1158 chomp;
1043 next unless open (my $fh, '<', "$_");1159 s/#.*//;
1044 while (<$fh>) {1160 s/^\s+//;
1045 chomp;1161 s/\s+$//;
1046 s/#.*//;1162 s/'|"//g;
1047 s/^\s+//;1163 s/true/1/i; # switch to 1/0 perl boolean
1048 s/\s+$//;1164 s/false/0/i; # switch to 1/0 perl boolean
1049 s/'|"//g;1165 next unless length;
1050 s/true/1/i; # switch to 1/0 perl boolean1166 ($key, $val) = split(/\s*=\s*/, $_, 2);
1051 s/false/0/i; # switch to 1/0 perl boolean1167 next unless length($val);
1052 next unless length;1168 process_item($key,$val);
1053 ($key, $val) = split(/\s*=\s*/, $_, 2);1169 # print "f: $file key: $key val: $val\n";
1054 next unless length($val);1170 }
1055 get_config_item($key,$val);1171 close $fh;
1056 # print "f: $file key: $key val: $val\n";1172 }
1057 }1173}
1058 close $fh;1174# note: someone managed to make a config file with corrupted values, so check
1059 }1175# int explicitly, don't assume it was done correctly.
1060}
1061
1062# note: someone managed to make a config file with corrupted values, so check int
1063# explicitly, don't assume it was done correctly.
1064# args: 0: key; 1: value1176# args: 0: key; 1: value
1065sub get_config_item {1177sub process_item {
1066 my ($key,$val) = @_;1178 my ($key,$val) = @_;
1067 if ($key eq 'ALLOW_UPDATE' || $key eq 'B_ALLOW_UPDATE') {$b_update = $val if is_int($val)}1179 if ($key eq 'ALLOW_UPDATE' || $key eq 'B_ALLOW_UPDATE'){
1068 elsif ($key eq 'ALLOW_WEATHER' || $key eq 'B_ALLOW_WEATHER') {$b_weather = $val if is_int($val)}1180 $use{'update'} = $val if main::is_int($val)}
1069 elsif ($key eq 'CPU_SLEEP') {$cpu_sleep = $val if is_numeric($val)}1181 elsif ($key eq 'ALLOW_WEATHER' || $key eq 'B_ALLOW_WEATHER'){
1070 elsif ($key eq 'DL_TIMEOUT') {$dl_timeout = $val if is_int($val)}1182 $use{'weather'} = $val if main::is_int($val)}
1071 elsif ($key eq 'DOWNLOADER') {1183 elsif ($key eq 'CPU_SLEEP'){
1072 if ($val =~ /^(curl|fetch|ftp|perl|wget)$/){1184 $cpu_sleep = $val if main::is_numeric($val)}
1073 # this dumps all the other data and resets %dl for only the1185 elsif ($key eq 'DL_TIMEOUT'){
1074 # desired downloader.1186 $dl_timeout = $val if main::is_int($val)}
1075 $val = set_perl_downloader($val);1187 elsif ($key eq 'DOWNLOADER'){
1076 %dl = ('dl' => $val, $val => 1);1188 if ($val =~ /^(curl|fetch|ftp|perl|wget)$/){
1077 }}1189 # this dumps all the other data and resets %dl for only the
1078 elsif ($key eq 'FILTER_STRING') {$filter_string = $val}1190 # desired downloader.
1079 elsif ($key eq 'LANGUAGE') {$language = $val if $val =~ /^(en)$/}1191 $val = main::set_perl_downloader($val);
1080 elsif ($key eq 'LIMIT') {$limit = $val if is_int($val)}1192 %dl = ('dl' => $val, $val => 1);
1081 elsif ($key eq 'OUTPUT_TYPE') {$output_type = $val if $val =~ /^(json|screen|xml)$/}1193 }}
1082 elsif ($key eq 'PARTITION_SORT') {$show{'partition-sort'} = $val if ($val =~ /^(dev-base|fs|id|label|percent-used|size|uuid|used)$/) }1194 elsif ($key eq 'FILTER_STRING'){
1083 elsif ($key eq 'PS_COUNT') {$ps_count = $val if is_int($val) }1195 $filter_string = $val}
1084 elsif ($key eq 'SENSORS_CPU_NO') {$sensors_cpu_nu = $val if is_int($val)}1196 elsif ($key eq 'LANGUAGE'){
1085 elsif ($key eq 'SHOW_HOST' || $key eq 'B_SHOW_HOST') { $show{'host'} = $val if is_int($val)}1197 $language = $val if $val =~ /^(en)$/}
1086 elsif ($key eq 'USB_SYS') {$b_usb_sys = $val if is_int($val)}1198 elsif ($key eq 'LIMIT'){
1087 elsif ($key eq 'WEATHER_UNIT') { 1199 $limit = $val if main::is_int($val)}
1088 $val = lc($val) if $val;1200 elsif ($key eq 'OUTPUT_TYPE'){
1089 if ($val && $val =~ /^(c|f|cf|fc|i|m|im|mi)$/){1201 $output_type = $val if $val =~ /^(json|screen|xml)$/}
1090 my %units = ('c'=>'m','f'=>'i','cf'=>'mi','fc'=>'im');1202 elsif ($key eq 'NO_DIG'){
1091 $val = $units{$val} if defined $units{$val};1203 $force{'no-dig'} = $val if main::is_int($val)}
1092 $weather_unit = $val;1204 elsif ($key eq 'NO_DOAS'){
1093 }1205 $force{'no-doas'} = $val if main::is_int($val)}
1094 }1206 elsif ($key eq 'NO_HTML_WAN'){
1095 # layout1207 $force{'no-html-wan'} = $val if main::is_int($val)}
1096 elsif ($key eq 'CONSOLE_COLOR_SCHEME') {$colors{'console'} = $val if is_int($val)}1208 elsif ($key eq 'NO_SUDO'){
1097 elsif ($key eq 'GLOBAL_COLOR_SCHEME') {$colors{'global'} = $val if is_int($val)}1209 $force{'no-sudo'} = $val if main::is_int($val)}
1098 elsif ($key eq 'IRC_COLOR_SCHEME') {$colors{'irc-gui'} = $val if is_int($val)}1210 elsif ($key eq 'PARTITION_SORT'){
1099 elsif ($key eq 'IRC_CONS_COLOR_SCHEME') {$colors{'irc-console'} = $val if is_int($val)}1211 if ($val =~ /^(dev-base|fs|id|label|percent-used|size|uuid|used)$/){
1100 elsif ($key eq 'IRC_X_TERM_COLOR_SCHEME') {$colors{'irc-virt-term'} = $val if is_int($val)}1212 $show{'partition-sort'} = $val;
1101 elsif ($key eq 'VIRT_TERM_COLOR_SCHEME') {$colors{'virt-term'} = $val if is_int($val)}1213 }}
1102 # note: not using the old short SEP1/SEP21214 elsif ($key eq 'PS_COUNT'){
1103 elsif ($key eq 'SEP1_IRC') {$sep{'s1-irc'} = $val}1215 $ps_count = $val if main::is_int($val) }
1104 elsif ($key eq 'SEP1_CONSOLE') {$sep{'s1-console'} = $val}1216 elsif ($key eq 'SENSORS_CPU_NO'){
1105 elsif ($key eq 'SEP2_IRC') {$sep{'s2-irc'} = $val}1217 $sensors_cpu_nu = $val if main::is_int($val)}
1106 elsif ($key eq 'SEP2_CONSOLE') {$sep{'s2-console'} = $val}1218 elsif ($key eq 'SENSORS_EXCLUDE'){
1107 # size1219 @sensors_exclude = split(/\s*,\s*/, $val) if $val}
1108 elsif ($key eq 'COLS_MAX_CONSOLE') {$size{'console'} = $val if is_int($val)}1220 elsif ($key eq 'SENSORS_USE'){
1109 elsif ($key eq 'COLS_MAX_IRC') {$size{'irc'} = $val if is_int($val)}1221 @sensors_use = split(/\s*,\s*/, $val) if $val}
1110 elsif ($key eq 'COLS_MAX_NO_DISPLAY') {$size{'no-display'} = $val if is_int($val)}1222 elsif ($key eq 'SHOW_HOST' || $key eq 'B_SHOW_HOST'){
1111 elsif ($key eq 'INDENT') {$size{'indent'} = $val if is_int($val)}1223 if (main::is_int($val)){
1112 elsif ($key eq 'INDENT_MIN') {$size{'indent-min'} = $val if is_int($val)}1224 $show{'host'} = $val;
1113 # print "mc: key: $key val: $val\n";1225 $show{'no-host'} = 1 if !$show{'host'};
1114 # print Dumper (keys %size) . "\n";1226 }
1227 }
1228 elsif ($key eq 'USB_SYS'){
1229 $force{'usb-sys'} = $val if main::is_int($val)}
1230 elsif ($key eq 'WAN_IP_URL'){
1231 if ($val =~ /^(ht|f)tp[s]?:\//i){
1232 $wan_url = $val;
1233 $force{'no-dig'} = 1;
1234 }
1235 }
1236 elsif ($key eq 'WEATHER_SOURCE'){
1237 $weather_source = $val if main::is_int($val)}
1238 elsif ($key eq 'WEATHER_UNIT'){
1239 $val = lc($val) if $val;
1240 if ($val && $val =~ /^(c|f|cf|fc|i|m|im|mi)$/){
1241 my %units = ('c'=>'m','f'=>'i','cf'=>'mi','fc'=>'im');
1242 $val = $units{$val} if defined $units{$val};
1243 $weather_unit = $val;
1244 }
1245 }
1246 # layout
1247 elsif ($key eq 'CONSOLE_COLOR_SCHEME'){
1248 $colors{'console'} = $val if main::is_int($val)}
1249 elsif ($key eq 'GLOBAL_COLOR_SCHEME'){
1250 $colors{'global'} = $val if main::is_int($val)}
1251 elsif ($key eq 'IRC_COLOR_SCHEME'){
1252 $colors{'irc-gui'} = $val if main::is_int($val)}
1253 elsif ($key eq 'IRC_CONS_COLOR_SCHEME'){
1254 $colors{'irc-console'} = $val if main::is_int($val)}
1255 elsif ($key eq 'IRC_X_TERM_COLOR_SCHEME'){
1256 $colors{'irc-virt-term'} = $val if main::is_int($val)}
1257 elsif ($key eq 'VIRT_TERM_COLOR_SCHEME'){
1258 $colors{'virt-term'} = $val if main::is_int($val)}
1259 # note: not using the old short SEP1/SEP2
1260 elsif ($key eq 'SEP1_IRC'){
1261 $sep{'s1-irc'} = $val}
1262 elsif ($key eq 'SEP1_CONSOLE'){
1263 $sep{'s1-console'} = $val}
1264 elsif ($key eq 'SEP2_IRC'){
1265 $sep{'s2-irc'} = $val}
1266 elsif ($key eq 'SEP2_CONSOLE'){
1267 $sep{'s2-console'} = $val}
1268 # size
1269 elsif ($key eq 'COLS_MAX_CONSOLE'){
1270 $size{'console'} = $val if main::is_int($val)}
1271 elsif ($key eq 'COLS_MAX_IRC'){
1272 $size{'irc'} = $val if main::is_int($val)}
1273 elsif ($key eq 'COLS_MAX_NO_DISPLAY'){
1274 $size{'no-display'} = $val if main::is_int($val)}
1275 elsif ($key eq 'INDENT'){
1276 $size{'indent'} = $val if main::is_int($val)}
1277 elsif ($key eq 'WRAP_MAX' || $key eq 'INDENT_MIN'){
1278 $size{'wrap-max'} = $val if main::is_int($val)}
1279 # print "mc: key: $key val: $val\n";
1280 # print Dumper (keys %size) . "\n";
1281}
1282sub check_file {
1283 $user_config_file = "$user_config_dir/$self_name.conf";
1284 if (! -f $user_config_file){
1285 open(my $fh, '>', $user_config_file) or
1286 main::error_handler('create', $user_config_file, $!);
1287 }
1288}
1115}1289}
11161290
1117#### -------------------------------------------------------------------1291#### -------------------------------------------------------------------
@@ -1122,40 +1296,40 @@ sub get_config_item {
1122# as soon as possible # will have max 3 files, inxi.log, inxi.1.log, 1296# as soon as possible # will have max 3 files, inxi.log, inxi.1.log,
1123# inxi.2.log1297# inxi.2.log
1124sub begin_logging {1298sub begin_logging {
1125 return 1 if $fh_l; # if we want to start logging for testing before options1299 return 1 if $fh_l; # if we want to start logging for testing before options
1126 my $log_file_2="$user_data_dir/$self_name.1.log";1300 my $log_file_2="$user_data_dir/$self_name.1.log";
1127 my $log_file_3="$user_data_dir/$self_name.2.log";1301 my $log_file_3="$user_data_dir/$self_name.2.log";
1128 my $data = '';1302 my $data = '';
1129 $end='main::log_data("fe", (caller(1))[3], "");';1303 $end='main::log_data("fe", (caller(1))[3], "");';
1130 $start='main::log_data("fs", (caller(1))[3], \@_);';1304 $start='main::log_data("fs", (caller(1))[3], \@_);';
1131 #$t3 = tv_interval ($t0, [gettimeofday]);1305 #$t3 = tv_interval ($t0, [gettimeofday]);
1132 $t3 = eval 'Time::HiRes::tv_interval (\@t0, [Time::HiRes::gettimeofday()]);' if $b_hires;1306 $t3 = eval 'Time::HiRes::tv_interval (\@t0, [Time::HiRes::gettimeofday()]);' if $b_hires;
1133 #print Dumper $@;1307 # print Dumper $@;
1134 my $now = strftime "%Y-%m-%d %H:%M:%S", localtime;1308 my $now = strftime "%Y-%m-%d %H:%M:%S", localtime;
1135 return if $debugger{'timers'};1309 return if $debugger{'timers'};
1136 # do the rotation if logfile exists1310 # do the rotation if logfile exists
1137 if ( -f $log_file ){1311 if (-f $log_file){
1138 # copy if present second to third1312 # copy if present second to third
1139 if ( -f $log_file_2 ){1313 if (-f $log_file_2){
1140 rename $log_file_2, $log_file_3 or error_handler('rename', "$log_file_2 -> $log_file_3", "$!");1314 rename $log_file_2, $log_file_3 or error_handler('rename', "$log_file_2 -> $log_file_3", "$!");
1141 }1315 }
1142 # then copy initial to second1316 # then copy initial to second
1143 rename $log_file, $log_file_2 or error_handler('rename', "$log_file -> $log_file_2", "$!");1317 rename $log_file, $log_file_2 or error_handler('rename', "$log_file -> $log_file_2", "$!");
1144 }1318 }
1145 # now create the logfile1319 # now create the logfile
1146 # print "Opening log file for reading: $log_file\n";1320 # print "Opening log file for reading: $log_file\n";
1147 open $fh_l, '>', $log_file or error_handler(4, $log_file, "$!");1321 open($fh_l, '>', $log_file) or error_handler(4, $log_file, "$!");
1148 # and echo the start data1322 # and echo the start data
1149 $data = $line2;1323 $data = $line2;
1150 $data .= "START $self_name LOGGING:\n";1324 $data .= "START $self_name LOGGING:\n";
1151 $data .= "NOTE: HiRes timer not available.\n" if !$b_hires;1325 $data .= "NOTE: HiRes timer not available.\n" if !$b_hires;
1152 $data .= "$now\n";1326 $data .= "$now\n";
1153 $data .= "Elapsed since start: $t3\n";1327 $data .= "Elapsed since start: $t3\n";
1154 $data .= "n: $self_name v: $self_version p: $self_patch d: $self_date\n";1328 $data .= "n: $self_name v: $self_version p: $self_patch d: $self_date\n";
1155 $data .= '@paths:' . joiner(\@paths, '::', 'unset') . "\n";1329 $data .= '@paths:' . joiner(\@paths, '::', 'unset') . "\n";
1156 $data .= $line2;1330 $data .= $line2;
1157 1331
1158 print $fh_l $data;1332 print $fh_l $data;
1159}1333}
11601334
1161# NOTE: no logging available until get_parameters is run, since that's what 1335# NOTE: no logging available until get_parameters is run, since that's what
@@ -1166,985 +1340,1120 @@ sub begin_logging {
1166# arg: $one type (fs/fe/cat/dump/raw) or logged data; 1340# arg: $one type (fs/fe/cat/dump/raw) or logged data;
1167# [$two is function name; [$three - function args]]1341# [$two is function name; [$three - function args]]
1168sub log_data {1342sub log_data {
1169 return if ! $b_log;1343 return if !$b_log;
1170 my ($one, $two, $three) = @_;1344 my ($one, $two, $three) = @_;
1171 my ($args,$data,$timer) = ('','','');1345 my ($args,$data,$timer) = ('','','');
1172 my $spacer = ' ';1346 my $spacer = ' ';
1173 # print "1: $one 2: $two 3: $three\n";1347 # print "1: $one 2: $two 3: $three\n";
1174 if ($one eq 'fs') {1348 if ($one eq 'fs'){
1175 if (ref $three eq 'ARRAY'){1349 if (ref $three eq 'ARRAY'){
1176 my @temp = @$three;1350 # print Data::Dumper::Dumper $three;
1177 # print Data::Dumper::Dumper \@$three;1351 $args = "\n${spacer}Args: " . joiner($three, '; ', 'unset');
1178 $args = "\n${spacer}Args: " . joiner($three, '; ', 'unset');1352 }
1179 }1353 else {
1180 else {1354 $args = "\n${spacer}Args: None";
1181 $args = "\n${spacer}Args: None";1355 }
1182 }1356 # $t1 = [gettimeofday];
1183 # $t1 = [gettimeofday];1357 #$t3 = tv_interval ($t0, [gettimeofday]);
1184 #$t3 = tv_interval ($t0, [gettimeofday]);1358 $t3 = eval 'Time::HiRes::tv_interval(\@t0, [Time::HiRes::gettimeofday()])' if $b_hires;
1185 $t3 = eval 'Time::HiRes::tv_interval(\@t0, [Time::HiRes::gettimeofday()])' if $b_hires;1359 # print Dumper $@;
1186 #print Dumper $@;1360 $data = "Start: Function: $two$args\n${spacer}Elapsed: $t3\n";
1187 $data = "Start: Function: $two$args\n${spacer}Elapsed: $t3\n";1361 $spacer='';
1188 $spacer='';1362 $timer = $data if $debugger{'timers'};
1189 $timer = $data if $debugger{'timers'};1363 }
1190 }1364 elsif ($one eq 'fe'){
1191 elsif ( $one eq 'fe') {1365 # print 'timer:', Time::HiRes::tv_interval(\@t0, [Time::HiRes::gettimeofday()]),"\n";
1192 # print 'timer:', Time::HiRes::tv_interval(\@t0, [Time::HiRes::gettimeofday()]),"\n";1366 #$t3 = tv_interval ($t0, [gettimeofday]);
1193 #$t3 = tv_interval ($t0, [gettimeofday]);1367 eval '$t3 = Time::HiRes::tv_interval(\@t0, [Time::HiRes::gettimeofday()])' if $b_hires;
1194 eval '$t3 = Time::HiRes::tv_interval(\@t0, [Time::HiRes::gettimeofday()])' if $b_hires;1368 # print Dumper $t3;
1195 #print Dumper $t3;1369 $data = "${spacer}Elapsed: $t3\nEnd: Function: $two\n";
1196 $data = "${spacer}Elapsed: $t3\nEnd: Function: $two\n";1370 $spacer='';
1197 $spacer='';1371 $timer = $data if $debugger{'timers'};
1198 $timer = $data if $debugger{'timers'};1372 }
1199 }1373 elsif ($one eq 'cat'){
1200 elsif ( $one eq 'cat') {1374 if ($b_log_full){
1201 if ( $b_log_full ){1375 foreach my $file ($two){
1202 for my $file ($two){1376 my $contents = do { local(@ARGV, $/) = $file; <> }; # or: qx(cat $file)
1203 my $contents = do { local( @ARGV, $/ ) = $file; <> }; # or: qx(cat $file)1377 $data = "$data${line3}Full file data: $file\n\n$contents\n$line3\n";
1204 $data = "$data${line3}Full file data: $file\n\n$contents\n$line3\n";1378 }
1205 }1379 $spacer='';
1206 $spacer='';1380 }
1207 }1381 }
1208 }1382 elsif ($one eq 'cmd'){
1209 elsif ($one eq 'cmd'){1383 $data = "Command: $two\n";
1210 $data = "Command: $two\n";1384 $data .= qx($two);
1211 $data .= qx($two);1385 }
1212 }1386 elsif ($one eq 'data'){
1213 elsif ($one eq 'data'){1387 $data = "$two\n";
1214 $data = "$two\n";1388 }
1215 }1389 elsif ($one eq 'dump'){
1216 elsif ( $one eq 'dump') {1390 $data = "$two:\n";
1217 $data = "$two:\n";1391 if (ref $three eq 'HASH'){
1218 if (ref $three eq 'HASH'){1392 $data .= Data::Dumper::Dumper $three;
1219 $data .= Data::Dumper::Dumper \%$three;1393 }
1220 }1394 elsif (ref $three eq 'ARRAY'){
1221 elsif (ref $three eq 'ARRAY'){1395 # print Data::Dumper::Dumper $three;
1222 # print Data::Dumper::Dumper \@$three;1396 $data .= Data::Dumper::Dumper $three;
1223 $data .= Data::Dumper::Dumper \@$three;1397 }
1224 }1398 else {
1225 else {1399 $data .= Data::Dumper::Dumper $three;
1226 $data .= Data::Dumper::Dumper $three;1400 }
1227 }1401 $data .= "\n";
1228 $data .= "\n";1402 # print $data;
1229 # print $data;1403 }
1230 }1404 elsif ($one eq 'raw'){
1231 elsif ( $one eq 'raw') {1405 if ($b_log_full){
1232 if ( $b_log_full ){1406 $data = "\n${line3}Raw System Data:\n\n$two\n$line3";
1233 $data = "\n${line3}Raw System Data:\n\n$two\n$line3";1407 $spacer='';
1234 $spacer='';1408 }
1235 }1409 }
1236 }1410 else {
1237 else {1411 $data = "$two\n";
1238 $data = "$two\n";1412 }
1239 }1413 if ($debugger{'timers'}){
1240 if ($debugger{'timers'}){1414 print $timer if $timer;
1241 print $timer if $timer;1415 }
1242 }1416 # print "d: $data";
1243 #print "d: $data";1417 elsif ($data){
1244 elsif ($data){1418 print $fh_l "$spacer$data";
1245 print $fh_l "$spacer$data";1419 }
1246 }
1247}1420}
12481421
1249sub set_debugger {1422sub set_debugger {
1250 user_debug_test_1() if $debugger{'test-1'};1423 user_debug_test_1() if $debugger{'test-1'};
1251 if ( $debug >= 20){1424 if ($debugger{'level'} >= 20){
1252 error_handler('not-in-irc', 'debug data generator') if $b_irc;1425 error_handler('not-in-irc', 'debug data generator') if $b_irc;
1253 my $option = ( $debug > 22 ) ? 'main-full' : 'main';1426 my $option = ($debugger{'level'} > 22) ? 'main-full' : 'main';
1254 $debugger{'gz'} = 1 if ($debug == 22 || $debug == 24);1427 $debugger{'gz'} = 1 if ($debugger{'level'} == 22 || $debugger{'level'} == 24);
1255 my $ob_sys = SystemDebugger->new($option);1428 my $ob_sys = SystemDebugger->new($option);
1256 $ob_sys->run_debugger();1429 $ob_sys->run_debugger();
1257 $ob_sys->upload_file($ftp_alt) if $debug > 20;1430 $ob_sys->upload_file($ftp_alt) if $debugger{'level'} > 20;
1258 exit 0;1431 exit 0;
1259 }1432 }
1260 elsif ($debug >= 10 && $debug <= 12){1433 elsif ($debugger{'level'} >= 10 && $debugger{'level'} <= 12){
1261 $b_log = 1;1434 $b_log = 1;
1262 if ($debug == 11){1435 if ($debugger{'level'} == 11){
1263 $b_log_full = 1;1436 $b_log_full = 1;
1264 }1437 }
1265 elsif ($debug == 12){1438 elsif ($debugger{'level'} == 12){
1266 $b_log_colors = 1;1439 $b_log_colors = 1;
1267 }1440 }
1268 begin_logging();1441 begin_logging();
1269 }1442 }
1270 elsif ($debug <= 3){1443 elsif ($debugger{'level'} <= 3){
1271 if ($debug == 3){1444 if ($debugger{'level'} == 3){
1272 $b_log = 1;1445 $b_log = 1;
1273 $debugger{'timers'} = 1;1446 $debugger{'timers'} = 1;
1274 begin_logging();1447 begin_logging();
1275 }1448 }
1276 else {1449 else {
1277 $end = '';1450 $end = '';
1278 $start = '';1451 $start = '';
1279 }1452 }
1280 }1453 }
1281}1454}
12821455
1283## SystemDebugger1456## SystemDebugger
1284{1457{
1285package SystemDebugger;1458package SystemDebugger;
1286
1287# use File::Find q(find);
1288#no warnings 'File::Find';
1289# use File::Spec::Functions;
1290#use File::Copy;
1291#use POSIX qw(strftime);
1292
1293my $option = 'main';1459my $option = 'main';
1294my ($data_dir,$debug_dir,$debug_gz,$parse_src,$upload) = ('','','','','');1460my ($data_dir,$debug_dir,$debug_gz,$parse_src,$upload) = ('','','','','');
1295my @content = (); 1461my @content;
1296my $b_debug = 0;1462my $b_debug = 0;
1297my $b_delete_dir = 1;1463my $b_delete_dir = 1;
1298# args: 1 - type1464# args: 1 - type
1299# args: 2 - upload1465# args: 2 - upload
1300sub new {1466sub new {
1301 my $class = shift;1467 my $class = shift;
1302 ($option) = @_;1468 ($option) = @_;
1303 my $self = {};1469 my $self = {};
1304 # print "$f\n";1470 # print "$f\n";
1305 # print "$option\n";1471 # print "$option\n";
1306 return bless $self, $class;1472 return bless $self, $class;
1307}1473}
13081474
1309sub run_debugger {1475sub run_debugger {
1310 #require File::Find;1476 print "Starting $self_name debugging data collector...\n";
1311 #import File::Find::Functions;1477 print "Loading required debugger Perl File:: modules... \n";
1312 require File::Copy;1478 # Fedora/Redhat doesn't include File::Find File::Copy in
1313 import File::Copy;1479 # core modules. why? Or rather, they deliberately removed them.
1314 require File::Spec::Functions;1480 if (main::check_perl_module('File::Find')){
1315 import File::Spec::Functions;1481 File::Find->import;
1316 1482 }
1317 print "Starting $self_name debugging data collector...\n";1483 else {
1318 create_debug_directory();1484 main::error_handler('required-module', 'File', 'File::Find');
1319 print "Note: for dmidecode data you must be root.\n" if !$b_root;1485 }
1320 print $line3;1486 if (main::check_perl_module('File::Copy')){
1321 if (!$b_debug){1487 File::Copy->import;
1322 audio_data();1488 }
1323 disk_data();1489 else {
1324 display_data();1490 main::error_handler('required-module', 'File', 'File::Copy');
1325 network_data();1491 }
1326 perl_modules();1492 if (main::check_perl_module('File::Spec::Functions')){
1327 system_data();1493 File::Spec::Functions->import;
1328 }1494 }
1329 system_files();1495 else {
1330 print $line3;1496 main::error_handler('required-module', 'File', 'File::Spec::Functions');
1331 if (!$b_debug){1497 }
1332 # note: android has unreadable /sys, but -x and -r tests pass1498 if ($debugger{'level'} > 20){
1333 # main::globber('/sys/*') && 1499 if (main::check_perl_module('Net::FTP')){
1334 if ( main::count_dir_files('/sys') ){1500 Net::FTP->import;
1335 build_tree('sys');1501 }
1336 # kernel crash, not sure what creates it, for ppc, as root1502 else {
1337 sys_traverse_data() if ($debugger{'sys'} && ($debugger{'sys-force'} || !$b_root || !$b_ppc )) ; 1503 main::error_handler('required-module', 'Net', 'Net::FTP');
1338 }1504 }
1339 else {1505 }
1340 print "Skipping /sys data collection. /sys not present, or empty.\n";1506 create_debug_directory();
1341 }1507 print "Note: for dmidecode, smartctl, lvm data you must be root.\n" if !$b_root;
1342 print $line3;1508 print $line3;
1343 # note: proc has some files that are apparently kernel processes, I've tried 1509 if (!$b_debug){
1344 # filtering them out but more keep appearing, so only run proc debugger if not root1510 audio_data();
1345 if ( !$debugger{'no-proc'} && (!$b_root || $debugger{'proc'} ) && -d '/proc' && main::count_dir_files('/proc') ){1511 bluetooth_data();
1346 build_tree('proc');1512 disk_data();
1347 proc_traverse_data();1513 display_data();
1348 }1514 network_data();
1349 else {1515 perl_modules();
1350 print "Skipping /proc data collection.\n";1516 system_data();
1351 }1517 }
1352 print $line3;1518 system_files();
1353 }1519 print $line3;
1354 run_self();1520 if (!$b_debug){
1355 print $line3;1521 # note: android has unreadable /sys, but -x and -r tests pass
1356 compress_dir();1522 # main::globber('/sys/*') &&
1523 if ($debugger{'sys'} && main::count_dir_files('/sys')){
1524 build_tree('sys');
1525 # kernel crash, not sure what creates it, for ppc, as root
1526 sys_traverse_data() if ($debugger{'sys'} && ($debugger{'sys-force'} || !$b_root || !$b_ppc)) ;
1527 }
1528 else {
1529 print "Skipping /sys data collection.\n";
1530 }
1531 print $line3;
1532 # note: proc has some files that are apparently kernel processes, I've tried
1533 # filtering them out but more keep appearing, so only run proc debugger if not root
1534 if (!$debugger{'no-proc'} && (!$b_root || $debugger{'proc'}) && -d '/proc' && main::count_dir_files('/proc')){
1535 build_tree('proc');
1536 proc_traverse_data();
1537 }
1538 else {
1539 print "Skipping /proc data collection.\n";
1540 }
1541 print $line3;
1542 }
1543 run_self();
1544 print $line3;
1545 compress_dir();
1357}1546}
13581547
1359sub create_debug_directory {1548sub create_debug_directory {
1360 my $host = main::get_hostname();1549 my $host = main::get_hostname();
1361 $host =~ s/ /-/g;1550 $host =~ s/ /-/g;
1362 $host = 'no-host' if !$host || $host eq 'N/A';1551 $host = 'no-host' if !$host || $host eq 'N/A';
1363 my ($alt_string,$bsd_string,$root_string) = ('','','');1552 my ($alt_string,$bsd_string,$root_string) = ('','','');
1364 # note: Time::Piece was introduced in perl 5.9.51553 # note: Time::Piece was introduced in perl 5.9.5
1365 my ($sec,$min,$hour,$mday,$mon,$year) = localtime;1554 my ($sec,$min,$hour,$mday,$mon,$year) = localtime;
1366 $year = $year+1900;1555 $year = $year+1900;
1367 $mon += 1;1556 $mon += 1;
1368 if (length($sec) == 1) {$sec = "0$sec";}1557 if (length($sec) == 1){$sec = "0$sec";}
1369 if (length($min) == 1) {$min = "0$min";}1558 if (length($min) == 1){$min = "0$min";}
1370 if (length($hour) == 1) {$hour = "0$hour";}1559 if (length($hour) == 1){$hour = "0$hour";}
1371 if (length($mon) == 1) {$mon = "0$mon";}1560 if (length($mon) == 1){$mon = "0$mon";}
1372 if (length($mday) == 1) {$mday = "0$mday";}1561 if (length($mday) == 1){$mday = "0$mday";}
1373 1562 my $today = "$year-$mon-${mday}_$hour$min$sec";
1374 my $today = "$year-$mon-${mday}_$hour$min$sec";1563 # my $date = strftime "-%Y-%m-%d_", localtime;
1375 # my $date = strftime "-%Y-%m-%d_", localtime;1564 if ($b_root){
1376 if ($b_root){1565 $root_string = '-root';
1377 $root_string = '-root';1566 }
1378 }1567 $bsd_string = "-BSD-$bsd_type" if $bsd_type;
1379 $bsd_string = "-BSD-$bsd_type" if $bsd_type;1568 my $id = ($debugger{'id'}) ? '-' . $debugger{'id'}: '';
1380 if ($b_arm ){$alt_string = '-ARM'}1569 if ($b_arm){$alt_string = '-ARM'}
1381 elsif ($b_mips) {$alt_string = '-MIPS'}1570 elsif ($b_mips){$alt_string = '-MIPS'}
1382 elsif ($b_ppc) {$alt_string = '-PPC'}1571 elsif ($b_ppc){$alt_string = '-PPC'}
1383 elsif ($b_sparc) {$alt_string = '-SPARC'}1572 elsif ($b_sparc){$alt_string = '-SPARC'}
1384 $debug_dir = "$self_name$alt_string$bsd_string-$host-$today$root_string-$self_version";1573 $debug_dir = "$self_name$alt_string$bsd_string-$host$id-$today$root_string-$self_version-$self_patch";
1385 $debug_gz = "$debug_dir.tar.gz";1574 $debug_gz = "$debug_dir.tar.gz";
1386 $data_dir = "$user_data_dir/$debug_dir";1575 $data_dir = "$user_data_dir/$debug_dir";
1387 if ( -d $data_dir ){1576 if (-d $data_dir){
1388 unlink $data_dir or main::error_handler('remove', "$data_dir", "$!");1577 unlink $data_dir or main::error_handler('remove', "$data_dir", "$!");
1389 }1578 }
1390 mkdir $data_dir or main::error_handler('mkdir', "$data_dir", "$!");1579 mkdir $data_dir or main::error_handler('mkdir', "$data_dir", "$!");
1391 if ( -e "$user_data_dir/$debug_gz" ){1580 if (-e "$user_data_dir/$debug_gz"){
1392 #rmdir "$user_data_dir$debug_gz" or main::error_handler('remove', "$user_data_dir/$debug_gz", "$!");1581 #rmdir "$user_data_dir$debug_gz" or main::error_handler('remove', "$user_data_dir/$debug_gz", "$!");
1393 print "Failed removing leftover directory:\n$user_data_dir$debug_gz error: $?" if system('rm','-rf',"$user_data_dir$debug_gz");1582 print "Failed removing leftover directory:\n$user_data_dir$debug_gz error: $?" if system('rm','-rf',"$user_data_dir$debug_gz");
1394 }1583 }
1395 print "Data going into:\n$data_dir\n";1584 print "Debugger data going into:\n$data_dir\n";
1396}1585}
1397sub compress_dir {1586sub compress_dir {
1398 print "Creating tar.gz compressed file of this material...\n";1587 print "Creating tar.gz compressed file of this material...\n";
1399 print "File: $debug_gz\n";1588 print "File: $debug_gz\n";
1400 system("cd $user_data_dir; tar -czf $debug_gz $debug_dir");1589 system("cd $user_data_dir; tar -czf $debug_gz $debug_dir");
1401 print "Removing $data_dir...\n";1590 print "Removing $data_dir...\n";
1402 #rmdir $data_dir or print "failed removing: $data_dir error: $!\n";1591 #rmdir $data_dir or print "failed removing: $data_dir error: $!\n";
1403 return 1 if !$b_delete_dir;1592 return 1 if !$b_delete_dir;
1404 if (system('rm','-rf',$data_dir) ){1593 if (system('rm','-rf',$data_dir)){
1405 print "Failed removing: $data_dir\nError: $?\n";1594 print "Failed removing: $data_dir\nError: $?\n";
1406 }1595 }
1407 else {1596 else {
1408 print "Directory removed.\n";1597 print "Directory removed.\n";
1409 }1598 }
1410}1599}
1411# NOTE: incomplete, don't know how to ever find out 1600# NOTE: incomplete, don't know how to ever find out
1412# what sound server is actually running, and is in control1601# what sound server is actually running, and is in control
1413sub audio_data {1602sub audio_data {
1414 my (%data,@files,@files2);1603 my (%data,@files,@files2);
1415 print "Collecting audio data...\n";1604 print "Collecting audio data...\n";
1416 my @cmds = (1605 my @cmds = (
1417 ['aplay', '-l'], # alsa1606 ['aplay', '-l'], # alsa
1418 ['pactl', 'list'], # pulseaudio1607 ['pactl', 'list'], # pulseaudio
1419 );1608 );
1420 run_commands(\@cmds,'audio');1609 run_commands(\@cmds,'audio');
1421 @files = main::globber('/proc/asound/card*/codec*');1610 @files = main::globber('/proc/asound/card*/codec*');
1422 if (@files){1611 if (@files){
1423 my $asound = qx(head -n 1 /proc/asound/card*/codec* 2>&1);1612 my $asound = qx(head -n 1 /proc/asound/card*/codec* 2>&1);
1424 $data{'proc-asound-codecs'} = $asound;1613 $data{'proc-asound-codecs'} = $asound;
1425 }1614 }
1426 else {1615 else {
1427 $data{'proc-asound-codecs'} = undef;1616 $data{'proc-asound-codecs'} = undef;
1428 }1617 }
1429 1618 write_data(\%data,'audio');
1430 write_data(\%data,'audio');1619 @files = (
1431 @files = (1620 '/proc/asound/cards',
1432 '/proc/asound/cards',1621 '/proc/asound/version',
1433 '/proc/asound/version',1622 );
1434 );1623 @files2 = main::globber('/proc/asound/*/usbid');
1435 @files2 = main::globber('/proc/asound/*/usbid');1624 push(@files,@files2) if @files2;
1436 @files = (@files,@files2) if @files2;1625 copy_files(\@files,'audio');
1437 copy_files(\@files,'audio');1626}
1627sub bluetooth_data {
1628 print "Collecting bluetooth data...\n";
1629# no warnings 'uninitialized';
1630 my @cmds = (
1631 ['hciconfig','-a'],
1632 #['hcidump',''], # hangs sometimes
1633 ['hcitool','dev'],
1634 ['rfkill','--output-all'],
1635 );
1636 # these hang if bluetoothd not enabled
1637 if (@ps_cmd && (grep {m|/bluetoothd|} @ps_cmd)){
1638 push(@cmds,
1639 ['bt-adapter','--list'],
1640 ['bt-adapter','--info'],
1641 ['bluetoothctl','-- list'],
1642 ['bluetoothctl','-- show']
1643 );
1644 }
1645 run_commands(\@cmds,'bluetooth');
1438}1646}
1647
1439## NOTE: >/dev/null 2>&1 is sh, and &>/dev/null is bash, fix this1648## NOTE: >/dev/null 2>&1 is sh, and &>/dev/null is bash, fix this
1440# ls -w 1 /sysrs > tester 2>&11649# ls -w 1 /sysrs > tester 2>&1
1441sub disk_data {1650sub disk_data {
1442 my (%data,@files,@files2);1651 my (%data,@files,@files2);
1443 print "Collecting dev, label, disk, uuid data, df...\n";1652 print "Collecting dev, label, disk, uuid data, df...\n";
1444 @files = (1653 @files = (
1445 '/etc/fstab',1654 '/etc/fstab',
1446 '/etc/mtab',1655 '/etc/mtab',
1447 '/proc/mdstat',1656 '/proc/devices',
1448 '/proc/mounts',1657 '/proc/mdstat',
1449 '/proc/partitions',1658 '/proc/mounts',
1450 '/proc/scsi/scsi',1659 '/proc/partitions',
1451 '/proc/sys/dev/cdrom/info',1660 '/proc/scsi/scsi',
1452 );1661 '/proc/sys/dev/cdrom/info',
1453 # very old systems1662 );
1454 if (-d '/proc/ide/'){1663 # very old systems
1455 my @ides = main::globber('/proc/ide/*/*');1664 if (-d '/proc/ide/'){
1456 @files = (@files, @ides) if @ides;1665 my @ides = main::globber('/proc/ide/*/*');
1457 }1666 push(@files, @ides) if @ides;
1458 else {1667 }
1459 push (@files, '/proc-ide-directory');1668 else {
1460 }1669 push(@files, '/proc-ide-directory');
1461 copy_files(\@files, 'disk');1670 }
1462 my @cmds = (1671 copy_files(\@files, 'disk');
1463 ['blockdev', '--report'],1672 my @cmds = (
1464 ['btrfs', 'filesystem show'],1673 ['blockdev', '--report'],
1465 ['btrfs', 'filesystem show --mounted'],1674 ['btrfs', 'fi show'],
1466 # ['btrfs', 'filesystem show --all-devices'],1675 ['btrfs', 'filesystem show'],
1467 ['df', '-h -T'],1676 ['btrfs', 'filesystem show --mounted'],
1468 ['df', '-h'],1677 # ['btrfs', 'filesystem show --all-devices'],
1469 ['df', '-k'],1678 ['df', '-h -T'],
1470 ['df', '-k -T'],1679 ['df', '-h'],
1471 ['df', '-k -T -P'],1680 ['df', '-k'],
1472 ['df', '-k -T -P -a'],1681 ['df', '-k -T'],
1473 ['df', '-P'],1682 ['df', '-k -T -P'],
1474 ['findmnt', ''],1683 ['df', '-k -T -P -a'],
1475 ['findmnt', '--df --no-truncate'],1684 ['df', '-P'],
1476 ['findmnt', '--list --no-truncate'],1685 ['dmsetup', 'ls --tree'],
1477 ['lsblk', '-fs'],1686 ['findmnt', ''],
1478 ['lsblk', '-fsr'],1687 ['findmnt', '--df --no-truncate'],
1479 ['lsblk', '-fsP'],1688 ['findmnt', '--list --no-truncate'],
1480 ['lsblk', '-a'],1689 ['gpart', 'list'],
1481 ['lsblk', '-aP'],1690 ['gpart', 'show'],
1482 ['lsblk', '-ar'],1691 ['gpart', 'status'],
1483 ['lsblk', '-p'],1692 ['ls', '-l /dev'],
1484 ['lsblk', '-pr'],1693 # block is for mmcblk / arm devices
1485 ['lsblk', '-pP'],1694 ['ls', '-l /dev/block'],
1486 ['lsblk', '-r'],1695 ['ls', '-l /dev/block/bootdevice'],
1487 ['lsblk', '-r --output NAME,PKNAME,TYPE,RM,FSTYPE,SIZE,LABEL,UUID,MOUNTPOINT,PHY-SEC,LOG-SEC'],1696 ['ls', '-l /dev/block/bootdevice/by-name'],
1488 ['lsblk', '-rb --output NAME,PKNAME,TYPE,RM,FSTYPE,SIZE,LABEL,UUID,MOUNTPOINT,PHY-SEC,LOG-SEC'],1697 ['ls', '-l /dev/disk'],
1489 ['lsblk', '-Pb --output NAME,PKNAME,TYPE,RM,FSTYPE,SIZE'],1698 ['ls', '-l /dev/disk/by-id'],
1490 ['lsblk', '-Pb --output NAME,TYPE,RM,FSTYPE,SIZE,LABEL,UUID,SERIAL,MOUNTPOINT,PHY-SEC,LOG-SEC'],1699 ['ls', '-l /dev/disk/by-label'],
1491 ['gpart', 'list'],1700 ['ls', '-l /dev/disk/by-partlabel'],
1492 ['gpart', 'show'],1701 ['ls', '-l /dev/disk/by-partuuid'],
1493 ['gpart', 'status'],1702 ['ls', '-l /dev/disk/by-path'],
1494 ['ls', '-l /dev'],1703 ['ls', '-l /dev/disk/by-uuid'],
1495 ['ls', '-l /dev/disk'],1704 # http://comments.gmane.org/gmane.linux.file-systems.zfs.user/2032
1496 ['ls', '-l /dev/disk/by-id'],1705 ['ls', '-l /dev/disk/by-wwn'],
1497 ['ls', '-l /dev/disk/by-label'],1706 ['ls', '-l /dev/mapper'],
1498 ['ls', '-l /dev/disk/by-uuid'],1707 ['lsblk', '-fs'],
1499 # http://comments.gmane.org/gmane.linux.file-systems.zfs.user/20321708 ['lsblk', '-fsr'],
1500 ['ls', '-l /dev/disk/by-wwn'],1709 ['lsblk', '-fsP'],
1501 ['ls', '-l /dev/disk/by-path'],1710 ['lsblk', '-a'],
1502 ['ls', '-l /dev/mapper'],1711 ['lsblk', '-aP'],
1503 # LSI raid https://hwraid.le-vert.net/wiki/LSIMegaRAIDSAS1712 ['lsblk', '-ar'],
1504 ['megacli', '-AdpAllInfo -aAll'],1713 ['lsblk', '-p'],
1505 ['megacli', '-LDInfo -L0 -a0'],1714 ['lsblk', '-pr'],
1506 ['megacli', '-PDList -a0'],1715 ['lsblk', '-pP'],
1507 ['megaclisas-status', ''],1716 ['lsblk', '-r'],
1508 ['megaraidsas-status', ''],1717 ['lsblk', '-r --output NAME,PKNAME,TYPE,RM,FSTYPE,SIZE,LABEL,UUID,MOUNTPOINT,PHY-SEC,LOG-SEC,PARTFLAGS'],
1509 ['megasasctl', ''],1718 ['lsblk', '-rb --output NAME,PKNAME,TYPE,RM,FSTYPE,SIZE,LABEL,UUID,MOUNTPOINT,PHY-SEC,LOG-SEC,PARTFLAGS'],
1510 ['mount', ''],1719 ['lsblk', '-rb --output NAME,TYPE,RM,FSTYPE,SIZE,LABEL,UUID,SERIAL,MOUNTPOINT,PHY-SEC,LOG-SEC,PARTFLAGS,MAJ:MIN,PKNAME'],
1511 ['nvme', 'present'],1720 ['lsblk', '-Pb --output NAME,PKNAME,TYPE,RM,FSTYPE,SIZE'],
1512 ['readlink', '/dev/root'],1721 ['lsblk', '-Pb --output NAME,TYPE,RM,FSTYPE,SIZE,LABEL,UUID,SERIAL,MOUNTPOINT,PHY-SEC,LOG-SEC,PARTFLAGS'],
1513 ['swapon', '-s'],1722 # this should always be the live command used internally:
1514 # 3ware-raid1723 ['lsblk', '-bP --output NAME,TYPE,RM,FSTYPE,SIZE,LABEL,UUID,SERIAL,MOUNTPOINT,PHY-SEC,LOG-SEC,PARTFLAGS,MAJ:MIN,PKNAME'],
1515 ['tw-cli', 'info'],1724 ['lvdisplay', '-c'],
1516 ['zfs', 'list'],1725 ['lvdisplay', '-cv'],
1517 ['zpool', 'list'],1726 ['lvdisplay', '-cv --segments'],
1518 ['zpool', 'list -v'],1727 ['lvdisplay', '-m --segments'],
1519 );1728 ['lvdisplay', '-ma --segments'],
1520 run_commands(\@cmds,'disk');1729 ['lvs', '--separator :'],
1521 @cmds = (1730 ['lvs', '--separator : --segments'],
1522 ['atacontrol', 'list'],1731 ['lvs', '-o +devices --separator : --segments'],
1523 ['camcontrol', 'devlist'], 1732 ['lvs', '-o +devices -v --separator : --segments'],
1524 ['glabel', 'status'], 1733 ['lvs', '-o +devices -av --separator : --segments'],
1525 ['swapctl', '-l -k'],1734 ['lvs', '-o +devices -aPv --separator : --segments'],
1526 ['swapctl', '-l -k'],1735 # LSI raid https://hwraid.le-vert.net/wiki/LSIMegaRAIDSAS
1527 ['vmstat', '-H'],1736 ['megacli', '-AdpAllInfo -aAll'],
1528 );1737 ['megacli', '-LDInfo -L0 -a0'],
1529 run_commands(\@cmds,'disk-bsd');1738 ['megacli', '-PDList -a0'],
1739 ['megaclisas-status', ''],
1740 ['megaraidsas-status', ''],
1741 ['megasasctl', ''],
1742 ['mount', ''],
1743 ['nvme', 'present'],
1744 ['pvdisplay', '-c'],
1745 ['pvdisplay', '-cv'],
1746 ['pvdisplay', '-m'],
1747 ['pvdisplay', '-ma'],
1748 ['pvs', '--separator :'],
1749 ['pvs', '--separator : --segments'],
1750 ['pvs', '-a --separator : --segments'],
1751 ['pvs', '-av --separator : --segments'],
1752 ['pvs', '-aPv --separator : --segments -o +pv_major,pv_minor'],
1753 ['pvs', '-v --separator : --segments'],
1754 ['pvs', '-Pv --separator : --segments'],
1755 ['pvs', '--segments -o pv_name,pv_size,seg_size,vg_name,lv_name,lv_size,seg_pe_ranges'],
1756 ['readlink', '/dev/root'],
1757 ['swapon', '-s'],
1758 # 3ware-raid
1759 ['tw-cli', 'info'],
1760 ['vgdisplay', ''],
1761 ['vgdisplay', '-v'],
1762 ['vgdisplay', '-c'],
1763 ['vgdisplay', '-vc'],
1764 ['vgs', '--separator :'],
1765 ['vgs', '-av --separator :'],
1766 ['vgs', '-aPv --separator :'],
1767 ['vgs', '-v --separator :'],
1768 ['vgs', '-o +pv_name --separator :'],
1769 ['zfs', 'list'],
1770 ['zpool', 'list'],
1771 ['zpool', 'list -v'],
1772 );
1773 run_commands(\@cmds,'disk');
1774 @cmds = (
1775 ['atacontrol', 'list'],
1776 ['camcontrol', 'devlist'],
1777 ['camcontrol', 'devlist -v'],
1778 ['geom', 'part list'],
1779 ['glabel', 'status'],
1780 ['gpart', 'list'], # gpart in linux/bsd but do it here again
1781 ['gpart', 'show'],
1782 ['gpart', 'status'],
1783 ['swapctl', '-l -k'],
1784 ['swapctl', '-l -k'],
1785 ['vmstat', ''],
1786 ['vmstat', '-H'],
1787 );
1788 run_commands(\@cmds,'disk-bsd');
1530}1789}
1531sub display_data {1790sub display_data {
1532 my (%data,@files,@files2);1791 my (%data,@files,@files2);
1533 my $working = '';1792 my $working = '';
1534 if ( ! $b_display ){1793 if (!$b_display){
1535 print "Warning: only some of the data collection can occur if you are not in X\n";1794 print "Warning: only some of the data collection can occur if you are not in X\n";
1536 main::toucher("$data_dir/display-data-warning-user-not-in-x");1795 main::toucher("$data_dir/display-data-warning-user-not-in-x");
1537 }1796 }
1538 if ( $b_root ){1797 if ($b_root){
1539 print "Warning: only some of the data collection can occur if you are running as Root user\n";1798 print "Warning: only some of the data collection can occur if you are running as Root user\n";
1540 main::toucher("$data_dir/display-data-warning-root-user");1799 main::toucher("$data_dir/display-data-warning-root-user");
1541 }1800 }
1542 print "Collecting Xorg log and xorg.conf files...\n";1801 print "Collecting Xorg log and xorg.conf files...\n";
1543 if ( -d "/etc/X11/xorg.conf.d/" ){1802 if (-d "/etc/X11/xorg.conf.d/"){
1544 @files = main::globber("/etc/X11/xorg.conf.d/*");1803 @files = main::globber("/etc/X11/xorg.conf.d/*");
1545 }1804 }
1546 else {1805 else {
1547 @files = ('/xorg-conf-d');1806 @files = ('/xorg-conf-d');
1548 }1807 }
1549 push (@files, $files{'xorg-log'});1808 # keep this updated to handle all possible locations we know about for Xorg.0.log
1550 push (@files, '/etc/X11/xorg.conf');1809 # not using $system_files{'xorg-log'} for now though it would be best to know what file is used
1551 copy_files(\@files,'display-xorg');1810 main::set_xorg_log();
1552 print "Collecting X, xprop, glxinfo, xrandr, xdpyinfo data, wayland, weston...\n";1811 push(@files, '/var/log/Xorg.0.log');
1553 %data = (1812 push(@files, '/var/lib/gdm/.local/share/xorg/Xorg.0.log');
1554 'desktop-session' => $ENV{'DESKTOP_SESSION'},1813 push(@files, $ENV{'HOME'} . '/.local/share/xorg/Xorg.0.log');
1555 'gdmsession' => $ENV{'GDMSESSION'},1814 push(@files, $system_files{'xorg-log'}) if $system_files{'xorg-log'};
1556 'gnome-desktop-session-id' => $ENV{'GNOME_DESKTOP_SESSION_ID'},1815 push(@files, '/etc/X11/xorg.conf');
1557 'kde-full-session' => $ENV{'KDE_FULL_SESSION'},1816 copy_files(\@files,'display-xorg');
1558 'kde-session-version' => $ENV{'KDE_SESSION_VERSION'},1817 print "Collecting X, xprop, glxinfo, xrandr, xdpyinfo data, wayland, weston...\n";
1559 'vdpau-driver' => $ENV{'VDPAU_DRIVER'},1818 %data = (
1560 'xdg-current-desktop' => $ENV{'XDG_CURRENT_DESKTOP'},1819 'desktop-session' => $ENV{'DESKTOP_SESSION'},
1561 'xdg-session-desktop' => $ENV{'XDG_SESSION_DESKTOP'},1820 'gdmsession' => $ENV{'GDMSESSION'},
1562 'xdg-vtnr' => $ENV{'XDG_VTNR'},1821 'gnome-desktop-session-id' => $ENV{'GNOME_DESKTOP_SESSION_ID'},
1563 # wayland data collectors:1822 'kde-full-session' => $ENV{'KDE_FULL_SESSION'},
1564 'xdg-session-type' => $ENV{'XDG_SESSION_TYPE'},1823 'kde-session-version' => $ENV{'KDE_SESSION_VERSION'},
1565 'wayland-display' => $ENV{'WAYLAND_DISPLAY'},1824 'vdpau-driver' => $ENV{'VDPAU_DRIVER'},
1566 'gdk-backend' => $ENV{'GDK_BACKEND'},1825 'xdg-current-desktop' => $ENV{'XDG_CURRENT_DESKTOP'},
1567 'qt-qpa-platform' => $ENV{'QT_QPA_PLATFORM'},1826 'xdg-session-desktop' => $ENV{'XDG_SESSION_DESKTOP'},
1568 'clutter-backend' => $ENV{'CLUTTER_BACKEND'},1827 'xdg-vtnr' => $ENV{'XDG_VTNR'},
1569 'sdl-videodriver' => $ENV{'SDL_VIDEODRIVER'},1828 # wayland data collectors:
1570 # program display values1829 'xdg-session-type' => $ENV{'XDG_SESSION_TYPE'},
1571 'size-indent' => $size{'indent'},1830 'wayland-display' => $ENV{'WAYLAND_DISPLAY'},
1572 'size-indent-min' => $size{'indent-min'},1831 'gdk-backend' => $ENV{'GDK_BACKEND'},
1573 'size-cols-max' => $size{'max'},1832 'qt-qpa-platform' => $ENV{'QT_QPA_PLATFORM'},
1574 );1833 'clutter-backend' => $ENV{'CLUTTER_BACKEND'},
1575 write_data(\%data,'display');1834 'sdl-videodriver' => $ENV{'SDL_VIDEODRIVER'},
1576 my @cmds = (1835 # program display values
1577 # kde 5/plasma desktop 5, this is maybe an extra package and won't be used1836 'size-cols-max' => $size{'max'},
1578 ['about-distro',''],1837 'size-indent' => $size{'indent'},
1579 ['aticonfig','--adapter=all --od-gettemperature'],1838 'size-wrap-width' => $size{'wrap-max'},
1580 ['glxinfo',''],1839 );
1581 ['glxinfo','-B'],1840 write_data(\%data,'display');
1582 ['kded','--version'],1841 my @cmds = (
1583 ['kded1','--version'],1842 # kde 5/plasma desktop 5, this is maybe an extra package and won't be used
1584 ['kded2','--version'],1843 ['about-distro',''],
1585 ['kded3','--version'],1844 ['aticonfig','--adapter=all --od-gettemperature'],
1586 ['kded4','--version'],1845 ['glxinfo',''],
1587 ['kded5','--version'],1846 ['glxinfo','-B'],
1588 ['kded6','--version'],1847 ['kded','--version'],
1589 ['kf4-config','--version'],1848 ['kded1','--version'],
1590 ['kf5-config','--version'],1849 ['kded2','--version'],
1591 ['kf6-config','--version'],1850 ['kded3','--version'],
1592 ['kwin_x11','--version'],1851 ['kded4','--version'],
1593 # ['locate','/Xorg'], # for Xorg.wrap problem1852 ['kded5','--version'],
1594 ['loginctl','--no-pager list-sessions'],1853 ['kded6','--version'],
1595 ['nvidia-settings','-q screens'],1854 ['kded7','--version'],
1596 ['nvidia-settings','-c :0.0 -q all'],1855 ['kf-config','--version'],
1597 ['nvidia-smi','-q'],1856 ['kf4-config','--version'],
1598 ['nvidia-smi','-q -x'],1857 ['kf5-config','--version'],
1599 ['plasmashell','--version'],1858 ['kf6-config','--version'],
1600 ['vainfo',''],1859 ['kf7-config','--version'],
1601 ['vdpauinfo',''],1860 ['kwin_x11','--version'],
1602 ['weston-info',''], 1861 # ['locate','/Xorg'], # for Xorg.wrap problem
1603 ['wmctrl','-m'],1862 ['loginctl','--no-pager list-sessions'],
1604 ['weston','--version'],1863 ['nvidia-settings','-q screens'],
1605 ['xdpyinfo',''],1864 ['nvidia-settings','-c :0.0 -q all'],
1606 ['Xorg','-version'],1865 ['nvidia-smi','-q'],
1607 ['xprop','-root'],1866 ['nvidia-smi','-q -x'],
1608 ['xrandr',''],1867 ['plasmashell','--version'],
1609 );1868 ['vainfo',''],
1610 run_commands(\@cmds,'display');1869 ['vdpauinfo',''],
1870 ['vulkaninfo',''],
1871 ['weston-info',''],
1872 ['wmctrl','-m'],
1873 ['weston','--version'],
1874 ['xdpyinfo',''],
1875 ['Xorg','-version'],
1876 ['xprop','-root'],
1877 ['xrandr',''],
1878 );
1879 run_commands(\@cmds,'display');
1611}1880}
1612sub network_data {1881sub network_data {
1613 print "Collecting networking data...\n";1882 print "Collecting networking data...\n";
1614# no warnings 'uninitialized';1883# no warnings 'uninitialized';
1615 my @cmds = (1884 my @cmds = (
1616 ['ifconfig',''],1885 ['ifconfig',''],
1617 ['ip','addr'],1886 ['ip','addr'],
1618 ['ip','-s link'],1887 ['ip','-s link'],
1619 );1888 );
1620 run_commands(\@cmds,'network');1889 run_commands(\@cmds,'network');
1621}1890}
1622sub perl_modules {1891sub perl_modules {
1623 print "Collecting Perl module data (this can take a while)...\n";1892 print "Collecting Perl module data (this can take a while)...\n";
1624 my @modules = ();1893 my @modules;
1625 my ($dirname,$holder,$mods,$value) = ('','','','');1894 my ($dirname,$holder,$mods,$value) = ('','','','');
1626 my $filename = 'perl-modules.txt';1895 my $filename = 'perl-modules.txt';
1627 my @inc;1896 my @inc;
1628 foreach (sort @INC){1897 foreach (sort @INC){
1629 # some BSD installs have '.' n @INC path1898 # some BSD installs have '.' n @INC path
1630 if (-d $_ && $_ ne '.'){1899 if (-d $_ && $_ ne '.'){
1631 $_ =~ s/\/$//; # just in case, trim off trailing slash1900 $_ =~ s/\/$//; # just in case, trim off trailing slash
1632 $value .= "EXISTS: $_\n";1901 $value .= "EXISTS: $_\n";
1633 push @inc, $_;1902 push(@inc, $_);
1634 } 1903 }
1635 else {1904 else {
1636 $value .= "ABSENT: $_\n";1905 $value .= "ABSENT: $_\n";
1637 }1906 }
1638 }1907 }
1639 main::writer("$data_dir/perl-inc-data.txt",$value);1908 main::writer("$data_dir/perl-inc-data.txt",$value);
1640 File::Find::find { wanted => sub { 1909 File::Find::find({ wanted => sub {
1641 push @modules, File::Spec->canonpath($_) if /\.pm\z/ 1910 push(@modules, File::Spec->canonpath($_)) if /\.pm\z/
1642 }, no_chdir => 1 }, @inc;1911 }, no_chdir => 1 }, @inc);
1643 @modules = sort(@modules);1912 @modules = sort @modules;
1644 foreach (@modules){1913 foreach (@modules){
1645 my $dir = $_;1914 my $dir = $_;
1646 $dir =~ s/[^\/]+$//;1915 $dir =~ s/[^\/]+$//;
1647 if (!$holder || $holder ne $dir ){1916 if (!$holder || $holder ne $dir){
1648 $holder = $dir;1917 $holder = $dir;
1649 $value = "DIR: $dir\n";1918 $value = "DIR: $dir\n";
1650 $_ =~ s/^$dir//;1919 $_ =~ s/^$dir//;
1651 $value .= " $_\n";1920 $value .= " $_\n";
1652 }1921 }
1653 else {1922 else {
1654 $value = $_;1923 $value = $_;
1655 $value =~ s/^$dir//;1924 $value =~ s/^$dir//;
1656 $value = " $value\n";1925 $value = " $value\n";
1657 }1926 }
1658 $mods .= $value;1927 $mods .= $value;
1659 }1928 }
1660 open (my $fh, '>', "$data_dir/$filename");1929 open(my $fh, '>', "$data_dir/$filename");
1661 print $fh $mods;1930 print $fh $mods;
1662 close $fh;1931 close $fh;
1663}1932}
1664sub system_data {1933sub system_data {
1665 print "Collecting system data...\n";1934 print "Collecting system data...\n";
1666 my %data = (1935 # has to run here because if null, error, list constructor throws fatal error
1667 'cc' => $ENV{'CC'},1936 my $ksh = qx(ksh -c 'printf \%s "\$KSH_VERSION"' 2>/dev/null);
1668 # @(#)MIRBSD KSH R56 2018/03/09: ksh and mksh1937 my %data = (
1669 'ksh-version' => system('echo -n $KSH_VERSION'), # shell, not env, variable1938 'cc' => $ENV{'CC'},
1670 'manpath' => $ENV{'MANPATH'},1939 # @(#)MIRBSD KSH R56 2018/03/09: ksh and mksh
1671 'path' => $ENV{'PATH'},1940 'ksh-version' => $ksh, # shell, not env, variable
1672 'xdg-config-home' => $ENV{'XDG_CONFIG_HOME'},1941 'manpath' => $ENV{'MANPATH'},
1673 'xdg-config-dirs' => $ENV{'XDG_CONFIG_DIRS'},1942 'path' => $ENV{'PATH'},
1674 'xdg-data-home' => $ENV{'XDG_DATA_HOME'},1943 'xdg-config-home' => $ENV{'XDG_CONFIG_HOME'},
1675 'xdg-data-dirs' => $ENV{'XDG_DATA_DIRS'},1944 'xdg-config-dirs' => $ENV{'XDG_CONFIG_DIRS'},
1676 );1945 'xdg-data-home' => $ENV{'XDG_DATA_HOME'},
1677 my @files = main::globber('/usr/bin/gcc*');1946 'xdg-data-dirs' => $ENV{'XDG_DATA_DIRS'},
1678 if (@files){1947 );
1679 $data{'gcc-versions'} = join "\n",@files;1948 my @files = main::globber('/usr/bin/gcc*');
1680 }1949 if (@files){
1681 else {1950 $data{'gcc-versions'} = join("\n", @files);
1682 $data{'gcc-versions'} = undef;1951 }
1683 }1952 else {
1684 @files = main::globber('/sys/*');1953 $data{'gcc-versions'} = undef;
1685 if (@files){1954 }
1686 $data{'sys-tree-ls-1-basic'} = join "\n", @files;1955 @files = main::globber('/sys/*');
1687 }1956 if (@files){
1688 else {1957 $data{'sys-tree-ls-1-basic'} = join("\n", @files);
1689 $data{'sys-tree-ls-1-basic'} = undef;1958 }
1690 }1959 else {
1691 write_data(\%data,'system');1960 $data{'sys-tree-ls-1-basic'} = undef;
1692 # bsd tools http://cb.vu/unixtoolbox.xhtml1961 }
1693 my @cmds = (1962 write_data(\%data,'system');
1694 # general1963 # bsd tools http://cb.vu/unixtoolbox.xhtml
1695 ['sysctl', '-b kern.geom.conftxt'],1964 my @cmds = (
1696 ['sysctl', '-b kern.geom.confxml'],1965 # general
1697 ['usbdevs','-v'],1966 ['sysctl', '-a'],
1698 # freebsd1967 ['sysctl', '-b kern.geom.conftxt'],
1699 ['pciconf','-l -cv'],1968 ['sysctl', '-b kern.geom.confxml'],
1700 ['pciconf','-vl'],1969 ['usbdevs','-v'],
1701 ['pciconf','-l'],1970 # freebsd
1702 # openbsd1971 ['ofwdump','-a'], # arm / soc
1703 ['pcidump',''],1972 ['ofwdump','-ar'], # arm / soc
1704 ['pcidump','-v'],1973 ['pciconf','-l -cv'],
1705 # netbsd1974 ['pciconf','-vl'],
1706 ['kldstat',''],1975 ['pciconf','-l'],
1707 ['pcictl','list'],1976 ['usbconfig','dump_device_desc'],
1708 ['pcictl','list -ns'],1977 ['usbconfig','list'], # needs root, sigh... why?
1709 );1978 # openbsd
1710 run_commands(\@cmds,'system-bsd');1979 ['ofctl',''], # arm / soc, need to see data sample of this
1711 # diskinfo -v <disk>1980 ['pcidump',''],
1712 # fdisk <disk>1981 ['pcidump','-v'],
1713 @cmds = (1982 # netbsd
1714 ['clang','--version'],1983 ['kldstat',''],
1715 ['dmidecode',''],1984 ['pcictl','pci0 list'],
1716 ['dmesg',''],1985 ['pcictl','pci0 list -N'],
1717 ['gcc','--version'],1986 ['pcictl','pci0 list -n'],
1718 ['hciconfig','-a'],1987 );
1719 ['initctl','list'],1988 run_commands(\@cmds,'system-bsd');
1720 ['ipmi-sensors',''],1989 # diskinfo -v <disk>
1721 ['ipmi-sensors','--output-sensor-thresholds'],1990 # fdisk <disk>
1722 ['ipmitool','sensor'],1991 @cmds = (
1723 ['lscpu',''],1992 ['clang','--version'],
1724 ['lspci',''],1993 # only for prospective ram feature data collection: requires i2c-tools and module eeprom loaded
1725 ['lspci','-k'],1994 ['decode-dimms',''],
1726 ['lspci','-n'],1995 ['dmidecode',''],
1727 ['lspci','-nn'],1996 ['dmesg',''],
1728 ['lspci','-nnk'],1997 ['gcc','--version'],
1729 ['lspci','-nnkv'],# returns ports1998 ['initctl','list'],
1730 ['lspci','-nnv'],1999 ['ipmi-sensors',''],
1731 ['lspci','-mm'],2000 ['ipmi-sensors','--output-sensor-thresholds'],
1732 ['lspci','-mmk'],2001 ['ipmitool','sensor'],
1733 ['lspci','-mmkv'],2002 ['lscpu',''],
1734 ['lspci','-mmv'],2003 ['lspci',''],
1735 ['lspci','-mmnn'],2004 ['lspci','-k'],
1736 ['lspci','-v'],2005 ['lspci','-n'],
1737 ['lsusb',''],2006 ['lspci','-nn'],
1738 ['lsusb','-t'],2007 ['lspci','-nnk'],
1739 ['lsusb','-v'],2008 ['lspci','-nnkv'],# returns ports
1740 ['ps','aux'],2009 ['lspci','-nnv'],
1741 ['ps','-e'],2010 ['lspci','-mm'],
1742 ['ps','-p 1'],2011 ['lspci','-mmk'],
1743 ['runlevel',''],2012 ['lspci','-mmkv'],
1744 ['rc-status','-a'],2013 ['lspci','-mmv'],
1745 ['rc-status','-l'],2014 ['lspci','-mmnn'],
1746 ['rc-status','-r'],2015 ['lspci','-v'],
1747 ['sensors',''],2016 ['lsusb',''],
1748 # leaving this commented out to remind that some systems do not2017 ['lsusb','-t'],
1749 # support strings --version, but will just simply hang at that command2018 ['lsusb','-v'],
1750 # which you can duplicate by simply typing: strings then hitting enter.2019 ['ps','aux'],
1751 # ['strings','--version'],2020 ['ps','-e'],
1752 ['strings','present'],2021 ['ps','-p 1'],
1753 ['sysctl','-a'],2022 ['runlevel',''],
1754 ['systemctl','list-units'],2023 ['rc-status','-a'],
1755 ['systemctl','list-units --type=target'],2024 ['rc-status','-l'],
1756 ['systemd-detect-virt',''],2025 ['rc-status','-r'],
1757 ['upower','-e'],2026 ['sensors',''],
1758 ['uptime',''],2027 ['sensors','-j'],
1759 ['vcgencmd','get_mem arm'],2028 ['sensors','-u'],
1760 ['vcgencmd','get_mem gpu'],2029 # leaving this commented out to remind that some systems do not
1761 );2030 # support strings --version, but will just simply hang at that command
1762 run_commands(\@cmds,'system');2031 # which you can duplicate by simply typing: strings then hitting enter.
1763 @files = main::globber('/dev/bus/usb/*/*');2032 # ['strings','--version'],
1764 copy_files(\@files, 'system');2033 ['strings','present'],
2034 ['sysctl','-a'],
2035 ['systemctl','list-units'],
2036 ['systemctl','list-units --type=target'],
2037 ['systemd-detect-virt',''],
2038 ['uname','-a'],
2039 ['upower','-e'],
2040 ['uptime',''],
2041 ['vcgencmd','get_mem arm'],
2042 ['vcgencmd','get_mem gpu'],
2043 );
2044 run_commands(\@cmds,'system');
2045 @files = main::globber('/dev/bus/usb/*/*');
2046 copy_files(\@files, 'system');
1765}2047}
1766sub system_files {2048sub system_files {
1767 print "Collecting system files data...\n";2049 print "Collecting system files data...\n";
1768 my (%data,@files,@files2);2050 my (%data,@files,@files2);
1769 @files = RepoData::get($data_dir);2051 @files = RepoItem::get($data_dir);
1770 copy_files(\@files, 'repo');2052 copy_files(\@files, 'repo');
1771 # chdir "/etc";2053 # chdir "/etc";
1772 @files = main::globber('/etc/*[-_]{[rR]elease,[vV]ersion,issue}*');2054 @files = main::globber('/etc/*[-_]{[rR]elease,[vV]ersion,issue}*');
1773 push (@files, '/etc/issue');2055 push(@files, '/etc/issue');
1774 push (@files, '/etc/lsb-release');2056 push(@files, '/etc/lsb-release');
1775 push (@files, '/etc/os-release');2057 push(@files, '/etc/os-release');
1776 copy_files(\@files,'system-distro');2058 push(@files, '/system/build.prop');# android data file, requires rooted
1777 @files = main::globber('/etc/upstream[-_]{[rR]elease,[vV]ersion}/*');2059 push(@files, '/var/log/installer/oem-id'); # ubuntu only for oem installs?
1778 copy_files(\@files,'system-distro');2060 copy_files(\@files,'system-distro');
1779 @files = main::globber('/etc/calamares/branding/*/branding.desc');2061 @files = main::globber('/etc/upstream[-_]{[rR]elease,[vV]ersion}/*');
1780 copy_files(\@files,'system-distro');2062 copy_files(\@files,'system-distro');
1781 @files = (2063 @files = main::globber('/etc/calamares/branding/*/branding.desc');
1782 '/proc/1/comm',2064 copy_files(\@files,'system-distro');
1783 '/proc/cpuinfo',2065 @files = (
1784 '/proc/meminfo',2066 '/proc/1/comm',
1785 '/proc/modules',2067 '/proc/cmdline',
1786 '/proc/net/arp',2068 '/proc/cpuinfo',
1787 '/proc/version',2069 '/proc/meminfo',
1788 );2070 '/proc/modules',
1789 @files2=main::globber('/sys/class/power_supply/*/uevent');2071 '/proc/net/arp',
1790 if (@files2){2072 '/proc/version',
1791 @files = (@files,@files2);2073 );
1792 }2074 @files2=main::globber('/sys/class/power_supply/*/uevent');
1793 else {2075 if (@files2){
1794 push (@files, '/sys-class-power-supply-empty');2076 push(@files,@files2);
1795 }2077 }
1796 copy_files(\@files, 'system');2078 else {
1797 @files = (2079 push(@files, '/sys-class-power-supply-empty');
1798 '/etc/make.conf',2080 }
1799 '/etc/src.conf',2081 copy_files(\@files, 'system');
1800 '/var/run/dmesg.boot',2082 @files = (
1801 );2083 '/etc/make.conf',
1802 copy_files(\@files,'system-bsd');2084 '/etc/src.conf',
1803 @files = main::globber('/sys/devices/system/cpu/vulnerabilities/*');2085 '/var/run/dmesg.boot',
1804 copy_files(\@files,'security');2086 );
2087 copy_files(\@files,'system-bsd');
2088 @files = main::globber('/sys/devices/system/cpu/vulnerabilities/*');
2089 copy_files(\@files,'security');
1805}2090}
1806## SELF EXECUTE FOR LOG/OUTPUT2091## SELF EXECUTE FOR LOG/OUTPUT
1807sub run_self {2092sub run_self {
1808 print "Creating $self_name output file now. This can take a few seconds...\n";2093 print "Creating $self_name output file now. This can take a few seconds...\n";
1809 print "Starting $self_name from: $self_path\n";2094 print "Starting $self_name from: $self_path\n";
1810 my $i = ($option eq 'main-full')? ' -i' : '';2095 my $i = ($option eq 'main-full')? ' -i' : '';
1811 my $z = ($debugger{'z'}) ? ' -z' : '';2096 my $z = ($debugger{'filter'}) ? ' -z' : '';
1812 my $iz = "$i$z";2097 my $w = ($debugger{'width'}) ? $debugger{'width'} : 120;
1813 $iz =~ s/[\s\-]//g;2098 my $iz = "$i$z";
1814 my $cmd = "$self_path/$self_name -FRfrploudmaxxx$i$z --usb --slots --debug 10 -y 120 > $data_dir/$self_name-FRfrploudmaxxx$iz-usb-slots-y120.txt 2>&1";2099 $iz =~ s/[\s-]//g;
1815 system($cmd);2100 my $self_file = "$data_dir/$self_name-FERfJLrploudma$iz-slots-y$w.txt";
1816 copy($log_file, "$data_dir") or main::error_handler('copy-failed', "$log_file", "$!");2101 my $cmd = "$self_path/$self_name -FERfJLrploudma$i$z --slots --debug 10 -y $w > $self_file 2>&1";
1817 system("$self_path/$self_name --recommends -y 120 > $data_dir/$self_name-recommends-120.txt 2>&1");2102 system($cmd);
2103 copy($log_file, "$data_dir") or main::error_handler('copy-failed', "$log_file", "$!");
2104 system("$self_path/$self_name --recommends -y 120 > $data_dir/$self_name-recommends-120.txt 2>&1");
1818}2105}
18192106
1820## UTILITIES COPY/CMD/WRITE2107## UTILITIES COPY/CMD/WRITE
1821sub copy_files {2108sub copy_files {
1822 my ($files_ref,$type,$alt_dir) = @_;2109 my ($files_ref,$type,$alt_dir) = @_;
1823 my ($absent,$error,$good,$name,$unreadable);2110 my ($absent,$error,$good,$name,$unreadable);
1824 my $directory = ($alt_dir) ? $alt_dir : $data_dir;2111 my $directory = ($alt_dir) ? $alt_dir : $data_dir;
1825 my $working = ($type ne 'proc') ? "$type-file-": '';2112 my $working = ($type ne 'proc') ? "$type-file-": '';
1826 foreach (@$files_ref) {2113 foreach (@$files_ref){
1827 $name = $_;2114 $name = $_;
1828 $name =~ s/^\///;2115 $name =~ s/^\///;
1829 $name =~ s/\//~/g;2116 $name =~ s/\//~/g;
1830 # print "$name\n" if $type eq 'proc';2117 # print "$name\n" if $type eq 'proc';
1831 $name = "$directory/$working$name";2118 $name = "$directory/$working$name";
1832 $good = $name . '.txt';2119 $good = $name . '.txt';
1833 $absent = $name . '-absent';2120 $absent = $name . '-absent';
1834 $error = $name . '-error';2121 $error = $name . '-error';
1835 $unreadable = $name . '-unreadable';2122 $unreadable = $name . '-unreadable';
1836 # proc have already been tested for readable/exists2123 # proc have already been tested for readable/exists
1837 if ($type eq 'proc' || -e $_ ) {2124 if ($type eq 'proc' || -e $_){
1838 print "F:$_\n" if $type eq 'proc' && $debugger{'proc-print'};2125 print "F:$_\n" if $type eq 'proc' && $debugger{'proc-print'};
1839 if ($type eq 'proc' || -r $_){2126 if ($type eq 'proc' || -r $_){
1840 copy($_,"$good") or main::toucher($error);2127 copy($_,"$good") or main::toucher($error);
1841 }2128 }
1842 else {2129 else {
1843 main::toucher($unreadable);2130 main::toucher($unreadable);
1844 }2131 }
1845 }2132 }
1846 else {2133 else {
1847 main::toucher($absent);2134 main::toucher($absent);
1848 }2135 }
1849 }2136 }
1850}2137}
1851sub run_commands {2138sub run_commands {
1852 my ($cmds,$type) = @_;2139 my ($cmds,$type) = @_;
1853 my $holder = '';2140 my $holder = '';
1854 my ($name,$cmd,$args);2141 my ($name,$cmd,$args);
1855 foreach (@$cmds){2142 foreach my $rows (@$cmds){
1856 my @rows = @$_;2143 if (my $program = main::check_program($rows->[0])){
1857 if (my $program = main::check_program($rows[0])){2144 if ($rows->[1] eq 'present'){
1858 if ($rows[1] eq 'present'){2145 $name = "$data_dir/$type-cmd-$rows->[0]-present";
1859 $name = "$data_dir/$type-cmd-$rows[0]-present";2146 main::toucher($name);
1860 main::toucher($name);2147 }
1861 }2148 else {
1862 else {2149 $args = $rows->[1];
1863 $args = $rows[1];2150 $args =~ s/\s|--|\/|=/-/g; # for:
1864 $args =~ s/\s|--|\/|=/-/g; # for:2151 $args =~ s/--/-/g;# strip out -- that result from the above
1865 $args =~ s/--/-/g;# strip out -- that result from the above2152 $args =~ s/^-//g;
1866 $args =~ s/^-//g;2153 $args = "-$args" if $args;
1867 $args = "-$args" if $args;2154 $name = "$data_dir/$type-cmd-$rows->[0]$args.txt";
1868 $name = "$data_dir/$type-cmd-$rows[0]$args.txt";2155 $cmd = "$program $rows->[1] >$name 2>&1";
1869 $cmd = "$program $rows[1] >$name 2>&1";2156 system($cmd);
1870 system($cmd);2157 }
1871 }2158 }
1872 }2159 else {
1873 else {2160 if ($holder ne $rows->[0]){
1874 if ($holder ne $rows[0]){2161 $name = "$data_dir/$type-cmd-$rows->[0]-absent";
1875 $name = "$data_dir/$type-cmd-$rows[0]-absent";2162 main::toucher($name);
1876 main::toucher($name);2163 $holder = $rows->[0];
1877 $holder = $rows[0];2164 }
1878 }2165 }
1879 }2166 }
1880 }
1881}2167}
1882sub write_data {2168sub write_data {
1883 my ($data_ref, $type) = @_;2169 my ($data_ref, $type) = @_;
1884 my ($empty,$error,$fh,$good,$name,$undefined,$value);2170 my ($empty,$error,$fh,$good,$name,$undefined,$value);
1885 foreach (keys %$data_ref) {2171 foreach (keys %$data_ref){
1886 $value = $$data_ref{$_};2172 $value = $data_ref->{$_};
1887 $name = "$data_dir/$type-data-$_";2173 $name = "$data_dir/$type-data-$_";
1888 $good = $name . '.txt';2174 $good = $name . '.txt';
1889 $empty = $name . '-empty';2175 $empty = $name . '-empty';
1890 $error = $name . '-error';2176 $error = $name . '-error';
1891 $undefined = $name . '-undefined';2177 $undefined = $name . '-undefined';
1892 if (defined $value) {2178 if (defined $value){
1893 if ($value || $value eq '0'){2179 if ($value || $value eq '0'){
1894 open($fh, '>', $good) or main::toucher($error);2180 open($fh, '>', $good) or main::toucher($error);
1895 print $fh "$value";2181 print $fh "$value";
1896 }2182 }
1897 else {2183 else {
1898 main::toucher($empty);2184 main::toucher($empty);
1899 }2185 }
1900 }2186 }
1901 else {2187 else {
1902 main::toucher($undefined);2188 main::toucher($undefined);
1903 }2189 }
1904 }2190 }
1905}2191}
1906## TOOLS FOR DIRECTORY TREE/LS/TRAVERSE; UPLOADER2192## TOOLS FOR DIRECTORY TREE/LS/TRAVERSE; UPLOADER
1907sub build_tree {2193sub build_tree {
1908 my ($which) = @_;2194 my ($which) = @_;
1909 if ( $which eq 'sys' && main::check_program('tree') ){2195 if ($which eq 'sys' && main::check_program('tree')){
1910 print "Constructing /$which tree data...\n";2196 print "Constructing /$which tree data...\n";
1911 my $dirname = '/sys';2197 my $dirname = '/sys';
1912 my $cmd;2198 my $cmd;
1913 system("tree -a -L 10 /sys > $data_dir/sys-data-tree-full-10.txt");2199 system("tree -a -L 10 /sys > $data_dir/sys-data-tree-full-10.txt");
1914 opendir my($dh), $dirname or main::error_handler('open-dir',"$dirname", "$!");2200 opendir(my $dh, $dirname) or main::error_handler('open-dir',"$dirname", "$!");
1915 my @files = readdir $dh;2201 my @files = readdir($dh);
1916 closedir $dh;2202 closedir $dh;
1917 foreach (@files){2203 foreach (@files){
1918 next if /^\./;2204 next if /^\./;
1919 $cmd = "tree -a -L 10 $dirname/$_ > $data_dir/sys-data-tree-$_-10.txt";2205 $cmd = "tree -a -L 10 $dirname/$_ > $data_dir/sys-data-tree-$_-10.txt";
1920 #print "$cmd\n";2206 # print "$cmd\n";
1921 system($cmd);2207 system($cmd);
1922 }2208 }
1923 }2209 }
1924 print "Constructing /$which ls data...\n";2210 print "Constructing /$which ls data...\n";
1925 if ($which eq 'sys'){2211 if ($which eq 'sys'){
1926 directory_ls($which,1);2212 directory_ls($which,1);
1927 directory_ls($which,2);2213 directory_ls($which,2);
1928 directory_ls($which,3);2214 directory_ls($which,3);
1929 directory_ls($which,4);2215 directory_ls($which,4);
1930 }2216 }
1931 elsif ($which eq 'proc') {2217 elsif ($which eq 'proc'){
1932 directory_ls('proc',1);2218 directory_ls('proc',1);
1933 directory_ls('proc',2,'[a-z]');2219 directory_ls('proc',2,'[a-z]');
1934 # don't want the /proc/self or /proc/thread-self directories, those are 2220 # don't want the /proc/self or /proc/thread-self directories, those are
1935 # too invasive2221 # too invasive
1936 #directory_ls('proc',3,'[a-z]');2222 #directory_ls('proc',3,'[a-z]');
1937 #directory_ls('proc',4,'[a-z]');2223 #directory_ls('proc',4,'[a-z]');
1938 }2224 }
1939}2225}
19402226
1941# include is basic regex for ls path syntax, like [a-z]2227# include is basic regex for ls path syntax, like [a-z]
1942sub directory_ls {2228sub directory_ls {
1943 my ( $dir,$depth,$include) = @_;2229 my ($dir,$depth,$include) = @_;
1944 $include ||= '';2230 $include ||= '';
1945 my ($exclude) = ('');2231 my ($exclude) = ('');
1946 # wd do NOT want to see anything in self or thread-self!!2232 # wd do NOT want to see anything in self or thread-self!!
1947 # $exclude = 'I self -I thread-self' if $dir eq 'proc';2233 # $exclude = 'I self -I thread-self' if $dir eq 'proc';
1948 my $cmd = do {2234 my $cmd = do {
1949 if ( $depth == 1 ){ "ls -l $exclude /$dir/$include 2>/dev/null" }2235 if ($depth == 1){ "ls -l $exclude /$dir/$include 2>/dev/null" }
1950 elsif ( $depth == 2 ){ "ls -l $exclude /$dir/$include*/ 2>/dev/null" }2236 elsif ($depth == 2){ "ls -l $exclude /$dir/$include*/ 2>/dev/null" }
1951 elsif ( $depth == 3 ){ "ls -l $exclude /$dir/$include*/*/ 2>/dev/null" }2237 elsif ($depth == 3){ "ls -l $exclude /$dir/$include*/*/ 2>/dev/null" }
1952 elsif ( $depth == 4 ){ "ls -l $exclude /$dir/$include*/*/*/ 2>/dev/null" }2238 elsif ($depth == 4){ "ls -l $exclude /$dir/$include*/*/*/ 2>/dev/null" }
1953 elsif ( $depth == 5 ){ "ls -l $exclude /$dir/$include*/*/*/*/ 2>/dev/null" }2239 elsif ($depth == 5){ "ls -l $exclude /$dir/$include*/*/*/*/ 2>/dev/null" }
1954 elsif ( $depth == 6 ){ "ls -l $exclude /$dir/$include*/*/*/*/*/ 2>/dev/null" }2240 elsif ($depth == 6){ "ls -l $exclude /$dir/$include*/*/*/*/*/ 2>/dev/null" }
1955 };2241 };
1956 my @working = ();2242 my @working;
1957 my $output = '';2243 my $output = '';
1958 my ($type);2244 my ($type);
1959 my $result = qx($cmd);2245 my $result = qx($cmd);
1960 open my $ch, '<', \$result or main::error_handler('open-data',"$cmd", "$!");2246 open(my $ch, '<', \$result) or main::error_handler('open-data',"$cmd", "$!");
1961 while ( my $line = <$ch> ){2247 while (my $line = <$ch>){
1962 chomp($line);2248 chomp($line);
1963 $line =~ s/^\s+|\s+$//g;2249 $line =~ s/^\s+|\s+$//g;
1964 @working = split /\s+/, $line;2250 @working = split(/\s+/, $line);
1965 $working[0] ||= '';2251 $working[0] ||= '';
1966 if ( scalar @working > 7 ){2252 if (scalar @working > 7){
1967 if ($working[0] =~ /^d/ ){2253 if ($working[0] =~ /^d/){
1968 $type = "d - ";2254 $type = "d - ";
1969 }2255 }
1970 elsif ($working[0] =~ /^l/){2256 elsif ($working[0] =~ /^l/){
1971 $type = "l - ";2257 $type = "l - ";
1972 }2258 }
1973 else {2259 else {
1974 $type = "f - ";2260 $type = "f - ";
1975 }2261 }
1976 $working[9] ||= '';2262 $working[9] ||= '';
1977 $working[10] ||= '';2263 $working[10] ||= '';
1978 $output = $output . " $type$working[8] $working[9] $working[10]\n";2264 $output = $output . " $type$working[8] $working[9] $working[10]\n";
1979 }2265 }
1980 elsif ( $working[0] !~ /^total/ ){2266 elsif ($working[0] !~ /^total/){
1981 $output = $output . $line . "\n";2267 $output = $output . $line . "\n";
1982 }2268 }
1983 }2269 }
1984 close $ch;2270 close $ch;
1985 my $file = "$data_dir/$dir-data-ls-$depth.txt";2271 my $file = "$data_dir/$dir-data-ls-$depth.txt";
1986 open my $fh, '>', $file or main::error_handler('create',"$file", "$!");2272 open(my $fh, '>', $file) or main::error_handler('create',"$file", "$!");
1987 print $fh $output;2273 print $fh $output;
1988 close $fh;2274 close $fh;
1989 # print "$output\n";2275 # print "$output\n";
1990}2276}
1991sub proc_traverse_data {2277sub proc_traverse_data {
1992 print "Building /proc file list...\n";2278 print "Building /proc file list...\n";
1993 # get rid pointless error:Can't cd to (/sys/kernel/) debug: Permission denied2279 # get rid pointless error:Can't cd to (/sys/kernel/) debug: Permission denied
1994 no warnings 'File::Find';2280 #no warnings 'File::Find';
1995 $parse_src = 'proc';2281 no warnings;
1996 File::Find::find( \&wanted, "/proc");2282 $parse_src = 'proc';
1997 proc_traverse_processor();2283 File::Find::find(\&wanted, "/proc");
1998 @content = ();2284 process_proc_traverse();
1999}2285 @content = ();
2000sub proc_traverse_processor {2286}
2001 my ($data,$fh,$result,$row,$sep);2287sub process_proc_traverse {
2002 my $proc_dir = "$data_dir/proc";2288 my ($data,$fh,$result,$row,$sep);
2003 print "Adding /proc files...\n";2289 my $proc_dir = "$data_dir/proc";
2004 mkdir $proc_dir or main::error_handler('mkdir', "$proc_dir", "$!");2290 print "Adding /proc files...\n";
2005 # @content = sort @content; 2291 mkdir $proc_dir or main::error_handler('mkdir', "$proc_dir", "$!");
2006 copy_files(\@content,'proc',$proc_dir);2292 # @content = sort @content;
2007# foreach (@content){2293 copy_files(\@content,'proc',$proc_dir);
2008# print "$_\n";2294# foreach (@content){print "$_\n";}
2009# }
2010}2295}
20112296
2012sub sys_traverse_data {2297sub sys_traverse_data {
2013 print "Building /sys file list...\n";2298 print "Building /sys file list...\n";
2014 # get rid pointless error:Can't cd to (/sys/kernel/) debug: Permission denied2299 # get rid pointless error:Can't cd to (/sys/kernel/) debug: Permission denied
2015 no warnings 'File::Find';2300 #no warnings 'File::Find';
2016 $parse_src = 'sys';2301 no warnings;
2017 File::Find::find( \&wanted, "/sys");2302 $parse_src = 'sys';
2018 sys_traverse_processsor();2303 File::Find::find(\&wanted, "/sys");
2019 @content = ();2304 process_sys_traverse();
2020}2305 @content = ();
2021sub sys_traverse_processsor {2306}
2022 my ($data,$fh,$result,$row,$sep);2307sub process_sys_traverse {
2023 my $filename = "sys-data-parse.txt";2308 my ($data,$fh,$result,$row,$sep);
2024 print "Parsing /sys files...\n";2309 my $filename = "sys-data-parse.txt";
2025 # no sorts, we want the order it comes in2310 print "Parsing /sys files...\n";
2026 # @content = sort @content; 2311 # no sorts, we want the order it comes in
2027 foreach (@content){2312 # @content = sort @content;
2028 $data='';2313 foreach (@content){
2029 $sep='';2314 $data='';
2030 my $b_fh = 1;2315 $sep='';
2031 print "F:$_\n" if $debugger{'sys-print'};2316 my $b_fh = 1;
2032 open($fh, '<', $_) or $b_fh = 0;2317 print "F:$_\n" if $debugger{'sys-print'};
2033 # needed for removing -T test and root2318 open($fh, '<', $_) or $b_fh = 0;
2034 if ($b_fh){2319 # needed for removing -T test and root
2035 while ($row = <$fh>) {2320 if ($b_fh){
2036 chomp $row;2321 while ($row = <$fh>){
2037 $data .= $sep . '"' . $row . '"';2322 chomp($row);
2038 $sep=', ';2323 $data .= $sep . '"' . $row . '"';
2039 }2324 $sep=', ';
2040 }2325 }
2041 else {2326 }
2042 $data = '<unreadable>';2327 else {
2043 }2328 $data = '<unreadable>';
2044 $result .= "$_:[$data]\n";2329 }
2045 # print "$_:[$data]\n"2330 $result .= "$_:[$data]\n";
2046 }2331 # print "$_:[$data]\n"
2047 # print scalar @content . "\n";2332 }
2048 open ($fh, '>', "$data_dir/$filename");2333 # print scalar @content . "\n";
2049 print $fh $result;2334 open($fh, '>', "$data_dir/$filename");
2050 close $fh;2335 print $fh $result;
2051 # print $fh "$result";2336 close $fh;
2052}2337 # print $fh "$result";
20532338}
2339# perl compiler complains on start if prune = 1 used only once, so either
2340# do $File::Find::prune = 1 if !$File::Find::prune; OR use no warnings 'once'
2054sub wanted {2341sub wanted {
2055 return if -d; # not directory2342 # note: we want these directories pruned before the -d test so find
2056 return unless -e; # Must exist2343 # doesn't try to read files inside of the directories
2057 return unless -f; # Must be file2344 if ($parse_src eq 'proc'){
2058 return unless -r; # Must be readable2345 if ($File::Find::name =~ m!^/proc/[0-9]+! ||
2059 if ($parse_src eq 'sys'){2346 $File::Find::name =~ m!^/proc/(irq|spl|sys)! ||
2060 # note: a new file in 4.11 /sys can hang this, it is /parameter/ then2347 # these choke on sudo/root: kmsg kcore kpage and we don't want keys or kallsyms
2061 # a few variables. Since inxi does not need to see that file, we will2348 $File::Find::name =~ m!^/proc/k! ||
2062 # not use it. Also do not need . files or __ starting files2349 $File::Find::name =~ m!^/proc/bus/pci! ||
2063 # print $File::Find::name . "\n";2350 $File::Find::name =~ m!^/proc/(irq|spl|sys)!){
2064 # block maybe: cfgroup\/2351 $File::Find::prune = 1;
2065 # picdec\/|, wait_for_fb_sleep/wake is an odroid thing caused hang2352 return;
2066 return if $File::Find::name =~ /(^\/sys\/power\/wait_for_fb)/;2353 }
2067 return if $File::Find::name =~ /\/(\.[a-z]|kernel\/|trace\/|parameters\/|debug\/)/;2354 }
2068 # comment this one out if you experience hangs or if 2355 elsif ($parse_src eq 'sys'){
2069 # we discover syntax of foreign language characters2356 # note: a new file in 4.11 /sys can hang this, it is /parameter/ then
2070 # Must be ascii like. This is questionable and might require further2357 # a few variables. Since inxi does not need to see that file, we will
2071 # investigation, it is removing some characters that we might want2358 # not use it.
2072 # NOTE: this made a bunch of files on arm systems unreadable so we handle 2359 if ($File::Find::name =~ m!/(kernel/|trace/|parameters|debug)!){
2073 # the readable tests in copy_files()2360 $File::Find::prune = 1;
2074 # return unless -T; 2361 }
2075 }2362 }
2076 elsif ($parse_src eq 'proc') {2363 return if -d; # not directory
2077 return if $File::Find::name =~ /^\/proc\/[0-9]+\//;2364 return unless -e; # Must exist
2078 return if $File::Find::name =~ /^\/proc\/bus\/pci\//;2365 return unless -f; # Must be file
2079 return if $File::Find::name =~ /^\/proc\/(irq|spl|sys)\//;2366 return unless -r; # Must be readable
2080 # these choke on sudo/root: kmsg kcore kpage and we don't want keys or kallsyms2367 if ($parse_src eq 'sys'){
2081 return if $File::Find::name =~ /^\/proc\/k/; 2368 # print $File::Find::name . "\n";
2082 return if $File::Find::name =~ /(\/mb_groups|debug)$/;2369 # block maybe: cfgroup\/
2083 }2370 # picdec\/|, wait_for_fb_sleep/wake is an odroid thing caused hang
2084 # print $File::Find::name . "\n";2371 # wakeup_count also fails for android, but works fine on regular systems
2085 push (@content, $File::Find::name);2372 return if $b_arm && $File::Find::name =~ m!^/sys/power/(wait_for_fb_|wakeup_count$)!;
2086 return;2373 # do not need . files or __ starting files
2374 return if $File::Find::name =~ m!/\.[a-z]!;
2375 # pp_num_states: amdgpu driver bug; android: wakeup_count
2376 return if $File::Find::name =~ m!/pp_num_states$!;
2377 # comment this one out if you experience hangs or if
2378 # we discover syntax of foreign language characters
2379 # Must be ascii like. This is questionable and might require further
2380 # investigation, it is removing some characters that we might want
2381 # NOTE: this made a bunch of files on arm systems unreadable so we handle
2382 # the readable tests in copy_files()
2383 # return unless -T;
2384 }
2385 elsif ($parse_src eq 'proc'){
2386 return if $File::Find::name =~ m!(/mb_groups|debug)$!;
2387 }
2388 # print $File::Find::name . "\n";
2389 push(@content, $File::Find::name);
2390 return;
2087}2391}
2088# args: 1 - path to file to be uploaded2392# args: 1 - path to file to be uploaded
2089# args: 2 - optional: alternate ftp upload url2393# args: 2 - optional: alternate ftp upload url
2090# NOTE: must be in format: ftp.site.com/incoming2394# NOTE: must be in format: ftp.site.com/incoming
2091sub upload_file {2395sub upload_file {
2092 require Net::FTP;2396 my ($self, $ftp_url) = @_;
2093 import Net::FTP;2397 my ($ftp, $domain, $host, $user, $pass, $dir, $error);
2094 my ($self, $ftp_url) = @_;2398 $ftp_url ||= main::get_defaults('ftp-upload');
2095 my ($ftp, $domain, $host, $user, $pass, $dir, $error);2399 $ftp_url =~ s/\/$//g; # trim off trailing slash if present
2096 $ftp_url ||= main::get_defaults('ftp-upload');2400 my @url = split('/', $ftp_url);
2097 $ftp_url =~ s/\/$//g; # trim off trailing slash if present2401 my $file_path = "$user_data_dir/$debug_gz";
2098 my @url = split(/\//, $ftp_url);2402 $host = $url[0];
2099 my $file_path = "$user_data_dir/$debug_gz";2403 $dir = $url[1];
2100 $host = $url[0];2404 $domain = $host;
2101 $dir = $url[1];2405 $domain =~ s/^ftp\.//;
2102 $domain = $host;2406 $user = "anonymous";
2103 $domain =~ s/^ftp\.//;2407 $pass = "anonymous\@$domain";
2104 $user = "anonymous";2408
2105 $pass = "anonymous\@$domain";2409 print $line3;
2106 2410 print "Uploading to: $ftp_url\n";
2107 print $line3;2411 # print "$host $domain $dir $user $pass\n";
2108 print "Uploading to: $ftp_url\n";2412 print "File to be uploaded:\n$file_path\n";
2109 # print "$host $domain $dir $user $pass\n";2413
2110 print "File to be uploaded:\n$file_path\n";2414 if ($host && ($file_path && -e $file_path)){
2111 2415 # NOTE: important: must explicitly set to passive true/1
2112 if ($host && ( $file_path && -e $file_path ) ){2416 $ftp = Net::FTP->new($host, Debug => 0, Passive => 1) || main::error_handler('ftp-connect', $ftp->message);
2113 # NOTE: important: must explicitly set to passive true/12417 $ftp->login($user, $pass) || main::error_handler('ftp-login', $ftp->message);
2114 $ftp = Net::FTP->new($host, Debug => 0, Passive => 1) || main::error_handler('ftp-connect', $ftp->message);2418 $ftp->binary();
2115 $ftp->login($user, $pass) || main::error_handler('ftp-login', $ftp->message);2419 $ftp->cwd($dir);
2116 $ftp->binary();2420 print "Connected to FTP server.\n";
2117 $ftp->cwd($dir);2421 $ftp->put($file_path) || main::error_handler('ftp-upload', $ftp->message);
2118 print "Connected to FTP server.\n";2422 $ftp->quit;
2119 $ftp->put($file_path) || main::error_handler('ftp-upload', $ftp->message);2423 print "Uploaded file successfully!\n";
2120 $ftp->quit;2424 print $ftp->message;
2121 print "Uploaded file successfully!\n";2425 if ($debugger{'gz'}){
2122 print $ftp->message;2426 print "Removing debugger gz file:\n$file_path\n";
2123 if ($debugger{'gz'}){2427 unlink $file_path or main::error_handler('remove',"$file_path", "$!");
2124 print "Removing debugger gz file:\n$file_path\n";2428 print "File removed.\n";
2125 unlink $file_path or main::error_handler('remove',"$file_path", "$!");2429 }
2126 print "File removed.\n";2430 print "Debugger data generation and upload completed. Thank you for your help.\n";
2127 }2431 }
2128 print "Debugger data generation and upload completed. Thank you for your help.\n";2432 else {
2129 }2433 main::error_handler('ftp-bad-path', "$file_path");
2130 else {2434 }
2131 main::error_handler('ftp-bad-path', "$file_path");
2132 }
2133}2435}
2134}2436}
2437
2135# random tests for various issues2438# random tests for various issues
2136sub user_debug_test_1 {2439sub user_debug_test_1 {
2137# open(my $duped, '>&', STDOUT);2440# open(my $duped, '>&', STDOUT);
2138# local *STDOUT = $duped;2441# local *STDOUT = $duped;
2139# my $item = POSIX::strftime("%c", localtime);2442# my $item = POSIX::strftime("%c", localtime);
2140# print "Testing character encoding handling. Perl IO data:\n";2443# print "Testing character encoding handling. Perl IO data:\n";
2141# print(join(', ', PerlIO::get_layers(STDOUT)), "\n");2444# print(join(', ', PerlIO::get_layers(STDOUT)), "\n");
2142# print "Without binmode: ", $item,"\n";2445# print "Without binmode: ", $item,"\n";
2143# binmode STDOUT,":utf8";2446# binmode STDOUT,":utf8";
2144# print "With binmode: ", $item,"\n";2447# print "With binmode: ", $item,"\n";
2145# print "Perl IO data:\n";2448# print "Perl IO data:\n";
2146# print(join(', ', PerlIO::get_layers(STDOUT)), "\n");2449# print(join(', ', PerlIO::get_layers(STDOUT)), "\n");
2147# close($duped);2450# close $duped;
2451}
2452
2453# see docs/optimization.txt
2454sub ram_use {
2455 my ($name, $ref) = @_;
2456 printf "%-25s %5d %5d\n", $name, size($ref), total_size($ref);
2148}2457}
21492458
2150#### -------------------------------------------------------------------2459#### -------------------------------------------------------------------
@@ -2152,165 +2461,177 @@ sub user_debug_test_1 {
2152#### -------------------------------------------------------------------2461#### -------------------------------------------------------------------
21532462
2154sub download_file {2463sub download_file {
2155 my ($type, $url, $file) = @_;2464 my ($type, $url, $file,$ua) = @_;
2156 my ($cmd,$args,$timeout) = ('','','');2465 my ($cmd,$args,$timeout) = ('','','');
2157 my $debug_data = '';2466 my $debug_data = '';
2158 my $result = 1;2467 my $result = 1;
2159 $dl{'no-ssl-opt'} ||= '';2468 $ua = ($ua && $dl{'ua'}) ? $dl{'ua'} . $ua : '';
2160 $dl{'spider'} ||= '';2469 $dl{'no-ssl-opt'} ||= '';
2161 $file ||= 'N/A'; # to avoid debug error2470 $dl{'spider'} ||= '';
2162 if ( ! $dl{'dl'} ){2471 $file ||= 'N/A'; # to avoid debug error
2163 return 0;2472 if (!$dl{'dl'}){
2164 }2473 return 0;
2165 if ($dl{'timeout'}){2474 }
2166 $timeout = "$dl{'timeout'}$dl_timeout";2475 if ($dl{'timeout'}){
2167 }2476 $timeout = "$dl{'timeout'}$dl_timeout";
2168 # print "$dl{'no-ssl-opt'}\n";2477 }
2169 # print "$dl{'dl'}\n";2478 # print "$dl{'no-ssl-opt'}\n";
2170 # tiny supports spider sort of2479 # print "$dl{'dl'}\n";
2171 ## NOTE: 1 is success, 0 false for Perl2480 # tiny supports spider sort of
2172 if ($dl{'dl'} eq 'tiny' ){2481 ## NOTE: 1 is success, 0 false for Perl
2173 $cmd = "Using tiny: type: $type \nurl: $url \nfile: $file";2482 if ($dl{'dl'} eq 'tiny'){
2174 $result = get_file($type, $url, $file);2483 $cmd = "Using tiny: type: $type \nurl: $url \nfile: $file";
2175 $debug_data = ($type ne 'stdout') ? $result : 'Success: stdout data not null.';2484 $result = get_file($type, $url, $file);
2176 }2485 $debug_data = ($type ne 'stdout') ? $result : 'Success: stdout data not null.';
2177 # But: 0 is success, and 1 is false for these2486 }
2178 # when strings are returned, they will be taken as true2487 # But: 0 is success, and 1 is false for these
2179 else {2488 # when strings are returned, they will be taken as true
2180 if ($type eq 'stdout'){2489 # urls must be " quoted in case special characters present
2181 $args = $dl{'stdout'};2490 else {
2182 $cmd = "$dl{'dl'} $dl{'no-ssl-opt'} $timeout $args $url $dl{'null'}";2491 if ($type eq 'stdout'){
2183 $result = qx($cmd);2492 $args = $dl{'stdout'};
2184 $debug_data = ($result) ? 'Success: stdout data not null.' : 'Download resulted in null data!';2493 $cmd = "$dl{'dl'} $dl{'no-ssl-opt'} $ua $timeout $args \"$url\" $dl{'null'}";
2185 }2494 $result = qx($cmd);
2186 elsif ($type eq 'file') {2495 $debug_data = ($result) ? 'Success: stdout data not null.' : 'Download resulted in null data!';
2187 $args = $dl{'file'};2496 }
2188 $cmd = "$dl{'dl'} $dl{'no-ssl-opt'} $timeout $args $file $url $dl{'null'}";2497 elsif ($type eq 'file'){
2189 system($cmd);2498 $args = $dl{'file'};
2190 $result = ($?) ? 0 : 1; # reverse these into Perl t/f2499 $cmd = "$dl{'dl'} $dl{'no-ssl-opt'} $ua $timeout $args $file \"$url\" $dl{'null'}";
2191 $debug_data = $result;2500 system($cmd);
2192 }2501 $result = ($?) ? 0 : 1; # reverse these into Perl t/f
2193 elsif ( $dl{'dl'} eq 'wget' && $type eq 'spider'){2502 $debug_data = $result;
2194 $cmd = "$dl{'dl'} $dl{'no-ssl-opt'} $timeout $dl{'spider'} $url";2503 }
2195 system($cmd);2504 elsif ($dl{'dl'} eq 'wget' && $type eq 'spider'){
2196 $result = ($?) ? 0 : 1; # reverse these into Perl t/f2505 $cmd = "$dl{'dl'} $dl{'no-ssl-opt'} $ua $timeout $dl{'spider'} \"$url\"";
2197 $debug_data = $result;2506 system($cmd);
2198 }2507 $result = ($?) ? 0 : 1; # reverse these into Perl t/f
2199 }2508 $debug_data = $result;
2200 print "-------\nDownloader Data:\n$cmd\nResult: $debug_data\n" if $test[1];2509 }
2201 log_data('data',"$cmd\nResult: $result") if $b_log;2510 }
2202 return $result;2511 print "-------\nDownloader Data:\n$cmd\nResult: $debug_data\n" if $dbg[1];
2512 log_data('data',"$cmd\nResult: $result") if $b_log;
2513 return $result;
2203}2514}
22042515
2205sub get_file {2516sub get_file {
2206 my ($type, $url, $file) = @_;2517 my ($type, $url, $file) = @_;
2207 my $response = HTTP::Tiny->new->get($url);2518 my $tiny = HTTP::Tiny->new;
2208 my $return = 1;2519 # note: default is no verify, so default here actually is to verify unless overridden
2209 my $debug = 0;2520 $tiny->verify_SSL => 1 if !$dl{'no-ssl-opt'};
2210 my $fh;2521 my $response = $tiny->get($url);
2211 $file ||= 'N/A';2522 my $return = 1;
2212 log_data('dump','%{$response}',\%{$response}) if $b_log;2523 my $debug = 0;
2213 # print Dumper \%{$response};2524 my $fh;
2214 if ( ! $response->{success} ){2525 $file ||= 'N/A';
2215 my $content = $response->{content};2526 log_data('dump','%{$response}',$response) if $b_log;
2216 $content ||= "N/A\n";2527 # print Dumper $response;
2217 my $msg = "Failed to connect to server/file!\n";2528 if (!$response->{'success'}){
2218 $msg .= "Response: ${content}Downloader: HTTP::Tiny URL: $url\nFile: $file";2529 my $content = $response->{'content'};
2219 log_data('data',$msg) if $b_log;2530 $content ||= "N/A\n";
2220 print error_defaults('download-error',$msg) if $test[1];2531 my $msg = "Failed to connect to server/file!\n";
2221 $return = 0;2532 $msg .= "Response: ${content}Downloader: HTTP::Tiny URL: $url\nFile: $file";
2222 }2533 log_data('data',$msg) if $b_log;
2223 else {2534 print error_defaults('download-error',$msg) if $dbg[1];
2224 if ( $debug ){2535 $return = 0;
2225 print "$response->{success}\n";2536 }
2226 print "$response->{status} $response->{reason}\n";2537 else {
2227 while (my ($key, $value) = each %{$response->{headers}}) {2538 if ($debug){
2228 for (ref $value eq "ARRAY" ? @$value : $value) {2539 print "$response->{success}\n";
2229 print "$key: $_\n";2540 print "$response->{status} $response->{reason}\n";
2230 }2541 while (my ($key, $value) = each %{$response->{'headers'}}){
2231 }2542 for (ref $value eq "ARRAY" ? @$value : $value){
2232 }2543 print "$key: $_\n";
2233 if ( $type eq "stdout" || $type eq "ua-stdout" ){2544 }
2234 $return = $response->{content};2545 }
2235 }2546 }
2236 elsif ($type eq "spider"){2547 if ($type eq "stdout" || $type eq "ua-stdout"){
2237 # do nothing, just use the return value2548 $return = $response->{'content'};
2238 }2549 }
2239 elsif ($type eq "file"){2550 elsif ($type eq "spider"){
2240 open($fh, ">", $file);2551 # do nothing, just use the return value
2241 print $fh $response->{content}; # or die "can't write to file!\n";2552 }
2242 close $fh;2553 elsif ($type eq "file"){
2243 }2554 open($fh, ">", $file);
2244 }2555 print $fh $response->{'content'}; # or die "can't write to file!\n";
2245 return $return;2556 close $fh;
2557 }
2558 }
2559 return $return;
2246}2560}
22472561
2248sub set_downloader {2562sub set_downloader {
2249 eval $start if $b_log;2563 eval $start if $b_log;
2250 $dl{'no-ssl'} = '';2564 my $quiet = '';
2251 $dl{'null'} = '';2565 $dl{'no-ssl'} = '';
2252 $dl{'spider'} = '';2566 $dl{'null'} = '';
2253 # we only want to use HTTP::Tiny if it's present in user system.2567 $dl{'spider'} = '';
2254 # It is NOT part of core modules. IO::Socket::SSL is also required 2568 # we only want to use HTTP::Tiny if it's present in user system.
2255 # For some https connections so only use tiny as option if both present2569 # It is NOT part of core modules. IO::Socket::SSL is also required
2256 if ($dl{'tiny'}){2570 # For some https connections so only use tiny as option if both present
2257 if (check_module('HTTP::Tiny') && check_module('IO::Socket::SSL')){2571 if ($dl{'tiny'}){
2258 import HTTP::Tiny;2572 if (check_perl_module('HTTP::Tiny') && check_perl_module('IO::Socket::SSL')){
2259 import IO::Socket::SSL;2573 HTTP::Tiny->import;
2260 $dl{'tiny'} = 1;2574 IO::Socket::SSL->import;
2261 }2575 $dl{'tiny'} = 1;
2262 else {2576 }
2263 $dl{'tiny'} = 0;2577 else {
2264 }2578 $dl{'tiny'} = 0;
2265 }2579 }
2266 #print $dl{'tiny'} . "\n";2580 }
2267 if ($dl{'tiny'}){2581 # print $dl{'tiny'} . "\n";
2268 $dl{'dl'} = 'tiny';2582 if ($dl{'tiny'}){
2269 $dl{'file'} = '';2583 $dl{'dl'} = 'tiny';
2270 $dl{'stdout'} = '';2584 $dl{'file'} = '';
2271 $dl{'timeout'} = '';2585 $dl{'stdout'} = '';
2272 }2586 $dl{'timeout'} = '';
2273 elsif ( $dl{'curl'} && check_program('curl') ){2587 }
2274 $dl{'dl'} = 'curl';2588 elsif ($dl{'curl'} && check_program('curl')){
2275 $dl{'file'} = ' -L -s -o ';2589 $quiet = '-s ' if !$dbg[1];
2276 $dl{'no-ssl'} = ' --insecure';2590 $dl{'dl'} = 'curl';
2277 $dl{'stdout'} = ' -L -s ';2591 $dl{'file'} = " -L ${quiet}-o ";
2278 $dl{'timeout'} = ' -y ';2592 $dl{'no-ssl'} = ' --insecure';
2279 }2593 $dl{'stdout'} = " -L ${quiet}";
2280 elsif ($dl{'wget'} && check_program('wget') ){2594 $dl{'timeout'} = ' -y ';
2281 $dl{'dl'} = 'wget';2595 $dl{'ua'} = ' -A ' . $dl_ua;
2282 $dl{'file'} = ' -q -O ';2596 }
2283 $dl{'no-ssl'} = ' --no-check-certificate';2597 elsif ($dl{'wget'} && check_program('wget')){
2284 $dl{'spider'} = ' -q --spider';2598 $quiet = '-q ' if !$dbg[1];
2285 $dl{'stdout'} = ' -q -O -';2599 $dl{'dl'} = 'wget';
2286 $dl{'timeout'} = ' -T ';2600 $dl{'file'} = " ${quiet}-O ";
2287 }2601 $dl{'no-ssl'} = ' --no-check-certificate';
2288 elsif ($dl{'fetch'} && check_program('fetch')){2602 $dl{'spider'} = " ${quiet}--spider";
2289 $dl{'dl'} = 'fetch';2603 $dl{'stdout'} = " $quiet -O -";
2290 $dl{'file'} = ' -q -o ';2604 $dl{'timeout'} = ' -T ';
2291 $dl{'no-ssl'} = ' --no-verify-peer';2605 $dl{'ua'} = ' -U ' . $dl_ua;
2292 $dl{'stdout'} = ' -q -o -';2606 }
2293 $dl{'timeout'} = ' -T ';2607 elsif ($dl{'fetch'} && check_program('fetch')){
2294 }2608 $quiet = '-q ' if !$dbg[1];
2295 elsif ( $bsd_type eq 'openbsd' && check_program('ftp') ){2609 $dl{'dl'} = 'fetch';
2296 $dl{'dl'} = 'ftp';2610 $dl{'file'} = " ${quiet}-o ";
2297 $dl{'file'} = ' -o ';2611 $dl{'no-ssl'} = ' --no-verify-peer';
2298 $dl{'null'} = ' 2>/dev/null';2612 $dl{'stdout'} = " ${quiet}-o -";
2299 $dl{'stdout'} = ' -o - ';2613 $dl{'timeout'} = ' -T ';
2300 $dl{'timeout'} = '';2614 }
2301 }2615 # at least openbsd/netbsd
2302 else {2616 elsif ($bsd_type && check_program('ftp')){
2303 $dl{'dl'} = '';2617 $dl{'dl'} = 'ftp';
2304 }2618 $dl{'file'} = ' -o ';
2305 # no-ssl-opt is set to 1 with --no-ssl, so it is true, then assign2619 $dl{'null'} = ' 2>/dev/null';
2306 $dl{'no-ssl-opt'} = $dl{'no-ssl'} if $dl{'no-ssl-opt'};2620 $dl{'stdout'} = ' -o - ';
2307 eval $end if $b_log;2621 $dl{'timeout'} = '';
2622 }
2623 else {
2624 $dl{'dl'} = '';
2625 }
2626 # no-ssl-opt is set to 1 with --no-ssl, so it is true, then assign
2627 $dl{'no-ssl-opt'} = $dl{'no-ssl'} if $dl{'no-ssl-opt'};
2628 eval $end if $b_log;
2308}2629}
23092630
2310sub set_perl_downloader {2631sub set_perl_downloader {
2311 my ($downloader) = @_;2632 my ($downloader) = @_;
2312 $downloader =~ s/perl/tiny/;2633 $downloader =~ s/perl/tiny/;
2313 return $downloader;2634 return $downloader;
2314}2635}
23152636
2316#### -------------------------------------------------------------------2637#### -------------------------------------------------------------------
@@ -2318,97 +2639,97 @@ sub set_perl_downloader {
2318#### -------------------------------------------------------------------2639#### -------------------------------------------------------------------
23192640
2320sub error_handler {2641sub error_handler {
2321 eval $start if $b_log;2642 eval $start if $b_log;
2322 my ( $err, $one, $two) = @_;2643 my ($err,$one,$two) = @_;
2323 my ($b_help,$b_recommends);2644 my ($b_help,$b_recommends);
2324 my ($b_exit,$errno) = (1,0);2645 my ($b_exit,$errno) = (1,0);
2325 my $message = do {2646 my $message = do {
2326 if ( $err eq 'empty' ) { 'empty value' }2647 if ($err eq 'empty'){ 'empty value' }
2327 ## Basic rules2648 ## Basic rules
2328 elsif ( $err eq 'not-in-irc' ) { 2649 elsif ($err eq 'not-in-irc'){
2329 $errno=1; "You can't run option $one in an IRC client!" }2650 $errno=1; "You can't run option $one in an IRC client!" }
2330 ## Internal/external options2651 ## Internal/external options
2331 elsif ( $err eq 'bad-arg' ) { 2652 elsif ($err eq 'bad-arg'){
2332 $errno=10; $b_help=1; "Unsupported value: $two for option: $one" }2653 $errno=10; $b_help=1; "Unsupported value: $two for option: $one" }
2333 elsif ( $err eq 'bad-arg-int' ) { 2654 elsif ($err eq 'bad-arg-int'){
2334 $errno=11; "Bad internal argument: $one" }2655 $errno=11; "Bad internal argument: $one" }
2335 elsif ( $err eq 'distro-block' ) { 2656 elsif ($err eq 'distro-block'){
2336 $errno=20; "Option: $one has been disabled by the $self_name distribution maintainer." }2657 $errno=20; "Option: $one has been disabled by the $self_name distribution maintainer." }
2337 elsif ( $err eq 'option-feature-incomplete' ) { 2658 elsif ($err eq 'option-feature-incomplete'){
2338 $errno=21; "Option: '$one' feature: '$two' has not been implemented yet." }2659 $errno=21; "Option: '$one' feature: '$two' has not been implemented yet." }
2339 elsif ( $err eq 'unknown-option' ) { 2660 elsif ($err eq 'unknown-option'){
2340 $errno=22; $b_help=1; "Unsupported option: $one" }2661 $errno=22; $b_help=1; "Unsupported option: $one" }
2341 ## Data2662 ## Data
2342 elsif ( $err eq 'open-data' ) { 2663 elsif ($err eq 'open-data'){
2343 $errno=32; "Error opening data for reading: $one \nError: $two" }2664 $errno=32; "Error opening data for reading: $one \nError: $two" }
2344 elsif ( $err eq 'download-error' ) { 2665 elsif ($err eq 'download-error'){
2345 $errno=33; "Error downloading file with $dl{'dl'}: $one \nError: $two" }2666 $errno=33; "Error downloading file with $dl{'dl'}: $one \nError: $two" }
2346 ## Files:2667 ## Files:
2347 elsif ( $err eq 'copy-failed' ) { 2668 elsif ($err eq 'copy-failed'){
2348 $errno=40; "Error copying file: $one \nError: $two" }2669 $errno=40; "Error copying file: $one \nError: $two" }
2349 elsif ( $err eq 'create' ) { 2670 elsif ($err eq 'create'){
2350 $errno=41; "Error creating file: $one \nError: $two" }2671 $errno=41; "Error creating file: $one \nError: $two" }
2351 elsif ( $err eq 'downloader-error' ) { 2672 elsif ($err eq 'downloader-error'){
2352 $errno=42; "Error downloading file: $one \nfor download source: $two" }2673 $errno=42; "Error downloading file: $one \nfor download source: $two" }
2353 elsif ( $err eq 'file-corrupt' ) { 2674 elsif ($err eq 'file-corrupt'){
2354 $errno=43; "Downloaded file is corrupted: $one" }2675 $errno=43; "Downloaded file is corrupted: $one" }
2355 elsif ( $err eq 'mkdir' ) { 2676 elsif ($err eq 'mkdir'){
2356 $errno=44; "Error creating directory: $one \nError: $two" }2677 $errno=44; "Error creating directory: $one \nError: $two" }
2357 elsif ( $err eq 'open' ) { 2678 elsif ($err eq 'open'){
2358 $errno=45; $b_exit=0; "Error opening file: $one \nError: $two" }2679 $errno=45; $b_exit=0; "Error opening file: $one \nError: $two" }
2359 elsif ( $err eq 'open-dir' ) { 2680 elsif ($err eq 'open-dir'){
2360 $errno=46; "Error opening directory: $one \nError: $two" }2681 $errno=46; "Error opening directory: $one \nError: $two" }
2361 elsif ( $err eq 'output-file-bad' ) { 2682 elsif ($err eq 'output-file-bad'){
2362 $errno=47; "Value for --output-file must be full path, a writable directory, \nand include file name. Path: $two" }2683 $errno=47; "Value for --output-file must be full path, a writable directory, \nand include file name. Path: $two" }
2363 elsif ( $err eq 'not-writable' ) { 2684 elsif ($err eq 'not-writable'){
2364 $errno=48; "The file: $one is not writable!" }2685 $errno=48; "The file: $one is not writable!" }
2365 elsif ( $err eq 'open-dir-failed' ) { 2686 elsif ($err eq 'open-dir-failed'){
2366 $errno=49; "The directory: $one failed to open with error: $two" }2687 $errno=49; "The directory: $one failed to open with error: $two" }
2367 elsif ( $err eq 'remove' ) { 2688 elsif ($err eq 'remove'){
2368 $errno=50; "Failed to remove file: $one Error: $two" }2689 $errno=50; "Failed to remove file: $one Error: $two" }
2369 elsif ( $err eq 'rename' ) { 2690 elsif ($err eq 'rename'){
2370 $errno=51; "There was an error moving files: $one\nError: $two" }2691 $errno=51; "There was an error moving files: $one\nError: $two" }
2371 elsif ( $err eq 'write' ) { 2692 elsif ($err eq 'write'){
2372 $errno=52; "Failed writing file: $one - Error: $two!" }2693 $errno=52; "Failed writing file: $one - Error: $two!" }
2373 ## Downloaders2694 ## Downloaders
2374 elsif ( $err eq 'missing-downloader' ) { 2695 elsif ($err eq 'missing-downloader'){
2375 $errno=60; "Downloader program $two could not be located on your system." }2696 $errno=60; "Downloader program $two could not be located on your system." }
2376 elsif ( $err eq 'missing-perl-downloader' ) { 2697 elsif ($err eq 'missing-perl-downloader'){
2377 $errno=61; $b_recommends=1; "Perl downloader missing required module." }2698 $errno=61; $b_recommends=1; "Perl downloader missing required module." }
2378 ## FTP2699 ## FTP
2379 elsif ( $err eq 'ftp-bad-path' ) { 2700 elsif ($err eq 'ftp-bad-path'){
2380 $errno=70; "Unable to locate for FTP upload file:\n$one" }2701 $errno=70; "Unable to locate for FTP upload file:\n$one" }
2381 elsif ( $err eq 'ftp-connect' ) { 2702 elsif ($err eq 'ftp-connect'){
2382 $errno=71; "There was an error with connection to ftp server: $one" }2703 $errno=71; "There was an error with connection to ftp server: $one" }
2383 elsif ( $err eq 'ftp-login' ) { 2704 elsif ($err eq 'ftp-login'){
2384 $errno=72; "There was an error with login to ftp server: $one" }2705 $errno=72; "There was an error with login to ftp server: $one" }
2385 elsif ( $err eq 'ftp-upload' ) { 2706 elsif ($err eq 'ftp-upload'){
2386 $errno=73; "There was an error with upload to ftp server: $one" }2707 $errno=73; "There was an error with upload to ftp server: $one" }
2387 ## Modules2708 ## Modules
2388 elsif ( $err eq 'required-module' ) { 2709 elsif ($err eq 'required-module'){
2389 $errno=80; $b_recommends=1; "The required $one Perl module is not installed:\n$two" }2710 $errno=80; $b_recommends=1; "The required $one Perl module is not installed:\n$two" }
2390 ## DEFAULT2711 ## DEFAULT
2391 else {2712 else {
2392 $errno=255; "Error handler ERROR!! Unsupported options: $err!"}2713 $errno=255; "Error handler ERROR!! Unsupported options: $err!"}
2393 };2714 };
2394 print_line("Error $errno: $message\n");2715 print_line("Error $errno: $message\n");
2395 if ($b_help){2716 if ($b_help){
2396 print_line("Check -h for correct parameters.\n");2717 print_line("Check -h for correct parameters.\n");
2397 }2718 }
2398 if ($b_recommends){2719 if ($b_recommends){
2399 print_line("See --recommends for more information.\n");2720 print_line("See --recommends for more information.\n");
2400 }2721 }
2401 eval $end if $b_log;2722 eval $end if $b_log;
2402 exit $errno if $b_exit && !$debugger{'no-exit'};2723 exit $errno if $b_exit && !$debugger{'no-exit'};
2403}2724}
24042725
2405sub error_defaults {2726sub error_defaults {
2406 my ($type,$one) = @_;2727 my ($type,$one) = @_;
2407 $one ||= '';2728 $one ||= '';
2408 my %errors = (2729 my %errors = (
2409 'download-error' => "Download Failure:\n$one\n",2730 'download-error' => "Download Failure:\n$one\n",
2410 );2731 );
2411 return $errors{$type};2732 return $errors{$type};
2412}2733}
24132734
2414#### -------------------------------------------------------------------2735#### -------------------------------------------------------------------
@@ -2418,615 +2739,756 @@ sub error_defaults {
2418## CheckRecommends2739## CheckRecommends
2419{2740{
2420package CheckRecommends;2741package CheckRecommends;
2742my (@modules);
2421sub run {2743sub run {
2422 main::error_handler('not-in-irc', 'recommends') if $b_irc;2744 main::error_handler('not-in-irc', 'recommends') if $b_irc;
2423 my (@data,@rows);2745 my (@data,@rows);
2424 my $line = make_line();2746 my $line = make_line();
2425 my $pm = get_pm();2747 my $pm = get_pm();
2426 @data = basic_data($line);2748 @data = basic_data($line,$pm);
2427 push @rows,@data;2749 push(@rows, @data);
2428 if (!$bsd_type){2750 if (!$bsd_type){
2429 @data = check_items('required system directories',$line,$pm);2751 @data = check_items('required system directories',$line,$pm);
2430 push @rows,@data;2752 push(@rows, @data);
2431 }2753 }
2432 @data = check_items('recommended system programs',$line,$pm);2754 @data = check_items('recommended system programs',$line,$pm);
2433 push @rows,@data;2755 push(@rows, @data);
2434 @data = check_items('recommended display information programs',$line,$pm);2756 @data = check_items('recommended display information programs',$line,$pm);
2435 push @rows,@data;2757 push(@rows, @data);
2436 @data = check_items('recommended downloader programs',$line,$pm);2758 @data = check_items('recommended downloader programs',$line,$pm);
2437 push @rows,@data;2759 push(@rows, @data);
2438 @data = check_items('recommended Perl modules',$line,$pm);2760 if (!$bsd_type){
2439 push @rows,@data;2761 @data = check_items('recommended kernel modules',$line,$pm);
2440 @data = check_items('recommended directories',$line,'');2762 push(@rows, @data);
2441 push @rows,@data;2763 }
2442 @data = check_items('recommended files',$line,'');2764 @data = check_items('recommended Perl modules',$line,$pm);
2443 push @rows,@data;2765 push(@rows, @data);
2444 @data = (2766 @data = check_items('recommended directories',$line,'');
2445 ['0', '', '', "$line"],2767 push(@rows, @data);
2446 ['0', '', '', "Ok, all done with the checks. Have a nice day."],2768 @data = check_items('recommended files',$line,'');
2447 ['0', '', '', " "],2769 push(@rows, @data);
2448 );2770 @data = (
2449 push @rows,@data;2771 ['0', '', '', "$line"],
2450 #print Data::Dumper::Dumper \@rows;2772 ['0', '', '', "Ok, all done with the checks. Have a nice day."],
2451 main::print_basic(@rows); 2773 ['0', '', '', " "],
2452 exit 0; # shell true2774 );
2775 push(@rows, @data);
2776 # print Data::Dumper::Dumper \@rows;
2777 main::print_basic(\@rows);
2778 exit 0; # shell true
2453}2779}
24542780
2455sub basic_data {2781sub basic_data {
2456 my ($line) = @_;2782 my ($line,$pm_local) = @_;
2457 my (@data,@rows);2783 my (@data,@rows);
2458 my $client = $client{'name-print'};2784 my $client = $client{'name-print'};
2459 $client .= ' ' . $client{'version'} if $client{'version'};2785 $pm_local ||= 'N/A';
2460 my $default_shell = 'N/A';2786 $client .= ' ' . $client{'version'} if $client{'version'};
2461 if ($ENV{'SHELL'}){2787 my $default_shell = 'N/A';
2462 $default_shell = $ENV{'SHELL'};2788 if ($ENV{'SHELL'}){
2463 $default_shell =~ s/.*\///;2789 $default_shell = $ENV{'SHELL'};
2464 }2790 $default_shell =~ s/.*\///;
2465 my $sh = main::check_program('sh');2791 }
2466 my $sh_real = Cwd::abs_path($sh);2792 my $sh = main::check_program('sh');
2467 @rows = (2793 my $sh_real = Cwd::abs_path($sh);
2468 ['0', '', '', "$self_name will now begin checking for the programs it needs 2794 @rows = (
2469 to operate."],2795 ['0', '', '', "$self_name will now begin checking for the programs it needs
2470 ['0', '', '', "" ],2796 to operate."],
2471 ['0', '', '', "Check $self_name --help or the man page (man $self_name) 2797 ['0', '', '', "" ],
2472 to see what options are available." ],2798 ['0', '', '', "Check $self_name --help or the man page (man $self_name)
2473 ['0', '', '', "$line" ],2799 to see what options are available." ],
2474 ['0', '', '', "Test: core tools:" ],2800 ['0', '', '', "$line" ],
2475 ['0', '', '', "" ],2801 ['0', '', '', "Test: core tools:" ],
2476 ['0', '', '', "Perl version: ^$]" ],2802 ['0', '', '', "" ],
2477 ['0', '', '', "Current shell: " . $client ],2803 ['0', '', '', "Perl version: ^$]" ],
2478 ['0', '', '', "Default shell: " . $default_shell ],2804 ['0', '', '', "Current shell: " . $client ],
2479 ['0', '', '', "sh links to: $sh_real" ],2805 ['0', '', '', "Default shell: " . $default_shell ],
2480 );2806 ['0', '', '', "sh links to: $sh_real" ],
2481 return @rows;2807 ['0', '', '', "Package manager: $pm_local" ],
2808 );
2809 return @rows;
2482}2810}
2483sub check_items {2811sub check_items {
2484 my ($type,$line,$pm) = @_;
2485 my (@data,%info,@missing,$row,@rows,$result,@unreadable);
2486 my ($b_dir,$b_file,$b_module,$b_program,$item);
2487 my ($about,$extra,$extra2,$extra3,$extra4,$info_os,$install) = ('','','','','','info','');
2488 if ($type eq 'required system directories'){
2489 @data = qw(/proc /sys);
2490 $b_dir = 1;
2491 $item = 'Directory';
2492 }
2493 elsif ($type eq 'recommended system programs'){
2494 if ($bsd_type){
2495 @data = qw(camcontrol dig dmidecode fdisk file glabel gpart ifconfig ipmi-sensors
2496 ipmitool lsusb sudo smartctl sysctl tree upower uptime usbdevs);
2497 $info_os = 'info-bsd';
2498 }
2499 else {
2500 @data = qw(blockdev dig dmidecode fdisk file hddtemp ifconfig ip ipmitool
2501 ipmi-sensors lsblk lsusb modinfo runlevel sensors strings sudo tree upower uptime);
2502 }
2503 $b_program = 1;
2504 $item = 'Program';
2505 $extra2 = "Note: IPMI sensors are generally only found on servers. To access
2506 that data, you only need one of the ipmi items.";
2507 }
2508 elsif ($type eq 'recommended display information programs'){
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches