Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I am using MIME::Parser to get the contents of an email passed to my script. It works fine like this:
my $input = \*STDIN; my $entity = $parser->parse($input);
But, I also want to keep a copy of the email exactly as it came in, before MIME::Parser does it's thing. However,
my $input = \*STDIN; my @copy = <$input>; open(COPY, ">copy.txt"); print COPY @copy; close COPY; my $entity = $parser->parse($input);
works fine for keeping the copy, but then there is nothing left for MIME::Parser to parse it seems. If I reverse the order, and parse it first, then there is nothing to print in my copy file.I gues STDIN is only good for one read? I tried makeing a copy of the reference, like
my $input = \*STDIN; my $copy = $input;
but that just makes another reference to the same data address I guess (which makes a lot of sense), because it is still only good for one read. I tried
my $input = \*STDIN; my @copy = <$input>; open (TMP, ">/tmp/copy.txt"); print TMP @copy; close(TMP); open($copy, "</tmp/copy.txt"); my $entity = $parser->parse($copy);
Which seems to make sense, but now MIME::Parse doesn't parse the $copy. If I print $copy; instead, I see that $copy does indeed contain a copy of the file, but I can't figure out why MIME::Parse will only parse it if it is the original. Anybody have any ideas?
Kbeen

Replies are listed 'Best First'.
Re: Copy of a filehandle reference
by antirice (Priest) on Jun 19, 2003 at 05:59 UTC

    Well, you could do this:

    my $original; { local $/; $original = <STDIN>; # slurp } die "Ah darn it! Nothing in original!" unless $original; my $entity = $parser->parse_data($original);

    Since the contents of $original are passed by value, $original should still contain everything that was originally in STDIN. Hope this helps.

    On a side note:

    antirice    
    The first rule of Perl club is - use Perl
    The
    ith rule of Perl club is - follow rule i - 1 for i > 1

      Thanks! That did the trick... so simple, yet for some reason I tried every thing but.

      I like the example below this, because it has a lot of things I have never used before, so I'll get a chance to try em out, but unfortunatly it didn'T work for me as is. I got
      write-open ./msg-2379-1.txt: Permission denied at /usr/lib/perl5/site_ +perl/5.6.0/MIME/Body.pm line 414, <TMP> line 22.
      and since this one is quicker and simpler, I'll put it inot production and try to figure the other one out later...
Re: Copy of a filehandle reference
by sgifford (Prior) on Jun 19, 2003 at 06:17 UTC
    This works for me:
    #!/usr/bin/perl use MIME::Parser; my $parser = MIME::Parser->new; # Open temp file for both read and write open (TMP, "+> /tmp/copy.txt") or die "Couldn't open copy for write: $!\n"; # Copy the whole thing while (read(STDIN,$buf,8192)) { print TMP $buf; } # Rewind the temp file seek(TMP,0,0) or die "Seek error: $!\n"; # Now create our MIME entity. my $entity = $parser->parse(\*TMP) or die "Couldn't parse: \n"; close(TMP) or die "Error closing temp file: $!\n"; # Done! $entity->dump_skeleton;
Re: Copy of a filehandle reference
by fglock (Vicar) on Jun 19, 2003 at 03:55 UTC

    The docs say:

    parse_data DATA Instance method. Parse a MIME message that's already in core.

    so this should work:

    my @copy = <$input>; my $entity = $parser->parse_data( @copy );
      That didn't work either. The @copy got a number value... (number of lines?) and the parser returned nothing.
      I guess I should look up what "already in core" means.