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 Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Developing class over net::ftp issue with multiple instation. 1

Status
Not open for further replies.

cdlvj

MIS
Nov 18, 2003
678
US
Have developed a class to wrap around net::ftp. Does the connection with retry logic, and allows alternate servers.

Works fine for 1 instance, but on 2nd instance, the $ftp variable is not null and has the 1st net::ftp object.

Do I have to keep track of each ftp object?
ie my $ftp in my class is visible to everywhere.
 
This is the code
Code:
use strict;
use Net::FTP;


package FB::myFTP;
my @servers = ( "151.1.152.11", "151.1.152.15");
my   $myftpuser;
my   $myftpcode;
my   $retries=20;
my   $ftp;
my   $connection;
my   $mode=1;        ## 1 is ascii 2 is binary
my   $ftplog="";

sub new
{
	my $self = {};
	bless($self);
	my $class = shift;

	return $self;
}

sub DESTROY
{
	my $self = shift;
	$self->logoff();
}

sub getAuthorization
{
my $self = shift;
my ($s) = @_;
my $ftpauth;
$ftpauth = FB::Authorize->new($s); 
if (! $ftpauth)
        {
            return undef;
        }
$myftpuser = $ftpauth->getUser();
$myftpcode = $ftpauth->getPasswd();
}

sub setFtpLog
{
#####################################################
# Purpose: Method to set ftp log class 
#####################################################
# Accept Parameters
#   
   my $self = shift;
   my ($r) = @_;
   $ftplog=$r;
   return "OK";
}

sub setRetries
{
#####################################################
# Purpose: Method to set retries 
#####################################################
# Accept Parameters
#   
   my $self = shift;
   my ($r) = @_;
   $retries=$r;
   return "OK";
}

sub setModeBinary
{
#####################################################
# Purpose: Method to set Mode Binary 
#####################################################
# Accept Parameters
#   
   my $self = shift;
   $mode=2;
   return "OK";
}

sub setModeAscii
{
#####################################################
# Purpose: Method to set Mode Ascii 
#####################################################
# Accept Parameters
#   
   my $self = shift;
   $mode=1;
   return "OK";
}

sub setServers
{
#####################################################
# Purpose: Method to set servers 
#####################################################
# Accept Parameters
#   
   my $self = shift;
   my (@r) = @_;
   @servers=@r;
   return "OK";
}

sub login
{
   my $self = shift;

   $self->getAuthorization($connection);
   $ftp->login($myftpuser,$myftpcode)|| return ("Error Logging On: $!");
   if ($mode == 1)
   {
   $ftp->ascii || return ("Error setting ascii mode: $!");
   }
   else
   {
   $ftp->binary || return ("Error setting binary mode: $!");
   }
   return "OK";
}


sub logoff
{
   my $rc;
   my $self = shift;
   if ($ftp)
   {
        $rc=$ftp->quit;
   }
   undef $ftp;
}

sub connect
{
   my $self = shift;
   my $tryAgain = 1;
   while($retries)
   {
	  foreach my $s (@servers)
	  {
          if ($ftp = Net::FTP->new($s))
	 	 {
	         $connection = $s;   ## save the server success connect
             	 return "OK";
          	} 
          }
          $retries--;
          sleep 120;                 
                    
   }
   return "Connection error to Server";
}

sub setDirectory
{
#####################################################
# Purpose: Method to set directory 
#####################################################
# Accept Parameters
#   
   my $self = shift;
   my ($dir) = @_;
   my $rc;

   if (!$ftp)
   {
	$rc=$self->connect();
	$rc=$self->login();
   }
   $ftp->cwd($dir)|| return("Failed to cd to $dir: $!");
   return "OK";
}

sub MakeDirectory
{
#####################################################
# Purpose: Method to make directory 
#####################################################
# Accept Parameters
#   
   my $self = shift;
   my ($dir) = @_;
   my $rc;

   if (!$ftp)
   {
	$rc=$self->connect();
	$rc=$self->login();
   }
   $ftp->mkdir($dir)|| return("Failed to make $dir: $!");
   return "OK";
}

sub readDirectory
{
#####################################################
# Purpose: Method to list directory 
#####################################################
# Accept Parameters
#   
   my $self = shift;
   my ($dir) = @_;
   my $rc;
   my @list;
   my $name;
   my @rlist;

   if (!$ftp)
   {
	$rc=$self->connect();
	$rc=$self->login();
   }
   if ($dir)
   {
   @list=$ftp->dir($dir)|| return("Failed to list directory: $!");
   }
   else
   {
   @list=$ftp->dir|| return("Failed to list directory: $!");
   }
   return @{$list[0]};
}

sub sendFile
{
#####################################################
# Purpose: Method to send the file 
#####################################################
# Accept Parameters
#   
   my $self = shift;
   my ($fi, $fo) = @_;
   my $rc;

   if (!$ftp)
   {
	$rc=$self->connect();
	$rc=$self->login();
   }
   if ($fo)
   {
   $ftp->put($fi, $fo)|| return("Failed to send $fi FTP: $!");
   }
   else
   {
   $ftp->put($fi)|| return("Failed to send $fi FTP: $!");
   }
   return "OK";
}

