X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=binutils%2Far.c;h=ea1b456d9e56b15e3d8979a70e75a6096fd0f394;hb=ff0a3bf8241108b84d35feee538f05ca23fa4e75;hp=bdc5103872a025418eb1b43ec53f34b682e80326;hpb=a20a10a650d7948012d62d0341812cbf8ac5fde8;p=deliverable%2Fbinutils-gdb.git diff --git a/binutils/ar.c b/binutils/ar.c index bdc5103872..ea1b456d9e 100644 --- a/binutils/ar.c +++ b/binutils/ar.c @@ -1,30 +1,31 @@ /* ar.c - Archive modify and extract. - Copyright 1991, 92, 93, 94, 95, 96, 97, 98, 1999 + Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, + 2001, 2002 Free Software Foundation, Inc. -This file is part of GNU Binutils. + This file is part of GNU Binutils. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Bugs: should use getopt the way tar does (complete w/optional -) and should have long options too. GNU ar used to check file against filesystem in quick_update and replace operations (would check mtime). Doesn't warn when name truncated. No way to specify pos_end. Error messages should be - more consistant. -*/ + more consistant. */ + #include "bfd.h" #include "libiberty.h" #include "progress.h" @@ -32,6 +33,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "aout/ar.h" #include "libbfd.h" #include "arsup.h" +#include "filenames.h" +#include "binemul.h" #include #ifdef __GO32___ @@ -215,11 +218,11 @@ map_over_members (arch, function, files, count) bfd_stat_arch_elt (head, &buf); } if ((head->filename != NULL) && - (!strcmp (normalize (*files, arch), head->filename))) + (!FILENAME_CMP (normalize (*files, arch), head->filename))) { ++match_count; if (counted_name_mode - && match_count != counted_name_counter) + && match_count != counted_name_counter) { /* Counting, and didn't match on count; go on to the next one. */ @@ -245,11 +248,11 @@ usage (help) FILE *s; s = help ? stdout : stderr; - + if (! is_ranlib) { /* xgettext:c-format */ - fprintf (s, _("Usage: %s [-]{dmpqrstx}[abcfilNoPsSuvV] [member-name] [count] archive-file file...\n"), + fprintf (s, _("Usage: %s [emulation options] [-]{dmpqrstx}[abcfilNoPsSuvV] [member-name] [count] archive-file file...\n"), program_name); /* xgettext:c-format */ fprintf (s, _(" %s -M [ filename)) + filename = bslash; + if (filename == NULL && file[0] != '\0' && file[1] == ':') + filename = file + 1; + } +#endif if (filename != (char *) NULL) filename++; else @@ -345,6 +366,8 @@ remove_output () /* The option parsing should be in its own function. It will be when I have getopt working. */ +int main PARAMS ((int, char **)); + int main (argc, argv) int argc; @@ -362,9 +385,13 @@ main (argc, argv) int file_count; char *inarch_filename; int show_version; + int i; #if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES) setlocale (LC_MESSAGES, ""); +#endif +#if defined (HAVE_SETLOCALE) + setlocale (LC_CTYPE, ""); #endif bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); @@ -377,12 +404,22 @@ main (argc, argv) char *temp; temp = strrchr (program_name, '/'); +#ifdef HAVE_DOS_BASED_FILE_SYSTEM + { + /* We could have foo/bar\\baz, or foo\\bar, or d:bar. */ + char *bslash = strrchr (program_name, '\\'); + if (temp == NULL || (bslash != NULL && bslash > temp)) + temp = bslash; + if (temp == NULL && program_name[0] != '\0' && program_name[1] == ':') + temp = program_name + 1; + } +#endif if (temp == NULL) temp = program_name; else ++temp; if (strlen (temp) >= 6 - && strcmp (temp + strlen (temp) - 6, "ranlib") == 0) + && FILENAME_CMP (temp + strlen (temp) - 6, "ranlib") == 0) is_ranlib = 1; else is_ranlib = 0; @@ -410,11 +447,20 @@ main (argc, argv) xatexit (remove_output); + for (i = 1; i < argc; i++) + if (! ar_emul_parse_arg (argv[i])) + break; + argv += (i - 1); + argc -= (i - 1); + if (is_ranlib) { boolean touch = false; - if (argc < 2 || strcmp (argv[1], "--help") == 0) + if (argc < 2 + || strcmp (argv[1], "--help") == 0 + || strcmp (argv[1], "-h") == 0 + || strcmp (argv[1], "-H") == 0) usage (0); if (strcmp (argv[1], "-V") == 0 || strcmp (argv[1], "-v") == 0 @@ -538,7 +584,7 @@ main (argc, argv) break; default: /* xgettext:c-format */ - fprintf (stderr, _("%s: illegal option -- %c\n"), program_name, c); + non_fatal (_("illegal option -- %c"), c); usage (0); } } @@ -580,12 +626,12 @@ main (argc, argv) if (postype != pos_default) posname = argv[arg_index++]; - if (counted_name_mode) + if (counted_name_mode) { - if (operation != extract && operation != delete) - fatal (_("`N' is only meaningful with the `x' and 'd' options.")); + if (operation != extract && operation != delete) + fatal (_("`N' is only meaningful with the `x' and `d' options.")); counted_name_counter = atoi (argv[arg_index++]); - if (counted_name_counter <= 0) + if (counted_name_counter <= 0) fatal (_("Value for `N' must be positive.")); } @@ -621,7 +667,7 @@ main (argc, argv) if (operation == quick_append) { /* Note that quick appending to a non-existent archive creates it, - even if there are no files to append. */ + even if there are no files to append. */ do_quick_append (inarch_filename, files); xexit (0); } @@ -669,9 +715,7 @@ main (argc, argv) /* Shouldn't happen! */ default: /* xgettext:c-format */ - fprintf (stderr, _("%s: internal error -- this option not implemented\n"), - program_name); - xexit (1); + fatal (_("internal error -- this option not implemented")); } } @@ -699,12 +743,15 @@ open_inarch (archive_filename, file) if (stat (archive_filename, &sbuf) != 0) { -#ifndef __GO32__ +#if !defined(__GO32__) || defined(__DJGPP__) + + /* FIXME: I don't understand why this fragment was ifndef'ed + away for __GO32__; perhaps it was in the days of DJGPP v1.x. + stat() works just fine in v2.x, so I think this should be + removed. For now, I enable it for DJGPP v2. -- EZ. */ /* KLUDGE ALERT! Temporary fix until I figger why - * stat() is wrong ... think it's buried in GO32's IDT - * - Jax - */ + stat() is wrong ... think it's buried in GO32's IDT - Jax */ if (errno != ENOENT) bfd_fatal (archive_filename); #endif @@ -790,9 +837,10 @@ print_contents (abfd) fatal (_("internal stat error on %s"), bfd_get_filename (abfd)); if (verbose) - printf ("\n<%s>\n\n", bfd_get_filename (abfd)); + /* xgettext:c-format */ + printf (_("\n\n\n"), bfd_get_filename (abfd)); - bfd_seek (abfd, 0, SEEK_SET); + bfd_seek (abfd, (file_ptr) 0, SEEK_SET); size = buf.st_size; while (ncopied < size) @@ -803,8 +851,7 @@ print_contents (abfd) if (tocopy > BUFSIZE) tocopy = BUFSIZE; - nread = bfd_read (cbuf, 1, tocopy, abfd); /* oops -- broke - abstraction! */ + nread = bfd_bread (cbuf, (bfd_size_type) tocopy, abfd); if (nread != tocopy) /* xgettext:c-format */ fatal (_("%s is not a valid archive"), @@ -835,7 +882,7 @@ extract_file (abfd) long ncopied = 0; long size; struct stat buf; - + if (bfd_stat_arch_elt (abfd, &buf) != 0) /* xgettext:c-format */ fatal (_("internal stat error on %s"), bfd_get_filename (abfd)); @@ -844,11 +891,11 @@ extract_file (abfd) if (size < 0) /* xgettext:c-format */ fatal (_("stat returns negative size for %s"), bfd_get_filename (abfd)); - + if (verbose) printf ("x - %s\n", bfd_get_filename (abfd)); - bfd_seek (abfd, 0, SEEK_SET); + bfd_seek (abfd, (file_ptr) 0, SEEK_SET); ostream = NULL; if (size == 0) @@ -872,7 +919,7 @@ extract_file (abfd) if (tocopy > BUFSIZE) tocopy = BUFSIZE; - nread = bfd_read (cbuf, 1, tocopy, abfd); + nread = bfd_bread (cbuf, (bfd_size_type) tocopy, abfd); if (nread != tocopy) /* xgettext:c-format */ fatal (_("%s is not a valid archive"), @@ -934,12 +981,18 @@ do_quick_append (archive_filename, files_to_append) if (stat (archive_filename, &sbuf) != 0) { -#ifndef __GO32__ +#if !defined(__GO32__) || defined(__DJGPP__) + + /* FIXME: I don't understand why this fragment was ifndef'ed + away for __GO32__; perhaps it was in the days of DJGPP v1.x. + stat() works just fine in v2.x, so I think this should be + removed. For now, I enable it for DJGPP v2. + + (And yes, I know this is all unused, but somebody, someday, + might wish to resurrect this again... -- EZ. */ /* KLUDGE ALERT! Temporary fix until I figger why - * stat() is wrong ... think it's buried in GO32's IDT - * - Jax - */ + stat() is wrong ... think it's buried in GO32's IDT - Jax */ if (errno != ENOENT) bfd_fatal (archive_filename); @@ -971,8 +1024,7 @@ do_quick_append (archive_filename, files_to_append) fwrite (ARMAG, 1, SARMAG, ofile); if (!silent_create) /* xgettext:c-format */ - fprintf (stderr, _("%s: creating %s\n"), - program_name, archive_filename); + non_fatal (_("creating %s"), archive_filename); } if (ar_truncate) @@ -1110,7 +1162,7 @@ get_pos_bfd (contents, default_pos, default_posname) else { for (; *after_bfd; after_bfd = &(*after_bfd)->next) - if (strcmp ((*after_bfd)->filename, realposname) == 0) + if (FILENAME_CMP ((*after_bfd)->filename, realposname) == 0) { if (realpos == pos_after) after_bfd = &(*after_bfd)->next; @@ -1150,12 +1202,12 @@ delete_members (arch, files_to_delete) current_ptr_ptr = &(arch->next); while (*current_ptr_ptr) { - if (strcmp (normalize (*files_to_delete, arch), - (*current_ptr_ptr)->filename) == 0) + if (FILENAME_CMP (normalize (*files_to_delete, arch), + (*current_ptr_ptr)->filename) == 0) { ++match_count; if (counted_name_mode - && match_count != counted_name_counter) + && match_count != counted_name_counter) { /* Counting, and didn't match on count; go on to the next one. */ @@ -1207,8 +1259,8 @@ move_members (arch, files_to_move) while (*current_ptr_ptr) { bfd *current_ptr = *current_ptr_ptr; - if (strcmp (normalize (*files_to_move, arch), - current_ptr->filename) == 0) + if (FILENAME_CMP (normalize (*files_to_move, arch), + current_ptr->filename) == 0) { /* Move this file to the end of the list - first cut from where it is. */ @@ -1230,9 +1282,8 @@ move_members (arch, files_to_move) current_ptr_ptr = &((*current_ptr_ptr)->next); } /* xgettext:c-format */ - fprintf (stderr, _("%s: no entry %s in archive %s!\n"), - program_name, *files_to_move, arch->filename); - xexit (1); + fatal (_("no entry %s in archive %s!"), *files_to_move, arch->filename); + next_file:; } @@ -1251,7 +1302,6 @@ replace_members (arch, files_to_move, quick) bfd **after_bfd; /* New entries go after this one */ bfd *current; bfd **current_ptr; - bfd *temp; while (files_to_move && *files_to_move) { @@ -1264,8 +1314,8 @@ replace_members (arch, files_to_move, quick) /* For compatibility with existing ar programs, we permit the same file to be added multiple times. */ - if (strcmp (normalize (*files_to_move, arch), - normalize (current->filename, arch)) == 0 + if (FILENAME_CMP (normalize (*files_to_move, arch), + normalize (current->filename, arch)) == 0 && current->arelt_data != NULL) { if (newer_only) @@ -1280,7 +1330,8 @@ replace_members (arch, files_to_move, quick) } if (bfd_stat_arch_elt (current, &asbuf) != 0) /* xgettext:c-format */ - fatal (_("internal stat error on %s"), current->filename); + fatal (_("internal stat error on %s"), + current->filename); if (fsbuf.st_mtime <= asbuf.st_mtime) goto next_file; @@ -1288,24 +1339,13 @@ replace_members (arch, files_to_move, quick) after_bfd = get_pos_bfd (&arch->next, pos_after, current->filename); - temp = *after_bfd; - - *after_bfd = bfd_openr (*files_to_move, NULL); - if (*after_bfd == (bfd *) NULL) + if (ar_emul_replace (after_bfd, *files_to_move, + verbose)) { - bfd_fatal (*files_to_move); + /* Snip out this entry from the chain. */ + *current_ptr = (*current_ptr)->next; + changed = true; } - (*after_bfd)->next = temp; - - /* snip out this entry from the chain */ - *current_ptr = (*current_ptr)->next; - - if (verbose) - { - printf ("r - %s\n", *files_to_move); - } - - changed = true; goto next_file; } @@ -1314,22 +1354,9 @@ replace_members (arch, files_to_move, quick) } /* Add to the end of the archive. */ - after_bfd = get_pos_bfd (&arch->next, pos_end, NULL); - temp = *after_bfd; - *after_bfd = bfd_openr (*files_to_move, NULL); - if (*after_bfd == (bfd *) NULL) - { - bfd_fatal (*files_to_move); - } - if (verbose) - { - printf ("a - %s\n", *files_to_move); - } - - (*after_bfd)->next = temp; - - changed = true; + if (ar_emul_append (after_bfd, *files_to_move, verbose)) + changed = true; next_file:;