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

Okay - here's the situation. I'm a TOTAL perl Newbie. In fact, I'm what my old Gunny used to call a NUB - that's a Non Useful Body to you civilian types.

I run http://www.lrsehosting.com, a small slash and scoop hosting business. I'd like to play a more active role in the business (other than just book keeping and sales, basically) and help the admins out (and myself) and be more productive, so I have to learn perl. What a better way to do that then to write something I need written?

I know what I want to do - I need a script that will add users to Password.pm for me, and I'd like to try and write that script. With the help of a friend, I've managed to figure out how to make the script always fine the correct file, and set it as $filepath. At that point, I'm completely lost. The way the module currently works, you setup one or more virtual users at install, and you then have to find and hand edit the file thereafter. That sucks. Hard. So, the following is what I have to date, and from here I'd like some idea(s) on how to make it (a) check to see if the user you want to add already exists, (b) add that user if not and (c) remove a user with a command like argument (like -delete foo):

#!/bin/perl # # addvirtu.pl by William Scott Lockwood III and Peter Johnson # use DBIx::Password; my $filepath = $INC{"DBIx/Password.pm"};
  • Comment on How do I write what I need, given that I know nothing at all about perl.
  • Download Code

Replies are listed 'Best First'.
Re: How do I write what I need, given that I know nothing at all about perl.
by atcroft (Abbot) on Jan 02, 2003 at 08:25 UTC

    First of all, welcome to perl. Come in, make yourself to home, and hope you enjoy your stay.

    As an initial recommendation, from what you mention, I would suggest Learning Perl (AKA the Llama book), Programming Perl (AKA the Camel book), then Perl Cookbook. The first of these will help you in getting used to Perl, the second gives you a deeper technical understanding of it (and serve as a good reference), and the latter gives a number of examples of solving relatively common problems in Perl. Some people will go to the second and go back to the first later, especially if they have some previous programming experience, but in general those three would be a good starting point.

    In addition, you may also wish to refer to the Tutorials section of this site, as well as posting here and reading the posts of others.

      Thank you! I actually have two of those books - I need the cookbook. I'm reading them though understanding is a challenge. :-) I have already found some really useful stuff in the Tutorials section - thank you! I will keep reading!
Re: How do I write what I need, given that I know nothing at all about perl.
by tachyon (Chancellor) on Jan 02, 2003 at 10:00 UTC

    This module pissed me off with its totally shite interface so I have added the necessary stuff and will submit it to the author so he can add it. No documentation but should be pretty self explanatory if you follow the synopsis example.

    Please note that I would not use the DBIx::Password module in a pink fit as it is a very insecure way of saving passwords - this code demonstrates just how easy it is to extract the data-structure. In this case it is for (perhaps) a worthwhile purpose although adding functionality to the module seems like a bad idea in retrospect.

    use strict; use warnings; use Data::Dumper; my $d = new DBIx::Password::Modify; # have a look at the object we created print Dumper $d; # use the methods $d->add_user( 'new user', { 'database' => 'databasename', 'port' => 'port', 'host' => 'host_name', 'password' => 'password', 'driver' => 'mysql', 'username' => 'username', 'attributes'=> { 'extra_attrib' => 'attrib_value' }, 'connect' => 'DBI:mysql:database=databasename;host=m +achine_name;port=port' } ); $d->delete_user('new user'); $d->set_attribute( 'user', 'password', 'new_pass' ); my $password = $d->get_attribute( 'user', 'password' ); $d->write_data(); ### ### DBIx::Password::Modify ### A quick hack to fix the issues with DBIx::Password ### package DBIx::Password::Modify; sub new { my $class = shift; my $location = find_dbix_password(); die "Can't find DBIx::Password.pm" unless $location; my %parse = _parse_password_pm($location); return bless { location => $location, %parse }, $class; } sub find_dbix_password { for my $dir ( @INC ) { return "$dir/DBIx/Password.pm" if -e "$dir/DBIx/Password.pm"; } return 0; } sub _parse_password_pm { my $location = shift; open FILE, $location or die "Can't open $location, perl says $!\n" +; undef $/; my $file = <FILE>; close FILE; $file =~ s/my\s*\$virtual1\s*=(.*?)(my %driver_cache)/<VIRTUAL1>\n +\n$2/s; my $virtual1 = $1; return 'file' => $file, 'config' => eval $virtual1; } sub write_data { my $self = shift; #Now, lets build up our data structure require Data::Dumper; my $data = Data::Dumper->new( [$self->{config}] ); $data->Purity(1); $data->Indent(3); $data->Varname('virtual'); my $dump = $data->Dump(); my $text = $self->{file}; $text =~ s/<VIRTUAL1>/my $dump/; open FILE, ">$self->{location}" or die "Can't write $self->{locati +on}, perl says $!\n"; print FILE $text; close FILE; } sub add_user { my ( $self, $user, $hash_ref ) = @_; $self->{config}->{$user} = $hash_ref; } sub delete_user { my ( $self, $user ) = @_; if ( exists $self->{config}->{$user} ) { delete $self->{config}->{$user}; return 1; } else { $self->error("$user does not exist\n"); return 0; } } sub get_attribute { my ( $self, $user, $attribute ) = @_; if ( exists $self->{config}->{$user}->{$attribute} ) { return $self->{config}->{$user}->{$attribute} } else { $self->error("$attribute does not exist for $user\n"); return 0; } } sub set_attribute { my ( $self, $user, $attribute, $value ) = @_; $self->{config}->{$user}->{$attribute} = $value; } sub error { my ( $self, $error ) = @_; $self->{error} .= $error if $error; return $self->{error}; } 1;

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: How do I write what I need, given that I know nothing at all about perl.
by tachyon (Chancellor) on Jan 02, 2003 at 09:55 UTC

    You would be hard pressed to pick a more difficult task upon which to cut your teeth. The DBIx::Password module is in a word poorly designed. Essentially there is a configuration script within the Makefile.PL that you run on installation that takes some user input and then uses Data::Dumper to dump the configuration back into DBIx::Password.pm. Personally I think it is a horrible way to do it. Anyway all the configuration is in a variable called $virtual1 within the Password.pm module

    my $virtual1 = { 'user' => { 'driver' => 'mysql', 'username' => 'username', 'attributes' => { 'extra_attrib' => 'attrib_ +value' }, 'port' => 'port', 'database' => 'databasename', 'password' => 'password', 'host' => 'machine_name', 'connect' => 'DBI:mysql:database=databasenam +e;host=machine_name;port=port' } };

    There are no methods provided to modify this data structure after the fact so you will have to open the Password.pm file. Extract the data-structure and probably eval it into a variable. Modify the data structure. Dump it back out aka the original.

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: How do I write what I need, given that I know nothing at all about perl.
by Vladinator (Novice) on Jan 02, 2003 at 08:18 UTC
    Okay, having read some of what's available in the tutorial section on this site, the code now looks like this:

    #!/bin/perl -w # # addvirtu.pl by William Scott Lockwood III and Peter Johnson # use strict; use warnings; use diagnostics; use DBIx::Password; my $filepath = $INC{"DBIx/Password.pm"};
