Got medieval on another pointless extern. Removed extern struct ipzero
[tprouty/samba.git] / source3 / nmbd / nmbd.c
1 /*
2    Unix SMB/Netbios implementation.
3    NBT netbios routines and daemon - version 2
4    Copyright (C) Andrew Tridgell 1994-1998
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19    
20    Revision History:
21
22    14 jan 96: lkcl@pires.co.uk
23    added multiple workgroup domain master support
24
25 */
26
27 #include "includes.h"
28
29 extern pstring debugf;
30
31 int ClientNMB       = -1;
32 int ClientDGRAM     = -1;
33 int global_nmb_port = -1;
34
35 extern pstring global_myname;
36 extern fstring global_myworkgroup;
37 extern char **my_netbios_names;
38
39 extern BOOL global_in_nmbd;
40
41 /* are we running as a daemon ? */
42 static BOOL is_daemon = False;
43
44 /* have we found LanMan clients yet? */
45 BOOL found_lm_clients = False;
46
47 /* what server type are we currently */
48
49 time_t StartupTime = 0;
50
51 /**************************************************************************** **
52   catch a sigterm
53  **************************************************************************** */
54 static void sig_term(int sig)
55 {
56   BlockSignals(True,SIGTERM);
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(False);
62   
63   /* Remove all SELF registered names. */
64   release_my_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 } /* sig_term */
75
76 /**************************************************************************** **
77  catch a sighup
78  **************************************************************************** */
79 static VOLATILE sig_atomic_t reload_after_sighup = False;
80
81 static void sig_hup(int sig)
82 {
83   BlockSignals( True, SIGHUP );
84
85   DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) );
86
87   write_browse_list( 0, True );
88
89   dump_all_namelists();
90
91   reload_after_sighup = True;
92
93   BlockSignals(False,SIGHUP);
94
95 } /* sig_hup */
96
97
98 #if DUMP_CORE
99 /**************************************************************************** **
100  prepare to dump a core file - carefully!
101  **************************************************************************** */
102 static BOOL dump_core(void)
103 {
104   char *p;
105   pstring dname;
106   pstrcpy( dname, debugf );
107   if ((p=strrchr_m(dname,'/')))
108     *p=0;
109   pstrcat( dname, "/corefiles" );
110   mkdir( dname, 0700 );
111   sys_chown( dname, getuid(), getgid() );
112   chmod( dname, 0700 );
113   if ( chdir(dname) )
114     return( False );
115   umask( ~(0700) );
116
117 #ifdef HAVE_GETRLIMIT
118 #ifdef RLIMIT_CORE
119   {
120     struct rlimit rlp;
121     getrlimit( RLIMIT_CORE, &rlp );
122     rlp.rlim_cur = MAX( 4*1024*1024, rlp.rlim_cur );
123     setrlimit( RLIMIT_CORE, &rlp );
124     getrlimit( RLIMIT_CORE, &rlp );
125     DEBUG( 3, ( "Core limits now %d %d\n", (int)rlp.rlim_cur, (int)rlp.rlim_max ) );
126   }
127 #endif
128 #endif
129
130
131   DEBUG(0,("Dumping core in %s\n",dname));
132   abort();
133   return( True );
134 } /* dump_core */
135 #endif
136
137
138 /**************************************************************************** **
139  possibly continue after a fault
140  **************************************************************************** */
141 static void fault_continue(void)
142 {
143 #if DUMP_CORE
144   dump_core();
145 #endif
146 } /* fault_continue */
147
148 /**************************************************************************** **
149  expire old names from the namelist and server list
150  **************************************************************************** */
151 static void expire_names_and_servers(time_t t)
152 {
153   static time_t lastrun = 0;
154   
155   if ( !lastrun )
156     lastrun = t;
157   if ( t < (lastrun + 5) )
158     return;
159   lastrun = t;
160
161   /*
162    * Expire any timed out names on all the broadcast
163    * subnets and those registered with the WINS server.
164    * (nmbd_namelistdb.c)
165    */
166   expire_names(t);
167
168   /*
169    * Go through all the broadcast subnets and for each
170    * workgroup known on that subnet remove any expired
171    * server names. If a workgroup has an empty serverlist
172    * and has itself timed out then remove the workgroup.
173    * (nmbd_workgroupdb.c)
174    */
175   expire_workgroups_and_servers(t);
176 } /* expire_names_and_servers */
177
178
179 /************************************************************************** **
180 reload the list of network interfaces
181  ************************************************************************** */
182 static BOOL reload_interfaces(time_t t)
183 {
184         static time_t lastt;
185         int n;
186         struct subnet_record *subrec;
187         extern BOOL rescan_listen_set;
188         extern struct in_addr loopback_ip;
189
190         if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) return False;
191         lastt = t;
192
193         if (!interfaces_changed()) return False;
194
195         /* the list of probed interfaces has changed, we may need to add/remove
196            some subnets */
197         load_interfaces();
198
199         /* find any interfaces that need adding */
200         for (n=iface_count() - 1; n >= 0; n--) {
201                 struct interface *iface = get_interface(n);
202
203                 /*
204                  * We don't want to add a loopback interface, in case
205                  * someone has added 127.0.0.1 for smbd, nmbd needs to
206                  * ignore it here. JRA.
207                  */
208
209                 if (ip_equal(iface->ip, loopback_ip)) {
210                         DEBUG(2,("reload_interfaces: Ignoring loopback interface %s\n", inet_ntoa(iface->ip)));
211                         continue;
212                 }
213
214                 for (subrec=subnetlist; subrec; subrec=subrec->next) {
215                         if (ip_equal(iface->ip, subrec->myip) &&
216                             ip_equal(iface->nmask, subrec->mask_ip)) break;
217                 }
218
219                 if (!subrec) {
220                         /* it wasn't found! add it */
221                         DEBUG(2,("Found new interface %s\n", 
222                                  inet_ntoa(iface->ip)));
223                         subrec = make_normal_subnet(iface);
224                         if (subrec) register_my_workgroup_one_subnet(subrec);
225                 }
226         }
227
228         /* find any interfaces that need deleting */
229         for (subrec=subnetlist; subrec; subrec=subrec->next) {
230                 for (n=iface_count() - 1; n >= 0; n--) {
231                         struct interface *iface = get_interface(n);
232                         if (ip_equal(iface->ip, subrec->myip) &&
233                             ip_equal(iface->nmask, subrec->mask_ip)) break;
234                 }
235                 if (n == -1) {
236                         /* oops, an interface has disapeared. This is
237                          tricky, we don't dare actually free the
238                          interface as it could be being used, so
239                          instead we just wear the memory leak and
240                          remove it from the list of interfaces without
241                          freeing it */
242                         DEBUG(2,("Deleting dead interface %s\n", 
243                                  inet_ntoa(subrec->myip)));
244                         close_subnet(subrec);
245                 }
246         }
247         
248         rescan_listen_set = True;
249
250         /* We need to shutdown if there are no subnets... */
251         if (FIRST_SUBNET == NULL) {
252                 DEBUG(0,("reload_interfaces: No subnets to listen to. Shutting down...\n"));
253                 return True;
254         }
255         return False;
256 }
257
258
259
260 /**************************************************************************** **
261   reload the services file
262  **************************************************************************** */
263 static BOOL reload_nmbd_services(BOOL test)
264 {
265   BOOL ret;
266   extern fstring remote_machine;
267
268   fstrcpy( remote_machine, "nmbd" );
269
270   if ( lp_loaded() )
271   {
272     pstring fname;
273     pstrcpy( fname,lp_configfile());
274     if (file_exist(fname,NULL) && !strcsequal(fname,dyn_CONFIGFILE))
275     {
276       pstrcpy(dyn_CONFIGFILE,fname);
277       test = False;
278     }
279   }
280
281   if ( test && !lp_file_list_changed() )
282     return(True);
283
284   ret = lp_load( dyn_CONFIGFILE, True , False, False);
285
286   /* perhaps the config filename is now set */
287   if ( !test )
288   {
289     DEBUG( 3, ( "services not loaded\n" ) );
290     reload_nmbd_services( True );
291   }
292
293   /* Do a sanity check for a misconfigured nmbd */
294   if( lp_wins_support() && wins_srv_count() )
295     {
296     if( DEBUGLVL(0) )
297       {
298       dbgtext( "ERROR: 'wins support = true' and 'wins server = <server>'\n" );
299       dbgtext( "are conflicting settings.  nmbd aborting.\n" );
300       }
301     exit(10);
302     }
303
304   return(ret);
305 } /* reload_nmbd_services */
306
307 /**************************************************************************** **
308  The main select loop.
309  **************************************************************************** */
310 static void process(void)
311 {
312   BOOL run_election;
313
314   while( True )
315   {
316     time_t t = time(NULL);
317
318     /* check for internal messages */
319     message_dispatch();
320
321     /*
322      * Check all broadcast subnets to see if
323      * we need to run an election on any of them.
324      * (nmbd_elections.c)
325      */
326     run_election = check_elections();
327
328     /*
329      * Read incoming UDP packets.
330      * (nmbd_packets.c)
331      */
332     if(listen_for_packets(run_election))
333       return;
334
335     /*
336      * Process all incoming packets
337      * read above. This calls the success and
338      * failure functions registered when response
339      * packets arrrive, and also deals with request
340      * packets from other sources.
341      * (nmbd_packets.c)
342      */
343     run_packet_queue();
344
345     /*
346      * Run any elections - initiate becoming
347      * a local master browser if we have won.
348      * (nmbd_elections.c)
349      */
350     run_elections(t);
351
352     /*
353      * Send out any broadcast announcements
354      * of our server names. This also announces
355      * the workgroup name if we are a local
356      * master browser.
357      * (nmbd_sendannounce.c)
358      */
359     announce_my_server_names(t);
360
361     /*
362      * Send out any LanMan broadcast announcements
363      * of our server names.
364      * (nmbd_sendannounce.c)
365      */
366     announce_my_lm_server_names(t);
367
368     /*
369      * If we are a local master browser, periodically
370      * announce ourselves to the domain master browser.
371      * This also deals with syncronising the domain master
372      * browser server lists with ourselves as a local
373      * master browser.
374      * (nmbd_sendannounce.c)
375      */
376     announce_myself_to_domain_master_browser(t);
377
378     /*
379      * Fullfill any remote announce requests.
380      * (nmbd_sendannounce.c)
381      */
382     announce_remote(t);
383
384     /*
385      * Fullfill any remote browse sync announce requests.
386      * (nmbd_sendannounce.c)
387      */
388     browse_sync_remote(t);
389
390     /*
391      * Scan the broadcast subnets, and WINS client
392      * namelists and refresh any that need refreshing.
393      * (nmbd_mynames.c)
394      */
395     refresh_my_names(t);
396
397     /*
398      * Scan the subnet namelists and server lists and
399      * expire thos that have timed out.
400      * (nmbd.c)
401      */
402     expire_names_and_servers(t);
403
404     /*
405      * Write out a snapshot of our current browse list into
406      * the browse.dat file. This is used by smbd to service
407      * incoming NetServerEnum calls - used to synchronise
408      * browse lists over subnets.
409      * (nmbd_serverlistdb.c)
410      */
411     write_browse_list(t, False);
412
413     /*
414      * If we are a domain master browser, we have a list of
415      * local master browsers we should synchronise browse
416      * lists with (these are added by an incoming local
417      * master browser announcement packet). Expire any of
418      * these that are no longer current, and pull the server
419      * lists from each of these known local master browsers.
420      * (nmbd_browsesync.c)
421      */
422     dmb_expire_and_sync_browser_lists(t);
423
424     /*
425      * Check that there is a local master browser for our
426      * workgroup for all our broadcast subnets. If one
427      * is not found, start an election (which we ourselves
428      * may or may not participate in, depending on the
429      * setting of the 'local master' parameter.
430      * (nmbd_elections.c)
431      */
432     check_master_browser_exists(t);
433
434     /*
435      * If we are configured as a logon server, attempt to
436      * register the special NetBIOS names to become such
437      * (WORKGROUP<1c> name) on all broadcast subnets and
438      * with the WINS server (if used). If we are configured
439      * to become a domain master browser, attempt to register
440      * the special NetBIOS name (WORKGROUP<1b> name) to
441      * become such.
442      * (nmbd_become_dmb.c)
443      */
444     add_domain_names(t);
445
446     /*
447      * If we are a WINS server, do any timer dependent
448      * processing required.
449      * (nmbd_winsserver.c)
450      */
451     initiate_wins_processing(t);
452
453     /*
454      * If we are a domain master browser, attempt to contact the
455      * WINS server to get a list of all known WORKGROUPS/DOMAINS.
456      * This will only work to a Samba WINS server.
457      * (nmbd_browsesync.c)
458      */
459     if (lp_enhanced_browsing()) {
460             collect_all_workgroup_names_from_wins_server(t);
461     }
462
463     /*
464      * Go through the response record queue and time out or re-transmit
465      * and expired entries.
466      * (nmbd_packets.c)
467      */
468     retransmit_or_expire_response_records(t);
469
470     /*
471      * check to see if any remote browse sync child processes have completed
472      */
473     sync_check_completion();
474
475     /*
476      * regularly sync with any other DMBs we know about 
477      */
478     if (lp_enhanced_browsing()) {
479             sync_all_dmbs(t);
480     }
481
482     /*
483      * clear the unexpected packet queue 
484      */
485     clear_unexpected(t);
486
487     /*
488      * Reload the services file if we got a sighup.
489      */
490
491     if(reload_after_sighup) {
492             reload_nmbd_services( True );
493             reopen_logs();
494             if(reload_interfaces(0))
495                         return;
496             reload_after_sighup = False;
497     }
498
499     /* check for new network interfaces */
500     if(reload_interfaces(t))
501                 return;
502
503     /* free up temp memory */
504     lp_talloc_free();
505   }
506 } /* process */
507
508
509 /**************************************************************************** **
510  open the socket communication
511  **************************************************************************** */
512 static BOOL open_sockets(BOOL isdaemon, int port)
513 {
514   /* The sockets opened here will be used to receive broadcast
515      packets *only*. Interface specific sockets are opened in
516      make_subnet() in namedbsubnet.c. Thus we bind to the
517      address "0.0.0.0". The parameter 'socket address' is
518      now deprecated.
519    */
520
521   if ( isdaemon )
522     ClientNMB = open_socket_in(SOCK_DGRAM, port,0,0,True);
523   else
524     ClientNMB = 0;
525   
526   ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3,0,True);
527
528   if ( ClientNMB == -1 )
529     return( False );
530
531   /* we are never interested in SIGPIPE */
532   BlockSignals(True,SIGPIPE);
533
534   set_socket_options( ClientNMB,   "SO_BROADCAST" );
535   set_socket_options( ClientDGRAM, "SO_BROADCAST" );
536
537   DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
538   return( True );
539 } /* open_sockets */
540
541
542 /**************************************************************************** **
543  initialise connect, service and file structs
544  **************************************************************************** */
545 static BOOL init_structs(void)
546 {
547   extern fstring local_machine;
548   char *p, **ptr;
549   int namecount;
550   int n;
551   int nodup;
552   char *nbname;
553
554   if (! *global_myname)
555   {
556     fstrcpy( global_myname, myhostname() );
557     p = strchr_m( global_myname, '.' );
558     if (p)
559       *p = 0;
560   }
561   strupper( global_myname );
562
563   /* Add any NETBIOS name aliases. Ensure that the first entry
564      is equal to global_myname.
565    */
566   /* Work out the max number of netbios aliases that we have */
567   ptr = lp_netbios_aliases();
568   namecount = 0;
569   if (ptr)
570     for( ; *ptr; namecount++,ptr++ )
571       ;
572   if ( *global_myname )
573     namecount++;
574
575   /* Allocate space for the netbios aliases */
576   my_netbios_names = (char **)malloc( sizeof(char *) * (namecount+1) );
577   if( NULL == my_netbios_names )
578   {
579      DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
580      return( False );
581   }
582  
583   /* Use the global_myname string first */
584   namecount=0;
585   if ( *global_myname )
586     my_netbios_names[namecount++] = global_myname;
587   
588   ptr = lp_netbios_aliases();
589   if (ptr)
590   {
591     while ( *ptr )
592     {
593       nbname = strdup(*ptr);
594       if (nbname == NULL)
595       {
596         DEBUG(0,("init_structs: malloc fail when allocating names.\n"));
597         return False;
598       }
599       strupper( nbname );
600       /* Look for duplicates */
601       nodup=1;
602       for( n=0; n<namecount; n++ )
603       {
604         if( 0 == strcmp( nbname, my_netbios_names[n] ) )
605           nodup=0;
606       }
607       if (nodup)
608         my_netbios_names[namecount++] = nbname;
609       else
610         SAFE_FREE(nbname);
611
612       ptr++;
613     }
614   }
615   
616   /* Terminate name list */
617   my_netbios_names[namecount++] = NULL;
618   
619   fstrcpy( local_machine, global_myname );
620   trim_string( local_machine, " ", " " );
621   p = strchr_m( local_machine, ' ' );
622   if (p)
623     *p = 0;
624   strlower( local_machine );
625
626   DEBUG( 5, ("Netbios name list:-\n") );
627   for( n=0; my_netbios_names[n]; n++ )
628     DEBUGADD( 5, ( "my_netbios_names[%d]=\"%s\"\n", n, my_netbios_names[n] ) );
629
630   return( True );
631 } /* init_structs */
632
633 /**************************************************************************** **
634  usage on the program
635  **************************************************************************** */
636 static void usage(char *pname)
637 {
638
639   printf( "Usage: %s [-DaohV] [-H lmhosts file] [-d debuglevel] [-l log basename]\n", pname );
640   printf( "       [-n name] [-p port] [-s configuration file]\n" );
641   printf( "\t-D                    Become a daemon\n" );
642   printf( "\t-a                    Append to log file (default)\n" );
643   printf( "\t-o                    Overwrite log file, don't append\n" );
644   printf( "\t-h                    Print usage\n" );
645   printf( "\t-V                    Print version\n" );
646   printf( "\t-H hosts file         Load a netbios hosts file\n" );
647   printf( "\t-d debuglevel         Set the debuglevel\n" );
648   printf( "\t-l log basename.      Basename for log/debug files\n" );
649   printf( "\t-n netbiosname.       Primary netbios name\n" );
650   printf( "\t-p port               Listen on the specified port\n" );
651   printf( "\t-s configuration file Configuration file name\n" );
652   printf( "\n");
653 } /* usage */
654
655
656 /**************************************************************************** **
657  main program
658  **************************************************************************** */
659  int main(int argc,char *argv[])
660 {
661   int opt;
662   extern char *optarg;
663   extern BOOL  append_log;
664
665   append_log = True;  /* Default, override with '-o' option. */
666
667   global_nmb_port = NMB_PORT;
668   global_in_nmbd = True;
669
670   StartupTime = time(NULL);
671
672   sys_srandom(time(NULL) ^ sys_getpid());
673
674   slprintf(debugf, sizeof(debugf)-1, "%s/log.nmbd", dyn_LOGFILEBASE);
675   setup_logging( argv[0], False );
676
677   /* this is for people who can't start the program correctly */
678   while (argc > 1 && (*argv[1] != '-'))
679   {
680     argv++;
681     argc--;
682   }
683
684   fault_setup((void (*)(void *))fault_continue );
685
686   /* POSIX demands that signals are inherited. If the invoking process has
687    * these signals masked, we will have problems, as we won't recieve them. */
688   BlockSignals(False, SIGHUP);
689   BlockSignals(False, SIGUSR1);
690   BlockSignals(False, SIGTERM);
691
692   CatchSignal( SIGHUP,  SIGNAL_CAST sig_hup );
693   CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
694
695 #if defined(SIGFPE)
696   /* we are never interested in SIGFPE */
697   BlockSignals(True,SIGFPE);
698 #endif
699
700   /* We no longer use USR2... */
701 #if defined(SIGUSR2)
702   BlockSignals(True, SIGUSR2);
703 #endif
704
705   while( EOF != 
706          (opt = getopt( argc, argv, "Vaos:T:I:C:bAB:N:Rn:l:d:Dp:hSH:G:f:" )) )
707     {
708       switch (opt)
709         {
710         case 's':
711           pstrcpy(dyn_CONFIGFILE, optarg);
712           break;          
713         case 'N':
714         case 'B':
715         case 'I':
716         case 'C':
717         case 'G':
718           DEBUG(0,("Obsolete option '%c' used\n",opt));
719           break;
720         case 'H':
721           pstrcpy(dyn_LMHOSTSFILE, optarg);
722           break;
723         case 'n':
724           pstrcpy(global_myname,optarg);
725           strupper(global_myname);
726           break;
727         case 'l':
728           slprintf(debugf, sizeof(debugf)-1, "%s/log.nmbd", optarg);
729           break;
730         case 'a':
731           append_log = True;
732           break;
733         case 'o':
734           append_log = False;
735           break;
736         case 'D':
737           is_daemon = True;
738           break;
739         case 'd':
740           DEBUGLEVEL = atoi(optarg);
741           break;
742         case 'p':
743           global_nmb_port = atoi(optarg);
744           break;
745         case 'h':
746           usage(argv[0]);
747           exit(0);
748           break;
749         case 'V':
750           printf( "Version %s\n", VERSION );
751           exit(0);
752           break;
753         default:
754           if( !is_a_socket(0) )
755           {
756             DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
757             usage(argv[0]);
758             exit(0);
759           }
760           break;
761         }
762     }
763
764   reopen_logs();
765
766   DEBUG( 1, ( "Netbios nameserver version %s started.\n", VERSION ) );
767   DEBUGADD( 1, ( "Copyright Andrew Tridgell 1994-1998\n" ) );
768
769   if ( !reload_nmbd_services(False) )
770     return(-1);
771
772   if(!init_structs())
773     return -1;
774
775   reload_nmbd_services( True );
776
777   fstrcpy( global_myworkgroup, lp_workgroup() );
778
779   if (strequal(global_myworkgroup,"*"))
780   {
781     DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
782     exit(1);
783   }
784
785   set_samba_nb_type();
786
787   if (!is_daemon && !is_a_socket(0))
788   {
789     DEBUG(0,("standard input is not a socket, assuming -D option\n"));
790     is_daemon = True;
791   }
792   
793   if (is_daemon)
794   {
795     DEBUG( 2, ( "Becoming a daemon.\n" ) );
796     become_daemon();
797   }
798
799 #ifndef SYNC_DNS
800   /* Setup the async dns. We do it here so it doesn't have all the other
801      stuff initialised and thus chewing memory and sockets */
802   if(lp_we_are_a_wins_server()) {
803           start_async_dns();
804   }
805 #endif
806
807   if (!directory_exist(lp_lockdir(), NULL)) {
808           mkdir(lp_lockdir(), 0755);
809   }
810
811   pidfile_create("nmbd");
812   message_init();
813   message_register(MSG_FORCE_ELECTION, nmbd_message_election);
814
815   DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
816
817   if ( !open_sockets( is_daemon, global_nmb_port ) )
818     return 1;
819
820   /* Determine all the IP addresses we have. */
821   load_interfaces();
822
823   /* Create an nmbd subnet record for each of the above. */
824   if( False == create_subnets() )
825   {
826     DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
827     exit(1);
828   }
829
830   /* Load in any static local names. */ 
831   load_lmhosts_file(dyn_LMHOSTSFILE);
832   DEBUG(3,("Loaded hosts file %s\n", dyn_LMHOSTSFILE));
833
834   /* If we are acting as a WINS server, initialise data structures. */
835   if( !initialise_wins() )
836   {
837     DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
838     exit(1);
839   }
840
841   /* 
842    * Register nmbd primary workgroup and nmbd names on all
843    * the broadcast subnets, and on the WINS server (if specified).
844    * Also initiate the startup of our primary workgroup (start
845    * elections if we are setup as being able to be a local
846    * master browser.
847    */
848
849   if( False == register_my_workgroup_and_names() )
850   {
851     DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
852     exit(1);
853   }
854
855   /* We can only take signals in the select. */
856   BlockSignals( True, SIGTERM );
857
858   process();
859
860   if (dbf)
861     x_fclose(dbf);
862   return(0);
863 } /* main */