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); }
static int expect(int master, char *issue, char *expected) { pstring buffer; int attempts, timeout, nread, len; BOOL match = False; for (attempts = 0; attempts < 2; attempts++) { if (!strequal(issue, ".")) { if (lp_passwd_chat_debug()) DEBUG(100, ("expect: sending [%s]\n", issue)); if ((len = write(master, issue, strlen(issue))) != strlen(issue)) { DEBUG(2,("expect: (short) write returned %d\n", len )); return False; } } if (strequal(expected, ".")) return True; /* Initial timeout. */ timeout = lp_passwd_chat_timeout() * 1000; nread = 0; buffer[nread] = 0; while ((len = read_socket_with_timeout(master, buffer + nread, 1, sizeof(buffer) - nread - 1, timeout)) > 0) { nread += len; buffer[nread] = 0; { /* Eat leading/trailing whitespace before match. */ pstring str; pstrcpy( str, buffer); trim_char( str, ' ', ' '); if ((match = (unix_wild_match(expected, str) == 0))) { /* Now data has started to return, lower timeout. */ timeout = lp_passwd_chat_timeout() * 100; } } } if (lp_passwd_chat_debug()) DEBUG(100, ("expect: expected [%s] received [%s] match %s\n", expected, buffer, match ? "yes" : "no" )); if (match) break; if (len < 0) { DEBUG(2, ("expect: %s\n", strerror(errno))); return False; } } DEBUG(10,("expect: returning %s\n", match ? "True" : "False" )); return match; }
ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len) { NTSTATUS status; set_smb_read_error(&cli->smb_rw_error, SMB_READ_OK); status = read_socket_with_timeout( cli->fd, buffer, len, len, cli->timeout, NULL); if (NT_STATUS_IS_OK(status)) { return len; } if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { set_smb_read_error(&cli->smb_rw_error, SMB_READ_EOF); return -1; } if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { set_smb_read_error(&cli->smb_rw_error, SMB_READ_TIMEOUT); return -1; } set_smb_read_error(&cli->smb_rw_error, SMB_READ_ERROR); return -1; }
BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) { ssize_t len,ret; smb_read_error = 0; 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) { if (timeout > 0) { ret = read_socket_with_timeout(fd,buffer+4,len,len,timeout); } else { ret = read_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; }