/* archive-setup.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/panic.h" #include "hackerlab/bugs/exception.h" #include "hackerlab/arrays/ar.h" #include "hackerlab/char/str.h" #include "hackerlab/vu/safe.h" #include "libawk/associative.h" #include "libarch/chatter.h" #include "libarch/namespace.h" #include "libarch/archive.h" #include "libarch/tag.h" #include "libarch/archive-cache.h" #include "libarch/archive-setup.h" /* __STDC__ prototypes for static functions */ static struct arch_archive * find_archive (struct arch_archive ** archs, t_uchar * name); void arch_setup_archive_simple (int chatter_fd, t_uchar * archive_spec, t_uchar * revision_spec) { rel_table wants = 0; rel_add_records (&wants, rel_make_record (archive_spec, revision_spec, 0), 0); arch_setup_archive (chatter_fd, wants, arch_archive_setup_no_tags, 0); rel_free_table (wants); } /** * \brief setup a branch in an archive somewhere * * TODO: FIXME-REMOVENAME give .._ext url + namespace elements, * not registered-names. then we can change registered_name to location * below */ void arch_setup_archive_simple_ext (int chatter_fd, struct arch_archive * arch, t_uchar * revision_spec) { rel_table wants = 0; rel_add_records (&wants, rel_make_record (arch->registered_name, revision_spec, 0), 0); arch_setup_archive_ext (chatter_fd, wants, arch_archive_setup_no_tags, 0, arch); rel_free_table (wants); } void arch_setup_archive (int chatter_fd, rel_table wants, enum arch_archive_setup_tag_op tag_op, int archive_cache) { arch_setup_archive_ext (chatter_fd, wants, tag_op, archive_cache, NULL); } static void arch_archive_populate_fqcategory_exists (struct arch_archive *arch, assoc_table * fqcategory_exists) { int c; rel_table categories = arch_archive_categories (arch); for (c = 0; c < rel_n_records (categories); ++c) { t_uchar * cat = 0; cat = arch_fully_qualify (arch->official_name, categories[c][0]); assoc_set (fqcategory_exists, cat, "yes"); lim_free (0, cat); } rel_free_table (categories); } void arch_setup_archive_ext (int chatter_fd, rel_table wants, enum arch_archive_setup_tag_op tag_op, int archive_cache, struct arch_archive * initial_arch) { t_uchar * errstr = 0; struct arch_archive ** archs = 0; assoc_table fqcategories_checked = 0; assoc_table fqbranches_checked = 0; assoc_table fqcategory_exists = 0; assoc_table fqbranch_exists = 0; assoc_table fqversion_exists = 0; int x; if (initial_arch) ar_push_arch_archive (&archs, initial_arch); for (x = 0; x < rel_n_records (wants); ++x) { t_uchar * archive; struct arch_archive * arch = 0; t_uchar * spec; t_uchar * category = 0; t_uchar * fqcategory = 0; archive = wants[x][0]; arch = find_archive (archs, archive); if (!arch) { arch = arch_archive_connect_branch (archive, NULL); if (!arch) { safe_printfmt (2, "Could not connect to archive %s ", archive); exit (2); } ar_push_arch_archive (&archs, arch); arch_archive_populate_fqcategory_exists (arch, &fqcategory_exists); } if (!fqcategory_exists) arch_archive_populate_fqcategory_exists (arch, &fqcategory_exists); spec = wants[x][1]; category = arch_parse_package_name (arch_ret_category, 0, spec); fqcategory = arch_fully_qualify (arch->official_name, category); if (arch->type != arch_archive_baz && !assoc_ref (fqcategory_exists, fqcategory)) { arch_chatter (chatter_fd, "* creating category %s/%s\n", arch->official_name, category); if (arch_make_category (&errstr, arch, category)) { safe_printfmt (2, "archive-setup: error making category %s/%s in %s (%s)\n", arch->official_name, category, arch->location, errstr); exit (1); } assoc_set (&fqcategory_exists, fqcategory, "yes"); } if (str_cmp (spec, category)) { if (arch_valid_package_name (spec, arch_no_archive, arch_req_package, 1)) { t_uchar * branch = 0; t_uchar * fqbranch = 0; branch = arch_parse_package_name (arch_ret_package, 0, spec); fqbranch = arch_fully_qualify (arch->official_name, branch); if (!assoc_ref (fqcategories_checked, fqcategory)) { rel_table branches = 0; int b; branches = arch_archive_branches (arch, category); for (b = 0; b < rel_n_records (branches); ++b) { t_uchar * bran = 0; bran = arch_fully_qualify (arch->official_name, branches[b][0]); assoc_set (&fqbranch_exists, bran, "yes"); lim_free (0, bran); } rel_free_table (branches); } if (arch->type != arch_archive_baz && !assoc_ref (fqbranch_exists, fqbranch)) { arch_chatter (chatter_fd, "* creating branch %s/%s\n", arch->official_name, branch); if (arch_make_branch (&errstr, arch, branch)) { safe_printfmt (2, "archive-setup: error making branch %s/%s (%s)\n", arch->official_name, branch, errstr); exit (1); } assoc_set (&fqbranch_exists, fqbranch, "yes"); } if (arch_valid_package_name (spec, arch_no_archive, arch_req_version, 0)) { t_uchar * version = 0; t_uchar * fqversion = 0; version = arch_parse_package_name (arch_ret_package_version, 0, spec); fqversion = arch_fully_qualify (arch->official_name, version); if (!assoc_ref (fqbranches_checked, fqbranch)) { rel_table versions = 0; int v; versions = arch_archive_versions (arch, branch); for (v = 0; v < rel_n_records (versions); ++v) { t_uchar * vers = 0; vers = arch_fully_qualify (arch->official_name, versions[v][0]); assoc_set (&fqversion_exists, vers, "yes"); lim_free (0, vers); } rel_free_table (versions); } if (!assoc_ref (fqversion_exists, fqversion)) { arch_chatter (chatter_fd, "* creating version %s/%s\n", arch->official_name, version); if (arch_make_version (&errstr, arch, version)) { safe_printfmt (2, "archive-setup: error making version %s/%s (%s)\n", arch->official_name, version, errstr); exit (1); } assoc_set (&fqversion_exists, fqversion, "yes"); } if (tag_op != arch_archive_setup_no_tags) { rel_table has_revisions = 0; t_uchar * tag_from_archive; t_uchar * tag_from_rev_spec; struct arch_archive * from_arch = 0; t_uchar * tag_from_version = 0; rel_table from_has_revisions = 0; arch_chatter (chatter_fd, "* creating tag in %s/%s\n", arch->official_name, version); has_revisions = arch_archive_revisions (arch, version, 0); tag_from_archive = wants[x][2]; tag_from_rev_spec = wants[x][3]; from_arch = find_archive (archs, tag_from_archive); if (!from_arch) { /* FIXME-REMOVENAME use the namespace out facility */ from_arch = arch_archive_connect_branch (tag_from_archive, NULL); if (!arch) { safe_printfmt (2, "Could not connect to archive %s ", archive); exit (2); } ar_push_arch_archive (&archs, from_arch); } tag_from_version = arch_parse_package_name (arch_ret_package_version, 0, tag_from_rev_spec); from_has_revisions = arch_archive_revisions (from_arch, tag_from_version, 0); switch (tag_op) { default: { panic ("archive-setup.c internal error"); break; } case arch_archive_setup_make_base0_tag: { if (has_revisions) arch_chatter (chatter_fd, " ...skipping, base-0 already exists"); else { t_uchar * tag_revision = 0; t_uchar * tag_from_revision = 0; tag_revision = str_alloc_cat (0, version, "--base-0"); if (arch_valid_package_name (tag_from_rev_spec, 0, arch_req_patch_level, 0)) tag_from_revision = arch_parse_package_name (arch_ret_non_archive, 0, tag_from_rev_spec); else if (from_has_revisions) tag_from_revision = str_alloc_cat_many (0, tag_from_version, "--", from_has_revisions[rel_n_records (from_has_revisions) - 1][0], str_end); if (tag_from_revision) { tag_method_t * tag = arch_tag (talloc_context, chatter_fd, arch, tag_revision, from_arch, tag_from_revision, 0); if (archive_cache) arch_tag_cacherev (tag); talloc_free (tag); } lim_free (0, tag_from_revision); lim_free (0, tag_revision); } break; } } rel_free_table (has_revisions); lim_free (0, tag_from_version); rel_free_table (from_has_revisions); } lim_free (0, version); lim_free (0, fqversion); } lim_free (0, branch); lim_free (0, fqbranch); } } lim_free (0, category); lim_free (0, fqcategory); } for (x = 0; x < ar_size_arch_archive (archs); ++x) if (archs[x] != initial_arch) arch_archive_close (archs[x]); ar_free_arch_archive (&archs); free_assoc_table (fqcategories_checked); free_assoc_table (fqbranches_checked); free_assoc_table (fqcategory_exists); free_assoc_table (fqbranch_exists); free_assoc_table (fqversion_exists); } /** * \brief find an archive in the local cache. * * TODO, FIXME-REMOVENAME - replace registered_name with location here, * and in all callers. */ static struct arch_archive * find_archive (struct arch_archive ** archs, t_uchar * name) { int x; for (x = 0; x < ar_size_arch_archive (archs); ++x) if (!str_cmp (name, archs[x]->registered_name)) return archs[x]; return 0; } /* tag: Tom Lord Wed Jun 11 11:58:43 2003 (archive-setup.c) */