1 |
#!/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 |
versionNumber='0.2' |
24 |
|
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 |
|
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 |
[ -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 |
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 |
# 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 |
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 |
} |
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 |
$(basename $0) v. $versionNumber - (C) 2009-2010 S. Georgaras <sng@hellug.gr> |
258 |
" |
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 |
e Print extended info (image size and disk model) |
269 |
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 |
while getopts hvdsei: opt |
281 |
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 |
e) |
303 |
EXTENDED=y;; |
304 |
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 |