+# New style routing handler
+sub handle_59
+{
+ my $self = shift;
+ my $pcno = shift;
+ my $line = shift;
+ my $origin = shift;
+
+ return unless eph_dup($line);
+
+ my ($sort, $hextime, $ncall) = @_[1,2,3];
+ if ($ncall eq $main::mycall) {
+ dbg("PCPROT: ignoring PC59 for me") if isdbg('chan');
+ return;
+ }
+
+ # mark myself as NewRoute if I get a PC59
+ $self->{newroute} = 1 if $ncall eq $self->{call};
+
+ # do this once for filtering with a throwaway routing entry if a new node
+ my $fnode = Route::Node::get($ncall) || Route::new($ncall);
+ return unless $self->in_filter_route($fnode);
+
+ # now do it properly for actions
+ my $node = Route::Node::get($ncall) || Route::Node::new($ncall);
+
+ # find each of the entries (or create new ones)
+ my @refs;
+ for my $ent (@_[4..-1]) {
+ my ($esort, $ehere, $ecall) = unpack "A A A*", $ent;
+ my $ref;
+
+ # create user, if required
+ my $user = DXUser->get_current($ecall);
+ unless ($user) {
+ $user = DXUser->new($ecall);
+ $user->sort();
+ $user->priv(1); # I have relented and defaulted nodes
+ $user->lockout(1);
+ $user->homenode($call);
+ $user->node($call);
+ }
+ if ($esort eq 'U') {
+ $ref = Route::User::get($ecall);
+ unless ($ref) {
+ # create user, if required
+ my $user = DXUser->get_current($ecall);
+ unless ($user) {
+ $user = DXUser->new($ecall);
+ $user->sort('U');
+ $user->homenode($ncall);
+ $user->node($ncall);
+ $user->put;
+ }
+ $ref = Route::User::new($ecall, 0);
+ }
+ } elsif ($esort eq 'N') {
+ $ref = Route::Node::get($ecall);
+ unless ($ref) {
+ # create user, if required
+ my $user = DXUser->get_current($ecall);
+ unless ($user) {
+ $user = DXUser->new($ecall);
+ $user->priv(1); # I have relented and defaulted nodes
+ $user->lockout(1);
+ $user->sort('A');
+ $user->homenode($ncall);
+ $user->node($ncall);
+ $user->put;
+ }
+ $ref = Route::Node::new($ecall, 0);
+ }
+ } else {
+ dbg("DXPROT: unknown entity type '$esort' on $ecall for node $ncall") if isdbg('chan');
+ next;
+ }
+ $ref->here($here); # might as well set this here
+ push @refs, $ref;
+ }
+
+ # if it is a delete or a configure, disconnect all the entries mentioned
+ # from this node (which is a parent in this context).
+ my @del;
+ if ($sort eq 'D' || $sort eq 'C') {
+ for my $ref (@refs) {
+ next if $ref->call eq $ncall;
+ if ($ref->isa('Route::Node')) {
+ push @del, $ref->del($node);
+ } elsif ($ref->isa('Route::User')) {
+ push @del, $node->del_user($ref);
+ }
+ }
+ }
+
+ # if it is an add or a configure, connect all the entries
+ my @add;
+ if ($sort eq 'A' || $sort eq 'C') {
+ for my $ref (@refs) {
+ next if $ref->call eq $ncall;
+ if ($ref->isa('Route::Node')) {
+ my $new = $node->add($ref->call);
+ push @add, $new if $new;
+ } elsif ($ref->isa('Route::User')) {
+ push @add, $node->add_user($ref->call);
+ }
+ }
+ }
+}
+
+