]> arthur.barton.de Git - netatalk.git/blobdiff - libatalk/dsi/dsi_getsess.c
Merge master
[netatalk.git] / libatalk / dsi / dsi_getsess.c
index 24ef45db687e72a470ca0b188b92a5a11197625a..5ea32b01a4afb8bccd46dce7ad76a2656a24880e 100644 (file)
@@ -1,87 +1,87 @@
 /*
+ * $Id: dsi_getsess.c,v 1.7 2005-04-28 20:50:02 bfernhomberg Exp $
+ *
  * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
  * All rights reserved. See COPYRIGHT.
  */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
+#endif /* HAVE_CONFIG_H */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <errno.h>
 #include <unistd.h>
-#include <sys/types.h>
 #include <signal.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/time.h>
-#include <syslog.h>
+#include <atalk/logger.h>
+#include <atalk/util.h>
 
 #include <atalk/dsi.h>
 #include <atalk/server_child.h>
 
-static server_child *children = NULL;
-
-void dsi_kill(int sig)
-{
-  if (children)
-    server_child_kill(children, CHILD_DSIFORK, sig);
-}
-
 /* hand off the command. return child connection to the main program */
-DSI *dsi_getsession(DSI *dsi, server_child *serv_children, 
-                   const int tickleval)
+afp_child_t *dsi_getsession(DSI *dsi, server_child *serv_children, int tickleval)
 {
   pid_t pid;
-  
-  /* do a couple things on first entry */
-  if (!dsi->inited) {
-    if (!(children = serv_children))
-      return NULL;
-    dsi->inited = 1;
+  unsigned int ipc_fds[2];  
+  afp_child_t *child;
+
+  if (socketpair(PF_UNIX, SOCK_STREAM, 0, ipc_fds) < 0) {
+      LOG(log_error, logtype_dsi, "dsi_getsess: %s", strerror(errno));
+      exit( EXITERR_CLNT );
   }
-  
-  switch (pid = dsi->proto_open(dsi)) {
+
+  if (setnonblock(ipc_fds[0], 1) != 0 || setnonblock(ipc_fds[1], 1) != 0) {
+      LOG(log_error, logtype_dsi, "dsi_getsess: setnonblock: %s", strerror(errno));
+      exit(EXITERR_CLNT);
+  }
+
+  switch (pid = dsi->proto_open(dsi)) { /* in libatalk/dsi/dsi_tcp.c */
   case -1:
     /* if we fail, just return. it might work later */
-    syslog(LOG_ERR, "dsi_getsess: %m");
-    return dsi;
+    LOG(log_error, logtype_dsi, "dsi_getsess: %s", strerror(errno));
+    return NULL;
 
   case 0: /* child. mostly handled below. */
-    dsi->child = 1;
     break;
 
   default: /* parent */
     /* using SIGQUIT is hokey, but the child might not have
      * re-established its signal handler for SIGTERM yet. */
-    if (server_child_add(children, CHILD_DSIFORK, pid) < 0) {
-      syslog(LOG_ERR, "dsi_getsess: %m");
+    if ((child = server_child_add(serv_children, CHILD_DSIFORK, pid, ipc_fds)) < 0) {
+      LOG(log_error, logtype_dsi, "dsi_getsess: %s", strerror(errno));
       dsi->header.dsi_flags = DSIFL_REPLY;
       dsi->header.dsi_code = DSIERR_SERVBUSY;
       dsi_send(dsi);
       dsi->header.dsi_code = DSIERR_OK;
       kill(pid, SIGQUIT);
     }
-
     dsi->proto_close(dsi);
-    return dsi;
+    return child;
   }
   
   /* child: check number of open connections. this is one off the
    * actual count. */
-  if ((children->count >= children->nsessions) &&
+  if ((serv_children->count >= serv_children->nsessions) &&
       (dsi->header.dsi_command == DSIFUNC_OPEN)) {
-    syslog(LOG_INFO, "dsi_getsess: too many connections");
+    LOG(log_info, logtype_dsi, "dsi_getsess: too many connections");
     dsi->header.dsi_flags = DSIFL_REPLY;
     dsi->header.dsi_code = DSIERR_TOOMANY;
     dsi_send(dsi);
-    exit(1);
+    exit(EXITERR_CLNT);
   }
 
   /* get rid of some stuff */
   close(dsi->serversock);
-  server_child_free(children); 
-  children = NULL;
+  server_child_free(serv_children); 
 
   switch (dsi->header.dsi_command) {
   case DSIFUNC_STAT: /* send off status and return */
@@ -112,12 +112,15 @@ DSI *dsi_getsession(DSI *dsi, server_child *serv_children,
     dsi->timer.it_interval.tv_usec = dsi->timer.it_value.tv_usec = 0;
     signal(SIGPIPE, SIG_IGN); /* we catch these ourselves */
     dsi_opensession(dsi);
-    return dsi;
+    if ((child = calloc(1, sizeof(afp_child_t))) == NULL)
+        exit(EXITERR_SYS);
+    child->ipc_fds[1] = ipc_fds[1];
+    return child;
     break;
 
   default: /* just close */
-    syslog(LOG_INFO, "DSIUnknown %d", dsi->header.dsi_command);
+    LOG(log_info, logtype_dsi, "DSIUnknown %d", dsi->header.dsi_command);
     dsi->proto_close(dsi);
-    exit(1);
+    exit(EXITERR_CLNT);
   }
 }