-->

Perl updating a value in .conf file from a form

2020-03-08 08:22发布

问题:

I have a admin.conf file and the file looks like this. For example,

[online_offline_status]
online_offline_status.online_offline_state = ONLINE

i have another file called index.cgi that works as a form. For example,

#!/usr/bin/perl
#index.cgi

require 'foobar-lib.pl';


ui_print_header(undef, $module_info{'desc'}, "", undef, 1, 1);


ui_print_footer("/", $text{'index'});

print "Content-type:text/html\n\n";
print qq~
<html>
<head>
<link rel="stylesheet" type="text/css" href="cstyle17.css">
</head>
<body>
<div id="content">
<div id="bar">
<span><p>Controller Settings</p></span>
</div>
<div id="tab-container">
<ul>
<li class="active"><span><a href="index.cgi">Offline / Online Status</a></span></li>
<li><span><a href="#">Data Online</a></span></li>
</ul>
</div>
<div id="main-container">
<table width='100%' height='60%'>
<tr>
<td width="50%" align="left">
<div id="title"><span>Offline / Online Status :</span></div>
</td>
<td>
<div id="form">
<form method="POST" action="index9.cgi">
<input type="radio" name="state" value="online">Online
<br/>
<input type="radio" name="state" value="offline">Offline
</div>
</td>
</tr>
<tr>
<td colspan='2'>
<div id="button">
<input type="submit" value="Submit"><input type="reset" value="Clear">
</div>
</td>
</tr>
</form>
</table>
</div>
</div>

</body>
</html>

~;

When the user choose one of the radio option button and submit. The value will be sent to index9.cgi. It will process the form in this file (index9.cgi)

#!/usr/bin/perl
#index.cgi

require 'foobar-lib.pl';


ui_print_header(undef, $module_info{'desc'}, "", undef, 1, 1);


ui_print_footer("/", $text{'index'});

local ($buffer, @pairs, $pair, $name, $value, %FORM);
# Read in text
$ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/;
if ($ENV{'REQUEST_METHOD'} eq "POST")
{
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
}else {
$buffer = $ENV{'QUERY_STRING'};
}
# Split information into name/value pairs
@pairs = split(/&/, $buffer);
foreach $pair (@pairs)
{
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%(..)/pack("C", hex($1))/eg;
$FORM{$name} = $value;
}
$status = $FORM{state};

print "Content-type:text/html\n\n";
print qq~
<html>
<head>
<link rel="stylesheet" type="text/css" href="cstyle17.css">
</head>
<body>
<div id="content">
<div id="bar">
<span><p>Controller Settings</p></span>
</div>
<div id="tab-container">
<ul>
<li class="active"><span><a href="index.cgi">Offline / Online Status</a></span></li>
<li><span><a href="#">Data Online</a></span></li>
</ul>
</div>
<div id="main-container">
<table width='100%' height='60%'>
<tr>
<td width="50%" align="left">
<div id="title"><span>Offline / Online State :</span></div>
</td>
<td>
<div id="form">
<form method="link" action="index.cgi">
<p>Offline / Online state has been changed to : <b>$status</b><p>
</div>
</td>
</tr>
<tr>
<td colspan='2'>
<div id="button">
<input type="submit" value="Back">
</div>
</td>
</tr>
</form>
</table>
</div>
</div>

</body>
</html>

~;

Is it possible for when the user choose "offline" in index.cgi and sent to process the value ("offline") in index9.cgi, the value in the .conf file also be updated from ONLINE to OFFLINE?

回答1:

Yes, it is possible.

Dirtiest way is to change the file on place via sed script, called from Perl..

Better way is to open the file in perl, read into a string, replace offline with online and print it out again, clobbering the old file.

ps: Did you hear about CGI.pm? It could ease your work.

Ps Ps: It would be better to use some modern web framework, like mojolicious, Dancer.

with CGI.pm

(be sure that the admin.conf is writeable by the webserver account)

In index9.cgi

use strict;
use warnings;
use CGI;
use Config::Tiny;
use Data::Dumper;
use CGI::Carp qw(fatalsToBrowser);

my $q = CGI->new;
print $q->header();
my $state = $q->param('state');
my $file = "/full/path/to/admin.conf";
my $Config = Config::Tiny->read( $file );
my $status_in_file = $Config->{online_offline_status}->{online_offline_status.online_offline_state};

my $msg = "No changes being made";
$msg = "Status changed from $status_in_file to $status" if $status_in_file ne $status;
$Config->{online_offline_status}->{online_offline_status.online_offline_state} = $status;
$Config->write( $file );



print qq~
<html>
<head>
<link rel="stylesheet" type="text/css" href="cstyle17.css">
</head>
<body>
<div id="content">
<div id="bar">
<span><p>Controller Settings</p></span>
</div>
<div id="tab-container">
<ul>
<li class="active"><span><a href="index.cgi">Offline / Online Status</a></span></li>
<li><span><a href="#">Data Online</a></span></li>
</ul>
</div>
<div id="main-container">
<table width='100%' height='60%'>
<tr>
<td width="50%" align="left">
<div id="title"><span>Offline / Online State :</span></div>
</td>
<td>
<div id="form">
<form method="link" action="index.cgi">
<p>$msg</p>
</div>
</td>
</tr>
<tr>
<td colspan='2'>
<div id="button">
<input type="submit" value="Back">
</div>
</td>
</tr>
</form>
</table>
</div>
</div>

</body>
</html>

~;