use
Dancer
qw/:syntax :script/
;
our
@EXPORT
= ();
our
@EXPORT_OK
=
qw/ nbtstat_resolve_async store_nbt /
;
our
%EXPORT_TAGS
= (
all
=> \
@EXPORT_OK
);
sub
nbtstat_resolve_async {
my
$ips
=
shift
;
my
$timeout
= setting(
'nbtstat_timeout'
) || 1;
my
$interval
= setting(
'nbtstat_interval'
) || 0.02;
my
$stater
= App::Netdisco::AnyEvent::Nbtstat->new(
timeout
=>
$timeout
,
interval
=>
$interval
);
my
$cv
= AE::cv;
$cv
->begin(
sub
{
shift
->
send
} );
foreach
my
$hash_ref
(
@$ips
) {
my
$ip
=
$hash_ref
->{
'ip'
};
$cv
->begin;
$stater
->nbtstat(
$ip
,
sub
{
my
$res
=
shift
;
_filter_nbname(
$ip
,
$hash_ref
,
$res
);
$cv
->end;
}
);
}
$cv
->end;
$cv
->
recv
;
undef
$stater
;
return
$ips
;
}
sub
_filter_nbname {
my
$ip
=
shift
;
my
$hash_ref
=
shift
;
my
$node_status
=
shift
;
my
$server
= 0;
my
$nbname
=
''
;
my
$domain
=
''
;
my
$nbuser
=
''
;
for
my
$rr
( @{
$node_status
->{
'names'
}} ) {
my
$suffix
=
defined
$rr
->{
'suffix'
} ?
$rr
->{
'suffix'
} : -1;
my
$G
=
defined
$rr
->{
'G'
} ?
$rr
->{
'G'
} :
''
;
my
$name
=
defined
$rr
->{
'name'
} ?
$rr
->{
'name'
} :
''
;
if
(
$suffix
== 0 and
$G
eq
"GROUP"
) {
$domain
=
$name
;
}
if
(
$suffix
== 3 and
$G
eq
"UNIQUE"
) {
$nbuser
=
$name
;
}
if
(
$suffix
== 0 and
$G
eq
"UNIQUE"
) {
$nbname
=
$name
unless
$name
=~ /^IS~/;
}
if
(
$suffix
== 32 and
$G
eq
"UNIQUE"
) {
$server
= 1;
}
}
unless
(
$nbname
) {
debug
sprintf
' nbtstat no computer name found for %s'
,
$ip
;
return
;
}
my
$mac
=
$node_status
->{
'mac_address'
} ||
''
;
unless
( check_mac(
$ip
,
$mac
) ) {
my
$node_ip
= schema(
'netdisco'
)->resultset(
'NodeIp'
)
->single( {
ip
=>
$ip
,
-bool
=>
'active'
} );
if
( !
defined
$node_ip
) {
debug
sprintf
' no MAC for %s returned by nbtstat or in DB'
,
$ip
;
return
;
}
$mac
=
$node_ip
->mac;
}
$hash_ref
->{
'ip'
} =
$ip
;
$hash_ref
->{
'mac'
} =
$mac
;
$hash_ref
->{
'nbname'
} = Encode::decode(
'UTF-8'
,
$nbname
);
$hash_ref
->{
'domain'
} = Encode::decode(
'UTF-8'
,
$domain
);
$hash_ref
->{
'server'
} =
$server
;
$hash_ref
->{
'nbuser'
} = Encode::decode(
'UTF-8'
,
$nbuser
);
return
;
}
sub
store_nbt {
my
(
$hash_ref
,
$now
) =
@_
;
$now
||=
'now()'
;
schema(
'netdisco'
)->resultset(
'NodeNbt'
)->update_or_create(
{
mac
=>
$hash_ref
->{
'mac'
},
ip
=>
$hash_ref
->{
'ip'
},
nbname
=>
$hash_ref
->{
'nbname'
},
domain
=>
$hash_ref
->{
'domain'
},
server
=>
$hash_ref
->{
'server'
},
nbuser
=>
$hash_ref
->{
'nbuser'
},
active
=> \
'true'
,
time_last
=> \
$now
,
},
{
key
=>
'primary'
,
for
=>
'update'
,
}
);
return
;
}
1;