home *** CD-ROM | disk | FTP | other *** search
- # dr_mail.pl -- handle request via email
- # SCCS Status : @(#)@ dr_mail.pl 3.1
- # Author : Johan Vromans
- # Created On : Thu Jun 4 22:22:20 1992
- # Last Modified By: Johan Vromans
- # Last Modified On: Thu Jun 4 23:06:48 1992
- # Update Count : 8
- # Status : OK
-
- sub mail_request {
-
- local ($rcpt, $address, $request, $file, $encoding, $limit, $parts) = @_;
-
- if ( $opt_debug ) {
- print STDERR ("&mail_request(rcpt=$rcpt, address=$address, ",
- "request=$request,\n",
- " file=$file,\n",
- " encoding=$encoding, limit=$limit, parts=$parts)\n");
- }
-
- # This routine handles the requests.
- # Handling includes encoding, splitting and transmitting.
-
- &check_file ($file, 0);
-
- local ($fname); # Basename of file to send
- local ($cmd); # Command to handle encoding
- local ($code); # Verbose description of encoding
- local ($files); # Number of files to send
- local (@files); # List of files to send
- local ($the_file); # Current part be send
- local ($the_part); # Sequence number thereof
- local ($size); # Size of chunk
- local ($tmpfile_prefix) = $opt_keep || "$tmpdir/drq$$.";
- local ($Dtmpdir); # Private dir for Dumas uue
- local ($opt_nolog) = $opt_nolog;
- local ($opt_keep) = $opt_keep;
-
- if ( $address eq "" || $address eq "-" ) {
- # Use this e.g. to include an encoded archive in email.
- $limit = "0";
- $opt_nolog = 1; # Local.
- $address = "";
- }
- $limit = 32*1024 if $limit eq "";
- if ( $limit ne "0" ) {
- # Limit must be between 10 and 256K, with 32K default.
- $limit = $`*1024 if $limit =~ /K$/;
- $limit = 10*1024 if $limit < 10*1024;
- $limit = 256*1024 if $limit > 256*1024;
- }
- print STDERR ("Using limit = $limit\n") if $opt_debug;
-
- $encoding = $default_encoding unless defined $encoding;
-
- # Get dir and basename of the requested file.
- local ($dir, $fname) = &fnsplit ($file);
-
- # Prepare the command to use.
- # The result of command should be the encoded file, written
- # to standard output.
-
- if ( $encoding =~ /^u/i ) {
-
- # Standard UU encoding.
- $encoding = "U";
- $code = "uuencoded";
- $cmd = "$uuencode $file '$fname'";
- }
- elsif ( $encoding =~ /^x/i ) {
-
- # Modified UU encoding.
- $encoding = "X";
- $code = "xxencoded";
- $cmd = "$xxencode $file '$fname'";
- }
- elsif ( $encoding =~ /^d/i ) {
-
- # Dumas' modified UU encoding.
- # Uue has a built-in facility to generate multi-part
- # files. The customer wants to use this feature...
- local ($split) = '';
- $encoding = "D";
- $code = "uue-encoded";
- $split = '-' . (int ($limit / 63) - 2) if $limit;
-
- # Prepare a private directory for uue to work in.
- $Dtmpdir = "$tmpdir/D$$";
- &system ("rm -fr $Dtmpdir");
- &system ("mkdir $Dtmpdir");
- &symlink ($file, "$Dtmpdir/$fname");
- $cmd = "cd $Dtmpdir; $uue $split '$fname'";
- }
- elsif ( $encoding =~ /^[pa]/i || $encoding eq "" ) {
-
- # No decoding.
- $encoding = "A";
- $code = "ascii";
- $cmd = "";
- }
- else {
-
- # Binary-to-Ascii encoding.
- $encoding = "B";
- $code = "btoa encoded";
- $cmd = "$btoa < $file";
- }
- print STDERR ("Using encoding = $encoding ($code)\n") if $opt_debug;
-
- if ( $encoding eq "A" && ($limit == 0 || (-s $file <= $limit)) ) {
- # A simple ascii file smaller than $limit -> use it.
- @files = ($file);
- $opt_keep = 1; # Local copy!
- }
- elsif ( $encoding eq "D" ) {
- local ($path) = ($Dtmpdir);
-
- # Encode and split.
- &system ($cmd);
-
- # Now gather all the parts, and tally them.
- opendir (DIR, $path)
- || &die ("Cannot read $path/ [$!]");
- @files = sort (grep (/\.u[a-z][a-z]$/o, readdir (DIR)));
- close (DIR);
- foreach ( @files ) {
- # Note: $_ is a *ref* into @files!
- $_ = "$path/$_";
- }
- }
- else {
- # It is tempting to use 'split' to cut the request into
- # pieces. Until recently, I did.
- # Splitting ourselves makes it possible to split ascii files
- # also. In this case we can spare another process.
- local ($suffix) = "aa";
- local ($size) = $limit + 1;
-
- if ( $cmd ) {
- print STDERR ("+ $cmd|\n") if $opt_trace;
- open (FEED, "$cmd|")
- || die ("Error opening pipe \"$cmd|\" [$!]\n");
- }
- else {
- print STDERR ("+ <$file\n") if $opt_trace;
- open (FEED, "$file")
- || die ("Error opening file \"$file\" [$!]\n");
- }
-
- @files = ();
- while ( <FEED> ) {
- if ( $limit > 0 && ($size += length ($_)) > $limit ) {
- close (OUT);
- open (OUT, ">$tmpfile_prefix$suffix")
- || die ("Cannot create $tmpfile_prefix$suffix: [$!]\n");
- push (@files, "$tmpfile_prefix$suffix");
- $size = length ($_);
- $suffix++;
- }
- print OUT;
- }
- close (OUT);
- close (FEED);
- }
-
- $files = @files;
-
- if ( $opt_debug ) {
- if ( $files > 1 ) {
- print STDERR ("Sending ", $files, " files: ",
- $files[0], " .. ", $files[$#files], "\n");
- }
- elsif ( $files == 1 ) {
- print STDERR ("Sending file: ", $files[0], "\n");
- }
- else {
- printf STDERR ("No files to send.\n");
- }
- }
-
- $the_part = 0;
- foreach $the_file ( @files ) {
-
- $the_part++;
-
- if ( $parts && $parts !~ /\b$the_part\b/ ) {
- unlink ($the_file) unless $opt_keep;
- print STDERR ("Skipping part $the_part (not requested).\n")
- if $opt_debug;
- next;
- }
- else {
- print STDERR ("Sending part $the_part of $files.\n")
- if $opt_debug;
- }
-
- # Form "part xx of yy" message.
- $part = ( $files == 1 ) ? "complete" : "part $the_part of $files";
-
- # Send it.
- if ( open (PART, $the_file) ) {
- if ( $address eq "" ) {
- $size = © (*STDOUT);
- }
- else {
- # Suppress sleep after the last part.
- local ($mailer_delay) = $mailer_delay;
- undef $mailer_delay if $the_part == $files;
- $size = &xfer;
- }
- close (PART);
- }
-
- # Write a log message.
- &writelog ("M \"$address\" $request $encoding$the_part/$files $size")
- if $address ne "";
-
- unlink ($the_file) unless $opt_keep;
- }
-
- &system ("rm -fr $Dtmpdir") if $encoding eq "D" && !$opt_keep;
- }
-
- sub headers {
- local (*FILE, $full) = @_;
-
- # Provide some RFC822 compliant headers.
-
- local ($size) = 0;
-
- if ( defined $sender ) {
- print FILE "$sender\n";
- $size += length ($sender) + 1;
- }
-
- $ln = "To: $address\n";
- $ln .= "Subject: $fname ($part) $code\n";
- $ln .= "Precedence: bulk\n";
- $ln .= join ("\n", @x_headers) . "\n" if defined @x_headers;
- print FILE ($ln, "\n");
- $size += length ($ln) + 1;
- }
-
- sub copy {
- local (*FILE) = shift (@_);
- local ($size);
- local ($ln);
-
- $ln = "Request: $request\n\n".
- "------ begin of $fname -- $code -- $part ------\n";
- $size = length ($ln);
- print FILE $ln;
- while ( <PART> ) {
- print FILE $_;
- $size += length ($_);
- }
- $ln = "------ end of $fname -- $code -- $part ------\n";
- print FILE $ln;
- $size + length ($ln);
- }
-
- sub xfer {
-
- # Send the file via e-mail.
- local ($size);
-
- if ( $opt_nomail ) {
- print STDERR "[Would call \"$chunkmail\"]\n";
- &headers (*STDOUT, 0);
- }
- elsif ( open (MAILER, "|$chunkmail '$address'") ) {
- $size = &headers (*MAILER, 0);
- $size += © (*MAILER);
- close MAILER;
-
- # Allow system to stabilize.
- sleep ($mailer_delay) if defined $mailer_delay;
- }
- $size;
- }
-
- 1;
-