Files
seta75D d6fe8fe829 Init
2021-10-11 22:19:34 -03:00

251 lines
6.7 KiB
C

/*
* COMPONENT_NAME: BLDPROCESS
*
* FUNCTIONS: ArchFixMembName
* ArchReadHdr
* ArchReadMember
* ArchTOCTime
* ArchToNextMember
* ArchTouchTOC
* IS_AR_LONG_NAME
* IS_AR_STR_TABLE
* IS_AR_SYM_TABLE
*
* ORIGINS: 27,71
*
* This module contains IBM CONFIDENTIAL code. -- (IBM
* Confidential Restricted when combined with the aggregated
* modules for this product)
* SOURCE MATERIALS
*
* (C) COPYRIGHT International Business Machines Corp. 1994
* All Rights Reserved
* US Government Users Restricted Rights - Use, duplication or
* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*/
/*
* @OSF_FREE_COPYRIGHT@
* COPYRIGHT NOTICE
* Copyright (c) 1992, 1991, 1990
* Open Software Foundation, Inc.
*
* Permission is hereby granted to use, copy, modify and freely distribute
* the software in this file and its documentation for any purpose without
* fee, provided that the above copyright notice appears in all copies and
* that both the copyright notice and this permission notice appear in
* supporting documentation. Further, provided that the name of Open
* Software Foundation, Inc. ("OSF") not be used in advertising or
* publicity pertaining to distribution of the software without prior
* written permission from OSF. OSF makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*/
/*
* HISTORY
* $Log: arch_fmtdep.c,v $
* Revision 1.1.2.3 1992/12/03 19:04:48 damon
* ODE 2.2 CR 346. Expanded copyright
* [1992/12/03 18:34:44 damon]
*
* Revision 1.1.2.2 1992/09/24 19:22:56 gm
* CR286: Major improvements to make internals.
* [1992/09/24 17:51:49 gm]
*
* New SVR4 file
*
* $EndLog$
*/
/*
* (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems, Burlington, MA, USA
* All Rights Reserved
*/
#ifndef lint
static char sccsid[] = "@(#)38 1.1 src/bldenv/make/SVR4ARCH/arch_fmtdep.c, bldprocess, bos412, GOLDA411a 1/19/94 15:57:41";
#endif /* not lint */
#include <sys/types.h>
#include <sys/time.h>
#include <ctype.h>
#include <ar.h>
#include <stdio.h>
#include "make.h"
#include "hash.h"
/*
* In SYSV.4:
*
* Archives contain no table of contents member.
* The symbol table is the first archive member and has the name '/'.
* It is created if the archive contains any object files.
* The string table is the second archive member if it exists. It has the name '//'.
* It exists only if the name of one or more of the other
* archive members is greater than 15 characters.
* An archive member with a name longer than 15 characters has in its name field
* a '/', followed by the decimal representation of the offset
* into the string table of the name. In the string table,
* each name is terminated by a '/' followed by a '\n' character.
*/
#define AR_MAX_NAME_LEN 255
#define IS_AR_SYM_TABLE(a) ((a)->ar_name[0] == '/' && (a)->ar_name[1] == ' ')
#define IS_AR_STR_TABLE(a) ((a)->ar_name[0] == '/' && (a)->ar_name[1] == '/')
#define IS_AR_LONG_NAME(a) ((a)->ar_name[0] == '/' && (a)->ar_name[1] != ' ' && \
(a)->ar_name[1] != '/')
void
ArchFixMembName(string_t *memberPtr)
{
int len;
char *member;
string_t old_member;
if (DEBUG(ARCH)) {
printf("ArchFixMembName(%s)\n", (*memberPtr)->data);
}
len = (*memberPtr)->len;
if (len <= AR_MAX_NAME_LEN)
return;
old_member = *memberPtr;
member = strndup((*memberPtr)->data, AR_MAX_NAME_LEN);
*memberPtr = string_create(member);
string_deref(old_member);
if (DEBUG(ARCH)) {
printf("ArchFixMembName: truncated to %s\n", (*memberPtr)->data);
}
}
int
ArchReadHdr(FILE *arch, void **hdrInfoPtr)
{
char magic[SARMAG];
if ((fread (magic, SARMAG, 1, arch) != 1) ||
(strncmp (magic, ARMAG, SARMAG) != 0)) {
if (DEBUG(ARCH))
printf("ArchReadHdr: bad header\n");
return 0;
}
if (DEBUG(ARCH))
printf("ArchReadHdr: header OK\n");
return 1;
}
int
ArchReadMember(FILE *arch,
string_t *memNamePtr,
struct ar_hdr *arhPtr,
void *hdrInfo)
{
char memName[AR_MAX_NAME_LEN+1];
char *cp;
int i, size, offset;
long whereami;
static char *string_tbl = NULL;
reread:
if (fread ((char *)arhPtr, sizeof(struct ar_hdr), 1, arch) != 1) {
/*
* reinitialize string table for next archive
*/
if (string_tbl != NULL) {
free(string_tbl);
string_tbl = NULL;
}
return 0;
}
if (strncmp (arhPtr->ar_fmag, ARFMAG, sizeof(arhPtr->ar_fmag)) != 0) {
/*
* The header is bogus, so the archive is bad
* and there's no way we can recover. Reinitialize string table.
*/
if (DEBUG(ARCH))
printf("ArchReadMember: bad archive header\n");
if (string_tbl != NULL) {
free(string_tbl);
string_tbl = NULL;
}
return -1;
}
/*
* we don't cache symbol table or string table
*/
if (IS_AR_SYM_TABLE(arhPtr)) {
if (DEBUG(ARCH))
printf("ArchReadMember: read symbol table\n");
ArchToNextMember(arch, arhPtr, hdrInfo);
goto reread;
}
if (IS_AR_STR_TABLE(arhPtr)) {
/*
* If this is the string table, read it in for later use
*/
whereami = ftell (arch);
(void) sscanf (arhPtr->ar_size, "%10d", &size);
string_tbl = emalloc(size);
if (DEBUG(ARCH) || DEBUG(MAKE)) {
printf("ArchReadMember: read archive string table (%d bytes)\n", size);
}
if ((fread (string_tbl, size, 1, arch) != 1)) {
fclose (arch);
return 0;
}
fseek(arch, whereami, 0);
ArchToNextMember(arch, arhPtr, hdrInfo);
goto reread;
}
if (IS_AR_LONG_NAME(arhPtr)) {
/*
* If this is a long name, find the offset and copy out of
* the string table. Else, copy it out of the header.
* If we have a long name and no a string table, error.
*/
if (string_tbl == NULL) {
fclose (arch);
return 0;
}
(void) sscanf (&arhPtr->ar_name[1], "%10d", &offset);
for (size = 0, cp = string_tbl + offset; *cp != '/'; cp++, size++)
memName[size] = *cp;
memName[size] = '\0';
} else {
/*
* Copy name into memName array and NULL-terminate it.
* The '/' character terminates member names in SYSV.4
*/
for (cp = arhPtr->ar_name, i = 0; i < sizeof(arhPtr->ar_name); i++, cp++) {
if ((memName[i] = *cp) == '/') {
memName[i] = '\0';
break;
}
}
}
*memNamePtr = string_create(memName);
if (DEBUG(ARCH) || DEBUG(MAKE)) {
printf("Archiving %s\n", memName);
}
return 1;
}
void
ArchToNextMember(FILE *arch, struct ar_hdr *arhPtr, void *hdrInfo)
{
int size;
arhPtr->ar_size[sizeof(arhPtr->ar_size)-1] = '\0';
(void) sscanf (arhPtr->ar_size, "%10d", &size);
fseek (arch, (size + 1) & ~1, 1);
}
void
ArchTouchTOC(GNode *gn)
{
}
void
ArchTOCTime(GNode *gn, Boolean *oodatePtr)
{
*oodatePtr = FALSE;
}