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

Taking the advice of the fellow monks on one of my previous posts, Im trying to use IPC::Open2or IPC::Open3 to control a forked process. Ok. Im having a tuff time with figuring this out. I have searched for code but havent found many good examples of how to use it. I originally was trying this on a Win32 machine and thought my problems were rooted in windows issues. So now Im trying on my linux box. Still no luck.

For my test, Im trying to spawn pgp and have it encrypt data that I send to it and read back the encrypted output.

First I make sure I have pgp working correctly. I do the following from the shell:

$ export PGPPASS="MY PASSPHRASE" $ echo $PGPPASS MY PASSPHRASE $ pgp -feast zzSPECTREz <test.dat Pretty Good Privacy(tm) 2.6.3a - Public-key encryption for the masses. (c) 1990-96 Philip Zimmermann, Phil's Pretty Good Software. 1996-03-04 Uses the RSAREF(tm) Toolkit, which is copyright RSA Data Security, Inc +. Distributed by the Massachusetts Institute of Technology. Export of this software may be restricted by the U.S. government. Current time: 2000/11/28 08:02 GMT You specified no user ID to select your secret key, so the default user ID and key will be the most recently added key on your secret keyring. Pass phrase is good. Just a moment.... Key for user ID: zzSPECTREz <zzspectrez@yahoo.com> 1024-bit key, key ID 30331F8D, created 2000/11/28 .-----BEGIN PGP MESSAGE----- Version: 2.6.3a hIwDFugMGjAzH40BA/0QTFT3pazbHqhMp7tGiXDG0GBhvc1LOO3Nq0JUxyHKzNRo Zy8KMS186W+bVtEx0Bcp7EWVlQdt9JtFTYl0D9+zitKCmFpg0RT0mWNH9hEtixr3 WufvK4p0B/0wQKQypgS8rl/+cNR4+uGUbsD8YremUDBV8+YoE5B5yn5jh/mYvaYA AADnyBa016F+SSgwl5tUSgDZVBeMnl5mWmGvLivqG5NYrvyb4AATFgPQPeOzksGM bJKf5E3q9uxvtl7mZOuNCf6VC8lZPAt1NGHrGBMwCkptR835ZV1kSoSEMZhU1+nC 6i4g1VZA3bYyE5fOK4gA3IfhRAyvhYY5guCe9ff1+FtGSIVXmR3D8y4GaOrALhAZ FiK3B/FXx81coA3S7xOJnyVbBvTSh0ncppZwE5TvmK5anD4Hl8eJSZsJjwK5Jd5z 9Hs1nbqhAUs96PDnqjRMIP+sPU8dCRgylq9SwombStl18IEtvo/R4XHV =yeUi -----END PGP MESSAGE-----

Now for my test code.

#!/usr/bin/perl -w use strict; use IPC::Open2 use FileHandle; $ENV{PGPPASS} = "MY PASSPHRASE"; print "\nEnter user id: "; my $user_id = <STDIN>; chomp $user_id; print "\nInput file: "; my $inp_file = <STDIN>; chomp $inp_file; open (INFILE, $inp_file) or die ("Could not open $inp_file: $!\n"); my @in_data = <INFILE>; close (INFILE); my $pid = open2(\*READER, \*WRITER, 'pgp -feast $user_id') or warn "$!\n"; READER->autoflush(); WRITER->autoflush(); print WRITER @in_data; while (<READER>) { print; }

This code runs and then hangs with the following output:

$ ./pgpify.pl Enter user id: zzSPECTREz Input file: test.dat Pretty Good Privacy(tm) 2.6.3a - Public-key encryption for the masses. (c) 1990-96 Philip Zimmermann, Phil's Pretty Good Software. 1996-03-04 Uses the RSAREF(tm) Toolkit, which is copyright RSA Data Security, Inc +. Distributed by the Massachusetts Institute of Technology. Export of this software may be restricted by the U.S. government. Current time: 2000/11/28 07:51 GMT

I thought it might be that I had to read the output of the program before writing the data to it so I tried adding the followin:  my @junk = <READER>. Didnt help. Any suggestions?

Thanks!
zzSPECTREz

