This makes the daemon somewhat more robust, it supports
foreground, background, pidfile, chroot and more.
I also moved the code for closing the handles etc from
the library to the main, feel free to move it back,
but I think this belongs to main.
Signed-off-by: Alon Bar-Lev <[EMAIL PROTECTED]>
---
diff -urNp ecryptfs-utils-26.t1/src/daemon/main.c
ecryptfs-utils-26.t2/src/daemon/main.c
--- ecryptfs-utils-26.t1/src/daemon/main.c 2007-10-13 18:19:01.000000000
+0200
+++ ecryptfs-utils-26.t2/src/daemon/main.c 2007-10-13 18:21:43.000000000
+0200
@@ -27,12 +27,23 @@
#include <stdlib.h>
#include <syslog.h>
#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <sys/resource.h>
#include "../include/ecryptfs.h"
static int ecryptfs_socket = 0;
+static char *pidfile = NULL;
static void ecryptfsd_exit(int retval)
{
+ if (pidfile != NULL) {
+ unlink(pidfile);
+ free(pidfile);
+ pidfile = NULL;
+ }
+
if (!ecryptfs_socket)
goto out;
if (ecryptfs_send_netlink(ecryptfs_socket, NULL,
@@ -47,45 +58,234 @@ out:
exit(retval);
}
+void daemonize()
+{
+ pid_t pid;
+ int fd;
+
+ /* already a daemon */
+ if(getppid() == 1) {
+ return;
+ }
+
+ /*
+ * Initial fork
+ */
+ if ((pid=fork()) == -1) {
+ fprintf(stderr, "Failed to create daemon process: %s\n",
strerror(errno));
+ exit (1);
+ }
+
+ if (pid != 0) {
+ exit (0);
+ }
+
+ /*
+ * Session setup
+ */
+ setsid();
+ umask(027);
+ chdir("/");
+
+ /*
+ * Fork in new session
+ */
+ if ((pid=fork()) == -1) {
+ syslog(LOG_ERR, "Failed to create daemon process: %s\n",
strerror(errno));
+ exit (1);
+ }
+
+ if (pid != 0) {
+ exit (0);
+ }
+
+ /*
+ * Make std handles write to null
+ * Close all others.
+ */
+ if ((fd=open("/dev/null",O_RDWR)) == -1) {
+ syslog(LOG_ERR, "Cannot open /dev/null");
+ exit (1);
+ }
+ dup2(fd, 0);
+ dup2(fd, 1);
+ dup2(fd, 2);
+
+ for (fd=getdtablesize()-1;fd>2;fd--) {
+ close(fd);
+ }
+
+ /*
+ * Ignore major signals
+ */
+ signal(SIGCHLD, SIG_IGN);
+ signal(SIGTSTP, SIG_IGN);
+ signal(SIGTTOU, SIG_IGN);
+ signal(SIGTTIN, SIG_IGN);
+ signal(SIGHUP, SIG_IGN);
+ signal(SIGTERM, SIG_IGN);
+ signal(SIGINT, SIG_IGN);
+}
+
void sigterm_handler(int sig)
{
ecryptfsd_exit(0);
}
+void usage(const char * const me, const struct option * const options, const
char * const short_options)
+{
+ const struct option *opt;
+
+ printf("Usage: %s [options]", me);
+ for (opt = options; opt->name; opt++)
+ {
+ const char *descr = opt->name + strlen(opt->name) + 1;
+ if (strchr(short_options, opt->val))
+ printf("\n -%c, --%s", opt->val, opt->name);
+ else
+ printf("\n --%s", opt->name);
+
+ if (opt->has_arg)
+ printf(" <%s>", opt->name);
+
+ if (strlen(descr))
+ printf("\t%s",descr);
+ }
+
+ printf("\n");
+}
+
int main(int argc, char **argv)
{
- pid_t daemon_pid;
+ static struct option long_options[] = {
+ { "pidfile\0\tSet pid file name", required_argument, NULL, 'p'
},
+ { "foreground\0\t\tDon't fork into background", no_argument,
NULL, 'f' },
+ { "chroot\0\t\tChroot to directory", required_argument, NULL,
'C' },
+ { "version\0\t\t\tShow version information", no_argument, NULL,
'V' },
+ { "help\0\t\t\tShow usage information", no_argument, NULL, 'h'
},
+ { NULL, 0, NULL, 0 }
+ };
+ static char * short_options = "p:f:C:Vh";
+ int long_options_ret;
+ struct rlimit core = { 0, 0 };
+ int foreground = 0;
+ char *chrootdir = NULL;
+ char *tty = NULL;
int rc = 0;
- daemon_pid = fork();
- if (daemon_pid < 0) {
- rc = -errno;
- printf("Failed to create daemon process: %s\n",
strerror(errno));
- } else if (!daemon_pid) {
- if (signal(SIGTERM, sigterm_handler)) {
- rc = -ENOTSUP;
- printf("Failed to attach handler to SIGTERM\n");
- goto daemon_out;
+ while (
+ (long_options_ret = getopt_long (argc, argv, short_options,
long_options, NULL)) != -1
+ ) {
+ switch (long_options_ret) {
+ case 'p':
+ pidfile=strdup(optarg);
+ break;
+ case 'f':
+ foreground=1;
+ break;
+ case 'C':
+ chrootdir=strdup(optarg);
+ break;
+ case 'V':
+ printf(
+ (
+ "%s (%s) %s\n"
+ "\n"
+ "This is free software. You
may redistribute copies of it under the terms of\n"
+ "the GNU General Public License
<http://www.gnu.org/licenses/gpl.html>.\n"
+ "There is NO WARRANTY, to the
extent permitted by law.\n"
+ ),
+ basename(argv[0]),
+ PACKAGE_NAME,
+ PACKAGE_VERSION
+ );
+ break;
+ case 'h':
+ default:
+ usage(basename(argv[0]), long_options,
short_options);
+ exit(1);
+ break;
}
- rc = init_netlink_daemon();
- if (rc) {
- syslog(LOG_ERR, "Error initializing netlink daemon; rc
= [%d]\n", rc);
- goto daemon_out;
- }
- rc = ecryptfs_init_netlink(&ecryptfs_socket);
- if (rc) {
- syslog(LOG_ERR, "Failed to run netlink daemon\n");
+ }
+
+ /*
+ * Store our tty name
+ * we may need it later.
+ */
+ tty = ttyname (0);
+ if (tty != NULL) {
+ setenv ("TERM_DEVICE", tty, 0);
+ }
+
+ if (!foreground) {
+ /*
+ * This will exit if cannot be
+ * completed.
+ */
+ daemonize();
+ }
+
+ /*
+ * We don't wish to have core file
+ * as it may be sensitive.
+ */
+ if (setrlimit (RLIMIT_CORE, &core) == -1) {
+ rc = -errno;
+ syslog(LOG_ERR, "Cannot setrlimit: %s", strerror (errno));
+ goto daemon_out;
+ }
+
+ if (chrootdir != NULL) {
+ if (chroot(chrootdir) == -1) {
+ rc = -errno;
+ syslog(LOG_ERR, "Failed to chroot to '%s': %s",
chrootdir, strerror(errno));
goto daemon_out;
}
- rc = ecryptfs_send_netlink(ecryptfs_socket, NULL,
- ECRYPTFS_NLMSG_HELO, 0, 0);
- if (rc < 0) {
- syslog(LOG_ERR, "Failed to register netlink daemon with
the eCryptfs kernel module\n");
+ free(chrootdir);
+ chrootdir = NULL;
+ }
+
+ if (pidfile != NULL) {
+ FILE *fp = fopen(pidfile, "w");
+ if (fp == NULL) {
+ rc = -errno;
+ syslog(LOG_ERR, "Failed to open pid file '%s': %s",
pidfile, strerror(errno));
goto daemon_out;
}
- rc = ecryptfs_run_netlink_daemon(ecryptfs_socket);
-daemon_out:
- ecryptfsd_exit(rc);
+ fprintf(fp, "%d", (int)getpid());
+ fclose(fp);
}
+
+ if (signal(SIGTERM, sigterm_handler) == SIG_ERR) {
+ rc = -ENOTSUP;
+ syslog(LOG_ERR, "Failed to attach handler to SIGTERM");
+ goto daemon_out;
+ }
+
+ if (signal(SIGINT, sigterm_handler) == SIG_ERR) {
+ rc = -ENOTSUP;
+ syslog(LOG_ERR, "Failed to attach handler to SIGINT");
+ goto daemon_out;
+ }
+
+ rc = init_netlink_daemon();
+ if (rc) {
+ syslog(LOG_ERR, "Error initializing netlink daemon; rc =
[%d]\n", rc);
+ goto daemon_out;
+ }
+ rc = ecryptfs_init_netlink(&ecryptfs_socket);
+ if (rc) {
+ syslog(LOG_ERR, "Failed to run netlink daemon\n");
+ goto daemon_out;
+ }
+ rc = ecryptfs_send_netlink(ecryptfs_socket, NULL,
+ ECRYPTFS_NLMSG_HELO, 0, 0);
+ if (rc < 0) {
+ syslog(LOG_ERR, "Failed to register netlink daemon with the
eCryptfs kernel module\n");
+ goto daemon_out;
+ }
+ rc = ecryptfs_run_netlink_daemon(ecryptfs_socket);
+daemon_out:
+ ecryptfsd_exit(rc);
return rc;
}
diff -urNp ecryptfs-utils-26.base1/src/libecryptfs/netlink.c
ecryptfs-utils-26.prompt/src/libecryptfs/netlink.c
--- ecryptfs-utils-26.base1/src/libecryptfs/netlink.c 2007-10-13
18:23:35.000000000 +0200
+++ ecryptfs-utils-26.prompt/src/libecryptfs/netlink.c 2007-10-13
21:35:15.000000000 +0200
@@ -184,44 +184,6 @@ int init_netlink_daemon(void)
syslog(LOG_INFO, "Starting eCryptfs userspace netlink daemon "
"[%u]\n", getpid());
- setsid();
- null_fd = open("/dev/null", O_RDWR);
- if (null_fd < 0) {
- rc = -errno;
- syslog(LOG_ERR, "Failed to open /dev/null: %s\n",
- strerror(errno));
- goto out;
- }
- if (dup2(null_fd, STDIN_FILENO) < 0) {
- rc = -errno;
- syslog(LOG_ERR, "Failed to dup stdin: %s\n",
- strerror(errno));
- goto out;
- }
- if (dup2(null_fd, STDOUT_FILENO) < 0) {
- rc = -errno;
- syslog(LOG_ERR, "Failed to dup stdout: %s\n",
- strerror(errno));
- goto out;
- }
- if (dup2(null_fd, STDERR_FILENO) < 0) {
- rc = -errno;
- syslog(LOG_ERR, "Failed to dup stderr: %s\n",
- strerror(errno));
- goto out;
- }
- close(null_fd);
- if (chdir("/") < 0) {
- rc = -errno;
- syslog(LOG_ERR, "Failed to change working directory "
- "to '/': %s\n", strerror(errno));
- goto out;
- }
- if (signal(SIGCHLD, SIG_IGN) == SIG_ERR) {
- rc = -ENOTSUP;
- syslog(LOG_ERR, "Failed to ignore SIGCHLD\n");
- goto out;
- }
rc = 0;
out:
return rc;
-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
eCryptfs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ecryptfs-devel