1 /* local-cache.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/mem/alloc-limits.h"
13 #include "hackerlab/char/str.h"
14 #include "hackerlab/fs/file-names.h"
15 #include "hackerlab/vu/safe.h"
16 #include "tla/libfsutils/tmp-files.h"
17 #include "tla/libfsutils/rmrf.h"
18 #include "tla/libfsutils/ensure-dir.h"
19 #include "tla/libarch/build-revision.h"
20 #include "tla/libarch/pristines.h"
21 #include "tla/libarch/libraries.h"
22 #include "tla/libarch/chatter.h"
23 #include "tla/libarch/my.h"
24 #include "tla/libarch/library-txn.h"
25 #include "tla/libarch/local-cache.h"
26 #include "tla/libarch/namespace.h"
27 
28 
29 
30 
31 int
arch_greedy_library_wants_revision(t_uchar * archive,t_uchar * revision)32 arch_greedy_library_wants_revision (t_uchar * archive, t_uchar * revision)
33 {
34   int answer = 0;
35   rel_table lib_path = rel_table_nil;
36 
37   lib_path = arch_my_library_path (arch_library_path_add_order);
38 
39   if (rel_n_records (lib_path))
40     {
41       t_uchar * default_add_lib = 0;
42 
43       default_add_lib = arch_library_add_choice (archive, revision, 0, 0);
44       if (arch_library_is_greedy (default_add_lib))
45         {
46           answer = 1;
47         }
48 
49       lim_free (0, default_add_lib);
50     }
51 
52   rel_free_table (lib_path);
53 
54   return answer;
55 }
56 
57 
58 t_uchar *
arch_find_local_copy(int chatter_fd,t_uchar * tree_root,t_uchar * cache_dir,t_uchar * archive,t_uchar * revision,t_uchar * hook)59 arch_find_local_copy (int chatter_fd,
60                       t_uchar * tree_root,
61                       t_uchar * cache_dir,
62                       t_uchar * archive,
63                       t_uchar * revision,
64                       t_uchar * hook)
65 {
66   t_uchar * answer = 0;
67   if (hook)
68     {
69       int error;
70 
71       error = arch_run_hook (hook,
72                              "ARCH_ARCHIVE", archive,
73                              "ARCH_REVISION", revision,
74                              (t_uchar*)0);
75 
76       if (error)
77         {
78           safe_printfmt (2, "tla: error running hook `%s' (%d)\n", hook, error);
79           exit (2);
80         }
81     }
82 
83   if (!answer)
84     answer = arch_library_find (rel_table_nil, archive, revision, 1);
85 
86   if (!answer && tree_root)
87     answer = arch_find_pristine (0, tree_root, archive, revision, arch_any_pristine, arch_tree_and_sibling_pristine_search);
88 
89   if (!answer && cache_dir)
90     answer = arch_find_pristine (0, cache_dir, archive, revision, arch_any_pristine, arch_cache_dir_pristine_search);
91 
92   if (!answer)
93     {
94       t_uchar *greedy_choice = 0;
95       greedy_choice = arch_library_greedy_add_choice(archive, revision, 0, 1);
96       if (greedy_choice)
97 	{
98 	  /* something wants a pristine copy that isn't around.
99 	   *
100 	   * There is a greedy library in the path, so add the revision to it.
101 	   */
102 
103 	  struct arch_archive * arch = 0;
104 
105 	  arch_chatter (chatter_fd, "* auto-adding %s/%s to greedy revision library %s\n", archive, revision, greedy_choice);
106 	  arch = arch_archive_connect (archive, 0);
107 	  arch_library_add (chatter_fd, 1, arch, revision, greedy_choice, 0, -1, 0);
108 	  answer = arch_library_find (rel_table_nil, archive, revision, 1);
109 	  arch_archive_close (arch);
110 	}
111     }
112 
113   return answer;
114 }
115 
116 
117 t_uchar *
arch_find_or_make_local_copy(int chatter_fd,t_uchar * tree_root,t_uchar * cache_dir,struct arch_archive * arch,t_uchar * archive,t_uchar * revision)118 arch_find_or_make_local_copy (int chatter_fd,
119                               t_uchar * tree_root,
120                               t_uchar * cache_dir,
121                               struct arch_archive * arch,
122                               t_uchar * archive,
123                               t_uchar * revision)
124 {
125   t_uchar * answer = 0;
126   t_uchar * parent_dir = 0;
127 
128   invariant (!!tree_root);
129   invariant (!arch || !str_cmp (archive, arch->name));
130 
131   if (!cache_dir)
132     {
133       parent_dir = file_name_directory_file (0, tree_root);
134       cache_dir = parent_dir;
135     }
136 
137   answer = arch_find_local_copy (chatter_fd, tree_root, cache_dir, archive, revision, "make-pristine");
138 
139   if (!answer)
140     {
141       t_uchar * tree_dir = 0;
142       t_uchar * tmp_path = 0;
143 
144       tree_dir = file_name_directory_file (0, tree_root);
145       if (!tree_dir)
146         tree_dir = str_save (0, ".");
147 
148       tmp_path = tmp_file_name (tree_dir, ",,new-pristine");
149 
150       rmrf_file (tmp_path);
151       safe_mkdir (tmp_path, 0777);
152 
153       arch_chatter (chatter_fd, "* build pristine tree for %s/%s\n", archive, revision);
154 
155       arch_build_revision (chatter_fd, tmp_path, arch, archive, revision, cache_dir);
156 
157       arch_install_pristine (tree_root, archive, revision, tmp_path);
158 
159       answer = arch_find_local_copy (chatter_fd, tree_root, cache_dir, archive, revision, 0);
160 
161       lim_free (0, tree_dir);
162       lim_free (0, tmp_path);
163     }
164 
165   if (parent_dir)
166     lim_free (0, parent_dir);
167 
168   return answer;
169 }
170 
171 
172 t_uchar *
arch_find_or_make_tmp_local_copy(int chatter_fd,t_uchar * tmp_dir,t_uchar * tree_root,t_uchar * cache_dir,struct arch_archive * arch,t_uchar * archive,t_uchar * revision)173 arch_find_or_make_tmp_local_copy  (int chatter_fd,
174                                    t_uchar * tmp_dir,
175                                    t_uchar * tree_root,
176                                    t_uchar * cache_dir,
177                                    struct arch_archive * arch,
178                                    t_uchar * archive,
179                                    t_uchar * revision)
180 {
181   t_uchar * answer = 0;
182   t_uchar * parent_dir = 0;
183 
184   if (!cache_dir)
185     {
186       parent_dir = file_name_directory_file (0, tree_root);
187       cache_dir = parent_dir;
188     }
189 
190   answer = arch_find_local_copy (chatter_fd, tree_root, cache_dir, archive, revision, "make-tmp-pristine");
191 
192   if (!answer)
193     {
194       t_uchar * tmp_stem = 0;
195       t_uchar * tmp_path = 0;
196       t_uchar * version = 0;
197       tmp_stem = str_alloc_cat_many (0, ",,", revision, "--", archive, str_end);
198       tmp_path = tmp_file_name (tmp_dir, tmp_stem);
199 
200       rmrf_file (tmp_path);
201       ensure_directory_exists (tmp_dir);
202       safe_mkdir (tmp_path, 0777);
203 
204       arch_chatter (chatter_fd, "* build reference tree for %s/%s\n", archive, revision);
205 
206       arch_build_revision (chatter_fd, tmp_path, arch, archive, revision, cache_dir);
207 
208       version = arch_parse_package_name (arch_ret_package_version, 0, revision);
209 
210       arch_set_tree_version(tmp_path, archive, version);
211 
212       lim_free (0, tmp_stem);
213       lim_free (0, version);
214       answer = tmp_path;
215     }
216 
217   if (parent_dir)
218     lim_free (0, parent_dir);
219 
220   return answer;
221 }
222 
223 
224 
225 
226 /* tag: Tom Lord Fri May 23 14:42:03 2003 (local-cache.c)
227  */
228