# *|* PERL *|*
#
# A Generic RPC interface (a bad example of perl code - right now)
#
# File: Gen.pm
#
# Author: Nem W Schlecht
# Last Modification: $Date$
#
# $Id$
# $Log$
#


package RPC::Gen;
require 5.002;

require 'rpc/pmap_prot.ph';
use Carp;
use Socket;
#use strict;

$VERSION = '.02';
$sockaddr = 'S n C4 x8';

sub new { bless {} }

sub init_sock { # sets up sockets, takes hostname [port]
    my($self)=shift;
    my($host)=shift;
    my($port);
    $port=shift;
    my($addrtype,$length,@addrs,$this,$that);
    ($self->{name},$self->{aliases},$port) =
	getservbyname('sunrpc','udp') if (!$port);

    $self->{'SOCK'}=$self . "_SOCKET";
    if (!$self->{bytes}) {
	if ($host =~ /^\d+\./) {
	    @{$self->{bytes}}=split(/\./,$host);
	} else {
	    ($self->{name},$self->{aliases},$addrtype,$length,@addrs) =
		gethostbyname($host);
	    croak "Can't lookup $host\n" unless $self->{name};
	    @{$self->{bytes}} = unpack("C4",$addrs[0]);
	}
    }
    my ($this) = pack($sockaddr,AF_INET,0,0,0,0,0);
    my ($that) = pack($sockaddr,AF_INET,$port,@{$self->{bytes}});
    socket($self->{'SOCK'},PF_INET,SOCK_DGRAM,17) || croak "socket: $!\n";
    bind($self->{'SOCK'},$this) || croak "bind: $!\n";
    connect($self->{'SOCK'},$that) || croak "connect: $!\n";
    select($self->{'SOCK'}); $| = 1;
    select(STDOUT); $| = 1;
}
	
#
# Contacts the portserver and gets the port of the requested service
sub get_port {	# takes socket and service nums - returns port of service
    my($self)=shift;
    my(@in)=@_;
    my($sock)=$self->{'SOCK'};
    my($xid)=int(rand(5000));
    print $sock pack("N13", $xid, 0, &PMAPVERS_PROTO, &PMAPPROG, &PMAPVERS,
	&PMAPPROC_GETPORT, 0, 0, 0, 0, @in);
    sysread($sock, $_, 32767);
    return (unpack("N" . length($_)/4, $_))[6];
}

#
# Contacts the service and gets the requested data (array)
sub get_info {	# takes service nums
    my($self)=shift;
    my(@in)=@_;
    my($sock)=$self->{'SOCK'};
    my($xid)=int(rand(5000));
    print $sock pack("N13", $xid, 0, &PMAPVERS_PROTO, @in);
    sysread($sock, $_, 32767);
    return (unpack("N" . length($_)/4, $_));
}

1;
