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

📄 util_sock.c

📁 MC Linux/Unix 终端下文件管理器
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    Unix SMB/Netbios implementation.   Version 1.9.   Samba utility functions   Copyright (C) Andrew Tridgell 1992-1998      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"#ifdef WITH_SSL#include <ssl.h>#undef Realloc  /* SSLeay defines this and samba has a function of this name */extern SSL  *ssl;extern int  sslFd;#endif  /* WITH_SSL */extern int DEBUGLEVEL;BOOL passive = False;/* the client file descriptor */int Client = -1;/* 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,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};static const struct{  char *name;  int level;  int option;  int value;  int opttype;} 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 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_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  {NULL,0,0,0,0}};	/****************************************************************************set user socket options****************************************************************************/void set_socket_options(int fd, 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(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\n",tok));    }}/****************************************************************************  close the socket communication****************************************************************************/void close_sockets(void ){#ifdef WITH_SSL  sslutil_disconnect(Client);#endif /* WITH_SSL */  close(Client);  Client = -1;}/****************************************************************************write to a socket****************************************************************************/ssize_t write_socket(int fd,char *buf,size_t len){  ssize_t ret=0;  if (passive)    return(len);  DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len));  ret = write_data(fd,buf,len);        DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret));  if(ret <= 0)    DEBUG(1,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n",        (int)len, fd, strerror(errno) ));  return(ret);}/****************************************************************************read from a socket****************************************************************************/ssize_t read_udp_socket(int fd,char *buf,size_t len){  ssize_t ret;  struct sockaddr_in sock;  int socklen;    socklen = sizeof(sock);  memset((char *)&sock,'\0',socklen);  memset((char *)&lastip,'\0',sizeof(lastip));  ret = (ssize_t)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: %d\n",             inet_ntoa(lastip), lastport, ret));  return(ret);}/****************************************************************************read data from a device with a timout in msec.mincount = if timeout, minimum to read before returningmaxcount = number to be read.time_out = timeout in milliseconds****************************************************************************/ssize_t read_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) {#ifdef WITH_SSL      if(fd == sslFd){        readret = SSL_read(ssl, buf + nread, maxcnt - nread);      }else{        readret = read(fd, buf + nread, maxcnt - nread);      }#else /* WITH_SSL */      readret = read(fd, buf + nread, maxcnt - nread);#endif /* WITH_SSL */      if (readret == 0) {        DEBUG(5,("read_with_timeout: blocking read. EOF from client.\n"));        smb_read_error = READ_EOF;        return -1;      }      if (readret == -1) {        DEBUG(0,("read_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 */  /* Set initial timeout */  timeout.tv_sec = (time_t)(time_out / 1000);  timeout.tv_usec = (long)(1000 * (time_out % 1000));  for (nread=0; nread < mincnt; )   {          FD_ZERO(&fds);    FD_SET(fd,&fds);          selrtn = sys_select(fd+1,&fds,&timeout);    /* Check if error */    if(selrtn == -1) {      /* something is wrong. Maybe the socket is dead? */      DEBUG(0,("read_with_timeout: timeout read. select error = %s.\n", strerror(errno) ));      smb_read_error = READ_ERROR;      return -1;    }    /* Did we timeout ? */    if (selrtn == 0) {      DEBUG(10,("read_with_timeout: timeout read. select timed out.\n"));      smb_read_error = READ_TIMEOUT;      return -1;    }      #ifdef WITH_SSL    if(fd == sslFd){      readret = SSL_read(ssl, buf + nread, maxcnt - nread);    }else{      readret = read(fd, buf + nread, maxcnt - nread);    }#else /* WITH_SSL */    readret = read(fd, buf+nread, maxcnt-nread);#endif /* WITH_SSL */    if (readret == 0) {      /* we got EOF on the file descriptor */      DEBUG(5,("read_with_timeout: timeout read. EOF from client.\n"));      smb_read_error = READ_EOF;      return -1;    }    if (readret == -1) {      /* the descriptor is probably dead */      DEBUG(0,("read_with_timeout: timeout read. read error = %s.\n", strerror(errno) ));      smb_read_error = READ_ERROR;      return -1;    }          nread += readret;  }  /* Return the number we got */  return((ssize_t)nread);}/****************************************************************************send a keepalive packet (rfc1002)****************************************************************************/BOOL send_keepalive(int client){  unsigned char buf[4];  buf[0] = 0x85;  buf[1] = buf[2] = buf[3] = 0;  return(write_data(client,(char *)buf,4) == 4);}/****************************************************************************  read data from the client, reading exactly N bytes. ****************************************************************************/ssize_t read_data(int fd,char *buffer,size_t N){  ssize_t  ret;  size_t total=0;     smb_read_error = 0;  while (total < N)  {#ifdef WITH_SSL    if(fd == sslFd){      ret = SSL_read(ssl, buffer + total, N - total);    }else{      ret = read(fd,buffer + total,N - total);    }#else /* WITH_SSL */    ret = read(fd,buffer + total,N - total);#endif /* WITH_SSL */    if (ret == 0)    {      DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));      smb_read_error = READ_EOF;      return 0;    }    if (ret == -1)    {      DEBUG(0,("read_data: 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;}/****************************************************************************  write data to a fd ****************************************************************************/ssize_t write_data(int fd,char *buffer,size_t N){  size_t total=0;  ssize_t ret;  while (total < N)  {#ifdef WITH_SSL    if(fd == sslFd){      ret = SSL_write(ssl,buffer + total,N - total);    }else{      ret = write(fd,buffer + total,N - total);    }#else /* WITH_SSL */    ret = write(fd,buffer + total,N - total);#endif /* WITH_SSL */    if (ret == -1) {      DEBUG(1,("write_data: write failure. Error = %s\n", strerror(errno) ));      return -1;    }    if (ret == 0) return total;    total += ret;  }  return (ssize_t)total;}/****************************************************************************read 4 bytes of a smb packet and return the smb length of the packetstore the result in the bufferThis version of the function will return a length of zero on receivinga keepalive packet.timeout is in milliseconds.****************************************************************************/static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout){  ssize_t len=0;  int msg_type;  BOOL ok = False;  while (!ok)  {    if (timeout > 0)      ok = (read_with_timeout(fd,inbuf,4,4,timeout) == 4);    else       ok = (read_data(fd,inbuf,4) == 4);    if (!ok)      return(-1);

⌨️ 快捷键说明

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