Subversion Repositories Kolibri OS

Rev

Rev 5221 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5219 serge 1
/* ar.c - Archive modify and extract.
6324 serge 2
   Copyright (C) 1991-2015 Free Software Foundation, Inc.
5219 serge 3
 
4
   This file is part of GNU Binutils.
5
 
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 3 of the License, or
9
   (at your option) any later version.
10
 
11
   This program is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
   GNU General Public License for more details.
15
 
16
   You should have received a copy of the GNU General Public License
17
   along with this program; if not, write to the Free Software
18
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19
   MA 02110-1301, USA.  */
20
 
21
/*
22
   Bugs: GNU ar used to check file against filesystem in quick_update and
23
   replace operations (would check mtime). Doesn't warn when name truncated.
24
   No way to specify pos_end. Error messages should be more consistent.  */
25
 
26
#include "sysdep.h"
27
#include "bfd.h"
28
#include "libiberty.h"
29
#include "progress.h"
30
#include "getopt.h"
31
#include "aout/ar.h"
32
#include "libbfd.h"
33
#include "bucomm.h"
34
#include "arsup.h"
35
#include "filenames.h"
36
#include "binemul.h"
37
#include "plugin.h"
38
 
39
#ifdef __GO32___
40
#define EXT_NAME_LEN 3		/* Bufflen of addition to name if it's MS-DOS.  */
41
#else
42
#define EXT_NAME_LEN 6		/* Ditto for *NIX.  */
43
#endif
44
 
45
/* Static declarations.  */
46
 
47
static void mri_emul (void);
48
static const char *normalize (const char *, bfd *);
49
static void remove_output (void);
50
static void map_over_members (bfd *, void (*)(bfd *), char **, int);
51
static void print_contents (bfd * member);
52
static void delete_members (bfd *, char **files_to_delete);
53
 
54
static void move_members (bfd *, char **files_to_move);
55
static void replace_members
56
  (bfd *, char **files_to_replace, bfd_boolean quick);
57
static void print_descr (bfd * abfd);
58
static void write_archive (bfd *);
59
static int  ranlib_only (const char *archname);
60
static int  ranlib_touch (const char *archname);
61
static void usage (int);
62
 
63
/** Globals and flags.  */
64
 
65
static int mri_mode;
66
 
67
/* This flag distinguishes between ar and ranlib:
68
   1 means this is 'ranlib'; 0 means this is 'ar'.
69
   -1 means if we should use argv[0] to decide.  */
70
extern int is_ranlib;
71
 
72
/* Nonzero means don't warn about creating the archive file if necessary.  */
73
int silent_create = 0;
74
 
75
/* Nonzero means describe each action performed.  */
76
int verbose = 0;
77
 
78
/* Nonzero means preserve dates of members when extracting them.  */
79
int preserve_dates = 0;
80
 
81
/* Nonzero means don't replace existing members whose dates are more recent
82
   than the corresponding files.  */
83
int newer_only = 0;
84
 
85
/* Controls the writing of an archive symbol table (in BSD: a __.SYMDEF
86
   member).  -1 means we've been explicitly asked to not write a symbol table;
87
   +1 means we've been explicitly asked to write it;
88
 
89
   Traditionally, the default in BSD has been to not write the table.
90
   However, for POSIX.2 compliance the default is now to write a symbol table
91
   if any of the members are object files.  */
92
int write_armap = 0;
93
 
94
/* Operate in deterministic mode: write zero for timestamps, uids,
95
   and gids for archive members and the archive symbol table, and write
96
   consistent file modes.  */
97
int deterministic = -1;			/* Determinism indeterminate.  */
98
 
99
/* Nonzero means it's the name of an existing member; position new or moved
100
   files with respect to this one.  */
101
char *posname = NULL;
102
 
103
/* Sez how to use `posname': pos_before means position before that member.
104
   pos_after means position after that member. pos_end means always at end.
105
   pos_default means default appropriately. For the latter two, `posname'
106
   should also be zero.  */
107
enum pos
108
  {
109
    pos_default, pos_before, pos_after, pos_end
110
  } postype = pos_default;
111
 
112
enum operations
113
  {
114
    none = 0, del, replace, print_table,
115
    print_files, extract, move, quick_append
116
  } operation = none;
117
 
118
static bfd **
119
get_pos_bfd (bfd **, enum pos, const char *);
120
 
