Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- # This script scans your hardware and sends the collected data
- # to linux-hardware-guide.com
- # It uses standard tools like lsusb, lscpi, lsb_release to gather data,
- # sends it to our database, and then creates a link to the result page.
- #
- # It is intended as a simple method to add your hardware components to
- # the Linux-Hardware-Guide database.
- #
- # Latest version of the script can be found at:
- # https://github.com/paralib5/lhg_scanner
- use Getopt::Long qw(GetOptions);
- Getopt::Long::Configure qw(gnu_getopt);
- $VERSION = "0.5.1";
- # Options from command line in upper case
- $DEBUG = 0; # run in debug mode
- $SILENT = 0; # run in batch mode, no user interaction
- $USERID = ""; # LHG userid
- $USERIDDE = ""; # LHG.de userid
- $COMMENTID = ""; # Link with comment
- $TMPDIR = "$ENV{HOME}/.tmp/LHG.".$$;
- GetOptions (
- "silent" => \$SILENT,
- "debug" => \$DEBUG,
- "c=s" => \$COMMENTID,
- "d=s" => \$USERIDDE,
- "u=s" => \$USERID
- );
- # The Linux-Hardware-Guide library server
- $upload_server="http://library.linux-hardware-guide.com";
- # The Linux-Hardware-Guide configuration file
- $lhg_conf_filename="/etc/lhg-tools.conf";
- check_configuration_file();
- print "***********\n";
- print "* This is the hardware scan program of \n";
- print "* http://www.Linux-Hardware-Guide.com\n";
- print "* \n";
- print "* It will check your hardware and send the results to \n";
- print "* the Linux-Hardware-Guide\n";
- print "* \n";
- print "* Log outputs will be stored in: ";
- print "$TMPDIR \n";
- print "***********\n";
- if ($DEBUG) { print "- Debug mode enabled\n"; };
- if ($SILENT) { print "- Silent mode (batch) enabled\n"; };
- if ($USERID) { print "- User id = $USERID\n"; };
- if ($USERIDDE) { print "- User id (de) = $USERIDDE\n"; };
- if ($COMMENTID) { print "- Comment id = $COMMENTID\n"; };
- print "\n";
- my @allfiles = ("alsa_cards.txt","alsa_devices.txt","aplay.txt","cpuinfo.txt",
- "dd.err.txt","dd.txt","dmesg.txt","lsb_release.txt","lspci.txt",
- "lsusb.txt","lsusb_v.err.txt","lsusb_v.txt","scanimage.txt",
- "version.txt","hdparm.txt","hdparm_direct.txt");
- # Harddisk check only possible as root.
- # However, this test (and therefore root privileges) is not mandatory
- check_root();
- print "Collecting data:\n";
- system ("mkdir -p $TMPDIR");
- # System information
- print " -> general system information \n";
- system ("lsb_release -a > $TMPDIR/lsb_release.txt");
- system ("cat /etc/*-release >> $TMPDIR/lsb_release.txt");
- system ("cat /proc/version > $TMPDIR/version.txt");
- # General HW overview
- print " -> general hardware overview \n";
- system ("lsusb > $TMPDIR/lsusb.txt");
- system ("lsusb -v > $TMPDIR/lsusb_v.txt 2> $TMPDIR/lsusb_v.err.txt");
- # lspci needed to be started with absolute path for some distribution (e.g. OpenSUSE)
- if (-e "/usr/bin/lspci") {
- system ("/usr/bin/lspci -nnk > $TMPDIR/lspci.txt");
- }elsif (-e "/sbin/lspci") {
- system ("/sbin/lspci -nnk > $TMPDIR/lspci.txt");
- }else{
- system ("lspci -nnk > $TMPDIR/lspci.txt");
- }
- system ("cat /proc/cpuinfo > $TMPDIR/cpuinfo.txt");
- # system boot messages
- print " -> boot messages \n";
- system ("dmesg > $TMPDIR/dmesg.txt");
- # system boot messages
- print " -> graphic card/drivers \n";
- check_graphics();
- # Scanner search
- print " -> checking scanners \n";
- system ("scanimage -L > $TMPDIR/scanimage.txt");
- # Sound system information
- print " -> checking sound system \n";
- system ("cat /proc/asound/devices > $TMPDIR/alsa_devices.txt");
- system ("cat /proc/asound/cards > $TMPDIR/alsa_cards.txt");
- system ("aplay -l > $TMPDIR/aplay.txt");
- # HDD measurement
- print " -> checking harddisk\n";
- check_drives();
- #The HDD write test uses a significant amount of space for its temporary file
- #We skip this test if there is not enough space left on the drive
- $available_space = `df $TMPDIR | awk 'NR==2 {print \$4}'`;
- if ($available_space > 1073741824/1024*1.5){ # 1.5 ... safety margin
- system("dd if=/dev/zero of=$TMPDIR/dd_tempfile bs=1M count=1024 conv=fdatasync,notrunc > $TMPDIR/dd.txt 2> $TMPDIR/dd.err.txt");
- system("rm $TMPDIR/dd_tempfile");
- }else{
- print "Skipping HDD write test due to limited storage capacity\n";
- }
- #only possible as root
- if ( $< == 0 ) {
- system ("hdparm -tT /dev/sda > $TMPDIR/hdparm.txt");
- system("hdparm -tT --direct /dev/sda > $TMPDIR/hdparm_direct.txt");
- }else{
- #create empty dummy file
- system ("touch $TMPDIR/hdparm.txt");
- system ("touch $TMPDIR/hdparm_direct.txt");
- }
- # Equipment paired with Logitech Unifying Receivers is hard to distinguish
- # We will need some help by other tools here
- print " -> checking Unifying Receivers \n";
- check_unifying_receivers();
- read_dmi();
- misc_stats();
- print " -> Make data anonymous\n";
- anonymize_data();
- print "done\n";
- if (! $DEBUG) {
- # Upload request and open browser
- print "\nUploading data\n";
- upload_files();
- }
- exit 0;
- $mailtext ="Please fill out the following mail body:
- 1) Hardware to be added to the database:
- (Please enter the hardware name)
- 2) Hardware URL:
- (Please add a link to the manufacturer's or Amazon's web site where details of the hardware can be found)
- 3) Describe the Linux compatibility of the Hardware:
- (e.g. works out-of-the-box, necessary configuration steps)
- 4) Please send this mail with its attachments to webmaster\@linux-hardware-guide.com
- Thank you for your submission!
- ";
- $files = create_attachment_string();
- system ("thunderbird -compose \"to='webmaster\@linux-hardware-guide.com',subject='Linux Hardware - automatic scan',body='$mailtext',attachment='$files'\"");
- exit 0;
- sub read_configfile {
- # read preferences from configuration key-value file
- # only the keys defined in the hash %prefs are read,
- # all other stuff is ignored
- my $configfile = shift;
- my $prefs = shift;
- if (! -e $configfile) {
- return 0;
- };
- open(my $fh, $configfile);
- while (<$fh>) {
- chomp; # no newline
- s/#.*//; # no comments
- s/^\s+//; # no leading white
- s/\s+$//; # no trailing white
- next unless length; # anything left?
- my ($var, $value) = split(/\s*=\s*/, $_, 2);
- if (exists $$prefs{$var}) {
- $$prefs{$var} = $value;
- }
- }
- close($fh);
- return 1;
- }
- sub ask_for_proxy_credentials {
- # first test if we have the necessary Perl module installed
- my $modtest = eval {
- require IO::Prompter;
- IO::Prompter->import();
- 1;
- };
- if (! $modtest) {
- print "Error: Module IO::Prompter not found!\n";
- return ("", "");
- }
- # second ask the user for input
- print "Proxy requires username and password\n";
- my $username = prompt( "Username: " );
- my $password = prompt( "Password: ", -echo=>'*');
- return ($username, $password);
- }
- sub check_proxy {
- # check if we access library.linux-hardware-guide.com via a proxy
- # returns LWP::UserAgent object
- use URI::Split qw(uri_split uri_join);
- my $ua = LWP::UserAgent->new;
- if ($ENV{http_proxy} eq "") {
- print "No http proxy defined.\n";
- return $ua;
- }
- $ua->env_proxy;
- my $response = $ua->get($upload_server);
- if ($response->code == 407) {
- my (@parts) = uri_split($ENV{http_proxy});
- my $proxyurl;
- my %proxyprefs = (
- 'proxy_user' => "",
- 'proxy_password' => ""
- );
- # try to fetch credentials from ~/.wgetrc
- my $configfile = $ENV{"HOME"}."/.wgetrc";
- if (!read_configfile($configfile, \%proxyprefs)) {
- print "Configuration file for proxy credentials not found: " . $configfile . "\n";
- }
- if ($proxyprefs{'proxy_user'} && $proxyprefs{'proxy_password'}) {
- # found credentials
- $proxyurl = uri_join(@parts[0], $proxyprefs{'proxy_user'} . ":" . $proxyprefs{'proxy_password'} . "@" . @parts[1]);
- }
- else {
- if ($SILENT) {
- # user prompt will not work in --silent mode
- # do not ask for proxy data, end program with error message
- print "Error: proxy username and password needed\n";
- exit 1;
- }
- else {
- # username and password are required, but cannot found
- # so the last chance ist to query the user about it
- my ($u, $p) = ask_for_proxy_credentials();
- if (! ($u || $p)) {
- print "Error: Could not get proxy credentials. Terminating.\n";
- exit 1;
- }
- $proxyurl = uri_join(@parts[0], $u . ":" . $p . "@" . @parts[1]);
- }
- }
- $ua->proxy(['http', 'ftp'], $proxyurl);
- }
- elsif ($response->code != 200) {
- print "Warning: Unexpected response code ". $response->code . "\n";
- }
- return $ua;
- };
- sub upload_files {
- my $sid;
- use LWP::UserAgent;
- use HTTP::Request::Common;
- # get session ID
- $request = HTTP::Request->new(GET => $upload_server."/uploadrequest.php?v=0.2");
- $ua = check_proxy;
- $response = $ua->request($request);
- if ($response->code == 200) {
- # HTTP_OK
- $sid = $response->content;
- } else {
- print "Error: obtaining session id for upload failed!";
- return 0;
- }
- # upload files
- $response = $ua->request(POST $upload_server."/uploadfiles.php",
- Content_Type => 'form-data',
- Content => [ sid => $sid,
- file1 => ["$TMPDIR/".$allfiles[0]],
- file2 => ["$TMPDIR/".$allfiles[1]],
- file3 => ["$TMPDIR/".$allfiles[2]],
- file4 => ["$TMPDIR/".$allfiles[3]],
- file5 => ["$TMPDIR/".$allfiles[4]],
- file6 => ["$TMPDIR/".$allfiles[5]],
- file7 => ["$TMPDIR/".$allfiles[6]],
- file8 => ["$TMPDIR/".$allfiles[7]],
- file9 => ["$TMPDIR/".$allfiles[8]],
- file10 => ["$TMPDIR/".$allfiles[9]],
- file11 => ["$TMPDIR/".$allfiles[10]],
- file12 => ["$TMPDIR/".$allfiles[11]],
- file13 => ["$TMPDIR/".$allfiles[12]],
- file14 => ["$TMPDIR/".$allfiles[13]],
- file15 => ["$TMPDIR/".$allfiles[14]],
- file16 => ["$TMPDIR/".$allfiles[15]],
- ]
- );
- print " -> ";
- print "(".$response->code.") :";
- print $response->content;
- if ($response->code == HTTP::Status::HTTP_REQUEST_TIMEOUT) {
- print "Connection timeout. Upload failed \n";
- exit 3;
- }
- elsif ($response->code == 500 ) {
- print "Bad Hostname, upload failed. Please check your internet connection. \n";
- exit 4;
- }
- print "\n\nOpening scan results at:\nhttp://www.linux-hardware-guide.com/hardware-profile/scan-".$sid."\n";
- # store help in file
- open FILE_OUT, ">", "$TMPDIR/readme.txt";
- print FILE_OUT "This directory contains the log messages sent to the Linux-Hardware-Guide.\n";
- print FILE_OUT "http://www.Linux-Hardware-Guide.com\n";
- print FILE_OUT "\n";
- print FILE_OUT "You can find your processed scan results at \n";
- print FILE_OUT "http://www.linux-hardware-guide.com/hardware-profile/scan-".$sid."\n";
- close FILE_OUT;
- if ($SILENT) {
- #service mode -> do nothing
- }else{
- open_browser($sid);
- }
- print "\n\n\n****************************** ";
- print "\nYour scan results can be found at";
- print "\nhttp://www.linux-hardware-guide.com/hardware-profile/scan-".$sid."";
- print "\n****************************** \n\n";
- exit 0;
- }
- sub open_browser {
- my $sid = shift;
- print "Trying to open scan results in browser...\n";
- if (-e "/usr/bin/sensible-browser") {
- system "sensible-browser http://www.linux-hardware-guide.com/hardware-profile/scan-$sid 2>> $TMPDIR/errors.txt ";
- }elsif (-e "/usr/bin/xdg-open") {
- system "sensible-browser http://www.linux-hardware-guide.com/hardware-profile/scan-$sid 2>> $TMPDIR/errors.txt";
- }elsif (-e "/usr/bin/firefox") {
- system "firefox --new-tab http://www.linux-hardware-guide.com/hardware-profile/scan-$sid 2>> $TMPDIR/errors.txt";
- }elsif (-e "/usr/bin/chromium-browser") {
- system "chromium-browser --app=http://www.linux-hardware-guide.com/hardware-profile/scan-$sid 2>> $TMPDIR/errors.txt";
- }
- }
- sub check_root {
- if ( $< != 0 ) {
- #print "WARNING:\n";
- #print "========\n";
- print "(This script is running without root privileges. ";
- print "Harddisk performance can only be measured with root privileges and therefore will be skipped.)\n";
- #print "\n";
- print "\n";
- }
- }
- sub create_attachment_string {
- foreach (@allfiles) {
- if (-e "$TMPDIR/$_") {
- $attachments .= "$TMPDIR/$_,";
- }
- }
- $attachments = substr($attachments,0,-1);
- return $attachments;
- }
- sub anonymize_data {
- # We do not need your IP or MAC addresses, therefore we filter them before uploading the files.
- # Serial Numbers of Equipment on the other hand might carry important
- # information, e.g. if hardware compatibility changes for certain serial numbers
- # Therefore, serial numbers are currently not filtered
- foreach (@allfiles) {
- if (-e "$TMPDIR/$_") {
- open FILE_OUT, ">", "$TMPDIR/$_.clean";
- open FILE, "<", "$TMPDIR/$_";
- while ($line = <FILE>) {
- # Replace MAC adresses
- if ($line =~ m/(([0-9A-Fa-f]{2}:){5})[0-9A-Fa-f]{2}/) {
- $line =~ s/(([0-9A-Fa-f]{2}:){5})[0-9A-Fa-f]{2}/00:11:22:33:44:55/g;
- }
- # Replace IP adresses, conservative filter used
- if ($line =~ m/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/) {
- $line =~ s/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/192.168.0.0/g;
- }
- #apparmor output can contain sensitive information (e.g. home directory file names)
- if ($line =~ m/apparmor=/) {
- $line = "FILTERED LINE (apparmor)";
- }
- print FILE_OUT $line;
- }
- close FILE;
- close FILE_OUT;
- #overwrite log files with anonymized one
- $old = "$TMPDIR/$_.clean";
- $new = "$TMPDIR/$_";
- rename ( $old, $new );
- }
- }
- return;
- }
- sub check_unifying_receivers {
- #ToDo: This information should be stored in a separate file
- my $path_solaar = `which solaar-cli`;
- if ($path_solaar eq "") {
- # tool not installed
- } else {
- system( 'echo "\n ------ solaar-cli output ------- \n" >> '.$TMPDIR.'/dmesg.txt');
- $cmd = substr($path_solaar,0,-1). " show >> $TMPDIR/dmesg.txt 2>> $TMPDIR/dmesg.txt ";
- system($cmd);
- }
- }
- sub check_graphics {
- #ToDo: This information should be stored in a separate file
- my $path_xinput = `which xinput`;
- if ($path_xinput eq "") {
- # tool not installed
- } else {
- system( 'echo "\n ------ xinput ------- \n" >> '.$TMPDIR.'/dmesg.txt');
- $cmd = substr($path_xinput,0,-1). " >> $TMPDIR/dmesg.txt 2>> $TMPDIR/dmesg.txt ";
- system($cmd);
- }
- system( 'echo "\n ------ Xorg.log ------- \n" >> '.$TMPDIR.'/dmesg.txt');
- $cmd = "cat /var/log/Xorg.0.log >> $TMPDIR/dmesg.txt 2>> $TMPDIR/dmesg.txt ";
- system($cmd);
- }
- sub check_drives {
- #ToDo: This information should be stored in a separate file
- if (-e "/sys/block/") {
- system( 'echo "\n ------ ls -d /sys/block/s* ------- \n" >> '.$TMPDIR.'/dmesg.txt');
- $cmd0 = "ls -d /sys/block/s* >> $TMPDIR/dmesg.txt 2>> $TMPDIR/dmesg.txt ";
- system( 'echo "\n ------ /sys/block/s*/device/model ------- \n" >> '.$TMPDIR.'/dmesg.txt');
- $cmd1 = "cat /sys/block/s*/device/model >> $TMPDIR/dmesg.txt 2>> $TMPDIR/dmesg.txt ";
- system($cmd0);
- system($cmd1);
- }
- }
- sub misc_stats {
- # Adding some anonymous stats
- system( 'echo "\n ------ STATS ------- \n" >> '.$TMPDIR.'/version.txt');
- system( 'echo "LHG_VERSION = '.$VERSION.' \n" >> '.$TMPDIR.'/version.txt');
- system( 'echo "UID = '.$uid.' \n" >> '.$TMPDIR.'/version.txt');
- system( 'echo "LHGUID = '.$USERID.' \n" >> '.$TMPDIR.'/version.txt');
- system( 'echo "LHGUIDDE = '.$USERIDDE.' \n" >> '.$TMPDIR.'/version.txt');
- system( 'echo "COMMENTID = '.$COMMENTID.' \n" >> '.$TMPDIR.'/version.txt');
- system( 'echo "USER_MAIL = '.$umail.' \n" >> '.$TMPDIR.'/version.txt');
- system( 'echo "\n ------ PCIDATA ------ \n" >> '.$TMPDIR.'/version.txt');
- if (-e "/var/spool/lhg-tools/pcidata") {
- system( 'cat /var/spool/lhg-tools/pcidata >> '.$TMPDIR.'/version.txt');
- }
- system( 'echo "\n ------ USBDATA ------ \n" >> '.$TMPDIR.'/version.txt');
- if (-e "/var/spool/lhg-tools/usbdata") {
- system( 'cat /var/spool/lhg-tools/usbdata >> '.$TMPDIR.'/version.txt');
- }
- }
- sub create_lhg_configfile {
- # create random uid
- my @chars = (0 .. 9, 'A'..'Z', 'a'..'z');
- my $rndstring;
- $rndstring .= $chars[rand @chars] for 1..16;
- # use example domain as of RFC 2606
- my $dummymail = 'unknown@example.com';
- open(my $fh, '>', $lhg_conf_filename) or return;
- print $fh <<"EOT";
- # This is the configuration file of the Linux-Hardware-Guide tools
- # Every user gets an anonymous user id assigned to allow checking
- # his own upload results
- # ID is set by ANONYMOUS_USER_ID
- ANONYMOUS_USER_ID = $rndstring
- # Your account can be linked with your email address. This way we can
- # contact you, if we have questions regarding your uploaded hardware
- # data.
- USER_EMAIL = $dummymail
- EOT
- close($fh);
- print "Configuration file '$lhg_conf_filename' created.\n";
- print "Please configure your email address if wanted or remove the file ";
- print "if not used in the future.\n";
- return ($rndstring, $dummymail);
- }
- sub check_configuration_file {
- # If file does not exist try to create a new one
- if (! -e $lhg_conf_filename) {
- if ( $< == 0 ) {
- ($uid, $umail) = create_lhg_configfile();
- }
- return;
- }
- # Read configuration from already existing file
- my %prefs = (
- 'ANONYMOUS_USER_ID' => "",
- 'USER_EMAIL' => ""
- );
- read_configfile($lhg_conf_filename, \%prefs);
- # Set global variables for later usage
- $uid = $prefs{'ANONYMOUS_USER_ID'};
- $umail = $prefs{'USER_EMAIL'};
- }
- sub read_dmi {
- system( 'echo "\n ------ DMI DATA ------ \n" >> '.$TMPDIR.'/dmesg.txt');
- if ( $< == 0 ) {
- system ("dmidecode >> $TMPDIR/dmesg.txt");
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement