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

📄 util_sock.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*    Unix SMB/CIFS implementation.   Samba utility functions   Copyright (C) Andrew Tridgell 1992-1998   Copyright (C) Tim Potter      2000-2001   Copyright (C) Jeremy Allison  1992-2005      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"/* the following 3 client_*() functions are nasty ways of allowing   some generic functions to get info that really should be hidden in   particular modules */static int client_fd = -1;/* What to print out on a client disconnect error. */static char client_ip_string[16];void client_setfd(int fd){	client_fd = fd;	safe_strcpy(client_ip_string, get_peer_addr(client_fd), sizeof(client_ip_string)-1);}static char *get_socket_addr(int fd){	struct sockaddr sa;	struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);	socklen_t length = sizeof(sa);	static fstring addr_buf;	fstrcpy(addr_buf,"0.0.0.0");	if (fd == -1) {		return addr_buf;	}		if (getsockname(fd, &sa, &length) < 0) {		DEBUG(0,("getsockname failed. Error was %s\n", strerror(errno) ));		return addr_buf;	}		fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));		return addr_buf;}static int get_socket_port(int fd){	struct sockaddr sa;	struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);	socklen_t length = sizeof(sa);	if (fd == -1)		return -1;		if (getsockname(fd, &sa, &length) < 0) {		DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) ));		return -1;	}		return ntohs(sockin->sin_port);}char *client_name(void){	return get_peer_name(client_fd,False);}char *client_addr(void){	return get_peer_addr(client_fd);}char *client_socket_addr(void){	return get_socket_addr(client_fd);}int client_socket_port(void){	return get_socket_port(client_fd);}struct in_addr *client_inaddr(struct sockaddr *sa){	struct sockaddr_in *sockin = (struct sockaddr_in *) (sa);	socklen_t  length = sizeof(*sa);		if (getpeername(client_fd, sa, &length) < 0) {		DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) ));		return NULL;	}		return &sockin->sin_addr;}/* the last IP received from */struct in_addr lastip;/* the last port received from */int lastport=0;int smb_read_error = 0;/**************************************************************************** Determine if a file descriptor is in fact a socket.****************************************************************************/BOOL is_a_socket(int fd){	int v;	socklen_t l;	l = sizeof(int);	return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);}enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};typedef struct smb_socket_option {	const char *name;	int level;	int option;	int value;	int opttype;} smb_socket_option;static const smb_socket_option socket_options[] = {  {"SO_KEEPALIVE",      SOL_SOCKET,    SO_KEEPALIVE,    0,                 OPT_BOOL},  {"SO_REUSEADDR",      SOL_SOCKET,    SO_REUSEADDR,    0,                 OPT_BOOL},  {"SO_BROADCAST",      SOL_SOCKET,    SO_BROADCAST,    0,                 OPT_BOOL},#ifdef TCP_NODELAY  {"TCP_NODELAY",       IPPROTO_TCP,   TCP_NODELAY,     0,                 OPT_BOOL},#endif#ifdef TCP_KEEPCNT  {"TCP_KEEPCNT",       IPPROTO_TCP,   TCP_KEEPCNT,     0,                 OPT_INT},#endif#ifdef TCP_KEEPIDLE  {"TCP_KEEPIDLE",      IPPROTO_TCP,   TCP_KEEPIDLE,    0,                 OPT_INT},#endif#ifdef TCP_KEEPINTVL  {"TCP_KEEPINTVL",     IPPROTO_TCP,   TCP_KEEPINTVL,   0,                 OPT_INT},#endif#ifdef IPTOS_LOWDELAY  {"IPTOS_LOWDELAY",    IPPROTO_IP,    IP_TOS,          IPTOS_LOWDELAY,    OPT_ON},#endif#ifdef IPTOS_THROUGHPUT  {"IPTOS_THROUGHPUT",  IPPROTO_IP,    IP_TOS,          IPTOS_THROUGHPUT,  OPT_ON},#endif#ifdef SO_REUSEPORT  {"SO_REUSEPORT",      SOL_SOCKET,    SO_REUSEPORT,    0,                 OPT_BOOL},#endif#ifdef SO_SNDBUF  {"SO_SNDBUF",         SOL_SOCKET,    SO_SNDBUF,       0,                 OPT_INT},#endif#ifdef SO_RCVBUF  {"SO_RCVBUF",         SOL_SOCKET,    SO_RCVBUF,       0,                 OPT_INT},#endif#ifdef SO_SNDLOWAT  {"SO_SNDLOWAT",       SOL_SOCKET,    SO_SNDLOWAT,     0,                 OPT_INT},#endif#ifdef SO_RCVLOWAT  {"SO_RCVLOWAT",       SOL_SOCKET,    SO_RCVLOWAT,     0,                 OPT_INT},#endif#ifdef SO_SNDTIMEO  {"SO_SNDTIMEO",       SOL_SOCKET,    SO_SNDTIMEO,     0,                 OPT_INT},#endif#ifdef SO_RCVTIMEO  {"SO_RCVTIMEO",       SOL_SOCKET,    SO_RCVTIMEO,     0,                 OPT_INT},#endif#ifdef TCP_FASTACK  {"TCP_FASTACK",       IPPROTO_TCP,   TCP_FASTACK,     0,                 OPT_INT},#endif  {NULL,0,0,0,0}};/**************************************************************************** Print socket options.****************************************************************************/static void print_socket_options(int s){	int value;	socklen_t vlen = 4;	const smb_socket_option *p = &socket_options[0];	/* wrapped in if statement to prevent streams leak in SCO Openserver 5.0 */	/* reported on samba-technical  --jerry */	if ( DEBUGLEVEL >= 5 ) {	for (; p->name != NULL; p++) {		if (getsockopt(s, p->level, p->option, (void *)&value, &vlen) == -1) {			DEBUG(5,("Could not test socket option %s.\n", p->name));		} else {			DEBUG(5,("socket option %s = %d\n",p->name,value));			}		}	} }/**************************************************************************** Set user socket options.****************************************************************************/void set_socket_options(int fd, const char *options){	fstring tok;	while (next_token(&options,tok," \t,", sizeof(tok))) {		int ret=0,i;		int value = 1;		char *p;		BOOL got_value = False;		if ((p = strchr_m(tok,'='))) {			*p = 0;			value = atoi(p+1);			got_value = True;		}		for (i=0;socket_options[i].name;i++)			if (strequal(socket_options[i].name,tok))				break;		if (!socket_options[i].name) {			DEBUG(0,("Unknown socket option %s\n",tok));			continue;		}		switch (socket_options[i].opttype) {		case OPT_BOOL:		case OPT_INT:			ret = setsockopt(fd,socket_options[i].level,						socket_options[i].option,(char *)&value,sizeof(int));			break;		case OPT_ON:			if (got_value)				DEBUG(0,("syntax error - %s does not take a value\n",tok));			{				int on = socket_options[i].value;				ret = setsockopt(fd,socket_options[i].level,							socket_options[i].option,(char *)&on,sizeof(int));			}			break;	  		}      		if (ret != 0)			DEBUG(0,("Failed to set socket option %s (Error %s)\n",tok, strerror(errno) ));	}	print_socket_options(fd);}/**************************************************************************** Read from a socket.****************************************************************************/ssize_t read_udp_socket(int fd,char *buf,size_t len){	ssize_t ret;	struct sockaddr_in sock;	socklen_t socklen = sizeof(sock);	memset((char *)&sock,'\0',socklen);	memset((char *)&lastip,'\0',sizeof(lastip));	ret = (ssize_t)sys_recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);	if (ret <= 0) {		DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));		return(0);	}	lastip = sock.sin_addr;	lastport = ntohs(sock.sin_port);	DEBUG(10,("read_udp_socket: lastip %s lastport %d read: %lu\n",			inet_ntoa(lastip), lastport, (unsigned long)ret));	return(ret);}#if 0Socket routines from HEAD - maybe re-enable in future. JRA./**************************************************************************** Work out if we've timed out.****************************************************************************/static BOOL timeout_until(struct timeval *timeout, const struct timeval *endtime){	struct timeval now;	SMB_BIG_INT t_dif;	GetTimeOfDay(&now);	t_dif = usec_time_diff(endtime, &now);	if (t_dif <= 0) {		return False;	}	timeout->tv_sec = (t_dif / (SMB_BIG_INT)1000000);	timeout->tv_usec = (t_dif % (SMB_BIG_INT)1000000);	return True;}/**************************************************************************** Read data from the client, reading exactly N bytes, or until endtime timeout. Use with a non-blocking socket if endtime != NULL.****************************************************************************/ssize_t read_data_until(int fd,char *buffer,size_t N, const struct timeval *endtime){	ssize_t ret;	size_t total=0;	smb_read_error = 0;	while (total < N) {		if (endtime != NULL) {			fd_set r_fds;			struct timeval timeout;			int selrtn;			if (!timeout_until(&timeout, endtime)) {				DEBUG(10,("read_data_until: read timed out\n"));				smb_read_error = READ_TIMEOUT;				return -1;			}			FD_ZERO(&r_fds);			FD_SET(fd, &r_fds);			/* Select but ignore EINTR. */			selrtn = sys_select_intr(fd+1, &r_fds, NULL, NULL, &timeout);			if (selrtn == -1) {				/* something is wrong. Maybe the socket is dead? */				DEBUG(0,("read_data_until: select error = %s.\n", strerror(errno) ));				smb_read_error = READ_ERROR;				return -1;			}			/* Did we timeout ? */			if (selrtn == 0) {				DEBUG(10,("read_data_until: select timed out.\n"));				smb_read_error = READ_TIMEOUT;				return -1;			}		}		ret = sys_read(fd,buffer + total,N - total);		if (ret == 0) {			DEBUG(10,("read_data_until: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));			smb_read_error = READ_EOF;			return 0;		}		if (ret == -1) {			if (errno == EAGAIN) {				/* Non-blocking socket with no data available. Try select again. */				continue;			}			DEBUG(0,("read_data_until: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));			smb_read_error = READ_ERROR;			return -1;		}		total += ret;	}	return (ssize_t)total;}#endif/**************************************************************************** Read data from a socket with a timout in msec. mincount = if timeout, minimum to read before returning maxcount = number to be read. time_out = timeout in milliseconds****************************************************************************/ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out){	fd_set fds;	int selrtn;	ssize_t readret;	size_t nread = 0;	struct timeval timeout;		/* just checking .... */	if (maxcnt <= 0)		return(0);		smb_read_error = 0;		/* Blocking read */	if (time_out == 0) {		if (mincnt == 0) {			mincnt = maxcnt;		}				while (nread < mincnt) {			readret = sys_read(fd, buf + nread, maxcnt - nread);						if (readret == 0) {				DEBUG(5,("read_socket_with_timeout: blocking read. EOF from client.\n"));				smb_read_error = READ_EOF;				return -1;			}						if (readret == -1) {				if (fd == client_fd) {					/* Try and give an error message saying what client failed. */					DEBUG(0,("read_socket_with_timeout: client %s read error = %s.\n",						client_ip_string, strerror(errno) ));				} else {					DEBUG(0,("read_socket_with_timeout: read error = %s.\n", strerror(errno) ));				}				smb_read_error = READ_ERROR;				return -1;			}			nread += readret;		}		return((ssize_t)nread);	}		/* Most difficult - timeout read */	/* If this is ever called on a disk file and 	   mincnt is greater then the filesize then	   system performance will suffer severely as 	   select always returns true on disk files */

⌨️ 快捷键说明

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