<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>change log for rtems (2011-07-18)</title>
</head>
<body text='#000000' bgcolor='#ffffff'>
<a name='cs1'></a>
<table border='0' cellspacing='0' cellpadding='5' width='100%' bgcolor='#eeeeee'>
<tr><td colspan='3' bgcolor='#dddddd'>
 <font color='#bb2222'><strong>sh</strong></font>
</td></tr>
<tr><td colspan='3' bgcolor='#dddddd'><pre>2011-07-18 Sebastian Huber <sebastian.huber@embedded-brains.de>

        * libnetworking/lib/ftpfs.c: Fixed reply parsing.
</pre></td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/ChangeLog.diff?r1=text&tr1=1.2878&r2=text&tr2=1.2879&diff_format=h">M</a></td><td width='1%'>1.2879</td><td width='100%'>cpukit/ChangeLog</td></tr>
<tr><td width='1%'><a href="http://www.rtems.com/cgi-bin/viewcvs.cgi//rtems/cpukit/libnetworking/lib/ftpfs.c.diff?r1=text&tr1=1.36&r2=text&tr2=1.37&diff_format=h">M</a></td><td width='1%'>1.37</td><td width='100%'>cpukit/libnetworking/lib/ftpfs.c</td></tr>
</table>
<pre>
<font color='#006600'>diff -u rtems/cpukit/ChangeLog:1.2878 rtems/cpukit/ChangeLog:1.2879
--- rtems/cpukit/ChangeLog:1.2878       Mon Jul 18 10:00:45 2011
+++ rtems/cpukit/ChangeLog      Mon Jul 18 10:25:32 2011
</font><font color='#997700'>@@ -1,5 +1,9 @@
</font> 2011-07-18        Sebastian Huber <sebastian.huber@embedded-brains.de>
 
<font color='#000088'>+   * libnetworking/lib/ftpfs.c: Fixed reply parsing.
+
+2011-07-18     Sebastian Huber <sebastian.huber@embedded-brains.de>
+
</font>   * rtems/src/msgmp.c: Getting a remote object does not start a critical
        section.
 

<font color='#006600'>diff -u rtems/cpukit/libnetworking/lib/ftpfs.c:1.36 rtems/cpukit/libnetworking/lib/ftpfs.c:1.37
--- rtems/cpukit/libnetworking/lib/ftpfs.c:1.36 Mon Feb 21 04:58:15 2011
+++ rtems/cpukit/libnetworking/lib/ftpfs.c      Mon Jul 18 10:25:33 2011
</font><font color='#997700'>@@ -79,6 +79,21 @@
</font>   int data_socket;
 
   /**
<font color='#000088'>+   * Current index into the reply buffer.
+   */
+  size_t reply_current;
+
+  /**
+   * End index of the reply buffer.
+   */
+  size_t reply_end;
+
+  /**
+   * Buffer for relpy data.
+   */
+  char reply_buffer [128];
+
+  /**
</font>    * End of file flag.
    */
   bool eof;
