Handle hostnames with upper-case letters
[webmin.git] / mount / unixware-lib.pl
1 # unixware-lib.pl
2 # Filesystem functions for UnixWare (works for me on 7.0.1)
3
4 # Return information about a filesystem, in the form:
5 #  directory, device, type, options, fsck_order, mount_at_boot
6 # If a field is unused or ignored, a - appears instead of the value.
7 # Swap-filesystems (devices or files mounted for VM) have a type of 'swap',
8 # and 'swap' in the directory field
9 sub list_mounts
10 {
11 local(@rv, @p, $_, $i); $i = 0;
12
13 # List normal filesystem mounts
14 open(FSTAB, $config{fstab_file});
15 while(<FSTAB>) {
16         chop; s/#.*$//g;
17         if (!/\S/) { next; }
18         @p = split(/\s+/, $_);
19         if ($p[3] eq "swap") { $p[2] = "swap"; }
20         $rv[$i++] = [ $p[2], $p[0], $p[3], $p[6], $p[4], $p[5] ];
21         }
22 close(FSTAB);
23
24 # List automount points
25 open(AUTOTAB, $config{autofs_file});
26 while(<AUTOTAB>) {
27         chop; s/#.*$//g;
28         if (!/\S/ || /^[+\-]/) { next; }
29         @p = split(/\s+/, $_);
30         if ($p[2] eq "") { $p[2] = "-"; }
31         else { $p[2] =~ s/^-//g; }
32         $rv[$i++] = [ $p[0], $p[1], "autofs", $p[2], "-", "yes" ];
33         }
34 close(AUTOTAB);
35
36 return @rv;
37 }
38
39
40 # create_mount(directory, device, type, options, fsck_order, mount_at_boot)
41 # Add a new entry to the fstab file, and return the index of the new entry
42 sub create_mount
43 {
44 local($len, @mlist, $fcsk, $dir);
45 if ($_[2] eq "autofs") {
46         # An autofs mount.. add to /etc/auto_master
47         $len = grep { $_->[2] eq "autofs" } (&list_mounts());
48         &open_tempfile(AUTOTAB, ">> $config{autofs_file}");
49         &print_tempfile(AUTOTAB, "$_[0] $_[1]",($_[3] eq "-" ? "" : " -$_[3]"),"\n");
50         &close_tempfile(AUTOTAB);
51         }
52 else {
53         # Add to the fstab file
54         $len = grep { $_->[2] ne "autofs" } (&list_mounts());
55         &open_tempfile(FSTAB, ">> $config{fstab_file}");
56         if ($_[2] eq "ufs" || $_[2] eq "s5fs") {
57                 ($fsck = $_[1]) =~ s/\/dsk\//\/rdsk\//g;
58                 }
59         else { $fsck = "-"; }
60         if ($_[2] eq "swap") { $dir = "-"; }
61         else { $dir = $_[0]; }
62         &print_tempfile(FSTAB, "$_[1]  $fsck  $dir  $_[2]  $_[4]  $_[5]  $_[3]\n");
63         &close_tempfile(FSTAB);
64         }
65 return $len;
66 }
67
68
69 # delete_mount(index)
70 # Delete some mount from the table
71 sub delete_mount
72 {
73 local(@fstab, $i, $line, $_);
74 open(FSTAB, $config{fstab_file});
75 @fstab = <FSTAB>;
76 close(FSTAB);
77 $i = 0;
78
79 &open_tempfile(FSTAB, "> $config{fstab_file}");
80 foreach (@fstab) {
81         chop; ($line = $_) =~ s/#.*$//g;
82         if ($line =~ /\S/ && $i++ == $_[0]) {
83                 # found the line not to include
84                 }
85         else { &print_tempfile(FSTAB, $_,"\n"); }
86         }
87 &close_tempfile(FSTAB);
88
89 open(AUTOTAB, $config{autofs_file});
90 @autotab = <AUTOTAB>;
91 close(AUTOTAB);
92 &open_tempfile(AUTOTAB, "> $config{autofs_file}");
93 foreach (@autotab) {
94         chop; ($line = $_) =~ s/#.*$//g;
95         if ($line =~ /\S/ && $line !~ /^[+\-]/ && $i++ == $_[0]) {
96                 # found line not to include..
97                 }
98         else { &print_tempfile(AUTOTAB, $_,"\n"); }
99         }
100 &close_tempfile(AUTOTAB);
101 }
102
103
104 # change_mount(num, directory, device, type, options, fsck_order, mount_at_boot)
105 # Change an existing permanent mount
106 sub change_mount
107 {
108 local(@fstab, @autotab, $i, $line, $fsck, $dir, $_);
109 $i = 0;
110
111 open(FSTAB, $config{fstab_file});
112 @fstab = <FSTAB>;
113 close(FSTAB);
114 &open_tempfile(FSTAB, "> $config{fstab_file}");
115 foreach (@fstab) {
116         chop; ($line = $_) =~ s/#.*$//g;
117         if ($line =~ /\S/ && $i++ == $_[0]) {
118                 # Found the line to replace
119                 if ($_[3] eq "ufs" || $_[3] eq "s5fs") {
120                         ($fsck = $_[2]) =~ s/\/dsk\//\/rdsk\//g;
121                         }
122                 else { $fsck = "-"; }
123                 if ($_[3] eq "swap") { $dir = "-"; }
124                 else { $dir = $_[1]; }
125                 &print_tempfile(FSTAB, "$_[2]  $fsck  $dir  $_[3]  $_[5]  $_[6]  $_[4]\n");
126                 }
127         else { &print_tempfile(FSTAB, $_,"\n"); }
128         }
129 &close_tempfile(FSTAB);
130
131 open(AUTOTAB, $config{autofs_file});
132 @autotab = <AUTOTAB>;
133 close(AUTOTAB);
134 &open_tempfile(AUTOTAB, "> $config{autofs_file}");
135 foreach (@autotab) {
136         chop; ($line = $_) =~ s/#.*$//g;
137         if ($line =~ /\S/ && $line !~ /^[+\-]/ && $i++ == $_[0]) {
138                 # Found the line to replace
139                 &print_tempfile(AUTOTAB, "$_[1]  $_[2]  ",
140                                 ($_[4] eq "-" ? "" : "-$_[4]"),"\n");
141                 }
142         else { &print_tempfile(AUTOTAB, $_,"\n"); }
143         }
144 &close_tempfile(AUTOTAB);
145 }
146
147
148 # list_mounted()
149 # Return a list of all the currently mounted filesystems and swap files.
150 # The list is in the form:
151 #  directory device type options
152 # For swap files, the directory will be 'swap'
153 sub list_mounted
154 {
155 local(@rv, @p, $_, $i, $r);
156 &open_execute_command(SWAP, "swap -l 2>/dev/null", 1, 1);
157 while(<SWAP>) {
158         if (/^(\/\S+)\s+/) { push(@rv, [ "swap", $1, "swap", "-" ]); }
159         }
160 close(SWAP);
161 &open_tempfile(MNTTAB, "/etc/mnttab");
162 while(<MNTTAB>) {
163         s/#.*$//g; if (!/\S/) { next; }
164         @p = split(/\s+/, $_);
165         if ($p[0] =~ /:vold/) { next; }
166         if ($p[0] =~ /^rumba-(\d+)$/) {
167                 # rumba smb mount
168                 local($args, $ps); $p[3] = "pid=$1";
169                 $ps = (-x "/usr/ucb/ps") ? "/usr/ucb/ps auwwwwx $1"
170                                          : "ps -o args -f $1";
171                 &backquote_command($ps, 1) =~
172                         /rumba\s+\/\/([^\/]+)\/(.*\S)\s+(\/\S+)(.*)/ || next;
173                 $serv = $1; $shar = $2; $p[2] = "rumba"; $args = $4;
174                 if ($args =~ /\s+-s\s+(\S+)/ && $1 ne $serv) {
175                         $p[0] = "\\\\$1\\$shar";
176                         $p[3] .= ",machinename=$serv";
177                         }
178                 else { $p[0] = "\\\\$serv\\$shar"; }
179                 if ($args =~ /\s+-c\s+(\S+)/) { $p[3] .= ",clientname=$1"; }
180                 if ($args =~ /\s+-U\s+(\S+)/) { $p[3] .= ",username=$1"; }
181                 if ($args =~ /\s+-u\s+(\S+)/) { $p[3] .= ",uid=$1"; }
182                 if ($args =~ /\s+-g\s+(\S+)/) { $p[3] .= ",gid=$1"; }
183                 if ($args =~ /\s+-f\s+(\S+)/) { $p[3] .= ",fmode=$1"; }
184                 if ($args =~ /\s+-d\s+(\S+)/) { $p[3] .= ",dmode=$1"; }
185                 if ($args =~ /\s+-C/) { $p[3] .= ",noupper"; }
186                 if ($args =~ /\s+-P\s+(\S+)/) { $p[3] .= ",password=$1"; }
187                 if ($args =~ /\s+-S/) { $p[3] .= ",readwrite"; }
188                 if ($args =~ /\s+-w/) { $p[3] .= ",readonly"; }
189                 if ($args =~ /\s+-e/) { $p[3] .= ",attr"; }
190                 }
191         else { $p[3] = join(',' , (grep {!/^dev=/} split(/,/ , $p[3]))); }
192         push(@rv, [ $p[1], $p[0], $p[2], $p[3] ]);
193         }
194 &close_tempfile(MNTTAB);
195 foreach $r (@rv) {
196         if ($r->[2] eq "cachefs" && $r->[1] =~ /\.cfs_mnt_points/) {
197                 # Oh no.. a caching filesystem mount. Fiddle things so that
198                 # it looks right.
199                 for($i=0; $i<@rv; $i++) {
200                         if ($rv[$i]->[0] eq $r->[1]) {
201                                 # Found the automatically mounted entry. lose it
202                                 $r->[1] = $rv[$i]->[1];
203                                 splice(@rv, $i, 1);
204                                 last;
205                                 }
206                         }
207                 }
208         }
209 return @rv;
210 }
211
212
213 # mount_dir(directory, device, type, options)
214 # Mount a new directory from some device, with some options. Returns 0 if ok,
215 # or an error string if failed. If the directory is 'swap', then mount as
216 # virtual memory.
217 sub mount_dir
218 {
219 local($out, $opts);
220 if ($_[0] eq "swap") {
221         # Adding a swap device
222         $out = &backquote_logged("swap -a $_[1] 2>&1");
223         if ($?) { return $out; }
224         }
225 else {
226         # Mounting a directory
227         if ($_[2] eq "cachefs") {
228                 # Mounting a caching filesystem.. need to create cache first
229                 local(%options);
230                 &parse_options("cachefs", $_[3]);
231                 if (!(-r "$options{cachedir}/.cfs_resource")) {
232                         # The cache directory does not exist.. set it up
233                         if (-d $options{cachedir} &&
234                             !rmdir($options{"cachedir"})) {
235                                 return "The directory $options{cachedir} ".
236                                        "already exists. Delete it";
237                                 }
238                         $out = &backquote_logged("cfsadmin -c $options{cachedir} 2>&1");
239                         if ($?) { return $out; }
240                         }
241                 }
242         if ($_[2] eq "rumba") {
243                 # call 'rumba' to mount
244                 local(%options, $shortname, $shar, $opts, $rv);
245                 &parse_options("rumba", $_[3]);
246                 $shortname = &get_system_hostname();
247                 if ($shortname =~ /^([^\.]+)\.(.+)$/) { $shortname = $1; }
248                 $_[1] =~ /^\\\\(.+)\\(.+)$/;
249                 $shar = "//".($options{machinename} ?$options{machinename} :$1).
250                         "/$2";
251                 $opts = ("-s $1 ").
252                  (defined($options{'clientname'}) ?
253                         "-c $options{'clientname'} " : "-c $shortname ").
254                  (defined($options{'username'}) ?
255                         "-U $options{'username'} " : "").
256                  (defined($options{'uid'}) ? "-u $options{'uid'} " : "").
257                  (defined($options{'gid'}) ? "-g $options{'gid'} " : "").
258                  (defined($options{'fmode'}) ? "-f $options{'fmode'} " : "").
259                  (defined($options{'dmode'}) ? "-d $options{'dmode'} " : "").
260                  (defined($options{'noupper'}) ? "-C " : "").
261                  (defined($options{'password'}) ?
262                         "-P $options{'password'} " : "-n ").
263                  (defined($options{'readwrite'}) ? "-S " : "").
264                  (defined($options{'readonly'}) ? "-w " : "").
265                  (defined($options{'attr'}) ? "-e " : "");
266                 local $rtemp = &transname();
267                 $rv = &system_logged("rumba \"$shar\" $_[0] $opts >$rtemp 2>&1 </dev/null");
268                 $out = `cat $rtemp`; unlink($rtemp);
269                 if ($rv) { return "<pre>$out</pre> : rumba \"$shar\" $_[0] $opts"; }
270                 }
271         else {
272                 $opts = $_[3] eq "-" ? "" : "-o \"$_[3]\"";
273                 $out = &backquote_logged("mount -F $_[2] $opts -- $_[1] $_[0] 2>&1");
274                 if ($?) { return $out; }
275                 }
276         }
277 return 0;
278 }
279
280
281 # unmount_dir(directory, device, type)
282 # Unmount a directory (or swap device) that is currently mounted. Returns 0 if
283 # ok, or an error string if failed
284 sub unmount_dir
285 {
286 if ($_[0] eq "swap") {
287         $out = &backquote_logged("swap -d $_[1] 2>&1");
288         }
289 elsif ($_[2] eq "rumba") {
290         # kill the process (if nobody is in the directory)
291         $dir = $_[0];
292         if (&backquote_command("fuser -c $_[0] 2>/dev/null") =~ /\d/) {
293                 return "$_[0] is busy";
294                 }
295         if (&backquote_command("cat /etc/mnttab") =~
296             /rumba-(\d+)\s+$dir\s+nfs/) {
297                 &kill_logged('TERM', $1) || return "Failed to kill rumba";
298                 }
299         else {
300                 return "Failed to find rumba pid";
301                 }
302         sleep(1);
303         }
304 else {
305         $out = &backquote_logged("umount $_[0] 2>&1");
306         }
307 if ($?) { return $out; }
308 return 0;
309 }
310
311
312 # disk_space(type, directory)
313 # Returns the amount of total and free space for some filesystem, or an
314 # empty array if not appropriate.
315 sub disk_space
316 {
317 if (&get_mounted($_[1], "*") < 0) { return (); }
318 if ($_[0] eq "fd" || $_[0] eq "proc" || $_[0] eq "swap" || $_[0] eq "autofs") {
319         return ();
320         }
321 if (&backquote_command("df -k ".quotemeta($_[1]), 1) =~
322     /Mounted on\n\S+\s+(\S+)\s+\S+\s+(\S+)/) {
323         return ($1, $2);
324         }
325 return ( );
326 }
327
328
329 # list_fstypes()
330 # Returns an array of all the supported filesystem types. If a filesystem is
331 # found that is not one of the supported types, generate_location() and
332 # generate_options() will not be called for it.
333 sub list_fstypes
334 {
335 local(@fs);
336 @fs = ("vxfs", "ufs", "nfs", "hsfs", "pcfs", "lofs", "cachefs", "swap", "tmpfs", "autofs");
337 if (&has_command("rumba")) { push(@fs, "rumba"); }
338 return @fs;
339 }
340
341
342 # fstype_name(type)
343 # Given a short filesystem type, return a human-readable name for it
344 sub fstype_name
345 {
346 local(%fsmap);
347 %fsmap = ("vxfs", "Veritas Filesystem",
348           "ufs","Unix Filesystem",
349           "nfs","Network Filesystem",
350           "hsfs","ISO9660 CD-ROM",
351           "pcfs","MS-DOS Filesystem",
352           "lofs","Loopback Filesystem",
353           "cachefs","Caching Filesystem",
354           "swap","Virtual Memory",
355           "tmpfs","Ram Disk",
356           "autofs","Automounter Filesystem",
357           "proc","Process Image Filesystem",
358           "fd","File Descriptor Filesystem",
359           "rumba","Windows Networking Filesystem");
360 return $config{long_fstypes} && $fsmap{$_[0]} ? $fsmap{$_[0]} : uc($_[0]);
361 }
362
363
364 # mount_modes(type)
365 # Given a filesystem type, returns 4 numbers that determine how the file
366 # system can be mounted, and whether it can be fsck'd
367 #  0 - cannot be permanently recorded
368 #  1 - can be permanently recorded, and is always mounted at boot
369 #  2 - can be permanently recorded, and may or may not be mounted at boot
370 # The second is:
371 #  0 - mount is always permanent => mounted when saved
372 #  1 - doesn't have to be permanent
373 # The third is:
374 #  0 - cannot be fsck'd at boot time
375 #  1 - can be be fsck'd at boot time
376 # The fourth is:
377 #  0 - can be unmounted
378 #  1 - cannot be unmounted
379 sub mount_modes
380 {
381 if ($_[0] eq "vxfs" || $_[0] eq "ufs" || $_[0] eq "cachefs" || $_[0] eq "s5fs")
382    { return (2, 1, 1, 0); }
383 elsif ($_[0] eq "rumba") { return (0, 1, 0, 0); }
384 else { return (2, 1, 0, 0); }
385 }
386
387
388 # multiple_mount(type)
389 # Returns 1 if filesystems of this type can be mounted multiple times, 0 if not
390 sub multiple_mount
391 {
392 return ($_[0] eq "vxfs" || $_[0] eq "nfs" || $_[0] eq "tmpfs" || $_[0] eq "cachefs" || $_[0] eq "autofs" || $_[0] eq "lofs" || $_[0] eq "rumba");
393 }
394
395
396 # generate_location(type, location)
397 # Output HTML for editing the mount location of some filesystem.
398 sub generate_location
399 {
400 if ($_[0] eq "nfs") {
401         # NFS mount from some host and directory
402         if ($_[1] =~ /^nfs:/) { $nfsmode = 2; }
403         elsif (!$_[1] || $_[1] =~ /^([A-z0-9\-\.]+):([^,]+)$/) {
404                 $nfsmode = 0; $nfshost = $1; $nfspath = $2;
405                 }
406         else { $nfsmode = 1; }
407         if ($gconfig{'os_version'} >= 2.6) {
408                 # UnixWare 7 can list multiple NFS servers in mount
409                 print "<tr> <td><b>NFS Source</b></td>\n";
410                 printf "<td><input type=radio name=nfs_serv value=0 %s>\n",
411                         $nfsmode == 0 ? "checked" : "";
412                 print "<b>NFS Hostname</b></td>\n";
413                 print "<td><input name=nfs_host size=20 value=\"$nfshost\">\n";
414                 &nfs_server_chooser_button("nfs_host");
415                 print "&nbsp;<b>NFS Directory</b>\n";
416                 print "<input name=nfs_dir size=20 value=\"$nfspath\">\n";
417                 &nfs_export_chooser_button("nfs_host", "nfs_dir");
418                 print "</td> </tr>\n";
419
420                 print "<tr> <td></td>\n";
421                 printf "<td><input type=radio name=nfs_serv value=1 %s>\n",
422                         $nfsmode == 1 ? "checked" : "";
423                 print "<b>Multiple NFS Servers</b></td>\n";
424                 printf "<td><input name=nfs_list size=40 value=\"%s\">\n",
425                         $nfsmode == 1 ? $_[1] : "";
426                 print "</td> </tr>\n";
427
428                 if ($gconfig{'os_version'} >= 7) {
429                         print "<tr> <td></td> <td>\n";
430                         printf "<input type=radio name=nfs_serv value=2 %s>\n",
431                                 $nfsmode == 2 ? "checked" : "";
432                         print "<b>WebNFS URL</b></td> <td>\n";
433                         printf "<input name=nfs_url size=40 value=\"%s\">\n",
434                                 $nfsmode == 2 ? $_[1] : "";
435                         print "</td> </tr>\n";
436                         }
437                 }
438         else {
439                 print "<tr> <td><b>NFS Hostname</b></td>\n";
440                 print "<td><input name=nfs_host size=20 value=\"$nfshost\">\n";
441                 &nfs_server_chooser_button("nfs_host");
442                 print "</td>\n";
443                 print "<td><b>NFS Directory</b></td>\n";
444                 print "<td><input name=nfs_dir size=20 value=\"$nfspath\">\n";
445                 &nfs_export_chooser_button("nfs_host", "nfs_dir");
446                 print "</td> </tr>\n";
447                 }
448         }
449 elsif ($_[0] eq "tmpfs") {
450         # Location is irrelevant for tmpfs filesystems
451         }
452 elsif ($_[0] eq "ufs") {
453         # Mounted from a normal disk, raid (MD) device or from
454         # somewhere else
455         print "<tr> <td valign=top><b>UFS Disk</b></td>\n";
456         print "<td colspan=3>\n";
457         if ($_[1] =~ /^\/dev\/dsk\/c([0-9]+)t([0-9]+)d([0-9]+)s([0-9]+)$/) {
458                 $ufs_dev = 0;
459                 $scsi_c = $1; $scsi_t = $2; $scsi_d = $3; $scsi_s = $4;
460                 }
461         elsif ($_[1] eq "") {
462                 $ufs_dev = 0; $scsi_c = $scsi_t = $scsi_s = $scsi_d = 0;
463                 }
464         elsif ($_[1] =~ /^\/dev\/md\/dsk\/d([0-9]+)$/) {
465                 $ufs_dev = 1; $scsi_md = $1;
466                 }
467         else {
468                 $ufs_dev = 2; $scsi_path = $_[1];
469                 }
470         printf "<input type=radio name=ufs_dev value=0 %s> SCSI Disk:\n",
471                 $ufs_dev == 0 ? "checked" : "";
472         print "Controller <input name=ufs_c size=3 value=\"$scsi_c\">\n";
473         print "Target <input name=ufs_t size=3 value=\"$scsi_t\">\n";
474         print "Unit <input name=ufs_d size=3 value=\"$scsi_d\">\n";
475         print "Partition <input name=ufs_s size=3 value=\"$scsi_s\"><br>\n";
476
477         printf "<input type=radio name=ufs_dev value=1 %s> RAID Device:\n",
478                 $ufs_dev == 1 ? "checked" : "";
479         print "Unit <input name=ufs_md size=3 value=\"$scsi_md\"><br>\n";
480
481         printf "<input type=radio name=ufs_dev value=2 %s> Other Device:\n",
482                 $ufs_dev == 2 ? "checked" : "";
483         print "<input name=ufs_path size=20 value=\"$scsi_path\"><br>\n";
484         print "</td> </tr>\n";
485         }
486 elsif ($_[0] eq "vxfs") {
487         # Mounted from a normal disk, LVM device or from
488         # somewhere else
489         print "<tr> <td valign=top><b>VXFS Device</b></td>\n";
490         print "<td colspan=3>\n";
491         if ($_[1] =~ /^\/dev\/dsk\/c([0-9]+)t([0-9]+)d([0-9]+)s([0-9]+)$/) {
492                 $jfs_dev = 0;
493                 $scsi_c = $1; $scsi_t = $2; $scsi_d = $3; $scsi_s = $4;
494                 }
495         elsif ($_[1] eq "") {
496                 $jfs_dev = 0; $scsi_c = $scsi_t = $scsi_s = $scsi_d = 0;
497                 }
498         elsif ($_[1] =~ /^\/dev\/vg([0-9]+)\/(\S+)/) {
499                 $jfs_dev = 1; $scsi_vg = $1; $scsi_lv = $2;
500                 }
501         else {
502                 $jfs_dev = 2; $scsi_path = $_[1];
503                 }
504         $scsi_path = $_[1];
505
506         printf "<input type=radio name=jfs_dev value=0 %s> SCSI Disk:\n",
507                 $jfs_dev == 0 ? "checked" : "";
508         print "Controller <input name=jfs_c size=3 value=\"$scsi_c\">\n";
509         print "Target <input name=jfs_t size=3 value=\"$scsi_t\">\n";
510         print "Unit <input name=jfs_d size=3 value=\"$scsi_d\">\n";
511         print "Partition <input name=jfs_s size=3 value=\"$scsi_s\"><br>\n";
512
513         printf "<input type=radio name=jfs_dev value=1 %s> LVM Device:\n",
514                 $jfs_dev == 1 ? "checked" : "";
515         print "Volume Group <input name=jfs_vg size=2 value=\"$scsi_vg\">\n";
516         print "Logical Volume <input name=jfs_lv size=20 value=\"$scsi_lv\"><br>\n";
517
518         printf "<input type=radio name=jfs_dev value=2 %s> Other Device:\n",
519                 $jfs_dev == 2 ? "checked" : "";
520         print "<input name=jfs_path size=20 value=\"$scsi_path\">";
521         print &file_chooser_button("jfs_path", 0);
522         print "<br>\n";
523         print "</td> </tr>\n";
524         }
525 elsif ($_[0] eq "swap") {
526         # Swapping to a disk partition or a file
527         print "<tr> <td valign=top><b>Swap File</b></td>\n";
528         print "<td colspan=3>\n";
529         if ($_[1] =~ /^\/dev\/dsk\/c([0-9]+)t([0-9]+)d([0-9]+)s([0-9]+)$/) {
530                 $swap_dev = 0;
531                 $scsi_c = $1; $scsi_t = $2; $scsi_d = $3; $scsi_s = $4;
532                 }
533         elsif ($_[1] eq "") {
534                 $swap_dev = 1; $scsi_path = "";
535                 }
536         else {
537                 $swap_dev = 1; $scsi_path = $_[1];
538                 }
539         printf "<input type=radio name=swap_dev value=0 %s> SCSI Disk:\n",
540                 $swap_dev == 0 ? "checked" : "";
541         print "Controller <input name=swap_c size=3 value=\"$scsi_c\">\n";
542         print "Target <input name=swap_t size=3 value=\"$scsi_t\">\n";
543         print "Unit <input name=swap_d size=3 value=\"$scsi_d\">\n";
544         print "Partition <input name=swap_s size=3 value=\"$scsi_s\"><br>\n";
545
546         printf "<input type=radio name=swap_dev value=1 %s> File:\n",
547                 $swap_dev == 1 ? "checked" : "";
548         print "<input name=swap_path size=20 value=\"$scsi_path\"><br>\n";
549         print "</td> </tr>\n";
550         }
551 elsif ($_[0] eq "hsfs") {
552         # Mounting a SCSI cdrom
553         print "<tr> <td valign=top><b>CDROM Disk</b></td>\n";
554         print "<td colspan=3>\n";
555         if ($_[1] =~ /^\/dev\/dsk\/c([0-9]+)t([0-9]+)d([0-9]+)s([0-9]+)$/) {
556                 $hsfs_dev = 0;
557                 $scsi_c = $1; $scsi_t = $2; $scsi_d = $3; $scsi_s = $4;
558                 }
559         elsif ($_[1] eq "") {
560                 $hsfs_dev = 0;
561                 $scsi_c = 0; $scsi_t = 6; $scsi_d = 0; $scsi_s = 0;
562                 }
563         else {
564                 $hsfs_dev = 1; $scsi_path = $_[1];
565                 }
566         printf "<input type=radio name=hsfs_dev value=0 %s> SCSI Device:\n",
567                 $hsfs_dev == 0 ? "checked" : "";
568         print "Controller <input name=hsfs_c size=3 value=\"$scsi_c\">\n";
569         print "Target <input name=hsfs_t size=3 value=\"$scsi_t\">\n";
570         print "Unit <input name=hsfs_d size=3 value=\"$scsi_d\">\n";
571         print "Partition <input name=hsfs_s size=3 value=\"$scsi_s\"><br>\n";
572
573         printf "<input type=radio name=hsfs_dev value=1 %s> Other Device:\n",
574                 $hsfs_dev == 1 ? "checked" : "";
575         print "<input name=hsfs_path size=20 value=\"$scsi_path\"><br>\n";
576         print "</td> </tr>\n";
577         }
578 elsif ($_[0] eq "pcfs") {
579         # Mounting a SCSI msdos filesystem
580         print "<tr> <td valign=top><b>MS-DOS Disk</b></td>\n";
581         print "<td colspan=3>\n";
582         if ($_[1] =~ /^\/dev\/dsk\/c([0-9]+)t([0-9]+)d([0-9]+)s([0-9]+)$/) {
583                 $pcfs_dev = 0;
584                 $scsi_c = $1; $scsi_t = $2; $scsi_d = $3; $scsi_s = $4;
585                 }
586         elsif ($_[1] eq "") {
587                 $pcfs_dev = 1; $scsi_path = "";
588                 }
589         else {
590                 $pcfs_dev = 1; $scsi_path = $_[1];
591                 }
592         printf "<input type=radio name=pcfs_dev value=0 %s> SCSI Device:\n",
593                 $pcfs_dev == 0 ? "checked" : "";
594         print "Controller <input name=pcfs_c size=3 value=\"$scsi_c\">\n";
595         print "Target <input name=pcfs_t size=3 value=\"$scsi_t\">\n";
596         print "Unit <input name=pcfs_d size=3 value=\"$scsi_d\">\n";
597         print "Partition <input name=pcfs_s size=3 value=\"$scsi_s\"><br>\n";
598
599         printf "<input type=radio name=pcfs_dev value=1 %s> Other Device:\n",
600                 $pcfs_dev == 1 ? "checked" : "";
601         print "<input name=pcfs_path size=20 value=\"$scsi_path\"><br>\n";
602         print "</td> </tr>\n";
603         }
604 elsif ($_[0] eq "lofs") {
605         # Mounting some directory to another location
606         print "<tr> <td><b>Original Directory</b></td>\n";
607         print "<td><input name=lofs_src size=30 value=\"$_[1]\">\n";
608         print &file_chooser_button("lofs_src", 1);
609         print "</td> </tr>\n";
610         }
611 elsif ($_[0] eq "cachefs") {
612         # Mounting a cached filesystem of some type.. need a location for
613         # the source of the mount
614         print "<tr> <td><b>Cache Source</b></td>\n";
615         print "<td><input name=cfs_src size=20 value=\"$_[1]\"></td> </tr>\n";
616         }
617 elsif ($_[0] eq "autofs") {
618         # An automounter entry.. can be -hosts, -xfn or from some mapping
619         print "<tr> <td valign=top><b>Automounter map</b></td>\n";
620         printf "<td><input type=radio name=autofs_type value=0 %s>\n",
621                 $_[1] eq "-hosts" || $_[1] eq "-xfn" ? "" : "checked";
622         printf "Use map <input name=autofs_map size=20 value=\"%s\"><br>\n",
623                 $_[1] eq "-hosts" || $_[1] eq "-xfn" ? "" : $_[1];
624         printf "<input type=radio name=autofs_type value=1 %s>\n",
625                 $_[1] eq "-hosts" ? "checked" : "";
626         print "All NFS exports map<br>\n";
627         printf "<input type=radio name=autofs_type value=2 %s>\n",
628                 $_[1] eq "-xfn" ? "checked" : "";
629         print "Federated  Naming  Service map</td> </tr>\n";
630         }
631 elsif ($_[0] eq "rumba") {
632         # Windows filesystem
633         $_[1] =~ /^\\\\(.*)\\(.*)$/;
634         print "<tr> <td><b>Server Name</b></td>\n";
635         print "<td><input name=rumba_server value=\"$1\" size=20>\n";
636         &smb_server_chooser_button("rumba_server");
637         print "</td>\n";
638         print "<td><b>Share Name</b></td>\n";
639         print "<td><input name=rumba_share value=\"$2\" size=20>\n";
640         &smb_share_chooser_button("rumba_server", "rumba_share");
641         print "</td> </tr>\n";
642         }
643 }
644
645
646 # generate_options(type, newmount)
647 # Output HTML for editing mount options for a partilcar filesystem 
648 # under this OS
649 sub generate_options
650 {
651 if ($_[0] eq "nfs") {
652         # UnixWare NFS has many options, not all of which are editable here
653         print "<tr> <td><b>Read-Only?</b></td>\n";
654         printf "<td nowrap><input type=radio name=nfs_ro value=1 %s> Yes\n",
655                 defined($options{"ro"}) ? "checked" : "";
656         printf "<input type=radio name=nfs_ro value=0 %s> No</td>\n",
657                 defined($options{"ro"}) ? "" : "checked";
658
659         print "<td><b>Disallow setuid programs?</b></td>\n";
660         printf "<td nowrap><input type=radio name=nfs_nosuid value=1 %s> Yes\n",
661                 defined($options{"nosuid"}) ? "checked" : "";
662         printf "<input type=radio name=nfs_nosuid value=0 %s> No</td> </tr>\n",
663                 defined($options{"nosuid"}) ? "" : "checked";
664
665         print "<tr> <td><b>Files inherit parent GID?</b></td>\n";
666         printf "<td nowrap><input type=radio name=nfs_grpid value=0 %s> Yes\n",
667                 defined($options{"grpid"}) ? "" : "checked";
668         printf "<input type=radio name=nfs_grpid value=1 %s> No</td>\n",
669                 defined($options{"grpid"}) ? "checked" : "";
670
671         print "<td><b>Return error on timeouts?</b></td>\n";
672         printf "<td nowrap><input type=radio name=nfs_soft value=1 %s> Yes\n",
673                 defined($options{"soft"}) ? "checked" : "";
674         printf "<input type=radio name=nfs_soft value=0 %s> No</td> </tr>\n",
675                 defined($options{"soft"}) ? "" : "checked";
676
677         print "<tr> <td><b>Retry mounts in background?</b></td>\n";
678         printf "<td nowrap><input type=radio name=nfs_bg value=1 %s> Yes\n",
679                 defined($options{"bg"}) ? "checked" : "";
680         printf "<input type=radio name=nfs_bg value=0 %s> No</td>\n",
681                 defined($options{"bg"}) ? "" : "checked";
682
683         print "<td><b>Display quotas?</b></td>\n";
684         printf "<td nowrap><input type=radio name=nfs_quota value=1 %s> Yes\n",
685                 defined($options{"quota"}) ? "checked" : "";
686         printf "<input type=radio name=nfs_quota value=0 %s> No</td> </tr>\n",
687                 defined($options{"quota"}) ? "" : "checked";
688
689         print "<tr> <td><b>Allow user interrupt?</b></td>\n";
690         printf "<td nowrap><input type=radio name=nfs_nointr value=0 %s> Yes\n",
691                 defined($options{"nointr"}) ? "" : "checked";
692         printf "<input type=radio name=nfs_nointr value=1 %s> No</td>\n",
693                 defined($options{"nointr"}) ? "checked" : "";
694
695         print "<td><b>NFS version</b></td>\n";
696         printf "<td nowrap><input type=radio name=nfs_vers_def value=1 %s> Highest\n",
697                 defined($options{"vers"}) ? "" : "checked";
698         printf "<input type=radio name=nfs_vers_def value=0 %s>\n",
699                 defined($options{"vers"}) ? "checked" : "";
700         print "<input size=1 name=nfs_vers value=$options{vers}></td> </tr>\n";
701
702         print "<tr> <td><b>Protocol</b></td>\n";
703         print "<td nowrap><select name=proto>\n";
704         printf "<option value=\"\" %s> Default\n",
705                 defined($options{"proto"}) ? "" : "selected";
706         &open_tempfile(NETCONFIG, "/etc/netconfig");
707         while(<NETCONFIG>) {
708                 if (!/^([A-z0-9\_\-]+)\s/) { next; }
709                 printf "<option value=\"$1\" %s> $1\n",
710                         $options{"proto"} eq $1 ? "selected" : "";
711                 }
712         &close_tempfile(NETCONFIG);
713         print "</select></td>\n";
714
715         print "<td><b>NFS Port</b></td>\n";
716         printf "<td nowrap><input type=radio name=nfs_port_def value=1 %s> Default\n",
717                 defined($options{"port"}) ? "" : "checked";
718         printf "<input type=radio name=nfs_port_def value=0 %s>\n",
719                 defined($options{"port"}) ? "checked" : "";
720         print "<input size=5 name=nfs_port value=$options{port}></td> </tr>\n";
721
722         print "<tr> <td><b>Timeout</b></td>\n";
723         printf "<td nowrap><input type=radio name=nfs_timeo_def value=1 %s> Default\n",
724                 defined($options{"timeo"}) ? "" : "checked";
725         printf "<input type=radio name=nfs_timeo_def value=0 %s>\n",
726                 defined($options{"timeo"}) ? "checked" : "";
727         printf "<input size=5 name=nfs_timeo value=$options{timeo}></td>\n";
728
729         print "<td><b>Number of Retransmissions</b></td>\n";
730         printf "<td nowrap><input type=radio name=nfs_retrans_def value=1 %s> Default\n",
731                 defined($options{"retrans"}) ? "" : "checked";
732         printf "<input type=radio name=nfs_retrans_def value=0 %s>\n",
733                 defined($options{"retrans"}) ? "checked" : "";
734         print "<input size=5 name=nfs_retrans value=$options{retrans}></td> </tr>\n";
735
736         print "<tr> <td><b>Authentication</b></td>\n";
737         $nfs_auth = $options{'sec'} ? $options{'sec'} :
738                     defined($options{"secure"}) ? "dh" :
739                     defined($options{"kerberos"}) ? "krb" : "";
740         print "<td><select name=nfs_auth>\n";
741         printf "<option value=\"\" %s> None\n",
742                 $nfs_auth eq "" ? "selected" : "";
743         printf "<option value=dh %s> DES\n",
744                 $nfs_auth eq "dh" ? "selected" : "";
745         printf "<option value=krb %s> Kerberos\n",
746                 $nfs_auth eq "krb" ? "selected" : "";
747         print "</select></td>\n";
748
749         if ($gconfig{'os_version'} >= 7) {
750                 print "<td><b>WebNFS mount?</b></td> <td>\n";
751                 printf "<input type=radio name=nfs_public value=1 %s> Yes\n",
752                         defined($options{'public'}) ? "checked" : "";
753                 printf "<input type=radio name=nfs_public value=0 %s> No\n",
754                         defined($options{'public'}) ? "" : "checked";
755                 print "</td>\n";
756                 }
757         print "</tr>\n";
758         }
759 if ($_[0] eq "ufs") {
760         # UnixWare UFS also has many options, not all of which are here
761         print "<tr> <td><b>Read-Only?</b></td>\n";
762         printf "<td nowrap><input type=radio name=ufs_ro value=1 %s> Yes\n",
763                 defined($options{"ro"}) ? "checked" : "";
764         printf "<input type=radio name=ufs_ro value=0 %s> No</td>\n",
765                 defined($options{"ro"}) ? "" : "checked";
766
767         print "<td><b>Disallow setuid programs?</b></td>\n";
768         printf "<td nowrap><input type=radio name=ufs_nosuid value=1 %s> Yes\n",
769                 defined($options{"nosuid"}) ? "checked" : "";
770         printf "<input type=radio name=ufs_nosuid value=0 %s> No</td> </tr>\n",
771                 defined($options{"nosuid"}) ? "" : "checked";
772
773         print "<tr> <td><b>Allow user interrupt?</b></td>\n";
774         printf "<td nowrap><input type=radio name=ufs_nointr value=0 %s> Yes\n",
775                 defined($options{"nointr"}) ? "" : "checked";
776         printf "<input type=radio name=ufs_nointr value=1 %s> No</td>\n",
777                 defined($options{"nointr"}) ? "checked" : "";
778
779         print "<td><b>Enable quotas at boot time?</b></td>\n";
780         printf "<td nowrap><input type=radio name=ufs_quota value=1 %s> Yes\n",
781                 defined($options{"quota"}) || defined($options{"rq"}) ?
782                         "checked" : "";
783         printf "<input type=radio name=ufs_quota value=0 %s> No</td> </tr>\n",
784                 defined($options{"quota"}) || defined($options{"rq"}) ?
785                         "" : "checked";
786
787         print "<tr> <td><b>Action on error</b></td>\n";
788         print "<td><select name=ufs_onerror>\n";
789         foreach ('panic', 'lock', 'umount', 'repair') {
790                 printf "<option value=\"$_\" %s> $_\n",
791                  $options{onerror} eq $_ ||
792                  !defined($options{onerror}) && $_ eq "panic" ? "selected" : "";
793                 }
794         print "</select></td>\n";
795
796         print "<td><b>Repair Delay</b></td>\n";
797         $options{toosoon} =~ /([0-9]+)([A-z])/;
798         print "<td nowrap><input size=5 name=ufs_toosoon_time value=$1>\n";
799         print "<select name=ufs_toosoon_units>\n";
800         printf "<option value=s %s> Seconds\n", $2 eq "s" ? "selected" : "";
801         printf "<option value=m %s> Minutes\n", $2 eq "m" ? "selected" : "";
802         printf "<option value=h %s> Hours\n", $2 eq "h" ? "selected" : "";
803         printf "<option value=d %s> Days\n", $2 eq "d" ? "selected" : "";
804         printf "<option value=w %s> Months\n", $2 eq "w" ? "selected" : "";
805         printf "<option value=y %s> Years\n", $2 eq "y" ? "selected" : "";
806         print "</select></td> </tr>\n";
807
808         if ($gconfig{'os_version'} >= 7) {
809                 print "<tr> <td><b>Update access times?</b></td> <td>\n";
810                 printf "<input type=radio name=ufs_noatime value=0 %s> Yes\n",
811                         defined($options{'noatime'}) ? "" : "checked";
812                 printf "<input type=radio name=ufs_noatime value=1 %s> No\n",
813                         defined($options{'noatime'}) ? "checked" : "";
814                 print "</td>\n";
815
816                 print "<td><b>Force direct IO?</b></td> <td>\n";
817                 printf "<input type=radio name=ufs_force value=1 %s> Yes\n",
818                         defined($options{'forcedirectio'}) ? "checked" : "";
819                 printf "<input type=radio name=ufs_force value=0 %s> No\n",
820                         defined($options{'forcedirectio'}) ? "" : "checked";
821                 print "</td> </tr>\n";
822
823                 print "<tr> <td><b>Allow large files?</td> <td>\n";
824                 printf "<input type=radio name=ufs_nolarge value=0 %s> Yes\n",
825                         defined($options{'nolargefiles'}) ? "" : "checked";
826                 printf "<input type=radio name=ufs_nolarge value=1 %s> No\n",
827                         defined($options{'nolargefiles'}) ? "checked" : "";
828                 print "</td>\n";
829
830                 print "<td><b>Enabled logging?</td> <td>\n";
831                 printf "<input type=radio name=ufs_logging value=1 %s> Yes\n",
832                         defined($options{'logging'}) ? "checked" : "";
833                 printf "<input type=radio name=ufs_logging value=0 %s> No\n",
834                         defined($options{'logging'}) ? "" : "checked";
835                 print "</td> </tr>\n";
836                 }
837         }
838 if ($_[0] eq "hsfs") {
839         # UnixWare hsfs is used for CDROMs
840         print "<tr> <td><b>Ignore Unix attributes?</b></td>\n";
841         printf "<td nowrap><input type=radio name=hsfs_nrr value=1 %s> Yes\n",
842                 defined($options{"nrr"}) ? "checked" : "";
843         printf "<input type=radio name=hsfs_nrr value=0 %s> No</td>\n",
844                 defined($options{"nrr"}) ? "" : "checked";
845
846         print "<td><b>Ignore trailing dot?</b></td>\n";
847         printf "<td nowrap><input type=radio name=hsfs_notraildot value=1 %s> Yes\n",
848                 defined($options{"notraildot"}) ? "checked" : "";
849         printf "<input type=radio name=hsfs_notraildot value=0 %s> No</td> </tr>\n",
850                 defined($options{"notraildot"}) ? "" : "checked";
851
852         print "<tr> <td><b>Use lower case?</b></td>\n";
853         printf "<td nowrap><input type=radio name=hsfs_nomaplcase value=0 %s> Yes\n",
854                 defined($options{"nomaplcase"}) ? "" : "checked";
855         printf "<input type=radio name=hsfs_nomaplcase value=1 %s> No</td>\n",
856                 defined($options{"nomaplcase"}) ? "checked" : "";
857
858         print "<td><b>Disallow setuid programs?</b></td>\n";
859         printf"<td nowrap><input type=radio name=hsfs_nosuid value=1 %s> Yes\n",
860                 defined($options{"nosuid"}) ? "checked" : "";
861         printf "<input type=radio name=hsfs_nosuid value=0 %s> No</td> </tr>\n",
862                 defined($options{"nosuid"}) ? "" : "checked";
863         }
864 if ($_[0] eq "pcfs") {
865         # UnixWare pcfs for for FAT filesystems. It doesn't have many options
866         print "<tr> <td width=25%><b>Read Only?</b></td> <td width=25%>\n";
867         printf "<input type=radio name=pcfs_ro value=1 %s> Yes\n",
868                 defined($options{"ro"}) ? "checked" : "";
869         printf "<input type=radio name=pcfs_ro value=0 %s> No</td>\n",
870                 defined($options{"ro"}) ? "" : "checked";
871
872         if ($gconfig{'os_version'} >= 7) {
873                 print "<td><b>Force lower case?</b></td> <td>\n";
874                 printf "<input type=radio name=pcfs_foldcase value=1 %s> Yes\n",
875                         defined($options{'foldcase'}) ? "checked" : "";
876                 printf "<input type=radio name=pcfs_foldcase value=0 %s> No\n",
877                         defined($options{'foldcase'}) ? "" : "checked";
878                 print "</td>\n";
879                 }
880         else {
881                 print "<td colspan=2></td> </tr>\n";
882                 }
883         }
884 if ($_[0] eq "vxfs") {
885         print "<tr> <td><b>Read-Only?</b></td>\n";
886         printf "<td nowrap><input type=radio name=jfs_ro value=1 %s> Yes\n",
887                 defined($options{"ro"}) ? "checked" : "";
888         printf "<input type=radio name=jfs_ro value=0 %s> No</td>\n",
889                 defined($options{"ro"}) ? "" : "checked";
890
891         print "<td><b>Disallow setuid programs?</b></td>\n";
892         printf "<td nowrap><input type=radio name=jfs_nosuid value=1 %s> Yes\n",
893                 defined($options{"nosuid"}) ? "checked" : "";
894         printf "<input type=radio name=jfs_nosuid value=0 %s> No</td> </tr>\n",
895                 defined($options{"nosuid"}) ? "" : "checked";
896
897         print "<tr> <td><b>Full integrity for all Metadata?</b></td>\n";
898         printf "<td nowrap><input type=radio name=jfs_log value=1 %s> Yes\n",
899                 defined($options{"log"}) ? "checked" : "";
900         printf "<input type=radio name=jfs_log value=0 %s> No</td>\n",
901                 defined($options{"log"}) ? "" : "checked";
902
903         print "<td><b>Synchronous-write data logging?</b></td>\n";
904         printf "<td nowrap><input type=radio name=jfs_syncw value=1 %s> Yes\n",
905                 !defined($options{"nodatainlog"}) ? "checked" : "";
906         printf "<input type=radio name=jfs_syncw value=0 %s> No</td> </tr>\n",
907                 !defined($options{"nodatainlog"}) ? "" : "checked";
908
909         print "<tr> <td><b>Enable quotas at boot time?</b></td>\n";
910         printf "<td nowrap><input type=radio name=jfs_quota value=1 %s> Yes\n",
911                 defined($options{"quota"}) ? "checked" : "";
912         printf "<input type=radio name=jfs_quota value=0 %s> No</td> </tr>\n",
913                 defined($options{"quota"}) ? "" : "checked";
914         }
915 if ($_[0] eq "lofs") {
916         # No options as far as I know
917         print "<tr> <td><i>No Options Available</i></td> </tr>\n";
918         }
919 if ($_[0] eq "tmpfs") {
920         # UnixWare tmpfs (virtual memory) filesystem.
921         print "<tr> <td><b>Size</b>&nbsp;&nbsp;&nbsp;</td>\n";
922         printf"<td><input type=radio name=tmpfs_size_def value=1 %s> Maximum\n",
923                 defined($options{"size"}) ? "" : "checked";
924         printf"&nbsp;&nbsp;<input type=radio name=tmpfs_size_def value=0 %s>\n",
925                 defined($options{"size"}) ? "checked" : "";
926         ($tmpsz = $options{size}) =~ s/[A-z]+$//g;
927         print "<input name=tmpfs_size size=6 value=\"$tmpsz\">\n";
928         print "<select name=tmpfs_unit>\n";
929         printf "<option value=m %s> MB\n",
930                 $options{"size"} =~ /m$/ ? "selected" : "";
931         printf "<option value=k %s> kB\n",
932                 $options{"size"} =~ /k$/ ? "selected" : "";
933         printf "<option value=b %s> bytes\n",
934                 $options{"size"} !~ /(k|m)$/ ? "selected" : "";
935         print "</select></td>\n";
936
937         print "<td><b>Disallow setuid programs?</b></td> <td nowrap>\n";
938         printf "<input type=radio name=tmpfs_nosuid value=1 %s> Yes\n",
939                 defined($options{"nosuid"}) ? "checked" : "";
940         printf "<input type=radio name=tmpfs_nosuid value=0 %s> No</td>\n",
941                 defined($options{"nosuid"}) ? "" : "checked";
942         print "</tr>\n";
943         }
944 if ($_[0] eq "swap") {
945         # UnixWare swap has no options
946         print "<tr> <td><i>No Options Available</i></td> </tr>\n";
947         }
948 if ($_[0] eq "cachefs") {
949         # The caching filesystem has lots of options.. cachefs mounts can
950         # be of an existing 'manually' mounted back filesystem, or of a
951         # back-filesystem that has been automatically mounted by the cache.
952         # The user should never see the automatic mountings made by cachefs.
953         print "<tr> <td><b>Real filesystem type</b></td>\n";
954         print "<td nowrap><select name=cfs_backfstype>\n";
955         if (!defined($options{backfstype})) { $options{backfstype} = "nfs"; }
956         foreach (&list_fstypes()) {
957                 if ($_ eq "cachefs") { next; }
958                 printf "<option value=\"$_\" %s>$_\n",
959                         $_ eq $options{backfstype} ? "selected" : "";
960                 }
961         print "</select></td>\n";
962
963         print "<td><b>Real mount point</b></td>\n";
964         printf"<td nowrap><input type=radio name=cfs_noback value=1 %s> Automatic\n",
965                 defined($options{"backpath"}) ? "" : "checked";
966         printf "<input type=radio name=cfs_noback value=0 %s>\n",
967                 defined($options{"backpath"}) ? "checked" : "";
968         print "<input size=10 name=cfs_backpath value=\"$options{backpath}\"></td> </tr>\n";
969
970         print "<tr> <td><b>Cache directory</b></td>\n";
971         printf "<td nowrap><input size=10 name=cfs_cachedir value=\"%s\"></td>\n",
972                 defined($options{"cachedir"}) ? $options{"cachedir"} : "/cache";
973
974         print "<td><b>Write mode</b></td>\n";
975         printf"<td nowrap><input type=radio name=cfs_wmode value=0 %s> Write-around\n",
976                 defined($options{"non-shared"}) ? "" : "checked";
977         printf "<input type=radio name=cfs_wmode value=1 %s> Non-shared\n",
978                 defined($options{"non-shared"}) ? "checked" : "";
979         print "</td> </tr>\n";
980
981         print "<tr> <td><b>Consistency check</b></td>\n";
982         print "<td><select name=cfs_con>\n";
983         print "<option value=1> Periodically\n";
984         printf "<option value=0 %s> Never\n",
985                 defined($options{"noconst"}) ? "selected" : "";
986         printf "<option value=2 %s> On demand\n",
987                 defined($options{"demandconst"}) ? "selected" : "";
988         print "</select></td>\n";
989
990         print "<td><b>Check permissions in cache?</b></td>\n";
991         printf "<td nowrap><input type=radio name=cfs_local value=1 %s> Yes\n",
992                 defined($options{"local-access"}) ? "checked" : "";
993         printf "<input type=radio name=cfs_local value=0 %s> No</td> </tr>\n",
994                 defined($options{"local-access"}) ? "" : "checked";
995
996         print "<tr> <td><b>Read-Only?</b></td>\n";
997         printf "<td nowrap><input type=radio name=cfs_ro value=1 %s> Yes\n",
998                 defined($options{"ro"}) ? "checked" : "";
999         printf "<input type=radio name=cfs_ro value=0 %s> No</td>\n",
1000                 defined($options{"ro"}) ? "" : "checked";
1001
1002         print "<td><b>Disallow setuid programs?</b></td>\n";
1003         printf "<td nowrap><input type=radio name=cfs_nosuid value=1 %s> Yes\n",
1004                 defined($options{"nosuid"}) ? "checked" : "";
1005         printf "<input type=radio name=cfs_nosuid value=0 %s> No</td> </tr>\n",
1006                 defined($options{"nosuid"}) ? "" : "checked";
1007         }
1008 if ($_[0] eq "autofs") {
1009         # Autofs has lots of options, depending on the type of file
1010         # system being automounted.. the fstype options determines this
1011         local($fstype);
1012         $fstype = $options{fstype} eq "" ? "nfs" : $options{fstype};
1013         if ($gconfig{'os_version'} >= 2.6) {
1014                 print "<tr> <td><b>Browsing enabled?</b></td> <td>\n";
1015                 printf "<input type=radio name=auto_nobrowse value=0 %s> Yes\n",
1016                         defined($options{'nobrowse'}) ? "" : "checked";
1017                 printf "<input type=radio name=auto_nobrowse value=1 %s> No\n",
1018                         defined($options{'nobrowse'}) ? "checked" : "";
1019                 print "</td> <td colspan=2></td> </tr>\n";
1020                 }
1021         &generate_options($fstype);
1022         print "<input type=hidden name=autofs_fstype value=\"$fstype\">\n";
1023         }
1024 if ($_[0] eq "rumba") {
1025         # SMB filesystems have a few options..
1026         print "<tr> <td><b>Server Hostname</b></td>\n";
1027         printf "<td><input type=radio name=rumba_mname_def value=1 %s> Automatic\n",
1028                 defined($options{"machinename"}) ? "" : "checked";
1029         printf "<input type=radio name=rumba_mname_def value=0 %s>\n",
1030                 defined($options{"machinename"}) ? "checked" : "";
1031         print "<input size=10 name=rumba_mname value=\"$options{machinename}\"></td>\n";
1032
1033         print "<td><b>Client Name</b></td>\n";
1034         printf "<td><input type=radio name=rumba_cname_def value=1 %s> Automatic\n",
1035                 defined($options{"clientname"}) ? "" : "checked";
1036         printf "<input type=radio name=rumba_cname_def value=0 %s>\n",
1037                 defined($options{"clientname"}) ? "checked" : "";
1038         print "<input size=10 name=rumba_cname value=\"$options{clientname}\"></td> </tr>\n";
1039
1040         print "<tr> <td><b>Login Name</b></td>\n";
1041         print "<td><input name=rumba_username size=15 value=\"$options{username}\"></td>\n";
1042
1043         print "<td><b>Login Password</b></td>\n";
1044         print "<td><input type=password name=rumba_password size=15 value=\"$options{password}\"></td> </tr>\n";
1045
1046         print "<tr> <td><b>User files are owned by</b></td>\n";
1047         printf "<td><input name=rumba_uid size=8 value=\"%s\">\n",
1048                 defined($options{'uid'}) ? getpwuid($options{'uid'}) : "";
1049         print &user_chooser_button("rumba_uid", 0),"</td>\n";
1050
1051         print "<td><b>Group files are owned by</b></td>\n";
1052         printf "<td><input name=rumba_gid size=8 value=\"%s\">\n",
1053                 defined($options{'gid'}) ? getgrgid($options{'gid'}) : "";
1054         print &group_chooser_button("rumba_gid", 0),"</td>\n";
1055
1056         print "<tr> <td><b>File permissions</b></td>\n";
1057         printf "<td><input name=rumba_fmode size=5 value=\"%s\"></td>\n",
1058                 defined($options{fmode}) ? $options{fmode} : "755";
1059
1060         print "<td><b>Directory permissions</b></td>\n";
1061         printf "<td><input name=rumba_dmode size=5 value=\"%s\"></td> </tr>\n",
1062                 defined($options{dmode}) ? $options{dmode} : "755";
1063
1064         print "<tr> <td><b>Read/write access is safe?</b></td>\n";
1065         printf"<td nowrap><input type=radio name=rumba_readwrite value=1 %s> Yes\n",
1066                 defined($options{"readwrite"}) ? "checked" : "";
1067         printf "<input type=radio name=rumba_readwrite value=0 %s> No</td>\n",
1068                 defined($options{"readwrite"}) ? "" : "checked";
1069
1070         print "<td><b>Files can be read-only?</b></td>\n";
1071         printf"<td nowrap><input type=radio name=rumba_readonly value=1 %s> Yes\n",
1072                 defined($options{"readonly"}) ? "checked" : "";
1073         printf "<input type=radio name=rumba_readonly value=0 %s> No</td> </tr>\n",
1074                 defined($options{"readonly"}) ? "" : "checked";
1075
1076         print "<tr> <td><b>Send password in upper case?</b></td>\n";
1077         printf"<td nowrap><input type=radio name=rumba_noupper value=0 %s> Yes\n",
1078                 defined($options{"noupper"}) ? "" : "checked";
1079         printf "<input type=radio name=rumba_noupper value=1 %s> No</td>\n",
1080                 defined($options{"noupper"}) ? "checked" : "";
1081
1082         print "<td><b>Use attrE commands?</b></td>\n";
1083         printf"<td nowrap><input type=radio name=rumba_attr value=1 %s> Yes\n",
1084                 defined($options{"attr"}) ? "checked" : "";
1085         printf "<input type=radio name=rumba_attr value=0 %s> No</td> </tr>\n",
1086                 defined($options{"attr"}) ? "" : "checked";
1087         }
1088 }
1089
1090
1091 # check_location(type)
1092 # Parse and check inputs from %in, calling &error() if something is wrong.
1093 # Returns the location string for storing in the fstab file
1094 sub check_location
1095 {
1096 if ($_[0] eq "nfs") {
1097         local($out, $temp, $mout, $dirlist);
1098
1099         if ($in{'nfs_serv'} == 1) {
1100                 # multiple servers listed.. assume the user has a brain
1101                 return $in{'nfs_list'};
1102                 }
1103         elsif ($in{'nfs_serv'} == 2) {
1104                 # NFS url.. check syntax
1105                 if ($in{'nfs_url'} !~ /^nfs:\/\/([^\/ ]+)(\/([^\/ ]*))?$/) {
1106                         &error("'$in{'nfs_url'}' is not a valid NFS URL");
1107                         }
1108                 return $in{'nfs_url'};
1109                 }
1110
1111         # Use dfshares to see if the host exists and is up
1112         if ($in{nfs_host} !~ /^\S+$/) {
1113                 &error("'$in{nfs_host}' is not a valid hostname");
1114                 }
1115         $out = &backquote_command("dfshares '$in{nfs_host}' 2>&1");
1116         if ($out =~ /Unknown host/) {
1117                 &error("The host '$in{nfs_host}' does not exist");
1118                 }
1119         elsif ($out =~ /Timed out/) {
1120                 &error("The host '$in{nfs_host}' is down or does not ".
1121                        "support NFS");
1122                 }
1123         elsif ($out =~ /Program not registered/) {
1124                 &error("The host '$in{nfs_host}' does not support NFS");
1125                 }
1126
1127         # Try a test mount to see if filesystem is available
1128         foreach (split(/\n/, $out)) {
1129                 if (/^\s*([^ :]+):(\/\S+)\s+/) { $dirlist .= "$2\n"; }
1130                 }
1131         if ($in{nfs_dir} !~ /^\S+$/) {
1132                 &error("'$in{nfs_dir}' is not a valid directory name. The ".
1133                        "available directories on $in{nfs_host} are:".
1134                        "<pre>$dirlist</pre>");
1135                 }
1136         $temp = &transname();
1137         &make_dir($temp, 0755);
1138         $mout = &backquote_command("mount $in{nfs_host}:$in{nfs_dir} $temp 2>&1");
1139         if ($mout =~ /No such file or directory/) {
1140                 rmdir($temp);
1141                 &error("The directory '$in{nfs_dir}' does not exist on the ".
1142                        "host $in{nfs_host}. The available directories are:".
1143                        "<pre>$dirlist</pre>");
1144                 }
1145         elsif ($mout =~ /Permission denied/) {
1146                 rmdir($temp);
1147                 &error("This host is not allowed to mount the directory ".
1148                        "$in{nfs_dir} from $in{nfs_host}");
1149                 }
1150         elsif ($?) {
1151                 rmdir($temp);
1152                 &error("NFS Error - $mout");
1153                 }
1154         # It worked! unmount
1155         &execute_command("umount $temp");
1156         &unlink_file($temp);
1157         return "$in{nfs_host}:$in{nfs_dir}";
1158         }
1159 elsif ($_[0] eq "ufs") {
1160         # Get the device name
1161         if ($in{ufs_dev} == 0) {
1162                 $in{ufs_c} =~ /^[0-9]+$/ ||
1163                         &error("'$in{ufs_c}' is not a valid SCSI controller");
1164                 $in{ufs_t} =~ /^[0-9]+$/ ||
1165                         &error("'$in{ufs_t}' is not a valid SCSI target");
1166                 $in{ufs_d} =~ /^[0-9]+$/ ||
1167                         &error("'$in{ufs_d}' is not a valid SCSI unit");
1168                 $in{ufs_s} =~ /^[0-9]+$/ ||
1169                         &error("'$in{ufs_s}' is not a valid SCSI partition");
1170                 $dv = "/dev/dsk/c$in{ufs_c}t$in{ufs_t}d$in{ufs_d}s$in{ufs_s}";
1171                 }
1172         elsif ($in{ufs_dev} == 1) {
1173                 $in{ufs_md} =~ /^[0-9]+$/ ||
1174                         &error("'$in{ufs_md}' is not a valid RAID unit");
1175                 $dv = "/dev/md/dsk/d$in{ufs_md}";
1176                 }
1177         else {
1178                 $in{ufs_path} =~ /^\/\S+$/ ||
1179                         &error("'$in{ufs_path}' is not a valid pathname");
1180                 $dv = $in{ufs_path};
1181                 }
1182
1183         &fstyp_check($dv, "ufs");
1184         return $dv;
1185         }
1186 elsif ($_[0] eq "vxfs") {
1187         # Get the device name
1188         if ($in{jfs_dev} == 0) {
1189                 $in{jfs_c} =~ /^[0-9]+$/ ||
1190                         &error("'$in{jfs_c}' is not a valid SCSI controller");
1191                 $in{jfs_t} =~ /^[0-9]+$/ ||
1192                         &error("'$in{jfs_t}' is not a valid SCSI target");
1193                 $in{jfs_d} =~ /^[0-9]+$/ ||
1194                         &error("'$in{jfs_d}' is not a valid SCSI unit");
1195                 $in{jfs_s} =~ /^[0-9]+$/ ||
1196                         &error("'$in{jfs_s}' is not a valid SCSI partition");
1197                 $dv = "/dev/dsk/c$in{jfs_c}t$in{jfs_t}d$in{jfs_d}s$in{jfs_s}";
1198                 }
1199         elsif ($in{jfs_dev} == 1) {
1200                 $in{jfs_vg} =~ /^[0-9]+$/ ||
1201                         &error("'$in{jfs_vg}' is not a valid Volume Group");
1202                 $in{jfs_lv} =~ /^\S+$/ ||
1203                         &error("'$in{jfs_lv}' is not a valid Logical Volume");
1204                 $dv = "/dev/vg$in{jfs_vg}/$in{jfs_lv}";
1205                 }
1206         else {
1207                 $in{jfs_path} =~ /^\/\S+$/ ||
1208                         &error("'$in{jfs_path}' is not a valid pathname");
1209                 $dv = $in{jfs_path};
1210                 }
1211
1212         &fstyp_check($dv, "vxfs");
1213         return $dv;
1214         }
1215 elsif ($_[0] eq "lofs") {
1216         # Get and check the original directory
1217         $dv = $in{'lofs_src'};
1218         if (!(-r $dv)) { &error("'$in{lofs_src}' does not exist"); }
1219         if (!(-d $dv)) { &error("'$in{lofs_src}' is not a directory"); }
1220         return $dv;
1221         }
1222 elsif ($_[0] eq "swap") {
1223         if ($in{swap_dev} == 0) {
1224                 $in{swap_c} =~ /^[0-9]+$/ ||
1225                         &error("'$in{swap_c}' is not a valid SCSI controller");
1226                 $in{swap_t} =~ /^[0-9]+$/ ||
1227                         &error("'$in{swap_t}' is not a valid SCSI target");
1228                 $in{swap_d} =~ /^[0-9]+$/ ||
1229                         &error("'$in{swap_d}' is not a valid SCSI unit");
1230                 $in{swap_s} =~ /^[0-9]+$/ ||
1231                         &error("'$in{swap_s}' is not a valid SCSI partition");
1232                 $dv="/dev/dsk/c$in{swap_c}t$in{swap_t}d$in{swap_d}s$in{swap_s}";
1233                 }
1234         else { $dv = $in{swap_path}; }
1235
1236         if (!open(SWAPFILE, $dv)) {
1237                 if ($! =~ /No such file/ && $in{swap_dev}) {
1238                         if ($dv !~ /^\/dev/) {
1239                                 &swap_form($dv);
1240                                 }
1241                         else {
1242                                 &error("The swap file '$dv' does not exist");
1243                                 }
1244                         }
1245                 elsif ($! =~ /No such file/) {
1246                         &error("The SCSI target '$in{swap_t}' does not exist");
1247                         }
1248                 elsif ($! =~ /No such device or address/) {
1249                         &error("The partition '$in{swap_s}' does not exist");
1250                         }
1251                 else {
1252                         &error("Failed to open '$dv' : $!");
1253                         }
1254                 }
1255         close(SWAPFILE);
1256         return $dv;
1257         }
1258 elsif ($_[0] eq "tmpfs") {
1259         # Ram-disk filesystems have no location
1260         return "swap";
1261         }
1262 elsif ($_[0] eq "cachefs") {
1263         # In order to check the location for the caching filesystem, we need
1264         # to check the back filesystem
1265         if (!$in{cfs_noback}) {
1266                 # The back filesystem is manually mounted.. hopefully
1267                 local($bidx, @mlist, @binfo);
1268                 $bidx = &get_mounted($in{cfs_backpath}, "*");
1269                 if ($bidx < 0) {
1270                         &error("The back filesystem '$in{cfs_backpath}' is ".
1271                                "not mounted");
1272                         }
1273                 @mlist = &list_mounted();
1274                 @binfo = @{$mlist[$bidx]};
1275                 if ($binfo[2] ne $in{cfs_backfstype}) {
1276                         &error("The back filesystem is '$binfo[2]', not ".
1277                                "'$in{cfs_backfstype}'");
1278                         }
1279                 }
1280         else {
1281                 # Need to automatically mount the back filesystem.. check
1282                 # it for sanity first.
1283                 # But HOW?
1284                 $in{cfs_src} =~ /^\S+$/ ||
1285                         &error("'$in{cfs_src}' is not a valid cache source");
1286                 }
1287         return $in{cfs_src};
1288         }
1289 elsif ($_[0] eq "autofs") {
1290         # An autofs filesystem can be either mounted from the special
1291         # -hosts and -xfn maps, or from a normal map. The map can be a file
1292         # name (if it starts with /), or an NIS map (if it doesn't)
1293         if ($in{autofs_type} == 0) {
1294                 # Normal map
1295                 $in{autofs_map} =~ /\S/ ||
1296                         &error("You did not enter an automount map name");
1297                 if ($in{autofs_map} =~ /^\// && !(-r $in{autofs_map})) {
1298                         &error("The map file '$in{autofs_map}' does not exist");
1299                         }
1300                 return $in{autofs_map};
1301                 }
1302         elsif ($in{autofs_type} == 1) {
1303                 # Special hosts map (automount all shares from some host)
1304                 return "-hosts";
1305                 }
1306         else {
1307                 # Special FNS map (not sure what this does)
1308                 return "-xfn";
1309                 }
1310         }
1311 elsif ($_[0] eq "rumba") {
1312         # Cannot check much here..
1313         return "\\\\$in{rumba_server}\\$in{rumba_share}";
1314         }
1315 }
1316
1317
1318 # fstyp_check(device, type)
1319 # Check if some device exists, and contains a filesystem of the given type,
1320 # using the fstyp command.
1321 sub fstyp_check
1322 {
1323 local($out, $part, $found);
1324
1325 # Check if the device/partition actually exists
1326 if ($_[0] =~ /^\/dev\/dsk\/c(.)t(.)d(.)s(.)$/) {
1327         # mounting a normal scsi device..
1328         $out = &backquote_command("prtvtoc -h $_[0] 2>&1");
1329         if ($out =~ /No such file or directory|No such device or address/) {
1330                 &error("The SCSI target for '$_[0]' does not exist");
1331                 }
1332         $part = $4;
1333         foreach (split(/\n/, $out)) {
1334                 /^\s+([0-9]+)\s+([0-9]+)/;
1335                 if ($1 == $part) {
1336                         $found = 1; last;
1337                         }
1338                 }
1339         if (!$found) {
1340                 &error("The SCSI partition for '$_[0]' does not exist");
1341                 }
1342         }
1343 elsif ($_[0] =~ /^\/dev\/md\/dsk\/d(.)$/) {
1344         # mounting a multi-disk (raid) device..
1345         $out = &backquote_command("prtvtoc -h $_[0] 2>&1");
1346         if ($out =~ /No such file or directory|No such device or address/) {
1347                 &error("The RAID device for '$_[0]' does not exist");
1348                 }
1349         if ($out !~ /\S/) {
1350                 &error("No partitions on '$_[0]' ??");
1351                 }
1352         }
1353 else {
1354         # Some other device
1355         if (!open(DEV, $_[0])) {
1356                 if ($! =~ /No such file or directory/) {
1357                         &error("The device file '$_[0]' does not exist");
1358                         }
1359                 elsif ($! =~ /No such device or address/) {
1360                         &error("The device for '$_[0]' does not exist");
1361                         }
1362                 }
1363         close(DEV);
1364         }
1365
1366 # Check the filesystem type
1367 $out = &backquote_command("fstyp $_[0] 2>&1");
1368 if ($out =~ /^([A-z0-9]+)\n$/) {
1369         if ($1 eq $_[1]) { return; }
1370         else {
1371                 # Wrong filesystem type
1372                 &error("The device '$_[0]' is formatted as a ".
1373                        &fstype_name($1));
1374                 }
1375         }
1376 else {
1377         &error("Failed to check filesystem type : $out");
1378         }
1379 }
1380
1381
1382 # check_options(type)
1383 # Read options for some filesystem from %in, and use them to update the
1384 # %options array. Options handled by the user interface will be set or
1385 # removed, while unknown options will be left untouched.
1386 sub check_options
1387 {
1388 local($k, @rv);
1389 if ($_[0] eq "nfs") {
1390         # NFS has lots of options to parse
1391         if ($in{'nfs_ro'}) {
1392                 # Read-only
1393                 $options{"ro"} = ""; delete($options{"rw"});
1394                 }
1395         else {
1396                 # Read-write
1397                 $options{"rw"} = ""; delete($options{"ro"});
1398                 }
1399
1400         delete($options{'quota'}); delete($options{'noquota'});
1401         if ($in{'nfs_quota'}) { $options{'quota'} = ""; }
1402
1403         delete($options{"nosuid"}); delete($options{"suid"});
1404         if ($in{nfs_nosuid}) { $options{"nosuid"} = ""; }
1405
1406         delete($options{"grpid"});
1407         if ($in{nfs_grpid}) { $options{"grpid"} = ""; }
1408
1409         delete($options{"soft"}); delete($options{"hard"});
1410         if ($in{nfs_soft}) { $options{"soft"} = ""; }
1411
1412         delete($options{"bg"}); delete($options{"fg"});
1413         if ($in{nfs_bg}) { $options{"bg"} = ""; }
1414
1415         delete($options{"intr"}); delete($options{"nointr"});
1416         if ($in{nfs_nointr}) { $options{"nointr"} = ""; }
1417
1418         delete($options{"vers"});
1419         if (!$in{nfs_vers_def}) { $options{"vers"} = $in{nfs_vers}; }
1420
1421         delete($options{"proto"});
1422         if ($in{nfs_proto} ne "") { $options{"proto"} = $in{nfs_proto}; }
1423
1424         delete($options{"port"});
1425         if (!$in{nfs_port_def}) { $options{"port"} = $in{nfs_port}; }
1426
1427         delete($options{"timeo"});
1428         if (!$in{nfs_timeo_def}) { $options{"timeo"} = $in{nfs_timeo}; }
1429
1430         delete($options{"secure"}); delete($options{"kerberos"});
1431         delete($options{"sec"});
1432         if ($gconfig{'os_version'} >= 2.6) {
1433                 if ($in{'nfs_auth'}) { $options{'sec'} = $in{'nfs_auth'}; }
1434                 }
1435         else {
1436                 if ($in{'nfs_auth'} eq "dh") { $options{"secure"} = ""; }
1437                 elsif ($in{'nfs_auth'} eq "krb") { $options{"kerberos"} = ""; }
1438                 }
1439
1440         if ($gconfig{'os_version'} >= 7) {
1441                 delete($options{'public'});
1442                 $options{'public'} = "" if ($in{'nfs_public'});
1443                 }
1444         }
1445 elsif ($_[0] eq "ufs") {
1446         # UFS also has lots of options..
1447         if ($in{ufs_ro}) {
1448                 # read-only (and thus no quota)
1449                 $options{"ro"} = ""; delete($options{"rw"});
1450                 delete($options{"rq"}); delete($options{"quota"});
1451                 }
1452         elsif ($in{ufs_quota}) {
1453                 # read-write, with quota
1454                 delete($options{"ro"}); $options{"rw"} = "";
1455                 $options{"quota"} = "";
1456                 }
1457         else {
1458                 # read-write, without quota
1459                 delete($options{"ro"}); $options{"rw"} = "";
1460                 delete($options{"quota"});
1461                 }
1462
1463         delete($options{"nosuid"});
1464         if ($in{ufs_nosuid}) { $options{"nosuid"} = ""; }
1465
1466         delete($options{"intr"}); delete($options{"nointr"});
1467         if ($in{ufs_nointr}) { $options{"nointr"} = ""; }
1468
1469         delete($options{"onerror"});
1470         if ($in{ufs_onerror} ne "panic") {
1471                 $options{"onerror"} = $in{ufs_onerror};
1472                 }
1473
1474         delete($options{"toosoon"});
1475         if ($in{ufs_toosoon_time}) {
1476                 $options{"toosoon"} = $in{ufs_toosoon_time}.
1477                                       $in{ufs_toosoon_units};
1478                 }
1479         if ($gconfig{'os_version'} >= 7) {
1480                 delete($options{'noatime'});
1481                 $options{'noatime'} = "" if ($in{'ufs_noatime'});
1482
1483                 delete($options{'forcedirectio'});
1484                 delete($options{'noforcedirectio'});
1485                 $options{'forcedirectio'} = "" if ($in{'ufs_force'});
1486
1487                 delete($options{'nolargefiles'});delete($options{'largefiles'});
1488                 $options{'nolargefiles'} = "" if ($in{'ufs_nolarge'});
1489
1490                 delete($options{'logging'}); delete($options{'nologging'});
1491                 $options{'logging'} = "" if ($in{'ufs_logging'});
1492                 }
1493         }
1494 elsif ($_[0] eq "vxfs") {
1495         if ($in{jfs_ro}) {
1496                 # read-only
1497                 $options{"ro"} = ""; delete($options{"rw"});
1498                 }
1499         else {
1500                 # read-write
1501                 $options{"rw"} = ""; delete($options{"ro"});
1502                 }
1503         if ($in{jfs_nosuid}) {
1504                 # nosuid
1505                 $options{"nosuid"} = ""; delete($options{"suid"});
1506                 }
1507         else {
1508                 # suid
1509                 $options{"suid"} = ""; delete($options{"nosuid"});
1510                 }
1511         if ($in{jfs_log}) {
1512                 # log
1513                 $options{"log"} = ""; delete($options{"delaylog"});
1514                 }
1515         else {
1516                 # delaylog
1517                 $options{"delaylog"} = ""; delete($options{"log"});
1518                 }
1519         if ($in{jfs_syncw}) {
1520                 # datainlog
1521                 $options{"datainlog"} = ""; delete($options{"nodatainlog"});
1522                 }
1523         else {
1524                 # nodatainlog
1525                 $options{"nodatainlog"} = ""; delete($options{"datainlog"});
1526                 }
1527         if ($in{jfs_quota}) {
1528                 # quota
1529                 $options{"quota"} = "";
1530                 }
1531         else {
1532                 # noquota
1533                 delete($options{"quota"});
1534                 }
1535         }
1536 elsif ($_[0] eq "lofs") {
1537         # Loopback has no options to parse
1538         }
1539 elsif ($_[0] eq "swap") {
1540         # Swap has no options to parse
1541         }
1542 elsif ($_[0] eq "pcfs") {
1543         # PCFS has only 2 options
1544         delete($options{'ro'}); delete($options{'rw'});
1545         $options{'ro'} = "" if ($in{'pcfs_rp'});
1546
1547         delete($options{'foldcase'}); delete($options{'nofoldcase'});
1548         $options{'foldcase'} = "" if ($in{'pcfs_foldcase'});
1549         }
1550 elsif ($_[0] eq "tmpfs") {
1551         # Ram-disk filesystems have only two options
1552         delete($options{"size"});
1553         if (!$in{"tmpfs_size_def"}) {
1554                 $options{"size"} = "$in{tmpfs_size}$in{tmpfs_unit}";
1555                 }
1556
1557         delete($options{"nosuid"});
1558         if ($in{'tmpfs_nosuid'}) { $options{"nosuid"} = ""; }
1559         }
1560 elsif ($_[0] eq "cachefs") {
1561         # The caching filesystem has lots of options
1562         $options{"backfstype"} = $in{"cfs_backfstype"};
1563
1564         delete($options{"backpath"});
1565         if (!$in{"cfs_noback"}) {
1566                 # A back filesystem was given..  (alreadys checked)
1567                 $options{"backpath"} = $in{"cfs_backpath"};
1568                 }
1569
1570         if ($in{"cfs_cachedir"} !~ /^\/\S+/) {
1571                 &error("'$in{cfs_cachedir}' is not a valid cache directory");
1572                 }
1573         $options{"cachedir"} = $in{"cfs_cachedir"};
1574
1575         delete($options{"write-around"}); delete($options{"non-shared"});
1576         if ($in{"cfs_wmode"}) {
1577                 $options{"non-shared"} = "";
1578                 }
1579
1580         delete($options{"noconst"}); delete($options{"demandconst"});
1581         if ($in{"cfs_con"} == 0) { $options{"noconst"} = ""; }
1582         elsif ($in{"cfs_con"} == 2) { $options{"demandconst"} = ""; }
1583
1584         delete($options{"ro"}); delete($options{"rw"});
1585         if ($in{"cfs_ro"}) { $options{"ro"} = ""; }
1586
1587         delete($options{"suid"}); delete($options{"nosuid"});
1588         if ($in{"cfs_nosuid"}) { $options{"nosuid"} = ""; }
1589         }
1590 elsif ($_[0] eq "autofs") {
1591         # The options for autofs depend on the type of the automounted
1592         # filesystem.. 
1593         $options{"fstype"} = $in{"autofs_fstype"};
1594         if ($gconfig{'os_version'} >= 2.6) {
1595                 delete($options{'nobrowse'}); delete($options{'browse'});
1596                 $options{'nobrowse'} = "" if ($in{'auto_nobrowse'});
1597                 }
1598         return &check_options($options{"fstype"});
1599         }
1600 elsif ($_[0] eq "rumba") {
1601         # Options for smb filesystems..
1602         delete($options{machinename});
1603         if (!$in{rumba_mname_def}) { $options{machinename} = $in{rumba_mname}; }
1604
1605         delete($options{clientname});
1606         if (!$in{rumba_cname_def}) { $options{clientname} = $in{rumba_cname}; }
1607
1608         delete($options{username});
1609         if ($in{rumba_username}) { $options{username} = $in{rumba_username}; }
1610
1611         delete($options{password});
1612         if ($in{rumba_password}) { $options{password} = $in{rumba_password}; }
1613
1614         delete($options{uid});
1615         if ($in{rumba_uid} ne "") { $options{uid} = getpwnam($in{rumba_uid}); }
1616
1617         delete($options{gid});
1618         if ($in{rumba_gid} ne "") { $options{gid} = getgrnam($in{rumba_gid}); }
1619
1620         delete($options{fmode});
1621         if ($in{rumba_fmode} !~ /^[0-7]{3}$/) {
1622                 &error("'$in{rumba_fmode}' is not a valid octal file mode");
1623                 }
1624         elsif ($in{rumba_fmode} ne "755") { $options{fmode} = $in{rumba_fmode}; }
1625
1626         delete($options{dmode});
1627         if ($in{rumba_dmode} !~ /^[0-7]{3}$/) {
1628                 &error("'$in{rumba_dmode}' is not a valid octal directory mode");
1629                 }
1630         elsif ($in{rumba_dmode} ne "755") { $options{dmode} = $in{rumba_dmode}; }
1631
1632         delete($options{'readwrite'});
1633         if ($in{'rumba_readwrite'}) { $options{'readwrite'} = ""; }
1634
1635         delete($options{'readonly'});
1636         if ($in{'rumba_readonly'}) { $options{'readonly'} = ""; }
1637
1638         delete($options{'attr'});
1639         if ($in{'rumba_attr'}) { $options{'attr'} = ""; }
1640
1641         delete($options{'noupper'});
1642         if ($in{'rumba_noupper'}) { $options{'noupper'} = ""; }
1643         }
1644
1645 # Return options string
1646 foreach $k (keys %options) {
1647         if ($options{$k} eq "") { push(@rv, $k); }
1648         else { push(@rv, "$k=$options{$k}"); }
1649         }
1650 return @rv ? join(',' , @rv) : "-";
1651 }
1652
1653
1654 # create_swap(path, size, units)
1655 # Attempt to create a swap file 
1656 sub create_swap
1657 {
1658 local($out);
1659 $out = &backquote_logged("mkfile $_[1]$_[2] $_[0] 2>&1");
1660 if ($?) {
1661         &unlink_file($_[0]);
1662         return "mkfile failed : $out";
1663         }
1664 return 0;
1665 }
1666
1667
1668 # exports_list(host, dirarray, clientarray)
1669 # Fills the directory and client array references with exports from some
1670 # host. Returns an error string if something went wrong
1671 sub exports_list
1672 {
1673 local($dref, $cref, $out, $_);
1674 $dref = $_[1]; $cref = $_[2];
1675 $out = &backquote_command("showmount -e ".quotemeta($_[0])." 2>&1", 1);
1676 if ($?) { return $out; }
1677 foreach (split(/\n/, $out)) {
1678         if (/^(\/\S*)\s+(.*)$/) {
1679                 push(@$dref, $1); push(@$cref, $2);
1680                 }
1681         }
1682 return undef;
1683 }
1684
1685 # broadcast_addr()
1686 # Returns a useable broadcast address for finding NFS servers
1687 sub broadcast_addr
1688 {
1689 local($out);
1690 $out = &backquote_command("ifconfig -a 2>&1", 1);
1691 if ($out =~ /broadcast\s+(\S+)/) { return $1; }
1692 return "255.255.255.255";
1693 }
1694
1695 sub device_name
1696 {
1697 return $_[0];
1698 }
1699
1700 sub files_to_lock
1701 {
1702 return ( $config{'fstab_file'}, $config{'autofs_file'} );
1703 }
1704
1705 1;