Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Trouble with libnet module 2

Status
Not open for further replies.

kleinicus

MIS
Dec 4, 2002
98
US
Hello. I have precisely zero Perl experience. I was told to follow a set of instructions to make a Bugzilla server work with Windows. It was working until I made the changes necessary for Bugzilla to send e-mail. Normally, it would run on Linux where Sendmail would take care of the MTA stuff. But, all I have is an SMTP server on the same box as Bugzilla.
Anyway, the original file had the following lines...

--------------------------------
open(SENDMAIL, "|/usr/lib/sendmail $sendmailparam -t -i") ||
die "Can't open sendmail";
print SENDMAIL trim($msg) . "\n";
close SENDMAIL;
--------------------------------

The instructions for installing on Windows say to change this section to use Perl's libnet, specifically, the SMTP portion. The replacement code provided looks like this...

--------------------------------
use Net::SMTP;
my $smtp_server = 'server.domain.com';
my $smtp = Net::SMTP->new($smtp_server) ||
die 'Cannot connect to server \'$smtp_server\";
$smtp->mail('admin@domain.com');
$smtp->to($person);
$smtp->data();
$smtp->datasend($msg);
$smtp->dataend();
$smtp->quit;
--------------------------------

Obviously, I have changed the above lines to use our SMTP server's FQDN and to use a valid e-mail address on that server, but I didn't want everyone and their mother knowing the name of our mail server. :)
This is supposed to make Perl use SMTP instead of Sendmail. After making the changes, I'm supposed to run a checksetup.pl file from the command line to make sure everything's ready to rock. It spits out this error...

--------------------------------
Bareword found where operator expected at Bugzilla/BugMail.pm line 877, near "$smtp->mail('admin"
(Might be a runaway multi-line '' string starting on line 875)
(Missing operator before admin?)
Array found where operator expected at Bugzilla/BugMail.pm line 877, at end of line
Bad name after com' at Bugzilla/BugMail.pm line 877.
Compilation failed in require at globals.pl line 36.
BEGIN failed--compilation aborted at globals.pl line 36.
Compilation failed in require at D:\bugzillafiles\checksetup.pl line 1422.
--------------------------------

I don't know how to debug Perl commands. If someone could help me, I would appreciate it.
Thanks.
 
Try changing this
Code:
  die 'Cannot connect to server \'$smtp_server\";
to this
Code:
  die [b]qq([/b]Cannot connect to server [b]"[/b]$smtp_server[b]")[/b];
The original has unbalanced quotes, which I think accounts for the later errors.



 
Well, I still got an error, but it was a different one this time. The code looks like this now...

-----------------------------
use Net::SMTP;
my $smtp_server = 'server.domain.com';
my $smtp = Net::SMTP->new($smtp_server) ||
die qq(Cannot connect to server "$smtp_server");
$smtp->mail('admin@domain.com');
$smtp->to($person);
$smtp->data();
$smtp->datasend($msg);
$smtp->dataend();
$smtp->quit;
-----------------------------

And the error message looks like this...

-----------------------------
Global symbol "$person" requires explicit package name at Bugzilla/BugMail.pm line 878.
Compilation failed in require at globals.pl line 36.
BEGIN failed--compilation aborted at globals.pl line 36.
Compilation failed in require at D:\bugzillafiles\checksetup.pl line 1422.
-----------------------------

Person is mentioned lots of other times in the same program, and I would imagine elsewhere too.

Again, thanks for your help. By the way, how do you make certain parts of the post appear in a "Code" section?
 
Global symbol "$person" requires explicit package name at Bugzilla/BugMail.pm line 878.
This is telling you that the variable $person is not declared with my before it's used. (See the way $smtp_server and $smtp are declared?)
Code:
my $smtp_server = 'server.domain.com';
my $smtp = Net::SMTP->new($smtp_server)
If you have use strict in your module, all variables must be declared this way. (That's a good thing. Don't turn off strict.) Find the first mention of $person and stick my in front of it.

Re: how to get code to appear in a CODE section (and much more besides) click on Process TGML under the box where you type your posts.

 
$person needs to be packaged with "my":

my $person

but where to "package" it is not possible to say. If $person is used often in the script then I assume the above code is running in a sub rotuine of some sort, so you need to send $person to the sub routine when the sub is called, this is often done like this:

sendmail($person)

where sendmail is the name of the sub routine, then in the sub you import the data:

Code:
sub sendmail {
  my $person = shift;#gets the data out of the system array
  .....
}

but your script might be coded differently
 
I found the first instance of $person. It's pasted below.

