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