1 /* archive-setup.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/bugs/panic.h"
12 #include "hackerlab/arrays/ar.h"
13 #include "hackerlab/char/str.h"
14 #include "hackerlab/vu/safe.h"
15 #include "tla/libawk/associative.h"
16 #include "tla/libarch/chatter.h"
17 #include "tla/libarch/namespace.h"
18 #include "tla/libarch/archive.h"
19 #include "tla/libarch/tag.h"
20 #include "tla/libarch/archive-cache.h"
21 #include "tla/libarch/archive-setup.h"
22 
23 
24 /* __STDC__ prototypes for static functions */
25 static struct arch_archive * find_archive (struct arch_archive ** archs,
26                                            const t_uchar * name);
27 
28 
29 
30 void
arch_setup_archive_simple(int chatter_fd,const t_uchar * archive_spec,const t_uchar * revision_spec)31 arch_setup_archive_simple (int chatter_fd,
32                            const t_uchar * archive_spec,
33                            const t_uchar * revision_spec)
34 {
35   rel_table wants  = rel_table_nil;
36 
37   rel_add_records (&wants, rel_make_record_2_taking (rel_make_field_str (archive_spec), rel_make_field_str (revision_spec)), rel_record_null);
38   arch_setup_archive (chatter_fd, wants, arch_archive_setup_no_tags, 0);
39 
40   rel_free_table (wants);
41 }
42 
43 void
arch_setup_archive_simple_ext(int chatter_fd,struct arch_archive * arch,const t_uchar * revision_spec)44 arch_setup_archive_simple_ext (int chatter_fd,
45 			       struct arch_archive * arch,
46 			       const t_uchar * revision_spec)
47 {
48   rel_table wants = rel_table_nil;
49 
50   rel_add_records (&wants, rel_make_record_2_taking (rel_make_field_str (arch->name), rel_make_field_str (revision_spec)), rel_record_null);
51   arch_setup_archive_ext (chatter_fd, wants, arch_archive_setup_no_tags, 0, arch);
52 
53   rel_free_table (wants);
54 }
55 
56 void
arch_setup_archive(int chatter_fd,rel_table wants,enum arch_archive_setup_tag_op tag_op,int archive_cache)57 arch_setup_archive (int chatter_fd, rel_table wants,
58                     enum arch_archive_setup_tag_op tag_op,
59                     int archive_cache)
60 {
61   arch_setup_archive_ext (chatter_fd, wants, tag_op, archive_cache, NULL);
62 }
63 
64 static void
arch_archive_populate_fqcategory_exists(struct arch_archive * arch,assoc_table * fqcategory_exists)65 arch_archive_populate_fqcategory_exists (struct arch_archive * arch, assoc_table * fqcategory_exists)
66 {
67   int c;
68   rel_table categories = arch_archive_categories (arch);
69 
70   for (c = 0; c < rel_n_records (categories); ++c)
71     {
72       t_uchar * cat = 0;
73 
74       cat = arch_fully_qualify (arch->name, rel_peek_str (categories, c, 0));
75       assoc_set_taking (fqcategory_exists, rel_make_field_str (cat), rel_make_field_str ("yes"));
76 
77       lim_free (0, cat);
78     }
79 
80   rel_free_table (categories);
81 }
82 
83 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)84 arch_setup_archive_ext (int chatter_fd, rel_table wants,
85                         enum arch_archive_setup_tag_op tag_op,
86                         int archive_cache,
87                         struct arch_archive * initial_arch)
88 {
89   t_uchar * errstr = 0;
90   struct arch_archive ** archs = 0;
91   assoc_table fqcategories_checked = 0;
92   assoc_table fqbranches_checked = 0;
93   assoc_table fqcategory_exists = 0;
94   assoc_table fqbranch_exists = 0;
95   assoc_table fqversion_exists = 0;
96   int x;
97 
98   if (initial_arch)
99     *(struct arch_archive **)ar_push ((void **)&archs, 0, sizeof (initial_arch)) = initial_arch;
100 
101   for (x = 0; x < rel_n_records (wants); ++x)
102     {
103       const t_uchar * archive;
104       struct arch_archive * arch = 0;
105       const t_uchar * spec;
106       t_uchar * category = 0;
107       t_uchar * fqcategory = 0;
108 
109       archive = rel_peek_str (wants, x, 0);
110 
111       arch = find_archive (archs, archive);
112 
113       if (!arch)
114         {
115           arch = arch_archive_connect (archive, 0);
116           *(struct arch_archive **)ar_push ((void **)&archs, 0, sizeof (arch)) = arch;
117 
118           arch_archive_populate_fqcategory_exists (arch, &fqcategory_exists);
119         }
120 
121       if (!fqcategory_exists)
122         arch_archive_populate_fqcategory_exists (arch, &fqcategory_exists);
123 
124       spec = rel_peek_str (wants, x, 1);
125 
126       category = arch_parse_package_name (arch_ret_category, 0, spec);
127       fqcategory = arch_fully_qualify (archive, category);
128 
129       if ((arch->type != arch_archive_baz) && !assoc_get_str_taking (fqcategory_exists, rel_make_field_str (fqcategory)))
130         {
131           arch_chatter (chatter_fd, "* creating category %s/%s\n", archive, category);
132           if (arch_make_category (&errstr, arch, category))
133             {
134               safe_printfmt (2, "archive-setup: error making category %s/%s (%s)\n", archive, category, errstr);
135               exit (1);
136             }
137           assoc_set_taking (&fqcategory_exists, rel_make_field_str (fqcategory), rel_make_field_str ("yes"));
138         }
139 
140       if (str_cmp (spec, category))
141         {
142           if (arch_valid_package_name (spec, arch_no_archive, arch_req_package, 1))
143             {
144               t_uchar * branch = 0;
145               t_uchar * fqbranch = 0;
146 
147               branch = arch_parse_package_name (arch_ret_package, 0, spec);
148               fqbranch = arch_fully_qualify (archive, branch);
149 
150               if (!assoc_get_str_taking (fqcategories_checked, rel_make_field_str (fqcategory)))
151                 {
152                   rel_table branches  = rel_table_nil;
153                   int b;
154 
155                   branches = arch_archive_branches (arch, category);
156                   for (b = 0; b < rel_n_records (branches); ++b)
157                     {
158                       t_uchar * bran = 0;
159 
160                       bran = arch_fully_qualify (archive, rel_peek_str (branches, b, 0));
161                       assoc_set_taking (&fqbranch_exists, rel_make_field_str (bran), rel_make_field_str ("yes"));
162 
163                       lim_free (0, bran);
164                     }
165 
166                   rel_free_table (branches);
167                 }
168 
169               if ((arch->type != arch_archive_baz) && !assoc_get_str_taking (fqbranch_exists, rel_make_field_str (fqbranch)))
170                 {
171                   arch_chatter (chatter_fd, "* creating branch %s/%s\n", archive, branch);
172                   if (arch_make_branch (&errstr, arch, branch))
173                     {
174                       safe_printfmt (2, "archive-setup: error making branch %s/%s (%s)\n", archive, branch, errstr);
175                       exit (1);
176                     }
177                   assoc_set_taking (&fqbranch_exists, rel_make_field_str (fqbranch), rel_make_field_str ("yes"));
178                 }
179 
180               if (arch_valid_package_name (spec, arch_no_archive, arch_req_version, 0))
181                 {
182                   t_uchar * version = 0;
183                   t_uchar * fqversion = 0;
184 
185                   version = arch_parse_package_name (arch_ret_package_version, 0, spec);
186                   fqversion = arch_fully_qualify (archive, version);
187 
188                   if (!assoc_get_str_taking (fqbranches_checked, rel_make_field_str (fqbranch)))
189                     {
190                       rel_table versions  = rel_table_nil;
191                       int v;
192 
193                       versions = arch_archive_versions (arch, branch);
194                       for (v = 0; v < rel_n_records (versions); ++v)
195                         {
196                           t_uchar * vers = 0;
197                           vers = arch_fully_qualify (archive, rel_peek_str (versions, v, 0));
198                           assoc_set_taking (&fqversion_exists, rel_make_field_str (vers), rel_make_field_str ("yes"));
199                           lim_free (0, vers);
200                         }
201 
202                       rel_free_table (versions);
203                     }
204 
205                   if (!assoc_get_str_taking (fqversion_exists, rel_make_field_str (fqversion)))
206                     {
207                       arch_chatter (chatter_fd, "* creating version %s/%s\n", archive, version);
208                       if (arch_make_version (&errstr, arch, version))
209                         {
210                           safe_printfmt (2, "archive-setup: error making version %s/%s (%s)\n", archive, version, errstr);
211                           exit (1);
212                         }
213                       assoc_set_taking (&fqversion_exists, rel_make_field_str (fqversion), rel_make_field_str ("yes"));
214                     }
215 
216                   if (tag_op != arch_archive_setup_no_tags)
217                     {
218                       rel_table has_revisions  = rel_table_nil;
219 
220                       const t_uchar * tag_from_archive;
221                       const t_uchar * tag_from_rev_spec;
222 
223                       struct arch_archive * from_arch = 0;
224                       t_uchar * tag_from_version = 0;
225                       rel_table from_has_revisions  = rel_table_nil;
226 
227                       arch_chatter (chatter_fd, "* creating tag in %s/%s\n", archive, version);
228                       has_revisions = arch_archive_revisions (arch, version, 0);
229 
230                       tag_from_archive = rel_peek_str (wants, x, 2);
231                       tag_from_rev_spec = rel_peek_str (wants, x, 3);
232 
233                       from_arch = find_archive (archs, tag_from_archive);
234                       if (!from_arch)
235                         {
236                           from_arch = arch_archive_connect (tag_from_archive, 0);
237                           *(struct arch_archive **)ar_push ((void **)&archs, 0, sizeof (arch)) = from_arch;
238                         }
239 
240                       tag_from_version = arch_parse_package_name (arch_ret_package_version, 0, tag_from_rev_spec);
241                       from_has_revisions = arch_archive_revisions (from_arch, tag_from_version, 0);
242 
243                       switch (tag_op)
244                         {
245                         default:
246                           {
247                             panic ("archive-setup.c internal error");
248                             break;
249                           }
250                         case arch_archive_setup_make_base0_tag:
251                           {
252                             if (rel_n_records (has_revisions))
253                               arch_chatter (chatter_fd, " ...skipping, base-0 already exists");
254                             else
255                               {
256                                 t_uchar * tag_revision = 0;
257                                 t_uchar * tag_from_revision = 0;
258 
259                                 tag_revision = str_alloc_cat (0, version, "--base-0");
260 
261                                 if (arch_valid_package_name (tag_from_rev_spec, 0, arch_req_patch_level, 0))
262                                   tag_from_revision = arch_parse_package_name (arch_ret_non_archive, 0, tag_from_rev_spec);
263                                 else if (rel_n_records (from_has_revisions))
264                                   tag_from_revision = str_alloc_cat_many (0, tag_from_version, "--", rel_peek_str (from_has_revisions, rel_n_records (from_has_revisions) - 1, 0), str_end);
265 
266                                 if (tag_from_revision)
267                                   {
268                                     arch_tag (chatter_fd, arch, tag_revision, from_arch, tag_from_revision, 0);
269 
270                                     if (archive_cache)
271                                       {
272                                         arch_chatter (chatter_fd, "* archive caching %s/%s\n", archive, tag_revision);
273                                         arch_archive_cache (chatter_fd, arch, archive, tag_revision, 0);
274                                       }
275                                   }
276 
277                                 lim_free (0, tag_from_revision);
278                                 lim_free (0, tag_revision);
279                               }
280 
281                             break;
282                           }
283                         }
284 
285                       rel_free_table (has_revisions);
286                       lim_free (0, tag_from_version);
287                       rel_free_table (from_has_revisions);
288                     }
289 
290                   lim_free (0, version);
291                   lim_free (0, fqversion);
292                 }
293 
294               lim_free (0, branch);
295               lim_free (0, fqbranch);
296             }
297         }
298       lim_free (0, category);
299       lim_free (0, fqcategory);
300     }
301 
302   for (x = 0; x < ar_size ((void *)archs, 0, sizeof (*archs)); ++x)
303     if (archs[x] != initial_arch)
304       arch_archive_close (archs[x]);
305 
306   ar_free ((void **)&archs, 0);
307   free_assoc_table (fqcategories_checked);
308   free_assoc_table (fqbranches_checked);
309   free_assoc_table (fqcategory_exists);
310   free_assoc_table (fqbranch_exists);
311   free_assoc_table (fqversion_exists);
312 }
313 
314 
315 static struct arch_archive *
find_archive(struct arch_archive ** archs,const t_uchar * name)316 find_archive (struct arch_archive ** archs,
317               const t_uchar * name)
318 {
319   int x;
320 
321   for (x = 0; x < ar_size ((void *)archs, 0, sizeof (*archs)); ++x)
322     if (!str_cmp (name, archs[x]->name))
323       return archs[x];
324 
325   return 0;
326 }
327 
328 
329 
330 /* tag: Tom Lord Wed Jun 11 11:58:43 2003 (archive-setup.c)
331  */
332