121
/* For extract/delete only.  If COUNTED_NAME_MODE is TRUE, we only
122
   extract the COUNTED_NAME_COUNTER instance of that name.  */
123
static bfd_boolean counted_name_mode = 0;
124
static int counted_name_counter = 0;
125
 
126
/* Whether to truncate names of files stored in the archive.  */
127
static bfd_boolean ar_truncate = FALSE;
128
 
129
/* Whether to use a full file name match when searching an archive.
130
   This is convenient for archives created by the Microsoft lib
131
   program.  */
132
static bfd_boolean full_pathname = FALSE;
133
 
134
/* Whether to create a "thin" archive (symbol index only -- no files).  */
135
static bfd_boolean make_thin_archive = FALSE;
136
 
137
static int show_version = 0;
138
 
139
static int show_help = 0;
140
 
6324 serge 141
#if BFD_SUPPORTS_PLUGINS
142
static const char *plugin_target = "plugin";
143
#else
5219 serge 144
static const char *plugin_target = NULL;
6324 serge 145
#endif
5219 serge 146
 
147
static const char *target = NULL;
148
 
149
#define OPTION_PLUGIN 201
150
#define OPTION_TARGET 202
151
 
152
static struct option long_options[] =
153
{
154
  {"help", no_argument, &show_help, 1},
155
  {"plugin", required_argument, NULL, OPTION_PLUGIN},
156
  {"target", required_argument, NULL, OPTION_TARGET},
157
  {"version", no_argument, &show_version, 1},
158
  {NULL, no_argument, NULL, 0}
159
};
160
 
161
int interactive = 0;
162
 
163
static void
164
mri_emul (void)
165
{
6324 serge 166
  interactive = 0;//isatty (fileno (stdin));
5219 serge 167
  yyparse ();
168
}
169
 
170
/* If COUNT is 0, then FUNCTION is called once on each entry.  If nonzero,
171
   COUNT is the length of the FILES chain; FUNCTION is called on each entry
172
   whose name matches one in FILES.  */
173
 
174
static void
175
map_over_members (bfd *arch, void (*function)(bfd *), char **files, int count)
176
{
177
  bfd *head;
178
  int match_count;
179
 
180
  if (count == 0)
181
    {
182
      for (head = arch->archive_next; head; head = head->archive_next)
183
	{
184
	  PROGRESS (1);
185
	  function (head);
186
	}
187
      return;
188
    }
189
 
190
  /* This may appear to be a baroque way of accomplishing what we want.
191
     However we have to iterate over the filenames in order to notice where
192
     a filename is requested but does not exist in the archive.  Ditto
193
     mapping over each file each time -- we want to hack multiple
194
     references.  */
195
 
196
  for (head = arch->archive_next; head; head = head->archive_next)
197
    head->archive_pass = 0;
198
 
199
  for (; count > 0; files++, count--)
200
    {
201
      bfd_boolean found = FALSE;
202
 
203
      match_count = 0;
204
      for (head = arch->archive_next; head; head = head->archive_next)
205
	{
206
	  const char * filename;
207
 
208
	  PROGRESS (1);
209
	  /* PR binutils/15796: Once an archive element has been matched
210
	     do not match it again.  If the user provides multiple same-named
211
	     parameters on the command line their intent is to match multiple
212
	     same-named entries in the archive, not the same entry multiple
213
	     times.  */
214
	  if (head->archive_pass)
215
	    continue;
216
 
217
	  filename = head->filename;
218
	  if (filename == NULL)
219
	    {
220
	      /* Some archive formats don't get the filenames filled in
221
		 until the elements are opened.  */
222
	      struct stat buf;
223
	      bfd_stat_arch_elt (head, &buf);
224
	    }
225
	  else if (bfd_is_thin_archive (arch))
226
	    {
227
	      /* Thin archives store full pathnames.  Need to normalize.  */
228
	      filename = normalize (filename, arch);
229
	    }
230
 
231
	  if (filename != NULL
232
	      && !FILENAME_CMP (normalize (*files, arch), filename))
233
	    {
234
	      ++match_count;
235
	      if (counted_name_mode
236
		  && match_count != counted_name_counter)
237
		{
238
		  /* Counting, and didn't match on count; go on to the
239
                     next one.  */
240
		  continue;
241
		}
242
 
243
	      found = TRUE;
244
	      function (head);
245
	      head->archive_pass = 1;
246
	      /* PR binutils/15796: Once a file has been matched, do not
247
		 match any more same-named files in the archive.  If the
248
		 user does want to match multiple same-name files in an
249
		 archive they should provide multiple same-name parameters
250
		 to the ar command.  */
251
	      break;
252
	    }
253
	}
254
 
255
      if (!found)
256
	/* xgettext:c-format */
257
	fprintf (stderr, _("no entry %s in archive\n"), *files);
258
    }
259
}
260
 
