123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- Writing scripts for Midnight Commander's external vfs
- IMPORTANT NOTE: There may be some bugs left in extfs. Enjoy.
- 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 suffix. For example, if you have .zip file, and would
- like to see what's inside it, path will be
- /anypath/my.zip#uzip/some_path/...
- Then you add a line extfs.ini file containing just that extension. If
- your vfs does not require file to work on, add ':' to the end of name.
- In this example, .zip is suffix, but I call vfs 'uzip'. Why? Well,
- what this vfs essentially does is UNzip. UN is too long, so I choosed
- U. Note that sometime in future filesystem like zip may exist: It will
- take whole tree and create .zip file from it. So /usr#zip will be
- zipfile containing whole /usr tree.
- 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/uzip).
- * Commands that should be implemented by your shell script
- ----------------------------------------------------------
- Return zero from your script upon completion of the command, otherwise
- nonzero for failure or in case of an unsupported command.
- $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-YYYY hh:mm
- where Mon is a three letter English month name, DD is day
- 1-31, MM is month 01-12, YYYY is four digit year, hh hour is
- and mm is 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
- [this is wrong. current extfs strips paths! -- pavel@ucw.cz])
- 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.
- * Command: rm archivename storedfilename
- This should remove storedfilename from archivename.
- * Command: mkdir archivename dirname
- This should create a new directory called dirname inside archivename.
- * Command: rmdir archivename dirname
- This should remove an existing directory dirname. If the directory is
- not empty, mc will recursively delete it (possibly prompting).
- * Command: run
- Undocumented :-)
- ---------------------------------------------------------
- Don't forget to mark this file executable (chmod 755 ThisFile, for example)
- For skeleton structure of executable, look at some of filesystems
- similar to yours.
- ---------------------------------------------------------
- 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.
|