/* archive-snapshot.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/os/errno.h" #include "hackerlab/os/errno-to-string.h" #include "hackerlab/char/str.h" #include "hackerlab/fs/file-names.h" #include "hackerlab/vu/safe.h" #include "libfsutils/ensure-dir.h" #include "libfsutils/tmp-files.h" #include "libawk/relational.h" #include "libarch/archive.h" #include "libarch/namespace.h" #include "libarch/archive-snapshot.h" /* __STDC__ prototypes for static functions */ static void put_file_contents (t_uchar * path, t_uchar * contents); static void ensure_basename (t_uchar * dir, t_uchar * basename); void archive_snapshot (struct arch_archive * arch, t_uchar * limit, t_uchar * dir) { t_uchar * only_category = 0; t_uchar * only_branch = 0; t_uchar * only_version = 0; t_uchar * only_revision = 0; t_uchar * archive_basename = 0; t_uchar * archive_subdir = 0; rel_table categories = 0; int c; if (limit) { only_category = arch_parse_package_name (arch_ret_category, 0, limit); if (arch_valid_package_name (limit, arch_no_archive, arch_req_package, 1)) { only_branch = arch_parse_package_name (arch_ret_package, 0, limit); if (!str_cmp (only_branch, only_category)) { lim_free (0, only_branch); only_branch = 0; } else if (arch_valid_package_name (limit, arch_no_archive, arch_req_version, 1)) { only_version = arch_parse_package_name (arch_ret_package_version, 0, limit); if (arch_valid_package_name (limit, arch_no_archive, arch_req_patch_level, 1)) { only_revision = arch_parse_package_name (arch_ret_non_archive, 0, limit); } } } } archive_basename = str_alloc_cat (0, arch->official_name, ".added"); ensure_basename (dir, archive_basename); archive_subdir = file_name_in_vicinity (0, dir, arch->official_name); ensure_directory_exists (archive_subdir); categories = arch_archive_categories (arch); for (c = 0; c < rel_n_records (categories); ++c) { t_uchar * category_basename = 0; t_uchar * category_subdir = 0; rel_table branches = 0; int b; if (only_category && str_cmp (only_category, categories[c][0])) continue; category_basename = str_alloc_cat (0, categories[c][0], ".added"); category_subdir = file_name_in_vicinity (0, archive_subdir, categories[c][0]); branches = arch_archive_branches (arch, categories[c][0]); ensure_basename (archive_subdir, category_basename); ensure_directory_exists (category_subdir); for (b = 0; b < rel_n_records (branches); ++b) { t_uchar * branch_basename = 0; t_uchar * branch_subdir = 0; rel_table versions = 0; int v; if (only_branch && str_cmp (only_branch, branches[b][0])) continue; branch_basename = str_alloc_cat (0, branches[b][0], ".added"); branch_subdir = file_name_in_vicinity (0, category_subdir, branches[b][0]); versions = arch_archive_versions (arch, branches[b][0]); ensure_basename (category_subdir, branch_basename); ensure_directory_exists (branch_subdir); for (v = 0; v < rel_n_records (versions); ++v) { t_uchar * version_basename = 0; t_uchar * version_subdir = 0; rel_table revisions = 0; int r; if (only_version && str_cmp (only_version, versions[v][0])) continue; version_basename = str_alloc_cat (0, versions[v][0], ".added"); version_subdir = file_name_in_vicinity (0, branch_subdir, versions[v][0]); revisions = arch_archive_revisions (arch, versions[v][0], 2); ensure_basename (branch_subdir, version_basename); ensure_directory_exists (version_subdir); for (r = 0; r < rel_n_records (revisions); ++r) { t_uchar * revision_basename = 0; t_uchar * revision_file = 0; t_uchar * log = 0; if (only_revision && str_cmp (only_revision, revisions[r][0])) continue; revision_basename = str_alloc_cat (0, revisions[r][0], ".added"); revision_file = file_name_in_vicinity (0, version_subdir, revision_basename); if (safe_access (revision_file, F_OK)) { t_uchar * tmp_file = 0; tmp_file = talloc_tmp_file_name (talloc_context, version_subdir, ",,new-log"); log = arch_archive_log (arch, revisions[r][0]); put_file_contents (tmp_file, log); safe_rename (tmp_file, revision_file); talloc_free (tmp_file); } lim_free (0, revision_basename); lim_free (0, revision_file); lim_free (0, log); } lim_free (0, version_basename); lim_free (0, version_subdir); rel_free_table (revisions); } lim_free (0, branch_basename); lim_free (0, branch_subdir); rel_free_table (versions); } lim_free (0, category_basename); lim_free (0, category_subdir); rel_free_table (branches); } lim_free (0, only_category); lim_free (0, only_branch); lim_free (0, only_version); lim_free (0, only_revision); lim_free (0, archive_basename); lim_free (0, archive_subdir); rel_free_table (categories); } static void put_file_contents (t_uchar * path, t_uchar * contents) { int out_fd; out_fd = safe_open (path, O_WRONLY | O_CREAT | O_EXCL, 0444); safe_printfmt (out_fd, "%s\n", contents); safe_close (out_fd); } static void ensure_basename (t_uchar * dir, t_uchar * basename) { int errn; t_uchar * path = 0; int in_fd; path = file_name_in_vicinity (0, dir, basename); in_fd = vu_open (&errn, path, O_WRONLY | O_CREAT | O_EXCL, 0444); if (in_fd >= 0) safe_close (in_fd); else if (errn != EEXIST) { safe_printfmt (2, "archive-snapshot: error creating file %s/%s (%s)\n", dir, basename, errno_to_string (errn)); exit (2); } lim_free (0, path); } /* tag: Tom Lord Mon Jun 9 01:03:59 2003 (archive-snapshot.c) */