Handle hostnames with upper-case letters
[webmin.git] / mount / hpux-lib.pl
1 # hpux-lib.pl
2 # Filesystem functions for HP-UX (works for me on 10.xx and 11.00)
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[2] eq "ignore") { next; }
20         if ($p[2] eq "swap") { $p[1] = "swap"; }
21         $rv[$i++] = [ $p[1], $p[0], $p[2], $p[3], $p[5], "yes" ];
22         }
23 close(FSTAB);
24
25 # List automount points
26 open(AUTOTAB, $config{autofs_file});
27 while(<AUTOTAB>) {
28         chop; s/#.*$//g;
29         if (!/\S/ || /^[+\-]/) { next; }
30         @p = split(/\s+/, $_);
31         if ($p[2] eq "") { $p[2] = "-"; }
32         else { $p[2] =~ s/^-//g; }
33         $rv[$i++] = [ $p[0], $p[1], "autofs", $p[2], "-", "yes" ];
34         }
35 close(AUTOTAB);
36
37 return @rv;
38 }
39
40
41 # create_mount(directory, device, type, options, fsck_order, mount_at_boot)
42 # Add a new entry to the fstab file, and return the index of the new entry
43 sub create_mount
44 {
45 local($len, @mlist, $fsck, $dir);
46 if ($_[2] eq "autofs") {
47         # An autofs mount.. add to /etc/auto_master
48         $len = grep { $_->[2] eq "autofs" } (&list_mounts());
49         &open_tempfile(AUTOTAB, ">> $config{autofs_file}");
50         &print_tempfile(AUTOTAB, "$_[0] $_[1]",($_[3] eq "-" ? "" : " -$_[3]"),"\n");
51         &close_tempfile(AUTOTAB);
52         }
53 else {
54         # Add to the fstab file
55         $len = grep { $_->[2] ne "autofs" } (&list_mounts());
56         if ($_[4] eq "-") { 
57                 $fsck = "0";
58                 }
59         else {
60                 $fsck = $_[4];
61                 }
62         &open_tempfile(FSTAB, ">> $config{fstab_file}");
63         &print_tempfile(FSTAB, "$_[1] $_[0] $_[2] $_[3] 0 $fsck\n");
64         &close_tempfile(FSTAB);
65         }
66 return $len;
67 }
68
69
70 # delete_mount(index)
71 # Delete some mount from the table
72 sub delete_mount
73 {
74 local(@fstab, $i, $line, $_);
75 open(FSTAB, $config{fstab_file});
76 @fstab = <FSTAB>;
77 close(FSTAB);
78 $i = 0;
79
80 &open_tempfile(FSTAB, "> $config{fstab_file}");
81 foreach (@fstab) {
82         chop; ($line = $_) =~ s/#.*$//g;
83         if ($line =~ /\S/ && $i++ == $_[0]) {
84                 # found the line not to include
85                 }
86         else {
87                 &print_tempfile(FSTAB, $_,"\n");
88                 }
89         }
90 &close_tempfile(FSTAB);
91
92 open(AUTOTAB, $config{autofs_file});
93 @autotab = <AUTOTAB>;
94 close(AUTOTAB);
95 &open_tempfile(AUTOTAB, "> $config{autofs_file}");
96 foreach (@autotab) {
97         chop; ($line = $_) =~ s/#.*$//g;
98         if ($line =~ /\S/ && $line !~ /^[+\-]/ && $i++ == $_[0]) {
99                 # found line not to include..
100                 }
101         else {
102                 &print_tempfile(AUTOTAB, $_,"\n");
103                 }
104         }
105 &close_tempfile(AUTOTAB);
106 }
107
108
109 # change_mount(num, directory, device, type, options, fsck_order, mount_at_boot)
110 # Change an existing permanent mount
111 sub change_mount
112 {
113 local(@fstab, @autotab, $i, $line, $fsck, $dir, $_);
114 $i = 0;
115
116 open(FSTAB, $config{fstab_file});
117 @fstab = <FSTAB>;
118 close(FSTAB);
119 &open_tempfile(FSTAB, "> $config{fstab_file}");
120 foreach (@fstab) {
121         chop; ($line = $_) =~ s/#.*$//g;
122         if ($line =~ /\S/ && $i++ == $_[0]) {
123                 if ($_[5] eq "-") {
124                         $fsck = "0";
125                         }
126                 else {
127                         $fsck = $_[5];
128                         }
129                 # Found the line to replace
130                 &print_tempfile(FSTAB, "$_[2] $_[1] $_[3] $_[4] 0 $fsck\n");
131                 }
132         else {
133                 &print_tempfile(FSTAB, $_,"\n");
134                 }
135         }
136 &close_tempfile(FSTAB);
137
138 open(AUTOTAB, $config{autofs_file});
139 @autotab = <AUTOTAB>;
140 close(AUTOTAB);
141 &open_tempfile(AUTOTAB, "> $config{autofs_file}");
142 foreach (@autotab) {
143         chop; ($line = $_) =~ s/#.*$//g;
144         if ($line =~ /\S/ && $line !~ /^[+\-]/ && $i++ == $_[0]) {
145                 # Found the line to replace
146                 &print_tempfile(AUTOTAB, "$_[1]  $_[2]  ",
147                                 ($_[4] eq "-" ? "" : "-$_[4]"),"\n");
148                 }
149         else {
150                 &print_tempfile(AUTOTAB, $_,"\n");
151                 }
152         }
153 &close_tempfile(AUTOTAB);
154 }
155
156
157 # list_mounted()
158 # Return a list of all the currently mounted filesystems and swap files.
159 # The list is in the form: directory device type options
160 # For swap files, the directory will be 'swap'
161 sub list_mounted
162 {
163 local(@rv, @p, $_, $i, $r);
164 &open_execute_command(SWAP, "swapinfo -a", 1, 1);
165 while(<SWAP>) {
166         if (/^dev\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/) { push(@rv, [ "swap", $8, "swap", "pri=$7" ]); }
167         }
168 close(SWAP);
169 &open_tempfile(MNTTAB, "/etc/mnttab");
170 while(<MNTTAB>) {
171         s/#.*$//g; if (!/\S/) { next; }
172         @p = split(/\s+/, $_);
173         if ($p[2] eq "ignore") { next; }
174         push(@rv, [ $p[1], $p[0], $p[2], $p[3] ]);
175         }
176 close(MNTTAB);
177 return @rv;
178 }
179
180
181 # mount_dir(directory, device, type, options)
182 # Mount a new directory from some device, with some options. Returns 0 if ok,
183 # or an error string if failed. If the directory is 'swap', then mount as
184 # virtual memory.
185 sub mount_dir
186 {
187 local($out, $opts);
188 if ($_[0] eq "swap") {
189         # Adding a swap device
190         local(%options, $opts);
191         &parse_options("swap", $_[3]);
192         if (defined($options{"pri"})) {
193                 $opts = "-p $options{'pri'}";
194                 }
195         $out = &backquote_logged("swapon $opts $_[1] 2>&1");
196         if ($? && !($out =~ /already enabled for paging/)) { return $out; }
197         }
198 else {
199         $opts = $_[3] eq "-" ? "" : "-o \"$_[3]\"";
200         $out = &backquote_logged("mount -F $_[2] $opts -- $_[1] $_[0] 2>&1");
201         if ($?) { return $out; }
202         }
203 return 0;
204 }
205
206
207 # unmount_dir(directory, device, type)
208 # Unmount a directory (or swap device) that is currently mounted. Returns 0 if
209 # ok, or an error string if failed
210 sub unmount_dir
211 {
212 if ($_[0] eq "swap") {
213         # Not possible!
214         &error("Swap space cannot be removed");
215         }
216 else {
217         $out = &backquote_logged("umount $_[0] 2>&1");
218         }
219 if ($?) { return $out; }
220 return 0;
221 }
222
223
224 # disk_space(type, directory)
225 # Returns the amount of total and free space for some filesystem, or an
226 # empty array if not appropriate.
227 sub disk_space
228 {
229 if (&get_mounted($_[1], "*") < 0) { return (); }
230 if ($_[0] eq "swap") {
231         return ();
232         }
233 my $out;
234 &execute_command("bdf ".quotemeta($_[1]), undef, \$out, \$out, 0, 1);
235 if ($out =~ /Mounted on\n\S+\s+(\S+)\s+\S+\s+(\S+)/) {
236         return ($1, $2);
237         }
238 else {
239         return ( );
240         }
241 }
242
243
244 # list_fstypes()
245 # Returns an array of all the supported filesystem types. If a filesystem is
246 # found that is not one of the supported types, generate_location() and
247 # generate_options() will not be called for it.
248 sub list_fstypes
249 {
250 return ("hfs", "vxfs", "swap", "cdfs", "nfs", "lofs");
251 }
252
253
254 # fstype_name(type)
255 # Given a short filesystem type, return a human-readable name for it
256 sub fstype_name
257 {
258 local(%fsmap);
259 %fsmap = ("hfs","HP Unix Filesystem",
260           "vxfs","HP Journaled Unix Filesystem",
261           "nfs","Network Filesystem",
262           "cdfs","ISO9660 CD-ROM",
263           "lofs","Loopback Filesystem",
264           "swapfs","Filesystem Swap Space",
265           "swap","Virtual Memory",
266           "autofs","Automounter Filesystem");
267 return $config{long_fstypes} && $fsmap{$_[0]} ? $fsmap{$_[0]} : uc($_[0]);
268 }
269
270
271 # mount_modes(type)
272 # Given a filesystem type, returns 4 numbers that determine how the file
273 # system can be mounted, and whether it can be fsck'd
274 #  0 - cannot be permanently recorded
275 #  1 - can be permanently recorded, and is always mounted at boot
276 #  2 - can be permanently recorded, and may or may not be mounted at boot
277 # The second is:
278 #  0 - mount is always permanent => mounted when saved
279 #  1 - doesn't have to be permanent
280 # The third is:
281 #  0 - cannot be fsck'd at boot time
282 #  1 - can be be fsck'd at boot time
283 # The fourth is:
284 #  0 - can be unmounted
285 #  1 - cannot be unmounted
286 sub mount_modes
287 {
288 if ($_[0] eq "hfs" || $_[0] eq "vxfs") {
289         return (1, 1, 1, 0);
290         }
291 elsif ($_[0] eq "swap") {
292         return (1, 1, 0, 0);
293         }
294 else { return (1, 1, 0, 0); }
295 }
296
297
298 # multiple_mount(type)
299 # Returns 1 if filesystems of this type can be mounted multiple times, 0 if not
300 sub multiple_mount
301 {
302 return ($_[0] eq "nfs" || $_[0] eq "lofs");
303 }
304
305
306 # generate_location(type, location)
307 # Output HTML for editing the mount location of some filesystem.
308 sub generate_location
309 {
310 if ($_[0] eq "nfs") {
311         # NFS mount from some host and directory
312         $onenfs = !$_[1] || $_[1] =~ /^([A-z0-9\-\.]+):([^,]+)$/;
313         print "<tr> <td><b>NFS Hostname</b></td>\n";
314         print "<td><input name=nfs_host size=20 value=\"$1\">\n";
315         &nfs_server_chooser_button("nfs_host");
316         print "</td>\n";
317         print "<td><b>NFS Directory</b></td>\n";
318         print "<td><input name=nfs_dir size=20 value=\"$2\">\n";
319         &nfs_export_chooser_button("nfs_host", "nfs_dir");
320         print "</td> </tr>\n";
321         }
322 elsif ($_[0] eq "hfs") {
323         # Mounted from a normal disk, LVM device or from
324         # somewhere else
325         print "<tr> <td valign=top><b>HFS Device</b></td>\n";
326         print "<td colspan=3>\n";
327         if ($_[1] =~ /^\/dev\/dsk\/c([0-9]+)t([0-9]+)d([0-9]+)s([0-9]+)$/) {
328                 $hfs_dev = 0;
329                 $scsi_c = $1; $scsi_t = $2; $scsi_d = $3; $scsi_s = $4;
330                 }
331         elsif ($_[1] eq "") {
332                 $hfs_dev = 0; $scsi_c = $scsi_t = $scsi_s = $scsi_d = 0;
333                 }
334         elsif ($_[1] =~ /^\/dev\/vg([0-9]+)\/(\S+)/) {
335                 $hfs_dev = 1; $scsi_vg = $1; $scsi_lv = $2;
336                 }
337         else {
338                 $hfs_dev = 2; $scsi_path = $_[1];
339                 }
340         $scsi_path = $_[1];
341
342         printf "<input type=radio name=hfs_dev value=0 %s> SCSI Disk:\n",
343                 $hfs_dev == 0 ? "checked" : "";
344         print "Controller <input name=hfs_c size=3 value=\"$scsi_c\">\n";
345         print "Target <input name=hfs_t size=3 value=\"$scsi_t\">\n";
346         print "Unit <input name=hfs_d size=3 value=\"$scsi_d\">\n";
347         print "Partition <input name=hfs_s size=3 value=\"$scsi_s\"><br>\n";
348
349         printf "<input type=radio name=hfs_dev value=1 %s> LVM Device:\n",
350                 $hfs_dev == 1 ? "checked" : "";
351         print "Volume Group <input name=hfs_vg size=2 value=\"$scsi_vg\">\n";
352         print "Logical Volume <input name=hfs_lv size=20 value=\"$scsi_lv\"><br>\n";
353
354         printf "<input type=radio name=hfs_dev value=2 %s> Other Device:\n",
355                 $hfs_dev == 2 ? "checked" : "";
356         print "<input name=hfs_path size=20 value=\"$scsi_path\">";
357         print &file_chooser_button("hfs_path", 0);
358         print "<br>\n";
359         print "</td> </tr>\n";
360         }
361 elsif ($_[0] eq "vxfs") {
362         # Mounted from a normal disk, LVM device or from
363         # somewhere else
364         print "<tr> <td valign=top><b>VXFS Device</b></td>\n";
365         print "<td colspan=3>\n";
366         if ($_[1] =~ /^\/dev\/dsk\/c([0-9]+)t([0-9]+)d([0-9]+)s([0-9]+)$/) {
367                 $jfs_dev = 0;
368                 $scsi_c = $1; $scsi_t = $2; $scsi_d = $3; $scsi_s = $4;
369                 }
370         elsif ($_[1] eq "") {
371                 $jfs_dev = 0; $scsi_c = $scsi_t = $scsi_s = $scsi_d = 0;
372                 }
373         elsif ($_[1] =~ /^\/dev\/vg([0-9]+)\/(\S+)/) {
374                 $jfs_dev = 1; $scsi_vg = $1; $scsi_lv = $2;
375                 }
376         else {
377                 $jfs_dev = 2; $scsi_path = $_[1];
378                 }
379         $scsi_path = $_[1];
380
381         printf "<input type=radio name=jfs_dev value=0 %s> SCSI Disk:\n",
382                 $jfs_dev == 0 ? "checked" : "";
383         print "Controller <input name=jfs_c size=3 value=\"$scsi_c\">\n";
384         print "Target <input name=jfs_t size=3 value=\"$scsi_t\">\n";
385         print "Unit <input name=jfs_d size=3 value=\"$scsi_d\">\n";
386         print "Partition <input name=jfs_s size=3 value=\"$scsi_s\"><br>\n";
387
388         printf "<input type=radio name=jfs_dev value=1 %s> LVM Device:\n",
389                 $jfs_dev == 1 ? "checked" : "";
390         print "Volume Group <input name=jfs_vg size=2 value=\"$scsi_vg\">\n";
391         print "Logical Volume <input name=jfs_lv size=20 value=\"$scsi_lv\"><br>\n";
392
393         printf "<input type=radio name=jfs_dev value=2 %s> Other Device:\n",
394                 $jfs_dev == 2 ? "checked" : "";
395         print "<input name=jfs_path size=20 value=\"$scsi_path\">";
396         print &file_chooser_button("jfs_path", 0);
397         print "<br>\n";
398         print "</td> </tr>\n";
399         }
400 elsif ($_[0] eq "swap") {
401         # Swapping to a disk partition or a file
402         print "<tr> <td valign=top><b>Swap File</b></td>\n";
403         print "<td colspan=3>\n";
404         if ($_[1] =~ /^\/dev\/dsk\/c([0-9]+)t([0-9]+)d([0-9]+)s([0-9]+)$/) {
405                 $swap_dev = 0;
406                 $scsi_c = $1; $scsi_t = $2; $scsi_d = $3; $scsi_s = $4;
407                 }
408         elsif ($_[1] =~ /^\/dev\/vg([0-9]+)\/(\S+)/) {
409                 $swap_dev = 1; $scsi_vg = $1; $scsi_lv = $2;
410                 }
411         else {
412                 $swap_dev = 2; $scsi_path = $_[1];
413                 }
414         $scsi_path = $_[1];
415         printf "<input type=radio name=swap_dev value=0 %s> SCSI Disk:\n",
416                 $swap_dev == 0 ? "checked" : "";
417         print "Controller <input name=swap_c size=3 value=\"$scsi_c\">\n";
418         print "Target <input name=swap_t size=3 value=\"$scsi_t\">\n";
419         print "Unit <input name=swap_d size=3 value=\"$scsi_d\">\n";
420         print "Partition <input name=swap_s size=3 value=\"$scsi_s\"><br>\n";
421
422         printf "<input type=radio name=swap_dev value=1 %s> LVM Device:\n",
423                 $swap_dev == 1 ? "checked" : "";
424         print "Volume Group <input name=swap_vg size=2 value=\"$scsi_vg\">\n";
425         print "Logical Volume <input name=swap_lv size=20 value=\"$scsi_lv\"><br>\n";
426
427         printf "<input type=radio name=swap_dev value=2 %s> File:\n",
428                 $swap_dev == 2 ? "checked" : "";
429         print "<input name=swap_path size=20 value=\"$scsi_path\">";
430         print &file_chooser_button("swap_path", 0);
431         print "<br>\n";
432         print "</td> </tr>\n";
433         }
434 elsif ($_[0] eq "cdfs") {
435         # Mounting a SCSI cdrom
436         print "<tr> <td valign=top><b>CDROM Disk</b></td>\n";
437         print "<td colspan=3>\n";
438         if ($_[1] =~ /^\/dev\/dsk\/c([0-9]+)t([0-9]+)d([0-9]+)$/) {
439                 $cdfs_dev = 0;
440                 $scsi_c = $1; $scsi_t = $2; $scsi_d = $3;
441                 }
442         else {
443                 $cdfs_dev = 1; $scsi_path = $_[1];
444                 }
445         $scsi_path = $_[1];
446         printf "<input type=radio name=cdfs_dev value=0 %s> SCSI Device:\n",
447                 $cdfs_dev == 0 ? "checked" : "";
448         print "Controller <input name=cdfs_c size=3 value=\"$scsi_c\">\n";
449         print "Target <input name=cdfs_t size=3 value=\"$scsi_t\">\n";
450         print "Unit <input name=cdfs_d size=3 value=\"$scsi_d\">\n<BR>";
451
452         printf "<input type=radio name=cdfs_dev value=1 %s> Other Device:\n",
453                 $cdfs_dev == 1 ? "checked" : "";
454         print "<input name=cdfs_path size=20 value=\"$scsi_path\">";
455         print &file_chooser_button("cdfs_path", 0);
456         print "<br>\n";
457         print "</td> </tr>\n";
458         }
459 elsif ($_[0] eq "lofs") {
460         # Mounting some directory to another location
461         print "<tr> <td><b>Original Directory</b></td>\n";
462         print "<td><input name=lofs_src size=30 value=\"$_[1]\">\n";
463         print &file_chooser_button("lofs_src", 1);
464         print "</td> </tr>\n";
465         }
466 elsif ($_[0] eq "swapfs") {
467         # Mounting a cached filesystem of some type.. need a location for
468         # the source of the mount
469         print "<tr> <td><b>Cache Source</b></td>\n";
470         print "<td><input name=cfs_src size=20 value=\"$_[1]\"></td> </tr>\n";
471         }
472 elsif ($_[0] eq "autofs") {
473         # An automounter entry.. can be -hosts, -xfn or from some mapping
474         print "<tr> <td valign=top><b>Automounter map</b></td>\n";
475         printf "<td><input type=radio name=autofs_type value=0 %s>\n",
476                 $_[1] eq "-hosts" || $_[1] eq "-xfn" ? "" : "checked";
477         printf "Use map <input name=autofs_map size=20 value=\"%s\"><br>\n",
478                 $_[1] eq "-hosts" || $_[1] eq "-xfn" ? "" : $_[1];
479         printf "<input type=radio name=autofs_type value=1 %s>\n",
480                 $_[1] eq "-hosts" ? "checked" : "";
481         print "All NFS exports map<br>\n";
482         printf "<input type=radio name=autofs_type value=2 %s>\n",
483                 $_[1] eq "-xfn" ? "checked" : "";
484         print "Federated  Naming  Service map</td> </tr>\n";
485         }
486 }
487
488
489 # generate_options(type, newmount)
490 # Output HTML for editing mount options for a partilcar filesystem 
491 # under this OS
492 sub generate_options
493 {
494 if ($_[0] eq "nfs") {
495         # NFS has many options, not all of which are editable here
496         print "<tr> <td><b>Read-Only?</b></td>\n";
497         printf "<td nowrap><input type=radio name=nfs_ro value=1 %s> Yes\n",
498                 defined($options{"ro"}) ? "checked" : "";
499         printf "<input type=radio name=nfs_ro value=0 %s> No</td>\n",
500                 defined($options{"ro"}) ? "" : "checked";
501
502         print "<td><b>Disallow setuid programs?</b></td>\n";
503         printf "<td nowrap><input type=radio name=nfs_nosuid value=1 %s> Yes\n",
504                 defined($options{"nosuid"}) ? "checked" : "";
505         printf "<input type=radio name=nfs_nosuid value=0 %s> No</td> </tr>\n",
506                 defined($options{"nosuid"}) ? "" : "checked";
507
508         print "<tr> <td><b>Return error on timeouts?</b></td>\n";
509         printf "<td nowrap><input type=radio name=nfs_soft value=1 %s> Yes\n",
510                 defined($options{"soft"}) ? "checked" : "";
511         printf "<input type=radio name=nfs_soft value=0 %s> No</td>\n",
512                 defined($options{"soft"}) ? "" : "checked";
513
514         print "<td><b>Retry mounts in background?</b></td>\n";
515         printf "<td nowrap><input type=radio name=nfs_bg value=1 %s> Yes\n",
516                 defined($options{"bg"}) ? "checked" : "";
517         printf "<input type=radio name=nfs_bg value=0 %s> No</td> </tr>\n",
518                 defined($options{"bg"}) ? "" : "checked";
519
520         print "<tr> <td><b>Allow interrupts?</b></td>\n";
521         printf "<td nowrap><input type=radio name=nfs_nointr value=0 %s> Yes\n",
522                 defined($options{"nointr"}) ? "" : "checked";
523         printf "<input type=radio name=nfs_nointr value=1 %s> No</td>\n",
524                 defined($options{"nointr"}) ? "checked" : "";
525
526         print "<td><b>Allow Access to Local Devices?</b></td>\n";
527         printf "<td nowrap><input type=radio name=nfs_nodevs value=0 %s> Yes\n",
528                 defined($options{"nodevs"}) ? "" : "checked";
529         printf "<input type=radio name=nfs_nodevs value=1 %s> No</td> </tr>\n",
530                 defined($options{"nodevs"}) ? "checked" : "";
531         }
532 if ($_[0] eq "hfs") {
533         print "<tr> <td><b>Read-Only?</b></td>\n";
534         printf "<td nowrap><input type=radio name=hfs_ro value=1 %s> Yes\n",
535                 defined($options{"ro"}) ? "checked" : "";
536         printf "<input type=radio name=hfs_ro value=0 %s> No</td>\n",
537                 defined($options{"ro"}) ? "" : "checked";
538
539         print "<td><b>Disallow setuid programs?</b></td>\n";
540         printf "<td nowrap><input type=radio name=hfs_nosuid value=1 %s> Yes\n",
541                 defined($options{"nosuid"}) ? "checked" : "";
542         printf "<input type=radio name=hfs_nosuid value=0 %s> No</td> </tr>\n",
543                 defined($options{"nosuid"}) ? "" : "checked";
544
545         print "<tr> <td><b>Enable quotas at boot time?</b></td>\n";
546         printf "<td nowrap><input type=radio name=hfs_quota value=1 %s> Yes\n",
547                 defined($options{"quota"}) ? "checked" : "";
548         printf "<input type=radio name=hfs_quota value=0 %s> No</td> </tr>\n",
549                 defined($options{"quota"}) ? "" : "checked";
550         }
551 if ($_[0] eq "vxfs") {
552         print "<tr> <td><b>Read-Only?</b></td>\n";
553         printf "<td nowrap><input type=radio name=jfs_ro value=1 %s> Yes\n",
554                 defined($options{"ro"}) ? "checked" : "";
555         printf "<input type=radio name=jfs_ro value=0 %s> No</td>\n",
556                 defined($options{"ro"}) ? "" : "checked";
557
558         print "<td><b>Disallow setuid programs?</b></td>\n";
559         printf "<td nowrap><input type=radio name=jfs_nosuid value=1 %s> Yes\n",
560                 defined($options{"nosuid"}) ? "checked" : "";
561         printf "<input type=radio name=jfs_nosuid value=0 %s> No</td> </tr>\n",
562                 defined($options{"nosuid"}) ? "" : "checked";
563
564         print "<tr> <td><b>Full integrity for all Metadata?</b></td>\n";
565         printf "<td nowrap><input type=radio name=jfs_log value=1 %s> Yes\n",
566                 defined($options{"log"}) ? "checked" : "";
567         printf "<input type=radio name=jfs_log value=0 %s> No</td>\n",
568                 defined($options{"log"}) ? "" : "checked";
569
570         print "<td><b>Synchronous-write data logging?</b></td>\n";
571         printf "<td nowrap><input type=radio name=jfs_syncw value=1 %s> Yes\n",
572                 !defined($options{"nodatainlog"}) ? "checked" : "";
573         printf "<input type=radio name=jfs_syncw value=0 %s> No</td> </tr>\n",
574                 !defined($options{"nodatainlog"}) ? "" : "checked";
575
576         print "<tr> <td><b>Enable quotas at boot time?</b></td>\n";
577         printf "<td nowrap><input type=radio name=jfs_quota value=1 %s> Yes\n",
578                 defined($options{"quota"}) ? "checked" : "";
579         printf "<input type=radio name=jfs_quota value=0 %s> No</td> </tr>\n",
580                 defined($options{"quota"}) ? "" : "checked";
581         }
582 if ($_[0] eq "cdfs") {
583         print "<tr> <td><b>Disallow setuid programs?</b></td>\n";
584         printf"<td nowrap><input type=radio name=cdfs_nosuid value=1 %s> Yes\n",
585                 defined($options{"nosuid"}) ? "checked" : "";
586         printf "<input type=radio name=cdfs_nosuid value=0 %s> No</td> </tr>\n",
587                 defined($options{"nosuid"}) ? "" : "checked";
588         }
589 if ($_[0] eq "lofs") {
590         print "<tr> <td><b>Read-Only?</b></td>\n";
591         printf "<td nowrap><input type=radio name=lofs_ro value=1 %s> Yes\n",
592                 defined($options{"ro"}) ? "checked" : "";
593         printf "<input type=radio name=lofs_ro value=0 %s> No</td> </tr>\n",
594                 defined($options{"ro"}) ? "" : "checked";
595         }
596 if ($_[0] eq "swap") {
597         local($i);
598         print "<tr> <td><b>Priority</b></td>\n";
599         print "<td><select name=swap_pri>\n";
600         for ($i = 0; $i < 11; ++$i) {
601                 printf "<option value=\"%s\" %s>%s\n",
602                         $i, $options{"pri"} == $i ? "selected" : "", $i;
603                 }
604         print "</select></td> </tr>\n";
605         }
606 if ($_[0] eq "swapfs") {
607         # The caching filesystem has lots of options.. cachefs mounts can
608         # be of an existing 'manually' mounted back filesystem, or of a
609         # back-filesystem that has been automatically mounted by the cache.
610         # The user should never see the automatic mountings made by cachefs.
611         print "<tr> <td><b>Real filesystem type</b></td>\n";
612         print "<td nowrap><select name=cfs_backfstype>\n";
613         if (!defined($options{backfstype})) { $options{backfstype} = "nfs"; }
614         foreach (&list_fstypes()) {
615                 if ($_ eq "cachefs") { next; }
616                 printf "<option value=\"$_\" %s>$_\n",
617                         $_ eq $options{backfstype} ? "selected" : "";
618                 }
619         print "</select></td>\n";
620
621         print "<td><b>Real mount point</b></td>\n";
622         printf"<td nowrap><input type=radio name=cfs_noback value=1 %s> Automatic\n",
623                 defined($options{"backpath"}) ? "" : "checked";
624         printf "<input type=radio name=cfs_noback value=0 %s>\n",
625                 defined($options{"backpath"}) ? "checked" : "";
626         print "<input size=10 name=cfs_backpath value=\"$options{backpath}\"></td> </tr>\n";
627
628         print "<tr> <td><b>Cache directory</b></td>\n";
629         printf "<td nowrap><input size=10 name=cfs_cachedir value=\"%s\"></td>\n",
630                 defined($options{"cachedir"}) ? $options{"cachedir"} : "/cache";
631
632         print "<td><b>Write mode</b></td>\n";
633         printf"<td nowrap><input type=radio name=cfs_wmode value=0 %s> Write-around\n",
634                 defined($options{"non-shared"}) ? "" : "checked";
635         printf "<input type=radio name=cfs_wmode value=1 %s> Non-shared\n",
636                 defined($options{"non-shared"}) ? "checked" : "";
637         print "</td> </tr>\n";
638
639         print "<tr> <td><b>Consistency check</b></td>\n";
640         print "<td><select name=cfs_con>\n";
641         print "<option value=1> Periodically\n";
642         printf "<option value=0 %s> Never\n",
643                 defined($options{"noconst"}) ? "selected" : "";
644         printf "<option value=2 %s> On demand\n",
645                 defined($options{"demandconst"}) ? "selected" : "";
646         print "</select></td>\n";
647
648         print "<td><b>Check permissions in cache?</b></td>\n";
649         printf "<td nowrap><input type=radio name=cfs_local value=1 %s> Yes\n",
650                 defined($options{"local-access"}) ? "checked" : "";
651         printf "<input type=radio name=cfs_local value=0 %s> No</td> </tr>\n",
652                 defined($options{"local-access"}) ? "" : "checked";
653
654         print "<tr> <td><b>Read-Only?</b></td>\n";
655         printf "<td nowrap><input type=radio name=cfs_ro value=1 %s> Yes\n",
656                 defined($options{"ro"}) ? "checked" : "";
657         printf "<input type=radio name=cfs_ro value=0 %s> No</td>\n",
658                 defined($options{"ro"}) ? "" : "checked";
659
660         print "<td><b>Disallow setuid programs?</b></td>\n";
661         printf "<td nowrap><input type=radio name=cfs_nosuid value=1 %s> Yes\n",
662                 defined($options{"nosuid"}) ? "checked" : "";
663         printf "<input type=radio name=cfs_nosuid value=0 %s> No</td> </tr>\n",
664                 defined($options{"nosuid"}) ? "" : "checked";
665         }
666 if ($_[0] eq "autofs") {
667         # Autofs has lots of options, depending on the type of file
668         # system being automounted.. the fstype options determines this
669         local($fstype);
670         $fstype = $options{fstype} eq "" ? "nfs" : $options{fstype};
671         &generate_options($fstype);
672         print "<input type=hidden name=autofs_fstype value=\"$fstype\">\n";
673         }
674 }
675
676
677 # check_location(type)
678 # Parse and check inputs from %in, calling &error() if something is wrong.
679 # Returns the location string for storing in the fstab file
680 sub check_location
681 {
682 if ($_[0] eq "nfs") {
683         local($out, $temp, $mout, $dirlist);
684
685         # Use ping and showmount to see if the host exists and is up
686         if ($in{nfs_host} !~ /^\S+$/) {
687                 &error("'$in{nfs_host}' is not a valid hostname");
688                 }
689         &execute_command("ping -c 1 '$in{nfs_host}'", undef, \$out, \$out);
690         if ($out =~ /unknown host/i) {
691                 &error("The host '$in{nfs_host}' does not exist");
692                 }
693         elsif ($out =~ /100\% packet loss/) {
694                 &error("The host '$in{nfs_host}' is down");
695                 }
696         &execute_command("showmount -e '$in{nfs_host}'", undef, \$out, \$out);
697         if ($out =~ /Unable to receive/) {
698                 &error("The host '$in{nfs_host}' does not support NFS");
699                 }
700         elsif ($?) {
701                 &error("Failed to get mount list : $out");
702                 }
703
704         # Validate directory name
705         foreach (split(/\n/, $out)) {
706                 if (/^(\/\S+)/) { $dirlist .= "$1\n"; }
707                 }
708         if ($in{nfs_dir} !~ /^\/\S+$/) {
709                 &error("'$in{nfs_dir}' is not a valid directory name. The ".
710                        "available directories on $in{nfs_host} are:".
711                        "<pre>$dirlist</pre>");
712                 }
713
714         # Try a test mount to see if filesystem is available
715         $temp = &transname();
716         &make_dir($temp, 0755);
717         &execute_command("mount $in{nfs_host}:$in{nfs_dir} $temp",
718                          undef, \$mout, \$mout);
719         if ($mout =~ /No such file or directory/) {
720                 &error("The directory '$in{nfs_dir}' does not exist on the ".
721                        "host $in{nfs_host}. The available directories are:".
722                        "<pre>$dirlist</pre>");
723                 }
724         elsif ($mout =~ /Permission denied/) {
725                 &error("This host is not allowed to mount the directory ".
726                        "$in{nfs_dir} from $in{nfs_host}");
727                 }
728         elsif ($?) {
729                 &error("NFS Error - $mout");
730                 }
731         # It worked! unmount
732         &execute_command("umount $temp");
733         &unlink_file($temp);
734         return "$in{nfs_host}:$in{nfs_dir}";
735         }
736 elsif ($_[0] eq "hfs") {
737         # Get the device name
738         if ($in{hfs_dev} == 0) {
739                 $in{hfs_c} =~ /^[0-9]+$/ ||
740                         &error("'$in{hfs_c}' is not a valid SCSI controller");
741                 $in{hfs_t} =~ /^[0-9]+$/ ||
742                         &error("'$in{hfs_t}' is not a valid SCSI target");
743                 $in{hfs_d} =~ /^[0-9]+$/ ||
744                         &error("'$in{hfs_d}' is not a valid SCSI unit");
745                 $in{hfs_s} =~ /^[0-9]+$/ ||
746                         &error("'$in{hfs_s}' is not a valid SCSI partition");
747                 $dv = "/dev/dsk/c$in{hfs_c}t$in{hfs_t}d$in{hfs_d}s$in{hfs_s}";
748                 }
749         elsif ($in{hfs_dev} == 1) {
750                 $in{hfs_vg} =~ /^[0-9]+$/ ||
751                         &error("'$in{hfs_vg}' is not a valid Volume Group");
752                 $in{hfs_lv} =~ /^\S+$/ ||
753                         &error("'$in{hfs_lv}' is not a valid Logical Volume");
754                 $dv = "/dev/vg$in{hfs_vg}/$in{hfs_lv}";
755                 }
756         else {
757                 $in{hfs_path} =~ /^\/\S+$/ ||
758                         &error("'$in{hfs_path}' is not a valid pathname");
759                 $dv = $in{hfs_path};
760                 }
761
762         &fstyp_check($dv, "hfs");
763         return $dv;
764         }
765 elsif ($_[0] eq "vxfs") {
766         # Get the device name
767         if ($in{jfs_dev} == 0) {
768                 $in{jfs_c} =~ /^[0-9]+$/ ||
769                         &error("'$in{jfs_c}' is not a valid SCSI controller");
770                 $in{jfs_t} =~ /^[0-9]+$/ ||
771                         &error("'$in{jfs_t}' is not a valid SCSI target");
772                 $in{jfs_d} =~ /^[0-9]+$/ ||
773                         &error("'$in{jfs_d}' is not a valid SCSI unit");
774                 $in{jfs_s} =~ /^[0-9]+$/ ||
775                         &error("'$in{jfs_s}' is not a valid SCSI partition");
776                 $dv = "/dev/dsk/c$in{jfs_c}t$in{jfs_t}d$in{jfs_d}s$in{jfs_s}";
777                 }
778         elsif ($in{jfs_dev} == 1) {
779                 $in{jfs_vg} =~ /^[0-9]+$/ ||
780                         &error("'$in{jfs_vg}' is not a valid Volume Group");
781                 $in{jfs_lv} =~ /^\S+$/ ||
782                         &error("'$in{jfs_lv}' is not a valid Logical Volume");
783                 $dv = "/dev/vg$in{jfs_vg}/$in{jfs_lv}";
784                 }
785         else {
786                 $in{jfs_path} =~ /^\/\S+$/ ||
787                         &error("'$in{jfs_path}' is not a valid pathname");
788                 $dv = $in{jfs_path};
789                 }
790
791         &fstyp_check($dv, "vxfs");
792         return $dv;
793         }
794 elsif ($_[0] eq "lofs") {
795         # Get and check the original directory
796         $dv = $in{'lofs_src'};
797         if (!(-r $dv)) { &error("'$in{lofs_src}' does not exist"); }
798         if (!(-d $dv)) { &error("'$in{lofs_src}' is not a directory"); }
799         return $dv;
800         }
801 elsif ($_[0] eq "swap") {
802         if ($in{swap_dev} == 0) {
803                 $in{swap_c} =~ /^[0-9]+$/ ||
804                         &error("'$in{swap_c}' is not a valid SCSI controller");
805                 $in{swap_t} =~ /^[0-9]+$/ ||
806                         &error("'$in{swap_t}' is not a valid SCSI target");
807                 $in{swap_d} =~ /^[0-9]+$/ ||
808                         &error("'$in{swap_d}' is not a valid SCSI unit");
809                 $in{swap_s} =~ /^[0-9]+$/ ||
810                         &error("'$in{swap_s}' is not a valid SCSI partition");
811                 $dv="/dev/dsk/c$in{swap_c}t$in{swap_t}d$in{swap_d}s$in{swap_s}";
812                 }
813         elsif ($in{swap_dev} == 1) {
814                 $in{swap_vg} =~ /^[0-9]+$/ ||
815                         &error("'$in{swap_vg}' is not a valid Volume Group");
816                 $in{swap_lv} =~ /^\S+$/ ||
817                         &error("'$in{swap_lv}' is not a valid Logical Volume");
818                 $dv = "/dev/vg$in{swap_vg}/$in{swap_lv}";
819                 }
820         else {
821                 $in{swap_path} =~ /^\/\S+$/ ||
822                         &error("'$in{swap_path}' is not a valid pathname");
823                 $dv = $in{swap_path};
824                 }
825         &fstyp_check($dv, "swap");
826         return $dv;
827         }
828 elsif ($_[0] eq "cdfs") {
829         # Get the device name
830         if ($in{cdfs_dev} == 0) {
831                 $in{cdfs_c} =~ /^[0-9]+$/ ||
832                         &error("'$in{cdfs_c}' is not a valid SCSI controller");
833                 $in{cdfs_t} =~ /^[0-9]+$/ ||
834                         &error("'$in{cdfs_t}' is not a valid SCSI target");
835                 $in{cdfs_d} =~ /^[0-9]+$/ ||
836                         &error("'$in{cdfs_d}' is not a valid SCSI unit");
837                 $dv = "/dev/dsk/c$in{cdfs_c}t$in{cdfs_t}d$in{cdfs_d}";
838                 }
839         else {
840                 $in{cdfs_path} =~ /^\/\S+$/ ||
841                         &error("'$in{cdfs_path}' is not a valid pathname");
842                 $dv = $in{cdfs_path};
843                 }
844
845         &fstyp_check($dv, "cdfs");
846         return $dv;
847         }
848 elsif ($_[0] eq "swapfs") {
849         # In order to check the location for the caching filesystem, we need
850         # to check the back filesystem
851         if (!$in{cfs_noback}) {
852                 # The back filesystem is manually mounted.. hopefully
853                 local($bidx, @mlist, @binfo);
854                 $bidx = &get_mounted($in{cfs_backpath}, "*");
855                 if ($bidx < 0) {
856                         &error("The back filesystem '$in{cfs_backpath}' is ".
857                                "not mounted");
858                         }
859                 @mlist = &list_mounted();
860                 @binfo = @{$mlist[$bidx]};
861                 if ($binfo[2] ne $in{cfs_backfstype}) {
862                         &error("The back filesystem is '$binfo[2]', not ".
863                                "'$in{cfs_backfstype}'");
864                         }
865                 }
866         else {
867                 # Need to automatically mount the back filesystem.. check
868                 # it for sanity first.
869                 # But HOW?
870                 $in{cfs_src} =~ /^\S+$/ ||
871                         &error("'$in{cfs_src}' is not a valid cache source");
872                 }
873         return $in{cfs_src};
874         }
875 elsif ($_[0] eq "autofs") {
876         # An autofs filesystem can be either mounted from the special
877         # -hosts and -xfn maps, or from a normal map. The map can be a file
878         # name (if it starts with /), or an NIS map (if it doesn't)
879         if ($in{autofs_type} == 0) {
880                 # Normal map
881                 $in{autofs_map} =~ /\S/ ||
882                         &error("You did not enter an automount map name");
883                 if ($in{autofs_map} =~ /^\// && !(-r $in{autofs_map})) {
884                         &error("The map file '$in{autofs_map}' does not exist");
885                         }
886                 return $in{autofs_map};
887                 }
888         elsif ($in{autofs_type} == 1) {
889                 # Special hosts map (automount all shares from some host)
890                 return "-hosts";
891                 }
892         else {
893                 # Special FNS map (not sure what this does)
894                 return "-xfn";
895                 }
896         }
897 }
898
899 # fstyp_check(device, type)
900 # Check if some device exists, and contains a filesystem of the given type,
901 # using the fstyp command.
902 sub fstyp_check
903 {
904 local($out, $part, $found);
905
906 # Check if the device/partition actually exists
907 if ($_[0] =~ /^\/dev\/dsk\/c(.)t(.)d(.)s(.)$/) {
908         # a normal scsi device..
909         if (!&open_tempfile(DEV, $_[0], 0, 1)) {
910                 if ($! =~ /No such file or directory/) {
911                         &error("The SCSI target for '$_[0]' does not exist");
912                         }
913                 elsif ($! =~ /No such device or address/) {
914                         &error("The SCSI target for '$_[0]' does not exist");
915                         }
916                 }
917         &close_tempfile(DEV);
918         }
919 elsif ($_[0] =~ /^\/dev\/vg([0-9]+)\/(\S+)$/) {
920         # Logical Volume device..
921         $out = &backquote_command("lvdisplay -v $_[0] 2>&1");
922         if ($out =~ /No such file or directory/) {
923                 &error("The Logical Volume device for '$_[0]' does not exist");
924                 }
925         }
926 else {
927         # Some other device
928         if (!&open_tempfile(DEV, $_[0], 0, 1)) {
929                 if ($! =~ /No such file or directory/) {
930                         &error("The device file '$_[0]' does not exist");
931                         }
932                 elsif ($! =~ /No such device or address/) {
933                         &error("The device for '$_[0]' does not exist");
934                         }
935                 }
936         &close_tempfile(DEV);
937         }
938
939 # Check the filesystem type
940 if ($_[1] ne "cdfs" && $_[1] ne "swap") {
941         $out = &backquote_command("fstyp $_[0] 2>&1");
942         if ($out =~ /^([A-z0-9]+)\n$/) {
943                 if ($1 eq $_[1]) { return; }
944                 else {
945                         # Wrong filesystem type
946                         &error("The device '$_[0]' is formatted as a ".
947                                &fstype_name($1));
948                         }
949                 }
950         else {
951                 &error("Failed to check filesystem type : $out");
952                 }
953         }
954 }
955
956
957 # check_options(type)
958 # Read options for some filesystem from %in, and use them to update the
959 # %options array. Options handled by the user interface will be set or
960 # removed, while unknown options will be left untouched.
961 sub check_options
962 {
963 local($k, @rv);
964 delete($options{"defaults"});
965
966 if ($_[0] eq "nfs") {
967         # NFS has lots of options to parse
968         if ($in{'nfs_ro'}) {
969                 # Read-only
970                 $options{"ro"} = ""; delete($options{"rw"});
971                 }
972         else {
973                 # Read-write
974                 $options{"rw"} = ""; delete($options{"ro"});
975                 }
976
977         if ($in{hfs_nosuid}) {
978                 # nosuid
979                 $options{"nosuid"} = ""; delete($options{"suid"});
980                 }
981         else {
982                 # suid
983                 $options{"suid"} = ""; delete($options{"nosuid"});
984                 }
985
986         delete($options{"soft"}); delete($options{"hard"});
987         if ($in{nfs_soft}) { $options{"soft"} = ""; }
988
989         delete($options{"bg"}); delete($options{"fg"});
990         if ($in{nfs_bg}) { $options{"bg"} = ""; }
991
992         delete($options{"intr"}); delete($options{"nointr"});
993         if ($in{nfs_nointr}) { $options{"nointr"} = ""; }
994
995         delete($options{"devs"}); delete($options{"nodevs"});
996         if ($in{nfs_nodevs}) { $options{"nodevs"} = ""; }
997         }
998 elsif ($_[0] eq "hfs") {
999         if ($in{hfs_ro}) {
1000                 # read-only
1001                 $options{"ro"} = ""; delete($options{"rw"});
1002                 }
1003         else {
1004                 # read-write
1005                 $options{"rw"} = ""; delete($options{"ro"});
1006                 }
1007         if ($in{hfs_nosuid}) {
1008                 # nosuid
1009                 $options{"nosuid"} = ""; delete($options{"suid"});
1010                 }
1011         else {
1012                 # suid
1013                 $options{"suid"} = ""; delete($options{"nosuid"});
1014                 }
1015         if ($in{hfs_quota}) {
1016                 # quota
1017                 $options{"quota"} = "";
1018                 }
1019         else {
1020                 # noquota
1021                 delete($options{"quota"});
1022                 }
1023         }
1024 elsif ($_[0] eq "vxfs") {
1025         if ($in{jfs_ro}) {
1026                 # read-only
1027                 $options{"ro"} = ""; delete($options{"rw"});
1028                 }
1029         else {
1030                 # read-write
1031                 $options{"rw"} = ""; delete($options{"ro"});
1032                 }
1033         if ($in{jfs_nosuid}) {
1034                 # nosuid
1035                 $options{"nosuid"} = ""; delete($options{"suid"});
1036                 }
1037         else {
1038                 # suid
1039                 $options{"suid"} = ""; delete($options{"nosuid"});
1040                 }
1041         if ($in{jfs_log}) {
1042                 # log
1043                 $options{"log"} = ""; delete($options{"delaylog"});
1044                 }
1045         else {
1046                 # delaylog
1047                 $options{"delaylog"} = ""; delete($options{"log"});
1048                 }
1049         if ($in{jfs_syncw}) {
1050                 # datainlog
1051                 $options{"datainlog"} = ""; delete($options{"nodatainlog"});
1052                 }
1053         else {
1054                 # nodatainlog
1055                 $options{"nodatainlog"} = ""; delete($options{"datainlog"});
1056                 }
1057         if ($in{jfs_quota}) {
1058                 # quota
1059                 $options{"quota"} = "";
1060                 }
1061         else {
1062                 # noquota
1063                 delete($options{"quota"});
1064                 }
1065         }
1066 elsif ($_[0] eq "lofs") {
1067         if ($in{lofs_ro}) {
1068                 # read-only
1069                 $options{"ro"} = "";
1070                 }
1071         else {
1072                 # read-write
1073                 $options{"defaults"} = "";
1074                 }
1075         }
1076 elsif ($_[0] eq "swap") {
1077         $options{"pri"} = $in{swap_pri};
1078         }
1079 elsif ($_[0] eq "cdfs") {
1080         # read-only
1081         $options{"ro"} = "";
1082         if ($in{cdfs_nosuid}) {
1083                 # nosuid
1084                 $options{"nosuid"} = ""; delete($options{"suid"});
1085                 }
1086         else {
1087                 # suid
1088                 $options{"suid"} = ""; delete($options{"nosuid"});
1089                 }
1090         }
1091 elsif ($_[0] eq "tmpfs") {
1092         # Ram-disk filesystems have only one option
1093         delete($options{"size"});
1094         if (!$in{"tmpfs_size_def"}) {
1095                 $options{"size"} = "$in{tmpfs_size}$in{tmpfs_unit}";
1096                 }
1097         }
1098 elsif ($_[0] eq "swapfs") {
1099         # The caching filesystem has lots of options
1100         $options{"backfstype"} = $in{"cfs_backfstype"};
1101
1102         delete($options{"backpath"});
1103         if (!$in{"cfs_noback"}) {
1104                 # A back filesystem was given..  (alreadys checked)
1105                 $options{"backpath"} = $in{"cfs_backpath"};
1106                 }
1107
1108         if ($in{"cfs_cachedir"} !~ /^\/\S+/) {
1109                 &error("'$in{cfs_cachedir}' is not a valid cache directory");
1110                 }
1111         $options{"cachedir"} = $in{"cfs_cachedir"};
1112
1113         delete($options{"write-around"}); delete($options{"non-shared"});
1114         if ($in{"cfs_wmode"}) {
1115                 $options{"non-shared"} = "";
1116                 }
1117
1118         delete($options{"noconst"}); delete($options{"demandconst"});
1119         if ($in{"cfs_con"} == 0) { $options{"noconst"} = ""; }
1120         elsif ($in{"cfs_con"} == 2) { $options{"demandconst"} = ""; }
1121
1122         delete($options{"ro"}); delete($options{"rw"});
1123         if ($in{"cfs_ro"}) { $options{"ro"} = ""; }
1124
1125         delete($options{"suid"}); delete($options{"nosuid"});
1126         if ($in{"cfs_nosuid"}) { $options{"nosuid"} = ""; }
1127         }
1128 elsif ($_[0] eq "autofs") {
1129         # The options for autofs depend on the type of the automounted
1130         # filesystem.. 
1131         $options{"fstype"} = $in{"autofs_fstype"};
1132         return &check_options($options{"fstype"});
1133         }
1134
1135 # Return options string
1136 foreach $k (keys %options) {
1137         if ($options{$k} eq "") { push(@rv, $k); }
1138         else { push(@rv, "$k=$options{$k}"); }
1139         }
1140 return @rv ? join(',' , @rv) : "-";
1141 }
1142
1143
1144 # create_swap(path, size, units)
1145 # Attempt to create a swap file 
1146 sub create_swap
1147 {
1148 local($out);
1149 $out = &backquote_logged("mkfile $_[1]$_[2] $_[0] 2>&1");
1150 if ($?) {
1151         &unlink_file($_[0]);
1152         return "mkfile failed : $out";
1153         }
1154 return 0;
1155 }
1156
1157
1158 # exports_list(host, dirarray, clientarray)
1159 # Fills the directory and client array references with exports from some
1160 # host. Returns an error string if something went wrong
1161 sub exports_list
1162 {
1163 local($dref, $cref, $out, $_);
1164 $dref = $_[1]; $cref = $_[2];
1165 $out = &backquote_command("showmount -e ".quotemeta($_[0])." 2>&1", 1);
1166 if ($?) { return $out; }
1167 foreach (split(/\n/, $out)) {
1168         if (/^(\/\S*)\s+(.*)$/) {
1169                 push(@$dref, $1); push(@$cref, $2);
1170                 }
1171         }
1172 return undef;
1173 }
1174
1175 # broadcast_addr()
1176 # Returns a useable broadcast address for finding NFS servers
1177 sub broadcast_addr
1178 {
1179 local($out, $hostname, $broadcast, @tmp);
1180 $hostname = get_system_hostname();
1181 $out = &backquote_command("netstat -i 2>&1 | grep $hostname", 1);
1182 if ($out =~ /\s+(\S*)\s+(\S*)\s+(.*)/) {
1183         $broadcast = "$2.255.255.255";
1184         @tmp = split(/\./,$broadcast);
1185         $broadcast = "$tmp[0].$tmp[1].$tmp[2].$tmp[3]";
1186         return $broadcast;
1187         }
1188 return "255.255.255.255";
1189 }
1190
1191 sub device_name
1192 {
1193 return $_[0];
1194 }
1195
1196 sub files_to_lock
1197 {
1198 return ( $config{'fstab_file'} );
1199 }
1200
1201 1;