Solved

Problems with 'use of uninitialized value' using ReadParse in CGI

Posted on 1997-10-20
19
706 Views
Last Modified: 2013-12-25
Hi There,

Weel my problem seems to be a catch 22 sistuation. I have used numerous hours trying to figure out why ReadParse returns a value of '0' when it reads from a HTML form using the POST method. When I test the script from the browser it exits to the error message. When I test it from a commandline it returns the error message:

Use of uninitialized value at manpage.pl line 24.
Content-type: text/html
Status: 500 UNIX Manual Page Gateway Error

<html>
<head><title>CGI Program - Unexspected Error</title></head>
<body>
<h1>UNIX Manual Page Gateway Error</h1>
<hr>Invalid manual page specification.<hr>
Please contact <a href="mailto:you@your.address">Name (cj@hum.auc.dk)</a> for more information!
</body>
</html>

The script is written to work as a gateway for displaying UNIX man pages in HTML format. i have tried to get teh script to print $_ as well as <STDIN> before executing anything else, but it still returns a vaule of '0' and fails. How can I solve this problem? Should I use CGI.pm instead og the ReadParse in the standard cgi-lib.pl??? What gives...

Sincerely,  Chris.

Below is the script:
!# /path/to/perl -w
require "cgi-lib.pl";

$webmaster = "Your Name Here(name\@your.address)";
$script = $ENV{'SCRIPT_NAME'};
$man_path = "/path/to/man";
$nroff = "/path/to/nroff -man";
$last_line = "Last change:";


&ReadParse (*FORM);

my $manpage = $FORM{'manpage'}; #this is where it fails
my $section = $FORM{'section'};

($manpage = $FORM{'manpage'}) =~ s/^\s*(.*)\b\s*$/$1/;

if ( (!$manpage) || ($manpage !~ /^[\w\+\-]+$/) ) {
   &error (500, "UNIX Manual Page Gateway Error", "Invalid manual page specification.");
}
else
{
   if ($section !~ /^\d+$/) {
       $section = &find_section ();
       } else {
       $section = &check_section ();
}
   if ( ($section >= 1) && ($section <= 9) ) {
   &display ();
}
else
{
   &error (500, "UNIX Manual Page Gateway Error", "Could not find the requested document.");
}
}

exit (0);

sub find_section {
    local ($temp_section, $loop, $temp_dir, $temp_file);

    $temp_section = 0;

    for ($loop = 1; $loop <= 9; $loop++) {
        $temp_dir = join ("", $man_path, "/man", $loop);
        $temp_file = join ("", $temp_dir, "/", $manpage, ".", $loop);
   
        if (-e $temp_file) {
           $temp_section = $loop;
        }
    }
    return ($temp_section);
}

sub check_section {
    local ($temp_section, $temp_file);
    $temp_section = 0;
    $temp_file = join ("", $man_path, "/man", $section, "/", $manpage, ".", $section);

    if (-e $temp_file) {
       $temp_section = $section;
    }
    return ($temp_section);
}

sub display {
    local ($file, $blank, $heading);
    $file = join ("", $man_path, "/man", $section, "/", $manpage, ".", $section);

    print "Content-type: text/html\n\n";
    print "<HTML>\n";
    print "<HEAD><TITLE>UNIX Manual Page Gateway</TITLE></HEAD>\n";
    print "<BODY>\n";
    print "<p align=\"center\"><font size=\"6\"><strong>UNIX Manual Page Gateway</strong></font></p>\n";
    print "<p><pre>\n";

    open (MANUAL, "$nroff $file |");
    $blank = 0;
    while (<MANUAL>) {
       next if ( (/^$manpage\(\w+\)/i) || (/\b$last_line/o) );

    if (/^([A-Z0-9_ ]+)$/) {
        $heading = $1;
        print "<H2>", $heading, "</H2>", "\n";
    } elsif (/^\s*$/) {
        $blank++;
        if ($blank < 2) {
           print;
        }
    } else {
        $blank = 0;
        s//&amp;/g    if(/&/);
        s//&lt;/g     if(/</);
        s//&gt;/g     if(/>/);
 
        if (/((_\010\S)+)/) {
           s//<B>$1<\/B>/g;
           s/_\010//g;
        }

        if ($heading =~ /ALSO/) {
           if (/([\w\+\-]+)\((\w+)\)/) {
              s//<A HREF="$script\?manpage=$1\&section=$2">$1($2)<\/A>/g;
           }
        }

        print;
     }
  }

  print "</pre><hr>\n";
  print "</BODY></HTML>\n";
  close (MANUAL);
}