Re: How do I write what I need, given that I know nothing at all about perl.
by Aragorn (Curate) on Jan 02, 2003 at 09:41 UTC
    In my opionion, the design of the DBIx::Password module is brain-damaged. Maybe I'm missing something, but it would be much easier to have the user information in a separate file with a standard layout, so you can easily scan the file for double usernames, etc, etc. Maybe it's done for performance or some other reason.

    The problem you have now is that you have to scan through the Password.pm source code, and add code at the correct lines. Or thinking along another line, you could also automate the interaction with the Makefile.PL script which then inserts the information (possibly from a file you maintain), and let Makefile.PL do the hard work of generating the module with the desired user information.

    --
    All that is gold does not glitter...

Re: How do I write what I need, given that I know nothing at all about perl.
by theorbtwo (Prior) on Jan 02, 2003 at 09:53 UTC

    If you want to use a specific version of a module, IIRC use will take a filename as well as a modulename. Whoops, after checking, use won't allow a filename, but require will. So if you want, you can say somthing like require '/home/you/perllocal/site/DBIx/Password.pm';, and be assured that you're picking up the right version. (BTW, use and require have other differneces too. If you're using an OOish convention for DBIx::Password (that is, all functions you use in DBIx::Password are either fully named (IE include "DBIx::Password" in them) or use an object that was already created using a fully-named call) then it won't matter. If you aren't, you need to wrap the require inside a BEGIN {...} block (for reasons I don't feel like explaining, it needs to happen earlier then it would with normal code, at the BEGINing of your program's lifetime, just after the line is compiled. use does this for you, behind the seans. The POD (Plain Old Documentation) for DBIx::Password uses a style that would be OK, so you probably don't need the BEGIN block. (BTW, I'm not yelling, BEGIN has to be written in all-caps.)


    Warning: Unless otherwise stated, code is untested. Do not use without understanding. Code is posted in the hopes it is useful, but without warranty. All copyrights are relinquished into the public domain unless otherwise stated. I am not an angel. I am capable of error, and err on a fairly regular basis. If I made a mistake, please let me know (such as by replying to this node).

Re: How do I write what I need, given that I know nothing at all about perl.
by Popcorn Dave (Abbot) on Jan 03, 2003 at 04:12 UTC
    The one thing everyone seems to forget for those that are learning Perl is to take a class!

    There are a lot of community colleges that have computer science programs and they usually run about $15 a class. Not only is the price right, but you're learning from someone who is (hopefully) proficient in their craft and will lead you in the right direction.

    That said, I would also reccommend the Perl Black Book by Holzner. It's a nice reference, and since the publisher is out of business, it can be found on half.com for about $7-8 nowdays.

    Good luck!

    There is no emoticon for what I'm feeling now.

Re: How do I write what I need, given that I know nothing at all about perl.
by Vladinator (Novice) on Jan 05, 2003 at 06:39 UTC
    I just wanted to say thanks to everyone for all the great advice and help. I have decided that I will take a class to do this, and I now understand why no one has done it yet. :-)
A reply falls below the community's threshold of quality. You may see it by logging in.