-
Notifications
You must be signed in to change notification settings - Fork 0
/
fvi
executable file
·830 lines (724 loc) · 25.4 KB
/
fvi
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
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
#!/bin/sh
# fvi - file metainformation lister
#
# Copyright (c) 2009-2024 Dan Fandrich <[email protected]>
# Licensed under the MIT license (see LICENSE).
#
# Format of file type entries in this file:
#
# * The requires: comment lines below the file type refer to the
# software package(s) required to view the metadata of the file
# (RedHat package names are listed in most cases). This information is not
# currently used by the program but is merely a note to the curious user
# who wants to know how to look inside a new file type.
#
# * An filetype_label line must be found within the code handling each
# file type. Any special shell characters must be enclosed in single
# quotes. These lines are listed (along with the Also lines) using the
# -v -l option.
#
# * A comment line beginning See gives a URL with more information about
# the file format. This information is not currently used by
# the program but is merely a note to the curious user.
#
# * A comment line beginning Also gives an alternative file name for the
# following file type similar to the format of filetype_label, except
# that the comment ends with the file extension and special shell characters
# must not be quoted. These lines are listed along with the filetype_label
# lines using the -v -l option.
#
# * Each case entry line matching a file extension must have a tab character
# in the first position. These extensions are listed using the -l option.
usage () {
echo 'fvi ver. 8-dev'
echo 'Displays metadata for many file types.'
echo ''
echo 'Usage: fvi [-v] [-?] [-h] [-l] [-t type] file1 [ file2 ... ]'
echo ' -v show verbose output (more than once for more verbosity)'
echo ' -h, -? show this help'
echo ' -l list supported file extensions (or file types with -v)'
echo ' -t treat the files as having the specified file extension'
exit 3
}
if [ X"$1" = X"-v" ] ; then
FV_VERBOSE=1
shift
if [ X"$1" = X"-v" ] ; then
FV_VERBOSE=2
shift
fi
fi
if [ $# -eq 0 -o X"$1" = X"-?" -o X"$1" = X"-h" ] ; then
usage
fi
if [ X"$1" = X"-l" ] ; then
# requires: textutils, sed
if [ X"$FV_VERBOSE" != X ] ; then
# Scan this script looking for label lines and Also comments
sed -n -e "s/'//g" -e 's/^[^#]\+filetype[_]label //p' \
-e 's/^[ ]*# Also \(.*\) [\.a-z0-9A-Z,_]*$/\1/p' "$0" | sort -f | uniq
else
echo 'Supported file extensions:'
# Scan this script looking for wildcard case statement entries
sed -n -e 's/^[ ][ ]*\(\*[^#)]*\)[)\\].*$/\1/p' "$0" | sed -e 's/ *| */\
/g' | sed -e 's/\*//g' -e '/^\**$/d' | sort -f | uniq | fmt
fi
exit
fi
staticfiletype=""
if [ X"$1" = X"-t" ] ; then
staticfiletype="$2"
# Make sure file type starts with . for comparision purposes
case "$staticfiletype" in
.*) ;;
*) staticfiletype=".$staticfiletype"
;;
esac
shift
shift
fi
if [ $# -eq 0 ] ; then
usage
fi
filetype_label () {
# Display the file type in verbose mode
if [ X"$FV_VERBOSE" != X ] ; then
echo "$*"
if [ X"$FV_VERBOSE" = X2 ] ; then
# echo the actual command used to display the file
set -x
fi
fi
}
# Make a filename starting with a dash - safe to provide a program that
# would interpret it as an option.
safefn () {
case "$1" in
-*) echo "./$1" ;;
*) echo "$1" ;;
esac
}
# Check if 'tar' needs the --wildcards option for globbing
# Set the TAR_WILDCARDS environment variable with the appropriate option
TAR_WILDCARDS=
checked_tar_wildcards=
check_tar_wildcards () {
if [ -n "$checked_tar_wildcards" ]; then
# We've already done the check
return
fi
if tar --help 2>&1 | grep '[-]-wildcards' >/dev/null; then
TAR_WILDCARDS=--wildcards
fi
checked_tar_wildcards=yes
}
for f in "$@" ; do
# "safe" filename guaranteed not to start with a dash
sf="`safefn "$f"`"
if [ X"$staticfiletype" = X"" ] ; then
filetype=`basename "$sf"`
else
filetype="$staticfiletype"
fi
echo "$f":
case "$filetype" in
# requires: unzip, xmlstarlet
*.3mf) filetype_label 3MF 3-D Manufacturing file
TMPFILE="`mktemp`"
unzip -pq "$sf" 3D/3dmodel.model > "${TMPFILE}"
# This could probably be combined into a single xmlstarlet invocation for speed
printf 'Name: '
xmlstarlet sel -t -v "/*[local-name()='model']/*[local-name()='metadata'][@name]" < "${TMPFILE}"
printf '\n'
xmlstarlet sel -t -v "count(/*[local-name()='model']/*[local-name()='resources']/*[local-name()='object'])" < "${TMPFILE}"
printf ' object(s)\n'
xmlstarlet sel -t -v "count(/*[local-name()='model']/*[local-name()='build']/*[local-name()='item'])" < "${TMPFILE}"
printf ' build item(s)\n'
xmlstarlet sel -t -v "count(/*[local-name()='model']/*[local-name()='resources']/*[local-name()='basematerials']/*[local-name()='base'])" < "${TMPFILE}"
printf ' material(s)\n'
rm -f "${TMPFILE}"
;;
# See https://p7zip.sourceforge.net/
# requires: p7zip
*.7z) filetype_label 7zip archive
7za l -slt -bso0 -- "$f" | sed '/^----------/,$d'
;;
# requires: unzip, xmlstarlet
*.amf) filetype_label Additive Manufacturing File
if [ "`dd if="$f" bs=1 count=2 2>/dev/null`" = "PK" ]; then
# If the amf file is zip compressed, uncompress it first
TMPFILE=`mktemp`
INFILE="${TMPFILE}"
unzip -pq "$sf" > "$INFILE"
else
TMPFILE=
INFILE="$f"
fi
# BUG: There will be no separators between names if they come from
# multiple objeccts. But, it's often the case that there is only a single
# object
xmlstarlet sel -t \
-o 'Name: ' -v "/amf/metadata[@type='name'] | /amf/object/metadata[@type='name']" -n \
-v "count(/amf/object)" -o " object(s)" -n \
-v "count(/amf/material)" -o ' material(s)' -n \
< "$INFILE"
if [ -n "$TMPFILE" ]; then
rm -f "$TMPFILE"
fi
;;
# requires Android SDK
*.apk) filetype_label Android package
aapt d --include-meta-data badging "$f"
;;
# See https://sourceforge.net/projects/avifile/
# requires: avifile-samples
*.avi) filetype_label Microsoft Audio Video Interleaved
avitype -- "$f"
;;
# requires: Java jdk
*.class) filetype_label Java compiled class file
javap "$sf" | grep -E '(^C)|(\{$)'
;;
# requires: openssl
*.crl) filetype_label X509 CRL
openssl crl -text -in "$f"
;;
# requires: openssl
*.csr) filetype_label X509 Certificate Signing Request
openssl req -text -noout -in "$f"
;;
# requires: xz
synthesis.hdlist.cz) filetype_label URPM synthesis file
printf "synthesis file for %d packages\n" \
"$(xz -qdc < "$f" | grep '^@info@' | wc -l)"
# Guess this info from the filenames
printf "primary architecture %s\n" \
"$(xz -qdc < "$f" | sed -n -Ee 's/^@info@[^@]+\.([^.@]+)@.*$/\1/p' | grep -v 'noarch' | head -1)"
# This could be the distro tag or a media tag
TAG="$(xz -qdc < "$f" | sed -n -Ee 's/^@info@[^@]+\.([^.]+)\.[^.]+@.*$/\1/p' | head -1)"
# Assume it's the distro tag if it has a version number
if ! printf "%s" "$TAG" | grep -q '[0-9]'; then
TAG="$(xz -qdc < "$f" | sed -n -Ee 's/^@info@[^@]+\.([^.]+)(\.[^.]+){2}@.*$/\1/p' | head -1).$TAG"
fi
printf "distribution tag %s\n" "$TAG"
;;
# See http://dar.linux.free.fr/
# requires: dar >= 2.7.0
*.dar) filetype_label Disk Archiver archive
dar -Q -q -vm -l "$f"
;;
# requires: db53-utils
# This extension is rather generic and often contains a gdbm, sqlite3
# or some other file.
*.db) filetype_label Berkeley Database
db53_stat -d "$f"
;;
# requires: tar
*.depot) filetype_label HP-UX package
tar xOf - catalog/INDEX < "$f"
;;
# requires: tar, gzip
*.depot.gz) filetype_label HP-UX package
gzip -dc -- "$f" | tar xOf - catalog/INDEX
;;
# requires: openssl
*.der) filetype_label DER certificate
openssl x509 -text -inform der -in "$f"
;;
# requires: binutils, gzip, tar, xz, zstd
# On a Debian system, this should use 'dpkg -I "$f"' instead
# Also OpenMoko package .opk
*.deb | *.opk) filetype_label Debian distribution archive
case "$(ar t -- "$f" control.tar.zst control.tar.xz control.tar.gz 2>/dev/null)" in
*zst) ar p -- "$f" control.tar.zst | zstd -dc | tar xOf - ./control ;;
*xz) ar p -- "$f" control.tar.xz | xz -qdc | tar xOf - ./control ;;
*gz) ar p -- "$f" control.tar.gz | gzip -qdc | tar xOf - ./control ;;
*) echo Error: unknown deb compression 1>&2 ;;
esac
;;
# needs Android SDK
*.dex) filetype_label Android Java class file
dexlist -- "$f"
;;
# hdiutil comes standard on OS X; use qemu-img elsewhere
# requires: <nothing> || qemu-img
*.dmg) filetype_label Mac OS X Disk Image
hdiutil imageinfo "$sf" || qemu-img info -- "$f"
;;
# requires: libdsk-progs
*.cfi) filetype_label CFI floppy disk image
# This type can't be auto-detected so it needs to be specified
dskid -type cfi -- "$f"
dsklabel -type cfi "$sf"
;;
# requires: libdsk-progs
*.dsk) filetype_label Floppy disk image
dskid -- "$f"
dsklabel "$sf"
;;
# requires: dtc || device-tree-compiler
*.dtb) filetype_label Device Tree Binary file
dtc -I dtb -O dts -o - -- "$f"
;;
# Used on macOS
*.dylib) filetype_label Mach dynamic library
otool -h -l -L "$sf"
;;
# requires: unzip
*.egg) filetype_label Python egg package
unzip -qp "$sf" EGG-INFO/PKG-INFO
;;
# requires: ebook-tools
*.epub) filetype_label EPub Document
einfo "$sf"
;;
# requires: pev || pefile (https://pypi.org/project/pefile/)
# Also Windows PE Dynamic Link Library .dll
*.exe | *.dll) filetype_label Windows PE executable
pescan -v "$sf" || python3 -m pefile "$f"
;;
# requires: flac
*.flac) filetype_label FLAC audio
metaflac --list -- "$f"
;;
# requires: gdbm
# These databases are often given a .db extension instead
*.gdbm) filetype_label GDBM database
echo 'set open=readonly;header;count;' | gdbmtool -q -- "$f"
;;
# requires: libungif-progs
*.gif) filetype_label GIF image
giftext < "$f"
;;
# Also GnuPG signature
# requires: gnupg2
# .sig is used a bit generically, but GPG is probably the most general
*.gpg | *.pgp | *.sig) filetype_label Gnu Privacy Guard/Pretty Good Privacy file
gpg --list-packets --list-only --no-autostart -- "$f"
;;
# See https://pypi.org/project/gpxpy/
# requires: gpxinfo || gpxpy
*.gpx) filetype_label GPS exchange format file
gpxinfo "$sf"
;;
# requires: libheif
*.heic | *.heif) filetype_label HEIF image
heif-info -- "$f"
;;
# See http://www.handhelds.org/ (defunct as of 2021)
# requires: binutils, file, grep, gzip, tar
*.ipk) filetype_label Itsy package
# Detect the old or new style ipk format
if file -- "$f" | egrep -iq 'Debian|ar archive' ; then
ar -p "$sf" control.tar.gz | gzip -dc | tar xOf -
else
# Internal file name may or may not be prefixed with ./
# which is what the \* catches.
check_tar_wildcards
gzip -dc -- "$f" | tar xOf - $TAR_WILDCARDS \*control.tar.gz | gzip -dc | tar xOf -
fi
;;
# requires: cdrecord
*.iso) filetype_label ISO9660 filesystem image file
isoinfo -d -i "$f"
;;
# requires: unzip
*.jar) filetype_label Java jar file
unzip -pqaa "$sf" META-INF/MANIFEST.MF | sed '/^$/,$d'
;;
# requires: system
*.journal) filetype_label journald log file
journalctl --header --file "$f"
;;
# requires: jhead || exiv2 || exif
*.jpg | *.jpeg | *.jfif) filetype_label JPEG image
jhead "$sf" || exiv2 pr "$sf" || exif -- "$f"
;;
# requires: openssl
*.key) filetype_label Private key
openssl asn1parse -in "$f"
;;
# requires: fv, lzip
*.lz) filetype_label lzip-compressed file
fv -t lz "$f"
;;
# requires: fv, lzop
*.lzo) filetype_label LZOP-compressed file
fv -t lzo "$f"
;;
# requires: libquicktime-progs
*.m4a) filetype_label Quicktime audio
qtinfo "$f"
;;
# requires: gettext
# requires: sed
*.mo | *.gmo) filetype_label Binary message catalog file
msgunfmt -- "$f" | sed '/^$/,$d'
;;
# requires: mkvtoolnix
*.mkv | *.webm) filetype_label Matroska video file
mkvinfo "$sf"
;;
# requires: advancecomp
*.mng) filetype_label Multiple-image Network Graphics file
advmng -l -- "$f"
;;
# requires: python-id3 || id3ed || mp3info || id3lib || id3v2 || mpgtx
*.mp3) filetype_label MP3 audio file
id3v2 -l "$sf" || listid3v2.py "$sf" || id3ed -i "$sf" || mp3info -- "$f" || id3info -- "$f" || tagmp3 show "$f"
;;
# requires: libquicktime-progs
*.mp4 | *.mpg4 | *.mov | *.qt | *.3gp) filetype_label Quicktime video
qtinfo "$f"
;;
# requires: mpgtx
*.mpg | *.mpeg | *.mpe | *.m1v | *.m2v) filetype_label MPEG video
mpginfo -- "$f"
;;
# requires: binutils
*.o | *.a | *.so | *.so.? | *.so.?? | *.so.???) filetype_label Object file/archive
objdump -afph -- "$f"
;;
# requires: vorbis-tools
*.ogg | *.ogv) filetype_label OGG audio/video
ogginfo -- "$f"
;;
# requires: wireshark-tools
*.pcap | *.pcapng | *.5vw | *.erf | *.trc0 | *.cap | *.tr1 | *.snoop | \
*.ncf | *.ncfx | *.bfr | *.pcap.gz | *.pcapng.gz | *.5vw.gz | \
*.erf.gz | *.trc0.gz | *.cap.gz | *.tr1.gz | *.snoop.gz | *.ncf.gz | \
*.ncfx.gz | *.bfr.gz) filetype_label Pcap network capture file
capinfos -- "$f"
;;
# requires: pilot-link
*.pdb | *.prc) filetype_label Palm Pilot file
pilot-file -Ha -- "$f"
;;
# requires: xpdf
*.pdf | *.ai) filetype_label Portable Document Format document
pdfinfo -- "$f"
;;
# Also X.509 certificate .crt
# Also X.509 CA certificate .cacrt
# requires: openssl || java-X-openjdk
*.pem | *.cacrt | *.crt) filetype_label PEM certificate
openssl crl2pkcs7 -nocrl -certfile "$f" | openssl pkcs7 -print_certs -text -noout || keytool -printcert -v -file "$f"
;;
# requires: pacman
*.pkg.tar | *.pkg.tar.xz | *.pkg.tar.zst | *.pkg.tar.bz2 | \
*.pkg.tar.gz) filetype_label Pacman package
pacman -Qip "$sf"
;;
# requires: pngtools
*.png) filetype_label Portable Network Graphics image
pnginfo "$sf"
;;
# requires: sed
*.po) filetype_label Text message catalog file
sed '/^$/,$d' < "$f"
;;
# requires: netpbm
*.ppm | *.pbm | *.pgm | *.pam | *.pnm) filetype_label Portable pixmap image
pamfile -- "$f"
;;
# requires: uncompyle6
*.pyc | *.pyd | *.pyo) filetype_label Python compiled file
uncompyle6 -- "$f" | grep '^#'
;;
# requires: qemu-img
*.qcow | *.qcow2 | *.qed | *.vpc | *.bochs | \
*.parallels) filetype_label QEMU disk image
qemu-img info -- "$f"
;;
# requires: unrar
*.rar | *.rsn) filetype_label RAR compressed archive
unrar vta -sl0 -idc -- "$f"
;;
# See http://www.rpm.org/
# requires: rpm
*.rpm | *.spm) filetype_label Red Hat RPM package
rpm -qip -- "$f"
;;
# requires: fv, python
*.rz) filetype_label rzip archive
fv -t rz "$f"
;;
# See https://sourceforge.net/projects/sistk/
# requires: DumpSIS
*.sis) filetype_label SymbianOS SIS installable package
DumpSIS.pl -e -- "$f" | sed '/^Files$/,$d'
;;
# See https://github.com/itkach/slob/
# requires: slob
*.slob) filetype_label Sorted List of Blobs dictionary
slob info -- "$f"
;;
# requires: sqlite3-tools
*.sqlite | *.sqlite3) filetype_label Sqlite database file
sqlite3 "$sf" .dbinfo "select 'Available Tables:';" .tables
;;
# See https://github.com/plougher/squashfs-tools/
# Also Snap package .snap
# requires: squashfs-tools
*.sqsh | *.squashfs | *.sqfs | *.snap) filetype_label Squashfs filesystem image
unsquashfs -s "$sf"
;;
# requires: python >= 3
*.stl) filetype_label STL model file
# Detect ASCII or binary format
if [ "`dd if="$f" bs=1 count=80 2>/dev/null | wc -l`" -gt 0 -a "`dd if="$f" bs=1 count=6 2>/dev/null | tr -d '\0'`" = "solid " -a "`dd if="$f" bs=1 count=1 skip=80 2>/dev/null | od -An -b`" != "000" ]; then
# ASCII stl format
sed -n -E -e '1s/^solid +//p' < "$f" | iconv -f windows-1252
grep "^[[:space:]]*facet " < "$f" | wc -l | tr -d ' \n'
echo " facets"
else
# Binary stl format
python3 - "$f" <<EOF
import struct, sys
with open(sys.argv[1], 'rb') as f:
comment = f.read(80)
z = comment.find(b'\x00')
if z >= 0:
comment = comment[0:z]
comment = comment.strip(b'\n').strip(b'\r').replace(b'\n', b' ').replace(b'\r', b' ').strip(b' ')
# This character encoding likely isn't always correct
print(comment.decode('windows-1252'))
length = struct.unpack('<I', f.read(4))[0]
print('%0d facets' % length)
EOF
fi
;;
# requires: imagemagick, gzip
*.svgz) filetype_label Compressed Scalable Vector Graphic image file
zcat -- "$f" | identify -verbose -
;;
# requires: swftools
*.swf) filetype_label Shockwave Flash file
swfdump "$sf"
;;
# See http://www.encode.ru/tc/ (defunct as of 2022)
# requires: python >= 3
# Note: the real file extension conflicts with Tellico files, so this
# is a made up one
*.tc-compressed) filetype_label tc-compressed file
python3 - "$f" <<EOF
import struct, sys, os
fn=sys.argv[1]
with open(fn, 'rb') as f:
length = struct.unpack('<I', f.read(4))[0]
basefn=os.path.basename(fn).rsplit('.')[0]
print(' length filename')
print('%10d %s' % (length, basefn))
EOF
;;
*.tc) filetype_label Tellico database
printf 'Database name: '
unzip -pq "$sf" tellico.xml | xmlstarlet sel -t -v "/*[local-name()='tellico']/*[local-name()='collection']/@title" -n 2> /dev/null
printf 'Number of records: '
unzip -pq "$sf" tellico.xml | xmlstarlet sel -t -v "count(/*[local-name()='tellico']/*[local-name()='collection']/*[local-name()='entry'])" -n 2>/dev/null
printf 'Number of images:'
unzip -pq "$sf" tellico.xml | xmlstarlet sel -t -v "count(/*[local-name()='tellico']/*[local-name()='collection']/*[local-name()='images']/*[local-name()='image'])" -n 2>/dev/null
echo 'Database fields:'
unzip -pq "$sf" tellico.xml | xmlstarlet sel -t -m "/*[local-name()='tellico']/*[local-name()='collection']/*[local-name()='fields']/*[local-name()='field']" -o ' ' -v '@name' -n 2>/dev/null
;;
# requires: samba-client
# Note: running as non-root usually results in
# "ERROR: could not init messaging context" since it needs to create
# a samba message lock file.
*.tdb) filetype_label TDB database file
printf 'Number of keys in database: '
dbwrap_tool --persistent --configfile=/dev/null -- "$f" listkeys | wc -l
;;
# See https://simonowen.com/samdisk/
# requires: samdisk
*.bpb | *.cfi | *.cpm | *.d2m | *.d4m | *.d80 | *.d81 | *.d88 | *.dfi | \
*.dmk | *.ds2 | *.dsc | *.dsk | *.dti | *.edsk | *.fdi | *.hfe | *.imd | \
*.ipf | *.lif | *.mbd | *.mgt | *.msa | *.opd | *.raw | *.raw | *.s24 | \
*.sad | *.sbt | *.scl | *.scp | *.sdf | *.td0 | *.trd | *.udi \
) filetype_label Floppy disk image file
samdisk info -- "$f"
;;
# Also Digital Negative Raw Image .dng
# requires: libtiff-progs
*.tif | *.tiff | *.dng) filetype_label Tagged Image File Format image
tiffinfo -- "$f" || tiffdump -- "$f"
;;
# requires: bittorrent
*.torrent) filetype_label BitTorrent torrent file
torrentinfo-console "$sf"
;;
# requires: gobject-introspection, xmlstarlet
*.typelib) filetype_label G-IR binary database
g-ir-generate -- "$f" | xmlstarlet sel -N x=http://www.gtk.org/introspection/core/1.0 -t -o 'Typelib for ' -v '/x:repository/x:namespace/@name' -o ' ' -v '/x:repository/x:namespace/@version' -o ' ' -v '/x:repository/x:namespace/@shared-library' -n -
;;
# .vmdk is actually a VMWare disk image, and .vhd{,x} are Microsoft formats
# but VirtualBox supports them as well.
# requires: virtualbox || qemu-img
*.vdi | *.vmdk | *.vhd | *.vhdx) filetype_label VirtualBox disk image
VBoxManage showmediuminfo -- "$f" || qemu-img info -- "$f"
;;
*.warc.gz) filetype_label Compressed Web Archive Collection file
gzip -dc -- "$f" | tr -d '\015' | sed -n -e 1d -e '2,/^$/{p;b' -e '}' -e p -e '/^$/q'
;;
# requires: wavplay
*.wav) filetype_label WAV audio file
wavplay -i -- "$f"
;;
# requires: unzip, jq
*.wacz) filetype_label Web Archive Collection Zipped
unzip -pq "$sf" datapackage.json | jq 'del(.resources)'
;;
# requires: unzip
*.whl) filetype_label Python wheel package
unzip -pq "$sf" '*.dist-info/METADATA' | sed '/^$/,$d'
;;
# zip archive .zip
# Also Android package .apk
# Also Apkmirror Android package .apkm
# Also Mozilla Java Cross Platform Installer .xpi
# Also Perl package .par
# Also Winamp compressed skin file .wsz,.wal
# Also Google Earth .kmz
# Also iPod Game .ipg
# Also OpenOffice Impress Presentation .sxi
# Also OpenOffice Drawing .sxd
# Also OpenOffice Math .sxm
# Also OpenOffice Writer Document .sxw
# Also OpenDocument .odt
# Also OpenDocument Drawing .odg
# Also OpenDocument Spreadsheet .ods
# Also OpenDocument Presentation .odp
# Also OpenDocument Formula .odf
# Also OpenDocument Drawing Template .otg
# Also OpenDocument Presentation Template .otp
# Also OpenDocument Spreadsheet Template .ots
# Also OpenDocument Presentation Template .otp
# Also OpenDocument Extension .oxt
# Also Quake3 packed file .pk3
# Also Nokia mobile phone theme .nth
# Also Microsoft Office Open XML .docx
# Also Microsoft Office Open XML with Macros .docm
# Also Microsoft Office Open XML .pptx
# Also Microsoft Office Open XML .xlsx
# Also EPub Document .epub
# Also Java Web Start .war
# Also XML Paper Specification .xps
# Also Syllable resource package .resource
# Also Syllable application package .application
# Also (unknown 3D package) .f3d
# Also Krita image .kra
# Also Scratch Project .sb2
# Also Scratch Project .sb3
# Also MuseScore music score .mscz
# SkyOS .pkg file are in .zip format, but the extension conflicts
# requires: unzip
*.zip | *.jar | *.xpi | *.par | *.wsz | *.wal | *.kmz | \
*.sxi | *.sxd | *.sxw | *.sxm | *.pk3 | *.ipg | *.nth | *.odt | \
*.ods | *.odp | *.odg | *.odf | *.oxt | \
*.otp | *.otg | *.ots | \
*.docx | *.pptx | *.xlsx | *.epub | *.apk | *.war | *.xps | \
*.resource | *.application | *.docm | *.f3d | *.kra | \
*.sb2 | *.sb3 | *.apkm | *.mscz)
filetype_label ZIP archive
zipinfo -h -z "$sf" | grep -v "^$"; zipinfo -l "$sf" | tail -1
;;
# Catch-all handlers. These must appear after the rest because they include
# more general extensions and occasionally duplicate but less-desirable
# handlers of previous extensions.
# Catch-all bitmapped image information displayer
# requires: imagemagick
*.raw | *.pcl | *.xpm | *.jbig | *.jp2 | *.png | *.fpx | *.pcx | \
*.xbm | *.webp | *.heic \
) filetype_label Bitmapped image file
identify -verbose -- "$f"
;;
# Also Windows Media compressed skin file .wmz
# Catch-all vector information displayer
# requires: imagemagick
*.ps | *.eps | *.hpgl | *.fig | *.cgm | *.gplt | \
*.rle | *.wmf | *.wmz | *.svg \
) filetype_label Vector image file
identify -verbose -- "$f"
;;
# Catch-all font information displayer
# requires: freetype2-demos
*.ttf | *.pfa | *.pfb | *.otf | *.woff \
) filetype_label Font file
ftdump "$sf"
;;
# Catch-all video and audio formats
# requires: ffmpeg
# First batch of extensions come from "ffmpeg -formats"
# which lists some things that probably aren't actual file extensions
*.3g2 | *.3gp | *.4xm | *.MTV | *.RoQ | *.aac | *.ac3 | *.adts | *.aiff | \
*.alaw | *.amr | *.apc | *.ape | *.asf | *.asf_stream | *.au | *.avi | \
*.avs | *.bethsoftvid | *.c93 | *.crc | *.daud | *.dirac | *.dsicin | *.dts | \
*.dv | *.dv1394 | *.dvd | *.dxa | *.ea | *.ffm | *.film_cpk | *.flac | *.flic | \
*.flv | *.framecrc | *.gif | *.gxf | *.h261 | *.h263 | *.h264 | *.idcin | \
*.image2 | *.image2pipe | *.ingenient | *.ipmovie | *.libnut | *.m4v |\
*.matroska | *.mjpeg | *.mm | *.mmf | *.mov | *.mov | *.m4a | \
*.mj2 | *.mp2 | *.mp3 | *.mp4 | *.mpc | *.mpeg | *.mpeg1video | \
*.mpeg2video | *.mpegts | *.mpegtsraw | *.mpegvideo | *.mpjpeg | *.mulaw |\
*.mxf | *.nsv | *.null | *.nut | *.nuv | *.ogg | *.oss | *.psp | *.psxstr | \
*.rawvideo | *.redir | *.rm | *.rtp | *.rtsp | *.s16be | *.s16le | *.s8 | \
*.sdp | *.shn | *.siff | *.smk | *.sol | *.svcd | *.swf | *.thp | \
*.tiertexseq | *.tta | *.txd | *.u16be | *.u16le | *.u8 | *.vc1 | \
*.vcd | *.video4linux | *.video4linux2 | *.vmd | *.vob | *.voc | \
*.wav | *.wc3movie | *.wsaud | *.wsvqa | *.wv | *.x11grab | *.yuv4mpegpipe | \
\
*.mpg4 | *.wmv | *.mts | \
*.amv | *.ram \
) filetype_label Video or audio file
ffprobe "$f" || ffmpeg -i "$f"
;;
# Plain compressed files must come after otherwise compressed files
# requires: fv, bzip2
# Also Stampede Linux package .slp
# Also bzip2-compressed tar archive .tbz,.tbz2
*.slp | *.tbz | *.tbz2 | \
*.bz2) filetype_label bzip2-compressed file
fv -t bz2 "$f"
;;
# requires: fv, gzip
*.cgz | *.pet | \
*.nif | *.epk | *.qpk | *.qpr | *.fpm | *.rub | \
*.kpr | *.chrt | *.kfo | *.flw | *.kil | *.ksp | *.kwd | \
*.tgz | *.taz | \
*.gz | *.Z | *.z) filetype_label gzip-compressed file
fv -t gz "$f"
;;
# requires: fv, lzma
# Also Tukaani Linux package .tlz
*.tlz | \
*.lzma) filetype_label LZMA compressed file
fv -t lzma "$f"
;;
# requires: fv, xz
# Also Midnight BSD ports package .mport
# Also xz-compressed tar archive .txz
*.txz | *.mport | \
*.xz) filetype_label XZ compressed file
fv -t xz "$f"
;;
# requires: fv, zstd
*.zst) filetype_label zstd-compressed file
fv -t zst "$f"
;;
# Unknown format
# requires: file
*) echo "$filetype: Unsupported file format." 1>&2
file -- "$f" 1>&2
# Indicate that an error has occurred
false
;;
esac
if [ X"$FV_VERBOSE" = X2 ] ; then
set +x
fi
# Save the return code of the last program run so we can return that from
# the script. This won't work for some of the metadata programs, but it's
# better than nothing.
rc=$?
echo ""
done
exit $rc