#!/bin/bash
# License: GPL 
# Author: Steven Shiau <steven _at_ clonezilla org>
# Description: Program to prepare Clonezilla live image home dir via URI (Uniform Resource Identifier)
# //NOTE// This program uses some of the common variables and function with prep-ocsroot. If
# it's modified, remember to check prep-ocsroot, too.

# https://en.wikipedia.org/wiki/Uniform_Resource_Identifier
# scheme:[//[user:password@]host[:port]][/]path[?query][#fragment]
# General URI in Clonezilla:
# [dev|smb|ssh|nfs|nfs4|http|https]:[//[user:password@]host[:port]][/]path
# local_dev:     dev:///dev/partition
# nfs_server:    nfs|nfs4://host/path
# samba_server:  smb://[domain;user:password@]host/path
# ssh_server:    ssh://[user@]host[:port]/path  (No password can be assigned in URI)
# webdav_server: http|https://host[:port]/path  (No username and password can be assigned in URI)
# E.g.
# ocs_repository="dev:///dev/sdf1"
# ocs_repository="nfs://192.168.100.254/home/partimag/"
# ocs_repository="nfs4://192.168.100.254/partimag/"
# ocs_repository="smb://administrator:mypasswd@192.168.100.175/images/"
# ocs_repository="smb://my_domain;jack:mypasswd@192.168.1.1:445/images/"
# ocs_repository="ssh://jack@192.168.100.211/home/partimag/"
# ocs_repository="http://192.168.100.180/share"

DRBL_SCRIPT_PATH="${DRBL_SCRIPT_PATH:-/usr/share/drbl}"
. $DRBL_SCRIPT_PATH/sbin/drbl-conf-functions
. /etc/drbl/drbl-ocs.conf
. $DRBL_SCRIPT_PATH/sbin/ocs-functions

# Settings
cmdl_file_def="/proc/cmdline"
chk_ocsroot_mountpont="yes"
# Since this command is usually run for unattended mode, make it in batch mode
ocs_batch_mode="on"

#
get_ocsroot_src_from_ocs_repository_if_assigned() {
  parse_cmdline_option -c $cmdl_file "ocs_repository"
  case "$ocs_repository" in
    dev://*)             ocsroot_src="local_dev" ;;
    smb://*)             ocsroot_src="samba_server" ;; 
    ssh://*)             ocsroot_src="ssh_server" ;; 
    nfs://*)             ocsroot_src="nfs_server" ;;
    nfs4://*)            ocsroot_src="nfs4_server" ;;
    http://*|https://*)  ocsroot_src="webdav_server" ;;
    "")                  ocsroot_src="none";;
     *)                  ocsroot_src="unknown";;
  esac
}
#
do_uri_mount_local_dev() {
  target_part="$(drbl-uriparse "$ocs_repository" path)"
  # Strip the leading "/dev/"
  target_part="$(strip_heading_dev $target_part)"
  # Browse?
  prepare_mnt_point_ocsroot
  LC_ALL=C mount -t auto -o $ocsroot_def_mnt_opt,nodiratime /dev/$target_part $ocsroot
  [ "$chk_ocsroot_mountpont" = "yes" ] && check_if_ocsroot_a_mountpoint
} # end of do_uri_mount_local_dev
#
do_uri_mount_samba_server(){
  # The URI for samba:
  # smb://[[domain;]username[:password]@]server[/share[/path]]
  # TODO: Security mode option (smb_sec_opt)? e.g. sec=ntlm, sec=ntlmv2 or auto
  smb_srv="$(drbl-uriparse "$ocs_repository" domain)"
  smbfs_dir="$(drbl-uriparse "$ocs_repository" path)"
  smb_username="$(drbl-uriparse "$ocs_repository" username)"
  smb_password="$(drbl-uriparse "$ocs_repository" password)"
  # smb_username from URI might contain domain, like: "mygroup;jack"
  if [ -n "$(echo $smb_username | grep ";")" ]; then
    smb_domain="$(echo $smb_username | awk -F";" '{print $1}')"
    smb_account="$(echo $smb_username | awk -F";" '{print $2}')"
  else
    smb_account="$smb_username"
  fi
  if [ -n "$smb_password" ]; then
    smb_password_opt=",password=$smb_password"
  fi
  if [ -n "$smb_domain" ]; then
    smb_domain_opt=",domain=$smb_domain"
  fi
  if [ -z "$(LC_ALL=C lsmod | grep -Ew "^cifs")" ]; then
    # In case cifs is not loaded
    modprobe cifs
  fi
  prepare_mnt_point_ocsroot
  load_ocsroot_mnt_cmd
  # mount -t cifs "//${smb_srv}${smbfs_dir}" $ocsroot -o user="${smb_account}${smb_password_opt}${smb_domain_opt}"${smb_sec_opt} 
  echo "Mounting samba server by:"
  echo "$ocsroot_mnt_cmd_smb"
  eval $ocsroot_mnt_cmd_smb
  [ "$chk_ocsroot_mountpont" = "yes" ] && check_if_ocsroot_a_mountpoint
} # end of do_uri_mount_samba_server
#
do_uri_mount_nfs_server() {
  # For NFS v2, v3
  nfs_ver=nfs
  nfsvers_opt="nfsvers=3"
  nfs_srv="$(drbl-uriparse "$ocs_repository" domain)"
  nfs_dir="$(drbl-uriparse "$ocs_repository" path)"
  prepare_mnt_point_ocsroot
  load_ocsroot_mnt_cmd
  # mount -t $nfs_ver $nfs_srv:$nfs_dir $ocsroot -o $ocsroot_def_mnt_opt,nodiratime,$nfsvers_opt
  echo "Mounting NFS2/NFS3 server by:"
  echo "$ocsroot_mnt_cmd_nfs"
  eval $ocsroot_mnt_cmd_nfs
  [ "$chk_ocsroot_mountpont" = "yes" ] && check_if_ocsroot_a_mountpoint
} # end of do_uri_mount_nfs_server
#
do_uri_mount_nfs4_server() {
  # For NFS v4
  nfs_ver=nfs4
  nfsvers_opt=""
  nfs_srv="$(drbl-uriparse "$ocs_repository" domain)"
  nfs_dir="$(drbl-uriparse "$ocs_repository" path)"
  prepare_mnt_point_ocsroot
  load_ocsroot_mnt_cmd
  # mount -t $nfs_ver $nfs_srv:$nfs_dir $ocsroot -o $ocsroot_def_mnt_opt,nodiratime,$nfsvers_opt
  echo "Mounting NFS4 server by:"
  echo "$ocsroot_mnt_cmd_nfs"
  eval $ocsroot_mnt_cmd_nfs
  [ "$chk_ocsroot_mountpont" = "yes" ] && check_if_ocsroot_a_mountpoint
} # end of do_uri_mount_nfs4_server

