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