1 /* libraries.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/char/str.h"
13 #include "hackerlab/fs/file-names.h"
14 #include "hackerlab/vu/safe.h"
15 #include "tla/libfsutils/dir-listing.h"
16 #include "tla/libfsutils/same.h"
17 #include "tla/libarch/my.h"
18 #include "tla/libarch/namespace.h"
19 #include "tla/libarch/patch-logs.h"
20 #include "tla/libarch/changeset-utils.h"
21 #include "tla/libarch/libraries.h"
22 #include "tla/libarch/inode-sig.h"
23
24
25 /* __STDC__ prototypes for static functions */
26
27
28
29
30
31 rel_table
arch_library_archive_dirs(rel_table opt_lib_path,const t_uchar * archive,int for_add)32 arch_library_archive_dirs (rel_table opt_lib_path,
33 const t_uchar * archive,
34 int for_add)
35 {
36 rel_table lib_path = rel_table_nil;
37 rel_table answer = rel_table_nil;
38 int x;
39
40 invariant (arch_valid_archive_name (archive));
41
42 if (rel_n_records (opt_lib_path))
43 {
44 lib_path = rel_copy_table (opt_lib_path);
45 }
46 else
47 {
48 lib_path = arch_my_library_path (for_add ? arch_library_path_add_order : arch_library_path_search_order);
49 if (!rel_n_records (lib_path))
50 return rel_table_nil;
51 }
52
53 for (x = 0; x < rel_n_records (lib_path); ++x)
54 {
55 const t_uchar * lib_dir;
56 t_uchar * maybe_archive_dir = 0;
57
58 lib_dir = rel_peek_str (lib_path, x, 0);
59 maybe_archive_dir = file_name_in_vicinity (0, lib_dir, archive);
60
61 if (!safe_access (maybe_archive_dir, F_OK))
62 {
63 rel_add_records (&answer, rel_singleton_record_taking (rel_make_field_str (maybe_archive_dir)), rel_record_null);
64 }
65
66 lim_free (0, maybe_archive_dir);
67 }
68
69 if (for_add && !rel_n_records (answer))
70 {
71 const t_uchar * priority_lib_dir;
72 t_uchar * archive_dir = 0;
73
74 priority_lib_dir = rel_peek_str (lib_path, 0, 0);
75 archive_dir = file_name_in_vicinity (0, priority_lib_dir, archive);
76 rel_add_records (&answer, rel_singleton_record_taking (rel_make_field_str (archive_dir)), rel_record_null);
77
78 lim_free (0, archive_dir);
79 }
80
81 rel_free_table (lib_path);
82 return answer;
83 }
84
85
86 rel_table
arch_library_category_dirs(rel_table opt_lib_path,const t_uchar * archive,const t_uchar * category,int for_add)87 arch_library_category_dirs (rel_table opt_lib_path,
88 const t_uchar * archive,
89 const t_uchar * category,
90 int for_add)
91 {
92 rel_table answer = rel_table_nil;
93 rel_table archive_dirs = rel_table_nil;
94 int x;
95
96 invariant (arch_valid_package_name (category, arch_no_archive, arch_req_category, 0));
97
98 archive_dirs = arch_library_archive_dirs (opt_lib_path, archive, for_add);
99 if (!rel_n_records (archive_dirs))
100 return rel_table_nil;
101
102 for (x = 0; x < rel_n_records (archive_dirs); ++x)
103 {
104 const t_uchar * archive_dir;
105 t_uchar * maybe_category_dir = 0;
106
107 archive_dir = rel_peek_str (archive_dirs, x, 0);
108 maybe_category_dir = file_name_in_vicinity (0, archive_dir, category);
109
110 if (!safe_access (maybe_category_dir, F_OK))
111 {
112 rel_add_records (&answer, rel_singleton_record_taking (rel_make_field_str (maybe_category_dir)), rel_record_null);
113 }
114
115 lim_free (0, maybe_category_dir);
116 }
117
118 if (for_add && !rel_n_records (answer))
119 {
120 const t_uchar * priority_archive_dir;
121 t_uchar * category_dir = 0;
122
123 priority_archive_dir = rel_peek_str (archive_dirs, 0, 0);
124 category_dir = file_name_in_vicinity (0, priority_archive_dir, category);
125 rel_add_records (&answer, rel_singleton_record_taking (rel_make_field_str (category_dir)), rel_record_null);
126
127 lim_free (0, category_dir);
128 }
129
130 rel_free_table (archive_dirs);
131
132 return answer;
133 }
134
135
136 rel_table
arch_library_branch_dirs(rel_table opt_lib_path,const t_uchar * archive,const t_uchar * branch,int for_add)137 arch_library_branch_dirs (rel_table opt_lib_path,
138 const t_uchar * archive,
139 const t_uchar * branch,
140 int for_add)
141 {
142 rel_table answer = rel_table_nil;
143 t_uchar * category = 0;
144 rel_table category_dirs = rel_table_nil;
145 int x;
146
147 invariant (arch_valid_package_name (branch, arch_no_archive, arch_req_package, 0));
148
149 category = arch_parse_package_name (arch_ret_category, 0, branch);
150
151 category_dirs = arch_library_category_dirs (opt_lib_path, archive, category, for_add);
152 if (!rel_n_records (category_dirs))
153 return rel_table_nil;
154
155 for (x = 0; x < rel_n_records (category_dirs); ++x)
156 {
157 const t_uchar * category_dir;
158 t_uchar * maybe_branch_dir = 0;
159
160 category_dir = rel_peek_str (category_dirs, x, 0);
161 maybe_branch_dir = file_name_in_vicinity (0, category_dir, branch);
162
163 if (!safe_access (maybe_branch_dir, F_OK))
164 {
165 rel_add_records (&answer, rel_singleton_record_taking (rel_make_field_str (maybe_branch_dir)), rel_record_null);
166 }
167
168 lim_free (0, maybe_branch_dir);
169 }
170
171 if (for_add && !rel_n_records (answer))
172 {
173 const t_uchar * priority_category_dir;
174 t_uchar * branch_dir = 0;
175
176 priority_category_dir = rel_peek_str (category_dirs, 0, 0);
177 branch_dir = file_name_in_vicinity (0, priority_category_dir, branch);
178 rel_add_records (&answer, rel_singleton_record_taking (rel_make_field_str (branch_dir)), rel_record_null);
179
180 lim_free (0, branch_dir);
181 }
182
183 rel_free_table (category_dirs);
184 lim_free (0, category);
185
186 return answer;
187 }
188
189
190 rel_table
arch_library_version_dirs(rel_table opt_lib_path,const t_uchar * archive,const t_uchar * version,int for_add)191 arch_library_version_dirs (rel_table opt_lib_path,
192 const t_uchar * archive,
193 const t_uchar * version,
194 int for_add)
195 {
196 rel_table answer = rel_table_nil;
197 t_uchar * branch = 0;
198 rel_table branch_dirs = rel_table_nil;
199 int x;
200
201 invariant (arch_valid_package_name (version, arch_no_archive, arch_req_version, 0));
202
203 branch = arch_parse_package_name (arch_ret_package, 0, version);
204
205 branch_dirs = arch_library_branch_dirs (opt_lib_path, archive, branch, for_add);
206 if (!rel_n_records (branch_dirs))
207 return rel_table_nil;
208
209 for (x = 0; x < rel_n_records (branch_dirs); ++x)
210 {
211 const t_uchar * branch_dir;
212 t_uchar * maybe_version_dir = 0;
213
214 branch_dir = rel_peek_str (branch_dirs, x, 0);
215 maybe_version_dir = file_name_in_vicinity (0, branch_dir, version);
216
217 if (!safe_access (maybe_version_dir, F_OK))
218 {
219 rel_add_records (&answer, rel_singleton_record_taking (rel_make_field_str (maybe_version_dir)), rel_record_null);
220 }
221
222 lim_free (0, maybe_version_dir);
223 }
224
225 if (for_add && !rel_n_records (answer))
226 {
227 const t_uchar * priority_branch_dir;
228 t_uchar * version_dir = 0;
229
230 priority_branch_dir = rel_peek_str (branch_dirs, 0, 0);
231 version_dir = file_name_in_vicinity (0, priority_branch_dir, version);
232 rel_add_records (&answer, rel_singleton_record_taking (rel_make_field_str (version_dir)), rel_record_null);
233
234 lim_free (0, version_dir);
235 }
236
237 rel_free_table (branch_dirs);
238 lim_free (0, branch);
239
240 return answer;
241 }
242
243
244 rel_table
arch_library_revision_dirs(rel_table opt_lib_path,const t_uchar * archive,const t_uchar * revision,int for_add)245 arch_library_revision_dirs (rel_table opt_lib_path,
246 const t_uchar * archive,
247 const t_uchar * revision,
248 int for_add)
249 {
250 rel_table answer = rel_table_nil;
251 t_uchar * version = 0;
252 rel_table version_dirs = rel_table_nil;
253 int x;
254
255 invariant (arch_valid_package_name (revision, arch_no_archive, arch_req_patch_level, 0));
256
257 version = arch_parse_package_name (arch_ret_package_version, 0, revision);
258
259 version_dirs = arch_library_version_dirs (opt_lib_path, archive, version, for_add);
260 if (!rel_n_records (version_dirs))
261 return rel_table_nil;
262
263 for (x = 0; x < rel_n_records (version_dirs); ++x)
264 {
265 const t_uchar * version_dir;
266 t_uchar * maybe_revision_dir = 0;
267
268 version_dir = rel_peek_str (version_dirs, x, 0);
269 maybe_revision_dir = file_name_in_vicinity (0, version_dir, revision);
270
271 if (!safe_access (maybe_revision_dir, F_OK))
272 {
273 rel_add_records (&answer, rel_singleton_record_taking (rel_make_field_str (maybe_revision_dir)), rel_record_null);
274 }
275
276 lim_free (0, maybe_revision_dir);
277 }
278
279 if (for_add && !rel_n_records (answer))
280 {
281 const t_uchar * priority_version_dir;
282 t_uchar * revision_dir = 0;
283
284 priority_version_dir = rel_peek_str (version_dirs, 0, 0);
285 revision_dir = file_name_in_vicinity (0, priority_version_dir, revision);
286 rel_add_records (&answer, rel_singleton_record_taking (rel_make_field_str (revision_dir)), rel_record_null);
287
288 lim_free (0, revision_dir);
289 }
290
291 rel_free_table (version_dirs);
292 lim_free (0, version);
293
294 return answer;
295 }
296
297
298
299 t_uchar *
arch_library_find(rel_table opt_lib_path,const t_uchar * archive,const t_uchar * revision,int check_inode_sigs)300 arch_library_find (rel_table opt_lib_path,
301 const t_uchar * archive,
302 const t_uchar * revision,
303 int check_inode_sigs)
304 {
305 rel_table revision_dirs = rel_table_nil;
306 t_uchar * answer = 0;
307 int x;
308
309 revision_dirs = arch_library_revision_dirs (opt_lib_path, archive, revision, 0);
310
311 for (x = 0; x < rel_n_records (revision_dirs); ++x)
312 {
313 if (!safe_access (rel_peek_str (revision_dirs, x, 0), F_OK))
314 {
315 if (check_inode_sigs) {
316 if (!arch_valid_inode_sig (rel_peek_str (revision_dirs, 0, 0), archive, revision))
317 {
318 safe_printfmt (2, "corrupt library (failed inode signature validation)\n archive: %s\n revision: %s\nYou should remove this revision from your library.\n",
319 archive, revision);
320 exit (2);
321 }
322 }
323 answer = str_save (0, rel_peek_str (revision_dirs, 0, 0));
324 break;
325 }
326 }
327
328 rel_free_table (revision_dirs);
329 return answer;
330 }
331
332
333
334 t_uchar *
arch_library_find_file(const t_uchar * archive,const t_uchar * revision,const t_uchar * loc)335 arch_library_find_file (const t_uchar * archive,
336 const t_uchar * revision,
337 const t_uchar * loc)
338 {
339 t_uchar * revision_dir = 0;
340 t_uchar * file_path = 0;
341
342 revision_dir = arch_library_find (rel_table_nil, archive, revision, 1);
343
344 if (revision_dir)
345 {
346 file_path = file_name_in_vicinity (0, revision_dir, loc);
347
348 if (safe_access (file_path, F_OK))
349 {
350 lim_free (0, file_path);
351 file_path = 0;
352 }
353 }
354
355 lim_free (0, revision_dir);
356
357 return file_path;
358 }
359
360
361 t_uchar *
arch_library_find_file_by_id(const t_uchar * archive,const t_uchar * revision,const t_uchar * id)362 arch_library_find_file_by_id (const t_uchar * archive,
363 const t_uchar * revision,
364 const t_uchar * id)
365 {
366 t_uchar * revision_dir = 0;
367 t_uchar * file_path = 0;
368
369 revision_dir = arch_library_find (rel_table_nil, archive, revision, 1);
370
371 if (revision_dir)
372 {
373 t_uchar * index_file = 0;
374 rel_table index = rel_table_nil;
375 int x;
376
377 index_file = arch_library_index_file (archive, revision);
378 index = arch_read_changeset_index (index_file);
379
380 for (x = 0; x < rel_n_records (index); ++x)
381 {
382 if (!str_cmp (id, rel_peek_str (index, x, 1)))
383 {
384 file_path = file_name_in_vicinity (0, revision_dir, rel_peek_str (index, x, 0));
385 break;
386 }
387 }
388
389 lim_free (0, index_file);
390 rel_free_table (index);
391 }
392
393 lim_free (0, revision_dir);
394
395 return file_path;
396 }
397
398
399
400 rel_table
arch_library_archives(void)401 arch_library_archives (void)
402 {
403 rel_table lib_path = rel_table_nil;
404 rel_table answer = rel_table_nil;
405 int x;
406
407 lib_path = arch_my_library_path (arch_library_path_search_order);
408
409 for (x = 0; x < rel_n_records (lib_path); ++x)
410 {
411 rel_table tmp = rel_table_nil;
412 rel_table files = rel_table_nil;
413
414 files = directory_files (rel_peek_str (lib_path, x, 0));
415 tmp = arch_pick_archives_by_field (files, 0);
416
417 rel_append_x (&answer, tmp);
418
419 rel_free_table (tmp);
420 rel_free_table (files);
421 }
422
423 rel_sort_table_by_field (0, answer, 0);
424 rel_uniq_by_field (&answer, 0);
425
426 rel_free_table (lib_path);
427 return answer;
428 }
429
430
431 rel_table
arch_library_categories(const t_uchar * archive)432 arch_library_categories (const t_uchar * archive)
433 {
434 rel_table answer = rel_table_nil;
435 rel_table archive_dirs = rel_table_nil;
436 int x;
437
438 archive_dirs = arch_library_archive_dirs (rel_table_nil, archive, 0);
439
440 for (x = 0; x < rel_n_records (archive_dirs); ++x)
441 {
442 rel_table files = rel_table_nil;
443 rel_table tmp = rel_table_nil;
444
445 files = directory_files (rel_peek_str (archive_dirs, x, 0));
446 tmp = arch_pick_categories_by_field (files, 0);
447 rel_append_x (&answer, tmp);
448
449 rel_free_table (files);
450 rel_free_table (tmp);
451 }
452
453 rel_sort_table_by_field (0, answer, 0);
454 rel_uniq_by_field (&answer, 0);
455
456 rel_free_table (archive_dirs);
457
458 return answer;
459 }
460
461
462 rel_table
arch_library_branches(const t_uchar * archive,const t_uchar * category)463 arch_library_branches (const t_uchar * archive,
464 const t_uchar * category)
465 {
466 rel_table answer = rel_table_nil;
467 rel_table category_dirs = rel_table_nil;
468 int x;
469
470 category_dirs = arch_library_category_dirs (rel_table_nil, archive, category, 0);
471
472 for (x = 0; x < rel_n_records (category_dirs); ++x)
473 {
474 rel_table files = rel_table_nil;
475 rel_table tmp = rel_table_nil;
476
477 files = directory_files (rel_peek_str (category_dirs, x, 0));
478 tmp = arch_pick_branches_by_field (files, 0);
479 rel_append_x (&answer, tmp);
480
481 rel_free_table (files);
482 rel_free_table (tmp);
483 }
484
485 rel_sort_table_by_field (0, answer, 0);
486 rel_uniq_by_field (&answer, 0);
487
488 rel_free_table (category_dirs);
489
490 return answer;
491 }
492
493
494 rel_table
arch_library_versions(const t_uchar * archive,const t_uchar * branch)495 arch_library_versions (const t_uchar * archive,
496 const t_uchar * branch)
497 {
498 rel_table answer = rel_table_nil;
499 rel_table branch_dirs = rel_table_nil;
500 int x;
501
502 branch_dirs = arch_library_branch_dirs (rel_table_nil, archive, branch, 0);
503
504 for (x = 0; x < rel_n_records (branch_dirs); ++x)
505 {
506 rel_table files = rel_table_nil;
507 rel_table tmp = rel_table_nil;
508
509 files = directory_files (rel_peek_str (branch_dirs, x, 0));
510 tmp = arch_pick_versions_by_field (files, 0);
511 rel_append_x (&answer, tmp);
512
513 rel_free_table (files);
514 rel_free_table (tmp);
515 }
516
517 rel_sort_table_by_field (0, answer, 0);
518 rel_uniq_by_field (&answer, 0);
519
520 rel_free_table (branch_dirs);
521
522 return answer;
523 }
524
525
526 rel_table
arch_library_revisions(const t_uchar * archive,const t_uchar * version,int full)527 arch_library_revisions (const t_uchar * archive,
528 const t_uchar * version,
529 int full)
530 {
531 rel_table answer = rel_table_nil;
532 rel_table version_dirs = rel_table_nil;
533 int x;
534
535 version_dirs = arch_library_version_dirs (rel_table_nil, archive, version, 0);
536
537 for (x = 0; x < rel_n_records (version_dirs); ++x)
538 {
539 rel_table files = rel_table_nil;
540 rel_table tmp = rel_table_nil;
541 int y;
542
543 files = directory_files (rel_peek_str (version_dirs, x, 0));
544 tmp = arch_pick_revisions_by_field (files, 0);
545
546 for (y = 0; y < rel_n_records (tmp); ++y)
547 {
548 t_uchar * t = 0;
549
550 if (full)
551 {
552 t = arch_fully_qualify (archive, rel_peek_str (tmp, y, 0));
553 rel_set_taking (tmp, y, 0, rel_make_field_str (t));
554 }
555 else
556 {
557 t = arch_parse_package_name (arch_ret_patch_level, 0, rel_peek_str (tmp, y, 0));
558 rel_set_taking (tmp, y, 0, rel_make_field_str (t));
559 }
560
561 lim_free (0, t);
562 }
563
564 rel_append_x (&answer, tmp);
565
566 rel_free_table (files);
567 rel_free_table (tmp);
568 }
569
570 if (full)
571 {
572 arch_sort_table_by_name_field (0, answer, 0);
573 }
574 else
575 {
576 arch_sort_table_by_patch_level_field (0, answer, 0);
577 }
578 rel_uniq_by_field (&answer, 0);
579
580 rel_free_table (version_dirs);
581
582 return answer;
583 }
584
585
586
587 t_uchar *
arch_library_log(const t_uchar * archive,const t_uchar * revision)588 arch_library_log (const t_uchar * archive,
589 const t_uchar * revision)
590 {
591 t_uchar * rev_dir = 0;
592 t_uchar * log_path = 0;
593 int in_fd;
594 t_uchar * answer = 0;
595 size_t len;
596
597 rev_dir = arch_library_find (rel_table_nil, archive, revision, 1);
598 log_path = arch_log_file (rev_dir, archive, revision);
599 in_fd = safe_open (log_path, O_RDONLY, 0);
600 safe_file_to_string (&answer, &len, in_fd);
601 answer = lim_realloc (0, answer, len + 1);
602 answer[len] = 0;
603 safe_close (in_fd);
604
605 lim_free (0, rev_dir);
606 lim_free (0, log_path);
607 return answer;
608 }
609
610
611 t_uchar *
arch_library_index_file(const t_uchar * archive,const t_uchar * revision)612 arch_library_index_file (const t_uchar * archive,
613 const t_uchar * revision)
614 {
615 t_uchar * revision_dir = 0;
616 t_uchar * answer = 0;
617
618 revision_dir = arch_library_find (rel_table_nil, archive, revision, 1);
619 invariant (!!revision_dir);
620
621 answer = file_name_in_vicinity (0, revision_dir, ",,index");
622
623 lim_free (0, revision_dir);
624 return answer;
625 }
626
627
628 rel_table
arch_library_index(const t_uchar * archive,const t_uchar * revision)629 arch_library_index (const t_uchar * archive,
630 const t_uchar * revision)
631 {
632 t_uchar * index_path = 0;
633 rel_table answer = rel_table_nil;
634
635 index_path = arch_library_index_file (archive, revision);
636 answer = arch_read_changeset_index (index_path);
637
638 lim_free (0, index_path);
639 return answer;
640 }
641
642
643
644 int
arch_library_has_archive(const t_uchar * lib,const t_uchar * archive)645 arch_library_has_archive (const t_uchar * lib,
646 const t_uchar * archive)
647 {
648 t_uchar * path = file_name_in_vicinity (0, lib, archive);
649 int answer;
650
651 answer = !safe_access (path, F_OK);
652
653 lim_free (0, path);
654 return answer;
655 }
656
657
658 int
arch_library_has_category(const t_uchar * lib,const t_uchar * archive,const t_uchar * category)659 arch_library_has_category (const t_uchar * lib,
660 const t_uchar * archive,
661 const t_uchar * category)
662 {
663 t_uchar * archive_path = file_name_in_vicinity (0, lib, archive);
664 t_uchar * category_path = file_name_in_vicinity (0, archive_path, category);
665 int answer;
666
667 answer = !safe_access (category_path, F_OK);
668
669 lim_free (0, archive_path);
670 lim_free (0, category_path);
671 return answer;
672 }
673
674
675 int
arch_library_has_branch(const t_uchar * lib,const t_uchar * archive,const t_uchar * branch)676 arch_library_has_branch (const t_uchar * lib,
677 const t_uchar * archive,
678 const t_uchar * branch)
679 {
680 t_uchar * category = arch_parse_package_name (arch_ret_category, 0, branch);
681 t_uchar * archive_path = file_name_in_vicinity (0, lib, archive);
682 t_uchar * category_path = file_name_in_vicinity (0, archive_path, category);
683 t_uchar * branch_path = file_name_in_vicinity (0, category_path, branch);
684 int answer;
685
686 answer = !safe_access (branch_path, F_OK);
687
688 lim_free (0, category);
689
690 lim_free (0, archive_path);
691 lim_free (0, category_path);
692 lim_free (0, branch_path);
693 return answer;
694 }
695
696
697 int
arch_library_has_version(const t_uchar * lib,const t_uchar * archive,const t_uchar * version)698 arch_library_has_version (const t_uchar * lib,
699 const t_uchar * archive,
700 const t_uchar * version)
701 {
702 t_uchar * category = arch_parse_package_name (arch_ret_category, 0, version);
703 t_uchar * branch = arch_parse_package_name (arch_ret_package, 0, version);
704 t_uchar * archive_path = file_name_in_vicinity (0, lib, archive);
705 t_uchar * category_path = file_name_in_vicinity (0, archive_path, category);
706 t_uchar * branch_path = file_name_in_vicinity (0, category_path, branch);
707 t_uchar * version_path = file_name_in_vicinity (0, branch_path, version);
708 int answer;
709
710 answer = !safe_access (version_path, F_OK);
711
712 lim_free (0, category);
713 lim_free (0, branch);
714
715 lim_free (0, archive_path);
716 lim_free (0, category_path);
717 lim_free (0, branch_path);
718 lim_free (0, version_path);
719 return answer;
720 }
721
722
723 t_uchar *
arch_library_revision_dir_in_lib(const t_uchar * lib,const t_uchar * archive,const t_uchar * revision)724 arch_library_revision_dir_in_lib (const t_uchar * lib,
725 const t_uchar * archive,
726 const t_uchar * revision)
727 {
728 t_uchar * category = arch_parse_package_name (arch_ret_category, 0, revision);
729 t_uchar * branch = arch_parse_package_name (arch_ret_package, 0, revision);
730 t_uchar * version = arch_parse_package_name (arch_ret_package_version, 0, revision);
731 t_uchar * archive_path = file_name_in_vicinity (0, lib, archive);
732 t_uchar * category_path = file_name_in_vicinity (0, archive_path, category);
733 t_uchar * branch_path = file_name_in_vicinity (0, category_path, branch);
734 t_uchar * version_path = file_name_in_vicinity (0, branch_path, version);
735 t_uchar * revision_path = file_name_in_vicinity (0, version_path, revision);
736
737 lim_free (0, category);
738 lim_free (0, branch);
739 lim_free (0, version);
740
741 lim_free (0, archive_path);
742 lim_free (0, category_path);
743 lim_free (0, branch_path);
744 lim_free (0, version_path);
745
746 return revision_path;
747 }
748
749
750
751 int
arch_library_is_greedy(const t_uchar * lib)752 arch_library_is_greedy (const t_uchar * lib)
753 {
754 t_uchar * greed_path = file_name_in_vicinity (0, lib, "=greedy");
755 int answer = 0;
756
757 answer = !safe_access (greed_path, F_OK);
758
759 lim_free (0, greed_path);
760
761 return answer;
762 }
763
764
765 void
arch_set_library_greediness(const t_uchar * lib,int setting)766 arch_set_library_greediness (const t_uchar * lib,
767 int setting)
768 {
769 t_uchar * greed_path = file_name_in_vicinity (0, lib, "=greedy");
770
771 if (setting)
772 {
773 int fd;
774
775 fd = safe_open (greed_path, O_RDONLY | O_CREAT, 0666);
776 safe_close (fd);
777 }
778 else
779 {
780 if (!safe_access (greed_path, F_OK))
781 safe_unlink (greed_path);
782 }
783
784 lim_free (0, greed_path);
785 }
786
787
788 int
arch_library_is_sparse(const t_uchar * lib)789 arch_library_is_sparse (const t_uchar * lib)
790 {
791 t_uchar * sparse_path = file_name_in_vicinity (0, lib, "=sparse");
792 int answer = 0;
793
794 answer = !safe_access (sparse_path, F_OK);
795
796 lim_free (0, sparse_path);
797
798 return answer;
799 }
800
801
802 void
arch_set_library_sparseness(const t_uchar * lib,int setting)803 arch_set_library_sparseness (const t_uchar * lib,
804 int setting)
805 {
806 t_uchar * sparse_path = file_name_in_vicinity (0, lib, "=sparse");
807
808 if (setting)
809 {
810 int fd;
811
812 fd = safe_open (sparse_path, O_RDONLY | O_CREAT, 0666);
813 safe_close (fd);
814 }
815 else
816 {
817 if (!safe_access (sparse_path, F_OK))
818 safe_unlink (sparse_path);
819 }
820
821 lim_free (0, sparse_path);
822 }
823
824
825
826
827 void
arch_verify_is_library(const t_uchar * lib)828 arch_verify_is_library (const t_uchar * lib)
829 {
830 rel_table lib_path = rel_table_nil;
831 int x;
832
833 lib_path = arch_my_library_path (arch_library_path_search_order);
834
835 for (x = 0; x < rel_n_records (lib_path); ++x)
836 {
837 if (names_same_inode (lib, rel_peek_str (lib_path, x, 0)))
838 return;
839 }
840
841 safe_printfmt (2, "tla: indicated library is not on library path\n dir %s\n", lib);
842 exit (2);
843 }
844
845
846
847 /* tag: Tom Lord Wed May 21 13:56:29 2003 (libraries.c)
848 */
849