package Lemonldap::NG::Common::Conf::File; use strict; use utf8; use Lemonldap::NG::Common::Conf::Constants; #inherits use JSON::MaybeXS; our $VERSION = '1.4.0'; our $initDone; sub Lemonldap::NG::Common::Conf::_lock { my ( $self, $cfgNum ) = @_; return "$self->{dirName}/lmConf.lock"; } sub Lemonldap::NG::Common::Conf::_file { my ( $self, $cfgNum ) = @_; return "$self->{dirName}/lmConf-$cfgNum.js"; } sub prereq { my $self = shift; unless ( $self->{dirName} ) { $Lemonldap::NG::Common::Conf::msg .= '"dirName" is required in "File" configuration type ! \n'; return 0; } unless ( -d $self->{dirName} ) { $Lemonldap::NG::Common::Conf::msg .= "Directory \"$self->{dirName}\" does not exist ! \n"; return 0; } 1; } sub available { my $self = shift; opendir D, $self->{dirName}; my @conf = readdir(D); closedir D; @conf = sort { $a <=> $b } map { /lmConf-(\d+)(?:\.js)?/ ? ( $1 + 0 ) : () } @conf; return @conf; } sub lastCfg { my $self = shift; my @avail = $self->available; return $avail[$#avail]; } sub lock { my $self = shift; if ( $self->isLocked ) { sleep 2; return 0 if ( $self->isLocked ); } unless ( open F, ">" . $self->_lock ) { $Lemonldap::NG::Common::Conf::msg .= "Unable to lock (" . $self->_lock . ") \n"; return 0; } print F $$; close F; return 1; } sub isLocked { my $self = shift; -e $self->_lock; } sub unlock { my $self = shift; unlink $self->_lock; 1; } sub store { my ( $self, $fields ) = @_; my $mask = umask; umask( oct('0027') ); unless ( open FILE, ">" . $self->_file( $fields->{cfgNum} ) ) { $Lemonldap::NG::Common::Conf::msg .= "Open file failed: $! \n"; $self->unlock; return UNKNOWN_ERROR; } print FILE JSON->new->canonical(1)->encode($fields); close FILE; umask($mask); return $fields->{cfgNum}; } sub load { my ( $self, $cfgNum, $fields ) = @_; my $f; if ( -e $self->_file($cfgNum) ) { local $/ = ''; open FILE, $self->_file($cfgNum) or die "$!$@"; $f = join( '', ); close FILE; my $ret = eval { decode_json($f); }; die "Unable to load conf: $@\n" if ($@); return $ret; } # Old format elsif ( -e "$self->{dirName}/lmConf-$cfgNum" ) { open FILE, "$self->{dirName}/lmConf-$cfgNum" or die "$!$@"; local $/ = ""; unless ( open FILE, $self->{dirName} . "/lmConf-$cfgNum" ) { $Lemonldap::NG::Common::Conf::msg .= "Open file failed: $! \n"; return undef; } while () { my ( $k, $v ) = split /\n\s+/; chomp $k; $v =~ s/\n*$//; if ($fields) { $f->{$k} = $v if ( grep { $_ eq $k } @$fields ); } else { $f->{$k} = $v; } } close FILE; require Lemonldap::NG::Common::Conf::Serializer; return $self->unserialize($f); } else { $Lemonldap::NG::Common::Conf::msg .= "Unable to find configuration file"; return undef; } } sub delete { my ( $self, $cfgNum ) = @_; my $file = $self->_file($cfgNum); if ( -e $file ) { my $res = unlink($file); $Lemonldap::NG::Common::Conf::msg .= $! unless ($res); return $res; } else { $Lemonldap::NG::Common::Conf::msg .= "Unable to delete conf $cfgNum, no such file"; return 0; } } 1; __END__