⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nmbd.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   Unix SMB/CIFS implementation.   NBT netbios routines and daemon - version 2   Copyright (C) Andrew Tridgell 1994-1998   Copyright (C) Jeremy Allison 1997-2002   Copyright (C) Jelmer Vernooij 2002,2003 (Conversion to popt)      This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.      This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.      You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   */#include "includes.h"int ClientNMB       = -1;int ClientDGRAM     = -1;int global_nmb_port = -1;extern BOOL rescan_listen_set;extern struct in_addr loopback_ip;extern BOOL global_in_nmbd;extern BOOL override_logfile;/* are we running as a daemon ? */static BOOL is_daemon;/* fork or run in foreground ? */static BOOL Fork = True;/* log to standard output ? */static BOOL log_stdout;/* have we found LanMan clients yet? */BOOL found_lm_clients = False;/* what server type are we currently */time_t StartupTime = 0;/**************************************************************************** ** Handle a SIGTERM in band. **************************************************************************** */static void terminate(void){	DEBUG(0,("Got SIGTERM: going down...\n"));  	/* Write out wins.dat file if samba is a WINS server */	wins_write_database(False);  	/* Remove all SELF registered names from WINS */	release_wins_names();  	/* Announce all server entries as 0 time-to-live, 0 type. */	announce_my_servers_removed();	/* If there was an async dns child - kill it. */	kill_async_dns_child();	exit(0);}/**************************************************************************** ** Handle a SHUTDOWN message from smbcontrol. **************************************************************************** */static void nmbd_terminate(int msg_type, struct process_id src,			   void *buf, size_t len){	terminate();}/**************************************************************************** ** Catch a SIGTERM signal. **************************************************************************** */static SIG_ATOMIC_T got_sig_term;static void sig_term(int sig){	got_sig_term = 1;	sys_select_signal(SIGTERM);}/**************************************************************************** ** Catch a SIGHUP signal. **************************************************************************** */static SIG_ATOMIC_T reload_after_sighup;static void sig_hup(int sig){	reload_after_sighup = 1;	sys_select_signal(SIGHUP);}#if DUMP_CORE/**************************************************************************** ** Prepare to dump a core file - carefully! **************************************************************************** */static BOOL dump_core(void){	char *p;	pstring dname;	pstrcpy( dname, lp_logfile() );	if ((p=strrchr_m(dname,'/')))		*p=0;	pstrcat( dname, "/corefiles" );	mkdir( dname, 0700 );	sys_chown( dname, getuid(), getgid() );	chmod( dname, 0700 );	if ( chdir(dname) )		return( False );	umask( ~(0700) );#ifdef HAVE_GETRLIMIT#ifdef RLIMIT_CORE	{		struct rlimit rlp;		getrlimit( RLIMIT_CORE, &rlp );		rlp.rlim_cur = MAX( 4*1024*1024, rlp.rlim_cur );		setrlimit( RLIMIT_CORE, &rlp );		getrlimit( RLIMIT_CORE, &rlp );		DEBUG( 3, ( "Core limits now %d %d\n", (int)rlp.rlim_cur, (int)rlp.rlim_max ) );	}#endif#endif	DEBUG(0,("Dumping core in %s\n",dname));	abort();	return( True );}#endif/**************************************************************************** ** Possibly continue after a fault. **************************************************************************** */static void fault_continue(void){#if DUMP_CORE	dump_core();#endif}/**************************************************************************** ** Expire old names from the namelist and server list. **************************************************************************** */static void expire_names_and_servers(time_t t){	static time_t lastrun = 0;  	if ( !lastrun )		lastrun = t;	if ( t < (lastrun + 5) )		return;	lastrun = t;	/*	 * Expire any timed out names on all the broadcast	 * subnets and those registered with the WINS server.	 * (nmbd_namelistdb.c)	 */	expire_names(t);	/*	 * Go through all the broadcast subnets and for each	 * workgroup known on that subnet remove any expired	 * server names. If a workgroup has an empty serverlist	 * and has itself timed out then remove the workgroup.	 * (nmbd_workgroupdb.c)	 */	expire_workgroups_and_servers(t);}/************************************************************************** ** Reload the list of network interfaces. ************************************************************************** */static BOOL reload_interfaces(time_t t){	static time_t lastt;	int n;	struct subnet_record *subrec;	if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) return False;	lastt = t;	if (!interfaces_changed()) return False;	/* the list of probed interfaces has changed, we may need to add/remove	   some subnets */	load_interfaces();	/* find any interfaces that need adding */	for (n=iface_count() - 1; n >= 0; n--) {		struct interface *iface = get_interface(n);		/*		 * We don't want to add a loopback interface, in case		 * someone has added 127.0.0.1 for smbd, nmbd needs to		 * ignore it here. JRA.		 */		if (ip_equal(iface->ip, loopback_ip)) {			DEBUG(2,("reload_interfaces: Ignoring loopback interface %s\n", inet_ntoa(iface->ip)));			continue;		}		for (subrec=subnetlist; subrec; subrec=subrec->next) {			if (ip_equal(iface->ip, subrec->myip) &&			    ip_equal(iface->nmask, subrec->mask_ip)) break;		}		if (!subrec) {			/* it wasn't found! add it */			DEBUG(2,("Found new interface %s\n", 				 inet_ntoa(iface->ip)));			subrec = make_normal_subnet(iface);			if (subrec)				register_my_workgroup_one_subnet(subrec);		}	}	/* find any interfaces that need deleting */	for (subrec=subnetlist; subrec; subrec=subrec->next) {		for (n=iface_count() - 1; n >= 0; n--) {			struct interface *iface = get_interface(n);			if (ip_equal(iface->ip, subrec->myip) &&			    ip_equal(iface->nmask, subrec->mask_ip)) break;		}		if (n == -1) {			/* oops, an interface has disapeared. This is			 tricky, we don't dare actually free the			 interface as it could be being used, so			 instead we just wear the memory leak and			 remove it from the list of interfaces without			 freeing it */			DEBUG(2,("Deleting dead interface %s\n", 				 inet_ntoa(subrec->myip)));			close_subnet(subrec);		}	}		rescan_listen_set = True;	/* We need to shutdown if there are no subnets... */	if (FIRST_SUBNET == NULL) {		DEBUG(0,("reload_interfaces: No subnets to listen to. Shutting down...\n"));		return True;	}	return False;}/**************************************************************************** ** Reload the services file. **************************************************************************** */static BOOL reload_nmbd_services(BOOL test){	BOOL ret;	set_remote_machine_name("nmbd", False);	if ( lp_loaded() ) {		pstring fname;		pstrcpy( fname,lp_configfile());		if (file_exist(fname,NULL) && !strcsequal(fname,dyn_CONFIGFILE)) {			pstrcpy(dyn_CONFIGFILE,fname);			test = False;		}	}	if ( test && !lp_file_list_changed() )		return(True);	ret = lp_load( dyn_CONFIGFILE, True , False, False);	/* perhaps the config filename is now set */	if ( !test ) {		DEBUG( 3, ( "services not loaded\n" ) );		reload_nmbd_services( True );	}	return(ret);}/**************************************************************************** ** * React on 'smbcontrol nmbd reload-config' in the same way as to SIGHUP * We use buf here to return BOOL result to process() when reload_interfaces() * detects that there are no subnets. **************************************************************************** */static void msg_reload_nmbd_services(int msg_type, struct process_id src,				     void *buf, size_t len){	write_browse_list( 0, True );	dump_all_namelists();	reload_nmbd_services( True );	reopen_logs();		if(buf) {		/* We were called from process() */		/* If reload_interfaces() returned True */		/* we need to shutdown if there are no subnets... */		/* pass this info back to process() */		*((BOOL*)buf) = reload_interfaces(0);  	}}static void msg_nmbd_send_packet(int msg_type, struct process_id src,				 void *buf, size_t len){	struct packet_struct *p = (struct packet_struct *)buf;	struct subnet_record *subrec;	struct in_addr *local_ip;	DEBUG(10, ("Received send_packet from %d\n", procid_to_pid(&src)));	if (len != sizeof(struct packet_struct)) {		DEBUG(2, ("Discarding invalid packet length from %d\n",			  procid_to_pid(&src)));		return;	}	if ((p->packet_type != NMB_PACKET) &&	    (p->packet_type != DGRAM_PACKET)) {		DEBUG(2, ("Discarding invalid packet type from %d: %d\n",			  procid_to_pid(&src), p->packet_type));		return;	}	local_ip = iface_ip(p->ip);	if (local_ip == NULL) {		DEBUG(2, ("Could not find ip for packet from %d\n",			  procid_to_pid(&src)));		return;	}	subrec = FIRST_SUBNET;	p->fd = (p->packet_type == NMB_PACKET) ?		subrec->nmb_sock : subrec->dgram_sock;	for (subrec = FIRST_SUBNET; subrec != NULL;	     subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {		if (ip_equal(*local_ip, subrec->myip)) {			p->fd = (p->packet_type == NMB_PACKET) ?				subrec->nmb_sock : subrec->dgram_sock;			break;		}	}	if (p->packet_type == DGRAM_PACKET) {		p->port = 138;		p->packet.dgram.header.source_ip.s_addr = local_ip->s_addr;		p->packet.dgram.header.source_port = 138;	}	send_packet(p);}/**************************************************************************** ** The main select loop. **************************************************************************** */static void process(void){	BOOL run_election;	BOOL no_subnets;	while( True ) {		time_t t = time(NULL);		/* Check for internal messages */		message_dispatch();		/*		 * Check all broadcast subnets to see if		 * we need to run an election on any of them.		 * (nmbd_elections.c)		 */		run_election = check_elections();		/*		 * Read incoming UDP packets.		 * (nmbd_packets.c)		 */		if(listen_for_packets(run_election))			return;		/*		 * Handle termination inband.		 */		if (got_sig_term) {			got_sig_term = 0;			terminate();		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -