1 /* archives.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/bugs/panic.h"
13 #include "hackerlab/char/char-class.h"
14 #include "hackerlab/char/str.h"
15 #include "hackerlab/mem/mem.h"
16 #include "hackerlab/fs/file-names.h"
17 #include "hackerlab/fs/cwd.h"
18 #include "hackerlab/vu/safe.h"
19 #include "tla/libfsutils/tmp-files.h"
20 #include "tla/libfsutils/read-line.h"
21 #include "tla/libfsutils/dir-listing.h"
22 #include "tla/libawk/relational.h"
23 #include "tla/libarch/my.h"
24 #include "tla/libarch/namespace.h"
25 #include "tla/libarch/archive-version.h"
26 #include "tla/libarch/archives.h"
27 
28 
29 
30 t_uchar *
arch_archive_location_file(const t_uchar * archive_name)31 arch_archive_location_file (const t_uchar * archive_name)
32 {
33   t_uchar * location_dir = 0;
34   t_uchar * answer = 0;
35 
36   if (! arch_valid_archive_name(archive_name))
37     {
38       int ign;
39 
40       printfmt (&ign, 2, "Invalid archive name `%s'.", archive_name);
41       exit (2);
42     }
43 
44   location_dir = arch_my_archive_locations_dir ();
45   answer = file_name_in_vicinity (0, location_dir, archive_name);
46 
47   lim_free (0, location_dir);
48 
49   return answer;
50 }
51 
52 
53 void
arch_set_archive_location(const t_uchar * archive_name,const t_uchar * location,int force_p,int quietly_fail)54 arch_set_archive_location (const t_uchar * archive_name,
55                            const t_uchar * location,
56                            int force_p,
57                            int quietly_fail)
58 {
59   t_uchar * file = 0;
60   t_uchar * dir = 0;
61   t_uchar * tmp_name = 0;
62 
63   file = arch_archive_location_file (archive_name);
64   dir = file_name_directory_file (0, file);
65   tmp_name = tmp_file_name (dir, ",,new-location");
66 
67   if (!force_p && !safe_access (file, F_OK))
68     {
69       if (! quietly_fail)
70         {
71           safe_printfmt (2, "archive already registered: %s\n", archive_name);
72           if (quietly_fail == ARCH_REG_FAIL_NOFAIL)
73             {
74               return;
75             }
76           else
77             {
78               exit (2);
79             }
80         }
81     }
82   else
83     {
84       int ign;
85       int out_fd;
86 
87       arch_ensure_my_arch_params ();
88       vu_mkdir (&ign, dir, 0700);
89 
90       out_fd = safe_open (tmp_name, O_WRONLY | O_CREAT | O_EXCL, 0666);
91       safe_printfmt (out_fd, "%s\n", location);
92       safe_close (out_fd);
93 
94       safe_rename (tmp_name, file);
95     }
96 
97   lim_free (0, file);
98   lim_free (0, dir);
99   lim_free (0, tmp_name);
100 }
101 
102 
103 t_uchar *
arch_archive_location(const t_uchar * archive_name,int soft)104 arch_archive_location (const t_uchar * archive_name,
105                        int soft)
106 {
107   t_uchar * file = 0;
108   t_uchar * first_line = 0;
109   t_uchar * start;
110   t_uchar * end;
111   t_uchar * answer = 0;
112 
113   file = arch_archive_location_file (archive_name);
114 
115   if (safe_access (file, F_OK))
116     {
117       if (soft)
118         return 0;
119 
120       safe_printfmt (2, "archive not registered: %s\n", archive_name);
121       safe_printfmt (2, "  (see register-archive)\n");
122       exit (2);
123     }
124 
125   first_line = read_line_from_file (file);
126 
127   for (start = first_line; char_is_blank (*start); ++start)
128     ;
129   for (end = start; *end && !char_is_space (*start); ++end)
130     ;
131 
132   answer = str_save_n (0, start, end - start);
133 
134   lim_free (0, file);
135   lim_free (0, first_line);
136 
137   return answer;
138 }
139 
140 
141 void
arch_delete_archive_location(const t_uchar * archive_name,int force_p)142 arch_delete_archive_location (const t_uchar * archive_name,
143                               int force_p)
144 {
145   t_uchar * file = 0;
146   int errn;
147 
148   file = arch_archive_location_file (archive_name);
149 
150   if (vu_unlink (&errn, file))
151     {
152       if (!(force_p && (errn == ENOENT)))
153         {
154           safe_printfmt (2, "archive not registered: %s\n", archive_name);
155           safe_printfmt (2, "  (see register-archive)\n");
156           exit (2);
157         }
158     }
159 
160   lim_free (0, file);
161 }
162 
163 
164 rel_table
arch_registered_archives(void)165 arch_registered_archives (void)
166 {
167   t_uchar * dir = 0;
168   rel_table files  = rel_table_nil;
169   rel_table answer  = rel_table_nil;
170   int x;
171 
172   dir = arch_my_archive_locations_dir ();
173   files = maybe_directory_files (dir);
174 
175   for (x = 0; x < rel_n_records (files); ++x)
176     {
177       const t_uchar * f;
178 
179       f = rel_peek_str (files, x, 0);
180       if (str_cmp (".", f) && str_cmp ("..", f) && arch_valid_archive_name (f))
181         {
182           t_uchar * location = 0;
183 
184           location = arch_archive_location (f, 0);
185           rel_add_records (&answer, rel_make_record_2_taking (rel_get_field (files, x, 0), rel_make_field_str (location)), rel_record_null);
186 
187           lim_free (0, location);
188         }
189     }
190 
191 
192   lim_free (0, dir);
193   rel_free_table (files);
194 
195   return answer;
196 }
197 
198 t_uchar *
arch_mirrored_at_name(const t_uchar * archive)199 arch_mirrored_at_name (const t_uchar * archive)
200 {
201   t_uchar * mirror_name = 0;
202 
203   mirror_name = str_alloc_cat (0, archive, "-MIRROR");
204 
205   return mirror_name;
206 }
207 
208 t_uchar *
arch_mirrored_from_name(const t_uchar * archive)209 arch_mirrored_from_name (const t_uchar * archive)
210 {
211   t_uchar * source_name = 0;
212 
213   source_name = str_alloc_cat (0, archive, "-SOURCE");
214 
215   return source_name;
216 }
217 
218 t_uchar *
arch_mirrored_at(const t_uchar * archive)219 arch_mirrored_at (const t_uchar * archive)
220 {
221   t_uchar * mirror_name = 0;
222   t_uchar * mirror_loc = 0;
223 
224   mirror_name = arch_mirrored_at_name (archive);
225   mirror_loc = arch_archive_location (mirror_name, 1);
226 
227   if (!mirror_loc)
228     {
229       lim_free (0, mirror_name);
230       mirror_name = 0;
231     }
232 
233   lim_free (0, mirror_loc);
234   return mirror_name;
235 }
236 
237 
238 t_uchar *
arch_mirrored_from(const t_uchar * archive)239 arch_mirrored_from (const t_uchar * archive)
240 {
241   t_uchar * source_name = 0;
242   t_uchar * source_loc = 0;
243 
244   source_name = arch_mirrored_from_name (archive);
245   source_loc = arch_archive_location (source_name, 1);
246 
247   if (!source_loc)
248     {
249       lim_free (0, source_name);
250       source_name = 0;
251     }
252 
253   lim_free (0, source_loc);
254   return source_name;
255 }
256 
257 
258 
259 t_uchar *
arch_fs_archive_archive_version_path(const t_uchar * archive_path)260 arch_fs_archive_archive_version_path (const t_uchar * archive_path)
261 {
262   return file_name_in_vicinity (0, archive_path, ".archive-version");
263 }
264 
265 
266 t_uchar *
arch_fs_archive_meta_info_path(const t_uchar * archive_path)267 arch_fs_archive_meta_info_path (const t_uchar * archive_path)
268 {
269   return file_name_in_vicinity (0, archive_path, "=meta-info");
270 }
271 
272 
273 t_uchar *
arch_fs_archive_meta_info_item_path(const t_uchar * archive_path,const t_uchar * meta_info_name)274 arch_fs_archive_meta_info_item_path (const t_uchar * archive_path,
275                                      const t_uchar * meta_info_name)
276 {
277   t_uchar * meta_info_dir = 0;
278   t_uchar * meta_info_path;
279 
280   meta_info_dir = arch_fs_archive_meta_info_path (archive_path);
281   meta_info_path = file_name_in_vicinity (0, meta_info_dir, meta_info_name);
282 
283   lim_free (0, meta_info_dir);
284 
285   return meta_info_path;
286 }
287 
288 
289 
290 
291 /* tag: Tom Lord Sun May 18 19:17:40 2003 (archives.c)
292  */
293