CDDB

 view release on metacpan or  search on metacpan

lib/CDDB.pm  view on Meta::CPAN

}

#------------------------------------------------------------------------------
# Disconnect from a cddbp server.  This is needed sometimes when a
# server decides a session has performed enough requests.

sub disconnect {
	my $self = shift;
	if ($self->{handle}) {
		$self->command('quit');     # quit
		$self->response();          # wait for any response
		delete $self->{handle};     # close the socket
	}
	else {
		$self->debug_print( 0, '--- disconnect on unconnected handle' );
	}
}

#------------------------------------------------------------------------------
# Connect to a cddbp server.  Connecting and disconnecting are done
# transparently and are performed on the basis of need.  Furthermore,
# this routine will cycle through servers until one connects or it has
# exhausted all its possibilities.  Returns true if successful, or
# false if failed.

sub connect {
	my $self = shift;
	my $cddbp_host;

	# Try to get our hostname yet again, in case it failed during the
	# constructor call.
	unless (defined $self->{hostname}) {
		$self->{hostname} = &hostname() or croak "can't get hostname: $!";
	}

	# The handshake loop tries to complete an entire connection
	# negociation.  It loops until success, or until HOST returns
	# because all the hosts have failed us.

	HANDSHAKE: while ('true') {

		# Loop through the CDDB protocol hosts list up to twice in order
		# to find a server that will respond.  This implements a 2x retry.

		HOST: for (1..(@cddbp_hosts * 2)) {

			# Hard disconnect here to prevent recursion.
			delete $self->{handle};

			($self->{host}, $self->{port}) = @{$cddbp_hosts[$cddbp_host_selector]};

			# Assign the host we selected, and attempt a connection.
			$self->debug_print(
				0,
				"=== connecting to $self->{host} port $self->{port}"
			);
			$self->{handle} = new IO::Socket::INET(
				PeerAddr => $self->{host},
				PeerPort => $self->{port},
				Proto    => 'tcp',
				Timeout  => 30,
			);

			# The host did not answer.  Clean up after the failed attempt
			# and cycle to the next host.
			unless (defined $self->{handle}) {
				$self->debug_print(
					0,
					"--- error connecting to $self->{host} port $self->{port}: $!"
				);

				delete $self->{handle};
				$self->{host} = $self->{port} = '';

				# Try the next host in the list.  Wrap if necessary.
				$cddbp_host_selector = 0 if ++$cddbp_host_selector > @cddbp_hosts;

				next HOST;
			}

			# The host accepted our connection.  We'll push it back on the
			# list of known cddbp hosts so it can be tried later.  And we're
			# done with the host list cycle for now.
			$self->debug_print(
				0,
				"+++ successfully connected to $self->{host} port $self->{port}"
			);

			last HOST;
		}

		# Tried the whole list twice without success?  Time to give up.
		unless (defined $self->{handle}) {
			$self->debug_print( 0, "--- all cddbp servers failed to answer" );
			warn "No cddb protocol servers answer.  Is your network OK?\n"
				unless $self->{debug};
			return;
		}

		# Turn off buffering on the socket handle.
		select((select($self->{handle}), $|=1)[0]);

		# Get the server's banner message.  Try reconnecting if it's bad.
		my $code = $self->response();
		if ($code != 2) {
			$self->debug_print(
				0, "--- bad cddbp response: ",
				$self->code(), ' ', $self->text()
			);
			next HANDSHAKE;
		}

		# Say hello, and wait for a response.
		$self->command(
			'cddb hello',
			 $self->{login}, $self->{hostname},
			 $self->{libname}, $self->{libver}
		);
		$code = $self->response();
		if ($code == 4) {
			$self->debug_print(



( run in 2.162 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )