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