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); }
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); }
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; }
/************************************************************************** ... **************************************************************************/ 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(); } }
/**************************************************************************** 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); } } }