1 #! /bin/bash 2 3 # Print usage information 4 function print_help() { 5 echo "Usage: fakeroot [-m <size>] [-c <cpiopath>] [-C <cpiofile>] [-T <tmpfile>] [-hrz] [--] <command>..." 6 } 7 8 # Parse arguments 9 mem='512M' 10 cpiodir='' 11 cpiofile='out.cpio' 12 tmpfile='' 13 add_args='' 14 gzip_cpio='0' 15 readonly='0' 16 while getopts 'm:c:C:T:hrz' var; do 17 case "${var}" in 18 m) 19 mem="${OPTARG}" 20 ;; 21 c) 22 cpiodir="${OPTARG}" 23 ;; 24 C) 25 cpiofile="${OPTARG}" 26 ;; 27 T) 28 tmpfile="${OPTARG}" 29 ;; 30 z) 31 gzip_cpio='1' 32 ;; 33 r) 34 readonly='1' 35 ;; 36 h) 37 print_help 38 39 exit 0 40 ;; 41 *) 42 print_help >&2 43 44 exit 1 45 ;; 46 esac 47 done 48 shift $[${OPTIND} - 1] 49 50 if [ -z "$*" ]; then 51 echo "Command not specified." >&2 52 53 print_help >&2 54 55 exit 1 56 fi 57 58 # Locate path to our script 59 ourdir="$(dirname "$(which "$0")")" 60 61 # Define path to root image 62 rootfs="${ourdir}/uml_root.img" 63 64 # Build UML root image if needed 65 if [ ! -e "${rootfs}" ]; then 66 ( 67 PATH="${PATH}:/usr/sbin:/sbin" 68 export PATH 69 70 cd "${ourdir}" || exit 1 71 72 rm -rf uml_root.new 73 mkdir uml_root.new uml_root.new/bin uml_root.new/lib uml_root.new/host uml_root.new/proc uml_root.new/tmp 74 ln -s . uml_root.new/usr 75 ln -s lib uml_root.new/lib64 76 ln -s lib uml_root.new/lib32 77 ln -s bin uml_root.new/sbin 78 cp $(which bash mount cp chroot) uml_root.new/bin 79 cp bin/uml_root_init uml_root.new/init 80 echo -ne '#include <unistd.h>\n#include <sys/reboot.h>\nint main(int argc, char **argv) { sync(); return(reboot(RB_HALT_SYSTEM)); }' | gcc -Wall -x c -o uml_root.new/bin/halt - 81 ./bin/copy-bin-libs uml_root.new/bin uml_root.new/lib 82 rm -rf uml_root 83 mv uml_root.new uml_root 84 85 rm -f uml_root.img.new 86 ( cd uml_root && find | cpio -o -H newc ) | gzip -9c > uml_root.img.new 87 mv uml_root.img.new uml_root.img 88 89 rm -rf uml_root 90 ) 91 fi 92 93 # Create UML kernel if needed 94 if [ ! -e "${ourdir}/linux" ]; then 95 ${MAKE:-make} -C "${ourdir}" linux 96 fi 97 98 # Create SLiRP binary, if needed 99 if [ ! -e "${ourdir}/slirp" ]; then 100 ${MAKE:-make} -C "${ourdir}" slirp 101 fi 102 103 # Create tmpfile, if requested 104 if [ -n "${tmpfile}" ]; then 105 if [ ! -e "${tmpfile}" ]; then 106 rm -f "${tmpfile}" 107 108 ## Create 2GB file 109 dd if=/dev/zero of="${tmpfile}" bs=1024 count=1 seek=$[6 * 1024 * 1024 - 1] 2>/dev/null >/dev/null 110 111 ## Put ext2 filesystem on it 112 ( 113 PATH="${PATH}:/sbin:/usr/sbin:/usr/local/sbin" 114 115 mkfs -F -t ext2 "${tmpfile}" >/dev/null 2>/dev/null 116 ) 117 fi 118 119 ## Attach the disk to the UML image 120 add_args="${add_args} ubd1d=$(set | grep '^tmpfile=' | cut -f 2- -d =)" 121 122 if [ "${readonly}" = '1' ]; then 123 add_args="${add_args} fakeroot_disk_readonly" 124 fi 125 fi 126 127 marker="::${RANDOM}${RANDOM}${RANDOM}${RANDOM}${RANDOM}${RANDOM}${RANDOM}${RANDOM}__" 128 script="/tmp/fakeroot-script-${RANDOM}${RANDOM}${RANDOM}${RANDOM}${RANDOM}${RANDOM}${RANDOM}${RANDOM}" 129 130 # Create a script to run in the fake root environment 131 echo '#! /bin/bash' > "${script}" 132 export >> "${script}" 133 echo "hostname $(hostname)" >> "${script}" 134 echo "cd $(set | grep '^PWD=' | cut -f 2- -d =)" >> "${script}" 135 cat << \__SCRIPT_EOF__ >> "${script}" 136 PATH="/tmp/fakebin:/sbin:/usr/sbin:/usr/local/sbin:${PATH}" 137 export PATH 138 139 ifconfig lo 127.0.0.1 netmask 255.0.0.0 broadcast 127.255.255.25 140 ifconfig eth0 10.0.2.14 netmask 255.255.255.240 broadcast 10.0.2.15 141 route add default gw 10.0.2.2 142 143 __SCRIPT_EOF__ 144 145 cat << __SCRIPT_EOF__ >> "${script}" 146 cat << \_EOF_ > /tmp/hosts 147 10.0.2.14 $(hostname) $(hostname --fqdn) 148 __SCRIPT_EOF__ 149 150 getent hosts | sed 's@$@ @' | grep -v " $(hostname) " >> "${script}" 151 152 cat << __SCRIPT_EOF__ >> "${script}" 153 _EOF_ 154 mount -n --bind /tmp/hosts /etc/hosts 155 __SCRIPT_EOF__ 156 157 echo "echo -n ${marker}" >> "${script}" 158 for arg in "$@"; do 159 echo -n "$(set | grep '^arg=' | cut -f 2- -d =) " >> "${script}" 160 done 161 echo "" >> "${script}" 162 echo 'retval=$?' >> "${script}" 163 echo "echo -n ${marker}" >> "${script}" 164 echo "echo \${retval} > /tmp/root/${script}.retval" >> "${script}" 165 166 # If a cpio directory was specified, create a cpio file from it 167 if [ -n "${cpiodir}" ]; then 168 echo 'if [ "${retval}" = "0" ]; then' >> "${script}" 169 echo -n "( cd $(set | grep '^cpiodir=' | cut -f 2- -d =) && find . -xdev -print0 | cpio -o -0 -H newc )" >> "${script}" 170 if [ "${gzip_cpio}" = '1' ]; then 171 echo -n " | gzip -1c" >> "${script}" 172 fi 173 echo " > $(set | grep '^cpiofile=' | cut -f 2- -d =)" >> "${script}" 174 echo 'fi' >> "${script}" 175 fi 176 177 chmod 700 "${script}" 178 179 if ! tty 2>/dev/null >/dev/null; then 180 con="con=null,fd:1" 181 else 182 con="con=fd:0,fd:1" 183 fi 184 185 # Launch the kernel 186 rm -f "${script}.retval" 187 echo '-1' > "${script}.retval" 188 "${ourdir}/linux" "${con}" ssl=null mem="${mem}" initrd="${rootfs}" eth0=slirp,,"${ourdir}/slirp" quiet hostfs=/ ${add_args} script="/tmp/root${script}" 2>/dev/null | "${ourdir}/bin/line-cut" "${marker}" 189 retval="$(cat "${script}.retval")" 190 191 # Reset our tty 192 stty echo opost 2>/dev/null 193 194 # Cleanup 195 rm -f "${script}" "${script}.retval" 196 197 # Exit with the return value of the script 198 exit "${retval}" |