[PATCH] fstab, mfstab
Sza'sz Gergely
szaszg at hu.inter.net
Fri May 16 22:52:53 UTC 2003
On Fri, May 16, 2003 at 11:56:40AM -0400, Pavel Roskin wrote:
> This is all cool and nice, but I don't think this can be included into the
Thanks!
> sources in its present form. We shouldn't encourage users to do system
> administration from mc. I don't want to answer e-mails from the users who
> lost their data because they didn't see and didn't know what they were
> doing.
I see. But I don't think, it is 'system administration' at all:
- my script is just a frontend for '(u)mount' and 'df'
- (u)mounting a partition is less 'dangerouse' than delete it [F8] :-)
- you don't lose any data even if you (u)mount 'root/system' partitions
- my script can't do any extra thing, which you can't do with (u)mount
- you can only (u)mount normally a floppy, a CD-ROM (DVD), or e.g. a
CF card. Those which exist in '/etc/fstab' with 'user' option
- you can't do any 'unexpected' (u)mount, because, only root (uid=0)
can (u)mount
- All in all, to (u)mount user (u)mountable partitions (imho) *not
system administration*
And to top it all:
- I think that, most of the people (I'm sure, You too), do system
administration 'from' mc, when editing /etc/xxx files :-) :-)
**But, You are the boss**
>
> System administration tools must provide a very high level of reliability
> that the development process of GNU Midnight Commander doesn't provide
> and doesn't aim to provide. Also, the level of testing received by
> undocumented external VFSs is inadequate for system administration tools.
> There were major bugs sitting for years in some of the scripts, and nobody
> complained.
I see. But my script cannot change any of system files (fstab), or system
settings. And if you can't (u)mount a partition from 'fstab VFS', or get
wrong info from an 'fstab' entry/mount... I think that, it is not critical :-)
> I'm ready to put your script to the "contribution" section on the website
> if you write a README and settle on one script.
Thanks. I think this will be the 'mfstab' script, because it can work with
the present state of 'mc' VFS... (fstab need a patch on 'extfs.c', which I
send before...)
Gergely
P.s.: And what about the extfs.c patch? Don't we need any similar function
in VFS? (Rescan (get a new list/kill from cache) from an external FS
data when it is neccesary?)
-------------- next part --------------
#! /usr/bin/perl
#
# 2003 (c) Gergely Sz?sz <szaszg at hu.inter.net>
# This software is under GNU license
#
sub mcfstabfs_list
{
#
#
print "-r--r--r-- 1 root root 0 $date README\n";
print "-r--r--r-- 1 root root 0 $date TODO\n";
print "-r--r--r-- 1 root root 0 $date BUGS\n";
print "-r--r--r-- 1 root root 0 $date read_fstab\n";
print "-r--r--r-- 1 root root 0 $date pipe_mount\n";
print "-r--r--r-- 1 root root 0 $date read_mtab\n";
$i = 0;
foreach (@f)
{
@_ = @{$_};
print "-r-xr-xr-x 1 root root 0 $date $_[0] on $_[1]/info\n";
if ($_[6] eq 'Yes (not in fstab)')
{
printf "lr-xr-xr-x 1 root root 0 $date _mount_%03d -> $_[0] on $_[1]\n", $i;
}
else
{
printf "lr-xr-xr-x 1 root root 0 $date _fstab_%03d -> $_[0] on $_[1]\n", $i;
print "---x--x--x 1 root root 0 $date $_[0] on $_[1]/mount\n";
print "---x--x--x 1 root root 0 $date $_[0] on $_[1]/umount\n";
}
$i++;
}
}
sub mcfstabfs_dumpfile # $destfile $string
{
if (open (FILEOUT,">$_[0]"))
{
print FILEOUT $_[1];
close FILEOUT;
# system ("chmod a+x $_[0]"); #we need it?
}
}
sub mcfstab_uline
{
@_ = split //, $_[0];
return '_' . join ('_', @_);
}
sub mcfstab_bold
{
my $r;
@_ = split //, $_[0];
foreach (@_)
{
$r .= $_ . '' . $_;
}
return $r;
}
sub mcfstab_red
{
return '[1;31m' . $_[0] . '[0;39m';
}
sub mcfstab_yellow
{
return '[1;33m' . $_[0] . '[0;39m';
}
sub mcfstabfs_copyout
{
local($archive,$filename,$destfile)=@_;
if ($filename eq 'README')
{
mcfstabfs_dumpfile ($destfile, $readme_str);
exit 0;
}
if ($filename eq 'BUGS')
{
mcfstabfs_dumpfile ($destfile, $bugs_str);
exit 0;
}
if ($filename eq 'TODO')
{
mcfstabfs_dumpfile ($destfile, $todo_str);
exit 0;
}
if ($filename eq 'read_fstab')
{
open (FSTAB, "</etc/fstab");
$fstab .= $_ while (<FSTAB>);
close FSTAB;
mcfstabfs_dumpfile ($destfile, $fstab);
exit 0;
}
if ($filename eq 'pipe_mount')
{
open (FSTAB, "/bin/mount |");
$fstab .= $_ while (<FSTAB>);
close FSTAB;
mcfstabfs_dumpfile ($destfile, $fstab);
exit 0;
}
if ($filename eq 'read_mtab')
{
open (FSTAB, "</etc/mtab");
$fstab .= $_ while (<FSTAB>);
close FSTAB;
mcfstabfs_dumpfile ($destfile, $fstab);
exit 0;
}
unless ($filename =~ /_mount_([0-9]+)/)
{
$fs =~ /$filename ([^\n]+)/m;
}
@_ = @{@f[$1]};
if ($filename =~ s/\/info$//)
{
mcfstabfs_dumpfile ($destfile, sprintf ($info_str,
mcfstab_uline ($_[0]),
mcfstab_uline ($_[1])));
exit 0;
}
if ($filename =~ s/\/umount$//)
{
($_, $filename) = split / on /, $filename;
mcfstabfs_dumpfile ($destfile, sprintf ($umount_str,
mcfstab_uline ($_[0]),
mcfstab_uline ($_[1])));
exit 0;
}
if ($filename =~ s/\/mount$//)
{
($_, $filename) = split / on /, $filename;
mcfstabfs_dumpfile ($destfile, sprintf ($mount_str,
mcfstab_uline ($_[0]),
mcfstab_uline ($_[1])));
exit 0;
}
if ($filename eq 'mount-OPEN-ERROR')
{
mcfstabfs_dumpfile ($destfile, "*** ERROR***\n\nCannot execute '/bin/mount' system utility!\n");
exit 0;
}
if ($filename eq 'fstab-OPEN-ERROR')
{
mcfstabfs_dumpfile ($destfile, "*** ERROR***\n\nCannot read the '/etc/fstab' file!\n");
exit 0;
}
}
sub mcfstabfs_run
{
local($archive,$filename)=@_;
unless ($filename =~ /_mount_([0-9]+)/)
{
$fs =~ /$filename ([^\n]+)/m;
}
@_ = @{@f[$1]};
if($filename =~ /\/info$/)
{
$_ = "\n\nDevice:\t\t" . mcfstab_yellow ($_[0]) .
"\nMount point:\t" . mcfstab_yellow ($_[1]) .
"\nType:\t\t" . mcfstab_red ($_[2]) .
"\nOptions:\t" . mcfstab_red ($_[3]) .
"\nDump:\t\t" . $_[4] .
"\nPass:\t\t" . $_[5] .
"\nMounted:\t" . mcfstab_yellow ($_[6]);
if ($_[7] ne undef)
{
$_ .= "\nSize:\t\t" . mcfstab_yellow ($_[7]) .
"k\nUsed:\t\t" . mcfstab_yellow ($_[8]) .
"k\nFree:\t\t" . mcfstab_yellow ($_[9]) .
"k\nUsage:\t\t" . mcfstab_yellow ($_[10]);
}
print $_ . "\n\n";
}
elsif($filename =~ /\/umount$/)
{
if ($_[6] eq 'Yes')
{
print "Umounting: $_[0] from $_[1]...\n";
system("umount $_[1]");
}
else
{
print "This filesystem " . mcfstab_red ('do not') .
" mounted yet.\n";
}
}
else
{
if ($_[6] eq 'No')
{
print "Mounting: $_[0] to $_[1]...\n";
system("mount $_[1]");
# system("mount -t $_[2] -o $_[4] $_[0] $_[1]");
}
else
{
print "This filesystem " . mcfstab_red ('already') .
" mounted.\n";
}
}
}
$readme_str=<<EOS;
****FFSSTTAABB VVFFSS****
This is a modified version of the original fstab VFS, to work with an
unmodified 'mc'. We found executable 'info' files in each leaf directory,
and we can get information from a specified mount when executing this info
file, rather than showing ([F3]) it...
The sizes of symlinks are all zero (no mount/umount info in it), and
the 'mount' and 'umount' executables exist together, and warn if you try
to mount a mounted, or umount a not mounted filesystem...
So, not so nice interface, but works with unpatched VFS...
The original README:
This virtual filesystem (fstab) gives you an easy to use (u)mounting
tool for 'mounting' and 'umounting' filesystems defined in '/etc/fstab'.
You see one symlink for each definition in fstab, named '_mount_NNN'.
Where NNN is a number. The size of the symlinks is 0 if not mounted, 1 if
mounted and 2 if mounted, but there is no size information (e.g. usbfs,
procfs ...).
Every symlink points to a directory, which represents the fstab entry.
The path of the directory is like 'DEVICE on MOUNTPOINT', where DEVICE is the
device and the MOUNTPOINT is the mount point of it (e.g. '/dev/hda1 on /usr'.
There is a 'dev' directory, containing a 'hda1 on' directory, which containing
an 'usr' directory.).
There are two files in every 'leaf' directory:
- a readable 'info' and
- an executable 'mount' or 'umount' depend on the state of the filesystem
Read the 'info' ([F3]) to get some information, and execute ([ENTER]) the
(u)mount file, to (u)mount the specified device.
Please enjoy...
Created by Gergely Sz?sz <mailto:szaszg at hu.inter.net>
EOS
$bugs_str=<<EOS;
****KKNNOOWWNN BBUUGGSS****
Please report bugs to <mailto:szaszg at hu.inter.net>...
EOS
$info_str=<<EOS;
****GGEETTTTIINNGG IINNFFOO****
If you tap _[_E_N_T_E_R_] over this file, you get information
about %s on %s mount.
EOS
$mount_str=<<EOS;
****MMOOUUNNTTIINNGG AANN FFSS****
If you tap _[_E_N_T_E_R_] over this file, you mount filesystem on
%s device to the %s directory.
EOS
$umount_str=<<EOS;
****UUMMOOUUNNTTIINNGG AANN FFSS****
If you tap _[_E_N_T_E_R_] over this file, you umount filesystem on
%s device from the %s directory.
EOS
$todo_str=<<EOS;
****TTOODDOO****
Please write your ideas for me <mailto:szaszg at hu.inter.net>...
EOS
umask 077;
chop($date=`LC_ALL=C date "+%b %d %Y %H:%M"`);
unless (-x '/bin/mount')
{
print "-r--r--r-- 1 root root 0 $date mount-EXEC-ERROR\n";
exit 0;
}
unless (-r '/etc/fstab')
{
print "-r--r--r-- 1 root root 0 $date fstab-OPEN-ERROR\n";
exit 0;
}
unless (-r '/etc/mtab')
{
print "-r--r--r-- 1 root root 0 $date mtab-OPEN-ERROR\n";
exit 0;
}
undef $/;
open (IN, "</etc/fstab") and $fs = <IN>;
open (IN, "mount |") and $mn = <IN>;
open (IN, "df |") and $df = <IN>;
close IN;
$/ = "\n";
$fs =~ s/^#.*\n|^[ \t]*\n//mg;
$fs =~ s/[ \t]+/ /mg;
$mn =~ s/ on | type / /mg;
$mn =~ s/\((.*?)\)\n/$1\n/mg;
$df =~ s/File.*?\n//g;
$df =~ s/[ \t]+/ /mg;
@fs = split /\n/, $fs;
@mn = split /\n/, $mn;
@df = split /\n/, $df;
$i = 0;
foreach (@fs) #process predefined ones
{
split; #get pieces $_[0] = filesys, 1 = mountp, 2 = type,
# 3 = options, 4 = dump, 5 = pass
if ($mn =~ /^$_[0] $_[1] ([^ ]+) ([^\n]+)/m) #ok! mounted
# get actual options...
{
$_[6] = 'Yes'; #mounted
$_[2] = $1; $_[3] = $2; #type and options
if ($df =~ /^$_[0] ([^ ]+) ([^ ]+) ([^ ]+) ([^\n]+) $_[1]$/m) #
# ok, have size info!!!
{
$_[7] = $1; $_[8] = $2; $_[9] = $3; $_[10] = $4;
#size, used, free, use%
}
}
else
{
$_[6] = 'No'; #umounted
}
push (@f, [@_]); #an array
$_[0] =~ s/^\///; #we throw it away... :-)
$fs .= join (' ', $_[0], 'on', $_[1], $i) . "\n";
#a matchable var with linenum
$i++;
}
foreach (@mn) #process actual mounts
{
split; #get pieces $_[0] = filesys, 1 = mountp, 2 = type,
# 3 = options, 4 = dump, 5 = pass
next if ($fs =~ /^$_[0] $_[1]/m); #ok! already have
# get actual options...
$_[4] = '-'; $_[5] = '-';
$_[6] = 'Yes (not in fstab)'; #mounted
if ($df =~ /^$_[0] ([^ ]+) ([^ ]+) ([^ ]+) ([^\n]+) $_[1]$/m) #
# ok, have size info!!!
{
$_[7] = $1; $_[8] = $2; $_[9] = $3; $_[10] = $4;
#size, used, free, use%
}
push (@f, [@_]); #an array
$_[0] =~ s/^\///; #we throw it away... :-)
$fs .= join (' ', $_[0], 'on', $_[1], $i) . "\n";
#a matchable var with linenum
$i++;
}
if($ARGV[0] eq "list") { shift; &mcfstabfs_list(@ARGV); exit 0; }
elsif($ARGV[0] eq "copyout") { shift; &mcfstabfs_copyout(@ARGV); exit 0; }
elsif($ARGV[0] eq "run") { shift; &mcfstabfs_run(@ARGV); exit 0; }
exit 1;
-------------- next part --------------
**FSTAB VFS**
This is a modified version of the original fstab VFS, to work with an
unmodified 'mc'. We found executable 'info' files in each leaf directory,
and we can get information from a specified mount when executing this info
file, rather than showing ([F3]) it...
The sizes of symlinks are all zero (no mount/umount info in it), and
the 'mount' and 'umount' executables exist together, and warn if you try
to mount a mounted, or umount a not mounted filesystem...
So, not so nice interface, but works with unpatched VFS...
The original README:
This virtual filesystem (fstab) gives you an easy to use (u)mounting
tool for 'mounting' and 'umounting' filesystems defined in '/etc/fstab'.
You see one symlink for each definition in fstab, named '_mount_NNN'.
Where NNN is a number. The size of the symlinks is 0 if not mounted, 1 if
mounted and 2 if mounted, but there is no size information (e.g. usbfs,
procfs ...).
Every symlink points to a directory, which represents the fstab entry.
The path of the directory is like 'DEVICE on MOUNTPOINT', where DEVICE is the
device and the MOUNTPOINT is the mount point of it (e.g. '/dev/hda1 on /usr'.
There is a 'dev' directory, containing a 'hda1 on' directory, which containing
an 'usr' directory.).
There are two files in every 'leaf' directory:
- a readable 'info' and
- an executable 'mount' or 'umount' depend on the state of the filesystem
Read the 'info' ([F3]) to get some information, and execute ([ENTER]) the
(u)mount file, to (u)mount the specified device.
You should add a line (mfstab:) to the 'extfs.ini' file, and copy the 'mfstab'
script to that directory (where is 'extfs.ini').
Then start 'mc' and type: cd #mfstab[ENTER]
Please enjoy...
Created by Gergely Sz?sz <mailto:szaszg at hu.inter.net>
More information about the mc-devel
mailing list