2 # Midnight Commander - ISO9660 VFS for MC
3 # based on lslR by Tomas Novak <tnovak@ipex.cz> April 2000
5 # Copyright (C) 2000, 2003
6 # The Free Software Foundation, Inc.
9 # Michael Shigorin <mike@altlinux.org>,
10 # Grigory Milev <week@altlinux.org>,
11 # Kachalov Anton <mouse@linux.ru.net>, 2003
12 # Victor Ananjevsky <ananasik@gmail.com>, 2013
13 # slava zanko <slavazanko@gmail.com>, 2013
14 # slowpeek <slowpeek@users.noreply.github.com>, 2024
16 # This file is part of the Midnight Commander.
18 # The Midnight Commander is free software: you can redistribute it
19 # and/or modify it under the terms of the GNU General Public License as
20 # published by the Free Software Foundation, either version 3 of the License,
21 # or (at your option) any later version.
23 # The Midnight Commander is distributed in the hope that it will be useful,
24 # but WITHOUT ANY WARRANTY; without even the implied warranty of
25 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 # GNU General Public License for more details.
28 # You should have received a copy of the GNU General Public License
29 # along with this program. If not, see <https://www.gnu.org/licenses/>.
31 #*** include section (source functions, for example) *******************
33 #*** file scope functions **********************************************
35 XORRISO
=`command -v xorriso 2>/dev/null`
37 # This snippet is used to undo xorriso's Text_shellsafe(). Pseudocode for the
40 # Text_shellsafe( s) {
41 # return q(') replace(q('), q('"'"'), s) q(')
44 # Xorriso_ls() uses two formats for pathes:
45 # - generic: Text_shellsafe(path)
46 # - symlink: Text_shellsafe(link) q( -> ) Text_shellsafe(target)
48 # References in xorriso sources:
49 # - iso_tree.c:Xorriso_ls()
50 # - text_io.c:Xorriso_esc_filepath()
51 # - misc_funct.c:Text_shellsafe()
52 awk_xorriso_unesc
=`cat <<'EOF'
54 # Start of the path part
58 # The path part with the wrapping quotes removed
59 s = substr(s, 2, length(s)-2)
61 if (substr($0, 1, 1) == "l") {
63 if (gsub("->", "", s1) > 1) {
64 # Ambiguity: either the link or its target contains q(->) in
65 # addition to the link/target delimiter
69 j = index(s, "' -> '")
70 # link -> target with the wrapping quotes removed from both
71 s = substr(s, 1, j-1) " -> " substr(s, j+6)
72 } else if (index(s, "->")) {
73 # Ambiguity: not a symlink, but there is q(->)
77 gsub("'\"'\"'", "'", s)
78 print substr($0, 1, i-1) s
84 if test -z "$XORRISO"; then
88 temp_ls
=`mktemp "${MC_TMPDIR:-/tmp}"/mc-iso9660.XXXXXX` ||
return 1
90 # $XORRISO must be unquoted here to hook into the testing framework
91 $XORRISO -abort_on FATAL
-dev stdio
:"$1" -find / -exec lsdl
2>/dev
/null
>"$temp_ls"
94 if [ "$r" != 0 ]; then
99 # The first line is /, skip it
100 sed 1,1d
"$temp_ls" |
101 # disk_ops.c:Xorriso_format_ls_l() prints the boot catalog file as of
102 # type "e". Make it a generic file
104 @AWK@
"$awk_xorriso_unesc"
110 if test -z "$XORRISO"; then
113 $XORRISO -dev stdio
:"$1" -osirrox on
-extract "$2" "$3" >/dev
/null
2>&1
117 if test -z "$XORRISO"; then
120 $XORRISO -dev stdio
:"$1" -cpr "$3" "$2" >/dev
/null
2>&1
124 if test -z "$XORRISO"; then
127 $XORRISO -dev stdio
:"$1" -mkdir "$2" >/dev
/null
2>&1
131 if test -z "$XORRISO"; then
134 $XORRISO -dev stdio
:"$1" -rmdir "$2" >/dev
/null
2>&1
138 if test -z "$XORRISO"; then
141 $XORRISO -dev stdio
:"$1" -rm "$2" >/dev
/null
2>&1
144 # tested to comply with isoinfo 2.0's output
146 ISOINFO
=`command -v isoinfo 2>/dev/null`
147 if test -z "$ISOINFO"; then
148 echo "isoinfo not found" >&2
152 CHARSET
=`locale charmap 2>/dev/null`
153 if test -z "$CHARSET"; then
154 CHARSET
=`locale 2>/dev/null | grep LC_CTYPE | sed -n -e 's/.*\.\(.*\)"$/\1/p'`
156 if test -n "$CHARSET"; then
157 CHARSET
=`echo "$CHARSET" | tr '[A-Z]' '[a-z]' | sed -e 's/^iso-/iso/'`
158 $ISOINFO -j $CHARSET -i /dev
/null
2>&1 |
grep "Iconv not yet supported\|Unknown charset" >/dev
/null
&& CHARSET
=
160 if test -n "$CHARSET"; then
161 JOLIET_OPT
="-j $CHARSET -J"
166 ISOINFO_D_I
=`$ISOINFO -d -i "$1" 2>/dev/null`
167 ISOINFO
="$ISOINFO -R"
169 echo "$ISOINFO_D_I" |
grep "UCS level 1\|NO Joliet" > /dev
/null || ISOINFO
="$ISOINFO $JOLIET_OPT"
171 if [ `echo "$ISOINFO_D_I" | grep "Joliet with UCS level 3 found" | wc -l` = 1 \
172 -a `echo "$ISOINFO_D_I" | grep "NO Rock Ridge" | wc -l` = 1 ] ; then
178 # left as a reminder to implement compressed image support =)
180 *.lz
) MYCAT
="lzip -dc";;
181 *.lz4
) MYCAT
="lz4 -dc";;
182 *.lzma
) MYCAT
="lzma -dc";;
183 *.lzo
) MYCAT
="lzop -dc";;
184 *.xz
) MYCAT
="xz -dc";;
185 *.zst
) MYCAT
="zstd -dc";;
186 *.bz2
) MYCAT
="bzip2 -dc";;
187 *.gz
) MYCAT
="gzip -dc";;
188 *.z
) MYCAT
="gzip -dc";;
189 *.Z
) MYCAT
="gzip -dc";;
193 lsl
=`$ISOINFO -l -i "$1" 2>/dev/null`
195 test $r -gt 0 && return $r
197 echo "$lsl" | @AWK@
-v SEMICOLON
=$SEMICOLON '
200 # Pattern to match 8 first fields.
202 rx = "^" rx rx rx rx rx rx rx rx;
203 irx = "^\\[ *-?[0-9]* *[0-9]+\\] +";
206 /^d---------/ { next }
207 /^Directory listing of [^ ].*$/ {
214 attr=substr($0, 1, length($0)-length(name))
215 # strip inodes and extra dir entries; fix perms
217 sub("^---------- 0 0 0", "-r--r--r-- 1 0 0 ", attr)
219 # for Joliet UCS level 3
220 if (SEMICOLON == "YES") sub(";1$", "", name);
221 ## sub(";[0-9]+$", "", name) ## would break copyout
223 if (name == ".") next;
224 if (name == "..") next;
225 printf "%s%s%s\n", attr, dir, name
230 if [ "x$SEMICOLON" = "xYES" ]; then
231 $ISOINFO -i "$1" -x "/$2;1" 2>/dev
/null
> "$3"
233 $ISOINFO -i "$1" -x "/$2" 2>/dev
/null
> "$3"
237 #*** main code *********************************************************
246 if [ -n "${MC_TEST_EXTFS_LIST_CMD:-}" ]; then
247 case "${MC_TEST_EXTFS_ISO9660_TOOL}" in
249 XORRISO
="$MC_TEST_EXTFS_LIST_CMD"
250 xorriso_list
"$@" ||
exit 1
260 xorriso_list
"$@" ||
{
261 test_iso
"$@" ||
exit 1
262 mcisofs_list
"$@" ||
exit 1
273 xorriso_rmdir
"$@" ||
{
279 xorriso_mkdir
"$@" ||
{
285 xorriso_copyin
"$@" ||
{
291 xorriso_copyout
"$@" ||
{
292 test_iso
"$@" ||
exit 1
293 mcisofs_copyout
"$@" ||
exit 1