12a6b7db3Sskrll /* arsup.c - Archive support for MRI compatibility
2*e072ec67Schristos    Copyright (C) 1992-2022 Free Software Foundation, Inc.
32a6b7db3Sskrll 
42a6b7db3Sskrll    This file is part of GNU Binutils.
52a6b7db3Sskrll 
62a6b7db3Sskrll    This program is free software; you can redistribute it and/or modify
72a6b7db3Sskrll    it under the terms of the GNU General Public License as published by
82a6b7db3Sskrll    the Free Software Foundation; either version 3 of the License, or
92a6b7db3Sskrll    (at your option) any later version.
102a6b7db3Sskrll 
112a6b7db3Sskrll    This program is distributed in the hope that it will be useful,
122a6b7db3Sskrll    but WITHOUT ANY WARRANTY; without even the implied warranty of
132a6b7db3Sskrll    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
142a6b7db3Sskrll    GNU General Public License for more details.
152a6b7db3Sskrll 
162a6b7db3Sskrll    You should have received a copy of the GNU General Public License
172a6b7db3Sskrll    along with this program; if not, write to the Free Software
182a6b7db3Sskrll    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
192a6b7db3Sskrll    MA 02110-1301, USA.  */
202a6b7db3Sskrll 
212a6b7db3Sskrll 
222a6b7db3Sskrll /* Contributed by Steve Chamberlain
232a6b7db3Sskrll    sac@cygnus.com
242a6b7db3Sskrll 
252a6b7db3Sskrll    This file looks after requests from arparse.y, to provide the MRI
262a6b7db3Sskrll    style librarian command syntax + 1 word LIST.  */
272a6b7db3Sskrll 
282a6b7db3Sskrll #include "sysdep.h"
292a6b7db3Sskrll #include "bfd.h"
302a6b7db3Sskrll #include "libiberty.h"
312a6b7db3Sskrll #include "filenames.h"
322a6b7db3Sskrll #include "bucomm.h"
332a6b7db3Sskrll #include "arsup.h"
342a6b7db3Sskrll 
352a6b7db3Sskrll static void map_over_list
362a6b7db3Sskrll   (bfd *, void (*function) (bfd *, bfd *), struct list *);
372a6b7db3Sskrll static void ar_directory_doer (bfd *, bfd *);
382a6b7db3Sskrll static void ar_addlib_doer (bfd *, bfd *);
392a6b7db3Sskrll 
402a6b7db3Sskrll extern int verbose;
41438aacb6Schristos extern int deterministic;
422a6b7db3Sskrll 
432a6b7db3Sskrll static bfd *obfd;
442a6b7db3Sskrll static char *real_name;
45*e072ec67Schristos static char *temp_name;
46*e072ec67Schristos static int temp_fd;
472a6b7db3Sskrll static FILE *outfile;
482a6b7db3Sskrll 
492a6b7db3Sskrll static void
map_over_list(bfd * arch,void (* function)(bfd *,bfd *),struct list * list)502a6b7db3Sskrll map_over_list (bfd *arch, void (*function) (bfd *, bfd *), struct list *list)
512a6b7db3Sskrll {
522a6b7db3Sskrll   bfd *head;
532a6b7db3Sskrll 
542a6b7db3Sskrll   if (list == NULL)
552a6b7db3Sskrll     {
562a6b7db3Sskrll       bfd *next;
572a6b7db3Sskrll 
582a6b7db3Sskrll       head = arch->archive_next;
592a6b7db3Sskrll       while (head != NULL)
602a6b7db3Sskrll 	{
612a6b7db3Sskrll 	  next = head->archive_next;
622a6b7db3Sskrll 	  function (head, (bfd *) NULL);
632a6b7db3Sskrll 	  head = next;
642a6b7db3Sskrll 	}
652a6b7db3Sskrll     }
662a6b7db3Sskrll   else
672a6b7db3Sskrll     {
682a6b7db3Sskrll       struct list *ptr;
692a6b7db3Sskrll 
702a6b7db3Sskrll       /* This may appear to be a baroque way of accomplishing what we
712a6b7db3Sskrll 	 want.  however we have to iterate over the filenames in order
722a6b7db3Sskrll 	 to notice where a filename is requested but does not exist in
732a6b7db3Sskrll 	 the archive.  Ditto mapping over each file each time -- we
742a6b7db3Sskrll 	 want to hack multiple references.  */
752a6b7db3Sskrll       for (ptr = list; ptr; ptr = ptr->next)
762a6b7db3Sskrll 	{
77*e072ec67Schristos 	  bool found = false;
782a6b7db3Sskrll 	  bfd *prev = arch;
792a6b7db3Sskrll 
802a6b7db3Sskrll 	  for (head = arch->archive_next; head; head = head->archive_next)
812a6b7db3Sskrll 	    {
82*e072ec67Schristos 	      if (bfd_get_filename (head) != NULL
83*e072ec67Schristos 		  && FILENAME_CMP (ptr->name, bfd_get_filename (head)) == 0)
842a6b7db3Sskrll 		{
85*e072ec67Schristos 		  found = true;
862a6b7db3Sskrll 		  function (head, prev);
872a6b7db3Sskrll 		}
882a6b7db3Sskrll 	      prev = head;
892a6b7db3Sskrll 	    }
902a6b7db3Sskrll 	  if (! found)
912a6b7db3Sskrll 	    fprintf (stderr, _("No entry %s in archive.\n"), ptr->name);
922a6b7db3Sskrll 	}
932a6b7db3Sskrll     }
942a6b7db3Sskrll }
952a6b7db3Sskrll 
962a6b7db3Sskrll 
972a6b7db3Sskrll 
982a6b7db3Sskrll static void
ar_directory_doer(bfd * abfd,bfd * ignore ATTRIBUTE_UNUSED)992a6b7db3Sskrll ar_directory_doer (bfd *abfd, bfd *ignore ATTRIBUTE_UNUSED)
1002a6b7db3Sskrll {
101*e072ec67Schristos   print_arelt_descr(outfile, abfd, verbose, false);
1022a6b7db3Sskrll }
1032a6b7db3Sskrll 
1042a6b7db3Sskrll void
ar_directory(char * ar_name,struct list * list,char * output)1052a6b7db3Sskrll ar_directory (char *ar_name, struct list *list, char *output)
1062a6b7db3Sskrll {
1072a6b7db3Sskrll   bfd *arch;
1082a6b7db3Sskrll 
1092a6b7db3Sskrll   arch = open_inarch (ar_name, (char *) NULL);
1102a6b7db3Sskrll   if (output)
1112a6b7db3Sskrll     {
1122a6b7db3Sskrll       outfile = fopen(output,"w");
1132a6b7db3Sskrll       if (outfile == 0)
1142a6b7db3Sskrll 	{
1152a6b7db3Sskrll 	  outfile = stdout;
1162a6b7db3Sskrll 	  fprintf (stderr,_("Can't open file %s\n"), output);
1172a6b7db3Sskrll 	  output = 0;
1182a6b7db3Sskrll 	}
1192a6b7db3Sskrll     }
1202a6b7db3Sskrll   else
1212a6b7db3Sskrll     outfile = stdout;
1222a6b7db3Sskrll 
1232a6b7db3Sskrll   map_over_list (arch, ar_directory_doer, list);
1242a6b7db3Sskrll 
1252a6b7db3Sskrll   bfd_close (arch);
1262a6b7db3Sskrll 
1272a6b7db3Sskrll   if (output)
1282a6b7db3Sskrll    fclose (outfile);
1292a6b7db3Sskrll }
1302a6b7db3Sskrll 
1312a6b7db3Sskrll void
prompt(void)1322a6b7db3Sskrll prompt (void)
1332a6b7db3Sskrll {
1342a6b7db3Sskrll   extern int interactive;
1352a6b7db3Sskrll 
1362a6b7db3Sskrll   if (interactive)
1372a6b7db3Sskrll     {
1382a6b7db3Sskrll       printf ("AR >");
1392a6b7db3Sskrll       fflush (stdout);
1402a6b7db3Sskrll     }
1412a6b7db3Sskrll }
1422a6b7db3Sskrll 
1432a6b7db3Sskrll void
maybequit(void)1442a6b7db3Sskrll maybequit (void)
1452a6b7db3Sskrll {
1462a6b7db3Sskrll   if (! interactive)
1472a6b7db3Sskrll     xexit (9);
1482a6b7db3Sskrll }
1492a6b7db3Sskrll 
1502a6b7db3Sskrll 
1512a6b7db3Sskrll void
ar_open(char * name,int t)1522a6b7db3Sskrll ar_open (char *name, int t)
1532a6b7db3Sskrll {
154*e072ec67Schristos   real_name = xstrdup (name);
155*e072ec67Schristos   temp_name = make_tempname (real_name, &temp_fd);
1562a6b7db3Sskrll 
157*e072ec67Schristos   if (temp_name == NULL)
15880c47ddaSchristos     {
159*e072ec67Schristos       fprintf (stderr, _("%s: Can't open temporary file (%s)\n"),
16080c47ddaSchristos 	       program_name, strerror(errno));
16180c47ddaSchristos       maybequit ();
16280c47ddaSchristos       return;
16380c47ddaSchristos     }
16480c47ddaSchristos 
165*e072ec67Schristos   obfd = bfd_fdopenw (temp_name, NULL, temp_fd);
1662a6b7db3Sskrll 
1672a6b7db3Sskrll   if (!obfd)
1682a6b7db3Sskrll     {
1692a6b7db3Sskrll       fprintf (stderr,
1702a6b7db3Sskrll 	       _("%s: Can't open output archive %s\n"),
171*e072ec67Schristos 	       program_name, temp_name);
1722a6b7db3Sskrll 
1732a6b7db3Sskrll       maybequit ();
1742a6b7db3Sskrll     }
1752a6b7db3Sskrll   else
1762a6b7db3Sskrll     {
1772a6b7db3Sskrll       if (!t)
1782a6b7db3Sskrll 	{
1792a6b7db3Sskrll 	  bfd **ptr;
1802a6b7db3Sskrll 	  bfd *element;
1812a6b7db3Sskrll 	  bfd *ibfd;
1822a6b7db3Sskrll 
183*e072ec67Schristos #if BFD_SUPPORTS_PLUGINS
184*e072ec67Schristos 	  ibfd = bfd_openr (name, "plugin");
185*e072ec67Schristos #else
1862a6b7db3Sskrll 	  ibfd = bfd_openr (name, NULL);
187*e072ec67Schristos #endif
1882a6b7db3Sskrll 
1892a6b7db3Sskrll 	  if (!ibfd)
1902a6b7db3Sskrll 	    {
1912a6b7db3Sskrll 	      fprintf (stderr,_("%s: Can't open input archive %s\n"),
1922a6b7db3Sskrll 		       program_name, name);
1932a6b7db3Sskrll 	      maybequit ();
1942a6b7db3Sskrll 	      return;
1952a6b7db3Sskrll 	    }
1962a6b7db3Sskrll 
1972a6b7db3Sskrll 	  if (!bfd_check_format(ibfd, bfd_archive))
1982a6b7db3Sskrll 	    {
1992a6b7db3Sskrll 	      fprintf (stderr,
2002a6b7db3Sskrll 		       _("%s: file %s is not an archive\n"),
2012a6b7db3Sskrll 		       program_name, name);
2022a6b7db3Sskrll 	      maybequit ();
2032a6b7db3Sskrll 	      return;
2042a6b7db3Sskrll 	    }
2052a6b7db3Sskrll 
2062a6b7db3Sskrll 	  ptr = &(obfd->archive_head);
2072a6b7db3Sskrll 	  element = bfd_openr_next_archived_file (ibfd, NULL);
2082a6b7db3Sskrll 
2092a6b7db3Sskrll 	  while (element)
2102a6b7db3Sskrll 	    {
2112a6b7db3Sskrll 	      *ptr = element;
2122a6b7db3Sskrll 	      ptr = &element->archive_next;
2132a6b7db3Sskrll 	      element = bfd_openr_next_archived_file (ibfd, element);
2142a6b7db3Sskrll 	    }
2152a6b7db3Sskrll 	}
2162a6b7db3Sskrll 
2172a6b7db3Sskrll       bfd_set_format (obfd, bfd_archive);
2182a6b7db3Sskrll 
2192a6b7db3Sskrll       obfd->has_armap = 1;
2202a6b7db3Sskrll       obfd->is_thin_archive = 0;
2212a6b7db3Sskrll     }
2222a6b7db3Sskrll }
2232a6b7db3Sskrll 
2242a6b7db3Sskrll static void
ar_addlib_doer(bfd * abfd,bfd * prev)2252a6b7db3Sskrll ar_addlib_doer (bfd *abfd, bfd *prev)
2262a6b7db3Sskrll {
2272a6b7db3Sskrll   /* Add this module to the output bfd.  */
2282a6b7db3Sskrll   if (prev != NULL)
2292a6b7db3Sskrll     prev->archive_next = abfd->archive_next;
2302a6b7db3Sskrll 
2312a6b7db3Sskrll   abfd->archive_next = obfd->archive_head;
2322a6b7db3Sskrll   obfd->archive_head = abfd;
2332a6b7db3Sskrll }
2342a6b7db3Sskrll 
2352a6b7db3Sskrll void
ar_addlib(char * name,struct list * list)2362a6b7db3Sskrll ar_addlib (char *name, struct list *list)
2372a6b7db3Sskrll {
2382a6b7db3Sskrll   if (obfd == NULL)
2392a6b7db3Sskrll     {
2402a6b7db3Sskrll       fprintf (stderr, _("%s: no output archive specified yet\n"), program_name);
2412a6b7db3Sskrll       maybequit ();
2422a6b7db3Sskrll     }
2432a6b7db3Sskrll   else
2442a6b7db3Sskrll     {
2452a6b7db3Sskrll       bfd *arch;
2462a6b7db3Sskrll 
2472a6b7db3Sskrll       arch = open_inarch (name, (char *) NULL);
2482a6b7db3Sskrll       if (arch != NULL)
2492a6b7db3Sskrll 	map_over_list (arch, ar_addlib_doer, list);
2502a6b7db3Sskrll 
2512a6b7db3Sskrll       /* Don't close the bfd, since it will make the elements disappear.  */
2522a6b7db3Sskrll     }
2532a6b7db3Sskrll }
2542a6b7db3Sskrll 
2552a6b7db3Sskrll void
ar_addmod(struct list * list)2562a6b7db3Sskrll ar_addmod (struct list *list)
2572a6b7db3Sskrll {
2582a6b7db3Sskrll   if (!obfd)
2592a6b7db3Sskrll     {
2602a6b7db3Sskrll       fprintf (stderr, _("%s: no open output archive\n"), program_name);
2612a6b7db3Sskrll       maybequit ();
2622a6b7db3Sskrll     }
2632a6b7db3Sskrll   else
2642a6b7db3Sskrll     {
2652a6b7db3Sskrll       while (list)
2662a6b7db3Sskrll 	{
267aa4b58b1Schristos 	  bfd *abfd;
2682a6b7db3Sskrll 
269aa4b58b1Schristos #if BFD_SUPPORTS_PLUGINS
270aa4b58b1Schristos 	  abfd = bfd_openr (list->name, "plugin");
271aa4b58b1Schristos #else
272aa4b58b1Schristos 	  abfd = bfd_openr (list->name, NULL);
273aa4b58b1Schristos #endif
2742a6b7db3Sskrll 	  if (!abfd)
2752a6b7db3Sskrll 	    {
2762a6b7db3Sskrll 	      fprintf (stderr, _("%s: can't open file %s\n"),
2772a6b7db3Sskrll 		       program_name, list->name);
2782a6b7db3Sskrll 	      maybequit ();
2792a6b7db3Sskrll 	    }
2802a6b7db3Sskrll 	  else
2812a6b7db3Sskrll 	    {
2822a6b7db3Sskrll 	      abfd->archive_next = obfd->archive_head;
2832a6b7db3Sskrll 	      obfd->archive_head = abfd;
2842a6b7db3Sskrll 	    }
2852a6b7db3Sskrll 	  list = list->next;
2862a6b7db3Sskrll 	}
2872a6b7db3Sskrll     }
2882a6b7db3Sskrll }
2892a6b7db3Sskrll 
2902a6b7db3Sskrll 
2912a6b7db3Sskrll void
ar_clear(void)2922a6b7db3Sskrll ar_clear (void)
2932a6b7db3Sskrll {
2942a6b7db3Sskrll   if (obfd)
2952a6b7db3Sskrll     obfd->archive_head = 0;
2962a6b7db3Sskrll }
2972a6b7db3Sskrll 
2982a6b7db3Sskrll void
ar_delete(struct list * list)2992a6b7db3Sskrll ar_delete (struct list *list)
3002a6b7db3Sskrll {
3012a6b7db3Sskrll   if (!obfd)
3022a6b7db3Sskrll     {
3032a6b7db3Sskrll       fprintf (stderr, _("%s: no open output archive\n"), program_name);
3042a6b7db3Sskrll       maybequit ();
3052a6b7db3Sskrll     }
3062a6b7db3Sskrll   else
3072a6b7db3Sskrll     {
3082a6b7db3Sskrll       while (list)
3092a6b7db3Sskrll 	{
3102a6b7db3Sskrll 	  /* Find this name in the archive.  */
3112a6b7db3Sskrll 	  bfd *member = obfd->archive_head;
3122a6b7db3Sskrll 	  bfd **prev = &(obfd->archive_head);
3132a6b7db3Sskrll 	  int found = 0;
3142a6b7db3Sskrll 
3152a6b7db3Sskrll 	  while (member)
3162a6b7db3Sskrll 	    {
317*e072ec67Schristos 	      if (FILENAME_CMP (bfd_get_filename (member), list->name) == 0)
3182a6b7db3Sskrll 		{
3192a6b7db3Sskrll 		  *prev = member->archive_next;
3202a6b7db3Sskrll 		  found = 1;
3212a6b7db3Sskrll 		}
3222a6b7db3Sskrll 	      else
3232a6b7db3Sskrll 		prev = &(member->archive_next);
3242a6b7db3Sskrll 
3252a6b7db3Sskrll 	      member = member->archive_next;
3262a6b7db3Sskrll 	    }
3272a6b7db3Sskrll 
3282a6b7db3Sskrll 	  if (!found)
3292a6b7db3Sskrll 	    {
3302a6b7db3Sskrll 	      fprintf (stderr, _("%s: can't find module file %s\n"),
3312a6b7db3Sskrll 		       program_name, list->name);
3322a6b7db3Sskrll 	      maybequit ();
3332a6b7db3Sskrll 	    }
3342a6b7db3Sskrll 
3352a6b7db3Sskrll 	  list = list->next;
3362a6b7db3Sskrll 	}
3372a6b7db3Sskrll     }
3382a6b7db3Sskrll }
3392a6b7db3Sskrll 
3402a6b7db3Sskrll void
ar_save(void)3412a6b7db3Sskrll ar_save (void)
3422a6b7db3Sskrll {
3432a6b7db3Sskrll   if (!obfd)
3442a6b7db3Sskrll     {
3452a6b7db3Sskrll       fprintf (stderr, _("%s: no open output archive\n"), program_name);
3462a6b7db3Sskrll       maybequit ();
3472a6b7db3Sskrll     }
3482a6b7db3Sskrll   else
3492a6b7db3Sskrll     {
350*e072ec67Schristos       struct stat target_stat;
3512a6b7db3Sskrll 
352438aacb6Schristos       if (deterministic > 0)
353438aacb6Schristos         obfd->flags |= BFD_DETERMINISTIC_OUTPUT;
354438aacb6Schristos 
355*e072ec67Schristos       temp_fd = dup (temp_fd);
3562a6b7db3Sskrll       bfd_close (obfd);
3572a6b7db3Sskrll 
358*e072ec67Schristos       if (stat (real_name, &target_stat) != 0)
359*e072ec67Schristos 	{
360*e072ec67Schristos 	  /* The temp file created in ar_open has mode 0600 as per mkstemp.
361*e072ec67Schristos 	     Create the real empty output file here so smart_rename will
362*e072ec67Schristos 	     update the mode according to the process umask.  */
363*e072ec67Schristos 	  obfd = bfd_openw (real_name, NULL);
364*e072ec67Schristos 	  if (obfd != NULL)
365*e072ec67Schristos 	    {
366*e072ec67Schristos 	      bfd_set_format (obfd, bfd_archive);
367*e072ec67Schristos 	      bfd_close (obfd);
368*e072ec67Schristos 	    }
369*e072ec67Schristos 	}
370*e072ec67Schristos 
371*e072ec67Schristos       smart_rename (temp_name, real_name, temp_fd, NULL, false);
3722a6b7db3Sskrll       obfd = 0;
373*e072ec67Schristos       free (temp_name);
374*e072ec67Schristos       free (real_name);
3752a6b7db3Sskrll     }
3762a6b7db3Sskrll }
3772a6b7db3Sskrll 
3782a6b7db3Sskrll void
ar_replace(struct list * list)3792a6b7db3Sskrll ar_replace (struct list *list)
3802a6b7db3Sskrll {
3812a6b7db3Sskrll   if (!obfd)
3822a6b7db3Sskrll     {
3832a6b7db3Sskrll       fprintf (stderr, _("%s: no open output archive\n"), program_name);
3842a6b7db3Sskrll       maybequit ();
3852a6b7db3Sskrll     }
3862a6b7db3Sskrll   else
3872a6b7db3Sskrll     {
3882a6b7db3Sskrll       while (list)
3892a6b7db3Sskrll 	{
3902a6b7db3Sskrll 	  /* Find this name in the archive.  */
3912a6b7db3Sskrll 	  bfd *member = obfd->archive_head;
3922a6b7db3Sskrll 	  bfd **prev = &(obfd->archive_head);
3932a6b7db3Sskrll 	  int found = 0;
3942a6b7db3Sskrll 
3952a6b7db3Sskrll 	  while (member)
3962a6b7db3Sskrll 	    {
397*e072ec67Schristos 	      if (FILENAME_CMP (bfd_get_filename (member), list->name) == 0)
3982a6b7db3Sskrll 		{
3992a6b7db3Sskrll 		  /* Found the one to replace.  */
400aa4b58b1Schristos 		  bfd *abfd = bfd_openr (list->name, NULL);
4012a6b7db3Sskrll 
4022a6b7db3Sskrll 		  if (!abfd)
4032a6b7db3Sskrll 		    {
4042a6b7db3Sskrll 		      fprintf (stderr, _("%s: can't open file %s\n"),
4052a6b7db3Sskrll 			       program_name, list->name);
4062a6b7db3Sskrll 		      maybequit ();
4072a6b7db3Sskrll 		    }
4082a6b7db3Sskrll 		  else
4092a6b7db3Sskrll 		    {
4102a6b7db3Sskrll 		      *prev = abfd;
4112a6b7db3Sskrll 		      abfd->archive_next = member->archive_next;
4122a6b7db3Sskrll 		      found = 1;
4132a6b7db3Sskrll 		    }
4142a6b7db3Sskrll 		}
4152a6b7db3Sskrll 	      else
4162a6b7db3Sskrll 		{
4172a6b7db3Sskrll 		  prev = &(member->archive_next);
4182a6b7db3Sskrll 		}
4192a6b7db3Sskrll 	      member = member->archive_next;
4202a6b7db3Sskrll 	    }
4212a6b7db3Sskrll 
4222a6b7db3Sskrll 	  if (!found)
4232a6b7db3Sskrll 	    {
424aa4b58b1Schristos 	      bfd *abfd = bfd_openr (list->name, NULL);
4252a6b7db3Sskrll 
4262a6b7db3Sskrll 	      fprintf (stderr,_("%s: can't find module file %s\n"),
4272a6b7db3Sskrll 		       program_name, list->name);
4282a6b7db3Sskrll 	      if (!abfd)
4292a6b7db3Sskrll 		{
4302a6b7db3Sskrll 		  fprintf (stderr, _("%s: can't open file %s\n"),
4312a6b7db3Sskrll 			   program_name, list->name);
4322a6b7db3Sskrll 		  maybequit ();
4332a6b7db3Sskrll 		}
4342a6b7db3Sskrll 	      else
4352a6b7db3Sskrll 		*prev = abfd;
4362a6b7db3Sskrll 	    }
4372a6b7db3Sskrll 
4382a6b7db3Sskrll 	  list = list->next;
4392a6b7db3Sskrll 	}
4402a6b7db3Sskrll     }
4412a6b7db3Sskrll }
4422a6b7db3Sskrll 
4432a6b7db3Sskrll /* And I added this one.  */
4442a6b7db3Sskrll void
ar_list(void)4452a6b7db3Sskrll ar_list (void)
4462a6b7db3Sskrll {
4472a6b7db3Sskrll   if (!obfd)
4482a6b7db3Sskrll     {
4492a6b7db3Sskrll       fprintf (stderr, _("%s: no open output archive\n"), program_name);
4502a6b7db3Sskrll       maybequit ();
4512a6b7db3Sskrll     }
4522a6b7db3Sskrll   else
4532a6b7db3Sskrll     {
4542a6b7db3Sskrll       bfd *abfd;
4552a6b7db3Sskrll 
4562a6b7db3Sskrll       outfile = stdout;
4572a6b7db3Sskrll       verbose =1 ;
4582a6b7db3Sskrll       printf (_("Current open archive is %s\n"), bfd_get_filename (obfd));
4592a6b7db3Sskrll 
4602a6b7db3Sskrll       for (abfd = obfd->archive_head;
4612a6b7db3Sskrll 	   abfd != (bfd *)NULL;
4622a6b7db3Sskrll 	   abfd = abfd->archive_next)
4632a6b7db3Sskrll 	ar_directory_doer (abfd, (bfd *) NULL);
4642a6b7db3Sskrll     }
4652a6b7db3Sskrll }
4662a6b7db3Sskrll 
4672a6b7db3Sskrll void
ar_end(void)4682a6b7db3Sskrll ar_end (void)
4692a6b7db3Sskrll {
4702a6b7db3Sskrll   if (obfd)
4712a6b7db3Sskrll     {
4722a6b7db3Sskrll       bfd_cache_close (obfd);
4732a6b7db3Sskrll       unlink (bfd_get_filename (obfd));
4742a6b7db3Sskrll     }
4752a6b7db3Sskrll }
4762a6b7db3Sskrll 
4772a6b7db3Sskrll void
ar_extract(struct list * list)4782a6b7db3Sskrll ar_extract (struct list *list)
4792a6b7db3Sskrll {
4802a6b7db3Sskrll   if (!obfd)
4812a6b7db3Sskrll     {
4822a6b7db3Sskrll       fprintf (stderr, _("%s: no open archive\n"), program_name);
4832a6b7db3Sskrll       maybequit ();
4842a6b7db3Sskrll     }
4852a6b7db3Sskrll   else
4862a6b7db3Sskrll     {
4872a6b7db3Sskrll       while (list)
4882a6b7db3Sskrll 	{
4892a6b7db3Sskrll 	  /* Find this name in the archive.  */
4902a6b7db3Sskrll 	  bfd *member = obfd->archive_head;
4912a6b7db3Sskrll 	  int found = 0;
4922a6b7db3Sskrll 
4932a6b7db3Sskrll 	  while (member && !found)
4942a6b7db3Sskrll 	    {
495*e072ec67Schristos 	      if (FILENAME_CMP (bfd_get_filename (member), list->name) == 0)
4962a6b7db3Sskrll 		{
4972a6b7db3Sskrll 		  extract_file (member);
4982a6b7db3Sskrll 		  found = 1;
4992a6b7db3Sskrll 		}
5002a6b7db3Sskrll 
5012a6b7db3Sskrll 	      member = member->archive_next;
5022a6b7db3Sskrll 	    }
5032a6b7db3Sskrll 
5042a6b7db3Sskrll 	  if (!found)
5052a6b7db3Sskrll 	    {
506aa4b58b1Schristos 	      bfd_openr (list->name, NULL);
5072a6b7db3Sskrll 	      fprintf (stderr, _("%s: can't find module file %s\n"),
5082a6b7db3Sskrll 		       program_name, list->name);
5092a6b7db3Sskrll 	    }
5102a6b7db3Sskrll 
5112a6b7db3Sskrll 	  list = list->next;
5122a6b7db3Sskrll 	}
5132a6b7db3Sskrll     }
5142a6b7db3Sskrll }
515