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