Hi
I have written yet another Linux config setting program. It works but I am seeking advice in improving it.
This one reads network settings from an input file. The file is generated by an application that accepts user entries to a GUI. The entries are fully checked to ensure they are within valid ip ranges before they are saved to the file.
This programme will rarely run as a Systemd service only when the input file is changed by the user. Readability and maintainability are more important to me that speed or brevity.
The input file looks like this:
#IP Configuration
#Fri Aug 27 16:07:40 NZST 2021
routers=192.130.1.1
interface=eth0
domain_name_servers=8.8.8. 8.8.1.1
ip_address=192.130.1.10/24
The target configuration file is dhcpcd.conf. The cut down version of the file looks like this:
#static domain_name_servers=192.168.1.1
# fallback to static profile on eth0
#interface eth0
#fallback static_eth0
### Static LAN IP profile
profile static_eth0
static ip_address=192.130.1.10/24
static routers=192.130.1.1
static domain_name_servers=8.8.8. 8.8.1.1
# fallback to static profile on eth0
interface eth0
fallback static_eth0
# Access Point Static interface mimirbox wlan0
interface wlan0
static ip_address=192.130.3.10/24
nohook wpa_supplicant
The target section is the static IP LAN profile, and nothing else.
I have written a programme that basically is divided into 2 sections:
- reads the input file into a hash.
- does a find and replace on the dhcpcd config file.
The programme works but it is a lot longer that it probably should be.
The programme is as follows:
#!/usr/bin/perl
use strict;
use warnings;
use Tie::File;
use feature "switch";
no warnings 'experimental';
# Declare constants
use constant false => 0;
use constant true => 1;
# Declare variables
my $ip_filename = '/home/mimir/mb_ip.cfg'; # The ip info entered by t
+he user into the GUI
my $dhcpcd_filename = '/home/mimir/d.conf'; # The dhcp configuration f
+ile to be written to
#my $dhcpcd_filename = '/etc/dhcpcd.conf';
# A hash of config parameters to be updated in order
# of how they should be saved.
# Initiate with reasonable start values.
my %ip_params = ( interface => "usb0",
ip_address => "1.1.1.0",
routers => "127.0.0.0",
domain_servers => "1.1.1.1");
my $ip_line; # whole parameter line
my @ip_fields; # parameter fields in a line
# The list of saved user param variables
tie my @ip_array, 'Tie::File', $ip_filename
or die "Cannot tie file '$ip_filename': $!";
########### Get param values from the GUI input file mb_ip.cfg
### Read the values from mb_ip.cfg and save to a hash
for $ip_line (@ip_array)
{
@ip_fields = split /=/, $ip_line; # get the parameter name and val
+ue
given ($ip_fields[0]){
when ( /interface/ ) {
$ip_params{'interface'} = $ip_fields[1]; }
when ( /ip_address/ ) {
$ip_params{'ip_address'} = $ip_fields[1]; }
when ( /routers/ ) {
$ip_params{'routers'} = $ip_fields[1]; }
when ( /domain_name_servers/ ) {
$ip_params{'domain_servers'} = $ip_fields[1]; }
default {
print "no match to params\n\n"
}
}
}
print "Network parameters loaded into the array \n"
+;
for(keys %ip_params){
print(" $_ is $ip_params{$_}\n");
}
untie @ip_array;
########### Find the lines in the config file to be replaced.
# Find the required interface section
# Initiate the boolean variables that only change one parameter
# in the config file section.
# When all are found and changed, jump out.
my $isFoundInterface = false;
my $isFoundIP = false;
my $isFoundRouters = false;
my $isFoundDNS = false;
# The config file to search and replace variables
tie my @dhcpcd_array, 'Tie::File', $dhcpcd_filename
or die "Cannot tie file '$dhcpcd_filename': $!";
print " \n\n\n";
# Find and replace the config lines
for $ip_line (@dhcpcd_array){
print "$ip_line\n";
# look for 'profile static_eth0' that marks start of the section
if ( $ip_line =~ /^.*profile\s*static_$ip_params{'interface'}\s*/ )
+ {
$isFoundInterface = true; # Found the first line of the sectio
+n.
print "############## Found profile line\n" ;
next; # Jump to the next line in the file.
}
# When the profile interface section is found, look for the parameters
+ to change
if ( $isFoundInterface == true ) {
given ($ip_line){
when ( /^.*static\s*ip_address=/ ) {
$ip_line = " static ip_address=$ip_params{'ip_address'}
+";
$isFoundIP = true;
}
when ( /^.*static\s*routers=/ ) {
$ip_line = " static routers=$ip_params{'routers'}";
$isFoundRouters = true;
}
when ( /^.*static\s*domain_name_servers=/ ) {
$ip_line = " static domain_name_servers=$ip_params{'dom
+ain_servers'}";
$isFoundDNS = true;
}
default { if ($isFoundInterface
and $isFoundIP
and $isFoundRouters
and $isFoundDNS ) { last; } #stop searching the co
+nfig file when changes all done.
}
}
}
print "isIP : $isFoundIP\n";
print "isRouters : $isFoundRouters\n";
print "isDNS : $isFoundDNS\n\n";
print "looking for the ip config params\n";
}
untie @dhcpcd_array;
Note:
The program still includes debug print statements.
None of the ip addresses are actually used by me.
I looked through the CPAN library and could not find anything that precisely suits my needs.
I don't do much perl programming so there is a lot I don't know.
I am seeking constructive feedback on my programme.
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: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.