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

Reply via email to