sub getFile
{
#####################################################
# Purpose: Method to get a file 
#####################################################
# Accept Parameters
#   
   my $self = shift;
   my ($fi, $fo) = @_;
   my $rc;

   if (!$ftp)
   {
	$rc=$self->connect();
	$rc=$self->login();
   }
   if ($fo)
   {
   $ftp->get($fi, $fo)|| return("Failed to get $fi FTP: $!");
   }
   else
   {
   $ftp->get($fi)|| return("Failed to get $fi FTP: $!");
   }
   return "OK";
}
return 1;
 
The problem is that you are declaring $ftp outside of your new() construct. Declaring a variable in a module outside of any subroutine makes it a module global, meaning that every instance of your module shares the same variable.

You'll need to make your FTP object be something within the object hashref $self, and make it object-specific.

i.e.

Code:
[url=http://perldoc.perl.org/functions/sub.html][black][b]sub[/b][/black][/url] [maroon]new[/maroon]
[red]{[/red]
    [url=http://perldoc.perl.org/functions/my.html][black][b]my[/b][/black][/url] [blue]$self[/blue] = [red]{[/red][red]}[/red][red];[/red]
    [url=http://perldoc.perl.org/functions/bless.html][black][b]bless[/b][/black][/url][red]([/red][blue]$self[/blue][red])[/red][red];[/red]
    [black][b]my[/b][/black] [blue]$class[/blue] = [url=http://perldoc.perl.org/functions/shift.html][black][b]shift[/b][/black][/url][red];[/red]

    [blue]$self[/blue]->[red]{[/red]ftp[red]}[/red] = [url=http://perldoc.perl.org/functions/undef.html][black][b]undef[/b][/black][/url][red];[/red] [gray][i]# make an FTP object here later[/i][/gray]

    [url=http://perldoc.perl.org/functions/return.html][black][b]return[/b][/black][/url] [blue]$self[/blue][red];[/red]
[red]}[/red]

In your connect() routine, change $ftp to $self->{ftp}:

Code:
[url=http://perldoc.perl.org/functions/sub.html][black][b]sub[/b][/black][/url] [maroon]connect[/maroon]
[red]{[/red]
   [url=http://perldoc.perl.org/functions/my.html][black][b]my[/b][/black][/url] [blue]$self[/blue] = [url=http://perldoc.perl.org/functions/shift.html][black][b]shift[/b][/black][/url][red];[/red]
   [black][b]my[/b][/black] [blue]$tryAgain[/blue] = [fuchsia]1[/fuchsia][red];[/red]
   [olive][b]while[/b][/olive][red]([/red][blue]$retries[/blue][red])[/red]
   [red]{[/red]
      [olive][b]foreach[/b][/olive] [black][b]my[/b][/black] [blue]$s[/blue] [red]([/red][blue]@servers[/blue][red])[/red]
      [red]{[/red]
          [olive][b]if[/b][/olive] [red]([/red][blue]$self[/blue]->[red]{[/red]ftp[red]}[/red] = Net::FTP->[maroon]new[/maroon][red]([/red][blue]$s[/blue][red])[/red][red])[/red]
          [red]{[/red]
             [blue]$connection[/blue] = [blue]$s[/blue][red];[/red]   [gray][i]## save the server success connect[/i][/gray]
                  [url=http://perldoc.perl.org/functions/return.html][black][b]return[/b][/black][/url] [red]"[/red][purple]OK[/purple][red]"[/red][red];[/red]
              [red]}[/red]
          [red]}[/red]
          [blue]$retries[/blue]--[red];[/red]
          [url=http://perldoc.perl.org/functions/sleep.html][black][b]sleep[/b][/black][/url] [fuchsia]120[/fuchsia][red];[/red]                 
                    
   [red]}[/red]
   [black][b]return[/b][/black] [red]"[/red][purple]Connection error to Server[/purple][red]"[/red][red];[/red]
[red]}[/red]

And everywhere in your code where you referenced $ftp, use $self->{ftp} instead.

In this way, every instance of your object has its very own $self, with its very own ftp object in $self->{ftp}

-------------
Cuvou.com | The NEW Kirsle.net
 
Looking back at your code again, you may need to follow suit with all these variables:

Code:
my @servers = ( "151.1.152.11", "151.1.152.15");
my   $myftpuser;
my   $myftpcode;
my   $retries=20;
my   $ftp;
my   $connection;
my   $mode=1;        ## 1 is ascii 2 is binary
my   $ftplog="";

make $self->{myftpuser}, $self->{connection}, $self->{mode}, etc.

For every variable that you don't want all your objects to share, move them under $self to make them object-specific and not global.

-------------
Cuvou.com | The NEW Kirsle.net
 
Got ya.
I just set up a structure with the elements, and pulled them in each method.
Many thanks.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top