]> arthur.barton.de Git - netatalk.git/commitdiff
test224 works
authorFrank Lahm <franklahm@googlemail.com>
Mon, 28 Feb 2011 16:12:14 +0000 (17:12 +0100)
committerFrank Lahm <franklahm@googlemail.com>
Mon, 28 Feb 2011 16:12:14 +0000 (17:12 +0100)
etc/afpd/afp_dsi.c
etc/afpd/auth.c
etc/afpd/globals.h
etc/afpd/status.c
include/atalk/afp.h
include/atalk/dsi.h
libatalk/dsi/dsi_stream.c
libatalk/util/server_child.c
libatalk/util/server_ipc.c

index 7bb4bbc6fd18c658cf45fd83aea38fb26dda52dd..375891aaf011596a78bdb9a0346a34870cd9d273 100644 (file)
@@ -122,6 +122,11 @@ static void afp_dsi_die(int sig)
         return; /* this returns to afp_disconnect */
     }
 
+    if (dsi->flags & DSI_DISCONNECTED) {
+        LOG(log_note, logtype_afpd, "Disconnected session terminating");
+        exit(0);
+    }
+
     dsi_attention(AFPobj->handle, AFPATTN_SHUTDOWN);
     afp_dsi_close(AFPobj);
     if (sig) /* if no signal, assume dieing because logins are disabled &
@@ -135,6 +140,7 @@ static void afp_dsi_die(int sig)
     }
 }
 
+/* SIGURG handler (primary reconnect) */
 static void afp_dsi_transfer_session(int sig _U_)
 {
     uint16_t dsiID;
@@ -158,9 +164,10 @@ static void afp_dsi_transfer_session(int sig _U_)
     LOG(log_note, logtype_afpd, "afp_dsi_transfer_session: received socket fd: %i", socket);
 
     dsi->socket = socket;
-    dsi->flags |= DSI_RECONSOCKET;
-    dsi->flags &= ~DSI_DISCONNECTED;
+    dsi->flags = DSI_RECONSOCKET;
     dsi->datalen = 0;
+    dsi->eof = dsi->start = dsi->buffer;
+    dsi->in_write = 0;
     dsi->header.dsi_requestID = dsiID;
     dsi->header.dsi_command = DSIFUNC_CMD;
 
@@ -183,12 +190,6 @@ static void afp_dsi_transfer_session(int sig _U_)
     siglongjmp(recon_jmp, 1);
 }
 
