Created
January 9, 2012 00:57
-
-
Save acidprime/1580344 to your computer and use it in GitHub Desktop.
Hardware Serial Number Validation script, compares CSV file from AppleCare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# set -vx | |
# Required commands | |
declare -x awk="/usr/bin/awk" | |
declare -x cat="/bin/cat" | |
declare -x dscl="/usr/bin/dscl" | |
declare -x defaults="/usr/bin/defaults" | |
declare -x du="/usr/bin/du" | |
declare -x id="/usr/bin/id" | |
declare -x ntpdate="ntpdate" | |
declare -x scutil="/usr/sbin/scutil" | |
declare -x perl="/usr/bin/perl" | |
declare -x basename="/usr/bin/basename" | |
declare -x date="/bin/date" | |
declare -x defaults="/usr/bin/defaults" | |
declare -x dscl="/usr/bin/dscl" | |
declare -x find="/usr/bin/find" | |
declare -x groups="/usr/bin/groups" | |
declare -x ls="/bin/ls" | |
declare -x mv="/bin/mv" | |
declare -x rm="/bin/rm " | |
declare -x rmdir="/bin/rmdir" | |
declare -x sudo="/usr/bin/sudo" | |
# -- Runtime varibles | |
declare -x REQCMDS="$awk $dscl $deaults $ntpdate $perl $scutil" | |
declare -x SCRIPT="${0##*/}" ; SCRIPTNAME="${SCRIPT%%\.*}" | |
declare -x SCRIPTPATH="$0" RUNDIRECTORY="${0%/*}" | |
declare -x SYSTEMVERSION="/System/Library/CoreServices/SystemVersion.plist" | |
declare -x OSVER="$("$defaults" read "${SYSTEMVERSION%.plist}" ProductVersion )" | |
#declare -x CONFIGFILE="${RUNDIRECTORY:?}/${SCRIPTNAME}.conf" | |
declare -x BUILDVERSION="2009051" | |
#[ "$EUID" != 0 ] && printf "%s\n" "This script requires root access ($EUID)!" && exit 1 | |
# -- Start the script log | |
# Set to "VERBOSE" for more logging prior to using -v | |
declare -x LOGLEVEL="NORMAL" SCRIPTLOG="/Library/Logs/${SCRIPT%%\.*}.log" | |
declare -i CURRENT_LOG_SIZE="$("$du" -hm "${SCRIPTLOG:?}" | | |
"$awk" '/^[0-9]/{print $1;exit}')" | |
if [ ${CURRENT_LOG_SIZE:=0} -gt 50 ] ; then | |
"$rm" "$SCRIPTLOG" | |
statusMessage "LOGSIZE:$CURRENT_LOG_SIZE, too large removing" | |
fi | |
exec 2>>"${SCRIPTLOG:?}" # Redirect standard error to log file | |
# Strip any extention from scriptname and log stderr to script log | |
if [ -n ${SCRIPTLOG:?"The script log has not been specified"} ] ; then | |
printf "%s\n" \ | |
"STARTED:$SCRIPTNAME:EUID:$EUID:$("$date" +%H:%M:%S): Mac OS X $OSVER:BUILD:$BUILDVERSION" >>"${SCRIPTLOG:?}" | |
printf "%s\n" "Log file is: ${SCRIPTLOG:?}" | |
fi | |
statusMessage() { # Status message function with type and now color! | |
# Requires SCRIPTLOG STATUS_TYPE=1 STATUS_MESSAGE=2 | |
declare date="${date:="/bin/date"}" | |
declare DATE="$("$date" -u "+%Y-%m-%d")" | |
declare STATUS_TYPE="$1" STATUS_MESSAGE="$2" | |
if [ "$ENABLECOLOR" = "YES" ] ; then | |
# Background Color | |
declare REDBG="41" WHITEBG="47" BLACKBG="40" | |
declare YELLOWBG="43" BLUEBG="44" GREENBG="42" | |
# Foreground Color | |
declare BLACKFG="30" WHITEFG="37" YELLOWFG="33" | |
declare BLUEFG="36" REDFG="31" | |
declare BOLD="1" NOTBOLD="0" | |
declare format='\033[%s;%s;%sm%s\033[0m\n' | |
# "Bold" "Background" "Forground" "Status message" | |
printf '\033[0m' # Clean up any previous color in the prompt | |
else | |
declare format='%s\n' | |
fi | |
# Function only seems to work on intel and higher. | |
showUIDialog(){ | |
statusMessage header "FUNCTION: # $FUNCNAME" ; unset EXITVALUE TRY | |
"$killall" -HUP "System Events" 2>/dev/null | |
declare -x UIMESSAGE="$1" | |
"$osascript" <<EOF | |
try | |
with timeout of 0.1 seconds | |
tell application "System Events" | |
set UIMESSAGE to (system attribute "UIMESSAGE") as string | |
activate | |
display dialog UIMESSAGE with icon 2 giving up after "3600" buttons "Dismiss" default button "Dismiss" | |
end tell | |
end timeout | |
end try | |
EOF | |
return 0 | |
} # END showUIDialog() | |
case "${STATUS_TYPE:?"Error status message with null type"}" in | |
progress) \ | |
[ -n "$LOGLEVEL" ] && | |
printf $format $NOTBOLD $WHITEBG $BLACKFG "PROGRESS:$STATUS_MESSAGE" ; | |
printf "%s\n" "$DATE:PROGRESS: $STATUS_MESSAGE" >> "${SCRIPTLOG:?}" ;; | |
# Used for general progress messages, always viewable | |
notice) \ | |
printf "%s\n" "$DATE:NOTICE:$STATUS_MESSAGE" >> "${SCRIPTLOG:?}" ; | |
[ -n "$LOGLEVEL" ] && | |
printf $format $NOTBOLD $YELLOWBG $BLACKFG "NOTICE :$STATUS_MESSAGE" ;; | |
# Notifications of non-fatal errors , always viewable | |
error) \ | |
printf "%s\n\a" "$DATE:ERROR:$STATUS_MESSAGE" >> "${SCRIPTLOG:?}" ; | |
[ -n "$LOGLEVEL" ] && | |
printf $format $NOTBOLD $REDBG $YELLOWFG "ERROR :$STATUS_MESSAGE" ;; | |
# Errors , always viewable | |
verbose) \ | |
printf "%s\n" "$DATE:VERBOSE: $STATUS_MESSAGE" >> "${SCRIPTLOG:?}" ; | |
[ "$LOGLEVEL" = "VERBOSE" ] && | |
printf $format $NOTBOLD $WHITEBG $BLACKFG "VERBOSE :$STATUS_MESSAGE" ;; | |
# All verbose output | |
header) \ | |
[ "$LOGLEVEL" = "VERBOSE" ] && | |
printf $format $NOTBOLD $BLUEBG $BLUEFG "VERBOSE :$STATUS_MESSAGE" ; | |
printf "%s\n" "$DATE:PROGRESS: $STATUS_MESSAGE" >> "${SCRIPTLOG:?}" ;; | |
# Function and section headers for the script | |
passed) \ | |
[ "$LOGLEVEL" = "VERBOSE" ] && | |
printf $format $NOTBOLD $GREENBG $BLACKFG "SANITY :$STATUS_MESSAGE" ; | |
printf "%s\n" "$DATE:SANITY: $STATUS_MESSAGE" >> "${SCRIPTLOG:?}" ;; | |
# Sanity checks and "good" information | |
graphical) \ | |
[ "$GUI" = "ENABLED" ] && | |
showUIDialog "$STATUS_MESSAGE" ;; | |
esac | |
return 0 | |
} # END statusMessage() | |
die() { # die Function | |
statusMessage header "FUNCTION: # $FUNCNAME" ; unset EXITVALUE | |
declare LASTDIETYPE="$1" LAST_MESSAGE="$2" LASTEXIT="$3" | |
declare LASTDIETYPE="${LASTDIETYPE:="UNTYPED"}" | |
if [ ${LASTEXIT:="192"} -gt 0 ] ; then | |
statusMessage error "$LASTDIETYPE :$LAST_MESSAGE:EXIT:$LASTEXIT" | |
# Print specific error message in red | |
else | |
statusMessage verbose "$LASTDIETYPE :$LAST_MESSAGE:EXIT:$LASTEXIT" | |
# Print specific error message in white | |
fi | |
statusMessage verbose "COMPLETED:$SCRIPT IN $SECONDS SECONDS" | |
"$killall" "System Events" | |
exit "${LASTEXIT}" # Exit with last status or 192 if none. | |
return 1 # Should never get here | |
} # END die() | |
cleanUp() { # -- Clean up of our inportant sessions variables and functions. | |
statusMessage header "FUNCTION: # $FUNCNAME" ; unset EXITVALUE | |
statusMessage verbose "TIME: $SCRIPT ran in $SECONDS seconds" | |
unset -f ${!check*} | |
[ "${ENABLECOLOR:-"ENABLECOLOR"}" = "YES" ] && printf '\033[0m' # Clear Color | |
if [ "$PPID" == 1 ] ; then # LaunchD is always PID 1 in 10.4+ | |
: # Future LaunchD code | |
fi | |
exec 2>&- # Reset the error redirects | |
return 0 | |
} # END cleanUp() | |
# Check script options | |
statusMessage header "GETOPTS: Processing script $# options:$@" | |
# ABOVE: Check to see if we are running as a postflight script,the installer creates $SCRIPT_NAME | |
[ $# = 0 ] && statusMessage verbose "No options given" | |
# If we are not running postflight and no parameters given, print usage to stderr and exit status 1 | |
while getopts vCud:f:c: SWITCH ; do | |
case $SWITCH in | |
v ) export LOGLEVEL="VERBOSE" ;; | |
C ) export ENABLECOLOR="YES" ;; | |
c ) export COMPARE_FILE="$OPTARG" ;; | |
u ) export GUI="ENABLED" ;; | |
d ) export SAVE_DIRECTORY="$OPTARG" ;; | |
f ) export CSV_FILE="$OPTARG" ;; | |
esac | |
done # END getopts | |
checkCommands() { # CHECK_CMDS Required Commands installed check using the REQCMDS varible. | |
declare -i FUNCSECONDS="$SECONDS" # Capture start time | |
statusMessage header "FUNCTION: # ${FUNCNAME}" ; unset EXITVALUE | |
declare REQCMDS="$1" | |
for RQCMD in ${REQCMDS:?} ; do | |
if [ -x "$RQCMD" ] ; then | |
statusMessage passed "PASSED: $RQCMD is executable" | |
else | |
# Export the command Name to the die status message can refernce it" | |
export RQCMD ; return 1 | |
fi | |
done | |
return 0 | |
declare -i FUNCTIME=$(( ${SECONDS:?} - ${FUNCSECONDS:?} )) | |
[ "${FUNCTIME:?}" != 0 ] && | |
statusMessage verbose "TIME:$FUNCNAME:Took $FUNCTIME seconds to EXIT:$EXITVALUE" | |
} # END checkCommands() | |
checkSystemVersion() { | |
# CHECK_OS Read the /Sys*/Lib*/CoreSer*/S*Version.plist value for OS version | |
statusMessage header "FUNCTION: # ${FUNCNAME}" ; unset EXITVALUE | |
declare OSVER="$1" | |
case "${OSVER:?}" in | |
10.0* | 10.1* | 10.2* | 10.3*) \ | |
die ERROR "$FUNCNAME: Unsupported OS version: $OSVER." 192 ;; | |
10.4*) \ | |
statusMessage passed "CHECK_OS: OS check: $OSVER successful!"; | |
return 0;; | |
10.5*) \ | |
statusMessage passed "CHECK_OS: OS check: $OSVER successful!"; | |
return 0;; | |
10.6*) \ | |
die ERROR "$FUNCNAME:$LINENO Unsupported OS:$OSVER is too new." 192 ;; | |
*) \ | |
die ERROR "CHECK_OS:$LINENO Unsupported OS:$OSVER unknown error" 192 ;; | |
esac | |
return 1 | |
} # END checkSystemVersion() | |
checkLineEndings(){ | |
declare -i FUNCSECONDS="$SECONDS" # Capture start time | |
declare FILE_TO_CHECK="$1" | |
statusMessage header "FUNCTION: # ${FUNCNAME}" ; unset EXITVALUE | |
if [ -f "$FILE_TO_CHECK" ] ; then | |
if ! $perl -ne "exit 1 if m/\r\n/;" "$FILE_TO_CHECK" ; then | |
statusMessage notice \ | |
"Incorrect line endings detected (probobly due to Mircosoft edit)" | |
statusMessage notice \ | |
"Backup: $CSV_FILE.bak" | |
$cp -f "$FILE_TO_CHECK" "$FILE_TO_CHECK".bak | |
statusMessage verbose 'Resetting line endings \r/\n/ to \n' | |
$perl -i -pe 's/\r/\n/g' "$FILE_TO_CHECK" | |
elif ! $perl -ne "exit 1 if m/\r/;" "$FILE_TO_CHECK" ; then | |
statusMessage notice \ | |
"Incorrect line endings detected (DOS?) fixing backup: $FILE_TO_CHECK.bak" | |
$cp -f "$FILE_TO_CHECK" "$FILE_TO_CHECK".bak | |
statusMessage verbose 'Resetting line endings \r/\n/' | |
$perl -i -pe 's/\r/\n/g' "$FILE_TO_CHECK" | |
fi | |
else | |
statusMessage error "File: $FILE_TO_CHECK does not exist" | |
die ERROR "Invalid file specified: $FILE_TO_CHECK" | |
fi | |
statusMessage verbose "TIME:$FUNCNAME:Took $FUNCTIME seconds to EXIT:$EXITVALUE" | |
} | |
statusMessage verbose "Using file: $CSV_FILE" | |
checkLineEndings "$CSV_FILE" | |
OLDIFS="$IFS" | |
IFS=$'\n' | |
for LINE in `$cat "$CSV_FILE"` ; do | |
let LINE_NUM++ | |
if [ $LINE_NUM -eq 1 ] ; then | |
statusMessage progress "Skipping first line:$LINE" | |
continue | |
fi | |
SERVER_HOSTNAME="$(echo "$LINE" | $awk -F',' '{print $4}')" | |
SERVER_IP="$(echo "$LINE" | $awk -F',' '{print $5}')" | |
XSERVE_SERIAL="$(echo "$LINE" | $awk -F',' '{print $15}')" | |
if [ ${SERVER_HOSTNAME:-null} = "null" ] ; then | |
continue | |
fi | |
checkLineEndings "$COMPARE_FILE" | |
declare -i SERIAL_VALID="$($cat "$COMPARE_FILE" | grep -c "$XSERVE_SERIAL")" | |
if [ $SERIAL_VALID -eq 1 ] ; then | |
statusMessage passed \ | |
"XSERVE_SERIAL[VALID]$SERVER_HOSTNAME ($SERVER_IP) : $XSERVE_SERIAL" | |
else | |
statusMessage error \ | |
"XSERVE_SERIAL[INVALID]$SERVER_HOSTNAME ($SERVER_IP) : $XSERVE_SERIAL" | |
fi | |
done | |
OLDIFS="$IFS" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment