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