Created
January 11, 2025 00:46
-
-
Save nyteshade/d964db0da6539d3709c04da9d4a77038 to your computer and use it in GitHub Desktop.
unpkg - For extracting .pkg files on the macintosh
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/zsh | |
# A functon that shows users how to use the script. It describes | |
# and offers some help text that appears when invoked without | |
# parameters. | |
showUsage() { | |
local tool="\x1b[1;35munpkg\x1b[22;39m" | |
printf "${tool} <path-to-package.pkg> <destination-directory>\n\n" | |
printf "${tool} will attempt to unpackage the \x1b[1m.pkg\x1b[0m file provided,\n" | |
printf "however, if certain expectations are not met, it will stop and inform\n" | |
printf "to the best of its ability, what you should do to continue manually.\n" | |
} | |
# Print a message when a file (first parameter) is missing from an | |
# indicated path | |
missingFile() { | |
printf "The file specified ${1}, cannot be found.\n" | |
} | |
# Print a message when a directory (first parameter) is missing from | |
# an indicated path | |
missingDir() { | |
printf "The directory ${1}, cannot be found.\n" | |
} | |
# Generate a random string of the supplied length, defaults to 8 | |
# characters long. | |
randString() { | |
local -a alpha | |
local string="" | |
local count="${1:-8}" | |
local r=0 | |
for i in {a..z} {A..Z} {0..9}; do | |
alpha+=( "${i}" ) | |
done | |
for ((i = 0; i < count; i++)); do | |
r=$(($RANDOM % 62)) | |
string="${string}${alpha[$r]}" | |
done | |
printf "${string}" | |
} | |
# If we don't have at least two parameters, show the usage | |
# text and quit | |
if [[ "${#}" -lt 2 ]]; then | |
showUsage | |
exit 0 | |
fi | |
# If the file cannot be found, show the missing file text | |
# and quit | |
if ! [[ -f "${1}" ]]; then | |
missingFile "${1}" | |
exit 1 | |
fi | |
# If the output directory cannot be found, show the missing | |
# directory text and quit | |
if ! [[ -d "${2}" ]]; then | |
missingDir "${2}" | |
exit 1 | |
fi | |
# Declare some local variables for file, output directory, | |
# temporary directory, and the current directory | |
local file="${1}" | |
local outDir="${2}" | |
local tmpDir="/tmp/$(randString)" | |
local curDir="$(pwd)" | |
# Remove the temporary directory and contents, if possible, | |
# return to the original directory and exit with the status | |
# code supplied (or defaults to 0) | |
cleanup() { | |
cd "${curDir}" | |
rm 2>&1 >/dev/null -rf "${tmpDir}" | |
if ! [[ "${?}" -eq 0 ]]; then | |
printf "Could not remove temp directory '${tmpDir}'\n" | |
fi | |
exit ${1:-0} | |
} | |
# Create the temporary directory | |
mkdir -p "${tmpDir}" | |
# If we cannot create the temp directory, print a message, | |
# and cleanup with a status of 1 | |
if ! [[ "$?" -eq 0 ]]; then | |
printf "Could not create temporary directory ${tmpDir}\n" | |
cleanup 1 | |
fi | |
# Move to the temporary directory | |
cd "${tmpDir}" | |
# Extract, using xar, the package file | |
xar -xf "${file}" | |
# Within the extracted files, should be a file called Payload. | |
# Find the path to this file. | |
local payload="$(realpath $(find . -type f -name 'Payload'))" | |
# If we cannot find the Payload file, then stop and instruct the | |
# caller on what to do. At this point, we should not try to proceed | |
if [[ "${#payload}" -eq 0 ]]; then | |
printf "Could not find a file called 'Payload' in the extracted contents.\n" | |
printf "Find the file, move to your target directory, then run\n" | |
printf "cat ${tmpDir}/path/to/file | gunzip -dc | cpio -i\n" | |
exit 1 | |
fi | |
# Move to the output directory | |
cd "${outDir}" | |
# Invoke the holy trinity of commands to extract the Payload file | |
cat "${payload}" | gunzip -dc | cpio -i | |
# Remove the temp directory as its contents are no longer needed | |
rm 2>&1 >/dev/null -rf "${tmpDir}" | |
# Let the user know if we could not clean up | |
if ! [[ "${?}" -eq 0 ]]; then | |
printf "Could not remove ${tmpDir}" | |
fi | |
# Clean up and exit with status 0 | |
cleanup |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment