#!/bin/sh # FIXME: does not work with space in filenames or directories # (can be fixed by | while read ... the ldd output, but.. why?) # FIXME: directory permissions are not copied # (can be fixed with stat -f '%p %u %g' . and walk the path with mkdir -m ...) ## ## USAGE ## _usage() { echo "usage: mkchroot [-xn] [-u or executable] directory" echo "options: -u - runs for all executables found in /bin/ directories" echo " -x - copy stuff required to connect to X" echo " -n - copy stuff required for networking" } ## ## HANDLE ARGUMENTS ## while getopts xnuh arg do case $arg in x) _with_x=1 ;; # creates /tmp with X connection n) _with_network=1 ;; # copies resolv.conf u) _update_mode=1 ;; # updates the existing directory h) _usage; exit 0 ;; esac done shift $(($OPTIND - 1)) if [ -z "$1" ] && [ -z "$_update_mode" ] then _usage exit 1 fi if [ -z "$2" ] && [ -z "$_update_mode" ] then _usage exit 1 fi if [ "$_update_mode" == "1" ] then _indir="$1" else _infile="$1" _indir="$2" fi ### ### FUNCTIONS ### _ldd_extract() { for _file in $(ldd "$1" | awk '/\// { print $7 }' | xargs) do _name="$(basename "$_file")" _dir="$2/$(dirname "$_file" | cut -b2-)" if [ ! -d "$_dir" ] then echo "mkdir: $_dir" mkdir -p "$_dir" fi if [ ! -f "$_dir/$_name" ] then echo "copy: $_file -> $_dir/$_name" cp -af "$_file" "$_dir/$_name" else echo "skip: $_file -> $_dir/$_name (existing)" fi done } _find_binfile() { # remove basedir _f=$(echo "$1" | sed "s|${1%%/*}||g") _ofile="$(readlink -f "$_f" 2> /dev/null)" echo $_ofile } ### ### MAIN PROGRAM ### if [ -z "$_update_mode" ] then _ldd_extract "$_infile" "$_indir" fi if [ "$_update_mode" == "1" ] then _binfiles="$(find "$_indir" -type f -path "*/bin/*")" for _binfile in $_binfiles do _infile= _infile=$(_find_binfile "$_binfile") if [ -z "$_infile" ] then echo "skip: $_binfile -> $_infile (not found)" else _ldd_extract "$_infile" "$_indir" fi done fi