r7025: 1 if not all data is available at the time we go to read a packet, retry
authorDerrell Lipman <derrell@samba.org>
Fri, 27 May 2005 14:38:00 +0000 (14:38 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:57:00 +0000 (10:57 -0500)
  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

source/lib/util_sock.c
source/tdb/tdbtool.c

index 72837d73d92dc679ff97a86f04f2f68b2125b29a..ca7ecce74b5aa6b474317c5a94febd27e86dcd61 100644 (file)
@@ -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;
index 70400e1f3772927a5f036937838db452f60a36b4..d9e7b9315a05e7c7073494a0a3f603febb1e03ca 100644 (file)
@@ -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) {