export EXPORT_DIR=/export
function usage() {
echo "usage: $(basename $0) [-v] [-d export-dir ] [-p package | -f file]" >&2
echo " $@" >&2
}
function parse_commandline() {
while getopts "vp:f:d:" OPT; do
case "$OPT" in
v)
VERBOSE=v
;;
p)
PACKAGES="$PACKAGES $OPTARG"
;;
f)
FILES="$FILES $OPTARG"
;;
d)
EXPORT_DIR="$OPTARG"
;;
*)
usage
exit 1
;;
esac
done
shift $((OPTIND-1))
if [ -z "$PACKAGES" -a -z "$FILES" ] ; then
usage "Missing -p or -f options"
exit 1
fi
if [ ! -d $EXPORT_DIR ] ; then
usage "$EXPORT_DIR is not a directory."
exit 1
fi
}
function print_file() {
if [ "$1" = "/usr/bin/ldd" ]; then
exit
fi
if [ -e "$1" ] ; then
echo "$1"
else
test -n "$VERBOSE" && echo "INFO: ignoring not existent file '$1'" >&2
fi
if [ -s "$1" ] ; then
TARGET=$(readlink "$1")
if [ -n "$TARGET" ] ; then
if expr "$TARGET" : '^/' >/dev/null 2>&1 ; then
list_dependencies "$TARGET"
else
list_dependencies $(dirname "$1")/"$TARGET"
fi
fi
fi
}
function list_dependencies() {
for FILE in $@ ; do
if [ -e "$FILE" ] ; then
print_file "$FILE"
if /usr/bin/ldd "$FILE" >/dev/null 2>&1 ; then
/usr/bin/ldd "$FILE" | \
awk '/statically/{next;} /=>/ { print $3; next; } { print $1 }' | \
while read LINE ; do
test -n "$VERBOSE" && echo "INFO: including $LINE" >&2
print_file "$LINE"
done
fi
else
test -n "$VERBOSE" && echo "INFO: ignoring not existent file $FILE" >&2
fi
done
}
function list_packages() {
if test -e /usr/bin/dpkg; then
DEPS=$(/usr/bin/dpkg -L $1)
elif test -e /usr/bin/rpm; then
DEPS=$(/usr/bin/rpm -ql $1)
elif test -e /sbin/apk; then
DEPS=$(/sbin/apk info -L $1 | grep -Ev '^$|contains:' | sed 's/^/\//g')
else
echo 'WARN: Unknown OS, aborted list_packages()'
exit
fi
while read FILE ; do
if [ ! -d "$FILE" ] ; then
list_dependencies "$FILE"
fi
done <<< "$DEPS"
}
function list_all_packages() {
for i in "$@" ; do
list_packages "$i"
done
}
parse_commandline "$@"
tar czf - $(
(
list_all_packages $PACKAGES
list_dependencies $FILES
) | sort -u
) | ( cd $EXPORT_DIR ; tar -xzh${VERBOSE}f - )