Midnight commander opens zip archives with image/PDF viewer instead of listing the contents

534 Views Asked by At

I am using mc 4.8.27 in Kubuntu 22.04. My problem is: When I hit Enter on a zip archive (but not tar or tgz) it opens in the gwenview image viewer if there are any images among its contents, and in the okular PDF viewer if there are any PDFs but no images. This is utterly bizarre for archives with mixed content and anyway never what I want; I want it to open any archive as a directory listing of its contents. The view action (F3 in mc) also doesn't work on zip archives; it fails with error messages about bad image or PDF formats. The entry in the extension file ~/.config/mc/mc.ext reads

# zip
type/^([Zz][Ii][Pp])\ archive
    Open=%cd %p/uzip://
    View=%view{ascii} unzip -v %f

So far I have tried: Set environment variable MC_XDG_OPEN=/usr/bin/false - it appears in the mc subshell but makes no change in behavior. Made the same variable change in /usr/lib/mc/ext.d/archive.sh and .../image.sh, still without effect. Typing cd file.zip/uzip:// on the mc command line works as expected but replacing the real file name with the macros %f or %p makes mc core dump, leaving the terminal or tab unusably locked. My unzip seems to be version 6.0-26.

Edit: The complete (well, minus the large block of comments at the start) extension file is

### GIT Repo ###
# gitfs changeset
regex/^\[git\]
    Open=%cd %p/changesetfs://
    View=%cd %p/patchsetfs://

### Archives ###

# .tgz, .tpz, .tar.gz, .tar.z, .tar.Z, .ipk
regex/\.t([gp]?z|ar\.g?[zZ])$|\.ipk|\.gem$
    Open=%cd %p/utar://
    View=%view{ascii} gzip -dc %f 2>/dev/null | tar tvvf -

regex/\.tar\.bz$
    # Open=%cd %p/utar://
    View=%view{ascii} bzip -dc %f 2>/dev/null | tar tvvf -

regex/\.t(ar\.bz2|bz2?|b2)$
    Open=%cd %p/utar://
    View=%view{ascii} bzip2 -dc %f 2>/dev/null | tar tvvf -

# .tar.lzma, .tlz
regex/\.t(ar\.lzma|lz)$
    Open=%cd %p/utar://
    View=%view{ascii} lzma -dc %f 2>/dev/null | tar tvvf -

# .tar.xz, .txz
regex/\.t(ar\.xz|xz)$
    Open=%cd %p/utar://
    View=%view{ascii} xz -dc %f 2>/dev/null | tar tvvf -

# .tar.F - used in QNX
regex/\.tar\.F$
    # Open=%cd %p/utar://
    View=%view{ascii} freeze -dc %f 2>/dev/null | tar tvvf -

# .qpr/.qpk - QNX Neutrino package installer files
regex/\.(qp[rk])$
    Open=%cd %p/utar://
    View=%view{ascii} gzip -dc %f 2>/dev/null | tar tvvf -

# tar
regex/\.(tar|TAR)$
    Open=%cd %p/utar://
    View=%view{ascii} tar tvvf - < %f

# lha
type/^LHa\ .*archive
    Open=%cd %p/ulha://
    View=%view{ascii} lha l %f

# arj
regex/\.a(rj|[0-9][0-9])$
    Open=%cd %p/uarj://
    View=%view{ascii} unarj l %f

# cab
regex/\.([cC][aA][bB])$
    Open=%cd %p/ucab://
    View=%view{ascii} cabextract -l %f

# ha
regex/\.([Hh][Aa])$
    Open=%cd %p/uha://
    View=%view{ascii} ha lf %f

# rar
regex/\.[rR]([aA][rR]|[0-9][0-9])$
    Open=%cd %p/urar://
    View=%view{ascii} rar v -c- %f

# ALZip
regex/\.(alz|ALZ)$
    Open=%cd %p/ualz://
    View=%view{ascii} unalz -l %f

# cpio
shell/.cpio.Z
    Open=%cd %p/ucpio://
    View=%view{ascii} gzip -dc %f | cpio -itv 2>/dev/null

shell/.cpio.xz
    Open=%cd %p/ucpio://
    View=%view{ascii} xz -dc %f | cpio -itv 2>/dev/null

shell/.cpio.gz
    Open=%cd %p/ucpio://
    View=%view{ascii} gzip -dc %f | cpio -itv 2>/dev/null

