1package Client;
2
3use IO::Select;
4use IO::Socket;
5use strict;
6use Carp;
7use Sys::Syslog;
8use Crypt::HCE_MD5;
9
10my @response;
11my $data;
12
13sub new {
14    my $class = shift;
15    my $self = {};
16
17    bless $self, $class;
18    if ((scalar(@_) % 2) != 0) {
19	croak "incorrect number of parameters";
20    }
21    while (@_) {
22	my $key = shift(@_);
23	my $value = shift(@_);
24	$self->{$key} = $value;
25    }
26    $self->_initialize;
27    return $self;
28}
29
30sub _initialize {
31    my $self = shift;
32    my $timeout;
33
34    if (!defined($self->{'Server'})) {
35	croak "Client not initialized properly : Server parameter missing";
36    }
37    if (!defined($self->{'Port'})) {
38	croak "Client not initialized properly : Port parameter missing";
39    }
40    if (!defined($self->{'SKey'})) {
41	croak "Client not initialized properly : SKey parameter missing";
42    }
43    if (!eval {$self->{'Socket'} = IO::Socket::INET->new(PeerAddr => $self->{'Server'},
44							 PeerPort => $self->{'Port'},
45							 Proto => 'tcp',
46							 Reuse => 1); })
47    {
48	croak "Client couldn't establish a connection to $self->{'Server'}";
49    }
50    $self->{'Socket'}->autoflush(1);
51    srand($$|time()); # poor random generator should be replaced
52    $self->{'RKey'} = rand(100000000)+1000000;
53    $self->{'HCE'} = Crypt::HCE_MD5->new($self->{'SKey'}, $self->{'RKey'});
54    print { $self->{'Socket'} } "$self->{'RKey'}\n";
55}
56
57sub send {
58    my $self = shift;
59    my @items = @_;
60    my ($item, $enc_item);
61
62    if (defined($self->{'HCE'})) {
63	foreach $item (@items) {
64#	    syslog('debug','Client encode: %s',$item);
65	    $enc_item = $self->{'HCE'}->hce_block_encode_mime($item);
66#	    syslog('debug','Client sending: %s', $enc_item);
67	    print { $self->{'Socket'} } "$enc_item\n";
68	}
69	$enc_item = $self->{'HCE'}->hce_block_encode_mime("+END_OF_LIST");
70	print { $self->{'Socket'} } "$enc_item\n";
71    } else {
72	foreach $item (@items) {
73#	    syslog('debug','Client sending: %s',$item);
74	    print { $self->{'Socket'} } "$item\n";
75	}
76	print { $self->{'Socket'} } "+END_OF_LIST\n";
77    }
78    return 0;
79}
80
81sub recv {
82    my $self = shift;
83    my $fh = $self->{'Socket'};
84    my ($data, $dec_data);
85
86    if (defined($self->{'HCE'})) {
87	$data = "";
88	undef(@response);
89	while (<$fh>) {
90	    chomp;
91	    $data = 1;
92#	    syslog('debug','Client recv: %s', $_);
93	    $dec_data = $self->{'HCE'}->hce_block_decode_mime($_);
94#	    syslog('debug','Client decode: %s', $dec_data);
95	    last if ($dec_data eq "+END_OF_LIST");
96	    push @response, $dec_data;
97	};
98	if (!defined $data) {
99	    close ($self->{'Socket'});
100	    return $data;
101
102	} else {
103	    close ($self->{'Socket'});
104	    return @response;
105	};
106    } else {
107	$data = "";
108	undef(@response);
109	while (<$fh>) {
110	    chomp;
111	    $data = 1;
112	    push @response, $_;
113	};
114	if (!defined $data) {
115	    close ($self->{'Socket'});
116	    return $data;
117	} else {
118	    close ($self->{'Socket'});
119	    return @response;
120	};
121    }
122}
123
1241;
125__END__
126
127#------- POD ------
128