How to print out package code? - perl

I have some difficulties with perl script which have one module (.pm) encoded by custom function and before module is loaded into .cgi scrcript is always decoded.
I could even let it be as it is but currently I have to do several changes in subroutines which this module contains and since it is encoded I am helpless ;/
So far I've tried several ways i.e:
#!/usr/bin/perl
use strict;
use lib '.';
use ModuleX; ### This is encoded module which I need
use CGI::Carp qw(fatalsToBrowser);
Unfortunatelly $body returns only ";" as a result ;/ I hope that it is possible to get those method code, but I have no idea what else I could do.
Thanks for help.

Are you trying to deparse the new method in the ModuleX package? Then I believe that you want to say
my $body = $deparse->coderef2text(\&Modulex::new);

Related

How can I pass variables from one CGI script to another?

I have a CGI perl script called install-app-pl.cgi:
#!/usr/bin/perl -w
print header('text/html');
use strict;
use CGI ':standard';
# Get me some vars
my #params = param();
my $APP_NAME = param('app_name');
my $APP_WEB_PORT = param('app_web_port');
my $APP_WEB_USER = param('app_web_user');
my $APP_WEB_PASS = param('app_web_pass');
my $DOWNLOAD_DIR = param('download_dir');
my $CONFIG_DIR = param('config_dir');
my $LIBRARY_DIR = param('library_dir');
my $TEMP_DOWNLOAD_DIR = param('temp_download_dir');
# Run another script
if ( $APP_NAME ) {
print "Installing $APP_NAME...";
print "<pre>";
system ("perl /var/www/mysite.local/public_html/lib/$APP_NAME/install-$APP_NAME.pl");
print "</pre>" ;
}
else {
print "No app specified, check the error log";
}
I'm trying to get it to pass the variables defined from the CGI parameters to install-$APP_NAME.pl
#!/usr/bin/perl -w
print header('text/html');
use strict;
use CGI ':standard';
require "/var/www/mysite.local/public_html/cgi-bin/install-app-pl.cgi"
# Echo my vars
print "$CONFIG_DIR $DOWNLOAD_DIR $LIBRARY_DIR $PGID $PUID $TZ $APP_WEB_PORT";
But I'm not sure of the best way to pass those on.
Are you sure that install-app-pl.cgi is a CGI program? Are you sure that it's not just a Perl command-line program? I mean, I see how it's named, but it seems very strange to call a CGI program using system() like that.
And the difference is crucial here. CGI programs access their parameters in a different way command-line programs.
If it really is a CGI program, then you have a few options:
Make an HTTP request to it (using something from the LWP bundle of modules).
Use CGI.pm's debugging mechanism to call it the same way as you're currently calling it, but passing the CGI parameters like foo=xxx&bar=yyy&baz=zzz (see the DEBUGGING section of the CGI.pm documentation for details). This, of course, relies on the program using CGI.pm and it feels a bit hacky to me.
Ask yourself if the program really needs to be a CGI program if you're calling from another program using system(). And then decide to rewrite it as a command-line program. If you want both a CGI version and a command-line version, then you could move most of the code to a module which could be used by two thin wrappers which just extract the parameters.
A few other points about your code.
Perl 5.6 (released in 2000) introduced a use warnings pragma. Most people now use that in place of -w on the shebang line.
It seems weird to call the header() function before loading the CGI module that defines it. It works, because the use is handled at compile time, but it would be nice to re-order that code to make more sense.
Similarly. most people would have use strict (and use warnings) as the very first things in their program. Immediately after the shebang line.
system() returns the return value from the process. If your second program produces useful output that you want displayed on the web page, you should use backticks instead.
If all of your output is going to be in a <pre> element, why not just remove that element and return a content type of "text/plain" instead?
Update: And I'd be remiss if I didn't reiterate what many people have already said in comments on your original question - this sounds like a terrible idea.

how to use utf-8 in a perl cgi-bin script?

