]> arthur.barton.de Git - netatalk.git/commitdiff
Correct afp logout vs dsi eof behaviour
authorFrank Lahm <franklahm@googlemail.com>
Fri, 8 Apr 2011 10:32:09 +0000 (12:32 +0200)
committerFrank Lahm <franklahm@googlemail.com>
Fri, 8 Apr 2011 10:32:09 +0000 (12:32 +0200)
etc/afpd/afp_dsi.c
etc/afpd/auth.c
etc/afpd/fork.h
etc/afpd/ofork.c
include/atalk/dsi.h
libatalk/dsi/dsi_close.c

index 2d0da9f26a096df9991bae7a8a997bceb755d317..0a735ea4d2ae1a0946b63d0ece3cdea8756547f8 100644 (file)
@@ -118,7 +118,7 @@ static void afp_dsi_die(int sig)
 
     dsi_attention(AFPobj->handle, AFPATTN_SHUTDOWN);
     afp_dsi_close(AFPobj);
-    if (sig) /* if no signal, assume dieing because logins are disabled &
+   if (sig) /* if no signal, assume dieing because logins are disabled &
                 don't log it (maintenance mode)*/
         LOG(log_info, logtype_afpd, "Connection terminated");
     if (sig == SIGTERM || sig == SIGALRM) {
@@ -495,6 +495,13 @@ void afp_over_dsi(AFPObj *obj)
             }
             /* Some error on the client connection, enter disconnected state */
             dsi->flags |= DSI_DISCONNECTED;
+
+            /* the client sometimes logs out (afp_logout) but doesn't close the DSI session */
+            if (dsi->flags & DSI_AFP_LOGGED_OUT) {
+                afp_dsi_close(obj);
+                exit(0);
+            }
+
             pause(); /* gets interrupted by SIGALARM or SIGURG tickle */
             continue; /* continue receiving until disconnect timer expires
                        * or a primary reconnect succeeds  */
@@ -542,7 +549,7 @@ void afp_over_dsi(AFPObj *obj)
             LOG(log_debug, logtype_afpd, "DSI: close session request");
             afp_dsi_close(obj);
             LOG(log_note, logtype_afpd, "done");
-            return;
+            exit(0);
 
         case DSIFUNC_TICKLE:
             dsi->flags &= ~DSI_DATA; /* thats no data in the sense we use it in alarm_handler */
index 675111e6529c1fef092b4e0eda6be78b84011129..566a8d0e05b1b838ddc5e2dceef29463e9c33d03 100644 (file)
@@ -937,8 +937,12 @@ int afp_logincont(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *r
 
 int afp_logout(AFPObj *obj, char *ibuf _U_, size_t ibuflen  _U_, char *rbuf  _U_, size_t *rbuflen)
 {
+    DSI *dsi = (DSI *)(obj->handle);
+
     LOG(log_note, logtype_afpd, "AFP logout by %s", obj->username);
+    of_close_all_forks();
     close_all_vol();
+    dsi->flags = DSI_AFP_LOGGED_OUT;
     *rbuflen = 0;
     return AFP_OK;
 }
index 0cd55cec41aaf609990ef121c4adcaa205e6af09..7ea7a8a6edc56e52424897ce07616847224f4886 100644 (file)
@@ -70,6 +70,7 @@ extern int          of_stat      (struct path *);
 extern int          of_statdir   (struct vol *vol, struct path *);
 extern int          of_closefork (struct ofork *ofork);
 extern void         of_closevol  (const struct vol *vol);
+extern void         of_close_all_forks(void);
 extern struct adouble *of_ad     (const struct vol *, struct path *, struct adouble *);
 
 #ifdef HAVE_ATFUNCS
index 8d6ef268b223e28cf330b2a92876cea4b0d5a4d6..e65c4024f530077f8db5cd3416735c81bcdc21fc 100644 (file)
@@ -485,3 +485,23 @@ void of_closevol(const struct vol *vol)
     return;
 }
 
+/* ----------------------
+   close all forks for a volume
+*/
+void of_close_all_forks(void)
+{
+    int refnum;
+
+    if (!oforks)
+        return;
+
+    for ( refnum = 0; refnum < nforks; refnum++ ) {
+        if (oforks[ refnum ] != NULL) {
+            if (of_closefork( oforks[ refnum ]) < 0 ) {
+                LOG(log_error, logtype_afpd, "of_close_all_forks: %s", strerror(errno) );
+            }
+        }
+    }
+    return;
+}
+
index 4d48190045bac14792df3071368dd7b436c30259..babd8288ce3fc55745b5acb7d2897479822ac4f5 100644 (file)
@@ -156,6 +156,7 @@ typedef struct DSI {
 #define DSI_NOREPLY          (1 << 6) /* in dsi_write we generate our own replies */
 #define DSI_RECONSOCKET      (1 << 7) /* we have a new socket from primary reconnect */
 #define DSI_RECONINPROG      (1 << 8) /* used in the new session in reconnect */
+#define DSI_AFP_LOGGED_OUT   (1 << 9) /* client called afp_logout, quit on next EOF from socket */
 
 /* basic initialization: dsi_init.c */
 extern DSI *dsi_init (const dsi_proto /*protocol*/,
index d409814f5f82c038e736368b8b2bad3ca3138f06..6362182ba49fe6d259dd67277eb8cc0f7df6b7e3 100644 (file)
@@ -17,7 +17,7 @@
 void dsi_close(DSI *dsi)
 {
   /* server generated. need to set all the fields. */
-  if (!(dsi->flags & DSI_SLEEPING)) {
+  if (!(dsi->flags & DSI_SLEEPING) && !(dsi->flags & DSI_DISCONNECTED)) {
       dsi->header.dsi_flags = DSIFL_REQUEST;
       dsi->header.dsi_command = DSIFUNC_CLOSE;
       dsi->header.dsi_requestID = htons(dsi_serverID(dsi));