]> git.tuebingen.mpg.de Git - dss.git/blobdiff - dss.c
Allow word-splitting for exit hook.
[dss.git] / dss.c
diff --git a/dss.c b/dss.c
index d0dab0dc3f688254163d9d138069a48dd77ccd5b..a65967c07e41785c165deffefc69bc02fe80bef3 100644 (file)
--- a/dss.c
+++ b/dss.c
@@ -1055,9 +1055,15 @@ static int handle_sigchld(void)
 
 static int change_to_dest_dir(void)
 {
+       int ret;
        const char *dd = OPT_STRING_VAL(DSS, DEST_DIR);
+
        DSS_INFO_LOG(("changing cwd to %s\n", dd));
-       return dss_chdir(dd);
+       if (chdir(dd) >= 0)
+               return 1;
+       ret = -ERRNO_TO_DSS_ERROR(errno);
+       DSS_ERROR_LOG(("could not change cwd to %s\n", dd));
+       return ret;
 }
 
 static int check_config(const struct lls_command *cmd)
@@ -1341,6 +1347,7 @@ static void create_rsync_argv(char ***argv, int64_t *num)
        char *logname;
        int i = 0, j, N = OPT_GIVEN(DSS, RSYNC_OPTION);
        struct snapshot_list sl;
+       static bool seeded;
 
        dss_get_snapshot_list(&sl);
        assert(!name_of_reference_snapshot);
@@ -1351,6 +1358,14 @@ static void create_rsync_argv(char ***argv, int64_t *num)
        (*argv)[i++] = dss_strdup("rsync");
        (*argv)[i++] = dss_strdup("-a");
        (*argv)[i++] = dss_strdup("--delete");
+       if (!seeded) {
+               srandom((unsigned)time(NULL)); /* no need to be fancy here */
+               seeded = true;
+       }
+       if (1000 * (random() / (RAND_MAX + 1.0)) < OPT_UINT32_VAL(DSS, CHECKSUM)) {
+               DSS_NOTICE_LOG(("adding --checksum to rsync options\n"));
+               (*argv)[i++] = dss_strdup("--checksum");
+       }
        for (j = 0; j < N; j++)
                (*argv)[i++] = dss_strdup(lls_string_val(j,
                        OPT_RESULT(DSS, RSYNC_OPTION)));
@@ -1485,15 +1500,18 @@ out:
 
 static void exit_hook(int exit_code)
 {
-       const char *argv[3];
        pid_t pid;
-
-       argv[0] = OPT_STRING_VAL(DSS, EXIT_HOOK);
-       argv[1] = dss_strerror(-exit_code);
-       argv[2] = NULL;
-
-       DSS_NOTICE_LOG(("executing %s %s\n", argv[0], argv[1]));
-       dss_exec(&pid, argv[0], (char **)argv);
+       char **argv, *tmp = dss_strdup(OPT_STRING_VAL(DSS, EXIT_HOOK));
+       unsigned n = split_args(tmp, &argv, " \t");
+
+       n++;
+       argv = dss_realloc(argv, (n + 1) * sizeof(char *));
+       argv[n - 1] = dss_strdup(dss_strerror(-exit_code));
+       argv[n] = NULL;
+       dss_exec(&pid, argv[0], argv);
+       free(argv[n - 1]);
+       free(argv);
+       free(tmp);
 }
 
 static void lock_dss_or_die(void)
@@ -1510,14 +1528,23 @@ static void lock_dss_or_die(void)
 
 static int com_run(void)
 {
-       int ret;
+       int ret, fd = -1;
+       char *config_file;
+       pid_t pid;
 
        if (OPT_GIVEN(DSS, DRY_RUN)) {
                DSS_ERROR_LOG(("dry run not supported by this command\n"));
                return -E_SYNTAX;
        }
+       config_file = get_config_file_name();
+       ret = get_dss_pid(config_file, &pid);
+       free(config_file);
+       if (ret >= 0) {
+               DSS_ERROR_LOG(("pid %d\n", (int)pid));
+               return -E_ALREADY_RUNNING;
+       }
        if (OPT_GIVEN(RUN, DAEMON)) {
-               daemon_init();
+               fd = daemon_init();
                daemonized = true;
                logfile = open_log(OPT_STRING_VAL(RUN, LOGFILE));
        }
@@ -1526,6 +1553,16 @@ static int com_run(void)
        ret = install_sighandler(SIGHUP);
        if (ret < 0)
                return ret;
+       if (fd >= 0) {
+               ret = write(fd, "\0", 1);
+               if (ret != 1) {
+                       DSS_ERROR_LOG(("write to daemon pipe returned %d\n",
+                               ret));
+                       if (ret < 0)
+                               return -ERRNO_TO_DSS_ERROR(errno);
+                       return -E_BUG;
+               }
+       }
        ret = select_loop();
        if (ret >= 0) /* impossible */
                ret = -E_BUG;