<font color='#997700'>@@ -218,10 +233,9 @@
</font> typedef enum {
   RTEMS_FTPFS_REPLY_START,
   RTEMS_FTPFS_REPLY_SINGLE_LINE,
<font color='#880000'>-  RTEMS_FTPFS_REPLY_SINGLE_LINE_DONE,
</font><font color='#000088'>+  RTEMS_FTPFS_REPLY_DONE,
</font>   RTEMS_FTPFS_REPLY_MULTI_LINE,
<font color='#880000'>-  RTEMS_FTPFS_REPLY_NEW_LINE,
-  RTEMS_FTPFS_REPLY_NEW_LINE_START
</font><font color='#000088'>+  RTEMS_FTPFS_REPLY_MULTI_LINE_START
</font> } rtems_ftpfs_reply_state;
 
 typedef enum {
<font color='#997700'>@@ -235,73 +249,99 @@
</font> 
 #define RTEMS_FTPFS_REPLY_SIZE 3
 
<font color='#000088'>+static bool rtems_ftpfs_is_reply_code_valid(unsigned char *reply)
+{
+  return isdigit(reply [0]) && isdigit(reply [1]) && isdigit(reply [2]);
+}
+
</font> static rtems_ftpfs_reply rtems_ftpfs_get_reply(
<font color='#880000'>-  int socket,
</font><font color='#000088'>+  rtems_ftpfs_entry *e,
</font>   rtems_ftpfs_reply_parser parser,
   void *parser_arg,
   bool verbose
 )
 {
   rtems_ftpfs_reply_state state = RTEMS_FTPFS_REPLY_START;
<font color='#880000'>-  unsigned char reply_first [RTEMS_FTPFS_REPLY_SIZE] = { 'a', 'a', 'a' };
-  unsigned char reply_last [RTEMS_FTPFS_REPLY_SIZE] = { 'b', 'b', 'b' };
-  size_t reply_first_index = 0;
-  size_t reply_last_index = 0;
-  char buf [128];
</font><font color='#000088'>+  unsigned char reply_code [RTEMS_FTPFS_REPLY_SIZE] = { 'a', 'a', 'a' };
+  size_t reply_code_index = 0;
+
+  while (state != RTEMS_FTPFS_REPLY_DONE) {
+    char *buf = NULL;
+    size_t i = 0;
+    size_t n = 0;
</font> 
<font color='#880000'>-  while (true) {
</font>     /* Receive reply fragment from socket */
<font color='#880000'>-    ssize_t i = 0;
-    ssize_t rv = recv(socket, buf, sizeof(buf), 0);
</font><font color='#000088'>+    if (e->reply_current == e->reply_end) {
+      ssize_t rv = 0;
</font> 
<font color='#880000'>-    if (rv <= 0) {
-      return RTEMS_FTPFS_REPLY_ERROR;
-    }
</font><font color='#000088'>+      e->reply_current = 0;
+      e->reply_end = 0;
</font> 
<font color='#880000'>-    /* Be verbose if necessary */
-    if (verbose) {
-      write(STDERR_FILENO, buf, (size_t) rv);
</font><font color='#000088'>+      rv = recv(
+        e->ctrl_socket,
+        &e->reply_buffer [0],
+        sizeof(e->reply_buffer),
+        0
+      );
+
+      if (rv > 0) {
+        e->reply_end = (size_t) rv;
+      } else {
+        return RTEMS_FTPFS_REPLY_ERROR;
+      }
</font>     }
 
<font color='#000088'>+    buf = &e->reply_buffer [e->reply_current];
+    n = e->reply_end - e->reply_current;
+
</font>     /* Invoke parser if necessary */
     if (parser != NULL) {
<font color='#880000'>-      parser(buf, (size_t) rv, parser_arg);
</font><font color='#000088'>+      parser(buf, n, parser_arg);
</font>     }
 
     /* Parse reply fragment */
<font color='#880000'>-    for (i = 0; i < rv; ++i) {
</font><font color='#000088'>+    for (i = 0; i < n && state != RTEMS_FTPFS_REPLY_DONE; ++i) {
</font>       char c = buf [i];
 
       switch (state) {
         case RTEMS_FTPFS_REPLY_START:
<font color='#880000'>-          if (reply_first_index < RTEMS_FTPFS_REPLY_SIZE) {
-            reply_first [reply_first_index] = c;
-            ++reply_first_index;
-          } else if (c == '-') {
-            state = RTEMS_FTPFS_REPLY_MULTI_LINE;
</font><font color='#000088'>+          if (reply_code_index < RTEMS_FTPFS_REPLY_SIZE) {
+            reply_code [reply_code_index] = c;
+            ++reply_code_index;
+          } else if (rtems_ftpfs_is_reply_code_valid(reply_code)) {
+            if (c == '-') {
+              state = RTEMS_FTPFS_REPLY_MULTI_LINE;
+            } else {
+              state = RTEMS_FTPFS_REPLY_SINGLE_LINE;
+            }
</font>           } else {
<font color='#880000'>-            state = RTEMS_FTPFS_REPLY_SINGLE_LINE;
</font><font color='#000088'>+            return RTEMS_FTPFS_REPLY_ERROR;
</font>           }
           break;
         case RTEMS_FTPFS_REPLY_SINGLE_LINE:
           if (c == '\n') {
<font color='#880000'>-            state = RTEMS_FTPFS_REPLY_SINGLE_LINE_DONE;
</font><font color='#000088'>+            state = RTEMS_FTPFS_REPLY_DONE;
</font>           }
           break;
         case RTEMS_FTPFS_REPLY_MULTI_LINE:
           if (c == '\n') {
<font color='#880000'>-            state = RTEMS_FTPFS_REPLY_NEW_LINE_START;
-            reply_last_index = 0;
</font><font color='#000088'>+            state = RTEMS_FTPFS_REPLY_MULTI_LINE_START;
+            reply_code_index = 0;
</font>           }
           break;
<font color='#880000'>-        case RTEMS_FTPFS_REPLY_NEW_LINE:
-        case RTEMS_FTPFS_REPLY_NEW_LINE_START:
-          if (reply_last_index < RTEMS_FTPFS_REPLY_SIZE) {
-            state = RTEMS_FTPFS_REPLY_NEW_LINE;
-            reply_last [reply_last_index] = c;
-            ++reply_last_index;
</font><font color='#000088'>+        case RTEMS_FTPFS_REPLY_MULTI_LINE_START:
+          if (reply_code_index < RTEMS_FTPFS_REPLY_SIZE) {
+            if (reply_code [reply_code_index] == c) {
+              ++reply_code_index;
+            } else {
+              state = RTEMS_FTPFS_REPLY_MULTI_LINE;
+            }
</font>           } else {
<font color='#880000'>-            state = RTEMS_FTPFS_REPLY_MULTI_LINE;
</font><font color='#000088'>+            if (c == ' ') {
+              state = RTEMS_FTPFS_REPLY_SINGLE_LINE;
+            } else {
+              state = RTEMS_FTPFS_REPLY_MULTI_LINE;
+            }
</font>           }
           break;
         default:
<font color='#997700'>@@ -309,37 +349,20 @@
</font>       }
     }
 
<font color='#880000'>-    /* Check reply */
-    if (state == RTEMS_FTPFS_REPLY_SINGLE_LINE_DONE) {
-      if (
-        isdigit(reply_first [0])
-          && isdigit(reply_first [1])
-          && isdigit(reply_first [2])
-      ) {
-        break;
-      } else {
-        return RTEMS_FTPFS_REPLY_ERROR;
-      }
-    } else if (state == RTEMS_FTPFS_REPLY_NEW_LINE_START) {
-      bool ok = true;
-
-      for (i = 0; i < RTEMS_FTPFS_REPLY_SIZE; ++i) {
-        ok = ok
-          && reply_first [i] == reply_last [i]
-          && isdigit(reply_first [i]);
-      }
-
-      if (ok) {
-        break;
-      }
</font><font color='#000088'>+    /* Be verbose if necessary */
+    if (verbose) {
+      write(STDERR_FILENO, buf, i);
</font>     }
<font color='#000088'>+
+    /* Update reply index */
+    e->reply_current += i;
</font>   }
 
<font color='#880000'>-  return reply_first [0];
</font><font color='#000088'>+  return reply_code [0];
</font> }
 
 static rtems_ftpfs_reply rtems_ftpfs_send_command_with_parser(
<font color='#880000'>-  int socket,
</font><font color='#000088'>+  rtems_ftpfs_entry *e,
</font>   const char *cmd,
   const char *arg,
   rtems_ftpfs_reply_parser parser,
<font color='#997700'>@@ -364,14 +387,14 @@
</font>     buf_eol [1] = '\n';
 
     /* Send */
<font color='#880000'>-    n = send(socket, buf, len, 0);
</font><font color='#000088'>+    n = send(e->ctrl_socket, buf, len, 0);
</font>     if (n == (ssize_t) len) {
       if (verbose) {
         write(STDERR_FILENO, buf, len);
       }
 
       /* Reply */
<font color='#880000'>-      reply = rtems_ftpfs_get_reply(socket, parser, parser_arg, verbose);
</font><font color='#000088'>+      reply = rtems_ftpfs_get_reply(e, parser, parser_arg, verbose);
</font>     }
 
     free(buf);
<font color='#997700'>@@ -381,14 +404,14 @@
</font> }
 
 static rtems_ftpfs_reply rtems_ftpfs_send_command(
<font color='#880000'>-  int socket,
</font><font color='#000088'>+  rtems_ftpfs_entry *e,
</font>   const char *cmd,
   const char *arg,
   bool verbose
 )
 {
   return rtems_ftpfs_send_command_with_parser(
<font color='#880000'>-    socket,
</font><font color='#000088'>+    e,
</font>     cmd,
     arg,
     NULL,
<font color='#997700'>@@ -542,7 +565,7 @@
</font>           && (iop->flags & LIBIO_FLAGS_WRITE) != 0
           && !error
       ) {
<font color='#880000'>-        reply = rtems_ftpfs_get_reply(e->ctrl_socket, NULL, NULL, verbose);
</font><font color='#000088'>+        reply = rtems_ftpfs_get_reply(e, NULL, NULL, verbose);
</font>         if (reply != RTEMS_FTPFS_REPLY_2) {
           eno = EIO;
         }
<font color='#997700'>@@ -551,12 +574,7 @@
</font> 
     /* Close control connection if necessary */
     if (e->ctrl_socket >= 0) {
<font color='#880000'>-      reply = rtems_ftpfs_send_command(
-        e->ctrl_socket,
-        "QUIT",
-        NULL,
-        verbose
-      );
</font><font color='#000088'>+      reply = rtems_ftpfs_send_command(e, "QUIT", NULL, verbose);
</font>       if (reply != RTEMS_FTPFS_REPLY_2) {
         eno = EIO;
       }
<font color='#997700'>@@ -644,21 +662,16 @@
</font>   DEBUG_PRINTF("client = %s\n", inet_ntoa(sa.sin_addr));
 
   /* Now we should get a welcome message from the server */
<font color='#880000'>-  reply = rtems_ftpfs_get_reply(e->ctrl_socket, NULL, NULL, verbose);
</font><font color='#000088'>+  reply = rtems_ftpfs_get_reply(e, NULL, NULL, verbose);
</font>   if (reply != RTEMS_FTPFS_REPLY_2) {
     return ENOENT;
   }
 
   /* Send USER command */
<font color='#880000'>-  reply = rtems_ftpfs_send_command(e->ctrl_socket, "USER ", user, verbose);
</font><font color='#000088'>+  reply = rtems_ftpfs_send_command(e, "USER ", user, verbose);
</font>   if (reply == RTEMS_FTPFS_REPLY_3) {
     /* Send PASS command */
<font color='#880000'>-    reply = rtems_ftpfs_send_command(
-      e->ctrl_socket,
-      "PASS ",
-      password,
-      verbose
-    );
</font><font color='#000088'>+    reply = rtems_ftpfs_send_command(e, "PASS ", password, verbose);
</font>     if (reply != RTEMS_FTPFS_REPLY_2) {
       return EACCES;
     }
<font color='#997700'>@@ -669,7 +682,7 @@
</font>   }
 
   /* Send TYPE command to set binary mode for all data transfers */
<font color='#880000'>-  reply = rtems_ftpfs_send_command(e->ctrl_socket, "TYPE I", NULL, verbose);
</font><font color='#000088'>+  reply = rtems_ftpfs_send_command(e, "TYPE I", NULL, verbose);
</font>   if (reply != RTEMS_FTPFS_REPLY_2) {
     return EIO;
   }
<font color='#997700'>@@ -739,12 +752,7 @@
</font>     (data_port >> 8) & 0xffUL,
     (data_port >> 0) & 0xffUL
   );
<font color='#880000'>-  reply = rtems_ftpfs_send_command(
-    e->ctrl_socket,
-    port_command,
-    NULL,
-    verbose
-  );
</font><font color='#000088'>+  reply = rtems_ftpfs_send_command(e, port_command, NULL, verbose);
</font>   if (reply != RTEMS_FTPFS_REPLY_2) {
     eno = ENOTSUP;
     goto cleanup;
<font color='#997700'>@@ -758,12 +766,7 @@
</font>   }
 
   /* Send RETR or STOR command with filename */
<font color='#880000'>-  reply = rtems_ftpfs_send_command(
-    e->ctrl_socket,
-    file_command,
-    filename,
-    verbose
-  );
</font><font color='#000088'>+  reply = rtems_ftpfs_send_command(e, file_command, filename, verbose);
</font>   if (reply != RTEMS_FTPFS_REPLY_1) {
     eno = EIO;
     goto cleanup;
<font color='#997700'>@@ -888,7 +891,7 @@
</font> 
   /* Send PASV command */
   reply = rtems_ftpfs_send_command_with_parser(
<font color='#880000'>-    e->ctrl_socket,
</font><font color='#000088'>+    e,
</font>     "PASV",
     NULL,
     rtems_ftpfs_pasv_parser,
<font color='#997700'>@@ -925,12 +928,7 @@
</font>   }
 
   /* Send RETR or STOR command with filename */
<font color='#880000'>-  reply = rtems_ftpfs_send_command(
-    e->ctrl_socket,
-    file_command,
-    filename,
-    verbose
-  );
</font><font color='#000088'>+  reply = rtems_ftpfs_send_command(e, file_command, filename, verbose);
</font>   if (reply != RTEMS_FTPFS_REPLY_1) {
     return EIO;
   }
<font color='#997700'>@@ -1006,7 +1004,7 @@
</font>   }
 
   /* Allocate connection entry */
<font color='#880000'>-  e = malloc(sizeof(*e));
</font><font color='#000088'>+  e = calloc(1, sizeof(*e));
</font>   if (e == NULL) {
     rtems_set_errno_and_return_minus_one(ENOMEM);
   }
<font color='#997700'>@@ -1014,7 +1012,6 @@
</font>   /* Initialize connection entry */
   e->ctrl_socket = -1;
   e->data_socket = -1;
<font color='#880000'>-  e->eof = false;
</font> 
   /* Save connection state */
   iop->data1 = e;
<font color='#997700'>@@ -1094,7 +1091,7 @@
</font>     if (rv <= 0) {
       if (rv == 0) {
         rtems_ftpfs_reply reply =
<font color='#880000'>-          rtems_ftpfs_get_reply(e->ctrl_socket, NULL, NULL, verbose);
</font><font color='#000088'>+          rtems_ftpfs_get_reply(e, NULL, NULL, verbose);
</font> 
         if (reply == RTEMS_FTPFS_REPLY_2) {
           e->eof = true;
</pre>
<p> </p>

<p>--<br />
<small>Generated by <a href="http://www.codewiz.org/projects/index.html#loginfo">Deluxe Loginfo</a> 2.122 by Bernardo Innocenti <bernie@develer.com></small></p>
</body>
</html>