Don't like ads? PRO users don't see any ads ;-)
Guest

Optimum Mac App InstallationCheck

By: a guest on Apr 29th, 2012  |  syntax: Perl  |  size: 15.04 KB  |  hits: 45  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #!/usr/bin/perl
  2.  
  3. use URI::Escape;
  4.  
  5. #Created/Modified by
  6. #BT 9/24/11 Initial code for all inclusive msr check
  7.  
  8. #CPU type codes
  9. my $CPU_PPC = 18;
  10. my $CPU_INTEL = 7;
  11.  
  12. #bools
  13. my $TRUE = 1;
  14. my $FALSE = 0;
  15.  
  16. my $serialNumCmd = 'grep "Serial Number (system)"';     #not valid on 10.4
  17.  
  18. #determines if the OS is lion or higher
  19. my $lion = $FALSE;
  20.  
  21. #vals
  22. my %sysvals = ();
  23.        
  24. ########################################
  25. # Perl trim function to remove whitespace from the start and end of the string
  26. #source: http://www.somacon.com/p114.php
  27. sub trim($)
  28. {
  29.         my $string = shift;
  30.         $string =~ s/^\s+//;
  31.         $string =~ s/\s+$//;
  32.         return $string;
  33. }
  34. ########################################
  35.  
  36. #CPU Blacklist
  37. #Designed so that future processors can be accommodated, regardless of speed
  38. ##############
  39. #All Motorola (not going to check for this since likelihood of this actually coming up is nil, last processor was from '95)
  40. #All PowerPC
  41. #All Intel Core Solo
  42. #Intel Core Duo if < 1.83 GHz
  43. #pass otherwise
  44. sub checkCPU
  45. {
  46.         #blacklisted cpu names
  47.         my $bl_coreSolo  = "Intel Core Solo";
  48.         my $bl_coreDuo = "Intel Core Duo";      #only blacklisting if under 1.83 GHz
  49.  
  50.         #required CPU Freq
  51.         my $req_freqcoreduo = 1.83 * 1000 * 1000 * 1000;        #1.83 GHz converted to Hz
  52.  
  53.         #get cpu type
  54.         my $cputype = trim(`sysctl -n hw.cputype`);
  55.  
  56.         #get cpu speed
  57.         my $cpufreq = trim(`sysctl -n hw.cpufrequency_max`);
  58.         $sysvals{'cpu_speed'} = int($cpufreq / (1000 * 1000));  #convert to MHz from Hz
  59.        
  60.         #get cpu name
  61.         my $cpuname = trim(`system_profiler -detailLevel mini | grep "Processor Name:" | cut -d : -f 2-9`);
  62.         $sysvals{'cpu_name'} = $cpuname;
  63.        
  64.         #other values we'd like to collect
  65.         $sysvals{'cpu_cores'} = trim(`sysctl -n hw.activecpu`); #compatible with 10.3.9 mac mini
  66.        
  67.         #cpuResult
  68.         my $cpuFail = $FALSE;
  69.  
  70.         #blacklist all PowerPCs
  71.         if($cputype == $CPU_PPC)
  72.         {
  73.                 $cpuFail = $TRUE;
  74.         }
  75.         elsif($cputype == $CPU_INTEL)
  76.         {
  77.                 my $cmp = 999;
  78.                 #blacklist core solos
  79.                 if(($cmp = index($cpuname, $bl_coreSolo)) != -1)
  80.                 {
  81.                         print "Intel Core Solo failed: $cpuname, result=$cmp\n";
  82.                         $cpuFail = $TRUE;
  83.                 }
  84.                 elsif(($cmp = index($cpuname, $bl_coreDuo)) != -1)
  85.                 {
  86.                         #blacklist all core duos that are below the speed requirement
  87.                         if($cpufreq < $req_freqcoreduo)
  88.                         {
  89.                                 print "Intel Core Duo: failed cpufreq < intel cpu : $cpuname, result=$cmp\n";
  90.                                 $cpuFail = $TRUE;
  91.                         }
  92.                         else
  93.                         {
  94.                                 print "Intel Core Duo passed: $cpuname, result=$cmp\n";
  95.                         }
  96.                 }
  97.                 else
  98.                 {
  99.                         print "CPU Passed: $cpuname\n";
  100.                 }
  101.         }
  102.        
  103.         return $cpuFail;
  104. }
  105.  
  106. sub checkMem
  107. {
  108.         my $memFail = $FALSE;
  109.        
  110.         #mem requirement
  111.         my $req_mem = 1 * 1024 * 1024 * 1024;   #1 GB, convert to bytes
  112.        
  113.         #get memsize
  114.         my $memsize = trim(`sysctl -n hw.memsize`);     #in bytes
  115.         $sysvals{'memory_amount'} = int($memsize / (1024 * 1024)); #convert to GB for easy reading in db
  116.        
  117.         #other values to retrieve
  118.         #memory speed
  119.         $sysvals{'memory_speed'}=trim(`system_profiler SPMemoryDataType | grep "Speed:" | grep "Hz" | tail -n 1 | tr -cd 0-9`);
  120.        
  121.         if($memsize < $req_mem)
  122.         {
  123.                 print "memsize < req memsize : $memsize < $req_mem\n";
  124.                 $memFail = $TRUE;
  125.         }
  126.         else
  127.         {
  128.                 print "memsize passed : $memsize >= $req_mem\n";
  129.         }      
  130.        
  131.         return $memFail;
  132. }
  133.  
  134. sub setLionFlag
  135. {
  136.         my $major = $_[0];
  137.         my $minor = $_[1];
  138.        
  139.         #lion flag is FALSE by default, so only need to check for true
  140.         if($major == 10)
  141.         {
  142.                 if($minor >= 7)
  143.                 {
  144.                         $lion = $TRUE;
  145.                 }
  146.         }
  147.         else
  148.         {
  149.                 #default to silverlight 5 in other cases
  150.                 $lion = $TRUE;
  151.         }
  152. }
  153.  
  154. #need to see how OS X 10.0 is reported...might need to use looks_like_number
  155. sub checkOSX
  156. {
  157.         #required min OSX version
  158.         my $req_major = 10;
  159.         my $req_minor = 5;
  160.         my $req_bugfix = 0;
  161.        
  162.         #get OSX version
  163.         my $major = trim(`sw_vers -productVersion | cut -d . -f 1`);
  164.         my $minor = trim(`sw_vers -productVersion | cut -d . -f 2`);
  165.         my $bugfix = trim(`sw_vers -productVersion | cut -d . -f 3`);
  166.        
  167.         #get data for storage
  168.         $sysvals{'os'} = trim(`sw_vers -productName`);
  169.         $sysvals{'os_version'} = trim(`sw_vers -productVersion`);
  170.        
  171.         #set the lion flag
  172.         setLionFlag($major, $minor);
  173.        
  174.         my $osxFail = $FALSE;
  175.        
  176.         if($major < $req_major)
  177.         {
  178.                 $osxFail = $TRUE;
  179.                 print "OSX Failed: Major $major.$minor.$bugfix < $req_major.$req_minor.$req_bugfix\n";
  180.         }
  181.         elsif ($major == $req_major)    #skip if major > req_major
  182.         {
  183.                 if($minor < $req_minor)
  184.                 {
  185.                         $osxFail = $TRUE;
  186.                         print "OSX Failed: Minor $major.$minor.$bugfix < $req_major.$req_minor.$req_bugfix\n";
  187.                 }
  188.                 elsif ($minor == $req_minor)    #skip if minor > req_minor
  189.                 {
  190.                         if($bugfix < $req_bugfix)
  191.                         {
  192.                                 $osxFail = $TRUE;      
  193.                                 print "OSX Failed: Bugfix $major.$minor.$bugfix < $req_major.$req_minor.$req_bugfix\n";
  194.                         }
  195.                         else    #else bugfix >= req_bugfix
  196.                         {
  197.                                 print "OSX Passed: $major.$minor.$bugfix >= $req_major.$req_minor.$req_bugfix\n";      
  198.                         }
  199.                 }
  200.         }
  201.        
  202.         return $osxFail;
  203. }
  204.  
  205. #need to see how OS X 10.0 is reported...might need to use looks_like_number
  206. sub checkSilverlight
  207. {
  208.         print "Checking Silverlight...\n";
  209.        
  210.         #required min Silverlight version
  211.         my $req_major = 4;
  212.         my $req_minor = 0;
  213.         my $req_bugfix = 60310;
  214.        
  215.         if($lion)
  216.         {
  217.                 $req_major = 5;
  218.                 $req_minor = 0;
  219.                 $req_bugfix = 0;
  220.         }
  221.        
  222.         #get silverlight version
  223.         #read file located at /Library/Internet Plug-Ins/Silverlight.plugin/Contents/Info.plist
  224.         open FILE, "/Library/Application Support/Microsoft/Silverlight/version.txt" or return $TRUE;
  225.         my @filelines = <FILE>;
  226.         close FILE;
  227.        
  228.         my @verparts = split(/\./, $filelines[0]);
  229.         #not sure if that produces a permission denied error
  230.         my $major = $verparts[0];
  231.         my $minor = $verparts[1];
  232.         my $bugfix = $verparts[2];
  233.        
  234.         #get data for storage
  235.         $sysvals{'silverlight_version'} = trim($filelines[0]);
  236.        
  237.         my $slFail = $FALSE;
  238.        
  239.         if($major < $req_major)
  240.         {
  241.                 $slFail = $TRUE;
  242.                 print "Silverlight Failed: Major $major.$minor.$bugfix < $req_major.$req_minor.$req_bugfix\n";
  243.         }
  244.         elsif ($major == $req_major)    #skip if major > req_major
  245.         {
  246.                 if($minor < $req_minor)
  247.                 {
  248.                         $slFail = $TRUE;
  249.                         print "Silverlight Failed: Minor $major.$minor.$bugfix < $req_major.$req_minor.$req_bugfix\n";
  250.                 }
  251.                 elsif ($minor == $req_minor)    #skip if minor > req_minor
  252.                 {
  253.                         if($bugfix < $req_bugfix)
  254.                         {
  255.                                 $slFail = $TRUE;       
  256.                                 print "Silverlight Failed: Bugfix $major.$minor.$bugfix < $req_major.$req_minor.$req_bugfix\n";
  257.                         }
  258.                         #else   #else bugfix >= req_bugfix
  259.                         #{
  260.                         #       print "Silverlight Passed: $major.$minor.$bugfix >= $req_major.$req_minor.$req_bugfix\n";      
  261.                         #}
  262.                 }
  263.         }
  264.        
  265.         if($slFail == $FALSE){
  266.                 print "Silverlight Passed: $major.$minor.$bugfix >= $req_major.$req_minor.$req_bugfix\n";
  267.         }
  268.        
  269.         return $slFail;
  270. }
  271.  
  272. sub checkFreeDisk
  273. {
  274.         #recommended free disk
  275.         my $req_disk = 30 * 1024 * 1024;        #25 Megabytes, in bytes
  276.        
  277.         #get free disk
  278.         my $freedisk = `df -b / | tail -n 1 | tr -s "[:space:]" | cut -d ' ' -f 4` * 512;       #mult by 512 bc the shell command returns number of 512-byte blocks
  279.         $sysvals{'hard_drive_free'} = int($freedisk / (1024 * 1024));   #convert to megabytes from bytes
  280.        
  281.         #other info to store
  282.         $sysvals{'hard_drive_total'} = (`df -b / | tail -n 1 | tr -s "[:space:]" | cut -d ' ' -f 3` * 512) + $freedisk;
  283.         $sysvals{'hard_drive_total'} = int($sysvals{'hard_drive_total'} / (1024 * 1024));       #convert to megabytes from bytes
  284.        
  285.         my $diskFail = $FALSE;
  286.         if($freedisk < $req_disk)
  287.         {
  288.                 print "Free Disk fail: $freedisk < $req_disk\n";
  289.                 $diskFail = $TRUE;
  290.         }
  291.         else
  292.         {
  293.                 print "Free Disk pass: $freedisk >= $req_disk\n";
  294.         }
  295.        
  296.         return $diskFail;
  297. }
  298.  
  299. sub checkWiFi
  300. {
  301.         my $wifiFail = $FALSE;
  302.        
  303.         $sysvals{'network_secure'}="U"; #Unknown
  304.                        
  305.         #wifi fail conditions
  306.         my @fail = ("link auth: none", "Security: none", "link auth: unknown");
  307.        
  308.         #need to merge fail with bypass
  309.         #where airport does not exist, invoking the airport command returns:
  310.         #WirelessAttach: getInterfaceWithName failed
  311.         #tested on mac mini, OS X 10.3.9
  312.         my @bypassfail = ("failed", "linkStatus: Disabled", "BSSID: 0:0:0:0:0:0");
  313.        
  314.         #get airport status
  315.         #using --getinfo instead of -I for legacy support
  316.         my $airportdata = `/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport --getinfo`;
  317.        
  318.         #check wifi authentication enabled
  319.         my $stage1fail = $FALSE;
  320.         for($i = 0; $i < scalar(@fail); $i++)
  321.         {
  322.                 my $cmp = 999;
  323.                 if(($cmp = index($airportdata, $fail[$i])) != -1)
  324.                 {
  325.                         $stage1fail = $TRUE;
  326.                         print "WiFi Stage 1 Fail: $fail[$i] : index=$cmp\n$airportdata\n";     
  327.                 }
  328.         }
  329.        
  330.         #this accounts for the case where airport is off (returns "AirPort: Off")
  331.         #also should allow it to pass if it returns unrecognized text.
  332.         if($stage1fail)
  333.         {
  334.                 my $stage2bypass = $FALSE;
  335.                 for($i = 0; $i < scalar(@bypassfail); $i++)
  336.                 {
  337.                         my $cmp = 999;
  338.                         if(($cmp = index($airportdata, $bypassfail[$i])) != -1)
  339.                         {
  340.                                 $stage2bypass = $TRUE;
  341.                                 print "WiFi Stage 2 BypassFail: $bypassfail[$i] : index=$cmp\n$airportdata\n";
  342.                         }
  343.                 }
  344.                
  345.                 if(!$stage2bypass)
  346.                 {
  347.                         $wifiFail = $TRUE;
  348.                         $sysvals{'network_secure'}="N";
  349.                 }
  350.                 else
  351.                 {
  352.                         print "WiFi passed\n"; 
  353.                         $sysvals{'network_secure'}="Y";
  354.                 }
  355.         }
  356.         else
  357.         {
  358.                 print "WiFi passed\n"; 
  359.         }
  360.        
  361.         return $wifiFail;
  362. }
  363.  
  364. sub checkWiFiTwo
  365. {
  366.         # conditions where wifi isn't valid include:
  367.         #       airport doesn't exist
  368.         #       airport is off
  369.         #       airport is on but not connected
  370.         my $wifiFail = $FALSE;
  371.        
  372.         $sysvals{'network_secure'}="U"; #Unknown
  373.                        
  374.         #wifi fail conditions
  375.         my @fail = ("link auth: none", "Security: none", "link auth: unknown");
  376.        
  377.         #need to merge fail with bypass
  378.         #where airport does not exist, invoking the airport command returns:
  379.         #WirelessAttach: getInterfaceWithName failed
  380.         #tested on mac mini, OS X 10.3.9
  381.         my @bypass = ("failed", "linkStatus: Disabled", "BSSID: 0:0:0:0:0:0", "AirPort: Off");
  382.        
  383.         #get airport status
  384.         #using --getinfo instead of -I for legacy support
  385.         my $airportdata = trim(`/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport --getinfo`);
  386.        
  387.         #check wifi authentication enabled
  388.         my $stage1bypass = $FALSE;
  389.         for($i = 0; $i < scalar(@bypass); $i++)
  390.         {
  391.                 my $cmp = 999;
  392.                 if(($cmp = index($airportdata, $bypass[$i])) != -1)
  393.                 {
  394.                         $stage1bypass = $TRUE;
  395.                         print "WiFi Stage 1 Bypass: $bypass[$i] : index=$cmp\n$airportdata\n"; 
  396.                         last;
  397.                 }
  398.         }
  399.        
  400.         #if it didn't bypass then we are alive and connected
  401.         #also should allow it to pass if we have unrecognized text.
  402.         if(!$stage1bypass)
  403.         {
  404.                 my $stage2fail = $FALSE;
  405.                 for($i = 0; $i < scalar(@fail); $i++)
  406.                 {
  407.                         my $cmp = 999;
  408.                         if(($cmp = index($airportdata, $fail[$i])) != -1)
  409.                         {
  410.                                 $stage2fail = $TRUE;
  411.                                 print "WiFi Stage 2 Fail: $fail[$i] : index=$cmp\n$airportdata\n";
  412.                                 last;
  413.                         }
  414.                 }
  415.                
  416.                 if($stage2fail)
  417.                 {
  418.                         $wifiFail = $TRUE;
  419.                         $sysvals{'network_secure'}="N";
  420.                 }
  421.                 else
  422.                 {
  423.                         print "WiFi passed\n"; 
  424.                         $sysvals{'network_secure'}="Y";
  425.                 }
  426.         }
  427.         else
  428.         {
  429.                 print "WiFi passed\n"; 
  430.         }
  431.        
  432.         return $wifiFail;
  433. }
  434.  
  435. #source: http://stackoverflow.com/questions/1743406/user-properties-privileges-in-applescript
  436. sub checkAdmin
  437. {
  438.         my $ADMIN = 80;
  439.         my $permTxt = `id -G`;
  440.         my @perms = split(/ /, $permTxt);
  441.         print @perms;
  442.        
  443.         my $adminFail = $TRUE;
  444.         for($i = 0; $i < scalar(@perms); $i++)
  445.         {
  446.                 if($perms[$i] == $ADMIN)
  447.                 {
  448.                         print "User is Admin\n";
  449.                         $adminFail = $FALSE;
  450.                         $sysvals{'admin'}="Y";
  451.                 }
  452.         }
  453.        
  454.         if($adminFail)
  455.         {
  456.                 print "User Not Admin\n";
  457.                 $sysvals{'admin'}="N";
  458.         }      
  459.         return $adminFail;
  460. }
  461. #checkExternal
  462. sub checkExternal
  463. {
  464.         print "FUNC: checking external\n";
  465.         my $extFail = $FALSE;
  466.         $numDisplays = trim(`system_profiler SPDisplaysDataType | grep -c "Resolution"`);
  467.         if($numDisplays >1 )
  468.         {
  469.                 $extFail = $TRUE;
  470.                 print "FUNC: external detected\n";
  471.  
  472.         }
  473.         return $extFail;
  474. }
  475. sub checkLaptop
  476. {
  477.         print "FUNC: checking laptop\n";
  478.         my $laptopFail = $FALSE;
  479.         $numLaptop = trim(`system_profiler SPDisplaysDataType | grep -c "LCD:"`);
  480.         $numIMac = trim(`system_profiler SPDisplaysDataType | grep -c "iMac:"`);
  481.         if(($numLaptop == 0) && ($numIMac == 0))
  482.         {
  483.                 $laptopFail = $TRUE;
  484.                 print "FUNC: not laptop or iMac\n";
  485.         }
  486.         return $laptopFail;
  487. }
  488.  
  489. #send to db
  490. sub dbstore
  491. {
  492.         $url = "http://optimumapp.iptv.optimum.net/iotvlogger.jsp?type=msr_mac";
  493.         $i = 0;
  494.         while ( my ($key, $value) = each(%sysvals) ) {
  495.                 $url .= "&$key=".uri_escape($value);
  496.         }
  497.        
  498.         print "$url\n";
  499.         $result = `curl -Sv "$url"`;
  500.         print $result;
  501. }
  502.  
  503. sub getOtherInfo
  504. {
  505.         #get additional info that was not already retrieved and used for the msr
  506.        
  507.         #mac addresses
  508.        
  509.         #osx serial
  510.         $cmd = 'system_profiler SPHardwareDataType | '.$serialNumCmd.' | cut -d : -f 2';
  511.         $sysvals{'osx_serial'}= trim(`$cmd`);
  512.        
  513.         #gpu
  514.         $sysvals{'gpu_name'}= trim(`system_profiler SPDisplaysDataType | grep "Chipset Model:" | cut -d : -f 2`);
  515.        
  516.         #gpu_ram
  517.         $sysvals{'gpu_ram'}=trim(`system_profiler SPDisplaysDataType | grep "VRAM" | cut -d : -f 2 | tr -cd 0-9`);
  518.        
  519. }
  520.  
  521. sub exitWarn
  522. {
  523.         $sysvals{'result'}="W";
  524.         my $warnOffset = 32;
  525.         $sysvals{'resultCode'}=$_[0];
  526.         dbstore();
  527.         exit ($_[0] + $warnOffset);
  528. }
  529.  
  530. sub exitFail
  531. {
  532.         $sysvals{'result'}="F";
  533.         my $failOffset = 96;#for utest 32;
  534.         $sysvals{'resultCode'}=$_[0];
  535.         #print"exitfail $_[0] offsetresult is ($_[0]+$failOffset)\n";
  536.         dbstore();
  537.         exit ($_[0] + $failOffset);
  538. }
  539.  
  540. sub exitSuccess
  541. {
  542.         $sysvals{'result'}="P";
  543.         dbstore();
  544.         exit 0;
  545. }
  546.  
  547. #retrieve info
  548. $sysvals{'app_version'} = "1.56";
  549.  
  550. #high priority checks
  551. $cpu = checkCPU();
  552. $mem = checkMem();
  553. $osx = checkOSX();
  554.  
  555. #ensure that silverlight check is done AFTER OSX check due to Lion check
  556. $slversion = checkSilverlight();
  557.  
  558. #misc check warnings
  559. $disk = checkFreeDisk();
  560. $wifi = checkWiFiTwo();
  561. $admin = checkAdmin();
  562. $laptop = checkLaptop();
  563. $external = checkExternal();
  564. getOtherInfo();
  565.  
  566. #return custom error codes for each class of failure
  567. #order is important here
  568.  
  569. #no longer returning all of these error codes
  570. if($cpu && $mem && $osx){
  571.         print "RESULT: CPU, Mem and OSX Fail\n";
  572.         exitFail(16);  
  573. }
  574.  
  575. if($cpu && $mem){
  576.         print "RESULT: CPU and Mem Fail\n";
  577.         exitFail(17);
  578. }
  579.  
  580. if($cpu && $osx){
  581.         print "RESULT: CPU and OSX Fail\n";
  582.         exitFail(18);
  583. }
  584.  
  585. if($mem && $osx){
  586.         print "RESULT: Mem and OSX Fail\n";
  587.         exitFail(19);
  588. }
  589.  
  590. if($cpu){
  591.         print "RESULT: CPU Fail\n";
  592.         exitFail(20);
  593. }
  594.  
  595. if($mem){
  596.         print "RESULT: Mem Fail\n";
  597.         exitFail(21);
  598. }
  599.  
  600. if($osx){
  601.         print "RESULT: OSX Fail\n";
  602.         exitFail(22);
  603. }
  604.  
  605. if($laptop)
  606. {
  607.         print "RESULT: not laptop\n";
  608.         exitFail(28);
  609. }
  610.  
  611. if($external)
  612. {
  613.         print "RESULT: external detected\n";
  614.         exitFail(27);  
  615. }
  616.  
  617. #if($disk && $wifi){
  618. #       print "RESULT: Disk and Wifi Fail\n";
  619. #       exitWarn(23);   #warning only
  620. #}
  621.  
  622. #if($disk){
  623. #       print "RESULT: Disk Fail\n";
  624. #       exitWarn(24);   #warning only
  625. #}
  626.  
  627. #if($wifi){
  628. #       print "RESULT: Wifi Fail\n";
  629. #       exitWarn(25); #warning only
  630. #}
  631.  
  632. if($slversion){
  633.         print "RESULT: Silverlight Version Fail\n";
  634.         my $sldl = $ARGV[0]."/Contents/Resources/sldl.sh";
  635.         my $response = `"$sldl"`; #need to place quotes to account for spaces in path
  636.         if(index($response, "Yes") != -1)
  637.         {
  638.                 `open http://go2.microsoft.com/fwlink/?LinkID=149156`;
  639.         }
  640.         exitFail(29); #warning only
  641. }
  642.  
  643. if($admin){
  644.         print "RESULT: Admin Fail\n";
  645.         exitWarn(26);   #warning only
  646. }
  647.  
  648.  
  649. #otherwise successful
  650. exitSuccess();