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

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??
for updates see

hi monks, this question is asked quite often, at least in the forums i read often. people have a webserver, but only ftp access, and of course no root.

while it is relatively easy to provide the answer if it's a pure perl module (create directory and put .pm file into it) it gets more complicated if the module is not pure perl.

still, i think, many people might have make and a compiler available through system() in a CGI-script.
however, to do all the Makefile.PL stuff with a CGI-script is messy. so i wrote a little script (namely cgipan) which does that. it's probably far from being able to install all kinds of modules, but i could install Config::IniFiles and with it (yes, there's no on my webhoster's machine...)

also my script does no sanity checks at all (yet), but it shouldn't be be publicly accessible at all anyway.
note that the script should only be accessible for you (use .htaccess or just use it temporarily), and note that the created library is writeable for the webserver. this might or might not be a security risk in your shared environment. when in doubt, copy the created lib to another directory with your user/ftpuser permissions.

i would be glad if someone could look over it and try it out, or just comment if this is a good idea. update: It's also availabe at my module archive

it's ready for running, and you probably only have to change the $root-variable and/or $build_dir and $lib. these directories have to be writeable by the webserver. put your Module-3.13.tgz in $build_dir and start. to use the installed module, you have to do use lib $lib, where $lib is that directory you set in the cgipan script.

so if you think it's a good idea i would continue to work on it.

and, in advance, i wish you all a happy new year!

update: yes, probably 'Cool uses' is a better place for it

update: okay, i'll move the script from my scratchpad here in readmore tags (or is it too much code?):

update 2.1.2005: extended security tipps

