Index: Makefile =================================================================== RCS file: /home/ncvs/ports/net/netatalk/Makefile,v retrieving revision 1.101 diff -u -r1.101 Makefile --- Makefile 14 Aug 2011 17:17:28 -0000 1.101 +++ Makefile 19 Aug 2011 21:51:38 -0000 @@ -7,7 +7,7 @@ PORTNAME= netatalk PORTVERSION= 2.2.0 -PORTREVISION= 3 +PORTREVISION= 4 PORTEPOCH= 1 CATEGORIES= net print MASTER_SITES= SF/netatalk/netatalk/2.2 Index: files/patch-etc__afpd__afp_options.c =================================================================== RCS file: files/patch-etc__afpd__afp_options.c diff -N files/patch-etc__afpd__afp_options.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ files/patch-etc__afpd__afp_options.c 19 Aug 2011 21:44:02 -0000 @@ -0,0 +1,13 @@ +--- ./etc/afpd/afp_options.c.orig 2011-07-27 04:55:39.000000000 -0700 ++++ ./etc/afpd/afp_options.c 2011-08-19 14:43:45.034785568 -0700 +@@ -240,6 +240,10 @@ + options->flags |= OPTION_ANNOUNCESSH; + if (strstr(buf, " -noacl2maccess")) + options->flags &= ~OPTION_ACL2MACCESS; ++ if (strstr(buf, " -keepsessions")) { ++ default_options.flags |= OPTION_KEEPSESSIONS; ++ options->flags |= OPTION_KEEPSESSIONS; ++ } + + /* passwd bits */ + if (strstr(buf, " -nosavepassword")) Index: files/patch-etc__afpd__main.c =================================================================== RCS file: files/patch-etc__afpd__main.c diff -N files/patch-etc__afpd__main.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ files/patch-etc__afpd__main.c 19 Aug 2011 21:44:02 -0000 @@ -0,0 +1,139 @@ +--- ./etc/afpd/main.c.orig 2011-07-27 04:55:39.000000000 -0700 ++++ ./etc/afpd/main.c 2011-08-19 14:43:45.042815401 -0700 +@@ -52,11 +52,11 @@ + #endif /* TRU64 */ + + unsigned char nologin = 0; +- + struct afp_options default_options; + static AFPConfig *configs; + static server_child *server_children; + static sig_atomic_t reloadconfig = 0; ++static sig_atomic_t gotsigchld = 0; + + /* Two pointers to dynamic allocated arrays which store pollfds and associated data */ + static struct pollfd *fdset; +@@ -94,7 +94,11 @@ + continue; + fdset_add_fd(&fdset, &polldata, &fdset_used, &fdset_size, config->fd, LISTEN_FD, config); + } +- fdset_add_fd(&fdset, &polldata, &fdset_used, &fdset_size, disasociated_ipc_fd, DISASOCIATED_IPC_FD, NULL); ++ ++ if (default_options.flags & OPTION_KEEPSESSIONS) { ++ LOG(log_note, logtype_afpd, "Activating continous service"); ++ fdset_add_fd(&fdset, &polldata, &fdset_used, &fdset_size, disasociated_ipc_fd, DISASOCIATED_IPC_FD, NULL); ++ } + } + + static void fd_reset_listening_sockets(void) +@@ -106,7 +110,9 @@ + continue; + fdset_del_fd(&fdset, &polldata, &fdset_used, &fdset_size, config->fd); + } +- fdset_del_fd(&fdset, &polldata, &fdset_used, &fdset_size, disasociated_ipc_fd); ++ ++ if (default_options.flags & OPTION_KEEPSESSIONS) ++ fdset_del_fd(&fdset, &polldata, &fdset_used, &fdset_size, disasociated_ipc_fd); + } + + /* ------------------ */ +@@ -127,7 +133,12 @@ + LOG(log_note, logtype_afpd, "AFP Server shutting down on SIGTERM"); + break; + case SIGQUIT: +- LOG(log_note, logtype_afpd, "AFP Server shutting down on SIGQUIT, NOT disconnecting clients"); ++ if (default_options.flags & OPTION_KEEPSESSIONS) { ++ LOG(log_note, logtype_afpd, "AFP Server shutting down on SIGQUIT, NOT disconnecting clients"); ++ } else { ++ LOG(log_note, logtype_afpd, "AFP Server shutting down on SIGQUIT"); ++ sig = SIGTERM; ++ } + break; + } + if (server_children) +@@ -154,13 +165,18 @@ + reloadconfig = 1; + break; + ++ case SIGCHLD: ++ /* w/ a configuration file, we can force a re-read if we want */ ++ gotsigchld = 1; ++ break; ++ + default : + LOG(log_error, logtype_afpd, "afp_goaway: bad signal" ); + } + return; + } + +-static void child_handler(int sig _U_) ++static void child_handler(void) + { + int fd; + int status, i; +@@ -273,7 +289,8 @@ + } + #endif + +- sv.sa_handler = child_handler; ++ sv.sa_handler = afp_goaway; /* handler for all sigs */ ++ + sigemptyset( &sv.sa_mask ); + sigaddset(&sv.sa_mask, SIGALRM); + sigaddset(&sv.sa_mask, SIGHUP); +@@ -286,7 +303,6 @@ + exit(EXITERR_SYS); + } + +- sv.sa_handler = afp_goaway; + sigemptyset( &sv.sa_mask ); + sigaddset(&sv.sa_mask, SIGALRM); + sigaddset(&sv.sa_mask, SIGTERM); +@@ -374,6 +390,7 @@ + afp_child_t *child; + int fd[2]; /* we only use one, but server_child_add expects [2] */ + pid_t pid; ++ int saveerrno; + + /* wait for an appleshare connection. parent remains in the loop + * while the children get handled by afp_over_{asp,dsi}. this is +@@ -386,7 +403,13 @@ + pthread_sigmask(SIG_UNBLOCK, &sigs, NULL); + ret = poll(fdset, fdset_used, -1); + pthread_sigmask(SIG_BLOCK, &sigs, NULL); +- int saveerrno = errno; ++ saveerrno = errno; ++ ++ if (gotsigchld) { ++ gotsigchld = 0; ++ child_handler(); ++ continue; ++ } + + if (reloadconfig) { + nologin++; +@@ -441,11 +464,11 @@ + 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) { ++ if (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) { ++ if ((default_options.flags & OPTION_KEEPSESSIONS) && child->disasociated) { + LOG(log_note, logtype_afpd, "main: removing reattached child[%u]", child->pid); + server_child_remove(server_children, CHILD_DSIFORK, child->pid); + } +@@ -461,8 +484,9 @@ + 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]); ++ break; + } +- LOG(log_note, logtype_afpd, "main: IPC reconnect from [%u]", pid); ++ LOG(log_note, logtype_afpd, "main: IPC reconnect from pid [%u]", pid); + if ((child = server_child_add(server_children, CHILD_DSIFORK, pid, fd)) == NULL) { + LOG(log_error, logtype_afpd, "main: server_child_add"); + close(fd[0]); Index: files/patch-include__atalk__globals.h =================================================================== RCS file: files/patch-include__atalk__globals.h diff -N files/patch-include__atalk__globals.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ files/patch-include__atalk__globals.h 19 Aug 2011 21:44:02 -0000 @@ -0,0 +1,39 @@ +--- ./include/atalk/globals.h.orig 2011-07-27 04:55:39.000000000 -0700 ++++ ./include/atalk/globals.h 2011-08-19 14:43:45.046204676 -0700 +@@ -43,6 +43,7 @@ + #define OPTION_UUID (1 << 7) + #define OPTION_ACL2MACCESS (1 << 8) + #define OPTION_NOZEROCONF (1 << 9) ++#define OPTION_KEEPSESSIONS (1 << 10) /* preserve sessions across master afpd restart with SIGQUIT */ + + #ifdef FORCE_UIDGID + /* set up a structure for this */ +@@ -127,18 +128,16 @@ + /* typedef for AFP functions handlers */ + typedef int (*AFPCmd)(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *rbuflen); + +-/* afp_dsi.c */ +-extern AFPObj *AFPobj; +- +-extern int afp_version; +-extern int afp_errno; +-extern unsigned char nologin; +-extern struct dir *curdir; +-extern char getwdbuf[]; +- +-/* FIXME CNID */ +-extern const char *Cnid_srv; +-extern const char *Cnid_port; ++/* Global variables */ ++extern AFPObj *AFPobj; ++extern int afp_version; ++extern int afp_errno; ++extern unsigned char nologin; ++extern struct dir *curdir; ++extern char getwdbuf[]; ++extern struct afp_options default_options; ++extern const char *Cnid_srv; ++extern const char *Cnid_port; + + extern int get_afp_errno (const int param); + extern void afp_options_init (struct afp_options *); Index: files/patch-libatalk__util__server_child.c =================================================================== RCS file: files/patch-libatalk__util__server_child.c diff -N files/patch-libatalk__util__server_child.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ files/patch-libatalk__util__server_child.c 19 Aug 2011 21:44:02 -0000 @@ -0,0 +1,14 @@ +--- ./libatalk/util/server_child.c.orig 2011-07-27 04:55:39.000000000 -0700 ++++ ./libatalk/util/server_child.c 2011-08-19 14:42:28.704028827 -0700 +@@ -135,8 +135,10 @@ + + /* it's possible that the child could have already died before the + * pthread_sigmask. we need to check for this. */ +- if (kill(pid, 0) < 0) ++ if (kill(pid, 0) < 0) { ++ LOG(log_error, logtype_default, "server_child_add: no such process pid [%d]", pid); + goto exit; ++ } + + fork = (server_child_fork *) children->fork + forkid; + Index: files/patch-libatalk__util__server_ipc.c =================================================================== RCS file: files/patch-libatalk__util__server_ipc.c diff -N files/patch-libatalk__util__server_ipc.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ files/patch-libatalk__util__server_ipc.c 19 Aug 2011 21:44:02 -0000 @@ -0,0 +1,61 @@ +--- ./libatalk/util/server_ipc.c.orig 2011-07-27 04:55:39.000000000 -0700 ++++ ./libatalk/util/server_ipc.c 2011-08-19 14:42:28.728518099 -0700 +@@ -214,21 +214,27 @@ + /*! + * Read a IPC message from a child + * ++ * This is using an fd with non-blocking IO, so EAGAIN is not an error ++ * + * @args children (rw) pointer to our structure with all childs + * @args fd (r) IPC socket with child + * +- * @returns number of bytes transfered, -1 on error, 0 on EOF ++ * @returns -1 on error, 0 on success + */ + int ipc_server_read(server_child *children, int fd) + { +- int ret = 0; ++ int ret; + struct ipc_header ipc; + char buf[IPC_MAXMSGSIZE], *p; + + if ((ret = read(fd, buf, IPC_HEADERLEN)) != IPC_HEADERLEN) { +- LOG(log_error, logtype_afpd, "Reading IPC header failed (%i of %u bytes read): %s", +- ret, IPC_HEADERLEN, strerror(errno)); +- return ret; ++ if (ret != 0) { ++ if (errno == EAGAIN) ++ return 0; ++ LOG(log_error, logtype_afpd, "Reading IPC header failed (%i of %u bytes read): %s", ++ ret, IPC_HEADERLEN, strerror(errno)); ++ } ++ return -1; + } + + p = buf; +@@ -255,7 +261,7 @@ + if ((ret = read(fd, buf, ipc.len)) != (int) ipc.len) { + LOG(log_info, logtype_afpd, "Reading IPC message failed (%u of %u bytes read): %s", + ret, ipc.len, strerror(errno)); +- return ret; ++ return -1; + } + } + ipc.msg = buf; +@@ -271,6 +277,7 @@ + if (readt(fd, &ipc.DSI_requestID, 2, 0, 2) != 2) { + LOG (log_error, logtype_afpd, "ipc_read(%s:child[%u]): couldnt read DSI id: %s", + ipc_cmd_str[ipc.command], ipc.child_pid, strerror(errno)); ++ return -1; + } + if ((ipc.afp_socket = recv_fd(fd, 1)) == -1) { + LOG (log_error, logtype_afpd, "ipc_read(%s:child[%u]): recv_fd: %s", +@@ -296,7 +303,7 @@ + return -1; + } + +- return ret; ++ return 0; + } + + /* ----------------- */