Fix for termination problems when no interfaces found - bug #5267.
[samba.git] / source / nmbd / nmbd.c
1 /*
2    Unix SMB/CIFS implementation.
3    NBT netbios routines and daemon - version 2
4    Copyright (C) Andrew Tridgell 1994-1998
5    Copyright (C) Jeremy Allison 1997-2002
6    Copyright (C) Jelmer Vernooij 2002,2003 (Conversion to popt)
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21    
22 */
23
24 #include "includes.h"
25
26 int ClientNMB       = -1;
27 int ClientDGRAM     = -1;
28 int global_nmb_port = -1;
29
30 extern BOOL rescan_listen_set;
31 extern struct in_addr loopback_ip;
32 extern BOOL global_in_nmbd;
33
34 extern BOOL override_logfile;
35
36 /* are we running as a daemon ? */
37 static BOOL is_daemon;
38
39 /* fork or run in foreground ? */
40 static BOOL Fork = True;
41
42 /* log to standard output ? */
43 static BOOL log_stdout;
44
45 /* have we found LanMan clients yet? */
46 BOOL found_lm_clients = False;
47
48 /* what server type are we currently */
49
50 time_t StartupTime = 0;
51
52 /**************************************************************************** **
53  Handle a SIGTERM in band.
54  **************************************************************************** */
55
56 static void terminate(void)
57 {
58         DEBUG(0,("Got SIGTERM: going down...\n"));
59   
60         /* Write out wins.dat file if samba is a WINS server */
61         wins_write_database(0,False);
62   
63         /* Remove all SELF registered names from WINS */
64         release_wins_names();
65   
66         /* Announce all server entries as 0 time-to-live, 0 type. */
67         announce_my_servers_removed();
68
69         /* If there was an async dns child - kill it. */
70         kill_async_dns_child();
71
72         exit(0);
73 }
74
75 /**************************************************************************** **
76  Handle a SHUTDOWN message from smbcontrol.
77  **************************************************************************** */
78
79 static void nmbd_terminate(int msg_type, struct process_id src,
80                            void *buf, size_t len, void *private_data)
81 {
82         terminate();
83 }
84
85 /**************************************************************************** **
86  Catch a SIGTERM signal.
87  **************************************************************************** */
88
89 static SIG_ATOMIC_T got_sig_term;
90
91 static void sig_term(int sig)
92 {
93         got_sig_term = 1;
94         sys_select_signal(SIGTERM);
95 }
96
97 /**************************************************************************** **
98  Catch a SIGHUP signal.
99  **************************************************************************** */
100
101 static SIG_ATOMIC_T reload_after_sighup;
102
103 static void sig_hup(int sig)
104 {
105         reload_after_sighup = 1;
106         sys_select_signal(SIGHUP);
107 }
108
109 /**************************************************************************** **
110  Possibly continue after a fault.
111  **************************************************************************** */
112
113 static void fault_continue(void)
114 {
115         dump_core();
116 }
117
118 /**************************************************************************** **
119  Expire old names from the namelist and server list.
120  **************************************************************************** */
121
122 static void expire_names_and_servers(time_t t)
123 {
124         static time_t lastrun = 0;
125   
126         if ( !lastrun )
127                 lastrun = t;
128         if ( t < (lastrun + 5) )
129                 return;
130         lastrun = t;
131
132         /*
133          * Expire any timed out names on all the broadcast
134          * subnets and those registered with the WINS server.
135          * (nmbd_namelistdb.c)
136          */
137
138         expire_names(t);
139
140         /*
141          * Go through all the broadcast subnets and for each
142          * workgroup known on that subnet remove any expired
143          * server names. If a workgroup has an empty serverlist
144          * and has itself timed out then remove the workgroup.
145          * (nmbd_workgroupdb.c)
146          */
147
148         expire_workgroups_and_servers(t);
149 }
150
151 /************************************************************************** **
152  Reload the list of network interfaces.
153  Doesn't return until a network interface is up.
154  ************************************************************************** */
155
156 static void reload_interfaces(time_t t)
157 {
158         static time_t lastt;
159         int n;
160         struct subnet_record *subrec;
161
162         if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) {
163                 return;
164         }
165         lastt = t;
166
167         if (!interfaces_changed()) {
168                 return;
169         }
170
171   try_again:
172
173         /* the list of probed interfaces has changed, we may need to add/remove
174            some subnets */
175         load_interfaces();
176
177
178         /* find any interfaces that need adding */
179         for (n=iface_count() - 1; n >= 0; n--) {
180                 struct interface *iface = get_interface(n);
181
182                 if (!iface) {
183                         DEBUG(2,("reload_interfaces: failed to get interface %d\n", n));
184                         continue;
185                 }
186
187                 /*
188                  * We don't want to add a loopback interface, in case
189                  * someone has added 127.0.0.1 for smbd, nmbd needs to
190                  * ignore it here. JRA.
191                  */
192
193                 if (ip_equal(iface->ip, loopback_ip)) {
194                         DEBUG(2,("reload_interfaces: Ignoring loopback interface %s\n", inet_ntoa(iface->ip)));
195                         continue;
196                 }
197
198                 for (subrec=subnetlist; subrec; subrec=subrec->next) {
199                         if (ip_equal(iface->ip, subrec->myip) &&
200                             ip_equal(iface->nmask, subrec->mask_ip)) break;
201                 }
202
203                 if (!subrec) {
204                         /* it wasn't found! add it */
205                         DEBUG(2,("Found new interface %s\n", 
206                                  inet_ntoa(iface->ip)));
207                         subrec = make_normal_subnet(iface);
208                         if (subrec)
209                                 register_my_workgroup_one_subnet(subrec);
210                 }
211         }
212
213         /* find any interfaces that need deleting */
214         for (subrec=subnetlist; subrec; subrec=subrec->next) {
215                 for (n=iface_count() - 1; n >= 0; n--) {
216                         struct interface *iface = get_interface(n);
217                         if (ip_equal(iface->ip, subrec->myip) &&
218                             ip_equal(iface->nmask, subrec->mask_ip)) break;
219                 }
220                 if (n == -1) {
221                         /* oops, an interface has disapeared. This is
222                          tricky, we don't dare actually free the
223                          interface as it could be being used, so
224                          instead we just wear the memory leak and
225                          remove it from the list of interfaces without
226                          freeing it */
227                         DEBUG(2,("Deleting dead interface %s\n", 
228                                  inet_ntoa(subrec->myip)));
229                         close_subnet(subrec);
230                 }
231         }
232
233         rescan_listen_set = True;
234
235         /* We need to wait if there are no subnets... */
236         if (FIRST_SUBNET == NULL) {
237
238                 DEBUG(0,("reload_interfaces: "
239                         "No subnets to listen to. Waiting..\n"));
240
241                 /*
242                  * Whilst we're waiting for an interface, allow SIGTERM to
243                  * cause us to exit.
244                  */
245
246                 BlockSignals(false, SIGTERM);
247
248                 while (iface_count() == 0 && !got_sig_term) {
249                         sleep(5);
250                         load_interfaces();
251                 }
252
253                 /*
254                  * Handle termination inband.
255                  */
256
257                 if (got_sig_term) {
258                         got_sig_term = 0;
259                         terminate();
260                 }
261
262                 /*
263                  * We got an interface, go back to blocking term.
264                  */
265
266                 BlockSignals(true, SIGTERM);
267                 goto try_again;
268         }
269 }
270
271 /**************************************************************************** **
272  Reload the services file.
273  **************************************************************************** */
274
275 static BOOL reload_nmbd_services(BOOL test)
276 {
277         BOOL ret;
278
279         set_remote_machine_name("nmbd", False);
280
281         if ( lp_loaded() ) {
282                 pstring fname;
283                 pstrcpy( fname,lp_configfile());
284                 if (file_exist(fname,NULL) && !strcsequal(fname,dyn_CONFIGFILE)) {
285                         pstrcpy(dyn_CONFIGFILE,fname);
286                         test = False;
287                 }
288         }
289
290         if ( test && !lp_file_list_changed() )
291                 return(True);
292
293         ret = lp_load( dyn_CONFIGFILE, True , False, False, True);
294
295         /* perhaps the config filename is now set */
296         if ( !test ) {
297                 DEBUG( 3, ( "services not loaded\n" ) );
298                 reload_nmbd_services( True );
299         }
300
301         return(ret);
302 }
303
304 /**************************************************************************** **
305  * React on 'smbcontrol nmbd reload-config' in the same way as to SIGHUP
306  **************************************************************************** */
307
308 static void msg_reload_nmbd_services(int msg_type, struct process_id src,
309                                      void *buf, size_t len, void *private_data)
310 {
311         write_browse_list( 0, True );
312         dump_all_namelists();
313         reload_nmbd_services( True );
314         reopen_logs();
315         reload_interfaces(0);
316 }
317
318 static void msg_nmbd_send_packet(int msg_type, struct process_id src,
319                                  void *buf, size_t len, void *private_data)
320 {
321         struct packet_struct *p = (struct packet_struct *)buf;
322         struct subnet_record *subrec;
323         struct in_addr *local_ip;
324
325         DEBUG(10, ("Received send_packet from %d\n", procid_to_pid(&src)));
326
327         if (len != sizeof(struct packet_struct)) {
328                 DEBUG(2, ("Discarding invalid packet length from %d\n",
329                           procid_to_pid(&src)));
330                 return;
331         }
332
333         if ((p->packet_type != NMB_PACKET) &&
334             (p->packet_type != DGRAM_PACKET)) {
335                 DEBUG(2, ("Discarding invalid packet type from %d: %d\n",
336                           procid_to_pid(&src), p->packet_type));
337                 return;
338         }
339
340         local_ip = iface_ip(p->ip);
341
342         if (local_ip == NULL) {
343                 DEBUG(2, ("Could not find ip for packet from %d\n",
344                           procid_to_pid(&src)));
345                 return;
346         }
347
348         subrec = FIRST_SUBNET;
349
350         p->fd = (p->packet_type == NMB_PACKET) ?
351                 subrec->nmb_sock : subrec->dgram_sock;
352
353         for (subrec = FIRST_SUBNET; subrec != NULL;
354              subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
355                 if (ip_equal(*local_ip, subrec->myip)) {
356                         p->fd = (p->packet_type == NMB_PACKET) ?
357                                 subrec->nmb_sock : subrec->dgram_sock;
358                         break;
359                 }
360         }
361
362         if (p->packet_type == DGRAM_PACKET) {
363                 p->port = 138;
364                 p->packet.dgram.header.source_ip.s_addr = local_ip->s_addr;
365                 p->packet.dgram.header.source_port = 138;
366         }
367
368         send_packet(p);
369 }
370
371 /**************************************************************************** **
372  The main select loop.
373  **************************************************************************** */
374
375 static void process(void)
376 {
377         BOOL run_election;
378
379         while( True ) {
380                 time_t t = time(NULL);
381
382                 /* Check for internal messages */
383
384                 message_dispatch();
385
386                 /*
387                  * Check all broadcast subnets to see if
388                  * we need to run an election on any of them.
389                  * (nmbd_elections.c)
390                  */
391
392                 run_election = check_elections();
393
394                 /*
395                  * Read incoming UDP packets.
396                  * (nmbd_packets.c)
397                  */
398
399                 if(listen_for_packets(run_election))
400                         return;
401
402                 /*
403                  * Handle termination inband.
404                  */
405
406                 if (got_sig_term) {
407                         got_sig_term = 0;
408                         terminate();
409                 }
410
411                 /*
412                  * Process all incoming packets
413                  * read above. This calls the success and
414                  * failure functions registered when response
415                  * packets arrrive, and also deals with request
416                  * packets from other sources.
417                  * (nmbd_packets.c)
418                  */
419
420                 run_packet_queue();
421
422                 /*
423                  * Run any elections - initiate becoming
424                  * a local master browser if we have won.
425                  * (nmbd_elections.c)
426                  */
427
428                 run_elections(t);
429
430                 /*
431                  * Send out any broadcast announcements
432                  * of our server names. This also announces
433                  * the workgroup name if we are a local
434                  * master browser.
435                  * (nmbd_sendannounce.c)
436                  */
437
438                 announce_my_server_names(t);
439
440                 /*
441                  * Send out any LanMan broadcast announcements
442                  * of our server names.
443                  * (nmbd_sendannounce.c)
444                  */
445
446                 announce_my_lm_server_names(t);
447
448                 /*
449                  * If we are a local master browser, periodically
450                  * announce ourselves to the domain master browser.
451                  * This also deals with syncronising the domain master
452                  * browser server lists with ourselves as a local
453                  * master browser.
454                  * (nmbd_sendannounce.c)
455                  */
456
457                 announce_myself_to_domain_master_browser(t);
458
459                 /*
460                  * Fullfill any remote announce requests.
461                  * (nmbd_sendannounce.c)
462                  */
463
464                 announce_remote(t);
465
466                 /*
467                  * Fullfill any remote browse sync announce requests.
468                  * (nmbd_sendannounce.c)
469                  */
470
471                 browse_sync_remote(t);
472
473                 /*
474                  * Scan the broadcast subnets, and WINS client
475                  * namelists and refresh any that need refreshing.
476                  * (nmbd_mynames.c)
477                  */
478
479                 refresh_my_names(t);
480
481                 /*
482                  * Scan the subnet namelists and server lists and
483                  * expire thos that have timed out.
484                  * (nmbd.c)
485                  */
486
487                 expire_names_and_servers(t);
488
489                 /*
490                  * Write out a snapshot of our current browse list into
491                  * the browse.dat file. This is used by smbd to service
492                  * incoming NetServerEnum calls - used to synchronise
493                  * browse lists over subnets.
494                  * (nmbd_serverlistdb.c)
495                  */
496
497                 write_browse_list(t, False);
498
499                 /*
500                  * If we are a domain master browser, we have a list of
501                  * local master browsers we should synchronise browse
502                  * lists with (these are added by an incoming local
503                  * master browser announcement packet). Expire any of
504                  * these that are no longer current, and pull the server
505                  * lists from each of these known local master browsers.
506                  * (nmbd_browsesync.c)
507                  */
508
509                 dmb_expire_and_sync_browser_lists(t);
510
511                 /*
512                  * Check that there is a local master browser for our
513                  * workgroup for all our broadcast subnets. If one
514                  * is not found, start an election (which we ourselves
515                  * may or may not participate in, depending on the
516                  * setting of the 'local master' parameter.
517                  * (nmbd_elections.c)
518                  */
519
520                 check_master_browser_exists(t);
521
522                 /*
523                  * If we are configured as a logon server, attempt to
524                  * register the special NetBIOS names to become such
525                  * (WORKGROUP<1c> name) on all broadcast subnets and
526                  * with the WINS server (if used). If we are configured
527                  * to become a domain master browser, attempt to register
528                  * the special NetBIOS name (WORKGROUP<1b> name) to
529                  * become such.
530                  * (nmbd_become_dmb.c)
531                  */
532
533                 add_domain_names(t);
534
535                 /*
536                  * If we are a WINS server, do any timer dependent
537                  * processing required.
538                  * (nmbd_winsserver.c)
539                  */
540
541                 initiate_wins_processing(t);
542
543                 /*
544                  * If we are a domain master browser, attempt to contact the
545                  * WINS server to get a list of all known WORKGROUPS/DOMAINS.
546                  * This will only work to a Samba WINS server.
547                  * (nmbd_browsesync.c)
548                  */
549
550                 if (lp_enhanced_browsing())
551                         collect_all_workgroup_names_from_wins_server(t);
552
553                 /*
554                  * Go through the response record queue and time out or re-transmit
555                  * and expired entries.
556                  * (nmbd_packets.c)
557                  */
558
559                 retransmit_or_expire_response_records(t);
560
561                 /*
562                  * check to see if any remote browse sync child processes have completed
563                  */
564
565                 sync_check_completion();
566
567                 /*
568                  * regularly sync with any other DMBs we know about 
569                  */
570
571                 if (lp_enhanced_browsing())
572                         sync_all_dmbs(t);
573
574                 /*
575                  * clear the unexpected packet queue 
576                  */
577
578                 clear_unexpected(t);
579
580                 /*
581                  * Reload the services file if we got a sighup.
582                  */
583
584                 if(reload_after_sighup) {
585                         DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) );
586                         msg_reload_nmbd_services(MSG_SMB_CONF_UPDATED,
587                                                  pid_to_procid(0), NULL, 0, NULL);
588                         reload_after_sighup = 0;
589                 }
590
591                 /* check for new network interfaces */
592
593                 reload_interfaces(t);
594
595                 /* free up temp memory */
596                 lp_TALLOC_FREE();
597         }
598 }
599
600 /**************************************************************************** **
601  Open the socket communication.
602  **************************************************************************** */
603
604 static BOOL open_sockets(BOOL isdaemon, int port)
605 {
606         /*
607          * The sockets opened here will be used to receive broadcast
608          * packets *only*. Interface specific sockets are opened in
609          * make_subnet() in namedbsubnet.c. Thus we bind to the
610          * address "0.0.0.0". The parameter 'socket address' is
611          * now deprecated.
612          */
613
614         if ( isdaemon )
615                 ClientNMB = open_socket_in(SOCK_DGRAM, port,
616                                            0, interpret_addr(lp_socket_address()),
617                                            True);
618         else
619                 ClientNMB = 0;
620   
621         ClientDGRAM = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
622                                            3, interpret_addr(lp_socket_address()),
623                                            True);
624
625         if ( ClientNMB == -1 )
626                 return( False );
627
628         /* we are never interested in SIGPIPE */
629         BlockSignals(True,SIGPIPE);
630
631         set_socket_options( ClientNMB,   "SO_BROADCAST" );
632         set_socket_options( ClientDGRAM, "SO_BROADCAST" );
633
634         /* Ensure we're non-blocking. */
635         set_blocking( ClientNMB, False);
636         set_blocking( ClientDGRAM, False);
637
638         DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
639         return( True );
640 }
641
642 /**************************************************************************** **
643  main program
644  **************************************************************************** */
645  int main(int argc, const char *argv[])
646 {
647         pstring logfile;
648         static BOOL opt_interactive;
649         poptContext pc;
650         static char *p_lmhosts = dyn_LMHOSTSFILE;
651         static BOOL no_process_group = False;
652         struct poptOption long_options[] = {
653         POPT_AUTOHELP
654         {"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon(default)" },
655         {"interactive", 'i', POPT_ARG_VAL, &opt_interactive, True, "Run interactive (not a daemon)" },
656         {"foreground", 'F', POPT_ARG_VAL, &Fork, False, "Run daemon in foreground (for daemontools & etc)" },
657         {"no-process-group", 0, POPT_ARG_VAL, &no_process_group, True, "Don't create a new process group" },
658         {"log-stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout" },
659         {"hosts", 'H', POPT_ARG_STRING, &p_lmhosts, 'H', "Load a netbios hosts file"},
660         {"port", 'p', POPT_ARG_INT, &global_nmb_port, NMB_PORT, "Listen on the specified port" },
661         POPT_COMMON_SAMBA
662         { NULL }
663         };
664
665         load_case_tables();
666
667         global_nmb_port = NMB_PORT;
668
669         pc = poptGetContext("nmbd", argc, argv, long_options, 0);
670         while (poptGetNextOpt(pc) != -1) {};
671         poptFreeContext(pc);
672
673         global_in_nmbd = True;
674         
675         StartupTime = time(NULL);
676         
677         sys_srandom(time(NULL) ^ sys_getpid());
678         
679         if (!override_logfile) {
680                 slprintf(logfile, sizeof(logfile)-1, "%s/log.nmbd", dyn_LOGFILEBASE);
681                 lp_set_logfile(logfile);
682         }
683         
684         fault_setup((void (*)(void *))fault_continue );
685         dump_core_setup("nmbd");
686         
687         /* POSIX demands that signals are inherited. If the invoking process has
688          * these signals masked, we will have problems, as we won't receive them. */
689         BlockSignals(False, SIGHUP);
690         BlockSignals(False, SIGUSR1);
691         BlockSignals(False, SIGTERM);
692         
693         CatchSignal( SIGHUP,  SIGNAL_CAST sig_hup );
694         CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
695         
696 #if defined(SIGFPE)
697         /* we are never interested in SIGFPE */
698         BlockSignals(True,SIGFPE);
699 #endif
700
701         /* We no longer use USR2... */
702 #if defined(SIGUSR2)
703         BlockSignals(True, SIGUSR2);
704 #endif
705
706         if ( opt_interactive ) {
707                 Fork = False;
708                 log_stdout = True;
709         }
710
711         if ( log_stdout && Fork ) {
712                 DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
713                 exit(1);
714         }
715
716         setup_logging( argv[0], log_stdout );
717
718         reopen_logs();
719
720         DEBUG( 0, ( "Netbios nameserver version %s started.\n", SAMBA_VERSION_STRING) );
721         DEBUGADD( 0, ( "%s\n", COPYRIGHT_STARTUP_MESSAGE ) );
722
723         if ( !reload_nmbd_services(False) )
724                 return(-1);
725
726         if(!init_names())
727                 return -1;
728
729         reload_nmbd_services( True );
730
731         if (strequal(lp_workgroup(),"*")) {
732                 DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
733                 exit(1);
734         }
735
736         set_samba_nb_type();
737
738         if (!is_daemon && !is_a_socket(0)) {
739                 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
740                 is_daemon = True;
741         }
742   
743         if (is_daemon && !opt_interactive) {
744                 DEBUG( 2, ( "Becoming a daemon.\n" ) );
745                 become_daemon(Fork, no_process_group);
746         }
747
748 #if HAVE_SETPGID
749         /*
750          * If we're interactive we want to set our own process group for 
751          * signal management.
752          */
753         if (opt_interactive && !no_process_group)
754                 setpgid( (pid_t)0, (pid_t)0 );
755 #endif
756
757 #ifndef SYNC_DNS
758         /* Setup the async dns. We do it here so it doesn't have all the other
759                 stuff initialised and thus chewing memory and sockets */
760         if(lp_we_are_a_wins_server() && lp_dns_proxy()) {
761                 start_async_dns();
762         }
763 #endif
764
765         if (!directory_exist(lp_lockdir(), NULL)) {
766                 mkdir(lp_lockdir(), 0755);
767         }
768
769         pidfile_create("nmbd");
770         message_init();
771         message_register(MSG_FORCE_ELECTION, nmbd_message_election, NULL);
772 #if 0
773         /* Until winsrepl is done. */
774         message_register(MSG_WINS_NEW_ENTRY, nmbd_wins_new_entry, NULL);
775 #endif
776         message_register(MSG_SHUTDOWN, nmbd_terminate, NULL);
777         message_register(MSG_SMB_CONF_UPDATED, msg_reload_nmbd_services, NULL);
778         message_register(MSG_SEND_PACKET, msg_nmbd_send_packet, NULL);
779
780         TimeInit();
781
782         DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
783
784         if ( !open_sockets( is_daemon, global_nmb_port ) ) {
785                 kill_async_dns_child();
786                 return 1;
787         }
788
789         /* Determine all the IP addresses we have. */
790         load_interfaces();
791
792         /* Create an nmbd subnet record for each of the above. */
793         if( False == create_subnets() ) {
794                 DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
795                 kill_async_dns_child();
796                 exit(1);
797         }
798
799         /* Load in any static local names. */ 
800         load_lmhosts_file(p_lmhosts);
801         DEBUG(3,("Loaded hosts file %s\n", p_lmhosts));
802
803         /* If we are acting as a WINS server, initialise data structures. */
804         if( !initialise_wins() ) {
805                 DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
806                 kill_async_dns_child();
807                 exit(1);
808         }
809
810         /* 
811          * Register nmbd primary workgroup and nmbd names on all
812          * the broadcast subnets, and on the WINS server (if specified).
813          * Also initiate the startup of our primary workgroup (start
814          * elections if we are setup as being able to be a local
815          * master browser.
816          */
817
818         if( False == register_my_workgroup_and_names() ) {
819                 DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
820                 kill_async_dns_child();
821                 exit(1);
822         }
823
824         /* We can only take signals in the select. */
825         BlockSignals( True, SIGTERM );
826
827         process();
828
829         if (dbf)
830                 x_fclose(dbf);
831         kill_async_dns_child();
832         return(0);
833 }