2 * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
3 * All rights reserved. See COPYRIGHT.
14 #include <sys/types.h>
20 #include <atalk/dsi.h>
21 #include <atalk/server_child.h>
23 static server_child *children = NULL;
25 void dsi_kill(int sig)
28 server_child_kill(children, CHILD_DSIFORK, sig);
31 /* hand off the command. return child connection to the main program */
32 DSI *dsi_getsession(DSI *dsi, server_child *serv_children,
37 /* do a couple things on first entry */
39 if (!(children = serv_children))
44 switch (pid = dsi->proto_open(dsi)) {
46 /* if we fail, just return. it might work later */
47 syslog(LOG_ERR, "dsi_getsess: %m");
50 case 0: /* child. mostly handled below. */
55 /* using SIGQUIT is hokey, but the child might not have
56 * re-established its signal handler for SIGTERM yet. */
57 if (server_child_add(children, CHILD_DSIFORK, pid) < 0) {
58 syslog(LOG_ERR, "dsi_getsess: %m");
59 dsi->header.dsi_flags = DSIFL_REPLY;
60 dsi->header.dsi_code = DSIERR_SERVBUSY;
62 dsi->header.dsi_code = DSIERR_OK;
66 dsi->proto_close(dsi);
70 /* child: check number of open connections. this is one off the
72 if ((children->count >= children->nsessions) &&
73 (dsi->header.dsi_command == DSIFUNC_OPEN)) {
74 syslog(LOG_INFO, "dsi_getsess: too many connections");
75 dsi->header.dsi_flags = DSIFL_REPLY;
76 dsi->header.dsi_code = DSIERR_TOOMANY;
81 /* get rid of some stuff */
82 close(dsi->serversock);
83 server_child_free(children);
86 switch (dsi->header.dsi_command) {
87 case DSIFUNC_STAT: /* send off status and return */
89 /* OpenTransport 1.1.2 bug workaround:
91 * OT code doesn't currently handle close sockets well. urk.
92 * the workaround: wait for the client to close its
93 * side. timeouts prevent indefinite resource use.
96 static struct timeval timeout = {120, 0};
102 FD_SET(dsi->socket, &readfds);
104 select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
109 case DSIFUNC_OPEN: /* setup session */
110 /* set up the tickle timer */
111 dsi->timer.it_interval.tv_sec = dsi->timer.it_value.tv_sec = tickleval;
112 dsi->timer.it_interval.tv_usec = dsi->timer.it_value.tv_usec = 0;
113 signal(SIGPIPE, SIG_IGN); /* we catch these ourselves */
114 dsi_opensession(dsi);
118 default: /* just close */
119 syslog(LOG_INFO, "DSIUnknown %d", dsi->header.dsi_command);
120 dsi->proto_close(dsi);