2
* $Id: main.c,v 1.20.2.1 2003/11/05 06:41:01 didg Exp $
4
* Copyright (c) 1990,1993 Regents of The University of Michigan.
5
* All Rights Reserved. See COPYRIGHT.
10
#endif /* HAVE_CONFIG_H */
17
#endif /* HAVE_UNISTD_H */
20
#endif /* HAVE_FCNTL_H */
23
#include <sys/types.h>
25
#include <sys/param.h>
27
#include <atalk/logger.h>
29
#include <sys/socket.h>
33
#include <netatalk/endian.h>
34
#include <netatalk/at.h>
35
#include <atalk/compat.h>
36
#include <atalk/dsi.h>
37
#include <atalk/atp.h>
38
#include <atalk/asp.h>
39
#include <atalk/afp.h>
40
#include <atalk/adouble.h>
41
#include <atalk/paths.h>
42
#include <atalk/util.h>
43
#include <atalk/server_child.h>
46
#include "afp_config.h"
52
#include <sys/security.h>
57
static char **argv = NULL;
60
unsigned char nologin = 0;
62
struct afp_options default_options;
63
static AFPConfig *configs;
64
static server_child *server_children;
65
static fd_set save_rfds;
68
void afp_get_cmdline( int *ac, char ***av)
75
static void afp_exit(const int i)
77
server_unlock(default_options.pidfile);
81
static void afp_goaway(int sig)
89
LOG(log_info, logtype_afpd, "shutting down on signal %d", sig );
92
/* w/ a configuration file, we can force a re-read if we want */
94
if ((nologin + 1) & 1) {
97
LOG(log_info, logtype_afpd, "re-reading configuration file");
98
for (config = configs; config; config = config->next)
99
if (config->server_cleanup)
100
config->server_cleanup(config);
102
configfree(configs, NULL);
103
if (!(configs = configinit(&default_options))) {
104
LOG(log_error, logtype_afpd, "config re-read: no servers configured");
108
for (config = configs; config; config = config->next) {
111
FD_SET(config->fd, &save_rfds);
114
LOG(log_info, logtype_afpd, "disallowing logins");
119
LOG(log_error, logtype_afpd, "afp_goaway: bad signal" );
121
if ( sig == SIGTERM ) {
124
for (config = configs; config; config = config->next)
125
if (config->server_cleanup)
126
config->server_cleanup(config);
133
static void child_handler()
135
server_child_handler(server_children);
151
set_auth_parameters( ac, av );
154
afp_options_init(&default_options);
155
if (!afp_options_parse(ac, av, &default_options))
158
/* Save the user's current umask for use with CNID (and maybe some
159
* other things, too). */
160
default_options.save_mask = umask( default_options.umask );
162
switch(server_lock("afpd", default_options.pidfile,
163
default_options.flags & OPTION_DEBUG)) {
168
default: /* server */
172
/* install child handler for asp and dsi. we do this before afp_goaway
173
* as afp_goaway references stuff from here.
174
* XXX: this should really be setup after the initial connections. */
175
if (!(server_children = server_child_alloc(default_options.connections,
177
LOG(log_error, logtype_afpd, "main: server_child alloc: %s", strerror(errno) );
181
memset(&sv, 0, sizeof(sv));
182
sv.sa_handler = child_handler;
183
sigemptyset( &sv.sa_mask );
184
sigaddset(&sv.sa_mask, SIGALRM);
185
sigaddset(&sv.sa_mask, SIGHUP);
186
sigaddset(&sv.sa_mask, SIGTERM);
187
sv.sa_flags = SA_RESTART;
188
if ( sigaction( SIGCHLD, &sv, 0 ) < 0 ) {
189
LOG(log_error, logtype_afpd, "main: sigaction: %s", strerror(errno) );
193
sv.sa_handler = afp_goaway;
194
sigemptyset( &sv.sa_mask );
195
sigaddset(&sv.sa_mask, SIGALRM);
196
sigaddset(&sv.sa_mask, SIGTERM);
197
sigaddset(&sv.sa_mask, SIGCHLD);
198
sv.sa_flags = SA_RESTART;
199
if ( sigaction( SIGHUP, &sv, 0 ) < 0 ) {
200
LOG(log_error, logtype_afpd, "main: sigaction: %s", strerror(errno) );
204
sigemptyset( &sv.sa_mask );
205
sigaddset(&sv.sa_mask, SIGALRM);
206
sigaddset(&sv.sa_mask, SIGHUP);
207
sigaddset(&sv.sa_mask, SIGCHLD);
208
sv.sa_flags = SA_RESTART;
209
if ( sigaction( SIGTERM, &sv, 0 ) < 0 ) {
210
LOG(log_error, logtype_afpd, "main: sigaction: %s", strerror(errno) );
214
/* afpd.conf: not in config file: lockfile, connections, configfile
215
* preference: command-line provides defaults.
216
* config file over-writes defaults.
218
* we also need to make sure that killing afpd during startup
219
* won't leave any lingering registered names around.
223
sigaddset(&sigs, SIGALRM);
224
sigaddset(&sigs, SIGHUP);
226
/* don't block SIGTERM */
227
sigaddset(&sigs, SIGTERM);
229
sigaddset(&sigs, SIGCHLD);
230
sigprocmask(SIG_BLOCK, &sigs, NULL);
231
if (!(configs = configinit(&default_options))) {
232
LOG(log_error, logtype_afpd, "main: no servers configured: %s\n", strerror(errno));
235
sigprocmask(SIG_UNBLOCK, &sigs, NULL);
237
/* watch atp and dsi sockets. */
239
for (config = configs; config; config = config->next) {
240
if (config->fd < 0) /* for proxies */
242
FD_SET(config->fd, &save_rfds);
245
/* wait for an appleshare connection. parent remains in the loop
246
* while the children get handled by afp_over_{asp,dsi}. this is
247
* currently vulnerable to a denial-of-service attack if a
248
* connection is made without an actual login attempt being made
249
* afterwards. establishing timeouts for logins is a possible
253
sigprocmask(SIG_UNBLOCK, &sigs, NULL);
254
ret = select(FD_SETSIZE, &rfds, NULL, NULL, NULL);
255
sigprocmask(SIG_BLOCK, &sigs, NULL);
259
LOG(log_error, logtype_afpd, "main: can't wait for input: %s", strerror(errno));
263
for (config = configs; config; config = config->next) {
266
if (FD_ISSET(config->fd, &rfds))
267
config->server_start(config, configs, server_children);