#!/bin/bash ############################################################################## # # # reloc-img, (C) 2007-2010 S. Georgaras # # # # This file is part of Clonezilla-SysRescCD. # # # # Clonezilla-SysRescCD is free software: you can redistribute it and/or # # modify it under the terms of the GNU General Public License as published # # by the Free Software Foundation, either version 2 of the License, or # # (at your option) any later version. # # # # Clonezilla-SysRescCD is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # # GNU General Public License for more details. # # # # You should have received a copy of the GNU General Public License along # # with Clonezilla-SysRescCD. If not, see . # # # ############################################################################## # DEBUG=true versionNumber='0.7' function findDirectories(){ # # <- selectedInputPartition # # -> activeDirectory - selected directory # local lines local dialogLines local cur=1 local cmdLine='' local thisLine local allDirs="$(find "$1" -maxdepth 1 -type d | sed 's|^\.$|/|' | sed '/ /d' | sed 's|^\./||' | sed "s|$1/||" | sed "s|$1||" | sed 's|^$|/|' | sort)" lines="$(echo "$allDirs" | wc -l | sed 's|[ ]*||g')" if [ "$lines" = "" ] || [ "$lines" = "0" ];then activeDirectory='/' return fi while [ "$cur" -le "$lines" ];do thisLine="$(echo "$allDirs" | sed -n "$cur"p)" cmdLine="$cmdLine"\"$thisLine\"" " if [ "$thisLine" = "/" ];then cmdLine="$cmdLine"" \"Top directory in the local device\" " else cmdLine="$cmdLine"\""$(ls -lad "$1"/"$thisLine" | awk '{print $6 " " $7}')\" " fi ((cur++)) done # echo "$cmdLine" # exit if [ "$lines" -gt 10 ];then dialogLines=10 else if [ "$lines" -lt 4 ];then dialogLines=4 else dialogLines="$lines" fi fi echo "dialog --backtitle \"$backTitle\" --title \" Select directory \" --menu 'Please select the directory that holds your images' $((dialogLines+7)) 78 $dialogLines $cmdLine" > /root/dialog.$$ . /root/dialog.$$ 2>/root/selectedDirectory.$$ activeDirectory=$(cat /root/selectedDirectory.$$) rm /root/dialog.$$ } function findSystemPartitions(){ # <- NONE # # -> selectedInputPartition - the partition to scan for images # -> selectedInputPartitionNumber - Index of selectedInputPartition in inputPartition array # # -> diskCount - Number of disks on the system # -> inputDisk - Disks present on the system (array) # -> diskSize - Size of each disk (array) # # -> partitionCount - Number of partitions on the system # -> inputPartition - Partitions present on the system (array) # -> partitionSize - The size of each partition (array) # -> partitionType - The type of each partition (array) # -> CD - Not empty if partition is a CD (array) # allDisks=$(cat /proc/partitions | sed 's|.* ||' | grep -ve '[0-9]$'| grep -v name |grep -ve '^$') [ -z "$allDisks" ] && { dialog --backtitle "$backTitle" --title " No disks found!!! " --msgbox "There seems to be no disk connected to your system, therefore no restoration is possible" 7 70 cleanUP exit 1 } local cmdLine='' diskCount=$(echo "$allDisks" | wc -l) local fDisks='' local count=1 while [ $count -le $diskCount ];do inputDisk[$count]=$(echo "$allDisks" | sed -n ""$count"p") fdisk -l /dev/"${inputDisk[$count]}" 2>/dev/null > /root/clsys-raw-fdisk-"$count".$$ # parted /dev/"${inputDisk[$count]}" print > /root/clsys-raw-parted-"$count".$$ diskSize[$count]=$(sed -n '1p' /root/clsys-raw-fdisk-"$count".$$ | sed 's|.*, ||' | sed 's| bytes||' | sed 's| ||g') cat /root/clsys-raw-fdisk-"$count".$$ | grep -e '^/' | grep -v "Ext'd" | grep -ve "[Ee]xtended" | grep -ve '[sS][wW][aA][pP]' > /root/clsys-part-"$count".$$ ((count++)) done # echo 33 allPartitions=$(cat /root/clsys-part-*$$ | sed 's| .*||' | sed 's|/dev/||') # allSizes=$(grep -e '^ [0-9]' /root/clsys-raw-parted-*.$$ | awk '{print $4}') partitionCount=$(echo "$allPartitions" | wc -l) local cmdLine='' count=1 while [ $count -le $partitionCount ];do inputPartition[$count]=$(echo "$allPartitions" | sed -n ""$count"p") getPartitionSizeFromFdisk "${inputPartition[$count]}" partitionSize[$count]=$( echo "$THIS_PARTITION_SIZE" | sed 's|,|.|') partitionType[$count]=$(grep "${inputPartition[$count]}" /root/clsys-raw-fdisk-*.$$| sed 's|*||' | awk '{printf "%s %s %s %s",$6,$7,$8,$9}' |sed 's| *$||') cmdLine="$cmdLine""${inputPartition[$count]}"" ""\"Size: ${partitionSize[$count]}, Type: ${partitionType[$count]}\""" " ((count++)) done # cleanUP # exit # integrate CD-ROMs local theCDs=$(cat /proc/sys/dev/cdrom/info | grep 'drive name' |sed 's|drive name:[ \t]*||' | awk '{for(i=1;i<=NF;i++) print $i}') local cdCount=$(echo "$theCDs" | wc -l) count=1 while [ $count -le $cdCount ];do ((partitionCount++)) inputPartition[$partitionCount]=$(echo "$theCDs" | sed -n ""$count"p") CD[$partitionCount]=$count cmdLine="$cmdLine""${inputPartition[$partitionCount]}"" ""\"Type: CD-ROM\""" " ((count++)) done # integrate samba shares (cifs) local smbShares=$(mount | sort | grep -e '[ ]cifs[ ]'| sed 's|on ||' |sed 's|type ||' | awk '$3 == "cifs" {print $2}') #### DEBUG #### [ -z "$DEBUG" ] || smbShares='/data' #### END DEBUG #### [ -z "$smbShares" ] || { local smbCount=$(echo "$smbShares" | wc -l) count=1 while [ $count -le $smbCount ];do ((partitionCount++)) inputPartition[$partitionCount]=$(echo "$smbShares" | sed -n ""$count"p") SMB[$count]=$partitionCount cmdLine="$cmdLine"smb"$count"" ""\"Type: Samba Share, $(echo "${inputPartition[$partitionCount]}"|sed 's|.*/||')\""" " ((count++)) done } local nfsShares=$(mount | sort | grep -e '[ ]nfs[ ]'| sed 's|on ||' |sed 's|type ||' | awk '$3 == "nfs" {print $2}') #### DEBUG #### [ -z "$DEBUG" ] || nfsShares='/data' #### END DEBUG #### [ -z "$nfsShares" ] || { local nfsCount=$(echo "$nfsShares" | wc -l) count=1 while [ $count -le $nfsCount ];do ((partitionCount++)) inputPartition[$partitionCount]=$(echo "$nfsShares" | sed -n ""$count"p") NFS[$count]=$partitionCount cmdLine="$cmdLine"nfs"$count"" ""\"Type: NFS Share, $(echo "${inputPartition[$partitionCount]}"|sed 's|.*/||')\""" " ((count++)) done } # echo 66 selectedInputPartition='' echo "dialog --backtitle \"$backTitle\" --title \" Source Partition \" --menu 'Please select the location of your image file' $((partitionCount+7)) 78 $partitionCount $cmdLine" > /root/dialog.$$ . /root/dialog.$$ 2>/root/selectedPartition.$$ selectedInputPartition=$(cat /root/selectedPartition.$$) # set -x # cleanUP # exit [ -z "$selectedInputPartition" ] && { cleanUP exit } if [ ! -z $(echo "$selectedInputPartition"|grep -e '^smb[0-9][0-9]*$') ];then local num=$(echo "$selectedInputPartition"|sed 's|smb||') selectedInputPartitionNumber=${SMB[$num]} workingRemote='y' elif [ ! -z $(echo "$selectedInputPartition"|grep -e '^smb[0-9][0-9]*$') ];then local num=$(echo "$selectedInputPartition"|sed 's|nfs||') selectedInputPartitionNumber=${NFS[$num]} workingRemote='y' else count=1 while [ "${inputPartition[$count]}" != "$selectedInputPartition" ];do ((count++)) done selectedInputPartitionNumber=$count fi # echo 100 # echo EOF # read # cleanUP # exit } function findSambaShare(){ # used only when -i smb echo 'Looking for Samba Shares (this may take some time)... ' partitionCount=0 local smbShares=$(mount | sort | awk '/cifs/ { for(x=1; x<=NF; ++x){ s=substr($x,1,2) if(s!="//"){ s=substr($x,1,1) if(s=="/") mountpoint=$x }if($x=="cifs"){ if(mountpoint!="") print mountpoint }}}') #### DEBUG #### [ -z "$DEBUG" ] || smbShares='/data' #### END DEBUG #### [ -z "$smbShares" ] && { echo echo "No Samba Shares mounted" exit 1 } local smbCount=$(echo "$nfsShares" | wc -l) count=1 while [ $count -le $smbCount ];do ((partitionCount++)) inputPartition[$partitionCount]=$(echo "$smbShares" | sed -n ""$count"p") SMB[$count]=$partitionCount ((count++)) done local num=1 selectedInputPartitionNumber=${SMB[$num]} echo } function findNFSShare(){ # used only when -i nfs echo 'Looking for NFS Shares (this may take some time)... ' partitionCount=0 local nfsShares=$(mount | sort | awk '/nfs/ { for(x=1; x<=NF; ++x){ s=substr($x,1,2) if(s!="//"){ s=substr($x,1,1) if(s=="/") mountpoint=$x }if($x=="nfs"){ if(mountpoint!="") print mountpoint }}}') #### DEBUG #### [ -z "$DEBUG" ] || nfsShares='/data' #### END DEBUG #### [ -z "$nfsShares" ] && { echo echo "No NFS Shares mounted" exit 1 } local nfsCount=$(echo "$nfsShares" | wc -l) count=1 while [ $count -le $nfsCount ];do ((partitionCount++)) inputPartition[$partitionCount]=$(echo "$nfsShares" | sed -n ""$count"p") NFS[$count]=$partitionCount ((count++)) done local num=1 selectedInputPartitionNumber=${NFS[$num]} echo } function findImages(){ # <- folder to scan # # -> selectedInputImage - Number (index) in img array # -> selectedInputImageSize - Size of disk / partition # -> selectedInputImageID - Number - Partition ID (if user selected partition) # # -> imgCount - Number of images found # -> partCount - Number of partitions found # # -> img - image name # -> type - image type (partition/disk) # -> activeItem - name of partition/disk # -> imagePartitionSize - size of partition # -> diskSizeFromImage - disk size # -> partitionIdName - partition id in words # -> id - description if [ -z "$onlyImages" ];then dialog --backtitle "$backTitle" --title " Working " --infobox "Searching for image files" 3 29 fi imgCount=0 partCount=0 local count=1 local n local tmp local pCount local tmpImg local hasDisk=0 # set -x for n in $(find "$1" -name parts 2>/dev/null);do tmp="$(dirname "$n")" if [ -z "$onlyImages" ];then if [ "$(dirname "$tmp")" != "$1" ];then continue fi fi validateImage "$tmp" || continue img[$count]="$(basename "$tmp")" [ -r "$(dirname "$n")"/disk ] && { # it's a disk image hasDisk=1 type[$count]=disk tmp="$(dirname "$n")"/disk activeItem[$count]=$(cat "$tmp") partCount=$(cat "$(dirname "$n")"/parts | awk '{print NF}') tmp=$(dirname "$n") diskSizeFromImage[$count]=$(getDiskSizeFromImage "$tmp") id[$count]="Image: ${img[$count]}, ${type[$count]}: ${activeItem[$count]}"", size: ${diskSizeFromImage[$count]}, parts: $partCount" # scan parts pCount=1 tmpImg="${img[$count]}" while [ $pCount -le $partCount ];do ((count++)) img[$count]="$tmpImg" type[$count]=part activeItem[$count]=$(cat "$n" | awk '{for(i=1;i<=NF;i++) print $i}' | sed -n ""$pCount"p") # set -x calcInputSize "$tmp" "${activeItem[$count]}" imagePartitionSize[$count]="$THIS_INPUT_SIZE" partitionIdName[$count]=$(getPartitionIdNameFromImage /"$tmp" "${activeItem[$count]}") ((pCount++)) id[$count]=" ${type[$count]}: ${activeItem[$count]}, size: ${imagePartitionSize[$count]}, type: ${partitionIdName[$count]}" done } || { # it's a partition image type[$count]=part activeItem[$count]=$(cat "$n") partCount=1 calcInputSize /"$tmp" "${activeItem[$count]}" imagePartitionSize[$count]="$THIS_INPUT_SIZE" partitionIdName[$count]=$(getPartitionIdNameFromImage /"$tmp" "${activeItem[$count]}") id[$count]="Image: ${img[$count]}, ${type[$count]}: ${activeItem[$count]}, size: ${imagePartitionSize[$count]}, type: ${partitionIdName[$count]}" } imgCount="$count" ((count++)) done # exit [ $imgCount -eq 0 ] &&{ local msgType [ -z "${CD[$selectedInputPartitionNumber]}" ] && msgType=Partition || msgType=CD-ROM if [ -n "$(echo "$selectedInputPartition" | grep '/')" ];then msgType=Folder selectedInputPartition=/"$selectedInputPartition" fi if [ -z "$onlyImages" ];then dialog --backtitle "$backTitle" --title " No images found!!! " --msgbox "$msgType"" $selectedInputPartition contains no valid image files Please try again selecting a different location" 7 60 else echo "Error: $msgType $selectedInputPartition contains no valid image files!!!" fi cleanUP exit 1 } if [ -z "$onlyImages" ];then local cmdLine='' count=1 while [ $count -le $imgCount ];do cmdLine="$cmdLine""$count"" \"""${id[$count]}""\" " ((count++)) done selectedInputImage='' if [ $hasDisk -eq 1 ];then local tit=" Partition/Disk to Restore " local txt="Please select the partition/disk to restore" # local msg="At least one of the images found contains a full disk backup # # Please use this image file to restore a full disk, ONLY in case the target disk is EXACTLY the same type as the original one (the disk that was backed up) # # In case the target disk is a different (bigger) one, you should NOT perform a full disk restore. Instead, exit this program, partition the target disk manually, in such a way that its partitions represent the partitions of the original disk, and then restore EACH partition seperatelly # # This way you will not have to resize the restored partitions on the target disk, after the entire restoration procedure has ended # # Do you want to continue?" # # dialog --backtitle "$backTitle" --title " Tips on disk restoration " --yesno "$msg" 20 72 # # if [ $? -eq 1 ];then # cleanUP # exit # fi else local tit=" Target Partition " local txt="Please select the partition to restore" fi echo "dialog --backtitle \"$backTitle\" --title \""$tit"\" --menu \""$txt"\" $((imgCount+7)) 78 $imgCount $cmdLine" > /root/dialog.$$ . /root/dialog.$$ 2>/root/selectedImage.$$ selectedInputImage=$(cat /root/selectedImage.$$) [ -z "$selectedInputImage" ] && { cleanUP exit } # set -x # calculate image size and partition ID (if required) if [ "${type[$selectedInputImage]}" = "part" ];then calcInputSize /"$selectedInputPartition"/"${img[$selectedInputImage]}" "${activeItem[$selectedInputImage]}" selectedInputImageSize="$THIS_INPUT_SIZE" calcInputID /"$selectedInputPartition"/"${img[$selectedInputImage]}" "${activeItem[$selectedInputImage]}" selectedInputImageID=$THIS_INPUT_ID else # calcInputSize /"$selectedInputPartition"/"${img[$selectedInputImage]}" selectedInputImageSize="${diskSizeFromImage[$selectedInputImage]}" fi # # # cleanUP # exit else echo "Image files found in: $selectedInputPartition" count=1 until [ -z "${id[$count]}" ];do echo " ${id[$count]}" ((count++)) done fi } function getPartitionIdNameFromImage(){ local id=$(grep "$2" "$1"/*pt.sf | sed 's|.*Id= *||' | sed 's|,.*$||') sfdisk -T |sed 's|^[ ]||' | grep -e "^$id[ \t]" | sed "s|^$id *||" } function getDiskSizeFromImage(){ local lin=$(awk 'BEGIN{FS="=" count=0} {if (count==0) b=$2 else{ b=b" * " b=b$2 } count++} END{print b}' "$1"/*chs.sf | bc) local size=$(echo "$lin * 512" | bc) toMGByte "$size" } function getDiskSizeFromDisk(){ local size=$(fdisk -l /dev/"$1" | grep -e '^Disk /dev/' | sed 's|.*, *||' | sed 's| *bytes||') toMGByte "$size" } function toMGByte(){ if [ $(expr length "$1") -le 9 ];then echo $(expr substr "$1" 1 3 )"MB" elif [ $(expr length "$1") -eq 10 ];then echo $(expr substr "$1" 1 2 | sed 's|\([0-9]\)$|.\1|')"GB" elif [ $(expr length "$1") -lt 12 ];then echo $(expr substr "$1" 1 3 | sed 's|\([0-9]\)$|.\1|')"GB" else echo $(expr substr "$1" 1 4 | sed 's|\([0-9]\)$|.\1|')"GB" fi } function validateImage(){ [ -d "$1"/parts ] && return 1 local sf=$(find "$1" -name "*-chs.sf" 2>/dev/null | wc -l) [ $sf -eq 0 ] && return 1 local pt=$(find "$1" -name "*-pt.sf" 2>/dev/null | wc -l) [ $pt -eq 0 ] && return 1 # modification to read unsplited images # thanks to Viking (24/11/2008) # local aa=$(find "$1" -name "*.aa" 2>/dev/null | wc -l) # [ $aa -eq 0 ] && return 1 return 0 } function cleanUP(){ if [ ! -z "$selectedInputPartition" ];then [ -z "$workingRemote" ] && umount /"$selectedInputPartition" 2>/dev/null fi cd rm /root/*.$$ 2>/dev/null rm -rf /home/partimag/reloc-image umount /home/partimag 2>/dev/null # umount -a 2>/dev/null [ -z "$onlyImages" ] && clear } function calcInputID(){ THIS_INPUT_ID=$(sed -n "/$2/p" "$1"/*-pt.sf | sed 's|.*Id= *||' | sed 's|,.*$||') } function calcInputSize(){ local bytesPerSector=512 local l local pSize local cylinders local heads local sectors if [ -z "$2" ];then cylinders=$(sed -n '/cylinders=/p' "$1"/*-chs.sf | sed 's|cylinders=||') heads=$(sed -n '/heads=/p' "$1"/*-chs.sf | sed 's|heads=||') sectors=$(sed -n '/sectors=/p' "$1"/*-chs.sf | sed 's|sectors=||') THIS_INPUT_SIZE=$(echo "scale=2; $cylinders * $heads * $sectors * $bytesPerSector" | bc) else pSize=$(sed -n "/$2/p" "$1"/*-pt.sf | sed 's|.*size= *||' | sed 's|,.*||') THIS_INPUT_SIZE=$(echo "scale=2; $pSize * $bytesPerSector" | bc) fi l=$(expr length $THIS_INPUT_SIZE) if [ $l -gt 9 ];then THIS_INPUT_SIZE=$(echo "scale=2; $THIS_INPUT_SIZE / 1024 / 1024 / 1024" | bc)GB else THIS_INPUT_SIZE=$(echo "scale=3; $THIS_INPUT_SIZE / 1024 / 1024" | bc | sed 's|\.000|.00|')MB fi } function getPartitionSizeFromFdisk(){ local disk=$(echo "$1" | sed 's|[0-9]||') if [ ! -e /root/closys-fdisk-"$disk".$$ ];then fdisk -l /dev/"$disk" > /root/closys-fdisk-"$disk".$$ fi local size=$(sed 's|*||' /root/closys-fdisk-"$disk".$$ | grep "$1" | awk '{print $4}' | sed 's|[+-]||') local gB=$(echo "scale=2; $size / 1024 / 1024 " | bc | sed 's|^\.|0.|')GB local mB=$(echo "scale=2; $size / 1024 " | bc)MB if [ -z $(echo "$gB" | grep -e '^[0]') ];then THIS_PARTITION_SIZE="$gB" else THIS_PARTITION_SIZE="$mB" fi } function getOutputPartition(){ ## select target partition dialog --backtitle "$backTitle" --title " Working " --infobox "Searching for valid partitions" 3 34 local count=1 local cmdLine='' local outputPartitionCount=0 local tmpDisk local tmpID local fatpartitions='' local compResult until [ -z "${inputPartition[$count]}" ];do if [ "${inputPartition[$count]}" != "$selectedInputPartition" ] && [ -z "${CD[$count]}" ];then tmpDisk=$(echo "${inputPartition[$count]}" | sed 's|[0-9]||') tmpID=$(fdisk -l /dev/"$tmpDisk" 2>/dev/null| grep "${inputPartition[$count]}" | sed 's|*||' | awk '{print $5}') if [ "$tmpID" = "$selectedInputImageID" ];then comparePartitionsSize "$selectedInputImageSize" "${partitionSize[$count]}" compResult=$? if [ $compResult -eq 0 ];then cmdLine="$cmdLine""${inputPartition[$count]}"" ""\"Size: ${partitionSize[$count]}, Type: ${partitionType[$count]} (identical part)\""" " ((outputPartitionCount++)) elif [ $compResult -eq 2 ];then cmdLine="$cmdLine""${inputPartition[$count]}"" ""\"Size: ${partitionSize[$count]}, Type: ${partitionType[$count]}\""" " ((outputPartitionCount++)) needsResize[$count]='-r' # echo "count = $count" fi fi if [ "$tmpID" = "b" ] && [ "$selectedInputImageID" = "6" ];then comparePartitionsSize "$selectedInputImageSize" "${partitionSize[$count]}" compResult=$? if [ $compResult -eq 0 ];then cmdLine="$cmdLine""${inputPartition[$count]}"" ""\"Size: ${partitionSize[$count]}, Type: ${partitionType[$count]} (identical part)\""" " ((outputPartitionCount++)) elif [ $compResult -eq 2 ];then cmdLine="$cmdLine""${inputPartition[$count]}"" ""\"Size: ${partitionSize[$count]}, Type: ${partitionType[$count]}\""" " ((outputPartitionCount++)) needsResize[$count]='-r' # echo "count = $count" fi fi if [ "$tmpID" = "c" ] && [ "$selectedInputImageID" = "6" ];then comparePartitionsSize "$selectedInputImageSize" "${partitionSize[$count]}" compResult=$? if [ $compResult -eq 0 ];then cmdLine="$cmdLine""${inputPartition[$count]}"" ""\"Size: ${partitionSize[$count]}, Type: ${partitionType[$count]} (identical part)\""" " ((outputPartitionCount++)) elif [ $compResult -eq 2 ];then cmdLine="$cmdLine""${inputPartition[$count]}"" ""\"Size: ${partitionSize[$count]}, Type: ${partitionType[$count]}\""" " ((outputPartitionCount++)) needsResize[$count]='-r' # echo "count = $count" fi fi fi ((count++)) done if [ $outputPartitionCount -eq 0 ];then dialog --backtitle "$backTitle" --title " No available partitions!!! " --msgbox "The program found no valid partitions for restoration!!! The selected (backed up) partition size is $selectedInputImageSize, type ${partitionIdName[$selectedInputImage]}, but none of the partitions found on your disks are either this big or of this type This means that you should repartition one of your disks and create a partition with size at least $selectedInputImageSize and type ${partitionIdName[$selectedInputImage]}" 12 70 cleanUP exit fi # cleanUP # exit tmpPartName=$(sfdisk -T | sed 's|^[ \t]||' | grep -e "^"$selectedInputImageID" " | sed "s|^"$selectedInputImageID"[ /t]*||" | sed 's|,.*$||') if [ $outputPartitionCount -gt 0 ];then # chech partitions size local thisHeight=$outputPartitionCount local totHeigh=$((outputPartitionCount+8)) if [ $totHeigh -gt 20 ];then totHeigh=20 thisHeight=$(totHeigh-8) fi echo "dialog --backtitle \"$backTitle\" --title \" Target Partition \" --menu \"Please select the partition where your image file will be restored Original image type: $tmpPartName, size: $selectedInputImageSize\" $totHeigh 78 $thisHeight $cmdLine" > /root/dialog.$$ . /root/dialog.$$ 2>/root/outputPartition.$$ selectedOutputPartition=$(cat /root/outputPartition.$$) [ -z "$selectedOutputPartition" ] && { cleanUP exit } else dialog --backtitle "$backTitle" --title " No available partitions!!! " --msgbox "The program found no valid partitions for restoration!!! The selected (backed up) partition type is $tmpPartName (ID = $selectedInputImageID), but none of the partitions found on your disks are of this type This means that you should repartition one of your disks and create a $tmpPartName partition with ID $selectedInputImageID, or change an existing ID to $selectedInputImageID" 12 70 cleanUP exit 1 fi # set -x count=1 until [ -z "${inputPartition[$count]}" ];do if [ "${inputPartition[$count]}" = "$selectedOutputPartition" ];then selectedOutputPartitionIndex=$count break fi ((count++)) done set +x } function comparePartitionsSize(){ # # partition size format: xxxx.x[kMG]B # # <- $1 $2 - the sizes # # -> 0 - equal # -> 1 - $1 > $2 # -> 2 - $2 > $1 # set -x if [ "$1" = "$2" ];then return 0;fi local count=1 while [ $count -le 2 ];do local size[$count]=$(echo "$1" | sed 's|[kMG]B||') # echo "size[$count] = ${size[$count]}" local factor[$count]=$(echo "$1" | sed 's|.*\([kMG]\)B|\1|') # echo "factor[$count] = ${factor[$count]}" getMultiplier ${factor[$count]} local multiplier[$count]=$THIS_MULTIPLIER # echo "multiplier[$count] = ${multiplier[$count]}" shift ((count++)) done return $(echo "a=${size[1]} * ${multiplier[1]}; b=${size[2]} * ${multiplier[2]}; if (a==b) print 0 if (a>b) print 1 if (a/root/params.$$ if [ $? -ne 0 ];then cleanUP exit fi count=1 while [ $count -le 3 ];do param[$count]=$(sed -n ""$count"p" /root/params.$$ | sed 's/[ ]*//' ) ((count++)) done } function preparePartitionImage(){ dialog --backtitle "$backTitle" --title " Working " --infobox "Preparing temporary image file" 3 34 if [ -d /home/partimag ];then umount /home/partimag 2>/dev/null rm -rf /home/partimag/* 2>/dev/null else rm -rf /home/partimag 2>/dev/null mkdir /home/partimag fi rm -rf /home/partimag/reloc-image 2>/dev/null mkdir /home/partimag/reloc-image # echo /"$selectedInputPartition"/"${img[$selectedInputImage]}" local inTmpDisk=$(echo "${activeItem[$selectedInputImage]}" | sed 's|[0-9]||') local outTmpDisk=$(echo "$selectedOutputPartition" | sed 's|[0-9]||') local outTmpPartition=$(echo "$selectedOutputPartition" | sed 's|[a-z]*||') local tmpFile local outFile local count #set -x for n in $(find /"$selectedInputPartition"/"${img[$selectedInputImage]}" -name "*");do tmpFile=$(basename "$n") if [ "$tmpFile" != "${img[$selectedInputImage]}" ];then # echo "$tmpFile" outFile=$(echo "$tmpFile" | sed "s|${activeItem[$selectedInputImage]}|$selectedOutputPartition|" |sed "s|$inTmpDisk|$outTmpDisk|") # echo "${activeItem[$selectedInputImage]} => $selectedOutputPartition" # echo ln -s "$n" /home/partimag/reloc-image/"$outFile" ln -s "$n" /home/partimag/reloc-image/"$outFile" fi done if [ "${activeItem[$selectedInputImage]}" != "$selectedOutputPartition" ];then [ -e /home/partimag/reloc-image/disk ] && { rm /home/partimag/reloc-image/disk echo "$outTmpDisk" > /home/partimag/reloc-image/disk } sed "s|${activeItem[$selectedInputImage]}|$selectedOutputPartition|" /home/partimag/reloc-image/parts | sed "s|$inTmpDisk|$outTmpDisk|" > /home/partimag/reloc-image/parts.tmp rm /home/partimag/reloc-image/parts mv /home/partimag/reloc-image/parts.tmp /home/partimag/reloc-image/parts rm /home/partimag/reloc-image/"$outTmpDisk"-pt.sf echo "# partition table of /dev/"$outTmpDisk"" > /home/partimag/reloc-image/"$outTmpDisk"-pt.sf echo "unit: sectors" >> /home/partimag/reloc-image/"$outTmpDisk"-pt.sf echo >> /home/partimag/reloc-image/"$outTmpDisk"-pt.sf count=1 while [ $count -lt $outTmpPartition ];do echo "/dev/"$outTmpDisk""$count" : start= 0, size= 0, Id= 0" >> /home/partimag/reloc-image/"$outTmpDisk"-pt.sf.tmp ((count++)) done grep "${activeItem[$selectedInputImage]}" /home/partimag/reloc-image/"$outTmpDisk"-pt.sf | sed "s|${activeItem[$selectedInputImage]}|$selectedOutputPartition|" >> /home/partimag/reloc-image/"$outTmpDisk"-pt.sf.tmp rm /home/partimag/reloc-image/"$outTmpDisk"-pt.sf mv /home/partimag/reloc-image/"$outTmpDisk"-pt.sf.tmp /home/partimag/reloc-image/"$outTmpDisk"-pt.sf fi } function doPartitionRestore(){ # set -x if [ -z "${needsResize[$selectedOutputPartitionIndex]}" ];then msg="The temporary image file is now ready, and you are about to start the Restore operation Are you sure you want to restore the backup of partition ${activeItem[$selectedInputImage]} to partition $selectedOutputPartition?" else msg="The temporary image file is now ready, and you are about to start the Restore operation Are you sure you want to restore and resize the backup of partition ${activeItem[$selectedInputImage]} to partition $selectedOutputPartition?" fi dialog --backtitle "$backTitle" --title "Ready to Restore" --yesno "$msg" 11 70 if [ $? -eq 0 ];then # Do restore COMMAND="ocs-sr -p true -k -t "${needsResize[$selectedOutputPartitionIndex]}" -b restoreparts reloc-image $selectedOutputPartition" fi } function getOutputDisk(){ # # -> diskGeometry - system disk geometry (array) # item empty if disk smaller than image # or not same number of partitions # or partitions not same type # -> equalDisk - denotes an equal disk geometry (array) # item ont empty if disk is equal to image disk # -> diskToRestoreCount - Number of available disks to restore local cmdLine diskToRestoreCount=0 getDiskGeometry selectedImageDiskGeometry=$THIS_GEOMETRY local count=1 local mountedDisk=$(echo "$selectedInputPartition" | sed 's|[0-9]||') # set -x while [ $count -le $diskCount ];do if [ "${inputDisk[$count]}" != "$mountedDisk" ];then getDiskGeometry /dev/"${inputDisk[$count]}" if [ "$THIS_GEOMETRY" = "$selectedImageDiskGeometry" ];then # we have two identical disks diskGeometry[$count]="$THIS_GEOMETRY" equalDisk[$count]=1 ((diskToRestoreCount++)) cmdLine="$cmdLine""\"""${inputDisk[$count]}""\""" ""\"""Size: $(getDiskSizeFromDisk ${inputDisk[$count]}) (identical disk)""\" " else # disks are different local selGeo=$(echo "$selectedImageDiskGeometry" |sed 's|,|*|g') local thisGeo=$(echo "$THIS_GEOMETRY" |sed 's|,|*|g') local compResult=$(echo "a=$selGeo; b=$thisGeo; if (a==b) print 0 if (a>b) print 1 if (a /root/dialog.$$ . /root/dialog.$$ 2>/root/selectedDisk.$$ selectedOutputDisk=$(cat /root/selectedDisk.$$) [ -z "$selectedOutputDisk" ] && { cleanUP exit } } function getDiskGeometry(){ if [ -z "$1" ];then # get image disk geometry THIS_GEOMETRY=$(awk 'BEGIN{FS="=" count=0} {if (count==0) b=$2 else{ b=b"," b=b$2 } count++} END{print b}' /"$selectedInputPartition"/"${img[$selectedInputImage]}"/*-chs.sf) else # get disk geometry THIS_GEOMETRY=$(sfdisk -g "$1" | sed 's|^.*:||' | sed 's|cylinders||' | sed 's|heads||' | sed 's|sectors/track||' | sed 's| *||g') fi } function checkDisksPartitions(){ local imgData=$(grep -e '^/dev/' /"$selectedInputPartition"/"${img[$selectedInputImage]}"/*-pt.sf | sed 's| : .*Id= *|:|') local diskData=$(sfdisk -l /dev/${inputDisk[$count]} 2>/dev/null| grep -e '^/dev/' | awk '{ if ($2=="*") print $1 ":" $7 ", bootable" else print $1 ":" $6}' | sed "s|${inputDisk[$count]}|${activeItem[$selectedInputImage]}|") if [ "$imgData" != "$diskData" ];then echo 1 return fi # check partitions size local numOfPartitions=$(grep 'size=' /"$selectedInputPartition"/"${img[$selectedInputImage]}"/*-pt.sf | wc -l) local imgPartitionSize local diskPartitionSize local partCount=1 sfdisk -d /dev/${inputDisk[$count]} > /root/disk-${inputDisk[$count]}.$$ while [ $partCount -le $numOfPartitions ];do imgPartitionSize=$(grep 'size=' /"$selectedInputPartition"/"${img[$selectedInputImage]}"/*-pt.sf | sed -n ""$partCount"p"| sed 's|.*size= *||' | sed 's|,.*$||' | sed 's|[+-]||') diskPartitionSize=$(grep 'size=' /root/disk-${inputDisk[$count]}.$$ | sed -n ""$partCount"p"| sed 's|.*size= *||' | sed 's|,.*$||' | sed 's|[+-]||') local compResult=$(echo "a=$imgPartitionSize; b=$diskPartitionSize; if (a==b) print 0 if (a>b) print 1 if (a/dev/null rm -rf /home/partimag/* 2>/dev/null else rm -rf /home/partimag 2>/dev/null mkdir /home/partimag fi rm -rf /home/partimag/reloc-image 2>/dev/null mkdir /home/partimag/reloc-image # count is not local, will be used in doDiskRestore count=1 until [ -z "${inputDisk[$count]}" ];do # if [ "${activeItem[$count]}" = "$selectedOutputDisk" ];then if [ "${inputDisk[$count]}" = "$selectedOutputDisk" ];then break fi ((count++)) done local tmpFile for n in $(find /"$selectedInputPartition"/"${img[$selectedInputImage]}" -name "*");do tmpFile=$(basename "$n") if [ "$tmpFile" != "${img[$selectedInputImage]}" ];then outFile=$(echo "$tmpFile" |sed "s|${activeItem[$selectedInputImage]}|$selectedOutputDisk|") ln -s "$n" /home/partimag/reloc-image/"$outFile" fi done if [ "${activeItem[$selectedInputImage]}" != "$selectedOutputDisk" ];then rm /home/partimag/reloc-image/disk echo "$selectedOutputDisk" > /home/partimag/reloc-image/disk rm /home/partimag/reloc-image/parts echo "$(cat /"$selectedInputPartition"/"${img[$selectedInputImage]}"/parts | sed "s|${activeItem[$selectedInputImage]}|$selectedOutputDisk|")" > /home/partimag/reloc-image/parts rm /home/partimag/reloc-image/"$selectedOutputDisk"-pt.sf sfdisk -d /dev/"$selectedOutputDisk" > /home/partimag/reloc-image/"$selectedOutputDisk"-pt.sf if [ -z "${equalDisk[$count]}" ];then rm /home/partimag/reloc-image/"$selectedOutputDisk"-chs.sf sfdisk -d /dev/"$selectedOutputDisk" > /home/partimag/reloc-image/"$selectedOutputDisk"-chs.sf fi fi } function doDiskRestore(){ if [ -z "${equalDisk[$count]}" ];then getRestoreParameters # disks not equal, do resize, restore MBR, don't create partitions msg="The temporary image file is now ready, and you are about to start the Restore operation You are about to restore the backup of disk ${activeItem[$selectedInputImage]} to disk $selectedOutputDisk Info: The target disk is larger than the backed up disk Selected Restore options will be be applied Do you want to continue?" dialog --backtitle "$backTitle" --title "Ready to Restore" --yesno "$msg" 16 70 if [ $? -eq 0 ];then # Do restore COMMAND="ocs-sr -p true -e -b "${param[1]}" "${param[2]}" "${param[3]}" restoredisk reloc-image $selectedOutputDisk" fi else # disks are equal, restore MBR, do partitioning, no resize msg="The temporary image file is now ready, and you are about to start the Restore operation You are about to restore the backup of disk ${activeItem[$selectedInputImage]} to disk $selectedOutputDisk Info: The disks are identical, so the target disk will be partitioned and the MBR will be restored Do you want to continue?" dialog --backtitle "$backTitle" --title "Ready to Restore" --yesno "$msg" 16 70 if [ $? -eq 0 ];then # Do restore COMMAND="ocs-sr -p true -e -b restoredisk reloc-image $selectedOutputDisk" fi fi } function testRoot(){ if [ "$(whoami)" != "root" ];then printVersion echo "Error: This script must be executed by root..." exit fi } function printVersion(){ echo "Clonezilla Live Image Restoration with Relocation $(basename $0) v. $versionNumber - (C) 2007-2008 S. Georgaras " } function printHelp(){ printVersion echo "Usage: $(basename $0) Available options: i [location] Print info about Clonezilla Live Image files found in [location] [location] may be a hard disk partition, a CD-ROM device name or smb - the first Samba Share nfs - the first NFS Share Remote shares must be mounted beforehand v Print version info and exit h Print this screen and exit" } # # # Script starts here # # # findDirectories /home/spiros/multibootcd/files # #findDirectories /home/partimag # # exit #toMGByte "$1" #exit # grep -e '^/dev/' /data/test-img/hda-pt.sf | sed 's| : .*Id= *|:|' # # # sfdisk -l /dev/hda 2>/dev/null| grep -e '^/dev/' | awk '{ # if ($2=="*") # print $1 ":" $7 ", bootable" # else # print $1 ":" $6}' # exit # getPartitionIdNameFromImage /data/usb250-img sda4 # exit # set -x # getDiskSizeFromImage /data/usb250-img # exit # echo "$partitionList" # exit # getMultiplier M f g # echo "$THIS_MULTIPLIER" # set -x # comparePartitionsSize 2GB 2GB # echo $? # exit # set -x # getPartitionSizeFromFdisk hda1 # echo "$THIS_PARTITION_SIZE" # exit # mountedInputPartition=/data # # set -x # findImages "$mountedInputPartition" # set -x # count=1 # until [ -z "${img[$count]}" ];do # echo "${id[$count]}" # ((count++)) # done # # exit # calcInputSize /data/usb250-img # calcInputSize /data/usb250-img sda4 # calcInputID /data/usb250-img sda4 # exit while getopts hvi: opt do case "$opt" in i) onlyImages=true diskToScan=$(echo "$OPTARG" | sed 's|^/dev/||') ;; v) printVersion exit;; h) printHelp exit;; esac done shift $(( OPTIND - 1 )) testRoot backTitle="Clonezilla Live Image Restoration with Relocation" for CHK_DIR in /home/partimag /tmp/local-dev;do CHK_HOME_PARTIMAG="$(mount | grep "$CHK_DIR")" if [ -n "$CHK_HOME_PARTIMAG" ];then CHK_MSG=" A local partition or shared folder is already mounted under "$CHK_DIR". reloc-img will now terminate to prevent loss of data Please unmount it and try again" CHK_TITLE=" "$CHK_DIR" already mounted!!! " if [ -z "$onlyImages" ];then dialog --backtitle "$backTitle" --title "$CHK_TITLE" --msgbox "$CHK_MSG" 10 66 else echo "$CHK_MSG" echo fi # Don't use cleanUP here, we want user to see the mounted partition # cleanUP exit fi done trap cleanUP 2 if [ ! -z "$onlyImages" ];then printVersion if [ "$diskToScan" = "smb" ];then # if [ $(mount |grep cifs | wc -l) -eq 0 ];then # echo "Error: No Samba Share mounted!!!" # cleanUP # exit # fi # set -x selectedInputPartition=smb1 workingRemote='y' findSambaShare elif [ "$diskToScan" = "nfs" ];then if [ $(mount |grep nfs | wc -l) -eq 0 ];then echo "Error: No NFS Share mounted!!!" cleanUP exit fi selectedInputPartition=nfs1 workingRemote='y' findNFSShare else test1=$(cat /proc/partitions | grep "$diskToScan") if [ -z "$test1" ];then # It is not a disk partition # Is it a CD-ROM? test1=$(cat /proc/sys/dev/cdrom/info | grep 'drive name' |sed 's|drive name:[ \t]*||' | awk '{for(i=1;i<=NF;i++) print $i}' | grep "$diskToScan") if [ -z "$test1" ];then echo "Error: No such partition or CD-ROM: $diskToScan" cleanUP exit fi fi selectedInputPartition="$diskToScan" fi else msg="This program is part of Clonezilla-SysRescCD, and is provided with the hope that it will be error-free and useful. If you have found a bug, or the program does not behave as expected, please report it to Spiros Georgaras It will help you restore a Clonezilla Image file to a disk/partition different from the one originally backed up. For example, you will be able to restore your backed up hdb disk to a (new) disk, hdc, or your backed up hda4 partition to a (new) partition, hdb3. The target disk/partition must be the same partition type and at least equal (size-wise) to the old - backed up - disk/partition Please make sure all removable devices are connected to the system before pressing OK, and that no local partition is mounted All data in the target disk/partition will be OVERWRITTEN!!! ---------------------- THIS SOFTWARE COMES WITH ABSOLUTELY NO WARRANTY! USE AT YOUR OWN RISK! ----------------------" msg1="Do you want to continue?" dialog --backtitle "$backTitle" --title " Wellcome " \ --msgbox "$msg" 20 72 \ --and-widget --yesno "$msg1" 5 45 || { clear exit } dialog --backtitle "$backTitle" --title " Working " --infobox "Determining system disks and partitions" 3 43 findSystemPartitions # mount selectedInputPartition dialog --backtitle "$backTitle" --title " Working " --infobox "Mounting selected device" 3 28 fi [ -z "$selectedInputPartition" ] && { cleanUP echo "Error: selectedInputPartition is empty!!!" exit 1 } # set -x if [ -z "$workingRemote" ];then # mount partition mkdir /"$selectedInputPartition" 2>/dev/null [ -d /"$selectedInputPartition" ] || { cleanUP echo "Error: Could not create folder: /$selectedInputPartition" exit 1 } #set -x if [ -z "$DEBUG" ];then mkdir /"$selectedInputPartition" 2>/dev/null if [ -z "${CD[$selectedInputPartitionNumber]}" ];then # This is a disk partition mount /dev/"$selectedInputPartition" /"$selectedInputPartition" 2>/dev/null mountResult=$? else # This is a CD # Is it mounted? rm /home/partimag 2>/dev/null mkdir /home/partimag 2>/dev/null if [ -z "$(mount | grep "/dev/$selectedInputPartition")" ];then # No it's not, mount it echo "mount /dev/\"$selectedInputPartition\" /\"$selectedInputPartition\"" > /root/mountCommand.$$ . /root/mountCommand.$$ && mountResult=0 || mountResult=1 else # Yes it is ,mount through bind bindDir=$(mount | grep "/dev/$selectedInputPartition" | sed 's|.* on ||' | sed 's| type.*||') # echo "mount --bind \"$bindDir\" /\"$selectedInputPartition\" 2>/dev/null" > /root/mountCommand.$$ if [ -d "$bindDir"/home/partimag ]; then bindDir="$bindDir"/home/partimag;fi echo "mount --bind \"$bindDir\" /\"$selectedInputPartition\" 2>/dev/null" > /root/mountCommand.$$ chmod +x /root/mountCommand.$$ . /root/mountCommand.$$ && mountResult=0 || mountResult=1 fi fi else ### start DEBUG section mount --bind /data /"$selectedInputPartition" mountResult=$? ### end DEBUG section fi #read # Chech mounting result if [ $mountResult -ne 0 ];then if [ -z "$onlyImages" ];then if [ -z "${CD[$selectedInputPartitionNumber]}" ];then dialog --backtitle "$backTitle" --title " Mount error!!! " --msgbox "Partition $selectedInputPartition could not be mounted Please unmount all local partitions, and try again" 7 70 cleanUP exit 1 else while [ $mountResult -ne 0 ];do dialog --backtitle "$backTitle" --title " Mount error!!! " --yesno "CD-ROM $selectedInputPartition could not be mounted. This may be caused because you did not load the disk in the CD-ROM drive. Make sure the disk is in the drive and press Yes Do you want to try again?" 9 70 if [ $? -eq 0 ];then dialog --backtitle "$backTitle" --title " Working " --infobox "Mounting selected device" 3 28 . /root/mountCommand.$$ && mountResult=0 || mountResult=1 else cleanUP exit 1 fi done fi else echo "Error: Could not mount $selectedInputPartition" cleanUP exit 1 fi fi else selectedInputPartition=$(echo "${inputPartition[$selectedInputPartitionNumber]}" | sed 's|^/||') fi ######################################################## # # find directories... # ######################################################## if [ -z "$onlyImages" ];then findDirectories /"$selectedInputPartition" if [ -z "$activeDirectory" ];then cleanUP exit fi if [ "$activeDirectory" != "/" ];then selectedInputPartition="$selectedInputPartition"/"$activeDirectory" fi fi ######################################################## findImages /"$selectedInputPartition" if [ ! -z "$onlyImages" ];then cleanUP exit fi if [ "${type[$selectedInputImage]}" = "part" ];then getOutputPartition preparePartitionImage doPartitionRestore else getOutputDisk prepareDiskImage doDiskRestore fi # checking=aaa if [ ! -z "$COMMAND" ];then if [ -z "$checking" ];then $COMMAND else echo "The command that would be executed is: $COMMAND" # read fi fi cleanUP