#!/bin/ash

export PATH=.:/:/usr/sbin:/usr/bin:/sbin:/bin
. liblinuxlive

header "starting Linux Live scripts <http://www.linux-live.org/>"

echolog "mounting /proc and /sys filesystems"
mount -t proc proc /proc
mount -t sysfs sysfs /sys
ln -sf /proc/mounts /etc/mtab # this allows us to use umount -a

# setup DEBUGCMD variable. If debug boot option is present, call debug()
# function several times during script's execution
if [ "`cmdline_parameter debug`" ]; then DEBUGCMD="debug"; else DEBUGCMD=""; fi

$DEBUGCMD

# we have to set these variables very carefully
UNION=/union
MEMORY=/memory
MOUNTDIR=mnt
CHANGES=$MEMORY/changes
COPY2RAM=$MEMORY/copy2ram
IMAGES=$MEMORY/images
INITRAMDISK=$MOUNTDIR/live
ISOMOUNT=/$MOUNTDIR/iso
LIVECDSGN=livecd.sgn

# amount of RAM to store changes
RAMSIZE="`cmdline_value ramsize`"
if [ "$RAMSIZE" = "" ]; then RAMSIZE="60%"; fi

# cdrom support, isofs support, unionfs support, etc
modprobe_essential_modules
setup_dma
echo -e "ext3\next2\nvfat\n*" >/etc/filesystems

# in some cases, we need USB modules soon
if [ "`cmdline_parameter probeusb`" != "" ]; then
   modprobe_usb_modules
fi

mkdir -p $UNION
mkdir -p $MEMORY

$DEBUGCMD

echolog -n "setup directory for changes "
CHANGESPATH="`cmdline_value changes`"
CHANGESPATH="`find_file $MOUNTDIR $CHANGESPATH`"
echo $CHANGESPATH
mount_device $CHANGESPATH $MEMORY # silently ignored if changespath is empty

# mount tmpfs only in the case when changes= boot parameter was empty
# or we were not able to mount the storage device
if [ $? -ne 0 ]; then mount -t tmpfs -o "size=$RAMSIZE" tmpfs $MEMORY; fi

# $UNION will be used as a root directory, livecd modules will be added soon
echolog "setup union on $UNION"

mkdir -p $CHANGES
if [ 0$? -ne 0 ]; then
   fatal "it seems you're using a Read-Only filesystem"
fi

mkdir -p $IMAGES
mount -t unionfs -o dirs=$CHANGES=rw unionfs $UNION
if [ $? -ne 0 ]; then fatal "can't setup union in /union directory"; fi

$DEBUGCMD

# try to find livecd data directory. If not found, try modprobing
# USB kernel modules and repeat the find procedure again
echolog "looking for data modules"

FROMISO="`cmdline_value fromiso`"
FROMISO="`find_file $MOUNTDIR $FROMISO`"

# when fromiso is used, search for livecd.sgn
if [ "$FROMISO" ]; then
   mount_device $FROMISO $ISOMOUNT
   if [ 0$? -eq 0 -a -e "$ISOMOUNT/$LIVECDSGN" ]; then
      echolog "found in $FROMISO"
      DATA=$ISOMOUNT
   fi
fi

if [ "$DATA" = "" ]; then
   # fromiso is not used or it didn't contain livecd.sgn
   DATA="`find_file $MOUNTDIR $LIVECDSGN`"
   DATA="`dirname \"$DATA\"`"
fi

if [ "$DATA" = "" ]; then
   # data still not found, probe for USB devices and wait
   modprobe_usb_modules;
   echolog -n "waiting for usb devices .."
   for i in 1 2 3 4 5 6 7 8; do # max 36 seconds, prolong the delay each time
      echo -n "."
      create_block_devices >/dev/null
      DATA="`find_file $MOUNTDIR $LIVECDSGN`";
      if [ "$DATA" != "" ]; then break; fi
      sleep $i;
   done
fi

$DEBUGCMD

if [ "$DATA" = "" ]; then fatal "
LiveData not found. Searching for $LIVECDSGN file,but file not found.
You are maybe using an unsupported boot device (eg. SCSI or PCMCIA CD-ROM)
Try to copy all data from CD/USB to your IDE harddisk, for example
to /mnt/sda1/alldata/ in Linux or C:\\alldata\\ in Windos. Then boot again."
fi

echolog "LiveData mounted to $DATA"

$DEBUGCMD

# If toram or copy2ram boot parameter is present, copy all .mo modules to RAM.
# (skip modules from /optional/ which are not listed in load= boot option)
# Finaly modify DATA variable so it will point to correct directory
if [ "`cmdline_parameter toram`" != "" -o "`cmdline_parameter copy2ram`" != "" ]; then
   echolog "copying data to RAM, this may take some time..."
   mkdir -p $COPY2RAM

   # make sure it's in RAM even with changes= parameter
   if [ "$CHANGESPATH" ]; then mount -t tmpfs -o "size=$RAMSIZE" tmpfs $COPY2RAM; fi
   copy_to_ram $DATA $COPY2RAM

   cd_autoeject 1
   umount $DATA 2>/dev/null
   umount $MOUNTDIR/* 2>/dev/null
   rmdir $MOUNTDIR/* 2>/dev/null # mounted device names are empty, remove them
   DATA=$COPY2RAM
   cd_autoeject 0
fi

mkdir -p $UNION/boot
mount -o bind $DATA $UNION/boot

$DEBUGCMD

# DATA contains path to the base directory of all .mo images which need
# to be mounted and inserted into live filesystem. Do it now.
echolog "inserting all modules and creating live filesystem"
union_insert_modules $UNION $DATA $IMAGES

# the $MEMORY directory can contain $MEMORY/modules too
# in the case where changes= boot argument is used. If not, it doesn't hurt
union_insert_modules $UNION $MEMORY $IMAGES

$DEBUGCMD

echolog "copying rootchanges"
cp -a $DATA/rootcopy/* $UNION 2>/dev/null # may be empty

$DEBUGCMD

echolog "creating /etc/fstab"
fstab_update $UNION

# More likely these directories aren't there.
# Even if they are, this won't hurt.
mkdir -p $UNION/proc
mkdir -p $UNION/sys
mkdir -p $UNION/dev
mkdir -p $UNION/tmp
chmod 0777 $UNION/tmp

$DEBUGCMD

# Union contains all the files and directories unioned from all modules.
# Change root directory to it, and move initrd's root to /mnt/live/initramdisk
# Finaly execute /sbin/init to start the distribution.
echolog "changing root directory..."
cd $UNION
mkdir -p $INITRAMDISK

umount /sys # we won't need it anymore
if [ ! -e $UNION/dev/console ]; then mknod $UNION/dev/console c 5 1; fi

if [ -x $UNION/usr/sbin/chroot ];
  then CHROOT=/usr/sbin/chroot
  else CHROOT=/usr/bin/chroot
fi

header "linux live end"
pivot_root . $INITRAMDISK
exec $CHROOT . sbin/init <dev/console >dev/console 2>&1

header "ERROR!"
echolog "You are not supposed to be here, something went wrong!"
echolog "Even Ctrl+Alt+Del won't help you in kernel panic."

