1 |
#!/bin/bash |
2 |
# DEBUG=true |
3 |
versionNumber='0.7' |
4 |
|
5 |
function findDirectories(){ |
6 |
# |
7 |
# <- selectedInputPartition |
8 |
# |
9 |
# -> activeDirectory - selected directory |
10 |
# |
11 |
|
12 |
local lines |
13 |
local dialogLines |
14 |
local cur=1 |
15 |
local cmdLine='' |
16 |
local thisLine |
17 |
|
18 |
local allDirs="$(find "$1" -maxdepth 1 -type d | sed 's|^\.$|/|' | sed '/ /d' | sed 's|^\./||' | sed "s|$1/||" | sed "s|$1||" | sed 's|^$|/|' | sort)" |
19 |
lines="$(echo "$allDirs" | wc -l | sed 's|[ ]*||g')" |
20 |
if [ "$lines" = "" ] || [ "$lines" = "0" ];then |
21 |
activeDirectory='/' |
22 |
return |
23 |
fi |
24 |
|
25 |
|
26 |
while [ "$cur" -le "$lines" ];do |
27 |
thisLine="$(echo "$allDirs" | sed -n "$cur"p)" |
28 |
cmdLine="$cmdLine"\"$thisLine\"" " |
29 |
if [ "$thisLine" = "/" ];then |
30 |
cmdLine="$cmdLine"" \"Top directory in the local device\" " |
31 |
else |
32 |
cmdLine="$cmdLine"\""$(ls -lad "$1"/"$thisLine" | awk '{print $6 " " $7}')\" " |
33 |
fi |
34 |
((cur++)) |
35 |
done |
36 |
|
37 |
# echo "$cmdLine" |
38 |
# exit |
39 |
|
40 |
if [ "$lines" -gt 10 ];then |
41 |
dialogLines=10 |
42 |
else |
43 |
if [ "$lines" -lt 4 ];then |
44 |
dialogLines=4 |
45 |
else |
46 |
dialogLines="$lines" |
47 |
fi |
48 |
fi |
49 |
|
50 |
echo "dialog --backtitle \"$backTitle\" --title \" Select directory \" --menu 'Please select the directory that holds your images' $((dialogLines+7)) 78 $dialogLines $cmdLine" > /root/dialog.$$ |
51 |
|
52 |
. /root/dialog.$$ 2>/root/selectedDirectory.$$ |
53 |
|
54 |
activeDirectory=$(cat /root/selectedDirectory.$$) |
55 |
|
56 |
rm /root/dialog.$$ |
57 |
} |
58 |
|
59 |
function findSystemPartitions(){ |
60 |
# <- NONE |
61 |
# |
62 |
# -> selectedInputPartition - the partition to scan for images |
63 |
# -> selectedInputPartitionNumber - Index of selectedInputPartition in inputPartition array |
64 |
# |
65 |
# -> diskCount - Number of disks on the system |
66 |
# -> inputDisk - Disks present on the system (array) |
67 |
# -> diskSize - Size of each disk (array) |
68 |
# |
69 |
# -> partitionCount - Number of partitions on the system |
70 |
# -> inputPartition - Partitions present on the system (array) |
71 |
# -> partitionSize - The size of each partition (array) |
72 |
# -> partitionType - The type of each partition (array) |
73 |
# -> CD - Not empty if partition is a CD (array) |
74 |
# |
75 |
allDisks=$(cat /proc/partitions | sed 's|.* ||' | grep -ve '[0-9]$'| grep -v name |grep -ve '^$') |
76 |
|
77 |
[ -z "$allDisks" ] && { |
78 |
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 |
79 |
cleanUP |
80 |
exit 1 |
81 |
} |
82 |
|
83 |
|
84 |
local cmdLine='' |
85 |
diskCount=$(echo "$allDisks" | wc -l) |
86 |
|
87 |
local fDisks='' |
88 |
|
89 |
local count=1 |
90 |
while [ $count -le $diskCount ];do |
91 |
inputDisk[$count]=$(echo "$allDisks" | sed -n ""$count"p") |
92 |
fdisk -l /dev/"${inputDisk[$count]}" 2>/dev/null > /root/clsys-raw-fdisk-"$count".$$ |
93 |
# parted /dev/"${inputDisk[$count]}" print > /root/clsys-raw-parted-"$count".$$ |
94 |
diskSize[$count]=$(sed -n '1p' /root/clsys-raw-fdisk-"$count".$$ | sed 's|.*, ||' | sed 's| bytes||' | sed 's| ||g') |
95 |
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".$$ |
96 |
((count++)) |
97 |
done |
98 |
# echo 33 |
99 |
|
100 |
allPartitions=$(cat /root/clsys-part-*$$ | sed 's| .*||' | sed 's|/dev/||') |
101 |
# allSizes=$(grep -e '^ [0-9]' /root/clsys-raw-parted-*.$$ | awk '{print $4}') |
102 |
partitionCount=$(echo "$allPartitions" | wc -l) |
103 |
|
104 |
local cmdLine='' |
105 |
count=1 |
106 |
while [ $count -le $partitionCount ];do |
107 |
inputPartition[$count]=$(echo "$allPartitions" | sed -n ""$count"p") |
108 |
getPartitionSizeFromFdisk "${inputPartition[$count]}" |
109 |
partitionSize[$count]=$( echo "$THIS_PARTITION_SIZE" | sed 's|,|.|') |
110 |
partitionType[$count]=$(grep "${inputPartition[$count]}" /root/clsys-raw-fdisk-*.$$| sed 's|*||' | awk '{printf "%s %s %s %s",$6,$7,$8,$9}' |sed 's| *$||') |
111 |
cmdLine="$cmdLine""${inputPartition[$count]}"" ""\"Size: ${partitionSize[$count]}, Type: ${partitionType[$count]}\""" " |
112 |
|
113 |
((count++)) |
114 |
done |
115 |
|
116 |
# cleanUP |
117 |
# exit |
118 |
|
119 |
# integrate CD-ROMs |
120 |
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}') |
121 |
local cdCount=$(echo "$theCDs" | wc -l) |
122 |
|
123 |
count=1 |
124 |
while [ $count -le $cdCount ];do |
125 |
((partitionCount++)) |
126 |
inputPartition[$partitionCount]=$(echo "$theCDs" | sed -n ""$count"p") |
127 |
CD[$partitionCount]=$count |
128 |
cmdLine="$cmdLine""${inputPartition[$partitionCount]}"" ""\"Type: CD-ROM\""" " |
129 |
((count++)) |
130 |
done |
131 |
|
132 |
# integrate samba shares (cifs) |
133 |
local smbShares=$(mount | sort | grep -e '[ ]cifs[ ]'| sed 's|on ||' |sed 's|type ||' | awk '$3 == "cifs" {print $2}') |
134 |
#### DEBUG #### |
135 |
[ -z "$DEBUG" ] || smbShares='/data' |
136 |
#### END DEBUG #### |
137 |
|
138 |
[ -z "$smbShares" ] || { |
139 |
local smbCount=$(echo "$smbShares" | wc -l) |
140 |
count=1 |
141 |
while [ $count -le $smbCount ];do |
142 |
((partitionCount++)) |
143 |
inputPartition[$partitionCount]=$(echo "$smbShares" | sed -n ""$count"p") |
144 |
SMB[$count]=$partitionCount |
145 |
cmdLine="$cmdLine"smb"$count"" ""\"Type: Samba Share, $(echo "${inputPartition[$partitionCount]}"|sed 's|.*/||')\""" " |
146 |
((count++)) |
147 |
done |
148 |
} |
149 |
|
150 |
|
151 |
local nfsShares=$(mount | sort | grep -e '[ ]nfs[ ]'| sed 's|on ||' |sed 's|type ||' | awk '$3 == "nfs" {print $2}') |
152 |
#### DEBUG #### |
153 |
[ -z "$DEBUG" ] || nfsShares='/data' |
154 |
#### END DEBUG #### |
155 |
[ -z "$nfsShares" ] || { |
156 |
local nfsCount=$(echo "$nfsShares" | wc -l) |
157 |
count=1 |
158 |
while [ $count -le $nfsCount ];do |
159 |
((partitionCount++)) |
160 |
inputPartition[$partitionCount]=$(echo "$nfsShares" | sed -n ""$count"p") |
161 |
NFS[$count]=$partitionCount |
162 |
cmdLine="$cmdLine"nfs"$count"" ""\"Type: NFS Share, $(echo "${inputPartition[$partitionCount]}"|sed 's|.*/||')\""" " |
163 |
((count++)) |
164 |
done |
165 |
} |
166 |
# echo 66 |
167 |
selectedInputPartition='' |
168 |
|
169 |
echo "dialog --backtitle \"$backTitle\" --title \" Source Partition \" --menu 'Please select the location of your image file' $((partitionCount+7)) 78 $partitionCount $cmdLine" > /root/dialog.$$ |
170 |
|
171 |
. /root/dialog.$$ 2>/root/selectedPartition.$$ |
172 |
|
173 |
selectedInputPartition=$(cat /root/selectedPartition.$$) |
174 |
|
175 |
# set -x |
176 |
# cleanUP |
177 |
# exit |
178 |
|
179 |
|
180 |
[ -z "$selectedInputPartition" ] && { |
181 |
cleanUP |
182 |
exit |
183 |
} |
184 |
|
185 |
if [ ! -z $(echo "$selectedInputPartition"|grep -e '^smb[0-9][0-9]*$') ];then |
186 |
local num=$(echo "$selectedInputPartition"|sed 's|smb||') |
187 |
selectedInputPartitionNumber=${SMB[$num]} |
188 |
workingRemote='y' |
189 |
elif [ ! -z $(echo "$selectedInputPartition"|grep -e '^smb[0-9][0-9]*$') ];then |
190 |
local num=$(echo "$selectedInputPartition"|sed 's|nfs||') |
191 |
selectedInputPartitionNumber=${NFS[$num]} |
192 |
workingRemote='y' |
193 |
else |
194 |
count=1 |
195 |
while [ "${inputPartition[$count]}" != "$selectedInputPartition" ];do |
196 |
((count++)) |
197 |
done |
198 |
selectedInputPartitionNumber=$count |
199 |
fi |
200 |
# echo 100 |
201 |
# echo EOF |
202 |
# read |
203 |
# cleanUP |
204 |
# exit |
205 |
|
206 |
} |
207 |
|
208 |
function findSambaShare(){ |
209 |
# used only when -i smb |
210 |
echo 'Looking for Samba Shares (this may take some time)... ' |
211 |
partitionCount=0 |
212 |
local smbShares=$(mount | sort | awk '/cifs/ { |
213 |
for(x=1; x<=NF; ++x){ |
214 |
s=substr($x,1,2) |
215 |
if(s!="//"){ |
216 |
s=substr($x,1,1) |
217 |
if(s=="/") mountpoint=$x |
218 |
}if($x=="cifs"){ |
219 |
if(mountpoint!="") print mountpoint |
220 |
}}}') |
221 |
#### DEBUG #### |
222 |
[ -z "$DEBUG" ] || smbShares='/data' |
223 |
#### END DEBUG #### |
224 |
[ -z "$smbShares" ] && { |
225 |
echo |
226 |
echo "No Samba Shares mounted" |
227 |
exit 1 |
228 |
} |
229 |
local smbCount=$(echo "$nfsShares" | wc -l) |
230 |
count=1 |
231 |
while [ $count -le $smbCount ];do |
232 |
((partitionCount++)) |
233 |
inputPartition[$partitionCount]=$(echo "$smbShares" | sed -n ""$count"p") |
234 |
SMB[$count]=$partitionCount |
235 |
((count++)) |
236 |
done |
237 |
local num=1 |
238 |
selectedInputPartitionNumber=${SMB[$num]} |
239 |
echo |
240 |
} |
241 |
|
242 |
function findNFSShare(){ |
243 |
# used only when -i nfs |
244 |
echo 'Looking for NFS Shares (this may take some time)... ' |
245 |
partitionCount=0 |
246 |
local nfsShares=$(mount | sort | awk '/nfs/ { |
247 |
for(x=1; x<=NF; ++x){ |
248 |
s=substr($x,1,2) |
249 |
if(s!="//"){ |
250 |
s=substr($x,1,1) |
251 |
if(s=="/") mountpoint=$x |
252 |
}if($x=="nfs"){ |
253 |
if(mountpoint!="") print mountpoint |
254 |
}}}') |
255 |
#### DEBUG #### |
256 |
[ -z "$DEBUG" ] || nfsShares='/data' |
257 |
#### END DEBUG #### |
258 |
[ -z "$nfsShares" ] && { |
259 |
echo |
260 |
echo "No NFS Shares mounted" |
261 |
exit 1 |
262 |
} |
263 |
|
264 |
local nfsCount=$(echo "$nfsShares" | wc -l) |
265 |
count=1 |
266 |
while [ $count -le $nfsCount ];do |
267 |
((partitionCount++)) |
268 |
inputPartition[$partitionCount]=$(echo "$nfsShares" | sed -n ""$count"p") |
269 |
NFS[$count]=$partitionCount |
270 |
((count++)) |
271 |
done |
272 |
local num=1 |
273 |
selectedInputPartitionNumber=${NFS[$num]} |
274 |
echo |
275 |
} |
276 |
|
277 |
|
278 |
function findImages(){ |
279 |
# <- folder to scan |
280 |
# |
281 |
# -> selectedInputImage - Number (index) in img array |
282 |
# -> selectedInputImageSize - Size of disk / partition |
283 |
# -> selectedInputImageID - Number - Partition ID (if user selected partition) |
284 |
# |
285 |
# -> imgCount - Number of images found |
286 |
# -> partCount - Number of partitions found |
287 |
# |
288 |
# -> img - image name |
289 |
# -> type - image type (partition/disk) |
290 |
# -> activeItem - name of partition/disk |
291 |
# -> imagePartitionSize - size of partition |
292 |
# -> diskSizeFromImage - disk size |
293 |
# -> partitionIdName - partition id in words |
294 |
# -> id - description |
295 |
|
296 |
if [ -z "$onlyImages" ];then |
297 |
dialog --backtitle "$backTitle" --title " Working " --infobox "Searching for image files" 3 29 |
298 |
fi |
299 |
imgCount=0 |
300 |
partCount=0 |
301 |
|
302 |
local count=1 |
303 |
local n |
304 |
local tmp |
305 |
local pCount |
306 |
local tmpImg |
307 |
local hasDisk=0 |
308 |
# set -x |
309 |
for n in $(find "$1" -name parts 2>/dev/null);do |
310 |
tmp="$(dirname "$n")" |
311 |
if [ -z "$onlyImages" ];then |
312 |
if [ "$(dirname "$tmp")" != "$1" ];then |
313 |
continue |
314 |
fi |
315 |
fi |
316 |
validateImage "$tmp" || continue |
317 |
img[$count]="$(basename "$tmp")" |
318 |
|
319 |
[ -r "$(dirname "$n")"/disk ] && { |
320 |
# it's a disk image |
321 |
hasDisk=1 |
322 |
type[$count]=disk |
323 |
tmp="$(dirname "$n")"/disk |
324 |
activeItem[$count]=$(cat "$tmp") |
325 |
partCount=$(cat "$(dirname "$n")"/parts | awk '{print NF}') |
326 |
tmp=$(dirname "$n") |
327 |
diskSizeFromImage[$count]=$(getDiskSizeFromImage "$tmp") |
328 |
id[$count]="Image: ${img[$count]}, ${type[$count]}: ${activeItem[$count]}"", size: ${diskSizeFromImage[$count]}, parts: $partCount" |
329 |
# scan parts |
330 |
pCount=1 |
331 |
tmpImg="${img[$count]}" |
332 |
while [ $pCount -le $partCount ];do |
333 |
((count++)) |
334 |
img[$count]="$tmpImg" |
335 |
type[$count]=part |
336 |
activeItem[$count]=$(cat "$n" | awk '{for(i=1;i<=NF;i++) print $i}' | sed -n ""$pCount"p") |
337 |
# set -x |
338 |
calcInputSize "$tmp" "${activeItem[$count]}" |
339 |
imagePartitionSize[$count]="$THIS_INPUT_SIZE" |
340 |
partitionIdName[$count]=$(getPartitionIdNameFromImage /"$tmp" "${activeItem[$count]}") |
341 |
((pCount++)) |
342 |
id[$count]=" ${type[$count]}: ${activeItem[$count]}, size: ${imagePartitionSize[$count]}, type: ${partitionIdName[$count]}" |
343 |
done |
344 |
} || { |
345 |
# it's a partition image |
346 |
type[$count]=part |
347 |
activeItem[$count]=$(cat "$n") |
348 |
partCount=1 |
349 |
calcInputSize /"$tmp" "${activeItem[$count]}" |
350 |
imagePartitionSize[$count]="$THIS_INPUT_SIZE" |
351 |
partitionIdName[$count]=$(getPartitionIdNameFromImage /"$tmp" "${activeItem[$count]}") |
352 |
id[$count]="Image: ${img[$count]}, ${type[$count]}: ${activeItem[$count]}, size: ${imagePartitionSize[$count]}, type: ${partitionIdName[$count]}" |
353 |
} |
354 |
imgCount="$count" |
355 |
((count++)) |
356 |
done |
357 |
# exit |
358 |
[ $imgCount -eq 0 ] &&{ |
359 |
local msgType |
360 |
[ -z "${CD[$selectedInputPartitionNumber]}" ] && msgType=Partition || msgType=CD-ROM |
361 |
if [ -n "$(echo "$selectedInputPartition" | grep '/')" ];then |
362 |
msgType=Folder |
363 |
selectedInputPartition=/"$selectedInputPartition" |
364 |
fi |
365 |
if [ -z "$onlyImages" ];then |
366 |
dialog --backtitle "$backTitle" --title " No images found!!! " --msgbox "$msgType"" $selectedInputPartition contains no valid image files |
367 |
|
368 |
Please try again selecting a different location" 7 60 |
369 |
else |
370 |
echo "Error: $msgType $selectedInputPartition contains no valid image files!!!" |
371 |
fi |
372 |
cleanUP |
373 |
exit 1 |
374 |
} |
375 |
if [ -z "$onlyImages" ];then |
376 |
|
377 |
local cmdLine='' |
378 |
|
379 |
count=1 |
380 |
while [ $count -le $imgCount ];do |
381 |
cmdLine="$cmdLine""$count"" \"""${id[$count]}""\" " |
382 |
((count++)) |
383 |
done |
384 |
|
385 |
selectedInputImage='' |
386 |
|
387 |
if [ $hasDisk -eq 1 ];then |
388 |
local tit=" Partition/Disk to Restore " |
389 |
local txt="Please select the partition/disk to restore" |
390 |
|
391 |
|
392 |
# local msg="At least one of the images found contains a full disk backup |
393 |
# |
394 |
# 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) |
395 |
# |
396 |
# 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 |
397 |
# |
398 |
# This way you will not have to resize the restored partitions on the target disk, after the entire restoration procedure has ended |
399 |
# |
400 |
# Do you want to continue?" |
401 |
# |
402 |
# dialog --backtitle "$backTitle" --title " Tips on disk restoration " --yesno "$msg" 20 72 |
403 |
# |
404 |
# if [ $? -eq 1 ];then |
405 |
# cleanUP |
406 |
# exit |
407 |
# fi |
408 |
|
409 |
else |
410 |
local tit=" Target Partition " |
411 |
local txt="Please select the partition to restore" |
412 |
fi |
413 |
|
414 |
echo "dialog --backtitle \"$backTitle\" --title \""$tit"\" --menu \""$txt"\" $((imgCount+7)) 78 $imgCount $cmdLine" > /root/dialog.$$ |
415 |
|
416 |
. /root/dialog.$$ 2>/root/selectedImage.$$ |
417 |
selectedInputImage=$(cat /root/selectedImage.$$) |
418 |
[ -z "$selectedInputImage" ] && { |
419 |
cleanUP |
420 |
exit |
421 |
} |
422 |
|
423 |
# set -x |
424 |
# calculate image size and partition ID (if required) |
425 |
if [ "${type[$selectedInputImage]}" = "part" ];then |
426 |
calcInputSize /"$selectedInputPartition"/"${img[$selectedInputImage]}" "${activeItem[$selectedInputImage]}" |
427 |
selectedInputImageSize="$THIS_INPUT_SIZE" |
428 |
calcInputID /"$selectedInputPartition"/"${img[$selectedInputImage]}" "${activeItem[$selectedInputImage]}" |
429 |
selectedInputImageID=$THIS_INPUT_ID |
430 |
else |
431 |
# calcInputSize /"$selectedInputPartition"/"${img[$selectedInputImage]}" |
432 |
selectedInputImageSize="${diskSizeFromImage[$selectedInputImage]}" |
433 |
fi |
434 |
# |
435 |
# |
436 |
# cleanUP |
437 |
# exit |
438 |
else |
439 |
echo "Image files found in: $selectedInputPartition" |
440 |
count=1 |
441 |
until [ -z "${id[$count]}" ];do |
442 |
echo " ${id[$count]}" |
443 |
((count++)) |
444 |
done |
445 |
fi |
446 |
} |
447 |
|
448 |
function getPartitionIdNameFromImage(){ |
449 |
local id=$(grep "$2" "$1"/*pt.sf | sed 's|.*Id= *||' | sed 's|,.*$||') |
450 |
sfdisk -T |sed 's|^[ ]||' | grep -e "^$id[ \t]" | sed "s|^$id *||" |
451 |
} |
452 |
|
453 |
function getDiskSizeFromImage(){ |
454 |
local lin=$(awk 'BEGIN{FS="=" |
455 |
count=0} |
456 |
{if (count==0) b=$2 |
457 |
else{ |
458 |
b=b" * " |
459 |
b=b$2 |
460 |
} |
461 |
count++} |
462 |
END{print b}' "$1"/*chs.sf | bc) |
463 |
local size=$(echo "$lin * 512" | bc) |
464 |
toMGByte "$size" |
465 |
} |
466 |
|
467 |
function getDiskSizeFromDisk(){ |
468 |
local size=$(fdisk -l /dev/"$1" | grep -e '^Disk /dev/' | sed 's|.*, *||' | sed 's| *bytes||') |
469 |
toMGByte "$size" |
470 |
} |
471 |
|
472 |
function toMGByte(){ |
473 |
if [ $(expr length "$1") -le 9 ];then |
474 |
echo $(expr substr "$1" 1 3 )"MB" |
475 |
elif [ $(expr length "$1") -eq 10 ];then |
476 |
echo $(expr substr "$1" 1 2 | sed 's|\([0-9]\)$|.\1|')"GB" |
477 |
elif [ $(expr length "$1") -lt 12 ];then |
478 |
echo $(expr substr "$1" 1 3 | sed 's|\([0-9]\)$|.\1|')"GB" |
479 |
else |
480 |
echo $(expr substr "$1" 1 4 | sed 's|\([0-9]\)$|.\1|')"GB" |
481 |
fi |
482 |
} |
483 |
|
484 |
function validateImage(){ |
485 |
[ -d "$1"/parts ] && return 1 |
486 |
local sf=$(find "$1" -name "*-chs.sf" 2>/dev/null | wc -l) |
487 |
[ $sf -eq 0 ] && return 1 |
488 |
local pt=$(find "$1" -name "*-pt.sf" 2>/dev/null | wc -l) |
489 |
[ $pt -eq 0 ] && return 1 |
490 |
# modification to read unsplited images |
491 |
# thanks to Viking (24/11/2008) |
492 |
# local aa=$(find "$1" -name "*.aa" 2>/dev/null | wc -l) |
493 |
# [ $aa -eq 0 ] && return 1 |
494 |
return 0 |
495 |
} |
496 |
|
497 |
function cleanUP(){ |
498 |
if [ ! -z "$selectedInputPartition" ];then |
499 |
[ -z "$workingRemote" ] && umount /"$selectedInputPartition" 2>/dev/null |
500 |
fi |
501 |
cd |
502 |
rm /root/*.$$ 2>/dev/null |
503 |
rm -rf /home/partimag/reloc-image |
504 |
umount /home/partimag 2>/dev/null |
505 |
# umount -a 2>/dev/null |
506 |
[ -z "$onlyImages" ] && clear |
507 |
} |
508 |
|
509 |
function calcInputID(){ |
510 |
THIS_INPUT_ID=$(sed -n "/$2/p" "$1"/*-pt.sf | sed 's|.*Id= *||' | sed 's|,.*$||') |
511 |
} |
512 |
|
513 |
function calcInputSize(){ |
514 |
local bytesPerSector=512 |
515 |
local l |
516 |
local pSize |
517 |
local cylinders |
518 |
local heads |
519 |
local sectors |
520 |
if [ -z "$2" ];then |
521 |
cylinders=$(sed -n '/cylinders=/p' "$1"/*-chs.sf | sed 's|cylinders=||') |
522 |
heads=$(sed -n '/heads=/p' "$1"/*-chs.sf | sed 's|heads=||') |
523 |
sectors=$(sed -n '/sectors=/p' "$1"/*-chs.sf | sed 's|sectors=||') |
524 |
THIS_INPUT_SIZE=$(echo "scale=2; $cylinders * $heads * $sectors * $bytesPerSector" | bc) |
525 |
else |
526 |
pSize=$(sed -n "/$2/p" "$1"/*-pt.sf | sed 's|.*size= *||' | sed 's|,.*||') |
527 |
THIS_INPUT_SIZE=$(echo "scale=2; $pSize * $bytesPerSector" | bc) |
528 |
fi |
529 |
|
530 |
l=$(expr length $THIS_INPUT_SIZE) |
531 |
if [ $l -gt 9 ];then |
532 |
THIS_INPUT_SIZE=$(echo "scale=2; $THIS_INPUT_SIZE / 1024 / 1024 / 1024" | bc)GB |
533 |
else |
534 |
THIS_INPUT_SIZE=$(echo "scale=3; $THIS_INPUT_SIZE / 1024 / 1024" | bc | sed 's|\.000|.00|')MB |
535 |
fi |
536 |
} |
537 |
|
538 |
function getPartitionSizeFromFdisk(){ |
539 |
local disk=$(echo "$1" | sed 's|[0-9]||') |
540 |
if [ ! -e /root/closys-fdisk-"$disk".$$ ];then |
541 |
fdisk -l /dev/"$disk" > /root/closys-fdisk-"$disk".$$ |
542 |
fi |
543 |
local size=$(sed 's|*||' /root/closys-fdisk-"$disk".$$ | grep "$1" | awk '{print $4}' | sed 's|[+-]||') |
544 |
local gB=$(echo "scale=2; $size / 1024 / 1024 " | bc | sed 's|^\.|0.|')GB |
545 |
local mB=$(echo "scale=2; $size / 1024 " | bc)MB |
546 |
if [ -z $(echo "$gB" | grep -e '^[0]') ];then |
547 |
THIS_PARTITION_SIZE="$gB" |
548 |
else |
549 |
THIS_PARTITION_SIZE="$mB" |
550 |
fi |
551 |
} |
552 |
|
553 |
function getOutputPartition(){ |
554 |
## select target partition |
555 |
dialog --backtitle "$backTitle" --title " Working " --infobox "Searching for valid partitions" 3 34 |
556 |
local count=1 |
557 |
local cmdLine='' |
558 |
local outputPartitionCount=0 |
559 |
local tmpDisk |
560 |
local tmpID |
561 |
local fatpartitions='' |
562 |
local compResult |
563 |
until [ -z "${inputPartition[$count]}" ];do |
564 |
if [ "${inputPartition[$count]}" != "$selectedInputPartition" ] && [ -z "${CD[$count]}" ];then |
565 |
tmpDisk=$(echo "${inputPartition[$count]}" | sed 's|[0-9]||') |
566 |
tmpID=$(fdisk -l /dev/"$tmpDisk" 2>/dev/null| grep "${inputPartition[$count]}" | sed 's|*||' | awk '{print $5}') |
567 |
if [ "$tmpID" = "$selectedInputImageID" ];then |
568 |
comparePartitionsSize "$selectedInputImageSize" "${partitionSize[$count]}" |
569 |
compResult=$? |
570 |
if [ $compResult -eq 0 ];then |
571 |
cmdLine="$cmdLine""${inputPartition[$count]}"" ""\"Size: ${partitionSize[$count]}, Type: ${partitionType[$count]} (identical part)\""" " |
572 |
((outputPartitionCount++)) |
573 |
elif [ $compResult -eq 2 ];then |
574 |
cmdLine="$cmdLine""${inputPartition[$count]}"" ""\"Size: ${partitionSize[$count]}, Type: ${partitionType[$count]}\""" " |
575 |
((outputPartitionCount++)) |
576 |
needsResize[$count]='-r' |
577 |
# echo "count = $count" |
578 |
fi |
579 |
fi |
580 |
if [ "$tmpID" = "b" ] && [ "$selectedInputImageID" = "6" ];then |
581 |
comparePartitionsSize "$selectedInputImageSize" "${partitionSize[$count]}" |
582 |
compResult=$? |
583 |
if [ $compResult -eq 0 ];then |
584 |
cmdLine="$cmdLine""${inputPartition[$count]}"" ""\"Size: ${partitionSize[$count]}, Type: ${partitionType[$count]} (identical part)\""" " |
585 |
((outputPartitionCount++)) |
586 |
elif [ $compResult -eq 2 ];then |
587 |
cmdLine="$cmdLine""${inputPartition[$count]}"" ""\"Size: ${partitionSize[$count]}, Type: ${partitionType[$count]}\""" " |
588 |
((outputPartitionCount++)) |
589 |
needsResize[$count]='-r' |
590 |
# echo "count = $count" |
591 |
fi |
592 |
fi |
593 |
if [ "$tmpID" = "c" ] && [ "$selectedInputImageID" = "6" ];then |
594 |
comparePartitionsSize "$selectedInputImageSize" "${partitionSize[$count]}" |
595 |
compResult=$? |
596 |
if [ $compResult -eq 0 ];then |
597 |
cmdLine="$cmdLine""${inputPartition[$count]}"" ""\"Size: ${partitionSize[$count]}, Type: ${partitionType[$count]} (identical part)\""" " |
598 |
((outputPartitionCount++)) |
599 |
elif [ $compResult -eq 2 ];then |
600 |
cmdLine="$cmdLine""${inputPartition[$count]}"" ""\"Size: ${partitionSize[$count]}, Type: ${partitionType[$count]}\""" " |
601 |
((outputPartitionCount++)) |
602 |
needsResize[$count]='-r' |
603 |
# echo "count = $count" |
604 |
fi |
605 |
fi |
606 |
fi |
607 |
((count++)) |
608 |
done |
609 |
|
610 |
if [ $outputPartitionCount -eq 0 ];then |
611 |
dialog --backtitle "$backTitle" --title " No available partitions!!! " --msgbox "The program found no valid partitions for restoration!!! |
612 |
|
613 |
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 |
614 |
|
615 |
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 |
616 |
cleanUP |
617 |
exit |
618 |
fi |
619 |
|
620 |
# cleanUP |
621 |
# exit |
622 |
tmpPartName=$(sfdisk -T | sed 's|^[ \t]||' | grep -e "^"$selectedInputImageID" " | sed "s|^"$selectedInputImageID"[ /t]*||" | sed 's|,.*$||') |
623 |
if [ $outputPartitionCount -gt 0 ];then |
624 |
|
625 |
# chech partitions size |
626 |
local thisHeight=$outputPartitionCount |
627 |
local totHeigh=$((outputPartitionCount+8)) |
628 |
if [ $totHeigh -gt 20 ];then |
629 |
totHeigh=20 |
630 |
thisHeight=$(totHeigh-8) |
631 |
fi |
632 |
echo "dialog --backtitle \"$backTitle\" --title \" Target Partition \" --menu \"Please select the partition where your image file will be restored |
633 |
Original image type: $tmpPartName, size: $selectedInputImageSize\" $totHeigh 78 $thisHeight $cmdLine" > /root/dialog.$$ |
634 |
|
635 |
. /root/dialog.$$ 2>/root/outputPartition.$$ |
636 |
selectedOutputPartition=$(cat /root/outputPartition.$$) |
637 |
[ -z "$selectedOutputPartition" ] && { |
638 |
cleanUP |
639 |
exit |
640 |
} |
641 |
else |
642 |
dialog --backtitle "$backTitle" --title " No available partitions!!! " --msgbox "The program found no valid partitions for restoration!!! |
643 |
|
644 |
The selected (backed up) partition type is $tmpPartName (ID = $selectedInputImageID), but none of the partitions found on your disks are of this type |
645 |
|
646 |
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 |
647 |
cleanUP |
648 |
exit 1 |
649 |
fi |
650 |
# set -x |
651 |
count=1 |
652 |
until [ -z "${inputPartition[$count]}" ];do |
653 |
if [ "${inputPartition[$count]}" = "$selectedOutputPartition" ];then |
654 |
selectedOutputPartitionIndex=$count |
655 |
break |
656 |
fi |
657 |
((count++)) |
658 |
done |
659 |
set +x |
660 |
|
661 |
} |
662 |
|
663 |
function comparePartitionsSize(){ |
664 |
# |
665 |
# partition size format: xxxx.x[kMG]B |
666 |
# |
667 |
# <- $1 $2 - the sizes |
668 |
# |
669 |
# -> 0 - equal |
670 |
# -> 1 - $1 > $2 |
671 |
# -> 2 - $2 > $1 |
672 |
# set -x |
673 |
if [ "$1" = "$2" ];then return 0;fi |
674 |
local count=1 |
675 |
while [ $count -le 2 ];do |
676 |
local size[$count]=$(echo "$1" | sed 's|[kMG]B||') |
677 |
# echo "size[$count] = ${size[$count]}" |
678 |
local factor[$count]=$(echo "$1" | sed 's|.*\([kMG]\)B|\1|') |
679 |
# echo "factor[$count] = ${factor[$count]}" |
680 |
getMultiplier ${factor[$count]} |
681 |
local multiplier[$count]=$THIS_MULTIPLIER |
682 |
# echo "multiplier[$count] = ${multiplier[$count]}" |
683 |
shift |
684 |
((count++)) |
685 |
done |
686 |
return $(echo "a=${size[1]} * ${multiplier[1]}; |
687 |
b=${size[2]} * ${multiplier[2]}; |
688 |
if (a==b) print 0 |
689 |
if (a>b) print 1 |
690 |
if (a<b) print 2" | bc) |
691 |
} |
692 |
|
693 |
function getMultiplier(){ |
694 |
# echo $# |
695 |
case "$1" in |
696 |
k) THIS_MULTIPLIER=1024;; |
697 |
M) THIS_MULTIPLIER=1048576;; |
698 |
G) THIS_MULTIPLIER=1073741824;; |
699 |
esac |
700 |
} |
701 |
|
702 |
function getRestoreParameters(){ |
703 |
# used only in disk restore, when disks not equal |
704 |
# # Get restore parameters |
705 |
dialog --separate-output --backtitle "$backTitle" --title " Restore options " --checklist "Please select your restore options" 10 78 3 "-k" "Keep target disk partition table (do not re-partition)" on "-r" "Resize partitions on target disk to maximum size" on "-t" "Do not write the MBR to the target disk" off 2>/root/params.$$ |
706 |
if [ $? -ne 0 ];then |
707 |
cleanUP |
708 |
exit |
709 |
fi |
710 |
count=1 |
711 |
while [ $count -le 3 ];do |
712 |
param[$count]=$(sed -n ""$count"p" /root/params.$$ | sed 's/[ ]*//' ) |
713 |
((count++)) |
714 |
done |
715 |
} |
716 |
|
717 |
function preparePartitionImage(){ |
718 |
dialog --backtitle "$backTitle" --title " Working " --infobox "Preparing temporary image file" 3 34 |
719 |
if [ -d /home/partimag ];then |
720 |
umount /home/partimag 2>/dev/null |
721 |
rm -rf /home/partimag/* 2>/dev/null |
722 |
else |
723 |
rm -rf /home/partimag 2>/dev/null |
724 |
mkdir /home/partimag |
725 |
fi |
726 |
rm -rf /home/partimag/reloc-image 2>/dev/null |
727 |
mkdir /home/partimag/reloc-image |
728 |
# echo /"$selectedInputPartition"/"${img[$selectedInputImage]}" |
729 |
local inTmpDisk=$(echo "${activeItem[$selectedInputImage]}" | sed 's|[0-9]||') |
730 |
local outTmpDisk=$(echo "$selectedOutputPartition" | sed 's|[0-9]||') |
731 |
local outTmpPartition=$(echo "$selectedOutputPartition" | sed 's|[a-z]*||') |
732 |
local tmpFile |
733 |
local outFile |
734 |
local count |
735 |
#set -x |
736 |
for n in $(find /"$selectedInputPartition"/"${img[$selectedInputImage]}" -name "*");do |
737 |
tmpFile=$(basename "$n") |
738 |
if [ "$tmpFile" != "${img[$selectedInputImage]}" ];then |
739 |
# echo "$tmpFile" |
740 |
outFile=$(echo "$tmpFile" | sed "s|${activeItem[$selectedInputImage]}|$selectedOutputPartition|" |sed "s|$inTmpDisk|$outTmpDisk|") |
741 |
# echo "${activeItem[$selectedInputImage]} => $selectedOutputPartition" |
742 |
# echo ln -s "$n" /home/partimag/reloc-image/"$outFile" |
743 |
ln -s "$n" /home/partimag/reloc-image/"$outFile" |
744 |
fi |
745 |
done |
746 |
if [ "${activeItem[$selectedInputImage]}" != "$selectedOutputPartition" ];then |
747 |
[ -e /home/partimag/reloc-image/disk ] && { |
748 |
rm /home/partimag/reloc-image/disk |
749 |
echo "$outTmpDisk" > /home/partimag/reloc-image/disk |
750 |
} |
751 |
sed "s|${activeItem[$selectedInputImage]}|$selectedOutputPartition|" /home/partimag/reloc-image/parts | sed "s|$inTmpDisk|$outTmpDisk|" > /home/partimag/reloc-image/parts.tmp |
752 |
rm /home/partimag/reloc-image/parts |
753 |
mv /home/partimag/reloc-image/parts.tmp /home/partimag/reloc-image/parts |
754 |
rm /home/partimag/reloc-image/"$outTmpDisk"-pt.sf |
755 |
echo "# partition table of /dev/"$outTmpDisk"" > /home/partimag/reloc-image/"$outTmpDisk"-pt.sf |
756 |
echo "unit: sectors" >> /home/partimag/reloc-image/"$outTmpDisk"-pt.sf |
757 |
echo >> /home/partimag/reloc-image/"$outTmpDisk"-pt.sf |
758 |
count=1 |
759 |
while [ $count -lt $outTmpPartition ];do |
760 |
echo "/dev/"$outTmpDisk""$count" : start= 0, size= 0, Id= 0" >> /home/partimag/reloc-image/"$outTmpDisk"-pt.sf.tmp |
761 |
((count++)) |
762 |
done |
763 |
grep "${activeItem[$selectedInputImage]}" /home/partimag/reloc-image/"$outTmpDisk"-pt.sf | sed "s|${activeItem[$selectedInputImage]}|$selectedOutputPartition|" >> /home/partimag/reloc-image/"$outTmpDisk"-pt.sf.tmp |
764 |
rm /home/partimag/reloc-image/"$outTmpDisk"-pt.sf |
765 |
mv /home/partimag/reloc-image/"$outTmpDisk"-pt.sf.tmp /home/partimag/reloc-image/"$outTmpDisk"-pt.sf |
766 |
fi |
767 |
} |
768 |
|
769 |
function doPartitionRestore(){ |
770 |
# set -x |
771 |
if [ -z "${needsResize[$selectedOutputPartitionIndex]}" ];then |
772 |
msg="The temporary image file is now ready, and you are about to start the Restore operation |
773 |
|
774 |
Are you sure you want to restore |
775 |
the backup of partition ${activeItem[$selectedInputImage]} |
776 |
to |
777 |
partition $selectedOutputPartition?" |
778 |
else |
779 |
msg="The temporary image file is now ready, and you are about to start the Restore operation |
780 |
|
781 |
Are you sure you want to restore and resize |
782 |
the backup of partition ${activeItem[$selectedInputImage]} |
783 |
to |
784 |
partition $selectedOutputPartition?" |
785 |
fi |
786 |
dialog --backtitle "$backTitle" --title "Ready to Restore" --yesno "$msg" 11 70 |
787 |
|
788 |
if [ $? -eq 0 ];then |
789 |
# Do restore |
790 |
COMMAND="ocs-sr -p true -k -t "${needsResize[$selectedOutputPartitionIndex]}" -b restoreparts reloc-image $selectedOutputPartition" |
791 |
fi |
792 |
} |
793 |
|
794 |
function getOutputDisk(){ |
795 |
# |
796 |
# -> diskGeometry - system disk geometry (array) |
797 |
# item empty if disk smaller than image |
798 |
# or not same number of partitions |
799 |
# or partitions not same type |
800 |
# -> equalDisk - denotes an equal disk geometry (array) |
801 |
# item ont empty if disk is equal to image disk |
802 |
# -> diskToRestoreCount - Number of available disks to restore |
803 |
local cmdLine |
804 |
diskToRestoreCount=0 |
805 |
getDiskGeometry |
806 |
selectedImageDiskGeometry=$THIS_GEOMETRY |
807 |
|
808 |
local count=1 |
809 |
local mountedDisk=$(echo "$selectedInputPartition" | sed 's|[0-9]||') |
810 |
# set -x |
811 |
while [ $count -le $diskCount ];do |
812 |
if [ "${inputDisk[$count]}" != "$mountedDisk" ];then |
813 |
getDiskGeometry /dev/"${inputDisk[$count]}" |
814 |
if [ "$THIS_GEOMETRY" = "$selectedImageDiskGeometry" ];then |
815 |
# we have two identical disks |
816 |
diskGeometry[$count]="$THIS_GEOMETRY" |
817 |
equalDisk[$count]=1 |
818 |
((diskToRestoreCount++)) |
819 |
cmdLine="$cmdLine""\"""${inputDisk[$count]}""\""" ""\"""Size: $(getDiskSizeFromDisk ${inputDisk[$count]}) (identical disk)""\" " |
820 |
else |
821 |
# disks are different |
822 |
local selGeo=$(echo "$selectedImageDiskGeometry" |sed 's|,|*|g') |
823 |
local thisGeo=$(echo "$THIS_GEOMETRY" |sed 's|,|*|g') |
824 |
local compResult=$(echo "a=$selGeo; |
825 |
b=$thisGeo; |
826 |
if (a==b) print 0 |
827 |
if (a>b) print 1 |
828 |
if (a<b) print 2" | bc) |
829 |
if [ $compResult -eq 2 ];then |
830 |
# disk is large enough |
831 |
# do we have same number of partitions and same type? |
832 |
compResult=$(checkDisksPartitions) |
833 |
if [ $compResult -eq 0 ];then |
834 |
diskGeometry[$count]="$THIS_GEOMETRY" |
835 |
((diskToRestoreCount++)) |
836 |
cmdLine="$cmdLine""\"""${inputDisk[$count]}""\""" ""\"""Size: $(getDiskSizeFromDisk ${inputDisk[$count]})""\" " |
837 |
fi |
838 |
fi |
839 |
fi |
840 |
|
841 |
fi |
842 |
((count++)) |
843 |
done |
844 |
if [ $diskToRestoreCount -eq 0 ];then |
845 |
dialog --backtitle "$backTitle" --title " No disks found!!! " --msgbox "Your system has no valid disks to restore this image file!!! |
846 |
|
847 |
In order to perform a disk restoration, you must have: |
848 |
|
849 |
a. A disk with the same geometry as the source disk |
850 |
In this case you will perform a full disk restore, creating |
851 |
partitions and restoring the MBR, or |
852 |
|
853 |
b. A prepartitioned larger disk which contains exactly the same |
854 |
partitions as the source disk (same partition number and id) |
855 |
In this case no partition creation will take place, but the |
856 |
target partitions will be resized to maximum size" 16 70 |
857 |
cleanUP |
858 |
exit |
859 |
fi |
860 |
|
861 |
# make dialog |
862 |
echo "dialog --backtitle \"$backTitle\" --title \" Target Disk \" --menu \"Please select the disk where your image file will be restored |
863 |
Original image: ${img[$selectedInputImage]}, disk: ${activeItem[$selectedInputImage]}, size: $selectedInputImageSize\" $((diskToRestoreCount+8)) 78 $diskToRestoreCount $cmdLine" > /root/dialog.$$ |
864 |
|
865 |
. /root/dialog.$$ 2>/root/selectedDisk.$$ |
866 |
selectedOutputDisk=$(cat /root/selectedDisk.$$) |
867 |
|
868 |
[ -z "$selectedOutputDisk" ] && { |
869 |
cleanUP |
870 |
exit |
871 |
} |
872 |
|
873 |
|
874 |
} |
875 |
|
876 |
function getDiskGeometry(){ |
877 |
if [ -z "$1" ];then |
878 |
# get image disk geometry |
879 |
THIS_GEOMETRY=$(awk 'BEGIN{FS="=" |
880 |
count=0} |
881 |
{if (count==0) b=$2 |
882 |
else{ |
883 |
b=b"," |
884 |
b=b$2 |
885 |
} |
886 |
count++} |
887 |
END{print b}' /"$selectedInputPartition"/"${img[$selectedInputImage]}"/*-chs.sf) |
888 |
else |
889 |
# get disk geometry |
890 |
THIS_GEOMETRY=$(sfdisk -g "$1" | sed 's|^.*:||' | sed 's|cylinders||' | sed 's|heads||' | sed 's|sectors/track||' | sed 's| *||g') |
891 |
fi |
892 |
|
893 |
} |
894 |
|
895 |
function checkDisksPartitions(){ |
896 |
local imgData=$(grep -e '^/dev/' /"$selectedInputPartition"/"${img[$selectedInputImage]}"/*-pt.sf | sed 's| : .*Id= *|:|') |
897 |
|
898 |
local diskData=$(sfdisk -l /dev/${inputDisk[$count]} 2>/dev/null| grep -e '^/dev/' | awk '{ |
899 |
if ($2=="*") |
900 |
print $1 ":" $7 ", bootable" |
901 |
else |
902 |
print $1 ":" $6}' | sed "s|${inputDisk[$count]}|${activeItem[$selectedInputImage]}|") |
903 |
|
904 |
if [ "$imgData" != "$diskData" ];then |
905 |
echo 1 |
906 |
return |
907 |
fi |
908 |
|
909 |
# check partitions size |
910 |
local numOfPartitions=$(grep 'size=' /"$selectedInputPartition"/"${img[$selectedInputImage]}"/*-pt.sf | wc -l) |
911 |
local imgPartitionSize |
912 |
local diskPartitionSize |
913 |
local partCount=1 |
914 |
|
915 |
sfdisk -d /dev/${inputDisk[$count]} > /root/disk-${inputDisk[$count]}.$$ |
916 |
while [ $partCount -le $numOfPartitions ];do |
917 |
imgPartitionSize=$(grep 'size=' /"$selectedInputPartition"/"${img[$selectedInputImage]}"/*-pt.sf | sed -n ""$partCount"p"| sed 's|.*size= *||' | sed 's|,.*$||' | sed 's|[+-]||') |
918 |
diskPartitionSize=$(grep 'size=' /root/disk-${inputDisk[$count]}.$$ | sed -n ""$partCount"p"| sed 's|.*size= *||' | sed 's|,.*$||' | sed 's|[+-]||') |
919 |
local compResult=$(echo "a=$imgPartitionSize; |
920 |
b=$diskPartitionSize; |
921 |
if (a==b) print 0 |
922 |
if (a>b) print 1 |
923 |
if (a<b) print 2" | bc) |
924 |
if [ $compResult -eq 2 ];then |
925 |
echo 1 |
926 |
return |
927 |
fi |
928 |
((partCount++)) |
929 |
done |
930 |
echo 0 |
931 |
} |
932 |
|
933 |
|
934 |
|
935 |
function prepareDiskImage(){ |
936 |
dialog --backtitle "$backTitle" --title " Working " --infobox "Preparing temporary image file" 3 34 |
937 |
if [ -d /home/partimag ];then |
938 |
umount /home/partimag 2>/dev/null |
939 |
rm -rf /home/partimag/* 2>/dev/null |
940 |
else |
941 |
rm -rf /home/partimag 2>/dev/null |
942 |
mkdir /home/partimag |
943 |
fi |
944 |
rm -rf /home/partimag/reloc-image 2>/dev/null |
945 |
mkdir /home/partimag/reloc-image |
946 |
|
947 |
# count is not local, will be used in doDiskRestore |
948 |
count=1 |
949 |
until [ -z "${inputDisk[$count]}" ];do |
950 |
# if [ "${activeItem[$count]}" = "$selectedOutputDisk" ];then |
951 |
if [ "${inputDisk[$count]}" = "$selectedOutputDisk" ];then |
952 |
break |
953 |
fi |
954 |
((count++)) |
955 |
done |
956 |
|
957 |
local tmpFile |
958 |
for n in $(find /"$selectedInputPartition"/"${img[$selectedInputImage]}" -name "*");do |
959 |
tmpFile=$(basename "$n") |
960 |
if [ "$tmpFile" != "${img[$selectedInputImage]}" ];then |
961 |
outFile=$(echo "$tmpFile" |sed "s|${activeItem[$selectedInputImage]}|$selectedOutputDisk|") |
962 |
ln -s "$n" /home/partimag/reloc-image/"$outFile" |
963 |
fi |
964 |
done |
965 |
|
966 |
if [ "${activeItem[$selectedInputImage]}" != "$selectedOutputDisk" ];then |
967 |
rm /home/partimag/reloc-image/disk |
968 |
echo "$selectedOutputDisk" > /home/partimag/reloc-image/disk |
969 |
rm /home/partimag/reloc-image/parts |
970 |
echo "$(cat /"$selectedInputPartition"/"${img[$selectedInputImage]}"/parts | sed "s|${activeItem[$selectedInputImage]}|$selectedOutputDisk|")" > /home/partimag/reloc-image/parts |
971 |
rm /home/partimag/reloc-image/"$selectedOutputDisk"-pt.sf |
972 |
sfdisk -d /dev/"$selectedOutputDisk" > /home/partimag/reloc-image/"$selectedOutputDisk"-pt.sf |
973 |
if [ -z "${equalDisk[$count]}" ];then |
974 |
rm /home/partimag/reloc-image/"$selectedOutputDisk"-chs.sf |
975 |
sfdisk -d /dev/"$selectedOutputDisk" > /home/partimag/reloc-image/"$selectedOutputDisk"-chs.sf |
976 |
fi |
977 |
fi |
978 |
} |
979 |
|
980 |
function doDiskRestore(){ |
981 |
if [ -z "${equalDisk[$count]}" ];then |
982 |
getRestoreParameters |
983 |
# disks not equal, do resize, restore MBR, don't create partitions |
984 |
|
985 |
msg="The temporary image file is now ready, and you are about to start the Restore operation |
986 |
|
987 |
You are about to restore |
988 |
the backup of disk ${activeItem[$selectedInputImage]} |
989 |
to |
990 |
disk $selectedOutputDisk |
991 |
|
992 |
Info: The target disk is larger than the backed up disk |
993 |
Selected Restore options will be be applied |
994 |
|
995 |
Do you want to continue?" |
996 |
dialog --backtitle "$backTitle" --title "Ready to Restore" --yesno "$msg" 16 70 |
997 |
|
998 |
if [ $? -eq 0 ];then |
999 |
# Do restore |
1000 |
COMMAND="ocs-sr -p true -e -b "${param[1]}" "${param[2]}" "${param[3]}" restoredisk reloc-image $selectedOutputDisk" |
1001 |
fi |
1002 |
else |
1003 |
# disks are equal, restore MBR, do partitioning, no resize |
1004 |
msg="The temporary image file is now ready, and you are about to start the Restore operation |
1005 |
|
1006 |
You are about to restore |
1007 |
the backup of disk ${activeItem[$selectedInputImage]} |
1008 |
to |
1009 |
disk $selectedOutputDisk |
1010 |
|
1011 |
Info: The disks are identical, so the target disk will be |
1012 |
partitioned and the MBR will be restored |
1013 |
|
1014 |
Do you want to continue?" |
1015 |
dialog --backtitle "$backTitle" --title "Ready to Restore" --yesno "$msg" 16 70 |
1016 |
|
1017 |
if [ $? -eq 0 ];then |
1018 |
# Do restore |
1019 |
COMMAND="ocs-sr -p true -e -b restoredisk reloc-image $selectedOutputDisk" |
1020 |
fi |
1021 |
fi |
1022 |
} |
1023 |
|
1024 |
function testRoot(){ |
1025 |
if [ "$(whoami)" != "root" ];then |
1026 |
printVersion |
1027 |
echo "Error: This script must be executed by root..." |
1028 |
exit |
1029 |
fi |
1030 |
} |
1031 |
|
1032 |
function printVersion(){ |
1033 |
echo "Clonezilla Live Image Restoration with Relocation |
1034 |
$(basename $0) v. $versionNumber - (C) 2007-2008 S. Georgaras <sng@hellug.gr> |
1035 |
" |
1036 |
} |
1037 |
|
1038 |
function printHelp(){ |
1039 |
printVersion |
1040 |
echo "Usage: $(basename $0) <options> |
1041 |
|
1042 |
Available options: |
1043 |
i [location] Print info about Clonezilla Live Image files found in [location] |
1044 |
[location] may be a hard disk partition, a CD-ROM device name or |
1045 |
smb - the first Samba Share |
1046 |
nfs - the first NFS Share |
1047 |
Remote shares must be mounted beforehand |
1048 |
v Print version info and exit |
1049 |
h Print this screen and exit" |
1050 |
} |
1051 |
|
1052 |
# |
1053 |
# |
1054 |
# Script starts here |
1055 |
# |
1056 |
# |
1057 |
|
1058 |
# findDirectories /home/spiros/multibootcd/files |
1059 |
# #findDirectories /home/partimag |
1060 |
# |
1061 |
# exit |
1062 |
|
1063 |
|
1064 |
#toMGByte "$1" |
1065 |
#exit |
1066 |
|
1067 |
|
1068 |
|
1069 |
|
1070 |
# grep -e '^/dev/' /data/test-img/hda-pt.sf | sed 's| : .*Id= *|:|' |
1071 |
# |
1072 |
# |
1073 |
# sfdisk -l /dev/hda 2>/dev/null| grep -e '^/dev/' | awk '{ |
1074 |
# if ($2=="*") |
1075 |
# print $1 ":" $7 ", bootable" |
1076 |
# else |
1077 |
# print $1 ":" $6}' |
1078 |
# exit |
1079 |
|
1080 |
|
1081 |
# getPartitionIdNameFromImage /data/usb250-img sda4 |
1082 |
# exit |
1083 |
|
1084 |
# set -x |
1085 |
# getDiskSizeFromImage /data/usb250-img |
1086 |
# exit |
1087 |
|
1088 |
# echo "$partitionList" |
1089 |
# exit |
1090 |
|
1091 |
# getMultiplier M f g |
1092 |
# echo "$THIS_MULTIPLIER" |
1093 |
|
1094 |
# set -x |
1095 |
# comparePartitionsSize 2GB 2GB |
1096 |
# echo $? |
1097 |
# exit |
1098 |
# set -x |
1099 |
# getPartitionSizeFromFdisk hda1 |
1100 |
# echo "$THIS_PARTITION_SIZE" |
1101 |
# exit |
1102 |
|
1103 |
|
1104 |
# mountedInputPartition=/data |
1105 |
# # set -x |
1106 |
# findImages "$mountedInputPartition" |
1107 |
|
1108 |
# set -x |
1109 |
# count=1 |
1110 |
# until [ -z "${img[$count]}" ];do |
1111 |
# echo "${id[$count]}" |
1112 |
# ((count++)) |
1113 |
# done |
1114 |
# |
1115 |
# exit |
1116 |
|
1117 |
|
1118 |
# calcInputSize /data/usb250-img |
1119 |
# calcInputSize /data/usb250-img sda4 |
1120 |
# calcInputID /data/usb250-img sda4 |
1121 |
# exit |
1122 |
|
1123 |
while getopts hvi: opt |
1124 |
do |
1125 |
case "$opt" in |
1126 |
i) |
1127 |
onlyImages=true |
1128 |
diskToScan=$(echo "$OPTARG" | sed 's|^/dev/||') |
1129 |
;; |
1130 |
v) |
1131 |
printVersion |
1132 |
exit;; |
1133 |
h) |
1134 |
printHelp |
1135 |
exit;; |
1136 |
esac |
1137 |
done |
1138 |
shift $(( OPTIND - 1 )) |
1139 |
|
1140 |
testRoot |
1141 |
backTitle="Clonezilla Live Image Restoration with Relocation" |
1142 |
|
1143 |
for CHK_DIR in /home/partimag /tmp/local-dev;do |
1144 |
CHK_HOME_PARTIMAG="$(mount | grep "$CHK_DIR")" |
1145 |
if [ -n "$CHK_HOME_PARTIMAG" ];then |
1146 |
CHK_MSG=" |
1147 |
A local partition or shared folder is already mounted |
1148 |
under "$CHK_DIR". reloc-img will now terminate to |
1149 |
prevent loss of data |
1150 |
|
1151 |
Please unmount it and try again" |
1152 |
CHK_TITLE=" "$CHK_DIR" already mounted!!! " |
1153 |
|
1154 |
if [ -z "$onlyImages" ];then |
1155 |
|
1156 |
dialog --backtitle "$backTitle" --title "$CHK_TITLE" --msgbox "$CHK_MSG" 10 66 |
1157 |
else |
1158 |
echo "$CHK_MSG" |
1159 |
echo |
1160 |
fi |
1161 |
# Don't use cleanUP here, we want user to see the mounted partition |
1162 |
# cleanUP |
1163 |
exit |
1164 |
fi |
1165 |
done |
1166 |
|
1167 |
|
1168 |
trap cleanUP 2 |
1169 |
|
1170 |
if [ ! -z "$onlyImages" ];then |
1171 |
printVersion |
1172 |
|
1173 |
|
1174 |
if [ "$diskToScan" = "smb" ];then |
1175 |
# if [ $(mount |grep cifs | wc -l) -eq 0 ];then |
1176 |
# echo "Error: No Samba Share mounted!!!" |
1177 |
# cleanUP |
1178 |
# exit |
1179 |
# fi |
1180 |
# set -x |
1181 |
selectedInputPartition=smb1 |
1182 |
workingRemote='y' |
1183 |
findSambaShare |
1184 |
elif [ "$diskToScan" = "nfs" ];then |
1185 |
if [ $(mount |grep nfs | wc -l) -eq 0 ];then |
1186 |
echo "Error: No NFS Share mounted!!!" |
1187 |
cleanUP |
1188 |
exit |
1189 |
fi |
1190 |
selectedInputPartition=nfs1 |
1191 |
workingRemote='y' |
1192 |
findNFSShare |
1193 |
else |
1194 |
test1=$(cat /proc/partitions | grep "$diskToScan") |
1195 |
if [ -z "$test1" ];then |
1196 |
# It is not a disk partition |
1197 |
# Is it a CD-ROM? |
1198 |
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") |
1199 |
if [ -z "$test1" ];then |
1200 |
echo "Error: No such partition or CD-ROM: $diskToScan" |
1201 |
cleanUP |
1202 |
exit |
1203 |
fi |
1204 |
fi |
1205 |
selectedInputPartition="$diskToScan" |
1206 |
fi |
1207 |
else |
1208 |
|
1209 |
|
1210 |
|
1211 |
|
1212 |
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 |
1213 |
Spiros Georgaras <sng@hellug.gr> |
1214 |
|
1215 |
It will help you restore a Clonezilla Image file to a disk/partition different from the one originally backed up. |
1216 |
|
1217 |
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. |
1218 |
|
1219 |
The target disk/partition must be the same partition type and at least equal (size-wise) to the old - backed up - disk/partition |
1220 |
|
1221 |
Please make sure all removable devices are connected to the system before pressing OK, and that no local partition is mounted |
1222 |
|
1223 |
All data in the target disk/partition will be OVERWRITTEN!!! |
1224 |
|
1225 |
---------------------- |
1226 |
THIS SOFTWARE COMES WITH ABSOLUTELY NO WARRANTY! |
1227 |
USE AT YOUR OWN RISK! |
1228 |
----------------------" |
1229 |
|
1230 |
msg1="Do you want to continue?" |
1231 |
dialog --backtitle "$backTitle" --title " Wellcome " \ |
1232 |
--msgbox "$msg" 20 72 \ |
1233 |
--and-widget --yesno "$msg1" 5 45 || { |
1234 |
clear |
1235 |
exit |
1236 |
} |
1237 |
|
1238 |
dialog --backtitle "$backTitle" --title " Working " --infobox "Determining system disks and partitions" 3 43 |
1239 |
|
1240 |
findSystemPartitions |
1241 |
# mount selectedInputPartition |
1242 |
dialog --backtitle "$backTitle" --title " Working " --infobox "Mounting selected device" 3 28 |
1243 |
|
1244 |
fi |
1245 |
|
1246 |
|
1247 |
|
1248 |
|
1249 |
[ -z "$selectedInputPartition" ] && { |
1250 |
cleanUP |
1251 |
echo "Error: selectedInputPartition is empty!!!" |
1252 |
exit 1 |
1253 |
} |
1254 |
# set -x |
1255 |
if [ -z "$workingRemote" ];then |
1256 |
# mount partition |
1257 |
mkdir /"$selectedInputPartition" 2>/dev/null |
1258 |
[ -d /"$selectedInputPartition" ] || { |
1259 |
cleanUP |
1260 |
echo "Error: Could not create folder: /$selectedInputPartition" |
1261 |
exit 1 |
1262 |
} |
1263 |
#set -x |
1264 |
if [ -z "$DEBUG" ];then |
1265 |
mkdir /"$selectedInputPartition" 2>/dev/null |
1266 |
if [ -z "${CD[$selectedInputPartitionNumber]}" ];then |
1267 |
# This is a disk partition |
1268 |
mount /dev/"$selectedInputPartition" /"$selectedInputPartition" 2>/dev/null |
1269 |
mountResult=$? |
1270 |
else |
1271 |
# This is a CD |
1272 |
# Is it mounted? |
1273 |
rm /home/partimag 2>/dev/null |
1274 |
mkdir /home/partimag 2>/dev/null |
1275 |
if [ -z "$(mount | grep "/dev/$selectedInputPartition")" ];then |
1276 |
# No it's not, mount it |
1277 |
echo "mount /dev/\"$selectedInputPartition\" /\"$selectedInputPartition\"" > /root/mountCommand.$$ |
1278 |
. /root/mountCommand.$$ && mountResult=0 || mountResult=1 |
1279 |
else |
1280 |
# Yes it is ,mount through bind |
1281 |
bindDir=$(mount | grep "/dev/$selectedInputPartition" | sed 's|.* on ||' | sed 's| type.*||') |
1282 |
# echo "mount --bind \"$bindDir\" /\"$selectedInputPartition\" 2>/dev/null" > /root/mountCommand.$$ |
1283 |
|
1284 |
|
1285 |
if [ -d "$bindDir"/home/partimag ]; then bindDir="$bindDir"/home/partimag;fi |
1286 |
|
1287 |
echo "mount --bind \"$bindDir\" /\"$selectedInputPartition\" 2>/dev/null" > /root/mountCommand.$$ |
1288 |
|
1289 |
|
1290 |
|
1291 |
chmod +x /root/mountCommand.$$ |
1292 |
. /root/mountCommand.$$ && mountResult=0 || mountResult=1 |
1293 |
fi |
1294 |
fi |
1295 |
else |
1296 |
### start DEBUG section |
1297 |
mount --bind /data /"$selectedInputPartition" |
1298 |
mountResult=$? |
1299 |
### end DEBUG section |
1300 |
fi |
1301 |
#read |
1302 |
|
1303 |
# Chech mounting result |
1304 |
if [ $mountResult -ne 0 ];then |
1305 |
if [ -z "$onlyImages" ];then |
1306 |
if [ -z "${CD[$selectedInputPartitionNumber]}" ];then |
1307 |
dialog --backtitle "$backTitle" --title " Mount error!!! " --msgbox "Partition $selectedInputPartition could not be mounted |
1308 |
|
1309 |
Please unmount all local partitions, and try again" 7 70 |
1310 |
cleanUP |
1311 |
exit 1 |
1312 |
else |
1313 |
while [ $mountResult -ne 0 ];do |
1314 |
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 |
1315 |
|
1316 |
Do you want to try again?" 9 70 |
1317 |
if [ $? -eq 0 ];then |
1318 |
dialog --backtitle "$backTitle" --title " Working " --infobox "Mounting selected device" 3 28 |
1319 |
. /root/mountCommand.$$ && mountResult=0 || mountResult=1 |
1320 |
else |
1321 |
cleanUP |
1322 |
exit 1 |
1323 |
fi |
1324 |
done |
1325 |
fi |
1326 |
else |
1327 |
echo "Error: Could not mount $selectedInputPartition" |
1328 |
cleanUP |
1329 |
exit 1 |
1330 |
fi |
1331 |
|
1332 |
fi |
1333 |
else |
1334 |
selectedInputPartition=$(echo "${inputPartition[$selectedInputPartitionNumber]}" | sed 's|^/||') |
1335 |
fi |
1336 |
|
1337 |
|
1338 |
######################################################## |
1339 |
# |
1340 |
# find directories... |
1341 |
# |
1342 |
######################################################## |
1343 |
if [ -z "$onlyImages" ];then |
1344 |
findDirectories /"$selectedInputPartition" |
1345 |
if [ -z "$activeDirectory" ];then |
1346 |
cleanUP |
1347 |
exit |
1348 |
fi |
1349 |
|
1350 |
if [ "$activeDirectory" != "/" ];then |
1351 |
selectedInputPartition="$selectedInputPartition"/"$activeDirectory" |
1352 |
fi |
1353 |
fi |
1354 |
######################################################## |
1355 |
|
1356 |
|
1357 |
findImages /"$selectedInputPartition" |
1358 |
|
1359 |
if [ ! -z "$onlyImages" ];then |
1360 |
cleanUP |
1361 |
exit |
1362 |
fi |
1363 |
|
1364 |
|
1365 |
if [ "${type[$selectedInputImage]}" = "part" ];then |
1366 |
getOutputPartition |
1367 |
preparePartitionImage |
1368 |
doPartitionRestore |
1369 |
else |
1370 |
getOutputDisk |
1371 |
prepareDiskImage |
1372 |
doDiskRestore |
1373 |
fi |
1374 |
# checking=aaa |
1375 |
if [ ! -z "$COMMAND" ];then |
1376 |
if [ -z "$checking" ];then |
1377 |
$COMMAND |
1378 |
else |
1379 |
echo "The command that would be executed is: |
1380 |
$COMMAND" |
1381 |
# read |
1382 |
fi |
1383 |
fi |
1384 |
cleanUP |