use Crypt::PRNG qw(random_bytes);
use File::KDBX::Constants qw(:key_file);
use File::KDBX::Error;
-use File::KDBX::Util qw(:erase trim);
+use File::KDBX::Util qw(:class :erase trim);
use Ref::Util qw(is_ref is_scalarref);
use Scalar::Util qw(openhandle);
use XML::LibXML::Reader;
use namespace::clean;
-use parent 'File::KDBX::Key';
+extends 'File::KDBX::Key';
our $VERSION = '999.999'; # VERSION
+=attr type
+
+ $type = $key->type;
+
+Get the type of key file. Can be one of from L<File::KDBX::Constants/":key_file">:
+
+=for :list
+* C<KEY_FILE_TYPE_BINARY>
+* C<KEY_FILE_TYPE_HEX>
+* C<KEY_FILE_TYPE_XML>
+* C<KEY_FILE_TYPE_HASHED>
+
+=attr version
+
+ $version = $key->version;
+
+Get the file version. Only applies to XML key files.
+
+=attr filepath
+
+ $filepath = $key->filepath;
+
+Get the filepath to the key file, if known.
+
+=cut
+
+has 'type', is => 'ro';
+has 'version', is => 'ro';
+has 'filepath', is => 'ro';
+
=method load
$key = $key->load($filepath);
return $self;
}
-=attr type
-
- $type = $key->type;
-
-Get the type of key file. Can be one of:
-
-=for :list
-* C<KEY_FILE_TYPE_BINARY>
-* C<KEY_FILE_TYPE_HEX>
-* C<KEY_FILE_TYPE_XML>
-* C<KEY_FILE_TYPE_HASHED>
-
-=cut
-
-sub type { $_[0]->{type} }
-
-=attr version
-
- $version = $key->version;
-
-Get the file version. Only applies to XML key files.
-
-=cut
-
-sub version { $_[0]->{version} }
-
-=attr filepath
-
- $filepath = $key->filepath;
-
-Get the filepath to the key file, if known.
-
-=cut
-
-sub filepath { $_[0]->{filepath} }
-
=method save
$key->save;
* C<filepath> - Where to save the file (default: value of L</filepath>)
* C<fh> - IO handle to write to (overrides C<filepath>, one of which must be defined)
* C<raw_key> - Raw key (default: value of L</raw_key>)
+* C<atomic> - Write to the filepath atomically (default: true)
=cut
my $version = $args{version} // $self->version // 2;
my $filepath = $args{filepath} // $self->filepath;
my $fh = $args{fh};
+ my $atomic = $args{atomic} // 1;
my $filepath_temp;
if (!openhandle($fh)) {
$filepath or throw 'Must specify where to safe the key file to';
- require File::Temp;
- ($fh, $filepath_temp) = eval { File::Temp::tempfile("${filepath}-XXXXXX", CLEANUP => 1) };
- if (!$fh or my $err = $@) {
- $err //= 'Unknown error';
- throw sprintf('Open file failed (%s): %s', $filepath_temp, $err),
- error => $err,
- filepath => $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;
}
}