ar.c revision 130561
1/* ar.c - Archive modify and extract.
2   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3   2001, 2002, 2003, 2004
4   Free Software Foundation, Inc.
5
6   This file is part of GNU Binutils.
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2 of the License, or
11   (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program; if not, write to the Free Software
20   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21
22/*
23   Bugs: should use getopt the way tar does (complete w/optional -) and
24   should have long options too. GNU ar used to check file against filesystem
25   in quick_update and replace operations (would check mtime). Doesn't warn
26   when name truncated. No way to specify pos_end. Error messages should be
27   more consistent.  */
28
29#include "bfd.h"
30#include "libiberty.h"
31#include "progress.h"
32#include "bucomm.h"
33#include "aout/ar.h"
34#include "libbfd.h"
35#include "arsup.h"
36#include "filenames.h"
37#include "binemul.h"
38#include <sys/stat.h>
39
40#ifdef __GO32___
41#define EXT_NAME_LEN 3		/* bufflen of addition to name if it's MS-DOS */
42#else
43#define EXT_NAME_LEN 6		/* ditto for *NIX */
44#endif
45
46/* We need to open files in binary modes on system where that makes a
47   difference.  */
48#ifndef O_BINARY
49#define O_BINARY 0
50#endif
51
52#define BUFSIZE 8192
53
54/* Kludge declaration from BFD!  This is ugly!  FIXME!  XXX */
55
56struct ar_hdr *
57  bfd_special_undocumented_glue (bfd * abfd, const char *filename);
58
59/* Static declarations */
60
61static void mri_emul (void);
62static const char *normalize (const char *, bfd *);
63static void remove_output (void);
64static void map_over_members (bfd *, void (*)(bfd *), char **, int);
65static void print_contents (bfd * member);
66static void delete_members (bfd *, char **files_to_delete);
67
68#if 0
69static void do_quick_append
70  (const char *archive_filename, char **files_to_append);
71#endif
72
73static void move_members (bfd *, char **files_to_move);
74static void replace_members
75  (bfd *, char **files_to_replace, bfd_boolean quick);
76static void print_descr (bfd * abfd);
77static void write_archive (bfd *);
78static void ranlib_only (const char *archname);
79static void ranlib_touch (const char *archname);
80static void usage (int);
81
82/** Globals and flags */
83
84int mri_mode;
85
86/* This flag distinguishes between ar and ranlib:
87   1 means this is 'ranlib'; 0 means this is 'ar'.
88   -1 means if we should use argv[0] to decide.  */
89extern int is_ranlib;
90
91/* Nonzero means don't warn about creating the archive file if necessary.  */
92int silent_create = 0;
93
94/* Nonzero means describe each action performed.  */
95int verbose = 0;
96
97/* Nonzero means preserve dates of members when extracting them.  */
98int preserve_dates = 0;
99
100/* Nonzero means don't replace existing members whose dates are more recent
101   than the corresponding files.  */
102int newer_only = 0;
103
104/* Controls the writing of an archive symbol table (in BSD: a __.SYMDEF
105   member).  -1 means we've been explicitly asked to not write a symbol table;
106   +1 means we've been explicitly asked to write it;
107   0 is the default.
108   Traditionally, the default in BSD has been to not write the table.
109   However, for POSIX.2 compliance the default is now to write a symbol table
110   if any of the members are object files.  */
111int write_armap = 0;
112
113/* Nonzero means it's the name of an existing member; position new or moved
114   files with respect to this one.  */
115char *posname = NULL;
116
117/* Sez how to use `posname': pos_before means position before that member.
118   pos_after means position after that member. pos_end means always at end.
119   pos_default means default appropriately. For the latter two, `posname'
120   should also be zero.  */
121enum pos
122  {
123    pos_default, pos_before, pos_after, pos_end
124  } postype = pos_default;
125
126static bfd **
127get_pos_bfd (bfd **, enum pos, const char *);
128
129/* For extract/delete only.  If COUNTED_NAME_MODE is TRUE, we only
130   extract the COUNTED_NAME_COUNTER instance of that name.  */
131static bfd_boolean counted_name_mode = 0;
132static int counted_name_counter = 0;
133
134/* Whether to truncate names of files stored in the archive.  */
135static bfd_boolean ar_truncate = FALSE;
136
137/* Whether to use a full file name match when searching an archive.
138   This is convenient for archives created by the Microsoft lib
139   program.  */
140static bfd_boolean full_pathname = FALSE;
141
142int interactive = 0;
143
144static void
145mri_emul (void)
146{
147  interactive = isatty (fileno (stdin));
148  yyparse ();
149}
150
151/* If COUNT is 0, then FUNCTION is called once on each entry.  If nonzero,
152   COUNT is the length of the FILES chain; FUNCTION is called on each entry
153   whose name matches one in FILES.  */
154
155static void
156map_over_members (bfd *arch, void (*function)(bfd *), char **files, int count)
157{
158  bfd *head;
159  int match_count;
160
161  if (count == 0)
162    {
163      for (head = arch->next; head; head = head->next)
164	{
165	  PROGRESS (1);
166	  function (head);
167	}
168      return;
169    }
170
171  /* This may appear to be a baroque way of accomplishing what we want.
172     However we have to iterate over the filenames in order to notice where
173     a filename is requested but does not exist in the archive.  Ditto
174     mapping over each file each time -- we want to hack multiple
175     references.  */
176
177  for (; count > 0; files++, count--)
178    {
179      bfd_boolean found = FALSE;
180
181      match_count = 0;
182      for (head = arch->next; head; head = head->next)
183	{
184	  PROGRESS (1);
185	  if (head->filename == NULL)
186	    {
187	      /* Some archive formats don't get the filenames filled in
188		 until the elements are opened.  */
189	      struct stat buf;
190	      bfd_stat_arch_elt (head, &buf);
191	    }
192	  if ((head->filename != NULL) &&
193	      (!FILENAME_CMP (normalize (*files, arch), head->filename)))
194	    {
195	      ++match_count;
196	      if (counted_name_mode
197		  && match_count != counted_name_counter)
198		{
199		  /* Counting, and didn't match on count; go on to the
200                     next one.  */
201		  continue;
202		}
203
204	      found = TRUE;
205	      function (head);
206	    }
207	}
208      if (!found)
209	/* xgettext:c-format */
210	fprintf (stderr, _("no entry %s in archive\n"), *files);
211    }
212}
213
214bfd_boolean operation_alters_arch = FALSE;
215
216static void
217usage (int help)
218{
219  FILE *s;
220
221  s = help ? stdout : stderr;
222
223  if (! is_ranlib)
224    {
225      /* xgettext:c-format */
226      fprintf (s, _("Usage: %s [emulation options] [-]{dmpqrstx}[abcfilNoPsSuvV] [member-name] [count] archive-file file...\n"),
227	       program_name);
228      /* xgettext:c-format */
229      fprintf (s, _("       %s -M [<mri-script]\n"), program_name);
230      fprintf (s, _(" commands:\n"));
231      fprintf (s, _("  d            - delete file(s) from the archive\n"));
232      fprintf (s, _("  m[ab]        - move file(s) in the archive\n"));
233      fprintf (s, _("  p            - print file(s) found in the archive\n"));
234      fprintf (s, _("  q[f]         - quick append file(s) to the archive\n"));
235      fprintf (s, _("  r[ab][f][u]  - replace existing or insert new file(s) into the archive\n"));
236      fprintf (s, _("  t            - display contents of archive\n"));
237      fprintf (s, _("  x[o]         - extract file(s) from the archive\n"));
238      fprintf (s, _(" command specific modifiers:\n"));
239      fprintf (s, _("  [a]          - put file(s) after [member-name]\n"));
240      fprintf (s, _("  [b]          - put file(s) before [member-name] (same as [i])\n"));
241      fprintf (s, _("  [N]          - use instance [count] of name\n"));
242      fprintf (s, _("  [f]          - truncate inserted file names\n"));
243      fprintf (s, _("  [P]          - use full path names when matching\n"));
244      fprintf (s, _("  [o]          - preserve original dates\n"));
245      fprintf (s, _("  [u]          - only replace files that are newer than current archive contents\n"));
246      fprintf (s, _(" generic modifiers:\n"));
247      fprintf (s, _("  [c]          - do not warn if the library had to be created\n"));
248      fprintf (s, _("  [s]          - create an archive index (cf. ranlib)\n"));
249      fprintf (s, _("  [S]          - do not build a symbol table\n"));
250      fprintf (s, _("  [v]          - be verbose\n"));
251      fprintf (s, _("  [V]          - display the version number\n"));
252
253      ar_emul_usage (s);
254    }
255  else
256    {
257      /* xgettext:c-format */
258      fprintf (s, _("Usage: %s [options] archive\n"), program_name);
259      fprintf (s, _(" Generate an index to speed access to archives\n"));
260      fprintf (s, _(" The options are:\n\
261  -h --help                    Print this help message\n\
262  -V --version                 Print version information\n"));
263    }
264
265  list_supported_targets (program_name, stderr);
266
267  if (help)
268    fprintf (s, _("Report bugs to %s\n"), REPORT_BUGS_TO);
269
270  xexit (help ? 0 : 1);
271}
272
273/* Normalize a file name specified on the command line into a file
274   name which we will use in an archive.  */
275
276static const char *
277normalize (const char *file, bfd *abfd)
278{
279  const char *filename;
280
281  if (full_pathname)
282    return file;
283
284  filename = strrchr (file, '/');
285#ifdef HAVE_DOS_BASED_FILE_SYSTEM
286  {
287    /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
288    char *bslash = strrchr (file, '\\');
289    if (filename == NULL || (bslash != NULL && bslash > filename))
290      filename = bslash;
291    if (filename == NULL && file[0] != '\0' && file[1] == ':')
292      filename = file + 1;
293  }
294#endif
295  if (filename != (char *) NULL)
296    filename++;
297  else
298    filename = file;
299
300  if (ar_truncate
301      && abfd != NULL
302      && strlen (filename) > abfd->xvec->ar_max_namelen)
303    {
304      char *s;
305
306      /* Space leak.  */
307      s = (char *) xmalloc (abfd->xvec->ar_max_namelen + 1);
308      memcpy (s, filename, abfd->xvec->ar_max_namelen);
309      s[abfd->xvec->ar_max_namelen] = '\0';
310      filename = s;
311    }
312
313  return filename;
314}
315
316/* Remove any output file.  This is only called via xatexit.  */
317
318static const char *output_filename = NULL;
319static FILE *output_file = NULL;
320static bfd *output_bfd = NULL;
321
322static void
323remove_output (void)
324{
325  if (output_filename != NULL)
326    {
327      if (output_bfd != NULL)
328	bfd_cache_close (output_bfd);
329      if (output_file != NULL)
330	fclose (output_file);
331      unlink (output_filename);
332    }
333}
334
335/* The option parsing should be in its own function.
336   It will be when I have getopt working.  */
337
338int main (int, char **);
339
340int
341main (int argc, char **argv)
342{
343  char *arg_ptr;
344  char c;
345  enum
346    {
347      none = 0, delete, replace, print_table,
348      print_files, extract, move, quick_append
349    } operation = none;
350  int arg_index;
351  char **files;
352  int file_count;
353  char *inarch_filename;
354  int show_version;
355  int i;
356  int do_posix = 0;
357
358#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
359  setlocale (LC_MESSAGES, "");
360#endif
361#if defined (HAVE_SETLOCALE)
362  setlocale (LC_CTYPE, "");
363#endif
364  bindtextdomain (PACKAGE, LOCALEDIR);
365  textdomain (PACKAGE);
366
367  program_name = argv[0];
368  xmalloc_set_program_name (program_name);
369
370  if (is_ranlib < 0)
371    {
372      char *temp;
373
374      temp = strrchr (program_name, '/');
375#ifdef HAVE_DOS_BASED_FILE_SYSTEM
376      {
377	/* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
378	char *bslash = strrchr (program_name, '\\');
379	if (temp == NULL || (bslash != NULL && bslash > temp))
380	  temp = bslash;
381	if (temp == NULL && program_name[0] != '\0' && program_name[1] == ':')
382	  temp = program_name + 1;
383      }
384#endif
385      if (temp == NULL)
386	temp = program_name;
387      else
388	++temp;
389      if (strlen (temp) >= 6
390	  && FILENAME_CMP (temp + strlen (temp) - 6, "ranlib") == 0)
391	is_ranlib = 1;
392      else
393	is_ranlib = 0;
394    }
395
396  if (argc > 1 && argv[1][0] == '-')
397    {
398      if (strcmp (argv[1], "--help") == 0)
399	usage (1);
400      else if (strcmp (argv[1], "--version") == 0)
401	{
402	  if (is_ranlib)
403	    print_version ("ranlib");
404	  else
405	    print_version ("ar");
406	}
407    }
408
409  START_PROGRESS (program_name, 0);
410
411  bfd_init ();
412  set_default_bfd_target ();
413
414  show_version = 0;
415
416  xatexit (remove_output);
417
418  for (i = 1; i < argc; i++)
419    if (! ar_emul_parse_arg (argv[i]))
420      break;
421  argv += (i - 1);
422  argc -= (i - 1);
423
424  if (is_ranlib)
425    {
426      bfd_boolean touch = FALSE;
427
428      if (argc < 2
429	  || strcmp (argv[1], "--help") == 0
430	  || strcmp (argv[1], "-h") == 0
431	  || strcmp (argv[1], "-H") == 0)
432	usage (0);
433      if (strcmp (argv[1], "-V") == 0
434	  || strcmp (argv[1], "-v") == 0
435	  || strncmp (argv[1], "--v", 3) == 0)
436	print_version ("ranlib");
437      arg_index = 1;
438      if (strcmp (argv[1], "-t") == 0)
439	{
440	  ++arg_index;
441	  touch = TRUE;
442	}
443      while (arg_index < argc)
444	{
445	  if (! touch)
446	    ranlib_only (argv[arg_index]);
447	  else
448	    ranlib_touch (argv[arg_index]);
449	  ++arg_index;
450	}
451      xexit (0);
452    }
453
454  if (argc == 2 && strcmp (argv[1], "-M") == 0)
455    {
456      mri_emul ();
457      xexit (0);
458    }
459
460  if (argc < 2)
461    usage (0);
462
463  arg_index = 1;
464  arg_ptr = argv[arg_index];
465
466  if (*arg_ptr == '-')
467    {
468      /* When the first option starts with '-' we support POSIX-compatible
469	 option parsing.  */
470      do_posix = 1;
471      ++arg_ptr;			/* compatibility */
472    }
473
474  do
475    {
476      while ((c = *arg_ptr++) != '\0')
477	{
478	  switch (c)
479	    {
480	    case 'd':
481	    case 'm':
482	    case 'p':
483	    case 'q':
484	    case 'r':
485	    case 't':
486	    case 'x':
487	      if (operation != none)
488		fatal (_("two different operation options specified"));
489	      switch (c)
490		{
491		case 'd':
492		  operation = delete;
493		  operation_alters_arch = TRUE;
494		  break;
495		case 'm':
496		  operation = move;
497		  operation_alters_arch = TRUE;
498		  break;
499		case 'p':
500		  operation = print_files;
501		  break;
502		case 'q':
503		  operation = quick_append;
504		  operation_alters_arch = TRUE;
505		  break;
506		case 'r':
507		  operation = replace;
508		  operation_alters_arch = TRUE;
509		  break;
510		case 't':
511		  operation = print_table;
512		  break;
513		case 'x':
514		  operation = extract;
515		  break;
516		}
517	    case 'l':
518	      break;
519	    case 'c':
520	      silent_create = 1;
521	      break;
522	    case 'o':
523	      preserve_dates = 1;
524	      break;
525	    case 'V':
526	      show_version = TRUE;
527	      break;
528	    case 's':
529	      write_armap = 1;
530	      break;
531	    case 'S':
532	      write_armap = -1;
533	      break;
534	    case 'u':
535	      newer_only = 1;
536	      break;
537	    case 'v':
538	      verbose = 1;
539	      break;
540	    case 'a':
541	      postype = pos_after;
542	      break;
543	    case 'b':
544	      postype = pos_before;
545	      break;
546	    case 'i':
547	      postype = pos_before;
548	      break;
549	    case 'M':
550	      mri_mode = 1;
551	      break;
552	    case 'N':
553	      counted_name_mode = TRUE;
554	      break;
555	    case 'f':
556	      ar_truncate = TRUE;
557	      break;
558	    case 'P':
559	      full_pathname = TRUE;
560	      break;
561	    default:
562	      /* xgettext:c-format */
563	      non_fatal (_("illegal option -- %c"), c);
564	      usage (0);
565	    }
566	}
567
568      /* With POSIX-compatible option parsing continue with the next
569	 argument if it starts with '-'.  */
570      if (do_posix && arg_index + 1 < argc && argv[arg_index + 1][0] == '-')
571	arg_ptr = argv[++arg_index] + 1;
572      else
573	do_posix = 0;
574    }
575  while (do_posix);
576
577  if (show_version)
578    print_version ("ar");
579
580  ++arg_index;
581  if (arg_index >= argc)
582    usage (0);
583
584  if (mri_mode)
585    {
586      mri_emul ();
587    }
588  else
589    {
590      bfd *arch;
591
592      /* We can't write an armap when using ar q, so just do ar r
593         instead.  */
594      if (operation == quick_append && write_armap)
595	operation = replace;
596
597      if ((operation == none || operation == print_table)
598	  && write_armap == 1)
599	{
600	  ranlib_only (argv[arg_index]);
601	  xexit (0);
602	}
603
604      if (operation == none)
605	fatal (_("no operation specified"));
606
607      if (newer_only && operation != replace)
608	fatal (_("`u' is only meaningful with the `r' option."));
609
610      if (postype != pos_default)
611	posname = argv[arg_index++];
612
613      if (counted_name_mode)
614	{
615	  if (operation != extract && operation != delete)
616	     fatal (_("`N' is only meaningful with the `x' and `d' options."));
617	  counted_name_counter = atoi (argv[arg_index++]);
618	  if (counted_name_counter <= 0)
619	    fatal (_("Value for `N' must be positive."));
620	}
621
622      inarch_filename = argv[arg_index++];
623
624      files = arg_index < argc ? argv + arg_index : NULL;
625      file_count = argc - arg_index;
626
627#if 0
628      /* We don't use do_quick_append any more.  Too many systems
629         expect ar to always rebuild the symbol table even when q is
630         used.  */
631
632      /* We can't do a quick append if we need to construct an
633	 extended name table, because do_quick_append won't be able to
634	 rebuild the name table.  Unfortunately, at this point we
635	 don't actually know the maximum name length permitted by this
636	 object file format.  So, we guess.  FIXME.  */
637      if (operation == quick_append && ! ar_truncate)
638	{
639	  char **chk;
640
641	  for (chk = files; chk != NULL && *chk != '\0'; chk++)
642	    {
643	      if (strlen (normalize (*chk, (bfd *) NULL)) > 14)
644		{
645		  operation = replace;
646		  break;
647		}
648	    }
649	}
650
651      if (operation == quick_append)
652	{
653	  /* Note that quick appending to a non-existent archive creates it,
654	     even if there are no files to append.  */
655	  do_quick_append (inarch_filename, files);
656	  xexit (0);
657	}
658#endif
659
660      arch = open_inarch (inarch_filename,
661			  files == NULL ? (char *) NULL : files[0]);
662
663      switch (operation)
664	{
665	case print_table:
666	  map_over_members (arch, print_descr, files, file_count);
667	  break;
668
669	case print_files:
670	  map_over_members (arch, print_contents, files, file_count);
671	  break;
672
673	case extract:
674	  map_over_members (arch, extract_file, files, file_count);
675	  break;
676
677	case delete:
678	  if (files != NULL)
679	    delete_members (arch, files);
680	  else
681	    output_filename = NULL;
682	  break;
683
684	case move:
685	  if (files != NULL)
686	    move_members (arch, files);
687	  else
688	    output_filename = NULL;
689	  break;
690
691	case replace:
692	case quick_append:
693	  if (files != NULL || write_armap > 0)
694	    replace_members (arch, files, operation == quick_append);
695	  else
696	    output_filename = NULL;
697	  break;
698
699	  /* Shouldn't happen! */
700	default:
701	  /* xgettext:c-format */
702	  fatal (_("internal error -- this option not implemented"));
703	}
704    }
705
706  END_PROGRESS (program_name);
707
708  xexit (0);
709  return 0;
710}
711
712bfd *
713open_inarch (const char *archive_filename, const char *file)
714{
715  const char *target;
716  bfd **last_one;
717  bfd *next_one;
718  struct stat sbuf;
719  bfd *arch;
720  char **matching;
721
722  bfd_set_error (bfd_error_no_error);
723
724  target = NULL;
725
726  if (stat (archive_filename, &sbuf) != 0)
727    {
728#if !defined(__GO32__) || defined(__DJGPP__)
729
730      /* FIXME: I don't understand why this fragment was ifndef'ed
731	 away for __GO32__; perhaps it was in the days of DJGPP v1.x.
732	 stat() works just fine in v2.x, so I think this should be
733	 removed.  For now, I enable it for DJGPP v2. -- EZ.  */
734
735/* KLUDGE ALERT! Temporary fix until I figger why
736   stat() is wrong ... think it's buried in GO32's IDT - Jax */
737      if (errno != ENOENT)
738	bfd_fatal (archive_filename);
739#endif
740
741      if (!operation_alters_arch)
742	{
743	  fprintf (stderr, "%s: ", program_name);
744	  perror (archive_filename);
745	  maybequit ();
746	  return NULL;
747	}
748
749      /* Try to figure out the target to use for the archive from the
750         first object on the list.  */
751      if (file != NULL)
752	{
753	  bfd *obj;
754
755	  obj = bfd_openr (file, NULL);
756	  if (obj != NULL)
757	    {
758	      if (bfd_check_format (obj, bfd_object))
759		target = bfd_get_target (obj);
760	      (void) bfd_close (obj);
761	    }
762	}
763
764      /* Create an empty archive.  */
765      arch = bfd_openw (archive_filename, target);
766      if (arch == NULL
767	  || ! bfd_set_format (arch, bfd_archive)
768	  || ! bfd_close (arch))
769	bfd_fatal (archive_filename);
770      else if (!silent_create)
771        non_fatal (_("creating %s"), archive_filename);
772
773      /* If we die creating a new archive, don't leave it around.  */
774      output_filename = archive_filename;
775    }
776
777  arch = bfd_openr (archive_filename, target);
778  if (arch == NULL)
779    {
780    bloser:
781      bfd_fatal (archive_filename);
782    }
783
784  if (! bfd_check_format_matches (arch, bfd_archive, &matching))
785    {
786      bfd_nonfatal (archive_filename);
787      if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
788	{
789	  list_matching_formats (matching);
790	  free (matching);
791	}
792      xexit (1);
793    }
794
795  last_one = &(arch->next);
796  /* Read all the contents right away, regardless.  */
797  for (next_one = bfd_openr_next_archived_file (arch, NULL);
798       next_one;
799       next_one = bfd_openr_next_archived_file (arch, next_one))
800    {
801      PROGRESS (1);
802      *last_one = next_one;
803      last_one = &next_one->next;
804    }
805  *last_one = (bfd *) NULL;
806  if (bfd_get_error () != bfd_error_no_more_archived_files)
807    goto bloser;
808  return arch;
809}
810
811static void
812print_contents (bfd *abfd)
813{
814  int ncopied = 0;
815  char *cbuf = xmalloc (BUFSIZE);
816  struct stat buf;
817  long size;
818  if (bfd_stat_arch_elt (abfd, &buf) != 0)
819    /* xgettext:c-format */
820    fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
821
822  if (verbose)
823    /* xgettext:c-format */
824    printf (_("\n<%s>\n\n"), bfd_get_filename (abfd));
825
826  bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
827
828  size = buf.st_size;
829  while (ncopied < size)
830    {
831
832      int nread;
833      int tocopy = size - ncopied;
834      if (tocopy > BUFSIZE)
835	tocopy = BUFSIZE;
836
837      nread = bfd_bread (cbuf, (bfd_size_type) tocopy, abfd);
838      if (nread != tocopy)
839	/* xgettext:c-format */
840	fatal (_("%s is not a valid archive"),
841	       bfd_get_filename (bfd_my_archive (abfd)));
842      fwrite (cbuf, 1, nread, stdout);
843      ncopied += tocopy;
844    }
845  free (cbuf);
846}
847
848/* Extract a member of the archive into its own file.
849
850   We defer opening the new file until after we have read a BUFSIZ chunk of the
851   old one, since we know we have just read the archive header for the old
852   one.  Since most members are shorter than BUFSIZ, this means we will read
853   the old header, read the old data, write a new inode for the new file, and
854   write the new data, and be done. This 'optimization' is what comes from
855   sitting next to a bare disk and hearing it every time it seeks.  -- Gnu
856   Gilmore  */
857
858void
859extract_file (bfd *abfd)
860{
861  FILE *ostream;
862  char *cbuf = xmalloc (BUFSIZE);
863  int nread, tocopy;
864  long ncopied = 0;
865  long size;
866  struct stat buf;
867
868  if (bfd_stat_arch_elt (abfd, &buf) != 0)
869    /* xgettext:c-format */
870    fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
871  size = buf.st_size;
872
873  if (size < 0)
874    /* xgettext:c-format */
875    fatal (_("stat returns negative size for %s"), bfd_get_filename (abfd));
876
877  if (verbose)
878    printf ("x - %s\n", bfd_get_filename (abfd));
879
880  bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
881
882  ostream = NULL;
883  if (size == 0)
884    {
885      /* Seems like an abstraction violation, eh?  Well it's OK! */
886      output_filename = bfd_get_filename (abfd);
887
888      ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
889      if (ostream == NULL)
890	{
891	  perror (bfd_get_filename (abfd));
892	  xexit (1);
893	}
894
895      output_file = ostream;
896    }
897  else
898    while (ncopied < size)
899      {
900	tocopy = size - ncopied;
901	if (tocopy > BUFSIZE)
902	  tocopy = BUFSIZE;
903
904	nread = bfd_bread (cbuf, (bfd_size_type) tocopy, abfd);
905	if (nread != tocopy)
906	  /* xgettext:c-format */
907	  fatal (_("%s is not a valid archive"),
908		 bfd_get_filename (bfd_my_archive (abfd)));
909
910	/* See comment above; this saves disk arm motion */
911	if (ostream == NULL)
912	  {
913	    /* Seems like an abstraction violation, eh?  Well it's OK! */
914	    output_filename = bfd_get_filename (abfd);
915
916	    ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
917	    if (ostream == NULL)
918	      {
919		perror (bfd_get_filename (abfd));
920		xexit (1);
921	      }
922
923	    output_file = ostream;
924	  }
925	fwrite (cbuf, 1, nread, ostream);
926	ncopied += tocopy;
927      }
928
929  if (ostream != NULL)
930    fclose (ostream);
931
932  output_file = NULL;
933  output_filename = NULL;
934
935  chmod (bfd_get_filename (abfd), buf.st_mode);
936
937  if (preserve_dates)
938    set_times (bfd_get_filename (abfd), &buf);
939
940  free (cbuf);
941}
942
943#if 0
944
945/* We don't use this anymore.  Too many systems expect ar to rebuild
946   the symbol table even when q is used.  */
947
948/* Just do it quickly; don't worry about dups, armap, or anything like that */
949
950static void
951do_quick_append (const char *archive_filename, char **files_to_append)
952{
953  FILE *ofile, *ifile;
954  char *buf = xmalloc (BUFSIZE);
955  long tocopy, thistime;
956  bfd *temp;
957  struct stat sbuf;
958  bfd_boolean newfile = FALSE;
959  bfd_set_error (bfd_error_no_error);
960
961  if (stat (archive_filename, &sbuf) != 0)
962    {
963
964#if !defined(__GO32__) || defined(__DJGPP__)
965
966      /* FIXME: I don't understand why this fragment was ifndef'ed
967	 away for __GO32__; perhaps it was in the days of DJGPP v1.x.
968	 stat() works just fine in v2.x, so I think this should be
969	 removed.  For now, I enable it for DJGPP v2.
970
971	 (And yes, I know this is all unused, but somebody, someday,
972	 might wish to resurrect this again... -- EZ.  */
973
974/* KLUDGE ALERT! Temporary fix until I figger why
975   stat() is wrong ... think it's buried in GO32's IDT - Jax  */
976
977      if (errno != ENOENT)
978	bfd_fatal (archive_filename);
979#endif
980
981      newfile = TRUE;
982    }
983
984  ofile = fopen (archive_filename, FOPEN_AUB);
985  if (ofile == NULL)
986    {
987      perror (program_name);
988      xexit (1);
989    }
990
991  temp = bfd_openr (archive_filename, NULL);
992  if (temp == NULL)
993    {
994      bfd_fatal (archive_filename);
995    }
996  if (!newfile)
997    {
998      if (!bfd_check_format (temp, bfd_archive))
999	/* xgettext:c-format */
1000	fatal (_("%s is not an archive"), archive_filename);
1001    }
1002  else
1003    {
1004      fwrite (ARMAG, 1, SARMAG, ofile);
1005      if (!silent_create)
1006	/* xgettext:c-format */
1007	non_fatal (_("creating %s"), archive_filename);
1008    }
1009
1010  if (ar_truncate)
1011    temp->flags |= BFD_TRADITIONAL_FORMAT;
1012
1013  /* assume it's an archive, go straight to the end, sans $200 */
1014  fseek (ofile, 0, 2);
1015
1016  for (; files_to_append && *files_to_append; ++files_to_append)
1017    {
1018      struct ar_hdr *hdr = bfd_special_undocumented_glue (temp, *files_to_append);
1019      if (hdr == NULL)
1020	{
1021	  bfd_fatal (*files_to_append);
1022	}
1023
1024      BFD_SEND (temp, _bfd_truncate_arname, (temp, *files_to_append, (char *) hdr));
1025
1026      ifile = fopen (*files_to_append, FOPEN_RB);
1027      if (ifile == NULL)
1028	{
1029	  bfd_nonfatal (*files_to_append);
1030	}
1031
1032      if (stat (*files_to_append, &sbuf) != 0)
1033	{
1034	  bfd_nonfatal (*files_to_append);
1035	}
1036
1037      tocopy = sbuf.st_size;
1038
1039      /* XXX should do error-checking! */
1040      fwrite (hdr, 1, sizeof (struct ar_hdr), ofile);
1041
1042      while (tocopy > 0)
1043	{
1044	  thistime = tocopy;
1045	  if (thistime > BUFSIZE)
1046	    thistime = BUFSIZE;
1047	  fread (buf, 1, thistime, ifile);
1048	  fwrite (buf, 1, thistime, ofile);
1049	  tocopy -= thistime;
1050	}
1051      fclose (ifile);
1052      if ((sbuf.st_size % 2) == 1)
1053	putc ('\012', ofile);
1054    }
1055  fclose (ofile);
1056  bfd_close (temp);
1057  free (buf);
1058}
1059
1060#endif /* 0 */
1061
1062static void
1063write_archive (bfd *iarch)
1064{
1065  bfd *obfd;
1066  char *old_name, *new_name;
1067  bfd *contents_head = iarch->next;
1068
1069  old_name = xmalloc (strlen (bfd_get_filename (iarch)) + 1);
1070  strcpy (old_name, bfd_get_filename (iarch));
1071  new_name = make_tempname (old_name);
1072
1073  output_filename = new_name;
1074
1075  obfd = bfd_openw (new_name, bfd_get_target (iarch));
1076
1077  if (obfd == NULL)
1078    bfd_fatal (old_name);
1079
1080  output_bfd = obfd;
1081
1082  bfd_set_format (obfd, bfd_archive);
1083
1084  /* Request writing the archive symbol table unless we've
1085     been explicitly requested not to.  */
1086  obfd->has_armap = write_armap >= 0;
1087
1088  if (ar_truncate)
1089    {
1090      /* This should really use bfd_set_file_flags, but that rejects
1091         archives.  */
1092      obfd->flags |= BFD_TRADITIONAL_FORMAT;
1093    }
1094
1095  if (!bfd_set_archive_head (obfd, contents_head))
1096    bfd_fatal (old_name);
1097
1098  if (!bfd_close (obfd))
1099    bfd_fatal (old_name);
1100
1101  output_bfd = NULL;
1102  output_filename = NULL;
1103
1104  /* We don't care if this fails; we might be creating the archive.  */
1105  bfd_close (iarch);
1106
1107  if (smart_rename (new_name, old_name, 0) != 0)
1108    xexit (1);
1109}
1110
1111/* Return a pointer to the pointer to the entry which should be rplacd'd
1112   into when altering.  DEFAULT_POS should be how to interpret pos_default,
1113   and should be a pos value.  */
1114
1115static bfd **
1116get_pos_bfd (bfd **contents, enum pos default_pos, const char *default_posname)
1117{
1118  bfd **after_bfd = contents;
1119  enum pos realpos;
1120  const char *realposname;
1121
1122  if (postype == pos_default)
1123    {
1124      realpos = default_pos;
1125      realposname = default_posname;
1126    }
1127  else
1128    {
1129      realpos = postype;
1130      realposname = posname;
1131    }
1132
1133  if (realpos == pos_end)
1134    {
1135      while (*after_bfd)
1136	after_bfd = &((*after_bfd)->next);
1137    }
1138  else
1139    {
1140      for (; *after_bfd; after_bfd = &(*after_bfd)->next)
1141	if (FILENAME_CMP ((*after_bfd)->filename, realposname) == 0)
1142	  {
1143	    if (realpos == pos_after)
1144	      after_bfd = &(*after_bfd)->next;
1145	    break;
1146	  }
1147    }
1148  return after_bfd;
1149}
1150
1151static void
1152delete_members (bfd *arch, char **files_to_delete)
1153{
1154  bfd **current_ptr_ptr;
1155  bfd_boolean found;
1156  bfd_boolean something_changed = FALSE;
1157  int match_count;
1158
1159  for (; *files_to_delete != NULL; ++files_to_delete)
1160    {
1161      /* In a.out systems, the armap is optional.  It's also called
1162	 __.SYMDEF.  So if the user asked to delete it, we should remember
1163	 that fact. This isn't quite right for COFF systems (where
1164	 __.SYMDEF might be regular member), but it's very unlikely
1165	 to be a problem.  FIXME */
1166
1167      if (!strcmp (*files_to_delete, "__.SYMDEF"))
1168	{
1169	  arch->has_armap = FALSE;
1170	  write_armap = -1;
1171	  continue;
1172	}
1173
1174      found = FALSE;
1175      match_count = 0;
1176      current_ptr_ptr = &(arch->next);
1177      while (*current_ptr_ptr)
1178	{
1179	  if (FILENAME_CMP (normalize (*files_to_delete, arch),
1180			    (*current_ptr_ptr)->filename) == 0)
1181	    {
1182	      ++match_count;
1183	      if (counted_name_mode
1184		  && match_count != counted_name_counter)
1185		{
1186		  /* Counting, and didn't match on count; go on to the
1187                     next one.  */
1188		}
1189	      else
1190		{
1191		  found = TRUE;
1192		  something_changed = TRUE;
1193		  if (verbose)
1194		    printf ("d - %s\n",
1195			    *files_to_delete);
1196		  *current_ptr_ptr = ((*current_ptr_ptr)->next);
1197		  goto next_file;
1198		}
1199	    }
1200
1201	  current_ptr_ptr = &((*current_ptr_ptr)->next);
1202	}
1203
1204      if (verbose && !found)
1205	{
1206	  /* xgettext:c-format */
1207	  printf (_("No member named `%s'\n"), *files_to_delete);
1208	}
1209    next_file:
1210      ;
1211    }
1212
1213  if (something_changed)
1214    write_archive (arch);
1215  else
1216    output_filename = NULL;
1217}
1218
1219
1220/* Reposition existing members within an archive */
1221
1222static void
1223move_members (bfd *arch, char **files_to_move)
1224{
1225  bfd **after_bfd;		/* New entries go after this one */
1226  bfd **current_ptr_ptr;	/* cdr pointer into contents */
1227
1228  for (; *files_to_move; ++files_to_move)
1229    {
1230      current_ptr_ptr = &(arch->next);
1231      while (*current_ptr_ptr)
1232	{
1233	  bfd *current_ptr = *current_ptr_ptr;
1234	  if (FILENAME_CMP (normalize (*files_to_move, arch),
1235			    current_ptr->filename) == 0)
1236	    {
1237	      /* Move this file to the end of the list - first cut from
1238		 where it is.  */
1239	      bfd *link;
1240	      *current_ptr_ptr = current_ptr->next;
1241
1242	      /* Now glue to end */
1243	      after_bfd = get_pos_bfd (&arch->next, pos_end, NULL);
1244	      link = *after_bfd;
1245	      *after_bfd = current_ptr;
1246	      current_ptr->next = link;
1247
1248	      if (verbose)
1249		printf ("m - %s\n", *files_to_move);
1250
1251	      goto next_file;
1252	    }
1253
1254	  current_ptr_ptr = &((*current_ptr_ptr)->next);
1255	}
1256      /* xgettext:c-format */
1257      fatal (_("no entry %s in archive %s!"), *files_to_move, arch->filename);
1258
1259    next_file:;
1260    }
1261
1262  write_archive (arch);
1263}
1264
1265/* Ought to default to replacing in place, but this is existing practice!  */
1266
1267static void
1268replace_members (bfd *arch, char **files_to_move, bfd_boolean quick)
1269{
1270  bfd_boolean changed = FALSE;
1271  bfd **after_bfd;		/* New entries go after this one */
1272  bfd *current;
1273  bfd **current_ptr;
1274
1275  while (files_to_move && *files_to_move)
1276    {
1277      if (! quick)
1278	{
1279	  current_ptr = &arch->next;
1280	  while (*current_ptr)
1281	    {
1282	      current = *current_ptr;
1283
1284	      /* For compatibility with existing ar programs, we
1285		 permit the same file to be added multiple times.  */
1286	      if (FILENAME_CMP (normalize (*files_to_move, arch),
1287				normalize (current->filename, arch)) == 0
1288		  && current->arelt_data != NULL)
1289		{
1290		  if (newer_only)
1291		    {
1292		      struct stat fsbuf, asbuf;
1293
1294		      if (stat (*files_to_move, &fsbuf) != 0)
1295			{
1296			  if (errno != ENOENT)
1297			    bfd_fatal (*files_to_move);
1298			  goto next_file;
1299			}
1300		      if (bfd_stat_arch_elt (current, &asbuf) != 0)
1301			/* xgettext:c-format */
1302			fatal (_("internal stat error on %s"),
1303			       current->filename);
1304
1305		      if (fsbuf.st_mtime <= asbuf.st_mtime)
1306			goto next_file;
1307		    }
1308
1309		  after_bfd = get_pos_bfd (&arch->next, pos_after,
1310					   current->filename);
1311		  if (ar_emul_replace (after_bfd, *files_to_move,
1312				       verbose))
1313		    {
1314		      /* Snip out this entry from the chain.  */
1315		      *current_ptr = (*current_ptr)->next;
1316		      changed = TRUE;
1317		    }
1318
1319		  goto next_file;
1320		}
1321	      current_ptr = &(current->next);
1322	    }
1323	}
1324
1325      /* Add to the end of the archive.  */
1326      after_bfd = get_pos_bfd (&arch->next, pos_end, NULL);
1327
1328      if (get_file_size (* files_to_move) > 0
1329	  && ar_emul_append (after_bfd, *files_to_move, verbose))
1330	changed = TRUE;
1331
1332    next_file:;
1333
1334      files_to_move++;
1335    }
1336
1337  if (changed)
1338    write_archive (arch);
1339  else
1340    output_filename = NULL;
1341}
1342
1343static void
1344ranlib_only (const char *archname)
1345{
1346  bfd *arch;
1347
1348  if (get_file_size (archname) < 1)
1349    return;
1350  write_armap = 1;
1351  arch = open_inarch (archname, (char *) NULL);
1352  if (arch == NULL)
1353    xexit (1);
1354  write_archive (arch);
1355}
1356
1357/* Update the timestamp of the symbol map of an archive.  */
1358
1359static void
1360ranlib_touch (const char *archname)
1361{
1362#ifdef __GO32__
1363  /* I don't think updating works on go32.  */
1364  ranlib_only (archname);
1365#else
1366  int f;
1367  bfd *arch;
1368  char **matching;
1369
1370  if (get_file_size (archname) < 1)
1371    return;
1372  f = open (archname, O_RDWR | O_BINARY, 0);
1373  if (f < 0)
1374    {
1375      bfd_set_error (bfd_error_system_call);
1376      bfd_fatal (archname);
1377    }
1378
1379  arch = bfd_fdopenr (archname, (const char *) NULL, f);
1380  if (arch == NULL)
1381    bfd_fatal (archname);
1382  if (! bfd_check_format_matches (arch, bfd_archive, &matching))
1383    {
1384      bfd_nonfatal (archname);
1385      if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1386	{
1387	  list_matching_formats (matching);
1388	  free (matching);
1389	}
1390      xexit (1);
1391    }
1392
1393  if (! bfd_has_map (arch))
1394    /* xgettext:c-format */
1395    fatal (_("%s: no archive map to update"), archname);
1396
1397  bfd_update_armap_timestamp (arch);
1398
1399  if (! bfd_close (arch))
1400    bfd_fatal (archname);
1401#endif
1402}
1403
1404/* Things which are interesting to map over all or some of the files: */
1405
1406static void
1407print_descr (bfd *abfd)
1408{
1409  print_arelt_descr (stdout, abfd, verbose);
1410}
1411