#!/usr/bin/perl -w # vim: set sw=4 ts=4 si et: # Written by: Guido Socher # To use this you will need the command uudecode in your PATH. # Version: 2018-08-27 # - first version # Version: 2018-10-22 # - sanitize file names # - option to decode all sections # Version: 2018-10-24 # - bug fix: end of uuencode not detected properly # Version: 2018-11-22 # - fix spelling error in error message use strict; use vars qw($opt_u $opt_h); use Getopt::Std; sub help(); sub printuuencode(); sub uudec_at($$$); sub show_avail_uu($); # getopts("hu")||exit 1; help() if ($opt_h); printuuencode() if ($opt_u); help() unless($ARGV[0]); my @uuenc_in_file=(); my $infile=$ARGV[0]; show_avail_uu($infile); if (scalar(@uuenc_in_file)<1){ print "ERROR: no uuencoded section found in file $infile\n"; exit 1; } my $dec=0; print "which uuencode do you want to decode? (1..".scalar(@uuenc_in_file).", 0 for all) >"; $dec=; chomp($dec); # in case somebody types "a" or "all" install of 0: if ($dec=~/^[aA]l?l?$/){ $dec=0; } if ($dec=~/(\d+)/){ if ($1 >= 0 && $1 <= (scalar(@uuenc_in_file))){ $dec=$1; }else{ print "ERROR: out of range :-(. exit\n"; exit 1; } }else{ print "ERROR: you should have entered a number :-(. exit\n"; exit 1; } my $uudec_l=0; my $uudec_name=""; if ($dec==0){ for my $todec (@uuenc_in_file){ if ($todec=~ /^(\d+);(.+)/){ $uudec_l=$1; $uudec_name=$2; uudec_at($infile,$uudec_l,$uudec_name); }else{ die "ERROR: unknown uuenc_in_file format: $todec\n"; } } }else{ if ($uuenc_in_file[$dec-1] =~ /^(\d+);(.+)/){ $uudec_l=$1; $uudec_name=$2; uudec_at($infile,$uudec_l,$uudec_name); }else{ die "ERROR: index $dec not found\n"; } } sub uudec_at($$$){ my $infile=shift; my $uudec_l=shift; my $uudec_name=shift; print "OK: decoding now $infile at line $uudec_l to file $uudec_name ... "; open(FF,"$infile")||die "ERROR: can not read $infile\n"; my $ln=0; my $state=0; while(){ $ln++; if ($ln == $uudec_l){ if (/^begin (\d+) /){ my $mode=$1; $_="begin $mode $uudec_name\n\r"; open(OU,"|uudecode")||die; $state=1; }else{ die "ERROR: no begin found at line $ln\n" } } next unless($state==1); s/\r$//; print OU; if (/^end\s*$/){ print "done\n"; close OU; $state=0; } } close FF; } # show available uuencoded sections in file, writes to @uuenc_in_file sub show_avail_uu($){ my $filename=shift; my $l=0; my $uucnt=0; open(FF,"$filename")||die "ERROR: can not read $filename\n"; while(){ $l++; if (/^begin (\d+) (\S.*)/){ my $t=$2; my $t_orig; my $mode=$1; $t=~s/[\n\r]//g; $t_orig=$t; $t=~s/[^\w\.\-]/_/g; # clean file name, sanitize $uucnt++; print "$uucnt) line $l: begin $mode $t_orig (will be: \"$t\")"; if (-f $t){ print ", file exists, would overwrite.\n"; }else{ print "\n"; } push(@uuenc_in_file,"$l;$t"); } } close FF; } # sub printuuencode(){ my $uu = <<'EOUU'; ==== copy/paste this to the remote site, save it, chmod 755 uuencode.pl ==== #!/usr/bin/perl -w # vim: set sw=4 ts=4 si et: written by Guido Socher unless($ARGV[1]){ print "USAGE: uuencode.pl fileToEncode filenameToUseForDecoding Example: uuencode.pl /tmp/file.gz file.gz "; exit 0; } open (FH, $ARGV[0]) || die "ERROR: can not read $ARGV[0]\n"; binmode(FH); my $t;my $bindat=""; while(read(FH,$t,1000)){ $bindat.=$t;} close FH; print "begin 644 $ARGV[1]\n"; print (pack 'u', $bindat); print "`\nend\n"; # end of uuencode.pl EOUU print "$uu"; exit(0); } sub help(){ print "uudecode-from-log.pl -- extract uuencoded section from a log file This is usefule to transfer files in-line when logged in via a terminal session to a remote site. USAGE: uudecode-from-log.pl [-hu] logfile-with-all-kinds-of-stuff-and-some-uuencodes.txt OPTIONS: -h this help -u print a perl version of uuencode that you can copy/paste to the remote site in case there is no uuencode installed. The best way to generate the log from a linux terminal session is to use script -fa log.txt before starting to login to a remote site. EXAMPLE: uudecode-from-log.pl log.txt You need to have the command uudecode (part of sharutils package in many linux distros) to use uudecode-from-log.pl \n"; exit(0); } __END__