HP3000-L Archives

October 2001, Week 3

HP3000-L@RAVEN.UTC.EDU

Options: Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Subject:
From:
Ken Hirsch <[log in to unmask]>
Reply To:
Ken Hirsch <[log in to unmask]>
Date:
Tue, 16 Oct 2001 16:07:33 -0400
Content-Type:
text/plain
Parts/Attachments:
text/plain (323 lines)
Here's a Perl script that can send mail, with attachments, from an HP3000.
You can use it with the HP3000 as your mail server if you have Sendmail
running.  Or, you can use another computer as the SMTP server if the HP3000
is connected to it at the time the script is run.

I hope the internal comments are sufficient to explain it.  If you have
questions, comments, bug reports, please send them to me.

Ken
anyparm args= 2>/dev/null
if hpacctcap=hpcidepth
then
  # This is for running it from the shell; it is skipped by CI
  eval 'exec /PERL/PUB/perl -x -wS $0 ${1+"$@"}'
  echo ERROR: Cannot execute Perl
  exit 1
fi
ENDIF

setvar _margs anyparm(!args)
setvar _margs repl(repl(_margs, '"', '""'), "'", "''")
setvar _mailscript finfo(hpfile, "POSIXFULLFNAME")
/bin/sh "-c '/PERL/PUB/perl -x -w !_mailscript !_margs '"
deletevar _mailscript
return

#================================================================
# Ken Hirsch <[log in to unmask]>
# Oct 2001
#
mailto
  Perl program to E-mail a file from the HP3000

usage:
MAILTO [-f from] [-t to] [-s subject] [-a afile] [-b bfile] textfile
  Flags:
     -f from   Set the 'From' address of the e-mail
         You may also use SETVAR FROM "address"
     -t to
         You may also use SETVAR TO "address"
         You may use several -t options for multiple addressess
         or separate them by commas.

     -s  subject
         You may also use SETVAR SUBJECT "subject"
     -a  afile
         The name of an ASCII file to send as an attachment.
         The parameter 'afile' has the form
           sendname=HFSNAME
         or
           HFSNAME
         Where 'sendname' is the name of the file as it will
         appear to the mail recipient, and 'HFSNAME' is the name
         of a file on the HP3000, preferably in HFS syntax,
           i.e.  /ACCOUNT/GROUP/FILE
         However, the script will try to convert the name.
         If you don't include 'sendname', the last component
         of HFSNAME will be used.
         You may use several -a options to attach multiple files.

     -b  bfile
         The name of an BINARY file to send as an attachment.
         The parameter 'bfile' has the same form as 'afile', above
         You may use several -b options to attach multiple files.

     textfile - the body of the message, textfile can be specified
                in either HFS syntax or MPE syntax

                You can use the "<" operator to read the text from
                any file, including a temporary file, in MPE syntax.

               If there is no body to the message, you can
               MAILTO ... <$NULL
               (or  </dev/null from the shell)


  Check the jcw CJCW for exit status: 0 means success

  example:
    SETVAR SUBJECT "This is a message from me!"
    setvar FROM "Ken Hirsch <[log in to unmask]>"
    ECHO Here's that spreadsheet you wanted >M1
    MAILTO -t "Mark <[log in to unmask]>" -b btu.xls=BTUXLS.PUB <M1

Notes:
   This program may be called from either the CI or the shell
   without any changes.

   The modules it uses should all come with Perl/iX except for
   MPE::CIvar, which you can get from
     http://invent3k.external.hp.com/~KEN.HIRSCH/
   or, if I get my act together, from CPAN

   DNS address resolution must be working, so you may need to
   edit RESOLVCNF.NET.SYS

   The service name 'smtp' is looked up in SERVICES.NET.SYS, so
   you may need to add this line if it's not already there:
smtp          25/tcp                 #Simple Mail Transfer Protocol


   See also the comments below marked with "CONFIG"


=cut
#!perl -w
use Net::SMTP;
use MPE::CIvar ':all';
use Net::hostent;

# CONFIG: You can replace 'localhost' with the name
# of your SMTP server, if it's different.
# Or
my $server  = $CIVAR{'MAILSERVER'} || 'localhost';

# CONFIG: You should put your address here
my $from    = $CIVAR{'FROM'}       || 'Your address goes here';

my $subject = $CIVAR{'SUBJECT'}    || "No Subject";
my $now     = localtime();
my $boundary = "";
my $mime = 0;
my $to;

my $hostname = gethost($CIVAR{HPLOCIPADDR})->name || 'localhost';

my @tolist;
my @afiles;
my @bfiles;

my $usage=
"usage: $0 [-f from] [-t to] "
. "[-s subject] [-a afile] [-b bfile] textfile\n"
;

if (defined($to = $CIVAR{'TO'})) {
  push @tolist, $to;
}

while (defined($opt = shift)) {
  if ($opt =~ /^-([abfts])/) {
    my $flag = $1;
    my $arg = shift or die $usage;
    if ($flag eq 's') {
      $subject = $arg;
    } elsif ($flag eq 'f') {
      $from = $arg;
    } elsif ($flag eq 't') {
      push @tolist, $arg;
    } elsif ($flag eq 'a') {
      push @afiles, $arg;
    } elsif ($flag eq 'b') {
      push @bfiles, $arg;
    }
  } elsif ($opt =~ /^-/ && $opt !~ /^--?$/) {
    die $usage;
  } else {
    unshift(@ARGV, $opt) if $opt ne "--";
    last;
  }
}

