3 # Save or create an export
5 require './bsdexports-lib.pl';
7 &error_setup($text{'save_err'});
10 # Redirect to delete CGI
11 &redirect("delete_export.cgi?idx=$in{'idx'}");
15 # Validate and save inputs
16 @dl = split(/\s+/, $in{'dirs'});
18 -d $d || &error(&text('save_edir', $d));
20 @dl || &error($text{'save_enone'});
22 @dl == 1 || &error($text{'save_esub'});
23 if (&root_dir($dl[0]) ne $dl[0]) {
24 &error($text{'save_eroot'});
28 @devno = map { (stat($_))[0] } @dl;
29 $exp{'alldirs'} = $in{'alldirs'};
30 $exp{'ro'} = $in{'ro'};
31 $exp{'kerb'} = $in{'kerb'};
33 if (!$in{'maproot_def'}) {
34 $in{'maproot'} =~ /^-?\d+$/ || defined(getpwnam($in{'maproot'})) ||
35 &error(&text('save_euser', $in{'maproot'}));
36 if ($in{'maprootg_def'}) {
37 @rgl = split(/\s+/, $in{'maprootg'});
39 $g =~ /^-?\d+$/ || defined(getgrnam($g)) ||
40 &error(&text('save_egroup', $g));
42 $exp{'maproot'} = "$in{'maproot'}:".join(':', @rgl);
44 else { $exp{'maproot'} = $in{'maproot'}; }
47 if (!$in{'mapall_def'}) {
48 $in{'mapall'} =~ /^-?\d+$/ || defined(getpwnam($in{'mapall'})) ||
49 &error(&text('save_euser', $in{'mapall'}));
50 if ($in{'mapallg_def'}) {
51 @rgl = split(/\s+/, $in{'mapallg'});
53 $g =~ /^-?\d+$/ || defined(getgrnam($g)) ||
54 &error(&text('save_egroup', $g));
56 $exp{'mapall'} = "$in{'mapall'}:".join(':', @agl);
58 else { $exp{'mapall'} = $in{'mapall'}; }
61 if (!$in{'maproot_def'} + !$in{'mapall_def'} + $in{'kerb'} > 1) {
62 &error($text{'save_ekerb'});
65 if ($in{'cmode'} == 0) {
66 # Exporting to a list of hosts
67 @hl = split(/\s+/, $in{'hosts'});
68 @hl || &error($text{'save_ehosts'});
71 $ip = &to_ipaddress($h) || &to_ip6address($h);
72 if ($ip) { push(@iplist, $ip); }
76 # Exporting to a subnet
77 &check_ipaddress($in{'network'}) ||
78 &error(&text('save_enetwork', $in{'network'}));
79 &check_ipaddress($in{'mask'}) ||
80 &error(&text('save_enetmask', $in{'netmask'}));
81 $exp{'network'} = $in{'network'};
82 $exp{'mask'} = $in{'mask'};
85 # Check for an export to the same host on the same local filesystem
86 &lock_file($config{'exports_file'});
87 @exps = &list_exports();
88 for($i=0; $i<@exps; $i++) {
89 next if (defined($in{'index'}) && $in{'index'} == $i);
91 foreach $d (@{$exps[$i]->{'dirs'}}) {
92 if (&indexof((stat($d))[0], @devno) >= 0) {
93 # Same filesystem as this export..
98 foreach $h (@{$exps[$i]->{'hosts'}}) {
99 $ip = &to_ipaddress($h) || &to_ip6address($h);
100 if ($ip && &indexof($ip, @iplist) >= 0) {
101 # Another export on this filesystem is to the same host
102 &error(&text('save_esame1', $samefs, $h));
105 if ($exp{'mask'} && $exp{'mask'} eq $exps[$i]->{'mask'} &&
106 $exp{'network'} eq $exps[$i]->{'network'}) {
107 # Another export on this filesystem to the same net
108 &error(&text('save_esame1', $samefs, $exp{'network'}));
112 if (defined($in{'index'})) {
113 $old = $exps[$in{'index'}];
114 $exp{'public'} = $old->{'public'};
115 $exp{'webnfs'} = $old->{'webnfs'};
116 $exp{'index'} = $old->{'index'};
117 &modify_export($old, \%exp);
120 &create_export(\%exp);
122 &unlock_file($config{'exports_file'});
126 # Returns the root directory of the filesystem some path is in
130 my @pst = stat($dir);
132 if ($dir eq "/") { return "/"; }
134 $dir =~ s/\/[^\/]+$//g;
135 if ($dir eq "") { $dir = "/"; }
136 my @ust = stat($dir);
137 if ($ust[0] != $pst[0]) { return $lastdir; }