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