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

With great effort I'm pulling myself out from behind a pile of O'Riellys and climbing the mountain the seek guidance.
Using ActivePerl (5.8) I get the following errors:
syntax error at D:\plscipts\fwimport.pl line 44, near "sub nameimport +" Global symbol "@name" requires explicit package name at D:\plscipts\fw +import.pl line 47. Execution of D:\plscipts\fwimport.pl aborted due to compilation errors +.
For the following script:
#!/bin/perl -W # This script is for the importing of Pix firewall configs. # This script requires Acitve Perl with the DBI module # and DBD module for ODBC. Also a user DSN needs to be made for # the FWexcept database to be used named FW. # # This script is for internal use, it has not been built to # production standards. There are no input or performance # sanity checks. # # For the sake of my sanity I'm continuing to use my naming standard # for DBI functions. For database handles the convention is "(name)db" # where (name) is the database name. For all SQL commands the # convention is "name""table""SQL command type", where the table is # the table/s names and "SQL command type" is qry, ins, upd, or del. use strict; use DBI; # get the firewall config, submited as an argument # the config will be passed to the script as the array @config if (/$ARGV[0]/) { open (CONFIG,"$ARGV[0]") || die "Could not open $ARGV[0]\n"; my @config = <CONFIG>; close (CONFIG); } # connect to the DSN on the local system database handles end in db my $FWdb = DBI->connect('DBI:ODBC:FW'); # Build insert statement for the exception table my $FWexceptioninst = $FWdb->prepare(q(INSERT INTO Exception(access-li +st,acl-name,firewallID,Interface,server,Active) VALUES (?,?,?,?,?,Yes +))); # Build insert statement for the firewall table my $FWfirewallinst = $FWdb->prepare(q(INSERT INTO firewalls(FW-Name,Ty +pe,SW-revision,ContactID-PriWAN,ContactID-SecWAN,ContactID-ISSO) VALU +ES (?,PIX,?,2,3,1))); # Build query of the FirewalID assigned by the database my $FWfirewallqry = $FWdb->prepare(q(SELECT FirewallID FROM firewalls +WHERE FW-name = ?)) # The routine imports basic information about the firewall into the fi +realls table. # It assumes that the firewall is administratied by Foo and Bar by th +e WAN team, # and Baz in the ISSO. It returns the hostname of the firewall and the + FirewallID. sub nameimport { foreach (@_) { if (/hostname/) { local @name = split(/ /); } elsif (/version/) { local @version = split(/ /); }; }; $FWfirewallsinst->execute($name[1],$version[2]); $FWdb->commit; $FWfirewallsqry->execute($name[1]); @FWfirewallsinfo = $FWfirewallsqry->fetchrow_array; # print "$FWfirewallsinfo[0]\n"; return ($FWfirewallsinfo[0],$name[1]); } # The routine imports the acls into the Exception table. # It requires the $FWID global var is set to the FirewallID in the dat +abase. # The local var $aclimport keeps track of the number of successfully i +mported rules. # It assumes that all rules imported are active. Output is the number +of rules imported. sub acl { local $aclimport = 0; local $part = ""; foreach (@_) { if (/access-list/) { local @acl = split(/ /); foreach $part (@acl) { if ($part =~ /192\.35\.84\./) {local $server = $part}; }; local $interface = $acl[1] =~ s/acl-//; local @importinfo = (q($_,$acl[1],$FWID,$interface,$server +)); $FWexecptionins->execute(@importinfo) && $aclimport++; }; }; return scalar($aclimport); }; # If the firewall name has been supplied then get the FirewallID other +wise assume new config if (/$ARGV[1]/) { $FWfirewallsqry->execute($ARGV[1]); @FWfirewallsinfo = $FWfirewallsqry->fetchrow_array; my $FWID = $FWfirewallsinfo[0]; my $FWname = $ARGV[1]; } else { my ($FWID,$FWname) = nameimport(@config); }; my $aclimport = acl(@config); print "The script has successfully imported $aclimport rules for $FWna +me.\n";
I can't figure out what's wrong with my sub or my local declarations, can somebody shed some illumination on a poor novice?

Vec

Replies are listed 'Best First'.
Re: What's wrong with my syntax?
by Improv (Pilgrim) on Apr 10, 2003 at 16:21 UTC
    For the first problem, you're missing a semicolon in the last statement above it.
    my $FWfirewallqry = $FWdb->prepare(q(SELECT FirewallID FROM firewalls +WHERE FW-name = ?))


    For the second, you might want to look into using 'my' instead. See this.
Re: What's wrong with my syntax?
by omnibus (Scribe) on Apr 10, 2003 at 16:30 UTC

    A couple things spring to mind

    1. It looks like you're using local when you mean to be using my.
    2. You are declaring @name as local within the for block - so when you exit the for block it goes away. What you need to do is declare it outside the for block so that it's available throughout your entire sub. See below:
    sub nameimport { my (@name, @version); foreach (@_) { if (/hostname/) { @name = split(/ /); } elsif (/version/) { @version = split(/ /); }; }; #blah, blah, blah, do stuff... }
Re: What's wrong with my syntax?
by bbfu (Curate) on Apr 10, 2003 at 16:34 UTC

    Just to expand on what Improv mentioned at the end of his post... Pretty much everywhere you use local in your code, you should be using my instead.

    For information on the differences between my and local, see the FAQ, or this excellent article from The Perl Journal called Coping With Scoping. There are also various nodes on PM talking about it; just search for "my local".

    The specific reason why the local's are giving you an error is because they work on global variables, not lexicals. Since you're using strict (good job!) and haven't previously declared those variables as global, you get an error. But really, since you don't use the variables anywhere outside the sub you're localing them in, there's no reason for them to be globals. Hence, you should use my instead. :)

    Update: Added some clarification.

    bbfu
    Black flowers blossom
    Fearless on my breath

Re: What's wrong with my syntax?
by rir (Vicar) on Apr 10, 2003 at 16:29 UTC
    You might try:
    use diagnostics;
    for more verbosity in Perl's messages.
Re: What's wrong with my syntax?
by vek (Prior) on Apr 10, 2003 at 19:25 UTC
Re: What's wrong with my syntax?
by jasonk (Parson) on Apr 10, 2003 at 16:21 UTC

    This line is missing a semicolon:

    my $FWfirewallqry = $FWdb->prepare(q(SELECT FirewallID FROM firewalls +WHERE FW-name = ?))

    We're not surrounded, we're in a target-rich environment!
Re: What's wrong with my syntax?
by zby (Vicar) on Apr 10, 2003 at 16:32 UTC
    As was allready pointed out change local to my. But you need to take the declaration out of the foreach block too. Like that:
    my @name; my @vhost; foreach (@_){