10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * CDDL HEADER START
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * The contents of this file are subject to the terms of the
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Common Development and Distribution License (the "License").
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * You may not use this file except in compliance with the License.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * See the License for the specific language governing permissions
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * and limitations under the License.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * When distributing Covered Code, include this CDDL HEADER in each
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * If applicable, add the following below this CDDL HEADER, with the
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * CDDL HEADER END
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Use is subject to license terms.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Deal with the lib.a(member.o) and lib.a((entry-point)) notations
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Look inside archives for notations a(b) and a((b))
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * a(b) is file member b in archive a
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * a((b)) is entry point b in object archive a
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * For 6.0, create a make which can understand all archive
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * formats. This is kind of tricky, and <ar.h> isnt any help.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Included files
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe off_t ran_off; /* library member at this offset */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Defined macros
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Defines for all the different archive formats. See next comment
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * block for justification for not using <ar.h>s versions.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#define AR_5_MAGIC "<ar>" /* 5.0 format magic string */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#define AR_5_MAGIC_LENGTH 4 /* 5.0 format string length */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#define AR_PORT_MAGIC "!<arch>\n" /* Port. (6.0) magic string */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#define AR_PORT_MAGIC_LENGTH 8 /* Port. (6.0) string length */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#define AR_PORT_END_MAGIC "`\n" /* Port. (6.0) end of header */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#define AR_PORT_WORD 4 /* Port. (6.0) 'word' length */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * typedefs & structs
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * These are the archive file headers for the formats. Note
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * that it really doesnt matter if these structures are defined
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * here. They are correct as of the respective archive format
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * releases. If the archive format is changed, then since backwards
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * compatability is the desired behavior, a new structure is added
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * to the list.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowetypedef struct { /* 5.0 ar header format: vax family; 3b family */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char ar_magic[AR_5_MAGIC_LENGTH]; /* AR_5_MAGIC*/
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char ar_date[AR_PORT_WORD]; /* sgetl() accessed */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char ar_syms[AR_PORT_WORD]; /* sgetl() accessed */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowetypedef struct { /* 5.0 ar symbol format: vax family; 3b family */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char sym_ptr[AR_PORT_WORD]; /* sgetl() accessed */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowetypedef struct { /* 5.0 ar member format: vax family; 3b family */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char arf_date[AR_PORT_WORD]; /* sgetl() accessed */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char arf_uid[AR_PORT_WORD]; /* sgetl() accessed */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char arf_gid[AR_PORT_WORD]; /* sgetl() accessed */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char arf_mode[AR_PORT_WORD]; /* sgetl() accessed */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char arf_size[AR_PORT_WORD]; /* sgetl() accessed */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowetypedef struct { /* Portable (6.0) ar format: vax family; 3b family */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* left-adjusted fields; decimal ascii; blank filled */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* special end-of-header string (AR_PORT_END_MAGIC) */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowetypedef unsigned int ar_port_word; // must be 4-bytes long
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowetypedef struct {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* to distiguish ar format */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* where first ar member header is at */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* where the symbol lookup starts */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* the number of symbols available */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* length of symbol directory file */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Static variables
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * File table of contents
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweextern timestruc_t& read_archive(register Name target);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowestatic Boolean open_archive(char *filename, register Ar *arp);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowestatic Boolean read_archive_dir(register Ar *arp, Name library, char **long_names_table);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowestatic void translate_entry(register Ar *arp, Name target, register Property member, char **long_names_table);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowestatic long sgetl(char *);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * read_archive(target)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Read the contents of an ar file.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Return value:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * The time the member was created
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Parameters:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * target The member to find time for
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Global variables used:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * empty_name The Name ""
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweint read_member_header (Ar_port *header, FILE *fd, char* filename);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweint process_long_names_member (register Ar *arp, char **long_names_table, char *filename);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char *long_names_table = NULL; /* Table of long
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member names */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Check if the member has directory component.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * If so, remove the dir and see if we know the date.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Wstring member_string(member->body.member.member);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if((slash = (wchar_t *) wcsrchr(wcb, (int) slash_char)) != NULL) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe INIT_STRING_FROM_STACK(true_member_name, buffer);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe append_string(member->body.member.library->string_mb,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe append_char((int) parenleft_char, &true_member_name);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe append_string(slash + 1, &true_member_name, FIND_LENGTH);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe append_char((int) parenright_char, &true_member_name);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe true_member = GETNAME(true_member_name.buffer.start,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (open_archive(member->body.member.library->string_mb, &ar) == failed) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Can't access archive `%s': %s"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (read_archive_dir(&ar, member->body.member.library,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Can't access archive `%s': %s"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe translate_entry(&ar, target, member,&long_names_table);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * open_archive(filename, arp)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Return value:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Indicates if open failed or not
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Parameters:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * filename The name of the archive we need to read
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * arp Pointer to ar file description block
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Global variables used:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fd = open_vroot(filename, O_RDONLY, 0, NULL, VROOT_DEFAULT);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if ((fd < 0) || ((arp->fd = fdopen(fd, "r")) == NULL)) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (fread(mag_port, AR_PORT_MAGIC_LENGTH, 1, arp->fd) != 1) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (IS_EQUALN(mag_port, AR_PORT_MAGIC, AR_PORT_MAGIC_LENGTH)) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Read in first member header to find out if there is
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * a symbol definition table.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe int ret = read_member_header(&arp->ar_port, arp->fd, filename);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* There is no member header - empty archive */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe arp->sym_size = arp->num_symbols = arp->sym_begin = 0L;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * The following values are the default if there is
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * no symbol directory and long member names.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe arp->sym_size = arp->num_symbols = arp->sym_begin = 0L;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe arp->first_ar_mem = ftell(arp->fd) - (long) sizeof (Ar_port);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Do we have a symbol table? A symbol table is always
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * the first member in an archive. In 4.1.x it has the
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * name __.SYMDEF, in SVr4, it has the name "/ "
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe MBSTOWCS(wcs_buffer, "/ ");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (IS_WEQUALN(arp->ar_port.ar_name, wcs_buffer, 16)) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe arp->sym_size += (arp->sym_size & 1); /* round up */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (fread(buffer, sizeof buffer, 1, arp->fd) != 1) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("`%s' is not an archive"), filename);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* NOTREACHED */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * close_archive(arp)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Parameters:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * arp Pointer to ar file description block
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Global variables used:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * read_archive_dir(arp, library, long_names_table)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Reads the directory of an archive and enters all
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * the members into the make symboltable in lib(member) format
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * with their dates.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Parameters:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * arp Pointer to ar file description block
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * library Name of lib to enter members for.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Used to form "lib(member)" string.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * long_names_table table that contains list of members
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * with names > 15 characters long
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Global variables used:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweread_archive_dir(register Ar *arp, Name library, char **long_names_table)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register wchar_t *p;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register char *q;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * If any of the members has a name > 15 chars,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * it will be found here.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (process_long_names_member(arp, long_names_table, library->string_mb) == failed) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe name_string = ALLOC_WC((int) (library->hash.length +
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (void) mbstowcs(name_string, library->string_mb, (int) library->hash.length);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member_string = name_string + library->hash.length;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (fseek(arp->fd, arp->first_ar_mem, 0) != 0) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* Read the directory using the appropriate format */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (fread((char *) &arp->arf_5, sizeof arp->arf_5, 1, arp->fd)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe for (p = member_string, q = arp->arf_5.arf_name;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (len > 0) && (*q != (int) nul_char) && !isspace(*q);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * [tolik] Fix for dmake bug 1234018.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * If name->stat.time is already set, then it should not
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * be changed. (D)make propogates time stamp for one
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * member, and when it calls exists() for another member,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * the first one may be changed.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe name->stat.time.tv_sec = sgetl(arp->arf_5.arf_date);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *--p = (int) nul_char;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe gettext("Read error in archive `%s': invalid archive file member header at 0x%x"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* If it's a long name, retrieve it from long name table */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * "len" is used for hashing the string.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * We're using "ar_member_name_len" instead of
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * the actual name length since it's the longest
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * string the "ar" command can handle at this
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (*q != (int) nul_char) &&
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (*q != (int) slash_char);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *--p = (int) nul_char;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (sscanf(arp->ar_port.ar_date, "%ld", &date) != 1) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Bad date field for member `%s' in archive `%s'"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * [tolik] Fix for dmake bug 1234018.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (sscanf(arp->ar_port.ar_size, "%ld", &ptr) != 1) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Bad size field for member `%s' in archive `%s'"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* Only here if fread() [or IS_EQUALN()] failed and not at EOF */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Read error in archive `%s': %s"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* NOTREACHED */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * process_long_names_member(arp)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * If the archive contains members with names longer
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * than 15 characters, then it has a special member
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * with the name "// " that contains a table
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * of null-terminated long names. This member
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * is always the first member, after the symbol table
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * if it exists.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Parameters:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * arp Pointer to ar file description block
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Global variables used:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweprocess_long_names_member(register Ar *arp, char **long_names_table, char *filename)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (fseek(arp->fd, arp->first_ar_mem, 0) != 0) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (Ar_port *) alloca((int) sizeof(Ar_port))) == NULL){
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe int ret = read_member_header(ar_member_header, arp->fd, filename);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* There is no member header - empty archive */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* Do we have special member containing long names? */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *long_names_table = (char *) malloc(table_size);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* Read the list of long member names into the table */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (fread(*long_names_table, table_size, 1, arp->fd) != 1) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * translate_entry(arp, target, member)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Finds the member for one lib.a((entry))
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Parameters:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * arp Pointer to ar file description block
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * target Target to find member name for
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * member Property to fill in with info
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Global variables used:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowetranslate_entry(register Ar *arp, Name target, register Property member, char **long_names_table)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register int i;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe ar_port_word *offend; /* end of offsets table */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (arp->sym_begin == 0L || arp->num_symbols == 0L) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Cannot find symbol `%s' in archive `%s'"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member_string = ALLOC_WC((int) ((int) ar_member_name_len * 2));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if ((len = member->body.member.entry->hash.length) > 8) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe target->stat.time.tv_sec = sgetl(arp->arf_5.arf_date);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe offs = (ar_port_word *) alloca((int) (arp->num_symbols * AR_PORT_WORD));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe strtablen=arp->sym_size-4-(int) (arp->num_symbols * AR_PORT_WORD);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe sizeof (char),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe maxs = strlen(member->body.member.entry->string_mb);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Bad date field for member `%s' in archive `%s'"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* If it's a long name, retrieve it from long name table */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Cannot find symbol `%s' in archive `%s'"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /*NOTREACHED*/
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Read error in archive `%s': %s"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Read error in archive `%s': Premature EOF"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * sgetl(buffer)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * The intent here is to provide a means to make the value of
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * bytes in an io-buffer correspond to the value of a long
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * in the memory while doing the io a long at a time.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Files written and read in this way are machine-independent.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Return value:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Long int read from buffer
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Parameters:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * buffer buffer we need to read long int from
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Global variables used:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register long w = 0;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe while ((i -= BITSPERBYTE) >= 0) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe w |= (long) ((unsigned char) *buffer++) << i;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * read_member_header(header, fd, filename)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * reads the member header for the 4.1.x and SVr4 archives.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Return value:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * fails if read error or member
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * header is not the right format
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Parameters:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * header There's one before each archive member
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * fd file descriptor for the archive file.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Global variables used:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweread_member_header(Ar_port *header, FILE *fd, char* filename)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe int num = fread((char *) header, sizeof (Ar_port), 1, fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* There is no member header - empty archive */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe gettext("Read error in archive `%s': invalid archive file member header at 0x%x"),