#!/bin/sh
## 
## Copyright 2018-2022 The Regents of the University of California
## All rights reserved.
## 
## This file is part of Spoofer.
## 
## Spoofer is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
## 
## Spoofer is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
## 
## You should have received a copy of the GNU General Public License
## along with Spoofer.  If not, see <http://www.gnu.org/licenses/>.
## 


usage() {
    cat <<EOF
usage: $0 <bundle> ...

Finds unportable shared library references within app <bundle>, copies those
shared libraries to bundle's Frameworks, and modifies the binaries to refer to
the copies.  (macdeployqt already does this for Qt libaries, but not
necessarily other libaries.)
EOF
}

fixfile() {
    bundle="$1"
    prefix="$2"
    f="$3"
    echo "    $f"
    otool -L "$f" | sed -E -ne '\;(:$|@|/usr/lib|/System/Library);!s/^.(.*.dylib)( \(.*\))*$/\1/p' | while read lib; do
	base=$(basename "$lib")
	new="$prefix/$base"
	echo "        change: $lib"
	echo "        to:     $new"
	if ! test -f "$bundle/Contents/Frameworks/$base"; then
	    cp "$lib" "$bundle/Contents/Frameworks"
	    newlibs="$newlibs $base"
	fi
	install_name_tool -change "$lib" "$new" "$f"
    done
}


set -e
if test "$#" = 0 || test "$1" = "-?" || test $1 = "--help"; then
    usage
    exit 0
fi

for bundle in "$@"; do
    echo "$bundle"
    test -d "$bundle/Contents/MacOS" || { echo >&2 "$bundle does not appear to be an app bundle."; exit 1; }

    # fix binaries
    for f in "$bundle/Contents/MacOS/"*; do
	if file "$f" | egrep executable | egrep -v -q script; then
	    fixfile "$bundle" "@executable_path/../Frameworks" "$f"
	fi
    done

    # fix libraries
    newlibs=""; # global, ugh
    if test -d "$bundle/Contents/Frameworks"; then
	for f in "$bundle/Contents/Frameworks/"*".dylib"; do
	    fixfile "$bundle" "@loader_path" "$f"
	done
    fi

    # now repeat the process on any libraries we just copied
    while test -n "$newlibs"; do
	libs="$newlibs"
	newlibs=""
	for f in $libs; do
	    fixfile "$bundle" "@loader_path" "$bundle/Contents/Frameworks/$f"
	done
    done
done
