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

Hi People

There are two things that i would like to ask you about the code below:

1. Can it be improved, and if so, how?
2. Can someone show me how i can do some kind of error trapping on this? I want the script to 'unlink $to_delete' if there is a problem creating the user account and log the error to a file, or if there is a problem creating quota/opening-closing files just log the error.
#! /usr/bin/perl -w use strict; #################################### # Open Directory And Pick Up Files # #################################### my $path='/var/log/cr_user'; @ARGV=(); my @files=glob "$path/*"; while (@files) { my $to_delete=shift @files; push @ARGV,$to_delete; while (<>) { chomp; my ( $fullname, $username, $mothers, $email, $ip ) = split /,/; ############################### # Encrypt Password Using Salt # ############################### my @chars = ('a'..'z', 'A'..'Z', 0..9); my $password = do {{ local $_ = join "" => map {$chars [rand @chars]} 1..8; redo unless /[a-z]/ && /[A-Z]/ && /\d/; $_; }}; my $salt = '$1$' . join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z') [ map { int rand 64 } 0 .. 7 ]; my $epassword = crypt($password, $salt); ################################# # Create User Account And Quota # ################################# system ('/usr/sbin/useradd', '-g', 'users', '-d', "/home/$username", '-p', $epassword, '-s', '/bin/false', '-c', $fullname, $username); system ('/usr/sbin/edquota', '-p', "control", $username); ################################################ # Edit Postfix Virtual File And Write It Back. # ################################################ my $datafile = '/etc/postfix/virtual'; my @reg_addrs = ("$username\@domain1.com", "$username\@domain2.com"); open FH,"<",$datafile; my @virtual = <FH>; close FH; for my $reg_addr (@reg_addrs) { my ($name,$domain) = split /@/,$reg_addr; my ($i) = 0; for my $entry (@virtual) { ++$i; if ($entry =~ /\Q$domain\E/) { splice @virtual,$i,0,"$reg_addr\t$username\n"; last;}}} open FH,">",$datafile; print FH @virtual; close FH; system ('/usr/sbin/postmap', 'hash:/etc/postfix/virtual'); system ('/usr/sbin/postfix', 'reload'); ######################################## # Send E-Mails To Support And New User # ######################################## open (MAIL, "|/usr/sbin/sendmail -t"); print MAIL <<"END_OF_MAIL"; To: support\@foo.com Reply-to: $email From: $email Subject: foo Blah END_OF_MAIL close (MAIL); open (MAIL, "|/usr/sbin/sendmail -t"); print MAIL <<"END_OF_MAIL"; To: $email Reply-to: support\@foo.com From: support\@foo.com Subject: foo $fullname, You Suck END_OF_MAIL close (MAIL); } unlink $to_delete; }

Replies are listed 'Best First'.
Re: Error trapping, and improving code
by Zaxo (Archbishop) on Jul 05, 2003 at 16:19 UTC

    The system calls will return nonzero if they fail, so a construction like,     (my $res = system @args) and unlink $to_delete; will work. The return value is kept in $res in case you want to do something more about it.

    Update: Ok, here's a fancier version

    UFILE: while (@files) { #... system @args and do { unlink $to_delete; print LOG "'system @args' failed: ", $?; next UFILE; }; system @other_args and print LOG "'system @other_args' failed: ", $?; #... }

    After Compline,
    Zaxo

      sorry, i forgot to also add that if an error is found and the file is unlinked, that it shous return to the begining of the script and process the next file.
      Thanks Zaxo, where would i put that in my code?
      Also, the code i have seems to run regardless of whether there are any files in the directory or not. Is is trying to process '.' and '..'?