home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / Networking / SambaManager / samba-1.9.17p4 / source / nmbd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-30  |  18.0 KB  |  756 lines

  1. /*
  2.    Unix SMB/Netbios implementation.
  3.    Version 1.9.
  4.    NBT netbios routines and daemon - version 2
  5.    Copyright (C) Andrew Tridgell 1994-1997
  6.    
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 2 of the License, or
  10.    (at your option) any later version.
  11.    
  12.    This program is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.    GNU General Public License for more details.
  16.    
  17.    You should have received a copy of the GNU General Public License
  18.    along with this program; if not, write to the Free Software
  19.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.    
  21.    Revision History:
  22.  
  23.    14 jan 96: lkcl@pires.co.uk
  24.    added multiple workgroup domain master support
  25.  
  26. */
  27.  
  28. #include "includes.h"
  29.  
  30. extern int DEBUGLEVEL;
  31.  
  32. extern pstring debugf;
  33. pstring servicesf = CONFIGFILE;
  34.  
  35. extern pstring scope;
  36.  
  37. int ClientNMB   = -1;
  38. int ClientDGRAM = -1;
  39.  
  40. extern pstring myhostname;
  41. static pstring host_file;
  42. extern pstring myname;
  43. extern fstring myworkgroup;
  44. extern char **my_netbios_names;
  45.  
  46. /* are we running as a daemon ? */
  47. static BOOL is_daemon = False;
  48.  
  49. /* what server type are we currently */
  50.  
  51. time_t StartupTime =0;
  52.  
  53. extern struct in_addr ipzero;
  54.  
  55.  /****************************************************************************
  56.   catch a sigterm
  57.   ****************************************************************************/
  58. static int sig_term()
  59. {
  60.   BlockSignals(True,SIGTERM);
  61.   
  62.   DEBUG(0,("Got SIGTERM: going down...\n"));
  63.   
  64.   /* write out wins.dat file if samba is a WINS server */
  65.   dump_names();
  66.   
  67.   /* remove all samba names, with wins server if necessary. */
  68.   remove_my_names();
  69.   
  70.   /* announce all server entries as 0 time-to-live, 0 type */
  71.   /* XXXX don't care if we never receive a response back... yet */
  72.   announce_my_servers_removed();
  73.  
  74.   /* XXXX other things: if we are a master browser, force an election? */
  75.   
  76.   exit(0);
  77.   /* Keep compiler happy.. */
  78.   return 0;
  79. }
  80.  
  81.  
  82. /****************************************************************************
  83. catch a sighup
  84. ****************************************************************************/
  85. static int sig_hup(void)
  86. {
  87.   BlockSignals(True,SIGHUP);
  88.  
  89.   DEBUG(0,("Got SIGHUP (reload not implemented)\n"));
  90.   dump_names();
  91.   reload_services(True);
  92.  
  93.   set_samba_nb_type();
  94.  
  95.   BlockSignals(False,SIGHUP);
  96. #ifndef DONT_REINSTALL_SIG
  97.   signal(SIGHUP,SIGNAL_CAST sig_hup);
  98. #endif
  99.   return(0);
  100. }
  101.  
  102. /****************************************************************************
  103. catch a sigpipe
  104. ****************************************************************************/
  105. static int sig_pipe(void)
  106. {
  107.   BlockSignals(True,SIGPIPE);
  108.  
  109.   DEBUG(0,("Got SIGPIPE\n"));
  110.   if (!is_daemon)
  111.     exit(1);
  112.   BlockSignals(False,SIGPIPE);
  113.   return(0);
  114. }
  115.  
  116. #if DUMP_CORE
  117. /*******************************************************************
  118. prepare to dump a core file - carefully!
  119. ********************************************************************/
  120. static BOOL dump_core(void)
  121. {
  122.   char *p;
  123.   pstring dname;
  124.   pstrcpy(dname,debugf);
  125.   if ((p=strrchr(dname,'/'))) *p=0;
  126.   strcat(dname,"/corefiles");
  127.   mkdir(dname,0700);
  128.   sys_chown(dname,getuid(),getgid());
  129.   chmod(dname,0700);
  130.   if (chdir(dname)) return(False);
  131.   umask(~(0700));
  132.  
  133. #ifndef NO_GETRLIMIT
  134. #ifdef RLIMIT_CORE
  135.   {
  136.     struct rlimit rlp;
  137.     getrlimit(RLIMIT_CORE, &rlp);
  138.     rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
  139.     setrlimit(RLIMIT_CORE, &rlp);
  140.     getrlimit(RLIMIT_CORE, &rlp);
  141.     DEBUG(3,("Core limits now %d %d\n",rlp.rlim_cur,rlp.rlim_max));
  142.   }
  143. #endif
  144. #endif
  145.  
  146.  
  147.   DEBUG(0,("Dumping core in %s\n",dname));
  148.   return(True);
  149. }
  150. #endif
  151.  
  152.  
  153. /****************************************************************************
  154. possibly continue after a fault
  155. ****************************************************************************/
  156. static void fault_continue(void)
  157. {
  158. #if DUMP_CORE
  159.   dump_core();
  160. #endif
  161. }
  162.  
  163. /*******************************************************************
  164.   expire old names from the namelist and server list
  165.   ******************************************************************/
  166. static void expire_names_and_servers(time_t t)
  167. {
  168.   static time_t lastrun = 0;
  169.   
  170.   if (!lastrun) lastrun = t;
  171.   if (t < lastrun + 5) return;
  172.   lastrun = t;
  173.   
  174.   expire_names(t);
  175.   expire_servers(t);
  176. }
  177.  
  178. /*****************************************************************************
  179.   reload the services file
  180.   **************************************************************************/
  181. BOOL reload_services(BOOL test)
  182. {
  183.   BOOL ret;
  184.   extern fstring remote_machine;
  185.  
  186.   strcpy(remote_machine,"nmbd");
  187.  
  188.   if (lp_loaded())
  189.     {
  190.       pstring fname;
  191.       pstrcpy(fname,lp_configfile());
  192.       if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
  193.     {
  194.       pstrcpy(servicesf,fname);
  195.       test = False;
  196.     }
  197.     }
  198.  
  199.   if (test && !lp_file_list_changed())
  200.     return(True);
  201.  
  202.   ret = lp_load(servicesf,True);
  203.  
  204.   /* perhaps the config filename is now set */
  205.   if (!test) {
  206.     DEBUG(3,("services not loaded\n"));
  207.     reload_services(True);
  208.   }
  209.  
  210.   /* Do a sanity check for a misconfigured nmbd */
  211.   if(lp_wins_support() && *lp_wins_server()) {
  212.     DEBUG(0,("ERROR: both 'wins support = true' and 'wins server = <server>' \
  213. cannot be set in the smb.conf file. nmbd aborting.\n"));
  214.     exit(10);
  215.   }
  216.  
  217.   return(ret);
  218. }
  219.  
  220.  
  221.  
  222. /****************************************************************************
  223. load a netbios hosts file
  224. ****************************************************************************/
  225. #ifdef USE_NETINFO
  226. /*
  227.  * The code to use when accesssing netinfo on NEXTSTEP/OPENSTEP
  228.  * This file is included in ../nmbd.c.
  229.  */
  230.  
  231. static void load_hosts_from_file(char *fname);
  232.  
  233. static void load_hosts_file(char *fname)
  234. {
  235.     ni_status        status;
  236.     ni_name            name, netbiosname, ip;
  237.     ni_id                ndir;
  238.     ni_idlist        ndirs;
  239.     void                *handle;
  240.     ni_proplist    props;
  241.  
  242.     int                    i,j,k;
  243.   struct subnet_record    *d;
  244.   struct in_addr                ipaddr;
  245.   enum name_source            source;
  246.  
  247.     DEBUG(10, ("load_hosts: opening netinfo for netbios hosts.\n"));
  248.  
  249.     /*
  250.      * Scan the NetInfo hierarchy, starting from the local level,
  251.      * until either an entry is found or we are past the top level.
  252.      */
  253.     handle = NULL;
  254.     status = ni_search_for_dir(S_HOSTDIR, ".", &handle, &ndir, 5, 0, 1);
  255.  
  256.     while (status == NI_OK) {
  257.     
  258.         /* Read the directory and all its subdirectories. */
  259.         status = ni_children(handle, &ndir, &ndirs);
  260.         if (status != NI_OK) {
  261.             ni_free(handle);
  262.             DEBUG(0, ("Unable to get netinfo entries for hosts.\n"));
  263.             return;
  264.         }            
  265.  
  266.         /*
  267.          * For each subdirectory, scan the properties for the S_NETBIOSNAME property.
  268.          * If any is present, compare to the name passed.
  269.          */
  270.         for (k = 0; k < ndirs.ni_idlist_len; k++) {
  271.  
  272.             /* Read the directory and all its properties, set the indexes. */
  273.             ndir.nii_object = ndirs.ni_idlist_val[k];
  274.             status = ni_read(handle, &ndir, &props);
  275.             if (status != NI_OK) {
  276.                 DEBUG(0, ("Unable to get netinfo entries for printer with ID %d.\n", ndirs.ni_idlist_val[i]));
  277.                 continue;
  278.             }            
  279.  
  280.             netbiosname = NULL;
  281.             name = NULL;
  282.             ip = NULL;
  283.             source = LMHOSTS;
  284.             for (i = 0; i < props.ni_proplist_len; i++) {
  285.                 if (!strcmp(PWENTNAME(i), S_NETBIOSNAME))
  286.                     netbiosname = PWENTVALU(i);
  287.                 else if (!strcmp(PWENTNAME(i), S_HOSTNAME))
  288.                     name = PWENTVALU(i);
  289.                 else if (!strcmp(PWENTNAME(i), S_HOSTIP))
  290.                     ip = PWENTVALU(i);
  291.             }
  292.  
  293.             if ((netbiosname != NULL) && ((name != NULL) || (ip != NULL))){
  294.                 if (!strcmp(myhostname, name))
  295.                     source = SELF;
  296.                 ipaddr = *interpret_addr2((ip!=NULL)?ip:name);
  297.                 d = find_subnet_all(ipaddr);
  298.           DEBUG(4, ("lmhost entry: %s %s (%s)\n", ip, netbiosname, name));
  299.                 if (d) {
  300.                     add_netbios_entry(d, netbiosname, 0x00, NB_ACTIVE, 0, source, ipaddr, True, True);
  301.                     add_netbios_entry(d, netbiosname, 0x20, NB_ACTIVE, 0, source, ipaddr, True, True);
  302.                 } 
  303.  
  304.             }
  305.             ni_proplist_free(&props);
  306.         }
  307.         ni_idlist_free(&ndirs);
  308.         
  309.         status = ni_search_for_dir(S_HOSTDIR, "..", &handle, &ndir, 5, 0, 1);
  310.     } 
  311.  
  312.     if (strcmp("netinfo", fname)) {
  313.         DEBUG(0, ("Checking flat lmhosts file %s\n", fname));
  314.         load_hosts_from_file(fname);
  315.     }
  316.     
  317. }
  318.  
  319. static void load_hosts_from_file(char *fname)
  320. #else /* ! USE_NETINFO */
  321. static void load_hosts_file(char *fname)
  322. #endif
  323. {
  324.  
  325.   FILE *f = fopen(fname,"r");
  326.   pstring line;
  327.   if (!f) {
  328.     DEBUG(2,("Can't open lmhosts file %s\n",fname));
  329.     return;
  330.   }
  331.  
  332.   while (!feof(f))
  333.     {
  334.       pstring ip,name,flags,extra;
  335.       struct subnet_record *d;
  336.       char *ptr;
  337.       int count = 0;
  338.       struct in_addr ipaddr;
  339.       enum name_source source = LMHOSTS;
  340.  
  341.       if (!fgets_slash(line,sizeof(pstring),f)) continue;
  342.  
  343.       if (*line == '#') continue;
  344.  
  345.       strcpy(ip,"");
  346.       strcpy(name,"");
  347.       strcpy(flags,"");
  348.       
  349.       ptr = line;
  350.       
  351.       if (next_token(&ptr,ip   ,NULL)) ++count;
  352.       if (next_token(&ptr,name ,NULL)) ++count;
  353.       if (next_token(&ptr,flags,NULL)) ++count;
  354.       if (next_token(&ptr,extra,NULL)) ++count;
  355.       
  356.       if (count <= 0) continue;
  357.       
  358.       if (count > 0 && count < 2) {
  359.     DEBUG(0,("Ill formed hosts line [%s]\n",line));        
  360.     continue;
  361.       }
  362.       
  363.       if (count >= 4) {
  364.     DEBUG(0,("too many columns in %s (obsolete syntax)\n",fname));
  365.     continue;
  366.       }
  367.       
  368.       DEBUG(4, ("lmhost entry: %s %s %s\n", ip, name, flags));
  369.       
  370.       if (strchr(flags,'G') || strchr(flags,'S')) {
  371.     DEBUG(0,("group flag in %s ignored (obsolete)\n",fname));
  372.     continue;
  373.       }
  374.       
  375.       if (strchr(flags,'M')) {
  376.     source = SELF;
  377.     pstrcpy(myname,name);
  378.       }
  379.       
  380.       ipaddr = *interpret_addr2(ip);
  381.       d = find_subnet_all(ipaddr);
  382.       if (d) {
  383.     add_netbios_entry(d,name,0x00,NB_ACTIVE,0,source,ipaddr,True,True);
  384.     add_netbios_entry(d,name,0x20,NB_ACTIVE,0,source,ipaddr,True,True);
  385.       } 
  386.     }
  387.   
  388.   fclose(f);
  389. }
  390.  
  391.  
  392. /****************************************************************************
  393.   The main select loop.
  394.   ***************************************************************************/
  395. static void process(void)
  396. {
  397.   BOOL run_election;
  398.  
  399.   while (True)
  400.     {
  401.       time_t t = time(NULL);
  402.       run_election = check_elections();
  403.       listen_for_packets(run_election);
  404.  
  405.       run_packet_queue();
  406.       run_elections(t);
  407.  
  408.       announce_host(t);
  409.       announce_master(t);
  410.       announce_remote(t);
  411.  
  412.       query_refresh_names(t);
  413.  
  414.       expire_names_and_servers(t);
  415.       expire_netbios_response_entries(t);
  416.       refresh_my_names(t);
  417.  
  418.       write_browse_list(t);
  419.       do_browser_lists(t);
  420.       check_master_browser(t);
  421.       add_domain_names(t);
  422.     }
  423. }
  424.  
  425.  
  426. /****************************************************************************
  427.   open the socket communication
  428. ****************************************************************************/
  429. static BOOL open_sockets(BOOL isdaemon, int port)
  430. {
  431.   struct hostent *hp;
  432.  
  433.   /* get host info */
  434.   if ((hp = Get_Hostbyname(myhostname)) == 0) {
  435.     DEBUG(0,( "Get_Hostbyname: Unknown host. %s\n",myhostname));
  436.     return False;
  437.   }   
  438.  
  439.   if (isdaemon)
  440.     ClientNMB = open_socket_in(SOCK_DGRAM, port,0,interpret_addr(lp_socket_address()));
  441.   else
  442.     ClientNMB = 0;
  443.   
  444.   ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3,interpret_addr(lp_socket_address()));
  445.  
  446.   if (ClientNMB == -1)
  447.     return(False);
  448.  
  449.   signal(SIGPIPE, SIGNAL_CAST sig_pipe);
  450.  
  451.   set_socket_options(ClientNMB,"SO_BROADCAST");
  452.   set_socket_options(ClientDGRAM,"SO_BROADCAST");
  453.  
  454.   DEBUG(3,("Sockets opened.\n"));
  455.   return True;
  456. }
  457.  
  458.  
  459. /****************************************************************************
  460.   initialise connect, service and file structs
  461. ****************************************************************************/
  462. static BOOL init_structs()
  463. {
  464.   extern fstring local_machine;
  465.   char *p, *ptr;
  466.   int namecount;
  467.   int n;
  468.   int nodup;
  469.   pstring nbname;
  470.  
  471.   if (! *myname) {
  472.        pstrcpy(myname,myhostname);
  473.     p = strchr(myname,'.');
  474.     if (p) *p = 0;
  475.   }
  476.   strupper(myname);
  477.  
  478.   /* Add any NETBIOS name aliases. Ensure that the first entry
  479.      is equal to myname. */
  480.   /* Work out the max number of netbios aliases that we have */
  481.   ptr=lp_netbios_aliases();
  482.   for (namecount=0; next_token(&ptr,nbname,NULL); namecount++)
  483.     ;
  484.   if (*myname)
  485.       namecount++;
  486.  
  487.   /* Allocate space for the netbios aliases */
  488.   if((my_netbios_names=(char **)malloc(sizeof(char *)*(namecount+1))) == NULL)
  489.   {
  490.      DEBUG(0,("init_structs: malloc fail.\n"));
  491.      return False;
  492.   }
  493.  
  494.   /* Use the myname string first */
  495.   namecount=0;
  496.   if (*myname)
  497.     my_netbios_names[namecount++] = myname;
  498.   
  499.   ptr=lp_netbios_aliases();
  500.   while (next_token(&ptr,nbname,NULL)) {
  501.     strupper(nbname);
  502.     /* Look for duplicates */
  503.     nodup=1;
  504.     for(n=0; n<namecount; n++) {
  505.       if (strcmp(nbname, my_netbios_names[n])==0)
  506.         nodup=0;
  507.     }
  508.     if (nodup)
  509.       my_netbios_names[namecount++]=strdup(nbname);
  510.   }
  511.   
  512.   /* Check the strdups succeeded. */
  513.   for(n = 0; n < namecount; n++)
  514.     if(my_netbios_names[n]==NULL)
  515.     {
  516.       DEBUG(0,("init_structs: malloc fail when allocating names.\n"));
  517.       return False;
  518.     }
  519.   
  520.   /* Terminate name list */
  521.   my_netbios_names[namecount++]=NULL;
  522.   
  523.   fstrcpy(local_machine,myname);
  524.   trim_string(local_machine," "," ");
  525.   p = strchr(local_machine,' ');
  526.   if (p) 
  527.     *p = 0;
  528.   strlower(local_machine);
  529.  
  530.   DEBUG(5, ("Netbios name list:-\n"));
  531.   for (n=0; my_netbios_names[n]; n++)
  532.     DEBUG(5, ("my_netbios_names[%d]=\"%s\"\n", n, my_netbios_names[n]));
  533.  
  534.   return True;
  535. }
  536.  
  537. /****************************************************************************
  538. usage on the program
  539. ****************************************************************************/
  540. static void usage(char *pname)
  541. {
  542.   DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
  543.  
  544.   printf("Usage: %s [-n name] [-D] [-p port] [-d debuglevel] [-l log basename]\n",pname);
  545.   printf("Version %s\n",VERSION);
  546.   printf("\t-D                    become a daemon\n");
  547.   printf("\t-p port               listen on the specified port\n");
  548.   printf("\t-d debuglevel         set the debuglevel\n");
  549.   printf("\t-l log basename.      Basename for log/debug files\n");
  550.   printf("\t-n netbiosname.       the netbios name to advertise for this host\n");
  551.   printf("\t-H hosts file        load a netbios hosts file\n");
  552.   printf("\n");
  553. }
  554.  
  555.  
  556. /****************************************************************************
  557.   main program
  558.   **************************************************************************/
  559.  int main(int argc,char *argv[])
  560. {
  561.   int port = NMB_PORT;
  562.   int opt;
  563.   extern FILE *dbf;
  564.   extern char *optarg;
  565.   char pidFile[100] = { 0 };
  566. #ifdef USE_NETINFO
  567.     char    *opts = "s:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:f:V";
  568. #else
  569.     char    *opts = "s:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:f:";
  570. #endif
  571.  
  572.   *host_file = 0;
  573.  
  574.   StartupTime = time(NULL);
  575.  
  576.   TimeInit();
  577.  
  578.   strcpy(debugf,NMBLOGFILE);
  579.  
  580.   setup_logging(argv[0],False);
  581.  
  582.   charset_initialise();
  583.  
  584. #ifdef LMHOSTSFILE
  585.   strcpy(host_file,LMHOSTSFILE);
  586. #endif
  587.  
  588.   /* this is for people who can't start the program correctly */
  589.   while (argc > 1 && (*argv[1] != '-')) {
  590.     argv++;
  591.     argc--;
  592.   }
  593.  
  594.   fault_setup(fault_continue);
  595.  
  596.   signal(SIGHUP ,SIGNAL_CAST sig_hup);
  597.   signal(SIGTERM,SIGNAL_CAST sig_term);
  598.  
  599.   while ((opt = getopt(argc, argv, opts)) != EOF)
  600.     {
  601.       switch (opt)
  602.     {
  603.         case 'f':
  604.           strncpy(pidFile, optarg, sizeof(pidFile));
  605.           break;
  606.     case 's':
  607.       pstrcpy(servicesf,optarg);
  608.       break;      
  609.     case 'N':
  610.     case 'B':
  611.     case 'I':
  612.     case 'C':
  613.     case 'G':
  614.       DEBUG(0,("Obsolete option '%c' used\n",opt));
  615.       break;
  616.     case 'H':
  617.       pstrcpy(host_file,optarg);
  618.       break;
  619.     case 'n':
  620.       pstrcpy(myname,optarg);
  621.       strupper(myname);
  622.       break;
  623.     case 'l':
  624.       sprintf(debugf,"%s.nmb",optarg);
  625.       break;
  626.     case 'i':
  627.       pstrcpy(scope,optarg);
  628.       strupper(scope);
  629.       break;
  630.     case 'D':
  631.       is_daemon = True;
  632.       break;
  633.     case 'd':
  634.       DEBUGLEVEL = atoi(optarg);
  635.       break;
  636.     case 'p':
  637.       port = atoi(optarg);
  638.       break;
  639.     case 'h':
  640.       usage(argv[0]);
  641.       exit(0);
  642.       break;
  643. #ifdef USE_NETINFO
  644.     case 'V':
  645.         printf("NetInfo based netbios nameserver version %s.\n", VERSION);
  646.         exit(0);
  647. #endif /* USE_NETINFO */
  648.     default:
  649.       if (!is_a_socket(0)) {
  650.         usage(argv[0]);
  651.       }
  652.       break;
  653.     }
  654.     }
  655.  
  656.   DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION));
  657.   DEBUG(1,("Copyright Andrew Tridgell 1994-1997\n"));
  658.  
  659.   if(!get_myname(myhostname,NULL))
  660.   {
  661.     DEBUG(0,("Unable to get my hostname - exiting.\n"));
  662.     return -1;
  663.   }
  664.  
  665.   if (!reload_services(False))
  666.     return(-1);    
  667.  
  668.   codepage_initialise(lp_client_code_page());
  669.  
  670.   if(!init_structs())
  671.     return -1;
  672.  
  673.   reload_services(True);
  674.  
  675.   pstrcpy(myworkgroup, lp_workgroup());
  676.  
  677.   if (strequal(myworkgroup,"*")) {
  678.     DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
  679.     exit(1);
  680.   }
  681.  
  682.   set_samba_nb_type();
  683.  
  684.   if (!is_daemon && !is_a_socket(0)) {
  685.     DEBUG(0,("standard input is not a socket, assuming -D option\n"));
  686.     is_daemon = True;
  687.   }
  688.   
  689.   if (is_daemon) {
  690.     DEBUG(2,("%s becoming a daemon\n",timestring()));
  691.     become_daemon();
  692.   }
  693.  
  694.   if (*pidFile)
  695.     {
  696.       int     fd;
  697.       char    buf[20];
  698.  
  699.       if ((fd = open(pidFile,
  700. #ifdef O_NONBLOCK
  701.         O_NONBLOCK | 
  702. #endif
  703.         O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0)
  704.         {
  705.           DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
  706.           exit(1);
  707.         }
  708.       if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
  709.         {
  710.           DEBUG(0,("ERROR: nmbd is already running\n"));
  711.           exit(1);
  712.         }
  713.       sprintf(buf, "%u\n", (unsigned int) getpid());
  714.       if (write(fd, buf, strlen(buf)) < 0)
  715.         {
  716.           DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
  717.           exit(1);
  718.         }
  719.       /* Leave pid file open & locked for the duration... */
  720.     }
  721.  
  722.  
  723.   DEBUG(3,("Opening sockets %d\n", port));
  724.  
  725.   if (!open_sockets(is_daemon,port)) return 1;
  726.  
  727.   load_interfaces();
  728.   add_my_subnets(myworkgroup);
  729.  
  730.   add_my_names();
  731.  
  732.   DEBUG(3,("Checked names\n"));
  733.   
  734.   load_netbios_names();
  735.  
  736.   DEBUG(3,("Loaded names\n"));
  737.  
  738.   if (*host_file) {
  739.     load_hosts_file(host_file);
  740.     DEBUG(3,("Loaded hosts file\n"));
  741.   }
  742.  
  743.   write_browse_list(time(NULL));
  744.  
  745.   DEBUG(3,("Dumped names\n"));
  746.  
  747.   /* We can only take sigterm signals in the select. */
  748.   BlockSignals(True,SIGTERM);
  749.   process();
  750.   close_sockets();
  751.  
  752.   if (dbf)
  753.     fclose(dbf);
  754.   return(0);
  755. }
  756.