261
bfd_boolean operation_alters_arch = FALSE;
262
 
263
static void
264
usage (int help)
265
{
266
  FILE *s;
267
 
268
#if BFD_SUPPORTS_PLUGINS
269
  /* xgettext:c-format */
270
  const char *command_line
271
    = _("Usage: %s [emulation options] [-]{dmpqrstx}[abcDfilMNoPsSTuvV]"
272
	" [--plugin ] [member-name] [count] archive-file file...\n");
273
 
274
#else
275
  /* xgettext:c-format */
276
  const char *command_line
277
    = _("Usage: %s [emulation options] [-]{dmpqrstx}[abcDfilMNoPsSTuvV]"
278
	" [member-name] [count] archive-file file...\n");
279
#endif
280
  s = help ? stdout : stderr;
281
 
282
  fprintf (s, command_line, program_name);
283
 
284
  /* xgettext:c-format */
285
  fprintf (s, _("       %s -M [
286
  fprintf (s, _(" commands:\n"));
287
  fprintf (s, _("  d            - delete file(s) from the archive\n"));
288
  fprintf (s, _("  m[ab]        - move file(s) in the archive\n"));
289
  fprintf (s, _("  p            - print file(s) found in the archive\n"));
290
  fprintf (s, _("  q[f]         - quick append file(s) to the archive\n"));
291
  fprintf (s, _("  r[ab][f][u]  - replace existing or insert new file(s) into the archive\n"));
292
  fprintf (s, _("  s            - act as ranlib\n"));
293
  fprintf (s, _("  t            - display contents of archive\n"));
294
  fprintf (s, _("  x[o]         - extract file(s) from the archive\n"));
295
  fprintf (s, _(" command specific modifiers:\n"));
296
  fprintf (s, _("  [a]          - put file(s) after [member-name]\n"));
297
  fprintf (s, _("  [b]          - put file(s) before [member-name] (same as [i])\n"));
298
  if (DEFAULT_AR_DETERMINISTIC)
299
    {
300
      fprintf (s, _("\
301
  [D]          - use zero for timestamps and uids/gids (default)\n"));
302
      fprintf (s, _("\
303
  [U]          - use actual timestamps and uids/gids\n"));
304
    }
305
  else
306
    {
307
      fprintf (s, _("\
308
  [D]          - use zero for timestamps and uids/gids\n"));
309
      fprintf (s, _("\
310
  [U]          - use actual timestamps and uids/gids (default)\n"));
311
    }
312
  fprintf (s, _("  [N]          - use instance [count] of name\n"));
313
  fprintf (s, _("  [f]          - truncate inserted file names\n"));
314
  fprintf (s, _("  [P]          - use full path names when matching\n"));
315
  fprintf (s, _("  [o]          - preserve original dates\n"));
316
  fprintf (s, _("  [u]          - only replace files that are newer than current archive contents\n"));
317
  fprintf (s, _(" generic modifiers:\n"));
318
  fprintf (s, _("  [c]          - do not warn if the library had to be created\n"));
319
  fprintf (s, _("  [s]          - create an archive index (cf. ranlib)\n"));
320
  fprintf (s, _("  [S]          - do not build a symbol table\n"));
321
  fprintf (s, _("  [T]          - make a thin archive\n"));
322
  fprintf (s, _("  [v]          - be verbose\n"));
323
  fprintf (s, _("  [V]          - display the version number\n"));
324
  fprintf (s, _("  @      - read options from \n"));
325
  fprintf (s, _("  --target=BFDNAME - specify the target object format as BFDNAME\n"));
326
#if BFD_SUPPORTS_PLUGINS
327
  fprintf (s, _(" optional:\n"));
328
  fprintf (s, _("  --plugin 

- load the specified plugin\n"));

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