File-KDBX
view release on metacpan or search on metacpan
lib/File/KDBX/Dumper.pm view on Meta::CPAN
my %args = @_ % 2 == 0 ? @_ : (key => shift, @_);
my $key = delete $args{key};
$args{kdbx} //= $self->kdbx;
$ref //= do {
my $buf = '';
\$buf;
};
open(my $fh, '>', $ref) or throw "Failed to open string buffer: $!";
$self = $self->new if !ref $self;
$self->init(%args, fh => $fh)->_dump($fh, $key);
return $ref;
}
sub dump_file {
my $self = shift;
my $filepath = shift;
my %args = @_ % 2 == 0 ? @_ : (key => shift, @_);
my $key = delete $args{key};
my $mode = delete $args{mode};
my $uid = delete $args{uid};
my $gid = delete $args{gid};
my $atomic = delete $args{atomic} // 1;
$args{kdbx} //= $self->kdbx;
my ($fh, $filepath_temp);
if ($atomic) {
require File::Temp;
($fh, $filepath_temp) = eval { File::Temp::tempfile("${filepath}-XXXXXX", UNLINK => 1) };
if (!$fh or my $err = $@) {
$err //= 'Unknown error';
throw sprintf('Open file failed (%s): %s', $filepath_temp, $err),
error => $err,
filepath => $filepath_temp;
}
}
else {
open($fh, '>:raw', $filepath) or throw "Open file failed ($filepath): $!", filepath => $filepath;
}
$fh->autoflush(1);
$self = $self->new if !ref $self;
$self->init(%args, fh => $fh, filepath => $filepath);
$self->_dump($fh, $key);
close($fh);
my ($file_mode, $file_uid, $file_gid) = (stat($filepath))[2, 4, 5];
if ($filepath_temp) {
$mode //= $file_mode // do { my $m = umask; defined $m ? oct(666) &~ $m : undef };
$uid //= $file_uid // -1;
$gid //= $file_gid // -1;
chmod($mode, $filepath_temp) if defined $mode;
chown($uid, $gid, $filepath_temp);
rename($filepath_temp, $filepath) or throw "Failed to write file ($filepath): $!",
filepath => $filepath;
}
return $self;
}
sub dump_handle {
my $self = shift;
my $fh = shift;
my %args = @_ % 2 == 0 ? @_ : (key => shift, @_);
$fh = *STDOUT if $fh eq '-';
my $key = delete $args{key};
$args{kdbx} //= $self->kdbx;
$self = $self->new if !ref $self;
$self->init(%args, fh => $fh)->_dump($fh, $key);
}
sub kdbx {
my $self = shift;
return File::KDBX->new if !ref $self;
$self->{kdbx} = shift if @_;
$self->{kdbx} //= File::KDBX->new;
}
has 'format', is => 'ro';
has 'inner_format', is => 'ro', default => 'XML';
has 'allow_upgrade', is => 'ro', default => 1;
has 'randomize_seeds', is => 'ro', default => 1;
sub _fh { $_[0]->{fh} or throw 'IO handle not set' }
sub _dump {
my $self = shift;
my $fh = shift;
my $key = shift;
my $kdbx = $self->kdbx;
my $min_version = $kdbx->minimum_version;
if ($kdbx->version < $min_version && $self->allow_upgrade) {
alert sprintf("Implicitly upgrading database from %x to %x\n", $kdbx->version, $min_version),
version => $kdbx->version, min_version => $min_version;
$kdbx->version($min_version);
}
$self->_rebless;
if (ref($self) =~ /::(?:KDB|V[34])$/) {
$key //= $kdbx->key ? $kdbx->key->reload : undef;
defined $key or throw 'Must provide a master key', type => 'key.missing';
}
$self->_prepare;
lib/File/KDBX/Dumper.pm view on Meta::CPAN
=over 4
=item *
C<kdbx> - Database to dump (default: value of L</kdbx>)
=item *
C<key> - Alternative way to specify C<$key> (default: value of L</File::KDBX/key>)
=back
Other options are supported depending on the first argument. See L</dump_string>, L</dump_file> and
L</dump_handle>.
=head2 dump_string
$dumper->dump_string(\$string, %options);
$dumper->dump_string(\$string, $key, %options);
\$string = $dumper->dump_string(%options);
\$string = $dumper->dump_string($key, %options);
Dump a KDBX file to a string / memory buffer. Available options:
=over 4
=item *
C<kdbx> - Database to dump (default: value of L</kdbx>)
=item *
C<key> - Alternative way to specify C<$key> (default: value of L</File::KDBX/key>)
=back
=head2 dump_file
$dumper->dump_file($filepath, %options);
$dumper->dump_file($filepath, $key, %options);
Dump a KDBX file to a filesystem. Available options:
=over 4
=item *
C<kdbx> - Database to dump (default: value of L</kdbx>)
=item *
C<key> - Alternative way to specify C<$key> (default: value of L</File::KDBX/key>)
=item *
C<mode> - File mode / permissions (see L<perlfunc/"chmod LIST">
=item *
C<uid> - User ID (see L<perlfunc/"chown LIST">)
=item *
C<gid> - Group ID (see L<perlfunc/"chown LIST">)
=item *
C<atomic> - Write to the filepath atomically (default: true)
=back
=head2 dump_handle
$dumper->dump_handle($fh, %options);
$dumper->dump_handle(*IO, $key, %options);
$dumper->dump_handle($fh, %options);
$dumper->dump_handle(*IO, $key, %options);
Dump a KDBX file to an output stream / file handle. Available options:
=over 4
=item *
C<kdbx> - Database to dump (default: value of L</kdbx>)
=item *
C<key> - Alternative way to specify C<$key> (default: value of L</File::KDBX/key>)
=back
=head1 BUGS
Please report any bugs or feature requests on the bugtracker website
L<https://github.com/chazmcgarvey/File-KDBX/issues>
When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.
=head1 AUTHOR
Charles McGarvey <ccm@cpan.org>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2022 by Charles McGarvey.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut
( run in 0.520 second using v1.01-cache-2.11-cpan-71847e10f99 )