package fs::mount_point; use diagnostics; use strict; use common; use any; use fs::type; sub guess_mount_point { my ($part, $prefix, $user) = @_; my %l = ( '/' => 'etc/fstab', '/boot' => 'vmlinuz', '/boot' => 'vmlinux', '/boot' => 'uImage', '/tmp' => '.X11-unix', '/usr' => 'src', '/var' => 'spool', ); my $handle = any::inspect($part, $prefix) or return; my $d = $handle->{dir}; my $mnt = find { -e "$d/$l{$_}" } keys %l; $mnt ||= (stat("$d/.bashrc"))[4] ? '/root' : '/home/user' . ++$$user if -e "$d/.bashrc"; $mnt ||= (any { -d $_ && (stat($_))[4] >= 1000 && -e "$_/.bashrc" } glob_($d)) ? '/home' : ''; # Keep uid 500 here for guesswork, but base it on .bash_history to increase # changes it's a real user. $mnt ||= (any { -d $_ && (stat($_))[4] >= 500 && -e "$_/.bash_history" } glob_($d)) ? '/home' : ''; ($mnt, $handle); } sub suggest_mount_points { my ($fstab, $prefix, $uniq) = @_; my $user; foreach my $part (grep { isTrueFS($_) } @$fstab) { $part->{mntpoint} && !$part->{unsafeMntpoint} and next; #- if already found via an fstab my ($mnt, $handle) = guess_mount_point($part, $prefix, \$user) or next; next if $uniq && fs::get::mntpoint2part($mnt, $fstab); $part->{mntpoint} = $mnt; delete $part->{unsafeMntpoint}; #- try to find other mount points via fstab fs::merge_info_from_fstab($fstab, $handle->{dir}, $uniq, 'loose') if $mnt eq '/'; } # reuse existing ESP under UEFI: my @ESP = if_(is_uefi(), grep { isESP($_) } @$fstab); if (@ESP) { $ESP[0]{mntpoint} = '/boot/EFI'; delete $ESP[0]{unsafeMntpoint}; } $_->{mntpoint} and log::l("suggest_mount_points: $_->{device} -> $_->{mntpoint}") foreach @$fstab; } sub suggest_mount_points_always { my ($fstab) = @_; my @ESP = grep { isESP($_) && maybeFormatted($_) && !$_->{is_removable} } @$fstab; if (@ESP) { $ESP[0]{mntpoint} = "/boot/EFI"; } my @win = grep { isnormal_Fat_or_NTFS($_) && !$_->{isMounted} && maybeFormatted($_) && !$_->{is_removable} } @$fstab; log::l("win parts: ", join ",", map { $_->{device} } @win) if @win; if (@win == 1) { $win[0]{mntpoint} = "/media/windows"; } else { my %w; foreach (@win) { my $v = $w{$_->{device_windobe}}++; $_->{mntpoint} = $_->{unsafeMntpoint} = "/media/win_" . lc($_->{device_windobe}) . ($v ? $v+1 : ''); #- lc cuz of StartOffice(!) cf dadou } } } sub validate_mount_points { my ($fstab) = @_; #- TODO: set the mntpoints my %m; foreach (@$fstab) { my $m = $_->{mntpoint}; $m && $m =~ m!^/! or next; #- there may be a lot of swaps or "none" $m{$m} and die N("Duplicate mount point %s", $m); $m{$m} = 1; #- in case the type does not correspond, force it to default fs (ext4 currently) fs::type::set_fs_type($_, defaultFS()) if !isTrueFS($_) && !isOtherAvailableFS($_); } 1; } sub ask_mount_points { my ($in, $fstab, $all_hds) = @_; my @fstab = grep { isTrueFS($_) } @$fstab; @fstab = grep { isSwap($_) } @$fstab if @fstab == 0; @fstab = @$fstab if @fstab == 0; die N("No partition available") if @fstab == 0; { my $_w = $in->wait_message('', N("Scanning partitions to find mount points")); suggest_mount_points($fstab, $::prefix, 'uniq'); log::l("default mntpoint $_->{mntpoint} $_->{device}") foreach @fstab; } if (@fstab == 1) { $fstab[0]{mntpoint} = '/'; } else { $in->ask_from_({ messages => N("Choose the mount points"), title => N("Partitioning"), interactive_help_id => 'ask_mntpoint_s', callbacks => { complete => sub { require diskdrake::interactive; eval { 1, find_index { !diskdrake::interactive::check_mntpoint($in, $_->{mntpoint}, $_, $all_hds); } @fstab }; }, }, }, [ map { { label => partition_table::description($_), val => \$_->{mntpoint}, not_edit => 0, list => [ '', fsedit::suggestions_mntpoint(fs::get::empty_all_hds()) ], }; } @fstab ]) or return; } validate_mount_points($fstab); } 1;