]> Git Repo - binutils.git/blobdiff - binutils/ar.c
misc fixes
[binutils.git] / binutils / ar.c
index 244a15a1bd300778117b4754f3b85b9ffdb910eb..c77abb97bb81447ec1bd7b29470a252e824d4851 100644 (file)
@@ -1,5 +1,5 @@
 /* ar.c - Archive modify and extract.
-   Copyright (C) 1991 Free Software Foundation, Inc.
+   Copyright 1991, 1992 Free Software Foundation, Inc.
 
 This file is part of GNU Binutils.
 
@@ -31,30 +31,52 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "../bfd/libbfd.h"
 #include "arsup.h"
 #include <stdio.h>
-#ifdef USG
+#ifdef POSIX_UTIME
+#include <utime.h>
+#else /* ! POSIX_UTIME */
+#ifdef USE_UTIME
 #include <time.h>
-#else
+#else /* ! USE_UTIME */
 #include <sys/time.h>
-#endif
+#endif /* ! USE_UTIME */
+#endif /* ! POSIX_UTIME */
 #include <errno.h>
+#ifndef errno
+extern int errno;
+#endif
 #define BUFSIZE 8192
 
-void EXFUN(open_inarch,(char *archive_filename));
+/* Kludge declaration from BFD!  This is ugly!  FIXME!  XXX */
+
+struct ar_hdr *
+bfd_special_undocumented_glue PARAMS ((bfd *abfd, char *filename));
+
+/* Forward declarations */
+
+static void
+print_contents PARAMS ((bfd * member));
+
+static void
+delete_members PARAMS ((char **files_to_delete));
+
+static void
+do_quick_append PARAMS ((char *archive_filename, char **files_to_append));
+
+static void
+move_members PARAMS ((char **files_to_move));
+
+static void
+replace_members PARAMS ((char **files_to_replace));
 
+static void
+print_descr PARAMS ((bfd * abfd));
 
-PROTO(void, print_contents, (bfd * member));
-PROTO(void, extract_file, (bfd * abfd));
-PROTO(void, delete_members, (char **files_to_delete));
-PROTO(void, do_quick_append, (char *archive_filename, char **files_to_append));
-PROTO(void, move_members, (char **files_to_move));
-PROTO(void, replace_members, (char **files_to_replace));
-PROTO(void, print_descr, (bfd * abfd));
-PROTO(void, ranlib_only, (char *archname));
+static void
+ranlib_only PARAMS ((char *archname));
 
 /** Globals and flags */
 
 char           *program_name = NULL;
-bfd             bogus_archive;
 bfd            *inarch;                /* The input arch we're manipulating */
 
 int mri_mode;
@@ -73,13 +95,16 @@ int             preserve_dates = 0;
    than the corresponding files.
 */
 int             newer_only = 0;
-/* write a __.SYMDEF member into the modified archive.  */
-boolean         write_armap = false;
-/*
-   Nonzero means don't update __.SYMDEF unless command line explicitly
-   requested it
-*/
-int             ignore_symdef = 0;
+
+/* Controls the writing of an archive symbol table (in BSD: a __.SYMDEF
+   member).  -1 means we've been explicitly asked to not write a symbol table;
+   +1 means we've been explictly asked to write it;
+   0 is the default.
+   Traditionally, the default in BSD has been to not write the table.
+   However, for Posix.2 compliance the default is now to write a symbol table
+   if any of the members are object files. */
+int write_armap = 0;
+
 /*
    Nonzero means it's the name of an existing member; position new or moved
    files with respect to this one.
@@ -152,11 +177,20 @@ DEFUN(map_over_members,(function, files, count),
   for (; count > 0; files++, count--) {
     boolean         found = false;
     for (head = inarch->next; head; head = head->next)
-     if ((head->filename != NULL) &&
-        (!strcmp(*files, head->filename))) {
-       found = true;
-       function(head);
-     }
+    {
+      if (head->filename == NULL)
+      {
+       /* Some archive formats don't get the filenames filled in
+          'till the elements are opened */
+       struct stat buf;
+       bfd_stat_arch_elt(head, &buf);
+      }
+      if ((head->filename != NULL) &&
+         (!strcmp(*files, head->filename))) {
+       found = true;
+       function(head);
+      }
+    }
     if (!found)
      fprintf(stderr, "No entry %s in archive.\n", *files);
   }