shell/.cpio
    Open=%cd %p/ucpio://
    View=%view{ascii} cpio -itv < %f 2>/dev/null

# ls-lR
regex/(^|\.)ls-?lR(\.gz|Z|bz2)$
    Open=%cd %p/lslR://

# patch
regex/\.(diff|patch)(\.bz2)$
    Open=%cd %p/patchfs://
    View=%view{ascii} bzip2 -dc %f 2>/dev/null

regex/\.(diff|patch)(\.(gz|Z))$
    Open=%cd %p/patchfs://
    View=%view{ascii} gzip -dc %f 2>/dev/null

regex/\.(diff|patch)$
    Open=%cd %p/patchfs://
    View=%view{ascii} /bin/cat %f 2>/dev/null

# ar library
regex/\.s?a$
    Open=%cd %p/uar://
    #Open=%view{ascii} ar tv %f
    View=%view{ascii} file %f && nm -C %f

# trpm
regex/\.trpm$
    Open=%cd %p/trpm://
    View=%view{ascii} rpm -qivl --scripts `basename %p .trpm`

# RPM packages (SuSE uses *.spm for source packages)
regex/\.(src\.rpm|spm)$
    Open=%cd %p/rpm://
    View=%view{ascii} if rpm --nosignature --version >/dev/null 2>&1; then RPM="rpm --nosignature" ; else RPM="rpm" ; fi ; $RPM -qivlp --scripts %f

regex/\.rpm$
    Open=%cd %p/rpm://
    View=%view{ascii} if rpm --nosignature --version >/dev/null 2>&1; then RPM="rpm --nosignature" ; else RPM="rpm" ; fi ; $RPM -qivlp --scripts %f

# deb
regex/\.u?deb$
    Open=%cd %p/deb://
    View=%view{ascii} dpkg-deb -I %f && echo && dpkg-deb -c %f

# dpkg
shell/.debd
        Open=%cd %p/debd://
        View=%view{ascii} dpkg -s `echo %p | sed 's/\([0-9a-z.-]*\).*/\1/'`
# apt
shell/.deba
        Open=%cd %p/deba://
        View=%view{ascii} apt-cache show `echo %p | sed 's/\([0-9a-z.-]*\).*/\1/'`

# ISO9660
regex/\.([iI][sS][oO])$
    Open=%cd %p/iso9660://
    View=%view{ascii} isoinfo -l -i %f

# 7zip archives (they are not man pages)
regex/\.(7z|7Z)$
    Open=%cd %p/u7z://
    View=%view{ascii} 7za l %f 2>/dev/null

# Mailboxes
type/^ASCII\ mail\ text
    Open=%cd %p/mailfs://


### Sources ###

# C
shell/.c
    Include=editor

# Fortran
shell/.f
    Include=editor

# Header
regex/\.(h|hpp)$
    Include=editor

# Asm
shell/.s
    Include=editor

# C++
regex/\.(C|cc|cpp)$
    Include=editor

include/editor
    Open=%var{EDITOR:vi} %f

# .so libraries
regex/\.(so|so\.[0-9\.]*)$
    View=%view{ascii} file %f && nm -C -D %f

# Object
type/^ELF
    #Open=%var{PAGER:more} %f
    View=%view{ascii} file %f && nm -C %f

### Documentation ###

# Texinfo
regex/\.(te?xi|texinfo)$

# GNU Info page
type/^Info\ text
    Open=info -f %f

shell/.info
    Open=info -f %f

# Exception: .3gp are video files not manual pages
regex/\.(3[gG][pP])$
    Include=video

# Exception: .264 are special video files not manual pages
regex/\.[hH]?264$
    Open=h264vw %f
    View=(exiftool %f && echo -n "Hit <CR> to return: " && read x)

# Exception: .3mf is a Cura project archive
regex/\.3mf$
    Open=%cd %p/uzip://
    View=%view{ascii} unzip -v %f

