This repository has been archived by the owner on Sep 23, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathlto_analyzer.sh
executable file
·363 lines (311 loc) · 10.2 KB
/
lto_analyzer.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
#!/bin/sh
# ------------------------------------------------
# Tools
# ------------------------------------------------
show_field () {
fd_start_addr=$(($2*2+1))
fd_end_addr=$(($3*2-1+$fd_start_addr))
data=`echo $1 | cut -c $fd_start_addr-$fd_end_addr`
if [ "$5" = "ascii" ]
then
echo " "$4": "`echo $data | xxd -p -r | tr -d '\0'`
elif [ "$5" = "decimal" ]
then
echo " "$4": "`echo "ibase=16; $data" | bc`
else
echo " "$4": "$data
fi
}
calc_page_data () {
pg_start_addr=`echo "ibase=16; $1" | bc`
pg_start_addr=$(($pg_start_addr*2+1))
pg_end_addr=$(($2*2-1+$pg_start_addr))
echo $3 | cut -c $pg_start_addr-$pg_end_addr
}
# ------------------------------------------------
# Sub - Show Page
# ------------------------------------------------
show_lto_cm_mfg_info () {
echo "-- LTO CM Manufacturer's Information --"
show_field $1 0 4 "LTO CM Serial Number"
show_field $1 4 1 "CM Serial Number Check Byte"
show_field $1 5 1 "CM Size"
show_field $1 6 2 "Type"
show_field $1 8 24 "Manufacturer's Information"
}
show_lto_cm_wrtinh () {
echo "-- LTO CM Write-Inhibit --"
show_field $1 0 1 "Last Write-Inhibited Block Number"
show_field $1 1 1 "Block 1 Protection Flag"
show_field $1 2 2 "Reserved"
}
show_cart_mfg_info () {
echo "-- Cartridge Manufacturer's Information --"
show_field $1 0 2 "Page Id"
show_field $1 2 2 "Page Length"
show_field $1 4 8 "Cartridge Manufacturer" "ascii"
show_field $1 12 10 "Serial Number" "ascii"
show_field $1 22 2 "Cartridge Type"
show_field $1 24 8 "Date of Manufacture" "ascii"
show_field $1 32 2 "Tape Length"
show_field $1 34 2 "Tape Thickness"
show_field $1 36 2 "Empty Reel Inertia"
show_field $1 38 2 "Hub Radius"
show_field $1 40 2 "Full Reel Pack Radius"
show_field $1 42 2 "Maximum Media Speed"
show_field $1 44 4 "License Code"
show_field $1 48 12 "Cartridge Manufacturer's Use"
show_field $1 60 4 "CRC"
}
show_media_mfg_info () {
echo "-- Media Manufacturer's Information --"
show_field $1 0 2 "Page Id"
show_field $1 2 2 "Page Length"
show_field $1 4 48 "Servowriter Manufacturer" "ascii"
show_field $1 52 8 "Reserved"
show_field $1 60 4 "CRC"
}
show_init_data () {
echo "-- Initialisation Data --"
show_field $1 0 2 "Page Id"
show_field $1 2 2 "Page Length"
show_field $1 4 8 "Initialising Drive Manufacturer" "ascii"
show_field $1 12 10 "Drive Id" "ascii"
show_field $1 22 2 "Format Type"
show_field $1 24 4 "LP1 Position"
show_field $1 28 4 "LP2 Position"
show_field $1 32 4 "LP3 Position"
show_field $1 36 4 "LP4 Position"
show_field $1 40 4 "LP5 Position"
show_field $1 44 4 "LP6 Position"
show_field $1 48 12 "Reserved"
show_field $1 60 4 "CRC"
}
show_tape_wrt_pass () {
echo "-- Tape Write Pass --"
show_field $1 0 2 "Page Id"
show_field $1 2 2 "Page Length"
show_field $1 4 12 "Reserved"
show_field $1 16 4 "Write Pass Field 0"
show_field $1 20 4 "Write Pass Field 1"
show_field $1 24 4 "Write Pass Field 2"
show_field $1 28 4 "Write Pass Field 3"
show_field $1 32 4 "Write Pass Field 4"
show_field $1 36 4 "Write Pass Field 5"
show_field $1 40 4 "Write Pass Field 6"
show_field $1 44 4 "Write Pass Field 7"
}
show_tape_dir () {
echo "-- Tape Directory --"
show_field $1 0 2 "Page Id"
show_field $1 2 2 "Page Length"
show_field $1 4 4 "FID Tape Write Pass"
show_field $1 8 8 "Reserved"
for i in `seq 0 95`
do
show_field $1 $((16+$i*16)) 16 "Wrap Section $i"
done
}
show_eod_info () {
echo "-- EOD Information --"
show_field $1 0 2 "Page Id"
show_field $1 2 2 "Page Length"
show_field $1 4 4 "Tape Write Pass for last written EOD"
show_field $1 8 4 "Thread Count"
show_field $1 12 6 "Record count at EOD"
show_field $1 18 6 "File Mark Count at EOD"
show_field $1 24 4 "EOD Data Set Number"
show_field $1 28 4 "Wrap Section Number of EOD"
show_field $1 32 2 "Validity of EOD"
show_field $1 34 2 "First CQ Set Number"
show_field $1 36 4 "Physical Position of EOD"
show_field $1 40 20 "Reserved"
show_field $1 60 4 "CRC"
}
show_status_alert () {
echo "-- Cartridge Status and Tape Alert Flags --"
show_field $1 0 2 "Page Id"
show_field $1 2 2 "Page Length"
show_field $1 4 8 "Tape Alert Flags"
show_field $1 12 4 "Thread Count"
show_field $1 16 2 "Cartridge Status"
show_field $1 18 10 "Reserved"
show_field $1 28 4 "CRC"
}
show_mechanism_related () {
echo "-- Mechanism Related --"
show_field $1 0 2 "Page Id"
show_field $1 2 2 "Page Length"
show_field $1 4 8 "Drive Manufacturer Identity" "ascii"
#show_field $1 12 368 "Mechanism related data"
show_field $1 380 4 "CRC"
}
show_sus_appd_wrt () {
echo "-- Suspended Append Writes --"
show_field $1 0 2 "Page Id"
show_field $1 2 2 "Page Length"
show_field $1 4 4 "Reserved"
for i in `seq 0 13`
do
show_field $1 $((8*$i+8)) 8 "Suspended Append $i"
done
show_field $1 120 4 "Reserved"
show_field $1 124 4 "CRC"
}
show_usage_info () {
echo "-- Usage Information $2 --"
show_field $1 0 2 "Page Id"
show_field $1 2 2 "Page Length"
show_field $1 4 8 "Drive Manufacturer" "ascii"
show_field $1 12 10 "Drive Id" "ascii"
show_field $1 22 2 "Suspended Writes at Append" "decimal"
show_field $1 24 4 "Thread Count" "decimal"
show_field $1 28 8 "Total Data Sets Written" "decimal"
show_field $1 36 8 "Total Data Sets Read" "decimal"
show_field $1 44 4 "Total Write Retries" "decimal"
show_field $1 48 4 "Total Read Retries" "decimal"
show_field $1 52 2 "Total Unrecovered Write Errors" "decimal"
show_field $1 54 2 "Total Unrecovered Read Errors" "decimal"
show_field $1 56 2 "Total Number of Suspended Writes" "decimal"
show_field $1 58 2 "Total Number of Fatal Suspended Writes" "decimal"
show_field $1 60 4 "CRC"
}
show_app_specific () {
echo "-- Application Specific Data --"
show_field $1 0 2 "Page Id"
show_field $1 2 2 "Page Length"
#show_field $1 4 1024 "Application Data"
show_field $1 1028 24 "Reserved"
show_field $1 1052 4 "CRC"
}
# ------------------------------------------------
# Main
# ------------------------------------------------
if [ "$1" = "" ]; then
echo "Usage: $(basename "$0") [*.eml or *.bin]"
exit 2
fi
if [ ! -e "$1" ]; then
echo "File Not Found"
exit 2
fi
#Read File
if [ "`echo $1 | grep .eml`" ]
then
input=`cat "$1" | tr -d '\n'`
elif [ "`echo $1 | grep .bin`" ]
then
input=`xxd -u -ps "$1" | tr -d '\n'`
else
echo "Unsupported File"
exit 2
fi
#Search for Starting Address of Protected Pages
p_page_table=`calc_page_data 24 $((${#input}/2-36)) $input`
i=0
while :
do
page_descriptor=`echo $p_page_table | cut -c $((1+i*8))-$((8+i*8))`
page_version=`echo $page_descriptor | cut -c 1`
page_id=`echo $page_descriptor | cut -c 2-4`
start_addr=`echo $page_descriptor | cut -c 5-8`
case "$page_id" in
"001" ) cart_mfg_info_addr=$start_addr;;
"002" ) media_mfg_info_addr=$start_addr;;
"101" ) init_data_addr=$start_addr;;
esac
#An End Of Page Table (EOPT) Page Descriptor. Exit search loop
if [ "$page_id" = "FFF" -a "$page_version" = "0" ]; then
unprotected_page_addr=$start_addr
break
fi
i=$((i+1))
done
#Search for Starting Address of Unprotected Pages
unprotected_page_addr_d=`echo "ibase=16; $unprotected_page_addr"|bc`
u_page_table=`calc_page_data $unprotected_page_addr $((${#input}/2-unprotected_page_addr_d)) $input`
i=0
while :
do
page_descriptor=`echo $u_page_table | cut -c $((1+i*8))-$((8+i*8))`
page_version=`echo $page_descriptor | cut -c 1`
page_id=`echo $page_descriptor | cut -c 2-4`
start_addr=`echo $page_descriptor | cut -c 5-8`
case "$page_id" in
"101" ) init_data_addr=$start_addr;;
"102" ) tape_wrt_pass_addr=$start_addr;;
"103" ) tape_dir_addr=$start_addr;;
"104" ) eod_info_addr=$start_addr;;
"105" ) status_alert_addr=$start_addr;;
"106" ) mechanism_related_addr=$start_addr;;
"107" ) sus_appd_wrt_addr=$start_addr;;
"108" ) usage_info0_addr=$start_addr;;
"109" ) usage_info1_addr=$start_addr;;
"10A" ) usage_info2_addr=$start_addr;;
"10B" ) usage_info3_addr=$start_addr;;
"200" ) app_specific_addr=$start_addr;;
esac
#An End Of Page Table (EOPT) Page Descriptor. Exit search loop
if [ "$page_id" = "FFF" -a "$page_version" = "0" ]; then
break
fi
i=$((i+1))
done
lto_cm_mfg_info=`calc_page_data 0 32 $input`
show_lto_cm_mfg_info $lto_cm_mfg_info
lto_cm_wrtinh=`calc_page_data 20 4 $input`
show_lto_cm_wrtinh $lto_cm_wrtinh
cart_mfg_info=`calc_page_data $cart_mfg_info_addr 64 $input`
show_cart_mfg_info $cart_mfg_info
if [ "$media_mfg_info_addr" != "" ]; then
media_mfg_info=`calc_page_data $media_mfg_info_addr 64 $input`
show_media_mfg_info $media_mfg_info
fi
if [ "$init_data_addr" != "" ]; then
init_data=`calc_page_data $init_data_addr 64 $input`
show_init_data $init_data
fi
if [ "$tape_wrt_pass_addr" != "" ]; then
tape_wrt_pass=`calc_page_data $tape_wrt_pass_addr 48 $input`
show_tape_wrt_pass $tape_wrt_pass
fi
if [ "$tape_dir_addr" != "" ]; then
tape_dir=`calc_page_data $tape_dir_addr 1552 $input`
show_tape_dir $tape_dir
fi
if [ "$eod_info_addr" != "" ]; then
eod_info=`calc_page_data $eod_info_addr 64 $input`
show_eod_info $eod_info
fi
if [ "$status_alert_addr" != "" ]; then
status_alert=`calc_page_data $status_alert_addr 32 $input`
show_status_alert $status_alert
fi
if [ "$mechanism_related_addr" != "" ]; then
mechanism_related=`calc_page_data $mechanism_related_addr 384 $input`
show_mechanism_related $mechanism_related
fi
if [ "$sus_appd_wrt_addr" != "" ]; then
sus_appd_wrt=`calc_page_data $sus_appd_wrt_addr 128 $input`
show_sus_appd_wrt $sus_appd_wrt
fi
if [ "$usage_info0_addr" != "" ]; then
usage_info=`calc_page_data $usage_info0_addr 64 $input`
show_usage_info $usage_info 0
fi
if [ "$usage_info1_addr" != "" ]; then
usage_info=`calc_page_data $usage_info1_addr 64 $input`
show_usage_info $usage_info 1
fi
if [ "$usage_info2_addr" != "" ]; then
usage_info=`calc_page_data $usage_info2_addr 64 $input`
show_usage_info $usage_info 2
fi
if [ "$usage_info3_addr" != "" ]; then
usage_info=`calc_page_data $usage_info3_addr 64 $input`
show_usage_info $usage_info 3
fi
if [ "$app_specific_addr" != "" ]; then
app_specific=`calc_page_data $app_specific_addr 1056 $input`
show_app_specific $app_specific
fi