| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package IO::EPP::Verisign; | 
| 2 |  |  |  |  |  |  |  | 
| 3 |  |  |  |  |  |  | =encoding utf8 | 
| 4 |  |  |  |  |  |  |  | 
| 5 |  |  |  |  |  |  | =head1 NAME | 
| 6 |  |  |  |  |  |  |  | 
| 7 |  |  |  |  |  |  | IO::EPP::Verisign | 
| 8 |  |  |  |  |  |  |  | 
| 9 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | use IO::EPP::Verisign; | 
| 12 |  |  |  |  |  |  |  | 
| 13 |  |  |  |  |  |  | # Parameters for IO::Socket::SSL | 
| 14 |  |  |  |  |  |  | my %sock_params = ( | 
| 15 |  |  |  |  |  |  | PeerHost        => 'epp.verisign-grs.com', | 
| 16 |  |  |  |  |  |  | PeerPort        => 700, | 
| 17 |  |  |  |  |  |  | SSL_key_file    => 'key_file.pem', | 
| 18 |  |  |  |  |  |  | SSL_cert_file   => 'cert_file.pem', | 
| 19 |  |  |  |  |  |  | Timeout         => 30, | 
| 20 |  |  |  |  |  |  | ); | 
| 21 |  |  |  |  |  |  |  | 
| 22 |  |  |  |  |  |  | # Create object, get greeting and call login() | 
| 23 |  |  |  |  |  |  | my $conn = IO::EPP::Verisign->new( { | 
| 24 |  |  |  |  |  |  | user => 'login', | 
| 25 |  |  |  |  |  |  | pass => 'XXXXX', | 
| 26 |  |  |  |  |  |  | sock_params => \%sock_params, | 
| 27 |  |  |  |  |  |  | server => 'Core', # or NameStore, or  DotName | 
| 28 |  |  |  |  |  |  | test_mode => 0, # real connect | 
| 29 |  |  |  |  |  |  | } ); | 
| 30 |  |  |  |  |  |  |  | 
| 31 |  |  |  |  |  |  | # Check domain | 
| 32 |  |  |  |  |  |  | my ( $answ, $code, $msg ) = $conn->check_domains( { domains => [ 'com.net', 'net.com' ] } ); | 
| 33 |  |  |  |  |  |  |  | 
| 34 |  |  |  |  |  |  | # Call logout() and destroy object | 
| 35 |  |  |  |  |  |  | undef $conn; | 
| 36 |  |  |  |  |  |  |  | 
| 37 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 38 |  |  |  |  |  |  |  | 
| 39 |  |  |  |  |  |  | Work with Verisign EPP API | 
| 40 |  |  |  |  |  |  |  | 
| 41 |  |  |  |  |  |  | Features: | 
| 42 |  |  |  |  |  |  | Very mach extension, verisign here is leader. Absolutely all extensions have not yet been implemented | 
| 43 |  |  |  |  |  |  |  | 
| 44 |  |  |  |  |  |  | docs: | 
| 45 |  |  |  |  |  |  | L, | 
| 46 |  |  |  |  |  |  | L (need white IP) | 
| 47 |  |  |  |  |  |  |  | 
| 48 |  |  |  |  |  |  | for .name: | 
| 49 |  |  |  |  |  |  | L | 
| 50 |  |  |  |  |  |  |  | 
| 51 |  |  |  |  |  |  | The behavior of C and C servers is markedly different. | 
| 52 |  |  |  |  |  |  |  | 
| 53 |  |  |  |  |  |  | =cut | 
| 54 |  |  |  |  |  |  |  | 
| 55 | 1 |  |  | 1 |  | 1382 | use IO::EPP::Base; | 
|  | 1 |  |  |  |  | 4 |  | 
|  | 1 |  |  |  |  | 46 |  | 
| 56 | 1 |  |  | 1 |  | 12 | use parent qw( IO::EPP::Base ); | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 8 |  | 
| 57 |  |  |  |  |  |  |  | 
| 58 | 1 |  |  | 1 |  | 75 | use strict; | 
|  | 1 |  |  |  |  | 2 |  | 
|  | 1 |  |  |  |  | 22 |  | 
| 59 | 1 |  |  | 1 |  | 5 | use warnings; | 
|  | 1 |  |  |  |  | 1 |  | 
|  | 1 |  |  |  |  | 2925 |  | 
| 60 |  |  |  |  |  |  |  | 
| 61 |  |  |  |  |  |  | # not to change formatting: | 
| 62 |  |  |  |  |  |  | our $sub_product_ext_begin = | 
| 63 |  |  |  |  |  |  | ' | 
| 64 |  |  |  |  |  |  | '; | 
| 65 |  |  |  |  |  |  | our $sub_product_ext_end = | 
| 66 |  |  |  |  |  |  | ' | 
| 67 |  |  |  |  |  |  | '; | 
| 68 |  |  |  |  |  |  | our $idn_ext = | 
| 69 |  |  |  |  |  |  | 'xmlns:idnLang="http://www.verisign.com/epp/idnLang-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.verisign.com/epp/idnLang-1.0 idnLang-1.0.xsd"'; | 
| 70 |  |  |  |  |  |  | our $rgp_ext = | 
| 71 |  |  |  |  |  |  | 'xmlns:rgp="urn:ietf:params:xml:ns:rgp-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:ietf:params:xml:ns:rgp-1.0 rgp-1.0.xsd"'; | 
| 72 |  |  |  |  |  |  |  | 
| 73 |  |  |  |  |  |  | =head1 FUNCTIONS | 
| 74 |  |  |  |  |  |  |  | 
| 75 |  |  |  |  |  |  | =head2 make_request | 
| 76 |  |  |  |  |  |  |  | 
| 77 |  |  |  |  |  |  | Make a single request to the registry | 
| 78 |  |  |  |  |  |  |  | 
| 79 |  |  |  |  |  |  | A complete example is found in L | 
| 80 |  |  |  |  |  |  |  | 
| 81 |  |  |  |  |  |  | =cut | 
| 82 |  |  |  |  |  |  |  | 
| 83 |  |  |  |  |  |  | sub make_request { | 
| 84 | 26 |  |  | 26 | 1 | 10257 | my ( $action, $params ) = @_; | 
| 85 |  |  |  |  |  |  |  | 
| 86 | 26 |  |  |  |  | 38 | my ( $self, $code, $msg, $answ ); | 
| 87 |  |  |  |  |  |  |  | 
| 88 | 26 | 100 |  |  |  | 61 | unless ( $params->{conn} ) { | 
| 89 | 19 |  | 50 |  |  | 50 | $params->{sock_params}{PeerHost} ||= 'epp.verisign-grs.com'; | 
| 90 | 19 |  | 50 |  |  | 46 | $params->{sock_params}{PeerPort} ||= 700; | 
| 91 |  |  |  |  |  |  |  | 
| 92 | 19 |  |  |  |  | 52 | ( $self, $code, $msg ) = __PACKAGE__->new( $params ); | 
| 93 |  |  |  |  |  |  |  | 
| 94 | 19 | 50 | 33 |  |  | 68 | unless ( $code  and  $code == 1000 ) { | 
| 95 | 0 |  |  |  |  | 0 | goto END_MR; | 
| 96 |  |  |  |  |  |  | } | 
| 97 |  |  |  |  |  |  | } | 
| 98 |  |  |  |  |  |  | else { | 
| 99 | 7 |  |  |  |  | 15 | $self = $params->{conn}; | 
| 100 |  |  |  |  |  |  | } | 
| 101 |  |  |  |  |  |  |  | 
| 102 |  |  |  |  |  |  |  | 
| 103 |  |  |  |  |  |  | # You can change the zone if you do not change the server | 
| 104 |  |  |  |  |  |  | # com <-> net <-> edu | 
| 105 |  |  |  |  |  |  | # cc <-> tv <-> jobs <-> name <-> ... new gtld | 
| 106 | 26 |  | 100 |  |  | 69 | my $tld = $self->{tld} || ''; | 
| 107 |  |  |  |  |  |  |  | 
| 108 | 26 | 50 | 66 |  |  | 73 | if ( not $tld  and  $params->{dname} ) { | 
| 109 | 0 |  |  |  |  | 0 | ( $tld ) = $params->{dname} =~ /\.([^.]+)$/; | 
| 110 |  |  |  |  |  |  | } | 
| 111 |  |  |  |  |  |  |  | 
| 112 | 26 | 100 |  |  |  | 48 | if ( $tld ) { | 
| 113 | 17 | 50 |  |  |  | 31 | if ( lc ( $tld ) eq 'name' ) { | 
| 114 | 0 |  |  |  |  | 0 | $self->{dzone} = 'name'; | 
| 115 |  |  |  |  |  |  | } | 
| 116 |  |  |  |  |  |  | else { | 
| 117 | 17 |  |  |  |  | 37 | $self->{dzone} = 'dot' . uc( $tld ); | 
| 118 |  |  |  |  |  |  | } | 
| 119 |  |  |  |  |  |  |  | 
| 120 | 17 |  |  |  |  | 54 | $self->{namestore_ext} = $sub_product_ext_begin . $self->{dzone} . $sub_product_ext_end ."\n"; | 
| 121 |  |  |  |  |  |  | } | 
| 122 |  |  |  |  |  |  |  | 
| 123 |  |  |  |  |  |  |  | 
| 124 | 26 |  |  |  |  | 40 | $self->{critical_error} = ''; | 
| 125 |  |  |  |  |  |  |  | 
| 126 | 26 | 50 |  |  |  | 102 | if ( $self->can( $action ) ) { | 
| 127 | 26 |  |  |  |  | 65 | ( $answ, $code, $msg ) = $self->$action( $params ); | 
| 128 |  |  |  |  |  |  | } | 
| 129 |  |  |  |  |  |  | else { | 
| 130 | 0 |  |  |  |  | 0 | $msg = "undefined command <$action>, request cancelled"; | 
| 131 | 0 |  |  |  |  | 0 | $code = 0; | 
| 132 |  |  |  |  |  |  | } | 
| 133 |  |  |  |  |  |  |  | 
| 134 |  |  |  |  |  |  |  | 
| 135 |  |  |  |  |  |  | END_MR: | 
| 136 |  |  |  |  |  |  |  | 
| 137 | 26 | 50 |  |  |  | 65 | $msg .= '; ' . $self->{critical_error} if $self->{critical_error}; | 
| 138 |  |  |  |  |  |  |  | 
| 139 | 26 |  |  |  |  | 62 | my $full_answ = "code: $code\nmsg: $msg"; | 
| 140 |  |  |  |  |  |  |  | 
| 141 | 26 | 50 | 33 |  |  | 97 | $answ = {} unless $answ && ref $answ; | 
| 142 |  |  |  |  |  |  |  | 
| 143 | 26 |  |  |  |  | 69 | $answ->{code} = $code; | 
| 144 | 26 |  |  |  |  | 45 | $answ->{msg}  = $msg; | 
| 145 |  |  |  |  |  |  |  | 
| 146 | 26 | 50 |  |  |  | 112 | return wantarray ? ( $answ, $full_answ, $self ) : $answ; | 
| 147 |  |  |  |  |  |  | } | 
| 148 |  |  |  |  |  |  |  | 
| 149 |  |  |  |  |  |  |  | 
| 150 |  |  |  |  |  |  | =head1 METHODS | 
| 151 |  |  |  |  |  |  |  | 
| 152 |  |  |  |  |  |  | Here are the features that distinguish the registry from the EPP RFC. | 
| 153 |  |  |  |  |  |  | All basic information about functions is in L | 
| 154 |  |  |  |  |  |  |  | 
| 155 |  |  |  |  |  |  | =cut | 
| 156 |  |  |  |  |  |  |  | 
| 157 |  |  |  |  |  |  | sub req_test { | 
| 158 | 166 |  |  | 166 | 1 | 260 | my ( $self, $out_data, $info ) = @_; | 
| 159 |  |  |  |  |  |  |  | 
| 160 | 166 | 100 |  |  |  | 563 | $self->epp_log( "$info request:\n$out_data" ) if $out_data; | 
| 161 |  |  |  |  |  |  |  | 
| 162 | 166 |  |  |  |  | 209 | my $answ; | 
| 163 |  |  |  |  |  |  |  | 
| 164 | 166 | 50 |  |  |  | 308 | if ( $self->{server} eq 'Core' ) { | 
| 165 | 166 |  |  |  |  | 1501 | require IO::EPP::Test::VerisignCore; | 
| 166 |  |  |  |  |  |  |  | 
| 167 |  |  |  |  |  |  | eval{ | 
| 168 | 166 |  |  |  |  | 386 | $answ = IO::EPP::Test::VerisignCore::req( @_ ); | 
| 169 | 166 |  |  |  |  | 343 | 1; | 
| 170 |  |  |  |  |  |  | } | 
| 171 | 166 | 50 |  |  |  | 223 | or do { | 
| 172 | 0 |  |  |  |  | 0 | $self->{critical_error} = "$info req error: $@"; | 
| 173 | 0 |  |  |  |  | 0 | return; | 
| 174 |  |  |  |  |  |  | }; | 
| 175 |  |  |  |  |  |  | } | 
| 176 |  |  |  |  |  |  | else { # DotName, NameStore | 
| 177 | 0 |  |  |  |  | 0 | require IO::EPP::Test::VerisignName; | 
| 178 |  |  |  |  |  |  |  | 
| 179 |  |  |  |  |  |  | eval{ | 
| 180 | 0 |  |  |  |  | 0 | $answ = IO::EPP::Test::VerisignName::req( @_ ); | 
| 181 | 0 |  |  |  |  | 0 | 1; | 
| 182 |  |  |  |  |  |  | } | 
| 183 | 0 | 0 |  |  |  | 0 | or do { | 
| 184 | 0 |  |  |  |  | 0 | $self->{critical_error} = "$info req error: $@"; | 
| 185 | 0 |  |  |  |  | 0 | return; | 
| 186 |  |  |  |  |  |  | }; | 
| 187 |  |  |  |  |  |  | } | 
| 188 |  |  |  |  |  |  |  | 
| 189 | 166 |  |  |  |  | 656 | $self->epp_log( "$info answer:\n$answ" ); | 
| 190 |  |  |  |  |  |  |  | 
| 191 | 166 |  |  |  |  | 390 | return $answ; | 
| 192 |  |  |  |  |  |  | } | 
| 193 |  |  |  |  |  |  |  | 
| 194 |  |  |  |  |  |  |  | 
| 195 |  |  |  |  |  |  | =head2 new | 
| 196 |  |  |  |  |  |  |  | 
| 197 |  |  |  |  |  |  | See description in L | 
| 198 |  |  |  |  |  |  |  | 
| 199 |  |  |  |  |  |  | Requires the C field to be specified, which can have values: | 
| 200 |  |  |  |  |  |  | C for .com/.net/.edu, | 
| 201 |  |  |  |  |  |  | C for .name, | 
| 202 |  |  |  |  |  |  | C for cctld and new gtlds. | 
| 203 |  |  |  |  |  |  |  | 
| 204 |  |  |  |  |  |  | =cut | 
| 205 |  |  |  |  |  |  |  | 
| 206 |  |  |  |  |  |  | sub new { | 
| 207 | 28 |  |  | 28 | 1 | 8275 | my ( $package, $params ) = @_; | 
| 208 |  |  |  |  |  |  |  | 
| 209 | 28 | 0 | 33 |  |  | 67 | unless ( $params->{server}  ||  $params->{dname}  ||  $params->{tld} ) { | 
|  |  |  | 0 |  |  |  |  | 
| 210 | 0 | 0 |  |  |  | 0 | if ( $params->{sock_params}{PeerHost} =~ 'epp.verisign-grs.com' ) { | 
|  |  | 0 |  |  |  |  |  | 
| 211 | 0 |  |  |  |  | 0 | $params->{server} = 'Core'; | 
| 212 |  |  |  |  |  |  | } | 
| 213 |  |  |  |  |  |  | elsif ( $params->{sock_params}{PeerHost} eq 'namestoressl.verisign-grs.com' ) { | 
| 214 | 0 |  |  |  |  | 0 | $params->{server} = 'NameStore'; | 
| 215 |  |  |  |  |  |  | } | 
| 216 |  |  |  |  |  |  | } | 
| 217 |  |  |  |  |  |  |  | 
| 218 | 28 | 0 | 33 |  |  | 65 | unless ( $params->{server}  or  $params->{tld}  or  $params->{dname} ) { | 
|  |  |  | 0 |  |  |  |  | 
| 219 | 0 | 0 |  |  |  | 0 | return wantarray ? ( 0, 0, 'unknown server: Core or DotName, need set server, tld or dname field' ) : 0 ; | 
| 220 |  |  |  |  |  |  | } | 
| 221 |  |  |  |  |  |  |  | 
| 222 | 28 | 100 |  |  |  | 90 | $params->{dname} = lc $params->{dname} if $params->{dname}; | 
| 223 |  |  |  |  |  |  |  | 
| 224 | 28 |  | 100 |  |  | 84 | my $tld = $params->{tld} || ''; | 
| 225 |  |  |  |  |  |  |  | 
| 226 | 28 | 50 | 66 |  |  | 82 | if ( not $tld  and  $params->{dname} ) { | 
| 227 | 0 |  |  |  |  | 0 | ( $tld ) = $params->{dname} =~ /\.([^.]+)$/; | 
| 228 |  |  |  |  |  |  | } | 
| 229 |  |  |  |  |  |  |  | 
| 230 | 28 | 100 | 66 |  |  | 101 | if ( $params->{server}  and  not $tld ) { | 
| 231 | 11 | 50 |  |  |  | 32 | if ( $params->{server} eq 'Core' ) { | 
|  |  | 0 |  |  |  |  |  | 
| 232 | 11 |  |  |  |  | 16 | $tld = 'com'; | 
| 233 |  |  |  |  |  |  | } | 
| 234 |  |  |  |  |  |  | elsif ( $params->{server} eq 'DotName' ) { | 
| 235 | 0 |  |  |  |  | 0 | $tld = 'name'; | 
| 236 |  |  |  |  |  |  | } | 
| 237 |  |  |  |  |  |  | else { | 
| 238 | 0 |  |  |  |  | 0 | $tld = 'tv'; | 
| 239 |  |  |  |  |  |  | } | 
| 240 |  |  |  |  |  |  | } | 
| 241 |  |  |  |  |  |  |  | 
| 242 | 28 | 50 | 33 |  |  | 112 | if ( $tld  and  not $params->{server} ) { | 
| 243 | 0 | 0 |  |  |  | 0 | if ( $tld eq 'name' ) { | 
|  |  | 0 |  |  |  |  |  | 
| 244 | 0 |  |  |  |  | 0 | $params->{server} = 'DotName'; | 
| 245 |  |  |  |  |  |  | } | 
| 246 |  |  |  |  |  |  | elsif ( $tld =~ /^(com|net|edu)$/ ) { | 
| 247 | 0 |  |  |  |  | 0 | $params->{server} = 'Core'; | 
| 248 |  |  |  |  |  |  | } | 
| 249 |  |  |  |  |  |  | else { | 
| 250 | 0 |  |  |  |  | 0 | $params->{server} = 'NameStore'; | 
| 251 |  |  |  |  |  |  | } | 
| 252 |  |  |  |  |  |  | } | 
| 253 |  |  |  |  |  |  |  | 
| 254 | 28 | 50 | 33 |  |  | 70 | $params->{server} = 'DotName' if $tld eq 'name' && $params->{server} ne 'DotName'; | 
| 255 |  |  |  |  |  |  |  | 
| 256 |  |  |  |  |  |  |  | 
| 257 | 28 |  |  |  |  | 75 | my ( $self, $code, $msg ) = $package->SUPER::new( $params ); | 
| 258 |  |  |  |  |  |  |  | 
| 259 | 28 | 50 | 33 |  |  | 103 | unless ( $code  and  $code == 1000 ) { | 
| 260 | 0 | 0 |  |  |  | 0 | return wantarray ? ( 0, $code, $msg ) : 0; | 
| 261 |  |  |  |  |  |  | } | 
| 262 |  |  |  |  |  |  |  | 
| 263 | 28 | 50 |  |  |  | 69 | if ( $tld ) { | 
| 264 | 28 | 50 |  |  |  | 73 | if ( lc ( $tld ) eq 'name' ) { | 
| 265 | 0 |  |  |  |  | 0 | $self->{dzone} = 'name'; | 
| 266 |  |  |  |  |  |  | } | 
| 267 |  |  |  |  |  |  | else { | 
| 268 | 28 |  |  |  |  | 89 | $self->{dzone} = 'dot' . uc( $tld ); | 
| 269 |  |  |  |  |  |  | } | 
| 270 |  |  |  |  |  |  |  | 
| 271 | 28 |  |  |  |  | 105 | $self->{namestore_ext} = "   $sub_product_ext_begin" . $self->{dzone} . "$sub_product_ext_end\n"; | 
| 272 |  |  |  |  |  |  | } | 
| 273 |  |  |  |  |  |  |  | 
| 274 | 28 | 100 |  |  |  | 95 | return wantarray ? ( $self, $code, $msg ) : $self; | 
| 275 |  |  |  |  |  |  | } | 
| 276 |  |  |  |  |  |  |  | 
| 277 |  |  |  |  |  |  |  | 
| 278 |  |  |  |  |  |  | =head2 login | 
| 279 |  |  |  |  |  |  |  | 
| 280 |  |  |  |  |  |  | Ext params for login, | 
| 281 |  |  |  |  |  |  |  | 
| 282 |  |  |  |  |  |  | INPUT: new password for change | 
| 283 |  |  |  |  |  |  |  | 
| 284 |  |  |  |  |  |  | =cut | 
| 285 |  |  |  |  |  |  |  | 
| 286 |  |  |  |  |  |  | sub login { | 
| 287 | 28 |  |  | 28 | 1 | 66 | my ( $self, $pw ) = @_; | 
| 288 |  |  |  |  |  |  |  | 
| 289 | 28 |  |  |  |  | 45 | my $svcs = ' | 
| 290 |  |  |  |  |  |  | urn:ietf:params:xml:ns:domain-1.0 | 
| 291 |  |  |  |  |  |  | urn:ietf:params:xml:ns:host-1.0 | 
| 292 |  |  |  |  |  |  | urn:ietf:params:xml:ns:contact-1.0 | 
| 293 |  |  |  |  |  |  | http://www.verisign.com/epp/lowbalance-poll-1.0'; | 
| 294 |  |  |  |  |  |  |  | 
| 295 | 28 |  |  |  |  | 40 | my $extension = ' | 
| 296 |  |  |  |  |  |  | urn:ietf:params:xml:ns:secDNS-1.1 | 
| 297 |  |  |  |  |  |  | http://www.verisign.com/epp/idnLang-1.0 | 
| 298 |  |  |  |  |  |  | http://www.verisign-grs.com/epp/namestoreExt-1.1 | 
| 299 |  |  |  |  |  |  | urn:ietf:params:xml:ns:rgp-1.0'; | 
| 300 |  |  |  |  |  |  |  | 
| 301 | 28 | 50 |  |  |  | 66 | if ( $self->{server} eq 'Core' ) { | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 302 |  |  |  |  |  |  |  | 
| 303 | 28 |  |  |  |  | 43 | $svcs .= ' | 
| 304 |  |  |  |  |  |  | http://www.verisign.com/epp/registry-1.0 | 
| 305 |  |  |  |  |  |  | http://www.verisign.com/epp/rgp-poll-1.0'; | 
| 306 | 28 |  |  |  |  | 63 | $extension .= ' | 
| 307 |  |  |  |  |  |  | http://www.verisign.com/epp/whoisInf-1.0 | 
| 308 |  |  |  |  |  |  | urn:ietf:params:xml:ns:coa-1.0 | 
| 309 |  |  |  |  |  |  | http://www.verisign.com/epp/sync-1.0 | 
| 310 |  |  |  |  |  |  | http://www.verisign.com/epp/relatedDomain-1.0 | 
| 311 |  |  |  |  |  |  | urn:ietf:params:xml:ns:changePoll-1.0'; | 
| 312 |  |  |  |  |  |  |  | 
| 313 |  |  |  |  |  |  | } | 
| 314 |  |  |  |  |  |  | elsif ( $self->{server} eq 'DotName' ) { | 
| 315 |  |  |  |  |  |  | # moved to NameStore but extension in use | 
| 316 |  |  |  |  |  |  | # https://www.verisign.com/assets/email-forwarding-mapping.pdf | 
| 317 | 0 |  |  |  |  | 0 | $svcs .= ' | 
| 318 |  |  |  |  |  |  | http://www.nic.name/epp/nameWatch-1.0 | 
| 319 |  |  |  |  |  |  | http://www.nic.name/epp/emailFwd-1.0 | 
| 320 |  |  |  |  |  |  | http://www.nic.name/epp/defReg-1.0'; | 
| 321 | 0 |  |  |  |  | 0 | $extension .= ' | 
| 322 |  |  |  |  |  |  | http://www.nic.name/epp/persReg-1.0'; | 
| 323 |  |  |  |  |  |  |  | 
| 324 |  |  |  |  |  |  | } | 
| 325 |  |  |  |  |  |  | elsif ( $self->{server} eq 'NameStore' ) { | 
| 326 |  |  |  |  |  |  |  | 
| 327 | 0 |  |  |  |  | 0 | $svcs .= ' | 
| 328 |  |  |  |  |  |  | http://www.verisign.com/epp/rgp-poll-1.0 | 
| 329 |  |  |  |  |  |  | http://www.verisign.com/epp/balance-1.0 | 
| 330 |  |  |  |  |  |  | http://www.verisign-grs.com/epp/suggestion-1.1 | 
| 331 |  |  |  |  |  |  | http://www.verisign.com/epp/registry-1.0'; | 
| 332 | 0 |  |  |  |  | 0 | $extension .= ' | 
| 333 |  |  |  |  |  |  | http://www.verisign.com/epp/sync-1.0 | 
| 334 |  |  |  |  |  |  | http://www.verisign.com/epp/jobsContact-1.0 | 
| 335 |  |  |  |  |  |  | http://www.verisign.com/epp/premiumdomain-1.0 | 
| 336 |  |  |  |  |  |  | urn:ietf:params:xml:ns:launch-1.0 | 
| 337 |  |  |  |  |  |  | urn:ietf:params:xml:ns:verificationCode-1.0 | 
| 338 |  |  |  |  |  |  | urn:ietf:params:xml:ns:fee-0.9'; | 
| 339 |  |  |  |  |  |  |  | 
| 340 |  |  |  |  |  |  | } | 
| 341 |  |  |  |  |  |  |  | 
| 342 | 28 |  |  |  |  | 92 | return $self->SUPER::login( $pw, $svcs, $extension ); | 
| 343 |  |  |  |  |  |  | } | 
| 344 |  |  |  |  |  |  |  | 
| 345 |  |  |  |  |  |  | =head2 check_contacts | 
| 346 |  |  |  |  |  |  |  | 
| 347 |  |  |  |  |  |  | .com/.net/.edu zones are not currently supported | 
| 348 |  |  |  |  |  |  |  | 
| 349 |  |  |  |  |  |  | For more information, see L | 
| 350 |  |  |  |  |  |  |  | 
| 351 |  |  |  |  |  |  | An Example | 
| 352 |  |  |  |  |  |  |  | 
| 353 |  |  |  |  |  |  | my ( $answ, $msg ) = make_request( 'check_contacts', { tld => 'name', contacts => [ 'PP-SP-001', 'GB789HBHKS' ] } ); | 
| 354 |  |  |  |  |  |  |  | 
| 355 |  |  |  |  |  |  | # answer: | 
| 356 |  |  |  |  |  |  |  | 
| 357 |  |  |  |  |  |  | { | 
| 358 |  |  |  |  |  |  | 'msg' => 'Command completed successfully', | 
| 359 |  |  |  |  |  |  | 'PP-SP-001' => { | 
| 360 |  |  |  |  |  |  | 'avail' => '0' | 
| 361 |  |  |  |  |  |  | }, | 
| 362 |  |  |  |  |  |  | 'GB789HBHKS' => { | 
| 363 |  |  |  |  |  |  | 'avail' => '1' | 
| 364 |  |  |  |  |  |  | }, | 
| 365 |  |  |  |  |  |  | 'BHJVJH' => { | 
| 366 |  |  |  |  |  |  | 'avail' => '1' | 
| 367 |  |  |  |  |  |  | }, | 
| 368 |  |  |  |  |  |  | 'code' => '1000' | 
| 369 |  |  |  |  |  |  | }; | 
| 370 |  |  |  |  |  |  |  | 
| 371 |  |  |  |  |  |  | =cut | 
| 372 |  |  |  |  |  |  |  | 
| 373 |  |  |  |  |  |  | sub check_contacts { | 
| 374 | 0 |  |  | 0 | 1 | 0 | my ( $self, $params ) = @_; | 
| 375 |  |  |  |  |  |  |  | 
| 376 | 0 |  |  |  |  | 0 | $params->{extension} = $self->{namestore_ext}; | 
| 377 |  |  |  |  |  |  |  | 
| 378 | 0 |  |  |  |  | 0 | return $self->SUPER::check_contacts( $params ); | 
| 379 |  |  |  |  |  |  | } | 
| 380 |  |  |  |  |  |  |  | 
| 381 |  |  |  |  |  |  | =head2 create_contact | 
| 382 |  |  |  |  |  |  |  | 
| 383 |  |  |  |  |  |  | You cannot register a contact that has two data types at once -- C and C, | 
| 384 |  |  |  |  |  |  | a contact can have any type, but only one. | 
| 385 |  |  |  |  |  |  |  | 
| 386 |  |  |  |  |  |  | .com/.net/.edu zones are not currently supported. | 
| 387 |  |  |  |  |  |  |  | 
| 388 |  |  |  |  |  |  | For .jobs need additional parameters: | 
| 389 |  |  |  |  |  |  | C, C, C, C. | 
| 390 |  |  |  |  |  |  |  | 
| 391 |  |  |  |  |  |  | About .jobs parameters see L. | 
| 392 |  |  |  |  |  |  |  | 
| 393 |  |  |  |  |  |  | The C /  flag is not supported, and the registry does not display contacts in whois | 
| 394 |  |  |  |  |  |  |  | 
| 395 |  |  |  |  |  |  | For more information, see L. | 
| 396 |  |  |  |  |  |  |  | 
| 397 |  |  |  |  |  |  | Example with C data type | 
| 398 |  |  |  |  |  |  |  | 
| 399 |  |  |  |  |  |  | my %cont = ( | 
| 400 |  |  |  |  |  |  | name       => 'Protection of Private Person', | 
| 401 |  |  |  |  |  |  | org        => 'Private Person', | 
| 402 |  |  |  |  |  |  | addr       => 'PO box 01, Protection Service', | 
| 403 |  |  |  |  |  |  | city       => 'Moscow', | 
| 404 |  |  |  |  |  |  | state      => '', | 
| 405 |  |  |  |  |  |  | postcode   => '125000', | 
| 406 |  |  |  |  |  |  | country_code => 'RU', | 
| 407 |  |  |  |  |  |  | phone      => '+7.4951111111', | 
| 408 |  |  |  |  |  |  | fax        => '+7.4951111111', | 
| 409 |  |  |  |  |  |  | email      => 'my@private.ru', | 
| 410 |  |  |  |  |  |  | ); | 
| 411 |  |  |  |  |  |  |  | 
| 412 |  |  |  |  |  |  | my ( $answ, $msg ) = make_request( 'create_contact', { tld => 'name', %cont } ); | 
| 413 |  |  |  |  |  |  |  | 
| 414 |  |  |  |  |  |  | # answer | 
| 415 |  |  |  |  |  |  | { | 
| 416 |  |  |  |  |  |  | 'msg' => 'Command completed successfully', | 
| 417 |  |  |  |  |  |  | 'cont_id' => '5555LECTU555', | 
| 418 |  |  |  |  |  |  | 'cre_date' => '2020-01-11 11:11:11', | 
| 419 |  |  |  |  |  |  | 'cltrid' => '5552d5cc9ab81c787eb9892eed888888', | 
| 420 |  |  |  |  |  |  | 'code' => 1000, | 
| 421 |  |  |  |  |  |  | 'svtrid' => '8888176177629-666916888' | 
| 422 |  |  |  |  |  |  | }; | 
| 423 |  |  |  |  |  |  |  | 
| 424 |  |  |  |  |  |  | Example with C data type | 
| 425 |  |  |  |  |  |  |  | 
| 426 |  |  |  |  |  |  | my %cont = ( | 
| 427 |  |  |  |  |  |  | loc => { | 
| 428 |  |  |  |  |  |  | name       => 'Защита персональных данных', | 
| 429 |  |  |  |  |  |  | org        => 'Частное лицо', | 
| 430 |  |  |  |  |  |  | addr       => 'А/Я 01, Сервис защиты персональных данных', | 
| 431 |  |  |  |  |  |  | city       => 'Москва', | 
| 432 |  |  |  |  |  |  | state      => '', | 
| 433 |  |  |  |  |  |  | postcode   => '125000', | 
| 434 |  |  |  |  |  |  | country_code => 'RU', | 
| 435 |  |  |  |  |  |  | }, | 
| 436 |  |  |  |  |  |  | phone      => '+7.4951111111', | 
| 437 |  |  |  |  |  |  | fax        => '+7.4951111111', | 
| 438 |  |  |  |  |  |  | email      => 'my@private.ru', | 
| 439 |  |  |  |  |  |  | ); | 
| 440 |  |  |  |  |  |  |  | 
| 441 |  |  |  |  |  |  | my ( $answ, $msg ) = make_request( 'create_contact', { tld => 'name', %cont } ); | 
| 442 |  |  |  |  |  |  |  | 
| 443 |  |  |  |  |  |  | # answer | 
| 444 |  |  |  |  |  |  |  | 
| 445 |  |  |  |  |  |  | { | 
| 446 |  |  |  |  |  |  | 'msg' => 'Command completed successfully', | 
| 447 |  |  |  |  |  |  | 'cont_id' => '5555EMELT555', | 
| 448 |  |  |  |  |  |  | 'cre_date' => '2020-01-11 11:11:11', | 
| 449 |  |  |  |  |  |  | 'cltrid' => '88807717dfcb0ea49d0106697e888888', | 
| 450 |  |  |  |  |  |  | 'code' => 1000, | 
| 451 |  |  |  |  |  |  | 'svtrid' => '8889175980353-666988888' | 
| 452 |  |  |  |  |  |  | }; | 
| 453 |  |  |  |  |  |  |  | 
| 454 |  |  |  |  |  |  | =cut | 
| 455 |  |  |  |  |  |  |  | 
| 456 |  |  |  |  |  |  | sub create_contact { | 
| 457 | 0 |  |  | 0 | 1 | 0 | my ( $self, $params ) = @_; | 
| 458 |  |  |  |  |  |  |  | 
| 459 | 0 |  | 0 |  |  | 0 | $params->{cont_id} ||= IO::EPP::Base::gen_id( 16 ); | 
| 460 |  |  |  |  |  |  |  | 
| 461 | 0 |  |  |  |  | 0 | $params->{authinfo} = IO::EPP::Base::gen_pw( 16 ); | 
| 462 |  |  |  |  |  |  |  | 
| 463 | 0 |  |  |  |  | 0 | my $extension = ''; | 
| 464 |  |  |  |  |  |  |  | 
| 465 | 0 | 0 |  |  |  | 0 | if ( $self->{dzone} eq 'dotJOBS' ) { | 
| 466 | 0 |  |  |  |  | 0 | $extension .= q|   \n|; | 
| 467 | 0 |  |  |  |  | 0 | $extension .=  "    $$params{jobs_title}\n"; | 
| 468 | 0 |  |  |  |  | 0 | $extension .=  "    $$params{jobs_website}\n"; | 
| 469 | 0 |  |  |  |  | 0 | $extension .=  "    $$params{jobs_industry_type}\n"; | 
| 470 | 0 |  |  |  |  | 0 | $extension .=  "    $$params{is_admin}\n"; | 
| 471 | 0 |  |  |  |  | 0 | $extension .=  "    No\n"; | 
| 472 | 0 |  |  |  |  | 0 | $extension .=  "   \n"; | 
| 473 |  |  |  |  |  |  | } | 
| 474 |  |  |  |  |  |  |  | 
| 475 | 0 |  |  |  |  | 0 | $params->{extension} = $extension . $self->{namestore_ext}; | 
| 476 |  |  |  |  |  |  |  | 
| 477 | 0 |  |  |  |  | 0 | return $self->SUPER::create_contact( $params ); | 
| 478 |  |  |  |  |  |  | } | 
| 479 |  |  |  |  |  |  |  | 
| 480 |  |  |  |  |  |  | =head2 get_contact_info | 
| 481 |  |  |  |  |  |  |  | 
| 482 |  |  |  |  |  |  | .com/.net/.edu zones are not currently supported. | 
| 483 |  |  |  |  |  |  |  | 
| 484 |  |  |  |  |  |  | For more information, see L. | 
| 485 |  |  |  |  |  |  |  | 
| 486 |  |  |  |  |  |  | An Example | 
| 487 |  |  |  |  |  |  |  | 
| 488 |  |  |  |  |  |  | my ( $answ, $msg ) = make_request( 'get_contact_info', { tld => 'name', cont_id => '5555LECTU555' } ); | 
| 489 |  |  |  |  |  |  |  | 
| 490 |  |  |  |  |  |  | # answer | 
| 491 |  |  |  |  |  |  |  | 
| 492 |  |  |  |  |  |  | { | 
| 493 |  |  |  |  |  |  | 'int' => { | 
| 494 |  |  |  |  |  |  | 'city' => 'Moscow', | 
| 495 |  |  |  |  |  |  | 'country_code' => 'RU', | 
| 496 |  |  |  |  |  |  | 'name' => 'Protection of Private Person', | 
| 497 |  |  |  |  |  |  | 'postcode' => '125000', | 
| 498 |  |  |  |  |  |  | 'addr' => 'PO box 01, Protection Service', | 
| 499 |  |  |  |  |  |  | 'state' => undef | 
| 500 |  |  |  |  |  |  | }, | 
| 501 |  |  |  |  |  |  | 'roid' => '22222100_CONTACT_NAME-VRSN', | 
| 502 |  |  |  |  |  |  | 'cre_date' => '2020-01-11 11:11:11', | 
| 503 |  |  |  |  |  |  | 'email' => [ | 
| 504 |  |  |  |  |  |  | 'my@private.ru' | 
| 505 |  |  |  |  |  |  | ], | 
| 506 |  |  |  |  |  |  | 'upd_date' => '2020-01-11 11:11:11', | 
| 507 |  |  |  |  |  |  | 'fax' => [ | 
| 508 |  |  |  |  |  |  | '+7.4951111111' | 
| 509 |  |  |  |  |  |  | ], | 
| 510 |  |  |  |  |  |  | 'creater' => 'login', | 
| 511 |  |  |  |  |  |  | 'authinfo' => 'HF+B5ON$,qUDkyYW', | 
| 512 |  |  |  |  |  |  | 'code' => '1000', | 
| 513 |  |  |  |  |  |  | 'owner' => 'LOGIN', | 
| 514 |  |  |  |  |  |  | 'msg' => 'Command completed successfully', | 
| 515 |  |  |  |  |  |  | 'phone' => [ | 
| 516 |  |  |  |  |  |  | '+7.4951111111' | 
| 517 |  |  |  |  |  |  | ], | 
| 518 |  |  |  |  |  |  | 'updater' => 'login', | 
| 519 |  |  |  |  |  |  | 'cont_id' => '5555LECTU555', | 
| 520 |  |  |  |  |  |  | 'statuses' => { | 
| 521 |  |  |  |  |  |  | 'ok' => '+' | 
| 522 |  |  |  |  |  |  | } | 
| 523 |  |  |  |  |  |  | }; | 
| 524 |  |  |  |  |  |  |  | 
| 525 |  |  |  |  |  |  | =cut | 
| 526 |  |  |  |  |  |  |  | 
| 527 |  |  |  |  |  |  | sub get_contact_info { | 
| 528 | 0 |  |  | 0 | 1 | 0 | my ( $self, $params ) = @_; | 
| 529 |  |  |  |  |  |  |  | 
| 530 | 0 |  |  |  |  | 0 | $params->{extension} = $self->{namestore_ext}; | 
| 531 |  |  |  |  |  |  |  | 
| 532 | 0 |  |  |  |  | 0 | return $self->SUPER::get_contact_info( $params ); | 
| 533 |  |  |  |  |  |  | } | 
| 534 |  |  |  |  |  |  |  | 
| 535 |  |  |  |  |  |  |  | 
| 536 |  |  |  |  |  |  | =head2 update_contact | 
| 537 |  |  |  |  |  |  |  | 
| 538 |  |  |  |  |  |  | .com/.net/.edu zones are not currently supported. | 
| 539 |  |  |  |  |  |  |  | 
| 540 |  |  |  |  |  |  | For more information, see L. | 
| 541 |  |  |  |  |  |  |  | 
| 542 |  |  |  |  |  |  | =cut | 
| 543 |  |  |  |  |  |  |  | 
| 544 |  |  |  |  |  |  | sub update_contact { | 
| 545 | 0 |  |  | 0 | 1 | 0 | my ( $self, $params ) = @_; | 
| 546 |  |  |  |  |  |  |  | 
| 547 | 0 |  |  |  |  | 0 | $params->{extension} = $self->{namestore_ext}; | 
| 548 |  |  |  |  |  |  |  | 
| 549 | 0 |  |  |  |  | 0 | return $self->SUPER::update_contact( $params ); | 
| 550 |  |  |  |  |  |  | } | 
| 551 |  |  |  |  |  |  |  | 
| 552 |  |  |  |  |  |  |  | 
| 553 |  |  |  |  |  |  | =head2 delete_contact | 
| 554 |  |  |  |  |  |  |  | 
| 555 |  |  |  |  |  |  | .com/.net/.edu zones are not currently supported. | 
| 556 |  |  |  |  |  |  |  | 
| 557 |  |  |  |  |  |  | For more information, see L. | 
| 558 |  |  |  |  |  |  |  | 
| 559 |  |  |  |  |  |  | =cut | 
| 560 |  |  |  |  |  |  |  | 
| 561 |  |  |  |  |  |  | sub delete_contact { | 
| 562 | 0 |  |  | 0 | 1 | 0 | my ( $self, $params ) = @_; | 
| 563 |  |  |  |  |  |  |  | 
| 564 | 0 |  |  |  |  | 0 | $params->{extension} = $self->{namestore_ext}; | 
| 565 |  |  |  |  |  |  |  | 
| 566 | 0 |  |  |  |  | 0 | return $self->SUPER::delete_contact( $params ); | 
| 567 |  |  |  |  |  |  | } | 
| 568 |  |  |  |  |  |  |  | 
| 569 |  |  |  |  |  |  |  | 
| 570 |  |  |  |  |  |  | sub check_nss { | 
| 571 | 1 |  |  | 1 | 1 | 3 | my ( $self, $params ) = @_; | 
| 572 |  |  |  |  |  |  |  | 
| 573 | 1 |  |  |  |  | 4 | $params->{extension} = $self->{namestore_ext}; | 
| 574 |  |  |  |  |  |  |  | 
| 575 | 1 |  |  |  |  | 6 | return $self->SUPER::check_nss( $params ); | 
| 576 |  |  |  |  |  |  | } | 
| 577 |  |  |  |  |  |  |  | 
| 578 |  |  |  |  |  |  | =head2 create_ns | 
| 579 |  |  |  |  |  |  |  | 
| 580 |  |  |  |  |  |  | Within a single server, all NS-s are shared, that is, | 
| 581 |  |  |  |  |  |  | if you register NS for the .com tld, it will be available for the .net tld as well. | 
| 582 |  |  |  |  |  |  |  | 
| 583 |  |  |  |  |  |  | For details, see L. | 
| 584 |  |  |  |  |  |  |  | 
| 585 |  |  |  |  |  |  | =cut | 
| 586 |  |  |  |  |  |  |  | 
| 587 |  |  |  |  |  |  | sub create_ns { | 
| 588 | 9 |  |  | 9 | 1 | 1006 | my ( $self, $params ) = @_; | 
| 589 |  |  |  |  |  |  |  | 
| 590 | 9 |  |  |  |  | 21 | $params->{extension} = $self->{namestore_ext}; | 
| 591 |  |  |  |  |  |  |  | 
| 592 | 9 |  |  |  |  | 27 | return $self->SUPER::create_ns( $params ); | 
| 593 |  |  |  |  |  |  | } | 
| 594 |  |  |  |  |  |  |  | 
| 595 |  |  |  |  |  |  |  | 
| 596 |  |  |  |  |  |  | sub get_ns_info { | 
| 597 | 4 |  |  | 4 | 1 | 3586 | my ( $self, $params ) = @_; | 
| 598 |  |  |  |  |  |  |  | 
| 599 | 4 |  |  |  |  | 47 | $params->{extension} = $self->{namestore_ext}; | 
| 600 |  |  |  |  |  |  |  | 
| 601 | 4 |  |  |  |  | 20 | return $self->SUPER::get_ns_info( $params ); | 
| 602 |  |  |  |  |  |  | } | 
| 603 |  |  |  |  |  |  |  | 
| 604 |  |  |  |  |  |  |  | 
| 605 |  |  |  |  |  |  | sub update_ns { | 
| 606 | 13 |  |  | 13 | 1 | 13867 | my ( $self, $params ) = @_; | 
| 607 |  |  |  |  |  |  |  | 
| 608 | 13 |  |  |  |  | 27 | $params->{extension} = $self->{namestore_ext}; | 
| 609 |  |  |  |  |  |  |  | 
| 610 | 13 | 50 |  |  |  | 32 | $params->{no_empty_chg} = 1 unless $params->{chg}; | 
| 611 |  |  |  |  |  |  |  | 
| 612 | 13 |  |  |  |  | 35 | return $self->SUPER::update_ns( $params ); | 
| 613 |  |  |  |  |  |  | } | 
| 614 |  |  |  |  |  |  |  | 
| 615 |  |  |  |  |  |  |  | 
| 616 |  |  |  |  |  |  | sub delete_ns { | 
| 617 | 3 |  |  | 3 | 1 | 2460 | my ( $self, $params ) = @_; | 
| 618 |  |  |  |  |  |  |  | 
| 619 | 3 |  |  |  |  | 6 | $params->{extension} = $self->{namestore_ext}; | 
| 620 |  |  |  |  |  |  |  | 
| 621 | 3 |  |  |  |  | 12 | return $self->SUPER::delete_ns( $params ); | 
| 622 |  |  |  |  |  |  | } | 
| 623 |  |  |  |  |  |  |  | 
| 624 |  |  |  |  |  |  | =head2 check_domains | 
| 625 |  |  |  |  |  |  |  | 
| 626 |  |  |  |  |  |  | With a single request, you can check availability in all zones of this server at once, | 
| 627 |  |  |  |  |  |  | if they have accreditation | 
| 628 |  |  |  |  |  |  |  | 
| 629 |  |  |  |  |  |  | In the example, accreditation is not available in the .edu tld. | 
| 630 |  |  |  |  |  |  | The .info tld belongs to a different registry. | 
| 631 |  |  |  |  |  |  |  | 
| 632 |  |  |  |  |  |  | my ( $answ, $msg ) = make_request( 'check_domains', { | 
| 633 |  |  |  |  |  |  | tld => 'com', | 
| 634 |  |  |  |  |  |  | domains => [ 'qwerty.com', 'bjdwferbkr-e3jd0hf.net', 'bjk8bj-kewew.edu', 'xn--xx.com', 'hiebw.info' ] | 
| 635 |  |  |  |  |  |  | } ); | 
| 636 |  |  |  |  |  |  |  | 
| 637 |  |  |  |  |  |  | # answer | 
| 638 |  |  |  |  |  |  |  | 
| 639 |  |  |  |  |  |  | { | 
| 640 |  |  |  |  |  |  | 'msg' => 'Command completed successfully', | 
| 641 |  |  |  |  |  |  | 'qwerty.com' => { | 
| 642 |  |  |  |  |  |  | 'reason' => 'Domain exists', | 
| 643 |  |  |  |  |  |  | 'avail' => '0' | 
| 644 |  |  |  |  |  |  | }, | 
| 645 |  |  |  |  |  |  | 'hiebw.info' => { | 
| 646 |  |  |  |  |  |  | 'reason' => 'Not an authoritative TLD', | 
| 647 |  |  |  |  |  |  | 'avail' => '0' | 
| 648 |  |  |  |  |  |  | }, | 
| 649 |  |  |  |  |  |  | 'bjk8bj-kewew.edu' => { | 
| 650 |  |  |  |  |  |  | 'reason' => 'Not authorized', | 
| 651 |  |  |  |  |  |  | 'avail' => '0' | 
| 652 |  |  |  |  |  |  | }, | 
| 653 |  |  |  |  |  |  | 'code' => '1000', | 
| 654 |  |  |  |  |  |  | 'xn--xx.com' => { | 
| 655 |  |  |  |  |  |  | 'reason' => 'Invalid punycode encoding', | 
| 656 |  |  |  |  |  |  | 'avail' => '0' | 
| 657 |  |  |  |  |  |  | }, | 
| 658 |  |  |  |  |  |  | 'bjdwferbkr-e3jd0hf.net' => { | 
| 659 |  |  |  |  |  |  | 'avail' => '1' | 
| 660 |  |  |  |  |  |  | } | 
| 661 |  |  |  |  |  |  | }; | 
| 662 |  |  |  |  |  |  |  | 
| 663 |  |  |  |  |  |  | For details, see L. | 
| 664 |  |  |  |  |  |  |  | 
| 665 |  |  |  |  |  |  | =cut | 
| 666 |  |  |  |  |  |  |  | 
| 667 |  |  |  |  |  |  | sub check_domains { | 
| 668 | 1 |  |  | 1 | 1 | 2 | my ( $self, $params ) = @_; | 
| 669 |  |  |  |  |  |  |  | 
| 670 | 1 |  |  |  |  | 3 | $params->{extension} = $self->{namestore_ext}; | 
| 671 |  |  |  |  |  |  |  | 
| 672 | 1 |  |  |  |  | 10 | return $self->SUPER::check_domains( $params ); | 
| 673 |  |  |  |  |  |  | } | 
| 674 |  |  |  |  |  |  |  | 
| 675 |  |  |  |  |  |  | =head2 create_domain | 
| 676 |  |  |  |  |  |  |  | 
| 677 |  |  |  |  |  |  | For IDN domains you need to specify the language code in the C field | 
| 678 |  |  |  |  |  |  |  | 
| 679 |  |  |  |  |  |  | See L, | 
| 680 |  |  |  |  |  |  | and L for .com, .net | 
| 681 |  |  |  |  |  |  |  | 
| 682 |  |  |  |  |  |  | An Example of a domain with C, without NSs | 
| 683 |  |  |  |  |  |  |  | 
| 684 |  |  |  |  |  |  | ( $answ, $code, $msg ) = $conn->create_domain( { | 
| 685 |  |  |  |  |  |  | tld => 'com', | 
| 686 |  |  |  |  |  |  | dname => 'xn----htbdjfuifot5a9e.com', # хитрый-домен.com | 
| 687 |  |  |  |  |  |  | period => 1, | 
| 688 |  |  |  |  |  |  | idn_lang => 'RUS' | 
| 689 |  |  |  |  |  |  | } ); | 
| 690 |  |  |  |  |  |  |  | 
| 691 |  |  |  |  |  |  | # answer | 
| 692 |  |  |  |  |  |  |  | 
| 693 |  |  |  |  |  |  | { | 
| 694 |  |  |  |  |  |  | 'dname' => 'xn----htbdjfuifot5a9e.com', | 
| 695 |  |  |  |  |  |  | 'exp_date' => '2021-01-01 01:01:01', | 
| 696 |  |  |  |  |  |  | 'cre_date' => '2020-01-01 01:01:01', | 
| 697 |  |  |  |  |  |  | 'cltrid' => '37777a45e43d0c691c65538aacd77777', | 
| 698 |  |  |  |  |  |  | 'svtrid' => '8888827708-7856526698888' | 
| 699 |  |  |  |  |  |  | }; | 
| 700 |  |  |  |  |  |  |  | 
| 701 |  |  |  |  |  |  | For more information, see L. | 
| 702 |  |  |  |  |  |  |  | 
| 703 |  |  |  |  |  |  | =cut | 
| 704 |  |  |  |  |  |  |  | 
| 705 |  |  |  |  |  |  | sub create_domain { | 
| 706 | 9 |  |  | 9 | 1 | 8690 | my ( $self, $params ) = @_; | 
| 707 |  |  |  |  |  |  |  | 
| 708 | 9 |  | 66 |  |  | 42 | $params->{authinfo} ||= IO::EPP::Base::gen_pw( 16 ); | 
| 709 |  |  |  |  |  |  |  | 
| 710 |  |  |  |  |  |  | # Do not change the order of records | 
| 711 | 9 |  |  |  |  | 16 | my $extension = $self->{namestore_ext}; | 
| 712 |  |  |  |  |  |  |  | 
| 713 | 9 | 50 |  |  |  | 18 | if ( $params->{idn_lang} ) { | 
| 714 | 0 |  |  |  |  | 0 | $extension .= "   $$params{idn_lang}\n"; | 
| 715 |  |  |  |  |  |  | } | 
| 716 |  |  |  |  |  |  |  | 
| 717 | 9 |  |  |  |  | 16 | $params->{extension} = $extension; | 
| 718 |  |  |  |  |  |  |  | 
| 719 | 9 |  |  |  |  | 26 | return $self->SUPER::create_domain( $params ); | 
| 720 |  |  |  |  |  |  | } | 
| 721 |  |  |  |  |  |  |  | 
| 722 |  |  |  |  |  |  |  | 
| 723 |  |  |  |  |  |  | sub transfer { | 
| 724 | 0 |  |  | 0 | 1 | 0 | my ( $self, $params ) = @_; | 
| 725 |  |  |  |  |  |  |  | 
| 726 | 0 | 0 |  |  |  | 0 | if ( defined $params->{authinfo} ) { | 
| 727 | 0 |  |  |  |  | 0 | $params->{authinfo} =~ s/&/&/g; | 
| 728 | 0 |  |  |  |  | 0 | $params->{authinfo} =~ s/</g; | 
| 729 | 0 |  |  |  |  | 0 | $params->{authinfo} =~ s/>/>/g; | 
| 730 |  |  |  |  |  |  | } | 
| 731 |  |  |  |  |  |  |  | 
| 732 | 0 |  |  |  |  | 0 | $params->{extension} = $self->{namestore_ext}; | 
| 733 |  |  |  |  |  |  |  | 
| 734 | 0 |  |  |  |  | 0 | return $self->SUPER::transfer( $params ); | 
| 735 |  |  |  |  |  |  | } | 
| 736 |  |  |  |  |  |  |  | 
| 737 |  |  |  |  |  |  | =head2 get_domain_info | 
| 738 |  |  |  |  |  |  |  | 
| 739 |  |  |  |  |  |  | For details, see L. | 
| 740 |  |  |  |  |  |  |  | 
| 741 |  |  |  |  |  |  | An Example | 
| 742 |  |  |  |  |  |  |  | 
| 743 |  |  |  |  |  |  | my ( $answ, $msg, $conn ) = make_request( 'get_domain_info', { dname => 'llll.com' } ); | 
| 744 |  |  |  |  |  |  |  | 
| 745 |  |  |  |  |  |  | # answer | 
| 746 |  |  |  |  |  |  |  | 
| 747 |  |  |  |  |  |  | { | 
| 748 |  |  |  |  |  |  | 'msg' => 'Command completed successfully', | 
| 749 |  |  |  |  |  |  | 'owner' => '1000', | 
| 750 |  |  |  |  |  |  | 'hosts' => [ | 
| 751 |  |  |  |  |  |  | 'ns2.llll.com', | 
| 752 |  |  |  |  |  |  | 'ns1.llll.com' | 
| 753 |  |  |  |  |  |  | ], | 
| 754 |  |  |  |  |  |  | 'roid' => '2222489946_DOMAIN_COM-VRSN', | 
| 755 |  |  |  |  |  |  | 'exp_date' => '2020-01-01 01:01:01', | 
| 756 |  |  |  |  |  |  | 'cre_date' => '2018-01-01 01:01:01', | 
| 757 |  |  |  |  |  |  | 'nss' => [ | 
| 758 |  |  |  |  |  |  | 'ns1.rrr.ru', | 
| 759 |  |  |  |  |  |  | 'ns2.rrr.ru' | 
| 760 |  |  |  |  |  |  | ], | 
| 761 |  |  |  |  |  |  | 'dname' => 'llll.com', | 
| 762 |  |  |  |  |  |  | 'updater' => 'login', | 
| 763 |  |  |  |  |  |  | 'upd_date' => '2019-12-30 13:17:54', | 
| 764 |  |  |  |  |  |  | 'creater' => 'login', | 
| 765 |  |  |  |  |  |  | 'authinfo' => 'AAA:8k.o5*p"_pAA', | 
| 766 |  |  |  |  |  |  | 'statuses' => { | 
| 767 |  |  |  |  |  |  | 'clientTransferProhibited' => '+' | 
| 768 |  |  |  |  |  |  | }, | 
| 769 |  |  |  |  |  |  | 'code' => 1000 | 
| 770 |  |  |  |  |  |  | }; | 
| 771 |  |  |  |  |  |  |  | 
| 772 |  |  |  |  |  |  | =cut | 
| 773 |  |  |  |  |  |  |  | 
| 774 |  |  |  |  |  |  | sub get_domain_info { | 
| 775 | 10 |  |  | 10 | 1 | 7169 | my ( $self, $params ) = @_; | 
| 776 |  |  |  |  |  |  |  | 
| 777 | 10 |  |  |  |  | 23 | $params->{extension} = $self->{namestore_ext}; | 
| 778 |  |  |  |  |  |  |  | 
| 779 | 10 |  |  |  |  | 35 | return $self->SUPER::get_domain_info( $params ); | 
| 780 |  |  |  |  |  |  | } | 
| 781 |  |  |  |  |  |  |  | 
| 782 |  |  |  |  |  |  |  | 
| 783 |  |  |  |  |  |  | sub renew_domain { | 
| 784 | 6 |  |  | 6 | 1 | 4646 | my ( $self, $params ) = @_; | 
| 785 |  |  |  |  |  |  |  | 
| 786 | 6 |  |  |  |  | 13 | $params->{extension} = $self->{namestore_ext}; | 
| 787 |  |  |  |  |  |  |  | 
| 788 | 6 |  |  |  |  | 20 | return $self->SUPER::renew_domain( $params ); | 
| 789 |  |  |  |  |  |  | } | 
| 790 |  |  |  |  |  |  |  | 
| 791 |  |  |  |  |  |  |  | 
| 792 |  |  |  |  |  |  | sub update_domain { | 
| 793 | 17 |  |  | 17 | 1 | 1550 | my ( $self, $params ) = @_; | 
| 794 |  |  |  |  |  |  |  | 
| 795 | 17 |  |  |  |  | 44 | $params->{extension} = $self->{namestore_ext}; | 
| 796 |  |  |  |  |  |  |  | 
| 797 | 17 |  |  |  |  | 66 | return $self->SUPER::update_domain( $params ); | 
| 798 |  |  |  |  |  |  | } | 
| 799 |  |  |  |  |  |  |  | 
| 800 |  |  |  |  |  |  | =head2 delete_domain | 
| 801 |  |  |  |  |  |  |  | 
| 802 |  |  |  |  |  |  | You can delete a domain only if it does not have NS-s that are used by other domains. | 
| 803 |  |  |  |  |  |  | If there are such NS-s, they should be renamed using the C<< update_ns( chg => { new_name => 'new.ns.xxxx.com' } ) >>, | 
| 804 |  |  |  |  |  |  | For details see L. | 
| 805 |  |  |  |  |  |  |  | 
| 806 |  |  |  |  |  |  | For more information about C, see L | 
| 807 |  |  |  |  |  |  |  | 
| 808 |  |  |  |  |  |  | =cut | 
| 809 |  |  |  |  |  |  |  | 
| 810 |  |  |  |  |  |  | sub delete_domain { | 
| 811 | 6 |  |  | 6 | 1 | 3865 | my ( $self, $params ) = @_; | 
| 812 |  |  |  |  |  |  |  | 
| 813 | 6 |  |  |  |  | 12 | $params->{extension} = $self->{namestore_ext}; | 
| 814 |  |  |  |  |  |  |  | 
| 815 | 6 |  |  |  |  | 23 | return $self->SUPER::delete_domain( $params ); | 
| 816 |  |  |  |  |  |  | } | 
| 817 |  |  |  |  |  |  |  | 
| 818 |  |  |  |  |  |  |  | 
| 819 |  |  |  |  |  |  | =head2 restore_domain | 
| 820 |  |  |  |  |  |  |  | 
| 821 |  |  |  |  |  |  | First call of restore — request | 
| 822 |  |  |  |  |  |  |  | 
| 823 |  |  |  |  |  |  | INPUT: | 
| 824 |  |  |  |  |  |  |  | 
| 825 |  |  |  |  |  |  | params with key: | 
| 826 |  |  |  |  |  |  |  | 
| 827 |  |  |  |  |  |  | C — domain name | 
| 828 |  |  |  |  |  |  |  | 
| 829 |  |  |  |  |  |  | OUTPUT: | 
| 830 |  |  |  |  |  |  | see L. | 
| 831 |  |  |  |  |  |  |  | 
| 832 |  |  |  |  |  |  | =cut | 
| 833 |  |  |  |  |  |  |  | 
| 834 |  |  |  |  |  |  | sub restore_domain { | 
| 835 | 1 |  |  | 1 | 1 | 8 | my ( $self, $params ) = @_; | 
| 836 |  |  |  |  |  |  |  | 
| 837 |  |  |  |  |  |  | $params->{extension} = $self->{namestore_ext} . | 
| 838 | 1 |  |  |  |  | 4 | " | 
| 839 |  |  |  |  |  |  |  | 
| 840 |  |  |  |  |  |  | \n"; | 
| 841 |  |  |  |  |  |  |  | 
| 842 | 1 |  |  |  |  | 4 | return $self->SUPER::update_domain( $params ); | 
| 843 |  |  |  |  |  |  | } | 
| 844 |  |  |  |  |  |  |  | 
| 845 |  |  |  |  |  |  |  | 
| 846 |  |  |  |  |  |  | =head2 confirmations_restore_domain | 
| 847 |  |  |  |  |  |  |  | 
| 848 |  |  |  |  |  |  | Secont call of restore — confirmation | 
| 849 |  |  |  |  |  |  |  | 
| 850 |  |  |  |  |  |  | INPUT: | 
| 851 |  |  |  |  |  |  |  | 
| 852 |  |  |  |  |  |  | params with keys: | 
| 853 |  |  |  |  |  |  |  | 
| 854 |  |  |  |  |  |  | C — domain name | 
| 855 |  |  |  |  |  |  |  | 
| 856 |  |  |  |  |  |  | C   — whois before delete, may be none; | 
| 857 |  |  |  |  |  |  |  | 
| 858 |  |  |  |  |  |  | C  — whois now, may be none; | 
| 859 |  |  |  |  |  |  |  | 
| 860 |  |  |  |  |  |  | C   — domain delete datetime in UTC; | 
| 861 |  |  |  |  |  |  |  | 
| 862 |  |  |  |  |  |  | C  — restore request call datetime in UTC. | 
| 863 |  |  |  |  |  |  |  | 
| 864 |  |  |  |  |  |  | The following fields already contain the required value, they do not need to be passed: | 
| 865 |  |  |  |  |  |  |  | 
| 866 |  |  |  |  |  |  | C — restore reason: "Customer forgot to renew."; | 
| 867 |  |  |  |  |  |  |  | 
| 868 |  |  |  |  |  |  | C — need to write what it is for the client: | 
| 869 |  |  |  |  |  |  | "I agree that the Domain Name has not been restored in order to assume the rights to use or sell the name to myself or for any third party. | 
| 870 |  |  |  |  |  |  | I agree that the information provided in this Restore Report is true to the best of my knowledge, and acknowledge that intentionally supplying false information in the Restore Report shall constitute an incurable material breach of the Registry-Registrar Agreement."; | 
| 871 |  |  |  |  |  |  |  | 
| 872 |  |  |  |  |  |  | C     — additional information, may be empty. | 
| 873 |  |  |  |  |  |  |  | 
| 874 |  |  |  |  |  |  | OUTPUT: | 
| 875 |  |  |  |  |  |  | see L. | 
| 876 |  |  |  |  |  |  |  | 
| 877 |  |  |  |  |  |  | =cut | 
| 878 |  |  |  |  |  |  |  | 
| 879 |  |  |  |  |  |  | sub confirmations_restore_domain { | 
| 880 | 1 |  |  | 1 | 1 | 741 | my ( $self, $params ) = @_; | 
| 881 |  |  |  |  |  |  |  | 
| 882 | 1 |  |  |  |  | 3 | my $extension = $self->{namestore_ext}; | 
| 883 |  |  |  |  |  |  |  | 
| 884 | 1 |  | 50 |  |  | 6 | $params->{pre_data}  ||= 'none'; | 
| 885 | 1 |  | 50 |  |  | 5 | $params->{post_data} ||= 'none'; | 
| 886 |  |  |  |  |  |  |  | 
| 887 | 1 |  |  |  |  | 7 | $params->{extension} = < | 
| 888 |  |  |  |  |  |  | $extension | 
| 889 |  |  |  |  |  |  |  | 
| 890 |  |  |  |  |  |  |  | 
| 891 |  |  |  |  |  |  |  | 
| 892 |  |  |  |  |  |  | $$params{pre_data} | 
| 893 |  |  |  |  |  |  | $$params{post_data} | 
| 894 |  |  |  |  |  |  | $$params{del_time} | 
| 895 |  |  |  |  |  |  | $$params{rest_time} | 
| 896 |  |  |  |  |  |  | Customer forgot to renew. | 
| 897 |  |  |  |  |  |  | I agree that the Domain Name has not been restored in order to assume the rights to use or sell the name to myself or for any third party. | 
| 898 |  |  |  |  |  |  | I agree that the information provided in this Restore Report is true to the best of my knowledge, and acknowledge that intentionally supplying false information in the Restore Report shall constitute an incurable material breach of the Registry-Registrar Agreement. | 
| 899 |  |  |  |  |  |  |  | 
| 900 |  |  |  |  |  |  |  | 
| 901 |  |  |  |  |  |  |  | 
| 902 |  |  |  |  |  |  |  | 
| 903 |  |  |  |  |  |  | RGPEXT | 
| 904 |  |  |  |  |  |  |  | 
| 905 | 1 |  |  |  |  | 3 | return $self->SUPER::update_domain( $params ); | 
| 906 |  |  |  |  |  |  | } | 
| 907 |  |  |  |  |  |  |  | 
| 908 |  |  |  |  |  |  |  | 
| 909 |  |  |  |  |  |  | =head2 req_poll_ext | 
| 910 |  |  |  |  |  |  |  | 
| 911 |  |  |  |  |  |  | Processing a special messages from a poll. | 
| 912 |  |  |  |  |  |  | Now only processing the message about deleting NS. | 
| 913 |  |  |  |  |  |  |  | 
| 914 |  |  |  |  |  |  | An Example | 
| 915 |  |  |  |  |  |  |  | 
| 916 |  |  |  |  |  |  | my ( $answ, $msg, $conn ) = make_request( 'req_poll', \%conn_params ); | 
| 917 |  |  |  |  |  |  |  | 
| 918 |  |  |  |  |  |  | # answer: | 
| 919 |  |  |  |  |  |  |  | 
| 920 |  |  |  |  |  |  | { | 
| 921 |  |  |  |  |  |  | 'roid' => '77777866_HOST_NAME-VRSN', | 
| 922 |  |  |  |  |  |  | 'date' => '2020-01-10 10:10:10', | 
| 923 |  |  |  |  |  |  | 'cre_date' => '2010-01-10 10:15:05', | 
| 924 |  |  |  |  |  |  | 'ips' => [ | 
| 925 |  |  |  |  |  |  | '3.1.1.1' | 
| 926 |  |  |  |  |  |  | ], | 
| 927 |  |  |  |  |  |  | 'upd_date' => '2013-01-01 10:00:01', | 
| 928 |  |  |  |  |  |  | 'qmsg' => 'Unused Objects Policy', | 
| 929 |  |  |  |  |  |  | 'creater' => 'direct', | 
| 930 |  |  |  |  |  |  | 'id' => '2222282', | 
| 931 |  |  |  |  |  |  | 'ext' => { | 
| 932 |  |  |  |  |  |  | 'change' => { | 
| 933 |  |  |  |  |  |  | 'who' => 'ctldbatch', | 
| 934 |  |  |  |  |  |  | 'row_msg' => 'delete', | 
| 935 |  |  |  |  |  |  | 'date' => '2020-01-10 10:00:10.000', | 
| 936 |  |  |  |  |  |  | 'reason' => 'Unused objects policy', | 
| 937 |  |  |  |  |  |  | 'svtrid' => '416801225', | 
| 938 |  |  |  |  |  |  | 'state' => 'before' | 
| 939 |  |  |  |  |  |  | } | 
| 940 |  |  |  |  |  |  | }, | 
| 941 |  |  |  |  |  |  | 'code' => 1301, | 
| 942 |  |  |  |  |  |  | 'msg' => 'Command completed successfully; ack to dequeue', | 
| 943 |  |  |  |  |  |  | 'owner' => 'LOGIN', | 
| 944 |  |  |  |  |  |  | 'count' => '13', | 
| 945 |  |  |  |  |  |  | 'cltrid' => '2222701245bb287334838a273fd22222', | 
| 946 |  |  |  |  |  |  | 'ns' => 'ns1.abuse.name', | 
| 947 |  |  |  |  |  |  | 'updater' => 'ctldbatch', | 
| 948 |  |  |  |  |  |  | 'statuses' => { | 
| 949 |  |  |  |  |  |  | 'ok' => '+' | 
| 950 |  |  |  |  |  |  | }, | 
| 951 |  |  |  |  |  |  | 'svtrid' => '7777770945650-666947777' | 
| 952 |  |  |  |  |  |  | }; | 
| 953 |  |  |  |  |  |  |  | 
| 954 |  |  |  |  |  |  | =cut | 
| 955 |  |  |  |  |  |  |  | 
| 956 |  |  |  |  |  |  | sub req_poll_ext { | 
| 957 | 0 |  |  | 0 | 1 |  | my ( $self, $ext ) = @_; | 
| 958 |  |  |  |  |  |  |  | 
| 959 | 0 |  |  |  |  |  | my %info; | 
| 960 |  |  |  |  |  |  |  | 
| 961 | 0 | 0 |  |  |  |  | if ( $ext =~ m|]+>(.+)|s ) { | 
| 962 | 0 |  |  |  |  |  | $info{change}{'state'} = $1; | 
| 963 | 0 |  |  |  |  |  | my $row = $2; | 
| 964 |  |  |  |  |  |  |  | 
| 965 | 0 | 0 |  |  |  |  | if ( $row =~ s|([^<>]+)|| ) { | 
| 966 | 0 |  |  |  |  |  | $info{change}{date} = $1; | 
| 967 |  |  |  |  |  |  |  | 
| 968 | 0 |  |  |  |  |  | $info{change}{date} =~ s/T/ /; | 
| 969 | 0 |  |  |  |  |  | $info{change}{date} =~ s/Z$//; | 
| 970 |  |  |  |  |  |  | } | 
| 971 |  |  |  |  |  |  |  | 
| 972 | 0 | 0 |  |  |  |  | if ( $row =~ s|([^<>]+)|| ) { | 
| 973 | 0 |  |  |  |  |  | $info{change}{who} = $1; | 
| 974 |  |  |  |  |  |  | } | 
| 975 |  |  |  |  |  |  |  | 
| 976 | 0 | 0 |  |  |  |  | if ( $row =~ s|([^<>]+)|| ) { | 
| 977 | 0 |  |  |  |  |  | $info{change}{svtrid} = $1; | 
| 978 |  |  |  |  |  |  | } | 
| 979 |  |  |  |  |  |  |  | 
| 980 | 0 | 0 |  |  |  |  | if ( $row =~ s|([^<>]+)|| ) { | 
| 981 | 0 |  |  |  |  |  | $info{change}{reason} = $1; | 
| 982 |  |  |  |  |  |  | } | 
| 983 |  |  |  |  |  |  |  | 
| 984 | 0 |  |  |  |  |  | $info{change}{row_msg} = $row; | 
| 985 |  |  |  |  |  |  | } | 
| 986 |  |  |  |  |  |  | else { | 
| 987 | 0 |  |  |  |  |  | $info{ext} = $ext; | 
| 988 |  |  |  |  |  |  | } | 
| 989 |  |  |  |  |  |  |  | 
| 990 | 0 |  |  |  |  |  | return \%info; | 
| 991 |  |  |  |  |  |  | } | 
| 992 |  |  |  |  |  |  |  | 
| 993 |  |  |  |  |  |  |  | 
| 994 |  |  |  |  |  |  | =head2 get_registry_info | 
| 995 |  |  |  |  |  |  |  | 
| 996 |  |  |  |  |  |  | Registry information for the specified zone | 
| 997 |  |  |  |  |  |  |  | 
| 998 |  |  |  |  |  |  | key in params: C | 
| 999 |  |  |  |  |  |  |  | 
| 1000 |  |  |  |  |  |  | An Example: | 
| 1001 |  |  |  |  |  |  |  | 
| 1002 |  |  |  |  |  |  | my ( $answ, $code, $msg ) = $conn->get_registry_info( { tld => 'net' } ); | 
| 1003 |  |  |  |  |  |  |  | 
| 1004 |  |  |  |  |  |  | # answer | 
| 1005 |  |  |  |  |  |  |  | 
| 1006 |  |  |  |  |  |  | { | 
| 1007 |  |  |  |  |  |  | 'alphaNumStart' => 'true', | 
| 1008 |  |  |  |  |  |  | 'max' => [ | 
| 1009 |  |  |  |  |  |  | '13', | 
| 1010 |  |  |  |  |  |  | '13' | 
| 1011 |  |  |  |  |  |  | ], | 
| 1012 |  |  |  |  |  |  | 'language code' => [ | 
| 1013 |  |  |  |  |  |  | 'ARG', | 
| 1014 |  |  |  |  |  |  | 'ASM', | 
| 1015 |  |  |  |  |  |  | 'AST', | 
| 1016 |  |  |  |  |  |  | 'AVE', | 
| 1017 |  |  |  |  |  |  | 'AWA', | 
| 1018 |  |  |  |  |  |  | 'BAK', | 
| 1019 |  |  |  |  |  |  | 'BAL', | 
| 1020 |  |  |  |  |  |  | 'BAN', | 
| 1021 |  |  |  |  |  |  | 'BAS', | 
| 1022 |  |  |  |  |  |  | 'BEL', | 
| 1023 |  |  |  |  |  |  | 'BOS', | 
| 1024 |  |  |  |  |  |  | 'CAR', | 
| 1025 |  |  |  |  |  |  | 'CHE', | 
| 1026 |  |  |  |  |  |  | 'CHV', | 
| 1027 |  |  |  |  |  |  | 'COP', | 
| 1028 |  |  |  |  |  |  | 'COS', | 
| 1029 |  |  |  |  |  |  | 'WEL', | 
| 1030 |  |  |  |  |  |  | 'DIV', | 
| 1031 |  |  |  |  |  |  | 'DOI', | 
| 1032 |  |  |  |  |  |  | 'FIJ', | 
| 1033 |  |  |  |  |  |  | 'FRY', | 
| 1034 |  |  |  |  |  |  | 'GLA', | 
| 1035 |  |  |  |  |  |  | 'GLE', | 
| 1036 |  |  |  |  |  |  | 'GON', | 
| 1037 |  |  |  |  |  |  | 'INC', | 
| 1038 |  |  |  |  |  |  | 'IND', | 
| 1039 |  |  |  |  |  |  | 'INH', | 
| 1040 |  |  |  |  |  |  | 'JAV', | 
| 1041 |  |  |  |  |  |  | 'KAS', | 
| 1042 |  |  |  |  |  |  | 'KAZ', | 
| 1043 |  |  |  |  |  |  | 'KHM', | 
| 1044 |  |  |  |  |  |  | 'KIR', | 
| 1045 |  |  |  |  |  |  | 'LTZ', | 
| 1046 |  |  |  |  |  |  | 'MAO', | 
| 1047 |  |  |  |  |  |  | 'MAY', | 
| 1048 |  |  |  |  |  |  | 'MLT', | 
| 1049 |  |  |  |  |  |  | 'MOL', | 
| 1050 |  |  |  |  |  |  | 'MON', | 
| 1051 |  |  |  |  |  |  | 'OSS', | 
| 1052 |  |  |  |  |  |  | 'PUS', | 
| 1053 |  |  |  |  |  |  | 'SIN', | 
| 1054 |  |  |  |  |  |  | 'SMO', | 
| 1055 |  |  |  |  |  |  | 'SOM', | 
| 1056 |  |  |  |  |  |  | 'SRD', | 
| 1057 |  |  |  |  |  |  | 'TGK', | 
| 1058 |  |  |  |  |  |  | 'YID', | 
| 1059 |  |  |  |  |  |  | 'AFR', | 
| 1060 |  |  |  |  |  |  | 'ALB', | 
| 1061 |  |  |  |  |  |  | 'ARA', | 
| 1062 |  |  |  |  |  |  | 'ARM', | 
| 1063 |  |  |  |  |  |  | 'AZE', | 
| 1064 |  |  |  |  |  |  | 'BAQ', | 
| 1065 |  |  |  |  |  |  | 'BEN', | 
| 1066 |  |  |  |  |  |  | 'BHO', | 
| 1067 |  |  |  |  |  |  | 'TIB', | 
| 1068 |  |  |  |  |  |  | 'BUL', | 
| 1069 |  |  |  |  |  |  | 'BUR', | 
| 1070 |  |  |  |  |  |  | 'CAT', | 
| 1071 |  |  |  |  |  |  | 'CZE', | 
| 1072 |  |  |  |  |  |  | 'CHI', | 
| 1073 |  |  |  |  |  |  | 'DAN', | 
| 1074 |  |  |  |  |  |  | 'GER', | 
| 1075 |  |  |  |  |  |  | 'DUT', | 
| 1076 |  |  |  |  |  |  | 'GRE', | 
| 1077 |  |  |  |  |  |  | 'ENG', | 
| 1078 |  |  |  |  |  |  | 'EST', | 
| 1079 |  |  |  |  |  |  | 'FAO', | 
| 1080 |  |  |  |  |  |  | 'PER', | 
| 1081 |  |  |  |  |  |  | 'FIN', | 
| 1082 |  |  |  |  |  |  | 'FRE', | 
| 1083 |  |  |  |  |  |  | 'GEO', | 
| 1084 |  |  |  |  |  |  | 'GUJ', | 
| 1085 |  |  |  |  |  |  | 'HEB', | 
| 1086 |  |  |  |  |  |  | 'HIN', | 
| 1087 |  |  |  |  |  |  | 'SCR', | 
| 1088 |  |  |  |  |  |  | 'HUN', | 
| 1089 |  |  |  |  |  |  | 'ICE', | 
| 1090 |  |  |  |  |  |  | 'ITA', | 
| 1091 |  |  |  |  |  |  | 'JPN', | 
| 1092 |  |  |  |  |  |  | 'KOR', | 
| 1093 |  |  |  |  |  |  | 'KUR', | 
| 1094 |  |  |  |  |  |  | 'LAO', | 
| 1095 |  |  |  |  |  |  | 'LAV', | 
| 1096 |  |  |  |  |  |  | 'LIT', | 
| 1097 |  |  |  |  |  |  | 'MAC', | 
| 1098 |  |  |  |  |  |  | 'MAL', | 
| 1099 |  |  |  |  |  |  | 'NEP', | 
| 1100 |  |  |  |  |  |  | 'NOR', | 
| 1101 |  |  |  |  |  |  | 'ORI', | 
| 1102 |  |  |  |  |  |  | 'PAN', | 
| 1103 |  |  |  |  |  |  | 'POL', | 
| 1104 |  |  |  |  |  |  | 'POR', | 
| 1105 |  |  |  |  |  |  | 'RAJ', | 
| 1106 |  |  |  |  |  |  | 'RUM', | 
| 1107 |  |  |  |  |  |  | 'RUS', | 
| 1108 |  |  |  |  |  |  | 'SAN', | 
| 1109 |  |  |  |  |  |  | 'SCC', | 
| 1110 |  |  |  |  |  |  | 'SLO', | 
| 1111 |  |  |  |  |  |  | 'SLV', | 
| 1112 |  |  |  |  |  |  | 'SND', | 
| 1113 |  |  |  |  |  |  | 'SPA', | 
| 1114 |  |  |  |  |  |  | 'SWA', | 
| 1115 |  |  |  |  |  |  | 'SWE', | 
| 1116 |  |  |  |  |  |  | 'SYR', | 
| 1117 |  |  |  |  |  |  | 'TAM', | 
| 1118 |  |  |  |  |  |  | 'TEL', | 
| 1119 |  |  |  |  |  |  | 'THA', | 
| 1120 |  |  |  |  |  |  | 'TUR', | 
| 1121 |  |  |  |  |  |  | 'UKR', | 
| 1122 |  |  |  |  |  |  | 'URD', | 
| 1123 |  |  |  |  |  |  | 'UZB', | 
| 1124 |  |  |  |  |  |  | 'VIE' | 
| 1125 |  |  |  |  |  |  | ], | 
| 1126 |  |  |  |  |  |  | 'gracePeriod command:transfer unit:d' => '5', | 
| 1127 |  |  |  |  |  |  | 'gracePeriod command:create unit:d' => '5', | 
| 1128 |  |  |  |  |  |  | 'default unit:y' => [ | 
| 1129 |  |  |  |  |  |  | '1', | 
| 1130 |  |  |  |  |  |  | '1', | 
| 1131 |  |  |  |  |  |  | '1' | 
| 1132 |  |  |  |  |  |  | ], | 
| 1133 |  |  |  |  |  |  | 'gracePeriod command:autorenew unit:d' => '45', | 
| 1134 |  |  |  |  |  |  | 'subProduct' => 'NET', | 
| 1135 |  |  |  |  |  |  | 'idnVersion' => '1.1', | 
| 1136 |  |  |  |  |  |  | 'expression' => [ | 
| 1137 |  |  |  |  |  |  | '[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?', | 
| 1138 |  |  |  |  |  |  | '^(?=.*\\\\d)(?=.*[a-zA-Z])(?=.*[\\\\x21-\\\\x2F\\\\x3A-\\\\x40\\\\x5B-\\\\x60\\\\x7B-\\\\x7E])[\\\\x21-\\\\x7e]{8,32}$', | 
| 1139 |  |  |  |  |  |  | '^([\\-|\\w])+\\.([\\-|\\w])+\\s{0,}$)$' | 
| 1140 |  |  |  |  |  |  | ], | 
| 1141 |  |  |  |  |  |  | 'redemptionPeriod unit:d' => '30', | 
| 1142 |  |  |  |  |  |  | 'encoding' => 'PunyCode', | 
| 1143 |  |  |  |  |  |  | 'max unit:y' => [ | 
| 1144 |  |  |  |  |  |  | '10', | 
| 1145 |  |  |  |  |  |  | '10', | 
| 1146 |  |  |  |  |  |  | '1' | 
| 1147 |  |  |  |  |  |  | ], | 
| 1148 |  |  |  |  |  |  | 'name' => 'NET', | 
| 1149 |  |  |  |  |  |  | 'maxCheckHost' => '20', | 
| 1150 |  |  |  |  |  |  | 'urgent' => 'false', | 
| 1151 |  |  |  |  |  |  | 'default' => '604800', | 
| 1152 |  |  |  |  |  |  | 'onlyDnsChars' => 'true', | 
| 1153 |  |  |  |  |  |  | 'maxCheckDomain' => '20', | 
| 1154 |  |  |  |  |  |  | 'transferHoldPeriod unit:d' => '5', | 
| 1155 |  |  |  |  |  |  | 'digestType' => [ | 
| 1156 |  |  |  |  |  |  | 'SHA-1', | 
| 1157 |  |  |  |  |  |  | 'SHA-256', | 
| 1158 |  |  |  |  |  |  | 'GOST R 34.11-94', | 
| 1159 |  |  |  |  |  |  | 'SHA-384' | 
| 1160 |  |  |  |  |  |  | ], | 
| 1161 |  |  |  |  |  |  | 'alg' => [ | 
| 1162 |  |  |  |  |  |  | 'RSAMD5', | 
| 1163 |  |  |  |  |  |  | 'DH', | 
| 1164 |  |  |  |  |  |  | 'DSA', | 
| 1165 |  |  |  |  |  |  | 'RSASHA1', | 
| 1166 |  |  |  |  |  |  | 'DSA-NSEC3-SHA1', | 
| 1167 |  |  |  |  |  |  | 'RSASHA1-NSEC3-SHA1', | 
| 1168 |  |  |  |  |  |  | 'RSASHA256', | 
| 1169 |  |  |  |  |  |  | 'RSASHA512', | 
| 1170 |  |  |  |  |  |  | 'ECC-GOST', | 
| 1171 |  |  |  |  |  |  | 'ECDSAP256SHA256', | 
| 1172 |  |  |  |  |  |  | 'ECDSAP384SHA384' | 
| 1173 |  |  |  |  |  |  | ], | 
| 1174 |  |  |  |  |  |  | 'startDate' => '2000-01-01T00:00:00Z', | 
| 1175 |  |  |  |  |  |  | 'minLength' => '3', | 
| 1176 |  |  |  |  |  |  | 'status' => [ | 
| 1177 |  |  |  |  |  |  | 'ok', | 
| 1178 |  |  |  |  |  |  | 'serverHold', | 
| 1179 |  |  |  |  |  |  | 'serverRenewProhibited', | 
| 1180 |  |  |  |  |  |  | 'serverTransferProhibited', | 
| 1181 |  |  |  |  |  |  | 'serverUpdateProhibited', | 
| 1182 |  |  |  |  |  |  | 'serverDeleteProhibited', | 
| 1183 |  |  |  |  |  |  | 'redemptionPeriod', | 
| 1184 |  |  |  |  |  |  | 'pendingRestore', | 
| 1185 |  |  |  |  |  |  | 'pendingDelete', | 
| 1186 |  |  |  |  |  |  | 'clientRenewProhibited', | 
| 1187 |  |  |  |  |  |  | 'clientTransferProhibited', | 
| 1188 |  |  |  |  |  |  | 'clientUpdateProhibited', | 
| 1189 |  |  |  |  |  |  | 'clientDeleteProhibited', | 
| 1190 |  |  |  |  |  |  | 'pendingTransfer', | 
| 1191 |  |  |  |  |  |  | 'clientHold', | 
| 1192 |  |  |  |  |  |  | 'ok', | 
| 1193 |  |  |  |  |  |  | 'pendingDelete', | 
| 1194 |  |  |  |  |  |  | 'pendingTransfer', | 
| 1195 |  |  |  |  |  |  | 'serverUpdateProhibited', | 
| 1196 |  |  |  |  |  |  | 'serverDeleteProhibited', | 
| 1197 |  |  |  |  |  |  | 'clientUpdateProhibited', | 
| 1198 |  |  |  |  |  |  | 'clientDeleteProhibited', | 
| 1199 |  |  |  |  |  |  | 'linked' | 
| 1200 |  |  |  |  |  |  | ], | 
| 1201 |  |  |  |  |  |  | 'zoneMember type:equal' => 'NET', | 
| 1202 |  |  |  |  |  |  | 'group' => 'THIN', | 
| 1203 |  |  |  |  |  |  | 'clientDefined' => 'false', | 
| 1204 |  |  |  |  |  |  | 'pendingRestore unit:d' => '7', | 
| 1205 |  |  |  |  |  |  | 'minIP' => [ | 
| 1206 |  |  |  |  |  |  | '1', | 
| 1207 |  |  |  |  |  |  | '0' | 
| 1208 |  |  |  |  |  |  | ], | 
| 1209 |  |  |  |  |  |  | 'extURI required:true' => [ | 
| 1210 |  |  |  |  |  |  | 'urn:ietf:params:xml:ns:coa-1.0', | 
| 1211 |  |  |  |  |  |  | 'http://www.verisign.com/epp/idnLang-1.0', | 
| 1212 |  |  |  |  |  |  | 'urn:ietf:params:xml:ns:secDNS-1.1', | 
| 1213 |  |  |  |  |  |  | 'http://www.verisign-grs.com/epp/namestoreExt-1.1', | 
| 1214 |  |  |  |  |  |  | 'urn:ietf:params:xml:ns:rgp-1.0', | 
| 1215 |  |  |  |  |  |  | 'http://www.verisign.com/epp/whoisInf-1.0', | 
| 1216 |  |  |  |  |  |  | 'http://www.verisign.com/epp/sync-1.0', | 
| 1217 |  |  |  |  |  |  | 'http://www.verisign.com/epp/relatedDomain-1.0', | 
| 1218 |  |  |  |  |  |  | 'urn:ietf:params:xml:ns:launch-1.0' | 
| 1219 |  |  |  |  |  |  | ], | 
| 1220 |  |  |  |  |  |  | 'upDate' => '2013-08-10T21:16:01Z', | 
| 1221 |  |  |  |  |  |  | 'min unit:y' => [ | 
| 1222 |  |  |  |  |  |  | '1', | 
| 1223 |  |  |  |  |  |  | '1', | 
| 1224 |  |  |  |  |  |  | '1' | 
| 1225 |  |  |  |  |  |  | ], | 
| 1226 |  |  |  |  |  |  | 'unicodeVersion' => '6.0', | 
| 1227 |  |  |  |  |  |  | 'commingleAllowed' => 'false', | 
| 1228 |  |  |  |  |  |  | 'pendingDelete unit:d' => '5', | 
| 1229 |  |  |  |  |  |  | 'sharePolicy' => [ | 
| 1230 |  |  |  |  |  |  | 'perSystem', | 
| 1231 |  |  |  |  |  |  | 'perSystem' | 
| 1232 |  |  |  |  |  |  | ], | 
| 1233 |  |  |  |  |  |  | 'min' => [ | 
| 1234 |  |  |  |  |  |  | '0', | 
| 1235 |  |  |  |  |  |  | '0', | 
| 1236 |  |  |  |  |  |  | '1' | 
| 1237 |  |  |  |  |  |  | ], | 
| 1238 |  |  |  |  |  |  | 'idnaVersion' => 'IDNA 2008', | 
| 1239 |  |  |  |  |  |  | 'objURI required:true' => [ | 
| 1240 |  |  |  |  |  |  | 'urn:ietf:params:xml:ns:domain-1.0', | 
| 1241 |  |  |  |  |  |  | 'urn:ietf:params:xml:ns:contact-1.0', | 
| 1242 |  |  |  |  |  |  | 'urn:ietf:params:xml:ns:host-1.0', | 
| 1243 |  |  |  |  |  |  | 'http://www.verisign.com/epp/registry-1.0', | 
| 1244 |  |  |  |  |  |  | 'http://www.verisign.com/epp/lowbalance-poll-1.0', | 
| 1245 |  |  |  |  |  |  | 'http://www.verisign.com/epp/rgp-poll-1.0' | 
| 1246 |  |  |  |  |  |  | ], | 
| 1247 |  |  |  |  |  |  | 'crDate' => '2000-01-01T00:00:00Z', | 
| 1248 |  |  |  |  |  |  | 'premiumSupport' => 'false', | 
| 1249 |  |  |  |  |  |  | 'alphaNumEnd' => 'true', | 
| 1250 |  |  |  |  |  |  | 'gracePeriod command:renew unit:d' => '5', | 
| 1251 |  |  |  |  |  |  | 'maxLength' => '63', | 
| 1252 |  |  |  |  |  |  | 'maxIP' => [ | 
| 1253 |  |  |  |  |  |  | '13', | 
| 1254 |  |  |  |  |  |  | '0' | 
| 1255 |  |  |  |  |  |  | ], | 
| 1256 |  |  |  |  |  |  | 'contactsSupported' => 'false' | 
| 1257 |  |  |  |  |  |  | }; | 
| 1258 |  |  |  |  |  |  |  | 
| 1259 |  |  |  |  |  |  | =cut | 
| 1260 |  |  |  |  |  |  |  | 
| 1261 |  |  |  |  |  |  | sub get_registry_info { | 
| 1262 | 0 |  |  | 0 | 1 |  | my ( $self, $params ) = @_; | 
| 1263 |  |  |  |  |  |  |  | 
| 1264 | 0 |  |  |  |  |  | my $tld = uc( $params->{tld} ); | 
| 1265 |  |  |  |  |  |  |  | 
| 1266 | 0 |  |  |  |  |  | my $cltrid = IO::EPP::Base::get_cltrid(); | 
| 1267 |  |  |  |  |  |  |  | 
| 1268 | 0 |  |  |  |  |  | my $body = < | 
| 1269 |  |  |  |  |  |  | $$self{urn}{head} | 
| 1270 |  |  |  |  |  |  |  | 
| 1271 |  |  |  |  |  |  |  | 
| 1272 |  |  |  |  |  |  |  | 
| 1273 |  |  |  |  |  |  | $tld | 
| 1274 |  |  |  |  |  |  |  | 
| 1275 |  |  |  |  |  |  |  | 
| 1276 |  |  |  |  |  |  | $cltrid | 
| 1277 |  |  |  |  |  |  |  | 
| 1278 |  |  |  |  |  |  |  | 
| 1279 |  |  |  |  |  |  | RINFO | 
| 1280 |  |  |  |  |  |  |  | 
| 1281 | 0 |  |  |  |  |  | my $content = $self->req( $body, 'get_registry_info' ); | 
| 1282 |  |  |  |  |  |  |  | 
| 1283 | 0 | 0 |  |  |  |  | if ( $content =~ /result code=['"](\d+)['"]/ ) { | 
| 1284 | 0 |  |  |  |  |  | my $rcode = $1 + 0; | 
| 1285 |  |  |  |  |  |  |  | 
| 1286 | 0 |  |  |  |  |  | my $msg = ''; | 
| 1287 | 0 | 0 |  |  |  |  | if ( $content =~ /]*>(.+)<\/msg>.+\/result>/s ) { | 
| 1288 | 0 |  |  |  |  |  | $msg = $1; | 
| 1289 |  |  |  |  |  |  | } | 
| 1290 |  |  |  |  |  |  |  | 
| 1291 | 0 |  |  |  |  |  | my %info; | 
| 1292 |  |  |  |  |  |  |  | 
| 1293 |  |  |  |  |  |  | # take the main part and disassemble | 
| 1294 | 0 | 0 |  |  |  |  | if ( $content =~ /(.+)<\/resData>/s ) { | 
| 1295 | 0 |  |  |  |  |  | my $rdata = $1; | 
| 1296 |  |  |  |  |  |  |  | 
| 1297 | 0 |  |  |  |  |  | my @list = $rdata =~ m|(]+>[^<>]+]+>)|g; | 
| 1298 |  |  |  |  |  |  |  | 
| 1299 | 0 |  |  |  |  |  | foreach my $row ( @list ) { | 
| 1300 | 0 | 0 |  |  |  |  | if ( $row =~ m|([^<>]+)]+>| ) { | 
|  |  | 0 |  |  |  |  |  | 
|  |  | 0 |  |  |  |  |  | 
| 1301 | 0 |  |  |  |  |  | my $k = $1; | 
| 1302 |  |  |  |  |  |  |  | 
| 1303 | 0 |  |  |  |  |  | push @{$info{$k}}, $2; | 
|  | 0 |  |  |  |  |  |  | 
| 1304 |  |  |  |  |  |  | } | 
| 1305 |  |  |  |  |  |  | elsif ( $row =~ m|([^<>]+)]+>| ) { | 
| 1306 | 0 |  |  |  |  |  | my $k = "$1 $2:$3"; | 
| 1307 |  |  |  |  |  |  |  | 
| 1308 | 0 |  |  |  |  |  | push @{$info{$k}}, $4; | 
|  | 0 |  |  |  |  |  |  | 
| 1309 |  |  |  |  |  |  | } | 
| 1310 |  |  |  |  |  |  | elsif ( $row =~ m|([^<>]+)]+>| ) { | 
| 1311 | 0 |  |  |  |  |  | my $k = "$1 $2:$3 $4:$5"; | 
| 1312 |  |  |  |  |  |  |  | 
| 1313 | 0 |  |  |  |  |  | push @{$info{$k}}, $6; | 
|  | 0 |  |  |  |  |  |  | 
| 1314 |  |  |  |  |  |  | } | 
| 1315 |  |  |  |  |  |  | } | 
| 1316 |  |  |  |  |  |  |  | 
| 1317 | 0 |  |  |  |  |  | @list = $rdata =~ m|(]+/>)|g; | 
| 1318 |  |  |  |  |  |  |  | 
| 1319 | 0 |  |  |  |  |  | foreach my $row ( @list ) { | 
| 1320 | 0 | 0 |  |  |  |  | if ( $row =~ m|| ) { | 
| 1321 | 0 |  |  |  |  |  | my $k .= "$1 $2"; | 
| 1322 |  |  |  |  |  |  |  | 
| 1323 | 0 |  |  |  |  |  | push @{$info{$k}}, "$3"; | 
|  | 0 |  |  |  |  |  |  | 
| 1324 |  |  |  |  |  |  | } | 
| 1325 |  |  |  |  |  |  | } | 
| 1326 |  |  |  |  |  |  |  | 
| 1327 | 0 |  |  |  |  |  | foreach my $k ( keys %info ) { | 
| 1328 | 0 | 0 |  |  |  |  | if ( ( scalar @{$info{$k}} ) == 1 ) { | 
|  | 0 |  |  |  |  |  |  | 
| 1329 | 0 |  |  |  |  |  | $info{$k} = $info{$k}[0]; | 
| 1330 |  |  |  |  |  |  | } | 
| 1331 |  |  |  |  |  |  | } | 
| 1332 |  |  |  |  |  |  | } | 
| 1333 |  |  |  |  |  |  | else { | 
| 1334 | 0 | 0 |  |  |  |  | return wantarray ? ( 0, $rcode, $msg ) : 0 ; | 
| 1335 |  |  |  |  |  |  | } | 
| 1336 |  |  |  |  |  |  |  | 
| 1337 | 0 | 0 |  |  |  |  | return wantarray ? ( \%info, $rcode, $msg ) : \%info; | 
| 1338 |  |  |  |  |  |  | } | 
| 1339 |  |  |  |  |  |  |  | 
| 1340 | 0 | 0 |  |  |  |  | return wantarray ? ( 0, 0, 'empty answer' ) : 0 ; | 
| 1341 |  |  |  |  |  |  | } | 
| 1342 |  |  |  |  |  |  |  | 
| 1343 |  |  |  |  |  |  |  | 
| 1344 |  |  |  |  |  |  | 1; | 
| 1345 |  |  |  |  |  |  |  | 
| 1346 |  |  |  |  |  |  |  | 
| 1347 |  |  |  |  |  |  | __END__ |