nmbd/nmbd.c

説明を見る。
00001 /*
00002    Unix SMB/CIFS implementation.
00003    NBT netbios routines and daemon - version 2
00004    Copyright (C) Andrew Tridgell 1994-1998
00005    Copyright (C) Jeremy Allison 1997-2002
00006    Copyright (C) Jelmer Vernooij 2002,2003 (Conversion to popt)
00007    
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012    
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017    
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00021    
00022 */
00023 
00024 #include "includes.h"
00025 
00026 int ClientNMB       = -1;
00027 int ClientDGRAM     = -1;
00028 int global_nmb_port = -1;
00029 
00030 extern BOOL rescan_listen_set;
00031 extern struct in_addr loopback_ip;
00032 extern BOOL global_in_nmbd;
00033 
00034 extern BOOL override_logfile;
00035 
00036 /* are we running as a daemon ? */
00037 static BOOL is_daemon;
00038 
00039 /* fork or run in foreground ? */
00040 static BOOL Fork = True;
00041 
00042 /* log to standard output ? */
00043 static BOOL log_stdout;
00044 
00045 /* have we found LanMan clients yet? */
00046 BOOL found_lm_clients = False;
00047 
00048 /* what server type are we currently */
00049 
00050 time_t StartupTime = 0;
00051 
00052 /**************************************************************************** **
00053  Handle a SIGTERM in band.
00054  **************************************************************************** */
00055 
00056 static void terminate(void)
00057 {
00058         DEBUG(0,("Got SIGTERM: going down...\n"));
00059   
00060         /* Write out wins.dat file if samba is a WINS server */
00061         wins_write_database(0,False);
00062   
00063         /* Remove all SELF registered names from WINS */
00064         release_wins_names();
00065   
00066         /* Announce all server entries as 0 time-to-live, 0 type. */
00067         announce_my_servers_removed();
00068 
00069         /* If there was an async dns child - kill it. */
00070         kill_async_dns_child();
00071 
00072         exit(0);
00073 }
00074 
00075 /**************************************************************************** **
00076  Handle a SHUTDOWN message from smbcontrol.
00077  **************************************************************************** */
00078 
00079 static void nmbd_terminate(int msg_type, struct process_id src,
00080                            void *buf, size_t len, void *private_data)
00081 {
00082         terminate();
00083 }
00084 
00085 /**************************************************************************** **
00086  Catch a SIGTERM signal.
00087  **************************************************************************** */
00088 
00089 static SIG_ATOMIC_T got_sig_term;
00090 
00091 static void sig_term(int sig)
00092 {
00093         got_sig_term = 1;
00094         sys_select_signal(SIGTERM);
00095 }
00096 
00097 /**************************************************************************** **
00098  Catch a SIGHUP signal.
00099  **************************************************************************** */
00100 
00101 static SIG_ATOMIC_T reload_after_sighup;
00102 
00103 static void sig_hup(int sig)
00104 {
00105         reload_after_sighup = 1;
00106         sys_select_signal(SIGHUP);
00107 }
00108 
00109 /**************************************************************************** **
00110  Possibly continue after a fault.
00111  **************************************************************************** */
00112 
00113 static void fault_continue(void)
00114 {
00115         dump_core();
00116 }
00117 
00118 /**************************************************************************** **
00119  Expire old names from the namelist and server list.
00120  **************************************************************************** */
00121 
00122 static void expire_names_and_servers(time_t t)
00123 {
00124         static time_t lastrun = 0;
00125   
00126         if ( !lastrun )
00127                 lastrun = t;
00128         if ( t < (lastrun + 5) )
00129                 return;
00130         lastrun = t;
00131 
00132         /*
00133          * Expire any timed out names on all the broadcast
00134          * subnets and those registered with the WINS server.
00135          * (nmbd_namelistdb.c)
00136          */
00137 
00138         expire_names(t);
00139 
00140         /*
00141          * Go through all the broadcast subnets and for each
00142          * workgroup known on that subnet remove any expired
00143          * server names. If a workgroup has an empty serverlist
00144          * and has itself timed out then remove the workgroup.
00145          * (nmbd_workgroupdb.c)
00146          */
00147 
00148         expire_workgroups_and_servers(t);
00149 }
00150 
00151 /************************************************************************** **
00152  Reload the list of network interfaces.
00153  Doesn't return until a network interface is up.
00154  ************************************************************************** */
00155 
00156 static void reload_interfaces(time_t t)
00157 {
00158         static time_t lastt;
00159         int n;
00160         bool print_waiting_msg = true;
00161         struct subnet_record *subrec;
00162 
00163         if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) {
00164                 return;
00165         }
00166         lastt = t;
00167 
00168         if (!interfaces_changed()) {
00169                 return;
00170         }
00171 
00172   try_again:
00173 
00174         /* the list of probed interfaces has changed, we may need to add/remove
00175            some subnets */
00176         load_interfaces();
00177 
00178         /* find any interfaces that need adding */
00179         for (n=iface_count() - 1; n >= 0; n--) {
00180                 struct interface *iface = get_interface(n);
00181 
00182                 if (!iface) {
00183                         DEBUG(2,("reload_interfaces: failed to get interface %d\n", n));
00184                         continue;
00185                 }
00186 
00187                 /*
00188                  * We don't want to add a loopback interface, in case
00189                  * someone has added 127.0.0.1 for smbd, nmbd needs to
00190                  * ignore it here. JRA.
00191                  */
00192 
00193                 if (ip_equal(iface->ip, loopback_ip)) {
00194                         DEBUG(2,("reload_interfaces: Ignoring loopback interface %s\n", inet_ntoa(iface->ip)));
00195                         continue;
00196                 }
00197 
00198                 for (subrec=subnetlist; subrec; subrec=subrec->next) {
00199                         if (ip_equal(iface->ip, subrec->myip) &&
00200                             ip_equal(iface->nmask, subrec->mask_ip)) break;
00201                 }
00202 
00203                 if (!subrec) {
00204                         /* it wasn't found! add it */
00205                         DEBUG(2,("Found new interface %s\n", 
00206                                  inet_ntoa(iface->ip)));
00207                         subrec = make_normal_subnet(iface);
00208                         if (subrec)
00209                                 register_my_workgroup_one_subnet(subrec);
00210                 }
00211         }
00212 
00213         /* find any interfaces that need deleting */
00214         for (subrec=subnetlist; subrec; subrec=subrec->next) {
00215                 for (n=iface_count() - 1; n >= 0; n--) {
00216                         struct interface *iface = get_interface(n);
00217                         if (ip_equal(iface->ip, subrec->myip) &&
00218                             ip_equal(iface->nmask, subrec->mask_ip)) break;
00219                 }
00220                 if (n == -1) {
00221                         /* oops, an interface has disapeared. This is
00222                          tricky, we don't dare actually free the
00223                          interface as it could be being used, so
00224                          instead we just wear the memory leak and
00225                          remove it from the list of interfaces without
00226                          freeing it */
00227                         DEBUG(2,("Deleting dead interface %s\n", 
00228                                  inet_ntoa(subrec->myip)));
00229                         close_subnet(subrec);
00230                 }
00231         }
00232 
00233         rescan_listen_set = True;
00234 
00235         /* We need to wait if there are no subnets... */
00236         if (FIRST_SUBNET == NULL) {
00237 
00238                 if (print_waiting_msg) {
00239                         DEBUG(0,("reload_interfaces: "
00240                                 "No subnets to listen to. Waiting..\n"));
00241                         print_waiting_msg = false;
00242                 }
00243 
00244                 /*
00245                  * Whilst we're waiting for an interface, allow SIGTERM to
00246                  * cause us to exit.
00247                  */
00248 
00249                 BlockSignals(false, SIGTERM);
00250 
00251                 while (iface_count_nl() == 0 && !got_sig_term) {
00252                         sleep(5);
00253                         load_interfaces();
00254                 }
00255 
00256                 /*
00257                  * Handle termination inband.
00258                  */
00259 
00260                 if (got_sig_term) {
00261                         got_sig_term = 0;
00262                         terminate();
00263                 }
00264 
00265                 /*
00266                  * We got an interface, go back to blocking term.
00267                  */
00268 
00269                 BlockSignals(true, SIGTERM);
00270                 goto try_again;
00271         }
00272 }
00273 
00274 /**************************************************************************** **
00275  Reload the services file.
00276  **************************************************************************** */
00277 
00278 static BOOL reload_nmbd_services(BOOL test)
00279 {
00280         BOOL ret;
00281 
00282         set_remote_machine_name("nmbd", False);
00283 
00284         if ( lp_loaded() ) {
00285                 pstring fname;
00286                 pstrcpy( fname,lp_configfile());
00287                 if (file_exist(fname,NULL) && !strcsequal(fname,dyn_CONFIGFILE)) {
00288                         pstrcpy(dyn_CONFIGFILE,fname);
00289                         test = False;
00290                 }
00291         }
00292 
00293         if ( test && !lp_file_list_changed() )
00294                 return(True);
00295 
00296         ret = lp_load( dyn_CONFIGFILE, True , False, False, True);
00297 
00298         /* perhaps the config filename is now set */
00299         if ( !test ) {
00300                 DEBUG( 3, ( "services not loaded\n" ) );
00301                 reload_nmbd_services( True );
00302         }
00303 
00304         return(ret);
00305 }
00306 
00307 /**************************************************************************** **
00308  * React on 'smbcontrol nmbd reload-config' in the same way as to SIGHUP
00309  **************************************************************************** */
00310 
00311 static void msg_reload_nmbd_services(int msg_type, struct process_id src,
00312                                      void *buf, size_t len, void *private_data)
00313 {
00314         write_browse_list( 0, True );
00315         dump_all_namelists();
00316         reload_nmbd_services( True );
00317         reopen_logs();
00318         reload_interfaces(0);
00319 }
00320 
00321 static void msg_nmbd_send_packet(int msg_type, struct process_id src,
00322                                  void *buf, size_t len, void *private_data)
00323 {
00324         struct packet_struct *p = (struct packet_struct *)buf;
00325         struct subnet_record *subrec;
00326         struct in_addr *local_ip;
00327 
00328         DEBUG(10, ("Received send_packet from %d\n", procid_to_pid(&src)));
00329 
00330         if (len != sizeof(struct packet_struct)) {
00331                 DEBUG(2, ("Discarding invalid packet length from %d\n",
00332                           procid_to_pid(&src)));
00333                 return;
00334         }
00335 
00336         if ((p->packet_type != NMB_PACKET) &&
00337             (p->packet_type != DGRAM_PACKET)) {
00338                 DEBUG(2, ("Discarding invalid packet type from %d: %d\n",
00339                           procid_to_pid(&src), p->packet_type));
00340                 return;
00341         }
00342 
00343         local_ip = iface_ip(p->ip);
00344 
00345         if (local_ip == NULL) {
00346                 DEBUG(2, ("Could not find ip for packet from %d\n",
00347                           procid_to_pid(&src)));
00348                 return;
00349         }
00350 
00351         subrec = FIRST_SUBNET;
00352 
00353         p->fd = (p->packet_type == NMB_PACKET) ?
00354                 subrec->nmb_sock : subrec->dgram_sock;
00355 
00356         for (subrec = FIRST_SUBNET; subrec != NULL;
00357              subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
00358                 if (ip_equal(*local_ip, subrec->myip)) {
00359                         p->fd = (p->packet_type == NMB_PACKET) ?
00360                                 subrec->nmb_sock : subrec->dgram_sock;
00361                         break;
00362                 }
00363         }
00364 
00365         if (p->packet_type == DGRAM_PACKET) {
00366                 p->port = 138;
00367                 p->packet.dgram.header.source_ip.s_addr = local_ip->s_addr;
00368                 p->packet.dgram.header.source_port = 138;
00369         }
00370 
00371         send_packet(p);
00372 }
00373 
00374 /**************************************************************************** **
00375  The main select loop.
00376  **************************************************************************** */
00377 
00378 static void process(void)
00379 {
00380         BOOL run_election;
00381 
00382         while( True ) {
00383                 time_t t = time(NULL);
00384 
00385                 /* Check for internal messages */
00386 
00387                 message_dispatch();
00388 
00389                 /*
00390                  * Check all broadcast subnets to see if
00391                  * we need to run an election on any of them.
00392                  * (nmbd_elections.c)
00393                  */
00394 
00395                 run_election = check_elections();
00396 
00397                 /*
00398                  * Read incoming UDP packets.
00399                  * (nmbd_packets.c)
00400                  */
00401 
00402                 if(listen_for_packets(run_election))
00403                         return;
00404 
00405                 /*
00406                  * Handle termination inband.
00407                  */
00408 
00409                 if (got_sig_term) {
00410                         got_sig_term = 0;
00411                         terminate();
00412                 }
00413 
00414                 /*
00415                  * Process all incoming packets
00416                  * read above. This calls the success and
00417                  * failure functions registered when response
00418                  * packets arrrive, and also deals with request
00419                  * packets from other sources.
00420                  * (nmbd_packets.c)
00421                  */
00422 
00423                 run_packet_queue();
00424 
00425                 /*
00426                  * Run any elections - initiate becoming
00427                  * a local master browser if we have won.
00428                  * (nmbd_elections.c)
00429                  */
00430 
00431                 run_elections(t);
00432 
00433                 /*
00434                  * Send out any broadcast announcements
00435                  * of our server names. This also announces
00436                  * the workgroup name if we are a local
00437                  * master browser.
00438                  * (nmbd_sendannounce.c)
00439                  */
00440 
00441                 announce_my_server_names(t);
00442 
00443                 /*
00444                  * Send out any LanMan broadcast announcements
00445                  * of our server names.
00446                  * (nmbd_sendannounce.c)
00447                  */
00448 
00449                 announce_my_lm_server_names(t);
00450 
00451                 /*
00452                  * If we are a local master browser, periodically
00453                  * announce ourselves to the domain master browser.
00454                  * This also deals with syncronising the domain master
00455                  * browser server lists with ourselves as a local
00456                  * master browser.
00457                  * (nmbd_sendannounce.c)
00458                  */
00459 
00460                 announce_myself_to_domain_master_browser(t);
00461 
00462                 /*
00463                  * Fullfill any remote announce requests.
00464                  * (nmbd_sendannounce.c)
00465                  */
00466 
00467                 announce_remote(t);
00468 
00469                 /*
00470                  * Fullfill any remote browse sync announce requests.
00471                  * (nmbd_sendannounce.c)
00472                  */
00473 
00474                 browse_sync_remote(t);
00475 
00476                 /*
00477                  * Scan the broadcast subnets, and WINS client
00478                  * namelists and refresh any that need refreshing.
00479                  * (nmbd_mynames.c)
00480                  */
00481 
00482                 refresh_my_names(t);
00483 
00484                 /*
00485                  * Scan the subnet namelists and server lists and
00486                  * expire thos that have timed out.
00487                  * (nmbd.c)
00488                  */
00489 
00490                 expire_names_and_servers(t);
00491 
00492                 /*
00493                  * Write out a snapshot of our current browse list into
00494                  * the browse.dat file. This is used by smbd to service
00495                  * incoming NetServerEnum calls - used to synchronise
00496                  * browse lists over subnets.
00497                  * (nmbd_serverlistdb.c)
00498                  */
00499 
00500                 write_browse_list(t, False);
00501 
00502                 /*
00503                  * If we are a domain master browser, we have a list of
00504                  * local master browsers we should synchronise browse
00505                  * lists with (these are added by an incoming local
00506                  * master browser announcement packet). Expire any of
00507                  * these that are no longer current, and pull the server
00508                  * lists from each of these known local master browsers.
00509                  * (nmbd_browsesync.c)
00510                  */
00511 
00512                 dmb_expire_and_sync_browser_lists(t);
00513 
00514                 /*
00515                  * Check that there is a local master browser for our
00516                  * workgroup for all our broadcast subnets. If one
00517                  * is not found, start an election (which we ourselves
00518                  * may or may not participate in, depending on the
00519                  * setting of the 'local master' parameter.
00520                  * (nmbd_elections.c)
00521                  */
00522 
00523                 check_master_browser_exists(t);
00524 
00525                 /*
00526                  * If we are configured as a logon server, attempt to
00527                  * register the special NetBIOS names to become such
00528                  * (WORKGROUP<1c> name) on all broadcast subnets and
00529                  * with the WINS server (if used). If we are configured
00530                  * to become a domain master browser, attempt to register
00531                  * the special NetBIOS name (WORKGROUP<1b> name) to
00532                  * become such.
00533                  * (nmbd_become_dmb.c)
00534                  */
00535 
00536                 add_domain_names(t);
00537 
00538                 /*
00539                  * If we are a WINS server, do any timer dependent
00540                  * processing required.
00541                  * (nmbd_winsserver.c)
00542                  */
00543 
00544                 initiate_wins_processing(t);
00545 
00546                 /*
00547                  * If we are a domain master browser, attempt to contact the
00548                  * WINS server to get a list of all known WORKGROUPS/DOMAINS.
00549                  * This will only work to a Samba WINS server.
00550                  * (nmbd_browsesync.c)
00551                  */
00552 
00553                 if (lp_enhanced_browsing())
00554                         collect_all_workgroup_names_from_wins_server(t);
00555 
00556                 /*
00557                  * Go through the response record queue and time out or re-transmit
00558                  * and expired entries.
00559                  * (nmbd_packets.c)
00560                  */
00561 
00562                 retransmit_or_expire_response_records(t);
00563 
00564                 /*
00565                  * check to see if any remote browse sync child processes have completed
00566                  */
00567 
00568                 sync_check_completion();
00569 
00570                 /*
00571                  * regularly sync with any other DMBs we know about 
00572                  */
00573 
00574                 if (lp_enhanced_browsing())
00575                         sync_all_dmbs(t);
00576 
00577                 /*
00578                  * clear the unexpected packet queue 
00579                  */
00580 
00581                 clear_unexpected(t);
00582 
00583                 /*
00584                  * Reload the services file if we got a sighup.
00585                  */
00586 
00587                 if(reload_after_sighup) {
00588                         DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) );
00589                         msg_reload_nmbd_services(MSG_SMB_CONF_UPDATED,
00590                                                  pid_to_procid(0), NULL, 0, NULL);
00591                         reload_after_sighup = 0;
00592                 }
00593 
00594                 /* check for new network interfaces */
00595 
00596                 reload_interfaces(t);
00597 
00598                 /* free up temp memory */
00599                 lp_TALLOC_FREE();
00600         }
00601 }
00602 
00603 /**************************************************************************** **
00604  Open the socket communication.
00605  **************************************************************************** */
00606 
00607 static BOOL open_sockets(BOOL isdaemon, int port)
00608 {
00609         /*
00610          * The sockets opened here will be used to receive broadcast
00611          * packets *only*. Interface specific sockets are opened in
00612          * make_subnet() in namedbsubnet.c. Thus we bind to the
00613          * address "0.0.0.0". The parameter 'socket address' is
00614          * now deprecated.
00615          */
00616 
00617         if ( isdaemon )
00618                 ClientNMB = open_socket_in(SOCK_DGRAM, port,
00619                                            0, interpret_addr(lp_socket_address()),
00620                                            True);
00621         else
00622                 ClientNMB = 0;
00623   
00624         ClientDGRAM = open_socket_in(SOCK_DGRAM, DGRAM_PORT,
00625                                            3, interpret_addr(lp_socket_address()),
00626                                            True);
00627 
00628         if ( ClientNMB == -1 )
00629                 return( False );
00630 
00631         /* we are never interested in SIGPIPE */
00632         BlockSignals(True,SIGPIPE);
00633 
00634         set_socket_options( ClientNMB,   "SO_BROADCAST" );
00635         set_socket_options( ClientDGRAM, "SO_BROADCAST" );
00636 
00637         /* Ensure we're non-blocking. */
00638         set_blocking( ClientNMB, False);
00639         set_blocking( ClientDGRAM, False);
00640 
00641         DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
00642         return( True );
00643 }
00644 
00645 /**************************************************************************** **
00646  main program
00647  **************************************************************************** */
00648  int main(int argc, const char *argv[])
00649 {
00650         pstring logfile;
00651         static BOOL opt_interactive;
00652         poptContext pc;
00653         static char *p_lmhosts = dyn_LMHOSTSFILE;
00654         static BOOL no_process_group = False;
00655         struct poptOption long_options[] = {
00656         POPT_AUTOHELP
00657         {"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon(default)" },
00658         {"interactive", 'i', POPT_ARG_VAL, &opt_interactive, True, "Run interactive (not a daemon)" },
00659         {"foreground", 'F', POPT_ARG_VAL, &Fork, False, "Run daemon in foreground (for daemontools & etc)" },
00660         {"no-process-group", 0, POPT_ARG_VAL, &no_process_group, True, "Don't create a new process group" },
00661         {"log-stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout" },
00662         {"hosts", 'H', POPT_ARG_STRING, &p_lmhosts, 'H', "Load a netbios hosts file"},
00663         {"port", 'p', POPT_ARG_INT, &global_nmb_port, NMB_PORT, "Listen on the specified port" },
00664         POPT_COMMON_SAMBA
00665         POPT_COMMON_CONNECTION
00666         { NULL }
00667         };
00668 
00669         load_case_tables();
00670 
00671         global_nmb_port = NMB_PORT;
00672 
00673         pc = poptGetContext("nmbd", argc, argv, long_options, 0);
00674         while (poptGetNextOpt(pc) != -1) {};
00675         poptFreeContext(pc);
00676 
00677         global_in_nmbd = True;
00678         
00679         StartupTime = time(NULL);
00680         
00681         sys_srandom(time(NULL) ^ sys_getpid());
00682         
00683         if (!override_logfile) {
00684                 slprintf(logfile, sizeof(logfile)-1, "%s/nmbd.log", dyn_LOGFILEBASE);
00685                 lp_set_logfile(logfile);
00686         }
00687         
00688         fault_setup((void (*)(void *))fault_continue );
00689         dump_core_setup("nmbd");
00690         
00691         /* POSIX demands that signals are inherited. If the invoking process has
00692          * these signals masked, we will have problems, as we won't receive them. */
00693         BlockSignals(False, SIGHUP);
00694         BlockSignals(False, SIGUSR1);
00695         BlockSignals(False, SIGTERM);
00696         
00697         CatchSignal( SIGHUP,  SIGNAL_CAST sig_hup );
00698         CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
00699         
00700 #if defined(SIGFPE)
00701         /* we are never interested in SIGFPE */
00702         BlockSignals(True,SIGFPE);
00703 #endif
00704 
00705         /* We no longer use USR2... */
00706 #if defined(SIGUSR2)
00707         BlockSignals(True, SIGUSR2);
00708 #endif
00709 
00710         if ( opt_interactive ) {
00711                 Fork = False;
00712                 log_stdout = True;
00713         }
00714 
00715         if ( log_stdout && Fork ) {
00716                 DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
00717                 exit(1);
00718         }
00719 
00720         setup_logging( argv[0], log_stdout );
00721 
00722         reopen_logs();
00723 
00724         DEBUG( 0, ( "Netbios nameserver version %s started.\n", SAMBA_VERSION_STRING) );
00725         DEBUGADD( 0, ( "%s\n", COPYRIGHT_STARTUP_MESSAGE ) );
00726 
00727         if ( !reload_nmbd_services(False) )
00728                 return(-1);
00729 
00730         if(!init_names())
00731                 return -1;
00732 
00733         reload_nmbd_services( True );
00734 
00735         if (strequal(lp_workgroup(),"*")) {
00736                 DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
00737                 exit(1);
00738         }
00739 
00740         set_samba_nb_type();
00741 
00742         if (!is_daemon && !is_a_socket(0)) {
00743                 DEBUG(0,("standard input is not a socket, assuming -D option\n"));
00744                 is_daemon = True;
00745         }
00746   
00747         if (is_daemon && !opt_interactive) {
00748                 DEBUG( 2, ( "Becoming a daemon.\n" ) );
00749                 become_daemon(Fork, no_process_group);
00750         }
00751 
00752 #if HAVE_SETPGID
00753         /*
00754          * If we're interactive we want to set our own process group for 
00755          * signal management.
00756          */
00757         if (opt_interactive && !no_process_group)
00758                 setpgid( (pid_t)0, (pid_t)0 );
00759 #endif
00760 
00761 #ifndef SYNC_DNS
00762         /* Setup the async dns. We do it here so it doesn't have all the other
00763                 stuff initialised and thus chewing memory and sockets */
00764         if(lp_we_are_a_wins_server() && lp_dns_proxy()) {
00765                 start_async_dns();
00766         }
00767 #endif
00768 
00769         if (!directory_exist(lp_lockdir(), NULL)) {
00770                 mkdir(lp_lockdir(), 0755);
00771         }
00772 
00773         pidfile_create("nmbd");
00774         message_init();
00775         message_register(MSG_FORCE_ELECTION, nmbd_message_election, NULL);
00776 #if 0
00777         /* Until winsrepl is done. */
00778         message_register(MSG_WINS_NEW_ENTRY, nmbd_wins_new_entry, NULL);
00779 #endif
00780         message_register(MSG_SHUTDOWN, nmbd_terminate, NULL);
00781         message_register(MSG_SMB_CONF_UPDATED, msg_reload_nmbd_services, NULL);
00782         message_register(MSG_SEND_PACKET, msg_nmbd_send_packet, NULL);
00783 
00784         TimeInit();
00785 
00786         DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
00787 
00788         if ( !open_sockets( is_daemon, global_nmb_port ) ) {
00789                 kill_async_dns_child();
00790                 return 1;
00791         }
00792 
00793         /* Determine all the IP addresses we have. */
00794         load_interfaces();
00795 
00796         /* Create an nmbd subnet record for each of the above. */
00797         if( False == create_subnets() ) {
00798                 DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
00799                 kill_async_dns_child();
00800                 exit(1);
00801         }
00802 
00803         /* Load in any static local names. */ 
00804         load_lmhosts_file(p_lmhosts);
00805         DEBUG(3,("Loaded hosts file %s\n", p_lmhosts));
00806 
00807         /* If we are acting as a WINS server, initialise data structures. */
00808         if( !initialise_wins() ) {
00809                 DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
00810                 kill_async_dns_child();
00811                 exit(1);
00812         }
00813 
00814         /* 
00815          * Register nmbd primary workgroup and nmbd names on all
00816          * the broadcast subnets, and on the WINS server (if specified).
00817          * Also initiate the startup of our primary workgroup (start
00818          * elections if we are setup as being able to be a local
00819          * master browser.
00820          */
00821 
00822         if( False == register_my_workgroup_and_names() ) {
00823                 DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
00824                 kill_async_dns_child();
00825                 exit(1);
00826         }
00827 
00828         /* We can only take signals in the select. */
00829         BlockSignals( True, SIGTERM );
00830 
00831         process();
00832 
00833         if (dbf)
00834                 x_fclose(dbf);
00835         kill_async_dns_child();
00836         return(0);
00837 }

Sambaに対してSat Aug 29 21:23:07 2009に生成されました。  doxygen 1.4.7