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