Advertisement
s243a

psandbox.sh (wary)

Dec 12th, 2020 (edited)
1,340
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 28.79 KB | None | 0 0
  1. #!/bin/bash
  2. #Based on James Budiono 2015 sandbox.sh (version 10) but with many options added
  3. # version 10 - (2015) use pid/mount namespaces if available
  4. #
  5. # 0. directory locations
  6. #. $BOOTSTATE_PATH # AUFS_ROOT_ID
  7. #XTERM="defaultterm"
  8. #
  9. # All options below were added by s243a:
  10. #
  11. # -o, --output-file
  12. #    Just write layer paths to an output file but don't mount the sandbox.
  13. # --no-exit
  14. #   if an output file is specified (i.e. -o or --output-file) layer paths are just written to a file and the program exits unless the no-exit flag is specified.
  15. # f, --input-file
  16. #   read layer paths from a file rather than reading existing layers
  17. # m,--pmedia
  18. #   determines pupmodes. Refer to puppy boot parmaters
  19. # d, --pdrv
  20. #   this is the particiaion where the puppy files are located. The default is /mnt/home
  21. # s, psubdir
  22. #   this is the sub directory where the puppy files are located
  23. # c, --clear-env
  24. #   deletes enviornental variabls
  25. # --env-prefix
  26. #   enviornental variable prefix
  27. # b --boot-config
  28. #   path to boot config (e.g. /etc/rc.d/BOOTCONFIG
  29. # --disto-specs
  30. #   path to distro specs (e.g. /etc/DISTRO_SPECS; e.g. /initrd/distro-specs)
  31. # L, --layer
  32. #   a subgke kater
  33. #  e, --extra-sfs
  34. #   a list of extra sfs files (space seperated)
  35. #  u, --union-record
  36. # --xterm
  37. # --sandbox
  38. # -initrd
  39. # --save
  40. # --noexit
  41. # --psave
  42. # --pupmode
  43.  
  44. #I thought some assoitive arrays might be useful but I'm not using them yet.
  45. #declare -A KEYs_by_MNT_PT
  46. #declare -A KEYs_by_FILE_PATH
  47. #declare -A KEYs_by_trimmed_MNT_PT
  48. #declare -A KEYs_by_trimmed_FILE_PATH
  49. #declare -A MNT_PTs
  50. #declare -A FILE_PATHs
  51. #declare -A ON_status
  52. declare -a bind_sources
  53. declare -a bind_targets
  54. declare -a rev_bind_sources
  55. declare -a rev_bind_targets
  56. cd "$(dirname "$0")"
  57. MAX_STR_LEN=50
  58. if [ -f ../local/psandbox/sandbox.awk ]; then
  59.   SANDBOX_AWK="$(realpath ../local/psandbox/sandbox.awk)"
  60. elif [ -f /usr/local/psandbox/sandbox.awk ]; then
  61.  SANDBOX_AWK=/usr/local/psandbox/sandbox.awk
  62. fi
  63. SANDBOX_AWK_DIR="$(dirname $SANDBOX_AWK)"
  64. if [ -f ../local/psandbox/sb_db_rec_field.awk ]; then
  65.   SB_DB_REC_FIELD_AWK="$(realpath ../local/psandbox/sb_db_rec_field.awk)"
  66. elif [ -f /usr/local/psandbox/sb_db_rec_field.awk ]; then
  67.   SB_DB_REC_FIELD_AWK=/usr/local/psandbox/sb_db_rec_field.awk
  68. fi
  69.  
  70. if [ -f ../local/psandbox/sandbox_mnt_fn.sh ]; then
  71.   SANDBOX_MNT_FN="$(realpath ../local/psandbox/sandbox_mnt_fn.sh)"
  72. elif [ -f /usr/local/psandbox/sandbox_mnt_fn.sh ]; then
  73.   SANDBOX_MNT_FN=/usr/local/psandbox/sandbox_mnt_fn.sh
  74. fi
  75.  
  76. . "$SANDBOX_MNT_FN"
  77.  
  78. XTERM=${XTERM:-urxvt}
  79. SANDBOX_ROOT=${SANDBOX_ROOT:-/mnt/sb}
  80.  
  81. declare -a options2
  82. declare -a binds
  83. function log(){
  84.   local logfile="${2}"
  85.   local trace="$3"
  86.   #[ -z "$logfile" ] && LOGFILE
  87.   #[ -z "$trace" ] && trace=TRACE
  88.   if [ ! -z "$LOGFILE" ]; then
  89.     case "$1" in
  90.     init)
  91.       [ "$TRACE" = true ] && set -x
  92.       [ ! -z "$LOGFILE" ] && rm "$LOGFILE"
  93.       exec 6>&1           # Link file descriptor #6 with stdout.
  94.       #exec &1> >(tee -a "$LOGFILE")
  95.       #exec &2> >(tee -a "$LOGFILE")
  96.       exec &> >(tee -a "$LOGFILE")
  97.       ;;
  98.     start)
  99.       [ "$TRACE" = true ] && set -x
  100.       #exec &1> >(tee -a "$LOGFILE")
  101.       #exec &2> >(tee -a "$LOGFILE")
  102.       exec &> >(tee -a "$LOGFILE")
  103.       ;;
  104.     stop)
  105.       #https://stackoverflow.com/questions/21106465/restoring-stdout-and-stderr-to-default-value
  106.       [ "$TRACE" = true ] && set +x
  107.       exec 1>&6  
  108.       exec 6>&-      # Restore stdout and close file descriptor #6.
  109.       exec &2> /dev/stderr    
  110.       ;;
  111.     esac
  112.   fi    
  113. }
  114. function find_save(){
  115.   for prefix in '${DISTRO_FILE_PREFIX}save' '.*save'; do
  116.     for dir in "$PDRV/${PSUBDIR}" "PDRV";  do
  117.        
  118.       ONE_SAVE="$(ls $dir -1 | grep -m "${prefix}save")"
  119.       if [ -z "$ONE_SAVE" ]; then
  120.          continue
  121.       else
  122.          SAVE_FILE="$ONE_SAVE"
  123.          FULL_SAVE_PATH="$dir"/ONE_SAVE
  124.          break
  125.       fi
  126.     done
  127.    done
  128.    echo "PSAVE"mount_items
  129. }
  130. function find_bk_folders(){
  131.   for a_PDRV in "$PDRV" sr0 sr1; do #Consider adding /mnt/home here
  132.     for a_psubdir in "${PSUBDIR}" "";  do
  133.       MT_PT_of_Folder="$(mount_fn2 "$PDRV" "${PSUBDIR}")"
  134.       #https://github.com/puppylinux-woof-CE/woof-CE/blob/c483d010a8402c5a1711517c2dce782b3551a0b8/initrd-progs/0initrd/init#L981
  135.       BKFOLDERS="$(find $MT_PT_of_Folder -maxdepth 1 -xdev -type d -name '20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]-[0-9][0-9]' | sed -e s%^${SAVE_MP}/%% | sort -r)"
  136.       [ ! -z "#BKFOLDERS" ] && break  
  137.     done
  138.   done
  139. }
  140. function mount_items(){
  141.   local Moun_Point
  142.   local File_PATH #Might be a directory
  143.   cd "$SANDBOX_AWK_DIR"
  144.   while IFS="" read -r p || [ -n "$p" ]; do #https://stackoverflow.com/questions/1521462/looping-through-the-content-of-a-file-in-bash
  145.      File_PATH="$(echo "$1" | awk -v FIELD_NUM=6 -f "$SB_DB_REC_FIELD_AWK")"
  146.      Mount_Point="$(echo "$1" | awk -v FIELD_NUM=1 -f "$SB_DB_REC_FIELD_AWK")"
  147.      PDRV_MNT="$(echo "$1" | awk -v FIELD_NUM=7 -f "$SB_DB_REC_FIELD_AWK")"
  148.      PDRV_UUID="$(echo "$1" | awk -v FIELD_NUM=8 -f "$SB_DB_REC_FIELD_AWK")"
  149.      
  150.      [ -z "$PDRV_MNT" ] &&
  151.      mount_fn2 "PDRV" "$File_PATH" "$Moun_Point"
  152.   done <"$1"
  153. }
  154.  
  155. function mk_initrd_dir(){
  156.   mkdir -p "$FAKEROOT"/initrd
  157.   if [ -z "$PUPMODE" ] ; then
  158.     if [ -z "$PMEDIA" ]; then
  159.       #if [ "$PUPMODE" = 5 ] ; then
  160.       #  #aufs layers:              RW (top)      RO1             RO2              PUPMODE
  161.       #  #First boot (or pfix=ram): tmpfs                         pup_xxx.sfs      5
  162.       PUPMODE=5 #MAYBE PUPMODE=2 would be better
  163.     elif [ PMEDIA = 'atahd' ] || [ "$PMEDIA" = 'usbhd' ]; then
  164.       find_save
  165.       if [ -f "$FULL_SAVE_PATH" ] || [ -d "$FULL_SAVE_PATH" ]; then
  166.         #aufs layers:               RW (top)      RO1             RO2              PUPMODE
  167.         #Normal running puppy:      pup_save.3fs                  pup_xxx.sfs      12      
  168.         PUPMODE=12
  169.       else
  170.         echo "Invalid SAVE_PATH=$SAVE_PATH does not exist"
  171.         PUMPMODE=2
  172.         #TODO, prompt to either search for save file/folder or alternatively create it.
  173.       fi
  174.     elif [ PMEDIA = 'usbflash' ] || [ pmedia = 'ideflash' ]; then
  175.       find_save
  176.       #aufs layers:                 RW (top)      RO1             RO2              PUPMODE
  177.       #ditto, but flash drive:      tmpfs         pup_save.3fs    pup_xxx.sfs      13
  178.       if [ -f "$SAVE_PATH" ] || [ -d "$SAVE_PATH" ]; then
  179.         #aufs layers:               RW (top)      RO1             RO2              PUPMODE
  180.         #ditto, but flash drive:    tmpfs         pup_save.3fs    pup_xxx.sfs      13
  181.         PUPMODE=13
  182.       else
  183.         echo "Invalid SAVE_PATH=$SAVE_PATH does not exist"
  184.         PUPMODE=5
  185.       fi
  186.     elif [ "$PMEDIA" =  usbcd ] || [ "$PMEDIA" =  idecd ] || [ "$PMEDIA" =  satacd ] ; then
  187.       find_bk_folders
  188.       if [ ! -z "$BKFOLDERS" ]; then
  189.         PUPMODE=77  #MULTI-Session CD
  190.       else #First Boot
  191.         find_save
  192.         if [ -f "$FULL_SAVE_PATH" ] || [ -d "$FULL_SAVE_PATH" ]; then
  193.           PUPMODE=13      
  194.         else
  195.           PUPMODE=5
  196.         fi
  197.       fi
  198.       #aufs layers:            RW (top)      RO1             RO2              PUPMODE
  199.       #Multisession cd/dvd:       tmpfs         folders         pup_xxx.sfs      77
  200.     else #[PUPMODE=2 -> full install
  201.       PUPMODE=2
  202.     fi
  203.     if [ "$PUPMODE" = 2 ]; then #Full install
  204.       echo "Full install has no initrd"
  205.     else
  206.       mkdir -p "$FAKEROOT/initrd"
  207.       cd $FAKEROOT/initrd
  208.       if [ "$PUPMODE" = 12 ]; then # Usually [ PMEDIA = 'atahd' ] || [ "$PMEDIA" = usbhd ]
  209.         ln -s mnt/dev_save/"${SAVE_PATH}" pup_rw
  210.       elif [ "$PUPMODE" = 13 ] || [ "$PUPMODE" = 5 ] || [ "$PUPMODE" = 77 ]; then
  211.         ln -s mnt/tmpfs/pup_rw pup_rw
  212.         if [ "$PUPMODE" = 13 ]; then  # Usually [ PMEDIA = 'usbflash' ] || [ pmedia = 'ideflash' ]
  213.           ln -s "mnt/tmpfs/dev_save/${SAVE_PATH}" pup_ro1
  214.         elif [ "$PUPMODE" = 77 ]; then
  215.           ln -s mnt/tmpfs/pup_ro1/"${SAVE_PATH}" pup_ro1  #Usually [ "$PMEDIA" =  usbcd ] || [ "$PMEDIA" =  idecd ] || [ "$PMEDIA" =  satacd ]
  216.         fi
  217.       fi
  218.     fi
  219.   fi
  220. }
  221. function get_items(){
  222.     local out
  223.     OUTFILE=/tmp/get_items_out
  224.     rm "$OUTFILE"
  225.     cd "$SANDBOX_AWK_DIR"
  226.     out+="$(
  227.  { echo ==mount==; cat /proc/mounts;
  228.    echo ==losetup==; losetup-FULL -a;
  229.    echo ==branches==;
  230.      if [ $# -eq 0 ]; then
  231.        ls -v /sys/fs/aufs/$AUFS_ROOT_ID/br[0-9]* | xargs sed 's/=.*//';
  232.      else
  233.        if [ "$1" = "-f" ]; then
  234.          cat "$2";
  235.        elif [ "$1" = "-s" ]; then
  236.          cat <<<"$2";
  237.        fi;
  238.      fi; } | \
  239.    awk -v PDRV="$PDRV" -v MAX_STR_LEN="$MAX_STR_LEN" -v OUTFILE="$OUTFILE" \
  240. -f "$SANDBOX_AWK"
  241. )"
  242.   echo "$out"
  243. }
  244. function process_psubdir(){
  245.       item_source="$1"
  246.       if [ "$item_source" = "maybe-psubdir" ]; then
  247.          [ ! -z "$items" ] && continue
  248.       fi
  249.       [ -z "$DISTRO_ADRVSFS" ] && DISTRO_ADRVSFS="$(ls -1 "${PDRV}/${PSUBDIR}" | grep -i -m1 'adrv.*\.sfs$')"
  250.       [ -z "$DISTRO_YDRVSFS" ] && DISTRO_YDRVSFS="$(ls -1 "${PDRV}/${PSUBDIR}" | grep -i -m1 'ydrv.*\.sfs$')"  
  251.       [ -z "$DISTRO_ZDRVSFS" ] && DISTRO_ZDRVSFS="$(ls -1 "${PDRV}/${PSUBDIR}" | grep -i -m1 'zdrv.*\.sfs$')"
  252.       [ -z "$DISTRO_FDRVSFS" ] && DISTRO_FDRVSFS="$(ls -1 "${PDRV}/${PSUBDIR}" | grep -i -m1 'fdrv.*\.sfs$')"                        
  253.       [ -z "$DISTRO_PUPPYSFS" ] && DISTRO_PUPPYSFS="$(ls -1 "${PDRV}/${PSUBDIR}" | grep -i -m1 'puppy_.*\.sfs$')"
  254.  
  255.       new_items=""
  256.       for rec in "$DISTRO_ADRVSFS" "$DISTRO_YDRVSFS" "$DISTRO_ZDRVSFS" "$DISTRO_FDRVSFS" "$DISTRO_PUPPYSFS";  do
  257.         #MNT_PATH="${rec}"
  258.         [ -z "$rec" ] && continue
  259.         #[ ! -z "${PSUBDIR}" ] && MNT_PATH=${PSUBDIR}/${MNT_PATH}
  260.         MNT_PATH="${PDRV}/${PSUBDIR}/$rec"
  261.         MNT_PT="$(mount_fn "$MNT_PATH")"
  262.         new_items+="\"${MNT_PT}\" \"$rec\" \"on\""$'\n'
  263.        
  264.       done
  265.       #export new_items="$new_items"
  266.       #echo "$new_items"
  267.       items+="$(get_items -s "$new_items")"$'\n'
  268.      
  269. }
  270. process_union_record(){
  271.        new_items=''
  272.        for rec in $LASTUNIONRECORD; do
  273.         if [ -f "$rec" ]; then
  274.           MNT_PT="$(mount_fm "$rec" )"
  275.           new_items+="\"$MNT_PT\" \"$rec\" \"on\""$'\n'
  276.         elif [ -f "$PDRV/$rec" ]; then
  277.           MNT_PT="$(mount_fm "$PDRV/$rec" )"
  278.           new_items+="\"$MNT_PT\", \"$PDRV/$rec\", \"on\""$'\n'
  279.         fi
  280.       done
  281.       items+="$(get_items -f <<<"$new_items")"$'\n'    
  282. }
  283. process_extra_sfs(){
  284.      EXTRASFSLIST="$2";
  285.      unset new_items
  286.      if [ ! -f "$EXTRASFSLIST" ]; then
  287.        EXTRASFSLIST_tmp=$(realpath "$PDRV/$PSUBDIR/$EXTRASFSLIST")
  288.        if [ -f "$EXTRASFSLIST_tmp" ]; then
  289.          EXTRASFSLIST="$EXTRASFSLIST_tmp"
  290.        fi
  291.      fi
  292.      if [ ! -f "$EXTRASFSLIST" ]; then
  293.        EXTRASFSLIST_tmp=$(realpath "$PDRV/$EXTRASFSLIST")
  294.        if [ -f "$EXTRASFSLIST_tmp" ]; then
  295.          EXTRASFSLIST="$EXTRASFSLIST_tmp"
  296.        fi
  297.      fi
  298.      if [[ "$EXTRASFSLIST" = *.sfs ]]; then
  299.          a_sfs="$EXTRASFSLIST"
  300.          MNT_PT="$(mount_fn "$a_sfs" )"
  301.          new_items+="\"$MNT_PT\" \"$a_sfs\" \"on\""$'\n'
  302.      else
  303.        while read a_sfs; do
  304.          a_sfs=$(echo"$a_sfs") #Trims leading and trailing whitespace
  305.          if [ -f "$a_sfs" ]; then
  306.            a_sfs=$(realpath "$a_sfs")
  307.          else
  308.            a_sfs1="$PDRV/${PSUBDIR}/$a_sfs"
  309.            a_sfs=$(realpath "$a_sfs")
  310.            if [ -f "$a_sfs"]; then
  311.              a_sfs=$(realpath "$a_sfs")
  312.            else        
  313.              a_sfs1="$PDRV/$a_sfs1"
  314.              if [ -f "$a_sfs1" ]; then
  315.                a_sfs=$(realpath "$a_sfs")
  316.              fi            
  317.            fi
  318.          fi
  319.          if [ -f  "$a_sfs" ]; then
  320.            MNT_PT="$(mount_fn "$a_sfs" )"
  321.            new_items+="\"$MNT_PT\" \"$a_sfs\" \"on\""$'\n'        
  322.          fi
  323.        done <"$EXTRASFSLIST"
  324.      fi
  325.      items+="$(get_items -s "$new_items")"$'\n'
  326.      #items+="$(get_items -f <<<"$new_items")"
  327. }
  328. process_layer(){
  329.       item_path="$2"
  330.       if [ -f "$item_path" ]; then
  331.         MNT_PT="$(mount_fm "$item_path" )"
  332.       elif [ -d "$item_path" ]; then  
  333.         MNT_PT="$item_path" #This isn't really a mount poing
  334.       elif [ ! -d  "$item_path" ]; then
  335.         echo "Warning  cannot mount $item_path"
  336.         continue
  337.       fi
  338.       items+="\"$MNT_PT\" \"$item_path\" \"on\""$'\n'  
  339. }
  340. declare -a options="$(getopt -o f:,o:,m:,d:,s:,b:,e:,l:,t::,a::,u::,r::,j: --long input-file:output-file:,pmedia:,pdrv:,psubdir:,boot-config:,distro-specs:,extra-sfs:,aufs,maybe-aufs,maybe-psubdir:,no-exit::,psave:,pupmode:,logfile:,trace::,rw-layer:,copy-Xauth::,bind-X11-sockets::,copy-resolv_conf::,layer:,rev_bind:,bind:,before-chroot -- "$@")"
  341. eval set --"$options"
  342. while [ $# -gt 0 ]; do
  343.   echo "processing args: $@"
  344.   case "$1" in
  345.   -f|--input-file)
  346.      INPUT_FILE=$2
  347.     mount_items "$INPUT_FILE"
  348.     items+="$(get_items -f "$INPUT_FILE")"
  349.     shift 2; ;;      
  350.   -o|--output-file) OUTPUT_FILE=$2; shift 2; ;;
  351.   --no-exit)
  352.     if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
  353.       NO_EXIT="$2"
  354.       [ -z "$NO_EXI" ] && NO_EXIT=true
  355.       shift 2
  356.     else
  357.       NO_EXIT=true
  358.       shift 1
  359.     fi; ;;
  360.   -p|--env-prefix) ENV_PREFIX=$2; shift 2; ;;
  361.   -m|--pmedia) PMEDIA=$2; shift 2; ;;
  362.   -d| --pdrv) PDRV=$2; shift 2; ;;
  363.   -s|--psubdir) PSUBDIR=$2;
  364.     process_psubdir psubdir
  365.     shift 2; ;;
  366.     --maybe-psubdir) PSUBDIR=$2;
  367.     process_psubdir maybe-psubdir    
  368.     shift 2; ;;    
  369.   --distro-specs)
  370.      DISTRO_SPECS=$2;
  371.      [ -f "$DISTRO_SPECS" ] && . "$DISTRO_SPECS"
  372.      shift 2
  373.      ;;
  374.    --boot-config)
  375.        BOOTCONFIG=$2;
  376.      [ -f "$BOOTCONFIG" ] && . "$BOOTCONFIG"
  377.      shift 2
  378.      ;;
  379.    --union-record)  
  380.      LASTUNIONRECORD="$2";
  381.      process_union_record union-record "$LASTUNIONRECORD"
  382.      shift 2; ;;
  383.    -e|--extra-sfs)
  384.      EXTRASFSLIST="$2";
  385.      process_extra_sfs extra-sfs "$EXTRASFSLIST"
  386.      shift 2; ;;
  387.   --aufs)
  388.     items+="$(get_items)"
  389.     shift 1; ;;
  390.   --maybe-aufs)
  391.     [  -z "$items" ] && items+="$(get_items)"
  392.     shift 1; ;;
  393.   --psave)
  394.     PSAVE=$2
  395.     shift 2
  396.     ;;
  397.   --pupmode)
  398.     PUPMODE=$2
  399.     shift 2
  400.     ;;
  401.   --rw-layer)
  402.     RW_LAYER=$2
  403.     shift 2
  404.     ;;
  405.   --layer)
  406.     RW_LAYER=$2
  407.     process_layer layer $2
  408.     shift 2
  409.     ;;
  410.   -l|--logfile)
  411.     LOGFILE=$2
  412.     [ -z "$TRACE" ] && TRACE=true
  413.     shift 2
  414.     log init
  415.     ;;  
  416.   -t|--trace)
  417.     TRACE=$2
  418.     if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
  419.       TRACE="$2"
  420.       [ -z "$TRACE" ] && TRACE=true
  421.       shift 2
  422.     else
  423.       TRACE=true
  424.       shift 1
  425.     fi
  426.     log init
  427.     ;;
  428.   -a|--copy-Xauth)
  429.     if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
  430.       XAUTH=$(realpath "$2")
  431.       [ -z "$XAUTH" ] && XAUTH=$(realpath "~/.Xauthority")
  432.       shift 2
  433.     else
  434.       XAUTH=$(realpath "~/.Xauthority")
  435.       shift 1
  436.     fi
  437.     ;;
  438.   -u|--bind-X11-sockets)
  439.     if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
  440.       uSocketDir=$(realpath "$2")
  441.       [ -z "$uSocketDir" ] && uSocketDir=/tmp/.X11-unix
  442.       shift 2
  443.     else
  444.       uSocketDir=/tmp/.X11-unix
  445.       shift 1
  446.     fi
  447.     ;;
  448.   -r|--copy-resolv_conf)
  449.     if [ $# -gt 1 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ]; then
  450.       RESOLV_CONF_PATH=$(realpath "$2")
  451.       [ -z "$RESOLV_CONF_PATH" ] && RESOLV_CONF_PATH=/etc/resolv.conf
  452.       shift 2
  453.     else
  454.       RESOLV_CONF_PATH=/etc/resolv.conf
  455.       shift 1
  456.     fi
  457.     ;;
  458.   --rev_bind) #Bind the fakeroot into a folder (e.g. a samba share)
  459.        unset rev_b_source
  460.       unset rev_b_target
  461.       while true
  462.       do
  463.         if [ $# -lt 1 ]; then
  464.           break
  465.         fi
  466.         if [[ $1 = -* ]]; then
  467.           if [ ! -z "$rev_b_target" ]; then
  468.             break
  469.           else
  470.           #TODO, add some further checking here. What we want to do is eat the -- at the end of the positional parameters if we are missing a target.
  471.             shift
  472.             continue
  473.           fi
  474.         fi
  475.         if [ -z "$rev_b_source" ]; then
  476.           if [ ! -z "$1" ]; then
  477.             rev_b_source="$1"; shift
  478.             continue
  479.           fi
  480.         elif [ -z "$b_target" ]; then
  481.           if [ ! -z "$1" ]; then
  482.             rev_b_target="$1"; shift
  483.             rev_bind_sources+=( "$b_source" )
  484.             rev_bind_targets+=( "$b_target" )
  485.             unset rev_b_source
  486.             unset rev_b_target
  487.             shift
  488.             continue
  489.           fi        
  490.         fi
  491.         shift
  492.       done
  493.  #   fi
  494.     ;;
  495.   --before-chroot)
  496.      BEFORE_CHROOT_CMD="$2";
  497.      shift 2
  498.      ;;
  499.   --bind)
  500. #    if [ $# -ge 4 ] && [[ ! "$2" = --* ]] && [ ! -z "$2" ] && \
  501. #[[ "$3" = -j ]] && [[ ! "$4" = --* ]] && [ ! -z "$4" ]; then
  502. #       bind_source=$(realpath "$2")
  503. #       bind_target=$(realpath "$2")
  504. #       bind_sources+=( "$bind_source" )
  505. #       bind_targets+=( "$bind_target" )
  506. #       shift 4
  507. #    else
  508.       unset b_source
  509.       unset b_target
  510.       while true
  511.       do
  512.         if [ $# -lt 1 ]; then
  513.           break
  514.         fi
  515.         if [[ $1 = -* ]]; then
  516.           if [ ! -z "$b_target" ]; then
  517.             break
  518.           else
  519.           #TODO, add some further checking here. What we want to do is eat the -- at the end of the positional parameters if we are missing a target.
  520.             shift
  521.             continue
  522.           fi
  523.         fi
  524.         if [ -z "$b_source" ]; then
  525.           if [ ! -z "$1" ]; then
  526.             b_source="$1"; shift
  527.             continue
  528.           fi
  529.         elif [ -z "$b_target" ]; then
  530.           if [ ! -z "$1" ]; then
  531.             b_target="$1"; shift
  532.             bind_sources+=( "$b_source" )
  533.             bind_targets+=( "$b_target" )
  534.             unset b_source
  535.             unset b_target
  536.             shift
  537.             continue
  538.           fi        
  539.         fi
  540.         shift
  541.       done
  542.  #   fi
  543.     ;;          
  544.   --)
  545.     shift 1
  546.     options2+=( "$@" )
  547.     break; ;;
  548.   *)
  549.      options2+=( "$1" )
  550.      shift 1; ;;
  551.   esac
  552. done
  553. items="$(echo "$items" | sed -n '/^\s*\(on\)\?\s*$/! p' | sed -n '/^Error: Expected on/! p' | sed -n '/^Use --help on/! p')"
  554. #set -- "${options2[@]}"
  555. #if [ "$LAYER_SOURCE" = none ] && [ ! -z "$PDRV" ]; then
  556. #  PDRV=${PDRV:-/mnt/home}
  557. #  for rec in $LASTUNIONRECORD; do
  558. #    if [ -f "$PDRV/$rec" ]; then
  559. #      items+="\"$PDRV/$rec\" \"$rec\""$'\n'
  560. #    fi
  561. #  done
  562. #  if [ ! -z "$$PDRV" ]; then #if [ -z "$items" ]; then
  563. #    [ -z "$DISTRO_ADRVSFS" ] && DISTRO_ADRVSFS=$(ls -1 $PDRV | grep -i -m1 adrv.*\.sfs$)  
  564. #    [ -z "$DISTRO_YDRVSFS" ] && DISTRO_YDRVSFS=$(ls -1 $PDRV | grep -i -m1 ydrv.*\.sfs$)      
  565. #    [ -z "$DISTRO_ZDRVSFS" ] && DISTRO_ZDRVSFS=$(ls -1 $PDRV | grep -i -m1 zdrv.*\.sfs$)
  566. #    [ -z "$DISTRO_FDRVSFS" ] && DISTRO_FDRVSFS=$(ls -1 $PDRV | grep -i -m1 fdrv.*\.sfs$)        
  567. #    [ -z "$DISTRO_PUPPYSFS" ] && DISTRO_PUPPYSFS=$(ls -1 $PDRV | grep -i -m1 puppy_.*\.sfs$)
  568. #
  569. #    for rec in "$DISTRO_ADRVSFS" "$DISTRO_YDRVSFS" "$DISTRO_ZDRVSFS" "$DISTRO_FDRVSFS" "$DISTRO_PUPPYSFS"; do
  570. #      [ -z "$rec" ] && continue
  571. #      items+="$PDRV/$rec" "$rec"$'\n'  
  572. #    done
  573. #  fi
  574. #  #if [ ! -z "$items" ]; then  
  575. #  #  for rec in $EXTRASFSLIST; do
  576. #  #    if [ -f "$rec" ]; then
  577. #  #      items+="\"$PDRV/$rec\" \"$rec\" "on"\""$'\n'
  578. #  #    elif [ -f "$PDRV/$rec" ]; then
  579. #  #      items+="\"$PDRV/$rec\" \"$rec\" "on"\""$'\n'
  580. #  #    fi
  581. #  #  done
  582. #  #fi
  583. #fi
  584. #if [ -z "$items" ] && [ "$LAYER_SOURCE" = none ] ; then
  585. #    LAYER_SOURCE=aufs  
  586. #    LAYER_SOURCES+=( aufs )
  587. #fi
  588. #    for rec in "${LAYER_SOURCES[@]}"; do
  589. #      [ -z "$rec" ] && continue
  590. #      if [ -f "$rec" ]; then
  591. #        rec=$(realpath "$rec")
  592. #        rec_name=$(basename $rec);
  593. #        items+="'$rec' '$rec'"$'\n'
  594. #      elif [ -f "$PDRV/$rec" ]; then
  595. #        items+="'$PDRV/$rec' '$rec'"$'\n'
  596. #      fi
  597. #    done
  598. #[ -z "$PDRV" ] && PDRV="/mnt/home"
  599.  
  600. if [ "$(cat /proc/mounts | grep -c "$(realpath "$PDRV")")" = 0 ]; then
  601.  PDRV_DEV="$(blkid | grep -m1 "$PDRV" | cut -d ':' -f1)"
  602.  PDRV="$(echo "$PDRV_DEV" | sed 's#^/dev/#/mnt/#')"
  603.  mount "$PDRV_DEV" "$PDRVV"
  604. fi  
  605.  
  606.  
  607. FAKEROOT=$SANDBOX_ROOT/fakeroot   # mounted chroot location of sandbox - ie, the fake root
  608. [ -z "$RW_LAYER" ] && SANDBOX_TMPFS=$SANDBOX_ROOT/sandbox # mounted rw location of tmpfs used for sandbox
  609. DEV_SAVE=$SANDBOX_ROOT/dev_save
  610. mkdir -p "$DEV_SAVE"
  611.  
  612. SANDBOX_ID=
  613. TMPFILE=$(mktemp -p /tmp)
  614. # use namespaces if available
  615. #[ -e /proc/1/ns/pid ] && [ -e /proc/1/ns/mnt ] && type unshare >/dev/null && USE_NS=1
  616.  
  617.  
  618.  
  619.  
  620. # umount all if we are accidentally killed
  621. trap 'umountall' 1
  622. umountall() {
  623.  {
  624.  umount -l $FAKEROOT/$SANDBOX_TMPFS
  625.  if [ PUPMODE = 2 ]; then #Full Install
  626.      umount -l $FAKEROOT/tmp
  627.    else
  628.      umount -l $FAKEROOT/initrd/mnt/tmpfs
  629.    fi
  630.  for layer_name in "pup_ro2" "pup_ro3" "pup_ro4" "pup_ro5" "pup_z"; do
  631.    layer="$(eval 'echo $'$layer_name)"
  632.    if [ ! -z "$layer" ] ; then
  633.      umount -l "$FAKEROOT/initrd/$layer_name"
  634.    fi
  635.  done    
  636.  umount -l $FAKEROOT/proc
  637.  umount -l $FAKEROOT/sys
  638.  umount -l $FAKEROOT/dev
  639.  
  640.  umount -l $FAKEROOT
  641.  [ -z "$RW_LAYER" ] && umount -l $SANDBOX_TMPFS
  642.  rmdir $FAKEROOT
  643.  #if  [ PUPMODE = 2 ] || PUPMODE = 5 ]; then
  644.    [ -z "$RW_LAYER" ] && rmdir $SANDBOX_TMPFS
  645.  #fi
  646.  } 2> /dev/null
  647. }
  648.  
  649. # 0.1 must be root
  650. if [ $(id -u) -ne 0 ]; then
  651.  echo "You must be root to use sandbox."
  652.  exit
  653. fi
  654.  
  655. # 0.2 cannot launch sandbox within sandbox
  656. if [ "$AUFS_ROOT_ID" != "" ] ; then
  657.  grep -q $SANDBOX_ROOT /sys/fs/aufs/$AUFS_ROOT_ID/br0 &&
  658.    echo "Cannot launch sandbox within sandbox." && exit
  659. fi
  660.  
  661. # 0.3 help
  662. case "$1" in
  663.  --help|-h)
  664.  echo "Usage: ${0##*/}"
  665.  echo "Starts an in-memory (throwaway) sandbox. Type 'exit' to leave."
  666.  exit
  667. esac
  668.  
  669. # 0.4 if not running from terminal but in Xorg, then launch via terminal
  670. ! [ -t 0 ] && [ -n "$DISPLAY" ] && exec $XTERM -e "$0" "$@"
  671. ! [ -t 0 ] && exit
  672. # 1. get aufs system-id for the root filesystem
  673. if [ -z "$AUFS_ROOT_ID" ] ; then
  674.  AUFS_ROOT_ID=$(
  675.    awk '{ if ($2 == "/" && $3 == "aufs") { match($4,/si=[0-9a-f]*/); print "si_" substr($4,RSTART+3,RLENGTH-3) } }' /proc/mounts
  676.  )
  677. fi
  678.  
  679.  
  680. # 3. Ask user to choose the SFS
  681. echo "items=$items"
  682. cat <<EOF
  683. dialog --separate-output --backtitle "tmpfs sandbox" --title "sandbox config" \
  684.  --checklist "Choose which SFS you want to use" 0 0 0 $items 2> $TMPFILE
  685. EOF
  686.  
  687. log stop
  688. dialog --separate-output --backtitle "tmpfs sandbox" --title "sandbox config" \
  689.  --checklist "Choose which SFS you want to use" 0 0 0 $items 2> $TMPFILE
  690. chosen="$(cat $TMPFILE)"
  691. log start
  692. clear
  693. if [ -z "$chosen" ]; then
  694.  echo "Cancelled or no SFS is chosen - exiting."
  695.  exit 1
  696. fi
  697.  
  698.  
  699. # 4. convert chosen SFS to robranches
  700. robranches=""
  701. for a in $(cat $TMPFILE) ; do
  702.    #a="$(echo "$a" | sed 's/,$//')" # | sed 's/^'//' | sed 's/'$//' )"
  703.     a="$(echo "$a" | sed 's/"//g')" # | sed 's/^'//' | sed 's/'$//' )"
  704.   robranches=$robranches:$a=ro
  705.   sed -i "\#^$a # {s/ off / on /}" /tmp/get_items_out
  706. done
  707. if [ ! -z "$OUTPUT_FILE" ]; then
  708.   cp "/tmp/get_items_out" "$OUTPUT_FILE"
  709.   if [ ! "$NO_EXIT" = true ]; then
  710.     exit 0
  711.   fi
  712. fi
  713. rm $TMPFILE
  714.  
  715. #if [ PUPMODE = 2 ] || PUPMODE = 5 ]; then
  716.   # 0.5 is this the first sandbox? If not, then create another name for mountpoints
  717.   if grep -q $FAKEROOT /proc/mounts && [ -z "$RW_LAYER" ]; then
  718.   FAKEROOT=$(mktemp -d -p $SANDBOX_ROOT ${FAKEROOT##*/}.XXXXXXX)
  719.   SANDBOX_ID=".${FAKEROOT##*.}"
  720.   SANDBOX_TMPFS=$SANDBOX_ROOT/${SANDBOX_TMPFS##*/}${SANDBOX_ID}
  721.   rmdir $FAKEROOT
  722.   fi
  723.   # 5. make the mountpoints if not exist  yet
  724.   [ -z "$RW_LAYER" ] && mkdir -p $FAKEROOT $SANDBOX_TMPFS
  725. #else
  726. #  SANDBOX_TMPFS="$SAVE_MP_FULL_PATH"
  727. #fi
  728.  
  729.  
  730.  
  731. mk_initrd_dir
  732.  
  733.  
  734. # 6. do the magic - mount the tmpfs first, and then the rest with aufs
  735. if mount -t tmpfs none $SANDBOX_TMPFS || [ ! -z "$RW_LAYER" ]; then
  736.   if [ -z "$RW_LAYER" ]; then
  737.     TOP_LAYER="$SANDBOX_TMPFS"
  738.   else
  739.     mkdir -p "$RW_LAYER"
  740.     #TODO maybe check if the RW layer is a file and if so mount it first.
  741.     TOP_LAYER="$RW_LAYER"
  742.   fi
  743.   if mount -t aufs -o "udba=reval,diropq=w,br:$TOP_LAYER=rw$robranches" aufs $FAKEROOT; then
  744.     # 5. record our new aufs-root-id so tools don't hack real filesystem  
  745.     SANDBOX_AUFS_ID=$(grep $FAKEROOT /proc/mounts | sed 's/.*si=/si_/; s/ .*//') #'
  746.     sed -i -e '/AUFS_ROOT_ID/ d' $FAKEROOT/etc/BOOTSTATE 2> /dev/null
  747.     echo AUFS_ROOT_ID=$SANDBOX_AUFS_ID >> $FAKEROOT/etc/BOOTSTATE
  748.    
  749.     # 7. sandbox is ready, now just need to mount other supports - pts, proc, sysfs, usb and tmp
  750.     mkdir -p $FAKEROOT/dev $FAKEROOT/sys $FAKEROOT/proc $FAKEROOT/tmp
  751.     mkdir -p  "$DEV_SAVE/${PSUBDIR}"
  752.     mount -o bind  "PDRV/${PSUBDIR}" "$DEV_SAVE/${PSUBDIR}" #TODO: ONLY do this if we aren't going to mount all of mnt/dev_save
  753.     mount -o bind  "$DEV_SAVE/${PSUBDIR}" "$FAKEROOT/initrd/mnt/dev_save"
  754.     #Maybe optionally do this based on some input paramater:
  755.     #Also pull these layers from an array
  756.     for layer_name in "pup_ro2" "pup_ro3" "pup_ro4" "pup_ro5" "pup_z"; do
  757.         layer="$(eval 'echo $'$layer_name)"
  758.       if [ ! -z "$layer" ] ; then
  759.         mount -o bind  "$layer" "$FAKEROOT/initrd/$layer_name"
  760.       fi
  761.     done
  762.     mount -o rbind /dev $FAKEROOT/dev
  763.     mount -t sysfs none $FAKEROOT/sys
  764.     mount -t proc none $FAKEROOT/proc
  765.     if [ PUPMODE = 2 ]; then #Full Install
  766.       tmp_des=$FAKEROOT/tmp
  767.       tmp_source=/tmp
  768.     else
  769.         mkdir -p $FAKEROOT/initrd/mnt/tmpfs
  770.       tmp_des=$FAKEROOT/initrd/mnt/tmpfs
  771.       tmp_source=/initrd/mnt/tmpfs
  772.       cd $FAKEROOT
  773.       rm tmp
  774.       ln -s initrd/mnt/tmpfs tmp
  775.     fi
  776.     mount -o bind $tmp_source $tmp_des
  777.     mkdir -p $FAKEROOT/$SANDBOX_TMPFS
  778.     mount -o bind $SANDBOX_TMPFS $FAKEROOT/$SANDBOX_TMPFS # so we can access it within sandbox
  779.    
  780.     # 8. optional copy, to enable running sandbox-ed xwin
  781.     cp /usr/share/sandbox/* $FAKEROOT/usr/bin 2> /dev/null
  782.    
  783.     # 9. make sure we identify ourself as in sandbox - and we're good to go!
  784.     echo -e '\nexport PS1="sandbox'${SANDBOX_ID}'# "' >> $FAKEROOT/etc/shinit #fatdog 600
  785.     sed -i -e '/^PS1/ s/^.*$/PS1="sandbox'${SANDBOX_ID}'# "/' $FAKEROOT/etc/profile # earlier fatdog
  786.    
  787.     if [ -d "$FULL_SAVE_PATH" ]; then #TODO verify that this works with a save file
  788.       if [ $PUPMODE -eq 13 ] && [ $PUPMODE -eq 77 ]; then
  789.         #TODO: when PUPMODE=77 (multisession cd) we need to copy folders. See: https://github.com/puppylinux-woof-CE/woof-CE/blob/c483d010a8402c5a1711517c2dce782b3551a0b8/initrd-progs/0initrd/init#L1084
  790.         #and copy_folders()  https://github.com/puppylinux-woof-CE/woof-CE/blob/c483d010a8402c5a1711517c2dce782b3551a0b8/initrd-progs/0initrd/init#L482
  791.           #https://github.com/puppylinux-woof-CE/woof-CE/blob/c483d010a8402c5a1711517c2dce782b3551a0b8/initrd-progs/0initrd/init#L1091
  792.           mount -o remount,prepend:"$FULL_SAVE_PATH"=rw,mod:"$SANDBOX_TMPFS"=ro,del:"$SANDBOX_TMPFS" "$FAKEROOT"
  793.           #mount -o remount,add:1:"$FULL_SAVE_PATH"=ro+wh "$FAKEROOT"
  794.       fi
  795.     fi
  796.     if [ ! -z "$XAUTH" ]; then
  797.       cp "$XAUTH" "$FAKEROOT/$XAUTH"
  798.     fi
  799.     if [ ! -z "$uSocketDir" ]; then
  800.       mkdir -p "$FAKEROOT$uSocketDir"
  801.       mount --bind "$uSocketDir" "$FAKEROOT$uSocketDir"    
  802.     fi  
  803.     if [ ! -z "$RESOLV_CONF_PATH" ]; then
  804.       cp "$RESOLV_CONF_PATH" "$FAKEROOT/etc/resolv.conf"
  805.     fi  
  806.     for i in "${!bind_sources[@]}"; do
  807.       b_source="${bind_sources[$i]}"
  808. #      chroot "$FAKEROOT" busybox ash <<EOF
  809. #         cd "$FAKEROOT"
  810. #         if [ ! -z "\`which realpath\`" ]; then
  811. #           target=\$(realpath "${bind_targets[$i]}"
  812. #           mkdir -p $target
  813. #         else
  814. #           target=${bind_targets[$i]}
  815. #           mkdir -p $target
  816. #         fi
  817. #        
  818. #EOF
  819.       b_target=$(realpath -m "$FAKEROOT/${bind_targets[$i]}")
  820.       mkdir -p "$b_target"
  821.       mkdir -p "$b_source"
  822.       log stop
  823.       read -p "Press enter to continue"
  824.       log start
  825.       mount --bind "$b_source" "$b_target"
  826.     done
  827.     for i in "${!rev_bind_sources[@]}"; do
  828.       rev_b_source="$rev_bind_sources[$i]"
  829.       rev_b_source="${rev_b_source#/}"
  830.       rev_b_source="${rev_$FAKEROOT/bind_sources[$i]}"
  831.       rev_b_target="${bind_targets[$i]}"
  832.       rev_b_target=$(eval "echo \"$rev_b_target\"")
  833.       rev_b_target=$(realpath -m "$rev_b_target")
  834.       mkdir -p "$rev_b_target"
  835.       mkdir -p "$rev_b_source"
  836.       log stop
  837.       read -p "Press enter to continue"
  838.       log start
  839.       mount --bind "$b_source" "$b_target"
  840.     done    
  841.     echo "Starting sandbox now."
  842.     echo "USE_NS=$USE_NS"
  843.     $BEFORE_CHROOT_CMD
  844.     log stop    
  845.     if [ $USE_NS ]; then
  846.        read -p "Press enter to continue"
  847.       unshare -f -p --mount-proc=$FAKEROOT/proc chroot $FAKEROOT
  848.     else
  849.       read -p "Press enter to continue"
  850.  
  851.       chroot $FAKEROOT
  852.     fi
  853. log start
  854.     # 10. done - clean up everything
  855.     umountall
  856.     echo "Leaving sandbox."
  857.   else
  858.     echo "Unable to mount aufs br:$SANDBOX_TMPFS=rw$robranches"
  859.     umount -l $SANDBOX_TMPFS    
  860.   fi
  861. else
  862.   echo "unable to mount tmpfs."
  863. fi
  864.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement