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