10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * CDDL HEADER START
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
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 *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * or http://www.opensolaris.org/os/licensing.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * See the License for the specific language governing permissions
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * and limitations under the License.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
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 *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * CDDL HEADER END
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Use is subject to license terms.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * ar.c
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Deal with the lib.a(member.o) and lib.a((entry-point)) notations
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
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 *
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 */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Included files
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#include <alloca.h> /* alloca() */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#include <ar.h>
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#include <errno.h> /* errno */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#include <fcntl.h> /* open() */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#include <libintl.h>
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#include <mk/defs.h>
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#include <mksh/misc.h> /* retmem_mb() */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowestruct ranlib {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe union {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe off_t ran_strx; /* string table index of */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char *ran_name; /* symbol defined by */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } ran_un;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe off_t ran_off; /* library member at this offset */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe};
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#include <unistd.h> /* close() */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Defined macros
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#ifndef S5EMUL
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#undef BITSPERBYTE
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#define BITSPERBYTE 8
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe#endif
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
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 */
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
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
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * typedefs & structs
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
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 Lowe */
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_name[16]; /* Space terminated */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char ar_date[AR_PORT_WORD]; /* sgetl() accessed */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char ar_syms[AR_PORT_WORD]; /* sgetl() accessed */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe} Arh_5;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowetypedef struct { /* 5.0 ar symbol format: vax family; 3b family */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char sym_name[8]; /* Space terminated */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char sym_ptr[AR_PORT_WORD]; /* sgetl() accessed */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe} Ars_5;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowetypedef struct { /* 5.0 ar member format: vax family; 3b family */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char arf_name[16]; /* Space terminated */
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 Lowe} Arf_5;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowetypedef struct { /* Portable (6.0) ar format: vax family; 3b family */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char ar_name[16]; /* Space terminated */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* left-adjusted fields; decimal ascii; blank filled */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char ar_date[12];
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char ar_uid[6];
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char ar_gid[6];
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char ar_mode[8]; /* octal ascii */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char ar_size[10];
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* special end-of-header string (AR_PORT_END_MAGIC) */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char ar_fmag[2];
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe} Ar_port;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweenum ar_type {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe AR_5,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe AR_PORT
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe};
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowetypedef unsigned int ar_port_word; // must be 4-bytes long
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowetypedef struct {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe FILE *fd;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* to distiguish ar format */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe enum ar_type type;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* where first ar member header is at */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe long first_ar_mem;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* where the symbol lookup starts */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe long sym_begin;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* the number of symbols available */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe long num_symbols;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* length of symbol directory file */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe long sym_size;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Arh_5 arh_5;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Ars_5 ars_5;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Arf_5 arf_5;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Ar_port ar_port;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe} Ar;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Static variables
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * File table of contents
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweextern timestruc_t& read_archive(register Name target);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowestatic Boolean open_archive(char *filename, register Ar *arp);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowestatic void close_archive(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
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * read_archive(target)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Read the contents of an ar file.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Return value:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * The time the member was created
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Parameters:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * target The member to find time for
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Global variables used:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * empty_name The Name ""
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
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
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowetimestruc_t&
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweread_archive(register Name target)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe{
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register Property member;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe wchar_t *slash;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe String_rec true_member_name;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe wchar_t buffer[STRING_BUFFER_LENGTH];
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register Name true_member = NULL;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Ar ar;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char *long_names_table = NULL; /* Table of long
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member names */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member = get_prop(target->prop, member_prop);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /*
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 */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (member->body.member.member != NULL) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Wstring member_string(member->body.member.member);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe wchar_t * wcb = member_string.get_string();
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 &true_member_name,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe FIND_LENGTH);
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 FIND_LENGTH);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (true_member->stat.time != file_no_time) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe target->stat.time = true_member->stat.time;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return target->stat.time;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (open_archive(member->body.member.library->string_mb, &ar) == failed) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (errno == ENOENT) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe target->stat.stat_errno = ENOENT;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe close_archive(&ar);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (member->body.member.member == NULL) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member->body.member.member = empty_name;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return target->stat.time = file_doesnt_exist;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } else {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Can't access archive `%s': %s"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member->body.member.library->string_mb,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe errmsg(errno));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (target->stat.time == file_no_time) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (read_archive_dir(&ar, member->body.member.library,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe &long_names_table)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe == failed){
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Can't access archive `%s': %s"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member->body.member.library->string_mb,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe errmsg(errno));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (member->body.member.entry != NULL) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe translate_entry(&ar, target, member,&long_names_table);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe close_archive(&ar);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (long_names_table) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe retmem_mb(long_names_table);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (true_member != NULL) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe target->stat.time = true_member->stat.time;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (target->stat.time == file_no_time) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe target->stat.time = file_doesnt_exist;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return target->stat.time;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe}
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * open_archive(filename, arp)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Return value:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Indicates if open failed or not
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
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 *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Global variables used:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowestatic Boolean
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweopen_archive(char *filename, register Ar *arp)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe{
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe int fd;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char mag_5[AR_5_MAGIC_LENGTH];
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char mag_port[AR_PORT_MAGIC_LENGTH];
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char buffer[4];
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe arp->fd = NULL;
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 return failed;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (void) fcntl(fileno(arp->fd), F_SETFD, 1);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (fread(mag_port, AR_PORT_MAGIC_LENGTH, 1, arp->fd) != 1) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return failed;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (IS_EQUALN(mag_port, AR_PORT_MAGIC, AR_PORT_MAGIC_LENGTH)) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe arp->type = AR_PORT;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Read in first member header to find out if there is
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * a symbol definition table.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe int ret = read_member_header(&arp->ar_port, arp->fd, filename);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (ret == failed) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return failed;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } else if(ret == -1) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* There is no member header - empty archive */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe arp->sym_size = arp->num_symbols = arp->sym_begin = 0L;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe arp->first_ar_mem = ftell(arp->fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return succeeded;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * The following values are the default if there is
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * no symbol directory and long member names.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
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
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /*
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 */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe MBSTOWCS(wcs_buffer, "/ ");
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (IS_WEQUALN(arp->ar_port.ar_name, wcs_buffer, 16)) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (IS_EQUALN(arp->ar_port.ar_name,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe "/ ",
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe 16)) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (sscanf(arp->ar_port.ar_size,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe "%ld",
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe &arp->sym_size) != 1) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return failed;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe arp->sym_size += (arp->sym_size & 1); /* round up */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (fread(buffer, sizeof buffer, 1, arp->fd) != 1) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return failed;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe arp->num_symbols = sgetl(buffer);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe arp->sym_begin = ftell(arp->fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe arp->first_ar_mem = arp->sym_begin +
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe arp->sym_size - sizeof buffer;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return succeeded;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("`%s' is not an archive"), filename);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* NOTREACHED */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return failed;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe}
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * close_archive(arp)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Parameters:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * arp Pointer to ar file description block
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Global variables used:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowestatic void
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweclose_archive(register Ar *arp)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe{
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (arp->fd != NULL) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (void) fclose(arp->fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe}
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * read_archive_dir(arp, library, long_names_table)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
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 *
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 *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Global variables used:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowestatic Boolean
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweread_archive_dir(register Ar *arp, Name library, char **long_names_table)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe{
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe wchar_t *name_string;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe wchar_t *member_string;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register long len;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register wchar_t *p;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register char *q;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register Name name;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Property member;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe long ptr;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe long date;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe int offset;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * If any of the members has a name > 15 chars,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * it will be found here.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (process_long_names_member(arp, long_names_table, library->string_mb) == failed) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return failed;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe name_string = ALLOC_WC((int) (library->hash.length +
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (int) ar_member_name_len * 2));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (void) mbstowcs(name_string, library->string_mb, (int) library->hash.length);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member_string = name_string + library->hash.length;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *member_string++ = (int) parenleft_char;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (fseek(arp->fd, arp->first_ar_mem, 0) != 0) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe goto read_error;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* Read the directory using the appropriate format */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe switch (arp->type) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe case AR_5:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe for (;;) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (fread((char *) &arp->arf_5, sizeof arp->arf_5, 1, arp->fd)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe != 1) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (feof(arp->fd)) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return succeeded;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe break;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe len = sizeof arp->arf_5.arf_name;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe for (p = member_string, q = arp->arf_5.arf_name;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (len > 0) && (*q != (int) nul_char) && !isspace(*q);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe ) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe MBTOWC(p, q);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe p++;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe q++;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *p++ = (int) parenright_char;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *p = (int) nul_char;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe name = GETNAME(name_string, FIND_LENGTH);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /*
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 */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if(name->stat.time == file_no_time) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe name->stat.time.tv_sec = sgetl(arp->arf_5.arf_date);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe name->stat.time.tv_nsec = LONG_MAX;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe name->is_member = library->is_member;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member = maybe_append_prop(name, member_prop);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member->body.member.library = library;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *--p = (int) nul_char;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (member->body.member.member == NULL) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member->body.member.member =
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe GETNAME(member_string, FIND_LENGTH);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe ptr = sgetl(arp->arf_5.arf_size);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe ptr += (ptr & 1);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (fseek(arp->fd, ptr, 1) != 0) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe goto read_error;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe break;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe case AR_PORT:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe for (;;) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if ((fread((char *) &arp->ar_port,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe sizeof arp->ar_port,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe 1,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe arp->fd) != 1) ||
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe !IS_EQUALN(arp->ar_port.ar_fmag,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe AR_PORT_END_MAGIC,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe sizeof arp->ar_port.ar_fmag)) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (feof(arp->fd)) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return succeeded;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe gettext("Read error in archive `%s': invalid archive file member header at 0x%x"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe library->string_mb,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe ftell(arp->fd)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe );
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* If it's a long name, retrieve it from long name table */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (arp->ar_port.ar_name[0] == '/') {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /*
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 * point.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe len = ar_member_name_len;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe sscanf(arp->ar_port.ar_name + 1,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe "%ld",
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe &offset);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe q = *long_names_table + offset;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } else {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe q = arp->ar_port.ar_name;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe len = sizeof arp->ar_port.ar_name;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe for (p = member_string;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (len > 0) &&
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (*q != (int) nul_char) &&
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe !isspace(*q) &&
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (*q != (int) slash_char);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe ) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe MBTOWC(p, q);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe p++;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe q++;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *p++ = (int) parenright_char;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *p = (int) nul_char;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe name = GETNAME(name_string, FIND_LENGTH);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe name->is_member = library->is_member;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member = maybe_append_prop(name, member_prop);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member->body.member.library = library;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *--p = (int) nul_char;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (member->body.member.member == NULL) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member->body.member.member =
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe GETNAME(member_string, FIND_LENGTH);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (sscanf(arp->ar_port.ar_date, "%ld", &date) != 1) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe WCSTOMBS(mbs_buffer, name_string);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Bad date field for member `%s' in archive `%s'"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe mbs_buffer,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe library->string_mb);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * [tolik] Fix for dmake bug 1234018.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if(name->stat.time == file_no_time) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe name->stat.time.tv_sec = date;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe name->stat.time.tv_nsec = LONG_MAX;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (sscanf(arp->ar_port.ar_size, "%ld", &ptr) != 1) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe WCSTOMBS(mbs_buffer, name_string);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Bad size field for member `%s' in archive `%s'"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe mbs_buffer,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe library->string_mb);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe ptr += (ptr & 1);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (fseek(arp->fd, ptr, 1) != 0) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe goto read_error;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe break;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* Only here if fread() [or IS_EQUALN()] failed and not at EOF */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweread_error:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Read error in archive `%s': %s"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe library->string_mb,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe errmsg(errno));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* NOTREACHED */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe}
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * process_long_names_member(arp)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
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 *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Parameters:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * arp Pointer to ar file description block
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Global variables used:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweint
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweprocess_long_names_member(register Ar *arp, char **long_names_table, char *filename)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe{
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe Ar_port *ar_member_header;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe int table_size;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (fseek(arp->fd, arp->first_ar_mem, 0) != 0) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return failed;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if ((ar_member_header =
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (Ar_port *) alloca((int) sizeof(Ar_port))) == NULL){
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe perror(gettext("memory allocation failure"));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return failed;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe int ret = read_member_header(ar_member_header, arp->fd, filename);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (ret == failed) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return failed;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } else if(ret == -1) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* There is no member header - empty archive */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return succeeded;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* Do we have special member containing long names? */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (IS_EQUALN(ar_member_header->ar_name,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe "// ",
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe 16)){
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (sscanf(ar_member_header->ar_size,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe "%ld",
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe &table_size) != 1) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return failed;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
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 return failed;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe arp->first_ar_mem = ftell(arp->fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return succeeded;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe}
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * translate_entry(arp, target, member)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Finds the member for one lib.a((entry))
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
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 *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Global variables used:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowestatic void
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowetranslate_entry(register Ar *arp, Name target, register Property member, char **long_names_table)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe{
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register int len;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register int i;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe wchar_t *member_string;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe ar_port_word *offs;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe int strtablen;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char *syms; /* string table */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char *csym; /* string table */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe ar_port_word *offend; /* end of offsets table */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe int date;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register wchar_t *ap;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register char *hp;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe int maxs;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe int offset;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe char buffer[4];
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
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->body.member.entry->string_mb,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member->body.member.library->string_mb);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (fseek(arp->fd, arp->sym_begin, 0) != 0) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe goto read_error;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member_string = ALLOC_WC((int) ((int) ar_member_name_len * 2));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe switch (arp->type) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe case AR_5:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if ((len = member->body.member.entry->hash.length) > 8) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe len = 8;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe for (i = 0; i < arp->num_symbols; i++) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (fread((char *) &arp->ars_5,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe sizeof arp->ars_5,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe 1,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe arp->fd) != 1) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe goto read_error;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (IS_EQUALN(arp->ars_5.sym_name,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member->body.member.entry->string_mb,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe len)) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if ((fseek(arp->fd,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe sgetl(arp->ars_5.sym_ptr),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe 0) != 0) ||
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (fread((char *) &arp->arf_5,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe sizeof arp->arf_5,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe 1,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe arp->fd) != 1)) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe goto read_error;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe MBSTOWCS(wcs_buffer, arp->arf_5.arf_name);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (void) wcsncpy(member_string,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe wcs_buffer,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe wcslen(wcs_buffer));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member_string[sizeof(arp->arf_5.arf_name)] =
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (int) nul_char;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member->body.member.member =
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe GETNAME(member_string, FIND_LENGTH);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe target->stat.time.tv_sec = sgetl(arp->arf_5.arf_date);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe target->stat.time.tv_nsec = LONG_MAX;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe break;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe case AR_PORT:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe offs = (ar_port_word *) alloca((int) (arp->num_symbols * AR_PORT_WORD));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (fread((char *) offs,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe AR_PORT_WORD,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (int) arp->num_symbols,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe arp->fd) != arp->num_symbols) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe goto read_error;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe for(i=0;i<arp->num_symbols;i++) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *((int*)buffer)=offs[i];
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe offs[i]=(ar_port_word)sgetl(buffer);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe strtablen=arp->sym_size-4-(int) (arp->num_symbols * AR_PORT_WORD);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe syms = (char *) alloca(strtablen);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (fread(syms,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe sizeof (char),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe strtablen,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe arp->fd) != strtablen) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe goto read_error;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe offend = &offs[arp->num_symbols];
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe while (offs < offend) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe maxs = strlen(member->body.member.entry->string_mb);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if(strlen(syms) > maxs)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe maxs = strlen(syms);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (IS_EQUALN(syms,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member->body.member.entry->string_mb,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe maxs)) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (fseek(arp->fd,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (long) *offs,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe 0) != 0) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe goto read_error;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if ((fread((char *) &arp->ar_port,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe sizeof arp->ar_port,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe 1,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe arp->fd) != 1) ||
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe !IS_EQUALN(arp->ar_port.ar_fmag,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe AR_PORT_END_MAGIC,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe sizeof arp->ar_port.ar_fmag)) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe goto read_error;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (sscanf(arp->ar_port.ar_date,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe "%ld",
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe &date) != 1) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Bad date field for member `%s' in archive `%s'"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe arp->ar_port.ar_name,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe target->string_mb);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* If it's a long name, retrieve it from long name table */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (arp->ar_port.ar_name[0] == '/') {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe sscanf(arp->ar_port.ar_name + 1,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe "%ld",
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe &offset);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe len = ar_member_name_len;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe hp = *long_names_table + offset;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } else {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe len = sizeof arp->ar_port.ar_name;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe hp = arp->ar_port.ar_name;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe ap = member_string;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe while (*hp &&
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (*hp != (int) slash_char) &&
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe (ap < &member_string[len])) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe MBTOWC(ap, hp);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe ap++;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe hp++;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *ap = (int) nul_char;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member->body.member.member =
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe GETNAME(member_string, FIND_LENGTH);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe target->stat.time.tv_sec = date;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe target->stat.time.tv_nsec = LONG_MAX;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe offs++;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe while(*syms!='\0') syms++;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe syms++;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Cannot find symbol `%s' in archive `%s'"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member->body.member.entry->string_mb,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member->body.member.library->string_mb);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /*NOTREACHED*/
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweread_error:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (ferror(arp->fd)) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Read error in archive `%s': %s"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member->body.member.library->string_mb,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe errmsg(errno));
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe } else {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(gettext("Read error in archive `%s': Premature EOF"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe member->body.member.library->string_mb);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe}
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * sgetl(buffer)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
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 *
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 *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Global variables used:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowestatic long
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowesgetl(register char *buffer)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe{
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register long w = 0;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe register int i = BITSPERBYTE * AR_PORT_WORD;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe while ((i -= BITSPERBYTE) >= 0) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe w |= (long) ((unsigned char) *buffer++) << i;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return w;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe}
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe/*
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * read_member_header(header, fd, filename)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * reads the member header for the 4.1.x and SVr4 archives.
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe *
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 *
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe * Global variables used:
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweint
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Loweread_member_header(Ar_port *header, FILE *fd, char* filename)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe{
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe int num = fread((char *) header, sizeof (Ar_port), 1, fd);
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if (num != 1 && feof(fd)) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe /* There is no member header - empty archive */
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return -1;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe if ((num != 1) ||
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe !IS_EQUALN(
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe AR_PORT_END_MAGIC,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe header->ar_fmag,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe sizeof (header->ar_fmag)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe )
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe ) {
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe fatal(
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe gettext("Read error in archive `%s': invalid archive file member header at 0x%x"),
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe filename,
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe ftell(fd)
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe );
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe }
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe return succeeded;
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe}
10d63b7db37a83b39c7f511cf9426c9d03ea0760Richard Lowe