Flame has asked for the wisdom of the Perl Monks concerning the following question:

Greetings Monks,

I've been working on a small suite of programs lately, and I've recently come to the conclusion that I need to write an installer for them. The reason: The vast majority of people using and installing the programs will be idiots unable to deal with simple things such as installing modules or configuring each script with the correct path to Perl (Or: Be subject of moronic administrators at their server and unable to do those things in a timely fassion).

On this subject, I've found a few things I wasn't sure about, so I decided to ask.

1) What's the fastest/most efficient (without wasting memory) way to check if a module is installed?

2) What happens when a program tries to use 'CPAN' but no one has configured it?

3) Is there any way to determine the path to sendmail? Or is there a common default path?

Thats all for now, thanks if you bothered to read the whole thing :)



"Weird things happen, get used to it."

Flame ~ Lead Programmer: GMS

Replies are listed 'Best First'.
Re: Installer Program
by rob_au (Abbot) on May 20, 2002 at 05:00 UTC
    Depending upon the directions which you take with development, this could be a bigger project than anticipated. If I were tackling this project my first task would be to develop a schema of installation steps, both prior to and following the copying of files, allowing for the searching for dependencies and execution of external script or configuration components - This schema to my mind would need to be modular in fashion so that installation behaviour can be defined by a series of definition or configuration files such that your installer script would offer you the greatest flexibility without having to go back and constantly modify/update it.

    On to your specific questions however ...

    1. What's the fastest/most efficient (without wasting memory) way to check if a module is installed?

      To my mind, the quickest would be to actually try and use the module - For example:

      eval { require $module; } if ($@) { # handling for when module fails to load }

      This approach to module and library handling is discussed in the perlfunc:require man page.

       

    2. What happens when a program tries to use 'CPAN' but noone has configured it?

      The init method from the module CPAN::FirstTime is invoked which attempts to configure the CPAN module by prompting the user for information and writing a CPAN::Config configuration file.

       

    3. Is there any way to determine the path to sendmail? Or is there a common default path?

      While the majority of sendmail installations use the target location of /usr/sbin/sendmail, this is not absolute and should not be relied upon. A better way would be to search for the sendmail binary within your script, making use of the File::Find module. However, for better cross-platform compatibility, it may be better still to prompt the user for the local network mail server and communicate directly via SMTP - The advantage which this has is that your script installation is not dependent upon a local sendmail installation for execution and offers greater flexibility to administrators who may wish to impose local mail security policies.

       

    Good luck! :-)

     

      Note that the File::Find method may not be overly secure if used in a simplistic way. People with any kind of write access can happily drop any program into their space and call it 'Sendmail', and if you're just relying on the filename (or even on it acting vaguely like Sendmail.. it's not overly tricky to do a basic impersonation to hide evilcode) then you're going to end up calling unknown and untrusted code.

      Even without this it's possible that you'd end up calling an old version kept around for compatibility reasons or so on.

      Possibly the best way to handle this, in my opinion, would be to ask the user installing the script which version of Sendmail to use and offering /usr/bin/sendmail as a default if it exists.

      Ok, time to expand on my problem then, this installer is run from the web. (Most of the people running it won't have TelNet acess) So how do I get CPAN to work if it hasn't been set up?



      "Weird things happen, get used to it."

      Flame ~ Lead Programmer: GMS

Re: Installer Program
by mugwumpjism (Hermit) on May 20, 2002 at 10:46 UTC
    1. Try scanning @INC looking for the .pm files. Or you could fork(), (so the memory used by the module isn't left around afterwards) then require the module
    2. It prompts the user for configuration :-). Ideally the CPAN module should auto-configure CPAN mirror selection with <cite>netselect(8)</cite>
    3. it is usually linked in /usr/lib/sendmail or /usr/sbin/sendmail, otherwise look for it in $ENV{PATH}. If you can install Net::SMTP then you can alter the nature of this configuration problem, as others have mentioned.

    Try the install of RT for one approach to the problem. It basically has a step-by-step guide, and a script that tests the configuration and provides appropriate configuration advice.

Re: Installer Program
by Starky (Chaplain) on May 21, 2002 at 04:34 UTC
    Another easy way to find sendmail without recursively searching directories etc. is
    $path = `which sendmail`;
    # Perhaps check the return value here
    chomp $path;
    
    This is assuming that you are dealing in a *nixy environment.

    And as far as installing an application, well, again, if you're in a *nixy environment, there is no better installer for Perl stuff than the CPAN module.

    If you put something like

    WriteMakefile(
        # . . . blah blah blah . . .
        'PREREQ_PM' => {
          # your dependencies go here ... the CPAN
          # module will add them to the build list
                },
        'PM' => {
          'bin/myscript' => '$(INST_SCRIPT)/myscript.pl'
                },
        # . . . blah blah blah . . .
    );
    
    in your Makefile.PL, the script will generally be placed in /usr/bin. Installing with the CPAN module would also obviate your need to check dependencies and make updating a breeze. And you can do all sorts of other wacky things from Makefile.PL, such as prompting the user for input and building a configuration file.

    I'm not an expert on the CPAN module, so I don't know how exactly you'd tell it to install such-and-such a tarball in such-and-such a directory (i.e., bypassing the 'get' step and eliminating the need to have people put the tarball in, for example, /root/.cpan/build).

    So, as you can see, there would be some things to think about. Just throwin' the idea out there ...

    Hope this helps :-)