Mail-SpamAssassin

 view release on metacpan or  search on metacpan

spamd/spamd.raw  view on Meta::CPAN

      # make sure not to enter this socket into @listen_sockets,
      # otherwise exit handlers would unlink it!
      die "spamd: already running on $path, exiting\n";
    }
    else {
      dbg("spamd: removing stale socket file $path");
      unlink $path;
    }
  }
  if (not -d (File::Spec->splitpath($path))[1]) {
    die "spamd: directory for $path does not exist, exiting\n";
  }

  my %socket = (
    Local  => $path,
    Type   => &SOCK_STREAM,
    Listen => &SOMAXCONN,
  );
  dbg("spamd: creating UNIX socket:\n" . join("\n", map { " $_: " . (defined $socket{$_} ? $socket{$_} : "(undef)") } sort keys %socket));
  my $server_unix = IO::Socket::UNIX->new(%socket);
  
  # sanity check!  cf. bug 3490
  if (not $server_unix or not -S $path) {
    unless ($server_unix) {
      dbg "spamd: socket path might have been truncated due to system limits\n";
      die "spamd: could not create UNIX socket on $path: $!\n";
    }
    my $hostpath = $server_unix->hostpath();
    if ($hostpath ne $path) {
      warn "spamd: socket path was truncated at position " . length($hostpath) . "\n";
      warn "spamd: leaving stale socket at $hostpath\n" if -S $hostpath;
      die "spamd: path length for UNIX socket on $path exceeds system limit, exiting\n";
    }
    else {
      die "spamd: could not find newly-created UNIX socket on $path: $!\n";
    }
  }

  my $mode = $opt{socketmode};
  if ($mode) {
    $mode = oct $mode;
  } else {
    $mode = 0666;        # default
  }

  my $owner = $opt{socketowner};
  my $group = $opt{socketgroup};
  if ($owner || $group) {
    my $uid = -1;
    my $gid = -1;
    if ($owner) {
      my ($login,$pass,$puid,$pgid) = getpwnam($owner)
                           or die "spamd: $owner not in passwd database\n";
      $uid = $puid;
    }
    if ($group) {
      my ($name,$pass,$ggid,$members) = getgrnam($group)
                           or die "spamd: $group not in group database\n";
      $gid = $ggid;
    }
    if (!chown $uid, $gid, $path) {
      die "spamd: could not chown $path to $uid/$gid: $!";
    }
  }

  if (!chmod $mode, $path) {    # make sure everybody can talk to it
    die "spamd: could not chmod $path to $mode: $!";
  }

  push(@listen_sockets, { specs => $socket_specs,
                          path => $path,
                          socket => $server_unix,
                          fd => $server_unix->fileno })  if $server_unix;
  1;
}

sub server_sock_setup_inet {
  my($socket_specs, $addr, $port, $ssl) = @_;

  $have_inet4 || $have_inet6
    or warn "spamd: neither the PF_INET (IPv4) nor the PF_INET6 (IPv6) ".
            "protocol families seem to be available, pushing our luck anyway\n";

  my $ai_family = &AF_UNSPEC;  # defaults to any address family (i.e. both)
  if      ($have_inet6 && (!$have_inet4 || $opt{'force_ipv6'})) {
    $ai_family = &AF_INET6;
  } elsif ($have_inet4 && (!$have_inet6 || $opt{'force_ipv4'})) {
    $ai_family = &AF_INET;
  }
  my($error, @addresses);
  if (!defined $addr || lc $addr eq 'localhost') {  # loopback interface
    push(@addresses, '::1')
      if $ai_family == &AF_UNSPEC || $ai_family == &AF_INET6;
    push(@addresses, '127.0.0.1')
      if $ai_family == &AF_UNSPEC || $ai_family == &AF_INET;
  } elsif ($addr eq '*' || $addr eq '') {  # any address
    push(@addresses, '::')
      if $ai_family == &AF_UNSPEC || $ai_family == &AF_INET6;
    push(@addresses, '0.0.0.0')
      if $ai_family == &AF_UNSPEC || $ai_family == &AF_INET;
  } else {
    ($error, @addresses) = ip_or_name_to_ip_addresses($addr, $ai_family);
  }
  die "spamd: invalid address for a listen socket: \"$socket_specs\": $error\n"
    if $error;
  die "spamd: no valid address for a listen socket: \"$socket_specs\"\n"
    if !@addresses;

  dbg("spamd: attempting to listen on IP addresses: %s, port %d",
      join(', ',@addresses), $port);
  my(@diag_succ, @diag_fail);
  for my $adr (@addresses) {
    my %sockopt = (
      LocalAddr => $adr,
      LocalPort => $port,
      Type      => &SOCK_STREAM,
      Proto     => 'tcp',
      ReuseAddr => 1,
      Listen    => &SOMAXCONN,
    );
    $sockopt{V6Only} = 1  if $io_socket_module_name eq 'IO::Socket::IP'
                             && IO::Socket::IP->VERSION >= 0.09;



( run in 2.180 seconds using v1.01-cache-2.11-cpan-71847e10f99 )