mirror of https://github.com/MidnightCommander/mc
215 lines
7.7 KiB
Plaintext
215 lines
7.7 KiB
Plaintext
Writing scripts for Midnight Commander's external vfs
|
|
|
|
IMPORTANT NOTE: extfs is not officialy released and fully bug free
|
|
in 3.0! You have been warned. If you would really like to try it,
|
|
you can (by typing make install.extfs in the vfs directory).
|
|
|
|
Starting with version 3.1, the Midnight Commander comes with so called
|
|
extfs, which is one of the virtual filesystems. This system makes it
|
|
possible to create new virtual filesystems for the GNU MC very easily.
|
|
|
|
Such work has two basic steps:
|
|
|
|
Editing $(libdir)/extfs/extfs.ini.
|
|
Creating a shell script/program to handle requests.
|
|
(Note: $(libdir) should be substituted for actual libdir path stored when
|
|
configured or compiled, like /usr/local/lib/mc or /usr/lib/mc).
|
|
|
|
The first one is very easy:
|
|
You assign a vfs prefix and vfs extensions to your vfs. Both will be used in
|
|
vfs pseudoURL names, like if you assign prefix zip and extensions .zip,
|
|
.ZIP, then URLs will look like
|
|
zip:anypath/my.zip/some_path/in_the/archive
|
|
Then you add a line to the end of the [extfs] section:
|
|
prefix=space_separated_extensions
|
|
e.g.
|
|
zip=.zip .ZIP
|
|
|
|
The second one may require some your knowledge of shell/c programming:
|
|
You have to create a program (with executable permissions) prefix in
|
|
$(libdir)/extfs (in our example $(libdir)/extfs/zip).
|
|
|
|
* Commands that should be implemented by your shell script
|
|
----------------------------------------------------------
|
|
|
|
$libdir/extfs/prefix command [arguments]
|
|
|
|
* Command: list archivename
|
|
|
|
This command should list the complete archive content in the following format
|
|
(a little modified ls -l listing):
|
|
|
|
AAAAAAA NNN OOOOOOOO GGGGGGGG SSSSSSSS DATETIME [PATH/]FILENAME [-> [PATH/]FILENAME[/]]]
|
|
|
|
where (things in [] are optional):
|
|
|
|
AAAAAAA is the permission string like in ls -l
|
|
NNN is the number of links
|
|
OOOOOOOO is the owner (either UID or name)
|
|
GGGGGGGG is the group (either GID or name)
|
|
SSSSSSSS is the file size
|
|
FILENAME is the filename
|
|
PATH is the path from the archive's root without the leading slash (/)
|
|
DATETIME has one of the following formats:
|
|
Mon DD hh:mm
|
|
Mon DD YYYY
|
|
Mon DD YYYY hh:mm
|
|
MM-DD-YY hh:mm
|
|
|
|
where Mon is a three digit english month name, DD day
|
|
1-31, MM month 01-12, YY two digit year, YYYY four digit
|
|
year, hh hour and mm minute.
|
|
|
|
If the -> [PATH/]FILENAME part is present, it means:
|
|
|
|
If permissions start with an l (ell), then it is the name that symlink
|
|
points to. (If this PATH starts with a MC vfs prefix, then it is a symlink
|
|
somewhere to the other virtual filesystem (if you want to specify path from
|
|
the local root, use local:/path_name instead of /path_name, since /path_name
|
|
means from root of the archive listed).
|
|
If permissions do not start with l, but number of links is greater than one,
|
|
then it says that this file should be a hardlinked with the other file.
|
|
|
|
|
|
* Command: copyout archivename storedfilename extractto
|
|
|
|
This should extract from archive archivename the file called
|
|
storedfilename (possibly with path if not located in archive's root)
|
|
to file extractto.
|
|
|
|
* Command: copyin archivename storedfilename sourcefile
|
|
|
|
This should add to the archivename the sourcefile with the name
|
|
storedfilename inside the archive.
|
|
|
|
Important note: archivename in the above examples may not have the
|
|
extension you are expecting to have, like it may happen that
|
|
archivename will be something like /tmp/f43513254 or just
|
|
anything. Some archivers do not like it, so you'll have to find some
|
|
workaround.
|
|
|
|
---------------------------------------------------------
|
|
|
|
Don't forget to mark this file executable (chmod 755 ThisFile, for example)
|
|
|
|
This is a skeleton structure of the executable:
|
|
|
|
#!/bin/sh
|
|
|
|
# Command functions
|
|
mcvfs_list ()
|
|
# $1 is the archive name
|
|
{
|
|
# Apply a system command to obtain a list of filenames
|
|
# For example 'zip -l $1'
|
|
# Scan each line of the 'list' output, discarding unused information, and
|
|
# constructing a printable line in a form, described above, that mc can use.
|
|
# Exit
|
|
}
|
|
|
|
mcvfs_copyout ()
|
|
# $1 is the archive name
|
|
# $2 is a name of a file within the archive
|
|
# $3 is a name of a file within the system (to add from or extract to)
|
|
{
|
|
# Apply the system command used to extract one file from the archive
|
|
# Exit
|
|
}
|
|
|
|
mcvfs_copyin ()
|
|
# $1 is the archive name
|
|
# $2 is a name of a file within the archive
|
|
# $3 is a name of a file within the system (to add from or extract to)
|
|
{
|
|
# Apply the system command used to add one file to the archive
|
|
# Exit
|
|
}
|
|
|
|
# Command line parser
|
|
# $1 is the command
|
|
# $2 is the archive name
|
|
# $3 is a name of a file within the archive
|
|
# $4 is a name of a file within the system (to add from or extract to)
|
|
case "$1" in
|
|
list) mcvfs_list $2; exit $?;;
|
|
copyout) mcvfs_copyout $2 $3 $4; exit $?;;
|
|
copyin) mcvfs_copyin $2 $3 $4; exit $?;;
|
|
esac
|
|
# Show an error if this was called with some other command
|
|
exit 1
|
|
|
|
---------------------------------------------------------
|
|
|
|
In constructing these routines, errors will be made, and mc will not display
|
|
a malformed printing line. That can lead the programmer down many false
|
|
trails in search of the bug. Since this routine is an executable shell script
|
|
it can be run from the command line independently of mc, and its output will
|
|
show on the console or can be redirected to a file.
|
|
|
|
* Putting it to use
|
|
----------------------------------------------------------
|
|
The file .mc.ext in a home directory, and in mc's user directory (commonly
|
|
/usr/local/lib/mc), contains instructions for operations on files depending
|
|
on filename extensions. It is well documented in other files in this
|
|
distribution, so here are just a few notes specifically on use of the
|
|
Virtual File System you just built.
|
|
|
|
There are entries in .mc.ext defining a few operations that can be done on a
|
|
file from an mc panel. Typically they are annotated with a hash mark and a
|
|
file extension like this:
|
|
|
|
# zip
|
|
|
|
There must be a way to find the file by extension, so the next line does
|
|
that. In essence it says "identify the string ".zip" or (|) ".ZIP" at the
|
|
end ($) of a filename":
|
|
|
|
regex/\.(zip|ZIP)$
|
|
|
|
The operations themselves follow that. They must be indented by at least a
|
|
space, and a tab works as well. In particular, the Open operation will
|
|
now use your new virtual file system by cd'ing to it like this:
|
|
|
|
Open=%cd zip:%d/%p
|
|
|
|
This is the line used when a file is highlighted in a panel and the user
|
|
presses <Enter> or <Return>. The contents of the archive should show just
|
|
as if they were in a real directory, and can be manipulated as such.
|
|
The rest of the entry pertains to use of the F3 View key:
|
|
|
|
View=%view{ascii} unzip -v %f
|
|
|
|
And perhaps an optional icon for X:
|
|
|
|
Icon=zip.xpm
|
|
|
|
And perhaps an operation to extract the contents of the file, called from
|
|
a menu selection:
|
|
|
|
Extract=unzip %f '*'
|
|
|
|
This is just an example. The current entry for .zip files has a menu selection
|
|
of 'Unzip' which could be used in place of 'Extract'. What goes here depends
|
|
on what items you have in, or add to, the menu system, and that's another
|
|
subject. The sum of this is the .mc.ext entry:
|
|
|
|
# zip
|
|
regex/\.(zip|ZIP)$
|
|
Open=%cd zip:%d/%p
|
|
View=%view{ascii} unzip -v %f
|
|
Icon=zip.xpm
|
|
Extract=unzip %f '*'
|
|
|
|
Add an entry like this to the .mc.ext file in a user's home directory, If you
|
|
want others to have it, add it to the mc.ext file in the mc system directory,
|
|
often /usr/local/lib/mc/mc.ext. Notice this file is not prepended with a dot.
|
|
|
|
Once all this is done, and things are in their proper places, exit mc if you
|
|
were using it, and restart it so it picks up the new information.
|
|
|
|
That's all there is to it. The hardest part is making a listing function
|
|
that sorts the output of a system listing command and turns it into a form
|
|
that mc can use. Currently awk (or gawk) is used because nearly all systems
|
|
have it. If another scripting language is available, like perl, that could
|
|
also be used.
|