sub error {

   local ($status, $keyword, $message) = @_;

   print "Content-type: text/html", "\n";
   print "Status: $status $keyword\n\n";
   print "<html>\n";
   print "<head><title>CGI Program - Unexspected Error</title></head>\n";
   print "<body>\n";
   print "<h1>$keyword</h1>\n";
   print "<hr>$message<hr>\n";
   print "Please contact <a href=\"mailto:name\@your.address\">$webmaster<\/a> for more information!\n";
   print "</body>\n";
   print "</html>\n";
   close();

exit (1);
}
0
Comment
Question by:Bastholm
  • 9
  • 7
  • 3
19 Comments
 
LVL 7

Expert Comment

by:faster
ID: 1830962
It has no reason to fail there.  Probably you didn't config your cgi or cgi-lib correctly.
0
 

Author Comment

by:Bastholm
ID: 1830963
What do you mean when you say: Probably you didn't config your cgi or cgi-lib correctly??

My sys.adm. has used this cgi-lib.pl in other scripts and so have I - without any problems. I have used ReadParse prior to this script in a cgi-mail gateway - no problemo!

The script is running on a UNIX(r) System V Release 4.0 server, but I'm planning on moving all my scripts to an Apache 1.2.4 server running under SunOS 5.6 - and maybe using CGI.pm instead.

0
 
LVL 6

Expert Comment

by:alamo
ID: 1830964
Your script looks fine, in fact I tested the relevant portions of it here and it worked. You should do 2 things next to debug this:

- Post here the HTML source of the form which calls the script - this problem could be as simple as the fieldnames not matching (wrong case for example). If I made the fieldnames wrong on purpose in my test html I got the same errors you did.

- As a debugging measure change the method from POST to GET and see if the behavior changes. This might eliminate a few possibilities.
0
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 

Author Comment

by:Bastholm
ID: 1830965
Hi Alamo,

This is how my html-form looks. My first "name=manpage" should work if I say $in{'manpage'} = $value and then put than into my variable $manpage - or not? And the same for "name=section" ?
What did you use in your form for "name=" in the textfield and selection?

The html-form I use is the following:

<form action="http://path/to/cgi-bin/manpage.pl"
method="POST">
<p><font size="2" face="Verdana, Arial,Helvetica">Command:</font> <input type="text" size="40" name="manpage"></p>
<p><font size="2" face="Verdana, Arial, Helvetica">Which section is the man page located in?</font>
<select name="section" size="1">
<option selected>Don't know</option>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
<option>6</option>
<option>7</option>
<option>8</option>
</select></p>
<p><input type="submit" value="Submit">
<input type="reset" value="Clear Form"></p>
</form>

0
 
LVL 6

Expert Comment

by:alamo
ID: 1830966
Unfortunately it looks like everything you are doing in your HTML and your .pl is correct :) Your HTML uses the same field names as I did, as expected. Maybe some quirk of the way your server sets up the environment or in how cgi-lib.pl runs on your particular version of perl is responsible. Here are some suggestions:

- make certain the version of cgi-lib.pl perl is using is what you expect - make the path explicit rather than depending on @INC (perhaps an old version is laying around somewhere on your system).

- Change POST to GET. GET is a little simpler and is probably the right choice for your script in the first place, anyway - the result of a GET can be bookmarked which seems useful for a manpage utility.

- If that doesn't work, decide whether you want to debug a library module. (The usual answer is 'no', though I am sometimes stubborn enough to debug it just to get it working, and then throw it away since it was so buggy in the first place).
Start by putting in a couple of lines of code to print out the contents of $ENV{} so you can check what you are being passed.  

You could also ditch cgi-lib.pl and add a simple ReadParse-like function into your code, it's not that hard. If you choose this path I can post one I have used. Or, as you considered in the first place, use CGI.pm. Of course it's unlikely but certainly possible you will have similar problems with CGI.pm as well.
0
 

Author Comment

by:Bastholm
ID: 1830967
Hi alamo,

I hope you understand why I have been bewildered about this problem ;-) and I have reached the point where I want to abort using the readparse in cgi-lib.pl, and I have just tried using CGI.pm - guess what? same thing! I would very much like to see the code you are using for a local readparse function :-)

The thing about the GET vs. POST action yopu point out I must admit I never thought of.. I'll use GET instead, thanx.

And I thank you for your help!! SMILES ALL AROUND - even my sys.adm ;-)
0
 
LVL 7

Expert Comment

