Net-MitDK
view release on metacpan or search on metacpan
lib/Net/MitDK.pm view on Meta::CPAN
}
sub create
{
my ($self, $profile, %opt) = @_;
my $file = $self->homepath . "/$profile.profile";
if ( -f $file ) {
return 2 if $opt{ok_if_exists};
return (undef, "Profile exists already");
}
return $self->save($profile, $opt{payload} // {} );
}
sub lock
{
my $f = shift;
return 1 if flock( $f, LOCK_NB | LOCK_EX);
sleep(1);
return 1 if flock( $f, LOCK_NB | LOCK_EX);
sleep(1);
return flock( $f, LOCK_NB | LOCK_EX);
}
sub load
{
my ($self, $profile ) = @_;
my $file = $self->homepath . "/$profile.profile";
return (undef, "No such profile") unless -f $file;
local $/;
open my $f, "<", $file or return (0, "Cannot open $file:$!");
return (undef, "Cannot acquire lock on $file") unless lock($f);
my $r = <$f>;
close $f;
my $json;
eval { $json = decode_json($r) };
return (undef, "Corrupted profile $file: $@") unless $json;
$self->{timestamps}->{$profile} = time;
return $json;
}
sub save
{
my ($self, $profile, $hash) = @_;
return (undef, "$profile is readonly") if $self->readonly;
my $home = $self->homepath;
unless ( -d $home ) {
mkdir $home or return (undef, "Cannot create $home: $!");
return (undef, "cannot chmod 0750 $home:$!") unless chmod 0750, $home;
if ( $^O !~ /win32/i) {
my (undef,undef,$gid) = getgrnam('nobody');
return (undef, "no group `nobody`") unless defined $gid;
return (undef, "cannot chown user:nobody $home:$!") unless chown $>, $gid, $home;
}
}
my $json;
my $encoder = JSON::XS->new->ascii->pretty;
eval { $json = $encoder->encode($hash) };
return (undef, "Cannot serialize profile: $!") if $@;
my $file = "$home/$profile.profile";
my $f;
if ( -f $file ) {
open $f, "+<", $file or return (undef, "Cannot create $file:$!");
return (undef, "Cannot acquire lock on $file") unless lock($f);
seek $f, 0, SEEK_SET;
truncate $f, 0 or return (undef, "Cannot save $file:$!");
} else {
open $f, ">", $file or return (undef, "Cannot create $file:$!");
}
print $f $json or return (undef, "Cannot save $file:$!");
close $f or return (undef, "Cannot save $file:$!");
if ( $^O !~ /win32/i) {
return (undef, "cannot chmod 0640 $file:$!") unless chmod 0640, $file;
my (undef,undef,$gid) = getgrnam('nobody');
return (undef, "no group `nobody`") unless defined $gid;
return (undef, "cannot chown user:nobody $file:$!") unless chown $>, $gid, $file;
}
$self->{timestamps}->{$profile} = time;
return 1;
}
sub remove
{
my ($self, $profile) = @_;
unlink $self->homepath . "/$profile.profile" or return (undef, "Cannot remove $profile:$!");
return 1;
}
sub refresh_needed
{
my ( $self, $profile ) = @_;
return 0 unless exists $self->{timestamps}->{$profile};
my $file = $self->homepath . "/$profile.profile";
my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat($file);
return 0 unless defined $mtime;
return $mtime > $self->{timestamps}->{$profile};
}
1;
=pod
=head1 NAME
Net::MitDK - perl API for http://mit.dk/
=head1 DESCRIPTION
Read-only interface for MitDK. See README for more info.
=head1 AUTHOR
Dmitry Karasik <dmitry@karasik.eu.org>
=cut
( run in 1.492 second using v1.01-cache-2.11-cpan-71847e10f99 )