Input parameter for perl CGI script - perl

I need some insight on my Perl CGI script.
First of all all this is running under webmin so i'm doing a custom module.
I'm calling a CGI Perl script passing 2 parameter from another Perl CGI. The link I'm calling is in the following format:
http://IP:8080/foobar/alat.cgi?sysinfo=xxxxxxx&SR=yyyyyyyy
The alat.cgi script look like this
#!/usr/bin/perl
use CGI qw(:standard);
ReadParse();
$q = new CGI;
my $dir = $in->param('SR');
my $s = $in->param('sysinfo');
ui_print_header(undef, $text{'edit_title'}.$dir, "");
print $dir."<br>";
print $s"<br>";
The only output I get printed is the value of $dir and $s seems to be empty.
What am I doing wrong?

As #Сухой27 said, add use strict;, but also use warnings; to the top of your script, right below the shebang (#!/usr/bin/perl) line. Those will tell you about syntax errors and other stuff where Perl is doing something other than you might intend.
With CGI (which is btw not part of the Perl core in the latest 5.22 release any more) and the object oriented approach you are tyring to take, you don't need to use ReadParse(). That is an abomination left in from Perl 4's cgilib.pl times.
I don't know what your ui_print_header function does. I'm guessing it outputs a bunch of HTML. Are you sure you defined it?
With fixing all your syntax errors and using modern syntax, your program would look like this. I'll break down what is happening for you.
#!/usr/bin/perl
use strict;
use warnings;
use CGI;
my $q = CGI->new;
my $dir = $q->param('SR');
my $s = $q->param('sysinfo');
# you need to declare this to use it below
my %text = ( edit_title => 'foo' );
# we declare this sub further down
ui_print_header(undef, $text{'edit_title'} . $dir, q{});
print $dir . '<br />';
print $s . '<br />';
sub ui_print_header {
my ( $foo, $title, $dir, $bar ) = #_;
# do stuff here...
}
Let's look at some of the things I did here.
Saying new CGI as the CGI docs suggest is fine, but since we are using the OOP way you can use the more common CGI->new. It's the same thing really, but it's consistent with the rest of the OOP Perl world and it's more clear that you are calling the new method on the CGI package.
If you have $q, keep using it. There is no $in.
Declare all your variables with my.
Declare %text so you can use $text{'edit_title'} later. Probably you imported that, or ommitted it from the code you showed us.
Declare ui_print_header(). See above.
q{} is the same as '', but it's clearer that it's an empty string.

thank you everyone for the very quick answer, and as I was suspecting I just had some silly mistake.
Adding here the corrected code that now works
#!/usr/bin/perl
# Run alat on selected sysinfo and allow display of output
#use strict;
use diagnostics;
require 'recoverpoint-lib.pl';
use CGI qw(:standard);
ReadParse();
my $q = new CGI;
my $dir = $q->param('SR');
my $s = $q->param('sysinfo');
ui_print_header(undef, $text{'edit_title'}.$dir, "");
print $dir."<br>";
print $s."<br>";
Just to clarify for some of previous answer, this is a custom module of webmin so variable $text is imported and function ui_print_header is a webmin defined one, it basically print the page header in HTML

As you enable strict and warnings you can easily know the errors.Also you should check Apache error logs, I think the script should be like this:
#!/usr/bin/perl
use CGI qw(:standard);
use strict;
use warnings;
ReadParse();
my $q = new CGI;
my $dir = $q->param('SR');
my $s = $q->param('sysinfo');
ui_print_header(undef, $text{'edit_title'}.$dir, "");
print $dir."<br>";
print $s."<br>";

Related

using perl cgi to fetch cookies

