#include <sys/poll.h>
#include <errno.h>
#include <sys/wait.h>
+#include <sys/resource.h>
#include <atalk/adouble.h>
static struct polldata *polldata;
static int fdset_size; /* current allocated size */
static int fdset_used; /* number of used elements */
-
+static int disasociated_ipc_fd; /* disasociated sessions uses this fd for IPC */
#ifdef TRU64
void afp_get_cmdline( int *ac, char ***av)
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);
}
static void fd_reset_listening_sockets(void)
continue;
fdset_del_fd(&fdset, &polldata, &fdset_used, &fdset_size, config->fd);
}
- fd_set_listening_sockets();
+ fdset_del_fd(&fdset, &polldata, &fdset_used, &fdset_size, disasociated_ipc_fd);
}
/* ------------------ */
static void afp_goaway(int sig)
{
+ AFPConfig *config;
#ifndef NO_DDP
asp_kill(sig);
#endif /* ! NO_DDP */
- if (server_children)
- server_child_kill(server_children, CHILD_DSIFORK, sig);
-
switch( sig ) {
case SIGTERM :
LOG(log_note, logtype_afpd, "AFP Server shutting down on SIGTERM");
- AFPConfig *config;
+
+ if (server_children)
+ server_child_kill(server_children, CHILD_DSIFORK, sig);
+
+ for (config = configs; config; config = config->next)
+ if (config->server_cleanup)
+ config->server_cleanup(config);
+ server_unlock(default_options.pidfile);
+ exit(0);
+ break;
+
+ case SIGQUIT:
+ LOG(log_note, logtype_afpd, "AFP Server shutting down on SIGQUIT, NOT disconnecting clients");
+
for (config = configs; config; config = config->next)
if (config->server_cleanup)
config->server_cleanup(config);
+
server_unlock(default_options.pidfile);
exit(0);
break;
nologin++;
auth_unload();
LOG(log_info, logtype_afpd, "disallowing logins");
+
+ if (server_children)
+ server_child_kill(server_children, CHILD_DSIFORK, sig);
break;
case SIGHUP :
}
}
+static int setlimits(void)
+{
+ struct rlimit rlim;
+
+ if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) {
+ LOG(log_error, logtype_afpd, "setlimits: %s", strerror(errno));
+ exit(1);
+ }
+ if (rlim.rlim_cur != RLIM_INFINITY && rlim.rlim_cur < 65535) {
+ rlim.rlim_cur = 65535;
+ if (rlim.rlim_max != RLIM_INFINITY && rlim.rlim_max < 65535)
+ rlim.rlim_max = 65535;
+ if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) {
+ LOG(log_error, logtype_afpd, "setlimits: %s", strerror(errno));
+ exit(1);
+ }
+ }
+ return 0;
+}
+
int main(int ac, char **av)
{
AFPConfig *config;
sigaddset(&sv.sa_mask, SIGHUP);
sigaddset(&sv.sa_mask, SIGTERM);
sigaddset(&sv.sa_mask, SIGUSR1);
-
+ sigaddset(&sv.sa_mask, SIGQUIT);
sv.sa_flags = SA_RESTART;
if ( sigaction( SIGCHLD, &sv, NULL ) < 0 ) {
LOG(log_error, logtype_afpd, "main: sigaction: %s", strerror(errno) );
sigaddset(&sv.sa_mask, SIGTERM);
sigaddset(&sv.sa_mask, SIGHUP);
sigaddset(&sv.sa_mask, SIGCHLD);
+ sigaddset(&sv.sa_mask, SIGQUIT);
sv.sa_flags = SA_RESTART;
if ( sigaction( SIGUSR1, &sv, NULL ) < 0 ) {
LOG(log_error, logtype_afpd, "main: sigaction: %s", strerror(errno) );
sigaddset(&sv.sa_mask, SIGTERM);
sigaddset(&sv.sa_mask, SIGUSR1);
sigaddset(&sv.sa_mask, SIGCHLD);
+ sigaddset(&sv.sa_mask, SIGQUIT);
sv.sa_flags = SA_RESTART;
if ( sigaction( SIGHUP, &sv, NULL ) < 0 ) {
LOG(log_error, logtype_afpd, "main: sigaction: %s", strerror(errno) );
sigaddset(&sv.sa_mask, SIGHUP);
sigaddset(&sv.sa_mask, SIGUSR1);
sigaddset(&sv.sa_mask, SIGCHLD);
+ sigaddset(&sv.sa_mask, SIGQUIT);
sv.sa_flags = SA_RESTART;
if ( sigaction( SIGTERM, &sv, NULL ) < 0 ) {
LOG(log_error, logtype_afpd, "main: sigaction: %s", strerror(errno) );
exit(EXITERR_SYS);
}
+ sigemptyset( &sv.sa_mask );
+ sigaddset(&sv.sa_mask, SIGALRM);
+ sigaddset(&sv.sa_mask, SIGHUP);
+ sigaddset(&sv.sa_mask, SIGUSR1);
+ sigaddset(&sv.sa_mask, SIGCHLD);
+ sigaddset(&sv.sa_mask, SIGTERM);
+ sv.sa_flags = SA_RESTART;
+ if (sigaction(SIGQUIT, &sv, NULL ) < 0 ) {
+ LOG(log_error, logtype_afpd, "main: sigaction: %s", strerror(errno) );
+ exit(EXITERR_SYS);
+ }
+
/* afpd.conf: not in config file: lockfile, connections, configfile
* preference: command-line provides defaults.
* config file over-writes defaults.
cnid_init();
/* watch atp, dsi sockets and ipc parent/child file descriptor. */
+ disasociated_ipc_fd = ipc_server_uds(_PATH_AFP_IPC);
fd_set_listening_sockets();
+ /* set limits */
+ (void)setlimits();
+
afp_child_t *child;
/* wait for an appleshare connection. parent remains in the loop
if (reloadconfig) {
nologin++;
auth_unload();
+ fd_reset_listening_sockets();
LOG(log_info, logtype_afpd, "re-reading configuration file");
for (config = configs; config; config = config->next)
LOG(log_error, logtype_afpd, "config re-read: no servers configured");
exit(EXITERR_CONF);
}
- fd_reset_listening_sockets();
+
+ fd_set_listening_sockets();
+
nologin = 0;
reloadconfig = 0;
errno = saveerrno;
+ continue;
}
if (ret == 0)