X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libatalk%2Fdsi%2Fdsi_getsess.c;h=a928d34ee38d8f23f9fd34350198d00fffc91e75;hb=e450b7b95579a4a4358e499fdbf93620aa09bae2;hp=747a880a6442c247299a0e7d85643c8106eff448;hpb=8ae15a83dc6c7a0251a8357d43481b833f9a1e63;p=netatalk.git diff --git a/libatalk/dsi/dsi_getsess.c b/libatalk/dsi/dsi_getsess.c index 747a880a..a928d34e 100644 --- a/libatalk/dsi/dsi_getsess.c +++ b/libatalk/dsi/dsi_getsess.c @@ -1,5 +1,4 @@ /* - * $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. @@ -18,18 +17,8 @@ #include #include -/* POSIX.1 sys/wait.h check */ #include -#ifdef HAVE_SYS_WAIT_H #include -#endif /* HAVE_SYS_WAIT_H */ -#ifndef WEXITSTATUS -#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) -#endif /* ! WEXITSTATUS */ -#ifndef WIFEXITED -#define WIFEXITED(stat_val) (((stat_val) & 255) == 0) -#endif /* ! WIFEXITED */ - #include #include #include @@ -37,60 +26,71 @@ #include #include -/* hand off the command. return child connection to the main program */ -afp_child_t *dsi_getsession(DSI *dsi, server_child *serv_children, int tickleval) +/*! + * Start a DSI session, fork an afpd process + * + * @param childp (w) after fork: parent return pointer to child, child returns NULL + * @returns 0 on sucess, any other value denotes failure + */ +int dsi_getsession(DSI *dsi, server_child_t *serv_children, int tickleval, afp_child_t **childp) { pid_t pid; - unsigned int ipc_fds[2]; + int ipc_fds[2]; afp_child_t *child; if (socketpair(PF_UNIX, SOCK_STREAM, 0, ipc_fds) < 0) { - LOG(log_error, logtype_afpd, "dsi_getsess: %s", strerror(errno)); - exit( EXITERR_CLNT ); + LOG(log_error, logtype_dsi, "dsi_getsess: %s", strerror(errno)); + return -1; } if (setnonblock(ipc_fds[0], 1) != 0 || setnonblock(ipc_fds[1], 1) != 0) { - LOG(log_error, logtype_afpd, "dsi_getsess: setnonblock: %s", strerror(errno)); - exit(EXITERR_CLNT); + LOG(log_error, logtype_dsi, "dsi_getsess: setnonblock: %s", strerror(errno)); + return -1; } switch (pid = dsi->proto_open(dsi)) { /* in libatalk/dsi/dsi_tcp.c */ case -1: /* if we fail, just return. it might work later */ LOG(log_error, logtype_dsi, "dsi_getsess: %s", strerror(errno)); - return NULL; + return -1; case 0: /* child. mostly handled below. */ break; default: /* parent */ - /* using SIGQUIT is hokey, but the child might not have + /* using SIGKILL 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) { + close(ipc_fds[1]); + if ((child = server_child_add(serv_children, pid, ipc_fds[0])) == NULL) { LOG(log_error, logtype_dsi, "dsi_getsess: %s", strerror(errno)); + close(ipc_fds[0]); dsi->header.dsi_flags = DSIFL_REPLY; - dsi->header.dsi_code = DSIERR_SERVBUSY; + dsi->header.dsi_data.dsi_code = DSIERR_SERVBUSY; dsi_send(dsi); - dsi->header.dsi_code = DSIERR_OK; - kill(pid, SIGQUIT); + dsi->header.dsi_data.dsi_code = DSIERR_OK; + kill(pid, SIGKILL); } dsi->proto_close(dsi); - return child; + *childp = child; + return 0; } /* child: check number of open connections. this is one off the * actual count. */ - if ((serv_children->count >= serv_children->nsessions) && + if ((serv_children->servch_count >= serv_children->servch_nsessions) && (dsi->header.dsi_command == DSIFUNC_OPEN)) { LOG(log_info, logtype_dsi, "dsi_getsess: too many connections"); dsi->header.dsi_flags = DSIFL_REPLY; - dsi->header.dsi_code = DSIERR_TOOMANY; + dsi->header.dsi_data.dsi_code = DSIERR_TOOMANY; dsi_send(dsi); exit(EXITERR_CLNT); } /* get rid of some stuff */ + dsi->AFPobj->ipc_fd = ipc_fds[1]; + close(ipc_fds[0]); close(dsi->serversock); + dsi->serversock = -1; server_child_free(serv_children); switch (dsi->header.dsi_command) { @@ -120,13 +120,9 @@ afp_child_t *dsi_getsession(DSI *dsi, server_child *serv_children, int tickleval /* set up the tickle timer */ dsi->timer.it_interval.tv_sec = dsi->timer.it_value.tv_sec = tickleval; dsi->timer.it_interval.tv_usec = dsi->timer.it_value.tv_usec = 0; - signal(SIGPIPE, SIG_IGN); /* we catch these ourselves */ dsi_opensession(dsi); - if ((child = calloc(1, sizeof(afp_child_t))) == NULL) - exit(EXITERR_SYS); - child->ipc_fds[1] = ipc_fds[1]; - return child; - break; + *childp = NULL; + return 0; default: /* just close */ LOG(log_info, logtype_dsi, "DSIUnknown %d", dsi->header.dsi_command);