I have the following cgi bin script:
#! /usr/bin/perl
#
use utf8;
use CGI;
my $q = CGI->new();
my %params = $q->Vars;
print $q->header('text/html');
$w = $params{"words"};
print "$w\n";
I want to be able to call it as cgi-bin/script.pl?words=É for example, but when I do that, what's printed is not UTF-8, but instead garbled:
É
Is there any way to use cgi-bin with utf8?
Your line use utf8 doesn't do anything for you, other than allowing UTF-8 characters in the source file itself. You must make sure that the output handles (on STDOUT as well as any files) are set to utf8. One easy way to handle this is the utf8::all module. Also, make sure you are sending the correct headers, and use the -utf8 CGI pragma to treat incoming parameters as UTF-8. Finally, as always, be sure to use strict and warnings.
The following should get you started:
#!/usr/bin/perl
use strict;
use warnings;
use utf8::all;
use CGI qw(-utf8);
my $q = CGI->new;
print $q->header("text/html;charset=UTF-8");
print $q->param("words");
exit;
I have been having this problem of intermittent failure of utf8 encoding with my CGI script.
I tried everything but couldn't reliably repeat the problem.
I finally discovered that is is absolutely critical to be consistent with you use of the utf8 pragma throughout every module that uses CGI
use CGI qw(-utf8);
What seems to happen is that modperl invokes the CGI module just once per requests. If there is inconsistent including of the CGI module - say for some utility function that is just using a redirect function and you haven't bothered to set the utf8 pragma. Then this invocation can be the one that modperl decides to use to decode requests.
You will save yourself a lot of pain in the long run if you start out by reading the perlunitut and perlunicode documentation pages. They will give you the basics on exactly what Unicode and character encodings are, and how to work with them in Perl.
Also, what you're asking for is more complex than you think. There are many layers hidden in the phrase "use cgi-bin with utf8", starting with your interface to whatever tool you're using to send requests to the web server and ending with that tool having parsed a response and presenting it to you. You need to understand all those layers well enough to at least be able to tell if the problem lies in your CGI script or not. For example, it doesn't help if your script works perfectly if the problem is that bash and curl don't agree on the encoding of your command line arguments.

How do i load the package self in perl?

Right now I'm trying to generate XML and print it out from Perl. I found this module, XML::Write, which looked rather nice. But when i wanted to try it out i ran in to some rather strange errors...
My test script looks like this
#!/usr/local/bin/perl -w
use strict;
use strict 'refs';
use XML::Writer;
my $writer = XML::Writer->new(OUTPUT => 'self');
$writer->xmlDecl("ISO-8859-1");
$writer->startTag("foo");
$writer->endTag("foo");
$writer->end;
print $writer->to_string;
and when I run it the only output is
Can't locate object method "print" via package "self" (perhaps you forgot to load "self"?) at /usr/lib/perl5/site_perl/5.8.8/XML/Writer.pm line 132.
What am I missing? Do i have to install some extra module to make the OO parts of perl avaliable? Should I somehow install an old version of XML::Write since I have a rather old Perl version?
Any help would be appreciated!
The special value self for the OUTPUT option of the constructor was added in v0.620. Previously, it expected an IO::Handle or a scalar reference.
Install the current version to be able to use this feature, or consult the documentation of the version you have installed (e.g. with command-line perldoc XML::Writer or by selecting your version in the “Go to version” drop-down list on the metacpan page.)
For your use case, you can supply a reference:
my $output;
my $writer = XML::Writer->new(OUTPUT => \$output);
...;
print $output;
I had a similar error message. My problem was that I was missing a $sign in the body of the module I was trying to load. There was an instruction self->... that should have been $self->....
I hope this helps

Got error using LWP

I was trying to use LWP in perl, and I followed the example given in the link:http://www.perl.com/pub/2002/08/20/perlandlwp.html,
But I got errors as such:
"www.google.com" is not exported by the LWP::Simple module
Can't continue after import errors at /System/Library/Perl/Extras/5.12/LWP/Simple.pm line 23
And here is my code:
#!/usr/bin/perl -w
use LWP::Simple
$url = 'www.google.com';
$content = get $url;
Am I doing something wrong here?
You need a semicolon after your use statement, and your URL needs to have a protocol specified.
#!/usr/bin/perl
use LWP::Simple;
use strict;
use warnings;
my $url = 'http://www.google.com';
my $content = get $url;
Yes. You missed the semicolon after use LWP::Simple.
Had you used strict it would have told you that you have to declare $url. But if you declared both variables, you would still have gotten the error you did.
So, it's not a simple case of USUW.
Because you didn't put a semi-colon after the import statement, perl is assigning the string 'www.google.com' to the autovariable $url. And then, as it is an expression that can be passed, it passes that value as an export arguments of LWP::Simple.
Modules expect that any values passed as arguments to its import process, are symbols that the module--or Exporter--knows how to export.
So it's telling you that the whatever that string that you passed in is, it's not something that the module exports.
So, you just have to get used to this type of message pointing out that something is wrong with your import statement.

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