1 /* archive-snapshot.c:
2 *
3 ****************************************************************
4 * Copyright (C) 2003 Tom Lord
5 *
6 * See the file "COPYING" for further information about
7 * the copyright and warranty status of this work.
8 */
9
10
11 #include "hackerlab/os/errno.h"
12 #include "hackerlab/os/errno-to-string.h"
13 #include "hackerlab/char/str.h"
14 #include "hackerlab/fs/file-names.h"
15 #include "hackerlab/vu/safe.h"
16 #include "tla/libfsutils/ensure-dir.h"
17 #include "tla/libfsutils/tmp-files.h"
18 #include "tla/libawk/relational.h"
19 #include "tla/libarch/archive.h"
20 #include "tla/libarch/namespace.h"
21 #include "tla/libarch/archive-snapshot.h"
22
23
24 /* __STDC__ prototypes for static functions */
25 static void put_file_contents (t_uchar * path, t_uchar * contents);
26 static void ensure_basename (t_uchar * dir, t_uchar * basename);
27
28
29
30 void
archive_snapshot(struct arch_archive * arch,t_uchar * limit,t_uchar * dir)31 archive_snapshot (struct arch_archive * arch, t_uchar * limit, t_uchar * dir)
32 {
33 t_uchar * only_category = 0;
34 t_uchar * only_branch = 0;
35 t_uchar * only_version = 0;
36 t_uchar * only_revision = 0;
37 t_uchar * archive_basename = 0;
38 t_uchar * archive_subdir = 0;
39 rel_table categories = rel_table_nil;
40 int c;
41
42 if (limit)
43 {
44 only_category = arch_parse_package_name (arch_ret_category, 0, limit);
45
46 if (arch_valid_package_name (limit, arch_no_archive, arch_req_package, 1))
47 {
48 only_branch = arch_parse_package_name (arch_ret_package, 0, limit);
49
50 if (!str_cmp (only_branch, only_category))
51 {
52 lim_free (0, only_branch);
53 only_branch = 0;
54 }
55 else if (arch_valid_package_name (limit, arch_no_archive, arch_req_version, 1))
56 {
57 only_version = arch_parse_package_name (arch_ret_package_version, 0, limit);
58
59 if (arch_valid_package_name (limit, arch_no_archive, arch_req_patch_level, 1))
60 {
61 only_revision = arch_parse_package_name (arch_ret_non_archive, 0, limit);
62 }
63 }
64 }
65 }
66
67
68 archive_basename = str_alloc_cat (0, arch->name, ".added");
69 ensure_basename (dir, archive_basename);
70
71 archive_subdir = file_name_in_vicinity (0, dir, arch->name);
72 ensure_directory_exists (archive_subdir);
73
74 categories = arch_archive_categories (arch);
75
76 for (c = 0; c < rel_n_records (categories); ++c)
77 {
78 t_uchar * category_basename = 0;
79 t_uchar * category_subdir = 0;
80 rel_table branches = rel_table_nil;
81 int b;
82
83 if (only_category && str_cmp (only_category, rel_peek_str (categories, c, 0)))
84 continue;
85
86 category_basename = str_alloc_cat (0, rel_peek_str (categories, c, 0), ".added");
87 category_subdir = file_name_in_vicinity (0, archive_subdir, rel_peek_str (categories, c, 0));
88 branches = arch_archive_branches (arch, rel_peek_str (categories, c, 0));
89
90 ensure_basename (archive_subdir, category_basename);
91 ensure_directory_exists (category_subdir);
92
93 for (b = 0; b < rel_n_records (branches); ++b)
94 {
95 t_uchar * branch_basename = 0;
96 t_uchar * branch_subdir = 0;
97 rel_table versions = rel_table_nil;
98 int v;
99
100 if (only_branch && str_cmp (only_branch, rel_peek_str (branches, b, 0)))
101 continue;
102
103 branch_basename = str_alloc_cat (0, rel_peek_str (branches, b, 0), ".added");
104 branch_subdir = file_name_in_vicinity (0, category_subdir, rel_peek_str (branches, b, 0));
105 versions = arch_archive_versions (arch, rel_peek_str (branches, b, 0));
106
107 ensure_basename (category_subdir, branch_basename);
108 ensure_directory_exists (branch_subdir);
109
110 for (v = 0; v < rel_n_records (versions); ++v)
111 {
112 t_uchar * version_basename = 0;
113 t_uchar * version_subdir = 0;
114 rel_table revisions = rel_table_nil;
115 int r;
116
117 if (only_version && str_cmp (only_version, rel_peek_str (versions, v, 0)))
118 continue;
119
120 version_basename = str_alloc_cat (0, rel_peek_str (versions, v, 0), ".added");
121 version_subdir = file_name_in_vicinity (0, branch_subdir, rel_peek_str (versions, v, 0));
122 revisions = arch_archive_revisions (arch, rel_peek_str (versions, v, 0), 2);
123
124 ensure_basename (branch_subdir, version_basename);
125 ensure_directory_exists (version_subdir);
126
127 for (r = 0; r < rel_n_records (revisions); ++r)
128 {
129 t_uchar * revision_basename = 0;
130 t_uchar * revision_file = 0;
131 t_uchar * log = 0;
132
133 if (only_revision && str_cmp (only_revision, rel_peek_str (revisions, r, 0)))
134 continue;
135
136 revision_basename = str_alloc_cat (0, rel_peek_str (revisions, r, 0), ".added");
137 revision_file = file_name_in_vicinity (0, version_subdir, revision_basename);
138 if (safe_access (revision_file, F_OK))
139 {
140 t_uchar * tmp_file = 0;
141
142 tmp_file = tmp_file_name (version_subdir, ",,new-log");
143 log = arch_archive_log (arch, rel_peek_str (revisions, r, 0));
144 put_file_contents (tmp_file, log);
145 safe_rename (tmp_file, revision_file);
146
147 lim_free (0, tmp_file);
148 }
149
150
151 lim_free (0, revision_basename);
152 lim_free (0, revision_file);
153 lim_free (0, log);
154 }
155
156
157 lim_free (0, version_basename);
158 lim_free (0, version_subdir);
159 rel_free_table (revisions);
160 }
161
162
163 lim_free (0, branch_basename);
164 lim_free (0, branch_subdir);
165 rel_free_table (versions);
166 }
167
168
169 lim_free (0, category_basename);
170 lim_free (0, category_subdir);
171 rel_free_table (branches);
172 }
173
174
175
176 lim_free (0, only_category);
177 lim_free (0, only_branch);
178 lim_free (0, only_version);
179 lim_free (0, only_revision);
180 lim_free (0, archive_basename);
181 lim_free (0, archive_subdir);
182 rel_free_table (categories);
183 }
184
185
186
187 static void
put_file_contents(t_uchar * path,t_uchar * contents)188 put_file_contents (t_uchar * path, t_uchar * contents)
189 {
190 int out_fd;
191
192 out_fd = safe_open (path, O_WRONLY | O_CREAT | O_EXCL, 0444);
193 safe_printfmt (out_fd, "%s\n", contents);
194 safe_close (out_fd);
195 }
196
197 static void
ensure_basename(t_uchar * dir,t_uchar * basename)198 ensure_basename (t_uchar * dir, t_uchar * basename)
199 {
200 int errn;
201 t_uchar * path = 0;
202 int in_fd;
203
204 path = file_name_in_vicinity (0, dir, basename);
205 in_fd = vu_open (&errn, path, O_WRONLY | O_CREAT | O_EXCL, 0444);
206 if (in_fd >= 0)
207 safe_close (in_fd);
208 else if (errn != EEXIST)
209 {
210 safe_printfmt (2, "archive-snapshot: error creating file %s/%s (%s)\n", dir, basename, errno_to_string (errn));
211 exit (2);
212 }
213
214 lim_free (0, path);
215 }
216
217
218
219
220 /* tag: Tom Lord Mon Jun 9 01:03:59 2003 (archive-snapshot.c)
221 */
222