Removed version number from file header.
[kai/samba.git] / source3 / nmbd / asyncdns.c
index ee3fdfcd17ca5b6de6848188ad13ea61b5b968ae..c5ff718836c0b90af7e6ad53e09780fd7cd7ce5e 100644 (file)
@@ -1,5 +1,5 @@
 /*
-   Unix SMB/Netbios implementation.
+   Unix SMB/CIFS implementation.
    a async DNS handler
    Copyright (C) Andrew Tridgell 1997-1998
    
@@ -20,8 +20,6 @@
 
 #include "includes.h"
 
-extern int DEBUGLEVEL;
-
 /***************************************************************************
   Add a DNS result to the name cache.
 ****************************************************************************/
@@ -35,16 +33,16 @@ static struct name_record *add_dns_result(struct nmb_name *question, struct in_a
   if (!addr.s_addr) {
     /* add the fail to WINS cache of names. give it 1 hour in the cache */
     DEBUG(3,("add_dns_result: Negative DNS answer for %s\n", qname));
-    add_name_to_subnet(wins_server_subnet,qname,name_type,
-                       NB_ACTIVE, 60*60, DNSFAIL_NAME, 1, &addr);
-    return NULL;
+    (void)add_name_to_subnet( wins_server_subnet, qname, name_type,
+                              NB_ACTIVE, 60*60, DNSFAIL_NAME, 1, &addr );
+    return( NULL );
   }
 
   /* add it to our WINS cache of names. give it 2 hours in the cache */
   DEBUG(3,("add_dns_result: DNS gave answer for %s of %s\n", qname, inet_ntoa(addr)));
 
-  return add_name_to_subnet(wins_server_subnet,qname,name_type,
-                            NB_ACTIVE, 2*60*60, DNS_NAME, 1, &addr);
+  return( add_name_to_subnet( wins_server_subnet, qname, name_type,
+                              NB_ACTIVE, 2*60*60, DNS_NAME, 1, &addr ) );
 }
 
 
@@ -52,7 +50,7 @@ static struct name_record *add_dns_result(struct nmb_name *question, struct in_a
 #ifndef SYNC_DNS
 
 static int fd_in = -1, fd_out = -1;
-static int child_pid = -1;
+static pid_t child_pid = -1;
 static int in_dns;
 
 /* this is the structure that is passed between the parent and child */
@@ -103,17 +101,27 @@ static void asyncdns_process(void)
 }
 
 /**************************************************************************** **
-  catch a sigterm
+  catch a sigterm (in the child process - the parent has a different handler
+  see nmbd.c for details).
   We need a separate term handler here so we don't release any 
   names that our parent is going to release, or overwrite a 
   WINS db that our parent is going to write.
  **************************************************************************** */
 
-static int sig_term()
+static void sig_term(int sig)
 {
   _exit(0);
-  /* Keep compiler happy.. */
-  return 0;
+}
+
+/***************************************************************************
+ Called by the parent process when it receives a SIGTERM - also kills the
+ child so we don't get child async dns processes lying around, causing trouble.
+  ****************************************************************************/
+
+void kill_async_dns_child(void)
+{
+  if(child_pid != 0 && child_pid != -1)
+    kill(child_pid, SIGTERM);
 }
 
 /***************************************************************************
@@ -123,29 +131,31 @@ void start_async_dns(void)
 {
        int fd1[2], fd2[2];
 
-       signal(SIGCLD, SIG_IGN);
+       CatchChild();
 
        if (pipe(fd1) || pipe(fd2)) {
+               DEBUG(0,("can't create asyncdns pipes\n"));
                return;
        }
 
-       child_pid = fork();
+       child_pid = sys_fork();
 
        if (child_pid) {
                fd_in = fd1[0];
                fd_out = fd2[1];
                close(fd1[1]);
                close(fd2[0]);
+               DEBUG(0,("started asyncdns process %d\n", (int)child_pid));
                return;
        }
 
        fd_in = fd2[0];
        fd_out = fd1[1];
 
-       signal(SIGUSR2, SIG_IGN);
-       signal(SIGUSR1, SIG_IGN);
-       signal(SIGHUP, SIG_IGN);
-        signal(SIGTERM, SIGNAL_CAST sig_term );
+       CatchSignal(SIGUSR2, SIG_IGN);
+       CatchSignal(SIGUSR1, SIG_IGN);
+       CatchSignal(SIGHUP, SIG_IGN);
+        CatchSignal(SIGTERM, SIGNAL_CAST sig_term );
 
        asyncdns_process();
 }
@@ -187,6 +197,9 @@ void run_dns_queue(void)
        if (fd_in == -1)
                return;
 
+        /* Allow SIGTERM to kill us. */
+        BlockSignals(False, SIGTERM);
+
        if (!process_exists(child_pid)) {
                close(fd_in);
                start_async_dns();
@@ -197,9 +210,12 @@ void run_dns_queue(void)
                        DEBUG(0,("Incomplete DNS answer from child!\n"));
                        fd_in = -1;
                }
+                BlockSignals(True, SIGTERM);
                return;
        }
 
+        BlockSignals(True, SIGTERM);
+
        namerec = add_dns_result(&r.name, r.result);
 
        if (dns_current) {
@@ -287,7 +303,7 @@ BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
                dns_queue = p;
        }
 
-       DEBUG(3,("added DNS query for %s\n", namestr(question)));
+       DEBUG(3,("added DNS query for %s\n", nmb_namestr(question)));
        return True;
 }
 
@@ -295,7 +311,7 @@ BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
 
 
 /***************************************************************************
-  we use this then we can't do async DNS lookups
+  we use this when we can't do async DNS lookups
   ****************************************************************************/
 BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
                     struct name_record **n)
@@ -303,10 +319,16 @@ BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
        char *qname = question->name;
        struct in_addr dns_ip;
 
-       DEBUG(3,("DNS search for %s - ", namestr(question)));
+       DEBUG(3,("DNS search for %s - ", nmb_namestr(question)));
+
+        /* Unblock TERM signal so we can be killed in DNS lookup. */
+        BlockSignals(False, SIGTERM);
 
        dns_ip.s_addr = interpret_addr(qname);
 
+        /* Re-block TERM signal. */
+        BlockSignals(True, SIGTERM);
+
        *n = add_dns_result(question, dns_ip);
         if(*n == NULL)
           send_wins_name_query_response(NAM_ERR, p, NULL);
@@ -314,4 +336,12 @@ BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
           send_wins_name_query_response(0, p, *n);
        return False;
 }
+
+/***************************************************************************
+ With sync dns there is no child to kill on SIGTERM.
+  ****************************************************************************/
+void kill_async_dns_child(void)
+{
+  return;
+}
 #endif