+ my ($pid, $client, $hostinfo);
+
+ while ($client = $server->accept()) {
+ &log("Forking to handle client request") if (defined($opts{v}));
+ next if $pid = fork; # parent
+ die "fork: $!" unless defined $pid;
+
+ # child
+ $client->autoflush(1);
+ my $hostinfo = gethostbyaddr($client->peeraddr, AF_INET);
+ &log(sprintf("[Connect from %s]", $hostinfo || $client->peerhost));
+ my $query = &readdata($client);
+ &ProcessQuery($client, $query) if (defined($query));
+ $client->close;
+ exit;
+ } continue {
+ $client->close;
+ }
+} else { # inetd
+ &log("inetd mode");
+ my $sockaddr = getpeername(STDIN);
+ if ($sockaddr) {
+ my ($port, $addr) = unpack_sockaddr_in(getpeername(STDIN));
+ &log(sprintf("[Connect from %s (%s)]", gethostbyaddr($addr, AF_INET), inet_ntoa($addr)));
+ } else {
+ &log("[Connect via terminal]");
+ }
+ my $query = &readdata(\*STDIN);
+ &ProcessQuery(\*STDOUT, $query) if (defined($query));
+ exit;
+}
+
+$ldap->unbind;
+
+sub DieHandler {
+ $ldap->unbind if (defined($ldap));
+ exit 0;
+}
+
+sub Reaper {
+ 1 until (-1 == waitpid(-1, WNOHANG));
+ $SIG{CHLD} = \&Reaper;
+}
+
+sub ProcessQuery {
+ my $client = shift;
+ my $query = shift;
+
+ my ($uid, $fields, $mesg, $entries, $dn, $key, $pid, $data);