From 54aee75980dd7eb4cc4d5b8e94149fc088a3d7e5 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Fri, 27 May 2005 14:38:00 +0000 Subject: 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 (This used to be commit 7b4d4f6109d815ec70c65564435d7d9bd22f66d9) --- source3/lib/util_sock.c | 71 ++++++++++++++++++++++++++++++++++++++++--------- source3/tdb/tdbtool.c | 27 ++++++++++++------- 2 files changed, 75 insertions(+), 23 deletions(-) (limited to 'source3') diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 72837d73d9..ca7ecce74b 100644 --- a/source3/lib/util_sock.c +++ b/source3/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; diff --git a/source3/tdb/tdbtool.c b/source3/tdb/tdbtool.c index 70400e1f37..d9e7b9315a 100644 --- a/source3/tdb/tdbtool.c +++ b/source3/tdb/tdbtool.c @@ -416,14 +416,14 @@ static void info_tdb(void) static char *tdb_getline(const char *prompt) { - static char line[1024]; + static char thisline[1024]; char *p; fputs(prompt, stdout); - line[0] = 0; - p = fgets(line, sizeof(line)-1, stdin); + thisline[0] = 0; + p = fgets(thisline, sizeof(thisline)-1, stdin); if (p) p = strchr(p, '\n'); if (p) *p = 0; - return p?line:NULL; + return p?thisline:NULL; } static int do_delete_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, @@ -560,6 +560,15 @@ static int do_command(void) case CMD_HELP: help(); return 0; + case CMD_CREATE_TDB: + case CMD_OPEN_TDB: + case CMD_SYSTEM: + case CMD_QUIT: + /* + * unhandled commands. cases included here to avoid compiler + * warnings. + */ + return 0; } } @@ -600,19 +609,17 @@ static char *convert_string(char *instring, size_t *sizep) int main(int argc, char *argv[]) { - int i; - - cmdname = ""; + cmdname = (char *) ""; arg1 = NULL; arg1len = 0; arg2 = NULL; arg2len = 0; if (argv[1]) { - cmdname = "open"; + cmdname = (char *) "open"; arg1 = argv[1]; do_command(); - cmdname = ""; + cmdname = (char *) ""; arg1 = NULL; } @@ -622,7 +629,7 @@ int main(int argc, char *argv[]) /* Interactive mode */ while ((cmdname = tdb_getline("tdb> "))) { arg2 = arg1 = NULL; - if (arg1 = strchr((const char *)cmdname,' ')) { + if ((arg1 = strchr((const char *)cmdname,' ')) != NULL) { arg1++; arg2 = arg1; while (*arg2) { -- cgit