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