+void compute_next_snapshot_time(struct snapshot_list *sl)
+{
+ struct timeval now, unit_interval = {.tv_sec = 24 * 3600 * conf.unit_interval_arg},
+ tmp, diff;
+ int64_t x = 0;
+ unsigned wanted = num_snapshots(0), num_complete_snapshots = 0;
+ int i, ret;
+ struct snapshot *s;
+
+ gettimeofday(&now, NULL);
+ FOR_EACH_SNAPSHOT(s, i, sl) {
+ if (!(s->flags & SS_COMPLETE))
+ continue;
+ num_complete_snapshots++;
+ x += s->completion_time - s->creation_time;
+ }
+ assert(x >= 0);
+ if (num_complete_snapshots)
+ x /= num_complete_snapshots; /* avg time to create one snapshot */
+ x *= wanted; /* time to create all snapshots in interval 0 */
+ tmp.tv_sec = x;
+ tmp.tv_usec = 0;
+ ret = tv_diff(&unit_interval, &tmp, &diff); /* time between creation */
+ if (ret < 0) {
+ next_snapshot_time = now;
+ return;
+ }
+ tv_divide(wanted, &diff, &tmp);
+ tv_add(&now, &tmp, &next_snapshot_time);
+}
+
+void handle_signal(struct snapshot_list *sl)
+{
+ int sig, ret = next_signal();
+
+ if (ret <= 0)
+ goto out;
+ sig = ret;
+ switch (sig) {
+ int status;
+ pid_t pid;
+ case SIGINT:
+ case SIGTERM:
+ restart_rsync_process();
+ kill_process(rsync_pid);
+ kill_process(rm_pid);
+ exit(EXIT_FAILURE);
+ case SIGHUP:
+ handle_sighup();
+ break;
+ case SIGCHLD:
+ ret = reap_child(&pid, &status);
+ if (ret <= 0)
+ break;
+ assert(pid == rsync_pid || pid == rm_pid);
+ if (pid == rsync_pid)
+ ret = handle_rsync_exit(status);
+ else
+ ret = handle_rm_exit(status);
+ free_snapshot_list(sl);
+ get_snapshot_list(sl);
+ compute_next_snapshot_time(sl);
+ }
+out:
+ if (ret < 0)
+ log_err_msg(ERROR, -ret);
+}
+
+int get_oldest(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.creation_time > esd->snap.creation_time)
+ return 1;
+ free(esd->snap.name);
+ esd->snap = s;
+ return 1;
+}
+
+int remove_oldest_snapshot()