[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: (hopefully perl) API to /etc/network/interfaces?



On 05/26/11 17:16, Mike Mestnik wrote:
> In-Reply-To: <20080412023656.GR14599@yi.org>
>
> Hello,
>   This is an old thread, but I find myself in a similar situation.  I'd
> like to edit a 4in6 tunnel endpoint and reconfigure the interface. 
> While I can handle the Apache/sudo parts of this I'm stuck with... OK
> now how and I going to change this one value out of this whole file?
>
> My current plan is to convert the file to XML storing away comments and
> partial white space as well as the settings.  Then I should be able to
> edit the setting a write the file back out.
>
> Any better ideas?  For this project Perl seams to be the ideal language.
>
> I may contact the ifupdown maintainer to include this in his package, so
> I'm looking to get it done right.
>
I'm quite certain this is a some-what usable solution.  However it
dosen't appear to have any means to preserver order.  I'd also like
input for the XMLers about the use of etc_network_interfaces for the
RootName?

#!/usr/bin/perl -w

use warnings;
use strict;
use feature 'switch';
use XML::Simple;
use Data::Dumper;

sub trim
{   $_[0]=~s/\A\s+//;
    $_[0]=~s/\s+\z//;
    $_[0];
}

my $file = q{/etc/network/interfaces};
open (my $INTER, '<', $file) or die "Can't read $file: $!";

my %tmp;
$tmp{'HEAD'}=[''];
my $ptr = \$tmp{'HEAD'}[0];
LINE: while (my $ln=<$INTER>) {
  chomp $ln;
  # A line may be extended across multiple lines by making the last charac-
  #     ter a backslash.
  while ($ln =~ /\\$/) {
    chop $ln; chomp($ln.=<$INTER>); last if (eof $INTER);
  }
  if (ref($ptr) ne 'SCALAR' and $ln =~ /^\s*#/ ) {
    push(@{$tmp{'COMMENT'}}, $ln);
    next LINE;
  }
  foreach my $rx (qr(auto),qr(allow-auto),qr(allow-[^ ]*),
      qr(mapping),qr(iface)) {
    if ($ln =~ /^\s*($rx)\s+(\S*)\s*(.*)$/) {
      $ptr = undef;
      given ($1){
        when('mapping') { push(@{$tmp{'mapping'}},{ $2 => { 'opts' => $3
}}); $ptr = $tmp{'mapping'}[$#{$tmp{'mapping'}}]{$2}; }
        when('iface') { push(@{$tmp{'iface'}},{ $2 => { 'opts' => $3
}}); $ptr = $tmp{'iface'}[$#{$tmp{'iface'}}]{$2}; }
        default { push (@{$tmp{$1}}, trim("$2 $3")); $ptr = $tmp{$1}; }
      }
      next LINE;
    }
  }
  if ($ln =~ /^\s*(\S*)\s(.*)$/) {
    if (defined $ptr) {
      given (ref($ptr)){
    when('HASH') { given ($1){
        when(['up', 'down']) { push(@{${$ptr}{$1}}, $2); }
            default { ${$ptr}{$1}.=$2; }
        } }
    when('ARRAY') { push(@{$ptr}, trim("$1 $2")); }
    when('SCALAR') { ${$ptr}.="$ln\n"; }
        default { warn Dumper(ref($ptr)); warn Dumper(\$ptr); }
      }
      next LINE;
    }
    warn $ln;
    next LINE;
  }
  if ($ln eq '') {
    push(@{$tmp{'br'}}, '');
    next LINE;
  }
  warn $ln;
}

warn XMLout(\%tmp, (RootName => 'etc_network_interfaces'));


Reply to: