Wise Monks,

I spend much of my time mucking about with dhcp data. I'm also in the process of trying to learn OO perl. So, I figured I would practice my class-building skills by creating a DHCP module for myself which will gather various lease/network information.

I find parsing the dhcpd.leases file to be pretty easy because the data is nice and predictable. The human-generated dhcpd.conf file, on the other hand, is a nightmare. I have figured out a way to gather some of the information I need, but I know there must be some established algorithm that is much more elegant. I've browsed a few of the configuration file parsing modules on cpan to search for ideas, but either they aren't sufficiently commented, or they deal with simpler configuration schemes (as far as I can tell).

Does anyone know of an online tutorial somewhere that covers configuration file parsing algorithms?

The current bit of code I have works for what I need right now, but I know it's extremely oversimplified and prone to break under various conditions.

Here's a simplified snippet of what I have:

sub new { my $invocant = shift; my $class = ref($invocant) || $invocant; my $self = { # Paths for the leases and conf files lease_file => '/var/state/dhcp/dhcpd.leases', conf_file => '/etc/dhcpd.conf', # Hash keyed by dhcpd.conf configuration option # Values contain references to subroutines for handling # each option conf_fields => { host => \&_host, # Static hosts }, # Hash keyed by MAC address # Values contain array of lease arrays leases => { }, @_, }; # Load static hosts &_init_conf($self); bless ($self, $class); return $self; } # Initialize static hosts sub _init_conf { my $self = shift; open CONF, $self->{'conf_file'} or die "Couldn't open ", $self->{'conf_file'}, " $!"; + my $option; while (<CONF>) { # If the current line contains an open bracket grab the first +word # as the option key $option = $1 if $_ !~ /^\s*#/ && /^\s*(\w+).*{/; # Call the subroutine associated with the current option # Must eval this call in case no such subroutine exists. eval { $self->{'conf_fields'}{$option}->($self, $_) } if $opti +on; # Clear option key if closing bracket $option = undef and eval { $self->{'conf_fields'}{$option}->($ +self, $_) } if $_ !~ /^\s*#/ && /}/; } close CONF; } # Method to handle static host declarations { my $mac, $ip; sub _host { my $self = shift; # Current line of dhcpd.conf $_ = shift; # Grab MAC address $mac = mac_normal($1) if /\s*hardware ethernet (\w+:\w+:\w+:\w ++:\w+:\w+)/; # Grab IP $ip = $1 if /\s*fixed-address (\d+.\d+.\d+.\d+)/; # Push entry onto array of leases for host's MAC # and clear $mac, $ip variables push @{$self->{'leases'}{$mac}}, [ $ip, 'static'] and ($ip, $m +ac) = ('', '') if /}/ and $ip && $mac; } }

--------------------------
Sample Static Host:

host camel { hardware ethernet 00:AA:12:BB:A1:34; filename "/default.cfg"; fixed-address 10.1.2.3; }

In reply to Config file parsing tutorial? by tombmbdil

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.