line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Net::IPMessenger::CommandLine; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
2418
|
use warnings; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
43
|
|
4
|
1
|
|
|
1
|
|
6
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
41
|
|
5
|
1
|
|
|
1
|
|
5
|
use IO::Socket; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
9
|
|
6
|
1
|
|
|
1
|
|
1069
|
use base qw( Net::IPMessenger ); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
2514
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
__PACKAGE__->mk_accessors( qw( use_secret ) ); |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
our $AUTOLOAD; |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
# sort by IP address |
13
|
|
|
|
|
|
|
sub by_addr { |
14
|
0
|
|
|
0
|
1
|
|
my( $ipa1, $ipa2, $ipa3, $ipa4 ) = split( /\./, $a->peeraddr, 4 ); |
15
|
0
|
|
|
|
|
|
my( $ipb1, $ipb2, $ipb3, $ipb4 ) = split( /\./, $b->peeraddr, 4 ); |
16
|
|
|
|
|
|
|
|
17
|
0
|
0
|
0
|
|
|
|
$ipa1 <=> $ipb1 |
|
|
|
0
|
|
|
|
|
18
|
|
|
|
|
|
|
|| $ipa2 <=> $ipb2 |
19
|
|
|
|
|
|
|
|| $ipa3 <=> $ipb3 |
20
|
|
|
|
|
|
|
|| $ipa4 <=> $ipb4; |
21
|
|
|
|
|
|
|
} |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
# DEBUG |
24
|
|
|
|
|
|
|
sub dumper { |
25
|
0
|
|
|
0
|
1
|
|
require Data::Dumper; |
26
|
0
|
|
|
|
|
|
import Data::Dumper qw(Dumper); |
27
|
|
|
|
|
|
|
|
28
|
0
|
|
|
|
|
|
my $self = shift; |
29
|
0
|
|
|
|
|
|
my $output = Dumper($self) . "\n"; |
30
|
0
|
|
|
|
|
|
return $output; |
31
|
|
|
|
|
|
|
} |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
sub debuguserbyaddr { |
34
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
35
|
0
|
|
|
|
|
|
my $addr = shift; |
36
|
|
|
|
|
|
|
|
37
|
0
|
|
|
|
|
|
my $output; |
38
|
0
|
|
|
|
|
|
for my $key ( keys %{ $self->user } ) { |
|
0
|
|
|
|
|
|
|
39
|
0
|
|
|
|
|
|
my $hashref = $self->user->{$key}; |
40
|
0
|
0
|
|
|
|
|
if ( $hashref->addr eq $addr ) { |
41
|
0
|
|
|
|
|
|
$output .= $key . "\n"; |
42
|
0
|
|
|
|
|
|
for my $item ( sort keys %{$hashref} ) { |
|
0
|
|
|
|
|
|
|
43
|
0
|
0
|
|
|
|
|
$output .= sprintf "\t%-12s : %s\n", $item, $hashref->{$item} |
44
|
|
|
|
|
|
|
if defined $hashref->{$item}; |
45
|
|
|
|
|
|
|
} |
46
|
|
|
|
|
|
|
} |
47
|
|
|
|
|
|
|
} |
48
|
|
|
|
|
|
|
|
49
|
0
|
|
|
|
|
|
return $output; |
50
|
|
|
|
|
|
|
} |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
sub socktest { |
53
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
54
|
0
|
|
|
|
|
|
return sprintf "socktest %s\n", inet_ntoa( $self->socket->peeraddr ); |
55
|
|
|
|
|
|
|
} |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
# Command |
58
|
|
|
|
|
|
|
sub AUTOLOAD { |
59
|
0
|
|
|
0
|
|
|
my $self = shift; |
60
|
0
|
|
|
|
|
|
my $name = $AUTOLOAD; |
61
|
0
|
|
|
|
|
|
$name =~ s/.*://; |
62
|
|
|
|
|
|
|
|
63
|
0
|
|
|
|
|
|
return "$name is not the command"; |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
sub join { |
67
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
68
|
0
|
|
|
|
|
|
$self->user( {} ); |
69
|
|
|
|
|
|
|
|
70
|
0
|
|
|
|
|
|
my $command = $self->messagecommand('BR_ENTRY')->set_broadcast; |
71
|
0
|
0
|
|
|
|
|
if ( $self->encrypt ) { |
72
|
0
|
|
|
|
|
|
$command->set_encrypt; |
73
|
|
|
|
|
|
|
} |
74
|
|
|
|
|
|
|
$self->send( |
75
|
|
|
|
|
|
|
{ |
76
|
0
|
|
|
|
|
|
command => $command, |
77
|
|
|
|
|
|
|
option => $self->my_info, |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
); |
80
|
0
|
|
|
|
|
|
return; |
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
|
83
|
|
|
|
|
|
|
sub quit { |
84
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
85
|
|
|
|
|
|
|
|
86
|
0
|
|
|
|
|
|
my $command = $self->messagecommand('BR_EXIT')->set_broadcast; |
87
|
0
|
|
|
|
|
|
$self->send( { command => $command, } ); |
88
|
0
|
|
|
|
|
|
return 'exiting'; |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
sub list { |
92
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
93
|
0
|
|
|
|
|
|
my $output; |
94
|
|
|
|
|
|
|
|
95
|
0
|
|
|
|
|
|
my $i = 0; |
96
|
0
|
|
|
|
|
|
print " ip address : port : nickname\n"; |
97
|
0
|
|
|
|
|
|
print "-----------------:------:---------\n"; |
98
|
0
|
0
|
|
|
|
|
if ( $self->user ) { |
99
|
0
|
|
|
|
|
|
for my $val ( sort by_addr values %{ $self->user } ) { |
|
0
|
|
|
|
|
|
|
100
|
0
|
|
|
|
|
|
$output .= sprintf "%16s : %s : %s\n", $val->peeraddr, |
101
|
|
|
|
|
|
|
$val->peerport, $val->nickname; |
102
|
0
|
|
|
|
|
|
$i++; |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
} |
105
|
0
|
|
|
|
|
|
$output .= sprintf "%s users listed\n", $i; |
106
|
0
|
|
|
|
|
|
return $output; |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
sub messages { |
110
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
111
|
0
|
|
|
|
|
|
my $output; |
112
|
|
|
|
|
|
|
my $j; |
113
|
0
|
0
|
0
|
|
|
|
if ( $self->message and @{ $self->message } ) { |
|
0
|
|
|
|
|
|
|
114
|
0
|
|
|
|
|
|
for my $message ( @{ $self->message } ) { |
|
0
|
|
|
|
|
|
|
115
|
0
|
|
|
|
|
|
$output .= sprintf "%03d : %s : %s\n", ++$j, $message->time, |
116
|
|
|
|
|
|
|
$message->nickname; |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
else { |
120
|
0
|
|
|
|
|
|
$output = "no message arrived"; |
121
|
|
|
|
|
|
|
} |
122
|
0
|
|
|
|
|
|
return $output; |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
sub read { |
126
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
127
|
0
|
|
|
|
|
|
my $output; |
128
|
|
|
|
|
|
|
|
129
|
0
|
0
|
0
|
|
|
|
if ( $self->message and @{ $self->message } ) { |
|
0
|
|
|
|
|
|
|
130
|
0
|
|
|
|
|
|
my $message = shift @{ $self->message }; |
|
0
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
|
132
|
0
|
|
|
|
|
|
$output = sprintf "%s: %s\n%s\n", $message->time, $message->nickname, |
133
|
|
|
|
|
|
|
$message->get_message; |
134
|
|
|
|
|
|
|
|
135
|
0
|
|
|
|
|
|
my $command = $self->messagecommand( $message->command ); |
136
|
0
|
0
|
|
|
|
|
if ( $command->get_secret ) { |
137
|
0
|
|
|
|
|
|
$self->send( |
138
|
|
|
|
|
|
|
{ |
139
|
|
|
|
|
|
|
command => $self->messagecommand('READMSG'), |
140
|
|
|
|
|
|
|
option => $message->packet_num, |
141
|
|
|
|
|
|
|
peeraddr => $message->peeraddr, |
142
|
|
|
|
|
|
|
peerport => $message->peerport |
143
|
|
|
|
|
|
|
} |
144
|
|
|
|
|
|
|
); |
145
|
|
|
|
|
|
|
} |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
else { |
148
|
0
|
|
|
|
|
|
$output = "no message arrived"; |
149
|
|
|
|
|
|
|
} |
150
|
0
|
|
|
|
|
|
return $output; |
151
|
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
sub write { |
154
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
155
|
0
|
|
|
|
|
|
my $sendto = shift; |
156
|
|
|
|
|
|
|
|
157
|
0
|
0
|
|
|
|
|
unless ( defined $sendto ) { |
158
|
0
|
|
|
|
|
|
return ("Usage: write nickname_to_send"); |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
|
161
|
0
|
|
|
|
|
|
my $target; |
162
|
0
|
|
|
|
|
|
for my $user ( values %{ $self->user } ) { |
|
0
|
|
|
|
|
|
|
163
|
0
|
0
|
|
|
|
|
if ( $user->nickname eq $sendto ) { |
164
|
0
|
0
|
0
|
|
|
|
if ( $user->encrypt and $self->encrypt and not $user->pubkey ) { |
|
|
|
0
|
|
|
|
|
165
|
0
|
|
|
|
|
|
my $option = sprintf "%x", |
166
|
|
|
|
|
|
|
$self->encrypt->support_encryption; |
167
|
0
|
|
|
|
|
|
$self->send( |
168
|
|
|
|
|
|
|
{ |
169
|
|
|
|
|
|
|
command => $self->messagecommand('GETPUBKEY'), |
170
|
|
|
|
|
|
|
option => $option, |
171
|
|
|
|
|
|
|
peeraddr => $user->peeraddr, |
172
|
|
|
|
|
|
|
peerport => $user->peerport, |
173
|
|
|
|
|
|
|
} |
174
|
|
|
|
|
|
|
); |
175
|
|
|
|
|
|
|
} |
176
|
0
|
|
|
|
|
|
$target = $user; |
177
|
0
|
|
|
|
|
|
last; |
178
|
|
|
|
|
|
|
} |
179
|
|
|
|
|
|
|
} |
180
|
0
|
0
|
|
|
|
|
return "no target found" unless defined $target; |
181
|
|
|
|
|
|
|
|
182
|
0
|
|
|
|
|
|
$self->{_target} = $target; |
183
|
0
|
|
|
|
|
|
$self->{_write_buffer} = ""; |
184
|
|
|
|
|
|
|
|
185
|
0
|
|
|
|
|
|
return <<__MESSAGE__; |
186
|
|
|
|
|
|
|
writing message to '$sendto' is ready |
187
|
|
|
|
|
|
|
input message then '.' to finish and send it. |
188
|
|
|
|
|
|
|
__MESSAGE__ |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
sub writing { |
192
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
193
|
0
|
|
|
|
|
|
my $data = shift; |
194
|
|
|
|
|
|
|
|
195
|
0
|
0
|
|
|
|
|
return unless defined $data; |
196
|
|
|
|
|
|
|
|
197
|
0
|
0
|
|
|
|
|
if ( $data eq '.' ) { |
198
|
0
|
|
|
|
|
|
my $target = $self->{_target}; |
199
|
0
|
|
|
|
|
|
my $peeraddr = $target->peeraddr; |
200
|
0
|
|
|
|
|
|
my $peerport = $target->peerport; |
201
|
|
|
|
|
|
|
|
202
|
0
|
0
|
0
|
|
|
|
if ( $peeraddr and $peerport ) { |
203
|
0
|
|
|
|
|
|
my $command = $self->messagecommand('SENDMSG'); |
204
|
0
|
|
|
|
|
|
$command->set_sendcheck; |
205
|
0
|
0
|
|
|
|
|
$command->set_secret if $self->use_secret; |
206
|
|
|
|
|
|
|
# encrypt message |
207
|
0
|
0
|
0
|
|
|
|
if ( $target->encrypt and $self->encrypt ) { |
208
|
0
|
|
|
|
|
|
$command->set_encrypt; |
209
|
0
|
|
|
|
|
|
my $encrypted = $self->encrypt->encrypt_message( |
210
|
|
|
|
|
|
|
$self->{_write_buffer}, |
211
|
|
|
|
|
|
|
$target->pubkey, |
212
|
|
|
|
|
|
|
); |
213
|
0
|
|
|
|
|
|
$self->{_write_buffer} = $encrypted; |
214
|
|
|
|
|
|
|
} |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
$self->send( |
217
|
|
|
|
|
|
|
{ |
218
|
0
|
|
|
|
|
|
command => $command, |
219
|
|
|
|
|
|
|
option => $self->{_write_buffer}, |
220
|
|
|
|
|
|
|
peeraddr => $peeraddr, |
221
|
|
|
|
|
|
|
peerport => $peerport |
222
|
|
|
|
|
|
|
} |
223
|
|
|
|
|
|
|
); |
224
|
|
|
|
|
|
|
} |
225
|
|
|
|
|
|
|
|
226
|
0
|
|
|
|
|
|
delete $self->{_write_buffer}; |
227
|
0
|
|
|
|
|
|
delete $self->{_target}; |
228
|
|
|
|
|
|
|
} |
229
|
|
|
|
|
|
|
else { |
230
|
0
|
|
|
|
|
|
$self->{_write_buffer} .= $data . "\n"; |
231
|
|
|
|
|
|
|
} |
232
|
|
|
|
|
|
|
} |
233
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
sub is_writing { |
235
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
236
|
0
|
0
|
|
|
|
|
if ( exists $self->{_write_buffer} ) { |
237
|
0
|
|
|
|
|
|
return 1; |
238
|
|
|
|
|
|
|
} |
239
|
0
|
|
|
|
|
|
return; |
240
|
|
|
|
|
|
|
} |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
sub info { |
243
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
244
|
|
|
|
|
|
|
|
245
|
0
|
|
|
|
|
|
my $output = "It's Your information\n"; |
246
|
0
|
|
|
|
|
|
$output .= sprintf "nickname : %s\n", $self->nickname; |
247
|
0
|
|
|
|
|
|
$output .= sprintf "groupname : %s\n", $self->groupname; |
248
|
0
|
|
|
|
|
|
$output .= sprintf "username : %s\n", $self->username; |
249
|
0
|
|
|
|
|
|
$output .= sprintf "hostname : %s\n", $self->hostname; |
250
|
0
|
|
|
|
|
|
$output .= sprintf "server addr : %s\n", $self->serveraddr; |
251
|
0
|
|
0
|
|
|
|
$output .= sprintf "broadcast addr : %s\n", @{ $self->broadcast } || ''; |
252
|
0
|
|
|
|
|
|
return $output; |
253
|
|
|
|
|
|
|
} |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
sub help { |
256
|
0
|
|
|
0
|
1
|
|
my $self = shift; |
257
|
0
|
|
|
|
|
|
my $output = <<__OUTPUT__; |
258
|
|
|
|
|
|
|
Text IP Messenger Client Help: |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
This is just another IP messenger client for text console. |
261
|
|
|
|
|
|
|
These commands are available. |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
Command list (shortcut) : |
264
|
|
|
|
|
|
|
join (j) : send entry packet (BR_ENTRY) to the broad cast address |
265
|
|
|
|
|
|
|
info (i) : show information of yourself |
266
|
|
|
|
|
|
|
list (l) : list users |
267
|
|
|
|
|
|
|
message (m) : show message list |
268
|
|
|
|
|
|
|
read (r) : read 1 oldest message and delete |
269
|
|
|
|
|
|
|
write (w) : write message to the nickname user |
270
|
|
|
|
|
|
|
quit (q) : send exit packet (BR_EXIT) to the broad cast address |
271
|
|
|
|
|
|
|
help (h) : show this help |
272
|
|
|
|
|
|
|
__OUTPUT__ |
273
|
|
|
|
|
|
|
|
274
|
0
|
|
|
|
|
|
return $output; |
275
|
|
|
|
|
|
|
} |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
# regist some shortcuts |
278
|
0
|
|
|
0
|
1
|
|
sub j { shift->join(@_); } |
279
|
0
|
|
|
0
|
1
|
|
sub q { shift->quit(@_); } |
280
|
0
|
|
|
0
|
1
|
|
sub l { shift->list(@_); } |
281
|
0
|
|
|
0
|
1
|
|
sub m { shift->messages(@_); } |
282
|
0
|
|
|
0
|
1
|
|
sub r { shift->read(@_); } |
283
|
0
|
|
|
0
|
1
|
|
sub w { shift->write(@_); } |
284
|
0
|
|
|
0
|
1
|
|
sub i { shift->info(@_); } |
285
|
0
|
|
|
0
|
1
|
|
sub h { shift->help(@_); } |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
1; |
288
|
|
|
|
|
|
|
__END__ |