Handle hostnames with upper-case letters
[webmin.git] / mount / linux-lib.pl
1 # linux-lib.pl
2 # Mount table functions for linux
3
4 if (!$no_check_support) {
5         if (&has_command("amd")) {
6                 local $amd = &read_amd_conf();
7                 $amd_support = $amd =~ /\[\s*global\s*\]/i ? 2 : 1;
8                 }
9         $autofs_support = &has_command("automount");
10         if (&has_command("mount.cifs")) {
11                 $cifs_support = 4;
12                 }
13         if (&has_command("mount.smbfs")) {
14                 $smbfs_support = &backquote_command("mount.smbfs -v 2>&1", 1) =~ /username=/i ? 4 : 3;
15                 $smbfs_fs = "smbfs";
16                 }
17         elsif (&has_command("mount.smb")) {
18                 $smbfs_support = &backquote_command("mount.smb -v 2>&1", 1) =~ /username=/i ? 4 : 3;
19                 $smbfs_fs = "smb";
20                 }
21         elsif (&has_command("smbmount")) {
22                 $smbfs_support = &backquote_command("smbmount -v 2>&1", 1) =~ /Version\s+2/i ? 2 : 1;
23                 $smbfs_fs = "smbfs";
24                 }
25         $swaps_support = -r "/proc/swaps";
26         if (&backquote_command("uname -r") =~ /^(\d+\.\d+)/ && $1 >= 2.4) {
27                 $tmpfs_support = 1;
28                 $ext3_support = 1;
29                 $no_mount_check = 1;
30                 $bind_support = 1;      # XXX which version?
31                 if ($1 >= 2.6) {
32                         $ext4_support = 1;
33                         }
34                 }
35         if (&has_command("mkfs.xfs")) {
36                 $xfs_support = 1;
37                 }
38         if (&has_command("mkfs.jfs")) {
39                 $jfs_support = 1;
40                 }
41         }
42
43 # We always need to check this, to fix up LABEL= mounts
44 if (&has_command("e2label")) {
45         $has_e2label = 1;
46         }
47 if (&has_command("xfs_db")) {
48         $has_xfs_db = 1;
49         }
50 if (&has_command("vol_id")) {
51         $has_volid = 1;
52         }
53 if (&has_command("reiserfstune")) {
54         $has_reiserfstune = 1;
55         }
56 $uuid_directory = "/dev/disk/by-uuid";
57
58 # Return information about a filesystem, in the form:
59 #  directory, device, type, options, fsck_order, mount_at_boot
60 # If a field is unused or ignored, a - appears instead of the value.
61 # Swap-filesystems (devices or files mounted for VM) have a type of 'swap',
62 # and 'swap' in the directory field
63 sub list_mounts
64 {
65 return @list_mounts_cache if (@list_mounts_cache);
66 local(@rv, @p, @o, $_, $i, $j);
67 $i = 0;
68
69 # Get /etc/fstab mounts
70 open(FSTAB, $config{fstab_file});
71 while(<FSTAB>) {
72         local(@o, $at_boot);
73         chop; s/#.*$//g;
74         if (!/\S/ || /\signore\s/) { next; }
75         @p = split(/\s+/, $_);
76         if ($p[2] eq "proc") { $p[0] = "proc"; }
77         elsif ($p[2] eq "auto") { $p[2] = "*"; }
78         elsif ($p[2] eq "swap") { $p[1] = "swap"; }
79         elsif ($p[2] eq $smbfs_fs || $p[2] eq "cifs") {
80                 $p[0] =~ s/\\040/ /g;
81                 $p[0] =~ s/\//\\/g;
82                 }
83         $rv[$i] = [ $p[1], $p[0], $p[2] ];
84         $rv[$i]->[5] = "yes";
85         @o = split(/,/ , $p[3] eq "defaults" ? "" : $p[3]);
86         if (($j = &indexof("noauto", @o)) >= 0) {
87                 # filesytem is not mounted at boot
88                 splice(@o, $j, 1);
89                 $rv[$i]->[5] = "no";
90                 }
91         if (($j = &indexof("bind", @o)) >= 0) {
92                 # Special bind option, which indicates a loopback filesystem
93                 splice(@o, $j, 1);
94                 $rv[$i]->[2] = "bind";
95                 }
96         $rv[$i]->[3] = (@o ? join(',' , @o) : "-");
97         $rv[$i]->[4] = (@p >= 5 ? $p[5] : 0);
98         $i++;
99         }
100 close(FSTAB);
101
102 if ($amd_support == 1) {
103         # Get old automounter configuration, as used by redhat
104         local $amd = &read_amd_conf();
105         if ($amd =~ /MOUNTPTS='(.*)'/) {
106                 @p = split(/\s+/, $1);
107                 for($j=0; $j<@p; $j+=2) {
108                         $rv[$i++] = [ $p[$j], $p[$j+1], "auto",
109                                       "-", 0, "yes" ];
110                         }
111                 }
112         }
113 elsif ($amd_support == 2) {
114         # Guess what? There's now a *new* amd config file format, introduced
115         # in redhat 6.1 and caldera 2.3
116         local @amd = &parse_amd_conf();
117         local @sp = split(/:/, $amd[0]->{'opts'}->{'search_path'});
118         local ($am, $sp);
119         foreach $am (@amd) {
120                 local $mn = $am->{'opts'}->{'map_name'};
121                 if ($mn !~ /^\//) {
122                         foreach $sp (@sp) {
123                                 if (-r "$sp/$mn") {
124                                         $mn = "$sp/$mn";
125                                         last;
126                                         }
127                                 }
128                         }
129                 $rv[$i++] = [ $am->{'dir'}, $mn,
130                               "auto", $am->{'opts'}, 0, "yes" ]
131                         if ($am->{'dir'} ne 'global');
132                 }
133         }
134
135 # Get kernel automounter configuration
136 if ($autofs_support) {
137         open(AUTO, $config{'autofs_file'});
138         while(<AUTO>) {
139                 chop;
140                 s/#.*$//g;
141                 if (/^\s*(\S+)\s+(\S+)\s*(.*)$/) {
142                         $rv[$i++] = [ $1, $2, "autofs",
143                                       ($3 ? &autofs_options($3) : "-"),
144                                       0, "yes" ];
145                         }
146                 }
147         close(AUTO);
148         }
149
150 @list_mounts_cache = @rv;
151 return @rv;
152 }
153
154
155 # create_mount(directory, device, type, options, fsck_order, mount_at_boot)
156 # Add a new entry to the fstab file, old or new automounter file
157 sub create_mount
158 {
159 local(@mlist, @amd, $_); local($opts);
160
161 if ($_[2] eq "auto") {
162         if ($amd_support == 1) {
163                 # Adding an old automounter mount
164                 local $amd = &read_amd_conf();
165                 local $m = "$_[0] $_[1]";
166                 if ($amd =~ /MOUNTPTS=''/) {
167                         $amd =~ s/MOUNTPTS=''/MOUNTPTS='$m'/;
168                         }
169                 else {
170                         $amd =~ s/MOUNTPTS='(.*)'/MOUNTPTS='$1 $m'/;
171                         }
172                 &write_amd_conf($amd);
173                 }
174         elsif ($amd_support == 2) {
175                 # Adding a new automounter mount
176                 local @amfs = split(/\s+/, $config{'auto_file'});
177                 &open_tempfile(AMD, ">>$amfs[0]");
178                 &print_tempfile(AMD, "\n");
179                 &print_tempfile(AMD, "[ $_[0] ]\n");
180                 &print_tempfile(AMD, "map_name = $_[1]\n");
181                 &close_tempfile(AMD);
182                 }
183         }
184 elsif ($_[2] eq "autofs") {
185         # Adding a new automounter mount
186         &open_tempfile(AUTO, ">> $config{'autofs_file'}");
187         &print_tempfile(AUTO, "$_[0]  $_[1]");
188         if ($_[3]) {
189                 &print_tempfile(AUTO, "  ",&autofs_args($_[3]));
190                 }
191         &print_tempfile(AUTO, "\n");
192         &close_tempfile(AUTO);
193         }
194 else {
195         # Adding a normal mount to the fstab file
196         local $dev = $_[1];
197         if ($_[2] eq $smbfs_fs || $_[2] eq "cifs") {
198                 $dev =~ s/\\/\//g;
199                 $dev =~ s/ /\\040/g;
200                 }
201         &open_tempfile(FSTAB, ">> $config{fstab_file}");
202         &print_tempfile(FSTAB, "$dev  $_[0]  $_[2]");
203         local @opts = $_[3] eq "-" ? ( ) : split(/,/, $_[3]);
204         if ($_[5] eq "no") {
205                 push(@opts, "noauto");
206                 }
207         else {
208                 @opts = grep { $_ !~ /^(auto|noauto)$/ } @opts;
209                 }
210         if ($_[2] eq "bind") {
211                 push(@opts, "bind");
212                 }
213         if (!@opts) { &print_tempfile(FSTAB, "  defaults"); }
214         else { &print_tempfile(FSTAB, "  ".join(",", @opts)); }
215         &print_tempfile(FSTAB, "  0  ");
216         &print_tempfile(FSTAB, $_[4] eq "-" ? "0\n" : "$_[4]\n");
217         &close_tempfile(FSTAB);
218         }
219 undef(@list_mounts_cache);
220 }
221
222
223 # change_mount(num, directory, device, type, options, fsck_order, mount_at_boot)
224 # Change an existing permanent mount
225 sub change_mount
226 {
227 local($i, @fstab, $line, $opts, $j, @amd);
228 $i = 0;
229
230 # Update fstab file
231 open(FSTAB, $config{fstab_file});
232 @fstab = <FSTAB>;
233 close(FSTAB);
234 &open_tempfile(FSTAB, "> $config{fstab_file}");
235 foreach (@fstab) {
236         chop; ($line = $_) =~ s/#.*$//g;
237         if ($line =~ /\S/ && $line !~ /\signore\s/ && $i++ == $_[0]) {
238                 # Found the line to replace
239                 local $dev = $_[2];
240                 $dev =~ s/ /\\040/g;
241                 &print_tempfile(FSTAB, "$dev  $_[1]  $_[3]");
242                 local @opts = $_[4] eq "-" ? ( ) : split(/,/, $_[4]);
243                 if ($_[6] eq "no") {
244                         push(@opts, "noauto");
245                         }
246                 else {
247                         @opts = grep { $_ !~ /^(auto|noauto)$/ } @opts;
248                         }
249                 if ($_[3] eq "bind") {
250                         push(@opts, "bind");
251                         }
252                 if (!@opts) { &print_tempfile(FSTAB, "  defaults"); }
253                 else { &print_tempfile(FSTAB, "  ".join(",", @opts)); }
254                 &print_tempfile(FSTAB, "  0  ");
255                 &print_tempfile(FSTAB, $_[5] eq "-" ? "0\n" : "$_[5]\n");
256                 }
257         else { &print_tempfile(FSTAB, $_,"\n"); }
258         }
259 &close_tempfile(FSTAB);
260
261 if ($amd_support == 1) {
262         # Update older amd configuration
263         local $amd = &read_amd_conf();
264         if ($amd =~ /MOUNTPTS='(.*)'/) {
265                 # found mount points line..
266                 local @mpts = split(/\s+/, $1);
267                 for($j=0; $j<@mpts; $j+=2) {
268                         if ($i++ == $_[0]) {
269                                 $mpts[$j] = $_[1];
270                                 $mpts[$j+1] = $_[2];
271                                 }
272                         }
273                 local $mpts = join(" ", @mpts);
274                 $amd =~ s/MOUNTPTS='(.*)'/MOUNTPTS='$mpts'/;
275                 }
276         &write_amd_conf($amd);
277         }
278 elsif ($amd_support == 2) {
279         # Update new amd configuration
280         local @amd = &parse_amd_conf();
281         foreach $am (@amd) {
282                 next if ($am->{'dir'} eq 'global');
283                 if ($i++ == $_[0]) {
284                         local $lref = &read_file_lines($am->{'file'});
285                         local @nl = ( "[ $_[1] ]" );
286                         local %opts = %{$am->{'opts'}};
287                         $opts{'map_name'} = $_[2];
288                         foreach $o (keys %opts) {
289                                 push(@nl, "$o = $opts{$o}");
290                                 }
291                         splice(@$lref, $am->{'line'},
292                                $am->{'eline'} - $am->{'line'} + 1, @nl);
293                         &flush_file_lines();
294                         }
295                 }
296         }
297
298 # Update autofs configuration
299 if ($autofs_support) {
300         open(AUTO, $config{'autofs_file'});
301         @auto = <AUTO>;
302         close(AUTO);
303         &open_tempfile(AUTO, "> $config{'autofs_file'}");
304         foreach (@auto) {
305                 chop; ($line = $_) =~ s/#.*$//g;
306                 if ($line =~ /\S/ && $i++ == $_[0]) {
307                         &print_tempfile(AUTO, "$_[1]  $_[2]");
308                         if ($_[4]) {
309                                 &print_tempfile(AUTO, "  ",&autofs_args($_[4]));
310                                 }
311                         &print_tempfile(AUTO, "\n");
312                         }
313                 else {
314                         &print_tempfile(AUTO, $_,"\n");
315                         }
316                 }
317         &close_tempfile(AUTO);
318         }
319 undef(@list_mounts_cache);
320 }
321
322
323 # delete_mount(index)
324 # Delete an existing permanent mount
325 sub delete_mount
326 {
327 local($i, @fstab, $line, $opts, $j, @amd);
328 $i = 0;
329
330 # Update fstab file
331 open(FSTAB, $config{fstab_file});
332 @fstab = <FSTAB>;
333 close(FSTAB);
334 &open_tempfile(FSTAB, ">$config{fstab_file}");
335 foreach (@fstab) {
336         chop; ($line = $_) =~ s/#.*$//g;
337         if ($line !~ /\S/ || $line =~ /\signore\s/ || $i++ != $_[0]) {
338                 # Don't delete this line
339                 &print_tempfile(FSTAB, $_,"\n");
340                 }
341         }
342 &close_tempfile(FSTAB);
343
344 if ($amd_support == 1) {
345         # Update older amd configuration
346         local $foundamd = 0;
347         local $amd = &read_amd_conf();
348         if ($amd =~ /MOUNTPTS='(.*)'/) {
349                 # found mount points line..
350                 local @mpts = split(/\s+/, $1);
351                 for($j=0; $j<@mpts; $j+=2) {
352                         if ($i++ == $_[0]) {
353                                 splice(@mpts, $j, 2);
354                                 $foundamd = 1;
355                                 }
356                         }
357                 local $mpts = join(" ", @mpts);
358                 $amd =~ s/MOUNTPTS='(.*)'/MOUNTPTS='$mpts'/;
359                 }
360         &write_amd_conf($amd) if ($foundamd);
361         }
362 elsif ($amd_support == 2) {
363         # Update new amd configuration
364         local @amd = &parse_amd_conf();
365         foreach $am (@amd) {
366                 next if ($am->{'dir'} eq 'global');
367                 if ($i++ == $_[0]) {
368                         local $lref = &read_file_lines($am->{'file'});
369                         splice(@$lref, $am->{'line'},
370                                $am->{'eline'} - $am->{'line'} + 1);
371                         &flush_file_lines();
372                         }
373                 }
374         }
375
376 # Update AMD file
377 if ($amd_support) {
378         open(AMD, $config{auto_file});
379         @amd = <AMD>;
380         close(AMD);
381         &open_tempfile(AMD, ">$config{auto_file}");
382         foreach (@amd) {
383                 if (/MOUNTPTS='(.*)'/) {
384                         # found mount points line..
385                         @mpts = split(/\s+/, $1);
386                         for($j=0; $j<@mpts; $j+=2) {
387                                 if ($i++ != $_[0]) {
388                                         push(@nmpts, $mpts[$j]);
389                                         push(@nmpts, $mpts[$j+1]);
390                                         }
391                                 }
392                         &print_tempfile(AMD, "MOUNTPTS='".join(' ', @nmpts)."'\n");
393                         }
394                 else { &print_tempfile(AMD, $_); }
395                 }
396         &close_tempfile(AMD);
397         }
398
399 # Update autofs file
400 if ($autofs_support) {
401         open(AUTO, $config{'autofs_file'});
402         @auto = <AUTO>;
403         close(AUTO);
404         &open_tempfile(AUTO, ">$config{'autofs_file'}");
405         foreach (@auto) {
406                 chop; ($line = $_) =~ s/#.*$//g;
407                 if ($line !~ /\S/ || $i++ != $_[0]) {
408                         # keep this line
409                         &print_tempfile(AUTO, $_,"\n");
410                         }
411                 }
412         &close_tempfile(AUTO);
413         }
414 undef(@list_mounts_cache);
415 }
416
417
418 # list_mounted([no-label])
419 # Return a list of all the currently mounted filesystems and swap files.
420 # The list is in the form:
421 #  directory device type options
422 sub list_mounted
423 {
424 return @list_mounted_cache
425         if (@list_mounted_cache && $list_mounted_cache_mode == $_[0]);
426 local(@rv, @p, @o, $mo, $_, %smbopts);
427 local @mounts = &list_mounts();
428
429 &read_smbopts();
430 open(MTAB, "/etc/mtab");
431 while(<MTAB>) {
432         chop;
433         s/#.*$//g; if (!/\S/) { next; }
434         @p = split(/\s+/, $_);
435         if ($p[2] eq "auto" || $p[0] =~ /^\S+:\(pid\d+\)$/) {
436                 # Automounter map.. turn the map= option into the device
437                 @o = split(/,/ , $p[3]);
438                 ($mo) = grep {/^map=/} (@o);
439                 $mo =~ /^map=(.*)$/; $p[0] = $1;
440                 $p[3] = join(',' , grep {!/^map=/} (@o));
441                 $p[2] = "auto";
442                 }
443         elsif ($p[2] eq "autofs") {
444                 # Kernel automounter map.. use the pid to find the map
445                 $p[0] =~ /automount\(pid(\d+)\)/ || next;
446                 $out = &backquote_command("ps hwwww $1", 1);
447                 $out =~ /automount\s+(.*)\s*(\S+)\s+(file|program|yp)(,\S+)?\s+(\S+)/ || next;
448                 $p[0] = $5;
449                 $p[3] = $1 ? &autofs_options($1) : "-";
450                 }
451         elsif ($p[2] eq $smbfs_fs || $p[2] eq "cifs") {
452                 # Change from //FOO/BAR to \\foo\bar
453                 $p[0] =~ s/\//\\/g;
454                 $p[0] = lc($p[0]);
455                 $p[3] = $smbopts{$p[1]};
456                 }
457         elsif ($p[2] eq "proc") {
458                 # The source for proc mounts is always proc
459                 $p[0] = "proc";
460                 }
461         if (!$_[0] && ($p[2] =~ /^ext\d+$/ && $has_e2label ||
462                        $p[2] eq "xfs" && $has_xfs_db ||
463                        $p[2] eq "reiserfs" && $has_reiserfstune)) {
464                 # Check for a label on this partition, and there is one
465                 # and this filesystem is in fstab with the label, change
466                 # the device.
467                 local $label;
468                 if ($p[2] eq "xfs") {
469                         local $out = &backquote_command("xfs_db -x -p xfs_admin -c label -r $p[0] 2>&1", 1);
470                         $label = $1 if ($out =~ /label\s*=\s*"(.*)"/ &&
471                                         $1 ne '(null)');
472                         }
473                 elsif ($p[2] eq "reiserfs") {
474                         local $out = &backquote_command("reiserfstune $p[0] 2>&1");
475                         if ($out =~ /LABEL:\s*(\S+)/) {
476                                 $label = $1;
477                                 }
478                         }
479                 else {
480                         $label = &backquote_command("e2label $p[0] 2>&1", 1);
481                         chop($label);
482                         }
483                 if (!$?) {
484                         foreach $m (@mounts) {
485                                 if ($m->[0] eq $p[1] &&
486                                     $m->[1] eq "LABEL=$label") {
487                                         $p[0] = "LABEL=$label";
488                                         last;
489                                         }
490                                 }
491                         }
492                 }
493
494         # Check for a UUID on this partition, and if there is one
495         # and the filesystem is in fstab with the label, change
496         # the device.
497         if (!$_[0]) {
498                 local $uuid = &device_to_uuid($p[0], \@mounts);
499                 if ($uuid) {
500                         $p[0] = "UUID=$uuid";
501                         }
502                 }
503
504         # check fstab for a mount on the same dir which is a symlink
505         # to the device
506         local @st = stat($p[0]);
507         foreach $m (@mounts) {
508                 if ($m->[0] eq $p[1]) {
509                         local @fst = stat($m->[1]);
510                         if ($fst[0] == $st[0] && $fst[1] == $st[1]) {
511                                 # symlink to the same place!
512                                 $p[0] = $m->[1];
513                                 last;
514                                 }
515                         }
516                 }
517
518         if ($p[3] =~ s/,bind,// || $p[3] =~ s/^bind,// ||
519             $p[3] =~ s/,bind$// || $p[3] =~ s/^bind$//) {
520                 # Special bind option, which indicates a loopback filesystem
521                 $p[2] = "bind";
522                 }
523
524         push(@rv, [ $p[1], $p[0], $p[2], $p[3] ]);
525         }
526 close(MTAB);
527 open(SWAPS, "/proc/swaps");
528 while(<SWAPS>) {
529         chop;
530         if (/^(\/\S+)\s+/) {
531                 local $sf = $1;
532                 if ($sf =~ /^\/dev\/ide\// || $sf =~ /^\/dev\/mapper\//) {
533                         # check fstab for a mount on a device which is a symlink
534                         local @st = stat($sf);
535                         foreach $m (@mounts) {
536                                 local @fst = stat($m->[1]);
537                                 if ($m->[2] eq 'swap' && $fst[0] == $st[0] &&
538                                     $fst[1] == $st[1]) {
539                                         $sf = $m->[1];
540                                         last;
541                                         }
542                                 }
543                         }
544
545                 # Convert to UUID format if used in fstab
546                 if (!$_[0]) {
547                         local $uuid = &device_to_uuid($sf, \@mounts);
548                         if ($uuid) {
549                                 $sf = "UUID=$uuid";
550                                 }
551                         }
552                 push(@rv, [ "swap", $sf, "swap", "-" ]);
553                 }
554         }
555 close(SWAPS);
556 @list_mounted_cache = @rv;
557 $list_mounted_cache_mode = $_[0];
558 return @rv;
559 }
560
561 # device_to_uuid(device, [&mounts])
562 # Given a device name like /dev/sda1, return the UUID for it.
563 # If a list of mounts are given, only match if found in mount list.
564 sub device_to_uuid
565 {
566 local ($device, $mounts) = @_;
567 local $uuid;
568 if ($device =~ /^\/dev\// && ($has_volid || -d $uuid_directory)) {
569         if (-d $uuid_directory) {
570                 # Use UUID mapping directory
571                 opendir(DIR, $uuid_directory);
572                 foreach my $f (readdir(DIR)) {
573                         local $linkdest = &simplify_path(
574                                 &resolve_links("$uuid_directory/$f"));
575                         if ($linkdest eq $device) {
576                                 $uuid = $f;
577                                 last;
578                                 }
579                         }
580                 closedir(DIR);
581                 }
582         else {
583                 # Use vol_id command
584                 local $out = &backquote_command(
585                                 "vol_id ".quotemeta($device)." 2>&1", 1);
586                 if ($out =~ /ID_FS_UUID=(\S+)/) {
587                         $uuid = $1;
588                         }
589                 }
590         }
591 if ($uuid && @$mounts) {
592         my $found;
593         foreach my $m (@$mounts) {
594                 if ($m->[1] eq "UUID=$uuid") {
595                         $found++;
596                         last;
597                         }
598                 }
599         $uuid = undef if (!$found);
600         }
601 return $uuid;
602 }
603
604 # mount_dir(directory, device, type, options)
605 # Mount a new directory from some device, with some options. Returns 0 if ok,
606 # or an error string if failed
607 sub mount_dir
608 {
609 local($out, $opts, $shar, %options, %smbopts);
610 local @opts = $_[3] eq "-" || $_[3] eq "" ? ( ) :
611                 grep { $_ ne "noauto" } split(/,/, $_[3]);
612 if ($_[2] eq "bind") {
613         push(@opts, "bind");
614         }
615 $opts = @opts ? "-o ".quotemeta(join(",", @opts)) : "";
616 &parse_options($_[2], $_[3]);
617
618 # Work out args for label or UUID
619 local $devargs;
620 if ($_[1] =~ /LABEL=(.*)/) {
621         $devargs = "-L ".quotemeta($1);
622         }
623 elsif ($_[1] =~ /UUID=(\S+)/) {
624         $devargs = "-U ".quotemeta($1);
625         }
626 else {
627         $devargs = quotemeta($_[1]);
628         }
629
630 if ($_[2] eq "swap") {
631         # Use swapon to add the swap space..
632         local $priarg = $options{'pri'} ne "" ? "-p $options{'pri'}" : "";
633         $out = &backquote_logged("swapon $priarg $devargs 2>&1");
634         if ($out =~ /Invalid argument/) {
635                 # looks like this swap partition isn't ready yet.. set it up
636                 $out = &backquote_logged("mkswap $devargs 2>&1");
637                 if ($?) { return "mkswap failed : <pre>$out</pre>"; }
638                 $out = &backquote_logged("swapon $devargs 2>&1");
639                 }
640         if ($?) { return "<pre>$out</pre>"; }
641         }
642 elsif ($_[2] eq "auto") {
643         # Old automounter filesystem
644         $out = &backquote_logged("amd $_[0] $_[1] >/dev/null 2>/dev/null");
645         if ($?) { return $text{'linux_eamd'}; }
646         }
647 elsif ($_[2] eq "autofs") {
648         # New automounter filesystem
649         $opts = &autofs_args($_[3]);
650         $type = $_[1] !~ /^\// ? "yp" :
651                 (-x $_[1]) ? "program" : "file";
652         $out = &backquote_logged("automount $opts $_[0] $type $_[1] 2>&1");
653         if ($?) { return &text('linux_eauto', "<pre>$out</pre>"); }
654         }
655 elsif ($_[2] eq $smbfs_fs || $_[2] eq "cifs") {
656         local $shar = $_[1];
657         $shar =~ s/\\/\//g if ($shar =~ /^\\/);
658         local $support = $_[2] eq $smbfs_fs ? $smbfs_support : $cifs_support;
659         return uc($_[2])." not supported" if (!$support);
660         local $qshar = quotemeta($shar);
661         if ($support >= 3) {
662                 # SMB filesystem mounted with mount command
663                 local $temp = &transname();
664                 local $ex = &system_logged("mount -t $_[2] $opts $qshar $_[0] >$temp 2>&1 </dev/null");
665                 local $out = `cat $temp`;
666                 unlink($temp);
667                 if ($ex || $out =~ /failed|error/i) {
668                         &system_logged("umount $_[0] >/dev/null 2>&1");
669                         return "<pre>$out</pre>";
670                         }
671                 }
672         elsif ($support == 2) {
673                 # SMB filesystem mounted with version 2.x smbmount
674                 $opts =
675                     ($options{'user'} ? "-U $options{'user'} " : "").
676                     ($options{'passwd'} ? "" : "-N ").
677                     ($options{'workgroup'} ? "-W $options{'workgroup'} " : "").
678                     ($options{'clientname'} ? "-n $options{'clientname'} " : "").
679                     ($options{'machinename'} ? "-I $options{'machinename'} " : "");
680                 &foreign_require("proc");
681                 local ($fh, $fpid) = &proc::pty_process_exec_logged(
682                         "sh -c 'smbmount $shar $_[0] -d 0 $opts'");
683                 if ($options{'passwd'}) {
684                         local $w = &wait_for($fh, "word:");
685                         if ($w < 0) {
686                                 &system_logged("umount $_[0] >/dev/null 2>&1");
687                                 return $text{'linux_esmbconn'};
688                                 }
689                         local $p = "$options{'passwd'}\n";
690                         syswrite($fh, $p, length($p));
691                         }
692                 local $got;
693                 while(<$fh>) {
694                         $got .= $_;
695                         }
696                 if ($got =~ /failed/) {
697                         &system_logged("umount $_[0] >/dev/null 2>&1");
698                         return "<pre>$got</pre>\n";
699                         }
700                 close($fh);
701                 }
702         elsif ($support == 1) {
703                 # SMB filesystem mounted with older smbmount
704                 $shortname = &get_system_hostname();
705                 if ($shortname =~ /^([^\.]+)\.(.+)$/) { $shortname = $1; }
706                 $opts =
707                    ($options{servername} ? "-s $options{servername} " : "").
708                    ($options{clientname} ? "-c $options{clientname} "
709                                          : "-c $shortname ").
710                    ($options{machinename} ? "-I $options{machinename} " : "").
711                    ($options{user} ? "-U $options{user} " : "").
712                    ($options{passwd} ? "-P $options{passwd} " : "-n ").
713                    ($options{uid} ? "-u $options{uid} " : "").
714                    ($options{gid} ? "-g $options{gid} " : "").
715                    ($options{fmode} ? "-f $options{fmode} " : "").
716                    ($options{dmode} ? "-d $options{dmode} " : "");
717                 $out = &backquote_logged("smbmount $shar $_[0] $opts 2>&1 </dev/null");
718                 if ($out) {
719                         &system_logged("umount $_[0] >/dev/null 2>&1");
720                         return "<pre>$out</pre>";
721                         }
722                 }
723         &read_smbopts();
724         $smbopts{$_[0]} = $_[3] eq "-" ? "dummy=1" : $_[3];
725         &write_smbopts();
726         }
727 else {
728         # some filesystem supported by mount
729         local $fs = $_[2] eq "*" ? "auto" : $_[2];
730         $cmd = "mount -t $fs $opts $devargs ".quotemeta($_[0]);
731         $out = &backquote_logged("$cmd 2>&1 </dev/null");
732         if ($?) { return "<pre>$out</pre>"; }
733         }
734 undef(@list_mounted_cache);
735 return 0;
736 }
737
738 # os_remount_dir(directory, device, type, options)
739 # Adjusts the options for some mounted filesystem, by re-mounting
740 sub os_remount_dir
741 {
742 if ($_[2] eq "swap" || $_[2] eq "auto" || $_[2] eq "autofs" ||
743     $_[2] eq $smbfs_fs || $_[2] eq "cifs") {
744         # Cannot use remount
745         local $err = &unmount_dir(@_);
746         return $err if ($err);
747         return &mount_dir(@_);
748         }
749 else {
750         # Attempt to use remount
751         local @opts = $_[3] eq "-" || $_[3] eq "" ? ( ) :
752                         grep { $_ ne "noauto" } split(/,/, $_[3]);
753         push(@opts, "remount");
754         local $opts = @opts ? "-o ".quotemeta(join(",", @opts)) : "";
755         local $fs = $_[2] eq "*" ? "auto" : $_[2];
756         if ($_[1] =~ /LABEL=(.*)/) {
757                 $cmd = "mount -t $fs -L $1 $opts $_[0]";
758                 }
759         elsif ($_[1] =~ /UUID=(\S+)/) {
760                 $cmd = "mount -t $fs -U $1 $opts $_[0]";
761                 }
762         else {
763                 $cmd = "mount -t $fs $opts $_[1] $_[0]";
764                 }
765         $out = &backquote_logged("$cmd 2>&1 </dev/null");
766         if ($?) { return "<pre>$out</pre>"; }
767         undef(@list_mounted_cache);
768         return undef;
769         }
770 }
771
772 # unmount_dir(directory, device, type, options, [force])
773 # Unmount a directory that is currently mounted. Returns 0 if ok,
774 # or an error string if failed
775 sub unmount_dir
776 {
777 local($out, %smbopts, $dir);
778 if ($_[2] eq "swap") {
779         # Use swapoff to remove the swap space..
780         $out = &backquote_logged("swapoff $_[1]");
781         if ($?) { return "<pre>$out</pre>"; }
782         }
783 elsif ($_[2] eq "auto") {
784         # Kill the amd process
785         $dir = $_[0];
786         if (&backquote_command("cat /etc/mtab") =~ /:\(pid([0-9]+)\)\s+$dir\s+(auto|nfs)\s+/) {
787                 &kill_logged('TERM', $1) || return $text{'linux_ekillamd'};
788                 }
789         sleep(2);
790         }
791 elsif ($_[2] eq "autofs") {
792         # Kill the automount process
793         $dir = $_[0];
794         &backquote_command("cat /etc/mtab") =~ /automount\(pid([0-9]+)\)\s+$dir\s+autofs\s+/;
795         &kill_logged('TERM', $1) || return $text{'linux_ekillauto'};
796         sleep(2);
797         }
798 else {
799         local $fflag = $_[4] ? "-l" : "";
800         $out = &backquote_logged("umount $fflag $_[0] 2>&1");
801         if ($?) { return "<pre>$out</pre>"; }
802         if ($_[2] eq $smbfs_fs || $_[2] eq "cifs") {
803                 # remove options from list
804                 &read_smbopts();
805                 delete($smbopts{$_[0]});
806                 &write_smbopts();
807                 &execute_command("rmmod smbfs");
808                 &execute_command("rmmod cifs");
809                 }
810         }
811 undef(@list_mounted_cache);
812 return 0;
813 }
814
815 # can_force_unmount_dir(directory, device, type)
816 # Returns 1 if some directory can be forcibly un-mounted
817 sub can_force_unmount_dir
818 {
819 if ($_[2] ne "swap" && $_[2] ne "auto" && $_[2] ne "autofs") {
820         # All filesystems using the normal 'mount' command can be
821         return 1;
822         }
823 else {
824         return 0;
825         }
826 }
827
828 # mount_modes(type)
829 # Given a filesystem type, returns 4 numbers that determine how the file
830 # system can be mounted, and whether it can be fsck'd
831 #  0 - cannot be permanently recorded
832 #       (smbfs under linux before 2.2)
833 #  1 - can be permanently recorded, and is always mounted at boot
834 #       (swap under linux)
835 #  2 - can be permanently recorded, and may or may not be mounted at boot
836 #       (most normal filesystems)
837 # The second is:
838 #  0 - mount is always permanent => mounted when saved
839 #       (swap under linux before 2.2, or any filesystem that is always
840 #        mounted at boot by some script)
841 #  1 - doesn't have to be permanent
842 #       (normal fs types)
843 # The third is:
844 #  0 - cannot be fsck'd at boot time
845 #  1 - can be be fsck'd at boot
846 # The fourth is:
847 #  0 - can be unmounted
848 #  1 - cannot be unmounted
849 # The (optional) fourth is:
850 #  0 - can be edited
851 #  1 - cannot be edited (because is always mounted at boot by some script)
852 sub mount_modes
853 {
854 if ($_[0] eq "swap")
855         { return (1, $swaps_support ? 1 : 0, 0, 0); }
856 elsif ($_[0] eq "auto" || $_[0] eq "autofs")
857         { return (1, 1, 0, 0); }
858 elsif ($_[0] eq $smbfs_fs)
859         { return ($smbfs_support >= 3 ? 2 : 0, 1, 0, 0); }
860 elsif ($_[0] eq "cifs") { return (2, 1, 0, 0); }
861 elsif ($_[0] =~ /^ext\d+$/ || $_[0] eq "minix" ||
862        $_[0] eq "xiafs" || $_[0] eq "xfs" || $_[0] eq "jfs")
863         { return (2, 1, 1, 0); }
864 else
865         { return (2, 1, 0, 0); }
866 }
867
868
869 # disk_space(type, directory)
870 # Returns the amount of total and free space for some filesystem, or an
871 # empty array if not appropriate.
872 sub disk_space
873 {
874 if (&get_mounted($_[1], "*") < 0) { return (); }
875 if ($_[0] eq "proc" || $_[0] eq "swap" ||
876     $_[0] eq "auto" || $_[0] eq "autofs") { return (); }
877 &clean_language();
878 local $out = &backquote_command("df -k ".quotemeta($_[1]), 1);
879 &reset_environment();
880 if ($out =~ /Mounted on\n\S+\s+(\S+)\s+\S+\s+(\S+)/) {
881         return ($1, $2);
882         }
883 return ( );
884 }
885
886 # inode_space(type, directory)
887 # Returns the total and free number of inodes for some filesystem.
888 sub inode_space
889 {
890 if (&get_mounted($_[1], "*") < 0) { return (); }
891 &clean_language();
892 local $out = &backquote_command("df -i $_[1]", 1);
893 &reset_environment();
894 if ($out =~ /Mounted on\n\S+\s+(\S+)\s+\S+\s+(\S+)/) {
895         return ($1, $2);
896         }
897 return ( );
898 }
899
900 # list_fstypes()
901 # Returns an array of all the supported filesystem types. If a filesystem is
902 # found that is not one of the supported types, generate_location() and
903 # generate_options() will not be called for it.
904 sub list_fstypes
905 {
906 local @sup = ("ext2", "minix", "msdos", "nfs", "nfs4", "iso9660", "ext",
907               "xiafs", "hpfs", "fat", "vfat", "umsdos", "sysv", "reiserfs",
908               "ntfs", "hfs", "fatx");
909 push(@sup, $smbfs_fs) if ($smbfs_support);
910 push(@sup, "cifs") if ($cifs_support);
911 push(@sup, "auto") if ($amd_support);
912 push(@sup, "autofs") if ($autofs_support);
913 push(@sup, "tmpfs") if ($tmpfs_support);
914 push(@sup, "ext3") if ($ext3_support);
915 push(@sup, "ext4") if ($ext4_support);
916 push(@sup, "xfs") if ($xfs_support);
917 push(@sup, "jfs") if ($jfs_support);
918 push(@sup, "bind") if ($bind_support);
919 push(@sup, "swap");
920 return @sup;
921 }
922
923
924 # fstype_name(type)
925 # Given a short filesystem type, return a human-readable name for it
926 sub fstype_name
927 {
928 local(%fsmap);
929 %fsmap = ("ext2","Old Linux Native Filesystem",
930           "ext3","Linux Native Filesystem",
931           "ext4","New Linux Native Filesystem",
932           "minix","Minix Filesystem",
933           "msdos","MS-DOS Filesystem",
934           "nfs","Network Filesystem",
935           "nfs4","Network Filesystem v4",
936           $smbfs_fs,"Windows Networking Filesystem",
937           "cifs","Common Internet Filesystem",
938           "iso9660","ISO9660 CD-ROM",
939           "ext","Old EXT Linux Filesystem",
940           "xiafs","Old XIAFS Linux Filesystem",
941           "hpfs","OS/2 Filesystem",
942           "fat","MS-DOS Filesystem",
943           "vfat","Windows Filesystem",
944           "umsdos","Linux on top of MS-DOS Filesystem",
945           "sysv","System V Filesystem",
946           "swap","Virtual Memory",
947           "proc","Kernel Filesystem",
948           "sysfs","Kernel Filesystem",
949           "devpts","Pseudoterminal Device Filesystem",
950           "auto",($autofs_support ? "Old " : "")."Automounter Filesystem",
951           "reiserfs","Reiser Filesystem",
952           "autofs","New Automounter Filesystem",
953           "usbdevfs","USB Devices",
954           "shm","SysV Shared Memory",
955           "tmpfs","RAM/Swap Disk",
956           "devtmpfs","RAM/Swap Disk",
957           "ramfs","RAM Disk",
958           "btrfs","Oracle B-Tree Filesystem",
959           "ocfs2","Oracle Clustering Filesystem",
960           "gfs2","RedHat Clustering Filesystem",
961           "xfs","SGI Filesystem",
962           "jfs","IBM Journalling Filesystem",
963           "ntfs","Windows NT Filesystem",
964           "bind","Loopback Filesystem",
965           "hfs","Apple Filesystem",
966           "fatx","XBOX Filesystem",
967           );
968 return $config{long_fstypes} && $fsmap{$_[0]} ? $fsmap{$_[0]} : uc($_[0]);
969 }
970
971
972 # multiple_mount(type)
973 # Returns 1 if filesystems of this type can be mounted multiple times, 0 if not
974 sub multiple_mount
975 {
976 return ($_[0] eq "nfs" || $_[0] eq "nfs4" || $_[0] eq "auto" ||
977         $_[0] eq "autofs" || $_[0] eq "bind" || $_[0] eq "tmpfs");
978 }
979
980
981 # generate_location(type, location)
982 # Output HTML for editing the mount location of some filesystem.
983 sub generate_location
984 {
985 if (($_[0] eq "nfs") || ($_[0] eq "nfs4")) {
986         # NFS mount from some host and directory
987         $_[1] =~ /^([^:]+):(.*)$/;
988         print "<tr> <td>", &hlink("<b>$text{'linux_nfshost'}</b>", "nfshost"), "</td>\n";
989         print "<td><input name=nfs_host size=20 value=\"$1\">\n";
990         &nfs_server_chooser_button("nfs_host");
991         print "&nbsp;", &hlink("<b>$text{'linux_nfsdir'}</b>", "nfsdir"), "\n";
992         printf "<input name=nfs_dir size=20 value=%s>\n",
993                ($_[0] eq "nfs4") && ($2 eq "") ? "/" : $2;
994         &nfs_export_chooser_button("nfs_host", "nfs_dir");
995         print "</td> </tr>\n";
996         }
997 elsif ($_[0] eq "auto") {
998         # Using some automounter map
999         print "<tr> <td><b>$text{'linux_map'}</b></td>\n";
1000         print "<td><input name=auto_map size=20 value=\"$_[1]\">\n";
1001         print &file_chooser_button("auto_map", 0);
1002         print "</td> <td colspan=2></td> </tr>\n";
1003         }
1004 elsif ($_[0] eq "autofs") {
1005         # Using some kernel automounter map
1006         print "<tr> <td><b>$text{'linux_map'}</b></td>\n";
1007         print "<td><input name=autofs_map size=20 value=\"$_[1]\">\n";
1008         print &file_chooser_button("autofs_map", 0);
1009         print "</td> <td colspan=2></td> </tr>\n";
1010         }
1011 elsif ($_[0] eq "swap") {
1012         # Swap file or device
1013         &foreign_require("fdisk");
1014         printf "<tr> <td valign=top><b>$text{'linux_swapfile'}</b></td>\n";
1015         print "<td colspan=3>\n";
1016         local ($found, $ufound);
1017
1018         # Show partitions input
1019         local $sel = &fdisk::partition_select("lnx_disk", $_[1], 3, \$found);
1020         printf "<input type=radio name=lnx_dev value=0 %s> %s %s<br>\n",
1021                 $found ? "checked" : "", $text{'linux_disk'}, $sel;
1022
1023         # Show UUID input
1024         if ($has_volid || -d $uuid_directory) {
1025                 local $u = $_[1] =~ /UUID=(\S+)/ ? $1 : undef;
1026                 local $usel = &fdisk::volid_select("lnx_uuid", $u, \$ufound);
1027                 if ($usel) {
1028                         printf "<input type=radio name=lnx_dev value=5 %s> %s %s<br>\n", $ufound ? "checked" : "", $text{'linux_usel'}, $usel;
1029                         }
1030                 }
1031
1032         # Show other file input
1033         printf "<input type=radio name=lnx_dev value=1 %s> %s\n",
1034                 $found || $ufound ? "" : "checked", $text{'linux_swapfile'};
1035         printf "<input name=lnx_other size=35 value='%s'> %s<br>\n",
1036                 $found || $ufound ? "" : $_[1],
1037                 &file_chooser_button("lnx_other");
1038         print "</td> </tr>\n";
1039         }
1040 elsif ($_[0] eq $smbfs_fs || $_[0] eq "cifs") {
1041         # Windows filesystem
1042         $_[1] =~ /^\\\\([^\\]*)\\(.*)$/;
1043         local ($server, $share) = ($1, $2);
1044         print "<tr> <td><b>$text{'linux_smbserver'}</b></td>\n";
1045         print "<td><input name=smbfs_server value=\"$server\" size=20>\n";
1046         &smb_server_chooser_button("smbfs_server");
1047         print "</td>\n";
1048         print "<td><b>$text{'linux_smbshare'}</b></td>\n";
1049         print "<td><input name=smbfs_share value=\"$share\" size=20>\n";
1050         &smb_share_chooser_button("smbfs_server", "smbfs_share");
1051         print "</td> </tr>\n";
1052         }
1053 elsif ($_[0] eq "tmpfs") {
1054         # RAM disk (no location needed)
1055         }
1056 elsif ($_[0] eq "bind") {
1057         # Loopback filesystem, mounted from some other directory
1058         print "<tr> <td><b>$text{'linux_bind'}</b></td> <td colspan=3>\n";
1059         printf "<input name=bind_dir value='%s' size=35> %s</td> </tr>\n",
1060                 $_[1], &file_chooser_button("bind_dir", 1);
1061         }
1062 else {
1063         # This is some linux disk-based filesystem
1064         &foreign_require("fdisk");
1065         printf "<tr> <td valign=top><b>%s</b></td>\n", &fstype_name($_[0]);
1066         print "<td colspan=3>\n";
1067         local ($found, $rfound, $lfound, $vfound, $ufound, $rsel, $c);
1068
1069         # Show regular partition input
1070         local $sel = &fdisk::partition_select("lnx_disk", $_[1], 0, \$found);
1071         printf "<input type=radio name=lnx_dev value=0 %s> %s %s<br>\n",
1072                 $found ? "checked" : "", $text{'linux_disk'}, $sel;
1073
1074         # Show RAID input
1075         if (&foreign_check("raid")) {
1076                 &foreign_require("raid");
1077                 local $conf = &raid::get_raidtab();
1078                 foreach $c (@$conf) {
1079                         if ($c->{'active'}) {
1080                                 $rsel .= sprintf "<option value=%s %s>%s\n",
1081                                         $c->{'value'},
1082                                         $_[1] eq $c->{'value'} ? 'selected' : '',
1083                                         &text('linux_rdev', substr($c->{'value'}, -1));
1084                                 $rfound++ if ($_[1] eq $c->{'value'});
1085                                 }
1086                         }
1087                 if ($rsel) {
1088                         printf "<input type=radio name=lnx_dev value=2 %s> %s\n",
1089                                 $rfound ? "checked" : " ", $text{'linux_raid'};
1090                         print "<select name=lnx_raid>\n",$rsel,"</select><br>\n";
1091                         }
1092                 }
1093
1094         # Show LVM input
1095         if (&foreign_check("lvm")) {
1096                 &foreign_require("lvm");
1097                 local @vgs = &lvm::list_volume_groups();
1098                 local @lvs;
1099                 foreach $v (@vgs) {
1100                         push(@lvs, &lvm::list_logical_volumes($v->{'name'}));
1101                         }
1102                 if (@lvs) {
1103                         local $lsel;
1104                         foreach $l (@lvs) {
1105                                 local $sf = &same_file($_[1], $l->{'device'});
1106                                 $lsel .= sprintf "<option value=%s %s>%s\n",
1107                                         $l->{'device'},
1108                                         $sf ? 'selected' : '',
1109                                         &text('linux_ldev', $l->{'vg'},
1110                                                             $l->{'name'});
1111                                 $vfound++ if ($sf);
1112                                 }
1113                         printf "<input type=radio name=lnx_dev value=4 %s> %s\n",
1114                                 $vfound ? "checked" : " ", $text{'linux_lvm'};
1115                         print "<select name=lnx_lvm>\n",$lsel,"</select><br>\n";
1116                         }
1117                 }
1118
1119         # Show label input
1120         if ($has_e2label || $has_xfs_db || $has_reiserfstune) {
1121                 local $l = $_[1] =~ /LABEL=(.*)/ ? $1 : undef;
1122                 local $esel = &fdisk::label_select("lnx_label", $l, \$lfound);
1123                 if ($esel) {
1124                         printf "<input type=radio name=lnx_dev value=3 %s> %s %s<br>\n", $lfound ? "checked" : "", $text{'linux_lsel'}, $esel;
1125                         }
1126                 }
1127
1128         # Show UUID input
1129         if ($has_volid || -d $uuid_directory) {
1130                 local $u = $_[1] =~ /UUID=(\S+)/ ? $1 : undef;
1131                 local $usel = &fdisk::volid_select("lnx_uuid", $u, \$ufound);
1132                 if ($usel) {
1133                         printf "<input type=radio name=lnx_dev value=5 %s> %s %s<br>\n", $ufound ? "checked" : "", $text{'linux_usel'}, $usel;
1134                         }
1135                 }
1136
1137         # Show other device input
1138         local $anyfound = $found || $rfound || $lfound || $vfound || $ufound;
1139         printf "<input type=radio name=lnx_dev value=1 %s> %s\n",
1140                 $anyfound ? "" : "checked",
1141                 $text{'linux_other'};
1142         printf "<input name=lnx_other size=35 value='%s'> %s<br>\n",
1143                 $anyfound ? "" : $_[1],
1144                 &file_chooser_button("lnx_other");
1145         print "</td> </tr>\n";
1146         }
1147 }
1148
1149
1150 # generate_options(type, newmount)
1151 # Output HTML for editing mount options for a particular filesystem 
1152 # under this OS
1153 sub generate_options
1154 {
1155 if ($_[0] ne "swap" && $_[0] ne "auto" &&
1156     $_[0] ne "autofs" && $_[0] ne $smbfs_fs && $_[0] ne "cifs") {
1157         # Lots of options are common to all linux filesystems
1158         print "<tr $tb> <td colspan=4><b>$text{'edit_comm_opt'}</b></td> </tr>\n";
1159         print "<tr> <td>", &hlink("<b>$text{'linux_ro'}</b>", "linux_ro"),"</td>\n";
1160         printf "<td nowrap><input type=radio name=lnx_ro value=1 %s> $text{'yes'}\n",
1161                 defined($options{"ro"}) ? "checked" : "";
1162         printf "<input type=radio name=lnx_ro value=0 %s> $text{'no'}</td>\n",
1163                 defined($options{"ro"}) ? "" : "checked";
1164
1165         print "<td>", &hlink("<b>$text{'linux_sync'}</b>", "linux_sync"), "</td>\n";
1166         printf"<td nowrap><input type=radio name=lnx_sync value=0 %s> $text{'yes'}\n",
1167                 defined($options{"sync"}) ? "" : "checked";
1168         printf "<input type=radio name=lnx_sync value=1 %s> $text{'no'}</td> </tr>\n",
1169                 defined($options{"sync"}) ? "checked" : "";
1170
1171         local $nodev = defined($options{"nodev"}) ||
1172                        defined($options{"user"}) && !defined($options{"dev"});
1173         print "<tr> <td>", &hlink("<b>$text{'linux_nodev'}</b>", "linux_nodev"), "</td>\n";
1174         printf "<td nowrap><input type=radio name=lnx_nodev value=0 %s> $text{'yes'}\n",
1175                 $nodev ? "" : "checked";
1176         printf "<input type=radio name=lnx_nodev value=1 %s> $text{'no'}</td>\n",
1177                 $nodev ? "checked" : "";
1178
1179         local $noexec = defined($options{"noexec"}) ||
1180                        defined($options{"user"}) && !defined($options{"exec"});
1181         print "<td>", &hlink("<b>$text{'linux_noexec'}</b>", "linux_noexec"), "</td>\n";
1182         printf"<td nowrap><input type=radio name=lnx_noexec value=0 %s> $text{'yes'}\n",
1183                 $noexec ? "" : "checked";
1184         printf "<input type=radio name=lnx_noexec value=1 %s> $text{'no'}</td> </tr>\n",
1185                 $noexec ? "checked" : "";
1186
1187         local $nosuid = defined($options{"nosuid"}) ||
1188                        defined($options{"user"}) && !defined($options{"suid"});
1189         print "<tr> <td>", &hlink("<b>$text{'linux_nosuid'}</b>", "linux_nosuid"), "</td>\n";
1190         printf "<td nowrap><input type=radio name=lnx_nosuid value=1 %s> $text{'yes'}\n",
1191                 $nosuid ? "checked" : "";
1192         printf "<input type=radio name=lnx_nosuid value=0 %s> $text{'no'}</td>\n",
1193                 $nosuid ? "" : "checked";
1194
1195         print "<td>", &hlink("<b>$text{'linux_user'}</b>", "linux_user"), "</td>\n";
1196         printf"<td nowrap><input type=radio name=lnx_user value=1 %s> $text{'yes'}\n",
1197                 defined($options{"user"}) ? "checked" : "";
1198         printf "<input type=radio name=lnx_user value=0 %s> $text{'no'}</td> </tr>\n",
1199                 defined($options{"user"}) ? "" : "checked";
1200
1201         print "<td>", &hlink("<b>$text{'linux_noatime'}</b>", "linux_noatime"), "</td>\n";
1202         printf "<td><input type=radio name=lnx_noatime value=1 %s> %s\n",
1203             defined($options{"noatime"}) ? "checked" : "", $text{'yes'};
1204         printf "<input type=radio name=lnx_noatime value=0 %s> %s</td>\n",
1205             defined($options{"noatime"}) ? "" : "checked", $text{'no'};
1206
1207         print "</tr>\n";
1208         }
1209         
1210 if ($_[0] =~ /^ext\d+$/) {
1211         # Ext2 has lots more options..
1212         print "<tr $tb> <td colspan=4><b>$text{'edit_ext_opt'}</b></td> </tr>\n";
1213         if ($no_mount_check) {
1214                 print "<tr> <td><b>$text{'linux_df'}</b></td>\n";
1215                 printf "<td><input type=radio name=ext2_df value=1 %s> %s\n",
1216                     defined($options{"minixdf"}) ? "checked" : "", $text{'yes'};
1217                 printf "<input type=radio name=ext2_df value=0 %s> %s</td>\n",
1218                     defined($options{"minixdf"}) ? "" : "checked", $text{'no'};
1219                 }
1220         else {
1221                 print "<tr> <td><b>$text{'linux_check'}</b></td>\n";
1222                 print "<td><select name=ext2_check>\n";
1223                 printf "<option value=normal %s> $text{'linux_normal'}\n",
1224                         $options{"check"} eq "" ||
1225                         $options{"check"} eq "normal" ?  "selected" : "";
1226                 printf "<option value=strict %s> $text{'linux_strict'}\n",
1227                         $options{"check"} eq "strict" ? "selected" : "";
1228                 printf "<option value=none %s> $text{'linux_none'}\n",
1229                         $options{"check"} eq "none" ||
1230                         defined($options{"nocheck"}) ?  "selected" : "";
1231                 print "</select></td>\n";
1232                 }
1233
1234         print "<td><b>$text{'linux_errors'}</b></td>\n";
1235         print "<td><select name=ext2_errors>\n";
1236         printf "<option value=default %s> $text{'default'}\n",
1237                 !defined($options{"errors"}) ? "selected" : "";
1238         printf "<option value=continue %s> $text{'linux_continue'}\n",
1239                 $options{"error"} eq "continue" ? "selected" : "";
1240         printf "<option value=remount-ro %s> $text{'linux_remount_ro'}\n",
1241                 $options{"error"} eq "remount-ro" ? "selected" : "";
1242         printf "<option value=panic %s> $text{'linux_panic'}\n",
1243                 $options{"error"} eq "panic" ? "selected" : "";
1244         print "</select></td> </tr>\n";
1245
1246         print "<tr> <td><b>$text{'linux_grpid'}</b></td>\n";
1247         printf "<td nowrap><input type=radio name=ext2_grpid value=1 %s> %s\n",
1248                 defined($options{"grpid"}) || defined($options{"bsdgroups"}) ?
1249                         "checked" : "", $text{'yes'};
1250         printf "<input type=radio name=ext2_grpid value=0 %s> %s</td>\n",
1251                 defined($options{"grpid"}) || defined($options{"bsdgroups"}) ?
1252                         "" : "checked", $text{'no'};
1253
1254         print "<td><b>$text{'linux_quotas'}</b></td>\n";
1255         local $usrquota = defined($options{"usrquota"});
1256         local $grpquota = defined($options{"grpquota"});
1257         print "<td nowrap><select name=ext2_quota>\n";
1258         printf "<option value=0 %s> $text{'no'}\n",
1259                 $usrquota || $grpquota ? "" : "selected";
1260         printf "<option value=1 %s> $text{'linux_usrquota'}\n",
1261                 $usrquota && !$grpquota ? "selected" : "";
1262         printf "<option value=2 %s> $text{'linux_grpquota'}\n",
1263                 $grpquota && !$usrquota ? "selected" : "";
1264         if (`uname -r` =~ /^2\.0\.(\d+)/ && $1 < 31) {
1265                 printf "<option value=3 %s> $text{'linux_usrgrpquota2'}\n",
1266                         $usrquota && $grpquota ? "selected" : "";
1267                 }
1268         else {
1269                 printf "<option value=3 %s> $text{'linux_usrgrpquota'}\n",
1270                         $usrquota && $grpquota ? "selected" : "";
1271                 }
1272         print "</select></td> </tr>\n";
1273
1274         print "<tr> <td><b>$text{'linux_resuid'}</b></td>\n";
1275         printf "<td><input name=ext2_resuid size=8 value=\"%s\">\n",
1276                 defined($options{"resuid"}) ? getpwuid($options{"resuid"}) : "";
1277         print &user_chooser_button("ext2_resuid", 0),"</td>\n";
1278
1279         print "<td><b>$text{'linux_resgid'}</b></td>\n";
1280         printf "<td><input name=ext2_resgid size=8 value=\"%s\">\n",
1281                 defined($options{"resgid"}) ? getgrgid($options{"resgid"}) : "";
1282         print &group_chooser_button("ext2_resgid", 0),"</td> </tr>\n";
1283         }
1284 elsif (($_[0] eq "nfs") || ($_[0] eq "nfs4")) {
1285         # Linux nfs has some more options...
1286         print "<tr $tb> <td colspan=4><b>$text{'edit_nfs_opt'}</b></td> </tr>\n";
1287         
1288         print "<tr> <td>", &hlink("<b>$text{'linux_vers'}</b>", "linux_vers"), "</td>\n";
1289         if ($_[0] eq "nfs4") {
1290             print "<td nowrap><input type=radio name=nfs_vers value=4 checked> 4</td>\n";
1291         } else {
1292             print "<td nowrap><input type=radio name=nfs_vers value=3 checked> $text{'edit_3_or_lower'}</td>\n";
1293         }
1294         print "<td>", &hlink("<b>$text{'linux_port'}</b>", "linux_port"), "</td>\n";
1295         printf "<td nowrap><input type=radio name=nfs_port_def value=1 %s> $text{'default'}\n",
1296                 defined($options{"port"}) ? "" : "checked";
1297         printf "<input type=radio name=nfs_port_def value=0 %s>\n",
1298                 defined($options{"port"}) ? "checked" : "";
1299         print "<input size=5 name=nfs_port value=$options{port}></td> </tr>\n";
1300
1301         print "<tr> <td>", &hlink("<b>$text{'linux_bg'}</b>", "linux_bg"), "</td>\n";
1302         printf "<td nowrap><input type=radio name=nfs_bg value=1 %s> $text{'yes'}\n",
1303                 defined($options{"bg"}) ? "checked" : "";
1304         printf "<input type=radio name=nfs_bg value=0 %s> $text{'no'}</td>\n",
1305                 defined($options{"bg"}) ? "" : "checked";
1306
1307         print "<td>", &hlink("<b>$text{'linux_soft'}</b>", "linux_soft"), "</td>\n";
1308         printf "<td nowrap><input type=radio name=nfs_soft value=1 %s> $text{'yes'}\n",
1309                 defined($options{"soft"}) ? "checked" : "";
1310         printf "<input type=radio name=nfs_soft value=0 %s> $text{'no'}</td> </tr>\n",
1311                 defined($options{"soft"}) ? "" : "checked";
1312
1313         print "<tr> <td>", &hlink("<b>$text{'linux_timeo'}</b>", "linux_timeo"), "</td>\n";
1314         printf "<td nowrap><input type=radio name=nfs_timeo_def value=1 %s> $text{'default'}\n",
1315                 defined($options{"timeo"}) ? "" : "checked";
1316         printf "<input type=radio name=nfs_timeo_def value=0 %s>\n",
1317                 defined($options{"timeo"}) ? "checked" : "";
1318         printf "<input size=5 name=nfs_timeo value=$options{timeo}></td>\n";
1319
1320         print "<td>", &hlink("<b>$text{'linux_retrans'}</b>", "linux_retrans"), "</td>\n";
1321         printf "<td nowrap><input type=radio name=nfs_retrans_def value=1 %s> $text{'default'}\n",
1322                 defined($options{"retrans"}) ? "" : "checked";
1323         printf "<input type=radio name=nfs_retrans_def value=0 %s>\n",
1324                 defined($options{"retrans"}) ? "checked" : "";
1325         print "<input size=5 name=nfs_retrans value=$options{retrans}></td> </tr>\n";
1326
1327         print "<tr> <td>", &hlink("<b>$text{'linux_intr'}</b>", "linux_intr"), "</td>\n";
1328         printf "<td nowrap><input type=radio name=nfs_intr value=1 %s> $text{'yes'}\n",
1329                 defined($options{"intr"}) ? "checked" : "";
1330         printf "<input type=radio name=nfs_intr value=0 %s> $text{'no'}</td>\n",
1331                 defined($options{"intr"}) ? "" : "checked";
1332
1333         local $proto = defined($options{"udp"}) ? "udp" :
1334                        defined($options{"tcp"}) ? "tcp" : "";
1335         print "<td>", &hlink("<b>$text{'linux_transfert'}</b>", "linux_transfert"), "</td>\n";
1336         print "<td nowrap><select name=nfs_transfert>\n";
1337         printf "<option value='' %s>Default</option>\n",
1338                 $proto eq "" ? "selected" : "";
1339         printf "<option value=tcp %s>TCP</option>\n",
1340                 $proto eq "tcp" ? "selected" : "";
1341         printf "<option value=udp %s %s>UDP</option>\n",
1342                 $proto eq "udp" ? "selected" : "", ($_[0] eq "nfs4") ? "disabled" : "";
1343         print "</select></td> </tr>\n";
1344
1345         print "<tr> <td>", &hlink("<b>$text{'linux_rsize'}</b>", "linux_rsize"), "</td>\n";
1346         printf "<td nowrap><input type=radio name=nfs_rsize_def value=1 %s> $text{'default'}\n",
1347                 defined($options{"rsize"}) ? "" : "checked";
1348         printf "<input type=radio name=nfs_rsize_def value=0 %s>\n",
1349                 defined($options{"rsize"}) ? "checked" : "";
1350         printf "<input size=5 name=nfs_rsize value=$options{rsize}></td>\n";
1351
1352         print "<td>", &hlink("<b>$text{'linux_wsize'}</b>", "linux_wsize"), "</td>\n";
1353         printf "<td nowrap><input type=radio name=nfs_wsize_def value=1 %s> $text{'default'}\n",
1354                 defined($options{"wsize"}) ? "" : "checked";
1355         printf "<input type=radio name=nfs_wsize_def value=0 %s>\n",
1356                 defined($options{"wsize"}) ? "checked" : "";
1357         print "<input size=5 name=nfs_wsize value=$options{wsize}></td> </tr>\n";
1358         print "<tr> <td>", &hlink("<b>$text{'linux_auth'}</b>", "linux_auth"), "</td>\n";
1359         printf "<td nowrap colspan=2><input type=radio name=nfs_auth value=0 %s onclick=enable_sec(0)> sys\n",
1360                 !defined($options{"sec"}) ? "checked" : "";
1361         printf "<input type=radio name=nfs_auth value=1 %s onclick=enable_sec(1)> krb5\n",
1362                 ($options{"sec"} =~ /krb5/) ? "checked" : "";
1363         printf "<input type=radio name=nfs_auth value=2 %s disabled> lipkey\n",
1364                 ($options{"sec"} =~ /lipkey/) ? "checked" : "";
1365         printf "<input type=radio name=nfs_auth value=3 %s disabled> spkm-3</td></tr>\n",
1366                 ($options{"sec"} =~ /spkm/) ? "checked" : "";
1367
1368         print "<tr> <td>", &hlink("<b>$text{'linux_sec'}</b>", "linux_sec"), "</td>\n";
1369         printf "<td nowrap colspan=2><input type=radio name=nfs_sec value=0 %s> $text{'config_none'}\n",
1370                 (!defined($options{"sec"}) || ($options{"sec"} !~ /[ip]$/)) ? "checked" : "";
1371         printf "<input type=radio name=nfs_sec value=1 %s> $text{'linux_integrity'}\n",
1372                 ($options{"sec"} =~ /i$/) ? "checked" : "";
1373         printf "<input type=radio name=nfs_sec value=2 %s> $text{'linux_privacy'}</td></tr>\n",
1374                 ($options{"sec"} =~ /p$/) ? "checked" : "";
1375         
1376         print "<script type=\"text/javascript\">\n";
1377         print "function enable_sec(level) {\n";
1378         print " if (level) {\n";
1379         print "   document.forms[0].nfs_sec[1].disabled=0;\n";
1380         print "   document.forms[0].nfs_sec[2].disabled=0;\n";
1381         print "   } else {\n";
1382         print "   document.forms[0].nfs_sec[1].disabled=1;\n";
1383         print "   document.forms[0].nfs_sec[2].disabled=1;\n";
1384         print "   document.forms[0].nfs_sec[0].checked=1;\n";
1385         print " } }\n";
1386         print "window.onload = function() {;\n";
1387         printf "   enable_sec(%d);\n", !defined($options{"sec"}) ? 0 : 1;
1388         print "   }\n";
1389         print "</script>\n";
1390         }
1391 elsif ($_[0] eq "fat" || $_[0] eq "vfat" || $_[0] eq "msdos" ||
1392        $_[0] eq "umsdos" || $_[0] eq "fatx"){
1393         # All dos-based filesystems share some options
1394         print "<tr $tb> <td colspan=4><b>$text{'edit_dos_opt'}</b></td> </tr>\n";
1395         print "<tr> <td><b>$text{'linux_uid'}</b></td>\n";
1396         printf "<td><input name=fat_uid size=8 value=\"%s\">\n",
1397                 defined($options{'uid'}) ? getpwuid($options{'uid'}) : "";
1398         print &user_chooser_button("fat_uid", 0),"</td>\n";
1399
1400         print "<td><b>$text{'linux_gid'}</b></td>\n";
1401         printf "<td><input name=fat_gid size=8 value=\"%s\">\n",
1402                 defined($options{'gid'}) ? getgrgid($options{'gid'}) : "";
1403         print &group_chooser_button("fat_gid", 0),"</td> </tr>\n";
1404
1405         print "<tr> <td><b>$text{'linux_rules'}</b></td>\n";
1406         print "<td><select name=fat_check>\n";
1407         printf "<option value=\"\" %s> $text{'default'}\n",
1408                 defined($options{"check"}) ? "" : "selected";
1409         printf "<option value=r %s> $text{'linux_relaxed'}\n",
1410                 $options{"check"} =~ /^r/ ? "selected" : "";
1411         printf "<option value=n %s> $text{'linux_normal'}\n",
1412                 $options{"check"} =~ /^n/ ? "selected" : "";
1413         printf "<option value=s %s> $text{'linux_strict'}\n",
1414                 $options{"check"} =~ /^s/ ? "selected" : "";
1415         print "</select></td>\n";
1416
1417         print "<td><b>$text{'linux_conv'}</b></td>\n";
1418         print "<td><select name=fat_conv>\n";
1419         printf "<option value=\"\" %s> $text{'linux_none'}\n",
1420                 $options{"conv"} =~ /^b/ || !defined($options{"conv"}) ?
1421                 "selected" : "";
1422         printf "<option value=t %s> $text{'linux_allfiles'}\n",
1423                 $options{"conv"} =~ /^t/ ? "selected" : "";
1424         printf "<option value=a %s> $text{'linux_textfiles'}\n",
1425                 $options{"conv"} =~ /^a/ ? "selected" : "";
1426         print "</select></td> </tr>\n";
1427
1428         print "<tr> <td><b>$text{'linux_umask'}</b></td>\n";
1429         printf "<td><input type=radio name=fat_umask_def value=1 %s> $text{'default'}\n",
1430                 defined($options{"umask"}) ? "" : "checked";
1431         printf "<input type=radio name=fat_umask_def value=0 %s>\n",
1432                 defined($options{"umask"}) ? "checked" : "";
1433         print "<input size=5 name=fat_umask value=\"$options{umask}\"></td>\n";
1434
1435         print "<td><b>$text{'linux_quiet'}</b></td>\n";
1436         printf "<td nowrap><input type=radio name=fat_quiet value=0 %s> $text{'yes'}\n",
1437                 defined($options{"quiet"}) ? "" : "checked";
1438         printf "<input type=radio name=fat_quiet value=1 %s> $text{'no'}</td> </tr>\n",
1439                 defined($options{"quiet"}) ? "checked" : "";
1440
1441         if ($_[0] eq "vfat") {
1442                 # vfat has some extra options beyond fat
1443                 print "<tr> <td><b>$text{'linux_uni_xlate'}</b></td>\n";
1444                 printf "<td><input type=radio name=fat_uni_xlate value=1 %s> $text{'yes'}\n",
1445                         defined($options{"uni_xlate"}) ? "checked" : "";
1446                 printf "<input type=radio name=fat_uni_xlate value=0 %s> $text{'no'}</td>\n",
1447                         defined($options{"uni_xlate"}) ? "" : "checked";
1448
1449                 print "<td><b>$text{'linux_posix'}</b></td>\n";
1450                 printf "<td nowrap><input type=radio name=fat_posix value=1 %s> $text{'yes'}\n",
1451                         defined($options{"posix"}) ? "checked" : "";
1452                 printf "<input type=radio name=fat_posix value=0 %s> $text{'no'}</td> </tr>\n",
1453                         defined($options{"posix"}) ? "" : "checked";
1454                 }
1455         }
1456 elsif ($_[0] eq "hpfs") {
1457         # OS/2 filesystems has some more options..
1458         print "<tr $tb> <td colspan=4><b>$text{'edit_hpfs_opt'}</b></td> </tr>\n";
1459         print "<tr> <td><b>$text{'linux_uid'}</b></td>\n";
1460         printf "<td><input name=hpfs_uid size=8 value=\"%s\">\n",
1461                 defined($options{"uid"}) ? getpwuid($options{"uid"}) : "";
1462         print &user_chooser_button("hpfs_uid", 0),"</td>\n";
1463
1464         print "<td><b>$text{'linux_gid'}</b></td>\n";
1465         printf "<td><input name=hpfs_gid size=8 value=\"%s\">\n",
1466                 defined($options{"gid"}) ? getgrgid($options{"gid"}) : "";
1467         print &group_chooser_button("hpfs_gid", 0),"</td> </tr>\n";
1468
1469         print "<tr> <td><b>$text{'linux_umask'}</b></td>\n";
1470         printf"<td><input type=radio name=hpfs_umask_def value=1 %s> Default\n",
1471                 defined($options{"umask"}) ? "" : "checked";
1472         printf "<input type=radio name=hpfs_umask_def value=0 %s>\n",
1473                 defined($options{"umask"}) ? "checked" : "";
1474         print "<input size=5 name=hpfs_umask value=\"$options{umask}\"></td>\n";
1475
1476         print "<td><b>$text{'linux_conv2'}</b></td>\n";
1477         print "<td><select name=hpfs_conv>\n";
1478         printf "<option value=b %s> $text{'linux_none'}\n",
1479                 $options{"conv"} =~ /^b/ || !defined($options{"conv"}) ?
1480                 "selected" : "";
1481         printf "<option value=t %s> $text{'linux_allfiles'}\n",
1482                 $options{"conv"} =~ /^t/ ? "selected" : "";
1483         printf "<option value=a %s> $text{'linux_textfiles'}\n",
1484                 $options{"conv"} =~ /^a/ ? "selected" : "";
1485         print "</select></td> </tr>\n";
1486         }
1487 elsif ($_[0] eq "iso9660") {
1488         # CD-ROM filesystems have some more options..
1489         print "<tr $tb> <td colspan=4><b>$text{'edit_iso9660_opt'}</b></td> </tr>\n";
1490         print "<tr> <td><b>$text{'linux_uid'}</b></td>\n";
1491         printf "<td><input name=iso9660_uid size=8 value=\"%s\">\n",
1492                 defined($options{"uid"}) ? getpwuid($options{"uid"}) : "";
1493         print &user_chooser_button("iso9660_uid", 0),"</td>\n";
1494
1495         print "<td><b>$text{'linux_gid'}</b></td>\n";
1496         printf "<td><input name=iso9660_gid size=8 value=\"%s\">\n",
1497                 defined($options{"gid"}) ? getgrgid($options{"gid"}) : "";
1498         print &group_chooser_button("iso9660_gid", 0),"</td>\n";
1499
1500         print "<tr> <td><b>$text{'linux_rock'}</b></td>\n";
1501         printf "<td><input type=radio name=iso9660_norock value=1 %s> $text{'yes'}\n",
1502                 defined($options{"norock"}) ? "checked" : "";
1503         printf "<input type=radio name=iso9660_norock value=0 %s> $text{'no'}</td>\n",
1504                 defined($options{"norock"}) ? "" : "checked";
1505
1506         print "<td><b>$text{'linux_mode'}</b></td>\n";
1507         printf"<td><input size=10 name=iso9660_mode value=\"%s\"></td> </tr>\n",
1508                 defined($options{"mode"}) ? $options{"mode"} : "444";
1509         }
1510 elsif ($_[0] eq "auto") {
1511         # Don't know how to set options for auto filesystems yet..
1512         print "<tr> <td><i>$text{'linux_noopts'}</i></td> </tr>\n";
1513         }
1514 elsif ($_[0] eq "autofs") {
1515         print "<tr $tb> <td colspan=4><b>$text{'edit_autofs_opt'}</b></td> </tr>\n";
1516         print "<tr> <td><b>$text{'linux_timeout'}</b></td> <td>\n";
1517         printf"<input type=radio name=autofs_timeout_def value=1 %s> $text{'default'}\n",
1518                 defined($options{'timeout'}) ? "" : "checked";
1519         printf "<input type=radio name=autofs_timeout_def value=0 %s>\n",
1520                 defined($options{'timeout'}) ? "checked" : "";
1521         printf "<input name=autofs_timeout size=5 value=\"%s\"> $text{'linux_secs'}</td>\n",
1522                 $options{'timeout'};
1523
1524         print "<td><b>$text{'linux_pid_file'}</b>?</td>\n";
1525         printf"<td><input type=radio name=autofs_pid-file_def value=1 %s> $text{'no'}\n",
1526                 defined($options{'pid-file'}) ? "" : "checked";
1527         printf "<input type=radio name=autofs_pid-file_def value=0 %s> $text{'yes'}\n",
1528                 defined($options{'pid-file'}) ? "checked" : "";
1529         printf "<input name=autofs_pid-file size=20 value=\"%s\">\n",
1530                 $options{'pid-file'};
1531         print &file_chooser_button("autofs_pid-file", 1);
1532         print "</td> </tr>\n";
1533         }
1534 elsif ($_[0] eq "swap") {
1535         # Swap has no options..
1536         print "<tr> <td width=25%><b>$text{'linux_swappri'}</b></td>\n";
1537         print "<td width=25%>",&ui_opt_textbox("swap_pri", $options{'pri'}, 6,
1538                                      $text{'default'}),"</td>\n";
1539
1540         print "<td width=50% colspan=2></td>\n";
1541         print "</tr>\n";
1542         }
1543 elsif ($_[0] eq $smbfs_fs || $_[0] eq "cifs") {
1544         # SMB filesystems have a few options..
1545         print "<tr $tb> <td colspan=4><b>$text{'edit_smbfs_opt'}</b></td> </tr>\n";
1546         $support = $_[0] eq $smbfs_fs ? $smbfs_support : $cifs_support;
1547         if (keys(%options) == 0 && !$_[1]) {
1548                 print "<tr> <td colspan=4><i>$text{'linux_smbwarn'}</i></td> </tr>\n";
1549                 }
1550
1551         print "<tr> <td><b>$text{'linux_username'}</b></td>\n";
1552         printf "<td><input name=smbfs_user size=15 value=\"%s\"></td>\n",
1553                 $support == 4 ? $options{'username'} : $options{'user'};
1554
1555         print "<td><b>$text{'linux_password'}</b></td>\n";
1556         printf "<td><input type=password name=smbfs_passwd size=15 value=\"%s\"></td> </tr>\n",
1557                 $support == 4 ? $options{'password'} : $options{'passwd'};
1558         
1559         print "<td><b>$text{'linux_credentials'}</b></td>\n";
1560         if ($support == 4) {
1561                 printf "<td><input name=smbfs_creds size=30 value=\"%s\"> ",
1562                         defined($options{"credentials"}) ? $options{'credentials'} : "";
1563                 
1564                 if ($access{'browse'}) {
1565                         print &file_chooser_button("smbfs_creds", 0);
1566                         }
1567                 }
1568         print "</td>\n";
1569         if (!$access{'simopts'}) {
1570                 if ($support != 2) {
1571                         print "<tr> <td><b>$text{'linux_uid'}</b></td>\n";
1572                         printf "<td><input name=smbfs_uid size=8 value=\"%s\">\n",
1573                                 defined($options{"uid"}) ? getpwuid($options{"uid"}) : "";
1574                         print &user_chooser_button("smbfs_uid", 0),"</td>\n";
1575
1576                         print "<td><b>$text{'linux_gid'}</b></td>\n";
1577                         printf "<td><input name=smbfs_gid size=8 value=\"%s\">\n",
1578                                 defined($options{"gid"}) ? getgrgid($options{"gid"}) : "";
1579                         print &group_chooser_button("smbfs_gid", 0),"</td>\n";
1580                         }
1581
1582                 if ($support == 1) {
1583                         print "<tr> <td><b>$text{'linux_sname'}</b></td>\n";
1584                         printf "<td><input type=radio name=smbfs_sname_def value=1 %s> $text{'linux_auto'}\n",
1585                                 defined($options{"servername"}) ? "" : "checked";
1586                         printf "<input type=radio name=smbfs_sname_def value=0 %s>\n",
1587                                 defined($options{"servername"}) ? "checked" : "";
1588                         print "<input size=10 name=smbfs_sname value=\"$options{servername}\"></td>\n";
1589                         }
1590                 elsif ($support == 2) {
1591                         print "<tr> <td><b>$text{'linux_wg'}</b></td>\n";
1592                         printf "<td><input type=radio name=smbfs_wg_def value=1 %s> $text{'linux_auto'}\n",
1593                                 defined($options{"workgroup"}) ? "" : "checked";
1594                         printf "<input type=radio name=smbfs_wg_def value=0 %s>\n",
1595                                 defined($options{"workgroup"}) ? "checked" : "";
1596                         print "<input size=10 name=smbfs_wg value=\"$options{'workgroup'}\"></td>\n";
1597                         }
1598
1599                 if ($support < 3) {
1600                         print "<td><b>$text{'linux_cname'}</b></td>\n";
1601                         printf "<td><input type=radio name=smbfs_cname_def value=1 %s> $text{'linux_auto'}\n",
1602                                 defined($options{"clientname"}) ? "" : "checked";
1603                         printf "<input type=radio name=smbfs_cname_def value=0 %s>\n",
1604                                 defined($options{"clientname"}) ? "checked" : "";
1605                         print "<input size=10 name=smbfs_cname value=\"$options{clientname}\"></td> </tr>\n";
1606
1607                         print "<tr> <td><b>$text{'linux_mname'}</b></td>\n";
1608                         printf "<td colspan=3><input type=radio name=smbfs_mname_def value=1 %s> %s\n",
1609                                 defined($options{"machinename"}) ? "" : "checked", $text{'linux_auto'};
1610                         printf "<input type=radio name=smbfs_mname_def value=0 %s>\n",
1611                                 defined($options{"machinename"}) ? "checked" : "";
1612                         print "<input size=30 name=smbfs_mname value=\"$options{machinename}\"></td> </tr>\n";
1613                         }
1614                 
1615                 if ($support == 1) {
1616                         print "<tr> <td><b>$text{'linux_fmode'}</b></td>\n";
1617                         printf
1618                             "<td><input name=smbfs_fmode size=5 value=\"%s\"></td>\n",
1619                             defined($options{'fmode'}) ? $options{'fmode'} : "755";
1620
1621                         print "<td><b>$text{'linux_dmode'}</b></td>\n";
1622                         printf
1623                             "<td><input name=smbfs_dmode size=5 value=\"%s\"></td>\n",
1624                             defined($options{'dmode'}) ? $options{'dmode'} : "755";
1625                         print "</tr>\n";
1626                         }
1627                 elsif ($support >= 3) {
1628                         print "<tr> <td><b>$text{'linux_fmode'}</b></td> <td>\n";
1629                         printf"<input type=radio name=smbfs_fmask_def value=1 %s> %s\n",
1630                                 defined($options{'fmask'}) ? "" : "checked",
1631                                 $text{'default'};
1632                         printf"<input type=radio name=smbfs_fmask_def value=0 %s>\n",
1633                                 defined($options{'fmask'}) ? "checked" : "";
1634                         printf "<input name=smbfs_fmask size=5 value='%s'></td>\n",
1635                                 $options{'fmask'};
1636
1637                         print "<td><b>$text{'linux_dmode'}</b></td> <td>\n";
1638                         printf"<input type=radio name=smbfs_dmask_def value=1 %s> %s\n",
1639                                 defined($options{'dmask'}) ? "" : "checked",
1640                                 $text{'default'};
1641                         printf"<input type=radio name=smbfs_dmask_def value=0 %s>\n",
1642                                 defined($options{'dmask'}) ? "checked" : "";
1643                         printf "<input name=smbfs_dmask size=5 value='%s'></td></tr>\n",
1644                                 $options{'dmask'};
1645
1646                         print "<tr> <td><b>$text{'linux_ro'}</b></td>\n";
1647                         printf "<td><input type=radio name=smbfs_ro value=1 %s> $text{'yes'}\n",
1648                                 defined($options{"ro"}) ? "checked" : "";
1649                         printf "<input type=radio name=smbfs_ro value=0 %s> $text{'no'}</td>\n",
1650                                 defined($options{"ro"}) ? "" : "checked";
1651                         }
1652                 if ($support == 4) {
1653                         print "<td><b>$text{'linux_user'}</b></td>\n";
1654                         printf "<td><input type=radio name=smbfs_user2 value=1 %s> $text{'yes'}\n",
1655                                 defined($options{"user"}) ? "checked" : "";
1656                         printf "<input type=radio name=smbfs_user2 value=0 %s> $text{'no'}</td> </tr>\n",
1657                                 defined($options{"user"}) ? "" : "checked";
1658
1659                         print "<tr> <td><b>$text{'linux_cname'}</b></td>\n";
1660                         printf "<td colspan=3><input type=radio name=smbfs_cname_def value=1 %s> $text{'linux_auto'}\n",
1661                                 defined($options{"netbiosname"}) ? "" : "checked";
1662                         printf "<input type=radio name=smbfs_cname_def value=0 %s>\n",
1663                                 defined($options{"netbiosname"}) ? "checked" : "";
1664                         print "<input size=40 name=smbfs_cname value=\"$options{netbiosname}\"></td> </tr>\n";
1665
1666                         print "<tr> <td><b>$text{'linux_mname'}</b></td>\n";
1667                         printf "<td colspan=3><input type=radio name=smbfs_mname_def value=1 %s> %s\n",
1668                                 defined($options{"ip"}) ? "" : "checked", $text{'linux_auto'};
1669                         printf "<input type=radio name=smbfs_mname_def value=0 %s>\n",
1670                                 defined($options{"ip"}) ? "checked" : "";
1671                         print "<input size=40 name=smbfs_mname value=\"$options{ip}\"></td> </tr>\n";
1672
1673                         print "<tr> <td><b>$text{'linux_wg'}</b></td>\n";
1674                         printf "<td><input type=radio name=smbfs_wg_def value=1 %s> $text{'linux_auto'}\n",
1675                                 defined($options{"workgroup"}) ? "" : "checked";
1676                         printf "<input type=radio name=smbfs_wg_def value=0 %s>\n",
1677                                 defined($options{"workgroup"}) ? "checked" : "";
1678                         print "<input size=10 name=smbfs_wg value=\"$options{'workgroup'}\"></td>\n";
1679                         }
1680                 if ($support >= 3) {
1681                         print "</tr>\n";
1682                         }
1683                 }
1684
1685         if ($_[0] eq "cifs") {
1686                 # Show cifs-only options
1687                 print "<tr> <td><b>$text{'linux_codepage'}</b></td>\n";
1688                 print "<td>",&ui_opt_textbox("smbfs_codepage",
1689                     $options{'codepage'}, 10, $text{'default'}),"</td>\n";
1690
1691                 print "<td><b>$text{'linux_iocharset'}</b></td>\n";
1692                 print "<td>",&ui_opt_textbox("smbfs_iocharset",
1693                     $options{'iocharset'}, 10, $text{'default'}),"</td> </tr>\n";
1694                 }
1695         }
1696 elsif ($_[0] eq "reiserfs") {
1697         # Reiserfs is a new super-efficient filesystem
1698         print "<tr $tb> <td colspan=4><b>$text{'edit_reiserfs_opt'}</b></td> </tr>\n";
1699         print "<tr> <td><b>$text{'linux_notail'}</b></td>\n";
1700         printf "<td><input type=radio name=lnx_notail value=1 %s> $text{'yes'}\n",
1701                 defined($options{"notail"}) ? "checked" : "";
1702         printf "<input type=radio name=lnx_notail value=0 %s> $text{'no'}</td> </tr>\n",
1703                 defined($options{"notail"}) ? "" : "checked";
1704         }
1705 elsif ($_[0] eq "tmpfs") {
1706         # Tmpfs has some size options
1707         print "<tr $tb> <td colspan=4><b>$text{'edit_tmpfs_opt'}</b></td> </tr>\n";
1708         print "<tr> <td><b>$text{'linux_tmpsize'}</b></td>\n";
1709         printf "<td><input type=radio name=lnx_tmpsize_def value=1 %s> %s\n",
1710                 !defined($options{"size"}) ? "checked" : "",
1711                 $text{'linux_unlimited'};
1712         printf "<input type=radio name=lnx_tmpsize_def value=0 %s>\n",
1713                 !defined($options{"size"}) ? "" : "checked";
1714         printf "<input name=lnx_tmpsize size=6 value='%s'></td>\n",
1715                 $options{"size"};
1716
1717         print "<td><b>$text{'linux_nr_blocks'}</b></td>\n";
1718         printf "<td><input type=radio name=lnx_nr_blocks_def value=1 %s> %s\n",
1719                 !defined($options{"nr_blocks"}) ? "checked" : "",
1720                 $text{'linux_unlimited'};
1721         printf "<input type=radio name=lnx_nr_blocks_def value=0 %s>\n",
1722                 !defined($options{"nr_blocks"}) ? "" : "checked";
1723         printf "<input name=lnx_nr_blocks size=6 value='%s'></td> </tr>\n",
1724                 $options{"nr_blocks"};
1725
1726         print "<tr> <td><b>$text{'linux_nr_inodes'}</b></td>\n";
1727         printf "<td><input type=radio name=lnx_nr_inodes_def value=1 %s> %s\n",
1728                 !defined($options{"nr_inodes"}) ? "checked" : "",
1729                 $text{'linux_unlimited'};
1730         printf "<input type=radio name=lnx_nr_inodes_def value=0 %s>\n",
1731                 !defined($options{"nr_inodes"}) ? "" : "checked";
1732         printf "<input name=lnx_nr_inodes size=6 value='%s'></td>\n",
1733                 $options{"nr_inodes"};
1734
1735         print "<td><b>$text{'linux_tmpmode'}</b></td>\n";
1736         printf "<td><input type=radio name=lnx_tmpmode_def value=1 %s> %s\n",
1737                 !defined($options{"mode"}) ? "checked" : "", $text{'default'};
1738         printf "<input type=radio name=lnx_tmpmode_def value=0 %s>\n",
1739                 !defined($options{"mode"}) ? "" : "checked";
1740         printf "<input name=lnx_tmpmode size=3 value='%s'></td> </tr>\n",
1741                 $options{"mode"};
1742         }
1743 elsif ($_[0] eq "xfs") {
1744         # Show options for XFS
1745         print "<tr $tb> <td colspan=4><b>$text{'edit_xfs_opt'}</b></td> </tr>\n";
1746         print "<tr> <td><b>$text{'linux_usrquotas'}</b></td>\n";
1747         print "<td colspan=3>\n";
1748         printf "<input type=radio name=xfs_usrquota value=1 %s> %s\n",
1749                 defined($options{"quota"}) || defined($options{"usrquota"}) ?
1750                 "checked" : "", $text{'yes'};
1751         printf "<input type=radio name=xfs_usrquota value=2 %s> %s\n",
1752                 defined($options{"uqnoenforce"}) ? "checked" : "",
1753                 $text{'linux_noenforce'};
1754         printf "<input type=radio name=xfs_usrquota value=0 %s> %s</td></tr>\n",
1755                 defined($options{"quota"}) || defined($options{"usrquota"}) ||
1756                 defined($options{"uqnoenforce"}) ? "" : "checked", $text{'no'};
1757
1758         print "<tr> <td><b>$text{'linux_grpquotas'}</b></td>\n";
1759         print "<td colspan=3>\n";
1760         printf "<input type=radio name=xfs_grpquota value=1 %s> %s\n",
1761                 defined($options{"grpquota"}) ?  "checked" : "", $text{'yes'};
1762         printf "<input type=radio name=xfs_grpquota value=2 %s> %s\n",
1763                 defined($options{"gqnoenforce"}) ? "checked" : "",
1764                 $text{'linux_noenforce'};
1765         printf "<input type=radio name=xfs_grpquota value=0 %s> %s</td></tr>\n",
1766                 defined($options{"grpquota"}) ||
1767                 defined($options{"gqnoenforce"}) ? "" : "checked", $text{'no'};
1768         }
1769 elsif ($_[0] eq "jfs") {
1770         # No other JFS options yet!
1771         }
1772 elsif ($_[0] eq "ntfs") {
1773         # Windows NT/XP/2000 filesystem
1774         print "<tr $tb> <td colspan=4><b>$text{'edit_ntfs_opt'}</b></td> </tr>\n";
1775         print "<tr> <td><b>$text{'linux_uid'}</b></td>\n";
1776         printf "<td><input name=ntfs_uid size=8 value=\"%s\">\n",
1777                 defined($options{"uid"}) ? getpwuid($options{"uid"}) : "";
1778         print &user_chooser_button("ntfs_uid", 0),"</td>\n";
1779
1780         print "<td><b>$text{'linux_gid'}</b></td>\n";
1781         printf "<td><input name=ntfs_gid size=8 value=\"%s\">\n",
1782                 defined($options{"gid"}) ? getgrgid($options{"gid"}) : "";
1783         print &group_chooser_button("ntfs_gid", 0),"</td>\n";
1784         }
1785 }
1786
1787
1788 # check_location(type)
1789 # Parse and check inputs from %in, calling &error() if something is wrong.
1790 # Returns the location string for storing in the fstab file
1791 sub check_location
1792 {
1793 if (($_[0] eq "nfs") || ($_[0] eq "nfs4")) {
1794         local($out, $temp, $mout, $dirlist);
1795
1796         if (&has_command("showmount")) {
1797                 # Use ping and showmount to see if the host exists and is up
1798                 if ($in{nfs_host} !~ /^\S+$/) {
1799                         &error(&text('linux_ehost', $in{'nfs_host'}));
1800                         }
1801                 $out = &backquote_command("ping -c 1 '$in{nfs_host}' 2>&1");
1802                 if ($out =~ /unknown host/) {
1803                         &error(&text('linux_ehost2', $in{'nfs_host'}));
1804                         }
1805                 elsif ($out =~ /100\% packet loss/) {
1806                         &error(&text('linux_edown', $in{'nfs_host'}));
1807                         }
1808                 $out = &backquote_command("showmount -e '$in{nfs_host}' 2>&1");
1809                 if ($out =~ /Unable to receive/) {
1810                         &error(&text('linux_enfs', $in{'nfs_host'}));
1811                         }
1812                 elsif ($?) {
1813                         &error(&text('linux_elist', $out));
1814                         }
1815
1816                 # Validate directory name for NFSv3 (in v4 '/' exists)
1817                 foreach (split(/\n/, $out)) {
1818                         if (/^(\/\S+)/) { $dirlist .= "$1\n"; }
1819                         }
1820                 
1821                 if (($_[0] ne "nfs4") && ($in{nfs_dir} !~ /^\/.*$/)) {
1822                         &error(&text('linux_enfsdir', $in{'nfs_dir'},
1823                                      $in{'nfs_host'}, "<pre>$dirlist</pre>"));
1824                     }
1825             }
1826
1827         # Try a test mount to see if filesystem is available
1828         $temp = &tempname();
1829         &make_dir($temp, 0755);
1830         &execute_command("mount -t $_[0] ".
1831                          quotemeta("$in{nfs_host}:$in{nfs_dir}")." ".
1832                          quotemeta($temp),
1833                          undef, \$mout, \$mout);
1834         if ($mout =~ /No such file or directory/i) {
1835                 &error(&text('linux_enfsdir', $in{'nfs_dir'},
1836                              $in{'nfs_host'}, "<pre>$dirlist</pre>"));
1837                 }
1838         elsif ($mout =~ /Permission denied/i) {
1839                 &error(&text('linux_enfsperm', $in{'nfs_dir'}, $in{'nfs_host'}));
1840                 }
1841         elsif ($?) {
1842                 &error(&text('linux_enfsmount', "<tt>$mout</tt>"));
1843                 }
1844         # It worked! unmount
1845         local $umout;
1846         &execute_command("umount ".quotemeta($temp), undef, \$umout, \$umout);
1847         if ($?) {
1848                 &error(&text('linux_enfsmount', "<tt>$umout</tt>"));
1849                 }
1850         rmdir(&translate_filename($temp));      # Don't delete mounted files!
1851
1852         return "$in{nfs_host}:$in{nfs_dir}";
1853         }
1854 elsif ($_[0] eq "auto") {
1855         # Check if the automounter map exists..
1856         (-r $in{auto_map}) || &error(&text('linux_eautomap', $in{'auto_map'}));
1857         return $in{auto_map};
1858         }
1859 elsif ($_[0] eq "autofs") {
1860         # Check if the map exists (if it is a file)
1861         if ($in{'autofs_map'} =~ /^\// && !(-r $in{'autofs_map'})) {
1862                 &error(&text('linux_eautomap', $in{'autofs_map'}));
1863                 }
1864         return $in{autofs_map};
1865         }
1866 elsif ($_[0] eq $smbfs_fs || $_[0] eq "cifs") {
1867         # No real checking done
1868         $in{'smbfs_server'} =~ /\S/ || &error($text{'linux_eserver'});
1869         $in{'smbfs_share'} =~ /\S/ || &error($text{'linux_eshare'});
1870         return "\\\\".lc($in{'smbfs_server'})."\\".lc($in{'smbfs_share'});
1871         }
1872 elsif ($_[0] eq "tmpfs") {
1873         # No location needed
1874         return "tmpfs";
1875         }
1876 elsif ($_[0] eq "bind") {
1877         # Just check the directory
1878         -d $in{'bind_dir'} || &error($text{'linux_ebind'});
1879         return $in{'bind_dir'};
1880         }
1881 else {
1882         # This is some kind of disk-based linux filesystem.. get the device name
1883         if ($in{'lnx_dev'} == 0) {
1884                 $dv = $in{'lnx_disk'};
1885                 }
1886         elsif ($in{'lnx_dev'} == 2) {
1887                 $dv = $in{'lnx_raid'};
1888                 }
1889         elsif ($in{'lnx_dev'} == 3) {
1890                 $dv = "LABEL=".$in{'lnx_label'};
1891                 }
1892         elsif ($in{'lnx_dev'} == 4) {
1893                 $dv = $in{'lnx_lvm'};
1894                 }
1895         elsif ($in{'lnx_dev'} == 5) {
1896                 $dv = "UUID=".$in{'lnx_uuid'};
1897                 }
1898         else {
1899                 $dv = $in{'lnx_other'};
1900                 $dv || &error($text{'linux_edev'});
1901                 }
1902
1903         # If the device entered is a symlink, follow it
1904         #if ($dvlink = readlink($dv)) {
1905         #       if ($dvlink =~ /^\//) { $dv = $dvlink; }
1906         #       else {  $dv =~ /^(.*\/)[^\/]+$/;
1907         #               $dv = $1.$dvlink;
1908         #               }
1909         #       }
1910
1911         # Check if the device actually exists and uses the right filesystem
1912         if (!-r $dv && $dv !~ /LABEL=/ && $dv !~ /UUID=/) {
1913                 if ($_[0] eq "swap" && $dv !~ /\/dev/) {
1914                         &swap_form($dv);
1915                         }
1916                 else {
1917                         &error(&text('linux_edevfile', $dv));
1918                         }
1919                 }
1920         return $dv;
1921         }
1922 }
1923
1924 # check_options(type, device, directory)
1925 # Read options for some filesystem from %in, and use them to update the
1926 # %options array. Options handled by the user interface will be set or
1927 # removed, while unknown options will be left untouched.
1928 sub check_options
1929 {
1930 local($k, @rv);
1931
1932 # Parse the common options first..
1933 if ($_[0] ne "swap" && $_[0] ne "auto" &&
1934     $_[0] ne "autofs" && $_[0] ne $smbfs_fs && $_[0] ne "cifs") {
1935         delete($options{"ro"}); delete($options{"rw"});
1936         if ($in{lnx_ro}) { $options{"ro"} = ""; }
1937
1938         delete($options{"sync"}); delete($options{"async"});
1939         if ($in{lnx_sync}) { $options{"sync"} = ""; }
1940
1941         delete($options{"dev"}); delete($options{"nodev"});
1942         if ($in{lnx_nodev}) { $options{"nodev"} = ""; }
1943
1944         delete($options{"exec"}); delete($options{"noexec"});
1945         if ($in{lnx_noexec}) { $options{"noexec"} = ""; }
1946
1947         delete($options{"suid"}); delete($options{"nosuid"});
1948         if ($in{lnx_nosuid}) { $options{"nosuid"} = ""; }
1949
1950         delete($options{"user"}); delete($options{"nouser"});
1951         if ($in{lnx_user}) { $options{"user"} = ""; }
1952
1953         delete($options{"noatime"});
1954         $options{"noatime"} = "" if ($in{'lnx_noatime'});
1955         delete($options{"relatime"}) if ($in{'lnx_noatime'});
1956         }
1957
1958 if (($_[0] eq "nfs") || ($_[0] eq "nfs4")) {
1959         # NFS has a few specific options..
1960         delete($options{"bg"}); delete($options{"fg"});
1961         if ($in{nfs_bg}) { $options{"bg"} = ""; }
1962
1963         delete($options{"soft"}); delete($options{"hard"});
1964         if ($in{nfs_soft}) { $options{"soft"} = ""; }
1965
1966         delete($options{"timeo"});
1967         if (!$in{nfs_timeo_def}) { $options{"timeo"} = $in{nfs_timeo}; }
1968
1969         delete($options{"port"});
1970         if (!$in{nfs_port_def}) { $options{"port"} = $in{nfs_port}; }
1971
1972         delete($options{"intr"}); delete($options{"nointr"});
1973         if ($in{nfs_intr}) { $options{"intr"} = ""; }
1974
1975         delete($options{"tcp"}); delete($options{"udp"});
1976         if ($in{nfs_transfert} eq "tcp") {
1977                 $options{"tcp"} = "";
1978                 }
1979         elsif ($in{nfs_transfert} eq "udp") {
1980                 $options{"udp"} = "";
1981                 }
1982
1983         delete($options{"wsize"});
1984         if (!$in{nfs_wsize_def}) { $options{"wsize"} = $in{nfs_wsize}; }
1985
1986         delete($options{"rsize"});
1987         if (!$in{nfs_rsize_def}) { $options{"rsize"} = $in{nfs_rsize}; }
1988
1989         delete($options{"sec"});
1990         # Only sys and krb5 for the moment
1991         if ($in{nfs_auth}) {
1992             if ($in{nfs_sec} == 0) { $options{"sec"} = "krb5"; }
1993             if ($in{nfs_sec} == 1) { $options{"sec"} = "krb5i"; }
1994             if ($in{nfs_sec} == 2) { $options{"sec"} = "krb5p"; }
1995         }
1996     }
1997 elsif ($_[0] =~ /^ext\d+$/) {
1998         # More options for ext2..
1999         if ($no_mount_check) {
2000                 delete($options{"bsddf"}); delete($options{"minixdf"});
2001                 $options{"minixdf"} = "" if ($in{'ext2_df'});
2002                 }
2003         else {
2004                 delete($options{"check"}); delete($options{"nocheck"});
2005                 if ($in{ext2_check} ne "normal") {
2006                         $options{"check"} = $in{ext2_check};
2007                         }
2008                 }
2009
2010         delete($options{"errors"});
2011         if ($in{ext2_errors} ne "default") {
2012                 $options{"errors"} = $in{ext2_errors};
2013                 }
2014
2015         delete($options{"grpid"}); delete($options{"bsdgroups"});
2016         delete($options{"sysvgroups"}); delete($options{"nogrpid"});
2017         if ($in{ext2_grpid}) {
2018                 $options{"grpid"} = "";
2019                 }
2020
2021         delete($options{"resuid"}); delete($options{"resgid"});
2022         if ($in{'ext2_resuid'})
2023                 { $options{"resuid"} = getpwnam($in{'ext2_resuid'}); }
2024         if ($in{'ext2_resgid'})
2025                 { $options{"resgid"} = getgrnam($in{'ext2_resgid'}); }
2026
2027         delete($options{"quota"}); delete($options{"noquota"});
2028         delete($options{"usrquota"}); delete($options{"grpquota"});
2029         if ($in{'ext2_quota'} == 1) { $options{'usrquota'} = ""; }
2030         elsif ($in{'ext2_quota'} == 2) { $options{'grpquota'} = ""; }
2031         elsif ($in{'ext2_quota'} == 3)
2032                 { $options{'usrquota'} = $options{'grpquota'} = ""; }
2033         }
2034 elsif ($_[0] eq "fat" || $_[0] eq "vfat" ||
2035        $_[0] eq "msdos" || $_[0] eq "umsdos" || $_[0] eq "fatx") {
2036         # All dos-based filesystems have similar options
2037         delete($options{"uid"}); delete($options{"gid"});
2038         if ($in{fat_uid} ne "") { $options{"uid"} = getpwnam($in{'fat_uid'}); }
2039         if ($in{fat_gid} ne "") { $options{"gid"} = getgrnam($in{'fat_gid'}); }
2040
2041         delete($options{"check"});
2042         if ($in{fat_check} ne "") { $options{"check"} = $in{fat_check}; }
2043
2044         delete($options{"conv"});
2045         if ($in{fat_conv} ne "") { $options{"conv"} = $in{fat_conv}; }
2046
2047         delete($options{"umask"});
2048         if (!$in{fat_umask_def}) {
2049                 $in{fat_umask} =~ /^[0-7]{3}$/ ||
2050                         &error(&text('linux_emask', $in{'fat_umask'}));
2051                 $options{"umask"} = $in{fat_umask};
2052                 }
2053
2054         delete($options{"quiet"});
2055         if ($in{fat_quiet}) {
2056                 $options{"quiet"} = "";
2057                 }
2058
2059         if ($_[0] eq "vfat") {
2060                 # Parse extra vfat options..
2061                 delete($options{"uni_xlate"});
2062                 if ($in{fat_uni_xlate}) { $options{"uni_xlate"} = ""; }
2063
2064                 delete($options{"posix"});
2065                 if ($in{fat_posix}) { $options{"posix"} = ""; }
2066                 }
2067         }
2068 elsif ($_[0] eq "hpfs") {
2069         # OS/2 filesystem options..
2070         delete($options{"uid"}); delete($options{"gid"});
2071         if ($in{hpfs_uid} ne "") { $options{"uid"} = getpwnam($in{hpfs_uid}); }
2072         if ($in{hpfs_gid} ne "") { $options{"gid"} = getgrnam($in{hpfs_gid}); }
2073
2074         delete($options{"umask"});
2075         if (!$in{hpfs_umask_def}) {
2076                 $in{hpfs_umask} =~ /^[0-7]{3}$/ ||
2077                         &error(&text('linux_emask', $in{'hpfs_umask'}));
2078                 $options{"umask"} = $in{hpfs_umask};
2079                 }
2080
2081         delete($options{"conv"});
2082         if ($in{hpfs_conv} ne "") { $options{"conv"} = $in{hpfs_conv}; }
2083         }
2084 elsif ($_[0] eq "iso9660") {
2085         # Options for iso9660 cd-roms
2086         delete($options{"uid"}); delete($options{"gid"});
2087         if ($in{iso9660_uid} ne "")
2088                 { $options{"uid"} = getpwnam($in{iso9660_uid}); }
2089         if ($in{iso9660_gid} ne "")
2090                 { $options{"gid"} = getgrnam($in{iso9660_gid}); }
2091
2092         delete($options{"norock"});
2093         if ($in{iso9660_norock}) { $options{"norock"} = ""; }
2094
2095         delete($options{"mode"});
2096         $in{iso9660_mode} =~ /^[0-7]{3}$/ ||
2097                 &error(&text('linux_emask', $in{'iso9660_mode'}));
2098         $options{"mode"} = $in{iso9660_mode};
2099         }
2100 elsif ($_[0] eq "autofs") {
2101         # Options for automounter filesystems
2102         delete($options{'timeout'});
2103         if (!$in{'autofs_timeout_def'}) {
2104                 $in{'autofs_timeout'} =~ /^\d+$/ ||
2105                         &error(&text('linux_etimeout', $in{'autofs_timeout'}));
2106                 $options{'timeout'} = $in{'autofs_timeout'};
2107                 }
2108         delete($options{'pid-file'});
2109         if (!$in{'autofs_pid-file_def'}) {
2110                 $in{'autofs_pid-file'} =~ /^\/\S+$/ ||
2111                        &error(&text('linux_epidfile', $in{'autofs_pid-file'}));
2112                 $options{'pid-file'} = $in{'autofs_pid-file'};
2113                 }
2114         }
2115 elsif ($_[0] eq $smbfs_fs || $_[0] eq "cifs") {
2116         # Options for smb filesystems..
2117         local $support = $_[0] eq $smbfs_fs ? $smbfs_support : $cifs_support;
2118         delete($options{'user'}); delete($options{'username'});
2119         if ($in{smbfs_user}) {
2120                 $options{$support == 4 ? 'username' : 'user'} = $in{smbfs_user};
2121                 }
2122
2123         delete($options{'passwd'}); delete($options{'password'});
2124         if ($in{smbfs_passwd}) {
2125                 $options{$support == 4 ? 'password' : 'passwd'} = $in{smbfs_passwd};
2126                 }
2127
2128         if ($support == 4) {    
2129                 delete($options{'credentials'});
2130                 if ($in{smbfs_creds}) {
2131                         $options{'credentials'} = $in{smbfs_creds};
2132                         }
2133                 }
2134
2135         if (!$access{'simopts'}) {
2136                 if ($support != 2) {
2137                         delete($options{uid});
2138                         if ($in{smbfs_uid} ne "") { $options{uid} = getpwnam($in{smbfs_uid}); }
2139
2140                         delete($options{gid});
2141                         if ($in{smbfs_gid} ne "") { $options{gid} = getgrnam($in{smbfs_gid}); }
2142                         }
2143
2144                 if ($support == 1) {
2145                         delete($options{servername});
2146                         if (!$in{smbfs_sname_def})
2147                                 { $options{servername} = $in{smbfs_sname}; }
2148                         }
2149                 elsif ($support == 2 || $support == 4) {
2150                         delete($options{workgroup});
2151                         if (!$in{smbfs_wg_def})
2152                                 { $options{workgroup} = $in{smbfs_wg}; }
2153                         }
2154
2155                 if ($support < 3) {
2156                         delete($options{clientname});
2157                         if (!$in{smbfs_cname_def})
2158                                 { $options{clientname} = $in{smbfs_cname}; }
2159
2160                         delete($options{machinename});
2161                         if (!$in{smbfs_mname_def})
2162                                 { $options{machinename} = $in{smbfs_mname}; }
2163                         elsif (!&to_ipaddress($in{'smbfs_server'})) {
2164                                 # No hostname found for the server.. try to guess
2165                                 local($out, $sname);
2166                                 $sname = $in{'smbfs_server'};
2167                                 $out = &backquote_command("$config{'nmblookup_path'} -d 0 $sname 2>&1");
2168                                 if (!$? && $out =~ /^([0-9\.]+)\s+$sname\n/) {
2169                                         $options{machinename} = $1;
2170                                         }
2171                                 }
2172                         }
2173                 elsif ($support == 4) {
2174                         delete($options{"netbiosname"});
2175                         if (!$in{"smbfs_cname_def"}) {
2176                                 $in{"smbfs_cname"} =~ /^\S+$/ ||
2177                                         &error($text{'linux_ecname'});
2178                                 $options{"netbiosname"} = $in{"smbfs_cname"};
2179                                 }
2180                         delete($options{"ip"});
2181                         if (!$in{"smbfs_mname_def"}) {
2182                                 &to_ipaddress($in{"smbfs_mname"}) ||
2183                                         &error($text{'linux_emname'});
2184                                 $options{"ip"} = $in{"smbfs_mname"};
2185                                 }
2186                         }
2187
2188                 if ($support == 1) {
2189                         delete($options{fmode});
2190                         if ($in{smbfs_fmode} !~ /^[0-7]{3}$/) {
2191                                 &error(&text('linux_efmode', $in{'smbfs_fmode'}));
2192                                 }
2193                         elsif ($in{smbfs_fmode} ne "755")
2194                                 { $options{fmode} = $in{smbfs_fmode}; }
2195
2196                         delete($options{dmode});
2197                         if ($in{smbfs_dmode} !~ /^[0-7]{3}$/) {
2198                                 &error(&text('linux_edmode', $in{'smbfs_dmode'}));
2199                                 }
2200                         elsif ($in{smbfs_dmode} ne "755")
2201                                 { $options{dmode} = $in{smbfs_dmode}; }
2202                         }
2203                 elsif ($support >= 3) {
2204                         if ($in{'smbfs_fmask_def'}) {
2205                                 delete($options{'fmask'});
2206                                 }
2207                         else {
2208                                 $in{'smbfs_fmask'} =~ /^[0-7]{3}$/ ||
2209                                     &error(&text('linux_efmode', $in{'smbfs_fmask'}));
2210                                 $options{'fmask'} = $in{'smbfs_fmask'};
2211                                 }
2212
2213                         if ($in{'smbfs_dmask_def'}) {
2214                                 delete($options{'dmask'});
2215                                 }
2216                         else {
2217                                 $in{'smbfs_dmask'} =~ /^[0-7]{3}$/ ||
2218                                     &error(&text('linux_edmode', $in{'smbfs_dmask'}));
2219                                 $options{'dmask'} = $in{'smbfs_dmask'};
2220                                 }
2221
2222                         delete($options{'ro'}); delete($options{'rw'});
2223                         if ($in{'smbfs_ro'}) { $options{'ro'} = ''; }
2224                         }
2225                 if ($support == 4) {
2226                         delete($options{'user'});
2227                         if ($in{'smbfs_user2'}) { $options{'user'} = ''; }
2228                         }
2229                 }
2230
2231         if ($_[0] eq "cifs") {
2232                 # Parse CIFS-specific options
2233                 delete($options{'codepage'});
2234                 if (!$in{'smbfs_codepage_def'}) {
2235                         $in{'smbfs_codepage'} =~ /^\S+$/ ||
2236                                 &error($text{'linux_ecodepage'});
2237                         $options{'codepage'} = $in{'smbfs_codepage'};
2238                         }
2239
2240                 delete($options{'iocharset'});
2241                 if (!$in{'smbfs_iocharset_def'}) {
2242                         $in{'smbfs_iocharset'} =~ /^\S+$/ ||
2243                                 &error($text{'linux_eiocharset'});
2244                         $options{'iocharset'} = $in{'smbfs_iocharset'};
2245                         }
2246                 }
2247         }
2248 elsif ($_[0] eq "reiserfs") {
2249         # Save reiserfs options
2250         delete($options{'notail'});
2251         $options{'notail'} = "" if ($in{'lnx_notail'});
2252
2253         if ($in{'lnx_user'} && !$in{'lnx_noexec'}) {
2254                 # Have to force on the exec option
2255                 $options{"exec"} = "";
2256                 }
2257         }
2258 elsif ($_[0] eq "tmpfs") {
2259         # Save tmpfs options
2260         if ($in{'lnx_tmpsize_def'}) {
2261                 delete($options{'size'});
2262                 }
2263         else {
2264                 $in{'lnx_tmpsize'} =~ /^(\d+)([kmg]?)$/ ||
2265                         &error($text{'lnx_etmpsize'});
2266                 $options{'size'} = $in{'lnx_tmpsize'};
2267                 }
2268
2269         if ($in{'lnx_nr_blocks_def'}) {
2270                 delete($options{'nr_blocks'});
2271                 }
2272         else {
2273                 $in{'lnx_nr_blocks'} =~ /^\d+$/ ||
2274                         &error($text{'lnx_enr_blocks'});
2275                 $options{'nr_blocks'} = $in{'lnx_nr_blocks'};
2276                 }
2277
2278         if ($in{'lnx_nr_inodes_def'}) {
2279                 delete($options{'nr_inodes'});
2280                 }
2281         else {
2282                 $in{'lnx_nr_inodes'} =~ /^\d+$/ ||
2283                         &error($text{'lnx_enr_inodes'});
2284                 $options{'nr_inodes'} = $in{'lnx_nr_inodes'};
2285                 }
2286
2287         if ($in{'lnx_tmpmode_def'}) {
2288                 delete($options{'mode'});
2289                 }
2290         else {
2291                 $in{'lnx_tmpmode'} =~ /^[0-7]{3,4}$/ ||
2292                         &error($text{'lnx_etmpmode'});
2293                 $options{'mode'} = $in{'lnx_tmpmode'};
2294                 }
2295         }
2296 elsif ($_[0] eq "xfs") {
2297         # Save XFS options
2298         delete($options{'quota'});
2299         delete($options{'usrquota'});
2300         delete($options{'uqnoenforce'});
2301         $options{'usrquota'} = "" if ($in{'xfs_usrquota'} == 1);
2302         $options{'uqnoenforce'} = "" if ($in{'xfs_usrquota'} == 2);
2303
2304         delete($options{'grpquota'});
2305         delete($options{'gqnoenforce'});
2306         $options{'grpquota'} = "" if ($in{'xfs_grpquota'} == 1);
2307         $options{'gqnoenforce'} = "" if ($in{'xfs_grpquota'} == 2);
2308         }
2309 elsif ($_[0] eq "ntfs") {
2310         # Save NTFS options
2311         delete($options{"uid"}); delete($options{"gid"});
2312         if ($in{ntfs_uid} ne "")
2313                 { $options{"uid"} = getpwnam($in{ntfs_uid}); }
2314         if ($in{ntfs_gid} ne "")
2315                 { $options{"gid"} = getgrnam($in{ntfs_gid}); }
2316         }
2317 elsif ($_[0] eq "swap") {
2318         # Save SWAP options
2319         if ($in{'swap_pri_def'}) {
2320                 delete($options{'pri'});
2321                 }
2322         else {
2323                 $in{'swap_pri'} =~ /^\d+$/ && $in{'swap_pri'} <= 32767 ||
2324                         &error($text{'linux_eswappri'});
2325                 $options{'pri'} = $in{'swap_pri'};
2326                 }
2327         }
2328
2329 # Add loop option if mounting a normal file
2330 if ($_[0] ne "swap" && $_[0] ne "auto" && $_[0] ne "autofs" &&
2331     $_[0] ne $smbfs_fs && $_[0] ne "cifs" && $_[0] ne "nfs" &&
2332     $_[0] ne "nfs4" && $_[0] ne "tmpfs") {
2333         local(@st);
2334         @st = stat($_[1]);
2335         if (@st && ($st[2] & 0xF000) == 0x8000) {
2336                 # a regular file.. add the loop option
2337                 if (!$options{'loop'}) {
2338                         $options{'loop'} = "";
2339                         }
2340                 }
2341         }
2342
2343 # Return options string
2344 foreach $k (sort { ($b eq "user" ? 1 : 0) <=> ($a eq "user" ? 1 : 0) } (keys %options)) {
2345         if ($options{$k} eq "") { push(@rv, $k); }
2346         else { push(@rv, "$k=$options{$k}"); }
2347         }
2348 return @rv ? join(',' , @rv) : "-";
2349 }
2350
2351
2352 # Get the smbfs options from 'smbfs_opts' file in the current directory. This
2353 # is sadly necessary because there is no way to get the current options for
2354 # an existing smbfs mount... so webmin has to save them in a file when
2355 # mounting. Blech.
2356 sub read_smbopts
2357 {
2358 local($_);
2359 open(SMBOPTS, "$module_config_directory/smbfs");
2360 while(<SMBOPTS>) {
2361         /^(\S+)\s+(\S+)$/;
2362         $smbopts{$1} = $2;
2363         }
2364 close(SMBOPTS);
2365 }
2366
2367 sub write_smbopts
2368 {
2369 local($_);
2370 &open_tempfile(SMBOPTS, "> $module_config_directory/smbfs");
2371 foreach (keys %smbopts) {
2372         &print_tempfile(SMBOPTS, "$_\t$smbopts{$_}\n");
2373         }
2374 &close_tempfile(SMBOPTS);
2375 }
2376
2377
2378 # create_swap(file, size, units)
2379 # Calls dd and mkswap to setup a swap file
2380 sub create_swap
2381 {
2382 local($out, $bl);
2383 $bl = $_[1] * ($_[2] eq "g" ? 1024*1024 :
2384                $_[2] eq "m" ? 1024 : 1);
2385 $out = &backquote_logged("dd if=/dev/zero of=$_[0] bs=1024 count=$bl 2>&1");
2386 if ($?) { return "dd failed : $out"; }
2387 $out = &backquote_logged("mkswap $_[0] $bl 2>&1");
2388 if ($?) { return "mkswap failed : $out"; }
2389 &system_logged("sync >/dev/null 2>&1");
2390 return 0;
2391 }
2392
2393 # exports_list(host, dirarray, clientarray)
2394 # Fills the directory and client array references with exports from some
2395 # host. Returns an error string if something went wrong
2396 sub exports_list
2397 {
2398 local($dref, $cref, $out, $_);
2399 $dref = $_[1]; $cref = $_[2];
2400 $out = &backquote_command("showmount -e ".quotemeta($_[0])." 2>&1", 1);
2401 if ($?) { return $out; }
2402
2403 # Add '/' if the server is in NFSv4
2404 if (nfs_max_version($_[0]) >= 4) {
2405     push(@$dref, "/"); push(@$cref, "*"); }
2406
2407 foreach (split(/\n/, $out)) {
2408         if (/^(\/\S*)\s+(.*)$/) {
2409                 push(@$dref, $1); push(@$cref, $2);
2410                 }
2411         }
2412 return undef;
2413 }
2414
2415 # nfs_max_version(host)
2416 # Return the max NFS version allowed on a server
2417 sub nfs_max_version
2418 {
2419     local($_, $max, $out);
2420     $max = 0;
2421     $out = &backquote_command("/usr/sbin/rpcinfo -p ".quotemeta($_[0])." 2>&1", 1);
2422     if ($?) { return $out; }
2423     foreach (split(/\n/, $out)) {
2424         if ((/ +(\d) +.*nfs/) && ($1 > $max)) {
2425             $max = $1; }
2426     }
2427     return $max;
2428 }
2429
2430 # broadcast_addr()
2431 # Returns a useable broadcast address for finding NFS servers
2432 sub broadcast_addr
2433 {
2434 local($out);
2435 $out = &backquote_command("ifconfig -a 2>&1", 1);
2436 if ($out =~ /(eth|tr)\d\s+.*\n.*Bcast:(\S+)\s+/) { return $2; }
2437 return "255.255.255.255";
2438 }
2439
2440 # autofs_options(string)
2441 # Converts a string of options line --timeout 60 to something like timeout=60
2442 sub autofs_options
2443 {
2444 local(@options);
2445 if ($_[0] =~ /--timeout\s+(\d+)/ || $_[0] =~ /-t\s+(\d+)/) {
2446         push(@options, "timeout=$1");
2447         }
2448 if ($_[0] =~ /--pid-file\s+(\S+)/ || $_[0] =~ /-p\s+(\d+)/) {
2449         push(@options, "pid-file=$1");
2450         }
2451 return join(',', @options);
2452 }
2453
2454 # autofs_args(string)
2455 # Convert a comma-separated options string into args for automount
2456 sub autofs_args
2457 {
2458 local(%options, $args);
2459 &parse_options("autofs", $_[0]);
2460 if (defined($options{'timeout'})) {
2461         $args .= " --timeout $options{'timeout'}";
2462         }
2463 if (defined($options{'pid-file'})) {
2464         $args .= " --pid-file $options{'pid-file'}";
2465         }
2466 return $args;
2467 }
2468
2469 # read_amd_conf()
2470 # Returns the entire amd config file as a string
2471 sub read_amd_conf
2472 {
2473 local $sl = $/;
2474 $/ = undef;
2475 local $rv;
2476 foreach $f (split(/\s+/, $config{'auto_file'})) {
2477         open(AMD, $f);
2478         $rv .= <AMD>;
2479         close(AMD);
2480         }
2481 $/ = $sl;
2482 return $rv;
2483 }
2484
2485 # write_amd_conf(text)
2486 sub write_amd_conf
2487 {
2488 local @af = split(/\s+/, $config{'auto_file'});
2489 &open_tempfile(AMD, ">$config{'auto_file'}");
2490 &print_tempfile(AMD, $_[0]);
2491 &close_tempfile(AMD);
2492 }
2493
2494 # parse_amd_conf()
2495 # Parses a new-style amd.conf file into a hashtable
2496 sub parse_amd_conf
2497 {
2498 local (@rv, $str);
2499 foreach $f (split(/\s+/, $config{'auto_file'})) {
2500         local $lnum = 0;
2501         open(AMD, $f);
2502         while(<AMD>) {
2503                 s/\r|\n//g;
2504                 s/#.*$//g;
2505                 if (/\[\s*(\S+)\s*\]/) {
2506                         $str = { 'dir' => $1,
2507                                  'line' => $lnum,
2508                                  'eline' => $lnum,
2509                                  'file' => $f };
2510                         push(@rv, $str);
2511                         }
2512                 elsif (/(\S+)\s*=\s*"(.*)"/ || /(\S+)\s*=\s*(\S+)/) {
2513                         $str->{'opts'}->{$1} = $2;
2514                         $str->{'eline'} = $lnum;
2515                         }
2516                 $lnum++;
2517                 }
2518         close(AMD);
2519         }
2520 return @rv;
2521 }
2522
2523 # device_name(device, [non-local])
2524 # Converts a device name to a human-readable form
2525 sub device_name
2526 {
2527 # First try to get name from fdisk module, as it knowns better about IDE
2528 # and SCSI devices
2529 if (&foreign_check("fdisk") && !$_[1]) {
2530         &foreign_require("fdisk");
2531         my @disks = &fdisk::list_disks_partitions();
2532         foreach my $d (@disks) {
2533                 if ($d->{'device'} eq $_[0]) {
2534                         return $d->{'desc'};
2535                         }
2536                 foreach my $p (@{$d->{'parts'}}) {
2537                         if ($p->{'device'} eq $_[0]) {
2538                                 return $p->{'desc'};
2539                                 }
2540                         }
2541                 }
2542         }
2543
2544 if (!$text{'select_part'}) {
2545         local %flang = &load_language('fdisk');
2546         foreach $k (keys %flang) {
2547                 $text{$k} = $flang{$k} if ($k =~ /^select_/);
2548                 }
2549         }
2550 return $_[0] =~ /^\/dev\/(s|h|xv|v)d([a-z]+)(\d+)$/ ?
2551         &text('select_part', $1 eq 's' ? 'SCSI' : $1 eq 'xv' ? 'Xen' :
2552                              $1 eq 'v' ? 'VirtIO' : 'IDE',
2553                              uc($2), "$3") :
2554        $_[0] =~ /^\/dev\/(s|h|xv|v)d([a-z]+)$/ ?
2555         &text('select_device', $1 eq 's' ? 'SCSI' : $1 eq 'xv' ? 'Xen' :
2556                                $1 eq 'v' ? 'VirtIO' : 'IDE',
2557                                uc($2)) :
2558        $_[0] =~ /rd\/c(\d+)d(\d+)p(\d+)$/ ?
2559         &text('select_mpart', "$1", "$2", "$3") :
2560        $_[0] =~ /ida\/c(\d+)d(\d+)p(\d+)$/ ?
2561         &text('select_cpart', "$1", "$2", "$3") :
2562        $_[0] =~ /cciss\/c(\d+)d(\d+)p(\d+)$/ ?
2563         &text('select_smartpart', "$1", "$2", "$3") :
2564        $_[0] =~ /scsi\/host(\d+)\/bus(\d+)\/target(\d+)\/lun(\d+)\/part(\d+)/ ?
2565         &text('select_spart', "$1", "$2", "$3", "$4", "$5") :
2566        $_[0] =~ /scsi\/host(\d+)\/bus(\d+)\/target(\d+)\/lun(\d+)\/disc/ ?
2567         &text('select_scsi', "$1", "$2", "$3", "$4") :
2568        $_[0] =~ /ide\/host(\d+)\/bus(\d+)\/target(\d+)\/lun(\d+)\/part(\d+)/ ?
2569         &text('select_snewide', "$1", "$2", "$3", "$4", "$5") :
2570        $_[0] =~ /ide\/host(\d+)\/bus(\d+)\/target(\d+)\/lun(\d+)\/disc/ ?
2571         &text('select_newide', "$1", "$2", "$3", "$4") :
2572        $_[0] =~ /ataraid\/disc(\d+)\/part(\d+)$/ ?
2573         &text('select_ppart', "$1", "$2") :
2574        $_[0] =~ /fd(\d+)$/ ?
2575         &text('select_fd', "$1") :
2576        $_[0] =~ /md(\d+)$/ ?
2577         &text('linux_rdev', "$1") :
2578        $_[0] =~ /\/dev\/([^\/]+)\/([^\/]+)$/ && $1 ne "cdroms" ?
2579         &text('linux_ldev', "$1", "$2") :
2580        $_[0] =~ /LABEL=(\S+)/i ?
2581         &text('linux_label', "$1") :
2582        $_[0] =~ /UUID=(\S+)/i ?
2583         &text('linux_uuid', "$1") :
2584        $_[0] eq '/dev/cdrom' ?
2585         $text{'linux_cddev'} :
2586        $_[0] eq '/dev/burner' ?
2587         $text{'linux_burnerdev'} :
2588        $_[0] =~ /cdroms\/cdrom(\d+)$/ ?
2589         &text('linux_cddev2', "$1") :
2590         $_[0];
2591 }
2592
2593 sub files_to_lock
2594 {
2595 return ( $config{'fstab_file'}, $config{'autofs_file'},
2596          split(/\s+/, $config{'auto_file'}) );
2597 }
2598
2599 1;
2600