server.c
来自「samba-3.0.22.tar.gz 编译smb服务器的源码」· C语言 代码 · 共 671 行 · 第 1/2 页
C
671 行
/* Unix SMB/CIFS implementation. Main SMB server routines Copyright (C) Jean Fran鏾is Micouleau 1998-2002. 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"#include "wins_repl.h"extern pstring user_socket_options;extern WINS_OWNER *global_wins_table;extern int partner_count;extern fd_set *listen_set;extern int listen_number;extern int *sock_array;extern TALLOC_CTX *mem_ctx;int wins_port = 42;/**************************************************************************** when exiting, take the whole family****************************************************************************/static void *dflt_sig(void){ exit_server("caught signal"); return NULL;}/**************************************************************************** reload the services file **************************************************************************/BOOL reload_services(BOOL test){ BOOL ret; if (lp_loaded()) { pstring fname; pstrcpy(fname,lp_configfile()); if (file_exist(fname,NULL) && !strcsequal(fname,dyn_CONFIGFILE)) { pstrcpy(dyn_CONFIGFILE,fname); test = False; } } reopen_logs(); if (test && !lp_file_list_changed()) return(True); ret = lp_load(dyn_CONFIGFILE,False,False,True); /* perhaps the config filename is now set */ if (!test) reload_services(True); reopen_logs(); load_interfaces(); return(ret);}/**************************************************************************** Catch a sighup.****************************************************************************/VOLATILE sig_atomic_t reload_after_sighup = False;static void sig_hup(int sig){ BlockSignals(True,SIGHUP); DEBUG(0,("Got SIGHUP\n")); sys_select_signal(SIGHUP); reload_after_sighup = True; BlockSignals(False,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/****************************************************************************exit the server****************************************************************************/void exit_server(const char *reason){ static int firsttime=1; if (!firsttime) exit(0); firsttime = 0; DEBUG(2,("Closing connections\n")); if (!reason) { int oldlevel = DEBUGLEVEL; DEBUGLEVEL = 10; DEBUGLEVEL = oldlevel; DEBUG(0,("===============================================================\n"));#if DUMP_CORE if (dump_core()) return;#endif } DEBUG(3,("Server exit (%s)\n", (reason ? reason : ""))); exit(0);}/**************************************************************************** Create an fd_set containing all the sockets in the subnet structures, plus the broadcast sockets.***************************************************************************/static BOOL create_listen_fdset( int *maxfd){ int i; int num_interfaces = iface_count(); int s; listen_set = (fd_set *)malloc(sizeof(fd_set)); if(listen_set == NULL) { DEBUG(0,("create_listen_fdset: malloc fail !\n")); return True; }#ifdef HAVE_ATEXIT { static int atexit_set; if(atexit_set == 0) { atexit_set=1; } }#endif FD_ZERO(listen_set); 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. */ if(num_interfaces > FD_SETSIZE) { DEBUG(0,("create_listen_fdset: Too many interfaces specified to bind to. Number was %d max can be %d\n", num_interfaces, FD_SETSIZE)); return False; } /* 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); if(ifip == NULL) { DEBUG(0,("create_listen_fdset: interface %d has NULL IP address !\n", i)); continue; } s = open_socket_in(SOCK_STREAM, wins_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); if (listen(s, 5) == -1) { DEBUG(5,("listen: %s\n",strerror(errno))); close(s); return False; } add_fd_to_sock_array(s); FD_SET(s, listen_set); *maxfd = MAX( *maxfd, s); } } else { /* Just bind to 0.0.0.0 - accept connections from anywhere. */ num_interfaces = 1; /* open an incoming socket */ s = open_socket_in(SOCK_STREAM, wins_port, 0, interpret_addr(lp_socket_address()),True); if (s == -1) return(False); /* ready to listen */ set_socket_options(s,"SO_KEEPALIVE"); set_socket_options(s,user_socket_options); if (listen(s, 5) == -1) { DEBUG(0,("create_listen_fdset: listen: %s\n", strerror(errno))); close(s); return False; } add_fd_to_sock_array(s); FD_SET(s, listen_set); *maxfd = MAX( *maxfd, s); } return True;}/******************************************************************* read a packet from a socket and parse it, returning a packet ready to be used or put on the queue. This assumes a UDP socket ******************************************************************/static struct wins_packet_struct *read_wins_packet(int fd, int timeout){ struct wins_packet_struct *p; GENERIC_PACKET *q; struct BUFFER inbuf; ssize_t len=0; size_t total=0; ssize_t ret; BOOL ok = False; inbuf.buffer=NULL; inbuf.length=0; inbuf.offset=0; if(!grow_buffer(&inbuf, 4)) return NULL; ok = (read(fd, inbuf.buffer,4) == 4); if (!ok) return NULL; len = smb_len(inbuf.buffer); if (len<=0) return NULL; if(!grow_buffer(&inbuf, len)) return NULL; while (total < len) { ret = read(fd, inbuf.buffer + total + 4, len - total); if (ret == 0) { DEBUG(10,("read_socket_data: recv of %d returned 0. Error = %s\n", (int)(len - total), strerror(errno) )); return NULL; } if (ret == -1) { DEBUG(0,("read_socket_data: recv failure for %d. Error = %s\n", (int)(len - total), strerror(errno) )); return NULL; } total += ret; } q = talloc(mem_ctx, GENERIC_PACKET); p = talloc(mem_ctx, struct wins_packet_struct); if (q==NULL || p==NULL) return NULL; decode_generic_packet(&inbuf, q); q->fd=fd; p->next = NULL; p->prev = NULL; p->stop_packet = False; p->timestamp = time(NULL); p->fd = fd; p->packet=q; return p;}static struct wins_packet_struct *packet_queue = NULL;/******************************************************************* Queue a packet into a packet queue******************************************************************/static void queue_packet(struct wins_packet_struct *packet){ struct wins_packet_struct *p; if (!packet_queue) { packet->prev = NULL; packet->next = NULL; packet_queue = packet; return; } /* find the bottom */ for (p=packet_queue;p->next;p=p->next) ;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?