@@ -165,6 +199,24 @@ DEFUN(map_over_members,(function, files, count),
 
 boolean operation_alters_arch = false;
 
+extern char *program_version;
+
+void
+do_show_version ()
+{
+  printf ("%s version %s\n", program_name, program_version);
+}
+
+void
+usage ()
+{
+  fprintf(stderr, "ar %s\n\
+Usage: %s [-]{dmpqrtx}[abcilosuv] [member-name] archive-file file...\n\
+       %s -M [<mri-script]\n",
+         program_version, program_name, program_name);
+  exit(1);
+}
+
 /*
    The option parsing should be in its own function.  It will be when I have
    getopt working.
@@ -184,9 +236,10 @@ main(argc, argv)
   char          **files;
   char           *inarch_filename;
   char           *temp;
+  int           show_version;
 
   bfd_init();
-verbose = 1;
+  show_version = 0;
 #ifdef GNU960
   check_v960( argc, argv );
   default_target = bfd_make_targ_name(BFD_COFF_FORMAT,HOST_BYTE_ORDER_BIG_P);
@@ -201,16 +254,24 @@ verbose = 1;
    ++temp;
   if (is_ranlib > 0 || (is_ranlib < 0 && strcmp(temp, "ranlib") == 0)) {
     if (argc < 2)
-     bfd_fatal("Too few command arguments.");
-    ranlib_only(argv[1]);
+      usage ();
+    arg_ptr = argv[1];
+    if (strcmp(argv[1], "-V") == 0 || strcmp(argv[1], "-v") == 0) {
+      do_show_version();
+      if (argc == 2)
+       exit(0);
+      arg_ptr = argv[2];
+    }
+    ranlib_only(arg_ptr);
   }
 
   if (argc == 2 && strcmp(argv[1],"-M") == 0) {
     mri_emul();
     exit(0);
   }
-  if (argc < 3)
-   bfd_fatal("Too few command arguments.");
+
+  if (argc < 2)
+    usage ();
 
   arg_ptr = argv[1];
 
@@ -263,8 +324,11 @@ verbose = 1;
      case 'o':
       preserve_dates = 1;
       break;
+     case 'V':
+      show_version = true;
+      break;
      case 's':
-      write_armap = true;
+      write_armap = 1;
       break;
      case 'u':
       newer_only = 1;
@@ -290,12 +354,21 @@ verbose = 1;
     }
   }
 
+  if (show_version)
+     do_show_version();
+
+  if (argc < 3)
+    if (show_version)
+       exit(0);
+    else
+      usage ();
+
   if (mri_mode) {
     mri_emul();
   }
   else {
     if ((operation == none || operation == print_table) 
-       && write_armap == true)
+       && write_armap == 1)
      ranlib_only(argv[2]);
 
     if (operation == none)
@@ -311,16 +384,7 @@ verbose = 1;
 
     inarch_filename = argv[arg_index++];
 
-    if (arg_index < argc) {
-      files = argv + arg_index;
-      while (arg_index < argc)
-       if (!strcmp(argv[arg_index++], "__.SYMDEF")) {
-        ignore_symdef = 1;
-        break;
-       }
-    }
-    else
-     files = NULL;
+    files = arg_index < argc ? argv + arg_index : NULL;
 
     if (operation == quick_append) {
       if (files != NULL)
@@ -330,16 +394,7 @@ verbose = 1;
 
 
     open_inarch(inarch_filename);
-    /*
-      If we have no archive, and we've been asked to replace then create one
-      */
-#if 0
-    if (operation == replace && inarch == &bogus_archive) {
-      silent_create = 1;
-      do_quick_append(inarch_filename, 0);
-      open_inarch(inarch_filename);
-    }
-#endif
+
     switch (operation) {
 
      case print_table:
@@ -365,7 +420,7 @@ verbose = 1;
       break;
 
      case replace:
-      if (files != NULL || write_armap)
+      if (files != NULL || write_armap > 0)
        replace_members(files);
       break;
 
@@ -391,7 +446,7 @@ char *file;
     return filename;
 }
 
- void
+int 
 open_inarch(archive_filename)
     char           *archive_filename;
 {
@@ -406,53 +461,49 @@ open_inarch(archive_filename)
          fprintf (stderr, "%s: %s not found.\n", program_name,
                   archive_filename);
          maybequit();
-         return ;
+         return 0;
        }       
-       if (!silent_create)
-           fprintf(stderr,
-                   "%s: creating %s\n", program_name, archive_filename);
-
-       inarch = &bogus_archive;
-       inarch->filename = archive_filename;
-       inarch->has_armap = true;
 
+       /* This routine is one way to forcibly create the archive. */
+       do_quick_append(archive_filename, 0);
     }
