]> arthur.barton.de Git - netatalk.git/commitdiff
master done
authorFrank Lahm <franklahm@googlemail.com>
Wed, 25 May 2011 13:46:40 +0000 (15:46 +0200)
committerFrank Lahm <franklahm@googlemail.com>
Wed, 25 May 2011 13:46:40 +0000 (15:46 +0200)
etc/afpd/main.c
include/atalk/server_child.h
libatalk/dsi/dsi_getsess.c
libatalk/util/server_ipc.c

index 0df5a5b71bc49136d88bd1033880121b213a6fba..cb2a943f3eb46bcb3436a88af743bd75e724e15a 100644 (file)
@@ -376,6 +376,8 @@ int main(int ac, char **av)
     (void)setlimits();
 
     afp_child_t *child;
+    int fd[2];  /* we only use one, but server_child_add expects [2] */
+    pid_t pid;
 
     /* wait for an appleshare connection. parent remains in the loop
      * while the children get handled by afp_over_{asp,dsi}.  this is
@@ -427,8 +429,9 @@ int main(int ac, char **av)
         }
 
         for (int i = 0; i < fdset_used; i++) {
-            if (fdset[i].revents & POLLIN) {
+            if (fdset[i].revents & (POLLIN | POLLERR | POLLHUP)) {
                 switch (polldata[i].fdtype) {
+
                 case LISTEN_FD:
                     config = (AFPConfig *)polldata[i].data;
                     /* config->server_start is afp_config.c:dsi_start() for DSI */
@@ -437,15 +440,46 @@ int main(int ac, char **av)
                         fdset_add_fd(&fdset, &polldata, &fdset_used, &fdset_size, child->ipc_fds[0], IPC_FD, child);
                     }
                     break;
+
                 case IPC_FD:
                     child = (afp_child_t *)polldata[i].data;
-                    LOG(log_debug, logtype_afpd, "main: IPC request from child[%u]", child->pid);
-                    if ((ret = ipc_server_read(server_children, child->ipc_fds[0])) == 0) {
-                        fdset_del_fd(&fdset, &polldata, &fdset_used, &fdset_size, child->ipc_fds[0]);
-                        close(child->ipc_fds[0]);
-                        child->ipc_fds[0] = -1;
+                    if (fdset[i].revents & POLLIN) {
+                        LOG(log_debug, logtype_afpd, "main: IPC request from child[%u]", child->pid);
+                        if ((ret = ipc_server_read(server_children, child->ipc_fds[0])) == 0) {
+                            fdset_del_fd(&fdset, &polldata, &fdset_used, &fdset_size, child->ipc_fds[0]);
+                            close(child->ipc_fds[0]);
+                            child->ipc_fds[0] = -1;
+                            if (child->disasociated)
+                                server_child_remove(server_children, CHILD_DSIFORK, child->pid);
+                        }
+                    } else {
+                        if (child->disasociated) {
+                            fdset_del_fd(&fdset, &polldata, &fdset_used, &fdset_size, child->ipc_fds[0]);
+                            close(child->ipc_fds[0]);
+                            child->ipc_fds[0] = -1;
+                        }
                     }
                     break;
+
+                case DISASOCIATED_IPC_FD:
+                    LOG(log_note, logtype_afpd, "main: DISASOCIATED_IPC_FD request");
+                    if ((fd[0] = accept(disasociated_ipc_fd, NULL, NULL)) == -1) {
+                        LOG(log_error, logtype_afpd, "main: accept: %s", strerror(errno));
+                        break;
+                    }
+                    if (readt(fd[0], &pid, sizeof(pid_t), 0, 1) != sizeof(pid_t)) {
+                        LOG(log_error, logtype_afpd, "main: readt: %s", strerror(errno));
+                        close(fd[0]);
+                    }
+                    if ((child = server_child_add(server_children, CHILD_DSIFORK, pid, fd)) == NULL) {
+                        LOG(log_error, logtype_afpd, "main: server_child_add");
+                        close(fd[0]);
+                        break;
+                    }
+                    child->disasociated = 1;
+                    fdset_add_fd(&fdset, &polldata, &fdset_used, &fdset_size, fd[0], IPC_FD, child);
+                    break;
+
                 default:
                     LOG(log_debug, logtype_afpd, "main: IPC request for unknown type");
                     break;
index b45a3a42daf088c958618a69a6f350c4ff6653a4..f548ce4d5ab8a0db8a673403d93d268f6de91189 100644 (file)
@@ -27,8 +27,9 @@ typedef struct server_child_data {
   pid_t     pid;               /* afpd worker process pid (from the worker afpd process )*/
   uid_t     uid;               /* user id of connected client (from the worker afpd process) */
   int       valid;             /* 1 if we have a clientid */
-  uint32_t  time;              /* client boot time (from the mac client) */
   int       killed;            /* 1 if we already tried to kill the client */
+  int       disasociated; /* 1 if this is not a child, but a child from a previous afpd master */
+  uint32_t  time;              /* client boot time (from the mac client) */
   uint32_t  idlen;             /* clientid len (from the Mac client) */
   char      *clientid;  /* clientid (from the Mac client) */
   int       ipc_fds[2]; /* socketpair for IPC bw */
index 221ac47af76d50f4a01f777d8e17979207d1d578..ea22c2dca5cb096f5846c351913a82fd15ff0964 100644 (file)
@@ -66,7 +66,7 @@ afp_child_t *dsi_getsession(DSI *dsi, server_child *serv_children, int tickleval
   default: /* parent */
     /* using SIGQUIT is hokey, but the child might not have
      * re-established its signal handler for SIGTERM yet. */
-    if ((child = server_child_add(serv_children, CHILD_DSIFORK, pid, ipc_fds)) < 0) {
+    if ((child = server_child_add(serv_children, CHILD_DSIFORK, pid, ipc_fds)) ==  NULL) {
       LOG(log_error, logtype_dsi, "dsi_getsess: %s", strerror(errno));
       dsi->header.dsi_flags = DSIFL_REPLY;
       dsi->header.dsi_code = DSIERR_SERVBUSY;
index 400b2b4d8eab852ad29d8d6a3ae0e562fc4ee7de..a78826c2920ad9a14c8a906c6689a9598627ba57 100644 (file)
@@ -122,6 +122,7 @@ int ipc_server_uds(const char *name)
     int fd = -1;
 
     EC_NEG1_LOG( fd = socket(PF_UNIX, SOCK_STREAM, 0) );
+    EC_ZERO_LOG( setnonblock(fd, 1) );
     unlink(name);
     address.sun_family = AF_UNIX;
     address_length = sizeof(address.sun_family) + sprintf(address.sun_path, name);