diff options
author | Derrell Lipman <derrell@samba.org> | 2005-05-27 14:38:00 +0000 |
---|---|---|
committer | Derrell Lipman <derrell@samba.org> | 2005-05-27 14:38:00 +0000 |
commit | 2de1f68c47c065744fb604959335d92a4dccfc80 (patch) | |
tree | 886280f3003a9f326a75dea88d3be5acffc95d79 /source/lib | |
parent | 6ae6efefc2ade45e4b93e7a94f120265f6689373 (diff) | |
download | samba-2de1f68c47c065744fb604959335d92a4dccfc80.tar.gz samba-2de1f68c47c065744fb604959335d92a4dccfc80.tar.xz samba-2de1f68c47c065744fb604959335d92a4dccfc80.zip |
r7025: 1 if not all data is available at the time we go to read a packet, retry
the read using a timeout to ensure that all data for the packet is received.
2 some minor changes to meet coding standards
3 eliminate some compiler warnings
Diffstat (limited to 'source/lib')
-rw-r--r-- | source/lib/util_sock.c | 71 |
1 files changed, 58 insertions, 13 deletions
diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c index 72837d73d92..ca7ecce74b5 100644 --- a/source/lib/util_sock.c +++ b/source/lib/util_sock.c @@ -554,7 +554,8 @@ ssize_t read_smb_length(int fd, char *inbuf, unsigned int timeout) BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) { - ssize_t len,ret; + char *p; + ssize_t n_remaining, n_read, len, ret; smb_read_error = 0; @@ -570,18 +571,20 @@ BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) * variables still suck :-). JRA. */ - if (smb_read_error == 0) + 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. - */ + * 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)); + DEBUG(0,("Invalid packet length! (%lu bytes).\n", + (unsigned long)len)); if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) { /* @@ -590,23 +593,65 @@ BOOL receive_smb_raw(int fd, char *buffer, unsigned int timeout) * variables still suck :-). JRA. */ - if (smb_read_error == 0) + 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) + /* + * Read the remainder of the data. Don't use a timeout since + * the overhead of it is not usually necessary. + */ + p = buffer + 4; /* initial read buffer pointer */ + n_remaining = len; /* initial length to be read */ + n_read = 0; /* initialize number of bytes read */ + + ret = read_socket_data(fd, p, n_remaining); + + if ((ret < 0 && errno == EAGAIN) || + (ret > 0 && ret < n_remaining)) { + /* + * We were able to read the length earlier, but all of + * the remainder of the data is not yet available to + * us (as indicated by EAGAIN if we got nothing, or by + * the amount of just-read data not matching the + * packet length). Read again, this time awaiting the + * data to arrive for a short period of time. + */ + + /* If partial read occurred... */ + if (ret > 0) { + /* ... then update buffer pointer and counts */ + p += ret; + n_read += ret; + n_remaining -= ret; + } + + ret = read_socket_with_timeout(fd, p, n_remaining, + n_remaining, 20000); + if (ret > 0) { + n_read += ret; + } + } else { + n_read = ret; + } + + if (n_read != 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); + /* + * 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; |