# Manual page
regex/(([^0-9]|^[^\.]*)\.([1-9][A-Za-z]*|[ln])|\.man)$
    Open=case %d/%f in */log/*|*/logs/*) cat %f ;; *) { zsoelim %f 2>/dev/null || cat %f; } | nroff -c -Tlatin1 -mandoc ;; esac | %var{PAGER:more}
    View=%view{ascii,nroff} case %d/%f in */log/*|*/logs/*) cat %f ;; *) { zsoelim %f 2>/dev/null || cat %f; } | nroff -c -Tlatin1 -mandoc ;; esac

# Perl pod page
shell/.pod
    Open=pod2man %f | nroff -c -Tlatin1 -mandoc | %var{PAGER:more}
    View=%view{ascii,nroff} pod2man %f | nroff -c -Tlatin1 -mandoc

# Troff with me macros.
# Exception - "read.me" is not a nroff file.
shell/read.me
    Open=
    View=

shell/.me
    Open=nroff -c -Tlatin1 -me %f | %var{PAGER:more}
    View=%view{ascii,nroff} nroff -c -Tlatin1 -me %f

# Troff with ms macros.
shell/.ms
    Open=nroff -c -Tlatin1 -ms %f | %var{PAGER:more}
    View=%view{ascii,nroff} nroff -c -Tlatin1 -ms %f

# Manual page - compressed
regex/([^0-9]|^[^\.]*)\.([1-9][A-Za-z]*|[ln])\.g?[Zz]$
    Open=case %d/%f in */log/*|*/logs/*) gzip -dc %f ;; *) gzip -dc %f | nroff -c -Tlatin1 -mandoc ;; esac | %var{PAGER:more}
    View=%view{ascii,nroff} case %d/%f in */log/*|*/logs/*) gzip -dc %f ;; *) gzip -dc %f | nroff -c -Tlatin1 -mandoc ;; esac

regex/([^0-9]|^[^\.]*)\.([1-9][A-Za-z]*|[ln])\.bz$
    Open=case %d/%f in */log/*|*/logs/*) bzip -dc %f ;; *) bzip -dc %f | nroff -c -Tlatin1 -mandoc ;; esac | %var{PAGER:more}
    View=%view{ascii,nroff} case %d/%f in */log/*|*/logs/*) bzip -dc %f ;; *) bzip -dc %f | nroff -c -Tlatin1 -mandoc ;; esac

regex/([^0-9]|^[^\.]*)\.([1-9][A-Za-z]*|[ln])\.bz2$
    Open=case %d/%f in */log/*|*/logs/*) bzip2 -dc %f ;; *) bzip2 -dc %f | nroff -c -Tlatin1 -mandoc ;; esac | %var{PAGER:more}
    View=%view{ascii,nroff} case %d/%f in */log/*|*/logs/*) bzip2 -dc %f ;; *) bzip2 -dc %f | nroff -c -Tlatin1 -mandoc ;; esac

regex/([^0-9]|^[^\.]*)\.([1-9][A-Za-z]*|[ln])\.lzma$
    Open=case %d/%f in */log/*|*/logs/*) lzma -dc %f ;; *) lzma -dc %f | nroff -c -Tlatin1 -mandoc ;; esac | %var{PAGER:more}
    View=%view{ascii,nroff} case %d/%f in */log/*|*/logs/*) lzma -dc %f ;; *) lzma -dc %f | nroff -c -Tlatin1 -mandoc ;; esac

regex/([^0-9]|^[^\.]*)\.([1-9][A-Za-z]*|[ln])\.xz$
    Open=case %d/%f in */log/*|*/logs/*) xz -dc %f ;; *) xz -dc %f | nroff -c -Tlatin1 -mandoc ;; esac | %var{PAGER:more}
    View=%view{ascii,nroff} case %d/%f in */log/*|*/logs/*) xz -dc %f ;; *) xz -dc %f | nroff -c -Tlatin1 -mandoc ;; esac

# CHM
regex/\.(chm|CHM)$
    Open=which kchmviewer > /dev/null 2>&1 && (kchmviewer %f &) || (xchm %f &)

### Images ###

type/^GIF
    Include=image

type/^JPEG
    Include=image
    View=%view{ascii} identify %f; test -x /usr/bin/exiftool && echo && ( exiftool -s %f ) 2>/dev/null

type/^PC\ bitmap
    Include=image

type/^PNG
    Include=image

type/^TIFF
    Include=image

type/^PBM
    Include=image

type/^PGM
    Include=image

type/^PPM
    Include=image

type/^Netpbm
    Include=image

shell/.xcf
    Open=(gimp %f &)

shell/.xbm
    Open=bitmap %f

shell/.xpm
    Include=image
    View=sxpm %f

shell/.ico
    Include=image

include/image
    Open=(gwenview %f &)
    View=%view{ascii} identify %f
    #View=%view{ascii} asciiview %f

shell/.gpx
    Open=(gpsprune %f &)

shell/.pfs
    Open=(photofilmstrip %f &)
    View=sqlitebrowser %f
    Edit=(sqlitebrowser %f &)


### Sound files ###

regex/\.([wW][aA][vV]|[sS][nN][dD]|[vV][oO][cC]|[aA][uU]|[sS][mM][pP]|[aA][iI][fF][fF]|[sS][nN][dD])$
#       Open=if [ "$DISPLAY" = "" ]; then play %f; else (xmms %f >/dev/null 2>&1 &); fi
#   Open=/usr/bin/mpg123 -K %f
    Open=melt %f
    View=%view{ascii} /usr/bin/soxi %f |sed 1,/Encoding/d

#regex/\.([mM][oO][dD]|[sS]3[mM]|[xX][mM]|[iI][tT]|[mM][tT][mM]|669|[sS][tT][mM]|[uU][lL][tT]|[fF][aA][rR])$
#       Open=mikmod %f
#       #Open=tracker %f
#
#regex/\.([wW][aA][wW]22)$
#       Open=vplay -s 22 %f

regex/\.([mM][pP]3)$
#   Open=if [ "$DISPLAY" = "" ]; then mpg123 %f; else (xmms %f >/dev/null 2>&1 &); fi
#   Open=mpg123 -C %s
#   Open=mpg321 -K %s
    Open=melt %s
    View=%view{ascii} /usr/bin/soxi %f |sed 1,/Encoding/d
#   View=%view{ascii} mpg123 -vtn1 %f 2>&1 | sed -n '/^Title/,/^Comment/p;/^MPEG/,/^Audio/p'

regex/\.([oO][gG][gG|aA|vV|xX])$
#   Open=if [ "$DISPLAY" = "" ]; then ogg123 %f; else (xmms %f >/dev/null 2>&1 &); fi
#   Open=mpg123 -C %f
    Open=melt %s
    View=%view{ascii} /usr/bin/soxi %f |sed 1,/Encoding/d

#regex/\.([sS][pP][xX]|[fF][lL][aA][cC])$
#   Open=if [ "$DISPLAY" = "" ]; then play %f; else (xmms %f >/dev/null 2>&1 &); fi
#
#regex/\.([mM][iI][dD][iI]?|[rR][mM][iI][dD]?)$
#   Open=timidity %f

regex/\.([wW][mM][aA])$
#   Open=mplayer -vo null %f
#   Open=mplayer %f
    Open=melt %f
    View=%view{ascii} mplayer -quiet -slave -frames 0 -vo null -ao null -identify %f 2>/dev/null | tail +13 || file %f


### Play lists ###

regex/\.([mM]3[uU]|[pP][lL][sS])$
    Open=mplayer -vo null %f
#   Open=if [ -z "$DISPLAY" ]; then mplayer -vo null -playlist %f; else (xmms -p %f >/dev/null 2>&1 &); fi

shell/.amz
    Open=clamz %f


### Video ###

shell/REC*.([aA][vV][iI])$
    open=cvlc %f --demux h264 --h264-fps=5 --play-and-exit

regex/\.([aA][vV][iI])$
    Include=video

regex/\.([aA][sS][fFxX])$
    Include=video

regex/\.([dD][iI][vV][xX])$
    Include=video

regex/\.([mM][kK][vV])$
    Include=video

regex/\.([mM][oO][vV]|[qQ][tT])$
    Include=video

regex/\.([mM][pP]4|[mM][pP][eE]?[gG]|[mM]4[vV])$
    Include=video

# MPEG-2 TS container + H.264 codec
regex/\.([mM][tT][sS])$
    Include=video

regex/\.([vV][oO][bB])$
    Include=video

regex/\.([wW][mM][vV])$
    Include=video

regex/\.([fF][lL][iIcCvV])$
    Include=video

regex/\.([oO][gG][mM])$
    Include=video

regex/\.([rR][aA]?[mM])$
    Open=(realplay %f >/dev/null 2>&1 &)

include/video
    Open=(vlc %f >/dev/null 2>&1 &)
    #Open=(dragon %f >/dev/null 2>&1 &)
    #Open=(gtv %f >/dev/null 2>&1 &)
    #Open=(xanim %f >/dev/null 2>&1 &)
    View=(exiftool %f && echo -n "Hit <CR> to return: " && read x)


### Documents ###

# Postscript
type/^PostScript
    Open=(okular -p 1 %f &)
    View=%view{ascii} ps2ascii %f

# PDF
type/^PDF
    #Open=(acroread %f &)
    Open=(okular %f &)
    #Open=(ghostview %f &)
    #Open=(mupdf %f &)
    View=%view{ascii} pdftotext %f -
    Edit=(flpsed %f &)

# The following code very ugly and should not be taken as example.
# It should be cleaned up when the new format of mc.ext is developed.

# html
regex/\.([hH][tT][mM][lL]?)$
    Open=(if test -n "" && test -n "$DISPLAY"; then ( file://%d/%p &) 1>&2; else links %f || elinks -force-html %f || ${PAGER:-more} %f; fi) 2>/dev/null
    View=%view{ascii} links -dump %f 2>/dev/null || w3m -dump %f 2>/dev/null || elinks -dump -force-html %f

# StarOffice 5.2
shell/.sdw
    Open=(libreoffice %f &)

# StarOffice 6 and OpenOffice.org formats
regex/\.(odt|ott|sxw|stw|ods|ots|sxc|stc|odp|otp|sxi|sti|odg|otg|sxd|std|odb|odf|sxm|odm|sxg)$
    Open=(libreoffice %f &)
    View=%view{ascii} odt2txt %f

# AbiWord
shell/.abw
    Open=(abiword %f &)

# Microsoft Word Document
regex/\.([Dd][oO][cCtT][xX]?|[Ww][rR][iI])$
    Open=(libreoffice --writer %f >/dev/null 2>&1 &)
    View=%view{ascii} antiword -t %f || catdoc -w %f || word2x -f text %f - || strings %f
type/^Microsoft\ Word
    Open=(libreoffice --writer %f >/dev/null 2>&1 &)
    View=%view{ascii} antiword -t %f || catdoc -w %f || word2x -f text %f - || strings %f

# RTF document
regex/\.([rR][tT][fF])$
    Open=(libreoffice --writer %f >/dev/null 2>&1 &)

# Microsoft Excel Worksheet
regex/\.([xX][lL][sSwW])$
    Open=(libreoffice --calc %f >/dev/null 2>&1 &)
    View=%view{ascii} xls2csv %f || strings %f
type/^Microsoft\ Excel
    Open=(libreoffice --calc %f >/dev/null 2>&1 &)
    View=%view{ascii} xls2csv %f || strings %f

# Use OpenOffice.org to open any MS Office documents
type/^Microsoft\ Office\ Document
    Open=(libreoffice %f &)
# powerpoint
regex/\.([pP][pP][tT][xX]?)$
    Open=(libreoffice --impress %f >/dev/null 2>&1 &)

# Framemaker
type/^FrameMaker
    Open=fmclient -f %f

# DVI
regex/\.([dD][vV][iI])$
    Open=run-mailcap %f 2>&1 &
    View=%view{ascii} catdvi %f

# TeX
regex/\.([Tt][Ee][Xx])$
    Include=editor

# DjVu
regex/\.(djvu|DJVU)$
    Open=djview %f &

# epub e-books
regex/\.epub
    Open=okular %f &
    View=lsar -l %f

### Miscellaneous ###

# Makefile
regex/[Mm]akefile$
    Open=make -f %f %{Enter parameters}

# Imakefile
shell/Imakefile
    Open=xmkmf -a

# Makefile.PL (MakeMaker)
regex/^Makefile.(PL|pl)$
    Open=%var{PERL:perl} %f

# dbf
regex/\.([dD][bB][fF])$
       Open=%view{ascii} dbview %f
       View=%view{ascii} dbview -b %f

# REXX script
regex/\.(rexx?|cmd)$
       Open=rexx %f %{Enter parameters};echo "Press ENTER";read y

# Disk images for Commodore computers (VIC20, C64, C128)
regex/\.(d64|D64)$
    Open=%cd %p/uc1541://
    View=%view{ascii} c1541 %f -list
    Extract=c1541 %f -extract

# Glade, a user interface designer for GTK+ and GNOME
regex/\.([Gg][Ll][Aa][Dd][Ee])$
    Open=if glade-3 --version >/dev/null 2>&1; then (glade-3 %f >/dev/null 2>&1 &); else (glade-2 %f >/dev/null 2>&1 &); fi

# Gettext Catalogs
shell/.mo
    View=%view{ascii} msgunfmt %f || cat %f

# lyx
regex/\.(lyx|LYX)$
    Open=lyx %f
    View=%view{ascii} lyxcat %f

# torrent
regex/\.([tT][oO][rR][rR][eE][nN][tT])$
    View=%view{ascii} rtorrent -x %f 2>/dev/null

### Plain compressed files ###

# ace
regex/\.(ace|ACE)$
    Open=%cd %p/uace://
    View=%view{ascii} unace l %f
    Extract=unace x %f

# arc
regex/\.(arc|ARC)$
    Open=%cd %p/uarc://
    View=%view{ascii} arc l %f
    Extract=arc x %f '*'
    Extract (with flags)=I=%{Enter any Arc flags:}; if test -n "$I"; then arc x $I %f; fi

# zip
type/^([Zz][Ii][Pp])\ archive
    Open=%cd %p/uzip://
    View=%view{ascii} unzip -v %f

# zoo
regex/\.([Zz][Oo][Oo])$
    Open=%cd %p/uzoo://
    View=%view{ascii} zoo l %f

# gzip
type/^gzip
    Open=gzip -dc %f | %var{PAGER:more}
    View=%view{ascii} gzip -dc %f 2>/dev/null

regex/\.(gz|Z)$
    View=%view{ascii} gzip -dc %f 2>/dev/null

# bzip2
type/^bzip2
    Open=bzip2 -dc %f | %var{PAGER:more}
    View=%view{ascii} bzip2 -dc %f 2>/dev/null

regex/\.bz2?$
    View=%view{ascii} bzip2 -dc %f 2>/dev/null

# bzip
type/^bzip
    Open=bzip -dc %f | %var{PAGER:more}
    View=%view{ascii} bzip -dc %f 2>/dev/null

# compress
type/^compress
    Open=gzip -dc %f | %var{PAGER:more}
    View=%view{ascii} gzip -dc %f 2>/dev/null

# lzma
regex/\.lzma$
    Open=lzma -dc %f | %var{PAGER:more}
    View=%view{ascii} lzma -dc %f 2>/dev/null

# xz
regex/\.xz$
    Open=xz -dc %f | %var{PAGER:more}
    View=%view{ascii} xz -dc %f 2>/dev/null

# MS Windows
shell/\.exe
    Open=wine %f

# Solid modeling
shell/.stl
    View=view-mesh %f &
#   Open=makerware %f &

# Solvespace CAD
shell/.slvs
    Open=solvespace %f &
    View=vim -R %f

# Openscad
shell/.scad
    Open=openscad %f &
    View=%view{ascii} %f

### Default ###

# Default target for anything not described above
default/*
    Open=
    View=

Output of mc -F:

Home directory: /home/s
Profile root directory: /home/s

[System data]
    Config directory: /etc/mc/
    Data directory:   /usr/share/mc/
    File extension handlers: /usr/lib/mc/ext.d/
    VFS plugins and scripts: /usr/lib/mc/
        extfs.d:        /usr/lib/mc/extfs.d/
        fish:           /usr/lib/mc/fish/

[User data]
    Config directory: /home/s/.config/mc/
    Data directory:   /home/s/.local/share/mc/
        skins:          /home/s/.local/share/mc/skins/
        extfs.d:        /home/s/.local/share/mc/extfs.d/
        fish:           /home/s/.local/share/mc/fish/
        mcedit macros:  /home/s/.local/share/mc/mc.macros
        mcedit external macros: /home/s/.local/share/mc/mcedit/macros.d/macro.*
    Cache directory:  /home/s/.cache/mc/

Output of file x.zip:

x.zip: Zip archive data, at least v2.0 to extract, compression method=deflate

There is no directory /home/s/.local/share/mc/extfs.d.

Adding the contents of /usr/lib/mc/extfs.d/uzip would get me over the max. 30k characters; it is a 482-line Perl script.

0

There are 0 best solutions below