2
#-*- Mode: perl; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
4
# Working with filesystems, both local and networked.
6
# Copyright (C) 2000-2001 Ximian, Inc.
8
# Authors: Hans Petter Jansson <hpj@ximian.com>
10
# This program is free software; you can redistribute it and/or modify
11
# it under the terms of the GNU Library General Public License as published
12
# by the Free Software Foundation; either version 2 of the License, or
13
# (at your option) any later version.
15
# This program is distributed in the hope that it will be useful,
16
# but WITHOUT ANY WARRANTY; without even the implied warranty of
17
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
# GNU Library General Public License for more details.
20
# You should have received a copy of the GNU Library General Public License
21
# along with this program; if not, write to the Free Software
22
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
25
$SCRIPTSDIR = "@scriptsdir@";
26
if ($SCRIPTSDIR =~ /^@scriptsdir[@]/)
32
require "$SCRIPTSDIR/file.pl$DOTIN";
33
require "$SCRIPTSDIR/parse.pl$DOTIN";
34
require "$SCRIPTSDIR/xml.pl$DOTIN";
39
# Merge items in hash B missing in A into A.
45
foreach $key (keys %$hb)
47
$$ha{$key} = $$hb{$key} if !exists $$ha{$key};
51
sub gst_filesys_ext2_device_to_label # device
57
$fd = &gst_file_run_pipe_read ("e2label $device");
58
return undef if $fd eq undef;
61
&gst_file_close ($fd);
67
# --- filesys_info; information on a particular filesystem --- #
70
sub gst_filesys_info_new
75
$$info{'options'} = $opthash;
79
# Make a deep copy of a filesys_info struct.
81
# Returns a newly allocated filesys_info, identical to the argument.
83
sub gst_filesys_info_dup # filesys_info
87
my $options = $$orig{'options'};
90
$$dup{'options'} = { %$options };
95
sub gst_filesys_info_match # filesys_info, device, label, uuid, network_host, network_path
97
my ($info, $device, $label, $uuid, $network_host, $network_path, $point) = @_;
99
if (($label && $info->{'label'} eq $label) ||
100
($uuid && $info->{'uuid'} eq $uuid) ||
101
($network_host && $network_path &&
102
$info->{'network_host'} eq $network_host &&
103
$info->{'network_path'} eq $network_path) ||
104
($device && $device ne "none" && $info->{'device'} eq $device) ||
105
($device eq "none" && $info->{'device'} eq "none" && $point eq $info->{'point'}))
113
sub gst_filesys_info_settings_to_options
117
if (&gst_filesys_info_get_mounted ($info))
119
&gst_filesys_info_remove_option ($info, "noauto");
123
&gst_filesys_info_set_option ($info, "noauto", "");
127
sub gst_filesys_info_match_options # filesys_info, filesys_info
129
my ($info_a, $info_b) = @_;
131
if (&gst_filesys_info_print_options ($info_a) eq &gst_filesys_info_print_options ($info_b))
139
sub gst_filesys_info_match_data # filesys_info, filesys_info
141
my ($info_a, $info_b) = @_;
143
if (&gst_filesys_info_get_point ($info_a) eq &gst_filesys_info_get_point ($info_b) &&
144
&gst_filesys_info_get_fs ($info_a) eq &gst_filesys_info_get_fs ($info_b) &&
145
&gst_filesys_info_get_dump ($info_a) eq &gst_filesys_info_get_dump ($info_b) &&
146
&gst_filesys_info_get_priority ($info_a) eq &gst_filesys_info_get_priority ($info_b) &&
147
&gst_filesys_info_match_options ($info_a, $info_b))
155
# Merge options in B missing in A into A.
156
sub gst_filesys_info_merge_options
158
my ($info_a, $info_b) = @_;
159
my ($opt_a, $opt_b, $key);
161
$opt_a = $$info_a{'options'};
162
$opt_b = $$info_b{'options'};
164
&merge_hashes ($opt_a, $opt_b);
167
# Merge stuff in B missing in A into A.
168
sub gst_filesys_info_merge
170
my ($info_a, $info_b) = @_;
173
&merge_hashes ($info_a, $info_b);
174
&gst_filesys_info_merge_options ($info_a, $info_b);
177
# Generic set function for filesys_info properties. We need this to
178
# delete keys if they don't have meaningful values, otherwise an empty
179
# value could override a perfectly good value in a merge.
181
sub gst_filesys_info_set # filesys_info, key, value
183
my ($filesys_info, $key, $value) = @_;
187
delete $filesys_info->{$key};
191
$filesys_info->{$key} = $value;
195
sub gst_filesys_info_get_device # filesys_info
197
return $_[0]->{'device'};
200
sub gst_filesys_info_set_device # filesys_info, device
202
&gst_filesys_info_set ($_[0], 'device', $_[1]);
205
sub gst_filesys_info_get_label # filesys_info
207
return $_[0]->{'label'};
210
sub gst_filesys_info_set_label # filesys_info, label
212
&gst_filesys_info_set ($_[0], 'label', $_[1]);
215
sub gst_filesys_info_get_network_host # filesys_info
217
return $_[0]->{'network_host'};
220
sub gst_filesys_info_set_network_host # filesys_info, network_host
222
my ($info, $host) = @_;
225
&gst_filesys_info_set ($info, 'network_host', $host);
228
sub gst_filesys_info_get_network_path # filesys_info
230
return $_[0]->{'network_path'};
233
sub gst_filesys_info_set_network_path # filesys_info, network_path
235
my ($info, $path) = @_;
237
$path = "/" . $path if (!($path =~ /^\//));
238
&gst_filesys_info_set ($info, 'network_path', $path);
241
sub gst_filesys_info_get_uuid # filesys_info
243
return $_[0]->{'uuid'};
246
sub gst_filesys_info_set_uuid # filesys_info, uuid
248
&gst_filesys_info_set ($_[0], 'uuid', $_[1]);
251
sub gst_filesys_info_get_point # filesys_info
253
return $_[0]->{'point'};
256
sub gst_filesys_info_set_point # filesys_info, point
258
&gst_filesys_info_set ($_[0], 'point', $_[1]);
261
sub gst_filesys_info_get_fs # filesys_info
263
return $_[0]->{'fs'};
266
sub gst_filesys_info_set_fs # filesys_info, fs
268
&gst_filesys_info_set ($_[0], 'fs', $_[1]);
271
sub gst_filesys_info_get_dump # filesys_info
273
return $_[0]->{'dump'} || "0";
276
sub gst_filesys_info_set_dump # filesys_info, dump
278
&gst_filesys_info_set ($_[0], 'dump', $_[1]);
281
sub gst_filesys_info_get_priority # filesys_info
283
return $_[0]->{'priority'} || "0";
286
sub gst_filesys_info_set_priority # filesys_info, priority
288
&gst_filesys_info_set ($_[0], 'priority', $_[1]);
291
sub gst_filesys_info_get_mounted # filesys_info
293
return $_[0]->{'mounted'};
296
sub gst_filesys_info_set_mounted # filesys_info, boolean
298
&gst_filesys_info_set ($_[0], 'mounted', $_[1]);
301
sub gst_filesys_info_get_permanent # filesys_info
303
return $_[0]->{'permanent'};
306
sub gst_filesys_info_set_permanent # filesys_info, boolean
308
&gst_filesys_info_set ($_[0], 'permanent', $_[1]);
311
sub gst_filesys_info_get_detected # filesys_info
313
return $_[0]->{'detected'};
316
sub gst_filesys_info_set_detected # filesys_info, boolean
318
&gst_filesys_info_set ($_[0], 'detected', $_[1]);
321
sub gst_filesys_info_get_option # filesys_info, option
323
return $_[0]->{'options'}{$_[1]};
326
# We can't delete keys with no values here, since most fs options don't
327
# have values (i.e. they key's presence constitutes a boolean). A value of
328
# " " (one space) indicates that this entry takes a value (is non-bool), but
331
sub gst_filesys_info_set_option # filesys_info, option, value
333
$_[0]->{'options'}{$_[1]} = $_[2];
336
sub gst_filesys_info_remove_option # filesys_info, option
338
delete $_[0]->{'options'}{$_[1]};
341
# --- filesys_table; multiple instances of filesys_info --- #
344
sub gst_filesys_table_new
350
# Make a deep copy of a filesys_table struct.
352
# Returns a newly allocated filesys_table, identical to the argument.
354
sub gst_filesys_table_dup # filesys_table
357
my $dup = &gst_filesys_table_new ();
362
&gst_filesys_table_add ($dup, &gst_filesys_info_dup ($i));
368
# Add a filesys_info reference to a filesys_table. Note: This function
369
# does not check for uniqueness, which lets you add several references
370
# to the same filesys_info.
372
sub gst_filesys_table_add # filesys_table, filesys_info
374
my ($table, $info) = @_;
379
# Ensure that a filesys_info reference exists in a filesys_table. If it
380
# doesn't, it will be added. If it does, no action will be taken.
382
sub gst_filesys_table_ensure # filesys_table, filesys_info
384
my ($table, $info) = @_;
389
return if ($i eq $info);
392
&gst_filesys_table_add ($table, $info);
395
# Remove a filesys_info reference from a filesys_table.
397
sub gst_filesys_table_remove # filesys_table, filesys_info
399
my ($table, $info) = @_;
402
if ($info == undef) { return; }
404
for ($i = 0; $i < @$table; $i++)
406
if (@$table [$i] eq $info)
408
@$table = (@$table [0 .. $i - 1], @$table [$i + 1 .. @$table - 1]);
413
&gst_debug_print_line ("Entry to remove [" . $info . "] not found in filesys_table.");
416
# Find and return a reference to a filesys_info in a filesys_table
417
# matching any of the information provided.
419
sub gst_filesys_table_find # filesys_table, device, label, uuid, network_host, network_path
421
my ($table, $device, $label, $uuid, $network_host, $network_path, $point) = @_;
424
# Match on high-quality keys.
428
if (($label && $i->{'label'} eq $label) ||
429
($uuid && $i->{'uuid'} eq $uuid) ||
430
($network_host && $network_path &&
431
$i->{'network_host'} eq $network_host &&
432
$i->{'network_path'} eq $network_path))
438
# Match on low-quality keys.
444
if (($device && $device ne "none" && $i->{'device'} eq $device) ||
445
($device eq "none" && $i->{'device'} eq "none" && $point eq $i->{'point'}))
452
&gst_debug_print_line ("Entry [" . $device . "] not found in filesys_table.");
456
sub gst_filesys_table_find_info_equivalent # filesys_table, filesys_info
458
my ($table, $info) = @_;
460
return &gst_filesys_table_find ($table, &gst_filesys_info_get_device ($info),
461
&gst_filesys_info_get_label ($info),
462
&gst_filesys_info_get_uuid ($info),
463
&gst_filesys_info_get_network_host ($info),
464
&gst_filesys_info_get_network_path ($info),
465
&gst_filesys_info_get_point ($info));
468
# Merges filesys tables A and B, resolving conflicts by giving priority to A.
469
# Any entries in A not in B are preserved. This can also be described as
470
# "salting" one table with another.
472
# Returns a newly allocated table C, which is a superset of A and B.
474
sub gst_filesys_table_merge_superset # filesys_table A, filesys_table B
476
my ($intab_a, $intab_b) = @_;
477
my ($hash_c, $hash_b, $key);
480
$outtab = &gst_filesys_table_dup ($intab_a);
482
foreach $info_b (@$intab_b)
486
if ($info_c = &gst_filesys_table_find_info_equivalent ($outtab, $info_b))
488
&gst_filesys_info_merge ($info_c, $info_b);
492
$info_c = &gst_filesys_info_dup ($info_b);
493
&gst_filesys_table_add ($outtab, $info_c);
500
# Merges filesys tables A and B, resolving conflicts by giving priority to A.
501
# Any entries not in A are dropped.
503
# Returns a newly allocated table C, which is a subset of A and B.
505
sub gst_filesys_table_merge_subset # filesys_table A, filesys_table B
507
my ($intab_a, $intab_b) = @_;
508
my ($hash_c, $hash_b, $key);
511
$outtab = &gst_filesys_table_dup ($intab_a);
513
foreach $info_b (@$intab_b)
517
if ($info_c = &gst_filesys_table_find_info_equivalent ($outtab, $info_b))
519
&gst_filesys_info_merge ($info_c, $info_b);
526
# Called to indicate that entries in a filesys table are mounted.
528
sub gst_filesys_table_set_mounted_true # filesys_table
533
&gst_filesys_info_set_mounted ($i, 1);
537
# Called to indicate that entries in a filesys table are permanent.
539
sub gst_filesys_table_set_permanent_true # filesys_table
544
&gst_filesys_info_set_permanent ($i, 1);
548
# Called to indicate that entries in a filesys table have been detected,
549
# e.g. by a network or bus scanner, and were not specified in any part of
550
# the user's configuration.
552
sub gst_filesys_table_set_detected_true # filesys_table
557
&gst_filesys_info_set_detected ($i, 1);
563
sub gst_filesys_entry_identify
565
my ($device, $fs) = @_;
566
my ($label, $uuid, $network_host, $network_path);
568
# <device> expands to "LABEL=<label>", "UUID=<uuid>" or "<device node>".
569
if ($device =~ /^LABEL=(.*)/i) { $label = $1; $device = ""; }
570
elsif ($device =~ /^UUID=(.*)/i) { $uuid = $1; $device = ""; }
573
# We know only the device node. Try to get label too.
574
if ($fs eq "ext2" || ($fs eq "auto" && !($device =~ /fd[0-9]$/)))
576
$label = &gst_filesys_ext2_device_to_label ($device);
578
# Network filesystem devices can be separated into remote host and remote path.
581
$device =~ /([^:]+):(.+)/;
584
$network_path = "/" . $network_path if (!($network_path =~ /^\//));
587
elsif ($fs eq "smbfs")
589
$device =~ /[\\\/]*([^\\\/]+)[\\\/]+(.+)/;
592
$network_path = "/" . $network_path if (!($network_path =~ /^\//));
597
return ($device, $label, $uuid, $network_host, $network_path);
600
sub gst_filesys_entry_identify_info
602
my ($fsi, $device, $fs) = @_;
603
my ($label, $uuid, $network_host, $network_path);
605
($device, $label, $uuid, $network_host, $network_path) = &gst_filesys_entry_identify ($device, $fs);
607
if ($device) { &gst_filesys_info_set_device ($fsi, $device); }
608
if ($label) { &gst_filesys_info_set_label ($fsi, $label); }
609
if ($uuid) { &gst_filesys_info_set_uuid ($fsi, $uuid); }
610
if ($network_host) { &gst_filesys_info_set_network_host ($fsi, $network_host); }
611
if ($network_path) { &gst_filesys_info_set_network_path ($fsi, $network_path); }
614
# Get all instances from fstab-style file. Returns a filesys_table.
616
# This is not done in smaller, atomic funcs that get single options
617
# per disk device, due to the fact that a device is identified either
618
# by its label, uuid or device node, and a label can be made to look
619
# like a device node. For each device, we need to specify the kind of
620
# key(s) used, and making a special-format string for that (which could
621
# be passed to option readers) would be a bad hack.
623
sub gst_filesys_fstab_parse # filename
628
$fd = &gst_file_open_read_from_names ($file);
629
return undef if !$fd;
631
$table = &gst_filesys_table_new ();
633
while (($_ = &gst_parse_chomp_line_hash_comment ($fd)) != -1)
635
# Each line is in the following format:
636
# <device> <mount point> <filesystem> <options> <dump flag> <fsck priority>
637
my @line = split /[ \t]+/, $$_;
639
my ($device, $point, $fs, $options, $dump, $fsck) = @line;
641
my $fsi = &gst_filesys_info_new ();
642
&gst_filesys_entry_identify_info ($fsi, $device, $fs);
644
# <mount point>, <fs>, <dump flag> and <fsck priority> are verbatim.
645
&gst_filesys_info_set_point ($fsi, $point);
646
&gst_filesys_info_set_fs ($fsi, $fs);
647
&gst_filesys_info_set_dump ($fsi, $dump);
648
&gst_filesys_info_set_priority ($fsi, $fsck);
650
# <options> expands to "<option>[,<option>[,...]]".
651
my @optlist = split /[,]/, $options;
653
foreach $option (@optlist)
655
# <option> expands to "<key>[=<value>]". <key> == "defaults" is ignored.
656
my ($key, $value) = split /[=]/, $option;
657
next if ($key eq "" || $key eq "defaults");
659
if ($value eq "" && $option =~ /=/) { $value = " "; }
660
&gst_filesys_info_set_option ($fsi, $key, $value);
664
&gst_filesys_table_add ($table, $fsi);
667
&gst_file_close ($fd);
671
# Get all instances from 'mount -p' output. Returns a filesys_table.
672
sub gst_filesys_freebsd_mount_cmd_parse
674
my ($table, $mount_cmd);
677
$table = &gst_filesys_table_new ();
678
$mount_cmd = &gst_file_locate_tool ("mount");
679
@output = (readpipe ("$mount_cmd -p"));
683
# Columns are separated by any number of spaces/tabs.
685
my @line = split (/[ \t]+/, $l);
687
# Each line is in the following format:
688
# <device> <mount point> <filesystem> <options> <dump flag> <fsck priority>
689
next if ($#line < 5);
690
my ($device, $point, $fs, $options, $dump, $fsck) = @line;
692
my $fsi = &gst_filesys_info_new ();
693
&gst_filesys_entry_identify_info ($fsi, $device, $fs);
695
# <device> expands to "<device node>" (unlike fstab, which has dev|label|uuid).
696
# <mount point>, <fs>, <dump flag> and <fsck priority> are verbatim.
697
&gst_filesys_info_set_device ($fsi, $device);
698
&gst_filesys_info_set_point ($fsi, $point);
699
&gst_filesys_info_set_fs ($fsi, $fs);
700
&gst_filesys_info_set_dump ($fsi, $dump);
701
&gst_filesys_info_set_priority ($fsi, $fsck);
703
# <options> expands to "<option>[,<option>[,...]]".
704
my @optlist = split (/,/, $options);
706
foreach $option (@optlist)
708
# <option> expands to "<key>[=<value>]". <key> == "defaults" is ignored.
709
my ($key, $value) = split /[=]/, $option;
710
next if ($key eq "" || $key eq "defaults");
712
$value = " " if ($value eq "" && $option =~ /=/);
713
&gst_filesys_info_set_option ($fsi, $key, $value);
717
&gst_filesys_table_add ($table, $fsi);
723
# Get all instances from mtab-style file. Returns a filesys_table.
725
sub gst_filesys_mtab_parse # filename
730
$fd = &gst_file_open_read_from_names ($file);
731
return undef if !$fd;
733
$table = &gst_filesys_table_new ();
735
while (($_ = &gst_parse_chomp_line_hash_comment ($fd)) != -1)
737
# Columns are separated by one, and only one, space. The presence of one or
738
# more blank values is indicated by a string of several spaces.
739
my @line = split /[ ]/, $$_;
741
# Each line is in the following format:
742
# <device> <mount point> <filesystem> <options> <dump flag> <fsck priority>
744
my ($device, $point, $fs, $options, $dump, $fsck) = @line;
746
my $fsi = &gst_filesys_info_new ();
747
&gst_filesys_entry_identify_info ($fsi, $device, $fs);
749
# <device> expands to "<device node>" (unlike fstab, which has dev|label|uuid).
750
# <mount point>, <fs>, <dump flag> and <fsck priority> are verbatim.
751
&gst_filesys_info_set_device ($fsi, $device);
752
&gst_filesys_info_set_point ($fsi, $point);
753
&gst_filesys_info_set_fs ($fsi, $fs);
754
&gst_filesys_info_set_dump ($fsi, $dump);
755
&gst_filesys_info_set_priority ($fsi, $fsck);
757
# <options> expands to "<option>[,<option>[,...]]".
758
my @optlist = split /[,]/, $options;
760
foreach $option (@optlist)
762
# <option> expands to "<key>[=<value>]". <key> == "defaults" is ignored.
763
my ($key, $value) = split /[=]/, $option;
764
next if ($key eq "" || $key eq "defaults");
766
if ($value eq "" && $option =~ /=/) { $value = " "; }
767
&gst_filesys_info_set_option ($fsi, $key, $value);
771
&gst_filesys_table_add ($table, $fsi);
774
&gst_file_close ($fd);
779
# --- Replacing --- #
782
sub gst_filesys_fstab_get_next_entry_line # $infd, $outfd
784
my ($infd, $outfd) = @_;
788
# Each line is in the following format:
789
# <device> <mount point> <filesystem> <options> <dump flag> <fsck priority>
790
my @line = split /[ \t]+/, $_;
791
if ($line[0] eq "") { shift @line; }
792
if (@line < 6 || &gst_ignore_line (@line)) { print $outfd $_; next; }
800
sub gst_filesys_fstab_get_entry_line_fields # line
804
# Remove leading spaces.
805
$line =~ s/^[ \t]*//;
807
# Remove trailing spaces and comments.
808
$line =~ s/[ \t]*\#.*//;
810
return split /[ \t]+/, $line;
813
sub gst_filesys_fstab_get_entry_line_comments # line
817
sub gst_filesys_info_print_options # filesys_info
823
$opthash = $$info{'options'};
825
for $option (keys (%$opthash))
827
if ($optstring) { $optstring .= ","; }
828
$optstring .= $option;
829
if ($info->{'options'}{$option})
831
$optstring .= "=" . $info->{'options'}{$option};
836
if ($optstring eq "")
838
$optstring = "defaults";
844
sub gst_filesys_info_print_device
849
if (&gst_filesys_info_get_label ($info))
851
$device = "LABEL=" . &gst_filesys_info_get_label ($info);
853
elsif (&gst_filesys_info_get_uuid ($info))
855
$device = "UUID=" . &gst_filesys_info_get_uuid ($info);
857
elsif (&gst_filesys_info_get_network_host ($info) &&
858
&gst_filesys_info_get_network_path ($info))
860
if (&gst_filesys_info_get_fs ($info) eq "smbfs")
862
$device = "//" . &gst_filesys_info_get_network_host ($info)
863
. &gst_filesys_info_get_network_path ($info);
867
$device = &gst_filesys_info_get_network_host ($info) . ":" .
868
&gst_filesys_info_get_network_path ($info);
873
$device = &gst_filesys_info_get_device ($info);
879
sub gst_filesys_info_print_entry
886
$line = sprintf ("%-23s", &gst_filesys_info_print_device ($info));
890
if (&gst_filesys_info_get_point ($info))
892
$line .= sprintf ("%-24s", (" " . &gst_filesys_info_get_point ($info))) . " ";
896
$line .= sprintf ("%-24s", (" none")) . " ";
899
# <filesystem> <options> <dump flag> <fsck priority>
901
$line .= sprintf ("%-7s", &gst_filesys_info_get_fs ($info)) . " " .
902
sprintf ("%-15s", &gst_filesys_info_print_options ($info)) . " " .
903
&gst_filesys_info_get_dump ($info) . " " .
904
&gst_filesys_info_get_priority ($info);
909
sub gst_filesys_fstab_add_entry # filename, filesys_info
911
my ($file, $info) = @_;
915
($infd, $outfd) = &gst_file_open_filter_write_from_names ($file);
916
return undef if !$outfd;
918
while (<$infd>) { print $outfd $_; }
919
&gst_file_close ($infd);
921
print $outfd &gst_filesys_info_print_entry ($info) . "\n";
922
&gst_file_close ($outfd);
925
sub gst_filesys_fstab_update_entry # filename, filesys_info
927
my ($file, $info) = @_;
932
($infd, $outfd) = &gst_file_open_filter_write_from_names ($file);
933
return undef if !$outfd;
935
while ($line = &gst_filesys_fstab_get_next_entry_line ($infd, $outfd))
937
my ($device, $point, $fs, $options, $dump, $fsck) = &gst_filesys_fstab_get_entry_line_fields ($line);
938
my ($device, $label, $uuid, $network_host, $network_path) = &gst_filesys_entry_identify ($device, $fs);
940
if (!$replaced && &gst_filesys_info_match ($info, $device, $label, $uuid,
941
$network_host, $network_path, $point))
943
print $outfd &gst_filesys_info_print_entry ($info) . "\n";
952
&gst_file_close ($infd);
953
&gst_file_close ($outfd);
956
sub gst_filesys_fstab_remove_entry # filename, filesys_info
958
my ($file, $info) = @_;
962
($infd, $outfd) = &gst_file_open_filter_write_from_names ($file);
963
return undef if !$outfd;
965
while ($line = &gst_filesys_fstab_get_next_entry_line ($infd, $outfd))
967
my ($device, $point, $fs, $options, $dump, $fsck) = &gst_filesys_fstab_get_entry_line_fields ($line);
968
my ($device, $label, $uuid, $network_host, $network_path) = &gst_filesys_entry_identify ($device, $fs);
970
if (!&gst_filesys_info_match ($info, $device, $label, $uuid, $network_host, $network_path, $point))
976
&gst_file_close ($infd);
977
&gst_file_close ($outfd);
980
# Replace instances in fstab-style file.
982
sub gst_filesys_fstab_replace # filename, table
984
my ($file, $table) = @_;
985
my ($new_table, $old_table);
987
$old_table = &gst_filesys_fstab_parse ($file);
988
$new_table = &gst_filesys_table_dup ($table);
990
for $info (@$new_table)
992
my $old_info = &gst_filesys_table_find_info_equivalent ($old_table, $info);
994
# print "Looking for entry - ";
995
if (&gst_filesys_info_get_permanent ($info) && !$old_info)
998
&gst_filesys_fstab_add_entry ($file, $info);
1000
elsif (!&gst_filesys_info_get_permanent ($info) && $old_info)
1002
# print "removing.\n";
1003
&gst_filesys_fstab_remove_entry ($file, $info);
1005
elsif ($old_info && !&gst_filesys_info_match_data ($old_info, $info))
1007
# print "updating.\n";
1008
&gst_filesys_fstab_update_entry ($file, $info);
1018
for $old_info (@$old_table)
1020
# print "Looking for entry - ";
1021
if (!&gst_filesys_table_find_info_equivalent ($new_table, $old_info))
1023
# print "removing.\n";
1024
&gst_filesys_fstab_remove_entry ($file, $old_info);
1034
# --- Mounting --- #
1037
sub gst_filesys_mount_on
1040
my ($dev, $point, $fs);
1042
$dev = &gst_filesys_info_print_device ($info);
1043
$point = &gst_filesys_info_get_point ($info);
1045
&gst_report_enter ();
1046
&gst_report ("filesys_mount", $dev, $point);
1048
$fs = &gst_filesys_info_get_fs ($info);
1049
$fs = "auto" if ($fs eq "");
1051
if (&gst_file_run ("mount -t " . $fs . " -o " . &gst_filesys_info_print_options ($info) . " " .
1052
$dev . " " . $point))
1054
&gst_report ("filesys_mount_failed", $dev, $point);
1057
&gst_report_leave ();
1060
sub gst_filesys_mount_off
1065
$dev = &gst_filesys_info_print_device ($info);
1066
$point = &gst_filesys_info_get_point ($info);
1068
&gst_report_enter ();
1069
&gst_report ("filesys_unmount", $dev, $point);
1071
if (&gst_file_run ("umount -f " . $point))
1073
&gst_report ("filesys_unmount_failed", $dev, $point);
1076
&gst_report_leave ();
1079
sub gst_filesys_mount_sync_all
1081
my ($fstab_file, $mtab_file, $new_table) = @_;
1082
my ($mount_table, $fs_table);
1084
$fs_table = &gst_filesys_fstab_parse ($fstab_file);
1085
$mount_table = &gst_filesys_mtab_parse ($mtab_file);
1087
for $info (@$new_table)
1089
my $mounted_info = &gst_filesys_table_find_info_equivalent ($mount_table, $info);
1091
if ($mounted_info && !&gst_filesys_info_get_mounted ($info))
1093
&gst_filesys_mount_off ($mounted_info);
1095
elsif (!$mounted_info && &gst_filesys_info_get_mounted ($info))
1097
# If the mount has an fstab entry, we prefer that over the information
1100
my $fs_info = &gst_filesys_table_find_info_equivalent ($fs_table, $info);
1104
&gst_filesys_mount_on ($fs_info);
1108
&gst_filesys_mount_on ($info);