weldon
11/16/2018 - 7:33 PM

Download all ipsws

Download all ipsws

#!/bin/sh


PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/libexec:/usr/local/bin
export PATH

### Begin user editable values ###

# Set the following to the location you wish to download to, we will attempt to make it if it doesn't exist
TARGET_DIR="/Users/Shared/IPSWs"

### End user editable values ###

# Internal variables, do not edit
THE_LIST_URL="http://ax.phobos.apple.com.edgesuite.net/WebObjects/MZStore.woa/wa/com.apple.jingle.appserver.client.MZITunesClientCheck/version"
PROG_NAME=`basename "${0}"`
DATE=`date +%Y-%m-%d_%H:%M:%S`
LOG_LOCATION="${HOME}/Library/Logs/${PROG_NAME}"
LOG_FILE_NAME="${PROG_NAME}_${DATE}.log"
BACKGROUND="true"
FORCE_UPDATE="false"
VERBOSE="false"

# parse the options...
while getopts 'wfvhl' OPTION
do
	case ${OPTION} in
		w)	BACKGROUND="false"	# Remove the &
			;;
		f)	FORCE_UPDATE="true"
			;;
		v)	VERBOSE="true"
			;;
		l)	mkdir -p "${LOG_LOCATION}"
			set -x
			exec 1>>"${LOG_LOCATION}"/"${LOG_FILE_NAME}" 2>&1
			;;
		?)	cat >&2 <<-EOF
			Usage: ${PROG_NAME}: [-h] [-w] [-f] [-v] [target_dir]
			
			Download available IPSWs to ${TARGET_DIR} or target_dir, if specified.
			
			Options:
			-w  Wait for downloads. Default is to schedule downloads in the background
			    and exit.
			-f  Force downloading of all updates. Default is to download only IPSWs
			    that are not already in the target directory.
			-v  Verbose output. Default is to operate silently.
			-l  Enables logging to the directory ${LOG_LOCATION}.
			    Default is to not log.
			-h  Print this message and exit.
			EOF
			exit 1
			;;
	esac
done
# and eat them
shift $((OPTIND - 1))

# If an arg has been specified, use it as the target
if [ "${1}" != "" ]; then
	TARGET_DIR=${1}
fi

# Try to make the target directory, if it doesn't exist.
if [ ! -d "${TARGET_DIR}" ]; then	
	mkdir -p "${TARGET_DIR}"
	if [ $? -ne 0 ]; then
	        echo "$0: Can't create ${TARGET_DIR}, exiting..."
	        exit 2
	fi
fi

# Get a temp file
TEMP_FILE=`mktemp -q "/tmp/${PROG_NAME}.XXXXXX"`
if [ $? -ne 0 ]; then
        echo "$0: Can't create temp file, exiting..."
        exit 3
fi

DOWNLOAD_COUNT_FILE=`mktemp -q "/tmp/${PROG_NAME}.XXXXXX"`
if [ $? -ne 0 ]; then
        echo "$0: Can't create temp file, exiting..."
        exit 4
fi

DOWNLOAD_COUNT=0

# Fetch the catalog and filter for IPSW files
curl -s -L "$THE_LIST_URL" | grep -v "http://www.apple.com" | grep "http://.*ipsw" | sed -e 's/<string>//' -e 's/<\/string>//' | awk '{print $1}' | uniq | while read IPSW_URL; do
	# get just the FILE_NAME to save 
	FILE_NAME=`echo "$IPSW_URL" | awk 'BEGIN { FS="/" } ; { print $NF }'` 
	
	# Check the temp file for this filename
	grep -q "${FILE_NAME}" "${TEMP_FILE}"
	IN_FILE=$?
	
	if [ "${IN_FILE}" -ne "0" ]; then
		# It wasn't in the temp file, so we're not downloading it currently. Should we?
		if [ "${FORCE_UPDATE}" == "true" -o ! -e "${TARGET_DIR}/${FILE_NAME}" ]; then 
			echo "${FILE_NAME}" >> "${TEMP_FILE}"
			if [ "${VERBOSE}" == "true" ]; then
				echo "Fetching ${FILE_NAME}"
			fi
			if [ "${BACKGROUND}" == "true" ]; then
				curl -s -L "${IPSW_URL}" -o "${TARGET_DIR}/${FILE_NAME}" &
			else
				curl -s -L "${IPSW_URL}" -o "${TARGET_DIR}/${FILE_NAME}"
			fi
			DOWNLOAD_COUNT=`expr ${DOWNLOAD_COUNT} + 1`
			echo "${DOWNLOAD_COUNT}" > "${DOWNLOAD_COUNT_FILE}"
		fi
	fi
	
done

if [ "${VERBOSE}" == "true" ]; then
	DOWNLOAD_COUNT=`cat "${DOWNLOAD_COUNT_FILE}"`
	if [ "${BACKGROUND}" == "true" ]; then
		echo "Downloading ${DOWNLOAD_COUNT} iOS IPSW updates to ${TARGET_DIR} in the background."
	else
		echo "Downloaded ${DOWNLOAD_COUNT} iOS IPSW updates to ${TARGET_DIR}."
	fi
fi

# clean up the temporary files
rm "${TEMP_FILE}"
rm "${DOWNLOAD_COUNT_FILE}"

exit 0