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