#!/bin/bash
#
# License: GPL 
# Original author: Blake, Kuo-Lien Huang
# Description:
#  2003/04/11 the first version, only work on /dev/hda1 & PXE
#  2003/06/01 disk to disk mode & etherboot support 
#             (the etherboot lzdsk images are located in
#              /tftpboot/etherboot-5.0.7 after DRBLCD installed)
#  2003/07/18 `checkInodeForDevice`
#
# Author: Steven Shiau <steven _at_ nchc org tw>
# 2003/07/21 the first version for Redhat, modified from Blake's version,
# only work on /dev/hda1 & PXE
# 2004/02/04 add the multicast function
# 2005/01/21 add code to save/restore some partitions (not entire disk).
# 2005/11/06 Many thanks to Christian Treczoks for providing "dd skip=1" method
# 2006/05/06 Remove save & restore hda1, since we can use save & restore partitions.
# 2006/12/07 Rewrite drbl-ocs to drbl-ocs + ocs-sr + ocs-functions.

# input parameters:
# save/savedisk/saveparts/restore/restoredisk/restoreparts/multicast_restore/multicast_restoredisk IMAGE-NAME DEVICES

# Notes:
# task_restorexxx/savexxx function will always use $ocsroot (/home/partimag) as mount point to do the save/restore, so it might overwrite the /home/partimag by mounting $ocsroot from server:/home2 (for example).
# The mount action is done in function task_preprocessing

ocs_file="$0"
ocs=`basename $ocs_file`
ocs_myself_id="$$"
# we need ocs_ppid for ocs-functions
ocs_ppid="$PPID"
# log file for sfdisk when restoring
# RESTORE_SFDISK_LOG is loaded from drbl.conf

# Some initial setting
confirm_before_clone="no"
ocs_sr_mode=""

# Load DRBL setting and functions
if [ ! -f "/opt/drbl/sbin/drbl-conf-functions" ]; then
  echo "Unable to find /opt/drbl/sbin/drbl-conf-functions! Program terminated!" 
  exit 1
fi
. /opt/drbl/sbin/drbl-conf-functions

# Load some necessary setting from drbl-ocs.conf
. /opt/drbl/conf/drbl-ocs.conf

# Load basic functions of ocs
. /opt/drbl/sbin/ocs-functions

# Load the config in ocs-live.conf. This is specially for Clonezilla live. It will overwrite some settings of /opt/drbl/conf/drbl-ocs.conf, such as $DIA...
[ -e "/etc/ocs/ocs-live.conf" ] && . /etc/ocs/ocs-live.conf

# Fedora Core 1 seems to use dumb for rc1, we have to force it use linux.
# otherwise setterm will complain.
[ -z "$TERM" -o "$TERM" = "dumb" ] && TERM="linux"
echo "Setting the TERM as $TERM"
export TERM="$TERM"

#
check_if_root

