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