OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [binutils/] [ar.c] - Blame information for rev 241

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 15 khays
/* ar.c - Archive modify and extract.
2
   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 166 khays
   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 15 khays
   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
 
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 166 khays
int deterministic = -1;                 /* Determinism indeterminate.  */
100 15 khays
 
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 166 khays
  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 15 khays
  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 166 khays
  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 15 khays
  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 166 khays
  while ((c = getopt_long (argc, argv, "hdmpqrtxlcoVsSuvabiMNfPTDU",
457 15 khays
                           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 166 khays
        case 'U':
554
          deterministic = FALSE;
555
          break;
556 15 khays
        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 166 khays
/* If neither -D nor -U was not specified explicitly,
579
   then use the configured default.  */
580 15 khays
static void
581 166 khays
default_deterministic (void)
582
{
583
  if (deterministic < 0)
584
    deterministic = DEFAULT_AR_DETERMINISTIC;
585
}
586
 
587
static void
588 15 khays
ranlib_main (int argc, char **argv)
589
{
590
  int arg_index, status = 0;
591
  bfd_boolean touch = FALSE;
592
  int c;
593
 
594 166 khays
  while ((c = getopt_long (argc, argv, "DhHUvVt", long_options, NULL)) != EOF)
595 15 khays
    {
596
      switch (c)
597
        {
598 166 khays
        case 'D':
599
          deterministic = TRUE;
600
          break;
601
        case 'U':
602
          deterministic = FALSE;
603
          break;
604 15 khays
        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 166 khays
 
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 15 khays
    }
628
 
629
  if (argc < 2)
630
    ranlib_usage (0);
631
 
632
  if (show_help)
633 166 khays
    ranlib_usage (1);
634 15 khays
 
635
  if (show_version)
636
    print_version ("ranlib");
637
 
638 166 khays
  default_deterministic ();
639
 
640 15 khays
  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 166 khays
      if (newer_only && deterministic > 0)
750
        fatal (_("`u' is not meaningful with the `D' option."));
751 15 khays
 
752 166 khays
      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 15 khays
      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 161 khays
          /* 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 15 khays
 
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 163 khays
      /* 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 15 khays
        {
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
  size_t ncopied = 0;
941
  char *cbuf = (char *) xmalloc (BUFSIZE);
942
  struct stat buf;
943
  size_t size;
944
  if (bfd_stat_arch_elt (abfd, &buf) != 0)
945
    /* xgettext:c-format */
946
    fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
947
 
948
  if (verbose)
949
    printf ("\n<%s>\n\n", bfd_get_filename (abfd));
950
 
951
  bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
952
 
953
  size = buf.st_size;
954
  while (ncopied < size)
955
    {
956
 
957
      size_t nread;
958
      size_t tocopy = size - ncopied;
959
      if (tocopy > BUFSIZE)
960
        tocopy = BUFSIZE;
961
 
962
      nread = bfd_bread (cbuf, (bfd_size_type) tocopy, abfd);
963
      if (nread != tocopy)
964
        /* xgettext:c-format */
965
        fatal (_("%s is not a valid archive"),
966
               bfd_get_filename (bfd_my_archive (abfd)));
967
 
968
      /* fwrite in mingw32 may return int instead of size_t. Cast the
969
         return value to size_t to avoid comparison between signed and
970
         unsigned values.  */
971
      if ((size_t) fwrite (cbuf, 1, nread, stdout) != nread)
972
        fatal ("stdout: %s", strerror (errno));
973
      ncopied += tocopy;
974
    }
975
  free (cbuf);
976
}
977
 
978
/* Extract a member of the archive into its own file.
979
 
980
   We defer opening the new file until after we have read a BUFSIZ chunk of the
981
   old one, since we know we have just read the archive header for the old
982
   one.  Since most members are shorter than BUFSIZ, this means we will read
983
   the old header, read the old data, write a new inode for the new file, and
984
   write the new data, and be done. This 'optimization' is what comes from
985
   sitting next to a bare disk and hearing it every time it seeks.  -- Gnu
986
   Gilmore  */
987
 
988
void
989
extract_file (bfd *abfd)
990
{
991
  FILE *ostream;
992
  char *cbuf = (char *) xmalloc (BUFSIZE);
993
  size_t nread, tocopy;
994
  size_t ncopied = 0;
995
  size_t size;
996
  struct stat buf;
997
 
998
  if (bfd_stat_arch_elt (abfd, &buf) != 0)
999
    /* xgettext:c-format */
1000
    fatal (_("internal stat error on %s"), bfd_get_filename (abfd));
1001
  size = buf.st_size;
1002
 
1003
  if (verbose)
1004
    printf ("x - %s\n", bfd_get_filename (abfd));
1005
 
1006
  bfd_seek (abfd, (file_ptr) 0, SEEK_SET);
1007
 
1008
  ostream = NULL;
1009
  if (size == 0)
1010
    {
1011
      /* Seems like an abstraction violation, eh?  Well it's OK! */
1012
      output_filename = bfd_get_filename (abfd);
1013
 
1014
      ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
1015
      if (ostream == NULL)
1016
        {
1017
          perror (bfd_get_filename (abfd));
1018
          xexit (1);
1019
        }
1020
 
1021
      output_file = ostream;
1022
    }
1023
  else
1024
    while (ncopied < size)
1025
      {
1026
        tocopy = size - ncopied;
1027
        if (tocopy > BUFSIZE)
1028
          tocopy = BUFSIZE;
1029
 
1030
        nread = bfd_bread (cbuf, (bfd_size_type) tocopy, abfd);
1031
        if (nread != tocopy)
1032
          /* xgettext:c-format */
1033
          fatal (_("%s is not a valid archive"),
1034
                 bfd_get_filename (bfd_my_archive (abfd)));
1035
 
1036
        /* See comment above; this saves disk arm motion */
1037
        if (ostream == NULL)
1038
          {
1039
            /* Seems like an abstraction violation, eh?  Well it's OK! */
1040
            output_filename = bfd_get_filename (abfd);
1041
 
1042
            ostream = fopen (bfd_get_filename (abfd), FOPEN_WB);
1043
            if (ostream == NULL)
1044
              {
1045
                perror (bfd_get_filename (abfd));
1046
                xexit (1);
1047
              }
1048
 
1049
            output_file = ostream;
1050
          }
1051
 
1052
        /* fwrite in mingw32 may return int instead of size_t. Cast
1053
           the return value to size_t to avoid comparison between
1054
           signed and unsigned values.  */
1055
        if ((size_t) fwrite (cbuf, 1, nread, ostream) != nread)
1056
          fatal ("%s: %s", output_filename, strerror (errno));
1057
        ncopied += tocopy;
1058
      }
1059
 
1060
  if (ostream != NULL)
1061
    fclose (ostream);
1062
 
1063
  output_file = NULL;
1064
  output_filename = NULL;
1065
 
1066
  chmod (bfd_get_filename (abfd), buf.st_mode);
1067
 
1068
  if (preserve_dates)
1069
    {
1070
      /* Set access time to modification time.  Only st_mtime is
1071
         initialized by bfd_stat_arch_elt.  */
1072
      buf.st_atime = buf.st_mtime;
1073
      set_times (bfd_get_filename (abfd), &buf);
1074
    }
1075
 
1076
  free (cbuf);
1077
}
1078
 
1079
static void
1080
write_archive (bfd *iarch)
1081
{
1082
  bfd *obfd;
1083
  char *old_name, *new_name;
1084
  bfd *contents_head = iarch->archive_next;
1085
 
1086
  old_name = (char *) xmalloc (strlen (bfd_get_filename (iarch)) + 1);
1087
  strcpy (old_name, bfd_get_filename (iarch));
1088
  new_name = make_tempname (old_name);
1089
 
1090
  if (new_name == NULL)
1091 163 khays
    bfd_fatal (_("could not create temporary file whilst writing archive"));
1092 15 khays
 
1093
  output_filename = new_name;
1094
 
1095
  obfd = bfd_openw (new_name, bfd_get_target (iarch));
1096
 
1097
  if (obfd == NULL)
1098
    bfd_fatal (old_name);
1099
 
1100
  output_bfd = obfd;
1101
 
1102
  bfd_set_format (obfd, bfd_archive);
1103
 
1104
  /* Request writing the archive symbol table unless we've
1105
     been explicitly requested not to.  */
1106
  obfd->has_armap = write_armap >= 0;
1107
 
1108
  if (ar_truncate)
1109
    {
1110
      /* This should really use bfd_set_file_flags, but that rejects
1111
         archives.  */
1112
      obfd->flags |= BFD_TRADITIONAL_FORMAT;
1113
    }
1114
 
1115
  if (deterministic)
1116
    obfd->flags |= BFD_DETERMINISTIC_OUTPUT;
1117
 
1118
  if (make_thin_archive || bfd_is_thin_archive (iarch))
1119
    bfd_is_thin_archive (obfd) = 1;
1120
 
1121
  if (!bfd_set_archive_head (obfd, contents_head))
1122
    bfd_fatal (old_name);
1123
 
1124
  if (!bfd_close (obfd))
1125
    bfd_fatal (old_name);
1126
 
1127
  output_bfd = NULL;
1128
  output_filename = NULL;
1129
 
1130
  /* We don't care if this fails; we might be creating the archive.  */
1131
  bfd_close (iarch);
1132
 
1133
  if (smart_rename (new_name, old_name, 0) != 0)
1134
    xexit (1);
1135
  free (old_name);
1136
}
1137
 
1138
/* Return a pointer to the pointer to the entry which should be rplacd'd
1139
   into when altering.  DEFAULT_POS should be how to interpret pos_default,
1140
   and should be a pos value.  */
1141
 
1142
static bfd **
1143
get_pos_bfd (bfd **contents, enum pos default_pos, const char *default_posname)
1144
{
1145
  bfd **after_bfd = contents;
1146
  enum pos realpos;
1147
  const char *realposname;
1148
 
1149
  if (postype == pos_default)
1150
    {
1151
      realpos = default_pos;
1152
      realposname = default_posname;
1153
    }
1154
  else
1155
    {
1156
      realpos = postype;
1157
      realposname = posname;
1158
    }
1159
 
1160
  if (realpos == pos_end)
1161
    {
1162
      while (*after_bfd)
1163
        after_bfd = &((*after_bfd)->archive_next);
1164
    }
1165
  else
1166
    {
1167
      for (; *after_bfd; after_bfd = &(*after_bfd)->archive_next)
1168
        if (FILENAME_CMP ((*after_bfd)->filename, realposname) == 0)
1169
          {
1170
            if (realpos == pos_after)
1171
              after_bfd = &(*after_bfd)->archive_next;
1172
            break;
1173
          }
1174
    }
1175
  return after_bfd;
1176
}
1177
 
1178
static void
1179
delete_members (bfd *arch, char **files_to_delete)
1180
{
1181
  bfd **current_ptr_ptr;
1182
  bfd_boolean found;
1183
  bfd_boolean something_changed = FALSE;
1184
  int match_count;
1185
 
1186
  for (; *files_to_delete != NULL; ++files_to_delete)
1187
    {
1188
      /* In a.out systems, the armap is optional.  It's also called
1189
         __.SYMDEF.  So if the user asked to delete it, we should remember
1190
         that fact. This isn't quite right for COFF systems (where
1191
         __.SYMDEF might be regular member), but it's very unlikely
1192
         to be a problem.  FIXME */
1193
 
1194
      if (!strcmp (*files_to_delete, "__.SYMDEF"))
1195
        {
1196
          arch->has_armap = FALSE;
1197
          write_armap = -1;
1198
          continue;
1199
        }
1200
 
1201
      found = FALSE;
1202
      match_count = 0;
1203
      current_ptr_ptr = &(arch->archive_next);
1204
      while (*current_ptr_ptr)
1205
        {
1206
          if (FILENAME_CMP (normalize (*files_to_delete, arch),
1207
                            (*current_ptr_ptr)->filename) == 0)
1208
            {
1209
              ++match_count;
1210
              if (counted_name_mode
1211
                  && match_count != counted_name_counter)
1212
                {
1213
                  /* Counting, and didn't match on count; go on to the
1214
                     next one.  */
1215
                }
1216
              else
1217
                {
1218
                  found = TRUE;
1219
                  something_changed = TRUE;
1220
                  if (verbose)
1221
                    printf ("d - %s\n",
1222
                            *files_to_delete);
1223
                  *current_ptr_ptr = ((*current_ptr_ptr)->archive_next);
1224
                  goto next_file;
1225
                }
1226
            }
1227
 
1228
          current_ptr_ptr = &((*current_ptr_ptr)->archive_next);
1229
        }
1230
 
1231
      if (verbose && !found)
1232
        {
1233
          /* xgettext:c-format */
1234
          printf (_("No member named `%s'\n"), *files_to_delete);
1235
        }
1236
    next_file:
1237
      ;
1238
    }
1239
 
1240
  if (something_changed)
1241
    write_archive (arch);
1242
  else
1243
    output_filename = NULL;
1244
}
1245
 
1246
 
1247
/* Reposition existing members within an archive */
1248
 
1249
static void
1250
move_members (bfd *arch, char **files_to_move)
1251
{
1252
  bfd **after_bfd;              /* New entries go after this one */
1253
  bfd **current_ptr_ptr;        /* cdr pointer into contents */
1254
 
1255
  for (; *files_to_move; ++files_to_move)
1256
    {
1257
      current_ptr_ptr = &(arch->archive_next);
1258
      while (*current_ptr_ptr)
1259
        {
1260
          bfd *current_ptr = *current_ptr_ptr;
1261
          if (FILENAME_CMP (normalize (*files_to_move, arch),
1262
                            current_ptr->filename) == 0)
1263
            {
1264
              /* Move this file to the end of the list - first cut from
1265
                 where it is.  */
1266
              bfd *link_bfd;
1267
              *current_ptr_ptr = current_ptr->archive_next;
1268
 
1269
              /* Now glue to end */
1270
              after_bfd = get_pos_bfd (&arch->archive_next, pos_end, NULL);
1271
              link_bfd = *after_bfd;
1272
              *after_bfd = current_ptr;
1273
              current_ptr->archive_next = link_bfd;
1274
 
1275
              if (verbose)
1276
                printf ("m - %s\n", *files_to_move);
1277
 
1278
              goto next_file;
1279
            }
1280
 
1281
          current_ptr_ptr = &((*current_ptr_ptr)->archive_next);
1282
        }
1283
      /* xgettext:c-format */
1284
      fatal (_("no entry %s in archive %s!"), *files_to_move, arch->filename);
1285
 
1286
    next_file:;
1287
    }
1288
 
1289
  write_archive (arch);
1290
}
1291
 
1292
/* Ought to default to replacing in place, but this is existing practice!  */
1293
 
1294
static void
1295
replace_members (bfd *arch, char **files_to_move, bfd_boolean quick)
1296
{
1297
  bfd_boolean changed = FALSE;
1298
  bfd **after_bfd;              /* New entries go after this one.  */
1299
  bfd *current;
1300
  bfd **current_ptr;
1301
 
1302
  while (files_to_move && *files_to_move)
1303
    {
1304
      if (! quick)
1305
        {
1306
          current_ptr = &arch->archive_next;
1307
          while (*current_ptr)
1308
            {
1309
              current = *current_ptr;
1310
 
1311
              /* For compatibility with existing ar programs, we
1312
                 permit the same file to be added multiple times.  */
1313
              if (FILENAME_CMP (normalize (*files_to_move, arch),
1314
                                normalize (current->filename, arch)) == 0
1315
                  && current->arelt_data != NULL)
1316
                {
1317
                  if (newer_only)
1318
                    {
1319
                      struct stat fsbuf, asbuf;
1320
 
1321
                      if (stat (*files_to_move, &fsbuf) != 0)
1322
                        {
1323
                          if (errno != ENOENT)
1324
                            bfd_fatal (*files_to_move);
1325
                          goto next_file;
1326
                        }
1327
                      if (bfd_stat_arch_elt (current, &asbuf) != 0)
1328
                        /* xgettext:c-format */
1329
                        fatal (_("internal stat error on %s"),
1330
                               current->filename);
1331
 
1332
                      if (fsbuf.st_mtime <= asbuf.st_mtime)
1333
                        goto next_file;
1334
                    }
1335
 
1336
                  after_bfd = get_pos_bfd (&arch->archive_next, pos_after,
1337
                                           current->filename);
1338
                  if (ar_emul_replace (after_bfd, *files_to_move,
1339
                                       target, verbose))
1340
                    {
1341
                      /* Snip out this entry from the chain.  */
1342
                      *current_ptr = (*current_ptr)->archive_next;
1343
                      changed = TRUE;
1344
                    }
1345
 
1346
                  goto next_file;
1347
                }
1348
              current_ptr = &(current->archive_next);
1349
            }
1350
        }
1351
 
1352
      /* Add to the end of the archive.  */
1353
      after_bfd = get_pos_bfd (&arch->archive_next, pos_end, NULL);
1354
 
1355
      if (ar_emul_append (after_bfd, *files_to_move, target,
1356
                          verbose, make_thin_archive))
1357
        changed = TRUE;
1358
 
1359
    next_file:;
1360
 
1361
      files_to_move++;
1362
    }
1363
 
1364
  if (changed)
1365
    write_archive (arch);
1366
  else
1367
    output_filename = NULL;
1368
}
1369
 
1370
static int
1371
ranlib_only (const char *archname)
1372
{
1373
  bfd *arch;
1374
 
1375
  if (get_file_size (archname) < 1)
1376
    return 1;
1377
  write_armap = 1;
1378
  arch = open_inarch (archname, (char *) NULL);
1379
  if (arch == NULL)
1380
    xexit (1);
1381
  write_archive (arch);
1382
  return 0;
1383
}
1384
 
1385
/* Update the timestamp of the symbol map of an archive.  */
1386
 
1387
static int
1388
ranlib_touch (const char *archname)
1389
{
1390
#ifdef __GO32__
1391
  /* I don't think updating works on go32.  */
1392
  ranlib_only (archname);
1393
#else
1394
  int f;
1395
  bfd *arch;
1396
  char **matching;
1397
 
1398
  if (get_file_size (archname) < 1)
1399
    return 1;
1400
  f = open (archname, O_RDWR | O_BINARY, 0);
1401
  if (f < 0)
1402
    {
1403
      bfd_set_error (bfd_error_system_call);
1404
      bfd_fatal (archname);
1405
    }
1406
 
1407
  arch = bfd_fdopenr (archname, (const char *) NULL, f);
1408
  if (arch == NULL)
1409
    bfd_fatal (archname);
1410
  if (! bfd_check_format_matches (arch, bfd_archive, &matching))
1411
    {
1412
      bfd_nonfatal (archname);
1413
      if (bfd_get_error () == bfd_error_file_ambiguously_recognized)
1414
        {
1415
          list_matching_formats (matching);
1416
          free (matching);
1417
        }
1418
      xexit (1);
1419
    }
1420
 
1421
  if (! bfd_has_map (arch))
1422
    /* xgettext:c-format */
1423
    fatal (_("%s: no archive map to update"), archname);
1424
 
1425 166 khays
  if (deterministic)
1426
    arch->flags |= BFD_DETERMINISTIC_OUTPUT;
1427
 
1428 15 khays
  bfd_update_armap_timestamp (arch);
1429
 
1430
  if (! bfd_close (arch))
1431
    bfd_fatal (archname);
1432
#endif
1433
  return 0;
1434
}
1435
 
1436
/* Things which are interesting to map over all or some of the files: */
1437
 
1438
static void
1439
print_descr (bfd *abfd)
1440
{
1441
  print_arelt_descr (stdout, abfd, verbose);
1442
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.