/* undo.c: * * vim:smartindent ts=8:sts=2:sta:et:ai:shiftwidth=2 **************************************************************** * Copyright (C) 2003 Tom Lord * * See the file "COPYING" for further information about * the copyright and warranty status of this work. */ #include "hackerlab/bugs/exception.h" #include "hackerlab/char/str.h" #include "hackerlab/char/char-class.h" #include "hackerlab/fmt/cvt.h" #include "hackerlab/fs/file-names.h" #include "hackerlab/vu/safe.h" #include "libfsutils/dir-listing.h" #include "libfsutils/rmrf.h" #include "libarch/conflict-handling.h" #include "libarch/make-changeset.h" #include "libarch/make-changeset-files.h" #include "libarch/apply-changeset.h" #include "libarch/chatter.h" #include "libarch/undo.h" /* __STDC__ prototypes for static functions */ void arch_undo (int chatter_fd, t_uchar * dest_dir, int delete_changeset, arch_project_tree_t * tree, arch_project_tree_t * baseline_tree, rel_table file_list, assoc_table inode_shortcut, int forward, int escape_classes) { struct arch_make_changeset_report make_report = {0, }; struct arch_apply_changeset_report * apply_report; arch_apply_changeset_report_callback apply_report_callback = NULL; void * apply_report_thunk = NULL; if (!file_list) arch_make_changeset (&make_report, baseline_tree, tree, dest_dir, arch_unspecified_id_tagging, arch_inventory_unrecognized, 0, inode_shortcut, 0, escape_classes); else arch_make_files_changeset (&make_report, dest_dir, file_list, baseline_tree, tree, arch_unspecified_id_tagging, arch_inventory_unrecognized, escape_classes); arch_chatter (chatter_fd, "* reverting changes\n"); if (chatter_fd >= 0) { apply_report_callback = apply_print_callback; apply_report_thunk = (void *)(long)chatter_fd; } apply_report = arch_apply_changeset (dest_dir, talloc_context, tree, arch_unspecified_id_tagging, arch_inventory_unrecognized, 1, forward, escape_classes, apply_report_callback, apply_report_thunk); if (delete_changeset) rmrf_file (dest_dir); /* FIXME rbc 20050203 FIXME resolve conflicts on the files in file_list * this wants a rel_table taking resolved-specific-files call for ease. */ if (!file_list) arch_tree_clear_conflicts (tree); talloc_free (apply_report); } t_uchar * arch_latest_undo_changeset (t_ulong * level_n, t_uchar * tree_root) { rel_table files = 0; t_uchar * answer = 0; t_ulong latest_n = 0; int x; files = directory_files (tree_root); for (x = 0; x < rel_n_records (files); ++x) { if (!str_cmp_prefix (",,undo-", files[x][0])) { int ign; t_uchar * pos; t_ulong this_n; for (pos = files[x][0] + sizeof (",,undo-") - 1; char_is_digit (*pos); ++pos) ; if (*pos) continue; pos = files[x][0] + sizeof (",,undo-") - 1; if (cvt_decimal_to_ulong (&ign, &this_n, pos, str_length (pos))) continue; if (this_n >= latest_n) { lim_free (0, answer); answer = file_name_in_vicinity (0, tree_root, files[x][0]); if (level_n) *level_n = this_n; latest_n = this_n; } } } rel_free_table (files); return answer; } t_uchar * arch_next_undo_changeset (t_ulong * level_n, t_uchar * tree_root) { t_uchar * prev = 0; t_ulong prev_n; t_uchar * this = 0; t_uchar * answer = 0; prev = arch_latest_undo_changeset (&prev_n, tree_root); if (!prev) { if (level_n) *level_n = 1; this = str_save (0, ",,undo-1"); } else { t_uchar buf[64]; cvt_ulong_to_decimal (buf, prev_n + 1); this = str_alloc_cat (0, ",,undo-", buf); } answer = file_name_in_vicinity (0, tree_root, this); lim_free (0, prev); lim_free (0, this); return answer; } /* tag: Tom Lord Thu May 29 14:20:31 2003 (undo.c) */