The Perl script works with the -w option, but not without

advertisements

This script works on localhost with the -w switch but not without. It also works when use strict and use warning are active.

apache2/error.log:

without switch (aborted script):

(2)No such file or directory: exec of ... failed

with the switch I get:

Use of uninitialized value $email_flag in string ne ...

which looks initialised to me.

On the live web server neither one works. Perl is new to me, but I know some BASH and PHP.

I run Debian Lenny, Apache2, Perl 5.10.

#!/usr/bin/perl -w

$| = 1;

my $mailprog = '/usr/sbin/sendmail'; # where the mail program lives

my $to = "not\@for.you";   # where the mail is sent

my ($command,$email,@pairs,$buffer,$pair,$email_flag) ;

 read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});

        @pairs = split(/&/, $buffer);
       foreach $pair (@pairs) {

        # Split the pair up into individual variables.                       #
        my($name, $value) = split(/=/, $pair);

        # Decode the form encoding on the name and value variables.          #
        $name =~ tr/+/ /;
        $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

        $value =~ tr/+/ /;
        $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

        # If they try to include server side includes, erase them, so they
        # aren't a security risk if the html gets returned.  Another
        # security hole plugged up.
        $value =~ s/<!--(.|\n)*-->//g;

     ##  print "Name of form element is $name with value of $value \n";

        if ($name eq 'email') {
            $email = $value;
           }

        if ($name eq 'command') {
            $command = $value;
           }

       }

    if ($email =~ /(@.*@)|(\.\.)|(@\.)|(\[email protected])|(^\.)/ ||
        $email !~ /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,3}|[0-9]{1,3})(\]?)$/ ) {
        $email_flag = "ERROR";

    }

my $urlcommand = $command;

if ($command eq 'Subscribe') {
$command = "SUBSCRIBE rpc-news";
}

if ($command eq 'Unsubscribe') {
$command = "UNSUBSCRIBE rpc-news";
}

if ($command eq 'Suspend') {
$command = "SET rpc-news NOMAIL";
}

if ($command eq 'Resume') {
$command = "SET rpc-news MAIL";
}

my $getInfo = '';

print "Content-Type: text/html\n";

  if ($email_flag ne "ERROR") {

    open(MAIL,"|$mailprog -t");
     print MAIL "To: $to\n";
     print MAIL "From: $email\n";
     print MAIL "Subject: [rpc-news] $command \n";
     print MAIL "Reply-to: $email \n";

     print MAIL "$command \n";
     print MAIL "EXIT \n";
    close (MAIL);

    $getInfo = "?result=good";
   }
if ($email_flag eq "ERROR") {
    $getInfo = "?result=bad";
}   

my $rootURL= $ENV{'SERVER_NAME'};
my $url = "http://${rootURL}/thank_you.html${getInfo}&action=${urlcommand}";

print "Location: $url\n\n";


Did you create your script on a Windows machine and upload it to a Linux server without fixing the line endings? Without the -w switch, the shebang line may look like "#!/usr/bin/perl\r", so the system goes looking for a program named "perl\r" (or however the line ending looks). With the -w switch, "#!/usr/bin/perl" doesn't have an indecipherable line ending stuck to it. Instead, that gets stuck to -w where it doesn't cause failure.

I thought there was a perlfaq about this, but I can't seem to find it in the docs at the moment.

Update: I found it over on PerlMonks, in a really old Q&A topic that seems unrelated until you read the body of the message: Answer: How to get rid of premature end of script headers. Yeah, I know, if you were just browsing threads you wouldn't even stop on that one. But here's the text of the post:

If you developed this script on Windows, it's possible that the script file has non-UNIX line endings. (The perl interpreter can handle them, but the shebang line is interpreted by the shell, and is not tolerant of incorrect line endings.) If this is the problem, the script may terminate with an error right at the shebang line.