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