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