File Coverage

blib/lib/COPE/Announcer.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             # $Id: Announcer.pm,v 1.3 1997/07/25 10:12:41 schuller Exp $
2             # Copyright (c) 1997 Lunatech Research / Bart Schuller
3             # See the file "Artistic" in the distribution for licensing and
4             # (lack of) warranties.
5              
6             package COPE::Announcer;
7              
8 1     1   2359 use strict;
  1         3  
  1         38  
9 1     1   1047 use IO::Handle;
  1         8018  
  1         42  
10 1     1   821 use Socket;
  1         4067  
  1         632  
11 1     1   702 use COPE::CORBA::ORB;
  0            
  0            
12              
13             # Subs
14              
15             sub announce ($$) {
16             my($name, $value) = @_;
17             my($msg,$index) = ('ADD ', 4);
18             CORBA::ORB::_marshal_string(\$msg, \$index, 0, $name);
19             CORBA::ORB::_marshal_string(\$msg, \$index, 0, $value);
20             my $broadcaster = new COPE::Announcer;
21             $broadcaster->shout();
22             return $broadcaster->send_and_get_message($msg);
23             }
24              
25             sub resolve ($) {
26             my($name) = @_;
27             my($msg,$index) = ('GET ', 4);
28             CORBA::ORB::_marshal_string(\$msg, \$index, 0, $name);
29             my $broadcaster = new COPE::Announcer;
30             $broadcaster->shout();
31             $msg = $broadcaster->send_and_get_message($msg);
32             return undef if !defined $msg;
33             $index = 0;
34             my $value = CORBA::ORB::_unmarshal_string(\$msg,\$index,0);
35             return $value;
36             }
37              
38             sub daemon () {
39             my %db;
40             my $listener = new COPE::Announcer;
41             $listener->listen();
42             while (1) {
43             my $msg = $listener->get_message(undef);
44             next if !$msg;
45             my $cmd = substr($msg, 0, 4);
46             my $index = 4;
47             if ($cmd eq 'ADD ') {
48             my $name = CORBA::ORB::_unmarshal_string(\$msg,\$index,0);
49             my $value = CORBA::ORB::_unmarshal_string(\$msg,\$index,0);
50             $db{$name} = $value;
51             $listener->send_message('ADDED');
52             next;
53             }
54             if ($cmd eq 'GET ') {
55             my $name = CORBA::ORB::_unmarshal_string(\$msg,\$index,0);
56             $msg = ''; $index = 0;
57             CORBA::ORB::_marshal_string(\$msg,\$index,0,$db{$name});
58             $listener->send_message($msg);
59             next;
60             }
61             }
62             }
63              
64             # Class methods
65              
66             sub new {
67             my($class) = @_;
68             my $self = { sock => new IO::Handle };
69             socket($self->{sock}, PF_INET, SOCK_DGRAM, getprotobyname('udp')) || die "socket: $!";
70             return bless $self, $class;
71             }
72              
73             # Object methods
74              
75             sub listen {
76             my($self) = @_;
77             bind($self->{sock}, scalar sockaddr_in(3228, INADDR_ANY)) || die "bind: $!";
78             }
79              
80             sub shout {
81             my($self) = @_;
82             $self->{peer} = sockaddr_in(3228, INADDR_BROADCAST);
83             setsockopt $self->{sock}, SOL_SOCKET, SO_BROADCAST, undef;
84             }
85              
86             sub get_message {
87             my($self,$timeout) = @_;
88             my($msg,$rout);
89             my $rin = '';
90             vec($rin,fileno($self->{sock}),1) = 1;
91             select($rout=$rin, undef, undef, $timeout);
92             if (vec($rout,fileno($self->{sock}),1)) {
93             $self->{peer} = recv $self->{sock}, $msg, 4096, 0;
94             return $msg;
95             } else {
96             return undef;
97             }
98             }
99              
100             sub send_message {
101             my($self, $msg) = @_;
102             send $self->{sock}, $msg, 0, $self->{peer};
103             }
104              
105             sub send_and_get_message {
106             my($self,$in) = @_;
107             my $out;
108             for (my $i=0; $i < 10; $i++) {
109             $self->send_message($in);
110             last if defined($out = $self->get_message(1));
111             }
112             return $out;
113             }
114              
115             1;