/* BFD back-end for archive files (libraries).
- Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 1998
+ Copyright 1990, 91, 92, 93, 94, 95, 96, 97, 98, 1999
Free Software Foundation, Inc.
Written by Cygnus Support. Mostly Gumby Henkel-Wallace's fault.
#include "libbfd.h"
#include "aout/ar.h"
#include "aout/ranlib.h"
-#include <errno.h>
-#include <string.h> /* For memchr, strrchr and friends */
#include <ctype.h>
#ifndef errno
static boolean do_slurp_coff_armap PARAMS ((bfd *abfd));
static const char *normalize PARAMS ((bfd *, const char *file));
static struct areltdata *bfd_ar_hdr_from_filesystem PARAMS ((bfd *abfd,
- const char *));
+ const char *,
+ bfd *member));
\f
boolean
_bfd_generic_mkarchive (abfd)
}
/* Extract the filename from the archive - there are two ways to
- specify an extendend name table, either the first char of the
+ specify an extended name table, either the first char of the
name is a space, or it's a slash. */
if ((hdr.ar_name[0] == '/'
|| (hdr.ar_name[0] == ' '
spaces, so only look for ' ' if we don't find '/'. */
char *e;
- e = memchr(hdr.ar_name, '\0', ar_maxnamelen (abfd));
+ e = memchr (hdr.ar_name, '\0', ar_maxnamelen (abfd));
if (e == NULL)
{
- e = memchr(hdr.ar_name, '/', ar_maxnamelen (abfd));
+ e = memchr (hdr.ar_name, '/', ar_maxnamelen (abfd));
if (e == NULL)
- e = memchr(hdr.ar_name, ' ', ar_maxnamelen (abfd));
+ e = memchr (hdr.ar_name, ' ', ar_maxnamelen (abfd));
}
- if (e == NULL)
+
+ if (e != NULL)
+ namelen = e - hdr.ar_name;
+ else
{
- bfd_set_error (bfd_error_malformed_archive);
- return NULL;
+ /* If we didn't find a termination character, then the name
+ must be the entire field. */
+ namelen = ar_maxnamelen (abfd);
}
- namelen = e - hdr.ar_name;
allocsize += namelen + 1;
}
#else
static const char *
normalize (abfd, file)
- bfd *abfd;
+ bfd *abfd ATTRIBUTE_UNUSED;
const char *file;
{
const char *filename = strrchr (file, '/');
\f
/** A couple of functions for creating ar_hdrs */
+#ifndef HAVE_GETUID
+#define getuid() 0
+#endif
+
+#ifndef HAVE_GETGID
+#define getgid() 0
+#endif
+
/* Takes a filename, returns an arelt_data for it, or NULL if it can't
make one. The filename must refer to a filename in the filesystem.
- The filename field of the ar_hdr will NOT be initialized */
+ The filename field of the ar_hdr will NOT be initialized. If member
+ is set, and it's an in-memory bfd, we fake it. */
static struct areltdata *
-bfd_ar_hdr_from_filesystem (abfd, filename)
+bfd_ar_hdr_from_filesystem (abfd, filename, member)
bfd *abfd;
const char *filename;
+ bfd *member;
{
struct stat status;
struct areltdata *ared;
struct ar_hdr *hdr;
char *temp, *temp1;
- if (stat (filename, &status) != 0)
+ if (member && (member->flags & BFD_IN_MEMORY) != 0)
+ {
+ /* Assume we just "made" the member, and fake it */
+ struct bfd_in_memory *bim = (struct bfd_in_memory *) member->iostream;
+ time(&status.st_mtime);
+ status.st_uid = getuid();
+ status.st_gid = getgid();
+ status.st_mode = 0644;
+ status.st_size = bim->size;
+ }
+ else if (stat (filename, &status) != 0)
{
bfd_set_error (bfd_error_system_call);
return NULL;
bfd *abfd;
const char *filename;
{
- struct areltdata *ar_elt = bfd_ar_hdr_from_filesystem (abfd, filename);
+ struct areltdata *ar_elt = bfd_ar_hdr_from_filesystem (abfd, filename, 0);
if (ar_elt == NULL)
return NULL;
return (struct ar_hdr *) ar_elt->arch_header;
if (!current->arelt_data)
{
current->arelt_data =
- (PTR) bfd_ar_hdr_from_filesystem (arch, current->filename);
+ (PTR) bfd_ar_hdr_from_filesystem (arch, current->filename, current);
if (!current->arelt_data)
return false;
bfd_ardata (arch)->armap_datepos = (SARMAG
+ offsetof (struct ar_hdr, ar_date[0]));
sprintf (hdr.ar_date, "%ld", bfd_ardata (arch)->armap_timestamp);
-#ifndef _WIN32
sprintf (hdr.ar_uid, "%ld", (long) getuid ());
sprintf (hdr.ar_gid, "%ld", (long) getgid ());
-#else
- sprintf (hdr.ar_uid, "%ld", (long) 666);
- sprintf (hdr.ar_gid, "%ld", (long) 42);
-#endif
sprintf (hdr.ar_size, "%-10d", (int) mapsize);
strncpy (hdr.ar_fmag, ARFMAG, 2);
for (i = 0; i < sizeof (struct ar_hdr); i++)