please look here for updates. I added taint mode now in version 0.05
#!/usr/bin/perl -w # --------------------------- # Cgipan # CGI-Script for installing modules on a server where you don't # have root access and no shell access. You have to have # tools like make and tar, though. # Tina Mueller, Dec 29th 2004 # --------------------------- use strict; use vars qw($VERSION); $VERSION = 0.04; # --------------------------- # Change variables to your needs (you probably just need # to change $root) # own root dir on server (not / though) # or leave blank, then $ENV{DOCUMENT_ROOT} will be used, # which might not be a good thing my $root = '/homepages/bla/blubb/cgipan' || $ENV{DOCUMENT_ROOT} || ''; # create before starting; must have write permissions # for webserver my $build_dir = "$root/build"; my $lib = "$root/mylib"; # path to make my $make = '/usr/bin/make'; # path to tar my $tar = '/bin/tar'; # or /usr/bin/gtar ... # url to cgi-script. $ENV{SCRIPT_NAME} should be sufficient my $self = '' || $ENV{SCRIPT_NAME}; # or you can define all these variables in your own cgipan.conf # ($self, $make, $tar, $build_dir, $lib) if (-f "cgipan.conf") { open D, "cgipan.conf" or die $!; local $/; my $conf = <D>; close D; eval $conf; } # --------------------------- #use Data::Dumper; use CGI; use CGI::Carp qw(fatalsToBrowser); my $cgi = CGI->new; my $w = $cgi->param('w') || $cgi->path_info || 'start'; $w =~ s#^/##; print head($w); #print "$_ = $ENV{$_}<br>" for sort keys %ENV; my %map = ( start => \&start, ut => \&unpack_tar, sd => \&show_dist, pmf => \&makefile, make => \&mmake, maket => \&make_test, makei => \&make_install, tm => \&test_module, ); my $sub = $map{$w}; $sub->(); print foot($w); sub test_module { my $module = $cgi->param('mod'); unless ($module) { print <<EOM; <br>Test if Module is installed: <form action="$self/tm"> <input type="text" name="mod"> <input type="submit" value="go"> </form> EOM return; } my $version; my $path; my $inc_mod = $module; $inc_mod =~ s#::#/#g; $inc_mod .= ".pm"; eval qq#use lib qw($lib); use $module; \$version = \$${module} +::VERSION; \$path = \$INC{"$inc_mod"};#; print <<EOM; Errors: (<tt>$@</tt>)<br> \$${module}::VERSION = $version<br> \$INC{$inc_mod} = $path<br> EOM } sub makefile { my $dist = $cgi->param('dist'); chdir $build_dir; chdir $dist; my $cmd = qq#perl -I$lib Makefile.PL PREFIX=$lib LIB=$lib 2>&1 +#; my $out = command($cmd); print $out; print qq#if everything looks okay, you may now build the modul +e: <a href="$self/make?dist=$dist">make</a>#; } sub mmake { my $dist = $cgi->param('dist'); chdir $build_dir; chdir $dist; my $cmd = qq#$make 2>&1#; my $out = command($cmd); print $out; print qq#if everything looks okay, you may now make the tests: <a href="$self/maket?dist=$dist">test</a>#; } sub make_test { my $dist = $cgi->param('dist'); chdir $build_dir; chdir $dist; my $cmd = qq#$make test 2>&1#; my $out = command($cmd); print $out; print qq#if everything looks okay, you may now install: <a href="$self/makei?dist=$dist">install</a>#; } sub make_install { my $dist = $cgi->param('dist'); chdir $build_dir; chdir $dist; my $cmd = qq#$make install 2>&1#; my $out = command($cmd); print $out; print qq#Ok, if everything looks fine, you are done! You can verify if the module is <a href="$self/tm">installed</a>.#; } sub command { my $cmd = shift; my $output = qx#$cmd#; return qq#<pre>$cmd:\n$output</pre>#; } sub unpack_tar { my $tarf = $cgi->param('tar'); chdir $build_dir; print q#Trying to unpack $tarf...<br>#; my $cmd = qq#$tar -xvzf $tarf 2>&1#; my $output = command($cmd); print <<EOM; $output if everything looks okay, you should see the unpacked directory: <a href="$self">start</a> EOM } sub show_dist { my $dist = $cgi->param('dist'); chdir $build_dir; opendir my $dir, $dist or die "Could not open '$dist': $!"; my @files = grep { !m/^\.\.?$/ } readdir $dir; closedir $dir; print <<EOM; 1. <a href="$self/pmf?dist=$dist"><tt>perl -I$lib Makefile.PL PREFIX=$ +lib LIB=$lib</tt></a><br> 2. <a href="$self/make?dist=$dist"><tt>make</tt></a><br> 3. <a href="$self/maket?dist=$dist"><tt>make test</tt></a><br> 4.<a href="$self/makei?dist=$dist"><tt>make install</tt></a><br> <p> EOM print qq#<pre>#; print qq#$_\n# for @files; print qq#</pre>#; } sub start { my %list = list_build(); print qq#Directories:<br><ul>#; foreach my $file (@{$list{dir}}) { print qq#<li><a href="$self/sd?dist=$file">$file</a></ +li>#; } print qq#</ul>Files:<br><ul>#; foreach my $file (@{$list{file}}) { print qq#<li>$file <a href="$self/ut?tar=$file">unpack</a></li>#; } print qq#</ul>#; } sub list_build { chdir $build_dir; opendir my $dir, "." or die "Could not open '$build_dir': $!"; my @files = grep { !m/^\.\.?$/ } readdir $dir; closedir $dir; my %hash; for my $f (sort @files) { next if -l $f; if (-d $f) { push @{$hash{dir}}, $f; } elsif (-f $f) { push @{$hash{file}}, $f; } } return %hash; } sub foot { $cgi->end_html; } sub head { # do some checking my $bd_ok = 'ok'; my $l_ok = 'ok'; my $errors = ""; my $user = getpwuid($<); if (!-d $build_dir) { $errors .= qq#Your build_dir '$build_dir' does not exi +st. Please create it, with the correct permissions.<br>#; $bd_ok = 'not there'; } elsif (!-w $build_dir) { $errors .= qq#Your build_dir '$build_dir exists, but i +s not writeable for me (I am $user, uid $<).#; $bd_ok = 'not writeable'; } if (!-d $lib) { $errors .= qq#Your lib '$lib' does not exist. Please c +reate it, with the correct permissions.<br>#; $l_ok = 'not there'; } elsif (!-w $lib) { $errors .= qq#Your lib '$lib exists, but is not writea +ble for me (I am $user, uid $<).#; $l_ok = 'not writeable'; } my $err = $errors ? qq#<font color="red"><b>Errors:</b><br>$er +rors</font># : ""; my $st = $cgi->header; $st .= $cgi->start_html(-title => 'CGIPAN'); $st .= <<EOM; <h3 align="center">Welcome to Cgipan</h3> <b>Config:</b><br> <table border="1"> <tr><td>perl version:</td><td>$]</td></tr> <tr><td>\$root:</td><td>$root</td></tr> <tr><td>\$build_dir:</td><td>$build_dir ($bd_ok)</td></tr> <tr><td>\$lib:</td><td>$lib ($l_ok)</td></tr> <tr><td>document root:</td><td>$ENV{DOCUMENT_ROOT}</td></tr> </table> $err<br> <a href="$self">Start</a> | <a href="$self/tm">Test Module</a> <p> EOM } =pod =head1 NAME cgipan =head1 README CGI-Script for installing modules on a server where you don't have root access and no shell access. You have to have tools like make and tar, though. =head1 DESCRIPTION To use cgipan, put it in your cgi-bin directory on your server and make it executable. Then it will run. It will most likely show you the message that /homepages/bla/blubb/cgipan/build|lib don't exist. These are the directories you need for cgipan. Create them where you need them and change the variables $build_dir and $lib. They have to be writeable by the webserver, so if they aren't, cgipan will show te appropriate error messge. Note: Don't make this script accessible for others!! (yes, two exclamation marks) While this script shouldn't be public anyway, at the moment it does no sanity checks at all. Ok, I warned you. Now have fun =) =head1 OSNAMES C<Linux> =head1 PREREQUISITES CGI CGI::Carp tar or gnutar make =head1 LICENSE L<cgipan> may be distributed under the same terms as Perl itself. =head1 SCRIPT CATEGORIES CPAN CGI =head1 BUGS No sanity checks; not enough HTML-entities-replacing etc. =head1 AUTHOR Tina Mueller, Dec 30th 2004 ( =cut

In reply to Installing modules without root and shell by tinita

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?

What's my password?
Create A New User
Domain Nodelet?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (4)
As of 2023-12-09 18:26 GMT
Find Nodes?
    Voting Booth?
    What's your preferred 'use VERSION' for new CPAN modules in 2023?

    Results (38 votes). Check out past polls.