server.c
来自「samba-3.0.22.tar.gz 编译smb服务器的源码」· C语言 代码 · 共 671 行 · 第 1/2 页
C
671 行
p->next = packet; packet->next = NULL; packet->prev = p;}/**************************************************************************** Listens for NMB or DGRAM packets, and queues them. return True if the socket is dead***************************************************************************/static BOOL listen_for_wins_packets(void){ int num_interfaces = iface_count(); fd_set fds; int i, num, s, new_s; static int maxfd = 0; struct timeval timeout; if(listen_set == NULL) { if(!create_listen_fdset( &maxfd)) { DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n")); return True; } } memcpy((char *)&fds, (char *)listen_set, sizeof(fd_set)); timeout.tv_sec = NMBD_SELECT_LOOP; timeout.tv_usec = 0; /* Prepare for the select - allow certain signals. */ BlockSignals(False, SIGTERM); num = sys_select(maxfd+1, &fds, NULL, NULL, &timeout); /* We can only take signals when we are in the select - block them again here. */ BlockSignals(True, SIGTERM); if(num == -1) return False; for (; num > 0; num--) { s = -1; /* check the sockets we are only listening on, waiting to accept */ for (i=0; i<num_interfaces; i++) { struct sockaddr addr; socklen_t in_addrlen = sizeof(addr); if(FD_ISSET(sock_array[i], &fds)) { s = sock_array[i]; /* Clear this so we don't look at it again. */ FD_CLR(sock_array[i], &fds); /* accept and add the new socket to the listen set */ new_s=accept(s, &addr, &in_addrlen); if (new_s < 0) continue; DEBUG(5,("listen_for_wins_packets: new connection, old: %d, new : %d\n", s, new_s)); set_socket_options(new_s, "SO_KEEPALIVE"); set_socket_options(new_s, user_socket_options); FD_SET(new_s, listen_set); add_fd_to_sock_array(new_s); maxfd = MAX( maxfd, new_s); } } /* * check for the sockets we are waiting data from * either client sending datas * or reply to our requests */ for (i=num_interfaces; i<listen_number; i++) { if(FD_ISSET(sock_array[i], &fds)) { struct wins_packet_struct *packet = read_wins_packet(sock_array[i], timeout.tv_sec); if (packet) { packet->fd = sock_array[i]; queue_packet(packet); } DEBUG(2,("listen_for_wins_packets: some data on fd %d\n", sock_array[i])); FD_CLR(sock_array[i], &fds); break; } } } return False;}/******************************************************************* Run elements off the packet queue till its empty******************************************************************/static void run_wins_packet_queue(void){ struct wins_packet_struct *p; while ((p = packet_queue)) { packet_queue = p->next; if (packet_queue) packet_queue->prev = NULL; p->next = p->prev = NULL; construct_reply(p); /* if it was a stop assoc, close the connection */ if (p->stop_packet) { FD_CLR(p->fd, listen_set); remove_fd_from_sock_array(p->fd); close(p->fd); } }} /**************************************************************************** ** The main select loop. **************************************************************************** */static void process(void){ while( True ) { time_t t = time(NULL); /* check for internal messages */ message_dispatch(); if(listen_for_wins_packets()) return; run_wins_packet_queue(); run_pull_replication(t); run_push_replication(t); /* * Reload the services file if we got a sighup. */ if(reload_after_sighup) { reload_services( True ); reopen_logs(); reload_after_sighup = False; } /* free temp memory */ talloc_free_children(mem_ctx); /* free up temp memory */ lp_talloc_free(); }} /* process *//**************************************************************************** main program****************************************************************************/ int main(int argc,char *argv[]){ /* shall I run as a daemon */ static BOOL is_daemon = False; static BOOL interactive = False; static BOOL Fork = True; static BOOL log_stdout = False; struct poptOption long_options[] = { POPT_AUTOHELP { "daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon (default)" }, { "foreground", 'F', POPT_ARG_VAL, &Fork, False, "Run daemon in foreground (for daemontools, etc)" }, { "stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout" }, { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Run interactive (not a daemon)" }, { "port", 'p', POPT_ARG_INT, &wins_port, 'p', "Listen on the specified port" }, POPT_COMMON_SAMBA POPT_TABLEEND }; int opt; poptContext pc;#ifdef HAVE_SET_AUTH_PARAMETERS set_auth_parameters(argc,argv);#endif pc = poptGetContext("wrepld", argc, (const char **)argv, long_options, POPT_CONTEXT_KEEP_FIRST); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case 'i': interactive = True; Fork = False; log_stdout = True; break; } } if (log_stdout && Fork) { d_printf("Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"); poptPrintUsage(pc, stderr, 0); exit(1); }#ifdef HAVE_SETLUID /* needed for SecureWare on SCO */ setluid(0);#endif sec_init(); load_case_tables(); set_remote_machine_name("wrepld", False); setup_logging(argv[0],log_stdout); /* we want to re-seed early to prevent time delays causing client problems at a later date. (tridge) */ generate_random_buffer(NULL, 0); /* make absolutely sure we run as root - to handle cases where people are crazy enough to have it setuid */ gain_root_privilege(); gain_root_group_privilege(); fault_setup((void (*)(void *))exit_server); CatchSignal(SIGTERM , SIGNAL_CAST dflt_sig); /* we are never interested in SIGPIPE */ BlockSignals(True,SIGPIPE);#if defined(SIGFPE) /* we are never interested in SIGFPE */ BlockSignals(True,SIGFPE);#endif#if defined(SIGUSR2) /* We are no longer interested in USR2 */ BlockSignals(True,SIGUSR2);#endif /* POSIX demands that signals are inherited. If the invoking process has * these signals masked, we will have problems, as we won't recieve them. */ BlockSignals(False, SIGHUP); BlockSignals(False, SIGUSR1); /* we want total control over the permissions on created files, so set our umask to 0 */ umask(0); reopen_logs(); DEBUG(0,( "wrepld version %s started.\n", SAMBA_VERSION_STRING)); DEBUGADD( 0, ( "%s\n", COPYRIGHT_STARTUP_MESSAGE ) ); DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n", (int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid())); if (sizeof(uint16) < 2 || sizeof(uint32) < 4) { DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n")); exit(1); } /* * Do this before reload_services. */ if (!reload_services(False)) return(-1); if (!init_names()) return -1; #ifdef WITH_PROFILE if (!profile_setup(False)) { DEBUG(0,("ERROR: failed to setup profiling\n")); return -1; }#endif CatchSignal(SIGHUP,SIGNAL_CAST sig_hup); DEBUG(3,( "loaded services\n")); if (!is_daemon && !is_a_socket(0)) { DEBUG(0,("standard input is not a socket, assuming -D option\n")); is_daemon = True; } if (is_daemon && !interactive) { DEBUG( 3, ( "Becoming a daemon.\n" ) ); become_daemon(Fork); }#if HAVE_SETPGID /* * If we're interactive we want to set our own process group for * signal management. */ if (interactive) setpgid( (pid_t)0, (pid_t)0);#endif if (!directory_exist(lp_lockdir(), NULL)) { mkdir(lp_lockdir(), 0755); } if (is_daemon) { pidfile_create("wrepld"); } if (!message_init()) { exit(1); } /* Initialise the memory context */ mem_ctx=talloc_init("wins repl talloc ctx"); /* initialise the global partners table */ partner_count=init_wins_partner_table(); /* We can only take signals in the select. */ BlockSignals( True, SIGTERM ); process(); poptFreeContext(pc); exit_server("normal exit"); return(0);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?