by:faster
ID: 1830968
This has to be some config problem, since all the html and pl are files are correct.  We just use your code for test and it turns out to be OK.

You can try one thing: put debug lines in cgi-lib.pl's ReadParse function and see where it goes wrong.  By trying this for several times( put it in different places to locate the exact problem), you should be able to solve it quickly.
0
 
LVL 7

Expert Comment

by:faster
ID: 1830969
For example, you can use the following code to replace the corresponding part of your cgi-lib.pl and see what it outputs.


  if ($len > $cgi_lib'maxdata) { #'
      &CgiDie("cgi-lib.pl: Request to receive too much data: $len bytes\n");
  }

print "type=$type,len=$len,meth=$meth\n";
 
  if (!defined $meth || $meth eq '' || $meth eq 'GET' ||
      $type eq 'application/x-www-form-urlencoded') {
    local ($key, $val, $i);
print "0000000000000";
       
    # Read in text
    if (!defined $meth || $meth eq '') {
      $in = $ENV{'QUERY_STRING'};
      $cmdflag = 1;  # also use command-line options
    } elsif($meth eq 'GET' || $meth eq 'HEAD') {
      $in = $ENV{'QUERY_STRING'};
    } elsif ($meth eq 'POST') {
print "11111111111111";
        if (($got = read(STDIN, $in, $len) != $len))
          {$errflag="Short Read: wanted $len, got $got\n";};
    } else {
      &CgiDie("cgi-lib.pl: Unknown request method: $meth\n");
    }


0
 
LVL 6

Expert Comment

by:alamo
ID: 1830970
Here's the simple drop-in replacement for ReadParse which assumes you are using GET. It's not intended to be general-purpose. Comment out the require line for cgi-lib.pl.

sub ReadParse {
  *FORM = pop;
  local(@rawargs) = split(/&/, $ENV{'QUERY_STRING'});
  foreach (@rawargs) {
    local($name, $value) = split(/=/);
    $value =~ tr/+/ /;
    $value =~ s/%([a-fA-F0-9]{2})/pack("C", hex($1))/eg;
    $FORM{$name} = $value;
  }
}

I suggest for debugging you add the following lines after calling ReadParse:

print "Content-type: text/html\n\n";  # need headers
foreach (keys %ENV) { print "ENV: $_=$ENV{$_}<br>\n"; } # print Environment
foreach (keys %FORM) { print "FORM: $_=$FORM{$_}<br>\n"; } # print form values

I would expect the following values in your environment:

ENV: REQUEST_METHOD=GET
ENV: QUERY_STRING=manpage=command&section=1 (exact values depend on query of course)

If you don't see those, something is wrong in how your script is being called - configuration, as faster said. If this works but you want to figure out what was wrong before, I'd expect the following in your previous program using POST:

ENV: REQUEST_METHOD=POST
ENV: HTTP_CONTENT_LENGTH=25 (exact length isn't that important)
ENV: HTTP_CONTENT_TYPE=application/x-www-form-urlencoded
0
 

Author Comment

by:Bastholm
ID: 1830971
Hi alamo and faster,

I have put the ReadParse function alamo included and changed the method to GET - and it works :) just fine now - except for the formatting of the nroff pages - but that might have something to do with the format of our man pages. The script runs fine and it returns:
 
print "Content-type: text/html\n\n"; # need headers
                   foreach (keys %ENV) { print "ENV: $_=$ENV{$_}<br>\n"; } # print Environment
                   foreach (keys %FORM) { print "FORM: $_=$FORM{$_}<br>\n"; } # print form values

as it is supposed to.

I haven't had time to test faster's add-on-script on my local cgi-lib.pl - but I hope to get it done quickly.

cheers!
0
 
LVL 6

Accepted Solution

by:
alamo earned 100 total points
ID: 1830972
Well, since the GET function I posted as a comment worked, let me propose it as the answer :-) We can continue to debug your POST problem via comments. The ENV debugging code I gave you should help determine where the problem was - maybe in the environment passed to you, maybe in the read from STDIN of the POST arguments  , maybe something else.
0
 

Author Comment

by:Bastholm
ID: 1830973
Thanx to both alamo and faster for their help with my problem - faster eventually ;-) threw in a couple of goodies to use in debugging my script!
0
 

Author Comment

by:Bastholm
ID: 1830974
Hi all,

Just a question: did the formating from nroff to html work fine in the environment you tested the script? I have tried to fiddle around with the $nroff = "/path/to/nroff -man"; statement - alternatively I have used -sun and some of the -ehiq switches. If you try to use these switches what sort of output behaviour do you get? Mine is all f... up - including the formating of the nroff in this statement - it just doesn't get the job done:

