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