set_auth_parameters( ac, av );
#endif /* TRU64 */
+ /* Parse argv args and initialize default options */
+ afp_options_init(&default_options);
+ if (!afp_options_parse(ac, av, &default_options))
+ exit(EXITERR_CONF);
+
+ if (!(default_options.flags & OPTION_DEBUG) && (daemonize(0, 0) != 0))
+ exit(EXITERR_SYS);
+
+ switch(check_lockfile("afpd", default_options.pidfile)) {
+ case 0:
+ break;
+ default:
+ exit(EXITERR_SYS);
+ }
+
/* Log SIGBUS/SIGSEGV SBT */
fault_setup(NULL);
set_processname("afpd");
setuplog("default log_note");
- afp_options_init(&default_options);
- if (!afp_options_parse(ac, av, &default_options))
- exit(EXITERR_CONF);
-
- /* Save the user's current umask for use with CNID (and maybe some
- * other things, too). */
+ /* Save the user's current umask */
default_options.save_mask = umask( default_options.umask );
- switch(server_lock("afpd", default_options.pidfile,
- default_options.flags & OPTION_DEBUG)) {
- case -1: /* error */
- exit(EXITERR_SYS);
- case 0: /* child */
- break;
- default: /* server */
- exit(0);
- }
atexit(afp_exit);
/* install child handler for asp and dsi. we do this before afp_goaway
}
}
+ if (!debug && daemonize(0, 0) != 0)
+ exit(EXITERR_SYS);
+
+ /* Check PID lockfile and become a daemon */
+ switch(check_lockfile("cnid_metad", _PATH_CNID_METAD_LOCK)) {
+ case 0:
+ break;
+ default:
+ exit(EXITERR_SYS);
+ }
+
if (loglevel) {
strlcpy(logconfig + 8, loglevel, 13);
free(loglevel);
(void)setlimits();
- /* Check PID lockfile and become a daemon */
- switch(server_lock("cnid_metad", _PATH_CNID_METAD_LOCK, debug)) {
- case -1: /* error */
- daemon_exit(EXITERR_SYS);
- case 0: /* child */
- break;
- default: /* server */
- exit(0);
- }
-
if ((srvfd = tsockfd_create(host, port, 10)) < 0)
daemon_exit(1);
extern int strdiacasecmp (const char *, const char *);
extern int strndiacasecmp (const char *, const char *, size_t);
extern pid_t server_lock (char * /*program*/, char * /*file*/, int /*debug*/);
+extern int check_lockfile (const char *program, const char *pidfile);
extern void fault_setup (void (*fn)(void *));
extern void netatalk_panic(const char *why);
#define server_unlock(x) (unlink(x))
extern char *stripped_slashes_basename(char *p);
extern int lchdir(const char *dir);
extern void randombytes(void *buf, int n);
+extern int daemonize(int nochdir, int noclose);
/******************************************************************
* cnid.c
return 0;
}
+/*!
+ * Check and write lockfile
+ */
+int check_lockfile(const char *program, const char *pidfile)
+{
+ char buf[10];
+ FILE *pf;
+ pid_t pid;
+ int mask;
+
+ /* check for pid. this can get fooled by stale pid's. */
+ if ((pf = fopen(pidfile, "r"))) {
+ if (fgets(buf, sizeof(buf), pf) && !kill(pid = atol(buf), 0)) {
+ fprintf(stderr, "%s is already running (pid = %d), or the lock file is stale.\n",
+ program, pid);
+ fclose(pf);
+ return -1;
+ }
+ fclose(pf);
+ }
+
+ /* Write PID to pidfile */
+ mask = umask(022);
+ if ((pf = fopen(pidfile, "w")) == NULL) {
+ fprintf(stderr, "%s: can't open lock file, \"%s\"\n", program,
+ pidfile);
+ return -1;
+ }
+ umask(mask);
+ fprintf(pf, "%d\n", getpid());
+ fclose(pf);
+
+ return 0;
+}
#include <atalk/util.h>
#include <atalk/unix.h>
+/* close all FDs >= a specified value */
+static void closeall(int fd)
+{
+ int fdlimit = sysconf(_SC_OPEN_MAX);
+
+ while (fd < fdlimit)
+ close(fd++);
+}
+
+/*!
+ * Daemonize
+ *
+ * Fork, exit parent, setsid(), optionally chdir("/"), optionally close all fds
+ *
+ * returns -1 on failure, but you can't do much except exit in that case
+ * since we may already have forked
+ */
+int daemonize(int nochdir, int noclose)
+{
+ switch (fork()) {
+ case 0:
+ break;
+ case -1:
+ return -1;
+ default:
+ _exit(0);
+ }
+
+ if (setsid() < 0)
+ return -1;
+
+ switch (fork()) {
+ case 0:
+ break;
+ case -1:
+ return -1;
+ default:
+ _exit(0);
+ }
+
+ if (!nochdir)
+ chdir("/");
+
+ if (!noclose) {
+ closeall(0);
+ open("/dev/null",O_RDWR);
+ dup(0);
+ dup(0);
+ }
+
+ return 0;
+}
+
/*!
* @brief get cwd in static buffer
*