$NetBSD: patch-archive,v 1.1 1999/01/04 22:37:32 tv Exp $

--- ./bfd/archive.c.orig	Fri May  1 11:48:01 1998
+++ ./bfd/archive.c	Mon Dec 28 17:43:17 1998
@@ -595,7 +595,9 @@
 	 Note that last_file->origin can be odd in the case of
 	 BSD-4.4-style element with a long odd size. */
       filestart = last_file->origin + size;
-      filestart += filestart % 2;
+      if (!strncmp(arch_hdr (last_file)->ar_name, "#1/", 3))
+	size += strlen(normalize(last_file, last_file->filename));
+      filestart += size % 2;
     }
 
   return _bfd_get_elt_at_filepos (archive, filestart);
@@ -1202,6 +1204,44 @@
   return _bfd_construct_extended_name_table (abfd, false, tabloc, tablen);
 }
 
+/* 4.4BSD: frob short names, but leave extended name until write time. */
+
+boolean
+_bfd_archive_bsd44_construct_extended_name_table (abfd, tabloc, tablen, name)
+     bfd *abfd;
+     char **tabloc;
+     bfd_size_type *tablen;
+     const char **name;
+{
+  unsigned int maxname = abfd->xvec->ar_max_namelen;
+  bfd *current;
+
+  for (current = abfd->archive_head; current != NULL; current = current->next)
+    {
+      const char *normal;
+      unsigned int thislen;
+
+      normal = normalize (current, current->filename);
+      if (normal == NULL)
+	return false;
+
+      thislen = strlen (normal);
+      if (((thislen > maxname) || (strchr(normal, ' ') != NULL))
+	  && ((bfd_get_file_flags (abfd) & BFD_TRADITIONAL_FORMAT) == 0))
+	{
+	  struct ar_hdr *hdr = arch_hdr (current);
+	  sprintf ((hdr->ar_name), "#1/%-12ld", (long) thislen);
+	  hdr->ar_name[15] = ' ';
+	  sprintf ((hdr->ar_size), "%-9ld", (long) arelt_size(current) + thislen);
+	  hdr->ar_size[9] = ' ';
+	}
+    }
+
+  *name = *tabloc = NULL;
+  *tablen = 0;
+  return true;
+}
+
 /* Build an SVR4 style extended name table.  */
 
 boolean
@@ -1371,8 +1411,12 @@
 
   /* Goddamned sprintf doesn't permit MAXIMUM field lengths */
   sprintf ((hdr->ar_date), "%-12ld", (long) status.st_mtime);
-  sprintf ((hdr->ar_uid), "%ld", (long) status.st_uid);
-  sprintf ((hdr->ar_gid), "%ld", (long) status.st_gid);
+  if (status.st_uid > 65535U)
+    fprintf (stderr, "%s: uid %ld truncated to 16 bits\n", filename, status.st_uid);
+  sprintf ((hdr->ar_uid), "%ld", (long) status.st_uid & 0xffffU);
+  if (status.st_gid > 65535U)
+    fprintf (stderr, "%s: gid %ld truncated to 16 bits\n", filename, status.st_gid);
+  sprintf ((hdr->ar_gid), "%ld", (long) status.st_gid & 0xffffU);
   sprintf ((hdr->ar_mode), "%-8o", (unsigned int) status.st_mode);
   sprintf ((hdr->ar_size), "%-10ld", (long) status.st_size);
   /* Correct for a lossage in sprintf whereby it null-terminates.  I cannot
@@ -1654,12 +1698,22 @@
   for (current = arch->archive_head; current; current = current->next)
     {
       char buffer[DEFAULT_BUFFERSIZE];
-      unsigned int remaining = arelt_size (current);
+      unsigned int saved_size = arelt_size (current);
+      unsigned int remaining = saved_size;
       struct ar_hdr *hdr = arch_hdr (current);
 
       /* write ar header */
       if (bfd_write ((char *) hdr, 1, sizeof (*hdr), arch) != sizeof (*hdr))
 	return false;
+      /* write filename if it is a 4.4BSD extended file, and add to size */
+      if (!strncmp (hdr->ar_name, "#1/", 3))
+	{
+	  const char *normal = normalize (current, current->filename);
+	  unsigned int thislen = strlen (normal);
+	  if (bfd_write (normal, 1, thislen, arch) != thislen)
+	    return false;
+	  saved_size += thislen;
+	}
       if (bfd_seek (current, (file_ptr) 0, SEEK_SET) != 0)
 	return false;
       while (remaining)
@@ -1678,7 +1732,7 @@
 	    return false;
 	  remaining -= amt;
 	}
-      if ((arelt_size (current) % 2) == 1)
+      if ((saved_size % 2) == 1)
 	{
 	  if (bfd_write ("\012", 1, 1, arch) != 1)
 	    return false;
@@ -1914,8 +1968,11 @@
 	{
 	  do
 	    {
-	      firstreal += arelt_size (current) + sizeof (struct ar_hdr);
-	      firstreal += firstreal % 2;
+	      unsigned int size = arelt_size (current);
+	      if (!strncmp(arch_hdr (current)->ar_name, "#1/", 3))
+		size += strlen(normalize(current, current->filename));
+	      firstreal += size + sizeof (struct ar_hdr);
+	      firstreal += size % 2;
 	      current = current->next;
 	    }
 	  while (current != (bfd *) (map[count]).pos);
--- ./bfd/libbfd-in.h.orig	Fri May  1 11:48:12 1998
+++ ./bfd/libbfd-in.h	Mon Dec 28 17:43:21 1998
@@ -219,6 +219,8 @@
   _bfd_slurp_extended_name_table
 extern boolean _bfd_archive_bsd_construct_extended_name_table
   PARAMS ((bfd *, char **, bfd_size_type *, const char **));
+extern boolean _bfd_archive_bsd44_construct_extended_name_table
+  PARAMS ((bfd *, char **, bfd_size_type *, const char **));
 #define _bfd_archive_bsd_truncate_arname bfd_bsd_truncate_arname
 #define _bfd_archive_bsd_write_armap bsd_write_armap
 #define _bfd_archive_bsd_read_ar_hdr _bfd_generic_read_ar_hdr
--- ./bfd/libbfd.h.orig	Fri May  1 11:48:12 1998
+++ ./bfd/libbfd.h	Mon Dec 28 17:43:21 1998
@@ -219,6 +219,8 @@
   _bfd_slurp_extended_name_table
 extern boolean _bfd_archive_bsd_construct_extended_name_table
   PARAMS ((bfd *, char **, bfd_size_type *, const char **));
+extern boolean _bfd_archive_bsd44_construct_extended_name_table
+  PARAMS ((bfd *, char **, bfd_size_type *, const char **));
 #define _bfd_archive_bsd_truncate_arname bfd_bsd_truncate_arname
 #define _bfd_archive_bsd_write_armap bsd_write_armap
 #define _bfd_archive_bsd_read_ar_hdr _bfd_generic_read_ar_hdr
--- bfd/netbsd.h.orig	Mon Jan  4 09:58:12 1999
+++ bfd/netbsd.h	Mon Jan  4 09:58:37 1999
@@ -66,6 +66,8 @@
 #define MY_write_object_contents MY(write_object_contents)
 static boolean MY(write_object_contents) PARAMS ((bfd *abfd));
 #define MY_text_includes_header 1
+#define MY_construct_extended_name_table \
+	_bfd_archive_bsd44_construct_extended_name_table
 
 #include "aout-target.h"
 
