We have few files which don't have the standard perl extension like cgi etc.
Couple of them end with *.cfm and have perl code in them.
Now i am not sure why the developer decided to use a coldfusion extension and decide to use perl in it, but we are at a point now where we cannot alter the filename and we need to make some configuration changes such that perl is able to render *.cfm files too.
Is there a way we can modify the perl configuration to accept *.cfm files and render them as perl scripts?
I'll go out on a limb and guess that your actually asking about running ".cfm" files as CGI scripts, through Apache. In that case, you would use a "handler" to tell Apache to treat all *.cfm files as Perl scripts. If I've guessed what's going on, then add this to your Apache 2.2 configuration:
AddHandler cgi-script .cfm
Also, make sure the Perl scripts have the right "shebang" line on the first line, usually:
#!/usr/bin/perl
If you want some *.cfm files to be still be treated as Cold Fusion, then you'll need a different solution.
Related
Perl newbie here with very little time and support to learn Perl but all the expectations from management to use it like a Perl Pro :)
I am using Perl (v5.30.2 by Larry Wall) under Cygwin (windows 10)
My developer issued a new script, that now uses a Perl module I didn't have.
They then sent me the .pm file (which they authored themselves and it is not on any online Perl repo).
I was unable to use CPAN to install that file into my Perl execution environment.
Where should the .pm file be saved at? (please specify the exact folder)
How to tell CPAN to install this file for usage? Ideally, a one-time affair, as I don't want to forget installing this file, if I have to do that every time I need to run the Perl script...
Just in case there may be any security concern from the dear answer-ers: There isn't any security concern here, this is all under an environment that has no connection to the internet.
A Perl module is just a file (or collection of files). You don't have to put them anywhere special, but you need to tell Perl where to find them.
When you call use or require with a bareword, Perl translates that module name, like Some::Module, into Some/Module.pm (or whatever is appropriate for your system. Anyone still using VMS?).
Once it has the filename form of the module, it looks for that subpath in the directories in #INC. It tries the first directory. If it doesn't find it it moves on to the next, and so on down the line. These directories are decided when someone configures and installs Perl. And, before v5.26, it included the current working directory (see v5.26 removes dot from #INC and Doesn't Perl include current directory in #INC by default?
)
But, you can tell Perl where else to look. perlfaq8 has How do I add a directory to my include path (#INC) at runtime?. ikegami also showed FindBin in the comments (How do I add the directory my program lives in to the module/library search path?).
Beyond that, you can tell require to load a path, although you then need to ensure that the program can find that path even if someone runs it from another directory
require './this_file/over/here';
require '/usr/local/lib/this_file/over/here';
I got a huge project written on Perl, which contains many of scripts which starts with typical #!/usr/bin/perl
For this project I need a custom-built Perl to be compiled from source.
I tried just to replace /usr/bin/perl with my compiled one but OS becomes broken (for ex. module version mismatch etc).
So is there any correct way to replace system perl with my own-built one or the easiest way would be to edit all tons of scripts and replace /usr/bin/perl with /usr/local/bin/perl or something like this?
Do not replace system perl (or system binaries in general). You can build it to another location (as you suggested, /usr/local for example) and call it manually.
My personal preference is to use plenv. There's a nice guide here to get you started.
If you admin the server and other users are logging in an using your scripts, you'll want to build plenv somewhere outside your home directory (eg. /opt/plenv) and ensure that all users $PATH is prepended with the bin path of your new perl. Without digressing too much, this can be done in /etc/profile or even better to declare you custom profile mods in a custom profile script (eg. /etc/profile.d/custom.sh).
I would also suggest using a more portable shebang such as #!/usr/bin/env perl which will use whichever perl is in a users $PATH first. The only exception to this is cron jobs, which I typically always hardcode full paths. (This is a personal preference based entirely how I admin my boxes and probably not a good idea to recommend unless you know the full repercussions. Administering a server is entirely subjective based on it's use-case, your use-case likely differs vastly from mine).
According to comments, there is no solution to replace system Perl without of destroying something but the're 3 solutions to solve the descibed problem. For all of them i need to modify all the scripts.
Using #!/usr/bin/env perl (need to be very careful and place custom perl bin path before all at $PATH of user which runs the script. The nice solution would be to set PATH exactly at crontab.
Using straight new perl path at shebang like as #!/usr/local/bin/perl5.26.1
Totally remove shebang from scripts and use plain calls at cron and manual runs - like as /usr/bin/perl script.pl. Or just use plain calls - shebang would be ignored.
Special thanks to #Joshua and #ikegami
I have a perl script that is encrypted. This script can be compiled only if Filter::decrypt is installed. I have that Filter and I installed it and the script is compiled with no problem, but now I want to open that script with some text editor and edit it.
Can someone help me and tell me how can I do this?
Pretty fundamentally - it's extremely difficult to make a script unreadable, simply because perl is an interpreted language. Exactly how to disentangle something is more a question of how it got tangled in the first place.
So I would suggest as a first port of call - have a look through Mastering Perl which has a whole chapter on the subject of disassembling perl code.
However if you just look at the Filter::decrypt module page, it indicates several places which the module simply cannot cover - you can only truly 'protect' code if you've control of the perl interpreter in the first place. However the things it suggests are:
Strip the Perl binary to remove all symbols.
Build the decrypt extension using static linking. If the extension is provided as a dynamic module, there is nothing to stop someone from linking it at run time with a modified Perl binary.
Do not build Perl with -DDEBUGGING. If you do then your source can be retrieved with the -Dp command line option.
The sample filter contains logic to detect the DEBUGGING option.
Do not build Perl with C debugging support enabled.
Do not implement the decryption filter as a sub-process (like the cpp source filter). It is possible to peek into the pipe that connects to the sub-process.
Check that the Perl Compiler isn't being used.
There is code in the BOOT: section of decrypt.xs that shows how to detect the presence of the Compiler. Make sure you include it in your module.
Assuming you haven't taken any steps to spot when the compiler is in use and you have an encrypted Perl script called "myscript.pl", you can get access the source code inside it using the perl Compiler backend, like this
perl -MO=Deparse myscript.pl
Note that even if you have included the BOOT: test, it is still possible to use the Deparse module to get the source code for individual subroutines.
So:
perl -MO=Deparse yourscript
perl -Dp yourscript
If these don't work - look at your local copy of Filter::decrypt and alter it so it prints the decrypted result.
Best option: Just edit your unencrypted copy and reinstall it.
Alternative: Use decr (comes with Filter::decrypt) to decrypt an encrypted file.
I am working on creating an agent in perl which does several actions. It uses several modules which are in .pm format and also few libraries. Now i want to convert it as one executable file so that i can install in n number of servers by copying that single file. Is it something i can achieve in perl? I am just a beginner in perl, perhaps my question might sound dumb but it will teach me something.
pp script provided with PAR::Packer is able to create single-file executables. An example from its page:
pp -o foo foo.pl bar.pl # Pack 'foo.pl' and 'bar.pl' into 'foo'
Some modules are included with Perl, so even though they're separate modules, they will work on other Perl installs without installing those modules. These include File::Copy, File::Find, Time::Piece.
You can see the listing of all standard modules on the Perldoc home page. Be sure to set the drop down version field (located on the left side) to the version that you're using. It goes all the way back to Perl 5.8.8 which is on Solaris.
It is entirely possible that the modules you need are already included in the standard Perl distribution, so there's no need to worry. Sometimes, you can substitute a non-standard module that's being used for one that's a standard module with little rewriting.
Some modules include compiled C code and can't be redistributed. They must be compiled on the machine they'r running on and installed. However, most modules are pure Perl modules, and can be redistributed with a program.
If a module isn't a standard module, and it's a pure Perl module, there are two ways it can be redistributed:
Perl has an #INC list that says what directories to search for when you search for modules. There's a Perl use lib pragma that allows you to add directories. You could include modules as sub directories for your program, and then zip up the entire structure. Users would unzip the entire directory tree which would include your program and the modules you need. By the way, the default #INC usually includes the current directory.
The other way is to append the modules to your program and then remove the use statement for that module (since it's now part of the file). This is a bit tricky, but it means a single program file.
Just remember that a module might require another module, so check thoroughly.
Another thing you can do is check for the module, and if it isn't there, download it via CPAN. Testing is easy:
BEGIN {
eval {
require My::Module; Module->import( LIST );
};
if ($#) {
die qq(Module doesn't exist);
}
}
Of course, doing a die is sort of silly because use would do that. However, it might be possible instead of dying to load the module via the CPAN module programmer's interface. I've never done that, and I don't know people who have. But, it is possible.
So, your best bet is to check to see if your program uses standard Perl modules, and if not, see if you can modify the program to use them. For example, if your program uses Archive::Zip, you might be able to modify it to use IO::Uncompress::Unzip and IO::Compress::Zip instead.
Otherwise, your choice is to try include those modules for installation (and watch for recursiveness and non-Pure Perl modules) or to try to detect that a module isn't installed, and programmatically install it.
The answer is a bit complicated.
The nature of Perl makes it practically impossible to compile a perl script in most use cases, so that a single executable could be distributed (with executable in the Windows sense). There are ways to do something similar, but sadly I don't know them.
But you can actually embed the Perl interpreter inside any C application, including the Perl source (your scripts + modules). When you statically link all C libraries, this should work as well. You can then use the Perl API to call your scripts.
If all of the servers you target are guaranteed to run the exact same OS, using the exact same libraries, and are preferably a *nix of some sort, it would be possible to pack all required files into an archive and write an install script. It is possible to write self-extracting shell scripts that contain the archive they are about to unpack. Same goes with perl, using the special __DATA__ command and the DATA filehandle:
#!/usr/bin/perl
print for <DATA>;
__DATA__
1
2
3
prints
1
2
3
Works great for piping data to tar as well.
You should include all dependent modules and all compiled libraries into the file and figure out a metadata system to install all files to the correct place.
As a general rule, software should rather be compiled on the target system itself, than just copying the binary files. It is too easy to overlook architecture differencies, configuration files or special registration entries hidden from view.
If you have to target different systems, it might be better to write a script that delegates the bulk of the installation to cpan or whatever perl package manager you prefer. This will be more flexible than hard-coding filepaths.
#!/bin/bash
cpan install Foo::Bar
cpan install Acme
cpan install ...
# etc.
I would stick with that.
The most elegant solution would be to create your own package or distribution like the ones you download from CPAN. As you would include a metadata file referencing all your dependencies, cpan would figure out everything by itself and do possibly neccessary compilation. I don't think this exactly is a beginners topic, but it would give you max flexibility and maintainability (easy upgrades!). This should make it fairly easy to include some installation tests.
This is just for starters, I am sure the internet or somebody else with more knowledge will elaborate.
What does it mean when I access my Perl script via URL, but when I do, the source code is printed on the screen?
Does this mean that Perl isn't properly set up? I'm using Apache on Fedora.
This means your webserver isn't set up to execute the script at that url. What server are you using?
It could also mean you are putting the Perl script in the wrong folder. The cgi-bin folder is still widely used as the folder where CGI scripts should be stored and run from. Other folders may just open the file and read it as text, similar to an HTML document, instead of running the document as code. But it can also mean the server is just not setup properly to run Perl scripts or other types of server-side scripts.
This means that you probably aren't doing what your server is expecting. Usually servers expect either that every file in a CGI directory is an executable, or that files with a certain extension are executable and it can serve any other file as its content.
Figure out which file extension your server expects your CGI program to use.
Ovid's CGI Course may help you (if you use CGI of course)