1 /* arsup.c - Archive support for MRI compatibility
2 Copyright (C) 1992-2021 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
22 /* Contributed by Steve Chamberlain
25 This file looks after requests from arparse.y, to provide the MRI
26 style librarian command syntax + 1 word LIST. */
30 #include "libiberty.h"
31 #include "filenames.h"
35 static void map_over_list
36 (bfd
*, void (*function
) (bfd
*, bfd
*), struct list
*);
37 static void ar_directory_doer (bfd
*, bfd
*);
38 static void ar_addlib_doer (bfd
*, bfd
*);
41 extern int deterministic
;
44 static char *real_name
;
45 static char *temp_name
;
50 map_over_list (bfd
*arch
, void (*function
) (bfd
*, bfd
*), struct list
*list
)
58 head
= arch
->archive_next
;
61 next
= head
->archive_next
;
62 function (head
, (bfd
*) NULL
);
70 /* This may appear to be a baroque way of accomplishing what we
71 want. however we have to iterate over the filenames in order
72 to notice where a filename is requested but does not exist in
73 the archive. Ditto mapping over each file each time -- we
74 want to hack multiple references. */
75 for (ptr
= list
; ptr
; ptr
= ptr
->next
)
77 bfd_boolean found
= FALSE
;
80 for (head
= arch
->archive_next
; head
; head
= head
->archive_next
)
82 if (bfd_get_filename (head
) != NULL
83 && FILENAME_CMP (ptr
->name
, bfd_get_filename (head
)) == 0)
86 function (head
, prev
);
91 fprintf (stderr
, _("No entry %s in archive.\n"), ptr
->name
);
99 ar_directory_doer (bfd
*abfd
, bfd
*ignore ATTRIBUTE_UNUSED
)
101 print_arelt_descr(outfile
, abfd
, verbose
, FALSE
);
105 ar_directory (char *ar_name
, struct list
*list
, char *output
)
109 arch
= open_inarch (ar_name
, (char *) NULL
);
112 outfile
= fopen(output
,"w");
116 fprintf (stderr
,_("Can't open file %s\n"), output
);
123 map_over_list (arch
, ar_directory_doer
, list
);
134 extern int interactive
;
152 ar_open (char *name
, int t
)
154 real_name
= xstrdup (name
);
155 temp_name
= make_tempname (real_name
, &real_ofd
);
157 if (temp_name
== NULL
)
159 fprintf (stderr
, _("%s: Can't open temporary file (%s)\n"),
160 program_name
, strerror(errno
));
165 obfd
= bfd_fdopenw (temp_name
, NULL
, real_ofd
);
170 _("%s: Can't open output archive %s\n"),
171 program_name
, temp_name
);
183 ibfd
= bfd_openr (name
, NULL
);
187 fprintf (stderr
,_("%s: Can't open input archive %s\n"),
193 if (!bfd_check_format(ibfd
, bfd_archive
))
196 _("%s: file %s is not an archive\n"),
202 ptr
= &(obfd
->archive_head
);
203 element
= bfd_openr_next_archived_file (ibfd
, NULL
);
208 ptr
= &element
->archive_next
;
209 element
= bfd_openr_next_archived_file (ibfd
, element
);
213 bfd_set_format (obfd
, bfd_archive
);
216 obfd
->is_thin_archive
= 0;
221 ar_addlib_doer (bfd
*abfd
, bfd
*prev
)
223 /* Add this module to the output bfd. */
225 prev
->archive_next
= abfd
->archive_next
;
227 abfd
->archive_next
= obfd
->archive_head
;
228 obfd
->archive_head
= abfd
;
232 ar_addlib (char *name
, struct list
*list
)
236 fprintf (stderr
, _("%s: no output archive specified yet\n"), program_name
);
243 arch
= open_inarch (name
, (char *) NULL
);
245 map_over_list (arch
, ar_addlib_doer
, list
);
247 /* Don't close the bfd, since it will make the elements disappear. */
252 ar_addmod (struct list
*list
)
256 fprintf (stderr
, _("%s: no open output archive\n"), program_name
);
265 #if BFD_SUPPORTS_PLUGINS
266 abfd
= bfd_openr (list
->name
, "plugin");
268 abfd
= bfd_openr (list
->name
, NULL
);
272 fprintf (stderr
, _("%s: can't open file %s\n"),
273 program_name
, list
->name
);
278 abfd
->archive_next
= obfd
->archive_head
;
279 obfd
->archive_head
= abfd
;
291 obfd
->archive_head
= 0;
295 ar_delete (struct list
*list
)
299 fprintf (stderr
, _("%s: no open output archive\n"), program_name
);
306 /* Find this name in the archive. */
307 bfd
*member
= obfd
->archive_head
;
308 bfd
**prev
= &(obfd
->archive_head
);
313 if (FILENAME_CMP (bfd_get_filename (member
), list
->name
) == 0)
315 *prev
= member
->archive_next
;
319 prev
= &(member
->archive_next
);
321 member
= member
->archive_next
;
326 fprintf (stderr
, _("%s: can't find module file %s\n"),
327 program_name
, list
->name
);
341 fprintf (stderr
, _("%s: no open output archive\n"), program_name
);
346 bfd_boolean skip_stat
= FALSE
;
347 struct stat target_stat
;
350 if (deterministic
> 0)
351 obfd
->flags
|= BFD_DETERMINISTIC_OUTPUT
;
353 #if !defined (_WIN32) || defined (__CYGWIN32__)
354 /* It's OK to fail; at worst it will result in SMART_RENAME using a slow
355 copy fallback to write the output. */
360 if (lstat (real_name
, &target_stat
) != 0)
362 /* The temp file created in ar_open has mode 0600 as per mkstemp.
363 Create the real empty output file here so smart_rename will
364 update the mode according to the process umask. */
365 obfd
= bfd_openw (real_name
, NULL
);
367 || bfd_stat (obfd
, &target_stat
) != 0)
371 bfd_set_format (obfd
, bfd_archive
);
376 smart_rename (temp_name
, real_name
, ofd
,
377 skip_stat
? NULL
: &target_stat
, 0);
385 ar_replace (struct list
*list
)
389 fprintf (stderr
, _("%s: no open output archive\n"), program_name
);
396 /* Find this name in the archive. */
397 bfd
*member
= obfd
->archive_head
;
398 bfd
**prev
= &(obfd
->archive_head
);
403 if (FILENAME_CMP (bfd_get_filename (member
), list
->name
) == 0)
405 /* Found the one to replace. */
406 bfd
*abfd
= bfd_openr (list
->name
, NULL
);
410 fprintf (stderr
, _("%s: can't open file %s\n"),
411 program_name
, list
->name
);
417 abfd
->archive_next
= member
->archive_next
;
423 prev
= &(member
->archive_next
);
425 member
= member
->archive_next
;
430 bfd
*abfd
= bfd_openr (list
->name
, NULL
);
432 fprintf (stderr
,_("%s: can't find module file %s\n"),
433 program_name
, list
->name
);
436 fprintf (stderr
, _("%s: can't open file %s\n"),
437 program_name
, list
->name
);
449 /* And I added this one. */
455 fprintf (stderr
, _("%s: no open output archive\n"), program_name
);
464 printf (_("Current open archive is %s\n"), bfd_get_filename (obfd
));
466 for (abfd
= obfd
->archive_head
;
468 abfd
= abfd
->archive_next
)
469 ar_directory_doer (abfd
, (bfd
*) NULL
);
478 bfd_cache_close (obfd
);
479 unlink (bfd_get_filename (obfd
));
484 ar_extract (struct list
*list
)
488 fprintf (stderr
, _("%s: no open archive\n"), program_name
);
495 /* Find this name in the archive. */
496 bfd
*member
= obfd
->archive_head
;
499 while (member
&& !found
)
501 if (FILENAME_CMP (bfd_get_filename (member
), list
->name
) == 0)
503 extract_file (member
);
507 member
= member
->archive_next
;
512 bfd_openr (list
->name
, NULL
);
513 fprintf (stderr
, _("%s: can't find module file %s\n"),
514 program_name
, list
->name
);
This page took 0.088192 seconds and 5 git commands to generate.