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