else {
                   $blank = 0;
                   s//&amp;/g if(/&/);
                   s//&lt;/g if(/</);
                   s//&gt;/g if(/>/);
                 
                   if (/((_\010\S)+)/) {
                   s//<B>$1<\/B>/g;
                   s/_\010//g;
                   }

                   if ($heading =~ /ALSO/) {
                   if (/([\w\+\-]+)\((\w+)\)/) {
                   s//<A HREF="$script\?manpage=$1\&section=$2">$1($2)<\/A>/g;
                   }

Just more trouble heading my way ;-[
0
 
LVL 6

Expert Comment

by:alamo
ID: 1830975
Well I orginally stripped that whole function out of my test, since it really wasn't relevant to the previous problem, but i took a look at it now. The biggest thing I noticed is that you weren't properly dealing with the bold sequence (at least on my nroff output). On mine, to bold a character it issues \010 and the character a few times, and to underline it it preceeds it with _\010. I think your code
  if (/((_\010\S)+)/) {
     s//<B>$1<\/B>/g;
     s/_\010//g;
  }
was supposed to do this. Replace the above code with:

# convert x\010x sequences to <b>x</b>
# need to check for < > & since we aleady converted them to multichar sequences
  s/(&amp;|&lt;|&gt;|.)(\010\1)+/<b>$1<\/b>/g;
  s/<\/b><b>//g;
# do same for underlined text - though in this case we convert to <i>
  s/(_\010)+(.)/<i>$2<\/i>/g;
  s/<\/i><i>//g;

If your output is anything like mine this will make a big difference. You still need to detect headers properly (move the header check to after the above code, not the first thing in the function, and change what it's looking for). This should get you a lot farther though and give you something to work with.
0
 

Author Comment

by:Bastholm
ID: 1830976
That snippet of code really helped alot, the full man-page is now displayed with the bold and italics (as expected ;-)) - but I still have the problem with the style for SYNOPSIS, DESCRIPTION etc. they are displayed as:

SSSSYYYYNNNNOOOOPPPPOOOOSSSSIIIISSSS

I have looked in the info on nroff that is available to me (not much) but I can't really figure out what sort of nroff heading I'm supposed to look for to replace with a html <h3>

if (nroff format) {
s/(format)+/<h3>$3<\/h3>/g;
s/<\/h3><h3>//g;
}

Who said it was ever going to be easy?!


0
 
LVL 6

Expert Comment

by:alamo
ID: 1830977
Isn't the heading line simply bold? for example, if you don't check for the header at all does it get converted to bold by the code you just added? That's how it looks to me. If not- maybe you could nroff -man (file) >out and make the out file accessible somewhere on the web so I see exactly what the codes are.
0
 

Author Comment

by:Bastholm
ID: 1830978
The nroff output is available at this url:

http://www.hum.auc.dk/~cj/nroff.format.txt

I have captured the perl.1 document and saved it to this file.
All the codes should be there.

If you want to see the scripts output - go to:

http://www.hum.auc.dk/~cj/unix.html -  then type in perl

(notice that it is NOT all commands which can be found??!!).
0
 
LVL 6

Expert Comment

by:alamo
ID: 1830979
Hi Bastholm, I didn't just forget about you, but I have tried that page every few days for 2 weeks now and I have always gotten the html form but the submit never ever connects. Is the action URL correct? Is the CGI machine behind a firewall or somehow otherwise inaccessible? If you can make it accessible to me I'll still look at it.
0
 

Author Comment

by:Bastholm
ID: 1830980
The local sys.adm has moved the Apache-server I use behind a local firewall which means that the script is only accessible to someone on the local network - I'll see if I can get him to put my script on another server - and then I'll post the URL that can access it, OK ;-) Sorry about the hassle.
0

Featured Post

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Preface In the first article: A Better Website Login System (http://www.experts-exchange.com/A_2902.html) I introduced the EE Collaborative Login System and its intended purpose. In this article I will discuss some of the design consideratio…
I will show you how to create a ASP.NET Captcha control without using any HTTP HANDELRS or what so ever. you can easily plug it into your web pages. For Example a = 2 + 3 (where 2 and 3 are 2 random numbers) Session("Answer") = 5 then we…
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…
The viewer will receive an overview of the basics of CSS showing inline styles. In the head tags set up your style tags: (CODE) Reference the nav tag and set your properties.: (CODE) Set the reference for the UL element and styles for it to ensu…

773 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question