+int get_newest_complete(const char *dirname, void *private)
+{
+ struct edge_snapshot_data *esd = private;
+ struct snapshot s;
+ int ret = is_snapshot(dirname, esd->now, &s);
+
+ if (ret <= 0)
+ return 1;
+ if (s.flags != SS_COMPLETE) /* incomplete or being deleted */
+ return 1;
+ if (s.creation_time < esd->snap.creation_time)
+ return 1;
+ free(esd->snap.name);
+ esd->snap = s;
+ return 1;
+}
+
+__malloc char *name_of_newest_complete_snapshot(void)
+{
+ struct edge_snapshot_data esd = {
+ .now = get_current_time(),
+ .snap = {.creation_time = -1}
+ };
+ for_each_subdir(get_newest_complete, &esd);
+ return esd.snap.name;
+}
+
+void create_rsync_argv(char ***argv, int64_t *num)
+{
+ char *logname, *newest = name_of_newest_complete_snapshot();
+ int i = 0, j;
+
+ *argv = dss_malloc((15 + conf.rsync_option_given) * sizeof(char *));
+ (*argv)[i++] = dss_strdup("rsync");
+ (*argv)[i++] = dss_strdup("-aq");
+ (*argv)[i++] = dss_strdup("--delete");
+ for (j = 0; j < conf.rsync_option_given; j++)
+ (*argv)[i++] = dss_strdup(conf.rsync_option_arg[j]);
+ if (newest) {
+ DSS_INFO_LOG("using %s as reference snapshot\n", newest);
+ (*argv)[i++] = make_message("--link-dest=../%s", newest);
+ free(newest);
+ } else
+ DSS_INFO_LOG("no previous snapshot found\n");
+ if (conf.exclude_patterns_given) {
+ (*argv)[i++] = dss_strdup("--exclude-from");
+ (*argv)[i++] = dss_strdup(conf.exclude_patterns_arg);
+
+ }
+ logname = dss_logname();
+ if (conf.remote_user_given && !strcmp(conf.remote_user_arg, logname))
+ (*argv)[i++] = dss_strdup(conf.source_dir_arg);
+ else
+ (*argv)[i++] = make_message("%s@%s:%s/", conf.remote_user_given?
+ conf.remote_user_arg : logname,
+ conf.remote_host_arg, conf.source_dir_arg);
+ free(logname);
+ *num = get_current_time();
+ (*argv)[i++] = incomplete_name(*num);
+ (*argv)[i++] = NULL;
+ for (j = 0; j < i; j++)
+ DSS_DEBUG_LOG("argv[%d] = %s\n", j, (*argv)[j]);
+}
+
+void free_rsync_argv(char **argv)
+{
+ int i;
+ for (i = 0; argv[i]; i++)
+ free(argv[i]);
+ free(argv);
+}
+
+int create_snapshot(char **argv)
+{
+ int fds[3] = {0, 0, 0};
+ char *name = incomplete_name(current_snapshot_creation_time);
+
+ DSS_NOTICE_LOG("creating new snapshot %s\n", name);
+ free(name);
+ return dss_exec(&rsync_pid, argv[0], argv, fds);
+}
+