Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

fileparse(): need a valid pathname

by roopra (Initiate)
on Jul 06, 2018 at 18:18 UTC ( #1218062=perlquestion: print w/replies, xml ) Need Help??
roopra has asked for the wisdom of the Perl Monks concerning the following question:

Hi, Am trying to fix a bug in the Perl CGI code.

Below is the message

Status: 500 Content-type: text/html <h1>Software error:</h1> <pre>fileparse(): need a valid pathname at login.cgi line 34. </pre> <p> For help, please send mail to this site's webmaster, giving this error + message and the time and date of the error. </p> [Fri Jul 6 21:02:17 2018] login.cgi: fileparse(): need a valid pathna +me at login.cgi line 34.

please help

#!/usr/bin/perl -w #use strict; use DBI; use Carp; use File::Path; use File::stat; use File::Basename; use Cwd; use CGI; use CGI::Carp qw(carpout fatalsToBrowser); use Digest::MD5 qw(md5_hex); #use lib "$ENV{'DOCUMENT_ROOT'}/home/honeyisl/public_html/cgi-bin/sche +dule"; use lib "/home/honeyisl/public_html/cgi-bin/schedule"; use SUBS; use DBDAT; no warnings 'uninitialized'; #use lib "$ENV{'DOCUMENT_ROOT'}/home/honeyisl/public_html/cgi-bin"; use lib "/home/honeyisl/public_html/cgi-bin"; use Date::Manip; use Apache::DBI (); use Mail::Mailer; use Exporter; # P A R A M S A N D V A R I A B L E S my $q = CGI->new; my $action=$q->param("submit") || 'Annonymous'; my $user=$q->param('user'); my $msg=$q->param('msg'); #-------------------------------------------------------------------- my $md5 = Digest::MD5->new; my $digest; my $dir=dirname($ENV{'SCRIPT_FILENAME'}); #my $dir=cwd(dirname($ENV{"SCRIPT_FILENAME"}));
The error is coming from line " my $dir=dirname($ENV{'SCRIPT_FILENAME'});" Please help Thanks in advance

Replies are listed 'Best First'.
Re: fileparse(): need a valid pathname
by haj (Monk) on Jul 06, 2018 at 18:46 UTC

    I'd guess that your web server software doesn't provide the environment variable SCRIPT_FILENAME. That variable is not documented in the CGI 1.1 RFC, so maybe you need to check the documentation of your web server whether they changed their behaviour.

    Technically, $ENV{SCRIPT_FILENAME} is supposed to be the name of your program in "file space", as opposed to $ENV{SCRIPT_NAME} which is part of the RFC and is the name of the same program in "URL space". Depending on your web server configuration, you might succeed by simply writing my $dir=dirname($0); because $0 is the file name of your program.

Re: fileparse(): need a valid pathname
by hippo (Canon) on Jul 06, 2018 at 20:04 UTC
    use Apache::DBI ();

    Can you explain why you are using this module? Are you using some sort of persistent CGI? That certainly isn't what your prose suggests. Not that this directly impacts your error condition but it does make one wonder what else you might not be telling us.

Re: fileparse(): need a valid pathname
by eyepopslikeamosquito (Chancellor) on Jul 08, 2018 at 11:18 UTC

    #use strict;
    Can you explain why you commented out this line? Not that this directly impacts your error condition, but it may give us more context.

Re: fileparse(): need a valid pathname
by Anonymous Monk on Jul 06, 2018 at 19:32 UTC
Re: fileparse(): need a valid pathname
by ikegami (Pope) on Jul 09, 2018 at 03:10 UTC
    use lib "/home/honeyisl/public_html/cgi-bin/schedule"; ... my $dir = dirname($ENV{'SCRIPT_FILENAME'});
    should be
    use FindBin qw( $RealBin ); use lib $RealBin; ... my $dir = $RealBin;
Re: fileparse(): need a valid pathname
by sundialsvc4 (Abbot) on Jul 07, 2018 at 23:56 UTC

    Although it concerns PHP, the site https://www.sitepoint.com/php-server-api-differences/ has some good description of how web server configurations might vary some include certain environment variables (specifically this one) while others do not.   Some define SCRIPT_FILENAME as the name of the CGI script.   Therefore, as our friend Anonymous Monk has already suggested, let Perl itself tell you the name of the script that it is now executing.   This should be bulletproof.

    I have also seen “trampoline” code that was intended to facilitate running (very) old code in new environments, which set certain environment-variable values that the hoary old legacy code was expecting before passing-off control to the old software.

      To clarify a “trampoline” is the initial CGI script that is actually invoked by the web server.   (It might not be in Perl, but simply be a shell-script.)   Its purpose is to set up the environment expected by the “actual” script, then pass control to it via exec, which replaces the trampoline with the application as though the web-server had actually started it.   (The application-start module should be an executable Unix/Linux file which begins with “shebang” say:   #!/usr/bin/perl)

      Many variations exist, including trampolines that take the name of the script as their (only) command-line parameter.   Naturally, the trampoline will need to set the value of filename-referencing environment variables to point to the target not the trampoline.

      This is a very effective trick if you are dealing with an old application or, many applications which have a large number of environmental dependencies.   Sometimes, it is less-invasive to create the environment that they expect, by means of a short trampoline, than to re-tool the application(s) to no longer expect them.   The overhead contributed by the trampoline step is negligible.

        Here is an excerpt of an actual trampoline shell-script which runs thousands of times per second today, yes, driving a very old PHP site:   (classic CGI)

        #!/bin/sh # This file must be executable by any user and should NOT have # the 'setuid' bit turned on. # Apache must be able to execute it but not modfy it. if [ -z $REQUEST_METHOD ]; then echo "Your vain attempt to run this command outside of Apache fail +s to impress anyone ..." exit fi # Careful, no spaces here ... export PRODUCTION_CLOUD_TEST_DEV_LOCAL=PROD if [ -f "/test-box" ]; then export PRODUCTION_CLOUD_TEST_DEV_LOCAL=TEST elif [ -f "/dev-box" ]; then export PRODUCTION_CLOUD_TEST_DEV_LOCAL=DEV fi # The dot-com suffix becomes "local" on a development box. export DOT_COM_SUFFIX=com if [ -f "/test-box" ]; then export DOT_COM_SUFFIX=test elif [ -f "/dev-box" ]; then export DOT_COM_SUFFIX=dev fi # You might need to modify this export SCRIPT_FILENAME=$PATH_TRANSLATED # The 'exec' command will replace ourselves with the PHP executable. exec /usr/bin/php-cgi --php-ini /iapp/sys/config/php.ini \ $PATH_TRANSLATED

        Notice that the trampoline invokes whatever PHP-script the URL originally requested.   It “inserts itself” in front of every request.   Within such a trampoline you can easily (re-)define environment variables to create the environment that the legacy application expects.   When the exec command executes, it replaces the trampoline with the legacy application as though the trampoline had never been involved.

        Depending on your exact server configuration, some amount of Apache tomfoolery may be required in order to coax it into running the CGI script correctly for all requests. In our case:

        AddType text/html .php AddHandler webapp-php .php # This is the script-alias that must be used with the Actions. Equate + it to the physical directory which must be # described by the "<Directory>" directive just below. ScriptAlias /frobozz-cgi/ /sys/cgi-php/ # Direct each handler to the corresponding trampoline. # We must use the "Alias" here. # "Virtual" is important, too ... just don't ask me why. ;-) Action webapp-php /frobozz-cgi/webapp-php.cgi virtual # Specify access to the physical directory that is referred-to by the +ScriptAlias. <Directory "/sys/cgi-php/"> AllowOverride none Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch Require all granted </Directory>

        All of this translates quite-directly to the Perl environment and can be used even when FastCGI technology is being used.   (I do not think that it would apply readily to mod_XXX but I may be wrong.)

        The application in question consists of more than five thousand source-files and is about eleven years old.   It is stuffed with environmental dependencies dating back over multiple releases of Apache and of PHP.   Trying to “clean up” all those references would have been profoundly risky.   Instead, we avoided it with a trampoline.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1218062]
Approved by Corion
Front-paged by Corion
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (1)
As of 2018-07-22 05:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    It has been suggested to rename Perl 6 in order to boost its marketing potential. Which name would you prefer?















    Results (451 votes). Check out past polls.

    Notices?