#!/usr/bin/env perl #-*- Mode: perl; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- # Boot manager configurator: YABOOT-related routines. # # Copyright (C) 2001 Ximian, Inc. # # Authors: Carlos Garnacho Parro # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU Library General Public License as published # by the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Library General Public License for more details. # # You should have received a copy of the GNU Library General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. $SCRIPTSDIR = "@scriptsdir@"; if ($SCRIPTSDIR =~ /^@scriptsdir[@]/) { $SCRIPTSDIR = "."; $DOTIN = ".in"; } require "$SCRIPTSDIR/general.pl$DOTIN"; require "$SCRIPTSDIR/util.pl$DOTIN"; require "$SCRIPTSDIR/file.pl$DOTIN"; require "$SCRIPTSDIR/xml.pl$DOTIN"; require "$SCRIPTSDIR/parse.pl$DOTIN"; require "$SCRIPTSDIR/replace.pl$DOTIN"; require "$SCRIPTSDIR/partition.pl$DOTIN"; my @yaboot_global_vars = qw (default prompt delay timeout append boot root); my @yaboot_image_vars = qw (label image append initrd root); my @yaboot_other_vars = qw (bsd macos macosx darwin); sub gst_boot_yaboot_verify { return "success"; } sub gst_boot_yaboot_parse_entries { my ($file, $partition, $root) = @_; my ($fd, $line, @entries, $entry); my ($line, $known_vars, $found); $found = -1; $fd = &gst_file_open_read_from_names ($file); if (! $fd) { &gst_report ("boot_conf_read_failed", $file); return undef; } while (($line = <$fd>)) { chomp $line; $line =~ s/^[ \t]+//; if ($line =~ /^image/i) { $found++; $known_vars = \@yaboot_image_vars; $entries[$found]{"key"} = $found; } elsif ($line =~ /^(bsd|macos|macosx|darwin)/) { $found++; $known_vars = \@yaboot_other_vars; $entries[$found]{"key"} = $found; } next if $found < 0; next if $line =~ /^\#/; $line = &gst_parse_process_sh_line ($line); next if $line eq ""; my @line = split ("[ \t]*=[ \t]*", $line, 2); my $key = shift @line; # Only deal with known variables next unless &gst_boot_lilo_known_var ($key, $known_vars, 0); my $val = shift @line; $val =~ s/^[ \t]+//; $val =~ s/\"//g; $val =~ s/[ \t]+$//; if ($key =~ /^(bsd|macos|macosx|darwin)$/) { $entries[$found]{"label"} = $key; $key = "other"; } $entries[$found]{$key} = $val; # the root parameter may not exist, then we take the global parameter if (($entries[$found]{"root"} eq undef) && ($entries[$found]{"image"} ne undef)) { $entries[$found]{"root"} = $root; } } &gst_file_close ($fd); foreach $entry (@entries) { &gst_boot_lilo_set_default_type ($entry, $partition); } return \@entries; } sub gst_boot_yaboot_find_entry { my ($buff, $lineno) = @_; my $i; for (; $lineno <= $#$buff; $lineno++) { $i = $$buff[$lineno]; return $lineno if ($i =~ /^[ \t]*(image|bsd|macos|macosx|darwin)[ \t]*=[ \t]*\S+/); } # Not found. return -1; } sub gst_boot_yaboot_delete_entry { my ($buff, $lineno) = @_; my ($end, $i); $end = &gst_boot_yaboot_find_entry ($buff, $lineno + 1); $end = scalar @$buff if ($end < 0); for ($i = $lineno; $i < $end; $i++) { $$buff[$i] = ""; } return $buff; } sub gst_boot_yaboot_edit_entry { my ($entry, $buff, $lineno) = @_; my $known_vars = \@yaboot_image_vars if (exists $entry->{'image'}); $known_vars = \@yaboot_other_vars if (!$known_vars && exists $entry->{'other'}); return $buff unless $known_vars; my $end = &gst_boot_yaboot_find_entry ($buff, $lineno + 1); $end = scalar @$buff if ($end < 0); for ($lineno; $lineno < $end; $lineno++) { # Get the variable. my $key = $1 if ($$buff[$lineno] =~ /^[ \t]*([\w\-]+)/); next if ($key && (!&gst_boot_lilo_known_var ($key, $known_vars, 0))); next unless $key; if (exists ($entry->{"other"})) { my $old_val = $$buff[$lineno]; $old_val =~ s/^[ \t]*$key[ \t]*=[ \t]*//; #everything till value $old_val =~ s/[ \t]*\#.*$//; #post comment; chomp $old_val; if ($old_val) { # String. my $val = $entry->{"other"}; $val = "\"$val\"" if ($val =~ /[ \t]/ && (! ($val =~ /^\".+\"$/))); $val = "\"$val\"" if ($val =~ /\=/ && (!($val =~ /^\".+\"$/))); $$buff[$lineno] =~ s/$old_val/$val/; } } else { unless (exists ($entry->{$key})) { # Keyword is known, but isn't in entry. delete $$buff[$lineno]; next; } # Read old value my $old_val = $$buff[$lineno]; $old_val =~ s/^[ \t]*$key[ \t]*=[ \t]*//; #everything till value $old_val =~ s/[ \t]*\#.*$//; #post comment; chomp $old_val; if ($old_val) { # String. my $val = $entry->{$key}; $val = "\"$val\"" if ($val =~ /[ \t]/ && (! ($val =~ /^\".+\"$/))); $val = "\"$val\"" if ($val =~ /\=/ && (!($val =~ /^\".+\"$/))); $$buff[$lineno] =~ s/$old_val/$val/; } delete $entry->{$key}; } } # Add new fields. foreach my $key (keys %$entry) { next unless &gst_boot_lilo_known_var ($key, $known_vars, 1); my $val = $entry->{$key}; $val = "\"$val\"" if ($val =~ /[ \t]/ && (! ($val =~ /^\".+\"$/))); $val = "\"$val\"" if ($val =~ /\=/ && (!($val =~ /^\".+\"$/))); my $line = "\t$key";; $line .= " = $val" if $val; $line .= "\n"; $$buff[$end -1] .= $line; } } # Add $entry to the end of $buff. sub gst_boot_yaboot_add_entry { my ($entry, $buff) = @_; my ($line, $key, $value, $known_vars); # Entry line if (exists $entry->{'image'}) { $known_vars = \@yaboot_image_vars; $value = 'image'; $line = $value . " = " . $$entry{$value} . "\n"; } elsif (exists $entry->{'other'}) { $known_vars = \@yaboot_other_vars; # FIXME: this is a really terrible hack, the xml needs to be redesigned if ($entry->{'label'} =~ /(macos|macosx|bsd|darwin)/) { $value = $entry->{'label'}; } else { $value = 'macosx'; } $line = $value . " = " . $$entry{"other"} . "\n"; } else { return; } push @$buff, $line; delete $$entry{$value}; # Parameters for entry foreach $key (keys %$entry) { next unless &gst_boot_lilo_known_var ($key, $known_vars, 1); $value = $$entry{$key}; $value = "\"$value\"" if ($value =~ /[ \t]/ && (!($value =~ /^\".+\"$/))); $value = "\"$value\"" if ($value =~ /\=/&& (!($value =~ /^\".+\"$/))); $line = "\t$key"; $line .= " = " . $value if $value; $line .= "\n"; push @$buff, $line; } } sub gst_boot_yaboot_entries_set { my ($file, $entries) = @_; my ($buff, $lineno, $found, $entry); return if (scalar @$entries <= 0); $buff = &gst_file_buffer_load ($file); &gst_file_buffer_join_lines ($buff); my $entry_nr = -1; $lineno = &gst_boot_yaboot_find_entry ($buff, 0); while ($lineno > 0) { $entry_nr++; $found = 0; foreach $entry (@$entries) { next unless $entry; if (exists ($entry->{"key"})) { $found++ if $entry->{"key"} == $entry_nr; if ($found > 0) { # Found entry, change it if necessary, # remove %entry from @entries and find new entry. &gst_boot_yaboot_edit_entry ($entry, $buff, $lineno); $entry = undef; last; } } } # Found entry wasn't in our @entries list: delete. $buff = &gst_boot_yaboot_delete_entry ($buff, $lineno) if ($found <= 0); # Search new entry line. $lineno = &gst_boot_yaboot_find_entry ($buff, $lineno + 1); } # At this point @entries contains only new entries, let's add them. foreach $entry (@$entries) { next if ($entry eq undef); &gst_boot_yaboot_add_entry ($entry, $buff); } &gst_file_buffer_clean ($buff); return &gst_file_buffer_save ($buff, $file); }