#
USAGE() {
    echo "Usage:"
    echo "To save or restore image"
    echo "$ocs [OPTION] {savedisk|saveparts|restoredisk|restoreparts} IMAGE_NAME DEVICE"
    echo 
    echo " Options for restoring:"
    USAGE_common_restore
    echo " --mcast-port   NO     Assign the udp port number for multicast restore. This is used by clonezilla server. Normally it's not necessary to manually assign this option."
    echo
    echo " Options for saving:"
    USAGE_common_save
    echo " -i, --image-size SIZE    Set the split image file volume size SIZE (MB). When $ocs is run with -x, the default SIZE is set as $VOL_LIMIT_IN_INTERACTIVE, if without -x, we will not split it"
    echo
    echo " General options:"
    USAGE_common_general
    dialog_like_prog_help_prompt
    echo " -x, --interactive     Interactive mode to save or restore."
    echo
    echo "Example:"
    echo "   To save or restore image in client (Only that DRBL client will join, and its local partitions is NOT mounted). NOTE!!! You should run the command in DRBL client or you have to make sure the target device is NOT busy!."
    echo "   To save all the data in local first IDE harddrive 'hda' as image 'IMAGE1', use ntfsclone instead of partimage, and lzop compression (NOTE!!! You should run the command in DRBL client or make sure hda is NOT busy/mounted!):"
    echo "   $ocs --use-ntfsclone -z3 savedisk IMAGE1 hda"
    echo
    echo "   To save the data in first and second partitions in local first IDE harddrive 'hda' as image 'IMAGE2', use ntfsclone instead of partimage, and lzop compression (NOTE!!! You should run the command in DRBL client, or make sure hda is NOT busy/mounted!):"
    echo "   $ocs" '--use-ntfsclone -z3 saveparts IMAGE2 "hda1 hda2"'
    echo
    echo "   To restore image "IMAGE1" to local hda. grub-install will be run after cloning (image IMAGE1 is already in DRBL server. NOTE!!!  You should run the command in DRBL client or make sure hda is NOT busy/mounted!):"
    echo "   $ocs -g auto restoredisk IMAGE1 hda"
    echo
    echo "   To restore image first and second partitions from "IMAGE2" to local hda1 and hda2. grub-install will be run after cloning (image IMAGE2 is already in DRBL server. NOTE!!!  You should run the command in DRBL client or make sure hda is NOT busy/mounted!):"
    echo "   $ocs" '-g auto restoreparts IMAGE2 "hda1 hda2"'
    echo
    echo "   To save disk(s)/partitition(s) as an image or restore an image to disk(s)/partitition(s) interactively, use:"
    echo "   $ocs -x"
}
#
parse_ocs_sr_cmd_options_with_dash() {
 # Parse command-line options
 # It's UGLY to use "shift; n_shift=$((n_shift+1))"
 # However, we want to reuse the parse_ocs_sr_cmd_options_with_dash, 
 # a problem here:
 # The parameters (-b -g auto --nogui --max-time-to-wait 300 --language 0 multicast_restoreparts sarge-base "hda1 hda3" 2232), when put it as $*, it will
 # become (-b -g auto --nogui --max-time-to-wait 300 --language 0 multicast_restoreparts sarge-base hda1 hda3 2232), you see, "hda1 hda3" -> hda1 hda3
 # Then everyting is in a mess... so now the best solution I can find is to
 # calculate the n_shift, then parse it to original shell, not in the function.

 n_shift=0
 while [ $# -gt 0 ]; do
  case "$1" in
    -l|--language)
            shift; n_shift=$((n_shift+1))
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
	      specified_lang="$1"
              shift; n_shift=$((n_shift+1))
            fi
            [ -z "$specified_lang" ] && USAGE && exit 1
	    ;;
    -g|--grub-install)  
            install_grub="on"
            shift; n_shift=$((n_shift+1))
            # skip the -xx option, in case 
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              grub_partition=$1
              shift; n_shift=$((n_shift+1))
            fi
            [ -z "$grub_partition" ] && USAGE && exit 1
            ;;
    -a|--no-force-dma-on)  
	    force_dma_on="no"
            shift; n_shift=$((n_shift+1));;
    -k|--no-fdisk|--no-create-partition)  
	    create_part="no"
            shift; n_shift=$((n_shift+1));;
    -t|--no-restore-mbr)  
	    restore_mbr="no"
            shift; n_shift=$((n_shift+1));;
    -u|--select-img-in-client)
	    select_img_in_client="yes"
            shift; n_shift=$((n_shift+1));;
    -e|--load-geometry)
	    load_HD_CHS="yes"
            shift; n_shift=$((n_shift+1));;
    -y|-y0|--always-restore|--always-restore-default-local)
	    always_restore="yes"
            pxe_menu_default_mode="local"
            shift; n_shift=$((n_shift+1));;
    -y1|--always-restore-default-clone)
	    always_restore="yes"
            pxe_menu_default_mode="clone"
            shift; n_shift=$((n_shift+1));;
    -y2|--always-restore-default-drbl)
	    always_restore="yes"
            pxe_menu_default_mode="drbl"
            shift; n_shift=$((n_shift+1));;
    -c|--confirm)
            confirm_before_clone="yes"
	    shift; n_shift=$((n_shift+1));;
    -w|--wait-time)
            shift; n_shift=$((n_shift+1))
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
	      TIME_to_wait="$1"
              shift; n_shift=$((n_shift+1))
            fi
	    ;;
    --debug=?*)
            debug_level=${1#--debug=}
	    shift; n_shift=$((n_shift+1));;
    -b|--batch)
            batch_mode="on"
	    shift; n_shift=$((n_shift+1));;
    -d|--debug-mode)
            debug_mode="on"
	    shift; n_shift=$((n_shift+1));;
    -d0|--dialog)  
	    DIA="dialog" 
	    shift;;
    -d1|--Xdialog)  
	    DIA="Xdialog" 
	    shift;;
    -d2|--whiptail)  
	    DIA="whiptail" 
	    shift;;
    -d3|--gdialog)  
	    DIA="gdialog" 
	    shift;;
    -d4|--kdialog)  
	    DIA="kdialog" 
	    shift;;
    -m|--module)
            shift; n_shift=$((n_shift+1))
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
              module_to_load=$1
              shift; n_shift=$((n_shift+1))
            fi
            [ -z "$module_to_load" ] && USAGE && exit 1
            ;;
    -r|--resize-partition)
            resize_partition="on"
	    shift; n_shift=$((n_shift+1));;
    -v|--verbose)
	    verbose="on"
	    shift; n_shift=$((n_shift+1));;
    -z0|--no-compress)
            IMG_CLONE_CMP="cat"
	    shift; n_shift=$((n_shift+1));;
    -z1|--gzip-compress)
            IMG_CLONE_CMP="gzip -c"
	    shift; n_shift=$((n_shift+1));;
    -z2|--bz2-compress)
            IMG_CLONE_CMP="bzip2 -c"
	    shift; n_shift=$((n_shift+1));;
    -z3|--lzo-compress)
            # Now only for ntfsclone, partimage not yet.
            IMG_CLONE_CMP="lzop -c"
	    shift; n_shift=$((n_shift+1));;
    -nogui|--nogui)
            # -nogui is for backward compatable, better to use --nogui
            nogui="on"
	    shift; n_shift=$((n_shift+1));;
    -ntfs-ok|--ntfs-ok)
            # if ntfs integrity is assumed OK, do not check
            ntfs_integrity_check="no"
	    shift; n_shift=$((n_shift+1));;
    -mp|--mount-point)
            shift; n_shift=$((n_shift+1)); 
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
              mount_point=$1
	      shift; n_shift=$((n_shift+1))
            fi
            [ -z "$mount_point" ] && USAGE && exit 1
	    ;;
    -or|--ocsroot)
            # overwrite the ocsroot in drbl.conf
            shift; n_shift=$((n_shift+1)); 
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
              ocsroot="$1"
	      shift; n_shift=$((n_shift+1))
            fi
            [ -z "$ocsroot" ] && USAGE && exit 1
	    ;;
    -i|--image-size)
	    shift; n_shift=$((n_shift+1))
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
              VOL_LIMIT=$1
	      shift; n_shift=$((n_shift+1))
            fi
            [ -z "$VOL_LIMIT" ] && USAGE && exit 1
	    ;;
    --max-time-to-wait)
	    # ocs-sr need to know the --max-time-to-wait so that when sleeping
	    # between partitions restoring clone won't timeout.
	    shift; n_shift=$((n_shift+1))
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
	      mcast_max_wait_time="$1"
	      shift; n_shift=$((n_shift+1))
            fi
            [ -z "$mcast_max_wait_time" ] && USAGE && exit 1
	    ;;
    -q|--use-ntfsclone)
            USE_NTFSCLONE="yes"
	    shift; n_shift=$((n_shift+1));;
    -j|--create-part-by-sfdisk)
            # We leave this option for backward compatability.
            create_part_by_sfdisk="yes"
	    shift; n_shift=$((n_shift+1));;
    -j0|--create-part-by-dd)
            create_part_by_sfdisk="no"
	    shift; n_shift=$((n_shift+1));;
    -hn0)
	    shift; n_shift=$((n_shift+1))
            change_win_hostname="By_IP"
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
	      win_hostname_prefix="$1"
	      shift; n_shift=$((n_shift+1))
            fi
            [ -z "$win_hostname_prefix" ] && USAGE && exit 1
	    ;;
    -hn1)
	    shift; n_shift=$((n_shift+1))
            change_win_hostname="By_MAC"
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
	      win_hostname_prefix="$1"
	      shift; n_shift=$((n_shift+1))
            fi
            [ -z "$win_hostname_prefix" ] && USAGE && exit 1
	    ;;
    -o|-o1|--run-postrun-dir) 
            # -o is for backward compatability
	    run_postrun_dir="yes"
	    shift; n_shift=$((n_shift+1));;
    -o0|--run-prerun-dir) 
	    run_prerun_dir="yes"
	    shift; n_shift=$((n_shift+1));;
    -ns|--ntfs-progress-in-image-dir)
	    ntfsclone_progress="image_dir"
	    shift; n_shift=$((n_shift+1));;
    -x|--interactive) 
	    ocs_sr_mode="interactive"
	    shift; n_shift=$((n_shift+1));;
    --mcast-port)
            shift; n_shift=$((n_shift+1)); 
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
              ocs_sr_mcast_port="$1"
	      shift; n_shift=$((n_shift+1))
            fi
            [ -z "$ocs_sr_mcast_port" ] && USAGE && exit 1
	    ;;
    -p|--postaction)  
            shift; n_shift=$((n_shift+1)); 
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
	      postrun="$1"
	      shift; n_shift=$((n_shift+1))
            fi
            [ -z "$postrun" ] && USAGE && exit 1
            ;;
    --restore-only)
	    ocs_x_mode="restore_only"
	    shift; n_shift=$((n_shift+1));;
    --save-only)
	    ocs_x_mode="save_only"
	    shift; n_shift=$((n_shift+1));;
    -*)     echo "${0}: ${1}: invalid option" >&2
            USAGE >& 2
            exit 2 ;;
    *)      break ;;
  esac
 done
} # end of parse_ocs_sr_cmd_options_with_dash
#
save_only_dia_des() {
  savedisk_msg_1="savedisk"
  savedisk_msg_2="$msg_clonezilla_save_disk"
  savedisk_msg_3="off"
  saveparts_msg_1="saveparts"
  saveparts_msg_2="$msg_clonezilla_save_parts"
  saveparts_msg_3="off"
}
#
restore_only_dia_des() {
  restoredisk_msg_1="restoredisk"
  restoredisk_msg_2="$msg_clonezilla_restore_disk"
  restoredisk_msg_3="off"
  restoreparts_msg_1="restoreparts"
  restoreparts_msg_2="$msg_clonezilla_restore_parts"
  restoreparts_msg_3="off"
}
# functions to process options.
wrap_up_opt() {
[ -z "$VOL_LIMIT" ] && VOL_LIMIT=$VOL_LIMIT_DEFAULT

# put default postrun if empty
[ -z "$postrun" ] && postrun="$POSTRUN_DEF"

# change to other mount point for extra harddisk
# Note: functions get_existing_disk_image, get_existing_parts_image and get_existing_partitions_from_img will use $imagedir 
if [ -n "$mount_point" ]; then
   echo "Using the image root directory $mount_point instead of $ocsroot."
   imagedir="$mount_point" 
else
   imagedir="$ocsroot"
fi

check_ocs_input_params

#
PARTIMAGE_SAVE_OPT="$PARTIMAGE_SAVE_OPT --debug=$debug_level"
PARTIMAGE_RESTORE_OPT="$PARTIMAGE_RESTORE_OPT --debug=$debug_level"
if [ "$nogui" = "on" ]; then
  PARTIMAGE_SAVE_OPT="$PARTIMAGE_SAVE_OPT -B gui=no"
  PARTIMAGE_RESTORE_OPT="$PARTIMAGE_RESTORE_OPT -B gui=no"
fi

# ocs root
[ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
echo "clonezilla image dir: $ocsroot"
[ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
[ ! -d "$ocsroot" ] && mkdir -p $ocsroot

echo $msg_delimiter_star_line
[ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
[ "$create_part" = "no" ] && echo "$msg_do_not_create_part"
[ "$restore_mbr" = "no" ] && echo "$msg_do_not_restore_mbr"
[ "$select_img_in_client" = "yes" ] && echo "$msg_you_have_to_input_image_names_in_client"
[ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
echo $msg_delimiter_star_line

if [ "$verbose" = "on" ]; then
  echo "OCS_OPT: $OCS_OPT"
  echo "PARTIMAGE_RESTORE_OPT: $PARTIMAGE_RESTORE_OPT"
  echo "PARTIMAGE_SAVE_OPT: $PARTIMAGE_SAVE_OPT"
  # The default output for udpcast stderr is surpressed, now turn it on
  udpcast_stderr="/dev/stderr"
fi
} # end of wrap_up_opt


# OCS_OPT is for drbl-ocs using, will not put into the partimage command options
# PARTIMAGE_RESTORE_OPT & PARTIMAGE_SAVE_OPT will put into partimage command options
PARTIMAGE_RESTORE_OPT=
PARTIMAGE_SAVE_OPT=
OCS_OPT=
report_msg=
# Set some default values, 
nfs_restart="no"
always_restore="no"
pxe_menu_default_mode=""
mcast_loop="1"
udp_sender_extra_opt=""
USE_NTFSCLONE="no"
force_dma_on="yes"
create_part="yes"
restore_mbr="yes"
select_img_in_client="no"
# If create_part_by_sfdisk=no, then we will use "dd if=$tgt_dir/mbr of=$sfdisk_target_hd skip=446 seek=446 bs=1 count=66" to dump the partition table.
create_part_by_sfdisk="yes"
# we want to make sfdisk --force if sfdisk is used.
sfdisk_opt="--force"
# default output for udpcast stderr is surpressed.
# NOTE! Do not redirect it to standard output (stdin), otherwise partimage/ntfsclone pipe will get wrong image!
udpcast_stderr="/dev/null"
# default not to run those scripts in $OCS_PRERUN_DIR $OCS_POSTRUN_DIR
run_prerun_dir="no"
run_postrun_dir="no"
# default to put the ntfsclone progress in local /tmp/ (tmpfs)
ntfsclone_progress="local_tmp"

# The parameters, example: 
# (-b -g auto --nogui --max-time-to-wait 300 --language 0 multicast_restoreparts sarge-base "hda1 hda3" 2232) ->
# (multicast_restoreparts sarge-base "hda1 hda3" 2232)
parse_ocs_sr_cmd_options_with_dash $*
shift ${n_shift}
ocs_sr_type_assign="$1"
ocs_sr_img_name="$2"
shift 2
ocs_sr_dev="$*"
# If the inputted dev is: "hda hdb", convert it to hda hdb (so it won't be ""hda hdb"")
ocs_sr_dev="$(echo $ocs_sr_dev | tr -d \")"

#
ask_and_load_lang_set $specified_lang

# check DIA
check_DIA_set_ESC $DIA

##############
#### main ####
##############

# ocs root
if [ ! -d "$ocsroot" ]; then
  echo "Please make sure your $ocsroot is a directory!!!"
  # The common error is user try to create a ocsroot as /home/partimage, the default is /home/partimag (without e)
  if [ "$ocsroot" = "/home/partimag" -a -d "/home/partimage" ]; then
    [ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
    echo "$msg_home_partimag_not_home_partimage" 
    [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
  fi
  echo "We can NOT go on! Press \"c\" to enter command prompt or any other key to quit the program..." 
  read fail_answer
  case "$fail_answer" in
    [cC]) sulogin ;;
       *) exit 1 ;;
  esac
fi

#
if [ "$ocs_sr_type_assign" = "ask_user" -o \
     "$ocs_sr_mode" = "interactive" ]; then
  ASK_OCS_SR_TYPE=1
  TMP=$(mktemp /tmp/menu.XXXXXX)
  trap "[ -f "$TMP" ] && rm -f $TMP" HUP INT QUIT TERM EXIT
  case "$ocs_x_mode" in
    "save_only")
      save_only_dia_des
      ;;
    "restore_only")
      restore_only_dia_des
      ;;
    *) # both
      save_only_dia_des
      restore_only_dia_des
      ;;
  esac
  echo "Choose the mode for ocs-sr"
  while [ "$ASK_OCS_SR_TYPE" -ne 0 ]; do
    $DIA --backtitle "$msg_nchc_free_software_labs" --title  \
    "Clonezilla: $msg_choose_mode" --menu "$msg_clonezilla_is_free_and_no_warranty\n$msg_choose_mode:" \
    0 0 0 \
    $savedisk_msg_1 $savedisk_msg_2 \
    $restoredisk_msg_1 $restoredisk_msg_2 \
    $saveparts_msg_1 $saveparts_msg_2 \
    $restoreparts_msg_1 $restoreparts_msg_2 \
    "exit"           "$msg_exit. $msg_enter_cml" \
    2> $TMP
    ocs_sr_type="$(cat $TMP)"
    if [ -z "$ocs_sr_type" ]; then
      ASK_OCS_SR_TYPE=1
    else
      ASK_OCS_SR_TYPE=0
    fi
  done
  [ -f "$TMP" ] && rm -f $TMP
  [ -z "$ocs_sr_type" ] && echo "You must specify the action! Program terminated!!!" && exit 1
  # If ocs_sr_type from ask_user, then we should let ocs_sr_img_name & ocs_sr_dev as ask_user, too
  ocs_sr_img_name="ask_user"
  ocs_sr_dev="ask_user"
  # Do not default to reboot, otherwise if it's save mode, user does not have
  # any chance to umount device after save is done. If postrun is assigned, honor that.
  [ -z "$postrun" ] && postrun="choose"
  # Overwrite the default HALT_REBOOT_OPT (-f -n) so that if user choose to halt/reboot, it will use normal halt/reboot sequence, then mounted device will be unmounted.
  HALT_REBOOT_OPT=""
  VOL_LIMIT="$VOL_LIMIT_IN_INTERACTIVE"
else
  ocs_sr_type="$ocs_sr_type_assign"
fi

#
if [ "$ocs_sr_type_assign" = "ask_user" -o \
     "$ocs_sr_mode" = "interactive" ]; then
 # since this ocs-sr asks for ocs_sr type, this means the option maybe not parsed.
 case "$ocs_sr_type" in
  save*)
   # Turn off swap and LVM2, unlock the busy partitions.
   turn_off_swap_and_LVM2
   # ask if want to set ocs extra param
   OCS_PARAM_TMP=`mktemp /tmp/ocs_sr_param_tmp.XXXXXX`
   trap "[ -f "$OCS_PARAM_TMP" ] && rm -f $OCS_PARAM_TMP" HUP INT QUIT TERM EXIT
   set_ocs_sr_extra_param save $OCS_PARAM_TMP
   OCS_OPTS="$(cat $OCS_PARAM_TMP)"
   [ -f "$OCS_PARAM_TMP" ] && rm -f $OCS_PARAM_TMP
   parse_ocs_sr_cmd_options_with_dash $OCS_OPTS
   ;;
  restore*)
   # Skip the multicast_restore*, since it's spawned by drbl-ocs, not from ocs-sr
   # ask if want to set ocs extra param
   OCS_PARAM_TMP=`mktemp /tmp/ocs_sr_param_tmp.XXXXXX`
   trap "[ -f "$OCS_PARAM_TMP" ] && rm -f $OCS_PARAM_TMP" HUP INT QUIT TERM EXIT
   set_ocs_sr_extra_param restore $OCS_PARAM_TMP
   OCS_OPTS="$(cat $OCS_PARAM_TMP)"
   [ -f "$OCS_PARAM_TMP" ] && rm -f $OCS_PARAM_TMP
   parse_ocs_sr_cmd_options_with_dash $OCS_OPTS
   ;;
  exit)
   echo "To use it again, run \"$ocs -x\"."
   exit 2
   ;;
 esac
