| 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__ |