I'm trying to inspect cookie values in a cgi script; my test script looks like
#!/usr/bin/perl -w
use DBI;
use CGI qw/:standard/;
use CGI::Cookie;
my $cgiH = CGI->new;
print header;
print start_html(-title=>'Cookie Terms'), h1("Cookie Terms"), "<hr>\n";
%cookies = CGI::Cookie->fetch;
foreach $k (keys %cookies) {
my $term = "$cookies{$k}";
my $term =~ s/SubjectTerm//;
print "at $k is $term \n";
}
print end_html;
the relevant input to the script (from an HTTP GET) is
Cookie: SubjectTerm1=ponies
Cookie: SubjectTerm2=horses
(this is verified by using either fiddler or debugging the code in my delphi app). the result of my script (omitting the HTML wrapper) is either
at SubjectTerm1 is
at SubjectTerm2 is
or if I change the print statement to
print "at $k is $cookies{$k}\n";
it is
at SubjectTerm1 is SubjectTerm1=ponies; path=/
at SubjectTerm2 is SubjectTerm2=horses; path=/
What I want to arrive it is something like this
at SubjectTerm1 is ponies
at SubjectTerm2 is horses
I know I'm missing something about the hash usage but can't quite figure out what it is.
am I not addressing the %cookies hash correctly?
If you had use warnings you would see you are clobbering the $term with the line
my $term =~ s/SubjectTerm//;
Remove the my.
I think you might be able to extract the value is simply changing the assignment to
my $term = $cookies{$k}->value();
and get rid of the s/SubjectTerm//. But not sure about this sorry.
As an aside, before I answer the question, I'd strongly recommend you look at using something other than CGI.pm -- it's the best of late-90s Perl, and other than being included by default in the core perl distribution has little to recommend it.
Some more modern, more featureful alternatives include:
CGI::Application - http://cgi-app.org/
Mojolicious - http://mojolicio.us/
Dancer - http://www.perldancer.org/
Beyond that, as #Sodved says if you'd included use strict; and use warnings; at the top of your file the first of your problems -- clobbering $term by using my twice -- would have been highlighted immediately.
Once you're using the strict and warnings pragmas (and I'd say, don't leave home without them) you'll also want to change your foreach to either:
foreach (keys %cookies) {
my $term = $cookies{$_};
...
OR
foreach my $k (keys %cookies) {
my $term = $cookies{$k};
...
That is, you'll either need to declare the $k variable, or you may prefer to use Perl's built-in $_ inside the loop -- it's purely a matter of style.
Good luck!

How to use a module in Perl

Guys im really confused on how to use a module i just installed in Perl.
I installed a Corelist module in Perl. And i want to display all the modules that came with Perl 5.006. But there is a hint in doing this by using this code which i dont understand:
my %modules = %{ $Module::CoreList::version{5.006} };
But when i did this
#! usr/bin/perl
use warnings;
use strict;
my %modules = %{$Module::CoreList::version{5.006}};
print %modules;
it gives this error: Module::CoreList::version used only once . I also tried putting
use Module::CoreList; still no luck
The name of the module is 'Module::CoreList'. You should put the following line into your programme:
use Module::CoreList;
Also note the capital L. Perl is case sensitive.
If you simply want to print the hash, just add Data::Dumper module along with strict and warnings, then
print Dumper(\%modules);
Updated: try something like
use warnings;
use strict;
use Module::CoreList;
use Data::Dumper;
my %module = %{ $Module::CoreList::version{5.006} };
print Dumper (\%module);

How to use Term::ReadLine to retrieve command history?

I've the following script, which is almost the same of the sample in synopsis paragraph in documentation.
use strict;
use warnings;
use Term::ReadLine;
my $term = Term::ReadLine->new('My shell');
print $term, "\n";
my $prompt = "-> ";
while ( defined ($_ = $term->readline($prompt)) ) {
print $_, "\n";
$term->addhistory($_);
}
It executes with no error, but unfortunately, even if I click the Up Arrow, I only get ^[[A and no history. What am I missing?
The print $term statement prints Term::ReadLine::Stub=ARRAY(0x223d2b8).
Since we are here, I noticed it prints the prompt underlined... but I can't find in the docs anything which could prevent it. Is there any way to avoid it?
To answer the main question, you probably don't have a good Term::ReadLine library installed. you will want either 'perl-Term-ReadLine-Perl' or 'perl-Term-ReadLine-Gnu'. These are the fedora package names, but i'm sure that the ubuntu/debian names would be similar. I believe you could also get them from CPAN, but I haven't tested that. If you haven't installed the package, perl loads a dummy module that has almost no features. for this reason history was not part of it.
The underline is part of what readline calls ornaments. if you want to turn them off completely, add $term->ornaments(0); somewhere apropriate.
my rewrite of your script is as follows
#!/usr/bin/perl
use strict;
use warnings;
use Term::ReadLine; # make sure you have the gnu or perl implementation of readline isntalled
# eg: Term::ReadLine::Gnu or Term::ReadLine::Perl
my $term = Term::ReadLine->new('My shell');
my $prompt = "-> ";
$term->ornaments(0); # disable ornaments.
while ( defined ($_ = $term->readline($prompt)) ) {
print $_, "\n";
$term->addhistory($_);
}

Is there a module that searches for superfluous code?

Is there a module, which can find code not needed?
As an example a script with code not needed to run the script:
#!/usr/bin/env perl
use warnings;
use 5.12.0;
use utf8;
binmode STDOUT, ':utf8';
use DateTime;
use WWW::Mechanize;
sub my_print {
my ( $string, $tab, $color ) = #_;
say $string;
}
sub check {
my $string = shift;
return if length $string > 10;
return $string;
}
my_print( 'Hello World' );
Not categorically. Perl is notoriously difficult to analyze without actually executing, to the point that compiling a Perl program to be run later actually requires including a copy of the perl interpreter! As a result there are very few code analysis tools for Perl. What you can do is use a profiler, but this is a bit overkill (and as I mentioned, requires actually executing the program. I like Devel::NYTProf. This will spit out some HTML files showing how many times eaqch line or sub was executed, as well as how much time was spent there, but this only works for that specific execution of the program. It will allow you to see that WWW::Mechanize is loaded but never called, but it will not be able to tell you if warnings or binmode had any effect on execution.
Devel::Cover provides code coverage metrics that may be of some use here.

In Perl, how do I send CGI parameters on the command line?

Normally i get the data from a webpage but i want to send it from the command line to facilitate debugging.
To get the data i do something like:
my $query = new CGI;
my $username = $query->param("the_username");
this doesn't seem to work:
$ ./script.pl the_username=user1
EDIT:
Actually the above works. The if statement that checked $username was wrong (using == instead of eq).
As I found out long time ago, you can indeed pass query string parameters to a script using CGI.pm. I am not recommending this as a preferred debugging method (better to have replicable stuff saved in files which are then directed to the STDIN of the script), however, it does work:
#!/usr/bin/env perl
use warnings; use strict;
use CGI;
my $cgi = CGI->new;
my $param_name = 'the_username';
printf(
"The value of '%s' is '%s'.\n",
$param_name, $cgi->param($param_name)
);
Output:
$ ./t.pl the_username=yadayada
The value of 'the_username' is 'yadayada'.
CGI reads the variables from standard input.
See this part of the CGI.pm documentation:
http://search.cpan.org/dist/CGI/lib/CGI.pod#DEBUGGING