File Coverage

blib/lib/Net/Server/Proto/UNIX.pm
Criterion Covered Total %
statement 42 73 57.5
branch 16 42 38.1
condition 4 21 19.0
subroutine 13 19 68.4
pod 3 15 20.0
total 78 170 45.8


line stmt bran cond sub pod time code
1             # -*- perl -*-
2             #
3             # Net::Server::Proto::UNIX - Net::Server Protocol module
4             #
5             # Copyright (C) 2001-2022
6             #
7             # Paul Seamons
8             #
9             # This package may be distributed under the terms of either the
10             # GNU General Public License
11             # or the
12             # Perl Artistic License
13             #
14             # All rights reserved.
15             #
16             ################################################################
17              
18             package Net::Server::Proto::UNIX;
19              
20 1     1   10 use strict;
  1         3  
  1         52  
21 1     1   7 use Carp qw(croak);
  1         2  
  1         98  
22 1     1   9 use base qw(IO::Socket::UNIX);
  1         2  
  1         218  
23 1     1   7 use Socket qw(SOCK_STREAM SOCK_DGRAM SOMAXCONN);
  1         2  
  1         1793  
24              
25 6     6 0 19 sub NS_proto { 'UNIX' }
26 21 100   21 0 42 sub NS_port { my $sock = shift; ${*$sock}{'NS_port'} = shift if @_; return ${*$sock}{'NS_port'} }
  21         99  
  8         30  
  21         37  
  21         84  
27 11     11 0 35 sub NS_host { '*' }
28 11     11 0 73 sub NS_ipv { '*' }
29 6 100   6 0 12 sub NS_listen { my $sock = shift; ${*$sock}{'NS_listen'} = shift if @_; return ${*$sock}{'NS_listen'} }
  6         16  
  4         10  
  6         9  
  6         15  
30 2     2 1 8 sub NS_unix_type { 'SOCK_STREAM' }
31 2     2 1 153 sub NS_unix_path { shift->NS_port } # legacy systems used this
32              
33             sub object {
34 6     6 0 17 my ($class, $info, $server) = @_;
35              
36 6 50       18 if ($class eq __PACKAGE__) {
37             $server->configure({
38             unix_type => \$server->{'server'}->{'unix_type'},
39             unix_path => \$server->{'server'}->{'unix_path'}, # I don't believe this ever worked since a valid port specification also has to exist
40 6 50       100 }) if ! exists $server->{'server'}->{'unix_type'};
41             my $u_type = uc( defined($info->{'unix_type'}) ? $info->{'unix_type'}
42 6 50       38 : defined($server->{'server'}->{'unix_type'}) ? $server->{'server'}->{'unix_type'}
    100          
43             : 'SOCK_STREAM');
44 6 100 66     33 if ($u_type eq 'SOCK_DGRAM' || $u_type eq ''.SOCK_DGRAM()) { # allow for legacy invocations passing unix_type to UNIX - now just use proto UNIXDGRAM
    50 33        
45 2         9 require Net::Server::Proto::UNIXDGRAM;
46 2         57 return Net::Server::Proto::UNIXDGRAM->object($info, $server);
47             } elsif ($u_type ne 'SOCK_STREAM' && $u_type ne ''.SOCK_STREAM()) {
48 0         0 $server->fatal("Invalid type for UNIX socket ($u_type)... must be SOCK_STREAM or SOCK_DGRAM");
49             }
50 4   33     13 $info->{'port'} ||= $info->{'unix_path'} = $server->{'server'}->{'unix_path'};
51             }
52              
53 4         28 my $sock = $class->SUPER::new();
54 4 50       462 my $port = $info->{'port'} =~ m{^ ([\w\.\-\*\/]+) $ }x ? $1 : $server->fatal("Insecure filename");
55 4         17 $sock->NS_port($port);
56             $sock->NS_listen(defined($info->{'listen'}) ? $info->{'listen'}
57 4 50       25 : defined($server->{'server'}->{'listen'}) ? $server->{'server'}->{'listen'}
    100          
58             : SOMAXCONN);
59 4         26 return $sock;
60             }
61              
62             sub connect {
63 0     0 0 0 my ($sock, $server) = @_;
64 0         0 my $path = $sock->NS_port;
65 0 0 0     0 $server->fatal("Can't connect to UNIX socket at file $path [$!]") if -e $path && ! unlink $path;
66              
67 0 0       0 $sock->SUPER::configure({
68             Local => $path,
69             Type => SOCK_STREAM,
70             Listen => $sock->NS_listen,
71             }) or $server->fatal("Can't connect to UNIX socket at file $path [$!]");
72             }
73              
74             sub log_connect {
75 0     0 0 0 my ($sock, $server) = @_;
76 0         0 $server->log(2, "Binding to ".$sock->NS_proto." socket file \"".$sock->NS_port."\"");
77             }
78              
79             sub reconnect { # connect on a sig -HUP
80 0     0 0 0 my ($sock, $fd, $server) = @_;
81 0 0       0 $sock->fdopen($fd, 'w') or $server->fatal("Error opening to file descriptor ($fd) [$!]");
82             }
83              
84             sub accept {
85 0     0 1 0 my ($sock, $class) = (@_);
86 0         0 my ($client, $peername);
87 0 0       0 if (wantarray) {
88 0         0 ($client, $peername) = $sock->SUPER::accept($class);
89             } else {
90 0         0 $client = $sock->SUPER::accept($class);
91             }
92 0 0       0 if (defined $client) {
93 0         0 $client->NS_port($sock->NS_port);
94             }
95 0 0       0 return wantarray ? ($client, $peername) : $client;
96             }
97              
98             # a string containing any information necessary for restarting the server
99             # via a -HUP signal
100             # a newline is not allowed
101             # the hup_string must be a unique identifier based on configuration info
102             sub hup_string {
103 8     8 0 2132 my $sock = shift;
104 8         24 return join "|", $sock->NS_host, $sock->NS_port, $sock->NS_proto, $sock->NS_ipv;
105             }
106              
107             sub show {
108 0     0 0   my $sock = shift;
109 0           return "Ref = \"".ref($sock). "\" (".$sock->hup_string.")\n";
110             }
111              
112             ###----------------------------------------------------------------###
113              
114             sub read_until { # only sips the data - but it allows for compatibility with SSLEAY
115 0     0 0   my ($client, $bytes, $end_qr) = @_;
116 0 0 0       croak "read_until: One of bytes or end_qr should be defined" if !defined($bytes) && !defined($end_qr);
117 0           my $content = '';
118 0           my $ok = 0;
119 0           while (1) {
120 0           $client->read($content, 1, length($content));
121 0 0 0       if (defined($bytes) && length($content) >= $bytes) {
    0 0        
122 0           $ok = 2;
123 0           last;
124             } elsif (defined($end_qr) && $content =~ $end_qr) {
125 0           $ok = 1;
126 0           last;
127             }
128             }
129 0 0         return wantarray ? ($ok, $content) : $content;
130             }
131              
132             1;
133              
134             __END__