Code:
    foreach my $person (@emailList) {
        # don't modify the original so it sends out with the right case
        # based on who came first.
        $checkperson = lc($person);
        if ( !($AlreadySeen{$checkperson}) ) {
            push(@allEmail,$person);
            $AlreadySeen{$checkperson}++;
        }

Is the syntax wrong here somewhere?
 
kleinicus, in the code you posted
Code:
    foreach my $person (@emailList) {
the scope of the variable $person is the foreach loop, since $person is declared at the beginning of the loop. The syntax is correct, but $person is not known outside the foreach. If you need it outside the foreach, it must be declared outside. If you need to declare it without initializing it, you can just say my $person;



 
It looks like this reference to $person is only within the scope of this subroutine...

Code:
sub MessageToMTA ($) {
   my ($msg) = (@_);

    my $sendmailparam = "";
    unless (Param("sendmailnow")) {
       $sendmailparam = "-ODeliveryMode=deferred";
    }

    if ($enableSendMail == 1) {
        use Net::SMTP;
	my $smtp_server = 'sgibugzilla.sgi-net.com';
	# Use die on error, so that the mail will be in the 'unsent mails' and
	# can be sent from the sanity check page.
	my $smtp = Net::SMTP->new($smtp_server) ||
	  die qq(Cannot connect to server "$smtp_server");

	$smtp->mail('sklein@sgi-net.com');
	$smtp->to($person);
	$smtp->data();
	$smtp->datasend($msg);
	$smtp->dataend();
	$smtp->quit;
    }
}

I'm not sure how to go about creating a new instance of it for this subroutine. I don't have any idea what data type is supposed to be in the object, or even which subroutine is sending the information.

::drowns in Perl::
 
you will need to find where your script is calling the sub:

MessageToMTA

there you will also need to pass in $person if possible.

MessageToMTA looks like a prototype since it has the () after the sub routine name: MessageToMTA($)

I think you can still pass in more than one variable to a prototype but my knowledge of perl prototypes is pretty much zero. Many perl gurus say to not use them since they are never really needed and just cause confusion. But I do not have enough experience to know how vaild that claim is.

 
The ($) after the sub name means it takes 1 scalar argument, $msg.

You can modify MessageToMTA to take 2 scalar args by changing it as below.
Code:
sub MessageToMTA ([b]$$[/b]) {
   my ($msg, [b]$person[/b]) = @_;
...
As KevinADC says, find where this sub is being called from and pass in $person along with $msg. Of course $person will still have to be declared (and hopefully initialized) before the sub call.

(I haven't found prototypes to be of much use, myself.)


 
Another change, another error. :)

I noticed that $person is created before the procedure call...

Code:
my $person .= Param('emailsuffix');

I changed the MessageToMTA procedure call so that it passes $person along with $msg, and changed MessageToMTA along with it, like so...

Code:
    my $msg = PerformSubsts($template, \%substs);

    MessageToMTA($msg, $person);

    push(@sentlist, $person);
    return 1;
}

sub MessageToMTA ($$) {
   my ($msg, $person) = (@_);

    my $sendmailparam = "";
    unless (Param("sendmailnow")) {
       $sendmailparam = "-ODeliveryMode=deferred";
    }

    if ($enableSendMail == 1) {
        use Net::SMTP;
	my $smtp_server = mailserver.domain.com';
	my $smtp = Net::SMTP->new($smtp_server) ||
	  die qq(Cannot connect to server "$smtp_server");

And then I received this error when running the checksetup.pl file.

"my" variable $person masks earlier declaration in same scope at Bugzilla/BugMail.pm line 829.
Not enough arguments for Bugzilla::BugMail::MessageToMTA at Bugzilla/Token.pm line 95, near "$message)"
Not enough arguments for Bugzilla::BugMail::MessageToMTA at Bugzilla/Token.pm line 104, near "$message)"
Not enough arguments for Bugzilla::BugMail::MessageToMTA at Bugzilla/Token.pm line 156, near "$message)"
Not enough arguments for Bugzilla::BugMail::MessageToMTA at Bugzilla/Token.pm line 232, near "$message)"
Compilation failed in require at globals.pl line 358.
BEGIN failed--compilation aborted at globals.pl line 358.
Compilation failed in require at D:\bugzillafiles\checksetup.pl line 1422.

Ideas?
 
with the code you posted its not possible to say where $person is masking an earlier declaration. If $person is initialized here:

my ($msg, $person) = (@_);

you don't need to use "my $person" again within the same scope.

I don't know why you are getting the other error messages.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top