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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [binutils/] [ar.c] - Blame information for rev 233

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

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

powered by: WebSVN 2.1.0

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