Пример #1
0
 int main(int argc, char *argv[])
{
	pid_t pid;
	int i, n;
	static pstring servicesf = CONFIGFILE;
	char buf[12];

	TimeInit();
	setup_logging(argv[0],True);
	
	charset_initialise();

	lp_load(servicesf,False,False,False);

	message_init();

	if (argc != 3) {
		fprintf(stderr, "%s: Usage - %s pid count\n", argv[0], argv[0]);
		exit(1);
	}

	pid = atoi(argv[1]);
	n = atoi(argv[2]);

	message_register(MSG_PONG, pong_message);

	for (i=0;i<n;i++) {
		message_send_pid(pid, MSG_PING, NULL, 0, True);
	}

	while (pong_count < i) {
		message_dispatch();
		msleep(1);
	}

	/* Now test that the duplicate filtering code works. */
	pong_count = 0;

	safe_strcpy(buf, "1234567890", sizeof(buf)-1);

	for (i=0;i<n;i++) {
		message_send_pid(getpid(), MSG_PING, NULL, 0, False);
		message_send_pid(getpid(), MSG_PING, buf, 11, False);
	}

	for (i=0;i<n;i++) {
		message_dispatch();
		msleep(1);
	}

	if (pong_count != 2) {
		fprintf(stderr, "Duplicate filter failed (%d).\n", pong_count);
		exit(1);
	}

	return (0);
}
Пример #2
0
static void wait_replies(BOOL multiple_replies)
{
	time_t start_time = time(NULL);

	/* Wait around a bit.  This is pretty disgusting - we have to
           busy-wait here as there is no nicer way to do it. */

	do {
		message_dispatch();
		if (num_replies > 0 && !multiple_replies)
			break;
		sleep(1);
	} while (timeout - (time(NULL) - start_time) > 0);
}
Пример #3
0
Файл: app.c Проект: tstih/yx
void main() {

	/* init OS wrapper */	
	heap_size=0xffff - (word)&heap; /* calc heap size */
	register_interfaces();
	yx=(yx_t *)query_interface("yx");

	/* init buddy */
	buddy_init();

	/* main loop */
	while (TRUE) {
		buddy_harvest_events();
		message_dispatch();
	}
}
Пример #4
0
static void wait_replies(BOOL multiple_replies)
{
	time_t start_time = 0;

	/* Wait around a bit.  This is pretty disgusting - we have to
           busy-wait here as there is no nicer way to do it. */

	do {
		start_time = time(NULL);
		message_dispatch();
		if (num_replies > 0 && !multiple_replies)
			break;
		do
			sleep(1);
		while ((5 + start_time - time(NULL)) > 0 && num_replies == 0);
		if (num_replies > 0 && !multiple_replies)
			break;
	} while (1);
}
Пример #5
0
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();
		}

		/*
		 * Process all incoming packets
		 * read above. This calls the success and
		 * failure functions registered when response
		 * packets arrrive, and also deals with request
		 * packets from other sources.
		 * (nmbd_packets.c)
		 */

		run_packet_queue();

		/*
		 * Run any elections - initiate becoming
		 * a local master browser if we have won.
		 * (nmbd_elections.c)
		 */

		run_elections(t);

		/*
		 * Send out any broadcast announcements
		 * of our server names. This also announces
		 * the workgroup name if we are a local
		 * master browser.
		 * (nmbd_sendannounce.c)
		 */

		announce_my_server_names(t);

		/*
		 * Send out any LanMan broadcast announcements
		 * of our server names.
		 * (nmbd_sendannounce.c)
		 */

		announce_my_lm_server_names(t);

		/*
		 * If we are a local master browser, periodically
		 * announce ourselves to the domain master browser.
		 * This also deals with syncronising the domain master
		 * browser server lists with ourselves as a local
		 * master browser.
		 * (nmbd_sendannounce.c)
		 */

		announce_myself_to_domain_master_browser(t);

		/*
		 * Fullfill any remote announce requests.
		 * (nmbd_sendannounce.c)
		 */

		announce_remote(t);

		/*
		 * Fullfill any remote browse sync announce requests.
		 * (nmbd_sendannounce.c)
		 */

		browse_sync_remote(t);

		/*
		 * Scan the broadcast subnets, and WINS client
		 * namelists and refresh any that need refreshing.
		 * (nmbd_mynames.c)
		 */

		refresh_my_names(t);

		/*
		 * Scan the subnet namelists and server lists and
		 * expire thos that have timed out.
		 * (nmbd.c)
		 */

		expire_names_and_servers(t);

		/*
		 * Write out a snapshot of our current browse list into
		 * the browse.dat file. This is used by smbd to service
		 * incoming NetServerEnum calls - used to synchronise
		 * browse lists over subnets.
		 * (nmbd_serverlistdb.c)
		 */

		write_browse_list(t, False);

		/*
		 * If we are a domain master browser, we have a list of
		 * local master browsers we should synchronise browse
		 * lists with (these are added by an incoming local
		 * master browser announcement packet). Expire any of
		 * these that are no longer current, and pull the server
		 * lists from each of these known local master browsers.
		 * (nmbd_browsesync.c)
		 */

		dmb_expire_and_sync_browser_lists(t);

		/*
		 * Check that there is a local master browser for our
		 * workgroup for all our broadcast subnets. If one
		 * is not found, start an election (which we ourselves
		 * may or may not participate in, depending on the
		 * setting of the 'local master' parameter.
		 * (nmbd_elections.c)
		 */

		check_master_browser_exists(t);

		/*
		 * If we are configured as a logon server, attempt to
		 * register the special NetBIOS names to become such
		 * (WORKGROUP<1c> name) on all broadcast subnets and
		 * with the WINS server (if used). If we are configured
		 * to become a domain master browser, attempt to register
		 * the special NetBIOS name (WORKGROUP<1b> name) to
		 * become such.
		 * (nmbd_become_dmb.c)
		 */

		add_domain_names(t);

		/*
		 * If we are a WINS server, do any timer dependent
		 * processing required.
		 * (nmbd_winsserver.c)
		 */

		initiate_wins_processing(t);

		/*
		 * If we are a domain master browser, attempt to contact the
		 * WINS server to get a list of all known WORKGROUPS/DOMAINS.
		 * This will only work to a Samba WINS server.
		 * (nmbd_browsesync.c)
		 */

		if (lp_enhanced_browsing())
			collect_all_workgroup_names_from_wins_server(t);

		/*
		 * Go through the response record queue and time out or re-transmit
		 * and expired entries.
		 * (nmbd_packets.c)
		 */

		retransmit_or_expire_response_records(t);

		/*
		 * check to see if any remote browse sync child processes have completed
		 */

		sync_check_completion();

		/*
		 * regularly sync with any other DMBs we know about 
		 */

		if (lp_enhanced_browsing())
			sync_all_dmbs(t);

		/*
		 * clear the unexpected packet queue 
		 */

		clear_unexpected(t);

		/*
		 * Reload the services file if we got a sighup.
		 */

		if(reload_after_sighup) {
			DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) );
			msg_reload_nmbd_services(MSG_SMB_CONF_UPDATED,
						 pid_to_procid(0), (void*) &no_subnets, 0, NULL);
			if(no_subnets)
				return;
			reload_after_sighup = 0;
		}

		/* check for new network interfaces */

		if(reload_interfaces(t))
			return;

		/* free up temp memory */
			lp_TALLOC_FREE();
	}
}
Пример #6
0
static void process_loop(void)
{
	/* We'll be doing this a lot */

	while (1) {
		struct winbindd_cli_state *state;
		fd_set r_fds, w_fds;
		int maxfd, listen_sock, listen_priv_sock, selret;
		struct timeval timeout;

		/* Handle messages */

		message_dispatch();

		/* refresh the trusted domain cache */
		   
		rescan_trusted_domains();

		/* Free up temporary memory */

		lp_talloc_free();
		main_loop_talloc_free();

		/* Initialise fd lists for select() */

		listen_sock = open_winbindd_socket();
		listen_priv_sock = open_winbindd_priv_socket();

		if (listen_sock == -1 || listen_priv_sock == -1) {
			perror("open_winbind_socket");
			exit(1);
		}

		maxfd = MAX(listen_sock, listen_priv_sock);

		FD_ZERO(&r_fds);
		FD_ZERO(&w_fds);
		FD_SET(listen_sock, &r_fds);
		FD_SET(listen_priv_sock, &r_fds);

		timeout.tv_sec = WINBINDD_ESTABLISH_LOOP;
		timeout.tv_usec = 0;

		if (opt_dual_daemon) {
			maxfd = dual_select_setup(&w_fds, maxfd);
		}

		/* Set up client readers and writers */

		state = winbindd_client_list();

		while (state) {

			/* Dispose of client connection if it is marked as 
			   finished */ 

			if (state->finished) {
				struct winbindd_cli_state *next = state->next;

				remove_client(state);
				state = next;
				continue;
			}

			/* Select requires we know the highest fd used */

			if (state->sock > maxfd)
				maxfd = state->sock;

			/* Add fd for reading */

			if (state->read_buf_len != sizeof(state->request))
				FD_SET(state->sock, &r_fds);

			/* Add fd for writing */

			if (state->write_buf_len)
				FD_SET(state->sock, &w_fds);

			state = state->next;
		}

		/* Call select */
        
		selret = sys_select(maxfd + 1, &r_fds, &w_fds, NULL, &timeout);

		if (selret == 0)
			continue;

		if ((selret == -1 && errno != EINTR) || selret == 0) {

			/* Select error, something is badly wrong */

			perror("select");
			exit(1);
		}

		/* Create a new connection if listen_sock readable */

		if (selret > 0) {

			if (opt_dual_daemon) {
				dual_select(&w_fds);
			}

			if (FD_ISSET(listen_sock, &r_fds)) {
				while (winbindd_num_clients() > WINBINDD_MAX_SIMULTANEOUS_CLIENTS - 1) {
					DEBUG(5,("winbindd: Exceeding %d client connections, removing idle connection.\n",
						WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
					if (!remove_idle_client()) {
						DEBUG(0,("winbindd: Exceeding %d client connections, no idle connection found\n",
							WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
						break;
					}
				}
				/* new, non-privileged connection */
				new_connection(listen_sock, False);
			}
            
			if (FD_ISSET(listen_priv_sock, &r_fds)) {
				while (winbindd_num_clients() > WINBINDD_MAX_SIMULTANEOUS_CLIENTS - 1) {
					DEBUG(5,("winbindd: Exceeding %d client connections, removing idle connection.\n",
						WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
					if (!remove_idle_client()) {
						DEBUG(0,("winbindd: Exceeding %d client connections, no idle connection found\n",
							WINBINDD_MAX_SIMULTANEOUS_CLIENTS));
						break;
					}
				}
				/* new, privileged connection */
				new_connection(listen_priv_sock, True);
			}
            
			/* Process activity on client connections */
            
			for (state = winbindd_client_list(); state; 
			     state = state->next) {
                
				/* Data available for reading */
                
				if (FD_ISSET(state->sock, &r_fds)) {
                    
					/* Read data */
                    
					winbind_client_read(state);

					/* 
					 * If we have the start of a
					 * packet, then check the
					 * length field to make sure
					 * the client's not talking
					 * Mock Swedish.
					 */

					if (state->read_buf_len >= sizeof(uint32)
					    && *(uint32 *) &state->request != sizeof(state->request)) {
						DEBUG(0,("process_loop: Invalid request size from pid %lu: %d bytes sent, should be %ld\n",
								(unsigned long)state->request.pid, *(uint32 *) &state->request, (unsigned long)sizeof(state->request)));
						DEBUGADD(0, ("This usually means that you are running old wbinfo, pam_winbind or libnss_winbind clients\n"));

						remove_client(state);
						break;
					}

					/* A request packet might be 
					   complete */
                    
					if (state->read_buf_len == 
					    sizeof(state->request)) {
						winbind_process_packet(state);
					}
				}
                
				/* Data available for writing */
                
				if (FD_ISSET(state->sock, &w_fds))
					client_write(state);
			}
		}

#if 0
		winbindd_check_cache_size(time(NULL));
#endif

		/* Check signal handling things */

		if (do_sigterm)
			terminate();

		if (do_sighup) {

			DEBUG(3, ("got SIGHUP\n"));

			msg_reload_services(MSG_SMB_CONF_UPDATED, (pid_t) 0, NULL, 0);
			do_sighup = False;
		}

		if (do_sigusr2) {
			print_winbindd_status();
			do_sigusr2 = False;
		}
	}
}
Пример #7
0
/****************************************************************************
do command
****************************************************************************/
static BOOL do_command(char *dest, char *msg_name, int iparams, char **params)
{
	int i, n, v;
	int mtype;
	BOOL retval=False;
	int debuglevel_class[DBGC_LAST];

	mtype = parse_type(msg_name);
	if (mtype == -1) {
		fprintf(stderr,"Couldn't resolve message type: %s\n", msg_name);
		return(False);
	}

	switch (mtype) {
	case MSG_DEBUG:
		if (!params || !params[0]) {
			fprintf(stderr,"MSG_DEBUG needs a parameter\n");
			return(False);
		}

		ZERO_ARRAY(debuglevel_class);
		if (!debug_parse_params(params, debuglevel_class)) {
			fprintf(stderr, "MSG_DEBUG error. Expected <class name>:level\n");
			return(False);
		} else
			send_message(dest, MSG_DEBUG, debuglevel_class, sizeof(debuglevel_class), False);
		break;

	case MSG_PROFILE:
		if (!params || !params[0]) {
			fprintf(stderr,"MSG_PROFILE needs a parameter\n");
			return(False);
		}
		if (strequal(params[0], "off")) {
			v = 0;
		} else if (strequal(params[0], "count")) {
			v = 1;
		} else if (strequal(params[0], "on")) {
			v = 2;
		} else if (strequal(params[0], "flush")) {
			v = 3;
		} else {
		    fprintf(stderr,
			"MSG_PROFILE parameter must be off, count, on, or flush\n");
		    return(False);
		}
		send_message(dest, MSG_PROFILE, &v, sizeof(int), False);
		break;

	case MSG_FORCE_ELECTION:
		if (!strequal(dest, "nmbd")) {
			fprintf(stderr,"force-election can only be sent to nmbd\n");
			return(False);
		}
		send_message(dest, MSG_FORCE_ELECTION, NULL, 0, False);
		break;

	case MSG_REQ_PROFILELEVEL:
		if (!profilelevel_registered) {
		    message_register(MSG_PROFILELEVEL, profilelevel_function);
		    profilelevel_registered = True;
		}
		got_level = False;
		retval = send_message(dest, MSG_REQ_PROFILELEVEL, NULL, 0, True);
		if (retval) {
			timeout_start = time(NULL);
			while (!got_level) {
				message_dispatch();
				if ((time(NULL) - timeout_start) > MAX_WAIT) {
					fprintf(stderr,"profilelevel timeout\n");
					break;
				}
			}
		}
		break;

	case MSG_REQ_DEBUGLEVEL:
		if (!debuglevel_registered) {
		    message_register(MSG_DEBUGLEVEL, debuglevel_function);
		    debuglevel_registered = True;
		}
		got_level = False;
		retval = send_message(dest, MSG_REQ_DEBUGLEVEL, NULL, 0, True);
		if (retval) {
			timeout_start = time(NULL);
			while (!got_level) {
				message_dispatch();
				if ((time(NULL) - timeout_start) > MAX_WAIT) {
					fprintf(stderr,"debuglevel timeout\n");
					break;
				}
			}
		}
		break;

	case MSG_PRINTER_NOTIFY:
		if (!strequal(dest, "smbd")) {
			fprintf(stderr,"printer-notify can only be sent to smbd\n");
			return(False);
		}
		if (!params || !params[0]) {
			fprintf(stderr, "printer-notify needs a printer name\n");
			return (False);
		}
		{
			char msg[8 + sizeof(fstring)+4];
			SIVAL(msg,0,PRINTER_CHANGE_ALL);
			SIVAL(msg,4,0);
			fstrcpy(&msg[8], params[0]);
			SIVAL(msg,8+strlen(params[0])+1, PRINTER_MESSAGE_DRIVER);

			retval = send_message(dest, MSG_PRINTER_NOTIFY, msg, 8 + strlen(params[0]) + 1 + 4, False);
		}
		break;

	case MSG_SMB_FORCE_TDIS:
		if (!strequal(dest, "smbd")) {
			fprintf(stderr,"close-share can only be sent to smbd\n");
			return(False);
		}
		if (!params || !params[0]) {
			fprintf(stderr, "close-share needs a share name or '*'\n");
			return (False);
		}
		retval = send_message(dest, MSG_SMB_FORCE_TDIS, params[0],
				      strlen(params[0]) + 1, False);
		break;

	case MSG_PING:
		if (!pong_registered) {
		    message_register(MSG_PONG, pong_function);
		    pong_registered = True;
		}
		if (!params || !params[0]) {
			fprintf(stderr,"MSG_PING needs a parameter\n");
			return(False);
		}
		n = atoi(params[0]);
		pong_count = 0;
		for (i=0;i<n;i++) {
			if (iparams > 1)
				retval = send_message(dest, MSG_PING, params[1], strlen(params[1]) + 1, True);
			else
				retval = send_message(dest, MSG_PING, NULL, 0, True);
			if (retval == False) break;
		}
		if (retval) {
			timeout_start = time(NULL);
			while (pong_count < n) {
				message_dispatch();
				if ((time(NULL) - timeout_start) > MAX_WAIT) {
					fprintf(stderr,"PING timeout\n");
					break;
				}
			}
		}
		break;

	}
	
	return (True);
}
Пример #8
0
static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_ports)
{
	int num_interfaces = iface_count();
	int num_sockets = 0;
	int fd_listenset[FD_SETSIZE];
	fd_set listen_set;
	int s;
	int maxfd = 0;
	int i;
	char *ports;

	if (!is_daemon) {
		return open_sockets_inetd();
	}

		
#ifdef HAVE_ATEXIT
	{
		static int atexit_set;
		if(atexit_set == 0) {
			atexit_set=1;
			atexit(killkids);
		}
	}
#endif

#ifndef _XBOX
	/* Stop zombies */
	CatchChild();
#endif

	FD_ZERO(&listen_set);

	/* use a reasonable default set of ports - listing on 445 and 139 */
	if (!smb_ports) {
		ports = lp_smb_ports();
		if (!ports || !*ports) {
			ports = smb_xstrdup(SMB_PORTS);
		} else {
			ports = smb_xstrdup(ports);
		}
	} else {
		ports = smb_xstrdup(smb_ports);
	}

	if (lp_interfaces() && lp_bind_interfaces_only()) {
		/* We have been given an interfaces line, and been 
		   told to only bind to those interfaces. Create a
		   socket per interface and bind to only these.
		*/
		
		/* Now open a listen socket for each of the
		   interfaces. */
		for(i = 0; i < num_interfaces; i++) {
			struct in_addr *ifip = iface_n_ip(i);
			fstring tok;
			const char *ptr;

			if(ifip == NULL) {
				DEBUG(0,("open_sockets_smbd: interface %d has NULL IP address !\n", i));
				continue;
			}

			for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
				unsigned port = atoi(tok);
				if (port == 0) {
					continue;
				}
				s = fd_listenset[num_sockets] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
				if(s == -1)
					return False;

				/* ready to listen */
				set_socket_options(s,"SO_KEEPALIVE"); 
				set_socket_options(s,user_socket_options);
     
				/* Set server socket to non-blocking for the accept. */
				set_blocking(s,False); 
 
				if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
					DEBUG(0,("listen: %s\n",strerror(errno)));
					close(s);
					return False;
				}
				FD_SET(s,&listen_set);
				maxfd = MAX( maxfd, s);

				num_sockets++;
				if (num_sockets >= FD_SETSIZE) {
					DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
					return False;
				}
			}
		}
	} else {
		/* Just bind to 0.0.0.0 - accept connections
		   from anywhere. */

		fstring tok;
		const char *ptr;

		num_interfaces = 1;
		
		for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) {
			unsigned port = atoi(tok);
			if (port == 0) continue;
			/* open an incoming socket */
			s = open_socket_in(SOCK_STREAM, port, 0,
					   interpret_addr(lp_socket_address()),True);
			if (s == -1)
				return(False);
		
			/* ready to listen */
#ifndef _XBOX
			set_socket_options(s,"SO_KEEPALIVE"); 
#endif
			set_socket_options(s,user_socket_options);
			
			/* Set server socket to non-blocking for the accept. */
			set_blocking(s,False); 
 
			if (listen(s, SMBD_LISTEN_BACKLOG) == -1) {
				DEBUG(0,("open_sockets_smbd: listen: %s\n",
					 strerror(errno)));
				close(s);
				return False;
			}

			fd_listenset[num_sockets] = s;
			FD_SET(s,&listen_set);
			maxfd = MAX( maxfd, s);

			num_sockets++;

			if (num_sockets >= FD_SETSIZE) {
				DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n"));
				return False;
			}
		}
	} 

	SAFE_FREE(ports);

        /* Listen to messages */

        message_register(MSG_SMB_SAM_SYNC, msg_sam_sync);
        message_register(MSG_SMB_SAM_REPL, msg_sam_repl);
        message_register(MSG_SHUTDOWN, msg_exit_server);
        message_register(MSG_SMB_FILE_RENAME, msg_file_was_renamed);
	message_register(MSG_SMB_CONF_UPDATED, smb_conf_updated); 

#ifdef DEVELOPER
	message_register(MSG_SMB_INJECT_FAULT, msg_inject_fault); 
#endif

	/* now accept incoming connections - forking a new process
	   for each incoming connection */
	DEBUG(2,("waiting for a connection\n"));
	while (1) {
		fd_set lfds;
		int num;
		
		/* Free up temporary memory from the main smbd. */
		lp_TALLOC_FREE();

		/* Ensure we respond to PING and DEBUG messages from the main smbd. */
		message_dispatch();

		memcpy((char *)&lfds, (char *)&listen_set, 
		       sizeof(listen_set));
		
		num = sys_select(maxfd+1,&lfds,NULL,NULL,NULL);
		
		if (num == -1 && errno == EINTR) {
			if (got_sig_term) {
				exit_server_cleanly(NULL);
			}

			/* check for sighup processing */
			if (reload_after_sighup) {
				change_to_root_user();
				DEBUG(1,("Reloading services after SIGHUP\n"));
				reload_services(False);
				reload_after_sighup = 0;
			}

			continue;
		}
		
		/* check if we need to reload services */
		check_reload(time(NULL));

		/* Find the sockets that are read-ready -
		   accept on these. */
		for( ; num > 0; num--) {
			struct sockaddr addr;
			socklen_t in_addrlen = sizeof(addr);

			s = -1;
			for(i = 0; i < num_sockets; i++) {
				if(FD_ISSET(fd_listenset[i],&lfds)) {
					s = fd_listenset[i];
					/* Clear this so we don't look
					   at it again. */
					FD_CLR(fd_listenset[i],&lfds);
					break;
				}
			}

			smbd_set_server_fd(accept(s,&addr,&in_addrlen));
			
			if (smbd_server_fd() == -1 && errno == EINTR)
				continue;
			
			if (smbd_server_fd() == -1) {
				DEBUG(0,("open_sockets_smbd: accept: %s\n",
					 strerror(errno)));
				continue;
			}

			/* Ensure child is set to blocking mode */
			set_blocking(smbd_server_fd(),True);

			if (smbd_server_fd() != -1 && interactive) {
#ifdef _XBOX
				xb_IncClientCount();
#endif
				return True;
			}
			
			if (allowable_number_of_smbd_processes() && smbd_server_fd() != -1 && sys_fork()==0) {


				/* Child code ... */			

				/* close the listening socket(s) */
				for(i = 0; i < num_sockets; i++)
					close(fd_listenset[i]);
				
				/* close our standard file
				   descriptors */
				close_low_fds(False);
				am_parent = 0;
				
				set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
				set_socket_options(smbd_server_fd(),user_socket_options);
				
				/* this is needed so that we get decent entries
				   in smbstatus for port 445 connects */
				set_remote_machine_name(get_peer_addr(smbd_server_fd()), False);
				
				/* Reset the state of the random
				 * number generation system, so
				 * children do not get the same random
				 * numbers as each other */

				set_need_random_reseed();
				/* tdb needs special fork handling - remove CLEAR_IF_FIRST flags */
				if (tdb_reopen_all(1) == -1) {
					DEBUG(0,("tdb_reopen_all failed.\n"));
					smb_panic("tdb_reopen_all failed.");
				}

				return True; 
			}
			/* The parent doesn't need this socket */
			close(smbd_server_fd()); 

			/* Sun May 6 18:56:14 2001 [email protected]:
				Clear the closed fd info out of server_fd --
				and more importantly, out of client_fd in
				util_sock.c, to avoid a possible
				getpeername failure if we reopen the logs
				and use %I in the filename.
			*/

			smbd_set_server_fd(-1);

			/* Force parent to check log size after
			 * spawning child.  Fix from
			 * [email protected].  The
			 * parent smbd will log to logserver.smb.  It
			 * writes only two messages for each child
			 * started/finished. But each child writes,
			 * say, 50 messages also in logserver.smb,
			 * begining with the debug_count of the
			 * parent, before the child opens its own log
			 * file logserver.client. In a worst case
			 * scenario the size of logserver.smb would be
			 * checked after about 50*50=2500 messages
			 * (ca. 100kb).
			 * */
			force_check_log_size();
 
		} /* end for num */
	} /* end while 1 */

/* NOTREACHED	return True; */
}
Пример #9
0
int main(int argc, char *argv[])
{
    struct event_context *evt_ctx;
    struct messaging_context *msg_ctx;
    pid_t pid;
    int i, n;
    char buf[12];

    load_case_tables();

    setup_logging(argv[0],True);

    lp_load(get_dyn_CONFIGFILE(),False,False,False,True);

    if (!(evt_ctx = event_context_init(NULL)) ||
            !(msg_ctx = messaging_init(NULL, server_id_self(), evt_ctx))) {
        fprintf(stderr, "could not init messaging context\n");
        exit(1);
    }

    if (argc != 3) {
        fprintf(stderr, "%s: Usage - %s pid count\n", argv[0],
                argv[0]);
        exit(1);
    }

    pid = atoi(argv[1]);
    n = atoi(argv[2]);

    messaging_register(msg_ctx, NULL, MSG_PONG, pong_message);

    for (i=0; i<n; i++) {
        messaging_send(msg_ctx, pid_to_procid(pid), MSG_PING,
                       &data_blob_null);
    }

    while (pong_count < i) {
        message_dispatch(msg_ctx);
        smb_msleep(1);
    }

    /* Now test that the duplicate filtering code works. */
    pong_count = 0;

    safe_strcpy(buf, "1234567890", sizeof(buf)-1);

    for (i=0; i<n; i++) {
        messaging_send(msg_ctx, pid_to_procid(getpid()), MSG_PING,
                       &data_blob_null);
        messaging_send_buf(msg_ctx, pid_to_procid(getpid()), MSG_PING,
                           (uint8 *)buf, 11);
    }

    for (i=0; i<n; i++) {
        message_dispatch(msg_ctx);
        smb_msleep(1);
    }

    if (pong_count != 2) {
        fprintf(stderr, "Duplicate filter failed (%d).\n", pong_count);
    }

    /* Speed testing */

    pong_count = 0;

    {
        struct timeval tv = timeval_current();
        size_t timelimit = n;
        size_t ping_count = 0;

        printf("Sending pings for %d seconds\n", (int)timelimit);
        while (timeval_elapsed(&tv) < timelimit) {
            if(NT_STATUS_IS_OK(messaging_send_buf(
                                   msg_ctx, pid_to_procid(pid),
                                   MSG_PING,
                                   (uint8 *)buf, 11)))
                ping_count++;
            if(NT_STATUS_IS_OK(messaging_send(
                                   msg_ctx, pid_to_procid(pid),
                                   MSG_PING, &data_blob_null)))
                ping_count++;

            while (ping_count > pong_count + 20) {
                message_dispatch(msg_ctx);
            }
        }

        printf("waiting for %d remaining replies (done %d)\n",
               (int)(ping_count - pong_count), pong_count);
        while (timeval_elapsed(&tv) < 30 && pong_count < ping_count) {
            message_dispatch(msg_ctx);
        }

        if (ping_count != pong_count) {
            fprintf(stderr, "ping test failed! received %d, sent "
                    "%d\n", pong_count, (int)ping_count);
        }

        printf("ping rate of %.0f messages/sec\n",
               (ping_count+pong_count)/timeval_elapsed(&tv));
    }

    return (0);
}