summaryrefslogtreecommitdiffstats
path: root/perl-install/fs/mount_point.pm
blob: 9263d692f47204cb163f841aa8f3fb5fb6229028 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
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;