-/* */
-static void afp_dsi_sleep(void)
-{
-    dsi_sleep(AFPobj->handle, 1);
-}
-
 /* ------------------- */
 static void afp_dsi_timedown(int sig _U_)
 {
@@ -275,11 +276,11 @@ static void alarm_handler(int sig _U_)
     /* we got some traffic from the client since the previous timer tick. */
     if ((dsi->flags & DSI_DATA)) {
         dsi->flags &= ~DSI_DATA;
-        dsi->flags &= ~DSI_DISCONNECTED;
-       return;
+        return;
     }
 
     dsi->tickle++;
+    LOG(log_note, logtype_afpd, "afp_alarm: tickle count: %i", dsi->tickle);
 
     if (dsi->flags & DSI_SLEEPING) {
         if (dsi->tickle > AFPobj->options.sleep) {
@@ -298,8 +299,9 @@ 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)) {
+    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;
         return;
     }
@@ -351,7 +353,6 @@ void afp_over_dsi(AFPObj *obj)
     obj->exit = afp_dsi_die;
     obj->reply = (int (*)()) dsi_cmdreply;
     obj->attention = (int (*)(void *, AFPUserBytes)) dsi_attention;
-    obj->sleep = afp_dsi_sleep;
     dsi->tickle = 0;
 
     memset(&action, 0, sizeof(action));
@@ -456,15 +457,15 @@ void afp_over_dsi(AFPObj *obj)
 
     /* get stuck here until the end */
     while (1) {
-        if (sigsetjmp(recon_jmp, 1) != 0) {
-            LOG(log_note, logtype_afpd, "Resuming operation after succesfull primary reconnect");
-            dsi->flags &= ~(DSI_RUNNING | DSI_DATA);
-            dsi->eof = dsi->start = dsi->buffer;
-            dsi->in_write = 0;
+        if (sigsetjmp(recon_jmp, 1) != 0)
+            /* returning from SIGALARM handler for a primary reconnect */
             continue;
-        }
+
+        /* Blocking read on the network socket */
         cmd = dsi_receive(dsi);
+
         if (cmd == 0) {
+            /* cmd == 0 is the error condition */
             if (dsi->flags & DSI_RECONSOCKET) {
                 /* we just got a reconnect so we immediately try again to receive on the new fd */
                 dsi->flags &= ~DSI_RECONSOCKET;
@@ -484,8 +485,10 @@ void afp_over_dsi(AFPObj *obj)
             }
         }
 
-        dsi->tickle = 0;
-        dsi_sleep(dsi, 0); /* wake up */
+        if (!dsi->flags & DSI_EXTSLEEP) {
+            dsi->flags &= ~DSI_SLEEPING;
+            dsi->tickle = 0;
+        }
 
         if (reload_request) {
             reload_request = 0;
index ea774ee2f35fa9d6f899a35182b68780e528fe87..f6082fad16f0f51270bea2b54ff119d72bc7db49 100644 (file)
@@ -436,25 +436,48 @@ static int login(AFPObj *obj, struct passwd *pwd, void (*logout)(void), int expi
 }
 
 /* ---------------------- */
-int afp_zzz ( /* Function 122 */
-    AFPObj       *obj,
-    char         *ibuf _U_, size_t ibuflen _U_, 
-    char *rbuf, size_t *rbuflen)
+int afp_zzz(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen)
 {
-    u_int32_t   retdata;
+    uint32_t data;
+    DSI *dsi = (DSI *)AFPobj->handle;
 
     *rbuflen = 0;
 
-    retdata = obj->options.sleep /120;
-    if (!retdata) {
-        retdata = 1;
+    if (ibuflen < 4)
+        return AFPERR_MISC;
+    memcpy(&data, ibuf, 4); /* flag */
+    data = ntohl(data);
+
+    /*
+     * Possible sleeping states:
+     * 1) normal sleep: DSI_SLEEPING (up to 10.3)
+     * 2) extended sleep: DSI_SLEEPING | DSI_EXTSLEEP (starting with 10.4)
+     */
+
+    if (data & AFPZZZ_EXT_WAKEUP) {
+        /* wakeup request from exetended sleep */
+        if (dsi->flags & DSI_EXTSLEEP)
+            dsi->flags &= ~(DSI_SLEEPING | DSI_EXTSLEEP);
+    } else {
+        /* sleep request */
+        dsi->flags |= DSI_SLEEPING;
+        if (data & AFPZZZ_EXT_SLEEP)
+            dsi->flags |= DSI_EXTSLEEP;
     }
-    *rbuflen = sizeof(retdata);
-    retdata = htonl(retdata);
-    memcpy(rbuf, &retdata, sizeof(retdata));
-    if (obj->sleep)
-        obj->sleep();
-    rbuf += sizeof(retdata);
+    /*
+     * According to AFP 3.3 spec we should not return anything,
+     * but eg 10.5.8 server still returns the numbers of hours
+     * the server is keeping the sessino (ie max sleeptime).
+     */
+    data = obj->options.sleep / 120; /* hours */
+    if (!data) {
+        data = 1;
+    }
+    *rbuflen = sizeof(data);
+    data = htonl(data);
+    memcpy(rbuf, &data, sizeof(data));
+    rbuf += sizeof(data);
+
     return AFP_OK;
 }
 
index ddd2393705a00cbfe95a0528f5aa08f79c56ee84..4b6cea4ae0ca80cfa41a69935531a68af66c9cce 100644 (file)
@@ -102,7 +102,6 @@ typedef struct _AFPObj {
     void (*logout)(void), (*exit)(int);
     int (*reply)(void *, int);
     int (*attention)(void *, AFPUserBytes);
-    void (*sleep)(void);
     /* to prevent confusion, only use these in afp_* calls */
     char oldtmp[AFPOBJ_TMPSIZ + 1], newtmp[AFPOBJ_TMPSIZ + 1];
     void *uam_cookie; /* cookie for uams */
index 8147a038bc687e65787b3cd092b35c06c715bae5..28408658162948749d230d94f8f1c1764299a83a 100644 (file)
@@ -46,32 +46,26 @@ static   size_t maxstatuslen = 0;
 static void status_flags(char *data, const int notif, const int ipok,
                          const unsigned char passwdbits, const int dirsrvcs _U_, int flags)
 {
-    u_int16_t           status;
+    uint16_t           status;
+
+    status = AFPSRVRINFO_COPY
+           | AFPSRVRINFO_SRVSIGNATURE
+           | AFPSRVRINFO_SRVMSGS
+           | AFPSRVRINFO_FASTBOZO
+           | AFPSRVRINFO_SRVRDIR
+           | AFPSRVRINFO_SRVUTF8
+           | AFPSRVRINFO_EXTSLEEP;
 
-    status = AFPSRVRINFO_COPY;
     if (passwdbits & PASSWD_SET) /* some uams may not allow this. */
         status |= AFPSRVRINFO_PASSWD;
     if (passwdbits & PASSWD_NOSAVE)
         status |= AFPSRVRINFO_NOSAVEPASSWD;
-    status |= AFPSRVRINFO_SRVSIGNATURE;
-    /* only advertise tcp/ip if we have a valid address */
-    if (ipok)
+    if (ipok) /* only advertise tcp/ip if we have a valid address */        
         status |= AFPSRVRINFO_TCPIP;
-    status |= AFPSRVRINFO_SRVMSGS;
-    /* Allow the user to decide if we should support server notifications.
-     * With this turned off, the clients will poll for directory changes every
-     * 10 seconds.  This might be too costly to network resources, so make
-     * this an optional thing.  Default will be to _not_ support server
-     * notifications. */
-    if (notif) {
+    if (notif) /* Default is yes */        
         status |= AFPSRVRINFO_SRVNOTIFY;
-    }
-    status |= AFPSRVRINFO_FASTBOZO;
-    status |= AFPSRVRINFO_SRVRDIR; /* AFP 3.1 specs says we need to specify this, but may set the count to 0 */
-    /* We don't set the UTF8 name flag here, we don't know whether we have enough space ... */
-
-    if (flags & OPTION_UUID)   /* 05122008 FIXME: can we set AFPSRVRINFO_UUID here ? see AFPSRVRINFO_SRVRDIR*/
-       status |= AFPSRVRINFO_UUID;
+    if (flags & OPTION_UUID)
+        status |= AFPSRVRINFO_UUID;
 
     status = htons(status);
     memcpy(data + AFPSTATUS_FLAGOFF, &status, sizeof(status));
@@ -397,13 +391,6 @@ static size_t status_utf8servername(char *data, int *nameoffset,
        data += len;
        offset = htons(offset);
        memcpy(begin + *nameoffset, &offset, sizeof(u_int16_t));
-        
-        /* Now set the flag ... */
-       memcpy(&status, begin + AFPSTATUS_FLAGOFF, sizeof(status));
-       status = ntohs(status);
-       status |= AFPSRVRINFO_SRVUTF8;
-       status = htons(status);
-       memcpy(begin + AFPSTATUS_FLAGOFF, &status, sizeof(status));
     }
 
     /* return length of buffer */
index 550343d6fb5e4fcbf9a73c81fef867b518fa16ff..303e705047f58fa5b7b88a799222034dcb282670 100644 (file)
@@ -43,20 +43,19 @@ typedef u_int16_t AFPUserBytes;
 #define AFPTRANS_ALL          (AFPTRANS_DDP | AFPTRANS_TCP)
 
 /* server flags */
-#define AFPSRVRINFO_COPY        (1<<0)  /* supports copyfile */
-#define AFPSRVRINFO_PASSWD      (1<<1)  /* supports change password */
+#define AFPSRVRINFO_COPY         (1<<0)  /* supports copyfile */
+#define AFPSRVRINFO_PASSWD       (1<<1)  /* supports change password */
 #define AFPSRVRINFO_NOSAVEPASSWD (1<<2)  /* don't allow save password */
 #define AFPSRVRINFO_SRVMSGS      (1<<3)  /* supports server messages */
 #define AFPSRVRINFO_SRVSIGNATURE (1<<4)  /* supports server signature */
 #define AFPSRVRINFO_TCPIP        (1<<5)  /* supports tcpip */
 #define AFPSRVRINFO_SRVNOTIFY    (1<<6)  /* supports server notifications */ 
-
 #define AFPSRVRINFO_SRVRECONNECT (1<<7)  /* supports server reconnect */ 
 #define AFPSRVRINFO_SRVRDIR      (1<<8)  /* supports directories service */ 
-
 #define AFPSRVRINFO_SRVUTF8      (1<<9)  /* supports UTF8 names AFP 3.1 */ 
 #define AFPSRVRINFO_UUID         (1<<10) /* supports UUIDs */
-#define AFPSRVRINFO_FASTBOZO    (1<<15) /* fast copying */
+#define AFPSRVRINFO_EXTSLEEP     (1<<11) /* supports extended sleep */
+#define AFPSRVRINFO_FASTBOZO     (1<<15) /* fast copying */
 
 #define AFP_OK         0
 #define AFPERR_DID1     -4000   /* not an afp error DID is 1*/
@@ -129,6 +128,11 @@ typedef enum {
   AFPMESG_SERVER = 1
 } afpmessage_t;
 
+/* extended sleep flag */
+#define AFPZZZ_EXT_SLEEP  1
+#define AFPZZZ_EXT_WAKEUP 2
+
+
 /* AFP functions */
 #define AFP_BYTELOCK        1
 #define AFP_CLOSEVOL            2
index 6b53cfa7f9746bd2b7dd1a3d809f6bcae1059ef7..dc32f6e3779496edffa20d9ddcbd88992db82f41 100644 (file)
@@ -149,11 +149,12 @@ typedef struct DSI {
 #define DSI_DATA             (1 << 0) /* we have received a DSI command */
 #define DSI_RUNNING          (1 << 1) /* we have received a AFP command */
 #define DSI_SLEEPING         (1 << 2) /* we're sleeping after FPZzz */
-#define DSI_DISCONNECTED     (1 << 3) /* we're in diconnected state after a socket error */
-#define DSI_DIE              (1 << 4) /* SIGUSR1, going down in 5 minutes */
-#define DSI_NOREPLY          (1 << 5) /* in dsi_write we generate our own replies */
-#define DSI_RECONSOCKET      (1 << 6) /* we have a new socket from primary reconnect */
-#define DSI_RECONINPROG      (1 << 7) /* used in the new session in reconnect */
+#define DSI_EXTSLEEP         (1 << 3) /* we're sleeping after FPZzz */
+#define DSI_DISCONNECTED     (1 << 4) /* we're in diconnected state after a socket error */
+#define DSI_DIE              (1 << 5) /* SIGUSR1, going down in 5 minutes */
+#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 */
 
 /* basic initialization: dsi_init.c */
 extern DSI *dsi_init (const dsi_proto /*protocol*/,
@@ -175,7 +176,6 @@ extern int  dsi_cmdreply (DSI *, const int);
 extern int dsi_tickle (DSI *);
 extern void dsi_getstatus (DSI *);
 extern void dsi_close (DSI *);
-extern void dsi_sleep (DSI *, const int );
 
 #define DSI_NOWAIT 1
 /* low-level stream commands -- in dsi_stream.c */
index 52209850988bf5c7e80749171cb18a5e2914052c..75e94237a242b29d5d594f60ecf263f4ae4499a5 100644 (file)
@@ -355,16 +355,6 @@ static size_t dsi_buffered_stream_read(DSI *dsi, u_int8_t *data, const size_t le
   return len;
 }
 
-/* ---------------------------------------
-*/
-void dsi_sleep(DSI *dsi, const int state)
-{
-    if (state)
-        dsi->flags |= DSI_SLEEPING;
-    else
-        dsi->flags &= ~DSI_SLEEPING;
-}
-
 /* ---------------------------------------
 */
 static void block_sig(DSI *dsi)
index a5707fa2d9f5afdf2078ba653085b8da2356cb23..63f3683a54090e6caa27b5919bd5082e580188e0 100644 (file)
@@ -326,16 +326,21 @@ void server_child_kill_one_by_id(server_child *children, int forkid, pid_t pid,
             if ( child->pid != pid) {
                 if (child->idlen == idlen && memcmp(child->clientid, id, idlen) == 0) {
                     if ( child->time != boottime ) {
+                        /* Client rebooted */
                         if (uid == child->uid) {
                             kill_child(child);
-                            LOG(log_note, logtype_default, "Disconnected child[%u], client rebooted.", child->pid);
+                            LOG(log_warning, logtype_default,
+                                "Terminated disconnected child[%u], client rebooted.",
+                                child->pid);
                         } else {
-                            LOG(log_note, logtype_default, "Session with different pid[%u]", child->pid);
+                            LOG(log_warning, logtype_default,
+                                "Session with different pid[%u]", child->pid);
                         }
+                    } else {
+                        kill_child(child);
+                        LOG(log_note, logtype_default,
+                            "Terminated disconnected session[%u]", child->pid);
                     }
-                    if (child->killed)
-                        kill_child(child); /* this will send SIGKILL */
-                    LOG(log_note, logtype_default, "", child->pid, pid);
                 }
             } else {
                 /* update childs own slot */
index 14af95628d16057c4c5621451b9d12c1deaa1398..1115551ee4e10826f56aaa1d8fd2b807ecb25371 100644 (file)
@@ -85,8 +85,8 @@ static int ipc_get_session(struct ipc_header *ipc, server_child *children)
         return -1;
     memcpy (clientid, p, idlen);
   
-    LOG (log_debug, logtype_afpd, "ipc_get_session(pid: %u, uid: %u, time %x)",
-         ipc->child_pid, ipc->uid, boottime); 
+    LOG(log_debug, logtype_afpd, "ipc_get_session(pid: %u, uid: %u, time: 0x%08x)",
+        ipc->child_pid, ipc->uid, boottime); 
 
     server_child_kill_one_by_id(children,
                                 CHILD_DSIFORK,