#!/usr/bin/perl
# @(#) RpGet.pl  Remote-printer job-retrieval program; retrieves and prints
#                print-data files uploaded by the RpSend.pl program.
#
# Copyright (c) 2020 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-05-10

use strict;
use warnings;
use File::Basename;
use Compress::Raw::Lzma;
use Net::Netrc;
use Mail::POP3Client;
use Sys::Syslog;
use LWP::UserAgent qw();
use Net::CUPS::Destination;
use File::Temp qw/tempfile/;
use MIME::Lite;
use Sys::Hostname::Long;
use vars qw($VERSION);
$VERSION = "1.04";

# Uncompress subroutine; accepts string as parameter and uncompresses it
sub uncompress {
  my ($z,$o);
  $z=new Compress::Raw::Lzma::AutoDecoder;
  if ( $z->code($_[0],$o)==LZMA_STREAM_END ) { $_[0]=$o; return(1) }
  else                                       {           return(0) }        
}

# Check usage
if ( $#ARGV != 1) { 
  die "Usage: ".basename($0)." Pop3Server Printer\n".
      " e.g.: ".basename($0)." pop.aol.com HP1010\n"
}

# Read login details for Pop3Server
my $server=Net::Netrc->lookup($ARGV[0]) or die ".netrc entry not found\n";
my ($login, $pass) = $server->lpa       or die "Login or password not found\n";

# Generate a list of URLs for data files to be downloaded
my $pop=new Mail::POP3Client(USER=>$login, PASSWORD=>$pass, HOST=>$ARGV[0],
                        PORT=>995, USESSL=>1) or die "Couldn't Authenticate\n";
if ($pop->Count()<1) {exit 0}
my (@urllist,@userlist);
for (my $i = 1; $i <= $pop->Count(); $i++) {
  foreach ( my $body=$pop->Body( $i ) ) {
    if ( $body=~m/^Seq:/ ) {
      my $url=substr($body,index($body,"http"));
      my ($j1,$user,$j2)=split(/=/,$body);
      if ( defined($url) ) {
        $url =~ s/\r|\n//g;
        push(@urllist,$url);
        if ( defined($user) ) {push(@userlist,$user)} else {push(@userlist,"")}
        $pop->Delete($i)
      }
    }
  }
}
$pop->Close();

# Fork to process the URLs on the list
fork and exit;
while ( defined (my $url=pop(@urllist) ) ) {
  my $user=pop(@userlist);
  my $ua = LWP::UserAgent->new;
  my $req = HTTP::Request->new(GET => "$url");
  my $data=$ua->request($req)->content;
  syslog("info","Downloaded data from $url ".length($data)." bytes");
  if ( uncompress($data) ) {
    syslog("info","Uncompressed data from $url ".length($data)." bytes")
  }
  my ($fh,$tmp)=tempfile(UNLINK=>1); print $fh $data; close ($fh);
  my $cups=Net::CUPS->new();
  my $printer = $cups->getDestination($ARGV[1]);
  my $jobid=$printer->printFile("$tmp",basename($url));
  if ( defined($jobid) ) {
    syslog("info","Printed data from $url with jobid: $jobid")
  }
  if ( $user=~/\@/) {
    my $msg = MIME::Lite->new(From => getpwuid($<).'@'.hostname_long,
                To      => $user,
                Subject => "Remote Printing Confirmation: $url",
                Data    => length($data)." bytes were printed on: ".$ARGV[1]);
    $msg->send;
    syslog("info","Sent confirmation email for $url to: $user")
  }
}

__END__

=head1 NAME

RpGet - Remote printing retrieval utility

=head1 README

Remote-printer job-retrieval program; retrieves and prints
print-data files uploaded by the RpSend.pl program.

=head1 DESCRIPTION

C<RpGet> retrieves print-data files that have been sent by C<RpSend> 
to an ephemeral file-sharing website. It does this by checking
for location details in email messages sent by that utility.

=head1 USAGE

The program can be invoked as follows:

=over 5

RpGet PopServer Printer

=back

e.g. RpGet pop.aol.com HP1010

If a print-data file has been compressed for transmission, it will be
uncompressed automatically after it is downloaded.

C<RpGet> always forks the file-download, uncompression and print operations
so that it may be called repeatedly without significant delays.

C<RpGet> should be called at appropriate (e.g. 10-minute) intervals through
a 'cron' or equivalent utility.

=head1 SCRIPT CATEGORIES

Networking
UNIX/System_administration

=head1 AUTHOR

Graham Jenkins <grahjenk@cpan.org>

=head1 COPYRIGHT

Copyright (c) 2020 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