fi

# process options.
wrap_up_opt

#
case "$ocs_sr_type" in
  "savedisk")
    task_preprocessing "$ocs_sr_type"
    task_savedisk "$ocs_sr_img_name" "$ocs_sr_dev"
    task_postprocessing
    ;;
  "restoredisk")
    task_preprocessing "$ocs_sr_type"
    task_restoredisk "$ocs_sr_img_name" "$ocs_sr_dev"
    task_postprocessing
    ;;
  "saveparts")
    task_preprocessing "$ocs_sr_type"
    task_saveparts "$ocs_sr_img_name" "$ocs_sr_dev"
    task_postprocessing
    ;;
  "restoreparts")
    task_preprocessing "$ocs_sr_type"
    task_restoreparts "$ocs_sr_img_name" "$ocs_sr_dev"
    task_postprocessing
    ;;
  "multicast_restoredisk")
    task_preprocessing "$ocs_sr_type"
    task_multicast_restoredisk "$ocs_sr_img_name" "$ocs_sr_dev" "$ocs_sr_mcast_port"
    task_postprocessing
    ;;
  "multicast_restoreparts")
    task_preprocessing "$ocs_sr_type"
    task_multicast_restoreparts "$ocs_sr_img_name" "$ocs_sr_dev" "$ocs_sr_mcast_port"
    task_postprocessing
    ;;
  *)
    USAGE
    exit 2
    ;;
esac

exit 0
