Пример #1
0
BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
{
  ssize_t len,ret;

  smb_read_error = 0;

  memset(buffer,'\0',smb_size + 100);

  len = read_smb_length_return_keepalive(fd,buffer,timeout);
  if (len < 0)
  {
    DEBUG(10,("receive_smb: length < 0!\n"));
    return(False);
  }

  if (len > BUFFER_SIZE) {
    DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
    if (len > BUFFER_SIZE + (SAFETY_MARGIN/2))
    {
	exit(1);
    }
  }

  if(len > 0) {
    ret = read_socket_data(fd,buffer+4,len);
    if (ret != len) {
      smb_read_error = READ_ERROR;
      return False;
    }
  }
  return(True);
}
Пример #2
0
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_socket_with_timeout(fd,inbuf,4,4,timeout) == 4);
    else 
      ok = (read_socket_data(fd,inbuf,4) == 4);

    if (!ok)
      return(-1);

    len = smb_len(inbuf);
    msg_type = CVAL(inbuf,0);

    if (msg_type == 0x85) 
      DEBUG(5,("Got keepalive packet\n"));
  }

  DEBUG(10,("got smb length of %d\n",len));

  return(len);
}
Пример #3
0
BOOL receive_smb_raw(int fd,char *buffer, unsigned int timeout)
{
	ssize_t len,ret;

	smb_read_error = 0;

	memset(buffer,'\0',smb_size + 100);

	len = read_smb_length_return_keepalive(fd,buffer,timeout);
	if (len < 0) {
		DEBUG(10,("receive_smb_raw: length < 0!\n"));

		/*
		 * Correct fix. smb_read_error may have already been
		 * set. Only set it here if not already set. Global
		 * variables still suck :-). JRA.
		 */

		if (smb_read_error == 0)
			smb_read_error = READ_ERROR;
		return False;
	}

	/*
	 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
	 * of header. Don't print the error if this fits.... JRA.
	 */

	if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
		DEBUG(0,("Invalid packet length! (%lu bytes).\n",(unsigned long)len));
		if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) {

			/*
			 * Correct fix. smb_read_error may have already been
			 * set. Only set it here if not already set. Global
			 * variables still suck :-). JRA.
			 */

			if (smb_read_error == 0)
				smb_read_error = READ_ERROR;
			return False;
		}
	}

	if(len > 0) {
		ret = read_socket_data(fd,buffer+4,len);
		if (ret != len) {
			if (smb_read_error == 0)
				smb_read_error = READ_ERROR;
			return False;
		}
		
		/* not all of samba3 properly checks for packet-termination of strings. This
		   ensures that we don't run off into empty space. */
		SSVAL(buffer+4,len, 0);
	}

	return True;
}
Пример #4
0
/**************************************************************************
...
**************************************************************************/
void get_net_input(XtPointer client_data, int *fid, XtInputId *id)
{
  if(read_socket_data(*fid, &aconnection.buffer)>0) {
    int type;
    char *packet;

    while((packet=get_packet_from_connection(&aconnection, &type))) {
      handle_packet_input(packet, type);
    }
  }
  else {
    char buf[512];
    
    sprintf(buf, "Lost connection to server! Quit and reconnect with\n\
the option \"-n %s\", when ready..", game.player_ptr->name);
    
    append_output_window(buf);
    
    log(LOG_NORMAL, "lost connection to server");
    close(*fid);
    remove_net_input();
  }
}
Пример #5
0
/****************************************************************************
  A wrapper around read_socket_data() which also handles the case the
  socket becomes writeable and there is still data which should be sent
  to the server.

Returns:
    -1  :  an error occurred - you should close the socket
    -2  :  the connection was closed
    >0  :  number of bytes read
    =0  :  no data read, would block
****************************************************************************/
static int read_from_connection(struct connection *pc, bool block)
{
  for (;;) {
    fd_set readfs, writefs, exceptfs;
    int socket_fd = pc->sock;
    bool have_data_for_server = (pc->used && pc->send_buffer
                                 && 0 < pc->send_buffer->ndata);
    int n;
    struct timeval tv;

    tv.tv_sec = 0;
    tv.tv_usec = 0;

    FC_FD_ZERO(&readfs);
    FD_SET(socket_fd, &readfs);

    FC_FD_ZERO(&exceptfs);
    FD_SET(socket_fd, &exceptfs);

    if (have_data_for_server) {
      FC_FD_ZERO(&writefs);
      FD_SET(socket_fd, &writefs);
      n = fc_select(socket_fd + 1, &readfs, &writefs, &exceptfs,
                    block ? NULL : &tv);
    } else {
      n = fc_select(socket_fd + 1, &readfs, NULL, &exceptfs,
                    block ? NULL : &tv);
    }

    /* the socket is neither readable, writeable nor got an
     * exception */
    if (n == 0) {
      return 0;
    }

    if (n == -1) {
      if (errno == EINTR) {
        /* EINTR can happen sometimes, especially when compiling with -pg.
         * Generally we just want to run select again. */
        log_debug("select() returned EINTR");
        continue;
      }

      log_error("select() return=%d errno=%d (%s)",
                n, errno, fc_strerror(fc_get_errno()));
      return -1;
    }

    if (FD_ISSET(socket_fd, &exceptfs)) {
      return -1;
    }

    if (have_data_for_server && FD_ISSET(socket_fd, &writefs)) {
      flush_connection_send_buffer_all(pc);
    }

    if (FD_ISSET(socket_fd, &readfs)) {
      return read_socket_data(socket_fd, pc->buffer);
    }
  }
}