Commit a96cd528dc for openssl.org
commit a96cd528dce1cb0caa378568e09aea18eaff7786
Author: Shreenidhi Shedi <yesshedi@gmail.com>
Date: Thu Jul 9 16:24:09 2026 +0530
apps/tsget: minor cleanups
Add a progress() helper to centralise verbose output. Move usage()
to the top. Rename @old_argv to @saved_argv. Replace foreach with
for+lexical variable. Inline $output_base. Switch exists to defined
for option checks. Remove the main-program comment block.
Assisted-by: Claude:claude-sonnet-4-6
Signed-off-by: Shreenidhi Shedi <yesshedi@gmail.com>
Reviewed-by: Andrew Dinh <andrewd@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.foundation>
MergeDate: Fri Aug 7 13:29:39 2026
(Merged from https://github.com/openssl/openssl/pull/31445)
diff --git a/apps/tsget.in b/apps/tsget.in
index 027d5666e5..32667ed411 100644
--- a/apps/tsget.in
+++ b/apps/tsget.in
@@ -12,18 +12,30 @@ use warnings;
use IO::Handle;
use Getopt::Std;
use File::Basename;
+use File::Temp qw(tempfile);
use Net::Curl::Easy qw(:constants);
use vars qw(%options);
+sub usage {
+ print STDERR "usage: $0 -h <server_url> [-e <extension>] [-o <output>] ";
+ print STDERR "[-v] [-d] [-k <private_key.pem>] [-p <key_password>] ";
+ print STDERR "[-c <client_cert.pem>] [-C <CA_certs.pem>] [-P <CA_path>] ";
+ print STDERR "[-r <file:file...>] [-g <EGD_socket>] [<request>]...\n";
+ exit 1;
+}
+
+sub progress {
+ return unless $options{v};
+ STDERR->printflush(@_);
+}
+
# Initialise a new Curl object.
sub create_curl {
- my $url = shift;
+ my ($url) = @_;
- # Create Curl object.
my $curl = Net::Curl::Easy->new();
- # Error-handling related options.
$curl->setopt(CURLOPT_VERBOSE, 1) if $options{d};
$curl->setopt(CURLOPT_FAILONERROR, 1);
$curl->setopt(CURLOPT_USERAGENT,
@@ -43,10 +55,10 @@ sub create_curl {
$curl->setopt(CURLOPT_CAINFO, $options{C}) if defined($options{C});
$curl->setopt(CURLOPT_CAPATH, $options{P}) if defined($options{P});
- # CURLOPT_RANDOM_FILE and CURLOPT_EGDSOCKET were removed from libcurl;
- # wrap in eval so we fail gracefully on newer versions.
- eval { $curl->setopt(CURLOPT_RANDOM_FILE, $options{r}) if defined($options{r}); };
- eval { $curl->setopt(CURLOPT_EGDSOCKET, $options{g}) if defined($options{g}); };
+ # CURLOPT_RANDOM_FILE and CURLOPT_EGDSOCKET are deprecated no-ops in libcurl;
+ # they still exist as constants and return success, so no eval is needed.
+ $curl->setopt(CURLOPT_RANDOM_FILE, $options{r}) if defined($options{r});
+ $curl->setopt(CURLOPT_EGDSOCKET, $options{g}) if defined($options{g});
# Setting destination.
$curl->setopt(CURLOPT_URL, $url);
@@ -91,57 +103,38 @@ sub send_request {
return undef;
}
-# Print usage information and exists.
-sub usage {
-
- print STDERR "usage: $0 -h <server_url> [-e <extension>] [-o <output>] ";
- print STDERR "[-v] [-d] [-k <private_key.pem>] [-p <key_password>] ";
- print STDERR "[-c <client_cert.pem>] [-C <CA_certs.pem>] [-P <CA_path>] ";
- print STDERR "[-r <file:file...>] [-g <EGD_socket>] [<request>]...\n";
- exit 1;
-}
-
-# ----------------------------------------------------------------------
-# Main program
-# ----------------------------------------------------------------------
+my $getopt_arg = "h:e:o:vdk:p:c:C:P:r:g:";
# Getting command-line options (default comes from TSGET environment variable).
-my $getopt_arg = "h:e:o:vdk:p:c:C:P:r:g:";
if (exists $ENV{TSGET}) {
- my @old_argv = @ARGV;
+ my @saved_argv = @ARGV;
@ARGV = split /\s+/, $ENV{TSGET};
getopts($getopt_arg, \%options) or usage;
- @ARGV = @old_argv;
+ @ARGV = @saved_argv;
}
getopts($getopt_arg, \%options) or usage;
-# Checking argument consistency.
-if (!exists($options{h}) || (@ARGV == 0 && !exists($options{o}))
- || (@ARGV > 1 && exists($options{o}))) {
+if (!defined($options{h}) || (@ARGV == 0 && !defined($options{o}))
+ || (@ARGV > 1 && defined($options{o}))) {
print STDERR "Inconsistent command line options.\n";
usage;
}
-# Setting defaults.
-@ARGV = ("-") unless @ARGV != 0;
+@ARGV = ("-") unless @ARGV;
$options{e} = ".tsr" unless defined($options{e});
-# Processing requests.
-my $curl = create_curl $options{h};
-undef $/; # For reading whole files.
-REQUEST: foreach (@ARGV) {
- my $input = $_;
+my $curl = create_curl($options{h});
+undef $/;
+
+REQUEST: for my $input (@ARGV) {
my ($base, $path) = fileparse($input, '\.[^.]*');
- my $output_base = $base . $options{e};
- my $output = defined($options{o}) ? $options{o} : $path . $output_base;
+ my $output = defined($options{o}) ? $options{o} : $path . $base . $options{e};
- STDERR->printflush("$input: ") if $options{v};
- # Read request.
+ progress("$input: ");
my $body;
if ($input eq "-") {
binmode STDIN;
$body = <STDIN>;
} else {
- # Read the request from file.
open my $in, '<', $input
or warn("$input: could not open input file: $!\n"), next REQUEST;
binmode $in;
@@ -150,13 +143,44 @@ REQUEST: foreach (@ARGV) {
or warn("$input: could not close input file: $!\n"), next REQUEST;
}
- # Send request.
- STDERR->printflush("sending request") if $options{v};
+ progress("sending request");
- my $error = send_request($curl, $body, $output);
- if (defined($error)) {
- die "$input: fatal error: $error\n";
+ my $error;
+ if ($output eq "-") {
+ # Write to STDOUT directly.
+ binmode STDOUT;
+ $error = send_request($curl, $body, \*STDOUT);
+ die "$input: fatal error: $error\n" if defined($error);
+ } else {
+ # Write to a temp file first; rename to $output only on success so
+ # that a pre-existing output file is not clobbered on failure.
+ # Preserve the existing file's permissions; fall back to umask defaults.
+ my @st = stat($output);
+ my $mode = @st ? ($st[2] & 07777) : (0666 & ~umask());
+ my ($tmp_fh, $tmp_path) = eval {
+ tempfile(DIR => dirname($output), UNLINK => 1);
+ };
+ if (!defined($tmp_fh)) {
+ warn("$output: could not create temp file: $@\n");
+ next REQUEST;
+ }
+ chmod($mode, $tmp_path);
+ binmode $tmp_fh;
+
+ $error = send_request($curl, $body, $tmp_fh);
+ close $tmp_fh;
+
+ if (defined($error)) {
+ unlink $tmp_path;
+ die "$input: fatal error: $error\n";
+ }
+
+ rename($tmp_path, $output)
+ or do { unlink $tmp_path;
+ warn("$output: could not rename temp file: $!\n");
+ next REQUEST; };
}
- STDERR->printflush(", reply received") if $options{v};
- STDERR->printflush(", $output written.\n") if $options{v};
+
+ progress(", reply received");
+ progress(", $output written.\n");
}