#!/usr/bin/perl -w
# @(#) filemail.pl	Email utility for large binary files.
#
# Copyright (c) 2005 Graham Jenkins <grahjenk@cpan.org>. All rights reserved.
# This program is free software; you can redistribute it and/or modify it under
# the same terms as Perl itself. Revised: 2020-03-25

use strict;
use warnings;
use File::Basename;
use Sys::Hostname::Long;
use MIME::Lite;
use vars qw($VERSION);
$VERSION = "3.05";

my $PSize = 700;	# Default (input) part-size.
my ($Count,$Size,$Total,$InpBuf,$OutBuf,$InpLen,$FilNam);
if ($#ARGV ge 0) { if ($ARGV[0] =~ m/^-\d+$/ ) { $PSize=0-$ARGV[0]; shift } } 

die "Usage: cat file  |".basename($0)." [-KbPerPart] filename addr1 [addr2..]".
    "\n e.g.: tar cf - .|".basename($0)." -700 mydir.tar tom\@popser.acme.com".
    "\n(Note: default unencoded part size = $PSize","kb)\n"   if ($#ARGV lt 1);

die "Can't read input!\n" if ! open(INFILE,"-");
my $Fname=$ARGV[0]; shift;
my $List= $ARGV[0]; for (my $k=1;$k<=$#ARGV;$k++) {$List.=", $ARGV[$k]"}

binmode INFILE;
$Count=0; $Total="";   # Loop until no further input available.

do { $InpLen = read(INFILE, $InpBuf, 1024 * $PSize);
     $Total  = $Count if $InpLen lt 1;
     do { $Size = length($OutBuf);
          print STDERR "$Fname part $Count/$Total, $Size bytes => $List\n";
          $FilNam = substr(1000+$Count,1)."_".basename($Fname);
          my $msg = MIME::Lite->new(From    => getpwuid($<).'@'.hostname_long,
                       To       => $List,
                       Subject  => "$Fname:  part $Count/$Total  $Size bytes",
                       Type     => 'multipart/mixed'                          );
          $msg->attach(Type     => 'TEXT',
                       Data     => "This is part $Count of file $Fname encoded".
                                   " by ".basename($0)."; it has an unencoded" .
                                   " size of $Size bytes.\nTo recreate $Fname,".
                                   " just concatenate the parts in order."    );
          $msg->attach(Type     => 'application/octet-stream',
                       Filename => "$FilNam",
                       Data     => "$OutBuf"                                  );
          $msg->send 
     } if $Count gt 0;
     $Count++;
     $OutBuf = $InpBuf
   } until $InpLen lt 1;

__END__

=head1 NAME

filemail - an email utility for large binary files

=head1 README

filemail breaks an input stream into parts, then encodes
each part and emails it to designated recipients.

=head1 DESCRIPTION

This is a simple utility for emailing large
binary files. An input stream is broken into parts,
and each part is encoded for transmission to
one or more email addresses.

Base64 encoding is used for efficiency, and
an option is available to change the default part
size.

=head1 USAGE

=over 4

filemail [-part_size] file_name addr1 [addr2..]

=back

By default, the input stream is broken into parts of size
700kb. This can be adjusted by specifying a part-size
on the command line (e.g. -500 for a 500kb part-size).

Each part is then named by prepending "001_", "002_", etc. to
the basename of the designated file-name, and encoded for
transmission.

The recipients can recover the original data stream by
decoding each part, then concatenating the parts.

=head1 SCRIPT CATEGORIES

UNIX/System_administration
Networking

=head1 AUTHOR

Graham Jenkins <grahjenk@cpan.org>

=head1 COPYRIGHT

Copyright (c) 2005 Graham Jenkins. All rights reserved.
This program is free software; you can redistribute it
and/or modify it under the same terms as Perl itself.

=cut
