1 |
sng |
47 |
#!/bin/bash |
2 |
|
|
############################################################################## |
3 |
|
|
# # |
4 |
|
|
# imginfo, (C) 2007-2010 S. Georgaras <sng@hellug.gr> # |
5 |
|
|
# # |
6 |
|
|
# This file is part of Clonezilla-SysRescCD. # |
7 |
|
|
# # |
8 |
|
|
# Clonezilla-SysRescCD is free software: you can redistribute it and/or # |
9 |
|
|
# modify it under the terms of the GNU General Public License as published # |
10 |
|
|
# by the Free Software Foundation, either version 2 of the License, or # |
11 |
|
|
# (at your option) any later version. # |
12 |
|
|
# # |
13 |
|
|
# Clonezilla-SysRescCD is distributed in the hope that it will be useful, # |
14 |
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of # |
15 |
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # |
16 |
|
|
# GNU General Public License for more details. # |
17 |
|
|
# # |
18 |
|
|
# You should have received a copy of the GNU General Public License along # |
19 |
|
|
# with Clonezilla-SysRescCD. If not, see <http://www.gnu.org/licenses/>. # |
20 |
|
|
# # |
21 |
|
|
############################################################################## |
22 |
|
|
# DEBUG=true |
23 |
sng |
143 |
versionNumber='0.2' |
24 |
sng |
47 |
|
25 |
|
|
function readImage(){ |
26 |
|
|
# set -x |
27 |
|
|
# n="${partElm[$oCount]}" |
28 |
|
|
n="$1" |
29 |
|
|
tmp="$(dirname "$n")" |
30 |
|
|
validateImage "$tmp" || { |
31 |
|
|
((oCount++)) |
32 |
|
|
return 1 |
33 |
|
|
} |
34 |
|
|
img[$count]="$(basename "$tmp")" |
35 |
|
|
|
36 |
sng |
143 |
|
37 |
|
|
sizeInDisk[$count]=`du -hc "$(dirname "$n")" | sed -e '$!d' -e 's|[ \t].*||'`B |
38 |
|
|
diskModel[$count]="Disk "`head -n 1 "$(dirname "$n")"/*parted` |
39 |
sng |
47 |
[ -r "$(dirname "$n")"/disk ] && { |
40 |
|
|
hasDisk=1 |
41 |
|
|
type[$count]=disk |
42 |
|
|
tmp="$(dirname "$n")"/disk |
43 |
|
|
activeItem[$count]=$(cat "$tmp") |
44 |
|
|
partCount=$(cat "$(dirname "$n")"/parts | awk '{print NF}') |
45 |
|
|
tmp=$(dirname "$n") |
46 |
|
|
diskSizeFromImage[$count]=$(getDiskSizeFromImage "$tmp") |
47 |
sng |
143 |
if [ -z "$EXTENDED" ];then |
48 |
|
|
id[$count]="Image: ${img[$count]}, ${type[$count]}: ${activeItem[$count]}"", size: ${diskSizeFromImage[$count]}, parts: $partCount" |
49 |
|
|
else |
50 |
|
|
id[$count]="Image: ${img[$count]}, image size: ${sizeInDisk[$count]}, ${type[$count]}: ${activeItem[$count]}"", size: ${diskSizeFromImage[$count]}, parts: $partCount, ${diskModel[$count]}" |
51 |
|
|
fi |
52 |
sng |
47 |
# scan parts |
53 |
|
|
pCount=1 |
54 |
|
|
tmpImg="${img[$count]}" |
55 |
|
|
while [ $pCount -le $partCount ];do |
56 |
|
|
((count++)) |
57 |
|
|
img[$count]="$tmpImg" |
58 |
|
|
type[$count]=part |
59 |
|
|
activeItem[$count]=$(cat "$n" | awk '{for(i=1;i<=NF;i++) print $i}' | sed -n ""$pCount"p") |
60 |
|
|
calcInputSize "$tmp" "${activeItem[$count]}" |
61 |
|
|
imagePartitionSize[$count]="$THIS_INPUT_SIZE" |
62 |
|
|
partitionIdName[$count]=$(getPartitionIdNameFromImage "$tmp" "${activeItem[$count]}") |
63 |
|
|
((pCount++)) |
64 |
|
|
id[$count]=" ${type[$count]}: ${activeItem[$count]}, size: ${imagePartitionSize[$count]}, type: ${partitionIdName[$count]}" |
65 |
|
|
done |
66 |
|
|
} || { |
67 |
|
|
type[$count]=part |
68 |
|
|
activeItem[$count]=$(cat "$n") |
69 |
|
|
partCount=1 |
70 |
|
|
calcInputSize /"$tmp" "${activeItem[$count]}" |
71 |
|
|
imagePartitionSize[$count]="$THIS_INPUT_SIZE" |
72 |
|
|
partitionIdName[$count]=$(getPartitionIdNameFromImage "$tmp" "${activeItem[$count]}") |
73 |
sng |
143 |
if [ -z "$EXTENDED" ];then |
74 |
|
|
id[$count]="Image: ${img[$count]}, ${type[$count]}: ${activeItem[$count]}, size: ${imagePartitionSize[$count]}, type: ${partitionIdName[$count]}" |
75 |
|
|
else |
76 |
|
|
id[$count]="Image: ${img[$count]}, image size: ${sizeInDisk[$count]}, ${type[$count]}: ${activeItem[$count]}, size: ${imagePartitionSize[$count]}, type: ${partitionIdName[$count]}, ${diskModel[$count]}" |
77 |
|
|
fi |
78 |
sng |
47 |
} |
79 |
|
|
imgCount="$count" |
80 |
|
|
((count++)) |
81 |
|
|
((oCount++)) |
82 |
|
|
} |
83 |
|
|
|
84 |
|
|
|
85 |
|
|
function findImages(){ |
86 |
|
|
# <- folder to scan |
87 |
|
|
# |
88 |
|
|
# -> selectedInputImage - Number (index) in img array |
89 |
|
|
# -> selectedInputImageSize - Size of disk / partition |
90 |
|
|
# -> selectedInputImageID - Number - Partition ID (if user selected partition) |
91 |
|
|
# |
92 |
|
|
# -> imgCount - Number of images found |
93 |
|
|
# -> partCount - Number of partitions found |
94 |
|
|
# |
95 |
|
|
# -> img - image name |
96 |
|
|
# -> type - image type (partition/disk) |
97 |
|
|
# -> activeItem - name of partition/disk |
98 |
|
|
# -> imagePartitionSize - size of partition |
99 |
|
|
# -> diskSizeFromImage - disk size |
100 |
|
|
# -> partitionIdName - partition id in words |
101 |
|
|
# -> id - description |
102 |
|
|
|
103 |
|
|
imgCount=0 |
104 |
|
|
partCount=0 |
105 |
|
|
|
106 |
|
|
local count=1 |
107 |
|
|
local n |
108 |
|
|
local tmp |
109 |
|
|
local pCount |
110 |
|
|
local tmpImg |
111 |
|
|
local hasDisk=0 |
112 |
|
|
# set -x |
113 |
|
|
|
114 |
|
|
allParts="$(find -L "$1" -mindepth 2 -maxdepth 2 -name parts | sed 's|^\./||' 2>/dev/null)" |
115 |
|
|
|
116 |
|
|
psCount=1 |
117 |
|
|
partElm[$psCount]="$(echo "$allParts" | sed -n ""$psCount"p")" |
118 |
|
|
while [ -n "${partElm[$psCount]}" ];do |
119 |
|
|
((psCount++)) |
120 |
|
|
partElm[$psCount]="$(echo "$allParts" | sed -n ""$psCount"p")" |
121 |
|
|
done |
122 |
|
|
|
123 |
|
|
oCount=1 |
124 |
|
|
while [ "$oCount" -lt "$psCount" ];do |
125 |
|
|
readImage "${partElm[$oCount]}" |
126 |
|
|
done |
127 |
|
|
# exit |
128 |
|
|
[ $imgCount -eq 0 ] &&{ |
129 |
|
|
local msgType |
130 |
|
|
[ -z "${CD[$selectedInputPartitionNumber]}" ] && msgType=Partition || msgType=CD-ROM |
131 |
|
|
if [ -n "$(echo "$selectedInputPartition" | grep '/')" ];then |
132 |
|
|
msgType=Folder |
133 |
|
|
selectedInputPartition=/"$selectedInputPartition" |
134 |
|
|
fi |
135 |
|
|
|
136 |
|
|
if [ -z "$onSubDirs" ];then |
137 |
|
|
setterm -bold on |
138 |
|
|
echo -n "No image files found in: " |
139 |
|
|
setterm -foreground magenta |
140 |
|
|
echo -n "$startDir" |
141 |
|
|
setterm -foreground white |
142 |
|
|
setterm -bold off |
143 |
|
|
echo ' ' |
144 |
|
|
fi |
145 |
|
|
exit 1 |
146 |
|
|
} |
147 |
|
|
|
148 |
|
|
|
149 |
|
|
setterm -bold on |
150 |
|
|
echo -n "Image files found in: " |
151 |
|
|
setterm -foreground magenta |
152 |
|
|
echo "$startDir" |
153 |
|
|
setterm -foreground white |
154 |
|
|
setterm -bold off |
155 |
|
|
count=1 |
156 |
|
|
until [ -z "${id[$count]}" ];do |
157 |
|
|
echo " ${id[$count]}" |
158 |
|
|
((count++)) |
159 |
|
|
done |
160 |
|
|
} |
161 |
|
|
|
162 |
|
|
function getPartitionIdNameFromImage(){ |
163 |
|
|
local id=$(grep "$2" "$1"/*pt.sf | sed 's|.*Id= *||' | sed 's|,.*$||') |
164 |
|
|
sfdisk -T |sed 's|^[ ]||' | grep -e "^$id[ \t]" | sed "s|^$id *||" |
165 |
|
|
} |
166 |
|
|
|
167 |
|
|
function getDiskSizeFromImage(){ |
168 |
|
|
local lin=$(awk 'BEGIN{FS="=" |
169 |
|
|
count=0} |
170 |
|
|
{if (count==0) b=$2 |
171 |
|
|
else{ |
172 |
|
|
b=b" * " |
173 |
|
|
b=b$2 |
174 |
|
|
} |
175 |
|
|
count++} |
176 |
|
|
END{print b}' "$1"/*chs.sf | bc) |
177 |
|
|
local size=$(echo "$lin * 512" | bc) |
178 |
|
|
toMGByte "$size" |
179 |
|
|
} |
180 |
|
|
|
181 |
|
|
function getDiskSizeFromDisk(){ |
182 |
|
|
local size=$(fdisk -l /dev/"$1" | grep -e '^Disk /dev/' | sed 's|.*, *||' | sed 's| *bytes||') |
183 |
|
|
toMGByte "$size" |
184 |
|
|
} |
185 |
|
|
|
186 |
|
|
function toMGByte(){ |
187 |
|
|
if [ $(expr length "$1") -le 9 ];then |
188 |
|
|
echo $(expr substr "$1" 1 3 )"MB" |
189 |
|
|
elif [ $(expr length "$1") -eq 10 ];then |
190 |
|
|
echo $(expr substr "$1" 1 2 | sed 's|\([0-9]\)$|.\1|')"GB" |
191 |
|
|
elif [ $(expr length "$1") -lt 12 ];then |
192 |
|
|
echo $(expr substr "$1" 1 3 | sed 's|\([0-9]\)$|.\1|')"GB" |
193 |
|
|
else |
194 |
|
|
echo $(expr substr "$1" 1 4 | sed 's|\([0-9]\)$|.\1|')"GB" |
195 |
|
|
fi |
196 |
|
|
} |
197 |
|
|
|
198 |
|
|
function validateImage(){ |
199 |
|
|
######################################### |
200 |
|
|
# accept only disk images # |
201 |
|
|
######################################### |
202 |
|
|
# [ -r "$(dirname "$n")"/disk ] && return 0 |
203 |
|
|
######################################### |
204 |
|
|
[ -d "$1"/parts ] && return 1 |
205 |
|
|
local sf=$(find "$1" -name "*-chs.sf" 2>/dev/null | wc -l) |
206 |
|
|
[ $sf -eq 0 ] && return 1 |
207 |
|
|
local pt=$(find "$1" -name "*-pt.sf" 2>/dev/null | wc -l) |
208 |
|
|
[ $pt -eq 0 ] && return 1 |
209 |
|
|
# modification to read unsplited images |
210 |
|
|
# thanks to Viking (24/11/2008) |
211 |
|
|
# local aa=$(find "$1" -name "*.aa" 2>/dev/null | wc -l) |
212 |
|
|
# [ $aa -eq 0 ] && return 1 |
213 |
|
|
return 0 |
214 |
|
|
} |
215 |
|
|
|
216 |
|
|
function calcInputID(){ |
217 |
|
|
THIS_INPUT_ID=$(sed -n "/$2/p" "$1"/*-pt.sf | sed 's|.*Id= *||' | sed 's|,.*$||') |
218 |
|
|
} |
219 |
|
|
|
220 |
|
|
function calcInputSize(){ |
221 |
|
|
# set -x |
222 |
|
|
local bytesPerSector=512 |
223 |
|
|
local l |
224 |
|
|
local pSize |
225 |
|
|
local cylinders |
226 |
|
|
local heads |
227 |
|
|
local sectors |
228 |
|
|
if [ -z "$2" ];then |
229 |
|
|
cylinders=$(sed -n '/cylinders=/p' "$1"/*-chs.sf | sed 's|cylinders=||') |
230 |
|
|
heads=$(sed -n '/heads=/p' "$1"/*-chs.sf | sed 's|heads=||') |
231 |
|
|
sectors=$(sed -n '/sectors=/p' "$1"/*-chs.sf | sed 's|sectors=||') |
232 |
|
|
THIS_INPUT_SIZE=$(echo "scale=2; $cylinders * $heads * $sectors * $bytesPerSector" | bc) |
233 |
|
|
else |
234 |
|
|
pSize=$(sed -n "/$2/p" "$1"/*-pt.sf | sed 's|.*size= *||' | sed 's|,.*||') |
235 |
|
|
THIS_INPUT_SIZE=$(echo "scale=2; $pSize * $bytesPerSector" | bc) |
236 |
|
|
fi |
237 |
|
|
|
238 |
|
|
l=$(expr length $THIS_INPUT_SIZE) |
239 |
|
|
if [ $l -gt 9 ];then |
240 |
|
|
THIS_INPUT_SIZE=$(echo "scale=2; $THIS_INPUT_SIZE / 1024 / 1024 / 1024" | bc)GB |
241 |
|
|
else |
242 |
|
|
THIS_INPUT_SIZE=$(echo "scale=3; $THIS_INPUT_SIZE / 1024 / 1024" | bc | sed 's|\.000|.00|')MB |
243 |
|
|
fi |
244 |
|
|
# set +x |
245 |
|
|
} |
246 |
|
|
|
247 |
|
|
function testRoot(){ |
248 |
|
|
if [ "$(whoami)" != "root" ];then |
249 |
|
|
printVersion |
250 |
|
|
echo "Error: This script must be executed by root..." |
251 |
|
|
exit |
252 |
|
|
fi |
253 |
|
|
} |
254 |
|
|
|
255 |
|
|
function printVersion(){ |
256 |
|
|
echo "Clonezilla Live Image Information |
257 |
sng |
143 |
$(basename $0) v. $versionNumber - (C) 2009-2010 S. Georgaras <sng@hellug.gr> |
258 |
sng |
47 |
" |
259 |
|
|
} |
260 |
|
|
|
261 |
|
|
function printHelp(){ |
262 |
|
|
printVersion |
263 |
|
|
echo "Usage: $(basename $0) <options> <directory> |
264 |
|
|
|
265 |
|
|
Available options: |
266 |
|
|
s Search in sub-directories too |
267 |
|
|
i [name] Pring info for image [name] |
268 |
sng |
143 |
e Print extended info (image size and disk model) |
269 |
sng |
47 |
v Print version info and exit |
270 |
|
|
h Print this screen and exit" |
271 |
|
|
|
272 |
|
|
} |
273 |
|
|
|
274 |
|
|
# |
275 |
|
|
# |
276 |
|
|
# Script starts here |
277 |
|
|
# |
278 |
|
|
# |
279 |
|
|
# set -x |
280 |
sng |
143 |
while getopts hvdsei: opt |
281 |
sng |
47 |
do |
282 |
|
|
case "$opt" in |
283 |
|
|
i) |
284 |
|
|
testRoot |
285 |
|
|
imgOnly=1 |
286 |
|
|
startDir="$OPTARG" |
287 |
|
|
;; |
288 |
|
|
s) |
289 |
|
|
testRoot |
290 |
|
|
subDirs=1 |
291 |
|
|
;; |
292 |
|
|
d) |
293 |
|
|
testRoot |
294 |
|
|
onSubDirs=1 |
295 |
|
|
;; |
296 |
|
|
v) |
297 |
|
|
printVersion |
298 |
|
|
exit;; |
299 |
|
|
h) |
300 |
|
|
printHelp |
301 |
|
|
exit;; |
302 |
sng |
143 |
e) |
303 |
|
|
EXTENDED=y;; |
304 |
sng |
47 |
esac |
305 |
|
|
done |
306 |
|
|
shift $(( OPTIND - 1 )) |
307 |
|
|
|
308 |
|
|
testRoot |
309 |
|
|
# set -x |
310 |
|
|
[ -z "$startDir" ] && startDir="$1" |
311 |
|
|
if [ -z "$startDir" ];then |
312 |
|
|
startDir="$PWD" |
313 |
|
|
fi |
314 |
|
|
|
315 |
|
|
# remove ending / |
316 |
|
|
startDir="$(echo "$startDir" | sed 's|/$||')" |
317 |
|
|
|
318 |
|
|
# convert ./xxx -> /sss/ddd/xxx |
319 |
|
|
# xxx -> /sss/ddd/xxx |
320 |
|
|
if [ "$(echo "$startDir" |sed -n '/^\.\//p')" != "" ] || [ "$(echo "$startDir" | sed -n '/^\//p')" = "" ];then |
321 |
|
|
if [ -d "$PWD"/`echo "$startDir" | sed 's|\.*/||'` ];then |
322 |
|
|
startDir="$PWD"/`echo "$startDir" | sed 's|\.*/||'` |
323 |
|
|
pathFixed=1 |
324 |
|
|
elif [ -d /home/partimag/`echo "$startDir" | sed 's|\.*/||'` ];then |
325 |
|
|
startDir=/home/partimag/`echo "$startDir" | sed 's|\.*/||'` |
326 |
|
|
pathFixed=1 |
327 |
|
|
fi |
328 |
|
|
fi |
329 |
|
|
|
330 |
|
|
if [ ! -d "$startDir" ];then |
331 |
|
|
printVersion |
332 |
|
|
echo "Error: Folder \"$( basename "$startDir")\" not found!!!" |
333 |
|
|
exit 1 |
334 |
|
|
fi |
335 |
|
|
|
336 |
|
|
if [ -z "$imgOnly" ];then |
337 |
|
|
findImages "$startDir" |
338 |
|
|
if [ ! -z "$subDirs" ];then |
339 |
|
|
for n in "$startDir"/*;do |
340 |
|
|
if [ -d "$n" ] && [ -r "$n" ];then |
341 |
|
|
"$0" -d "$n" |
342 |
|
|
fi |
343 |
|
|
done |
344 |
|
|
fi |
345 |
|
|
else |
346 |
|
|
readImage "$startDir"/parts |
347 |
|
|
count=0 |
348 |
|
|
if [ -z "${id[$count]}" ];then |
349 |
|
|
printVersion |
350 |
|
|
echo "Error: Image \"$startDir\" does not exist!!!" |
351 |
|
|
exit 1 |
352 |
|
|
fi |
353 |
|
|
until [ -z "${id[$count]}" ];do |
354 |
|
|
echo " ${id[$count]}" |
355 |
|
|
((count++)) |
356 |
|
|
done |
357 |
|
|
fi |