-    else {
+
 #ifdef GNU960
-       inarch = bfd_openr(archive_filename, default_target);
+    inarch = bfd_openr(archive_filename, default_target);
 #else
-       inarch = bfd_openr(archive_filename, NULL);
+    inarch = bfd_openr(archive_filename, NULL);
 #endif
-       if (inarch == NULL) {
-    bloser:
-           bfd_perror(archive_filename);
-           exit(1);
-       }
+    if (inarch == NULL) {
+      bloser:
+        fprintf (stderr, "%s: ", program_name);
+       bfd_perror(archive_filename);
+       exit(1);
+    }
 
-       if (bfd_check_format(inarch, bfd_archive) != true)
-           fatal("File %s is not an archive.", archive_filename);
+    if (bfd_check_format(inarch, bfd_archive) != true)
+       fatal("File %s is not an archive.", archive_filename);
 #ifdef GNU960
-       gnu960_verify_target(inarch);   /* Exits on failure */
+    gnu960_verify_target(inarch);      /* Exits on failure */
 #endif
-       last_one = &(inarch->next);
-       /* Read all the contents right away, regardless. */
-       for (next_one = bfd_openr_next_archived_file(inarch, NULL);
-            next_one;
-            next_one = bfd_openr_next_archived_file(inarch, next_one)) {
-           *last_one = next_one;
-           last_one = &next_one->next;
-       }
-       *last_one = (bfd *) NULL;
-       if (bfd_error != no_more_archived_files)
-           goto bloser;
+    last_one = &(inarch->next);
+    /* Read all the contents right away, regardless. */
+    for (next_one = bfd_openr_next_archived_file(inarch, NULL);
+        next_one;
+        next_one = bfd_openr_next_archived_file(inarch, next_one)) {
+       *last_one = next_one;
+       last_one = &next_one->next;
     }
+    *last_one = (bfd *) NULL;
+    if (bfd_error != no_more_archived_files)
+       goto bloser;
+    return 1;
 }
 
 
 
 
 
-void
+static void
 print_contents(abfd)
     bfd            *abfd;
 {
@@ -553,30 +604,33 @@ extract_file(abfd)
     chmod(abfd->filename, buf.st_mode);
 
     if (preserve_dates) {
-#ifdef USG
+#ifdef POSIX_UTIME
+        struct utimbuf tb;
+       tb.actime = buf.st_mtime;
+       tb.modtime = buf.st_mtime;
+       utime(abfd->filename, &tb);     /* FIXME check result */
+#else /* ! POSIX_UTIME */
+#ifdef USE_UTIME
        long            tb[2];
        tb[0] = buf.st_mtime;
        tb[1] = buf.st_mtime;
        utime(abfd->filename, tb);      /* FIXME check result */
-#else
+#else /* ! USE_UTIME */
        struct timeval  tv[2];
        tv[0].tv_sec = buf.st_mtime;
        tv[0].tv_usec = 0;
        tv[1].tv_sec = buf.st_mtime;
        tv[1].tv_usec = 0;
        utimes(abfd->filename, tv);     /* FIXME check result */
-#endif
+#endif /* ! USE_UTIME */
+#endif /* ! POSIX_UTIME */
     }
 }
 
 
 /* Just do it quickly; don't worry about dups, armap, or anything like that */
 
-/* This is ugly! XXX */
-
-PROTO(struct ar_hdr *, bfd_special_undocumented_glue, (bfd *abfd, char *filename));
-
-void
+static void
 do_quick_append(archive_filename, files_to_append)
     char           *archive_filename;
     char          **files_to_append;
@@ -612,6 +666,7 @@ do_quick_append(archive_filename, files_to_append)
     temp = bfd_openr(archive_filename, NULL);
 #endif
     if (temp == NULL) {
+        fprintf (stderr, "%s: ", program_name);
        bfd_perror(archive_filename);
        exit(1);
     }
