ftp_die("(in $cwd) $msg",$exit_code);
}
+\f
+#
+# - Directive reader
+#
+
+=item $directive = read_directive ( $handle )
+
+Read a PGP-clearsigned directive from the provided handle, which must be
+open for reading. The handle is assumed to be positioned at the start of
+the file. This function will search for the PGP header and stop reading at
+the signature.
+
+The return value is an arrayref of key/value arrayrefs representing the
+directive elements in the first PGP-clearsigned message found while reading
+from HANDLE. The values in the returned structure are tainted.
+
+=cut
+
+sub read_directive {
+ my $directive = shift;
+
+ local *_;
+ my @records = ();
+
+ # First, we find the PGP signature header.
+ while (<$directive>) {
+ chomp; s/\r+$//; # remove line ending, including DOS type
+ last if m/^-----BEGIN PGP SIGNED MESSAGE-----$/;
+ }
+ # We are now in the armor headers.
+ while (<$directive>) {
+ chomp; s/\r+$//; # remove line ending, including DOS type
+ # According to RFC4880, there must be exactly one empty line to
+ # separate the signed message from the armor headers.
+ last if m/^$/;
+ }
+ # We are now looking at the signed message text.
+ while (<$directive>) {
+ chomp; s/\r+$//; # remove line ending, including DOS type
+ s/^\s+//; s/\s+$//; # trim leading and trailing whitespace
+
+ last if m/^-----BEGIN PGP SIGNATURE-----$/;
+
+ unless (/^$/) { # ignore blank lines
+ push @records, [split /\s+/,$_,2];
+ $records[-1][0] =~ s/\s*:$//; # trim trailing colon on key
+ }
+ }
+ # That is all: we have reached the signature and are done.
+ return \@records;
+}
+
+=item $directive = read_directive_from_file ( $filename )
+
+Read a PGP-clearsigned directive file and return an arrayref of key/value
+pair arrayrefs representing the directive elements in the signed portion of
+the file FILENAME. Any text in the file not within the first clearsigned
+message is ignored.
+
+The values returned from this procedure are tainted.
+
+=cut
+
+sub read_directive_from_file {
+ my $filename = shift;
+
+ open my $handle, '<', $filename
+ or die "open($filename) failed: $!";
+ my $records = read_directive($handle);
+ close $handle
+ or die "close($filename) failed: $!";
+
+ return $records;
+}
+
\f
#
# - [SC] Scan for incoming packets