mirror of https://github.com/MidnightCommander/mc
Ticket #3570: reimplement xorriso part of iso9660 listing.
When xorriso is installed, iso9660 listing was done with `xorriso .. -lsl ..` per dir recursively. It was unbearably slow on iso images with lots of subdirs. For example, it took my machine 2 minutes to open debian-12.5.0-amd64-DVD-1.iso which contains 2627 dirs. This commit makes use of `xorriso .. -find / -exec lsdl ..` instead to list the whole directory tree in a single pass. Also, parsing of xorriso output has been reworked and as a result such previously missing items became visible in the listing: - symlinks - the boot catalog file Closes MidnightCommander/mc#196. Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
parent
794823b885
commit
bbcfda3c62
|
@ -11,6 +11,7 @@
|
|||
# Kachalov Anton <mouse@linux.ru.net>, 2003
|
||||
# Victor Ananjevsky <ananasik@gmail.com>, 2013
|
||||
# slava zanko <slavazanko@gmail.com>, 2013
|
||||
# slowpeek <slowpeek@users.noreply.github.com>, 2024
|
||||
#
|
||||
# This file is part of the Midnight Commander.
|
||||
#
|
||||
|
@ -33,27 +34,76 @@
|
|||
|
||||
XORRISO=$(which xorriso 2>/dev/null)
|
||||
|
||||
# This snippet is used to undo xorriso's Text_shellsafe(). Pseudocode for the
|
||||
# function:
|
||||
#
|
||||
# Text_shellsafe( s) {
|
||||
# return q(') replace(q('), q('"'"'), s) q(')
|
||||
# }
|
||||
#
|
||||
# Xorriso_ls() uses two formats for pathes:
|
||||
# - generic: Text_shellsafe(path)
|
||||
# - symlink: Text_shellsafe(link) q( -> ) Text_shellsafe(target)
|
||||
#
|
||||
# References in xorriso sources:
|
||||
# - iso_tree.c:Xorriso_ls()
|
||||
# - text_io.c:Xorriso_esc_filepath()
|
||||
# - misc_funct.c:Text_shellsafe()
|
||||
awk_xorriso_unesc=$(cat <<'EOF'
|
||||
{
|
||||
# Start of the path part
|
||||
i = index($0, "'")
|
||||
|
||||
s = substr($0, i)
|
||||
# The path part with the wrapping quotes removed
|
||||
s = substr(s, 2, length(s)-2)
|
||||
|
||||
if (substr($0, 1, 1) == "l") {
|
||||
s1=s
|
||||
if (gsub("->", "", s1) > 1) {
|
||||
# Ambiguity: either the link or its target contains q(->) in
|
||||
# addition to the link/target delimiter
|
||||
next
|
||||
}
|
||||
|
||||
j = index(s, "' -> '")
|
||||
# link -> target with the wrapping quotes removed from both
|
||||
s = substr(s, 1, j-1) " -> " substr(s, j+6)
|
||||
} else if (index(s, "->")) {
|
||||
# Ambiguity: not a symlink, but there is q(->)
|
||||
next
|
||||
}
|
||||
|
||||
gsub("'\"'\"'", "'", s)
|
||||
print substr($0, 1, i-1) s
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
xorriso_list() {
|
||||
if test -z "$XORRISO"; then
|
||||
return 1
|
||||
fi
|
||||
local dir attr ln usr gr sz dt1 dt2 dt3 nm len name lsl r
|
||||
dir="${2:-/}"
|
||||
lsl=$( $XORRISO -abort_on FATAL -dev stdio:"$1" -cd "$dir" -lsl 2> /dev/null )
|
||||
r=$?
|
||||
test $r -gt 0 && return $r
|
||||
|
||||
echo "$lsl" | grep "^[-d]" | \
|
||||
while read attr ln usr gr sz dt1 dt2 dt3 nm ; do
|
||||
len=$((${#nm} - 1))
|
||||
name=$(printf -- "$nm" | cut -c2-$len) # remove quotes
|
||||
local temp_ls
|
||||
temp_ls=$(mktemp "${MC_TMPDIR:-/tmp}"/mc-iso9660.XXXXXX) || return 1
|
||||
|
||||
if test $(printf -- "$attr" | cut -c1-1) != "d"; then
|
||||
printf -- "%s %s %s %s %s %s %s %s %s/%s\n" "$attr" "$ln" "$usr" "$gr" "$sz" "$dt1" "$dt2" "$dt3" "$dir" "$name"
|
||||
else
|
||||
xorriso_list "$1" "$dir/$name"
|
||||
fi
|
||||
done
|
||||
"$XORRISO" -abort_on FATAL -dev stdio:"$1" -find / -exec lsdl 2>/dev/null >"$temp_ls"
|
||||
local r=$?
|
||||
|
||||
if [ "$r" != 0 ]; then
|
||||
rm -f "$temp_ls"
|
||||
return "$r"
|
||||
fi
|
||||
|
||||
# The first line is /, skip it
|
||||
tail -n+2 "$temp_ls" |
|
||||
# disk_ops.c:Xorriso_format_ls_l() prints the boot catalog file as of
|
||||
# type "e". Make it a generic file
|
||||
sed -E 's,^e,-,' |
|
||||
@AWK@ "$awk_xorriso_unesc"
|
||||
|
||||
rm -f "$temp_ls"
|
||||
}
|
||||
|
||||
xorriso_copyout() {
|
||||
|
|
Loading…
Reference in New Issue