#
do_uri_mount_webdav_server() {
  # [dev|smb|ssh|nfs|nfs4|webdav]:[//[user:password@]host[:port]][/]path
  davfs_scheme="$(drbl-uriparse "$ocs_repository" scheme)"
  davfs_srv="$(drbl-uriparse "$ocs_repository" domain)"
  davfs_dir="$(drbl-uriparse "$ocs_repository" path)"
  davfs_url="$davfs_scheme"://"${davfs_srv}""${davfs_dir}"
  ocs-tune-conf-for-webdav
  prepare_mnt_point_ocsroot
  load_ocsroot_mnt_cmd
  ocs_batch_mode="off" # Here it's interactive mode, so no batching.
  # mount -t davfs -o noexec $davfs_url $ocsroot
  echo "Mounting WebDAV server by:"
  echo "$ocsroot_mnt_cmd_webdav"
  eval $ocsroot_mnt_cmd_webdav
  [ "$chk_ocsroot_mountpont" = "yes" ] && check_if_ocsroot_a_mountpoint
} # end of do_uri_mount_webdav_server

#
do_uri_mount_ssh_server() {
  ssh_port_def="22"
  sshfs_extra_opt="-o nonempty,$ocsroot_def_mnt_opt"
  ssh_srv="$(drbl-uriparse "$ocs_repository" domain)"
  sshfs_dir="$(drbl-uriparse "$ocs_repository" path)"
  ssh_account="$(drbl-uriparse "$ocs_repository" username)"
  ssh_port="$(drbl-uriparse "$ocs_repository" port)"
  [ -n "$ssh_port" ] || ssh_port="$ssh_port_def"
  prepare_mnt_point_ocsroot
  load_ocsroot_mnt_cmd
  ocs_batch_mode="off" # Here it's interactive mode, so no batching.
  # sshfs "$ssh_account"@$ssh_srv:"$sshfs_dir/" $ocsroot -p $ssh_port $sshfs_extra_opt
  echo "Mounting SSH server by:"
  echo "$ocsroot_mnt_cmd_sshfs"
  eval $ocsroot_mnt_cmd_sshfs
  [ "$chk_ocsroot_mountpont" = "yes" ] && check_if_ocsroot_a_mountpoint
} # end of do_uri_mount_ssh_server

####################
### Main program ###
####################

ocs_file="$0"
ocs=`basename $ocs_file`
#
while [ $# -gt 0 ]; do
 case "$1" in
   -c|--cmdline-file)
      shift
      if [ -z "$(echo $1 |grep ^-.)" ]; then
        # skip the -xx option, in case 
        cmdl_file="$1"
        shift
      fi
      [ -z "$cmdl_file" ] && echo "-c is used, but no cmdl_file assigned." && exit 1
      ;;
   -s|--skip-ocsroot-mountpoint-chk) chk_ocsroot_mountpont="no"; shift;;
   -*)     echo "${0}: ${1}: invalid option" >&2
           USAGE >& 2
           exit 2 ;;
   *)      break ;;
 esac
done

check_if_root
ask_and_load_lang_set

[ -z "$cmdl_file" ] && cmdl_file="$cmdl_file_def"
if [ ! -e "$cmdl_file" ]; then
  [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
  echo "Kernel cmdline file ($cmdl_file) does _NOT_ exist!"
  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
  echo "$msg_program_stop!"
  exit 1
fi

#
get_ocsroot_src_from_ocs_repository_if_assigned
case $ocsroot_src in
  local_dev)      do_uri_mount_local_dev;;
  samba_server)   do_uri_mount_samba_server;; 
  ssh_server)     do_uri_mount_ssh_server;;
  nfs_server)     do_uri_mount_nfs_server;; 
  nfs4_server)    do_uri_mount_nfs4_server;; 
  webdav_server)  do_uri_mount_webdav_server;; 
  none)           # Nothing assigned, just exit
	          exit 9;;
  *)              
                  scheme="$(drbl-uriparse "$ocs_repository" scheme)"
		  if [ -n "$scheme" ]; then
		    error_msg="$scheme: Unknown or not supporting scheme!"
	          else
		    error_msg="No scheme is correctly assigned!"
	          fi
                  [ "$BOOTUP" = "color" ] && $SETCOLOR_FAILURE
                  echo $error_msg
		  echo "Assigned URI: $ocs_repository"
                  [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
                  echo "Program terminated!"
                  exit 1
		  ;;
esac