@@ -634,6 +689,7 @@ do_quick_append(archive_filename, files_to_append)
     for (; files_to_append && *files_to_append; ++files_to_append) {
        struct ar_hdr  *hdr = bfd_special_undocumented_glue(temp, *files_to_append);
        if (hdr == NULL) {
+           fprintf (stderr, "%s: ", program_name);
            bfd_perror(*files_to_append);
            exit(1);
        }
@@ -642,10 +698,15 @@ do_quick_append(archive_filename, files_to_append)
 
        ifile = fopen(*files_to_append, FOPEN_RB);
        if (ifile == NULL)
+         {
            bfd_perror(program_name);
+         }
 
        if (stat(*files_to_append, &sbuf) != 0)
+         {
+           fprintf (stderr, "%s: ", program_name);
            bfd_perror(*files_to_append);
+         }
 
        tocopy = sbuf.st_size;
 
@@ -677,13 +738,7 @@ write_archive()
     int             namelen = strlen(inarch->filename);
     char           *new_name = xmalloc(namelen + 6);
     bfd            *contents_head = inarch->next;
-#if 0
-    if (inarch == &bogus_archive) {
-       /* How can this be ? */
-       return;
-    }
-    else {
-#endif
+
        strcpy(new_name, inarch->filename);
        strcpy(new_name + namelen, "-art");
        obfd = bfd_openw(new_name,
@@ -694,7 +749,10 @@ write_archive()
            bfd_fatal(inarch->filename);
 
        bfd_set_format(obfd, bfd_archive);
-       obfd->has_armap = write_armap;
+
+       /* Request writing the archive symbol table unless we've
+          been explicitly requested not to. */
+       obfd->has_armap = write_armap >= 0;
 
        if (bfd_set_archive_head(obfd, contents_head) != true)
            bfd_fatal(inarch->filename);
@@ -708,9 +766,6 @@ write_archive()
 
        if (rename(new_name, inarch->filename) != 0)
            bfd_fatal(inarch->filename);
-#if 0
-    }
-#endif
 }
 
 
@@ -745,7 +800,7 @@ get_pos_bfd(contents, default_pos)
 }
 
 
-void
+static void
 delete_members(files_to_delete)
     char          **files_to_delete;
 {
@@ -756,12 +811,13 @@ delete_members(files_to_delete)
        /*
           In a.out systems, the armap is optional.  It's also called
           __.SYMDEF.  So if the user asked to delete it, we should remember
-          that fact. The name is NULL in COFF archives, so using this as a
-          key is as good as anything I suppose
-       */
+          that fact. This isn't quite right for COFF systems (where
+          __.SYMDEF might be regular member), but it's very unlikely
+          to be a problem.  FIXME */
+
        if (!strcmp(*files_to_delete, "__.SYMDEF")) {
            inarch->has_armap = false;
-           write_armap = false;
+           write_armap = -1;
            continue;
        }
 
@@ -798,7 +854,7 @@ next_file:;
 
 /* Reposition existing members within an archive */
 
-void
+static void
 move_members(files_to_move)
     char          **files_to_move;
 {
@@ -843,7 +899,7 @@ next_file:;
 
 /* Ought to default to replacing in place, but this is existing practice! */
 
-void
+static void
 replace_members(files_to_move)
     char          **files_to_move;
 {
@@ -851,15 +907,6 @@ replace_members(files_to_move)
     bfd            *current;
     bfd           **current_ptr;
     bfd            *temp;
-    /*
-       If the first item in the archive is an __.SYMDEF then remove it
-    */
-    if (inarch->next &&
-       strcmp(inarch->next->filename, "__.SYMDEF") == 0) {
-       inarch->next = inarch->next->next;
-    }
-
-
 
     while (files_to_move && *files_to_move) {
        current_ptr = &inarch->next;
@@ -941,11 +988,11 @@ next_file:;
     write_archive();
 }
 
-void
+static void
 ranlib_only(archname)
     char           *archname;
 {
-    write_armap = true;
+    write_armap = 1;
     open_inarch(archname);
     write_archive();
     exit(0);
@@ -955,12 +1002,9 @@ ranlib_only(archname)
 
 /* Things which are interesting to map over all or some of the files: */
 
-void
+static void
 print_descr(abfd)
     bfd            *abfd;
 {
     print_arelt_descr(stdout,abfd, verbose);
 }
-
-
-
This page took 0.039414 seconds and 4 git commands to generate.