MYDan
view release on metacpan or search on metacpan
lib/MYDan/Agent/Query.pm view on Meta::CPAN
=head3 load( $query )
Inverse of dump().
=cut
sub load
{
my ( $class, $query, $yaml, $data ) = splice @_;
if ( $query =~ s/^data:(\d+):// )
{
$data = substr( $query, 0, $1 );
substr( $query, 0, $1 ) = '';
$data = eval{ YAML::XS::Load Compress::Zlib::uncompress( $data ) };
die "invalid data" if $@;
}
die "invalid $query\n" unless
( $yaml = Compress::Zlib::uncompress( $query ) )
&& eval { $query = YAML::XS::Load $yaml }
&& ref $query eq 'HASH' && $query->{code};
idie( "code format error:$query->{code}\n" ) unless $query->{code} =~ /^[A-Za-z0-9_\.]+$/;
$yaml = YAML::XS::Dump +{ map{ $_ => $query->{$_} }grep{ $_ !~ /^__/ }keys %$query };
if( $o{'auth'} && $query->{code} !~ /^free\./ )
{
my $auth = delete $query->{auth};
idie( "auth fail\n" ) unless MYDan::Agent::Auth->new(
pub => $o{'auth'}
)->verify( $auth, YAML::XS::Dump $query );
idie ( "peri undef\n" ) unless my $peri = delete $query->{peri};
my @peri = split '#', $peri;
idie( "peri fail\n" ) unless $peri[0] < time && time < $peri[1];
}
idie( "auth fail.access\n" ) if $query->{node} && 0 == grep { $query->{node}{$_} } @myip;
$query->{data} = $data if $data;
bless { yaml => $yaml, query => $query }, ref $class || $class;
}
=head3 run( %path )
Run code in $path{code}. If code name is postfixed with '.mx',
run code in mutual exclusion mode.
=cut
sub run
{
my ( $self, %path ) = @_;
my $query = $self->{query};
my ( $code, $sudo, $env ) = @$query{ qw( code sudo env ) };
idie( "already running $code\n" ) if ( $code =~ /\.mx$/ ) && !
MYDan::Util::ProcLock->new( File::Spec->join( $path{run}, $code ) )->lock();
if ( $code ne 'proxy' && ! $< && $sudo && $sudo ne ( getpwuid $< )[0] )
{
idie( "invalid sudo $sudo\n" ) unless my @pw = getpwnam $sudo;
@pw = map { 0 + sprintf '%d', $_ } @pw[2,3];
POSIX::setgid( $pw[1] ); ## setgid must preceed setuid
POSIX::setuid( $pw[0] );
}
%ENV = ( %ENV, %$env ) if $env && ref $env eq 'HASH';
map{ $ENV{"MYDan_$_"} = $query->{$_} }qw( user sudo );
my $tmpfile = "tmp.agent.$$";
MYDan::Util::ReservedSpace::File::dump( $tmpfile, $query );
open STDIN, '<', "$MYDan::PATH/tmp/$tmpfile" or idie( "Can't open '$tmpfile': $!" );
MYDan::Util::ReservedSpace::File::unlink( $tmpfile );
exec "$path{code}/$code";
}
=head3 yaml()
Return query in YAML.
=cut
sub yaml
{
my $self = shift;
return $self->{yaml};
}
sub idie
{
my $info = shift;
print "MYDan $info";die $info;
}
1;
( run in 0.781 second using v1.01-cache-2.11-cpan-39bf76dae61 )