if (0 == scalar(@tolist)) {
  die "$0: No recipients specified\n";
}

$to = join(', ', @tolist);


my $smtp = Net::SMTP->new($server) or
       die "Cannot connect to $server: $!\n";

my $smtp_from = smtpaddr($from);

$smtp->hello("$hostname\n")      or mystat($smtp, "Hello");
$smtp->mail("<$smtp_from>\n")    or mystat($smtp, "mail");
for (@tolist) {
  for (split /,/) {
    my $smtp_to = smtpaddr($_);
    # print STDERR "RCPT TO:<$smtp_to>\n";
    $smtp->recipient("<$smtp_to>\n")
                or mystat($smtp, "recipient");
  }
}
$smtp->data()               or mystat($smtp, "data");
$smtp->datasend("From: $from\n");
$smtp->datasend("To: $to\n");
$smtp->datasend("Date: $now\n");
$smtp->datasend("Subject: $subject\n");
if (scalar(@afiles) || scalar(@bfiles)) {
  $mime = 1;
  $boundary = sprintf("=_%04x%04x.%04x%04x:%04x%04x",
             rand(65535), rand(65535),
             rand(65535), rand(65535),
             rand(65535), rand(65535));
    $smtp->datasend("Mime-Version: 1.0\n");
    $smtp->datasend("Content-Type: multipart/mixed;" .
             "boundary=\"$boundary\"\n");
}
$smtp->datasend("\n");
$firstline = 1;

unshift(@ARGV, '-') unless @ARGV;
while ($ARGV = shift) {
    if ($ARGV ne "-") {
      $ARGV = convertname($ARGV);
    }
    open(ARGVF, $ARGV);
    while (<ARGVF>) {
      if ($mime && $firstline) {
        $firstline = 0;
        $smtp->datasend("\n--$boundary\n");
        $smtp->datasend("Content-Type: text/plain\n");
        $smtp->datasend("Content-Disposition: Inline\n\n");
      }
      $smtp->datasend($_);
    }
}

if ($mime) {
  my $file;
  my $fname;
  my $binary = 0;
  for (@afiles) {
    ($file, $fname) = getfilenames($_);
    open FILE, "<$file" or die "Cannot open $file: $!\n";
    $smtp->datasend("\n--$boundary\n");
    $smtp->datasend("Content-Type: text/plain\n");
    $smtp->datasend("Content-Transfer-Encoding: "
                         ."Quoted-printable\n");
    $smtp->datasend("Content-Disposition: attachment;\n");
    $smtp->datasend(" filename=$fname\n\n");
    use MIME::QuotedPrint qw(encode_qp);
    while (<FILE>) {
      $_ = encode_qp($_);
      $smtp->datasend($_);
    }
  }
  for (@bfiles) {
    ($file, $fname) = getfilenames($_);
    open FILE, "<$file" or die "Cannot open $file: $!\n";
    binmode FILE;
    $smtp->datasend("\n--$boundary\n");
    $smtp->datasend("Content-Type: application/octet-stream\n");
    $smtp->datasend("Content-Transfer-Encoding: base64\n");
    $smtp->datasend("Content-Disposition: attachment;\n");
    $smtp->datasend(" filename=$fname\n\n");
    use MIME::Base64 qw(encode_base64);
    hpcicommand("SETVAR MAILTORECLEN FINFO('$file', 30)");
    my $reclen = $CIVAR{MAILTORECLEN};
    my $buf = "";
    while (read(FILE, $rec, $reclen)) {
      $buf .= $rec;
      while (length($buf) >= 57) {
        $rec = substr($buf, 0, 57);
        $smtp->datasend(encode_base64($rec));
        $buf = substr($buf, 57);
      }
    }
    if (length($buf)) {
      $smtp->datasend(encode_base64($buf));
    }
  }
 $smtp->datasend("\n--$boundary--\n");
}


$smtp->dataend() or mystat("dataend", $smtp);

print "Mail was sent to $to\n";

$smtp->quit() or mystat("quit", $smtp);


sub mystat {
  my ($smtp, $c) = @_;
  print "Error on SMTP command $c: return code = ",
                             $smtp->code(), "\n";
  print "  message = ", $smtp->message(), "\n";
  die "ERROR: Mail was not sent\n";
}

sub smtpaddr {
  my $addr = shift;
  if ($addr =~ m/<(.*)>/) {
    $addr = $1;
  } elsif ($addr =~ m/[ "']/ &&
               $addr =~ m/([.-a-z0-9_]+\@[.-a-z0-9]+)/) {
    $addr = $1;
  }
  return $addr;
}

sub getfilenames {
  my $file = shift;
  my $fname;
  if ($file =~ /(.*)[:=](.*)/) {
    $file = $2;
    $fname = $1;
  } else {
    $fname = lc($file);
    $fname =~ s!.*/!!;
  }
  $file = convertname($file);
  return ($file, $fname);
}

sub convertname {
  my $file = shift;
  my $filenew;

  if (! -f $file) {
      hpcicommand("SETVAR MAILPXFNAME ':BADFILENAME'");
      hpcicommand("SETVAR MAILPXFNAME FINFO('$file', 38)");
      $filenew = $CIVAR{MAILPXFNAME};
      $file = $filenew if $filenew ne ':BADFILENAME';
  }
  return $file;
}

* To join/leave the list, search archives, change list settings, *
* etc., please visit http://raven.utc.edu/archives/hp3000-l.html *

ATOM RSS1 RSS2