]> arthur.barton.de Git - netatalk.git/commitdiff
Fix for bug id #6: uncaught error condition from dsi_stream_read function call.
authorFrank Lahm <franklahm@googlemail.com>
Mon, 23 May 2011 08:07:32 +0000 (10:07 +0200)
committerFrank Lahm <franklahm@googlemail.com>
Mon, 23 May 2011 08:07:32 +0000 (10:07 +0200)
Add a func that enters disconnected state and call it in two places where disconnected state wasn't entered correctly before.

etc/afpd/afp_dsi.c
include/atalk/dsi.h
libatalk/dsi/dsi_stream.c

index c9c3da92e2c8cc97282268393165dab09ce3267d..760c8cf8dde3f9b55eff697919cdee233f60c5aa 100644 (file)
@@ -302,8 +302,7 @@ static void alarm_handler(int sig _U_)
     /* if we're in the midst of processing something, don't die. */        
     if ( !(dsi->flags & DSI_RUNNING) && (dsi->tickle >= AFPobj->options.timeout)) {
         LOG(log_error, logtype_afpd, "afp_alarm: child timed out, entering disconnected state");
-        dsi->proto_close(dsi);
-        dsi->flags |= DSI_DISCONNECTED;
+        (void)dsi_disconnect(dsi);
         return;
     }
 
@@ -312,8 +311,7 @@ static void alarm_handler(int sig _U_)
         err = dsi_tickle(AFPobj->handle);
     if (err <= 0) {
         LOG(log_error, logtype_afpd, "afp_alarm: connection problem, entering disconnected state");
-        dsi->proto_close(dsi);
-        dsi->flags |= DSI_DISCONNECTED;
+        (void)dsi_disconnect(dsi);
     }
 }
 
@@ -495,7 +493,7 @@ void afp_over_dsi(AFPObj *obj)
                 continue;
             }
             /* Some error on the client connection, enter disconnected state */
-            dsi->flags |= DSI_DISCONNECTED;
+            (void)dsi_disconnect(dsi);
 
             /* the client sometimes logs out (afp_logout) but doesn't close the DSI session */
             if (dsi->flags & DSI_AFP_LOGGED_OUT) {
@@ -627,7 +625,7 @@ void afp_over_dsi(AFPObj *obj)
 
             if (!dsi_cmdreply(dsi, err)) {
                 LOG(log_error, logtype_afpd, "dsi_cmdreply(%d): %s", dsi->socket, strerror(errno) );
-                dsi->flags |= DSI_DISCONNECTED;
+                (void)dsi_disconnect(dsi);
             }
             break;
 
@@ -660,7 +658,7 @@ void afp_over_dsi(AFPObj *obj)
 
             if (!dsi_wrtreply(dsi, err)) {
                 LOG(log_error, logtype_afpd, "dsi_wrtreply: %s", strerror(errno) );
-                dsi->flags |= DSI_DISCONNECTED;
+                (void)dsi_disconnect(dsi);
             }
             break;
 
index babd8288ce3fc55745b5acb7d2897479822ac4f5..8fcb950bf9295e984d79dd96bc4309ff6dde5149 100644 (file)
@@ -185,6 +185,7 @@ extern ssize_t dsi_stream_write (DSI *, void *, const size_t, const int mode);
 extern size_t dsi_stream_read (DSI *, void *, const size_t);
 extern int dsi_stream_send (DSI *, void *, size_t);
 extern int dsi_stream_receive (DSI *, void *, const size_t, size_t *);
+extern int dsi_disconnect(DSI *dsi);
 
 #ifdef WITH_SENDFILE
 extern ssize_t dsi_stream_read_file(DSI *, int, off_t off, const size_t len);
index 680967e8be1f543b833d6ae9e6c6caf70d59f532..1ed2b447f744a526b8b7e3cc0d68d3eef1527705 100644 (file)
@@ -122,6 +122,19 @@ static int dsi_peek(DSI *dsi)
     return 0;
 }
 
+/*!
+ * Communication error with the client, enter disconnected state
+ *
+ * 1. close the socket
+ * 2. set the DSI_DISCONNECTED flag
+ */
+int dsi_disconnect(DSI *dsi)
+{
+    dsi->proto_close(dsi);          /* 1 */
+    dsi->flags |= DSI_DISCONNECTED; /* 2 */
+    return 0;
+}
+
 /* ------------------------------
  * write raw data. return actual bytes read. checks against EINTR
  * aren't necessary if all of the signals have SA_RESTART
@@ -352,7 +365,10 @@ static size_t dsi_buffered_stream_read(DSI *dsi, u_int8_t *data, const size_t le
   }
 
   /* now get the remaining data */
-  len += dsi_stream_read(dsi, data + len, length - len);
+  if ((buflen = dsi_stream_read(dsi, data + len, length - len)) != length - len)
+      return 0;
+  len += buflen;
+
   return len;
 }