webmin/phpini/phpini-lib.pl

287 lines
7.0 KiB
Perl
Raw Normal View History

2007-04-12 20:24:50 +00:00
# Functions for managing the PHP configuration file
2009-03-01 21:35:40 +00:00
BEGIN { push(@INC, ".."); };
use WebminCore;
2007-04-12 20:24:50 +00:00
&init_config();
%access = &get_module_acl();
# get_config([file])
# Returns an array ref of PHP configuration directives from some file
sub get_config
{
local ($file) = @_;
2010-01-08 13:06:15 -08:00
$file ||= &get_default_php_ini();
2007-04-12 20:24:50 +00:00
if (!defined($get_config_cache{$file})) {
local @rv = ( );
local $lnum = 0;
local $section;
2009-07-02 23:51:56 +00:00
open(CONFIG, $file) || return undef;
2007-04-12 20:24:50 +00:00
while(<CONFIG>) {
s/\r|\n//g;
s/\s+$//;
2007-05-05 04:48:38 +00:00
local $uq;
2007-04-12 20:24:50 +00:00
if (/^(;?)\s*(\S+)\s*=\s*"(.*)"/ ||
/^(;?)\s*(\S+)\s*=\s*'(.*)'/ ||
2007-05-05 04:48:38 +00:00
($uq = ($_ =~ /^(;?)\s*(\S+)\s*=\s*(.*)/))) {
2007-04-12 20:24:50 +00:00
# Found a variable
push(@rv, { 'name' => $2,
'value' => $3,
'enabled' => !$1,
'line' => $lnum,
'file' => $file,
'section' => $section,
});
2007-05-05 04:48:38 +00:00
if ($uq) {
# Remove any comments
$rv[$#rv]->{'value'} =~ s/\s+;.*$//;
}
2007-04-12 20:24:50 +00:00
}
elsif (/^\[(.*)\]/) {
# A new section
$section = $1;
}
$lnum++;
}
close(CONFIG);
$get_config_cache{$file} = \@rv;
}
return $get_config_cache{$file};
}
# find(name, &config, [disabled-mode])
sub find
{
local ($name, $conf, $mode) = @_;
local @rv = grep { lc($_->{'name'}) eq lc($name) &&
($mode == 0 && $_->{'enabled'} ||
$mode == 1 && !$_->{'enabled'} ||
$mode == 2) } @$conf;
return wantarray ? @rv : $rv[0];
}
sub find_value
{
local @rv = map { $_->{'value'} } &find(@_);
return $rv[0];
}
2010-06-19 14:07:44 -07:00
# save_directive(&config, name, [value], [newsection], [neverquote])
2007-04-12 20:24:50 +00:00
# Updates a single entry in the PHP config file
sub save_directive
{
2010-06-19 14:07:44 -07:00
local ($conf, $name, $value, $newsection, $noquote) = @_;
2007-04-12 20:24:50 +00:00
$newsection ||= "PHP";
local $old = &find($name, $conf, 0);
local $cmt = &find($name, $conf, 1);
local $lref;
local $newline = $name." = ".
2010-06-19 14:07:44 -07:00
($value !~ /\s/ || $noquote ? $value :
2007-04-12 20:24:50 +00:00
$value =~ /"/ ? "'$value'" : "\"$value\"");
if (defined($value) && $old) {
# Update existing value
$lref = &read_file_lines($old->{'file'});
$lref->[$old->{'line'}] = $newline;
$old->{'value'} = $value;
}
elsif (defined($value) && !$old && $cmt) {
# Update existing commented value
$lref = &read_file_lines($cmt->{'file'});
$lref->[$cmt->{'line'}] = $newline;
$cmt->{'value'} = $value;
$cmt->{'enabled'} = 1;
}
elsif (defined($value) && !$old && !$cmt) {
# Add a new value, at the end of the section
local $last;
foreach my $c (@$conf) {
if ($c->{'section'} eq $newsection) {
$last = $c;
}
}
if ($last) {
# Found last value in the section - add after it
$lref = &read_file_lines($last->{'file'});
splice(@$lref, $last->{'line'}+1, 0, $newline);
&renumber($conf, $last->{'line'}, 1);
push(@$conf, { 'name' => $name,
'value' => $value,
'enabled' => 1,
'file' => $last->{'file'},
'line' => $last->{'line'}+1,
'section' => $newsection,
});
}
else {
&error("Could not find any values in section $newsection");
}
}
elsif (!defined($value) && $old && $cmt) {
# Totally remove a value
$lref = &read_file_lines($old->{'file'});
splice(@$lref, $old->{'line'}, 1);
@$conf = grep { $_ ne $old } @$conf;
&renumber($conf, $old->{'line'}, -1);
}
elsif (!defined($value) && $old && !$cmt) {
# Turn a value into a comment
$lref = &read_file_lines($old->{'file'});
$old->{'enabled'} = 0;
$lref->[$old->{'line'}] = "; ".$lref->[$old->{'line'}];
}
}
sub renumber
{
local ($conf, $line, $oset) = @_;
foreach my $c (@$conf) {
$c->{'line'} += $oset if ($c->{'line'} > $line);
}
}
# can_php_config(file)
# Returns 1 if some config file can be edited
sub can_php_config
{
local ($file) = @_;
return &indexof($file, map { $_->[0] } &list_php_configs()) >= 0 ||
$access{'anyfile'};
}
2010-01-08 13:06:15 -08:00
# get_default_php_ini()
# Returns the first php.ini that exists
sub get_default_php_ini
{
2013-03-30 17:56:53 -07:00
local @inis = split(/\t+/, $config{'php_ini'});
foreach my $ai (@inis) {
2010-01-08 13:06:15 -08:00
local ($f, $d) = split(/=/, $ai);
return $f if (-r $f);
}
2013-03-30 17:56:53 -07:00
if (-r $config{'alt_php_ini'} && @inis) {
# Fall back to default file
local ($f) = split(/=/, $inis[0]);
&copy_source_dest($config{'alt_php_ini'}, $f);
return $f;
}
2010-01-08 13:06:15 -08:00
return undef;
}
2007-04-12 20:24:50 +00:00
# list_php_configs()
2010-01-08 13:06:15 -08:00
# Returns a list of allowed config files and descriptions
2007-04-12 20:24:50 +00:00
sub list_php_configs
{
local @rv;
2013-03-30 17:56:53 -07:00
&get_default_php_ini(); # Force copy of sample ini file
2007-04-12 20:24:50 +00:00
if ($access{'global'}) {
foreach my $ai (split(/\t+/, $config{'php_ini'})) {
local ($f, $d) = split(/=/, $ai);
push(@rv, [ $f, $d || $text{'file_global'} ]);
}
}
foreach my $ai (split(/\t+/, $access{'php_inis'})) {
local ($f, $d) = split(/=/, $ai);
push(@rv, [ $f, $d || $f ]);
}
if (&foreign_installed("virtual-server")) {
&foreign_require("virtual-server");
foreach my $v (&virtual_server::list_available_php_versions()) {
if ($v->[0]) {
my $ini = &virtual_server::get_global_php_ini($v->[0]);
push(@rv, [ $ini, "PHP $v->[0]" ]) if ($ini && -r $ini);
}
}
}
my %done;
return grep { !$done{$_->[0]}++ } @rv;
2007-04-12 20:24:50 +00:00
}
# onoff_radio(name)
# Returns a field for editing a binary configuration value
sub onoff_radio
{
local ($name) = @_;
local $v = &find_value($name, $conf);
return &ui_radio($name, lc($v) eq "on" || lc($v) eq "true" ||
lc($v) eq "yes" || $v eq "1" ? "On" : $v ? "Off" : "",
[ !$v ? ( [ "", $text{'default'} ] ) : ( ),
[ "On", $text{'yes'} ],
[ "Off", $text{'no'} ] ]);
}
# graceful_apache_restart()
# Signal a graceful Apache restart, to pick up new php.ini settings
sub graceful_apache_restart
{
if (&foreign_installed("apache")) {
&foreign_require("apache", "apache-lib.pl");
if (&apache::is_apache_running() &&
$apache::httpd_modules{'core'} >= 2 &&
&has_command($apache::config{'apachectl_path'})) {
&clean_environment();
&system_logged("$apache::config{'apachectl_path'} graceful >/dev/null 2>&1");
&reset_environment();
}
}
}
2009-07-02 23:51:56 +00:00
# get_config_as_user([file])
# Like get_config, but reads with permissions of the ACL user
sub get_config_as_user
{
local ($file) = @_;
if ($access{'user'} && $access{'user'} ne 'root' && $< == 0) {
local $rv = &eval_as_unix_user(
$access{'user'}, sub { &get_config($file) });
if ((!$rv || !@$rv) && $!) {
&error(&text('file_eread', &html_escape($file), $!));
}
return $rv;
}
else {
return &get_config($file);
}
}
# read_file_contents_as_user(file)
sub read_file_contents_as_user
{
local ($file) = @_;
if ($access{'user'} && $access{'user'} ne 'root' && $< == 0) {
return &eval_as_unix_user(
$access{'user'}, sub { &read_file_contents($file) });
}
else {
return &read_file_contents($file);
}
}
# write_file_contents_as_user(file, data)
# Writes out the contents of some file
sub write_file_contents_as_user
{
local ($file, $data) = @_;
if ($access{'user'} && $access{'user'} ne 'root' && $< == 0) {
return &eval_as_unix_user(
$access{'user'}, sub { &write_file_contents($file, $data) });
}
else {
&write_file_contents($file, $data);
}
}
2009-07-02 23:51:56 +00:00
# flush_file_lines_as_user(file)
# Writes out a file as the Unix user configured in this module's ACL
sub flush_file_lines_as_user
{
local ($file) = @_;
if ($access{'user'} && $access{'user'} ne 'root' && $< == 0) {
&eval_as_unix_user($access{'user'},
sub { &flush_file_lines($file) });
}
else {
&flush_file_lines($file);
}
}
2007-04-12 20:24:50 +00:00
1;