Replies are listed 'Best First'.
Re: IPC::Open2 Help.
by geektron (Curate) on Nov 28, 2000 at 13:35 UTC
    a couple thoughts:
    1. altering the %ENV hash won't work unless you spawn a child process.
    2. you may not be printing everything to the WRITER filehandle. i had a similar problem with Open3 and commands. use join to get a string, and print THAT to the WRITER handle. your pgp program is probably waiting for input.
    3. and i may be wrong on this point: you need to create the filehandles with  my $READER = FileHandle->new() to properly use the methods in FileHandle. so, you may not be autoflushing your handles and running into buffer issues.
Re: IPC::Open2 Help.
by repson (Chaplain) on Nov 28, 2000 at 17:09 UTC
    Wait a minute...look at this line of code:
    my $pid = open2(\*READER, \*WRITER, 'pgp -feast $user_id')
    You are running 'pgp -feast $user_id' when you mean 'pgp -feast zzSPECTREz'.
    Instead try using "pgp -feast $user_id" to interpolate $user_id so pgp doesn't try literally using user '$user_id'.

      That was a typo. In my source I do have it written as my $pid = open2(\*READER, \*WRITER, "pgp -feast $user_id"). Plus I have even tryed it as my $pid = open2(\*READER, \*WRITER, 'pgp -feast zzSPECTREz')

      Thanks for catching my err.
      zzSPECTREz

Re: IPC::Open2 Help.
by jepri (Parson) on Nov 28, 2000 at 15:00 UTC
    Like the manual says, IPC is hard to use when you didn't write the program you are opening. You could grab the source to PGP, switch on debugging and see where it is stopping, if it has finished, etc.

    My (old) version of PGP encrypted files fine. Just write your message to a text file (in the tmp or c:\temp directory) and then read the final file. It used to be pgp -e filename.txt etc.etc.

    If at this point you start pointing out that you are worried about someone reading your harddrive sector by sector then you should probably go to the effort of installing one of the PGP modules from CPAN.

    ____________________
    Jeremy
    I didn't believe in evil until I dated it.

      I have been able to get it to work if Im either just reading or just writing to pgp by opening it with a pipe. The problem is I want to do this without a temporary file.

      The -f option as explained in the pgp documentation is used for UNIX-style filter mode to read from standard input and write to standard output. So I would think that you should be able to get this to work, and Im just doing something wrong.

      Looking to see how the modules work, I noticed that they are just do what Im trying to do. For example, looking at the module PGP::Pipe.pm I see that it is using the basic same method: $result = open3 ($fin, $fout, $ferr, "$self->{PGPexec} $baseopts $args") || croack "PGP command error"; So the error is in my code somewhere. I think Ill try to figure out how this module is doing stuff.

      Thanks.
      zzSPECTREz

Re: IPC::Open2 Help.
by zzspectrez (Hermit) on Nov 30, 2000 at 00:43 UTC

    For anyone who is interested, I found a solution and will post it for anyone else having problems working with open3. I got the following code to work on linux, but am still trying to figure out how to get it to work on my win2k box.

    #!/usr/bin/perl -w # pgp_test.pl <user_id> <passphrase> use strict; use IPC::Open3; my $encrypt_opts = '+force +batchmode +verbose=1 -fea'; my $decrypt_opts = '+force +batchmode +verbose=1 -f'; my $key = shift || 'zzSPECTREz'; my $passphrase = shift || '###MYSECRET KEY##'; sub encrypt () { my ($user_key, $text) = @_; my $pid = open3(\*PGPIN,\*PGPOUT,\*PGPERR,"pgp $encrypt_opts $user_k +ey"); print PGPIN $text; close (PGPIN); my $output = join ('',<PGPOUT>); return $output; } sub decrypt () { my ($text) = @_; my $pid = open3(\*PGPIN,\*PGPOUT,\*PGPERR,"pgp $decrypt_opts -z '$pa +ssphrase'"); print PGPIN $text; close(PGPIN); my $output = join ('',<PGPOUT>); return $output; } print "\nTEST PGP\n\n"; print "ENTER TEXT TO ENCRYPT: "; my $data = <STDIN>; my $enc_data = &encrypt ($key,$data); print "\nDATA ENCRYPTED:\n$enc_data\n\n"; my $dec_data = &decrypt ($enc_data); print "DATA DECRYPTED:\n$dec_data\n\n";

    zzSPECTREz