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