Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

uudecode: implement -i option #381

Merged
merged 1 commit into from
Dec 17, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 63 additions & 22 deletions bin/uudecode
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,17 @@ License: perl

use strict;

END {
close STDOUT or die "$0: can't close stdout: $!\n";
$? = 1 if $? == 255; # from die
}
use File::Basename qw(basename);
use Getopt::Std qw(getopts);

my $output_file;
if( $ARGV[0] eq '-o' ) {
shift @ARGV;
$output_file = shift @ARGV;
}
use constant EX_SUCCESS => 0;
use constant EX_FAILURE => 1;

my $Program = basename($0);

my %opt;
getopts('io:', \%opt) or usage();
my $output_file = $opt{'o'};

FILESPEC :
while (<>) {
Expand All @@ -34,14 +35,26 @@ while (<>) {
$output_file = $header_name unless defined $output_file;

my $out;
if( $output_file eq '-' ) { open $out, '>&', STDOUT }
if ($output_file eq '-') {
$out = *STDOUT;
}
else {
open( $out, ">", $output_file ) or die "can't create <$output_file>: $!";
if ($opt{'i'} && -e $output_file) {
warn "$Program: won't clobber file '$output_file'\n";
exit EX_FAILURE;
}
unless (open $out, '>', $output_file) {
warn "$Program: can't create '$output_file': $!\n";
exit EX_FAILURE;
}
# Quickly protect file before data is written.
# XXX: Does this break on sub-Unix systems, like if
# it's a mode 400 or 000 file? If so, then we must
# wait until after the close.
chmod oct($mode), $output_file or die "can't chmod <$output_file> to mode <$mode>: $!";
unless (chmod oct($mode), $output_file) {
warn "$Program: can't chmod '$output_file' to mode '$mode': $!\n";
exit EX_FAILURE;
}
}

binmode($out); # winsop
Expand All @@ -56,13 +69,28 @@ LINE:
next LINE if /[a-z]/;
next LINE unless int((((ord() - 32) & 077) + 2) / 3)
== int(length() / 4);
print $out unpack("u", $_)
or die "can't write <$output_file>: $!";

unless (print $out unpack("u", $_)) {
warn "$Program: can't write '$output_file': $!\n";
exit EX_FAILURE;
}
}
unless (close $out) {
warn "$Program: can't close '$output_file': $!\n";
exit EX_FAILURE;
}
unless ($ended) {
warn "$Program: missing end; '$output_file' may be truncated\n";
exit EX_FAILURE;
}
close($out) or die "can't close <$output_file>: $!";
$ended or die "missing end; <$output_file> may be truncated";
}
exit EX_SUCCESS;

sub usage {
require Pod::Usage;
Pod::Usage::pod2usage({ -exitval => 1, -verbose => 0 });
}

__END__

=encoding utf8

Expand All @@ -73,7 +101,7 @@ uudecode - decode a binary file
=head1 SYNOPSIS

# decode to the name in the header
% uudecode file.uu
% uudecode [-i] file.uu

# decode to the name on the command line
% uudecode -o output.txt file.uu
Expand All @@ -84,11 +112,24 @@ uudecode - decode a binary file
=head1 DESCRIPTION

This program decodes a uuencoded file and saves the results to the file
denoted in the header line. If that filename is C<->, the output goes to
standard output.
denoted in the header line.

=head1 OPTIONS

The following options are available:

=over 4

=item -i

Do not overwrite files.

=item -o FILE

Write output to specified FILE, ignoring filename in uuencode header line.
If FILE is '-', standard output will be used.

You can override the file named in the uuencoded text by supplying a
second command-line argument.
=back

=head1 AUTHOR

Expand Down