# irix-lib.pl # Filesystem functions for IRIX # XXX logging and locking? # Return information about a filesystem, in the form: # directory, device, type, options, fsck_order, mount_at_boot # If a field is unused or ignored, a - appears instead of the value. # Swap-filesystems (devices or files mounted for VM) have a type of 'swap', # and 'swap' in the directory field sub list_mounts { local(@rv, @p, $_, $i); $i = 0; open(FSTAB, $config{'fstab_file'}); while() { chop; s/#.*$//g; if (!/\S/) { next; } @p = split(/\s+/, $_); $rv[$i] = [ $p[1], $p[0], $p[2] ]; $rv[$i]->[5] = "yes"; local @o = split(/,/ , $p[3] eq "defaults" ? "" : $p[3]); if (($j = &indexof("noauto", @o)) >= 0) { # filesytem is not mounted at boot splice(@o, $j, 1); $rv[$i]->[5] = "no"; } $rv[$i]->[3] = (@o ? join(',' , @o) : "-"); $rv[$i]->[4] = (@p >= 5 ? $p[5] : 0); $i++; } close(FSTAB); # List automount points open(AUTOTAB, $config{'autofs_file'}); while() { chop; s/#.*$//g; if (!/\S/ || /^[+\-]/) { next; } @p = split(/\s+/, $_); if ($p[2] eq "") { $p[2] = "-"; } else { $p[2] =~ s/^-//g; } $rv[$i++] = [ $p[0], $p[1], "autofs", $p[2], "-", "yes" ]; } close(AUTOTAB); return @rv; } # create_mount(directory, device, type, options, fsck_order, mount_at_boot) # Add a new entry to the fstab file, and return the index of the new entry sub create_mount { local($len, @mlist, $fcsk, $dir); if ($_[2] eq "autofs") { # An autofs mount.. add to /etc/auto_master $len = grep { $_->[2] eq "autofs" } (&list_mounts()); &open_tempfile(AUTOTAB, ">> $config{autofs_file}"); &print_tempfile(AUTOTAB, "$_[0] $_[1]",($_[3] eq "-" ? "" : " -$_[3]"),"\n"); &close_tempfile(AUTOTAB); &system_logged("autofs -r >/dev/null 2>&1 [2] ne "autofs" } (&list_mounts()); &open_tempfile(FSTAB, ">> $config{fstab_file}"); &print_tempfile(FSTAB, "$_[1] $_[0] $_[2]"); local $opts = $_[3] eq "-" ? "" : $_[3]; if ($_[5] eq "no") { $opts = join(',' , (split(/,/ , $opts) , "noauto")); } if ($opts eq "") { &print_tempfile(FSTAB, " defaults"); } else { &print_tempfile(FSTAB, " $opts"); } &print_tempfile(FSTAB, " 0 "); &print_tempfile(FSTAB, $_[4] eq "-" ? "0\n" : "$_[4]\n"); &close_tempfile(FSTAB); } return $len; } # delete_mount(index) # Delete some mount from the table sub delete_mount { local(@fstab, @autotab, $i, $line, $_); open(FSTAB, $config{fstab_file}); @fstab = ; close(FSTAB); $i = 0; &open_tempfile(FSTAB, "> $config{fstab_file}"); foreach (@fstab) { chop; ($line = $_) =~ s/#.*$//g; if ($line =~ /\S/ && $i++ == $_[0]) { # found the line not to include } else { &print_tempfile(FSTAB, $_,"\n"); } } &close_tempfile(FSTAB); local $found; open(AUTOTAB, $config{autofs_file}); @autotab = ; close(AUTOTAB); &open_tempfile(AUTOTAB, "> $config{autofs_file}"); foreach (@autotab) { chop; ($line = $_) =~ s/#.*$//g; if ($line =~ /\S/ && $line !~ /^[+\-]/ && $i++ == $_[0]) { # found line not to include.. $line =~ /^(\S+)/; $found = $1; } else { &print_tempfile(AUTOTAB, $_,"\n"); } } &close_tempfile(AUTOTAB); if ($found) { &system_logged("autofs -r >/dev/null 2>&1 /dev/null 2>&1 ; close(FSTAB); &open_tempfile(FSTAB, "> $config{fstab_file}"); foreach (@fstab) { chop; ($line = $_) =~ s/#.*$//g; if ($line =~ /\S/ && $i++ == $_[0]) { # Found the line to replace &print_tempfile(FSTAB, "$_[2] $_[1] $_[3]"); local $opts = $_[4] eq "-" ? "" : $_[4]; if ($_[6] eq "no") { $opts = join(',' , (split(/,/ , $opts) , "noauto")); } if ($opts eq "") { &print_tempfile(FSTAB, " defaults"); } else { &print_tempfile(FSTAB, " $opts"); } &print_tempfile(FSTAB, " 0 "); &print_tempfile(FSTAB, $_[5] eq "-" ? "0\n" : "$_[5]\n"); } else { &print_tempfile(FSTAB, $_,"\n"); } } &close_tempfile(FSTAB); local $found; open(AUTOTAB, $config{autofs_file}); @autotab = ; close(AUTOTAB); &open_tempfile(AUTOTAB, "> $config{autofs_file}"); foreach (@autotab) { chop; ($line = $_) =~ s/#.*$//g; if ($line =~ /\S/ && $line !~ /^[+\-]/ && $i++ == $_[0]) { # Found the line to replace &print_tempfile(AUTOTAB, "$_[1] $_[2] ", ($_[4] eq "-" ? "" : "-$_[4]"),"\n"); $found++; } else { &print_tempfile(AUTOTAB, $_,"\n"); } } &close_tempfile(AUTOTAB); if ($found) { &system_logged("autofs -r >/dev/null 2>&1 /dev/null", 1, 1); while() { if (/^\s*\d+\s+(\/\S+)/) { push(@rv, [ "swap", $1, "swap", "-" ]); } } close(SWAP); open(MTAB, "/etc/mtab"); while() { s/#.*$//g; if (!/\S/) { next; } @p = split(/\s+/, $_); push(@rv, [ $p[1], $p[0], $p[2], $p[3] ]); } close(MTAB); return @rv; } # mount_dir(directory, device, type, options) # Mount a new directory from some device, with some options. Returns 0 if ok, # or an error string if failed. If the directory is 'swap', then mount as # virtual memory. sub mount_dir { local($out, $opts); if ($_[2] eq "swap") { # Adding a swap device $out = &backquote_logged("swap -a $_[1] 2>&1"); if ($?) { return $out; } } elsif ($_[2] eq "autofs") { # Do nothing, because autofs -r will be run after the auto_master file # is updated. } else { # Mounting a directory $opts = $_[3] eq "-" ? "" : "-o \"$_[3]\""; $out = &backquote_logged("mount -t $_[2] $opts $_[1] $_[0] 2>&1"); if ($?) { return $out; } } return 0; } # unmount_dir(directory, device, type) # Unmount a directory (or swap device) that is currently mounted. Returns 0 if # ok, or an error string if failed sub unmount_dir { if ($_[2] eq "swap") { $out = &backquote_logged("swap -d $_[1] 2>&1"); } elsif ($_[2] eq "autofs") { # Do nothing - see the comment in mount_dir return 0; } else { $out = &backquote_logged("umount $_[0] 2>&1"); } if ($?) { return $out; } return 0; } # disk_space(type, directory) # Returns the amount of total and free space for some filesystem, or an # empty array if not appropriate. sub disk_space { if (&get_mounted($_[1], "*") < 0) { return (); } if ($_[0] eq "fd" || $_[0] eq "proc" || $_[0] eq "swap" || $_[0] eq "autofs") { return (); } if (&backquote_command("df -k ".quotemeta($_[1]), 1) =~ /Mounted on\n\S+\s+\S+\s+(\S+)\s+\S+\s+(\S+)/) { return ($1, $2); } else { return ( ); } } # list_fstypes() # Returns an array of all the supported filesystem types. If a filesystem is # found that is not one of the supported types, generate_location() and # generate_options() will not be called for it. sub list_fstypes { return ("xfs","efs","nfs","iso9660","dos","autofs","swap"); } # fstype_name(type) # Given a short filesystem type, return a human-readable name for it sub fstype_name { local(%fsmap); %fsmap = ("xfs","SGI Filesystem", "nfs","Network Filesystem", "cachefs","Caching Filesystem", "iso9660","ISO9660 CD-ROM", "dos","MS-DOS Filesystem", "efs","Old SGI Filesystem", "fd","File Descriptor Filesystem", "hfs","Macintosh Filesystem", "kfs","AppleShare Filesystem", "proc","Process Image Filesystem", "hwgfs","Hardware Configuration Filesystem", "autofs","Automounter Filesystem", "nfs3","NIS Maps Filesystem", "swap","Virtual Memory"); return $config{long_fstypes} && $fsmap{$_[0]} ? $fsmap{$_[0]} : uc($_[0]); } # mount_modes(type, dir, device) # Given a filesystem type, returns 5 numbers that determine how the file # system can be mounted, and whether it can be fsck'd sub mount_modes { if ($_[0] eq "swap") { return $_[2] eq "/dev/swap" ? (1, 0, 0, 0, 1) : (1, 1, 0, 0); } elsif ($_[0] eq "fd" || $_[0] eq "proc" || $_[0] eq "hwgfs" || $_[0] eq "nfs3") { return (1, 0, 0, 1); } elsif ($_[0] eq "xfs" || $_[0] eq "efs" || $_[0] eq "cachefs") { return (2, 1, 1, 0); } elsif ($_[0] eq "autofs") { return (1, 0, 0, 0); } else { return (2, 1, 0, 0); } } # multiple_mount(type) # Returns 1 if filesystems of this type can be mounted multiple times, 0 if not sub multiple_mount { return ($_[0] eq "nfs" || $_[0] eq "kfs" || $_[0] eq "cachefs"); } # generate_location(type, location) # Output HTML for editing the mount location of some filesystem. sub generate_location { if ($_[0] eq "nfs") { # NFS mount from some host and directory local ($nfshost, $nfspath) = $_[1] =~ /^([^:]+):(.*)/ ? ( $1, $2 ) : (); print " $text{'irix_nhost'}\n"; print "\n"; &nfs_server_chooser_button("nfs_host"); print "\n"; print "$text{'irix_ndir'}\n"; print "\n"; &nfs_export_chooser_button("nfs_host", "nfs_dir"); print " \n"; } elsif ($_[0] eq "autofs") { # Selecting an automounter map print " $text{'irix_auto'}\n"; print "\n"; printf " %s
\n", $_[1] eq "-hosts" ? "checked" : "", $text{'irix_autohosts'}; printf " %s\n", $_[1] eq "-hosts" ? "" : "checked", $text{'irix_automap'}; printf "
\n", $_[1] eq "-hosts" ? "" : $_[1]; } elsif ($_[0] eq "iso9660") { # Selecting an entire SCSI disk print " $text{'irix_cd'}\n"; print "\n"; local ($mode, $ctrlr, $drive, $other); if ($_[1] =~ /^\/dev\/rdsk\/dks(\d+)d(\d+)vol$/) { $mode = 0; $ctrlr = $1; $drive = $2; } elsif ($_[1]) { $mode = 1; $other = $_[1]; } printf "\n", $mode == 0 ? "checked" : ""; print &text('irix_mode0cd', "", ""),"
\n"; printf " %s\n", $mode == 1 ? "checked" : "", $text{'irix_mode1'}; printf "
\n", $mode == 1 ? $other : ""; print " \n"; } else { # Mounting some local disk (or file) print " $text{'irix_part'}\n"; print "\n"; local ($mode, $ctrlr, $drive, $part, $other); if ($_[1] =~ /^\/dev\/dsk\/dks(\d+)d(\d+)s(\d+)$/) { $mode = 0; $ctrlr = $1; $drive = $2; $part = $3; } elsif ($_[1]) { $mode = 1; $other = $_[1]; } printf "\n", $mode == 0 ? "checked" : ""; local ($sel, $currctrlr, $currdrive); open(VTOC, "prtvtoc -a |"); while() { if (/^\/dev\/rdsk\/dks(\d+)d(\d+)vh/) { $currctrlr = $1; $currdrive = $2; } elsif (/^\/dev/) { undef($currctrlr); } elsif (/^\s*(\d+)\s+(\d+)\s+(\d+)/ && defined($currctrlr)) { $sel .= sprintf "