/* 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)
*/
syntax highlighted by Code2HTML, v. 0.9.1