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