ar.c revision 61843
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 [-]{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    }
280  else
281    /* xgettext:c-format */
282    fprintf (s, _("Usage: %s [-vV] archive\n"), program_name);
283
284  list_supported_targets (program_name, stderr);
285
286  if (help)
287    fprintf (s, _("Report bugs to %s\n"), REPORT_BUGS_TO);
288
289  xexit (help ? 0 : 1);
290}
291
292/* Normalize a file name specified on the command line into a file
293   name which we will use in an archive.  */
294
295static const char *
296normalize (file, abfd)
297     const char *file;
298     bfd *abfd;
299{
300  const char *filename;
301
302  if (full_pathname)
303    return file;
304
305  filename = strrchr (file, '/');
306#ifdef HAVE_DOS_BASED_FILE_SYSTEM
307  {
308    /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
309    char *bslash = strrchr (file, '\\');
310    if (bslash > filename)
311      filename = bslash;
312    if (filename == NULL && file[0] != '\0' && file[1] == ':')
313	filename = file + 1;
314  }
315#endif
316  if (filename != (char *) NULL)
317    filename++;
318  else
319    filename = file;
320
321  if (ar_truncate
322      && abfd != NULL
323      && strlen (filename) > abfd->xvec->ar_max_namelen)
324    {
325      char *s;
326
327      /* Space leak.  */
328      s = (char *) xmalloc (abfd->xvec->ar_max_namelen + 1);
329      memcpy (s, filename, abfd->xvec->ar_max_namelen);
330      s[abfd->xvec->ar_max_namelen] = '\0';
331      filename = s;
332    }
333
334  return filename;
335}
336
337/* Remove any output file.  This is only called via xatexit.  */
338
339static const char *output_filename = NULL;
340static FILE *output_file = NULL;
341static bfd *output_bfd = NULL;
342
343static void
344remove_output ()
345{
346  if (output_filename != NULL)
347    {
348      if (output_bfd != NULL && output_bfd->iostream != NULL)
349	fclose ((FILE *) (output_bfd->iostream));
350      if (output_file != NULL)
351	fclose (output_file);
352      unlink (output_filename);
353    }
354}
355
356/* The option parsing should be in its own function.
357   It will be when I have getopt working.  */
358
359int
360main (argc, argv)
361     int argc;
362     char **argv;
363{
364  char *arg_ptr;
365  char c;
366  enum
367    {
368      none = 0, delete, replace, print_table,
369      print_files, extract, move, quick_append
370    } operation = none;
371  int arg_index;
372  char **files;
373  int file_count;
374  char *inarch_filename;
375  int show_version;
376
377#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
378  setlocale (LC_MESSAGES, "");
379#endif
380  bindtextdomain (PACKAGE, LOCALEDIR);
381  textdomain (PACKAGE);
382
383  program_name = argv[0];
384  xmalloc_set_program_name (program_name);
385
386  if (is_ranlib < 0)
387    {
388      char *temp;
389
390      temp = strrchr (program_name, '/');
391#ifdef HAVE_DOS_BASED_FILE_SYSTEM
392	{
393	  /* We could have foo/bar\\baz, or foo\\bar, or d:bar.  */
394	  char *bslash = strrchr (program_name, '\\');
395	  if (bslash > temp)
396	    temp = bslash;
397	  if (temp == NULL && program_name[0] != '\0' && program_name[1] == ':')
398	    temp = program_name + 1;
399	}
400#endif
401      if (temp == NULL)
402	temp = program_name;
403      else
404	++temp;
405      if (strlen (temp) >= 6
406	  && FILENAME_CMP (temp + strlen (temp) - 6, "ranlib") == 0)
407	is_ranlib = 1;
408      else
409	is_ranlib = 0;
410    }
411
412  if (argc > 1 && argv[1][0] == '-')
413    {
414      if (strcmp (argv[1], "--help") == 0)
415	usage (1);
416      else if (strcmp (argv[1], "--version") == 0)
417	{
418	  if (is_ranlib)
419	    print_version ("ranlib");
420	  else
421	    print_version ("ar");
422	}
423    }
424
425  START_PROGRESS (program_name, 0);
426
427  bfd_init ();
428  set_default_bfd_target ();
429
430  show_version = 0;
431
432  xatexit (remove_output);
433
434  if (is_ranlib)
435    {
436      boolean touch = false;
437
438      if (argc < 2 || strcmp (argv[1], "--help") == 0)
439	usage (0);
440      if (strcmp (argv[1], "-V") == 0
441	  || strcmp (argv[1], "-v") == 0
442	  || strncmp (argv[1], "--v", 3) == 0)
443	print_version ("ranlib");
444      arg_index = 1;
445      if (strcmp (argv[1], "-t") == 0)
446	{
447	  ++arg_index;
448	  touch = true;
449	}
450      while (arg_index < argc)
451	{
452	  if (! touch)
453	    ranlib_only (argv[arg_index]);
454	  else
455	    ranlib_touch (argv[arg_index]);
456	  ++arg_index;
457	}
458      xexit (0);
459    }
460
461  if (argc == 2 && strcmp (argv[1], "-M") == 0)
462    {
463      mri_emul ();
464      xexit (0);
465    }
466
467  if (argc < 2)
468    usage (0);
469
470  arg_ptr = argv[1];
471
472  if (*arg_ptr == '-')
473    ++arg_ptr;			/* compatibility */
474
475  while ((c = *arg_ptr++) != '\0')
476    {
477      switch (c)
478	{
479	case 'd':
480	case 'm':
481	case 'p':
482	case 'q':
483	case 'r':
484	case 't':
485	case 'x':
486	  if (operation != none)
487	    fatal (_("two different operation options specified"));
488	  switch (c)
489	    {
490	    case 'd':
491	      operation = delete;
492	      operation_alters_arch = true;
493	      break;
494	    case 'm':
495	      operation = move;
496	      operation_alters_arch = true;
497	      break;
498	    case 'p':
499	      operation = print_files;
500	      break;
501	    case 'q':
502	      operation = quick_append;
503	      operation_alters_arch = true;
504	      break;
505	    case 'r':
506	      operation = replace;
507	      operation_alters_arch = true;
508	      break;
509	    case 't':
510	      operation = print_table;
511	      break;
512	    case 'x':
513	      operation = extract;
514	      break;
515	    }
516	case 'l':
517	  break;
518	case 'c':
519	  silent_create = 1;
520	  break;
521	case 'o':
522	  preserve_dates = 1;
523	  break;
524	case 'V':
525	  show_version = true;
526	  break;
527	case 's':
528	  write_armap = 1;
529	  break;
530	case 'S':
531	  write_armap = -1;
532	  break;
533	case 'u':
534	  newer_only = 1;
535	  break;
536	case 'v':
537	  verbose = 1;
538	  break;
539	case 'a':
540	  postype = pos_after;
541	  break;
542	case 'b':
543	  postype = pos_before;
544	  break;
545	case 'i':
546	  postype = pos_before;
547	  break;
548	case 'M':
549	  mri_mode = 1;
550	  break;
551	case 'N':
552	  counted_name_mode = true;
553	  break;
554	case 'f':
555	  ar_truncate = true;
556	  break;
557	case 'P':
558	  full_pathname = true;
559	  break;
560	default:
561	  /* xgettext:c-format */
562	  non_fatal (_("illegal option -- %c"), c);
563	  usage (0);
564	}
565    }
566
567  if (show_version)
568    print_version ("ar");
569
570  if (argc < 3)
571    usage (0);
572
573  if (mri_mode)
574    {
575      mri_emul ();
576    }
577  else
578    {
579      bfd *arch;
580
581      /* We can't write an armap when using ar q, so just do ar r
582         instead.  */
583      if (operation == quick_append && write_armap)
584	operation = replace;
585
586      if ((operation == none || operation == print_table)
587	  && write_armap == 1)
588	{
589	  ranlib_only (argv[2]);
590	  xexit (0);
591	}
592
593      if (operation == none)
594	fatal (_("no operation specified"));
595
596      if (newer_only && operation != replace)
597	fatal (_("`u' is only meaningful with the `r' option."));
598
599      arg_index = 2;
600
601      if (postype != pos_default)
602	posname = argv[arg_index++];
603
604      if (counted_name_mode)
605	{
606          if (operation != extract && operation != delete)
607	     fatal (_("`N' is only meaningful with the `x' and `d' options."));
608	  counted_name_counter = atoi (argv[arg_index++]);
609          if (counted_name_counter <= 0)
610	    fatal (_("Value for `N' must be positive."));
611	}
612
613      inarch_filename = argv[arg_index++];
614
615      files = arg_index < argc ? argv + arg_index : NULL;
616      file_count = argc - arg_index;
617
618#if 0
619      /* We don't use do_quick_append any more.  Too many systems
620         expect ar to always rebuild the symbol table even when q is
621         used.  */
622
623      /* We can't do a quick append if we need to construct an
624	 extended name table, because do_quick_append won't be able to
625	 rebuild the name table.  Unfortunately, at this point we
626	 don't actually know the maximum name length permitted by this
627	 object file format.  So, we guess.  FIXME.  */
628      if (operation == quick_append && ! ar_truncate)
629	{
630	  char **chk;
631
632	  for (chk = files; chk != NULL && *chk != '\0'; chk++)
633	    {
634	      if (strlen (normalize (*chk, (bfd *) NULL)) > 14)
635		{
636		  operation = replace;
637		  break;
638		}
639	    }
640	}
641
642      if (operation == quick_append)
643	{
644	  /* Note that quick appending to a non-existent archive creates it,
645	     even if there are no files to append. */
646	  do_quick_append (inarch_filename, files);
647	  xexit (0);
648	}
649#endif
650
651      arch = open_inarch (inarch_filename,
652			  files == NULL ? (char *) NULL : files[0]);
653
654      switch (operation)
655	{
656	case print_table:
657	  map_over_members (arch, print_descr, files, file_count);
658	  break;
659
660	case print_files:
661	  map_over_members (arch, print_contents, files, file_count);
662	  break;
663
664	case extract:
665	  map_over_members (arch, extract_file, files, file_count);
666	  break;
667
668	case delete:
669	  if (files != NULL)
670	    delete_members (arch, files);
671	  else
672	    output_filename = NULL;
673	  break;
674
675	case move:
676	  if (files != NULL)
677	    move_members (arch, files);
678	  else
679	    output_filename = NULL;
680	  break;
681
682	case replace:
683	case quick_append:
684	  if (files != NULL || write_armap > 0)
685	    replace_members (arch, files, operation == quick_append);
686	  else
687	    output_filename = NULL;
688	  break;
689
690	  /* Shouldn't happen! */
691	default:
692	  /* xgettext:c-format */
693	  fatal (_("internal error -- this option not implemented"));
694	}
695    }
696
697  END_PROGRESS (program_name);
698
699  xexit (0);
700  return 0;
701}
702
703bfd *
704open_inarch (archive_filename, file)
705     const char *archive_filename;
706     const char *file;
707{
708  const char *target;
709  bfd **last_one;
710  bfd *next_one;
711  struct stat sbuf;
712  bfd *arch;
713  char **matching;
714
715  bfd_set_error (bfd_error_no_error);
716
717  target = NULL;
718
719  if (stat (archive_filename, &sbuf) != 0)
720    {
721#if !defined(__GO32__) || defined(__DJGPP__)
722
723      /* FIXME: I don't understand why this fragment was ifndef'ed
724	 away for __GO32__; perhaps it was in the days of DJGPP v1.x.
725	 stat() works just fine in v2.x, so I think this should be
726	 removed.  For now, I enable it for DJGPP v2. -- EZ.  */
727
728/* KLUDGE ALERT! Temporary fix until I figger why
729   stat() is wrong ... think it's buried in GO32's IDT - Jax */
730      if (errno != ENOENT)
731	bfd_fatal (archive_filename);
732#endif
733
734      if (!operation_alters_arch)
735	{
736	  fprintf (stderr, "%s: ", program_name);
737	  perror (archive_filename);
738	  maybequit ();
739	  return NULL;
740	}
741
742      /* Try to figure out the target to use for the archive from the
743         first object on the list.  */
744      if (file != NULL)
745	{
746	  bfd *obj;
747
748	  obj = bfd_openr (file, NULL);
749	  if (obj != NULL)
750	    {
751	      if (bfd_check_format (obj, bfd_object))
752		target = bfd_get_target (obj);
753	      (void) bfd_close (obj);
754	    }
755	}
756
757      /* Create an empty archive.  */
758      arch = bfd_openw (archive_filename, target);
759      if (arch == NULL
760	  || ! bfd_set_format (arch, bfd_archive)
761	  || ! bfd_close (arch))
762	bfd_fatal (archive_filename);
763
764      /* If we die creating a new archive, don't leave it around.  */
765      output_filename = archive_filename;
766    }
767
768  arch = bfd_openr (archive_filename, target);
769  if (arch == NULL)
770    {
771    bloser:
772      bfd_fatal (archive_filename);
773    }
774
775  if (! bfd_check_format_matches (arch, bfd_archive, &matching))
776    {
777      bfd_nonfatal (archive_filename);
778      if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
779	{
780	  list_matching_formats (matching);
781	  free (matching);
782	}
783      xexit (1);
784    }
785
786  last_one = &(arch->next);
787  /* Read all the contents right away, regardless.  */
788  for (next_one = bfd_openr_next_archived_file (arch, NULL);
789       next_one;
790       next_one = bfd_openr_next_archived_file (arch, next_one))
791    {
792      PROGRESS (1);
793      *last_one = next_one;
794      last_one = &next_one->next;
795    }
796  *last_one = (bfd *) NULL;
797  if (bfd_get_error () != bfd_error_no_more_archived_files)
798    goto bloser;
799  return arch;
800}
801
802static void
803print_contents (abfd)
804     bfd *abfd;
805{
806  int ncopied = 0;
807  char *cbuf = xmalloc (BUFSIZE);
808  struct stat buf;
809  long size;
810  if (bfd_stat_arch_elt (abfd, &buf) != 0)
811    /* xgettext:c-format */
812    fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
813
814  if (verbose)
815    printf ("\n<%s>\n\n", bfd_get_filename (abfd));
816
817  bfd_seek (abfd, 0, SEEK_SET);
818
819  size = buf.st_size;
820  while (ncopied < size)
821    {
822
823      int nread;
824      int tocopy = size - ncopied;
825      if (tocopy > BUFSIZE)
826	tocopy = BUFSIZE;
827
828      nread = bfd_read (cbuf, 1, tocopy, abfd);	/* oops -- broke
829							   abstraction!  */
830      if (nread != tocopy)
831	/* xgettext:c-format */
832	fatal (_("%s is not a valid archive"),
833	       bfd_get_filename (bfd_my_archive (abfd)));
834      fwrite (cbuf, 1, nread, stdout);
835      ncopied += tocopy;
836    }
837  free (cbuf);
838}
839
840/* Extract a member of the archive into its own file.
841
842   We defer opening the new file until after we have read a BUFSIZ chunk of the
843   old one, since we know we have just read the archive header for the old
844   one.  Since most members are shorter than BUFSIZ, this means we will read
845   the old header, read the old data, write a new inode for the new file, and
846   write the new data, and be done. This 'optimization' is what comes from
847   sitting next to a bare disk and hearing it every time it seeks.  -- Gnu
848   Gilmore  */
849
850void
851extract_file (abfd)
852     bfd *abfd;
853{
854  FILE *ostream;
855  char *cbuf = xmalloc (BUFSIZE);
856  int nread, tocopy;
857  long ncopied = 0;
858  long size;
859  struct stat buf;
860
861  if (bfd_stat_arch_elt (abfd, &buf) != 0)
862    /* xgettext:c-format */
863    fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
864  size = buf.st_size;
865
866  if (size < 0)
867    /* xgettext:c-format */
868    fatal (_("stat returns negative size for %s"), bfd_get_filename (abfd));
869
870  if (verbose)
871    printf ("x - %s\n", bfd_get_filename (abfd));
872
873  bfd_seek (abfd, 0, SEEK_SET);
874
875  ostream = NULL;
876  if (size == 0)
877    {
878      /* Seems like an abstraction violation, eh?  Well it's OK! */
879      output_filename = bfd_get_filename (abfd);
880
881      ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
882      if (ostream == NULL)
883	{
884	  perror (bfd_get_filename (abfd));
885	  xexit (1);
886	}
887
888      output_file = ostream;
889    }
890  else
891    while (ncopied < size)
892      {
893	tocopy = size - ncopied;
894	if (tocopy > BUFSIZE)
895	  tocopy = BUFSIZE;
896
897	nread = bfd_read (cbuf, 1, tocopy, abfd);
898	if (nread != tocopy)
899	  /* xgettext:c-format */
900	  fatal (_("%s is not a valid archive"),
901		 bfd_get_filename (bfd_my_archive (abfd)));
902
903	/* See comment above; this saves disk arm motion */
904	if (ostream == NULL)
905	  {
906	    /* Seems like an abstraction violation, eh?  Well it's OK! */
907	    output_filename = bfd_get_filename (abfd);
908
909	    ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
910	    if (ostream == NULL)
911	      {
912		perror (bfd_get_filename (abfd));
913		xexit (1);
914	      }
915
916	    output_file = ostream;
917	  }
918	fwrite (cbuf, 1, nread, ostream);
919	ncopied += tocopy;
920      }
921
922  if (ostream != NULL)
923    fclose (ostream);
924
925  output_file = NULL;
926  output_filename = NULL;
927
928  chmod (bfd_get_filename (abfd), buf.st_mode);
929
930  if (preserve_dates)
931    set_times (bfd_get_filename (abfd), &buf);
932
933  free (cbuf);
934}
935
936#if 0
937
938/* We don't use this anymore.  Too many systems expect ar to rebuild
939   the symbol table even when q is used.  */
940
941/* Just do it quickly; don't worry about dups, armap, or anything like that */
942
943static void
944do_quick_append (archive_filename, files_to_append)
945     const char *archive_filename;
946     char **files_to_append;
947{
948  FILE *ofile, *ifile;
949  char *buf = xmalloc (BUFSIZE);
950  long tocopy, thistime;
951  bfd *temp;
952  struct stat sbuf;
953  boolean newfile = false;
954  bfd_set_error (bfd_error_no_error);
955
956  if (stat (archive_filename, &sbuf) != 0)
957    {
958
959#if !defined(__GO32__) || defined(__DJGPP__)
960
961      /* FIXME: I don't understand why this fragment was ifndef'ed
962	 away for __GO32__; perhaps it was in the days of DJGPP v1.x.
963	 stat() works just fine in v2.x, so I think this should be
964	 removed.  For now, I enable it for DJGPP v2.
965
966	 (And yes, I know this is all unused, but somebody, someday,
967	 might wish to resurrect this again... -- EZ.  */
968
969/* KLUDGE ALERT! Temporary fix until I figger why
970   stat() is wrong ... think it's buried in GO32's IDT - Jax  */
971
972      if (errno != ENOENT)
973	bfd_fatal (archive_filename);
974#endif
975
976      newfile = true;
977    }
978
979  ofile = fopen (archive_filename, FOPEN_AUB);
980  if (ofile == NULL)
981    {
982      perror (program_name);
983      xexit (1);
984    }
985
986  temp = bfd_openr (archive_filename, NULL);
987  if (temp == NULL)
988    {
989      bfd_fatal (archive_filename);
990    }
991  if (newfile == false)
992    {
993      if (bfd_check_format (temp, bfd_archive) != true)
994	/* xgettext:c-format */
995	fatal (_("%s is not an archive"), archive_filename);
996    }
997  else
998    {
999      fwrite (ARMAG, 1, SARMAG, ofile);
1000      if (!silent_create)
1001	/* xgettext:c-format */
1002	non_fatal (_("creating %s"), archive_filename);
1003    }
1004
1005  if (ar_truncate)
1006    temp->flags |= BFD_TRADITIONAL_FORMAT;
1007
1008  /* assume it's an achive, go straight to the end, sans $200 */
1009  fseek (ofile, 0, 2);
1010
1011  for (; files_to_append && *files_to_append; ++files_to_append)
1012    {
1013      struct ar_hdr *hdr = bfd_special_undocumented_glue (temp, *files_to_append);
1014      if (hdr == NULL)
1015	{
1016	  bfd_fatal (*files_to_append);
1017	}
1018
1019      BFD_SEND (temp, _bfd_truncate_arname, (temp, *files_to_append, (char *) hdr));
1020
1021      ifile = fopen (*files_to_append, FOPEN_RB);
1022      if (ifile == NULL)
1023	{
1024	  bfd_nonfatal (*files_to_append);
1025	}
1026
1027      if (stat (*files_to_append, &sbuf) != 0)
1028	{
1029	  bfd_nonfatal (*files_to_append);
1030	}
1031
1032      tocopy = sbuf.st_size;
1033
1034      /* XXX should do error-checking! */
1035      fwrite (hdr, 1, sizeof (struct ar_hdr), ofile);
1036
1037      while (tocopy > 0)
1038	{
1039	  thistime = tocopy;
1040	  if (thistime > BUFSIZE)
1041	    thistime = BUFSIZE;
1042	  fread (buf, 1, thistime, ifile);
1043	  fwrite (buf, 1, thistime, ofile);
1044	  tocopy -= thistime;
1045	}
1046      fclose (ifile);
1047      if ((sbuf.st_size % 2) == 1)
1048	putc ('\012', ofile);
1049    }
1050  fclose (ofile);
1051  bfd_close (temp);
1052  free (buf);
1053}
1054
1055#endif /* 0 */
1056
1057static void
1058write_archive (iarch)
1059     bfd *iarch;
1060{
1061  bfd *obfd;
1062  char *old_name, *new_name;
1063  bfd *contents_head = iarch->next;
1064
1065  old_name = xmalloc (strlen (bfd_get_filename (iarch)) + 1);
1066  strcpy (old_name, bfd_get_filename (iarch));
1067  new_name = make_tempname (old_name);
1068
1069  output_filename = new_name;
1070
1071  obfd = bfd_openw (new_name, bfd_get_target (iarch));
1072
1073  if (obfd == NULL)
1074    bfd_fatal (old_name);
1075
1076  output_bfd = obfd;
1077
1078  bfd_set_format (obfd, bfd_archive);
1079
1080  /* Request writing the archive symbol table unless we've
1081     been explicitly requested not to.  */
1082  obfd->has_armap = write_armap >= 0;
1083
1084  if (ar_truncate)
1085    {
1086      /* This should really use bfd_set_file_flags, but that rejects
1087         archives.  */
1088      obfd->flags |= BFD_TRADITIONAL_FORMAT;
1089    }
1090
1091  if (bfd_set_archive_head (obfd, contents_head) != true)
1092    bfd_fatal (old_name);
1093
1094  if (!bfd_close (obfd))
1095    bfd_fatal (old_name);
1096
1097  output_bfd = NULL;
1098  output_filename = NULL;
1099
1100  /* We don't care if this fails; we might be creating the archive.  */
1101  bfd_close (iarch);
1102
1103  if (smart_rename (new_name, old_name, 0) != 0)
1104    xexit (1);
1105}
1106
1107/* Return a pointer to the pointer to the entry which should be rplacd'd
1108   into when altering.  DEFAULT_POS should be how to interpret pos_default,
1109   and should be a pos value.  */
1110
1111static bfd **
1112get_pos_bfd (contents, default_pos, default_posname)
1113     bfd **contents;
1114     enum pos default_pos;
1115     const char *default_posname;
1116{
1117  bfd **after_bfd = contents;
1118  enum pos realpos;
1119  const char *realposname;
1120
1121  if (postype == pos_default)
1122    {
1123      realpos = default_pos;
1124      realposname = default_posname;
1125    }
1126  else
1127    {
1128      realpos = postype;
1129      realposname = posname;
1130    }
1131
1132  if (realpos == pos_end)
1133    {
1134      while (*after_bfd)
1135	after_bfd = &((*after_bfd)->next);
1136    }
1137  else
1138    {
1139      for (; *after_bfd; after_bfd = &(*after_bfd)->next)
1140	if (FILENAME_CMP ((*after_bfd)->filename, realposname) == 0)
1141	  {
1142	    if (realpos == pos_after)
1143	      after_bfd = &(*after_bfd)->next;
1144	    break;
1145	  }
1146    }
1147  return after_bfd;
1148}
1149
1150static void
1151delete_members (arch, files_to_delete)
1152     bfd *arch;
1153     char **files_to_delete;
1154{
1155  bfd **current_ptr_ptr;
1156  boolean found;
1157  boolean something_changed = false;
1158  int match_count;
1159
1160  for (; *files_to_delete != NULL; ++files_to_delete)
1161    {
1162      /* In a.out systems, the armap is optional.  It's also called
1163	 __.SYMDEF.  So if the user asked to delete it, we should remember
1164	 that fact. This isn't quite right for COFF systems (where
1165	 __.SYMDEF might be regular member), but it's very unlikely
1166	 to be a problem.  FIXME */
1167
1168      if (!strcmp (*files_to_delete, "__.SYMDEF"))
1169	{
1170	  arch->has_armap = false;
1171	  write_armap = -1;
1172	  continue;
1173	}
1174
1175      found = false;
1176      match_count = 0;
1177      current_ptr_ptr = &(arch->next);
1178      while (*current_ptr_ptr)
1179	{
1180	  if (FILENAME_CMP (normalize (*files_to_delete, arch),
1181		      (*current_ptr_ptr)->filename) == 0)
1182	    {
1183	      ++match_count;
1184	      if (counted_name_mode
1185		  && match_count != counted_name_counter)
1186		{
1187		  /* Counting, and didn't match on count; go on to the
1188                     next one.  */
1189		}
1190	      else
1191		{
1192		  found = true;
1193		  something_changed = true;
1194		  if (verbose)
1195		    printf ("d - %s\n",
1196			    *files_to_delete);
1197		  *current_ptr_ptr = ((*current_ptr_ptr)->next);
1198		  goto next_file;
1199		}
1200	    }
1201
1202	  current_ptr_ptr = &((*current_ptr_ptr)->next);
1203	}
1204
1205      if (verbose && found == false)
1206	{
1207	  /* xgettext:c-format */
1208	  printf (_("No member named `%s'\n"), *files_to_delete);
1209	}
1210    next_file:
1211      ;
1212    }
1213
1214  if (something_changed == true)
1215    write_archive (arch);
1216  else
1217    output_filename = NULL;
1218}
1219
1220
1221/* Reposition existing members within an archive */
1222
1223static void
1224move_members (arch, files_to_move)
1225     bfd *arch;
1226     char **files_to_move;
1227{
1228  bfd **after_bfd;		/* New entries go after this one */
1229  bfd **current_ptr_ptr;	/* cdr pointer into contents */
1230
1231  for (; *files_to_move; ++files_to_move)
1232    {
1233      current_ptr_ptr = &(arch->next);
1234      while (*current_ptr_ptr)
1235	{
1236	  bfd *current_ptr = *current_ptr_ptr;
1237	  if (FILENAME_CMP (normalize (*files_to_move, arch),
1238			    current_ptr->filename) == 0)
1239	    {
1240	      /* Move this file to the end of the list - first cut from
1241		 where it is.  */
1242	      bfd *link;
1243	      *current_ptr_ptr = current_ptr->next;
1244
1245	      /* Now glue to end */
1246	      after_bfd = get_pos_bfd (&arch->next, pos_end, NULL);
1247	      link = *after_bfd;
1248	      *after_bfd = current_ptr;
1249	      current_ptr->next = link;
1250
1251	      if (verbose)
1252		printf ("m - %s\n", *files_to_move);
1253
1254	      goto next_file;
1255	    }
1256
1257	  current_ptr_ptr = &((*current_ptr_ptr)->next);
1258	}
1259      /* xgettext:c-format */
1260      fatal (_("no entry %s in archive %s!"), *files_to_move, arch->filename);
1261
1262    next_file:;
1263    }
1264
1265  write_archive (arch);
1266}
1267
1268/* Ought to default to replacing in place, but this is existing practice!  */
1269
1270static void
1271replace_members (arch, files_to_move, quick)
1272     bfd *arch;
1273     char **files_to_move;
1274     boolean quick;
1275{
1276  boolean changed = false;
1277  bfd **after_bfd;		/* New entries go after this one */
1278  bfd *current;
1279  bfd **current_ptr;
1280  bfd *temp;
1281
1282  while (files_to_move && *files_to_move)
1283    {
1284      if (! quick)
1285	{
1286	  current_ptr = &arch->next;
1287	  while (*current_ptr)
1288	    {
1289	      current = *current_ptr;
1290
1291	      /* For compatibility with existing ar programs, we
1292		 permit the same file to be added multiple times.  */
1293	      if (FILENAME_CMP (normalize (*files_to_move, arch),
1294				normalize (current->filename, arch)) == 0
1295		  && current->arelt_data != NULL)
1296		{
1297		  if (newer_only)
1298		    {
1299		      struct stat fsbuf, asbuf;
1300
1301		      if (stat (*files_to_move, &fsbuf) != 0)
1302			{
1303			  if (errno != ENOENT)
1304			    bfd_fatal (*files_to_move);
1305			  goto next_file;
1306			}
1307		      if (bfd_stat_arch_elt (current, &asbuf) != 0)
1308			/* xgettext:c-format */
1309			fatal (_("internal stat error on %s"), current->filename);
1310
1311		      if (fsbuf.st_mtime <= asbuf.st_mtime)
1312			goto next_file;
1313		    }
1314
1315		  after_bfd = get_pos_bfd (&arch->next, pos_after,
1316					   current->filename);
1317		  temp = *after_bfd;
1318
1319		  *after_bfd = bfd_openr (*files_to_move, NULL);
1320		  if (*after_bfd == (bfd *) NULL)
1321		    {
1322		      bfd_fatal (*files_to_move);
1323		    }
1324		  (*after_bfd)->next = temp;
1325
1326		  /* snip out this entry from the chain */
1327		  *current_ptr = (*current_ptr)->next;
1328
1329		  if (verbose)
1330		    {
1331		      printf ("r - %s\n", *files_to_move);
1332		    }
1333
1334		  changed = true;
1335
1336		  goto next_file;
1337		}
1338	      current_ptr = &(current->next);
1339	    }
1340	}
1341
1342      /* Add to the end of the archive.  */
1343
1344      after_bfd = get_pos_bfd (&arch->next, pos_end, NULL);
1345      temp = *after_bfd;
1346      *after_bfd = bfd_openr (*files_to_move, NULL);
1347      if (*after_bfd == (bfd *) NULL)
1348	{
1349	  bfd_fatal (*files_to_move);
1350	}
1351      if (verbose)
1352	{
1353	  printf ("a - %s\n", *files_to_move);
1354	}
1355
1356      (*after_bfd)->next = temp;
1357
1358      changed = true;
1359
1360    next_file:;
1361
1362      files_to_move++;
1363    }
1364
1365  if (changed)
1366    write_archive (arch);
1367  else
1368    output_filename = NULL;
1369}
1370
1371static void
1372ranlib_only (archname)
1373     const char *archname;
1374{
1375  bfd *arch;
1376
1377  write_armap = 1;
1378  arch = open_inarch (archname, (char *) NULL);
1379  if (arch == NULL)
1380    xexit (1);
1381  write_archive (arch);
1382}
1383
1384/* Update the timestamp of the symbol map of an archive.  */
1385
1386static void
1387ranlib_touch (archname)
1388     const char *archname;
1389{
1390#ifdef __GO32__
1391  /* I don't think updating works on go32.  */
1392  ranlib_only (archname);
1393#else
1394  int f;
1395  bfd *arch;
1396  char **matching;
1397
1398  f = open (archname, O_RDWR | O_BINARY, 0);
1399  if (f < 0)
1400    {
1401      bfd_set_error (bfd_error_system_call);
1402      bfd_fatal (archname);
1403    }
1404
1405  arch = bfd_fdopenr (archname, (const char *) NULL, f);
1406  if (arch == NULL)
1407    bfd_fatal (archname);
1408  if (! bfd_check_format_matches (arch, bfd_archive, &matching))
1409    {
1410      bfd_nonfatal (archname);
1411      if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1412	{
1413	  list_matching_formats (matching);
1414	  free (matching);
1415	}
1416      xexit (1);
1417    }
1418
1419  if (! bfd_has_map (arch))
1420    /* xgettext:c-format */
1421    fatal (_("%s: no archive map to update"), archname);
1422
1423  bfd_update_armap_timestamp (arch);
1424
1425  if (! bfd_close (arch))
1426    bfd_fatal (archname);
1427#endif
1428}
1429
1430/* Things which are interesting to map over all or some of the files: */
1431
1432static void
1433print_descr (abfd)
1434     bfd *abfd;
1435{
1436  print_arelt_descr (stdout, abfd, verbose);
1437}
1438