Handle hostnames with upper-case letters
[webmin.git] / mount / irix-lib.pl
1 # irix-lib.pl
2 # Filesystem functions for IRIX
3 # XXX logging and locking?
4
5 # Return information about a filesystem, in the form:
6 #  directory, device, type, options, fsck_order, mount_at_boot
7 # If a field is unused or ignored, a - appears instead of the value.
8 # Swap-filesystems (devices or files mounted for VM) have a type of 'swap',
9 # and 'swap' in the directory field
10 sub list_mounts
11 {
12 local(@rv, @p, $_, $i); $i = 0;
13 open(FSTAB, $config{'fstab_file'});
14 while(<FSTAB>) {
15         chop; s/#.*$//g;
16         if (!/\S/) { next; }
17         @p = split(/\s+/, $_);
18         $rv[$i] = [ $p[1], $p[0], $p[2] ];
19         $rv[$i]->[5] = "yes";
20         local @o = split(/,/ , $p[3] eq "defaults" ? "" : $p[3]);
21         if (($j = &indexof("noauto", @o)) >= 0) {
22                 # filesytem is not mounted at boot
23                 splice(@o, $j, 1);
24                 $rv[$i]->[5] = "no";
25                 }
26         $rv[$i]->[3] = (@o ? join(',' , @o) : "-");
27         $rv[$i]->[4] = (@p >= 5 ? $p[5] : 0);
28         $i++;
29         }
30 close(FSTAB);
31
32 # List automount points
33 open(AUTOTAB, $config{'autofs_file'});
34 while(<AUTOTAB>) {
35         chop; s/#.*$//g;
36         if (!/\S/ || /^[+\-]/) { next; }
37         @p = split(/\s+/, $_);
38         if ($p[2] eq "") { $p[2] = "-"; }
39         else { $p[2] =~ s/^-//g; }
40         $rv[$i++] = [ $p[0], $p[1], "autofs", $p[2], "-", "yes" ];
41         }
42 close(AUTOTAB);
43
44 return @rv;
45 }
46
47
48 # create_mount(directory, device, type, options, fsck_order, mount_at_boot)
49 # Add a new entry to the fstab file, and return the index of the new entry
50 sub create_mount
51 {
52 local($len, @mlist, $fcsk, $dir);
53 if ($_[2] eq "autofs") {
54         # An autofs mount.. add to /etc/auto_master
55         $len = grep { $_->[2] eq "autofs" } (&list_mounts());
56         &open_tempfile(AUTOTAB, ">> $config{autofs_file}");
57         &print_tempfile(AUTOTAB, "$_[0] $_[1]",($_[3] eq "-" ? "" : " -$_[3]"),"\n");
58         &close_tempfile(AUTOTAB);
59         &system_logged("autofs -r >/dev/null 2>&1 </dev/null");
60         }
61 else {
62         # Add to the fstab file
63         $len = grep { $_->[2] ne "autofs" } (&list_mounts());
64         &open_tempfile(FSTAB, ">> $config{fstab_file}");
65         &print_tempfile(FSTAB, "$_[1]  $_[0]  $_[2]");
66         local $opts = $_[3] eq "-" ? "" : $_[3];
67         if ($_[5] eq "no") {
68                 $opts = join(',' , (split(/,/ , $opts) , "noauto"));
69                 }
70         if ($opts eq "") {
71                 &print_tempfile(FSTAB, "  defaults");
72                 }
73         else {
74                 &print_tempfile(FSTAB, "  $opts");
75                 }
76         &print_tempfile(FSTAB, "  0  ");
77         &print_tempfile(FSTAB, $_[4] eq "-" ? "0\n" : "$_[4]\n");
78         &close_tempfile(FSTAB);
79         }
80 return $len;
81 }
82
83
84 # delete_mount(index)
85 # Delete some mount from the table
86 sub delete_mount
87 {
88 local(@fstab, @autotab, $i, $line, $_);
89 open(FSTAB, $config{fstab_file});
90 @fstab = <FSTAB>;
91 close(FSTAB);
92 $i = 0;
93
94 &open_tempfile(FSTAB, "> $config{fstab_file}");
95 foreach (@fstab) {
96         chop; ($line = $_) =~ s/#.*$//g;
97         if ($line =~ /\S/ && $i++ == $_[0]) {
98                 # found the line not to include
99                 }
100         else {
101                 &print_tempfile(FSTAB, $_,"\n");
102                 }
103         }
104 &close_tempfile(FSTAB);
105
106 local $found;
107 open(AUTOTAB, $config{autofs_file});
108 @autotab = <AUTOTAB>;
109 close(AUTOTAB);
110 &open_tempfile(AUTOTAB, "> $config{autofs_file}");
111 foreach (@autotab) {
112         chop; ($line = $_) =~ s/#.*$//g;
113         if ($line =~ /\S/ && $line !~ /^[+\-]/ && $i++ == $_[0]) {
114                 # found line not to include..
115                 $line =~ /^(\S+)/;
116                 $found = $1;
117                 }
118         else {
119                 &print_tempfile(AUTOTAB, $_,"\n");
120                 }
121         }
122 &close_tempfile(AUTOTAB);
123 if ($found) {
124         &system_logged("autofs -r >/dev/null 2>&1 </dev/null");
125         &system_logged("umount $found >/dev/null 2>&1 </dev/null");
126         }
127 }
128
129
130 # change_mount(num, directory, device, type, options, fsck_order, mount_at_boot)
131 # Change an existing permanent mount
132 sub change_mount
133 {
134 local(@fstab, @autotab, $i, $line, $fsck, $dir, $_);
135 $i = 0;
136
137 open(FSTAB, $config{fstab_file});
138 @fstab = <FSTAB>;
139 close(FSTAB);
140 &open_tempfile(FSTAB, "> $config{fstab_file}");
141 foreach (@fstab) {
142         chop; ($line = $_) =~ s/#.*$//g;
143         if ($line =~ /\S/ && $i++ == $_[0]) {
144                 # Found the line to replace
145                 &print_tempfile(FSTAB, "$_[2]  $_[1]  $_[3]");
146                 local $opts = $_[4] eq "-" ? "" : $_[4];
147                 if ($_[6] eq "no") {
148                         $opts = join(',' , (split(/,/ , $opts) , "noauto"));
149                         }
150                 if ($opts eq "") {
151                         &print_tempfile(FSTAB, "  defaults");
152                         }
153                 else {
154                         &print_tempfile(FSTAB, "  $opts");
155                         }
156                 &print_tempfile(FSTAB, "  0  ");
157                 &print_tempfile(FSTAB, $_[5] eq "-" ? "0\n" : "$_[5]\n");
158                 }
159         else {
160                 &print_tempfile(FSTAB, $_,"\n");
161                 }
162         }
163 &close_tempfile(FSTAB);
164
165 local $found;
166 open(AUTOTAB, $config{autofs_file});
167 @autotab = <AUTOTAB>;
168 close(AUTOTAB);
169 &open_tempfile(AUTOTAB, "> $config{autofs_file}");
170 foreach (@autotab) {
171         chop; ($line = $_) =~ s/#.*$//g;
172         if ($line =~ /\S/ && $line !~ /^[+\-]/ && $i++ == $_[0]) {
173                 # Found the line to replace
174                 &print_tempfile(AUTOTAB, "$_[1]  $_[2]  ",
175                                 ($_[4] eq "-" ? "" : "-$_[4]"),"\n");
176                 $found++;
177                 }
178         else {
179                 &print_tempfile(AUTOTAB, $_,"\n");
180                 }
181         }
182 &close_tempfile(AUTOTAB);
183 if ($found) {
184         &system_logged("autofs -r >/dev/null 2>&1 </dev/null");
185         }
186 }
187
188
189 # list_mounted()
190 # Return a list of all the currently mounted filesystems and swap files.
191 # The list is in the form:
192 #  directory device type options
193 # For swap files, the directory will be 'swap'
194 sub list_mounted
195 {
196 local(@rv, @p, $_, $i, $r);
197 &open_execute_command(SWAP, "swap -l 2>/dev/null", 1, 1);
198 while(<SWAP>) {
199         if (/^\s*\d+\s+(\/\S+)/) {
200                 push(@rv, [ "swap", $1, "swap", "-" ]);
201                 }
202         }
203 close(SWAP);
204 open(MTAB, "/etc/mtab");
205 while(<MTAB>) {
206         s/#.*$//g; if (!/\S/) { next; }
207         @p = split(/\s+/, $_);
208         push(@rv, [ $p[1], $p[0], $p[2], $p[3] ]);
209         }
210 close(MTAB);
211 return @rv;
212 }
213
214
215 # mount_dir(directory, device, type, options)
216 # Mount a new directory from some device, with some options. Returns 0 if ok,
217 # or an error string if failed. If the directory is 'swap', then mount as
218 # virtual memory.
219 sub mount_dir
220 {
221 local($out, $opts);
222 if ($_[2] eq "swap") {
223         # Adding a swap device
224         $out = &backquote_logged("swap -a $_[1] 2>&1");
225         if ($?) { return $out; }
226         }
227 elsif ($_[2] eq "autofs") {
228         # Do nothing, because autofs -r will be run after the auto_master file
229         # is updated.
230         }
231 else {
232         # Mounting a directory
233         $opts = $_[3] eq "-" ? "" : "-o \"$_[3]\"";
234         $out = &backquote_logged("mount -t $_[2] $opts $_[1] $_[0] 2>&1");
235         if ($?) { return $out; }
236         }
237 return 0;
238 }
239
240
241 # unmount_dir(directory, device, type)
242 # Unmount a directory (or swap device) that is currently mounted. Returns 0 if
243 # ok, or an error string if failed
244 sub unmount_dir
245 {
246 if ($_[2] eq "swap") {
247         $out = &backquote_logged("swap -d $_[1] 2>&1");
248         }
249 elsif ($_[2] eq "autofs") {
250         # Do nothing - see the comment in mount_dir
251         return 0;
252         }
253 else {
254         $out = &backquote_logged("umount $_[0] 2>&1");
255         }
256 if ($?) { return $out; }
257 return 0;
258 }
259
260
261 # disk_space(type, directory)
262 # Returns the amount of total and free space for some filesystem, or an
263 # empty array if not appropriate.
264 sub disk_space
265 {
266 if (&get_mounted($_[1], "*") < 0) { return (); }
267 if ($_[0] eq "fd" || $_[0] eq "proc" || $_[0] eq "swap" || $_[0] eq "autofs") {
268         return ();
269         }
270 if (&backquote_command("df -k ".quotemeta($_[1]), 1) =~
271     /Mounted on\n\S+\s+\S+\s+(\S+)\s+\S+\s+(\S+)/) {
272         return ($1, $2);
273         }
274 else {
275         return ( );
276         }
277 }
278
279
280 # list_fstypes()
281 # Returns an array of all the supported filesystem types. If a filesystem is
282 # found that is not one of the supported types, generate_location() and
283 # generate_options() will not be called for it.
284 sub list_fstypes
285 {
286 return ("xfs","efs","nfs","iso9660","dos","autofs","swap");
287 }
288
289
290 # fstype_name(type)
291 # Given a short filesystem type, return a human-readable name for it
292 sub fstype_name
293 {
294 local(%fsmap);
295 %fsmap = ("xfs","SGI Filesystem",
296           "nfs","Network Filesystem",
297           "cachefs","Caching Filesystem",
298           "iso9660","ISO9660 CD-ROM",
299           "dos","MS-DOS Filesystem",
300           "efs","Old SGI Filesystem",
301           "fd","File Descriptor Filesystem",
302           "hfs","Macintosh Filesystem",
303           "kfs","AppleShare Filesystem",
304           "proc","Process Image Filesystem",
305           "hwgfs","Hardware Configuration Filesystem",
306           "autofs","Automounter Filesystem",
307           "nfs3","NIS Maps Filesystem",
308           "swap","Virtual Memory");
309 return $config{long_fstypes} && $fsmap{$_[0]} ? $fsmap{$_[0]} : uc($_[0]);
310 }
311
312
313 # mount_modes(type, dir, device)
314 # Given a filesystem type, returns 5 numbers that determine how the file
315 # system can be mounted, and whether it can be fsck'd
316 sub mount_modes
317 {
318 if ($_[0] eq "swap") {
319         return $_[2] eq "/dev/swap" ? (1, 0, 0, 0, 1) : (1, 1, 0, 0);
320         }
321 elsif ($_[0] eq "fd" || $_[0] eq "proc" || $_[0] eq "hwgfs" ||
322        $_[0] eq "nfs3") {
323         return (1, 0, 0, 1);
324         }
325 elsif ($_[0] eq "xfs" || $_[0] eq "efs" || $_[0] eq "cachefs") {
326         return (2, 1, 1, 0);
327         }
328 elsif ($_[0] eq "autofs") {
329         return (1, 0, 0, 0);
330         }
331 else {
332         return (2, 1, 0, 0);
333         }
334 }
335
336 # multiple_mount(type)
337 # Returns 1 if filesystems of this type can be mounted multiple times, 0 if not
338 sub multiple_mount
339 {
340 return ($_[0] eq "nfs" || $_[0] eq "kfs" || $_[0] eq "cachefs");
341 }
342
343
344 # generate_location(type, location)
345 # Output HTML for editing the mount location of some filesystem.
346 sub generate_location
347 {
348 if ($_[0] eq "nfs") {
349         # NFS mount from some host and directory
350         local ($nfshost, $nfspath) = $_[1] =~ /^([^:]+):(.*)/ ? ( $1, $2 ) : ();
351         print "<tr> <td><b>$text{'irix_nhost'}</b></td>\n";
352         print "<td><input name=nfs_host size=20 value=\"$nfshost\">\n";
353         &nfs_server_chooser_button("nfs_host");
354         print "</td>\n";
355         print "<td><b>$text{'irix_ndir'}</b></td>\n";
356         print "<td><input name=nfs_dir size=20 value=\"$nfspath\">\n";
357         &nfs_export_chooser_button("nfs_host", "nfs_dir");
358         print "</td> </tr>\n";
359         }
360 elsif ($_[0] eq "autofs") {
361         # Selecting an automounter map
362         print "<tr> <td valign=top><b>$text{'irix_auto'}</b></td>\n";
363         print "<td colspan=3>\n";
364         printf "<input type=radio name=auto_mode value=0 %s> %s<br>\n",
365                 $_[1] eq "-hosts" ? "checked" : "", $text{'irix_autohosts'};
366         printf "<input type=radio name=auto_mode value=1 %s> %s\n",
367                 $_[1] eq "-hosts" ? "" : "checked", $text{'irix_automap'};
368         printf "<input name=auto_map size=30 value='%s'><br>\n",
369                 $_[1] eq "-hosts" ? "" : $_[1];
370         }
371 elsif ($_[0] eq "iso9660") {
372         # Selecting an entire SCSI disk
373         print "<tr> <td valign=top><b>$text{'irix_cd'}</b></td>\n";
374         print "<td colspan=3>\n";
375         local ($mode, $ctrlr, $drive, $other);
376         if ($_[1] =~ /^\/dev\/rdsk\/dks(\d+)d(\d+)vol$/) {
377                 $mode = 0;
378                 $ctrlr = $1;
379                 $drive = $2;
380                 }
381         elsif ($_[1]) {
382                 $mode = 1;
383                 $other = $_[1];
384                 }
385         printf "<input type=radio name=irix_mode value=0 %s>\n",
386                 $mode == 0 ? "checked" : "";
387         print &text('irix_mode0cd',
388                     "<input name=irix_ctrlr size=2 value='$ctrlr'>",
389                     "<input name=irix_drive size=2 value='$drive'>"),"<br>\n";
390         printf "<input type=radio name=irix_mode value=1 %s> %s\n",
391                 $mode == 1 ? "checked" : "", $text{'irix_mode1'};
392         printf "<input name=irix_other size=30 value='%s'><br>\n",
393                 $mode == 1 ? $other : "";
394         print "</td> </tr>\n";
395
396         }
397 else {
398         # Mounting some local disk (or file)
399         print "<tr> <td valign=top><b>$text{'irix_part'}</b></td>\n";
400         print "<td colspan=3>\n";
401         local ($mode, $ctrlr, $drive, $part, $other);
402         if ($_[1] =~ /^\/dev\/dsk\/dks(\d+)d(\d+)s(\d+)$/) {
403                 $mode = 0;
404                 $ctrlr = $1;
405                 $drive = $2;
406                 $part = $3;
407                 }
408         elsif ($_[1]) {
409                 $mode = 1;
410                 $other = $_[1];
411                 }
412         printf "<input type=radio name=irix_mode value=0 %s>\n",
413                 $mode == 0 ? "checked" : "";
414         local ($sel, $currctrlr, $currdrive);
415         open(VTOC, "prtvtoc -a |");
416         while(<VTOC>) {
417                 if (/^\/dev\/rdsk\/dks(\d+)d(\d+)vh/) {
418                         $currctrlr = $1;
419                         $currdrive = $2;
420                         }
421                 elsif (/^\/dev/) {
422                         undef($currctrlr);
423                         }
424                 elsif (/^\s*(\d+)\s+(\d+)\s+(\d+)/ && defined($currctrlr)) {
425                         $sel .= sprintf "<option value=%s %s>%s\n",
426                                 "/dev/dsk/dks${currctrlr}d${currdrive}s$1",
427                                 $currctrlr == $ctrlr && $currdrive == $drive &&
428                                 $1 == $part ? "selected" : "",
429                                 &text('irix_mode0', $currctrlr,$currdrive,"$1");
430                         }
431                 }
432         close(VTOC);
433         if ($sel) {
434                 print "<select name=irix_sel>\n";
435                 print $sel;
436                 print "</select>\n";
437                 }
438         else {
439                 print &text('irix_mode0',
440                             "<input name=irix_ctrlr size=2 value='$ctrlr'>",
441                             "<input name=irix_drive size=2 value='$drive'>",
442                             "<input name=irix_part size=2 value='$part'>"),"\n";
443                 }
444         print "<br>\n";
445         printf "<input type=radio name=irix_mode value=1 %s> %s\n",
446                 $mode == 1 ? "checked" : "", $text{'irix_mode1'};
447         printf "<input name=irix_other size=30 value='%s'><br>\n",
448                 $mode == 1 ? $other : "";
449         print "</td> </tr>\n";
450         }
451 }
452
453
454 # generate_options(type, newmount)
455 # Output HTML for editing mount options for a partilcar filesystem 
456 # under this OS
457 sub generate_options
458 {
459 if ($_[0] ne "swap") {
460         # All filesystem types have these options
461         print "<tr> <td><b>$text{'irix_ro'}</b></td>\n";
462         printf "<td nowrap><input type=radio name=irix_ro value=1 %s> Yes\n",
463                 defined($options{"ro"}) ? "checked" : "";
464         printf "<input type=radio name=irix_ro value=0 %s> No</td>\n",
465                 defined($options{"ro"}) ? "" : "checked";
466
467         print "<td><b>$text{'irix_nosuid'}</b></td>\n";
468         printf "<td nowrap><input type=radio name=irix_nosuid value=1 %s> Yes\n",
469                 defined($options{"nosuid"}) ? "checked" : "";
470         printf "<input type=radio name=irix_nosuid value=0 %s> No</td> </tr>\n",
471                 defined($options{"nosuid"}) ? "" : "checked";
472
473         print "<tr> <td><b>$text{'irix_grpid'}</b></td>\n";
474         printf "<td nowrap><input type=radio name=irix_grpid value=0 %s> Yes\n",
475                 defined($options{"grpid"}) ? "" : "checked";
476         printf "<input type=radio name=irix_grpid value=1 %s> No</td>\n",
477                 defined($options{"grpid"}) ? "checked" : "";
478
479         print "<td><b>$text{'irix_nodev'}</b></td>\n";
480         printf "<td nowrap><input type=radio name=irix_nodev value=1 %s> Yes\n",
481                 defined($options{"nodev"}) ? "checked" : "";
482         printf "<input type=radio name=irix_nodev value=0 %s> No</td> </tr>\n",
483                 defined($options{"nodev"}) ? "" : "checked";
484         }
485 else {
486         # No options available for swap
487         print "<tr> <td><i>$text{'irix_noopts'}</i></td> </tr>\n";
488         }
489
490 if ($_[0] eq "nfs") {
491         # Irix NFS
492         print "<tr> <td><b>$text{'irix_bg'}</b></td>\n";
493         printf "<td nowrap><input type=radio name=nfs_bg value=1 %s> Yes\n",
494                 defined($options{"bg"}) ? "checked" : "";
495         printf "<input type=radio name=nfs_bg value=0 %s> No</td>\n",
496                 defined($options{"bg"}) ? "" : "checked";
497
498         print "<td><b>$text{'irix_soft'}</b></td>\n";
499         printf "<td nowrap><input type=radio name=nfs_soft value=1 %s> Yes\n",
500                 defined($options{"soft"}) ? "checked" : "";
501         printf "<input type=radio name=nfs_soft value=0 %s> No</td> </tr>\n",
502                 defined($options{"soft"}) ? "" : "checked";
503
504         print "<tr> <td><b>$text{'irix_nointr'}</b></td>\n";
505         printf "<td nowrap><input type=radio name=nfs_nointr value=0 %s> Yes\n",
506                 defined($options{"nointr"}) ? "" : "checked";
507         printf "<input type=radio name=nfs_nointr value=1 %s> No</td>\n",
508                 defined($options{"nointr"}) ? "checked" : "";
509
510         print "<td><b>$text{'irix_version'}</b></td>\n";
511         printf "<td nowrap><input type=radio name=nfs_vers_def value=1 %s> %s\n",
512                 defined($options{"vers"}) ? "" : "checked", $text{'default'};
513         printf "<input type=radio name=nfs_vers_def value=0 %s>\n",
514                 defined($options{"vers"}) ? "checked" : "";
515         print "<input size=2 name=nfs_vers value='$options{vers}'></td></tr>\n";
516
517         print "<tr> <td><b>$text{'irix_proto'}</b></td>\n";
518         print "<td nowrap><select name=proto>\n";
519         printf "<option value=\"\" %s> Default\n",
520                 defined($options{"proto"}) ? "" : "selected";
521         printf "<option value=tcp %s> TCP\n",
522                 $options{"proto"} eq "tcp" ? "selected" : "";
523         printf "<option value=udp %s> UDP\n",
524                 $options{"proto"} eq "udp" ? "selected" : "";
525         print "</select></td>\n";
526
527         print "<td><b>$text{'irix_port'}</b></td>\n";
528         printf "<td nowrap><input type=radio name=nfs_port_def value=1 %s> %s\n",
529                 defined($options{"port"}) ? "" : "checked", $text{'default'};
530         printf "<input type=radio name=nfs_port_def value=0 %s>\n",
531                 defined($options{"port"}) ? "checked" : "";
532         print "<input size=5 name=nfs_port value='$options{port}'></td></tr>\n";
533
534         print "<tr> <td><b>$text{'irix_timeo'}</b></td>\n";
535         printf "<td nowrap><input type=radio name=nfs_timeo_def value=1 %s> %s\n",
536                 defined($options{"timeo"}) ? "" : "checked", $text{'default'};
537         printf "<input type=radio name=nfs_timeo_def value=0 %s>\n",
538                 defined($options{"timeo"}) ? "checked" : "";
539         printf "<input size=5 name=nfs_timeo value='$options{timeo}'></td>\n";
540
541         print "<td><b>$text{'irix_retrans'}</b></td>\n";
542         printf "<td nowrap><input type=radio name=nfs_retrans_def value=1 %s> %s\n",
543                 defined($options{"retrans"}) ? "" : "checked", $text{'default'};
544         printf "<input type=radio name=nfs_retrans_def value=0 %s>\n",
545                 defined($options{"retrans"}) ? "checked" : "";
546         print "<input size=5 name=nfs_retrans value='$options{retrans}'></td> </tr>\n";
547
548         print "</tr>\n";
549
550         print "<tr> <td><b>$text{'irix_quota'}</b></td>\n";
551         printf "<td nowrap><input type=radio name=nfs_quota value=1 %s> %s\n",
552                 defined($options{"quota"}) ? "checked" : "", $text{'yes'};
553         printf "<input type=radio name=nfs_quota value=0 %s> %s</td>\n",
554                 defined($options{"quota"}) ? "" : "checked", $text{'no'};
555
556         print "</tr>\n";
557         }
558 elsif ($_[0] eq "xfs") {
559         # Irix XFS options
560         print "<tr> <td><b>$text{'irix_noatime'}</b></td>\n";
561         printf "<td nowrap><input type=radio name=xfs_noatime value=0 %s> %s\n",
562                 defined($options{"noatime"}) ? "" : "checked", $text{'yes'};
563         printf "<input type=radio name=xfs_noatime value=1 %s> %s</td>\n",
564                 defined($options{"noatime"}) ? "checked" : "", $text{'no'};
565
566         print "<td><b>$text{'irix_wsync'}</b></td>\n";
567         printf "<td nowrap><input type=radio name=xfs_wsync value=1 %s> %s\n",
568                 defined($options{"wsync"}) ? "checked" : "", $text{'yes'};
569         printf "<input type=radio name=xfs_wsync value=0 %s> %s</td> </tr>\n",
570                 defined($options{"wsync"}) ? "" : "checked", $text{'no'};
571
572         local $qm = defined($options{"qnoenforce"}) ? 2 :
573                     defined($options{"quota"}) ? 1 : 0;
574         print "<tr> <td><b>$text{'irix_quota'}</b></td> <td colspan=3>\n";
575         printf "<input type=radio name=xfs_quota value=1 %s> %s\n",
576                 $qm == 1 ? "checked" : "", $text{'yes'};
577         printf "<input type=radio name=xfs_quota value=2 %s> %s\n",
578                 $qm == 2 ? "checked" : "", $text{'irix_quotano'};
579         printf "<input type=radio name=xfs_quota value=0 %s> %s</td> </tr>\n",
580                 $qm == 0 ? "checked" : "", $text{'no'};
581         }
582 elsif ($_[0] eq "efs") {
583         # Irix EFS (old filesystem) options
584         print "<tr> <td><b>$text{'irix_quota'}</b></td>\n";
585         printf "<td nowrap><input type=radio name=efs_quota value=1 %s> %s\n",
586                 defined($options{"quota"}) ? "checked" : "", $text{'yes'};
587         printf "<input type=radio name=efs_quota value=0 %s> %s</td>\n",
588                 defined($options{"quota"}) ? "" : "checked", $text{'no'};
589
590         print "<td><b>$text{'irix_nofsck'}</b></td>\n";
591         printf "<td nowrap><input type=radio name=efs_nofsck value=0 %s> %s\n",
592                 defined($options{"nofsck"}) ? "" : "checked", $text{'yes'};
593         printf "<input type=radio name=efs_nofsck value=1 %s> %s</td> </tr>\n",
594                 defined($options{"nofsck"}) ? "checked" : "", $text{'no'};
595         }
596 elsif ($_[0] eq "dos") {
597         # There are no additional dos vfat options
598         }
599 elsif ($_[0] eq "iso9660") {
600         # Irix CD-ROM filesystem options
601         print "<tr> <td><b>$text{'irix_setx'}</b></td>\n";
602         printf "<td nowrap><input type=radio name=iso_setx value=1 %s> %s\n",
603                 defined($options{"setx"}) ? "checked" : "", $text{'yes'};
604         printf "<input type=radio name=iso_setx value=0 %s> %s</td>\n",
605                 defined($options{"setx"}) ? "" : "checked", $text{'no'};
606
607         local $rock = !defined($options{"norrip"}) &&
608                       !defined($options{"noext"});
609         print "<td><b>$text{'irix_rock'}</b></td>\n";
610         printf "<td nowrap><input type=radio name=iso_rock value=1 %s> %s\n",
611                 $rock ? "checked" : "", $text{'yes'};
612         printf "<input type=radio name=iso_rock value=0 %s> %s</td> </tr>\n",
613                 $rock ? "" : "checked", $text{'no'};
614         }
615 elsif ($_[0] eq "autofs") {
616         # Irix automounter options
617         }
618 }
619
620 # check_location(type)
621 # Parse and check inputs from %in, calling &error() if something is wrong.
622 # Returns the location string for storing in the fstab file
623 sub check_location
624 {
625 if ($_[0] eq "nfs") {
626         # Use ping and showmount to see if the host exists and is up
627         local $out = &backquote_command("ping -c 1 '$in{nfs_host}' 2>&1");
628         if ($out =~ /unknown host/i) {
629                 &error(&text('irix_ehost', $in{'nfs_host'}));
630                 }
631         elsif ($out =~ /100\% packet loss/) {
632                 &error(&text('irix_eloss', $in{'nfs_host'}));
633                 }
634         $out = &backquote_command("showmount -e '$in{nfs_host}' 2>&1");
635         if ($out =~ /port mapper failure/i) {
636                 &error(&text('irix_eshowmount', $in{'nfs_host'}));
637                 }
638         elsif ($?) {
639                 &error(&text('irix_emountlist', "<pre>$out</pre>"));
640                 }
641
642         # Validate directory name
643         foreach (split(/\n/, $out)) {
644                 if (/^(\/\S+)/) { $dirlist .= "$1\n"; }
645                 }
646         if ($in{'nfs_dir'} !~ /^\/\S+$/) {
647                 &error(&text('irix_edirlist', $in{'nfs_dir'}, $in{'nfs_host'},
648                                               "<pre>$dirlist</pre>"));
649                 }
650
651         # Try a test mount to see if filesystem is available
652         local $temp = &transname();
653         &make_dir($temp, 0755);
654         local $mout;
655         &execute_command("mount $in{'nfs_host'}:$in{'nfs_dir'} $temp 2>&1",
656                          undef, \$mout, \$mout);
657         if ($mout =~ /No such file or directory/i) {
658                 &error(&text('irix_enotexist', $in{'nfs_dir'}, $in{'nfs_host'},
659                              "<pre>$dirlist</pre>"));
660                 }
661         elsif ($mout =~ /Permission denied/i) {
662                 &error(&text('irix_epermission', $in{'nfs_dir'},
663                              $in{'nfs_host'}));
664                 }
665         elsif ($?) {
666                 &error(&text('irix_enfserr', $mout));
667                 }
668         # It worked! unmount
669         &execute_command("umount $temp");
670         &unlink_file($temp);
671         return "$in{nfs_host}:$in{nfs_dir}";
672         }
673 elsif ($_[0] eq "autofs") {
674         # Check automounter map
675         if ($in{'auto_mode'} == 0) {
676                 return "-hosts";
677                 }
678         else {
679                 $in{'auto_map'} =~ /^\S+$/ || &error($text{'irix_eautomap2'});
680                 $in{'auto_map'} =~ /^\// && !-r $in{'auto_map'} &&
681                         &error(&text('irix_eautomap', $in{'auto_map'}));
682                 return $in{'auto_map'};
683                 }
684         }
685 else {
686         # Get the device name
687         local $dv;
688         if ($in{'irix_mode'} == 0 && defined($in{'irix_sel'})) {
689                 $dv = $in{'irix_sel'};
690                 }
691         elsif ($in{'irix_mode'} == 0) {
692                 $in{'irix_ctrlr'} =~ /^\d+$/ ||
693                         &error(&text('irix_ectrlr', $in{'irix_ctrlr'}));
694                 $in{'irix_drive'} =~ /^\d+$/ ||
695                         &error(&text('irix_edrive', $in{'irix_drive'}));
696                 if ($_[0] eq "iso9660") {
697                         $dv = "/dev/rdsk/dks$in{'irix_ctrlr'}d$in{'irix_drive'}vol";
698                         }
699                 else {
700                         $in{'irix_part'} =~ /^\d+$/ ||
701                                 &error(&text('irix_epart', $in{'irix_part'}));
702                         $dv = "/dev/dsk/dks$in{'irix_ctrlr'}d$in{'irix_drive'}s$in{'irix_part'}";
703                         }
704                 }
705         else {
706                 $dv = $in{'irix_other'};
707                 }
708
709         # Check the filesystem type
710         if ($_[0] eq "xfs" || $_[0] eq "efs") {
711                 local $out = &backquote_command("fstyp '$dv' 2>&1");
712                 $out =~ s/[^A-Za-z0-9]//g;
713                 if ($?) {
714                         &error(&text('irix_efstyp2', $dv, $out));
715                         }
716                 elsif ($out ne $_[0]) {
717                         &error(&text('irix_efstyp', $dv, $out, $_[0]));
718                         }
719                 }
720
721         # Check if the file exists
722         if (!-r $dv) {
723                 if ($_[0] eq "swap") {
724                         if ($dv =~ /^\/dev/) {
725                                 &error(&text('solaris_eswapfile', $dv));
726                                 }
727                         else {
728                                 &swap_form($dv);
729                                 }
730                         }
731                 else {
732                         &error(&text('irix_edevice', $dv));
733                         }
734                 }
735         return $dv;
736         }
737 }
738
739
740 # check_options(type)
741 # Read options for some filesystem from %in, and use them to update the
742 # %options array. Options handled by the user interface will be set or
743 # removed, while unknown options will be left untouched.
744 sub check_options
745 {
746 local($k, @rv);
747
748 # Parse options common to all Irix filesystems
749 if ($_[0] ne "swap") {
750         if ($in{'irix_ro'}) {
751                 # Read-only
752                 $options{"ro"} = "";
753                 delete($options{"rw"});
754                 }
755         else {
756                 # Read-write
757                 $options{"rw"} = "";
758                 delete($options{"ro"});
759                 }
760
761         delete($options{"nosuid"}); delete($options{"suid"});
762         if ($in{'irix_nosuid'}) { $options{"nosuid"} = ""; }
763
764         delete($options{"grpid"});
765         if ($in{'irix_grpid'}) { $options{"grpid"} = ""; }
766
767         delete($options{"nodev"}); delete($options{"dev"});
768         if ($in{'irix_nodev'}) { $options{"nodev"} = ""; }
769         }
770
771 if ($_[0] eq "nfs") {
772         # Parse Irix NFS options
773         delete($options{"bg"}); delete($options{"fg"});
774         if ($in{nfs_bg}) { $options{"bg"} = ""; }
775
776         delete($options{"soft"}); delete($options{"hard"});
777         if ($in{nfs_soft}) { $options{"soft"} = ""; }
778
779         delete($options{"intr"}); delete($options{"nointr"});
780         if ($in{nfs_nointr}) { $options{"nointr"} = ""; }
781
782         delete($options{"vers"});
783         if (!$in{nfs_vers_def}) { $options{"vers"} = $in{nfs_vers}; }
784
785         delete($options{"proto"});
786         if ($in{nfs_proto} ne "") { $options{"proto"} = $in{nfs_proto}; }
787
788         delete($options{"port"});
789         if (!$in{nfs_port_def}) { $options{"port"} = $in{nfs_port}; }
790
791         delete($options{"timeo"});
792         if (!$in{nfs_timeo_def}) { $options{"timeo"} = $in{nfs_timeo}; }
793
794         delete($options{"retrans"});
795         if (!$in{nfs_retrans_def}) { $options{"retrans"} = $in{nfs_retrans};}
796
797         delete($options{"quota"});
798         if ($in{'nfs_quota'}) { $options{"quota"} = ""; }
799         }
800 elsif ($_[0] eq "xfs") {
801         # Parse Irix XFS options
802         delete($options{"noatime"});
803         if ($in{'xfs_noatime'}) { $options{"noatime"} = ""; }
804
805         delete($options{"wsync"});
806         if ($in{'xfs_wsync'}) { $options{"wsync"} = ""; }
807
808         delete($options{"quota"}); delete($options{"qnoenforce"});
809         if ($in{'xfs_quota'} == 2) { $options{"qnoenforce"} = ""; }
810         elsif ($in{'xfs_quota'} == 1) { $options{"quota"} = ""; }
811         }
812 elsif ($_[0] eq "iso9660") {
813         # Parse Irix ISO9660 options
814         delete($options{"setx"});
815         if ($in{'iso_setx'}) { $options{"setx"} = ""; }
816
817         delete($options{"norrip"}); delete($options{"rrip"});
818         delete($options{"noext"});
819         if (!$in{'iso_rock'}) { $options{"noext"} = ""; }
820         }
821
822 # Return options string
823 foreach $k (keys %options) {
824         if ($options{$k} eq "") { push(@rv, $k); }
825         else { push(@rv, "$k=$options{$k}"); }
826         }
827 return @rv ? join(',' , @rv) : "-";
828 }
829
830
831 # create_swap(path, size, units)
832 # Attempt to create a swap file 
833 sub create_swap
834 {
835 local($out);
836 $out = &backquote_logged("mkfile $_[1]$_[2] $_[0] 2>&1");
837 if ($?) {
838         &unlink_file($_[0]);
839         return "mkfile failed : $out";
840         }
841 return 0;
842 }
843
844
845 # exports_list(host, dirarray, clientarray)
846 # Fills the directory and client array references with exports from some
847 # host. Returns an error string if something went wrong
848 sub exports_list
849 {
850 local($dref, $cref, $out, $_);
851 $dref = $_[1]; $cref = $_[2];
852 $out = &backquote_command("showmount -e ".quotemeta($_[0]), 1);
853 if ($?) { return $out; }
854 foreach (split(/\n/, $out)) {
855         if (/^(\/\S*)\s+(.*)$/) {
856                 push(@$dref, $1); push(@$cref, $2);
857                 }
858         }
859 return undef;
860 }
861
862 # broadcast_addr()
863 # Returns a useable broadcast address for finding NFS servers
864 sub broadcast_addr
865 {
866 local($out);
867 $out = &backquote_command("ifconfig -a 2>&1", 1);
868 if ($out =~ /broadcast\s+(\S+)/) { return $1; }
869 return "255.255.255.255";
870 }
871
872 sub device_name
873 {
874 return $_[0] eq "/dev/root" ? $text{'irix_devroot'} :
875        $_[0] eq "/dev/swap" ? $text{'irix_devswap'} :
876        $_[0] eq "-hosts" ? $text{'irix_autohosts'} :
877        $_[0] =~ /^\/dev\/r?dsk\/dks(\d+)d(\d+)s(\d+)$/ ?
878         &text('irix_mode0', "$1", "$2", "$3") :
879        $_[0] =~ /^\/dev\/r?dsk\/dks(\d+)d(\d+)vol$/ ?
880         &text('irix_mode0cd', "$1", "$2", "$3") :
881         $_[0];
882 }
883
884 sub files_to_lock
885 {
886 return ( $config{'fstab_file'} );
887 }
888
889 1;